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 the PhotoshopExamples/ directory on the github page

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.moveLayer("Group/NestedGroup/Image", "Group");

// Delete the now empty group from the document
layeredFile.removeLayer("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.addLayer(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. Keep in mind that some of these are not fully implemented yet

Conversion Functions#

template<typename T>
std::unique_ptr<PhotoshopFile> LayeredToPhotoshopFile(LayeredFile<T> &&layeredFile)#

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>> findLayerAs(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>::findLayer() 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 an error is raised.

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> getData() const noexcept#

Return a copy of the ICC profile data.

inline uint32_t getDataSize() 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

LayeredFile(std::unique_ptr<PhotoshopFile> file)#

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

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

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 findLayer().

Parameters:

layer – The layer to be added.

void moveLayer(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).

void moveLayer(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).

void removeLayer(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.

void removeLayer(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.

void setCompression(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

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

Generates a flat layer stack from either the current root or a given layer.

Generate a flat layer stack from either the current root or (if supplied) from the given layer. Use this function if you wish to get the most up to date flat layer stack that is in the given

Use this function to get the most up-to-date flat layer stack based on the given order.

Parameters:
  • layer – Optional layer to start the generation from (default is root).

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

Returns:

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

uint16_t getNumChannels(bool ignoreMaskChannels = true, bool ignoreAlphaChannel = true)#

Gets the total number of channels in the document.

Excludes mask channels unless ignoreMaskChannels is set to false. Same goes for ignoreAlphaChannel

Parameters:
  • ignoreMaskChannels – Flag to exclude mask channels from the count.

  • ignoreMaskChannel – Flag to exclude the transparency alpha channel from the count.

Returns:

The total number of channels in the document.

bool isLayerInDocument(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.

Public Members

std::vector<std::shared_ptr<Layer<T>>> m_Layers#

The root layers in the file, they may contain multiple levels of sub-layers.

ICCProfile m_ICCProfile#

The ICC Profile associated with the file, this may be empty in which case there will be no colour profile associated with the file

float m_DotsPerInch = 72.0f#

The DPI of the document, this will only change the display unit and wont resize any data.

Enum::BitDepth m_BitDepth = Enum::BitDepth::BD_8#

The bit depth of the file.

Enum::ColorMode m_ColorMode = Enum::ColorMode::RGB#

The color mode of the file. Currently supports RGB only.

uint64_t m_Width = 0u#

The width of the file in pixels. Can be up to 30,000 for PSD and up to 300,000 for PSB.

uint64_t m_Height = 0u#

The height of the file in pixels. Can be up to 30,000 for PSD and up to 300,000 for PSB.

Public Static Functions

static 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 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’