diff --git a/PIL/ImageMode.py b/PIL/ImageMode.py index f78a8df90..44d466b0e 100644 --- a/PIL/ImageMode.py +++ b/PIL/ImageMode.py @@ -40,6 +40,7 @@ def getmode(mode): _modes[m] = ModeDescriptor(m, bands, basemode, basetype) # extra experimental modes _modes["RGBa"] = ModeDescriptor("RGBa", ("R", "G", "B", "a"), "RGB", "L") + _modes["BGRa"] = ModeDescriptor("BGRa", ("B", "G", "R", "a"), "BGR", "L") _modes["LA"] = ModeDescriptor("LA", ("L", "A"), "L", "L") _modes["La"] = ModeDescriptor("La", ("L", "a"), "L", "L") _modes["PA"] = ModeDescriptor("PA", ("P", "A"), "RGB", "L") diff --git a/libImaging/Convert.c b/libImaging/Convert.c index 9c562d4be..872460fdf 100644 --- a/libImaging/Convert.c +++ b/libImaging/Convert.c @@ -454,6 +454,21 @@ rgbA2rgba(UINT8* out, const UINT8* in, int xsize) } } +static void +rgbA2bgra(UINT8* out, const UINT8* in, int xsize) +{ + int x; + unsigned int alpha, tmp; + for (x = 0; x < xsize; x++) { + alpha = in[3]; + *out++ = MULDIV255(in[2], alpha, tmp); + *out++ = MULDIV255(in[1], alpha, tmp); + *out++ = MULDIV255(in[0], alpha, tmp); + *out++ = in[3]; + in += 4; + } +} + /* RGBa -> RGBA conversion to remove premultiplication Needed for correct transforms/resizing on RGBA images */ static void @@ -476,6 +491,26 @@ rgba2rgbA(UINT8* out, const UINT8* in, int xsize) } } +static void +bgra2rgbA(UINT8* out, const UINT8* in, int xsize) +{ + int x; + unsigned int alpha; + for (x = 0; x < xsize; x++, in+=4) { + alpha = in[3]; + if (alpha == 255 || alpha == 0) { + *out++ = in[2]; + *out++ = in[1]; + *out++ = in[0]; + } else { + *out++ = CLIP((255 * in[2]) / alpha); + *out++ = CLIP((255 * in[1]) / alpha); + *out++ = CLIP((255 * in[0]) / alpha); + } + *out++ = in[3]; + } +} + /* * Conversion of RGB + single transparent color to RGBA, * where any pixel that matches the color will have the @@ -834,11 +869,13 @@ static struct { { "RGBA", "F", rgb2f }, { "RGBA", "RGB", rgba2rgb }, { "RGBA", "RGBa", rgbA2rgba }, + { "RGBA", "BGRa", rgbA2bgra }, { "RGBA", "RGBX", rgb2rgba }, { "RGBA", "CMYK", rgb2cmyk }, { "RGBA", "YCbCr", ImagingConvertRGB2YCbCr }, { "RGBa", "RGBA", rgba2rgbA }, + { "BGRa", "RGBA", bgra2rgbA }, { "RGBX", "1", rgb2bit }, { "RGBX", "L", rgb2l }, diff --git a/libImaging/Pack.c b/libImaging/Pack.c index d83cb8284..0d84b65bf 100644 --- a/libImaging/Pack.c +++ b/libImaging/Pack.c @@ -534,6 +534,7 @@ static struct { {"RGBa", "RGBa", 32, copy4}, {"RGBa", "BGRa", 32, ImagingPackBGRA}, {"RGBa", "aBGR", 32, ImagingPackABGR}, + {"BGRa", "BGRa", 32, copy4}, /* true colour w. padding */ {"RGBX", "RGBX", 32, copy4}, diff --git a/libImaging/Storage.c b/libImaging/Storage.c index f40840671..54b6865d0 100644 --- a/libImaging/Storage.c +++ b/libImaging/Storage.c @@ -179,6 +179,11 @@ ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, im->bands = im->pixelsize = 4; im->linesize = xsize * 4; + } else if (strcmp(mode, "BGRa") == 0) { + /* 32-bit true colour images with premultiplied alpha */ + im->bands = im->pixelsize = 4; + im->linesize = xsize * 4; + } else if (strcmp(mode, "CMYK") == 0) { /* 32-bit colour separation */ im->bands = im->pixelsize = 4; diff --git a/libImaging/Unpack.c b/libImaging/Unpack.c index 702bc9f1f..c105d517f 100644 --- a/libImaging/Unpack.c +++ b/libImaging/Unpack.c @@ -747,6 +747,30 @@ unpackRGBa(UINT8* out, const UINT8* in, int pixels) } } +static void +unpackBGRa(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* premultiplied BGRA */ + for (i = 0; i < pixels; i++) { + int a = in[3]; + if (!a) + out[R] = out[G] = out[B] = out[A] = 0; + else if (a == 255) { + out[R] = in[2]; + out[G] = in[1]; + out[B] = in[0]; + out[A] = a; + } else { + out[R] = CLIP(in[2] * 255 / a); + out[G] = CLIP(in[1] * 255 / a); + out[B] = CLIP(in[0] * 255 / a); + out[A] = a; + } + out += 4; in += 4; + } +} + static void unpackRGBAI(UINT8* out, const UINT8* in, int pixels) { @@ -1206,6 +1230,7 @@ static struct { {"RGBA", "LA;16B", 32, unpackRGBALA16B}, {"RGBA", "RGBA", 32, copy4}, {"RGBA", "RGBa", 32, unpackRGBa}, + {"RGBA", "BGRa", 32, unpackBGRa}, {"RGBA", "RGBA;I", 32, unpackRGBAI}, {"RGBA", "RGBA;L", 32, unpackRGBAL}, {"RGBA", "RGBA;15", 16, ImagingUnpackRGBA15}, @@ -1226,6 +1251,7 @@ static struct { {"RGBa", "BGRa", 32, unpackBGRA}, {"RGBa", "aRGB", 32, unpackARGB}, {"RGBa", "aBGR", 32, unpackABGR}, + {"BGRa", "BGRa", 32, copy4}, /* true colour w. padding */ {"RGBX", "RGB", 24, ImagingUnpackRGB},