ImageLayer Structure#

Equivalent of Photoshops Image Layer

template<typename T>
struct ImageLayer : public Layer<T>, public WritableImageDataMixin<T>#

Masks

inline bool has_mask() const noexcept#

Checks whether the layer has a pixel mask.

Returns:

true if a mask is present, otherwise false.

inline std::vector<T> get_mask() const#

Retrieves the mask channel data, if present.

If the layer does not have a mask, this function returns an empty vector.

The returned vector contains

mask_width() * mask_height() elements.

inline void get_mask(std::span<T> buffer) const#

Fills a preallocated buffer with the mask channel data, if present.

If no mask is present, the buffer remains unchanged.

Parameters:

buffer – A preallocated buffer expected to have exactly mask_width() * mask_height() elements.

inline compressed::channel<T> extract_mask()#

Extract the compressed mask channel used internally.

Throws:

std::runtime_error – if no mask is present (as checked by has_mask).

inline void set_mask(std::span<const T> buffer, size_t width, size_t height)#

Sets the layer’s mask to the given buffer.

If no mask was previously held the inserted mask will be at the top-left of the canvas. Use mask_position to adjust this.

Parameters:
  • buffer – The image data for the mask, provided in scanline order.

  • width – The width of the new mask.

  • height – The height of the new mask.

Throws:

std::invalid_argument – If the buffer size does not match the expected dimensions.

inline void set_mask(compressed::channel<T> channel)#
inline void set_mask(const LayeredFile<T> &document, std::span<const T> buffer, std::optional<size_t> width = std::nullopt, std::optional<size_t> height = std::nullopt)#

Sets the layer’s mask to the given buffer.

If the layer previously had a mask, the new mask will be centered at the same position.

If no mask was previously present, the new mask will be centered on the document.

Parameters:
  • document – The file to which this mask layer belongs.

  • buffer – The image data for the mask, provided in scanline order. If width and height are unspecified, the buffer must have exactly mask_width() * mask_height() elements. If no dimensions are specified and the layer previously had no mask, an exception is thrown.

  • width – (Optional) The width of the new mask. Required if replacing with a differently sized mask.

  • height – (Optional) The height of the new mask. Required if replacing with a differently sized mask.

Throws:
  • std::invalid_argument – If the buffer size does not match the expected dimensions.

  • std::runtime_error – If no mask existed and no explicit dimensions were provided.

inline void set_mask_compression(Enum::Compression _compcode) noexcept#

Set the masks write compression.

If has_mask() evaluates to false this is a no-op.

Parameters:

_compcode – The compression codec to apply on-write.

inline Geometry::BoundingBox<double> mask_bbox() const#

Retrieves the bounding box of the mask, if present.

If no mask exists, this function returns a zero-sized bounding box.

Returns:

The mask’s bounding box, or an empty bounding box if no mask is present.

inline size_t mask_width() const#

Retrieves the width of the mask, if present.

If no mask exists, this function returns zero

Returns:

The mask’s width or zero if no mask exists

inline size_t mask_height() const#

Retrieves the height of the mask, if present.

If no mask exists, this function returns zero

Returns:

The mask’s height or zero if no mask exists

inline Geometry::Point2D<double> mask_position() const#

Retrieves the position of the mask, defined as its center.

If no mask is present, this function returns {-1.0, -1.0}.

Returns:

The center position of the mask, or {-1.0, -1.0} if no mask exists.

inline void mask_position(Geometry::Point2D<double> position)#

Sets the center position of the mask.

If no mask is present, this function does nothing.

Parameters:

position – The new center position of the mask.

inline bool mask_relative_to_layer()#

Checks whether the mask is relative to the layer.

Returns:

true if the mask is relative to the layer, otherwise false.

inline void mask_relative_to_layer(bool value)#

Sets whether the mask should be relative to the layer.

Parameters:

valuetrue to make the mask relative to the layer, otherwise false.

inline bool mask_disabled()#

Checks whether the mask is disabled.

Returns:

true if the mask is disabled, otherwise false.

inline void mask_disabled(bool value)#

Enables or disables the mask.

Parameters:

valuetrue to disable the mask, otherwise false.

