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