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