typedef unsigned int   uint;
typedef unsigned char  byte;
typedef unsigned short word;
typedef int Error;

// Error codes
#define RET_OK           0  //  all ok
#define RET_OPENERR      1  //  file open error
#define RET_INVALIDFMT   2  //  uncknown/invalid format
#define RET_IOERR        3  //  file read/write error
#define RET_NOMEM        4  //  no free memory
#define RET_END          5  //  end of file reached
#define RET_NOSUPPORT    6  //  operation is not supported
#define RET_BUFOVERFLOW  7  //  internal static buffer overflow
#define RET_INVALIDPTR   8  //  invalid pointer supplied
#define RET_MCBDESTROYD  9  //  SPCC structure headers destroyd
#define RET_BUSY        10  //  object is busy for other operation
#define RET_NEEDRESTORE 11  //  object must be restore before next operation
#define RET_INVALIDOP   12  //  invalid operation requested
#define RET_NOMESSAGES  13  //  no more messages in queue
#define RET_DUPLICATE   14  //  duplication is not allowed
#define RET_BREAK       15  //  operation break
#define RET_BADPATH     16  //  bad or invalid path
#define RET_NOACCESS    17  //  access denied
#define RET_BADCRC      18  //  invalid CRC - file damaged
#define RET_NOTFOUND    19  //  something was not founded
#define RET_SYNTAXERROR 20  //  syntax error in script or text file
#define RET_FAILED      21  //  operation failed
#define RET_ZEROPTR     22  //  NULL pointer supplied


import void* __cdecl malloc (int size);
import void* __cdecl realloc(void *ptr,int size);
import void  __cdecl free   (void *ptr);
import int   __cdecl strlen (char*);
import char *__cdecl strcpy (char*,char*);
import char *__cdecl strcat (char*,char*);
import int   __cdecl strcmp (char*,char*);
import void *__cdecl memmove(void*,void*,int);
import int   __cdecl memcmp (void*,void*,int);
import name "ihlpcPrintf"
       int   __cdecl printf (char*fmt,...);
import name "ihlpcSPrintf"
       int   __cdecl sprintf(char*buf,char*fmt,...);
typedef unsigned int  time_t;
typedef unsigned long size_t;
import time_t __cdecl time(time_t *tloc);

#pragma pack(push,1)

typedef byte Plt256[256][3];
typedef Plt256 *PPlt256;

// image
struct IFC {
  byte  internal[32];
  byte      *memdata;
  uint      imgFlags;
  uint   TranspColor;
  uint       LineLen;
  uint     PixLength;
  uint       RedMask;
  uint     GreenMask;
  uint      BlueMask;
  uint       ResMask;
  PPlt256       PPal;
  word             x;
  word             y;
  union {
    byte    dbMem[1];
    word    dwMem[1];
    uint    ddMem[1];
  }
};

struct IFF {
  byte      *memdata;
  uint      imgFlags;
  uint   TranspColor;
  uint       LineLen;
  uint     PixLength;
  uint       RedMask;
  uint     GreenMask;
  uint      BlueMask;
  uint       ResMask;
  PPlt256       PPal;
  word             x;
  word             y;
};

typedef struct {
  uint     PixLength; // 8/15/16/24/32
  uint       RedMask;
  uint     GreenMask;
  uint      BlueMask;
  uint       ResMask;
} CType;

#pragma pack(pop)

// imgFlags:
#define IMAGE_TRANSPARENT     0x00000001  // transparent image (TranspColor - direct color value)
#define IMAGE_WIDEPALETTE     0x00000010  // pallete entries 0..255, not 0..63
#define IMAGE_EMBEDDEDPALETTE 0x00000020  // palette in the same memory block with image
#define IMAGE_GRAYSCALE       0x00000040  // flag only (pallette still present in *PPal)

typedef int Error;
typedef IFC *PIFC;
typedef IFF *PIFF;

#ifndef NONCONVERT_MODE  // convert mode only (-si,-so keys)
// image list in process
PIFC *CvtImages;
// number of images in list
uint   CvtCount;

void ExtendImageList(uint NewCount) {
  if (NewCount>CvtCount)
    CvtImages=(PIFC*)realloc(CvtImages,NewCount*4);
}
#endif

