00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #include "pnmFileTypeTGA.h"
00050 #include "config_pnmimagetypes.h"
00051
00052 #include "pnmFileTypeRegistry.h"
00053 #include "bamReader.h"
00054 #include "pnmimage_base.h"
00055
00056 #include <string.h>
00057
00058 static const char * const extensions_tga[] = {
00059 "tga"
00060 };
00061 static const int num_extensions_tga = sizeof(extensions_tga) / sizeof(const char *);
00062
00063 TypeHandle PNMFileTypeTGA::_type_handle;
00064
00065
00066
00067 struct ImageHeader {
00068 unsigned char IDLength;
00069 unsigned char CoMapType;
00070 unsigned char ImgType;
00071 unsigned char Index_lo, Index_hi;
00072 unsigned char Length_lo, Length_hi;
00073 unsigned char CoSize;
00074 unsigned char X_org_lo, X_org_hi;
00075 unsigned char Y_org_lo, Y_org_hi;
00076 unsigned char Width_lo, Width_hi;
00077 unsigned char Height_lo, Height_hi;
00078 unsigned char PixelSize;
00079 unsigned char AttBits;
00080 unsigned char Rsrvd;
00081 unsigned char OrgBit;
00082 unsigned char IntrLve;
00083 };
00084
00085 typedef char ImageIDField[256];
00086
00087
00088 #define TGA_Null 0
00089 #define TGA_Map 1
00090 #define TGA_RGB 2
00091 #define TGA_Mono 3
00092 #define TGA_RLEMap 9
00093 #define TGA_RLERGB 10
00094 #define TGA_RLEMono 11
00095 #define TGA_CompMap 32
00096 #define TGA_CompMap4 33
00097
00098
00099 #define TGA_IL_None 0
00100 #define TGA_IL_Two 1
00101 #define TGA_IL_Four 2
00102
00103
00104
00105
00106
00107
00108 PNMFileTypeTGA::
00109 PNMFileTypeTGA() {
00110 }
00111
00112
00113
00114
00115
00116
00117 string PNMFileTypeTGA::
00118 get_name() const {
00119 return "Targa";
00120 }
00121
00122
00123
00124
00125
00126
00127
00128 int PNMFileTypeTGA::
00129 get_num_extensions() const {
00130 return num_extensions_tga;
00131 }
00132
00133
00134
00135
00136
00137
00138
00139
00140 string PNMFileTypeTGA::
00141 get_extension(int n) const {
00142 nassertr(n >= 0 && n < num_extensions_tga, string());
00143 return extensions_tga[n];
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153 string PNMFileTypeTGA::
00154 get_suggested_extension() const {
00155 return "tga";
00156 }
00157
00158
00159
00160
00161
00162
00163
00164
00165 PNMReader *PNMFileTypeTGA::
00166 make_reader(istream *file, bool owns_file, const string &magic_number) {
00167 init_pnm();
00168 return new Reader(this, file, owns_file, magic_number);
00169 }
00170
00171
00172
00173
00174
00175
00176
00177
00178 PNMWriter *PNMFileTypeTGA::
00179 make_writer(ostream *file, bool owns_file) {
00180 init_pnm();
00181 return new Writer(this, file, owns_file);
00182 }
00183
00184
00185
00186
00187
00188
00189
00190 PNMFileTypeTGA::Reader::
00191 Reader(PNMFileType *type, istream *file, bool owns_file, string magic_number) :
00192 PNMReader(type, file, owns_file)
00193 {
00194 tga_head = new ImageHeader;
00195 RLE_count = 0;
00196 RLE_flag = 0;
00197
00198
00199 readtga( file, tga_head, magic_number );
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 rows = ( (int) tga_head->Height_lo ) + ( (int) tga_head->Height_hi ) * 256;
00226 cols = ( (int) tga_head->Width_lo ) + ( (int) tga_head->Width_hi ) * 256;
00227
00228 switch ( tga_head->ImgType )
00229 {
00230 case TGA_Map:
00231 case TGA_RGB:
00232 case TGA_Mono:
00233 case TGA_RLEMap:
00234 case TGA_RLERGB:
00235 case TGA_RLEMono:
00236 break;
00237
00238 default:
00239 pm_error( "unknown Targa image type %d", tga_head->ImgType );
00240 }
00241
00242 int size;
00243
00244 if ( tga_head->ImgType == TGA_Map ||
00245 tga_head->ImgType == TGA_RLEMap ||
00246 tga_head->ImgType == TGA_CompMap ||
00247 tga_head->ImgType == TGA_CompMap4 )
00248 {
00249 if ( tga_head->CoMapType != 1 )
00250 pm_error(
00251 "mapped image (type %d) with color map type != 1",
00252 tga_head->ImgType );
00253 mapped = 1;
00254
00255 size = tga_head->CoSize;
00256 }
00257 else
00258 {
00259 mapped = 0;
00260 size = tga_head->PixelSize;
00261 }
00262
00263 switch ( size ) {
00264 case 8:
00265 _num_channels = 1;
00266 _maxval = 255;
00267 break;
00268
00269 case 24:
00270 _num_channels = 3;
00271 _maxval = 255;
00272 break;
00273
00274 case 32:
00275 _num_channels = 4;
00276 _maxval = 255;
00277 break;
00278
00279 case 15:
00280 case 16:
00281 _num_channels = 3;
00282 _maxval = 31;
00283 break;
00284
00285 default:
00286 pm_error("unknown pixel size - %d", size );
00287 }
00288
00289
00290 if ( tga_head->CoMapType != 0 )
00291 {
00292 unsigned int temp1, temp2;
00293 temp1 = tga_head->Index_lo + tga_head->Index_hi * 256;
00294 temp2 = tga_head->Length_lo + tga_head->Length_hi * 256;
00295 if ( ( temp1 + temp2 + 1 ) >= TGA_MAXCOLORS )
00296 pm_error( "too many colors - %d", ( temp1 + temp2 + 1 ) );
00297 for ( unsigned int i = temp1; i < ( temp1 + temp2 ); ++i )
00298 get_map_entry( file, &ColorMap[i], (int) tga_head->CoSize,
00299 &AlphaMap[i]);
00300 }
00301
00302
00303 if ( tga_head->ImgType == TGA_RLEMap ||
00304 tga_head->ImgType == TGA_RLERGB ||
00305 tga_head->ImgType == TGA_RLEMono )
00306 rlencoded = 1;
00307 else
00308 rlencoded = 0;
00309
00310 _x_size = cols;
00311 _y_size = rows;
00312 _num_channels = 3;
00313
00314 }
00315
00316
00317
00318
00319
00320
00321 PNMFileTypeTGA::Reader::
00322 ~Reader() {
00323 delete tga_head;
00324 }
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339 int PNMFileTypeTGA::Reader::
00340 read_data(xel *array, xelval *alpha) {
00341 int truerow = 0;
00342 int baserow = 0;
00343 for ( int row = 0; row < rows; ++row )
00344 {
00345 int realrow = truerow;
00346 if ( tga_head->OrgBit == 0 )
00347 realrow = rows - realrow - 1;
00348
00349 for ( int col = 0; col < cols; ++col )
00350 get_pixel( _file, &(array[realrow * cols + col]),
00351 (int) tga_head->PixelSize,
00352 &(alpha[realrow * cols + col]) );
00353 if ( tga_head->IntrLve == TGA_IL_Four )
00354 truerow += 4;
00355 else if ( tga_head->IntrLve == TGA_IL_Two )
00356 truerow += 2;
00357 else
00358 ++truerow;
00359 if ( truerow >= rows )
00360 truerow = ++baserow;
00361 }
00362
00363 return rows;
00364 }
00365
00366
00367
00368
00369
00370
00371 PNMFileTypeTGA::Writer::
00372 Writer(PNMFileType *type, ostream *file, bool owns_file) :
00373 PNMWriter(type, file, owns_file)
00374 {
00375 tgaHeader = new ImageHeader;
00376 chv = (colorhist_vector)0;
00377 cht = (colorhash_table)0;
00378 runlength = (int*)0;
00379 }
00380
00381
00382
00383
00384
00385
00386 PNMFileTypeTGA::Writer::
00387 ~Writer() {
00388 delete tgaHeader;
00389
00390 if (chv != (colorhist_vector)0) {
00391 ppm_freecolorhist(chv);
00392 }
00393 if (cht != (colorhash_table)0) {
00394 ppm_freecolorhash(cht);
00395 }
00396 if (runlength != (int *)0) {
00397 pm_freerow((char *)runlength);
00398 }
00399 }
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423 int PNMFileTypeTGA::Writer::
00424 write_data(xel *array, xelval *) {
00425
00426
00427 rle_flag = tga_rle;
00428
00429 int row, col;
00430 int i;
00431 pixel* pP;
00432
00433 cols = _x_size;
00434 rows = _y_size;
00435
00436 if (is_grayscale() && tga_grayscale) {
00437
00438 tgaHeader->ImgType = TGA_Mono;
00439
00440
00441 pnmimage_tga_cat.info()
00442 << "writing grayscale.\n";
00443
00444 } else {
00445
00446 tgaHeader->ImgType = TGA_RGB;
00447
00448 if (tga_colormap) {
00449
00450 pnmimage_tga_cat.info()
00451 << "computing colormap...\n";
00452 chv = ppm_computecolorhist(&array, cols * rows, 1, TGA_MAXCOLORS, &ncolors );
00453 if ( chv == (colorhist_vector) 0 ) {
00454 pnmimage_tga_cat.info()
00455 << "too many colors, writing RGB.\n";
00456 } else {
00457 pnmimage_tga_cat.info()
00458 << ncolors << " colors found.\n";
00459 tgaHeader->ImgType = TGA_Map;
00460 }
00461 }
00462 }
00463
00464 if ( rle_flag )
00465 {
00466 switch ( tgaHeader->ImgType )
00467 {
00468 case TGA_Mono:
00469 tgaHeader->ImgType = TGA_RLEMono;
00470 break;
00471 case TGA_Map:
00472 tgaHeader->ImgType = TGA_RLEMap;
00473 break;
00474 case TGA_RGB:
00475 tgaHeader->ImgType = TGA_RLERGB;
00476 break;
00477 default:
00478 pm_error( "can't happen" );
00479 }
00480 runlength = (int*) pm_allocrow( cols, sizeof(int) );
00481 }
00482
00483 tgaHeader->IDLength = 0;
00484 tgaHeader->Index_lo = 0;
00485 tgaHeader->Index_hi = 0;
00486 if ( tgaHeader->ImgType == TGA_Map || tgaHeader->ImgType == TGA_RLEMap )
00487 {
00488
00489 cht = ppm_colorhisttocolorhash( chv, ncolors );
00490
00491 tgaHeader->CoMapType = 1;
00492 tgaHeader->Length_lo = ncolors % 256;
00493 tgaHeader->Length_hi = ncolors / 256;
00494 tgaHeader->CoSize = 24;
00495 }
00496 else
00497 {
00498 tgaHeader->CoMapType = 0;
00499 tgaHeader->Length_lo = 0;
00500 tgaHeader->Length_hi = 0;
00501 tgaHeader->CoSize = 0;
00502 }
00503 if ( tgaHeader->ImgType == TGA_RGB || tgaHeader->ImgType == TGA_RLERGB )
00504 tgaHeader->PixelSize = 24;
00505 else
00506 tgaHeader->PixelSize = 8;
00507 tgaHeader->X_org_lo = tgaHeader->X_org_hi = 0;
00508 tgaHeader->Y_org_lo = tgaHeader->Y_org_hi = 0;
00509 tgaHeader->Width_lo = cols % 256;
00510 tgaHeader->Width_hi = cols / 256;
00511 tgaHeader->Height_lo = rows % 256;
00512 tgaHeader->Height_hi = rows / 256;
00513 tgaHeader->AttBits = 0;
00514 tgaHeader->Rsrvd = 0;
00515 tgaHeader->IntrLve = 0;
00516 tgaHeader->OrgBit = 0;
00517
00518
00519 writetga( tgaHeader, (char*) 0 );
00520
00521 if ( tgaHeader->ImgType == TGA_Map || tgaHeader->ImgType == TGA_RLEMap )
00522 {
00523
00524 for ( i = 0; i < ncolors; ++i )
00525 put_map_entry( &chv[i].color, tgaHeader->CoSize, _maxval );
00526 }
00527
00528
00529 for ( row = 0; row < rows; ++row )
00530 {
00531 int realrow = row;
00532 if ( tgaHeader->OrgBit == 0 )
00533 realrow = rows - realrow - 1;
00534 if ( rle_flag )
00535 {
00536 compute_runlengths( cols, &array[realrow * cols], runlength );
00537 for ( col = 0; col < cols; )
00538 {
00539 if ( runlength[col] > 0 )
00540 {
00541 _file->put( 0x80 + runlength[col] - 1 );
00542 put_pixel(&(array[realrow * cols + col]),
00543 tgaHeader->ImgType, _maxval, cht );
00544 col += runlength[col];
00545 }
00546 else if ( runlength[col] < 0 )
00547 {
00548 _file->put( -runlength[col] - 1 );
00549 for ( i = 0; i < -runlength[col]; ++i )
00550 put_pixel(&(array[realrow * cols + (col + i)]),
00551 tgaHeader->ImgType, _maxval, cht );
00552 col += -runlength[col];
00553 }
00554 else
00555 pm_error( "can't happen" );
00556 }
00557 }
00558 else
00559 {
00560 for ( col = 0, pP = &array[realrow * cols]; col < cols; ++col, ++pP )
00561 put_pixel( pP, tgaHeader->ImgType, _maxval, cht );
00562 }
00563 }
00564
00565 return rows;
00566 }
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576 void PNMFileTypeTGA::
00577 register_with_read_factory() {
00578 BamReader::get_factory()->
00579 register_factory(get_class_type(), make_PNMFileTypeTGA);
00580 }
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594 TypedWritable *PNMFileTypeTGA::
00595 make_PNMFileTypeTGA(const FactoryParams ¶ms) {
00596 return PNMFileTypeRegistry::get_ptr()->get_type_by_handle(get_class_type());
00597 }
00598
00599 void PNMFileTypeTGA::Reader::
00600 readtga( istream *ifp, struct ImageHeader *tgaP, const string &magic_number ) {
00601 unsigned char flags;
00602 ImageIDField junk;
00603
00604 if (magic_number.length() > 0) {
00605 tgaP->IDLength = (unsigned char)magic_number[0];
00606 } else {
00607 tgaP->IDLength = getbyte( ifp );
00608 }
00609 if (magic_number.length() > 1) {
00610 tgaP->CoMapType = (unsigned char)magic_number[1];
00611 } else {
00612 tgaP->CoMapType = getbyte( ifp );
00613 }
00614 if (magic_number.length() > 2) {
00615 tgaP->ImgType = (unsigned char)magic_number[2];
00616 } else {
00617 tgaP->ImgType = getbyte( ifp );
00618 }
00619 if (magic_number.length() > 3) {
00620 tgaP->Index_lo = (unsigned char)magic_number[3];
00621 } else {
00622 tgaP->Index_lo = getbyte( ifp );
00623 }
00624 tgaP->Index_hi = getbyte( ifp );
00625 tgaP->Length_lo = getbyte( ifp );
00626 tgaP->Length_hi = getbyte( ifp );
00627 tgaP->CoSize = getbyte( ifp );
00628 tgaP->X_org_lo = getbyte( ifp );
00629 tgaP->X_org_hi = getbyte( ifp );
00630 tgaP->Y_org_lo = getbyte( ifp );
00631 tgaP->Y_org_hi = getbyte( ifp );
00632 tgaP->Width_lo = getbyte( ifp );
00633 tgaP->Width_hi = getbyte( ifp );
00634 tgaP->Height_lo = getbyte( ifp );
00635 tgaP->Height_hi = getbyte( ifp );
00636 tgaP->PixelSize = getbyte( ifp );
00637 flags = getbyte( ifp );
00638 tgaP->AttBits = flags & 0xf;
00639 tgaP->Rsrvd = ( flags & 0x10 ) >> 4;
00640 tgaP->OrgBit = ( flags & 0x20 ) >> 5;
00641 tgaP->IntrLve = ( flags & 0xc0 ) >> 6;
00642
00643 if ( tgaP->IDLength != 0 )
00644 ifp->read(junk, (int) tgaP->IDLength);
00645 }
00646
00647 void PNMFileTypeTGA::Reader::
00648 get_map_entry( istream *ifp, pixel *Value, int Size, gray *Alpha ) {
00649 unsigned char j, k, r, g, b, a;
00650
00651
00652 switch ( Size )
00653 {
00654 case 8:
00655 r = g = b = getbyte( ifp );
00656 a = 0;
00657 break;
00658
00659 case 16:
00660 case 15:
00661 j = getbyte( ifp );
00662 k = getbyte( ifp );
00663 r = ( k & 0x7C ) >> 2;
00664 g = ( ( k & 0x03 ) << 3 ) + ( ( j & 0xE0 ) >> 5 );
00665 b = j & 0x1F;
00666 a = 0;
00667 break;
00668
00669 case 32:
00670 case 24:
00671 b = getbyte( ifp );
00672 g = getbyte( ifp );
00673 r = getbyte( ifp );
00674 if ( Size == 32 )
00675 a = getbyte( ifp );
00676 else
00677 a = 0;
00678 break;
00679
00680 default:
00681 pm_error( "unknown colormap pixel size (#2) - %d", Size );
00682 }
00683 PPM_ASSIGN( *Value, r, g, b );
00684 *Alpha = a;
00685 }
00686
00687
00688
00689 void PNMFileTypeTGA::Reader::
00690 get_pixel( istream *ifp, pixel *dest, int Size, gray *alpha_p) {
00691 static pixval Red, Grn, Blu;
00692 static pixval Alpha;
00693 unsigned char j, k;
00694 static unsigned int l;
00695
00696
00697 if ( rlencoded )
00698 {
00699 if ( RLE_count == 0 )
00700 {
00701 unsigned char i;
00702 i = getbyte( ifp );
00703 RLE_flag = ( i & 0x80 );
00704 if ( RLE_flag == 0 )
00705
00706 RLE_count = i + 1;
00707 else
00708
00709 RLE_count = i - 127;
00710
00711 --RLE_count;
00712 }
00713 else
00714 {
00715 --RLE_count;
00716 if ( RLE_flag != 0 )
00717
00718 goto PixEncode;
00719 }
00720 }
00721
00722 switch ( Size )
00723 {
00724 case 8:
00725 Red = Grn = Blu = l = getbyte( ifp );
00726 Alpha = 0;
00727 break;
00728
00729 case 16:
00730 case 15:
00731 j = getbyte( ifp );
00732 k = getbyte( ifp );
00733 l = ( (unsigned int) k << 8 ) + j;
00734 Red = ( k & 0x7C ) >> 2;
00735 Grn = ( ( k & 0x03 ) << 3 ) + ( ( j & 0xE0 ) >> 5 );
00736 Blu = j & 0x1F;
00737 Alpha = 0;
00738 break;
00739
00740 case 32:
00741 case 24:
00742 Blu = getbyte( ifp );
00743 Grn = getbyte( ifp );
00744 Red = getbyte( ifp );
00745 if ( Size == 32 )
00746 Alpha = getbyte( ifp );
00747 else
00748 Alpha = 0;
00749 l = 0;
00750 break;
00751
00752 default:
00753 pm_error( "unknown pixel size (#2) - %d", Size );
00754 }
00755
00756 PixEncode:
00757 if ( mapped ) {
00758 *dest = ColorMap[l];
00759 if (has_alpha()) {
00760 *alpha_p = AlphaMap[l];
00761 }
00762 } else {
00763 PPM_ASSIGN( *dest, Red, Grn, Blu );
00764 if (has_alpha()) {
00765 *alpha_p = Alpha;
00766 }
00767 }
00768 }
00769
00770
00771 unsigned char PNMFileTypeTGA::Reader::
00772 getbyte( istream *ifp ) {
00773 unsigned char c;
00774
00775 c = ifp->get();
00776 if (ifp->fail() || ifp->eof())
00777 pm_error( "EOF / read error" );
00778
00779 return c;
00780 }
00781
00782 void PNMFileTypeTGA::Writer::
00783 writetga( struct ImageHeader *tgaP, char *id )
00784 {
00785 unsigned char flags;
00786
00787 _file->put( tgaP->IDLength );
00788 _file->put( tgaP->CoMapType );
00789 _file->put( tgaP->ImgType );
00790 _file->put( tgaP->Index_lo );
00791 _file->put( tgaP->Index_hi );
00792 _file->put( tgaP->Length_lo );
00793 _file->put( tgaP->Length_hi );
00794 _file->put( tgaP->CoSize );
00795 _file->put( tgaP->X_org_lo );
00796 _file->put( tgaP->X_org_hi );
00797 _file->put( tgaP->Y_org_lo );
00798 _file->put( tgaP->Y_org_hi );
00799 _file->put( tgaP->Width_lo );
00800 _file->put( tgaP->Width_hi );
00801 _file->put( tgaP->Height_lo );
00802 _file->put( tgaP->Height_hi );
00803 _file->put( tgaP->PixelSize );
00804 flags = ( tgaP->AttBits & 0xf ) | ( ( tgaP->Rsrvd & 0x1 ) << 4 ) |
00805 ( ( tgaP->OrgBit & 0x1 ) << 5 ) | ( ( tgaP->OrgBit & 0x3 ) << 6 );
00806 _file->put( flags );
00807 if ( tgaP->IDLength )
00808 _file->write( id, (int) tgaP->IDLength );
00809 }
00810
00811 void PNMFileTypeTGA::Writer::
00812 put_map_entry( pixel* valueP, int size, pixval maxval )
00813 {
00814 int j;
00815 pixel p;
00816
00817 switch ( size )
00818 {
00819 case 8:
00820 put_mono( valueP, maxval );
00821 break;
00822
00823 case 16:
00824 case 15:
00825 PPM_DEPTH( p, *valueP, maxval, 31 );
00826 j = (int) PPM_GETB( p ) | ( (int) PPM_GETG( p ) << 5 ) |
00827 ( (int) PPM_GETR( p ) << 10 );
00828 _file->put( j % 256 );
00829 _file->put( j / 256 );
00830 break;
00831
00832 case 32:
00833 case 24:
00834 put_rgb( valueP, maxval );
00835 break;
00836
00837 default:
00838 pm_error( "unknown colormap pixel size (#2) - %d", size );
00839 }
00840 }
00841
00842 void PNMFileTypeTGA::Writer::
00843 compute_runlengths( int cols, pixel *pixelrow, int *runlength )
00844 {
00845 int col, start;
00846
00847
00848 for ( col = 0; col < cols; ++col )
00849 runlength[col] = 0;
00850
00851
00852 for ( col = 0; col < cols; )
00853 {
00854 start = col;
00855 do {
00856 ++col;
00857 }
00858 while ( col < cols &&
00859 col - start < 128 &&
00860 PPM_EQUAL( pixelrow[col], pixelrow[start] ) );
00861 runlength[start] = col - start;
00862 }
00863
00864
00865 for ( col = 0; col < cols; )
00866 {
00867 if ( runlength[col] == 1 )
00868 {
00869 start = col;
00870 while ( col < cols &&
00871 col - start < 128 &&
00872 runlength[col] == 1 )
00873 {
00874 runlength[col] = 0;
00875 ++col;
00876 }
00877 runlength[start] = - ( col - start );
00878 }
00879 else
00880 col += runlength[col];
00881 }
00882 }
00883
00884 void PNMFileTypeTGA::Writer::
00885 put_pixel( pixel* pP, int imgtype, pixval maxval, colorhash_table cht )
00886 {
00887 switch ( imgtype )
00888 {
00889 case TGA_Mono:
00890 case TGA_RLEMono:
00891 put_mono( pP, maxval );
00892 break;
00893 case TGA_Map:
00894 case TGA_RLEMap:
00895 put_map( pP, cht );
00896 break;
00897 case TGA_RGB:
00898 case TGA_RLERGB:
00899 put_rgb( pP, maxval );
00900 break;
00901 default:
00902 pm_error( "can't happen" );
00903 }
00904 }
00905
00906 void PNMFileTypeTGA::Writer::
00907 put_mono( pixel* pP, pixval maxval )
00908 {
00909 pixel p;
00910 PPM_DEPTH( p, *pP, maxval, (pixval) 255 );
00911 _file->put( PPM_GETB( p ) );
00912 }
00913
00914 void PNMFileTypeTGA::Writer::
00915 put_map( pixel *pP, colorhash_table cht )
00916 {
00917 _file->put( ppm_lookupcolor( cht, pP ) );
00918 }
00919
00920 void PNMFileTypeTGA::Writer::
00921 put_rgb( pixel* pP, pixval maxval ) {
00922 pixel p;
00923 PPM_DEPTH( p, *pP, maxval, (pixval) 255 );
00924 _file->put( PPM_GETB( p ) );
00925 if (is_grayscale()) {
00926 _file->put( PPM_GETB( p ) );
00927 _file->put( PPM_GETB( p ) );
00928 } else {
00929 _file->put( PPM_GETG( p ) );
00930 _file->put( PPM_GETR( p ) );
00931 }
00932 }