Structure Description: LayeredFile#

The LayeredFile struct is the primary interface for editing Photoshop Files. It creates an abstraction over the actual implementation and provides more high level control over the Photoshop binary file format. It makes modifying a layer structure very convenient and as we are just shuffling pointers around internally also very efficient

Usage#

The code snippets below show some examples of how one would generally use a LayeredFile. For more detailed examples please visit Examples

Read from disk and modify#
using namespace NAMESPACE_PSAPI;

LayeredFile<bpp16_t> layeredFile = LayeredFile<bpp16_t>::read("InFile.psd");

// Move a layer one level up in the hierarchy
layeredFile.move_layer("Group/NestedGroup/Image", "Group");

// Delete the now empty group from the document
layeredFile.remove_layer("Group/NestedGroup");

// We can now convert the LayeredFile to a PhotoshopFile and write it out (this is done internally
// but can be exposed, see the ExtendedSignature example for more information)
LayeredFile<bpp16_t>::write(std::move(layeredFile), "OutFile.psd");
Initialize, modify and write#
using namespace PhotoshopAPI;

const static uint32_t width = 64u;
const static uint32_t height = 64u;

LayeredFile<bpp8_t> document = { Enum::ColorMode::RGB, width, height };

// Create our individual channels to add to our image layer. Keep in mind that all these 3 channels
// need to be specified for RGB mode
std::unordered_map <Enum::ChannelID, std::vector<bpp8_t>> channelMap;
channelMap[Enum::ChannelID::Red] = std::vector<bpp8_t>(width * height, 255u);
channelMap[Enum::ChannelID::Green] = std::vector<bpp8_t>(width * height, 0u);
channelMap[Enum::ChannelID::Blue] = std::vector<bpp8_t>(width * height, 0u);

ImageLayer<bpp8_t>::Params layerParams = {};
layerParams.layerName = "Layer Red";
layerParams.width = width;
layerParams.height = height;

auto layer = std::make_shared<ImageLayer<bpp8_t>>(std::move(channelMap), layerParams);
document.add_layer(layer);

LayeredFile<bpp8_t>::write(std::move(layeredFile), "OutFile.psd");

Layer Type Derivatives#

Below you can find a list of layers that one is able to add to the LayeredFile instance.

Conversion Functions#

template<typename T>
std::unique_ptr<PhotoshopFile> layered_to_photoshop(LayeredFile<T> &&layered_file, std::filesystem::path file_path)#

Converts a layeredFile into a PhotoshopFile, taking ownership of and invalidating any data.

Note

This will not fill any specific TaggedBlocks or ResourceBlocks beyond what is required to create the layer structure.


Find Layer as specific type#

template<typename T, template<typename X> class LayerType>
std::shared_ptr<LayerType<T>> find_layer_as(const std::string path, const LayeredFile<T> &layeredFile)#

Finds a layer based on the given path and casts it to the given type.

This function matches LayeredFile<T>::find_layer() but instead of returning a generic layer basetype we return the requested type (if the cast is valid), this is especially useful if the layer type is known ahead of time and is the preferred way of accessing a layer.

Example call:

LayeredFile<bpp8_t> layeredFile{};  // We assume this is already populated
auto imageLayerPtr = findLayerAs<bpp8_t, ImageLayer>("Path/To/ImageLayer", layeredFile);

The path should be separated by forward slashes, e.g., “Group1/GroupNested/ImageLayer”. Returns a reference to the specific layer if found; otherwise, returns nullptr and issues a warning. If we cannot upcast to the specified ptr a warning is raised and nullptr is returned.

Parameters:
  • path – The path to the layer.

  • layeredFile – the file to search from

Returns:

A shared pointer to the found layer or nullptr.


ICC Profile Struct#

struct ICCProfile#

Helper Structure for loading an ICC profile from memory of disk. Photoshop will then store the raw bytes of the ICC profile in their ICCProfile ResourceBlock (ID 1039)

Public Functions

inline ICCProfile()#

Initialize an empty ICCProfile.

inline ICCProfile(std::vector<uint8_t> data)#

Initialize the ICCProfile by passing in a raw byte array of an ICC profile.

ICCProfile(const std::filesystem::path &pathToICCFile)#

Initialize the ICCProfile by loading the path contents from disk.

inline std::vector<uint8_t> data() const noexcept#

Return a copy of the ICC profile data.

inline uint32_t data_size() const noexcept#

Return the absolute size of the data.


LayeredFile Struct#

template<typename T>
struct LayeredFile#

Represents a layered file structure.

This struct defines a layered file structure, where each file contains a hierarchy of layers. Layers can be grouped and organized within this structure.

Template Parameters:

T – The data type used for pixel values in layers (e.g., uint8_t, uint16_t, float32_t).

Public Functions

