Subversion Repositories autosfx

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 daniel-mar 1
#include "stdafx.h"
2
#pragma hdrstop
3
#include "ZipDflt.h"
4
//#include "Zip.h"
5
//#include "ZipErr.h"
6
#include "dz_errs.h"
7
 
8
#undef _DZ_FILE_
9
#define _DZ_FILE_ DZ_ZBITS_CPP
10
 
11
/* Bits.c
12
 * Copyright (C) 1990-1996 Mark Adler, Richard B. Wales, Jean-loup Gailly,
13
 * Kai Uwe Rommel, Onno van der Linden and Igor Mandrichenko.
14
 * Permission is granted to any individual or institution to use, copy, or
15
 * redistribute this software so long as all of the original files are included,
16
 * that it is not sold for profit, and that this copyright notice is retained.
17
 * This version modified by Chris Vleghert and Eric Engler for BCB/Delphi Zip.
18
 
19
  Copyright (c) 1990-2007 Info-ZIP.  All rights reserved.
20
 
21
  See the accompanying file LICENSE, version 2007-Mar-4 or later
22
  (the contents of which are also included in zip.h) for terms of use.
23
  If, for some reason, all these files are missing, the Info-ZIP license
24
  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
25
 
26
  parts Copyright (C) 1997 Mike White, Eric W. Engler
27
************************************************************************
28
 Copyright (C) 2009, 2010  by Russell J. Peters, Roger Aelbrecht
29
 
30
   This file is part of TZipMaster Version 1.9.
31
 
32
    TZipMaster is free software: you can redistribute it and/or modify
33
    it under the terms of the GNU Lesser General Public License as published by
34
    the Free Software Foundation, either version 3 of the License, or
35
    (at your option) any later version.
36
 
37
    TZipMaster is distributed in the hope that it will be useful,
38
    but WITHOUT ANY WARRANTY; without even the implied warranty of
39
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
40
    GNU Lesser General Public License for more details.
41
 
42
    You should have received a copy of the GNU Lesser General Public License
43
    along with TZipMaster.  If not, see <http://www.gnu.org/licenses/>.
44
 
45
    contact: problems@delphizip.org (include ZipMaster in the subject).
46
    updates: http://www.delphizip.org
47
    DelphiZip maillist subscribe at http://www.freelists.org/list/delphizip
48
************************************************************************/
49
 
50
/*
51
 *  bits.c by Jean-loup Gailly and Kai Uwe Rommel.
52
 *
53
 *  This is a new version of im_bits.c originally written by Richard B. Wales
54
 *
55
 *  PURPOSE
56
 *
57
 *      Output variable-length bit strings. Compression can be done
58
 *      to a file or to memory.
59
 *
60
 *  DISCUSSION
61
 *
62
 *      The PKZIP "deflate" file format interprets compressed file data
63
 *      as a sequence of bits.  Multi-bit strings in the file may cross
64
 *      byte boundaries without restriction.
65
 *
66
 *      The first bit of each byte is the low-order bit.
67
 *
68
 *      The routines in this file allow a variable-length bit value to
69
 *      be output right-to-left (useful for literal values). For
70
 *      left-to-right output (useful for code strings from the tree routines),
71
 *      the bits must have been reversed first with bi_reverse().
72
 *
73
 *      For in-memory compression, the compressed bit stream goes directly
74
 *      into the requested output buffer. The input data is read in blocks
75
 *      by the mem_read() function. The buffer is limited to 64K on 16 bit
76
 *      machines.
77
 *
78
 *  INTERFACE
79
 *
80
 *      void bi_init(FILE *zipfile)
81
 *          Initialize the bit string routines.
82
 *
83
 *      void send_bits(int value, int length)
84
 *          Write out a bit string, taking the source bits right to
85
 *          left.
86
 *
87
 *      int bi_reverse(int value, int length)
88
 *          Reverse the bits of a bit string, taking the source bits left to
89
 *          right and emitting them right to left.
90
 *
91
 *      void bi_windup(void)
92
 *          Write out any remaining bits in an incomplete byte.
93
 *
94
 *      void copy_block(char *buf, unsigned len, int header)
95
 *          Copy a stored block to the zip file, storing first the length and
96
 *          its one's complement if requested.
97
 *
98
 *      int seekable(void)
99
 *          Return true if the zip file can be seeked.
100
 *
101
 *      ulg memcompress(char *tgt, ulg tgtsize, char *src, ulg srcsize);
102
 *          Compress the source buffer src into the target buffer tgt.
103
 */
