summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBo Xu <bo_xu@foxitsoftware.com>2014-08-25 13:45:17 -0700
committerBo Xu <bo_xu@foxitsoftware.com>2014-08-25 13:45:17 -0700
commit1dfbe601cfd9e1b5edb14d18d6a76c7e6d44d45f (patch)
treeff37d23fe15138daa474b4d55d0297a38e2b806d
parent187483a29f08416583bacd772eb77172d8ad06f3 (diff)
downloadpdfium-1dfbe601cfd9e1b5edb14d18d6a76c7e6d44d45f.tar.xz
Use number of components from ICC profile and alternate color space
BUG=406806 R=tsepez@chromium.org Review URL: https://codereview.chromium.org/503883002
-rw-r--r--core/include/fpdfapi/fpdf_parser.h2
-rw-r--r--core/include/fxcodec/fx_codec.h6
-rw-r--r--core/src/fpdfapi/fpdf_page/fpdf_page_colors.cpp91
-rw-r--r--core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp8
-rw-r--r--core/src/fpdfapi/fpdf_page/pageint.h6
-rw-r--r--core/src/fxcodec/codec/codec_int.h6
-rw-r--r--core/src/fxcodec/codec/fx_codec_icc.cpp53
7 files changed, 111 insertions, 61 deletions
diff --git a/core/include/fpdfapi/fpdf_parser.h b/core/include/fpdfapi/fpdf_parser.h
index 10072027b3..da22dc72ca 100644
--- a/core/include/fpdfapi/fpdf_parser.h
+++ b/core/include/fpdfapi/fpdf_parser.h
@@ -134,7 +134,7 @@ public:
CPDF_StreamAcc* LoadFontFile(CPDF_Stream* pStream);
- CPDF_IccProfile* LoadIccProfile(CPDF_Stream* pStream, int nComponents);
+ CPDF_IccProfile* LoadIccProfile(CPDF_Stream* pStream);
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
diff --git a/core/include/fxcodec/fx_codec.h b/core/include/fxcodec/fx_codec.h
index ac3f71e7bb..da8b309dd6 100644
--- a/core/include/fxcodec/fx_codec.h
+++ b/core/include/fxcodec/fx_codec.h
@@ -267,11 +267,11 @@ public:
) = 0;
- virtual FX_LPVOID CreateTransform_sRGB(FX_LPCBYTE pProfileData, unsigned int dwProfileSize, int nComponents, int intent = 0,
+ virtual FX_LPVOID CreateTransform_sRGB(FX_LPCBYTE pProfileData, FX_DWORD dwProfileSize, FX_INT32& nComponents, FX_INT32 intent = 0,
FX_DWORD dwSrcFormat = Icc_FORMAT_DEFAULT) = 0;
- virtual FX_LPVOID CreateTransform_CMYK(FX_LPCBYTE pSrcProfileData, unsigned int dwSrcProfileSize, int nSrcComponents,
- FX_LPCBYTE pDstProfileData, unsigned int dwDstProfileSize, int intent = 0,
+ virtual FX_LPVOID CreateTransform_CMYK(FX_LPCBYTE pSrcProfileData, FX_DWORD dwSrcProfileSize, FX_INT32& nSrcComponents,
+ FX_LPCBYTE pDstProfileData, FX_DWORD dwDstProfileSize, FX_INT32 intent = 0,
FX_DWORD dwSrcFormat = Icc_FORMAT_DEFAULT,
FX_DWORD dwDstFormat = Icc_FORMAT_DEFAULT
) = 0;
diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_colors.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_colors.cpp
index f1640ad14a..d99e643047 100644
--- a/core/src/fpdfapi/fpdf_page/fpdf_page_colors.cpp
+++ b/core/src/fpdfapi/fpdf_page/fpdf_page_colors.cpp
@@ -517,12 +517,17 @@ void CPDF_LabCS::TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int
pSrcBuf += 3;
}
}
-CPDF_IccProfile::CPDF_IccProfile(FX_LPCBYTE pData, FX_DWORD dwSize, int nComponents)
+CPDF_IccProfile::CPDF_IccProfile(FX_LPCBYTE pData, FX_DWORD dwSize):
+ m_bsRGB(FALSE),
+ m_pTransform(NULL),
+ m_nSrcComponents(0)
{
- m_bsRGB = nComponents == 3 && dwSize == 3144 && FXSYS_memcmp32(pData + 0x190, "sRGB IEC61966-2.1", 17) == 0;
- m_pTransform = NULL;
- if (!m_bsRGB && CPDF_ModuleMgr::Get()->GetIccModule()) {
- m_pTransform = CPDF_ModuleMgr::Get()->GetIccModule()->CreateTransform_sRGB(pData, dwSize, nComponents);
+ if (dwSize == 3144 && FXSYS_memcmp32(pData + 0x190, "sRGB IEC61966-2.1", 17) == 0) {
+ m_bsRGB = TRUE;
+ m_nSrcComponents = 3;
+ }
+ else if (CPDF_ModuleMgr::Get()->GetIccModule()) {
+ m_pTransform = CPDF_ModuleMgr::Get()->GetIccModule()->CreateTransform_sRGB(pData, dwSize, m_nSrcComponents);
}
}
CPDF_IccProfile::~CPDF_IccProfile()
@@ -583,49 +588,67 @@ FX_BOOL CPDF_ICCBasedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
if (pStream == NULL) {
return FALSE;
}
- CPDF_Dictionary* pDict = pStream->GetDict();
- m_nComponents = pDict ? pDict->GetInteger(FX_BSTRC("N")) : 0;
- if (m_nComponents != 1 && m_nComponents != 3 && m_nComponents != 4) {
- return FALSE;
- }
- CPDF_Array* pRanges = pDict->GetArray(FX_BSTRC("Range"));
- m_pRanges = FX_Alloc(FX_FLOAT, m_nComponents * 2);
- for (int i = 0; i < m_nComponents * 2; i ++) {
- if (pRanges) {
- m_pRanges[i] = pRanges->GetNumber(i);
- } else if (i % 2) {
- m_pRanges[i] = 1.0f;
- } else {
- m_pRanges[i] = 0;
- }
- }
- m_pProfile = pDoc->LoadIccProfile(pStream, m_nComponents);
+ m_pProfile = pDoc->LoadIccProfile(pStream);
if (!m_pProfile) {
return FALSE;
}
- if (m_pProfile->m_pTransform == NULL) {
+ m_nComponents = m_pProfile->GetComponents(); //Try using the nComponents from ICC profile
+ CPDF_Dictionary* pDict = pStream->GetDict();
+ if (m_pProfile->m_pTransform == NULL) { // No valid ICC profile or using sRGB
CPDF_Object* pAlterCSObj = pDict ? pDict->GetElementValue(FX_BSTRC("Alternate")) : NULL;
if (pAlterCSObj) {
- CPDF_ColorSpace* alter_cs = CPDF_ColorSpace::Load(pDoc, pAlterCSObj);
- if (alter_cs) {
- if (alter_cs->CountComponents() > m_nComponents) {
- alter_cs->ReleaseCS();
- } else {
- m_pAlterCS = alter_cs;
- m_bOwn = TRUE;
+ CPDF_ColorSpace* pAlterCS = CPDF_ColorSpace::Load(pDoc, pAlterCSObj);
+ if (pAlterCS) {
+ if (m_nComponents == 0) { // NO valid ICC profile
+ if (pAlterCS->CountComponents() > 0) { // Use Alternative colorspace
+ m_nComponents = pAlterCS->CountComponents();
+ m_pAlterCS = pAlterCS;
+ m_bOwn = TRUE;
+ }
+ else { // No valid alternative colorspace
+ pAlterCS->ReleaseCS();
+ FX_INT32 nDictComponents = pDict ? pDict->GetInteger(FX_BSTRC("N")) : 0;
+ if (nDictComponents != 1 && nDictComponents != 3 && nDictComponents != 4) {
+ return FALSE;
+ }
+ m_nComponents = nDictComponents;
+ }
+
+ }
+ else { // Using sRGB
+ if (pAlterCS->CountComponents() != m_nComponents) {
+ pAlterCS->ReleaseCS();
+ }
+ else {
+ m_pAlterCS = pAlterCS;
+ m_bOwn = TRUE;
+ }
}
}
}
if (!m_pAlterCS) {
- if (m_nComponents == 3) {
+ if (m_nComponents == 1) {
+ m_pAlterCS = GetStockCS(PDFCS_DEVICEGRAY);
+ }
+ else if (m_nComponents == 3) {
m_pAlterCS = GetStockCS(PDFCS_DEVICERGB);
- } else if (m_nComponents == 4) {
+ }
+ else if (m_nComponents == 4) {
m_pAlterCS = GetStockCS(PDFCS_DEVICECMYK);
- } else {
- m_pAlterCS = GetStockCS(PDFCS_DEVICEGRAY);
}
}
}
+ CPDF_Array* pRanges = pDict->GetArray(FX_BSTRC("Range"));
+ m_pRanges = FX_Alloc(FX_FLOAT, m_nComponents * 2);
+ for (int i = 0; i < m_nComponents * 2; i ++) {
+ if (pRanges) {
+ m_pRanges[i] = pRanges->GetNumber(i);
+ } else if (i % 2) {
+ m_pRanges[i] = 1.0f;
+ } else {
+ m_pRanges[i] = 0;
+ }
+ }
return TRUE;
}
FX_BOOL CPDF_ICCBasedCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const
diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp
index 0b52800939..16f0a9cfad 100644
--- a/core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp
+++ b/core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp
@@ -107,9 +107,9 @@ CPDF_Pattern* CPDF_Document::LoadPattern(CPDF_Object* pPatternObj, FX_BOOL bShad
{
return GetValidatePageData()->GetPattern(pPatternObj, bShading, matrix);
}
-CPDF_IccProfile* CPDF_Document::LoadIccProfile(CPDF_Stream* pStream, int nComponents)
+CPDF_IccProfile* CPDF_Document::LoadIccProfile(CPDF_Stream* pStream)
{
- return GetValidatePageData()->GetIccProfile(pStream, nComponents);
+ return GetValidatePageData()->GetIccProfile(pStream);
}
CPDF_Image* CPDF_Document::LoadImageF(CPDF_Object* pObj)
{
@@ -543,7 +543,7 @@ void CPDF_DocPageData::ReleaseImage(CPDF_Object* pImageStream)
}
PDF_DocPageData_Release<FX_DWORD, CPDF_Image*>(m_ImageMap, pImageStream->GetObjNum(), NULL);
}
-CPDF_IccProfile* CPDF_DocPageData::GetIccProfile(CPDF_Stream* pIccProfileStream, FX_INT32 nComponents)
+CPDF_IccProfile* CPDF_DocPageData::GetIccProfile(CPDF_Stream* pIccProfileStream)
{
if (!pIccProfileStream) {
return NULL;
@@ -563,7 +563,7 @@ CPDF_IccProfile* CPDF_DocPageData::GetIccProfile(CPDF_Stream* pIccProfileStream,
ipData->m_nCount++;
return ipData->m_Obj;
}
- CPDF_IccProfile* pProfile = FX_NEW CPDF_IccProfile(stream.GetData(), stream.GetSize(), nComponents);
+ CPDF_IccProfile* pProfile = FX_NEW CPDF_IccProfile(stream.GetData(), stream.GetSize());
if (!pProfile) {
return NULL;
}
diff --git a/core/src/fpdfapi/fpdf_page/pageint.h b/core/src/fpdfapi/fpdf_page/pageint.h
index 625e5df737..f79b8d38f3 100644
--- a/core/src/fpdfapi/fpdf_page/pageint.h
+++ b/core/src/fpdfapi/fpdf_page/pageint.h
@@ -426,7 +426,7 @@ public:
void ReleasePattern(CPDF_Object* pPatternObj);
CPDF_Image* GetImage(CPDF_Object* pImageStream);
void ReleaseImage(CPDF_Object* pImageStream);
- CPDF_IccProfile* GetIccProfile(CPDF_Stream* pIccProfileStream, FX_INT32 nComponents);
+ CPDF_IccProfile* GetIccProfile(CPDF_Stream* pIccProfileStream);
void ReleaseIccProfile(CPDF_Stream* pIccProfileStream, CPDF_IccProfile* pIccProfile);
CPDF_StreamAcc* GetFontFileStreamAcc(CPDF_Stream* pFontStream);
void ReleaseFontFileStreamAcc(CPDF_Stream* pFontStream, FX_BOOL bForce = FALSE);
@@ -468,9 +468,11 @@ protected:
class CPDF_IccProfile : public CFX_Object
{
public:
- CPDF_IccProfile(FX_LPCBYTE pData, FX_DWORD dwSize, int nComponents);
+ CPDF_IccProfile(FX_LPCBYTE pData, FX_DWORD dwSize);
~CPDF_IccProfile();
+ FX_INT32 GetComponents() const { return m_nSrcComponents; }
FX_BOOL m_bsRGB;
+ FX_INT32 m_nSrcComponents;
FX_LPVOID m_pTransform;
};
class CPDF_DeviceCS : public CPDF_ColorSpace
diff --git a/core/src/fxcodec/codec/codec_int.h b/core/src/fxcodec/codec/codec_int.h
index 47f2c8e1fe..78672e62ee 100644
--- a/core/src/fxcodec/codec/codec_int.h
+++ b/core/src/fxcodec/codec/codec_int.h
@@ -162,10 +162,10 @@ public:
FX_DWORD dwPrfIntent = Icc_INTENT_ABSOLUTE_COLORIMETRIC,
FX_DWORD dwPrfFlag = Icc_FLAGS_SOFTPROOFING
);
- virtual FX_LPVOID CreateTransform_sRGB(FX_LPCBYTE pProfileData, unsigned int dwProfileSize, int nComponents, int intent = 0,
+ virtual FX_LPVOID CreateTransform_sRGB(FX_LPCBYTE pProfileData, FX_DWORD dwProfileSize, FX_INT32& nComponents, FX_INT32 intent = 0,
FX_DWORD dwSrcFormat = Icc_FORMAT_DEFAULT);
- virtual FX_LPVOID CreateTransform_CMYK(FX_LPCBYTE pSrcProfileData, unsigned int dwSrcProfileSize, int nSrcComponents,
- FX_LPCBYTE pDstProfileData, unsigned int dwDstProfileSize, int intent = 0,
+ virtual FX_LPVOID CreateTransform_CMYK(FX_LPCBYTE pSrcProfileData, FX_DWORD dwSrcProfileSize, FX_INT32& nSrcComponents,
+ FX_LPCBYTE pDstProfileData, FX_DWORD dwDstProfileSize, FX_INT32 intent = 0,
FX_DWORD dwSrcFormat = Icc_FORMAT_DEFAULT,
FX_DWORD dwDstFormat = Icc_FORMAT_DEFAULT
);
diff --git a/core/src/fxcodec/codec/fx_codec_icc.cpp b/core/src/fxcodec/codec/fx_codec_icc.cpp
index b10d9c4868..6bdc225adf 100644
--- a/core/src/fxcodec/codec/fx_codec_icc.cpp
+++ b/core/src/fxcodec/codec/fx_codec_icc.cpp
@@ -7,6 +7,12 @@
#include "../../../include/fxcodec/fx_codec.h"
#include "codec_int.h"
#include "../lcms2/include/fx_lcms2.h"
+const FX_DWORD N_COMPONENT_LAB = 3;
+const FX_DWORD N_COMPONENT_GRAY = 1;
+const FX_DWORD N_COMPONENT_RGB = 3;
+const FX_DWORD N_COMPONENT_CMYK = 4;
+const FX_DWORD N_COMPONENT_DEFAULT = 3;
+
FX_BOOL MD5ComputeID( FX_LPCVOID buf, FX_DWORD dwSize, FX_BYTE ID[16] )
{
return cmsMD5computeIDExt(buf, dwSize, ID);
@@ -59,14 +65,37 @@ FX_BOOL CheckComponents(cmsColorSpaceSignature cs, int nComponents, FX_BOOL bDst
}
return TRUE;
}
-void* IccLib_CreateTransform(const unsigned char* pSrcProfileData, unsigned int dwSrcProfileSize, int nSrcComponents,
- const unsigned char* pDstProfileData, unsigned int dwDstProfileSize, int nDstComponents,
+FX_INT32 GetCSComponents(cmsColorSpaceSignature cs)
+{
+ FX_DWORD components;
+ switch (cs) {
+ case cmsSigLabData:
+ components = N_COMPONENT_LAB;
+ break;
+ case cmsSigGrayData:
+ components = N_COMPONENT_GRAY;
+ break;
+ case cmsSigRgbData:
+ components = N_COMPONENT_RGB;
+ break;
+ case cmsSigCmykData:
+ components = N_COMPONENT_CMYK;
+ break;
+ default:
+ components = N_COMPONENT_DEFAULT;
+ break;
+ }
+ return components;
+}
+void* IccLib_CreateTransform(const unsigned char* pSrcProfileData, FX_DWORD dwSrcProfileSize, FX_INT32& nSrcComponents,
+ const unsigned char* pDstProfileData, FX_DWORD dwDstProfileSize, FX_INT32 nDstComponents,
int intent, FX_DWORD dwSrcFormat = Icc_FORMAT_DEFAULT, FX_DWORD dwDstFormat = Icc_FORMAT_DEFAULT)
{
cmsHPROFILE srcProfile = NULL;
cmsHPROFILE dstProfile = NULL;
cmsHTRANSFORM hTransform = NULL;
CLcmsCmm* pCmm = NULL;
+ nSrcComponents = 0;
srcProfile = cmsOpenProfileFromMem((void*)pSrcProfileData, dwSrcProfileSize);
if (srcProfile == NULL) {
return NULL;
@@ -83,11 +112,7 @@ void* IccLib_CreateTransform(const unsigned char* pSrcProfileData, unsigned int
int srcFormat;
FX_BOOL bLab = FALSE;
cmsColorSpaceSignature srcCS = cmsGetColorSpace(srcProfile);
- if (!CheckComponents(srcCS, nSrcComponents, FALSE)) {
- cmsCloseProfile(srcProfile);
- cmsCloseProfile(dstProfile);
- return NULL;
- }
+ nSrcComponents = GetCSComponents(srcCS);
if (srcCS == cmsSigLabData) {
srcFormat = COLORSPACE_SH(PT_Lab) | CHANNELS_SH(nSrcComponents) | BYTES_SH(0);
bLab = TRUE;
@@ -135,7 +160,7 @@ void* IccLib_CreateTransform(const unsigned char* pSrcProfileData, unsigned int
cmsCloseProfile(dstProfile);
return pCmm;
}
-void* IccLib_CreateTransform_sRGB(const unsigned char* pProfileData, unsigned int dwProfileSize, int nComponents, int intent, FX_DWORD dwSrcFormat)
+void* IccLib_CreateTransform_sRGB(const unsigned char* pProfileData, FX_DWORD dwProfileSize, FX_INT32& nComponents, FX_INT32 intent, FX_DWORD dwSrcFormat)
{
return IccLib_CreateTransform(pProfileData, dwProfileSize, nComponents, NULL, 0, 3, intent, dwSrcFormat);
}
@@ -192,7 +217,7 @@ void IccLib_Translate(void* pTransform, FX_DWORD nSrcComponents, FX_FLOAT* pSrcV
break;
}
}
-void IccLib_TranslateImage(void* pTransform, unsigned char* pDest, const unsigned char* pSrc, int pixels)
+void IccLib_TranslateImage(void* pTransform, unsigned char* pDest, const unsigned char* pSrc, FX_INT32 pixels)
{
cmsDoTransform(((CLcmsCmm*)pTransform)->m_hTransform, (void*)pSrc, pDest, pixels);
}
@@ -242,7 +267,7 @@ ICodec_IccModule::IccCS GetProfileCSFromHandle(FX_LPVOID pProfile)
return ICodec_IccModule::IccCS_Unknown;
}
}
-ICodec_IccModule::IccCS CCodec_IccModule::GetProfileCS(FX_LPCBYTE pProfileData, unsigned int dwProfileSize)
+ICodec_IccModule::IccCS CCodec_IccModule::GetProfileCS(FX_LPCBYTE pProfileData, FX_DWORD dwProfileSize)
{
ICodec_IccModule::IccCS cs;
cmsHPROFILE hProfile = cmsOpenProfileFromMem((void*)pProfileData, dwProfileSize);
@@ -517,12 +542,12 @@ CCodec_IccModule::~CCodec_IccModule()
}
}
}
-void* CCodec_IccModule::CreateTransform_sRGB(FX_LPCBYTE pProfileData, unsigned int dwProfileSize, int nComponents, int intent, FX_DWORD dwSrcFormat)
+void* CCodec_IccModule::CreateTransform_sRGB(FX_LPCBYTE pProfileData, FX_DWORD dwProfileSize, FX_INT32& nComponents, FX_INT32 intent, FX_DWORD dwSrcFormat)
{
return IccLib_CreateTransform_sRGB(pProfileData, dwProfileSize, nComponents, intent, dwSrcFormat);
}
-void* CCodec_IccModule::CreateTransform_CMYK(FX_LPCBYTE pSrcProfileData, unsigned int dwSrcProfileSize, int nSrcComponents,
- FX_LPCBYTE pDstProfileData, unsigned int dwDstProfileSize, int intent,
+void* CCodec_IccModule::CreateTransform_CMYK(FX_LPCBYTE pSrcProfileData, FX_DWORD dwSrcProfileSize, FX_INT32& nSrcComponents,
+ FX_LPCBYTE pDstProfileData, FX_DWORD dwDstProfileSize, FX_INT32 intent,
FX_DWORD dwSrcFormat , FX_DWORD dwDstFormat)
{
return IccLib_CreateTransform(pSrcProfileData, dwSrcProfileSize, nSrcComponents,
@@ -536,7 +561,7 @@ void CCodec_IccModule::Translate(void* pTransform, FX_FLOAT* pSrcValues, FX_FLOA
{
IccLib_Translate(pTransform, m_nComponents, pSrcValues, pDestValues);
}
-void CCodec_IccModule::TranslateScanline(void* pTransform, FX_LPBYTE pDest, FX_LPCBYTE pSrc, int pixels)
+void CCodec_IccModule::TranslateScanline(void* pTransform, FX_LPBYTE pDest, FX_LPCBYTE pSrc, FX_INT32 pixels)
{
IccLib_TranslateImage(pTransform, pDest, pSrc, pixels);
}