Module: HexaPDF::Filter::FlateDecode

Defined in:
lib/hexapdf/filter/flate_decode.rb

Overview

Implements the Deflate filter using the Zlib library.

See: HexaPDF::Filter, PDF2.0 s7.4.4

Class Method Summary collapse

Class Method Details

.decoder(source, options = nil) ⇒ Object

See HexaPDF::Filter

The decoder also handles the case of an empty string not deflated to a correct flate stream but just output as an empty string.



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/hexapdf/filter/flate_decode.rb', line 55

def self.decoder(source, options = nil)
  fib = Fiber.new do
    inflater = Zlib::Inflate.new
    error_raised = nil

    while source.alive? && (data = source.resume)
      next if data.empty?
      begin
        Fiber.yield(inflater.inflate(data))
      rescue Zlib::DataError, Zlib::BufError => e
        # Only swallow the error if it appears at the end of the stream
        if error_raised || HexaPDF::GlobalConfiguration['filter.flate.on_error'].call(inflater, e)
          raise FilterError, "Problem while decoding Flate encoded stream: #{e}"
        else
          Fiber.yield(inflater.flush_next_out)
          error_raised = e
        end
      end
    end

    begin
      data = inflater.total_in == 0 || (data = inflater.finish).empty? ? nil : data
      inflater.close
      data
    rescue Zlib::DataError, Zlib::BufError => e
      if HexaPDF::GlobalConfiguration['filter.flate.on_error'].call(inflater, e)
        raise FilterError, "Problem while decoding Flate encoded stream: #{e}"
      else
        Fiber.yield(inflater.flush_next_out)
      end
    end
  end

  if options && options[:Predictor]
    Predictor.decoder(fib, options)
  else
    fib
  end
end

.encoder(source, options = nil) ⇒ Object

See HexaPDF::Filter



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/hexapdf/filter/flate_decode.rb', line 96

def self.encoder(source, options = nil)
  if options && options[:Predictor]
    source = Predictor.encoder(source, options)
  end

  Fiber.new do
    deflater = Zlib::Deflate.new(HexaPDF::GlobalConfiguration['filter.flate.compression'],
                                 Zlib::MAX_WBITS,
                                 HexaPDF::GlobalConfiguration['filter.flate.memory'])
    while source.alive? && (data = source.resume)
      data = deflater.deflate(data)
      Fiber.yield(data)
    end
    data = deflater.finish
    deflater.close
    data
  end
end