void DumpImageInfo(PIFC image) {
  printf("PIFC: <%c%c%c%c:%8.8X data:%8.8X>\n",image->internal[0],image->internal[1],
    image->internal[2],image->internal[3],image,image->memdata);
  printf("   Flags   : %8.8X",image->imgFlags);
  if (image->imgFlags) {
    printf(" ( ");
    if (image->imgFlags&1) printf("TRANSPARENT ");
    //if (image->imgFlags&2) printf("RLE ");              // obsolette
    //if (image->imgFlags&8) printf("CACHED ");
    if (image->imgFlags&0x10) printf("WIDEPALETTE ");
    if (image->imgFlags&0x20) printf("EMBEDDEDPALETTE ");
    if (image->imgFlags&0x40) printf("GRAYSCALE ");
    printf(")\n");
  }
  printf("   Tr.Color: %8.8X\n",image->TranspColor);
  printf("   Pitch   : %d\n",image->PixLength);
  printf("   Format  : %8.8X %8.8X %8.8X (%d)\n",image->RedMask, image->GreenMask,
    image->BlueMask, image->PixLength);
  printf("   Size    : %dx%d\n",image->x,image->y);
}

int IsTrasparent(PIFC image) { return image->imgFlags&IMAGE_TRANSPARENT?1:0; }

PIFC IFF2IFC(PIFF img) { return (PIFC)((int)img-32); }
PIFF IFC2IFF(PIFC img) { return (PIFF)((int)img+32); }

PIFC operator PIFC(PIFF img) { return (PIFC)((int)img-32); }
PIFF operator PIFF(PIFC img) { return (PIFF)((int)img+32); }

void operator = (PIFC&dst,PIFF src) { dst=IFF2IFC(src); }
void operator = (PIFF&dst,PIFC src) { dst=IFC2IFF(src); }

/// Stretch image to new size
import PIFF  __stdcall Stretch(IFF *Image,uint NewX,uint NewY);
/// Fast(&ugly) stretch image to new size
import PIFF  __stdcall StretchFast(IFF *Image,uint NewX,uint NewY);
/// Convert RGB64 palette to BGRI256 palette. DstPal must be 1024 bytes long
import void  __stdcall PalConvert(Plt256 *SrcPal,void *DstPal);
/// Convert RGB64 palette to RGBI256 palette
import void  __stdcall PalConvertRGB(Plt256 *SrcPal,void *DstPal);
/// Convert BGRI256 palette to RGB64 palette
import void  __stdcall PalReConvert(void *SrcPal,Plt256 *DstPal);
/// Convert RGBI256 palette to RGB64 palette
import void  __stdcall PalReConvertRGB(void *SrcPal,Plt256 *DstPal);
/// swap R&B in palette
import void  __stdcall SwapPalRB(PPlt256 Pal);
/// expand 768 to 1024 palette
import void  __stdcall ExpandPal(PPlt256 Pal,void *DstPal);
/// compact palette from 1024 to 768
import void  __stdcall CompactPal(void *SrcPal,PPlt256 Pal);
/// convert RGB64<->RGB256
import void  __stdcall SwitchWidePalette(PPlt256 Pal,bool Wide);
/// check for grayscale
import bool  __stdcall IsGrayscalePalette(PPlt256 Pal,bool WideSrc);

/// Convert image to supplied B(its)P(er)P(ixel)
import PIFF  __stdcall UniConvert(PIFF Source,uint BPP);
/// Convert image to supplied B(its)P(er)P(ixel) with custom line length
import PIFF  __stdcall UniConvertEx(PIFF Source,CType *Fmt,uint RoundLineLenTo);
/// Convert image to (optional) ready buffer. (one of Destin & BPP can be 0)
import PIFF  __stdcall UniConvert2(PIFF Source,uint BPP,PIFF Destin);

