OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "render_int.h" | 7 #include "render_int.h" |
8 | 8 |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "../fpdf_page/pageint.h" | 11 #include "../fpdf_page/pageint.h" |
12 #include "core/include/fpdfapi/fpdf_module.h" | 12 #include "core/include/fpdfapi/fpdf_module.h" |
13 #include "core/include/fpdfapi/fpdf_pageobj.h" | 13 #include "core/include/fpdfapi/fpdf_pageobj.h" |
14 #include "core/include/fpdfapi/fpdf_render.h" | 14 #include "core/include/fpdfapi/fpdf_render.h" |
15 #include "core/include/fxcodec/fx_codec.h" | 15 #include "core/include/fxcodec/fx_codec.h" |
16 #include "core/include/fxcrt/fx_safe_types.h" | 16 #include "core/include/fxcrt/fx_safe_types.h" |
17 #include "core/include/fxge/fx_ge.h" | 17 #include "core/include/fxge/fx_ge.h" |
18 #include "third_party/base/nonstd_unique_ptr.h" | 18 #include "third_party/base/nonstd_unique_ptr.h" |
19 | 19 |
20 namespace { | 20 namespace { |
21 | 21 |
22 unsigned int _GetBits8(const uint8_t* pData, int bitpos, int nbits) { | 22 unsigned int GetBits8(const uint8_t* pData, uint64_t bitpos, size_t nbits) { |
| 23 ASSERT(nbits == 1 || nbits == 2 || nbits == 4 || nbits == 8 || nbits == 16); |
| 24 ASSERT((bitpos & (nbits - 1)) == 0); |
23 unsigned int byte = pData[bitpos / 8]; | 25 unsigned int byte = pData[bitpos / 8]; |
24 if (nbits == 8) { | 26 if (nbits == 8) { |
25 return byte; | 27 return byte; |
26 } | 28 } |
27 if (nbits == 4) { | 29 if (nbits == 4) { |
28 return (bitpos % 8) ? (byte & 0x0f) : (byte >> 4); | 30 return (bitpos % 8) ? (byte & 0x0f) : (byte >> 4); |
29 } | 31 } |
30 if (nbits == 2) { | 32 if (nbits == 2) { |
31 return (byte >> (6 - bitpos % 8)) & 0x03; | 33 return (byte >> (6 - bitpos % 8)) & 0x03; |
32 } | 34 } |
(...skipping 953 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
986 *dest_scan++ = src_pos[2]; | 988 *dest_scan++ = src_pos[2]; |
987 *dest_scan++ = src_pos[1]; | 989 *dest_scan++ = src_pos[1]; |
988 *dest_scan++ = *src_pos; | 990 *dest_scan++ = *src_pos; |
989 src_pos += 3; | 991 src_pos += 3; |
990 } | 992 } |
991 break; | 993 break; |
992 default: | 994 default: |
993 int src_bit_pos = 0; | 995 int src_bit_pos = 0; |
994 int dest_byte_pos = 0; | 996 int dest_byte_pos = 0; |
995 for (int column = 0; column < m_Width; column++) { | 997 for (int column = 0; column < m_Width; column++) { |
996 int R = _GetBits8(src_scan, src_bit_pos, m_bpc); | 998 int R = GetBits8(src_scan, src_bit_pos, m_bpc); |
997 src_bit_pos += m_bpc; | 999 src_bit_pos += m_bpc; |
998 int G = _GetBits8(src_scan, src_bit_pos, m_bpc); | 1000 int G = GetBits8(src_scan, src_bit_pos, m_bpc); |
999 src_bit_pos += m_bpc; | 1001 src_bit_pos += m_bpc; |
1000 int B = _GetBits8(src_scan, src_bit_pos, m_bpc); | 1002 int B = GetBits8(src_scan, src_bit_pos, m_bpc); |
1001 src_bit_pos += m_bpc; | 1003 src_bit_pos += m_bpc; |
1002 R = NORMALCOLOR_MAX(R, max_data); | 1004 R = NORMALCOLOR_MAX(R, max_data); |
1003 G = NORMALCOLOR_MAX(G, max_data); | 1005 G = NORMALCOLOR_MAX(G, max_data); |
1004 B = NORMALCOLOR_MAX(B, max_data); | 1006 B = NORMALCOLOR_MAX(B, max_data); |
1005 dest_scan[dest_byte_pos] = B * 255 / max_data; | 1007 dest_scan[dest_byte_pos] = B * 255 / max_data; |
1006 dest_scan[dest_byte_pos + 1] = G * 255 / max_data; | 1008 dest_scan[dest_byte_pos + 1] = G * 255 / max_data; |
1007 dest_scan[dest_byte_pos + 2] = R * 255 / max_data; | 1009 dest_scan[dest_byte_pos + 2] = R * 255 / max_data; |
1008 dest_byte_pos += 3; | 1010 dest_byte_pos += 3; |
1009 } | 1011 } |
1010 break; | 1012 break; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1044 dest_scan[dest_byte_pos] = (int32_t)(B * 255); | 1046 dest_scan[dest_byte_pos] = (int32_t)(B * 255); |
1045 dest_scan[dest_byte_pos + 1] = (int32_t)(G * 255); | 1047 dest_scan[dest_byte_pos + 1] = (int32_t)(G * 255); |
1046 dest_scan[dest_byte_pos + 2] = (int32_t)(R * 255); | 1048 dest_scan[dest_byte_pos + 2] = (int32_t)(R * 255); |
1047 dest_byte_pos += 3; | 1049 dest_byte_pos += 3; |
1048 } | 1050 } |
1049 } else { | 1051 } else { |
1050 int src_bit_pos = 0; | 1052 int src_bit_pos = 0; |
1051 int dest_byte_pos = 0; | 1053 int dest_byte_pos = 0; |
1052 for (int column = 0; column < m_Width; column++) { | 1054 for (int column = 0; column < m_Width; column++) { |
1053 for (FX_DWORD color = 0; color < m_nComponents; color++) { | 1055 for (FX_DWORD color = 0; color < m_nComponents; color++) { |
1054 int data = _GetBits8(src_scan, src_bit_pos, m_bpc); | 1056 int data = GetBits8(src_scan, src_bit_pos, m_bpc); |
1055 color_values[color] = m_pCompData[color].m_DecodeMin + | 1057 color_values[color] = m_pCompData[color].m_DecodeMin + |
1056 m_pCompData[color].m_DecodeStep * data; | 1058 m_pCompData[color].m_DecodeStep * data; |
1057 src_bit_pos += m_bpc; | 1059 src_bit_pos += m_bpc; |
1058 } | 1060 } |
1059 if (TransMask()) { | 1061 if (TransMask()) { |
1060 FX_FLOAT k = 1.0f - color_values[3]; | 1062 FX_FLOAT k = 1.0f - color_values[3]; |
1061 R = (1.0f - color_values[0]) * k; | 1063 R = (1.0f - color_values[0]) * k; |
1062 G = (1.0f - color_values[1]) * k; | 1064 G = (1.0f - color_values[1]) * k; |
1063 B = (1.0f - color_values[2]) * k; | 1065 B = (1.0f - color_values[2]) * k; |
1064 } else { | 1066 } else { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1139 return m_pLineBuf; | 1141 return m_pLineBuf; |
1140 } | 1142 } |
1141 if (m_bpc * m_nComponents <= 8) { | 1143 if (m_bpc * m_nComponents <= 8) { |
1142 if (m_bpc == 8) { | 1144 if (m_bpc == 8) { |
1143 FXSYS_memcpy(m_pLineBuf, pSrcLine, src_pitch_value); | 1145 FXSYS_memcpy(m_pLineBuf, pSrcLine, src_pitch_value); |
1144 } else { | 1146 } else { |
1145 int src_bit_pos = 0; | 1147 int src_bit_pos = 0; |
1146 for (int col = 0; col < m_Width; col++) { | 1148 for (int col = 0; col < m_Width; col++) { |
1147 int color_index = 0; | 1149 int color_index = 0; |
1148 for (FX_DWORD color = 0; color < m_nComponents; color++) { | 1150 for (FX_DWORD color = 0; color < m_nComponents; color++) { |
1149 int data = _GetBits8(pSrcLine, src_bit_pos, m_bpc); | 1151 int data = GetBits8(pSrcLine, src_bit_pos, m_bpc); |
1150 color_index |= data << (color * m_bpc); | 1152 color_index |= data << (color * m_bpc); |
1151 src_bit_pos += m_bpc; | 1153 src_bit_pos += m_bpc; |
1152 } | 1154 } |
1153 m_pLineBuf[col] = color_index; | 1155 m_pLineBuf[col] = color_index; |
1154 } | 1156 } |
1155 } | 1157 } |
1156 if (m_bColorKey) { | 1158 if (m_bColorKey) { |
1157 uint8_t* pDestPixel = m_pMaskedLine; | 1159 uint8_t* pDestPixel = m_pMaskedLine; |
1158 const uint8_t* pSrcPixel = m_pLineBuf; | 1160 const uint8_t* pSrcPixel = m_pLineBuf; |
1159 for (int col = 0; col < m_Width; col++) { | 1161 for (int col = 0; col < m_Width; col++) { |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1361 uint8_t* dest_scan, | 1363 uint8_t* dest_scan, |
1362 int dest_width, | 1364 int dest_width, |
1363 FX_BOOL bFlipX, | 1365 FX_BOOL bFlipX, |
1364 int clip_left, | 1366 int clip_left, |
1365 int clip_width) const { | 1367 int clip_width) const { |
1366 if (m_bpc < 8) { | 1368 if (m_bpc < 8) { |
1367 int src_bit_pos = 0; | 1369 int src_bit_pos = 0; |
1368 for (FX_DWORD col = 0; col < src_width; col++) { | 1370 for (FX_DWORD col = 0; col < src_width; col++) { |
1369 int color_index = 0; | 1371 int color_index = 0; |
1370 for (FX_DWORD color = 0; color < m_nComponents; color++) { | 1372 for (FX_DWORD color = 0; color < m_nComponents; color++) { |
1371 int data = _GetBits8(pSrcLine, src_bit_pos, m_bpc); | 1373 int data = GetBits8(pSrcLine, src_bit_pos, m_bpc); |
1372 color_index |= data << (color * m_bpc); | 1374 color_index |= data << (color * m_bpc); |
1373 src_bit_pos += m_bpc; | 1375 src_bit_pos += m_bpc; |
1374 } | 1376 } |
1375 m_pLineBuf[col] = color_index; | 1377 m_pLineBuf[col] = color_index; |
1376 } | 1378 } |
1377 pSrcLine = m_pLineBuf; | 1379 pSrcLine = m_pLineBuf; |
1378 } | 1380 } |
1379 if (m_bColorKey) { | 1381 if (m_bColorKey) { |
1380 for (int i = 0; i < clip_width; i++) { | 1382 for (int i = 0; i < clip_width; i++) { |
1381 FX_DWORD src_x = (clip_left + i) * src_width / dest_width; | 1383 FX_DWORD src_x = (clip_left + i) * src_width / dest_width; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1424 int dest_Bpp, | 1426 int dest_Bpp, |
1425 FX_DWORD src_width, | 1427 FX_DWORD src_width, |
1426 const uint8_t* pSrcLine, | 1428 const uint8_t* pSrcLine, |
1427 uint8_t* dest_scan, | 1429 uint8_t* dest_scan, |
1428 int dest_width, | 1430 int dest_width, |
1429 FX_BOOL bFlipX, | 1431 FX_BOOL bFlipX, |
1430 int clip_left, | 1432 int clip_left, |
1431 int clip_width) const { | 1433 int clip_width) const { |
1432 int last_src_x = -1; | 1434 int last_src_x = -1; |
1433 FX_ARGB last_argb = FXARGB_MAKE(0xFF, 0xFF, 0xFF, 0xFF); | 1435 FX_ARGB last_argb = FXARGB_MAKE(0xFF, 0xFF, 0xFF, 0xFF); |
1434 FX_FLOAT orig_Not8Bpp = (FX_FLOAT)m_bpc * (FX_FLOAT)m_nComponents / 8.0f; | |
1435 FX_FLOAT unit_To8Bpc = 255.0f / ((1 << m_bpc) - 1); | 1436 FX_FLOAT unit_To8Bpc = 255.0f / ((1 << m_bpc) - 1); |
1436 for (int i = 0; i < clip_width; i++) { | 1437 for (int i = 0; i < clip_width; i++) { |
1437 int dest_x = clip_left + i; | 1438 int dest_x = clip_left + i; |
1438 FX_DWORD src_x = (bFlipX ? (dest_width - dest_x - 1) : dest_x) * | 1439 FX_DWORD src_x = (bFlipX ? (dest_width - dest_x - 1) : dest_x) * |
1439 (int64_t)src_width / dest_width; | 1440 (int64_t)src_width / dest_width; |
1440 src_x %= src_width; | 1441 src_x %= src_width; |
| 1442 |
| 1443 // No need to check for 32-bit overflow, as |src_x| is bounded by |
| 1444 // |src_width| and DownSampleScanline already checked for overflow with the |
| 1445 // pitch calculation. |
1441 const uint8_t* pSrcPixel = nullptr; | 1446 const uint8_t* pSrcPixel = nullptr; |
| 1447 size_t bit_offset = 0; |
1442 if (m_bpc % 8 == 0) { | 1448 if (m_bpc % 8 == 0) { |
1443 pSrcPixel = pSrcLine + src_x * orig_Bpp; | 1449 pSrcPixel = pSrcLine + src_x * orig_Bpp; |
1444 } else { | 1450 } else { |
1445 pSrcPixel = pSrcLine + (int)(src_x * orig_Not8Bpp); | 1451 size_t num_bits = src_x * m_bpc * m_nComponents; |
| 1452 pSrcPixel = pSrcLine + num_bits / 8; |
| 1453 bit_offset = num_bits % 8; |
1446 } | 1454 } |
| 1455 |
1447 uint8_t* pDestPixel = dest_scan + i * dest_Bpp; | 1456 uint8_t* pDestPixel = dest_scan + i * dest_Bpp; |
1448 FX_ARGB argb; | 1457 FX_ARGB argb; |
1449 if (src_x == last_src_x) { | 1458 if (src_x == last_src_x) { |
1450 argb = last_argb; | 1459 argb = last_argb; |
1451 } else { | 1460 } else { |
| 1461 CFX_FixedBufGrow<uint8_t, 128> extracted_components(m_nComponents); |
| 1462 if (m_bpc % 8 != 0) { |
| 1463 uint64_t src_bit_pos = bit_offset; |
| 1464 for (FX_DWORD j = 0; j < m_nComponents; ++j) { |
| 1465 extracted_components[j] = static_cast<uint8_t>( |
| 1466 GetBits8(pSrcPixel, src_bit_pos, m_bpc) * unit_To8Bpc); |
| 1467 src_bit_pos += m_bpc; |
| 1468 } |
| 1469 pSrcPixel = extracted_components; |
| 1470 } |
| 1471 |
1452 if (m_pColorSpace) { | 1472 if (m_pColorSpace) { |
1453 CFX_FixedBufGrow<uint8_t, 128> temp(orig_Bpp); | |
1454 uint8_t color[4]; | 1473 uint8_t color[4]; |
1455 const FX_BOOL bTransMask = TransMask(); | 1474 const FX_BOOL bTransMask = TransMask(); |
1456 if (m_bDefaultDecode) { | 1475 if (m_bDefaultDecode) { |
1457 if (m_bpc < 8) { | 1476 m_pColorSpace->TranslateImageLine(color, pSrcPixel, 1, 0, 0, |
1458 int src_bit_pos = 0; | 1477 bTransMask); |
1459 if (src_x % 2) { | |
1460 src_bit_pos = 4; | |
1461 } | |
1462 for (FX_DWORD j = 0; j < m_nComponents; ++j) { | |
1463 temp[j] = (uint8_t)(_GetBits8(pSrcPixel, src_bit_pos, m_bpc) * | |
1464 unit_To8Bpc); | |
1465 src_bit_pos += m_bpc; | |
1466 } | |
1467 m_pColorSpace->TranslateImageLine(color, temp, 1, 0, 0, bTransMask); | |
1468 } else { | |
1469 m_pColorSpace->TranslateImageLine(color, pSrcPixel, 1, 0, 0, | |
1470 bTransMask); | |
1471 } | |
1472 } else { | 1478 } else { |
1473 for (FX_DWORD j = 0; j < m_nComponents; ++j) { | 1479 for (FX_DWORD j = 0; j < m_nComponents; ++j) { |
| 1480 FX_FLOAT component_value = |
| 1481 static_cast<FX_FLOAT>(extracted_components[j]); |
1474 int color_value = | 1482 int color_value = |
1475 (int)((m_pCompData[j].m_DecodeMin + | 1483 (int)((m_pCompData[j].m_DecodeMin + |
1476 m_pCompData[j].m_DecodeStep * (FX_FLOAT)pSrcPixel[j]) * | 1484 m_pCompData[j].m_DecodeStep * component_value) * |
1477 255.0f + | 1485 255.0f + |
1478 0.5f); | 1486 0.5f); |
1479 temp[j] = | 1487 extracted_components[j] = |
1480 color_value > 255 ? 255 : (color_value < 0 ? 0 : color_value); | 1488 color_value > 255 ? 255 : (color_value < 0 ? 0 : color_value); |
1481 } | 1489 } |
1482 m_pColorSpace->TranslateImageLine(color, temp, 1, 0, 0, bTransMask); | 1490 m_pColorSpace->TranslateImageLine(color, extracted_components, 1, 0, |
| 1491 0, bTransMask); |
1483 } | 1492 } |
1484 argb = FXARGB_MAKE(0xFF, color[2], color[1], color[0]); | 1493 argb = FXARGB_MAKE(0xFF, color[2], color[1], color[0]); |
1485 } else { | 1494 } else { |
1486 argb = FXARGB_MAKE(0xFf, pSrcPixel[2], pSrcPixel[1], pSrcPixel[0]); | 1495 argb = FXARGB_MAKE(0xFF, pSrcPixel[2], pSrcPixel[1], pSrcPixel[0]); |
1487 } | 1496 } |
1488 if (m_bColorKey) { | 1497 if (m_bColorKey) { |
1489 int alpha = 0xFF; | 1498 int alpha = 0xFF; |
1490 if (m_nComponents == 3 && m_bpc == 8) { | 1499 if (m_nComponents == 3 && m_bpc == 8) { |
1491 alpha = (pSrcPixel[0] < m_pCompData[0].m_ColorKeyMin || | 1500 alpha = (pSrcPixel[0] < m_pCompData[0].m_ColorKeyMin || |
1492 pSrcPixel[0] > m_pCompData[0].m_ColorKeyMax || | 1501 pSrcPixel[0] > m_pCompData[0].m_ColorKeyMax || |
1493 pSrcPixel[1] < m_pCompData[1].m_ColorKeyMin || | 1502 pSrcPixel[1] < m_pCompData[1].m_ColorKeyMin || |
1494 pSrcPixel[1] > m_pCompData[1].m_ColorKeyMax || | 1503 pSrcPixel[1] > m_pCompData[1].m_ColorKeyMax || |
1495 pSrcPixel[2] < m_pCompData[2].m_ColorKeyMin || | 1504 pSrcPixel[2] < m_pCompData[2].m_ColorKeyMin || |
1496 pSrcPixel[2] > m_pCompData[2].m_ColorKeyMax) | 1505 pSrcPixel[2] > m_pCompData[2].m_ColorKeyMax) |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1641 } | 1650 } |
1642 FX_BOOL CPDF_ImageLoader::Continue(void* LoadHandle, IFX_Pause* pPause) { | 1651 FX_BOOL CPDF_ImageLoader::Continue(void* LoadHandle, IFX_Pause* pPause) { |
1643 return ((CPDF_ProgressiveImageLoaderHandle*)LoadHandle)->Continue(pPause); | 1652 return ((CPDF_ProgressiveImageLoaderHandle*)LoadHandle)->Continue(pPause); |
1644 } | 1653 } |
1645 CPDF_ImageLoader::~CPDF_ImageLoader() { | 1654 CPDF_ImageLoader::~CPDF_ImageLoader() { |
1646 if (!m_bCached) { | 1655 if (!m_bCached) { |
1647 delete m_pBitmap; | 1656 delete m_pBitmap; |
1648 delete m_pMask; | 1657 delete m_pMask; |
1649 } | 1658 } |
1650 } | 1659 } |
OLD | NEW |