summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Pena <npm@chromium.org>2017-03-10 15:15:33 -0500
committerChromium commit bot <commit-bot@chromium.org>2017-03-10 20:46:14 +0000
commit6791295a4e8c99097e6d75870871e128284f8cb5 (patch)
treeb541a50b59773f34b227b2b459a52d643451289a
parent5c1961dfa0b1828eb2db38dc637548584c5cc704 (diff)
downloadpdfium-6791295a4e8c99097e6d75870871e128284f8cb5.tar.xz
Normalize channels when transforming CMYK to RGB
PDF spec, section 'DeviceCMYK Color Space' states that: 'Each component is specified by a number in the range 0.0 to 1.0' BUG=chromium:699459 Change-Id: Ie476bbe8740c7b1b33c80be3e3dc4207df5e6e28 Reviewed-on: https://pdfium-review.googlesource.com/2954 Commit-Queue: Nicolás Peña <npm@chromium.org> Reviewed-by: Tom Sepez <tsepez@chromium.org>
-rw-r--r--BUILD.gn1
-rw-r--r--core/fpdfapi/page/cpdf_devicecs_unittest.cpp115
-rw-r--r--core/fpdfapi/page/fpdf_page_colors.cpp12
3 files changed, 120 insertions, 8 deletions
diff --git a/BUILD.gn b/BUILD.gn
index 8656ee7fb5..2a5a6bd39d 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1745,6 +1745,7 @@ test("pdfium_unittests") {
"core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp",
"core/fpdfapi/font/fpdf_font_cid_unittest.cpp",
"core/fpdfapi/font/fpdf_font_unittest.cpp",
+ "core/fpdfapi/page/cpdf_devicecs_unittest.cpp",
"core/fpdfapi/page/cpdf_streamcontentparser_unittest.cpp",
"core/fpdfapi/page/cpdf_streamparser_unittest.cpp",
"core/fpdfapi/parser/cpdf_array_unittest.cpp",
diff --git a/core/fpdfapi/page/cpdf_devicecs_unittest.cpp b/core/fpdfapi/page/cpdf_devicecs_unittest.cpp
new file mode 100644
index 0000000000..287fc02fc4
--- /dev/null
+++ b/core/fpdfapi/page/cpdf_devicecs_unittest.cpp
@@ -0,0 +1,115 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "core/fpdfapi/page/pageint.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+TEST(CPDF_DeviceCSTest, GetRGBFromGray) {
+ FX_FLOAT R;
+ FX_FLOAT G;
+ FX_FLOAT B;
+ CPDF_DeviceCS deviceGray(nullptr, PDFCS_DEVICEGRAY);
+
+ // Test normal values. For gray, only first value from buf should be used.
+ FX_FLOAT buf[3] = {0.43f, 0.11f, 0.34f};
+ ASSERT_TRUE(deviceGray.GetRGB(buf, R, G, B));
+ EXPECT_EQ(0.43f, R);
+ EXPECT_EQ(0.43f, G);
+ EXPECT_EQ(0.43f, B);
+ buf[0] = 0.872f;
+ ASSERT_TRUE(deviceGray.GetRGB(buf, R, G, B));
+ EXPECT_EQ(0.872f, R);
+ EXPECT_EQ(0.872f, G);
+ EXPECT_EQ(0.872f, B);
+
+ // Test boundary values
+ buf[0] = {0.0f};
+ ASSERT_TRUE(deviceGray.GetRGB(buf, R, G, B));
+ EXPECT_EQ(0.0f, R);
+ EXPECT_EQ(0.0f, G);
+ EXPECT_EQ(0.0f, B);
+ buf[0] = 1.0f;
+ ASSERT_TRUE(deviceGray.GetRGB(buf, R, G, B));
+ EXPECT_EQ(1.0f, R);
+ EXPECT_EQ(1.0f, G);
+ EXPECT_EQ(1.0f, B);
+
+ // Test out of range values
+ buf[0] = -0.01f;
+ ASSERT_TRUE(deviceGray.GetRGB(buf, R, G, B));
+ EXPECT_EQ(0.0f, R);
+ EXPECT_EQ(0.0f, G);
+ EXPECT_EQ(0.0f, B);
+ buf[0] = 12.5f;
+ ASSERT_TRUE(deviceGray.GetRGB(buf, R, G, B));
+ EXPECT_EQ(1.0f, R);
+ EXPECT_EQ(1.0f, G);
+ EXPECT_EQ(1.0f, B);
+}
+
+TEST(CPDF_DeviceCSTest, GetRGBFromRGB) {
+ FX_FLOAT R;
+ FX_FLOAT G;
+ FX_FLOAT B;
+ CPDF_DeviceCS deviceRGB(nullptr, PDFCS_DEVICERGB);
+
+ // Test normal values
+ FX_FLOAT buf[3] = {0.13f, 1.0f, 0.652f};
+ ASSERT_TRUE(deviceRGB.GetRGB(buf, R, G, B));
+ EXPECT_EQ(0.13f, R);
+ EXPECT_EQ(1.0f, G);
+ EXPECT_EQ(0.652f, B);
+ buf[0] = 0.0f;
+ buf[1] = 0.52f;
+ buf[2] = 0.78f;
+ ASSERT_TRUE(deviceRGB.GetRGB(buf, R, G, B));
+ EXPECT_EQ(0.0f, R);
+ EXPECT_EQ(0.52f, G);
+ EXPECT_EQ(0.78f, B);
+
+ // Test out of range values
+ buf[0] = -10.5f;
+ buf[1] = 100.0f;
+ ASSERT_TRUE(deviceRGB.GetRGB(buf, R, G, B));
+ EXPECT_EQ(0.0f, R);
+ EXPECT_EQ(1.0f, G);
+ EXPECT_EQ(0.78f, B);
+}
+
+TEST(CPDF_DeviceCSTest, GetRGBFromCMYK) {
+ FX_FLOAT R;
+ FX_FLOAT G;
+ FX_FLOAT B;
+ CPDF_DeviceCS deviceCMYK(nullptr, PDFCS_DEVICECMYK);
+ // Use an error threshold because of the calculations used here.
+ FX_FLOAT eps = 1e-6f;
+ // Test normal values
+ FX_FLOAT buf[4] = {0.6f, 0.5f, 0.3f, 0.9f};
+ ASSERT_TRUE(deviceCMYK.GetRGB(buf, R, G, B));
+ EXPECT_TRUE(std::abs(0.0627451f - R) < eps);
+ EXPECT_TRUE(std::abs(0.0627451f - G) < eps);
+ EXPECT_TRUE(std::abs(0.105882f - B) < eps);
+ buf[0] = 0.15f;
+ buf[2] = 0.0f;
+ ASSERT_TRUE(deviceCMYK.GetRGB(buf, R, G, B));
+ EXPECT_TRUE(std::abs(0.2f - R) < eps);
+ EXPECT_TRUE(std::abs(0.0862745f - G) < eps);
+ EXPECT_TRUE(std::abs(0.164706f - B) < eps);
+ buf[2] = 1.0f;
+ buf[3] = 0.0f;
+ ASSERT_TRUE(deviceCMYK.GetRGB(buf, R, G, B));
+ EXPECT_TRUE(std::abs(0.850980f - R) < eps);
+ EXPECT_TRUE(std::abs(0.552941f - G) < eps);
+ EXPECT_TRUE(std::abs(0.156863f - B) < eps);
+
+ // Test out of range values
+ buf[2] = 1.5f;
+ buf[3] = -0.6f;
+ ASSERT_TRUE(deviceCMYK.GetRGB(buf, R, G, B));
+ EXPECT_TRUE(std::abs(0.850980f - R) < eps);
+ EXPECT_TRUE(std::abs(0.552941f - G) < eps);
+ EXPECT_TRUE(std::abs(0.156863f - B) < eps);
+}
diff --git a/core/fpdfapi/page/fpdf_page_colors.cpp b/core/fpdfapi/page/fpdf_page_colors.cpp
index 69129e4f2b..54b61df975 100644
--- a/core/fpdfapi/page/fpdf_page_colors.cpp
+++ b/core/fpdfapi/page/fpdf_page_colors.cpp
@@ -46,13 +46,7 @@ void sRGB_to_AdobeCMYK(FX_FLOAT R,
c = 1.0f - R;
m = 1.0f - G;
y = 1.0f - B;
- k = c;
- if (m < k) {
- k = m;
- }
- if (y < k) {
- k = y;
- }
+ k = std::min(c, std::min(m, y));
}
void ReverseRGB(uint8_t* pDestBuf, const uint8_t* pSrcBuf, int pixels) {
@@ -101,7 +95,9 @@ bool CPDF_DeviceCS::GetRGB(FX_FLOAT* pBuf,
G = 1.0f - std::min(1.0f, pBuf[1] + k);
B = 1.0f - std::min(1.0f, pBuf[2] + k);
} else {
- AdobeCMYK_to_sRGB(pBuf[0], pBuf[1], pBuf[2], pBuf[3], R, G, B);
+ AdobeCMYK_to_sRGB(NormalizeChannel(pBuf[0]), NormalizeChannel(pBuf[1]),
+ NormalizeChannel(pBuf[2]), NormalizeChannel(pBuf[3]),
+ R, G, B);
}
break;
default: