1d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/*
2d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Copyright (C) 2012 The Android Open Source Project
3d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *
4d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Licensed under the Apache License, Version 2.0 (the "License");
5d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * you may not use this file except in compliance with the License.
6d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * You may obtain a copy of the License at
7d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *
8d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *      http://www.apache.org/licenses/LICENSE-2.0
9d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *
10d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Unless required by applicable law or agreed to in writing, software
11d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * distributed under the License is distributed on an "AS IS" BASIS,
12d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * See the License for the specific language governing permissions and
14d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * limitations under the License.
15d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */
16d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
17d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpackage com.android.messaging.util.exif;
18d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
19d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.util.Log;
20d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.LogUtil;
21d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
22d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.io.IOException;
23d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.io.InputStream;
24d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
25d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/**
26d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * This class reads the EXIF header of a JPEG file and stores it in
27d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * {@link ExifData}.
28d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */
29d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddclass ExifReader {
30d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private static final String TAG = LogUtil.BUGLE_TAG;
31d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
32d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private final ExifInterface mInterface;
33d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
34d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    ExifReader(ExifInterface iRef) {
35d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mInterface = iRef;
36d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
37d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
38d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    /**
39d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * Parses the inputStream and and returns the EXIF data in an
40d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * {@link ExifData}.
41d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     *
42d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * @throws ExifInvalidFormatException
43d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * @throws java.io.IOException
44d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     */
45d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    protected ExifData read(InputStream inputStream) throws ExifInvalidFormatException,
46d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            IOException {
47d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        ExifParser parser = ExifParser.parse(inputStream, mInterface);
48d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        ExifData exifData = new ExifData(parser.getByteOrder());
49d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        ExifTag tag = null;
50d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
51d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        int event = parser.next();
52d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        while (event != ExifParser.EVENT_END) {
53d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            switch (event) {
54d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                case ExifParser.EVENT_START_OF_IFD:
55d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    exifData.addIfdData(new IfdData(parser.getCurrentIfd()));
56d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    break;
57d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                case ExifParser.EVENT_NEW_TAG:
58d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    tag = parser.getTag();
59d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    if (!tag.hasValue()) {
60d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        parser.registerForTagValue(tag);
61d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    } else {
62d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        exifData.getIfdData(tag.getIfd()).setTag(tag);
63d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    }
64d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    break;
65d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                case ExifParser.EVENT_VALUE_OF_REGISTERED_TAG:
66d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    tag = parser.getTag();
67d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    if (tag.getDataType() == ExifTag.TYPE_UNDEFINED) {
68d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        parser.readFullTagValue(tag);
69d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    }
70d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    exifData.getIfdData(tag.getIfd()).setTag(tag);
71d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    break;
72d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                case ExifParser.EVENT_COMPRESSED_IMAGE:
73d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    byte buf[] = new byte[parser.getCompressedImageSize()];
74d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    if (buf.length == parser.read(buf)) {
75d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        exifData.setCompressedThumbnail(buf);
76d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    } else {
77d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        Log.w(TAG, "Failed to read the compressed thumbnail");
78d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    }
79d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    break;
80d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                case ExifParser.EVENT_UNCOMPRESSED_STRIP:
81d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    buf = new byte[parser.getStripSize()];
82d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    if (buf.length == parser.read(buf)) {
83d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        exifData.setStripBytes(parser.getStripIndex(), buf);
84d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    } else {
85d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        Log.w(TAG, "Failed to read the strip bytes");
86d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    }
87d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    break;
88d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
89d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            event = parser.next();
90d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
91d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return exifData;
92d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
93d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd}
94