1 /*---------------------------------------------------------------------*
2 Project:  tc library
3 File:     TCCreateDDS.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: TCCreateS3.cpp,v $
16  Revision 1.1  2006/02/17 09:01:53  mitu
17  1st version
18 
19 
20     2    4/11/01 3:08p John
21     Updated header copyrights and pathname.
22 
23     1     4/03/00 5:39p Mikepc
24     replaces TCCreateDDS.cpp
25     contains code to convert TCLayers to compressed S3_TEXTURE
26 
27     2     2/21/00 1:56p Mikepc
28     changed file to use newest (02/21/2000) version of s3tc.lib, S3_intrf.h
29     and s3_ddraw.h
30     1) changed #include from "s3_intrf.h" to "S3_intrf.h"
31     2) added #include <string.h> for 'memset()' call
32      ( formerly included in ddraw.h )
33     3) removed 1 flag (DDSD_ALPHABITDEPTH) from 'ddsRGB.dwFlags' in
34     TCConvertToDDS.  This flag is not defined by s3_ddraw.h
35 
36     1     12/03/99 3:45p Ryan
37 
38     17    11/15/99 6:32p Mikepc
39     line 97:  changed color weights for s3 compression from 1/3 for each of
40     r,g,b to values more representative of intensity.
41 
42     16    10/12/99 10:17p Howardc
43     setup system/local includes correctly
44 
45     15    10/12/99 8:01p Mikepc
46     changed include paths to vcc (tools/options) relative.
47 
48     14    10/08/99 2:45p Mikepc
49     update for tplConv portability: altered data structures, replaced
50     references to 'read tga code' with ' *fileFn, removed redundant
51     functions.  Changed some file conversion paths.
52 
53     13    10/01/99 6:17p Mikepc
54 
55     12    10/01/99 12:20p Mikepc
56     Integrated s3.lib code to generate s3 textures 'on the fly' as direct
57     draw surfaces.  Removed .dds file reading code.  Changed CMP texture
58     generation 'order of operations' to- rgb layer->s3->CMPR format per
59     mipmap LOD.
60 
61     11    9/17/99 4:42p Mikepc
62     ConvSi2Dds(): added a 'multiple of 4' dimension check to tga file
63     before conversion to dds file.
64 
65     10    9/16/99 8:47p Mikepc
66     updated code for auto-palette generation
67 
68     9     9/02/99 11:12a Mikepc
69     some code re-organization between files.
70     added code (verify.cpp) to invoke s3tc.exe from within tc program.
71     changed some routines to accommodate the new texture creation path.
72 
73     8     8/30/99 5:07p Mikepc
74     changes to dds/cmp processing code to allow odd sized images and images
75     smaller than 8x8 texel.
76 
77     7     8/26/99 4:59p Mikepc
78     renamed file extensions from .c to .cpp.
79     .cpp extension allows addition of namespace protection to remove
80     potential name collisions with tool code.  Exceptions are CreateTplFile
81     and QuickConvert.  These are extern "C" linked.
82 
83     6     8/26/99 11:38a Mikepc
84 
85     5     8/26/99 11:03a Mikepc
86     tplCon rewrite for efficient memory usage, batch file processing
87     ability.
88 
89  $NoKeywords: $
90 
91 -----------------------------------------------------------------------*/
92 
93 #include<string.h>  // for memset()
94 
95 #include <charPipeline/tc/TCCommon.h>
96 
97 #include "TCCreateS3.h"
98 #include "TCMem.h"
99 #include "TCLayerInternal.h"
100 #include "S3_intrf.h"
101 
102 
103 /*>*******************************(*)*******************************<*/
104 // convert an rgb and alpha layer to a cmp layer using s3.lib.
105 
106 // note: the only cmp alpha we support is 1 bit color key- alphas
107 //       should be either 0 or 255 in the alpha layer
108 /*>*******************************(*)*******************************<*/
TCConvertToS3(TCLayer * lyColor,TCLayer * lyAlpha,TCLayer * lyCmp)109 void TCConvertToS3( TCLayer* lyColor, TCLayer* lyAlpha, TCLayer* lyCmp )
110 {
111 
112     S3_TEXTURE s3RGB, s3CMP;  // input, output s3 textures
113     S3_COLOR*  pClr;
114 	u32 row, col;
115 	u16 r, a;
116 	u8  g, b;
117 	u32 size;
118     s32 ok = 0;
119 
120     // threshold alpha
121     s32 alphaRef   = 1;
122 
123 	// quantization weights for compression.
124 	// note: these are the default weight from S3TC.doc
125 	float redWgt   = 0.3086f;
126     float greenWgt = 0.6094f;
127     float blueWgt  = 0.0820f;
128 
129     // encode with 1-bit alpha
130     u32 encodeFlag = S3TC_ENCODE_RGB_ALPHA_COMPARE;
131 
132 
133 	// zero out structures, then set only the fields we need
134     memset( (void*)(&s3RGB), 0, sizeof(S3_TEXTURE) );
135 	memset( (void*)(&s3CMP), 0, sizeof(S3_TEXTURE) );
136 
137     //-------------------------------------------------------
138 
139 	// combine the color and alpha layers into an rgba s3 texture
140 
141 	s3RGB.lWidth   = lyColor->width;
142 	s3RGB.lHeight  = lyColor->height;
143 	s3RGB.lPitch   = lyColor->width * sizeof(S3_COLOR);
144 
145 	size           = lyColor->width * lyColor->height * sizeof(S3_COLOR);
146 	s3RGB.pSurface = (void*)TCCalloc( 1, size );
147 
148 	// s3RGB.ColorKey;		// color key is unused
149 
150 	s3RGB.PixelFormat.nFlags        =  S3_TF_HASALPHA;
151 	s3RGB.PixelFormat.nARGBBitCount =  32;
152 
153     // pixel masks match rgba packing order of pSurface buffer
154 	// pSurface color is array of u8[4] = {r,g,b,a}. Masks are little-endian.
155     s3RGB.PixelFormat.nRedMask      =  0x000000FF;
156     s3RGB.PixelFormat.nGreenMask    =  0x0000FF00;
157     s3RGB.PixelFormat.nBlueMask     =  0x00FF0000;
158     s3RGB.PixelFormat.nAlphaMask    =  0xFF000000;
159 
160 	// s3RGB.pPalette;		//palette is unused
161 
162     //-------------------------------------------------------
163 
164 	// combine both layers into the pSurface buffer
165 	pClr = (S3_COLOR*)( s3RGB.pSurface );
166 
167 	for( row = 0; row < lyColor->height; row++ )
168 	{
169 		for( col = 0; col < lyColor->width; col++ )
170 		{
171 			TCGetLayerValue( lyColor, col, row, &r, &g, &b );
172 
173 			a = 255;  // if no alpha layer, set a to max.
174 			if( lyAlpha != NULL )
175 			{
176 				TCGetLayerValue( lyAlpha, col, row, &a, NULL, NULL );
177 			}
178 
179 			// pack as S3_COLORs
180             pClr->cRed   = (char)r;
181             pClr->cGreen = (char)g;
182             pClr->cBlue  = (char)b;
183             pClr->cAlpha = (char)a;
184             pClr++;
185 		}
186 	}
187 
188     //-------------------------------------------------------
189 
190 	// create a cmp texture from the rgb texture
191 	// and a cmp color layer from the cmp texture.
192 	// S3TCencode() can compress directly to the layer buffer.
193 
194     // set color weights
195     S3TC_SetColorWeighting( redWgt, greenWgt, blueWgt );
196 
197     // set threshold for alpha compare
198     S3TC_SetAlphaReference( alphaRef );
199 
200 	// get the required buffer size.
201 	// encodeFlag signals 1-bit alpha encoding
202     size = S3TC_GetEncodeSize( s3RGB.lWidth, s3RGB.lHeight, encodeFlag );
203 
204     // set cmp layer attributes
205 	lyCmp->type   = LY_IMAGE_COLOR_CMP;
206     lyCmp->width  = lyColor->width;
207     lyCmp->height = lyColor->height;
208 
209 	// note: set 'data' explicitly ( not with lySetBuffer )
210 	//       to use the size returned by S3TCgetEncodeSize
211 	lyCmp->data = (u8*)TCCalloc( 1, size );
212 
213     // compress the texture
214     ok = S3TC_Encode( &s3RGB, &s3CMP, lyCmp->data, encodeFlag, NULL, NULL, NULL );
215 
216     TCAssertMsg( (ok==0), "error: TCConvertToDDS: s3 encoding failed\n" );
217 
218 	//---------------------------------------------------------------------------
219 
220 	// free the input surface memory
221 	TCFree( (void**)( &s3RGB.pSurface ) );
222 }
223 
224 /*>*******************************(*)*******************************<*/
225