mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-10-31 07:57:27 +03:00 
			
		
		
		
	Merge pull request #3728 from radarhere/pa_mode
Improvements to PA and LA conversion and palette operations
This commit is contained in:
		
						commit
						69ed0aa5b5
					
				|  | @ -12,7 +12,8 @@ class TestImageConvert(PillowTestCase): | ||||||
|             self.assertEqual(out.mode, mode) |             self.assertEqual(out.mode, mode) | ||||||
|             self.assertEqual(out.size, im.size) |             self.assertEqual(out.size, im.size) | ||||||
| 
 | 
 | ||||||
|         modes = "1", "L", "I", "F", "RGB", "RGBA", "RGBX", "CMYK", "YCbCr" |         modes = ("1", "L", "LA", "P", "PA", "I", "F", | ||||||
|  |                  "RGB", "RGBA", "RGBX", "CMYK", "YCbCr") | ||||||
| 
 | 
 | ||||||
|         for mode in modes: |         for mode in modes: | ||||||
|             im = hopper(mode) |             im = hopper(mode) | ||||||
|  |  | ||||||
|  | @ -14,8 +14,10 @@ class TestImagePutPalette(PillowTestCase): | ||||||
|                 return im.mode, p[:10] |                 return im.mode, p[:10] | ||||||
|             return im.mode |             return im.mode | ||||||
|         self.assertRaises(ValueError, palette, "1") |         self.assertRaises(ValueError, palette, "1") | ||||||
|         self.assertEqual(palette("L"), ("P", [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])) |         for mode in ["L", "LA", "P", "PA"]: | ||||||
|         self.assertEqual(palette("P"), ("P", [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])) |             self.assertEqual(palette(mode), | ||||||
|  |                              ("PA" if "A" in mode else "P", | ||||||
|  |                               [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])) | ||||||
|         self.assertRaises(ValueError, palette, "I") |         self.assertRaises(ValueError, palette, "I") | ||||||
|         self.assertRaises(ValueError, palette, "F") |         self.assertRaises(ValueError, palette, "F") | ||||||
|         self.assertRaises(ValueError, palette, "RGB") |         self.assertRaises(ValueError, palette, "RGB") | ||||||
|  |  | ||||||
|  | @ -1619,10 +1619,10 @@ class Image(object): | ||||||
| 
 | 
 | ||||||
|     def putpalette(self, data, rawmode="RGB"): |     def putpalette(self, data, rawmode="RGB"): | ||||||
|         """ |         """ | ||||||
|         Attaches a palette to this image.  The image must be a "P" or |         Attaches a palette to this image.  The image must be a "P", | ||||||
|         "L" image, and the palette sequence must contain 768 integer |         "PA", "L" or "LA" image, and the palette sequence must contain | ||||||
|         values, where each group of three values represent the red, |         768 integer values, where each group of three values represent | ||||||
|         green, and blue values for the corresponding pixel |         the red, green, and blue values for the corresponding pixel | ||||||
|         index. Instead of an integer sequence, you can use an 8-bit |         index. Instead of an integer sequence, you can use an 8-bit | ||||||
|         string. |         string. | ||||||
| 
 | 
 | ||||||
|  | @ -1631,7 +1631,7 @@ class Image(object): | ||||||
|         """ |         """ | ||||||
|         from . import ImagePalette |         from . import ImagePalette | ||||||
| 
 | 
 | ||||||
