## ZPB-EXIF - access to digital image Exif data for Common Lisp

> ### Abstract

> Exif is a standard for embedding information in an image file created by a digital camera. ZPB-EXIF is a library that makes Exif data accessible to Common Lisp programs. It is available under a BSD-like license. For more info about Exif, see Exif.org. The latest version is 1.2.4, released on June 3rd, 2020.

> Download shortcut: http://www.xach.com/lisp/zpb-exif.tgz

### Contents

1. Overview
2. Example
3. Terms
4. The ZPB-EXIF Dictionary
   1. `make-exif`
   2. `exif-value`
   3. `parsed-exif-value`
   4. `exif-alist`
   5. `ifd-alist`
   6. `ifd-entry`
   7. `entry-value`
   8. `parsed-entry-value`
   9. `image-ifd`
   10. `exif-ifd`
   11. `gps-ifd`
   12. `interoperability-ifd`
   13. `thumbnail-ifd`
   14. `exif-data`
   15. `thumbnail-image`
   16. `invalid-stream`
   17. `invalid-jpeg-stream`
   18. `invalid-exif-stream`
5. Parsed Values
   1. Image IFD
   2. Exif IFD
6. Feedback

### Overview

Exif data is structured like so:

- data about an image is separated into multiple sections called image file directories or IFDs
- each IFD contains one or more key/value pairs called IFD entries; the key is also called the tag
- there are two mandatory IFDs for an Exif image: the image IFD and the Exif IFD
- there are a number of optional IFDs: the GPS IFD, the interoperability IFD, the thumbnail IFD
  - the thumbnail IFD may also have separate GPS and interoperability IFDs, but these are not supported by ZPB-EXIF

ZPB-EXIF provides access to key/value lookup through an object created from an Exif file or stream. It provides quick access to image, Exif, and GPS IFD values, and indirect access to other IFDs and their key/value entries.

