Flipping image

Source code

//========================================================
//
//  Flip Horizontal/Vertical  - QUAGLIOZZI ERIC (c) 2004
//
//========================================================

/*
   Usable for low res (72 dpi) and double res (144 dpi)
   bitmap using 8 and 16 bits colors.
 ---------------------------------------------------------
 | Do not use with other resolutions, may system crash ! |
 ---------------------------------------------------------
*/


//------------------- Macros and constants ---------------

#if defined(_MSC_VER)        // If compiling with VC++...

    #define private        static __inline
    #define longint        __int64
    
#elif defined(__GNUC__)  // If compiling with GCC...

    #define private        static inline
    #define longint        long long int
    
#else

    #error "Unknown Compiler!"
    
#endif



#define Read68KUnaligned32(addr)            \
  (((((unsigned char *)(addr))[0]) << 24) | \
  ((((unsigned char *)(addr))[1]) << 16) |  \
  ((((unsigned char *)(addr))[2]) << 8) |   \
  ((((unsigned char *)(addr))[3])))   // For endianness conversions



#define Write68KUnaligned32(addr, value) \
    (((unsigned char *)(addr))[0] = (unsigned char)((unsigned long)(value) >> 24), \
     ((unsigned char *)(addr))[1] = (unsigned char)((unsigned long)(value) >> 16), \
     ((unsigned char *)(addr))[2] = (unsigned char)((unsigned long)(value) >> 8), \
     ((unsigned char *)(addr))[3] = (unsigned char)((unsigned long)(value)))



#define EndianSwap16(n) (((((unsigned int) n) << 8) & 0xFF00) | \
                         ((((unsigned int) n) >> 8) & 0x00FF))



#define EndianSwap32(n) (((((unsigned long) n) << 24) & 0xFF000000) | \
                         ((((unsigned long) n) <<  8) & 0x00FF0000) | \
                         ((((unsigned long) n) >>  8) & 0x0000FF00) | \
                         ((((unsigned long) n) >> 24) & 0x000000FF))


//------------------------ Types -------------------------


typedef unsigned long Call68KFuncType(const void * emulStateP,
                                      unsigned long trapOrFunction,
                                      const void * argsOnStackP,
                                      unsigned long argsSizeAndwantA0);

typedef unsigned long NativeFuncType(const void * emulStateP,
                                     void * userData68KP,
                                     Call68KFuncType * call68KFuncP);

/*

  BMPparam (32 bit) :
    BMPparam[3]=0
    BMPparam[2]=0
    BMPparam[1]=bitdepth (1=8 / 2=16)
    BMPparam[0]=density (1=low, 2=high)
  BMPWH (32 bits) :
    BMPWH [3][2](16bits) : Height
    BMPWH [1][0](16bits) : Width
  Param1 (32 bits) :
    Param1 [0]=Action (HFlip, VFlip)
    Param1 [1]=0
    Param1 [2]=0
    Param1 [3]=0
*/

typedef struct _ParamsType
  {
    long                  BMPWH;          // Width-height
    long                  BMPparam;       // infos on bitmap
    long                  Param1;         // infos on actions
    unsigned char    * pSrc;              // bitmap source pointer
  }
    ParamsType;

// REM:
// Action = 0 : Horizontal flip
// Action = 1 : Vertical flip


//----------------------- Main Function ------------------


unsigned long FlipFill(const void * emulStateP, void * userData68KP,
                                      Call68KFuncType * call68KFuncP)
{
 ParamsType    * p;                         //pointer to params structure
 long            BMPparam, BMPWH, Param1;   //Locale copy of params
 unsigned char * Pixels;
 unsigned char * P1;
 unsigned char * P2;
 unsigned int    w, h, wlimit;
 unsigned int    density, bitdepth;
 unsigned int    i, j, n;
 unsigned int    ix1, ix2;
 unsigned char   Action, c;

 // Do local copy of params

 p=(ParamsType *) userData68KP;
 BMPWH=Read68KUnaligned32(&(p->BMPWH)); 
 BMPparam=Read68KUnaligned32(&(p->BMPparam)); 
 Param1=Read68KUnaligned32(&(p->Param1)); 
 Pixels=(unsigned char *) Read68KUnaligned32(&(p->pSrc)); 

 // get bitmap infos

 bitdepth=(BMPparam >> 8) & 0x000000FF ;
 density=BMPparam & 0x000000FF;
 w=(BMPWH & 0x0000FFFF)*density;
 wlimit=w*bitdepth;
 if (wlimit & 0x0001) wlimit += 1;
 h=(BMPWH >> 16)*density;
 
 // Perform initialization
  
 Action=Param1 & 0x000000FF;


 switch(Action)
 {
  case 0:   // horizontal flip
  if (bitdepth==1)
   {
      n=w>>1;
      for (j=0; j<h; j++)
        {
          for (i=0; i<n; i++)
            {
              c=Pixels[i];
              Pixels[i]=Pixels[w-1-i];
              Pixels[w-1-i]=c;
            }

          Pixels+=wlimit;
        }
   }
  else
   {
      n=w>>1;
      for (j=0; j<h; j++)
        {
          for (i=0; i<n; i++)
            {
              ix1=i<<1;
              ix2=(w-1-i)<<1;
              c=Pixels[ix1];
              Pixels[ix1]=Pixels[ix2];
              Pixels[ix2]=c;
              ix1+=1;
              ix2+=1;
              c=Pixels[ix1];
              Pixels[ix1]=Pixels[ix2];
              Pixels[ix2]=c;
            }

          Pixels+=wlimit;
        }
   }
  break;

  case 1:   // vertical flip
  if (bitdepth==1)
   {
      n=h>>1;
      P1=Pixels;
      P2=Pixels+(h-1)*wlimit;
      for (j=0; j<n; j++)
        {
          for (i=0; i<w; i++)
            {
              c=P1[i];
              P1[i]=P2[i];
              P2[i]=c;
            }
          P1 += wlimit;
          P2 -= wlimit;
        }
   }
  else
   {
      n=h>>1;
      P1=Pixels;
      P2=Pixels+(h-1)*wlimit;
      for (j=0; j<n; j++)
        {
          for (i=0; i<w; i++)
            {
              ix1=i<<1;
              c=P1[ix1];
              P1[ix1]=P2[ix1];
              P2[ix1]=c;
              ix1+=1;
              c=P1[ix1];
              P1[ix1]=P2[ix1];
              P2[ix1]=c;
            }
          P1 += wlimit;
          P2 -= wlimit;
        }
   }
  break;
 }
 return 0;
}

//========================================================