|         if self.mode not in ("L", "P"): |         if self.mode not in ("L", "LA", "P", "PA"): | ||||||
|             raise ValueError("illegal image mode") |             raise ValueError("illegal image mode") | ||||||
|         self.load() |         self.load() | ||||||
|         if isinstance(data, ImagePalette.ImagePalette): |         if isinstance(data, ImagePalette.ImagePalette): | ||||||
|  | @ -1643,7 +1643,7 @@ class Image(object): | ||||||
|                 else: |                 else: | ||||||
|                     data = "".join(chr(x) for x in data) |                     data = "".join(chr(x) for x in data) | ||||||
|             palette = ImagePalette.raw(rawmode, data) |             palette = ImagePalette.raw(rawmode, data) | ||||||
|         self.mode = "P" |         self.mode = "PA" if "A" in self.mode else "P" | ||||||
|         self.palette = palette |         self.palette = palette | ||||||
|         self.palette.mode = "RGB" |         self.palette.mode = "RGB" | ||||||
|         self.load()  # install new palette |         self.load()  # install new palette | ||||||
|  |  | ||||||
|  | @ -1569,7 +1569,8 @@ _putpalette(ImagingObject* self, PyObject* args) | ||||||
|     if (!PyArg_ParseTuple(args, "s"PY_ARG_BYTES_LENGTH, &rawmode, &palette, &palettesize)) |     if (!PyArg_ParseTuple(args, "s"PY_ARG_BYTES_LENGTH, &rawmode, &palette, &palettesize)) | ||||||
|         return NULL; |         return NULL; | ||||||
| 
 | 
 | ||||||