104
 
105
// Number of bits used within bi_buf. (bi_buf might be implemented on more
106
//   than 16 bits on some systems.)
107
#define Buf_size  (8 * 2 * sizeof(char))
108
 
109
//            fout_buf[fout_offset++] = (char)(b);
110
// Output a 16 bit value to the bit stream, lower (oldest) byte first
111
#define PUTBYTE(b)                                 \
112
    {                                                  \
113
        if (fout_offset < sizeof(f_outbuf))             \
114
        {                                                \
115
            f_outbuf[fout_offset++] = (char)(b); \
116
        }                                                \
117
        else                                             \
118
        {                                                \
119
            flush_outbuf((b), 1);                    \
120
        }                                                \
121
    }
122
 
123
// Prototypes for local functions
124
#ifdef _USE_ASM_
125
extern unsigned __fastcall bi_reverse(unsigned code, int len);
126
#endif
127
 
128
// Initialize the bit string routines. zipfile :: Output zip file, NULL for
129
//   in-memory compression.
130
void ZipDflt::bi_init(void) //HANDLE zipfile)
131
{
132
//  fzfile = zipfile;
133
    fbi_buf = 0;
134
    fbi_valid = 0;
135
#ifdef DEBUG
136
    fbits_sent = 0L;
137
#endif
138
    // Set the defaults for file compression. They are set by memcompress for
139
    //   in-memory compression.
140
//  if (fzfile > 0)    //!= INVALID_HANDLE_VALUE)
141
//  if (fhOutz != INVALID_HANDLE_VALUE)
142
 
143
    if (fZipOutfile && fZipOutfile->IsOpen())
144
    {
145
//        fout_buf = ffile_outbuf;
146
//        fout_size = sizeof(ffile_outbuf);
147
        fout_offset = 0;
148
//    fread_buf = &ZipDflt::file_read;
149
//#if defined(USE_STRM_INPUT) && defined(USE_STRM_OUTPUT)
150
//        ReadingFile = -1;
151
//#endif
152
    }
153
}
154
 
155
// Send a value on a given number of bits. IN assertion: length <= 16 and
156
//   value fits in length bits. value :: Value to send. length :: Number of
157
//   bits.
158
void __fastcall ZipDflt::send_bits(int value, int length)
159
{
160
#ifdef DEBUG
161
    Tracevv((_T(" l %2d v %4x ")), (length, value));
162
    Assert(length > 0 && length <= 15, _T("invalid length"));
163
    fbits_sent += (ulg) length;
164
#endif
165
 
166
    // If not enough room in bi_buf, use (valid) bits from bi_buf and (16 -
167
    //   bi_valid) bits from value, leaving (width - (16-bi_valid)) unused bits
168
    //   in value.
169
 
170
    if (fbi_valid > (int)Buf_size - length)
171
    {
172
        fbi_buf |= (ush)(value << fbi_valid);                         // RCV Added (ush)
173
 
174
        //  PUTSHORT(fbi_buf);  /*
175
 
176
        if (fout_offset < sizeof(f_outbuf) -1) //fout_size - 1)
177
        {
178
            *(ush *)(f_outbuf + fout_offset) = (ush) fbi_buf;
179
//            f_outbuf[fout_offset] = (ush) fbi_buf;
180
            fout_offset += 2;
181
        }
182
        else
183
        {
184
            flush_outbuf((fbi_buf), 2);
185
        }
186
 
187
        fbi_buf = (ush)((ush) value >> (Buf_size - fbi_valid));     // RCV Added (ush)(...)
188
        fbi_valid += length - Buf_size;
189
    }
190
    else
191
    {
192
        fbi_buf |= (ush)(value << fbi_valid);                         // RCV Added (ush)
193
        fbi_valid += length;
194
    }
195
}
196
 
197
// Reverse the first len bits of a code, using straightforward code (a
198
//   faster method would use a table) IN assertion: 1 <= len <= 15 code :: The
199
//   value to invert. len :: Its bit length.
200
#ifndef _USE_ASM_
201
unsigned __fastcall bi_reverse(unsigned code, int len)
202
{
203
    register unsigned res = 0;
204
 
205
    do
206
    {
207
        res |= code & 1;
208
        code >>= 1, res <<= 1;
209
    }
210
    while (--len > 0);
211
 
212
    return (res >> 1);
213
}
214
//
215
//#else
216
//unsigned __fastcall bi_reverse(unsigned code, int len)
217
//{
218
//#pragma warn - rvl
219
//#pragma argsused
220
//    asm
221
//    {
222
//        // EAX=code EDX=len
223
//        mov ecx, eax
224
//        xor eax, eax
225
//
226
//Loop1:
227
//        dec edx
228
//        jl short doneit
229
//        ror ecx, 1
230
//        rcl eax, 1
231
//        jmp short Loop1
232
//
233
//doneit:
234
//    };
235
//}
236
 
