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