Bug 1965813 - Add the possibility to decode cmyk jpeg images coming from pdf files r=aosmond,necko-reviewers,valentin

Differential Revision: https://phabricator.services.mozilla.com/D248887
This commit is contained in:
Calixte Denizet
2025-05-13 14:40:32 +00:00
committed by cdenizet@mozilla.com
parent 932b430977
commit 4d77a2923c
5 changed files with 27 additions and 11 deletions

View File

@@ -5,6 +5,7 @@
#include "DecoderFactory.h"
#include "ImageUtils.h"
#include "nsMimeTypes.h"
#include "mozilla/RefPtr.h"
@@ -57,6 +58,8 @@ DecoderType DecoderFactory::GetDecoderType(const char* aMimeType) {
type = DecoderType::JPEG;
} else if (!strcmp(aMimeType, IMAGE_JPG)) {
type = DecoderType::JPEG;
} else if (!strcmp(aMimeType, IMAGE_JPEG_PDF)) {
type = DecoderType::JPEG_PDF;
// BMP
} else if (!strcmp(aMimeType, IMAGE_BMP)) {
@@ -131,10 +134,12 @@ already_AddRefed<Decoder> DecoderFactory::GetDecoder(DecoderType aType,
decoder = new nsGIFDecoder2(aImage);
break;
case DecoderType::JPEG:
case DecoderType::JPEG_PDF:
// If we have all the data we don't want to waste cpu time doing
// a progressive decode.
decoder = new nsJPEGDecoder(
aImage, aIsRedecode ? Decoder::SEQUENTIAL : Decoder::PROGRESSIVE);
aImage, aIsRedecode ? Decoder::SEQUENTIAL : Decoder::PROGRESSIVE,
aType == DecoderType::JPEG_PDF);
break;
case DecoderType::BMP:
decoder = new nsBMPDecoder(aImage);

View File

@@ -37,6 +37,7 @@ enum class DecoderType {
PNG,
GIF,
JPEG,
JPEG_PDF,
BMP,
BMP_CLIPBOARD,
ICO,

View File

@@ -36,7 +36,7 @@ extern "C" {
#endif
static void cmyk_convert_bgra(uint32_t* aInput, uint32_t* aOutput,
int32_t aWidth);
int32_t aWidth, bool aIsInverted);
using mozilla::gfx::SurfaceFormat;
@@ -72,7 +72,7 @@ METHODDEF(void) progress_monitor(j_common_ptr info);
#define MAX_JPEG_MARKER_LENGTH (((uint32_t)1 << 16) - 1)
nsJPEGDecoder::nsJPEGDecoder(RasterImage* aImage,
Decoder::DecodeStyle aDecodeStyle)
Decoder::DecodeStyle aDecodeStyle, bool aIsPDF)
: Decoder(aImage),
mLexer(Transition::ToUnbuffered(State::FINISHED_JPEG_DATA,
State::JPEG_DATA, SIZE_MAX),
@@ -80,7 +80,8 @@ nsJPEGDecoder::nsJPEGDecoder(RasterImage* aImage,
mProfile(nullptr),
mProfileLength(0),
mCMSLine(nullptr),
mDecodeStyle(aDecodeStyle) {
mDecodeStyle(aDecodeStyle),
mIsPDF(aIsPDF) {
this->mErr.pub.error_exit = nullptr;
this->mErr.pub.emit_message = nullptr;
this->mErr.pub.output_message = nullptr;
@@ -692,7 +693,7 @@ WriteState nsJPEGDecoder::OutputScanlines() {
case JCS_CMYK:
// Convert from CMYK to BGRA
MOZ_ASSERT(mCMSLine);
cmyk_convert_bgra(mCMSLine, aPixelBlock, aBlockSize);
cmyk_convert_bgra(mCMSLine, aPixelBlock, aBlockSize, mIsPDF);
break;
}
@@ -961,7 +962,7 @@ term_source(j_decompress_ptr jd) {
/// @param aOutput Points to row buffer to write BGRA to.
/// @param aWidth Number of pixels in the row.
static void cmyk_convert_bgra(uint32_t* aInput, uint32_t* aOutput,
int32_t aWidth) {
int32_t aWidth, bool aIsInverted) {
uint8_t* input = reinterpret_cast<uint8_t*>(aInput);
for (int32_t i = 0; i < aWidth; ++i) {
@@ -984,10 +985,16 @@ static void cmyk_convert_bgra(uint32_t* aInput, uint32_t* aOutput,
// B = 1 - Y => 1 - (1 - iY*iK) => iY*iK
// Convert from Inverted CMYK (0..255) to RGB (0..255)
const uint32_t iC = input[0];
const uint32_t iM = input[1];
const uint32_t iY = input[2];
const uint32_t iK = input[3];
uint32_t iC = input[0];
uint32_t iM = input[1];
uint32_t iY = input[2];
uint32_t iK = input[3];
if (MOZ_UNLIKELY(aIsInverted)) {
iC = 255 - iC;
iM = 255 - iM;
iY = 255 - iY;
iK = 255 - iK;
}
const uint8_t r = iC * iK / 255;
const uint8_t g = iM * iK / 255;

View File

@@ -69,7 +69,8 @@ class nsJPEGDecoder : public Decoder {
friend class DecoderFactory;
// Decoders should only be instantiated via DecoderFactory.
nsJPEGDecoder(RasterImage* aImage, Decoder::DecodeStyle aDecodeStyle);
nsJPEGDecoder(RasterImage* aImage, Decoder::DecodeStyle aDecodeStyle,
bool aIsPDF = false);
enum class State { JPEG_DATA, FINISHED_JPEG_DATA };
@@ -104,6 +105,7 @@ class nsJPEGDecoder : public Decoder {
bool mReading;
const Decoder::DecodeStyle mDecodeStyle;
bool mIsPDF;
SurfacePipe mPipe;
};

View File

@@ -141,6 +141,7 @@
#define IMAGE_JPEG "image/jpeg"
#define IMAGE_JPG "image/jpg"
#define IMAGE_PJPEG "image/pjpeg"
#define IMAGE_JPEG_PDF "image/x-jpeg-pdf"
#define IMAGE_PNG "image/png"
#define IMAGE_APNG "image/apng"
#define IMAGE_X_PNG "image/x-png"