Set C palette to be empty by default

This commit is contained in:
Andrew Murray 2023-07-17 23:04:43 +10:00
parent 7bfc6f16dc
commit fd310512b9
10 changed files with 43 additions and 57 deletions

View File

@ -205,14 +205,14 @@ def test_optimize_full_l():
def test_optimize_if_palette_can_be_reduced_by_half():
with Image.open("Tests/images/test.colors.gif") as im:
# Reduce dimensions because original is too big for _get_optimize()
im = im.resize((591, 443))
im_rgb = im.convert("RGB")
im = Image.new("P", (8, 1))
im.palette = ImagePalette.raw("RGB", bytes((0, 0, 0) * 150))
for i in range(8):
im.putpixel((i, 0), (i + 1, 0, 0))
for optimize, colors in ((False, 256), (True, 8)):
out = BytesIO()
im_rgb.save(out, "GIF", optimize=optimize)
im.save(out, "GIF", optimize=optimize)
with Image.open(out) as reloaded:
assert len(reloaded.palette.palette) // 3 == colors
@ -1172,18 +1172,17 @@ def test_palette_save_L(tmp_path):
def test_palette_save_P(tmp_path):
# Pass in a different palette, then construct what the image would look like.
# Forcing a non-straight grayscale palette.
im = hopper("P")
palette = bytes(255 - i // 3 for i in range(768))
im = Image.new("P", (1, 2))
im.putpixel((0, 1), 1)
out = str(tmp_path / "temp.gif")
im.save(out, palette=palette)
im.save(out, palette=bytes((1, 2, 3, 4, 5, 6)))
with Image.open(out) as reloaded:
im.putpalette(palette)
assert_image_equal(reloaded, im)
reloaded_rgb = reloaded.convert("RGB")
assert reloaded_rgb.getpixel((0, 0)) == (1, 2, 3)
assert reloaded_rgb.getpixel((0, 1)) == (4, 5, 6)
def test_palette_save_duplicate_entries(tmp_path):

View File

@ -632,8 +632,8 @@ class TestImage:
im.remap_palette(None)
def test_remap_palette_transparency(self):
im = Image.new("P", (1, 2))
im.putpixel((0, 1), 1)
im = Image.new("P", (1, 2), (0, 0, 0))
im.putpixel((0, 1), (255, 0, 0))
im.info["transparency"] = 0
im_remapped = im.remap_palette([1, 0])

View File

@ -117,11 +117,11 @@ def test_trns_p(tmp_path):
f = str(tmp_path / "temp.png")
im_l = im.convert("L")
assert im_l.info["transparency"] == 1 # undone
assert im_l.info["transparency"] == 0
im_l.save(f)
im_rgb = im.convert("RGB")
assert im_rgb.info["transparency"] == (0, 1, 2) # undone
assert im_rgb.info["transparency"] == (0, 0, 0)
im_rgb.save(f)

View File

@ -86,6 +86,11 @@ def test_rgba_palette(mode, palette):
assert im.palette.colors == {(1, 2, 3, 4): 0}
def test_empty_palette():
im = Image.new("P", (1, 1))
assert im.getpalette() == []
def test_undefined_palette_index():
im = Image.new("P", (1, 1), 3)
im.putpalette((1, 2, 3))

View File

@ -419,9 +419,11 @@ class BLPEncoder(ImageFile.PyEncoder):
def _write_palette(self):
data = b""
palette = self.im.getpalette("RGBA", "RGBA")
for i in range(256):
for i in range(len(palette) // 4):
r, g, b, a = palette[i * 4 : (i + 1) * 4]
data += struct.pack("<4B", b, g, r, a)
while len(data) < 256 * 4:
data += b"\x00" * 4
return data
def encode(self, bufsize):

View File

@ -1069,7 +1069,7 @@ class Image:
if mode == "P" and palette != Palette.ADAPTIVE:
from . import ImagePalette
new_im.palette = ImagePalette.ImagePalette("RGB", list(range(256)) * 3)
new_im.palette = ImagePalette.ImagePalette("RGB", im.getpalette("RGB"))
if delete_trns:
# crash fail if we leave a bytes transparency in an rgb/l mode.
del new_im.info["transparency"]

View File

@ -1676,12 +1676,11 @@ _quantize(ImagingObject *self, PyObject *args) {
static PyObject *
_putpalette(ImagingObject *self, PyObject *args) {
ImagingShuffler unpack;
int i, bits;
int bits;
char *rawmode, *palette_mode;
UINT8 *palette;
Py_ssize_t palettesize;
ImagingPalette im_palette;
if (!PyArg_ParseTuple(args, "sy#", &rawmode, &palette, &palettesize)) {
return NULL;
}
@ -1708,16 +1707,10 @@ _putpalette(ImagingObject *self, PyObject *args) {
strcpy(self->image->mode, strlen(self->image->mode) == 2 ? "PA" : "P");
im_palette = ImagingPaletteNew(palette_mode);
self->image->palette = im_palette;
self->image->palette = ImagingPaletteNew(palette_mode);
im_palette->size = palettesize * 8 / bits;
unpack(im_palette->palette, palette, im_palette->size);
for (i=im_palette->size; i<256; i++) {
im_palette->palette[i * 4] = 0;
im_palette->palette[i * 4 + 1] = 0;
im_palette->palette[i * 4 + 2] = 0;
}
self->image->palette->size = palettesize * 8 / bits;
unpack(self->image->palette->palette, palette, self->image->palette->size);
Py_INCREF(Py_None);
return Py_None;

View File

@ -1295,7 +1295,6 @@ topalette(
int alpha;
int x, y;
ImagingPalette palette = inpalette;
;
/* Map L or RGB/RGBX/RGBA to palette image */
if (strcmp(imIn->mode, "L") != 0 && strncmp(imIn->mode, "RGB", 3) != 0) {
@ -1307,7 +1306,14 @@ topalette(
if (palette == NULL) {
/* FIXME: make user configurable */
if (imIn->bands == 1) {
palette = ImagingPaletteNew("RGB"); /* Initialised to grey ramp */
palette = ImagingPaletteNew("RGB");
palette->size = 256;
int i;
for (i = 0; i < 256; i++) {
palette->palette[i * 4] = palette->palette[i * 4 + 1] =
palette->palette[i * 4 + 2] = (UINT8)i;
}
} else {
palette = ImagingPaletteNewBrowser(); /* Standard colour cube */
}

View File

@ -40,10 +40,8 @@ ImagingPaletteNew(const char *mode) {
palette->mode[IMAGING_MODE_LENGTH - 1] = 0;
/* Initialize to ramp */
palette->size = 256;
palette->size = 0;
for (i = 0; i < 256; i++) {
palette->palette[i * 4 + 0] = palette->palette[i * 4 + 1] =
palette->palette[i * 4 + 2] = (UINT8)i;
palette->palette[i * 4 + 3] = 255; /* opaque */
}
@ -62,16 +60,10 @@ ImagingPaletteNewBrowser(void) {
return NULL;
}
/* Blank out unused entries */
/* FIXME: Add 10-level windows palette here? */
for (i = 0; i < 10; i++) {
palette->palette[i * 4 + 0] = palette->palette[i * 4 + 1] =
palette->palette[i * 4 + 2] = 0;
}
/* Simple 6x6x6 colour cube */
i = 10;
for (b = 0; b < 256; b += 51) {
for (g = 0; g < 256; g += 51) {
for (r = 0; r < 256; r += 51) {
@ -82,15 +74,10 @@ ImagingPaletteNewBrowser(void) {
}
}
}
palette->size = i;
/* Blank out unused entries */
/* FIXME: add 30-level greyscale wedge here? */
for (; i < 256; i++) {
palette->palette[i * 4 + 0] = palette->palette[i * 4 + 1] =
palette->palette[i * 4 + 2] = 0;
}
return palette;
}

View File

@ -1825,6 +1825,7 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans) {
free(newData);
imOut->palette->size = (int)paletteLength;
pp = imOut->palette->palette;
for (i = j = 0; i < (int)paletteLength; i++) {
@ -1832,16 +1833,9 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans) {
*pp++ = palette[i].c.g;
*pp++ = palette[i].c.b;
if (withAlpha) {
*pp++ = palette[i].c.a;
} else {
*pp++ = 255;
*pp = palette[i].c.a;
}
}
for (; i < 256; i++) {
*pp++ = 0;
*pp++ = 0;
*pp++ = 0;
*pp++ = 255;
pp++;
}
if (withAlpha) {