Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1196)

Side by Side Diff: core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp

Issue 1433423002: Fix extraction of colour components in CPDF_DIBSource::DownSampleScanline32Bit (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: address comments Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « BUILD.gn ('k') | core/src/fpdfapi/fpdf_render/fpdf_render_loadimage_embeddertest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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);
Tom Sepez 2015/11/11 23:33:59 Just noticed this: Anything that GetBits8 is assig
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
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
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
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
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] =
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
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 }
OLDNEW
« no previous file with comments | « BUILD.gn ('k') | core/src/fpdfapi/fpdf_render/fpdf_render_loadimage_embeddertest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698