inline std::vector<std::shared_ptr<Layer<T>>> &layers() noexcept#

layers The Files’ child layers

inline void layers(std::vector<std::shared_ptr<Layer<T>>> layer_vec) noexcept#
inline ICCProfile icc_profile() const noexcept#

The files’ ICC Profile

The ICC Profile defines the view transform on the file but does not actually apply any color conversion. If you wish to actually convert your colors you should instead use something like lcms2

inline void icc_profile(ICCProfile profile) noexcept#
inline float &dpi() noexcept#

The files’ dots per inch (dpi) resolution.

inline float dpi() const noexcept#
inline void dpi(float resolution)#
inline uint64_t &width() noexcept#

The files’ width from 1 - 300,000.

inline uint64_t width() const noexcept#
inline void width(uint64_t file_width)#
inline uint64_t &height() noexcept#

The files’ height from 1 - 300,000.

inline uint64_t height() const noexcept#
inline void height(uint64_t file_height)#
inline Geometry::BoundingBox<double> bbox() const noexcept#

Retrieve the bounding box describing the canvas, will always have a minimum of 0, 0.

inline Enum::ColorMode &colormode() noexcept#

The files’ colormode.

Currently we only fully support RGB, CMYK and Greyscale.

inline Enum::ColorMode colormode() const noexcept#
inline void colormode(Enum::ColorMode color_mode) noexcept#
inline Enum::BitDepth bitdepth() const noexcept#

The files’ bitdepth.

As this is managed by the template type T we do not actually allow users to set this.

inline std::shared_ptr<LinkedLayers<T>> linked_layers() noexcept#

Primarily for internal use or advanced users. Users should usually not have to touch this as it’s handled for them by SmartObjects themselves

LinkedLayers describe a global state of linked files. Their purpose is to store the raw image data of smart objects such that any layer can have different resolution than the smart object and for deduplication.

inline const std::shared_ptr<LinkedLayers<T>> linked_layers() const noexcept#
inline std::vector<std::shared_ptr<TaggedBlock>> unparsed_blocks() const noexcept#

Primarily for internal use or advanced users.

Returns any unparsed blocks (tagged blocks that have no explicit parser yet) for roundtripping purposes.

LayeredFile() = default#
inline LayeredFile(std::unique_ptr<PhotoshopFile> file, std::filesystem::path file_path)#

Constructs a LayeredFile instance from a Photoshop file.

Takes ownership of the provided Photoshop file, transferring from a flat layer hierarchy to a layered file using the lrSectionDivider taggedBlock to identify layer breaks.

Parameters:
  • file – The PhotoshopFile to transfer

  • file_path – The path to the photoshop file

inline LayeredFile(Enum::ColorMode colorMode, uint64_t width, uint64_t height)#
requires std

Constructs an empty LayeredFile object.

Creates a LayeredFile with the specified color mode, width, and height.

Finds a layer based on the given path. The path should be separated by forward slashes, e.g., “Group1/GroupNested/ImageLayer”. Returns a reference to the specific layer if found; otherwise, returns nullptr and issues a warning.

Inserts a layer into the root of the layered file.

If you wish to add a layer to a group, use GroupLayer::addLayer() on a group node retrieved by \ref find_layer().

\param layer The layer to be added.

Parameters:
  • colorMode – The color mode of the file.

  • width – The width of the file in pixels.

  • height – The height of the file in pixels.

  • path – The path to the layer.

Returns:

A shared pointer to the found layer or nullptr.

inline void move_layer(std::shared_ptr<Layer<T>> layer, std::shared_ptr<Layer<T>> parentLayer = nullptr)#

Moves a layer from its current parent to a new parent node.

If no parentLayer is provided, moves the layer to the root. If the parentLayer is found to be under the layer it will issue a warning and stop the insertion. I.e. if moving “/Group” to “/Group/GroupNested/” that would be an illegal move operation as well as moving a layer to itself

Parameters:
  • layer – The layer to be moved.

  • parentLayer – The new parent layer (if not provided, moves to the root).

inline void move_layer(const std::string layer, const std::string parentLayer = "")#

Moves a layer from its current parent to a new parent node.

If no parentLayer is provided, moves the layer to the root. If the parentLayer is found to be under the layer it will issue a warning and stop the insertion. I.e. if moving “/Group” to “/Group/GroupNested/” that would be an illegal move operation as well as moving a layer to itself

Parameters:
  • layer – The layer to be moved.

  • parentLayer – The new parent layer (if not provided, moves to the root).

inline void remove_layer(std::shared_ptr<Layer<T>> layer)#

Recursively removes a layer from the layer structure.

Iterates the layer structure until the given node is found and then removes it from the tree.

Parameters:

layer – The layer to be removed.

inline void remove_layer(const std::string layer)#

