From 35ec1107b6e7eec6ee65e6a9cbd36d49543d7d38 Mon Sep 17 00:00:00 2001 From: Kirill Osipov Date: Tue, 30 Jun 2026 17:08:18 +0200 Subject: [PATCH] Add PixelBuffer#to_bytes for zero-overhead RGBA pixel access Exposes a GSI method on tl::PixelBuffer that returns the raw ARGB32 contents as a byte vector (4 bytes per pixel, row-major, top to bottom) via a single memcpy. Unlike to_png_data this skips all image encoding, which is useful when the caller just wants direct pixel data. --- src/gsi/gsi/gsiDeclTlPixelBuffer.cc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/gsi/gsi/gsiDeclTlPixelBuffer.cc b/src/gsi/gsi/gsiDeclTlPixelBuffer.cc index c78cd1b1d..a0fae9f7a 100644 --- a/src/gsi/gsi/gsiDeclTlPixelBuffer.cc +++ b/src/gsi/gsi/gsiDeclTlPixelBuffer.cc @@ -126,6 +126,14 @@ static std::vector pixel_buffer_to_png (const tl::PixelBuffer *pb) #endif } +// Returns the raw ARGB32 pixel data as a byte vector (no encoding overhead) +static std::vector pixel_buffer_to_bytes (const tl::PixelBuffer *pb) +{ + const char *p = (const char *) pb->data (); + size_t n = (size_t) pb->width () * (size_t) pb->height () * 4; + return std::vector (p, p + n); +} + Class decl_PixelBuffer ("lay", "PixelBuffer", gsi::constructor ("new", &create_pixel_buffer, gsi::arg ("width"), gsi::arg ("height"), @@ -188,6 +196,14 @@ Class decl_PixelBuffer ("lay", "PixelBuffer", "\n" "This method may not be available if PNG support is not compiled into KLayout." ) + + gsi::method_ext ("to_bytes", &pixel_buffer_to_bytes, + "@brief Converts the pixel buffer to a raw byte stream\n" + "\n" + "Returns the raw ARGB32 pixel data with 4 bytes per pixel in row-major order, " + "top to bottom. Unlike \\to_png_data this method has zero encoding overhead.\n" + "\n" + "This method has been added in version 0.30.9." + ) + gsi::method ("patch", &tl::PixelBuffer::patch, gsi::arg ("other"), "@brief Patches another pixel buffer into this one\n" "\n"