X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=libexif%2Fexif-tag.c;h=6c85e33024c5826a11f75e47d31aa43c4c8bac16;hb=e6a38a1a23ba94d139b1fa2cd4519fdcfe3c9bab;hp=9b4aaf129be082d1f16a53d23ab076f2b6caee51;hpb=6133ae626311deacb09e6c046bd34b109622dcac;p=platform%2Fupstream%2Flibexif.git diff --git a/libexif/exif-tag.c b/libexif/exif-tag.c index 9b4aaf1..6c85e33 100644 --- a/libexif/exif-tag.c +++ b/libexif/exif-tag.c @@ -14,8 +14,8 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. */ #include @@ -36,9 +36,23 @@ #define ESL_NNMM { EXIF_SUPPORT_LEVEL_NOT_RECORDED, EXIF_SUPPORT_LEVEL_NOT_RECORDED, EXIF_SUPPORT_LEVEL_MANDATORY, EXIF_SUPPORT_LEVEL_MANDATORY } #define ESL_NNNM { EXIF_SUPPORT_LEVEL_NOT_RECORDED, EXIF_SUPPORT_LEVEL_NOT_RECORDED, EXIF_SUPPORT_LEVEL_NOT_RECORDED, EXIF_SUPPORT_LEVEL_MANDATORY } #define ESL_NNNO { EXIF_SUPPORT_LEVEL_NOT_RECORDED, EXIF_SUPPORT_LEVEL_NOT_RECORDED, EXIF_SUPPORT_LEVEL_NOT_RECORDED, EXIF_SUPPORT_LEVEL_OPTIONAL } +#define ESL_UUUU { EXIF_SUPPORT_LEVEL_UNKNOWN, EXIF_SUPPORT_LEVEL_UNKNOWN, EXIF_SUPPORT_LEVEL_UNKNOWN, EXIF_SUPPORT_LEVEL_UNKNOWN } #define ESL_GPS { ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN } +#define ESL_UNKNOWN { ESL_UUUU, ESL_UUUU, ESL_UUUU, ESL_UUUU, ESL_UUUU } -static const struct { +/*! + * Table giving information about each EXIF tag. + * There may be more than one entry with the same tag value because some tags + * have different meanings depending on the IFD in which they appear. + * When there are such duplicate entries, there must be no overlap in their + * support levels. + * The entries MUST be sorted in tag order. + * The name and title are mandatory, but the description may be an empty + * string. None of the entries may be NULL except the final array terminator. + */ +static const struct TagEntry { + /*! Tag ID. There may be duplicate tags when the same number is used for + * different meanings in different IFDs. */ ExifTag tag; const char *name; const char *title; @@ -47,21 +61,170 @@ static const struct { ExifSupportLevel esl[EXIF_IFD_COUNT][EXIF_DATA_TYPE_COUNT]; } ExifTagTable[] = { #ifndef NO_VERBOSE_TAG_STRINGS - /* Not in EXIF 2.2 */ - {EXIF_TAG_NEW_SUBFILE_TYPE, "NewSubfileType", - N_("New Subfile Type"), N_("A general indication of the kind of data " - "contained in this subfile.")}, + {EXIF_TAG_GPS_VERSION_ID, "GPSVersionID", N_("GPS Tag Version"), + N_("Indicates the version of . The version is given " + "as 2.0.0.0. This tag is mandatory when tag is " + "present. (Note: The tag is given in bytes, " + "unlike the tag. When the version is " + "2.0.0.0, the tag value is 02000000.H)."), ESL_GPS}, {EXIF_TAG_INTEROPERABILITY_INDEX, "InteroperabilityIndex", - "InteroperabilityIndex", + N_("Interoperability Index"), N_("Indicates the identification of the Interoperability rule. " "Use \"R98\" for stating ExifR98 Rules. Four bytes used " "including the termination code (NULL). see the separate " "volume of Recommended Exif Interoperability Rules (ExifR98) " "for other tags used for ExifR98."), { ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_OOOO } }, + {EXIF_TAG_GPS_LATITUDE_REF, "GPSLatitudeRef", N_("North or South Latitude"), + N_("Indicates whether the latitude is north or south latitude. The " + "ASCII value 'N' indicates north latitude, and 'S' is south " + "latitude."), ESL_GPS}, {EXIF_TAG_INTEROPERABILITY_VERSION, "InteroperabilityVersion", - "InteroperabilityVersion", "", + N_("Interoperability Version"), "", { ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_OOOO } }, + {EXIF_TAG_GPS_LATITUDE, "GPSLatitude", N_("Latitude"), + N_("Indicates the latitude. The latitude is expressed as three " + "RATIONAL values giving the degrees, minutes, and seconds, " + "respectively. When degrees, minutes and seconds are expressed, " + "the format is dd/1,mm/1,ss/1. When degrees and minutes are used " + "and, for example, fractions of minutes are given up to two " + "decimal places, the format is dd/1,mmmm/100,0/1."), + ESL_GPS}, + {EXIF_TAG_GPS_LONGITUDE_REF, "GPSLongitudeRef", N_("East or West Longitude"), + N_("Indicates whether the longitude is east or west longitude. " + "ASCII 'E' indicates east longitude, and 'W' is west " + "longitude."), ESL_GPS}, + {EXIF_TAG_GPS_LONGITUDE, "GPSLongitude", N_("Longitude"), + N_("Indicates the longitude. The longitude is expressed as three " + "RATIONAL values giving the degrees, minutes, and seconds, " + "respectively. When degrees, minutes and seconds are expressed, " + "the format is ddd/1,mm/1,ss/1. When degrees and minutes are " + "used and, for example, fractions of minutes are given up to " + "two decimal places, the format is ddd/1,mmmm/100,0/1."), + ESL_GPS}, + {EXIF_TAG_GPS_ALTITUDE_REF, "GPSAltitudeRef", N_("Altitude Reference"), + N_("Indicates the altitude used as the reference altitude. If the " + "reference is sea level and the altitude is above sea level, 0 " + "is given. If the altitude is below sea level, a value of 1 is given " + "and the altitude is indicated as an absolute value in the " + "GPSAltitude tag. The reference unit is meters. Note that this tag " + "is BYTE type, unlike other reference tags."), ESL_GPS}, + {EXIF_TAG_GPS_ALTITUDE, "GPSAltitude", N_("Altitude"), + N_("Indicates the altitude based on the reference in GPSAltitudeRef. " + "Altitude is expressed as one RATIONAL value. The reference unit " + "is meters."), ESL_GPS}, + {EXIF_TAG_GPS_TIME_STAMP, "GPSTimeStamp", N_("GPS Time (Atomic Clock)"), + N_("Indicates the time as UTC (Coordinated Universal Time). " + "TimeStamp is expressed as three RATIONAL values giving " + "the hour, minute, and second."), ESL_GPS}, + {EXIF_TAG_GPS_SATELLITES, "GPSSatellites", N_("GPS Satellites"), + N_("Indicates the GPS satellites used for measurements. This " + "tag can be used to describe the number of satellites, their ID " + "number, angle of elevation, azimuth, SNR and other information " + "in ASCII notation. The format is not specified. If the GPS " + "receiver is incapable of taking measurements, value of the tag " + "shall be set to NULL."), ESL_GPS}, + {EXIF_TAG_GPS_STATUS, "GPSStatus", N_("GPS Receiver Status"), + N_("Indicates the status of the GPS receiver when the image is " + "recorded. 'A' means measurement is in progress, and 'V' means " + "the measurement is Interoperability."), ESL_GPS}, + {EXIF_TAG_GPS_MEASURE_MODE, "GPSMeasureMode", N_("GPS Measurement Mode"), + N_("Indicates the GPS measurement mode. '2' means " + "two-dimensional measurement and '3' means three-dimensional " + "measurement is in progress."), ESL_GPS}, + {EXIF_TAG_GPS_DOP, "GPSDOP", N_("Measurement Precision"), + N_("Indicates the GPS DOP (data degree of precision). An HDOP " + "value is written during two-dimensional measurement, and PDOP " + "during three-dimensional measurement."), ESL_GPS}, + {EXIF_TAG_GPS_SPEED_REF, "GPSSpeedRef", N_("Speed Unit"), + N_("Indicates the unit used to express the GPS receiver speed " + "of movement. 'K', 'M' and 'N' represent kilometers per hour, " + "miles per hour, and knots."), ESL_GPS}, + {EXIF_TAG_GPS_SPEED, "GPSSpeed", N_("Speed of GPS Receiver"), + N_("Indicates the speed of GPS receiver movement."), ESL_GPS}, + {EXIF_TAG_GPS_TRACK_REF, "GPSTrackRef", N_("Reference for direction of movement"), + N_("Indicates the reference for giving the direction of GPS " + "receiver movement. 'T' denotes true direction and 'M' is " + "magnetic direction."), ESL_GPS}, + {EXIF_TAG_GPS_TRACK, "GPSTrack", N_("Direction of Movement"), + N_("Indicates the direction of GPS receiver movement. The range " + "of values is from 0.00 to 359.99."), ESL_GPS}, + {EXIF_TAG_GPS_IMG_DIRECTION_REF, "GPSImgDirectionRef", N_("GPS Image Direction Reference"), + N_("Indicates the reference for giving the direction of the image when it is captured. " + "'T' denotes true direction and 'M' is magnetic direction."), ESL_GPS}, + {EXIF_TAG_GPS_IMG_DIRECTION, "GPSImgDirection", N_("GPS Image Direction"), + N_("Indicates the direction of the image when it was captured. The range of values is " + "from 0.00 to 359.99."), ESL_GPS}, + {EXIF_TAG_GPS_MAP_DATUM, "GPSMapDatum", N_("Geodetic Survey Data Used"), + N_("Indicates the geodetic survey data used by the GPS " + "receiver. If the survey data is restricted to Japan, the value " + "of this tag is 'TOKYO' or 'WGS-84'. If a GPS Info tag is " + "recorded, it is strongly recommended that this tag be recorded."), ESL_GPS}, + {EXIF_TAG_GPS_DEST_LATITUDE_REF, "GPSDestLatitudeRef", N_("Reference For Latitude of Destination"), + N_("Indicates whether the latitude of the destination point is " + "north or south latitude. The ASCII value 'N' indicates north " + "latitude, and 'S' is south latitude."), ESL_GPS}, + {EXIF_TAG_GPS_DEST_LATITUDE, "GPSDestLatitude", N_("Latitude of Destination"), + N_("Indicates the latitude of the destination point. The " + "latitude is expressed as three RATIONAL values giving the " + "degrees, minutes, and seconds, respectively. If latitude is " + "expressed as degrees, minutes and seconds, a typical format " + "would be dd/1,mm/1,ss/1. When degrees and minutes are used and, " + "for example, fractions of minutes are given up to two decimal " + "places, the format would be dd/1,mmmm/100,0/1."), ESL_GPS}, + {EXIF_TAG_GPS_DEST_LONGITUDE_REF, "GPSDestLongitudeRef", N_("Reference for Longitude of Destination"), + N_("Indicates whether the longitude of the destination point is " + "east or west longitude. ASCII 'E' indicates east longitude, and " + "'W' is west longitude."), ESL_GPS}, + {EXIF_TAG_GPS_DEST_LONGITUDE, "GPSDestLongitude", N_("Longitude of Destination"), + N_("Indicates the longitude of the destination point. The " + "longitude is expressed as three RATIONAL values giving the " + "degrees, minutes, and seconds, respectively. If longitude is " + "expressed as degrees, minutes and seconds, a typical format " + "would be ddd/1,mm/1,ss/1. When degrees and minutes are used " + "and, for example, fractions of minutes are given up to two " + "decimal places, the format would be ddd/1,mmmm/100,0/1."), + ESL_GPS}, + {EXIF_TAG_GPS_DEST_BEARING_REF, "GPSDestBearingRef", N_("Reference for Bearing of Destination"), + N_("Indicates the reference used for giving the bearing to " + "the destination point. 'T' denotes true direction and 'M' is " + "magnetic direction."), ESL_GPS}, + {EXIF_TAG_GPS_DEST_BEARING, "GPSDestBearing", N_("Bearing of Destination"), + N_("Indicates the bearing to the destination point. The range " + "of values is from 0.00 to 359.99."), ESL_GPS}, + {EXIF_TAG_GPS_DEST_DISTANCE_REF, "GPSDestDistanceRef", N_("Reference for Distance to Destination"), + N_("Indicates the unit used to express the distance to the " + "destination point. 'K', 'M' and 'N' represent kilometers, miles " + "and nautical miles."), ESL_GPS}, + {EXIF_TAG_GPS_DEST_DISTANCE, "GPSDestDistance", N_("Distance to Destination"), + N_("Indicates the distance to the destination point."), ESL_GPS}, + {EXIF_TAG_GPS_PROCESSING_METHOD, "GPSProcessingMethod", N_("Name of GPS Processing Method"), + N_("A character string recording the name of the method used " + "for location finding. The first byte indicates the character " + "code used, and this is followed by the name " + "of the method. Since the Type is not ASCII, NULL termination is " + "not necessary."), ESL_GPS}, + {EXIF_TAG_GPS_AREA_INFORMATION, "GPSAreaInformation", N_("Name of GPS Area"), + N_("A character string recording the name of the GPS area. The " + "first byte indicates the character code used, " + "and this is followed by the name of the GPS area. Since " + "the Type is not ASCII, NULL termination is not necessary."), ESL_GPS}, + {EXIF_TAG_GPS_DATE_STAMP, "GPSDateStamp", N_("GPS Date"), + N_("A character string recording date and time information " + "relative to UTC (Coordinated Universal Time). The format is " + "\"YYYY:MM:DD\". The length of the string is 11 bytes including " + "NULL."), ESL_GPS}, + {EXIF_TAG_GPS_DIFFERENTIAL, "GPSDifferential", N_("GPS Differential Correction"), + N_("Indicates whether differential correction is applied to the " + "GPS receiver."), ESL_GPS}, + {EXIF_TAG_GPS_H_POSITIONING_ERROR, "GPSHPositioningError", N_("GPS Horizontal Positioning Error"), + N_("Indicates the horizontal positioning errors in meters. This is " + "expressed as one RATIONAL value."), ESL_GPS}, + /* Not in EXIF 2.2 */ + {EXIF_TAG_NEW_SUBFILE_TYPE, "NewSubfileType", + N_("New Subfile Type"), N_("A general indication of the kind of data " + "contained in this subfile."), + ESL_UNKNOWN}, {EXIF_TAG_IMAGE_WIDTH, "ImageWidth", N_("Image Width"), N_("The number of columns of image data, equal to the number of " "pixels per row. In JPEG compressed data a JPEG marker is " @@ -89,9 +252,10 @@ static const struct { "marker is used instead of this tag."), { ESL_MMMN, ESL_MMMN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, /* Not in EXIF 2.2 */ - {EXIF_TAG_FILL_ORDER, "FillOrder", N_("Fill Order"), ""}, + {EXIF_TAG_FILL_ORDER, "FillOrder", N_("Fill Order"), "", ESL_UNKNOWN}, /* Not in EXIF 2.2 */ - {EXIF_TAG_DOCUMENT_NAME, "DocumentName", N_("Document Name"), ""}, + {EXIF_TAG_DOCUMENT_NAME, "DocumentName", N_("Document Name"), "", + ESL_UNKNOWN}, {EXIF_TAG_IMAGE_DESCRIPTION, "ImageDescription", N_("Image Description"), N_("A character string giving the title of the image. It may be " @@ -141,12 +305,12 @@ static const struct { N_("The total number of bytes in each strip. With JPEG compressed " "data this designation is not needed and is omitted."), { ESL_MMMN, ESL_MMMN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, - {EXIF_TAG_X_RESOLUTION, "XResolution", N_("x-Resolution"), + {EXIF_TAG_X_RESOLUTION, "XResolution", N_("X-Resolution"), N_("The number of pixels per in the " "direction. When the image resolution is unknown, 72 [dpi] " "is designated."), { ESL_MMMM, ESL_MMMM, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, - {EXIF_TAG_Y_RESOLUTION, "YResolution", N_("y-Resolution"), + {EXIF_TAG_Y_RESOLUTION, "YResolution", N_("Y-Resolution"), N_("The number of pixels per in the " "direction. The same value as is designated."), { ESL_MMMM, ESL_MMMM, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, @@ -199,12 +363,13 @@ static const struct { "specified in the color space information tag ()."), { ESL_OOOO, ESL_OOOO, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, /* Not in EXIF 2.2 */ - {EXIF_TAG_TRANSFER_RANGE, "TransferRange", N_("Transfer Range"), ""}, - /* Not in EXIF 2.2 */ {EXIF_TAG_SUB_IFDS, "SubIFDs", "SubIFD Offsets", N_("Defined by Adobe Corporation " - "to enable TIFF Trees within a TIFF file.")}, + "to enable TIFF Trees within a TIFF file."), ESL_UNKNOWN}, /* Not in EXIF 2.2 */ - {EXIF_TAG_JPEG_PROC, "JPEGProc", "JPEGProc", ""}, + {EXIF_TAG_TRANSFER_RANGE, "TransferRange", N_("Transfer Range"), "", + ESL_UNKNOWN}, + /* Not in EXIF 2.2 */ + {EXIF_TAG_JPEG_PROC, "JPEGProc", "JPEGProc", "", ESL_UNKNOWN}, {EXIF_TAG_JPEG_INTERCHANGE_FORMAT, "JPEGInterchangeFormat", N_("JPEG Interchange Format"), N_("The offset to the start byte (SOI) of JPEG compressed " @@ -263,27 +428,29 @@ static const struct { "Interoperability these conditions."), { ESL_OOOO, ESL_OOOO, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, /* Not in EXIF 2.2 */ - {EXIF_TAG_XML_PACKET, "XMLPacket", N_("XML Packet"), N_("XMP Metadata")}, + {EXIF_TAG_XML_PACKET, "XMLPacket", N_("XML Packet"), N_("XMP Metadata"), + ESL_UNKNOWN}, /* Not in EXIF 2.2 */ {EXIF_TAG_RELATED_IMAGE_FILE_FORMAT, "RelatedImageFileFormat", - "RelatedImageFileFormat", ""}, + "RelatedImageFileFormat", "", ESL_UNKNOWN}, /* Not in EXIF 2.2 */ {EXIF_TAG_RELATED_IMAGE_WIDTH, "RelatedImageWidth", - "RelatedImageWidth", ""}, + "RelatedImageWidth", "", ESL_UNKNOWN}, /* Not in EXIF 2.2 */ {EXIF_TAG_RELATED_IMAGE_LENGTH, "RelatedImageLength", - "RelatedImageLength", ""}, + "RelatedImageLength", "", ESL_UNKNOWN}, /* Not in EXIF 2.2 */ {EXIF_TAG_CFA_REPEAT_PATTERN_DIM, "CFARepeatPatternDim", - "CFARepeatPatternDim", ""}, + "CFARepeatPatternDim", "", ESL_UNKNOWN}, /* Not in EXIF 2.2 */ {EXIF_TAG_CFA_PATTERN, "CFAPattern", N_("CFA Pattern"), N_("Indicates the color filter array (CFA) geometric pattern of the " "image sensor when a one-chip color area sensor is used. " - "It does not apply to all sensing methods.")}, + "It does not apply to all sensing methods."), ESL_UNKNOWN}, /* Not in EXIF 2.2 */ - {EXIF_TAG_BATTERY_LEVEL, "BatteryLevel", N_("Battery Level"), ""}, + {EXIF_TAG_BATTERY_LEVEL, "BatteryLevel", N_("Battery Level"), "", + ESL_UNKNOWN}, {EXIF_TAG_COPYRIGHT, "Copyright", N_("Copyright"), N_("Copyright information. In this standard the tag is used to " "indicate both the photographer and editor copyrights. It is " @@ -309,13 +476,14 @@ static const struct { {EXIF_TAG_EXPOSURE_TIME, "ExposureTime", N_("Exposure Time"), N_("Exposure time, given in seconds (sec)."), { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, - {EXIF_TAG_FNUMBER, "FNumber", N_("FNumber"), + {EXIF_TAG_FNUMBER, "FNumber", N_("F-Number"), N_("The F number."), { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, /* Not in EXIF 2.2 */ - {EXIF_TAG_IPTC_NAA, "IPTC/NAA", "IPTC/NAA", ""}, + {EXIF_TAG_IPTC_NAA, "IPTC/NAA", "IPTC/NAA", "", ESL_UNKNOWN}, /* Not in EXIF 2.2 */ - {EXIF_TAG_IMAGE_RESOURCES, "ImageResources", N_("Image Resources Block"), ""}, + {EXIF_TAG_IMAGE_RESOURCES, "ImageResources", N_("Image Resources Block"), "", + ESL_UNKNOWN}, {EXIF_TAG_EXIF_IFD_POINTER, "ExifIfdPointer", "ExifIFDPointer", N_("A pointer to the Exif IFD. Interoperability, Exif IFD has the " "same structure as that of the IFD specified in TIFF. " @@ -324,7 +492,7 @@ static const struct { { ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, /* Not in EXIF 2.2 */ {EXIF_TAG_INTER_COLOR_PROFILE, "InterColorProfile", - "InterColorProfile", ""}, + "InterColorProfile", "", ESL_UNKNOWN}, {EXIF_TAG_EXPOSURE_PROGRAM, "ExposureProgram", N_("Exposure Program"), N_("The class of the program used by the camera to set exposure " "when the picture is taken."), @@ -336,180 +504,38 @@ static const struct { "with the standard developed by the ASTM Technical Committee."), { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, {EXIF_TAG_GPS_INFO_IFD_POINTER, "GPSInfoIFDPointer", - "GPSInfoIFDPointer", + N_("GPS Info IFD Pointer"), N_("A pointer to the GPS Info IFD. The " "Interoperability structure of the GPS Info IFD, like that of " "Exif IFD, has no image data."), { ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, - {EXIF_TAG_GPS_VERSION_ID, "GPSVersionID", N_("GPS tag version"), - N_("Indicates the version of . The version is given " - "as 2.0.0.0. This tag is mandatory when tag is " - "present. (Note: The tag is given in bytes, " - "unlike the tag. When the version is " - "2.0.0.0, the tag value is 02000000.H)."), ESL_GPS}, - {EXIF_TAG_GPS_LATITUDE_REF, "GPSLatitudeRef", N_("North or South Latitude"), - N_("Indicates whether the latitude is north or south latitude. The " - "ASCII value 'N' indicates north latitude, and 'S' is south " - "latitude."), ESL_GPS}, - {EXIF_TAG_GPS_LATITUDE, "GPSLatitude", N_("Latitude"), - N_("Indicates the latitude. The latitude is expressed as three " - "RATIONAL values giving the degrees, minutes, and seconds, " - "respectively. When degrees, minutes and seconds are expressed, " - "the format is dd/1,mm/1,ss/1. When degrees and minutes are used " - "and, for example, fractions of minutes are given up to two " - "decimal places, the format is dd/1,mmmm/100,0/1."), - ESL_GPS}, - {EXIF_TAG_GPS_LONGITUDE_REF, "GPSLongitudeRef", N_("East or West Longitude"), - N_("Indicates whether the longitude is east or west longitude. " - "ASCII 'E' indicates east longitude, and 'W' is west " - "longitude."), ESL_GPS}, - {EXIF_TAG_GPS_LONGITUDE, "GPSLongitude", N_("Longitude"), - N_("Indicates the longitude. The longitude is expressed as three " - "RATIONAL values giving the degrees, minutes, and seconds, " - "respectively. When degrees, minutes and seconds are expressed, " - "the format is ddd/1,mm/1,ss/1. When degrees and minutes are " - "used and, for example, fractions of minutes are given up to " - "two decimal places, the format is ddd/1,mmmm/100,0/1."), - ESL_GPS}, - {EXIF_TAG_GPS_ALTITUDE_REF, "GPSAltitudeRef", N_("Altitude reference"), - N_("Indicates the altitude used as the reference altitude. If the " - "reference is sea level and the altitude is above sea level, 0 " - "is given. If the altitude is below sea level, a value of 1 is given " - "and the altitude is indicated as an absolute value in the " - "GSPAltitude tag. The reference unit is meters. Note that this tag " - "is BYTE type, unlike other reference tags."), ESL_GPS}, - {EXIF_TAG_GPS_ALTITUDE, "GPSAltitude", N_("Altitude"), - N_("Indicates the altitude based on the reference in GPSAltitudeRef. " - "Altitude is expressed as one RATIONAL value. The reference unit " - "is meters."), ESL_GPS}, - {EXIF_TAG_GPS_TIME_STAMP, "GPSTimeStamp", N_("GPS time (atomic clock)"), - N_("Indicates the time as UTC (Coordinated Universal Time). " - "TimeStamp is expressed as three RATIONAL values giving " - "the hour, minute, and second."), ESL_GPS}, - {EXIF_TAG_GPS_SATELLITES, "GPSSatellites", N_("GPS satellites used for measurement"), - N_("Indicates the GPS satellites used for measurements. This " - "tag can be used to describe the number of satellites, their ID " - "number, angle of elevation, azimuth, SNR and other information " - "in ASCII notation. The format is not specified. If the GPS " - "receiver is incapable of taking measurements, value of the tag " - "shall be set to NULL."), ESL_GPS}, - {EXIF_TAG_GPS_STATUS, "GPSStatus", N_("GPS receiver status"), - N_("Indicates the status of the GPS receiver when the image is " - "recorded. 'A' means measurement is in progress, and 'V' means " - "the measurement is Interoperability."), ESL_GPS}, - {EXIF_TAG_GPS_MEASURE_MODE, "GPSMeasureMode", N_("GPS measurement mode"), - N_("Indicates the GPS measurement mode. '2' means " - "two-dimensional measurement and '3' means three-dimensional " - "measurement is in progress."), ESL_GPS}, - {EXIF_TAG_GPS_DOP, "GPSDOP", N_("Measurement precision"), - N_("Indicates the GPS DOP (data degree of precision). An HDOP " - "value is written during two-dimensional measurement, and PDOP " - "during three-dimensional measurement."), ESL_GPS}, - {EXIF_TAG_GPS_SPEED_REF, "GPSSpeedRef", N_("Speed unit"), - N_("Indicates the unit used to express the GPS receiver speed " - "of movement. 'K', 'M' and 'N' represent kilometers per hour, " - "miles per hour, and knots."), ESL_GPS}, - {EXIF_TAG_GPS_SPEED, "GPSSpeed", N_("Speed of GPS receiver"), - N_("Indicates the speed of GPS receiver movement."), ESL_GPS}, - {EXIF_TAG_GPS_TRACK_REF, "GPSTrackRef", N_("Reference for direction of movement"), - N_("Indicates the reference for giving the direction of GPS " - "receiver movement. 'T' denotes true direction and 'M' is " - "magnetic direction."), ESL_GPS}, - {EXIF_TAG_GPS_TRACK, "GPSTrack", N_("Direction of movement"), - N_("Indicates the direction of GPS receiver movement. The range " - "of values is from 0.00 to 359.99."), ESL_GPS}, - {EXIF_TAG_GPS_IMG_DIRECTION_REF, "GPSImgDirectionRef", N_("GPS Img Direction Reference"), - N_("Indicates the reference for giving the direction of the image when it is captured. " - "'T' denotes true direction and 'M' is magnetic direction."), ESL_GPS}, - {EXIF_TAG_GPS_IMG_DIRECTION, "GPSImgDirection", N_("GPS Img Direction"), - N_("Indicates the direction of the image when it was captured. The range of values is " - "from 0.00 to 359.99."), ESL_GPS}, - {EXIF_TAG_GPS_MAP_DATUM, "GPSMapDatum", N_("Geodetic survey data used"), - N_("Indicates the geodetic survey data used by the GPS " - "receiver. If the survey data is restricted to Japan, the value " - "of this tag is 'TOKYO' or 'WGS-84'. If a GPS Info tag is " - "recorded, it is strongly recommended that this tag be recorded."), ESL_GPS}, - {EXIF_TAG_GPS_DEST_LATITUDE_REF, "GPSDestLatitudeRef", N_("Reference for latitude of destination"), - N_("Indicates whether the latitude of the destination point is " - "north or south latitude. The ASCII value 'N' indicates north " - "latitude, and 'S' is south latitude."), ESL_GPS}, - {EXIF_TAG_GPS_DEST_LATITUDE, "GPSDestLatitude", N_("Latitude of destination"), - N_("Indicates the latitude of the destination point. The " - "latitude is expressed as three RATIONAL values giving the " - "degrees, minutes, and seconds, respectively. If latitude is " - "expressed as degrees, minutes and seconds, a typical format " - "would be dd/1,mm/1,ss/1. When degrees and minutes are used and, " - "for example, fractions of minutes are given up to two decimal " - "places, the format would be dd/1,mmmm/100,0/1."), ESL_GPS}, - {EXIF_TAG_GPS_DEST_LONGITUDE_REF, "GPSDestLongitudeRef", N_("Reference for longitude of destination"), - N_("Indicates whether the longitude of the destination point is " - "east or west longitude. ASCII 'E' indicates east longitude, and " - "'W' is west longitude."), ESL_GPS}, - {EXIF_TAG_GPS_DEST_LONGITUDE, "GPSDestLongitude", N_("Longitude of destination"), - N_("Indicates the longitude of the destination point. The " - "longitude is expressed as three RATIONAL values giving the " - "degrees, minutes, and seconds, respectively. If longitude is " - "expressed as degrees, minutes and seconds, a typical format " - "would be ddd/1,mm/1,ss/1. When degrees and minutes are used " - "and, for example, fractions of minutes are given up to two " - "decimal places, the format would be ddd/1,mmmm/100,0/1."), - ESL_GPS}, - {EXIF_TAG_GPS_DEST_BEARING_REF, "GPSDestBearingRef", N_("Reference for bearing of destination"), - N_("Indicates the reference used for giving the bearing to " - "the destination point. 'T' denotes true direction and 'M' is " - "magnetic direction."), ESL_GPS}, - {EXIF_TAG_GPS_DEST_BEARING, "GPSDestBearing", N_("Bearing of destination"), - N_("Indicates the bearing to the destination point. The range " - "of values is from 0.00 to 359.99."), ESL_GPS}, - {EXIF_TAG_GPS_DEST_DISTANCE_REF, "GPSDestDistanceRef", N_("Reference for distance to destination"), - N_("Indicates the unit used to express the distance to the " - "destination point. 'K', 'M' and 'N' represent kilometers, miles " - "and knots."), ESL_GPS}, - {EXIF_TAG_GPS_DEST_DISTANCE, "GPSDestDistance", N_("Distance to destination"), - N_("Indicates the distance to the destination point."), ESL_GPS}, - {EXIF_TAG_GPS_PROCESSING_METHOD, "GPSProcessingMethod", N_("Name of GPS processing method"), - N_("A character string recording the name of the method used " - "for location finding. The first byte indicates the character " - "code used, and this is followed by the name " - "of the method. Since the Type is not ASCII, NULL termination is " - "not necessary."), ESL_GPS}, - {EXIF_TAG_GPS_AREA_INFORMATION, "GPSAreaInformation", N_("Name of GPS area"), - N_("A character string recording the name of the GPS area. The " - "first byte indicates the character code used, " - "and this is followed by the name of the GPS area. Since " - "the Type is not ASCII, NULL termination is not necessary."), ESL_GPS}, - {EXIF_TAG_GPS_DATE_STAMP, "GPSDateStamp", N_("GPS date"), - N_("A character string recording date and time information " - "relative to UTC (Coordinated Universal Time). The format is " - "\"YYYY:MM:DD\". The length of the string is 11 bytes including " - "NULL."), ESL_GPS}, - {EXIF_TAG_GPS_DIFFERENTIAL, "GPSDifferential", N_("GPS differential correction"), - N_("Indicates whether differential correction is applied to the " - "GPS receiver."), ESL_GPS}, - {EXIF_TAG_ISO_SPEED_RATINGS, "ISOSpeedRatings", N_("ISO Speed Ratings"), N_("Indicates the ISO Speed and ISO Latitude of the camera or " "input device as specified in ISO 12232."), { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, - {EXIF_TAG_OECF, "OECF", "OECF", + {EXIF_TAG_OECF, "OECF", N_("Opto-Electronic Conversion Function"), N_("Indicates the Opto-Electronic Conversion Function (OECF) " "specified in ISO 14524. is the relationship between " "the camera optical input and the image values."), { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + /* Not in EXIF 2.2 */ + {EXIF_TAG_TIME_ZONE_OFFSET, "TimeZoneOffset", N_("Time Zone Offset"), + N_("Encodes time zone of camera clock relative to GMT."), + ESL_UNKNOWN}, {EXIF_TAG_EXIF_VERSION, "ExifVersion", N_("Exif Version"), N_("The version of this standard supported. Nonexistence of this " "field is taken to mean nonconformance to the standard."), { ESL_NNNN, ESL_NNNN, ESL_MMMM, ESL_NNNN, ESL_NNNN } }, {EXIF_TAG_DATE_TIME_ORIGINAL, "DateTimeOriginal", - N_("Date and Time (original)"), + N_("Date and Time (Original)"), N_("The date and time when the original image data was generated. " "For a digital still camera " "the date and time the picture was taken are recorded."), { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, {EXIF_TAG_DATE_TIME_DIGITIZED, "DateTimeDigitized", - N_("Date and Time (digitized)"), + N_("Date and Time (Digitized)"), N_("The date and time when the image was stored as digital data."), { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, {EXIF_TAG_COMPONENTS_CONFIGURATION, "ComponentsConfiguration", @@ -529,7 +555,7 @@ static const struct { "used for a compressed image is indicated in unit bits " "per pixel."), { ESL_NNNN, ESL_NNNN, ESL_NNNO, ESL_NNNN, ESL_NNNN } }, - {EXIF_TAG_SHUTTER_SPEED_VALUE, "ShutterSpeedValue", N_("Shutter speed"), + {EXIF_TAG_SHUTTER_SPEED_VALUE, "ShutterSpeedValue", N_("Shutter Speed"), N_("Shutter speed. The unit is the APEX (Additive System of " "Photographic Exposure) setting."), { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, @@ -545,7 +571,7 @@ static const struct { N_("The exposure bias. The units is the APEX value. Ordinarily " "it is given in the range of -99.99 to 99.99."), { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, - {EXIF_TAG_MAX_APERTURE_VALUE, "MaxApertureValue", "MaxApertureValue", + {EXIF_TAG_MAX_APERTURE_VALUE, "MaxApertureValue", N_("Maximum Aperture Value"), N_("The smallest F number of the lens. The unit is the APEX value. " "Ordinarily it is given in the range of 00.00 to 99.99, " "but it is not limited to this range."), @@ -568,6 +594,13 @@ static const struct { N_("The actual focal length of the lens, in mm. Conversion is not " "made to the focal length of a 35 mm film camera."), { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_SUBJECT_AREA, "SubjectArea", N_("Subject Area"), + N_("This tag indicates the location and area of the main subject " + "in the overall scene."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + /* Not in EXIF 2.2 */ + {EXIF_TAG_TIFF_EP_STANDARD_ID, "TIFF/EPStandardID", N_("TIFF/EP Standard ID"), "", + ESL_UNKNOWN}, {EXIF_TAG_MAKER_NOTE, "MakerNote", N_("Maker Note"), N_("A tag for manufacturers of Exif writers to record any desired " "information. The contents are up to the manufacturer."), @@ -596,31 +629,46 @@ static const struct { "the ID code be ASCII and that the following user comment " "part be filled with blank characters [20.H]."), { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, - {EXIF_TAG_SUB_SEC_TIME, "SubsecTime", "SubsecTime", + {EXIF_TAG_SUB_SEC_TIME, "SubsecTime", N_("Sub-second Time"), N_("A tag used to record fractions of seconds for the " " tag."), { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, {EXIF_TAG_SUB_SEC_TIME_ORIGINAL, "SubSecTimeOriginal", - "SubSecTimeOriginal", + N_("Sub-second Time (Original)"), N_("A tag used to record fractions of seconds for the " " tag."), { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, {EXIF_TAG_SUB_SEC_TIME_DIGITIZED, "SubSecTimeDigitized", - "SubSecTimeDigitized", + N_("Sub-second Time (Digitized)"), N_("A tag used to record fractions of seconds for the " " tag."), { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, - {EXIF_TAG_XP_TITLE, "XPTitle", N_("XP Title"), "", + /* Not in EXIF 2.2 (Microsoft extension) */ + {EXIF_TAG_XP_TITLE, "XPTitle", N_("XP Title"), + N_("A character string giving the title of the image, encoded in " + "UTF-16LE."), { ESL_OOOO, ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, - {EXIF_TAG_XP_COMMENT, "XPComment", N_("XP Comment"), "", + /* Not in EXIF 2.2 (Microsoft extension) */ + {EXIF_TAG_XP_COMMENT, "XPComment", N_("XP Comment"), + N_("A character string containing a comment about the image, encoded " + "in UTF-16LE."), { ESL_OOOO, ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, - {EXIF_TAG_XP_AUTHOR, "XPAuthor", N_("XP Author"), "", + /* Not in EXIF 2.2 (Microsoft extension) */ + {EXIF_TAG_XP_AUTHOR, "XPAuthor", N_("XP Author"), + N_("A character string containing the name of the image creator, " + "encoded in UTF-16LE."), { ESL_OOOO, ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, - {EXIF_TAG_XP_KEYWORDS, "XPKeywords", N_("XP Keywords"), "", + /* Not in EXIF 2.2 (Microsoft extension) */ + {EXIF_TAG_XP_KEYWORDS, "XPKeywords", N_("XP Keywords"), + N_("A character string containing key words describing the image, " + "encoded in UTF-16LE."), { ESL_OOOO, ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, - {EXIF_TAG_XP_SUBJECT, "XPSubject", N_("XP Subject"), "", + /* Not in EXIF 2.2 (Microsoft extension) */ + {EXIF_TAG_XP_SUBJECT, "XPSubject", N_("XP Subject"), + N_("A character string giving the image subject, encoded in " + "UTF-16LE."), { ESL_OOOO, ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, - {EXIF_TAG_FLASH_PIX_VERSION, "FlashPixVersion", "FlashPixVersion", + {EXIF_TAG_FLASH_PIX_VERSION, "FlashpixVersion", "FlashPixVersion", N_("The FlashPix format version supported by a FPXR file."), { ESL_NNNN, ESL_NNNN, ESL_MMMM, ESL_NNNN, ESL_NNNN } }, {EXIF_TAG_COLOR_SPACE, "ColorSpace", N_("Color Space"), @@ -632,14 +680,14 @@ static const struct { "recorded as Uncalibrated can be treated as sRGB when it is " "converted to FlashPix."), { ESL_NNNN, ESL_NNNN, ESL_MMMM, ESL_NNNN, ESL_NNNN } }, - {EXIF_TAG_PIXEL_X_DIMENSION, "PixelXDimension", "PixelXDimension", + {EXIF_TAG_PIXEL_X_DIMENSION, "PixelXDimension", N_("Pixel X Dimension"), N_("Information specific to compressed data. When a " "compressed file is recorded, the valid width of the " "meaningful image must be recorded in this tag, whether or " "not there is padding data or a restart marker. This tag " "should not exist in an uncompressed file."), { ESL_NNNN, ESL_NNNN, ESL_NNNM, ESL_NNNN, ESL_NNNN } }, - {EXIF_TAG_PIXEL_Y_DIMENSION, "PixelYDimension", "PixelYDimension", + {EXIF_TAG_PIXEL_Y_DIMENSION, "PixelYDimension", N_("Pixel Y Dimension"), N_("Information specific to compressed data. When a compressed " "file is recorded, the valid height of the meaningful image " "must be recorded in this tag, whether or not there is padding " @@ -650,7 +698,7 @@ static const struct { "will in fact be the same as that recorded in the SOF."), { ESL_NNNN, ESL_NNNN, ESL_NNNM, ESL_NNNN, ESL_NNNN } }, {EXIF_TAG_RELATED_SOUND_FILE, "RelatedSoundFile", - "RelatedSoundFile", + N_("Related Sound File"), N_("This tag is used to record the name of an audio file related " "to the image data. The only relational information " "recorded here is the Exif audio file name and extension (an " @@ -661,8 +709,7 @@ static const struct { "conformance to the Exif audio format. Writers are also allowed " "to store the data such as Audio within APP2 as FlashPix " "extension stream data. " - "Audio files must be recorded in conformance to the Exif audio " - "format. The mapping of Exif image files and audio files is done " + "The mapping of Exif image files and audio files is done " "in any of three ways, [1], [2] and [3]. If multiple files " "are mapped to one file as in [2] or [3], the above " "format is used to record just one audio file name. If " @@ -682,7 +729,7 @@ static const struct { "audio file end."), { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, {EXIF_TAG_INTEROPERABILITY_IFD_POINTER, "InteroperabilityIFDPointer", - "InteroperabilityIFDPointer", + N_("Interoperability IFD Pointer"), N_("Interoperability IFD is composed of tags which stores the " "information to ensure the Interoperability and pointed " "by the following tag located in Exif IFD. " @@ -704,12 +751,12 @@ static const struct { "12233."), { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, {EXIF_TAG_FOCAL_PLANE_X_RESOLUTION, "FocalPlaneXResolution", - N_("Focal Plane x-Resolution"), + N_("Focal Plane X-Resolution"), N_("Indicates the number of pixels in the image width (X) direction " "per on the camera focal plane."), { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, {EXIF_TAG_FOCAL_PLANE_Y_RESOLUTION, "FocalPlaneYResolution", - N_("Focal Plane y-Resolution"), + N_("Focal Plane Y-Resolution"), N_("Indicates the number of pixels in the image height (V) direction " "per on the camera focal plane."), { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, @@ -752,12 +799,6 @@ static const struct { "image sensor when a one-chip color area sensor is used. " "It does not apply to all sensing methods."), { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, - {EXIF_TAG_SUBJECT_AREA, "SubjectArea", N_("Subject Area"), - N_("This tag indicates the location and area of the main subject " - "in the overall scene."), - { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, - /* Not in EXIF 2.2 */ - {EXIF_TAG_TIFF_EP_STANDARD_ID, "TIFF/EPStandardID", N_("TIFF/EP Standard ID"), ""}, {EXIF_TAG_CUSTOM_RENDERED, "CustomRendered", N_("Custom Rendered"), N_("This tag indicates the use of special processing on image " "data, such as rendering geared to output. When special " @@ -780,7 +821,7 @@ static const struct { "indicates that digital zoom was not used."), { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, {EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM, "FocalLengthIn35mmFilm", - N_("Focal Length In 35mm Film"), + N_("Focal Length in 35mm Film"), N_("This tag indicates the equivalent focal length assuming a " "35mm film camera, in mm. A value of 0 means the focal " "length is unknown. Note that this tag differs from the " @@ -825,25 +866,66 @@ static const struct { "each image. It is recorded as an ASCII string equivalent " "to hexadecimal notation and 128-bit fixed length."), { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, - /* Not in EXIF 2.2 */ + /* EXIF 2.3 */ + {EXIF_TAG_CAMERA_OWNER_NAME, "CameraOwnerName", N_("Camera Owner Name"), + N_("This tag indicates the name of the camera owner, " + "photographer or image creator."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + /* EXIF 2.3 */ + {EXIF_TAG_BODY_SERIAL_NUMBER, "BodySerialNumber", N_("Body Serial Number"), + N_("This tag indicates the serial number of the body of the camera"), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + /* EXIF 2.3 */ + {EXIF_TAG_LENS_SPECIFICATION, "LensSpecification", N_("Lens Specification"), + N_("This tag indicates minimum focal length, " + "maximum focal length, minimum F number in the " + "minimum focal length, and minimum F number in " + "the maximum focal length."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + /* EXIF 2.3 */ + {EXIF_TAG_LENS_MAKE, "LensMake", N_("Lens Make"), + N_("This tag indicates the lens manufacturer."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + /* EXIF 2.3 */ + {EXIF_TAG_LENS_MODEL, "LensModel", N_("Lens Model"), + N_("This tag indicates the lens' model name and model number."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + /* EXIF 2.3 */ + {EXIF_TAG_LENS_SERIAL_NUMBER, "LensSerialNumber", N_("Lens Serial Number"), + N_("This tag indicates the serial number of the interchangeable lens."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + /* EXIF 2.3 */ {EXIF_TAG_GAMMA, "Gamma", N_("Gamma"), - N_("Indicates the value of coefficient gamma.")}, + N_("Indicates the value of coefficient gamma."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + /* Not in EXIF 2.2 */ {EXIF_TAG_PRINT_IMAGE_MATCHING, "PrintImageMatching", N_("PRINT Image Matching"), - N_("Related to Epson's PRINT Image Matching technology")}, + N_("Related to Epson's PRINT Image Matching technology"), + ESL_UNKNOWN}, + /* Not in EXIF 2.2 (from the Microsoft HD Photo specification) */ + {EXIF_TAG_PADDING, "Padding", N_("Padding"), + N_("This tag reserves space that can be reclaimed later when " + "additional metadata are added. New metadata can be written " + "in place by replacing this tag with a smaller data element " + "and using the reclaimed space to store the new or expanded " + "metadata tags."), + { ESL_OOOO, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, #endif - {0, NULL, NULL, NULL} + {0, NULL, NULL, NULL, ESL_UNKNOWN} }; /* For now, do not use these functions. */ -/*! \internal */ -ExifTag exif_tag_table_get_tag (unsigned int n); - -/*! \internal */ -const char *exif_tag_table_get_name (unsigned int n); +/*! + * Return the number of entries in the EXIF tag table, including the + * terminating NULL entry. + */ +unsigned int +exif_tag_table_count (void) +{ + return sizeof (ExifTagTable) / sizeof (ExifTagTable[0]); +} -/*! \internal */ -unsigned int exif_tag_table_count (void); ExifTag exif_tag_table_get_tag (unsigned int n) @@ -857,10 +939,44 @@ exif_tag_table_get_name (unsigned int n) return (n < exif_tag_table_count ()) ? ExifTagTable[n].name : NULL; } -unsigned int -exif_tag_table_count (void) +/*! + * Compares the tag with that in entry. + * \param[in] tag pointer to integer tag value + * \param[in] entry pointer to a struct TagEntry + * \return 0 if tags are equal, <0 if tag < entry, >0 if tag > entry + */ +static int +match_tag(const void *tag, const void *entry) { - return sizeof (ExifTagTable) / sizeof (ExifTagTable[0]); + return *(int*)tag - ((struct TagEntry *)entry)->tag; +} + + +/*! + * Finds the first entry in the EXIF tag table with the given tag number + * using a binary search. + * \param[in] tag to find + * \return index into table, or -1 if not found + */ +static int +exif_tag_table_first(ExifTag tag) +{ + int i; + struct TagEntry *entry = bsearch(&tag, ExifTagTable, + exif_tag_table_count()-1, sizeof(struct TagEntry), match_tag); + if (!entry) + return -1; /* Not found */ + + /* Calculate index of found entry */ + i = entry - ExifTagTable; + + /* There may be other entries with the same tag number, so search + * backwards to find the first + */ + while ((i > 0) && (ExifTagTable[i-1].tag == tag)) { + --i; + } + return i; } #define RECORDED \ @@ -873,10 +989,21 @@ const char * exif_tag_get_name_in_ifd (ExifTag tag, ExifIfd ifd) { unsigned int i; + int first; - if (ifd >= EXIF_IFD_COUNT) return NULL; - for (i = 0; ExifTagTable[i].name; i++) - if ((ExifTagTable[i].tag == tag) && RECORDED) break; + if (ifd >= EXIF_IFD_COUNT) + return NULL; + first = exif_tag_table_first(tag); + if (first < 0) + return NULL; + + for (i = first; ExifTagTable[i].name; i++) { + if (ExifTagTable[i].tag == tag) { + if (RECORDED) + break; + } else + return NULL; /* Recorded tag not found in the table */ + } return ExifTagTable[i].name; } @@ -884,18 +1011,22 @@ const char * exif_tag_get_title_in_ifd (ExifTag tag, ExifIfd ifd) { unsigned int i; + int first; - /* FIXME: This belongs to somewhere else. */ - /* libexif should use the default system locale. - * If an application specifically requires UTF-8, then we - * must give the application a way to tell libexif that. - * - * bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - */ - bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); - if (ifd >= EXIF_IFD_COUNT) return NULL; - for (i = 0; ExifTagTable[i].title; i++) - if ((ExifTagTable[i].tag == tag) && RECORDED) break; + if (ifd >= EXIF_IFD_COUNT) + return NULL; + first = exif_tag_table_first(tag); + if (first < 0) + return NULL; + + for (i = first; ExifTagTable[i].name; i++) { + if (ExifTagTable[i].tag == tag) { + if (RECORDED) + break; + } else + return NULL; /* Recorded tag not found in the table */ + } + (void) bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); return _(ExifTagTable[i].title); } @@ -903,6 +1034,25 @@ const char * exif_tag_get_description_in_ifd (ExifTag tag, ExifIfd ifd) { unsigned int i; + int first; + + if (ifd >= EXIF_IFD_COUNT) + return NULL; + first = exif_tag_table_first(tag); + if (first < 0) + return NULL; + + for (i = first; ExifTagTable[i].name; i++) { + if (ExifTagTable[i].tag == tag) { + if (RECORDED) + break; + } else + return NULL; /* Recorded tag not found in the table */ + } + + /* GNU gettext acts strangely when given an empty string */ + if (!ExifTagTable[i].description || !*ExifTagTable[i].description) + return ""; /* libexif should use the default system locale. * If an application specifically requires UTF-8, then we @@ -910,17 +1060,8 @@ exif_tag_get_description_in_ifd (ExifTag tag, ExifIfd ifd) * * bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); */ - bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); - - if (ifd >= EXIF_IFD_COUNT) return NULL; - for (i = 0; ExifTagTable[i].description; i++) - if ((ExifTagTable[i].tag == tag) && RECORDED) { - /* GNU gettext acts strangely when given an empty string */ - if (!*ExifTagTable[i].description) - return ""; - return _(ExifTagTable[i].description); - } - return NULL; + (void) bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); + return _(ExifTagTable[i].description); } @@ -934,15 +1075,16 @@ typedef const char * (*get_stuff_func) (ExifTag tag, ExifIfd ifd); static const char * exif_tag_get_stuff (ExifTag tag, get_stuff_func func) { - static const ExifIfd ifds[5] = { + /* Search IFDs in this order, in decreasing order of number of valid tags */ + static const ExifIfd ifds[EXIF_IFD_COUNT] = { + EXIF_IFD_EXIF, EXIF_IFD_0, EXIF_IFD_1, - EXIF_IFD_EXIF, EXIF_IFD_INTEROPERABILITY, EXIF_IFD_GPS }; int i; - for (i=0; i<5; i++) { + for (i=0; i= EXIF_IFD_COUNT) + return EXIF_SUPPORT_LEVEL_UNKNOWN; - if (ifd >= EXIF_IFD_COUNT) return EXIF_SUPPORT_LEVEL_UNKNOWN; - if (t >= EXIF_DATA_TYPE_COUNT) return EXIF_SUPPORT_LEVEL_UNKNOWN; + if (t >= EXIF_DATA_TYPE_COUNT) + return get_support_level_any_type (tag, ifd); - for (i = 0; ExifTagTable[i].description; i++) - if ((ExifTagTable[i].tag == tag) && - (ExifTagTable[i].esl[ifd][t] != EXIF_SUPPORT_LEVEL_NOT_RECORDED)) - return ExifTagTable[i].esl[ifd][t]; - return EXIF_SUPPORT_LEVEL_NOT_RECORDED; + return get_support_level_in_ifd (tag, ifd, t); }