1d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/* 2d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Copyright (C) 2013 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.graphics.Bitmap; 20d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.graphics.BitmapFactory; 21d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.util.SparseIntArray; 22d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 23d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.io.BufferedInputStream; 24d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.io.ByteArrayInputStream; 25d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.io.ByteArrayOutputStream; 26d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.io.Closeable; 27d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.io.File; 28d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.io.FileInputStream; 29d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.io.FileNotFoundException; 30d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.io.FileOutputStream; 31d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.io.IOException; 32d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.io.InputStream; 33d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.io.OutputStream; 34d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.io.RandomAccessFile; 35d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.nio.ByteBuffer; 36d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.nio.ByteOrder; 37d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.nio.channels.FileChannel.MapMode; 38d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.text.DateFormat; 39d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.text.SimpleDateFormat; 40d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.util.ArrayList; 41d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.util.Arrays; 42d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.util.Calendar; 43d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.util.Collection; 44d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.util.HashSet; 45d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.util.List; 46d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.util.TimeZone; 47d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 48d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/** 49d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * This class provides methods and constants for reading and writing jpeg file 50d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * metadata. It contains a collection of ExifTags, and a collection of 51d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * definitions for creating valid ExifTags. The collection of ExifTags can be 52d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * updated by: reading new ones from a file, deleting or adding existing ones, 53d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * or building new ExifTags from a tag definition. These ExifTags can be written 54d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * to a valid jpeg image as exif metadata. 55d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * <p> 56d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Each ExifTag has a tag ID (TID) and is stored in a specific image file 57d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * directory (IFD) as specified by the exif standard. A tag definition can be 58d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * looked up with a constant that is a combination of TID and IFD. This 59d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * definition has information about the type, number of components, and valid 60d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * IFDs for a tag. 61d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 62d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @see ExifTag 63d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 64d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpublic class ExifInterface { 65d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_NULL = -1; 66d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int IFD_NULL = -1; 67d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int DEFINITION_NULL = 0; 68d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 69d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 70d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Tag constants for Jeita EXIF 2.2 71d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 72d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 73d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // IFD 0 74d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_IMAGE_WIDTH = 75d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x0100); 76d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_IMAGE_LENGTH = 77d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x0101); // Image height 78d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_BITS_PER_SAMPLE = 79d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x0102); 80d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_COMPRESSION = 81d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x0103); 82d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_PHOTOMETRIC_INTERPRETATION = 83d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x0106); 84d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_IMAGE_DESCRIPTION = 85d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x010E); 86d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_MAKE = 87d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x010F); 88d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_MODEL = 89d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x0110); 90d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_STRIP_OFFSETS = 91d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x0111); 92d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_ORIENTATION = 93d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x0112); 94d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_SAMPLES_PER_PIXEL = 95d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x0115); 96d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_ROWS_PER_STRIP = 97d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x0116); 98d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_STRIP_BYTE_COUNTS = 99d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x0117); 100d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_X_RESOLUTION = 101d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x011A); 102d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_Y_RESOLUTION = 103d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x011B); 104d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_PLANAR_CONFIGURATION = 105d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x011C); 106d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_RESOLUTION_UNIT = 107d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x0128); 108d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_TRANSFER_FUNCTION = 109d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x012D); 110d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_SOFTWARE = 111d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x0131); 112d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_DATE_TIME = 113d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x0132); 114d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_ARTIST = 115d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x013B); 116d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_WHITE_POINT = 117d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x013E); 118d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_PRIMARY_CHROMATICITIES = 119d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x013F); 120d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_Y_CB_CR_COEFFICIENTS = 121d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x0211); 122d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_Y_CB_CR_SUB_SAMPLING = 123d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x0212); 124d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_Y_CB_CR_POSITIONING = 125d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x0213); 126d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_REFERENCE_BLACK_WHITE = 127d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x0214); 128d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_COPYRIGHT = 129d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x8298); 130d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_EXIF_IFD = 131d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x8769); 132d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_IFD = 133d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_0, (short) 0x8825); 134d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // IFD 1 135d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_JPEG_INTERCHANGE_FORMAT = 136d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_1, (short) 0x0201); 137d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_JPEG_INTERCHANGE_FORMAT_LENGTH = 138d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_1, (short) 0x0202); 139d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // IFD Exif Tags 140d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_EXPOSURE_TIME = 141d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x829A); 142d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_F_NUMBER = 143d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x829D); 144d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_EXPOSURE_PROGRAM = 145d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x8822); 146d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_SPECTRAL_SENSITIVITY = 147d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x8824); 148d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_ISO_SPEED_RATINGS = 149d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x8827); 150d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_OECF = 151d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x8828); 152d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_EXIF_VERSION = 153d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9000); 154d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_DATE_TIME_ORIGINAL = 155d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9003); 156d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_DATE_TIME_DIGITIZED = 157d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9004); 158d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_COMPONENTS_CONFIGURATION = 159d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9101); 160d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_COMPRESSED_BITS_PER_PIXEL = 161d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9102); 162d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_SHUTTER_SPEED_VALUE = 163d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9201); 164d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_APERTURE_VALUE = 165d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9202); 166d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_BRIGHTNESS_VALUE = 167d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9203); 168d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_EXPOSURE_BIAS_VALUE = 169d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9204); 170d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_MAX_APERTURE_VALUE = 171d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9205); 172d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_SUBJECT_DISTANCE = 173d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9206); 174d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_METERING_MODE = 175d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9207); 176d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_LIGHT_SOURCE = 177d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9208); 178d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_FLASH = 179d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9209); 180d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_FOCAL_LENGTH = 181d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x920A); 182d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_SUBJECT_AREA = 183d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9214); 184d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_MAKER_NOTE = 185d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x927C); 186d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_USER_COMMENT = 187d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9286); 188d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_SUB_SEC_TIME = 189d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9290); 190d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_SUB_SEC_TIME_ORIGINAL = 191d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9291); 192d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_SUB_SEC_TIME_DIGITIZED = 193d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9292); 194d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_FLASHPIX_VERSION = 195d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA000); 196d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_COLOR_SPACE = 197d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA001); 198d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_PIXEL_X_DIMENSION = 199d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA002); 200d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_PIXEL_Y_DIMENSION = 201d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA003); 202d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_RELATED_SOUND_FILE = 203d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA004); 204d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_INTEROPERABILITY_IFD = 205d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA005); 206d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_FLASH_ENERGY = 207d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA20B); 208d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_SPATIAL_FREQUENCY_RESPONSE = 209d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA20C); 210d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_FOCAL_PLANE_X_RESOLUTION = 211d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA20E); 212d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_FOCAL_PLANE_Y_RESOLUTION = 213d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA20F); 214d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_FOCAL_PLANE_RESOLUTION_UNIT = 215d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA210); 216d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_SUBJECT_LOCATION = 217d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA214); 218d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_EXPOSURE_INDEX = 219d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA215); 220d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_SENSING_METHOD = 221d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA217); 222d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_FILE_SOURCE = 223d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA300); 224d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_SCENE_TYPE = 225d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA301); 226d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_CFA_PATTERN = 227d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA302); 228d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_CUSTOM_RENDERED = 229d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA401); 230d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_EXPOSURE_MODE = 231d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA402); 232d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_WHITE_BALANCE = 233d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA403); 234d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_DIGITAL_ZOOM_RATIO = 235d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA404); 236d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_FOCAL_LENGTH_IN_35_MM_FILE = 237d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA405); 238d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_SCENE_CAPTURE_TYPE = 239d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA406); 240d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GAIN_CONTROL = 241d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA407); 242d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_CONTRAST = 243d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA408); 244d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_SATURATION = 245d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA409); 246d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_SHARPNESS = 247d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA40A); 248d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_DEVICE_SETTING_DESCRIPTION = 249d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA40B); 250d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_SUBJECT_DISTANCE_RANGE = 251d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA40C); 252d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_IMAGE_UNIQUE_ID = 253d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA420); 254d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // IFD GPS tags 255d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_VERSION_ID = 256d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 0); 257d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_LATITUDE_REF = 258d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 1); 259d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_LATITUDE = 260d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 2); 261d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_LONGITUDE_REF = 262d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 3); 263d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_LONGITUDE = 264d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 4); 265d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_ALTITUDE_REF = 266d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 5); 267d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_ALTITUDE = 268d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 6); 269d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_TIME_STAMP = 270d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 7); 271d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_SATTELLITES = 272d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 8); 273d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_STATUS = 274d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 9); 275d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_MEASURE_MODE = 276d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 10); 277d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_DOP = 278d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 11); 279d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_SPEED_REF = 280d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 12); 281d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_SPEED = 282d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 13); 283d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_TRACK_REF = 284d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 14); 285d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_TRACK = 286d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 15); 287d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_IMG_DIRECTION_REF = 288d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 16); 289d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_IMG_DIRECTION = 290d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 17); 291d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_MAP_DATUM = 292d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 18); 293d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_DEST_LATITUDE_REF = 294d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 19); 295d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_DEST_LATITUDE = 296d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 20); 297d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_DEST_LONGITUDE_REF = 298d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 21); 299d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_DEST_LONGITUDE = 300d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 22); 301d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_DEST_BEARING_REF = 302d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 23); 303d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_DEST_BEARING = 304d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 24); 305d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_DEST_DISTANCE_REF = 306d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 25); 307d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_DEST_DISTANCE = 308d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 26); 309d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_PROCESSING_METHOD = 310d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 27); 311d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_AREA_INFORMATION = 312d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 28); 313d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_DATE_STAMP = 314d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 29); 315d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_GPS_DIFFERENTIAL = 316d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_GPS, (short) 30); 317d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // IFD Interoperability tags 318d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final int TAG_INTEROPERABILITY_INDEX = 319d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defineTag(IfdId.TYPE_IFD_INTEROPERABILITY, (short) 1); 320d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 321d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 322d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Tags that contain offset markers. These are included in the banned 323d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * defines. 324d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 325d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static HashSet<Short> sOffsetTags = new HashSet<Short>(); 326d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd static { 327d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd sOffsetTags.add(getTrueTagKey(TAG_GPS_IFD)); 328d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd sOffsetTags.add(getTrueTagKey(TAG_EXIF_IFD)); 329d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd sOffsetTags.add(getTrueTagKey(TAG_JPEG_INTERCHANGE_FORMAT)); 330d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd sOffsetTags.add(getTrueTagKey(TAG_INTEROPERABILITY_IFD)); 331d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd sOffsetTags.add(getTrueTagKey(TAG_STRIP_OFFSETS)); 332d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 333d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 334d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 335d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Tags with definitions that cannot be overridden (banned defines). 336d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 337d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected static HashSet<Short> sBannedDefines = new HashSet<Short>(sOffsetTags); 338d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd static { 339d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd sBannedDefines.add(getTrueTagKey(TAG_NULL)); 340d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd sBannedDefines.add(getTrueTagKey(TAG_JPEG_INTERCHANGE_FORMAT_LENGTH)); 341d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd sBannedDefines.add(getTrueTagKey(TAG_STRIP_BYTE_COUNTS)); 342d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 343d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 344d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 345d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Returns the constant representing a tag with a given TID and default IFD. 346d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 347d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static int defineTag(int ifdId, short tagId) { 348d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return (tagId & 0x0000ffff) | (ifdId << 16); 349d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 350d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 351d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 352d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Returns the TID for a tag constant. 353d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 354d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static short getTrueTagKey(int tag) { 355d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Truncate 356d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return (short) tag; 357d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 358d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 359d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 360d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Returns the default IFD for a tag constant. 361d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 362d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static int getTrueIfd(int tag) { 363d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return tag >>> 16; 364d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 365d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 366d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 367d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_ORIENTATION}. They can be interpreted as 368d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * follows: 369d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * <ul> 370d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * <li>TOP_LEFT is the normal orientation.</li> 371d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * <li>TOP_RIGHT is a left-right mirror.</li> 372d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * <li>BOTTOM_LEFT is a 180 degree rotation.</li> 373d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * <li>BOTTOM_RIGHT is a top-bottom mirror.</li> 374d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * <li>LEFT_TOP is mirrored about the top-left<->bottom-right axis.</li> 375d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * <li>RIGHT_TOP is a 90 degree clockwise rotation.</li> 376d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * <li>LEFT_BOTTOM is mirrored about the top-right<->bottom-left axis.</li> 377d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * <li>RIGHT_BOTTOM is a 270 degree clockwise rotation.</li> 378d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * </ul> 379d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 380d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface Orientation { 381d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short TOP_LEFT = 1; 382d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short TOP_RIGHT = 2; 383d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short BOTTOM_LEFT = 3; 384d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short BOTTOM_RIGHT = 4; 385d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short LEFT_TOP = 5; 386d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short RIGHT_TOP = 6; 387d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short LEFT_BOTTOM = 7; 388d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short RIGHT_BOTTOM = 8; 389d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 390d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 391d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 392d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_Y_CB_CR_POSITIONING} 393d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 394d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface YCbCrPositioning { 395d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short CENTERED = 1; 396d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short CO_SITED = 2; 397d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 398d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 399d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 400d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_COMPRESSION} 401d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 402d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface Compression { 403d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short UNCOMPRESSION = 1; 404d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short JPEG = 6; 405d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 406d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 407d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 408d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_RESOLUTION_UNIT} 409d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 410d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface ResolutionUnit { 411d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short INCHES = 2; 412d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short CENTIMETERS = 3; 413d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 414d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 415d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 416d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_PHOTOMETRIC_INTERPRETATION} 417d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 418d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface PhotometricInterpretation { 419d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short RGB = 2; 420d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short YCBCR = 6; 421d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 422d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 423d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 424d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_PLANAR_CONFIGURATION} 425d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 426d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface PlanarConfiguration { 427d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short CHUNKY = 1; 428d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short PLANAR = 2; 429d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 430d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 431d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 432d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_EXPOSURE_PROGRAM} 433d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 434d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface ExposureProgram { 435d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short NOT_DEFINED = 0; 436d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short MANUAL = 1; 437d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short NORMAL_PROGRAM = 2; 438d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short APERTURE_PRIORITY = 3; 439d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short SHUTTER_PRIORITY = 4; 440d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short CREATIVE_PROGRAM = 5; 441d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short ACTION_PROGRAM = 6; 442d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short PROTRAIT_MODE = 7; 443d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short LANDSCAPE_MODE = 8; 444d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 445d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 446d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 447d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_METERING_MODE} 448d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 449d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface MeteringMode { 450d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short UNKNOWN = 0; 451d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short AVERAGE = 1; 452d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short CENTER_WEIGHTED_AVERAGE = 2; 453d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short SPOT = 3; 454d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short MULTISPOT = 4; 455d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short PATTERN = 5; 456d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short PARTAIL = 6; 457d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short OTHER = 255; 458d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 459d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 460d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 461d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_FLASH} As the definition in Jeita EXIF 2.2 462d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * standard, we can treat this constant as bitwise flag. 463d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * <p> 464d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * e.g. 465d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * <p> 466d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * short flash = FIRED | RETURN_STROBE_RETURN_LIGHT_DETECTED | 467d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * MODE_AUTO_MODE 468d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 469d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface Flash { 470d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // LSB 471d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short DID_NOT_FIRED = 0; 472d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short FIRED = 1; 473d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // 1st~2nd bits 474d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short RETURN_NO_STROBE_RETURN_DETECTION_FUNCTION = 0 << 1; 475d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short RETURN_STROBE_RETURN_LIGHT_NOT_DETECTED = 2 << 1; 476d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short RETURN_STROBE_RETURN_LIGHT_DETECTED = 3 << 1; 477d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // 3rd~4th bits 478d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short MODE_UNKNOWN = 0 << 3; 479d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short MODE_COMPULSORY_FLASH_FIRING = 1 << 3; 480d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short MODE_COMPULSORY_FLASH_SUPPRESSION = 2 << 3; 481d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short MODE_AUTO_MODE = 3 << 3; 482d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // 5th bit 483d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short FUNCTION_PRESENT = 0 << 5; 484d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short FUNCTION_NO_FUNCTION = 1 << 5; 485d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // 6th bit 486d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short RED_EYE_REDUCTION_NO_OR_UNKNOWN = 0 << 6; 487d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short RED_EYE_REDUCTION_SUPPORT = 1 << 6; 488d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 489d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 490d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 491d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_COLOR_SPACE} 492d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 493d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface ColorSpace { 494d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short SRGB = 1; 495d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short UNCALIBRATED = (short) 0xFFFF; 496d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 497d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 498d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 499d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_EXPOSURE_MODE} 500d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 501d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface ExposureMode { 502d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short AUTO_EXPOSURE = 0; 503d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short MANUAL_EXPOSURE = 1; 504d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short AUTO_BRACKET = 2; 505d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 506d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 507d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 508d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_WHITE_BALANCE} 509d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 510d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface WhiteBalance { 511d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short AUTO = 0; 512d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short MANUAL = 1; 513d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 514d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 515d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 516d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_SCENE_CAPTURE_TYPE} 517d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 518d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface SceneCapture { 519d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short STANDARD = 0; 520d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short LANDSCAPE = 1; 521d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short PROTRAIT = 2; 522d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short NIGHT_SCENE = 3; 523d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 524d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 525d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 526d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_COMPONENTS_CONFIGURATION} 527d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 528d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface ComponentsConfiguration { 529d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short NOT_EXIST = 0; 530d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short Y = 1; 531d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short CB = 2; 532d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short CR = 3; 533d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short R = 4; 534d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short G = 5; 535d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short B = 6; 536d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 537d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 538d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 539d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_LIGHT_SOURCE} 540d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 541d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface LightSource { 542d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short UNKNOWN = 0; 543d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short DAYLIGHT = 1; 544d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short FLUORESCENT = 2; 545d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short TUNGSTEN = 3; 546d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short FLASH = 4; 547d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short FINE_WEATHER = 9; 548d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short CLOUDY_WEATHER = 10; 549d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short SHADE = 11; 550d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short DAYLIGHT_FLUORESCENT = 12; 551d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short DAY_WHITE_FLUORESCENT = 13; 552d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short COOL_WHITE_FLUORESCENT = 14; 553d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short WHITE_FLUORESCENT = 15; 554d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short STANDARD_LIGHT_A = 17; 555d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short STANDARD_LIGHT_B = 18; 556d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short STANDARD_LIGHT_C = 19; 557d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short D55 = 20; 558d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short D65 = 21; 559d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short D75 = 22; 560d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short D50 = 23; 561d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short ISO_STUDIO_TUNGSTEN = 24; 562d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short OTHER = 255; 563d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 564d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 565d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 566d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_SENSING_METHOD} 567d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 568d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface SensingMethod { 569d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short NOT_DEFINED = 1; 570d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short ONE_CHIP_COLOR = 2; 571d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short TWO_CHIP_COLOR = 3; 572d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short THREE_CHIP_COLOR = 4; 573d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short COLOR_SEQUENTIAL_AREA = 5; 574d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short TRILINEAR = 7; 575d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short COLOR_SEQUENTIAL_LINEAR = 8; 576d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 577d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 578d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 579d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_FILE_SOURCE} 580d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 581d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface FileSource { 582d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short DSC = 3; 583d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 584d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 585d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 586d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_SCENE_TYPE} 587d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 588d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface SceneType { 589d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short DIRECT_PHOTOGRAPHED = 1; 590d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 591d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 592d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 593d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_GAIN_CONTROL} 594d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 595d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface GainControl { 596d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short NONE = 0; 597d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short LOW_UP = 1; 598d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short HIGH_UP = 2; 599d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short LOW_DOWN = 3; 600d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short HIGH_DOWN = 4; 601d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 602d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 603d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 604d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_CONTRAST} 605d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 606d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface Contrast { 607d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short NORMAL = 0; 608d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short SOFT = 1; 609d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short HARD = 2; 610d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 611d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 612d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 613d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_SATURATION} 614d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 615d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface Saturation { 616d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short NORMAL = 0; 617d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short LOW = 1; 618d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short HIGH = 2; 619d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 620d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 621d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 622d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_SHARPNESS} 623d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 624d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface Sharpness { 625d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short NORMAL = 0; 626d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short SOFT = 1; 627d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short HARD = 2; 628d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 629d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 630d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 631d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_SUBJECT_DISTANCE} 632d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 633d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface SubjectDistance { 634d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short UNKNOWN = 0; 635d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short MACRO = 1; 636d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short CLOSE_VIEW = 2; 637d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short DISTANT_VIEW = 3; 638d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 639d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 640d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 641d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_GPS_LATITUDE_REF}, 642d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * {@link TAG_GPS_DEST_LATITUDE_REF} 643d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 644d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface GpsLatitudeRef { 645d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String NORTH = "N"; 646d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String SOUTH = "S"; 647d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 648d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 649d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 650d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_GPS_LONGITUDE_REF}, 651d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * {@link TAG_GPS_DEST_LONGITUDE_REF} 652d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 653d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface GpsLongitudeRef { 654d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String EAST = "E"; 655d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String WEST = "W"; 656d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 657d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 658d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 659d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_GPS_ALTITUDE_REF} 660d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 661d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface GpsAltitudeRef { 662d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short SEA_LEVEL = 0; 663d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short SEA_LEVEL_NEGATIVE = 1; 664d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 665d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 666d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 667d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_GPS_STATUS} 668d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 669d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface GpsStatus { 670d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String IN_PROGRESS = "A"; 671d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String INTEROPERABILITY = "V"; 672d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 673d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 674d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 675d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_GPS_MEASURE_MODE} 676d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 677d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface GpsMeasureMode { 678d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String MODE_2_DIMENSIONAL = "2"; 679d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String MODE_3_DIMENSIONAL = "3"; 680d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 681d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 682d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 683d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_GPS_SPEED_REF}, 684d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * {@link TAG_GPS_DEST_DISTANCE_REF} 685d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 686d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface GpsSpeedRef { 687d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String KILOMETERS = "K"; 688d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String MILES = "M"; 689d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String KNOTS = "N"; 690d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 691d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 692d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 693d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_GPS_TRACK_REF}, 694d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * {@link TAG_GPS_IMG_DIRECTION_REF}, {@link TAG_GPS_DEST_BEARING_REF} 695d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 696d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface GpsTrackRef { 697d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String TRUE_DIRECTION = "T"; 698d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String MAGNETIC_DIRECTION = "M"; 699d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 700d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 701d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 702d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Constants for {@link TAG_GPS_DIFFERENTIAL} 703d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 704d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static interface GpsDifferential { 705d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short WITHOUT_DIFFERENTIAL_CORRECTION = 0; 706d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final short DIFFERENTIAL_CORRECTION_APPLIED = 1; 707d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 708d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 709d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String NULL_ARGUMENT_STRING = "Argument is null"; 710d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private ExifData mData = new ExifData(DEFAULT_BYTE_ORDER); 711d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final ByteOrder DEFAULT_BYTE_ORDER = ByteOrder.BIG_ENDIAN; 712d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 713d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public ExifInterface() { 714d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mGPSDateStampFormat.setTimeZone(TimeZone.getTimeZone("UTC")); 715d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 716d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 717d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 718d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Reads the exif tags from a byte array, clearing this ExifInterface 719d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * object's existing exif tags. 720d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 721d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param jpeg a byte array containing a jpeg compressed image. 722d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @throws java.io.IOException 723d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 724d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void readExif(byte[] jpeg) throws IOException { 725d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd readExif(new ByteArrayInputStream(jpeg)); 726d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 727d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 728d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 729d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Reads the exif tags from an InputStream, clearing this ExifInterface 730d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * object's existing exif tags. 731d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 732d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param inStream an InputStream containing a jpeg compressed image. 733d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @throws java.io.IOException 734d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 735d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void readExif(InputStream inStream) throws IOException { 736d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (inStream == null) { 737d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw new IllegalArgumentException(NULL_ARGUMENT_STRING); 738d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 739d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ExifData d = null; 740d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 741d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd d = new ExifReader(this).read(inStream); 742d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (ExifInvalidFormatException e) { 743d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw new IOException("Invalid exif format : " + e); 744d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 745d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mData = d; 746d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 747d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 748d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 749d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Reads the exif tags from a file, clearing this ExifInterface object's 750d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * existing exif tags. 751d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 752d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param inFileName a string representing the filepath to jpeg file. 753d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @throws java.io.FileNotFoundException 754d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @throws java.io.IOException 755d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 756d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void readExif(String inFileName) throws FileNotFoundException, IOException { 757d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (inFileName == null) { 758d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw new IllegalArgumentException(NULL_ARGUMENT_STRING); 759d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 760d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd InputStream is = null; 761d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 762d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd is = new BufferedInputStream(new FileInputStream(inFileName)); 763d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd readExif(is); 764d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (IOException e) { 765d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd closeSilently(is); 766d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw e; 767d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 768d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd is.close(); 769d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 770d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 771d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 772d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Sets the exif tags, clearing this ExifInterface object's existing exif 773d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * tags. 774d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 775d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param tags a collection of exif tags to set. 776d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 777d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void setExif(Collection<ExifTag> tags) { 778d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd clearExif(); 779d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd setTags(tags); 780d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 781d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 782d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 783d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Clears this ExifInterface object's existing exif tags. 784d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 785d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void clearExif() { 786d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mData = new ExifData(DEFAULT_BYTE_ORDER); 787d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 788d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 789d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 790d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Writes the tags from this ExifInterface object into a jpeg image, 791d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * removing prior exif tags. 792d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 793d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param jpeg a byte array containing a jpeg compressed image. 794d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param exifOutStream an OutputStream to which the jpeg image with added 795d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * exif tags will be written. 796d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @throws java.io.IOException 797d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 798d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void writeExif(byte[] jpeg, OutputStream exifOutStream) throws IOException { 799d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (jpeg == null || exifOutStream == null) { 800d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw new IllegalArgumentException(NULL_ARGUMENT_STRING); 801d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 802d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd OutputStream s = getExifWriterStream(exifOutStream); 803d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd s.write(jpeg, 0, jpeg.length); 804d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd s.flush(); 805d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 806d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 807d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 808d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Writes the tags from this ExifInterface object into a jpeg compressed 809d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * bitmap, removing prior exif tags. 810d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 811d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param bmap a bitmap to compress and write exif into. 812d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param exifOutStream the OutputStream to which the jpeg image with added 813d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * exif tags will be written. 814d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @throws java.io.IOException 815d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 816d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void writeExif(Bitmap bmap, OutputStream exifOutStream) throws IOException { 817d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (bmap == null || exifOutStream == null) { 818d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw new IllegalArgumentException(NULL_ARGUMENT_STRING); 819d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 820d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd OutputStream s = getExifWriterStream(exifOutStream); 821d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd bmap.compress(Bitmap.CompressFormat.JPEG, 90, s); 822d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd s.flush(); 823d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 824d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 825d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 826d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Writes the tags from this ExifInterface object into a jpeg stream, 827d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * removing prior exif tags. 828d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 829d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param jpegStream an InputStream containing a jpeg compressed image. 830d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param exifOutStream an OutputStream to which the jpeg image with added 831d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * exif tags will be written. 832d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @throws java.io.IOException 833d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 834d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void writeExif(InputStream jpegStream, OutputStream exifOutStream) throws IOException { 835d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (jpegStream == null || exifOutStream == null) { 836d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw new IllegalArgumentException(NULL_ARGUMENT_STRING); 837d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 838d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd OutputStream s = getExifWriterStream(exifOutStream); 839d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd doExifStreamIO(jpegStream, s); 840d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd s.flush(); 841d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 842d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 843d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 844d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Writes the tags from this ExifInterface object into a jpeg image, 845d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * removing prior exif tags. 846d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 847d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param jpeg a byte array containing a jpeg compressed image. 848d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param exifOutFileName a String containing the filepath to which the jpeg 849d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * image with added exif tags will be written. 850d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @throws java.io.FileNotFoundException 851d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @throws java.io.IOException 852d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 853d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void writeExif(byte[] jpeg, String exifOutFileName) throws FileNotFoundException, 854d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd IOException { 855d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (jpeg == null || exifOutFileName == null) { 856d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw new IllegalArgumentException(NULL_ARGUMENT_STRING); 857d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 858d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd OutputStream s = null; 859d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 860d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd s = getExifWriterStream(exifOutFileName); 861d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd s.write(jpeg, 0, jpeg.length); 862d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd s.flush(); 863d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (IOException e) { 864d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd closeSilently(s); 865d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw e; 866d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 867d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd s.close(); 868d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 869d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 870d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 871d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Writes the tags from this ExifInterface object into a jpeg compressed 872d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * bitmap, removing prior exif tags. 873d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 874d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param bmap a bitmap to compress and write exif into. 875d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param exifOutFileName a String containing the filepath to which the jpeg 876d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * image with added exif tags will be written. 877d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @throws java.io.FileNotFoundException 878d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @throws java.io.IOException 879d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 880d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void writeExif(Bitmap bmap, String exifOutFileName) throws FileNotFoundException, 881d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd IOException { 882d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (bmap == null || exifOutFileName == null) { 883d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw new IllegalArgumentException(NULL_ARGUMENT_STRING); 884d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 885d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd OutputStream s = null; 886d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 887d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd s = getExifWriterStream(exifOutFileName); 888d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd bmap.compress(Bitmap.CompressFormat.JPEG, 90, s); 889d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd s.flush(); 890d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (IOException e) { 891d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd closeSilently(s); 892d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw e; 893d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 894d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd s.close(); 895d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 896d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 897d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 898d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Writes the tags from this ExifInterface object into a jpeg stream, 899d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * removing prior exif tags. 900d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 901d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param jpegStream an InputStream containing a jpeg compressed image. 902d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param exifOutFileName a String containing the filepath to which the jpeg 903d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * image with added exif tags will be written. 904d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @throws java.io.FileNotFoundException 905d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @throws java.io.IOException 906d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 907d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void writeExif(InputStream jpegStream, String exifOutFileName) 908d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throws FileNotFoundException, IOException { 909d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (jpegStream == null || exifOutFileName == null) { 910d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw new IllegalArgumentException(NULL_ARGUMENT_STRING); 911d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 912d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd OutputStream s = null; 913d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 914d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd s = getExifWriterStream(exifOutFileName); 915d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd doExifStreamIO(jpegStream, s); 916d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd s.flush(); 917d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (IOException e) { 918d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd closeSilently(s); 919d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw e; 920d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 921d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd s.close(); 922d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 923d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 924d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 925d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Writes the tags from this ExifInterface object into a jpeg file, removing 926d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * prior exif tags. 927d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 928d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param jpegFileName a String containing the filepath for a jpeg file. 929d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param exifOutFileName a String containing the filepath to which the jpeg 930d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * image with added exif tags will be written. 931d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @throws java.io.FileNotFoundException 932d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @throws java.io.IOException 933d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 934d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void writeExif(String jpegFileName, String exifOutFileName) 935d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throws FileNotFoundException, IOException { 936d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (jpegFileName == null || exifOutFileName == null) { 937d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw new IllegalArgumentException(NULL_ARGUMENT_STRING); 938d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 939d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd InputStream is = null; 940d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 941d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd is = new FileInputStream(jpegFileName); 942d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd writeExif(is, exifOutFileName); 943d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (IOException e) { 944d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd closeSilently(is); 945d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw e; 946d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 947d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd is.close(); 948d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 949d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 950d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 951d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Wraps an OutputStream object with an ExifOutputStream. Exif tags in this 952d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * ExifInterface object will be added to a jpeg image written to this 953d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * stream, removing prior exif tags. Other methods of this ExifInterface 954d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * object should not be called until the returned OutputStream has been 955d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * closed. 956d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 957d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param outStream an OutputStream to wrap. 958d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return an OutputStream that wraps the outStream parameter, and adds exif 959d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * metadata. A jpeg image should be written to this stream. 960d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 961d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public OutputStream getExifWriterStream(OutputStream outStream) { 962d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (outStream == null) { 963d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw new IllegalArgumentException(NULL_ARGUMENT_STRING); 964d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 965d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ExifOutputStream eos = new ExifOutputStream(outStream, this); 966d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd eos.setExifData(mData); 967d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return eos; 968d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 969d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 970d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 971d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Returns an OutputStream object that writes to a file. Exif tags in this 972d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * ExifInterface object will be added to a jpeg image written to this 973d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * stream, removing prior exif tags. Other methods of this ExifInterface 974d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * object should not be called until the returned OutputStream has been 975d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * closed. 976d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 977d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param exifOutFileName an String containing a filepath for a jpeg file. 978d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return an OutputStream that writes to the exifOutFileName file, and adds 979d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * exif metadata. A jpeg image should be written to this stream. 980d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @throws java.io.FileNotFoundException 981d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 982d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public OutputStream getExifWriterStream(String exifOutFileName) throws FileNotFoundException { 983d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (exifOutFileName == null) { 984d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw new IllegalArgumentException(NULL_ARGUMENT_STRING); 985d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 986d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd OutputStream out = null; 987d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 988d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd out = new FileOutputStream(exifOutFileName); 989d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (FileNotFoundException e) { 990d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd closeSilently(out); 991d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw e; 992d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 993d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getExifWriterStream(out); 994d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 995d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 996d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 997d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Attempts to do an in-place rewrite the exif metadata in a file for the 998d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * given tags. If tags do not exist or do not have the same size as the 999d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * existing exif tags, this method will fail. 1000d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1001d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param filename a String containing a filepath for a jpeg file with exif 1002d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * tags to rewrite. 1003d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param tags tags that will be written into the jpeg file over existing 1004d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * tags if possible. 1005d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return true if success, false if could not overwrite. If false, no 1006d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * changes are made to the file. 1007d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @throws java.io.FileNotFoundException 1008d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @throws java.io.IOException 1009d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1010d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean rewriteExif(String filename, Collection<ExifTag> tags) 1011d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throws FileNotFoundException, IOException { 1012d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd RandomAccessFile file = null; 1013d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd InputStream is = null; 1014d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd boolean ret; 1015d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 1016d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd File temp = new File(filename); 1017d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd is = new BufferedInputStream(new FileInputStream(temp)); 1018d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1019d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Parse beginning of APP1 in exif to find size of exif header. 1020d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ExifParser parser = null; 1021d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 1022d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd parser = ExifParser.parse(is, this); 1023d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (ExifInvalidFormatException e) { 1024d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw new IOException("Invalid exif format : ", e); 1025d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1026d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd long exifSize = parser.getOffsetToExifEndFromSOF(); 1027d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1028d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Free up resources 1029d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd is.close(); 1030d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd is = null; 1031d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1032d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Open file for memory mapping. 1033d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd file = new RandomAccessFile(temp, "rw"); 1034d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd long fileLength = file.length(); 1035d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (fileLength < exifSize) { 1036d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw new IOException("Filesize changed during operation"); 1037d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1038d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1039d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Map only exif header into memory. 1040d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ByteBuffer buf = file.getChannel().map(MapMode.READ_WRITE, 0, exifSize); 1041d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1042d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Attempt to overwrite tag values without changing lengths (avoids 1043d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // file copy). 1044d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ret = rewriteExif(buf, tags); 1045d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (IOException e) { 1046d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd closeSilently(file); 1047d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw e; 1048d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } finally { 1049d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd closeSilently(is); 1050d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1051d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd file.close(); 1052d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return ret; 1053d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1054d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1055d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1056d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Attempts to do an in-place rewrite the exif metadata in a ByteBuffer for 1057d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * the given tags. If tags do not exist or do not have the same size as the 1058d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * existing exif tags, this method will fail. 1059d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1060d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param buf a ByteBuffer containing a jpeg file with existing exif tags to 1061d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * rewrite. 1062d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param tags tags that will be written into the jpeg ByteBuffer over 1063d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * existing tags if possible. 1064d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return true if success, false if could not overwrite. If false, no 1065d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * changes are made to the ByteBuffer. 1066d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @throws java.io.IOException 1067d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1068d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean rewriteExif(ByteBuffer buf, Collection<ExifTag> tags) throws IOException { 1069d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ExifModifier mod = null; 1070d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 1071d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mod = new ExifModifier(buf, this); 1072d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd for (ExifTag t : tags) { 1073d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mod.modifyTag(t); 1074d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1075d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mod.commit(); 1076d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (ExifInvalidFormatException e) { 1077d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw new IOException("Invalid exif format : " + e); 1078d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1079d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1080d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1081d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1082d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Attempts to do an in-place rewrite of the exif metadata. If this fails, 1083d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * fall back to overwriting file. This preserves tags that are not being 1084d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * rewritten. 1085d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1086d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param filename a String containing a filepath for a jpeg file. 1087d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param tags tags that will be written into the jpeg file over existing 1088d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * tags if possible. 1089d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @throws java.io.FileNotFoundException 1090d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @throws java.io.IOException 1091d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @see #rewriteExif 1092d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1093d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void forceRewriteExif(String filename, Collection<ExifTag> tags) 1094d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throws FileNotFoundException, 1095d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd IOException { 1096d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Attempt in-place write 1097d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (!rewriteExif(filename, tags)) { 1098d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Fall back to doing a copy 1099d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ExifData tempData = mData; 1100d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mData = new ExifData(DEFAULT_BYTE_ORDER); 1101d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd FileInputStream is = null; 1102d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ByteArrayOutputStream bytes = null; 1103d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 1104d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd is = new FileInputStream(filename); 1105d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd bytes = new ByteArrayOutputStream(); 1106d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd doExifStreamIO(is, bytes); 1107d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] imageBytes = bytes.toByteArray(); 1108d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd readExif(imageBytes); 1109d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd setTags(tags); 1110d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd writeExif(imageBytes, filename); 1111d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (IOException e) { 1112d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd closeSilently(is); 1113d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw e; 1114d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } finally { 1115d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd is.close(); 1116d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Prevent clobbering of mData 1117d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mData = tempData; 1118d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1119d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1120d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1121d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1122d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1123d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Attempts to do an in-place rewrite of the exif metadata using the tags in 1124d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * this ExifInterface object. If this fails, fall back to overwriting file. 1125d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * This preserves tags that are not being rewritten. 1126d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1127d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param filename a String containing a filepath for a jpeg file. 1128d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @throws java.io.FileNotFoundException 1129d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @throws java.io.IOException 1130d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @see #rewriteExif 1131d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1132d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void forceRewriteExif(String filename) throws FileNotFoundException, IOException { 1133d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd forceRewriteExif(filename, getAllTags()); 1134d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1135d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1136d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1137d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Get the exif tags in this ExifInterface object or null if none exist. 1138d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1139d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return a List of {@link ExifTag}s. 1140d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1141d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public List<ExifTag> getAllTags() { 1142d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mData.getAllTags(); 1143d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1144d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1145d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1146d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Returns a list of ExifTags that share a TID (which can be obtained by 1147d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * calling {@link #getTrueTagKey} on a defined tag constant) or null if none 1148d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * exist. 1149d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1150d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param tagId a TID as defined in the exif standard (or with 1151d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * {@link #defineTag}). 1152d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return a List of {@link ExifTag}s. 1153d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1154d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public List<ExifTag> getTagsForTagId(short tagId) { 1155d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mData.getAllTagsForTagId(tagId); 1156d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1157d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1158d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1159d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Returns a list of ExifTags that share an IFD (which can be obtained by 1160d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * calling {@link #getTrueIFD} on a defined tag constant) or null if none 1161d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * exist. 1162d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1163d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param ifdId an IFD as defined in the exif standard (or with 1164d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * {@link #defineTag}). 1165d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return a List of {@link ExifTag}s. 1166d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1167d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public List<ExifTag> getTagsForIfdId(int ifdId) { 1168d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mData.getAllTagsForIfd(ifdId); 1169d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1170d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1171d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1172d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Gets an ExifTag for an IFD other than the tag's default. 1173d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1174d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @see #getTag 1175d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1176d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public ExifTag getTag(int tagId, int ifdId) { 1177d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (!ExifTag.isValidIfd(ifdId)) { 1178d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 1179d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1180d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mData.getTag(getTrueTagKey(tagId), ifdId); 1181d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1182d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1183d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1184d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Returns the ExifTag in that tag's default IFD for a defined tag constant 1185d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * or null if none exists. 1186d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1187d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param tagId a defined tag constant, e.g. {@link #TAG_IMAGE_WIDTH}. 1188d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return an {@link ExifTag} or null if none exists. 1189d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1190d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public ExifTag getTag(int tagId) { 1191d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int ifdId = getDefinedTagDefaultIfd(tagId); 1192d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getTag(tagId, ifdId); 1193d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1194d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1195d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1196d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Gets a tag value for an IFD other than the tag's default. 1197d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1198d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @see #getTagValue 1199d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1200d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public Object getTagValue(int tagId, int ifdId) { 1201d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ExifTag t = getTag(tagId, ifdId); 1202d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return (t == null) ? null : t.getValue(); 1203d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1204d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1205d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1206d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Returns the value of the ExifTag in that tag's default IFD for a defined 1207d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * tag constant or null if none exists or the value could not be cast into 1208d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * the return type. 1209d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1210d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param tagId a defined tag constant, e.g. {@link #TAG_IMAGE_WIDTH}. 1211d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the value of the ExifTag or null if none exists. 1212d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1213d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public Object getTagValue(int tagId) { 1214d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int ifdId = getDefinedTagDefaultIfd(tagId); 1215d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getTagValue(tagId, ifdId); 1216d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1217d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1218d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* 1219d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Getter methods that are similar to getTagValue. Null is returned if the 1220d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * tag value cannot be cast into the return type. 1221d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1222d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1223d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1224d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @see #getTagValue 1225d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1226d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public String getTagStringValue(int tagId, int ifdId) { 1227d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ExifTag t = getTag(tagId, ifdId); 1228d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (t == null) { 1229d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 1230d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1231d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return t.getValueAsString(); 1232d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1233d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1234d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1235d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @see #getTagValue 1236d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1237d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public String getTagStringValue(int tagId) { 1238d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int ifdId = getDefinedTagDefaultIfd(tagId); 1239d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getTagStringValue(tagId, ifdId); 1240d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1241d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1242d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1243d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @see #getTagValue 1244d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1245d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public Long getTagLongValue(int tagId, int ifdId) { 1246d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd long[] l = getTagLongValues(tagId, ifdId); 1247d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (l == null || l.length <= 0) { 1248d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 1249d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1250d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return new Long(l[0]); 1251d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1252d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1253d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1254d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @see #getTagValue 1255d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1256d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public Long getTagLongValue(int tagId) { 1257d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int ifdId = getDefinedTagDefaultIfd(tagId); 1258d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getTagLongValue(tagId, ifdId); 1259d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1260d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1261d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1262d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @see #getTagValue 1263d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1264d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public Integer getTagIntValue(int tagId, int ifdId) { 1265d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int[] l = getTagIntValues(tagId, ifdId); 1266d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (l == null || l.length <= 0) { 1267d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 1268d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1269d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return new Integer(l[0]); 1270d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1271d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1272d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1273d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @see #getTagValue 1274d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1275d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public Integer getTagIntValue(int tagId) { 1276d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int ifdId = getDefinedTagDefaultIfd(tagId); 1277d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getTagIntValue(tagId, ifdId); 1278d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1279d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1280d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1281d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @see #getTagValue 1282d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1283d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public Byte getTagByteValue(int tagId, int ifdId) { 1284d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] l = getTagByteValues(tagId, ifdId); 1285d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (l == null || l.length <= 0) { 1286d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 1287d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1288d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return new Byte(l[0]); 1289d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1290d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1291d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1292d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @see #getTagValue 1293d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1294d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public Byte getTagByteValue(int tagId) { 1295d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int ifdId = getDefinedTagDefaultIfd(tagId); 1296d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getTagByteValue(tagId, ifdId); 1297d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1298d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1299d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1300d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @see #getTagValue 1301d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1302d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public Rational getTagRationalValue(int tagId, int ifdId) { 1303d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Rational[] l = getTagRationalValues(tagId, ifdId); 1304d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (l == null || l.length == 0) { 1305d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 1306d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1307d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return new Rational(l[0]); 1308d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1309d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1310d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1311d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @see #getTagValue 1312d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1313d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public Rational getTagRationalValue(int tagId) { 1314d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int ifdId = getDefinedTagDefaultIfd(tagId); 1315d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getTagRationalValue(tagId, ifdId); 1316d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1317d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1318d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1319d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @see #getTagValue 1320d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1321d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public long[] getTagLongValues(int tagId, int ifdId) { 1322d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ExifTag t = getTag(tagId, ifdId); 1323d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (t == null) { 1324d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 1325d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1326d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return t.getValueAsLongs(); 1327d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1328d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1329d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1330d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @see #getTagValue 1331d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1332d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public long[] getTagLongValues(int tagId) { 1333d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int ifdId = getDefinedTagDefaultIfd(tagId); 1334d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getTagLongValues(tagId, ifdId); 1335d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1336d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1337d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1338d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @see #getTagValue 1339d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1340d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public int[] getTagIntValues(int tagId, int ifdId) { 1341d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ExifTag t = getTag(tagId, ifdId); 1342d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (t == null) { 1343d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 1344d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1345d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return t.getValueAsInts(); 1346d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1347d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1348d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1349d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @see #getTagValue 1350d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1351d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public int[] getTagIntValues(int tagId) { 1352d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int ifdId = getDefinedTagDefaultIfd(tagId); 1353d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getTagIntValues(tagId, ifdId); 1354d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1355d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1356d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1357d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @see #getTagValue 1358d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1359d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public byte[] getTagByteValues(int tagId, int ifdId) { 1360d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ExifTag t = getTag(tagId, ifdId); 1361d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (t == null) { 1362d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 1363d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1364d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return t.getValueAsBytes(); 1365d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1366d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1367d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1368d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @see #getTagValue 1369d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1370d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public byte[] getTagByteValues(int tagId) { 1371d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int ifdId = getDefinedTagDefaultIfd(tagId); 1372d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getTagByteValues(tagId, ifdId); 1373d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1374d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1375d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1376d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @see #getTagValue 1377d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1378d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public Rational[] getTagRationalValues(int tagId, int ifdId) { 1379d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ExifTag t = getTag(tagId, ifdId); 1380d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (t == null) { 1381d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 1382d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1383d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return t.getValueAsRationals(); 1384d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1385d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1386d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1387d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @see #getTagValue 1388d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1389d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public Rational[] getTagRationalValues(int tagId) { 1390d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int ifdId = getDefinedTagDefaultIfd(tagId); 1391d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getTagRationalValues(tagId, ifdId); 1392d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1393d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1394d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1395d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Checks whether a tag has a defined number of elements. 1396d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1397d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param tagId a defined tag constant, e.g. {@link #TAG_IMAGE_WIDTH}. 1398d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return true if the tag has a defined number of elements. 1399d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1400d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean isTagCountDefined(int tagId) { 1401d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int info = getTagInfo().get(tagId); 1402d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // No value in info can be zero, as all tags have a non-zero type 1403d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (info == 0) { 1404d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1405d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1406d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getComponentCountFromInfo(info) != ExifTag.SIZE_UNDEFINED; 1407d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1408d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1409d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1410d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Gets the defined number of elements for a tag. 1411d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1412d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param tagId a defined tag constant, e.g. {@link #TAG_IMAGE_WIDTH}. 1413d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the number of elements or {@link ExifTag#SIZE_UNDEFINED} if the 1414d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * tag or the number of elements is not defined. 1415d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1416d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public int getDefinedTagCount(int tagId) { 1417d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int info = getTagInfo().get(tagId); 1418d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (info == 0) { 1419d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return ExifTag.SIZE_UNDEFINED; 1420d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1421d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getComponentCountFromInfo(info); 1422d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1423d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1424d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1425d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Gets the number of elements for an ExifTag in a given IFD. 1426d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1427d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param tagId a defined tag constant, e.g. {@link #TAG_IMAGE_WIDTH}. 1428d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param ifdId the IFD containing the ExifTag to check. 1429d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the number of elements in the ExifTag, if the tag's size is 1430d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * undefined this will return the actual number of elements that is 1431d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * in the ExifTag's value. 1432d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1433d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public int getActualTagCount(int tagId, int ifdId) { 1434d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ExifTag t = getTag(tagId, ifdId); 1435d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (t == null) { 1436d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return 0; 1437d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1438d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return t.getComponentCount(); 1439d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1440d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1441d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1442d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Gets the default IFD for a tag. 1443d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1444d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param tagId a defined tag constant, e.g. {@link #TAG_IMAGE_WIDTH}. 1445d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the default IFD for a tag definition or {@link #IFD_NULL} if no 1446d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * definition exists. 1447d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1448d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public int getDefinedTagDefaultIfd(int tagId) { 1449d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int info = getTagInfo().get(tagId); 1450d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (info == DEFINITION_NULL) { 1451d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return IFD_NULL; 1452d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1453d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getTrueIfd(tagId); 1454d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1455d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1456d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1457d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Gets the defined type for a tag. 1458d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1459d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param tagId a defined tag constant, e.g. {@link #TAG_IMAGE_WIDTH}. 1460d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the type. 1461d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @see ExifTag#getDataType() 1462d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1463d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public short getDefinedTagType(int tagId) { 1464d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int info = getTagInfo().get(tagId); 1465d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (info == 0) { 1466d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return -1; 1467d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1468d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getTypeFromInfo(info); 1469d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1470d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1471d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1472d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Returns true if tag TID is one of the following: {@link TAG_EXIF_IFD}, 1473d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * {@link TAG_GPS_IFD}, {@link TAG_JPEG_INTERCHANGE_FORMAT}, 1474d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * {@link TAG_STRIP_OFFSETS}, {@link TAG_INTEROPERABILITY_IFD} 1475d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * <p> 1476d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Note: defining tags with these TID's is disallowed. 1477d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1478d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param tag a tag's TID (can be obtained from a defined tag constant with 1479d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * {@link #getTrueTagKey}). 1480d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return true if the TID is that of an offset tag. 1481d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1482d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected static boolean isOffsetTag(short tag) { 1483d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return sOffsetTags.contains(tag); 1484d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1485d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1486d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1487d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Creates a tag for a defined tag constant in a given IFD if that IFD is 1488d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * allowed for the tag. This method will fail anytime the appropriate 1489d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * {@link ExifTag#setValue} for this tag's datatype would fail. 1490d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1491d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param tagId a tag constant, e.g. {@link #TAG_IMAGE_WIDTH}. 1492d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param ifdId the IFD that the tag should be in. 1493d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param val the value of the tag to set. 1494d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return an ExifTag object or null if one could not be constructed. 1495d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @see #buildTag 1496d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1497d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public ExifTag buildTag(int tagId, int ifdId, Object val) { 1498d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int info = getTagInfo().get(tagId); 1499d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (info == 0 || val == null) { 1500d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 1501d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1502d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd short type = getTypeFromInfo(info); 1503d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int definedCount = getComponentCountFromInfo(info); 1504d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd boolean hasDefinedCount = (definedCount != ExifTag.SIZE_UNDEFINED); 1505d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (!ExifInterface.isIfdAllowed(info, ifdId)) { 1506d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 1507d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1508d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ExifTag t = new ExifTag(getTrueTagKey(tagId), type, definedCount, ifdId, hasDefinedCount); 1509d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (!t.setValue(val)) { 1510d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 1511d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1512d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return t; 1513d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1514d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1515d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1516d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Creates a tag for a defined tag constant in the tag's default IFD. 1517d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1518d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param tagId a tag constant, e.g. {@link #TAG_IMAGE_WIDTH}. 1519d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param val the tag's value. 1520d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return an ExifTag object. 1521d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1522d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public ExifTag buildTag(int tagId, Object val) { 1523d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int ifdId = getTrueIfd(tagId); 1524d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return buildTag(tagId, ifdId, val); 1525d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1526d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1527d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected ExifTag buildUninitializedTag(int tagId) { 1528d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int info = getTagInfo().get(tagId); 1529d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (info == 0) { 1530d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 1531d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1532d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd short type = getTypeFromInfo(info); 1533d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int definedCount = getComponentCountFromInfo(info); 1534d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd boolean hasDefinedCount = (definedCount != ExifTag.SIZE_UNDEFINED); 1535d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int ifdId = getTrueIfd(tagId); 1536d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ExifTag t = new ExifTag(getTrueTagKey(tagId), type, definedCount, ifdId, hasDefinedCount); 1537d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return t; 1538d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1539d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1540d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1541d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Sets the value of an ExifTag if it exists in the given IFD. The value 1542d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * must be the correct type and length for that ExifTag. 1543d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1544d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param tagId a tag constant, e.g. {@link #TAG_IMAGE_WIDTH}. 1545d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param ifdId the IFD that the ExifTag is in. 1546d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param val the value to set. 1547d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return true if success, false if the ExifTag doesn't exist or the value 1548d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * is the wrong type/length. 1549d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @see #setTagValue 1550d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1551d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean setTagValue(int tagId, int ifdId, Object val) { 1552d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ExifTag t = getTag(tagId, ifdId); 1553d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (t == null) { 1554d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1555d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1556d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return t.setValue(val); 1557d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1558d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1559d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1560d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Sets the value of an ExifTag if it exists it's default IFD. The value 1561d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * must be the correct type and length for that ExifTag. 1562d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1563d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param tagId a tag constant, e.g. {@link #TAG_IMAGE_WIDTH}. 1564d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param val the value to set. 1565d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return true if success, false if the ExifTag doesn't exist or the value 1566d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * is the wrong type/length. 1567d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1568d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean setTagValue(int tagId, Object val) { 1569d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int ifdId = getDefinedTagDefaultIfd(tagId); 1570d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return setTagValue(tagId, ifdId, val); 1571d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1572d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1573d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1574d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Puts an ExifTag into this ExifInterface object's tags, removing a 1575d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * previous ExifTag with the same TID and IFD. The IFD it is put into will 1576d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * be the one the tag was created with in {@link #buildTag}. 1577d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1578d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param tag an ExifTag to put into this ExifInterface's tags. 1579d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the previous ExifTag with the same TID and IFD or null if none 1580d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * exists. 1581d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1582d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public ExifTag setTag(ExifTag tag) { 1583d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mData.addTag(tag); 1584d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1585d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1586d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1587d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Puts a collection of ExifTags into this ExifInterface objects's tags. Any 1588d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * previous ExifTags with the same TID and IFDs will be removed. 1589d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1590d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param tags a Collection of ExifTags. 1591d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @see #setTag 1592d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1593d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void setTags(Collection<ExifTag> tags) { 1594d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd for (ExifTag t : tags) { 1595d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd setTag(t); 1596d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1597d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1598d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1599d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1600d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Removes the ExifTag for a tag constant from the given IFD. 1601d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1602d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param tagId a tag constant, e.g. {@link #TAG_IMAGE_WIDTH}. 1603d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param ifdId the IFD of the ExifTag to remove. 1604d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1605d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void deleteTag(int tagId, int ifdId) { 1606d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mData.removeTag(getTrueTagKey(tagId), ifdId); 1607d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1608d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1609d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1610d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Removes the ExifTag for a tag constant from that tag's default IFD. 1611d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1612d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param tagId a tag constant, e.g. {@link #TAG_IMAGE_WIDTH}. 1613d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1614d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void deleteTag(int tagId) { 1615d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int ifdId = getDefinedTagDefaultIfd(tagId); 1616d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd deleteTag(tagId, ifdId); 1617d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1618d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1619d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1620d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Creates a new tag definition in this ExifInterface object for a given TID 1621d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * and default IFD. Creating a definition with the same TID and default IFD 1622d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * as a previous definition will override it. 1623d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1624d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param tagId the TID for the tag. 1625d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param defaultIfd the default IFD for the tag. 1626d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param tagType the type of the tag (see {@link ExifTag#getDataType()}). 1627d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param defaultComponentCount the number of elements of this tag's type in 1628d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * the tags value. 1629d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param allowedIfds the IFD's this tag is allowed to be put in. 1630d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the defined tag constant (e.g. {@link #TAG_IMAGE_WIDTH}) or 1631d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * {@link #TAG_NULL} if the definition could not be made. 1632d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1633d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public int setTagDefinition(short tagId, int defaultIfd, short tagType, 1634d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd short defaultComponentCount, int[] allowedIfds) { 1635d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (sBannedDefines.contains(tagId)) { 1636d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return TAG_NULL; 1637d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1638d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (ExifTag.isValidType(tagType) && ExifTag.isValidIfd(defaultIfd)) { 1639d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int tagDef = defineTag(defaultIfd, tagId); 1640d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (tagDef == TAG_NULL) { 1641d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return TAG_NULL; 1642d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1643d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int[] otherDefs = getTagDefinitionsForTagId(tagId); 1644d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd SparseIntArray infos = getTagInfo(); 1645d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Make sure defaultIfd is in allowedIfds 1646d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd boolean defaultCheck = false; 1647d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd for (int i : allowedIfds) { 1648d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (defaultIfd == i) { 1649d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defaultCheck = true; 1650d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1651d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (!ExifTag.isValidIfd(i)) { 1652d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return TAG_NULL; 1653d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1654d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1655d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (!defaultCheck) { 1656d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return TAG_NULL; 1657d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1658d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1659d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int ifdFlags = getFlagsFromAllowedIfds(allowedIfds); 1660d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Make sure no identical tags can exist in allowedIfds 1661d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (otherDefs != null) { 1662d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd for (int def : otherDefs) { 1663d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int tagInfo = infos.get(def); 1664d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int allowedFlags = getAllowedIfdFlagsFromInfo(tagInfo); 1665d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if ((ifdFlags & allowedFlags) != 0) { 1666d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return TAG_NULL; 1667d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1668d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1669d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1670d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd getTagInfo().put(tagDef, ifdFlags << 24 | (tagType << 16) | defaultComponentCount); 1671d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return tagDef; 1672d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1673d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return TAG_NULL; 1674d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1675d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1676d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected int getTagDefinition(short tagId, int defaultIfd) { 1677d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getTagInfo().get(defineTag(defaultIfd, tagId)); 1678d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1679d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1680d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected int[] getTagDefinitionsForTagId(short tagId) { 1681d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int[] ifds = IfdData.getIfds(); 1682d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int[] defs = new int[ifds.length]; 1683d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int counter = 0; 1684d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd SparseIntArray infos = getTagInfo(); 1685d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd for (int i : ifds) { 1686d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int def = defineTag(i, tagId); 1687d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (infos.get(def) != DEFINITION_NULL) { 1688d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd defs[counter++] = def; 1689d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1690d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1691d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (counter == 0) { 1692d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 1693d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1694d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1695d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return Arrays.copyOfRange(defs, 0, counter); 1696d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1697d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1698d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected int getTagDefinitionForTag(ExifTag tag) { 1699d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd short type = tag.getDataType(); 1700d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int count = tag.getComponentCount(); 1701d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int ifd = tag.getIfd(); 1702d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getTagDefinitionForTag(tag.getTagId(), type, count, ifd); 1703d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1704d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1705d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected int getTagDefinitionForTag(short tagId, short type, int count, int ifd) { 1706d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int[] defs = getTagDefinitionsForTagId(tagId); 1707d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (defs == null) { 1708d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return TAG_NULL; 1709d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1710d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd SparseIntArray infos = getTagInfo(); 1711d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int ret = TAG_NULL; 1712d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd for (int i : defs) { 1713d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int info = infos.get(i); 1714d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd short defType = getTypeFromInfo(info); 1715d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int defCount = getComponentCountFromInfo(info); 1716d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int[] defIfds = getAllowedIfdsFromInfo(info); 1717d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd boolean validIfd = false; 1718d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd for (int j : defIfds) { 1719d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (j == ifd) { 1720d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd validIfd = true; 1721d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 1722d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1723d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1724d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (validIfd && type == defType 1725d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd && (count == defCount || defCount == ExifTag.SIZE_UNDEFINED)) { 1726d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ret = i; 1727d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 1728d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1729d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1730d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return ret; 1731d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1732d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1733d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1734d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Removes a tag definition for given defined tag constant. 1735d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1736d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param tagId a defined tag constant, e.g. {@link #TAG_IMAGE_WIDTH}. 1737d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1738d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void removeTagDefinition(int tagId) { 1739d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd getTagInfo().delete(tagId); 1740d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1741d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1742d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1743d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Resets tag definitions to the default ones. 1744d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1745d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void resetTagDefinitions() { 1746d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo = null; 1747d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1748d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1749d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1750d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Returns the thumbnail from IFD1 as a bitmap, or null if none exists. 1751d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1752d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the thumbnail as a bitmap. 1753d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1754d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public Bitmap getThumbnailBitmap() { 1755d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (mData.hasCompressedThumbnail()) { 1756d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] thumb = mData.getCompressedThumbnail(); 1757d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return BitmapFactory.decodeByteArray(thumb, 0, thumb.length); 1758d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else if (mData.hasUncompressedStrip()) { 1759d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // TODO: implement uncompressed 1760d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1761d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 1762d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1763d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1764d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1765d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Returns the thumbnail from IFD1 as a byte array, or null if none exists. 1766d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * The bytes may either be an uncompressed strip as specified in the exif 1767d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * standard or a jpeg compressed image. 1768d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1769d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the thumbnail as a byte array. 1770d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1771d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public byte[] getThumbnailBytes() { 1772d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (mData.hasCompressedThumbnail()) { 1773d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mData.getCompressedThumbnail(); 1774d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else if (mData.hasUncompressedStrip()) { 1775d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // TODO: implement this 1776d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1777d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 1778d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1779d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1780d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1781d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Returns the thumbnail if it is jpeg compressed, or null if none exists. 1782d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1783d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the thumbnail as a byte array. 1784d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1785d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public byte[] getThumbnail() { 1786d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mData.getCompressedThumbnail(); 1787d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1788d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1789d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1790d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Check if thumbnail is compressed. 1791d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1792d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return true if the thumbnail is compressed. 1793d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1794d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean isThumbnailCompressed() { 1795d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mData.hasCompressedThumbnail(); 1796d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1797d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1798d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1799d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Check if thumbnail exists. 1800d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1801d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return true if a compressed thumbnail exists. 1802d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1803d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean hasThumbnail() { 1804d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // TODO: add back in uncompressed strip 1805d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mData.hasCompressedThumbnail(); 1806d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1807d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1808d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // TODO: uncompressed thumbnail setters 1809d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1810d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1811d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Sets the thumbnail to be a jpeg compressed image. Clears any prior 1812d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * thumbnail. 1813d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1814d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param thumb a byte array containing a jpeg compressed image. 1815d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return true if the thumbnail was set. 1816d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1817d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean setCompressedThumbnail(byte[] thumb) { 1818d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mData.clearThumbnailAndStrips(); 1819d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mData.setCompressedThumbnail(thumb); 1820d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return true; 1821d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1822d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1823d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1824d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Sets the thumbnail to be a jpeg compressed bitmap. Clears any prior 1825d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * thumbnail. 1826d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1827d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param thumb a bitmap to compress to a jpeg thumbnail. 1828d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return true if the thumbnail was set. 1829d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1830d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean setCompressedThumbnail(Bitmap thumb) { 1831d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ByteArrayOutputStream thumbnail = new ByteArrayOutputStream(); 1832d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (!thumb.compress(Bitmap.CompressFormat.JPEG, 90, thumbnail)) { 1833d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 1834d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1835d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return setCompressedThumbnail(thumbnail.toByteArray()); 1836d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1837d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1838d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1839d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Clears the compressed thumbnail if it exists. 1840d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1841d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void removeCompressedThumbnail() { 1842d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mData.setCompressedThumbnail(null); 1843d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1844d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1845d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Convenience methods: 1846d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1847d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1848d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Decodes the user comment tag into string as specified in the EXIF 1849d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * standard. Returns null if decoding failed. 1850d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1851d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public String getUserComment() { 1852d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mData.getUserComment(); 1853d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1854d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1855d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1856d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Returns the Orientation ExifTag value for a given number of degrees. 1857d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1858d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param degrees the amount an image is rotated in degrees. 1859d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1860d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static short getOrientationValueForRotation(int degrees) { 1861d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd degrees %= 360; 1862d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (degrees < 0) { 1863d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd degrees += 360; 1864d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1865d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (degrees < 90) { 1866d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return Orientation.TOP_LEFT; // 0 degrees 1867d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else if (degrees < 180) { 1868d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return Orientation.RIGHT_TOP; // 90 degrees cw 1869d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else if (degrees < 270) { 1870d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return Orientation.BOTTOM_LEFT; // 180 degrees 1871d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 1872d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return Orientation.RIGHT_BOTTOM; // 270 degrees cw 1873d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1874d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1875d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1876d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1877d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Returns the rotation degrees corresponding to an ExifTag Orientation 1878d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * value. 1879d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1880d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param orientation the ExifTag Orientation value. 1881d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1882d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static int getRotationForOrientationValue(short orientation) { 1883d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd switch (orientation) { 1884d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case Orientation.TOP_LEFT: 1885d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return 0; 1886d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case Orientation.RIGHT_TOP: 1887d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return 90; 1888d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case Orientation.BOTTOM_LEFT: 1889d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return 180; 1890d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case Orientation.RIGHT_BOTTOM: 1891d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return 270; 1892d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd default: 1893d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return 0; 1894d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1895d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1896d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1897d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static OrientationParams getOrientationParams(int orientation) { 1898d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd OrientationParams params = new OrientationParams(); 1899d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd switch (orientation) { 1900d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case Orientation.TOP_RIGHT: // Flip horizontal 1901d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.scaleX = -1; 1902d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 1903d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case Orientation.BOTTOM_RIGHT: // Flip vertical 1904d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.scaleY = -1; 1905d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 1906d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case Orientation.BOTTOM_LEFT: // Rotate 180 1907d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.rotation = 180; 1908d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 1909d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case Orientation.RIGHT_BOTTOM: // Rotate 270 1910d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.rotation = 270; 1911d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.invertDimensions = true; 1912d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 1913d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case Orientation.RIGHT_TOP: // Rotate 90 1914d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.rotation = 90; 1915d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.invertDimensions = true; 1916d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 1917d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case Orientation.LEFT_TOP: // Transpose 1918d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.rotation = 90; 1919d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.scaleX = -1; 1920d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.invertDimensions = true; 1921d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 1922d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case Orientation.LEFT_BOTTOM: // Transverse 1923d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.rotation = 270; 1924d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.scaleX = -1; 1925d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.invertDimensions = true; 1926d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 1927d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1928d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return params; 1929d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1930d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1931d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static class OrientationParams { 1932d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public int rotation = 0; 1933d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public int scaleX = 1; 1934d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public int scaleY = 1; 1935d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean invertDimensions = false; 1936d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1937d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1938d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1939d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Gets the double representation of the GPS latitude or longitude 1940d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * coordinate. 1941d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1942d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param coordinate an array of 3 Rationals representing the degrees, 1943d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * minutes, and seconds of the GPS location as defined in the 1944d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * exif specification. 1945d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param reference a GPS reference reperesented by a String containing "N", 1946d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * "S", "E", or "W". 1947d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the GPS coordinate represented as degrees + minutes/60 + 1948d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * seconds/3600 1949d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1950d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static double convertLatOrLongToDouble(Rational[] coordinate, String reference) { 1951d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 1952d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd double degrees = coordinate[0].toDouble(); 1953d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd double minutes = coordinate[1].toDouble(); 1954d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd double seconds = coordinate[2].toDouble(); 1955d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd double result = degrees + minutes / 60.0 + seconds / 3600.0; 1956d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if ((reference.equals("S") || reference.equals("W"))) { 1957d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return -result; 1958d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1959d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return result; 1960d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (ArrayIndexOutOfBoundsException e) { 1961d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw new IllegalArgumentException(); 1962d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1963d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1964d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1965d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1966d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Gets the GPS latitude and longitude as a pair of doubles from this 1967d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * ExifInterface object's tags, or null if the necessary tags do not exist. 1968d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1969d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return an array of 2 doubles containing the latitude, and longitude 1970d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * respectively. 1971d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @see #convertLatOrLongToDouble 1972d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 1973d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public double[] getLatLongAsDoubles() { 1974d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Rational[] latitude = getTagRationalValues(TAG_GPS_LATITUDE); 1975d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd String latitudeRef = getTagStringValue(TAG_GPS_LATITUDE_REF); 1976d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Rational[] longitude = getTagRationalValues(TAG_GPS_LONGITUDE); 1977d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd String longitudeRef = getTagStringValue(TAG_GPS_LONGITUDE_REF); 1978d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (latitude == null || longitude == null || latitudeRef == null || longitudeRef == null 1979d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd || latitude.length < 3 || longitude.length < 3) { 1980d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 1981d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1982d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd double[] latLon = new double[2]; 1983d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd latLon[0] = convertLatOrLongToDouble(latitude, latitudeRef); 1984d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd latLon[1] = convertLatOrLongToDouble(longitude, longitudeRef); 1985d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return latLon; 1986d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 1987d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1988d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String GPS_DATE_FORMAT_STR = "yyyy:MM:dd"; 1989d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String DATETIME_FORMAT_STR = "yyyy:MM:dd kk:mm:ss"; 1990d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private final DateFormat mDateTimeStampFormat = new SimpleDateFormat(DATETIME_FORMAT_STR); 1991d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private final DateFormat mGPSDateStampFormat = new SimpleDateFormat(GPS_DATE_FORMAT_STR); 1992d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private final Calendar mGPSTimeStampCalendar = Calendar 1993d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd .getInstance(TimeZone.getTimeZone("UTC")); 1994d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1995d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 1996d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Creates, formats, and sets the DateTimeStamp tag for one of: 1997d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * {@link #TAG_DATE_TIME}, {@link #TAG_DATE_TIME_DIGITIZED}, 1998d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * {@link #TAG_DATE_TIME_ORIGINAL}. 1999d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 2000d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param tagId one of the DateTimeStamp tags. 2001d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param timestamp a timestamp to format. 2002d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param timezone a TimeZone object. 2003d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return true if success, false if the tag could not be set. 2004d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 2005d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean addDateTimeStampTag(int tagId, long timestamp, TimeZone timezone) { 2006d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (tagId == TAG_DATE_TIME || tagId == TAG_DATE_TIME_DIGITIZED 2007d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd || tagId == TAG_DATE_TIME_ORIGINAL) { 2008d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mDateTimeStampFormat.setTimeZone(timezone); 2009d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ExifTag t = buildTag(tagId, mDateTimeStampFormat.format(timestamp)); 2010d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (t == null) { 2011d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 2012d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2013d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd setTag(t); 2014d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 2015d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 2016d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2017d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return true; 2018d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2019d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 2020d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 2021d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Creates and sets all to the GPS tags for a give latitude and longitude. 2022d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 2023d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param latitude a GPS latitude coordinate. 2024d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param longitude a GPS longitude coordinate. 2025d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return true if success, false if they could not be created or set. 2026d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 2027d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean addGpsTags(double latitude, double longitude) { 2028d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ExifTag latTag = buildTag(TAG_GPS_LATITUDE, toExifLatLong(latitude)); 2029d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ExifTag longTag = buildTag(TAG_GPS_LONGITUDE, toExifLatLong(longitude)); 2030d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ExifTag latRefTag = buildTag(TAG_GPS_LATITUDE_REF, 2031d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd latitude >= 0 ? GpsLatitudeRef.NORTH 2032d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd : GpsLatitudeRef.SOUTH); 2033d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ExifTag longRefTag = buildTag(TAG_GPS_LONGITUDE_REF, 2034d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd longitude >= 0 ? GpsLongitudeRef.EAST 2035d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd : GpsLongitudeRef.WEST); 2036d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (latTag == null || longTag == null || latRefTag == null || longRefTag == null) { 2037d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 2038d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2039d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd setTag(latTag); 2040d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd setTag(longTag); 2041d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd setTag(latRefTag); 2042d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd setTag(longRefTag); 2043d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return true; 2044d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2045d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 2046d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 2047d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Creates and sets the GPS timestamp tag. 2048d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 2049d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param timestamp a GPS timestamp. 2050d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return true if success, false if could not be created or set. 2051d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 2052d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean addGpsDateTimeStampTag(long timestamp) { 2053d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ExifTag t = buildTag(TAG_GPS_DATE_STAMP, mGPSDateStampFormat.format(timestamp)); 2054d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (t == null) { 2055d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 2056d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2057d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd setTag(t); 2058d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mGPSTimeStampCalendar.setTimeInMillis(timestamp); 2059d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd t = buildTag(TAG_GPS_TIME_STAMP, new Rational[] { 2060d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd new Rational(mGPSTimeStampCalendar.get(Calendar.HOUR_OF_DAY), 1), 2061d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd new Rational(mGPSTimeStampCalendar.get(Calendar.MINUTE), 1), 2062d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd new Rational(mGPSTimeStampCalendar.get(Calendar.SECOND), 1) 2063d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd }); 2064d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (t == null) { 2065d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 2066d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2067d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd setTag(t); 2068d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return true; 2069d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2070d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 2071d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static Rational[] toExifLatLong(double value) { 2072d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // convert to the format dd/1 mm/1 ssss/100 2073d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd value = Math.abs(value); 2074d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int degrees = (int) value; 2075d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd value = (value - degrees) * 60; 2076d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int minutes = (int) value; 2077d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd value = (value - minutes) * 6000; 2078d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int seconds = (int) value; 2079d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return new Rational[] { 2080d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd new Rational(degrees, 1), new Rational(minutes, 1), new Rational(seconds, 100) 2081d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd }; 2082d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2083d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 2084d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private void doExifStreamIO(InputStream is, OutputStream os) throws IOException { 2085d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd byte[] buf = new byte[1024]; 2086d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int ret = is.read(buf, 0, 1024); 2087d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd while (ret != -1) { 2088d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd os.write(buf, 0, ret); 2089d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ret = is.read(buf, 0, 1024); 2090d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2091d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2092d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 2093d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected static void closeSilently(Closeable c) { 2094d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (c != null) { 2095d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 2096d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd c.close(); 2097d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (Throwable e) { 2098d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // ignored 2099d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2100d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2101d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2102d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 2103d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private SparseIntArray mTagInfo = null; 2104d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 2105d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected SparseIntArray getTagInfo() { 2106d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (mTagInfo == null) { 2107d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo = new SparseIntArray(); 2108d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd initTagInfo(); 2109d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2110d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mTagInfo; 2111d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2112d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 2113d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private void initTagInfo() { 2114d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 2115d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * We put tag information in a 4-bytes integer. The first byte a bitmask 2116d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * representing the allowed IFDs of the tag, the second byte is the data 2117d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * type, and the last two byte are a short value indicating the default 2118d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * component count of this tag. 2119d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 2120d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // IFD0 tags 2121d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int[] ifdAllowedIfds = { 2122d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd IfdId.TYPE_IFD_0, IfdId.TYPE_IFD_1 2123d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd }; 2124d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int ifdFlags = getFlagsFromAllowedIfds(ifdAllowedIfds) << 24; 2125d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_MAKE, 2126d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED); 2127d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_IMAGE_WIDTH, 2128d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1); 2129d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_IMAGE_LENGTH, 2130d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1); 2131d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_BITS_PER_SAMPLE, 2132d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 3); 2133d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_COMPRESSION, 2134d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); 2135d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_PHOTOMETRIC_INTERPRETATION, 2136d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); 2137d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_ORIENTATION, ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 2138d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd | 1); 2139d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_SAMPLES_PER_PIXEL, 2140d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); 2141d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_PLANAR_CONFIGURATION, 2142d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); 2143d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_Y_CB_CR_SUB_SAMPLING, 2144d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 2); 2145d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_Y_CB_CR_POSITIONING, 2146d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); 2147d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_X_RESOLUTION, 2148d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); 2149d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_Y_RESOLUTION, 2150d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); 2151d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_RESOLUTION_UNIT, 2152d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); 2153d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_STRIP_OFFSETS, 2154d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_UNSIGNED_LONG << 16 | ExifTag.SIZE_UNDEFINED); 2155d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_ROWS_PER_STRIP, 2156d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1); 2157d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_STRIP_BYTE_COUNTS, 2158d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_UNSIGNED_LONG << 16 | ExifTag.SIZE_UNDEFINED); 2159d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_TRANSFER_FUNCTION, 2160d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 3 * 256); 2161d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_WHITE_POINT, 2162d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 2); 2163d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_PRIMARY_CHROMATICITIES, 2164d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 6); 2165d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_Y_CB_CR_COEFFICIENTS, 2166d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 3); 2167d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_REFERENCE_BLACK_WHITE, 2168d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 6); 2169d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_DATE_TIME, 2170d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_ASCII << 16 | 20); 2171d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_IMAGE_DESCRIPTION, 2172d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED); 2173d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_MAKE, 2174d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED); 2175d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_MODEL, 2176d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED); 2177d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_SOFTWARE, 2178d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED); 2179d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_ARTIST, 2180d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED); 2181d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_COPYRIGHT, 2182d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED); 2183d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_EXIF_IFD, 2184d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1); 2185d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_IFD, 2186d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1); 2187d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // IFD1 tags 2188d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int[] ifd1AllowedIfds = { 2189d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd IfdId.TYPE_IFD_1 2190d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd }; 2191d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int ifdFlags1 = getFlagsFromAllowedIfds(ifd1AllowedIfds) << 24; 2192d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT, 2193d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags1 | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1); 2194d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH, 2195d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ifdFlags1 | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1); 2196d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Exif tags 2197d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int[] exifAllowedIfds = { 2198d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd IfdId.TYPE_IFD_EXIF 2199d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd }; 2200d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int exifFlags = getFlagsFromAllowedIfds(exifAllowedIfds) << 24; 2201d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_EXIF_VERSION, 2202d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNDEFINED << 16 | 4); 2203d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_FLASHPIX_VERSION, 2204d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNDEFINED << 16 | 4); 2205d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_COLOR_SPACE, 2206d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); 2207d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_COMPONENTS_CONFIGURATION, 2208d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNDEFINED << 16 | 4); 2209d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_COMPRESSED_BITS_PER_PIXEL, 2210d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); 2211d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_PIXEL_X_DIMENSION, 2212d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1); 2213d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_PIXEL_Y_DIMENSION, 2214d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1); 2215d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_MAKER_NOTE, 2216d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNDEFINED << 16 | ExifTag.SIZE_UNDEFINED); 2217d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_USER_COMMENT, 2218d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNDEFINED << 16 | ExifTag.SIZE_UNDEFINED); 2219d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_RELATED_SOUND_FILE, 2220d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_ASCII << 16 | 13); 2221d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_DATE_TIME_ORIGINAL, 2222d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_ASCII << 16 | 20); 2223d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_DATE_TIME_DIGITIZED, 2224d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_ASCII << 16 | 20); 2225d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_SUB_SEC_TIME, 2226d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED); 2227d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_SUB_SEC_TIME_ORIGINAL, 2228d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED); 2229d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_SUB_SEC_TIME_DIGITIZED, 2230d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED); 2231d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_IMAGE_UNIQUE_ID, 2232d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_ASCII << 16 | 33); 2233d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_EXPOSURE_TIME, 2234d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); 2235d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_F_NUMBER, 2236d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); 2237d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_EXPOSURE_PROGRAM, 2238d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); 2239d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_SPECTRAL_SENSITIVITY, 2240d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED); 2241d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_ISO_SPEED_RATINGS, 2242d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | ExifTag.SIZE_UNDEFINED); 2243d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_OECF, 2244d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNDEFINED << 16 | ExifTag.SIZE_UNDEFINED); 2245d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_SHUTTER_SPEED_VALUE, 2246d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_RATIONAL << 16 | 1); 2247d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_APERTURE_VALUE, 2248d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); 2249d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_BRIGHTNESS_VALUE, 2250d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_RATIONAL << 16 | 1); 2251d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_EXPOSURE_BIAS_VALUE, 2252d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_RATIONAL << 16 | 1); 2253d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_MAX_APERTURE_VALUE, 2254d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); 2255d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_SUBJECT_DISTANCE, 2256d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); 2257d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_METERING_MODE, 2258d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); 2259d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_LIGHT_SOURCE, 2260d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); 2261d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_FLASH, 2262d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); 2263d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_FOCAL_LENGTH, 2264d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); 2265d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_SUBJECT_AREA, 2266d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | ExifTag.SIZE_UNDEFINED); 2267d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_FLASH_ENERGY, 2268d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); 2269d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_SPATIAL_FREQUENCY_RESPONSE, 2270d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNDEFINED << 16 | ExifTag.SIZE_UNDEFINED); 2271d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_FOCAL_PLANE_X_RESOLUTION, 2272d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); 2273d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_FOCAL_PLANE_Y_RESOLUTION, 2274d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); 2275d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_FOCAL_PLANE_RESOLUTION_UNIT, 2276d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); 2277d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_SUBJECT_LOCATION, 2278d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 2); 2279d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_EXPOSURE_INDEX, 2280d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); 2281d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_SENSING_METHOD, 2282d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); 2283d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_FILE_SOURCE, 2284d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNDEFINED << 16 | 1); 2285d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_SCENE_TYPE, 2286d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNDEFINED << 16 | 1); 2287d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_CFA_PATTERN, 2288d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNDEFINED << 16 | ExifTag.SIZE_UNDEFINED); 2289d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_CUSTOM_RENDERED, 2290d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); 2291d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_EXPOSURE_MODE, 2292d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); 2293d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_WHITE_BALANCE, 2294d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); 2295d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_DIGITAL_ZOOM_RATIO, 2296d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); 2297d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_FOCAL_LENGTH_IN_35_MM_FILE, 2298d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); 2299d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_SCENE_CAPTURE_TYPE, 2300d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); 2301d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GAIN_CONTROL, 2302d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); 2303d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_CONTRAST, 2304d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); 2305d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_SATURATION, 2306d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); 2307d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_SHARPNESS, 2308d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); 2309d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_DEVICE_SETTING_DESCRIPTION, 2310d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNDEFINED << 16 | ExifTag.SIZE_UNDEFINED); 2311d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_SUBJECT_DISTANCE_RANGE, 2312d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); 2313d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_INTEROPERABILITY_IFD, exifFlags 2314d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1); 2315d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // GPS tag 2316d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int[] gpsAllowedIfds = { 2317d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd IfdId.TYPE_IFD_GPS 2318d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd }; 2319d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int gpsFlags = getFlagsFromAllowedIfds(gpsAllowedIfds) << 24; 2320d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_VERSION_ID, 2321d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd gpsFlags | ExifTag.TYPE_UNSIGNED_BYTE << 16 | 4); 2322d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_LATITUDE_REF, 2323d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd gpsFlags | ExifTag.TYPE_ASCII << 16 | 2); 2324d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_LONGITUDE_REF, 2325d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd gpsFlags | ExifTag.TYPE_ASCII << 16 | 2); 2326d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_LATITUDE, 2327d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd gpsFlags | ExifTag.TYPE_RATIONAL << 16 | 3); 2328d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_LONGITUDE, 2329d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd gpsFlags | ExifTag.TYPE_RATIONAL << 16 | 3); 2330d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_ALTITUDE_REF, 2331d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd gpsFlags | ExifTag.TYPE_UNSIGNED_BYTE << 16 | 1); 2332d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_ALTITUDE, 2333d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd gpsFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); 2334d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_TIME_STAMP, 2335d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd gpsFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 3); 2336d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_SATTELLITES, 2337d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd gpsFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED); 2338d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_STATUS, 2339d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd gpsFlags | ExifTag.TYPE_ASCII << 16 | 2); 2340d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_MEASURE_MODE, 2341d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd gpsFlags | ExifTag.TYPE_ASCII << 16 | 2); 2342d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_DOP, 2343d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd gpsFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); 2344d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_SPEED_REF, 2345d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd gpsFlags | ExifTag.TYPE_ASCII << 16 | 2); 2346d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_SPEED, 2347d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd gpsFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); 2348d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_TRACK_REF, 2349d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd gpsFlags | ExifTag.TYPE_ASCII << 16 | 2); 2350d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_TRACK, 2351d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd gpsFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); 2352d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_IMG_DIRECTION_REF, 2353d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd gpsFlags | ExifTag.TYPE_ASCII << 16 | 2); 2354d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_IMG_DIRECTION, 2355d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd gpsFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); 2356d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_MAP_DATUM, 2357d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd gpsFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED); 2358d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_DEST_LATITUDE_REF, 2359d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd gpsFlags | ExifTag.TYPE_ASCII << 16 | 2); 2360d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_DEST_LATITUDE, 2361d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd gpsFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); 2362d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_DEST_BEARING_REF, 2363d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd gpsFlags | ExifTag.TYPE_ASCII << 16 | 2); 2364d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_DEST_BEARING, 2365d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd gpsFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); 2366d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_DEST_DISTANCE_REF, 2367d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd gpsFlags | ExifTag.TYPE_ASCII << 16 | 2); 2368d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_DEST_DISTANCE, 2369d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd gpsFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); 2370d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_PROCESSING_METHOD, 2371d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd gpsFlags | ExifTag.TYPE_UNDEFINED << 16 | ExifTag.SIZE_UNDEFINED); 2372d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_AREA_INFORMATION, 2373d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd gpsFlags | ExifTag.TYPE_UNDEFINED << 16 | ExifTag.SIZE_UNDEFINED); 2374d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_DATE_STAMP, 2375d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd gpsFlags | ExifTag.TYPE_ASCII << 16 | 11); 2376d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(ExifInterface.TAG_GPS_DIFFERENTIAL, 2377d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd gpsFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 11); 2378d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Interoperability tag 2379d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int[] interopAllowedIfds = { 2380d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd IfdId.TYPE_IFD_INTEROPERABILITY 2381d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd }; 2382d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int interopFlags = getFlagsFromAllowedIfds(interopAllowedIfds) << 24; 2383d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mTagInfo.put(TAG_INTEROPERABILITY_INDEX, interopFlags | ExifTag.TYPE_ASCII << 16 2384d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd | ExifTag.SIZE_UNDEFINED); 2385d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2386d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 2387d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected static int getAllowedIfdFlagsFromInfo(int info) { 2388d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return info >>> 24; 2389d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2390d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 2391d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected static int[] getAllowedIfdsFromInfo(int info) { 2392d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int ifdFlags = getAllowedIfdFlagsFromInfo(info); 2393d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int[] ifds = IfdData.getIfds(); 2394d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ArrayList<Integer> l = new ArrayList<Integer>(); 2395d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd for (int i = 0; i < IfdId.TYPE_IFD_COUNT; i++) { 2396d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int flag = (ifdFlags >> i) & 1; 2397d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (flag == 1) { 2398d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd l.add(ifds[i]); 2399d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2400d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2401d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (l.size() <= 0) { 2402d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 2403d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2404d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int[] ret = new int[l.size()]; 2405d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int j = 0; 2406d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd for (int i : l) { 2407d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ret[j++] = i; 2408d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2409d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return ret; 2410d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2411d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 2412d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected static boolean isIfdAllowed(int info, int ifd) { 2413d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int[] ifds = IfdData.getIfds(); 2414d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int ifdFlags = getAllowedIfdFlagsFromInfo(info); 2415d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd for (int i = 0; i < ifds.length; i++) { 2416d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (ifd == ifds[i] && ((ifdFlags >> i) & 1) == 1) { 2417d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return true; 2418d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2419d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2420d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 2421d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2422d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 2423d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected static int getFlagsFromAllowedIfds(int[] allowedIfds) { 2424d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (allowedIfds == null || allowedIfds.length == 0) { 2425d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return 0; 2426d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2427d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int flags = 0; 2428d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int[] ifds = IfdData.getIfds(); 2429d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd for (int i = 0; i < IfdId.TYPE_IFD_COUNT; i++) { 2430d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd for (int j : allowedIfds) { 2431d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (ifds[i] == j) { 2432d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd flags |= 1 << i; 2433d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 2434d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2435d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2436d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2437d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return flags; 2438d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2439d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 2440d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected static short getTypeFromInfo(int info) { 2441d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return (short) ((info >> 16) & 0x0ff); 2442d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2443d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 2444d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected static int getComponentCountFromInfo(int info) { 2445d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return info & 0x0ffff; 2446d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 2447d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 2448d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd} 2449