summaryrefslogtreecommitdiff
path: root/deflate.c
diff options
context:
space:
mode:
Diffstat (limited to 'deflate.c')
-rw-r--r--deflate.c139
1 files changed, 85 insertions, 54 deletions
diff --git a/deflate.c b/deflate.c
index db01adf..d34e1ad 100644
--- a/deflate.c
+++ b/deflate.c
@@ -1,5 +1,5 @@
1/* deflate.c -- compress data using the deflation algorithm 1/* deflate.c -- compress data using the deflation algorithm
2 * Copyright (C) 1995-2009 Jean-loup Gailly. 2 * Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
@@ -52,7 +52,7 @@
52#include "deflate.h" 52#include "deflate.h"
53 53
54const char deflate_copyright[] = 54const char deflate_copyright[] =
55 " deflate 1.2.3.4 Copyright 1995-2009 Jean-loup Gailly "; 55 " deflate 1.2.3.5 Copyright 1995-2010 Jean-loup Gailly and Mark Adler ";
56/* 56/*
57 If you use the zlib library in a product, an acknowledgment is welcome 57 If you use the zlib library in a product, an acknowledgment is welcome
58 in the documentation of your product. If for some reason you cannot 58 in the documentation of your product. If for some reason you cannot
@@ -79,19 +79,18 @@ local block_state deflate_fast OF((deflate_state *s, int flush));
79#ifndef FASTEST 79#ifndef FASTEST
80local block_state deflate_slow OF((deflate_state *s, int flush)); 80local block_state deflate_slow OF((deflate_state *s, int flush));
81#endif 81#endif
82local block_state deflate_rle OF((deflate_state *s, int flush));
83local block_state deflate_huff OF((deflate_state *s, int flush));
82local void lm_init OF((deflate_state *s)); 84local void lm_init OF((deflate_state *s));
83local void putShortMSB OF((deflate_state *s, uInt b)); 85local void putShortMSB OF((deflate_state *s, uInt b));
84local void flush_pending OF((z_streamp strm)); 86local void flush_pending OF((z_streamp strm));
85local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); 87local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
86#ifndef FASTEST
87#ifdef ASMV 88#ifdef ASMV
88 void match_init OF((void)); /* asm code initialization */ 89 void match_init OF((void)); /* asm code initialization */
89 uInt longest_match OF((deflate_state *s, IPos cur_match)); 90 uInt longest_match OF((deflate_state *s, IPos cur_match));
90#else 91#else
91local uInt longest_match OF((deflate_state *s, IPos cur_match)); 92local uInt longest_match OF((deflate_state *s, IPos cur_match));
92#endif 93#endif
93#endif
94local uInt longest_match_fast OF((deflate_state *s, IPos cur_match));
95 94
96#ifdef DEBUG 95#ifdef DEBUG
97local void check_match OF((deflate_state *s, IPos start, IPos match, 96local void check_match OF((deflate_state *s, IPos start, IPos match,
@@ -432,9 +431,10 @@ int ZEXPORT deflateParams(strm, level, strategy)
432 } 431 }
433 func = configuration_table[s->level].func; 432 func = configuration_table[s->level].func;
434 433
435 if (func != configuration_table[level].func && strm->total_in != 0) { 434 if ((strategy != s->strategy || func != configuration_table[level].func) &&
435 strm->total_in != 0) {
436 /* Flush the last buffer: */ 436 /* Flush the last buffer: */
437 err = deflate(strm, Z_PARTIAL_FLUSH); 437 err = deflate(strm, Z_BLOCK);
438 } 438 }
439 if (s->level != level) { 439 if (s->level != level) {
440 s->level = level; 440 s->level = level;
@@ -536,7 +536,8 @@ uLong ZEXPORT deflateBound(strm, sourceLen)
536 return complen + wraplen; 536 return complen + wraplen;
537 537
538 /* default settings: return tight bound for that case */ 538 /* default settings: return tight bound for that case */
539 return compressBound(sourceLen) - 6 + wraplen; 539 return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
540 (sourceLen >> 25) + 13 - 6 + wraplen;
540} 541}
541 542
542/* ========================================================================= 543/* =========================================================================
@@ -816,7 +817,9 @@ int ZEXPORT deflate (strm, flush)
816 (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { 817 (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
817 block_state bstate; 818 block_state bstate;
818 819
819 bstate = (*(configuration_table[s->level].func))(s, flush); 820 bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) :
821 (s->strategy == Z_RLE ? deflate_rle(s, flush) :
822 (*(configuration_table[s->level].func))(s, flush));
820 823
821 if (bstate == finish_started || bstate == finish_done) { 824 if (bstate == finish_started || bstate == finish_done) {
822 s->status = FINISH_STATE; 825 s->status = FINISH_STATE;
@@ -1200,12 +1203,13 @@ local uInt longest_match(s, cur_match)
1200 return s->lookahead; 1203 return s->lookahead;
1201} 1204}
1202#endif /* ASMV */ 1205#endif /* ASMV */
1203#endif /* FASTEST */ 1206
1207#else /* FASTEST */
1204 1208
1205/* --------------------------------------------------------------------------- 1209/* ---------------------------------------------------------------------------
1206 * Optimized version for level == 1 or strategy == Z_RLE only 1210 * Optimized version for FASTEST only
1207 */ 1211 */
1208local uInt longest_match_fast(s, cur_match) 1212local uInt longest_match(s, cur_match)
1209 deflate_state *s; 1213 deflate_state *s;
1210 IPos cur_match; /* current match */ 1214 IPos cur_match; /* current match */
1211{ 1215{
@@ -1258,6 +1262,8 @@ local uInt longest_match_fast(s, cur_match)
1258 return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; 1262 return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
1259} 1263}
1260 1264
1265#endif /* FASTEST */
1266
1261#ifdef DEBUG 1267#ifdef DEBUG
1262/* =========================================================================== 1268/* ===========================================================================
1263 * Check that the match at match_start is indeed a match. 1269 * Check that the match at match_start is indeed a match.
@@ -1336,7 +1342,6 @@ local void fill_window(s)
1336 later. (Using level 0 permanently is not an optimal usage of 1342 later. (Using level 0 permanently is not an optimal usage of
1337 zlib, so we don't care about this pathological case.) 1343 zlib, so we don't care about this pathological case.)
1338 */ 1344 */
1339 /* %%% avoid this when Z_RLE */
1340 n = s->hash_size; 1345 n = s->hash_size;
1341 p = &s->head[n]; 1346 p = &s->head[n];
1342 do { 1347 do {
@@ -1516,7 +1521,7 @@ local block_state deflate_fast(s, flush)
1516 deflate_state *s; 1521 deflate_state *s;
1517 int flush; 1522 int flush;
1518{ 1523{
1519 IPos hash_head = NIL; /* head of the hash chain */ 1524 IPos hash_head; /* head of the hash chain */
1520 int bflush; /* set if current block must be flushed */ 1525 int bflush; /* set if current block must be flushed */
1521 1526
1522 for (;;) { 1527 for (;;) {
@@ -1536,6 +1541,7 @@ local block_state deflate_fast(s, flush)
1536 /* Insert the string window[strstart .. strstart+2] in the 1541 /* Insert the string window[strstart .. strstart+2] in the
1537 * dictionary, and set hash_head to the head of the hash chain: 1542 * dictionary, and set hash_head to the head of the hash chain:
1538 */ 1543 */
1544 hash_head = NIL;
1539 if (s->lookahead >= MIN_MATCH) { 1545 if (s->lookahead >= MIN_MATCH) {
1540 INSERT_STRING(s, s->strstart, hash_head); 1546 INSERT_STRING(s, s->strstart, hash_head);
1541 } 1547 }
@@ -1548,19 +1554,8 @@ local block_state deflate_fast(s, flush)
1548 * of window index 0 (in particular we have to avoid a match 1554 * of window index 0 (in particular we have to avoid a match
1549 * of the string with itself at the start of the input file). 1555 * of the string with itself at the start of the input file).
1550 */ 1556 */
1551#ifdef FASTEST 1557 s->match_length = longest_match (s, hash_head);
1552 if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) || 1558 /* longest_match() sets match_start */
1553 (s->strategy == Z_RLE && s->strstart - hash_head == 1)) {
1554 s->match_length = longest_match_fast (s, hash_head);
1555 }
1556#else
1557 if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
1558 s->match_length = longest_match (s, hash_head);
1559 } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
1560 s->match_length = longest_match_fast (s, hash_head);
1561 }
1562#endif
1563 /* longest_match() or longest_match_fast() sets match_start */
1564 } 1559 }
1565 if (s->match_length >= MIN_MATCH) { 1560 if (s->match_length >= MIN_MATCH) {
1566 check_match(s, s->strstart, s->match_start, s->match_length); 1561 check_match(s, s->strstart, s->match_start, s->match_length);
@@ -1622,7 +1617,7 @@ local block_state deflate_slow(s, flush)
1622 deflate_state *s; 1617 deflate_state *s;
1623 int flush; 1618 int flush;
1624{ 1619{
1625 IPos hash_head = NIL; /* head of hash chain */ 1620 IPos hash_head; /* head of hash chain */
1626 int bflush; /* set if current block must be flushed */ 1621 int bflush; /* set if current block must be flushed */
1627 1622
1628 /* Process the input block. */ 1623 /* Process the input block. */
@@ -1643,6 +1638,7 @@ local block_state deflate_slow(s, flush)
1643 /* Insert the string window[strstart .. strstart+2] in the 1638 /* Insert the string window[strstart .. strstart+2] in the
1644 * dictionary, and set hash_head to the head of the hash chain: 1639 * dictionary, and set hash_head to the head of the hash chain:
1645 */ 1640 */
1641 hash_head = NIL;
1646 if (s->lookahead >= MIN_MATCH) { 1642 if (s->lookahead >= MIN_MATCH) {
1647 INSERT_STRING(s, s->strstart, hash_head); 1643 INSERT_STRING(s, s->strstart, hash_head);
1648 } 1644 }
@@ -1658,12 +1654,8 @@ local block_state deflate_slow(s, flush)
1658 * of window index 0 (in particular we have to avoid a match 1654 * of window index 0 (in particular we have to avoid a match
1659 * of the string with itself at the start of the input file). 1655 * of the string with itself at the start of the input file).
1660 */ 1656 */
1661 if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { 1657 s->match_length = longest_match (s, hash_head);
1662 s->match_length = longest_match (s, hash_head); 1658 /* longest_match() sets match_start */
1663 } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
1664 s->match_length = longest_match_fast (s, hash_head);
1665 }
1666 /* longest_match() or longest_match_fast() sets match_start */
1667 1659
1668 if (s->match_length <= 5 && (s->strategy == Z_FILTERED 1660 if (s->match_length <= 5 && (s->strategy == Z_FILTERED
1669#if TOO_FAR <= 32767 1661#if TOO_FAR <= 32767
@@ -1741,7 +1733,6 @@ local block_state deflate_slow(s, flush)
1741} 1733}
1742#endif /* FASTEST */ 1734#endif /* FASTEST */
1743 1735
1744#if 0
1745/* =========================================================================== 1736/* ===========================================================================
1746 * For Z_RLE, simply look for runs of bytes, generate matches only of distance 1737 * For Z_RLE, simply look for runs of bytes, generate matches only of distance
1747 * one. Do not maintain a hash table. (It will be regenerated if this run of 1738 * one. Do not maintain a hash table. (It will be regenerated if this run of
@@ -1751,11 +1742,9 @@ local block_state deflate_rle(s, flush)
1751 deflate_state *s; 1742 deflate_state *s;
1752 int flush; 1743 int flush;
1753{ 1744{
1754 int bflush; /* set if current block must be flushed */ 1745 int bflush; /* set if current block must be flushed */
1755 uInt run; /* length of run */ 1746 uInt prev; /* byte at distance one to match */
1756 uInt max; /* maximum length of run */ 1747 Bytef *scan, *strend; /* scan goes up to strend for length of run */
1757 uInt prev; /* byte at distance one to match */
1758 Bytef *scan; /* scan for end of run */
1759 1748
1760 for (;;) { 1749 for (;;) {
1761 /* Make sure that we always have enough lookahead, except 1750 /* Make sure that we always have enough lookahead, except
@@ -1771,23 +1760,33 @@ local block_state deflate_rle(s, flush)
1771 } 1760 }
1772 1761
1773 /* See how many times the previous byte repeats */ 1762 /* See how many times the previous byte repeats */
1774 run = 0; 1763 s->match_length = 0;
1775 if (s->strstart > 0) { /* if there is a previous byte, that is */ 1764 if (s->lookahead >= MIN_MATCH && s->strstart > 0) {
1776 max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH;
1777 scan = s->window + s->strstart - 1; 1765 scan = s->window + s->strstart - 1;
1778 prev = *scan++; 1766 prev = *scan;
1779 do { 1767 if (prev == *++scan && prev == *++scan && prev == *++scan) {
1780 if (*scan++ != prev) 1768 strend = s->window + s->strstart + MAX_MATCH;
1781 break; 1769 do {
1782 } while (++run < max); 1770 } while (prev == *++scan && prev == *++scan &&
1771 prev == *++scan && prev == *++scan &&
1772 prev == *++scan && prev == *++scan &&
1773 prev == *++scan && prev == *++scan &&
1774 scan < strend);
1775 s->match_length = MAX_MATCH - (int)(strend - scan);
1776 if (s->match_length > s->lookahead)
1777 s->match_length = s->lookahead;
1778 }
1783 } 1779 }
1784 1780
1785 /* Emit match if have run of MIN_MATCH or longer, else emit literal */ 1781 /* Emit match if have run of MIN_MATCH or longer, else emit literal */
1786 if (run >= MIN_MATCH) { 1782 if (s->match_length >= MIN_MATCH) {
1787 check_match(s, s->strstart, s->strstart - 1, run); 1783 check_match(s, s->strstart, s->strstart - 1, s->match_length);
1788 _tr_tally_dist(s, 1, run - MIN_MATCH, bflush); 1784
1789 s->lookahead -= run; 1785 _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush);
1790 s->strstart += run; 1786
1787 s->lookahead -= s->match_length;
1788 s->strstart += s->match_length;
1789 s->match_length = 0;
1791 } else { 1790 } else {
1792 /* No match, output a literal byte */ 1791 /* No match, output a literal byte */
1793 Tracevv((stderr,"%c", s->window[s->strstart])); 1792 Tracevv((stderr,"%c", s->window[s->strstart]));
@@ -1800,4 +1799,36 @@ local block_state deflate_rle(s, flush)
1800 FLUSH_BLOCK(s, flush == Z_FINISH); 1799 FLUSH_BLOCK(s, flush == Z_FINISH);
1801 return flush == Z_FINISH ? finish_done : block_done; 1800 return flush == Z_FINISH ? finish_done : block_done;
1802} 1801}
1803#endif 1802
1803/* ===========================================================================
1804 * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table.
1805 * (It will be regenerated if this run of deflate switches away from Huffman.)
1806 */
1807local block_state deflate_huff(s, flush)
1808 deflate_state *s;
1809 int flush;
1810{
1811 int bflush; /* set if current block must be flushed */
1812
1813 for (;;) {
1814 /* Make sure that we have a literal to write. */
1815 if (s->lookahead == 0) {
1816 fill_window(s);
1817 if (s->lookahead == 0) {
1818 if (flush == Z_NO_FLUSH)
1819 return need_more;
1820 break; /* flush the current block */
1821 }
1822 }
1823
1824 /* Output a literal byte */
1825 s->match_length = 0;
1826 Tracevv((stderr,"%c", s->window[s->strstart]));
1827 _tr_tally_lit (s, s->window[s->strstart], bflush);
1828 s->lookahead--;
1829 s->strstart++;
1830 if (bflush) FLUSH_BLOCK(s, 0);
1831 }
1832 FLUSH_BLOCK(s, flush == Z_FINISH);
1833 return flush == Z_FINISH ? finish_done : block_done;
1834}