inline uint8_t mask_default_color()#

Retrieves the mask’s default fill color.

Returns:

The default mask color.

inline void mask_default_color(uint8_t value)#

Sets the mask’s default fill color.

Parameters:

value – The new default color value.

inline std::optional<uint8_t> mask_density()#

Retrieves the mask density, if specified.

Returns:

The mask density value, or an empty optional if unspecified.

inline void mask_density(uint8_t value)#

Sets the mask density.

Parameters:

value – The new mask density.

inline void mask_density(std::optional<uint8_t> value)#

Sets the mask density, allowing for removal.

Parameters:

value – An optional new mask density.

inline std::optional<float64_t> mask_feather()#

Retrieves the mask feathering amount, if specified.

Returns:

The mask feather value, or an empty optional if unspecified.

inline void mask_feather(float64_t value)#

Sets the mask feathering amount.

Parameters:

value – The new mask feather value.

inline void mask_feather(std::optional<float64_t> value)#

Public Types

using value_type = T#

Template type accessor which can be used using decltype(layer::value_type)

using Base = ImageDataMixin<T>#

Type alias for the base class.

using channel_type = std::unique_ptr<channel_wrapper>#

Type used for a single channel.

using image_type = std::unordered_map<Enum::ChannelIDInfo, channel_type, Enum::ChannelIDInfoHasher>#

Type used for a mapping of channels.

using data_type = std::unordered_map<int, std::vector<T>>#

Type used for data as it is passed back to the user.

using view_type = std::unordered_map<int, std::span<T>>#

Type used for a view as it is passed back to the user.

Public Functions

inline virtual std::vector<int> channel_indices(bool include_mask) const override#

Get the channel indices held by this layer.

inline virtual size_t num_channels(bool include_mask) const override#

Get the total number of channels held by this layer.

inline virtual void set_write_compression(Enum::Compression _compcode) override#

Set the write compression for all channels.

This has no effect on the in-memory compression of these channels but only on write. Setting this therefore has a near-zero runtime cost.

Parameters:

_compcode – The new compression setting.

inline ImageLayer(std::unordered_map<Enum::ChannelID, std::vector<T>> data, Layer<T>::Params &parameters)#

Generate an ImageLayer instance ready to be used in a LayeredFile document.

Parameters:
  • data – the ImageData to associate with the layer

  • parameters – The parameters dictating layer name, width, height, mask etc.

inline ImageLayer(std::unordered_map<Enum::ChannelID, compressed::channel<T>> data, Layer<T>::Params &parameters)#

Generate an ImageLayer instance ready to be used in a LayeredFile document.

Parameters:
  • data – the ImageData to associate with the layer

  • parameters – The parameters dictating layer name, width, height, mask etc.

inline ImageLayer(std::unordered_map<int, std::vector<T>> data, Layer<T>::Params &parameters)#

Generate an ImageLayer instance ready to be used in a LayeredFile document.

Parameters:
  • data – the ImageData to associate with the channel

  • parameters – The parameters dictating layer name, width, height, mask etc.

inline ImageLayer(std::unordered_map<int, compressed::channel<T>> data, Layer<T>::Params &parameters)#

Generate an ImageLayer instance ready to be used in a LayeredFile document.

Parameters:
  • data – the ImageData to associate with the channel

  • parameters – The parameters dictating layer name, width, height, mask etc.

inline ImageLayer(const LayerRecord &layer_record, ChannelImageData &channel_image_data, const FileHeader &header)#

Initialize the ImageLayer from the photoshop primitives

This is part of the internal API and as a user you will likely never have to use this function

inline virtual void set_image_data(const data_type &data) override#

Sets the image data.

Parameters:

data – The data to be set.

inline virtual void set_image_data(const data_type &data, int32_t width, int32_t height) override#

Sets the image data with specified dimensions.

Parameters:
  • data – The image data to be set.

  • width – The width of the image.

  • height – The height of the image.

inline virtual void set_image_data(const std::unordered_map<Enum::ChannelID, std::vector<T>> &data) override#

Sets the image data.

Parameters:

data – The data to be set.