237
#endif
238
 
239
// Flush the current output buffer. w :: Value to flush. bytes :: Number of
240
//   bytes to flush (0, 1 or 2).
241
void __fastcall ZipDflt::flush_outbuf(unsigned w, unsigned bytes)
242
{
243
    // Encrypt and write the output buffer:
244
    if (fout_offset != 0)
245
    {
246
        if (!zfwrite(f_outbuf, (::extent) fout_offset))
247
        {
248
            diag(_T("Write error in flush_outbuf"));
249
//            FatalError(ZEN_WRITE01);
250
            throw DZException(DZ_ERM_ERROR_WRITE);
251
        }
252
    }
253
 
254
    fout_offset = 0;
255
 
256
    if (bytes == 2)
257
    {
258
        //    PUTSHORT(w); /*
259
        if (fout_offset < sizeof(f_outbuf) - 1)//fout_size - 1)
260
        {
261
            *(ush *)(f_outbuf + fout_offset) = (ush) w;
262
//            f_outbuf[fout_offset] = (ush) w;
263
            fout_offset += 2;
264
        }
265
        else
266
        {
267
            flush_outbuf((w), 2);
268
        }
269
    }
270
    else
271
        if (bytes == 1)
272
            f_outbuf[fout_offset++] = (char)(w & 0xFF);
273
}
274
 
275
// Write out any remaining bits in an incomplete byte.
276
void __fastcall ZipDflt::bi_windup(void)
277
{
278
    if (fbi_valid > 8)
279
    {
280
        if (fout_offset < sizeof(f_outbuf) - 1)//fout_size - 1)
281
        {
282
            *(ush *)(f_outbuf + fout_offset) = (ush) fbi_buf;
283
//            f_outbuf[fout_offset] = (ush) fbi_buf;
284
            fout_offset += 2;
285
        }
286
        else
287
        {
288
            flush_outbuf((fbi_buf), 2);
289
        }
290
    }
291
    else
292
        if (fbi_valid > 0)
293
        {
294
            PUTBYTE(fbi_buf);
295
        }
296
 
297
    if (fZipOutfile->IsOpen())
298
        flush_outbuf(0, 0);
299
 
300
    fbi_buf = 0;
301
    fbi_valid = 0;
302
#ifdef DEBUG
303
    fbits_sent = (fbits_sent + 7) & ~7;
304
#endif
305
}
306
 
307
// Copy a stored block to the zip file, storing first the length and its
308
//   one's complement if requested. block :: The input data. len :: Its length.
309
//   header :: True if block header must be written.
310
void __fastcall ZipDflt::copy_block(const uch *block, unsigned len, int header)
311
{
312
    bi_windup();        // align on byte boundary
313
 
314
    if (header)
315
    {
316
        if (fout_offset < sizeof(f_outbuf) -1)// fout_size - 1)
317
        {
318
            *(ush *)(f_outbuf + fout_offset) = (ush) len;
319
            fout_offset += 2;
320
        }
321
        else
322
        {
323
            flush_outbuf((len), 2);
324
        }
325
 
326
        //    PUTSHORT((ush)~len);
327
        if (fout_offset < sizeof(f_outbuf) -1)// fout_size - 1)
328
        {
329
            *(ush *)(f_outbuf + fout_offset) = (ush)~len;
330
            fout_offset += 2;
331
        }
332
        else
333
        {
334
            flush_outbuf((~len), 2);
335
        }
336
 
337
#ifdef DEBUG
338
        fbits_sent += 2 * 16;
339
#endif
340
    }
341
 
342
//  if (fzfile)
343
//  if (fhOutz != INVALID_HANDLE_VALUE)
344
    if (fZipOutfile)
345
    {
346
        flush_outbuf(0, 0);
347
 
348
        if (!zfwrite(block, len))
349
            throw DZException(DZ_ERM_ERROR_WRITE);
350
 
351
//            FatalError(ZEN_WRITE02);
352
    }
353
    else
354
    {
355
        if (fout_offset + len > sizeof(f_outbuf))//fout_size)
356
            throw DZException(DZ_ERM_LOGIC_ERROR);
357
 
358
//            FatalError(ZEN_LOGIC01);
359
//        else
360
//        {
361
        memcpy(f_outbuf + fout_offset, block, len);
362
        fout_offset += len;
363
 
364
    }
365
 
366
#ifdef DEBUG
367
    fbits_sent += (ulg) len << 3;
368
#endif
369
}
370
 
