Fix a problem that JP2 image is not displayed because index color space is used
authorJUN FANG <jun_fang@foxitsoftware.com>
Mon, 16 Mar 2015 19:10:04 +0000 (12:10 -0700)
committerJUN FANG <jun_fang@foxitsoftware.com>
Mon, 16 Mar 2015 19:10:04 +0000 (12:10 -0700)
There are two issues in this bug.

One is that JP2 image is not displayed because it aborts loading Jpx bitmap when the number of components in color space is different with that one in JPX images. I found that the number of components in color space isn't updated after it's initialized. For index color space, the component shall inherit from its base color space.

The second issue is that displayed color is not correct after I fixed the first issue. The root cause is that sRGB is used in JPX image, it doesn't need to map from index to RGB again.

BUG=464215
R=tsepez@chromium.org

Review URL: https://codereview.chromium.org/1009513003

core/src/fpdfapi/fpdf_page/fpdf_page_colors.cpp
core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp

index 86db177..90895cd 100644 (file)
@@ -7,6 +7,7 @@
 #include "../../../include/fpdfapi/fpdf_page.h"
 #include "../../../include/fpdfapi/fpdf_module.h"
 #include "../../../include/fxcodec/fx_codec.h"
+#include "../../fxcrt/fx_safe_types.h"
 #include "pageint.h"
 #include <limits.h>
 void sRGB_to_AdobeCMYK(FX_FLOAT R, FX_FLOAT G, FX_FLOAT B, FX_FLOAT& c, FX_FLOAT& m, FX_FLOAT& y, FX_FLOAT& k)
@@ -801,6 +802,7 @@ FX_BOOL CPDF_IndexedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
     }
     m_pCountedBaseCS = pDocPageData->FindColorSpacePtr(m_pBaseCS->GetArray());
     m_nBaseComponents = m_pBaseCS->CountComponents();
+    m_nComponents = m_nBaseComponents;
     m_pCompMinMax = FX_Alloc(FX_FLOAT, m_nBaseComponents * 2);
     FX_FLOAT defvalue;
     for (int i = 0; i < m_nBaseComponents; i ++) {
@@ -823,22 +825,29 @@ FX_BOOL CPDF_IndexedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
 }
 FX_BOOL CPDF_IndexedCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const
 {
-    int index = (FX_INT32)(*pBuf);
-    if (index < 0 || index > m_MaxIndex) {
+    int index = static_cast<FX_INT32>(*pBuf);
+    if (index < 0 || index > m_MaxIndex || m_nBaseComponents < 1) {
         return FALSE;
     }
-    if (m_nBaseComponents) {
-        if (index == INT_MAX || (index + 1) > INT_MAX / m_nBaseComponents ||
-                (index + 1)*m_nBaseComponents > (int)m_Table.GetLength()) {
-            R = G = B = 0;
-            return FALSE;
-        }
+    FX_SAFE_INT32 colIndex = index;
+    colIndex *= m_nBaseComponents;
+    colIndex += m_nBaseComponents - 1; 
+    if (!colIndex.IsValid() || colIndex.ValueOrDie() >= m_Table.GetLength()) {
+        R = G = B = 0;
+        return FALSE;
     }
+
     CFX_FixedBufGrow<FX_FLOAT, 16> Comps(m_nBaseComponents);
     FX_FLOAT* comps = Comps;
-    FX_LPCBYTE pTable = m_Table;
-    for (int i = 0; i < m_nBaseComponents; i ++) {
-        comps[i] = m_pCompMinMax[i * 2] + m_pCompMinMax[i * 2 + 1] * pTable[index * m_nBaseComponents + i] / 255;
+    if (m_pBaseCS->sRGB()) {
+        for (int i = 0; i < m_nBaseComponents; i ++) {
+            comps[i] = pBuf[i] / 255;
+        }
+    } else {
+        FX_LPCBYTE pTable = m_Table;
+        for (int i = 0; i < m_nBaseComponents; i ++) {
+            comps[i] = m_pCompMinMax[i * 2] + m_pCompMinMax[i * 2 + 1] * pTable[index * m_nBaseComponents + i] / 255;
+        }
     }
     m_pBaseCS->GetRGB(comps, R, G, B);
     return TRUE;
index 79d7351..4ed17cd 100644 (file)
@@ -505,10 +505,14 @@ DIB_COMP_DATA* CPDF_DIBSource::GetDecodeAndMaskArray(FX_BOOL& bDefaultDecode, FX
     }
     int max_data = (1 << m_bpc) - 1;
     CPDF_Array* pDecode = m_pDict->GetArray(FX_BSTRC("Decode"));
+    FX_DWORD arrSize = pDecode ? pDecode->GetCount() : 0;
+    if (arrSize == 0) {
+        return NULL;
+    }
     if (pDecode) {
         for (FX_DWORD i = 0; i < m_nComponents; i ++) {
-            pCompData[i].m_DecodeMin = pDecode->GetNumber(i * 2);
-            FX_FLOAT max = pDecode->GetNumber(i * 2 + 1);
+            pCompData[i].m_DecodeMin = pDecode->GetNumber((i * 2) % arrSize);
+            FX_FLOAT max = pDecode->GetNumber((i * 2 + 1) % arrSize);
             pCompData[i].m_DecodeStep = (max - pCompData[i].m_DecodeMin) / max_data;
             FX_FLOAT def_value, def_min, def_max;
             m_pColorSpace->GetDefaultValue(i, def_value, def_min, def_max);