inline virtual void set_image_data(const std::unordered_map<Enum::ChannelID, std::vector<T>> &data, int32_t width, int32_t height) override#

Sets the image data with specified dimensions.

Parameters:
  • data – The image data to be set.

  • width – The width of the image.

  • height – The height of the image.

inline virtual void set_image_data(const std::unordered_map<Enum::ChannelIDInfo, std::vector<T>> &data) override#

Sets the image data.

Parameters:

data – The data to be set.

inline virtual void set_image_data(const std::unordered_map<Enum::ChannelIDInfo, std::vector<T>> &data, int32_t width, int32_t height) override#

Sets the image data with specified dimensions.

Parameters:
  • data – The image data to be set.

  • width – The width of the image.

  • height – The height of the image.

inline virtual void set_channel(int _id, const std::vector<T> &channel) override#

Sets the data for a specific channel.

Parameters:
  • _id – The channel ID to set the data for.

  • channel – The channel data to be set.

inline virtual void set_channel(Enum::ChannelID _id, const std::vector<T> &channel) override#

Sets the data for a specific channel.

Parameters:
  • _id – The channel ID to set the data for.

  • channel – The channel data to be set.

inline virtual void set_channel(Enum::ChannelIDInfo _id, const std::vector<T> &channel) override#

Sets the data for a specific channel, using a ChannelIDInfo.

Parameters:
  • _id – The channel ID to set the data for.

  • channel – The channel data to be set.

inline virtual void set_channel(int _id, const std::span<const T> channel) override#

Sets the data for a specific channel.

Parameters:
  • _id – The channel ID to set the data for.

  • channel – The channel data to be set.

inline virtual void set_channel(Enum::ChannelID _id, const std::span<const T> channel) override#

Sets the data for a specific channel.

Parameters:
  • _id – The channel ID to set the data for.

  • channel – The channel data to be set.

inline virtual void set_channel(Enum::ChannelIDInfo _id, const std::span<const T> channel) override#

Sets the data for a specific channel, using a ChannelIDInfo.

Parameters:
  • _id – The channel ID to set the data for.

  • channel – The channel data to be set.

inline virtual std::tuple<LayerRecord, ChannelImageData> to_photoshop() override#

Converts the image layer to Photoshop layerRecords and imageData.

This is part of the internal API and as a user you will likely never have to use this function

Returns:

A tuple containing LayerRecord and ChannelImageData.

inline const std::string &name() const noexcept#

The layers’ name. Stored as a utf-8 string.

inline std::string &name() noexcept#

The layers’ name. Stored as a utf-8 string.

inline void name(const std::string &layer_name) noexcept#

The layers’ name. Stored as a utf-8 string.

inline Enum::BlendMode &blendmode() noexcept#

The blendmode of the layer, the Passthrough blendmode is only valid for groups.

inline Enum::BlendMode blendmode() const noexcept#

The blendmode of the layer, the Passthrough blendmode is only valid for groups.

inline void blendmode(Enum::BlendMode blend_mode) noexcept#

The blendmode of the layer, the Passthrough blendmode is only valid for groups.

inline bool &locked() noexcept#

Whether the layers’ pixel values are locked. This is currently an all or nothing setting.

inline bool locked() const noexcept#

Whether the layers’ pixel values are locked. This is currently an all or nothing setting.

inline void locked(bool is_locked) noexcept#

Whether the layers’ pixel values are locked. This is currently an all or nothing setting.

inline bool &visible() noexcept#

Visibility toggle of the layer.

inline bool visible() const noexcept#

Visibility toggle of the layer.

inline void visible(bool is_visible) noexcept#

Visibility toggle of the layer.

inline bool &clipping_mask() noexcept#

Clipping mask toggle of the layer, clips it to the layer below.

inline bool clipping_mask() const noexcept#

Clipping mask toggle of the layer, clips it to the layer below.

inline void clipping_mask(bool is_clipped) noexcept#

Clipping mask toggle of the layer, clips it to the layer below.

inline float opacity() const noexcept#

The layers’ opacity.

In photoshop this is stored as a uint8_t from 0-255 but access and write is in terms of a float for better consistency.

