From 29201324de188dc3f88d835a90af18e10f5ff868 Mon Sep 17 00:00:00 2001 From: Tom Sepez Date: Mon, 6 Aug 2018 18:17:23 +0000 Subject: Small optimization in CJBig2_Image::SubImage() We can use the memcpy() path whenever byte aligned. Split code into helper methods. Add test for fast path specifically. Change-Id: I52f6129b0e788eb2da60536cfa6fce12a0609375 Reviewed-on: https://pdfium-review.googlesource.com/39432 Reviewed-by: Lei Zhang Commit-Queue: Tom Sepez --- core/fxcodec/jbig2/JBig2_Image.cpp | 39 +++++++++++++++++++---------- core/fxcodec/jbig2/JBig2_Image.h | 11 ++++++++ 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::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::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( 32, 5, 8, reinterpret_cast(pattern)); @@ -234,6 +243,9 @@ TEST(fxcodec, JBig2SubImage) { auto expected22 = pdfium::MakeUnique( 30, 5, 8, reinterpret_cast(pattern22)); + auto expected161 = pdfium::MakeUnique( + 25, 5, 8, reinterpret_cast(pattern161)); + auto expected_zeros = pdfium::MakeUnique(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__); -- cgit v1.2.3