class PDF::Reader::XRef

def load_xref_stream(stream)


Read an XRef stream from the underlying buffer instead of a traditional xref table.
###############################################################################
def load_xref_stream(stream)
  unless stream.is_a?(PDF::Reader::Stream) && stream.hash[:Type] == :XRef
    raise PDF::Reader::MalformedPDFError, "xref stream not found when expected"
  end
  trailer = Hash[stream.hash.select { |key, value|
    [:Size, :Prev, :Root, :Encrypt, :Info, :ID].include?(key)
  }]
  widths = stream.hash[:W]
  PDF::Reader::Error.validate_type_as_malformed(widths, "xref stream widths", Array)
  entry_length = widths.inject(0) { |s, w|
    unless w.is_a?(Integer)
      w = 0
    end
    s + w
  }
  raw_data     = StringIO.new(stream.unfiltered_data)
  if stream.hash[:Index]
    index = stream.hash[:Index]
  else
    index = [0, stream.hash[:Size]]
  end
  index.each_slice(2) do |start_id, size|
    obj_ids = (start_id..(start_id+(size-1)))
    obj_ids.each do |objid|
      entry = raw_data.read(entry_length) || ""
      f1    = unpack_bytes(entry[0,widths[0]])
      f2    = unpack_bytes(entry[widths[0],widths[1]])
      f3    = unpack_bytes(entry[widths[0]+widths[1],widths[2]])
      if f1 == 1 && f2 > 0
        store(objid, f3, f2 + @junk_offset)
      elsif f1 == 2 && f2 > 0
        store(objid, 0, PDF::Reader::Reference.new(f2, 0))
      end
    end
  end
  load_offsets(trailer[:Prev].to_i) if trailer.has_key?(:Prev)
  trailer
end