Skip to content

Commit

Permalink
Added RGB to I;16, I;16L and I;16B conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
radarhere committed Mar 30, 2024
1 parent f0767ee commit fb6b860
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 2 deletions.
2 changes: 0 additions & 2 deletions Tests/helper.py
Expand Up @@ -263,8 +263,6 @@ def hopper(mode: str | None = None, cache: dict[str, Image.Image] = {}) -> Image
if im is None:
if mode == "F":
im = hopper("L").convert(mode)
elif mode[:4] == "I;16":
im = hopper("I").convert(mode)
else:
im = hopper().convert(mode)
cache[mode] = im
Expand Down
23 changes: 23 additions & 0 deletions src/libImaging/Convert.c
Expand Up @@ -250,6 +250,26 @@ rgb2i(UINT8 *out_, const UINT8 *in, int xsize) {
}
}

static void
rgb2i16l(UINT8 *out_, const UINT8 *in, int xsize) {
int x;
for (x = 0; x < xsize; x++, in += 4) {
UINT8 v = CLIP16(L24(in) >> 16);

This comment has been minimized.

Copy link
@lukegb

lukegb Apr 23, 2024

Contributor

This seems suspect to me (or I'm misunderstanding); we're clipping to 16 bits and then pushing that into a uint8? And then right-shifting this by 8 bits to populate the second half of the 16-bit int will always return 0.

But AIUI there's no way that (L24(in) >> 16) could be > 0xff anyway?

This comment has been minimized.

Copy link
@radarhere

radarhere Apr 24, 2024

Author Member

My intention was to combine

rgb2i(UINT8 *out_, const UINT8 *in, int xsize) {
int x;
for (x = 0; x < xsize; x++, in += 4, out_ += 4) {
INT32 v = L24(in) >> 16;
memcpy(out_, &v, sizeof(v));
}
}

and
I_I16L(UINT8 *out, const UINT8 *in_, int xsize) {
int x, v;
for (x = 0; x < xsize; x++, in_ += 4) {
INT32 i;
memcpy(&i, in_, sizeof(i));
v = CLIP16(i);
*out++ = (UINT8)v;
*out++ = (UINT8)(v >> 8);
}
}

It looks like I did that too simplistically.

But AIUI there's no way that (L24(in) >> 16) could be > 0xff anyway?

Yes, it makes sense that converting RGB, with a maximum of 0xff for each channel, wouldn't be greater than that in an I;16* mode.

I've created #8008

*out_++ = v;
*out_++ = v >> 8;
}
}

static void
rgb2i16b(UINT8 *out_, const UINT8 *in, int xsize) {
int x;
for (x = 0; x < xsize; x++, in += 4) {
UINT8 v = CLIP16(L24(in) >> 16);
*out_++ = v >> 8;
*out_++ = v;
}
}

static void
rgb2f(UINT8 *out_, const UINT8 *in, int xsize) {
int x;
Expand Down Expand Up @@ -944,6 +964,9 @@ static struct {
{"RGB", "LA", rgb2la},
{"RGB", "La", rgb2la},
{"RGB", "I", rgb2i},
{"RGB", "I;16", rgb2i16l},
{"RGB", "I;16L", rgb2i16l},
{"RGB", "I;16B", rgb2i16b},
{"RGB", "F", rgb2f},
{"RGB", "BGR;15", rgb2bgr15},
{"RGB", "BGR;16", rgb2bgr16},
Expand Down

0 comments on commit fb6b860

Please sign in to comment.