371
//// Return true if the zip file can be seeked. This is used to check if the
372
////   local header can be re-rewritten. This function always returns true for
373
////   in-memory compression. IN assertion: the local header has already been
374
////   written (ftell() > 0).
375
//int ZipDflt::seekable(void)
376
//{
377
//    return fZipOutfile->IsSeekable;
378
//}
379
 
380
 
381
//#ifdef USING_MEM_STRMS
382
//// In-memory compression. This version can be used only if the entire input
383
////   fits in one memory buffer. The compression is then done in a single call
384
////   of memcompress(). (An extension to allow repeated calls would be possible
385
////   but is not needed here.) The first two bytes of the compressed output are
386
////   set to a short with the method used (DEFLATE or STORE). The following four
387
////   bytes contain the CRC. The values are stored in little-endian order on all
388
////   machines. This function returns the byte size of the compressed output,
389
////   including the first six bytes (method and crc). tgt, *src :: Target and
390
////   source buffers. tgtsize, srcsize :: Target and source sizes.
391
//ulg ZipDflt::memcompress(char *tgt, ulg tgtsize, char *src, ulg srcsize)
392
//{
393
//    ush att = (ush) UNKNOWN;
394
//    ush flags = 0;
395
//    ulg crc;              // RCV Removed ...= 0;
396
//    int method = DEFLATE;
397
//
398
//    if (tgtsize <= 6L)
399
//        throw DZException(DZ_ERM_ERROR_LOGIC);
400
//
401
////        FatalError(ZEN_LOGIC02);
402
//
403
//    crc = crc32(0L, (uch *)NULL, 0);
404
//    crc = crc32(crc, (uch *)src, (extent) srcsize);
405
//
406
////  fread_buf = &ZipDflt::mem_read;
407
//    ReadingFile = 0;
408
//    fin_buf = src;
409
//    fin_size = (unsigned)srcsize;
410
//    fin_offset = 0;
411
//    fout_buf = tgt;
412
//    fout_size = (unsigned)tgtsize;
413
//    fout_offset = 2 + 4;
414
//    fwindow_size = 0L;
415
//    if (fZipOutfile)
416
//    {
417
//        delete fZipOutfile;
418
//        fZipOutfile = NULL;
419
//    }
420
//
421
////  if (fhOutz != INVALID_HANDLE_VALUE)
422
////    Close_Handle(&fhOutz);  // should not happen but...
423
//    bi_init(); //NULL);
424
//    ct_init(&att, &method);
425
//    lm_init((flevel != 0 ? flevel : 1), &flags);
426
//    deflate();
427
//    fwindow_size = 0L; // was updated by lm_init()
428
//    // For portability, force little-endian order on all machines:
429
//    tgt[0] = (char)(method & 0xFF);
430
//    tgt[1] = (char)((method >> 8) & 0xFF);
431
//    tgt[2] = (char)(crc & 0xFF);
432
//    tgt[3] = (char)((crc >> 8) & 0xFF);
433
//    tgt[4] = (char)((crc >> 16) & 0xFF);
434
//    tgt[5] = (char)((crc >> 24) & 0xFF);
435
//
436
//    return (ulg) fout_offset;
437
//}
438
//
439
//// In-memory read function. As opposed to file_read(), this function does
440
////   not perform end-of-line translation, and does not update the crc and input
441
////   size. Note that the size of the entire input buffer is an unsigned long,
442
////   but the size used in mem_read() is only an unsigned int. This makes a
443
////   difference on 16 bit machines. mem_read() may be called several times for
444
////   an in-memory compression.
445
//int ZipDflt::mem_read(unsigned char *b, unsigned bsize)
446
//{
447
//    if (fin_offset < fin_size)
448
//    {
449
//        ulg block_size = fin_size - fin_offset;
450
//
451
//        if (block_size > (ulg) bsize)
452
//            block_size = (ulg) bsize;
453
//
454
//        memcpy(b, fin_buf + fin_offset, (unsigned)block_size);
455
//        fin_offset += (unsigned)block_size;
456
//        return (int)block_size;
457
//    }
458
//
459
//    return 0;             // end of input
460
//}
461
//
462
//#endif
463
 
464
 
465
 
466