1104c45677660586026a7e74ef8c47d396403d50eMichael Jurka/* 2104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Copyright (C) 2012 The Android Open Source Project 3104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 4104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Licensed under the Apache License, Version 2.0 (the "License"); 5104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * you may not use this file except in compliance with the License. 6104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * You may obtain a copy of the License at 7104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 8104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * http://www.apache.org/licenses/LICENSE-2.0 9104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 10104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Unless required by applicable law or agreed to in writing, software 11104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * distributed under the License is distributed on an "AS IS" BASIS, 12104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * See the License for the specific language governing permissions and 14104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * limitations under the License. 15104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 16104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 17104c45677660586026a7e74ef8c47d396403d50eMichael Jurkapackage com.android.gallery3d.exif; 18104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 19104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport java.io.EOFException; 20104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport java.io.FilterInputStream; 21104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport java.io.IOException; 22104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport java.io.InputStream; 23104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport java.nio.ByteBuffer; 24104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport java.nio.ByteOrder; 25104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport java.nio.charset.Charset; 26104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 27104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaclass CountedDataInputStream extends FilterInputStream { 28104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 29104c45677660586026a7e74ef8c47d396403d50eMichael Jurka private int mCount = 0; 30104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 31104c45677660586026a7e74ef8c47d396403d50eMichael Jurka // allocate a byte buffer for a long value; 32104c45677660586026a7e74ef8c47d396403d50eMichael Jurka private final byte mByteArray[] = new byte[8]; 33104c45677660586026a7e74ef8c47d396403d50eMichael Jurka private final ByteBuffer mByteBuffer = ByteBuffer.wrap(mByteArray); 34104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 35104c45677660586026a7e74ef8c47d396403d50eMichael Jurka protected CountedDataInputStream(InputStream in) { 36104c45677660586026a7e74ef8c47d396403d50eMichael Jurka super(in); 37104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 38104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 39104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public int getReadByteCount() { 40104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return mCount; 41104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 42104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 43104c45677660586026a7e74ef8c47d396403d50eMichael Jurka @Override 44104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public int read(byte[] b) throws IOException { 45104c45677660586026a7e74ef8c47d396403d50eMichael Jurka int r = in.read(b); 46104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mCount += (r >= 0) ? r : 0; 47104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return r; 48104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 49104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 50104c45677660586026a7e74ef8c47d396403d50eMichael Jurka @Override 51104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public int read(byte[] b, int off, int len) throws IOException { 52104c45677660586026a7e74ef8c47d396403d50eMichael Jurka int r = in.read(b, off, len); 53104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mCount += (r >= 0) ? r : 0; 54104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return r; 55104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 56104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 57104c45677660586026a7e74ef8c47d396403d50eMichael Jurka @Override 58104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public int read() throws IOException { 59104c45677660586026a7e74ef8c47d396403d50eMichael Jurka int r = in.read(); 60104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mCount += (r >= 0) ? 1 : 0; 61104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return r; 62104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 63104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 64104c45677660586026a7e74ef8c47d396403d50eMichael Jurka @Override 65104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public long skip(long length) throws IOException { 66104c45677660586026a7e74ef8c47d396403d50eMichael Jurka long skip = in.skip(length); 67104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mCount += skip; 68104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return skip; 69104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 70104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 71104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public void skipOrThrow(long length) throws IOException { 72104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (skip(length) != length) throw new EOFException(); 73104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 74104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 75104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public void skipTo(long target) throws IOException { 76104c45677660586026a7e74ef8c47d396403d50eMichael Jurka long cur = mCount; 77104c45677660586026a7e74ef8c47d396403d50eMichael Jurka long diff = target - cur; 78104c45677660586026a7e74ef8c47d396403d50eMichael Jurka assert(diff >= 0); 79104c45677660586026a7e74ef8c47d396403d50eMichael Jurka skipOrThrow(diff); 80104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 81104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 82104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public void readOrThrow(byte[] b, int off, int len) throws IOException { 83104c45677660586026a7e74ef8c47d396403d50eMichael Jurka int r = read(b, off, len); 84104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (r != len) throw new EOFException(); 85104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 86104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 87104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public void readOrThrow(byte[] b) throws IOException { 88104c45677660586026a7e74ef8c47d396403d50eMichael Jurka readOrThrow(b, 0, b.length); 89104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 90104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 91104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public void setByteOrder(ByteOrder order) { 92104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mByteBuffer.order(order); 93104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 94104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 95104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public ByteOrder getByteOrder() { 96104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return mByteBuffer.order(); 97104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 98104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 99104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public short readShort() throws IOException { 100104c45677660586026a7e74ef8c47d396403d50eMichael Jurka readOrThrow(mByteArray, 0 ,2); 101104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mByteBuffer.rewind(); 102104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return mByteBuffer.getShort(); 103104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 104104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 105104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public int readUnsignedShort() throws IOException { 106104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return readShort() & 0xffff; 107104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 108104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 109104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public int readInt() throws IOException { 110104c45677660586026a7e74ef8c47d396403d50eMichael Jurka readOrThrow(mByteArray, 0 , 4); 111104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mByteBuffer.rewind(); 112104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return mByteBuffer.getInt(); 113104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 114104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 115104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public long readUnsignedInt() throws IOException { 116104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return readInt() & 0xffffffffL; 117104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 118104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 119104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public long readLong() throws IOException { 120104c45677660586026a7e74ef8c47d396403d50eMichael Jurka readOrThrow(mByteArray, 0 , 8); 121104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mByteBuffer.rewind(); 122104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return mByteBuffer.getLong(); 123104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 124104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 125104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public String readString(int n) throws IOException { 126104c45677660586026a7e74ef8c47d396403d50eMichael Jurka byte buf[] = new byte[n]; 127104c45677660586026a7e74ef8c47d396403d50eMichael Jurka readOrThrow(buf); 128104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return new String(buf, "UTF8"); 129104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 130104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 131104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public String readString(int n, Charset charset) throws IOException { 132104c45677660586026a7e74ef8c47d396403d50eMichael Jurka byte buf[] = new byte[n]; 133104c45677660586026a7e74ef8c47d396403d50eMichael Jurka readOrThrow(buf); 134104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return new String(buf, charset); 135104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 136104c45677660586026a7e74ef8c47d396403d50eMichael Jurka}