Stretching

Source code

//========================================================
//
// resize function without filtering 
// - QUAGLIOZZI ERIC (c) 2007 -
// This version can work with transparency color
//========================================================

/*
   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 ! |
 ---------------------------------------------------------
*/



#include "MathLibFixed.c"


//------------------ 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




//--------------------- 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);


typedef struct
  {
    char hb_object_header[14];
    short    padding;
    short    srcW;
    short    srcWL;
    short    srcH;
    short    dstW;
    short    dstWL;
    short    dstH;
    short    dens;
    short    BD;
    short    OffsetX;
    short    OffsetY;
    long     FactX;
    long     FactY;
    unsigned char    * pSrc;          // bitmap source pointer
    unsigned char    * pDest;         // bitmap destination pointer
    unsigned char TranspColorH;
    unsigned char TranspColorL;
    unsigned char TranspIndex;    
    unsigned char UseTransparency;    //0=no transparency, otherwise yes...
  }   HBStretch;

  
typedef struct _ParamsType
  {
    HBStretch    *  phbstch;          // HB class pointer
  }  ParamsType;



//---------------- stretch Function ----------------------


unsigned long BltStretchFunc(const void * emulStateP, void * userData68KP,
                                            Call68KFuncType * call68KFuncP)
{
  ParamsType    * p;               //pointer to params structure
  unsigned char * src;
  unsigned char * dest;
  unsigned char * Pal;
  HBStretch * pHB;

  unsigned char * P1;              //Vars for computations
  unsigned char * P2;
  short  ws, hs, wd, hd;
  long            FactW, FactH;
  short  is, js, id, jd;
  short  idx;
  short  density, bitdepth;
  short  wslimit, wdlimit;
  long   OffX, OffY, StartJD, StartID;

  // Do local copy of params

  p=(ParamsType *) userData68KP;
  pHB=p->phbstch; 
  ws=pHB->srcW;
  hs=pHB->srcH;
  wd=pHB->dstW;
  hd=pHB->dstH;
  src=pHB->pSrc; 
  dest=pHB->pDest; 
  density=pHB->dens;
  bitdepth=pHB->BD;
  wslimit=pHB->srcWL;
  wdlimit=pHB->dstWL;
  FactW=pHB->FactX;
  FactH=pHB->FactY;
  OffX=(pHB->OffsetX) << (density-1);
  OffY=(pHB->OffsetY) << (density-1);
  if(OffX<0)
   { StartID=0; } //OffX=-OffX;}
  else
   { StartID=OffX;}
  if(OffY<0)
   { StartJD=0; P2=dest;} //OffY=-OffY;}
  else
   { StartJD=OffY; P2=dest+OffY*(long)wdlimit;}

  //streching with clipping
  
  if (StartJD>=hd) { return 0; }
  
  P1=src;

  for (jd=StartJD;jd<hd;jd++)  
  {
    js = FixedPointToInt(FPS_MUL(IntToFixedPoint(jd-OffY),FactH));
    if ((js<hs)&&(js>=0))
    {
      P1=src+(long)js*(long)wslimit;
      for (id=StartID; id<wd; id++)
      {
        is = FixedPointToInt(FPS_MUL(IntToFixedPoint(id-OffX),FactW));
        if ((is<ws)&&(is>=0))
        { 
          if (bitdepth==1)
          {
            //Mode 8 bits : couleur pixel dest = couleur pixel source
            if(pHB->UseTransparency)
            { if(P1[is]!=pHB->TranspIndex) P2[id] = P1[is]; }
            else P2[id] = P1[is];
          }
          else
          {                  
            //Mode 16 bits : couleur pixel dest = couleur pixel source
            if(pHB->UseTransparency)
            { if((P1[(is<<1)]!=pHB->TranspColorH)||(P1[(is<<1)+1]!=pHB->TranspColorL))
              { P2[(id<<1)]=P1[(is<<1)];
                P2[(id<<1)+1]=P1[(is<<1)+1];
              }
            }
            else
            { P2[(id<<1)]=P1[(is<<1)];
              P2[(id<<1)+1]=P1[(is<<1)+1];
            }
          }
        }
      }
    } 
    P2+=wdlimit;
  }
  return 0;
}

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