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 "core/fxcodec/codec/codec_int.h" | 7 #include "core/fxcodec/codec/codec_int.h" |
8 #include "core/fxcodec/fx_codec.h" | 8 #include "core/fxcodec/fx_codec.h" |
9 #include "third_party/lcms2-2.6/include/lcms2.h" | 9 #include "third_party/lcms2-2.6/include/lcms2.h" |
10 | 10 |
(...skipping 1645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1656 void AdobeCMYK_to_sRGB(FX_FLOAT c, | 1656 void AdobeCMYK_to_sRGB(FX_FLOAT c, |
1657 FX_FLOAT m, | 1657 FX_FLOAT m, |
1658 FX_FLOAT y, | 1658 FX_FLOAT y, |
1659 FX_FLOAT k, | 1659 FX_FLOAT k, |
1660 FX_FLOAT& R, | 1660 FX_FLOAT& R, |
1661 FX_FLOAT& G, | 1661 FX_FLOAT& G, |
1662 FX_FLOAT& B) { | 1662 FX_FLOAT& B) { |
1663 // Convert to uint8_t with round-to-nearest. Avoid using FXSYS_round because | 1663 // Convert to uint8_t with round-to-nearest. Avoid using FXSYS_round because |
1664 // it is incredibly expensive with VC++ (tested on VC++ 2015) because round() | 1664 // it is incredibly expensive with VC++ (tested on VC++ 2015) because round() |
1665 // is very expensive. | 1665 // is very expensive. |
1666 // Adding 0.5f and truncating can round the wrong direction in some edge | 1666 // The 'magic' value of 0.49999997f, the float that precedes 0.5f, was chosen |
1667 // cases but these do not matter in this context. For instance, the float that | 1667 // because it gives identical results to FXSYS_round(). Using the constant |
1668 // is one ULP (unit in the last place) before 0.5 should round to zero but | 1668 // 0.5f gives different results (1 instead of 0) for one value, 0.0019607842. |
1669 // this will round it to one. These edge cases are never hit in this function | 1669 // That value is close to the cusp but zero is the correct answer, and |
1670 // due to the very limited precision of the input integers. | 1670 // getting the same answer as before is desirable. |
1671 // This method also doesn't handle negative or extremely large numbers, but | 1671 // All floats from 0.0 to 1.0 were tested and now give the same results. |
1672 // those are not needed here. | 1672 const float rounding_offset = 0.49999997f; |
1673 uint8_t c1 = int(c * 255.f + 0.5f); | 1673 uint8_t c1 = int(c * 255.f + rounding_offset); |
1674 uint8_t m1 = int(m * 255.f + 0.5f); | 1674 uint8_t m1 = int(m * 255.f + rounding_offset); |
1675 uint8_t y1 = int(y * 255.f + 0.5f); | 1675 uint8_t y1 = int(y * 255.f + rounding_offset); |
1676 uint8_t k1 = int(k * 255.f + 0.5f); | 1676 uint8_t k1 = int(k * 255.f + rounding_offset); |
1677 | 1677 |
1678 ASSERT(c1 == FXSYS_round(c * 255)); | 1678 ASSERT(c1 == FXSYS_round(c * 255)); |
1679 ASSERT(m1 == FXSYS_round(m * 255)); | 1679 ASSERT(m1 == FXSYS_round(m * 255)); |
1680 ASSERT(y1 == FXSYS_round(y * 255)); | 1680 ASSERT(y1 == FXSYS_round(y * 255)); |
1681 ASSERT(k1 == FXSYS_round(k * 255)); | 1681 ASSERT(k1 == FXSYS_round(k * 255)); |
1682 | 1682 |
1683 uint8_t r, g, b; | 1683 uint8_t r, g, b; |
1684 AdobeCMYK_to_sRGB1(c1, m1, y1, k1, r, g, b); | 1684 AdobeCMYK_to_sRGB1(c1, m1, y1, k1, r, g, b); |
1685 // Multiply by a constant rather than dividing because division is much | 1685 // Multiply by a constant rather than dividing because division is much |
1686 // more expensive. | 1686 // more expensive. |
1687 R = r * (1.0f / 255); | 1687 R = r * (1.0f / 255); |
1688 G = g * (1.0f / 255); | 1688 G = g * (1.0f / 255); |
1689 B = b * (1.0f / 255); | 1689 B = b * (1.0f / 255); |
1690 } | 1690 } |
OLD | NEW |