Advertisement
Guest User

Untitled

a guest
Sep 21st, 2017
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 122.39 KB | None | 0 0
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1999-2005 Id Software, Inc.
  4.  
  5. This file is part of Quake III Arena source code.
  6.  
  7. Quake III Arena source code is free software; you can redistribute it
  8. and/or modify it under the terms of the GNU General Public License as
  9. published by the Free Software Foundation; either version 2 of the License,
  10. or (at your option) any later version.
  11.  
  12. Quake III Arena source code is distributed in the hope that it will be
  13. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with Quake III Arena source code; if not, write to the Free Software
  19. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  20. ===========================================================================
  21. */
  22. // tr_image.c
  23. #include "tr_local.h"
  24.  
  25. /*
  26.  * Include file for users of JPEG library.
  27.  * You will need to have included system headers that define at least
  28.  * the typedefs FILE and size_t before you can include jpeglib.h.
  29.  * (stdio.h is sufficient on ANSI-conforming systems.)
  30.  * You may also wish to include "jerror.h".
  31.  */
  32.  
  33. #define JPEG_INTERNALS
  34. #include "../jpeg-6/jpeglib.h"
  35.  
  36. #include "../qcommon/puff.h"
  37.  
  38.  
  39. static void LoadBMP( const char *name, byte **pic, int *width, int *height );
  40. static void LoadTGA( const char *name, byte **pic, int *width, int *height );
  41. static void LoadJPG( const char *name, byte **pic, int *width, int *height );
  42. static void LoadPNG( const char *name, byte **pic, int *width, int *height );
  43.  
  44. static byte          s_intensitytable[256];
  45. static unsigned char s_gammatable[256];
  46.  
  47. int     gl_filter_min = GL_LINEAR_MIPMAP_NEAREST;
  48. int     gl_filter_max = GL_LINEAR;
  49.  
  50. #define FILE_HASH_SIZE      1024
  51. static  image_t*        hashTable[FILE_HASH_SIZE];
  52.  
  53. /*
  54. ** R_GammaCorrect
  55. */
  56. void R_GammaCorrect( byte *buffer, int bufSize ) {
  57.     int i;
  58.  
  59.     for ( i = 0; i < bufSize; i++ ) {
  60.         buffer[i] = s_gammatable[buffer[i]];
  61.     }
  62. }
  63.  
  64. typedef struct {
  65.     char *name;
  66.     int minimize, maximize;
  67. } textureMode_t;
  68.  
  69. textureMode_t modes[] = {
  70.     {"GL_NEAREST", GL_NEAREST, GL_NEAREST},
  71.     {"GL_LINEAR", GL_LINEAR, GL_LINEAR},
  72.     {"GL_NEAREST_MIPMAP_NEAREST", GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST},
  73.     {"GL_LINEAR_MIPMAP_NEAREST", GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR},
  74.     {"GL_NEAREST_MIPMAP_LINEAR", GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST},
  75.     {"GL_LINEAR_MIPMAP_LINEAR", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR}
  76. };
  77.  
  78. /*
  79. ================
  80. return a hash value for the filename
  81. ================
  82. */
  83. static long generateHashValue( const char *fname ) {
  84.     int     i;
  85.     long    hash;
  86.     char    letter;
  87.  
  88.     hash = 0;
  89.     i = 0;
  90.     while (fname[i] != '\0') {
  91.         letter = tolower(fname[i]);
  92.         if (letter =='.') break;                // don't include extension
  93.         if (letter =='\\') letter = '/';        // damn path names
  94.         hash+=(long)(letter)*(i+119);
  95.         i++;
  96.     }
  97.     hash &= (FILE_HASH_SIZE-1);
  98.     return hash;
  99. }
  100.  
  101. /*
  102. ===============
  103. GL_TextureMode
  104. ===============
  105. */
  106. void GL_TextureMode( const char *string ) {
  107.     int     i;
  108.     image_t *glt;
  109.  
  110.     for ( i=0 ; i< 6 ; i++ ) {
  111.         if ( !Q_stricmp( modes[i].name, string ) ) {
  112.             break;
  113.         }
  114.     }
  115.  
  116.     // hack to prevent trilinear from being set on voodoo,
  117.     // because their driver freaks...
  118.     if ( i == 5 && glConfig.hardwareType == GLHW_3DFX_2D3D ) {
  119.         ri.Printf( PRINT_ALL, "Refusing to set trilinear on a voodoo.\n" );
  120.         i = 3;
  121.     }
  122.  
  123.  
  124.     if ( i == 6 ) {
  125.         ri.Printf (PRINT_ALL, "bad filter name\n");
  126.         return;
  127.     }
  128.  
  129.     gl_filter_min = modes[i].minimize;
  130.     gl_filter_max = modes[i].maximize;
  131.  
  132.     // change all the existing mipmap texture objects
  133.     for ( i = 0 ; i < tr.numImages ; i++ ) {
  134.         glt = tr.images[ i ];
  135.         if ( glt->mipmap ) {
  136.             GL_Bind (glt);
  137.             qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
  138.             qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
  139.         }
  140.     }
  141. }
  142.  
  143. /*
  144. ===============
  145. R_SumOfUsedImages
  146. ===============
  147. */
  148. int R_SumOfUsedImages( void ) {
  149.     int total;
  150.     int i;
  151.  
  152.     total = 0;
  153.     for ( i = 0; i < tr.numImages; i++ ) {
  154.         if ( tr.images[i]->frameUsed == tr.frameCount ) {
  155.             total += tr.images[i]->uploadWidth * tr.images[i]->uploadHeight;
  156.         }
  157.     }
  158.  
  159.     return total;
  160. }
  161.  
  162. /*
  163. ===============
  164. R_ImageList_f
  165. ===============
  166. */
  167. void R_ImageList_f( void ) {
  168.     int     i;
  169.     image_t *image;
  170.     int     texels;
  171.     const char *yesno[] = {
  172.         "no ", "yes"
  173.     };
  174.  
  175.     ri.Printf (PRINT_ALL, "\n      -w-- -h-- -mm- -TMU- -if-- wrap --name-------\n");
  176.     texels = 0;
  177.  
  178.     for ( i = 0 ; i < tr.numImages ; i++ ) {
  179.         image = tr.images[ i ];
  180.  
  181.         texels += image->uploadWidth*image->uploadHeight;
  182.         ri.Printf (PRINT_ALL,  "%4i: %4i %4i  %s   %d   ",
  183.             i, image->uploadWidth, image->uploadHeight, yesno[image->mipmap], image->TMU );
  184.         switch ( image->internalFormat ) {
  185.         case 1:
  186.             ri.Printf( PRINT_ALL, "I    " );
  187.             break;
  188.         case 2:
  189.             ri.Printf( PRINT_ALL, "IA   " );
  190.             break;
  191.         case 3:
  192.             ri.Printf( PRINT_ALL, "RGB  " );
  193.             break;
  194.         case 4:
  195.             ri.Printf( PRINT_ALL, "RGBA " );
  196.             break;
  197.         case GL_RGBA8:
  198.             ri.Printf( PRINT_ALL, "RGBA8" );
  199.             break;
  200.         case GL_RGB8:
  201.             ri.Printf( PRINT_ALL, "RGB8" );
  202.             break;
  203.         case GL_RGB4_S3TC:
  204.             ri.Printf( PRINT_ALL, "S3TC " );
  205.             break;
  206.         case GL_RGBA4:
  207.             ri.Printf( PRINT_ALL, "RGBA4" );
  208.             break;
  209.         case GL_RGB5:
  210.             ri.Printf( PRINT_ALL, "RGB5 " );
  211.             break;
  212.         default:
  213.             ri.Printf( PRINT_ALL, "???? " );
  214.         }
  215.  
  216.         switch ( image->wrapClampMode ) {
  217.         case GL_REPEAT:
  218.             ri.Printf( PRINT_ALL, "rept " );
  219.             break;
  220.         case GL_CLAMP:
  221.             ri.Printf( PRINT_ALL, "clmp " );
  222.             break;
  223.         default:
  224.             ri.Printf( PRINT_ALL, "%4i ", image->wrapClampMode );
  225.             break;
  226.         }
  227.        
  228.         ri.Printf( PRINT_ALL, " %s\n", image->imgName );
  229.     }
  230.     ri.Printf (PRINT_ALL, " ---------\n");
  231.     ri.Printf (PRINT_ALL, " %i total texels (not including mipmaps)\n", texels);
  232.     ri.Printf (PRINT_ALL, " %i total images\n\n", tr.numImages );
  233. }
  234.  
  235. //=======================================================================
  236.  
  237. /*
  238. ================
  239. ResampleTexture
  240.  
  241. Used to resample images in a more general than quartering fashion.
  242.  
  243. This will only be filtered properly if the resampled size
  244. is greater than half the original size.
  245.  
  246. If a larger shrinking is needed, use the mipmap function
  247. before or after.
  248. ================
  249. */
  250. static void ResampleTexture( unsigned *in, int inwidth, int inheight, unsigned *out,  
  251.                             int outwidth, int outheight ) {
  252.     int     i, j;
  253.     unsigned    *inrow, *inrow2;
  254.     unsigned    frac, fracstep;
  255.     unsigned    p1[2048], p2[2048];
  256.     byte        *pix1, *pix2, *pix3, *pix4;
  257.  
  258.     if (outwidth>2048)
  259.         ri.Error(ERR_DROP, "ResampleTexture: max width");
  260.                                
  261.     fracstep = inwidth*0x10000/outwidth;
  262.  
  263.     frac = fracstep>>2;
  264.     for ( i=0 ; i<outwidth ; i++ ) {
  265.         p1[i] = 4*(frac>>16);
  266.         frac += fracstep;
  267.     }
  268.     frac = 3*(fracstep>>2);
  269.     for ( i=0 ; i<outwidth ; i++ ) {
  270.         p2[i] = 4*(frac>>16);
  271.         frac += fracstep;
  272.     }
  273.  
  274.     for (i=0 ; i<outheight ; i++, out += outwidth) {
  275.         inrow = in + inwidth*(int)((i+0.25)*inheight/outheight);
  276.         inrow2 = in + inwidth*(int)((i+0.75)*inheight/outheight);
  277.         frac = fracstep >> 1;
  278.         for (j=0 ; j<outwidth ; j++) {
  279.             pix1 = (byte *)inrow + p1[j];
  280.             pix2 = (byte *)inrow + p2[j];
  281.             pix3 = (byte *)inrow2 + p1[j];
  282.             pix4 = (byte *)inrow2 + p2[j];
  283.             ((byte *)(out+j))[0] = (pix1[0] + pix2[0] + pix3[0] + pix4[0])>>2;
  284.             ((byte *)(out+j))[1] = (pix1[1] + pix2[1] + pix3[1] + pix4[1])>>2;
  285.             ((byte *)(out+j))[2] = (pix1[2] + pix2[2] + pix3[2] + pix4[2])>>2;
  286.             ((byte *)(out+j))[3] = (pix1[3] + pix2[3] + pix3[3] + pix4[3])>>2;
  287.         }
  288.     }
  289. }
  290.  
  291. /*
  292. ================
  293. R_LightScaleTexture
  294.  
  295. Scale up the pixel values in a texture to increase the
  296. lighting range
  297. ================
  298. */
  299. void R_LightScaleTexture (unsigned *in, int inwidth, int inheight, qboolean only_gamma )
  300. {
  301.     if ( only_gamma )
  302.     {
  303.         if ( !glConfig.deviceSupportsGamma )
  304.         {
  305.             int     i, c;
  306.             byte    *p;
  307.  
  308.             p = (byte *)in;
  309.  
  310.             c = inwidth*inheight;
  311.             for (i=0 ; i<c ; i++, p+=4)
  312.             {
  313.                 p[0] = s_gammatable[p[0]];
  314.                 p[1] = s_gammatable[p[1]];
  315.                 p[2] = s_gammatable[p[2]];
  316.             }
  317.         }
  318.     }
  319.     else
  320.     {
  321.         int     i, c;
  322.         byte    *p;
  323.  
  324.         p = (byte *)in;
  325.  
  326.         c = inwidth*inheight;
  327.  
  328.         if ( glConfig.deviceSupportsGamma )
  329.         {
  330.             for (i=0 ; i<c ; i++, p+=4)
  331.             {
  332.                 p[0] = s_intensitytable[p[0]];
  333.                 p[1] = s_intensitytable[p[1]];
  334.                 p[2] = s_intensitytable[p[2]];
  335.             }
  336.         }
  337.         else
  338.         {
  339.             for (i=0 ; i<c ; i++, p+=4)
  340.             {
  341.                 p[0] = s_gammatable[s_intensitytable[p[0]]];
  342.                 p[1] = s_gammatable[s_intensitytable[p[1]]];
  343.                 p[2] = s_gammatable[s_intensitytable[p[2]]];
  344.             }
  345.         }
  346.     }
  347. }
  348.  
  349.  
  350. /*
  351. ================
  352. R_MipMap2
  353.  
  354. Operates in place, quartering the size of the texture
  355. Proper linear filter
  356. ================
  357. */
  358. static void R_MipMap2( unsigned *in, int inWidth, int inHeight ) {
  359.     int         i, j, k;
  360.     byte        *outpix;
  361.     int         inWidthMask, inHeightMask;
  362.     int         total;
  363.     int         outWidth, outHeight;
  364.     unsigned    *temp;
  365.  
  366.     outWidth = inWidth >> 1;
  367.     outHeight = inHeight >> 1;
  368.     temp = ri.Hunk_AllocateTempMemory( outWidth * outHeight * 4 );
  369.  
  370.     inWidthMask = inWidth - 1;
  371.     inHeightMask = inHeight - 1;
  372.  
  373.     for ( i = 0 ; i < outHeight ; i++ ) {
  374.         for ( j = 0 ; j < outWidth ; j++ ) {
  375.             outpix = (byte *) ( temp + i * outWidth + j );
  376.             for ( k = 0 ; k < 4 ; k++ ) {
  377.                 total =
  378.                     1 * ((byte *)&in[ ((i*2-1)&inHeightMask)*inWidth + ((j*2-1)&inWidthMask) ])[k] +
  379.                     2 * ((byte *)&in[ ((i*2-1)&inHeightMask)*inWidth + ((j*2)&inWidthMask) ])[k] +
  380.                     2 * ((byte *)&in[ ((i*2-1)&inHeightMask)*inWidth + ((j*2+1)&inWidthMask) ])[k] +
  381.                     1 * ((byte *)&in[ ((i*2-1)&inHeightMask)*inWidth + ((j*2+2)&inWidthMask) ])[k] +
  382.  
  383.                     2 * ((byte *)&in[ ((i*2)&inHeightMask)*inWidth + ((j*2-1)&inWidthMask) ])[k] +
  384.                     4 * ((byte *)&in[ ((i*2)&inHeightMask)*inWidth + ((j*2)&inWidthMask) ])[k] +
  385.                     4 * ((byte *)&in[ ((i*2)&inHeightMask)*inWidth + ((j*2+1)&inWidthMask) ])[k] +
  386.                     2 * ((byte *)&in[ ((i*2)&inHeightMask)*inWidth + ((j*2+2)&inWidthMask) ])[k] +
  387.  
  388.                     2 * ((byte *)&in[ ((i*2+1)&inHeightMask)*inWidth + ((j*2-1)&inWidthMask) ])[k] +
  389.                     4 * ((byte *)&in[ ((i*2+1)&inHeightMask)*inWidth + ((j*2)&inWidthMask) ])[k] +
  390.                     4 * ((byte *)&in[ ((i*2+1)&inHeightMask)*inWidth + ((j*2+1)&inWidthMask) ])[k] +
  391.                     2 * ((byte *)&in[ ((i*2+1)&inHeightMask)*inWidth + ((j*2+2)&inWidthMask) ])[k] +
  392.  
  393.                     1 * ((byte *)&in[ ((i*2+2)&inHeightMask)*inWidth + ((j*2-1)&inWidthMask) ])[k] +
  394.                     2 * ((byte *)&in[ ((i*2+2)&inHeightMask)*inWidth + ((j*2)&inWidthMask) ])[k] +
  395.                     2 * ((byte *)&in[ ((i*2+2)&inHeightMask)*inWidth + ((j*2+1)&inWidthMask) ])[k] +
  396.                     1 * ((byte *)&in[ ((i*2+2)&inHeightMask)*inWidth + ((j*2+2)&inWidthMask) ])[k];
  397.                 outpix[k] = total / 36;
  398.             }
  399.         }
  400.     }
  401.  
  402.     Com_Memcpy( in, temp, outWidth * outHeight * 4 );
  403.     ri.Hunk_FreeTempMemory( temp );
  404. }
  405.  
  406. /*
  407. ================
  408. R_MipMap
  409.  
  410. Operates in place, quartering the size of the texture
  411. ================
  412. */
  413. static void R_MipMap (byte *in, int width, int height) {
  414.     int     i, j;
  415.     byte    *out;
  416.     int     row;
  417.  
  418.     if ( !r_simpleMipMaps->integer ) {
  419.         R_MipMap2( (unsigned *)in, width, height );
  420.         return;
  421.     }
  422.  
  423.     if ( width == 1 && height == 1 ) {
  424.         return;
  425.     }
  426.  
  427.     row = width * 4;
  428.     out = in;
  429.     width >>= 1;
  430.     height >>= 1;
  431.  
  432.     if ( width == 0 || height == 0 ) {
  433.         width += height;    // get largest
  434.         for (i=0 ; i<width ; i++, out+=4, in+=8 ) {
  435.             out[0] = ( in[0] + in[4] )>>1;
  436.             out[1] = ( in[1] + in[5] )>>1;
  437.             out[2] = ( in[2] + in[6] )>>1;
  438.             out[3] = ( in[3] + in[7] )>>1;
  439.         }
  440.         return;
  441.     }
  442.  
  443.     for (i=0 ; i<height ; i++, in+=row) {
  444.         for (j=0 ; j<width ; j++, out+=4, in+=8) {
  445.             out[0] = (in[0] + in[4] + in[row+0] + in[row+4])>>2;
  446.             out[1] = (in[1] + in[5] + in[row+1] + in[row+5])>>2;
  447.             out[2] = (in[2] + in[6] + in[row+2] + in[row+6])>>2;
  448.             out[3] = (in[3] + in[7] + in[row+3] + in[row+7])>>2;
  449.         }
  450.     }
  451. }
  452.  
  453.  
  454. /*
  455. ==================
  456. R_BlendOverTexture
  457.  
  458. Apply a color blend over a set of pixels
  459. ==================
  460. */
  461. static void R_BlendOverTexture( byte *data, int pixelCount, byte blend[4] ) {
  462.     int     i;
  463.     int     inverseAlpha;
  464.     int     premult[3];
  465.  
  466.     inverseAlpha = 255 - blend[3];
  467.     premult[0] = blend[0] * blend[3];
  468.     premult[1] = blend[1] * blend[3];
  469.     premult[2] = blend[2] * blend[3];
  470.  
  471.     for ( i = 0 ; i < pixelCount ; i++, data+=4 ) {
  472.         data[0] = ( data[0] * inverseAlpha + premult[0] ) >> 9;
  473.         data[1] = ( data[1] * inverseAlpha + premult[1] ) >> 9;
  474.         data[2] = ( data[2] * inverseAlpha + premult[2] ) >> 9;
  475.     }
  476. }
  477.  
  478. byte    mipBlendColors[16][4] = {
  479.     {0,0,0,0},
  480.     {255,0,0,128},
  481.     {0,255,0,128},
  482.     {0,0,255,128},
  483.     {255,0,0,128},
  484.     {0,255,0,128},
  485.     {0,0,255,128},
  486.     {255,0,0,128},
  487.     {0,255,0,128},
  488.     {0,0,255,128},
  489.     {255,0,0,128},
  490.     {0,255,0,128},
  491.     {0,0,255,128},
  492.     {255,0,0,128},
  493.     {0,255,0,128},
  494.     {0,0,255,128},
  495. };
  496.  
  497.  
  498. /*
  499. ===============
  500. Upload32
  501.  
  502. ===============
  503. */
  504. extern qboolean charSet;
  505. static void Upload32( unsigned *data,
  506.                           int width, int height,
  507.                           qboolean mipmap,
  508.                           qboolean picmip,
  509.                             qboolean lightMap,
  510.                           int *format,
  511.                           int *pUploadWidth, int *pUploadHeight )
  512. {
  513.     int         samples;
  514.     unsigned    *scaledBuffer = NULL;
  515.     unsigned    *resampledBuffer = NULL;
  516.     int         scaled_width, scaled_height;
  517.     int         i, c;
  518.     byte        *scan;
  519.     GLenum      internalFormat = GL_RGB;
  520.     float       rMax = 0, gMax = 0, bMax = 0;
  521.  
  522.     //
  523.     // convert to exact power of 2 sizes
  524.     //
  525.     for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1)
  526.         ;
  527.     for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1)
  528.         ;
  529.     if ( r_roundImagesDown->integer && scaled_width > width )
  530.         scaled_width >>= 1;
  531.     if ( r_roundImagesDown->integer && scaled_height > height )
  532.         scaled_height >>= 1;
  533.  
  534.     if ( scaled_width != width || scaled_height != height ) {
  535.         resampledBuffer = ri.Hunk_AllocateTempMemory( scaled_width * scaled_height * 4 );
  536.         ResampleTexture (data, width, height, resampledBuffer, scaled_width, scaled_height);
  537.         data = resampledBuffer;
  538.         width = scaled_width;
  539.         height = scaled_height;
  540.     }
  541.  
  542.     //
  543.     // perform optional picmip operation
  544.     //
  545.     if ( picmip ) {
  546.         scaled_width >>= r_picmip->integer;
  547.         scaled_height >>= r_picmip->integer;
  548.     }
  549.  
  550.     //
  551.     // clamp to minimum size
  552.     //
  553.     if (scaled_width < 1) {
  554.         scaled_width = 1;
  555.     }
  556.     if (scaled_height < 1) {
  557.         scaled_height = 1;
  558.     }
  559.  
  560.     //
  561.     // clamp to the current upper OpenGL limit
  562.     // scale both axis down equally so we don't have to
  563.     // deal with a half mip resampling
  564.     //
  565.     while ( scaled_width > glConfig.maxTextureSize
  566.         || scaled_height > glConfig.maxTextureSize ) {
  567.         scaled_width >>= 1;
  568.         scaled_height >>= 1;
  569.     }
  570.  
  571.     scaledBuffer = ri.Hunk_AllocateTempMemory( sizeof( unsigned ) * scaled_width * scaled_height );
  572.  
  573.     //
  574.     // scan the texture for each channel's max values
  575.     // and verify if the alpha channel is being used or not
  576.     //
  577.     c = width*height;
  578.     scan = ((byte *)data);
  579.     samples = 3;
  580.     if (!lightMap) {
  581.         for ( i = 0; i < c; i++ )
  582.         {
  583.             if ( scan[i*4+0] > rMax )
  584.             {
  585.                 rMax = scan[i*4+0];
  586.             }
  587.             if ( scan[i*4+1] > gMax )
  588.             {
  589.                 gMax = scan[i*4+1];
  590.             }
  591.             if ( scan[i*4+2] > bMax )
  592.             {
  593.                 bMax = scan[i*4+2];
  594.             }
  595.             if ( scan[i*4 + 3] != 255 )
  596.             {
  597.                 samples = 4;
  598.                 break;
  599.             }
  600.         }
  601.         // select proper internal format
  602.         if ( samples == 3 )
  603.         {
  604.             if ( glConfig.textureCompression == TC_S3TC )
  605.             {
  606.                 internalFormat = GL_RGB4_S3TC;
  607.             }
  608.             else if ( r_texturebits->integer == 16 )
  609.             {
  610.                 internalFormat = GL_RGB5;
  611.             }
  612.             else if ( r_texturebits->integer == 32 )
  613.             {
  614.                 internalFormat = GL_RGB8;
  615.             }
  616.             else
  617.             {
  618.                 internalFormat = 3;
  619.             }
  620.         }
  621.         else if ( samples == 4 )
  622.         {
  623.             if ( r_texturebits->integer == 16 )
  624.             {
  625.                 internalFormat = GL_RGBA4;
  626.             }
  627.             else if ( r_texturebits->integer == 32 )
  628.             {
  629.                 internalFormat = GL_RGBA8;
  630.             }
  631.             else
  632.             {
  633.                 internalFormat = 4;
  634.             }
  635.         }
  636.     } else {
  637.         internalFormat = 3;
  638.     }
  639.     // copy or resample data as appropriate for first MIP level
  640.     if ( ( scaled_width == width ) &&
  641.         ( scaled_height == height ) ) {
  642.         if (!mipmap)
  643.         {
  644.             qglTexImage2D (GL_TEXTURE_2D, 0, internalFormat, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
  645.             *pUploadWidth = scaled_width;
  646.             *pUploadHeight = scaled_height;
  647.             *format = internalFormat;
  648.  
  649.             goto done;
  650.         }
  651.         Com_Memcpy (scaledBuffer, data, width*height*4);
  652.     }
  653.     else
  654.     {
  655.         // use the normal mip-mapping function to go down from here
  656.         while ( width > scaled_width || height > scaled_height ) {
  657.             R_MipMap( (byte *)data, width, height );
  658.             width >>= 1;
  659.             height >>= 1;
  660.             if ( width < 1 ) {
  661.                 width = 1;
  662.             }
  663.             if ( height < 1 ) {
  664.                 height = 1;
  665.             }
  666.         }
  667.         Com_Memcpy( scaledBuffer, data, width * height * 4 );
  668.     }
  669.  
  670.     R_LightScaleTexture (scaledBuffer, scaled_width, scaled_height, !mipmap );
  671.  
  672.     *pUploadWidth = scaled_width;
  673.     *pUploadHeight = scaled_height;
  674.     *format = internalFormat;
  675.  
  676.     qglTexImage2D (GL_TEXTURE_2D, 0, internalFormat, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaledBuffer );
  677.  
  678.     if (mipmap)
  679.     {
  680.         int     miplevel;
  681.  
  682.         miplevel = 0;
  683.         while (scaled_width > 1 || scaled_height > 1)
  684.         {
  685.             R_MipMap( (byte *)scaledBuffer, scaled_width, scaled_height );
  686.             scaled_width >>= 1;
  687.             scaled_height >>= 1;
  688.             if (scaled_width < 1)
  689.                 scaled_width = 1;
  690.             if (scaled_height < 1)
  691.                 scaled_height = 1;
  692.             miplevel++;
  693.  
  694.             if ( r_colorMipLevels->integer ) {
  695.                 R_BlendOverTexture( (byte *)scaledBuffer, scaled_width * scaled_height, mipBlendColors[miplevel] );
  696.             }
  697.  
  698.             qglTexImage2D (GL_TEXTURE_2D, miplevel, internalFormat, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaledBuffer );
  699.         }
  700.     }
  701. done:
  702.  
  703.     if (mipmap)
  704.     {
  705.         if ( textureFilterAnisotropic )
  706.             qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT,
  707.                     (GLint)Com_Clamp( 1, maxAnisotropy, r_ext_max_anisotropy->integer ) );
  708.  
  709.         qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
  710.         qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
  711.     }
  712.     else
  713.     {
  714.         if ( textureFilterAnisotropic )
  715.             qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1 );
  716.  
  717.         qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
  718.         qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
  719.     }
  720.  
  721.     GL_CheckErrors();
  722.  
  723.     if ( scaledBuffer != 0 )
  724.         ri.Hunk_FreeTempMemory( scaledBuffer );
  725.     if ( resampledBuffer != 0 )
  726.         ri.Hunk_FreeTempMemory( resampledBuffer );
  727. }
  728.  
  729.  
  730. /*
  731. ================
  732. R_CreateImage
  733.  
  734. This is the only way any image_t are created
  735. ================
  736. */
  737. image_t *R_CreateImage( const char *name, const byte *pic, int width, int height,
  738.                        qboolean mipmap, qboolean allowPicmip, int glWrapClampMode ) {
  739.     image_t     *image;
  740.     qboolean    isLightmap = qfalse;
  741.     long        hash;
  742.  
  743.     if (strlen(name) >= MAX_QPATH ) {
  744.         ri.Error (ERR_DROP, "R_CreateImage: \"%s\" is too long\n", name);
  745.     }
  746.     if ( !strncmp( name, "*lightmap", 9 ) ) {
  747.         isLightmap = qtrue;
  748.     }
  749.  
  750.     if ( tr.numImages == MAX_DRAWIMAGES ) {
  751.         ri.Error( ERR_DROP, "R_CreateImage: MAX_DRAWIMAGES hit\n");
  752.     }
  753.  
  754.     image = tr.images[tr.numImages] = ri.Hunk_Alloc( sizeof( image_t ), h_low );
  755.     image->texnum = 1024 + tr.numImages;
  756.     tr.numImages++;
  757.  
  758.     image->mipmap = mipmap;
  759.     image->allowPicmip = allowPicmip;
  760.  
  761.     strcpy (image->imgName, name);
  762.  
  763.     image->width = width;
  764.     image->height = height;
  765.     image->wrapClampMode = glWrapClampMode;
  766.  
  767.     // lightmaps are always allocated on TMU 1
  768.     if ( qglActiveTextureARB && isLightmap ) {
  769.         image->TMU = 1;
  770.     } else {
  771.         image->TMU = 0;
  772.     }
  773.  
  774.     if ( qglActiveTextureARB ) {
  775.         GL_SelectTexture( image->TMU );
  776.     }
  777.  
  778.     GL_Bind(image);
  779.  
  780.     Upload32( (unsigned *)pic, image->width, image->height,
  781.                                 image->mipmap,
  782.                                 allowPicmip,
  783.                                 isLightmap,
  784.                                 &image->internalFormat,
  785.                                 &image->uploadWidth,
  786.                                 &image->uploadHeight );
  787.  
  788.     qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapClampMode );
  789.     qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapClampMode );
  790.  
  791.     qglBindTexture( GL_TEXTURE_2D, 0 );
  792.  
  793.     if ( image->TMU == 1 ) {
  794.         GL_SelectTexture( 0 );
  795.     }
  796.  
  797.     hash = generateHashValue(name);
  798.     image->next = hashTable[hash];
  799.     hashTable[hash] = image;
  800.  
  801.     return image;
  802. }
  803.  
  804.  
  805. /*
  806. =========================================================
  807.  
  808. BMP LOADING
  809.  
  810. =========================================================
  811. */
  812. typedef struct
  813. {
  814.     char id[2];
  815.     unsigned long fileSize;
  816.     unsigned long reserved0;
  817.     unsigned long bitmapDataOffset;
  818.     unsigned long bitmapHeaderSize;
  819.     unsigned long width;
  820.     unsigned long height;
  821.     unsigned short planes;
  822.     unsigned short bitsPerPixel;
  823.     unsigned long compression;
  824.     unsigned long bitmapDataSize;
  825.     unsigned long hRes;
  826.     unsigned long vRes;
  827.     unsigned long colors;
  828.     unsigned long importantColors;
  829.     unsigned char palette[256][4];
  830. } BMPHeader_t;
  831.  
  832. static void LoadBMP( const char *name, byte **pic, int *width, int *height )
  833. {
  834.     int     columns, rows;
  835.     unsigned    numPixels;
  836.     byte    *pixbuf;
  837.     int     row, column;
  838.     byte    *buf_p;
  839.     byte    *buffer;
  840.     int     length;
  841.     BMPHeader_t bmpHeader;
  842.     byte        *bmpRGBA;
  843.  
  844.     *pic = NULL;
  845.  
  846.     //
  847.     // load the file
  848.     //
  849.     length = ri.FS_ReadFile( ( char * ) name, (void **)&buffer);
  850.     if (!buffer) {
  851.         return;
  852.     }
  853.  
  854.     buf_p = buffer;
  855.  
  856.     bmpHeader.id[0] = *buf_p++;
  857.     bmpHeader.id[1] = *buf_p++;
  858.     bmpHeader.fileSize = LittleLong( * ( long * ) buf_p );
  859.     buf_p += 4;
  860.     bmpHeader.reserved0 = LittleLong( * ( long * ) buf_p );
  861.     buf_p += 4;
  862.     bmpHeader.bitmapDataOffset = LittleLong( * ( long * ) buf_p );
  863.     buf_p += 4;
  864.     bmpHeader.bitmapHeaderSize = LittleLong( * ( long * ) buf_p );
  865.     buf_p += 4;
  866.     bmpHeader.width = LittleLong( * ( long * ) buf_p );
  867.     buf_p += 4;
  868.     bmpHeader.height = LittleLong( * ( long * ) buf_p );
  869.     buf_p += 4;
  870.     bmpHeader.planes = LittleShort( * ( short * ) buf_p );
  871.     buf_p += 2;
  872.     bmpHeader.bitsPerPixel = LittleShort( * ( short * ) buf_p );
  873.     buf_p += 2;
  874.     bmpHeader.compression = LittleLong( * ( long * ) buf_p );
  875.     buf_p += 4;
  876.     bmpHeader.bitmapDataSize = LittleLong( * ( long * ) buf_p );
  877.     buf_p += 4;
  878.     bmpHeader.hRes = LittleLong( * ( long * ) buf_p );
  879.     buf_p += 4;
  880.     bmpHeader.vRes = LittleLong( * ( long * ) buf_p );
  881.     buf_p += 4;
  882.     bmpHeader.colors = LittleLong( * ( long * ) buf_p );
  883.     buf_p += 4;
  884.     bmpHeader.importantColors = LittleLong( * ( long * ) buf_p );
  885.     buf_p += 4;
  886.  
  887.     Com_Memcpy( bmpHeader.palette, buf_p, sizeof( bmpHeader.palette ) );
  888.  
  889.     if ( bmpHeader.bitsPerPixel == 8 )
  890.         buf_p += 1024;
  891.  
  892.     if ( bmpHeader.id[0] != 'B' && bmpHeader.id[1] != 'M' )
  893.     {
  894.         ri.Error( ERR_DROP, "LoadBMP: only Windows-style BMP files supported (%s)\n", name );
  895.     }
  896.     if ( bmpHeader.fileSize != length )
  897.     {
  898.         ri.Error( ERR_DROP, "LoadBMP: header size does not match file size (%d vs. %d) (%s)\n", bmpHeader.fileSize, length, name );
  899.     }
  900.     if ( bmpHeader.compression != 0 )
  901.     {
  902.         ri.Error( ERR_DROP, "LoadBMP: only uncompressed BMP files supported (%s)\n", name );
  903.     }
  904.     if ( bmpHeader.bitsPerPixel < 8 )
  905.     {
  906.         ri.Error( ERR_DROP, "LoadBMP: monochrome and 4-bit BMP files not supported (%s)\n", name );
  907.     }
  908.  
  909.     columns = bmpHeader.width;
  910.     rows = bmpHeader.height;
  911.     if ( rows < 0 )
  912.         rows = -rows;
  913.     numPixels = columns * rows;
  914.  
  915.     if(columns <= 0 || !rows || numPixels > 0x1FFFFFFF // 4*1FFFFFFF == 0x7FFFFFFC < 0x7FFFFFFF
  916.         || ((numPixels * 4) / columns) / 4 != rows)
  917.     {
  918.       ri.Error (ERR_DROP, "LoadBMP: %s has an invalid image size\n", name);
  919.     }
  920.  
  921.     if ( width )
  922.         *width = columns;
  923.     if ( height )
  924.         *height = rows;
  925.  
  926.     bmpRGBA = ri.Malloc( numPixels * 4 );
  927.     *pic = bmpRGBA;
  928.  
  929.  
  930.     for ( row = rows-1; row >= 0; row-- )
  931.     {
  932.         pixbuf = bmpRGBA + row*columns*4;
  933.  
  934.         for ( column = 0; column < columns; column++ )
  935.         {
  936.             unsigned char red, green, blue, alpha;
  937.             int palIndex;
  938.             unsigned short shortPixel;
  939.  
  940.             switch ( bmpHeader.bitsPerPixel )
  941.             {
  942.             case 8:
  943.                 palIndex = *buf_p++;
  944.                 *pixbuf++ = bmpHeader.palette[palIndex][2];
  945.                 *pixbuf++ = bmpHeader.palette[palIndex][1];
  946.                 *pixbuf++ = bmpHeader.palette[palIndex][0];
  947.                 *pixbuf++ = 0xff;
  948.                 break;
  949.             case 16:
  950.                 shortPixel = * ( unsigned short * ) pixbuf;
  951.                 pixbuf += 2;
  952.                 *pixbuf++ = ( shortPixel & ( 31 << 10 ) ) >> 7;
  953.                 *pixbuf++ = ( shortPixel & ( 31 << 5 ) ) >> 2;
  954.                 *pixbuf++ = ( shortPixel & ( 31 ) ) << 3;
  955.                 *pixbuf++ = 0xff;
  956.                 break;
  957.  
  958.             case 24:
  959.                 blue = *buf_p++;
  960.                 green = *buf_p++;
  961.                 red = *buf_p++;
  962.                 *pixbuf++ = red;
  963.                 *pixbuf++ = green;
  964.                 *pixbuf++ = blue;
  965.                 *pixbuf++ = 255;
  966.                 break;
  967.             case 32:
  968.                 blue = *buf_p++;
  969.                 green = *buf_p++;
  970.                 red = *buf_p++;
  971.                 alpha = *buf_p++;
  972.                 *pixbuf++ = red;
  973.                 *pixbuf++ = green;
  974.                 *pixbuf++ = blue;
  975.                 *pixbuf++ = alpha;
  976.                 break;
  977.             default:
  978.                 ri.Error( ERR_DROP, "LoadBMP: illegal pixel_size '%d' in file '%s'\n", bmpHeader.bitsPerPixel, name );
  979.                 break;
  980.             }
  981.         }
  982.     }
  983.  
  984.     ri.FS_FreeFile( buffer );
  985.  
  986. }
  987.  
  988.  
  989. /*
  990. =================================================================
  991.  
  992. PCX LOADING
  993.  
  994. =================================================================
  995. */
  996.  
  997.  
  998. /*
  999. ==============
  1000. LoadPCX
  1001. ==============
  1002. */
  1003. static void LoadPCX ( const char *filename, byte **pic, byte **palette, int *width, int *height)
  1004. {
  1005.     byte    *raw;
  1006.     pcx_t   *pcx;
  1007.     int     x, y;
  1008.     int     len;
  1009.     int     dataByte, runLength;
  1010.     byte    *out, *pix;
  1011.     unsigned        xmax, ymax;
  1012.  
  1013.     *pic = NULL;
  1014.     *palette = NULL;
  1015.  
  1016.     //
  1017.     // load the file
  1018.     //
  1019.     len = ri.FS_ReadFile( ( char * ) filename, (void **)&raw);
  1020.     if (!raw) {
  1021.         return;
  1022.     }
  1023.  
  1024.     //
  1025.     // parse the PCX file
  1026.     //
  1027.     pcx = (pcx_t *)raw;
  1028.     raw = &pcx->data;
  1029.  
  1030.     xmax = LittleShort(pcx->xmax);
  1031.     ymax = LittleShort(pcx->ymax);
  1032.  
  1033.     if (pcx->manufacturer != 0x0a
  1034.         || pcx->version != 5
  1035.         || pcx->encoding != 1
  1036.         || pcx->bits_per_pixel != 8
  1037.         || xmax >= 1024
  1038.         || ymax >= 1024)
  1039.     {
  1040.         ri.Printf (PRINT_ALL, "Bad pcx file %s (%i x %i) (%i x %i)\n", filename, xmax+1, ymax+1, pcx->xmax, pcx->ymax);
  1041.         return;
  1042.     }
  1043.  
  1044.     out = ri.Malloc ( (ymax+1) * (xmax+1) );
  1045.  
  1046.     *pic = out;
  1047.  
  1048.     pix = out;
  1049.  
  1050.     if (palette)
  1051.     {
  1052.         *palette = ri.Malloc(768);
  1053.         Com_Memcpy (*palette, (byte *)pcx + len - 768, 768);
  1054.     }
  1055.  
  1056.     if (width)
  1057.         *width = xmax+1;
  1058.     if (height)
  1059.         *height = ymax+1;
  1060. // FIXME: use bytes_per_line here?
  1061.  
  1062.     for (y=0 ; y<=ymax ; y++, pix += xmax+1)
  1063.     {
  1064.         for (x=0 ; x<=xmax ; )
  1065.         {
  1066.             dataByte = *raw++;
  1067.  
  1068.             if((dataByte & 0xC0) == 0xC0)
  1069.             {
  1070.                 runLength = dataByte & 0x3F;
  1071.                 dataByte = *raw++;
  1072.             }
  1073.             else
  1074.                 runLength = 1;
  1075.  
  1076.             while(runLength-- > 0)
  1077.                 pix[x++] = dataByte;
  1078.         }
  1079.  
  1080.     }
  1081.  
  1082.     if ( raw - (byte *)pcx > len)
  1083.     {
  1084.         ri.Printf (PRINT_DEVELOPER, "PCX file %s was malformed", filename);
  1085.         ri.Free (*pic);
  1086.         *pic = NULL;
  1087.     }
  1088.  
  1089.     ri.FS_FreeFile (pcx);
  1090. }
  1091.  
  1092.  
  1093. /*
  1094. ==============
  1095. LoadPCX32
  1096. ==============
  1097. */
  1098. static void LoadPCX32 ( const char *filename, byte **pic, int *width, int *height) {
  1099.     byte    *palette;
  1100.     byte    *pic8;
  1101.     int     i, c, p;
  1102.     byte    *pic32;
  1103.  
  1104.     LoadPCX (filename, &pic8, &palette, width, height);
  1105.     if (!pic8) {
  1106.         *pic = NULL;
  1107.         return;
  1108.     }
  1109.  
  1110.     // LoadPCX32 ensures width, height < 1024
  1111.     c = (*width) * (*height);
  1112.     pic32 = *pic = ri.Malloc(4 * c );
  1113.     for (i = 0 ; i < c ; i++) {
  1114.         p = pic8[i];
  1115.         pic32[0] = palette[p*3];
  1116.         pic32[1] = palette[p*3 + 1];
  1117.         pic32[2] = palette[p*3 + 2];
  1118.         pic32[3] = 255;
  1119.         pic32 += 4;
  1120.     }
  1121.  
  1122.     ri.Free (pic8);
  1123.     ri.Free (palette);
  1124. }
  1125.  
  1126. /*
  1127. =========================================================
  1128.  
  1129. TARGA LOADING
  1130.  
  1131. =========================================================
  1132. */
  1133.  
  1134. /*
  1135. =============
  1136. LoadTGA
  1137. =============
  1138. */
  1139. static void LoadTGA ( const char *name, byte **pic, int *width, int *height)
  1140. {
  1141.     unsigned    columns, rows, numPixels;
  1142.     byte    *pixbuf;
  1143.     int     row, column;
  1144.     byte    *buf_p;
  1145.     byte    *buffer;
  1146.     TargaHeader targa_header;
  1147.     byte        *targa_rgba;
  1148.  
  1149.     *pic = NULL;
  1150.  
  1151.     //
  1152.     // load the file
  1153.     //
  1154.     ri.FS_ReadFile ( ( char * ) name, (void **)&buffer);
  1155.     if (!buffer) {
  1156.         return;
  1157.     }
  1158.  
  1159.     buf_p = buffer;
  1160.  
  1161.     targa_header.id_length = buf_p[0];
  1162.     targa_header.colormap_type = buf_p[1];
  1163.     targa_header.image_type = buf_p[2];
  1164.    
  1165.     memcpy(&targa_header.colormap_index, &buf_p[3], 2);
  1166.     memcpy(&targa_header.colormap_length, &buf_p[5], 2);
  1167.     targa_header.colormap_size = buf_p[7];
  1168.     memcpy(&targa_header.x_origin, &buf_p[8], 2);
  1169.     memcpy(&targa_header.y_origin, &buf_p[10], 2);
  1170.     memcpy(&targa_header.width, &buf_p[12], 2);
  1171.     memcpy(&targa_header.height, &buf_p[14], 2);
  1172.     targa_header.pixel_size = buf_p[16];
  1173.     targa_header.attributes = buf_p[17];
  1174.  
  1175.     targa_header.colormap_index = LittleShort(targa_header.colormap_index);
  1176.     targa_header.colormap_length = LittleShort(targa_header.colormap_length);
  1177.     targa_header.x_origin = LittleShort(targa_header.x_origin);
  1178.     targa_header.y_origin = LittleShort(targa_header.y_origin);
  1179.     targa_header.width = LittleShort(targa_header.width);
  1180.     targa_header.height = LittleShort(targa_header.height);
  1181.  
  1182.     buf_p += 18;
  1183.  
  1184.     if (targa_header.image_type!=2
  1185.         && targa_header.image_type!=10
  1186.         && targa_header.image_type != 3 )
  1187.     {
  1188.         ri.Error (ERR_DROP, "LoadTGA: Only type 2 (RGB), 3 (gray), and 10 (RGB) TGA images supported\n");
  1189.     }
  1190.  
  1191.     if ( targa_header.colormap_type != 0 )
  1192.     {
  1193.         ri.Error( ERR_DROP, "LoadTGA: colormaps not supported\n" );
  1194.     }
  1195.  
  1196.     if ( ( targa_header.pixel_size != 32 && targa_header.pixel_size != 24 ) && targa_header.image_type != 3 )
  1197.     {
  1198.         ri.Error (ERR_DROP, "LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
  1199.     }
  1200.  
  1201.     columns = targa_header.width;
  1202.     rows = targa_header.height;
  1203.     numPixels = columns * rows * 4;
  1204.  
  1205.     if (width)
  1206.         *width = columns;
  1207.     if (height)
  1208.         *height = rows;
  1209.  
  1210.     if(!columns || !rows || numPixels > 0x7FFFFFFF || numPixels / columns / 4 != rows)
  1211.     {
  1212.         ri.Error (ERR_DROP, "LoadTGA: %s has an invalid image size\n", name);
  1213.     }
  1214.  
  1215.     targa_rgba = ri.Malloc (numPixels);
  1216.     *pic = targa_rgba;
  1217.  
  1218.     if (targa_header.id_length != 0)
  1219.         buf_p += targa_header.id_length;  // skip TARGA image comment
  1220.    
  1221.     if ( targa_header.image_type==2 || targa_header.image_type == 3 )
  1222.     {
  1223.         // Uncompressed RGB or gray scale image
  1224.         for(row=rows-1; row>=0; row--)
  1225.         {
  1226.             pixbuf = targa_rgba + row*columns*4;
  1227.             for(column=0; column<columns; column++)
  1228.             {
  1229.                 unsigned char red,green,blue,alphabyte;
  1230.                 switch (targa_header.pixel_size)
  1231.                 {
  1232.                    
  1233.                 case 8:
  1234.                     blue = *buf_p++;
  1235.                     green = blue;
  1236.                     red = blue;
  1237.                     *pixbuf++ = red;
  1238.                     *pixbuf++ = green;
  1239.                     *pixbuf++ = blue;
  1240.                     *pixbuf++ = 255;
  1241.                     break;
  1242.  
  1243.                 case 24:
  1244.                     blue = *buf_p++;
  1245.                     green = *buf_p++;
  1246.                     red = *buf_p++;
  1247.                     *pixbuf++ = red;
  1248.                     *pixbuf++ = green;
  1249.                     *pixbuf++ = blue;
  1250.                     *pixbuf++ = 255;
  1251.                     break;
  1252.                 case 32:
  1253.                     blue = *buf_p++;
  1254.                     green = *buf_p++;
  1255.                     red = *buf_p++;
  1256.                     alphabyte = *buf_p++;
  1257.                     *pixbuf++ = red;
  1258.                     *pixbuf++ = green;
  1259.                     *pixbuf++ = blue;
  1260.                     *pixbuf++ = alphabyte;
  1261.                     break;
  1262.                 default:
  1263.                     ri.Error( ERR_DROP, "LoadTGA: illegal pixel_size '%d' in file '%s'\n", targa_header.pixel_size, name );
  1264.                     break;
  1265.                 }
  1266.             }
  1267.         }
  1268.     }
  1269.     else if (targa_header.image_type==10) {   // Runlength encoded RGB images
  1270.         unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j;
  1271.  
  1272.         red = 0;
  1273.         green = 0;
  1274.         blue = 0;
  1275.         alphabyte = 0xff;
  1276.  
  1277.         for(row=rows-1; row>=0; row--) {
  1278.             pixbuf = targa_rgba + row*columns*4;
  1279.             for(column=0; column<columns; ) {
  1280.                 packetHeader= *buf_p++;
  1281.                 packetSize = 1 + (packetHeader & 0x7f);
  1282.                 if (packetHeader & 0x80) {        // run-length packet
  1283.                     switch (targa_header.pixel_size) {
  1284.                         case 24:
  1285.                                 blue = *buf_p++;
  1286.                                 green = *buf_p++;
  1287.                                 red = *buf_p++;
  1288.                                 alphabyte = 255;
  1289.                                 break;
  1290.                         case 32:
  1291.                                 blue = *buf_p++;
  1292.                                 green = *buf_p++;
  1293.                                 red = *buf_p++;
  1294.                                 alphabyte = *buf_p++;
  1295.                                 break;
  1296.                         default:
  1297.                             ri.Error( ERR_DROP, "LoadTGA: illegal pixel_size '%d' in file '%s'\n", targa_header.pixel_size, name );
  1298.                             break;
  1299.                     }
  1300.    
  1301.                     for(j=0;j<packetSize;j++) {
  1302.                         *pixbuf++=red;
  1303.                         *pixbuf++=green;
  1304.                         *pixbuf++=blue;
  1305.                         *pixbuf++=alphabyte;
  1306.                         column++;
  1307.                         if (column==columns) { // run spans across rows
  1308.                             column=0;
  1309.                             if (row>0)
  1310.                                 row--;
  1311.                             else
  1312.                                 goto breakOut;
  1313.                             pixbuf = targa_rgba + row*columns*4;
  1314.                         }
  1315.                     }
  1316.                 }
  1317.                 else {                            // non run-length packet
  1318.                     for(j=0;j<packetSize;j++) {
  1319.                         switch (targa_header.pixel_size) {
  1320.                             case 24:
  1321.                                     blue = *buf_p++;
  1322.                                     green = *buf_p++;
  1323.                                     red = *buf_p++;
  1324.                                     *pixbuf++ = red;
  1325.                                     *pixbuf++ = green;
  1326.                                     *pixbuf++ = blue;
  1327.                                     *pixbuf++ = 255;
  1328.                                     break;
  1329.                             case 32:
  1330.                                     blue = *buf_p++;
  1331.                                     green = *buf_p++;
  1332.                                     red = *buf_p++;
  1333.                                     alphabyte = *buf_p++;
  1334.                                     *pixbuf++ = red;
  1335.                                     *pixbuf++ = green;
  1336.                                     *pixbuf++ = blue;
  1337.                                     *pixbuf++ = alphabyte;
  1338.                                     break;
  1339.                             default:
  1340.                                 ri.Error( ERR_DROP, "LoadTGA: illegal pixel_size '%d' in file '%s'\n", targa_header.pixel_size, name );
  1341.                                 break;
  1342.                         }
  1343.                         column++;
  1344.                         if (column==columns) { // pixel packet run spans across rows
  1345.                             column=0;
  1346.                             if (row>0)
  1347.                                 row--;
  1348.                             else
  1349.                                 goto breakOut;
  1350.                             pixbuf = targa_rgba + row*columns*4;
  1351.                         }                      
  1352.                     }
  1353.                 }
  1354.             }
  1355.             breakOut:;
  1356.         }
  1357.     }
  1358.  
  1359. #if 0
  1360.   // TTimo: this is the chunk of code to ensure a behavior that meets TGA specs
  1361.   // bit 5 set => top-down
  1362.   if (targa_header.attributes & 0x20) {
  1363.     unsigned char *flip = (unsigned char*)malloc (columns*4);
  1364.     unsigned char *src, *dst;
  1365.  
  1366.     for (row = 0; row < rows/2; row++) {
  1367.       src = targa_rgba + row * 4 * columns;
  1368.       dst = targa_rgba + (rows - row - 1) * 4 * columns;
  1369.  
  1370.       memcpy (flip, src, columns*4);
  1371.       memcpy (src, dst, columns*4);
  1372.       memcpy (dst, flip, columns*4);
  1373.     }
  1374.     free (flip);
  1375.   }
  1376. #endif
  1377.   // instead we just print a warning
  1378.   if (targa_header.attributes & 0x20) {
  1379.     ri.Printf( PRINT_WARNING, "WARNING: '%s' TGA file header declares top-down image, ignoring\n", name);
  1380.   }
  1381.  
  1382.   ri.FS_FreeFile (buffer);
  1383. }
  1384.  
  1385. static void LoadJPG( const char *filename, unsigned char **pic, int *width, int *height ) {
  1386.   /* This struct contains the JPEG decompression parameters and pointers to
  1387.    * working space (which is allocated as needed by the JPEG library).
  1388.    */
  1389.   struct jpeg_decompress_struct cinfo = {NULL};
  1390.   /* We use our private extension JPEG error handler.
  1391.    * Note that this struct must live as long as the main JPEG parameter
  1392.    * struct, to avoid dangling-pointer problems.
  1393.    */
  1394.   /* This struct represents a JPEG error handler.  It is declared separately
  1395.    * because applications often want to supply a specialized error handler
  1396.    * (see the second half of this file for an example).  But here we just
  1397.    * take the easy way out and use the standard error handler, which will
  1398.    * print a message on stderr and call exit() if compression fails.
  1399.    * Note that this struct must live as long as the main JPEG parameter
  1400.    * struct, to avoid dangling-pointer problems.
  1401.    */
  1402.   struct jpeg_error_mgr jerr;
  1403.   /* More stuff */
  1404.   JSAMPARRAY buffer;        /* Output row buffer */
  1405.   unsigned row_stride;      /* physical row width in output buffer */
  1406.   unsigned pixelcount, memcount;
  1407.   unsigned char *out;
  1408.   byte  *fbuffer;
  1409.   byte  *buf;
  1410.  
  1411.   /* In this example we want to open the input file before doing anything else,
  1412.    * so that the setjmp() error recovery below can assume the file is open.
  1413.    * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
  1414.    * requires it in order to read binary files.
  1415.    */
  1416.  
  1417.   ri.FS_ReadFile ( ( char * ) filename, (void **)&fbuffer);
  1418.   if (!fbuffer) {
  1419.     return;
  1420.   }
  1421.  
  1422.   /* Step 1: allocate and initialize JPEG decompression object */
  1423.  
  1424.   /* We have to set up the error handler first, in case the initialization
  1425.    * step fails.  (Unlikely, but it could happen if you are out of memory.)
  1426.    * This routine fills in the contents of struct jerr, and returns jerr's
  1427.    * address which we place into the link field in cinfo.
  1428.    */
  1429.   cinfo.err = jpeg_std_error(&jerr);
  1430.  
  1431.   /* Now we can initialize the JPEG decompression object. */
  1432.   jpeg_create_decompress(&cinfo);
  1433.  
  1434.   /* Step 2: specify data source (eg, a file) */
  1435.  
  1436.   jpeg_stdio_src(&cinfo, fbuffer);
  1437.  
  1438.   /* Step 3: read file parameters with jpeg_read_header() */
  1439.  
  1440.   (void) jpeg_read_header(&cinfo, TRUE);
  1441.   /* We can ignore the return value from jpeg_read_header since
  1442.    *   (a) suspension is not possible with the stdio data source, and
  1443.    *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
  1444.    * See libjpeg.doc for more info.
  1445.    */
  1446.  
  1447.   /* Step 4: set parameters for decompression */
  1448.  
  1449.   /* In this example, we don't need to change any of the defaults set by
  1450.    * jpeg_read_header(), so we do nothing here.
  1451.    */
  1452.  
  1453.   /* Step 5: Start decompressor */
  1454.  
  1455.   (void) jpeg_start_decompress(&cinfo);
  1456.   /* We can ignore the return value since suspension is not possible
  1457.    * with the stdio data source.
  1458.    */
  1459.  
  1460.   /* We may need to do some setup of our own at this point before reading
  1461.    * the data.  After jpeg_start_decompress() we have the correct scaled
  1462.    * output image dimensions available, as well as the output colormap
  1463.    * if we asked for color quantization.
  1464.    * In this example, we need to make an output work buffer of the right size.
  1465.    */
  1466.   /* JSAMPLEs per row in output buffer */
  1467.  
  1468.   pixelcount = cinfo.output_width * cinfo.output_height;
  1469.  
  1470.   if(!cinfo.output_width || !cinfo.output_height
  1471.       || ((pixelcount * 4) / cinfo.output_width) / 4 != cinfo.output_height
  1472.       || pixelcount > 0x1FFFFFFF || cinfo.output_components > 4) // 4*1FFFFFFF == 0x7FFFFFFC < 0x7FFFFFFF
  1473.   {
  1474.     ri.Error (ERR_DROP, "LoadJPG: %s has an invalid image size: %dx%d*4=%d, components: %d\n", filename,
  1475.             cinfo.output_width, cinfo.output_height, pixelcount * 4, cinfo.output_components);
  1476.   }
  1477.  
  1478.   memcount = pixelcount * 4;
  1479.   row_stride = cinfo.output_width * cinfo.output_components;
  1480.  
  1481.   out = ri.Malloc(memcount);
  1482.  
  1483.   *width = cinfo.output_width;
  1484.   *height = cinfo.output_height;
  1485.  
  1486.   /* Step 6: while (scan lines remain to be read) */
  1487.   /*           jpeg_read_scanlines(...); */
  1488.  
  1489.   /* Here we use the library's state variable cinfo.output_scanline as the
  1490.    * loop counter, so that we don't have to keep track ourselves.
  1491.    */
  1492.   while (cinfo.output_scanline < cinfo.output_height) {
  1493.     /* jpeg_read_scanlines expects an array of pointers to scanlines.
  1494.      * Here the array is only one element long, but you could ask for
  1495.      * more than one scanline at a time if that's more convenient.
  1496.      */
  1497.     buf = ((out+(row_stride*cinfo.output_scanline)));
  1498.     buffer = &buf;
  1499.     (void) jpeg_read_scanlines(&cinfo, buffer, 1);
  1500.   }
  1501.  
  1502.   buf = out;
  1503.  
  1504.   // If we are processing an 8-bit JPEG (greyscale), we'll have to convert
  1505.   // the greyscale values to RGBA.
  1506.   if(cinfo.output_components == 1)
  1507.   {
  1508.     int sindex = pixelcount, dindex = memcount;
  1509.     unsigned char greyshade;
  1510.  
  1511.     // Only pixelcount number of bytes have been written.
  1512.     // Expand the color values over the rest of the buffer, starting
  1513.     // from the end.
  1514.     do
  1515.     {
  1516.         greyshade = buf[--sindex];
  1517.  
  1518.         buf[--dindex] = 255;
  1519.         buf[--dindex] = greyshade;
  1520.         buf[--dindex] = greyshade;
  1521.         buf[--dindex] = greyshade;
  1522.     } while(sindex);
  1523.   }
  1524.   else
  1525.   {
  1526.     // clear all the alphas to 255
  1527.     int i;
  1528.  
  1529.     for ( i = 3 ; i < memcount ; i+=4 )
  1530.     {
  1531.         buf[i] = 255;
  1532.     }
  1533.   }
  1534.  
  1535.   *pic = out;
  1536.  
  1537.   /* Step 7: Finish decompression */
  1538.  
  1539.   (void) jpeg_finish_decompress(&cinfo);
  1540.   /* We can ignore the return value since suspension is not possible
  1541.    * with the stdio data source.
  1542.    */
  1543.  
  1544.   /* Step 8: Release JPEG decompression object */
  1545.  
  1546.   /* This is an important step since it will release a good deal of memory. */
  1547.   jpeg_destroy_decompress(&cinfo);
  1548.  
  1549.   /* After finish_decompress, we can close the input file.
  1550.    * Here we postpone it until after no more JPEG errors are possible,
  1551.    * so as to simplify the setjmp error logic above.  (Actually, I don't
  1552.    * think that jpeg_destroy can do an error exit, but why assume anything...)
  1553.    */
  1554.   ri.FS_FreeFile (fbuffer);
  1555.  
  1556.   /* At this point you may want to check to see whether any corrupt-data
  1557.    * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
  1558.    */
  1559.  
  1560.   /* And we're done! */
  1561. }
  1562.  
  1563.  
  1564. /* Expanded data destination object for stdio output */
  1565.  
  1566. typedef struct {
  1567.   struct jpeg_destination_mgr pub; /* public fields */
  1568.  
  1569.   byte* outfile;        /* target stream */
  1570.   int   size;
  1571. } my_destination_mgr;
  1572.  
  1573. typedef my_destination_mgr * my_dest_ptr;
  1574.  
  1575.  
  1576. /*
  1577.  * Initialize destination --- called by jpeg_start_compress
  1578.  * before any data is actually written.
  1579.  */
  1580.  
  1581. void init_destination (j_compress_ptr cinfo)
  1582. {
  1583.   my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
  1584.  
  1585.   dest->pub.next_output_byte = dest->outfile;
  1586.   dest->pub.free_in_buffer = dest->size;
  1587. }
  1588.  
  1589.  
  1590. /*
  1591.  * Empty the output buffer --- called whenever buffer fills up.
  1592.  *
  1593.  * In typical applications, this should write the entire output buffer
  1594.  * (ignoring the current state of next_output_byte & free_in_buffer),
  1595.  * reset the pointer & count to the start of the buffer, and return TRUE
  1596.  * indicating that the buffer has been dumped.
  1597.  *
  1598.  * In applications that need to be able to suspend compression due to output
  1599.  * overrun, a FALSE return indicates that the buffer cannot be emptied now.
  1600.  * In this situation, the compressor will return to its caller (possibly with
  1601.  * an indication that it has not accepted all the supplied scanlines).  The
  1602.  * application should resume compression after it has made more room in the
  1603.  * output buffer.  Note that there are substantial restrictions on the use of
  1604.  * suspension --- see the documentation.
  1605.  *
  1606.  * When suspending, the compressor will back up to a convenient restart point
  1607.  * (typically the start of the current MCU). next_output_byte & free_in_buffer
  1608.  * indicate where the restart point will be if the current call returns FALSE.
  1609.  * Data beyond this point will be regenerated after resumption, so do not
  1610.  * write it out when emptying the buffer externally.
  1611.  */
  1612.  
  1613. boolean empty_output_buffer (j_compress_ptr cinfo)
  1614. {
  1615.   return TRUE;
  1616. }
  1617.  
  1618.  
  1619. /*
  1620.  * Compression initialization.
  1621.  * Before calling this, all parameters and a data destination must be set up.
  1622.  *
  1623.  * We require a write_all_tables parameter as a failsafe check when writing
  1624.  * multiple datastreams from the same compression object.  Since prior runs
  1625.  * will have left all the tables marked sent_table=TRUE, a subsequent run
  1626.  * would emit an abbreviated stream (no tables) by default.  This may be what
  1627.  * is wanted, but for safety's sake it should not be the default behavior:
  1628.  * programmers should have to make a deliberate choice to emit abbreviated
  1629.  * images.  Therefore the documentation and examples should encourage people
  1630.  * to pass write_all_tables=TRUE; then it will take active thought to do the
  1631.  * wrong thing.
  1632.  */
  1633.  
  1634. GLOBAL void
  1635. jpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables)
  1636. {
  1637.   if (cinfo->global_state != CSTATE_START)
  1638.     ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
  1639.  
  1640.   if (write_all_tables)
  1641.     jpeg_suppress_tables(cinfo, FALSE); /* mark all tables to be written */
  1642.  
  1643.   /* (Re)initialize error mgr and destination modules */
  1644.   (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
  1645.   (*cinfo->dest->init_destination) (cinfo);
  1646.   /* Perform master selection of active modules */
  1647.   jinit_compress_master(cinfo);
  1648.   /* Set up for the first pass */
  1649.   (*cinfo->master->prepare_for_pass) (cinfo);
  1650.   /* Ready for application to drive first pass through jpeg_write_scanlines
  1651.    * or jpeg_write_raw_data.
  1652.    */
  1653.   cinfo->next_scanline = 0;
  1654.   cinfo->global_state = (cinfo->raw_data_in ? CSTATE_RAW_OK : CSTATE_SCANNING);
  1655. }
  1656.  
  1657.  
  1658. /*
  1659.  * Write some scanlines of data to the JPEG compressor.
  1660.  *
  1661.  * The return value will be the number of lines actually written.
  1662.  * This should be less than the supplied num_lines only in case that
  1663.  * the data destination module has requested suspension of the compressor,
  1664.  * or if more than image_height scanlines are passed in.
  1665.  *
  1666.  * Note: we warn about excess calls to jpeg_write_scanlines() since
  1667.  * this likely signals an application programmer error.  However,
  1668.  * excess scanlines passed in the last valid call are *silently* ignored,
  1669.  * so that the application need not adjust num_lines for end-of-image
  1670.  * when using a multiple-scanline buffer.
  1671.  */
  1672.  
  1673. GLOBAL JDIMENSION
  1674. jpeg_write_scanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines,
  1675.               JDIMENSION num_lines)
  1676. {
  1677.   JDIMENSION row_ctr, rows_left;
  1678.  
  1679.   if (cinfo->global_state != CSTATE_SCANNING)
  1680.     ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
  1681.   if (cinfo->next_scanline >= cinfo->image_height)
  1682.     WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
  1683.  
  1684.   /* Call progress monitor hook if present */
  1685.   if (cinfo->progress != NULL) {
  1686.     cinfo->progress->pass_counter = (long) cinfo->next_scanline;
  1687.     cinfo->progress->pass_limit = (long) cinfo->image_height;
  1688.     (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
  1689.   }
  1690.  
  1691.   /* Give master control module another chance if this is first call to
  1692.    * jpeg_write_scanlines.  This lets output of the frame/scan headers be
  1693.    * delayed so that application can write COM, etc, markers between
  1694.    * jpeg_start_compress and jpeg_write_scanlines.
  1695.    */
  1696.   if (cinfo->master->call_pass_startup)
  1697.     (*cinfo->master->pass_startup) (cinfo);
  1698.  
  1699.   /* Ignore any extra scanlines at bottom of image. */
  1700.   rows_left = cinfo->image_height - cinfo->next_scanline;
  1701.   if (num_lines > rows_left)
  1702.     num_lines = rows_left;
  1703.  
  1704.   row_ctr = 0;
  1705.   (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, num_lines);
  1706.   cinfo->next_scanline += row_ctr;
  1707.   return row_ctr;
  1708. }
  1709.  
  1710. /*
  1711.  * Terminate destination --- called by jpeg_finish_compress
  1712.  * after all data has been written.  Usually needs to flush buffer.
  1713.  *
  1714.  * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
  1715.  * application must deal with any cleanup that should happen even
  1716.  * for error exit.
  1717.  */
  1718.  
  1719. static int hackSize;
  1720.  
  1721. void term_destination (j_compress_ptr cinfo)
  1722. {
  1723.   my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
  1724.   size_t datacount = dest->size - dest->pub.free_in_buffer;
  1725.   hackSize = datacount;
  1726. }
  1727.  
  1728.  
  1729. /*
  1730.  * Prepare for output to a stdio stream.
  1731.  * The caller must have already opened the stream, and is responsible
  1732.  * for closing it after finishing compression.
  1733.  */
  1734.  
  1735. void jpegDest (j_compress_ptr cinfo, byte* outfile, int size)
  1736. {
  1737.   my_dest_ptr dest;
  1738.  
  1739.   /* The destination object is made permanent so that multiple JPEG images
  1740.    * can be written to the same file without re-executing jpeg_stdio_dest.
  1741.    * This makes it dangerous to use this manager and a different destination
  1742.    * manager serially with the same JPEG object, because their private object
  1743.    * sizes may be different.  Caveat programmer.
  1744.    */
  1745.   if (cinfo->dest == NULL) {    /* first time for this JPEG object? */
  1746.     cinfo->dest = (struct jpeg_destination_mgr *)
  1747.       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
  1748.                   sizeof(my_destination_mgr));
  1749.   }
  1750.  
  1751.   dest = (my_dest_ptr) cinfo->dest;
  1752.   dest->pub.init_destination = init_destination;
  1753.   dest->pub.empty_output_buffer = empty_output_buffer;
  1754.   dest->pub.term_destination = term_destination;
  1755.   dest->outfile = outfile;
  1756.   dest->size = size;
  1757. }
  1758.  
  1759. void SaveJPG(char * filename, int quality, int image_width, int image_height, unsigned char *image_buffer) {
  1760.   /* This struct contains the JPEG compression parameters and pointers to
  1761.    * working space (which is allocated as needed by the JPEG library).
  1762.    * It is possible to have several such structures, representing multiple
  1763.    * compression/decompression processes, in existence at once.  We refer
  1764.    * to any one struct (and its associated working data) as a "JPEG object".
  1765.    */
  1766.   struct jpeg_compress_struct cinfo;
  1767.   /* This struct represents a JPEG error handler.  It is declared separately
  1768.    * because applications often want to supply a specialized error handler
  1769.    * (see the second half of this file for an example).  But here we just
  1770.    * take the easy way out and use the standard error handler, which will
  1771.    * print a message on stderr and call exit() if compression fails.
  1772.    * Note that this struct must live as long as the main JPEG parameter
  1773.    * struct, to avoid dangling-pointer problems.
  1774.    */
  1775.   struct jpeg_error_mgr jerr;
  1776.   /* More stuff */
  1777.   JSAMPROW row_pointer[1];  /* pointer to JSAMPLE row[s] */
  1778.   int row_stride;       /* physical row width in image buffer */
  1779.   unsigned char *out;
  1780.  
  1781.   /* Step 1: allocate and initialize JPEG compression object */
  1782.  
  1783.   /* We have to set up the error handler first, in case the initialization
  1784.    * step fails.  (Unlikely, but it could happen if you are out of memory.)
  1785.    * This routine fills in the contents of struct jerr, and returns jerr's
  1786.    * address which we place into the link field in cinfo.
  1787.    */
  1788.   cinfo.err = jpeg_std_error(&jerr);
  1789.   /* Now we can initialize the JPEG compression object. */
  1790.   jpeg_create_compress(&cinfo);
  1791.  
  1792.   /* Step 2: specify data destination (eg, a file) */
  1793.   /* Note: steps 2 and 3 can be done in either order. */
  1794.  
  1795.   /* Here we use the library-supplied code to send compressed data to a
  1796.    * stdio stream.  You can also write your own code to do something else.
  1797.    * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
  1798.    * requires it in order to write binary files.
  1799.    */
  1800.   out = ri.Hunk_AllocateTempMemory(image_width*image_height*4);
  1801.   jpegDest(&cinfo, out, image_width*image_height*4);
  1802.  
  1803.   /* Step 3: set parameters for compression */
  1804.  
  1805.   /* First we supply a description of the input image.
  1806.    * Four fields of the cinfo struct must be filled in:
  1807.    */
  1808.   cinfo.image_width = image_width;  /* image width and height, in pixels */
  1809.   cinfo.image_height = image_height;
  1810.   cinfo.input_components = 4;       /* # of color components per pixel */
  1811.   cinfo.in_color_space = JCS_RGB;   /* colorspace of input image */
  1812.   /* Now use the library's routine to set default compression parameters.
  1813.    * (You must set at least cinfo.in_color_space before calling this,
  1814.    * since the defaults depend on the source color space.)
  1815.    */
  1816.   jpeg_set_defaults(&cinfo);
  1817.   /* Now you can set any non-default parameters you wish to.
  1818.    * Here we just illustrate the use of quality (quantization table) scaling:
  1819.    */
  1820.   jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
  1821.   /* If quality is set high, disable chroma subsampling */
  1822.   if (quality >= 85) {
  1823.     cinfo.comp_info[0].h_samp_factor = 1;
  1824.     cinfo.comp_info[0].v_samp_factor = 1;
  1825.   }
  1826.  
  1827.   /* Step 4: Start compressor */
  1828.  
  1829.   /* TRUE ensures that we will write a complete interchange-JPEG file.
  1830.    * Pass TRUE unless you are very sure of what you're doing.
  1831.    */
  1832.   jpeg_start_compress(&cinfo, TRUE);
  1833.  
  1834.   /* Step 5: while (scan lines remain to be written) */
  1835.   /*           jpeg_write_scanlines(...); */
  1836.  
  1837.   /* Here we use the library's state variable cinfo.next_scanline as the
  1838.    * loop counter, so that we don't have to keep track ourselves.
  1839.    * To keep things simple, we pass one scanline per call; you can pass
  1840.    * more if you wish, though.
  1841.    */
  1842.   row_stride = image_width * 4; /* JSAMPLEs per row in image_buffer */
  1843.  
  1844.   while (cinfo.next_scanline < cinfo.image_height) {
  1845.     /* jpeg_write_scanlines expects an array of pointers to scanlines.
  1846.      * Here the array is only one element long, but you could pass
  1847.      * more than one scanline at a time if that's more convenient.
  1848.      */
  1849.     row_pointer[0] = & image_buffer[((cinfo.image_height-1)*row_stride)-cinfo.next_scanline * row_stride];
  1850.     (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
  1851.   }
  1852.  
  1853.   /* Step 6: Finish compression */
  1854.  
  1855.   jpeg_finish_compress(&cinfo);
  1856.   /* After finish_compress, we can close the output file. */
  1857.   ri.FS_WriteFile( filename, out, hackSize );
  1858.  
  1859.   ri.Hunk_FreeTempMemory(out);
  1860.  
  1861.   /* Step 7: release JPEG compression object */
  1862.  
  1863.   /* This is an important step since it will release a good deal of memory. */
  1864.   jpeg_destroy_compress(&cinfo);
  1865.  
  1866.   /* And we're done! */
  1867. }
  1868.  
  1869. /*
  1870. =================
  1871. SaveJPGToBuffer
  1872. =================
  1873. */
  1874. int SaveJPGToBuffer( byte *buffer, int quality,
  1875.     int image_width, int image_height,
  1876.     byte *image_buffer )
  1877. {
  1878.   struct jpeg_compress_struct cinfo;
  1879.   struct jpeg_error_mgr jerr;
  1880.   JSAMPROW row_pointer[1];  /* pointer to JSAMPLE row[s] */
  1881.   int row_stride;       /* physical row width in image buffer */
  1882.  
  1883.   /* Step 1: allocate and initialize JPEG compression object */
  1884.   cinfo.err = jpeg_std_error(&jerr);
  1885.   /* Now we can initialize the JPEG compression object. */
  1886.   jpeg_create_compress(&cinfo);
  1887.  
  1888.   /* Step 2: specify data destination (eg, a file) */
  1889.   /* Note: steps 2 and 3 can be done in either order. */
  1890.   jpegDest(&cinfo, buffer, image_width*image_height*4);
  1891.  
  1892.   /* Step 3: set parameters for compression */
  1893.   cinfo.image_width = image_width;  /* image width and height, in pixels */
  1894.   cinfo.image_height = image_height;
  1895.   cinfo.input_components = 4;       /* # of color components per pixel */
  1896.   cinfo.in_color_space = JCS_RGB;   /* colorspace of input image */
  1897.  
  1898.   jpeg_set_defaults(&cinfo);
  1899.   jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
  1900.   /* If quality is set high, disable chroma subsampling */
  1901.   if (quality >= 85) {
  1902.     cinfo.comp_info[0].h_samp_factor = 1;
  1903.     cinfo.comp_info[0].v_samp_factor = 1;
  1904.   }
  1905.  
  1906.   /* Step 4: Start compressor */
  1907.   jpeg_start_compress(&cinfo, TRUE);
  1908.  
  1909.   /* Step 5: while (scan lines remain to be written) */
  1910.   /*           jpeg_write_scanlines(...); */
  1911.   row_stride = image_width * 4; /* JSAMPLEs per row in image_buffer */
  1912.  
  1913.   while (cinfo.next_scanline < cinfo.image_height) {
  1914.     /* jpeg_write_scanlines expects an array of pointers to scanlines.
  1915.      * Here the array is only one element long, but you could pass
  1916.      * more than one scanline at a time if that's more convenient.
  1917.      */
  1918.     row_pointer[0] = & image_buffer[((cinfo.image_height-1)*row_stride)-cinfo.next_scanline * row_stride];
  1919.     (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
  1920.   }
  1921.  
  1922.   /* Step 6: Finish compression */
  1923.   jpeg_finish_compress(&cinfo);
  1924.  
  1925.   /* Step 7: release JPEG compression object */
  1926.   jpeg_destroy_compress(&cinfo);
  1927.  
  1928.   /* And we're done! */
  1929.   return hackSize;
  1930. }
  1931.  
  1932. //===================================================================
  1933.  
  1934. /*
  1935. =================
  1936. PNG LOADING
  1937. =================
  1938. */
  1939.  
  1940. /*
  1941.  *  Quake 3 image format : RGBA
  1942.  */
  1943.  
  1944. #define Q3IMAGE_BYTESPERPIXEL (4)
  1945.  
  1946. /*
  1947.  *  PNG specifications
  1948.  */
  1949.  
  1950. /*
  1951.  *  The first 8 Bytes of every PNG-File are a fixed signature
  1952.  *  to identify the file as a PNG.
  1953.  */
  1954.  
  1955. #define PNG_Signature "\x89\x50\x4E\x47\xD\xA\x1A\xA"
  1956. #define PNG_Signature_Size (8)
  1957.  
  1958. /*
  1959.  *  After the signature diverse chunks follow.
  1960.  *  A chunk consists of a header and if Length
  1961.  *  is bigger than 0 a body and a CRC of the body follow.
  1962.  */
  1963.  
  1964. struct PNG_ChunkHeader
  1965. {
  1966.     uint32_t Length;
  1967.     uint32_t Type;
  1968. };
  1969.  
  1970. #define PNG_ChunkHeader_Size (8)
  1971.  
  1972. typedef uint32_t PNG_ChunkCRC;
  1973.  
  1974. #define PNG_ChunkCRC_Size (4)
  1975.  
  1976. /*
  1977.  *  We use the following ChunkTypes.
  1978.  *  All others are ignored.
  1979.  */
  1980.  
  1981. #define MAKE_CHUNKTYPE(a,b,c,d) (((a) << 24) | ((b) << 16) | ((c) << 8) | ((d)))
  1982.  
  1983. #define PNG_ChunkType_IHDR MAKE_CHUNKTYPE('I', 'H', 'D', 'R')
  1984. #define PNG_ChunkType_PLTE MAKE_CHUNKTYPE('P', 'L', 'T', 'E')
  1985. #define PNG_ChunkType_IDAT MAKE_CHUNKTYPE('I', 'D', 'A', 'T')
  1986. #define PNG_ChunkType_IEND MAKE_CHUNKTYPE('I', 'E', 'N', 'D')
  1987. #define PNG_ChunkType_tRNS MAKE_CHUNKTYPE('t', 'R', 'N', 'S')
  1988.  
  1989. /*
  1990.  *  Per specification the first chunk after the signature SHALL be IHDR.
  1991.  */
  1992.  
  1993. struct PNG_Chunk_IHDR
  1994. {
  1995.     uint32_t Width;
  1996.     uint32_t Height;
  1997.     uint8_t  BitDepth;
  1998.     uint8_t  ColourType;
  1999.     uint8_t  CompressionMethod;
  2000.     uint8_t  FilterMethod;
  2001.     uint8_t  InterlaceMethod;
  2002. };
  2003.  
  2004. #define PNG_Chunk_IHDR_Size (13)
  2005.  
  2006. /*
  2007.  *  ColourTypes
  2008.  */
  2009.  
  2010. #define PNG_ColourType_Grey      (0)
  2011. #define PNG_ColourType_True      (2)
  2012. #define PNG_ColourType_Indexed   (3)
  2013. #define PNG_ColourType_GreyAlpha (4)
  2014. #define PNG_ColourType_TrueAlpha (6)
  2015.  
  2016. /*
  2017.  *  number of colour components
  2018.  *
  2019.  *  Grey      : 1 grey
  2020.  *  True      : 1 R, 1 G, 1 B
  2021.  *  Indexed   : 1 index
  2022.  *  GreyAlpha : 1 grey, 1 alpha
  2023.  *  TrueAlpha : 1 R, 1 G, 1 B, 1 alpha
  2024.  */
  2025.  
  2026. #define PNG_NumColourComponents_Grey      (1)
  2027. #define PNG_NumColourComponents_True      (3)
  2028. #define PNG_NumColourComponents_Indexed   (1)
  2029. #define PNG_NumColourComponents_GreyAlpha (2)
  2030. #define PNG_NumColourComponents_TrueAlpha (4)
  2031.  
  2032. /*
  2033.  *  For the different ColourTypes
  2034.  *  different BitDepths are specified.
  2035.  */
  2036.  
  2037. #define PNG_BitDepth_1  ( 1)
  2038. #define PNG_BitDepth_2  ( 2)
  2039. #define PNG_BitDepth_4  ( 4)
  2040. #define PNG_BitDepth_8  ( 8)
  2041. #define PNG_BitDepth_16 (16)
  2042.  
  2043. /*
  2044.  *  Only one valid CompressionMethod is standardized.
  2045.  */
  2046.  
  2047. #define PNG_CompressionMethod_0 (0)
  2048.  
  2049. /*
  2050.  *  Only one valid FilterMethod is currently standardized.
  2051.  */
  2052.  
  2053. #define PNG_FilterMethod_0 (0)
  2054.  
  2055. /*
  2056.  *  This FilterMethod defines 5 FilterTypes
  2057.  */
  2058.  
  2059. #define PNG_FilterType_None    (0)
  2060. #define PNG_FilterType_Sub     (1)
  2061. #define PNG_FilterType_Up      (2)
  2062. #define PNG_FilterType_Average (3)
  2063. #define PNG_FilterType_Paeth   (4)
  2064.  
  2065. /*
  2066.  *  Two InterlaceMethods are standardized :
  2067.  *  0 - NonInterlaced
  2068.  *  1 - Interlaced
  2069.  */
  2070.  
  2071. #define PNG_InterlaceMethod_NonInterlaced (0)
  2072. #define PNG_InterlaceMethod_Interlaced    (1)
  2073.  
  2074. /*
  2075.  *  The Adam7 interlace method uses 7 passes.
  2076.  */
  2077.  
  2078. #define PNG_Adam7_NumPasses (7)
  2079.  
  2080. /*
  2081.  *  The compressed data starts with a header ...
  2082.  */
  2083.  
  2084. struct PNG_ZlibHeader
  2085. {
  2086.     uint8_t CompressionMethod;
  2087.     uint8_t Flags;
  2088. };
  2089.  
  2090. #define PNG_ZlibHeader_Size (2)
  2091.  
  2092. /*
  2093.  *  ... and is followed by a check value
  2094.  */
  2095.  
  2096. #define PNG_ZlibCheckValue_Size (4)
  2097.  
  2098. /*
  2099.  *  Some support functions for buffered files follow.
  2100.  */
  2101.  
  2102. /*
  2103.  *  buffered file representation
  2104.  */
  2105.  
  2106. struct BufferedFile
  2107. {
  2108.     byte *Buffer;
  2109.     int   Length;
  2110.     byte *Ptr;
  2111.     int   BytesLeft;
  2112. };
  2113.  
  2114. /*
  2115.  *  Read a file into a buffer.
  2116.  */
  2117.  
  2118. static struct BufferedFile *ReadBufferedFile(const char *name)
  2119. {
  2120.     struct BufferedFile *BF;
  2121.  
  2122.     /*
  2123.      *  input verification
  2124.      */
  2125.  
  2126.     if(!name)
  2127.     {
  2128.         return(NULL);
  2129.     }
  2130.  
  2131.     /*
  2132.      *  Allocate control struct.
  2133.      */
  2134.  
  2135.     BF = ri.Malloc(sizeof(struct BufferedFile));
  2136.     if(!BF)
  2137.     {
  2138.         return(NULL);
  2139.     }
  2140.  
  2141.     /*
  2142.      *  Initialize the structs components.
  2143.      */
  2144.  
  2145.     BF->Length    = 0;
  2146.     BF->Buffer    = NULL;
  2147.     BF->Ptr       = NULL;
  2148.     BF->BytesLeft = 0;
  2149.  
  2150.     /*
  2151.      *  Read the file.
  2152.      */
  2153.  
  2154.     BF->Length = ri.FS_ReadFile((char *) name, (void **) &BF->Buffer);
  2155.  
  2156.     /*
  2157.      *  Did we get it? Is it big enough?
  2158.      */
  2159.  
  2160.     if(!(BF->Buffer && (BF->Length > 0)))
  2161.     {
  2162.         ri.Free(BF);
  2163.  
  2164.         return(NULL);
  2165.     }
  2166.  
  2167.     /*
  2168.      *  Set the pointers and counters.
  2169.      */
  2170.  
  2171.     BF->Ptr       = BF->Buffer;
  2172.     BF->BytesLeft = BF->Length;
  2173.  
  2174.     return(BF);
  2175. }
  2176.  
  2177. /*
  2178.  *  Close a buffered file.
  2179.  */
  2180.  
  2181. static void CloseBufferedFile(struct BufferedFile *BF)
  2182. {
  2183.     if(BF)
  2184.     {
  2185.         if(BF->Buffer)
  2186.         {
  2187.             ri.FS_FreeFile(BF->Buffer);
  2188.         }
  2189.  
  2190.         ri.Free(BF);
  2191.     }
  2192. }
  2193.  
  2194. /*
  2195.  *  Get a pointer to the requested bytes.
  2196.  */
  2197.  
  2198. static void *BufferedFileRead(struct BufferedFile *BF, int Length)
  2199. {
  2200.     void *RetVal;
  2201.  
  2202.     /*
  2203.      *  input verification
  2204.      */
  2205.  
  2206.     if(!(BF && Length))
  2207.     {
  2208.         return(NULL);
  2209.     }
  2210.  
  2211.     /*
  2212.      *  not enough bytes left
  2213.      */
  2214.  
  2215.     if(Length > BF->BytesLeft)
  2216.     {
  2217.         return(NULL);
  2218.     }
  2219.  
  2220.     /*
  2221.      *  the pointer to the requested data
  2222.      */
  2223.  
  2224.     RetVal = BF->Ptr;
  2225.  
  2226.     /*
  2227.      *  Raise the pointer and counter.
  2228.      */
  2229.  
  2230.     BF->Ptr       += Length;
  2231.     BF->BytesLeft -= Length;
  2232.  
  2233.     return(RetVal);
  2234. }
  2235.  
  2236. /*
  2237.  *  Rewind the buffer.
  2238.  */
  2239.  
  2240. static qboolean BufferedFileRewind(struct BufferedFile *BF, int Offset)
  2241. {
  2242.     int BytesRead;
  2243.  
  2244.     /*
  2245.      *  input verification
  2246.      */
  2247.  
  2248.     if(!BF)
  2249.     {
  2250.         return(qfalse);
  2251.     }
  2252.  
  2253.     /*
  2254.      *  special trick to rewind to the beginning of the buffer
  2255.      */
  2256.  
  2257.     if(Offset == -1)
  2258.     {
  2259.         BF->Ptr       = BF->Buffer;
  2260.         BF->BytesLeft = BF->Length;
  2261.  
  2262.         return(qtrue);
  2263.     }
  2264.  
  2265.     /*
  2266.      *  How many bytes do we have already read?
  2267.      */
  2268.  
  2269.     BytesRead = BF->Ptr - BF->Buffer;
  2270.  
  2271.     /*
  2272.      *  We can only rewind to the beginning of the BufferedFile.
  2273.      */
  2274.  
  2275.     if(Offset > BytesRead)
  2276.     {
  2277.         return(qfalse);
  2278.     }
  2279.  
  2280.     /*
  2281.      *  lower the pointer and counter.
  2282.      */
  2283.  
  2284.     BF->Ptr       -= Offset;
  2285.     BF->BytesLeft += Offset;
  2286.  
  2287.     return(qtrue);
  2288. }
  2289.  
  2290. /*
  2291.  *  Skip some bytes.
  2292.  */
  2293.  
  2294. static qboolean BufferedFileSkip(struct BufferedFile *BF, int Offset)
  2295. {
  2296.     /*
  2297.      *  input verification
  2298.      */
  2299.  
  2300.     if(!BF)
  2301.     {
  2302.         return(qfalse);
  2303.     }
  2304.  
  2305.     /*
  2306.      *  We can only skip to the end of the BufferedFile.
  2307.      */
  2308.  
  2309.     if(Offset > BF->BytesLeft)
  2310.     {
  2311.         return(qfalse);
  2312.     }
  2313.  
  2314.     /*
  2315.      *  lower the pointer and counter.
  2316.      */
  2317.  
  2318.     BF->Ptr       += Offset;
  2319.     BF->BytesLeft -= Offset;
  2320.  
  2321.     return(qtrue);
  2322. }
  2323.  
  2324. /*
  2325.  *  Find a chunk
  2326.  */
  2327.  
  2328. static qboolean FindChunk(struct BufferedFile *BF, uint32_t ChunkType)
  2329. {
  2330.     struct PNG_ChunkHeader *CH;
  2331.  
  2332.     uint32_t Length;
  2333.     uint32_t Type;
  2334.  
  2335.     /*
  2336.      *  input verification
  2337.      */
  2338.  
  2339.     if(!BF)
  2340.     {
  2341.         return(qfalse);
  2342.     }
  2343.  
  2344.     /*
  2345.      *  cycle trough the chunks
  2346.      */
  2347.  
  2348.     while(qtrue)
  2349.     {
  2350.         /*
  2351.          *  Read the chunk-header.
  2352.          */
  2353.  
  2354.         CH = BufferedFileRead(BF, PNG_ChunkHeader_Size);
  2355.         if(!CH)
  2356.         {
  2357.             return(qfalse);
  2358.         }
  2359.  
  2360.         /*
  2361.          *  Do not swap the original types
  2362.          *  they might be needed later.
  2363.          */
  2364.  
  2365.         Length = BigLong(CH->Length);
  2366.         Type   = BigLong(CH->Type);
  2367.  
  2368.         /*
  2369.          *  We found it!
  2370.          */
  2371.  
  2372.         if(Type == ChunkType)
  2373.         {
  2374.             /*
  2375.              *  Rewind to the start of the chunk.
  2376.              */
  2377.          
  2378.             BufferedFileRewind(BF, PNG_ChunkHeader_Size);
  2379.  
  2380.             break;
  2381.         }
  2382.         else
  2383.         {
  2384.             /*
  2385.              *  Skip the rest of the chunk.
  2386.              */
  2387.  
  2388.             if(Length)
  2389.             {
  2390.                 if(!BufferedFileSkip(BF, Length + PNG_ChunkCRC_Size))
  2391.                 {
  2392.                     return(qfalse);
  2393.                 }  
  2394.             }
  2395.         }
  2396.     }
  2397.  
  2398.     return(qtrue);
  2399. }
  2400.  
  2401. /*
  2402.  *  Decompress all IDATs
  2403.  */
  2404.  
  2405. static uint32_t DecompressIDATs(struct BufferedFile *BF, uint8_t **Buffer)
  2406. {
  2407.     uint8_t  *DecompressedData;
  2408.     uint32_t  DecompressedDataLength;
  2409.  
  2410.     uint8_t  *CompressedData;
  2411.     uint8_t  *CompressedDataPtr;
  2412.     uint32_t  CompressedDataLength;
  2413.  
  2414.     struct PNG_ChunkHeader *CH;
  2415.  
  2416.     uint32_t Length;
  2417.     uint32_t Type;
  2418.  
  2419.     int BytesToRewind;
  2420.  
  2421.     int32_t   puffResult;
  2422.     uint8_t  *puffDest;
  2423.     uint32_t  puffDestLen;
  2424.     uint8_t  *puffSrc;
  2425.     uint32_t  puffSrcLen;
  2426.  
  2427.     /*
  2428.      *  input verification
  2429.      */
  2430.  
  2431.     if(!(BF && Buffer))
  2432.     {
  2433.         return(-1);
  2434.     }
  2435.  
  2436.     /*
  2437.      *  some zeroing
  2438.      */
  2439.  
  2440.     DecompressedData = NULL;
  2441.     DecompressedDataLength = 0;
  2442.     *Buffer = DecompressedData;
  2443.  
  2444.     CompressedData = NULL;
  2445.     CompressedDataLength = 0;
  2446.  
  2447.     BytesToRewind = 0;
  2448.  
  2449.     /*
  2450.      *  Find the first IDAT chunk.
  2451.      */
  2452.  
  2453.     if(!FindChunk(BF, PNG_ChunkType_IDAT))
  2454.     {
  2455.         return(-1);
  2456.     }
  2457.  
  2458.     /*
  2459.      *  Count the size of the uncompressed data
  2460.      */
  2461.  
  2462.     while(qtrue)
  2463.     {
  2464.         /*
  2465.          *  Read chunk header
  2466.          */
  2467.  
  2468.         CH = BufferedFileRead(BF, PNG_ChunkHeader_Size);
  2469.         if(!CH)
  2470.         {
  2471.             /*
  2472.              *  Rewind to the start of this adventure
  2473.              *  and return unsuccessfull
  2474.              */
  2475.  
  2476.             BufferedFileRewind(BF, BytesToRewind);
  2477.  
  2478.             return(-1);
  2479.         }
  2480.  
  2481.         /*
  2482.          *  Length and Type of chunk
  2483.          */
  2484.  
  2485.         Length = BigLong(CH->Length);
  2486.         Type   = BigLong(CH->Type);
  2487.  
  2488.         /*
  2489.          *  We have reached the end of the IDAT chunks
  2490.          */
  2491.  
  2492.         if(!(Type == PNG_ChunkType_IDAT))
  2493.         {
  2494.             BufferedFileRewind(BF, PNG_ChunkHeader_Size);
  2495.  
  2496.             break;
  2497.         }
  2498.  
  2499.         /*
  2500.          *  Add chunk header to count.
  2501.          */
  2502.  
  2503.         BytesToRewind += PNG_ChunkHeader_Size;
  2504.  
  2505.         /*
  2506.          *  Skip to next chunk
  2507.          */
  2508.  
  2509.         if(Length)
  2510.         {
  2511.             if(!BufferedFileSkip(BF, Length + PNG_ChunkCRC_Size))
  2512.             {
  2513.                 BufferedFileRewind(BF, BytesToRewind);
  2514.  
  2515.                 return(-1);
  2516.             }
  2517.  
  2518.             BytesToRewind += Length + PNG_ChunkCRC_Size;
  2519.             CompressedDataLength += Length;
  2520.         }
  2521.     }
  2522.  
  2523.     BufferedFileRewind(BF, BytesToRewind);
  2524.  
  2525.     CompressedData = ri.Malloc(CompressedDataLength);
  2526.     if(!CompressedData)
  2527.     {
  2528.         return(-1);
  2529.     }
  2530.  
  2531.     CompressedDataPtr = CompressedData;
  2532.  
  2533.     /*
  2534.      *  Collect the compressed Data
  2535.      */
  2536.  
  2537.     while(qtrue)
  2538.     {
  2539.         /*
  2540.          *  Read chunk header
  2541.          */
  2542.  
  2543.         CH = BufferedFileRead(BF, PNG_ChunkHeader_Size);
  2544.         if(!CH)
  2545.         {
  2546.             ri.Free(CompressedData);
  2547.  
  2548.             return(-1);
  2549.         }
  2550.  
  2551.         /*
  2552.          *  Length and Type of chunk
  2553.          */
  2554.  
  2555.         Length = BigLong(CH->Length);
  2556.         Type   = BigLong(CH->Type);
  2557.  
  2558.         /*
  2559.          *  We have reached the end of the IDAT chunks
  2560.          */
  2561.  
  2562.         if(!(Type == PNG_ChunkType_IDAT))
  2563.         {
  2564.             BufferedFileRewind(BF, PNG_ChunkHeader_Size);
  2565.  
  2566.             break;
  2567.         }
  2568.  
  2569.         /*
  2570.          *  Copy the Data
  2571.          */
  2572.  
  2573.         if(Length)
  2574.         {
  2575.             uint8_t *OrigCompressedData;
  2576.    
  2577.             OrigCompressedData = BufferedFileRead(BF, Length);
  2578.             if(!OrigCompressedData)
  2579.             {
  2580.                 ri.Free(CompressedData);
  2581.  
  2582.                 return(-1);
  2583.             }
  2584.  
  2585.             if(!BufferedFileSkip(BF, PNG_ChunkCRC_Size))
  2586.             {
  2587.                 ri.Free(CompressedData);
  2588.  
  2589.                 return(-1);
  2590.             }
  2591.  
  2592.             memcpy(CompressedDataPtr, OrigCompressedData, Length);
  2593.             CompressedDataPtr += Length;
  2594.         }
  2595.     }
  2596.  
  2597.     /*
  2598.      *  Let puff() calculate the decompressed data length.
  2599.      */
  2600.  
  2601.     puffDest    = NULL;
  2602.     puffDestLen = 0;
  2603.  
  2604.     /*
  2605.      *  The zlib header and checkvalue don't belong to the compressed data.
  2606.      */
  2607.  
  2608.     puffSrc    = CompressedData + PNG_ZlibHeader_Size;
  2609.     puffSrcLen = CompressedDataLength - PNG_ZlibHeader_Size - PNG_ZlibCheckValue_Size;
  2610.  
  2611.     /*
  2612.      *  first puff() to calculate the size of the uncompressed data
  2613.      */
  2614.  
  2615.     puffResult = puff(puffDest, &puffDestLen, puffSrc, &puffSrcLen);
  2616.     if(!((puffResult == 0) && (puffDestLen > 0)))
  2617.     {
  2618.         ri.Free(CompressedData);
  2619.  
  2620.         return(-1);
  2621.     }
  2622.  
  2623.     /*
  2624.      *  Allocate the buffer for the uncompressed data.
  2625.      */
  2626.  
  2627.     DecompressedData = ri.Malloc(puffDestLen);
  2628.     if(!DecompressedData)
  2629.     {
  2630.         ri.Free(CompressedData);
  2631.  
  2632.         return(-1);
  2633.     }
  2634.  
  2635.     /*
  2636.      *  Set the input again in case something was changed by the last puff() .
  2637.      */
  2638.  
  2639.     puffDest   = DecompressedData;
  2640.     puffSrc    = CompressedData + PNG_ZlibHeader_Size;
  2641.     puffSrcLen = CompressedDataLength - PNG_ZlibHeader_Size - PNG_ZlibCheckValue_Size;
  2642.  
  2643.     /*
  2644.      *  decompression puff()
  2645.      */
  2646.  
  2647.     puffResult = puff(puffDest, &puffDestLen, puffSrc, &puffSrcLen);
  2648.  
  2649.     /*
  2650.      *  The compressed data is not needed anymore.
  2651.      */
  2652.  
  2653.     ri.Free(CompressedData);
  2654.  
  2655.     /*
  2656.      *  Check if the last puff() was successfull.
  2657.      */
  2658.  
  2659.     if(!((puffResult == 0) && (puffDestLen > 0)))
  2660.     {
  2661.         ri.Free(DecompressedData);
  2662.  
  2663.         return(-1);
  2664.     }
  2665.  
  2666.     /*
  2667.      *  Set the output of this function.
  2668.      */
  2669.  
  2670.     DecompressedDataLength = puffDestLen;
  2671.     *Buffer = DecompressedData;
  2672.  
  2673.     return(DecompressedDataLength);
  2674. }
  2675.  
  2676. /*
  2677.  *  the Paeth predictor
  2678.  */
  2679.  
  2680. static uint8_t PredictPaeth(uint8_t a, uint8_t b, uint8_t c)
  2681. {
  2682.     /*
  2683.      *  a == Left
  2684.      *  b == Up
  2685.      *  c == UpLeft
  2686.      */
  2687.  
  2688.     uint8_t Pr;
  2689.     int p;
  2690.     int pa, pb, pc;
  2691.  
  2692.     Pr = 0;
  2693.  
  2694.     p  = ((int) a) + ((int) b) - ((int) c);
  2695.     pa = abs(p - ((int) a));
  2696.     pb = abs(p - ((int) b));
  2697.     pc = abs(p - ((int) c));
  2698.  
  2699.     if((pa <= pb) && (pa <= pc))
  2700.     {
  2701.         Pr = a;
  2702.     }
  2703.     else if(pb <= pc)
  2704.     {
  2705.         Pr = b;
  2706.     }
  2707.     else
  2708.     {
  2709.         Pr = c;
  2710.     }
  2711.  
  2712.     return(Pr);
  2713.  
  2714. }
  2715.  
  2716. /*
  2717.  *  Reverse the filters.
  2718.  */
  2719.  
  2720. static qboolean UnfilterImage(uint8_t  *DecompressedData,
  2721.                               uint32_t  ImageHeight,
  2722.                       uint32_t  BytesPerScanline,
  2723.                       uint32_t  BytesPerPixel)
  2724. {
  2725.     uint8_t   *DecompPtr;
  2726.     uint8_t   FilterType;
  2727.     uint8_t  *PixelLeft, *PixelUp, *PixelUpLeft;
  2728.     uint32_t  w, h, p;
  2729.  
  2730.     /*
  2731.      *  some zeros for the filters
  2732.      */
  2733.  
  2734.     uint8_t Zeros[8] = {0, 0, 0, 0, 0, 0, 0, 0};
  2735.  
  2736.     /*
  2737.      *  input verification
  2738.      *
  2739.      *  ImageHeight and BytesPerScanline are not checked,
  2740.      *  because these can be zero in some interlace passes.
  2741.      */
  2742.  
  2743.     if(!(DecompressedData && BytesPerPixel))
  2744.     {
  2745.     return(qfalse);
  2746.     }
  2747.  
  2748.  
  2749.     /*
  2750.      *  Set the pointer to the start of the decompressed Data.
  2751.      */
  2752.  
  2753.     DecompPtr = DecompressedData;
  2754.  
  2755.     /*
  2756.      *  Un-filtering is done in place.
  2757.      */
  2758.  
  2759.     /*
  2760.      *  Go trough all scanlines.
  2761.      */
  2762.  
  2763.     for(h = 0; h < ImageHeight; h++)
  2764.     {
  2765.         /*
  2766.          *  Every scanline starts with a FilterType byte.
  2767.          */
  2768.  
  2769.         FilterType = *DecompPtr;
  2770.         DecompPtr++;
  2771.  
  2772.         /*
  2773.          *  Left pixel of the first byte in a scanline is zero.
  2774.          */
  2775.  
  2776.         PixelLeft = Zeros;
  2777.  
  2778.         /*
  2779.          *  Set PixelUp to previous line only if we are on the second line or above.
  2780.          *
  2781.          *  Plus one byte for the FilterType
  2782.          */
  2783.  
  2784.         if(h > 0)
  2785.         {
  2786.             PixelUp = DecompPtr - (BytesPerScanline + 1);
  2787.         }
  2788.         else
  2789.         {
  2790.             PixelUp = Zeros;
  2791.         }
  2792.  
  2793.         /*
  2794.          * The pixel left to the first pixel of the previous scanline is zero too.
  2795.          */
  2796.  
  2797.         PixelUpLeft = Zeros;
  2798.  
  2799.         /*
  2800.          *  Cycle trough all pixels of the scanline.
  2801.          */
  2802.  
  2803.         for(w = 0; w < (BytesPerScanline / BytesPerPixel); w++)
  2804.         {
  2805.             /*
  2806.              *  Cycle trough the bytes of the pixel.
  2807.              */
  2808.  
  2809.             for(p = 0; p < BytesPerPixel; p++)
  2810.             {
  2811.                 switch(FilterType)
  2812.                 {
  2813.                     case PNG_FilterType_None :
  2814.                     {
  2815.                         /*
  2816.                          *  The byte is unfiltered.
  2817.                          */
  2818.  
  2819.                         break;
  2820.                     }
  2821.  
  2822.                     case PNG_FilterType_Sub :
  2823.                     {
  2824.                         DecompPtr[p] += PixelLeft[p];
  2825.  
  2826.                         break;
  2827.                     }
  2828.  
  2829.             case PNG_FilterType_Up :
  2830.                     {
  2831.                         DecompPtr[p] += PixelUp[p];
  2832.  
  2833.                         break;
  2834.                     }
  2835.  
  2836.                     case PNG_FilterType_Average :
  2837.                     {
  2838.                         DecompPtr[p] += ((uint8_t) ((((uint16_t) PixelLeft[p]) + ((uint16_t) PixelUp[p])) / 2));
  2839.  
  2840.                         break;
  2841.                     }
  2842.  
  2843.                     case PNG_FilterType_Paeth :
  2844.                     {
  2845.                         DecompPtr[p] += PredictPaeth(PixelLeft[p], PixelUp[p], PixelUpLeft[p]);
  2846.  
  2847.                         break;
  2848.                     }
  2849.  
  2850.                     default :
  2851.                     {
  2852.                         return(qfalse);
  2853.                     }
  2854.                 }
  2855.             }
  2856.    
  2857.             PixelLeft = DecompPtr;
  2858.  
  2859.             /*
  2860.              *  We only have a upleft pixel if we are on the second line or above.
  2861.              */
  2862.  
  2863.             if(h > 0)
  2864.             {
  2865.                 PixelUpLeft = DecompPtr - (BytesPerScanline + 1);
  2866.             }
  2867.  
  2868.         /*
  2869.              *  Skip to the next pixel.
  2870.              */
  2871.  
  2872.             DecompPtr += BytesPerPixel;
  2873.      
  2874.             /*
  2875.              *  We only have a previous line if we are on the second line and above.
  2876.              */
  2877.  
  2878.             if(h > 0)
  2879.             {
  2880.                 PixelUp = DecompPtr - (BytesPerScanline + 1);
  2881.             }
  2882.         }
  2883.     }
  2884.  
  2885.  return(qtrue);
  2886. }
  2887.  
  2888. /*
  2889.  *  Convert a raw input pixel to Quake 3 RGA format.
  2890.  */
  2891.  
  2892. static qboolean ConvertPixel(struct PNG_Chunk_IHDR *IHDR,
  2893.                  byte                  *OutPtr,
  2894.                  uint8_t               *DecompPtr,
  2895.                              qboolean               HasTransparentColour,
  2896.                              uint8_t               *TransparentColour,
  2897.                              uint8_t               *OutPal)
  2898. {
  2899.     /*
  2900.      *  input verification
  2901.      */
  2902.    
  2903.     if(!(IHDR && OutPtr && DecompPtr && TransparentColour && OutPal))
  2904.     {
  2905.      return(qfalse);
  2906.     }
  2907.  
  2908.     switch(IHDR->ColourType)
  2909.     {
  2910.         case PNG_ColourType_Grey :
  2911.         {
  2912.             switch(IHDR->BitDepth)
  2913.             {
  2914.                 case PNG_BitDepth_1 :
  2915.                 case PNG_BitDepth_2 :
  2916.                 case PNG_BitDepth_4 :
  2917.                 {
  2918.                 uint8_t Step;
  2919.                     uint8_t GreyValue;
  2920.  
  2921.                     Step = 0xFF / ((1 << IHDR->BitDepth) - 1);
  2922.  
  2923.                     GreyValue = DecompPtr[0] * Step;
  2924.  
  2925.                     OutPtr[0] = GreyValue;
  2926.                     OutPtr[1] = GreyValue;
  2927.                     OutPtr[2] = GreyValue;
  2928.                     OutPtr[3] = 0xFF;
  2929.  
  2930.                     /*
  2931.                      *  Grey supports full transparency for one specified colour
  2932.                      */
  2933.  
  2934.                     if(HasTransparentColour)
  2935.                     {
  2936.                         if(TransparentColour[1] == DecompPtr[0])
  2937.                         {
  2938.                             OutPtr[3] = 0x00;
  2939.                         }
  2940.                     }
  2941.    
  2942.  
  2943.                     break;
  2944.                 }
  2945.      
  2946.                 case PNG_BitDepth_8 :
  2947.                 case PNG_BitDepth_16 :
  2948.                 {
  2949.                     OutPtr[0] = DecompPtr[0];
  2950.                     OutPtr[1] = DecompPtr[0];
  2951.                     OutPtr[2] = DecompPtr[0];
  2952.                     OutPtr[3] = 0xFF;
  2953.      
  2954.                     /*
  2955.                      *  Grey supports full transparency for one specified colour
  2956.                      */
  2957.  
  2958.                     if(HasTransparentColour)
  2959.                     {
  2960.                         if(IHDR->BitDepth == PNG_BitDepth_8)
  2961.                         {
  2962.                             if(TransparentColour[1] == DecompPtr[0])
  2963.                             {
  2964.                                 OutPtr[3] = 0x00;
  2965.                             }
  2966.                         }
  2967.                         else
  2968.                         {
  2969.                             if((TransparentColour[0] == DecompPtr[0]) && (TransparentColour[1] == DecompPtr[1]))
  2970.                             {
  2971.                                 OutPtr[3] = 0x00;
  2972.                             }
  2973.                         }
  2974.                     }
  2975.  
  2976.                     break;
  2977.                 }
  2978.      
  2979.                 default :
  2980.                 {
  2981.                     return(qfalse);
  2982.                 }
  2983.             }
  2984.    
  2985.             break;
  2986.         }
  2987.  
  2988.         case PNG_ColourType_True :
  2989.         {
  2990.             switch(IHDR->BitDepth)
  2991.             {
  2992.                 case PNG_BitDepth_8 :
  2993.                 {
  2994.                     OutPtr[0] = DecompPtr[0];
  2995.                     OutPtr[1] = DecompPtr[1];
  2996.                     OutPtr[2] = DecompPtr[2];
  2997.                     OutPtr[3] = 0xFF;
  2998.      
  2999.                     /*
  3000.                      *  True supports full transparency for one specified colour
  3001.                      */
  3002.  
  3003.                     if(HasTransparentColour)
  3004.                     {
  3005.                         if((TransparentColour[1] == DecompPtr[0]) &&
  3006.                            (TransparentColour[3] == DecompPtr[1]) &&
  3007.                            (TransparentColour[5] == DecompPtr[3]))
  3008.                         {
  3009.                             OutPtr[3] = 0x00;
  3010.                         }
  3011.                     }
  3012.  
  3013.                     break;
  3014.                 }
  3015.      
  3016.                 case PNG_BitDepth_16 :
  3017.                 {
  3018.                     /*
  3019.                      *  We use only the upper byte.
  3020.                      */
  3021.  
  3022.                     OutPtr[0] = DecompPtr[0];
  3023.                     OutPtr[1] = DecompPtr[2];
  3024.                     OutPtr[2] = DecompPtr[4];
  3025.                     OutPtr[3] = 0xFF;
  3026.      
  3027.                     /*
  3028.                      *  True supports full transparency for one specified colour
  3029.                      */
  3030.  
  3031.                     if(HasTransparentColour)
  3032.                     {
  3033.                         if((TransparentColour[0] == DecompPtr[0]) && (TransparentColour[1] == DecompPtr[1]) &&
  3034.                            (TransparentColour[2] == DecompPtr[2]) && (TransparentColour[3] == DecompPtr[3]) &&
  3035.                            (TransparentColour[4] == DecompPtr[4]) && (TransparentColour[5] == DecompPtr[5]))
  3036.                         {
  3037.                             OutPtr[3] = 0x00;
  3038.                         }
  3039.                     }
  3040.  
  3041.                     break;
  3042.                 }
  3043.  
  3044.                 default :
  3045.                 {
  3046.                     return(qfalse);
  3047.                 }
  3048.             }
  3049.  
  3050.             break;
  3051.         }
  3052.  
  3053.         case PNG_ColourType_Indexed :
  3054.         {
  3055.             OutPtr[0] = OutPal[DecompPtr[0] * Q3IMAGE_BYTESPERPIXEL + 0];
  3056.             OutPtr[1] = OutPal[DecompPtr[0] * Q3IMAGE_BYTESPERPIXEL + 1];
  3057.             OutPtr[2] = OutPal[DecompPtr[0] * Q3IMAGE_BYTESPERPIXEL + 2];
  3058.             OutPtr[3] = OutPal[DecompPtr[0] * Q3IMAGE_BYTESPERPIXEL + 3];
  3059.    
  3060.             break;
  3061.         }
  3062.  
  3063.         case PNG_ColourType_GreyAlpha :
  3064.         {
  3065.             switch(IHDR->BitDepth)
  3066.             {
  3067.                 case PNG_BitDepth_8 :
  3068.                 {
  3069.                     OutPtr[0] = DecompPtr[0];
  3070.                     OutPtr[1] = DecompPtr[0];
  3071.                     OutPtr[2] = DecompPtr[0];
  3072.                     OutPtr[3] = DecompPtr[1];
  3073.      
  3074.                     break;
  3075.                 }
  3076.  
  3077.                 case PNG_BitDepth_16 :
  3078.                 {
  3079.                     /*
  3080.                      *  We use only the upper byte.
  3081.                      */
  3082.  
  3083.                     OutPtr[0] = DecompPtr[0];
  3084.                     OutPtr[1] = DecompPtr[0];
  3085.                     OutPtr[2] = DecompPtr[0];
  3086.                     OutPtr[3] = DecompPtr[2];
  3087.      
  3088.                     break;
  3089.                 }
  3090.  
  3091.                 default :
  3092.                 {
  3093.                     return(qfalse);
  3094.                 }
  3095.             }
  3096.  
  3097.             break;
  3098.         }
  3099.  
  3100.         case PNG_ColourType_TrueAlpha :
  3101.         {
  3102.             switch(IHDR->BitDepth)
  3103.             {
  3104.                 case PNG_BitDepth_8 :
  3105.                 {
  3106.                     OutPtr[0] = DecompPtr[0];
  3107.                     OutPtr[1] = DecompPtr[1];
  3108.                     OutPtr[2] = DecompPtr[2];
  3109.                     OutPtr[3] = DecompPtr[3];
  3110.      
  3111.                     break;
  3112.                 }
  3113.      
  3114.                 case PNG_BitDepth_16 :
  3115.                 {
  3116.                     /*
  3117.                      *  We use only the upper byte.
  3118.                      */
  3119.  
  3120.                     OutPtr[0] = DecompPtr[0];
  3121.                     OutPtr[1] = DecompPtr[2];
  3122.                     OutPtr[2] = DecompPtr[4];
  3123.                     OutPtr[3] = DecompPtr[6];
  3124.      
  3125.                     break;
  3126.                 }
  3127.  
  3128.                 default :
  3129.                 {
  3130.                     return(qfalse);
  3131.                 }
  3132.             }
  3133.  
  3134.             break;
  3135.         }
  3136.  
  3137.         default :
  3138.         {
  3139.             return(qfalse);
  3140.         }
  3141.     }
  3142.  
  3143.     return(qtrue);
  3144. }
  3145.  
  3146.  
  3147. /*
  3148.  *  Decode a non-interlaced image.
  3149.  */
  3150.  
  3151. static qboolean DecodeImageNonInterlaced(struct PNG_Chunk_IHDR *IHDR,
  3152.                                          byte                  *OutBuffer,
  3153.                                          uint8_t               *DecompressedData,
  3154.                                          uint32_t               DecompressedDataLength,
  3155.                                          qboolean               HasTransparentColour,
  3156.                                          uint8_t               *TransparentColour,
  3157.                                          uint8_t               *OutPal)
  3158. {
  3159.     uint32_t IHDR_Width;
  3160.     uint32_t IHDR_Height;
  3161.     uint32_t BytesPerScanline, BytesPerPixel, PixelsPerByte;
  3162.     uint32_t  w, h, p;
  3163.     byte *OutPtr;
  3164.     uint8_t *DecompPtr;
  3165.  
  3166.     /*
  3167.      *  input verification
  3168.      */
  3169.  
  3170.     if(!(IHDR && OutBuffer && DecompressedData && DecompressedDataLength && TransparentColour && OutPal))
  3171.     {
  3172.     return(qfalse);
  3173.     }
  3174.  
  3175.     /*
  3176.      *  byte swapping
  3177.      */
  3178.      
  3179.     IHDR_Width  = BigLong(IHDR->Width);
  3180.     IHDR_Height = BigLong(IHDR->Height);
  3181.  
  3182.     /*
  3183.      *  information for un-filtering
  3184.      */
  3185.  
  3186.     switch(IHDR->ColourType)
  3187.     {
  3188.         case PNG_ColourType_Grey :
  3189.         {
  3190.             switch(IHDR->BitDepth)
  3191.             {
  3192.                 case PNG_BitDepth_1 :
  3193.                 case PNG_BitDepth_2 :
  3194.                 case PNG_BitDepth_4 :
  3195.                 {
  3196.                     BytesPerPixel    = 1;
  3197.                     PixelsPerByte    = 8 / IHDR->BitDepth;
  3198.  
  3199.                     break;
  3200.                 }
  3201.  
  3202.                 case PNG_BitDepth_8  :
  3203.                 case PNG_BitDepth_16 :
  3204.                 {
  3205.                     BytesPerPixel    = (IHDR->BitDepth / 8) * PNG_NumColourComponents_Grey;
  3206.                     PixelsPerByte    = 1;
  3207.  
  3208.                     break;
  3209.                 }
  3210.  
  3211.                 default :
  3212.                 {
  3213.                     return(qfalse);
  3214.                 }
  3215.             }
  3216.  
  3217.             break;
  3218.         }
  3219.  
  3220.         case PNG_ColourType_True :
  3221.         {
  3222.             switch(IHDR->BitDepth)
  3223.             {
  3224.                 case PNG_BitDepth_8  :
  3225.                 case PNG_BitDepth_16 :
  3226.                 {
  3227.                     BytesPerPixel    = (IHDR->BitDepth / 8) * PNG_NumColourComponents_True;
  3228.                     PixelsPerByte    = 1;
  3229.  
  3230.                     break;
  3231.                 }
  3232.      
  3233.                 default :
  3234.                 {
  3235.                     return(qfalse);
  3236.                 }
  3237.             }
  3238.  
  3239.             break;
  3240.         }
  3241.  
  3242.         case PNG_ColourType_Indexed :
  3243.         {
  3244.             switch(IHDR->BitDepth)
  3245.             {
  3246.                 case PNG_BitDepth_1 :
  3247.                 case PNG_BitDepth_2 :
  3248.                 case PNG_BitDepth_4 :
  3249.                 {
  3250.                     BytesPerPixel    = 1;
  3251.                     PixelsPerByte    = 8 / IHDR->BitDepth;
  3252.  
  3253.                     break;
  3254.                 }
  3255.  
  3256.                 case PNG_BitDepth_8 :
  3257.                 {
  3258.                     BytesPerPixel    = PNG_NumColourComponents_Indexed;
  3259.                     PixelsPerByte    = 1;
  3260.  
  3261.                     break;
  3262.                 }
  3263.          
  3264.                 default :
  3265.                 {
  3266.                     return(qfalse);
  3267.                 }
  3268.             }
  3269.  
  3270.             break;
  3271.         }
  3272.  
  3273.         case PNG_ColourType_GreyAlpha :
  3274.         {
  3275.             switch(IHDR->BitDepth)
  3276.             {
  3277.                 case PNG_BitDepth_8 :
  3278.                 case PNG_BitDepth_16 :
  3279.                 {
  3280.                     BytesPerPixel    = (IHDR->BitDepth / 8) * PNG_NumColourComponents_GreyAlpha;
  3281.                     PixelsPerByte    = 1;
  3282.  
  3283.                     break;
  3284.                 }
  3285.      
  3286.                 default :
  3287.                 {
  3288.                     return(qfalse);
  3289.                 }
  3290.             }
  3291.  
  3292.             break;
  3293.         }
  3294.  
  3295.         case PNG_ColourType_TrueAlpha :
  3296.         {
  3297.             switch(IHDR->BitDepth)
  3298.             {
  3299.                 case PNG_BitDepth_8 :
  3300.                 case PNG_BitDepth_16 :
  3301.                 {
  3302.                     BytesPerPixel    = (IHDR->BitDepth / 8) * PNG_NumColourComponents_TrueAlpha;
  3303.                     PixelsPerByte    = 1;
  3304.  
  3305.                     break;
  3306.                 }
  3307.    
  3308.                 default :
  3309.                 {
  3310.                     return(qfalse);
  3311.                 }
  3312.             }
  3313.  
  3314.             break;
  3315.         }
  3316.  
  3317.         default :
  3318.         {
  3319.             return(qfalse);
  3320.         }
  3321.     }
  3322.  
  3323.     /*
  3324.      *  Calculate the size of one scanline
  3325.      */
  3326.  
  3327.     BytesPerScanline = (IHDR_Width * BytesPerPixel + (PixelsPerByte - 1)) / PixelsPerByte;
  3328.  
  3329.     /*
  3330.      *  Check if we have enough data for the whole image.
  3331.      */
  3332.  
  3333.     if(!(DecompressedDataLength == ((BytesPerScanline + 1) * IHDR_Height)))
  3334.     {
  3335.         return(qfalse);
  3336.     }
  3337.  
  3338.     /*
  3339.      *  Unfilter the image.
  3340.      */
  3341.  
  3342.     if(!UnfilterImage(DecompressedData, IHDR_Height, BytesPerScanline, BytesPerPixel))
  3343.     {
  3344.         return(qfalse);
  3345.     }
  3346.  
  3347.     /*
  3348.      *  Set the working pointers to the beginning of the buffers.
  3349.      */
  3350.  
  3351.     OutPtr = OutBuffer;
  3352.     DecompPtr = DecompressedData;
  3353.  
  3354.     /*
  3355.      *  Create the output image.
  3356.      */
  3357.  
  3358.     for(h = 0; h < IHDR_Height; h++)
  3359.     {
  3360.         /*
  3361.          *  Count the pixels on the scanline for those multipixel bytes
  3362.          */
  3363.  
  3364.         uint32_t CurrPixel;
  3365.  
  3366.         /*
  3367.          *  skip FilterType
  3368.          */
  3369.  
  3370.         DecompPtr++;
  3371.  
  3372.         /*
  3373.          *  Reset the pixel count.
  3374.          */
  3375.  
  3376.         CurrPixel = 0;
  3377.  
  3378.         for(w = 0; w < (BytesPerScanline / BytesPerPixel); w++)
  3379.         {
  3380.         if(PixelsPerByte > 1)
  3381.         {
  3382.                 uint8_t  Mask;
  3383.                 uint32_t Shift;
  3384.         uint8_t  SinglePixel;
  3385.  
  3386.                 for(p = 0; p < PixelsPerByte; p++)
  3387.                 {
  3388.                     if(CurrPixel < IHDR_Width)
  3389.                     {
  3390.                         Mask  = (1 << IHDR->BitDepth) - 1;
  3391.                         Shift = (PixelsPerByte - 1 - p) * IHDR->BitDepth;
  3392.  
  3393.                         SinglePixel = ((DecompPtr[0] & (Mask << Shift)) >> Shift);
  3394.  
  3395.             if(!ConvertPixel(IHDR, OutPtr, &SinglePixel, HasTransparentColour, TransparentColour, OutPal))
  3396.             {
  3397.                 return(qfalse);
  3398.             }
  3399.  
  3400.                         OutPtr += Q3IMAGE_BYTESPERPIXEL;
  3401.                         CurrPixel++;
  3402.                     }
  3403.                 }
  3404.        
  3405.         }
  3406.         else
  3407.         {
  3408.         if(!ConvertPixel(IHDR, OutPtr, DecompPtr, HasTransparentColour, TransparentColour, OutPal))
  3409.         {
  3410.             return(qfalse);
  3411.         }
  3412.  
  3413.  
  3414.                 OutPtr += Q3IMAGE_BYTESPERPIXEL;
  3415.         }
  3416.  
  3417.             DecompPtr += BytesPerPixel;
  3418.         }
  3419.     }
  3420.  
  3421.     return(qtrue);
  3422. }
  3423.  
  3424. /*
  3425.  *  Decode an interlaced image.
  3426.  */
  3427.  
  3428. static qboolean DecodeImageInterlaced(struct PNG_Chunk_IHDR *IHDR,
  3429.                                       byte                  *OutBuffer,
  3430.                                       uint8_t               *DecompressedData,
  3431.                                       uint32_t               DecompressedDataLength,
  3432.                                       qboolean               HasTransparentColour,
  3433.                                       uint8_t               *TransparentColour,
  3434.                                       uint8_t               *OutPal)
  3435. {
  3436.     uint32_t IHDR_Width;
  3437.     uint32_t IHDR_Height;
  3438.     uint32_t BytesPerScanline[PNG_Adam7_NumPasses], BytesPerPixel, PixelsPerByte;
  3439.     uint32_t PassWidth[PNG_Adam7_NumPasses], PassHeight[PNG_Adam7_NumPasses];
  3440.     uint32_t WSkip[PNG_Adam7_NumPasses], WOffset[PNG_Adam7_NumPasses], HSkip[PNG_Adam7_NumPasses], HOffset[PNG_Adam7_NumPasses];
  3441.     uint32_t w, h, p, a;
  3442.     byte *OutPtr;
  3443.     uint8_t *DecompPtr;
  3444.     uint32_t TargetLength;
  3445.  
  3446.     /*
  3447.      *  input verification
  3448.      */
  3449.  
  3450.     if(!(IHDR && OutBuffer && DecompressedData && DecompressedDataLength && TransparentColour && OutPal))
  3451.     {
  3452.     return(qfalse);
  3453.     }
  3454.  
  3455.     /*
  3456.      *  byte swapping
  3457.      */
  3458.  
  3459.     IHDR_Width  = BigLong(IHDR->Width);
  3460.     IHDR_Height = BigLong(IHDR->Height);
  3461.  
  3462.     /*
  3463.      *  Skip and Offset for the passes.
  3464.      */
  3465.  
  3466.     WSkip[0]   = 8;
  3467.     WOffset[0] = 0;
  3468.     HSkip[0]   = 8;
  3469.     HOffset[0] = 0;
  3470.  
  3471.     WSkip[1]   = 8;
  3472.     WOffset[1] = 4;
  3473.     HSkip[1]   = 8;
  3474.     HOffset[1] = 0;
  3475.  
  3476.     WSkip[2]   = 4;
  3477.     WOffset[2] = 0;
  3478.     HSkip[2]   = 8;
  3479.     HOffset[2] = 4;
  3480.  
  3481.     WSkip[3]   = 4;
  3482.     WOffset[3] = 2;
  3483.     HSkip[3]   = 4;
  3484.     HOffset[3] = 0;
  3485.  
  3486.     WSkip[4]   = 2;
  3487.     WOffset[4] = 0;
  3488.     HSkip[4]   = 4;
  3489.     HOffset[4] = 2;
  3490.  
  3491.     WSkip[5]   = 2;
  3492.     WOffset[5] = 1;
  3493.     HSkip[5]   = 2;
  3494.     HOffset[5] = 0;
  3495.  
  3496.     WSkip[6]   = 1;
  3497.     WOffset[6] = 0;
  3498.     HSkip[6]   = 2;
  3499.     HOffset[6] = 1;
  3500.  
  3501.     /*
  3502.      *  Calculate the sizes of the passes.
  3503.      */
  3504.  
  3505.     PassWidth[0]  = (IHDR_Width  + 7) / 8;
  3506.     PassHeight[0] = (IHDR_Height + 7) / 8;
  3507.  
  3508.     PassWidth[1]  = (IHDR_Width  + 3) / 8;
  3509.     PassHeight[1] = (IHDR_Height + 7) / 8;
  3510.  
  3511.     PassWidth[2]  = (IHDR_Width  + 3) / 4;
  3512.     PassHeight[2] = (IHDR_Height + 3) / 8;
  3513.  
  3514.     PassWidth[3]  = (IHDR_Width  + 1) / 4;
  3515.     PassHeight[3] = (IHDR_Height + 3) / 4;
  3516.  
  3517.     PassWidth[4]  = (IHDR_Width  + 1) / 2;
  3518.     PassHeight[4] = (IHDR_Height + 1) / 4;
  3519.  
  3520.     PassWidth[5]  = (IHDR_Width  + 0) / 2;
  3521.     PassHeight[5] = (IHDR_Height + 1) / 2;
  3522.  
  3523.     PassWidth[6]  = (IHDR_Width  + 0) / 1;
  3524.     PassHeight[6] = (IHDR_Height + 0) / 2;
  3525.  
  3526.     /*
  3527.      *  information for un-filtering
  3528.      */
  3529.  
  3530.     switch(IHDR->ColourType)
  3531.     {
  3532.         case PNG_ColourType_Grey :
  3533.         {
  3534.             switch(IHDR->BitDepth)
  3535.             {
  3536.                 case PNG_BitDepth_1 :
  3537.                 case PNG_BitDepth_2 :
  3538.                 case PNG_BitDepth_4 :
  3539.                 {
  3540.                     BytesPerPixel    = 1;
  3541.                     PixelsPerByte    = 8 / IHDR->BitDepth;
  3542.  
  3543.                     break;
  3544.                 }
  3545.  
  3546.                 case PNG_BitDepth_8  :
  3547.                 case PNG_BitDepth_16 :
  3548.                 {
  3549.                     BytesPerPixel    = (IHDR->BitDepth / 8) * PNG_NumColourComponents_Grey;
  3550.                     PixelsPerByte    = 1;
  3551.  
  3552.                     break;
  3553.                 }
  3554.  
  3555.                 default :
  3556.                 {
  3557.                     return(qfalse);
  3558.                 }
  3559.             }
  3560.  
  3561.             break;
  3562.         }
  3563.  
  3564.         case PNG_ColourType_True :
  3565.         {
  3566.             switch(IHDR->BitDepth)
  3567.             {
  3568.                 case PNG_BitDepth_8  :
  3569.                 case PNG_BitDepth_16 :
  3570.                 {
  3571.                     BytesPerPixel    = (IHDR->BitDepth / 8) * PNG_NumColourComponents_True;
  3572.                     PixelsPerByte    = 1;
  3573.  
  3574.                     break;
  3575.                 }
  3576.      
  3577.                 default :
  3578.                 {
  3579.                     return(qfalse);
  3580.                 }
  3581.             }
  3582.  
  3583.             break;
  3584.         }
  3585.  
  3586.         case PNG_ColourType_Indexed :
  3587.         {
  3588.             switch(IHDR->BitDepth)
  3589.             {
  3590.                 case PNG_BitDepth_1 :
  3591.                 case PNG_BitDepth_2 :
  3592.                 case PNG_BitDepth_4 :
  3593.                 {
  3594.                     BytesPerPixel    = 1;
  3595.                     PixelsPerByte    = 8 / IHDR->BitDepth;
  3596.  
  3597.                     break;
  3598.                 }
  3599.  
  3600.                 case PNG_BitDepth_8 :
  3601.                 {
  3602.                     BytesPerPixel    = PNG_NumColourComponents_Indexed;
  3603.                     PixelsPerByte    = 1;
  3604.  
  3605.                     break;
  3606.                 }
  3607.          
  3608.                 default :
  3609.                 {
  3610.                     return(qfalse);
  3611.                 }
  3612.             }
  3613.  
  3614.             break;
  3615.         }
  3616.  
  3617.         case PNG_ColourType_GreyAlpha :
  3618.         {
  3619.             switch(IHDR->BitDepth)
  3620.             {
  3621.                 case PNG_BitDepth_8 :
  3622.                 case PNG_BitDepth_16 :
  3623.                 {
  3624.                     BytesPerPixel    = (IHDR->BitDepth / 8) * PNG_NumColourComponents_GreyAlpha;
  3625.                     PixelsPerByte    = 1;
  3626.  
  3627.                     break;
  3628.                 }
  3629.      
  3630.                 default :
  3631.                 {
  3632.                     return(qfalse);
  3633.                 }
  3634.             }
  3635.  
  3636.             break;
  3637.         }
  3638.  
  3639.         case PNG_ColourType_TrueAlpha :
  3640.         {
  3641.             switch(IHDR->BitDepth)
  3642.             {
  3643.                 case PNG_BitDepth_8 :
  3644.                 case PNG_BitDepth_16 :
  3645.                 {
  3646.                     BytesPerPixel    = (IHDR->BitDepth / 8) * PNG_NumColourComponents_TrueAlpha;
  3647.                     PixelsPerByte    = 1;
  3648.  
  3649.                     break;
  3650.                 }
  3651.    
  3652.                 default :
  3653.                 {
  3654.                     return(qfalse);
  3655.                 }
  3656.             }
  3657.  
  3658.             break;
  3659.         }
  3660.  
  3661.         default :
  3662.         {
  3663.             return(qfalse);
  3664.         }
  3665.     }
  3666.  
  3667.     /*
  3668.      *  Calculate the size of the scanlines per pass
  3669.      */
  3670.  
  3671.     for(a = 0; a < PNG_Adam7_NumPasses; a++)
  3672.     {
  3673.     BytesPerScanline[a] = (PassWidth[a] * BytesPerPixel + (PixelsPerByte - 1)) / PixelsPerByte;
  3674.     }
  3675.  
  3676.     /*
  3677.      *  Calculate the size of all passes
  3678.      */
  3679.  
  3680.     TargetLength = 0;
  3681.  
  3682.     for(a = 0; a < PNG_Adam7_NumPasses; a++)
  3683.     {
  3684.     TargetLength += ((BytesPerScanline[a] + (BytesPerScanline[a] ? 1 : 0)) * PassHeight[a]);
  3685.     }
  3686.  
  3687.     /*
  3688.      *  Check if we have enough data for the whole image.
  3689.      */
  3690.  
  3691.     if(!(DecompressedDataLength == TargetLength))
  3692.     {
  3693.         return(qfalse);
  3694.     }
  3695.  
  3696.     /*
  3697.      *  Unfilter the image.
  3698.      */
  3699.  
  3700.     DecompPtr = DecompressedData;
  3701.  
  3702.     for(a = 0; a < PNG_Adam7_NumPasses; a++)
  3703.     {
  3704.         if(!UnfilterImage(DecompPtr, PassHeight[a], BytesPerScanline[a], BytesPerPixel))
  3705.         {
  3706.             return(qfalse);
  3707.         }
  3708.    
  3709.     DecompPtr += ((BytesPerScanline[a] + (BytesPerScanline[a] ? 1 : 0)) * PassHeight[a]);
  3710.     }
  3711.  
  3712.     /*
  3713.      *  Set the working pointers to the beginning of the buffers.
  3714.      */
  3715.  
  3716.     DecompPtr = DecompressedData;
  3717.  
  3718.     /*
  3719.      *  Create the output image.
  3720.      */
  3721.  
  3722.     for(a = 0; a < PNG_Adam7_NumPasses; a++)
  3723.     {
  3724.         for(h = 0; h < PassHeight[a]; h++)
  3725.         {
  3726.             /*
  3727.              *  Count the pixels on the scanline for those multipixel bytes
  3728.              */
  3729.  
  3730.             uint32_t CurrPixel;
  3731.  
  3732.             /*
  3733.              *  skip FilterType
  3734.              */
  3735.  
  3736.             DecompPtr++;
  3737.  
  3738.             /*
  3739.              *  Reset the pixel count.
  3740.              */
  3741.  
  3742.             CurrPixel = 0;
  3743.  
  3744.             for(w = 0; w < (BytesPerScanline[a] / BytesPerPixel); w++)
  3745.             {
  3746.             if(PixelsPerByte > 1)
  3747.             {
  3748.                     uint8_t  Mask;
  3749.                     uint32_t Shift;
  3750.             uint8_t  SinglePixel;
  3751.  
  3752.                     for(p = 0; p < PixelsPerByte; p++)
  3753.                     {
  3754.                         if(CurrPixel < PassWidth[a])
  3755.                         {
  3756.                             Mask  = (1 << IHDR->BitDepth) - 1;
  3757.                             Shift = (PixelsPerByte - 1 - p) * IHDR->BitDepth;
  3758.  
  3759.                             SinglePixel = ((DecompPtr[0] & (Mask << Shift)) >> Shift);
  3760.  
  3761.                     OutPtr = OutBuffer + (((((h * HSkip[a]) + HOffset[a]) * IHDR_Width) + ((CurrPixel * WSkip[a]) + WOffset[a])) * Q3IMAGE_BYTESPERPIXEL);
  3762.  
  3763.                     if(!ConvertPixel(IHDR, OutPtr, &SinglePixel, HasTransparentColour, TransparentColour, OutPal))
  3764.                 {
  3765.                     return(qfalse);
  3766.                 }
  3767.  
  3768.                             CurrPixel++;
  3769.                         }
  3770.                     }
  3771.        
  3772.             }
  3773.                 else
  3774.             {
  3775.                 OutPtr = OutBuffer + (((((h * HSkip[a]) + HOffset[a]) * IHDR_Width) + ((w * WSkip[a]) + WOffset[a])) * Q3IMAGE_BYTESPERPIXEL);
  3776.  
  3777.             if(!ConvertPixel(IHDR, OutPtr, DecompPtr, HasTransparentColour, TransparentColour, OutPal))
  3778.             {
  3779.                 return(qfalse);
  3780.             }
  3781.             }
  3782.  
  3783.                 DecompPtr += BytesPerPixel;
  3784.             }
  3785.         }
  3786.     }
  3787.  
  3788.     return(qtrue);
  3789. }
  3790.  
  3791. /*
  3792.  *  The PNG loader
  3793.  */
  3794.  
  3795. static void LoadPNG(const char *name, byte **pic, int *width, int *height)
  3796. {
  3797.     struct BufferedFile *ThePNG;
  3798.     byte *OutBuffer;
  3799.     uint8_t *Signature;
  3800.     struct PNG_ChunkHeader *CH;
  3801.     uint32_t ChunkHeaderLength;
  3802.     uint32_t ChunkHeaderType;
  3803.     struct PNG_Chunk_IHDR *IHDR;
  3804.     uint32_t IHDR_Width;
  3805.     uint32_t IHDR_Height;
  3806.     PNG_ChunkCRC *CRC;
  3807.     uint8_t *InPal;
  3808.     uint8_t *DecompressedData;
  3809.     uint32_t DecompressedDataLength;
  3810.     uint32_t i;
  3811.  
  3812.     /*
  3813.      *  palette with 256 RGBA entries
  3814.      */
  3815.  
  3816.     uint8_t OutPal[1024];
  3817.  
  3818.     /*
  3819.      *  transparent colour from the tRNS chunk
  3820.      */
  3821.  
  3822.     qboolean HasTransparentColour = qfalse;
  3823.     uint8_t TransparentColour[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
  3824.  
  3825.     /*
  3826.      *  input verification
  3827.      */
  3828.  
  3829.     if(!(name && pic))
  3830.     {
  3831.         return;
  3832.     }
  3833.  
  3834.     /*
  3835.      *  Zero out return values.
  3836.      */
  3837.  
  3838.     *pic = NULL;
  3839.  
  3840.     if(width)
  3841.     {
  3842.         *width = 0;
  3843.     }
  3844.  
  3845.     if(height)
  3846.     {
  3847.         *height = 0;
  3848.     }
  3849.  
  3850.     /*
  3851.      *  Read the file.
  3852.      */
  3853.  
  3854.     ThePNG = ReadBufferedFile(name);
  3855.     if(!ThePNG)
  3856.     {
  3857.         return;
  3858.     }          
  3859.  
  3860.     /*
  3861.      *  Read the siganture of the file.
  3862.      */
  3863.  
  3864.     Signature = BufferedFileRead(ThePNG, PNG_Signature_Size);
  3865.     if(!Signature)
  3866.     {
  3867.         CloseBufferedFile(ThePNG);
  3868.  
  3869.         return;
  3870.     }
  3871.  
  3872.     /*
  3873.      *  Is it a PNG?
  3874.      */
  3875.  
  3876.     if(memcmp(Signature, PNG_Signature, PNG_Signature_Size))
  3877.     {
  3878.         CloseBufferedFile(ThePNG);
  3879.  
  3880.         return;
  3881.     }
  3882.  
  3883.     /*
  3884.      *  Read the first chunk-header.
  3885.      */
  3886.  
  3887.     CH = BufferedFileRead(ThePNG, PNG_ChunkHeader_Size);
  3888.     if(!CH)
  3889.     {
  3890.         CloseBufferedFile(ThePNG);
  3891.  
  3892.         return;
  3893.     }
  3894.  
  3895.     /*
  3896.      *  PNG multi-byte types are in Big Endian
  3897.      */
  3898.  
  3899.     ChunkHeaderLength = BigLong(CH->Length);
  3900.     ChunkHeaderType   = BigLong(CH->Type);
  3901.  
  3902.     /*
  3903.      *  Check if the first chunk is an IHDR.
  3904.      */
  3905.  
  3906.     if(!((ChunkHeaderType == PNG_ChunkType_IHDR) && (ChunkHeaderLength == PNG_Chunk_IHDR_Size)))
  3907.     {
  3908.         CloseBufferedFile(ThePNG);
  3909.  
  3910.         return;
  3911.     }
  3912.  
  3913.     /*
  3914.      *  Read the IHDR.
  3915.      */
  3916.  
  3917.     IHDR = BufferedFileRead(ThePNG, PNG_Chunk_IHDR_Size);
  3918.     if(!IHDR)
  3919.     {
  3920.         CloseBufferedFile(ThePNG);
  3921.  
  3922.         return;
  3923.     }
  3924.  
  3925.     /*
  3926.      *  Read the CRC for IHDR
  3927.      */
  3928.  
  3929.     CRC = BufferedFileRead(ThePNG, PNG_ChunkCRC_Size);
  3930.     if(!CRC)
  3931.     {
  3932.         CloseBufferedFile(ThePNG);
  3933.  
  3934.         return;
  3935.     }
  3936.  
  3937.     /*
  3938.      *  Here we could check the CRC if we wanted to.
  3939.      */
  3940.  
  3941.     /*
  3942.      *  multi-byte type swapping
  3943.      */
  3944.  
  3945.     IHDR_Width  = BigLong(IHDR->Width);
  3946.     IHDR_Height = BigLong(IHDR->Height);
  3947.  
  3948.     /*
  3949.      *  Check if Width and Height are valid.
  3950.      */
  3951.  
  3952.     if(!((IHDR_Width > 0) && (IHDR_Height > 0)))
  3953.     {
  3954.         CloseBufferedFile(ThePNG);
  3955.  
  3956.         return;
  3957.     }
  3958.  
  3959.     /*
  3960.      *  Do we need to check if the dimensions of the image are valid for Quake3?
  3961.      */
  3962.  
  3963.     /*
  3964.      *  Check if CompressionMethod and FilterMethod are valid.
  3965.      */
  3966.  
  3967.     if(!((IHDR->CompressionMethod == PNG_CompressionMethod_0) && (IHDR->FilterMethod == PNG_FilterMethod_0)))
  3968.     {
  3969.         CloseBufferedFile(ThePNG);
  3970.  
  3971.         return;
  3972.     }
  3973.  
  3974.     /*
  3975.      *  Check if InterlaceMethod is valid.
  3976.      */
  3977.  
  3978.     if(!((IHDR->InterlaceMethod == PNG_InterlaceMethod_NonInterlaced)  || (IHDR->InterlaceMethod == PNG_InterlaceMethod_Interlaced)))
  3979.     {
  3980.         CloseBufferedFile(ThePNG);
  3981.  
  3982.         return;
  3983.     }
  3984.  
  3985.     /*
  3986.      *  Read palette for an indexed image.
  3987.      */
  3988.  
  3989.     if(IHDR->ColourType == PNG_ColourType_Indexed)
  3990.     {
  3991.         /*
  3992.          *  We need the palette first.
  3993.          */
  3994.  
  3995.         if(!FindChunk(ThePNG, PNG_ChunkType_PLTE))
  3996.         {
  3997.             CloseBufferedFile(ThePNG);
  3998.  
  3999.             return;
  4000.         }
  4001.  
  4002.         /*
  4003.          *  Read the chunk-header.
  4004.          */
  4005.  
  4006.         CH = BufferedFileRead(ThePNG, PNG_ChunkHeader_Size);
  4007.         if(!CH)
  4008.         {
  4009.             CloseBufferedFile(ThePNG);
  4010.    
  4011.             return;
  4012.         }
  4013.  
  4014.         /*
  4015.          *  PNG multi-byte types are in Big Endian
  4016.          */
  4017.  
  4018.         ChunkHeaderLength = BigLong(CH->Length);
  4019.         ChunkHeaderType   = BigLong(CH->Type);
  4020.  
  4021.         /*
  4022.          *  Check if the chunk is an PLTE.
  4023.          */
  4024.  
  4025.         if(!(ChunkHeaderType == PNG_ChunkType_PLTE))
  4026.         {
  4027.             CloseBufferedFile(ThePNG);
  4028.    
  4029.             return;
  4030.         }
  4031.  
  4032.         /*
  4033.          *  Check if Length is divisible by 3
  4034.          */
  4035.  
  4036.         if(ChunkHeaderLength % 3)
  4037.         {
  4038.             CloseBufferedFile(ThePNG);
  4039.    
  4040.             return;  
  4041.         }
  4042.  
  4043.         /*
  4044.          *  Read the raw palette data
  4045.          */
  4046.  
  4047.         InPal = BufferedFileRead(ThePNG, ChunkHeaderLength);
  4048.         if(!InPal)
  4049.         {
  4050.             CloseBufferedFile(ThePNG);
  4051.    
  4052.             return;
  4053.         }
  4054.    
  4055.         /*
  4056.          *  Read the CRC for the palette
  4057.          */
  4058.  
  4059.         CRC = BufferedFileRead(ThePNG, PNG_ChunkCRC_Size);
  4060.         if(!CRC)
  4061.         {
  4062.             CloseBufferedFile(ThePNG);
  4063.  
  4064.             return;
  4065.         }
  4066.  
  4067.         /*
  4068.          *  Set some default values.
  4069.          */
  4070.  
  4071.         for(i = 0; i < 256; i++)
  4072.         {
  4073.             OutPal[i * Q3IMAGE_BYTESPERPIXEL + 0] = 0x00;
  4074.             OutPal[i * Q3IMAGE_BYTESPERPIXEL + 1] = 0x00;
  4075.             OutPal[i * Q3IMAGE_BYTESPERPIXEL + 2] = 0x00;
  4076.             OutPal[i * Q3IMAGE_BYTESPERPIXEL + 3] = 0xFF;  
  4077.         }
  4078.  
  4079.         /*
  4080.          *  Convert to the Quake3 RGBA-format.
  4081.          */
  4082.  
  4083.         for(i = 0; i < (ChunkHeaderLength / 3); i++)
  4084.         {
  4085.             OutPal[i * Q3IMAGE_BYTESPERPIXEL + 0] = InPal[i*3+0];
  4086.             OutPal[i * Q3IMAGE_BYTESPERPIXEL + 1] = InPal[i*3+1];
  4087.             OutPal[i * Q3IMAGE_BYTESPERPIXEL + 2] = InPal[i*3+2];
  4088.             OutPal[i * Q3IMAGE_BYTESPERPIXEL + 3] = 0xFF;
  4089.         }
  4090.     }
  4091.  
  4092.     /*
  4093.      *  transparency information is sometimes stored in an tRNS chunk
  4094.      */
  4095.  
  4096.     /*
  4097.      *  Let's see if there is a tRNS chunk
  4098.      */
  4099.  
  4100.     if(FindChunk(ThePNG, PNG_ChunkType_tRNS))
  4101.     {
  4102.         uint8_t *Trans;
  4103.  
  4104.         /*
  4105.          *  Read the chunk-header.
  4106.          */
  4107.  
  4108.         CH = BufferedFileRead(ThePNG, PNG_ChunkHeader_Size);
  4109.         if(!CH)
  4110.         {
  4111.             CloseBufferedFile(ThePNG);
  4112.  
  4113.             return;
  4114.         }
  4115.  
  4116.         /*
  4117.          *  PNG multi-byte types are in Big Endian
  4118.          */
  4119.  
  4120.         ChunkHeaderLength = BigLong(CH->Length);
  4121.         ChunkHeaderType   = BigLong(CH->Type);
  4122.  
  4123.         /*
  4124.          *  Check if the chunk is an tRNS.
  4125.          */
  4126.  
  4127.         if(!(ChunkHeaderType == PNG_ChunkType_tRNS))
  4128.         {
  4129.             CloseBufferedFile(ThePNG);
  4130.  
  4131.             return;
  4132.         }
  4133.  
  4134.         /*
  4135.          *  Read the transparency information.
  4136.          */
  4137.  
  4138.         Trans = BufferedFileRead(ThePNG, ChunkHeaderLength);
  4139.         if(!Trans)
  4140.         {
  4141.             CloseBufferedFile(ThePNG);
  4142.  
  4143.             return;  
  4144.         }
  4145.  
  4146.         /*
  4147.          *  Read the CRC.
  4148.          */
  4149.  
  4150.         CRC = BufferedFileRead(ThePNG, PNG_ChunkCRC_Size);
  4151.         if(!CRC)
  4152.         {
  4153.             CloseBufferedFile(ThePNG);
  4154.  
  4155.             return;
  4156.         }
  4157.  
  4158.         /*
  4159.          *  Only for Grey, True and Indexed ColourType should tRNS exist.
  4160.          */
  4161.  
  4162.         switch(IHDR->ColourType)
  4163.         {
  4164.             case PNG_ColourType_Grey :
  4165.             {
  4166.                 if(!ChunkHeaderLength == 2)
  4167.                 {
  4168.                     CloseBufferedFile(ThePNG);
  4169.  
  4170.                     return;    
  4171.                 }
  4172.    
  4173.                 HasTransparentColour = qtrue;
  4174.    
  4175.         /*
  4176.          *  Grey can have one colour which is completely transparent.
  4177.          *  This colour is always stored in 16 bits.
  4178.          */
  4179.  
  4180.                 TransparentColour[0] = Trans[0];
  4181.                 TransparentColour[1] = Trans[1];
  4182.    
  4183.                 break;
  4184.             }
  4185.    
  4186.             case PNG_ColourType_True :
  4187.             {
  4188.                 if(!ChunkHeaderLength == 6)
  4189.                 {
  4190.                     CloseBufferedFile(ThePNG);
  4191.  
  4192.                     return;    
  4193.                 }
  4194.    
  4195.                 HasTransparentColour = qtrue;
  4196.  
  4197.         /*
  4198.          *  True can have one colour which is completely transparent.
  4199.          *  This colour is always stored in 16 bits.
  4200.          */
  4201.  
  4202.                 TransparentColour[0] = Trans[0];
  4203.                 TransparentColour[1] = Trans[1];
  4204.                 TransparentColour[2] = Trans[2];
  4205.                 TransparentColour[3] = Trans[3];
  4206.                 TransparentColour[4] = Trans[4];
  4207.                 TransparentColour[5] = Trans[5];
  4208.    
  4209.                 break;
  4210.             }
  4211.    
  4212.             case PNG_ColourType_Indexed :
  4213.             {
  4214.                 /*
  4215.          *  Maximum of 256 one byte transparency entries.
  4216.          */
  4217.        
  4218.         if(ChunkHeaderLength > 256)
  4219.                 {
  4220.                     CloseBufferedFile(ThePNG);
  4221.  
  4222.                     return;    
  4223.                 }
  4224.  
  4225.                 HasTransparentColour = qtrue;
  4226.  
  4227.                 /*
  4228.                  *  alpha values for palette entries
  4229.                  */
  4230.  
  4231.                 for(i = 0; i < ChunkHeaderLength; i++)
  4232.                 {
  4233.                     OutPal[i * Q3IMAGE_BYTESPERPIXEL + 3] = Trans[i];
  4234.                 }
  4235.  
  4236.                 break;
  4237.             }
  4238.  
  4239.             /*
  4240.              *  All other ColourTypes should not have tRNS chunks
  4241.              */
  4242.  
  4243.             default :
  4244.             {
  4245.                 CloseBufferedFile(ThePNG);
  4246.  
  4247.                 return;
  4248.             }
  4249.         }
  4250.     }
  4251.  
  4252.     /*
  4253.      *  Rewind to the start of the file.
  4254.      */
  4255.  
  4256.     if(!BufferedFileRewind(ThePNG, -1))
  4257.     {
  4258.         CloseBufferedFile(ThePNG);
  4259.  
  4260.         return;
  4261.     }
  4262.  
  4263.     /*
  4264.      *  Skip the signature
  4265.      */
  4266.  
  4267.     if(!BufferedFileSkip(ThePNG, PNG_Signature_Size))
  4268.     {
  4269.         CloseBufferedFile(ThePNG);
  4270.  
  4271.         return;
  4272.     }
  4273.  
  4274.     /*
  4275.      *  Decompress all IDAT chunks
  4276.      */
  4277.  
  4278.     DecompressedDataLength = DecompressIDATs(ThePNG, &DecompressedData);
  4279.     if(!(DecompressedDataLength && DecompressedData))
  4280.     {
  4281.         CloseBufferedFile(ThePNG);
  4282.  
  4283.         return;
  4284.     }
  4285.  
  4286.     /*
  4287.      *  Allocate output buffer.
  4288.      */
  4289.  
  4290.     OutBuffer = ri.Malloc(IHDR_Width * IHDR_Height * Q3IMAGE_BYTESPERPIXEL);
  4291.     if(!OutBuffer)
  4292.     {
  4293.         ri.Free(DecompressedData);
  4294.         CloseBufferedFile(ThePNG);
  4295.  
  4296.         return;  
  4297.     }
  4298.  
  4299.     /*
  4300.      *  Interlaced and Non-interlaced images need to be handled differently.
  4301.      */
  4302.  
  4303.     switch(IHDR->InterlaceMethod)
  4304.     {
  4305.     case PNG_InterlaceMethod_NonInterlaced :
  4306.     {
  4307.         if(!DecodeImageNonInterlaced(IHDR, OutBuffer, DecompressedData, DecompressedDataLength, HasTransparentColour, TransparentColour, OutPal))
  4308.         {
  4309.         ri.Free(OutBuffer);
  4310.             ri.Free(DecompressedData);
  4311.             CloseBufferedFile(ThePNG);
  4312.  
  4313.         return;
  4314.         }
  4315.    
  4316.         break;
  4317.     }
  4318.    
  4319.     case PNG_InterlaceMethod_Interlaced :
  4320.     {
  4321.         if(!DecodeImageInterlaced(IHDR, OutBuffer, DecompressedData, DecompressedDataLength, HasTransparentColour, TransparentColour, OutPal))
  4322.         {
  4323.         ri.Free(OutBuffer);
  4324.             ri.Free(DecompressedData);
  4325.             CloseBufferedFile(ThePNG);
  4326.  
  4327.         return;
  4328.         }
  4329.    
  4330.         break;
  4331.     }
  4332.    
  4333.     default :
  4334.     {
  4335.         ri.Free(OutBuffer);
  4336.             ri.Free(DecompressedData);
  4337.             CloseBufferedFile(ThePNG);
  4338.  
  4339.         return;
  4340.     }
  4341.     }
  4342.  
  4343.     /*
  4344.      *  update the pointer to the image data
  4345.      */
  4346.  
  4347.     *pic = OutBuffer;
  4348.  
  4349.     /*
  4350.      *  Fill width and height.
  4351.      */
  4352.  
  4353.     if(width)
  4354.     {
  4355.         *width = IHDR_Width;
  4356.     }
  4357.  
  4358.     if(height)
  4359.     {
  4360.         *height = IHDR_Height;
  4361.     }
  4362.  
  4363.     /*
  4364.      *  DecompressedData is not needed anymore.
  4365.      */
  4366.  
  4367.     ri.Free(DecompressedData);
  4368.  
  4369.     /*
  4370.      *  We have all data, so close the file.
  4371.      */
  4372.  
  4373.     CloseBufferedFile(ThePNG);
  4374. }
  4375.  
  4376. //===================================================================
  4377.  
  4378. typedef struct
  4379. {
  4380.     char *ext;
  4381.     void (*ImageLoader)( const char *, unsigned char **, int *, int * );
  4382. } imageExtToLoaderMap_t;
  4383.  
  4384. // Note that the ordering indicates the order of preference used
  4385. // when there are multiple images of different formats available
  4386. static imageExtToLoaderMap_t imageLoaders[ ] =
  4387. {
  4388.     { "tga",  LoadTGA },
  4389.     { "jpg",  LoadJPG },
  4390.     { "jpeg", LoadJPG },
  4391.     { "png",  LoadPNG },
  4392.     { "pcx",  LoadPCX32 },
  4393.     { "bmp",  LoadBMP }
  4394. };
  4395.  
  4396. static int numImageLoaders = sizeof( imageLoaders ) /
  4397.         sizeof( imageLoaders[ 0 ] );
  4398.  
  4399. /*
  4400. =================
  4401. R_LoadImage
  4402.  
  4403. Loads any of the supported image types into a cannonical
  4404. 32 bit format.
  4405. =================
  4406. */
  4407. void R_LoadImage( const char *name, byte **pic, int *width, int *height )
  4408. {
  4409.     qboolean orgNameFailed = qfalse;
  4410.     int i;
  4411.     char localName[ MAX_QPATH ];
  4412.     const char *ext;
  4413.  
  4414.     *pic = NULL;
  4415.     *width = 0;
  4416.     *height = 0;
  4417.  
  4418.     Q_strncpyz( localName, name, MAX_QPATH );
  4419.  
  4420.     ext = COM_GetExtension( localName );
  4421.  
  4422.     if( *ext )
  4423.     {
  4424.         // Look for the correct loader and use it
  4425.         for( i = 0; i < numImageLoaders; i++ )
  4426.         {
  4427.             if( !Q_stricmp( ext, imageLoaders[ i ].ext ) )
  4428.             {
  4429.                 // Load
  4430.                 imageLoaders[ i ].ImageLoader( localName, pic, width, height );
  4431.                 break;
  4432.             }
  4433.         }
  4434.  
  4435.         // A loader was found
  4436.         if( i < numImageLoaders )
  4437.         {
  4438.             if( *pic == NULL )
  4439.             {
  4440.                 // Loader failed, most likely because the file isn't there;
  4441.                 // try again without the extension
  4442.                 orgNameFailed = qtrue;
  4443.                 COM_StripExtension( name, localName, MAX_QPATH );
  4444.             }
  4445.             else
  4446.             {
  4447.                 // Something loaded
  4448.                 return;
  4449.             }
  4450.         }
  4451.     }
  4452.  
  4453.     // Try and find a suitable match using all
  4454.     // the image formats supported
  4455.     for( i = 0; i < numImageLoaders; i++ )
  4456.     {
  4457.         char *altName = va( "%s.%s", localName, imageLoaders[ i ].ext );
  4458.  
  4459.         // Load
  4460.         imageLoaders[ i ].ImageLoader( altName, pic, width, height );
  4461.  
  4462.         if( *pic )
  4463.         {
  4464.             if( orgNameFailed )
  4465.             {
  4466.                 ri.Printf( PRINT_DEVELOPER, "WARNING: %s not present, using %s instead\n",
  4467.                         name, altName );
  4468.             }
  4469.  
  4470.             break;
  4471.         }
  4472.     }
  4473. }
  4474.  
  4475.  
  4476. /*
  4477. ===============
  4478. R_FindImageFile
  4479.  
  4480. Finds or loads the given image.
  4481. Returns NULL if it fails, not a default image.
  4482. ==============
  4483. */
  4484. image_t *R_FindImageFile( const char *name, qboolean mipmap, qboolean allowPicmip, int glWrapClampMode ) {
  4485.     image_t *image;
  4486.     int     width, height;
  4487.     byte    *pic;
  4488.     long    hash;
  4489.  
  4490.     if (!name) {
  4491.         return NULL;
  4492.     }
  4493.  
  4494.     hash = generateHashValue(name);
  4495.  
  4496.     //
  4497.     // see if the image is already loaded
  4498.     //
  4499.     for (image=hashTable[hash]; image; image=image->next) {
  4500.         if ( !strcmp( name, image->imgName ) ) {
  4501.             // the white image can be used with any set of parms, but other mismatches are errors
  4502.             if ( strcmp( name, "*white" ) ) {
  4503.                 if ( image->mipmap != mipmap ) {
  4504.                     ri.Printf( PRINT_DEVELOPER, "WARNING: reused image %s with mixed mipmap parm\n", name );
  4505.                 }
  4506.                 if ( image->allowPicmip != allowPicmip ) {
  4507.                     ri.Printf( PRINT_DEVELOPER, "WARNING: reused image %s with mixed allowPicmip parm\n", name );
  4508.                 }
  4509.                 if ( image->wrapClampMode != glWrapClampMode ) {
  4510.                     ri.Printf( PRINT_ALL, "WARNING: reused image %s with mixed glWrapClampMode parm\n", name );
  4511.                 }
  4512.             }
  4513.             return image;
  4514.         }
  4515.     }
  4516.  
  4517.     //
  4518.     // load the pic from disk
  4519.     //
  4520.     R_LoadImage( name, &pic, &width, &height );
  4521.     if ( pic == NULL ) {
  4522.         return NULL;
  4523.     }
  4524.  
  4525.     image = R_CreateImage( ( char * ) name, pic, width, height, mipmap, allowPicmip, glWrapClampMode );
  4526.     ri.Free( pic );
  4527.     return image;
  4528. }
  4529.  
  4530.  
  4531. /*
  4532. ================
  4533. R_CreateDlightImage
  4534. ================
  4535. */
  4536. #define DLIGHT_SIZE 16
  4537. static void R_CreateDlightImage( void ) {
  4538.     int     x,y;
  4539.     byte    data[DLIGHT_SIZE][DLIGHT_SIZE][4];
  4540.     int     b;
  4541.  
  4542.     // make a centered inverse-square falloff blob for dynamic lighting
  4543.     for (x=0 ; x<DLIGHT_SIZE ; x++) {
  4544.         for (y=0 ; y<DLIGHT_SIZE ; y++) {
  4545.             float   d;
  4546.  
  4547.             d = ( DLIGHT_SIZE/2 - 0.5f - x ) * ( DLIGHT_SIZE/2 - 0.5f - x ) +
  4548.                 ( DLIGHT_SIZE/2 - 0.5f - y ) * ( DLIGHT_SIZE/2 - 0.5f - y );
  4549.             b = 4000 / d;
  4550.             if (b > 255) {
  4551.                 b = 255;
  4552.             } else if ( b < 75 ) {
  4553.                 b = 0;
  4554.             }
  4555.             data[y][x][0] =
  4556.             data[y][x][1] =
  4557.             data[y][x][2] = b;
  4558.             data[y][x][3] = 255;           
  4559.         }
  4560.     }
  4561.     tr.dlightImage = R_CreateImage("*dlight", (byte *)data, DLIGHT_SIZE, DLIGHT_SIZE, qfalse, qfalse, GL_CLAMP );
  4562. }
  4563.  
  4564.  
  4565. /*
  4566. =================
  4567. R_InitFogTable
  4568. =================
  4569. */
  4570. void R_InitFogTable( void ) {
  4571.     int     i;
  4572.     float   d;
  4573.     float   exp;
  4574.    
  4575.     exp = 0.5;
  4576.  
  4577.     for ( i = 0 ; i < FOG_TABLE_SIZE ; i++ ) {
  4578.         d = pow ( (float)i/(FOG_TABLE_SIZE-1), exp );
  4579.  
  4580.         tr.fogTable[i] = d;
  4581.     }
  4582. }
  4583.  
  4584. /*
  4585. ================
  4586. R_FogFactor
  4587.  
  4588. Returns a 0.0 to 1.0 fog density value
  4589. This is called for each texel of the fog texture on startup
  4590. and for each vertex of transparent shaders in fog dynamically
  4591. ================
  4592. */
  4593. float   R_FogFactor( float s, float t ) {
  4594.     float   d;
  4595.  
  4596.     s -= 1.0/512;
  4597.     if ( s < 0 ) {
  4598.         return 0;
  4599.     }
  4600.     if ( t < 1.0/32 ) {
  4601.         return 0;
  4602.     }
  4603.     if ( t < 31.0/32 ) {
  4604.         s *= (t - 1.0f/32.0f) / (30.0f/32.0f);
  4605.     }
  4606.  
  4607.     // we need to leave a lot of clamp range
  4608.     s *= 8;
  4609.  
  4610.     if ( s > 1.0 ) {
  4611.         s = 1.0;
  4612.     }
  4613.  
  4614.     d = tr.fogTable[ (int)(s * (FOG_TABLE_SIZE-1)) ];
  4615.  
  4616.     return d;
  4617. }
  4618.  
  4619. /*
  4620. ================
  4621. R_CreateFogImage
  4622. ================
  4623. */
  4624. #define FOG_S   256
  4625. #define FOG_T   32
  4626. static void R_CreateFogImage( void ) {
  4627.     int     x,y;
  4628.     byte    *data;
  4629.     float   g;
  4630.     float   d;
  4631.     float   borderColor[4];
  4632.  
  4633.     data = ri.Hunk_AllocateTempMemory( FOG_S * FOG_T * 4 );
  4634.  
  4635.     g = 2.0;
  4636.  
  4637.     // S is distance, T is depth
  4638.     for (x=0 ; x<FOG_S ; x++) {
  4639.         for (y=0 ; y<FOG_T ; y++) {
  4640.             d = R_FogFactor( ( x + 0.5f ) / FOG_S, ( y + 0.5f ) / FOG_T );
  4641.  
  4642.             data[(y*FOG_S+x)*4+0] =
  4643.             data[(y*FOG_S+x)*4+1] =
  4644.             data[(y*FOG_S+x)*4+2] = 255;
  4645.             data[(y*FOG_S+x)*4+3] = 255*d;
  4646.         }
  4647.     }
  4648.     // standard openGL clamping doesn't really do what we want -- it includes
  4649.     // the border color at the edges.  OpenGL 1.2 has clamp-to-edge, which does
  4650.     // what we want.
  4651.     tr.fogImage = R_CreateImage("*fog", (byte *)data, FOG_S, FOG_T, qfalse, qfalse, GL_CLAMP );
  4652.     ri.Hunk_FreeTempMemory( data );
  4653.  
  4654.     borderColor[0] = 1.0;
  4655.     borderColor[1] = 1.0;
  4656.     borderColor[2] = 1.0;
  4657.     borderColor[3] = 1;
  4658.  
  4659.     qglTexParameterfv( GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor );
  4660. }
  4661.  
  4662. /*
  4663. ==================
  4664. R_CreateDefaultImage
  4665. ==================
  4666. */
  4667. #define DEFAULT_SIZE    16
  4668. static void R_CreateDefaultImage( void ) {
  4669.     int     x;
  4670.     byte    data[DEFAULT_SIZE][DEFAULT_SIZE][4];
  4671.  
  4672.     // the default image will be a box, to allow you to see the mapping coordinates
  4673.     Com_Memset( data, 32, sizeof( data ) );
  4674.     for ( x = 0 ; x < DEFAULT_SIZE ; x++ ) {
  4675.         data[0][x][0] =
  4676.         data[0][x][1] =
  4677.         data[0][x][2] =
  4678.         data[0][x][3] = 255;
  4679.  
  4680.         data[x][0][0] =
  4681.         data[x][0][1] =
  4682.         data[x][0][2] =
  4683.         data[x][0][3] = 255;
  4684.  
  4685.         data[DEFAULT_SIZE-1][x][0] =
  4686.         data[DEFAULT_SIZE-1][x][1] =
  4687.         data[DEFAULT_SIZE-1][x][2] =
  4688.         data[DEFAULT_SIZE-1][x][3] = 255;
  4689.  
  4690.         data[x][DEFAULT_SIZE-1][0] =
  4691.         data[x][DEFAULT_SIZE-1][1] =
  4692.         data[x][DEFAULT_SIZE-1][2] =
  4693.         data[x][DEFAULT_SIZE-1][3] = 255;
  4694.     }
  4695.     tr.defaultImage = R_CreateImage("*default", (byte *)data, DEFAULT_SIZE, DEFAULT_SIZE, qtrue, qfalse, GL_REPEAT );
  4696. }
  4697.  
  4698. /*
  4699. ==================
  4700. R_CreateBuiltinImages
  4701. ==================
  4702. */
  4703. void R_CreateBuiltinImages( void ) {
  4704.     int     x,y;
  4705.     byte    data[DEFAULT_SIZE][DEFAULT_SIZE][4];
  4706.  
  4707.     R_CreateDefaultImage();
  4708.  
  4709.     // we use a solid white image instead of disabling texturing
  4710.     Com_Memset( data, 255, sizeof( data ) );
  4711.     tr.whiteImage = R_CreateImage("*white", (byte *)data, 8, 8, qfalse, qfalse, GL_REPEAT );
  4712.  
  4713.     // with overbright bits active, we need an image which is some fraction of full color,
  4714.     // for default lightmaps, etc
  4715.     for (x=0 ; x<DEFAULT_SIZE ; x++) {
  4716.         for (y=0 ; y<DEFAULT_SIZE ; y++) {
  4717.             data[y][x][0] =
  4718.             data[y][x][1] =
  4719.             data[y][x][2] = tr.identityLightByte;
  4720.             data[y][x][3] = 255;           
  4721.         }
  4722.     }
  4723.  
  4724.     tr.identityLightImage = R_CreateImage("*identityLight", (byte *)data, 8, 8, qfalse, qfalse, GL_REPEAT );
  4725.  
  4726.  
  4727.     for(x=0;x<32;x++) {
  4728.         // scratchimage is usually used for cinematic drawing
  4729.         tr.scratchImage[x] = R_CreateImage("*scratch", (byte *)data, DEFAULT_SIZE, DEFAULT_SIZE, qfalse, qtrue, GL_CLAMP );
  4730.     }
  4731.  
  4732.     R_CreateDlightImage();
  4733.     R_CreateFogImage();
  4734. }
  4735.  
  4736.  
  4737. /*
  4738. ===============
  4739. R_SetColorMappings
  4740. ===============
  4741. */
  4742. void R_SetColorMappings( void ) {
  4743.     int     i, j;
  4744.     float   g;
  4745.     int     inf;
  4746.     int     shift;
  4747.  
  4748.     // setup the overbright lighting
  4749.     tr.overbrightBits = r_overBrightBits->integer;
  4750.     if ( !glConfig.deviceSupportsGamma ) {
  4751.         tr.overbrightBits = 0;      // need hardware gamma for overbright
  4752.     }
  4753.  
  4754.     // never overbright in windowed mode
  4755.     if ( !glConfig.isFullscreen )
  4756.     {
  4757.         tr.overbrightBits = 0;
  4758.     }
  4759.  
  4760.     // allow 2 overbright bits in 24 bit, but only 1 in 16 bit
  4761.     if ( glConfig.colorBits > 16 ) {
  4762.         if ( tr.overbrightBits > 2 ) {
  4763.             tr.overbrightBits = 2;
  4764.         }
  4765.     } else {
  4766.         if ( tr.overbrightBits > 1 ) {
  4767.             tr.overbrightBits = 1;
  4768.         }
  4769.     }
  4770.     if ( tr.overbrightBits < 0 ) {
  4771.         tr.overbrightBits = 0;
  4772.     }
  4773.  
  4774.     tr.identityLight = 1.0f / ( 1 << tr.overbrightBits );
  4775.     tr.identityLightByte = 255 * tr.identityLight;
  4776.  
  4777.  
  4778.     if ( r_intensity->value <= 1 ) {
  4779.         ri.Cvar_Set( "r_intensity", "1" );
  4780.     }
  4781.  
  4782.     if ( r_gamma->value < 0.5f ) {
  4783.         ri.Cvar_Set( "r_gamma", "0.5" );
  4784.     } else if ( r_gamma->value > 3.0f ) {
  4785.         ri.Cvar_Set( "r_gamma", "3.0" );
  4786.     }
  4787.  
  4788.     g = r_gamma->value;
  4789.  
  4790.     shift = tr.overbrightBits;
  4791.  
  4792.     for ( i = 0; i < 256; i++ ) {
  4793.         if ( g == 1 ) {
  4794.             inf = i;
  4795.         } else {
  4796.             inf = 255 * pow ( i/255.0f, 1.0f / g ) + 0.5f;
  4797.         }
  4798.         inf <<= shift;
  4799.         if (inf < 0) {
  4800.             inf = 0;
  4801.         }
  4802.         if (inf > 255) {
  4803.             inf = 255;
  4804.         }
  4805.         s_gammatable[i] = inf;
  4806.     }
  4807.  
  4808.     for (i=0 ; i<256 ; i++) {
  4809.         j = i * r_intensity->value;
  4810.         if (j > 255) {
  4811.             j = 255;
  4812.         }
  4813.         s_intensitytable[i] = j;
  4814.     }
  4815.  
  4816.     if ( glConfig.deviceSupportsGamma )
  4817.     {
  4818.         GLimp_SetGamma( s_gammatable, s_gammatable, s_gammatable );
  4819.     }
  4820. }
  4821.  
  4822. /*
  4823. ===============
  4824. R_InitImages
  4825. ===============
  4826. */
  4827. void    R_InitImages( void ) {
  4828.     Com_Memset(hashTable, 0, sizeof(hashTable));
  4829.     // build brightness translation tables
  4830.     R_SetColorMappings();
  4831.  
  4832.     // create default texture and white texture
  4833.     R_CreateBuiltinImages();
  4834. }
  4835.  
  4836. /*
  4837. ===============
  4838. R_DeleteTextures
  4839. ===============
  4840. */
  4841. void R_DeleteTextures( void ) {
  4842.     int     i;
  4843.  
  4844.     for ( i=0; i<tr.numImages ; i++ ) {
  4845.         qglDeleteTextures( 1, &tr.images[i]->texnum );
  4846.     }
  4847.     Com_Memset( tr.images, 0, sizeof( tr.images ) );
  4848.  
  4849.     tr.numImages = 0;
  4850.  
  4851.     Com_Memset( glState.currenttextures, 0, sizeof( glState.currenttextures ) );
  4852.     if ( qglActiveTextureARB ) {
  4853.         GL_SelectTexture( 1 );
  4854.         qglBindTexture( GL_TEXTURE_2D, 0 );
  4855.         GL_SelectTexture( 0 );
  4856.         qglBindTexture( GL_TEXTURE_2D, 0 );
  4857.     } else {
  4858.         qglBindTexture( GL_TEXTURE_2D, 0 );
  4859.     }
  4860. }
  4861.  
  4862. /*
  4863. ============================================================================
  4864.  
  4865. SKINS
  4866.  
  4867. ============================================================================
  4868. */
  4869.  
  4870. /*
  4871. ==================
  4872. CommaParse
  4873.  
  4874. This is unfortunate, but the skin files aren't
  4875. compatable with our normal parsing rules.
  4876. ==================
  4877. */
  4878. static char *CommaParse( char **data_p ) {
  4879.     int c = 0, len;
  4880.     char *data;
  4881.     static  char    com_token[MAX_TOKEN_CHARS];
  4882.  
  4883.     data = *data_p;
  4884.     len = 0;
  4885.     com_token[0] = 0;
  4886.  
  4887.     // make sure incoming data is valid
  4888.     if ( !data ) {
  4889.         *data_p = NULL;
  4890.         return com_token;
  4891.     }
  4892.  
  4893.     while ( 1 ) {
  4894.         // skip whitespace
  4895.         while( (c = *data) <= ' ') {
  4896.             if( !c ) {
  4897.                 break;
  4898.             }
  4899.             data++;
  4900.         }
  4901.  
  4902.  
  4903.         c = *data;
  4904.  
  4905.         // skip double slash comments
  4906.         if ( c == '/' && data[1] == '/' )
  4907.         {
  4908.             while (*data && *data != '\n')
  4909.                 data++;
  4910.         }
  4911.         // skip /* */ comments
  4912.         else if ( c=='/' && data[1] == '*' )
  4913.         {
  4914.             while ( *data && ( *data != '*' || data[1] != '/' ) )
  4915.             {
  4916.                 data++;
  4917.             }
  4918.             if ( *data )
  4919.             {
  4920.                 data += 2;
  4921.             }
  4922.         }
  4923.         else
  4924.         {
  4925.             break;
  4926.         }
  4927.     }
  4928.  
  4929.     if ( c == 0 ) {
  4930.         return "";
  4931.     }
  4932.  
  4933.     // handle quoted strings
  4934.     if (c == '\"')
  4935.     {
  4936.         data++;
  4937.         while (1)
  4938.         {
  4939.             c = *data++;
  4940.             if (c=='\"' || !c)
  4941.             {
  4942.                 com_token[len] = 0;
  4943.                 *data_p = ( char * ) data;
  4944.                 return com_token;
  4945.             }
  4946.             if (len < MAX_TOKEN_CHARS)
  4947.             {
  4948.                 com_token[len] = c;
  4949.                 len++;
  4950.             }
  4951.         }
  4952.     }
  4953.  
  4954.     // parse a regular word
  4955.     do
  4956.     {
  4957.         if (len < MAX_TOKEN_CHARS)
  4958.         {
  4959.             com_token[len] = c;
  4960.             len++;
  4961.         }
  4962.         data++;
  4963.         c = *data;
  4964.     } while (c>32 && c != ',' );
  4965.  
  4966.     if (len == MAX_TOKEN_CHARS)
  4967.     {
  4968. //      Com_Printf ("Token exceeded %i chars, discarded.\n", MAX_TOKEN_CHARS);
  4969.         len = 0;
  4970.     }
  4971.     com_token[len] = 0;
  4972.  
  4973.     *data_p = ( char * ) data;
  4974.     return com_token;
  4975. }
  4976.  
  4977.  
  4978. /*
  4979. ===============
  4980. RE_RegisterSkin
  4981.  
  4982. ===============
  4983. */
  4984. qhandle_t RE_RegisterSkin( const char *name ) {
  4985.     qhandle_t   hSkin;
  4986.     skin_t      *skin;
  4987.     skinSurface_t   *surf;
  4988.     char        *text, *text_p;
  4989.     char        *token;
  4990.     char        surfName[MAX_QPATH];
  4991.  
  4992.     if ( !name || !name[0] ) {
  4993.         Com_Printf( "Empty name passed to RE_RegisterSkin\n" );
  4994.         return 0;
  4995.     }
  4996.  
  4997.     if ( strlen( name ) >= MAX_QPATH ) {
  4998.         Com_Printf( "Skin name exceeds MAX_QPATH\n" );
  4999.         return 0;
  5000.     }
  5001.  
  5002.  
  5003.     // see if the skin is already loaded
  5004.     for ( hSkin = 1; hSkin < tr.numSkins ; hSkin++ ) {
  5005.         skin = tr.skins[hSkin];
  5006.         if ( !Q_stricmp( skin->name, name ) ) {
  5007.             if( skin->numSurfaces == 0 ) {
  5008.                 return 0;       // default skin
  5009.             }
  5010.             return hSkin;
  5011.         }
  5012.     }
  5013.  
  5014.     // allocate a new skin
  5015.     if ( tr.numSkins == MAX_SKINS ) {
  5016.         ri.Printf( PRINT_WARNING, "WARNING: RE_RegisterSkin( '%s' ) MAX_SKINS hit\n", name );
  5017.         return 0;
  5018.     }
  5019.     tr.numSkins++;
  5020.     skin = ri.Hunk_Alloc( sizeof( skin_t ), h_low );
  5021.     tr.skins[hSkin] = skin;
  5022.     Q_strncpyz( skin->name, name, sizeof( skin->name ) );
  5023.     skin->numSurfaces = 0;
  5024.  
  5025.     // make sure the render thread is stopped
  5026.     R_SyncRenderThread();
  5027.  
  5028.     // If not a .skin file, load as a single shader
  5029.     if ( strcmp( name + strlen( name ) - 5, ".skin" ) ) {
  5030.         skin->numSurfaces = 1;
  5031.         skin->surfaces[0] = ri.Hunk_Alloc( sizeof(skin->surfaces[0]), h_low );
  5032.         skin->surfaces[0]->shader = R_FindShader( name, LIGHTMAP_NONE, qtrue );
  5033.         return hSkin;
  5034.     }
  5035.  
  5036.     // load and parse the skin file
  5037.     ri.FS_ReadFile( name, (void **)&text );
  5038.     if ( !text ) {
  5039.         return 0;
  5040.     }
  5041.  
  5042.     text_p = text;
  5043.     while ( text_p && *text_p ) {
  5044.         // get surface name
  5045.         token = CommaParse( &text_p );
  5046.         Q_strncpyz( surfName, token, sizeof( surfName ) );
  5047.  
  5048.         if ( !token[0] ) {
  5049.             break;
  5050.         }
  5051.         // lowercase the surface name so skin compares are faster
  5052.         Q_strlwr( surfName );
  5053.  
  5054.         if ( *text_p == ',' ) {
  5055.             text_p++;
  5056.         }
  5057.  
  5058.         if ( strstr( token, "tag_" ) ) {
  5059.             continue;
  5060.         }
  5061.        
  5062.         // parse the shader name
  5063.         token = CommaParse( &text_p );
  5064.  
  5065.         surf = skin->surfaces[ skin->numSurfaces ] = ri.Hunk_Alloc( sizeof( *skin->surfaces[0] ), h_low );
  5066.         Q_strncpyz( surf->name, surfName, sizeof( surf->name ) );
  5067.         surf->shader = R_FindShader( token, LIGHTMAP_NONE, qtrue );
  5068.         skin->numSurfaces++;
  5069.     }
  5070.  
  5071.     ri.FS_FreeFile( text );
  5072.  
  5073.  
  5074.     // never let a skin have 0 shaders
  5075.     if ( skin->numSurfaces == 0 ) {
  5076.         return 0;       // use default skin
  5077.     }
  5078.  
  5079.     return hSkin;
  5080. }
  5081.  
  5082.  
  5083. /*
  5084. ===============
  5085. R_InitSkins
  5086. ===============
  5087. */
  5088. void    R_InitSkins( void ) {
  5089.     skin_t      *skin;
  5090.  
  5091.     tr.numSkins = 1;
  5092.  
  5093.     // make the default skin have all default shaders
  5094.     skin = tr.skins[0] = ri.Hunk_Alloc( sizeof( skin_t ), h_low );
  5095.     Q_strncpyz( skin->name, "<default skin>", sizeof( skin->name )  );
  5096.     skin->numSurfaces = 1;
  5097.     skin->surfaces[0] = ri.Hunk_Alloc( sizeof( *skin->surfaces ), h_low );
  5098.     skin->surfaces[0]->shader = tr.defaultShader;
  5099. }
  5100.  
  5101. /*
  5102. ===============
  5103. R_GetSkinByHandle
  5104. ===============
  5105. */
  5106. skin_t  *R_GetSkinByHandle( qhandle_t hSkin ) {
  5107.     if ( hSkin < 1 || hSkin >= tr.numSkins ) {
  5108.         return tr.skins[0];
  5109.     }
  5110.     return tr.skins[ hSkin ];
  5111. }
  5112.  
  5113. /*
  5114. ===============
  5115. R_SkinList_f
  5116. ===============
  5117. */
  5118. void    R_SkinList_f( void ) {
  5119.     int         i, j;
  5120.     skin_t      *skin;
  5121.  
  5122.     ri.Printf (PRINT_ALL, "------------------\n");
  5123.  
  5124.     for ( i = 0 ; i < tr.numSkins ; i++ ) {
  5125.         skin = tr.skins[i];
  5126.  
  5127.         ri.Printf( PRINT_ALL, "%3i:%s\n", i, skin->name );
  5128.         for ( j = 0 ; j < skin->numSurfaces ; j++ ) {
  5129.             ri.Printf( PRINT_ALL, "       %s = %s\n",
  5130.                 skin->surfaces[j]->name, skin->surfaces[j]->shader->name );
  5131.         }
  5132.     }
  5133.     ri.Printf (PRINT_ALL, "------------------\n");
  5134. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement