Free cookie consent management tool by TermsFeed Policy Generator

source: branches/RemoveBackwardsCompatibility/HeuristicLab.ExtLibs/HeuristicLab.EPPlus/4.0.3/EPPlus-4.0.3/Packaging/DotNetZip/Zlib/Deflate.cs @ 13401

Last change on this file since 13401 was 12074, checked in by sraggl, 9 years ago

#2341: Added EPPlus-4.0.3 to ExtLibs

File size: 75.8 KB
Line 
1// Deflate.cs
2// ------------------------------------------------------------------
3//
4// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.
5// All rights reserved.
6//
7// This code module is part of DotNetZip, a zipfile class library.
8//
9// ------------------------------------------------------------------
10//
11// This code is licensed under the Microsoft Public License.
12// See the file License.txt for the license details.
13// More info on: http://dotnetzip.codeplex.com
14//
15// ------------------------------------------------------------------
16//
17// last saved (in emacs):
18// Time-stamp: <2011-August-03 19:52:15>
19//
20// ------------------------------------------------------------------
21//
22// This module defines logic for handling the Deflate or compression.
23//
24// This code is based on multiple sources:
25// - the original zlib v1.2.3 source, which is Copyright (C) 1995-2005 Jean-loup Gailly.
26// - the original jzlib, which is Copyright (c) 2000-2003 ymnk, JCraft,Inc.
27//
28// However, this code is significantly different from both.
29// The object model is not the same, and many of the behaviors are different.
30//
31// In keeping with the license for these other works, the copyrights for
32// jzlib and zlib are here.
33//
34// -----------------------------------------------------------------------
35// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
36//
37// Redistribution and use in source and binary forms, with or without
38// modification, are permitted provided that the following conditions are met:
39//
40// 1. Redistributions of source code must retain the above copyright notice,
41// this list of conditions and the following disclaimer.
42//
43// 2. Redistributions in binary form must reproduce the above copyright
44// notice, this list of conditions and the following disclaimer in
45// the documentation and/or other materials provided with the distribution.
46//
47// 3. The names of the authors may not be used to endorse or promote products
48// derived from this software without specific prior written permission.
49//
50// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
51// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
52// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
53// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
54// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
55// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
56// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
57// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
58// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
59// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60//
61// -----------------------------------------------------------------------
62//
63// This program is based on zlib-1.1.3; credit to authors
64// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
65// and contributors of zlib.
66//
67// -----------------------------------------------------------------------
68
69
70using System;
71
72namespace OfficeOpenXml.Packaging.Ionic.Zlib
73{
74
75    internal enum BlockState
76    {
77        NeedMore = 0,       // block not completed, need more input or more output
78        BlockDone,          // block flush performed
79        FinishStarted,              // finish started, need only more output at next deflate
80        FinishDone          // finish done, accept no more input or output
81    }
82
83    internal enum DeflateFlavor
84    {
85        Store,
86        Fast,
87        Slow
88    }
89
90    internal sealed class DeflateManager
91    {
92        private static readonly int MEM_LEVEL_MAX = 9;
93        private static readonly int MEM_LEVEL_DEFAULT = 8;
94
95        internal delegate BlockState CompressFunc(FlushType flush);
96
97        internal class Config
98        {
99            // Use a faster search when the previous match is longer than this
100            internal int GoodLength; // reduce lazy search above this match length
101
102            // Attempt to find a better match only when the current match is
103            // strictly smaller than this value. This mechanism is used only for
104            // compression levels >= 4.  For levels 1,2,3: MaxLazy is actually
105            // MaxInsertLength. (See DeflateFast)
106
107            internal int MaxLazy;    // do not perform lazy search above this match length
108
109            internal int NiceLength; // quit search above this match length
110
111            // To speed up deflation, hash chains are never searched beyond this
112            // length.  A higher limit improves compression ratio but degrades the speed.
113
114            internal int MaxChainLength;
115
116            internal DeflateFlavor Flavor;
117
118            private Config(int goodLength, int maxLazy, int niceLength, int maxChainLength, DeflateFlavor flavor)
119            {
120                this.GoodLength = goodLength;
121                this.MaxLazy = maxLazy;
122                this.NiceLength = niceLength;
123                this.MaxChainLength = maxChainLength;
124                this.Flavor = flavor;
125            }
126
127            public static Config Lookup(CompressionLevel level)
128            {
129                return Table[(int)level];
130            }
131
132
133            static Config()
134            {
135                Table = new Config[] {
136                    new Config(0, 0, 0, 0, DeflateFlavor.Store),
137                    new Config(4, 4, 8, 4, DeflateFlavor.Fast),
138                    new Config(4, 5, 16, 8, DeflateFlavor.Fast),
139                    new Config(4, 6, 32, 32, DeflateFlavor.Fast),
140
141                    new Config(4, 4, 16, 16, DeflateFlavor.Slow),
142                    new Config(8, 16, 32, 32, DeflateFlavor.Slow),
143                    new Config(8, 16, 128, 128, DeflateFlavor.Slow),
144                    new Config(8, 32, 128, 256, DeflateFlavor.Slow),
145                    new Config(32, 128, 258, 1024, DeflateFlavor.Slow),
146                    new Config(32, 258, 258, 4096, DeflateFlavor.Slow),
147                };
148            }
149
150            private static readonly Config[] Table;
151        }
152
153
154        private CompressFunc DeflateFunction;
155
156        private static readonly System.String[] _ErrorMessage = new System.String[]
157        {
158            "need dictionary",
159            "stream end",
160            "",
161            "file error",
162            "stream error",
163            "data error",
164            "insufficient memory",
165            "buffer error",
166            "incompatible version",
167            ""
168        };
169
170        // preset dictionary flag in zlib header
171        private static readonly int PRESET_DICT = 0x20;
172
173        private static readonly int INIT_STATE = 42;
174        private static readonly int BUSY_STATE = 113;
175        private static readonly int FINISH_STATE = 666;
176
177        // The deflate compression method
178        private static readonly int Z_DEFLATED = 8;
179
180        private static readonly int STORED_BLOCK = 0;
181        private static readonly int STATIC_TREES = 1;
182        private static readonly int DYN_TREES = 2;
183
184        // The three kinds of block type
185        private static readonly int Z_BINARY = 0;
186        private static readonly int Z_ASCII = 1;
187        private static readonly int Z_UNKNOWN = 2;
188
189        private static readonly int Buf_size = 8 * 2;
190
191        private static readonly int MIN_MATCH = 3;
192        private static readonly int MAX_MATCH = 258;
193
194        private static readonly int MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1);
195
196        private static readonly int HEAP_SIZE = (2 * InternalConstants.L_CODES + 1);
197
198        private static readonly int END_BLOCK = 256;
199
200        internal ZlibCodec _codec; // the zlib encoder/decoder
201        internal int status;       // as the name implies
202        internal byte[] pending;   // output still pending - waiting to be compressed
203        internal int nextPending;  // index of next pending byte to output to the stream
204        internal int pendingCount; // number of bytes in the pending buffer
205
206        internal sbyte data_type;  // UNKNOWN, BINARY or ASCII
207        internal int last_flush;   // value of flush param for previous deflate call
208
209        internal int w_size;       // LZ77 window size (32K by default)
210        internal int w_bits;       // log2(w_size)  (8..16)
211        internal int w_mask;       // w_size - 1
212
213        //internal byte[] dictionary;
214        internal byte[] window;
215
216        // Sliding window. Input bytes are read into the second half of the window,
217        // and move to the first half later to keep a dictionary of at least wSize
218        // bytes. With this organization, matches are limited to a distance of
219        // wSize-MAX_MATCH bytes, but this ensures that IO is always
220        // performed with a length multiple of the block size.
221        //
222        // To do: use the user input buffer as sliding window.
223
224        internal int window_size;
225        // Actual size of window: 2*wSize, except when the user input buffer
226        // is directly used as sliding window.
227
228        internal short[] prev;
229        // Link to older string with same hash index. To limit the size of this
230        // array to 64K, this link is maintained only for the last 32K strings.
231        // An index in this array is thus a window index modulo 32K.
232
233        internal short[] head;  // Heads of the hash chains or NIL.
234
235        internal int ins_h;     // hash index of string to be inserted
236        internal int hash_size; // number of elements in hash table
237        internal int hash_bits; // log2(hash_size)
238        internal int hash_mask; // hash_size-1
239
240        // Number of bits by which ins_h must be shifted at each input
241        // step. It must be such that after MIN_MATCH steps, the oldest
242        // byte no longer takes part in the hash key, that is:
243        // hash_shift * MIN_MATCH >= hash_bits
244        internal int hash_shift;
245
246        // Window position at the beginning of the current output block. Gets
247        // negative when the window is moved backwards.
248
249        internal int block_start;
250
251        Config config;
252        internal int match_length;    // length of best match
253        internal int prev_match;      // previous match
254        internal int match_available; // set if previous match exists
255        internal int strstart;        // start of string to insert into.....????
256        internal int match_start;     // start of matching string
257        internal int lookahead;       // number of valid bytes ahead in window
258
259        // Length of the best match at previous step. Matches not greater than this
260        // are discarded. This is used in the lazy match evaluation.
261        internal int prev_length;
262
263        // Insert new strings in the hash table only if the match length is not
264        // greater than this length. This saves time but degrades compression.
265        // max_insert_length is used only for compression levels <= 3.
266
267        internal CompressionLevel compressionLevel; // compression level (1..9)
268        internal CompressionStrategy compressionStrategy; // favor or force Huffman coding
269
270
271        internal short[] dyn_ltree;         // literal and length tree
272        internal short[] dyn_dtree;         // distance tree
273        internal short[] bl_tree;           // Huffman tree for bit lengths
274
275        internal Tree treeLiterals = new Tree();  // desc for literal tree
276        internal Tree treeDistances = new Tree();  // desc for distance tree
277        internal Tree treeBitLengths = new Tree(); // desc for bit length tree
278
279        // number of codes at each bit length for an optimal tree
280        internal short[] bl_count = new short[InternalConstants.MAX_BITS + 1];
281
282        // heap used to build the Huffman trees
283        internal int[] heap = new int[2 * InternalConstants.L_CODES + 1];
284
285        internal int heap_len;              // number of elements in the heap
286        internal int heap_max;              // element of largest frequency
287
288        // The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
289        // The same heap array is used to build all trees.
290
291        // Depth of each subtree used as tie breaker for trees of equal frequency
292        internal sbyte[] depth = new sbyte[2 * InternalConstants.L_CODES + 1];
293
294        internal int _lengthOffset;                 // index for literals or lengths
295
296
297        // Size of match buffer for literals/lengths.  There are 4 reasons for
298        // limiting lit_bufsize to 64K:
299        //   - frequencies can be kept in 16 bit counters
300        //   - if compression is not successful for the first block, all input
301        //     data is still in the window so we can still emit a stored block even
302        //     when input comes from standard input.  (This can also be done for
303        //     all blocks if lit_bufsize is not greater than 32K.)
304        //   - if compression is not successful for a file smaller than 64K, we can
305        //     even emit a stored file instead of a stored block (saving 5 bytes).
306        //     This is applicable only for zip (not gzip or zlib).
307        //   - creating new Huffman trees less frequently may not provide fast
308        //     adaptation to changes in the input data statistics. (Take for
309        //     example a binary file with poorly compressible code followed by
310        //     a highly compressible string table.) Smaller buffer sizes give
311        //     fast adaptation but have of course the overhead of transmitting
312        //     trees more frequently.
313
314        internal int lit_bufsize;
315
316        internal int last_lit;     // running index in l_buf
317
318        // Buffer for distances. To simplify the code, d_buf and l_buf have
319        // the same number of elements. To use different lengths, an extra flag
320        // array would be necessary.
321
322        internal int _distanceOffset;        // index into pending; points to distance data??
323
324        internal int opt_len;      // bit length of current block with optimal trees
325        internal int static_len;   // bit length of current block with static trees
326        internal int matches;      // number of string matches in current block
327        internal int last_eob_len; // bit length of EOB code for last block
328
329        // Output buffer. bits are inserted starting at the bottom (least
330        // significant bits).
331        internal short bi_buf;
332
333        // Number of valid bits in bi_buf.  All bits above the last valid bit
334        // are always zero.
335        internal int bi_valid;
336
337
338        internal DeflateManager()
339        {
340            dyn_ltree = new short[HEAP_SIZE * 2];
341            dyn_dtree = new short[(2 * InternalConstants.D_CODES + 1) * 2]; // distance tree
342            bl_tree = new short[(2 * InternalConstants.BL_CODES + 1) * 2]; // Huffman tree for bit lengths
343        }
344
345
346        // lm_init
347        private void _InitializeLazyMatch()
348        {
349            window_size = 2 * w_size;
350
351            // clear the hash - workitem 9063
352            Array.Clear(head, 0, hash_size);
353            //for (int i = 0; i < hash_size; i++) head[i] = 0;
354
355            config = Config.Lookup(compressionLevel);
356            SetDeflater();
357
358            strstart = 0;
359            block_start = 0;
360            lookahead = 0;
361            match_length = prev_length = MIN_MATCH - 1;
362            match_available = 0;
363            ins_h = 0;
364        }
365
366        // Initialize the tree data structures for a new zlib stream.
367        private void _InitializeTreeData()
368        {
369            treeLiterals.dyn_tree = dyn_ltree;
370            treeLiterals.staticTree = StaticTree.Literals;
371
372            treeDistances.dyn_tree = dyn_dtree;
373            treeDistances.staticTree = StaticTree.Distances;
374
375            treeBitLengths.dyn_tree = bl_tree;
376            treeBitLengths.staticTree = StaticTree.BitLengths;
377
378            bi_buf = 0;
379            bi_valid = 0;
380            last_eob_len = 8; // enough lookahead for inflate
381
382            // Initialize the first block of the first file:
383            _InitializeBlocks();
384        }
385
386        internal void _InitializeBlocks()
387        {
388            // Initialize the trees.
389            for (int i = 0; i < InternalConstants.L_CODES; i++)
390                dyn_ltree[i * 2] = 0;
391            for (int i = 0; i < InternalConstants.D_CODES; i++)
392                dyn_dtree[i * 2] = 0;
393            for (int i = 0; i < InternalConstants.BL_CODES; i++)
394                bl_tree[i * 2] = 0;
395
396            dyn_ltree[END_BLOCK * 2] = 1;
397            opt_len = static_len = 0;
398            last_lit = matches = 0;
399        }
400
401        // Restore the heap property by moving down the tree starting at node k,
402        // exchanging a node with the smallest of its two sons if necessary, stopping
403        // when the heap property is re-established (each father smaller than its
404        // two sons).
405        internal void pqdownheap(short[] tree, int k)
406        {
407            int v = heap[k];
408            int j = k << 1; // left son of k
409            while (j <= heap_len)
410            {
411                // Set j to the smallest of the two sons:
412                if (j < heap_len && _IsSmaller(tree, heap[j + 1], heap[j], depth))
413                {
414                    j++;
415                }
416                // Exit if v is smaller than both sons
417                if (_IsSmaller(tree, v, heap[j], depth))
418                    break;
419
420                // Exchange v with the smallest son
421                heap[k] = heap[j]; k = j;
422                // And continue down the tree, setting j to the left son of k
423                j <<= 1;
424            }
425            heap[k] = v;
426        }
427
428        internal static bool _IsSmaller(short[] tree, int n, int m, sbyte[] depth)
429        {
430            short tn2 = tree[n * 2];
431            short tm2 = tree[m * 2];
432            return (tn2 < tm2 || (tn2 == tm2 && depth[n] <= depth[m]));
433        }
434
435
436        // Scan a literal or distance tree to determine the frequencies of the codes
437        // in the bit length tree.
438        internal void scan_tree(short[] tree, int max_code)
439        {
440            int n; // iterates over all tree elements
441            int prevlen = -1; // last emitted length
442            int curlen; // length of current code
443            int nextlen = (int)tree[0 * 2 + 1]; // length of next code
444            int count = 0; // repeat count of the current code
445            int max_count = 7; // max repeat count
446            int min_count = 4; // min repeat count
447
448            if (nextlen == 0)
449            {
450                max_count = 138; min_count = 3;
451            }
452            tree[(max_code + 1) * 2 + 1] = (short)0x7fff; // guard //??
453
454            for (n = 0; n <= max_code; n++)
455            {
456                curlen = nextlen; nextlen = (int)tree[(n + 1) * 2 + 1];
457                if (++count < max_count && curlen == nextlen)
458                {
459                    continue;
460                }
461                else if (count < min_count)
462                {
463                    bl_tree[curlen * 2] = (short)(bl_tree[curlen * 2] + count);
464                }
465                else if (curlen != 0)
466                {
467                    if (curlen != prevlen)
468                        bl_tree[curlen * 2]++;
469                    bl_tree[InternalConstants.REP_3_6 * 2]++;
470                }
471                else if (count <= 10)
472                {
473                    bl_tree[InternalConstants.REPZ_3_10 * 2]++;
474                }
475                else
476                {
477                    bl_tree[InternalConstants.REPZ_11_138 * 2]++;
478                }
479                count = 0; prevlen = curlen;
480                if (nextlen == 0)
481                {
482                    max_count = 138; min_count = 3;
483                }
484                else if (curlen == nextlen)
485                {
486                    max_count = 6; min_count = 3;
487                }
488                else
489                {
490                    max_count = 7; min_count = 4;
491                }
492            }
493        }
494
495        // Construct the Huffman tree for the bit lengths and return the index in
496        // bl_order of the last bit length code to send.
497        internal int build_bl_tree()
498        {
499            int max_blindex; // index of last bit length code of non zero freq
500
501            // Determine the bit length frequencies for literal and distance trees
502            scan_tree(dyn_ltree, treeLiterals.max_code);
503            scan_tree(dyn_dtree, treeDistances.max_code);
504
505            // Build the bit length tree:
506            treeBitLengths.build_tree(this);
507            // opt_len now includes the length of the tree representations, except
508            // the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
509
510            // Determine the number of bit length codes to send. The pkzip format
511            // requires that at least 4 bit length codes be sent. (appnote.txt says
512            // 3 but the actual value used is 4.)
513            for (max_blindex = InternalConstants.BL_CODES - 1; max_blindex >= 3; max_blindex--)
514            {
515                if (bl_tree[Tree.bl_order[max_blindex] * 2 + 1] != 0)
516                    break;
517            }
518            // Update opt_len to include the bit length tree and counts
519            opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;
520
521            return max_blindex;
522        }
523
524
525        // Send the header for a block using dynamic Huffman trees: the counts, the
526        // lengths of the bit length codes, the literal tree and the distance tree.
527        // IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
528        internal void send_all_trees(int lcodes, int dcodes, int blcodes)
529        {
530            int rank; // index in bl_order
531
532            send_bits(lcodes - 257, 5); // not +255 as stated in appnote.txt
533            send_bits(dcodes - 1, 5);
534            send_bits(blcodes - 4, 4); // not -3 as stated in appnote.txt
535            for (rank = 0; rank < blcodes; rank++)
536            {
537                send_bits(bl_tree[Tree.bl_order[rank] * 2 + 1], 3);
538            }
539            send_tree(dyn_ltree, lcodes - 1); // literal tree
540            send_tree(dyn_dtree, dcodes - 1); // distance tree
541        }
542
543        // Send a literal or distance tree in compressed form, using the codes in
544        // bl_tree.
545        internal void send_tree(short[] tree, int max_code)
546        {
547            int n;                           // iterates over all tree elements
548            int prevlen   = -1;              // last emitted length
549            int curlen;                      // length of current code
550            int nextlen   = tree[0 * 2 + 1]; // length of next code
551            int count     = 0;               // repeat count of the current code
552            int max_count = 7;               // max repeat count
553            int min_count = 4;               // min repeat count
554
555            if (nextlen == 0)
556            {
557                max_count = 138; min_count = 3;
558            }
559
560            for (n = 0; n <= max_code; n++)
561            {
562                curlen = nextlen; nextlen = tree[(n + 1) * 2 + 1];
563                if (++count < max_count && curlen == nextlen)
564                {
565                    continue;
566                }
567                else if (count < min_count)
568                {
569                    do
570                    {
571                        send_code(curlen, bl_tree);
572                    }
573                    while (--count != 0);
574                }
575                else if (curlen != 0)
576                {
577                    if (curlen != prevlen)
578                    {
579                        send_code(curlen, bl_tree); count--;
580                    }
581                    send_code(InternalConstants.REP_3_6, bl_tree);
582                    send_bits(count - 3, 2);
583                }
584                else if (count <= 10)
585                {
586                    send_code(InternalConstants.REPZ_3_10, bl_tree);
587                    send_bits(count - 3, 3);
588                }
589                else
590                {
591                    send_code(InternalConstants.REPZ_11_138, bl_tree);
592                    send_bits(count - 11, 7);
593                }
594                count = 0; prevlen = curlen;
595                if (nextlen == 0)
596                {
597                    max_count = 138; min_count = 3;
598                }
599                else if (curlen == nextlen)
600                {
601                    max_count = 6; min_count = 3;
602                }
603                else
604                {
605                    max_count = 7; min_count = 4;
606                }
607            }
608        }
609
610        // Output a block of bytes on the stream.
611        // IN assertion: there is enough room in pending_buf.
612        private void put_bytes(byte[] p, int start, int len)
613        {
614            Array.Copy(p, start, pending, pendingCount, len);
615            pendingCount += len;
616        }
617
618#if NOTNEEDED
619        private void put_byte(byte c)
620        {
621            pending[pendingCount++] = c;
622        }
623        internal void put_short(int b)
624        {
625            unchecked
626            {
627                pending[pendingCount++] = (byte)b;
628                pending[pendingCount++] = (byte)(b >> 8);
629            }
630        }
631        internal void putShortMSB(int b)
632        {
633            unchecked
634            {
635                pending[pendingCount++] = (byte)(b >> 8);
636                pending[pendingCount++] = (byte)b;
637            }
638        }
639#endif
640
641        internal void send_code(int c, short[] tree)
642        {
643            int c2 = c * 2;
644            send_bits((tree[c2] & 0xffff), (tree[c2 + 1] & 0xffff));
645        }
646
647        internal void send_bits(int value, int length)
648        {
649            int len = length;
650            unchecked
651            {
652                if (bi_valid > (int)Buf_size - len)
653                {
654                    //int val = value;
655                    //      bi_buf |= (val << bi_valid);
656
657                    bi_buf |= (short)((value << bi_valid) & 0xffff);
658                    //put_short(bi_buf);
659                        pending[pendingCount++] = (byte)bi_buf;
660                        pending[pendingCount++] = (byte)(bi_buf >> 8);
661
662
663                    bi_buf = (short)((uint)value >> (Buf_size - bi_valid));
664                    bi_valid += len - Buf_size;
665                }
666                else
667                {
668                    //      bi_buf |= (value) << bi_valid;
669                    bi_buf |= (short)((value << bi_valid) & 0xffff);
670                    bi_valid += len;
671                }
672            }
673        }
674
675        // Send one empty static block to give enough lookahead for inflate.
676        // This takes 10 bits, of which 7 may remain in the bit buffer.
677        // The current inflate code requires 9 bits of lookahead. If the
678        // last two codes for the previous block (real code plus EOB) were coded
679        // on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
680        // the last real code. In this case we send two empty static blocks instead
681        // of one. (There are no problems if the previous block is stored or fixed.)
682        // To simplify the code, we assume the worst case of last real code encoded
683        // on one bit only.
684        internal void _tr_align()
685        {
686            send_bits(STATIC_TREES << 1, 3);
687            send_code(END_BLOCK, StaticTree.lengthAndLiteralsTreeCodes);
688
689            bi_flush();
690
691            // Of the 10 bits for the empty block, we have already sent
692            // (10 - bi_valid) bits. The lookahead for the last real code (before
693            // the EOB of the previous block) was thus at least one plus the length
694            // of the EOB plus what we have just sent of the empty static block.
695            if (1 + last_eob_len + 10 - bi_valid < 9)
696            {
697                send_bits(STATIC_TREES << 1, 3);
698                send_code(END_BLOCK, StaticTree.lengthAndLiteralsTreeCodes);
699                bi_flush();
700            }
701            last_eob_len = 7;
702        }
703
704
705        // Save the match info and tally the frequency counts. Return true if
706        // the current block must be flushed.
707        internal bool _tr_tally(int dist, int lc)
708        {
709            pending[_distanceOffset + last_lit * 2] = unchecked((byte) ( (uint)dist >> 8 ) );
710            pending[_distanceOffset + last_lit * 2 + 1] = unchecked((byte)dist);
711            pending[_lengthOffset + last_lit] = unchecked((byte)lc);
712            last_lit++;
713
714            if (dist == 0)
715            {
716                // lc is the unmatched char
717                dyn_ltree[lc * 2]++;
718            }
719            else
720            {
721                matches++;
722                // Here, lc is the match length - MIN_MATCH
723                dist--; // dist = match distance - 1
724                dyn_ltree[(Tree.LengthCode[lc] + InternalConstants.LITERALS + 1) * 2]++;
725                dyn_dtree[Tree.DistanceCode(dist) * 2]++;
726            }
727
728            if ((last_lit & 0x1fff) == 0 && (int)compressionLevel > 2)
729            {
730                // Compute an upper bound for the compressed length
731                int out_length = last_lit << 3;
732                int in_length = strstart - block_start;
733                int dcode;
734                for (dcode = 0; dcode < InternalConstants.D_CODES; dcode++)
735                {
736                    out_length = (int)(out_length + (int)dyn_dtree[dcode * 2] * (5L + Tree.ExtraDistanceBits[dcode]));
737                }
738                out_length >>= 3;
739                if ((matches < (last_lit / 2)) && out_length < in_length / 2)
740                    return true;
741            }
742
743            return (last_lit == lit_bufsize - 1) || (last_lit == lit_bufsize);
744            // dinoch - wraparound?
745            // We avoid equality with lit_bufsize because of wraparound at 64K
746            // on 16 bit machines and because stored blocks are restricted to
747            // 64K-1 bytes.
748        }
749
750
751
752        // Send the block data compressed using the given Huffman trees
753        internal void send_compressed_block(short[] ltree, short[] dtree)
754        {
755            int distance; // distance of matched string
756            int lc;       // match length or unmatched char (if dist == 0)
757            int lx = 0;   // running index in l_buf
758            int code;     // the code to send
759            int extra;    // number of extra bits to send
760
761            if (last_lit != 0)
762            {
763                do
764                {
765                    int ix = _distanceOffset + lx * 2;
766                    distance = ((pending[ix] << 8) & 0xff00) |
767                        (pending[ix + 1] & 0xff);
768                    lc = (pending[_lengthOffset + lx]) & 0xff;
769                    lx++;
770
771                    if (distance == 0)
772                    {
773                        send_code(lc, ltree); // send a literal byte
774                    }
775                    else
776                    {
777                        // literal or match pair
778                        // Here, lc is the match length - MIN_MATCH
779                        code = Tree.LengthCode[lc];
780
781                        // send the length code
782                        send_code(code + InternalConstants.LITERALS + 1, ltree);
783                        extra = Tree.ExtraLengthBits[code];
784                        if (extra != 0)
785                        {
786                            // send the extra length bits
787                            lc -= Tree.LengthBase[code];
788                            send_bits(lc, extra);
789                        }
790                        distance--; // dist is now the match distance - 1
791                        code = Tree.DistanceCode(distance);
792
793                        // send the distance code
794                        send_code(code, dtree);
795
796                        extra = Tree.ExtraDistanceBits[code];
797                        if (extra != 0)
798                        {
799                            // send the extra distance bits
800                            distance -= Tree.DistanceBase[code];
801                            send_bits(distance, extra);
802                        }
803                    }
804
805                    // Check that the overlay between pending and d_buf+l_buf is ok:
806                }
807                while (lx < last_lit);
808            }
809
810            send_code(END_BLOCK, ltree);
811            last_eob_len = ltree[END_BLOCK * 2 + 1];
812        }
813
814
815
816        // Set the data type to ASCII or BINARY, using a crude approximation:
817        // binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
818        // IN assertion: the fields freq of dyn_ltree are set and the total of all
819        // frequencies does not exceed 64K (to fit in an int on 16 bit machines).
820        internal void set_data_type()
821        {
822            int n = 0;
823            int ascii_freq = 0;
824            int bin_freq = 0;
825            while (n < 7)
826            {
827                bin_freq += dyn_ltree[n * 2]; n++;
828            }
829            while (n < 128)
830            {
831                ascii_freq += dyn_ltree[n * 2]; n++;
832            }
833            while (n < InternalConstants.LITERALS)
834            {
835                bin_freq += dyn_ltree[n * 2]; n++;
836            }
837            data_type = (sbyte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
838        }
839
840
841
842        // Flush the bit buffer, keeping at most 7 bits in it.
843        internal void bi_flush()
844        {
845            if (bi_valid == 16)
846            {
847                pending[pendingCount++] = (byte)bi_buf;
848                pending[pendingCount++] = (byte)(bi_buf >> 8);
849                bi_buf = 0;
850                bi_valid = 0;
851            }
852            else if (bi_valid >= 8)
853            {
854                //put_byte((byte)bi_buf);
855                pending[pendingCount++] = (byte)bi_buf;
856                bi_buf >>= 8;
857                bi_valid -= 8;
858            }
859        }
860
861        // Flush the bit buffer and align the output on a byte boundary
862        internal void bi_windup()
863        {
864            if (bi_valid > 8)
865            {
866                pending[pendingCount++] = (byte)bi_buf;
867                pending[pendingCount++] = (byte)(bi_buf >> 8);
868            }
869            else if (bi_valid > 0)
870            {
871                //put_byte((byte)bi_buf);
872                pending[pendingCount++] = (byte)bi_buf;
873            }
874            bi_buf = 0;
875            bi_valid = 0;
876        }
877
878        // Copy a stored block, storing first the length and its
879        // one's complement if requested.
880        internal void copy_block(int buf, int len, bool header)
881        {
882            bi_windup(); // align on byte boundary
883            last_eob_len = 8; // enough lookahead for inflate
884
885            if (header)
886                unchecked
887                {
888                    //put_short((short)len);
889                    pending[pendingCount++] = (byte)len;
890                    pending[pendingCount++] = (byte)(len >> 8);
891                    //put_short((short)~len);
892                    pending[pendingCount++] = (byte)~len;
893                    pending[pendingCount++] = (byte)(~len >> 8);
894                }
895
896            put_bytes(window, buf, len);
897        }
898
899        internal void flush_block_only(bool eof)
900        {
901            _tr_flush_block(block_start >= 0 ? block_start : -1, strstart - block_start, eof);
902            block_start = strstart;
903            _codec.flush_pending();
904        }
905
906        // Copy without compression as much as possible from the input stream, return
907        // the current block state.
908        // This function does not insert new strings in the dictionary since
909        // uncompressible data is probably not useful. This function is used
910        // only for the level=0 compression option.
911        // NOTE: this function should be optimized to avoid extra copying from
912        // window to pending_buf.
913        internal BlockState DeflateNone(FlushType flush)
914        {
915            // Stored blocks are limited to 0xffff bytes, pending is limited
916            // to pending_buf_size, and each stored block has a 5 byte header:
917
918            int max_block_size = 0xffff;
919            int max_start;
920
921            if (max_block_size > pending.Length - 5)
922            {
923                max_block_size = pending.Length - 5;
924            }
925
926            // Copy as much as possible from input to output:
927            while (true)
928            {
929                // Fill the window as much as possible:
930                if (lookahead <= 1)
931                {
932                    _fillWindow();
933                    if (lookahead == 0 && flush == FlushType.None)
934                        return BlockState.NeedMore;
935                    if (lookahead == 0)
936                        break; // flush the current block
937                }
938
939                strstart += lookahead;
940                lookahead = 0;
941
942                // Emit a stored block if pending will be full:
943                max_start = block_start + max_block_size;
944                if (strstart == 0 || strstart >= max_start)
945                {
946                    // strstart == 0 is possible when wraparound on 16-bit machine
947                    lookahead = (int)(strstart - max_start);
948                    strstart = (int)max_start;
949
950                    flush_block_only(false);
951                    if (_codec.AvailableBytesOut == 0)
952                        return BlockState.NeedMore;
953                }
954
955                // Flush if we may have to slide, otherwise block_start may become
956                // negative and the data will be gone:
957                if (strstart - block_start >= w_size - MIN_LOOKAHEAD)
958                {
959                    flush_block_only(false);
960                    if (_codec.AvailableBytesOut == 0)
961                        return BlockState.NeedMore;
962                }
963            }
964
965            flush_block_only(flush == FlushType.Finish);
966            if (_codec.AvailableBytesOut == 0)
967                return (flush == FlushType.Finish) ? BlockState.FinishStarted : BlockState.NeedMore;
968
969            return flush == FlushType.Finish ? BlockState.FinishDone : BlockState.BlockDone;
970        }
971
972
973        // Send a stored block
974        internal void _tr_stored_block(int buf, int stored_len, bool eof)
975        {
976            send_bits((STORED_BLOCK << 1) + (eof ? 1 : 0), 3); // send block type
977            copy_block(buf, stored_len, true); // with header
978        }
979
980        // Determine the best encoding for the current block: dynamic trees, static
981        // trees or store, and output the encoded block to the zip file.
982        internal void _tr_flush_block(int buf, int stored_len, bool eof)
983        {
984            int opt_lenb, static_lenb; // opt_len and static_len in bytes
985            int max_blindex = 0; // index of last bit length code of non zero freq
986
987            // Build the Huffman trees unless a stored block is forced
988            if (compressionLevel > 0)
989            {
990                // Check if the file is ascii or binary
991                if (data_type == Z_UNKNOWN)
992                    set_data_type();
993
994                // Construct the literal and distance trees
995                treeLiterals.build_tree(this);
996
997                treeDistances.build_tree(this);
998
999                // At this point, opt_len and static_len are the total bit lengths of
1000                // the compressed block data, excluding the tree representations.
1001
1002                // Build the bit length tree for the above two trees, and get the index
1003                // in bl_order of the last bit length code to send.
1004                max_blindex = build_bl_tree();
1005
1006                // Determine the best encoding. Compute first the block length in bytes
1007                opt_lenb = (opt_len + 3 + 7) >> 3;
1008                static_lenb = (static_len + 3 + 7) >> 3;
1009
1010                if (static_lenb <= opt_lenb)
1011                    opt_lenb = static_lenb;
1012            }
1013            else
1014            {
1015                opt_lenb = static_lenb = stored_len + 5; // force a stored block
1016            }
1017
1018            if (stored_len + 4 <= opt_lenb && buf != -1)
1019            {
1020                // 4: two words for the lengths
1021                // The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
1022                // Otherwise we can't have processed more than WSIZE input bytes since
1023                // the last block flush, because compression would have been
1024                // successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
1025                // transform a block into a stored block.
1026                _tr_stored_block(buf, stored_len, eof);
1027            }
1028            else if (static_lenb == opt_lenb)
1029            {
1030                send_bits((STATIC_TREES << 1) + (eof ? 1 : 0), 3);
1031                send_compressed_block(StaticTree.lengthAndLiteralsTreeCodes, StaticTree.distTreeCodes);
1032            }
1033            else
1034            {
1035                send_bits((DYN_TREES << 1) + (eof ? 1 : 0), 3);
1036                send_all_trees(treeLiterals.max_code + 1, treeDistances.max_code + 1, max_blindex + 1);
1037                send_compressed_block(dyn_ltree, dyn_dtree);
1038            }
1039
1040            // The above check is made mod 2^32, for files larger than 512 MB
1041            // and uLong implemented on 32 bits.
1042
1043            _InitializeBlocks();
1044
1045            if (eof)
1046            {
1047                bi_windup();
1048            }
1049        }
1050
1051        // Fill the window when the lookahead becomes insufficient.
1052        // Updates strstart and lookahead.
1053        //
1054        // IN assertion: lookahead < MIN_LOOKAHEAD
1055        // OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
1056        //    At least one byte has been read, or avail_in == 0; reads are
1057        //    performed for at least two bytes (required for the zip translate_eol
1058        //    option -- not supported here).
1059        private void _fillWindow()
1060        {
1061            int n, m;
1062            int p;
1063            int more; // Amount of free space at the end of the window.
1064
1065            do
1066            {
1067                more = (window_size - lookahead - strstart);
1068
1069                // Deal with !@#$% 64K limit:
1070                if (more == 0 && strstart == 0 && lookahead == 0)
1071                {
1072                    more = w_size;
1073                }
1074                else if (more == -1)
1075                {
1076                    // Very unlikely, but possible on 16 bit machine if strstart == 0
1077                    // and lookahead == 1 (input done one byte at time)
1078                    more--;
1079
1080                    // If the window is almost full and there is insufficient lookahead,
1081                    // move the upper half to the lower one to make room in the upper half.
1082                }
1083                else if (strstart >= w_size + w_size - MIN_LOOKAHEAD)
1084                {
1085                    Array.Copy(window, w_size, window, 0, w_size);
1086                    match_start -= w_size;
1087                    strstart -= w_size; // we now have strstart >= MAX_DIST
1088                    block_start -= w_size;
1089
1090                    // Slide the hash table (could be avoided with 32 bit values
1091                    // at the expense of memory usage). We slide even when level == 0
1092                    // to keep the hash table consistent if we switch back to level > 0
1093                    // later. (Using level 0 permanently is not an optimal usage of
1094                    // zlib, so we don't care about this pathological case.)
1095
1096                    n = hash_size;
1097                    p = n;
1098                    do
1099                    {
1100                        m = (head[--p] & 0xffff);
1101                        head[p] = (short)((m >= w_size) ? (m - w_size) : 0);
1102                    }
1103                    while (--n != 0);
1104
1105                    n = w_size;
1106                    p = n;
1107                    do
1108                    {
1109                        m = (prev[--p] & 0xffff);
1110                        prev[p] = (short)((m >= w_size) ? (m - w_size) : 0);
1111                        // If n is not on any hash chain, prev[n] is garbage but
1112                        // its value will never be used.
1113                    }
1114                    while (--n != 0);
1115                    more += w_size;
1116                }
1117
1118                if (_codec.AvailableBytesIn == 0)
1119                    return;
1120
1121                // If there was no sliding:
1122                //    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
1123                //    more == window_size - lookahead - strstart
1124                // => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
1125                // => more >= window_size - 2*WSIZE + 2
1126                // In the BIG_MEM or MMAP case (not yet supported),
1127                //   window_size == input_size + MIN_LOOKAHEAD  &&
1128                //   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
1129                // Otherwise, window_size == 2*WSIZE so more >= 2.
1130                // If there was sliding, more >= WSIZE. So in all cases, more >= 2.
1131
1132                n = _codec.read_buf(window, strstart + lookahead, more);
1133                lookahead += n;
1134
1135                // Initialize the hash value now that we have some input:
1136                if (lookahead >= MIN_MATCH)
1137                {
1138                    ins_h = window[strstart] & 0xff;
1139                    ins_h = (((ins_h) << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask;
1140                }
1141                // If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
1142                // but this is not important since only literal bytes will be emitted.
1143            }
1144            while (lookahead < MIN_LOOKAHEAD && _codec.AvailableBytesIn != 0);
1145        }
1146
1147        // Compress as much as possible from the input stream, return the current
1148        // block state.
1149        // This function does not perform lazy evaluation of matches and inserts
1150        // new strings in the dictionary only for unmatched strings or for short
1151        // matches. It is used only for the fast compression options.
1152        internal BlockState DeflateFast(FlushType flush)
1153        {
1154            //    short hash_head = 0; // head of the hash chain
1155            int hash_head = 0; // head of the hash chain
1156            bool bflush; // set if current block must be flushed
1157
1158            while (true)
1159            {
1160                // Make sure that we always have enough lookahead, except
1161                // at the end of the input file. We need MAX_MATCH bytes
1162                // for the next match, plus MIN_MATCH bytes to insert the
1163                // string following the next match.
1164                if (lookahead < MIN_LOOKAHEAD)
1165                {
1166                    _fillWindow();
1167                    if (lookahead < MIN_LOOKAHEAD && flush == FlushType.None)
1168                    {
1169                        return BlockState.NeedMore;
1170                    }
1171                    if (lookahead == 0)
1172                        break; // flush the current block
1173                }
1174
1175                // Insert the string window[strstart .. strstart+2] in the
1176                // dictionary, and set hash_head to the head of the hash chain:
1177                if (lookahead >= MIN_MATCH)
1178                {
1179                    ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
1180
1181                    //  prev[strstart&w_mask]=hash_head=head[ins_h];
1182                    hash_head = (head[ins_h] & 0xffff);
1183                    prev[strstart & w_mask] = head[ins_h];
1184                    head[ins_h] = unchecked((short)strstart);
1185                }
1186
1187                // Find the longest match, discarding those <= prev_length.
1188                // At this point we have always match_length < MIN_MATCH
1189
1190                if (hash_head != 0L && ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD)
1191                {
1192                    // To simplify the code, we prevent matches with the string
1193                    // of window index 0 (in particular we have to avoid a match
1194                    // of the string with itself at the start of the input file).
1195                    if (compressionStrategy != CompressionStrategy.HuffmanOnly)
1196                    {
1197                        match_length = longest_match(hash_head);
1198                    }
1199                    // longest_match() sets match_start
1200                }
1201                if (match_length >= MIN_MATCH)
1202                {
1203                    //        check_match(strstart, match_start, match_length);
1204
1205                    bflush = _tr_tally(strstart - match_start, match_length - MIN_MATCH);
1206
1207                    lookahead -= match_length;
1208
1209                    // Insert new strings in the hash table only if the match length
1210                    // is not too large. This saves time but degrades compression.
1211                    if (match_length <= config.MaxLazy && lookahead >= MIN_MATCH)
1212                    {
1213                        match_length--; // string at strstart already in hash table
1214                        do
1215                        {
1216                            strstart++;
1217
1218                            ins_h = ((ins_h << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
1219                            //      prev[strstart&w_mask]=hash_head=head[ins_h];
1220                            hash_head = (head[ins_h] & 0xffff);
1221                            prev[strstart & w_mask] = head[ins_h];
1222                            head[ins_h] = unchecked((short)strstart);
1223
1224                            // strstart never exceeds WSIZE-MAX_MATCH, so there are
1225                            // always MIN_MATCH bytes ahead.
1226                        }
1227                        while (--match_length != 0);
1228                        strstart++;
1229                    }
1230                    else
1231                    {
1232                        strstart += match_length;
1233                        match_length = 0;
1234                        ins_h = window[strstart] & 0xff;
1235
1236                        ins_h = (((ins_h) << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask;
1237                        // If lookahead < MIN_MATCH, ins_h is garbage, but it does not
1238                        // matter since it will be recomputed at next deflate call.
1239                    }
1240                }
1241                else
1242                {
1243                    // No match, output a literal byte
1244
1245                    bflush = _tr_tally(0, window[strstart] & 0xff);
1246                    lookahead--;
1247                    strstart++;
1248                }
1249                if (bflush)
1250                {
1251                    flush_block_only(false);
1252                    if (_codec.AvailableBytesOut == 0)
1253                        return BlockState.NeedMore;
1254                }
1255            }
1256
1257            flush_block_only(flush == FlushType.Finish);
1258            if (_codec.AvailableBytesOut == 0)
1259            {
1260                if (flush == FlushType.Finish)
1261                    return BlockState.FinishStarted;
1262                else
1263                    return BlockState.NeedMore;
1264            }
1265            return flush == FlushType.Finish ? BlockState.FinishDone : BlockState.BlockDone;
1266        }
1267
1268        // Same as above, but achieves better compression. We use a lazy
1269        // evaluation for matches: a match is finally adopted only if there is
1270        // no better match at the next window position.
1271        internal BlockState DeflateSlow(FlushType flush)
1272        {
1273            //    short hash_head = 0;    // head of hash chain
1274            int hash_head = 0; // head of hash chain
1275            bool bflush; // set if current block must be flushed
1276
1277            // Process the input block.
1278            while (true)
1279            {
1280                // Make sure that we always have enough lookahead, except
1281                // at the end of the input file. We need MAX_MATCH bytes
1282                // for the next match, plus MIN_MATCH bytes to insert the
1283                // string following the next match.
1284
1285                if (lookahead < MIN_LOOKAHEAD)
1286                {
1287                    _fillWindow();
1288                    if (lookahead < MIN_LOOKAHEAD && flush == FlushType.None)
1289                        return BlockState.NeedMore;
1290
1291                    if (lookahead == 0)
1292                        break; // flush the current block
1293                }
1294
1295                // Insert the string window[strstart .. strstart+2] in the
1296                // dictionary, and set hash_head to the head of the hash chain:
1297
1298                if (lookahead >= MIN_MATCH)
1299                {
1300                    ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
1301                    //  prev[strstart&w_mask]=hash_head=head[ins_h];
1302                    hash_head = (head[ins_h] & 0xffff);
1303                    prev[strstart & w_mask] = head[ins_h];
1304                    head[ins_h] = unchecked((short)strstart);
1305                }
1306
1307                // Find the longest match, discarding those <= prev_length.
1308                prev_length = match_length;
1309                prev_match = match_start;
1310                match_length = MIN_MATCH - 1;
1311
1312                if (hash_head != 0 && prev_length < config.MaxLazy &&
1313                    ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD)
1314                {
1315                    // To simplify the code, we prevent matches with the string
1316                    // of window index 0 (in particular we have to avoid a match
1317                    // of the string with itself at the start of the input file).
1318
1319                    if (compressionStrategy != CompressionStrategy.HuffmanOnly)
1320                    {
1321                        match_length = longest_match(hash_head);
1322                    }
1323                    // longest_match() sets match_start
1324
1325                    if (match_length <= 5 && (compressionStrategy == CompressionStrategy.Filtered ||
1326                                              (match_length == MIN_MATCH && strstart - match_start > 4096)))
1327                    {
1328
1329                        // If prev_match is also MIN_MATCH, match_start is garbage
1330                        // but we will ignore the current match anyway.
1331                        match_length = MIN_MATCH - 1;
1332                    }
1333                }
1334
1335                // If there was a match at the previous step and the current
1336                // match is not better, output the previous match:
1337                if (prev_length >= MIN_MATCH && match_length <= prev_length)
1338                {
1339                    int max_insert = strstart + lookahead - MIN_MATCH;
1340                    // Do not insert strings in hash table beyond this.
1341
1342                    //          check_match(strstart-1, prev_match, prev_length);
1343
1344                    bflush = _tr_tally(strstart - 1 - prev_match, prev_length - MIN_MATCH);
1345
1346                    // Insert in hash table all strings up to the end of the match.
1347                    // strstart-1 and strstart are already inserted. If there is not
1348                    // enough lookahead, the last two strings are not inserted in
1349                    // the hash table.
1350                    lookahead -= (prev_length - 1);
1351                    prev_length -= 2;
1352                    do
1353                    {
1354                        if (++strstart <= max_insert)
1355                        {
1356                            ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
1357                            //prev[strstart&w_mask]=hash_head=head[ins_h];
1358                            hash_head = (head[ins_h] & 0xffff);
1359                            prev[strstart & w_mask] = head[ins_h];
1360                            head[ins_h] = unchecked((short)strstart);
1361                        }
1362                    }
1363                    while (--prev_length != 0);
1364                    match_available = 0;
1365                    match_length = MIN_MATCH - 1;
1366                    strstart++;
1367
1368                    if (bflush)
1369                    {
1370                        flush_block_only(false);
1371                        if (_codec.AvailableBytesOut == 0)
1372                            return BlockState.NeedMore;
1373                    }
1374                }
1375                else if (match_available != 0)
1376                {
1377
1378                    // If there was no match at the previous position, output a
1379                    // single literal. If there was a match but the current match
1380                    // is longer, truncate the previous match to a single literal.
1381
1382                    bflush = _tr_tally(0, window[strstart - 1] & 0xff);
1383
1384                    if (bflush)
1385                    {
1386                        flush_block_only(false);
1387                    }
1388                    strstart++;
1389                    lookahead--;
1390                    if (_codec.AvailableBytesOut == 0)
1391                        return BlockState.NeedMore;
1392                }
1393                else
1394                {
1395                    // There is no previous match to compare with, wait for
1396                    // the next step to decide.
1397
1398                    match_available = 1;
1399                    strstart++;
1400                    lookahead--;
1401                }
1402            }
1403
1404            if (match_available != 0)
1405            {
1406                bflush = _tr_tally(0, window[strstart - 1] & 0xff);
1407                match_available = 0;
1408            }
1409            flush_block_only(flush == FlushType.Finish);
1410
1411            if (_codec.AvailableBytesOut == 0)
1412            {
1413                if (flush == FlushType.Finish)
1414                    return BlockState.FinishStarted;
1415                else
1416                    return BlockState.NeedMore;
1417            }
1418
1419            return flush == FlushType.Finish ? BlockState.FinishDone : BlockState.BlockDone;
1420        }
1421
1422
1423        internal int longest_match(int cur_match)
1424        {
1425            int chain_length = config.MaxChainLength; // max hash chain length
1426            int scan         = strstart;              // current string
1427            int match;                                // matched string
1428            int len;                                  // length of current match
1429            int best_len     = prev_length;           // best match length so far
1430            int limit        = strstart > (w_size - MIN_LOOKAHEAD) ? strstart - (w_size - MIN_LOOKAHEAD) : 0;
1431
1432            int niceLength = config.NiceLength;
1433
1434            // Stop when cur_match becomes <= limit. To simplify the code,
1435            // we prevent matches with the string of window index 0.
1436
1437            int wmask = w_mask;
1438
1439            int strend = strstart + MAX_MATCH;
1440            byte scan_end1 = window[scan + best_len - 1];
1441            byte scan_end = window[scan + best_len];
1442
1443            // The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
1444            // It is easy to get rid of this optimization if necessary.
1445
1446            // Do not waste too much time if we already have a good match:
1447            if (prev_length >= config.GoodLength)
1448            {
1449                chain_length >>= 2;
1450            }
1451
1452            // Do not look for matches beyond the end of the input. This is necessary
1453            // to make deflate deterministic.
1454            if (niceLength > lookahead)
1455                niceLength = lookahead;
1456
1457            do
1458            {
1459                match = cur_match;
1460
1461                // Skip to next match if the match length cannot increase
1462                // or if the match length is less than 2:
1463                if (window[match + best_len] != scan_end ||
1464                    window[match + best_len - 1] != scan_end1 ||
1465                    window[match] != window[scan] ||
1466                    window[++match] != window[scan + 1])
1467                    continue;
1468
1469                // The check at best_len-1 can be removed because it will be made
1470                // again later. (This heuristic is not always a win.)
1471                // It is not necessary to compare scan[2] and match[2] since they
1472                // are always equal when the other bytes match, given that
1473                // the hash keys are equal and that HASH_BITS >= 8.
1474                scan += 2; match++;
1475
1476                // We check for insufficient lookahead only every 8th comparison;
1477                // the 256th check will be made at strstart+258.
1478                do
1479                {
1480                }
1481                while (window[++scan] == window[++match] &&
1482                       window[++scan] == window[++match] &&
1483                       window[++scan] == window[++match] &&
1484                       window[++scan] == window[++match] &&
1485                       window[++scan] == window[++match] &&
1486                       window[++scan] == window[++match] &&
1487                       window[++scan] == window[++match] &&
1488                       window[++scan] == window[++match] && scan < strend);
1489
1490                len = MAX_MATCH - (int)(strend - scan);
1491                scan = strend - MAX_MATCH;
1492
1493                if (len > best_len)
1494                {
1495                    match_start = cur_match;
1496                    best_len = len;
1497                    if (len >= niceLength)
1498                        break;
1499                    scan_end1 = window[scan + best_len - 1];
1500                    scan_end = window[scan + best_len];
1501                }
1502            }
1503            while ((cur_match = (prev[cur_match & wmask] & 0xffff)) > limit && --chain_length != 0);
1504
1505            if (best_len <= lookahead)
1506                return best_len;
1507            return lookahead;
1508        }
1509
1510
1511        private bool Rfc1950BytesEmitted = false;
1512        private bool _WantRfc1950HeaderBytes = true;
1513        internal bool WantRfc1950HeaderBytes
1514        {
1515            get { return _WantRfc1950HeaderBytes; }
1516            set { _WantRfc1950HeaderBytes = value; }
1517        }
1518
1519
1520        internal int Initialize(ZlibCodec codec, CompressionLevel level)
1521        {
1522            return Initialize(codec, level, ZlibConstants.WindowBitsMax);
1523        }
1524
1525        internal int Initialize(ZlibCodec codec, CompressionLevel level, int bits)
1526        {
1527            return Initialize(codec, level, bits, MEM_LEVEL_DEFAULT, CompressionStrategy.Default);
1528        }
1529
1530        internal int Initialize(ZlibCodec codec, CompressionLevel level, int bits, CompressionStrategy compressionStrategy)
1531        {
1532            return Initialize(codec, level, bits, MEM_LEVEL_DEFAULT, compressionStrategy);
1533        }
1534
1535        internal int Initialize(ZlibCodec codec, CompressionLevel level, int windowBits, int memLevel, CompressionStrategy strategy)
1536        {
1537            _codec = codec;
1538            _codec.Message = null;
1539
1540            // validation
1541            if (windowBits < 9 || windowBits > 15)
1542                throw new ZlibException("windowBits must be in the range 9..15.");
1543
1544            if (memLevel < 1 || memLevel > MEM_LEVEL_MAX)
1545                throw new ZlibException(String.Format("memLevel must be in the range 1.. {0}", MEM_LEVEL_MAX));
1546
1547            _codec.dstate = this;
1548
1549            w_bits = windowBits;
1550            w_size = 1 << w_bits;
1551            w_mask = w_size - 1;
1552
1553            hash_bits = memLevel + 7;
1554            hash_size = 1 << hash_bits;
1555            hash_mask = hash_size - 1;
1556            hash_shift = ((hash_bits + MIN_MATCH - 1) / MIN_MATCH);
1557
1558            window = new byte[w_size * 2];
1559            prev = new short[w_size];
1560            head = new short[hash_size];
1561
1562            // for memLevel==8, this will be 16384, 16k
1563            lit_bufsize = 1 << (memLevel + 6);
1564
1565            // Use a single array as the buffer for data pending compression,
1566            // the output distance codes, and the output length codes (aka tree).
1567            // orig comment: This works just fine since the average
1568            // output size for (length,distance) codes is <= 24 bits.
1569            pending = new byte[lit_bufsize * 4];
1570            _distanceOffset = lit_bufsize;
1571            _lengthOffset = (1 + 2) * lit_bufsize;
1572
1573            // So, for memLevel 8, the length of the pending buffer is 65536. 64k.
1574            // The first 16k are pending bytes.
1575            // The middle slice, of 32k, is used for distance codes.
1576            // The final 16k are length codes.
1577
1578            this.compressionLevel = level;
1579            this.compressionStrategy = strategy;
1580
1581            Reset();
1582            return ZlibConstants.Z_OK;
1583        }
1584
1585
1586        internal void Reset()
1587        {
1588            _codec.TotalBytesIn = _codec.TotalBytesOut = 0;
1589            _codec.Message = null;
1590            //strm.data_type = Z_UNKNOWN;
1591
1592            pendingCount = 0;
1593            nextPending = 0;
1594
1595            Rfc1950BytesEmitted = false;
1596
1597            status = (WantRfc1950HeaderBytes) ? INIT_STATE : BUSY_STATE;
1598            _codec._Adler32 = Adler.Adler32(0, null, 0, 0);
1599
1600            last_flush = (int)FlushType.None;
1601
1602            _InitializeTreeData();
1603            _InitializeLazyMatch();
1604        }
1605
1606
1607        internal int End()
1608        {
1609            if (status != INIT_STATE && status != BUSY_STATE && status != FINISH_STATE)
1610            {
1611                return ZlibConstants.Z_STREAM_ERROR;
1612            }
1613            // Deallocate in reverse order of allocations:
1614            pending = null;
1615            head = null;
1616            prev = null;
1617            window = null;
1618            // free
1619            // dstate=null;
1620            return status == BUSY_STATE ? ZlibConstants.Z_DATA_ERROR : ZlibConstants.Z_OK;
1621        }
1622
1623
1624        private void SetDeflater()
1625        {
1626            switch (config.Flavor)
1627            {
1628                case DeflateFlavor.Store:
1629                    DeflateFunction = DeflateNone;
1630                    break;
1631                case DeflateFlavor.Fast:
1632                    DeflateFunction = DeflateFast;
1633                    break;
1634                case DeflateFlavor.Slow:
1635                    DeflateFunction = DeflateSlow;
1636                    break;
1637            }
1638        }
1639
1640
1641        internal int SetParams(CompressionLevel level, CompressionStrategy strategy)
1642        {
1643            int result = ZlibConstants.Z_OK;
1644
1645            if (compressionLevel != level)
1646            {
1647                Config newConfig = Config.Lookup(level);
1648
1649                // change in the deflate flavor (Fast vs slow vs none)?
1650                if (newConfig.Flavor != config.Flavor && _codec.TotalBytesIn != 0)
1651                {
1652                    // Flush the last buffer:
1653                    result = _codec.Deflate(FlushType.Partial);
1654                }
1655
1656                compressionLevel = level;
1657                config = newConfig;
1658                SetDeflater();
1659            }
1660
1661            // no need to flush with change in strategy?  Really?
1662            compressionStrategy = strategy;
1663
1664            return result;
1665        }
1666
1667
1668        internal int SetDictionary(byte[] dictionary)
1669        {
1670            int length = dictionary.Length;
1671            int index = 0;
1672
1673            if (dictionary == null || status != INIT_STATE)
1674                throw new ZlibException("Stream error.");
1675
1676            _codec._Adler32 = Adler.Adler32(_codec._Adler32, dictionary, 0, dictionary.Length);
1677
1678            if (length < MIN_MATCH)
1679                return ZlibConstants.Z_OK;
1680            if (length > w_size - MIN_LOOKAHEAD)
1681            {
1682                length = w_size - MIN_LOOKAHEAD;
1683                index = dictionary.Length - length; // use the tail of the dictionary
1684            }
1685            Array.Copy(dictionary, index, window, 0, length);
1686            strstart = length;
1687            block_start = length;
1688
1689            // Insert all strings in the hash table (except for the last two bytes).
1690            // s->lookahead stays null, so s->ins_h will be recomputed at the next
1691            // call of fill_window.
1692
1693            ins_h = window[0] & 0xff;
1694            ins_h = (((ins_h) << hash_shift) ^ (window[1] & 0xff)) & hash_mask;
1695
1696            for (int n = 0; n <= length - MIN_MATCH; n++)
1697            {
1698                ins_h = (((ins_h) << hash_shift) ^ (window[(n) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
1699                prev[n & w_mask] = head[ins_h];
1700                head[ins_h] = (short)n;
1701            }
1702            return ZlibConstants.Z_OK;
1703        }
1704
1705
1706
1707        internal int Deflate(FlushType flush)
1708        {
1709            int old_flush;
1710
1711            if (_codec.OutputBuffer == null ||
1712                (_codec.InputBuffer == null && _codec.AvailableBytesIn != 0) ||
1713                (status == FINISH_STATE && flush != FlushType.Finish))
1714            {
1715                _codec.Message = _ErrorMessage[ZlibConstants.Z_NEED_DICT - (ZlibConstants.Z_STREAM_ERROR)];
1716                throw new ZlibException(String.Format("Something is fishy. [{0}]", _codec.Message));
1717            }
1718            if (_codec.AvailableBytesOut == 0)
1719            {
1720                _codec.Message = _ErrorMessage[ZlibConstants.Z_NEED_DICT - (ZlibConstants.Z_BUF_ERROR)];
1721                throw new ZlibException("OutputBuffer is full (AvailableBytesOut == 0)");
1722            }
1723
1724            old_flush = last_flush;
1725            last_flush = (int)flush;
1726
1727            // Write the zlib (rfc1950) header bytes
1728            if (status == INIT_STATE)
1729            {
1730                int header = (Z_DEFLATED + ((w_bits - 8) << 4)) << 8;
1731                int level_flags = (((int)compressionLevel - 1) & 0xff) >> 1;
1732
1733                if (level_flags > 3)
1734                    level_flags = 3;
1735                header |= (level_flags << 6);
1736                if (strstart != 0)
1737                    header |= PRESET_DICT;
1738                header += 31 - (header % 31);
1739
1740                status = BUSY_STATE;
1741                //putShortMSB(header);
1742                unchecked
1743                {
1744                    pending[pendingCount++] = (byte)(header >> 8);
1745                    pending[pendingCount++] = (byte)header;
1746                }
1747                // Save the adler32 of the preset dictionary:
1748                if (strstart != 0)
1749                {
1750                    pending[pendingCount++] = (byte)((_codec._Adler32 & 0xFF000000) >> 24);
1751                    pending[pendingCount++] = (byte)((_codec._Adler32 & 0x00FF0000) >> 16);
1752                    pending[pendingCount++] = (byte)((_codec._Adler32 & 0x0000FF00) >> 8);
1753                    pending[pendingCount++] = (byte)(_codec._Adler32 & 0x000000FF);
1754                }
1755                _codec._Adler32 = Adler.Adler32(0, null, 0, 0);
1756            }
1757
1758            // Flush as much pending output as possible
1759            if (pendingCount != 0)
1760            {
1761                _codec.flush_pending();
1762                if (_codec.AvailableBytesOut == 0)
1763                {
1764                    //System.out.println("  avail_out==0");
1765                    // Since avail_out is 0, deflate will be called again with
1766                    // more output space, but possibly with both pending and
1767                    // avail_in equal to zero. There won't be anything to do,
1768                    // but this is not an error situation so make sure we
1769                    // return OK instead of BUF_ERROR at next call of deflate:
1770                    last_flush = -1;
1771                    return ZlibConstants.Z_OK;
1772                }
1773
1774                // Make sure there is something to do and avoid duplicate consecutive
1775                // flushes. For repeated and useless calls with Z_FINISH, we keep
1776                // returning Z_STREAM_END instead of Z_BUFF_ERROR.
1777            }
1778            else if (_codec.AvailableBytesIn == 0 &&
1779                     (int)flush <= old_flush &&
1780                     flush != FlushType.Finish)
1781            {
1782                // workitem 8557
1783                //
1784                // Not sure why this needs to be an error.  pendingCount == 0, which
1785                // means there's nothing to deflate.  And the caller has not asked
1786                // for a FlushType.Finish, but...  that seems very non-fatal.  We
1787                // can just say "OK" and do nothing.
1788
1789                // _codec.Message = z_errmsg[ZlibConstants.Z_NEED_DICT - (ZlibConstants.Z_BUF_ERROR)];
1790                // throw new ZlibException("AvailableBytesIn == 0 && flush<=old_flush && flush != FlushType.Finish");
1791
1792                return ZlibConstants.Z_OK;
1793            }
1794
1795            // User must not provide more input after the first FINISH:
1796            if (status == FINISH_STATE && _codec.AvailableBytesIn != 0)
1797            {
1798                _codec.Message = _ErrorMessage[ZlibConstants.Z_NEED_DICT - (ZlibConstants.Z_BUF_ERROR)];
1799                throw new ZlibException("status == FINISH_STATE && _codec.AvailableBytesIn != 0");
1800            }
1801
1802            // Start a new block or continue the current one.
1803            if (_codec.AvailableBytesIn != 0 || lookahead != 0 || (flush != FlushType.None && status != FINISH_STATE))
1804            {
1805                BlockState bstate = DeflateFunction(flush);
1806
1807                if (bstate == BlockState.FinishStarted || bstate == BlockState.FinishDone)
1808                {
1809                    status = FINISH_STATE;
1810                }
1811                if (bstate == BlockState.NeedMore || bstate == BlockState.FinishStarted)
1812                {
1813                    if (_codec.AvailableBytesOut == 0)
1814                    {
1815                        last_flush = -1; // avoid BUF_ERROR next call, see above
1816                    }
1817                    return ZlibConstants.Z_OK;
1818                    // If flush != Z_NO_FLUSH && avail_out == 0, the next call
1819                    // of deflate should use the same flush parameter to make sure
1820                    // that the flush is complete. So we don't have to output an
1821                    // empty block here, this will be done at next call. This also
1822                    // ensures that for a very small output buffer, we emit at most
1823                    // one empty block.
1824                }
1825
1826                if (bstate == BlockState.BlockDone)
1827                {
1828                    if (flush == FlushType.Partial)
1829                    {
1830                        _tr_align();
1831                    }
1832                    else
1833                    {
1834                        // FlushType.Full or FlushType.Sync
1835                        _tr_stored_block(0, 0, false);
1836                        // For a full flush, this empty block will be recognized
1837                        // as a special marker by inflate_sync().
1838                        if (flush == FlushType.Full)
1839                        {
1840                            // clear hash (forget the history)
1841                            for (int i = 0; i < hash_size; i++)
1842                                head[i] = 0;
1843                        }
1844                    }
1845                    _codec.flush_pending();
1846                    if (_codec.AvailableBytesOut == 0)
1847                    {
1848                        last_flush = -1; // avoid BUF_ERROR at next call, see above
1849                        return ZlibConstants.Z_OK;
1850                    }
1851                }
1852            }
1853
1854            if (flush != FlushType.Finish)
1855                return ZlibConstants.Z_OK;
1856
1857            if (!WantRfc1950HeaderBytes || Rfc1950BytesEmitted)
1858                return ZlibConstants.Z_STREAM_END;
1859
1860            // Write the zlib trailer (adler32)
1861            pending[pendingCount++] = (byte)((_codec._Adler32 & 0xFF000000) >> 24);
1862            pending[pendingCount++] = (byte)((_codec._Adler32 & 0x00FF0000) >> 16);
1863            pending[pendingCount++] = (byte)((_codec._Adler32 & 0x0000FF00) >> 8);
1864            pending[pendingCount++] = (byte)(_codec._Adler32 & 0x000000FF);
1865            //putShortMSB((int)(SharedUtils.URShift(_codec._Adler32, 16)));
1866            //putShortMSB((int)(_codec._Adler32 & 0xffff));
1867
1868            _codec.flush_pending();
1869
1870            // If avail_out is zero, the application will call deflate again
1871            // to flush the rest.
1872
1873            Rfc1950BytesEmitted = true; // write the trailer only once!
1874
1875            return pendingCount != 0 ? ZlibConstants.Z_OK : ZlibConstants.Z_STREAM_END;
1876        }
1877
1878    }
1879}
Note: See TracBrowser for help on using the repository browser.