00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "cmdlib.h"
00025 #include "imagelib.h"
00026
00027
00028 int fgetLittleShort (FILE *f)
00029 {
00030 byte b1, b2;
00031
00032 b1 = fgetc(f);
00033 b2 = fgetc(f);
00034
00035 return (short)(b1 + b2*256);
00036 }
00037
00038 int fgetLittleLong (FILE *f)
00039 {
00040 byte b1, b2, b3, b4;
00041
00042 b1 = fgetc(f);
00043 b2 = fgetc(f);
00044 b3 = fgetc(f);
00045 b4 = fgetc(f);
00046
00047 return b1 + (b2<<8) + (b3<<16) + (b4<<24);
00048 }
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 typedef unsigned char UBYTE;
00062
00063 typedef unsigned short UWORD;
00064 typedef long LONG;
00065
00066 typedef enum
00067 {
00068 ms_none,
00069 ms_mask,
00070 ms_transcolor,
00071 ms_lasso
00072 } mask_t;
00073
00074 typedef enum
00075 {
00076 cm_none,
00077 cm_rle1
00078 } compress_t;
00079
00080 typedef struct
00081 {
00082 UWORD w,h;
00083 short x,y;
00084 UBYTE nPlanes;
00085 UBYTE masking;
00086 UBYTE compression;
00087 UBYTE pad1;
00088 UWORD transparentColor;
00089 UBYTE xAspect,yAspect;
00090 short pageWidth,pageHeight;
00091 } bmhd_t;
00092
00093 extern bmhd_t bmhd;
00094
00095
00096
00097 #define FORMID ('F'+('O'<<8)+((int)'R'<<16)+((int)'M'<<24))
00098 #define ILBMID ('I'+('L'<<8)+((int)'B'<<16)+((int)'M'<<24))
00099 #define PBMID ('P'+('B'<<8)+((int)'M'<<16)+((int)' '<<24))
00100 #define BMHDID ('B'+('M'<<8)+((int)'H'<<16)+((int)'D'<<24))
00101 #define BODYID ('B'+('O'<<8)+((int)'D'<<16)+((int)'Y'<<24))
00102 #define CMAPID ('C'+('M'<<8)+((int)'A'<<16)+((int)'P'<<24))
00103
00104
00105 bmhd_t bmhd;
00106
00107 int Align (int l)
00108 {
00109 if (l&1)
00110 return l+1;
00111 return l;
00112 }
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 byte *LBMRLEDecompress (byte *source,byte *unpacked, int bpwidth)
00124 {
00125 int count;
00126 byte b,rept;
00127
00128 count = 0;
00129
00130 do
00131 {
00132 rept = *source++;
00133
00134 if (rept > 0x80)
00135 {
00136 rept = (rept^0xff)+2;
00137 b = *source++;
00138 memset(unpacked,b,rept);
00139 unpacked += rept;
00140 }
00141 else if (rept < 0x80)
00142 {
00143 rept++;
00144 memcpy(unpacked,source,rept);
00145 unpacked += rept;
00146 source += rept;
00147 }
00148 else
00149 rept = 0;
00150
00151 count += rept;
00152
00153 } while (count<bpwidth);
00154
00155 if (count>bpwidth)
00156 Error ("Decompression exceeded width!\n");
00157
00158
00159 return source;
00160 }
00161
00162
00163
00164
00165
00166
00167
00168 void LoadLBM (const char *filename, byte **picture, byte **palette)
00169 {
00170 byte *LBMbuffer, *picbuffer, *cmapbuffer;
00171 int y;
00172 byte *LBM_P, *LBMEND_P;
00173 byte *pic_p;
00174 byte *body_p;
00175
00176 int formtype,formlength;
00177 int chunktype,chunklength;
00178
00179
00180 picbuffer = NULL;
00181 cmapbuffer = NULL;
00182
00183
00184
00185
00186 LoadFile (filename, (void **)&LBMbuffer);
00187
00188
00189
00190
00191 LBM_P = LBMbuffer;
00192 if ( *(int *)LBMbuffer != LittleLong(FORMID) )
00193 Error ("No FORM ID at start of file!\n");
00194
00195 LBM_P += 4;
00196 formlength = BigLong( *(int *)LBM_P );
00197 LBM_P += 4;
00198 LBMEND_P = LBM_P + Align(formlength);
00199
00200 formtype = LittleLong(*(int *)LBM_P);
00201
00202 if (formtype != ILBMID && formtype != PBMID)
00203 Error ("Unrecognized form type: %c%c%c%c\n", formtype&0xff
00204 ,(formtype>>8)&0xff,(formtype>>16)&0xff,(formtype>>24)&0xff);
00205
00206 LBM_P += 4;
00207
00208
00209
00210
00211
00212 while (LBM_P < LBMEND_P)
00213 {
00214 chunktype = LBM_P[0] + (LBM_P[1]<<8) + (LBM_P[2]<<16) + (LBM_P[3]<<24);
00215 LBM_P += 4;
00216 chunklength = LBM_P[3] + (LBM_P[2]<<8) + (LBM_P[1]<<16) + (LBM_P[0]<<24);
00217 LBM_P += 4;
00218
00219 switch ( chunktype )
00220 {
00221 case BMHDID:
00222 memcpy (&bmhd,LBM_P,sizeof(bmhd));
00223 bmhd.w = BigShort(bmhd.w);
00224 bmhd.h = BigShort(bmhd.h);
00225 bmhd.x = BigShort(bmhd.x);
00226 bmhd.y = BigShort(bmhd.y);
00227 bmhd.pageWidth = BigShort(bmhd.pageWidth);
00228 bmhd.pageHeight = BigShort(bmhd.pageHeight);
00229 break;
00230
00231 case CMAPID:
00232 cmapbuffer = malloc (768);
00233 memset (cmapbuffer, 0, 768);
00234 memcpy (cmapbuffer, LBM_P, chunklength);
00235 break;
00236
00237 case BODYID:
00238 body_p = LBM_P;
00239
00240 pic_p = picbuffer = malloc (bmhd.w*bmhd.h);
00241 if (formtype == PBMID)
00242 {
00243
00244
00245
00246 for (y=0 ; y<bmhd.h ; y++, pic_p += bmhd.w)
00247 {
00248 if (bmhd.compression == cm_rle1)
00249 body_p = LBMRLEDecompress ((byte *)body_p
00250 , pic_p , bmhd.w);
00251 else if (bmhd.compression == cm_none)
00252 {
00253 memcpy (pic_p,body_p,bmhd.w);
00254 body_p += Align(bmhd.w);
00255 }
00256 }
00257
00258 }
00259 else
00260 {
00261
00262
00263
00264 Error ("%s is an interlaced LBM, not packed", filename);
00265 }
00266 break;
00267 }
00268
00269 LBM_P += Align(chunklength);
00270 }
00271
00272 free (LBMbuffer);
00273
00274 *picture = picbuffer;
00275
00276 if (palette)
00277 *palette = cmapbuffer;
00278 }
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 void WriteLBMfile (const char *filename, byte *data,
00295 int width, int height, byte *palette)
00296 {
00297 byte *lbm, *lbmptr;
00298 int *formlength, *bmhdlength, *cmaplength, *bodylength;
00299 int length;
00300 bmhd_t basebmhd;
00301
00302 lbm = lbmptr = malloc (width*height+1000);
00303
00304
00305
00306
00307 *lbmptr++ = 'F';
00308 *lbmptr++ = 'O';
00309 *lbmptr++ = 'R';
00310 *lbmptr++ = 'M';
00311
00312 formlength = (int*)lbmptr;
00313 lbmptr+=4;
00314
00315 *lbmptr++ = 'P';
00316 *lbmptr++ = 'B';
00317 *lbmptr++ = 'M';
00318 *lbmptr++ = ' ';
00319
00320
00321
00322
00323 *lbmptr++ = 'B';
00324 *lbmptr++ = 'M';
00325 *lbmptr++ = 'H';
00326 *lbmptr++ = 'D';
00327
00328 bmhdlength = (int *)lbmptr;
00329 lbmptr+=4;
00330
00331 memset (&basebmhd,0,sizeof(basebmhd));
00332 basebmhd.w = BigShort((short)width);
00333 basebmhd.h = BigShort((short)height);
00334 basebmhd.nPlanes = BigShort(8);
00335 basebmhd.xAspect = BigShort(5);
00336 basebmhd.yAspect = BigShort(6);
00337 basebmhd.pageWidth = BigShort((short)width);
00338 basebmhd.pageHeight = BigShort((short)height);
00339
00340 memcpy (lbmptr,&basebmhd,sizeof(basebmhd));
00341 lbmptr += sizeof(basebmhd);
00342
00343 length = lbmptr-(byte *)bmhdlength-4;
00344 *bmhdlength = BigLong(length);
00345 if (length&1)
00346 *lbmptr++ = 0;
00347
00348
00349
00350
00351 *lbmptr++ = 'C';
00352 *lbmptr++ = 'M';
00353 *lbmptr++ = 'A';
00354 *lbmptr++ = 'P';
00355
00356 cmaplength = (int *)lbmptr;
00357 lbmptr+=4;
00358
00359 memcpy (lbmptr,palette,768);
00360 lbmptr += 768;
00361
00362 length = lbmptr-(byte *)cmaplength-4;
00363 *cmaplength = BigLong(length);
00364 if (length&1)
00365 *lbmptr++ = 0;
00366
00367
00368
00369
00370 *lbmptr++ = 'B';
00371 *lbmptr++ = 'O';
00372 *lbmptr++ = 'D';
00373 *lbmptr++ = 'Y';
00374
00375 bodylength = (int *)lbmptr;
00376 lbmptr+=4;
00377
00378 memcpy (lbmptr,data,width*height);
00379 lbmptr += width*height;
00380
00381 length = lbmptr-(byte *)bodylength-4;
00382 *bodylength = BigLong(length);
00383 if (length&1)
00384 *lbmptr++ = 0;
00385
00386
00387
00388
00389 length = lbmptr-(byte *)formlength-4;
00390 *formlength = BigLong(length);
00391 if (length&1)
00392 *lbmptr++ = 0;
00393
00394
00395
00396
00397 SaveFile (filename, lbm, lbmptr-lbm);
00398 free (lbm);
00399 }
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410 typedef struct
00411 {
00412 char manufacturer;
00413 char version;
00414 char encoding;
00415 char bits_per_pixel;
00416 unsigned short xmin,ymin,xmax,ymax;
00417 unsigned short hres,vres;
00418 unsigned char palette[48];
00419 char reserved;
00420 char color_planes;
00421 unsigned short bytes_per_line;
00422 unsigned short palette_type;
00423 char filler[58];
00424 unsigned char data;
00425 } pcx_t;
00426
00427
00428
00429
00430
00431
00432
00433 void LoadPCX (const char *filename, byte **pic, byte **palette, int *width, int *height)
00434 {
00435 byte *raw;
00436 pcx_t *pcx;
00437 int x, y;
00438 int len;
00439 int dataByte, runLength;
00440 byte *out, *pix;
00441
00442
00443
00444
00445 len = LoadFile (filename, (void **)&raw);
00446
00447
00448
00449
00450 pcx = (pcx_t *)raw;
00451 raw = &pcx->data;
00452
00453 pcx->xmin = LittleShort(pcx->xmin);
00454 pcx->ymin = LittleShort(pcx->ymin);
00455 pcx->xmax = LittleShort(pcx->xmax);
00456 pcx->ymax = LittleShort(pcx->ymax);
00457 pcx->hres = LittleShort(pcx->hres);
00458 pcx->vres = LittleShort(pcx->vres);
00459 pcx->bytes_per_line = LittleShort(pcx->bytes_per_line);
00460 pcx->palette_type = LittleShort(pcx->palette_type);
00461
00462 if (pcx->manufacturer != 0x0a
00463 || pcx->version != 5
00464 || pcx->encoding != 1
00465 || pcx->bits_per_pixel != 8
00466 || pcx->xmax >= 640
00467 || pcx->ymax >= 480)
00468 Error ("Bad pcx file %s", filename);
00469
00470 if (palette)
00471 {
00472 *palette = malloc(768);
00473 memcpy (*palette, (byte *)pcx + len - 768, 768);
00474 }
00475
00476 if (width)
00477 *width = pcx->xmax+1;
00478 if (height)
00479 *height = pcx->ymax+1;
00480
00481 if (!pic)
00482 return;
00483
00484 out = malloc ( (pcx->ymax+1) * (pcx->xmax+1) );
00485 if (!out)
00486 Error ("Skin_Cache: couldn't allocate");
00487
00488 *pic = out;
00489
00490 pix = out;
00491
00492 for (y=0 ; y<=pcx->ymax ; y++, pix += pcx->xmax+1)
00493 {
00494 for (x=0 ; x<=pcx->xmax ; )
00495 {
00496 dataByte = *raw++;
00497
00498 if((dataByte & 0xC0) == 0xC0)
00499 {
00500 runLength = dataByte & 0x3F;
00501 dataByte = *raw++;
00502 }
00503 else
00504 runLength = 1;
00505
00506
00507
00508 if ( ( y == pcx->ymax ) && ( x + runLength > pcx->xmax + 1 ) ) {
00509 runLength = pcx->xmax - x + 1;
00510 }
00511
00512 while(runLength-- > 0)
00513 pix[x++] = dataByte;
00514 }
00515
00516 }
00517
00518 if ( raw - (byte *)pcx > len)
00519 Error ("PCX file %s was malformed", filename);
00520
00521 free (pcx);
00522 }
00523
00524
00525
00526
00527
00528
00529 void WritePCXfile (const char *filename, byte *data,
00530 int width, int height, byte *palette)
00531 {
00532 int i, j, length;
00533 pcx_t *pcx;
00534 byte *pack;
00535
00536 pcx = malloc (width*height*2+1000);
00537 memset (pcx, 0, sizeof(*pcx));
00538
00539 pcx->manufacturer = 0x0a;
00540 pcx->version = 5;
00541 pcx->encoding = 1;
00542 pcx->bits_per_pixel = 8;
00543 pcx->xmin = 0;
00544 pcx->ymin = 0;
00545 pcx->xmax = LittleShort((short)(width-1));
00546 pcx->ymax = LittleShort((short)(height-1));
00547 pcx->hres = LittleShort((short)width);
00548 pcx->vres = LittleShort((short)height);
00549 pcx->color_planes = 1;
00550 pcx->bytes_per_line = LittleShort((short)width);
00551 pcx->palette_type = LittleShort(1);
00552
00553
00554 pack = &pcx->data;
00555
00556 for (i=0 ; i<height ; i++)
00557 {
00558 for (j=0 ; j<width ; j++)
00559 {
00560 if ( (*data & 0xc0) != 0xc0)
00561 *pack++ = *data++;
00562 else
00563 {
00564 *pack++ = 0xc1;
00565 *pack++ = *data++;
00566 }
00567 }
00568 }
00569
00570
00571 *pack++ = 0x0c;
00572 for (i=0 ; i<768 ; i++)
00573 *pack++ = *palette++;
00574
00575
00576 length = pack - (byte *)pcx;
00577 SaveFile (filename, pcx, length);
00578
00579 free (pcx);
00580 }
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644 void LoadBMP (const char *filename, byte **pic, byte **palette, int *width, int *height)
00645 {
00646 byte *out;
00647 FILE *fin;
00648 int i;
00649 int bfSize;
00650 int bfOffBits;
00651 int structSize;
00652 int bcWidth;
00653 int bcHeight;
00654 int bcPlanes;
00655 int bcBitCount;
00656 byte bcPalette[1024];
00657 qboolean flipped;
00658
00659 fin = fopen (filename, "rb");
00660 if (!fin) {
00661 Error ("Couldn't read %s", filename);
00662 }
00663
00664 i = fgetLittleShort (fin);
00665 if (i != 'B' + ('M'<<8) ) {
00666 Error ("%s is not a bmp file", filename);
00667 }
00668
00669 bfSize = fgetLittleLong (fin);
00670 fgetLittleShort(fin);
00671 fgetLittleShort(fin);
00672 bfOffBits = fgetLittleLong (fin);
00673
00674
00675
00676 structSize = fgetLittleLong (fin);
00677 if (structSize == 40) {
00678
00679 bcWidth = fgetLittleLong(fin);
00680 bcHeight= fgetLittleLong(fin);
00681 bcPlanes = fgetLittleShort(fin);
00682 bcBitCount = fgetLittleShort(fin);
00683
00684 fseek (fin, 24, SEEK_CUR);
00685
00686 if (palette) {
00687 fread (bcPalette, 1, 1024, fin);
00688 *palette = malloc(768);
00689
00690 for (i = 0 ; i < 256 ; i++) {
00691 (*palette)[i * 3 + 0] = bcPalette[i * 4 + 2];
00692 (*palette)[i * 3 + 1] = bcPalette[i * 4 + 1];
00693 (*palette)[i * 3 + 2] = bcPalette[i * 4 + 0];
00694 }
00695 }
00696 } else if (structSize == 12) {
00697
00698 bcWidth = fgetLittleShort(fin);
00699 bcHeight= fgetLittleShort(fin);
00700 bcPlanes = fgetLittleShort(fin);
00701 bcBitCount = fgetLittleShort(fin);
00702
00703 if (palette) {
00704 fread (bcPalette, 1, 768, fin);
00705 *palette = malloc(768);
00706
00707 for (i = 0 ; i < 256 ; i++) {
00708 (*palette)[i * 3 + 0] = bcPalette[i * 3 + 2];
00709 (*palette)[i * 3 + 1] = bcPalette[i * 3 + 1];
00710 (*palette)[i * 3 + 2] = bcPalette[i * 3 + 0];
00711 }
00712 }
00713 } else {
00714 Error ("%s had strange struct size", filename);
00715 }
00716
00717 if (bcPlanes != 1) {
00718 Error ("%s was not a single plane image", filename);
00719 }
00720
00721 if (bcBitCount != 8) {
00722 Error ("%s was not an 8 bit image", filename);
00723 }
00724
00725 if (bcHeight < 0) {
00726 bcHeight = -bcHeight;
00727 flipped = qtrue;
00728 } else {
00729 flipped = qfalse;
00730 }
00731
00732 if (width)
00733 *width = bcWidth;
00734 if (height)
00735 *height = bcHeight;
00736
00737 if (!pic) {
00738 fclose (fin);
00739 return;
00740 }
00741
00742 out = malloc ( bcWidth * bcHeight );
00743 *pic = out;
00744 fseek (fin, bfOffBits, SEEK_SET);
00745
00746 if (flipped) {
00747 for (i = 0 ; i < bcHeight ; i++) {
00748 fread (out + bcWidth * (bcHeight - 1 - i), 1, bcWidth, fin);
00749 }
00750 } else {
00751 fread (out, 1, bcWidth*bcHeight, fin);
00752 }
00753
00754 fclose (fin);
00755 }
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774 void Load256Image (const char *name, byte **pixels, byte **palette,
00775 int *width, int *height)
00776 {
00777 char ext[128];
00778
00779 ExtractFileExtension (name, ext);
00780 if (!Q_stricmp (ext, "lbm"))
00781 {
00782 LoadLBM (name, pixels, palette);
00783 if (width)
00784 *width = bmhd.w;
00785 if (height)
00786 *height = bmhd.h;
00787 }
00788 else if (!Q_stricmp (ext, "pcx"))
00789 {
00790 LoadPCX (name, pixels, palette, width, height);
00791 }
00792 else if (!Q_stricmp (ext, "bmp"))
00793 {
00794 LoadBMP (name, pixels, palette, width, height);
00795 }
00796 else
00797 Error ("%s doesn't have a known image extension", name);
00798 }
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808 void Save256Image (const char *name, byte *pixels, byte *palette,
00809 int width, int height)
00810 {
00811 char ext[128];
00812
00813 ExtractFileExtension (name, ext);
00814 if (!Q_stricmp (ext, "lbm"))
00815 {
00816 WriteLBMfile (name, pixels, width, height, palette);
00817 }
00818 else if (!Q_stricmp (ext, "pcx"))
00819 {
00820 WritePCXfile (name, pixels, width, height, palette);
00821 }
00822 else
00823 Error ("%s doesn't have a known image extension", name);
00824 }
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837 typedef struct _TargaHeader {
00838 unsigned char id_length, colormap_type, image_type;
00839 unsigned short colormap_index, colormap_length;
00840 unsigned char colormap_size;
00841 unsigned short x_origin, y_origin, width, height;
00842 unsigned char pixel_size, attributes;
00843 } TargaHeader;
00844
00845
00846
00847
00848
00849
00850 void LoadTGABuffer ( byte *buffer, byte **pic, int *width, int *height)
00851 {
00852 int columns, rows, numPixels;
00853 byte *pixbuf;
00854 int row, column;
00855 byte *buf_p;
00856 TargaHeader targa_header;
00857 byte *targa_rgba;
00858
00859 *pic = NULL;
00860
00861 buf_p = buffer;
00862
00863 targa_header.id_length = *buf_p++;
00864 targa_header.colormap_type = *buf_p++;
00865 targa_header.image_type = *buf_p++;
00866
00867 targa_header.colormap_index = LittleShort ( *(short *)buf_p );
00868 buf_p += 2;
00869 targa_header.colormap_length = LittleShort ( *(short *)buf_p );
00870 buf_p += 2;
00871 targa_header.colormap_size = *buf_p++;
00872 targa_header.x_origin = LittleShort ( *(short *)buf_p );
00873 buf_p += 2;
00874 targa_header.y_origin = LittleShort ( *(short *)buf_p );
00875 buf_p += 2;
00876 targa_header.width = LittleShort ( *(short *)buf_p );
00877 buf_p += 2;
00878 targa_header.height = LittleShort ( *(short *)buf_p );
00879 buf_p += 2;
00880 targa_header.pixel_size = *buf_p++;
00881 targa_header.attributes = *buf_p++;
00882
00883 if (targa_header.image_type!=2
00884 && targa_header.image_type!=10
00885 && targa_header.image_type != 3 )
00886 {
00887 Error("LoadTGA: Only type 2 (RGB), 3 (gray), and 10 (RGB) TGA images supported\n");
00888 }
00889
00890 if ( targa_header.colormap_type != 0 )
00891 {
00892 Error("LoadTGA: colormaps not supported\n" );
00893 }
00894
00895 if ( ( targa_header.pixel_size != 32 && targa_header.pixel_size != 24 ) && targa_header.image_type != 3 )
00896 {
00897 Error("LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
00898 }
00899
00900 columns = targa_header.width;
00901 rows = targa_header.height;
00902 numPixels = columns * rows;
00903
00904 if (width)
00905 *width = columns;
00906 if (height)
00907 *height = rows;
00908
00909 targa_rgba = malloc (numPixels*4);
00910 *pic = targa_rgba;
00911
00912 if (targa_header.id_length != 0)
00913 buf_p += targa_header.id_length;
00914
00915 if ( targa_header.image_type==2 || targa_header.image_type == 3 )
00916 {
00917
00918 for(row=rows-1; row>=0; row--)
00919 {
00920 pixbuf = targa_rgba + row*columns*4;
00921 for(column=0; column<columns; column++)
00922 {
00923 unsigned char red,green,blue,alphabyte;
00924 switch (targa_header.pixel_size)
00925 {
00926
00927 case 8:
00928 blue = *buf_p++;
00929 green = blue;
00930 red = blue;
00931 *pixbuf++ = red;
00932 *pixbuf++ = green;
00933 *pixbuf++ = blue;
00934 *pixbuf++ = 255;
00935 break;
00936
00937 case 24:
00938 blue = *buf_p++;
00939 green = *buf_p++;
00940 red = *buf_p++;
00941 *pixbuf++ = red;
00942 *pixbuf++ = green;
00943 *pixbuf++ = blue;
00944 *pixbuf++ = 255;
00945 break;
00946 case 32:
00947 blue = *buf_p++;
00948 green = *buf_p++;
00949 red = *buf_p++;
00950 alphabyte = *buf_p++;
00951 *pixbuf++ = red;
00952 *pixbuf++ = green;
00953 *pixbuf++ = blue;
00954 *pixbuf++ = alphabyte;
00955 break;
00956 default:
00957
00958 break;
00959 }
00960 }
00961 }
00962 }
00963 else if (targa_header.image_type==10) {
00964 unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j;
00965
00966 red = 0;
00967 green = 0;
00968 blue = 0;
00969 alphabyte = 0xff;
00970
00971 for(row=rows-1; row>=0; row--) {
00972 pixbuf = targa_rgba + row*columns*4;
00973 for(column=0; column<columns; ) {
00974 packetHeader= *buf_p++;
00975 packetSize = 1 + (packetHeader & 0x7f);
00976 if (packetHeader & 0x80) {
00977 switch (targa_header.pixel_size) {
00978 case 24:
00979 blue = *buf_p++;
00980 green = *buf_p++;
00981 red = *buf_p++;
00982 alphabyte = 255;
00983 break;
00984 case 32:
00985 blue = *buf_p++;
00986 green = *buf_p++;
00987 red = *buf_p++;
00988 alphabyte = *buf_p++;
00989 break;
00990 default:
00991
00992 break;
00993 }
00994
00995 for(j=0;j<packetSize;j++) {
00996 *pixbuf++=red;
00997 *pixbuf++=green;
00998 *pixbuf++=blue;
00999 *pixbuf++=alphabyte;
01000 column++;
01001 if (column==columns) {
01002 column=0;
01003 if (row>0)
01004 row--;
01005 else
01006 goto breakOut;
01007 pixbuf = targa_rgba + row*columns*4;
01008 }
01009 }
01010 }
01011 else {
01012 for(j=0;j<packetSize;j++) {
01013 switch (targa_header.pixel_size) {
01014 case 24:
01015 blue = *buf_p++;
01016 green = *buf_p++;
01017 red = *buf_p++;
01018 *pixbuf++ = red;
01019 *pixbuf++ = green;
01020 *pixbuf++ = blue;
01021 *pixbuf++ = 255;
01022 break;
01023 case 32:
01024 blue = *buf_p++;
01025 green = *buf_p++;
01026 red = *buf_p++;
01027 alphabyte = *buf_p++;
01028 *pixbuf++ = red;
01029 *pixbuf++ = green;
01030 *pixbuf++ = blue;
01031 *pixbuf++ = alphabyte;
01032 break;
01033 default:
01034
01035 break;
01036 }
01037 column++;
01038 if (column==columns) {
01039 column=0;
01040 if (row>0)
01041 row--;
01042 else
01043 goto breakOut;
01044 pixbuf = targa_rgba + row*columns*4;
01045 }
01046 }
01047 }
01048 }
01049 breakOut:;
01050 }
01051 }
01052
01053
01054 }
01055
01056
01057
01058
01059
01060
01061
01062
01063 void LoadTGA (const char *name, byte **pixels, int *width, int *height)
01064 {
01065 byte *buffer;
01066 int nLen;
01067
01068
01069
01070 nLen = LoadFile ( ( char * ) name, (void **)&buffer);
01071 if (nLen == -1)
01072 {
01073 Error ("Couldn't read %s", name);
01074 }
01075
01076 LoadTGABuffer(buffer, pixels, width, height);
01077
01078 }
01079
01080
01081
01082
01083
01084
01085
01086 void WriteTGA (const char *filename, byte *data, int width, int height) {
01087 byte *buffer;
01088 int i;
01089 int c;
01090 FILE *f;
01091
01092 buffer = malloc(width*height*4 + 18);
01093 memset (buffer, 0, 18);
01094 buffer[2] = 2;
01095 buffer[12] = width&255;
01096 buffer[13] = width>>8;
01097 buffer[14] = height&255;
01098 buffer[15] = height>>8;
01099 buffer[16] = 32;
01100
01101
01102 c = 18 + width * height * 4;
01103 for (i=18 ; i<c ; i+=4)
01104 {
01105 buffer[i] = data[i-18+2];
01106 buffer[i+1] = data[i-18+1];
01107 buffer[i+2] = data[i-18+0];
01108 buffer[i+3] = data[i-18+3];
01109 }
01110
01111 f = fopen (filename, "wb");
01112 fwrite (buffer, 1, c, f);
01113 fclose (f);
01114
01115 free (buffer);
01116 }
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133 void Load32BitImage (const char *name, unsigned **pixels, int *width, int *height)
01134 {
01135 char ext[128];
01136 byte *palette;
01137 byte *pixels8;
01138 byte *pixels32;
01139 int size;
01140 int i;
01141 int v;
01142
01143 ExtractFileExtension (name, ext);
01144 if (!Q_stricmp (ext, "tga")) {
01145 LoadTGA (name, (byte **)pixels, width, height);
01146 } else {
01147 Load256Image (name, &pixels8, &palette, width, height);
01148 if (!pixels) {
01149 return;
01150 }
01151 size = *width * *height;
01152 pixels32 = malloc(size * 4);
01153 *pixels = (unsigned *)pixels32;
01154 for (i = 0 ; i < size ; i++) {
01155 v = pixels8[i];
01156 pixels32[i*4 + 0] = palette[ v * 3 + 0 ];
01157 pixels32[i*4 + 1] = palette[ v * 3 + 1 ];
01158 pixels32[i*4 + 2] = palette[ v * 3 + 2 ];
01159 pixels32[i*4 + 3] = 0xff;
01160 }
01161 }
01162 }
01163
01164