/*
=====================================================================
rotate.c

A fast 90-degree bit rotation routine.

The approach and much of the code are due to Sue-Ken Yap, "A Fast
90-Degree Bitmap Rotator," in GRAPHICS GEMS II, James Arvo, ed.,
San Diego, Academic Press, 1991, pp. 84-85 and 514-515.  This version
rotates CCW for chunky-to-planar conversions.

If DEMO is defined, this code is preprocessed out.
===================================================================== */

#ifndef DEMO

typedef unsigned long bit32;


#define table( name, n ) \
   static bit32 name[ 16 ] = { \
      0x00000000<<n,0x00000001<<n,0x00000100<<n,0x00000101<<n, \
      0x00010000<<n,0x00010001<<n,0x00010100<<n,0x00010101<<n, \
      0x01000000<<n,0x01000001<<n,0x01000100<<n,0x01000101<<n, \
      0x01010000<<n,0x01010001<<n,0x01010100<<n,0x01010101<<n };

table( ltab0, 7 )
table( ltab1, 6 )
table( ltab2, 5 )
table( ltab3, 4 )
table( ltab4, 3 )
table( ltab5, 2 )
table( ltab6, 1 )
table( ltab7, 0 )


void rotate8x8( unsigned char *src, int srcstep, unsigned char *dst, int dststep )
{
   unsigned char *p;
   int pstep, lonyb, hinyb;
   bit32 lo, hi;

   lo = hi = 0;

#define extract( d, t ) \
   lonyb = *d & 0xF; hinyb = *d >> 4; \
   lo |= t[ lonyb ]; hi |= t[ hinyb ]; d += pstep;

   p = src; pstep = srcstep;
   extract( p, ltab0 )
   extract( p, ltab1 )
   extract( p, ltab2 )
   extract( p, ltab3 )
   extract( p, ltab4 )
   extract( p, ltab5 )
   extract( p, ltab6 )
   extract( p, ltab7 )

#define unpack( d, w ) \
   *d =   w         & 0xFF; d += pstep; \
   *d = ( w >>  8 ) & 0xFF; d += pstep; \
   *d = ( w >> 16 ) & 0xFF; d += pstep; \
   *d = ( w >> 24 ) & 0xFF;

   p = dst; pstep = dststep;
   unpack( p, lo )
   p += pstep;
   unpack( p, hi )
}

#endif /* ifndef DEMO */