mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-10-31 07:57:27 +03:00 
			
		
		
		
	Merge pull request #7888 from radarhere/convert_rgb
This commit is contained in:
		
						commit
						d734c8b702
					
				|  | @ -183,6 +183,14 @@ def test_trns_RGB(tmp_path: Path) -> None: | ||||||
|     assert im_l.info["transparency"] == im_l.getpixel((0, 0))  # undone |     assert im_l.info["transparency"] == im_l.getpixel((0, 0))  # undone | ||||||
|     im_l.save(f) |     im_l.save(f) | ||||||
| 
 | 
 | ||||||
|  |     im_la = im.convert("LA") | ||||||
|  |     assert "transparency" not in im_la.info | ||||||
|  |     im_la.save(f) | ||||||
|  | 
 | ||||||
|  |     im_la = im.convert("La") | ||||||
|  |     assert "transparency" not in im_la.info | ||||||
|  |     assert im_la.getpixel((0, 0)) == (0, 0) | ||||||
|  | 
 | ||||||
|     im_p = im.convert("P") |     im_p = im.convert("P") | ||||||
|     assert "transparency" in im_p.info |     assert "transparency" in im_p.info | ||||||
|     im_p.save(f) |     im_p.save(f) | ||||||
|  | @ -191,6 +199,10 @@ def test_trns_RGB(tmp_path: Path) -> None: | ||||||
|     assert "transparency" not in im_rgba.info |     assert "transparency" not in im_rgba.info | ||||||
|     im_rgba.save(f) |     im_rgba.save(f) | ||||||
| 
 | 
 | ||||||
|  |     im_rgba = im.convert("RGBa") | ||||||
|  |     assert "transparency" not in im_rgba.info | ||||||
|  |     assert im_rgba.getpixel((0, 0)) == (0, 0, 0, 0) | ||||||
|  | 
 | ||||||
