Class: Zlib::Deflate

Inherits:
ZStream show all
Defined in:
zlib.c,
zlib.c

Overview

Zlib::Deflate is the class for compressing data. See Zlib::ZStream for more information.

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from ZStream

#adler, #avail_in, #avail_out, #avail_out=, #close, #closed?, #data_type, #end, #ended?, #finish, #finished?, #flush_next_in, #flush_next_out, #reset, #stream_end?, #total_in, #total_out

Constructor Details

#initialize(*args) ⇒ Object

call-seq:

Zlib::Deflate.new(level=DEFAULT_COMPRESSION, window_bits=MAX_WBITS, mem_level=DEF_MEM_LEVEL, strategy=DEFAULT_STRATEGY)

Creates a new deflate stream for compression. If a given argument is nil, the default value of that argument is used.

The level sets the compression level for the deflate stream between 0 (no compression) and 9 (best compression). The following constants have been defined to make code more readable:

  • Zlib::DEFAULT_COMPRESSION

  • Zlib::NO_COMPRESSION

  • Zlib::BEST_SPEED

  • Zlib::BEST_COMPRESSION

See www.zlib.net/manual.html#Constants for further information.

The window_bits sets the size of the history buffer and should be between 8 and 15. Larger values of this parameter result in better compression at the expense of memory usage.

The mem_level specifies how much memory should be allocated for the internal compression state. 1 uses minimum memory but is slow and reduces compression ratio while 9 uses maximum memory for optimal speed. The default value is 8. Two constants are defined:

  • Zlib::DEF_MEM_LEVEL

  • Zlib::MAX_MEM_LEVEL

The strategy sets the deflate compression strategy. The following strategies are available:

Zlib::DEFAULT_STRATEGY

For normal data

Zlib::FILTERED

For data produced by a filter or predictor

Zlib::FIXED

Prevents dynamic Huffman codes

Zlib::HUFFMAN_ONLY

Prevents string matching

Zlib::RLE

Designed for better compression of PNG image data

See the constants for further description.

Examples

Basic

open "compressed.file", "w+" do |io|
  io << Zlib::Deflate.new.deflate(File.read("big.file"))
end

Custom compression

open "compressed.file", "w+" do |compressed_io|
  deflate = Zlib::Deflate.new(Zlib::BEST_COMPRESSION,
                              Zlib::MAX_WBITS,
                              Zlib::MAX_MEM_LEVEL,
                              Zlib::HUFFMAN_ONLY)

  begin
    open "big.file" do |big_io|
      until big_io.eof? do
        compressed_io << zd.deflate(big_io.read(16384))
      end
    end
  ensure
    deflate.close
  end
end

While this example will work, for best optimization review the flags for your specific time, memory usage and output space requirements.



1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
# File 'zlib.c', line 1579

static VALUE
rb_deflate_initialize(int argc, VALUE *argv, VALUE obj)
{
    struct zstream *z;
    VALUE level, wbits, memlevel, strategy;
    int err;

    rb_scan_args(argc, argv, "04", &level, &wbits, &memlevel, &strategy);
    TypedData_Get_Struct(obj, struct zstream, &zstream_data_type, z);

    err = deflateInit2(&z->stream, ARG_LEVEL(level), Z_DEFLATED,
		       ARG_WBITS(wbits), ARG_MEMLEVEL(memlevel),
		       ARG_STRATEGY(strategy));
    if (err != Z_OK) {
	raise_zlib_error(err, z->stream.msg);
    }
    ZSTREAM_READY(z);

    return obj;
}

Class Method Details

.deflate(*args) ⇒ Object

call-seq:

Zlib.deflate(string[, level])
Zlib::Deflate.deflate(string[, level])

Compresses the given string. Valid values of level are Zlib::NO_COMPRESSION, Zlib::BEST_SPEED, Zlib::BEST_COMPRESSION, Zlib::DEFAULT_COMPRESSION, or an integer from 0 to 9.

This method is almost equivalent to the following code:

def deflate(string, level)
  z = Zlib::Deflate.new(level)
  dst = z.deflate(string, Zlib::FINISH)
  z.close
  dst
end

See also Zlib.inflate



1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
# File 'zlib.c', line 1659

static VALUE
rb_deflate_s_deflate(int argc, VALUE *argv, VALUE klass)
{
    struct zstream z;
    VALUE src, level, dst, args[2];
    int err, lev;

    rb_scan_args(argc, argv, "11", &src, &level);

    lev = ARG_LEVEL(level);
    StringValue(src);
    zstream_init_deflate(&z);
    err = deflateInit(&z.stream, lev);
    if (err != Z_OK) {
	raise_zlib_error(err, z.stream.msg);
    }
    ZSTREAM_READY(&z);

    args[0] = (VALUE)&z;
    args[1] = src;
    dst = rb_ensure(deflate_run, (VALUE)args, zstream_ensure_end, (VALUE)&z);

    return dst;
}

Instance Method Details

#<<(src) ⇒ Object

call-seq: << string

Inputs string into the deflate stream just like Zlib::Deflate#deflate, but returns the Zlib::Deflate object itself. The output from the stream is preserved in output buffer.



1744
1745
1746
1747
1748
1749
# File 'zlib.c', line 1744

static VALUE
rb_deflate_addstr(VALUE obj, VALUE src)
{
    do_deflate(get_zstream(obj), src, Z_NO_FLUSH);
    return obj;
}

#deflate(*args) ⇒ Object

call-seq:

