private boolean readCrossrefStream(PDFObject xrefStream, boolean followPrev) throws IOException {

        // the xref stream will have an object number but since there's no
        // decryption involved, it doesn't matter
        if (xrefStream == null) {
            xrefStream = readObject(fileBuf, -1, -1, IdentityDecrypter.getInstance());
            if (!isXrefStream(xrefStream)) {
                throw new PDFParseException("Object found at offset for cross" +
                        " reference stream is not a cross reference stream");
            }
        }


        final int size = xrefStream.getDictRef("Size").getIntValue();
        ensureXrefEntriesCapacity(size);
        final PDFObject[] wObjs = xrefStream.getDictRef("W").getArray();
        final int[] fieldLengths = new int[3];
        int entryLength = 0;
        for (int i = 0; i < 3; ++i) {
            fieldLengths[i] = wObjs[i].getIntValue();
            entryLength += fieldLengths[i];
        }

        final PDFObject[] index;
        final PDFObject indexObj = xrefStream.getDictRef("Index");
        if (indexObj != null) {
            index = indexObj.getArray();
        } else {
            index = new PDFObject[] {
                    new PDFObject(0),
                    new PDFObject(size)
            };             
        }

        final ByteBuffer table = xrefStream.getStreamBuffer();
        for (int i = 0; i < index.length; i += 2) {
            final int start = index[i].getIntValue();
            final int end = start + index[i + 1].getIntValue();
            for (int objNum = start; objNum < end; ++objNum) {
                if (xrefEntries[objNum] == null) {
                    PDFXrefEntry.Type type;
                    if (fieldLengths[0] == 0) {
                        type = PDFXrefEntry.Type.OBJ_IN_BODY;
                    } else {
                        type = PDFXrefEntry.Type.forTypeField(
                                readInt(table, fieldLengths[0]));
                    }
                    int field2  = readInt(table, fieldLengths[1]);
                    // note that this is supposed to default to 0 if field 3
                    // length is 0 for type 1 entries, and that will work just fine
                    int field3  = readInt(table, fieldLengths[2]);
                    xrefEntries[objNum] =
                            type.makeXrefStreamEntry(field2, field3);
                } else {
                    table.position(table.position() + entryLength);
                }
            }
        }
        
        return processTrailerDict(xrefStream, true, followPrev);

    }