1 /*****************************************************************************/
2 /* wave.cpp Copyright (c) Ladislav Zezula 2003 */
3 /*---------------------------------------------------------------------------*/
4 /* This module contains decompression methods used by Storm.dll to decompress*/
5 /* WAVe files. Thanks to Tom Amigo for releasing his sources. */
6 /*---------------------------------------------------------------------------*/
7 /* Date Ver Who Comment */
8 /* -------- ---- --- ------- */
9 /* 11.03.03 1.00 Lad Splitted from Pkware.cpp */
10 /* 20.05.03 2.00 Lad Added compression */
11 /* 19.11.03 2.01 Dan Big endian handling */
12 /*****************************************************************************/
16 //------------------------------------------------------------------------------
25 union TWordAndByteArray
31 //-----------------------------------------------------------------------------
32 // Tables necessary dor decompression
34 static long Table1503F120
[] =
36 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000004, 0xFFFFFFFF, 0x00000002, 0xFFFFFFFF, 0x00000006,
37 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0x00000005, 0xFFFFFFFF, 0x00000003, 0xFFFFFFFF, 0x00000007,
38 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0x00000005, 0xFFFFFFFF, 0x00000003, 0xFFFFFFFF, 0x00000007,
39 0xFFFFFFFF, 0x00000002, 0xFFFFFFFF, 0x00000004, 0xFFFFFFFF, 0x00000006, 0xFFFFFFFF, 0x00000008
42 static long Table1503F1A0
[] =
44 0x00000007, 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E,
45 0x00000010, 0x00000011, 0x00000013, 0x00000015, 0x00000017, 0x00000019, 0x0000001C, 0x0000001F,
46 0x00000022, 0x00000025, 0x00000029, 0x0000002D, 0x00000032, 0x00000037, 0x0000003C, 0x00000042,
47 0x00000049, 0x00000050, 0x00000058, 0x00000061, 0x0000006B, 0x00000076, 0x00000082, 0x0000008F,
48 0x0000009D, 0x000000AD, 0x000000BE, 0x000000D1, 0x000000E6, 0x000000FD, 0x00000117, 0x00000133,
49 0x00000151, 0x00000173, 0x00000198, 0x000001C1, 0x000001EE, 0x00000220, 0x00000256, 0x00000292,
50 0x000002D4, 0x0000031C, 0x0000036C, 0x000003C3, 0x00000424, 0x0000048E, 0x00000502, 0x00000583,
51 0x00000610, 0x000006AB, 0x00000756, 0x00000812, 0x000008E0, 0x000009C3, 0x00000ABD, 0x00000BD0,
52 0x00000CFF, 0x00000E4C, 0x00000FBA, 0x0000114C, 0x00001307, 0x000014EE, 0x00001706, 0x00001954,
53 0x00001BDC, 0x00001EA5, 0x000021B6, 0x00002515, 0x000028CA, 0x00002CDF, 0x0000315B, 0x0000364B,
54 0x00003BB9, 0x000041B2, 0x00004844, 0x00004F7E, 0x00005771, 0x0000602F, 0x000069CE, 0x00007462,
58 //----------------------------------------------------------------------------
62 int CompressWave(unsigned char * pbOutBuffer
, int dwOutLength
, short * pwInBuffer
, int dwInLength
, int nChannels
, int nCmpLevel
)
65 TWordAndByteArray Wcmp
;
66 TByteAndWordPtr out
; // Pointer to the output buffer
70 long nBytesRemains
= dwOutLength
; // Number of bytes remaining
71 long nWordsRemains
; // Number of words remaining
72 // unsigned char * pbSaveOutBuffer; // Copy of output buffer (actually not used)
73 unsigned long dwBitBuff
;
74 unsigned long dwStopBit
;
86 // If less than 2 bytes remain, don't decompress anything
87 // pbSaveOutBuffer = pbOutBuffer;
92 Wcmp
.b
[1] = (unsigned char)(nCmpLevel
- 1);
93 Wcmp
.b
[0] = (unsigned char)0;
95 *out
.pw
++ = BSWAP_INT16_SIGNED(Wcmp
.w
);
96 if((out
.pb
- pbOutBuffer
+ (nChannels
* 2)) > nBytesRemains
)
97 return (int)(out
.pb
- pbOutBuffer
+ (nChannels
* 2));
99 SInt32Array1
[0] = SInt32Array1
[1] = 0x2C;
101 for(int i
= 0; i
< nChannels
; i
++)
103 nOneWord
= BSWAP_INT16_SIGNED(*pwInBuffer
++);
104 *out
.pw
++ = BSWAP_INT16_SIGNED((short)nOneWord
);
105 SInt32Array2
[i
] = nOneWord
;
108 // Weird. But it's there
109 nLength
= dwInLength
;
110 if(nLength
< 0) // mov eax, dwInLength; cdq; sub eax, edx;
113 nLength
= (nLength
/ 2) - (int)(out
.pb
- pbOutBuffer
);
114 nLength
= (nLength
< 0) ? 0 : nLength
;
116 nIndex
= nChannels
- 1; // edi
117 nWordsRemains
= dwInLength
/ 2; // eax
121 for(int chnl
= nChannels
; chnl
< nWordsRemains
; chnl
++)
124 if((out
.pb
- pbOutBuffer
+ 2) > nBytesRemains
)
125 return (int)(out
.pb
- pbOutBuffer
+ 2);
129 nIndex
= (nIndex
== 0) ? 1 : 0;
131 // Load one word from the input stream
132 nOneWord
= BSWAP_INT16_SIGNED(*pwInBuffer
++); // ecx - nOneWord
133 SInt32Array3
[nIndex
] = nOneWord
;
135 // esi - SInt32Array2[nIndex]
137 nValue
= nOneWord
- SInt32Array2
[nIndex
];
138 nValue
= (nValue
< 0) ? ((nValue
^ 0xFFFFFFFF) + 1) : nValue
;
140 ebx
= (nOneWord
>= SInt32Array2
[nIndex
]) ? 0 : 0x40;
142 // esi - SInt32Array2[nIndex]
143 // edx - Table1503F1A0[SInt32Array2[nIndex]]
144 // edi - (Table1503F1A0[SInt32Array1[nIndex]] >> nCmpLevel)
145 nTableValue
= Table1503F1A0
[SInt32Array1
[nIndex
]];
146 dwStopBit
= (unsigned long)nCmpLevel
;
149 if(nValue
< (nTableValue
>> nCmpLevel
))
151 if(SInt32Array1
[nIndex
] != 0)
152 SInt32Array1
[nIndex
]--;
157 while(nValue
> nTableValue
* 2)
159 if(SInt32Array1
[nIndex
] >= 0x58 || nLength
== 0)
162 SInt32Array1
[nIndex
] += 8;
163 if(SInt32Array1
[nIndex
] > 0x58)
164 SInt32Array1
[nIndex
] = 0x58;
166 nTableValue
= Table1503F1A0
[SInt32Array1
[nIndex
]];
171 var_2C
= nTableValue
>> Wcmp
.b
[1];
174 esi
= (1 << (dwStopBit
- 2));
175 dwStopBit
= (esi
<= 0x20) ? esi
: 0x20;
177 for(var_1C
= 0, dwBit
= 1; ; dwBit
<<= 1)
179 // esi = var_1C + nTableValue;
180 if((var_1C
+ nTableValue
) <= nValue
)
182 var_1C
+= nTableValue
;
185 if(dwBit
== dwStopBit
)
191 nValue
= SInt32Array2
[nIndex
];
194 nValue
-= (var_1C
+ var_2C
);
200 nValue
+= (var_1C
+ var_2C
);
205 SInt32Array2
[nIndex
] = nValue
;
206 *out
.pb
++ = (unsigned char)(dwBitBuff
| ebx
);
207 nTableValue
= Table1503F120
[dwBitBuff
& 0x1F];
208 SInt32Array1
[nIndex
] = SInt32Array1
[nIndex
] + nTableValue
;
209 if(SInt32Array1
[nIndex
] < 0)
210 SInt32Array1
[nIndex
] = 0;
211 else if(SInt32Array1
[nIndex
] > 0x58)
212 SInt32Array1
[nIndex
] = 0x58;
216 return (int)(out
.pb
- pbOutBuffer
);
219 //----------------------------------------------------------------------------
223 int DecompressWave(unsigned char * pbOutBuffer
, int dwOutLength
, unsigned char * pbInBuffer
, int dwInLength
, int nChannels
)
225 TByteAndWordPtr out
; // Output buffer
227 unsigned char * pbInBufferEnd
= (pbInBuffer
+ dwInLength
);
228 long SInt32Array1
[2];
229 long SInt32Array2
[2];
231 int dwOutLengthCopy
= dwOutLength
;
234 SInt32Array1
[0] = SInt32Array1
[1] = 0x2C;
235 out
.pb
= pbOutBuffer
;
239 // Fill the Uint32Array2 array by channel values.
240 for(int i
= 0; i
< nChannels
; i
++)
242 nOneWord
= BSWAP_INT16_SIGNED(*in
.pw
++);
243 SInt32Array2
[i
] = nOneWord
;
244 if(dwOutLengthCopy
< 2)
245 return (int)(out
.pb
- pbOutBuffer
);
247 *out
.pw
++ = BSWAP_INT16_SIGNED((short)nOneWord
);
248 dwOutLengthCopy
-= sizeof(short);
251 // Get the initial index
252 nIndex
= nChannels
- 1;
254 // Perform the decompression
255 while(in
.pb
< pbInBufferEnd
)
257 unsigned char nOneByte
= *in
.pb
++;
261 nIndex
= (nIndex
== 0) ? 1 : 0;
263 // 1500F2A2: Get one byte from input buffer
266 switch(nOneByte
& 0x7F)
269 if(SInt32Array1
[nIndex
] != 0)
270 SInt32Array1
[nIndex
]--;
272 if(dwOutLengthCopy
< 2)
273 return (int)(out
.pb
- pbOutBuffer
);
275 *out
.pw
++ = BSWAP_INT16_SIGNED((unsigned short)SInt32Array2
[nIndex
]);
276 dwOutLength
-= sizeof(unsigned short);
280 SInt32Array1
[nIndex
] += 8;
281 if(SInt32Array1
[nIndex
] > 0x58)
282 SInt32Array1
[nIndex
] = 0x58;
285 nIndex
= (nIndex
== 0) ? 1 : 0;
292 SInt32Array1
[nIndex
] -= 8;
293 if(SInt32Array1
[nIndex
] < 0)
294 SInt32Array1
[nIndex
] = 0;
297 nIndex
= (nIndex
== 0) ? 1 : 0;
304 long temp1
= Table1503F1A0
[SInt32Array1
[nIndex
]]; // EDI
305 long temp2
= temp1
>> pbInBuffer
[1]; // ESI
306 long temp3
= SInt32Array2
[nIndex
]; // ECX
308 if(nOneByte
& 0x01) // EBX = nOneByte
309 temp2
+= (temp1
>> 0);
312 temp2
+= (temp1
>> 1);
315 temp2
+= (temp1
>> 2);
318 temp2
+= (temp1
>> 3);
321 temp2
+= (temp1
>> 4);
324 temp2
+= (temp1
>> 5);
328 temp3
= temp3
- temp2
;
334 temp3
= temp3
+ temp2
;
339 SInt32Array2
[nIndex
] = temp3
;
343 // Store the output 16-bit value
344 *out
.pw
++ = BSWAP_INT16_SIGNED((short)SInt32Array2
[nIndex
]);
347 SInt32Array1
[nIndex
] += Table1503F120
[nOneByte
& 0x1F];
349 if(SInt32Array1
[nIndex
] < 0)
350 SInt32Array1
[nIndex
] = 0;
351 else if(SInt32Array1
[nIndex
] > 0x58)
352 SInt32Array1
[nIndex
] = 0x58;
355 return (int)(out
.pb
- pbOutBuffer
);