Change cfx_cmyk_to_srgb code to return struct FX_RGB
Use FX_RGB consistently for color representation.
Change-Id: I282232f7eb6b91816af068edd152dccd46364596
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/117391
Reviewed-by: Thomas Sepez <tsepez@google.com>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/page/cpdf_devicecs.cpp b/core/fpdfapi/page/cpdf_devicecs.cpp
index d152938..c1986f7 100644
--- a/core/fpdfapi/page/cpdf_devicecs.cpp
+++ b/core/fpdfapi/page/cpdf_devicecs.cpp
@@ -64,9 +64,12 @@
*G = 1.0f - std::min(1.0f, pBuf[1] + k);
*B = 1.0f - std::min(1.0f, pBuf[2] + k);
} else {
- std::tie(*R, *G, *B) = AdobeCMYK_to_sRGB(
+ FX_RGB<float> rgb = AdobeCMYK_to_sRGB(
NormalizeChannel(pBuf[0]), NormalizeChannel(pBuf[1]),
NormalizeChannel(pBuf[2]), NormalizeChannel(pBuf[3]));
+ *R = rgb.red;
+ *G = rgb.green;
+ *B = rgb.blue;
}
return true;
default:
@@ -132,9 +135,11 @@
}
} else {
for (int i = 0; i < pixels; i++) {
- std::tie(pDestBuf[2], pDestBuf[1], pDestBuf[0]) =
- AdobeCMYK_to_sRGB1(pSrcBuf[0], pSrcBuf[1], pSrcBuf[2],
- pSrcBuf[3]);
+ FX_RGB<uint8_t> rgb = AdobeCMYK_to_sRGB1(pSrcBuf[0], pSrcBuf[1],
+ pSrcBuf[2], pSrcBuf[3]);
+ pDestBuf[0] = rgb.blue;
+ pDestBuf[1] = rgb.green;
+ pDestBuf[2] = rgb.red;
pSrcBuf += 4;
pDestBuf += 3;
}
diff --git a/core/fxcodec/progressive_decoder.cpp b/core/fxcodec/progressive_decoder.cpp
index 332df51..320b226 100644
--- a/core/fxcodec/progressive_decoder.cpp
+++ b/core/fxcodec/progressive_decoder.cpp
@@ -1353,7 +1353,8 @@
src_line += 4;
}
}
- } break;
+ break;
+ }
case FXDIB_Format::kRgb:
case FXDIB_Format::kRgb32: {
int32_t desBpp =
@@ -1373,7 +1374,8 @@
src_line += 4;
}
}
- } break;
+ break;
+ }
default:
break;
}
@@ -1596,7 +1598,8 @@
default:
m_TransMethod = -1;
}
- } break;
+ break;
+ }
case FXDIB_Format::k8bppMask:
case FXDIB_Format::k8bppRgb: {
switch (src_format) {
@@ -1621,7 +1624,8 @@
default:
m_TransMethod = -1;
}
- } break;
+ break;
+ }
case FXDIB_Format::kRgb: {
switch (src_format) {
case FXCodec_1bppGray:
@@ -1645,7 +1649,8 @@
default:
m_TransMethod = -1;
}
- } break;
+ break;
+ }
case FXDIB_Format::kRgb32:
case FXDIB_Format::kArgb: {
switch (src_format) {
@@ -1676,7 +1681,8 @@
default:
m_TransMethod = -1;
}
- } break;
+ break;
+ }
default:
m_TransMethod = -1;
}
@@ -1713,7 +1719,8 @@
dest_g += pixel_weight * src_scan[j];
}
*dest_scan++ = CStretchEngine::PixelFromFixed(dest_g);
- } break;
+ break;
+ }
case 3: {
uint32_t dest_r = 0;
uint32_t dest_g = 0;
@@ -1731,7 +1738,8 @@
FXRGB2GRAY(CStretchEngine::PixelFromFixed(dest_r),
CStretchEngine::PixelFromFixed(dest_g),
CStretchEngine::PixelFromFixed(dest_b)));
- } break;
+ break;
+ }
case 4: {
uint32_t dest_b = 0;
uint32_t dest_g = 0;
@@ -1749,31 +1757,30 @@
FXRGB2GRAY(CStretchEngine::PixelFromFixed(dest_r),
CStretchEngine::PixelFromFixed(dest_g),
CStretchEngine::PixelFromFixed(dest_b)));
- } break;
+ break;
+ }
case 5: {
- uint32_t dest_b = 0;
- uint32_t dest_g = 0;
uint32_t dest_r = 0;
+ uint32_t dest_g = 0;
+ uint32_t dest_b = 0;
for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
j++) {
uint32_t pixel_weight =
pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
const uint8_t* src_pixel = src_scan + j * src_bytes_per_pixel;
- uint8_t src_b = 0;
- uint8_t src_g = 0;
- uint8_t src_r = 0;
- std::tie(src_r, src_g, src_b) =
+ FX_RGB<uint8_t> src_rgb =
AdobeCMYK_to_sRGB1(255 - src_pixel[0], 255 - src_pixel[1],
255 - src_pixel[2], 255 - src_pixel[3]);
- dest_b += pixel_weight * src_b;
- dest_g += pixel_weight * src_g;
- dest_r += pixel_weight * src_r;
+ dest_r += pixel_weight * src_rgb.red;
+ dest_g += pixel_weight * src_rgb.green;
+ dest_b += pixel_weight * src_rgb.blue;
}
*dest_scan++ = static_cast<uint8_t>(
FXRGB2GRAY(CStretchEngine::PixelFromFixed(dest_r),
CStretchEngine::PixelFromFixed(dest_g),
CStretchEngine::PixelFromFixed(dest_b)));
- } break;
+ break;
+ }
case 6:
return;
case 7: {
@@ -1786,7 +1793,8 @@
}
memset(dest_scan, CStretchEngine::PixelFromFixed(dest_g), 3);
dest_scan += dest_bytes_per_pixel;
- } break;
+ break;
+ }
case 8: {
uint32_t dest_r = 0;
uint32_t dest_g = 0;
@@ -1804,7 +1812,8 @@
*dest_scan++ = CStretchEngine::PixelFromFixed(dest_g);
*dest_scan++ = CStretchEngine::PixelFromFixed(dest_r);
dest_scan += dest_bytes_per_pixel - 3;
- } break;
+ break;
+ }
case 12: {
#ifdef PDF_ENABLE_XFA_BMP
if (m_pBmpContext) {
@@ -1845,7 +1854,8 @@
*dest_scan++ = CStretchEngine::PixelFromFixed(dest_g);
*dest_scan++ = CStretchEngine::PixelFromFixed(dest_r);
*dest_scan++ = CStretchEngine::PixelFromFixed(dest_a);
- } break;
+ break;
+ }
case 9: {
uint32_t dest_b = 0;
uint32_t dest_g = 0;
@@ -1863,7 +1873,8 @@
*dest_scan++ = CStretchEngine::PixelFromFixed(dest_g);
*dest_scan++ = CStretchEngine::PixelFromFixed(dest_r);
dest_scan += dest_bytes_per_pixel - 3;
- } break;
+ break;
+ }
case 10: {
uint32_t dest_b = 0;
uint32_t dest_g = 0;
@@ -1873,21 +1884,19 @@
uint32_t pixel_weight =
pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
const uint8_t* src_pixel = src_scan + j * src_bytes_per_pixel;
- uint8_t src_b = 0;
- uint8_t src_g = 0;
- uint8_t src_r = 0;
- std::tie(src_r, src_g, src_b) =
+ FX_RGB<uint8_t> src_rgb =
AdobeCMYK_to_sRGB1(255 - src_pixel[0], 255 - src_pixel[1],
255 - src_pixel[2], 255 - src_pixel[3]);
- dest_b += pixel_weight * src_b;
- dest_g += pixel_weight * src_g;
- dest_r += pixel_weight * src_r;
+ dest_b += pixel_weight * src_rgb.blue;
+ dest_g += pixel_weight * src_rgb.green;
+ dest_r += pixel_weight * src_rgb.red;
}
*dest_scan++ = CStretchEngine::PixelFromFixed(dest_b);
*dest_scan++ = CStretchEngine::PixelFromFixed(dest_g);
*dest_scan++ = CStretchEngine::PixelFromFixed(dest_r);
dest_scan += dest_bytes_per_pixel - 3;
- } break;
+ break;
+ }
case 11: {
uint32_t dest_alpha = 0;
uint32_t dest_r = 0;
@@ -1908,7 +1917,8 @@
*dest_scan++ = CStretchEngine::PixelFromFixed(dest_g);
*dest_scan++ = CStretchEngine::PixelFromFixed(dest_r);
*dest_scan++ = CStretchEngine::PixelFromFixed(dest_alpha * 255);
- } break;
+ break;
+ }
default:
return;
}
diff --git a/core/fxge/dib/cfx_cmyk_to_srgb.cpp b/core/fxge/dib/cfx_cmyk_to_srgb.cpp
index 4abf3e1..8262cb0 100644
--- a/core/fxge/dib/cfx_cmyk_to_srgb.cpp
+++ b/core/fxge/dib/cfx_cmyk_to_srgb.cpp
@@ -7,7 +7,6 @@
#include "core/fxge/dib/cfx_cmyk_to_srgb.h"
#include <algorithm>
-#include <tuple>
#include "core/fxcrt/check_op.h"
#include "core/fxcrt/fx_system.h"
@@ -1662,10 +1661,7 @@
} // namespace
-std::tuple<uint8_t, uint8_t, uint8_t> AdobeCMYK_to_sRGB1(uint8_t c,
- uint8_t m,
- uint8_t y,
- uint8_t k) {
+FX_RGB<uint8_t> AdobeCMYK_to_sRGB1(uint8_t c, uint8_t m, uint8_t y, uint8_t k) {
int fix_c = c << 8;
int fix_m = m << 8;
int fix_y = y << 8;
@@ -1715,17 +1711,15 @@
fix_g += (kCMYK[pos][1] - kCMYK[k1_pos][1]) * k_rate / 32;
fix_b += (kCMYK[pos][2] - kCMYK[k1_pos][2]) * k_rate / 32;
- fix_r = std::max(fix_r, 0);
- fix_g = std::max(fix_g, 0);
- fix_b = std::max(fix_b, 0);
+ fix_r = std::max(fix_r, 0) >> 8;
+ fix_g = std::max(fix_g, 0) >> 8;
+ fix_b = std::max(fix_b, 0) >> 8;
- return std::make_tuple(fix_r >> 8, fix_g >> 8, fix_b >> 8);
+ return {static_cast<uint8_t>(fix_r), static_cast<uint8_t>(fix_g),
+ static_cast<uint8_t>(fix_b)};
}
-std::tuple<float, float, float> AdobeCMYK_to_sRGB(float c,
- float m,
- float y,
- float k) {
+FX_RGB<float> AdobeCMYK_to_sRGB(float c, float m, float y, float k) {
// Convert to uint8_t with round-to-nearest. Avoid using FXSYS_roundf because
// it is incredibly expensive with VC++ (tested on VC++ 2015) because round()
// is very expensive.
@@ -1735,24 +1729,26 @@
// That value is close to the cusp but zero is the correct answer, and
// getting the same answer as before is desirable.
// All floats from 0.0 to 1.0 were tested and now give the same results.
- const float rounding_offset = 0.49999997f;
- uint8_t c1 = static_cast<int>(c * 255.f + rounding_offset);
- uint8_t m1 = static_cast<int>(m * 255.f + rounding_offset);
- uint8_t y1 = static_cast<int>(y * 255.f + rounding_offset);
- uint8_t k1 = static_cast<int>(k * 255.f + rounding_offset);
+ constexpr float kRoundingOffset = 0.49999997f;
+ uint8_t c1 = static_cast<int>(c * 255.f + kRoundingOffset);
+ uint8_t m1 = static_cast<int>(m * 255.f + kRoundingOffset);
+ uint8_t y1 = static_cast<int>(y * 255.f + kRoundingOffset);
+ uint8_t k1 = static_cast<int>(k * 255.f + kRoundingOffset);
DCHECK_EQ(c1, FXSYS_roundf(c * 255));
DCHECK_EQ(m1, FXSYS_roundf(m * 255));
DCHECK_EQ(y1, FXSYS_roundf(y * 255));
DCHECK_EQ(k1, FXSYS_roundf(k * 255));
- uint8_t r;
- uint8_t g;
- uint8_t b;
- std::tie(r, g, b) = AdobeCMYK_to_sRGB1(c1, m1, y1, k1);
+ FX_RGB<uint8_t> int_results = AdobeCMYK_to_sRGB1(c1, m1, y1, k1);
// Multiply by a constant rather than dividing because division is much
// more expensive.
- return std::make_tuple(r * (1.0f / 255), g * (1.0f / 255), b * (1.0f / 255));
+ constexpr float kToFloat = 1.0f / 255.0f;
+ return {
+ int_results.red * kToFloat,
+ int_results.green * kToFloat,
+ int_results.blue * kToFloat,
+ };
}
} // namespace fxge
diff --git a/core/fxge/dib/cfx_cmyk_to_srgb.h b/core/fxge/dib/cfx_cmyk_to_srgb.h
index e38e57c..3481154 100644
--- a/core/fxge/dib/cfx_cmyk_to_srgb.h
+++ b/core/fxge/dib/cfx_cmyk_to_srgb.h
@@ -9,18 +9,12 @@
#include <stdint.h>
-#include <tuple>
+#include "core/fxge/dib/fx_dib.h"
namespace fxge {
-std::tuple<float, float, float> AdobeCMYK_to_sRGB(float c,
- float m,
- float y,
- float k);
-std::tuple<uint8_t, uint8_t, uint8_t> AdobeCMYK_to_sRGB1(uint8_t c,
- uint8_t m,
- uint8_t y,
- uint8_t k);
+FX_RGB<float> AdobeCMYK_to_sRGB(float c, float m, float y, float k);
+FX_RGB<uint8_t> AdobeCMYK_to_sRGB1(uint8_t c, uint8_t m, uint8_t y, uint8_t k);
} // namespace fxge
diff --git a/core/fxge/dib/cfx_cmyk_to_srgb_unittest.cpp b/core/fxge/dib/cfx_cmyk_to_srgb_unittest.cpp
index d28f9cd..b2d5c5b 100644
--- a/core/fxge/dib/cfx_cmyk_to_srgb_unittest.cpp
+++ b/core/fxge/dib/cfx_cmyk_to_srgb_unittest.cpp
@@ -19,14 +19,12 @@
// range.
constexpr float kStartValue = 0.001f;
constexpr float kEndValue = 0.003f;
- float R = 0.0f;
- float G = 0.0f;
- float B = 0.0f;
+ FX_RGB<float> rgb;
// Iterate through floats by incrementing the representation, as discussed in
// https://randomascii.wordpress.com/2012/01/23/stupid-float-tricks-2/
for (Float_t f = kStartValue; f.f < kEndValue; f.i++) {
- std::tie(R, G, B) = AdobeCMYK_to_sRGB(f.f, f.f, f.f, f.f);
+ rgb = AdobeCMYK_to_sRGB(f.f, f.f, f.f, f.f);
}
// Check various other 'special' numbers.
- std::tie(R, G, B) = AdobeCMYK_to_sRGB(0.0f, 0.25f, 0.5f, 1.0f);
+ rgb = AdobeCMYK_to_sRGB(0.0f, 0.25f, 0.5f, 1.0f);
}