|     if (strcmp(self->image->mode, "L") != 0 && strcmp(self->image->mode, "P")) { |     if (strcmp(self->image->mode, "L") && strcmp(self->image->mode, "LA") && | ||||||
|  |         strcmp(self->image->mode, "P") && strcmp(self->image->mode, "PA")) { | ||||||
|         PyErr_SetString(PyExc_ValueError, wrong_mode); |         PyErr_SetString(PyExc_ValueError, wrong_mode); | ||||||
|         return NULL; |         return NULL; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -517,6 +517,18 @@ l2cmyk(UINT8* out, const UINT8* in, int xsize) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void | ||||||
|  | la2cmyk(UINT8* out, const UINT8* in, int xsize) | ||||||
|  | { | ||||||
|  |     int x; | ||||||
|  |     for (x = 0; x < xsize; x++, in += 4) { | ||||||
|  |         *out++ = 0; | ||||||
|  |         *out++ = 0; | ||||||
|  |         *out++ = 0; | ||||||
|  |         *out++ = ~(in[0]); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static void | static void | ||||||
| rgb2cmyk(UINT8* out, const UINT8* in, int xsize) | rgb2cmyk(UINT8* out, const UINT8* in, int xsize) | ||||||
| { | { | ||||||
|  | @ -673,6 +685,18 @@ l2ycbcr(UINT8* out, const UINT8* in, int xsize) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void | ||||||
|  | la2ycbcr(UINT8* out, const UINT8* in, int xsize) | ||||||
|  | { | ||||||
|  |     int x; | ||||||
|  |     for (x = 0; x < xsize; x++, in += 4) { | ||||||
|  |         *out++ = in[0]; | ||||||
|  |         *out++ = 128; | ||||||
|  |         *out++ = 128; | ||||||
|  |         *out++ = 255; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static void | static void | ||||||
| ycbcr2l(UINT8* out, const UINT8* in, int xsize) | ycbcr2l(UINT8* out, const UINT8* in, int xsize) | ||||||
| { | { | ||||||
|  | @ -681,6 +705,16 @@ ycbcr2l(UINT8* out, const UINT8* in, int xsize) | ||||||
|         *out++ = in[0]; |         *out++ = in[0]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void | ||||||
|  | ycbcr2la(UINT8* out, const UINT8* in, int xsize) | ||||||
|  | { | ||||||
|  |     int x; | ||||||
|  |     for (x = 0; x < xsize; x++, in += 4, out += 4) { | ||||||
|  |         out[0] = out[1] = out[2] = in[0]; | ||||||
|  |         out[3] = 255; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /* ------------------------- */ | /* ------------------------- */ | ||||||
| /* I;16 (16-bit) conversions */ | /* I;16 (16-bit) conversions */ | ||||||
| /* ------------------------- */ | /* ------------------------- */ | ||||||
|  | @ -818,8 +852,10 @@ static struct { | ||||||
|     { "LA", "L", la2l }, |     { "LA", "L", la2l }, | ||||||
|     { "LA", "La", lA2la }, |     { "LA", "La", lA2la }, | ||||||
|     { "LA", "RGB", la2rgb }, |     { "LA", "RGB", la2rgb }, | ||||||
|     { "LA", "RGBX", la2rgb }, |  | ||||||
|     { "LA", "RGBA", la2rgb }, |     { "LA", "RGBA", la2rgb }, | ||||||
|  |     { "LA", "RGBX", la2rgb }, | ||||||
|  |     { "LA", "CMYK", la2cmyk }, | ||||||
|  |     { "LA", "YCbCr", la2ycbcr }, | ||||||
| 
 | 
 | ||||||
|     { "La", "LA", la2lA }, |     { "La", "LA", la2lA }, | ||||||
| 
 | 
 | ||||||
|  | @ -861,8 +897,9 @@ static struct { | ||||||
| 
 | 
 | ||||||
|     { "RGBX", "1", rgb2bit }, |     { "RGBX", "1", rgb2bit }, | ||||||
|     { "RGBX", "L", rgb2l }, |     { "RGBX", "L", rgb2l }, | ||||||
|     { "RGBA", "I", rgb2i }, |     { "RGBX", "LA", rgb2la }, | ||||||
|     { "RGBA", "F", rgb2f }, |     { "RGBX", "I", rgb2i }, | ||||||
|  |     { "RGBX", "F", rgb2f }, | ||||||
|     { "RGBX", "RGB", rgba2rgb }, |     { "RGBX", "RGB", rgba2rgb }, | ||||||
|     { "RGBX", "CMYK", rgb2cmyk }, |     { "RGBX", "CMYK", rgb2cmyk }, | ||||||
|     { "RGBX", "YCbCr", ImagingConvertRGB2YCbCr }, |     { "RGBX", "YCbCr", ImagingConvertRGB2YCbCr }, | ||||||
|  | @ -872,6 +909,7 @@ static struct { | ||||||
|     { "CMYK", "RGBX", cmyk2rgb }, |     { "CMYK", "RGBX", cmyk2rgb }, | ||||||
| 
 | 
 | ||||||
|     { "YCbCr", "L", ycbcr2l }, |     { "YCbCr", "L", ycbcr2l }, | ||||||
|  |     { "YCbCr", "LA", ycbcr2la }, | ||||||
|     { "YCbCr", "RGB", ImagingConvertYCbCr2RGB }, |     { "YCbCr", "RGB", ImagingConvertYCbCr2RGB }, | ||||||
| 
 | 
 | ||||||
|     { "HSV", "RGB", hsv2rgb }, |     { "HSV", "RGB", hsv2rgb }, | ||||||
|  | @ -913,6 +951,15 @@ p2bit(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) | ||||||
|         *out++ = (L(&palette[in[x]*4]) >= 128000) ? 255 : 0; |         *out++ = (L(&palette[in[x]*4]) >= 128000) ? 255 : 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void | ||||||
|  | pa2bit(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) | ||||||
|  | { | ||||||
|  |     int x; | ||||||
|  |     /* FIXME: precalculate greyscale palette? */ | ||||||
|  |     for (x = 0; x < xsize; x++, in += 4) | ||||||
|  |         *out++ = (L(&palette[in[0]*4]) >= 128000) ? 255 : 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static void | static void | ||||||
| p2l(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) | p2l(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) | ||||||
| { | { | ||||||
|  | @ -922,6 +969,28 @@ p2l(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) | ||||||
|         *out++ = L(&palette[in[x]*4]) / 1000; |         *out++ = L(&palette[in[x]*4]) / 1000; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void | ||||||
|  | pa2l(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) | ||||||
|  | { | ||||||
|  |     int x; | ||||||
|  |     /* FIXME: precalculate greyscale palette? */ | ||||||
|  |     for (x = 0; x < xsize; x++, in += 4) | ||||||
|  |         *out++ = L(&palette[in[0]*4]) / 1000; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | p2pa(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) | ||||||
|  | { | ||||||
|  |     int x; | ||||||
|  |     for (x = 0; x < xsize; x++, in+=4) { | ||||||
|  |         const UINT8* rgba = &palette[in[0] * 4]; | ||||||
|  |         *out++ = in[0]; | ||||||
|  |         *out++ = in[0]; | ||||||
|  |         *out++ = in[0]; | ||||||
|  |         *out++ = rgba[3]; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static void | static void | ||||||
| p2la(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) | p2la(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) | ||||||
| { | { | ||||||
|  | @ -939,9 +1008,9 @@ pa2la(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) | ||||||
| { | { | ||||||
|     int x; |     int x; | ||||||
|     /* FIXME: precalculate greyscale palette? */ |     /* FIXME: precalculate greyscale palette? */ | ||||||
|     for (x = 0; x < xsize; x++, in += 2) { |     for (x = 0; x < xsize; x++, in += 4, out += 4) { | ||||||
|         *out++ = L(&palette[in[0]*4]) / 1000; |         out[0] = out[1] = out[2] = L(&palette[in[0]*4]) / 1000; | ||||||
|         *out++ = in[1]; |         out[3] = in[3]; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -954,6 +1023,15 @@ p2i(UINT8* out_, const UINT8* in, int xsize, const UINT8* palette) | ||||||
|         *out++ = L(&palette[in[x]*4]) / 1000; |         *out++ = L(&palette[in[x]*4]) / 1000; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void | ||||||
|  | pa2i(UINT8* out_, const UINT8* in, int xsize, const UINT8* palette) | ||||||
|  | { | ||||||
|  |     int x; | ||||||
|  |     INT32* out = (INT32*) out_; | ||||||
|  |     for (x = 0; x < xsize; x++, in += 4) | ||||||
|  |         *out++ = L(&palette[in[0]*4]) / 1000; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static void | static void | ||||||
| p2f(UINT8* out_, const UINT8* in, int xsize, const UINT8* palette) | p2f(UINT8* out_, const UINT8* in, int xsize, const UINT8* palette) | ||||||
| { | { | ||||||
|  | @ -963,6 +1041,15 @@ p2f(UINT8* out_, const UINT8* in, int xsize, const UINT8* palette) | ||||||
|         *out++ = (float) L(&palette[in[x]*4]) / 1000.0F; |         *out++ = (float) L(&palette[in[x]*4]) / 1000.0F; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void | ||||||
|  | pa2f(UINT8* out_, const UINT8* in, int xsize, const UINT8* palette) | ||||||
|  | { | ||||||
|  |     int x; | ||||||
|  |     FLOAT32* out = (FLOAT32*) out_; | ||||||
|  |     for (x = 0; x < xsize; x++, in += 4) | ||||||
|  |         *out++ = (float) L(&palette[in[0]*4]) / 1000.0F; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static void | static void | ||||||
| p2rgb(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) | p2rgb(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) | ||||||
| { | { | ||||||
|  | @ -976,6 +1063,19 @@ p2rgb(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void | ||||||
|  | pa2rgb(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) | ||||||
|  | { | ||||||
|  |     int x; | ||||||
|  |     for (x = 0; x < xsize; x++, in += 4) { | ||||||
|  |         const UINT8* rgb = &palette[in[0] * 4]; | ||||||
|  |         *out++ = rgb[0]; | ||||||
|  |         *out++ = rgb[1]; | ||||||
|  |         *out++ = rgb[2]; | ||||||
|  |         *out++ = 255; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static void | static void | ||||||
| p2rgba(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) | p2rgba(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) | ||||||
| { | { | ||||||
|  | @ -1009,6 +1109,13 @@ p2cmyk(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) | ||||||
|     rgb2cmyk(out, out, xsize); |     rgb2cmyk(out, out, xsize); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void | ||||||
|  | pa2cmyk(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) | ||||||
|  | { | ||||||
|  |     pa2rgb(out, in, xsize, palette); | ||||||
|  |     rgb2cmyk(out, out, xsize); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static void | static void | ||||||
| p2ycbcr(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) | p2ycbcr(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) | ||||||
| { | { | ||||||
|  | @ -1016,6 +1123,13 @@ p2ycbcr(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) | ||||||
|     ImagingConvertRGB2YCbCr(out, out, xsize); |     ImagingConvertRGB2YCbCr(out, out, xsize); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void | ||||||
|  | pa2ycbcr(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) | ||||||
|  | { | ||||||
|  |     pa2rgb(out, in, xsize, palette); | ||||||
|  |     ImagingConvertRGB2YCbCr(out, out, xsize); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static Imaging | static Imaging | ||||||
| frompalette(Imaging imOut, Imaging imIn, const char *mode) | frompalette(Imaging imOut, Imaging imIn, const char *mode) | ||||||
| { | { | ||||||
|  | @ -1032,27 +1146,27 @@ frompalette(Imaging imOut, Imaging imIn, const char *mode) | ||||||
|     alpha = !strcmp(imIn->mode, "PA"); |     alpha = !strcmp(imIn->mode, "PA"); | ||||||
| 
 | 
 | ||||||
|     if (strcmp(mode, "1") == 0) |     if (strcmp(mode, "1") == 0) | ||||||
|         convert = p2bit; |         convert = alpha ? pa2bit : p2bit; | ||||||
|     else if (strcmp(mode, "L") == 0) |     else if (strcmp(mode, "L") == 0) | ||||||
|         convert = p2l; |         convert = alpha ? pa2l : p2l; | ||||||
|     else if (strcmp(mode, "LA") == 0) |     else if (strcmp(mode, "LA") == 0) | ||||||
|         convert = (alpha) ? pa2la : p2la; |         convert = alpha ? pa2la : p2la; | ||||||
|     else if (strcmp(mode, "PA") == 0) |     else if (strcmp(mode, "PA") == 0) | ||||||
|         convert = l2la; |         convert = p2pa; | ||||||
|     else if (strcmp(mode, "I") == 0) |     else if (strcmp(mode, "I") == 0) | ||||||
|         convert = p2i; |         convert = alpha ? pa2i : p2i; | ||||||
|     else if (strcmp(mode, "F") == 0) |     else if (strcmp(mode, "F") == 0) | ||||||
|         convert = p2f; |         convert = alpha ? pa2f : p2f; | ||||||
|     else if (strcmp(mode, "RGB") == 0) |     else if (strcmp(mode, "RGB") == 0) | ||||||
|         convert = p2rgb; |         convert = alpha ? pa2rgb : p2rgb; | ||||||
|     else if (strcmp(mode, "RGBA") == 0) |     else if (strcmp(mode, "RGBA") == 0) | ||||||
|         convert = (alpha) ? pa2rgba : p2rgba; |         convert = alpha ? pa2rgba : p2rgba; | ||||||
|     else if (strcmp(mode, "RGBX") == 0) |     else if (strcmp(mode, "RGBX") == 0) | ||||||
|         convert = p2rgba; |         convert = alpha ? pa2rgba : p2rgba; | ||||||
|     else if (strcmp(mode, "CMYK") == 0) |     else if (strcmp(mode, "CMYK") == 0) | ||||||
|         convert = p2cmyk; |         convert = alpha ? pa2cmyk : p2cmyk; | ||||||
|     else if (strcmp(mode, "YCbCr") == 0) |     else if (strcmp(mode, "YCbCr") == 0) | ||||||
|         convert = p2ycbcr; |         convert = alpha ? pa2ycbcr : p2ycbcr; | ||||||
|     else |     else | ||||||
|         return (Imaging) ImagingError_ValueError("conversion not supported"); |         return (Imaging) ImagingError_ValueError("conversion not supported"); | ||||||
| 
 | 
 | ||||||
|  | @ -1073,9 +1187,10 @@ frompalette(Imaging imOut, Imaging imIn, const char *mode) | ||||||
| #pragma optimize("", off) | #pragma optimize("", off) | ||||||
| #endif | #endif | ||||||
| static Imaging | static Imaging | ||||||
| topalette(Imaging imOut, Imaging imIn, ImagingPalette inpalette, int dither) | topalette(Imaging imOut, Imaging imIn, const char *mode, ImagingPalette inpalette, int dither) | ||||||
| { | { | ||||||
|     ImagingSectionCookie cookie; |     ImagingSectionCookie cookie; | ||||||
|  |     int alpha; | ||||||
|     int x, y; |     int x, y; | ||||||
|     ImagingPalette palette = inpalette;; |     ImagingPalette palette = inpalette;; | ||||||
| 
 | 
 | ||||||
|  | @ -1083,6 +1198,8 @@ topalette(Imaging imOut, Imaging imIn, ImagingPalette inpalette, int dither) | ||||||
|     if (strcmp(imIn->mode, "L") != 0 && strncmp(imIn->mode, "RGB", 3) != 0) |     if (strcmp(imIn->mode, "L") != 0 && strncmp(imIn->mode, "RGB", 3) != 0) | ||||||
|         return (Imaging) ImagingError_ValueError("conversion not supported"); |         return (Imaging) ImagingError_ValueError("conversion not supported"); | ||||||
| 
 | 
 | ||||||
|  |     alpha = !strcmp(mode, "PA"); | ||||||
|  | 
 | ||||||
|     if (palette == NULL) { |     if (palette == NULL) { | ||||||
|       /* FIXME: make user configurable */ |       /* FIXME: make user configurable */ | ||||||
|       if (imIn->bands == 1) |       if (imIn->bands == 1) | ||||||
|  | @ -1094,7 +1211,7 @@ topalette(Imaging imOut, Imaging imIn, ImagingPalette inpalette, int dither) | ||||||
|     if (!palette) |     if (!palette) | ||||||
|         return (Imaging) ImagingError_ValueError("no palette"); |         return (Imaging) ImagingError_ValueError("no palette"); | ||||||
| 
 | 
 | ||||||
|     imOut = ImagingNew2Dirty("P", imOut, imIn); |     imOut = ImagingNew2Dirty(mode, imOut, imIn); | ||||||
|     if (!imOut) { |     if (!imOut) { | ||||||
|       if (palette != inpalette) |       if (palette != inpalette) | ||||||
|         ImagingPaletteDelete(palette); |         ImagingPaletteDelete(palette); | ||||||
|  | @ -1109,8 +1226,13 @@ topalette(Imaging imOut, Imaging imIn, ImagingPalette inpalette, int dither) | ||||||
| 
 | 
 | ||||||
|         /* Greyscale palette: copy data as is */ |         /* Greyscale palette: copy data as is */ | ||||||
|         ImagingSectionEnter(&cookie); |         ImagingSectionEnter(&cookie); | ||||||
|         for (y = 0; y < imIn->ysize; y++) |         for (y = 0; y < imIn->ysize; y++) { | ||||||
|             memcpy(imOut->image[y], imIn->image[y], imIn->linesize); |             if (alpha) { | ||||||
|  |                 l2la((UINT8*) imOut->image[y], (UINT8*) imIn->image[y], imIn->xsize); | ||||||
|  |             } else { | ||||||
|  |                 memcpy(imOut->image[y], imIn->image[y], imIn->linesize); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|         ImagingSectionLeave(&cookie); |         ImagingSectionLeave(&cookie); | ||||||
| 
 | 
 | ||||||
|     } else { |     } else { | ||||||
|  | @ -1141,7 +1263,7 @@ topalette(Imaging imOut, Imaging imIn, ImagingPalette inpalette, int dither) | ||||||
|                 int g, g0, g1, g2; |                 int g, g0, g1, g2; | ||||||
|                 int b, b0, b1, b2; |                 int b, b0, b1, b2; | ||||||
|                 UINT8* in  = (UINT8*) imIn->image[y]; |                 UINT8* in  = (UINT8*) imIn->image[y]; | ||||||
|                 UINT8* out = imOut->image8[y]; |                 UINT8* out = alpha ? (UINT8*) imOut->image32[y] : imOut->image8[y]; | ||||||
|                 int* e = errors; |                 int* e = errors; | ||||||
| 
 | 
 | ||||||
|                 r = r0 = r1 = 0; |                 r = r0 = r1 = 0; | ||||||
|  | @ -1160,7 +1282,12 @@ topalette(Imaging imOut, Imaging imIn, ImagingPalette inpalette, int dither) | ||||||
|                     cache = &ImagingPaletteCache(palette, r, g, b); |                     cache = &ImagingPaletteCache(palette, r, g, b); | ||||||
|                     if (cache[0] == 0x100) |                     if (cache[0] == 0x100) | ||||||
|                         ImagingPaletteCacheUpdate(palette, r, g, b); |                         ImagingPaletteCacheUpdate(palette, r, g, b); | ||||||
|                     out[x] = (UINT8) cache[0]; |                     if (alpha) { | ||||||
|  |                         out[x*4] = out[x*4+1] = out[x*4+2] = (UINT8) cache[0]; | ||||||
|  |                         out[x*4+3] = 255; | ||||||
|  |                     } else { | ||||||
|  |                         out[x] = (UINT8) cache[0]; | ||||||
|  |                     } | ||||||
| 
 | 
 | ||||||
|                     r -= (int) palette->palette[cache[0]*4]; |                     r -= (int) palette->palette[cache[0]*4]; | ||||||
|                     g -= (int) palette->palette[cache[0]*4+1]; |                     g -= (int) palette->palette[cache[0]*4+1]; | ||||||
|  | @ -1193,7 +1320,7 @@ topalette(Imaging imOut, Imaging imIn, ImagingPalette inpalette, int dither) | ||||||
|             for (y = 0; y < imIn->ysize; y++) { |             for (y = 0; y < imIn->ysize; y++) { | ||||||
|                 int r, g, b; |                 int r, g, b; | ||||||
|                 UINT8* in  = (UINT8*) imIn->image[y]; |                 UINT8* in  = (UINT8*) imIn->image[y]; | ||||||
|                 UINT8* out = imOut->image8[y]; |                 UINT8* out = alpha ? (UINT8*) imOut->image32[y] : imOut->image8[y]; | ||||||
| 
 | 
 | ||||||
|                 for (x = 0; x < imIn->xsize; x++, in += 4) { |                 for (x = 0; x < imIn->xsize; x++, in += 4) { | ||||||
|                     INT16* cache; |                     INT16* cache; | ||||||
|  | @ -1204,8 +1331,12 @@ topalette(Imaging imOut, Imaging imIn, ImagingPalette inpalette, int dither) | ||||||
|                     cache = &ImagingPaletteCache(palette, r, g, b); |                     cache = &ImagingPaletteCache(palette, r, g, b); | ||||||
|                     if (cache[0] == 0x100) |                     if (cache[0] == 0x100) | ||||||
|                         ImagingPaletteCacheUpdate(palette, r, g, b); |                         ImagingPaletteCacheUpdate(palette, r, g, b); | ||||||
|                     out[x] = (UINT8) cache[0]; |                     if (alpha) { | ||||||
| 
 |                         out[x*4] = out[x*4+1] = out[x*4+2] = (UINT8) cache[0]; | ||||||
|  |                         out[x*4+3] = 255; | ||||||
|  |                     } else { | ||||||
|  |                         out[x] = (UINT8) cache[0]; | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             ImagingSectionLeave(&cookie); |             ImagingSectionLeave(&cookie); | ||||||
|  | @ -1335,8 +1466,8 @@ convert(Imaging imOut, Imaging imIn, const char *mode, | ||||||
|     if (strcmp(imIn->mode, "P") == 0 || strcmp(imIn->mode, "PA") == 0) |     if (strcmp(imIn->mode, "P") == 0 || strcmp(imIn->mode, "PA") == 0) | ||||||
|         return frompalette(imOut, imIn, mode); |         return frompalette(imOut, imIn, mode); | ||||||
| 
 | 
 | ||||||
|     if (strcmp(mode, "P") == 0) |     if (strcmp(mode, "P") == 0 || strcmp(mode, "PA") == 0) | ||||||
|         return topalette(imOut, imIn, palette, dither); |         return topalette(imOut, imIn, mode, palette, dither); | ||||||
| 
 | 
 | ||||||
|     if (dither && strcmp(mode, "1") == 0) |     if (dither && strcmp(mode, "1") == 0) | ||||||
|         return tobilevel(imOut, imIn, dither); |         return tobilevel(imOut, imIn, dither); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user