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:
committed by
cdenizet@mozilla.com
parent
932b430977
commit
4d77a2923c
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "DecoderFactory.h"
|
#include "DecoderFactory.h"
|
||||||
|
|
||||||
|
#include "ImageUtils.h"
|
||||||
#include "nsMimeTypes.h"
|
#include "nsMimeTypes.h"
|
||||||
#include "mozilla/RefPtr.h"
|
#include "mozilla/RefPtr.h"
|
||||||
|
|
||||||
@@ -57,6 +58,8 @@ DecoderType DecoderFactory::GetDecoderType(const char* aMimeType) {
|
|||||||
type = DecoderType::JPEG;
|
type = DecoderType::JPEG;
|
||||||
} else if (!strcmp(aMimeType, IMAGE_JPG)) {
|
} else if (!strcmp(aMimeType, IMAGE_JPG)) {
|
||||||
type = DecoderType::JPEG;
|
type = DecoderType::JPEG;
|
||||||
|
} else if (!strcmp(aMimeType, IMAGE_JPEG_PDF)) {
|
||||||
|
type = DecoderType::JPEG_PDF;
|
||||||
|
|
||||||
// BMP
|
// BMP
|
||||||
} else if (!strcmp(aMimeType, IMAGE_BMP)) {
|
} else if (!strcmp(aMimeType, IMAGE_BMP)) {
|
||||||
@@ -131,10 +134,12 @@ already_AddRefed<Decoder> DecoderFactory::GetDecoder(DecoderType aType,
|
|||||||
decoder = new nsGIFDecoder2(aImage);
|
decoder = new nsGIFDecoder2(aImage);
|
||||||
break;
|
break;
|
||||||
case DecoderType::JPEG:
|
case DecoderType::JPEG:
|
||||||
|
case DecoderType::JPEG_PDF:
|
||||||
// If we have all the data we don't want to waste cpu time doing
|
// If we have all the data we don't want to waste cpu time doing
|
||||||
// a progressive decode.
|
// a progressive decode.
|
||||||
decoder = new nsJPEGDecoder(
|
decoder = new nsJPEGDecoder(
|
||||||
aImage, aIsRedecode ? Decoder::SEQUENTIAL : Decoder::PROGRESSIVE);
|
aImage, aIsRedecode ? Decoder::SEQUENTIAL : Decoder::PROGRESSIVE,
|
||||||
|
aType == DecoderType::JPEG_PDF);
|
||||||
break;
|
break;
|
||||||
case DecoderType::BMP:
|
case DecoderType::BMP:
|
||||||
decoder = new nsBMPDecoder(aImage);
|
decoder = new nsBMPDecoder(aImage);
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ enum class DecoderType {
|
|||||||
PNG,
|
PNG,
|
||||||
GIF,
|
GIF,
|
||||||
JPEG,
|
JPEG,
|
||||||
|
JPEG_PDF,
|
||||||
BMP,
|
BMP,
|
||||||
BMP_CLIPBOARD,
|
BMP_CLIPBOARD,
|
||||||
ICO,
|
ICO,
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void cmyk_convert_bgra(uint32_t* aInput, uint32_t* aOutput,
|
static void cmyk_convert_bgra(uint32_t* aInput, uint32_t* aOutput,
|
||||||
int32_t aWidth);
|
int32_t aWidth, bool aIsInverted);
|
||||||
|
|
||||||
using mozilla::gfx::SurfaceFormat;
|
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)
|
#define MAX_JPEG_MARKER_LENGTH (((uint32_t)1 << 16) - 1)
|
||||||
|
|
||||||
nsJPEGDecoder::nsJPEGDecoder(RasterImage* aImage,
|
nsJPEGDecoder::nsJPEGDecoder(RasterImage* aImage,
|
||||||
Decoder::DecodeStyle aDecodeStyle)
|
Decoder::DecodeStyle aDecodeStyle, bool aIsPDF)
|
||||||
: Decoder(aImage),
|
: Decoder(aImage),
|
||||||
mLexer(Transition::ToUnbuffered(State::FINISHED_JPEG_DATA,
|
mLexer(Transition::ToUnbuffered(State::FINISHED_JPEG_DATA,
|
||||||
State::JPEG_DATA, SIZE_MAX),
|
State::JPEG_DATA, SIZE_MAX),
|
||||||
@@ -80,7 +80,8 @@ nsJPEGDecoder::nsJPEGDecoder(RasterImage* aImage,
|
|||||||
mProfile(nullptr),
|
mProfile(nullptr),
|
||||||
mProfileLength(0),
|
mProfileLength(0),
|
||||||
mCMSLine(nullptr),
|
mCMSLine(nullptr),
|
||||||
mDecodeStyle(aDecodeStyle) {
|
mDecodeStyle(aDecodeStyle),
|
||||||
|
mIsPDF(aIsPDF) {
|
||||||
this->mErr.pub.error_exit = nullptr;
|
this->mErr.pub.error_exit = nullptr;
|
||||||
this->mErr.pub.emit_message = nullptr;
|
this->mErr.pub.emit_message = nullptr;
|
||||||
this->mErr.pub.output_message = nullptr;
|
this->mErr.pub.output_message = nullptr;
|
||||||
@@ -692,7 +693,7 @@ WriteState nsJPEGDecoder::OutputScanlines() {
|
|||||||
case JCS_CMYK:
|
case JCS_CMYK:
|
||||||
// Convert from CMYK to BGRA
|
// Convert from CMYK to BGRA
|
||||||
MOZ_ASSERT(mCMSLine);
|
MOZ_ASSERT(mCMSLine);
|
||||||
cmyk_convert_bgra(mCMSLine, aPixelBlock, aBlockSize);
|
cmyk_convert_bgra(mCMSLine, aPixelBlock, aBlockSize, mIsPDF);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -961,7 +962,7 @@ term_source(j_decompress_ptr jd) {
|
|||||||
/// @param aOutput Points to row buffer to write BGRA to.
|
/// @param aOutput Points to row buffer to write BGRA to.
|
||||||
/// @param aWidth Number of pixels in the row.
|
/// @param aWidth Number of pixels in the row.
|
||||||
static void cmyk_convert_bgra(uint32_t* aInput, uint32_t* aOutput,
|
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);
|
uint8_t* input = reinterpret_cast<uint8_t*>(aInput);
|
||||||
|
|
||||||
for (int32_t i = 0; i < aWidth; ++i) {
|
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
|
// B = 1 - Y => 1 - (1 - iY*iK) => iY*iK
|
||||||
|
|
||||||
// Convert from Inverted CMYK (0..255) to RGB (0..255)
|
// Convert from Inverted CMYK (0..255) to RGB (0..255)
|
||||||
const uint32_t iC = input[0];
|
uint32_t iC = input[0];
|
||||||
const uint32_t iM = input[1];
|
uint32_t iM = input[1];
|
||||||
const uint32_t iY = input[2];
|
uint32_t iY = input[2];
|
||||||
const uint32_t iK = input[3];
|
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 r = iC * iK / 255;
|
||||||
const uint8_t g = iM * iK / 255;
|
const uint8_t g = iM * iK / 255;
|
||||||
|
|||||||
@@ -69,7 +69,8 @@ class nsJPEGDecoder : public Decoder {
|
|||||||
friend class DecoderFactory;
|
friend class DecoderFactory;
|
||||||
|
|
||||||
// Decoders should only be instantiated via 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 };
|
enum class State { JPEG_DATA, FINISHED_JPEG_DATA };
|
||||||
|
|
||||||
@@ -104,6 +105,7 @@ class nsJPEGDecoder : public Decoder {
|
|||||||
bool mReading;
|
bool mReading;
|
||||||
|
|
||||||
const Decoder::DecodeStyle mDecodeStyle;
|
const Decoder::DecodeStyle mDecodeStyle;
|
||||||
|
bool mIsPDF;
|
||||||
|
|
||||||
SurfacePipe mPipe;
|
SurfacePipe mPipe;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -141,6 +141,7 @@
|
|||||||
#define IMAGE_JPEG "image/jpeg"
|
#define IMAGE_JPEG "image/jpeg"
|
||||||
#define IMAGE_JPG "image/jpg"
|
#define IMAGE_JPG "image/jpg"
|
||||||
#define IMAGE_PJPEG "image/pjpeg"
|
#define IMAGE_PJPEG "image/pjpeg"
|
||||||
|
#define IMAGE_JPEG_PDF "image/x-jpeg-pdf"
|
||||||
#define IMAGE_PNG "image/png"
|
#define IMAGE_PNG "image/png"
|
||||||
#define IMAGE_APNG "image/apng"
|
#define IMAGE_APNG "image/apng"
|
||||||
#define IMAGE_X_PNG "image/x-png"
|
#define IMAGE_X_PNG "image/x-png"
|
||||||
|
|||||||
Reference in New Issue
Block a user