зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1555934 - Partially backout bug 1255106 part 3 to fix decoders with transparency. r=aosmond
This commit is contained in:
Родитель
c0011f4e0f
Коммит
008cb2a2d8
|
@ -116,7 +116,6 @@ nsPNGDecoder::nsPNGDecoder(RasterImage* aImage)
|
|||
mFrameIsHidden(false),
|
||||
mDisablePremultipliedAlpha(false),
|
||||
mGotInfoCallback(false),
|
||||
mUsePipeTransform(false),
|
||||
mNumFrames(0) {}
|
||||
|
||||
nsPNGDecoder::~nsPNGDecoder() {
|
||||
|
@ -213,10 +212,9 @@ nsresult nsPNGDecoder::CreateFrame(const FrameInfo& aFrameInfo) {
|
|||
pipeFlags |= SurfacePipeFlags::PROGRESSIVE_DISPLAY;
|
||||
}
|
||||
|
||||
qcms_transform* pipeTransform = mUsePipeTransform ? mTransform : nullptr;
|
||||
Maybe<SurfacePipe> pipe = SurfacePipeFactory::CreateSurfacePipe(
|
||||
this, Size(), OutputSize(), aFrameInfo.mFrameRect, mFormat, animParams,
|
||||
pipeTransform, pipeFlags);
|
||||
/*aTransform*/ nullptr, pipeFlags);
|
||||
|
||||
if (!pipe) {
|
||||
mPipe = SurfacePipe();
|
||||
|
@ -415,7 +413,8 @@ static void PNGDoGammaCorrection(png_structp png_ptr, png_infop info_ptr) {
|
|||
|
||||
// Adapted from http://www.littlecms.com/pngchrm.c example code
|
||||
static qcms_profile* PNGGetColorProfile(png_structp png_ptr, png_infop info_ptr,
|
||||
int color_type, uint32_t* intent) {
|
||||
int color_type, qcms_data_type* inType,
|
||||
uint32_t* intent) {
|
||||
qcms_profile* profile = nullptr;
|
||||
*intent = QCMS_INTENT_PERCEPTUAL; // Our default
|
||||
|
||||
|
@ -493,6 +492,24 @@ static qcms_profile* PNGGetColorProfile(png_structp png_ptr, png_infop info_ptr,
|
|||
}
|
||||
}
|
||||
|
||||
if (profile) {
|
||||
uint32_t profileSpace = qcms_profile_get_color_space(profile);
|
||||
if (profileSpace == icSigGrayData) {
|
||||
if (color_type & PNG_COLOR_MASK_ALPHA) {
|
||||
*inType = QCMS_DATA_GRAYA_8;
|
||||
} else {
|
||||
*inType = QCMS_DATA_GRAY_8;
|
||||
}
|
||||
} else {
|
||||
if (color_type & PNG_COLOR_MASK_ALPHA ||
|
||||
png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
|
||||
*inType = QCMS_DATA_RGBA_8;
|
||||
} else {
|
||||
*inType = QCMS_DATA_RGB_8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return profile;
|
||||
}
|
||||
|
||||
|
@ -570,41 +587,25 @@ void nsPNGDecoder::info_callback(png_structp png_ptr, png_infop info_ptr) {
|
|||
png_set_scale_16(png_ptr);
|
||||
}
|
||||
|
||||
// Let libpng expand interlaced images.
|
||||
const bool isInterlaced = interlace_type == PNG_INTERLACE_ADAM7;
|
||||
if (isInterlaced) {
|
||||
png_set_interlace_handling(png_ptr);
|
||||
}
|
||||
|
||||
qcms_data_type inType = QCMS_DATA_RGBA_8;
|
||||
uint32_t intent = -1;
|
||||
uint32_t pIntent;
|
||||
if (decoder->mCMSMode != eCMSMode_Off) {
|
||||
intent = gfxPlatform::GetRenderingIntent();
|
||||
decoder->mInProfile =
|
||||
PNGGetColorProfile(png_ptr, info_ptr, color_type, &pIntent);
|
||||
PNGGetColorProfile(png_ptr, info_ptr, color_type, &inType, &pIntent);
|
||||
// If we're not mandating an intent, use the one from the image.
|
||||
if (intent == uint32_t(-1)) {
|
||||
intent = pIntent;
|
||||
}
|
||||
}
|
||||
if (decoder->mInProfile && gfxPlatform::GetCMSOutputProfile()) {
|
||||
qcms_data_type inType;
|
||||
qcms_data_type outType;
|
||||
|
||||
uint32_t profileSpace = qcms_profile_get_color_space(decoder->mInProfile);
|
||||
decoder->mUsePipeTransform = profileSpace != icSigGrayData;
|
||||
if (decoder->mUsePipeTransform) {
|
||||
// If the transform happens with SurfacePipe, it will always be in BGRA.
|
||||
inType = QCMS_DATA_BGRA_8;
|
||||
outType = QCMS_DATA_BGRA_8;
|
||||
if (color_type & PNG_COLOR_MASK_ALPHA || num_trans) {
|
||||
outType = QCMS_DATA_RGBA_8;
|
||||
} else {
|
||||
if (color_type & PNG_COLOR_MASK_ALPHA) {
|
||||
inType = QCMS_DATA_GRAYA_8;
|
||||
outType = QCMS_DATA_RGBA_8;
|
||||
} else {
|
||||
inType = QCMS_DATA_GRAY_8;
|
||||
outType = QCMS_DATA_RGB_8;
|
||||
}
|
||||
outType = QCMS_DATA_RGB_8;
|
||||
}
|
||||
|
||||
decoder->mTransform = qcms_transform_create(
|
||||
|
@ -619,11 +620,20 @@ void nsPNGDecoder::info_callback(png_structp png_ptr, png_infop info_ptr) {
|
|||
}
|
||||
|
||||
if (decoder->mCMSMode == eCMSMode_All) {
|
||||
decoder->mTransform = gfxPlatform::GetCMSBGRATransform();
|
||||
decoder->mUsePipeTransform = true;
|
||||
if (color_type & PNG_COLOR_MASK_ALPHA || num_trans) {
|
||||
decoder->mTransform = gfxPlatform::GetCMSRGBATransform();
|
||||
} else {
|
||||
decoder->mTransform = gfxPlatform::GetCMSRGBTransform();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Let libpng expand interlaced images.
|
||||
const bool isInterlaced = interlace_type == PNG_INTERLACE_ADAM7;
|
||||
if (isInterlaced) {
|
||||
png_set_interlace_handling(png_ptr);
|
||||
}
|
||||
|
||||
// now all of those things we set above are used to update various struct
|
||||
// members and whatnot, after which we can get channels, rowbytes, etc.
|
||||
png_read_update_info(png_ptr, info_ptr);
|
||||
|
@ -688,8 +698,8 @@ void nsPNGDecoder::info_callback(png_structp png_ptr, png_infop info_ptr) {
|
|||
}
|
||||
#endif
|
||||
|
||||
if (decoder->mTransform && !decoder->mUsePipeTransform) {
|
||||
uint32_t bpp[] = {0, 3, 4};
|
||||
if (decoder->mTransform && (channels <= 2 || isInterlaced)) {
|
||||
uint32_t bpp[] = {0, 3, 4, 3, 4};
|
||||
decoder->mCMSLine =
|
||||
static_cast<uint8_t*>(malloc(bpp[channels] * frameRect.Width()));
|
||||
if (!decoder->mCMSLine) {
|
||||
|
@ -830,11 +840,21 @@ void nsPNGDecoder::WriteRow(uint8_t* aRow) {
|
|||
uint32_t width = uint32_t(mFrameRect.Width());
|
||||
|
||||
// Apply color management to the row, if necessary, before writing it out.
|
||||
// This is only needed for grayscale images.
|
||||
if (mTransform && !mUsePipeTransform) {
|
||||
MOZ_ASSERT(mCMSLine);
|
||||
qcms_transform_data(mTransform, rowToWrite, mCMSLine, width);
|
||||
rowToWrite = mCMSLine;
|
||||
if (mTransform) {
|
||||
if (mCMSLine) {
|
||||
qcms_transform_data(mTransform, rowToWrite, mCMSLine, width);
|
||||
|
||||
// Copy alpha over.
|
||||
if (HasAlphaChannel()) {
|
||||
for (uint32_t i = 0; i < width; ++i) {
|
||||
mCMSLine[4 * i + 3] = rowToWrite[mChannels * i + mChannels - 1];
|
||||
}
|
||||
}
|
||||
|
||||
rowToWrite = mCMSLine;
|
||||
} else {
|
||||
qcms_transform_data(mTransform, rowToWrite, rowToWrite, width);
|
||||
}
|
||||
}
|
||||
|
||||
// Write this row to the SurfacePipe.
|
||||
|
|
|
@ -101,7 +101,6 @@ class nsPNGDecoder : public Decoder {
|
|||
bool mFrameIsHidden;
|
||||
bool mDisablePremultipliedAlpha;
|
||||
bool mGotInfoCallback;
|
||||
bool mUsePipeTransform;
|
||||
|
||||
struct AnimFrameInfo {
|
||||
AnimFrameInfo();
|
||||
|
|
|
@ -228,8 +228,8 @@ nsresult nsWebPDecoder::CreateFrame(const nsIntRect& aFrameRect) {
|
|||
}
|
||||
|
||||
Maybe<SurfacePipe> pipe = SurfacePipeFactory::CreateSurfacePipe(
|
||||
this, Size(), OutputSize(), aFrameRect, mFormat, animParams, mTransform,
|
||||
pipeFlags);
|
||||
this, Size(), OutputSize(), aFrameRect, mFormat, animParams,
|
||||
/*aTransform*/ nullptr, pipeFlags);
|
||||
if (!pipe) {
|
||||
MOZ_LOG(sWebPLog, LogLevel::Error,
|
||||
("[this=%p] nsWebPDecoder::CreateFrame -- no pipe\n", this));
|
||||
|
@ -281,7 +281,7 @@ void nsWebPDecoder::ApplyColorProfile(const char* aProfile, size_t aLength) {
|
|||
("[this=%p] nsWebPDecoder::ApplyColorProfile -- not tagged, use "
|
||||
"sRGB transform\n",
|
||||
this));
|
||||
mTransform = gfxPlatform::GetCMSBGRATransform();
|
||||
mTransform = gfxPlatform::GetCMSRGBATransform();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -311,9 +311,9 @@ void nsWebPDecoder::ApplyColorProfile(const char* aProfile, size_t aLength) {
|
|||
}
|
||||
|
||||
// Create the color management transform.
|
||||
mTransform = qcms_transform_create(mInProfile, QCMS_DATA_BGRA_8,
|
||||
mTransform = qcms_transform_create(mInProfile, QCMS_DATA_RGBA_8,
|
||||
gfxPlatform::GetCMSOutputProfile(),
|
||||
QCMS_DATA_BGRA_8, (qcms_intent)intent);
|
||||
QCMS_DATA_RGBA_8, (qcms_intent)intent);
|
||||
MOZ_LOG(sWebPLog, LogLevel::Debug,
|
||||
("[this=%p] nsWebPDecoder::ApplyColorProfile -- use tagged "
|
||||
"transform\n",
|
||||
|
@ -463,6 +463,9 @@ LexerResult nsWebPDecoder::ReadSingle(const uint8_t* aData, size_t aLength,
|
|||
|
||||
for (int row = mLastRow; row < lastRow; row++) {
|
||||
uint8_t* src = rowStart + row * stride;
|
||||
if (mTransform) {
|
||||
qcms_transform_data(mTransform, src, src, width);
|
||||
}
|
||||
|
||||
WriteState result;
|
||||
if (mFormat == SurfaceFormat::B8G8R8A8) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче