static byte[] getBytes(final long start, final int count, final RandomAccessBuffer pdf_datafile) {

    final byte[] buffer = new byte[count];

    try {
      pdf_datafile.seek(start);
      pdf_datafile.read(buffer); // get next chars
    } catch (final IOException e) {
      LogWriter.writeLog("Exception: " + e.getMessage());
    }

    return buffer;
  }
  void closeFile() throws IOException {

    if (pdf_datafile != null) {
      pdf_datafile.close();
      pdf_datafile = null;
    }
  }
  /** returns current location pointer and sets to new value */
  public void movePointer(final long pointer) {
    try {
      // make sure inside file
      if (pointer > pdf_datafile.length()) {

        if (LogWriter.isOutput()) {
          LogWriter.writeLog("Attempting to access ref outside file");
        }
        // throw new PdfException("Exception moving file pointer - ref outside file");
      } else {
        pdf_datafile.seek(pointer);
      }
    } catch (final Exception e) {
      if (LogWriter.isOutput()) {
        LogWriter.writeLog("Exception " + e + " moving pointer to  " + pointer + " in file.");
      }
    }
  }
  byte[] getBytes(final long start, final int count) {
    final byte[] buffer = new byte[count];

    if (start >= 0) {
      try {
        pdf_datafile.seek(start);
        pdf_datafile.read(buffer); // get next chars
      } catch (final IOException e) {
        // tell user and log
        if (LogWriter.isOutput()) {
          LogWriter.writeLog("Exception: " + e.getMessage());
        }
        //
      }
    }

    return buffer;
  }
  /**
   * read reference table start to see if new 1.5 type or traditional xref
   *
   * @throws PdfException
   */
  public final PdfObject readReferenceTable(
      final PdfObject linearObj,
      final PdfFileReader currentPdfFile,
      final ObjectReader objectReader)
      throws PdfException {

    int pointer = -1;
    final int eof = (int) this.eof;

    boolean islinearizedCompressed = false;

    if (linearObj == null) {
      pointer = readFirstStartRef();
    } else { // find at start of Linearized
      final byte[] data = pdf_datafile.getPdfBuffer();

      final int count = data.length;
      int ptr = 5;
      for (int i = 0; i < count; i++) {

        // track start of this object (needed for compressed)
        if (data[i] == 'e'
            && data[i + 1] == 'n'
            && data[i + 2] == 'd'
            && data[i + 3] == 'o'
            && data[i + 4] == 'b'
            && data[i + 5] == 'j') {
          ptr = i + 6;
        }

        if (data[i] == 'x' && data[i + 1] == 'r' && data[i + 2] == 'e' && data[i + 3] == 'f') {
          pointer = i;
          i = count;
        } else if (data[i] == 'X'
            && data[i + 1] == 'R'
            && data[i + 2] == 'e'
            && data[i + 3] == 'f') {

          islinearizedCompressed = true;

          pointer = ptr;
          while (data[pointer] == 10 || data[pointer] == 13 || data[pointer] == 32) {
            pointer++;
          }

          i = count;
        }
      }
    }

    offset.addXref(pointer);

    PdfObject rootObj = null;

    if (pointer >= eof || pointer == 0) {

      if (LogWriter.isOutput()) {
        LogWriter.writeLog("Pointer not if file - trying to manually find startref");
      }

      offset.setRefTableInvalid(true);

      try {
        rootObj = new PageObject(BrokenRefTable.findOffsets(pdf_datafile, offset));
      } catch (Error err) {
        throw new PdfException(err.getMessage() + " attempting to manually scan file for objects");
      }

      currentPdfFile.readObject(rootObj);
      return rootObj;

    } else if (islinearizedCompressed || isCompressedStream(pointer, eof)) {
      return readCompressedStream(rootObj, pointer, currentPdfFile, objectReader, linearObj);
    } else {
      return readLegacyReferenceTable(rootObj, pointer, eof, currentPdfFile);
    }
  }