Subversion Repositories autosfx

Rev

Blame | Last modification | View Log | RSS feed

  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.  
  467.