예제 #1
0
  public int read(byte[] buffer, int pos, int len) throws IOException {

    if (transparent) {

      return (input.read(buffer, pos, len));
    }

    // [header]
    // file [body-start -> body-end]

    long start_pos = seek_position;
    int start_len = len;

    if (seek_position < header.length) {

      int rem = (int) (header.length - seek_position);

      if (rem > len) {

        rem = len;
      }

      System.arraycopy(header, (int) seek_position, buffer, pos, rem);

      pos += rem;
      len -= rem;

      seek_position += rem;
    }

    if (len > 0) {

      long file_position = body_start + seek_position - header.length;

      long rem = body_end - file_position;

      if (len < rem) {

        rem = len;
      }

      input.seek(file_position);

      int temp = input.read(buffer, pos, (int) rem);

      pos += temp;
      len -= temp;

      seek_position += temp;
    }

    int read = start_len - len;

    seek_position = start_pos + read;

    return (read);
  }
예제 #2
0
 public Atom(FileAccessor input) throws IOException {
   offset = input.getFilePointer();
   // get atom size
   size = input.readInt();
   // get atom type
   byte[] atomTypeFCC = new byte[4];
   input.readFully(atomTypeFCC);
   type = new String(atomTypeFCC);
   if (size == 1) {
     // 64 bit size. Read new size from body and store it
     size = input.readLong();
   }
   // skip back to atom start
   input.seek(offset);
 }
예제 #3
0
  public void seek(long pos) throws IOException {

    if (transparent) {

      input.seek(pos);

    } else {

      seek_position = pos;
    }
  }
예제 #4
0
  public QTFastStartRAF(FileAccessor accessor, boolean enable) throws IOException {

    input = accessor;

    if (enable) {

      String name = accessor.getName();

      boolean log;
      String fail = null;

      synchronized (tested) {
        log = !tested.contains(name);

        if (log) {

          tested.add(name);
        }
      }

      try {
        Atom ah = null;
        Atom ftypAtom = null;

        boolean gotFtyp = false;
        boolean gotMdat = false;
        boolean justCopy = false;

        while (input.getFilePointer() < input.length()) {

          ah = new Atom(input);

          // System.out.println( "got " + ah.type +", size=" + ah.size );

          if (!isValidTopLevelAtom(ah)) {
            throw new IOException("Non top level QT atom found (" + ah.type + "). File invalid?");
          }

          if (gotFtyp && !gotMdat && ah.type.equalsIgnoreCase(ATOM_MOOV)) {
            justCopy = true;
            break;
          }

          // store ftyp atom to buffer
          if (ah.type.equalsIgnoreCase(ATOM_FTYP)) {
            ftypAtom = ah;
            ftypAtom.fillBuffer(input);
            gotFtyp = true;
          } else if (ah.type.equalsIgnoreCase(ATOM_MDAT)) {
            gotMdat = true;
            input.skipBytes((int) ah.size);
          } else {
            input.skipBytes((int) ah.size);
          }
        }

        if (justCopy) {

          transparent = true;

          return;
        }

        if (ftypAtom == null) {

          throw new IOException("No FTYP atom found");
        }

        if (ah == null || !ah.type.equalsIgnoreCase(ATOM_MOOV)) {

          throw new IOException("Last QT atom was not the MOOV atom.");
        }

        input.seek(ah.offset);

        Atom moovAtom = ah;

        moovAtom.fillBuffer(input);

        if (isCompressedMoovAtom(moovAtom)) {

          throw new IOException("Compressed MOOV qt atoms are not supported");
        }

        patchMoovAtom(moovAtom);

        body_start = ftypAtom.offset + ftypAtom.size;
        body_end = moovAtom.offset;

        header = new byte[ftypAtom.buffer.length + moovAtom.buffer.length];

        System.arraycopy(ftypAtom.buffer, 0, header, 0, ftypAtom.buffer.length);
        System.arraycopy(
            moovAtom.buffer, 0, header, ftypAtom.buffer.length, moovAtom.buffer.length);

        if (accessor.length() != header.length + (body_end - body_start)) {

          throw (new IOException("Inconsistent: file size has changed"));
        }

      } catch (Throwable e) {

        // e.printStackTrace();

        fail = Debug.getNestedExceptionMessage(e);

        transparent = true;

      } finally {

        input.seek(0);

        if (log) {

          String message;

          if (fail == null) {

            message = transparent ? "Not required" : "Required";

          } else {

            message = "Failed - " + fail;
          }

          Debug.outNoStack("MOOV relocation for " + accessor.getName() + ": " + message);
        }
      }
    } else {

      transparent = true;
    }
  }
예제 #5
0
 public void fillBuffer(FileAccessor input) throws IOException {
   buffer = new byte[(int) size];
   input.readFully(buffer);
 }
예제 #6
0
  public void close() throws IOException {

    input.close();
  }
예제 #7
0
  public long length() throws IOException {

    return (input.length());
  }