Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
tgatodxt.cpp
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
4**
5** This program is free software: you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation, either version 3 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/***********************************************************************************************
20 *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
21 ***********************************************************************************************
22 * *
23 * Project Name : LevelEdit *
24 * *
25 * $Archive:: /Commando/Code/Tools/LevelEdit/TGAToDXT.cpp $*
26 * *
27 * Author:: Ian Leslie *
28 * *
29 * $Modtime:: 8/29/01 5:35p $*
30 * *
31 * $Revision:: 4 $*
32 * *
33 *---------------------------------------------------------------------------------------------*
34 * Functions: *
35 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
36
37#pragma message ("(gth) disabling TGAtoDXTClass temporarily so I can test the WW libs merge...")
38#if 0
39
40#include "always.h"
41#include "nvdxtlib.h"
42#include "targa.h"
43#include "tgatodxt.h"
44#include "wwdebug.h"
45#include <io.h>
46#include <stdlib.h>
47
48// Singletons.
49TGAToDXTClass _TGAToDXTConverter;
50
51
53//
54// TGAToDXTClass
55//
57TGAToDXTClass::TGAToDXTClass()
58 : WriteTimePtr (NULL),
59 BufferSize (1024),
60 BufferCount (0)
61{
62 Buffer = new unsigned char [BufferSize];
63 WWASSERT (Buffer != NULL);
64}
65
66
68//
69// ~TGAToDXTClass
70//
72TGAToDXTClass::~TGAToDXTClass()
73{
74 // Clean-up.
75 delete [] Buffer;
76}
77
78
80//
81// Convert
82//
84TGAToDXTClass::ErrorCode TGAToDXTClass::Convert (const char *inputpathname, const char *outputpathname, FILETIME *writetimeptr, bool &redundantalpha, bool dontcheckalpha)
85{
86 ErrorCode error_code;
87 Targa targa;
88 long error;
89
90 WriteTimePtr = writetimeptr;
91 redundantalpha = false;
92
93 error_code=TGA_LOAD_ERROR;
94 error = targa.Load (inputpathname, TGAF_IMAGE, false);
95 if (error == 0) {
96
97 bool validbitdepth, validsize, validaspect;
98
99 // Check that the targa is in the right format.
100 // In order to be valid it must adhere to the following:
101 // 1. Pixel depth must be 24 or 32 (compressor has no support for lower bit depths) or 8-bit not paletted
102 // 2. Dimensions >= 4 (DDS block size is 4x4).
103 // 3. Aspect ratio <= 1:8 (some H/W will not render textures above this ratio).
104 // 4. Dimensions must be power of 2 (see below).
105 validbitdepth = ((targa.Header.PixelDepth == 24) || (targa.Header.PixelDepth == 32)
106 || ( (targa.Header.PixelDepth == 8) && (targa.Header.ColorMapType != 1) ) );
107 validsize = (targa.Header.Width >= 4) && (targa.Header.Height >= 4);
108 validaspect = ((float) MAX (targa.Header.Width, targa.Header.Height)) / ((float) MIN (targa.Header.Width, targa.Header.Height)) <= 8.0f;
109
110 if (validbitdepth && validsize && validaspect) {
111
112 unsigned char *byte;
113 HRESULT errorcode;
114
115 targa.YFlip();
116
117 // If TGA has an alpha channel...
118 if (targa.Header.PixelDepth == 32) {
119
120 // Analyse the alpha channel and ignore it if it contains redundant data (ie. is either all black or all white).
121 if (!dontcheckalpha) {
122 byte = (unsigned char*) targa.GetImage();
123 if ((*(byte + 3) == 0x00) || (*(byte + 3) == 0xff)) {
124
125 const unsigned char alpha = *(byte + 3);
126
127 redundantalpha = true;
128 for (unsigned p = 0; p < ((unsigned) targa.Header.Width) * ((unsigned) targa.Header.Height); p++) {
129 redundantalpha &= (*(byte + 3) == alpha);
130 byte += 4;
131 }
132 }
133 }
134
135 if (!redundantalpha) {
136
137 errorcode = ::nvDXTcompress ((unsigned char*) targa.GetImage(), targa.Header.Width, targa.Header.Height, TF_DXT5, true, false, 4);
138
139 } else {
140
141 unsigned char *nonalphaimage, *nonalphabyte;
142
143 // Remove the alpha channel and swizel the pixel data.
144 nonalphaimage = new unsigned char [3 * ((unsigned) targa.Header.Width) * ((unsigned) targa.Header.Height)];
145 nonalphabyte = nonalphaimage;
146
147 byte = (unsigned char*) targa.GetImage();
148 for (unsigned p = 0; p < ((unsigned) targa.Header.Width) * ((unsigned) targa.Header.Height); p++) {
149
150 *(nonalphabyte + 0) = *(byte + 0);
151 *(nonalphabyte + 1) = *(byte + 1);
152 *(nonalphabyte + 2) = *(byte + 2);
153 nonalphabyte += 3;
154 byte += 4;
155 }
156
157 errorcode = ::nvDXTcompress (nonalphaimage, targa.Header.Width, targa.Header.Height, TF_DXT1, true, false, 3);
158 delete [] nonalphaimage;
159 }
160
161 } else if (targa.Header.PixelDepth == 8) {
162 // 8-bit luminance
163 unsigned char *image;
164
165 // convert to 24-bit monochrome
166 image = new unsigned char [3 * ((unsigned) targa.Header.Width) * ((unsigned) targa.Header.Height)];
167
168 byte = (unsigned char*) targa.GetImage();
169 for (unsigned p = 0; p < ((unsigned) targa.Header.Width) * ((unsigned) targa.Header.Height); p++) {
170 image[3*p]=image[3*p+1]=image[3*p+2]=byte[p];
171 }
172
173 errorcode = ::nvDXTcompress (image, targa.Header.Width, targa.Header.Height, TF_DXT1, true, false, 3);
174 delete [] image;
175
176 } else {
177 // 24-bit color
178 errorcode = ::nvDXTcompress ((unsigned char*) targa.GetImage(), targa.Header.Width, targa.Header.Height, TF_DXT1, true, false, 3);
179 }
180
181 // Was the image compressed successfully?
182 // NOTE: Any image that does not have power of 2 dimensions will not be compressed.
183 if (errorcode >= 0) {
184 Write (outputpathname);
185 error_code = OK;
186 } else {
187 error_code = COMPRESSION_ERROR;
188 }
189 } else {
190 if (!validbitdepth) error_code = INVALID_BIT_DEPTH;
191 if (!validsize) error_code = INVALID_SIZE;
192 if (!validaspect) error_code = INVALID_ASPECT_RATIO;
193 }
194 } // error == 0
195
196 return error_code;
197}
198
199
201//
202// Write
203//
205void TGAToDXTClass::Write (const char *outputpathname)
206{
207 HANDLE hfile;
208 DWORD bytecountwritten;
209
210 hfile = ::CreateFile (outputpathname, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0L, NULL);
211 if (hfile != INVALID_HANDLE_VALUE) {
212 LockFile (hfile, 0, 0, BufferCount, 0);
213 WriteFile (hfile, Buffer, BufferCount, &bytecountwritten, NULL);
214 UnlockFile (hfile, 0, 0, BufferCount, 0);
215
216 // Stamp the write time (if one has been supplied).
217 if (WriteTimePtr != NULL) {
218 SetFileTime (hfile, NULL, NULL, WriteTimePtr);
219 }
220
221 CloseHandle (hfile);
222 }
223
224 // Reset buffer.
225 BufferCount = 0;
226}
227
228
230//
231// ReadDTXnFile
232//
234void ReadDTXnFile (DWORD datacount, void *data)
235{
236 // Not implemented.
237 WWASSERT (false);
238}
239
240
242//
243// WriteDTXnFile
244//
246void WriteDTXnFile (DWORD datacount, void *data)
247{
248 // Ensure that the buffer is large enough.
249 if (_TGAToDXTConverter.BufferSize < _TGAToDXTConverter.BufferCount + datacount) {
250
251 unsigned newbuffersize;
252 unsigned char *newbuffer;
253
254 newbuffersize = MAX (_TGAToDXTConverter.BufferSize * 2, _TGAToDXTConverter.BufferCount + datacount);
255 newbuffer = new unsigned char [newbuffersize];
256 WWASSERT (newbuffer != NULL);
257 memcpy (newbuffer, _TGAToDXTConverter.Buffer, _TGAToDXTConverter.BufferCount);
258 delete [] _TGAToDXTConverter.Buffer;
259 _TGAToDXTConverter.Buffer = newbuffer;
260 _TGAToDXTConverter.BufferSize = newbuffersize;
261 }
262
263 // Write new data to buffer.
264 memcpy (_TGAToDXTConverter.Buffer + _TGAToDXTConverter.BufferCount, data, datacount);
265 _TGAToDXTConverter.BufferCount += datacount;
266}
267
268
269#endif
#define NULL
Definition BaseType.h:92
ErrorCode
Definition Errors.h:58
#define WWASSERT
#define TGAF_IMAGE
Definition TARGA.H:112
#define MIN(a, b)
Definition always.h:189
#define MAX(a, b)
Definition always.h:185
unsigned long DWORD
Definition bittype.h:57
Definition BUFF.H:57
Definition TARGA.H:260
TGAHeader Header
Definition TARGA.H:287
void YFlip(void)
Definition TARGA.CPP:870
long Load(const char *name, char *palette, char *image, bool invert_image=true)
Definition TARGA.CPP:354
char * GetImage(void) const
Definition TARGA.H:278