LZWSTRAW.CPP (10117B)
1 // 2 // Copyright 2020 Electronic Arts Inc. 3 // 4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 5 // software: you can redistribute it and/or modify it under the terms of 6 // the GNU General Public License as published by the Free Software Foundation, 7 // either version 3 of the License, or (at your option) any later version. 8 9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 10 // in the hope that it will be useful, but with permitted additional restrictions 11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 12 // distributed with this program. You should have received a copy of the 13 // GNU General Public License along with permitted additional restrictions 14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection 15 16 /* $Header: /CounterStrike/LZWSTRAW.CPP 1 3/03/97 10:25a Joe_bostic $ */ 17 /*********************************************************************************************** 18 *** 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 *** 19 *********************************************************************************************** 20 * * 21 * Project Name : Command & Conquer * 22 * * 23 * File Name : LZWSTRAW.CPP * 24 * * 25 * Programmer : Joe L. Bostic * 26 * * 27 * Start Date : 07/02/96 * 28 * * 29 * Last Update : July 4, 1996 [JLB] * 30 * * 31 *---------------------------------------------------------------------------------------------* 32 * Functions: * 33 * LZWStraw::Get -- Fetch data through the LZW processor. * 34 * LZWStraw::LZWStraw -- Constructor for LZW straw object. * 35 * LZWStraw::~LZWStraw -- Destructor for the LZW straw. * 36 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 37 38 #include "lzwstraw.h" 39 #include "lzw.h" 40 #include <string.h> 41 #include <assert.h> 42 43 44 /*********************************************************************************************** 45 * LZWStraw::LZWStraw -- Constructor for LZW straw object. * 46 * * 47 * This will initialize the LZW straw object. Whether the object is to compress or * 48 * decompress and the block size to use is specified. The data is compressed in blocks * 49 * that are sized to be quick to compress and yet still yield good compression ratios. * 50 * * 51 * INPUT: decrypt -- Should the data be decompressed? * 52 * * 53 * blocksize-- The size of the blocks to process. * 54 * * 55 * OUTPUT: none * 56 * * 57 * WARNINGS: It takes two buffers of the blocksize specified if compression is to be * 58 * performed. * 59 * * 60 * HISTORY: * 61 * 07/04/1996 JLB : Created. * 62 *=============================================================================================*/ 63 LZWStraw::LZWStraw(CompControl control, int blocksize) : 64 Control(control), 65 Counter(0), 66 Buffer(NULL), 67 Buffer2(NULL), 68 BlockSize(blocksize) 69 { 70 SafetyMargin = BlockSize; 71 // SafetyMargin = BlockSize/128+1; 72 Buffer = new char[BlockSize+SafetyMargin]; 73 if (control == COMPRESS) { 74 Buffer2 = new char[BlockSize+SafetyMargin]; 75 } 76 } 77 78 79 /*********************************************************************************************** 80 * LZWStraw::~LZWStraw -- Destructor for the LZW straw. * 81 * * 82 * The destructor will free up the allocated buffers that it allocated in the constructor. * 83 * * 84 * INPUT: none * 85 * * 86 * OUTPUT: none * 87 * * 88 * WARNINGS: none * 89 * * 90 * HISTORY: * 91 * 07/04/1996 JLB : Created. * 92 *=============================================================================================*/ 93 LZWStraw::~LZWStraw(void) 94 { 95 delete [] Buffer; 96 Buffer = NULL; 97 98 delete [] Buffer2; 99 Buffer2 = NULL; 100 } 101 102 103 /*********************************************************************************************** 104 * LZWStraw::Get -- Fetch data through the LZW processor. * 105 * * 106 * This routine will fetch the data bytes specified. It does this by first accumulating * 107 * a full block of data and then compressing or decompressing it as indicated. Subsequent * 108 * requests for data will draw from this buffer of processed data until it is exhausted * 109 * and another block must be fetched. * 110 * * 111 * INPUT: destbuf -- Pointer to the buffer to hold the data requested. * 112 * * 113 * length -- The number of data bytes requested. * 114 * * 115 * OUTPUT: Returns with the actual number of bytes stored into the buffer. If this number * 116 * is less than that requested, then this indicates that the data source has been * 117 * exhausted. * 118 * * 119 * WARNINGS: none * 120 * * 121 * HISTORY: * 122 * 07/04/1996 JLB : Created. * 123 *=============================================================================================*/ 124 int LZWStraw::Get(void * destbuf, int slen) 125 { 126 assert(Buffer != NULL); 127 128 int total = 0; 129 130 /* 131 ** Verify parameters for legality. 132 */ 133 if (destbuf == NULL || slen < 1) { 134 return(0); 135 } 136 137 while (slen > 0) { 138 139 /* 140 ** Copy as much data is requested and available into the desired 141 ** destination buffer. 142 */ 143 if (Counter) { 144 int len = (slen < Counter) ? slen : Counter; 145 if (Control == DECOMPRESS) { 146 memmove(destbuf, &Buffer[BlockHeader.UncompCount-Counter], len); 147 } else { 148 memmove(destbuf, &Buffer2[(BlockHeader.CompCount+sizeof(BlockHeader))-Counter], len); 149 } 150 destbuf = ((char *)destbuf) + len; 151 slen -= len; 152 Counter -= len; 153 total += len; 154 } 155 if (slen == 0) break; 156 157 if (Control == DECOMPRESS) { 158 int incount = Straw::Get(&BlockHeader, sizeof(BlockHeader)); 159 if (incount != sizeof(BlockHeader)) break; 160 161 void * ptr = &Buffer[(BlockSize+SafetyMargin) - BlockHeader.CompCount]; 162 incount = Straw::Get(ptr, BlockHeader.CompCount); 163 if (incount != BlockHeader.CompCount) break; 164 165 LZW_Uncompress(ptr, Buffer); 166 Counter = BlockHeader.UncompCount; 167 } else { 168 BlockHeader.UncompCount = (unsigned short)Straw::Get(Buffer, BlockSize); 169 if (BlockHeader.UncompCount == 0) break; 170 BlockHeader.CompCount = (unsigned short)LZW_Compress(::Buffer(Buffer, BlockHeader.UncompCount), &Buffer2[sizeof(BlockHeader)]); 171 memmove(Buffer2, &BlockHeader, sizeof(BlockHeader)); 172 Counter = BlockHeader.CompCount+sizeof(BlockHeader); 173 } 174 } 175 176 return(total); 177 }