12523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan/* 22523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * Copyright (C) 2012 The Android Open Source Project 32523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * 42523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * Licensed under the Apache License, Version 2.0 (the "License"); 52523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * you may not use this file except in compliance with the License. 62523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * You may obtain a copy of the License at 72523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * 82523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * http://www.apache.org/licenses/LICENSE-2.0 92523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * 102523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * Unless required by applicable law or agreed to in writing, software 112523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * distributed under the License is distributed on an "AS IS" BASIS, 122523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * See the License for the specific language governing permissions and 142523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * limitations under the License. 152523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan */ 162523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 17a16e7b50f3148f581439509279f242092e254309ztenghuipackage com.android.camera.exif; 182523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 192523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyanimport java.io.EOFException; 202523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyanimport java.io.FilterInputStream; 212523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyanimport java.io.IOException; 222523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyanimport java.io.InputStream; 232523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyanimport java.nio.ByteBuffer; 242523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyanimport java.nio.ByteOrder; 252523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyanimport java.nio.charset.Charset; 262523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 272523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyanclass CountedDataInputStream extends FilterInputStream { 282523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 292523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan private int mCount = 0; 302523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 312523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan // allocate a byte buffer for a long value; 322523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan private final byte mByteArray[] = new byte[8]; 332523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan private final ByteBuffer mByteBuffer = ByteBuffer.wrap(mByteArray); 342523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 352523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan protected CountedDataInputStream(InputStream in) { 362523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan super(in); 372523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 382523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 392523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan public int getReadByteCount() { 402523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan return mCount; 412523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 422523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 432523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan @Override 442523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan public int read(byte[] b) throws IOException { 452523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan int r = in.read(b); 462523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan mCount += (r >= 0) ? r : 0; 472523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan return r; 482523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 492523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 502523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan @Override 512523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan public int read(byte[] b, int off, int len) throws IOException { 522523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan int r = in.read(b, off, len); 532523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan mCount += (r >= 0) ? r : 0; 542523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan return r; 552523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 562523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 572523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan @Override 582523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan public int read() throws IOException { 592523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan int r = in.read(); 602523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan mCount += (r >= 0) ? 1 : 0; 612523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan return r; 622523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 632523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 642523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan @Override 652523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan public long skip(long length) throws IOException { 662523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan long skip = in.skip(length); 672523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan mCount += skip; 682523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan return skip; 692523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 702523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 712523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan public void skipOrThrow(long length) throws IOException { 722523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan if (skip(length) != length) throw new EOFException(); 732523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 742523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 752523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan public void skipTo(long target) throws IOException { 762523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan long cur = mCount; 772523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan long diff = target - cur; 782523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan assert(diff >= 0); 792523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan skipOrThrow(diff); 802523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 812523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 822523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan public void readOrThrow(byte[] b, int off, int len) throws IOException { 832523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan int r = read(b, off, len); 842523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan if (r != len) throw new EOFException(); 852523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 862523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 872523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan public void readOrThrow(byte[] b) throws IOException { 882523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan readOrThrow(b, 0, b.length); 892523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 902523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 912523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan public void setByteOrder(ByteOrder order) { 922523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan mByteBuffer.order(order); 932523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 942523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 952523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan public ByteOrder getByteOrder() { 962523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan return mByteBuffer.order(); 972523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 982523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 992523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan public short readShort() throws IOException { 1002523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan readOrThrow(mByteArray, 0 ,2); 1012523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan mByteBuffer.rewind(); 1022523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan return mByteBuffer.getShort(); 1032523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 1042523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 1052523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan public int readUnsignedShort() throws IOException { 1062523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan return readShort() & 0xffff; 1072523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 1082523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 1092523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan public int readInt() throws IOException { 1102523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan readOrThrow(mByteArray, 0 , 4); 1112523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan mByteBuffer.rewind(); 1122523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan return mByteBuffer.getInt(); 1132523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 1142523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 1152523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan public long readUnsignedInt() throws IOException { 1162523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan return readInt() & 0xffffffffL; 1172523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 1182523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 1192523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan public long readLong() throws IOException { 1202523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan readOrThrow(mByteArray, 0 , 8); 1212523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan mByteBuffer.rewind(); 1222523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan return mByteBuffer.getLong(); 1232523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 1242523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 1252523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan public String readString(int n) throws IOException { 1262523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan byte buf[] = new byte[n]; 1272523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan readOrThrow(buf); 1282523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan return new String(buf, "UTF8"); 1292523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 1302523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 1312523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan public String readString(int n, Charset charset) throws IOException { 1322523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan byte buf[] = new byte[n]; 1332523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan readOrThrow(buf); 1342523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan return new String(buf, charset); 1352523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 1362523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan}