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/fxge/fx_dib.h"
8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fxge/fx_ge.h"
9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fxcodec/fx_codec.h"
10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst FX_DWORD g_dwWinPalette[256] = {
11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff000000, 0xff800000, 0xff008000, 0xff808000, 0xff000080, 0xff800080,
12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff008080, 0xff808080, 0xffC0DCC0, 0xffA6CAF0, 0xff2A3FAA, 0xff2A3FFF,
13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff2A5F00, 0xff2A5F55, 0xff2A5FAA, 0xff2A5FFF, 0xff2A7F00, 0xff2A7F55,
14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff2A7FAA, 0xff2A7FFF, 0xff2A9F00, 0xff2A9F55, 0xff2A9FAA, 0xff2A9FFF,
15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff2ABF00, 0xff2ABF55, 0xff2ABFAA, 0xff2ABFFF, 0xff2ADF00, 0xff2ADF55,
16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff2ADFAA, 0xff2ADFFF, 0xff2AFF00, 0xff2AFF55, 0xff2AFFAA, 0xff2AFFFF,
17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff550000, 0xff550055, 0xff5500AA, 0xff5500FF, 0xff551F00, 0xff551F55,
18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff551FAA, 0xff551FFF, 0xff553F00, 0xff553F55, 0xff553FAA, 0xff553FFF,
19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff555F00, 0xff555F55, 0xff555FAA, 0xff555FFF, 0xff557F00, 0xff557F55,
20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff557FAA, 0xff557FFF, 0xff559F00, 0xff559F55, 0xff559FAA, 0xff559FFF,
21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff55BF00, 0xff55BF55, 0xff55BFAA, 0xff55BFFF, 0xff55DF00, 0xff55DF55,
22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff55DFAA, 0xff55DFFF, 0xff55FF00, 0xff55FF55, 0xff55FFAA, 0xff55FFFF,
23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff7F0000, 0xff7F0055, 0xff7F00AA, 0xff7F00FF, 0xff7F1F00, 0xff7F1F55,
24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff7F1FAA, 0xff7F1FFF, 0xff7F3F00, 0xff7F3F55, 0xff7F3FAA, 0xff7F3FFF,
25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff7F5F00, 0xff7F5F55, 0xff7F5FAA, 0xff7F5FFF, 0xff7F7F00, 0xff7F7F55,
26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff7F7FAA, 0xff7F7FFF, 0xff7F9F00, 0xff7F9F55, 0xff7F9FAA, 0xff7F9FFF,
27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff7FBF00, 0xff7FBF55, 0xff7FBFAA, 0xff7FBFFF, 0xff7FDF00, 0xff7FDF55,
28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff7FDFAA, 0xff7FDFFF, 0xff00FF7F, 0xff7FFF55, 0xff7FFFAA, 0xff7FFFFF,
29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffAA0000, 0xffAA0055, 0xffAA00AA, 0xffAA00FF, 0xffAA1F00, 0xffAA1F55,
30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffAA1FAA, 0xffAA1FFF, 0xffAA3F00, 0xffAA3F55, 0xffAA3FAA, 0xffAA3FFF,
31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffAA5F00, 0xffAA5F55, 0xffAA5FAA, 0xffAA5FFF, 0xffAA7F00, 0xffAA7F55,
32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffAA7FAA, 0xffAA7FFF, 0xffAA9F00, 0xffAA9F55, 0xffAA9FAA, 0xffAA9FFF,
33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffAABF00, 0xffAABF55, 0xffAABFAA, 0xffAABFFF, 0xffAADF00, 0xffAADF55,
34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffAADFAA, 0xffAADFFF, 0xffAAFF00, 0xffAAFF55, 0xffAAFFAA, 0xffAAFFFF,
35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffD40000, 0xffD40055, 0xffD400AA, 0xffD400FF, 0xffD41F00, 0xffD41F55,
36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffD41FAA, 0xffD41FFF, 0xffD43F00, 0xffD43F55, 0xffD43FAA, 0xffD43FFF,
37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffD45F00, 0xffD45F55, 0xffD45FAA, 0xffD45FFF, 0xffD47F00, 0xffD47F55,
38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffD47FAA, 0xffD4F7FF, 0xffD49F00, 0xffD49F55, 0xffD49FAA, 0xffD49FFF,
39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffD4BF00, 0xffD4BF55, 0xffD4BFAA, 0xffD4BFFF, 0xffD4DF00, 0xffD4DF55,
40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffD4DFAA, 0xffD4DFFF, 0xffD4FF00, 0xffD4FF55, 0xffD4FFAA, 0xffD4FFFF,
41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffFF0055, 0xffFF00AA, 0xffFF1F00, 0xffFF1F55, 0xffFF1FAA, 0xffFF1FFF,
42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffFF3F00, 0xffFF3F55, 0xffFF3FAA, 0xffFF3FFF, 0xffFF5F00, 0xffFF5F55,
43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffFF5FAA, 0xffFF5FFF, 0xffFF7F00, 0xffFF7F55, 0xffFF7FAA, 0xffFF7FFF,
44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffFF9F00, 0xffFF9F55, 0xffFF9FAA, 0xffFF9FFF, 0xffFFBF00, 0xffFFBF55,
45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffFFBFAA, 0xffFFBFFF, 0xffFFDF00, 0xffFFDF55, 0xffFFDFAA, 0xffFFDFFF,
46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffFFFF55, 0xffFFFFAA, 0xffCCCCFF, 0xffFFCCFF, 0xff33FFFF, 0xff66FFFF,
47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff99FFFF, 0xffCCFFFF, 0xff007F00, 0xff007F55, 0xff007FAA, 0xff007FFF,
48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff009F00, 0xff009F55, 0xff009FAA, 0xff009FFF, 0xff00BF00, 0xff00BF55,
49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff00BFAA, 0xff00BFFF, 0xff00DF00, 0xff00DF55, 0xff00DFAA, 0xff00DFFF,
50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff00FF55, 0xff00FFAA, 0xff2A0000, 0xff2A0055, 0xff2A00AA, 0xff2A00FF,
51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff2A1F00, 0xff2A1F55, 0xff2A1FAA, 0xff2A1FFF, 0xff2A3F00, 0xff2A3F55,
52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffFFFBF0, 0xffA0A0A4, 0xff808080, 0xffFF0000, 0xff00FF00, 0xffFF0000,
53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff0000FF, 0xffFF00FF, 0xff00FFFF, 0xffFFFFFF
54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst FX_DWORD g_dwMacPalette[256] = {
56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffFFFFFF, 0xffFFFFCC, 0xffFFFF99, 0xffFFFF66, 0xffFFFF33, 0xffFFFF00,
57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffFFCCFF, 0xffFFCCCC, 0xffFFCC99, 0xffFFCC66, 0xffFFCC33, 0xffFFCC00,
58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffFF99FF, 0xffFF99CC, 0xffFF9999, 0xffFF9966, 0xffFF9933, 0xffFF9900,
59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffFF66FF, 0xffFF66CC, 0xffFF6699, 0xffFF6666, 0xffFF6633, 0xffFF6600,
60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffFF33FF, 0xffFF33CC, 0xffFF3399, 0xffFF3366, 0xffFF3333, 0xffFF3300,
61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffFF00FF, 0xffFF00CC, 0xffFF0099, 0xffFF0066, 0xffFF0033, 0xffFF0000,
62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffCCFFFF, 0xffCCFFCC, 0xffCCFF99, 0xffCCFF66, 0xffCCFF33, 0xffCCFF00,
63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffCCCCFF, 0xffCCCCCC, 0xffCCCC99, 0xffCCCC66, 0xffCCCC33, 0xffCCCC00,
64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffCC99FF, 0xffCC99CC, 0xffCC9999, 0xffCC9966, 0xffCC9933, 0xffCC9900,
65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffCC66FF, 0xffCC66CC, 0xffCC6699, 0xffCC6666, 0xffCC6633, 0xffCC6600,
66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffCC33FF, 0xffCC33CC, 0xffCC3399, 0xffCC3366, 0xffCC3333, 0xffCC3300,
67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffCC00FF, 0xffCC00CC, 0xffCC0099, 0xffCC0066, 0xffCC0033, 0xffCC0000,
68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff99FFFF, 0xff99FFCC, 0xff99FF99, 0xff99FF66, 0xff99FF33, 0xff99FF00,
69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff99CCFF, 0xff99CCCC, 0xff99CC99, 0xff99CC66, 0xff99CC33, 0xff99CC00,
70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff9999FF, 0xff9999CC, 0xff999999, 0xff999966, 0xff999933, 0xff999900,
71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff9966FF, 0xff9966CC, 0xff996699, 0xff996666, 0xff996633, 0xff996600,
72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff9933FF, 0xff9933CC, 0xff993399, 0xff993366, 0xff993333, 0xff993300,
73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff9900FF, 0xff9900CC, 0xff990099, 0xff990066, 0xff990033, 0xff990000,
74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff66FFFF, 0xff66FFCC, 0xff66FF99, 0xff66FF66, 0xff66FF33, 0xff66FF00,
75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff66CCFF, 0xff66CCCC, 0xff66CC99, 0xff66CC66, 0xff66CC33, 0xff66CC00,
76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff6699FF, 0xff6699CC, 0xff669999, 0xff669966, 0xff669933, 0xff669900,
77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff6666FF, 0xff6666CC, 0xff666699, 0xff666666, 0xff666633, 0xff666600,
78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff6633FF, 0xff6633CC, 0xff663399, 0xff663366, 0xff663333, 0xff663300,
79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff6600FF, 0xff6600CC, 0xff660099, 0xff660066, 0xff660033, 0xff660000,
80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff33FFFF, 0xff33FFCC, 0xff33FF99, 0xff33FF66, 0xff33FF33, 0xff33FF00,
81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff33CCFF, 0xff33CCCC, 0xff33CC99, 0xff33CC66, 0xff33CC33, 0xff33CC00,
82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff3399FF, 0xff3399CC, 0xff339999, 0xff339966, 0xff339933, 0xff339900,
83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff3366FF, 0xff3366CC, 0xff336699, 0xff336666, 0xff336633, 0xff336600,
84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff3333FF, 0xff3333CC, 0xff333399, 0xff333366, 0xff333333, 0xff333300,
85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff3300FF, 0xff3300CC, 0xff330099, 0xff330066, 0xff330033, 0xff330000,
86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff00FFFF, 0xff00FFCC, 0xff00FF99, 0xff00FF66, 0xff00FF33, 0xff00FF00,
87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff00CCFF, 0xff00CCCC, 0xff00CC99, 0xff00CC66, 0xff00CC33, 0xff00CC00,
88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff0099FF, 0xff0099CC, 0xff009999, 0xff009966, 0xff009933, 0xff009900,
89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff0066FF, 0xff0066CC, 0xff006699, 0xff006666, 0xff006633, 0xff006600,
90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff0033FF, 0xff0033CC, 0xff003399, 0xff003366, 0xff003333, 0xff003300,
91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff0000FF, 0xff0000CC, 0xff000099, 0xff000066, 0xff000033,
92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffEE0000, 0xffDD0000, 0xffBB0000, 0xffAA0000, 0xff880000, 0xff770000,
93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff550000, 0xff440000, 0xff220000, 0xff110000, 0xff00EE00, 0xff00DD00,
94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff00BB00, 0xff00AA00, 0xff008800, 0xff007700, 0xff005500, 0xff004400,
95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff002200, 0xff001100, 0xff0000EE, 0xff0000DD, 0xff0000BB, 0xff0000AA,
96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff000088, 0xff000077, 0xff000055, 0xff000044, 0xff000022, 0xff000011,
97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xffEEEEEE, 0xffDDDDDD, 0xffBBBBBB, 0xffAAAAAA, 0xff888888, 0xff777777,
98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xff555555, 0xff444444, 0xff222222, 0xff111111, 0xff000000
99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovclass CFX_Palette : public CFX_Object
101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovpublic:
103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_Palette();
104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ~CFX_Palette();
105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovpublic:
106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL      BuildPalette(const CFX_DIBSource* pBitmap, int dwPaletteType);
107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD*    GetPalette() const
108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return m_pPalette;
110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD*    GetColorLut()const
113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return m_cLut;
115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD*    GetAmountLut()const
117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return m_aLut;
119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_INT32     Getlut()const
121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return m_lut;
123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovprotected:
125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD*    m_pPalette;
126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD*    m_cLut;
127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD*    m_aLut;
128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int          m_lut;
129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint _Partition(FX_DWORD* alut, FX_DWORD* clut, int l, int r)
131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD p_a = alut[l];
133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD p_c = clut[l];
134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while(l < r) {
135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        while(l < r && alut[r] >= p_a) {
136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            r--;
137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (l < r) {
139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            alut[l] = alut[r];
140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            clut[l++] = clut[r];
141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        while(l < r && alut[l] <= p_a) {
143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            l++;
144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (l < r) {
146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            alut[r] = alut[l];
147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            clut[r--] = clut[l];
148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    alut[l] = p_a;
151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clut[l] = p_c;
152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return l;
153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _Qsort(FX_DWORD* alut, FX_DWORD* clut, int l, int r)
155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if(l < r) {
157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int pI = _Partition(alut, clut, l, r);
158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        _Qsort(alut, clut, l, pI - 1);
159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        _Qsort(alut, clut, pI + 1, r);
160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _ColorDecode(FX_DWORD pal_v, FX_BYTE& r, FX_BYTE& g, FX_BYTE& b)
163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    r = (FX_BYTE)((pal_v & 0xf00) >> 4);
165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    g = (FX_BYTE)(pal_v & 0x0f0);
166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    b = (FX_BYTE)((pal_v & 0x00f) << 4);
167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _Obtain_Pal(FX_DWORD* aLut, FX_DWORD*cLut, FX_DWORD* dest_pal, int pal_type, FX_DWORD* win_mac_pal, FX_DWORD lut)
169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int row, col;
171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD lut_1 = lut - 1;
172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pal_type == FXDIB_PALETTE_LOC) {
173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (row = 0; row < 256; row++) {
174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int lut_offset = lut_1 - row;
175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (lut_offset < 0) {
176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                lut_offset += 256;
177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_DWORD color = cLut[lut_offset];
179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE r, g, b;
180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _ColorDecode(color, r, g, b);
181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_pal[row] = ((FX_DWORD)r << 16) | ((FX_DWORD)g << 8) | b | 0xff000000;
182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            aLut[lut_offset] = row;
183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (row = 0; row < 256; row++) {
186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int lut_offset = lut_1 - row;
187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (lut_offset < 0) {
188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                lut_offset += 256;
189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE r, g, b;
191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _ColorDecode(cLut[lut_offset], r, g, b);
192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int error, min_error = 1000000;
193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int c_index = 0;
194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (col = 0; col < 256; col++) {
195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_DWORD p_color = win_mac_pal[col];
196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int d_r = r - (FX_BYTE)(p_color >> 16);
197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int d_g = g - (FX_BYTE)(p_color >> 8);
198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int d_b = b - (FX_BYTE)p_color;
199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                error = d_r * d_r + d_g * d_g + d_b * d_b;
200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (error < min_error) {
201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    min_error = error;
202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    c_index = col;
203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_pal[row] =  win_mac_pal[c_index];
206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            aLut[lut_offset] = row;
207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
210ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_Palette::CFX_Palette()
211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pPalette = NULL;
213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_cLut = NULL;
214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_aLut = NULL;
215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_lut = 0;
216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
217ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_Palette::~CFX_Palette()
218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pPalette) {
220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Free(m_pPalette);
221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_cLut) {
223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Free(m_cLut);
224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_aLut) {
226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Free(m_aLut);
227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_lut = 0;
229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
230ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CFX_Palette::BuildPalette(const CFX_DIBSource* pBitmap, int pal_type)
231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pBitmap == NULL) {
233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pPalette != NULL) {
236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Free(m_pPalette);
237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pPalette = FX_Alloc(FX_DWORD, 256);
239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_pPalette) {
240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_memset32(m_pPalette, 0, sizeof(FX_DWORD) * 256);
243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int bpp    = pBitmap->GetBPP() / 8;
244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int width  = pBitmap->GetWidth();
245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int height = pBitmap->GetHeight();
246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_cLut) {
247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Free(m_cLut);
248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_cLut = NULL;
249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_aLut) {
251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Free(m_aLut);
252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_aLut = NULL;
253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_cLut = FX_Alloc(FX_DWORD, 4096);
255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_cLut) {
256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_aLut = FX_Alloc(FX_DWORD, 4096);
259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_aLut) {
260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_memset32(m_aLut, 0, sizeof(FX_DWORD) * 4096);
263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_memset32(m_cLut, 0, sizeof(FX_DWORD) * 4096);
264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int row, col;
265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_lut = 0;
266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (row = 0; row < height; row++) {
267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE* scan_line = (FX_BYTE*)pBitmap->GetScanline(row);
268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (col = 0; col < width; col++) {
269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE* src_port = scan_line + col * bpp;
270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_DWORD b = src_port[0] & 0xf0;
271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_DWORD g = src_port[1] & 0xf0;
272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_DWORD r = src_port[2] & 0xf0;
273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_DWORD index = (r << 4) + g + (b >> 4);
274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_aLut[index]++;
275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (row = 0; row < 4096; row++) {
278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_aLut[row] != 0) {
279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_aLut[m_lut] = m_aLut[row];
280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_cLut[m_lut] = row;
281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_lut++;
282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _Qsort(m_aLut, m_cLut, 0, m_lut - 1);
285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD* win_mac_pal = NULL;
286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pal_type == FXDIB_PALETTE_WIN) {
287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        win_mac_pal = (FX_DWORD*)g_dwWinPalette;
288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (pal_type == FXDIB_PALETTE_MAC) {
289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        win_mac_pal = (FX_DWORD*)g_dwMacPalette;
290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _Obtain_Pal(m_aLut, m_cLut, m_pPalette, pal_type, win_mac_pal, m_lut);
292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
294ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL _ConvertBuffer_1bppMask2Gray(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                     const CFX_DIBSource* pSrcBitmap, int src_left, int src_top)
296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BYTE set_gray, reset_gray;
298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    set_gray = 0xff;
299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    reset_gray = 0x00;
300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int row = 0; row < height; row ++) {
301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FXSYS_memset8(dest_scan, reset_gray, width);
303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row);
304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = src_left; col < src_left + width; col ++) {
305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_scan[col / 8] & (1 << (7 - col % 8))) {
306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = set_gray;
307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
313ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL _ConvertBuffer_8bppMask2Gray(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                     const CFX_DIBSource* pSrcBitmap, int src_left, int src_top)
315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int row = 0; row < height; row ++) {
317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left;
319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FXSYS_memcpy32(dest_scan, src_scan, width);
320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
323ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL _ConvertBuffer_1bppPlt2Gray(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform)
325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD* src_plt = pSrcBitmap->GetPalette();
327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BYTE gray[2];
328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pIccTransform) {
329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_DWORD plt[2];
330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pSrcBitmap->IsCmykImage()) {
331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            plt[0] = FXCMYK_TODIB(src_plt[0]);
332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            plt[1] = FXCMYK_TODIB(src_plt[1]);
333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPBYTE bgr_ptr = (FX_LPBYTE)plt;
335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bgr_ptr[0] = FXARGB_B(src_plt[0]);
336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bgr_ptr[1] = FXARGB_G(src_plt[0]);
337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bgr_ptr[2] = FXARGB_R(src_plt[0]);
338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bgr_ptr[3] = FXARGB_B(src_plt[1]);
339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bgr_ptr[4] = FXARGB_G(src_plt[1]);
340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bgr_ptr[5] = FXARGB_R(src_plt[1]);
341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pIccModule->TranslateScanline(pIccTransform, gray, (FX_LPCBYTE)plt, 2);
344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE reset_r, reset_g, reset_b,
346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                set_r, set_g, set_b;
347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pSrcBitmap->IsCmykImage()) {
348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            AdobeCMYK_to_sRGB1(FXSYS_GetCValue(src_plt[0]), FXSYS_GetMValue(src_plt[0]), FXSYS_GetYValue(src_plt[0]), FXSYS_GetKValue(src_plt[0]),
349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               reset_r, reset_g, reset_b);
350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            AdobeCMYK_to_sRGB1(FXSYS_GetCValue(src_plt[1]), FXSYS_GetMValue(src_plt[1]), FXSYS_GetYValue(src_plt[1]), FXSYS_GetKValue(src_plt[1]),
351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               set_r, set_g, set_b);
352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            reset_r = FXARGB_R(src_plt[0]);
354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            reset_g = FXARGB_G(src_plt[0]);
355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            reset_b = FXARGB_B(src_plt[0]);
356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            set_r = FXARGB_R(src_plt[1]);
357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            set_g = FXARGB_G(src_plt[1]);
358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            set_b = FXARGB_B(src_plt[1]);
359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        gray[0] = FXRGB2GRAY(reset_r, reset_g, reset_b);
361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        gray[1] = FXRGB2GRAY(set_r, set_g, set_b);
362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int row = 0; row < height; row ++) {
364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FXSYS_memset8(dest_scan, gray[0], width);
366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row);
367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = src_left; col < src_left + width; col ++) {
368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_scan[col / 8] & (1 << (7 - col % 8))) {
369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan = gray[1];
370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan ++;
372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
376ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL _ConvertBuffer_8bppPlt2Gray(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform)
378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD* src_plt = pSrcBitmap->GetPalette();
380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BYTE gray[256];
381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pIccTransform) {
382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_DWORD plt[256];
383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pSrcBitmap->IsCmykImage()) {
384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int i = 0; i < 256; i ++) {
385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                plt[i] = FXCMYK_TODIB(src_plt[i]);
386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPBYTE bgr_ptr = (FX_LPBYTE)plt;
389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int i = 0; i < 256; i ++) {
390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *bgr_ptr++ = FXARGB_B(src_plt[i]);
391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *bgr_ptr++ = FXARGB_G(src_plt[i]);
392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *bgr_ptr++ = FXARGB_R(src_plt[i]);
393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pIccModule->TranslateScanline(pIccTransform, gray, (FX_LPCBYTE)plt, 256);
397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pSrcBitmap->IsCmykImage()) {
399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE r, g, b;
400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int i = 0; i < 256; i ++) {
401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                AdobeCMYK_to_sRGB1(FXSYS_GetCValue(src_plt[i]), FXSYS_GetMValue(src_plt[i]), FXSYS_GetYValue(src_plt[i]), FXSYS_GetKValue(src_plt[i]),
402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   r, g, b);
403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                gray[i] = FXRGB2GRAY(r, g, b);
404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else
406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int i = 0; i < 256; i ++) {
407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                gray[i] = FXRGB2GRAY(FXARGB_R(src_plt[i]), FXARGB_G(src_plt[i]), FXARGB_B(src_plt[i]));
408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int row = 0; row < height; row ++) {
411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left;
413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan++ = gray[*src_scan++];
415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
419ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL _ConvertBuffer_RgbOrCmyk2Gray(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                      const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform)
421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int Bpp = pSrcBitmap->GetBPP() / 8;
423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pIccTransform) {
424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (Bpp == 3 || pSrcBitmap->IsCmykImage()) {
426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int row = 0; row < height; row ++) {
427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * Bpp;
429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, width);
430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int row = 0; row < height; row ++) {
433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * 4;
435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (int col = 0; col < width; col ++) {
436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    dest_scan++;
438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_scan += 4;
439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pSrcBitmap->IsCmykImage()) {
444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int row = 0; row < height; row ++) {
445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * 4;
447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (int col = 0; col < width; col ++) {
448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FX_BYTE r, g, b;
449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    AdobeCMYK_to_sRGB1(FXSYS_GetCValue((FX_DWORD)src_scan[0]), FXSYS_GetMValue((FX_DWORD)src_scan[1]), FXSYS_GetYValue((FX_DWORD)src_scan[2]), FXSYS_GetKValue((FX_DWORD)src_scan[3]),
450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                       r, g, b);
451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_scan++ = FXRGB2GRAY(r, g, b);
452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_scan += 4;
453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else
456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int row = 0; row < height; row ++) {
457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * Bpp;
459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (int col = 0; col < width; col ++) {
460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_scan++ = FXRGB2GRAY(src_scan[2], src_scan[1], src_scan[0]);
461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    src_scan += Bpp;
462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline void _ConvertBuffer_IndexCopy(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                     const CFX_DIBSource* pSrcBitmap, int src_left, int src_top)
469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pSrcBitmap->GetBPP() == 1) {
471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int row = 0; row < height; row ++) {
472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FXSYS_memset32(dest_scan, 0, width);
474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row);
475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int col = src_left; col < src_left + width; col ++) {
476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (src_scan[col / 8] & (1 << (7 - col % 8))) {
477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *dest_scan = 1;
478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan ++;
480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int row = 0; row < height; row ++) {
484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left;
486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FXSYS_memcpy32(dest_scan, src_scan, width);
487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
490ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL _ConvertBuffer_Plt2PltRgb8(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, FX_DWORD* dst_plt, void* pIccTransform)
492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _ConvertBuffer_IndexCopy(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top);
494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD* src_plt = pSrcBitmap->GetPalette();
495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int plt_size = pSrcBitmap->GetPaletteSize();
496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pIccTransform) {
497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_DWORD plt[256];
498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE bgr_ptr = (FX_LPBYTE)plt;
499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pSrcBitmap->IsCmykImage()) {
500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int i = 0; i < plt_size; i ++) {
501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                plt[i] = FXCMYK_TODIB(src_plt[i]);
502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int i = 0; i < plt_size; i ++) {
505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *bgr_ptr++ = FXARGB_B(src_plt[i]);
506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *bgr_ptr++ = FXARGB_G(src_plt[i]);
507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *bgr_ptr++ = FXARGB_R(src_plt[i]);
508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bgr_ptr = (FX_LPBYTE)plt;
510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pIccModule->TranslateScanline(pIccTransform, (FX_LPBYTE)plt, (FX_LPCBYTE)plt, plt_size);
513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int i = 0; i < plt_size; i ++) {
514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dst_plt[i] = FXARGB_MAKE(0xff, bgr_ptr[2], bgr_ptr[1], bgr_ptr[0]);
515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bgr_ptr += 3;
516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pSrcBitmap->IsCmykImage()) {
519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int i = 0; i < plt_size; i ++) {
520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE r, g, b;
521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                AdobeCMYK_to_sRGB1(FXSYS_GetCValue(src_plt[i]), FXSYS_GetMValue(src_plt[i]), FXSYS_GetYValue(src_plt[i]), FXSYS_GetKValue(src_plt[i]),
522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   r, g, b);
523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dst_plt[i] = FXARGB_MAKE(0xff, r, g, b);
524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FXSYS_memcpy32(dst_plt, src_plt, plt_size * 4);
527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline FX_BOOL _ConvertBuffer_Rgb2PltRgb8_NoTransform(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, FX_DWORD* dst_plt)
533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int bpp = pSrcBitmap->GetBPP() / 8;
535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int row, col;
536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_Palette palette;
537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    palette.BuildPalette(pSrcBitmap, FXDIB_PALETTE_LOC);
538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD* cLut = palette.GetColorLut();
539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD* aLut = palette.GetAmountLut();
540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (cLut == NULL || aLut == NULL) {
541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int lut = palette.Getlut();
544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD* pPalette = palette.GetPalette();
545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (lut > 256) {
546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int err, min_err;
547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int lut_256 = lut - 256;
548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (row = 0; row < lut_256; row++) {
549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            min_err = 1000000;
550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE r, g, b;
551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _ColorDecode(cLut[row], r, g, b);
552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int clrindex = 0;
553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int col = 0; col < 256; col++) {
554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_DWORD p_color = *(pPalette + col);
555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int d_r = r - (FX_BYTE)(p_color >> 16);
556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int d_g = g - (FX_BYTE)(p_color >> 8);
557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int d_b = b - (FX_BYTE)(p_color);
558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                err = d_r * d_r + d_g * d_g + d_b * d_b;
559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (err < min_err) {
560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    min_err = err;
561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    clrindex = col;
562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            aLut[row] = clrindex;
565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_INT32 lut_1 = lut - 1;
568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (row = 0; row < height; row ++) {
569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE* src_scan = (FX_BYTE*)pSrcBitmap->GetScanline(src_top + row) + src_left;
570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE* dest_scan = dest_buf + row * dest_pitch;
571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (col = 0; col < width; col++) {
572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE* src_port = src_scan + col * bpp;
573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int r = src_port[2] & 0xf0;
574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int g = src_port[1] & 0xf0;
575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int b = src_port[0] & 0xf0;
576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_DWORD clrindex = (r << 4) + g + (b >> 4);
577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int i = lut_1; i >= 0; i--)
578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (clrindex == cLut[i]) {
579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *(dest_scan + col) = (FX_BYTE)(aLut[i]);
580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_memcpy32(dst_plt, pPalette, sizeof(FX_DWORD) * 256);
585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
587ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL _ConvertBuffer_Rgb2PltRgb8(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, FX_DWORD* dst_plt, void* pIccTransform)
589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ICodec_IccModule* pIccModule = NULL;
591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pIccTransform) {
592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL ret = _ConvertBuffer_Rgb2PltRgb8_NoTransform(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, dst_plt);
595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (ret && pIccTransform) {
596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int i = 0; i < 256; i++) {
598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_ARGB* plt = dst_plt + i;
599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_ARGB plt_entry = FXARGB_TODIB(*plt);
600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pIccModule->TranslateScanline(pIccTransform, (FX_LPBYTE)&plt_entry, (FX_LPCBYTE)&plt_entry, 1);
601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *plt = FXARGB_TODIB(plt_entry);
602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return ret;
605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
606ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL _ConvertBuffer_1bppMask2Rgb(FXDIB_Format dst_format, FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    const CFX_DIBSource* pSrcBitmap, int src_left, int src_top)
608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int comps = (dst_format & 0xff) / 8;
610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BYTE set_gray, reset_gray;
611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    set_gray = 0xff;
612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    reset_gray = 0x00;
613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int row = 0; row < height; row ++) {
614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row);
616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = src_left; col < src_left + width; col ++) {
617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_scan[col / 8] & (1 << (7 - col % 8))) {
618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan[0] = set_gray;
619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan[1] = set_gray;
620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan[2] = set_gray;
621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan[0] = reset_gray;
623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan[1] = reset_gray;
624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan[2] = reset_gray;
625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += comps;
627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
631ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL _ConvertBuffer_8bppMask2Rgb(FXDIB_Format dst_format, FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    const CFX_DIBSource* pSrcBitmap, int src_left, int src_top)
633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int comps = (dst_format & 0xff) / 8;
635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int row = 0; row < height; row ++) {
636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left;
638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE src_pixel;
639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_pixel = *src_scan++;
641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan++ = src_pixel;
642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan++ = src_pixel;
643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan   = src_pixel;
644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += comps - 2;
645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
649ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL _ConvertBuffer_1bppPlt2Rgb(FXDIB_Format dst_format, FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform)
651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int comps = (dst_format & 0xff) / 8;
653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD* src_plt = pSrcBitmap->GetPalette();
654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD plt[2];
655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPBYTE bgr_ptr = (FX_LPBYTE)plt;
656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pSrcBitmap->IsCmykImage()) {
657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        plt[0] = FXCMYK_TODIB(src_plt[0]);
658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        plt[1] = FXCMYK_TODIB(src_plt[1]);
659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        bgr_ptr[0] = FXARGB_B(src_plt[0]);
661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        bgr_ptr[1] = FXARGB_G(src_plt[0]);
662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        bgr_ptr[2] = FXARGB_R(src_plt[0]);
663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        bgr_ptr[3] = FXARGB_B(src_plt[1]);
664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        bgr_ptr[4] = FXARGB_G(src_plt[1]);
665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        bgr_ptr[5] = FXARGB_R(src_plt[1]);
666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pIccTransform) {
668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pIccModule->TranslateScanline(pIccTransform, (FX_LPBYTE)plt, (FX_LPCBYTE)plt, 2);
670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pSrcBitmap->IsCmykImage()) {
672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            AdobeCMYK_to_sRGB1(FXSYS_GetCValue(src_plt[0]), FXSYS_GetMValue(src_plt[0]), FXSYS_GetYValue(src_plt[0]), FXSYS_GetKValue(src_plt[0]),
673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               bgr_ptr[2], bgr_ptr[1], bgr_ptr[0]);
674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            AdobeCMYK_to_sRGB1(FXSYS_GetCValue(src_plt[1]), FXSYS_GetMValue(src_plt[1]), FXSYS_GetYValue(src_plt[1]), FXSYS_GetKValue(src_plt[1]),
675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               bgr_ptr[5], bgr_ptr[4], bgr_ptr[3]);
676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int row = 0; row < height; row ++) {
679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row);
681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = src_left; col < src_left + width; col ++) {
682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (src_scan[col / 8] & (1 << (7 - col % 8))) {
683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = bgr_ptr[3];
684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = bgr_ptr[4];
685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan   = bgr_ptr[5];
686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = bgr_ptr[0];
688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = bgr_ptr[1];
689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan   = bgr_ptr[2];
690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += comps - 2;
692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
696ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL _ConvertBuffer_8bppPlt2Rgb(FXDIB_Format dst_format, FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform)
698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int comps = (dst_format & 0xff) / 8;
700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD* src_plt = pSrcBitmap->GetPalette();
701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD plt[256];
702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPBYTE bgr_ptr = (FX_LPBYTE)plt;
703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!pSrcBitmap->IsCmykImage()) {
704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int i = 0; i < 256; i++) {
705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *bgr_ptr++ = FXARGB_B(src_plt[i]);
706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *bgr_ptr++ = FXARGB_G(src_plt[i]);
707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *bgr_ptr++ = FXARGB_R(src_plt[i]);
708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        bgr_ptr = (FX_LPBYTE)plt;
710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pIccTransform) {
712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pSrcBitmap->IsCmykImage()) {
713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int i = 0; i < 256; i++) {
714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                plt[i] = FXCMYK_TODIB(src_plt[i]);
715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pIccModule->TranslateScanline(pIccTransform, (FX_LPBYTE)plt, (FX_LPCBYTE)plt, 256);
719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pSrcBitmap->IsCmykImage()) {
721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int i = 0; i < 256; i++) {
722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                AdobeCMYK_to_sRGB1(FXSYS_GetCValue(src_plt[i]), FXSYS_GetMValue(src_plt[i]), FXSYS_GetYValue(src_plt[i]), FXSYS_GetKValue(src_plt[i]),
723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   bgr_ptr[2], bgr_ptr[1], bgr_ptr[0]);
724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                bgr_ptr += 3;
725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bgr_ptr = (FX_LPBYTE)plt;
727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int row = 0; row < height; row ++) {
730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left;
732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPBYTE src_pixel = bgr_ptr + 3 * (*src_scan++);
734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan++ = *src_pixel++;
735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan++ = *src_pixel++;
736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan   = *src_pixel++;
737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan += comps - 2;
738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
742ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL _ConvertBuffer_24bppRgb2Rgb24(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                      const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform)
744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pIccTransform) {
746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int row = 0; row < height; row ++) {
748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * 3;
750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, width);
751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int row = 0; row < height; row ++) {
754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * 3;
756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FXSYS_memcpy32(dest_scan, src_scan, width * 3);
757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
761ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL _ConvertBuffer_32bppRgb2Rgb24(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                      const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform)
763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int row = 0; row < height; row ++) {
765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * 4;
767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = 0; col < width; col ++) {
768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan++ = *src_scan++;
769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan++ = *src_scan++;
770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *dest_scan++ = *src_scan++;
771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            src_scan++;
772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pIccTransform) {
775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int row = 0; row < height; row ++) {
777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pIccModule->TranslateScanline(pIccTransform, dest_scan, dest_scan, width);
779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
783ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL _ConvertBuffer_Rgb2Rgb32(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                 const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform)
785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int comps = pSrcBitmap->GetBPP() / 8;
787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pIccTransform) {
788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int row = 0; row < height; row ++) {
790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * comps;
792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int col = 0; col < width; col ++) {
793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan += 4;
795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += comps;
796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int row = 0; row < height; row ++) {
800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * comps;
802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int col = 0; col < width; col ++) {
803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = *src_scan++;
804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = *src_scan++;
805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *dest_scan++ = *src_scan++;
806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan++;
807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += comps - 3;
808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
813ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL _ConvertBuffer_32bppCmyk2Rgb32(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                       const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform)
815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pIccTransform) {
817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int row = 0; row < height; row ++) {
819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * 4;
821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int col = 0; col < width; col ++) {
822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan += 4;
824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += 4;
825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int row = 0; row < height; row ++) {
829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * 4;
831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int col = 0; col < width; col ++) {
832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                AdobeCMYK_to_sRGB1(src_scan[0], src_scan[1], src_scan[2], src_scan[3],
833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   dest_scan[2], dest_scan[1], dest_scan[0]);
834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                dest_scan += 4;
835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                src_scan += 4;
836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
841ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL ConvertBuffer(FXDIB_Format dest_format, FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                      const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, FX_DWORD*& d_pal, void* pIccTransform)
843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXDIB_Format src_format = pSrcBitmap->GetFormat();
845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!CFX_GEModule::Get()->GetCodecModule() || !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) {
846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pIccTransform = NULL;
847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    switch (dest_format) {
849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case FXDIB_Invalid:
850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case FXDIB_1bppCmyk:
851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case FXDIB_1bppMask:
852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case FXDIB_1bppRgb:
853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            ASSERT(FALSE);
854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case FXDIB_8bppMask: {
856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if ((src_format & 0xff) == 1) {
857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (pSrcBitmap->GetPalette()) {
858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        return _ConvertBuffer_1bppPlt2Gray(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return _ConvertBuffer_1bppMask2Gray(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top);
861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else if ((src_format & 0xff) == 8) {
862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (pSrcBitmap->GetPalette()) {
863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        return _ConvertBuffer_8bppPlt2Gray(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return _ConvertBuffer_8bppMask2Gray(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top);
866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else if ((src_format & 0xff) >= 24) {
867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return _ConvertBuffer_RgbOrCmyk2Gray(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return FALSE;
870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case FXDIB_8bppRgb:
872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case FXDIB_8bppRgba: {
873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if ((src_format & 0xff) == 8 && pSrcBitmap->GetPalette() == NULL) {
874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return ConvertBuffer(FXDIB_8bppMask, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, d_pal, pIccTransform);
875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                d_pal = FX_Alloc(FX_DWORD, 256);
877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (!d_pal) {
878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return FALSE;
879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FXSYS_memset32(d_pal, 0, sizeof(FX_DWORD) * 256);
881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (((src_format & 0xff) == 1 || (src_format & 0xff) == 8) && pSrcBitmap->GetPalette()) {
882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return _ConvertBuffer_Plt2PltRgb8(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, d_pal, pIccTransform);
883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else if ((src_format & 0xff) >= 24) {
884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return _ConvertBuffer_Rgb2PltRgb8(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, d_pal, pIccTransform);
885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return FALSE;
887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case FXDIB_Rgb:
889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case FXDIB_Rgba: {
890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if ((src_format & 0xff) == 1) {
891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (pSrcBitmap->GetPalette()) {
892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        return _ConvertBuffer_1bppPlt2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return _ConvertBuffer_1bppMask2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top);
895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else if ((src_format & 0xff) == 8) {
896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (pSrcBitmap->GetPalette()) {
897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        return _ConvertBuffer_8bppPlt2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return _ConvertBuffer_8bppMask2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top);
900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else if ((src_format & 0xff) == 24) {
901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return _ConvertBuffer_24bppRgb2Rgb24(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else if ((src_format & 0xff) == 32) {
903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return _ConvertBuffer_32bppRgb2Rgb24(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return FALSE;
906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case FXDIB_Argb:
908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case FXDIB_Rgb32: {
909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if ((src_format & 0xff) == 1) {
910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (pSrcBitmap->GetPalette()) {
911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        return _ConvertBuffer_1bppPlt2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return _ConvertBuffer_1bppMask2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top);
914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else if ((src_format & 0xff) == 8) {
915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (pSrcBitmap->GetPalette()) {
916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        return _ConvertBuffer_8bppPlt2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return _ConvertBuffer_8bppMask2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top);
919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else if ((src_format & 0xff) >= 24) {
920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (src_format & 0x0400) {
921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        return _ConvertBuffer_32bppCmyk2Rgb32(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return _ConvertBuffer_Rgb2Rgb32(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return FALSE;
926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        default:
928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FALSE;
931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
932ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_DIBitmap* CFX_DIBSource::CloneConvert(FXDIB_Format dest_format, const FX_RECT* pClip, void* pIccTransform) const
933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if(dest_format == GetFormat() && pIccTransform == NULL) {
935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return Clone(pClip);
936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pClip) {
938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFX_DIBitmap* pClone = Clone(pClip);
939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pClone == NULL) {
940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return NULL;
941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if(!pClone->ConvertFormat(dest_format, pIccTransform)) {
943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            delete pClone;
944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return NULL;
945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return pClone;
947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_DIBitmap* pClone = FX_NEW CFX_DIBitmap;
949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!pClone) {
950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if(!pClone->Create(m_Width, m_Height, dest_format)) {
953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete pClone;
954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL ret = TRUE;
957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_DIBitmap* pSrcAlpha = NULL;
958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_AlphaFlag & 2) {
959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pSrcAlpha = (GetFormat() == FXDIB_Argb) ? GetAlphaMask() : m_pAlphaMask;
960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pSrcAlpha == NULL) {
961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            delete pClone;
962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return NULL;
963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (dest_format & 0x0200) {
966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (dest_format == FXDIB_Argb)
967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            ret = pSrcAlpha ?
968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                  pClone->LoadChannel(FXDIB_Alpha, pSrcAlpha, FXDIB_Alpha) :
969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                  pClone->LoadChannel(FXDIB_Alpha, 0xff);
970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        else {
971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            ret = pClone->CopyAlphaMask(pSrcAlpha);
972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pSrcAlpha && pSrcAlpha != m_pAlphaMask) {
975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete pSrcAlpha;
976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pSrcAlpha = NULL;
977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!ret) {
979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete pClone;
980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD* pal_8bpp = NULL;
983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ret = ConvertBuffer(dest_format, pClone->GetBuffer(), pClone->GetPitch(), m_Width, m_Height, this, 0, 0, pal_8bpp, pIccTransform);
984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!ret) {
985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pal_8bpp) {
986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_Free(pal_8bpp);
987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete pClone;
989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pal_8bpp) {
992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pClone->CopyPalette(pal_8bpp);
993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Free(pal_8bpp);
994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pal_8bpp = NULL;
995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pClone;
997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
998ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CFX_DIBitmap::ConvertFormat(FXDIB_Format dest_format, void* pIccTransform)
999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXDIB_Format src_format = GetFormat();
1001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (dest_format == src_format && pIccTransform == NULL) {
1002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
1003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (dest_format == FXDIB_8bppMask && src_format == FXDIB_8bppRgb && m_pPalette == NULL) {
1005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_AlphaFlag = 1;
1006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
1007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (dest_format == FXDIB_Argb && src_format == FXDIB_Rgb32 && pIccTransform == NULL) {
1009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_AlphaFlag = 2;
1010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int row = 0; row < m_Height; row ++) {
1011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPBYTE scanline = m_pBuffer + row * m_Pitch + 3;
1012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int col = 0; col < m_Width; col ++) {
1013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *scanline = 0xff;
1014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                scanline += 4;
1015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
1018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int dest_bpp = dest_format & 0xff;
1020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int dest_pitch = (dest_bpp * m_Width + 31) / 32 * 4;
1021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPBYTE dest_buf = FX_AllocNL(FX_BYTE, dest_pitch * m_Height + 4);
1022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (dest_buf == NULL) {
1023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
1024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_DIBitmap* pAlphaMask = NULL;
1026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (dest_format == FXDIB_Argb) {
1027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FXSYS_memset8(dest_buf, 0xff, dest_pitch * m_Height + 4);
1028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_pAlphaMask) {
1029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int row = 0; row < m_Height; row ++) {
1030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_LPBYTE pDstScanline = dest_buf + row * dest_pitch + 3;
1031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_LPCBYTE pSrcScanline = m_pAlphaMask->GetScanline(row);
1032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (int col = 0; col < m_Width; col ++) {
1033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *pDstScanline = *pSrcScanline++;
1034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    pDstScanline += 4;
1035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (dest_format & 0x0200) {
1039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src_format == FXDIB_Argb) {
1040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pAlphaMask = GetAlphaMask();
1041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (pAlphaMask == NULL) {
1042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_Free(dest_buf);
1043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return FALSE;
1044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
1046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (m_pAlphaMask == NULL) {
1047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (!BuildAlphaMask()) {
1048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FX_Free(dest_buf);
1049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return FALSE;
1050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pAlphaMask = m_pAlphaMask;
1052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_pAlphaMask = NULL;
1053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
1054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pAlphaMask = m_pAlphaMask;
1055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL ret = FALSE;
1059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD* pal_8bpp = NULL;
1060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ret = ConvertBuffer(dest_format, dest_buf, dest_pitch, m_Width, m_Height, this, 0, 0, pal_8bpp, pIccTransform);
1061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!ret) {
1062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pal_8bpp) {
1063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_Free(pal_8bpp);
1064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pAlphaMask != m_pAlphaMask) {
1066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            delete pAlphaMask;
1067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (dest_buf) {
1069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_Free(dest_buf);
1070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
1072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pAlphaMask && pAlphaMask != m_pAlphaMask) {
1074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete m_pAlphaMask;
1075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pAlphaMask = pAlphaMask;
1077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pPalette) {
1078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Free(m_pPalette);
1079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pPalette = pal_8bpp;
1081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_bExtBuf) {
1082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Free(m_pBuffer);
1083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bExtBuf = FALSE;
1085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pBuffer = dest_buf;
1086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bpp = (FX_BYTE)dest_format;
1087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_AlphaFlag = (FX_BYTE)(dest_format >> 8);
1088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Pitch = dest_pitch;
1089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
1090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1091