diff options
-rw-r--r-- | core/fxcodec/jbig2/JBig2_Image.cpp | 39 | ||||
-rw-r--r-- | core/fxcodec/jbig2/JBig2_Image.h | 11 | ||||
-rw-r--r-- | core/fxcodec/jbig2/JBig2_Image_unittest.cpp | 16 |
3 files changed, 53 insertions, 13 deletions
diff --git a/core/fxcodec/jbig2/JBig2_Image.cpp b/core/fxcodec/jbig2/JBig2_Image.cpp index b64a4fdbe7..f37a368176 100644 --- a/core/fxcodec/jbig2/JBig2_Image.cpp +++ b/core/fxcodec/jbig2/JBig2_Image.cpp @@ -196,22 +196,36 @@ std::unique_ptr<CJBig2_Image> CJBig2_Image::SubImage(int32_t x, if (x < 0 || x >= m_nWidth || y < 0 || y >= m_nHeight) return pImage; + // Fast case when byte-aligned, normal slow case otherwise. + if ((x & 7) == 0) + SubImageFast(x, y, w, h, pImage.get()); + else + SubImageSlow(x, y, w, h, pImage.get()); + + return pImage; +} + +void CJBig2_Image::SubImageFast(int32_t x, + int32_t y, + int32_t w, + int32_t h, + CJBig2_Image* pImage) { + int32_t m = BIT_INDEX_TO_BYTE(x); + int32_t bytes_to_copy = std::min(pImage->m_nStride, m_nStride - m); + int32_t lines_to_copy = std::min(pImage->m_nHeight, m_nHeight - y); + for (int32_t j = 0; j < lines_to_copy; j++) + memcpy(pImage->GetLineUnsafe(j), GetLineUnsafe(y + j) + m, bytes_to_copy); +} + +void CJBig2_Image::SubImageSlow(int32_t x, + int32_t y, + int32_t w, + int32_t h, + CJBig2_Image* pImage) { int32_t m = BIT_INDEX_TO_ALIGNED_BYTE(x); int32_t n = x & 31; int32_t bytes_to_copy = std::min(pImage->m_nStride, m_nStride - m); int32_t lines_to_copy = std::min(pImage->m_nHeight, m_nHeight - y); - - // Fast case when DWORD-aligned. - if (n == 0) { - for (int32_t j = 0; j < lines_to_copy; j++) { - const uint8_t* pLineSrc = GetLineUnsafe(y + j); - uint8_t* pLineDst = pImage->GetLineUnsafe(j); - memcpy(pLineDst, pLineSrc + m, bytes_to_copy); - } - return pImage; - } - - // Normal slow case. for (int32_t j = 0; j < lines_to_copy; j++) { const uint8_t* pLineSrc = GetLineUnsafe(y + j); uint8_t* pLineDst = pImage->GetLineUnsafe(j); @@ -225,7 +239,6 @@ std::unique_ptr<CJBig2_Image> CJBig2_Image::SubImage(int32_t x, JBIG2_PUTDWORD(pDst, wTmp); } } - return pImage; } void CJBig2_Image::Expand(int32_t h, bool v) { diff --git a/core/fxcodec/jbig2/JBig2_Image.h b/core/fxcodec/jbig2/JBig2_Image.h index b61ce84e0f..d593054e4d 100644 --- a/core/fxcodec/jbig2/JBig2_Image.h +++ b/core/fxcodec/jbig2/JBig2_Image.h @@ -69,6 +69,17 @@ class CJBig2_Image { JBig2ComposeOp op); private: + void SubImageFast(int32_t x, + int32_t y, + int32_t w, + int32_t h, + CJBig2_Image* pImage); + void SubImageSlow(int32_t x, + int32_t y, + int32_t w, + int32_t h, + CJBig2_Image* pImage); + bool ComposeToOpt2(CJBig2_Image* pDst, int32_t x, int32_t y, diff --git a/core/fxcodec/jbig2/JBig2_Image_unittest.cpp b/core/fxcodec/jbig2/JBig2_Image_unittest.cpp index 4b078324e1..13e6eb5691 100644 --- a/core/fxcodec/jbig2/JBig2_Image_unittest.cpp +++ b/core/fxcodec/jbig2/JBig2_Image_unittest.cpp @@ -219,6 +219,15 @@ TEST(fxcodec, JBig2SubImage) { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, }; + // 1-px wide rectangle in image, offset 16 in x, 1 in y, padded. + uint8_t pattern161[5][8] = { + {0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + }; + // Image size a nice clean power of two. auto img32 = pdfium::MakeUnique<CJBig2_Image>( 32, 5, 8, reinterpret_cast<uint8_t*>(pattern)); @@ -234,6 +243,9 @@ TEST(fxcodec, JBig2SubImage) { auto expected22 = pdfium::MakeUnique<CJBig2_Image>( 30, 5, 8, reinterpret_cast<uint8_t*>(pattern22)); + auto expected161 = pdfium::MakeUnique<CJBig2_Image>( + 25, 5, 8, reinterpret_cast<uint8_t*>(pattern161)); + auto expected_zeros = pdfium::MakeUnique<CJBig2_Image>(32, 5); // Empty subimage. @@ -259,6 +271,10 @@ TEST(fxcodec, JBig2SubImage) { sub = img37->SubImage(2, 2, 30, 5); CheckImageEq(expected22.get(), sub.get(), __LINE__); + // Fast path. + sub = img37->SubImage(16, 1, 25, 5); + CheckImageEq(expected161.get(), sub.get(), __LINE__); + // Aligned Sub-image including cruft in stride beyond width. sub = img37->SubImage(32, 0, 32, 5); CheckImageEq(expected_zeros.get(), sub.get(), __LINE__); |