package org.jcodec.containers.mp4.boxes; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import org.jcodec.codecs.wav.StringReader; import org.jcodec.common.NIOUtils; import org.jcodec.common.JCodecUtil; import org.jcodec.common.SeekableByteChannel; /** * This class is part of JCodec ( www.jcodec.org ) This software is distributed * under FreeBSD License * * An MP4 file structure (atom) * * @author Jay Codec * */ public class Header { private static final long MAX_UNSIGNED_INT = 0x100000000L; private String fourcc; private long size; private boolean lng; public Header(String fourcc) { this.fourcc = fourcc; } public Header(String fourcc, long size) { this.size = size; this.fourcc = fourcc; } public Header(Header h) { this.fourcc = h.fourcc; this.size = h.size; } public Header(String fourcc, long size, boolean lng) { this(fourcc, size); this.lng = lng; } public static Header read(ByteBuffer input) { long size = 0; while (input.remaining() >= 4 && (size = (((long) input.getInt()) & 0xffffffffL)) == 0) ; if (input.remaining() < 4 || size < 8 && size != 1) { System.out.println("Broken atom of size " + size); return null; } String fourcc = NIOUtils.readString(input, 4); boolean lng = false; if (size == 1) { if (input.remaining() >= 8) { lng = true; size = input.getLong(); } else { System.out.println("Broken atom of size " + size); return null; } } return new Header(fourcc, size, lng); } public void print() { System.out.println(fourcc + "," + size); } public void skip(InputStream di) throws IOException { StringReader.sureSkip(di, size - headerSize()); } public long headerSize() { return lng || (size > MAX_UNSIGNED_INT) ? 16 : 8; } public byte[] readContents(InputStream di) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); for (int i = 0; i < size - headerSize(); i++) { baos.write(di.read()); } return baos.toByteArray(); } public String getFourcc() { return fourcc; } public long getBodySize() { return size - headerSize(); } public void setBodySize(int length) { size = length + headerSize(); } public void write(ByteBuffer out) { if (size > MAX_UNSIGNED_INT) out.putInt(1); else out.putInt((int) size); out.put(JCodecUtil.asciiString(fourcc)); if (size > MAX_UNSIGNED_INT) { out.putLong(size); } } public void write(SeekableByteChannel output) throws IOException { ByteBuffer bb = ByteBuffer.allocate(16); write(bb); bb.flip(); output.write(bb); } public long getSize() { return size; } }