1 /*---------------------------------------------------------------------*
2 Project:  tc library
3 File:     TCImageList.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: TCImageList.cpp,v $
16  Revision 1.1  2006/02/17 09:01:53  mitu
17  1st version
18 
19 
20     6    4/11/01 3:08p John
21     Updated header copyrights and pathname.
22 
23     5     3/09/01 2:49p John
24     Added TCSetImageWrap.  Added ability to specify wrapS and wrapT mode
25     using TCS script file.
26 
27     4     8/10/00 6:02p Mikepc
28     removed redundant #include<assert.h>,
29     changed any remaining asserts to TCAssertMsg
30 
31     3     4/10/00 2:09p Mikepc
32     fixed mipmap total # lod bug
33 
34     2     3/17/00 1:19p Mikepc
35     change tc to use indices numbered from 0.
36 
37     1     12/03/99 3:45p Ryan
38 
39     15    10/12/99 11:38a Mikepc
40     fixed a bug in imNew() - image alpha layer received an invalid pointer
41     if imageSrcAlpha was not 0 but file contained no alpha info.
42 
43     14    10/08/99 2:45p Mikepc
44     update for tplConv portability: altered data structures, replaced
45     references to 'read tga code' with ' *fileFn, removed redundant
46     functions.  Changed some file conversion paths.
47 
48     13    9/17/99 12:18p Mikepc
49     arbitrary palette size has been removed- changed RemapColors() to
50     RemapImageColors() and modified code to work only with 8-bit palettes
51 
52     12    9/16/99 8:47p Mikepc
53     updated code for auto-palette generation
54 
55     11    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     10    8/26/99 11:38a Mikepc
62 
63     9     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 #include <charPipeline/tc/TCCommon.h>
72 
73 #include "TCImageList.h"
74 #include "TCSrcImageList.h"
75 #include "TCLayerInternal.h"
76 #include "TCFileInternal.h"
77 #include "TCMem.h"
78 #include "TCGXDefs.h"
79 
80 /********************************/
81 // global Image linked list
82 TCImage* ImHead = NULL;
83 
84 /*>*******************************(*)*******************************<*/
85 static void TCSwapImage	( TCImage* src, TCImage* dst );
86 
87 /*>*******************************(*)*******************************<*/
88 // set image layer values from a tga file
89 /*>*******************************(*)*******************************<*/
TCSetImageValues(void)90 void TCSetImageValues ( void )
91 {
92 	TCSrcImage*      siPtr;
93 	TCImage*         imPtr;
94 	TCLayer*         lyPtr;
95 	TCFilePtr		 dfPtr;
96 
97 
98 	imPtr = ImHead;
99 	while( imPtr )
100 	{
101     	// find and decode this image's source file
102     	siPtr = TCFindSrcImageByIndex( imPtr->colorSrcImage );
103     	dfPtr = TCReadFile( siPtr->fileName );
104 
105     	// set color layer attributes
106     	lyPtr         = &(imPtr->lyColor);
107     	lyPtr->type   = dfPtr->lyColor->type;
108     	lyPtr->width  = dfPtr->lyColor->width;
109     	lyPtr->height = dfPtr->lyColor->height;
110     	lyPtr->data   = NULL;
111 
112     	// alpha layer attributes
113     	if( imPtr->alphaSrcImage != TC_UNUSED )
114     	{
115     		// if alpha layer comes from a different source, fetch another file
116     		if( imPtr->colorSrcImage != imPtr->alphaSrcImage )
117     		{
118     			siPtr = TCFindSrcImageByIndex( imPtr->alphaSrcImage );
119     			dfPtr = TCReadFile( siPtr->fileName );
120     		}
121 
122     		// check that alpha layer is present
123     		TCAssertMsg( (dfPtr->lyAlpha != NULL), "ImNew: no alpha layer in file %s for image %d\n", dfPtr->name, imPtr->index );
124 
125     		// set alpha layer attributes
126     		lyPtr         = &(imPtr->lyAlpha);
127     		lyPtr->type   = dfPtr->lyAlpha->type;
128     		lyPtr->width  = dfPtr->lyAlpha->width;
129     		lyPtr->height = dfPtr->lyAlpha->height;
130     		lyPtr->data   = NULL;
131 
132     	}
133 
134     	imPtr = imPtr->next;
135 
136 	} // end while ( imPtr );
137 
138 }
139 
140 /*>*******************************(*)*******************************<*/
TCNewImage(void)141 TCImage* TCNewImage ( void )
142 {
143 	TCImage* newIm, *tail;
144 
145 
146 	newIm = (TCImage*)TCCalloc( 1, sizeof(TCImage) );
147 
148 
149 	if( ImHead == NULL )
150 	{
151 		ImHead = newIm;
152 	}
153 	else
154 	{
155 		tail = ImHead;
156 		while( tail->next )
157 		{
158 			tail = tail->next;
159 		}
160 
161 		tail->next  = newIm;
162 		newIm->prev = tail;
163 		newIm->next = NULL;
164 	}
165 
166 	return newIm;
167 }
168 
169 /*>*******************************(*)*******************************<*/
TCSetImageIndex(TCImage * im,u32 index)170 void TCSetImageIndex ( TCImage* im, u32 index )
171 {
172 
173     TCAssertMsg( (index != TC_UNUSED), "TCSetImageIndex: invalid image index %d\n", index );
174     TCAssertMsg( (im != NULL),         "TCSetImageIndex: NULL image ptr for image %d\n", index );
175 
176 	im->index = index;
177 }
178 
179 /*>*******************************(*)*******************************<*/
TCSetImageLayerAtt(TCImage * im,u32 colorLayer,u32 alphaLayer)180 void TCSetImageLayerAtt ( TCImage* im, u32 colorLayer, u32 alphaLayer )
181 {
182 
183     TCAssertMsg( (im != NULL), "TCSetImageLayerAtt: NULL image ptr\n" );
184 
185 
186 	// color layer is mandatory; alpha is optional (may be TC_UNUSED)
187 
188 	// note:  if im->index is not already set, the printed index
189 	//        in the error message will be wrong
190     TCAssertMsg( (colorLayer != TC_UNUSED), "TCSetImageLayerAtt: invalid color layer %d for image %d\n", colorLayer, im->index );
191 
192 	im->colorSrcImage = colorLayer;
193 	im->alphaSrcImage = alphaLayer;
194 }
195 
196 /*>*******************************(*)*******************************<*/
TCSetImageWrap(TCImage * im,u32 wrapS,u32 wrapT)197 void TCSetImageWrap ( TCImage* im, u32 wrapS, u32 wrapT )
198 {
199 
200     TCAssertMsg( (im != NULL), "TCSetImageWrap: NULL image ptr\n" );
201 
202 	// wrapS and wrapT are optional.
203 	im->wrapS = wrapS;
204 	im->wrapT = wrapT;
205 }
206 
207 /*>*******************************(*)*******************************<*/
TCSetImageTexelFormat(TCImage * im,u32 texelFmt)208 void TCSetImageTexelFormat ( TCImage* im, u32 texelFmt )
209 {
210 
211     TCAssertMsg( (im != NULL), "TCSetImageTexelFormat: NULL image ptr\n" );
212 
213 
214 	switch( texelFmt )
215 	{
216 	case TPL_IMAGE_TEXEL_FMT_I4:				// fall through
217 	case TPL_IMAGE_TEXEL_FMT_I8:
218 	case TPL_IMAGE_TEXEL_FMT_IA4:
219 	case TPL_IMAGE_TEXEL_FMT_IA8:
220 
221 	case TPL_IMAGE_TEXEL_FMT_CI4:
222 	case TPL_IMAGE_TEXEL_FMT_CI8:
223 	case TPL_IMAGE_TEXEL_FMT_CI14_X2:
224 
225 	case TPL_IMAGE_TEXEL_FMT_R5G6B5:
226 	case TPL_IMAGE_TEXEL_FMT_RGB5A3:
227 	case TPL_IMAGE_TEXEL_FMT_RGBA8:
228 
229 	case TPL_IMAGE_TEXEL_FMT_CMP:
230 
231 		im->texelFormat = texelFmt;
232 		break;
233 
234 	default:
235 		// note: if im->index is not set, this message will print an incorrect value
236 		TCErrorMsg( "TCSetImageTexelFormat: invalid texel format %d for image %d\n", texelFmt, im->index );
237 		break;
238 	}
239 }
240 
241 /*>*******************************(*)*******************************<*/
242 // set mipmap LODs
243 // note:  range check is based on fn params only; whether actual image
244 //        data can support this range is not checked until mipmap creation.
245 /*>*******************************(*)*******************************<*/
TCSetImageMipMap(TCImage * im,u32 minLOD,u32 maxLOD,u32 baseLOD)246 void TCSetImageMipMap ( TCImage* im, u32 minLOD, u32 maxLOD, u32 baseLOD )
247 {
248     u32 numLOD;
249 
250 
251     TCAssertMsg( (im != NULL), "TCSetImageMipMap: NULL image ptr\n" );
252 
253 	// check LOD ranges
254     if( (minLOD > 10) || (maxLOD > 10) )
255     {
256         TCErrorMsg( "TCSetImageMipMap: invalid LOD range for image %d\n", im->index );
257     }
258 
259     if( minLOD > maxLOD )
260     {
261         TCErrorMsg( "TCSetImageMipMap: invalid LOD range for image %d\n", im->index );
262     }
263 
264     numLOD = maxLOD - minLOD + 1;
265     if( baseLOD + numLOD > 11 )
266     {
267         TCErrorMsg( "TCSetImageMipMap: invalid LOD range for image %d\n", im->index );
268     }
269 
270     // set values
271     im->minLOD      = minLOD;
272 	im->maxLOD      = maxLOD;
273 	im->remapMinLOD = baseLOD;
274 }
275 
276 
277 /*>*******************************(*)*******************************<*/
278 // sort image list in ascending order by index
279 /*>*******************************(*)*******************************<*/
TCSortImageByIndex(void)280 void TCSortImageByIndex ( void )
281 {
282 	TCImage* thisIm, *nextIm;
283 
284 
285     // empty or single-node list (already sorted)
286 	if( (ImHead == NULL) || (ImHead->next == NULL) )
287 	{
288 		return;
289 	}
290 
291 	thisIm = ImHead;
292 	while( thisIm->next )
293 	{
294 		nextIm = thisIm->next;
295 
296 		if( nextIm->index < thisIm->index )
297 		{
298 			// swap just the data, not the pointers
299 			TCSwapImage( thisIm, nextIm );
300 
301 			thisIm = ImHead;
302 			continue;
303 		}
304 
305 		thisIm = thisIm->next;
306 	}
307 }
308 
309 /*>*******************************(*)*******************************<*/
310 // swap just the data members, not the linked list pointers
311 /*>*******************************(*)*******************************<*/
TCSwapImage(TCImage * src,TCImage * dst)312 static void TCSwapImage( TCImage* src, TCImage* dst )
313 {
314 	TCImage  imTmp;
315 	TCImage* saveSrcPrev = src->prev;
316 	TCImage* saveSrcNext = src->next;
317 	TCImage* saveDstPrev = dst->prev;
318 	TCImage* saveDstNext = dst->next;
319 
320 
321     // src->tmp
322     TCCopyImage ( src, &imTmp );
323 
324     // dst->src
325     TCCopyImage( dst, src );
326 	src->prev = saveSrcPrev;
327 	src->next = saveSrcNext;
328 
329     // src(tmp)->dst
330     TCCopyImage( &imTmp, dst );
331 	dst->prev = saveDstPrev;
332 	dst->next = saveDstNext;
333 
334 }
335 
336 /*>*******************************(*)*******************************<*/
337 // copy an entire image including the Layer members and linked list
338 // pointers
339 /*>*******************************(*)*******************************<*/
TCCopyImage(TCImage * src,TCImage * dst)340 void TCCopyImage ( TCImage* src, TCImage* dst )
341 {
342 	u32 i;
343     u8* sPtr = (u8*)src;
344     u8* dPtr = (u8*)dst;
345 
346 
347 	for( i=0; i < sizeof(TCImage); i++ )
348 	{
349 		*dPtr++ = *sPtr++;
350 	}
351 }
352 
353 /*>*******************************(*)*******************************<*/
TCFindImageByIndex(u32 index)354 TCImage* TCFindImageByIndex ( u32 index )
355 {
356 	TCImage* imTmp;
357 
358 
359     if( index == TC_UNUSED )
360         return NULL;
361 
362 	imTmp = ImHead;
363 	while( imTmp )
364 	{
365 		if( imTmp->index == index )
366 		{
367 			return imTmp;
368 		}
369 		imTmp = imTmp->next;
370 	}
371 
372     TCErrorMsg( "TCFindImageByIndex: image %d is not part of image list\n", index );
373 	return NULL;
374 }
375 
376 /*>*******************************(*)*******************************<*/
377 // find the position of an image relative to the list head;
378 // this corresponds to its 'array' index (assume a sorted list)
379 /*>*******************************(*)*******************************<*/
TCFindImagePos(TCImage * im)380 u32 TCFindImagePos( TCImage* im )
381 {
382     TCImage* imPtr;
383     u32      pos;
384 
385 
386     TCAssertMsg( (im != NULL),     "TCFindImagePos: NULL image ptr\n"  );
387     TCAssertMsg( (ImHead != NULL), "TCFindImagePos: NULL image list\n" );
388 
389     pos   = 0;
390     imPtr = ImHead;
391     while( imPtr )
392     {
393         if( im == imPtr )
394         {
395             return pos;
396         }
397 
398         pos++;
399         imPtr = imPtr->next;
400     }
401 
402     TCErrorMsg( "TCFindImagePos: image %d is not part of image list\n", im->index );
403     return 0;
404 }
405 
406 /*>*******************************(*)*******************************<*/
407