home *** CD-ROM | disk | FTP | other *** search
/ PC PowerPlay 58 / pcpp58a.iso / extras / quake 3 source / Q3A_ToolSource.exe / Main / LBMLIB.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-02  |  27.0 KB  |  1,309 lines

  1. // lbmlib.c
  2.  
  3. #include "stdafx.h"
  4. #include "cmdlib.h"
  5. #include "lbmlib.h"
  6. #include "bmp.h"
  7. #include "pakstuff.h"
  8. #include "jpeglib.h"
  9.  
  10.  
  11. /*
  12. ============================================================================
  13.  
  14.                         LBM STUFF
  15.  
  16. ============================================================================
  17. */
  18.  
  19.  
  20. typedef unsigned char    UBYTE;
  21. //conflicts with windows typedef short            WORD;
  22. typedef unsigned short    UWORD;
  23. typedef long            LONG;
  24.  
  25. typedef enum
  26. {
  27.     ms_none,
  28.     ms_mask,
  29.     ms_transcolor,
  30.     ms_lasso
  31. } mask_t;
  32.  
  33. typedef enum
  34. {
  35.     cm_none,
  36.     cm_rle1
  37. } compress_t;
  38.  
  39. typedef struct
  40. {
  41.     UWORD        w,h;
  42.     short        x,y;
  43.     UBYTE        nPlanes;
  44.     UBYTE        masking;
  45.     UBYTE        compression;
  46.     UBYTE        pad1;
  47.     UWORD        transparentColor;
  48.     UBYTE        xAspect,yAspect;
  49.     short        pageWidth,pageHeight;
  50. } bmhd_t;
  51.  
  52. extern    bmhd_t    bmhd;                        // will be in native byte order
  53.  
  54.  
  55.  
  56. #define FORMID ('F'+('O'<<8)+((int)'R'<<16)+((int)'M'<<24))
  57. #define ILBMID ('I'+('L'<<8)+((int)'B'<<16)+((int)'M'<<24))
  58. #define PBMID  ('P'+('B'<<8)+((int)'M'<<16)+((int)' '<<24))
  59. #define BMHDID ('B'+('M'<<8)+((int)'H'<<16)+((int)'D'<<24))
  60. #define BODYID ('B'+('O'<<8)+((int)'D'<<16)+((int)'Y'<<24))
  61. #define CMAPID ('C'+('M'<<8)+((int)'A'<<16)+((int)'P'<<24))
  62.  
  63.  
  64. bmhd_t  bmhd;
  65.  
  66. int    Align (int l)
  67. {
  68.     if (l&1)
  69.         return l+1;
  70.     return l;
  71. }
  72.  
  73.  
  74.  
  75. /*
  76. ================
  77. LBMRLEdecompress
  78.  
  79. Source must be evenly aligned!
  80. ================
  81. */
  82. byte  *LBMRLEDecompress (byte *source,byte *unpacked, int bpwidth)
  83. {
  84.     int     count;
  85.     byte    b,rept;
  86.  
  87.     count = 0;
  88.  
  89.     do
  90.     {
  91.         rept = *source++;
  92.  
  93.         if (rept > 0x80)
  94.         {
  95.             rept = (rept^0xff)+2;
  96.             b = *source++;
  97.             memset(unpacked,b,rept);
  98.             unpacked += rept;
  99.         }
  100.         else if (rept < 0x80)
  101.         {
  102.             rept++;
  103.             memcpy(unpacked,source,rept);
  104.             unpacked += rept;
  105.             source += rept;
  106.         }
  107.         else
  108.             rept = 0;               // rept of 0x80 is NOP
  109.  
  110.         count += rept;
  111.  
  112.     } while (count<bpwidth);
  113.  
  114.     if (count>bpwidth)
  115.         Error ("Decompression exceeded width!\n");
  116.  
  117.  
  118.     return source;
  119. }
  120.  
  121.  
  122. /*
  123. =================
  124. LoadLBM
  125. =================
  126. */
  127. void LoadLBM (char *filename, byte **picture, byte **palette)
  128. {
  129.     byte    *LBMbuffer, *picbuffer, *cmapbuffer;
  130.     int             y;
  131.     byte    *LBM_P, *LBMEND_P;
  132.     byte    *pic_p;
  133.     byte    *body_p;
  134.  
  135.     int    formtype,formlength;
  136.     int    chunktype,chunklength;
  137.  
  138. // qiet compiler warnings
  139.     picbuffer = NULL;
  140.     cmapbuffer = NULL;
  141.  
  142. //
  143. // load the LBM
  144. //
  145.     LoadFile (filename, (void **)&LBMbuffer);
  146.  
  147.   if (LBMbuffer == NULL)
  148.   {
  149.     return;
  150.   }
  151. //
  152. // parse the LBM header
  153. //
  154.     LBM_P = LBMbuffer;
  155.     if ( *(int *)LBMbuffer != LittleLong(FORMID) )
  156.        Error ("No FORM ID at start of file!\n");
  157.  
  158.     LBM_P += 4;
  159.     formlength = BigLong( *(int *)LBM_P );
  160.     LBM_P += 4;
  161.     LBMEND_P = LBM_P + Align(formlength);
  162.  
  163.     formtype = LittleLong(*(int *)LBM_P);
  164.  
  165.     if (formtype != ILBMID && formtype != PBMID)
  166.         Error ("Unrecognized form type: %c%c%c%c\n", formtype&0xff
  167.         ,(formtype>>8)&0xff,(formtype>>16)&0xff,(formtype>>24)&0xff);
  168.  
  169.     LBM_P += 4;
  170.  
  171. //
  172. // parse chunks
  173. //
  174.  
  175.     while (LBM_P < LBMEND_P)
  176.     {
  177.         chunktype = LBM_P[0] + (LBM_P[1]<<8) + (LBM_P[2]<<16) + (LBM_P[3]<<24);
  178.         LBM_P += 4;
  179.         chunklength = LBM_P[3] + (LBM_P[2]<<8) + (LBM_P[1]<<16) + (LBM_P[0]<<24);
  180.         LBM_P += 4;
  181.  
  182.         switch ( chunktype )
  183.         {
  184.         case BMHDID:
  185.             memcpy (&bmhd,LBM_P,sizeof(bmhd));
  186.             bmhd.w = BigShort(bmhd.w);
  187.             bmhd.h = BigShort(bmhd.h);
  188.             bmhd.x = BigShort(bmhd.x);
  189.             bmhd.y = BigShort(bmhd.y);
  190.             bmhd.pageWidth = BigShort(bmhd.pageWidth);
  191.             bmhd.pageHeight = BigShort(bmhd.pageHeight);
  192.             break;
  193.  
  194.         case CMAPID:
  195.             cmapbuffer = (unsigned char*)malloc (768);
  196.             memset (cmapbuffer, 0, 768);
  197.             memcpy (cmapbuffer, LBM_P, chunklength);
  198.             break;
  199.  
  200.         case BODYID:
  201.             body_p = LBM_P;
  202.  
  203.             pic_p = picbuffer = (unsigned char*)malloc (bmhd.w*bmhd.h);
  204.             if (formtype == PBMID)
  205.             {
  206.             //
  207.             // unpack PBM
  208.             //
  209.                 for (y=0 ; y<bmhd.h ; y++, pic_p += bmhd.w)
  210.                 {
  211.                     if (bmhd.compression == cm_rle1)
  212.                         body_p = LBMRLEDecompress ((byte *)body_p
  213.                         , pic_p , bmhd.w);
  214.                     else if (bmhd.compression == cm_none)
  215.                     {
  216.                         memcpy (pic_p,body_p,bmhd.w);
  217.                         body_p += Align(bmhd.w);
  218.                     }
  219.                 }
  220.  
  221.             }
  222.             else
  223.             {
  224.             //
  225.             // unpack ILBM
  226.             //
  227.                 Error ("%s is an interlaced LBM, not packed", filename);
  228.             }
  229.             break;
  230.         }
  231.  
  232.         LBM_P += Align(chunklength);
  233.     }
  234.  
  235.     free (LBMbuffer);
  236.  
  237.     *picture = picbuffer;
  238.  
  239.     if (palette)
  240.         *palette = cmapbuffer;
  241. }
  242.  
  243.  
  244. /*
  245. ============================================================================
  246.  
  247.                             WRITE LBM
  248.  
  249. ============================================================================
  250. */
  251.  
  252. /*
  253. ==============
  254. WriteLBMfile
  255. ==============
  256. */
  257. void WriteLBMfile (char *filename, byte *data,
  258.                    int width, int height, byte *palette)
  259. {
  260.     byte    *lbm, *lbmptr;
  261.     int    *formlength, *bmhdlength, *cmaplength, *bodylength;
  262.     int    length;
  263.     bmhd_t  basebmhd;
  264.  
  265.     lbm = lbmptr = (unsigned char*)malloc (width*height+1000);
  266.  
  267. //
  268. // start FORM
  269. //
  270.     *lbmptr++ = 'F';
  271.     *lbmptr++ = 'O';
  272.     *lbmptr++ = 'R';
  273.     *lbmptr++ = 'M';
  274.  
  275.     formlength = (int*)lbmptr;
  276.     lbmptr+=4;                      // leave space for length
  277.  
  278.     *lbmptr++ = 'P';
  279.     *lbmptr++ = 'B';
  280.     *lbmptr++ = 'M';
  281.     *lbmptr++ = ' ';
  282.  
  283. //
  284. // write BMHD
  285. //
  286.     *lbmptr++ = 'B';
  287.     *lbmptr++ = 'M';
  288.     *lbmptr++ = 'H';
  289.     *lbmptr++ = 'D';
  290.  
  291.     bmhdlength = (int *)lbmptr;
  292.     lbmptr+=4;                      // leave space for length
  293.  
  294.     memset (&basebmhd,0,sizeof(basebmhd));
  295.     basebmhd.w = BigShort((short)width);
  296.     basebmhd.h = BigShort((short)height);
  297.     basebmhd.nPlanes = 8;
  298.     basebmhd.xAspect = 5;
  299.     basebmhd.yAspect = 6;
  300.     basebmhd.pageWidth = BigShort((short)width);
  301.     basebmhd.pageHeight = BigShort((short)height);
  302.  
  303.     memcpy (lbmptr,&basebmhd,sizeof(basebmhd));
  304.     lbmptr += sizeof(basebmhd);
  305.  
  306.     length = lbmptr-(byte *)bmhdlength-4;
  307.     *bmhdlength = BigLong(length);
  308.     if (length&1)
  309.         *lbmptr++ = 0;          // pad chunk to even offset
  310.  
  311. //
  312. // write CMAP
  313. //
  314.     *lbmptr++ = 'C';
  315.     *lbmptr++ = 'M';
  316.     *lbmptr++ = 'A';
  317.     *lbmptr++ = 'P';
  318.  
  319.     cmaplength = (int *)lbmptr;
  320.     lbmptr+=4;                      // leave space for length
  321.  
  322.     memcpy (lbmptr,palette,768);
  323.     lbmptr += 768;
  324.  
  325.     length = lbmptr-(byte *)cmaplength-4;
  326.     *cmaplength = BigLong(length);
  327.     if (length&1)
  328.         *lbmptr++ = 0;          // pad chunk to even offset
  329.  
  330. //
  331. // write BODY
  332. //
  333.     *lbmptr++ = 'B';
  334.     *lbmptr++ = 'O';
  335.     *lbmptr++ = 'D';
  336.     *lbmptr++ = 'Y';
  337.  
  338.     bodylength = (int *)lbmptr;
  339.     lbmptr+=4;                      // leave space for length
  340.  
  341.     memcpy (lbmptr,data,width*height);
  342.     lbmptr += width*height;
  343.  
  344.     length = lbmptr-(byte *)bodylength-4;
  345.     *bodylength = BigLong(length);
  346.     if (length&1)
  347.         *lbmptr++ = 0;          // pad chunk to even offset
  348.  
  349. //
  350. // done
  351. //
  352.     length = lbmptr-(byte *)formlength-4;
  353.     *formlength = BigLong(length);
  354.     if (length&1)
  355.         *lbmptr++ = 0;          // pad chunk to even offset
  356.  
  357. //
  358. // write output file
  359. //
  360.     SaveFile (filename, lbm, lbmptr-lbm);
  361.     free (lbm);
  362. }
  363.  
  364. /*
  365. ============================================================================
  366.  
  367. LOAD PCX
  368.  
  369. ============================================================================
  370. */
  371. typedef struct
  372. {
  373.     char    manufacturer;
  374.     char    version;
  375.     char    encoding;
  376.     char    bits_per_pixel;
  377.     unsigned short    xmin,ymin,xmax,ymax;
  378.     unsigned short    hres,vres;
  379.     unsigned char    palette[48];
  380.     char    reserved;
  381.     char    color_planes;
  382.     unsigned short    bytes_per_line;
  383.     unsigned short    palette_type;
  384.     char    filler[58];
  385.     unsigned char    data;            // unbounded
  386. } pcx_t;
  387.  
  388. /*
  389. ==============
  390. LoadPCX
  391. ==============
  392. */
  393. void LoadPCX (char *filename, byte **pic, byte **palette, int *width, int *height)
  394. {
  395.     byte    *raw = 0;
  396.     pcx_t    *pcx;
  397.     int        x, y;
  398.     int        len;
  399.     int        dataByte, runLength;
  400.     byte    *out, *pix;
  401.  
  402.     if (pic)
  403.         *pic = NULL;
  404.     if (palette)
  405.         *palette = NULL;
  406.     if (width)
  407.         *width = 0;
  408.     if (height)
  409.         *height = 0;
  410.  
  411.     //
  412.     // load the file
  413.     //
  414.     len = LoadFile (filename, (void **)&raw);
  415.     if (len == -1)
  416.         return;
  417.  
  418.     //
  419.     // parse the PCX file
  420.     //
  421.     pcx = (pcx_t *)raw;
  422.     raw = &pcx->data;
  423.  
  424.     pcx->xmin = LittleShort(pcx->xmin);
  425.     pcx->ymin = LittleShort(pcx->ymin);
  426.     pcx->xmax = LittleShort(pcx->xmax);
  427.     pcx->ymax = LittleShort(pcx->ymax);
  428.     pcx->hres = LittleShort(pcx->hres);
  429.     pcx->vres = LittleShort(pcx->vres);
  430.     pcx->bytes_per_line = LittleShort(pcx->bytes_per_line);
  431.     pcx->palette_type = LittleShort(pcx->palette_type);
  432.  
  433.     if (pcx->manufacturer != 0x0a
  434.         || pcx->version != 5
  435.         || pcx->encoding != 1
  436.         || pcx->bits_per_pixel != 8
  437.         || pcx->xmax >= 640
  438.         || pcx->ymax >= 480)
  439.         Error ("Bad pcx file %s", filename);
  440.     
  441.     if (palette)
  442.     {
  443.         *palette = (unsigned char*)malloc(768);
  444.         memcpy (*palette, (byte *)pcx + len - 768, 768);
  445.     }
  446.  
  447.     if (width)
  448.         *width = pcx->xmax+1;
  449.     if (height)
  450.         *height = pcx->ymax+1;
  451.  
  452.     if (!pic)
  453.   {
  454.     free(pcx);
  455.         return;
  456.   }
  457.  
  458.     out = (unsigned char*)malloc ( (pcx->ymax+1) * (pcx->xmax+1) );
  459.     if (!out)
  460.         Error ("Skin_Cache: couldn't allocate");
  461.  
  462.     *pic = out;
  463.  
  464.     pix = out;
  465.  
  466.     for (y=0 ; y<=pcx->ymax ; y++, pix += pcx->xmax+1)
  467.     {
  468.         for (x=0 ; x<=pcx->xmax ; )
  469.         {
  470.             dataByte = *raw++;
  471.  
  472.             if((dataByte & 0xC0) == 0xC0)
  473.             {
  474.                 runLength = dataByte & 0x3F;
  475.                 dataByte = *raw++;
  476.             }
  477.             else
  478.                 runLength = 1;
  479.  
  480.             while(runLength-- > 0)
  481.                 pix[x++] = dataByte;
  482.         }
  483.  
  484.     }
  485.  
  486.     if ( raw - (byte *)pcx > len)
  487.         Error ("PCX file %s was malformed", filename);
  488.  
  489.     free (pcx);
  490. }
  491. /* 
  492. ============== 
  493. WritePCXfile 
  494. ============== 
  495. */ 
  496. void WritePCXfile (char *filename, byte *data, 
  497.                    int width, int height, byte *palette) 
  498. {
  499.     int        i, j, length;
  500.     pcx_t    *pcx;
  501.     byte        *pack;
  502.       
  503.     pcx = (pcx_t*)malloc (width*height*2+1000);
  504.     memset (pcx, 0, sizeof(*pcx));
  505.  
  506.     pcx->manufacturer = 0x0a;    // PCX id
  507.     pcx->version = 5;            // 256 color
  508.      pcx->encoding = 1;        // uncompressed
  509.     pcx->bits_per_pixel = 8;        // 256 color
  510.     pcx->xmin = 0;
  511.     pcx->ymin = 0;
  512.     pcx->xmax = LittleShort((short)(width-1));
  513.     pcx->ymax = LittleShort((short)(height-1));
  514.     pcx->hres = LittleShort((short)width);
  515.     pcx->vres = LittleShort((short)height);
  516.     pcx->color_planes = 1;        // chunky image
  517.     pcx->bytes_per_line = LittleShort((short)width);
  518.     pcx->palette_type = LittleShort(2);        // not a grey scale
  519.  
  520.     // pack the image
  521.     pack = &pcx->data;
  522.     
  523.     for (i=0 ; i<height ; i++)
  524.     {
  525.         for (j=0 ; j<width ; j++)
  526.         {
  527.             if ( (*data & 0xc0) != 0xc0)
  528.                 *pack++ = *data++;
  529.             else
  530.             {
  531.                 *pack++ = 0xc1;
  532.                 *pack++ = *data++;
  533.             }
  534.         }
  535.     }
  536.             
  537.     // write the palette
  538.     *pack++ = 0x0c;    // palette ID byte
  539.     for (i=0 ; i<768 ; i++)
  540.         *pack++ = *palette++;
  541.         
  542. // write output file 
  543.     length = pack - (byte *)pcx;
  544.     SaveFile (filename, pcx, length);
  545.  
  546.     free (pcx);
  547.  
  548. /*
  549. ============================================================================
  550.  
  551. LOAD IMAGE
  552.  
  553. ============================================================================
  554. */
  555.  
  556. /*
  557. ==============
  558. Load256Image
  559.  
  560. Will load either an lbm or pcx, depending on extension.
  561. Any of the return pointers can be NULL if you don't want them.
  562. ==============
  563. */
  564. void Load256Image (char *name, byte **pixels, byte **palette,
  565.                    int *width, int *height)
  566. {
  567.     char    ext[128];
  568.     bitmap_t    bmp;
  569.  
  570.     ExtractFileExtension (name, ext);
  571.     if (stricmp(ext, "lbm"))
  572.     {
  573.         LoadLBM (name, pixels, palette);
  574.         if (width)
  575.             *width = bmhd.w;
  576.         if (height)
  577.             *height = bmhd.h;
  578.     }
  579.     else if (stricmp (ext, "pcx"))
  580.     {
  581.         LoadPCX (name, pixels, palette, width, height);
  582.     }
  583.     else if (stricmp (ext, "bmp"))
  584.     {
  585.         LoadBMP (name, &bmp);
  586.         if (bmp.palette)
  587.         {
  588.             *palette = (unsigned char*)malloc (768);
  589.             memcpy (*palette, bmp.palette, 768);
  590.         }
  591.         FreeBMP (&bmp);        
  592.     }
  593.     else
  594.         Error ("%s doesn't have a known image extension", name);
  595. }
  596.  
  597.  
  598. /*
  599. ==============
  600. Save256Image
  601.  
  602. Will save either an lbm or pcx, depending on extension.
  603. ==============
  604. */
  605. void Save256Image (char *name, byte *pixels, byte *palette,
  606.                    int width, int height)
  607. {
  608.     char    ext[128];
  609.  
  610.     ExtractFileExtension (name, ext);
  611.     if (!strcmp (ext, "lbm"))
  612.     {
  613.         WriteLBMfile (name, pixels, width, height, palette);
  614.     }
  615.     else if (!stricmp (ext, "pcx"))
  616.     {
  617.         WritePCXfile (name, pixels, width, height, palette);
  618.     }
  619.     else
  620.         Error ("%s doesn't have a known image extension", name);
  621. }
  622.  
  623.  
  624.  
  625. /*
  626. ============================================================================
  627.  
  628. TARGA IMAGE
  629.  
  630. ============================================================================
  631. */
  632. typedef struct _TargaHeader {
  633.     unsigned char     id_length, colormap_type, image_type;
  634.     unsigned short    colormap_index, colormap_length;
  635.     unsigned char    colormap_size;
  636.     unsigned short    x_origin, y_origin, width, height;
  637.     unsigned char    pixel_size, attributes;
  638. } TargaHeader;
  639.  
  640. int fgetLittleShort (FILE *f)
  641. {
  642.     byte    b1, b2;
  643.  
  644.     b1 = fgetc(f);
  645.     b2 = fgetc(f);
  646.  
  647.     return (short)(b1 + b2*256);
  648. }
  649.  
  650. int getLittleShort (byte*& p)
  651. {
  652.     byte    b1, b2;
  653.     b1 = *p++;
  654.     b2 = *p++;
  655.     return (short)(b1 + b2*256);
  656. }
  657.  
  658. int getLittleLong (byte*& p)
  659. {
  660.     byte    b1, b2, b3, b4;
  661.  
  662.     b1 = *p++;
  663.     b2 = *p++;
  664.     b3 = *p++;
  665.     b4 = *p++;
  666.     return b1 + (b2<<8) + (b3<<16) + (b4<<24);
  667. }
  668.  
  669. char getc(byte*& p)
  670. {
  671.   return *p++;
  672. }
  673.  
  674. /*
  675. =========================================================
  676.  
  677. BMP LOADING
  678.  
  679. =========================================================
  680. */
  681. typedef struct
  682. {
  683.     char id[2];
  684.     unsigned long fileSize;
  685.     unsigned long reserved0;
  686.     unsigned long bitmapDataOffset;
  687.     unsigned long bitmapHeaderSize;
  688.     unsigned long width;
  689.     unsigned long height;
  690.     unsigned short planes;
  691.     unsigned short bitsPerPixel;
  692.     unsigned long compression;
  693.     unsigned long bitmapDataSize;
  694.     unsigned long hRes;
  695.     unsigned long vRes;
  696.     unsigned long colors;
  697.     unsigned long importantColors;
  698.     unsigned char palette[256][4];
  699. } BMPHeader_t;
  700.  
  701. static void LoadBMP( const char *name, byte **pic, int *width, int *height )
  702. {
  703.     int        columns, rows, numPixels;
  704.     byte    *pixbuf;
  705.     int        row, column;
  706.     byte    *buf_p;
  707.     byte    *buffer;
  708.     unsigned int        length;
  709.     BMPHeader_t bmpHeader;
  710.     byte        *bmpRGBA;
  711.  
  712.     *pic = NULL;
  713.  
  714.     //
  715.     // load the file
  716.     //
  717.     length = LoadFile( ( char * ) name, (void **)&buffer);
  718.     if (length == -1)
  719.   {
  720.     length = PakLoadAnyFile( (char*)name, (void**)&buffer);
  721.     if (length == -1)
  722.     {
  723.           return;
  724.     }
  725.   }
  726.  
  727.     buf_p = buffer;
  728.  
  729.     bmpHeader.id[0] = *buf_p++;
  730.     bmpHeader.id[1] = *buf_p++;
  731.     bmpHeader.fileSize = LittleLong( * ( long * ) buf_p );
  732.     buf_p += 4;
  733.     bmpHeader.reserved0 = LittleLong( * ( long * ) buf_p );
  734.     buf_p += 4;
  735.     bmpHeader.bitmapDataOffset = LittleLong( * ( long * ) buf_p );
  736.     buf_p += 4;
  737.     bmpHeader.bitmapHeaderSize = LittleLong( * ( long * ) buf_p );
  738.     buf_p += 4;
  739.     bmpHeader.width = LittleLong( * ( long * ) buf_p );
  740.     buf_p += 4;
  741.     bmpHeader.height = LittleLong( * ( long * ) buf_p );
  742.     buf_p += 4;
  743.     bmpHeader.planes = LittleShort( * ( short * ) buf_p );
  744.     buf_p += 2;
  745.     bmpHeader.bitsPerPixel = LittleShort( * ( short * ) buf_p );
  746.     buf_p += 2;
  747.     bmpHeader.compression = LittleLong( * ( long * ) buf_p );
  748.     buf_p += 4;
  749.     bmpHeader.bitmapDataSize = LittleLong( * ( long * ) buf_p );
  750.     buf_p += 4;
  751.     bmpHeader.hRes = LittleLong( * ( long * ) buf_p );
  752.     buf_p += 4;
  753.     bmpHeader.vRes = LittleLong( * ( long * ) buf_p );
  754.     buf_p += 4;
  755.     bmpHeader.colors = LittleLong( * ( long * ) buf_p );
  756.     buf_p += 4;
  757.     bmpHeader.importantColors = LittleLong( * ( long * ) buf_p );
  758.     buf_p += 4;
  759.  
  760.     memcpy( bmpHeader.palette, buf_p, sizeof( bmpHeader.palette ) );
  761.  
  762.     if ( bmpHeader.bitsPerPixel == 8 )
  763.         buf_p += 1024;
  764.  
  765.     if ( bmpHeader.id[0] != 'B' && bmpHeader.id[1] != 'M' ) 
  766.     {
  767.         Sys_Printf("LoadBMP: only Windows-style BMP files supported (%s)\n", name );
  768.     }
  769.     if ( bmpHeader.fileSize != length )
  770.     {
  771.         Sys_Printf("LoadBMP: header size does not match file size (%d vs. %d) (%s)\n", bmpHeader.fileSize, length, name );
  772.     }
  773.     if ( bmpHeader.compression != 0 )
  774.     {
  775.         Sys_Printf("LoadBMP: only uncompressed BMP files supported (%s)\n", name );
  776.     }
  777.     if ( bmpHeader.bitsPerPixel < 8 )
  778.     {
  779.         Sys_Printf("LoadBMP: monochrome and 4-bit BMP files not supported (%s)\n", name );
  780.     }
  781.  
  782.     columns = bmpHeader.width;
  783.     rows = bmpHeader.height;
  784.     if ( rows < 0 )
  785.         rows = -rows;
  786.     numPixels = columns * rows;
  787.  
  788.     if ( width ) 
  789.         *width = columns;
  790.     if ( height )
  791.         *height = rows;
  792.  
  793.     bmpRGBA = reinterpret_cast<unsigned char*>(malloc( numPixels * 4 ));
  794.     *pic = bmpRGBA;
  795.  
  796.  
  797.     for ( row = rows-1; row >= 0; row-- )
  798.     {
  799.         pixbuf = bmpRGBA + row*columns*4;
  800.  
  801.         for ( column = 0; column < columns; column++ )
  802.         {
  803.             unsigned char red, green, blue, alpha;
  804.             int palIndex;
  805.             unsigned short shortPixel;
  806.  
  807.             switch ( bmpHeader.bitsPerPixel )
  808.             {
  809.             case 8:
  810.                 palIndex = *buf_p++;
  811.                 *pixbuf++ = bmpHeader.palette[palIndex][2];
  812.                 *pixbuf++ = bmpHeader.palette[palIndex][1];
  813.                 *pixbuf++ = bmpHeader.palette[palIndex][0];
  814.                 *pixbuf++ = 0xff;
  815.                 break;
  816.             case 16:
  817.                 shortPixel = * ( unsigned short * ) pixbuf;
  818.                 pixbuf += 2;
  819.                 *pixbuf++ = ( shortPixel & ( 31 << 10 ) ) >> 7;
  820.                 *pixbuf++ = ( shortPixel & ( 31 << 5 ) ) >> 2;
  821.                 *pixbuf++ = ( shortPixel & ( 31 ) ) << 3;
  822.                 *pixbuf++ = 0xff;
  823.                 break;
  824.  
  825.             case 24:
  826.                 blue = *buf_p++;
  827.                 green = *buf_p++;
  828.                 red = *buf_p++;
  829.                 *pixbuf++ = red;
  830.                 *pixbuf++ = green;
  831.                 *pixbuf++ = blue;
  832.                 *pixbuf++ = 255;
  833.                 break;
  834.             case 32:
  835.                 blue = *buf_p++;
  836.                 green = *buf_p++;
  837.                 red = *buf_p++;
  838.                 alpha = *buf_p++;
  839.                 *pixbuf++ = red;
  840.                 *pixbuf++ = green;
  841.                 *pixbuf++ = blue;
  842.                 *pixbuf++ = alpha;
  843.                 break;
  844.             default:
  845.                 Sys_Printf("LoadBMP: illegal pixel_size '%d' in file '%s'\n", bmpHeader.bitsPerPixel, name );
  846.                 break;
  847.             }
  848.         }
  849.     }
  850.  
  851.     free( buffer );
  852.  
  853. }
  854.  
  855.  
  856. /*
  857. =================================================================
  858.  
  859. PCX LOADING
  860.  
  861. =================================================================
  862. */
  863.  
  864.  
  865. /*
  866. ==============
  867. LoadPCX
  868. ==============
  869. */
  870. static void LoadPCX ( const char *filename, byte **pic, byte **palette, int *width, int *height)
  871. {
  872.     byte    *raw;
  873.     pcx_t    *pcx;
  874.     int        x, y;
  875.     int        len;
  876.     int        dataByte, runLength;
  877.     byte    *out, *pix;
  878.     int        xmax, ymax;
  879.  
  880.     *pic = NULL;
  881.     *palette = NULL;
  882.  
  883.     //
  884.     // load the file
  885.     //
  886.     len = LoadFile( ( char * ) filename, (void **)&raw);
  887.     if (len == -1) 
  888.   {
  889.     len = PakLoadAnyFile( (char*)filename, (void**)&raw);
  890.     if (len == -1)
  891.     {
  892.           return;
  893.     }
  894.     }
  895.  
  896.     //
  897.     // parse the PCX file
  898.     //
  899.     pcx = (pcx_t *)raw;
  900.     raw = &pcx->data;
  901.  
  902.       xmax = LittleShort(pcx->xmax);
  903.     ymax = LittleShort(pcx->ymax);
  904.  
  905.     if (pcx->manufacturer != 0x0a
  906.         || pcx->version != 5
  907.         || pcx->encoding != 1
  908.         || pcx->bits_per_pixel != 8
  909.         || xmax >= 1024
  910.         || ymax >= 1024)
  911.     {
  912.         Sys_Printf ("Bad pcx file %s (%i x %i) (%i x %i)\n", filename, xmax+1, ymax+1, pcx->xmax, pcx->ymax);
  913.         return;
  914.     }
  915.  
  916.     out = reinterpret_cast<unsigned char*>(malloc ( (ymax+1) * (xmax+1) ));
  917.  
  918.     *pic = out;
  919.  
  920.     pix = out;
  921.  
  922.     if (palette)
  923.     {
  924.         *palette = reinterpret_cast<unsigned char*>(malloc(768));
  925.         memcpy (*palette, (byte *)pcx + len - 768, 768);
  926.     }
  927.  
  928.     if (width)
  929.         *width = xmax+1;
  930.     if (height)
  931.         *height = ymax+1;
  932. // FIXME: use bytes_per_line here?
  933.  
  934.     for (y=0 ; y<=ymax ; y++, pix += xmax+1)
  935.     {
  936.         for (x=0 ; x<=xmax ; )
  937.         {
  938.             dataByte = *raw++;
  939.  
  940.             if((dataByte & 0xC0) == 0xC0)
  941.             {
  942.                 runLength = dataByte & 0x3F;
  943.                 dataByte = *raw++;
  944.             }
  945.             else
  946.                 runLength = 1;
  947.  
  948.             while(runLength-- > 0)
  949.                 pix[x++] = dataByte;
  950.         }
  951.  
  952.     }
  953.  
  954.     if ( raw - (byte *)pcx > len)
  955.     {
  956.         Sys_Printf ("PCX file %s was malformed", filename);
  957.         free (*pic);
  958.         *pic = NULL;
  959.     }
  960.  
  961.     free(pcx);
  962. }
  963.  
  964.  
  965. /*
  966. ==============
  967. LoadPCX32
  968. ==============
  969. */
  970. static void LoadPCX32 ( const char *filename, byte **pic, int *width, int *height) {
  971.     byte    *palette;
  972.     byte    *pic8;
  973.     int        i, c, p;
  974.     byte    *pic32;
  975.  
  976.     LoadPCX (filename, &pic8, &palette, width, height);
  977.     if (!pic8) {
  978.         *pic = NULL;
  979.         return;
  980.     }
  981.  
  982.     c = (*width) * (*height);
  983.     pic32 = *pic = reinterpret_cast<unsigned char*>(malloc(4 * c ));
  984.     for (i = 0 ; i < c ; i++) {
  985.         p = pic8[i];
  986.         pic32[0] = palette[p*3];
  987.         pic32[1] = palette[p*3 + 1];
  988.         pic32[2] = palette[p*3 + 2];
  989.         pic32[3] = 255;
  990.         pic32 += 4;
  991.     }
  992.  
  993.     free (pic8);
  994.     free (palette);
  995. }
  996.  
  997. /*
  998. =========================================================
  999.  
  1000. TARGA LOADING
  1001.  
  1002. =========================================================
  1003. */
  1004.  
  1005. /*
  1006. =============
  1007. LoadTGA
  1008. =============
  1009. */
  1010. void LoadTGA ( const char *name, byte **pic, int *width, int *height)
  1011. {
  1012.     int        columns, rows, numPixels;
  1013.     byte    *pixbuf;
  1014.     int        row, column;
  1015.     byte    *buf_p;
  1016.     byte    *buffer;
  1017.     TargaHeader    targa_header;
  1018.     byte        *targa_rgba;
  1019.  
  1020.     *pic = NULL;
  1021.  
  1022.     //
  1023.     // load the file
  1024.     //
  1025.     int nLen = LoadFile ( ( char * ) name, (void **)&buffer);
  1026.     if (nLen == -1) 
  1027.   {
  1028.     nLen = PakLoadAnyFile((char*)name, (void**)&buffer);
  1029.     if (nLen == -1)
  1030.     {
  1031.           return;
  1032.     }
  1033.     }
  1034.  
  1035.     buf_p = buffer;
  1036.  
  1037.     targa_header.id_length = *buf_p++;
  1038.     targa_header.colormap_type = *buf_p++;
  1039.     targa_header.image_type = *buf_p++;
  1040.     
  1041.     targa_header.colormap_index = LittleShort ( *(short *)buf_p );
  1042.     buf_p += 2;
  1043.     targa_header.colormap_length = LittleShort ( *(short *)buf_p );
  1044.     buf_p += 2;
  1045.     targa_header.colormap_size = *buf_p++;
  1046.     targa_header.x_origin = LittleShort ( *(short *)buf_p );
  1047.     buf_p += 2;
  1048.     targa_header.y_origin = LittleShort ( *(short *)buf_p );
  1049.     buf_p += 2;
  1050.     targa_header.width = LittleShort ( *(short *)buf_p );
  1051.     buf_p += 2;
  1052.     targa_header.height = LittleShort ( *(short *)buf_p );
  1053.     buf_p += 2;
  1054.     targa_header.pixel_size = *buf_p++;
  1055.     targa_header.attributes = *buf_p++;
  1056.  
  1057.     //++timo debug
  1058.     if (targa_header.pixel_size == 32)
  1059.         Sys_Printf("%s is 32bit\n", name);
  1060.     bool bAlphaOK = false;
  1061.  
  1062.     if (targa_header.image_type!=2 
  1063.         && targa_header.image_type!=10
  1064.         && targa_header.image_type != 3 ) 
  1065.     {
  1066.         Sys_Printf("LoadTGA: Only type 2 (RGB), 3 (gray), and 10 (RGB) TGA images supported\n");
  1067.     }
  1068.  
  1069.     if ( targa_header.colormap_type != 0 )
  1070.     {
  1071.         Sys_Printf("LoadTGA: colormaps not supported\n" );
  1072.     }
  1073.  
  1074.     if ( ( targa_header.pixel_size != 32 && targa_header.pixel_size != 24 ) && targa_header.image_type != 3 )
  1075.     {
  1076.         Sys_Printf("LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
  1077.     }
  1078.  
  1079.     columns = targa_header.width;
  1080.     rows = targa_header.height;
  1081.     numPixels = columns * rows;
  1082.  
  1083.     if (width)
  1084.         *width = columns;
  1085.     if (height)
  1086.         *height = rows;
  1087.  
  1088.     targa_rgba = reinterpret_cast<unsigned char*>(malloc (numPixels*4));
  1089.     *pic = targa_rgba;
  1090.  
  1091.     if (targa_header.id_length != 0)
  1092.         buf_p += targa_header.id_length;  // skip TARGA image comment
  1093.     
  1094.     if ( targa_header.image_type==2 || targa_header.image_type == 3 )
  1095.     { 
  1096.         // Uncompressed RGB or gray scale image
  1097.         for(row=rows-1; row>=0; row--) 
  1098.         {
  1099.             pixbuf = targa_rgba + row*columns*4;
  1100.             for(column=0; column<columns; column++) 
  1101.             {
  1102.                 unsigned char red,green,blue,alphabyte;
  1103.                 switch (targa_header.pixel_size) 
  1104.                 {
  1105.                     
  1106.                 case 8:
  1107.                     blue = *buf_p++;
  1108.                     green = blue;
  1109.                     red = blue;
  1110.                     *pixbuf++ = red;
  1111.                     *pixbuf++ = green;
  1112.                     *pixbuf++ = blue;
  1113.                     *pixbuf++ = 255;
  1114.                     break;
  1115.  
  1116.                 case 24:
  1117.                     blue = *buf_p++;
  1118.                     green = *buf_p++;
  1119.                     red = *buf_p++;
  1120.                     *pixbuf++ = red;
  1121.                     *pixbuf++ = green;
  1122.                     *pixbuf++ = blue;
  1123.                     *pixbuf++ = 255;
  1124.                     break;
  1125.                 case 32:
  1126.                     blue = *buf_p++;
  1127.                     green = *buf_p++;
  1128.                     red = *buf_p++;
  1129.                     alphabyte = *buf_p++;
  1130.                     //++timo debug: detect if the whole alpha channel is 0
  1131.                     if (alphabyte != 0)
  1132.                         bAlphaOK = true;
  1133.                     *pixbuf++ = red;
  1134.                     *pixbuf++ = green;
  1135.                     *pixbuf++ = blue;
  1136.                     *pixbuf++ = alphabyte;
  1137.                     break;
  1138.                 default:
  1139.                     Sys_Printf("LoadTGA: illegal pixel_size '%d' in file '%s'\n", targa_header.pixel_size, name );
  1140.                     break;
  1141.                 }
  1142.             }
  1143.         }
  1144.  
  1145.         //++timo debug
  1146.         if (bAlphaOK)
  1147.             Sys_Printf("alpha channel OK");
  1148.         else
  1149.             Sys_Printf("empty alpha channel!");
  1150.     }
  1151.     else if (targa_header.image_type==10) {   // Runlength encoded RGB images
  1152.  
  1153.         //++timo debug
  1154.         Sys_Printf("runlength encode RGB image");
  1155.  
  1156.         unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j;
  1157.  
  1158.         red = 0;
  1159.         green = 0;
  1160.         blue = 0;
  1161.         alphabyte = 0xff;
  1162.  
  1163.         for(row=rows-1; row>=0; row--) {
  1164.             pixbuf = targa_rgba + row*columns*4;
  1165.             for(column=0; column<columns; ) {
  1166.                 packetHeader= *buf_p++;
  1167.                 packetSize = 1 + (packetHeader & 0x7f);
  1168.                 if (packetHeader & 0x80) {        // run-length packet
  1169.                     switch (targa_header.pixel_size) {
  1170.                         case 24:
  1171.                                 blue = *buf_p++;
  1172.                                 green = *buf_p++;
  1173.                                 red = *buf_p++;
  1174.                                 alphabyte = 255;
  1175.                                 break;
  1176.                         case 32:
  1177.                                 blue = *buf_p++;
  1178.                                 green = *buf_p++;
  1179.                                 red = *buf_p++;
  1180.                                 alphabyte = *buf_p++;
  1181.                                 break;
  1182.                         default:
  1183.                             Sys_Printf("LoadTGA: illegal pixel_size '%d' in file '%s'\n", targa_header.pixel_size, name );
  1184.                             break;
  1185.                     }
  1186.     
  1187.                     for(j=0;j<packetSize;j++) {
  1188.                         *pixbuf++=red;
  1189.                         *pixbuf++=green;
  1190.                         *pixbuf++=blue;
  1191.                         *pixbuf++=alphabyte;
  1192.                         column++;
  1193.                         if (column==columns) { // run spans across rows
  1194.                             column=0;
  1195.                             if (row>0)
  1196.                                 row--;
  1197.                             else
  1198.                                 goto breakOut;
  1199.                             pixbuf = targa_rgba + row*columns*4;
  1200.                         }
  1201.                     }
  1202.                 }
  1203.                 else {                            // non run-length packet
  1204.                     for(j=0;j<packetSize;j++) {
  1205.                         switch (targa_header.pixel_size) {
  1206.                             case 24:
  1207.                                     blue = *buf_p++;
  1208.                                     green = *buf_p++;
  1209.                                     red = *buf_p++;
  1210.                                     *pixbuf++ = red;
  1211.                                     *pixbuf++ = green;
  1212.                                     *pixbuf++ = blue;
  1213.                                     *pixbuf++ = 255;
  1214.                                     break;
  1215.                             case 32:
  1216.                                     blue = *buf_p++;
  1217.                                     green = *buf_p++;
  1218.                                     red = *buf_p++;
  1219.                                     alphabyte = *buf_p++;
  1220.                                     *pixbuf++ = red;
  1221.                                     *pixbuf++ = green;
  1222.                                     *pixbuf++ = blue;
  1223.                                     *pixbuf++ = alphabyte;
  1224.                                     break;
  1225.                             default:
  1226.                                 Sys_Printf("LoadTGA: illegal pixel_size '%d' in file '%s'\n", targa_header.pixel_size, name );
  1227.                                 break;
  1228.                         }
  1229.                         column++;
  1230.                         if (column==columns) { // pixel packet run spans across rows
  1231.                             column=0;
  1232.                             if (row>0)
  1233.                                 row--;
  1234.                             else
  1235.                                 goto breakOut;
  1236.                             pixbuf = targa_rgba + row*columns*4;
  1237.                         }                        
  1238.                     }
  1239.                 }
  1240.             }
  1241.             breakOut:;
  1242.         }
  1243.     }
  1244.  
  1245.     free(buffer);
  1246. }
  1247.  
  1248.  
  1249.  
  1250.  
  1251. void LoadJPG( const char *filename, unsigned char **pic, int *width, int *height ) 
  1252. {
  1253.   byte    *fbuffer = NULL;
  1254.   int nLen = LoadFile( ( char * ) filename, (void **)&fbuffer);
  1255.   if (nLen == -1) 
  1256.   {
  1257.     nLen = PakLoadAnyFile((char*)filename, (void**)&fbuffer);
  1258.     if (nLen == -1)
  1259.     {
  1260.           return;
  1261.     }
  1262.   }
  1263.   LoadJPGBuff(fbuffer, pic, width, height);
  1264.   free(fbuffer);
  1265. }
  1266.  
  1267. //===================================================================
  1268.  
  1269. /*
  1270. =================
  1271. LoadImage
  1272.  
  1273. Loads any of the supported image types into a cannonical
  1274. 32 bit format.
  1275. =================
  1276. */
  1277. void LoadImage( const char *name, byte **pic, int *width, int *height ) 
  1278. {
  1279.     int        len;
  1280.     *pic = NULL;
  1281.     *width = 0;
  1282.     *height = 0;
  1283.  
  1284.     len = strlen(name);
  1285.     if (len<5) 
  1286.   {
  1287.         return;
  1288.     }
  1289.  
  1290.     if ( !stricmp( name+len-4, ".tga" ) ) 
  1291.   {
  1292.       LoadTGA( name, pic, width, height );
  1293.     }
  1294.   else if ( !stricmp(name+len-4, ".pcx") ) 
  1295.   {
  1296.     LoadPCX32( name, pic, width, height );
  1297.     } 
  1298.   else if ( !stricmp( name+len-4, ".bmp" ) ) 
  1299.   {
  1300.         LoadBMP( name, pic, width, height );
  1301.     } 
  1302.   else if ( !stricmp( name+len-4, ".jpg" ) ) 
  1303.   {
  1304.         LoadJPG( name, pic, width, height ); 
  1305.     }
  1306. }
  1307.  
  1308.