inline void opacity(float value) noexcept#

The layers’ opacity.

In photoshop this is stored as a uint8_t from 0-255 but access and write is in terms of a float for better consistency.

inline virtual uint32_t width() const noexcept#

The layers’ width from 0 - 300,000.

inline virtual void width(uint32_t layer_width)#

The layers’ width from 0 - 300,000.

inline virtual uint32_t height() const noexcept#

The layers’ height from 0 - 300,000.

inline virtual void height(uint32_t layer_height)#

The layers’ height from 0 - 300,000.

inline virtual float center_x() const noexcept#

The layers’ x center coordinate

I.e. if the layer has the bounds { 200, 200 } - { 1000, 1000 } The center would be at { 600, 600 }

inline virtual void center_x(float x_coord) noexcept#
inline virtual float center_y() const noexcept#

The layers’ y center coordinate

I.e. if the layer has the bounds { 200, 200 } - { 1000, 1000 } The center would be at { 600, 600 }

inline virtual void center_y(float y_coord) noexcept#
inline float top_left_x() const noexcept#

Convenience function for accessing the top left x coordinate of a layer.

inline float top_left_y() const noexcept#

Convenience function for accessing the top left y coordinate of a layer.

inline Enum::ColorMode color_mode() const noexcept#

The color mode with which the file was created, only stored to allow better detection during channel access for e.g. image layers

inline Enum::LayerColor display_color() const noexcept#

The layers’ display color in the GUI.

inline void display_color(const Enum::LayerColor color) noexcept#
inline void set_storage(image_type data)#

Sets the underlying storage of the image data held by this Layer.

Usually a user should not have to access image data this way and should instead use set_image_data() or set_channel().

inline const image_type &get_storage() const#

Get the underlying storage of the image data held by this Layer. This may not always be up-to-date in the case of layers that require rendering such as SmartObject layers or Text layers.

Usually a user should not have to access image data this way and should instead use get_image_data() or get_channel().

inline data_type get_image_data()#

Get the image data held by this layer, this includes all channels as well as any masks.

Therefore not all channels are guaranteed to be the same. If has_mask() is true (or channel -2 if in the data) the mask channel may be any size and does not have to overlap with the layer.

The other channels do however have to be the same size

Returns:

The evaluated image data including mask.

inline std::vector<T> get_channel(int _id)#

Get the channel held at the given index

This channel will have the dimensions width() * height() unless you are requesting the mask channel -2. This will instead hold the dimensions described by mask_bbox(). Calling get_channel() with index -2 is equivalent to calling get_mask()

Generally this will method will be slightly slower than calling get_image_data for multiple channels as get_image_data is parallelized.

Returns:

The evaluated channel

inline std::vector<T> get_channel(Enum::ChannelID _id)#

Get the channel held at the given index

This channel will have the dimensions width() * height() unless you are requesting the mask channel -2. This will instead hold the dimensions described by mask_bbox(). Calling get_channel() with index -2 is equivalent to calling get_mask()

Generally this will method will be slightly slower than calling get_image_data for multiple channels as get_image_data is parallelized.

Returns:

The evaluated channel

inline std::vector<T> get_channel(Enum::ChannelIDInfo _id)#

Get the channel held at the given index

This channel will have the dimensions width() * height() unless you are requesting the mask channel -2. This will instead hold the dimensions described by mask_bbox(). Calling get_channel() with index -2 is equivalent to calling get_mask()

Generally this will method will be slightly slower than calling get_image_data for multiple channels as get_image_data is parallelized.

Returns:

The evaluated channel

Public Static Functions

static inline std::optional<channel_type> split_mask(image_type &data)#

Convenience function for splitting a mask channel from an image data mapping. This is usually necessary to ensure the mask is handled separately and stored on e.g. the MaskMixin<T>.

This will extract the mask channel from data and optionally return it (if it exists)

Returns:

an optional mask channel if the passed image data contains it.

Public Static Attributes

static constexpr auto s_mask_index = Enum::ChannelIDInfo{Enum::ChannelID::UserSuppliedLayerMask, -2}#

Colormode independent mask index as Enum::ChannelIDInfo that may be used.