2 * Author : Paul Marquess, <pmqs@cpan.org>
3 * Created : 22nd January 1996
6 * Copyright (c) 1995-2007 Paul Marquess. All rights reserved.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the same terms as Perl itself.
12 /* Parts of this code are based on the files gzio.c and gzappend.c from
13 * the standard zlib source distribution. Below are the copyright statements
17 /* gzio.c -- IO on .gz files
18 * Copyright (C) 1995 Jean-loup Gailly.
19 * For conditions of distribution and use, see copyright notice in zlib.h
22 /* gzappend -- command to append to a gzip file
24 Copyright (C) 2003 Mark Adler, all rights reserved
25 version 1.1, 4 Nov 2003
36 /* zlib prior to 1.06 doesn't know about z_off_t */
41 #if ! defined(ZLIB_VERNUM) || ZLIB_VERNUM < 0x1200
42 # define NEED_DUMMY_BYTE_AT_END
45 #if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1210
49 #if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1221
50 # define AT_LEAST_ZLIB_1_2_2_1
53 #if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1223
54 # define AT_LEAST_ZLIB_1_2_2_3
57 #if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1230
58 # define AT_LEAST_ZLIB_1_2_3
62 # define NEED_sv_2pvbyte
63 # define NEED_sv_2pv_nolen
67 #if PERL_REVISION == 5 && PERL_VERSION == 9
69 # define sv_pvbyte_force(sv,lp) sv_pvbyten_force(sv,lp)
72 #if PERL_REVISION == 5 && (PERL_VERSION < 8 || (PERL_VERSION == 8 && PERL_SUBVERSION < 4 ))
74 # ifdef SvPVbyte_force
75 # undef SvPVbyte_force
78 # define SvPVbyte_force(sv,lp) SvPV_force(sv,lp)
82 #ifndef SvPVbyte_nolen
83 # define SvPVbyte_nolen SvPV_nolen
89 # ifndef SvPVbyte_nolen
90 # define SvPVbyte_nolen SvPV_nolen
93 # ifndef SvPVbyte_force
94 # define SvPVbyte_force(sv,lp) SvPV_force(sv,lp)
98 #if PERL_REVISION == 5 && (PERL_VERSION >= 8 || (PERL_VERSION == 8 && PERL_SUBVERSION < 4 ))
99 # define UTF8_AVAILABLE
102 typedef int DualType ;
103 typedef int int_undef ;
105 typedef struct di_stream {
107 #define FLAG_APPEND 1
109 #define FLAG_ADLER32 4
110 #define FLAG_CONSUME_INPUT 8
121 bool deflateParams_out_valid ;
122 Bytef deflateParams_out_byte;
124 #define deflateParams_BUFFER_SIZE 0x4000
125 uLong deflateParams_out_length;
126 Bytef* deflateParams_out_buffer;
133 uLong bytesInflated ;
134 uLong compressedBytes ;
135 uLong uncompressedBytes ;
138 #define WINDOW_SIZE 32768U
140 bool matchedEndBlock;
142 int window_lastbit, window_left, window_full;
143 unsigned window_have;
144 off_t window_lastoff, window_end;
145 off_t window_endOffset;
147 uLong lastBlockOffset ;
148 unsigned char window_lastByte ;
154 typedef di_stream * deflateStream ;
155 typedef di_stream * Compress__Raw__Zlib__deflateStream ;
156 typedef di_stream * inflateStream ;
157 typedef di_stream * Compress__Raw__Zlib__inflateStream ;
158 typedef di_stream * Compress__Raw__Zlib__inflateScanStream ;
160 #define ZMALLOC(to, typ) ((to = (typ *)safemalloc(sizeof(typ))), \
163 /* Figure out the Operating System */
165 # define OS_CODE 0x00
168 #if defined(AMIGA) || defined(AMIGAOS)
169 # define OS_CODE 0x01
172 #if defined(VAXC) || defined(VMS)
173 # define OS_CODE 0x02
177 # define OS_CODE 0x04
180 #if defined(ATARI) || defined(atarist)
181 # define OS_CODE 0x05
185 # define OS_CODE 0x06
188 #if defined(MACOS) || defined(TARGET_OS_MAC)
189 # define OS_CODE 0x07
193 # define OS_CODE 0x08
197 # define OS_CODE 0x09
201 # define OS_CODE 0x0a
204 #ifdef WIN32 /* Window 95 & Windows NT */
205 # define OS_CODE 0x0b
209 # define OS_CODE 0x0c
212 #if 0 /* Acorn RISCOS */
213 # define OS_CODE 0x0d
217 # define OS_CODE 0x0e
220 #ifdef __50SERIES /* Prime/PRIMOS */
221 # define OS_CODE 0x0F
224 /* Default to UNIX */
226 # define OS_CODE 0x03 /* assume Unix */
230 # define GZIP_OS_CODE OS_CODE
233 #define adlerInitial adler32(0L, Z_NULL, 0)
234 #define crcInitial crc32(0L, Z_NULL, 0)
236 /* static const char * const my_z_errmsg[] = { */
237 static const char my_z_errmsg[][32] = {
238 "need dictionary", /* Z_NEED_DICT 2 */
239 "stream end", /* Z_STREAM_END 1 */
241 "file error", /* Z_ERRNO (-1) */
242 "stream error", /* Z_STREAM_ERROR (-2) */
243 "data error", /* Z_DATA_ERROR (-3) */
244 "insufficient memory", /* Z_MEM_ERROR (-4) */
245 "buffer error", /* Z_BUF_ERROR (-5) */
246 "incompatible version",/* Z_VERSION_ERROR(-6) */
249 #define setDUALstatus(var, err) \
250 sv_setnv(var, (double)err) ; \
251 sv_setpv(var, ((err) ? GetErrorString(err) : "")) ; \
255 #if defined(__SYMBIAN32__)
256 # define NO_WRITEABLE_DATA
259 #define TRACE_DEFAULT 0
261 #ifdef NO_WRITEABLE_DATA
262 # define trace TRACE_DEFAULT
264 static int trace = TRACE_DEFAULT ;
267 /* Dodge PerlIO hiding of these functions. */
272 GetErrorString(int error_no)
274 GetErrorString(error_no)
281 if (error_no == Z_ERRNO) {
282 errstr = Strerror(errno) ;
285 /* errstr = gzerror(fil, &error_no) ; */
286 errstr = (char*) my_z_errmsg[2 - error_no];
295 The following two functions are taken almost directly from
296 examples/gzappend.c. Only cosmetic changes have been made to conform to
297 the coding style of the rest of the code in this file.
301 /* return the greatest common divisor of a and b using Euclid's algorithm,
302 modified to be fast when one argument much greater than the other, and
303 coded to avoid unnecessary swapping */
306 gcd(unsigned a, unsigned b)
331 /* rotate list[0..len-1] left by rot positions, in place */
334 rotate(unsigned char *list, unsigned len, unsigned rot)
336 rotate(list, len, rot)
344 unsigned char *start, *last, *to, *from;
346 /* normalize rot and handle degenerate cases */
348 if (rot >= len) rot %= len;
349 if (rot == 0) return;
351 /* pointer to last entry in list */
352 last = list + (len - 1);
354 /* do simple left shift by one */
357 memcpy(list, list + 1, len - 1);
362 /* do simple right shift by one */
363 if (rot == len - 1) {
365 memmove(list + 1, list, len - 1);
370 /* otherwise do rotate as a set of cycles in place */
371 cycles = gcd(len, rot); /* number of cycles */
373 start = from = list + cycles; /* start index is arbitrary */
374 tmp = *from; /* save entry to be overwritten */
376 to = from; /* next step in cycle */
377 from += rot; /* go right rot positions */
378 if (from > last) from -= len; /* (pointer better not wrap) */
379 if (from == start) break; /* all but one shifted */
380 *to = *from; /* shift left */
382 *to = tmp; /* complete the circle */
386 #endif /* MAGIC_APPEND */
390 DispHex(void * ptr, int length)
397 char * p = (char*)ptr;
399 for (i = 0; i < length; ++i) {
400 printf(" %02x", 0xFF & *(p+i));
407 DispStream(di_stream * s, char * message)
409 DispStream(s, message)
420 #define EnDis(f) (s->flags & f ? "Enabled" : "Disabled")
422 printf("DispStream 0x%p", s) ;
424 printf("- %s \n", message) ;
428 printf(" stream pointer is NULL\n");
431 printf(" stream 0x%p\n", &(s->stream));
432 printf(" zalloc 0x%p\n", s->stream.zalloc);
433 printf(" zfree 0x%p\n", s->stream.zfree);
434 printf(" opaque 0x%p\n", s->stream.opaque);
436 printf(" msg %s\n", s->stream.msg);
439 printf(" next_in 0x%p", s->stream.next_in);
440 if (s->stream.next_in){
442 DispHex(s->stream.next_in, 4);
446 printf(" next_out 0x%p", s->stream.next_out);
447 if (s->stream.next_out){
449 DispHex(s->stream.next_out, 4);
453 printf(" avail_in %lu\n", (unsigned long)s->stream.avail_in);
454 printf(" avail_out %lu\n", (unsigned long)s->stream.avail_out);
455 printf(" total_in %ld\n", s->stream.total_in);
456 printf(" total_out %ld\n", s->stream.total_out);
457 printf(" adler %ld\n", s->stream.adler );
458 printf(" bufsize %ld\n", s->bufsize);
459 printf(" dictionary 0x%p\n", s->dictionary);
460 printf(" dict_adler 0x%ld\n",s->dict_adler);
461 printf(" zip_mode %d\n", s->zip_mode);
462 printf(" crc32 0x%x\n", (unsigned)s->crc32);
463 printf(" adler32 0x%x\n", (unsigned)s->adler32);
464 printf(" flags 0x%x\n", s->flags);
465 printf(" APPEND %s\n", EnDis(FLAG_APPEND));
466 printf(" CRC32 %s\n", EnDis(FLAG_CRC32));
467 printf(" ADLER32 %s\n", EnDis(FLAG_ADLER32));
468 printf(" CONSUME %s\n", EnDis(FLAG_CONSUME_INPUT));
471 printf(" window 0x%p\n", s->window);
487 ZMALLOC(s, di_stream) ;
495 PostInitStream(di_stream * s, int flags, int bufsize, int windowBits)
497 PostInitStream(s, flags, bufsize, windowBits)
504 s->bufsize = bufsize ;
506 s->uncompressedBytes =
509 s->zip_mode = (windowBits < 0) ;
510 if (flags & FLAG_CRC32)
511 s->crc32 = crcInitial ;
512 if (flags & FLAG_ADLER32)
513 s->adler32 = adlerInitial ;
519 deRef(SV * sv, const char * string)
536 croak("%s: buffer parameter is not a SCALAR reference", string);
539 croak("%s: buffer parameter is a reference to a reference", string) ;
551 deRef_l(SV * sv, const char * string)
573 croak("%s: buffer parameter is not a SCALAR reference", string);
576 croak("%s: buffer parameter is a reference to a reference", string) ;
579 if (SvREADONLY(sv) && PL_curcop != &PL_compiling)
580 croak("%s: buffer parameter is read-only", string);
582 SvUPGRADE(sv, SVt_PV);
594 #include "constants.h"
596 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib PREFIX = Zip_
601 INCLUDE: constants.xs
604 /* Check this version of zlib is == 1 */
605 if (zlibVersion()[0] != '1')
606 croak("Compress::Raw::Zlib needs zlib version 1.x\n") ;
609 /* Create the $os_code scalar */
610 SV * os_code_sv = perl_get_sv("Compress::Raw::Zlib::gzip_os_code", GV_ADDMULTI) ;
611 sv_setiv(os_code_sv, GZIP_OS_CODE) ;
615 #define Zip_zlib_version() (const char*)zlib_version
623 RETVAL = ZLIB_VERNUM ;
625 /* 1.1.4 => 0x1140 */
626 RETVAL = (ZLIB_VERSION[0] - '0') << 12 ;
627 RETVAL += (ZLIB_VERSION[2] - '0') << 8 ;
628 RETVAL += (ZLIB_VERSION[4] - '0') << 4 ;
633 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib PREFIX = Zip_
635 #define Zip_adler32(buf, adler) adler32(adler, buf, (uInt)len)
638 Zip_adler32(buf, adler=adlerInitial)
639 uLong adler = NO_INIT
641 Bytef * buf = NO_INIT
644 /* If the buffer is a reference, dereference it */
645 sv = deRef(sv, "adler32") ;
646 #ifdef UTF8_AVAILABLE
647 if (DO_UTF8(sv) && !sv_utf8_downgrade(sv, 1))
648 croak("Wide character in Compress::Raw::Zlib::adler32");
650 buf = (Byte*)SvPVbyte(sv, len) ;
653 adler = adlerInitial;
654 else if (SvOK(ST(1)))
655 adler = SvUV(ST(1)) ;
657 adler = adlerInitial;
661 #define Zip_crc32(buf, crc) crc32(crc, buf, (uInt)len)
664 Zip_crc32(buf, crc=crcInitial)
667 Bytef * buf = NO_INIT
670 /* If the buffer is a reference, dereference it */
671 sv = deRef(sv, "crc32") ;
672 #ifdef UTF8_AVAILABLE
673 if (DO_UTF8(sv) && !sv_utf8_downgrade(sv, 1))
674 croak("Wide character in Compress::Raw::Zlib::crc32");
676 buf = (Byte*)SvPVbyte(sv, len) ;
680 else if (SvOK(ST(1)))
687 crc32_combine(crc1, crc2, len2)
692 #ifndef AT_LEAST_ZLIB_1_2_2_1
693 crc1 = crc1; crc2 = crc2 ; len2 = len2; /* Silence -Wall */
694 croak("crc32_combine needs zlib 1.2.3 or better");
696 RETVAL = crc32_combine(crc1, crc2, len2);
703 adler32_combine(adler1, adler2, len2)
708 #ifndef AT_LEAST_ZLIB_1_2_2_1
709 adler1 = adler1; adler2 = adler2 ; len2 = len2; /* Silence -Wall */
710 croak("adler32_combine needs zlib 1.2.3 or better");
712 RETVAL = adler32_combine(adler1, adler2, len2);
718 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib
721 _deflateInit(flags,level, method, windowBits, memLevel, strategy, bufsize, dictionary)
735 warn("in _deflateInit(level=%d, method=%d, windowBits=%d, memLevel=%d, strategy=%d, bufsize=%ld dictionary=%p)\n",
736 level, method, windowBits, memLevel, strategy, bufsize, dictionary) ;
737 if ((s = InitStream() )) {
741 s->WindowBits = windowBits;
742 s->MemLevel = memLevel;
743 s->Strategy = strategy;
745 err = deflateInit2(&(s->stream), level,
746 method, windowBits, memLevel, strategy);
748 /* Check if a dictionary has been specified */
750 if (err == Z_OK && SvCUR(dictionary)) {
751 #ifdef UTF8_AVAILABLE
752 if (DO_UTF8(dictionary) && !sv_utf8_downgrade(dictionary, 1))
753 croak("Wide character in Compress::Raw::Zlib::Deflate::new dicrionary parameter");
755 err = deflateSetDictionary(&(s->stream), (const Bytef*) SvPVbyte_nolen(dictionary),
757 s->dict_adler = s->stream.adler ;
765 PostInitStream(s, flags, bufsize, windowBits) ;
772 SV* obj = sv_setref_pv(sv_newmortal(),
773 "Compress::Raw::Zlib::deflateStream", (void*)s);
776 if (GIMME == G_ARRAY) {
777 SV * sv = sv_2mortal(newSViv(err)) ;
778 setDUALstatus(sv, err);
783 _inflateInit(flags, windowBits, bufsize, dictionary)
796 croak("inflateScanInit needs zlib 1.2.1 or better");
799 warn("in _inflateInit(windowBits=%d, bufsize=%lu, dictionary=%lu\n",
800 windowBits, bufsize, (unsigned long)SvCUR(dictionary)) ;
801 if ((s = InitStream() )) {
803 s->WindowBits = windowBits;
805 err = inflateInit2(&(s->stream), windowBits);
810 else if (SvCUR(dictionary)) {
811 /* Dictionary specified - take a copy for use in inflate */
812 s->dictionary = newSVsv(dictionary) ;
815 PostInitStream(s, flags, bufsize, windowBits) ;
819 s->window = (unsigned char *)safemalloc(WINDOW_SIZE);
828 SV* obj = sv_setref_pv(sv_newmortal(),
830 ? "Compress::Raw::Zlib::inflateScanStream"
831 : "Compress::Raw::Zlib::inflateStream",
835 if (GIMME == G_ARRAY) {
836 SV * sv = sv_2mortal(newSViv(err)) ;
837 setDUALstatus(sv, err);
843 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::deflateStream
846 DispStream(s, message=NULL)
847 Compress::Raw::Zlib::deflateStream s
852 Compress::Raw::Zlib::deflateStream s
854 RETVAL = deflateReset(&(s->stream)) ;
855 if (RETVAL == Z_OK) {
856 PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ;
862 deflate (s, buf, output)
863 Compress::Raw::Zlib::deflateStream s
866 uInt cur_length = NO_INIT
867 uInt increment = NO_INIT
868 uInt prefix = NO_INIT
870 uLong bufinc = NO_INIT
874 /* If the input buffer is a reference, dereference it */
875 buf = deRef(buf, "deflate") ;
877 /* initialise the input buffer */
878 #ifdef UTF8_AVAILABLE
879 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
880 croak("Wide character in Compress::Raw::Zlib::Deflate::deflate input parameter");
882 s->stream.next_in = (Bytef*)SvPVbyte_nolen(buf) ;
883 s->stream.avail_in = SvCUR(buf) ;
885 if (s->flags & FLAG_CRC32)
886 s->crc32 = crc32(s->crc32, s->stream.next_in, s->stream.avail_in) ;
888 if (s->flags & FLAG_ADLER32)
889 s->adler32 = adler32(s->adler32, s->stream.next_in, s->stream.avail_in) ;
891 /* and retrieve the output buffer */
892 output = deRef_l(output, "deflate") ;
893 #ifdef UTF8_AVAILABLE
894 if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
895 croak("Wide character in Compress::Raw::Zlib::Deflate::deflate output parameter");
898 if((s->flags & FLAG_APPEND) != FLAG_APPEND) {
899 SvCUR_set(output, 0);
900 /* sv_setpvn(output, "", 0); */
902 prefix = cur_length = SvCUR(output) ;
903 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length;
904 increment = SvLEN(output) - cur_length;
905 s->stream.avail_out = increment;
907 /* Check for saved output from deflateParams */
908 if (s->deflateParams_out_valid) {
909 *(s->stream.next_out) = s->deflateParams_out_byte;
910 ++ s->stream.next_out;
911 -- s->stream.avail_out ;
912 s->deflateParams_out_valid = FALSE;
915 /* Check for saved output from deflateParams */
916 if (s->deflateParams_out_length) {
917 uLong plen = s->deflateParams_out_length ;
918 /* printf("Copy %d bytes saved data\n", plen);*/
919 if (s->stream.avail_out < plen) {
920 /*printf("GROW from %d to %d\n", s->stream.avail_out,
921 SvLEN(output) + plen - s->stream.avail_out); */
922 Sv_Grow(output, SvLEN(output) + plen - s->stream.avail_out) ;
925 Copy(s->stream.next_out, s->deflateParams_out_buffer, plen, Bytef) ;
926 cur_length = cur_length + plen;
927 SvCUR_set(output, cur_length);
928 s->stream.next_out += plen ;
929 s->stream.avail_out = SvLEN(output) - cur_length ;
930 increment = s->stream.avail_out;
931 s->deflateParams_out_length = 0;
934 while (s->stream.avail_in != 0) {
936 if (s->stream.avail_out == 0) {
937 /* out of space in the output buffer so make it bigger */
938 Sv_Grow(output, SvLEN(output) + bufinc) ;
939 cur_length += increment ;
940 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
942 s->stream.avail_out = increment;
946 RETVAL = deflate(&(s->stream), Z_NO_FLUSH);
951 s->compressedBytes += cur_length + increment - prefix - s->stream.avail_out ;
952 s->uncompressedBytes += SvCUR(buf) - s->stream.avail_in ;
954 s->last_error = RETVAL ;
955 if (RETVAL == Z_OK) {
957 SvCUR_set(output, cur_length + increment - s->stream.avail_out) ;
966 Compress::Raw::Zlib::deflateStream s
968 deflateEnd(&s->stream) ;
970 SvREFCNT_dec(s->dictionary) ;
972 if (s->deflateParams_out_buffer)
973 Safefree(s->deflateParams_out_buffer);
979 flush(s, output, f=Z_FINISH)
980 Compress::Raw::Zlib::deflateStream s
983 uInt cur_length = NO_INIT
984 uInt increment = NO_INIT
985 uInt prefix = NO_INIT
986 uLong bufinc = NO_INIT
990 s->stream.avail_in = 0; /* should be zero already anyway */
992 /* retrieve the output buffer */
993 output = deRef_l(output, "flush") ;
994 #ifdef UTF8_AVAILABLE
995 if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
996 croak("Wide character in Compress::Raw::Zlib::Deflate::flush input parameter");
998 if(! s->flags & FLAG_APPEND) {
999 SvCUR_set(output, 0);
1000 /* sv_setpvn(output, "", 0); */
1002 prefix = cur_length = SvCUR(output) ;
1003 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length;
1004 increment = SvLEN(output) - cur_length;
1005 s->stream.avail_out = increment;
1007 /* Check for saved output from deflateParams */
1008 if (s->deflateParams_out_valid) {
1009 *(s->stream.next_out) = s->deflateParams_out_byte;
1010 ++ s->stream.next_out;
1011 -- s->stream.avail_out ;
1012 s->deflateParams_out_valid = FALSE;
1015 /* Check for saved output from deflateParams */
1016 if (s->deflateParams_out_length) {
1017 uLong plen = s->deflateParams_out_length ;
1018 /* printf("Copy %d bytes saved data\n", plen); */
1019 if (s->stream.avail_out < plen) {
1020 /* printf("GROW from %d to %d\n", s->stream.avail_out,
1021 SvLEN(output) + plen - s->stream.avail_out); */
1022 Sv_Grow(output, SvLEN(output) + plen - s->stream.avail_out) ;
1025 Copy(s->stream.next_out, s->deflateParams_out_buffer, plen, Bytef) ;
1026 cur_length = cur_length + plen;
1027 SvCUR_set(output, cur_length);
1028 s->stream.next_out += plen ;
1029 s->stream.avail_out = SvLEN(output) - cur_length ;
1030 increment = s->stream.avail_out;
1031 s->deflateParams_out_length = 0;
1036 if (s->stream.avail_out == 0) {
1037 /* consumed all the available output, so extend it */
1038 Sv_Grow(output, SvLEN(output) + bufinc) ;
1039 cur_length += increment ;
1040 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
1041 increment = bufinc ;
1042 s->stream.avail_out = increment;
1045 RETVAL = deflate(&(s->stream), f);
1047 /* deflate has finished flushing only when it hasn't used up
1048 * all the available space in the output buffer:
1050 if (s->stream.avail_out != 0 || RETVAL != Z_OK )
1054 RETVAL = (RETVAL == Z_STREAM_END ? Z_OK : RETVAL) ;
1055 s->last_error = RETVAL ;
1057 s->compressedBytes += cur_length + increment - prefix - s->stream.avail_out ;
1059 if (RETVAL == Z_OK) {
1061 SvCUR_set(output, cur_length + increment - s->stream.avail_out) ;
1069 _deflateParams(s, flags, level, strategy, bufsize)
1070 Compress::Raw::Zlib::deflateStream s
1076 /* printf("_deflateParams(Flags %d Level %d Strategy %d Bufsize %d)\n", flags, level, strategy, bufsize);
1077 printf("Before -- Level %d, Strategy %d, Bufsize %d\n", s->Level, s->Strategy, s->bufsize); */
1081 s->Strategy = strategy ;
1083 s->bufsize = bufsize;
1085 /* printf("After -- Level %d, Strategy %d, Bufsize %d\n", s->Level, s->Strategy, s->bufsize);*/
1087 s->stream.avail_in = 0;
1088 s->stream.next_out = &(s->deflateParams_out_byte) ;
1089 s->stream.avail_out = 1;
1090 RETVAL = deflateParams(&(s->stream), s->Level, s->Strategy);
1091 s->deflateParams_out_valid =
1092 (RETVAL == Z_OK && s->stream.avail_out == 0) ;
1093 /* printf("RETVAL %d, avail out %d, byte %c\n", RETVAL, s->stream.avail_out, s->deflateParams_out_byte); */
1095 /* printf("Level %d Strategy %d, Prev Len %d\n",
1096 s->Level, s->Strategy, s->deflateParams_out_length); */
1097 s->stream.avail_in = 0;
1098 if (s->deflateParams_out_buffer == NULL)
1099 s->deflateParams_out_buffer = safemalloc(deflateParams_BUFFER_SIZE);
1100 s->stream.next_out = s->deflateParams_out_buffer ;
1101 s->stream.avail_out = deflateParams_BUFFER_SIZE;
1103 RETVAL = deflateParams(&(s->stream), s->Level, s->Strategy);
1104 s->deflateParams_out_length = deflateParams_BUFFER_SIZE - s->stream.avail_out;
1105 /* printf("RETVAL %d, length out %d, avail %d\n",
1106 RETVAL, s->deflateParams_out_length, s->stream.avail_out ); */
1114 Compress::Raw::Zlib::deflateStream s
1122 Compress::Raw::Zlib::deflateStream s
1124 RETVAL = s->Strategy ;
1131 Compress::Raw::Zlib::deflateStream s
1133 RETVAL = s->bufsize ;
1140 Compress::Raw::Zlib::deflateStream s
1142 RETVAL = s->last_error ;
1148 Compress::Raw::Zlib::deflateStream s
1156 Compress::Raw::Zlib::deflateStream s
1158 RETVAL = s->dict_adler ;
1164 Compress::Raw::Zlib::deflateStream s
1166 RETVAL = s->adler32 ;
1172 Compress::Raw::Zlib::deflateStream s
1174 RETVAL = s->compressedBytes;
1179 uncompressedBytes(s)
1180 Compress::Raw::Zlib::deflateStream s
1182 RETVAL = s->uncompressedBytes;
1188 Compress::Raw::Zlib::deflateStream s
1190 RETVAL = s->stream.total_in ;
1196 Compress::Raw::Zlib::deflateStream s
1198 RETVAL = s->stream.total_out ;
1204 Compress::Raw::Zlib::deflateStream s
1206 RETVAL = s->stream.msg;
1211 deflateTune(s, good_length, max_lazy, nice_length, max_chain)
1212 Compress::Raw::Zlib::deflateStream s
1218 #ifndef AT_LEAST_ZLIB_1_2_2_3
1219 good_length = good_length; max_lazy = max_lazy ; /* Silence -Wall */
1220 nice_length = nice_length; max_chain = max_chain; /* Silence -Wall */
1221 croak("deflateTune needs zlib 1.2.2.3 or better");
1223 RETVAL = deflateTune(&(s->stream), good_length, max_lazy, nice_length, max_chain);
1229 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::inflateStream
1232 DispStream(s, message=NULL)
1233 Compress::Raw::Zlib::inflateStream s
1238 Compress::Raw::Zlib::inflateStream s
1240 RETVAL = inflateReset(&(s->stream)) ;
1241 if (RETVAL == Z_OK) {
1242 PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ;
1248 inflate (s, buf, output, eof=FALSE)
1249 Compress::Raw::Zlib::inflateStream s
1253 uInt cur_length = 0;
1254 uInt prefix_length = 0;
1256 STRLEN stmp = NO_INIT
1257 uLong bufinc = NO_INIT
1259 #ifdef UTF8_AVAILABLE
1260 bool out_utf8 = FALSE;
1263 bufinc = s->bufsize;
1264 /* If the buffer is a reference, dereference it */
1265 buf = deRef(buf, "inflate") ;
1267 if (s->flags & FLAG_CONSUME_INPUT && SvREADONLY(buf))
1268 croak("Compress::Raw::Zlib::Inflate::inflate input parameter cannot be read-only when ConsumeInput is specified");
1269 #ifdef UTF8_AVAILABLE
1270 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
1271 croak("Wide character in Compress::Raw::Zlib::Inflate::inflate input parameter");
1274 /* initialise the input buffer */
1275 s->stream.next_in = (Bytef*)SvPVbyte_force(buf, stmp) ;
1276 s->stream.avail_in = SvCUR(buf) ;
1278 /* and retrieve the output buffer */
1279 output = deRef_l(output, "inflate") ;
1280 #ifdef UTF8_AVAILABLE
1281 if (DO_UTF8(output))
1283 if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
1284 croak("Wide character in Compress::Raw::Zlib::Inflate::inflate output parameter");
1286 if((s->flags & FLAG_APPEND) != FLAG_APPEND) {
1287 SvCUR_set(output, 0);
1289 if (SvLEN(output)) {
1290 prefix_length = cur_length = SvCUR(output) ;
1291 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length;
1292 increment = SvLEN(output) - cur_length - 1;
1293 s->stream.avail_out = increment;
1296 s->stream.avail_out = 0;
1298 s->bytesInflated = 0;
1302 if (s->stream.avail_out == 0 ) {
1303 /* out of space in the output buffer so make it bigger */
1304 Sv_Grow(output, SvLEN(output) + bufinc) ;
1305 cur_length += increment ;
1306 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
1307 increment = bufinc ;
1308 s->stream.avail_out = increment;
1312 RETVAL = inflate(&(s->stream), Z_SYNC_FLUSH);
1314 if (RETVAL == Z_STREAM_ERROR || RETVAL == Z_MEM_ERROR ||
1315 RETVAL == Z_DATA_ERROR || RETVAL == Z_STREAM_END )
1318 if (RETVAL == Z_BUF_ERROR) {
1319 if (s->stream.avail_out == 0)
1321 if (s->stream.avail_in == 0) {
1327 if (RETVAL == Z_NEED_DICT && s->dictionary) {
1328 s->dict_adler = s->stream.adler ;
1329 RETVAL = inflateSetDictionary(&(s->stream),
1330 (const Bytef*)SvPVbyte_nolen(s->dictionary),
1331 SvCUR(s->dictionary));
1337 #ifdef NEED_DUMMY_BYTE_AT_END
1338 if (eof && RETVAL == Z_OK) {
1339 Bytef* nextIn = s->stream.next_in;
1340 uInt availIn = s->stream.avail_in;
1341 s->stream.next_in = (Bytef*) " ";
1342 s->stream.avail_in = 1;
1343 if (s->stream.avail_out == 0) {
1344 /* out of space in the output buffer so make it bigger */
1345 Sv_Grow(output, SvLEN(output) + bufinc) ;
1346 cur_length += increment ;
1347 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
1348 increment = bufinc ;
1349 s->stream.avail_out = increment;
1352 RETVAL = inflate(&(s->stream), Z_SYNC_FLUSH);
1353 s->stream.next_in = nextIn ;
1354 s->stream.avail_in = availIn ;
1358 s->last_error = RETVAL ;
1359 if (RETVAL == Z_OK || RETVAL == Z_STREAM_END || RETVAL == Z_DATA_ERROR) {
1362 s->bytesInflated = cur_length + increment - s->stream.avail_out - prefix_length;
1363 s->uncompressedBytes += s->bytesInflated ;
1364 s->compressedBytes += SvCUR(buf) - s->stream.avail_in ;
1367 SvCUR_set(output, prefix_length + s->bytesInflated) ;
1368 *SvEND(output) = '\0';
1369 #ifdef UTF8_AVAILABLE
1371 sv_utf8_upgrade(output);
1375 if (s->flags & FLAG_CRC32 )
1376 s->crc32 = crc32(s->crc32,
1377 (const Bytef*)SvPVbyte_nolen(output)+prefix_length,
1378 SvCUR(output)-prefix_length) ;
1380 if (s->flags & FLAG_ADLER32)
1381 s->adler32 = adler32(s->adler32,
1382 (const Bytef*)SvPVbyte_nolen(output)+prefix_length,
1383 SvCUR(output)-prefix_length) ;
1385 /* fix the input buffer */
1386 if (s->flags & FLAG_CONSUME_INPUT) {
1387 in = s->stream.avail_in ;
1388 SvCUR_set(buf, in) ;
1390 Move(s->stream.next_in, SvPVbyte_nolen(buf), in, char) ;
1400 Compress::Raw::Zlib::inflateStream s
1402 RETVAL = s->bytesInflated;
1408 Compress::Raw::Zlib::inflateStream s
1410 RETVAL = s->compressedBytes;
1415 uncompressedBytes(s)
1416 Compress::Raw::Zlib::inflateStream s
1418 RETVAL = s->uncompressedBytes;
1424 inflateSync (s, buf)
1425 Compress::Raw::Zlib::inflateStream s
1429 /* If the buffer is a reference, dereference it */
1430 buf = deRef(buf, "inflateSync") ;
1431 #ifdef UTF8_AVAILABLE
1432 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
1433 croak("Wide character in Compress::Raw::Zlib::Inflate::inflateSync");
1436 /* initialise the input buffer */
1437 s->stream.next_in = (Bytef*)SvPVbyte_nolen(buf) ;
1438 s->stream.avail_in = SvCUR(buf) ;
1440 /* inflateSync doesn't create any output */
1441 s->stream.next_out = (Bytef*) NULL;
1442 s->stream.avail_out = 0;
1444 RETVAL = inflateSync(&(s->stream));
1445 s->last_error = RETVAL ;
1447 /* fix the input buffer */
1449 unsigned in = s->stream.avail_in ;
1450 SvCUR_set(buf, in) ;
1452 Move(s->stream.next_in, SvPVbyte_nolen(buf), in, char) ;
1461 Compress::Raw::Zlib::inflateStream s
1463 inflateEnd(&s->stream) ;
1465 SvREFCNT_dec(s->dictionary) ;
1467 if (s->deflateParams_out_buffer)
1468 Safefree(s->deflateParams_out_buffer);
1472 Safefree(s->window);
1479 Compress::Raw::Zlib::inflateStream s
1481 RETVAL = s->last_error ;
1487 Compress::Raw::Zlib::inflateStream s
1495 Compress::Raw::Zlib::inflateStream s
1497 RETVAL = s->dict_adler ;
1503 Compress::Raw::Zlib::inflateStream s
1505 RETVAL = s->stream.total_in ;
1511 Compress::Raw::Zlib::inflateStream s
1513 RETVAL = s->adler32 ;
1519 Compress::Raw::Zlib::inflateStream s
1521 RETVAL = s->stream.total_out ;
1527 Compress::Raw::Zlib::inflateStream s
1529 RETVAL = s->stream.msg;
1536 Compress::Raw::Zlib::inflateStream s
1538 RETVAL = s->bufsize ;
1544 Compress::Raw::Zlib::inflateStream s
1547 RETVAL = ((s->flags & FLAG_APPEND) == FLAG_APPEND);
1549 s->flags |= FLAG_APPEND ;
1551 s->flags &= ~FLAG_APPEND ;
1555 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::inflateScanStream
1559 Compress::Raw::Zlib::inflateScanStream s
1561 inflateEnd(&s->stream) ;
1563 SvREFCNT_dec(s->dictionary) ;
1565 if (s->deflateParams_out_buffer)
1566 Safefree(s->deflateParams_out_buffer);
1570 Safefree(s->window);
1575 DispStream(s, message=NULL)
1576 Compress::Raw::Zlib::inflateScanStream s
1581 Compress::Raw::Zlib::inflateScanStream s
1583 RETVAL = inflateReset(&(s->stream)) ;
1584 if (RETVAL == Z_OK) {
1585 PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ;
1591 scan(s, buf, out=NULL, eof=FALSE)
1592 Compress::Raw::Zlib::inflateScanStream s
1596 bool eof_mode = FALSE;
1597 int start_len = NO_INIT
1598 STRLEN stmp = NO_INIT
1600 /* If the input buffer is a reference, dereference it */
1601 #ifndef MAGIC_APPEND
1603 croak("scan needs zlib 1.2.1 or better");
1605 buf = deRef(buf, "inflateScan") ;
1606 #ifdef UTF8_AVAILABLE
1607 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
1608 croak("Wide character in Compress::Raw::Zlib::InflateScan::scan input parameter");
1610 /* initialise the input buffer */
1611 s->stream.next_in = (Bytef*)SvPVbyte_force(buf, stmp) ;
1612 s->stream.avail_in = SvCUR(buf) ;
1613 start_len = s->stream.avail_in ;
1614 s->bytesInflated = 0 ;
1617 if (s->stream.avail_in == 0) {
1622 /* set up output to next available section of sliding window */
1623 s->stream.avail_out = WINDOW_SIZE - s->window_have;
1624 s->stream.next_out = s->window + s->window_have;
1626 /* DispStream(s, "before inflate\n"); */
1628 /* inflate and check for errors */
1629 RETVAL = inflate(&(s->stream), Z_BLOCK);
1631 if (start_len > 1 && ! eof_mode)
1632 s->window_lastByte = *(s->stream.next_in - 1 ) ;
1634 if (RETVAL == Z_STREAM_ERROR || RETVAL == Z_MEM_ERROR ||
1635 RETVAL == Z_DATA_ERROR )
1638 if (s->flags & FLAG_CRC32 )
1639 s->crc32 = crc32(s->crc32, s->window + s->window_have,
1640 WINDOW_SIZE - s->window_have - s->stream.avail_out);
1642 if (s->flags & FLAG_ADLER32)
1643 s->adler32 = adler32(s->adler32, s->window + s->window_have,
1644 WINDOW_SIZE - s->window_have - s->stream.avail_out);
1646 s->uncompressedBytes =
1647 s->bytesInflated += WINDOW_SIZE - s->window_have - s->stream.avail_out;
1649 if (s->stream.avail_out)
1650 s->window_have = WINDOW_SIZE - s->stream.avail_out;
1656 /* process end of block */
1657 if (s->stream.data_type & 128) {
1658 if (s->stream.data_type & 64) {
1659 s->window_left = s->stream.data_type & 0x1f;
1662 s->window_lastbit = s->stream.data_type & 0x1f;
1663 s->lastBlockOffset = s->stream.total_in;
1667 } while (RETVAL != Z_STREAM_END);
1669 s->last_error = RETVAL ;
1670 s->window_lastoff = s->stream.total_in ;
1671 s->compressedBytes += SvCUR(buf) - s->stream.avail_in ;
1673 if (RETVAL == Z_STREAM_END)
1675 s->matchedEndBlock = 1 ;
1677 /* save the location of the end of the compressed data */
1678 s->window_end = SvCUR(buf) - s->stream.avail_in - 1 ;
1679 s->window_endOffset = s->stream.total_in ;
1682 -- s->window_endOffset ;
1685 /* if window wrapped, build dictionary from window by rotating */
1686 if (s->window_full) {
1687 rotate(s->window, WINDOW_SIZE, s->window_have);
1688 s->window_have = WINDOW_SIZE;
1691 /* if (s->flags & FLAG_CONSUME_INPUT) { */
1693 unsigned in = s->stream.avail_in ;
1694 SvCUR_set(buf, in) ;
1696 Move(s->stream.next_in, SvPVbyte_nolen(buf), in, char) ;
1708 Compress::Raw::Zlib::inflateScanStream s
1710 #ifndef MAGIC_APPEND
1711 croak("getEndOffset needs zlib 1.2.1 or better");
1713 RETVAL = s->window_endOffset;
1720 Compress::Raw::Zlib::inflateScanStream s
1722 #ifndef MAGIC_APPEND
1723 croak("inflateCount needs zlib 1.2.1 or better");
1725 RETVAL = s->bytesInflated;
1732 Compress::Raw::Zlib::inflateScanStream s
1734 RETVAL = s->compressedBytes;
1739 uncompressedBytes(s)
1740 Compress::Raw::Zlib::inflateScanStream s
1742 RETVAL = s->uncompressedBytes;
1748 getLastBlockOffset(s)
1749 Compress::Raw::Zlib::inflateScanStream s
1751 #ifndef MAGIC_APPEND
1752 croak("getLastBlockOffset needs zlib 1.2.1 or better");
1754 RETVAL = s->lastBlockOffset - (s->window_lastbit != 0);
1760 getLastBufferOffset(s)
1761 Compress::Raw::Zlib::inflateScanStream s
1763 #ifndef MAGIC_APPEND
1764 croak("getLastBufferOffset needs zlib 1.2.1 or better");
1766 RETVAL = s->window_lastoff;
1772 resetLastBlockByte(s, byte)
1773 Compress::Raw::Zlib::inflateScanStream s
1776 #ifndef MAGIC_APPEND
1777 croak("resetLastBlockByte needs zlib 1.2.1 or better");
1780 *byte = *byte ^ (1 << ((8 - s->window_lastbit) & 7));
1785 _createDeflateStream(inf_s, flags,level, method, windowBits, memLevel, strategy, bufsize)
1786 Compress::Raw::Zlib::inflateScanStream inf_s
1796 #ifndef MAGIC_APPEND
1800 windowBits = windowBits;
1801 memLevel = memLevel;
1802 strategy = strategy;
1804 croak("_createDeflateStream needs zlib 1.2.1 or better");
1810 warn("in _createDeflateStream(level=%d, method=%d, windowBits=%d, memLevel=%d, strategy=%d, bufsize=%lu\n",
1811 level, method, windowBits, memLevel, strategy, bufsize) ;
1812 if ((s = InitStream() )) {
1816 s->WindowBits = windowBits;
1817 s->MemLevel = memLevel;
1818 s->Strategy = strategy;
1820 err = deflateInit2(&(s->stream), level,
1821 method, windowBits, memLevel, strategy);
1824 err = deflateSetDictionary(&(s->stream), inf_s->window, inf_s->window_have);
1825 s->dict_adler = s->stream.adler ;
1833 PostInitStream(s, flags, bufsize, windowBits) ;
1834 s->crc32 = inf_s->crc32;
1835 s->adler32 = inf_s->adler32;
1836 s->stream.adler = inf_s->stream.adler ;
1837 /* s->stream.total_out = inf_s->bytesInflated ; */
1838 s->stream.total_in = inf_s->stream.total_out ;
1839 if (inf_s->window_left) {
1840 /* printf("** window_left %d, window_lastByte %d\n", inf_s->window_left, inf_s->window_lastByte); */
1841 deflatePrime(&(s->stream), 8 - inf_s->window_left, inf_s->window_lastByte);
1848 XPUSHs(sv_setref_pv(sv_newmortal(),
1849 "Compress::Raw::Zlib::deflateStream", (void*)s));
1850 if (GIMME == G_ARRAY) {
1851 SV * sv = sv_2mortal(newSViv(err)) ;
1852 setDUALstatus(sv, err);
1860 Compress::Raw::Zlib::inflateScanStream s
1862 RETVAL = s->last_error ;
1868 Compress::Raw::Zlib::inflateScanStream s
1877 Compress::Raw::Zlib::inflateScanStream s
1879 RETVAL = s->adler32 ;