iterators (cpp)#

Note

This section only applies to the C++ bindings. The Python bindings do not support direct iteration. For Python usage, please refer to example: Read from file for iterating chunks through the API.

iterator#

The channel_iterator is the primary mechanism enabling range-based for loops over a compressed::channel<T>. When iterating using:

for (auto chunk : channel)

the chunk is obtained by dereferencing the iterator (operator*), returning a chunk span object that provides a view into the corresponding chunk of data in the channel.

template<typename T>
struct channel_iterator#

Public Types

using iterator_category = std::forward_iterator_tag#
using difference_type = std::ptrdiff_t#
using value_type = container::chunk_span<T>#
using pointer = value_type*#
using reference = value_type&#

Public Functions

channel_iterator() = default#
inline channel_iterator(blosc2::schunk_var_ptr<T> schunk, blosc2::context_raw_ptr compression_context, blosc2::context_raw_ptr decompression_context, size_t chunk_index, size_t width, size_t height)#
inline ~channel_iterator()#
inline value_type operator*()#

Dereference operator: decompress the current chunk and recompress (if necessary) the previously compressed chunk. value_type is a view over the current buffers. Iterator going out of scope while value_type is accessed is UB.

inline channel_iterator &operator++()#
inline channel_iterator &operator++(int)#
inline bool operator==(const channel_iterator &other) const noexcept#
inline bool operator!=(const channel_iterator &other) const noexcept#
inline size_t chunk_index() const noexcept#

Return the chunk index the iterator is currently at.

inline size_t chunk_elements() const noexcept#

Return the chunk size of all but the last chunk.

inline size_t chunk_bytes() const noexcept#

Return the chunk size of all but the last chunk.

chunk span#

The container::chunk_span<T> is a lightweight view over a chunk in a channel<T>. This object is returned when dereferencing a channel_iterator.

Each chunk_span provides access to:

  • The chunk’s pixel data as a contiguous range.

  • The ability to compute global (x, y) coordinates from local chunk indices.

  • In-place read/write access to pixels.

Here is an example of how to iterate through a channel and compute pixel values based on global coordinates:

compressed::channel<T> my_channel = ...;

for (compressed::container::chunk_span<T> chunk : my_channel)
{
    for (auto& [index, pixel] : std::views::enumerate(chunk))
    {
        // The index is local to the chunk. Compute global coordinates:
        auto x = chunk.x(index);
        auto y = chunk.y(index);

        // Modify the pixel in-place
        pixel = static_cast<T>(x) * y;
    }
}

Warning

A chunk_span is only valid for the lifetime of the iterator it was obtained from. Do not store or use a chunk_span after the loop or iterator scope has ended.

template<typename T>
struct chunk_span : public std::ranges::view_interface<chunk_span<T>>#

Represents a chunked view into a larger image, providing access to a decompressed segment of the image or channel.

This structure acts as a lightweight view into a chunk within the context of an image. It allows efficient iteration over the decompressed chunk while providing methods to determine the global X and Y coordinates relative to the full image.

The chunk is retrieved by dereferencing a compressed::iterator, and is used in scenarios like iterating over image channels and processing decompressed data in smaller segments

Template Parameters:

T – The data type stored in the chunk (e.g., pixel values).

Public Types

using iterator = std::span<T>::iterator#
using const_iterator = std::span<const T>::iterator#

Public Functions

chunk_span() = default#
inline chunk_span(std::span<T> data, size_t width, size_t height, size_t chunk_index, size_t chunk_size)#

Constructs a chunk_span pointing to a segment of an image.

Parameters:
  • data – The span of data representing this chunk.

  • width – The total width of the full image.

  • height – The total height of the full image.

  • chunk_index – The index of this chunk in the overall compressed image sequence.

inline size_t x(size_t _index) const noexcept#

Computes the X coordinate of a given index within this chunk, relative to the full image.

Parameters:

_index – The local index within this chunk_span.

Returns:

The X coordinate in the full image.

inline size_t y(size_t _index) const noexcept#

Computes the Y coordinate of a given index within this chunk, relative to the full image.

Parameters:

_index – The local index within this chunk_span.

Returns:

The Y coordinate in the full image.

inline size_t chunk_index() const noexcept#

Returns the current chunk index we are accessing.

inline auto begin() const noexcept#

Returns an iterator to the beginning of the chunk’s data.

This is required to fulfill the requirements of std::ranges::view_interface.

Returns:

An iterator to the start of the chunk’s span.

inline auto end() const noexcept#

Returns an iterator to the end of the chunk’s data.

This is required to fulfill the requirements of std::ranges::view_interface.

Returns:

An iterator to the end of the chunk’s span.

inline auto size() const noexcept#

Returns the size of the chunk.

zip channels#

The compressed::ranges::zip utility allows for synchronized iteration over multiple channels, similar to Python’s zip. This is particularly useful when working with multi-channel images (e.g., RGB), allowing direct access to corresponding pixels in each channel without manual chunk or pixel index management.

For best results, ensure that the zipped channels:

  • Have the same number of chunks.

  • Use identical chunk sizes and layouts.

Example usage:

compressed::image<T> image = ...;

// Get references to the R, G, and B channels by index
auto [r, g, b] = image.channels(0, 1, 2);

// Iterate over all chunks simultaneously
for (auto [r_chunk, g_chunk, b_chunk] : compressed::ranges::zip(r, g, b))
{
    // Iterate over pixels in each chunk simultaneously
    for (auto [r_pixel, g_pixel, b_pixel] : compressed::ranges::zip(r_chunk, g_chunk, b_chunk))
    {
        // Modify each pixel, e.g., grayscale average
        auto gray = static_cast<T>((r_pixel + g_pixel + b_pixel) / 3);
        r_pixel = g_pixel = b_pixel = gray;
    }
}
template<typename ...T>
struct zip#

Copied from https://debashish-ghosh.medium.com/lets-iterate-together-fd7f5e49672b. zip() implementation that is near-identical to std::ranges::zip() which is C++23 only

Public Functions

inline zip(T&... args)#
inline auto begin()#
inline auto end()#
inline auto size() const#

Public Members

std::tuple<T&...> data#
struct iterator#

Public Types

using iterator_category = std::forward_iterator_tag#
using value_type = std::tuple<std::iter_value_t<std::ranges::iterator_t<T>>...>#
using reference = std::tuple<std::iter_reference_t<std::ranges::iterator_t<T>>...>#
using difference_type = std::ptrdiff_t#
using pointer = std::tuple<typename std::iterator_traits<std::ranges::iterator_t<T>>::pointer...>#

Public Functions

inline reference operator*()#
inline reference operator*() const#
inline iterator &operator++()#
inline iterator operator++(int)#
inline auto operator!=(const iterator &iter) const#
inline bool operator==(const iterator &iter) const#
inline difference_type operator-(const iterator &other) const#

Public Members

std::tuple<std::ranges::iterator_t<T>...> data_#