parseCrossRefStream function

PdfCrossRefTable parseCrossRefStream(
  1. PdfDict dict,
  2. Uint8List decodedData
)

Parse a cross-reference stream.

Implementation

PdfCrossRefTable parseCrossRefStream(PdfDict dict, Uint8List decodedData) {
  final table = PdfCrossRefTable();
  table.trailer = dict;

  final wArray = dict.getArray('W');
  if (wArray == null || wArray.length < 3) return table;

  final w = wArray.toIntList();
  final w0 = w[0]; // type field width
  final w1 = w[1]; // field 2 width
  final w2 = w[2]; // field 3 width
  final entrySize = w0 + w1 + w2;

  // Determine index ranges
  List<int> index;
  final indexArray = dict.getArray('Index');
  if (indexArray != null) {
    index = indexArray.toIntList();
  } else {
    final size = dict.getInt('Size') ?? 0;
    index = [0, size];
  }

  int dataPos = 0;
  for (int r = 0; r < index.length - 1; r += 2) {
    final startObj = index[r];
    final count = index[r + 1];

    for (int i = 0;
        i < count && dataPos + entrySize <= decodedData.length;
        i++) {
      int type = 1; // default type
      if (w0 > 0) {
        type = _readInt(decodedData, dataPos, w0);
      }
      final field2 = _readInt(decodedData, dataPos + w0, w1);
      final field3 = _readInt(decodedData, dataPos + w0 + w1, w2);

      switch (type) {
        case 0: // free object
          table.addEntry(
            startObj + i,
            CrossRefEntry(offset: field2, generation: field3, inUse: false),
          );
          break;
        case 1: // uncompressed object
          table.addEntry(
            startObj + i,
            CrossRefEntry(offset: field2, generation: field3, inUse: true),
          );
          break;
        case 2: // compressed object
          table.addEntry(
            startObj + i,
            CrossRefEntry(
              offset: 0,
              generation: 0,
              inUse: true,
              objectStreamNumber: field2,
              objectStreamIndex: field3,
            ),
          );
          break;
      }

      dataPos += entrySize;
    }
  }

  return table;
}