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