Bug 1551084 - Part 4. Add support for BGRA to QCMS. r=miko

Differential Revision: https://phabricator.services.mozilla.com/D30821
This commit is contained in:
Andrew Osmond 2019-05-09 16:45:51 -04:00
parent 811c958f2b
commit 1871421d78
8 changed files with 137 additions and 37 deletions

View File

@ -109,6 +109,7 @@ typedef enum {
typedef enum {
QCMS_DATA_RGB_8,
QCMS_DATA_RGBA_8,
QCMS_DATA_BGRA_8,
QCMS_DATA_GRAY_8,
QCMS_DATA_GRAYA_8
} qcms_data_type;

View File

@ -272,6 +272,10 @@ void qcms_transform_data_rgba_out_lut_sse2(const qcms_transform *transform,
const unsigned char *src,
unsigned char *dest,
size_t length);
void qcms_transform_data_bgra_out_lut_sse2(const qcms_transform *transform,
const unsigned char *src,
unsigned char *dest,
size_t length);
void qcms_transform_data_rgb_out_lut_sse1(const qcms_transform *transform,
const unsigned char *src,
unsigned char *dest,
@ -280,6 +284,10 @@ void qcms_transform_data_rgba_out_lut_sse1(const qcms_transform *transform,
const unsigned char *src,
unsigned char *dest,
size_t length);
void qcms_transform_data_bgra_out_lut_sse1(const qcms_transform *transform,
const unsigned char *src,
unsigned char *dest,
size_t length);
void qcms_transform_data_rgb_out_lut_altivec(const qcms_transform *transform,
const unsigned char *src,
@ -289,6 +297,10 @@ void qcms_transform_data_rgba_out_lut_altivec(const qcms_transform *transform,
const unsigned char *src,
unsigned char *dest,
size_t length);
void qcms_transform_data_bgra_out_lut_altivec(const qcms_transform *transform,
const unsigned char *src,
unsigned char *dest,
size_t length);
extern bool qcms_supports_iccv4;

View File

@ -179,3 +179,11 @@ void qcms_transform_data_rgba_out_lut_altivec(const qcms_transform *transform,
{
qcms_transform_data_template_lut_altivec<RGBA_R_INDEX, RGBA_G_INDEX, RGBA_B_INDEX, RGBA_A_INDEX>(transform, src, dest, length);
}
void qcms_transform_data_bgra_out_lut_altivec(const qcms_transform *transform,
const unsigned char *src,
unsigned char *dest,
size_t length)
{
qcms_transform_data_template_lut_altivec<BGRA_R_INDEX, BGRA_G_INDEX, BGRA_B_INDEX, BGRA_A_INDEX>(transform, src, dest, length);
}

View File

@ -158,3 +158,11 @@ void qcms_transform_data_rgba_out_lut_sse1(const qcms_transform *transform,
{
qcms_transform_data_template_lut_sse1<RGBA_R_INDEX, RGBA_G_INDEX, RGBA_B_INDEX, RGBA_A_INDEX>(transform, src, dest, length);
}
void qcms_transform_data_bgra_out_lut_sse1(const qcms_transform *transform,
const unsigned char *src,
unsigned char *dest,
size_t length)
{
qcms_transform_data_template_lut_sse1<BGRA_R_INDEX, BGRA_G_INDEX, BGRA_B_INDEX, BGRA_A_INDEX>(transform, src, dest, length);
}

View File

@ -152,3 +152,11 @@ void qcms_transform_data_rgba_out_lut_sse2(const qcms_transform *transform,
{
qcms_transform_data_template_lut_sse2<RGBA_R_INDEX, RGBA_G_INDEX, RGBA_B_INDEX, RGBA_A_INDEX>(transform, src, dest, length);
}
void qcms_transform_data_bgra_out_lut_sse2(const qcms_transform *transform,
const unsigned char *src,
unsigned char *dest,
size_t length)
{
qcms_transform_data_template_lut_sse2<BGRA_R_INDEX, BGRA_G_INDEX, BGRA_B_INDEX, BGRA_A_INDEX>(transform, src, dest, length);
}

View File

@ -394,11 +394,16 @@ static void qcms_transform_data_gray_out_lut(const qcms_transform *transform, co
qcms_transform_data_gray_template_lut<RGBA_R_INDEX, RGBA_G_INDEX, RGBA_B_INDEX>(transform, src, dest, length);
}
static void qcms_transform_data_graya_out_lut(const qcms_transform *transform, const unsigned char *src, unsigned char *dest, size_t length)
static void qcms_transform_data_graya_rgba_out_lut(const qcms_transform *transform, const unsigned char *src, unsigned char *dest, size_t length)
{
qcms_transform_data_gray_template_lut<RGBA_R_INDEX, RGBA_G_INDEX, RGBA_B_INDEX, RGBA_A_INDEX>(transform, src, dest, length);
}
static void qcms_transform_data_graya_bgra_out_lut(const qcms_transform *transform, const unsigned char *src, unsigned char *dest, size_t length)
{
qcms_transform_data_gray_template_lut<BGRA_R_INDEX, BGRA_G_INDEX, BGRA_B_INDEX, BGRA_A_INDEX>(transform, src, dest, length);
}
template <size_t kRIndex, size_t kGIndex, size_t kBIndex, size_t kAIndex = NO_A_INDEX>
static void qcms_transform_data_gray_template_precache(const qcms_transform *transform, const unsigned char *src, unsigned char *dest, size_t length)
{
@ -432,11 +437,16 @@ static void qcms_transform_data_gray_out_precache(const qcms_transform *transfor
qcms_transform_data_gray_template_precache<RGBA_R_INDEX, RGBA_G_INDEX, RGBA_B_INDEX>(transform, src, dest, length);
}
static void qcms_transform_data_graya_out_precache(const qcms_transform *transform, const unsigned char *src, unsigned char *dest, size_t length)
static void qcms_transform_data_graya_rgba_out_precache(const qcms_transform *transform, const unsigned char *src, unsigned char *dest, size_t length)
{
qcms_transform_data_gray_template_precache<RGBA_R_INDEX, RGBA_G_INDEX, RGBA_B_INDEX, RGBA_A_INDEX>(transform, src, dest, length);
}
static void qcms_transform_data_graya_bgra_out_precache(const qcms_transform *transform, const unsigned char *src, unsigned char *dest, size_t length)
{
qcms_transform_data_gray_template_precache<BGRA_R_INDEX, BGRA_G_INDEX, BGRA_B_INDEX, BGRA_A_INDEX>(transform, src, dest, length);
}
template <size_t kRIndex, size_t kGIndex, size_t kBIndex, size_t kAIndex = NO_A_INDEX>
static void qcms_transform_data_template_lut_precache(const qcms_transform *transform, const unsigned char *src, unsigned char *dest, size_t length)
{
@ -491,6 +501,11 @@ static void qcms_transform_data_rgba_out_lut_precache(const qcms_transform *tran
qcms_transform_data_template_lut_precache<RGBA_R_INDEX, RGBA_G_INDEX, RGBA_B_INDEX, RGBA_A_INDEX>(transform, src, dest, length);
}
static void qcms_transform_data_bgra_out_lut_precache(const qcms_transform *transform, const unsigned char *src, unsigned char *dest, size_t length)
{
qcms_transform_data_template_lut_precache<BGRA_R_INDEX, BGRA_G_INDEX, BGRA_B_INDEX, BGRA_A_INDEX>(transform, src, dest, length);
}
// Not used
/*
static void qcms_transform_data_clut(const qcms_transform *transform, const unsigned char *src, unsigned char *dest, size_t length) {
@ -741,6 +756,11 @@ static void qcms_transform_data_rgba_out_lut(const qcms_transform *transform, co
qcms_transform_data_template_lut<RGBA_R_INDEX, RGBA_G_INDEX, RGBA_B_INDEX, RGBA_A_INDEX>(transform, src, dest, length);
}
static void qcms_transform_data_bgra_out_lut(const qcms_transform *transform, const unsigned char *src, unsigned char *dest, size_t length)
{
qcms_transform_data_template_lut<BGRA_R_INDEX, BGRA_G_INDEX, BGRA_B_INDEX, BGRA_A_INDEX>(transform, src, dest, length);
}
#if 0
static void qcms_transform_data_rgb_out_linear(const qcms_transform *transform, const unsigned char *src, unsigned char *dest, size_t length)
{
@ -1088,19 +1108,30 @@ qcms_transform* qcms_transform_create(
qcms_profile *out, qcms_data_type out_type,
qcms_intent intent)
{
bool precache = false;
// Ensure the requested input and output types make sense.
bool match = false;
if (in_type == QCMS_DATA_RGB_8) {
match = out_type == QCMS_DATA_RGB_8;
} else if (in_type == QCMS_DATA_RGBA_8) {
match = out_type == QCMS_DATA_RGBA_8;
} else if (in_type == QCMS_DATA_BGRA_8) {
match = out_type == QCMS_DATA_BGRA_8;
} else if (in_type == QCMS_DATA_GRAY_8) {
match = out_type == QCMS_DATA_RGB_8;
} else if (in_type == QCMS_DATA_GRAYA_8) {
match = out_type == QCMS_DATA_RGBA_8 || out_type == QCMS_DATA_BGRA_8;
}
if (!match) {
assert(0 && "input/output type");
return NULL;
}
qcms_transform *transform = transform_alloc();
if (!transform) {
return NULL;
}
if (out_type != QCMS_DATA_RGB_8 &&
out_type != QCMS_DATA_RGBA_8) {
assert(0 && "output type");
qcms_transform_release(transform);
return NULL;
}
bool precache = false;
if (out->output_table_r &&
out->output_table_g &&
out->output_table_b) {
@ -1146,52 +1177,60 @@ qcms_transform* qcms_transform_create(
if (in->color_space == RGB_SIGNATURE) {
struct matrix in_matrix, out_matrix, result;
if (in_type != QCMS_DATA_RGB_8 &&
in_type != QCMS_DATA_RGBA_8){
assert(0 && "input type");
qcms_transform_release(transform);
return NULL;
}
if (precache) {
#ifdef X86
if (sse_version_available() >= 2) {
if (in_type == QCMS_DATA_RGB_8)
if (in_type == QCMS_DATA_RGB_8) {
transform->transform_fn = qcms_transform_data_rgb_out_lut_sse2;
else
} else if (in_type == QCMS_DATA_RGBA_8) {
transform->transform_fn = qcms_transform_data_rgba_out_lut_sse2;
} else if (in_type == QCMS_DATA_BGRA_8) {
transform->transform_fn = qcms_transform_data_bgra_out_lut_sse2;
}
#if !(defined(_MSC_VER) && defined(_M_AMD64))
/* Microsoft Compiler for x64 doesn't support MMX.
* SSE code uses MMX so that we disable on x64 */
} else
if (sse_version_available() >= 1) {
if (in_type == QCMS_DATA_RGB_8)
if (in_type == QCMS_DATA_RGB_8) {
transform->transform_fn = qcms_transform_data_rgb_out_lut_sse1;
else
} else if (in_type == QCMS_DATA_RGBA_8) {
transform->transform_fn = qcms_transform_data_rgba_out_lut_sse1;
} else if (in_type == QCMS_DATA_BGRA_8) {
transform->transform_fn = qcms_transform_data_bgra_out_lut_sse1;
}
#endif
} else
#endif
#if (defined(__POWERPC__) || defined(__powerpc__) && !defined(__NO_FPRS__))
if (have_altivec()) {
if (in_type == QCMS_DATA_RGB_8)
if (in_type == QCMS_DATA_RGB_8) {
transform->transform_fn = qcms_transform_data_rgb_out_lut_altivec;
else
} else if (in_type == QCMS_DATA_RGBA_8) {
transform->transform_fn = qcms_transform_data_rgba_out_lut_altivec;
} else if (in_type == QCMS_DATA_BGRA_8) {
transform->transform_fn = qcms_transform_data_bgra_out_lut_altivec;
}
} else
#endif
{
if (in_type == QCMS_DATA_RGB_8)
if (in_type == QCMS_DATA_RGB_8) {
transform->transform_fn = qcms_transform_data_rgb_out_lut_precache;
else
} else if (in_type == QCMS_DATA_RGBA_8) {
transform->transform_fn = qcms_transform_data_rgba_out_lut_precache;
} else if (in_type == QCMS_DATA_BGRA_8) {
transform->transform_fn = qcms_transform_data_bgra_out_lut_precache;
}
}
} else {
if (in_type == QCMS_DATA_RGB_8)
if (in_type == QCMS_DATA_RGB_8) {
transform->transform_fn = qcms_transform_data_rgb_out_lut;
else
} else if (in_type == QCMS_DATA_RGBA_8) {
transform->transform_fn = qcms_transform_data_rgba_out_lut;
} else if (in_type == QCMS_DATA_BGRA_8) {
transform->transform_fn = qcms_transform_data_bgra_out_lut;
}
}
//XXX: avoid duplicating tables if we can
@ -1237,13 +1276,6 @@ qcms_transform* qcms_transform_create(
transform->matrix[2][2] = result.m[2][2];
} else if (in->color_space == GRAY_SIGNATURE) {
if (in_type != QCMS_DATA_GRAY_8 &&
in_type != QCMS_DATA_GRAYA_8){
assert(0 && "input type");
qcms_transform_release(transform);
return NULL;
}
transform->input_gamma_table_gray = build_input_gamma_table(in->grayTRC);
if (!transform->input_gamma_table_gray) {
qcms_transform_release(transform);
@ -1253,14 +1285,18 @@ qcms_transform* qcms_transform_create(
if (precache) {
if (in_type == QCMS_DATA_GRAY_8) {
transform->transform_fn = qcms_transform_data_gray_out_precache;
} else {
transform->transform_fn = qcms_transform_data_graya_out_precache;
} else if (out_type == QCMS_DATA_RGBA_8) {
transform->transform_fn = qcms_transform_data_graya_rgba_out_precache;
} else if (out_type == QCMS_DATA_BGRA_8) {
transform->transform_fn = qcms_transform_data_graya_bgra_out_precache;
}
} else {
if (in_type == QCMS_DATA_GRAY_8) {
transform->transform_fn = qcms_transform_data_gray_out_lut;
} else {
transform->transform_fn = qcms_transform_data_graya_out_lut;
} else if (out_type == QCMS_DATA_RGBA_8) {
transform->transform_fn = qcms_transform_data_graya_rgba_out_lut;
} else if (out_type == QCMS_DATA_BGRA_8) {
transform->transform_fn = qcms_transform_data_graya_bgra_out_lut;
}
}
} else {
@ -1268,6 +1304,7 @@ qcms_transform* qcms_transform_create(
qcms_transform_release(transform);
return NULL;
}
assert(transform->transform_fn);
return transform;
}

View File

@ -166,6 +166,7 @@ static bool gCMSRGBTransformFailed = false;
static qcms_transform* gCMSRGBTransform = nullptr;
static qcms_transform* gCMSInverseRGBTransform = nullptr;
static qcms_transform* gCMSRGBATransform = nullptr;
static qcms_transform* gCMSBGRATransform = nullptr;
static bool gCMSInitialized = false;
static eCMSMode gCMSMode = eCMSMode_Off;
@ -2148,6 +2149,22 @@ qcms_transform* gfxPlatform::GetCMSRGBATransform() {
return gCMSRGBATransform;
}
qcms_transform* gfxPlatform::GetCMSBGRATransform() {
if (!gCMSBGRATransform) {
qcms_profile *inProfile, *outProfile;
outProfile = GetCMSOutputProfile();
inProfile = GetCMSsRGBProfile();
if (!inProfile || !outProfile) return nullptr;
gCMSBGRATransform =
qcms_transform_create(inProfile, QCMS_DATA_BGRA_8, outProfile,
QCMS_DATA_BGRA_8, QCMS_INTENT_PERCEPTUAL);
}
return gCMSBGRATransform;
}
/* Shuts down various transforms and profiles for CMS. */
static void ShutdownCMS() {
if (gCMSRGBTransform) {
@ -2162,6 +2179,10 @@ static void ShutdownCMS() {
qcms_transform_release(gCMSRGBATransform);
gCMSRGBATransform = nullptr;
}
if (gCMSBGRATransform) {
qcms_transform_release(gCMSBGRATransform);
gCMSBGRATransform = nullptr;
}
if (gCMSOutputProfile) {
qcms_profile_release(gCMSOutputProfile);

View File

@ -543,6 +543,11 @@ class gfxPlatform : public mozilla::layers::MemoryPressureListener {
*/
static qcms_transform* GetCMSRGBATransform();
/**
* Return sRGBA -> output device transform.
*/
static qcms_transform* GetCMSBGRATransform();
virtual void FontsPrefsChanged(const char* aPref);
int32_t GetBidiNumeralOption();