|     im_p = pytest.warns(UserWarning, im.convert, "P", palette=Image.Palette.ADAPTIVE) |     im_p = pytest.warns(UserWarning, im.convert, "P", palette=Image.Palette.ADAPTIVE) | ||||||
|     assert "transparency" not in im_p.info |     assert "transparency" not in im_p.info | ||||||
|     im_p.save(f) |     im_p.save(f) | ||||||
|  |  | ||||||
|  | @ -978,7 +978,7 @@ class Image: | ||||||
|         # transparency handling |         # transparency handling | ||||||
|         if has_transparency: |         if has_transparency: | ||||||
|             if (self.mode in ("1", "L", "I", "I;16") and mode in ("LA", "RGBA")) or ( |             if (self.mode in ("1", "L", "I", "I;16") and mode in ("LA", "RGBA")) or ( | ||||||
|                 self.mode == "RGB" and mode == "RGBA" |                 self.mode == "RGB" and mode in ("La", "LA", "RGBa", "RGBA") | ||||||
|             ): |             ): | ||||||
|                 # Use transparent conversion to promote from transparent |                 # Use transparent conversion to promote from transparent | ||||||
|                 # color to an alpha channel. |                 # color to an alpha channel. | ||||||
|  |  | ||||||
|  | @ -499,26 +499,27 @@ rgba2rgb_(UINT8 *out, const UINT8 *in, int xsize) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Conversion of RGB + single transparent color to RGBA, |  * Conversion of RGB + single transparent color either to | ||||||
|  * where any pixel that matches the color will have the |  * RGBA or LA, where any pixel matching the color will have the alpha channel set to 0, or | ||||||
|  * alpha channel set to 0 |  * RGBa or La, where any pixel matching the color will have all channels set to 0 | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| static void | static void | ||||||
| rgbT2rgba(UINT8 *out, int xsize, int r, int g, int b) { | rgbT2a(UINT8 *out, UINT8 *in, int xsize, int r, int g, int b, int premultiplied) { | ||||||
| #ifdef WORDS_BIGENDIAN | #ifdef WORDS_BIGENDIAN | ||||||
|     UINT32 trns = ((r & 0xff) << 24) | ((g & 0xff) << 16) | ((b & 0xff) << 8) | 0xff; |     UINT32 trns = ((r & 0xff) << 24) | ((g & 0xff) << 16) | ((b & 0xff) << 8) | 0xff; | ||||||
|     UINT32 repl = trns & 0xffffff00; |     UINT32 repl = premultiplied ? 0 : (trns & 0xffffff00); | ||||||
| #else | #else | ||||||
|     UINT32 trns = (0xffU << 24) | ((b & 0xff) << 16) | ((g & 0xff) << 8) | (r & 0xff); |     UINT32 trns = (0xffU << 24) | ((b & 0xff) << 16) | ((g & 0xff) << 8) | (r & 0xff); | ||||||
|     UINT32 repl = trns & 0x00ffffff; |     UINT32 repl = premultiplied ? 0 : (trns & 0x00ffffff); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|     int i; |     int i; | ||||||
| 
 | 
 | ||||||
|     for (i = 0; i < xsize; i++, out += sizeof(trns)) { |     UINT8 *ref = in != NULL ? in : out; | ||||||
|  |     for (i = 0; i < xsize; i++, ref += sizeof(trns), out += sizeof(trns)) { | ||||||
|         UINT32 v; |         UINT32 v; | ||||||
|         memcpy(&v, out, sizeof(v)); |         memcpy(&v, ref, sizeof(v)); | ||||||
|         if (v == trns) { |         if (v == trns) { | ||||||
|             memcpy(out, &repl, sizeof(repl)); |             memcpy(out, &repl, sizeof(repl)); | ||||||
|         } |         } | ||||||
|  | @ -941,12 +942,14 @@ static struct { | ||||||
|     {"RGB", "1", rgb2bit}, |     {"RGB", "1", rgb2bit}, | ||||||
|     {"RGB", "L", rgb2l}, |     {"RGB", "L", rgb2l}, | ||||||
|     {"RGB", "LA", rgb2la}, |     {"RGB", "LA", rgb2la}, | ||||||
|  |     {"RGB", "La", rgb2la}, | ||||||
|     {"RGB", "I", rgb2i}, |     {"RGB", "I", rgb2i}, | ||||||
|     {"RGB", "F", rgb2f}, |     {"RGB", "F", rgb2f}, | ||||||
|     {"RGB", "BGR;15", rgb2bgr15}, |     {"RGB", "BGR;15", rgb2bgr15}, | ||||||
|     {"RGB", "BGR;16", rgb2bgr16}, |     {"RGB", "BGR;16", rgb2bgr16}, | ||||||
|     {"RGB", "BGR;24", rgb2bgr24}, |     {"RGB", "BGR;24", rgb2bgr24}, | ||||||
|     {"RGB", "RGBA", rgb2rgba}, |     {"RGB", "RGBA", rgb2rgba}, | ||||||
|  |     {"RGB", "RGBa", rgb2rgba}, | ||||||
|     {"RGB", "RGBX", rgb2rgba}, |     {"RGB", "RGBX", rgb2rgba}, | ||||||
|     {"RGB", "CMYK", rgb2cmyk}, |     {"RGB", "CMYK", rgb2cmyk}, | ||||||
|     {"RGB", "YCbCr", ImagingConvertRGB2YCbCr}, |     {"RGB", "YCbCr", ImagingConvertRGB2YCbCr}, | ||||||
|  | @ -1681,14 +1684,27 @@ ImagingConvertTransparent(Imaging imIn, const char *mode, int r, int g, int b) { | ||||||
|     ImagingSectionCookie cookie; |     ImagingSectionCookie cookie; | ||||||
|     ImagingShuffler convert; |     ImagingShuffler convert; | ||||||
|     Imaging imOut = NULL; |     Imaging imOut = NULL; | ||||||
|  |     int premultiplied = 0; | ||||||
|  |     // If the transparency matches pixels in the source image, not the converted image
 | ||||||
|  |     UINT8 *source; | ||||||
|  |     int source_transparency = 0; | ||||||
|     int y; |     int y; | ||||||
| 
 | 
 | ||||||
|     if (!imIn) { |     if (!imIn) { | ||||||
|         return (Imaging)ImagingError_ModeError(); |         return (Imaging)ImagingError_ModeError(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (strcmp(imIn->mode, "RGB") == 0 && strcmp(mode, "RGBA") == 0) { |     if (strcmp(imIn->mode, "RGB") == 0 && (strcmp(mode, "RGBA") == 0 || strcmp(mode, "RGBa") == 0)) { | ||||||
|         convert = rgb2rgba; |         convert = rgb2rgba; | ||||||
|  |         if (strcmp(mode, "RGBa") == 0) { | ||||||
|  |             premultiplied = 1; | ||||||
|  |         } | ||||||
|  |     } else if (strcmp(imIn->mode, "RGB") == 0 && (strcmp(mode, "LA") == 0 || strcmp(mode, "La") == 0)) { | ||||||
|  |         convert = rgb2la; | ||||||
|  |         source_transparency = 1; | ||||||
|  |         if (strcmp(mode, "La") == 0) { | ||||||
|  |             premultiplied = 1; | ||||||
|  |         } | ||||||
|     } else if ((strcmp(imIn->mode, "1") == 0 || |     } else if ((strcmp(imIn->mode, "1") == 0 || | ||||||
|                 strcmp(imIn->mode, "I") == 0 || |                 strcmp(imIn->mode, "I") == 0 || | ||||||
|                 strcmp(imIn->mode, "I;16") == 0 || |                 strcmp(imIn->mode, "I;16") == 0 || | ||||||
|  | @ -1726,7 +1742,9 @@ ImagingConvertTransparent(Imaging imIn, const char *mode, int r, int g, int b) { | ||||||
|     ImagingSectionEnter(&cookie); |     ImagingSectionEnter(&cookie); | ||||||
|     for (y = 0; y < imIn->ysize; y++) { |     for (y = 0; y < imIn->ysize; y++) { | ||||||
|         (*convert)((UINT8 *)imOut->image[y], (UINT8 *)imIn->image[y], imIn->xsize); |         (*convert)((UINT8 *)imOut->image[y], (UINT8 *)imIn->image[y], imIn->xsize); | ||||||
|         rgbT2rgba((UINT8 *)imOut->image[y], imIn->xsize, r, g, b); | 
 | ||||||
|  |         source = source_transparency ? (UINT8 *)imIn->image[y] : NULL; | ||||||
|  |         rgbT2a((UINT8 *)imOut->image[y], source, imIn->xsize, r, g, b, premultiplied); | ||||||
|     } |     } | ||||||
|     ImagingSectionLeave(&cookie); |     ImagingSectionLeave(&cookie); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user