Skip to main content Skip to navigation

Reading and writing a Photoshop TIFF

Categories:

This blog post draws on my experience adding reading and writing support for our app, and is intended to clarify the ambiguities in the official standard.

Introduction

Adobe Photoshop provides two ways to save layers: its proprietary PSD/PSB format, widely supported in imaging applications, and inside TIFF containers. The latter is not well supported; as detailed in an email to the OpenColorIO mailing list, the PSD standard is too vague and imprecise to be an useful reference in writing support for these files. Indeed, as of the writing of this post, only ImageMagick (commit, commit) provides any sort of support for this variant.

As of today, the official documentation on Photoshop TIFFs is:

  • page 11 of the “Adobe Photoshop® TIFF Technical Notes” available on the Adobe Open Standards page
  • section “Photoshop-specific TIFF Tags” in the “Adobe Photoshop File Formats Specification” of November 2019, available here.

In short, Photoshop layers are stored in tag or field 37724, identified as TIFFTAG_IMAGESOURCEDATA in the latest libtiff. The type of this tag shall be UNDEFINED, or TIFF_UNDEFINED in libtiff. The data blob shall be an array of uint8_t, and shall be headed by a magic signature that is one of the following null terminated ASCII strings:

  • for standard Photoshop files, Adobe Photoshop Document Data Block.
  • for Large Document Format (8BPB/PSB) files, Adobe Photoshop Document Data V0002 (the last five characters differ).

After the magic signature, the remainder of the blob is comprised of a series of Additional Layer Information blocks:

  • signature: 8BIM (4 bytes)
  • block type (4 bytes)
  • length of the block (4 bytes, variable, padded to a 4-byte offset)
  • data of the block (length as above)

The Technical Notes say that these are the available block types:

  • Layr (layer block)
  • LMsk (global mask info block)
  • Patt (pattern definition block)
  • Anno (annotations)

There is a second useful tag, 34377, also known as TIFFTAG_PHOTOSHOP. The type of this tag shall be BYTE (TIFF_BYTE). This is the TIFF equivalent of Photoshop’s image resource section; its contents must not be prepended by the length field, as it is already provided for by the TIFF container.

Supporting Photoshop TIFFs

Warning: The author has not seen a TIFF PSB (Photoshop Large Document Format) in the wild. A prospective developer should read the Standard and apply the PSB remarks accordingly in each paragraph.

The Photoshop standard says of its native file format:

All data is stored in big endian byte order. On the Windows platform, you must byte swap short and long integers when reading or writing.

The situation is more complex in Photoshop TIFF files. TIFFTAG_PHOTOSHOP data must be stored in big endian order. On the other hand, TIFFTAG_IMAGESOURCEDATA data must be stored in the endianness of its container. In practice, this means that existing PSD I/O routines can be reused, provided the developer byte-swaps integer and block type reading routines when interacting with a little-endian data source.

As an example, suppose a little-endian TIFF file, whose TIFFTAG_IMAGESOURCEDATA data blob starts at address 000371e8. Its format is PSD, and the first block is a Layr block of size 11463. Thus, the first 48 bytes of the data blob shall match the following:

$ xxd -s +225768 -l 48 1.tif
000371e8: 4164 6f62 6520 5068 6f74 6f73 686f 7020  Adobe Photoshop
000371f8: 446f 6375 6d65 6e74 2044 6174 6120 426c  Document Data Bl
00037208: 6f63 6b00 4d49 4238 7279 614c c72c 0000  ock.MIB8ryaL.,..

Do notice:

  • the null terminated magic signature Adobe Photoshop Document Data block
  • the MIB8 magic block signature, signaling both little endian and the start of a new info block
  • the ryaL block type, which is Layr in big endian and thus means a layer info block
  • the c72c0000, 00002cc7 in big endian, and thus 11463.

A valid Photoshop TIFF file must have a layer info block as a minimum. Its contents are described in Layer info. The type of this block shall be Layr, or one of the following (see Layer and mask information section):

  • Layr or Lr16 interchangeably, for 8-bit and 16-bit depth;
  • Lr32 for 32-bit layers.

Irrespective of the compression type, the raw channel image data in Photoshop TIFF files must be in big endian order. Prospective applications shall byteswap the channel values prior to compression and after decompression, where applicable.

The Lyid block is optional; if it is present, its value should be the position of the layer in a depth-first, left-right traversal of the layer tree.

Additional info blocks

The LMsk info block is described in Global layer mask info. It is optional; however, if it is present, its length shall not be 0. The overlay color space ID shall be one of the values described in Color space IDs, and the color components shall be the corresponding Pure color value. The opacity value shall be 50 and the kind 128.

The Patt block is optional; if it is present, the image data in the virtual memory array list must be in big endian order. Prospective applications shall byteswap the channel values prior to compression and after decompression, where applicable.

Adobe Photoshop, as of CC 2021, also outputs additional blocks. All of them are optional:

  • FMsk
  • cinf

Conclusion

Unlike its native and more widespread sibling, Photoshop TIFFs are a relatively obscure way yet portable way of exporting Photoshop layers. These are stored in the byte order of its container, except for the channel data in both layer and pattern blocks, which are stored in big endian order. A prospective developer should, given an existing suite of I/O primitives for the PSD format, be able to add support for TIFF containers with relative ease by: byteswapping all integers and block types; and ensuring channel data is always compressed and/or stored in big endian.