summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/com/android/gallery3d/exif/ExifOutputStream.java29
-rw-r--r--src/com/android/gallery3d/exif/ExifParser.java33
-rw-r--r--src/com/android/gallery3d/exif/JpegHeader.java39
3 files changed, 59 insertions, 42 deletions
diff --git a/src/com/android/gallery3d/exif/ExifOutputStream.java b/src/com/android/gallery3d/exif/ExifOutputStream.java
index 0f56014a4..e9475c53e 100644
--- a/src/com/android/gallery3d/exif/ExifOutputStream.java
+++ b/src/com/android/gallery3d/exif/ExifOutputStream.java
@@ -29,25 +29,6 @@ public class ExifOutputStream extends FilterOutputStream {
private static final int STATE_FRAME_HEADER = 1;
private static final int STATE_JPEG_DATA = 2;
- private static final short SOI = (short) 0xFFD8;
- private static final short APP1 = (short) 0xFFE1;
- private static final short EOI = (short) 0xFFD9;
-
- /**
- * SOF (start of frame). All value between SOF0 and SOF15 is SOF tag except for DHT, JPG,
- * and DAC tag.
- */
- private static final short SOF0 = (short) 0xFFC0;
- private static final short SOF15 = (short) 0xFFCF;
- private static final short DHT = (short) 0xFFC4;
- private static final short JPG = (short) 0xFFC8;
- private static final short DAC = (short) 0xFFCC;
-
- private static final boolean isSofMarker(short marker) {
- return marker >= SOF0 && marker <= SOF15 && marker != DHT && marker != JPG
- && marker != DAC;
- }
-
private static final int EXIF_HEADER = 0x45786966;
private static final short TIFF_HEADER = 0x002A;
private static final short TIFF_BIG_ENDIAN = 0x4d4d;
@@ -106,7 +87,7 @@ public class ExifOutputStream extends FilterOutputStream {
length -= byteRead;
if (mBuffer.position() < 2) return;
mBuffer.rewind();
- assert(mBuffer.getShort() == SOI);
+ assert(mBuffer.getShort() == JpegHeader.SOI);
out.write(mBuffer.array(), 0 ,2);
mState = STATE_FRAME_HEADER;
mBuffer.rewind();
@@ -120,7 +101,7 @@ public class ExifOutputStream extends FilterOutputStream {
// Check if this image data doesn't contain SOF.
if (mBuffer.position() == 2) {
short tag = mBuffer.getShort();
- if (tag == EOI) {
+ if (tag == JpegHeader.EOI) {
out.write(mBuffer.array(), 0, 2);
mBuffer.rewind();
}
@@ -128,10 +109,10 @@ public class ExifOutputStream extends FilterOutputStream {
if (mBuffer.position() < 4) return;
mBuffer.rewind();
short marker = mBuffer.getShort();
- if (marker == APP1) {
+ if (marker == JpegHeader.APP1) {
mByteToSkip = (mBuffer.getShort() & 0xff) - 2;
mState = STATE_JPEG_DATA;
- } else if (!isSofMarker(marker)) {
+ } else if (!JpegHeader.isSofMarker(marker)) {
out.write(mBuffer.array(), 0, 4);
mByteToCopy = (mBuffer.getShort() & 0xff) - 2;
} else {
@@ -162,7 +143,7 @@ public class ExifOutputStream extends FilterOutputStream {
int exifSize = calculateAllOffset();
OrderedDataOutputStream dataOutputStream = new OrderedDataOutputStream(out);
dataOutputStream.setByteOrder(ByteOrder.BIG_ENDIAN);
- dataOutputStream.writeShort(APP1);
+ dataOutputStream.writeShort(JpegHeader.APP1);
dataOutputStream.writeShort((short) (exifSize + 8));
dataOutputStream.writeInt(EXIF_HEADER);
dataOutputStream.writeShort((short) 0x0000);
diff --git a/src/com/android/gallery3d/exif/ExifParser.java b/src/com/android/gallery3d/exif/ExifParser.java
index f6ecd7798..72b479bed 100644
--- a/src/com/android/gallery3d/exif/ExifParser.java
+++ b/src/com/android/gallery3d/exif/ExifParser.java
@@ -122,10 +122,6 @@ public class ExifParser {
*/
public static final int OPTION_THUMBNAIL = 1 << 5;
- private static final short SOI = (short) 0xFFD8; // SOI marker of JPEG
- private static final short APP1 = (short) 0xFFE1; // APP1 marker of JPEG
- private static final short APP0 = (short) 0xFFE0; // APP0 marder of JPEG
-
private static final int EXIF_HEADER = 0x45786966; // EXIF header "Exif"
private static final short EXIF_HEADER_TAIL = (short) 0x0000; // EXIF header in APP1
@@ -148,6 +144,7 @@ public class ExifParser {
private ExifTag mStripSizeTag;
private ExifTag mJpegSizeTag;
private boolean mNeedToParseOffsetsInCurrentIfd;
+ private boolean mContainExifData = false;
private final TreeMap<Integer, Object> mCorrespondingEvent = new TreeMap<Integer, Object>();
@@ -173,9 +170,10 @@ public class ExifParser {
private ExifParser(InputStream inputStream, int options)
throws IOException, ExifInvalidFormatException {
- seekTiffData(inputStream);
+ mContainExifData = seekTiffData(inputStream);
mTiffStream = new CountedDataInputStream(inputStream);
mOptions = options;
+ if (!mContainExifData) return;
if (mTiffStream.getReadByteCount() == 0) {
parseTiffHeader();
long offset = mTiffStream.readUnsignedInt();
@@ -220,6 +218,9 @@ public class ExifParser {
* @see #EVENT_END
*/
public int next() throws IOException, ExifInvalidFormatException {
+ if (!mContainExifData) {
+ return EVENT_END;
+ }
int offset = mTiffStream.getReadByteCount();
int endOfTags = mIfdStartOffset + OFFSET_SIZE + TAG_SIZE * mNumOfTagInIfd;
if (offset < endOfTags) {
@@ -599,37 +600,33 @@ public class ExifParser {
}
}
- private void seekTiffData(InputStream inputStream) throws IOException,
+ private boolean seekTiffData(InputStream inputStream) throws IOException,
ExifInvalidFormatException {
DataInputStream dataStream = new DataInputStream(inputStream);
// SOI and APP1
- if (dataStream.readShort() != SOI) {
+ if (dataStream.readShort() != JpegHeader.SOI) {
throw new ExifInvalidFormatException("Invalid JPEG format");
}
- short tag = dataStream.readShort();
- if (tag == APP0) {
+ short marker = dataStream.readShort();
+ while(marker != JpegHeader.APP1 && marker != JpegHeader.EOI
+ && !JpegHeader.isSofMarker(marker)) {
int length = dataStream.readUnsignedShort();
if ((length - 2) != dataStream.skip(length - 2)) {
throw new EOFException();
}
- tag = dataStream.readShort();
+ marker = dataStream.readShort();
}
- if (tag != APP1) {
- throw new ExifInvalidFormatException("No APP1 segment");
- }
+ if (marker != JpegHeader.APP1) return false; // No APP1 segment
// APP1 length, it's not used for us
dataStream.readShort();
// Exif header
- if (dataStream.readInt() != EXIF_HEADER
- || dataStream.readShort() != EXIF_HEADER_TAIL) {
- // There is no EXIF data;
- throw new ExifInvalidFormatException("No Exif header in APP1");
- }
+ return (dataStream.readInt() == EXIF_HEADER
+ && dataStream.readShort() == EXIF_HEADER_TAIL);
}
public int read(byte[] buffer, int offset, int length) throws IOException {
diff --git a/src/com/android/gallery3d/exif/JpegHeader.java b/src/com/android/gallery3d/exif/JpegHeader.java
new file mode 100644
index 000000000..e3e787eff
--- /dev/null
+++ b/src/com/android/gallery3d/exif/JpegHeader.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.exif;
+
+class JpegHeader {
+ public static final short SOI = (short) 0xFFD8;
+ public static final short APP1 = (short) 0xFFE1;
+ public static final short APP0 = (short) 0xFFE0;
+ public static final short EOI = (short) 0xFFD9;
+
+ /**
+ * SOF (start of frame). All value between SOF0 and SOF15 is SOF marker except for DHT, JPG,
+ * and DAC marker.
+ */
+ public static final short SOF0 = (short) 0xFFC0;
+ public static final short SOF15 = (short) 0xFFCF;
+ public static final short DHT = (short) 0xFFC4;
+ public static final short JPG = (short) 0xFFC8;
+ public static final short DAC = (short) 0xFFCC;
+
+ public static final boolean isSofMarker(short marker) {
+ return marker >= SOF0 && marker <= SOF15 && marker != DHT && marker != JPG
+ && marker != DAC;
+ }
+}