Changeset 176:d0e7145e70b7

Show
Ignore:
Timestamp:
05/13/08 17:03:53 (2 years ago)
Author:
Madtree <madtree@…>
Branch:
renderer
Message:

Split tr_image.c source file (allign with icculus sources).

Files:
5 added
6 modified

Legend:

Unmodified
Added
Removed
  • Makefile

    r34 r176  
    10501050  \ 
    10511051  $(B)/client/jcapimin.o \ 
     1052  $(B)/client/jcapistd.o \ 
    10521053  $(B)/client/jchuff.o   \ 
    10531054  $(B)/client/jcinit.o \ 
     
    10921093  $(B)/client/tr_font.o \ 
    10931094  $(B)/client/tr_image.o \ 
     1095  $(B)/client/tr_image_png.o \ 
     1096  $(B)/client/tr_image_jpg.o \ 
     1097  $(B)/client/tr_image_bmp.o \ 
     1098  $(B)/client/tr_image_tga.o \ 
     1099  $(B)/client/tr_image_pcx.o \ 
    10941100  $(B)/client/tr_init.o \ 
    10951101  $(B)/client/tr_light.o \ 
  • src/jpeg-6/jdatasrc.c

    r0 r121  
    2121#include "jerror.h" 
    2222 
     23#ifndef MIN 
     24#define MIN(a, b) ((a)<(b)?(a):(b)) 
     25#endif 
     26 
    2327 
    2428/* Expanded data source object for stdio input */ 
     
    2731  struct jpeg_source_mgr pub;   /* public fields */ 
    2832 
    29   unsigned char *infile;                /* source stream */ 
     33  unsigned char *inbuf;         /* source stream */ 
     34  size_t inbufbytes; 
    3035  JOCTET * buffer;              /* start of buffer */ 
    3136  boolean start_of_file;        /* have we gotten any data yet? */ 
     
    9297{ 
    9398  my_src_ptr src = (my_src_ptr) cinfo->src; 
    94  
    95   memcpy( src->buffer, src->infile, INPUT_BUF_SIZE ); 
    96  
    97   src->infile += INPUT_BUF_SIZE; 
     99  size_t nbytes = MIN(src->inbufbytes, INPUT_BUF_SIZE); 
     100 
     101  if(!nbytes) 
     102  { 
     103    WARNMS(cinfo, JWRN_JPEG_EOF); 
     104    /* Insert a fake EOI marker */ 
     105    src->buffer[0] = (JOCTET) 0xFF; 
     106    src->buffer[1] = (JOCTET) JPEG_EOI; 
     107    nbytes = 2; 
     108  } 
     109  else 
     110  { 
     111    memcpy( src->buffer, src->inbuf, nbytes); 
     112 
     113    src->inbuf += nbytes; 
     114    src->inbufbytes -= nbytes; 
     115  } 
    98116 
    99117  src->pub.next_input_byte = src->buffer; 
    100   src->pub.bytes_in_buffer = INPUT_BUF_SIZE; 
     118  src->pub.bytes_in_buffer = nbytes; 
    101119  src->start_of_file = FALSE; 
    102120 
     
    172190 
    173191GLOBAL void 
    174 jpeg_stdio_src (j_decompress_ptr cinfo, unsigned char *infile) 
     192jpeg_mem_src (j_decompress_ptr cinfo, unsigned char *inbuf, size_t size) 
    175193{ 
    176194  my_src_ptr src; 
     
    199217  src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ 
    200218  src->pub.term_source = term_source; 
    201   src->infile = infile; 
     219  src->inbuf = inbuf; 
     220  src->inbufbytes = size; 
    202221  src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ 
    203222  src->pub.next_input_byte = NULL; /* until buffer loaded */ 
  • src/jpeg-6/jpeglib.h

    r0 r121  
    875875/* Caller is responsible for opening the file before and closing after. */ 
    876876EXTERN void jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile)); 
    877 EXTERN void jpeg_stdio_src JPP((j_decompress_ptr cinfo, unsigned char *infile)); 
     877EXTERN void jpeg_mem_src JPP((j_decompress_ptr cinfo, unsigned char *buffer, size_t size)); 
    878878 
    879879/* Default parameter setup for compression */ 
  • src/qcommon/qfiles.h

    r0 r176  
    7070        int             jtrgLength;                     // number of jump table targets 
    7171} vmHeader_t; 
    72  
    73  
    74 /* 
    75 ======================================================================== 
    76  
    77 PCX files are used for 8 bit images 
    78  
    79 ======================================================================== 
    80 */ 
    81  
    82 typedef struct { 
    83     char        manufacturer; 
    84     char        version; 
    85     char        encoding; 
    86     char        bits_per_pixel; 
    87     unsigned short      xmin,ymin,xmax,ymax; 
    88     unsigned short      hres,vres; 
    89     unsigned char       palette[48]; 
    90     char        reserved; 
    91     char        color_planes; 
    92     unsigned short      bytes_per_line; 
    93     unsigned short      palette_type; 
    94     char        filler[58]; 
    95     unsigned char       data;                   // unbounded 
    96 } pcx_t; 
    97  
    98  
    99 /* 
    100 ======================================================================== 
    101  
    102 TGA files are used for 24/32 bit images 
    103  
    104 ======================================================================== 
    105 */ 
    106  
    107 typedef struct _TargaHeader { 
    108         unsigned char   id_length, colormap_type, image_type; 
    109         unsigned short  colormap_index, colormap_length; 
    110         unsigned char   colormap_size; 
    111         unsigned short  x_origin, y_origin, width, height; 
    112         unsigned char   pixel_size, attributes; 
    113 } TargaHeader; 
    11472 
    11573 
  • src/renderer/tr_image.c

    r163 r176  
    2424#include "tr_local.h" 
    2525 
    26 /* 
    27  * Include file for users of JPEG library. 
    28  * You will need to have included system headers that define at least 
    29  * the typedefs FILE and size_t before you can include jpeglib.h. 
    30  * (stdio.h is sufficient on ANSI-conforming systems.) 
    31  * You may also wish to include "jerror.h". 
    32  */ 
    33  
    34 #define JPEG_INTERNALS 
    35 #include "../jpeg-6/jpeglib.h" 
    36  
    37 #include "../qcommon/puff.h" 
    38  
    39  
    40 static void LoadBMP( const char *name, byte **pic, int *width, int *height ); 
    41 static void LoadTGA( const char *name, byte **pic, int *width, int *height ); 
    42 static void LoadJPG( const char *name, byte **pic, int *width, int *height ); 
    43 static void LoadPNG( const char *name, byte **pic, int *width, int *height ); 
    4426 
    4527static byte                      s_intensitytable[256]; 
     
    822804 
    823805 
    824 /* 
    825 ========================================================= 
    826  
    827 BMP LOADING 
    828  
    829 ========================================================= 
    830 */ 
    831 typedef struct 
    832 { 
    833         char id[2]; 
    834         unsigned long fileSize; 
    835         unsigned long reserved0; 
    836         unsigned long bitmapDataOffset; 
    837         unsigned long bitmapHeaderSize; 
    838         unsigned long width; 
    839         unsigned long height; 
    840         unsigned short planes; 
    841         unsigned short bitsPerPixel; 
    842         unsigned long compression; 
    843         unsigned long bitmapDataSize; 
    844         unsigned long hRes; 
    845         unsigned long vRes; 
    846         unsigned long colors; 
    847         unsigned long importantColors; 
    848         unsigned char palette[256][4]; 
    849 } BMPHeader_t; 
    850  
    851 static void LoadBMP( const char *name, byte **pic, int *width, int *height ) 
    852 { 
    853         int             columns, rows; 
    854         unsigned        numPixels; 
    855         byte    *pixbuf; 
    856         int             row, column; 
    857         byte    *buf_p; 
    858         byte    *buffer; 
    859         int             length; 
    860         BMPHeader_t bmpHeader; 
    861         byte            *bmpRGBA; 
    862  
    863         *pic = NULL; 
    864  
    865         // 
    866         // load the file 
    867         // 
    868         length = ri.FS_ReadFile( ( char * ) name, (void **)&buffer); 
    869         if (!buffer) { 
    870                 return; 
    871         } 
    872  
    873         buf_p = buffer; 
    874  
    875         bmpHeader.id[0] = *buf_p++; 
    876         bmpHeader.id[1] = *buf_p++; 
    877         bmpHeader.fileSize = LittleLong( * ( long * ) buf_p ); 
    878         buf_p += 4; 
    879         bmpHeader.reserved0 = LittleLong( * ( long * ) buf_p ); 
    880         buf_p += 4; 
    881         bmpHeader.bitmapDataOffset = LittleLong( * ( long * ) buf_p ); 
    882         buf_p += 4; 
    883         bmpHeader.bitmapHeaderSize = LittleLong( * ( long * ) buf_p ); 
    884         buf_p += 4; 
    885         bmpHeader.width = LittleLong( * ( long * ) buf_p ); 
    886         buf_p += 4; 
    887         bmpHeader.height = LittleLong( * ( long * ) buf_p ); 
    888         buf_p += 4; 
    889         bmpHeader.planes = LittleShort( * ( short * ) buf_p ); 
    890         buf_p += 2; 
    891         bmpHeader.bitsPerPixel = LittleShort( * ( short * ) buf_p ); 
    892         buf_p += 2; 
    893         bmpHeader.compression = LittleLong( * ( long * ) buf_p ); 
    894         buf_p += 4; 
    895         bmpHeader.bitmapDataSize = LittleLong( * ( long * ) buf_p ); 
    896         buf_p += 4; 
    897         bmpHeader.hRes = LittleLong( * ( long * ) buf_p ); 
    898         buf_p += 4; 
    899         bmpHeader.vRes = LittleLong( * ( long * ) buf_p ); 
    900         buf_p += 4; 
    901         bmpHeader.colors = LittleLong( * ( long * ) buf_p ); 
    902         buf_p += 4; 
    903         bmpHeader.importantColors = LittleLong( * ( long * ) buf_p ); 
    904         buf_p += 4; 
    905  
    906         Com_Memcpy( bmpHeader.palette, buf_p, sizeof( bmpHeader.palette ) ); 
    907  
    908         if ( bmpHeader.bitsPerPixel == 8 ) 
    909                 buf_p += 1024; 
    910  
    911         if ( bmpHeader.id[0] != 'B' && bmpHeader.id[1] != 'M' )  
    912         { 
    913                 ri.Error( ERR_DROP, "LoadBMP: only Windows-style BMP files supported (%s)\n", name ); 
    914         } 
    915         if ( bmpHeader.fileSize != length ) 
    916         { 
    917                 ri.Error( ERR_DROP, "LoadBMP: header size does not match file size (%d vs. %d) (%s)\n", bmpHeader.fileSize, length, name ); 
    918         } 
    919         if ( bmpHeader.compression != 0 ) 
    920         { 
    921                 ri.Error( ERR_DROP, "LoadBMP: only uncompressed BMP files supported (%s)\n", name ); 
    922         } 
    923         if ( bmpHeader.bitsPerPixel < 8 ) 
    924         { 
    925                 ri.Error( ERR_DROP, "LoadBMP: monochrome and 4-bit BMP files not supported (%s)\n", name ); 
    926         } 
    927  
    928         columns = bmpHeader.width; 
    929         rows = bmpHeader.height; 
    930         if ( rows < 0 ) 
    931                 rows = -rows; 
    932         numPixels = columns * rows; 
    933  
    934         if(columns <= 0 || !rows || numPixels > 0x1FFFFFFF // 4*1FFFFFFF == 0x7FFFFFFC < 0x7FFFFFFF 
    935             || ((numPixels * 4) / columns) / 4 != rows) 
    936         { 
    937           ri.Error (ERR_DROP, "LoadBMP: %s has an invalid image size\n", name); 
    938         } 
    939  
    940         if ( width )  
    941                 *width = columns; 
    942         if ( height ) 
    943                 *height = rows; 
    944  
    945         bmpRGBA = ri.Malloc( numPixels * 4 ); 
    946         *pic = bmpRGBA; 
    947  
    948  
    949         for ( row = rows-1; row >= 0; row-- ) 
    950         { 
    951                 pixbuf = bmpRGBA + row*columns*4; 
    952  
    953                 for ( column = 0; column < columns; column++ ) 
    954                 { 
    955                         unsigned char red, green, blue, alpha; 
    956                         int palIndex; 
    957                         unsigned short shortPixel; 
    958  
    959                         switch ( bmpHeader.bitsPerPixel ) 
    960                         { 
    961                         case 8: 
    962                                 palIndex = *buf_p++; 
    963                                 *pixbuf++ = bmpHeader.palette[palIndex][2]; 
    964                                 *pixbuf++ = bmpHeader.palette[palIndex][1]; 
    965                                 *pixbuf++ = bmpHeader.palette[palIndex][0]; 
    966                                 *pixbuf++ = 0xff; 
    967                                 break; 
    968                         case 16: 
    969                                 shortPixel = * ( unsigned short * ) pixbuf; 
    970                                 pixbuf += 2; 
    971                                 *pixbuf++ = ( shortPixel & ( 31 << 10 ) ) >> 7; 
    972                                 *pixbuf++ = ( shortPixel & ( 31 << 5 ) ) >> 2; 
    973                                 *pixbuf++ = ( shortPixel & ( 31 ) ) << 3; 
    974                                 *pixbuf++ = 0xff; 
    975                                 break; 
    976  
    977                         case 24: 
    978                                 blue = *buf_p++; 
    979                                 green = *buf_p++; 
    980                                 red = *buf_p++; 
    981                                 *pixbuf++ = red; 
    982                                 *pixbuf++ = green; 
    983                                 *pixbuf++ = blue; 
    984                                 *pixbuf++ = 255; 
    985                                 break; 
    986                         case 32: 
    987                                 blue = *buf_p++; 
    988                                 green = *buf_p++; 
    989                                 red = *buf_p++; 
    990                                 alpha = *buf_p++; 
    991                                 *pixbuf++ = red; 
    992                                 *pixbuf++ = green; 
    993                                 *pixbuf++ = blue; 
    994                                 *pixbuf++ = alpha; 
    995                                 break; 
    996                         default: 
    997                                 ri.Error( ERR_DROP, "LoadBMP: illegal pixel_size '%d' in file '%s'\n", bmpHeader.bitsPerPixel, name ); 
    998                                 break; 
    999                         } 
    1000                 } 
    1001         } 
    1002  
    1003         ri.FS_FreeFile( buffer ); 
    1004  
    1005 } 
    1006  
    1007  
    1008 /* 
    1009 ================================================================= 
    1010  
    1011 PCX LOADING 
    1012  
    1013 ================================================================= 
    1014 */ 
    1015  
    1016  
    1017 /* 
    1018 ============== 
    1019 LoadPCX 
    1020 ============== 
    1021 */ 
    1022 static void LoadPCX ( const char *filename, byte **pic, byte **palette, int *width, int *height) 
    1023 { 
    1024         byte    *raw; 
    1025         pcx_t   *pcx; 
    1026         int             x, y; 
    1027         int             len; 
    1028         int             dataByte, runLength; 
    1029         byte    *out, *pix; 
    1030         unsigned                xmax, ymax; 
    1031  
    1032         *pic = NULL; 
    1033         *palette = NULL; 
    1034  
    1035         // 
    1036         // load the file 
    1037         // 
    1038         len = ri.FS_ReadFile( ( char * ) filename, (void **)&raw); 
    1039         if (!raw) { 
    1040                 return; 
    1041         } 
    1042  
    1043         // 
    1044         // parse the PCX file 
    1045         // 
    1046         pcx = (pcx_t *)raw; 
    1047         raw = &pcx->data; 
    1048  
    1049         xmax = LittleShort(pcx->xmax); 
    1050     ymax = LittleShort(pcx->ymax); 
    1051  
    1052         if (pcx->manufacturer != 0x0a 
    1053                 || pcx->version != 5 
    1054                 || pcx->encoding != 1 
    1055                 || pcx->bits_per_pixel != 8 
    1056                 || xmax >= 1024 
    1057                 || ymax >= 1024) 
    1058         { 
    1059                 ri.Printf (PRINT_ALL, "Bad pcx file %s (%i x %i) (%i x %i)\n", filename, xmax+1, ymax+1, pcx->xmax, pcx->ymax); 
    1060                 return; 
    1061         } 
    1062  
    1063         out = ri.Malloc ( (ymax+1) * (xmax+1) ); 
    1064  
    1065         *pic = out; 
    1066  
    1067         pix = out; 
    1068  
    1069         if (palette) 
    1070         { 
    1071                 *palette = ri.Malloc(768); 
    1072                 Com_Memcpy (*palette, (byte *)pcx + len - 768, 768); 
    1073         } 
    1074  
    1075         if (width) 
    1076                 *width = xmax+1; 
    1077         if (height) 
    1078                 *height = ymax+1; 
    1079 // FIXME: use bytes_per_line here? 
    1080  
    1081         for (y=0 ; y<=ymax ; y++, pix += xmax+1) 
    1082         { 
    1083                 for (x=0 ; x<=xmax ; ) 
    1084                 { 
    1085                         dataByte = *raw++; 
    1086  
    1087                         if((dataByte & 0xC0) == 0xC0) 
    1088                         { 
    1089                                 runLength = dataByte & 0x3F; 
    1090                                 dataByte = *raw++; 
    1091                         } 
    1092                         else 
    1093                                 runLength = 1; 
    1094  
    1095                         while(runLength-- > 0) 
    1096                                 pix[x++] = dataByte; 
    1097                 } 
    1098  
    1099         } 
    1100  
    1101         if ( raw - (byte *)pcx > len) 
    1102         { 
    1103                 ri.Printf (PRINT_DEVELOPER, "PCX file %s was malformed", filename); 
    1104                 ri.Free (*pic); 
    1105                 *pic = NULL; 
    1106         } 
    1107  
    1108         ri.FS_FreeFile (pcx); 
    1109 } 
    1110  
    1111  
    1112 /* 
    1113 ============== 
    1114 LoadPCX32 
    1115 ============== 
    1116 */ 
    1117 static void LoadPCX32 ( const char *filename, byte **pic, int *width, int *height) { 
    1118         byte    *palette; 
    1119         byte    *pic8; 
    1120         int             i, c, p; 
    1121         byte    *pic32; 
    1122  
    1123         LoadPCX (filename, &pic8, &palette, width, height); 
    1124         if (!pic8) { 
    1125                 *pic = NULL; 
    1126                 return; 
    1127         } 
    1128  
    1129         // LoadPCX32 ensures width, height < 1024 
    1130         c = (*width) * (*height); 
    1131         pic32 = *pic = ri.Malloc(4 * c ); 
    1132         for (i = 0 ; i < c ; i++) { 
    1133                 p = pic8[i]; 
    1134                 pic32[0] = palette[p*3]; 
    1135                 pic32[1] = palette[p*3 + 1]; 
    1136                 pic32[2] = palette[p*3 + 2]; 
    1137                 pic32[3] = 255; 
    1138                 pic32 += 4; 
    1139         } 
    1140  
    1141         ri.Free (pic8); 
    1142         ri.Free (palette); 
    1143 } 
    1144  
    1145 /* 
    1146 ========================================================= 
    1147  
    1148 TARGA LOADING 
    1149  
    1150 ========================================================= 
    1151 */ 
    1152  
    1153 /* 
    1154 ============= 
    1155 LoadTGA 
    1156 ============= 
    1157 */ 
    1158 static void LoadTGA ( const char *name, byte **pic, int *width, int *height) 
    1159 { 
    1160         unsigned        columns, rows, numPixels; 
    1161         byte    *pixbuf; 
    1162         int             row, column; 
    1163         byte    *buf_p; 
    1164         byte    *buffer; 
    1165         TargaHeader     targa_header; 
    1166         byte            *targa_rgba; 
    1167  
    1168         *pic = NULL; 
    1169  
    1170         // 
    1171         // load the file 
    1172         // 
    1173         ri.FS_ReadFile ( ( char * ) name, (void **)&buffer); 
    1174         if (!buffer) { 
    1175                 return; 
    1176         } 
    1177  
    1178         buf_p = buffer; 
    1179  
    1180         targa_header.id_length = buf_p[0]; 
    1181         targa_header.colormap_type = buf_p[1]; 
    1182         targa_header.image_type = buf_p[2]; 
    1183          
    1184         memcpy(&targa_header.colormap_index, &buf_p[3], 2); 
    1185         memcpy(&targa_header.colormap_length, &buf_p[5], 2); 
    1186         targa_header.colormap_size = buf_p[7]; 
    1187         memcpy(&targa_header.x_origin, &buf_p[8], 2); 
    1188         memcpy(&targa_header.y_origin, &buf_p[10], 2); 
    1189         memcpy(&targa_header.width, &buf_p[12], 2); 
    1190         memcpy(&targa_header.height, &buf_p[14], 2); 
    1191         targa_header.pixel_size = buf_p[16]; 
    1192         targa_header.attributes = buf_p[17]; 
    1193  
    1194         targa_header.colormap_index = LittleShort(targa_header.colormap_index); 
    1195         targa_header.colormap_length = LittleShort(targa_header.colormap_length); 
    1196         targa_header.x_origin = LittleShort(targa_header.x_origin); 
    1197         targa_header.y_origin = LittleShort(targa_header.y_origin); 
    1198         targa_header.width = LittleShort(targa_header.width); 
    1199         targa_header.height = LittleShort(targa_header.height); 
    1200  
    1201         buf_p += 18; 
    1202  
    1203         if (targa_header.image_type!=2  
    1204                 && targa_header.image_type!=10 
    1205                 && targa_header.image_type != 3 )  
    1206         { 
    1207                 ri.Error (ERR_DROP, "LoadTGA: Only type 2 (RGB), 3 (gray), and 10 (RGB) TGA images supported\n"); 
    1208         } 
    1209  
    1210         if ( targa_header.colormap_type != 0 ) 
    1211         { 
    1212                 ri.Error( ERR_DROP, "LoadTGA: colormaps not supported\n" ); 
    1213         } 
    1214  
    1215         if ( ( targa_header.pixel_size != 32 && targa_header.pixel_size != 24 ) && targa_header.image_type != 3 ) 
    1216         { 
    1217                 ri.Error (ERR_DROP, "LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n"); 
    1218         } 
    1219  
    1220         columns = targa_header.width; 
    1221         rows = targa_header.height; 
    1222         numPixels = columns * rows * 4; 
    1223  
    1224         if (width) 
    1225                 *width = columns; 
    1226         if (height) 
    1227                 *height = rows; 
    1228  
    1229         if(!columns || !rows || numPixels > 0x7FFFFFFF || numPixels / columns / 4 != rows) 
    1230         { 
    1231                 ri.Error (ERR_DROP, "LoadTGA: %s has an invalid image size\n", name); 
    1232         } 
    1233  
    1234         targa_rgba = ri.Malloc (numPixels); 
    1235         *pic = targa_rgba; 
    1236  
    1237         if (targa_header.id_length != 0) 
    1238                 buf_p += targa_header.id_length;  // skip TARGA image comment 
    1239          
    1240         if ( targa_header.image_type==2 || targa_header.image_type == 3 ) 
    1241         {  
    1242                 // Uncompressed RGB or gray scale image 
    1243                 for(row=rows-1; row>=0; row--)  
    1244                 { 
    1245                         pixbuf = targa_rgba + row*columns*4; 
    1246                         for(column=0; column<columns; column++)  
    1247                         { 
    1248                                 unsigned char red,green,blue,alphabyte; 
    1249                                 switch (targa_header.pixel_size)  
    1250                                 { 
    1251                                          
    1252                                 case 8: 
    1253                                         blue = *buf_p++; 
    1254                                         green = blue; 
    1255                                         red = blue; 
    1256                                         *pixbuf++ = red; 
    1257                                         *pixbuf++ = green; 
    1258                                         *pixbuf++ = blue; 
    1259                                         *pixbuf++ = 255; 
    1260                                         break; 
    1261  
    1262                                 case 24: 
    1263                                         blue = *buf_p++; 
    1264                                         green = *buf_p++; 
    1265                                         red = *buf_p++; 
    1266                                         *pixbuf++ = red; 
    1267                                         *pixbuf++ = green; 
    1268                                         *pixbuf++ = blue; 
    1269                                         *pixbuf++ = 255; 
    1270                                         break; 
    1271                                 case 32: 
    1272                                         blue = *buf_p++; 
    1273                                         green = *buf_p++; 
    1274                                         red = *buf_p++; 
    1275                                         alphabyte = *buf_p++; 
    1276                                         *pixbuf++ = red; 
    1277                                         *pixbuf++ = green; 
    1278                                         *pixbuf++ = blue; 
    1279                                         *pixbuf++ = alphabyte; 
    1280                                         break; 
    1281                                 default: 
    1282                                         ri.Error( ERR_DROP, "LoadTGA: illegal pixel_size '%d' in file '%s'\n", targa_header.pixel_size, name ); 
    1283                                         break; 
    1284                                 } 
    1285                         } 
    1286                 } 
    1287         } 
    1288         else if (targa_header.image_type==10) {   // Runlength encoded RGB images 
    1289                 unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j; 
    1290  
    1291                 red = 0; 
    1292                 green = 0; 
    1293                 blue = 0; 
    1294                 alphabyte = 0xff; 
    1295  
    1296                 for(row=rows-1; row>=0; row--) { 
    1297                         pixbuf = targa_rgba + row*columns*4; 
    1298                         for(column=0; column<columns; ) { 
    1299                                 packetHeader= *buf_p++; 
    1300                                 packetSize = 1 + (packetHeader & 0x7f); 
    1301                                 if (packetHeader & 0x80) {        // run-length packet 
    1302                                         switch (targa_header.pixel_size) { 
    1303                                                 case 24: 
    1304                                                                 blue = *buf_p++; 
    1305                                                                 green = *buf_p++; 
    1306                                                                 red = *buf_p++; 
    1307                                                                 alphabyte = 255; 
    1308                                                                 break; 
    1309                                                 case 32: 
    1310                                                                 blue = *buf_p++; 
    1311                                                                 green = *buf_p++; 
    1312                                                                 red = *buf_p++; 
    1313                                                                 alphabyte = *buf_p++; 
    1314                                                                 break; 
    1315                                                 default: 
    1316                                                         ri.Error( ERR_DROP, "LoadTGA: illegal pixel_size '%d' in file '%s'\n", targa_header.pixel_size, name ); 
    1317                                                         break; 
    1318                                         } 
    1319          
    1320                                         for(j=0;j<packetSize;j++) { 
    1321                                                 *pixbuf++=red; 
    1322                                                 *pixbuf++=green; 
    1323                                                 *pixbuf++=blue; 
    1324                                                 *pixbuf++=alphabyte; 
    1325                                                 column++; 
    1326                                                 if (column==columns) { // run spans across rows 
    1327                                                         column=0; 
    1328                                                         if (row>0) 
    1329                                                                 row--; 
    1330                                                         else 
    1331                                                                 goto breakOut; 
    1332                                                         pixbuf = targa_rgba + row*columns*4; 
    1333                                                 } 
    1334                                         } 
    1335                                 } 
    1336                                 else {                            // non run-length packet 
    1337                                         for(j=0;j<packetSize;j++) { 
    1338                                                 switch (targa_header.pixel_size) { 
    1339                                                         case 24: 
    1340                                                                         blue = *buf_p++; 
    1341                                                                         green = *buf_p++; 
    1342                                                                         red = *buf_p++; 
    1343                                                                         *pixbuf++ = red; 
    1344                                                                         *pixbuf++ = green; 
    1345                                                                         *pixbuf++ = blue; 
    1346                                                                         *pixbuf++ = 255; 
    1347                                                                         break; 
    1348                                                         case 32: 
    1349                                                                         blue = *buf_p++; 
    1350                                                                         green = *buf_p++; 
    1351                                                                         red = *buf_p++; 
    1352                                                                         alphabyte = *buf_p++; 
    1353                                                                         *pixbuf++ = red; 
    1354                                                                         *pixbuf++ = green; 
    1355                                                                         *pixbuf++ = blue; 
    1356                                                                         *pixbuf++ = alphabyte; 
    1357                                                                         break; 
    1358                                                         default: 
    1359                                                                 ri.Error( ERR_DROP, "LoadTGA: illegal pixel_size '%d' in file '%s'\n", targa_header.pixel_size, name ); 
    1360                                                                 break; 
    1361                                                 } 
    1362                                                 column++; 
    1363                                                 if (column==columns) { // pixel packet run spans across rows 
    1364                                                         column=0; 
    1365                                                         if (row>0) 
    1366                                                                 row--; 
    1367                                                         else 
    1368                                                                 goto breakOut; 
    1369                                                         pixbuf = targa_rgba + row*columns*4; 
    1370                                                 }                                                
    1371                                         } 
    1372                                 } 
    1373                         } 
    1374                         breakOut:; 
    1375                 } 
    1376         } 
    1377  
    1378 #if 0  
    1379   // TTimo: this is the chunk of code to ensure a behavior that meets TGA specs  
    1380   // bit 5 set => top-down 
    1381   if (targa_header.attributes & 0x20) { 
    1382     unsigned char *flip = (unsigned char*)malloc (columns*4); 
    1383     unsigned char *src, *dst; 
    1384  
    1385     for (row = 0; row < rows/2; row++) { 
    1386       src = targa_rgba + row * 4 * columns; 
    1387       dst = targa_rgba + (rows - row - 1) * 4 * columns; 
    1388  
    1389       memcpy (flip, src, columns*4); 
    1390       memcpy (src, dst, columns*4); 
    1391       memcpy (dst, flip, columns*4); 
    1392     } 
    1393     free (flip); 
    1394   } 
    1395 #endif 
    1396   // instead we just print a warning 
    1397   if (targa_header.attributes & 0x20) { 
    1398     ri.Printf( PRINT_WARNING, "WARNING: '%s' TGA file header declares top-down image, ignoring\n", name); 
    1399   } 
    1400  
    1401   ri.FS_FreeFile (buffer); 
    1402 } 
    1403  
    1404 static void LoadJPG( const char *filename, unsigned char **pic, int *width, int *height ) { 
    1405   /* This struct contains the JPEG decompression parameters and pointers to 
    1406    * working space (which is allocated as needed by the JPEG library). 
    1407    */ 
    1408   struct jpeg_decompress_struct cinfo = {NULL}; 
    1409   /* We use our private extension JPEG error handler. 
    1410    * Note that this struct must live as long as the main JPEG parameter 
    1411    * struct, to avoid dangling-pointer problems. 
    1412    */ 
    1413   /* This struct represents a JPEG error handler.  It is declared separately 
    1414    * because applications often want to supply a specialized error handler 
    1415    * (see the second half of this file for an example).  But here we just 
    1416    * take the easy way out and use the standard error handler, which will 
    1417    * print a message on stderr and call exit() if compression fails. 
    1418    * Note that this struct must live as long as the main JPEG parameter 
    1419    * struct, to avoid dangling-pointer problems. 
    1420    */ 
    1421   struct jpeg_error_mgr jerr; 
    1422   /* More stuff */ 
    1423   JSAMPARRAY buffer;            /* Output row buffer */ 
    1424   unsigned row_stride;          /* physical row width in output buffer */ 
    1425   unsigned pixelcount, memcount; 
    1426   unsigned char *out; 
    1427   byte  *fbuffer; 
    1428   byte  *buf; 
    1429  
    1430   /* In this example we want to open the input file before doing anything else, 
    1431    * so that the setjmp() error recovery below can assume the file is open. 
    1432    * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that 
    1433    * requires it in order to read binary files. 
    1434    */ 
    1435  
    1436   ri.FS_ReadFile ( ( char * ) filename, (void **)&fbuffer); 
    1437   if (!fbuffer) { 
    1438         return; 
    1439   } 
    1440  
    1441   /* Step 1: allocate and initialize JPEG decompression object */ 
    1442  
    1443   /* We have to set up the error handler first, in case the initialization 
    1444    * step fails.  (Unlikely, but it could happen if you are out of memory.) 
    1445    * This routine fills in the contents of struct jerr, and returns jerr's 
    1446    * address which we place into the link field in cinfo. 
    1447    */ 
    1448   cinfo.err = jpeg_std_error(&jerr); 
    1449  
    1450   /* Now we can initialize the JPEG decompression object. */ 
    1451   jpeg_create_decompress(&cinfo); 
    1452  
    1453   /* Step 2: specify data source (eg, a file) */ 
    1454  
    1455   jpeg_stdio_src(&cinfo, fbuffer); 
    1456  
    1457   /* Step 3: read file parameters with jpeg_read_header() */ 
    1458  
    1459   (void) jpeg_read_header(&cinfo, TRUE); 
    1460   /* We can ignore the return value from jpeg_read_header since 
    1461    *   (a) suspension is not possible with the stdio data source, and 
    1462    *   (b) we passed TRUE to reject a tables-only JPEG file as an error. 
    1463    * See libjpeg.doc for more info. 
    1464    */ 
    1465  
    1466   /* Step 4: set parameters for decompression */ 
    1467  
    1468   /* In this example, we don't need to change any of the defaults set by 
    1469    * jpeg_read_header(), so we do nothing here. 
    1470    */ 
    1471  
    1472   /* Step 5: Start decompressor */ 
    1473  
    1474   (void) jpeg_start_decompress(&cinfo); 
    1475   /* We can ignore the return value since suspension is not possible 
    1476    * with the stdio data source. 
    1477    */ 
    1478  
    1479   /* We may need to do some setup of our own at this point before reading 
    1480    * the data.  After jpeg_start_decompress() we have the correct scaled 
    1481    * output image dimensions available, as well as the output colormap 
    1482    * if we asked for color quantization. 
    1483    * In this example, we need to make an output work buffer of the right size. 
    1484    */  
    1485   /* JSAMPLEs per row in output buffer */ 
    1486  
    1487   pixelcount = cinfo.output_width * cinfo.output_height; 
    1488  
    1489   if(!cinfo.output_width || !cinfo.output_height 
    1490       || ((pixelcount * 4) / cinfo.output_width) / 4 != cinfo.output_height 
    1491       || pixelcount > 0x1FFFFFFF || cinfo.output_components > 4) // 4*1FFFFFFF == 0x7FFFFFFC < 0x7FFFFFFF 
    1492   { 
    1493     ri.Error (ERR_DROP, "LoadJPG: %s has an invalid image size: %dx%d*4=%d, components: %d\n", filename, 
    1494                     cinfo.output_width, cinfo.output_height, pixelcount * 4, cinfo.output_components); 
    1495   } 
    1496  
    1497   memcount = pixelcount * 4; 
    1498   row_stride = cinfo.output_width * cinfo.output_components; 
    1499  
    1500   out = ri.Malloc(memcount); 
    1501  
    1502   *width = cinfo.output_width; 
    1503   *height = cinfo.output_height; 
    1504  
    1505   /* Step 6: while (scan lines remain to be read) */ 
    1506   /*           jpeg_read_scanlines(...); */ 
    1507  
    1508   /* Here we use the library's state variable cinfo.output_scanline as the 
    1509    * loop counter, so that we don't have to keep track ourselves. 
    1510    */ 
    1511   while (cinfo.output_scanline < cinfo.output_height) { 
    1512     /* jpeg_read_scanlines expects an array of pointers to scanlines. 
    1513      * Here the array is only one element long, but you could ask for 
    1514      * more than one scanline at a time if that's more convenient. 
    1515      */ 
    1516         buf = ((out+(row_stride*cinfo.output_scanline))); 
    1517         buffer = &buf; 
    1518     (void) jpeg_read_scanlines(&cinfo, buffer, 1); 
    1519   } 
    1520    
    1521   buf = out; 
    1522  
    1523   // If we are processing an 8-bit JPEG (greyscale), we'll have to convert 
    1524   // the greyscale values to RGBA. 
    1525   if(cinfo.output_components == 1) 
    1526   { 
    1527         int sindex = pixelcount, dindex = memcount; 
    1528         unsigned char greyshade; 
    1529  
    1530         // Only pixelcount number of bytes have been written. 
    1531         // Expand the color values over the rest of the buffer, starting 
    1532         // from the end. 
    1533         do 
    1534         { 
    1535                 greyshade = buf[--sindex]; 
    1536  
    1537                 buf[--dindex] = 255; 
    1538                 buf[--dindex] = greyshade; 
    1539                 buf[--dindex] = greyshade; 
    1540                 buf[--dindex] = greyshade; 
    1541         } while(sindex); 
    1542   } 
    1543   else 
    1544   { 
    1545         // clear all the alphas to 255 
    1546         int     i; 
    1547  
    1548         for ( i = 3 ; i < memcount ; i+=4 ) 
    1549         { 
    1550                 buf[i] = 255; 
    1551         } 
    1552   } 
    1553  
    1554   *pic = out; 
    1555  
    1556   /* Step 7: Finish decompression */ 
    1557  
    1558   (void) jpeg_finish_decompress(&cinfo); 
    1559   /* We can ignore the return value since suspension is not possible 
    1560    * with the stdio data source. 
    1561    */ 
    1562  
    1563   /* Step 8: Release JPEG decompression object */ 
    1564  
    1565   /* This is an important step since it will release a good deal of memory. */ 
    1566   jpeg_destroy_decompress(&cinfo); 
    1567  
    1568   /* After finish_decompress, we can close the input file. 
    1569    * Here we postpone it until after no more JPEG errors are possible, 
    1570    * so as to simplify the setjmp error logic above.  (Actually, I don't 
    1571    * think that jpeg_destroy can do an error exit, but why assume anything...) 
    1572    */ 
    1573   ri.FS_FreeFile (fbuffer); 
    1574  
    1575   /* At this point you may want to check to see whether any corrupt-data 
    1576    * warnings occurred (test whether jerr.pub.num_warnings is nonzero). 
    1577    */ 
    1578  
    1579   /* And we're done! */ 
    1580 } 
    1581  
    1582  
    1583 /* Expanded data destination object for stdio output */ 
    1584  
    1585 typedef struct { 
    1586   struct jpeg_destination_mgr pub; /* public fields */ 
    1587  
    1588   byte* outfile;                /* target stream */ 
    1589   int   size; 
    1590 } my_destination_mgr; 
    1591  
    1592 typedef my_destination_mgr * my_dest_ptr; 
    1593  
    1594  
    1595 /* 
    1596  * Initialize destination --- called by jpeg_start_compress 
    1597  * before any data is actually written. 
    1598  */ 
    1599  
    1600 void init_destination (j_compress_ptr cinfo) 
    1601 { 
    1602   my_dest_ptr dest = (my_dest_ptr) cinfo->dest; 
    1603  
    1604   dest->pub.next_output_byte = dest->outfile; 
    1605   dest->pub.free_in_buffer = dest->size; 
    1606 } 
    1607  
    1608  
    1609 /* 
    1610  * Empty the output buffer --- called whenever buffer fills up. 
    1611  * 
    1612  * In typical applications, this should write the entire output buffer 
    1613  * (ignoring the current state of next_output_byte & free_in_buffer), 
    1614  * reset the pointer & count to the start of the buffer, and return TRUE 
    1615  * indicating that the buffer has been dumped. 
    1616  * 
    1617  * In applications that need to be able to suspend compression due to output 
    1618  * overrun, a FALSE return indicates that the buffer cannot be emptied now. 
    1619  * In this situation, the compressor will return to its caller (possibly with 
    1620  * an indication that it has not accepted all the supplied scanlines).  The 
    1621  * application should resume compression after it has made more room in the 
    1622  * output buffer.  Note that there are substantial restrictions on the use of 
    1623  * suspension --- see the documentation. 
    1624  * 
    1625  * When suspending, the compressor will back up to a convenient restart point 
    1626  * (typically the start of the current MCU). next_output_byte & free_in_buffer 
    1627  * indicate where the restart point will be if the current call returns FALSE. 
    1628  * Data beyond this point will be regenerated after resumption, so do not 
    1629  * write it out when emptying the buffer externally. 
    1630  */ 
    1631  
    1632 boolean empty_output_buffer (j_compress_ptr cinfo) 
    1633 { 
    1634   return TRUE; 
    1635 } 
    1636  
    1637  
    1638 /* 
    1639  * Compression initialization. 
    1640  * Before calling this, all parameters and a data destination must be set up. 
    1641  * 
    1642  * We require a write_all_tables parameter as a failsafe check when writing 
    1643  * multiple datastreams from the same compression object.  Since prior runs 
    1644  * will have left all the tables marked sent_table=TRUE, a subsequent run 
    1645  * would emit an abbreviated stream (no tables) by default.  This may be what 
    1646  * is wanted, but for safety's sake it should not be the default behavior: 
    1647  * programmers should have to make a deliberate choice to emit abbreviated 
    1648  * images.  Therefore the documentation and examples should encourage people 
    1649  * to pass write_all_tables=TRUE; then it will take active thought to do the 
    1650  * wrong thing. 
    1651  */ 
    1652  
    1653 GLOBAL void 
    1654 jpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables) 
    1655 { 
    1656   if (cinfo->global_state != CSTATE_START) 
    1657     ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); 
    1658  
    1659   if (write_all_tables) 
    1660     jpeg_suppress_tables(cinfo, FALSE); /* mark all tables to be written */ 
    1661  
    1662   /* (Re)initialize error mgr and destination modules */ 
    1663   (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo); 
    1664   (*cinfo->dest->init_destination) (cinfo); 
    1665   /* Perform master selection of active modules */ 
    1666   jinit_compress_master(cinfo); 
    1667   /* Set up for the first pass */ 
    1668   (*cinfo->master->prepare_for_pass) (cinfo); 
    1669   /* Ready for application to drive first pass through jpeg_write_scanlines 
    1670    * or jpeg_write_raw_data. 
    1671    */ 
    1672   cinfo->next_scanline = 0; 
    1673   cinfo->global_state = (cinfo->raw_data_in ? CSTATE_RAW_OK : CSTATE_SCANNING); 
    1674 } 
    1675  
    1676  
    1677 /* 
    1678  * Write some scanlines of data to the JPEG compressor. 
    1679  * 
    1680  * The return value will be the number of lines actually written. 
    1681  * This should be less than the supplied num_lines only in case that 
    1682  * the data destination module has requested suspension of the compressor, 
    1683  * or if more than image_height scanlines are passed in. 
    1684  * 
    1685  * Note: we warn about excess calls to jpeg_write_scanlines() since 
    1686  * this likely signals an application programmer error.  However, 
    1687  * excess scanlines passed in the last valid call are *silently* ignored, 
    1688  * so that the application need not adjust num_lines for end-of-image 
    1689  * when using a multiple-scanline buffer. 
    1690  */ 
    1691  
    1692 GLOBAL JDIMENSION 
    1693 jpeg_write_scanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines, 
    1694                       JDIMENSION num_lines) 
    1695 { 
    1696   JDIMENSION row_ctr, rows_left; 
    1697  
    1698   if (cinfo->global_state != CSTATE_SCANNING) 
    1699     ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); 
    1700   if (cinfo->next_scanline >= cinfo->image_height) 
    1701     WARNMS(cinfo, JWRN_TOO_MUCH_DATA); 
    1702  
    1703   /* Call progress monitor hook if present */ 
    1704   if (cinfo->progress != NULL) { 
    1705     cinfo->progress->pass_counter = (long) cinfo->next_scanline; 
    1706     cinfo->progress->pass_limit = (long) cinfo->image_height; 
    1707     (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); 
    1708   } 
    1709  
    1710   /* Give master control module another chance if this is first call to 
    1711    * jpeg_write_scanlines.  This lets output of the frame/scan headers be 
    1712    * delayed so that application can write COM, etc, markers between 
    1713    * jpeg_start_compress and jpeg_write_scanlines. 
    1714    */ 
    1715   if (cinfo->master->call_pass_startup) 
    1716     (*cinfo->master->pass_startup) (cinfo); 
    1717  
    1718   /* Ignore any extra scanlines at bottom of image. */ 
    1719   rows_left = cinfo->image_height - cinfo->next_scanline; 
    1720   if (num_lines > rows_left) 
    1721     num_lines = rows_left; 
    1722  
    1723   row_ctr = 0; 
    1724   (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, num_lines); 
    1725   cinfo->next_scanline += row_ctr; 
    1726   return row_ctr; 
    1727 } 
    1728  
    1729 /* 
    1730  * Terminate destination --- called by jpeg_finish_compress 
    1731  * after all data has been written.  Usually needs to flush buffer. 
    1732  * 
    1733  * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding 
    1734  * application must deal with any cleanup that should happen even 
    1735  * for error exit. 
    1736  */ 
    1737  
    1738 static int hackSize; 
    1739  
    1740 void term_destination (j_compress_ptr cinfo) 
    1741 { 
    1742   my_dest_ptr dest = (my_dest_ptr) cinfo->dest; 
    1743   size_t datacount = dest->size - dest->pub.free_in_buffer; 
    1744   hackSize = datacount; 
    1745 } 
    1746  
    1747  
    1748 /* 
    1749  * Prepare for output to a stdio stream. 
    1750  * The caller must have already opened the stream, and is responsible 
    1751  * for closing it after finishing compression. 
    1752  */ 
    1753  
    1754 void jpegDest (j_compress_ptr cinfo, byte* outfile, int size) 
    1755 { 
    1756   my_dest_ptr dest; 
    1757  
    1758   /* The destination object is made permanent so that multiple JPEG images 
    1759    * can be written to the same file without re-executing jpeg_stdio_dest. 
    1760    * This makes it dangerous to use this manager and a different destination 
    1761    * manager serially with the same JPEG object, because their private object 
    1762    * sizes may be different.  Caveat programmer. 
    1763    */ 
    1764   if (cinfo->dest == NULL) {    /* first time for this JPEG object? */ 
    1765     cinfo->dest = (struct jpeg_destination_mgr *) 
    1766       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, 
    1767                                   sizeof(my_destination_mgr)); 
    1768   } 
    1769  
    1770   dest = (my_dest_ptr) cinfo->dest; 
    1771   dest->pub.init_destination = init_destination; 
    1772   dest->pub.empty_output_buffer = empty_output_buffer; 
    1773   dest->pub.term_destination = term_destination; 
    1774   dest->outfile = outfile; 
    1775   dest->size = size; 
    1776 } 
    1777  
    1778 void SaveJPG(char * filename, int quality, int image_width, int image_height, unsigned char *image_buffer) { 
    1779   /* This struct contains the JPEG compression parameters and pointers to 
    1780    * working space (which is allocated as needed by the JPEG library). 
    1781    * It is possible to have several such structures, representing multiple 
    1782    * compression/decompression processes, in existence at once.  We refer 
    1783    * to any one struct (and its associated working data) as a "JPEG object". 
    1784    */ 
    1785   struct jpeg_compress_struct cinfo; 
    1786   /* This struct represents a JPEG error handler.  It is declared separately 
    1787    * because applications often want to supply a specialized error handler 
    1788    * (see the second half of this file for an example).  But here we just 
    1789    * take the easy way out and use the standard error handler, which will 
    1790    * print a message on stderr and call exit() if compression fails. 
    1791    * Note that this struct must live as long as the main JPEG parameter 
    1792    * struct, to avoid dangling-pointer problems. 
    1793    */ 
    1794   struct jpeg_error_mgr jerr; 
    1795   /* More stuff */ 
    1796   JSAMPROW row_pointer[1];      /* pointer to JSAMPLE row[s] */ 
    1797   int row_stride;               /* physical row width in image buffer */ 
    1798   unsigned char *out; 
    1799  
    1800   /* Step 1: allocate and initialize JPEG compression object */ 
    1801  
    1802   /* We have to set up the error handler first, in case the initialization 
    1803    * step fails.  (Unlikely, but it could happen if you are out of memory.) 
    1804    * This routine fills in the contents of struct jerr, and returns jerr's 
    1805    * address which we place into the link field in cinfo. 
    1806    */ 
    1807   cinfo.err = jpeg_std_error(&jerr); 
    1808   /* Now we can initialize the JPEG compression object. */ 
    1809   jpeg_create_compress(&cinfo); 
    1810  
    1811   /* Step 2: specify data destination (eg, a file) */ 
    1812   /* Note: steps 2 and 3 can be done in either order. */ 
    1813  
    1814   /* Here we use the library-supplied code to send compressed data to a 
    1815    * stdio stream.  You can also write your own code to do something else. 
    1816    * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that 
    1817    * requires it in order to write binary files. 
    1818    */ 
    1819   out = ri.Hunk_AllocateTempMemory(image_width*image_height*4); 
    1820   jpegDest(&cinfo, out, image_width*image_height*4); 
    1821  
    1822   /* Step 3: set parameters for compression */ 
    1823  
    1824   /* First we supply a description of the input image. 
    1825    * Four fields of the cinfo struct must be filled in: 
    1826    */ 
    1827   cinfo.image_width = image_width;      /* image width and height, in pixels */ 
    1828   cinfo.image_height = image_height; 
    1829   cinfo.input_components = 4;           /* # of color components per pixel */ 
    1830   cinfo.in_color_space = JCS_RGB;       /* colorspace of input image */ 
    1831   /* Now use the library's routine to set default compression parameters. 
    1832    * (You must set at least cinfo.in_color_space before calling this, 
    1833    * since the defaults depend on the source color space.) 
    1834    */ 
    1835   jpeg_set_defaults(&cinfo); 
    1836   /* Now you can set any non-default parameters you wish to. 
    1837    * Here we just illustrate the use of quality (quantization table) scaling: 
    1838    */ 
    1839   jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */); 
    1840   /* If quality is set high, disable chroma subsampling */ 
    1841   if (quality >= 85) { 
    1842     cinfo.comp_info[0].h_samp_factor = 1; 
    1843     cinfo.comp_info[0].v_samp_factor = 1; 
    1844   } 
    1845  
    1846   /* Step 4: Start compressor */ 
    1847  
    1848   /* TRUE ensures that we will write a complete interchange-JPEG file. 
    1849    * Pass TRUE unless you are very sure of what you're doing. 
    1850    */ 
    1851   jpeg_start_compress(&cinfo, TRUE); 
    1852  
    1853   /* Step 5: while (scan lines remain to be written) */ 
    1854   /*           jpeg_write_scanlines(...); */ 
    1855  
    1856   /* Here we use the library's state variable cinfo.next_scanline as the 
    1857    * loop counter, so that we don't have to keep track ourselves. 
    1858    * To keep things simple, we pass one scanline per call; you can pass 
    1859    * more if you wish, though. 
    1860    */ 
    1861   row_stride = image_width * 4; /* JSAMPLEs per row in image_buffer */ 
    1862  
    1863   while (cinfo.next_scanline < cinfo.image_height) { 
    1864     /* jpeg_write_scanlines expects an array of pointers to scanlines. 
    1865      * Here the array is only one element long, but you could pass 
    1866      * more than one scanline at a time if that's more convenient. 
    1867      */ 
    1868     row_pointer[0] = & image_buffer[((cinfo.image_height-1)*row_stride)-cinfo.next_scanline * row_stride]; 
    1869     (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); 
    1870   } 
    1871  
    1872   /* Step 6: Finish compression */ 
    1873  
    1874   jpeg_finish_compress(&cinfo); 
    1875   /* After finish_compress, we can close the output file. */ 
    1876   ri.FS_WriteFile( filename, out, hackSize ); 
    1877  
    1878   ri.Hunk_FreeTempMemory(out); 
    1879  
    1880   /* Step 7: release JPEG compression object */ 
    1881  
    1882   /* This is an important step since it will release a good deal of memory. */ 
    1883   jpeg_destroy_compress(&cinfo); 
    1884  
    1885   /* And we're done! */ 
    1886 } 
    1887  
    1888 /* 
    1889 ================= 
    1890 SaveJPGToBuffer 
    1891 ================= 
    1892 */ 
    1893 int SaveJPGToBuffer( byte *buffer, int quality, 
    1894     int image_width, int image_height, 
    1895     byte *image_buffer ) 
    1896 { 
    1897   struct jpeg_compress_struct cinfo; 
    1898   struct jpeg_error_mgr jerr; 
    1899   JSAMPROW row_pointer[1];      /* pointer to JSAMPLE row[s] */ 
    1900   int row_stride;               /* physical row width in image buffer */ 
    1901  
    1902   /* Step 1: allocate and initialize JPEG compression object */ 
    1903   cinfo.err = jpeg_std_error(&jerr); 
    1904   /* Now we can initialize the JPEG compression object. */ 
    1905   jpeg_create_compress(&cinfo); 
    1906  
    1907   /* Step 2: specify data destination (eg, a file) */ 
    1908   /* Note: steps 2 and 3 can be done in either order. */ 
    1909   jpegDest(&cinfo, buffer, image_width*image_height*4); 
    1910  
    1911   /* Step 3: set parameters for compression */ 
    1912   cinfo.image_width = image_width;      /* image width and height, in pixels */ 
    1913   cinfo.image_height = image_height; 
    1914   cinfo.input_components = 4;           /* # of color components per pixel */ 
    1915   cinfo.in_color_space = JCS_RGB;       /* colorspace of input image */ 
    1916  
    1917   jpeg_set_defaults(&cinfo); 
    1918   jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */); 
    1919   /* If quality is set high, disable chroma subsampling */ 
    1920   if (quality >= 85) { 
    1921     cinfo.comp_info[0].h_samp_factor = 1; 
    1922     cinfo.comp_info[0].v_samp_factor = 1; 
    1923   } 
    1924  
    1925   /* Step 4: Start compressor */ 
    1926   jpeg_start_compress(&cinfo, TRUE); 
    1927  
    1928   /* Step 5: while (scan lines remain to be written) */ 
    1929   /*           jpeg_write_scanlines(...); */ 
    1930   row_stride = image_width * 4; /* JSAMPLEs per row in image_buffer */ 
    1931  
    1932   while (cinfo.next_scanline < cinfo.image_height) { 
    1933     /* jpeg_write_scanlines expects an array of pointers to scanlines. 
    1934      * Here the array is only one element long, but you could pass 
    1935      * more than one scanline at a time if that's more convenient. 
    1936      */ 
    1937     row_pointer[0] = & image_buffer[((cinfo.image_height-1)*row_stride)-cinfo.next_scanline * row_stride]; 
    1938     (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); 
    1939   } 
    1940  
    1941   /* Step 6: Finish compression */ 
    1942   jpeg_finish_compress(&cinfo); 
    1943  
    1944   /* Step 7: release JPEG compression object */ 
    1945   jpeg_destroy_compress(&cinfo); 
    1946  
    1947   /* And we're done! */ 
    1948   return hackSize; 
    1949 } 
    1950  
    1951 //=================================================================== 
    1952  
    1953 /* 
    1954 ================= 
    1955 PNG LOADING 
    1956 ================= 
    1957 */ 
    1958  
    1959 /* 
    1960  *  Quake 3 image format : RGBA 
    1961  */ 
    1962  
    1963 #define Q3IMAGE_BYTESPERPIXEL (4) 
    1964  
    1965 /* 
    1966  *  PNG specifications 
    1967  */ 
    1968  
    1969 /* 
    1970  *  The first 8 Bytes of every PNG-File are a fixed signature 
    1971  *  to identify the file as a PNG. 
    1972  */ 
    1973  
    1974 #define PNG_Signature "\x89\x50\x4E\x47\xD\xA\x1A\xA" 
    1975 #define PNG_Signature_Size (8) 
    1976  
    1977 /* 
    1978  *  After the signature diverse chunks follow. 
    1979  *  A chunk consists of a header and if Length 
    1980  *  is bigger than 0 a body and a CRC of the body follow. 
    1981  */ 
    1982  
    1983 struct PNG_ChunkHeader 
    1984 { 
    1985     uint32_t Length; 
    1986     uint32_t Type; 
    1987 }; 
    1988  
    1989 #define PNG_ChunkHeader_Size (8) 
    1990  
    1991 typedef uint32_t PNG_ChunkCRC; 
    1992  
    1993 #define PNG_ChunkCRC_Size (4) 
    1994  
    1995 /* 
    1996  *  We use the following ChunkTypes. 
    1997  *  All others are ignored. 
    1998  */ 
    1999  
    2000 #define MAKE_CHUNKTYPE(a,b,c,d) (((a) << 24) | ((b) << 16) | ((c) << 8) | ((d))) 
    2001  
    2002 #define PNG_ChunkType_IHDR MAKE_CHUNKTYPE('I', 'H', 'D', 'R') 
    2003 #define PNG_ChunkType_PLTE MAKE_CHUNKTYPE('P', 'L', 'T', 'E') 
    2004 #define PNG_ChunkType_IDAT MAKE_CHUNKTYPE('I', 'D', 'A', 'T') 
    2005 #define PNG_ChunkType_IEND MAKE_CHUNKTYPE('I', 'E', 'N', 'D') 
    2006 #define PNG_ChunkType_tRNS MAKE_CHUNKTYPE('t', 'R', 'N', 'S') 
    2007  
    2008 /* 
    2009  *  Per specification the first chunk after the signature SHALL be IHDR. 
    2010  */ 
    2011  
    2012 struct PNG_Chunk_IHDR 
    2013 { 
    2014     uint32_t Width; 
    2015     uint32_t Height; 
    2016     uint8_t  BitDepth; 
    2017     uint8_t  ColourType; 
    2018     uint8_t  CompressionMethod; 
    2019     uint8_t  FilterMethod; 
    2020     uint8_t  InterlaceMethod; 
    2021 }; 
    2022  
    2023 #define PNG_Chunk_IHDR_Size (13) 
    2024  
    2025 /* 
    2026  *  ColourTypes 
    2027  */ 
    2028  
    2029 #define PNG_ColourType_Grey      (0) 
    2030 #define PNG_ColourType_True      (2) 
    2031 #define PNG_ColourType_Indexed   (3) 
    2032 #define PNG_ColourType_GreyAlpha (4) 
    2033 #define PNG_ColourType_TrueAlpha (6) 
    2034  
    2035 /* 
    2036  *  number of colour components 
    2037  * 
    2038  *  Grey      : 1 grey 
    2039  *  True      : 1 R, 1 G, 1 B 
    2040  *  Indexed   : 1 index 
    2041  *  GreyAlpha : 1 grey, 1 alpha 
    2042  *  TrueAlpha : 1 R, 1 G, 1 B, 1 alpha 
    2043  */ 
    2044  
    2045 #define PNG_NumColourComponents_Grey      (1) 
    2046 #define PNG_NumColourComponents_True      (3) 
    2047 #define PNG_NumColourComponents_Indexed   (1) 
    2048 #define PNG_NumColourComponents_GreyAlpha (2) 
    2049 #define PNG_NumColourComponents_TrueAlpha (4) 
    2050  
    2051 /* 
    2052  *  For the different ColourTypes 
    2053  *  different BitDepths are specified. 
    2054  */ 
    2055  
    2056 #define PNG_BitDepth_1  ( 1) 
    2057 #define PNG_BitDepth_2  ( 2) 
    2058 #define PNG_BitDepth_4  ( 4) 
    2059 #define PNG_BitDepth_8  ( 8) 
    2060 #define PNG_BitDepth_16 (16) 
    2061  
    2062 /* 
    2063  *  Only one valid CompressionMethod is standardized. 
    2064  */ 
    2065  
    2066 #define PNG_CompressionMethod_0 (0) 
    2067  
    2068 /* 
    2069  *  Only one valid FilterMethod is currently standardized. 
    2070  */ 
    2071  
    2072 #define PNG_FilterMethod_0 (0) 
    2073  
    2074 /* 
    2075  *  This FilterMethod defines 5 FilterTypes 
    2076  */ 
    2077  
    2078 #define PNG_FilterType_None    (0) 
    2079 #define PNG_FilterType_Sub     (1) 
    2080 #define PNG_FilterType_Up      (2) 
    2081 #define PNG_FilterType_Average (3) 
    2082 #define PNG_FilterType_Paeth   (4) 
    2083  
    2084 /* 
    2085  *  Two InterlaceMethods are standardized : 
    2086  *  0 - NonInterlaced 
    2087  *  1 - Interlaced 
    2088  */ 
    2089  
    2090 #define PNG_InterlaceMethod_NonInterlaced (0) 
    2091 #define PNG_InterlaceMethod_Interlaced    (1) 
    2092  
    2093 /* 
    2094  *  The Adam7 interlace method uses 7 passes. 
    2095  */ 
    2096  
    2097 #define PNG_Adam7_NumPasses (7) 
    2098  
    2099 /* 
    2100  *  The compressed data starts with a header ... 
    2101  */ 
    2102  
    2103 struct PNG_ZlibHeader 
    2104 { 
    2105     uint8_t CompressionMethod; 
    2106     uint8_t Flags; 
    2107 }; 
    2108  
    2109 #define PNG_ZlibHeader_Size (2) 
    2110  
    2111 /* 
    2112  *  ... and is followed by a check value 
    2113  */ 
    2114  
    2115 #define PNG_ZlibCheckValue_Size (4) 
    2116  
    2117 /* 
    2118  *  Some support functions for buffered files follow. 
    2119  */ 
    2120  
    2121 /* 
    2122  *  buffered file representation 
    2123  */ 
    2124  
    2125 struct BufferedFile 
    2126 { 
    2127     byte *Buffer; 
    2128     int   Length; 
    2129     byte *Ptr; 
    2130     int   BytesLeft; 
    2131 }; 
    2132  
    2133 /* 
    2134  *  Read a file into a buffer. 
    2135  */ 
    2136  
    2137 static struct BufferedFile *ReadBufferedFile(const char *name) 
    2138 { 
    2139     struct BufferedFile *BF; 
    2140  
    2141     /* 
    2142      *  input verification 
    2143      */ 
    2144  
    2145     if(!name) 
    2146     { 
    2147         return(NULL); 
    2148     } 
    2149  
    2150     /* 
    2151      *  Allocate control struct. 
    2152      */ 
    2153  
    2154     BF = ri.Malloc(sizeof(struct BufferedFile)); 
    2155     if(!BF) 
    2156     { 
    2157         return(NULL); 
    2158     } 
    2159  
    2160     /* 
    2161      *  Initialize the structs components. 
    2162      */ 
    2163  
    2164     BF->Length    = 0; 
    2165     BF->Buffer    = NULL; 
    2166     BF->Ptr       = NULL; 
    2167     BF->BytesLeft = 0; 
    2168  
    2169     /* 
    2170      *  Read the file. 
    2171      */ 
    2172  
    2173     BF->Length = ri.FS_ReadFile((char *) name, (void **) &BF->Buffer); 
    2174  
    2175     /* 
    2176      *  Did we get it? Is it big enough? 
    2177      */ 
    2178  
    2179     if(!(BF->Buffer && (BF->Length > 0))) 
    2180     { 
    2181         ri.Free(BF); 
    2182  
    2183         return(NULL); 
    2184     } 
    2185  
    2186     /* 
    2187      *  Set the pointers and counters. 
    2188      */ 
    2189  
    2190     BF->Ptr       = BF->Buffer; 
    2191     BF->BytesLeft = BF->Length; 
    2192  
    2193     return(BF); 
    2194 } 
    2195  
    2196 /* 
    2197  *  Close a buffered file. 
    2198  */ 
    2199  
    2200 static void CloseBufferedFile(struct BufferedFile *BF) 
    2201 { 
    2202     if(BF) 
    2203     { 
    2204         if(BF->Buffer) 
    2205         { 
    2206             ri.FS_FreeFile(BF->Buffer); 
    2207         } 
    2208   
    2209         ri.Free(BF); 
    2210     } 
    2211 } 
    2212  
    2213 /* 
    2214  *  Get a pointer to the requested bytes. 
    2215  */ 
    2216  
    2217 static void *BufferedFileRead(struct BufferedFile *BF, int Length) 
    2218 { 
    2219     void *RetVal; 
    2220  
    2221     /* 
    2222      *  input verification 
    2223      */ 
    2224  
    2225     if(!(BF && Length)) 
    2226     { 
    2227         return(NULL); 
    2228     } 
    2229   
    2230     /* 
    2231      *  not enough bytes left 
    2232      */ 
    2233  
    2234     if(Length > BF->BytesLeft) 
    2235     { 
    2236         return(NULL); 
    2237     } 
    2238  
    2239     /* 
    2240      *  the pointer to the requested data 
    2241      */ 
    2242  
    2243     RetVal = BF->Ptr; 
    2244   
    2245     /* 
    2246      *  Raise the pointer and counter. 
    2247      */ 
    2248  
    2249     BF->Ptr       += Length; 
    2250     BF->BytesLeft -= Length; 
    2251  
    2252     return(RetVal); 
    2253 } 
    2254  
    2255 /* 
    2256  *  Rewind the buffer. 
    2257  */ 
    2258  
    2259 static qboolean BufferedFileRewind(struct BufferedFile *BF, int Offset) 
    2260 { 
    2261     int BytesRead;  
    2262  
    2263     /* 
    2264      *  input verification 
    2265      */ 
    2266  
    2267     if(!BF) 
    2268     { 
    2269         return(qfalse); 
    2270     } 
    2271  
    2272     /* 
    2273      *  special trick to rewind to the beginning of the buffer 
    2274      */ 
    2275  
    2276     if(Offset == -1) 
    2277     { 
    2278         BF->Ptr       = BF->Buffer; 
    2279         BF->BytesLeft = BF->Length; 
    2280    
    2281         return(qtrue); 
    2282     } 
    2283  
    2284     /* 
    2285      *  How many bytes do we have already read? 
    2286      */ 
    2287  
    2288     BytesRead = BF->Ptr - BF->Buffer; 
    2289  
    2290     /* 
    2291      *  We can only rewind to the beginning of the BufferedFile. 
    2292      */ 
    2293  
    2294     if(Offset > BytesRead) 
    2295     { 
    2296         return(qfalse); 
    2297     } 
    2298  
    2299     /* 
    2300      *  lower the pointer and counter. 
    2301      */ 
    2302  
    2303     BF->Ptr       -= Offset; 
    2304     BF->BytesLeft += Offset; 
    2305  
    2306     return(qtrue); 
    2307 } 
    2308  
    2309 /* 
    2310  *  Skip some bytes. 
    2311  */ 
    2312  
    2313 static qboolean BufferedFileSkip(struct BufferedFile *BF, int Offset) 
    2314 { 
    2315     /* 
    2316      *  input verification 
    2317      */ 
    2318  
    2319     if(!BF) 
    2320     { 
    2321         return(qfalse); 
    2322     } 
    2323   
    2324     /* 
    2325      *  We can only skip to the end of the BufferedFile. 
    2326      */ 
    2327  
    2328     if(Offset > BF->BytesLeft) 
    2329     { 
    2330         return(qfalse); 
    2331     } 
    2332  
    2333     /* 
    2334      *  lower the pointer and counter. 
    2335      */ 
    2336  
    2337     BF->Ptr       += Offset; 
    2338     BF->BytesLeft -= Offset; 
    2339  
    2340     return(qtrue); 
    2341 } 
    2342  
    2343 /* 
    2344  *  Find a chunk 
    2345  */ 
    2346  
    2347 static qboolean FindChunk(struct BufferedFile *BF, uint32_t ChunkType) 
    2348 { 
    2349     struct PNG_ChunkHeader *CH; 
    2350  
    2351     uint32_t Length; 
    2352     uint32_t Type; 
    2353  
    2354     /* 
    2355      *  input verification 
    2356      */ 
    2357  
    2358     if(!BF) 
    2359     { 
    2360         return(qfalse); 
    2361     } 
    2362  
    2363     /* 
    2364      *  cycle trough the chunks 
    2365      */ 
    2366  
    2367     while(qtrue) 
    2368     { 
    2369         /* 
    2370          *  Read the chunk-header. 
    2371          */ 
    2372  
    2373         CH = BufferedFileRead(BF, PNG_ChunkHeader_Size); 
    2374         if(!CH) 
    2375         { 
    2376             return(qfalse); 
    2377         } 
    2378  
    2379         /* 
    2380          *  Do not swap the original types 
    2381          *  they might be needed later. 
    2382          */ 
    2383  
    2384         Length = BigLong(CH->Length); 
    2385         Type   = BigLong(CH->Type); 
    2386    
    2387         /* 
    2388          *  We found it! 
    2389          */ 
    2390  
    2391         if(Type == ChunkType) 
    2392         { 
    2393             /* 
    2394              *  Rewind to the start of the chunk. 
    2395              */ 
    2396               
    2397             BufferedFileRewind(BF, PNG_ChunkHeader_Size); 
    2398    
    2399             break; 
    2400         } 
    2401         else 
    2402         { 
    2403             /* 
    2404              *  Skip the rest of the chunk. 
    2405              */ 
    2406  
    2407             if(Length) 
    2408             { 
    2409                 if(!BufferedFileSkip(BF, Length + PNG_ChunkCRC_Size)) 
    2410                 { 
    2411                     return(qfalse); 
    2412                 }   
    2413             } 
    2414         } 
    2415     } 
    2416  
    2417     return(qtrue); 
    2418 } 
    2419  
    2420 /* 
    2421  *  Decompress all IDATs 
    2422  */ 
    2423  
    2424 static uint32_t DecompressIDATs(struct BufferedFile *BF, uint8_t **Buffer) 
    2425 { 
    2426     uint8_t  *DecompressedData; 
    2427     uint32_t  DecompressedDataLength; 
    2428  
    2429     uint8_t  *CompressedData; 
    2430     uint8_t  *CompressedDataPtr; 
    2431     uint32_t  CompressedDataLength; 
    2432  
    2433     struct PNG_ChunkHeader *CH; 
    2434  
    2435     uint32_t Length; 
    2436     uint32_t Type; 
    2437  
    2438     int BytesToRewind; 
    2439  
    2440     int32_t   puffResult; 
    2441     uint8_t  *puffDest; 
    2442     uint32_t  puffDestLen; 
    2443     uint8_t  *puffSrc; 
    2444     uint32_t  puffSrcLen; 
    2445  
    2446     /* 
    2447      *  input verification 
    2448      */ 
    2449  
    2450     if(!(BF && Buffer)) 
    2451     { 
    2452         return(-1); 
    2453     } 
    2454  
    2455     /* 
    2456      *  some zeroing 
    2457      */ 
    2458  
    2459     DecompressedData = NULL; 
    2460     DecompressedDataLength = 0; 
    2461     *Buffer = DecompressedData; 
    2462  
    2463     CompressedData = NULL; 
    2464     CompressedDataLength = 0; 
    2465  
    2466     BytesToRewind = 0; 
    2467  
    2468     /* 
    2469      *  Find the first IDAT chunk. 
    2470      */ 
    2471  
    2472     if(!FindChunk(BF, PNG_ChunkType_IDAT)) 
    2473     { 
    2474         return(-1); 
    2475     } 
    2476  
    2477     /* 
    2478      *  Count the size of the uncompressed data 
    2479      */ 
    2480  
    2481     while(qtrue) 
    2482     { 
    2483         /* 
    2484          *  Read chunk header 
    2485          */ 
    2486  
    2487         CH = BufferedFileRead(BF, PNG_ChunkHeader_Size); 
    2488         if(!CH) 
    2489         { 
    2490             /* 
    2491              *  Rewind to the start of this adventure 
    2492              *  and return unsuccessfull 
    2493              */ 
    2494  
    2495             BufferedFileRewind(BF, BytesToRewind); 
    2496  
    2497             return(-1); 
    2498         } 
    2499  
    2500         /* 
    2501          *  Length and Type of chunk 
    2502          */ 
    2503  
    2504         Length = BigLong(CH->Length); 
    2505         Type   = BigLong(CH->Type); 
    2506  
    2507         /* 
    2508          *  We have reached the end of the IDAT chunks 
    2509          */ 
    2510  
    2511         if(!(Type == PNG_ChunkType_IDAT)) 
    2512         { 
    2513             BufferedFileRewind(BF, PNG_ChunkHeader_Size);  
    2514    
    2515             break; 
    2516         } 
    2517  
    2518         /* 
    2519          *  Add chunk header to count. 
    2520          */ 
    2521  
    2522         BytesToRewind += PNG_ChunkHeader_Size; 
    2523  
    2524         /* 
    2525          *  Skip to next chunk 
    2526          */ 
    2527  
    2528         if(Length) 
    2529         { 
    2530             if(!BufferedFileSkip(BF, Length + PNG_ChunkCRC_Size)) 
    2531             { 
    2532                 BufferedFileRewind(BF, BytesToRewind); 
    2533  
    2534                 return(-1); 
    2535             } 
    2536  
    2537             BytesToRewind += Length + PNG_ChunkCRC_Size; 
    2538             CompressedDataLength += Length; 
    2539         }  
    2540     } 
    2541  
    2542     BufferedFileRewind(BF, BytesToRewind); 
    2543  
    2544     CompressedData = ri.Malloc(CompressedDataLength); 
    2545     if(!CompressedData) 
    2546     { 
    2547         return(-1); 
    2548     } 
    2549   
    2550     CompressedDataPtr = CompressedData; 
    2551  
    2552     /* 
    2553      *  Collect the compressed Data 
    2554      */ 
    2555  
    2556     while(qtrue) 
    2557     { 
    2558         /* 
    2559          *  Read chunk header 
    2560          */ 
    2561  
    2562         CH = BufferedFileRead(BF, PNG_ChunkHeader_Size); 
    2563         if(!CH) 
    2564         { 
    2565             ri.Free(CompressedData);  
    2566    
    2567             return(-1); 
    2568         } 
    2569  
    2570         /* 
    2571          *  Length and Type of chunk 
    2572          */ 
    2573  
    2574         Length = BigLong(CH->Length); 
    2575         Type   = BigLong(CH->Type); 
    2576  
    2577         /* 
    2578          *  We have reached the end of the IDAT chunks 
    2579          */ 
    2580  
    2581         if(!(Type == PNG_ChunkType_IDAT)) 
    2582         { 
    2583             BufferedFileRewind(BF, PNG_ChunkHeader_Size);  
    2584    
    2585             break; 
    2586         } 
    2587  
    2588         /* 
    2589          *  Copy the Data 
    2590          */ 
    2591  
    2592         if(Length) 
    2593         { 
    2594             uint8_t *OrigCompressedData; 
    2595     
    2596             OrigCompressedData = BufferedFileRead(BF, Length); 
    2597             if(!OrigCompressedData) 
    2598             { 
    2599                 ri.Free(CompressedData);  
    2600    
    2601                 return(-1); 
    2602             } 
    2603  
    2604             if(!BufferedFileSkip(BF, PNG_ChunkCRC_Size)) 
    2605             { 
    2606                 ri.Free(CompressedData);  
    2607  
    2608                 return(-1); 
    2609             } 
    2610    
    2611             memcpy(CompressedDataPtr, OrigCompressedData, Length); 
    2612             CompressedDataPtr += Length; 
    2613         }  
    2614     } 
    2615  
    2616     /* 
    2617      *  Let puff() calculate the decompressed data length. 
    2618      */ 
    2619  
    2620     puffDest    = NULL; 
    2621     puffDestLen = 0; 
    2622   
    2623     /* 
    2624      *  The zlib header and checkvalue don't belong to the compressed data. 
    2625      */ 
    2626  
    2627     puffSrc    = CompressedData + PNG_ZlibHeader_Size; 
    2628     puffSrcLen = CompressedDataLength - PNG_ZlibHeader_Size - PNG_ZlibCheckValue_Size; 
    2629  
    2630     /* 
    2631      *  first puff() to calculate the size of the uncompressed data 
    2632      */ 
    2633  
    2634     puffResult = puff(puffDest, &puffDestLen, puffSrc, &puffSrcLen); 
    2635     if(!((puffResult == 0) && (puffDestLen > 0))) 
    2636     { 
    2637         ri.Free(CompressedData); 
    2638   
    2639         return(-1); 
    2640     } 
    2641  
    2642     /* 
    2643      *  Allocate the buffer for the uncompressed data. 
    2644      */ 
    2645  
    2646     DecompressedData = ri.Malloc(puffDestLen); 
    2647     if(!DecompressedData) 
    2648     { 
    2649         ri.Free(CompressedData); 
    2650   
    2651         return(-1); 
    2652     } 
    2653  
    2654     /* 
    2655      *  Set the input again in case something was changed by the last puff() . 
    2656      */ 
    2657  
    2658     puffDest   = DecompressedData; 
    2659     puffSrc    = CompressedData + PNG_ZlibHeader_Size; 
    2660     puffSrcLen = CompressedDataLength - PNG_ZlibHeader_Size - PNG_ZlibCheckValue_Size; 
    2661   
    2662     /* 
    2663      *  decompression puff() 
    2664      */ 
    2665  
    2666     puffResult = puff(puffDest, &puffDestLen, puffSrc, &puffSrcLen); 
    2667  
    2668     /* 
    2669      *  The compressed data is not needed anymore. 
    2670      */ 
    2671  
    2672     ri.Free(CompressedData); 
    2673  
    2674     /* 
    2675      *  Check if the last puff() was successfull. 
    2676      */ 
    2677  
    2678     if(!((puffResult == 0) && (puffDestLen > 0))) 
    2679     { 
    2680         ri.Free(DecompressedData); 
    2681   
    2682         return(-1); 
    2683     } 
    2684  
    2685     /* 
    2686      *  Set the output of this function. 
    2687      */ 
    2688  
    2689     DecompressedDataLength = puffDestLen; 
    2690     *Buffer = DecompressedData; 
    2691  
    2692     return(DecompressedDataLength); 
    2693 } 
    2694  
    2695 /* 
    2696  *  the Paeth predictor 
    2697  */ 
    2698  
    2699 static uint8_t PredictPaeth(uint8_t a, uint8_t b, uint8_t c) 
    2700 { 
    2701     /* 
    2702      *  a == Left 
    2703      *  b == Up 
    2704      *  c == UpLeft 
    2705      */ 
    2706  
    2707     uint8_t Pr; 
    2708     int p; 
    2709     int pa, pb, pc; 
    2710  
    2711     Pr = 0; 
    2712  
    2713     p  = ((int) a) + ((int) b) - ((int) c); 
    2714     pa = abs(p - ((int) a)); 
    2715     pb = abs(p - ((int) b)); 
    2716     pc = abs(p - ((int) c)); 
    2717  
    2718     if((pa <= pb) && (pa <= pc)) 
    2719     { 
    2720         Pr = a; 
    2721     } 
    2722     else if(pb <= pc) 
    2723     { 
    2724         Pr = b; 
    2725     } 
    2726     else 
    2727     { 
    2728         Pr = c; 
    2729     } 
    2730  
    2731     return(Pr); 
    2732  
    2733 } 
    2734  
    2735 /* 
    2736  *  Reverse the filters. 
    2737  */ 
    2738  
    2739 static qboolean UnfilterImage(uint8_t  *DecompressedData,  
    2740                               uint32_t  ImageHeight, 
    2741                               uint32_t  BytesPerScanline,  
    2742                               uint32_t  BytesPerPixel) 
    2743 { 
    2744     uint8_t   *DecompPtr; 
    2745     uint8_t   FilterType; 
    2746     uint8_t  *PixelLeft, *PixelUp, *PixelUpLeft; 
    2747     uint32_t  w, h, p; 
    2748  
    2749     /* 
    2750      *  some zeros for the filters 
    2751      */ 
    2752  
    2753     uint8_t Zeros[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 
    2754  
    2755     /* 
    2756      *  input verification 
    2757      * 
    2758      *  ImageHeight and BytesPerScanline are not checked, 
    2759      *  because these can be zero in some interlace passes. 
    2760      */ 
    2761  
    2762     if(!(DecompressedData && BytesPerPixel)) 
    2763     { 
    2764         return(qfalse); 
    2765     } 
    2766  
    2767  
    2768     /* 
    2769      *  Set the pointer to the start of the decompressed Data. 
    2770      */ 
    2771  
    2772     DecompPtr = DecompressedData; 
    2773  
    2774     /* 
    2775      *  Un-filtering is done in place. 
    2776      */ 
    2777  
    2778     /* 
    2779      *  Go trough all scanlines. 
    2780      */ 
    2781  
    2782     for(h = 0; h < ImageHeight; h++) 
    2783     { 
    2784         /* 
    2785          *  Every scanline starts with a FilterType byte. 
    2786          */ 
    2787  
    2788         FilterType = *DecompPtr; 
    2789         DecompPtr++; 
    2790  
    2791         /* 
    2792          *  Left pixel of the first byte in a scanline is zero. 
    2793          */ 
    2794  
    2795         PixelLeft = Zeros; 
    2796  
    2797         /* 
    2798          *  Set PixelUp to previous line only if we are on the second line or above. 
    2799          * 
    2800          *  Plus one byte for the FilterType 
    2801          */ 
    2802  
    2803         if(h > 0) 
    2804         { 
    2805             PixelUp = DecompPtr - (BytesPerScanline + 1); 
    2806         } 
    2807         else 
    2808         { 
    2809             PixelUp = Zeros; 
    2810         } 
    2811  
    2812         /* 
    2813          * The pixel left to the first pixel of the previous scanline is zero too. 
    2814          */ 
    2815  
    2816         PixelUpLeft = Zeros; 
    2817  
    2818         /* 
    2819          *  Cycle trough all pixels of the scanline. 
    2820          */ 
    2821  
    2822         for(w = 0; w < (BytesPerScanline / BytesPerPixel); w++) 
    2823         { 
    2824             /* 
    2825              *  Cycle trough the bytes of the pixel. 
    2826              */ 
    2827  
    2828             for(p = 0; p < BytesPerPixel; p++) 
    2829             { 
    2830                 switch(FilterType) 
    2831                 {  
    2832                     case PNG_FilterType_None : 
    2833                     { 
    2834                         /* 
    2835                          *  The byte is unfiltered. 
    2836                          */ 
    2837  
    2838                         break; 
    2839                     } 
    2840  
    2841                     case PNG_FilterType_Sub : 
    2842                     { 
    2843                         DecompPtr[p] += PixelLeft[p]; 
    2844  
    2845                         break; 
    2846                     } 
    2847  
    2848                     case PNG_FilterType_Up : 
    2849                     { 
    2850                         DecompPtr[p] += PixelUp[p]; 
    2851  
    2852                         break; 
    2853                     } 
    2854  
    2855                     case PNG_FilterType_Average : 
    2856                     { 
    2857                         DecompPtr[p] += ((uint8_t) ((((uint16_t) PixelLeft[p]) + ((uint16_t) PixelUp[p])) / 2)); 
    2858  
    2859                         break; 
    2860                     } 
    2861  
    2862                     case PNG_FilterType_Paeth : 
    2863                     { 
    2864                         DecompPtr[p] += PredictPaeth(PixelLeft[p], PixelUp[p], PixelUpLeft[p]); 
    2865  
    2866                         break; 
    2867                     } 
    2868  
    2869                     default : 
    2870                     { 
    2871                         return(qfalse); 
    2872                     } 
    2873                 } 
    2874             } 
    2875     
    2876             PixelLeft = DecompPtr; 
    2877  
    2878             /* 
    2879              *  We only have a upleft pixel if we are on the second line or above. 
    2880              */ 
    2881  
    2882             if(h > 0) 
    2883             { 
    2884                 PixelUpLeft = DecompPtr - (BytesPerScanline + 1); 
    2885             } 
    2886  
    2887             /* 
    2888              *  Skip to the next pixel. 
    2889              */ 
    2890  
    2891             DecompPtr += BytesPerPixel; 
    2892           
    2893             /* 
    2894              *  We only have a previous line if we are on the second line and above. 
    2895              */ 
    2896  
    2897             if(h > 0) 
    2898             { 
    2899                 PixelUp = DecompPtr - (BytesPerScanline + 1); 
    2900             } 
    2901         } 
    2902     } 
    2903  
    2904  return(qtrue); 
    2905 } 
    2906  
    2907 /* 
    2908  *  Convert a raw input pixel to Quake 3 RGA format. 
    2909  */ 
    2910  
    2911 static qboolean ConvertPixel(struct PNG_Chunk_IHDR *IHDR, 
    2912                              byte                  *OutPtr, 
    2913                              uint8_t               *DecompPtr, 
    2914                              qboolean               HasTransparentColour, 
    2915                              uint8_t               *TransparentColour, 
    2916                              uint8_t               *OutPal) 
    2917 { 
    2918     /* 
    2919      *  input verification 
    2920      */ 
    2921      
    2922     if(!(IHDR && OutPtr && DecompPtr && TransparentColour && OutPal)) 
    2923     { 
    2924      return(qfalse); 
    2925     } 
    2926  
    2927     switch(IHDR->ColourType) 
    2928     { 
    2929         case PNG_ColourType_Grey : 
    2930         { 
    2931             switch(IHDR->BitDepth) 
    2932             { 
    2933                 case PNG_BitDepth_1 : 
    2934                 case PNG_BitDepth_2 : 
    2935                 case PNG_BitDepth_4 : 
    2936                 { 
    2937                     uint8_t Step; 
    2938                     uint8_t GreyValue; 
    2939  
    2940                     Step = 0xFF / ((1 << IHDR->BitDepth) - 1); 
    2941  
    2942                     GreyValue = DecompPtr[0] * Step; 
    2943    
    2944                     OutPtr[0] = GreyValue; 
    2945                     OutPtr[1] = GreyValue; 
    2946                     OutPtr[2] = GreyValue; 
    2947                     OutPtr[3] = 0xFF; 
    2948  
    2949                     /* 
    2950                      *  Grey supports full transparency for one specified colour 
    2951                      */ 
    2952  
    2953                     if(HasTransparentColour) 
    2954                     { 
    2955                         if(TransparentColour[1] == DecompPtr[0]) 
    2956                         { 
    2957                             OutPtr[3] = 0x00; 
    2958                         } 
    2959                     } 
    2960          
    2961  
    2962                     break; 
    2963                 } 
    2964        
    2965                 case PNG_BitDepth_8 : 
    2966                 case PNG_BitDepth_16 : 
    2967                 { 
    2968                     OutPtr[0] = DecompPtr[0]; 
    2969                     OutPtr[1] = DecompPtr[0]; 
    2970                     OutPtr[2] = DecompPtr[0]; 
    2971                     OutPtr[3] = 0xFF; 
    2972        
    2973                     /* 
    2974                      *  Grey supports full transparency for one specified colour 
    2975                      */ 
    2976  
    2977                     if(HasTransparentColour) 
    2978                     { 
    2979                         if(IHDR->BitDepth == PNG_BitDepth_8) 
    2980                         { 
    2981                             if(TransparentColour[1] == DecompPtr[0]) 
    2982                             { 
    2983                                 OutPtr[3] = 0x00; 
    2984                             } 
    2985                         } 
    2986                         else 
    2987                         { 
    2988                             if((TransparentColour[0] == DecompPtr[0]) && (TransparentColour[1] == DecompPtr[1])) 
    2989                             { 
    2990                                 OutPtr[3] = 0x00; 
    2991                             } 
    2992                         } 
    2993                     } 
    2994  
    2995                     break; 
    2996                 } 
    2997        
    2998                 default : 
    2999                 { 
    3000                     return(qfalse); 
    3001                 } 
    3002             } 
    3003      
    3004             break; 
    3005         } 
    3006  
    3007         case PNG_ColourType_True : 
    3008         { 
    3009             switch(IHDR->BitDepth) 
    3010             { 
    3011                 case PNG_BitDepth_8 : 
    3012                 { 
    3013                     OutPtr[0] = DecompPtr[0]; 
    3014                     OutPtr[1] = DecompPtr[1]; 
    3015                     OutPtr[2] = DecompPtr[2]; 
    3016                     OutPtr[3] = 0xFF; 
    3017        
    3018                     /* 
    3019                      *  True supports full transparency for one specified colour 
    3020                      */ 
    3021  
    3022                     if(HasTransparentColour) 
    3023                     { 
    3024                         if((TransparentColour[1] == DecompPtr[0]) && 
    3025                            (TransparentColour[3] == DecompPtr[1]) && 
    3026                            (TransparentColour[5] == DecompPtr[3])) 
    3027                         { 
    3028                             OutPtr[3] = 0x00; 
    3029                         } 
    3030                     } 
    3031  
    3032                     break; 
    3033                 } 
    3034        
    3035                 case PNG_BitDepth_16 : 
    3036                 { 
    3037                     /* 
    3038                      *  We use only the upper byte. 
    3039                      */ 
    3040  
    3041                     OutPtr[0] = DecompPtr[0]; 
    3042                     OutPtr[1] = DecompPtr[2]; 
    3043                     OutPtr[2] = DecompPtr[4]; 
    3044                     OutPtr[3] = 0xFF; 
    3045        
    3046                     /* 
    3047                      *  True supports full transparency for one specified colour 
    3048                      */ 
    3049  
    3050                     if(HasTransparentColour) 
    3051                     { 
    3052                         if((TransparentColour[0] == DecompPtr[0]) && (TransparentColour[1] == DecompPtr[1]) && 
    3053                            (TransparentColour[2] == DecompPtr[2]) && (TransparentColour[3] == DecompPtr[3]) && 
    3054                            (TransparentColour[4] == DecompPtr[4]) && (TransparentColour[5] == DecompPtr[5])) 
    3055                         { 
    3056                             OutPtr[3] = 0x00; 
    3057                         } 
    3058                     } 
    3059  
    3060                     break; 
    3061                 } 
    3062  
    3063                 default : 
    3064                 { 
    3065                     return(qfalse); 
    3066                 } 
    3067             } 
    3068  
    3069             break; 
    3070         } 
    3071  
    3072         case PNG_ColourType_Indexed : 
    3073         { 
    3074             OutPtr[0] = OutPal[DecompPtr[0] * Q3IMAGE_BYTESPERPIXEL + 0]; 
    3075             OutPtr[1] = OutPal[DecompPtr[0] * Q3IMAGE_BYTESPERPIXEL + 1]; 
    3076             OutPtr[2] = OutPal[DecompPtr[0] * Q3IMAGE_BYTESPERPIXEL + 2]; 
    3077             OutPtr[3] = OutPal[DecompPtr[0] * Q3IMAGE_BYTESPERPIXEL + 3]; 
    3078          
    3079             break; 
    3080         } 
    3081  
    3082         case PNG_ColourType_GreyAlpha : 
    3083         { 
    3084             switch(IHDR->BitDepth) 
    3085             { 
    3086                 case PNG_BitDepth_8 : 
    3087                 { 
    3088                     OutPtr[0] = DecompPtr[0]; 
    3089                     OutPtr[1] = DecompPtr[0]; 
    3090                     OutPtr[2] = DecompPtr[0]; 
    3091                     OutPtr[3] = DecompPtr[1]; 
    3092        
    3093                     break; 
    3094                 } 
    3095    
    3096                 case PNG_BitDepth_16 : 
    3097                 { 
    3098                     /* 
    3099                      *  We use only the upper byte. 
    3100                      */ 
    3101  
    3102                     OutPtr[0] = DecompPtr[0]; 
    3103                     OutPtr[1] = DecompPtr[0]; 
    3104                     OutPtr[2] = DecompPtr[0]; 
    3105                     OutPtr[3] = DecompPtr[2]; 
    3106        
    3107                     break; 
    3108                 } 
    3109  
    3110                 default : 
    3111                 { 
    3112                     return(qfalse); 
    3113                 } 
    3114             } 
    3115  
    3116             break; 
    3117         } 
    3118  
    3119         case PNG_ColourType_TrueAlpha : 
    3120         { 
    3121             switch(IHDR->BitDepth) 
    3122             { 
    3123                 case PNG_BitDepth_8 : 
    3124                 { 
    3125                     OutPtr[0] = DecompPtr[0]; 
    3126                     OutPtr[1] = DecompPtr[1]; 
    3127                     OutPtr[2] = DecompPtr[2]; 
    3128                     OutPtr[3] = DecompPtr[3]; 
    3129        
    3130                     break; 
    3131                 } 
    3132        
    3133                 case PNG_BitDepth_16 : 
    3134                 { 
    3135                     /* 
    3136                      *  We use only the upper byte. 
    3137                      */ 
    3138  
    3139                     OutPtr[0] = DecompPtr[0]; 
    3140                     OutPtr[1] = DecompPtr[2]; 
    3141                     OutPtr[2] = DecompPtr[4]; 
    3142                     OutPtr[3] = DecompPtr[6]; 
    3143        
    3144                     break; 
    3145                 } 
    3146  
    3147                 default : 
    3148                 { 
    3149                     return(qfalse); 
    3150                 } 
    3151             } 
    3152  
    3153             break; 
    3154         } 
    3155  
    3156         default : 
    3157         { 
    3158             return(qfalse); 
    3159         } 
    3160     } 
    3161  
    3162     return(qtrue); 
    3163 } 
    3164  
    3165  
    3166 /* 
    3167  *  Decode a non-interlaced image. 
    3168  */ 
    3169  
    3170 static qboolean DecodeImageNonInterlaced(struct PNG_Chunk_IHDR *IHDR, 
    3171                                          byte                  *OutBuffer,  
    3172                                          uint8_t               *DecompressedData, 
    3173                                          uint32_t               DecompressedDataLength, 
    3174                                          qboolean               HasTransparentColour, 
    3175                                          uint8_t               *TransparentColour, 
    3176                                          uint8_t               *OutPal) 
    3177 { 
    3178     uint32_t IHDR_Width; 
    3179     uint32_t IHDR_Height; 
    3180     uint32_t BytesPerScanline, BytesPerPixel, PixelsPerByte; 
    3181     uint32_t  w, h, p; 
    3182     byte *OutPtr; 
    3183     uint8_t *DecompPtr; 
    3184  
    3185     /* 
    3186      *  input verification 
    3187      */ 
    3188  
    3189     if(!(IHDR && OutBuffer && DecompressedData && DecompressedDataLength && TransparentColour && OutPal)) 
    3190     { 
    3191         return(qfalse); 
    3192     } 
    3193  
    3194     /* 
    3195      *  byte swapping 
    3196      */ 
    3197       
    3198     IHDR_Width  = BigLong(IHDR->Width); 
    3199     IHDR_Height = BigLong(IHDR->Height); 
    3200  
    3201     /* 
    3202      *  information for un-filtering 
    3203      */ 
    3204  
    3205     switch(IHDR->ColourType) 
    3206     { 
    3207         case PNG_ColourType_Grey : 
    3208         { 
    3209             switch(IHDR->BitDepth) 
    3210             { 
    3211                 case PNG_BitDepth_1 : 
    3212                 case PNG_BitDepth_2 : 
    3213                 case PNG_BitDepth_4 : 
    3214                 { 
    3215                     BytesPerPixel    = 1; 
    3216                     PixelsPerByte    = 8 / IHDR->BitDepth; 
    3217  
    3218                     break; 
    3219                 } 
    3220  
    3221                 case PNG_BitDepth_8  : 
    3222                 case PNG_BitDepth_16 : 
    3223                 { 
    3224                     BytesPerPixel    = (IHDR->BitDepth / 8) * PNG_NumColourComponents_Grey; 
    3225                     PixelsPerByte    = 1; 
    3226  
    3227                     break; 
    3228                 } 
    3229  
    3230                 default : 
    3231                 { 
    3232                     return(qfalse); 
    3233                 } 
    3234             } 
    3235    
    3236             break; 
    3237         } 
    3238    
    3239         case PNG_ColourType_True : 
    3240         { 
    3241             switch(IHDR->BitDepth) 
    3242             { 
    3243                 case PNG_BitDepth_8  : 
    3244                 case PNG_BitDepth_16 : 
    3245                 { 
    3246                     BytesPerPixel    = (IHDR->BitDepth / 8) * PNG_NumColourComponents_True; 
    3247                     PixelsPerByte    = 1; 
    3248  
    3249                     break; 
    3250                 } 
    3251       
    3252                 default : 
    3253                 { 
    3254                     return(qfalse); 
    3255                 } 
    3256             } 
    3257    
    3258             break; 
    3259         } 
    3260  
    3261         case PNG_ColourType_Indexed : 
    3262         { 
    3263             switch(IHDR->BitDepth) 
    3264             { 
    3265                 case PNG_BitDepth_1 : 
    3266                 case PNG_BitDepth_2 : 
    3267                 case PNG_BitDepth_4 : 
    3268                 { 
    3269                     BytesPerPixel    = 1; 
    3270                     PixelsPerByte    = 8 / IHDR->BitDepth; 
    3271  
    3272                     break; 
    3273                 } 
    3274  
    3275                 case PNG_BitDepth_8 : 
    3276                 { 
    3277                     BytesPerPixel    = PNG_NumColourComponents_Indexed; 
    3278                     PixelsPerByte    = 1; 
    3279  
    3280                     break; 
    3281                 } 
    3282           
    3283                 default : 
    3284                 { 
    3285                     return(qfalse); 
    3286                 } 
    3287             } 
    3288    
    3289             break; 
    3290         } 
    3291  
    3292         case PNG_ColourType_GreyAlpha : 
    3293         { 
    3294             switch(IHDR->BitDepth) 
    3295             { 
    3296                 case PNG_BitDepth_8 : 
    3297                 case PNG_BitDepth_16 : 
    3298                 { 
    3299                     BytesPerPixel    = (IHDR->BitDepth / 8) * PNG_NumColourComponents_GreyAlpha; 
    3300                     PixelsPerByte    = 1; 
    3301  
    3302                     break; 
    3303                 } 
    3304       
    3305                 default : 
    3306                 { 
    3307                     return(qfalse); 
    3308                 } 
    3309             } 
    3310    
    3311             break; 
    3312         } 
    3313  
    3314         case PNG_ColourType_TrueAlpha : 
    3315         { 
    3316             switch(IHDR->BitDepth) 
    3317             { 
    3318                 case PNG_BitDepth_8 : 
    3319                 case PNG_BitDepth_16 : 
    3320                 { 
    3321                     BytesPerPixel    = (IHDR->BitDepth / 8) * PNG_NumColourComponents_TrueAlpha; 
    3322                     PixelsPerByte    = 1; 
    3323  
    3324                     break; 
    3325                 } 
    3326      
    3327                 default : 
    3328                 { 
    3329                     return(qfalse); 
    3330                 } 
    3331             } 
    3332  
    3333             break; 
    3334         } 
    3335  
    3336         default : 
    3337         { 
    3338             return(qfalse); 
    3339         } 
    3340     } 
    3341  
    3342     /* 
    3343      *  Calculate the size of one scanline 
    3344      */ 
    3345  
    3346     BytesPerScanline = (IHDR_Width * BytesPerPixel + (PixelsPerByte - 1)) / PixelsPerByte; 
    3347  
    3348     /* 
    3349      *  Check if we have enough data for the whole image. 
    3350      */ 
    3351  
    3352     if(!(DecompressedDataLength == ((BytesPerScanline + 1) * IHDR_Height))) 
    3353     { 
    3354         return(qfalse); 
    3355     } 
    3356  
    3357     /* 
    3358      *  Unfilter the image. 
    3359      */ 
    3360  
    3361     if(!UnfilterImage(DecompressedData, IHDR_Height, BytesPerScanline, BytesPerPixel)) 
    3362     { 
    3363         return(qfalse); 
    3364     } 
    3365  
    3366     /* 
    3367      *  Set the working pointers to the beginning of the buffers. 
    3368      */ 
    3369  
    3370     OutPtr = OutBuffer; 
    3371     DecompPtr = DecompressedData; 
    3372  
    3373     /* 
    3374      *  Create the output image. 
    3375      */ 
    3376  
    3377     for(h = 0; h < IHDR_Height; h++) 
    3378     { 
    3379         /* 
    3380          *  Count the pixels on the scanline for those multipixel bytes 
    3381          */ 
    3382  
    3383         uint32_t CurrPixel; 
    3384    
    3385         /* 
    3386          *  skip FilterType 
    3387          */ 
    3388  
    3389         DecompPtr++; 
    3390  
    3391         /* 
    3392          *  Reset the pixel count. 
    3393          */ 
    3394  
    3395         CurrPixel = 0; 
    3396  
    3397         for(w = 0; w < (BytesPerScanline / BytesPerPixel); w++) 
    3398         { 
    3399             if(PixelsPerByte > 1) 
    3400             { 
    3401                 uint8_t  Mask; 
    3402                 uint32_t Shift; 
    3403                 uint8_t  SinglePixel; 
    3404  
    3405                 for(p = 0; p < PixelsPerByte; p++) 
    3406                 { 
    3407                     if(CurrPixel < IHDR_Width) 
    3408                     { 
    3409                         Mask  = (1 << IHDR->BitDepth) - 1; 
    3410                         Shift = (PixelsPerByte - 1 - p) * IHDR->BitDepth; 
    3411  
    3412                         SinglePixel = ((DecompPtr[0] & (Mask << Shift)) >> Shift); 
    3413  
    3414                         if(!ConvertPixel(IHDR, OutPtr, &SinglePixel, HasTransparentColour, TransparentColour, OutPal)) 
    3415                         { 
    3416                             return(qfalse); 
    3417                         } 
    3418  
    3419                         OutPtr += Q3IMAGE_BYTESPERPIXEL; 
    3420                         CurrPixel++; 
    3421                     } 
    3422                 } 
    3423              
    3424             } 
    3425             else 
    3426             { 
    3427                 if(!ConvertPixel(IHDR, OutPtr, DecompPtr, HasTransparentColour, TransparentColour, OutPal)) 
    3428                 { 
    3429                     return(qfalse); 
    3430                 } 
    3431    
    3432  
    3433                 OutPtr += Q3IMAGE_BYTESPERPIXEL; 
    3434             } 
    3435  
    3436             DecompPtr += BytesPerPixel; 
    3437         } 
    3438     } 
    3439  
    3440     return(qtrue); 
    3441 } 
    3442  
    3443 /* 
    3444  *  Decode an interlaced image. 
    3445  */ 
    3446  
    3447 static qboolean DecodeImageInterlaced(struct PNG_Chunk_IHDR *IHDR, 
    3448                                       byte                  *OutBuffer,  
    3449                                       uint8_t               *DecompressedData, 
    3450                                       uint32_t               DecompressedDataLength, 
    3451                                       qboolean               HasTransparentColour, 
    3452                                       uint8_t               *TransparentColour, 
    3453                                       uint8_t               *OutPal) 
    3454 { 
    3455     uint32_t IHDR_Width; 
    3456     uint32_t IHDR_Height; 
    3457     uint32_t BytesPerScanline[PNG_Adam7_NumPasses], BytesPerPixel, PixelsPerByte; 
    3458     uint32_t PassWidth[PNG_Adam7_NumPasses], PassHeight[PNG_Adam7_NumPasses]; 
    3459     uint32_t WSkip[PNG_Adam7_NumPasses], WOffset[PNG_Adam7_NumPasses], HSkip[PNG_Adam7_NumPasses], HOffset[PNG_Adam7_NumPasses]; 
    3460     uint32_t w, h, p, a; 
    3461     byte *OutPtr; 
    3462     uint8_t *DecompPtr; 
    3463     uint32_t TargetLength; 
    3464  
    3465     /* 
    3466      *  input verification 
    3467      */ 
    3468  
    3469     if(!(IHDR && OutBuffer && DecompressedData && DecompressedDataLength && TransparentColour && OutPal)) 
    3470     { 
    3471         return(qfalse); 
    3472     } 
    3473  
    3474     /* 
    3475      *  byte swapping 
    3476      */ 
    3477  
    3478     IHDR_Width  = BigLong(IHDR->Width); 
    3479     IHDR_Height = BigLong(IHDR->Height); 
    3480  
    3481     /* 
    3482      *  Skip and Offset for the passes. 
    3483      */ 
    3484  
    3485     WSkip[0]   = 8; 
    3486     WOffset[0] = 0; 
    3487     HSkip[0]   = 8; 
    3488     HOffset[0] = 0; 
    3489  
    3490     WSkip[1]   = 8; 
    3491     WOffset[1] = 4; 
    3492     HSkip[1]   = 8; 
    3493     HOffset[1] = 0; 
    3494  
    3495     WSkip[2]   = 4; 
    3496     WOffset[2] = 0; 
    3497     HSkip[2]   = 8; 
    3498     HOffset[2] = 4; 
    3499  
    3500     WSkip[3]   = 4; 
    3501     WOffset[3] = 2; 
    3502     HSkip[3]   = 4; 
    3503     HOffset[3] = 0; 
    3504  
    3505     WSkip[4]   = 2; 
    3506     WOffset[4] = 0; 
    3507     HSkip[4]   = 4; 
    3508     HOffset[4] = 2; 
    3509  
    3510     WSkip[5]   = 2; 
    3511     WOffset[5] = 1; 
    3512     HSkip[5]   = 2; 
    3513     HOffset[5] = 0; 
    3514  
    3515     WSkip[6]   = 1; 
    3516     WOffset[6] = 0; 
    3517     HSkip[6]   = 2; 
    3518     HOffset[6] = 1; 
    3519  
    3520     /* 
    3521      *  Calculate the sizes of the passes. 
    3522      */ 
    3523  
    3524     PassWidth[0]  = (IHDR_Width  + 7) / 8; 
    3525     PassHeight[0] = (IHDR_Height + 7) / 8; 
    3526  
    3527     PassWidth[1]  = (IHDR_Width  + 3) / 8; 
    3528     PassHeight[1] = (IHDR_Height + 7) / 8; 
    3529  
    3530     PassWidth[2]  = (IHDR_Width  + 3) / 4; 
    3531     PassHeight[2] = (IHDR_Height + 3) / 8; 
    3532  
    3533     PassWidth[3]  = (IHDR_Width  + 1) / 4; 
    3534     PassHeight[3] = (IHDR_Height + 3) / 4; 
    3535  
    3536     PassWidth[4]  = (IHDR_Width  + 1) / 2; 
    3537     PassHeight[4] = (IHDR_Height + 1) / 4; 
    3538  
    3539     PassWidth[5]  = (IHDR_Width  + 0) / 2; 
    3540     PassHeight[5] = (IHDR_Height + 1) / 2; 
    3541  
    3542     PassWidth[6]  = (IHDR_Width  + 0) / 1; 
    3543     PassHeight[6] = (IHDR_Height + 0) / 2; 
    3544  
    3545     /* 
    3546      *  information for un-filtering 
    3547      */ 
    3548  
    3549     switch(IHDR->ColourType) 
    3550     { 
    3551         case PNG_ColourType_Grey : 
    3552         { 
    3553             switch(IHDR->BitDepth) 
    3554             { 
    3555                 case PNG_BitDepth_1 : 
    3556                 case PNG_BitDepth_2 : 
    3557                 case PNG_BitDepth_4 : 
    3558                 { 
    3559                     BytesPerPixel    = 1; 
    3560                     PixelsPerByte    = 8 / IHDR->BitDepth; 
    3561  
    3562                     break; 
    3563                 } 
    3564  
    3565                 case PNG_BitDepth_8  : 
    3566                 case PNG_BitDepth_16 : 
    3567                 { 
    3568                     BytesPerPixel    = (IHDR->BitDepth / 8) * PNG_NumColourComponents_Grey; 
    3569                     PixelsPerByte    = 1; 
    3570  
    3571                     break; 
    3572                 } 
    3573  
    3574                 default : 
    3575                 { 
    3576                     return(qfalse); 
    3577                 } 
    3578             } 
    3579    
    3580             break; 
    3581         } 
    3582    
    3583         case PNG_ColourType_True : 
    3584         { 
    3585             switch(IHDR->BitDepth) 
    3586             { 
    3587                 case PNG_BitDepth_8  : 
    3588                 case PNG_BitDepth_16 : 
    3589                 { 
    3590                     BytesPerPixel    = (IHDR->BitDepth / 8) * PNG_NumColourComponents_True; 
    3591                     PixelsPerByte    = 1; 
    3592  
    3593                     break; 
    3594                 } 
    3595       
    3596                 default : 
    3597                 { 
    3598                     return(qfalse); 
    3599                 } 
    3600             } 
    3601    
    3602             break; 
    3603         } 
    3604  
    3605         case PNG_ColourType_Indexed : 
    3606         { 
    3607             switch(IHDR->BitDepth) 
    3608             { 
    3609                 case PNG_BitDepth_1 : 
    3610                 case PNG_BitDepth_2 : 
    3611                 case PNG_BitDepth_4 : 
    3612                 { 
    3613                     BytesPerPixel    = 1; 
    3614                     PixelsPerByte    = 8 / IHDR->BitDepth; 
    3615  
    3616                     break; 
    3617                 } 
    3618  
    3619                 case PNG_BitDepth_8 : 
    3620                 { 
    3621                     BytesPerPixel    = PNG_NumColourComponents_Indexed; 
    3622                     PixelsPerByte    = 1; 
    3623  
    3624                     break; 
    3625                 } 
    3626           
    3627                 default : 
    3628                 { 
    3629                     return(qfalse); 
    3630                 } 
    3631             } 
    3632    
    3633             break; 
    3634         } 
    3635  
    3636         case PNG_ColourType_GreyAlpha : 
    3637         { 
    3638             switch(IHDR->BitDepth) 
    3639             { 
    3640                 case PNG_BitDepth_8 : 
    3641                 case PNG_BitDepth_16 : 
    3642                 { 
    3643                     BytesPerPixel    = (IHDR->BitDepth / 8) * PNG_NumColourComponents_GreyAlpha; 
    3644                     PixelsPerByte    = 1; 
    3645  
    3646                     break; 
    3647                 } 
    3648       
    3649                 default : 
    3650                 { 
    3651                     return(qfalse); 
    3652                 } 
    3653             } 
    3654    
    3655             break; 
    3656         } 
    3657  
    3658         case PNG_ColourType_TrueAlpha : 
    3659         { 
    3660             switch(IHDR->BitDepth) 
    3661             { 
    3662                 case PNG_BitDepth_8 : 
    3663                 case PNG_BitDepth_16 : 
    3664                 { 
    3665                     BytesPerPixel    = (IHDR->BitDepth / 8) * PNG_NumColourComponents_TrueAlpha; 
    3666                     PixelsPerByte    = 1; 
    3667  
    3668                     break; 
    3669                 } 
    3670      
    3671                 default : 
    3672                 { 
    3673                     return(qfalse); 
    3674                 } 
    3675             } 
    3676  
    3677             break; 
    3678         } 
    3679  
    3680         default : 
    3681         { 
    3682             return(qfalse); 
    3683         } 
    3684     } 
    3685  
    3686     /* 
    3687      *  Calculate the size of the scanlines per pass 
    3688      */ 
    3689  
    3690     for(a = 0; a < PNG_Adam7_NumPasses; a++) 
    3691     { 
    3692         BytesPerScanline[a] = (PassWidth[a] * BytesPerPixel + (PixelsPerByte - 1)) / PixelsPerByte; 
    3693     } 
    3694  
    3695     /* 
    3696      *  Calculate the size of all passes 
    3697      */ 
    3698  
    3699     TargetLength = 0; 
    3700  
    3701     for(a = 0; a < PNG_Adam7_NumPasses; a++) 
    3702     { 
    3703         TargetLength += ((BytesPerScanline[a] + (BytesPerScanline[a] ? 1 : 0)) * PassHeight[a]); 
    3704     } 
    3705  
    3706     /* 
    3707      *  Check if we have enough data for the whole image. 
    3708      */ 
    3709  
    3710     if(!(DecompressedDataLength == TargetLength)) 
    3711     { 
    3712         return(qfalse); 
    3713     } 
    3714  
    3715     /* 
    3716      *  Unfilter the image. 
    3717      */ 
    3718  
    3719     DecompPtr = DecompressedData; 
    3720  
    3721     for(a = 0; a < PNG_Adam7_NumPasses; a++) 
    3722     { 
    3723         if(!UnfilterImage(DecompPtr, PassHeight[a], BytesPerScanline[a], BytesPerPixel)) 
    3724         { 
    3725             return(qfalse); 
    3726         } 
    3727          
    3728         DecompPtr += ((BytesPerScanline[a] + (BytesPerScanline[a] ? 1 : 0)) * PassHeight[a]); 
    3729     } 
    3730  
    3731     /* 
    3732      *  Set the working pointers to the beginning of the buffers. 
    3733      */ 
    3734  
    3735     DecompPtr = DecompressedData; 
    3736  
    3737     /* 
    3738      *  Create the output image. 
    3739      */ 
    3740  
    3741     for(a = 0; a < PNG_Adam7_NumPasses; a++) 
    3742     { 
    3743         for(h = 0; h < PassHeight[a]; h++) 
    3744         { 
    3745             /* 
    3746              *  Count the pixels on the scanline for those multipixel bytes 
    3747              */ 
    3748  
    3749             uint32_t CurrPixel; 
    3750  
    3751             /* 
    3752              *  skip FilterType 
    3753              */ 
    3754  
    3755             DecompPtr++; 
    3756  
    3757             /* 
    3758              *  Reset the pixel count. 
    3759              */ 
    3760  
    3761             CurrPixel = 0; 
    3762  
    3763             for(w = 0; w < (BytesPerScanline[a] / BytesPerPixel); w++) 
    3764             { 
    3765                 if(PixelsPerByte > 1) 
    3766                 { 
    3767                     uint8_t  Mask; 
    3768                     uint32_t Shift; 
    3769                     uint8_t  SinglePixel; 
    3770  
    3771                     for(p = 0; p < PixelsPerByte; p++) 
    3772                     { 
    3773                         if(CurrPixel < PassWidth[a]) 
    3774                         { 
    3775                             Mask  = (1 << IHDR->BitDepth) - 1; 
    3776                             Shift = (PixelsPerByte - 1 - p) * IHDR->BitDepth; 
    3777  
    3778                             SinglePixel = ((DecompPtr[0] & (Mask << Shift)) >> Shift); 
    3779  
    3780                             OutPtr = OutBuffer + (((((h * HSkip[a]) + HOffset[a]) * IHDR_Width) + ((CurrPixel * WSkip[a]) + WOffset[a])) * Q3IMAGE_BYTESPERPIXEL); 
    3781  
    3782                             if(!ConvertPixel(IHDR, OutPtr, &SinglePixel, HasTransparentColour, TransparentColour, OutPal)) 
    3783                             { 
    3784                                 return(qfalse); 
    3785                             } 
    3786  
    3787                             CurrPixel++; 
    3788                         } 
    3789                     } 
    3790              
    3791                 } 
    3792                 else 
    3793                 { 
    3794                     OutPtr = OutBuffer + (((((h * HSkip[a]) + HOffset[a]) * IHDR_Width) + ((w * WSkip[a]) + WOffset[a])) * Q3IMAGE_BYTESPERPIXEL); 
    3795  
    3796                     if(!ConvertPixel(IHDR, OutPtr, DecompPtr, HasTransparentColour, TransparentColour, OutPal)) 
    3797                     { 
    3798                         return(qfalse); 
    3799                     } 
    3800                 } 
    3801  
    3802                 DecompPtr += BytesPerPixel; 
    3803             } 
    3804         } 
    3805     } 
    3806  
    3807     return(qtrue); 
    3808 } 
    3809  
    3810 /* 
    3811  *  The PNG loader 
    3812  */ 
    3813  
    3814 static void LoadPNG(const char *name, byte **pic, int *width, int *height) 
    3815 { 
    3816     struct BufferedFile *ThePNG; 
    3817     byte *OutBuffer; 
    3818     uint8_t *Signature; 
    3819     struct PNG_ChunkHeader *CH; 
    3820     uint32_t ChunkHeaderLength; 
    3821     uint32_t ChunkHeaderType; 
    3822     struct PNG_Chunk_IHDR *IHDR; 
    3823     uint32_t IHDR_Width; 
    3824     uint32_t IHDR_Height; 
    3825     PNG_ChunkCRC *CRC; 
    3826     uint8_t *InPal; 
    3827     uint8_t *DecompressedData; 
    3828     uint32_t DecompressedDataLength; 
    3829     uint32_t i; 
    3830  
    3831     /* 
    3832      *  palette with 256 RGBA entries 
    3833      */ 
    3834  
    3835     uint8_t OutPal[1024]; 
    3836  
    3837     /* 
    3838      *  transparent colour from the tRNS chunk 
    3839      */ 
    3840  
    3841     qboolean HasTransparentColour = qfalse; 
    3842     uint8_t TransparentColour[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 
    3843  
    3844     /* 
    3845      *  input verification 
    3846      */ 
    3847  
    3848     if(!(name && pic)) 
    3849     { 
    3850         return; 
    3851     } 
    3852  
    3853     /* 
    3854      *  Zero out return values. 
    3855      */ 
    3856  
    3857     *pic = NULL; 
    3858  
    3859     if(width) 
    3860     { 
    3861         *width = 0; 
    3862     } 
    3863  
    3864     if(height) 
    3865     { 
    3866         *height = 0; 
    3867     } 
    3868  
    3869     /* 
    3870      *  Read the file. 
    3871      */ 
    3872  
    3873     ThePNG = ReadBufferedFile(name); 
    3874     if(!ThePNG) 
    3875     { 
    3876         return; 
    3877     }            
    3878  
    3879     /* 
    3880      *  Read the siganture of the file. 
    3881      */ 
    3882  
    3883     Signature = BufferedFileRead(ThePNG, PNG_Signature_Size); 
    3884     if(!Signature) 
    3885     { 
    3886         CloseBufferedFile(ThePNG); 
    3887   
    3888         return; 
    3889     } 
    3890   
    3891     /* 
    3892      *  Is it a PNG? 
    3893      */ 
    3894  
    3895     if(memcmp(Signature, PNG_Signature, PNG_Signature_Size)) 
    3896     { 
    3897         CloseBufferedFile(ThePNG); 
    3898   
    3899         return;  
    3900     } 
    3901  
    3902     /* 
    3903      *  Read the first chunk-header. 
    3904      */ 
    3905  
    3906     CH = BufferedFileRead(ThePNG, PNG_ChunkHeader_Size); 
    3907     if(!CH) 
    3908     { 
    3909         CloseBufferedFile(ThePNG); 
    3910   
    3911         return;  
    3912     } 
    3913  
    3914     /* 
    3915      *  PNG multi-byte types are in Big Endian 
    3916      */ 
    3917  
    3918     ChunkHeaderLength = BigLong(CH->Length); 
    3919     ChunkHeaderType   = BigLong(CH->Type); 
    3920  
    3921     /* 
    3922      *  Check if the first chunk is an IHDR. 
    3923      */ 
    3924  
    3925     if(!((ChunkHeaderType == PNG_ChunkType_IHDR) && (ChunkHeaderLength == PNG_Chunk_IHDR_Size))) 
    3926     { 
    3927         CloseBufferedFile(ThePNG); 
    3928   
    3929         return;  
    3930     } 
    3931  
    3932     /* 
    3933      *  Read the IHDR. 
    3934      */  
    3935  
    3936     IHDR = BufferedFileRead(ThePNG, PNG_Chunk_IHDR_Size); 
    3937     if(!IHDR) 
    3938     { 
    3939         CloseBufferedFile(ThePNG); 
    3940   
    3941         return;  
    3942     } 
    3943  
    3944     /* 
    3945      *  Read the CRC for IHDR 
    3946      */ 
    3947  
    3948     CRC = BufferedFileRead(ThePNG, PNG_ChunkCRC_Size); 
    3949     if(!CRC) 
    3950     { 
    3951         CloseBufferedFile(ThePNG); 
    3952   
    3953         return;  
    3954     } 
    3955   
    3956     /* 
    3957      *  Here we could check the CRC if we wanted to. 
    3958      */ 
    3959   
    3960     /* 
    3961      *  multi-byte type swapping 
    3962      */ 
    3963  
    3964     IHDR_Width  = BigLong(IHDR->Width); 
    3965     IHDR_Height = BigLong(IHDR->Height); 
    3966   
    3967     /* 
    3968      *  Check if Width and Height are valid. 
    3969      */ 
    3970  
    3971     if(!((IHDR_Width > 0) && (IHDR_Height > 0))) 
    3972     { 
    3973         CloseBufferedFile(ThePNG); 
    3974   
    3975         return;  
    3976     } 
    3977  
    3978     /* 
    3979      *  Do we need to check if the dimensions of the image are valid for Quake3? 
    3980      */ 
    3981  
    3982     /* 
    3983      *  Check if CompressionMethod and FilterMethod are valid. 
    3984      */ 
    3985  
    3986     if(!((IHDR->CompressionMethod == PNG_CompressionMethod_0) && (IHDR->FilterMethod == PNG_FilterMethod_0))) 
    3987     { 
    3988         CloseBufferedFile(ThePNG); 
    3989   
    3990         return;  
    3991     } 
    3992  
    3993     /* 
    3994      *  Check if InterlaceMethod is valid. 
    3995      */ 
    3996  
    3997     if(!((IHDR->InterlaceMethod == PNG_InterlaceMethod_NonInterlaced)  || (IHDR->InterlaceMethod == PNG_InterlaceMethod_Interlaced))) 
    3998     { 
    3999         CloseBufferedFile(ThePNG); 
    4000   
    4001         return; 
    4002     } 
    4003  
    4004     /* 
    4005      *  Read palette for an indexed image. 
    4006      */ 
    4007  
    4008     if(IHDR->ColourType == PNG_ColourType_Indexed) 
    4009     { 
    4010         /* 
    4011          *  We need the palette first. 
    4012          */ 
    4013  
    4014         if(!FindChunk(ThePNG, PNG_ChunkType_PLTE)) 
    4015         { 
    4016             CloseBufferedFile(ThePNG); 
    4017    
    4018             return; 
    4019         } 
    4020  
    4021         /* 
    4022          *  Read the chunk-header. 
    4023          */ 
    4024  
    4025         CH = BufferedFileRead(ThePNG, PNG_ChunkHeader_Size); 
    4026         if(!CH) 
    4027         { 
    4028             CloseBufferedFile(ThePNG); 
    4029     
    4030             return;  
    4031         } 
    4032  
    4033         /* 
    4034          *  PNG multi-byte types are in Big Endian 
    4035          */ 
    4036  
    4037         ChunkHeaderLength = BigLong(CH->Length); 
    4038         ChunkHeaderType   = BigLong(CH->Type); 
    4039    
    4040         /* 
    4041          *  Check if the chunk is an PLTE. 
    4042          */ 
    4043  
    4044         if(!(ChunkHeaderType == PNG_ChunkType_PLTE)) 
    4045         { 
    4046             CloseBufferedFile(ThePNG); 
    4047     
    4048             return;  
    4049         } 
    4050  
    4051         /* 
    4052          *  Check if Length is divisible by 3 
    4053          */ 
    4054  
    4055         if(ChunkHeaderLength % 3) 
    4056         { 
    4057             CloseBufferedFile(ThePNG); 
    4058     
    4059             return;    
    4060         } 
    4061  
    4062         /* 
    4063          *  Read the raw palette data 
    4064          */ 
    4065  
    4066         InPal = BufferedFileRead(ThePNG, ChunkHeaderLength); 
    4067         if(!InPal) 
    4068         { 
    4069             CloseBufferedFile(ThePNG); 
    4070     
    4071             return;  
    4072         } 
    4073     
    4074         /* 
    4075          *  Read the CRC for the palette 
    4076          */ 
    4077  
    4078         CRC = BufferedFileRead(ThePNG, PNG_ChunkCRC_Size); 
    4079         if(!CRC) 
    4080         { 
    4081             CloseBufferedFile(ThePNG); 
    4082   
    4083             return;  
    4084         } 
    4085  
    4086         /* 
    4087          *  Set some default values. 
    4088          */ 
    4089  
    4090         for(i = 0; i < 256; i++) 
    4091         { 
    4092             OutPal[i * Q3IMAGE_BYTESPERPIXEL + 0] = 0x00; 
    4093             OutPal[i * Q3IMAGE_BYTESPERPIXEL + 1] = 0x00; 
    4094             OutPal[i * Q3IMAGE_BYTESPERPIXEL + 2] = 0x00; 
    4095             OutPal[i * Q3IMAGE_BYTESPERPIXEL + 3] = 0xFF;   
    4096         } 
    4097  
    4098         /* 
    4099          *  Convert to the Quake3 RGBA-format. 
    4100          */ 
    4101  
    4102         for(i = 0; i < (ChunkHeaderLength / 3); i++) 
    4103         { 
    4104             OutPal[i * Q3IMAGE_BYTESPERPIXEL + 0] = InPal[i*3+0]; 
    4105             OutPal[i * Q3IMAGE_BYTESPERPIXEL + 1] = InPal[i*3+1]; 
    4106             OutPal[i * Q3IMAGE_BYTESPERPIXEL + 2] = InPal[i*3+2]; 
    4107             OutPal[i * Q3IMAGE_BYTESPERPIXEL + 3] = 0xFF; 
    4108         } 
    4109     } 
    4110  
    4111     /* 
    4112      *  transparency information is sometimes stored in an tRNS chunk 
    4113      */ 
    4114  
    4115     /* 
    4116      *  Let's see if there is a tRNS chunk 
    4117      */ 
    4118  
    4119     if(FindChunk(ThePNG, PNG_ChunkType_tRNS)) 
    4120     { 
    4121         uint8_t *Trans; 
    4122  
    4123         /* 
    4124          *  Read the chunk-header. 
    4125          */ 
    4126  
    4127         CH = BufferedFileRead(ThePNG, PNG_ChunkHeader_Size); 
    4128         if(!CH) 
    4129         { 
    4130             CloseBufferedFile(ThePNG); 
    4131   
    4132             return;  
    4133         } 
    4134  
    4135         /* 
    4136          *  PNG multi-byte types are in Big Endian 
    4137          */ 
    4138  
    4139         ChunkHeaderLength = BigLong(CH->Length); 
    4140         ChunkHeaderType   = BigLong(CH->Type); 
    4141  
    4142         /* 
    4143          *  Check if the chunk is an tRNS. 
    4144          */ 
    4145  
    4146         if(!(ChunkHeaderType == PNG_ChunkType_tRNS)) 
    4147         { 
    4148             CloseBufferedFile(ThePNG); 
    4149   
    4150             return;  
    4151         } 
    4152  
    4153         /* 
    4154          *  Read the transparency information. 
    4155          */ 
    4156  
    4157         Trans = BufferedFileRead(ThePNG, ChunkHeaderLength); 
    4158         if(!Trans) 
    4159         { 
    4160             CloseBufferedFile(ThePNG); 
    4161   
    4162             return;   
    4163         } 
    4164  
    4165         /* 
    4166          *  Read the CRC. 
    4167          */ 
    4168  
    4169         CRC = BufferedFileRead(ThePNG, PNG_ChunkCRC_Size); 
    4170         if(!CRC) 
    4171         { 
    4172             CloseBufferedFile(ThePNG); 
    4173    
    4174             return;  
    4175         } 
    4176   
    4177         /* 
    4178          *  Only for Grey, True and Indexed ColourType should tRNS exist. 
    4179          */ 
    4180  
    4181         switch(IHDR->ColourType) 
    4182         { 
    4183             case PNG_ColourType_Grey : 
    4184             { 
    4185                 if(!ChunkHeaderLength == 2) 
    4186                 { 
    4187                     CloseBufferedFile(ThePNG); 
    4188    
    4189                     return;     
    4190                 } 
    4191     
    4192                 HasTransparentColour = qtrue; 
    4193     
    4194                 /* 
    4195                  *  Grey can have one colour which is completely transparent. 
    4196                  *  This colour is always stored in 16 bits. 
    4197                  */ 
    4198  
    4199                 TransparentColour[0] = Trans[0]; 
    4200                 TransparentColour[1] = Trans[1]; 
    4201     
    4202                 break; 
    4203             } 
    4204     
    4205             case PNG_ColourType_True : 
    4206             { 
    4207                 if(!ChunkHeaderLength == 6) 
    4208                 { 
    4209                     CloseBufferedFile(ThePNG); 
    4210    
    4211                     return;     
    4212                 } 
    4213     
    4214                 HasTransparentColour = qtrue; 
    4215  
    4216                 /* 
    4217                  *  True can have one colour which is completely transparent. 
    4218                  *  This colour is always stored in 16 bits. 
    4219                  */ 
    4220  
    4221                 TransparentColour[0] = Trans[0]; 
    4222                 TransparentColour[1] = Trans[1]; 
    4223                 TransparentColour[2] = Trans[2]; 
    4224                 TransparentColour[3] = Trans[3]; 
    4225                 TransparentColour[4] = Trans[4]; 
    4226                 TransparentColour[5] = Trans[5]; 
    4227     
    4228                 break; 
    4229             } 
    4230     
    4231             case PNG_ColourType_Indexed : 
    4232             { 
    4233                 /* 
    4234                  *  Maximum of 256 one byte transparency entries. 
    4235                  */ 
    4236                  
    4237                 if(ChunkHeaderLength > 256) 
    4238                 { 
    4239                     CloseBufferedFile(ThePNG); 
    4240    
    4241                     return;     
    4242                 } 
    4243  
    4244                 HasTransparentColour = qtrue; 
    4245  
    4246                 /* 
    4247                  *  alpha values for palette entries 
    4248                  */ 
    4249  
    4250                 for(i = 0; i < ChunkHeaderLength; i++) 
    4251                 { 
    4252                     OutPal[i * Q3IMAGE_BYTESPERPIXEL + 3] = Trans[i]; 
    4253                 } 
    4254  
    4255                 break; 
    4256             } 
    4257    
    4258             /* 
    4259              *  All other ColourTypes should not have tRNS chunks 
    4260              */ 
    4261  
    4262             default : 
    4263             { 
    4264                 CloseBufferedFile(ThePNG); 
    4265    
    4266                 return; 
    4267             } 
    4268         }  
    4269     } 
    4270  
    4271     /* 
    4272      *  Rewind to the start of the file. 
    4273      */ 
    4274  
    4275     if(!BufferedFileRewind(ThePNG, -1)) 
    4276     { 
    4277         CloseBufferedFile(ThePNG); 
    4278   
    4279         return;  
    4280     } 
    4281   
    4282     /* 
    4283      *  Skip the signature 
    4284      */ 
    4285  
    4286     if(!BufferedFileSkip(ThePNG, PNG_Signature_Size)) 
    4287     { 
    4288         CloseBufferedFile(ThePNG); 
    4289   
    4290         return;  
    4291     } 
    4292  
    4293     /* 
    4294      *  Decompress all IDAT chunks 
    4295      */ 
    4296  
    4297     DecompressedDataLength = DecompressIDATs(ThePNG, &DecompressedData); 
    4298     if(!(DecompressedDataLength && DecompressedData)) 
    4299     { 
    4300         CloseBufferedFile(ThePNG); 
    4301   
    4302         return; 
    4303     } 
    4304  
    4305     /* 
    4306      *  Allocate output buffer. 
    4307      */ 
    4308  
    4309     OutBuffer = ri.Malloc(IHDR_Width * IHDR_Height * Q3IMAGE_BYTESPERPIXEL);  
    4310     if(!OutBuffer) 
    4311     { 
    4312         ri.Free(DecompressedData);  
    4313         CloseBufferedFile(ThePNG); 
    4314   
    4315         return;   
    4316     } 
    4317  
    4318     /* 
    4319      *  Interlaced and Non-interlaced images need to be handled differently. 
    4320      */ 
    4321  
    4322     switch(IHDR->InterlaceMethod) 
    4323     { 
    4324         case PNG_InterlaceMethod_NonInterlaced : 
    4325         { 
    4326             if(!DecodeImageNonInterlaced(IHDR, OutBuffer, DecompressedData, DecompressedDataLength, HasTransparentColour, TransparentColour, OutPal)) 
    4327             { 
    4328                 ri.Free(OutBuffer);  
    4329                 ri.Free(DecompressedData);  
    4330                 CloseBufferedFile(ThePNG); 
    4331  
    4332                 return; 
    4333             } 
    4334          
    4335             break; 
    4336         } 
    4337          
    4338         case PNG_InterlaceMethod_Interlaced : 
    4339         { 
    4340             if(!DecodeImageInterlaced(IHDR, OutBuffer, DecompressedData, DecompressedDataLength, HasTransparentColour, TransparentColour, OutPal)) 
    4341             { 
    4342                 ri.Free(OutBuffer);  
    4343                 ri.Free(DecompressedData);  
    4344                 CloseBufferedFile(ThePNG); 
    4345  
    4346                 return; 
    4347             } 
    4348          
    4349             break; 
    4350         } 
    4351      
    4352         default : 
    4353         { 
    4354             ri.Free(OutBuffer);  
    4355             ri.Free(DecompressedData);  
    4356             CloseBufferedFile(ThePNG); 
    4357  
    4358             return; 
    4359         } 
    4360     } 
    4361  
    4362     /* 
    4363      *  update the pointer to the image data 
    4364      */ 
    4365  
    4366     *pic = OutBuffer; 
    4367   
    4368     /* 
    4369      *  Fill width and height. 
    4370      */ 
    4371  
    4372     if(width) 
    4373     { 
    4374         *width = IHDR_Width; 
    4375     } 
    4376  
    4377     if(height) 
    4378     { 
    4379         *height = IHDR_Height; 
    4380     } 
    4381  
    4382     /* 
    4383      *  DecompressedData is not needed anymore. 
    4384      */ 
    4385  
    4386     ri.Free(DecompressedData);  
    4387  
    4388     /* 
    4389      *  We have all data, so close the file. 
    4390      */ 
    4391  
    4392     CloseBufferedFile(ThePNG); 
    4393 } 
    4394806 
    4395807//=================================================================== 
     
    4405817static imageExtToLoaderMap_t imageLoaders[ ] = 
    4406818{ 
    4407         { "tga",  LoadTGA }, 
    4408         { "jpg",  LoadJPG }, 
    4409         { "jpeg", LoadJPG }, 
    4410         { "png",  LoadPNG }, 
    4411         { "pcx",  LoadPCX32 }, 
    4412         { "bmp",  LoadBMP } 
     819        { "tga",  R_LoadTGA }, 
     820        { "jpg",  R_LoadJPG }, 
     821        { "jpeg", R_LoadJPG }, 
     822        { "png",  R_LoadPNG }, 
     823        { "pcx",  R_LoadPCX }, 
     824        { "bmp",  R_LoadBMP } 
    4413825}; 
    4414826 
  • src/renderer/tr_local.h

    r0 r176  
    14761476#endif 
    14771477 
     1478/* 
     1479============================================================= 
     1480 
     1481IMAGE LOADERS 
     1482 
     1483============================================================= 
     1484*/ 
     1485 
     1486void R_LoadBMP( const char *name, byte **pic, int *width, int *height ); 
     1487void R_LoadJPG( const char *name, byte **pic, int *width, int *height ); 
     1488void R_LoadPCX( const char *name, byte **pic, int *width, int *height ); 
     1489void R_LoadPNG( const char *name, byte **pic, int *width, int *height ); 
     1490void R_LoadTGA( const char *name, byte **pic, int *width, int *height ); 
    14781491/* 
    14791492=============================================================