// conversion routines (subset of UniConvert)
import bool  __stdcall CAnyTo8bpp (PIFF Source,PIFF *Destin);
import bool  __stdcall CAnyTo15bpp(PIFF Source,PIFF *Destin);
import bool  __stdcall CAnyTo16bpp(PIFF Source,PIFF *Destin);
import bool  __stdcall CAnyTo24bpp(PIFF Source,PIFF *Destin);
import bool  __stdcall CAnyTo32bpp(PIFF Source,PIFF *Destin);
import bool  __stdcall CAnyToGray (PIFF Source,PIFF *Destin);
// add alpha surface (x/y must be the same, AlphaSource - 8 bit image)
import bool  __stdcall CAnyToAlpha(PIFF Source,PIFF AlphaSource,PIFF *Destin);
// swap R&B
import bool  __stdcall C24RGBToBGR(IFF *Image);
import bool  __stdcall C32RGBToBGR(IFF *Image);
// covert color to color (ex. 24->16 BPP)
import uint  __stdcall ColorToColor(uint Color, uint BPP1, uint BPP2);
// recode 8-bit image to another palette
import void  __stdcall RecodeToPalette(IFF *Image,PPlt256 NewPlt);
// copy image palette from one to another
import bool  __stdcall CopyPalette(PIFF Src,PIFF Dst);

/** Set fields in IFF.Format for BPP=[8,15,16,24,32]
    else return IMG_INVALID */
import Error __stdcall SetDefFormat(CType *Format,long BPP);
import bool  __stdcall IsSameFormat(const CType *Fmt1,const CType *Fmt2);

// duplicate image
import PIFF  __stdcall DupFImage(IFF *Image);
// get image part
import PIFF  __stdcall SubImage (IFF *Image,uint x1,uint y1,uint dX,uint dY);
// get image size for malloc routine
import uint  __stdcall ImageSize(IFF *Image);
import uint  __stdcall ImageSizeXY(uint dX,uint dY,uint BPP);
// removing possible data alignment (pitch)
import bool  __stdcall DePitchImage(IFF *Image);
// allocate empty image
import PIFF  __stdcall AllocEmptyImage(uint dX,uint dY,uint BPP);
// anther allocate, with optional pitch (can be 0)
import PIFF  __stdcall AllocImageBuf (uint dX,uint dY,uint BPP,uint LineLen);
// Alloc buf with embedded palette. LineLen can be 0
import PIFF  __stdcall AllocImageBuf8(uint dX,uint dY,uint LineLen);
// Alloc buf with embedded palette. LineLen can be 0
import PIFF  __stdcall AllocImageBufGray(uint dX,uint dY,uint LineLen);
/** Alloc 1-bit buf with embedded palette. LineLen can be 0
    The only way to alloc 1-bit image
    There is no any support for with images in runtime now :(
*/
import PIFF  __stdcall AllocImageBuf1(uint dX,uint dY,uint LineLen);
// Alloc image with external data (only header with *memdata to ext. memory block)
import PIFF  __stdcall AllocPseudoImg(uint dX,uint dY,uint BPP,void *data,uint LineLen);
/// Copy dX*DY from (Sx1,Sy1) in source to (Dx1,Dy1) in destin
import bool  __stdcall CopyImageBlock(IFF *Source,IFF *Destin,
  uint Sx1,uint Sy1,uint Dx1,uint Dy1,uint dX,uint dY);
/// Make GrayScaled image ( do not change BPP & palette - only color values )
import void  __stdcall GrayScaleImage(IFF *Image);
/// return one of Source1,Source2 - nearest RGB to "ToValue"
import uint  __stdcall NearestColor24(uint Source1,uint Source2,uint ToValue);
// fint neated color index in palette
import uint  __stdcall FindNearestColor(uint Rp,uint Gp,uint Bp,Plt256 *Pal);
// fill image with direct color value
import void __stdcall ImageFillColor(IFF *Image,uint Color);
// flip image
import void __stdcall FlipVertical(PIFF img);
import void __stdcall FlipHorizontal(PIFF img);

// set trasparency (you still can do this directly, by changing image fields)
import void  __cdecl  SetTrasparency(PIFC Image,int On,uint Color);
// draw line
import PIFC  __stdcall DrawLine(PIFC Image,int x1,int y1,int x2,int y2,uint Color);
// load image from file
import PIFC  __cdecl   ihlpcLoadPic(char *name);
// read image from memory
import PIFC  __stdcall ReadMemImage(void *Buf,uint Size);
// save image to file
import Error __cdecl   ihlpcSavePic(char *fmt,char *name,PIFC Image);