### Example

    > (defparameter *exif* (make-exif #p"gg_gps.jpg"))
    => *EXIF*

    > (exif-value "FNumber" *exif*)
    => 9/2

    > (parsed-exif-value "MeteringMode" *exif*)
    => :PATTERN

    > (exif-value :DateTimeOriginal *exif*)
    => "2003:11:23 18:07:37"

    > (exif-value #x0112 *exif*)   ; #x0112 => orientation tag in the image IFD
    => 6

    > (parsed-exif-value #x0112 *exif*)
    => :ROTATED-270

    > (exif-value :ISOSpeedRating *exif*)   ; Field not present in this particular image
    => NIL

    > (list (exif-value "GPSLatitude" *exif*)
            (exif-value "GPSLatitudeRef" *exif*)
            (exif-value "GPSLongitude" *exif*)
            (exif-value "GPSLongitudeRef" *exif*))
    => (#(39 54 56) "N" #(116 23 27) "E")

### Terms

tag
  an integer that refers to a unique field in a specific IFD. For example, the integer #x0001 represents the `InteroperabilityIndex` field in the interoperability IFD and the `GPSVersionID` field in the GPS IFD
tag designator
  an object representing a tag and that is one of: a string (denoting a tag named by the string for a given IFD), a symbol (denoting a tag named by the string that is its name), or a tag (denoting itself)

### The ZPB-EXIF Dictionary

[Function]
make-exif exif-stream-designator => exif

> Returns an exif object. exif-stream-designator may be a stream (designating itself), a pathname (designating the stream created by opening the file), or a string (treated the same as a pathname). If exif-stream-designator does not refer to a JPEG, signals an `invalid-jpeg-stream` error. If exif-stream-designator refers to a JPEG, but the JPEG does not contain any Exif data, signals an `invalid-exif-stream` error.

[Function]
exif-value tag-designator exif => value

> Returns the value of the field identified by tag-designator from the image IFD, Exif IFD, or GPS IFD.

[Function]
parsed-exif-value tag-designator exif => parsed-value

> Returns an the value of the field identified by tag-designator from the image IFD, Exif IFD, or GPS IFD in parsed form.

[Function]
exif-alist exif `&key` parsedp => alist

> Returns an association list that has tag names for keys and IFD entry values for values for all entries in the image, Exif, and GPS IFDs in exif. If parsedp is true, the IFD entry values are in parsed form.

[Function]
ifd-alist exif `&key` parsedp => alist

> Returns an association list that has tag names for keys and IFD entry values for values for the entries ifd. If parsedp is true, the IFD entry values are in parsed form.

[Function]
ifd-entry tag-designator ifd => ifd-entry

> Returns the IFD entry identified by tag-designator in ifd, or NIL if no IFD entry could be found.

[Function]
entry-value ifd-entry => value

> Returns the value of ifd-entry.

[Function]
parsed-entry-value ifd-entry => value

> Returns the value of ifd-entry in parsed form.

[Function]
image-ifd exif => ifd

> Returns the image IFD for exif. The following tags may be available in the image IFD:

> Tag | Name | Data Type
> --- | --- | ---
> Tags Relating to Image Data Structure
> #x0100 | ImageWidth | short or long
> #x0101 | ImageHeight | short or long
> #x0102 | BitsPerSample | short
> #x0103 | Compression | short
> #x0106 | PhotometricInterpretation | short
> #x0112 | Orientation | short
> #x0115 | SamplesPerPixel | short
> #x011C | PlanarConfiguration | short
> #x0212 | YCbCrSubSampling | short
> #x0213 | YCbCrPositioning | short
> #x011A | XResolution | rational
> #x011B | YResolution | rational
> #x0128 | ResolutionUnit | short
> Tags Relating to Recording Offsets
> #x0111 | StripOffsets | short or long
> #x0116 | RowsPerStrip | short or long
> #x0117 | StripByteCounts | short or long
> #x0201 | JPEGInterchangeFormat | long
> #x0202 | JPEGInterchangeFormatLength | long
> Tags Relating to Image Data Characteristics
> #x012D | TransferFunction | short
> #x013E | WhitePoint | rational
> #x013F | PrimaryChromaticities | rational
> #x0211 | YCbCrCoefficients | rational; parsed value available
> #x0214 | ReferenceBlackWhite | rational
> Other Tags
> #x0132 | DateTime | ascii; parsed value available
> #x010E | ImageDescription | ascii
> #x010F | Make | ascii
> #x0110 | Model | ascii
> #x0131 | Software | ascii
> #x013B | Artist | ascii
> #x8298 | Copyright | ascii

[Function]
exif-ifd exif => ifd

> Returns the Exif IFD for exif. The following tags may be available in the exif IFD:

> Tag | Name | Data Type
> --- | --- | ---
> Tags Relating to Version
> #x9000 | ExifVersion | undefined; parsed value available
> #xA000 | FlashpixVersion | undefined
> Tags Relating to Image Data Characteristics
> #xA001 | ColorSpace | short; parsed value available
> #xA001 | Gamma | rational; parsed value available
> #x9101 | ComponentsConfiguration | undefined
> #x9102 | CompressedBitsPerPixel | rational
> #xA002 | PixelXDimension | short or long
> #xA003 | PixelYDimension | short or long
> Tags Relating to User Information
> #x927C | MakerNote | undefined
> #x9286 | UserComment | undefined; parsed value available
> #xA004 | RelatedSoundFile | ascii
> Tags Relating to Date and Time
> #x9003 | DateTimeOriginal | ascii; parsed value available
> #x9004 | DateTimeDigitized | ascii; parsed value available
> #x9290 | SubSecTime | ascii
> #x9291 | SubSecTimeOriginal | ascii
> #x9292 | SubSecTimeDigitized | ascii
> Tags Relating to Picture Taking Conditions
> #x829A | ExposureTime | rational; parsed value available
> #x829D | FNumber | rational; parsed value available
> #x8822 | ExposureProgram | rational; parsed value available
> #x8824 | SpectralSensitivity | ascii
> #x8827 | ISOSpeedRatings | short
> #x8828 | OECF | undefined
> #x9201 | ShutterSpeedValue | srational; parsed value available
> #x9202 | ApertureValue | rational; parsed value available
> #x9203 | BrightnessValue | srational
> #x9204 | ExposureBiasValue | srational
> #x9205 | MaxApertureValue | rational; parsed value available
> #x9206 | SubjectDistance | rational; parsed value available
> #x9207 | MeteringMode | short; parsed value available
> #x9208 | LightSource | short; parsed value available
> #x9209 | Flash | short; parsed value available
> #x920A | FocalLength | rational; parsed value available
> #x9214 | SubjectArea | short
> #xA20B | FlashEngergy | rational
> #xA20C | SpatialFrquencyResponse | undefined
> #xA20E | FocalPlaneXResolution | rational; parsed value available
> #xA20F | FocalPlaneYResolution | rational; parsed value available
> #xA210 | FocalPlaneResolutionUnit | short
> #xA214 | SubjectLocation | short
> #xA215 | ExposureIndex | rational
> #xA217 | SensingMethod | short; parsed value available
> #xA300 | FileSource | undefined
> #xA301 | SceneType | undefined
> #xA302 | CFAPattern | undefined
> #xA401 | CustomRendered | short
> #xA402 | ExposureMode | short; parsed value available
> #xA403 | WhiteBalance | short; parsed value available
> #xA404 | DigitalZoomRatio | rational
> #xA405 | FocalLengthIn35mmFilm | short
> #xA406 | SceneCaptureType | short; parsed value available
> #xA407 | GainControl | rational; parsed value available
> #xA408 | Contrast | short; parsed value available
> #xA409 | Saturation | short; parsed value available
> #xA40A | Sharpness | short; parsed value available
> #xA40B | DeviceSettingDescription | undefined
> #xA40C | SubjectDistanceRange | short
> #xA420 | ImageUniqueID | ascii

[Function]
gps-ifd exif => ifd

> Returns the GPS IFD for exif.

> The following tags are available in the GPS IFD:

> Tag | Name | Data Type
> --- | --- | ---
> #x0000 | GPSVersionID | byte
> #x0001 | GPSLatitudeRef | ascii
> #x0002 | GPSLatitude | rational
> #x0003 | GPSLongitudeRef | ascii
> #x0004 | GPSLongitude | ascii
> #x0005 | GPSAltitudeRef | byte
> #x0006 | GPSAltitude | rational
> #x0007 | GPSTimeStamp | rational
> #x0008 | GPSSatellites | ascii
> #x0009 | GPSStatus | ascii
> #x000A | GPSMeasureMode | ascii
> #x000B | GPSDOP | rational
> #x000C | GPSSpeedRef | ascii
> #x000D | GPSSpeed | rational
> #x000E | GPSTrackRef | ascii
> #x000F | GPSTrack | rational
> #x0010 | GPSImgDirectionRef | ascii
> #x0011 | GPSImgDirection | rational
> #x0012 | GPSMapDatum | ascii
> #x0013 | GPSDestLatitudeRef | ascii
> #x0014 | GPSDestLatitude | rational
> #x0015 | GPSDestLongitudeRef | ascii
> #x0016 | GPSDestLongitude | rational
> #x0017 | GPSDestBearingRef | ascii
> #x0018 | GPSDestBearing | rational
> #x0019 | GPSDestDistanceRef | ascii
> #x001A | GPSDestDistance | rational

[Function]
interoperability-ifd exif => ifd

> Returns the interoperability IFD for exif.

[Function]
thumbnail-ifd exif => ifd

> Returns the thumbnail IFD for exif. The tags available are the same as for the image IFD.

[Function]
exif-data exif => value

> Returns a vector of `(unsigned-byte 8)` data representing all the data in the Exif section of the stream from which exif was created.

[Function]
thumbnail-image exif => value

> Returns a vector of `(unsigned-byte 8)` data representing the embedded Exif thumbnail of exif, or NIL if no Exif thumbnail is present.

[Condition]
invalid-stream

> This error condition is a supertype of Exif stream conditions.

[Condition]
invalid-jpeg-stream

> This condition is signalled when a stream being processed is not a JPEG stream. It is a subtype of invalid-stream.

[Condition]
invalid-exif-stream

> This condition is signalled when a stream being processed is not an Exif stream. It is a subtype of invalid-stream.

### Parsed Values

When using `parsed-exif-value`, the following IFD/tag combinations are converted from the "raw" Exif value into a more processing-friendly format. All others return the same value that would be returned by `exif-value`

#### Image IFD

- YCbCrSubsampling: returns one of `:CENTERED`, `:CO-SITED`, or `:RESERVED`
- DateTime: returns a universal time

#### Exif IFD

- ExifVersion: returns a string representing the version, e.g. "2.1", "2.2", "2.21"
- ColorSpace: returns one of `:SRGB`, `:UNCALIBRATED`, or `:RESERVED`
- Gamma: returns a float
- UserComment: if the UserComment is in ASCII or Undefined format, returns a string representing the comment
- DateTimeOriginal: returns a universal time
- DateTimeDigitized: returns a universal time
- ExposureTime: returns a float
- FNumber: returns a float
- ExposureProgram: returns one of `:NOT-DEFINED`, `:MANUAL`, `:NORMAL-PROGRAM`, `:APERTURE-PRIORITY`, `:SHUTTER-PRIORITY`, `:CREATIVE-PROGRAM`, `:ACTION-PROGRAM`, `:PORTRAIT-MODE`, `:LANDSCAPE-MODE`, or `:RESERVED`
- ShutterSpeedValue: returns a float
- ApertureValue: returns a float
- MaxApertureValue: returns a float
- SubjectDistance: returns a float
- MeteringMode: returns one of `:UNKNOWN`, `:AVERAGE`, `:CENTER-WEIGHTED-AVERAGE`, `:SPOT`, `:MULTISPOT`, `:PATTERN`, `:PARTIAL`, `:OTHER`, or `:RESERVED`
- LightSource: returns one of `:UNKNOWN`, `:DAYLIGHT`, `:FLOURESCENT`, `:TUNGSTEN`, `:FLASH`, `:FINE-WEATHER`, `:CLOUDY-WEATHER`, `:SHADE`, `:DAYLIGHT-FLOURESCENT`, `:DAY-WHITE-FLOURESCENT`, `:COOL-WHITE-FLOURESCENT`, `:WHITE-FLOURESCENT`, `:STANDARD-LIGHT-A`, `:STANDARD-LIGHT-B`, `:STANDARD-LIGHT-C`, `:D55`, `:D65`, `:D75`, `:D50`, `:ISO-STUDIO-TUNGSTEN`, `:OTHER-LIGHT-SOURCE`, or `:RESERVED`.
- Flash: returns T if the flash fired
- FocalLength: returns a float
- FocalPlaneXResolution: returns a float
- FocalPlaneYResolution: returns a float
- SensingMethod: returns one of `:NOT-DEFINED`, `:ONE-CHIP-COLOR-AREA-SENSOR`, `:TWO-CHIP-COLOR-AREA-SENSOR`, `:THREE-CHIP-COLOR-AREA-SENSOR`, `:COLOR-SEQUENTIAL-AREA-SENSOR`, `:TRILINEAR-SENSOR`, `:COLOR-SEQUENTIAL-LINEAR-SENSOR`, or `:RESERVED`
- ExposureMode: returns one of `:AUTO-EXPOSURE`, `:MANUAL-EXPOSURE`, `:AUTO-BRACKET`, or `:RESERVED`
- WhiteBalance: returns one of `:AUTO`, `:MANUAL`, or `:RESERVED`
- SceneCaptureType: returns one of `:STANDARD`, `:LANDSCAPE`, `:PORTRAIT`, `:NIGHT-SCENE`, or `:RESERVED`
- Contrast: returns one of `:NORMAL`, `:SOFT`, `:HARD`, or `:RESERVED`
- Saturation: returns one of `:NORMAL`, `:LOW-SATURATION`, `:HIGH-SATURATION`, or `:RESERVED`
- Sharpness: returns one of `:NORMAL`, `:SOFT`, `:HARD`, or `:RESERVED`

### Feedback

This library was created by Zachary Beane. For questions, comments, bug reports, and patches, please email him.

$Header: /home/cvs/zpb-exif/zpb-exif.html,v 1.5 2009/09/08 17:16:34 xach Exp $