Source code for PIL.TiffTags

#
# The Python Imaging Library.
# $Id$
#
# TIFF tags
#
# This module provides clear-text names for various well-known
# TIFF tags.  the TIFF codec works just fine without it.
#
# Copyright (c) Secret Labs AB 1999.
#
# See the README file for information on usage and redistribution.
#

##
# This module provides constants and clear-text names for various
# well-known TIFF tags.
##
from __future__ import annotations

from typing import NamedTuple


class _TagInfo(NamedTuple):
    value: int | None
    name: str
    type: int | None
    length: int | None
    enum: dict[str, int]


[docs] class TagInfo(_TagInfo): __slots__: list[str] = [] def __new__(cls, value=None, name="unknown", type=None, length=None, enum=None): return super().__new__(cls, value, name, type, length, enum or {})
[docs] def cvt_enum(self, value): # Using get will call hash(value), which can be expensive # for some types (e.g. Fraction). Since self.enum is rarely # used, it's usually better to test it first. return self.enum.get(value, value) if self.enum else value
[docs] def lookup(tag, group=None): """ :param tag: Integer tag number :param group: Which :py:data:`~PIL.TiffTags.TAGS_V2_GROUPS` to look in .. versionadded:: 8.3.0 :returns: Taginfo namedtuple, From the ``TAGS_V2`` info if possible, otherwise just populating the value and name from ``TAGS``. If the tag is not recognized, "unknown" is returned for the name """ if group is not None: info = TAGS_V2_GROUPS[group].get(tag) if group in TAGS_V2_GROUPS else None else: info = TAGS_V2.get(tag) return info or TagInfo(tag, TAGS.get(tag, "unknown"))
## # Map tag numbers to tag info. # # id: (Name, Type, Length[, enum_values]) # # The length here differs from the length in the tiff spec. For # numbers, the tiff spec is for the number of fields returned. We # agree here. For string-like types, the tiff spec uses the length of # field in bytes. In Pillow, we are using the number of expected # fields, in general 1 for string-like types. BYTE = 1 ASCII = 2 SHORT = 3 LONG = 4 RATIONAL = 5 SIGNED_BYTE = 6 UNDEFINED = 7 SIGNED_SHORT = 8 SIGNED_LONG = 9 SIGNED_RATIONAL = 10 FLOAT = 11 DOUBLE = 12 IFD = 13 LONG8 = 16 TAGS_V2 = { 254: ("NewSubfileType", LONG, 1), 255: ("SubfileType", SHORT, 1), 256: ("ImageWidth", LONG, 1), 257: ("ImageLength", LONG, 1), 258: ("BitsPerSample", SHORT, 0), 259: ( "Compression", SHORT, 1, { "Uncompressed": 1, "CCITT 1d": 2, "Group 3 Fax": 3, "Group 4 Fax": 4, "LZW": 5, "JPEG": 6, "PackBits": 32773, }, ), 262: ( "PhotometricInterpretation", SHORT, 1, { "WhiteIsZero": 0, "BlackIsZero": 1, "RGB": 2, "RGB Palette": 3, "Transparency Mask": 4, "CMYK": 5, "YCbCr": 6, "CieLAB": 8, "CFA": 32803, # TIFF/EP, Adobe DNG "LinearRaw": 32892, # Adobe DNG }, ), 263: ("Threshholding", SHORT, 1), 264: ("CellWidth", SHORT, 1), 265: ("CellLength", SHORT, 1), 266: ("FillOrder", SHORT, 1), 269: ("DocumentName", ASCII, 1), 270: ("ImageDescription", ASCII, 1), 271: ("Make", ASCII, 1), 272: ("Model", ASCII, 1), 273: ("StripOffsets", LONG, 0), 274: ("Orientation", SHORT, 1), 277: ("SamplesPerPixel", SHORT, 1), 278: ("RowsPerStrip", LONG, 1), 279: ("StripByteCounts", LONG, 0), 280: ("MinSampleValue", SHORT, 0), 281: ("MaxSampleValue", SHORT, 0), 282: ("XResolution", RATIONAL, 1), 283: ("YResolution", RATIONAL, 1), 284: ("PlanarConfiguration", SHORT, 1, {"Contiguous": 1, "Separate": 2}), 285: ("PageName", ASCII, 1), 286: ("XPosition", RATIONAL, 1), 287: ("YPosition", RATIONAL, 1), 288: ("FreeOffsets", LONG, 1), 289: ("FreeByteCounts", LONG, 1), 290: ("GrayResponseUnit", SHORT, 1), 291: ("GrayResponseCurve", SHORT, 0), 292: ("T4Options", LONG, 1), 293: ("T6Options", LONG, 1), 296: ("ResolutionUnit", SHORT, 1, {"none": 1, "inch": 2, "cm": 3}), 297: ("PageNumber", SHORT, 2), 301: ("TransferFunction", SHORT, 0), 305: ("Software", ASCII, 1), 306: ("DateTime", ASCII, 1), 315: ("Artist", ASCII, 1), 316: ("HostComputer", ASCII, 1), 317: ("Predictor", SHORT, 1, {"none": 1, "Horizontal Differencing": 2}), 318: ("WhitePoint", RATIONAL, 2), 319: ("PrimaryChromaticities", RATIONAL, 6), 320: ("ColorMap", SHORT, 0), 321: ("HalftoneHints", SHORT, 2), 322: ("TileWidth", LONG, 1), 323: ("TileLength", LONG, 1), 324: ("TileOffsets", LONG, 0), 325: ("TileByteCounts", LONG, 0), 330: ("SubIFDs", LONG, 0), 332: ("InkSet", SHORT, 1), 333: ("InkNames", ASCII, 1), 334: ("NumberOfInks", SHORT, 1), 336: ("DotRange", SHORT, 0), 337: ("TargetPrinter", ASCII, 1), 338: ("ExtraSamples", SHORT, 0), 339: ("SampleFormat", SHORT, 0), 340: ("SMinSampleValue", DOUBLE, 0), 341: ("SMaxSampleValue", DOUBLE, 0), 342: ("TransferRange", SHORT, 6), 347: ("JPEGTables", UNDEFINED, 1), # obsolete JPEG tags 512: ("JPEGProc", SHORT, 1), 513: ("JPEGInterchangeFormat", LONG, 1), 514: ("JPEGInterchangeFormatLength", LONG, 1), 515: ("JPEGRestartInterval", SHORT, 1), 517: ("JPEGLosslessPredictors", SHORT, 0), 518: ("JPEGPointTransforms", SHORT, 0), 519: ("JPEGQTables", LONG, 0), 520: ("JPEGDCTables", LONG, 0), 521: ("JPEGACTables", LONG, 0), 529: ("YCbCrCoefficients", RATIONAL, 3), 530: ("YCbCrSubSampling", SHORT, 2), 531: ("YCbCrPositioning", SHORT, 1), 532: ("ReferenceBlackWhite", RATIONAL, 6), 700: ("XMP", BYTE, 0), 33432: ("Copyright", ASCII, 1), 33723: ("IptcNaaInfo", UNDEFINED, 1), 34377: ("PhotoshopInfo", BYTE, 0), # FIXME add more tags here 34665: ("ExifIFD", LONG, 1), 34675: ("ICCProfile", UNDEFINED, 1), 34853: ("GPSInfoIFD", LONG, 1), 36864: ("ExifVersion", UNDEFINED, 1), 37724: ("ImageSourceData", UNDEFINED, 1), 40965: ("InteroperabilityIFD", LONG, 1), 41730: ("CFAPattern", UNDEFINED, 1), # MPInfo 45056: ("MPFVersion", UNDEFINED, 1), 45057: ("NumberOfImages", LONG, 1), 45058: ("MPEntry", UNDEFINED, 1), 45059: ("ImageUIDList", UNDEFINED, 0), # UNDONE, check 45060: ("TotalFrames", LONG, 1), 45313: ("MPIndividualNum", LONG, 1), 45569: ("PanOrientation", LONG, 1), 45570: ("PanOverlap_H", RATIONAL, 1), 45571: ("PanOverlap_V", RATIONAL, 1), 45572: ("BaseViewpointNum", LONG, 1), 45573: ("ConvergenceAngle", SIGNED_RATIONAL, 1), 45574: ("BaselineLength", RATIONAL, 1), 45575: ("VerticalDivergence", SIGNED_RATIONAL, 1), 45576: ("AxisDistance_X", SIGNED_RATIONAL, 1), 45577: ("AxisDistance_Y", SIGNED_RATIONAL, 1), 45578: ("AxisDistance_Z", SIGNED_RATIONAL, 1), 45579: ("YawAngle", SIGNED_RATIONAL, 1), 45580: ("PitchAngle", SIGNED_RATIONAL, 1), 45581: ("RollAngle", SIGNED_RATIONAL, 1), 40960: ("FlashPixVersion", UNDEFINED, 1), 50741: ("MakerNoteSafety", SHORT, 1, {"Unsafe": 0, "Safe": 1}), 50780: ("BestQualityScale", RATIONAL, 1), 50838: ("ImageJMetaDataByteCounts", LONG, 0), # Can be more than one 50839: ("ImageJMetaData", UNDEFINED, 1), # see Issue #2006 } TAGS_V2_GROUPS = { # ExifIFD 34665: { 36864: ("ExifVersion", UNDEFINED, 1), 40960: ("FlashPixVersion", UNDEFINED, 1), 40965: ("InteroperabilityIFD", LONG, 1), 41730: ("CFAPattern", UNDEFINED, 1), }, # GPSInfoIFD 34853: { 0: ("GPSVersionID", BYTE, 4), 1: ("GPSLatitudeRef", ASCII, 2), 2: ("GPSLatitude", RATIONAL, 3), 3: ("GPSLongitudeRef", ASCII, 2), 4: ("GPSLongitude", RATIONAL, 3), 5: ("GPSAltitudeRef", BYTE, 1), 6: ("GPSAltitude", RATIONAL, 1), 7: ("GPSTimeStamp", RATIONAL, 3), 8: ("GPSSatellites", ASCII, 0), 9: ("GPSStatus", ASCII, 2), 10: ("GPSMeasureMode", ASCII, 2), 11: ("GPSDOP", RATIONAL, 1), 12: ("GPSSpeedRef", ASCII, 2), 13: ("GPSSpeed", RATIONAL, 1), 14: ("GPSTrackRef", ASCII, 2), 15: ("GPSTrack", RATIONAL, 1), 16: ("GPSImgDirectionRef", ASCII, 2), 17: ("GPSImgDirection", RATIONAL, 1), 18: ("GPSMapDatum", ASCII, 0), 19: ("GPSDestLatitudeRef", ASCII, 2), 20: ("GPSDestLatitude", RATIONAL, 3), 21: ("GPSDestLongitudeRef", ASCII, 2), 22: ("GPSDestLongitude", RATIONAL, 3), 23: ("GPSDestBearingRef", ASCII, 2), 24: ("GPSDestBearing", RATIONAL, 1), 25: ("GPSDestDistanceRef", ASCII, 2), 26: ("GPSDestDistance", RATIONAL, 1), 27: ("GPSProcessingMethod", UNDEFINED, 0), 28: ("GPSAreaInformation", UNDEFINED, 0), 29: ("GPSDateStamp", ASCII, 11), 30: ("GPSDifferential", SHORT, 1), }, # InteroperabilityIFD 40965: {1: ("InteropIndex", ASCII, 1), 2: ("InteropVersion", UNDEFINED, 1)}, } # Legacy Tags structure # these tags aren't included above, but were in the previous versions TAGS = { 347: "JPEGTables", 700: "XMP", # Additional Exif Info 32932: "Wang Annotation", 33434: "ExposureTime", 33437: "FNumber", 33445: "MD FileTag", 33446: "MD ScalePixel", 33447: "MD ColorTable", 33448: "MD LabName", 33449: "MD SampleInfo", 33450: "MD PrepDate", 33451: "MD PrepTime", 33452: "MD FileUnits", 33550: "ModelPixelScaleTag", 33723: "IptcNaaInfo", 33918: "INGR Packet Data Tag", 33919: "INGR Flag Registers", 33920: "IrasB Transformation Matrix", 33922: "ModelTiepointTag", 34264: "ModelTransformationTag", 34377: "PhotoshopInfo", 34735: "GeoKeyDirectoryTag", 34736: "GeoDoubleParamsTag", 34737: "GeoAsciiParamsTag", 34850: "ExposureProgram", 34852: "SpectralSensitivity", 34855: "ISOSpeedRatings", 34856: "OECF", 34864: "SensitivityType", 34865: "StandardOutputSensitivity", 34866: "RecommendedExposureIndex", 34867: "ISOSpeed", 34868: "ISOSpeedLatitudeyyy", 34869: "ISOSpeedLatitudezzz", 34908: "HylaFAX FaxRecvParams", 34909: "HylaFAX FaxSubAddress", 34910: "HylaFAX FaxRecvTime", 36864: "ExifVersion", 36867: "DateTimeOriginal", 36868: "DateTimeDigitized", 37121: "ComponentsConfiguration", 37122: "CompressedBitsPerPixel", 37724: "ImageSourceData", 37377: "ShutterSpeedValue", 37378: "ApertureValue", 37379: "BrightnessValue", 37380: "ExposureBiasValue", 37381: "MaxApertureValue", 37382: "SubjectDistance", 37383: "MeteringMode", 37384: "LightSource", 37385: "Flash", 37386: "FocalLength", 37396: "SubjectArea", 37500: "MakerNote", 37510: "UserComment", 37520: "SubSec", 37521: "SubSecTimeOriginal", 37522: "SubsecTimeDigitized", 40960: "FlashPixVersion", 40961: "ColorSpace", 40962: "PixelXDimension", 40963: "PixelYDimension", 40964: "RelatedSoundFile", 40965: "InteroperabilityIFD", 41483: "FlashEnergy", 41484: "SpatialFrequencyResponse", 41486: "FocalPlaneXResolution", 41487: "FocalPlaneYResolution", 41488: "FocalPlaneResolutionUnit", 41492: "SubjectLocation", 41493: "ExposureIndex", 41495: "SensingMethod", 41728: "FileSource", 41729: "SceneType", 41730: "CFAPattern", 41985: "CustomRendered", 41986: "ExposureMode", 41987: "WhiteBalance", 41988: "DigitalZoomRatio", 41989: "FocalLengthIn35mmFilm", 41990: "SceneCaptureType", 41991: "GainControl", 41992: "Contrast", 41993: "Saturation", 41994: "Sharpness", 41995: "DeviceSettingDescription", 41996: "SubjectDistanceRange", 42016: "ImageUniqueID", 42032: "CameraOwnerName", 42033: "BodySerialNumber", 42034: "LensSpecification", 42035: "LensMake", 42036: "LensModel", 42037: "LensSerialNumber", 42112: "GDAL_METADATA", 42113: "GDAL_NODATA", 42240: "Gamma", 50215: "Oce Scanjob Description", 50216: "Oce Application Selector", 50217: "Oce Identification Number", 50218: "Oce ImageLogic Characteristics", # Adobe DNG 50706: "DNGVersion", 50707: "DNGBackwardVersion", 50708: "UniqueCameraModel", 50709: "LocalizedCameraModel", 50710: "CFAPlaneColor", 50711: "CFALayout", 50712: "LinearizationTable", 50713: "BlackLevelRepeatDim", 50714: "BlackLevel", 50715: "BlackLevelDeltaH", 50716: "BlackLevelDeltaV", 50717: "WhiteLevel", 50718: "DefaultScale", 50719: "DefaultCropOrigin", 50720: "DefaultCropSize", 50721: "ColorMatrix1", 50722: "ColorMatrix2", 50723: "CameraCalibration1", 50724: "CameraCalibration2", 50725: "ReductionMatrix1", 50726: "ReductionMatrix2", 50727: "AnalogBalance", 50728: "AsShotNeutral", 50729: "AsShotWhiteXY", 50730: "BaselineExposure", 50731: "BaselineNoise", 50732: "BaselineSharpness", 50733: "BayerGreenSplit", 50734: "LinearResponseLimit", 50735: "CameraSerialNumber", 50736: "LensInfo", 50737: "ChromaBlurRadius", 50738: "AntiAliasStrength", 50740: "DNGPrivateData", 50778: "CalibrationIlluminant1", 50779: "CalibrationIlluminant2", 50784: "Alias Layer Metadata", } def _populate(): for k, v in TAGS_V2.items(): # Populate legacy structure. TAGS[k] = v[0] if len(v) == 4: for sk, sv in v[3].items(): TAGS[(k, sv)] = sk TAGS_V2[k] = TagInfo(k, *v) for tags in TAGS_V2_GROUPS.values(): for k, v in tags.items(): tags[k] = TagInfo(k, *v) _populate() ## # Map type numbers to type names -- defined in ImageFileDirectory. TYPES: dict[int, str] = {} # # These tags are handled by default in libtiff, without # adding to the custom dictionary. From tif_dir.c, searching for # case TIFFTAG in the _TIFFVSetField function: # Line: item. # 148: case TIFFTAG_SUBFILETYPE: # 151: case TIFFTAG_IMAGEWIDTH: # 154: case TIFFTAG_IMAGELENGTH: # 157: case TIFFTAG_BITSPERSAMPLE: # 181: case TIFFTAG_COMPRESSION: # 202: case TIFFTAG_PHOTOMETRIC: # 205: case TIFFTAG_THRESHHOLDING: # 208: case TIFFTAG_FILLORDER: # 214: case TIFFTAG_ORIENTATION: # 221: case TIFFTAG_SAMPLESPERPIXEL: # 228: case TIFFTAG_ROWSPERSTRIP: # 238: case TIFFTAG_MINSAMPLEVALUE: # 241: case TIFFTAG_MAXSAMPLEVALUE: # 244: case TIFFTAG_SMINSAMPLEVALUE: # 247: case TIFFTAG_SMAXSAMPLEVALUE: # 250: case TIFFTAG_XRESOLUTION: # 256: case TIFFTAG_YRESOLUTION: # 262: case TIFFTAG_PLANARCONFIG: # 268: case TIFFTAG_XPOSITION: # 271: case TIFFTAG_YPOSITION: # 274: case TIFFTAG_RESOLUTIONUNIT: # 280: case TIFFTAG_PAGENUMBER: # 284: case TIFFTAG_HALFTONEHINTS: # 288: case TIFFTAG_COLORMAP: # 294: case TIFFTAG_EXTRASAMPLES: # 298: case TIFFTAG_MATTEING: # 305: case TIFFTAG_TILEWIDTH: # 316: case TIFFTAG_TILELENGTH: # 327: case TIFFTAG_TILEDEPTH: # 333: case TIFFTAG_DATATYPE: # 344: case TIFFTAG_SAMPLEFORMAT: # 361: case TIFFTAG_IMAGEDEPTH: # 364: case TIFFTAG_SUBIFD: # 376: case TIFFTAG_YCBCRPOSITIONING: # 379: case TIFFTAG_YCBCRSUBSAMPLING: # 383: case TIFFTAG_TRANSFERFUNCTION: # 389: case TIFFTAG_REFERENCEBLACKWHITE: # 393: case TIFFTAG_INKNAMES: # Following pseudo-tags are also handled by default in libtiff: # TIFFTAG_JPEGQUALITY 65537 # some of these are not in our TAGS_V2 dict and were included from tiff.h # This list also exists in encode.c LIBTIFF_CORE = { 255, 256, 257, 258, 259, 262, 263, 266, 274, 277, 278, 280, 281, 340, 341, 282, 283, 284, 286, 287, 296, 297, 321, 320, 338, 32995, 322, 323, 32998, 32996, 339, 32997, 330, 531, 530, 301, 532, 333, # as above 269, # this has been in our tests forever, and works 65537, } LIBTIFF_CORE.remove(255) # We don't have support for subfiletypes LIBTIFF_CORE.remove(322) # We don't have support for writing tiled images with libtiff LIBTIFF_CORE.remove(323) # Tiled images LIBTIFF_CORE.remove(333) # Ink Names either # Note to advanced users: There may be combinations of these # parameters and values that when added properly, will work and # produce valid tiff images that may work in your application. # It is safe to add and remove tags from this set from Pillow's point # of view so long as you test against libtiff.