Home | History | Annotate | Download | only in iso
      1 /*
      2  * Copyright 2012 Sebastian Annies, Hamburg
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the License);
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an AS IS BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package com.coremedia.iso;
     17 
     18 import java.io.ByteArrayOutputStream;
     19 import java.nio.ByteBuffer;
     20 
     21 public final class IsoTypeReader {
     22 
     23 
     24     public static long readUInt32BE(ByteBuffer bb) {
     25         long ch1 = readUInt8(bb);
     26         long ch2 = readUInt8(bb);
     27         long ch3 = readUInt8(bb);
     28         long ch4 = readUInt8(bb);
     29         return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0));
     30 
     31     }
     32 
     33 
     34     public static long readUInt32(ByteBuffer bb) {
     35         long i = bb.getInt();
     36         if (i < 0) {
     37             i += 1l<<32;
     38         }
     39         return i;
     40     }
     41 
     42     public static int readUInt24(ByteBuffer bb) {
     43         int result = 0;
     44         result += readUInt16(bb) << 8;
     45         result += byte2int(bb.get());
     46         return result;
     47     }
     48 
     49 
     50     public static int readUInt16(ByteBuffer bb) {
     51         int result = 0;
     52         result += byte2int(bb.get()) << 8;
     53         result += byte2int(bb.get());
     54         return result;
     55     }
     56 
     57     public static int readUInt16BE(ByteBuffer bb) {
     58         int result = 0;
     59         result += byte2int(bb.get());
     60         result += byte2int(bb.get()) << 8;
     61         return result;
     62     }
     63 
     64     public static int readUInt8(ByteBuffer bb) {
     65         return byte2int(bb.get());
     66     }
     67 
     68     public static int byte2int(byte b) {
     69         return b < 0 ? b + 256 : b;
     70     }
     71 
     72 
     73     /**
     74      * Reads a zero terminated UTF-8 string.
     75      *
     76      * @param byteBuffer the data source
     77      * @return the string readByte
     78      * @throws Error in case of an error in the underlying stream
     79      */
     80     public static String readString(ByteBuffer byteBuffer) {
     81 
     82         ByteArrayOutputStream out = new ByteArrayOutputStream();
     83         int read;
     84         while ((read = byteBuffer.get()) != 0) {
     85             out.write(read);
     86         }
     87         return Utf8.convert(out.toByteArray());
     88     }
     89 
     90     public static String readString(ByteBuffer byteBuffer, int length) {
     91         byte[] buffer = new byte[length];
     92         byteBuffer.get(buffer);
     93         return Utf8.convert(buffer);
     94 
     95     }
     96 
     97     public static long readUInt64(ByteBuffer byteBuffer) {
     98         long result = 0;
     99         // thanks to Erik Nicolas for finding a bug! Cast to long is definitivly needed
    100         result += readUInt32(byteBuffer) << 32;
    101         if (result < 0) {
    102             throw new RuntimeException("I don't know how to deal with UInt64! long is not sufficient and I don't want to use BigInt");
    103         }
    104         result += readUInt32(byteBuffer);
    105 
    106         return result;
    107     }
    108 
    109     public static double readFixedPoint1616(ByteBuffer bb) {
    110         byte[] bytes = new byte[4];
    111         bb.get(bytes);
    112 
    113         int result = 0;
    114         result |= ((bytes[0] << 24) & 0xFF000000);
    115         result |= ((bytes[1] << 16) & 0xFF0000);
    116         result |= ((bytes[2] << 8) & 0xFF00);
    117         result |= ((bytes[3]) & 0xFF);
    118         return ((double) result) / 65536;
    119 
    120     }
    121 
    122     public static float readFixedPoint88(ByteBuffer bb) {
    123         byte[] bytes = new byte[2];
    124         bb.get(bytes);
    125         short result = 0;
    126         result |= ((bytes[0] << 8) & 0xFF00);
    127         result |= ((bytes[1]) & 0xFF);
    128         return ((float) result) / 256;
    129     }
    130 
    131     public static String readIso639(ByteBuffer bb) {
    132         int bits = readUInt16(bb);
    133         StringBuilder result = new StringBuilder();
    134         for (int i = 0; i < 3; i++) {
    135             int c = (bits >> (2 - i) * 5) & 0x1f;
    136             result.append((char) (c + 0x60));
    137         }
    138         return result.toString();
    139     }
    140 
    141     public static String read4cc(ByteBuffer bb) {
    142         byte[] b = new byte[4];
    143         bb.get(b);
    144         return IsoFile.bytesToFourCC(b);
    145     }
    146 
    147 }
    148