/// normal blitting
#define BLIT_NORMAL       0x00000000
/// blit with transparent color
#define BLIT_TRANSPARENT  0x00000001
/// blit 32-bit image with alpha channel to image
#define BLIT_ALPHA        0x00000002
/// blit only pixels, which have nonZero color in mask image
#define BLIT_MASK         0x00000003
/// blit color to image with using 8-bit image with alpha info
#define BLIT_ALPHACOLOR   0x00000004
/// use max (absolute, not brightness!!) pixel value from both images
#define BLIT_MAXVALUE     0x00000005
/// blit 8-bit brightness delta array to an image
#define BLIT_BRIGHTNESS   0x00000006

#define BLIT_STRECTH      0x00000100
#define BLIT_FILL         0x00000200

// common blit routine
import int   __stdcall ihlpBlt(uint Flags,PIFC Dst,int x,int y,int dx,int dy,
  PIFC Src,int sx,int sy,int sdx,int sdy,PIFC Mask,uint Color);
// draw rectange (with optional Fill and Alpha value 0...255))
import int   __stdcall ihlpRect(PIFC Dst,int x,int y,int dx,int dy,uint Color,
  uint Fill,byte Alpha);

// Direction values for ihlpCanvasSize
#define DIRECTION_NW     0xFFFF
#define DIRECTION_SW     0xFF01
#define DIRECTION_NE     0x01FF
#define DIRECTION_SE     0x0101
#define DIRECTION_STOP   0x0000
#define DIRECTION_NORTH  0x00FE
#define DIRECTION_SOUTH  0x0002
#define DIRECTION_WEST   0xFE00
#define DIRECTION_EAST   0x0200

// canvas size (Adobe Photoshop like)
import PIFC  __stdcall ihlpCanvasSize(PIFC Img,int dx,int dy,int Direction,
  int RoundLineLen,uint ColorToFill);


// --- SetConvertMode flags ------
#define CVT_MODE_DITHERING     0x00000001 // use dithering then convert 24->15/16
#define CVT_MODE_LOADFAST      0x00000002 // use fast image load routines if possible
#define CVT_MODE_LOAD16BIT     0x00000004 // return 16 bit image if image loader can do this

#define CVT_MODE_GIFLGSIZE     0x00008000 // read gif with logical image size, not actual

#define CVT_MODE_FLT_POINT     0x01000000 // HQ scale filter type. Default - Lanczos
#define CVT_MODE_FLT_BOX       0x02000000
#define CVT_MODE_FLT_TRIANGLE  0x03000000
#define CVT_MODE_FLT_HERMITE   0x04000000
#define CVT_MODE_FLT_HANNING   0x05000000
#define CVT_MODE_FLT_HAMMING   0x06000000
#define CVT_MODE_FLT_BLACKMAN  0x07000000
#define CVT_MODE_FLT_GAUSSIAN  0x08000000
#define CVT_MODE_FLT_QUADRATIC 0x09000000
#define CVT_MODE_FLT_CUBIC     0x0A000000
#define CVT_MODE_FLT_CATROM    0x0B000000
#define CVT_MODE_FLT_MITCHELL  0x0C000000
#define CVT_MODE_FLT_LANCZOS   0x0D000000
#define CVT_MODE_FLT_BESSEL    0x0E000000
#define CVT_MODE_FLT_SINC      0x0F000000

import void __stdcall SetConvertMode(uint Flags);

struct TRect {
  int xLeft,xRight,yTop,yBottom;
};

#ifndef FONT_SUPPORT_OFF

// font attributes
#define SPFNA_COLOR      0x00000001   // set color support
#define SPFNA_WIDTH      0x00000002   // monospaced width
#define SPFNA_HEIGHT     0x00000004   // height
#define SPFNA_ITALIC     0x00000008   // italic support
#define SPFNA_BOLD       0x00000010   // bold support
#define SPFNA_PROPORT    0x00000020   // proportional/monospaced
#define SPFNA_SMOOTH     0x00000040   // smooth support
#define SPFNA_WIDTHARRAY 0x00000080   // set/get letter width array
#define SPFNA_SPACING    0x00000100   // change spacing between chars
#define SPFNA_CODEPAGE   0x00000400   // set codepage
#define SPFNA_UNDERLINE  0x00000800   // underline support

#define MAGIC_iFntSet    0x41544E46
#define MAGIC_iFntSetEx  0x42544E46

typedef byte LetterWdtArray[256];

// font properties for Draw/Width op
struct iFntSet {
  uint        Magic;  // "FNTA"
  uint        Color;
  uint        Flags;  // bold, italic, proport, smooth
  int         Width;  // Font mono width
  int        Height;  // Font mono height
  int       Spacing;  // Font additional spacing
  uint     CodePage;  
};

struct iFntSetEx(iFntSet) { // note; Magic=="FNTB"
  LetterWdtArray wa;
};

typedef void *lpFnt;
import name "ihlpFontWidth"
        int  __stdcall fontWidth(lpFnt Fnt,iFntSet *fntSet,char *text);
import name "ihlpFontDraw"
        void __stdcall fontDraw(lpFnt Fnt,iFntSet *fntSet,PIFC Where,int x,int y,
        char *text,TRect*Clip);
import name "ihlpFontQueryAttr"
        uint __stdcall fontQueryAttr(lpFnt Fnt);
import name "ihlpFontQuerySize"
        uint*__stdcall fontQuerySize(lpFnt Fnt);
import name "ihlpFontGetDefAttr"
        uint __stdcall fontGetDefAttr(lpFnt Fnt,uint Attr);
import name "ihlpFontGetDefAttrSet"
        void __stdcall fontGetDefAttrSet(lpFnt Fnt,iFntSet *fntSet);
import name "ihlpFontQueryCP"
        uint*__stdcall fontQueryCP(lpFnt Fnt);
import name "ihlpFontQueryName"
        char*__stdcall fontQueryName(lpFnt Fnt);
import name "ihlpFontQueryWA"
        LetterWdtArray* __stdcall fontQueryWA(lpFnt Fnt);
import name "ihlpFontRegister"
       Error __stdcall fontRegister(lpFnt *Font,const char *InitData);
import name "ihlpFontFind"
       lpFnt __stdcall fontFind(const char*Name,uint Color,uint Size);
import name "ihlpFontEnumBegin"
       int   __stdcall fontEnumBegin();
import name "ihlpFontEnumNext"
       lpFnt __stdcall fontEnumNext(int Handle);
#endif // FONT_SUPPORT_OFF


#ifdef FILEIO_SUPPORT
/* there is no 64-bit fSeek/Set/GetSize here - script can`t handle long long
   but all those functions prerform 64-bit i/o if it available */
/* there are more flags in fOpen (in the second or later position):
    "c"      any output must be committed immediatly.
    "d-"     share: set compatibility mode
    "dr"     share: prevent read access to the file.
    "dw"     share: prevent write access of the file.
    "d+"     share: permit both read and write access to the file.
    "e"      delete file immediately after it has been closed
    "s","s+" may be added to indicate that the file is to be accessed
             sequentially from beginning to end.
    "s-"     indicates that the file is accessed randomly */
import uint  __stdcall fOpen(char *FileName,char *Mode);
import uint  __stdcall fRead(uint Handle,void*Buffer,uint Count);
import uint  __stdcall fWrite(uint Handle,void*Buffer,uint Count);
#define PTR_FILE_BEGIN    0
#define PTR_FILE_CURRENT  1
#define PTR_FILE_END      2
import uint  __stdcall fSeek(uint Handle,long Offset,uint Origin);
import uint  __stdcall fPos(uint Handle);
import Error __stdcall fFlush(uint Handle);
import Error __stdcall fClose(uint Handle);
import uint  __stdcall fGetSize(uint Handle);
import uint  __stdcall fSetSize(uint Handle,uint NewSize);
import Error __stdcall fGetLastError();
import Error __stdcall fGetLastFileError(uint Handle);
import uint  __stdcall fRemove(char *FileName);
import uint  __stdcall fExists(char *FileName);
#endif // FILEIO_SUPPORT

