summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/fxcodec/jbig2/JBig2_Image.cpp39
-rw-r--r--core/fxcodec/jbig2/JBig2_Image.h11
-rw-r--r--core/fxcodec/jbig2/JBig2_Image_unittest.cpp16
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__);