1 /*---------------------------------------------------------------------*
2 Project: TexConv
3 File: tga.cpp
4
5 Copyright 1998-2001 Nintendo. All rights reserved.
6
7 These coded instructions, statements and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 Change History:
14
15 $Log: tga.cpp,v $
16 Revision 1.1 2006/02/17 09:03:29 mitu
17 1st version
18
19
20 2 4/11/01 3:19p John
21 Updated header copyrights and pathname.
22
23 1 12/03/99 3:48p Ryan
24
25 4 10/13/99 12:39p Mikepc
26 remove unused local variables.
27
28 3 10/13/99 11:14a Mikepc
29 bug fix- had to change 'free' argument from mFree( (void**)&ptr ) to
30 free( ptr ) after switching from mFree to free function.
31
32 2 10/12/99 7:57p Mikepc
33 for less confusing portability, changed to use calloc and free instead
34 of internal tplConv.lib memory calls.
35
36 1 10/08/99 3:06p Mikepc
37 code for user-defined ( .tga ) file reading function. Moved here from
38 tplConv.lib for portability. Developer is free to modify/ add code to
39 read other file types.
40
41 1 10/08/99 3:02p Mikepc
42 code for user-defined ( .tga ) file-reading function. File reading
43 code has been moved to tc from tplConv.lib for portability. Developer
44 is free to modify/add to this code to create other file-reading
45 functions.
46
47 10 9/16/99 8:47p Mikepc
48 updated code for auto-palette generation
49
50 9 9/02/99 11:12a Mikepc
51 some code re-organization between files.
52 added code (verify.cpp) to invoke s3tc.exe from within tc program.
53 changed some routines to accommodate the new texture creation path.
54
55 8 8/26/99 4:59p Mikepc
56 renamed file extensions from .c to .cpp.
57 .cpp extension allows addition of namespace protection to remove
58 potential name collisions with tool code. Exceptions are CreateTplFile
59 and QuickConvert. These are extern "C" linked.
60
61 7 8/26/99 11:38a Mikepc
62
63 6 8/26/99 11:03a Mikepc
64 tplCon rewrite for efficient memory usage, batch file processing
65 ability.
66
67 $NoKeywords: $
68
69 -----------------------------------------------------------------------*/
70
71
72 #include <stdlib.h>
73 #include <assert.h>
74
75 #include "tga.h"
76
77
78
79 // simplified form of a .tga file ( header and data )
80 // used as an intermediate for .tga file to layer conversion
81 typedef struct SimpleTga
82 {
83 u32 imageType;
84 u32 width;
85 u32 height;
86 u32 pixelDepth;
87 u32 abpp;
88
89 u32 colorMapType;
90 u32 cMapLength;
91 u32 cMapDepth;
92
93 u32 imageDataSize;
94 u8* imageData;
95
96 u32 paletteDataSize;
97 u8* paletteData;
98
99 }SimpleTga;
100
101
102 // forward references
103 static void UncompressTgaImage( u8* rawImage, SimpleTga* tga );
104 static void UnencodeTgaImage( u8* riPtr, u8* dstPtr, u32 width, u32 height, u32 pixelDepth );
105 static void OrientUncompressedTgaData( u8* srcBuff, u32 width, u32 height, u32 pixelDepth, u32 imageDesc );
106 static void AdjustTgaForPaletteOffset( u8* dfData, SimpleTga* tga, u16 cMapStart );
107 static void CreateTgaColorLayer( TCFilePtr dfPtr, SimpleTga* tga );
108 static void CreateTgaAlphaLayer( TCFilePtr dfPtr, SimpleTga* tga );
109 static void CreateTgaPalTable( TCFilePtr dfPtr, SimpleTga* tga );
110
111
112 //----------------------------------------------------------------------------------
113
114 // decode a tga file into a 'DecodedFile' structure
115
ReadTgaFile(u32 rawSize,u8 * rawBits,TCFile * dfPtr)116 u32 ReadTgaFile( u32 rawSize, u8* rawBits, TCFile* dfPtr )
117 {
118 u32 i;
119 u8 *rawImage, *rawPalette;
120 u32 rawHeaderSize, rawPaletteSize;
121 u32 tgaImageSize;
122 u8 imageDesc;
123 u16 cMapStart;
124 SimpleTga tga;
125
126
127 assert( rawSize > 0 );
128 assert( rawBits != NULL );
129 assert( dfPtr != NULL );
130
131
132 // zero out the tga structure
133 for( i=0; i< sizeof(SimpleTga); i++ )
134 {
135 *(u8*)( (u8*)(&tga) + i ) = 0;
136 }
137
138 // fill 'tga' using .tga header byte offsets
139 tga.imageType = (u32)( *((u8* )( rawBits + 0x02 )) );
140 tga.width = (u32)( *((u16*)( rawBits + 0x0C )) );
141 tga.height = (u32)( *((u16*)( rawBits + 0x0E )) );
142 tga.pixelDepth = (u32)( *((u8* )( rawBits + 0x10 )) ); // bits
143 tga.abpp = (u32)( *((u8* )( rawBits + 0x11 )) & (u8)(0x0F) ); // bits 0 to 3
144
145 tga.colorMapType = (u32)( *((u8* )( rawBits + 0x01 )) );
146 tga.cMapLength = (u32)( *((u16*)( rawBits + 0x05 )) );
147 tga.cMapDepth = (u32)( *((u8* )( rawBits + 0x07 )) ); // bits
148
149 cMapStart = *((u16*)( rawBits + 0x03 ));
150 imageDesc = *((u8* )( rawBits + 0x11 ));
151
152
153 // quick error check- if image type == 0, there is neither image nor palette data present
154 if( tga.imageType == 0 )
155 {
156 TCErrorMsg( "DecodeTgaFile(): file %s contains no image or palette data\n", dfPtr->name );
157 return 0;
158 }
159
160 // convert cMapDepth and pixelDepths from bits to bytes
161 // can mostly just right-shift 3 bits but must check for 15-bit format
162 // don't accept other odd bit-depths.
163
164 // palette entry sizes
165 switch( tga.cMapDepth )
166 {
167 case 0x00: // no palette
168 tga.cMapDepth = 0;
169 break;
170
171 case 0x10: // 16-bits fall through
172 case 0x18: // 24 bits fall through
173 case 0x20: // 32 bits fall through
174 tga.cMapDepth >>= 3;
175 break;
176
177 case 0x0F: // 15 bit entries = 5551 format- will be treated the same as 16 bits
178 tga.cMapDepth = 2;
179 break;
180
181 default: // unsupported palette entry size
182 TCErrorMsg( "DecodeTgaFile(): unsupported palette entry size in file %s\n", dfPtr->name );
183 return 0;
184 break;
185 }
186
187
188 // pixel depths
189 switch(tga.pixelDepth)
190 {
191 case 0x08: // 8-bits fall through
192 case 0x10: // 16-bits fall through
193 case 0x18: // 24 bits fall through
194 case 0x20: // 32 bits fall through
195 tga.pixelDepth >>= 3;
196 break;
197
198 case 0x0F: // 15 bit entries = 5551 format- will be treated the same as 16 bits
199 tga.pixelDepth = 2;
200 break;
201
202 default: // unsupported pixel depth entry size
203 TCErrorMsg( "DecodeTgaFile(): unsupported palette bit depth in file %s\n", dfPtr->name );
204 return 0;
205 break;
206 }
207
208
209
210 // .tga header size is 18 bytes + IDLength bytes (byte 0 of .tga header)
211 rawHeaderSize = (u32)( rawBits[0] ) + 18;
212
213
214 // palette (if present) follows the header
215 if( tga.colorMapType == 0 )
216 {
217 rawPalette = 0;
218 rawPaletteSize = 0;
219 }
220 else
221 {
222
223 // a palette may be present even if not used by the image (e.g., TIPS prog. p. 867)
224 // in this case, account for the palette size but don't save the palette data
225 rawPalette = 0;
226 if( (tga.imageType == 1) || (tga.imageType == 9) ) // palette is used by image
227 {
228 rawPalette = ( rawBits + rawHeaderSize );
229 }
230
231 rawPaletteSize = (u32)tga.cMapDepth * (u32)tga.cMapLength;
232 }
233
234
235 // image (if present) follows the palette
236 if( (tga.width == 0) || (tga.height == 0) || (tga.pixelDepth == 0) )
237 {
238 rawImage = 0;
239 tgaImageSize = 0;
240 }
241 else
242 {
243 rawImage = ( rawBits + rawHeaderSize + rawPaletteSize );
244 tgaImageSize = tga.width * tga.height * tga.pixelDepth;
245 }
246
247
248 // data buffers must be allocated before decompression is performed
249
250 if( rawPalette != NULL )
251 {
252 tga.paletteDataSize = rawPaletteSize;
253 tga.paletteData = (u8*)calloc( 1, rawPaletteSize );
254
255 // copy the complete palette as is to 'tga->paletteData'
256 for(i=0; i<rawPaletteSize; i++)
257 {
258 *(u8*)( tga.paletteData + i ) = *(u8*)( rawPalette + i );
259 }
260 }
261
262
263 if( rawImage != NULL )
264 {
265
266 tga.imageDataSize = tgaImageSize;
267 tga.imageData = (u8*)calloc( 1, tgaImageSize );
268
269 // image simplification section
270
271 // if this image is compressed (RLE), uncompress it into tga->imageData
272 UncompressTgaImage( rawImage, &tga );
273
274 // if the tga file contains a palette and a cMapStart offset, adjust the image data values
275 // to include this offset
276 AdjustTgaForPaletteOffset( tga.imageData, &tga, cMapStart );
277
278 // orient the now un-encoded image data so that its origin is the upper left
279 // corner of the screen.
280 OrientUncompressedTgaData( tga.imageData, tga.width, tga.height,
281 tga.pixelDepth, imageDesc );
282
283 }
284
285 // create layer components of dfPtr from tga raw image and palette
286 CreateTgaColorLayer( dfPtr, &tga );
287 CreateTgaAlphaLayer( dfPtr, &tga );
288 CreateTgaPalTable( dfPtr, &tga );
289
290 // free tga memory when done
291 if( tga.imageData != NULL )
292 {
293 free( tga.imageData );
294 tga.imageData = NULL;
295 }
296
297 if( tga.paletteData != NULL )
298 {
299 free( tga.paletteData );
300 tga.paletteData = NULL;
301 }
302
303 return 1;
304 }
305
306 //-----------------------------------------------------------------------
307
308
309 // the simplified .tga file resides in 'tga'
310 // separate out the color information and place it in the color layer's buffer
CreateTgaColorLayer(TCFilePtr dfPtr,SimpleTga * tga)311 static void CreateTgaColorLayer( TCFilePtr dfPtr, SimpleTga* tga )
312 {
313 u8* pixelPtr;
314 u8 g, b;
315 u16 r, u16Tmp;
316 u32 row, col;
317 u32 type;
318 TCLayer* newLayer;
319
320
321
322 // allocate a color layer
323 dfPtr->lyColor = TCCreateLayer();
324 newLayer = dfPtr->lyColor;
325
326
327 // determine the data format for the layer buffer
328 // (make 'best fit' from .tga to layer color formats)
329
330 // only 3 image types possible for a simplified tga image
331 // ( color-index, monochrome, rgb (rgba) ).
332 switch( tga->imageType )
333 {
334 case 1: type = LY_IMAGE_COLOR_CI16; break; // color-index
335 case 2: type = LY_IMAGE_COLOR_RGB24; break; // truecolor
336 case 3: type = LY_IMAGE_COLOR_RGB24; break; // monochrome
337 }
338
339 // 1 LOD only from a tga file
340 TCSetLayerAttributes( newLayer, type, tga->width, tga->height );
341
342
343 // allocate a data buffer for this layer
344 if( (newLayer->data = TCSetLayerBuffer(newLayer)) == 0 )
345 {
346 TCErrorMsg( "CreateImageColorLayerFromTga(): couldn't allocate layer buffer\n" );
347 return;
348 }
349
350
351 // get ria, g, b values from 'tga' structure; set layer pixel values individually
352
353 pixelPtr = tga->imageData;
354
355 for(row=0; row<tga->height; row++)
356 {
357 for(col=0; col<tga->width; col++)
358 {
359
360 switch(tga->imageType)
361 {
362 case 1: // colormapped image data
363
364 switch(tga->pixelDepth)
365 {
366 case 1: r = (u16)(*pixelPtr); break;
367
368 case 2: r = (u16)( *(u16*)pixelPtr ); break;
369
370 default:
371 TCErrorMsg( "CreateImageColorLayerFromTga(): unknown pixel depth for file %s colormapped data\n", dfPtr->name );
372 return;
373 break;
374 }
375
376 break;
377
378 case 2: // truecolor image data
379
380 switch(tga->pixelDepth)
381 {
382 case 2:
383 u16Tmp = *(u16*)pixelPtr;
384 // duplicate msbs to maintain full range
385 r = (u16)( ((u16Tmp & 0x7C00) >> 7) | ((u16Tmp & 0x7000) >> 12) );
386 g = (u8)( ((u16Tmp & 0x03E0) >> 2) | ((u16Tmp & 0x0380) >> 7) );
387 b = (u8)( ((u16Tmp & 0x001F) << 3) | ((u16Tmp & 0x001C) >> 2) );
388 break;
389
390 case 3: // fall through
391 case 4: // for 4, ignore alpha value (pixelPtr + 3)
392
393 r = (u16)( *(pixelPtr + 2) );
394 g = *(pixelPtr + 1);
395 b = *pixelPtr;
396 break;
397
398 default:
399 TCErrorMsg( "CreateImageColorLayerFromTga(): unknown pixel depth for file %s data\n", dfPtr->name );
400 return;
401 break;
402 }
403
404 break;
405
406 case 3: // monochrome image data- set to rgb
407 // if pixel depth > 1, use the average of three color values
408
409 switch(tga->pixelDepth)
410 {
411 case 1:
412
413 r = (u16)(*pixelPtr);
414 g = (u8)r;
415 b = (u8)r;
416 break;
417
418 case 2:
419
420 u16Tmp = *(u16*)pixelPtr;
421 // duplicate msbs to maintain full range
422 r = (u16)( ((u16Tmp & 0x7C00) >> 7) | ((u16Tmp & 0x7000) >> 12) );
423 r += (u16)( ((u16Tmp & 0x03E0) >> 2) | ((u16Tmp & 0x0380) >> 7) );
424 r += (u16)( ((u16Tmp & 0x001F) << 3) | ((u16Tmp & 0x001C) >> 2) );
425 r /= 3;
426 g = (u8)r;
427 b = (u8)r;
428 break;
429
430 case 3: // fall through
431 case 4: // for 4, ignore alpha value (pixelPtr + 3)
432
433 r = (u16)(*(pixelPtr + 2)); // red
434 r += (u16)(*(pixelPtr + 1)); // green
435 r += (u16)(*pixelPtr); // blue
436 r /= 3; // average the 3 color values
437 g = (u8)r;
438 b = (u8)r;
439 break;
440
441 default:
442 TCErrorMsg( "CreateImageColorLayerFromTga(): unknown pixel depth for file %s intensity data\n", dfPtr->name );
443 return;
444 break;
445 }
446
447 break;
448
449 } // end switch( tga->imagetype )
450
451 TCSetLayerValue( newLayer, col, row, r, g, b );
452 pixelPtr += tga->pixelDepth;
453
454 } // end 'col' for loop
455
456 } // end 'row' for loop
457 }
458
459
460 //------------------------------------------------------------------------------------
461
462 // alpha layer can come from either alpha component of rgba (2 or 4 bytes/pixel) image
463 // or from monochrome image
CreateTgaAlphaLayer(TCFilePtr dfPtr,SimpleTga * tga)464 static void CreateTgaAlphaLayer( TCFilePtr dfPtr, SimpleTga* tga )
465 {
466 u8* pixelPtr;
467 u32 row, col;
468 u16 a, u16Tmp;
469 TCLayer* newLayer;
470
471
472 // alpha layer can only be created from the following image types: rgba, monochrome
473
474 if( tga->imageType == 1 ) // color-indexed
475 {
476 return;
477 }
478
479 if( tga->imageType == 2 ) // true color
480 {
481 // only rgba formats are acceptable
482 if( (tga->pixelDepth != 2) && (tga->pixelDepth != 4) )
483 {
484 return;
485 }
486 }
487
488
489 dfPtr->lyAlpha = TCCreateLayer();
490 newLayer = dfPtr->lyAlpha;
491
492 TCSetLayerAttributes( newLayer, LY_IMAGE_ALPHA_A8, tga->width, tga->height );
493 newLayer->data = TCSetLayerBuffer(newLayer);
494
495
496 // set alpha layer pixel values individually;
497 // source could be either the alpha channel of a 4 byte/pixel image, the alpha bit of a 16-bit image,
498 // or color data from a monochrome image
499
500 pixelPtr = (u8*)(tga->imageData);
501 for(row=0; row<tga->height; row++)
502 {
503 for(col=0; col< tga->width; col++)
504 {
505 // fetch, convert and set a pixel
506 switch(tga->imageType)
507 {
508
509 case 2: // truecolor image data
510 // use alpha bits if present
511 switch(tga->pixelDepth)
512 {
513
514 case 2: // 1-bit alpha
515 u16Tmp = *(u16*)pixelPtr;
516
517 a = 0;
518 if( (u16Tmp & 0x8000) == 0x8000 ) // check if alpha bit is set
519 {
520 a = 0x00FF; // (will be converted to u8 value when set)
521 }
522 break;
523
524 case 4: // use the 8-bit alpha channel
525 a = (u16)(*(pixelPtr + 3));
526 break;
527 }
528
529 break;
530
531 case 3: // monochrome image data
532 // if an alpha channel is available, use it.
533 // otherwise, average the three color values to obtain alpha.
534
535 switch(tga->pixelDepth)
536 {
537 case 1: // 8-bit monochrome
538 a = (u16)(*pixelPtr);
539 break;
540
541 case 2:
542 u16Tmp = *(u16*)pixelPtr; // 16-bit monochrome- use single alpha bit
543
544 a = 0;
545 if( (u16Tmp & 0x8000) == 0x8000 )
546 {
547 a = 0x00FF;
548 }
549 break;
550
551 case 3: // 24-bit monochrome- average the three color values
552
553 a = (u16)(*(pixelPtr + 2)); // red
554 a += (u16)(*(pixelPtr + 1)); // green
555 a += (u16)(*pixelPtr); // blue
556 a /= 3;
557 break;
558
559 case 4: // 32-bit monochrome- use alpha channel
560
561 a = (u16)(*(pixelPtr + 3));
562 break;
563
564 default:
565 TCErrorMsg( "CreateImageAlphaLayerFromTga(): intensity file %s has unknown pixel depth\n", dfPtr->name );
566 return;
567 break;
568 }
569
570 break;
571
572 } // end switch( tga->imageType )
573
574 TCSetLayerValue( newLayer, col, row, a, 0, 0 );
575 pixelPtr += tga->pixelDepth;
576
577 } // end 'col' for loop
578
579 } // end 'row' for loop
580 }
581
582 //------------------------------------------------------------------------------------
583
CreateTgaPalTable(TCFilePtr dfPtr,SimpleTga * tga)584 static void CreateTgaPalTable( TCFilePtr dfPtr, SimpleTga* tga )
585 {
586 u8 r, g, b, a;
587 u32 i;
588 u8* rawPtr;
589 u16 u16Tmp;
590
591
592 if( tga->paletteData == NULL )
593 {
594 return;
595 }
596
597 dfPtr->palPtr = (TCPalTable*)TCCreatePalTable( tga->cMapLength );
598
599 rawPtr = tga->paletteData;
600
601 for(i=0; i< tga->cMapLength; i++ )
602 {
603
604 switch( tga->cMapDepth )
605 {
606
607 case 2: // 15 or 16-bit case
608
609 u16Tmp = *(u16*)rawPtr;
610
611 // duplicate msbs to maintain full range
612 r = (u8)( ((u16Tmp & 0x7C00) >> 7) | ((u16Tmp & 0x7000) >> 12) );
613 g = (u8)( ((u16Tmp & 0x03E0) >> 2) | ((u16Tmp & 0x0380) >> 7 ) );
614 b = (u8)( ((u16Tmp & 0x001F) << 3) | ((u16Tmp & 0x001C) >> 2 ) );
615 a = 0;
616 if( (u16Tmp & 0x8000) == 0x0000 )
617 {
618 a = 0xFF;
619 }
620
621 rawPtr += 2;
622 break;
623
624 case 3: // rgb24
625
626 r = *( rawPtr + 2 );
627 g = *( rawPtr + 1 );
628 b = *( rawPtr );
629 a = 0xFF;
630
631 rawPtr += 3;
632 break;
633
634 case 4: // rgba
635
636 r = *( rawPtr + 2 );
637 g = *( rawPtr + 1 );
638 b = *( rawPtr );
639 a = *( rawPtr + 3 );
640
641 rawPtr += 4;
642 break;
643 }
644
645 // set this entry value
646 TCSetPalTableValue( dfPtr->palPtr, i, r, g, b, a );
647 }
648
649 }
650
651 //------------------------------------------------------------------------------------
652
653
654
655
656
657
658
659
660
661
662 // .TGA SIMPLIFICATION SECTION
663
664
665
666
667
668
669
670
671
672
673
674
675 //------------------------------------------------------------------------------------
676
677 // if required, decompress an RLE encoded image into pixel data.
678 // place the uncompressed pixel data into dfData
UncompressTgaImage(u8 * rawImage,SimpleTga * tga)679 static void UncompressTgaImage( u8* rawImage, SimpleTga* tga )
680 {
681 u32 i, size;
682 u8* srcPtr, *dstPtr;
683 u8* tmpBuff;
684
685
686 // uncompress the rawImage if needed into a temporary buffer
687 tmpBuff = NULL;
688 switch(tga->imageType)
689 {
690 // uncompressed raw image types; use 'rawImage' as is
691 case 0: // fall through
692 case 1: // fall through
693 case 2: // fall through
694 case 3: // fall through
695
696 srcPtr = rawImage;
697 break;
698 // RLE compressed raw image types
699 case 9: // fall through
700 case 10: // fall through
701 case 11: // fall through
702
703 // compute the size of the uncompressed image
704 size = tga->width * tga->height * tga->pixelDepth;
705 tmpBuff = (u8*)calloc( 1, size );
706
707 UnencodeTgaImage( rawImage, tmpBuff, tga->width, tga->height, tga->pixelDepth );
708
709 srcPtr = tmpBuff;
710 break;
711 }
712
713
714 // copy the uncompressed pixels from 'srcPtr' ('tmpBuff' or 'rawImage') into 'tgaBuffer->imageData'
715 // note: 'tgaBuffer->imageData' must already be allocated
716 size = tga->width * tga->height * tga->pixelDepth;
717 dstPtr = tga->imageData;
718
719 for( i=0; i < size; i++ )
720 {
721 *dstPtr++ = *srcPtr++;
722 }
723
724
725 // remap encoded imageType(s) to un-encoded equivalents
726 // (makes for shorter switch statements in later functions)
727 switch(tga->imageType)
728 {
729 case 9: tga->imageType = 1; break;
730 case 10: tga->imageType = 2; break;
731 case 11: tga->imageType = 3; break;
732 }
733
734 // free uncompressed raw image buffer
735 if( tmpBuff != NULL )
736 {
737 free( tmpBuff );
738 tmpBuff = NULL;
739 }
740
741 }
742
743 //------------------------------------------------------------------------------------
744
745
746 // convert an RLE tga image into an un-encoded image
747 // remove 'count' bytes from image- write data only
748 //
749 // riPtr: pointer to the raw compressed image data
750 // dstPtr: pointer to a buffer large enough to hold the uncompressed image data
751 // width: pixel width of the image
752 // height: pixel height of the image
753 // pixelDepth: pixel depth in bytes
754 //
UnencodeTgaImage(u8 * riPtr,u8 * dstPtr,u32 width,u32 height,u32 pixelDepth)755 static void UnencodeTgaImage( u8* riPtr, u8* dstPtr, u32 width, u32 height, u32 pixelDepth )
756 {
757 u32 i,j;
758 u32 totalCount, maxCount;
759 u32 runLength;
760 u32 riOffset, dstOffset;
761 u8 countByte;
762
763
764 riOffset = 0;
765 dstOffset = 0;
766 totalCount = 0;
767 maxCount = width * height; // total # of pixels in the uncompressed image
768
769
770 // perform read/write until all pixels have been decompressed
771 while(totalCount < maxCount)
772 {
773 // read the count byte
774 countByte = *((u8*)(riPtr + riOffset));
775
776 runLength = (u32)(countByte & 0x7F) + 1; // run length is lower 7 bits + 1 (1 to 128)
777 riOffset += 1; // moves riPtr past countByte to pixel data
778
779 // check high bit for RLE or un-encoded pixel run
780 if( (countByte & 0x80) == 0x80 ) // RLE
781 {
782
783 // read the pixel data out as a repeating run of pixels
784 for(i=0; i<runLength; i++)
785 {
786 for(j=0; j<pixelDepth; j++)
787 {
788 *(dstPtr + dstOffset) = *(riPtr + riOffset + j);
789 dstOffset++;
790 }
791 }
792 totalCount += runLength;
793 riOffset += pixelDepth;
794 }
795
796 else // un-encoded run
797 {
798
799 // read the pixel data out as a straight run of pixels
800 for(i=0; i<runLength; i++)
801 {
802 for(j=0; j<pixelDepth; j++)
803 {
804 *(dstPtr + dstOffset) = *(riPtr + riOffset);
805 dstOffset++;
806 riOffset++;
807 }
808 }
809 totalCount += runLength;
810 }
811
812 } // end while
813 }
814
815 //------------------------------------------------------------------------------------
816
817 // take an un-encoded .tga buffer (pure pixel data-no RLE, no count bytes)
818 // and orient it so that its origin is the upper left corner of the screen
819 // copy the oriented data over top of the original data
OrientUncompressedTgaData(u8 * srcBuff,u32 width,u32 height,u32 pixelDepth,u32 imageDesc)820 static void OrientUncompressedTgaData( u8* srcBuff, u32 width, u32 height, u32 pixelDepth, u32 imageDesc )
821 {
822 u32 i,j,k;
823 u32 size;
824 u8* dstBuff;
825 u8* srcPtr, *dstPtr;
826 s32 origin, dstXstep, dstYstep;
827
828
829 size = width * height * pixelDepth;
830 dstBuff = (u8*)calloc( 1, size );
831
832 origin = ( (imageDesc & 0x30) >> 4); // bits 4 & 5 give source screen origin
833
834 // destination image will have its origin in the upper left corner
835 // source image could have its origin in any of the 4 screen corners
836
837 // note: for origins with x on the right, must be careful not to copy
838 // multi-byte pixels out backwards!!
839
840 // pixels will always be written 'forwards' (dstPtr++), so dstXstep is the number of
841 // bytes needed to move to the start of the next pixel in x, and dstYstep is the
842 // number of bytes needed to relocate dstPtr from its final write position
843 // to the start of the first pixel of the next successive row.
844
845 switch(origin)
846 {
847 case 0x00: // lower left
848
849 dstPtr = (u8*)(dstBuff + (width * pixelDepth * (height - 1)));
850 dstXstep = pixelDepth;
851 dstYstep = -1 * (width * pixelDepth) * 2;
852 break;
853
854 case 0x01: // lower right
855
856 dstPtr = (u8*)(dstBuff + (width * pixelDepth * height) - pixelDepth);
857 dstXstep = -(s32)pixelDepth;
858 dstYstep = 0;
859 break;
860
861 case 0x02: // upper left
862
863 // srcBuff data is already oriented correctly; no processing required
864 if( dstBuff != NULL )
865 {
866 free( dstBuff );
867 dstBuff = NULL;
868 }
869 return;
870 break;
871
872 case 0x03: // upper right
873
874 dstPtr = (u8*)(dstBuff + (width * pixelDepth) - pixelDepth);
875 dstXstep = -(s32)pixelDepth;
876 dstYstep = ( width * pixelDepth ) * 2;
877 break;
878 }
879
880
881 //-----------------------------------
882
883
884 // copy and re-orient the srcBuff data
885 srcPtr = (u8*)srcBuff;
886 for(i=0; i<height; i++)
887 {
888 for(j=0; j<width; j++)
889 {
890 for(k=0; k<pixelDepth; k++)
891 {
892 *((u8*)(dstPtr + k)) = *srcPtr++;
893 }
894
895 dstPtr += dstXstep;
896 }
897
898 dstPtr += dstYstep;
899 }
900
901 //------------------------------------
902
903 // copy the correctly oriented data overtop of the original source data
904
905 size = width * height * pixelDepth;
906 srcPtr = (u8*)srcBuff;
907 dstPtr = dstBuff;
908 for(i=0; i<size; i++)
909 {
910 *srcPtr++ = *dstPtr++;
911 }
912
913 //------------------------------------
914
915 if( dstBuff != NULL )
916 {
917 free( dstBuff );
918 dstBuff = NULL;
919 }
920 }
921
922 //------------------------------------------------------------------------------------
923
924 // used only for color-mapped images of 8 or 16 bpp with a non-zero cMapStart value
925 // in case an image has an offset (cMapStart) into its palette, actual image data values
926 // will be (realValue - cMapStart). Update each value so that it equals (image data value + cMapStart).
AdjustTgaForPaletteOffset(u8 * dfData,SimpleTga * tga,u16 cMapStart)927 static void AdjustTgaForPaletteOffset( u8* dfData, SimpleTga* tga, u16 cMapStart )
928 {
929 u32 i, j;
930 void* vPtr;
931
932
933 if( cMapStart == 0 )
934 {
935 return;
936 }
937
938 // make sure this is a color-indexed image
939 if( (tga->imageType != 1) && (tga->imageType != 9) )
940 {
941 return;
942 }
943
944 // accept only 8 or 16 bit indices
945 if( (tga->pixelDepth != 1) && (tga->pixelDepth != 2) )
946 {
947 TCErrorMsg( "AdjustTgaForPaletteOffset(): unsupported pixel depth\n" );
948 return;
949 }
950
951
952 vPtr = (void*)( tga->imageData );
953
954 for(i=0; i< tga->height; i++)
955 {
956 for(j=0; j< tga->width; j++)
957 {
958
959 if(tga->pixelDepth == 1)
960 {
961 *(u8*)vPtr = (u8)( *(u8*)(vPtr) + cMapStart);
962 vPtr = (u8*)vPtr + 1;
963 }
964
965 else if(tga->pixelDepth == 2)
966 {
967 *(u16*)(vPtr) = (u16)( *(u16*)(vPtr) + cMapStart);
968 vPtr = (u8*)vPtr + 2;
969 }
970
971 }
972 }
973 }
974
975 //-----------------------------------------------------------------------------------------------
976
977
978