z.deflate(string, flush = Zlib::NO_FLUSH)                 -> String
z.deflate(string, flush = Zlib::NO_FLUSH) { |chunk| ... } -> nil

Inputs string into the deflate stream and returns the output from the stream. On calling this method, both the input and the output buffers of the stream are flushed. If string is nil, this method finishes the stream, just like Zlib::ZStream#finish.

If a block is given consecutive deflated chunks from the string are yielded to the block and nil is returned.

The flush parameter specifies the flush mode. The following constants may be used:

Zlib::NO_FLUSH

The default

Zlib::SYNC_FLUSH

Flushes the output to a byte boundary

Zlib::FULL_FLUSH

SYNC_FLUSH + resets the compression state

Zlib::FINISH

Pending input is processed, pending output is flushed.

See the constants for further description.



1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
# File 'zlib.c', line 1723

static VALUE
rb_deflate_deflate(int argc, VALUE *argv, VALUE obj)
{
    struct zstream *z = get_zstream(obj);
    VALUE src, flush;

    rb_scan_args(argc, argv, "11", &src, &flush);
    do_deflate(z, src, ARG_FLUSH(flush));

    return zstream_detach_buffer(z);
}

#flush(*args) ⇒ Object

call-seq:

flush(flush = Zlib::SYNC_FLUSH)                 -> String
flush(flush = Zlib::SYNC_FLUSH) { |chunk| ... } -> nil

This method is equivalent to deflate('', flush). This method is just provided to improve the readability of your Ruby program. If a block is given chunks of deflate output are yielded to the block until the buffer is flushed.

See Zlib::Deflate#deflate for detail on the flush constants NO_FLUSH, SYNC_FLUSH, FULL_FLUSH and FINISH.



1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
# File 'zlib.c', line 1766

static VALUE
rb_deflate_flush(int argc, VALUE *argv, VALUE obj)
{
    struct zstream *z = get_zstream(obj);
    VALUE v_flush;
    int flush;

    rb_scan_args(argc, argv, "01", &v_flush);
    flush = FIXNUMARG(v_flush, Z_SYNC_FLUSH);
    if (flush != Z_NO_FLUSH) {  /* prevent Z_BUF_ERROR */
	zstream_run(z, (Bytef*)"", 0, flush);
    }

    return zstream_detach_buffer(z);
}

#initialize_copy(orig) ⇒ Object

Duplicates the deflate stream.



1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
# File 'zlib.c', line 1605

static VALUE
rb_deflate_init_copy(VALUE self, VALUE orig)
{
    struct zstream *z1, *z2;
    int err;

    TypedData_Get_Struct(self, struct zstream, &zstream_data_type, z1);
    z2 = get_zstream(orig);

    if (z1 == z2) return self;
    err = deflateCopy(&z1->stream, &z2->stream);
    if (err != Z_OK) {
	raise_zlib_error(err, 0);
    }
    z1->input = NIL_P(z2->input) ? Qnil : rb_str_dup(z2->input);
    z1->buf   = NIL_P(z2->buf)   ? Qnil : rb_str_dup(z2->buf);
    z1->flags = z2->flags;

    return self;
}

#params(v_level, v_strategy) ⇒ Object

call-seq: params(level, strategy)

Changes the parameters of the deflate stream to allow changes between different types of data that require different types of compression. Any unprocessed data is flushed before changing the params.

See Zlib::Deflate.new for a description of level and strategy.



1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
# File 'zlib.c', line 1794

static VALUE
rb_deflate_params(VALUE obj, VALUE v_level, VALUE v_strategy)
{
    struct zstream *z = get_zstream(obj);
    int level, strategy;
    int err;
    uInt n;
    long filled;

    level = ARG_LEVEL(v_level);
    strategy = ARG_STRATEGY(v_strategy);

    n = z->stream.avail_out;
    err = deflateParams(&z->stream, level, strategy);
    filled = n - z->stream.avail_out;
    while (err == Z_BUF_ERROR) {
	rb_warning("deflateParams() returned Z_BUF_ERROR");
	zstream_expand_buffer(z);
	rb_str_set_len(z->buf, RSTRING_LEN(z->buf) + filled);
	n = z->stream.avail_out;
	err = deflateParams(&z->stream, level, strategy);
	filled = n - z->stream.avail_out;
    }
    if (err != Z_OK) {
	raise_zlib_error(err, z->stream.msg);
    }
    rb_str_set_len(z->buf, RSTRING_LEN(z->buf) + filled);

    return Qnil;
}

#set_dictionary(dic) ⇒ Object

call-seq: set_dictionary(string)

Sets the preset dictionary and returns string. This method is available just only after Zlib::Deflate.new or Zlib::ZStream#reset method was called. See zlib.h for details.

Can raise errors of Z_STREAM_ERROR if a parameter is invalid (such as NULL dictionary) or the stream state is inconsistent, Z_DATA_ERROR if the given dictionary doesn’t match the expected one (incorrect adler32 value)



1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
# File 'zlib.c', line 1839

static VALUE
rb_deflate_set_dictionary(VALUE obj, VALUE dic)
{
    struct zstream *z = get_zstream(obj);
    VALUE src = dic;
    int err;

    StringValue(src);
    err = deflateSetDictionary(&z->stream,
			       (Bytef*)RSTRING_PTR(src), RSTRING_LENINT(src));
    if (err != Z_OK) {
	raise_zlib_error(err, z->stream.msg);
    }

    return dic;
}