Gimp-Forum.net
Endianess of pixel data in a Python region for gimp 2.10. - Printable Version

+- Gimp-Forum.net (https://www.gimp-forum.net)
+-- Forum: GIMP (https://www.gimp-forum.net/Forum-GIMP)
+--- Forum: Extending the GIMP (https://www.gimp-forum.net/Forum-Extending-the-GIMP)
+---- Forum: Scripting questions (https://www.gimp-forum.net/Forum-Scripting-questions)
+---- Thread: Endianess of pixel data in a Python region for gimp 2.10. (/Thread-Endianess-of-pixel-data-in-a-Python-region-for-gimp-2-10)



Endianess of pixel data in a Python region for gimp 2.10. - teapot - 07-14-2025

For gimp 2.10, is my understanding correct?

Given a region's bytes from a layer ‘l’:

    r = l.get_pixel_rgn(0, 0, w, h)
    rb = r[:, :]

I think rb will hold the bytes of the channel's values in the machine's native endianess because:

- a region maps onto tiles,
- getting the tile's pixels uses a simple memcpy(), and
- a tile's pixels are in the native endianess.

I'm aware tile data in an XCF file is big-endian from
https://testing.developer.gimp.org/core/standards/xcf/#tile-data-organization
But I'm interested in what's in memory and guaranteed to be seen through slicing a Python region into a string of bytes.


RE: Endianess of pixel data in a Python region for gimp 2.10. - Ofnuts - 07-14-2025

In my code it appears that I assume it's R,G,B. Worrying about endianness would imply that you expect values in data types bigger than bytes?


RE: Endianess of pixel data in a Python region for gimp 2.10. - teapot - 07-14-2025

Hi Ofnuts, Yes, that's right.  The image's precision can be integers or floats of 16 or 32 bits.


RE: Endianess of pixel data in a Python region for gimp 2.10. - Ofnuts - 07-14-2025

(07-14-2025, 05:52 PM)teapot Wrote: Hi Ofnuts, Yes, that's right.  The image's precision can be integers or floats of 16 or 32 bits.

OK, so 
  • I create a 32-bit image, and fill with a (100%,50%,25%) color (values in the FG color selector, in other words #FF8040).
  • Get a pixel region. rgn.bpp is 3, so data is converted to one byte per channel.
  • Call pdb.gimp_plugin_enable_precision() 
  • rgn.bpp is now 12 (coherent with 32-bit per channel (no alpha channel).
Then
Code:
➤> rgn=image.active_layer.get_pixel_rgn(0,0,10,10)
➤> rgn.bpp # Check the precision of the returned data
3
➤> # Tell Gimp we are a big boy and can be told the truth
➤> pdb.gimp_plugin_enable_precision()

➤> rgn=image.active_layer.get_pixel_rgn(0,0,10,10)
➤> rgn.bpp
12
➤> # OK, much better (no alpha, so 3 channels of 4 bytes each)
➤> # Let's try some decoding
➤> import struct

➤> struct.unpack('f',rgn[0,0][0:4])  # Native order, get 1 for Red, as expected
(1.0,)
➤> struct.unpack('<f',rgn[0,0][0:4]) # Little-endian order (same as native on my x86 PC, still OK)
(1.0,)
➤> struct.unpack('>f',rgn[0,0][0:4]) # Big-endian, WTF
(4.600602988224807e-41,)
➤> struct.unpack('f',rgn[0,0][4:8])  # Green (obviously linear)
(0.21586056053638458,)
➤> struct.unpack('f',rgn[0,0][8:12]) # Blue (obviously linear too)
(0.051269471645355225,)
➤>