 Chromium Code Reviews
 Chromium Code Reviews Issue 1433423002:
  Fix extraction of colour components in CPDF_DIBSource::DownSampleScanline32Bit  (Closed) 
  Base URL: https://pdfium.googlesource.com/pdfium.git@master
    
  
    Issue 1433423002:
  Fix extraction of colour components in CPDF_DIBSource::DownSampleScanline32Bit  (Closed) 
  Base URL: https://pdfium.googlesource.com/pdfium.git@master| 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, size_t bitpos, size_t nbits) { | 
| 
Tom Sepez
2015/11/11 21:09:44
follow-up: bitpos needs to be an uint64_t.
kMaxIm
 
Oliver Chang
2015/11/11 22:30:59
Done. will fix up callers in a separate CL.
 | |
| 23 unsigned int byte = pData[bitpos / 8]; | 23 unsigned int byte = pData[bitpos / 8]; | 
| 
Tom Sepez
2015/11/11 21:09:45
ASSERT(nbits == 1 || nbits == 2 || nbits == 4 ||
 
Oliver Chang
2015/11/11 22:30:59
Done.
 | |
| 24 if (nbits == 8) { | 24 if (nbits == 8) { | 
| 25 return byte; | 25 return byte; | 
| 26 } | 26 } | 
| 27 if (nbits == 4) { | 27 if (nbits == 4) { | 
| 28 return (bitpos % 8) ? (byte & 0x0f) : (byte >> 4); | 28 return (bitpos % 8) ? (byte & 0x0f) : (byte >> 4); | 
| 29 } | 29 } | 
| 30 if (nbits == 2) { | 30 if (nbits == 2) { | 
| 31 return (byte >> (6 - bitpos % 8)) & 0x03; | 31 return (byte >> (6 - bitpos % 8)) & 0x03; | 
| 
Tom Sepez
2015/11/11 21:09:45
follow-up: There's probably a general form of this
 
Oliver Chang
2015/11/11 22:30:59
Acknowledged.
 | |
| 32 } | 32 } | 
| 33 if (nbits == 1) { | 33 if (nbits == 1) { | 
| 34 return (byte >> (7 - bitpos % 8)) & 0x01; | 34 return (byte >> (7 - bitpos % 8)) & 0x01; | 
| 35 } | 35 } | 
| 36 if (nbits == 16) { | 36 if (nbits == 16) { | 
| 37 return byte * 256 + pData[bitpos / 8 + 1]; | 37 return byte * 256 + pData[bitpos / 8 + 1]; | 
| 38 } | 38 } | 
| 39 return 0; | 39 return 0; | 
| 40 } | 40 } | 
| 41 | 41 | 
| (...skipping 1382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1424 int dest_Bpp, | 1424 int dest_Bpp, | 
| 1425 FX_DWORD src_width, | 1425 FX_DWORD src_width, | 
| 1426 const uint8_t* pSrcLine, | 1426 const uint8_t* pSrcLine, | 
| 1427 uint8_t* dest_scan, | 1427 uint8_t* dest_scan, | 
| 1428 int dest_width, | 1428 int dest_width, | 
| 1429 FX_BOOL bFlipX, | 1429 FX_BOOL bFlipX, | 
| 1430 int clip_left, | 1430 int clip_left, | 
| 1431 int clip_width) const { | 1431 int clip_width) const { | 
| 1432 int last_src_x = -1; | 1432 int last_src_x = -1; | 
| 1433 FX_ARGB last_argb = FXARGB_MAKE(0xFF, 0xFF, 0xFF, 0xFF); | 1433 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); | 1434 FX_FLOAT unit_To8Bpc = 255.0f / ((1 << m_bpc) - 1); | 
| 1436 for (int i = 0; i < clip_width; i++) { | 1435 for (int i = 0; i < clip_width; i++) { | 
| 1437 int dest_x = clip_left + i; | 1436 int dest_x = clip_left + i; | 
| 1438 FX_DWORD src_x = (bFlipX ? (dest_width - dest_x - 1) : dest_x) * | 1437 FX_DWORD src_x = (bFlipX ? (dest_width - dest_x - 1) : dest_x) * | 
| 1439 (int64_t)src_width / dest_width; | 1438 (int64_t)src_width / dest_width; | 
| 1440 src_x %= src_width; | 1439 src_x %= src_width; | 
| 1441 const uint8_t* pSrcPixel = nullptr; | 1440 | 
| 1441 // No need to check for overflow, as |src_x| is bounded by |src_width| and | |
| 1442 // DownSampleScanline already checked for overflow with the pitch | |
| 1443 // calculation. | |
| 1444 size_t byte_offset = src_x; | |
| 1445 size_t bit_offset = 0; | |
| 1442 if (m_bpc % 8 == 0) { | 1446 if (m_bpc % 8 == 0) { | 
| 1443 pSrcPixel = pSrcLine + src_x * orig_Bpp; | 1447 byte_offset *= orig_Bpp; | 
| 1444 } else { | 1448 } else { | 
| 1445 pSrcPixel = pSrcLine + (int)(src_x * orig_Not8Bpp); | 1449 byte_offset *= m_bpc; | 
| 
Tom Sepez
2015/11/11 21:09:45
nit: this can probably be an infix expression sinc
 
Oliver Chang
2015/11/11 22:30:59
Done. I initially used a safe size_t, but neglecte
 | |
| 1450 byte_offset *= m_nComponents; | |
| 1451 bit_offset = byte_offset % 8; | |
| 1452 byte_offset /= 8; | |
| 1446 } | 1453 } | 
| 1454 | |
| 1455 const uint8_t* pSrcPixel = pSrcLine + byte_offset; | |
| 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 for (FX_DWORD j = 0; j < m_nComponents; ++j) { | |
| 1464 extracted_components[j] = | |
| 1465 _GetBits8(pSrcPixel, bit_offset + (j * m_bpc), m_bpc) * | |
| 1466 unit_To8Bpc; | |
| 1467 } | |
| 1468 pSrcPixel = extracted_components; | |
| 1469 } | |
| 1470 | |
| 
Tom Sepez
2015/11/11 21:09:45
I think there's a problem with {} nesting, I'd exp
 
Oliver Chang
2015/11/11 22:30:59
Acknowledged.
 | |
| 1452 if (m_pColorSpace) { | 1471 if (m_pColorSpace) { | 
| 1453 CFX_FixedBufGrow<uint8_t, 128> temp(orig_Bpp); | |
| 1454 uint8_t color[4]; | 1472 uint8_t color[4]; | 
| 1455 const FX_BOOL bTransMask = TransMask(); | 1473 const FX_BOOL bTransMask = TransMask(); | 
| 1456 if (m_bDefaultDecode) { | 1474 if (m_bDefaultDecode) { | 
| 1457 if (m_bpc < 8) { | 1475 m_pColorSpace->TranslateImageLine(color, pSrcPixel, 1, 0, 0, | 
| 1458 int src_bit_pos = 0; | 1476 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 { | 1477 } else { | 
| 1473 for (FX_DWORD j = 0; j < m_nComponents; ++j) { | 1478 for (FX_DWORD j = 0; j < m_nComponents; ++j) { | 
| 1479 FX_FLOAT component_value = | |
| 1480 static_cast<FX_FLOAT>(extracted_components[j]); | |
| 1474 int color_value = | 1481 int color_value = | 
| 1475 (int)((m_pCompData[j].m_DecodeMin + | 1482 (int)((m_pCompData[j].m_DecodeMin + | 
| 1476 m_pCompData[j].m_DecodeStep * (FX_FLOAT)pSrcPixel[j]) * | 1483 m_pCompData[j].m_DecodeStep * component_value) * | 
| 1477 255.0f + | 1484 255.0f + | 
| 1478 0.5f); | 1485 0.5f); | 
| 1479 temp[j] = | 1486 extracted_components[j] = | 
| 1480 color_value > 255 ? 255 : (color_value < 0 ? 0 : color_value); | 1487 color_value > 255 ? 255 : (color_value < 0 ? 0 : color_value); | 
| 1481 } | 1488 } | 
| 1482 m_pColorSpace->TranslateImageLine(color, temp, 1, 0, 0, bTransMask); | 1489 m_pColorSpace->TranslateImageLine(color, extracted_components, 1, 0, | 
| 1490 0, bTransMask); | |
| 1483 } | 1491 } | 
| 1484 argb = FXARGB_MAKE(0xFF, color[2], color[1], color[0]); | 1492 argb = FXARGB_MAKE(0xFF, color[2], color[1], color[0]); | 
| 1485 } else { | 1493 } else { | 
| 1486 argb = FXARGB_MAKE(0xFf, pSrcPixel[2], pSrcPixel[1], pSrcPixel[0]); | 1494 argb = FXARGB_MAKE(0xFF, pSrcPixel[2], pSrcPixel[1], pSrcPixel[0]); | 
| 1487 } | 1495 } | 
| 1488 if (m_bColorKey) { | 1496 if (m_bColorKey) { | 
| 1489 int alpha = 0xFF; | 1497 int alpha = 0xFF; | 
| 1490 if (m_nComponents == 3 && m_bpc == 8) { | 1498 if (m_nComponents == 3 && m_bpc == 8) { | 
| 1491 alpha = (pSrcPixel[0] < m_pCompData[0].m_ColorKeyMin || | 1499 alpha = (pSrcPixel[0] < m_pCompData[0].m_ColorKeyMin || | 
| 1492 pSrcPixel[0] > m_pCompData[0].m_ColorKeyMax || | 1500 pSrcPixel[0] > m_pCompData[0].m_ColorKeyMax || | 
| 1493 pSrcPixel[1] < m_pCompData[1].m_ColorKeyMin || | 1501 pSrcPixel[1] < m_pCompData[1].m_ColorKeyMin || | 
| 1494 pSrcPixel[1] > m_pCompData[1].m_ColorKeyMax || | 1502 pSrcPixel[1] > m_pCompData[1].m_ColorKeyMax || | 
| 1495 pSrcPixel[2] < m_pCompData[2].m_ColorKeyMin || | 1503 pSrcPixel[2] < m_pCompData[2].m_ColorKeyMin || | 
| 1496 pSrcPixel[2] > m_pCompData[2].m_ColorKeyMax) | 1504 pSrcPixel[2] > m_pCompData[2].m_ColorKeyMax) | 
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1641 } | 1649 } | 
| 1642 FX_BOOL CPDF_ImageLoader::Continue(void* LoadHandle, IFX_Pause* pPause) { | 1650 FX_BOOL CPDF_ImageLoader::Continue(void* LoadHandle, IFX_Pause* pPause) { | 
| 1643 return ((CPDF_ProgressiveImageLoaderHandle*)LoadHandle)->Continue(pPause); | 1651 return ((CPDF_ProgressiveImageLoaderHandle*)LoadHandle)->Continue(pPause); | 
| 1644 } | 1652 } | 
| 1645 CPDF_ImageLoader::~CPDF_ImageLoader() { | 1653 CPDF_ImageLoader::~CPDF_ImageLoader() { | 
| 1646 if (!m_bCached) { | 1654 if (!m_bCached) { | 
| 1647 delete m_pBitmap; | 1655 delete m_pBitmap; | 
| 1648 delete m_pMask; | 1656 delete m_pMask; | 
| 1649 } | 1657 } | 
| 1650 } | 1658 } | 
| OLD | NEW |