zinflate.cpp

Go to the documentation of this file.
00001 // $Id: zinflate.cpp 1282 2006-06-09 09:46:49Z alex $
00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00003 ================================XARAHEADERSTART===========================
00004  
00005                Xara LX, a vector drawing and manipulation program.
00006                     Copyright (C) 1993-2006 Xara Group Ltd.
00007        Copyright on certain contributions may be held in joint with their
00008               respective authors. See AUTHORS file for details.
00009 
00010 LICENSE TO USE AND MODIFY SOFTWARE
00011 ----------------------------------
00012 
00013 This file is part of Xara LX.
00014 
00015 Xara LX is free software; you can redistribute it and/or modify it
00016 under the terms of the GNU General Public License version 2 as published
00017 by the Free Software Foundation.
00018 
00019 Xara LX and its component source files are distributed in the hope
00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022 See the GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License along
00025 with Xara LX (see the file GPL in the root directory of the
00026 distribution); if not, write to the Free Software Foundation, Inc., 51
00027 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00028 
00029 
00030 ADDITIONAL RIGHTS
00031 -----------------
00032 
00033 Conditional upon your continuing compliance with the GNU General Public
00034 License described above, Xara Group Ltd grants to you certain additional
00035 rights. 
00036 
00037 The additional rights are to use, modify, and distribute the software
00038 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00039 library and any other such library that any version of Xara LX relased
00040 by Xara Group Ltd requires in order to compile and execute, including
00041 the static linking of that library to XaraLX. In the case of the
00042 "CDraw" library, you may satisfy obligation under the GNU General Public
00043 License to provide source code by providing a binary copy of the library
00044 concerned and a copy of the license accompanying it.
00045 
00046 Nothing in this section restricts any of the rights you have under
00047 the GNU General Public License.
00048 
00049 
00050 SCOPE OF LICENSE
00051 ----------------
00052 
00053 This license applies to this program (XaraLX) and its constituent source
00054 files only, and does not necessarily apply to other Xara products which may
00055 in part share the same code base, and are subject to their own licensing
00056 terms.
00057 
00058 This license does not apply to files in the wxXtra directory, which
00059 are built into a separate library, and are subject to the wxWindows
00060 license contained within that directory in the file "WXXTRA-LICENSE".
00061 
00062 This license does not apply to the binary libraries (if any) within
00063 the "libs" directory, which are subject to a separate license contained
00064 within that directory in the file "LIBS-LICENSE".
00065 
00066 
00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00068 ----------------------------------------------
00069 
00070 Subject to the terms of the GNU Public License (see above), you are
00071 free to do whatever you like with your modifications. However, you may
00072 (at your option) wish contribute them to Xara's source tree. You can
00073 find details of how to do this at:
00074   http://www.xaraxtreme.org/developers/
00075 
00076 Prior to contributing your modifications, you will need to complete our
00077 contributor agreement. This can be found at:
00078   http://www.xaraxtreme.org/developers/contribute/
00079 
00080 Please note that Xara will not accept modifications which modify any of
00081 the text between the start and end of this header (marked
00082 XARAHEADERSTART and XARAHEADEREND).
00083 
00084 
00085 MARKS
00086 -----
00087 
00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00089 designs are registered or unregistered trademarks, design-marks, and/or
00090 service marks of Xara Group Ltd. All rights in these marks are reserved.
00091 
00092 
00093       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00094                         http://www.xara.com/
00095 
00096 =================================XARAHEADEREND============================
00097  */
00098 
00099 // This class contains all the file deflating code
00100 
00101 /*
00102 */
00103 
00104 #include "camtypes.h"
00105 //#include "fixmem.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00106 
00107 #include "zinflate.h"
00108 #include "zstream.h"
00109 
00110 // This is not compulsory, but you may as well put it in so that the correct version
00111 // of your file can be registered in the .exe
00112 DECLARE_SOURCE("$Revision: 1282 $");
00113 
00114 // An implement to match the Declare in the .h file.
00115 // If you have many classes, it is recommended to place them all together, here at the start of the file
00116 CC_IMPLEMENT_MEMDUMP(InflateState, CC_CLASS_MEMDUMP)
00117 CC_IMPLEMENT_MEMDUMP(ZipInflate, CC_CLASS_MEMDUMP)
00118 
00119 // This will get Camelot to display the filename and linenumber of any memory allocations
00120 // that are not released at program exit
00121 
00122 // Declare smart memory handling in Debug builds
00123 #define new CAM_DEBUG_NEW
00124 
00125 uInt inflate_mask[] = {
00126     0x0000,
00127     0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
00128     0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
00129 };
00130 
00131 // ------------------------------------------------------------------------------------------
00132 // From inflate.c
00133 // ------------------------------------------------------------------------------------------
00134 
00135 /* ---------------------------------- ZipInflate class -------------------------------------- */
00136 
00137 /********************************************************************************************
00138 
00139 >   ZipInflate::ZipInflate()
00140 
00141     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00142     Created:    24/05/95
00143     Purpose:    ZipInflate constructor.
00144 
00145 ********************************************************************************************/
00146 
00147 ZipInflate::ZipInflate()
00148 {
00149 }   
00150 
00151 /********************************************************************************************
00152 
00153 >   ZipInflate::ZipInflate()
00154 
00155     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00156     Created:    24/05/95
00157     Purpose:    ZipInflate destructor.
00158 
00159 ********************************************************************************************/
00160 
00161 ZipInflate::~ZipInflate()
00162 {
00163     
00164 }   
00165 
00166 /********************************************************************************************
00167 
00168 >   INT32 ZipInflate::Reset(ZStream *z)
00169 
00170     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00171     Created:    24/05/95
00172     Inputs:     s   the zip strema to use
00173     Purpose:    This function is equivalent to inflateEnd followed by inflateInit,
00174                 but does not free and reallocate all the internal decompression state.
00175                 The stream will keep attributes that may have been set by inflateInit2.
00176 
00177                 inflate Reset returns Z_OK if success, or Z_STREAM_ERROR if the source
00178                 stream state was inconsistent (such as zalloc or state being NULL).
00179 
00180 ********************************************************************************************/
00181 
00182 INT32 ZipInflate::Reset(ZStream *z)
00183 {
00184     uLong c;
00185 
00186     if (z == NULL || z->In_state == NULL)
00187         return Z_STREAM_ERROR;
00188 
00189     z->total_in = z->total_out = 0;
00190     z->msg = Z_NULL;
00191     z->In_state->mode = z->In_state->nowrap ? BLOCKS : METHOD;
00192     inflate_blocks_reset(z->In_state->blocks, z, &c);
00193     Trace((stderr, "inflate: reset\n"));
00194     return Z_OK;
00195 }
00196 
00197 
00198 /********************************************************************************************
00199 
00200 >   INT32 ZipInflate::End(ZStream *z)
00201 
00202     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00203     Created:    24/05/95
00204     Inputs:     s   the zip strema to use
00205     Purpose:    All dynamically allocated data structures for this stream are freed.
00206                 This function discards any unprocessed input and does not flush any
00207                 pending output.
00208 
00209                 inflate End returns Z_OK if success, Z_STREAM_ERROR if the stream state
00210                 was inconsistent. In the error case, msg may be set but then points to a
00211                 static string (which must not be deallocated).
00212 
00213 ********************************************************************************************/
00214 
00215 INT32 ZipInflate::End(ZStream *z)
00216 {
00217     uLong c;
00218 
00219     if (z == NULL || z->In_state == NULL || z->zfree == Z_NULL) // || z->zfree == NULL)
00220         return Z_STREAM_ERROR;
00221 
00222     if (z->In_state->blocks != NULL)
00223         inflate_blocks_free(z->In_state->blocks, z, &c);
00224 
00225     delete z->In_state;
00226     z->In_state = NULL;
00227     Trace((stderr, "inflate: end\n"));
00228 
00229     return Z_OK;
00230 }
00231 
00232 
00233 /********************************************************************************************
00234 
00235 >   INT32 ZipInflate::Init(ZStream *z, INT32 w)
00236 
00237     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00238     Created:    24/05/95
00239     Inputs:     s   the zip strema to use
00240                 w   base two logarithm of the maximum window size, in the range 8..15
00241     Purpose:    This is another version of inflate Init with more compression options. The
00242                 fields next_out, zalloc and zfree must be initialized before by the caller.
00243 
00244                  The windowBits parameter is the base two logarithm of the maximum window
00245                 size (the size of the history buffer).  It should be in the range 8..15 for
00246                 this version of the library (the value 16 will be allowed soon). The
00247                 default value is 15 if inflateInit is used instead. If a compressed stream
00248                 with a larger window size is given as input, inflate() will return with
00249                 the error code Z_DATA_ERROR instead of trying to allocate a larger window.
00250 
00251                  If next_out is not null, the library will use this buffer for the history
00252                 buffer; the buffer must either be large enough to hold the entire output
00253                 data, or have at least 1<<windowBits bytes.  If next_out is null, the
00254                 library will allocate its own buffer (and leave next_out null). next_in
00255                 need not be provided here but must be provided by the application for the
00256                 next call of inflate().
00257 
00258                  If the history buffer is provided by the application, next_out must
00259                 never be changed by the application since the decompressor maintains
00260                 history information inside this buffer from call to call; the application
00261                 can only reset next_out to the beginning of the history buffer when
00262                 avail_out is zero and all output has been consumed.
00263 
00264                   inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was
00265                 not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as
00266                 windowBits < 8). msg is set to null if there is no error message.
00267                 inflateInit2 does not perform any compression: this will be done by
00268                 inflate().
00269 
00270 ********************************************************************************************/
00271 
00272 INT32 ZipInflate::Init(ZStream *z, INT32 w)
00273 {
00274     //if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
00275     //  stream_size != sizeof(z_stream))
00276     //  return Z_VERSION_ERROR;
00277 
00278     /* initialize state */
00279     if (z == NULL)
00280         return Z_STREAM_ERROR;
00281 
00282     z->msg = Z_NULL;
00283 
00284     if (z->zalloc == NULL)
00285     {
00286         z->zalloc = GZipFile::zcalloc;
00287         z->opaque = 0;
00288     }
00289     if (z->zfree == NULL)
00290         z->zfree = GZipFile::zcfree;
00291 //  if ((z->In_state = (struct InflateState *)
00292 //       ZALLOC(z,1,sizeof(struct InflateState))) == NULL)
00293 //    return Z_MEM_ERROR;
00294     z->In_state = new InflateState;
00295     if ((z->In_state) == NULL)
00296         return Z_MEM_ERROR;
00297     z->In_state->blocks = NULL;
00298 
00299     /* handle undocumented nowrap option (no zlib header or check) */
00300     z->In_state->nowrap = 0;
00301     if (w < 0)
00302     {
00303         w = - w;
00304         z->In_state->nowrap = 1;
00305     }
00306 
00307     /* set window size */
00308     if (w < 8 || w > 15)
00309     {
00310         End(z);
00311         return Z_STREAM_ERROR;
00312     }
00313     z->In_state->wbits = (uInt)w;
00314 
00315     /* create inflate_blocks state */
00316     z->In_state->blocks = inflate_blocks_new(z, z->In_state->nowrap ? Z_NULL : GZipFile::adler32, (uInt)1 << w);
00317     if (z->In_state->blocks == NULL)
00318     {
00319         End(z);
00320         return Z_MEM_ERROR;
00321     }
00322     Trace((stderr, "inflate: allocated\n"));
00323 
00324     /* reset state */
00325     Reset(z);
00326 
00327     return Z_OK;
00328 }
00329 
00330 
00331 /********************************************************************************************
00332 
00333 >   INT32 ZipInflate::Init(ZStream *z)
00334 
00335     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00336     Created:    24/05/95
00337     Inputs:     s   the zip strema to use
00338     Purpose:    Initializes the internal stream state for decompression. The fields
00339                 zalloc and zfree must be initialized before by the caller.  If zalloc and
00340                 zfree are set to Z_NULL, deflateInit updates them to use default allocation
00341                 functions.
00342 
00343                 inflate Init returns Z_OK if success, Z_MEM_ERROR if there was not
00344                 enough memory.  msg is set to null if there is no error message.
00345                 inflateInit does not perform any decompression: this will be done by
00346                 inflate().
00347 
00348 ********************************************************************************************/
00349 
00350 INT32 ZipInflate::Init(ZStream *z)
00351 {
00352   return Init(z, DEF_WBITS);
00353 }
00354 
00355 /********************************************************************************************
00356 
00357 >   INT32 ZipInflate::inflate(ZStream *z, INT32 f)
00358 
00359     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00360     Created:    24/05/95
00361     Inputs:     s   the zip strema to use
00362                 f   dictates the flush type to use
00363     Purpose:    Performs one or both of the following actions:
00364 
00365                 - Decompress more input starting at next_in and update next_in and avail_in
00366                 accordingly. If not all input can be processed (because there is not
00367                 enough room in the output buffer), next_in is updated and processing
00368                 will resume at this point for the next call of inflate().
00369 
00370                  - Provide more output starting at next_out and update next_out and avail_out
00371                 accordingly.  inflate() provides as much output as possible, until there
00372                 is no more input data or no more space in the output buffer (see below
00373                 about the flush parameter).
00374 
00375                 Before the call of inflate(), the application should ensure that at least
00376                 one of the actions is possible, by providing more input and/or consuming
00377                 more output, and updating the next_* and avail_* values accordingly.
00378                 The application can consume the uncompressed output when it wants, for
00379                 example when the output buffer is full (avail_out == 0), or after each
00380                 call of inflate(). If inflate returns Z_OK and with zero avail_out, it
00381                 must be called again after making room in the output buffer because there
00382                 might be more output pending.
00383 
00384                 If the parameter flush is set to Z_PARTIAL_FLUSH, inflate flushes as much
00385                 output as possible to the output buffer. The flushing behavior of inflate is
00386                 not specified for values of the flush parameter other than Z_PARTIAL_FLUSH
00387                 and Z_FINISH, but the current implementation actually flushes as much output
00388                 as possible anyway.
00389 
00390                 inflate() should normally be called until it returns Z_STREAM_END or an
00391                 error. However if all decompression is to be performed in a single step
00392                 (a single call of inflate), the parameter flush should be set to
00393                 Z_FINISH. In this case all pending input is processed and all pending
00394                 output is flushed; avail_out must be large enough to hold all the
00395                 uncompressed data. (The size of the uncompressed data may have been saved
00396                 by the compressor for this purpose.) The next operation on this stream must
00397                 be inflateEnd to deallocate the decompression state.
00398 
00399                 inflate() returns Z_OK if some progress has been made (more input
00400                 processed or more output produced), ZStream_END if the end of the
00401                 compressed data has been reached and all uncompressed output has been
00402                 produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if
00403                 the stream structure was inconsistent (for example if next_in or next_out
00404                 was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no
00405                 progress is possible or if there was not enough room in the output buffer
00406                 when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then
00407                 call inflateSync to look for a good compression block.
00408 
00409 ********************************************************************************************/
00410 
00411 #define NEEDBYTE {if(z->avail_in==0)return r;r=Z_OK;}
00412 #define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
00413 
00414 INT32 ZipInflate::inflate(ZStream *z, INT32 f)
00415 {
00416   INT32 r;
00417   uInt b;
00418 
00419   if (z == Z_NULL || z->In_state == Z_NULL || z->next_in == Z_NULL || f < 0)
00420     return Z_STREAM_ERROR;
00421   r = Z_BUF_ERROR;
00422   while (1) switch (z->In_state->mode)
00423   {
00424     case METHOD:
00425       NEEDBYTE
00426       if (((z->In_state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
00427       {
00428         z->In_state->mode = BAD;
00429         z->msg = (char*)"unknown compression method";
00430         z->In_state->sub.marker = 5;       /* can't try inflateSync */
00431         break;
00432       }
00433       if ((z->In_state->sub.method >> 4) + 8 > z->In_state->wbits)
00434       {
00435         z->In_state->mode = BAD;
00436         z->msg = (char*)"invalid window size";
00437         z->In_state->sub.marker = 5;       /* can't try inflateSync */
00438         break;
00439       }
00440       z->In_state->mode = FLAG;
00441     case FLAG:
00442       NEEDBYTE
00443       b = NEXTBYTE;
00444       if (((z->In_state->sub.method << 8) + b) % 31)
00445       {
00446         z->In_state->mode = BAD;
00447         z->msg = (char*)"incorrect header check";
00448         z->In_state->sub.marker = 5;       /* can't try inflateSync */
00449         break;
00450       }
00451       Trace((stderr, "inflate: zlib header ok\n"));
00452       if (!(b & PRESET_DICT))
00453       {
00454         z->In_state->mode = BLOCKS;
00455     break;
00456       }
00457       z->In_state->mode = DICT4;
00458     case DICT4:
00459       NEEDBYTE
00460       z->In_state->sub.check.need = (uLong)NEXTBYTE << 24;
00461       z->In_state->mode = DICT3;
00462     case DICT3:
00463       NEEDBYTE
00464       z->In_state->sub.check.need += (uLong)NEXTBYTE << 16;
00465       z->In_state->mode = DICT2;
00466     case DICT2:
00467       NEEDBYTE
00468       z->In_state->sub.check.need += (uLong)NEXTBYTE << 8;
00469       z->In_state->mode = DICT1;
00470     case DICT1:
00471       NEEDBYTE
00472       z->In_state->sub.check.need += (uLong)NEXTBYTE;
00473       z->adler = z->In_state->sub.check.need;
00474       z->In_state->mode = DICT0;
00475       return Z_NEED_DICT;
00476     case DICT0:
00477       z->In_state->mode = BAD;
00478       z->msg = (char*)"need dictionary";
00479       z->In_state->sub.marker = 0;       /* can try inflateSync */
00480       return Z_STREAM_ERROR;
00481     case BLOCKS:
00482       r = inflate_blocks(z->In_state->blocks, z, r);
00483       if (r == Z_DATA_ERROR)
00484       {
00485         z->In_state->mode = BAD;
00486         z->In_state->sub.marker = 0;       /* can try inflateSync */
00487         break;
00488       }
00489       if (r != Z_STREAM_END)
00490         return r;
00491       r = Z_OK;
00492       inflate_blocks_reset(z->In_state->blocks, z, &z->In_state->sub.check.was);
00493       if (z->In_state->nowrap)
00494       {
00495         z->In_state->mode = DONE;
00496         break;
00497       }
00498       z->In_state->mode = CHECK4;
00499     case CHECK4:
00500       NEEDBYTE
00501       z->In_state->sub.check.need = (uLong)NEXTBYTE << 24;
00502       z->In_state->mode = CHECK3;
00503     case CHECK3:
00504       NEEDBYTE
00505       z->In_state->sub.check.need += (uLong)NEXTBYTE << 16;
00506       z->In_state->mode = CHECK2;
00507     case CHECK2:
00508       NEEDBYTE
00509       z->In_state->sub.check.need += (uLong)NEXTBYTE << 8;
00510       z->In_state->mode = CHECK1;
00511     case CHECK1:
00512       NEEDBYTE
00513       z->In_state->sub.check.need += (uLong)NEXTBYTE;
00514 
00515       if (z->In_state->sub.check.was != z->In_state->sub.check.need)
00516       {
00517         z->In_state->mode = BAD;
00518         z->msg = (char*)"incorrect data check";
00519         z->In_state->sub.marker = 5;       /* can't try inflateSync */
00520         break;
00521       }
00522       Trace((stderr, "inflate: zlib check ok\n"));
00523       z->In_state->mode = DONE;
00524     case DONE:
00525       return Z_STREAM_END;
00526     case BAD:
00527       return Z_DATA_ERROR;
00528     default:
00529       return Z_STREAM_ERROR;
00530   }
00531 }
00532 
00533 /********************************************************************************************
00534 
00535 >   INT32 ZipInflate::SetDictionary(ZStream *z, const Bytef *dictionary, uInt dictLength)
00536 
00537     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00538     Created:    24/05/95
00539     Inputs:     z   the zip stream to use
00540                 dictionary
00541                 dictLength
00542     Purpose:    Set the same dictionary on loading that was used on saving. For comments see:-
00543     SeeAlso:    ZipDeflate::SetDictionary
00544 
00545 ********************************************************************************************/
00546 
00547 INT32 ZipInflate::SetDictionary(ZStream *z, const Bytef *dictionary, uInt dictLength)
00548 {
00549   uInt length = dictLength;
00550 
00551   if (z == Z_NULL || z->In_state == Z_NULL || z->In_state->mode != DICT0)
00552     return Z_STREAM_ERROR;
00553   if (GZipFile::adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
00554   z->adler = 1L;
00555 
00556   if (length >= ((uInt)1<<z->In_state->wbits))
00557   {
00558     length = (1<<z->In_state->wbits)-1;
00559     dictionary += dictLength - length;
00560   }
00561   inflate_set_dictionary(z->In_state->blocks, dictionary, length);
00562   z->In_state->mode = BLOCKS;
00563   return Z_OK;
00564 }
00565 
00566 
00567 /********************************************************************************************
00568 
00569 >   INT32 ZipInflate::Sync(ZStream *z)
00570 
00571     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00572     Created:    24/05/95
00573     Inputs:     s   the zip stream to use
00574     Purpose:    Skips invalid compressed data until the special marker (see deflate()
00575                 above) can be found, or until all available input is skipped. No output
00576                 is provided.
00577 
00578                 inflate Sync returns Z_OK if the special marker has been found, Z_BUF_ERROR
00579                 if no more input was provided, Z_DATA_ERROR if no marker has been found,
00580                 or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
00581                 case, the application may save the current current value of total_in which
00582                 indicates where valid compressed data was found. In the error case, the
00583                 application may repeatedly call inflateSync, providing more input each time,
00584                 until success or end of the input data.
00585 
00586 ********************************************************************************************/
00587 
00588 INT32 ZipInflate::Sync(ZStream *z)
00589 {
00590   uInt n;       /* number of bytes to look at */
00591   Bytef *p;     /* pointer to bytes */
00592   uInt m;       /* number of marker bytes found in a row */
00593   uLong r, w;   /* temporaries to save total_in and total_out */
00594 
00595   /* set up */
00596   if (z == Z_NULL || z->In_state == Z_NULL)
00597     return Z_STREAM_ERROR;
00598   if (z->In_state->mode != BAD)
00599   {
00600     z->In_state->mode = BAD;
00601     z->In_state->sub.marker = 0;
00602   }
00603   if ((n = z->avail_in) == 0)
00604     return Z_BUF_ERROR;
00605   p = z->next_in;
00606   m = z->In_state->sub.marker;
00607 
00608   /* search */
00609   while (n && m < 4)
00610   {
00611     if (*p == (Byte)(m < 2 ? 0 : 0xff))
00612       m++;
00613     else if (*p)
00614       m = 0;
00615     else
00616       m = 4 - m;
00617     p++, n--;
00618   }
00619 
00620   /* restore */
00621   z->total_in += p - z->next_in;
00622   z->next_in = p;
00623   z->avail_in = n;
00624   z->In_state->sub.marker = m;
00625 
00626   /* return no joy or set up to restart on a new block */
00627   if (m != 4)
00628     return Z_DATA_ERROR;
00629   r = z->total_in;  w = z->total_out;
00630   Reset(z);
00631   z->total_in = r;  z->total_out = w;
00632   z->In_state->mode = BLOCKS;
00633   return Z_OK;
00634 }
00635 
00636 // ------------------------------------------------------------------------------------------
00637 // From infutil.c
00638 // ------------------------------------------------------------------------------------------
00639 
00640 /********************************************************************************************
00641 
00642 >   INT32 ZipInflate::inflate_flush(ZStream *z)
00643 
00644     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00645     Created:    24/05/95
00646     Inputs:     s   current inflate state
00647                 z   zip stream we are to use
00648                 r
00649     Purpose:    copy as much as possible from the sliding window to the output area
00650 
00651 ********************************************************************************************/
00652 
00653 INT32 ZipInflate::inflate_flush(inflate_blocks_state *s, ZStream *z, INT32 r)
00654 {
00655   uInt n;
00656   Bytef *p, *q;
00657 
00658   /* local copies of source and destination pointers */
00659   p = z->next_out;
00660   q = s->read;
00661 
00662   /* compute number of bytes to copy as far as end of window */
00663   n = (uInt)((q <= s->write ? s->write : s->end) - q);
00664   if (n > z->avail_out) n = z->avail_out;
00665   if (n && r == Z_BUF_ERROR) r = Z_OK;
00666 
00667   /* update counters */
00668   z->avail_out -= n;
00669   z->total_out += n;
00670 
00671   /* update check information */
00672   if (s->checkfn != Z_NULL)
00673     z->adler = s->check = (*s->checkfn)(s->check, q, n);
00674 
00675   /* copy as far as end of window */
00676   zmemcpy(p, q, n);
00677   p += n;
00678   q += n;
00679 
00680   /* see if more to copy at beginning of window */
00681   if (q == s->end)
00682   {
00683     /* wrap pointers */
00684     q = s->window;
00685     if (s->write == s->end)
00686       s->write = s->window;
00687 
00688     /* compute bytes to copy */
00689     n = (uInt)(s->write - q);
00690     if (n > z->avail_out) n = z->avail_out;
00691     if (n && r == Z_BUF_ERROR) r = Z_OK;
00692 
00693     /* update counters */
00694     z->avail_out -= n;
00695     z->total_out += n;
00696 
00697     /* update check information */
00698     if (s->checkfn != Z_NULL)
00699       z->adler = s->check = (*s->checkfn)(s->check, q, n);
00700 
00701     /* copy */
00702     zmemcpy(p, q, n);
00703     p += n;
00704     q += n;
00705   }
00706 
00707   /* update pointers */
00708   z->next_out = p;
00709   s->read = q;
00710 
00711   /* done */
00712   return r;
00713 }

Generated on Sat Nov 10 03:47:26 2007 for Camelot by  doxygen 1.4.4