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 readUInt32BE(ByteBuffer bb)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 readUInt32(ByteBuffer bb)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 readUInt24(ByteBuffer bb)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 readUInt16(ByteBuffer bb)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 readUInt16BE(ByteBuffer bb)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 readUInt8(ByteBuffer bb)64 public static int readUInt8(ByteBuffer bb) { 65 return byte2int(bb.get()); 66 } 67 byte2int(byte b)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 */ readString(ByteBuffer byteBuffer)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 readString(ByteBuffer byteBuffer, int length)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 readUInt64(ByteBuffer byteBuffer)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 readFixedPoint1616(ByteBuffer bb)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 readFixedPoint88(ByteBuffer bb)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 readIso639(ByteBuffer bb)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 read4cc(ByteBuffer bb)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