summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BUILD.gn1
-rw-r--r--core/fxcodec/jbig2/JBig2_Context.cpp14
-rw-r--r--core/fxcodec/jbig2/JBig2_GrdProc.cpp22
-rw-r--r--core/fxcodec/jbig2/JBig2_GrrdProc.cpp20
-rw-r--r--core/fxcodec/jbig2/JBig2_Image.cpp107
-rw-r--r--core/fxcodec/jbig2/JBig2_Image.h26
-rw-r--r--core/fxcodec/jbig2/JBig2_Image_unittest.cpp105
-rw-r--r--core/fxcodec/jbig2/JBig2_SddProc.cpp2
-rw-r--r--core/fxcodec/jbig2/JBig2_TrdProc.cpp16
9 files changed, 214 insertions, 99 deletions
diff --git a/BUILD.gn b/BUILD.gn
index 4b6e6581a8..60d656fb7d 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1550,6 +1550,7 @@ test("pdfium_unittests") {
"core/fpdfdoc/cpdf_filespec_unittest.cpp",
"core/fpdftext/fpdf_text_int_unittest.cpp",
"core/fxcodec/codec/fx_codec_jpx_unittest.cpp",
+ "core/fxcodec/jbig2/JBig2_Image_unittest.cpp",
"core/fxcrt/cfx_retain_ptr_unittest.cpp",
"core/fxcrt/fx_basic_bstring_unittest.cpp",
"core/fxcrt/fx_basic_gcc_unittest.cpp",
diff --git a/core/fxcodec/jbig2/JBig2_Context.cpp b/core/fxcodec/jbig2/JBig2_Context.cpp
index 256ce3910a..911eb0bf63 100644
--- a/core/fxcodec/jbig2/JBig2_Context.cpp
+++ b/core/fxcodec/jbig2/JBig2_Context.cpp
@@ -924,7 +924,7 @@ int32_t CJBig2_Context::parseTextRegion(CJBig2_Segment* pSegment) {
if (!m_bBufSpecified) {
JBig2PageInfo* pPageInfo = m_PageInfoList.back();
if ((pPageInfo->m_bIsStriped == 1) &&
- (ri.y + ri.height > m_pPage->m_nHeight)) {
+ (ri.y + ri.height > m_pPage->height())) {
m_pPage->expand(ri.y + ri.height, (pPageInfo->m_cFlags & 4) ? 1 : 0);
}
}
@@ -1015,8 +1015,8 @@ int32_t CJBig2_Context::parseHalftoneRegion(CJBig2_Segment* pSegment,
pHRD->HNUMPATS = pPatternDict->NUMPATS;
pHRD->HPATS = pPatternDict->HDPATS;
- pHRD->HPW = pPatternDict->HDPATS[0]->m_nWidth;
- pHRD->HPH = pPatternDict->HDPATS[0]->m_nHeight;
+ pHRD->HPW = pPatternDict->HDPATS[0]->width();
+ pHRD->HPH = pPatternDict->HDPATS[0]->height();
pSegment->m_nResultType = JBIG2_IMAGE_POINTER;
if (pHRD->HMMR == 0) {
const size_t size = GetHuffContextSize(pHRD->HTEMPLATE);
@@ -1042,7 +1042,7 @@ int32_t CJBig2_Context::parseHalftoneRegion(CJBig2_Segment* pSegment,
if (!m_bBufSpecified) {
JBig2PageInfo* pPageInfo = m_PageInfoList.back();
if (pPageInfo->m_bIsStriped == 1 &&
- ri.y + ri.height > m_pPage->m_nHeight) {
+ ri.y + ri.height > m_pPage->height()) {
m_pPage->expand(ri.y + ri.height, (pPageInfo->m_cFlags & 4) ? 1 : 0);
}
}
@@ -1108,7 +1108,7 @@ int32_t CJBig2_Context::parseGenericRegion(CJBig2_Segment* pSegment,
if (!m_bBufSpecified) {
JBig2PageInfo* pPageInfo = m_PageInfoList.back();
if ((pPageInfo->m_bIsStriped == 1) &&
- (m_ri.y + m_ri.height > m_pPage->m_nHeight)) {
+ (m_ri.y + m_ri.height > m_pPage->height())) {
m_pPage->expand(m_ri.y + m_ri.height,
(pPageInfo->m_cFlags & 4) ? 1 : 0);
}
@@ -1142,7 +1142,7 @@ int32_t CJBig2_Context::parseGenericRegion(CJBig2_Segment* pSegment,
if (!m_bBufSpecified) {
JBig2PageInfo* pPageInfo = m_PageInfoList.back();
if ((pPageInfo->m_bIsStriped == 1) &&
- (m_ri.y + m_ri.height > m_pPage->m_nHeight)) {
+ (m_ri.y + m_ri.height > m_pPage->height())) {
m_pPage->expand(m_ri.y + m_ri.height,
(pPageInfo->m_cFlags & 4) ? 1 : 0);
}
@@ -1215,7 +1215,7 @@ int32_t CJBig2_Context::parseGenericRefinementRegion(CJBig2_Segment* pSegment) {
if (!m_bBufSpecified) {
JBig2PageInfo* pPageInfo = m_PageInfoList.back();
if ((pPageInfo->m_bIsStriped == 1) &&
- (ri.y + ri.height > m_pPage->m_nHeight)) {
+ (ri.y + ri.height > m_pPage->height())) {
m_pPage->expand(ri.y + ri.height, (pPageInfo->m_cFlags & 4) ? 1 : 0);
}
}
diff --git a/core/fxcodec/jbig2/JBig2_GrdProc.cpp b/core/fxcodec/jbig2/JBig2_GrdProc.cpp
index 9527c1eaf8..b692909c01 100644
--- a/core/fxcodec/jbig2/JBig2_GrdProc.cpp
+++ b/core/fxcodec/jbig2/JBig2_GrdProc.cpp
@@ -71,7 +71,7 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template0_opt3(
FX_BOOL LTP = FALSE;
uint8_t* pLine = GBREG->m_pData;
- int32_t nStride = GBREG->m_nStride;
+ int32_t nStride = GBREG->stride();
int32_t nStride2 = nStride << 1;
int32_t nLineBytes = ((GBW + 7) >> 3) - 1;
int32_t nBitsLeft = GBW - (nLineBytes << 3);
@@ -197,7 +197,7 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template1_opt3(
FX_BOOL LTP = FALSE;
uint8_t* pLine = GBREG->m_pData;
- int32_t nStride = GBREG->m_nStride;
+ int32_t nStride = GBREG->stride();
int32_t nStride2 = nStride << 1;
int32_t nLineBytes = ((GBW + 7) >> 3) - 1;
int32_t nBitsLeft = GBW - (nLineBytes << 3);
@@ -320,7 +320,7 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template2_opt3(
FX_BOOL LTP = FALSE;
uint8_t* pLine = GBREG->m_pData;
- int32_t nStride = GBREG->m_nStride;
+ int32_t nStride = GBREG->stride();
int32_t nStride2 = nStride << 1;
int32_t nLineBytes = ((GBW + 7) >> 3) - 1;
int32_t nBitsLeft = GBW - (nLineBytes << 3);
@@ -441,7 +441,7 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template3_opt3(
FX_BOOL LTP = FALSE;
uint8_t* pLine = GBREG->m_pData;
- int32_t nStride = GBREG->m_nStride;
+ int32_t nStride = GBREG->stride();
int32_t nLineBytes = ((GBW + 7) >> 3) - 1;
int32_t nBitsLeft = GBW - (nLineBytes << 3);
for (uint32_t h = 0; h < GBH; h++) {
@@ -602,7 +602,7 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith(IFX_Pause* pPause) {
}
}
m_ReplaceRect.left = 0;
- m_ReplaceRect.right = pImage->m_nWidth;
+ m_ReplaceRect.right = pImage->width();
m_ReplaceRect.top = iline;
m_ReplaceRect.bottom = m_loopIndex;
if (m_ProssiveStatus == FXCODEC_STATUS_DECODE_FINISH) {
@@ -624,9 +624,9 @@ FXCODEC_STATUS CJBig2_GRDProc::Start_decode_MMR(CJBig2_Image** pImage,
}
bitpos = (int)pStream->getBitPos();
FaxG4Decode(pStream->getBuf(), pStream->getLength(), &bitpos,
- (*pImage)->m_pData, GBW, GBH, (*pImage)->m_nStride);
+ (*pImage)->m_pData, GBW, GBH, (*pImage)->stride());
pStream->setBitPos(bitpos);
- for (i = 0; (uint32_t)i < (*pImage)->m_nStride * GBH; i++) {
+ for (i = 0; (uint32_t)i < (*pImage)->stride() * GBH; i++) {
(*pImage)->m_pData[i] = ~(*pImage)->m_pData[i];
}
m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
@@ -653,7 +653,7 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template0_opt3(
if (!m_pLine) {
m_pLine = pImage->m_pData;
}
- int32_t nStride = pImage->m_nStride;
+ int32_t nStride = pImage->stride();
int32_t nStride2 = nStride << 1;
int32_t nLineBytes = ((GBW + 7) >> 3) - 1;
int32_t nBitsLeft = GBW - (nLineBytes << 3);
@@ -791,7 +791,7 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template1_opt3(
if (!m_pLine) {
m_pLine = pImage->m_pData;
}
- int32_t nStride = pImage->m_nStride;
+ int32_t nStride = pImage->stride();
int32_t nStride2 = nStride << 1;
int32_t nLineBytes = ((GBW + 7) >> 3) - 1;
int32_t nBitsLeft = GBW - (nLineBytes << 3);
@@ -924,7 +924,7 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template2_opt3(
if (!m_pLine) {
m_pLine = pImage->m_pData;
}
- int32_t nStride = pImage->m_nStride;
+ int32_t nStride = pImage->stride();
int32_t nStride2 = nStride << 1;
int32_t nLineBytes = ((GBW + 7) >> 3) - 1;
int32_t nBitsLeft = GBW - (nLineBytes << 3);
@@ -1057,7 +1057,7 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template3_opt3(
if (!m_pLine)
m_pLine = pImage->m_pData;
- int32_t nStride = pImage->m_nStride;
+ int32_t nStride = pImage->stride();
int32_t nLineBytes = ((GBW + 7) >> 3) - 1;
int32_t nBitsLeft = GBW - (nLineBytes << 3);
for (; m_loopIndex < GBH; m_loopIndex++) {
diff --git a/core/fxcodec/jbig2/JBig2_GrrdProc.cpp b/core/fxcodec/jbig2/JBig2_GrrdProc.cpp
index 25c9ea2d8a..672692da54 100644
--- a/core/fxcodec/jbig2/JBig2_GrrdProc.cpp
+++ b/core/fxcodec/jbig2/JBig2_GrrdProc.cpp
@@ -20,13 +20,13 @@ CJBig2_Image* CJBig2_GRRDProc::decode(CJBig2_ArithDecoder* pArithDecoder,
if (GRTEMPLATE == 0) {
if ((GRAT[0] == -1) && (GRAT[1] == -1) && (GRAT[2] == -1) &&
(GRAT[3] == -1) && (GRREFERENCEDX == 0) &&
- (GRW == (uint32_t)GRREFERENCE->m_nWidth)) {
+ (GRW == (uint32_t)GRREFERENCE->width())) {
return decode_Template0_opt(pArithDecoder, grContext);
}
return decode_Template0_unopt(pArithDecoder, grContext);
}
- if ((GRREFERENCEDX == 0) && (GRW == (uint32_t)GRREFERENCE->m_nWidth))
+ if ((GRREFERENCEDX == 0) && (GRW == (uint32_t)GRREFERENCE->width()))
return decode_Template1_opt(pArithDecoder, grContext);
return decode_Template1_unopt(pArithDecoder, grContext);
}
@@ -162,10 +162,10 @@ CJBig2_Image* CJBig2_GRRDProc::decode_Template0_opt(
FX_BOOL LTP = FALSE;
uint8_t* pLine = GRREG->m_pData;
uint8_t* pLineR = GRREFERENCE->m_pData;
- intptr_t nStride = GRREG->m_nStride;
- intptr_t nStrideR = GRREFERENCE->m_nStride;
- int32_t GRWR = GRREFERENCE->m_nWidth;
- int32_t GRHR = GRREFERENCE->m_nHeight;
+ intptr_t nStride = GRREG->stride();
+ intptr_t nStrideR = GRREFERENCE->stride();
+ int32_t GRWR = GRREFERENCE->width();
+ int32_t GRHR = GRREFERENCE->height();
if (GRREFERENCEDY < -GRHR + 1 || GRREFERENCEDY > GRHR - 1)
GRREFERENCEDY = 0;
intptr_t nOffset = -GRREFERENCEDY * nStrideR;
@@ -396,10 +396,10 @@ CJBig2_Image* CJBig2_GRRDProc::decode_Template1_opt(
FX_BOOL LTP = FALSE;
uint8_t* pLine = GRREG->m_pData;
uint8_t* pLineR = GRREFERENCE->m_pData;
- intptr_t nStride = GRREG->m_nStride;
- intptr_t nStrideR = GRREFERENCE->m_nStride;
- int32_t GRWR = GRREFERENCE->m_nWidth;
- int32_t GRHR = GRREFERENCE->m_nHeight;
+ intptr_t nStride = GRREG->stride();
+ intptr_t nStrideR = GRREFERENCE->stride();
+ int32_t GRWR = GRREFERENCE->width();
+ int32_t GRHR = GRREFERENCE->height();
if (GRREFERENCEDY < -GRHR + 1 || GRREFERENCEDY > GRHR - 1) {
GRREFERENCEDY = 0;
}
diff --git a/core/fxcodec/jbig2/JBig2_Image.cpp b/core/fxcodec/jbig2/JBig2_Image.cpp
index cf0ee3bbbc..b8cb21165b 100644
--- a/core/fxcodec/jbig2/JBig2_Image.cpp
+++ b/core/fxcodec/jbig2/JBig2_Image.cpp
@@ -10,46 +10,65 @@
#include "core/fxcrt/include/fx_coordinates.h"
#include "core/fxcrt/include/fx_safe_types.h"
-CJBig2_Image::CJBig2_Image(int32_t w, int32_t h) {
+namespace {
+
+const int kMaxImagePixels = INT_MAX - 31;
+const int kMaxImageBytes = kMaxImagePixels / 8;
+
+} // namespace
+
+CJBig2_Image::CJBig2_Image(int32_t w, int32_t h)
+ : m_pData(nullptr),
+ m_nWidth(0),
+ m_nHeight(0),
+ m_nStride(0),
+ m_bOwnsBuffer(true) {
+ if (w < 0 || h < 0 || w > kMaxImagePixels)
+ return;
+
+ int32_t stride_pixels = (w + 31) & ~31;
+ if (h > kMaxImagePixels / stride_pixels)
+ return;
+
m_nWidth = w;
m_nHeight = h;
- if (m_nWidth <= 0 || m_nHeight <= 0 || m_nWidth > INT_MAX - 31) {
- m_pData = nullptr;
- m_bNeedFree = FALSE;
- return;
- }
- m_nStride = ((w + 31) >> 5) << 2;
- if (m_nStride * m_nHeight > 0 && 104857600 / (int)m_nStride > m_nHeight) {
- m_pData = FX_Alloc2D(uint8_t, m_nStride, m_nHeight);
- } else {
- m_pData = nullptr;
- }
- m_bNeedFree = TRUE;
+ m_nStride = stride_pixels / 8;
+ m_pData = FX_Alloc2D(uint8_t, m_nStride, m_nHeight);
}
-CJBig2_Image::CJBig2_Image(int32_t w,
- int32_t h,
- int32_t stride,
- uint8_t* pBuf) {
+
+CJBig2_Image::CJBig2_Image(int32_t w, int32_t h, int32_t stride, uint8_t* pBuf)
+ : m_pData(nullptr),
+ m_nWidth(0),
+ m_nHeight(0),
+ m_nStride(0),
+ m_bOwnsBuffer(false) {
+ if (w < 0 || h < 0 || stride < 0 || stride > kMaxImageBytes)
+ return;
+
+ int32_t stride_pixels = 8 * stride;
+ if (stride_pixels < w || h > kMaxImagePixels / stride_pixels)
+ return;
+
m_nWidth = w;
m_nHeight = h;
m_nStride = stride;
m_pData = pBuf;
- m_bNeedFree = FALSE;
}
-CJBig2_Image::CJBig2_Image(const CJBig2_Image& im) {
- m_nWidth = im.m_nWidth;
- m_nHeight = im.m_nHeight;
- m_nStride = im.m_nStride;
- if (im.m_pData) {
+
+CJBig2_Image::CJBig2_Image(const CJBig2_Image& other)
+ : m_pData(nullptr),
+ m_nWidth(other.m_nWidth),
+ m_nHeight(other.m_nHeight),
+ m_nStride(other.m_nStride),
+ m_bOwnsBuffer(true) {
+ if (other.m_pData) {
m_pData = FX_Alloc2D(uint8_t, m_nStride, m_nHeight);
- JBIG2_memcpy(m_pData, im.m_pData, m_nStride * m_nHeight);
- } else {
- m_pData = nullptr;
+ JBIG2_memcpy(m_pData, other.m_pData, m_nStride * m_nHeight);
}
- m_bNeedFree = TRUE;
}
+
CJBig2_Image::~CJBig2_Image() {
- if (m_bNeedFree) {
+ if (m_bOwnsBuffer) {
FX_Free(m_pData);
}
}
@@ -209,30 +228,24 @@ CJBig2_Image* CJBig2_Image::subImage(int32_t x,
}
return pImage;
}
+
void CJBig2_Image::expand(int32_t h, FX_BOOL v) {
- if (!m_pData || h <= m_nHeight) {
+ if (!m_pData || h <= m_nHeight || h > kMaxImageBytes / m_nStride)
return;
- }
- uint32_t dwH = pdfium::base::checked_cast<uint32_t>(h);
- uint32_t dwStride = pdfium::base::checked_cast<uint32_t>(m_nStride);
- uint32_t dwHeight = pdfium::base::checked_cast<uint32_t>(m_nHeight);
- FX_SAFE_UINT32 safeMemSize = dwH;
- safeMemSize *= dwStride;
- if (!safeMemSize.IsValid()) {
- return;
- }
- // The guaranteed reallocated memory is to be < 4GB (unsigned int).
- m_pData = FX_Realloc(uint8_t, m_pData, safeMemSize.ValueOrDie());
- // The result of dwHeight * dwStride doesn't overflow after the
- // checking of safeMemSize.
- // The same as the result of (dwH - dwHeight) * dwStride) because
- // dwH - dwHeight is always less than dwH(h) which is checked in
- // the calculation of dwH * dwStride.
- JBIG2_memset(m_pData + dwHeight * dwStride, v ? 0xff : 0,
- (dwH - dwHeight) * dwStride);
+ if (m_bOwnsBuffer) {
+ m_pData = FX_Realloc(uint8_t, m_pData, h * m_nStride);
+ } else {
+ uint8_t* pExternalBuffer = m_pData;
+ m_pData = FX_Alloc(uint8_t, h * m_nStride);
+ JBIG2_memcpy(m_pData, pExternalBuffer, m_nHeight * m_nStride);
+ m_bOwnsBuffer = true;
+ }
+ JBIG2_memset(m_pData + m_nHeight * m_nStride, v ? 0xff : 0,
+ (h - m_nHeight) * m_nStride);
m_nHeight = h;
}
+
FX_BOOL CJBig2_Image::composeTo_opt2(CJBig2_Image* pDst,
int32_t x,
int32_t y,
diff --git a/core/fxcodec/jbig2/JBig2_Image.h b/core/fxcodec/jbig2/JBig2_Image.h
index a18a95d596..f27b86e854 100644
--- a/core/fxcodec/jbig2/JBig2_Image.h
+++ b/core/fxcodec/jbig2/JBig2_Image.h
@@ -9,6 +9,8 @@
#include "core/fxcodec/jbig2/JBig2_Define.h"
+struct FX_RECT;
+
enum JBig2ComposeOp {
JBIG2_COMPOSE_OR = 0,
JBIG2_COMPOSE_AND = 1,
@@ -17,23 +19,21 @@ enum JBig2ComposeOp {
JBIG2_COMPOSE_REPLACE = 4
};
-struct FX_RECT;
class CJBig2_Image {
public:
CJBig2_Image(int32_t w, int32_t h);
-
CJBig2_Image(int32_t w, int32_t h, int32_t stride, uint8_t* pBuf);
-
CJBig2_Image(const CJBig2_Image& im);
-
~CJBig2_Image();
- FX_BOOL getPixel(int32_t x, int32_t y);
+ int32_t width() const { return m_nWidth; }
+ int32_t height() const { return m_nHeight; }
+ int32_t stride() const { return m_nStride; }
+ FX_BOOL getPixel(int32_t x, int32_t y);
int32_t setPixel(int32_t x, int32_t y, FX_BOOL v);
void copyLine(int32_t hTo, int32_t hFrom);
-
void fill(FX_BOOL v);
FX_BOOL composeTo(CJBig2_Image* pDst,
@@ -67,19 +67,15 @@ class CJBig2_Image {
const FX_RECT* pSrcRect);
CJBig2_Image* subImage(int32_t x, int32_t y, int32_t w, int32_t h);
-
void expand(int32_t h, FX_BOOL v);
- public:
- int32_t m_nWidth;
-
- int32_t m_nHeight;
-
- int32_t m_nStride;
-
uint8_t* m_pData;
- FX_BOOL m_bNeedFree;
+ private:
+ int32_t m_nWidth; // 1-bit pixels
+ int32_t m_nHeight; // lines
+ int32_t m_nStride; // bytes
+ bool m_bOwnsBuffer;
};
#endif // CORE_FXCODEC_JBIG2_JBIG2_IMAGE_H_
diff --git a/core/fxcodec/jbig2/JBig2_Image_unittest.cpp b/core/fxcodec/jbig2/JBig2_Image_unittest.cpp
new file mode 100644
index 0000000000..788f922a02
--- /dev/null
+++ b/core/fxcodec/jbig2/JBig2_Image_unittest.cpp
@@ -0,0 +1,105 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// TODO(tsepez) this requires a lot more testing.
+
+#include <stdint.h>
+
+#include "core/fxcodec/jbig2/JBig2_Image.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+const int32_t kWidthPixels = 80;
+const int32_t kWidthBytes = 10;
+const int32_t kStrideBytes = kWidthBytes + 1; // For testing stride != width.
+const int32_t kHeightLines = 20;
+const int32_t kLargerHeightLines = 100;
+const int32_t kTooLargeHeightLines = 40000000;
+
+} // namespace
+
+TEST(fxcodec, JBig2ImageCreate) {
+ CJBig2_Image img(kWidthPixels, kHeightLines);
+ img.setPixel(0, 0, true);
+ img.setPixel(kWidthPixels - 1, kHeightLines - 1, false);
+ EXPECT_EQ(kWidthPixels, img.width());
+ EXPECT_EQ(kHeightLines, img.height());
+ EXPECT_TRUE(img.getPixel(0, 0));
+ EXPECT_FALSE(img.getPixel(kWidthPixels - 1, kHeightLines - 1));
+}
+
+TEST(fxcodec, JBig2ImageCreateTooBig) {
+ CJBig2_Image img(kWidthPixels, kTooLargeHeightLines);
+ EXPECT_EQ(0, img.width());
+ EXPECT_EQ(0, img.height());
+ EXPECT_EQ(nullptr, img.m_pData);
+}
+
+TEST(fxcodec, JBig2ImageCreateExternal) {
+ uint8_t buf[kHeightLines * kStrideBytes];
+ CJBig2_Image img(kWidthPixels, kHeightLines, kStrideBytes, buf);
+ img.setPixel(0, 0, true);
+ img.setPixel(kWidthPixels - 1, kHeightLines - 1, false);
+ EXPECT_EQ(kWidthPixels, img.width());
+ EXPECT_EQ(kHeightLines, img.height());
+ EXPECT_TRUE(img.getPixel(0, 0));
+ EXPECT_FALSE(img.getPixel(kWidthPixels - 1, kHeightLines - 1));
+}
+
+TEST(fxcodec, JBig2ImageCreateExternalTooBig) {
+ uint8_t buf[kHeightLines * kStrideBytes];
+ CJBig2_Image img(kWidthPixels, kTooLargeHeightLines, kStrideBytes, buf);
+ EXPECT_EQ(0, img.width());
+ EXPECT_EQ(0, img.height());
+ EXPECT_EQ(nullptr, img.m_pData);
+}
+
+TEST(fxcodec, JBig2ImageExpand) {
+ CJBig2_Image img(kWidthPixels, kHeightLines);
+ img.setPixel(0, 0, true);
+ img.setPixel(kWidthPixels - 1, kHeightLines - 1, false);
+ img.expand(kLargerHeightLines, true);
+ EXPECT_EQ(kWidthPixels, img.width());
+ EXPECT_EQ(kLargerHeightLines, img.height());
+ EXPECT_TRUE(img.getPixel(0, 0));
+ EXPECT_FALSE(img.getPixel(kWidthPixels - 1, kHeightLines - 1));
+ EXPECT_TRUE(img.getPixel(kWidthPixels - 1, kLargerHeightLines - 1));
+}
+
+TEST(fxcodec, JBig2ImageExpandTooBig) {
+ CJBig2_Image img(kWidthPixels, kHeightLines);
+ img.setPixel(0, 0, true);
+ img.setPixel(kWidthPixels - 1, kHeightLines - 1, false);
+ img.expand(kTooLargeHeightLines, true);
+ EXPECT_EQ(kWidthPixels, img.width());
+ EXPECT_EQ(kHeightLines, img.height());
+ EXPECT_TRUE(img.getPixel(0, 0));
+ EXPECT_FALSE(img.getPixel(kWidthPixels - 1, kHeightLines - 1));
+}
+
+TEST(fxcodec, JBig2ImageExpandExternal) {
+ uint8_t buf[kHeightLines * kStrideBytes];
+ CJBig2_Image img(kWidthPixels, kHeightLines, kStrideBytes, buf);
+ img.setPixel(0, 0, true);
+ img.setPixel(kWidthPixels - 1, kHeightLines - 1, false);
+ img.expand(kLargerHeightLines, true);
+ EXPECT_EQ(kWidthPixels, img.width());
+ EXPECT_EQ(kLargerHeightLines, img.height());
+ EXPECT_TRUE(img.getPixel(0, 0));
+ EXPECT_FALSE(img.getPixel(kWidthPixels - 1, kHeightLines - 1));
+ EXPECT_TRUE(img.getPixel(kWidthPixels - 1, kLargerHeightLines - 1));
+}
+
+TEST(fxcodec, JBig2ImageExpandExternalTooBig) {
+ uint8_t buf[kHeightLines * kStrideBytes];
+ CJBig2_Image img(kWidthPixels, kHeightLines, kStrideBytes, buf);
+ img.setPixel(0, 0, true);
+ img.setPixel(kWidthPixels - 1, kHeightLines - 1, false);
+ img.expand(kTooLargeHeightLines, true);
+ EXPECT_EQ(kWidthPixels, img.width());
+ EXPECT_EQ(kHeightLines, img.height());
+ EXPECT_TRUE(img.getPixel(0, 0));
+ EXPECT_FALSE(img.getPixel(kWidthPixels - 1, kHeightLines - 1));
+}
diff --git a/core/fxcodec/jbig2/JBig2_SddProc.cpp b/core/fxcodec/jbig2/JBig2_SddProc.cpp
index 9ab6cb8a2e..c6adfce784 100644
--- a/core/fxcodec/jbig2/JBig2_SddProc.cpp
+++ b/core/fxcodec/jbig2/JBig2_SddProc.cpp
@@ -523,7 +523,7 @@ CJBig2_SymbolDict* CJBig2_SDDProc::decode_Huffman(
if (pStream->getByteLeft() >= stride * HCHEIGHT) {
BHC = new CJBig2_Image(TOTWIDTH, HCHEIGHT);
for (I = 0; I < HCHEIGHT; I++) {
- JBIG2_memcpy(BHC->m_pData + I * BHC->m_nStride,
+ JBIG2_memcpy(BHC->m_pData + I * BHC->stride(),
pStream->getPointer(), stride);
pStream->offset(stride);
}
diff --git a/core/fxcodec/jbig2/JBig2_TrdProc.cpp b/core/fxcodec/jbig2/JBig2_TrdProc.cpp
index 177db9dec9..f3dd6be2b3 100644
--- a/core/fxcodec/jbig2/JBig2_TrdProc.cpp
+++ b/core/fxcodec/jbig2/JBig2_TrdProc.cpp
@@ -114,8 +114,8 @@ CJBig2_Image* CJBig2_TRDProc::decode_Huffman(CJBig2_BitStream* pStream,
if (!IBOI)
return nullptr;
- uint32_t WOI = IBOI->m_nWidth;
- uint32_t HOI = IBOI->m_nHeight;
+ uint32_t WOI = IBOI->width();
+ uint32_t HOI = IBOI->height();
if ((int)(WOI + RDWI) < 0 || (int)(HOI + RDHI) < 0)
return nullptr;
@@ -150,8 +150,8 @@ CJBig2_Image* CJBig2_TRDProc::decode_Huffman(CJBig2_BitStream* pStream,
if (!IBI) {
continue;
}
- uint32_t WI = IBI->m_nWidth;
- uint32_t HI = IBI->m_nHeight;
+ uint32_t WI = IBI->width();
+ uint32_t HI = IBI->height();
if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPRIGHT) ||
(REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
CURS = CURS + WI - 1;
@@ -327,8 +327,8 @@ CJBig2_Image* CJBig2_TRDProc::decode_Arith(CJBig2_ArithDecoder* pArithDecoder,
if (!IBOI)
return nullptr;
- uint32_t WOI = IBOI->m_nWidth;
- uint32_t HOI = IBOI->m_nHeight;
+ uint32_t WOI = IBOI->width();
+ uint32_t HOI = IBOI->height();
if ((int)(WOI + RDWI) < 0 || (int)(HOI + RDHI) < 0)
return nullptr;
@@ -350,8 +350,8 @@ CJBig2_Image* CJBig2_TRDProc::decode_Arith(CJBig2_ArithDecoder* pArithDecoder,
if (!pIBI)
return nullptr;
- uint32_t WI = pIBI->m_nWidth;
- uint32_t HI = pIBI->m_nHeight;
+ uint32_t WI = pIBI->width();
+ uint32_t HI = pIBI->height();
if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPRIGHT) ||
(REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
CURS += WI - 1;