diff options
author | Michael Jurka <mikejurka@google.com> | 2013-12-11 15:41:28 +0100 |
---|---|---|
committer | Michael Jurka <mikejurka@google.com> | 2013-12-11 15:41:28 +0100 |
commit | 96749c13218aa1b783709dc82a4e16657ce9753f (patch) | |
tree | 328761f12d078f62ac8d7b296bbf6f39f5657da2 /src/com/android/gallery3d/exif/ExifInterface.java | |
parent | 1f60653abcc349127014e4f32232261dfc28b309 (diff) | |
download | android_packages_apps_Trebuchet-96749c13218aa1b783709dc82a4e16657ce9753f.tar.gz android_packages_apps_Trebuchet-96749c13218aa1b783709dc82a4e16657ce9753f.tar.bz2 android_packages_apps_Trebuchet-96749c13218aa1b783709dc82a4e16657ce9753f.zip |
Revert "Revert "Move wallpaper picker code to a separate directory""
This reverts commit 39de459a8621abfc91382ce7b4cdd37d09aaac12.
Diffstat (limited to 'src/com/android/gallery3d/exif/ExifInterface.java')
-rw-r--r-- | src/com/android/gallery3d/exif/ExifInterface.java | 2407 |
1 files changed, 0 insertions, 2407 deletions
diff --git a/src/com/android/gallery3d/exif/ExifInterface.java b/src/com/android/gallery3d/exif/ExifInterface.java deleted file mode 100644 index a1cf0fc85..000000000 --- a/src/com/android/gallery3d/exif/ExifInterface.java +++ /dev/null @@ -1,2407 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.gallery3d.exif; - -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.util.SparseIntArray; - -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.Closeable; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.RandomAccessFile; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.channels.FileChannel.MapMode; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.TimeZone; - -/** - * This class provides methods and constants for reading and writing jpeg file - * metadata. It contains a collection of ExifTags, and a collection of - * definitions for creating valid ExifTags. The collection of ExifTags can be - * updated by: reading new ones from a file, deleting or adding existing ones, - * or building new ExifTags from a tag definition. These ExifTags can be written - * to a valid jpeg image as exif metadata. - * <p> - * Each ExifTag has a tag ID (TID) and is stored in a specific image file - * directory (IFD) as specified by the exif standard. A tag definition can be - * looked up with a constant that is a combination of TID and IFD. This - * definition has information about the type, number of components, and valid - * IFDs for a tag. - * - * @see ExifTag - */ -public class ExifInterface { - public static final int TAG_NULL = -1; - public static final int IFD_NULL = -1; - public static final int DEFINITION_NULL = 0; - - /** - * Tag constants for Jeita EXIF 2.2 - */ - - // IFD 0 - public static final int TAG_IMAGE_WIDTH = - defineTag(IfdId.TYPE_IFD_0, (short) 0x0100); - public static final int TAG_IMAGE_LENGTH = - defineTag(IfdId.TYPE_IFD_0, (short) 0x0101); // Image height - public static final int TAG_BITS_PER_SAMPLE = - defineTag(IfdId.TYPE_IFD_0, (short) 0x0102); - public static final int TAG_COMPRESSION = - defineTag(IfdId.TYPE_IFD_0, (short) 0x0103); - public static final int TAG_PHOTOMETRIC_INTERPRETATION = - defineTag(IfdId.TYPE_IFD_0, (short) 0x0106); - public static final int TAG_IMAGE_DESCRIPTION = - defineTag(IfdId.TYPE_IFD_0, (short) 0x010E); - public static final int TAG_MAKE = - defineTag(IfdId.TYPE_IFD_0, (short) 0x010F); - public static final int TAG_MODEL = - defineTag(IfdId.TYPE_IFD_0, (short) 0x0110); - public static final int TAG_STRIP_OFFSETS = - defineTag(IfdId.TYPE_IFD_0, (short) 0x0111); - public static final int TAG_ORIENTATION = - defineTag(IfdId.TYPE_IFD_0, (short) 0x0112); - public static final int TAG_SAMPLES_PER_PIXEL = - defineTag(IfdId.TYPE_IFD_0, (short) 0x0115); - public static final int TAG_ROWS_PER_STRIP = - defineTag(IfdId.TYPE_IFD_0, (short) 0x0116); - public static final int TAG_STRIP_BYTE_COUNTS = - defineTag(IfdId.TYPE_IFD_0, (short) 0x0117); - public static final int TAG_X_RESOLUTION = - defineTag(IfdId.TYPE_IFD_0, (short) 0x011A); - public static final int TAG_Y_RESOLUTION = - defineTag(IfdId.TYPE_IFD_0, (short) 0x011B); - public static final int TAG_PLANAR_CONFIGURATION = - defineTag(IfdId.TYPE_IFD_0, (short) 0x011C); - public static final int TAG_RESOLUTION_UNIT = - defineTag(IfdId.TYPE_IFD_0, (short) 0x0128); - public static final int TAG_TRANSFER_FUNCTION = - defineTag(IfdId.TYPE_IFD_0, (short) 0x012D); - public static final int TAG_SOFTWARE = - defineTag(IfdId.TYPE_IFD_0, (short) 0x0131); - public static final int TAG_DATE_TIME = - defineTag(IfdId.TYPE_IFD_0, (short) 0x0132); - public static final int TAG_ARTIST = - defineTag(IfdId.TYPE_IFD_0, (short) 0x013B); - public static final int TAG_WHITE_POINT = - defineTag(IfdId.TYPE_IFD_0, (short) 0x013E); - public static final int TAG_PRIMARY_CHROMATICITIES = - defineTag(IfdId.TYPE_IFD_0, (short) 0x013F); - public static final int TAG_Y_CB_CR_COEFFICIENTS = - defineTag(IfdId.TYPE_IFD_0, (short) 0x0211); - public static final int TAG_Y_CB_CR_SUB_SAMPLING = - defineTag(IfdId.TYPE_IFD_0, (short) 0x0212); - public static final int TAG_Y_CB_CR_POSITIONING = - defineTag(IfdId.TYPE_IFD_0, (short) 0x0213); - public static final int TAG_REFERENCE_BLACK_WHITE = - defineTag(IfdId.TYPE_IFD_0, (short) 0x0214); - public static final int TAG_COPYRIGHT = - defineTag(IfdId.TYPE_IFD_0, (short) 0x8298); - public static final int TAG_EXIF_IFD = - defineTag(IfdId.TYPE_IFD_0, (short) 0x8769); - public static final int TAG_GPS_IFD = - defineTag(IfdId.TYPE_IFD_0, (short) 0x8825); - // IFD 1 - public static final int TAG_JPEG_INTERCHANGE_FORMAT = - defineTag(IfdId.TYPE_IFD_1, (short) 0x0201); - public static final int TAG_JPEG_INTERCHANGE_FORMAT_LENGTH = - defineTag(IfdId.TYPE_IFD_1, (short) 0x0202); - // IFD Exif Tags - public static final int TAG_EXPOSURE_TIME = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x829A); - public static final int TAG_F_NUMBER = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x829D); - public static final int TAG_EXPOSURE_PROGRAM = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x8822); - public static final int TAG_SPECTRAL_SENSITIVITY = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x8824); - public static final int TAG_ISO_SPEED_RATINGS = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x8827); - public static final int TAG_OECF = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x8828); - public static final int TAG_EXIF_VERSION = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9000); - public static final int TAG_DATE_TIME_ORIGINAL = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9003); - public static final int TAG_DATE_TIME_DIGITIZED = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9004); - public static final int TAG_COMPONENTS_CONFIGURATION = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9101); - public static final int TAG_COMPRESSED_BITS_PER_PIXEL = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9102); - public static final int TAG_SHUTTER_SPEED_VALUE = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9201); - public static final int TAG_APERTURE_VALUE = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9202); - public static final int TAG_BRIGHTNESS_VALUE = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9203); - public static final int TAG_EXPOSURE_BIAS_VALUE = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9204); - public static final int TAG_MAX_APERTURE_VALUE = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9205); - public static final int TAG_SUBJECT_DISTANCE = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9206); - public static final int TAG_METERING_MODE = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9207); - public static final int TAG_LIGHT_SOURCE = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9208); - public static final int TAG_FLASH = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9209); - public static final int TAG_FOCAL_LENGTH = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x920A); - public static final int TAG_SUBJECT_AREA = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9214); - public static final int TAG_MAKER_NOTE = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x927C); - public static final int TAG_USER_COMMENT = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9286); - public static final int TAG_SUB_SEC_TIME = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9290); - public static final int TAG_SUB_SEC_TIME_ORIGINAL = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9291); - public static final int TAG_SUB_SEC_TIME_DIGITIZED = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9292); - public static final int TAG_FLASHPIX_VERSION = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA000); - public static final int TAG_COLOR_SPACE = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA001); - public static final int TAG_PIXEL_X_DIMENSION = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA002); - public static final int TAG_PIXEL_Y_DIMENSION = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA003); - public static final int TAG_RELATED_SOUND_FILE = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA004); - public static final int TAG_INTEROPERABILITY_IFD = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA005); - public static final int TAG_FLASH_ENERGY = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA20B); - public static final int TAG_SPATIAL_FREQUENCY_RESPONSE = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA20C); - public static final int TAG_FOCAL_PLANE_X_RESOLUTION = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA20E); - public static final int TAG_FOCAL_PLANE_Y_RESOLUTION = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA20F); - public static final int TAG_FOCAL_PLANE_RESOLUTION_UNIT = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA210); - public static final int TAG_SUBJECT_LOCATION = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA214); - public static final int TAG_EXPOSURE_INDEX = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA215); - public static final int TAG_SENSING_METHOD = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA217); - public static final int TAG_FILE_SOURCE = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA300); - public static final int TAG_SCENE_TYPE = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA301); - public static final int TAG_CFA_PATTERN = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA302); - public static final int TAG_CUSTOM_RENDERED = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA401); - public static final int TAG_EXPOSURE_MODE = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA402); - public static final int TAG_WHITE_BALANCE = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA403); - public static final int TAG_DIGITAL_ZOOM_RATIO = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA404); - public static final int TAG_FOCAL_LENGTH_IN_35_MM_FILE = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA405); - public static final int TAG_SCENE_CAPTURE_TYPE = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA406); - public static final int TAG_GAIN_CONTROL = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA407); - public static final int TAG_CONTRAST = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA408); - public static final int TAG_SATURATION = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA409); - public static final int TAG_SHARPNESS = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA40A); - public static final int TAG_DEVICE_SETTING_DESCRIPTION = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA40B); - public static final int TAG_SUBJECT_DISTANCE_RANGE = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA40C); - public static final int TAG_IMAGE_UNIQUE_ID = - defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA420); - // IFD GPS tags - public static final int TAG_GPS_VERSION_ID = - defineTag(IfdId.TYPE_IFD_GPS, (short) 0); - public static final int TAG_GPS_LATITUDE_REF = - defineTag(IfdId.TYPE_IFD_GPS, (short) 1); - public static final int TAG_GPS_LATITUDE = - defineTag(IfdId.TYPE_IFD_GPS, (short) 2); - public static final int TAG_GPS_LONGITUDE_REF = - defineTag(IfdId.TYPE_IFD_GPS, (short) 3); - public static final int TAG_GPS_LONGITUDE = - defineTag(IfdId.TYPE_IFD_GPS, (short) 4); - public static final int TAG_GPS_ALTITUDE_REF = - defineTag(IfdId.TYPE_IFD_GPS, (short) 5); - public static final int TAG_GPS_ALTITUDE = - defineTag(IfdId.TYPE_IFD_GPS, (short) 6); - public static final int TAG_GPS_TIME_STAMP = - defineTag(IfdId.TYPE_IFD_GPS, (short) 7); - public static final int TAG_GPS_SATTELLITES = - defineTag(IfdId.TYPE_IFD_GPS, (short) 8); - public static final int TAG_GPS_STATUS = - defineTag(IfdId.TYPE_IFD_GPS, (short) 9); - public static final int TAG_GPS_MEASURE_MODE = - defineTag(IfdId.TYPE_IFD_GPS, (short) 10); - public static final int TAG_GPS_DOP = - defineTag(IfdId.TYPE_IFD_GPS, (short) 11); - public static final int TAG_GPS_SPEED_REF = - defineTag(IfdId.TYPE_IFD_GPS, (short) 12); - public static final int TAG_GPS_SPEED = - defineTag(IfdId.TYPE_IFD_GPS, (short) 13); - public static final int TAG_GPS_TRACK_REF = - defineTag(IfdId.TYPE_IFD_GPS, (short) 14); - public static final int TAG_GPS_TRACK = - defineTag(IfdId.TYPE_IFD_GPS, (short) 15); - public static final int TAG_GPS_IMG_DIRECTION_REF = - defineTag(IfdId.TYPE_IFD_GPS, (short) 16); - public static final int TAG_GPS_IMG_DIRECTION = - defineTag(IfdId.TYPE_IFD_GPS, (short) 17); - public static final int TAG_GPS_MAP_DATUM = - defineTag(IfdId.TYPE_IFD_GPS, (short) 18); - public static final int TAG_GPS_DEST_LATITUDE_REF = - defineTag(IfdId.TYPE_IFD_GPS, (short) 19); - public static final int TAG_GPS_DEST_LATITUDE = - defineTag(IfdId.TYPE_IFD_GPS, (short) 20); - public static final int TAG_GPS_DEST_LONGITUDE_REF = - defineTag(IfdId.TYPE_IFD_GPS, (short) 21); - public static final int TAG_GPS_DEST_LONGITUDE = - defineTag(IfdId.TYPE_IFD_GPS, (short) 22); - public static final int TAG_GPS_DEST_BEARING_REF = - defineTag(IfdId.TYPE_IFD_GPS, (short) 23); - public static final int TAG_GPS_DEST_BEARING = - defineTag(IfdId.TYPE_IFD_GPS, (short) 24); - public static final int TAG_GPS_DEST_DISTANCE_REF = - defineTag(IfdId.TYPE_IFD_GPS, (short) 25); - public static final int TAG_GPS_DEST_DISTANCE = - defineTag(IfdId.TYPE_IFD_GPS, (short) 26); - public static final int TAG_GPS_PROCESSING_METHOD = - defineTag(IfdId.TYPE_IFD_GPS, (short) 27); - public static final int TAG_GPS_AREA_INFORMATION = - defineTag(IfdId.TYPE_IFD_GPS, (short) 28); - public static final int TAG_GPS_DATE_STAMP = - defineTag(IfdId.TYPE_IFD_GPS, (short) 29); - public static final int TAG_GPS_DIFFERENTIAL = - defineTag(IfdId.TYPE_IFD_GPS, (short) 30); - // IFD Interoperability tags - public static final int TAG_INTEROPERABILITY_INDEX = - defineTag(IfdId.TYPE_IFD_INTEROPERABILITY, (short) 1); - - /** - * Tags that contain offset markers. These are included in the banned - * defines. - */ - private static HashSet<Short> sOffsetTags = new HashSet<Short>(); - static { - sOffsetTags.add(getTrueTagKey(TAG_GPS_IFD)); - sOffsetTags.add(getTrueTagKey(TAG_EXIF_IFD)); - sOffsetTags.add(getTrueTagKey(TAG_JPEG_INTERCHANGE_FORMAT)); - sOffsetTags.add(getTrueTagKey(TAG_INTEROPERABILITY_IFD)); - sOffsetTags.add(getTrueTagKey(TAG_STRIP_OFFSETS)); - } - - /** - * Tags with definitions that cannot be overridden (banned defines). - */ - protected static HashSet<Short> sBannedDefines = new HashSet<Short>(sOffsetTags); - static { - sBannedDefines.add(getTrueTagKey(TAG_NULL)); - sBannedDefines.add(getTrueTagKey(TAG_JPEG_INTERCHANGE_FORMAT_LENGTH)); - sBannedDefines.add(getTrueTagKey(TAG_STRIP_BYTE_COUNTS)); - } - - /** - * Returns the constant representing a tag with a given TID and default IFD. - */ - public static int defineTag(int ifdId, short tagId) { - return (tagId & 0x0000ffff) | (ifdId << 16); - } - - /** - * Returns the TID for a tag constant. - */ - public static short getTrueTagKey(int tag) { - // Truncate - return (short) tag; - } - - /** - * Returns the default IFD for a tag constant. - */ - public static int getTrueIfd(int tag) { - return tag >>> 16; - } - - /** - * Constants for {@link TAG_ORIENTATION}. They can be interpreted as - * follows: - * <ul> - * <li>TOP_LEFT is the normal orientation.</li> - * <li>TOP_RIGHT is a left-right mirror.</li> - * <li>BOTTOM_LEFT is a 180 degree rotation.</li> - * <li>BOTTOM_RIGHT is a top-bottom mirror.</li> - * <li>LEFT_TOP is mirrored about the top-left<->bottom-right axis.</li> - * <li>RIGHT_TOP is a 90 degree clockwise rotation.</li> - * <li>LEFT_BOTTOM is mirrored about the top-right<->bottom-left axis.</li> - * <li>RIGHT_BOTTOM is a 270 degree clockwise rotation.</li> - * </ul> - */ - public static interface Orientation { - public static final short TOP_LEFT = 1; - public static final short TOP_RIGHT = 2; - public static final short BOTTOM_LEFT = 3; - public static final short BOTTOM_RIGHT = 4; - public static final short LEFT_TOP = 5; - public static final short RIGHT_TOP = 6; - public static final short LEFT_BOTTOM = 7; - public static final short RIGHT_BOTTOM = 8; - } - - /** - * Constants for {@link TAG_Y_CB_CR_POSITIONING} - */ - public static interface YCbCrPositioning { - public static final short CENTERED = 1; - public static final short CO_SITED = 2; - } - - /** - * Constants for {@link TAG_COMPRESSION} - */ - public static interface Compression { - public static final short UNCOMPRESSION = 1; - public static final short JPEG = 6; - } - - /** - * Constants for {@link TAG_RESOLUTION_UNIT} - */ - public static interface ResolutionUnit { - public static final short INCHES = 2; - public static final short CENTIMETERS = 3; - } - - /** - * Constants for {@link TAG_PHOTOMETRIC_INTERPRETATION} - */ - public static interface PhotometricInterpretation { - public static final short RGB = 2; - public static final short YCBCR = 6; - } - - /** - * Constants for {@link TAG_PLANAR_CONFIGURATION} - */ - public static interface PlanarConfiguration { - public static final short CHUNKY = 1; - public static final short PLANAR = 2; - } - - /** - * Constants for {@link TAG_EXPOSURE_PROGRAM} - */ - public static interface ExposureProgram { - public static final short NOT_DEFINED = 0; - public static final short MANUAL = 1; - public static final short NORMAL_PROGRAM = 2; - public static final short APERTURE_PRIORITY = 3; - public static final short SHUTTER_PRIORITY = 4; - public static final short CREATIVE_PROGRAM = 5; - public static final short ACTION_PROGRAM = 6; - public static final short PROTRAIT_MODE = 7; - public static final short LANDSCAPE_MODE = 8; - } - - /** - * Constants for {@link TAG_METERING_MODE} - */ - public static interface MeteringMode { - public static final short UNKNOWN = 0; - public static final short AVERAGE = 1; - public static final short CENTER_WEIGHTED_AVERAGE = 2; - public static final short SPOT = 3; - public static final short MULTISPOT = 4; - public static final short PATTERN = 5; - public static final short PARTAIL = 6; - public static final short OTHER = 255; - } - - /** - * Constants for {@link TAG_FLASH} As the definition in Jeita EXIF 2.2 - * standard, we can treat this constant as bitwise flag. - * <p> - * e.g. - * <p> - * short flash = FIRED | RETURN_STROBE_RETURN_LIGHT_DETECTED | - * MODE_AUTO_MODE - */ - public static interface Flash { - // LSB - public static final short DID_NOT_FIRED = 0; - public static final short FIRED = 1; - // 1st~2nd bits - public static final short RETURN_NO_STROBE_RETURN_DETECTION_FUNCTION = 0 << 1; - public static final short RETURN_STROBE_RETURN_LIGHT_NOT_DETECTED = 2 << 1; - public static final short RETURN_STROBE_RETURN_LIGHT_DETECTED = 3 << 1; - // 3rd~4th bits - public static final short MODE_UNKNOWN = 0 << 3; - public static final short MODE_COMPULSORY_FLASH_FIRING = 1 << 3; - public static final short MODE_COMPULSORY_FLASH_SUPPRESSION = 2 << 3; - public static final short MODE_AUTO_MODE = 3 << 3; - // 5th bit - public static final short FUNCTION_PRESENT = 0 << 5; - public static final short FUNCTION_NO_FUNCTION = 1 << 5; - // 6th bit - public static final short RED_EYE_REDUCTION_NO_OR_UNKNOWN = 0 << 6; - public static final short RED_EYE_REDUCTION_SUPPORT = 1 << 6; - } - - /** - * Constants for {@link TAG_COLOR_SPACE} - */ - public static interface ColorSpace { - public static final short SRGB = 1; - public static final short UNCALIBRATED = (short) 0xFFFF; - } - - /** - * Constants for {@link TAG_EXPOSURE_MODE} - */ - public static interface ExposureMode { - public static final short AUTO_EXPOSURE = 0; - public static final short MANUAL_EXPOSURE = 1; - public static final short AUTO_BRACKET = 2; - } - - /** - * Constants for {@link TAG_WHITE_BALANCE} - */ - public static interface WhiteBalance { - public static final short AUTO = 0; - public static final short MANUAL = 1; - } - - /** - * Constants for {@link TAG_SCENE_CAPTURE_TYPE} - */ - public static interface SceneCapture { - public static final short STANDARD = 0; - public static final short LANDSCAPE = 1; - public static final short PROTRAIT = 2; - public static final short NIGHT_SCENE = 3; - } - - /** - * Constants for {@link TAG_COMPONENTS_CONFIGURATION} - */ - public static interface ComponentsConfiguration { - public static final short NOT_EXIST = 0; - public static final short Y = 1; - public static final short CB = 2; - public static final short CR = 3; - public static final short R = 4; - public static final short G = 5; - public static final short B = 6; - } - - /** - * Constants for {@link TAG_LIGHT_SOURCE} - */ - public static interface LightSource { - public static final short UNKNOWN = 0; - public static final short DAYLIGHT = 1; - public static final short FLUORESCENT = 2; - public static final short TUNGSTEN = 3; - public static final short FLASH = 4; - public static final short FINE_WEATHER = 9; - public static final short CLOUDY_WEATHER = 10; - public static final short SHADE = 11; - public static final short DAYLIGHT_FLUORESCENT = 12; - public static final short DAY_WHITE_FLUORESCENT = 13; - public static final short COOL_WHITE_FLUORESCENT = 14; - public static final short WHITE_FLUORESCENT = 15; - public static final short STANDARD_LIGHT_A = 17; - public static final short STANDARD_LIGHT_B = 18; - public static final short STANDARD_LIGHT_C = 19; - public static final short D55 = 20; - public static final short D65 = 21; - public static final short D75 = 22; - public static final short D50 = 23; - public static final short ISO_STUDIO_TUNGSTEN = 24; - public static final short OTHER = 255; - } - - /** - * Constants for {@link TAG_SENSING_METHOD} - */ - public static interface SensingMethod { - public static final short NOT_DEFINED = 1; - public static final short ONE_CHIP_COLOR = 2; - public static final short TWO_CHIP_COLOR = 3; - public static final short THREE_CHIP_COLOR = 4; - public static final short COLOR_SEQUENTIAL_AREA = 5; - public static final short TRILINEAR = 7; - public static final short COLOR_SEQUENTIAL_LINEAR = 8; - } - - /** - * Constants for {@link TAG_FILE_SOURCE} - */ - public static interface FileSource { - public static final short DSC = 3; - } - - /** - * Constants for {@link TAG_SCENE_TYPE} - */ - public static interface SceneType { - public static final short DIRECT_PHOTOGRAPHED = 1; - } - - /** - * Constants for {@link TAG_GAIN_CONTROL} - */ - public static interface GainControl { - public static final short NONE = 0; - public static final short LOW_UP = 1; - public static final short HIGH_UP = 2; - public static final short LOW_DOWN = 3; - public static final short HIGH_DOWN = 4; - } - - /** - * Constants for {@link TAG_CONTRAST} - */ - public static interface Contrast { - public static final short NORMAL = 0; - public static final short SOFT = 1; - public static final short HARD = 2; - } - - /** - * Constants for {@link TAG_SATURATION} - */ - public static interface Saturation { - public static final short NORMAL = 0; - public static final short LOW = 1; - public static final short HIGH = 2; - } - - /** - * Constants for {@link TAG_SHARPNESS} - */ - public static interface Sharpness { - public static final short NORMAL = 0; - public static final short SOFT = 1; - public static final short HARD = 2; - } - - /** - * Constants for {@link TAG_SUBJECT_DISTANCE} - */ - public static interface SubjectDistance { - public static final short UNKNOWN = 0; - public static final short MACRO = 1; - public static final short CLOSE_VIEW = 2; - public static final short DISTANT_VIEW = 3; - } - - /** - * Constants for {@link TAG_GPS_LATITUDE_REF}, - * {@link TAG_GPS_DEST_LATITUDE_REF} - */ - public static interface GpsLatitudeRef { - public static final String NORTH = "N"; - public static final String SOUTH = "S"; - } - - /** - * Constants for {@link TAG_GPS_LONGITUDE_REF}, - * {@link TAG_GPS_DEST_LONGITUDE_REF} - */ - public static interface GpsLongitudeRef { - public static final String EAST = "E"; - public static final String WEST = "W"; - } - - /** - * Constants for {@link TAG_GPS_ALTITUDE_REF} - */ - public static interface GpsAltitudeRef { - public static final short SEA_LEVEL = 0; - public static final short SEA_LEVEL_NEGATIVE = 1; - } - - /** - * Constants for {@link TAG_GPS_STATUS} - */ - public static interface GpsStatus { - public static final String IN_PROGRESS = "A"; - public static final String INTEROPERABILITY = "V"; - } - - /** - * Constants for {@link TAG_GPS_MEASURE_MODE} - */ - public static interface GpsMeasureMode { - public static final String MODE_2_DIMENSIONAL = "2"; - public static final String MODE_3_DIMENSIONAL = "3"; - } - - /** - * Constants for {@link TAG_GPS_SPEED_REF}, - * {@link TAG_GPS_DEST_DISTANCE_REF} - */ - public static interface GpsSpeedRef { - public static final String KILOMETERS = "K"; - public static final String MILES = "M"; - public static final String KNOTS = "N"; - } - - /** - * Constants for {@link TAG_GPS_TRACK_REF}, - * {@link TAG_GPS_IMG_DIRECTION_REF}, {@link TAG_GPS_DEST_BEARING_REF} - */ - public static interface GpsTrackRef { - public static final String TRUE_DIRECTION = "T"; - public static final String MAGNETIC_DIRECTION = "M"; - } - - /** - * Constants for {@link TAG_GPS_DIFFERENTIAL} - */ - public static interface GpsDifferential { - public static final short WITHOUT_DIFFERENTIAL_CORRECTION = 0; - public static final short DIFFERENTIAL_CORRECTION_APPLIED = 1; - } - - private static final String NULL_ARGUMENT_STRING = "Argument is null"; - private ExifData mData = new ExifData(DEFAULT_BYTE_ORDER); - public static final ByteOrder DEFAULT_BYTE_ORDER = ByteOrder.BIG_ENDIAN; - - public ExifInterface() { - mGPSDateStampFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - } - - /** - * Reads the exif tags from a byte array, clearing this ExifInterface - * object's existing exif tags. - * - * @param jpeg a byte array containing a jpeg compressed image. - * @throws IOException - */ - public void readExif(byte[] jpeg) throws IOException { - readExif(new ByteArrayInputStream(jpeg)); - } - - /** - * Reads the exif tags from an InputStream, clearing this ExifInterface - * object's existing exif tags. - * - * @param inStream an InputStream containing a jpeg compressed image. - * @throws IOException - */ - public void readExif(InputStream inStream) throws IOException { - if (inStream == null) { - throw new IllegalArgumentException(NULL_ARGUMENT_STRING); - } - ExifData d = null; - try { - d = new ExifReader(this).read(inStream); - } catch (ExifInvalidFormatException e) { - throw new IOException("Invalid exif format : " + e); - } - mData = d; - } - - /** - * Reads the exif tags from a file, clearing this ExifInterface object's - * existing exif tags. - * - * @param inFileName a string representing the filepath to jpeg file. - * @throws FileNotFoundException - * @throws IOException - */ - public void readExif(String inFileName) throws FileNotFoundException, IOException { - if (inFileName == null) { - throw new IllegalArgumentException(NULL_ARGUMENT_STRING); - } - InputStream is = null; - try { - is = (InputStream) new BufferedInputStream(new FileInputStream(inFileName)); - readExif(is); - } catch (IOException e) { - closeSilently(is); - throw e; - } - is.close(); - } - - /** - * Sets the exif tags, clearing this ExifInterface object's existing exif - * tags. - * - * @param tags a collection of exif tags to set. - */ - public void setExif(Collection<ExifTag> tags) { - clearExif(); - setTags(tags); - } - - /** - * Clears this ExifInterface object's existing exif tags. - */ - public void clearExif() { - mData = new ExifData(DEFAULT_BYTE_ORDER); - } - - /** - * Writes the tags from this ExifInterface object into a jpeg image, - * removing prior exif tags. - * - * @param jpeg a byte array containing a jpeg compressed image. - * @param exifOutStream an OutputStream to which the jpeg image with added - * exif tags will be written. - * @throws IOException - */ - public void writeExif(byte[] jpeg, OutputStream exifOutStream) throws IOException { - if (jpeg == null || exifOutStream == null) { - throw new IllegalArgumentException(NULL_ARGUMENT_STRING); - } - OutputStream s = getExifWriterStream(exifOutStream); - s.write(jpeg, 0, jpeg.length); - s.flush(); - } - - /** - * Writes the tags from this ExifInterface object into a jpeg compressed - * bitmap, removing prior exif tags. - * - * @param bmap a bitmap to compress and write exif into. - * @param exifOutStream the OutputStream to which the jpeg image with added - * exif tags will be written. - * @throws IOException - */ - public void writeExif(Bitmap bmap, OutputStream exifOutStream) throws IOException { - if (bmap == null || exifOutStream == null) { - throw new IllegalArgumentException(NULL_ARGUMENT_STRING); - } - OutputStream s = getExifWriterStream(exifOutStream); - bmap.compress(Bitmap.CompressFormat.JPEG, 90, s); - s.flush(); - } - - /** - * Writes the tags from this ExifInterface object into a jpeg stream, - * removing prior exif tags. - * - * @param jpegStream an InputStream containing a jpeg compressed image. - * @param exifOutStream an OutputStream to which the jpeg image with added - * exif tags will be written. - * @throws IOException - */ - public void writeExif(InputStream jpegStream, OutputStream exifOutStream) throws IOException { - if (jpegStream == null || exifOutStream == null) { - throw new IllegalArgumentException(NULL_ARGUMENT_STRING); - } - OutputStream s = getExifWriterStream(exifOutStream); - doExifStreamIO(jpegStream, s); - s.flush(); - } - - /** - * Writes the tags from this ExifInterface object into a jpeg image, - * removing prior exif tags. - * - * @param jpeg a byte array containing a jpeg compressed image. - * @param exifOutFileName a String containing the filepath to which the jpeg - * image with added exif tags will be written. - * @throws FileNotFoundException - * @throws IOException - */ - public void writeExif(byte[] jpeg, String exifOutFileName) throws FileNotFoundException, - IOException { - if (jpeg == null || exifOutFileName == null) { - throw new IllegalArgumentException(NULL_ARGUMENT_STRING); - } - OutputStream s = null; - try { - s = getExifWriterStream(exifOutFileName); - s.write(jpeg, 0, jpeg.length); - s.flush(); - } catch (IOException e) { - closeSilently(s); - throw e; - } - s.close(); - } - - /** - * Writes the tags from this ExifInterface object into a jpeg compressed - * bitmap, removing prior exif tags. - * - * @param bmap a bitmap to compress and write exif into. - * @param exifOutFileName a String containing the filepath to which the jpeg - * image with added exif tags will be written. - * @throws FileNotFoundException - * @throws IOException - */ - public void writeExif(Bitmap bmap, String exifOutFileName) throws FileNotFoundException, - IOException { - if (bmap == null || exifOutFileName == null) { - throw new IllegalArgumentException(NULL_ARGUMENT_STRING); - } - OutputStream s = null; - try { - s = getExifWriterStream(exifOutFileName); - bmap.compress(Bitmap.CompressFormat.JPEG, 90, s); - s.flush(); - } catch (IOException e) { - closeSilently(s); - throw e; - } - s.close(); - } - - /** - * Writes the tags from this ExifInterface object into a jpeg stream, - * removing prior exif tags. - * - * @param jpegStream an InputStream containing a jpeg compressed image. - * @param exifOutFileName a String containing the filepath to which the jpeg - * image with added exif tags will be written. - * @throws FileNotFoundException - * @throws IOException - */ - public void writeExif(InputStream jpegStream, String exifOutFileName) - throws FileNotFoundException, IOException { - if (jpegStream == null || exifOutFileName == null) { - throw new IllegalArgumentException(NULL_ARGUMENT_STRING); - } - OutputStream s = null; - try { - s = getExifWriterStream(exifOutFileName); - doExifStreamIO(jpegStream, s); - s.flush(); - } catch (IOException e) { - closeSilently(s); - throw e; - } - s.close(); - } - - /** - * Writes the tags from this ExifInterface object into a jpeg file, removing - * prior exif tags. - * - * @param jpegFileName a String containing the filepath for a jpeg file. - * @param exifOutFileName a String containing the filepath to which the jpeg - * image with added exif tags will be written. - * @throws FileNotFoundException - * @throws IOException - */ - public void writeExif(String jpegFileName, String exifOutFileName) - throws FileNotFoundException, IOException { - if (jpegFileName == null || exifOutFileName == null) { - throw new IllegalArgumentException(NULL_ARGUMENT_STRING); - } - InputStream is = null; - try { - is = new FileInputStream(jpegFileName); - writeExif(is, exifOutFileName); - } catch (IOException e) { - closeSilently(is); - throw e; - } - is.close(); - } - - /** - * Wraps an OutputStream object with an ExifOutputStream. Exif tags in this - * ExifInterface object will be added to a jpeg image written to this - * stream, removing prior exif tags. Other methods of this ExifInterface - * object should not be called until the returned OutputStream has been - * closed. - * - * @param outStream an OutputStream to wrap. - * @return an OutputStream that wraps the outStream parameter, and adds exif - * metadata. A jpeg image should be written to this stream. - */ - public OutputStream getExifWriterStream(OutputStream outStream) { - if (outStream == null) { - throw new IllegalArgumentException(NULL_ARGUMENT_STRING); - } - ExifOutputStream eos = new ExifOutputStream(outStream, this); - eos.setExifData(mData); - return eos; - } - - /** - * Returns an OutputStream object that writes to a file. Exif tags in this - * ExifInterface object will be added to a jpeg image written to this - * stream, removing prior exif tags. Other methods of this ExifInterface - * object should not be called until the returned OutputStream has been - * closed. - * - * @param exifOutFileName an String containing a filepath for a jpeg file. - * @return an OutputStream that writes to the exifOutFileName file, and adds - * exif metadata. A jpeg image should be written to this stream. - * @throws FileNotFoundException - */ - public OutputStream getExifWriterStream(String exifOutFileName) throws FileNotFoundException { - if (exifOutFileName == null) { - throw new IllegalArgumentException(NULL_ARGUMENT_STRING); - } - OutputStream out = null; - try { - out = (OutputStream) new FileOutputStream(exifOutFileName); - } catch (FileNotFoundException e) { - closeSilently(out); - throw e; - } - return getExifWriterStream(out); - } - - /** - * Attempts to do an in-place rewrite the exif metadata in a file for the - * given tags. If tags do not exist or do not have the same size as the - * existing exif tags, this method will fail. - * - * @param filename a String containing a filepath for a jpeg file with exif - * tags to rewrite. - * @param tags tags that will be written into the jpeg file over existing - * tags if possible. - * @return true if success, false if could not overwrite. If false, no - * changes are made to the file. - * @throws FileNotFoundException - * @throws IOException - */ - public boolean rewriteExif(String filename, Collection<ExifTag> tags) - throws FileNotFoundException, IOException { - RandomAccessFile file = null; - InputStream is = null; - boolean ret; - try { - File temp = new File(filename); - is = new BufferedInputStream(new FileInputStream(temp)); - - // Parse beginning of APP1 in exif to find size of exif header. - ExifParser parser = null; - try { - parser = ExifParser.parse(is, this); - } catch (ExifInvalidFormatException e) { - throw new IOException("Invalid exif format : ", e); - } - long exifSize = parser.getOffsetToExifEndFromSOF(); - - // Free up resources - is.close(); - is = null; - - // Open file for memory mapping. - file = new RandomAccessFile(temp, "rw"); - long fileLength = file.length(); - if (fileLength < exifSize) { - throw new IOException("Filesize changed during operation"); - } - - // Map only exif header into memory. - ByteBuffer buf = file.getChannel().map(MapMode.READ_WRITE, 0, exifSize); - - // Attempt to overwrite tag values without changing lengths (avoids - // file copy). - ret = rewriteExif(buf, tags); - } catch (IOException e) { - closeSilently(file); - throw e; - } finally { - closeSilently(is); - } - file.close(); - return ret; - } - - /** - * Attempts to do an in-place rewrite the exif metadata in a ByteBuffer for - * the given tags. If tags do not exist or do not have the same size as the - * existing exif tags, this method will fail. - * - * @param buf a ByteBuffer containing a jpeg file with existing exif tags to - * rewrite. - * @param tags tags that will be written into the jpeg ByteBuffer over - * existing tags if possible. - * @return true if success, false if could not overwrite. If false, no - * changes are made to the ByteBuffer. - * @throws IOException - */ - public boolean rewriteExif(ByteBuffer buf, Collection<ExifTag> tags) throws IOException { - ExifModifier mod = null; - try { - mod = new ExifModifier(buf, this); - for (ExifTag t : tags) { - mod.modifyTag(t); - } - return mod.commit(); - } catch (ExifInvalidFormatException e) { - throw new IOException("Invalid exif format : " + e); - } - } - - /** - * Attempts to do an in-place rewrite of the exif metadata. If this fails, - * fall back to overwriting file. This preserves tags that are not being - * rewritten. - * - * @param filename a String containing a filepath for a jpeg file. - * @param tags tags that will be written into the jpeg file over existing - * tags if possible. - * @throws FileNotFoundException - * @throws IOException - * @see #rewriteExif - */ - public void forceRewriteExif(String filename, Collection<ExifTag> tags) - throws FileNotFoundException, - IOException { - // Attempt in-place write - if (!rewriteExif(filename, tags)) { - // Fall back to doing a copy - ExifData tempData = mData; - mData = new ExifData(DEFAULT_BYTE_ORDER); - FileInputStream is = null; - ByteArrayOutputStream bytes = null; - try { - is = new FileInputStream(filename); - bytes = new ByteArrayOutputStream(); - doExifStreamIO(is, bytes); - byte[] imageBytes = bytes.toByteArray(); - readExif(imageBytes); - setTags(tags); - writeExif(imageBytes, filename); - } catch (IOException e) { - closeSilently(is); - throw e; - } finally { - is.close(); - // Prevent clobbering of mData - mData = tempData; - } - } - } - - /** - * Attempts to do an in-place rewrite of the exif metadata using the tags in - * this ExifInterface object. If this fails, fall back to overwriting file. - * This preserves tags that are not being rewritten. - * - * @param filename a String containing a filepath for a jpeg file. - * @throws FileNotFoundException - * @throws IOException - * @see #rewriteExif - */ - public void forceRewriteExif(String filename) throws FileNotFoundException, IOException { - forceRewriteExif(filename, getAllTags()); - } - - /** - * Get the exif tags in this ExifInterface object or null if none exist. - * - * @return a List of {@link ExifTag}s. - */ - public List<ExifTag> getAllTags() { - return mData.getAllTags(); - } - - /** - * Returns a list of ExifTags that share a TID (which can be obtained by - * calling {@link #getTrueTagKey} on a defined tag constant) or null if none - * exist. - * - * @param tagId a TID as defined in the exif standard (or with - * {@link #defineTag}). - * @return a List of {@link ExifTag}s. - */ - public List<ExifTag> getTagsForTagId(short tagId) { - return mData.getAllTagsForTagId(tagId); - } - - /** - * Returns a list of ExifTags that share an IFD (which can be obtained by - * calling {@link #getTrueIFD} on a defined tag constant) or null if none - * exist. - * - * @param ifdId an IFD as defined in the exif standard (or with - * {@link #defineTag}). - * @return a List of {@link ExifTag}s. - */ - public List<ExifTag> getTagsForIfdId(int ifdId) { - return mData.getAllTagsForIfd(ifdId); - } - - /** - * Gets an ExifTag for an IFD other than the tag's default. - * - * @see #getTag - */ - public ExifTag getTag(int tagId, int ifdId) { - if (!ExifTag.isValidIfd(ifdId)) { - return null; - } - return mData.getTag(getTrueTagKey(tagId), ifdId); - } - - /** - * Returns the ExifTag in that tag's default IFD for a defined tag constant - * or null if none exists. - * - * @param tagId a defined tag constant, e.g. {@link #TAG_IMAGE_WIDTH}. - * @return an {@link ExifTag} or null if none exists. - */ - public ExifTag getTag(int tagId) { - int ifdId = getDefinedTagDefaultIfd(tagId); - return getTag(tagId, ifdId); - } - - /** - * Gets a tag value for an IFD other than the tag's default. - * - * @see #getTagValue - */ - public Object getTagValue(int tagId, int ifdId) { - ExifTag t = getTag(tagId, ifdId); - return (t == null) ? null : t.getValue(); - } - - /** - * Returns the value of the ExifTag in that tag's default IFD for a defined - * tag constant or null if none exists or the value could not be cast into - * the return type. - * - * @param tagId a defined tag constant, e.g. {@link #TAG_IMAGE_WIDTH}. - * @return the value of the ExifTag or null if none exists. - */ - public Object getTagValue(int tagId) { - int ifdId = getDefinedTagDefaultIfd(tagId); - return getTagValue(tagId, ifdId); - } - - /* - * Getter methods that are similar to getTagValue. Null is returned if the - * tag value cannot be cast into the return type. - */ - - /** - * @see #getTagValue - */ - public String getTagStringValue(int tagId, int ifdId) { - ExifTag t = getTag(tagId, ifdId); - if (t == null) { - return null; - } - return t.getValueAsString(); - } - - /** - * @see #getTagValue - */ - public String getTagStringValue(int tagId) { - int ifdId = getDefinedTagDefaultIfd(tagId); - return getTagStringValue(tagId, ifdId); - } - - /** - * @see #getTagValue - */ - public Long getTagLongValue(int tagId, int ifdId) { - long[] l = getTagLongValues(tagId, ifdId); - if (l == null || l.length <= 0) { - return null; - } - return new Long(l[0]); - } - - /** - * @see #getTagValue - */ - public Long getTagLongValue(int tagId) { - int ifdId = getDefinedTagDefaultIfd(tagId); - return getTagLongValue(tagId, ifdId); - } - - /** - * @see #getTagValue - */ - public Integer getTagIntValue(int tagId, int ifdId) { - int[] l = getTagIntValues(tagId, ifdId); - if (l == null || l.length <= 0) { - return null; - } - return new Integer(l[0]); - } - - /** - * @see #getTagValue - */ - public Integer getTagIntValue(int tagId) { - int ifdId = getDefinedTagDefaultIfd(tagId); - return getTagIntValue(tagId, ifdId); - } - - /** - * @see #getTagValue - */ - public Byte getTagByteValue(int tagId, int ifdId) { - byte[] l = getTagByteValues(tagId, ifdId); - if (l == null || l.length <= 0) { - return null; - } - return new Byte(l[0]); - } - - /** - * @see #getTagValue - */ - public Byte getTagByteValue(int tagId) { - int ifdId = getDefinedTagDefaultIfd(tagId); - return getTagByteValue(tagId, ifdId); - } - - /** - * @see #getTagValue - */ - public Rational getTagRationalValue(int tagId, int ifdId) { - Rational[] l = getTagRationalValues(tagId, ifdId); - if (l == null || l.length == 0) { - return null; - } - return new Rational(l[0]); - } - - /** - * @see #getTagValue - */ - public Rational getTagRationalValue(int tagId) { - int ifdId = getDefinedTagDefaultIfd(tagId); - return getTagRationalValue(tagId, ifdId); - } - - /** - * @see #getTagValue - */ - public long[] getTagLongValues(int tagId, int ifdId) { - ExifTag t = getTag(tagId, ifdId); - if (t == null) { - return null; - } - return t.getValueAsLongs(); - } - - /** - * @see #getTagValue - */ - public long[] getTagLongValues(int tagId) { - int ifdId = getDefinedTagDefaultIfd(tagId); - return getTagLongValues(tagId, ifdId); - } - - /** - * @see #getTagValue - */ - public int[] getTagIntValues(int tagId, int ifdId) { - ExifTag t = getTag(tagId, ifdId); - if (t == null) { - return null; - } - return t.getValueAsInts(); - } - - /** - * @see #getTagValue - */ - public int[] getTagIntValues(int tagId) { - int ifdId = getDefinedTagDefaultIfd(tagId); - return getTagIntValues(tagId, ifdId); - } - - /** - * @see #getTagValue - */ - public byte[] getTagByteValues(int tagId, int ifdId) { - ExifTag t = getTag(tagId, ifdId); - if (t == null) { - return null; - } - return t.getValueAsBytes(); - } - - /** - * @see #getTagValue - */ - public byte[] getTagByteValues(int tagId) { - int ifdId = getDefinedTagDefaultIfd(tagId); - return getTagByteValues(tagId, ifdId); - } - - /** - * @see #getTagValue - */ - public Rational[] getTagRationalValues(int tagId, int ifdId) { - ExifTag t = getTag(tagId, ifdId); - if (t == null) { - return null; - } - return t.getValueAsRationals(); - } - - /** - * @see #getTagValue - */ - public Rational[] getTagRationalValues(int tagId) { - int ifdId = getDefinedTagDefaultIfd(tagId); - return getTagRationalValues(tagId, ifdId); - } - - /** - * Checks whether a tag has a defined number of elements. - * - * @param tagId a defined tag constant, e.g. {@link #TAG_IMAGE_WIDTH}. - * @return true if the tag has a defined number of elements. - */ - public boolean isTagCountDefined(int tagId) { - int info = getTagInfo().get(tagId); - // No value in info can be zero, as all tags have a non-zero type - if (info == 0) { - return false; - } - return getComponentCountFromInfo(info) != ExifTag.SIZE_UNDEFINED; - } - - /** - * Gets the defined number of elements for a tag. - * - * @param tagId a defined tag constant, e.g. {@link #TAG_IMAGE_WIDTH}. - * @return the number of elements or {@link ExifTag#SIZE_UNDEFINED} if the - * tag or the number of elements is not defined. - */ - public int getDefinedTagCount(int tagId) { - int info = getTagInfo().get(tagId); - if (info == 0) { - return ExifTag.SIZE_UNDEFINED; - } - return getComponentCountFromInfo(info); - } - - /** - * Gets the number of elements for an ExifTag in a given IFD. - * - * @param tagId a defined tag constant, e.g. {@link #TAG_IMAGE_WIDTH}. - * @param ifdId the IFD containing the ExifTag to check. - * @return the number of elements in the ExifTag, if the tag's size is - * undefined this will return the actual number of elements that is - * in the ExifTag's value. - */ - public int getActualTagCount(int tagId, int ifdId) { - ExifTag t = getTag(tagId, ifdId); - if (t == null) { - return 0; - } - return t.getComponentCount(); - } - - /** - * Gets the default IFD for a tag. - * - * @param tagId a defined tag constant, e.g. {@link #TAG_IMAGE_WIDTH}. - * @return the default IFD for a tag definition or {@link #IFD_NULL} if no - * definition exists. - */ - public int getDefinedTagDefaultIfd(int tagId) { - int info = getTagInfo().get(tagId); - if (info == DEFINITION_NULL) { - return IFD_NULL; - } - return getTrueIfd(tagId); - } - - /** - * Gets the defined type for a tag. - * - * @param tagId a defined tag constant, e.g. {@link #TAG_IMAGE_WIDTH}. - * @return the type. - * @see ExifTag#getDataType() - */ - public short getDefinedTagType(int tagId) { - int info = getTagInfo().get(tagId); - if (info == 0) { - return -1; - } - return getTypeFromInfo(info); - } - - /** - * Returns true if tag TID is one of the following: {@link TAG_EXIF_IFD}, - * {@link TAG_GPS_IFD}, {@link TAG_JPEG_INTERCHANGE_FORMAT}, - * {@link TAG_STRIP_OFFSETS}, {@link TAG_INTEROPERABILITY_IFD} - * <p> - * Note: defining tags with these TID's is disallowed. - * - * @param tag a tag's TID (can be obtained from a defined tag constant with - * {@link #getTrueTagKey}). - * @return true if the TID is that of an offset tag. - */ - protected static boolean isOffsetTag(short tag) { - return sOffsetTags.contains(tag); - } - - /** - * Creates a tag for a defined tag constant in a given IFD if that IFD is - * allowed for the tag. This method will fail anytime the appropriate - * {@link ExifTag#setValue} for this tag's datatype would fail. - * - * @param tagId a tag constant, e.g. {@link #TAG_IMAGE_WIDTH}. - * @param ifdId the IFD that the tag should be in. - * @param val the value of the tag to set. - * @return an ExifTag object or null if one could not be constructed. - * @see #buildTag - */ - public ExifTag buildTag(int tagId, int ifdId, Object val) { - int info = getTagInfo().get(tagId); - if (info == 0 || val == null) { - return null; - } - short type = getTypeFromInfo(info); - int definedCount = getComponentCountFromInfo(info); - boolean hasDefinedCount = (definedCount != ExifTag.SIZE_UNDEFINED); - if (!ExifInterface.isIfdAllowed(info, ifdId)) { - return null; - } - ExifTag t = new ExifTag(getTrueTagKey(tagId), type, definedCount, ifdId, hasDefinedCount); - if (!t.setValue(val)) { - return null; - } - return t; - } - - /** - * Creates a tag for a defined tag constant in the tag's default IFD. - * - * @param tagId a tag constant, e.g. {@link #TAG_IMAGE_WIDTH}. - * @param val the tag's value. - * @return an ExifTag object. - */ - public ExifTag buildTag(int tagId, Object val) { - int ifdId = getTrueIfd(tagId); - return buildTag(tagId, ifdId, val); - } - - protected ExifTag buildUninitializedTag(int tagId) { - int info = getTagInfo().get(tagId); - if (info == 0) { - return null; - } - short type = getTypeFromInfo(info); - int definedCount = getComponentCountFromInfo(info); - boolean hasDefinedCount = (definedCount != ExifTag.SIZE_UNDEFINED); - int ifdId = getTrueIfd(tagId); - ExifTag t = new ExifTag(getTrueTagKey(tagId), type, definedCount, ifdId, hasDefinedCount); - return t; - } - - /** - * Sets the value of an ExifTag if it exists in the given IFD. The value - * must be the correct type and length for that ExifTag. - * - * @param tagId a tag constant, e.g. {@link #TAG_IMAGE_WIDTH}. - * @param ifdId the IFD that the ExifTag is in. - * @param val the value to set. - * @return true if success, false if the ExifTag doesn't exist or the value - * is the wrong type/length. - * @see #setTagValue - */ - public boolean setTagValue(int tagId, int ifdId, Object val) { - ExifTag t = getTag(tagId, ifdId); - if (t == null) { - return false; - } - return t.setValue(val); - } - - /** - * Sets the value of an ExifTag if it exists it's default IFD. The value - * must be the correct type and length for that ExifTag. - * - * @param tagId a tag constant, e.g. {@link #TAG_IMAGE_WIDTH}. - * @param val the value to set. - * @return true if success, false if the ExifTag doesn't exist or the value - * is the wrong type/length. - */ - public boolean setTagValue(int tagId, Object val) { - int ifdId = getDefinedTagDefaultIfd(tagId); - return setTagValue(tagId, ifdId, val); - } - - /** - * Puts an ExifTag into this ExifInterface object's tags, removing a - * previous ExifTag with the same TID and IFD. The IFD it is put into will - * be the one the tag was created with in {@link #buildTag}. - * - * @param tag an ExifTag to put into this ExifInterface's tags. - * @return the previous ExifTag with the same TID and IFD or null if none - * exists. - */ - public ExifTag setTag(ExifTag tag) { - return mData.addTag(tag); - } - - /** - * Puts a collection of ExifTags into this ExifInterface objects's tags. Any - * previous ExifTags with the same TID and IFDs will be removed. - * - * @param tags a Collection of ExifTags. - * @see #setTag - */ - public void setTags(Collection<ExifTag> tags) { - for (ExifTag t : tags) { - setTag(t); - } - } - - /** - * Removes the ExifTag for a tag constant from the given IFD. - * - * @param tagId a tag constant, e.g. {@link #TAG_IMAGE_WIDTH}. - * @param ifdId the IFD of the ExifTag to remove. - */ - public void deleteTag(int tagId, int ifdId) { - mData.removeTag(getTrueTagKey(tagId), ifdId); - } - - /** - * Removes the ExifTag for a tag constant from that tag's default IFD. - * - * @param tagId a tag constant, e.g. {@link #TAG_IMAGE_WIDTH}. - */ - public void deleteTag(int tagId) { - int ifdId = getDefinedTagDefaultIfd(tagId); - deleteTag(tagId, ifdId); - } - - /** - * Creates a new tag definition in this ExifInterface object for a given TID - * and default IFD. Creating a definition with the same TID and default IFD - * as a previous definition will override it. - * - * @param tagId the TID for the tag. - * @param defaultIfd the default IFD for the tag. - * @param tagType the type of the tag (see {@link ExifTag#getDataType()}). - * @param defaultComponentCount the number of elements of this tag's type in - * the tags value. - * @param allowedIfds the IFD's this tag is allowed to be put in. - * @return the defined tag constant (e.g. {@link #TAG_IMAGE_WIDTH}) or - * {@link #TAG_NULL} if the definition could not be made. - */ - public int setTagDefinition(short tagId, int defaultIfd, short tagType, - short defaultComponentCount, int[] allowedIfds) { - if (sBannedDefines.contains(tagId)) { - return TAG_NULL; - } - if (ExifTag.isValidType(tagType) && ExifTag.isValidIfd(defaultIfd)) { - int tagDef = defineTag(defaultIfd, tagId); - if (tagDef == TAG_NULL) { - return TAG_NULL; - } - int[] otherDefs = getTagDefinitionsForTagId(tagId); - SparseIntArray infos = getTagInfo(); - // Make sure defaultIfd is in allowedIfds - boolean defaultCheck = false; - for (int i : allowedIfds) { - if (defaultIfd == i) { - defaultCheck = true; - } - if (!ExifTag.isValidIfd(i)) { - return TAG_NULL; - } - } - if (!defaultCheck) { - return TAG_NULL; - } - - int ifdFlags = getFlagsFromAllowedIfds(allowedIfds); - // Make sure no identical tags can exist in allowedIfds - if (otherDefs != null) { - for (int def : otherDefs) { - int tagInfo = infos.get(def); - int allowedFlags = getAllowedIfdFlagsFromInfo(tagInfo); - if ((ifdFlags & allowedFlags) != 0) { - return TAG_NULL; - } - } - } - getTagInfo().put(tagDef, ifdFlags << 24 | (tagType << 16) | defaultComponentCount); - return tagDef; - } - return TAG_NULL; - } - - protected int getTagDefinition(short tagId, int defaultIfd) { - return getTagInfo().get(defineTag(defaultIfd, tagId)); - } - - protected int[] getTagDefinitionsForTagId(short tagId) { - int[] ifds = IfdData.getIfds(); - int[] defs = new int[ifds.length]; - int counter = 0; - SparseIntArray infos = getTagInfo(); - for (int i : ifds) { - int def = defineTag(i, tagId); - if (infos.get(def) != DEFINITION_NULL) { - defs[counter++] = def; - } - } - if (counter == 0) { - return null; - } - - return Arrays.copyOfRange(defs, 0, counter); - } - - protected int getTagDefinitionForTag(ExifTag tag) { - short type = tag.getDataType(); - int count = tag.getComponentCount(); - int ifd = tag.getIfd(); - return getTagDefinitionForTag(tag.getTagId(), type, count, ifd); - } - - protected int getTagDefinitionForTag(short tagId, short type, int count, int ifd) { - int[] defs = getTagDefinitionsForTagId(tagId); - if (defs == null) { - return TAG_NULL; - } - SparseIntArray infos = getTagInfo(); - int ret = TAG_NULL; - for (int i : defs) { - int info = infos.get(i); - short def_type = getTypeFromInfo(info); - int def_count = getComponentCountFromInfo(info); - int[] def_ifds = getAllowedIfdsFromInfo(info); - boolean valid_ifd = false; - for (int j : def_ifds) { - if (j == ifd) { - valid_ifd = true; - break; - } - } - if (valid_ifd && type == def_type - && (count == def_count || def_count == ExifTag.SIZE_UNDEFINED)) { - ret = i; - break; - } - } - return ret; - } - - /** - * Removes a tag definition for given defined tag constant. - * - * @param tagId a defined tag constant, e.g. {@link #TAG_IMAGE_WIDTH}. - */ - public void removeTagDefinition(int tagId) { - getTagInfo().delete(tagId); - } - - /** - * Resets tag definitions to the default ones. - */ - public void resetTagDefinitions() { - mTagInfo = null; - } - - /** - * Returns the thumbnail from IFD1 as a bitmap, or null if none exists. - * - * @return the thumbnail as a bitmap. - */ - public Bitmap getThumbnailBitmap() { - if (mData.hasCompressedThumbnail()) { - byte[] thumb = mData.getCompressedThumbnail(); - return BitmapFactory.decodeByteArray(thumb, 0, thumb.length); - } else if (mData.hasUncompressedStrip()) { - // TODO: implement uncompressed - } - return null; - } - - /** - * Returns the thumbnail from IFD1 as a byte array, or null if none exists. - * The bytes may either be an uncompressed strip as specified in the exif - * standard or a jpeg compressed image. - * - * @return the thumbnail as a byte array. - */ - public byte[] getThumbnailBytes() { - if (mData.hasCompressedThumbnail()) { - return mData.getCompressedThumbnail(); - } else if (mData.hasUncompressedStrip()) { - // TODO: implement this - } - return null; - } - - /** - * Returns the thumbnail if it is jpeg compressed, or null if none exists. - * - * @return the thumbnail as a byte array. - */ - public byte[] getThumbnail() { - return mData.getCompressedThumbnail(); - } - - /** - * Check if thumbnail is compressed. - * - * @return true if the thumbnail is compressed. - */ - public boolean isThumbnailCompressed() { - return mData.hasCompressedThumbnail(); - } - - /** - * Check if thumbnail exists. - * - * @return true if a compressed thumbnail exists. - */ - public boolean hasThumbnail() { - // TODO: add back in uncompressed strip - return mData.hasCompressedThumbnail(); - } - - // TODO: uncompressed thumbnail setters - - /** - * Sets the thumbnail to be a jpeg compressed image. Clears any prior - * thumbnail. - * - * @param thumb a byte array containing a jpeg compressed image. - * @return true if the thumbnail was set. - */ - public boolean setCompressedThumbnail(byte[] thumb) { - mData.clearThumbnailAndStrips(); - mData.setCompressedThumbnail(thumb); - return true; - } - - /** - * Sets the thumbnail to be a jpeg compressed bitmap. Clears any prior - * thumbnail. - * - * @param thumb a bitmap to compress to a jpeg thumbnail. - * @return true if the thumbnail was set. - */ - public boolean setCompressedThumbnail(Bitmap thumb) { - ByteArrayOutputStream thumbnail = new ByteArrayOutputStream(); - if (!thumb.compress(Bitmap.CompressFormat.JPEG, 90, thumbnail)) { - return false; - } - return setCompressedThumbnail(thumbnail.toByteArray()); - } - - /** - * Clears the compressed thumbnail if it exists. - */ - public void removeCompressedThumbnail() { - mData.setCompressedThumbnail(null); - } - - // Convenience methods: - - /** - * Decodes the user comment tag into string as specified in the EXIF - * standard. Returns null if decoding failed. - */ - public String getUserComment() { - return mData.getUserComment(); - } - - /** - * Returns the Orientation ExifTag value for a given number of degrees. - * - * @param degrees the amount an image is rotated in degrees. - */ - public static short getOrientationValueForRotation(int degrees) { - degrees %= 360; - if (degrees < 0) { - degrees += 360; - } - if (degrees < 90) { - return Orientation.TOP_LEFT; // 0 degrees - } else if (degrees < 180) { - return Orientation.RIGHT_TOP; // 90 degrees cw - } else if (degrees < 270) { - return Orientation.BOTTOM_LEFT; // 180 degrees - } else { - return Orientation.RIGHT_BOTTOM; // 270 degrees cw - } - } - - /** - * Returns the rotation degrees corresponding to an ExifTag Orientation - * value. - * - * @param orientation the ExifTag Orientation value. - */ - public static int getRotationForOrientationValue(short orientation) { - switch (orientation) { - case Orientation.TOP_LEFT: - return 0; - case Orientation.RIGHT_TOP: - return 90; - case Orientation.BOTTOM_LEFT: - return 180; - case Orientation.RIGHT_BOTTOM: - return 270; - default: - return 0; - } - } - - /** - * Gets the double representation of the GPS latitude or longitude - * coordinate. - * - * @param coordinate an array of 3 Rationals representing the degrees, - * minutes, and seconds of the GPS location as defined in the - * exif specification. - * @param reference a GPS reference reperesented by a String containing "N", - * "S", "E", or "W". - * @return the GPS coordinate represented as degrees + minutes/60 + - * seconds/3600 - */ - public static double convertLatOrLongToDouble(Rational[] coordinate, String reference) { - try { - double degrees = coordinate[0].toDouble(); - double minutes = coordinate[1].toDouble(); - double seconds = coordinate[2].toDouble(); - double result = degrees + minutes / 60.0 + seconds / 3600.0; - if ((reference.equals("S") || reference.equals("W"))) { - return -result; - } - return result; - } catch (ArrayIndexOutOfBoundsException e) { - throw new IllegalArgumentException(); - } - } - - /** - * Gets the GPS latitude and longitude as a pair of doubles from this - * ExifInterface object's tags, or null if the necessary tags do not exist. - * - * @return an array of 2 doubles containing the latitude, and longitude - * respectively. - * @see #convertLatOrLongToDouble - */ - public double[] getLatLongAsDoubles() { - Rational[] latitude = getTagRationalValues(TAG_GPS_LATITUDE); - String latitudeRef = getTagStringValue(TAG_GPS_LATITUDE_REF); - Rational[] longitude = getTagRationalValues(TAG_GPS_LONGITUDE); - String longitudeRef = getTagStringValue(TAG_GPS_LONGITUDE_REF); - if (latitude == null || longitude == null || latitudeRef == null || longitudeRef == null - || latitude.length < 3 || longitude.length < 3) { - return null; - } - double[] latLon = new double[2]; - latLon[0] = convertLatOrLongToDouble(latitude, latitudeRef); - latLon[1] = convertLatOrLongToDouble(longitude, longitudeRef); - return latLon; - } - - private static final String GPS_DATE_FORMAT_STR = "yyyy:MM:dd"; - private static final String DATETIME_FORMAT_STR = "yyyy:MM:dd kk:mm:ss"; - private final DateFormat mDateTimeStampFormat = new SimpleDateFormat(DATETIME_FORMAT_STR); - private final DateFormat mGPSDateStampFormat = new SimpleDateFormat(GPS_DATE_FORMAT_STR); - private final Calendar mGPSTimeStampCalendar = Calendar - .getInstance(TimeZone.getTimeZone("UTC")); - - /** - * Creates, formats, and sets the DateTimeStamp tag for one of: - * {@link #TAG_DATE_TIME}, {@link #TAG_DATE_TIME_DIGITIZED}, - * {@link #TAG_DATE_TIME_ORIGINAL}. - * - * @param tagId one of the DateTimeStamp tags. - * @param timestamp a timestamp to format. - * @param timezone a TimeZone object. - * @return true if success, false if the tag could not be set. - */ - public boolean addDateTimeStampTag(int tagId, long timestamp, TimeZone timezone) { - if (tagId == TAG_DATE_TIME || tagId == TAG_DATE_TIME_DIGITIZED - || tagId == TAG_DATE_TIME_ORIGINAL) { - mDateTimeStampFormat.setTimeZone(timezone); - ExifTag t = buildTag(tagId, mDateTimeStampFormat.format(timestamp)); - if (t == null) { - return false; - } - setTag(t); - } else { - return false; - } - return true; - } - - /** - * Creates and sets all to the GPS tags for a give latitude and longitude. - * - * @param latitude a GPS latitude coordinate. - * @param longitude a GPS longitude coordinate. - * @return true if success, false if they could not be created or set. - */ - public boolean addGpsTags(double latitude, double longitude) { - ExifTag latTag = buildTag(TAG_GPS_LATITUDE, toExifLatLong(latitude)); - ExifTag longTag = buildTag(TAG_GPS_LONGITUDE, toExifLatLong(longitude)); - ExifTag latRefTag = buildTag(TAG_GPS_LATITUDE_REF, - latitude >= 0 ? ExifInterface.GpsLatitudeRef.NORTH - : ExifInterface.GpsLatitudeRef.SOUTH); - ExifTag longRefTag = buildTag(TAG_GPS_LONGITUDE_REF, - longitude >= 0 ? ExifInterface.GpsLongitudeRef.EAST - : ExifInterface.GpsLongitudeRef.WEST); - if (latTag == null || longTag == null || latRefTag == null || longRefTag == null) { - return false; - } - setTag(latTag); - setTag(longTag); - setTag(latRefTag); - setTag(longRefTag); - return true; - } - - /** - * Creates and sets the GPS timestamp tag. - * - * @param timestamp a GPS timestamp. - * @return true if success, false if could not be created or set. - */ - public boolean addGpsDateTimeStampTag(long timestamp) { - ExifTag t = buildTag(TAG_GPS_DATE_STAMP, mGPSDateStampFormat.format(timestamp)); - if (t == null) { - return false; - } - setTag(t); - mGPSTimeStampCalendar.setTimeInMillis(timestamp); - t = buildTag(TAG_GPS_TIME_STAMP, new Rational[] { - new Rational(mGPSTimeStampCalendar.get(Calendar.HOUR_OF_DAY), 1), - new Rational(mGPSTimeStampCalendar.get(Calendar.MINUTE), 1), - new Rational(mGPSTimeStampCalendar.get(Calendar.SECOND), 1) - }); - if (t == null) { - return false; - } - setTag(t); - return true; - } - - private static Rational[] toExifLatLong(double value) { - // convert to the format dd/1 mm/1 ssss/100 - value = Math.abs(value); - int degrees = (int) value; - value = (value - degrees) * 60; - int minutes = (int) value; - value = (value - minutes) * 6000; - int seconds = (int) value; - return new Rational[] { - new Rational(degrees, 1), new Rational(minutes, 1), new Rational(seconds, 100) - }; - } - - private void doExifStreamIO(InputStream is, OutputStream os) throws IOException { - byte[] buf = new byte[1024]; - int ret = is.read(buf, 0, 1024); - while (ret != -1) { - os.write(buf, 0, ret); - ret = is.read(buf, 0, 1024); - } - } - - protected static void closeSilently(Closeable c) { - if (c != null) { - try { - c.close(); - } catch (Throwable e) { - // ignored - } - } - } - - private SparseIntArray mTagInfo = null; - - protected SparseIntArray getTagInfo() { - if (mTagInfo == null) { - mTagInfo = new SparseIntArray(); - initTagInfo(); - } - return mTagInfo; - } - - private void initTagInfo() { - /** - * We put tag information in a 4-bytes integer. The first byte a bitmask - * representing the allowed IFDs of the tag, the second byte is the data - * type, and the last two byte are a short value indicating the default - * component count of this tag. - */ - // IFD0 tags - int[] ifdAllowedIfds = { - IfdId.TYPE_IFD_0, IfdId.TYPE_IFD_1 - }; - int ifdFlags = getFlagsFromAllowedIfds(ifdAllowedIfds) << 24; - mTagInfo.put(ExifInterface.TAG_MAKE, - ifdFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED); - mTagInfo.put(ExifInterface.TAG_IMAGE_WIDTH, - ifdFlags | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1); - mTagInfo.put(ExifInterface.TAG_IMAGE_LENGTH, - ifdFlags | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1); - mTagInfo.put(ExifInterface.TAG_BITS_PER_SAMPLE, - ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 3); - mTagInfo.put(ExifInterface.TAG_COMPRESSION, - ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); - mTagInfo.put(ExifInterface.TAG_PHOTOMETRIC_INTERPRETATION, - ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); - mTagInfo.put(ExifInterface.TAG_ORIENTATION, ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 - | 1); - mTagInfo.put(ExifInterface.TAG_SAMPLES_PER_PIXEL, - ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); - mTagInfo.put(ExifInterface.TAG_PLANAR_CONFIGURATION, - ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); - mTagInfo.put(ExifInterface.TAG_Y_CB_CR_SUB_SAMPLING, - ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 2); - mTagInfo.put(ExifInterface.TAG_Y_CB_CR_POSITIONING, - ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); - mTagInfo.put(ExifInterface.TAG_X_RESOLUTION, - ifdFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); - mTagInfo.put(ExifInterface.TAG_Y_RESOLUTION, - ifdFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); - mTagInfo.put(ExifInterface.TAG_RESOLUTION_UNIT, - ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); - mTagInfo.put(ExifInterface.TAG_STRIP_OFFSETS, - ifdFlags | ExifTag.TYPE_UNSIGNED_LONG << 16 | ExifTag.SIZE_UNDEFINED); - mTagInfo.put(ExifInterface.TAG_ROWS_PER_STRIP, - ifdFlags | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1); - mTagInfo.put(ExifInterface.TAG_STRIP_BYTE_COUNTS, - ifdFlags | ExifTag.TYPE_UNSIGNED_LONG << 16 | ExifTag.SIZE_UNDEFINED); - mTagInfo.put(ExifInterface.TAG_TRANSFER_FUNCTION, - ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 3 * 256); - mTagInfo.put(ExifInterface.TAG_WHITE_POINT, - ifdFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 2); - mTagInfo.put(ExifInterface.TAG_PRIMARY_CHROMATICITIES, - ifdFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 6); - mTagInfo.put(ExifInterface.TAG_Y_CB_CR_COEFFICIENTS, - ifdFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 3); - mTagInfo.put(ExifInterface.TAG_REFERENCE_BLACK_WHITE, - ifdFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 6); - mTagInfo.put(ExifInterface.TAG_DATE_TIME, - ifdFlags | ExifTag.TYPE_ASCII << 16 | 20); - mTagInfo.put(ExifInterface.TAG_IMAGE_DESCRIPTION, - ifdFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED); - mTagInfo.put(ExifInterface.TAG_MAKE, - ifdFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED); - mTagInfo.put(ExifInterface.TAG_MODEL, - ifdFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED); - mTagInfo.put(ExifInterface.TAG_SOFTWARE, - ifdFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED); - mTagInfo.put(ExifInterface.TAG_ARTIST, - ifdFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED); - mTagInfo.put(ExifInterface.TAG_COPYRIGHT, - ifdFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED); - mTagInfo.put(ExifInterface.TAG_EXIF_IFD, - ifdFlags | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1); - mTagInfo.put(ExifInterface.TAG_GPS_IFD, - ifdFlags | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1); - // IFD1 tags - int[] ifd1AllowedIfds = { - IfdId.TYPE_IFD_1 - }; - int ifdFlags1 = getFlagsFromAllowedIfds(ifd1AllowedIfds) << 24; - mTagInfo.put(ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT, - ifdFlags1 | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1); - mTagInfo.put(ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH, - ifdFlags1 | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1); - // Exif tags - int[] exifAllowedIfds = { - IfdId.TYPE_IFD_EXIF - }; - int exifFlags = getFlagsFromAllowedIfds(exifAllowedIfds) << 24; - mTagInfo.put(ExifInterface.TAG_EXIF_VERSION, - exifFlags | ExifTag.TYPE_UNDEFINED << 16 | 4); - mTagInfo.put(ExifInterface.TAG_FLASHPIX_VERSION, - exifFlags | ExifTag.TYPE_UNDEFINED << 16 | 4); - mTagInfo.put(ExifInterface.TAG_COLOR_SPACE, - exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); - mTagInfo.put(ExifInterface.TAG_COMPONENTS_CONFIGURATION, - exifFlags | ExifTag.TYPE_UNDEFINED << 16 | 4); - mTagInfo.put(ExifInterface.TAG_COMPRESSED_BITS_PER_PIXEL, - exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); - mTagInfo.put(ExifInterface.TAG_PIXEL_X_DIMENSION, - exifFlags | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1); - mTagInfo.put(ExifInterface.TAG_PIXEL_Y_DIMENSION, - exifFlags | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1); - mTagInfo.put(ExifInterface.TAG_MAKER_NOTE, - exifFlags | ExifTag.TYPE_UNDEFINED << 16 | ExifTag.SIZE_UNDEFINED); - mTagInfo.put(ExifInterface.TAG_USER_COMMENT, - exifFlags | ExifTag.TYPE_UNDEFINED << 16 | ExifTag.SIZE_UNDEFINED); - mTagInfo.put(ExifInterface.TAG_RELATED_SOUND_FILE, - exifFlags | ExifTag.TYPE_ASCII << 16 | 13); - mTagInfo.put(ExifInterface.TAG_DATE_TIME_ORIGINAL, - exifFlags | ExifTag.TYPE_ASCII << 16 | 20); - mTagInfo.put(ExifInterface.TAG_DATE_TIME_DIGITIZED, - exifFlags | ExifTag.TYPE_ASCII << 16 | 20); - mTagInfo.put(ExifInterface.TAG_SUB_SEC_TIME, - exifFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED); - mTagInfo.put(ExifInterface.TAG_SUB_SEC_TIME_ORIGINAL, - exifFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED); - mTagInfo.put(ExifInterface.TAG_SUB_SEC_TIME_DIGITIZED, - exifFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED); - mTagInfo.put(ExifInterface.TAG_IMAGE_UNIQUE_ID, - exifFlags | ExifTag.TYPE_ASCII << 16 | 33); - mTagInfo.put(ExifInterface.TAG_EXPOSURE_TIME, - exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); - mTagInfo.put(ExifInterface.TAG_F_NUMBER, - exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); - mTagInfo.put(ExifInterface.TAG_EXPOSURE_PROGRAM, - exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); - mTagInfo.put(ExifInterface.TAG_SPECTRAL_SENSITIVITY, - exifFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED); - mTagInfo.put(ExifInterface.TAG_ISO_SPEED_RATINGS, - exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | ExifTag.SIZE_UNDEFINED); - mTagInfo.put(ExifInterface.TAG_OECF, - exifFlags | ExifTag.TYPE_UNDEFINED << 16 | ExifTag.SIZE_UNDEFINED); - mTagInfo.put(ExifInterface.TAG_SHUTTER_SPEED_VALUE, - exifFlags | ExifTag.TYPE_RATIONAL << 16 | 1); - mTagInfo.put(ExifInterface.TAG_APERTURE_VALUE, - exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); - mTagInfo.put(ExifInterface.TAG_BRIGHTNESS_VALUE, - exifFlags | ExifTag.TYPE_RATIONAL << 16 | 1); - mTagInfo.put(ExifInterface.TAG_EXPOSURE_BIAS_VALUE, - exifFlags | ExifTag.TYPE_RATIONAL << 16 | 1); - mTagInfo.put(ExifInterface.TAG_MAX_APERTURE_VALUE, - exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); - mTagInfo.put(ExifInterface.TAG_SUBJECT_DISTANCE, - exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); - mTagInfo.put(ExifInterface.TAG_METERING_MODE, - exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); - mTagInfo.put(ExifInterface.TAG_LIGHT_SOURCE, - exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); - mTagInfo.put(ExifInterface.TAG_FLASH, - exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); - mTagInfo.put(ExifInterface.TAG_FOCAL_LENGTH, - exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); - mTagInfo.put(ExifInterface.TAG_SUBJECT_AREA, - exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | ExifTag.SIZE_UNDEFINED); - mTagInfo.put(ExifInterface.TAG_FLASH_ENERGY, - exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); - mTagInfo.put(ExifInterface.TAG_SPATIAL_FREQUENCY_RESPONSE, - exifFlags | ExifTag.TYPE_UNDEFINED << 16 | ExifTag.SIZE_UNDEFINED); - mTagInfo.put(ExifInterface.TAG_FOCAL_PLANE_X_RESOLUTION, - exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); - mTagInfo.put(ExifInterface.TAG_FOCAL_PLANE_Y_RESOLUTION, - exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); - mTagInfo.put(ExifInterface.TAG_FOCAL_PLANE_RESOLUTION_UNIT, - exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); - mTagInfo.put(ExifInterface.TAG_SUBJECT_LOCATION, - exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 2); - mTagInfo.put(ExifInterface.TAG_EXPOSURE_INDEX, - exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); - mTagInfo.put(ExifInterface.TAG_SENSING_METHOD, - exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); - mTagInfo.put(ExifInterface.TAG_FILE_SOURCE, - exifFlags | ExifTag.TYPE_UNDEFINED << 16 | 1); - mTagInfo.put(ExifInterface.TAG_SCENE_TYPE, - exifFlags | ExifTag.TYPE_UNDEFINED << 16 | 1); - mTagInfo.put(ExifInterface.TAG_CFA_PATTERN, - exifFlags | ExifTag.TYPE_UNDEFINED << 16 | ExifTag.SIZE_UNDEFINED); - mTagInfo.put(ExifInterface.TAG_CUSTOM_RENDERED, - exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); - mTagInfo.put(ExifInterface.TAG_EXPOSURE_MODE, - exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); - mTagInfo.put(ExifInterface.TAG_WHITE_BALANCE, - exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); - mTagInfo.put(ExifInterface.TAG_DIGITAL_ZOOM_RATIO, - exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); - mTagInfo.put(ExifInterface.TAG_FOCAL_LENGTH_IN_35_MM_FILE, - exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); - mTagInfo.put(ExifInterface.TAG_SCENE_CAPTURE_TYPE, - exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); - mTagInfo.put(ExifInterface.TAG_GAIN_CONTROL, - exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); - mTagInfo.put(ExifInterface.TAG_CONTRAST, - exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); - mTagInfo.put(ExifInterface.TAG_SATURATION, - exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); - mTagInfo.put(ExifInterface.TAG_SHARPNESS, - exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); - mTagInfo.put(ExifInterface.TAG_DEVICE_SETTING_DESCRIPTION, - exifFlags | ExifTag.TYPE_UNDEFINED << 16 | ExifTag.SIZE_UNDEFINED); - mTagInfo.put(ExifInterface.TAG_SUBJECT_DISTANCE_RANGE, - exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1); - mTagInfo.put(ExifInterface.TAG_INTEROPERABILITY_IFD, exifFlags - | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1); - // GPS tag - int[] gpsAllowedIfds = { - IfdId.TYPE_IFD_GPS - }; - int gpsFlags = getFlagsFromAllowedIfds(gpsAllowedIfds) << 24; - mTagInfo.put(ExifInterface.TAG_GPS_VERSION_ID, - gpsFlags | ExifTag.TYPE_UNSIGNED_BYTE << 16 | 4); - mTagInfo.put(ExifInterface.TAG_GPS_LATITUDE_REF, - gpsFlags | ExifTag.TYPE_ASCII << 16 | 2); - mTagInfo.put(ExifInterface.TAG_GPS_LONGITUDE_REF, - gpsFlags | ExifTag.TYPE_ASCII << 16 | 2); - mTagInfo.put(ExifInterface.TAG_GPS_LATITUDE, - gpsFlags | ExifTag.TYPE_RATIONAL << 16 | 3); - mTagInfo.put(ExifInterface.TAG_GPS_LONGITUDE, - gpsFlags | ExifTag.TYPE_RATIONAL << 16 | 3); - mTagInfo.put(ExifInterface.TAG_GPS_ALTITUDE_REF, - gpsFlags | ExifTag.TYPE_UNSIGNED_BYTE << 16 | 1); - mTagInfo.put(ExifInterface.TAG_GPS_ALTITUDE, - gpsFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); - mTagInfo.put(ExifInterface.TAG_GPS_TIME_STAMP, - gpsFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 3); - mTagInfo.put(ExifInterface.TAG_GPS_SATTELLITES, - gpsFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED); - mTagInfo.put(ExifInterface.TAG_GPS_STATUS, - gpsFlags | ExifTag.TYPE_ASCII << 16 | 2); - mTagInfo.put(ExifInterface.TAG_GPS_MEASURE_MODE, - gpsFlags | ExifTag.TYPE_ASCII << 16 | 2); - mTagInfo.put(ExifInterface.TAG_GPS_DOP, - gpsFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); - mTagInfo.put(ExifInterface.TAG_GPS_SPEED_REF, - gpsFlags | ExifTag.TYPE_ASCII << 16 | 2); - mTagInfo.put(ExifInterface.TAG_GPS_SPEED, - gpsFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); - mTagInfo.put(ExifInterface.TAG_GPS_TRACK_REF, - gpsFlags | ExifTag.TYPE_ASCII << 16 | 2); - mTagInfo.put(ExifInterface.TAG_GPS_TRACK, - gpsFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); - mTagInfo.put(ExifInterface.TAG_GPS_IMG_DIRECTION_REF, - gpsFlags | ExifTag.TYPE_ASCII << 16 | 2); - mTagInfo.put(ExifInterface.TAG_GPS_IMG_DIRECTION, - gpsFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); - mTagInfo.put(ExifInterface.TAG_GPS_MAP_DATUM, - gpsFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED); - mTagInfo.put(ExifInterface.TAG_GPS_DEST_LATITUDE_REF, - gpsFlags | ExifTag.TYPE_ASCII << 16 | 2); - mTagInfo.put(ExifInterface.TAG_GPS_DEST_LATITUDE, - gpsFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); - mTagInfo.put(ExifInterface.TAG_GPS_DEST_BEARING_REF, - gpsFlags | ExifTag.TYPE_ASCII << 16 | 2); - mTagInfo.put(ExifInterface.TAG_GPS_DEST_BEARING, - gpsFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); - mTagInfo.put(ExifInterface.TAG_GPS_DEST_DISTANCE_REF, - gpsFlags | ExifTag.TYPE_ASCII << 16 | 2); - mTagInfo.put(ExifInterface.TAG_GPS_DEST_DISTANCE, - gpsFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1); - mTagInfo.put(ExifInterface.TAG_GPS_PROCESSING_METHOD, - gpsFlags | ExifTag.TYPE_UNDEFINED << 16 | ExifTag.SIZE_UNDEFINED); - mTagInfo.put(ExifInterface.TAG_GPS_AREA_INFORMATION, - gpsFlags | ExifTag.TYPE_UNDEFINED << 16 | ExifTag.SIZE_UNDEFINED); - mTagInfo.put(ExifInterface.TAG_GPS_DATE_STAMP, - gpsFlags | ExifTag.TYPE_ASCII << 16 | 11); - mTagInfo.put(ExifInterface.TAG_GPS_DIFFERENTIAL, - gpsFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 11); - // Interoperability tag - int[] interopAllowedIfds = { - IfdId.TYPE_IFD_INTEROPERABILITY - }; - int interopFlags = getFlagsFromAllowedIfds(interopAllowedIfds) << 24; - mTagInfo.put(TAG_INTEROPERABILITY_INDEX, interopFlags | ExifTag.TYPE_ASCII << 16 - | ExifTag.SIZE_UNDEFINED); - } - - protected static int getAllowedIfdFlagsFromInfo(int info) { - return info >>> 24; - } - - protected static int[] getAllowedIfdsFromInfo(int info) { - int ifdFlags = getAllowedIfdFlagsFromInfo(info); - int[] ifds = IfdData.getIfds(); - ArrayList<Integer> l = new ArrayList<Integer>(); - for (int i = 0; i < IfdId.TYPE_IFD_COUNT; i++) { - int flag = (ifdFlags >> i) & 1; - if (flag == 1) { - l.add(ifds[i]); - } - } - if (l.size() <= 0) { - return null; - } - int[] ret = new int[l.size()]; - int j = 0; - for (int i : l) { - ret[j++] = i; - } - return ret; - } - - protected static boolean isIfdAllowed(int info, int ifd) { - int[] ifds = IfdData.getIfds(); - int ifdFlags = getAllowedIfdFlagsFromInfo(info); - for (int i = 0; i < ifds.length; i++) { - if (ifd == ifds[i] && ((ifdFlags >> i) & 1) == 1) { - return true; - } - } - return false; - } - - protected static int getFlagsFromAllowedIfds(int[] allowedIfds) { - if (allowedIfds == null || allowedIfds.length == 0) { - return 0; - } - int flags = 0; - int[] ifds = IfdData.getIfds(); - for (int i = 0; i < IfdId.TYPE_IFD_COUNT; i++) { - for (int j : allowedIfds) { - if (ifds[i] == j) { - flags |= 1 << i; - break; - } - } - } - return flags; - } - - protected static short getTypeFromInfo(int info) { - return (short) ((info >> 16) & 0x0ff); - } - - protected static int getComponentCountFromInfo(int info) { - return info & 0x0ffff; - } - -} |