Pillow icon indicating copy to clipboard operation
Pillow copied to clipboard

Improved BCn overflow check

Open radarhere opened this issue 5 months ago • 0 comments

While checking for BCn overflow, dst is advanced by 8 bytes every loop. https://github.com/python-pillow/Pillow/blob/d07aa6fd17d356b8f09f89a5c485fc8b1532635f/src/libImaging/BcnEncode.c#L287

It is advanced by an additional 8 bytes under these conditions in the code.

if (n == 5) {
  ...
  dst += 8;
  ...
} else {
  if (n == 2 || n == 3) {
    if (has_alpha_channel) {
      ...
      dst += 8;
    } else {
      for (int i = 0; i < 8; i++) {
        *dst++ = ...;
      }
    }
  }

So when n is 1, it is only advanced by 8 each loop, not 16. In format terms, this is DXT1, also known as BC1.

https://learn.microsoft.com/en-us/windows/win32/direct3d10/d3d10-graphics-programming-guide-resources-block-compression#bc2

BC1 ... the BC1 format reduces the memory required from 48 bytes (16 colors × 3 components/color × 1 byte/component) to 8 bytes of memory. ... BC2 ... this compression technique reduces the memory required from 64 bytes (16 colors × 4 components/color × 1 byte/component) to 16 bytes of memory. ... BC3 ... this compression technique reduces the memory required from 64 bytes (16 colors × 4 components/color × 1 byte/component) to 16 bytes of memory. ... BC5 ... this compression technique reduces the memory required from 32 bytes (16 colors × 2 components/color × 1 byte/component) to 16 bytes.

This means we can change the check to look for 8 bytes if n is 1, rather than 16 bytes.

radarhere avatar Jun 27 '25 14:06 radarhere