Recursively removes a layer from the layer structure.

Iterates the layer structure until the given node is found and then removes it from the tree.

Parameters:

layer – The layer to be removed.

inline void set_compression(const Enum::Compression compCode)#

change the compression codec across all layers and channels

Iterates the layer structure and changes the compression codec for write on all layers. This is especially useful for e.g. 8-bit files which from Photoshop write with RLE compression but ZipCompression gives us better ratios

Parameters:

compCode – the compression codec to apply

inline std::vector<std::shared_ptr<Layer<T>>> flat_layers(std::optional<std::shared_ptr<Layer<T>>> layer, const LayerOrder order) const#

Generate a flat layer stack from either the current root or (if supplied) from the given layer. It should be preferred to use flat_layers() (no arguments) instead of this function.

Parameters:
  • layer – Optional layer to start the generation from (default is root). If you provide e.g. a group this will only build the below layer tree

  • order – The order in which layers should be stacked.

Returns:

The flat layer tree with automatic SectionDividerLayer inserted to mark section ends

inline std::vector<std::shared_ptr<Layer<T>>> flat_layers()#

Get a view over the flattened layer stack, helpful for iterating and applying properties to all layers such as visibility overrides etc.

After any layer modification actions this list may no longer be up-to-date so it would have to be re-generated. It is highly discouraged to use this flattened layer vector for any layer hierarchy modifications

Returns:

The layer hierarchy as a flattened vector that can be iterated over.

inline uint16_t num_channels()#

Gets the total number of channels in the document.

Returns:

The total number of channels in the document.

inline bool is_layer_in_file(const std::shared_ptr<Layer<T>> layer) const#

Checks if a layer already exists in the nested structure.

Parameters:

layer – The layer to check for existence.

Returns:

True if the layer exists, false otherwise.

inline void invalidate_text_cache()#

Remove the global Txt2 (TextEngineData) block to trigger Photoshop’s text update dialog.

The global Txt2 block is a document-level cache token that Photoshop uses to decide whether text layers are up-to-date. After removing it, Photoshop detects the mismatch on open and immediately shows the “Update text layers?” prompt. Clicking Update re-renders every text layer from the TySh metadata, giving you a fully rendered, editable text document in one click.

The per-layer text data (TySh / lrTypeTool) and all style information is completely unaffected by this call.

Public Static Functions

static inline LayeredFile<T> read(const std::filesystem::path &filePath, ProgressCallback &callback)#

read and create a LayeredFile from disk

Simplify the creation of a LayeredFile by abstracting away the step of PhotoshopFile -> LayeredFile doing the work internally without exposing the PhotoshopFile instance to the user

Parameters:
  • filePath – the path on disk of the file to be read

  • callback – the callback which reports back the current progress and task to the user

static inline LayeredFile<T> read(const std::filesystem::path &filePath)#

read and create a LayeredFile from disk

Simplify the creation of a LayeredFile by abstracting away the step of PhotoshopFile -> LayeredFile doing the work internally without exposing the PhotoshopFile instance to the user

Parameters:

filePath – the path on disk of the file to be read

static inline void write(LayeredFile<T> &&layeredFile, const std::filesystem::path &filePath, ProgressCallback &callback, const bool forceOvewrite = true)#

write the LayeredFile instance to disk, consumes and invalidates the instance

Simplify the writing of a LayeredFile by abstracting away the step of LayeredFile -> PhotoshopFile doing the work internally without exposing the PhotoshopFile instance to the user

Parameters:
  • layeredFile – The LayeredFile to consume, invalidates it

  • filePath – The path on disk of the file to be written

  • callback – the callback which reports back the current progress and task to the user

  • forceOvewrite – Whether to forcefully overwrite the file or fail if the file already exists

static inline void write(LayeredFile<T> &&layeredFile, const std::filesystem::path &filePath, const bool forceOvewrite = true)#

write the LayeredFile instance to disk, consumes and invalidates the instance

Simplify the writing of a LayeredFile by abstracting away the step of LayeredFile -> PhotoshopFile doing the work internally without exposing the PhotoshopFile instance to the user

Parameters:
  • layeredFile – The LayeredFile to consume, invalidates it

  • filePath – The path on disk of the file to be written

  • forceOvewrite – Whether to forcefully overwrite the file or fail if the file already exists


Layer Order Enum#

enum class LayerOrder#

Enumerator to specify the order of traversal for parsing.

Values:

enumerator forward#

Forward in this case refers to us going top to bottom. e.g. if we have the layer structure

Group
  NestedGroup
  Image
We would write out the layers starting with ‘Group’

enumerator reverse#

Reverse in this case refers to us going bottom to top. e.g. if we have the layer structure

Group
  NestedGroup
  Image
We would write out the layers starting with ‘Image’