Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
rle.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 : Command & Conquer *
24 * *
25 * $Archive:: /Commando/Code/Library/RLE.cpp $*
26 * *
27 * $Author:: Greg_h $*
28 * *
29 * $Modtime:: 9/24/98 10:05a $*
30 * *
31 * $Revision:: 2 $*
32 * *
33 *---------------------------------------------------------------------------------------------*
34 * Functions: *
35 * RLEEngine::Compress -- Compresses a sequence of bytes. *
36 * RLEEngine::Decompress -- Decompress a sequence of RLE compressed bytes. *
37 * RLEEngine::Line_Compress -- Compress a line of data. *
38 * RLEEngine::Line_Decompress -- Decompresses a line-compressed RLE data sequence. *
39 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
40
41#include "always.h"
42#include "rle.h"
43#include <assert.h>
44#include <stdlib.h>
45
46
47/***********************************************************************************************
48 * RLEEngine::Compress -- Compresses a sequence of bytes. *
49 * *
50 * This routine will compress the sequence of bytes specified by using RLE compression. *
51 * *
52 * INPUT: source -- Pointer to the data to be compressed. *
53 * *
54 * dest -- Pointer to the buffer that will hold the compressed data. *
55 * *
56 * length -- The length of the data to compress. *
57 * *
58 * OUTPUT: Returns with the number of bytes long for the compressed data. *
59 * *
60 * WARNINGS: The compressed data may, in rare instances, be larger than the data it was *
61 * compressing. The worst case is 33% larger. Keep that in mind when supplying *
62 * the destination buffer to this routine. *
63 * *
64 * HISTORY: *
65 * 04/17/1997 JLB : Created. *
66 *=============================================================================================*/
67int RLEEngine::Compress(void const * source, void * dest, int length) const
68{
69 assert(source != NULL);
70 assert(length > 0);
71
72 int outlen = 0;
73 unsigned char const * sptr = (unsigned char const *) source;
74 unsigned char * dptr = (unsigned char *)dest;
75 while (length > 0) {
76
77 /*
78 ** Examine each source byte. If the byte is zero (transparent), then
79 ** it is recorded as a run. Otherwise it is output without translation.
80 */
81 if (*sptr == '\0') {
82
83 /*
84 ** Count the number of transparent pixels in this run.
85 */
86 int runcount = 0;
87 while (sptr[runcount] == '\0' && runcount <= length) {
88 runcount++;
89 }
90
91 /*
92 ** Limit the run to 255 characters maximum.
93 */
94 runcount = MIN(runcount, 255);
95 if (dptr != NULL) {
96 *dptr++ = '\0';
97 *dptr++ = (unsigned char)runcount;
98 }
99 outlen += 2;
100 sptr += runcount;
101 length -= runcount;
102
103 } else {
104
105 /*
106 ** Store the raw byte without any translation.
107 */
108 if (dptr != NULL) {
109 *dptr++ = *sptr++;
110 } else {
111 sptr++;
112 }
113 outlen++;
114 length--;
115 }
116 }
117
118 /*
119 ** Return with the number of compressed output bytes.
120 */
121 return(outlen);
122}
123
124
125/***********************************************************************************************
126 * RLEEngine::Line_Compress -- Compress a line of data. *
127 * *
128 * This routine will compress a sequence of bytes and store the length of the compressed *
129 * data at the beginning of the output buffer. By encoding the compressed size in this *
130 * fashion, it is possible to build a sequence of compressed bytes (such as with a sprite) *
131 * so that each sequence can be quickly traversed. *
132 * *
133 * INPUT: source -- Pointer to the source data to be compressed. *
134 * *
135 * dest -- Pointer to the destination buffer that will hold the length value and *
136 * the compressed data. *
137 * *
138 * length -- The number of source bytes to compress. *
139 * *
140 * OUTPUT: Returns with the number of bytes stored into the output buffer. *
141 * *
142 * WARNINGS: The output data could be larger than the source data by as much as 33% + 2 *
143 * *
144 * HISTORY: *
145 * 04/17/1997 JLB : Created. *
146 *=============================================================================================*/
147int RLEEngine::Line_Compress(void const * source, void * dest, int length) const
148{
149 assert(source != NULL);
150 assert(length > 0);
151
152 /*
153 ** If an output buffer was specified, then the data is actually compressed
154 ** into the buffer.
155 */
156 if (dest != NULL) {
157 unsigned short * sizeptr = (unsigned short *)dest;
158 int complen = Compress(source, sizeptr+1, length) + sizeof(short);
159 *sizeptr = (unsigned short)complen;
160 return(complen);
161 }
162
163 /*
164 ** Since no output buffer was specifed, this call merely determins how
165 ** many bytes would be consumed in the output buffer.
166 */
167 return(Compress(source, NULL, length) + sizeof(short));
168}
169
170
171/***********************************************************************************************
172 * RLEEngine::Decompress -- Decompress a sequence of RLE compressed bytes. *
173 * *
174 * This will decompress a sequence of RLE compressed bytes. *
175 * *
176 * INPUT: source -- Pointer to the RLE compressed data. *
177 * *
178 * dest -- Pointer to the buffer that will hold the uncompressed data. *
179 * *
180 * length -- The length of the source RLE data to process. *
181 * *
182 * OUTPUT: Returns with the actual number of bytes stored into the output buffer. *
183 * *
184 * WARNINGS: The output buffer must be large enough to hold the decompressed data. This *
185 * could be as much as 128 times larger than the source RLE data. *
186 * *
187 * HISTORY: *
188 * 04/17/1997 JLB : Created. *
189 *=============================================================================================*/
190int RLEEngine::Decompress(void const * source, void * dest, int length) const
191{
192 assert(source != NULL);
193 assert(dest != NULL);
194 assert(length > 0);
195
196 unsigned char * dptr = (unsigned char *)dest;
197 unsigned char const * sptr = (unsigned char const *)source;
198
199 /*
200 ** Process the RLE data normally.
201 */
202 while (length > 0) {
203
204 /*
205 ** Detect if a zero-run code is present. If so, then dump the desired
206 ** number of bytes. Otherwise output the pixel in untranslated form.
207 */
208 unsigned char value = *sptr++;
209 length--;
210 if (value == '\0') {
211 int outlen = *sptr++;
212 length--;
213 while (outlen > 0) {
214 *dptr++ = '\0';
215 outlen--;
216 }
217
218 } else {
219 *dptr++ = value;
220 }
221 }
222
223 /*
224 ** Return with the number of bytes stored into the output buffer.
225 */
226 return(dptr - (unsigned char const *)dest);
227}
228
229
230/***********************************************************************************************
231 * RLEEngine::Line_Decompress -- Decompresses a line-compressed RLE data sequence. *
232 * *
233 * This routine is the counterpart to Line_Compress. It will take a compressed line and *
234 * fully decompress it into the destination buffer. *
235 * *
236 * INPUT: source -- The pointer to the line compressed RLE data. *
237 * *
238 * dest -- Pointer to the destination buffer that will hold the decompressed *
239 * data. *
240 * *
241 * OUTPUT: Returns with the number of bytes stored into the destination buffer. *
242 * *
243 * WARNINGS: none *
244 * *
245 * HISTORY: *
246 * 04/17/1997 JLB : Created. *
247 *=============================================================================================*/
248int RLEEngine::Line_Decompress(void const * source, void * dest) const
249{
250 assert(source != NULL);
251 assert(dest != NULL);
252
253 unsigned short const * sptr = (unsigned short const *)source;
254
255 int datalen = *sptr++;
256
257 /*
258 ** Process the RLE data normally.
259 */
260 return(Decompress(sptr, dest, datalen - sizeof(short)));
261}
262
#define NULL
Definition BaseType.h:92
void const char * value
#define MIN(a, b)
Definition always.h:189
int Compress(void const *source, void *dest, int length) const
Definition rle.cpp:67
int Decompress(void const *source, void *dest, int length) const
Definition rle.cpp:190
int Line_Compress(void const *source, void *dest, int length) const
Definition rle.cpp:147
int Line_Decompress(void const *source, void *dest) const
Definition rle.cpp:248