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 }