All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.coremedia.iso.AbstractIsoBufferWrapper Maven / Gradle / Ivy

Go to download

A generic parser and writer for all ISO 14496 based files (MP4, Quicktime, DCF, PDCF, ...)

There is a newer version: 1.1.22
Show newest version
package com.coremedia.iso;


import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

public abstract class AbstractIsoBufferWrapper implements IsoBufferWrapper {
    public int readBitsRemaining;
    private byte readBitsBuffer;

    public long readUInt64() throws IOException {
        long result = 0;
        // thanks to Erik Nicolas for finding a bug! Cast to long is definitivly needed
        result += readUInt32() << 32;
        if (result < 0) {
            throw new RuntimeException("I don't know how to deal with UInt64! long is not sufficient and I don't want to use BigInt");
        }
        result += readUInt32();

        return result;
    }

    public long readUInt32() throws IOException {
        long result = 0;
        result += ((long) readUInt16()) << 16;
        result += readUInt16();
        return result;
    }

    public int readInt32() throws IOException {
        int ch1 = readUInt8();
        int ch2 = readUInt8();
        int ch3 = readUInt8();
        int ch4 = readUInt8();
        return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));

    }

    public int readUInt24() throws IOException {
        int result = 0;
        result += readUInt16() << 8;
        result += readUInt8();
        return result;
    }

    public int readUInt16() throws IOException {
        int result = 0;
        result += readUInt8() << 8;
        result += readUInt8();
        return result;
    }

    public int readUInt8() throws IOException {
        byte b = readByte();
        return b < 0 ? b + 256 : b;
    }


    public byte readByte() throws IOException {
        if (readBitsRemaining != 0) {
            // throw new IllegalStateException("Not byte aligned! Use up all bits until you aligned again.");
        }
        int b = read();
        if (b == -1) {
            throw new RuntimeException("Read beyond buffer's end");
        } else {
            return (byte) (b >= 128 ? b - 256 : b);
        }
    }

    public String readIso639() throws IOException {
        int bits = readUInt16();
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < 3; i++) {
            int c = (bits >> (2 - i) * 5) & 0x1f;
            result.append((char) (c + 0x60));
        }
        return result.toString();
    }

    /**
     * Reads a zero terminated string.
     *
     * @return the string readByte
     * @throws Error in case of an error in the underlying stream
     */
    public String readString() throws IOException {

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int read;
        while ((read = readByte()) != 0) {
            out.write(read);
        }
        try {
            return out.toString("UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new Error("JVM doesn't support UTF-8");
        }

    }


    public long readUInt32BE() throws IOException {
        long result = 0;
        result += readUInt16BE();
        result += ((long) readUInt16BE()) << 16;
        return result;
    }

    public int readUInt16BE() throws IOException {
        int result = 0;
        result += readUInt8();
        result += readUInt8() << 8;
        return result;
    }


    /**
     * Reads i bits from the underlying buffers.
     * Caveat: this method always consumes full bytes even if just a bit is readByte!
     *
     * @param i number of bits to readByte, 31 max
     * @return bitstring value as unsigned int
     */
    public int readBits(int i) throws IOException {
        if (i > 31) {
            //> signed int
            throw new IllegalArgumentException("cannot readByte more than 31 bits");
        }

        int ret = 0;
        while (i > 8) {
            final int moved = parse8(8) << i - 8;
            ret = ret | moved;
            i -= 8;
        }
        return ret | parse8(i);
    }

    private int parse8(int i) throws IOException {
        if (readBitsRemaining == 0) {
            readBitsBuffer = readByte();
            readBitsRemaining = 8;
        }

        if (i > readBitsRemaining) {
            final int resultRemaining = i - readBitsRemaining;
            int buffer = (readBitsBuffer & (int) (Math.pow(2, readBitsRemaining) - 1)) << resultRemaining;

            readBitsBuffer = readByte();
            readBitsRemaining = 8 - resultRemaining;
            final int movedAndMasked = (readBitsBuffer >>> readBitsRemaining) & (int) (Math.pow(2, resultRemaining) - 1);
            return buffer | movedAndMasked;
        } else {
            readBitsRemaining -= i;

            return (readBitsBuffer >>> readBitsRemaining) & (int) (Math.pow(2, i) - 1);
        }
    }

    public int getReadBitsRemaining() {
        return readBitsRemaining;
    }

    public double readFixedPoint1616() throws IOException {
        byte[] bytes = read(4);
        int result = 0;
        result |= ((bytes[0] << 24) & 0xFF000000);
        result |= ((bytes[1] << 16) & 0xFF0000);
        result |= ((bytes[2] << 8) & 0xFF00);
        result |= ((bytes[3]) & 0xFF);
        return ((double) result) / 65536;

    }

    public float readFixedPoint88() throws IOException {
        byte[] bytes = read(2);
        short result = 0;
        result |= ((bytes[0] << 8) & 0xFF00);
        result |= ((bytes[1]) & 0xFF);
        return ((float) result) / 256;
    }

    public String readString(int length) throws IOException {
        byte[] buffer = new byte[length];
        this.read(buffer);
        try {
            return new String(buffer, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new Error("JVM doesn't support UTF-8");
        }
    }

    public byte[] read(int byteCount) throws IOException {
        byte[] result = new byte[byteCount];
        this.read(result);
        return result;

    }


    public long skip(long n) throws IOException {
        this.position(this.position() + n);
        return n;
    }


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy