doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Image_files.cpp
Go to the documentation of this file.
1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
8 
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
23 
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25 
26 ===========================================================================
27 */
28 
29 #include "../idlib/precompiled.h"
30 #pragma hdrstop
31 
32 #include "tr_local.h"
33 
34 /*
35 
36 This file only has a single entry point:
37 
38 void R_LoadImage( const char *name, byte **pic, int *width, int *height, bool makePowerOf2 );
39 
40 */
41 
42 /*
43  * Include file for users of JPEG library.
44  * You will need to have included system headers that define at least
45  * the typedefs FILE and size_t before you can include jpeglib.h.
46  * (stdio.h is sufficient on ANSI-conforming systems.)
47  * You may also wish to include "jerror.h".
48  */
49 
50 extern "C" {
51 #include "jpeg-6/jpeglib.h"
52 
53  // hooks from jpeg lib to our system
54 
55  void jpg_Error( const char *fmt, ... ) {
56  va_list argptr;
57  char msg[2048];
58 
59  va_start (argptr,fmt);
60  vsprintf (msg,fmt,argptr);
61  va_end (argptr);
62 
63  common->FatalError( "%s", msg );
64  }
65 
66  void jpg_Printf( const char *fmt, ... ) {
67  va_list argptr;
68  char msg[2048];
69 
70  va_start (argptr,fmt);
71  vsprintf (msg,fmt,argptr);
72  va_end (argptr);
73 
74  common->Printf( "%s", msg );
75  }
76 
77 }
78 
79 
80 /*
81 ================
82 R_WriteTGA
83 ================
84 */
85 void R_WriteTGA( const char *filename, const byte *data, int width, int height, bool flipVertical ) {
86  byte *buffer;
87  int i;
88  int bufferSize = width*height*4 + 18;
89  int imgStart = 18;
90 
91  buffer = (byte *)Mem_Alloc( bufferSize );
92  memset( buffer, 0, 18 );
93  buffer[2] = 2; // uncompressed type
94  buffer[12] = width&255;
95  buffer[13] = width>>8;
96  buffer[14] = height&255;
97  buffer[15] = height>>8;
98  buffer[16] = 32; // pixel size
99  if ( !flipVertical ) {
100  buffer[17] = (1<<5); // flip bit, for normal top to bottom raster order
101  }
102 
103  // swap rgb to bgr
104  for ( i=imgStart ; i<bufferSize ; i+=4 ) {
105  buffer[i] = data[i-imgStart+2]; // blue
106  buffer[i+1] = data[i-imgStart+1]; // green
107  buffer[i+2] = data[i-imgStart+0]; // red
108  buffer[i+3] = data[i-imgStart+3]; // alpha
109  }
110 
111  fileSystem->WriteFile( filename, buffer, bufferSize );
112 
113  Mem_Free (buffer);
114 }
115 
116 
117 /*
118 ================
119 R_WritePalTGA
120 ================
121 */
122 void R_WritePalTGA( const char *filename, const byte *data, const byte *palette, int width, int height, bool flipVertical ) {
123  byte *buffer;
124  int i;
125  int bufferSize = (width * height) + (256 * 3) + 18;
126  int palStart = 18;
127  int imgStart = 18 + (256 * 3);
128 
129  buffer = (byte *)Mem_Alloc( bufferSize );
130  memset( buffer, 0, 18 );
131  buffer[1] = 1; // color map type
132  buffer[2] = 1; // uncompressed color mapped image
133  buffer[5] = 0; // number of palette entries (lo)
134  buffer[6] = 1; // number of palette entries (hi)
135  buffer[7] = 24; // color map bpp
136  buffer[12] = width&255;
137  buffer[13] = width>>8;
138  buffer[14] = height&255;
139  buffer[15] = height>>8;
140  buffer[16] = 8; // pixel size
141  if ( !flipVertical ) {
142  buffer[17] = (1<<5); // flip bit, for normal top to bottom raster order
143  }
144 
145  // store palette, swapping rgb to bgr
146  for ( i=palStart ; i<imgStart ; i+=3 ) {
147  buffer[i] = palette[i-palStart+2]; // blue
148  buffer[i+1] = palette[i-palStart+1]; // green
149  buffer[i+2] = palette[i-palStart+0]; // red
150  }
151 
152  // store the image data
153  for ( i=imgStart ; i<bufferSize ; i++ ) {
154  buffer[i] = data[i-imgStart];
155  }
156 
157  fileSystem->WriteFile( filename, buffer, bufferSize );
158 
159  Mem_Free (buffer);
160 }
161 
162 
163 static void LoadBMP( const char *name, byte **pic, int *width, int *height, ID_TIME_T *timestamp );
164 static void LoadTGA( const char *name, byte **pic, int *width, int *height, ID_TIME_T *timestamp );
165 static void LoadJPG( const char *name, byte **pic, int *width, int *height, ID_TIME_T *timestamp );
166 
167 
168 /*
169 ========================================================================
170 
171 PCX files are used for 8 bit images
172 
173 ========================================================================
174 */
175 
176 typedef struct {
178  char version;
179  char encoding;
181  unsigned short xmin,ymin,xmax,ymax;
182  unsigned short hres,vres;
183  unsigned char palette[48];
184  char reserved;
186  unsigned short bytes_per_line;
187  unsigned short palette_type;
188  char filler[58];
189  unsigned char data; // unbounded
190 } pcx_t;
191 
192 
193 /*
194 ========================================================================
195 
196 TGA files are used for 24/32 bit images
197 
198 ========================================================================
199 */
200 
201 typedef struct _TargaHeader {
204  unsigned char colormap_size;
205  unsigned short x_origin, y_origin, width, height;
206  unsigned char pixel_size, attributes;
207 } TargaHeader;
208 
209 
210 
211 /*
212 =========================================================
213 
214 BMP LOADING
215 
216 =========================================================
217 */
218 typedef struct
219 {
220  char id[2];
221  unsigned long fileSize;
222  unsigned long reserved0;
223  unsigned long bitmapDataOffset;
224  unsigned long bitmapHeaderSize;
225  unsigned long width;
226  unsigned long height;
227  unsigned short planes;
228  unsigned short bitsPerPixel;
229  unsigned long compression;
230  unsigned long bitmapDataSize;
231  unsigned long hRes;
232  unsigned long vRes;
233  unsigned long colors;
234  unsigned long importantColors;
235  unsigned char palette[256][4];
236 } BMPHeader_t;
237 
238 /*
239 ==============
240 LoadBMP
241 ==============
242 */
243 static void LoadBMP( const char *name, byte **pic, int *width, int *height, ID_TIME_T *timestamp )
244 {
245  int columns, rows, numPixels;
246  byte *pixbuf;
247  int row, column;
248  byte *buf_p;
249  byte *buffer;
250  int length;
251  BMPHeader_t bmpHeader;
252  byte *bmpRGBA;
253 
254  if ( !pic ) {
255  fileSystem->ReadFile ( name, NULL, timestamp );
256  return; // just getting timestamp
257  }
258 
259  *pic = NULL;
260 
261  //
262  // load the file
263  //
264  length = fileSystem->ReadFile( name, (void **)&buffer, timestamp );
265  if ( !buffer ) {
266  return;
267  }
268 
269  buf_p = buffer;
270 
271  bmpHeader.id[0] = *buf_p++;
272  bmpHeader.id[1] = *buf_p++;
273  bmpHeader.fileSize = LittleLong( * ( long * ) buf_p );
274  buf_p += 4;
275  bmpHeader.reserved0 = LittleLong( * ( long * ) buf_p );
276  buf_p += 4;
277  bmpHeader.bitmapDataOffset = LittleLong( * ( long * ) buf_p );
278  buf_p += 4;
279  bmpHeader.bitmapHeaderSize = LittleLong( * ( long * ) buf_p );
280  buf_p += 4;
281  bmpHeader.width = LittleLong( * ( long * ) buf_p );
282  buf_p += 4;
283  bmpHeader.height = LittleLong( * ( long * ) buf_p );
284  buf_p += 4;
285  bmpHeader.planes = LittleShort( * ( short * ) buf_p );
286  buf_p += 2;
287  bmpHeader.bitsPerPixel = LittleShort( * ( short * ) buf_p );
288  buf_p += 2;
289  bmpHeader.compression = LittleLong( * ( long * ) buf_p );
290  buf_p += 4;
291  bmpHeader.bitmapDataSize = LittleLong( * ( long * ) buf_p );
292  buf_p += 4;
293  bmpHeader.hRes = LittleLong( * ( long * ) buf_p );
294  buf_p += 4;
295  bmpHeader.vRes = LittleLong( * ( long * ) buf_p );
296  buf_p += 4;
297  bmpHeader.colors = LittleLong( * ( long * ) buf_p );
298  buf_p += 4;
299  bmpHeader.importantColors = LittleLong( * ( long * ) buf_p );
300  buf_p += 4;
301 
302  memcpy( bmpHeader.palette, buf_p, sizeof( bmpHeader.palette ) );
303 
304  if ( bmpHeader.bitsPerPixel == 8 )
305  buf_p += 1024;
306 
307  if ( bmpHeader.id[0] != 'B' && bmpHeader.id[1] != 'M' )
308  {
309  common->Error( "LoadBMP: only Windows-style BMP files supported (%s)\n", name );
310  }
311  if ( bmpHeader.fileSize != length )
312  {
313  common->Error( "LoadBMP: header size does not match file size (%lu vs. %d) (%s)\n", bmpHeader.fileSize, length, name );
314  }
315  if ( bmpHeader.compression != 0 )
316  {
317  common->Error( "LoadBMP: only uncompressed BMP files supported (%s)\n", name );
318  }
319  if ( bmpHeader.bitsPerPixel < 8 )
320  {
321  common->Error( "LoadBMP: monochrome and 4-bit BMP files not supported (%s)\n", name );
322  }
323 
324  columns = bmpHeader.width;
325  rows = bmpHeader.height;
326  if ( rows < 0 )
327  rows = -rows;
328  numPixels = columns * rows;
329 
330  if ( width )
331  *width = columns;
332  if ( height )
333  *height = rows;
334 
335  bmpRGBA = (byte *)R_StaticAlloc( numPixels * 4 );
336  *pic = bmpRGBA;
337 
338 
339  for ( row = rows-1; row >= 0; row-- )
340  {
341  pixbuf = bmpRGBA + row*columns*4;
342 
343  for ( column = 0; column < columns; column++ )
344  {
345  unsigned char red, green, blue, alpha;
346  int palIndex;
347  unsigned short shortPixel;
348 
349  switch ( bmpHeader.bitsPerPixel )
350  {
351  case 8:
352  palIndex = *buf_p++;
353  *pixbuf++ = bmpHeader.palette[palIndex][2];
354  *pixbuf++ = bmpHeader.palette[palIndex][1];
355  *pixbuf++ = bmpHeader.palette[palIndex][0];
356  *pixbuf++ = 0xff;
357  break;
358  case 16:
359  shortPixel = * ( unsigned short * ) pixbuf;
360  pixbuf += 2;
361  *pixbuf++ = ( shortPixel & ( 31 << 10 ) ) >> 7;
362  *pixbuf++ = ( shortPixel & ( 31 << 5 ) ) >> 2;
363  *pixbuf++ = ( shortPixel & ( 31 ) ) << 3;
364  *pixbuf++ = 0xff;
365  break;
366 
367  case 24:
368  blue = *buf_p++;
369  green = *buf_p++;
370  red = *buf_p++;
371  *pixbuf++ = red;
372  *pixbuf++ = green;
373  *pixbuf++ = blue;
374  *pixbuf++ = 255;
375  break;
376  case 32:
377  blue = *buf_p++;
378  green = *buf_p++;
379  red = *buf_p++;
380  alpha = *buf_p++;
381  *pixbuf++ = red;
382  *pixbuf++ = green;
383  *pixbuf++ = blue;
384  *pixbuf++ = alpha;
385  break;
386  default:
387  common->Error( "LoadBMP: illegal pixel_size '%d' in file '%s'\n", bmpHeader.bitsPerPixel, name );
388  break;
389  }
390  }
391  }
392 
393  fileSystem->FreeFile( buffer );
394 
395 }
396 
397 
398 /*
399 =================================================================
400 
401 PCX LOADING
402 
403 =================================================================
404 */
405 
406 
407 /*
408 ==============
409 LoadPCX
410 ==============
411 */
412 static void LoadPCX ( const char *filename, byte **pic, byte **palette, int *width, int *height,
413  ID_TIME_T *timestamp ) {
414  byte *raw;
415  pcx_t *pcx;
416  int x, y;
417  int len;
418  int dataByte, runLength;
419  byte *out, *pix;
420  int xmax, ymax;
421 
422  if ( !pic ) {
423  fileSystem->ReadFile( filename, NULL, timestamp );
424  return; // just getting timestamp
425  }
426 
427  *pic = NULL;
428  *palette = NULL;
429 
430  //
431  // load the file
432  //
433  len = fileSystem->ReadFile( filename, (void **)&raw, timestamp );
434  if (!raw) {
435  return;
436  }
437 
438  //
439  // parse the PCX file
440  //
441  pcx = (pcx_t *)raw;
442  raw = &pcx->data;
443 
444  xmax = LittleShort(pcx->xmax);
445  ymax = LittleShort(pcx->ymax);
446 
447  if (pcx->manufacturer != 0x0a
448  || pcx->version != 5
449  || pcx->encoding != 1
450  || pcx->bits_per_pixel != 8
451  || xmax >= 1024
452  || ymax >= 1024)
453  {
454  common->Printf( "Bad pcx file %s (%i x %i) (%i x %i)\n", filename, xmax+1, ymax+1, pcx->xmax, pcx->ymax);
455  return;
456  }
457 
458  out = (byte *)R_StaticAlloc( (ymax+1) * (xmax+1) );
459 
460  *pic = out;
461 
462  pix = out;
463 
464  if (palette)
465  {
466  *palette = (byte *)R_StaticAlloc(768);
467  memcpy (*palette, (byte *)pcx + len - 768, 768);
468  }
469 
470  if (width)
471  *width = xmax+1;
472  if (height)
473  *height = ymax+1;
474 // FIXME: use bytes_per_line here?
475 
476  for (y=0 ; y<=ymax ; y++, pix += xmax+1)
477  {
478  for (x=0 ; x<=xmax ; )
479  {
480  dataByte = *raw++;
481 
482  if((dataByte & 0xC0) == 0xC0)
483  {
484  runLength = dataByte & 0x3F;
485  dataByte = *raw++;
486  }
487  else
488  runLength = 1;
489 
490  while(runLength-- > 0)
491  pix[x++] = dataByte;
492  }
493 
494  }
495 
496  if ( raw - (byte *)pcx > len)
497  {
498  common->Printf( "PCX file %s was malformed", filename );
499  R_StaticFree (*pic);
500  *pic = NULL;
501  }
502 
503  fileSystem->FreeFile( pcx );
504 }
505 
506 
507 /*
508 ==============
509 LoadPCX32
510 ==============
511 */
512 static void LoadPCX32 ( const char *filename, byte **pic, int *width, int *height, ID_TIME_T *timestamp) {
513  byte *palette;
514  byte *pic8;
515  int i, c, p;
516  byte *pic32;
517 
518  if ( !pic ) {
519  fileSystem->ReadFile( filename, NULL, timestamp );
520  return; // just getting timestamp
521  }
522  LoadPCX (filename, &pic8, &palette, width, height, timestamp);
523  if (!pic8) {
524  *pic = NULL;
525  return;
526  }
527 
528  c = (*width) * (*height);
529  pic32 = *pic = (byte *)R_StaticAlloc(4 * c );
530  for (i = 0 ; i < c ; i++) {
531  p = pic8[i];
532  pic32[0] = palette[p*3];
533  pic32[1] = palette[p*3 + 1];
534  pic32[2] = palette[p*3 + 2];
535  pic32[3] = 255;
536  pic32 += 4;
537  }
538 
539  R_StaticFree( pic8 );
540  R_StaticFree( palette );
541 }
542 
543 /*
544 =========================================================
545 
546 TARGA LOADING
547 
548 =========================================================
549 */
550 
551 /*
552 =============
553 LoadTGA
554 =============
555 */
556 static void LoadTGA( const char *name, byte **pic, int *width, int *height, ID_TIME_T *timestamp ) {
557  int columns, rows, numPixels, fileSize, numBytes;
558  byte *pixbuf;
559  int row, column;
560  byte *buf_p;
561  byte *buffer;
562  TargaHeader targa_header;
563  byte *targa_rgba;
564 
565  if ( !pic ) {
566  fileSystem->ReadFile( name, NULL, timestamp );
567  return; // just getting timestamp
568  }
569 
570  *pic = NULL;
571 
572  //
573  // load the file
574  //
575  fileSize = fileSystem->ReadFile( name, (void **)&buffer, timestamp );
576  if ( !buffer ) {
577  return;
578  }
579 
580  buf_p = buffer;
581 
582  targa_header.id_length = *buf_p++;
583  targa_header.colormap_type = *buf_p++;
584  targa_header.image_type = *buf_p++;
585 
586  targa_header.colormap_index = LittleShort ( *(short *)buf_p );
587  buf_p += 2;
588  targa_header.colormap_length = LittleShort ( *(short *)buf_p );
589  buf_p += 2;
590  targa_header.colormap_size = *buf_p++;
591  targa_header.x_origin = LittleShort ( *(short *)buf_p );
592  buf_p += 2;
593  targa_header.y_origin = LittleShort ( *(short *)buf_p );
594  buf_p += 2;
595  targa_header.width = LittleShort ( *(short *)buf_p );
596  buf_p += 2;
597  targa_header.height = LittleShort ( *(short *)buf_p );
598  buf_p += 2;
599  targa_header.pixel_size = *buf_p++;
600  targa_header.attributes = *buf_p++;
601 
602  if ( targa_header.image_type != 2 && targa_header.image_type != 10 && targa_header.image_type != 3 ) {
603  common->Error( "LoadTGA( %s ): Only type 2 (RGB), 3 (gray), and 10 (RGB) TGA images supported\n", name );
604  }
605 
606  if ( targa_header.colormap_type != 0 ) {
607  common->Error( "LoadTGA( %s ): colormaps not supported\n", name );
608  }
609 
610  if ( ( targa_header.pixel_size != 32 && targa_header.pixel_size != 24 ) && targa_header.image_type != 3 ) {
611  common->Error( "LoadTGA( %s ): Only 32 or 24 bit images supported (no colormaps)\n", name );
612  }
613 
614  if ( targa_header.image_type == 2 || targa_header.image_type == 3 ) {
615  numBytes = targa_header.width * targa_header.height * ( targa_header.pixel_size >> 3 );
616  if ( numBytes > fileSize - 18 - targa_header.id_length ) {
617  common->Error( "LoadTGA( %s ): incomplete file\n", name );
618  }
619  }
620 
621  columns = targa_header.width;
622  rows = targa_header.height;
623  numPixels = columns * rows;
624 
625  if ( width ) {
626  *width = columns;
627  }
628  if ( height ) {
629  *height = rows;
630  }
631 
632  targa_rgba = (byte *)R_StaticAlloc(numPixels*4);
633  *pic = targa_rgba;
634 
635  if ( targa_header.id_length != 0 ) {
636  buf_p += targa_header.id_length; // skip TARGA image comment
637  }
638 
639  if ( targa_header.image_type == 2 || targa_header.image_type == 3 )
640  {
641  // Uncompressed RGB or gray scale image
642  for( row = rows - 1; row >= 0; row-- )
643  {
644  pixbuf = targa_rgba + row*columns*4;
645  for( column = 0; column < columns; column++)
646  {
647  unsigned char red,green,blue,alphabyte;
648  switch( targa_header.pixel_size )
649  {
650 
651  case 8:
652  blue = *buf_p++;
653  green = blue;
654  red = blue;
655  *pixbuf++ = red;
656  *pixbuf++ = green;
657  *pixbuf++ = blue;
658  *pixbuf++ = 255;
659  break;
660 
661  case 24:
662  blue = *buf_p++;
663  green = *buf_p++;
664  red = *buf_p++;
665  *pixbuf++ = red;
666  *pixbuf++ = green;
667  *pixbuf++ = blue;
668  *pixbuf++ = 255;
669  break;
670  case 32:
671  blue = *buf_p++;
672  green = *buf_p++;
673  red = *buf_p++;
674  alphabyte = *buf_p++;
675  *pixbuf++ = red;
676  *pixbuf++ = green;
677  *pixbuf++ = blue;
678  *pixbuf++ = alphabyte;
679  break;
680  default:
681  common->Error( "LoadTGA( %s ): illegal pixel_size '%d'\n", name, targa_header.pixel_size );
682  break;
683  }
684  }
685  }
686  }
687  else if ( targa_header.image_type == 10 ) { // Runlength encoded RGB images
688  unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j;
689 
690  red = 0;
691  green = 0;
692  blue = 0;
693  alphabyte = 0xff;
694 
695  for( row = rows - 1; row >= 0; row-- ) {
696  pixbuf = targa_rgba + row*columns*4;
697  for( column = 0; column < columns; ) {
698  packetHeader= *buf_p++;
699  packetSize = 1 + (packetHeader & 0x7f);
700  if ( packetHeader & 0x80 ) { // run-length packet
701  switch( targa_header.pixel_size ) {
702  case 24:
703  blue = *buf_p++;
704  green = *buf_p++;
705  red = *buf_p++;
706  alphabyte = 255;
707  break;
708  case 32:
709  blue = *buf_p++;
710  green = *buf_p++;
711  red = *buf_p++;
712  alphabyte = *buf_p++;
713  break;
714  default:
715  common->Error( "LoadTGA( %s ): illegal pixel_size '%d'\n", name, targa_header.pixel_size );
716  break;
717  }
718 
719  for( j = 0; j < packetSize; j++ ) {
720  *pixbuf++=red;
721  *pixbuf++=green;
722  *pixbuf++=blue;
723  *pixbuf++=alphabyte;
724  column++;
725  if ( column == columns ) { // run spans across rows
726  column = 0;
727  if ( row > 0) {
728  row--;
729  }
730  else {
731  goto breakOut;
732  }
733  pixbuf = targa_rgba + row*columns*4;
734  }
735  }
736  }
737  else { // non run-length packet
738  for( j = 0; j < packetSize; j++ ) {
739  switch( targa_header.pixel_size ) {
740  case 24:
741  blue = *buf_p++;
742  green = *buf_p++;
743  red = *buf_p++;
744  *pixbuf++ = red;
745  *pixbuf++ = green;
746  *pixbuf++ = blue;
747  *pixbuf++ = 255;
748  break;
749  case 32:
750  blue = *buf_p++;
751  green = *buf_p++;
752  red = *buf_p++;
753  alphabyte = *buf_p++;
754  *pixbuf++ = red;
755  *pixbuf++ = green;
756  *pixbuf++ = blue;
757  *pixbuf++ = alphabyte;
758  break;
759  default:
760  common->Error( "LoadTGA( %s ): illegal pixel_size '%d'\n", name, targa_header.pixel_size );
761  break;
762  }
763  column++;
764  if ( column == columns ) { // pixel packet run spans across rows
765  column = 0;
766  if ( row > 0 ) {
767  row--;
768  }
769  else {
770  goto breakOut;
771  }
772  pixbuf = targa_rgba + row*columns*4;
773  }
774  }
775  }
776  }
777  breakOut: ;
778  }
779  }
780 
781  if ( (targa_header.attributes & (1<<5)) ) { // image flp bit
782  R_VerticalFlip( *pic, *width, *height );
783  }
784 
785  fileSystem->FreeFile( buffer );
786 }
787 
788 /*
789 =========================================================
790 
791 JPG LOADING
792 
793 Interfaces with the huge libjpeg
794 =========================================================
795 */
796 
797 /*
798 =============
799 LoadJPG
800 =============
801 */
802 static void LoadJPG( const char *filename, unsigned char **pic, int *width, int *height, ID_TIME_T *timestamp ) {
803  /* This struct contains the JPEG decompression parameters and pointers to
804  * working space (which is allocated as needed by the JPEG library).
805  */
806  struct jpeg_decompress_struct cinfo;
807  /* We use our private extension JPEG error handler.
808  * Note that this struct must live as long as the main JPEG parameter
809  * struct, to avoid dangling-pointer problems.
810  */
811  /* This struct represents a JPEG error handler. It is declared separately
812  * because applications often want to supply a specialized error handler
813  * (see the second half of this file for an example). But here we just
814  * take the easy way out and use the standard error handler, which will
815  * print a message on stderr and call exit() if compression fails.
816  * Note that this struct must live as long as the main JPEG parameter
817  * struct, to avoid dangling-pointer problems.
818  */
819  struct jpeg_error_mgr jerr;
820  /* More stuff */
821  JSAMPARRAY buffer; /* Output row buffer */
822  int row_stride; /* physical row width in output buffer */
823  unsigned char *out;
824  byte *fbuffer;
825  byte *bbuf;
826 
827  /* In this example we want to open the input file before doing anything else,
828  * so that the setjmp() error recovery below can assume the file is open.
829  * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
830  * requires it in order to read binary files.
831  */
832 
833  // JDC: because fill_input_buffer() blindly copies INPUT_BUF_SIZE bytes,
834  // we need to make sure the file buffer is padded or it may crash
835  if ( pic ) {
836  *pic = NULL; // until proven otherwise
837  }
838  {
839  int len;
840  idFile *f;
841 
842  f = fileSystem->OpenFileRead( filename );
843  if ( !f ) {
844  return;
845  }
846  len = f->Length();
847  if ( timestamp ) {
848  *timestamp = f->Timestamp();
849  }
850  if ( !pic ) {
851  fileSystem->CloseFile( f );
852  return; // just getting timestamp
853  }
854  fbuffer = (byte *)Mem_ClearedAlloc( len + 4096 );
855  f->Read( fbuffer, len );
856  fileSystem->CloseFile( f );
857  }
858 
859 
860  /* Step 1: allocate and initialize JPEG decompression object */
861 
862  /* We have to set up the error handler first, in case the initialization
863  * step fails. (Unlikely, but it could happen if you are out of memory.)
864  * This routine fills in the contents of struct jerr, and returns jerr's
865  * address which we place into the link field in cinfo.
866  */
867  cinfo.err = jpeg_std_error(&jerr);
868 
869  /* Now we can initialize the JPEG decompression object. */
870  jpeg_create_decompress(&cinfo);
871 
872  /* Step 2: specify data source (eg, a file) */
873 
874  jpeg_stdio_src(&cinfo, fbuffer);
875 
876  /* Step 3: read file parameters with jpeg_read_header() */
877 
878  (void) jpeg_read_header(&cinfo, true );
879  /* We can ignore the return value from jpeg_read_header since
880  * (a) suspension is not possible with the stdio data source, and
881  * (b) we passed TRUE to reject a tables-only JPEG file as an error.
882  * See libjpeg.doc for more info.
883  */
884 
885  /* Step 4: set parameters for decompression */
886 
887  /* In this example, we don't need to change any of the defaults set by
888  * jpeg_read_header(), so we do nothing here.
889  */
890 
891  /* Step 5: Start decompressor */
892 
893  (void) jpeg_start_decompress(&cinfo);
894  /* We can ignore the return value since suspension is not possible
895  * with the stdio data source.
896  */
897 
898  /* We may need to do some setup of our own at this point before reading
899  * the data. After jpeg_start_decompress() we have the correct scaled
900  * output image dimensions available, as well as the output colormap
901  * if we asked for color quantization.
902  * In this example, we need to make an output work buffer of the right size.
903  */
904  /* JSAMPLEs per row in output buffer */
905  row_stride = cinfo.output_width * cinfo.output_components;
906 
907  if (cinfo.output_components!=4) {
908  common->DWarning( "JPG %s is unsupported color depth (%d)",
909  filename, cinfo.output_components);
910  }
911  out = (byte *)R_StaticAlloc(cinfo.output_width*cinfo.output_height*4);
912 
913  *pic = out;
914  *width = cinfo.output_width;
915  *height = cinfo.output_height;
916 
917  /* Step 6: while (scan lines remain to be read) */
918  /* jpeg_read_scanlines(...); */
919 
920  /* Here we use the library's state variable cinfo.output_scanline as the
921  * loop counter, so that we don't have to keep track ourselves.
922  */
923  while (cinfo.output_scanline < cinfo.output_height) {
924  /* jpeg_read_scanlines expects an array of pointers to scanlines.
925  * Here the array is only one element long, but you could ask for
926  * more than one scanline at a time if that's more convenient.
927  */
928  bbuf = ((out+(row_stride*cinfo.output_scanline)));
929  buffer = &bbuf;
930  (void) jpeg_read_scanlines(&cinfo, buffer, 1);
931  }
932 
933  // clear all the alphas to 255
934  {
935  int i, j;
936  byte *buf;
937 
938  buf = *pic;
939 
940  j = cinfo.output_width * cinfo.output_height * 4;
941  for ( i = 3 ; i < j ; i+=4 ) {
942  buf[i] = 255;
943  }
944  }
945 
946  /* Step 7: Finish decompression */
947 
948  (void) jpeg_finish_decompress(&cinfo);
949  /* We can ignore the return value since suspension is not possible
950  * with the stdio data source.
951  */
952 
953  /* Step 8: Release JPEG decompression object */
954 
955  /* This is an important step since it will release a good deal of memory. */
956  jpeg_destroy_decompress(&cinfo);
957 
958  /* After finish_decompress, we can close the input file.
959  * Here we postpone it until after no more JPEG errors are possible,
960  * so as to simplify the setjmp error logic above. (Actually, I don't
961  * think that jpeg_destroy can do an error exit, but why assume anything...)
962  */
963  Mem_Free( fbuffer );
964 
965  /* At this point you may want to check to see whether any corrupt-data
966  * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
967  */
968 
969  /* And we're done! */
970 }
971 
972 //===================================================================
973 
974 /*
975 =================
976 R_LoadImage
977 
978 Loads any of the supported image types into a cannonical
979 32 bit format.
980 
981 Automatically attempts to load .jpg files if .tga files fail to load.
982 
983 *pic will be NULL if the load failed.
984 
985 Anything that is going to make this into a texture would use
986 makePowerOf2 = true, but something loading an image as a lookup
987 table of some sort would leave it in identity form.
988 
989 It is important to do this at image load time instead of texture load
990 time for bump maps.
991 
992 Timestamp may be NULL if the value is going to be ignored
993 
994 If pic is NULL, the image won't actually be loaded, it will just find the
995 timestamp.
996 =================
997 */
998 void R_LoadImage( const char *cname, byte **pic, int *width, int *height, ID_TIME_T *timestamp, bool makePowerOf2 ) {
999  idStr name = cname;
1000 
1001  if ( pic ) {
1002  *pic = NULL;
1003  }
1004  if ( timestamp ) {
1005  *timestamp = 0xFFFFFFFF;
1006  }
1007  if ( width ) {
1008  *width = 0;
1009  }
1010  if ( height ) {
1011  *height = 0;
1012  }
1013 
1014  name.DefaultFileExtension( ".tga" );
1015 
1016  if (name.Length()<5) {
1017  return;
1018  }
1019 
1020  name.ToLower();
1021  idStr ext;
1022  name.ExtractFileExtension( ext );
1023 
1024  if ( ext == "tga" ) {
1025  LoadTGA( name.c_str(), pic, width, height, timestamp ); // try tga first
1026  if ( ( pic && *pic == 0 ) || ( timestamp && *timestamp == -1 ) ) {
1027  name.StripFileExtension();
1028  name.DefaultFileExtension( ".jpg" );
1029  LoadJPG( name.c_str(), pic, width, height, timestamp );
1030  }
1031  } else if ( ext == "pcx" ) {
1032  LoadPCX32( name.c_str(), pic, width, height, timestamp );
1033  } else if ( ext == "bmp" ) {
1034  LoadBMP( name.c_str(), pic, width, height, timestamp );
1035  } else if ( ext == "jpg" ) {
1036  LoadJPG( name.c_str(), pic, width, height, timestamp );
1037  }
1038 
1039  if ( ( width && *width < 1 ) || ( height && *height < 1 ) ) {
1040  if ( pic && *pic ) {
1041  R_StaticFree( *pic );
1042  *pic = 0;
1043  }
1044  }
1045 
1046  //
1047  // convert to exact power of 2 sizes
1048  //
1049  if ( pic && *pic && makePowerOf2 ) {
1050  int w, h;
1051  int scaled_width, scaled_height;
1052  byte *resampledBuffer;
1053 
1054  w = *width;
1055  h = *height;
1056 
1057  for (scaled_width = 1 ; scaled_width < w ; scaled_width<<=1)
1058  ;
1059  for (scaled_height = 1 ; scaled_height < h ; scaled_height<<=1)
1060  ;
1061 
1062  if ( scaled_width != w || scaled_height != h ) {
1063  if ( globalImages->image_roundDown.GetBool() && scaled_width > w ) {
1064  scaled_width >>= 1;
1065  }
1066  if ( globalImages->image_roundDown.GetBool() && scaled_height > h ) {
1067  scaled_height >>= 1;
1068  }
1069 
1070  resampledBuffer = R_ResampleTexture( *pic, w, h, scaled_width, scaled_height );
1071  R_StaticFree( *pic );
1072  *pic = resampledBuffer;
1073  *width = scaled_width;
1074  *height = scaled_height;
1075  }
1076  }
1077 }
1078 
1079 
1080 /*
1081 =======================
1082 R_LoadCubeImages
1083 
1084 Loads six files with proper extensions
1085 =======================
1086 */
1087 bool R_LoadCubeImages( const char *imgName, cubeFiles_t extensions, byte *pics[6], int *outSize, ID_TIME_T *timestamp ) {
1088  int i, j;
1089  char *cameraSides[6] = { "_forward.tga", "_back.tga", "_left.tga", "_right.tga",
1090  "_up.tga", "_down.tga" };
1091  char *axisSides[6] = { "_px.tga", "_nx.tga", "_py.tga", "_ny.tga",
1092  "_pz.tga", "_nz.tga" };
1093  char **sides;
1094  char fullName[MAX_IMAGE_NAME];
1095  int width, height, size = 0;
1096 
1097  if ( extensions == CF_CAMERA ) {
1098  sides = cameraSides;
1099  } else {
1100  sides = axisSides;
1101  }
1102 
1103  // FIXME: precompressed cube map files
1104  if ( pics ) {
1105  memset( pics, 0, 6*sizeof(pics[0]) );
1106  }
1107  if ( timestamp ) {
1108  *timestamp = 0;
1109  }
1110 
1111  for ( i = 0 ; i < 6 ; i++ ) {
1112  idStr::snPrintf( fullName, sizeof( fullName ), "%s%s", imgName, sides[i] );
1113 
1114  ID_TIME_T thisTime;
1115  if ( !pics ) {
1116  // just checking timestamps
1117  R_LoadImageProgram( fullName, NULL, &width, &height, &thisTime );
1118  } else {
1119  R_LoadImageProgram( fullName, &pics[i], &width, &height, &thisTime );
1120  }
1121  if ( thisTime == FILE_NOT_FOUND_TIMESTAMP ) {
1122  break;
1123  }
1124  if ( i == 0 ) {
1125  size = width;
1126  }
1127  if ( width != size || height != size ) {
1128  common->Warning( "Mismatched sizes on cube map '%s'", imgName );
1129  break;
1130  }
1131  if ( timestamp ) {
1132  if ( thisTime > *timestamp ) {
1133  *timestamp = thisTime;
1134  }
1135  }
1136  if ( pics && extensions == CF_CAMERA ) {
1137  // convert from "camera" images to native cube map images
1138  switch( i ) {
1139  case 0: // forward
1140  R_RotatePic( pics[i], width);
1141  break;
1142  case 1: // back
1143  R_RotatePic( pics[i], width);
1144  R_HorizontalFlip( pics[i], width, height );
1145  R_VerticalFlip( pics[i], width, height );
1146  break;
1147  case 2: // left
1148  R_VerticalFlip( pics[i], width, height );
1149  break;
1150  case 3: // right
1151  R_HorizontalFlip( pics[i], width, height );
1152  break;
1153  case 4: // up
1154  R_RotatePic( pics[i], width);
1155  break;
1156  case 5: // down
1157  R_RotatePic( pics[i], width);
1158  break;
1159  }
1160  }
1161  }
1162 
1163  if ( i != 6 ) {
1164  // we had an error, so free everything
1165  if ( pics ) {
1166  for ( j = 0 ; j < i ; j++ ) {
1167  R_StaticFree( pics[j] );
1168  }
1169  }
1170 
1171  if ( timestamp ) {
1172  *timestamp = 0;
1173  }
1174  return false;
1175  }
1176 
1177  if ( outSize ) {
1178  *outSize = size;
1179  }
1180  return true;
1181 }
bool R_LoadCubeImages(const char *imgName, cubeFiles_t extensions, byte *pics[6], int *outSize, ID_TIME_T *timestamp)
void jpg_Printf(const char *fmt,...)
Definition: Image_files.cpp:66
void R_LoadImage(const char *cname, byte **pic, int *width, int *height, ID_TIME_T *timestamp, bool makePowerOf2)
unsigned short palette_type
virtual idFile * OpenFileRead(const char *relativePath, bool allowCopyFiles=true, const char *gamedir=NULL)=0
static int snPrintf(char *dest, int size, const char *fmt,...) id_attribute((format(printf
Definition: Str.cpp:1465
void R_WritePalTGA(const char *filename, const byte *data, const byte *palette, int width, int height, bool flipVertical)
char version
unsigned long height
void ToLower(void)
Definition: Str.h:817
GLOBAL boolean jpeg_start_decompress(j_decompress_ptr cinfo)
Definition: jdapistd.c:38
char manufacturer
unsigned short xmax
virtual int ReadFile(const char *relativePath, void **buffer, ID_TIME_T *timestamp=NULL)=0
int Length(void) const
Definition: Str.h:702
GLenum GLint GLint y
Definition: glext.h:2849
#define MAX_IMAGE_NAME
Definition: Image.h:144
int LoadJPG(const char *filename, unsigned char **pic, int *width, int *height)
Definition: jload.c:16
idFileSystem * fileSystem
Definition: FileSystem.cpp:500
char reserved
unsigned char data
unsigned short width
GLclampf GLclampf blue
Definition: glext.h:2843
GLclampf GLclampf GLclampf alpha
Definition: glext.h:2843
idStr & DefaultFileExtension(const char *extension)
Definition: Str.cpp:794
GLenum GLsizei len
Definition: glext.h:3472
unsigned short height
void R_LoadImageProgram(const char *name, byte **pic, int *width, int *height, ID_TIME_T *timestamp, textureDepth_t *depth=NULL)
GLenum GLint x
Definition: glext.h:2849
int i
Definition: process.py:33
virtual void FreeFile(void *buffer)=0
unsigned char colormap_type
struct jpeg_error_mgr jerr
Definition: Cinematic.cpp:1301
virtual int WriteFile(const char *relativePath, const void *buffer, int size, const char *basePath="fs_savepath")=0
unsigned long hRes
unsigned char id_length
unsigned long importantColors
cubeFiles_t
Definition: Image.h:138
Definition: File.h:50
unsigned short planes
unsigned short vres
GLOBAL void jpeg_create_decompress(j_decompress_ptr cinfo)
Definition: jdapimin.c:30
GLOBAL JDIMENSION jpeg_read_scanlines(j_decompress_ptr cinfo, JSAMPARRAY scanlines, JDIMENSION max_lines)
Definition: jdapistd.c:152
const GLubyte * c
Definition: glext.h:4677
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:3454
unsigned long bitmapDataOffset
idStr & StripFileExtension(void)
Definition: Str.cpp:757
char bits_per_pixel
virtual void virtual void virtual void DWarning(const char *fmt,...) id_attribute((format(printf
idCommon * common
Definition: Common.cpp:206
#define NULL
Definition: Lib.h:88
byte * R_ResampleTexture(const byte *in, int inwidth, int inheight, int outwidth, int outheight)
char encoding
GLsizei GLsizei GLenum GLenum const GLvoid * data
Definition: glext.h:2853
GLuint buffer
Definition: glext.h:3108
idImageManager * globalImages
Definition: Image_init.cpp:74
void R_HorizontalFlip(byte *data, int width, int height)
virtual void virtual void FatalError(const char *fmt,...) id_attribute((format(printf
virtual int Read(void *buffer, int len)
Definition: File.cpp:179
unsigned short y_origin
void Mem_Free(void *ptr)
Definition: Heap.cpp:1087
unsigned long vRes
unsigned short bytes_per_line
unsigned long reserved0
unsigned short x_origin
GLenum GLsizei width
Definition: glext.h:2846
unsigned long fileSize
unsigned char pixel_size
virtual void Printf(const char *fmt,...) id_attribute((format(printf
GLOBAL boolean jpeg_finish_decompress(j_decompress_ptr cinfo)
Definition: jdapimin.c:372
int LittleLong(int l)
Definition: Lib.cpp:281
virtual ID_TIME_T Timestamp(void)
Definition: File.cpp:208
GLenum GLsizei GLsizei height
Definition: glext.h:2856
static idCVar image_roundDown
Definition: Image.h:362
void R_RotatePic(byte *data, int width)
JSAMPROW * JSAMPARRAY
Definition: jpeglib.h:80
short LittleShort(short l)
Definition: Lib.cpp:279
unsigned long bitmapDataSize
GLOBAL void jpeg_destroy_decompress(j_decompress_ptr cinfo)
Definition: jdapimin.c:77
GLenum GLenum GLvoid * row
Definition: glext.h:2866
bool GetBool(void) const
Definition: CVarSystem.h:142
tuple f
Definition: idal.py:89
void R_VerticalFlip(byte *data, int width, int height)
unsigned char byte
Definition: Lib.h:75
void * R_StaticAlloc(int bytes)
Definition: tr_main.cpp:301
const GLcharARB * name
Definition: glext.h:3629
GLsizeiptr size
Definition: glext.h:3112
void R_WriteTGA(const char *filename, const byte *data, int width, int height, bool flipVertical)
Definition: Image_files.cpp:85
Definition: Str.h:116
struct _TargaHeader TargaHeader
GLsizei const GLcharARB const GLint * length
Definition: glext.h:3599
GLOBAL struct jpeg_error_mgr * jpeg_std_error(struct jpeg_error_mgr *err)
Definition: jerror.c:213
int vsprintf(idStr &string, const char *fmt, va_list argptr)
Definition: Str.cpp:1549
void * Mem_ClearedAlloc(const int size)
Definition: Heap.cpp:1149
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
const char * c_str(void) const
Definition: Str.h:487
unsigned char image_type
unsigned long bitmapHeaderSize
unsigned short ymax
unsigned char colormap_size
unsigned short colormap_index
unsigned long compression
void * Mem_Alloc(const int size)
Definition: Heap.cpp:1067
GLint j
Definition: qgl.h:264
void jpg_Error(const char *fmt,...)
Definition: Image_files.cpp:55
void ExtractFileExtension(idStr &dest) const
Definition: Str.cpp:965
virtual void CloseFile(idFile *f)=0
GLenum GLenum GLvoid GLvoid * column
Definition: glext.h:2866
char color_planes
void R_StaticFree(void *data)
Definition: tr_main.cpp:335
GLOBAL int jpeg_read_header(j_decompress_ptr cinfo, boolean require_image)
Definition: jdapimin.c:244
virtual void Error(const char *fmt,...) id_attribute((format(printf
GLfloat GLfloat p
Definition: glext.h:4674
unsigned long colors
virtual void virtual void Warning(const char *fmt,...) id_attribute((format(printf
unsigned char palette[256][4]
GLOBAL void jpeg_stdio_src(j_decompress_ptr cinfo, unsigned char *infile)
Definition: jdatasrc.c:174
virtual int Length(void)
Definition: File.cpp:199
unsigned long width
unsigned char attributes
unsigned short ymin
unsigned short bitsPerPixel
unsigned short colormap_length
GLclampf green
Definition: glext.h:2843