Add BGRa for compatibility with cairo

This commit is contained in:
Arjen Nienhuis 2016-08-06 10:54:58 +02:00
parent bc2c933552
commit 53eb33dd6d
5 changed files with 70 additions and 0 deletions

View File

@ -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")

View File

@ -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 },

View File

@ -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},

View File

@ -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;

View File

@ -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},