module HexaPDF::Filter::FlateDecode

def self.decoder(source, options = nil)

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

See HexaPDF::Filter
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

def self.encoder(source, options = nil)

See HexaPDF::Filter
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