diff options
-rw-r--r-- | BUILD.gn | 1 | ||||
-rw-r--r-- | core/fxcodec/jbig2/JBig2_Context.cpp | 14 | ||||
-rw-r--r-- | core/fxcodec/jbig2/JBig2_GrdProc.cpp | 22 | ||||
-rw-r--r-- | core/fxcodec/jbig2/JBig2_GrrdProc.cpp | 20 | ||||
-rw-r--r-- | core/fxcodec/jbig2/JBig2_Image.cpp | 107 | ||||
-rw-r--r-- | core/fxcodec/jbig2/JBig2_Image.h | 26 | ||||
-rw-r--r-- | core/fxcodec/jbig2/JBig2_Image_unittest.cpp | 105 | ||||
-rw-r--r-- | core/fxcodec/jbig2/JBig2_SddProc.cpp | 2 | ||||
-rw-r--r-- | core/fxcodec/jbig2/JBig2_TrdProc.cpp | 16 |
9 files changed, 214 insertions, 99 deletions
@@ -1463,6 +1463,7 @@ test("pdfium_unittests") { "core/fpdfdoc/doc_basic_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 8dde290be6..fdb326819c 100644 --- a/core/fxcodec/jbig2/JBig2_Context.cpp +++ b/core/fxcodec/jbig2/JBig2_Context.cpp @@ -939,7 +939,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); } } @@ -1030,8 +1030,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); @@ -1057,7 +1057,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); } } @@ -1123,7 +1123,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); } @@ -1158,7 +1158,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); } @@ -1231,7 +1231,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; |