1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Copyright 2014 PDFium Authors. All rights reserved.
2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Use of this source code is governed by a BSD-style license that can be
3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// found in the LICENSE file.
4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fpdfapi/fpdf_page.h"
8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fpdfapi/fpdf_module.h"
9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fxcodec/fx_codec.h"
10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "pageint.h"
11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include <limits.h>
12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid sRGB_to_AdobeCMYK(FX_FLOAT R, FX_FLOAT G, FX_FLOAT B, FX_FLOAT& c, FX_FLOAT& m, FX_FLOAT& y, FX_FLOAT& k)
13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    c = 1.0f - R;
15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m = 1.0f - G;
16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    y = 1.0f - B;
17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    k = c;
18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m < k) {
19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        k = m;
20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (y < k) {
22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        k = y;
23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
25ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_DeviceCS::CPDF_DeviceCS(int family)
26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Family = family;
28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Family == PDFCS_DEVICERGB) {
29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_nComponents = 3;
30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (m_Family == PDFCS_DEVICEGRAY) {
31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_nComponents = 1;
32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_nComponents = 4;
34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
36ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_DeviceCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const
37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Family == PDFCS_DEVICERGB) {
39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        R = pBuf[0];
40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (R < 0) {
41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            R = 0;
42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (R > 1) {
43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            R = 1;
44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        G = pBuf[1];
46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (G < 0) {
47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            G = 0;
48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (G > 1) {
49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            G = 1;
50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        B = pBuf[2];
52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (B < 0) {
53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            B = 0;
54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (B > 1) {
55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            B = 1;
56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (m_Family == PDFCS_DEVICEGRAY) {
58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        R = *pBuf;
59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (R < 0) {
60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            R = 0;
61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (R > 1) {
62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            R = 1;
63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        G = B = R;
65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (m_Family == PDFCS_DEVICECMYK) {
66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!m_dwStdConversion) {
67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            AdobeCMYK_to_sRGB(pBuf[0], pBuf[1], pBuf[2], pBuf[3], R, G, B);
68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_FLOAT k = pBuf[3];
70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            R = 1.0f - FX_MIN(1.0f, pBuf[0] + k);
71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            G = 1.0f - FX_MIN(1.0f, pBuf[1] + k);
72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            B = 1.0f - FX_MIN(1.0f, pBuf[2] + k);
73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ASSERT(m_Family == PDFCS_PATTERN);
76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        R = G = B = 0;
77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
81ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_DeviceCS::v_GetCMYK(FX_FLOAT* pBuf, FX_FLOAT& c, FX_FLOAT& m, FX_FLOAT& y, FX_FLOAT& k) const
82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Family != PDFCS_DEVICECMYK) {
84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    c = pBuf[0];
87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m = pBuf[1];
88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    y = pBuf[2];
89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    k = pBuf[3];
90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
92ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_DeviceCS::SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const
93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Family == PDFCS_DEVICERGB) {
95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBuf[0] = R;
96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBuf[1] = G;
97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBuf[2] = B;
98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (m_Family == PDFCS_DEVICEGRAY) {
100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (R == G && R == B) {
101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *pBuf = R;
102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return TRUE;
103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (m_Family == PDFCS_DEVICECMYK) {
107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        sRGB_to_AdobeCMYK(R, G, B, pBuf[0], pBuf[1], pBuf[2], pBuf[3]);
108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FALSE;
111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
112ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_DeviceCS::v_SetCMYK(FX_FLOAT* pBuf, FX_FLOAT c, FX_FLOAT m, FX_FLOAT y, FX_FLOAT k) const
113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Family == PDFCS_DEVICERGB) {
115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        AdobeCMYK_to_sRGB(c, m, y, k, pBuf[0], pBuf[1], pBuf[2]);
116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (m_Family == PDFCS_DEVICEGRAY) {
118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (m_Family == PDFCS_DEVICECMYK) {
120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBuf[0] = c;
121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBuf[1] = m;
122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBuf[2] = y;
123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBuf[3] = k;
124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FALSE;
127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic void ReverseRGB(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels)
129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pDestBuf == pSrcBuf)
131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int i = 0; i < pixels; i ++) {
132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE temp = pDestBuf[2];
133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pDestBuf[2] = pDestBuf[0];
134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pDestBuf[0] = temp;
135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pDestBuf += 3;
136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    else
138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int i = 0; i < pixels; i ++) {
139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *pDestBuf ++ = pSrcBuf[2];
140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *pDestBuf ++ = pSrcBuf[1];
141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *pDestBuf ++ = pSrcBuf[0];
142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pSrcBuf += 3;
143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_DeviceCS::TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask) const
146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (bTransMask && m_Family == PDFCS_DEVICECMYK) {
148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int i = 0; i < pixels; i ++) {
149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int k = 255 - pSrcBuf[3];
150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pDestBuf[0] = ((255 - pSrcBuf[0]) * k) / 255;
151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pDestBuf[1] = ((255 - pSrcBuf[1]) * k) / 255;
152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pDestBuf[2] = ((255 - pSrcBuf[2]) * k) / 255;
153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pDestBuf += 3;
154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pSrcBuf += 4;
155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Family == PDFCS_DEVICERGB) {
159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ReverseRGB(pDestBuf, pSrcBuf, pixels);
160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (m_Family == PDFCS_DEVICEGRAY) {
161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int i = 0; i < pixels; i ++) {
162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *pDestBuf ++ = pSrcBuf[i];
163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *pDestBuf ++ = pSrcBuf[i];
164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *pDestBuf ++ = pSrcBuf[i];
165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int i = 0; i < pixels; i ++) {
168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (!m_dwStdConversion) {
169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                AdobeCMYK_to_sRGB1(pSrcBuf[0], pSrcBuf[1], pSrcBuf[2], pSrcBuf[3], pDestBuf[2], pDestBuf[1], pDestBuf[0]);
170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE k = pSrcBuf[3];
172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pDestBuf[2] = 255 - FX_MIN(255, pSrcBuf[0] + k);
173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pDestBuf[1] = 255 - FX_MIN(255, pSrcBuf[1] + k);
174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pDestBuf[0] = 255 - FX_MIN(255, pSrcBuf[2] + k);
175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pSrcBuf += 4;
177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pDestBuf += 3;
178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst FX_BYTE g_sRGBSamples1[] = {
182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0,   3,   6,  10,  13,  15,  18,  20,  22,  23,  25,  27,  28,  30,  31,  32,
183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,  49,
184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    49,  50,  51,  52,  53,  53,  54,  55,  56,  56,  57,  58,  58,  59,  60,  61,
185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    61,  62,  62,  63,  64,  64,  65,  66,  66,  67,  67,  68,  68,  69,  70,  70,
186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    71,  71,  72,  72,  73,  73,  74,  74,  75,  76,  76,  77,  77,  78,  78,  79,
187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    79,  79,  80,  80,  81,  81,  82,  82,  83,  83,  84,  84,  85,  85,  85,  86,
188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    86,  87,  87,  88,  88,  88,  89,  89,  90,  90,  91,  91,  91,  92,  92,  93,
189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    93,  93,  94,  94,  95,  95,  95,  96,  96,  97,  97,  97,  98,  98,  98,  99,
190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    99,  99, 100, 100, 101, 101, 101, 102, 102, 102, 103, 103, 103, 104, 104, 104,
191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    105, 105, 106, 106, 106, 107, 107, 107, 108, 108, 108, 109, 109, 109, 110, 110,
192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    110, 110, 111, 111, 111, 112, 112, 112, 113, 113, 113, 114, 114, 114, 115, 115,
193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    115, 115, 116, 116, 116, 117, 117, 117, 118, 118, 118, 118, 119, 119, 119, 120,
194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst FX_BYTE g_sRGBSamples2[] = {
196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    120, 121, 122, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136,
197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 148, 149, 150, 151,
198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    152, 153, 154, 155, 155, 156, 157, 158, 159, 159, 160, 161, 162, 163, 163, 164,
199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    165, 166, 167, 167, 168, 169, 170, 170, 171, 172, 173, 173, 174, 175, 175, 176,
200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    177, 178, 178, 179, 180, 180, 181, 182, 182, 183, 184, 185, 185, 186, 187, 187,
201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    188, 189, 189, 190, 190, 191, 192, 192, 193, 194, 194, 195, 196, 196, 197, 197,
202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    198, 199, 199, 200, 200, 201, 202, 202, 203, 203, 204, 205, 205, 206, 206, 207,
203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    208, 208, 209, 209, 210, 210, 211, 212, 212, 213, 213, 214, 214, 215, 215, 216,
204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    216, 217, 218, 218, 219, 219, 220, 220, 221, 221, 222, 222, 223, 223, 224, 224,
205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    225, 226, 226, 227, 227, 228, 228, 229, 229, 230, 230, 231, 231, 232, 232, 233,
206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, 238, 239, 239, 240, 240,
207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 246, 247, 247, 248,
208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    248, 249, 249, 250, 250, 251, 251, 251, 252, 252, 253, 253, 254, 254, 255, 255,
209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic void XYZ_to_sRGB(FX_FLOAT X, FX_FLOAT Y, FX_FLOAT Z, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B)
211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT R1 = 3.2410f * X - 1.5374f * Y - 0.4986f * Z;
213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT G1 = -0.9692f * X + 1.8760f * Y + 0.0416f * Z;
214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT B1 =  0.0556f * X - 0.2040f * Y + 1.0570f * Z;
215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (R1 > 1) {
216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        R1 = 1;
217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (R1 < 0) {
219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        R1 = 0;
220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (G1 > 1) {
222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        G1 = 1;
223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (G1 < 0) {
225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        G1 = 0;
226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (B1 > 1) {
228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        B1 = 1;
229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (B1 < 0) {
231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        B1 = 0;
232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int scale = (int)(R1 * 1023);
234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (scale < 0) {
235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        scale = 0;
236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (scale < 192) {
238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        R = (g_sRGBSamples1[scale] / 255.0f);
239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        R = (g_sRGBSamples2[scale / 4 - 48] / 255.0f);
241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    scale = (int)(G1 * 1023);
243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (scale < 0) {
244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        scale = 0;
245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (scale < 192) {
247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        G = (g_sRGBSamples1[scale] / 255.0f);
248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        G = (g_sRGBSamples2[scale / 4 - 48] / 255.0f);
250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    scale = (int)(B1 * 1023);
252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (scale < 0) {
253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        scale = 0;
254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (scale < 192) {
256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        B = (g_sRGBSamples1[scale] / 255.0f);
257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        B = (g_sRGBSamples2[scale / 4 - 48] / 255.0f);
259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovclass CPDF_CalGray : public CPDF_ColorSpace
262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovpublic:
264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_CalGray();
265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual FX_BOOL		v_Load(CPDF_Document* pDoc, CPDF_Array* pArray);
266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual FX_BOOL		GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const;
267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual void		TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask = FALSE) const;
268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL				SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const;
269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT			m_WhitePoint[3];
270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT			m_BlackPoint[3];
271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT			m_Gamma;
272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
273ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_CalGray::CPDF_CalGray()
274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Family = PDFCS_CALGRAY;
276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_nComponents = 1;
277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
278ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_CalGray::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pDict = pArray->GetDict(1);
281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Array* pParam = pDict->GetArray(FX_BSTRC("WhitePoint"));
282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int i;
283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 0; i < 3; i ++) {
284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_WhitePoint[i] = pParam->GetNumber(i);
285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pParam = pDict->GetArray(FX_BSTRC("BlackPoint"));
287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 0; i < 3; i ++) {
288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_BlackPoint[i] = pParam ? pParam->GetNumber(i) : 0;
289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Gamma = pDict->GetNumber(FX_BSTRC("Gamma"));
291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Gamma == 0) {
292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Gamma = 1.0f;
293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
296ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_CalGray::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const
297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    R = G = B = *pBuf;
299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
301ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_CalGray::SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const
302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (R == G && R == B) {
304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *pBuf = R;
305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_CalGray::TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask) const
311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 0; i < pixels; i ++) {
313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *pDestBuf ++ = pSrcBuf[i];
314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *pDestBuf ++ = pSrcBuf[i];
315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *pDestBuf ++ = pSrcBuf[i];
316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovclass CPDF_CalRGB : public CPDF_ColorSpace
319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovpublic:
321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_CalRGB();
322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual FX_BOOL		v_Load(CPDF_Document* pDoc, CPDF_Array* pArray);
323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual FX_BOOL		GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const;
324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual void		TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask = FALSE) const;
325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL				SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const;
326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT			m_WhitePoint[3];
327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT			m_BlackPoint[3];
328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT			m_Gamma[3];
329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT			m_Matrix[9];
330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL				m_bGamma, m_bMatrix;
331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
332ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_CalRGB::CPDF_CalRGB()
333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Family = PDFCS_CALRGB;
335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_nComponents = 3;
336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
337ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_CalRGB::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pDict = pArray->GetDict(1);
340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Array* pParam = pDict->GetArray(FX_BSTRC("WhitePoint"));
341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int i;
342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 0; i < 3; i ++) {
343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_WhitePoint[i] = pParam->GetNumber(i);
344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pParam = pDict->GetArray(FX_BSTRC("BlackPoint"));
346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 0; i < 3; i ++) {
347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_BlackPoint[i] = pParam ? pParam->GetNumber(i) : 0;
348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pParam = pDict->GetArray(FX_BSTRC("Gamma"));
350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pParam) {
351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_bGamma = TRUE;
352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (i = 0; i < 3; i ++) {
353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_Gamma[i] = pParam->GetNumber(i);
354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_bGamma = FALSE;
357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pParam = pDict->GetArray(FX_BSTRC("Matrix"));
359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pParam) {
360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_bMatrix = TRUE;
361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (i = 0; i < 9; i ++) {
362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_Matrix[i] = pParam->GetNumber(i);
363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_bMatrix = FALSE;
366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
369ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_CalRGB::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const
370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT A_ = pBuf[0];
372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT B_ = pBuf[1];
373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT C_ = pBuf[2];
374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_bGamma) {
375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        A_ = (FX_FLOAT)FXSYS_pow(A_, m_Gamma[0]);
376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        B_ = (FX_FLOAT)FXSYS_pow(B_, m_Gamma[1]);
377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        C_ = (FX_FLOAT)FXSYS_pow(C_, m_Gamma[2]);
378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT X, Y, Z;
380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_bMatrix) {
381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        X = m_Matrix[0] * A_ + m_Matrix[3] * B_ + m_Matrix[6] * C_;
382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        Y = m_Matrix[1] * A_ + m_Matrix[4] * B_ + m_Matrix[7] * C_;
383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        Z = m_Matrix[2] * A_ + m_Matrix[5] * B_ + m_Matrix[8] * C_;
384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        X = A_;
386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        Y = B_;
387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        Z = C_;
388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    XYZ_to_sRGB(X, Y, Z, R, G, B);
390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
392ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_CalRGB::SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const
393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pBuf[0] = R;
395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pBuf[1] = G;
396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pBuf[2] = B;
397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_CalRGB::TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask) const
400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (bTransMask) {
402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_FLOAT Cal[3];
403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_FLOAT R, G, B;
404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for(int i = 0; i < pixels; i ++) {
405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            Cal[0] = ((FX_FLOAT)pSrcBuf[2]) / 255;
406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            Cal[1] = ((FX_FLOAT)pSrcBuf[1]) / 255;
407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            Cal[2] = ((FX_FLOAT)pSrcBuf[0]) / 255;
408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            GetRGB(Cal, R, G, B);
409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pDestBuf[0] = FXSYS_round(B * 255);
410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pDestBuf[1] = FXSYS_round(G * 255);
411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pDestBuf[2] = FXSYS_round(R * 255);
412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pSrcBuf += 3;
413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pDestBuf += 3;
414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ReverseRGB(pDestBuf, pSrcBuf, pixels);
417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovclass CPDF_LabCS : public CPDF_ColorSpace
419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovpublic:
421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_LabCS()
422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Family = PDFCS_LAB;
424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_nComponents = 3;
425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual FX_BOOL		v_Load(CPDF_Document* pDoc, CPDF_Array* pArray);
427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual void		GetDefaultValue(int iComponent, FX_FLOAT& value, FX_FLOAT& min, FX_FLOAT& max) const;
428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual FX_BOOL		GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const;
429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL		SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const;
430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual void		TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask = FALSE) const;
431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT	m_WhitePoint[3];
432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT	m_BlackPoint[3];
433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT	m_Ranges[4];
434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
435ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_LabCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pDict = pArray->GetDict(1);
438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Array* pParam = pDict->GetArray(FX_BSTRC("WhitePoint"));
439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int i;
440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 0; i < 3; i ++) {
441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_WhitePoint[i] = pParam->GetNumber(i);
442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pParam = pDict->GetArray(FX_BSTRC("BlackPoint"));
444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 0; i < 3; i ++) {
445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_BlackPoint[i] = pParam ? pParam->GetNumber(i) : 0;
446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pParam = pDict->GetArray(FX_BSTRC("Range"));
448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const FX_FLOAT def_ranges[4] = { -100 * 1.0f, 100 * 1.0f, -100 * 1.0f, 100 * 1.0f};
449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 0; i < 4; i ++) {
450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Ranges[i] = pParam ? pParam->GetNumber(i) : def_ranges[i];
451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_LabCS::GetDefaultValue(int iComponent, FX_FLOAT& value, FX_FLOAT& min, FX_FLOAT& max) const
455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    value = 0;
457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (iComponent == 0) {
458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        min = 0;
459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        max = 100 * 1.0f;
460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        min = m_Ranges[iComponent * 2 - 2];
462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        max = m_Ranges[iComponent * 2 - 1];
463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (value < min) {
464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            value = min;
465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (value > max) {
466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            value = max;
467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
470ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_LabCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const
471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT Lstar = pBuf[0];
473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT astar = pBuf[1];
474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT bstar = pBuf[2];
475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT M = (Lstar + 16.0f) / 116.0f;
476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT L = M + astar / 500.0f;
477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT N = M - bstar / 200.0f;
478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT X, Y, Z;
479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (L < 0.2069f) {
480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        X = 0.957f * 0.12842f * (L - 0.1379f);
481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        X = 0.957f * L * L * L;
483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (M < 0.2069f) {
485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        Y = 0.12842f * (M - 0.1379f);
486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        Y = M * M * M;
488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (N < 0.2069f) {
490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        Z = 1.0889f * 0.12842f * (N - 0.1379f);
491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        Z = 1.0889f * N * N * N;
493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    XYZ_to_sRGB(X, Y, Z, R, G, B);
495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
497ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_LabCS::SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const
498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FALSE;
500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_LabCS::TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask) const
502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 0; i < pixels; i ++) {
504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_FLOAT lab[3];
505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_FLOAT R, G, B;
506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        lab[0] = (pSrcBuf[0] * 100 / 255.0f);
507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        lab[1] = (FX_FLOAT)(pSrcBuf[1] - 128);
508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        lab[2] = (FX_FLOAT)(pSrcBuf[2] - 128);
509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        GetRGB(lab, R, G, B);
510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pDestBuf[0] = (FX_INT32)(B * 255);
511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pDestBuf[1] = (FX_INT32)(G * 255);
512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pDestBuf[2] = (FX_INT32)(R * 255);
513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pDestBuf += 3;
514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pSrcBuf += 3;
515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
517ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_IccProfile::CPDF_IccProfile(FX_LPCBYTE pData, FX_DWORD dwSize, int nComponents)
518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bsRGB = nComponents == 3 && dwSize == 3144 && FXSYS_memcmp32(pData + 0x190, "sRGB IEC61966-2.1", 17) == 0;
520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pTransform = NULL;
521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_bsRGB && CPDF_ModuleMgr::Get()->GetIccModule()) {
522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pTransform = CPDF_ModuleMgr::Get()->GetIccModule()->CreateTransform_sRGB(pData, dwSize, nComponents);
523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
525ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_IccProfile::~CPDF_IccProfile()
526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pTransform) {
528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_ModuleMgr::Get()->GetIccModule()->DestroyTransform(m_pTransform);
529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovclass CPDF_ICCBasedCS : public CPDF_ColorSpace
532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovpublic:
534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_ICCBasedCS();
535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual ~CPDF_ICCBasedCS();
536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual FX_BOOL		v_Load(CPDF_Document* pDoc, CPDF_Array* pArray);
537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    void				GetDefaultValue(int i, FX_FLOAT& min, FX_FLOAT& max) const
538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        min = m_pRanges[i * 2];
540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        max = m_pRanges[i * 2 + 1];
541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual FX_BOOL		GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const;
543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL				v_GetCMYK(FX_FLOAT* pBuf, FX_FLOAT& c, FX_FLOAT& m, FX_FLOAT& y, FX_FLOAT& k) const;
544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL				SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const;
545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual void		EnableStdConversion(FX_BOOL bEnabled);
546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual void		TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask = FALSE) const;
547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT*		m_pRanges;
548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_IccProfile*	m_pProfile;
549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_ColorSpace*	m_pAlterCS;
550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPBYTE			m_pCache;
551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL				m_bOwn;
552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
553ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_ICCBasedCS::CPDF_ICCBasedCS()
554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pAlterCS = NULL;
556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pProfile = NULL;
557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Family = PDFCS_ICCBASED;
558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pCache = NULL;
559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pRanges = NULL;
560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bOwn = FALSE;
561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
562ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_ICCBasedCS::~CPDF_ICCBasedCS()
563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pCache) {
565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Free(m_pCache);
566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pRanges) {
568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Free(m_pRanges);
569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pAlterCS && m_bOwn) {
571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pAlterCS->ReleaseCS();
572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pProfile && m_pDocument) {
574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pDocument->GetPageData()->ReleaseIccProfile(NULL, m_pProfile);
575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
577ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_ICCBasedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Stream* pStream = pArray->GetStream(1);
580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pStream == NULL) {
581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_nComponents = pStream->GetDict()->GetInteger(FX_BSTRC("N"));
584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_nComponents < 0 || m_nComponents > (1 << 16)) {
585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Array* pRanges = pStream->GetDict()->GetArray(FX_BSTRC("Range"));
588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pRanges = FX_Alloc(FX_FLOAT, m_nComponents * 2);
589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 0; i < m_nComponents * 2; i ++) {
590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pRanges) {
591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pRanges[i] = pRanges->GetNumber(i);
592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (i % 2) {
593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pRanges[i] = 1.0f;
594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pRanges[i] = 0;
596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pProfile = pDoc->LoadIccProfile(pStream, m_nComponents);
599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_pProfile) {
600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pProfile->m_pTransform == NULL) {
603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Object* pAlterCSObj = pStream->GetDict()->GetElementValue(FX_BSTRC("Alternate"));
604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pAlterCSObj) {
605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CPDF_ColorSpace* alter_cs = CPDF_ColorSpace::Load(pDoc, pAlterCSObj);
606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (alter_cs) {
607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (alter_cs->CountComponents() > m_nComponents) {
608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    alter_cs->ReleaseCS();
609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else {
610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    m_pAlterCS = alter_cs;
611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    m_bOwn = TRUE;
612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!m_pAlterCS) {
616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (m_nComponents == 3) {
617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_pAlterCS = GetStockCS(PDFCS_DEVICERGB);
618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else if (m_nComponents == 4) {
619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_pAlterCS = GetStockCS(PDFCS_DEVICECMYK);
620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_pAlterCS = GetStockCS(PDFCS_DEVICEGRAY);
622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
627ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_ICCBasedCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const
628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pProfile && m_pProfile->m_bsRGB) {
630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        R = pBuf[0];
631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        G = pBuf[1];
632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        B = pBuf[2];
633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ICodec_IccModule *pIccModule = CPDF_ModuleMgr::Get()->GetIccModule();
636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pProfile->m_pTransform == NULL || pIccModule == NULL) {
637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_pAlterCS) {
638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pAlterCS->GetRGB(pBuf, R, G, B);
639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            R = G = B = 0.0f;
641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT rgb[3];
645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pIccModule->Translate(m_pProfile->m_pTransform, pBuf, rgb);
646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    R = rgb[0];
647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    G = rgb[1];
648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    B = rgb[2];
649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
651ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_ICCBasedCS::v_GetCMYK(FX_FLOAT* pBuf, FX_FLOAT& c, FX_FLOAT& m, FX_FLOAT& y, FX_FLOAT& k) const
652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_nComponents != 4) {
654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    c = pBuf[0];
657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m = pBuf[1];
658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    y = pBuf[2];
659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    k = pBuf[3];
660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
662ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_ICCBasedCS::SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const
663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FALSE;
665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_ICCBasedCS::EnableStdConversion(FX_BOOL bEnabled)
667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_ColorSpace::EnableStdConversion(bEnabled);
669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pAlterCS) {
670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pAlterCS->EnableStdConversion(bEnabled);
671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_ICCBasedCS::TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask) const
674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pProfile->m_bsRGB) {
676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ReverseRGB(pDestBuf, pSrcBuf, pixels);
677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (m_pProfile->m_pTransform) {
678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int nMaxColors = 1;
679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int i = 0; i < m_nComponents; i ++) {
680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            nMaxColors *= 52;
681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_nComponents > 3 || image_width * image_height < nMaxColors * 3 / 2) {
683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CPDF_ModuleMgr::Get()->GetIccModule()->TranslateScanline(m_pProfile->m_pTransform, pDestBuf, pSrcBuf, pixels);
684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (m_pCache == NULL) {
686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                ((CPDF_ICCBasedCS*)this)->m_pCache = FX_Alloc(FX_BYTE, nMaxColors * 3);
687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_LPBYTE temp_src = FX_Alloc(FX_BYTE, nMaxColors * m_nComponents);
688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_LPBYTE pSrc = temp_src;
689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (int i = 0; i < nMaxColors; i ++) {
690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FX_DWORD color = i;
691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FX_DWORD order = nMaxColors / 52;
692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    for (int c = 0; c < m_nComponents; c ++) {
693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *pSrc++ = (FX_BYTE)(color / order * 5);
694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        color %= order;
695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        order /= 52;
696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                CPDF_ModuleMgr::Get()->GetIccModule()->TranslateScanline(m_pProfile->m_pTransform, m_pCache, temp_src, nMaxColors);
699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_Free(temp_src);
700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int i = 0; i < pixels; i ++) {
702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int index = 0;
703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (int c = 0; c < m_nComponents; c ++) {
704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    index = index * 52 + (*pSrcBuf) / 5;
705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    pSrcBuf ++;
706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                index *= 3;
708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *pDestBuf++ = m_pCache[index];
709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *pDestBuf++ = m_pCache[index + 1];
710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *pDestBuf++ = m_pCache[index + 2];
711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (m_pAlterCS) {
714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pAlterCS->TranslateImageLine(pDestBuf, pSrcBuf, pixels, image_width, image_height);
715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovclass CPDF_IndexedCS : public CPDF_ColorSpace
718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovpublic:
720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_IndexedCS();
721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual ~CPDF_IndexedCS();
722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual FX_BOOL		v_Load(CPDF_Document* pDoc, CPDF_Array* pArray);
723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    void				GetDefaultValue(int iComponent, FX_FLOAT& min, FX_FLOAT& max) const
724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        min = 0;
726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        max = (FX_FLOAT)m_MaxIndex;
727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual FX_BOOL		GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const;
729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual CPDF_ColorSpace*	GetBaseCS() const
730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return m_pBaseCS;
732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual void		EnableStdConversion(FX_BOOL bEnabled);
734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_ColorSpace*	m_pBaseCS;
735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int					m_nBaseComponents;
736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int					m_MaxIndex;
737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_ByteString		m_Table;
738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT*		m_pCompMinMax;
739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
740ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_IndexedCS::CPDF_IndexedCS()
741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pBaseCS = NULL;
743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Family = PDFCS_INDEXED;
744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_nComponents = 1;
745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pCompMinMax = NULL;
746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
747ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_IndexedCS::~CPDF_IndexedCS()
748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pCompMinMax) {
750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Free(m_pCompMinMax);
751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_ColorSpace* pCS = m_pBaseCS;
753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pCS && m_pDocument) {
754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray());
755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
757ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_IndexedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pArray->GetCount() < 4) {
760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Object* pBaseObj = pArray->GetElementValue(1);
763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pBaseObj == m_pArray) {
764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_DocPageData* pDocPageData = pDoc->GetPageData();
767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pBaseCS = pDocPageData->GetColorSpace(pBaseObj, NULL);
768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pBaseCS == NULL) {
769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_nBaseComponents = m_pBaseCS->CountComponents();
772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pCompMinMax = FX_Alloc(FX_FLOAT, m_nBaseComponents * 2);
773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT defvalue;
774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 0; i < m_nBaseComponents; i ++) {
775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pBaseCS->GetDefaultValue(i, defvalue, m_pCompMinMax[i * 2], m_pCompMinMax[i * 2 + 1]);
776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCompMinMax[i * 2 + 1] -= m_pCompMinMax[i * 2];
777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_MaxIndex = pArray->GetInteger(2);
779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Object* pTableObj = pArray->GetElementValue(3);
780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pTableObj == NULL) {
781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPCBYTE pTable = NULL;
784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD size = 0;
785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_StreamAcc* pStreamAcc = NULL;
786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pTableObj->GetType() == PDFOBJ_STRING) {
787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Table = ((CPDF_String*)pTableObj)->GetString();
788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (pTableObj->GetType() == PDFOBJ_STREAM) {
789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_StreamAcc acc;
790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        acc.LoadAllData((CPDF_Stream*)pTableObj, FALSE);
791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Table = CFX_ByteStringC(acc.GetData(), acc.GetSize());
792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
795ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_IndexedCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const
796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int index = (FX_INT32)(*pBuf);
798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (index < 0 || index > m_MaxIndex) {
799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_nBaseComponents) {
802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (index == INT_MAX || (index + 1) > INT_MAX / m_nBaseComponents ||
803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                (index + 1)*m_nBaseComponents > (int)m_Table.GetLength()) {
804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            R = G = B = 0;
805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_FixedBufGrow<FX_FLOAT, 16> Comps(m_nBaseComponents);
809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT* comps = Comps;
810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPCBYTE pTable = m_Table;
811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 0; i < m_nBaseComponents; i ++) {
812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        comps[i] = m_pCompMinMax[i * 2] + m_pCompMinMax[i * 2 + 1] * pTable[index * m_nBaseComponents + i] / 255;
813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pBaseCS->GetRGB(comps, R, G, B);
815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_IndexedCS::EnableStdConversion(FX_BOOL bEnabled)
818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_ColorSpace::EnableStdConversion(bEnabled);
820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pBaseCS) {
821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pBaseCS->EnableStdConversion(bEnabled);
822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define MAX_PATTERN_COLORCOMPS	16
825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef struct _PatternValue {
826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Pattern*	m_pPattern;
827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int				m_nComps;
828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT		m_Comps[MAX_PATTERN_COLORCOMPS];
829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} PatternValue;
830ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_PatternCS::CPDF_PatternCS()
831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Family = PDFCS_PATTERN;
833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pBaseCS = NULL;
834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_nComponents = 1;
835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
836ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_PatternCS::~CPDF_PatternCS()
837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_ColorSpace* pCS = m_pBaseCS;
839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pCS && m_pDocument) {
840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray());
841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
843ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_PatternCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Object* pBaseCS = pArray->GetElementValue(1);
846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pBaseCS == m_pArray) {
847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_DocPageData* pDocPageData = pDoc->GetPageData();
850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pBaseCS = pDocPageData->GetColorSpace(pBaseCS, NULL);
851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pBaseCS) {
852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_nComponents = m_pBaseCS->CountComponents() + 1;
853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_pBaseCS->CountComponents() > MAX_PATTERN_COLORCOMPS) {
854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_nComponents = 1;
858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
861ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_PatternCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const
862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pBaseCS) {
864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        PatternValue* pvalue = (PatternValue*)pBuf;
865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pBaseCS->GetRGB(pvalue->m_Comps, R, G, B);
866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    R = G = B = 0.75f;
869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FALSE;
870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovclass CPDF_SeparationCS : public CPDF_ColorSpace
872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovpublic:
874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_SeparationCS();
875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual ~CPDF_SeparationCS();
876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual void		GetDefaultValue(int iComponent, FX_FLOAT& value, FX_FLOAT& min, FX_FLOAT& max) const
877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        value = 1.0f;
879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        min = 0;
880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        max = 1.0f;
881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual FX_BOOL		v_Load(CPDF_Document* pDoc, CPDF_Array* pArray);
883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual FX_BOOL		GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const;
884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual void		EnableStdConversion(FX_BOOL bEnabled);
885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_ColorSpace*	m_pAltCS;
886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Function*		m_pFunc;
887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    enum {None, All, Colorant}	m_Type;
888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
889ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_SeparationCS::CPDF_SeparationCS()
890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Family = PDFCS_SEPARATION;
892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pAltCS = NULL;
893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pFunc = NULL;
894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_nComponents = 1;
895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
896ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_SeparationCS::~CPDF_SeparationCS()
897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pAltCS) {
899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pAltCS->ReleaseCS();
900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pFunc) {
902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete m_pFunc;
903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
905ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_SeparationCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_ByteString name = pArray->GetString(1);
908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (name == FX_BSTRC("None")) {
909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Type = None;
910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Type = Colorant;
912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Object* pAltCS = pArray->GetElementValue(2);
913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pAltCS == m_pArray) {
914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pAltCS = Load(pDoc, pAltCS);
917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Object* pFuncObj = pArray->GetElementValue(3);
918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pFuncObj && pFuncObj->GetType() != PDFOBJ_NAME) {
919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pFunc = CPDF_Function::Load(pFuncObj);
920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_pFunc && m_pAltCS && m_pFunc->CountOutputs() < m_pAltCS->CountComponents()) {
922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            delete m_pFunc;
923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pFunc = NULL;
924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
928ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_SeparationCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const
929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Type == None) {
931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pFunc == NULL) {
934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_pAltCS == NULL) {
935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int nComps = m_pAltCS->CountComponents();
938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFX_FixedBufGrow<FX_FLOAT, 16> results(nComps);
939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int i = 0; i < nComps; i ++) {
940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            results[i] = *pBuf;
941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pAltCS->GetRGB(results, R, G, B);
943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_FixedBufGrow<FX_FLOAT, 16> results(m_pFunc->CountOutputs());
946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int nresults;
947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pFunc->Call(pBuf, 1, results, nresults);
948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (nresults == 0) {
949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pAltCS) {
952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pAltCS->GetRGB(results, R, G, B);
953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        R = G = B = 0;
956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_SeparationCS::EnableStdConversion(FX_BOOL bEnabled)
960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_ColorSpace::EnableStdConversion(bEnabled);
962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pAltCS) {
963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pAltCS->EnableStdConversion(bEnabled);
964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovclass CPDF_DeviceNCS : public CPDF_ColorSpace
967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovpublic:
969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_DeviceNCS();
970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual ~CPDF_DeviceNCS();
971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual void		GetDefaultValue(int iComponent, FX_FLOAT& value, FX_FLOAT& min, FX_FLOAT& max) const
972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        value = 1.0f;
974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        min = 0;
975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        max = 1.0f;
976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual FX_BOOL	v_Load(CPDF_Document* pDoc, CPDF_Array* pArray);
978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual FX_BOOL	GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const;
979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual void	EnableStdConversion(FX_BOOL bEnabled);
980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_ColorSpace*	m_pAltCS;
981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Function*		m_pFunc;
982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
983ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_DeviceNCS::CPDF_DeviceNCS()
984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Family = PDFCS_DEVICEN;
986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pAltCS = NULL;
987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pFunc = NULL;
988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
989ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_DeviceNCS::~CPDF_DeviceNCS()
990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pFunc) {
992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete m_pFunc;
993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pAltCS) {
995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pAltCS->ReleaseCS();
996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
998ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_DeviceNCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Object* pObj = pArray->GetElementValue(1);
1001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!pObj) {
1002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
1003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pObj->GetType() != PDFOBJ_ARRAY) {
1005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
1006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_nComponents = ((CPDF_Array*)pObj)->GetCount();
1008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Object* pAltCS = pArray->GetElementValue(2);
1009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!pAltCS || pAltCS == m_pArray) {
1010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
1011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pAltCS = Load(pDoc, pAltCS);
1013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pFunc = CPDF_Function::Load(pArray->GetElementValue(3));
1014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pAltCS == NULL || m_pFunc == NULL) {
1015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
1016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pFunc->CountOutputs() < m_pAltCS->CountComponents()) {
1018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
1019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
1021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1022ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_DeviceNCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const
1023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pFunc == NULL) {
1025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
1026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_FixedBufGrow<FX_FLOAT, 16> results(m_pFunc->CountOutputs());
1028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int nresults;
1029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pFunc->Call(pBuf, m_nComponents, results, nresults);
1030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (nresults == 0) {
1031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
1032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pAltCS->GetRGB(results, R, G, B);
1034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
1035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_DeviceNCS::EnableStdConversion(FX_BOOL bEnabled)
1037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_ColorSpace::EnableStdConversion(bEnabled);
1039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pAltCS) {
1040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pAltCS->EnableStdConversion(bEnabled);
1041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1043ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_ColorSpace* CPDF_ColorSpace::GetStockCS(int family)
1044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return CPDF_ModuleMgr::Get()->GetPageModule()->GetStockCS(family);;
1046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1047ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_ColorSpace* _CSFromName(const CFX_ByteString& name)
1048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (name == FX_BSTRC("DeviceRGB") || name == FX_BSTRC("RGB")) {
1050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB);
1051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (name == FX_BSTRC("DeviceGray") || name == FX_BSTRC("G")) {
1053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY);
1054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (name == FX_BSTRC("DeviceCMYK") || name == FX_BSTRC("CMYK")) {
1056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK);
1057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (name == FX_BSTRC("Pattern")) {
1059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN);
1060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return NULL;
1062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1063ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_ColorSpace* CPDF_ColorSpace::Load(CPDF_Document* pDoc, CPDF_Object* pObj)
1064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pObj == NULL) {
1066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
1067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pObj->GetType() == PDFOBJ_NAME) {
1069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return _CSFromName(pObj->GetString());
1070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pObj->GetType() == PDFOBJ_STREAM) {
1072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Dictionary *pDict = ((CPDF_Stream *)pObj)->GetDict();
1073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!pDict) {
1074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return NULL;
1075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_ColorSpace *pRet = NULL;
1077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_POSITION pos = pDict->GetStartPos();
1078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        while (pos) {
1079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CFX_ByteString bsKey;
1080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CPDF_Object *pValue = pDict->GetNextElement(pos, bsKey);
1081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (pValue->GetType() == PDFOBJ_NAME) {
1082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pRet = _CSFromName(pValue->GetString());
1083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (pRet) {
1085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return pRet;
1086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
1089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pObj->GetType() != PDFOBJ_ARRAY) {
1091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
1092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1093ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Array* pArray = (CPDF_Array*)pObj;
1094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pArray->GetCount() == 0) {
1095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
1096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_ByteString familyname = pArray->GetElementValue(0)->GetString();
1098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pArray->GetCount() == 1) {
1099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return _CSFromName(familyname);
1100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_ColorSpace* pCS = NULL;
1102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD id = familyname.GetID();
1103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (id == FXBSTR_ID('C', 'a', 'l', 'G')) {
1104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pCS = FX_NEW CPDF_CalGray();
1105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (id == FXBSTR_ID('C', 'a', 'l', 'R')) {
1106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pCS = FX_NEW CPDF_CalRGB();
1107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (id == FXBSTR_ID('L', 'a', 'b', 0)) {
1108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pCS = FX_NEW CPDF_LabCS();
1109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (id == FXBSTR_ID('I', 'C', 'C', 'B')) {
1110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pCS = FX_NEW CPDF_ICCBasedCS();
1111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (id == FXBSTR_ID('I', 'n', 'd', 'e') || id == FXBSTR_ID('I', 0, 0, 0)) {
1112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pCS = FX_NEW CPDF_IndexedCS();
1113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (id == FXBSTR_ID('S', 'e', 'p', 'a')) {
1114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pCS = FX_NEW CPDF_SeparationCS();
1115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (id == FXBSTR_ID('D', 'e', 'v', 'i')) {
1116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pCS = FX_NEW CPDF_DeviceNCS();
1117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (id == FXBSTR_ID('P', 'a', 't', 't')) {
1118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pCS = FX_NEW CPDF_PatternCS();
1119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
1120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
1121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pCS->m_pDocument = pDoc;
1123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pCS->m_pArray = pArray;
1124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!pCS->v_Load(pDoc, pArray)) {
1125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pCS->ReleaseCS();
1126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
1127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pCS;
1129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1130ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_ColorSpace::CPDF_ColorSpace()
1131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Family = 0;
1133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pArray = NULL;
1134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_dwStdConversion = 0;
1135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pDocument = NULL;
1136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_ColorSpace::ReleaseCS()
1138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (this == GetStockCS(PDFCS_DEVICERGB)) {
1140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
1141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (this == GetStockCS(PDFCS_DEVICEGRAY)) {
1143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
1144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (this == GetStockCS(PDFCS_DEVICECMYK)) {
1146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
1147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (this == GetStockCS(PDFCS_PATTERN)) {
1149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
1150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    delete this;
1152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint CPDF_ColorSpace::GetBufSize() const
1154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Family == PDFCS_PATTERN) {
1156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return sizeof(PatternValue);
1157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return m_nComponents * sizeof(FX_FLOAT);
1159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1160ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_FLOAT* CPDF_ColorSpace::CreateBuf()
1161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int size = GetBufSize();
1163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BYTE* pBuf = FX_Alloc(FX_BYTE, size);
1164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_memset32(pBuf, 0, size);
1165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return (FX_FLOAT*)pBuf;
1166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1167ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_ColorSpace::sRGB() const
1168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Family == PDFCS_DEVICERGB) {
1170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
1171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Family != PDFCS_ICCBASED) {
1173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
1174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_ICCBasedCS* pCS = (CPDF_ICCBasedCS*)this;
1176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pCS->m_pProfile->m_bsRGB;
1177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1178ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_ColorSpace::GetCMYK(FX_FLOAT* pBuf, FX_FLOAT& c, FX_FLOAT& m, FX_FLOAT& y, FX_FLOAT& k) const
1179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (v_GetCMYK(pBuf, c, m, y, k)) {
1181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
1182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT R, G, B;
1184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!GetRGB(pBuf, R, G, B)) {
1185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
1186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    sRGB_to_AdobeCMYK(R, G, B, c, m, y, k);
1188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
1189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1190ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_ColorSpace::SetCMYK(FX_FLOAT* pBuf, FX_FLOAT c, FX_FLOAT m, FX_FLOAT y, FX_FLOAT k) const
1191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (v_SetCMYK(pBuf, c, m, y, k)) {
1193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
1194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT R, G, B;
1196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    AdobeCMYK_to_sRGB(c, m, y, k, R, G, B);
1197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return SetRGB(pBuf, R, G, B);
1198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_ColorSpace::GetDefaultColor(FX_FLOAT* buf) const
1200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (buf == NULL || m_Family == PDFCS_PATTERN) {
1202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
1203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT min, max;
1205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 0; i < m_nComponents; i ++) {
1206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        GetDefaultValue(i, buf[i], min, max);
1207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint CPDF_ColorSpace::GetMaxIndex() const
1210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Family != PDFCS_INDEXED) {
1212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return 0;
1213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_IndexedCS* pCS = (CPDF_IndexedCS*)this;
1215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pCS->m_MaxIndex;
1216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_ColorSpace::TranslateImageLine(FX_LPBYTE dest_buf, FX_LPCBYTE src_buf, int pixels, int image_width, int image_height, FX_BOOL bTransMask) const
1218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_FixedBufGrow<FX_FLOAT, 16> srcbuf(m_nComponents);
1220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT* src = srcbuf;
1221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT R, G, B;
1222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 0; i < pixels; i ++) {
1223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int j = 0; j < m_nComponents; j ++)
1224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (m_Family == PDFCS_INDEXED) {
1225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src[j] = (FX_FLOAT)(*src_buf ++);
1226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
1227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src[j] = (FX_FLOAT)(*src_buf ++) / 255;
1228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        GetRGB(src, R, G, B);
1230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *dest_buf ++ = (FX_INT32)(B * 255);
1231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *dest_buf ++ = (FX_INT32)(G * 255);
1232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *dest_buf ++ = (FX_INT32)(R * 255);
1233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_ColorSpace::EnableStdConversion(FX_BOOL bEnabled)
1236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (bEnabled) {
1238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_dwStdConversion ++;
1239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (m_dwStdConversion) {
1240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_dwStdConversion --;
1241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1243ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_Color::CPDF_Color(int family)
1244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pCS = CPDF_ColorSpace::GetStockCS(family);
1246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int nComps = 3;
1247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (family == PDFCS_DEVICEGRAY) {
1248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        nComps = 1;
1249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (family == PDFCS_DEVICECMYK) {
1250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        nComps = 4;
1251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pBuffer = FX_Alloc(FX_FLOAT, nComps);
1253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 0; i < nComps; i ++) {
1254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pBuffer[i] = 0;
1255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1257ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_Color::~CPDF_Color()
1258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ReleaseBuffer();
1260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ReleaseColorSpace();
1261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_Color::ReleaseBuffer()
1263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_pBuffer) {
1265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
1266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pCS->GetFamily() == PDFCS_PATTERN) {
1268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        PatternValue* pvalue = (PatternValue*)m_pBuffer;
1269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Pattern* pPattern = pvalue->m_pPattern;
1270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pPattern && pPattern->m_pDocument) {
1271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pPattern->m_pDocument->GetPageData()->ReleasePattern(pPattern->m_pPatternObj);
1272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_Free(m_pBuffer);
1275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pBuffer = NULL;
1276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_Color::ReleaseColorSpace()
1278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pCS && m_pCS->m_pDocument && m_pCS->GetArray()) {
1280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCS->m_pDocument->GetPageData()->ReleaseColorSpace(m_pCS->GetArray());
1281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCS = NULL;
1282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_Color::SetColorSpace(CPDF_ColorSpace* pCS)
1285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pCS == pCS) {
1287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_pBuffer == NULL) {
1288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pBuffer = pCS->CreateBuf();
1289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ReleaseColorSpace();
1291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCS = pCS;
1292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
1293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ReleaseBuffer();
1295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ReleaseColorSpace();
1296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pCS = pCS;
1297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pCS) {
1298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pBuffer = pCS->CreateBuf();
1299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pCS->GetDefaultColor(m_pBuffer);
1300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_Color::SetValue(FX_FLOAT* comps)
1303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pBuffer == NULL) {
1305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
1306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pCS->GetFamily() != PDFCS_PATTERN) {
1308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FXSYS_memcpy32(m_pBuffer, comps, m_pCS->CountComponents() * sizeof(FX_FLOAT));
1309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_Color::SetValue(CPDF_Pattern* pPattern, FX_FLOAT* comps, int ncomps)
1312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (ncomps > MAX_PATTERN_COLORCOMPS) {
1314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
1315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pCS == NULL || m_pCS->GetFamily() != PDFCS_PATTERN) {
1317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_pBuffer) {
1318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_Free(m_pBuffer);
1319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCS = CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN);
1321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pBuffer = m_pCS->CreateBuf();
1322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_DocPageData* pDocPageData = NULL;
1324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    PatternValue* pvalue = (PatternValue*)m_pBuffer;
1325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pvalue->m_pPattern && pvalue->m_pPattern->m_pDocument) {
1326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pDocPageData = pvalue->m_pPattern->m_pDocument->GetPageData();
1327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pDocPageData->ReleasePattern(pvalue->m_pPattern->m_pPatternObj);
1328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pvalue->m_nComps = ncomps;
1330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pvalue->m_pPattern = pPattern;
1331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (ncomps) {
1332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FXSYS_memcpy32(pvalue->m_Comps, comps, ncomps * sizeof(FX_FLOAT));
1333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_Color::Copy(const CPDF_Color* pSrc)
1336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ReleaseBuffer();
1338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ReleaseColorSpace();
1339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pCS = pSrc->m_pCS;
1340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pCS && m_pCS->m_pDocument) {
1341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Array* pArray = m_pCS->GetArray();
1342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pArray) {
1343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pCS = m_pCS->m_pDocument->GetPageData()->GetCopiedColorSpace(pArray);
1344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pCS == NULL) {
1347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
1348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pBuffer = m_pCS->CreateBuf();
1350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_memcpy32(m_pBuffer, pSrc->m_pBuffer, m_pCS->GetBufSize());
1351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pCS->GetFamily() == PDFCS_PATTERN) {
1352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        PatternValue* pvalue = (PatternValue*)m_pBuffer;
1353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pvalue->m_pPattern && pvalue->m_pPattern->m_pDocument) {
1354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pvalue->m_pPattern = pvalue->m_pPattern->m_pDocument->GetPageData()->GetPattern(pvalue->m_pPattern->m_pPatternObj, FALSE, &pvalue->m_pPattern->m_ParentMatrix);
1355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1358ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_Color::GetRGB(int& R, int& G, int& B) const
1359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pCS == NULL || m_pBuffer == NULL) {
1361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
1362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT r, g, b;
1364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_pCS->GetRGB(m_pBuffer, r, g, b)) {
1365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
1366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    R = (FX_INT32)(r * 255 + 0.5f);
1368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    G = (FX_INT32)(g * 255 + 0.5f);
1369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    B = (FX_INT32)(b * 255 + 0.5f);
1370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
1371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1372ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_Pattern* CPDF_Color::GetPattern() const
1373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pBuffer == NULL || m_pCS->GetFamily() != PDFCS_PATTERN) {
1375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
1376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    PatternValue* pvalue = (PatternValue*)m_pBuffer;
1378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pvalue->m_pPattern;
1379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1380ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_ColorSpace* CPDF_Color::GetPatternCS() const
1381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pBuffer == NULL || m_pCS->GetFamily() != PDFCS_PATTERN) {
1383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
1384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return m_pCS->GetBaseCS();
1386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1387ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_FLOAT* CPDF_Color::GetPatternColor() const
1388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pBuffer == NULL || m_pCS->GetFamily() != PDFCS_PATTERN) {
1390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
1391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    PatternValue* pvalue = (PatternValue*)m_pBuffer;
1393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pvalue->m_nComps ? pvalue->m_Comps : NULL;
1394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1395ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_Color::IsEqual(const CPDF_Color& other) const
1396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pCS != other.m_pCS || m_pCS == NULL) {
1398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
1399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FXSYS_memcmp32(m_pBuffer, other.m_pBuffer, m_pCS->GetBufSize()) == 0;
1401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1402