Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(169)

Side by Side Diff: core/src/fxge/dib/fx_dib_main.cpp

Issue 1265503005: clang-format all pdfium code. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: sigh Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 PDFium Authors. All rights reserved. 1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 6
7 #include "../../../include/fxge/fx_dib.h" 7 #include "../../../include/fxge/fx_dib.h"
8 #include "../../../include/fxge/fx_ge.h" 8 #include "../../../include/fxge/fx_ge.h"
9 #include "../../../include/fxcodec/fx_codec.h" 9 #include "../../../include/fxcodec/fx_codec.h"
10 #include "dib_int.h" 10 #include "dib_int.h"
11 #include <limits.h> 11 #include <limits.h>
12 FX_BOOL ConvertBuffer(FXDIB_Format dest_format, uint8_t* dest_buf, int dest_pitc h, int width, int height, 12 FX_BOOL ConvertBuffer(FXDIB_Format dest_format,
13 const CFX_DIBSource* pSrcBitmap, int src_left, int src_top , FX_DWORD*& pal, void* pIccTransform); 13 uint8_t* dest_buf,
14 void CmykDecode(FX_DWORD cmyk, int& c, int& m, int& y, int& k) 14 int dest_pitch,
15 { 15 int width,
16 c = FXSYS_GetCValue(cmyk); 16 int height,
17 m = FXSYS_GetMValue(cmyk); 17 const CFX_DIBSource* pSrcBitmap,
18 y = FXSYS_GetYValue(cmyk); 18 int src_left,
19 k = FXSYS_GetKValue(cmyk); 19 int src_top,
20 } 20 FX_DWORD*& pal,
21 void ArgbDecode(FX_DWORD argb, int& a, int& r, int& g, int& b) 21 void* pIccTransform);
22 { 22 void CmykDecode(FX_DWORD cmyk, int& c, int& m, int& y, int& k) {
23 a = FXARGB_A(argb); 23 c = FXSYS_GetCValue(cmyk);
24 r = FXARGB_R(argb); 24 m = FXSYS_GetMValue(cmyk);
25 g = FXARGB_G(argb); 25 y = FXSYS_GetYValue(cmyk);
26 b = FXARGB_B(argb); 26 k = FXSYS_GetKValue(cmyk);
27 } 27 }
28 void ArgbDecode(FX_DWORD argb, int& a, FX_COLORREF& rgb) 28 void ArgbDecode(FX_DWORD argb, int& a, int& r, int& g, int& b) {
29 { 29 a = FXARGB_A(argb);
30 a = FXARGB_A(argb); 30 r = FXARGB_R(argb);
31 rgb = FXSYS_RGB(FXARGB_R(argb), FXARGB_G(argb), FXARGB_B(argb)); 31 g = FXARGB_G(argb);
32 } 32 b = FXARGB_B(argb);
33 FX_DWORD ArgbEncode(int a, FX_COLORREF rgb) 33 }
34 { 34 void ArgbDecode(FX_DWORD argb, int& a, FX_COLORREF& rgb) {
35 return FXARGB_MAKE(a, FXSYS_GetRValue(rgb), FXSYS_GetGValue(rgb), FXSYS_GetB Value(rgb)); 35 a = FXARGB_A(argb);
36 } 36 rgb = FXSYS_RGB(FXARGB_R(argb), FXARGB_G(argb), FXARGB_B(argb));
37 CFX_DIBSource::CFX_DIBSource() 37 }
38 { 38 FX_DWORD ArgbEncode(int a, FX_COLORREF rgb) {
39 m_bpp = 0; 39 return FXARGB_MAKE(a, FXSYS_GetRValue(rgb), FXSYS_GetGValue(rgb),
40 m_AlphaFlag = 0; 40 FXSYS_GetBValue(rgb));
41 m_Width = m_Height = 0; 41 }
42 m_Pitch = 0; 42 CFX_DIBSource::CFX_DIBSource() {
43 m_bpp = 0;
44 m_AlphaFlag = 0;
45 m_Width = m_Height = 0;
46 m_Pitch = 0;
47 m_pPalette = NULL;
48 m_pAlphaMask = NULL;
49 }
50 CFX_DIBSource::~CFX_DIBSource() {
51 if (m_pPalette) {
52 FX_Free(m_pPalette);
53 }
54 delete m_pAlphaMask;
55 }
56 CFX_DIBitmap::CFX_DIBitmap() {
57 m_bExtBuf = FALSE;
58 m_pBuffer = NULL;
59 m_pPalette = NULL;
60 }
61 #define _MAX_OOM_LIMIT_ 12000000
62 FX_BOOL CFX_DIBitmap::Create(int width,
63 int height,
64 FXDIB_Format format,
65 uint8_t* pBuffer,
66 int pitch) {
67 m_pBuffer = NULL;
68 m_bpp = (uint8_t)format;
69 m_AlphaFlag = (uint8_t)(format >> 8);
70 m_Width = m_Height = m_Pitch = 0;
71 if (width <= 0 || height <= 0 || pitch < 0) {
72 return FALSE;
73 }
74 if ((INT_MAX - 31) / width < (format & 0xff)) {
75 return FALSE;
76 }
77 if (!pitch) {
78 pitch = (width * (format & 0xff) + 31) / 32 * 4;
79 }
80 if ((1 << 30) / pitch < height) {
81 return FALSE;
82 }
83 if (pBuffer) {
84 m_pBuffer = pBuffer;
85 m_bExtBuf = TRUE;
86 } else {
87 int size = pitch * height + 4;
88 int oomlimit = _MAX_OOM_LIMIT_;
89 if (oomlimit >= 0 && size >= oomlimit) {
90 m_pBuffer = FX_TryAlloc(uint8_t, size);
91 if (m_pBuffer == NULL) {
92 return FALSE;
93 }
94 } else {
95 m_pBuffer = FX_Alloc(uint8_t, size);
96 }
97 }
98 m_Width = width;
99 m_Height = height;
100 m_Pitch = pitch;
101 if (HasAlpha() && format != FXDIB_Argb) {
102 FX_BOOL ret = TRUE;
103 ret = BuildAlphaMask();
104 if (!ret) {
105 if (!m_bExtBuf && m_pBuffer) {
106 FX_Free(m_pBuffer);
107 m_pBuffer = NULL;
108 m_Width = m_Height = m_Pitch = 0;
109 return FALSE;
110 }
111 }
112 }
113 return TRUE;
114 }
115 FX_BOOL CFX_DIBitmap::Copy(const CFX_DIBSource* pSrc) {
116 if (m_pBuffer) {
117 return FALSE;
118 }
119 if (!Create(pSrc->GetWidth(), pSrc->GetHeight(), pSrc->GetFormat())) {
120 return FALSE;
121 }
122 CopyPalette(pSrc->GetPalette());
123 CopyAlphaMask(pSrc->m_pAlphaMask);
124 for (int row = 0; row < pSrc->GetHeight(); row++) {
125 FXSYS_memcpy(m_pBuffer + row * m_Pitch, pSrc->GetScanline(row), m_Pitch);
126 }
127 return TRUE;
128 }
129 CFX_DIBitmap::~CFX_DIBitmap() {
130 if (m_pBuffer && !m_bExtBuf) {
131 FX_Free(m_pBuffer);
132 }
133 m_pBuffer = NULL;
134 }
135 void CFX_DIBitmap::TakeOver(CFX_DIBitmap* pSrcBitmap) {
136 if (m_pBuffer && !m_bExtBuf) {
137 FX_Free(m_pBuffer);
138 }
139 if (m_pPalette) {
140 FX_Free(m_pPalette);
141 }
142 delete m_pAlphaMask;
143 m_pBuffer = pSrcBitmap->m_pBuffer;
144 m_pPalette = pSrcBitmap->m_pPalette;
145 m_pAlphaMask = pSrcBitmap->m_pAlphaMask;
146 pSrcBitmap->m_pBuffer = NULL;
147 pSrcBitmap->m_pPalette = NULL;
148 pSrcBitmap->m_pAlphaMask = NULL;
149 m_bpp = pSrcBitmap->m_bpp;
150 m_bExtBuf = pSrcBitmap->m_bExtBuf;
151 m_AlphaFlag = pSrcBitmap->m_AlphaFlag;
152 m_Width = pSrcBitmap->m_Width;
153 m_Height = pSrcBitmap->m_Height;
154 m_Pitch = pSrcBitmap->m_Pitch;
155 }
156 CFX_DIBitmap* CFX_DIBSource::Clone(const FX_RECT* pClip) const {
157 FX_RECT rect(0, 0, m_Width, m_Height);
158 if (pClip) {
159 rect.Intersect(*pClip);
160 if (rect.IsEmpty()) {
161 return NULL;
162 }
163 }
164 CFX_DIBitmap* pNewBitmap = new CFX_DIBitmap;
165 if (!pNewBitmap->Create(rect.Width(), rect.Height(), GetFormat())) {
166 delete pNewBitmap;
167 return NULL;
168 }
169 pNewBitmap->CopyPalette(m_pPalette);
170 pNewBitmap->CopyAlphaMask(m_pAlphaMask, pClip);
171 if (GetBPP() == 1 && rect.left % 8 != 0) {
172 int left_shift = rect.left % 32;
173 int right_shift = 32 - left_shift;
174 int dword_count = pNewBitmap->m_Pitch / 4;
175 for (int row = rect.top; row < rect.bottom; row++) {
176 FX_DWORD* src_scan = (FX_DWORD*)GetScanline(row) + rect.left / 32;
177 FX_DWORD* dest_scan = (FX_DWORD*)pNewBitmap->GetScanline(row - rect.top);
178 for (int i = 0; i < dword_count; i++) {
179 dest_scan[i] =
180 (src_scan[i] << left_shift) | (src_scan[i + 1] >> right_shift);
181 }
182 }
183 } else {
184 int copy_len = (pNewBitmap->GetWidth() * pNewBitmap->GetBPP() + 7) / 8;
185 if (m_Pitch < (FX_DWORD)copy_len) {
186 copy_len = m_Pitch;
187 }
188 for (int row = rect.top; row < rect.bottom; row++) {
189 const uint8_t* src_scan = GetScanline(row) + rect.left * m_bpp / 8;
190 uint8_t* dest_scan = (uint8_t*)pNewBitmap->GetScanline(row - rect.top);
191 FXSYS_memcpy(dest_scan, src_scan, copy_len);
192 }
193 }
194 return pNewBitmap;
195 }
196 void CFX_DIBSource::BuildPalette() {
197 if (m_pPalette) {
198 return;
199 }
200 if (GetBPP() == 1) {
201 m_pPalette = FX_Alloc(FX_DWORD, 2);
202 if (IsCmykImage()) {
203 m_pPalette[0] = 0xff;
204 m_pPalette[1] = 0;
205 } else {
206 m_pPalette[0] = 0xff000000;
207 m_pPalette[1] = 0xffffffff;
208 }
209 } else if (GetBPP() == 8) {
210 m_pPalette = FX_Alloc(FX_DWORD, 256);
211 if (IsCmykImage()) {
212 for (int i = 0; i < 256; i++) {
213 m_pPalette[i] = 0xff - i;
214 }
215 } else {
216 for (int i = 0; i < 256; i++) {
217 m_pPalette[i] = 0xff000000 | (i * 0x10101);
218 }
219 }
220 }
221 }
222 FX_BOOL CFX_DIBSource::BuildAlphaMask() {
223 if (m_pAlphaMask) {
224 return TRUE;
225 }
226 m_pAlphaMask = new CFX_DIBitmap;
227 if (!m_pAlphaMask->Create(m_Width, m_Height, FXDIB_8bppMask)) {
228 delete m_pAlphaMask;
229 m_pAlphaMask = NULL;
230 return FALSE;
231 }
232 FXSYS_memset(m_pAlphaMask->GetBuffer(), 0xff,
233 m_pAlphaMask->GetHeight() * m_pAlphaMask->GetPitch());
234 return TRUE;
235 }
236 FX_DWORD CFX_DIBSource::GetPaletteEntry(int index) const {
237 ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask());
238 if (m_pPalette) {
239 return m_pPalette[index];
240 }
241 if (IsCmykImage()) {
242 if (GetBPP() == 1) {
243 return index ? 0 : 0xff;
244 }
245 return 0xff - index;
246 }
247 if (GetBPP() == 1) {
248 return index ? 0xffffffff : 0xff000000;
249 }
250 return index * 0x10101 | 0xff000000;
251 }
252 void CFX_DIBSource::SetPaletteEntry(int index, FX_DWORD color) {
253 ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask());
254 if (m_pPalette == NULL) {
255 BuildPalette();
256 }
257 m_pPalette[index] = color;
258 }
259 int CFX_DIBSource::FindPalette(FX_DWORD color) const {
260 ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask());
261 if (m_pPalette == NULL) {
262 if (IsCmykImage()) {
263 if (GetBPP() == 1) {
264 return ((uint8_t)color == 0xff) ? 0 : 1;
265 }
266 return 0xff - (uint8_t)color;
267 }
268 if (GetBPP() == 1) {
269 return ((uint8_t)color == 0xff) ? 1 : 0;
270 }
271 return (uint8_t)color;
272 }
273 int palsize = (1 << GetBPP());
274 for (int i = 0; i < palsize; i++)
275 if (m_pPalette[i] == color) {
276 return i;
277 }
278 return -1;
279 }
280 void CFX_DIBitmap::Clear(FX_DWORD color) {
281 if (m_pBuffer == NULL) {
282 return;
283 }
284 switch (GetFormat()) {
285 case FXDIB_1bppMask:
286 FXSYS_memset(m_pBuffer, (color & 0xff000000) ? 0xff : 0,
287 m_Pitch * m_Height);
288 break;
289 case FXDIB_1bppRgb: {
290 int index = FindPalette(color);
291 FXSYS_memset(m_pBuffer, index ? 0xff : 0, m_Pitch * m_Height);
292 break;
293 }
294 case FXDIB_8bppMask:
295 FXSYS_memset(m_pBuffer, color >> 24, m_Pitch * m_Height);
296 break;
297 case FXDIB_8bppRgb: {
298 int index = FindPalette(color);
299 FXSYS_memset(m_pBuffer, index, m_Pitch * m_Height);
300 break;
301 }
302 case FXDIB_Rgb:
303 case FXDIB_Rgba: {
304 int a, r, g, b;
305 ArgbDecode(color, a, r, g, b);
306 if (r == g && g == b) {
307 FXSYS_memset(m_pBuffer, r, m_Pitch * m_Height);
308 } else {
309 int byte_pos = 0;
310 for (int col = 0; col < m_Width; col++) {
311 m_pBuffer[byte_pos++] = b;
312 m_pBuffer[byte_pos++] = g;
313 m_pBuffer[byte_pos++] = r;
314 }
315 for (int row = 1; row < m_Height; row++) {
316 FXSYS_memcpy(m_pBuffer + row * m_Pitch, m_pBuffer, m_Pitch);
317 }
318 }
319 break;
320 }
321 case FXDIB_Rgb32:
322 case FXDIB_Argb: {
323 color = IsCmykImage() ? FXCMYK_TODIB(color) : FXARGB_TODIB(color);
324 for (int i = 0; i < m_Width; i++) {
325 ((FX_DWORD*)m_pBuffer)[i] = color;
326 }
327 for (int row = 1; row < m_Height; row++) {
328 FXSYS_memcpy(m_pBuffer + row * m_Pitch, m_pBuffer, m_Pitch);
329 }
330 break;
331 }
332 default:
333 break;
334 }
335 }
336 void CFX_DIBSource::GetOverlapRect(int& dest_left,
337 int& dest_top,
338 int& width,
339 int& height,
340 int src_width,
341 int src_height,
342 int& src_left,
343 int& src_top,
344 const CFX_ClipRgn* pClipRgn) {
345 if (width == 0 || height == 0) {
346 return;
347 }
348 ASSERT(width > 0 && height > 0);
349 if (dest_left > m_Width || dest_top > m_Height) {
350 width = 0;
351 height = 0;
352 return;
353 }
354 int x_offset = dest_left - src_left;
355 int y_offset = dest_top - src_top;
356 FX_RECT src_rect(src_left, src_top, src_left + width, src_top + height);
357 FX_RECT src_bound(0, 0, src_width, src_height);
358 src_rect.Intersect(src_bound);
359 FX_RECT dest_rect(src_rect.left + x_offset, src_rect.top + y_offset,
360 src_rect.right + x_offset, src_rect.bottom + y_offset);
361 FX_RECT dest_bound(0, 0, m_Width, m_Height);
362 dest_rect.Intersect(dest_bound);
363 if (pClipRgn) {
364 dest_rect.Intersect(pClipRgn->GetBox());
365 }
366 dest_left = dest_rect.left;
367 dest_top = dest_rect.top;
368 src_left = dest_left - x_offset;
369 src_top = dest_top - y_offset;
370 width = dest_rect.right - dest_rect.left;
371 height = dest_rect.bottom - dest_rect.top;
372 }
373 FX_BOOL CFX_DIBitmap::TransferBitmap(int dest_left,
374 int dest_top,
375 int width,
376 int height,
377 const CFX_DIBSource* pSrcBitmap,
378 int src_left,
379 int src_top,
380 void* pIccTransform) {
381 if (m_pBuffer == NULL) {
382 return FALSE;
383 }
384 GetOverlapRect(dest_left, dest_top, width, height, pSrcBitmap->GetWidth(),
385 pSrcBitmap->GetHeight(), src_left, src_top, NULL);
386 if (width == 0 || height == 0) {
387 return TRUE;
388 }
389 FXDIB_Format dest_format = GetFormat();
390 FXDIB_Format src_format = pSrcBitmap->GetFormat();
391 if (dest_format == src_format && pIccTransform == NULL) {
392 if (GetBPP() == 1) {
393 for (int row = 0; row < height; row++) {
394 uint8_t* dest_scan = m_pBuffer + (dest_top + row) * m_Pitch;
395 const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row);
396 for (int col = 0; col < width; col++) {
397 if (src_scan[(src_left + col) / 8] &
398 (1 << (7 - (src_left + col) % 8))) {
399 dest_scan[(dest_left + col) / 8] |= 1
400 << (7 - (dest_left + col) % 8);
401 } else {
402 dest_scan[(dest_left + col) / 8] &=
403 ~(1 << (7 - (dest_left + col) % 8));
404 }
405 }
406 }
407 } else {
408 int Bpp = GetBPP() / 8;
409 for (int row = 0; row < height; row++) {
410 uint8_t* dest_scan =
411 m_pBuffer + (dest_top + row) * m_Pitch + dest_left * Bpp;
412 const uint8_t* src_scan =
413 pSrcBitmap->GetScanline(src_top + row) + src_left * Bpp;
414 FXSYS_memcpy(dest_scan, src_scan, width * Bpp);
415 }
416 }
417 } else {
418 if (m_pPalette) {
419 return FALSE;
420 }
421 if (m_bpp == 8) {
422 dest_format = FXDIB_8bppMask;
423 }
424 uint8_t* dest_buf =
425 m_pBuffer + dest_top * m_Pitch + dest_left * GetBPP() / 8;
426 FX_DWORD* d_plt = NULL;
427 if (!ConvertBuffer(dest_format, dest_buf, m_Pitch, width, height,
428 pSrcBitmap, src_left, src_top, d_plt, pIccTransform)) {
429 return FALSE;
430 }
431 }
432 return TRUE;
433 }
434 FX_BOOL CFX_DIBitmap::TransferMask(int dest_left,
435 int dest_top,
436 int width,
437 int height,
438 const CFX_DIBSource* pMask,
439 FX_DWORD color,
440 int src_left,
441 int src_top,
442 int alpha_flag,
443 void* pIccTransform) {
444 if (m_pBuffer == NULL) {
445 return FALSE;
446 }
447 ASSERT(HasAlpha() && (m_bpp >= 24));
448 ASSERT(pMask->IsAlphaMask());
449 if (!HasAlpha() || !pMask->IsAlphaMask() || m_bpp < 24) {
450 return FALSE;
451 }
452 GetOverlapRect(dest_left, dest_top, width, height, pMask->GetWidth(),
453 pMask->GetHeight(), src_left, src_top, NULL);
454 if (width == 0 || height == 0) {
455 return TRUE;
456 }
457 int src_bpp = pMask->GetBPP();
458 int alpha;
459 FX_DWORD dst_color;
460 if (alpha_flag >> 8) {
461 alpha = alpha_flag & 0xff;
462 dst_color = FXCMYK_TODIB(color);
463 } else {
464 alpha = FXARGB_A(color);
465 dst_color = FXARGB_TODIB(color);
466 }
467 uint8_t* color_p = (uint8_t*)&dst_color;
468 if (pIccTransform && CFX_GEModule::Get()->GetCodecModule() &&
469 CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) {
470 ICodec_IccModule* pIccModule =
471 CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
472 pIccModule->TranslateScanline(pIccTransform, color_p, color_p, 1);
473 } else {
474 if (alpha_flag >> 8 && !IsCmykImage())
475 AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color),
476 FXSYS_GetYValue(color), FXSYS_GetKValue(color),
477 color_p[2], color_p[1], color_p[0]);
478 else if (!(alpha_flag >> 8) && IsCmykImage()) {
479 return FALSE;
480 }
481 }
482 if (!IsCmykImage()) {
483 color_p[3] = (uint8_t)alpha;
484 }
485 if (GetFormat() == FXDIB_Argb) {
486 for (int row = 0; row < height; row++) {
487 FX_DWORD* dest_pos =
488 (FX_DWORD*)(m_pBuffer + (dest_top + row) * m_Pitch + dest_left * 4);
489 const uint8_t* src_scan = pMask->GetScanline(src_top + row);
490 if (src_bpp == 1) {
491 for (int col = 0; col < width; col++) {
492 int src_bitpos = src_left + col;
493 if (src_scan[src_bitpos / 8] & (1 << (7 - src_bitpos % 8))) {
494 *dest_pos = dst_color;
495 } else {
496 *dest_pos = 0;
497 }
498 dest_pos++;
499 }
500 } else {
501 src_scan += src_left;
502 dst_color = FXARGB_TODIB(dst_color);
503 dst_color &= 0xffffff;
504 for (int col = 0; col < width; col++) {
505 FXARGB_SETDIB(dest_pos++,
506 dst_color | ((alpha * (*src_scan++) / 255) << 24));
507 }
508 }
509 }
510 } else {
511 int comps = m_bpp / 8;
512 for (int row = 0; row < height; row++) {
513 uint8_t* dest_color_pos =
514 m_pBuffer + (dest_top + row) * m_Pitch + dest_left * comps;
515 uint8_t* dest_alpha_pos =
516 (uint8_t*)m_pAlphaMask->GetScanline(dest_top + row) + dest_left;
517 const uint8_t* src_scan = pMask->GetScanline(src_top + row);
518 if (src_bpp == 1) {
519 for (int col = 0; col < width; col++) {
520 int src_bitpos = src_left + col;
521 if (src_scan[src_bitpos / 8] & (1 << (7 - src_bitpos % 8))) {
522 FXSYS_memcpy(dest_color_pos, color_p, comps);
523 *dest_alpha_pos = 0xff;
524 } else {
525 FXSYS_memset(dest_color_pos, 0, comps);
526 *dest_alpha_pos = 0;
527 }
528 dest_color_pos += comps;
529 dest_alpha_pos++;
530 }
531 } else {
532 src_scan += src_left;
533 for (int col = 0; col < width; col++) {
534 FXSYS_memcpy(dest_color_pos, color_p, comps);
535 dest_color_pos += comps;
536 *dest_alpha_pos++ = (alpha * (*src_scan++) / 255);
537 }
538 }
539 }
540 }
541 return TRUE;
542 }
543 void CFX_DIBSource::CopyPalette(const FX_DWORD* pSrc, FX_DWORD size) {
544 if (pSrc == NULL || GetBPP() > 8) {
545 if (m_pPalette) {
546 FX_Free(m_pPalette);
547 }
43 m_pPalette = NULL; 548 m_pPalette = NULL;
44 m_pAlphaMask = NULL; 549 } else {
45 } 550 FX_DWORD pal_size = 1 << GetBPP();
46 CFX_DIBSource::~CFX_DIBSource() 551 if (m_pPalette == NULL) {
47 { 552 m_pPalette = FX_Alloc(FX_DWORD, pal_size);
48 if (m_pPalette) { 553 }
49 FX_Free(m_pPalette); 554 if (pal_size > size) {
50 } 555 pal_size = size;
51 delete m_pAlphaMask; 556 }
52 } 557 FXSYS_memcpy(m_pPalette, pSrc, pal_size * sizeof(FX_DWORD));
53 CFX_DIBitmap::CFX_DIBitmap() 558 }
54 { 559 }
55 m_bExtBuf = FALSE; 560 void CFX_DIBSource::GetPalette(FX_DWORD* pal, int alpha) const {
56 m_pBuffer = NULL; 561 ASSERT(GetBPP() <= 8 && !IsCmykImage());
57 m_pPalette = NULL; 562 if (GetBPP() == 1) {
58 } 563 pal[0] =
59 #define _MAX_OOM_LIMIT_»12000000 564 ((m_pPalette ? m_pPalette[0] : 0xff000000) & 0xffffff) | (alpha << 24);
60 FX_BOOL CFX_DIBitmap::Create(int width, int height, FXDIB_Format format, uint8_t * pBuffer, int pitch) 565 pal[1] =
61 { 566 ((m_pPalette ? m_pPalette[1] : 0xffffffff) & 0xffffff) | (alpha << 24);
62 m_pBuffer = NULL; 567 return;
63 m_bpp = (uint8_t)format; 568 }
64 m_AlphaFlag = (uint8_t)(format >> 8); 569 if (m_pPalette) {
65 m_Width = m_Height = m_Pitch = 0; 570 for (int i = 0; i < 256; i++) {
66 if (width <= 0 || height <= 0 || pitch < 0) { 571 pal[i] = (m_pPalette[i] & 0x00ffffff) | (alpha << 24);
67 return FALSE; 572 }
68 } 573 } else {
69 if ((INT_MAX - 31) / width < (format & 0xff)) { 574 for (int i = 0; i < 256; i++) {
70 return FALSE; 575 pal[i] = (i * 0x10101) | (alpha << 24);
71 } 576 }
72 if (!pitch) { 577 }
73 pitch = (width * (format & 0xff) + 31) / 32 * 4; 578 }
74 } 579 CFX_DIBitmap* CFX_DIBSource::GetAlphaMask(const FX_RECT* pClip) const {
75 if ((1 << 30) / pitch < height) { 580 ASSERT(GetFormat() == FXDIB_Argb);
76 return FALSE; 581 FX_RECT rect(0, 0, m_Width, m_Height);
77 } 582 if (pClip) {
78 if (pBuffer) { 583 rect.Intersect(*pClip);
79 m_pBuffer = pBuffer; 584 if (rect.IsEmpty()) {
80 m_bExtBuf = TRUE; 585 return NULL;
586 }
587 }
588 CFX_DIBitmap* pMask = new CFX_DIBitmap;
589 if (!pMask->Create(rect.Width(), rect.Height(), FXDIB_8bppMask)) {
590 delete pMask;
591 return NULL;
592 }
593 for (int row = rect.top; row < rect.bottom; row++) {
594 const uint8_t* src_scan = GetScanline(row) + rect.left * 4 + 3;
595 uint8_t* dest_scan = (uint8_t*)pMask->GetScanline(row - rect.top);
596 for (int col = rect.left; col < rect.right; col++) {
597 *dest_scan++ = *src_scan;
598 src_scan += 4;
599 }
600 }
601 return pMask;
602 }
603 FX_BOOL CFX_DIBSource::CopyAlphaMask(const CFX_DIBSource* pAlphaMask,
604 const FX_RECT* pClip) {
605 if (!HasAlpha() || GetFormat() == FXDIB_Argb) {
606 return FALSE;
607 }
608 if (pAlphaMask) {
609 FX_RECT rect(0, 0, pAlphaMask->m_Width, pAlphaMask->m_Height);
610 if (pClip) {
611 rect.Intersect(*pClip);
612 if (rect.IsEmpty() || rect.Width() != m_Width ||
613 rect.Height() != m_Height) {
614 return FALSE;
615 }
81 } else { 616 } else {
82 int size = pitch * height + 4; 617 if (pAlphaMask->m_Width != m_Width || pAlphaMask->m_Height != m_Height) {
83 int oomlimit = _MAX_OOM_LIMIT_; 618 return FALSE;
84 if (oomlimit >= 0 && size >= oomlimit) { 619 }
85 m_pBuffer = FX_TryAlloc(uint8_t, size); 620 }
86 if (m_pBuffer == NULL) { 621 for (int row = 0; row < m_Height; row++)
87 return FALSE; 622 FXSYS_memcpy((void*)m_pAlphaMask->GetScanline(row),
88 } 623 pAlphaMask->GetScanline(row + rect.top) + rect.left,
624 m_pAlphaMask->m_Pitch);
625 } else {
626 m_pAlphaMask->Clear(0xff000000);
627 }
628 return TRUE;
629 }
630 const int g_ChannelOffset[] = {0, 2, 1, 0, 0, 1, 2, 3, 3};
631 FX_BOOL CFX_DIBitmap::LoadChannel(FXDIB_Channel destChannel,
632 const CFX_DIBSource* pSrcBitmap,
633 FXDIB_Channel srcChannel) {
634 if (m_pBuffer == NULL) {
635 return FALSE;
636 }
637 CFX_DIBSource* pSrcClone = (CFX_DIBSource*)pSrcBitmap;
638 CFX_DIBitmap* pDst = this;
639 int destOffset, srcOffset;
640 if (srcChannel == FXDIB_Alpha) {
641 if (!pSrcBitmap->HasAlpha() && !pSrcBitmap->IsAlphaMask()) {
642 return FALSE;
643 }
644 if (pSrcBitmap->GetBPP() == 1) {
645 pSrcClone = pSrcBitmap->CloneConvert(FXDIB_8bppMask);
646 if (pSrcClone == NULL) {
647 return FALSE;
648 }
649 }
650 if (pSrcBitmap->GetFormat() == FXDIB_Argb) {
651 srcOffset = 3;
652 } else {
653 srcOffset = 0;
654 }
655 } else {
656 if (pSrcBitmap->IsAlphaMask()) {
657 return FALSE;
658 }
659 if (pSrcBitmap->GetBPP() < 24) {
660 if (pSrcBitmap->IsCmykImage()) {
661 pSrcClone = pSrcBitmap->CloneConvert(
662 (FXDIB_Format)((pSrcBitmap->GetFormat() & 0xff00) | 0x20));
663 } else {
664 pSrcClone = pSrcBitmap->CloneConvert(
665 (FXDIB_Format)((pSrcBitmap->GetFormat() & 0xff00) | 0x18));
666 }
667 if (pSrcClone == NULL) {
668 return FALSE;
669 }
670 }
671 srcOffset = g_ChannelOffset[srcChannel];
672 }
673 if (destChannel == FXDIB_Alpha) {
674 if (IsAlphaMask()) {
675 if (!ConvertFormat(FXDIB_8bppMask)) {
676 if (pSrcClone != pSrcBitmap) {
677 delete pSrcClone;
678 }
679 return FALSE;
680 }
681 destOffset = 0;
682 } else {
683 destOffset = 0;
684 if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) {
685 if (pSrcClone != pSrcBitmap) {
686 delete pSrcClone;
687 }
688 return FALSE;
689 }
690 if (GetFormat() == FXDIB_Argb) {
691 destOffset = 3;
692 }
693 }
694 } else {
695 if (IsAlphaMask()) {
696 if (pSrcClone != pSrcBitmap) {
697 delete pSrcClone;
698 }
699 return FALSE;
700 }
701 if (GetBPP() < 24) {
702 if (HasAlpha()) {
703 if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) {
704 if (pSrcClone != pSrcBitmap) {
705 delete pSrcClone;
706 }
707 return FALSE;
708 }
709 } else
710 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
711 if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb32)) {
712 #else
713 if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb)) {
714 #endif
715 if (pSrcClone != pSrcBitmap) {
716 delete pSrcClone;
717 }
718 return FALSE;
719 }
720 }
721 destOffset = g_ChannelOffset[destChannel];
722 }
723 if (srcChannel == FXDIB_Alpha && pSrcClone->m_pAlphaMask) {
724 CFX_DIBitmap* pAlphaMask = pSrcClone->m_pAlphaMask;
725 if (pSrcClone->GetWidth() != m_Width ||
726 pSrcClone->GetHeight() != m_Height) {
727 if (pAlphaMask) {
728 pAlphaMask = pAlphaMask->StretchTo(m_Width, m_Height);
729 if (pAlphaMask == NULL) {
730 if (pSrcClone != pSrcBitmap) {
731 delete pSrcClone;
732 }
733 return FALSE;
734 }
735 }
736 }
737 if (pSrcClone != pSrcBitmap) {
738 pSrcClone->m_pAlphaMask = NULL;
739 delete pSrcClone;
740 }
741 pSrcClone = pAlphaMask;
742 srcOffset = 0;
743 } else if (pSrcClone->GetWidth() != m_Width ||
744 pSrcClone->GetHeight() != m_Height) {
745 CFX_DIBitmap* pSrcMatched = pSrcClone->StretchTo(m_Width, m_Height);
746 if (pSrcClone != pSrcBitmap) {
747 delete pSrcClone;
748 }
749 if (pSrcMatched == NULL) {
750 return FALSE;
751 }
752 pSrcClone = pSrcMatched;
753 }
754 if (destChannel == FXDIB_Alpha && m_pAlphaMask) {
755 pDst = m_pAlphaMask;
756 destOffset = 0;
757 }
758 int srcBytes = pSrcClone->GetBPP() / 8;
759 int destBytes = pDst->GetBPP() / 8;
760 for (int row = 0; row < m_Height; row++) {
761 uint8_t* dest_pos = (uint8_t*)pDst->GetScanline(row) + destOffset;
762 const uint8_t* src_pos = pSrcClone->GetScanline(row) + srcOffset;
763 for (int col = 0; col < m_Width; col++) {
764 *dest_pos = *src_pos;
765 dest_pos += destBytes;
766 src_pos += srcBytes;
767 }
768 }
769 if (pSrcClone != pSrcBitmap && pSrcClone != pSrcBitmap->m_pAlphaMask) {
770 delete pSrcClone;
771 }
772 return TRUE;
773 }
774 FX_BOOL CFX_DIBitmap::LoadChannel(FXDIB_Channel destChannel, int value) {
775 if (m_pBuffer == NULL) {
776 return FALSE;
777 }
778 int destOffset;
779 if (destChannel == FXDIB_Alpha) {
780 if (IsAlphaMask()) {
781 if (!ConvertFormat(FXDIB_8bppMask)) {
782 return FALSE;
783 }
784 destOffset = 0;
785 } else {
786 destOffset = 0;
787 if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) {
788 return FALSE;
789 }
790 if (GetFormat() == FXDIB_Argb) {
791 destOffset = 3;
792 }
793 }
794 } else {
795 if (IsAlphaMask()) {
796 return FALSE;
797 }
798 if (GetBPP() < 24) {
799 if (HasAlpha()) {
800 if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) {
801 return FALSE;
802 }
803 } else
804 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
805 if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb)) {
806 return FALSE;
807 }
808 #else
809 if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb32)) {
810 return FALSE;
811 }
812 #endif
813 }
814 destOffset = g_ChannelOffset[destChannel];
815 }
816 int Bpp = GetBPP() / 8;
817 if (Bpp == 1) {
818 FXSYS_memset(m_pBuffer, value, m_Height * m_Pitch);
819 return TRUE;
820 }
821 if (destChannel == FXDIB_Alpha && m_pAlphaMask) {
822 FXSYS_memset(m_pAlphaMask->GetBuffer(), value,
823 m_pAlphaMask->GetHeight() * m_pAlphaMask->GetPitch());
824 return TRUE;
825 }
826 for (int row = 0; row < m_Height; row++) {
827 uint8_t* scan_line = m_pBuffer + row * m_Pitch + destOffset;
828 for (int col = 0; col < m_Width; col++) {
829 *scan_line = value;
830 scan_line += Bpp;
831 }
832 }
833 return TRUE;
834 }
835 FX_BOOL CFX_DIBitmap::MultiplyAlpha(const CFX_DIBSource* pSrcBitmap) {
836 if (m_pBuffer == NULL) {
837 return FALSE;
838 }
839 ASSERT(pSrcBitmap->IsAlphaMask());
840 if (!pSrcBitmap->IsAlphaMask()) {
841 return FALSE;
842 }
843 if (!IsAlphaMask() && !HasAlpha()) {
844 return LoadChannel(FXDIB_Alpha, pSrcBitmap, FXDIB_Alpha);
845 }
846 CFX_DIBitmap* pSrcClone = (CFX_DIBitmap*)pSrcBitmap;
847 if (pSrcBitmap->GetWidth() != m_Width ||
848 pSrcBitmap->GetHeight() != m_Height) {
849 pSrcClone = pSrcBitmap->StretchTo(m_Width, m_Height);
850 ASSERT(pSrcClone != NULL);
851 if (pSrcClone == NULL) {
852 return FALSE;
853 }
854 }
855 if (IsAlphaMask()) {
856 if (!ConvertFormat(FXDIB_8bppMask)) {
857 if (pSrcClone != pSrcBitmap) {
858 delete pSrcClone;
859 }
860 return FALSE;
861 }
862 for (int row = 0; row < m_Height; row++) {
863 uint8_t* dest_scan = m_pBuffer + m_Pitch * row;
864 uint8_t* src_scan = pSrcClone->m_pBuffer + pSrcClone->m_Pitch * row;
865 if (pSrcClone->GetBPP() == 1) {
866 for (int col = 0; col < m_Width; col++) {
867 if (!((1 << (7 - col % 8)) & src_scan[col / 8])) {
868 dest_scan[col] = 0;
869 }
870 }
871 } else {
872 for (int col = 0; col < m_Width; col++) {
873 *dest_scan = (*dest_scan) * src_scan[col] / 255;
874 dest_scan++;
875 }
876 }
877 }
878 } else {
879 if (GetFormat() == FXDIB_Argb) {
880 if (pSrcClone->GetBPP() == 1) {
881 if (pSrcClone != pSrcBitmap) {
882 delete pSrcClone;
883 }
884 return FALSE;
885 }
886 for (int row = 0; row < m_Height; row++) {
887 uint8_t* dest_scan = m_pBuffer + m_Pitch * row + 3;
888 uint8_t* src_scan = pSrcClone->m_pBuffer + pSrcClone->m_Pitch * row;
889 for (int col = 0; col < m_Width; col++) {
890 *dest_scan = (*dest_scan) * src_scan[col] / 255;
891 dest_scan += 4;
892 }
893 }
894 } else {
895 m_pAlphaMask->MultiplyAlpha(pSrcClone);
896 }
897 }
898 if (pSrcClone != pSrcBitmap) {
899 delete pSrcClone;
900 }
901 return TRUE;
902 }
903 FX_BOOL CFX_DIBitmap::GetGrayData(void* pIccTransform) {
904 if (m_pBuffer == NULL) {
905 return FALSE;
906 }
907 switch (GetFormat()) {
908 case FXDIB_1bppRgb: {
909 if (m_pPalette == NULL) {
910 return FALSE;
911 }
912 uint8_t gray[2];
913 for (int i = 0; i < 2; i++) {
914 int r = (uint8_t)(m_pPalette[i] >> 16);
915 int g = (uint8_t)(m_pPalette[i] >> 8);
916 int b = (uint8_t)m_pPalette[i];
917 gray[i] = (uint8_t)FXRGB2GRAY(r, g, b);
918 }
919 CFX_DIBitmap* pMask = new CFX_DIBitmap;
920 if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) {
921 delete pMask;
922 return FALSE;
923 }
924 FXSYS_memset(pMask->GetBuffer(), gray[0], pMask->GetPitch() * m_Height);
925 for (int row = 0; row < m_Height; row++) {
926 uint8_t* src_pos = m_pBuffer + row * m_Pitch;
927 uint8_t* dest_pos = (uint8_t*)pMask->GetScanline(row);
928 for (int col = 0; col < m_Width; col++) {
929 if (src_pos[col / 8] & (1 << (7 - col % 8))) {
930 *dest_pos = gray[1];
931 }
932 dest_pos++;
933 }
934 }
935 TakeOver(pMask);
936 delete pMask;
937 break;
938 }
939 case FXDIB_8bppRgb: {
940 if (m_pPalette == NULL) {
941 return FALSE;
942 }
943 uint8_t gray[256];
944 for (int i = 0; i < 256; i++) {
945 int r = (uint8_t)(m_pPalette[i] >> 16);
946 int g = (uint8_t)(m_pPalette[i] >> 8);
947 int b = (uint8_t)m_pPalette[i];
948 gray[i] = (uint8_t)FXRGB2GRAY(r, g, b);
949 }
950 CFX_DIBitmap* pMask = new CFX_DIBitmap;
951 if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) {
952 delete pMask;
953 return FALSE;
954 }
955 for (int row = 0; row < m_Height; row++) {
956 uint8_t* dest_pos = pMask->GetBuffer() + row * pMask->GetPitch();
957 uint8_t* src_pos = m_pBuffer + row * m_Pitch;
958 for (int col = 0; col < m_Width; col++) {
959 *dest_pos++ = gray[*src_pos++];
960 }
961 }
962 TakeOver(pMask);
963 delete pMask;
964 break;
965 }
966 case FXDIB_Rgb: {
967 CFX_DIBitmap* pMask = new CFX_DIBitmap;
968 if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) {
969 delete pMask;
970 return FALSE;
971 }
972 for (int row = 0; row < m_Height; row++) {
973 uint8_t* src_pos = m_pBuffer + row * m_Pitch;
974 uint8_t* dest_pos = pMask->GetBuffer() + row * pMask->GetPitch();
975 for (int col = 0; col < m_Width; col++) {
976 *dest_pos++ = FXRGB2GRAY(src_pos[2], src_pos[1], *src_pos);
977 src_pos += 3;
978 }
979 }
980 TakeOver(pMask);
981 delete pMask;
982 break;
983 }
984 case FXDIB_Rgb32: {
985 CFX_DIBitmap* pMask = new CFX_DIBitmap;
986 if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) {
987 delete pMask;
988 return FALSE;
989 }
990 for (int row = 0; row < m_Height; row++) {
991 uint8_t* src_pos = m_pBuffer + row * m_Pitch;
992 uint8_t* dest_pos = pMask->GetBuffer() + row * pMask->GetPitch();
993 for (int col = 0; col < m_Width; col++) {
994 *dest_pos++ = FXRGB2GRAY(src_pos[2], src_pos[1], *src_pos);
995 src_pos += 4;
996 }
997 }
998 TakeOver(pMask);
999 delete pMask;
1000 break;
1001 }
1002 default:
1003 return FALSE;
1004 }
1005 return TRUE;
1006 }
1007 FX_BOOL CFX_DIBitmap::MultiplyAlpha(int alpha) {
1008 if (m_pBuffer == NULL) {
1009 return FALSE;
1010 }
1011 switch (GetFormat()) {
1012 case FXDIB_1bppMask:
1013 if (!ConvertFormat(FXDIB_8bppMask)) {
1014 return FALSE;
1015 }
1016 MultiplyAlpha(alpha);
1017 break;
1018 case FXDIB_8bppMask: {
1019 for (int row = 0; row < m_Height; row++) {
1020 uint8_t* scan_line = m_pBuffer + row * m_Pitch;
1021 for (int col = 0; col < m_Width; col++) {
1022 scan_line[col] = scan_line[col] * alpha / 255;
1023 }
1024 }
1025 break;
1026 }
1027 case FXDIB_Argb: {
1028 for (int row = 0; row < m_Height; row++) {
1029 uint8_t* scan_line = m_pBuffer + row * m_Pitch + 3;
1030 for (int col = 0; col < m_Width; col++) {
1031 *scan_line = (*scan_line) * alpha / 255;
1032 scan_line += 4;
1033 }
1034 }
1035 break;
1036 }
1037 default:
1038 if (HasAlpha()) {
1039 m_pAlphaMask->MultiplyAlpha(alpha);
1040 } else if (IsCmykImage()) {
1041 if (!ConvertFormat((FXDIB_Format)(GetFormat() | 0x0200))) {
1042 return FALSE;
1043 }
1044 m_pAlphaMask->MultiplyAlpha(alpha);
1045 } else {
1046 if (!ConvertFormat(FXDIB_Argb)) {
1047 return FALSE;
1048 }
1049 MultiplyAlpha(alpha);
1050 }
1051 break;
1052 }
1053 return TRUE;
1054 }
1055 FX_DWORD CFX_DIBitmap::GetPixel(int x, int y) const {
1056 if (m_pBuffer == NULL) {
1057 return 0;
1058 }
1059 uint8_t* pos = m_pBuffer + y * m_Pitch + x * GetBPP() / 8;
1060 switch (GetFormat()) {
1061 case FXDIB_1bppMask: {
1062 if ((*pos) & (1 << (7 - x % 8))) {
1063 return 0xff000000;
1064 }
1065 return 0;
1066 }
1067 case FXDIB_1bppRgb: {
1068 if ((*pos) & (1 << (7 - x % 8))) {
1069 return m_pPalette ? m_pPalette[1] : 0xffffffff;
1070 }
1071 return m_pPalette ? m_pPalette[0] : 0xff000000;
1072 }
1073 case FXDIB_8bppMask:
1074 return (*pos) << 24;
1075 case FXDIB_8bppRgb:
1076 return m_pPalette ? m_pPalette[*pos] : (0xff000000 | ((*pos) * 0x10101));
1077 case FXDIB_Rgb:
1078 case FXDIB_Rgba:
1079 case FXDIB_Rgb32:
1080 return FXARGB_GETDIB(pos) | 0xff000000;
1081 case FXDIB_Argb:
1082 return FXARGB_GETDIB(pos);
1083 default:
1084 break;
1085 }
1086 return 0;
1087 }
1088 void CFX_DIBitmap::SetPixel(int x, int y, FX_DWORD color) {
1089 if (m_pBuffer == NULL) {
1090 return;
1091 }
1092 if (x < 0 || x >= m_Width || y < 0 || y >= m_Height) {
1093 return;
1094 }
1095 uint8_t* pos = m_pBuffer + y * m_Pitch + x * GetBPP() / 8;
1096 switch (GetFormat()) {
1097 case FXDIB_1bppMask:
1098 if (color >> 24) {
1099 *pos |= 1 << (7 - x % 8);
1100 } else {
1101 *pos &= ~(1 << (7 - x % 8));
1102 }
1103 break;
1104 case FXDIB_1bppRgb:
1105 if (m_pPalette) {
1106 if (color == m_pPalette[1]) {
1107 *pos |= 1 << (7 - x % 8);
89 } else { 1108 } else {
90 m_pBuffer = FX_Alloc(uint8_t, size); 1109 *pos &= ~(1 << (7 - x % 8));
91 } 1110 }
92 } 1111 } else {
93 m_Width = width; 1112 if (color == 0xffffffff) {
94 m_Height = height; 1113 *pos |= 1 << (7 - x % 8);
95 m_Pitch = pitch; 1114 } else {
96 if (HasAlpha() && format != FXDIB_Argb) { 1115 *pos &= ~(1 << (7 - x % 8));
97 FX_BOOL ret = TRUE; 1116 }
98 ret = BuildAlphaMask(); 1117 }
99 if (!ret) { 1118 break;
100 if (!m_bExtBuf && m_pBuffer) { 1119 case FXDIB_8bppMask:
101 FX_Free(m_pBuffer); 1120 *pos = (uint8_t)(color >> 24);
102 m_pBuffer = NULL; 1121 break;
103 m_Width = m_Height = m_Pitch = 0; 1122 case FXDIB_8bppRgb: {
104 return FALSE; 1123 if (m_pPalette) {
105 } 1124 for (int i = 0; i < 256; i++) {
106 } 1125 if (m_pPalette[i] == color) {
107 } 1126 *pos = (uint8_t)i;
1127 return;
1128 }
1129 }
1130 *pos = 0;
1131 } else {
1132 *pos = FXRGB2GRAY(FXARGB_R(color), FXARGB_G(color), FXARGB_B(color));
1133 }
1134 break;
1135 }
1136 case FXDIB_Rgb:
1137 case FXDIB_Rgb32: {
1138 int alpha = FXARGB_A(color);
1139 pos[0] = (FXARGB_B(color) * alpha + pos[0] * (255 - alpha)) / 255;
1140 pos[1] = (FXARGB_G(color) * alpha + pos[1] * (255 - alpha)) / 255;
1141 pos[2] = (FXARGB_R(color) * alpha + pos[2] * (255 - alpha)) / 255;
1142 break;
1143 }
1144 case FXDIB_Rgba: {
1145 pos[0] = FXARGB_B(color);
1146 pos[1] = FXARGB_G(color);
1147 pos[2] = FXARGB_R(color);
1148 break;
1149 }
1150 case FXDIB_Argb:
1151 FXARGB_SETDIB(pos, color);
1152 break;
1153 default:
1154 break;
1155 }
1156 }
1157 void CFX_DIBitmap::DownSampleScanline(int line,
1158 uint8_t* dest_scan,
1159 int dest_bpp,
1160 int dest_width,
1161 FX_BOOL bFlipX,
1162 int clip_left,
1163 int clip_width) const {
1164 if (m_pBuffer == NULL) {
1165 return;
1166 }
1167 int src_Bpp = m_bpp / 8;
1168 uint8_t* scanline = m_pBuffer + line * m_Pitch;
1169 if (src_Bpp == 0) {
1170 for (int i = 0; i < clip_width; i++) {
1171 FX_DWORD dest_x = clip_left + i;
1172 FX_DWORD src_x = dest_x * m_Width / dest_width;
1173 if (bFlipX) {
1174 src_x = m_Width - src_x - 1;
1175 }
1176 src_x %= m_Width;
1177 dest_scan[i] = (scanline[src_x / 8] & (1 << (7 - src_x % 8))) ? 255 : 0;
1178 }
1179 } else if (src_Bpp == 1) {
1180 for (int i = 0; i < clip_width; i++) {
1181 FX_DWORD dest_x = clip_left + i;
1182 FX_DWORD src_x = dest_x * m_Width / dest_width;
1183 if (bFlipX) {
1184 src_x = m_Width - src_x - 1;
1185 }
1186 src_x %= m_Width;
1187 int dest_pos = i;
1188 if (m_pPalette) {
1189 if (!IsCmykImage()) {
1190 dest_pos *= 3;
1191 FX_ARGB argb = m_pPalette[scanline[src_x]];
1192 dest_scan[dest_pos] = FXARGB_B(argb);
1193 dest_scan[dest_pos + 1] = FXARGB_G(argb);
1194 dest_scan[dest_pos + 2] = FXARGB_R(argb);
1195 } else {
1196 dest_pos *= 4;
1197 FX_CMYK cmyk = m_pPalette[scanline[src_x]];
1198 dest_scan[dest_pos] = FXSYS_GetCValue(cmyk);
1199 dest_scan[dest_pos + 1] = FXSYS_GetMValue(cmyk);
1200 dest_scan[dest_pos + 2] = FXSYS_GetYValue(cmyk);
1201 dest_scan[dest_pos + 3] = FXSYS_GetKValue(cmyk);
1202 }
1203 } else {
1204 dest_scan[dest_pos] = scanline[src_x];
1205 }
1206 }
1207 } else {
1208 for (int i = 0; i < clip_width; i++) {
1209 FX_DWORD dest_x = clip_left + i;
1210 FX_DWORD src_x =
1211 bFlipX ? (m_Width - dest_x * m_Width / dest_width - 1) * src_Bpp
1212 : (dest_x * m_Width / dest_width) * src_Bpp;
1213 src_x %= m_Width * src_Bpp;
1214 int dest_pos = i * src_Bpp;
1215 for (int b = 0; b < src_Bpp; b++) {
1216 dest_scan[dest_pos + b] = scanline[src_x + b];
1217 }
1218 }
1219 }
1220 }
1221 FX_BOOL CFX_DIBitmap::ConvertColorScale(FX_DWORD forecolor,
1222 FX_DWORD backcolor) {
1223 ASSERT(!IsAlphaMask());
1224 if (m_pBuffer == NULL || IsAlphaMask()) {
1225 return FALSE;
1226 }
1227 int fc, fm, fy, fk, bc, bm, by, bk;
1228 int fr, fg, fb, br, bg, bb;
1229 FX_BOOL isCmykImage = IsCmykImage();
1230 if (isCmykImage) {
1231 fc = FXSYS_GetCValue(forecolor);
1232 fm = FXSYS_GetMValue(forecolor);
1233 fy = FXSYS_GetYValue(forecolor);
1234 fk = FXSYS_GetKValue(forecolor);
1235 bc = FXSYS_GetCValue(backcolor);
1236 bm = FXSYS_GetMValue(backcolor);
1237 by = FXSYS_GetYValue(backcolor);
1238 bk = FXSYS_GetKValue(backcolor);
1239 } else {
1240 fr = FXSYS_GetRValue(forecolor);
1241 fg = FXSYS_GetGValue(forecolor);
1242 fb = FXSYS_GetBValue(forecolor);
1243 br = FXSYS_GetRValue(backcolor);
1244 bg = FXSYS_GetGValue(backcolor);
1245 bb = FXSYS_GetBValue(backcolor);
1246 }
1247 if (m_bpp <= 8) {
1248 if (isCmykImage) {
1249 if (forecolor == 0xff && backcolor == 0 && m_pPalette == NULL) {
1250 return TRUE;
1251 }
1252 } else if (forecolor == 0 && backcolor == 0xffffff && m_pPalette == NULL) {
1253 return TRUE;
1254 }
1255 if (m_pPalette == NULL) {
1256 BuildPalette();
1257 }
1258 int size = 1 << m_bpp;
1259 if (isCmykImage) {
1260 for (int i = 0; i < size; i++) {
1261 uint8_t b, g, r;
1262 AdobeCMYK_to_sRGB1(FXSYS_GetCValue(m_pPalette[i]),
1263 FXSYS_GetMValue(m_pPalette[i]),
1264 FXSYS_GetYValue(m_pPalette[i]),
1265 FXSYS_GetKValue(m_pPalette[i]), r, g, b);
1266 int gray = 255 - FXRGB2GRAY(r, g, b);
1267 m_pPalette[i] = CmykEncode(
1268 bc + (fc - bc) * gray / 255, bm + (fm - bm) * gray / 255,
1269 by + (fy - by) * gray / 255, bk + (fk - bk) * gray / 255);
1270 }
1271 } else
1272 for (int i = 0; i < size; i++) {
1273 int gray = FXRGB2GRAY(FXARGB_R(m_pPalette[i]), FXARGB_G(m_pPalette[i]),
1274 FXARGB_B(m_pPalette[i]));
1275 m_pPalette[i] = FXARGB_MAKE(0xff, br + (fr - br) * gray / 255,
1276 bg + (fg - bg) * gray / 255,
1277 bb + (fb - bb) * gray / 255);
1278 }
108 return TRUE; 1279 return TRUE;
109 } 1280 }
110 FX_BOOL CFX_DIBitmap::Copy(const CFX_DIBSource* pSrc) 1281 if (isCmykImage) {
111 { 1282 if (forecolor == 0xff && backcolor == 0x00) {
112 if (m_pBuffer) { 1283 for (int row = 0; row < m_Height; row++) {
113 return FALSE; 1284 uint8_t* scanline = m_pBuffer + row * m_Pitch;
114 } 1285 for (int col = 0; col < m_Width; col++) {
115 if (!Create(pSrc->GetWidth(), pSrc->GetHeight(), pSrc->GetFormat())) { 1286 uint8_t b, g, r;
116 return FALSE; 1287 AdobeCMYK_to_sRGB1(scanline[0], scanline[1], scanline[2], scanline[3],
117 } 1288 r, g, b);
118 CopyPalette(pSrc->GetPalette()); 1289 *scanline++ = 0;
119 CopyAlphaMask(pSrc->m_pAlphaMask); 1290 *scanline++ = 0;
120 for (int row = 0; row < pSrc->GetHeight(); row ++) { 1291 *scanline++ = 0;
121 FXSYS_memcpy(m_pBuffer + row * m_Pitch, pSrc->GetScanline(row), m_Pitch) ; 1292 *scanline++ = 255 - FXRGB2GRAY(r, g, b);
1293 }
1294 }
1295 return TRUE;
1296 }
1297 } else if (forecolor == 0 && backcolor == 0xffffff) {
1298 for (int row = 0; row < m_Height; row++) {
1299 uint8_t* scanline = m_pBuffer + row * m_Pitch;
1300 int gap = m_bpp / 8 - 2;
1301 for (int col = 0; col < m_Width; col++) {
1302 int gray = FXRGB2GRAY(scanline[2], scanline[1], scanline[0]);
1303 *scanline++ = gray;
1304 *scanline++ = gray;
1305 *scanline = gray;
1306 scanline += gap;
1307 }
122 } 1308 }
123 return TRUE; 1309 return TRUE;
124 } 1310 }
125 CFX_DIBitmap::~CFX_DIBitmap() 1311 if (isCmykImage) {
126 { 1312 for (int row = 0; row < m_Height; row++) {
127 if (m_pBuffer && !m_bExtBuf) { 1313 uint8_t* scanline = m_pBuffer + row * m_Pitch;
128 FX_Free(m_pBuffer); 1314 for (int col = 0; col < m_Width; col++) {
129 } 1315 uint8_t b, g, r;
130 m_pBuffer = NULL; 1316 AdobeCMYK_to_sRGB1(scanline[0], scanline[1], scanline[2], scanline[3],
131 } 1317 r, g, b);
132 void CFX_DIBitmap::TakeOver(CFX_DIBitmap* pSrcBitmap) 1318 int gray = 255 - FXRGB2GRAY(r, g, b);
133 { 1319 *scanline++ = bc + (fc - bc) * gray / 255;
134 if (m_pBuffer && !m_bExtBuf) { 1320 *scanline++ = bm + (fm - bm) * gray / 255;
135 FX_Free(m_pBuffer); 1321 *scanline++ = by + (fy - by) * gray / 255;
136 } 1322 *scanline++ = bk + (fk - bk) * gray / 255;
137 if (m_pPalette) { 1323 }
138 FX_Free(m_pPalette); 1324 }
139 } 1325 } else {
140 delete m_pAlphaMask; 1326 for (int row = 0; row < m_Height; row++) {
141 m_pBuffer = pSrcBitmap->m_pBuffer; 1327 uint8_t* scanline = m_pBuffer + row * m_Pitch;
142 m_pPalette = pSrcBitmap->m_pPalette; 1328 int gap = m_bpp / 8 - 2;
143 m_pAlphaMask = pSrcBitmap->m_pAlphaMask; 1329 for (int col = 0; col < m_Width; col++) {
144 pSrcBitmap->m_pBuffer = NULL; 1330 int gray = FXRGB2GRAY(scanline[2], scanline[1], scanline[0]);
145 pSrcBitmap->m_pPalette = NULL; 1331 *scanline++ = bb + (fb - bb) * gray / 255;
146 pSrcBitmap->m_pAlphaMask = NULL; 1332 *scanline++ = bg + (fg - bg) * gray / 255;
147 m_bpp = pSrcBitmap->m_bpp; 1333 *scanline = br + (fr - br) * gray / 255;
148 m_bExtBuf = pSrcBitmap->m_bExtBuf; 1334 scanline += gap;
149 m_AlphaFlag = pSrcBitmap->m_AlphaFlag; 1335 }
150 m_Width = pSrcBitmap->m_Width; 1336 }
151 m_Height = pSrcBitmap->m_Height; 1337 }
152 m_Pitch = pSrcBitmap->m_Pitch; 1338 return TRUE;
153 } 1339 }
154 CFX_DIBitmap* CFX_DIBSource::Clone(const FX_RECT* pClip) const 1340 FX_BOOL CFX_DIBitmap::DitherFS(const FX_DWORD* pPalette,
155 { 1341 int pal_size,
156 FX_RECT rect(0, 0, m_Width, m_Height); 1342 const FX_RECT* pRect) {
157 if (pClip) { 1343 if (m_pBuffer == NULL) {
158 rect.Intersect(*pClip); 1344 return FALSE;
159 if (rect.IsEmpty()) { 1345 }
160 return NULL; 1346 if (m_bpp != 8 && m_pPalette != NULL && m_AlphaFlag != 0) {
161 } 1347 return FALSE;
162 } 1348 }
163 CFX_DIBitmap* pNewBitmap = new CFX_DIBitmap; 1349 if (m_Width < 4 && m_Height < 4) {
164 if (!pNewBitmap->Create(rect.Width(), rect.Height(), GetFormat())) { 1350 return FALSE;
165 delete pNewBitmap; 1351 }
166 return NULL; 1352 FX_RECT rect(0, 0, m_Width, m_Height);
167 } 1353 if (pRect) {
168 pNewBitmap->CopyPalette(m_pPalette); 1354 rect.Intersect(*pRect);
169 pNewBitmap->CopyAlphaMask(m_pAlphaMask, pClip); 1355 }
170 if (GetBPP() == 1 && rect.left % 8 != 0) { 1356 uint8_t translate[256];
171 int left_shift = rect.left % 32; 1357 for (int i = 0; i < 256; i++) {
172 int right_shift = 32 - left_shift; 1358 int err2 = 65536;
173 int dword_count = pNewBitmap->m_Pitch / 4; 1359 for (int j = 0; j < pal_size; j++) {
174 for (int row = rect.top; row < rect.bottom; row ++) { 1360 uint8_t entry = (uint8_t)pPalette[j];
175 FX_DWORD* src_scan = (FX_DWORD*)GetScanline(row) + rect.left / 32; 1361 int err = (int)entry - i;
176 FX_DWORD* dest_scan = (FX_DWORD*)pNewBitmap->GetScanline(row - rect. top); 1362 if (err * err < err2) {
177 for (int i = 0; i < dword_count; i ++) { 1363 err2 = err * err;
178 dest_scan[i] = (src_scan[i] << left_shift) | (src_scan[i + 1] >> right_shift); 1364 translate[i] = entry;
179 } 1365 }
1366 }
1367 }
1368 for (int row = rect.top; row < rect.bottom; row++) {
1369 uint8_t* scan = m_pBuffer + row * m_Pitch;
1370 uint8_t* next_scan = m_pBuffer + (row + 1) * m_Pitch;
1371 for (int col = rect.left; col < rect.right; col++) {
1372 int src_pixel = scan[col];
1373 int dest_pixel = translate[src_pixel];
1374 scan[col] = (uint8_t)dest_pixel;
1375 int error = -dest_pixel + src_pixel;
1376 if (col < rect.right - 1) {
1377 int src = scan[col + 1];
1378 src += error * 7 / 16;
1379 if (src > 255) {
1380 scan[col + 1] = 255;
1381 } else if (src < 0) {
1382 scan[col + 1] = 0;
1383 } else {
1384 scan[col + 1] = src;
1385 }
1386 }
1387 if (col < rect.right - 1 && row < rect.bottom - 1) {
1388 int src = next_scan[col + 1];
1389 src += error * 1 / 16;
1390 if (src > 255) {
1391 next_scan[col + 1] = 255;
1392 } else if (src < 0) {
1393 next_scan[col + 1] = 0;
1394 } else {
1395 next_scan[col + 1] = src;
1396 }
1397 }
1398 if (row < rect.bottom - 1) {
1399 int src = next_scan[col];
1400 src += error * 5 / 16;
1401 if (src > 255) {
1402 next_scan[col] = 255;
1403 } else if (src < 0) {
1404 next_scan[col] = 0;
1405 } else {
1406 next_scan[col] = src;
1407 }
1408 }
1409 if (col > rect.left && row < rect.bottom - 1) {
1410 int src = next_scan[col - 1];
1411 src += error * 3 / 16;
1412 if (src > 255) {
1413 next_scan[col - 1] = 255;
1414 } else if (src < 0) {
1415 next_scan[col - 1] = 0;
1416 } else {
1417 next_scan[col - 1] = src;
1418 }
1419 }
1420 }
1421 }
1422 return TRUE;
1423 }
1424 CFX_DIBitmap* CFX_DIBSource::FlipImage(FX_BOOL bXFlip, FX_BOOL bYFlip) const {
1425 CFX_DIBitmap* pFlipped = new CFX_DIBitmap;
1426 if (!pFlipped->Create(m_Width, m_Height, GetFormat())) {
1427 delete pFlipped;
1428 return NULL;
1429 }
1430 pFlipped->CopyPalette(m_pPalette);
1431 uint8_t* pDestBuffer = pFlipped->GetBuffer();
1432 int Bpp = m_bpp / 8;
1433 for (int row = 0; row < m_Height; row++) {
1434 const uint8_t* src_scan = GetScanline(row);
1435 uint8_t* dest_scan =
1436 pDestBuffer + m_Pitch * (bYFlip ? (m_Height - row - 1) : row);
1437 if (!bXFlip) {
1438 FXSYS_memcpy(dest_scan, src_scan, m_Pitch);
1439 continue;
1440 }
1441 if (m_bpp == 1) {
1442 FXSYS_memset(dest_scan, 0, m_Pitch);
1443 for (int col = 0; col < m_Width; col++)
1444 if (src_scan[col / 8] & (1 << (7 - col % 8))) {
1445 int dest_col = m_Width - col - 1;
1446 dest_scan[dest_col / 8] |= (1 << (7 - dest_col % 8));
180 } 1447 }
181 } else { 1448 } else {
182 int copy_len = (pNewBitmap->GetWidth() * pNewBitmap->GetBPP() + 7) / 8; 1449 dest_scan += (m_Width - 1) * Bpp;
183 if (m_Pitch < (FX_DWORD)copy_len) { 1450 if (Bpp == 1) {
184 copy_len = m_Pitch; 1451 for (int col = 0; col < m_Width; col++) {
185 } 1452 *dest_scan = *src_scan;
186 for (int row = rect.top; row < rect.bottom; row ++) { 1453 dest_scan--;
187 const uint8_t* src_scan = GetScanline(row) + rect.left * m_bpp / 8; 1454 src_scan++;
188 uint8_t* dest_scan = (uint8_t*)pNewBitmap->GetScanline(row - rect.to p); 1455 }
189 FXSYS_memcpy(dest_scan, src_scan, copy_len); 1456 } else if (Bpp == 3) {
190 } 1457 for (int col = 0; col < m_Width; col++) {
191 } 1458 dest_scan[0] = src_scan[0];
192 return pNewBitmap; 1459 dest_scan[1] = src_scan[1];
193 } 1460 dest_scan[2] = src_scan[2];
194 void CFX_DIBSource::BuildPalette() 1461 dest_scan -= 3;
195 { 1462 src_scan += 3;
196 if (m_pPalette) { 1463 }
197 return; 1464 } else {
198 } 1465 ASSERT(Bpp == 4);
199 if (GetBPP() == 1) { 1466 for (int col = 0; col < m_Width; col++) {
200 m_pPalette = FX_Alloc(FX_DWORD, 2); 1467 *(FX_DWORD*)dest_scan = *(FX_DWORD*)src_scan;
201 if(IsCmykImage()) { 1468 dest_scan -= 4;
202 m_pPalette[0] = 0xff; 1469 src_scan += 4;
203 m_pPalette[1] = 0; 1470 }
1471 }
1472 }
1473 }
1474 if (m_pAlphaMask) {
1475 pDestBuffer = pFlipped->m_pAlphaMask->GetBuffer();
1476 FX_DWORD dest_pitch = pFlipped->m_pAlphaMask->GetPitch();
1477 for (int row = 0; row < m_Height; row++) {
1478 const uint8_t* src_scan = m_pAlphaMask->GetScanline(row);
1479 uint8_t* dest_scan =
1480 pDestBuffer + dest_pitch * (bYFlip ? (m_Height - row - 1) : row);
1481 if (!bXFlip) {
1482 FXSYS_memcpy(dest_scan, src_scan, dest_pitch);
1483 continue;
1484 }
1485 dest_scan += (m_Width - 1);
1486 for (int col = 0; col < m_Width; col++) {
1487 *dest_scan = *src_scan;
1488 dest_scan--;
1489 src_scan++;
1490 }
1491 }
1492 }
1493 return pFlipped;
1494 }
1495 CFX_DIBExtractor::CFX_DIBExtractor(const CFX_DIBSource* pSrc) {
1496 m_pBitmap = NULL;
1497 if (pSrc->GetBuffer() == NULL) {
1498 m_pBitmap = pSrc->Clone();
1499 } else {
1500 m_pBitmap = new CFX_DIBitmap;
1501 if (!m_pBitmap->Create(pSrc->GetWidth(), pSrc->GetHeight(),
1502 pSrc->GetFormat(), pSrc->GetBuffer())) {
1503 delete m_pBitmap;
1504 m_pBitmap = NULL;
1505 return;
1506 }
1507 m_pBitmap->CopyPalette(pSrc->GetPalette());
1508 m_pBitmap->CopyAlphaMask(pSrc->m_pAlphaMask);
1509 }
1510 }
1511 CFX_DIBExtractor::~CFX_DIBExtractor() {
1512 delete m_pBitmap;
1513 }
1514 CFX_FilteredDIB::CFX_FilteredDIB() {
1515 m_pScanline = NULL;
1516 m_pSrc = NULL;
1517 }
1518 CFX_FilteredDIB::~CFX_FilteredDIB() {
1519 if (m_bAutoDropSrc) {
1520 delete m_pSrc;
1521 }
1522 if (m_pScanline) {
1523 FX_Free(m_pScanline);
1524 }
1525 }
1526 void CFX_FilteredDIB::LoadSrc(const CFX_DIBSource* pSrc, FX_BOOL bAutoDropSrc) {
1527 m_pSrc = pSrc;
1528 m_bAutoDropSrc = bAutoDropSrc;
1529 m_Width = pSrc->GetWidth();
1530 m_Height = pSrc->GetHeight();
1531 FXDIB_Format format = GetDestFormat();
1532 m_bpp = (uint8_t)format;
1533 m_AlphaFlag = (uint8_t)(format >> 8);
1534 m_Pitch = (m_Width * (format & 0xff) + 31) / 32 * 4;
1535 m_pPalette = GetDestPalette();
1536 m_pScanline = FX_Alloc(uint8_t, m_Pitch);
1537 }
1538 const uint8_t* CFX_FilteredDIB::GetScanline(int line) const {
1539 TranslateScanline(m_pScanline, m_pSrc->GetScanline(line));
1540 return m_pScanline;
1541 }
1542 void CFX_FilteredDIB::DownSampleScanline(int line,
1543 uint8_t* dest_scan,
1544 int dest_bpp,
1545 int dest_width,
1546 FX_BOOL bFlipX,
1547 int clip_left,
1548 int clip_width) const {
1549 m_pSrc->DownSampleScanline(line, dest_scan, dest_bpp, dest_width, bFlipX,
1550 clip_left, clip_width);
1551 TranslateDownSamples(dest_scan, dest_scan, clip_width, dest_bpp);
1552 }
1553 CFX_ImageRenderer::CFX_ImageRenderer() {
1554 m_Status = 0;
1555 m_pTransformer = NULL;
1556 m_bRgbByteOrder = FALSE;
1557 m_BlendType = FXDIB_BLEND_NORMAL;
1558 }
1559 CFX_ImageRenderer::~CFX_ImageRenderer() {
1560 delete m_pTransformer;
1561 }
1562 extern FX_RECT _FXDIB_SwapClipBox(FX_RECT& clip,
1563 int width,
1564 int height,
1565 FX_BOOL bFlipX,
1566 FX_BOOL bFlipY);
1567 FX_BOOL CFX_ImageRenderer::Start(CFX_DIBitmap* pDevice,
1568 const CFX_ClipRgn* pClipRgn,
1569 const CFX_DIBSource* pSource,
1570 int bitmap_alpha,
1571 FX_DWORD mask_color,
1572 const CFX_AffineMatrix* pMatrix,
1573 FX_DWORD dib_flags,
1574 FX_BOOL bRgbByteOrder,
1575 int alpha_flag,
1576 void* pIccTransform,
1577 int blend_type) {
1578 m_Matrix = *pMatrix;
1579 CFX_FloatRect image_rect_f = m_Matrix.GetUnitRect();
1580 FX_RECT image_rect = image_rect_f.GetOutterRect();
1581 m_ClipBox = pClipRgn ? pClipRgn->GetBox() : FX_RECT(0, 0, pDevice->GetWidth(),
1582 pDevice->GetHeight());
1583 m_ClipBox.Intersect(image_rect);
1584 if (m_ClipBox.IsEmpty()) {
1585 return FALSE;
1586 }
1587 m_pDevice = pDevice;
1588 m_pClipRgn = pClipRgn;
1589 m_MaskColor = mask_color;
1590 m_BitmapAlpha = bitmap_alpha;
1591 m_Matrix = *pMatrix;
1592 m_Flags = dib_flags;
1593 m_AlphaFlag = alpha_flag;
1594 m_pIccTransform = pIccTransform;
1595 m_bRgbByteOrder = bRgbByteOrder;
1596 m_BlendType = blend_type;
1597 FX_BOOL ret = TRUE;
1598 if ((FXSYS_fabs(m_Matrix.b) >= 0.5f || m_Matrix.a == 0) ||
1599 (FXSYS_fabs(m_Matrix.c) >= 0.5f || m_Matrix.d == 0)) {
1600 if (FXSYS_fabs(m_Matrix.a) < FXSYS_fabs(m_Matrix.b) / 20 &&
1601 FXSYS_fabs(m_Matrix.d) < FXSYS_fabs(m_Matrix.c) / 20 &&
1602 FXSYS_fabs(m_Matrix.a) < 0.5f && FXSYS_fabs(m_Matrix.d) < 0.5f) {
1603 int dest_width = image_rect.Width();
1604 int dest_height = image_rect.Height();
1605 FX_RECT bitmap_clip = m_ClipBox;
1606 bitmap_clip.Offset(-image_rect.left, -image_rect.top);
1607 bitmap_clip = _FXDIB_SwapClipBox(bitmap_clip, dest_width, dest_height,
1608 m_Matrix.c > 0, m_Matrix.b < 0);
1609 m_Composer.Compose(pDevice, pClipRgn, bitmap_alpha, mask_color, m_ClipBox,
1610 TRUE, m_Matrix.c > 0, m_Matrix.b < 0, m_bRgbByteOrder,
1611 alpha_flag, pIccTransform, m_BlendType);
1612 if (!m_Stretcher.Start(&m_Composer, pSource, dest_height, dest_width,
1613 bitmap_clip, dib_flags)) {
1614 return FALSE;
1615 }
1616 m_Status = 1;
1617 return TRUE;
1618 }
1619 m_Status = 2;
1620 m_pTransformer = new CFX_ImageTransformer;
1621 m_pTransformer->Start(pSource, &m_Matrix, dib_flags, &m_ClipBox);
1622 return TRUE;
1623 }
1624 int dest_width = image_rect.Width();
1625 if (m_Matrix.a < 0) {
1626 dest_width = -dest_width;
1627 }
1628 int dest_height = image_rect.Height();
1629 if (m_Matrix.d > 0) {
1630 dest_height = -dest_height;
1631 }
1632 if (dest_width == 0 || dest_height == 0) {
1633 return FALSE;
1634 }
1635 FX_RECT bitmap_clip = m_ClipBox;
1636 bitmap_clip.Offset(-image_rect.left, -image_rect.top);
1637 m_Composer.Compose(pDevice, pClipRgn, bitmap_alpha, mask_color, m_ClipBox,
1638 FALSE, FALSE, FALSE, m_bRgbByteOrder, alpha_flag,
1639 pIccTransform, m_BlendType);
1640 m_Status = 1;
1641 ret = m_Stretcher.Start(&m_Composer, pSource, dest_width, dest_height,
1642 bitmap_clip, dib_flags);
1643 return ret;
1644 }
1645 FX_BOOL CFX_ImageRenderer::Continue(IFX_Pause* pPause) {
1646 if (m_Status == 1) {
1647 return m_Stretcher.Continue(pPause);
1648 }
1649 if (m_Status == 2) {
1650 if (m_pTransformer->Continue(pPause)) {
1651 return TRUE;
1652 }
1653 CFX_DIBitmap* pBitmap = m_pTransformer->m_Storer.Detach();
1654 if (pBitmap == NULL) {
1655 return FALSE;
1656 }
1657 if (pBitmap->GetBuffer() == NULL) {
1658 delete pBitmap;
1659 return FALSE;
1660 }
1661 if (pBitmap->IsAlphaMask()) {
1662 if (m_BitmapAlpha != 255) {
1663 if (m_AlphaFlag >> 8) {
1664 m_AlphaFlag =
1665 (((uint8_t)((m_AlphaFlag & 0xff) * m_BitmapAlpha / 255)) |
1666 ((m_AlphaFlag >> 8) << 8));
204 } else { 1667 } else {
205 m_pPalette[0] = 0xff000000; 1668 m_MaskColor = FXARGB_MUL_ALPHA(m_MaskColor, m_BitmapAlpha);
206 m_pPalette[1] = 0xffffffff; 1669 }
207 } 1670 }
208 } else if (GetBPP() == 8) { 1671 m_pDevice->CompositeMask(m_pTransformer->m_ResultLeft,
209 m_pPalette = FX_Alloc(FX_DWORD, 256); 1672 m_pTransformer->m_ResultTop, pBitmap->GetWidth(),
210 if(IsCmykImage()) { 1673 pBitmap->GetHeight(), pBitmap, m_MaskColor, 0, 0,
211 for (int i = 0; i < 256; i ++) { 1674 m_BlendType, m_pClipRgn, m_bRgbByteOrder,
212 m_pPalette[i] = 0xff - i; 1675 m_AlphaFlag, m_pIccTransform);
213 }
214 } else {
215 for (int i = 0; i < 256; i ++) {
216 m_pPalette[i] = 0xff000000 | (i * 0x10101);
217 }
218 }
219 }
220 }
221 FX_BOOL CFX_DIBSource::BuildAlphaMask()
222 {
223 if (m_pAlphaMask) {
224 return TRUE;
225 }
226 m_pAlphaMask = new CFX_DIBitmap;
227 if (!m_pAlphaMask->Create(m_Width, m_Height, FXDIB_8bppMask)) {
228 delete m_pAlphaMask;
229 m_pAlphaMask = NULL;
230 return FALSE;
231 }
232 FXSYS_memset(m_pAlphaMask->GetBuffer(), 0xff, m_pAlphaMask->GetHeight()*m_pA lphaMask->GetPitch());
233 return TRUE;
234 }
235 FX_DWORD CFX_DIBSource::GetPaletteEntry(int index) const
236 {
237 ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask());
238 if (m_pPalette) {
239 return m_pPalette[index];
240 }
241 if (IsCmykImage()) {
242 if (GetBPP() == 1) {
243 return index ? 0 : 0xff;
244 }
245 return 0xff - index;
246 }
247 if (GetBPP() == 1) {
248 return index ? 0xffffffff : 0xff000000;
249 }
250 return index * 0x10101 | 0xff000000;
251 }
252 void CFX_DIBSource::SetPaletteEntry(int index, FX_DWORD color)
253 {
254 ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask());
255 if (m_pPalette == NULL) {
256 BuildPalette();
257 }
258 m_pPalette[index] = color;
259 }
260 int CFX_DIBSource::FindPalette(FX_DWORD color) const
261 {
262 ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask());
263 if (m_pPalette == NULL) {
264 if (IsCmykImage()) {
265 if (GetBPP() == 1) {
266 return ((uint8_t)color == 0xff) ? 0 : 1;
267 }
268 return 0xff - (uint8_t)color;
269 }
270 if (GetBPP() == 1) {
271 return ((uint8_t)color == 0xff) ? 1 : 0;
272 }
273 return (uint8_t)color;
274 }
275 int palsize = (1 << GetBPP());
276 for (int i = 0; i < palsize; i ++)
277 if (m_pPalette[i] == color) {
278 return i;
279 }
280 return -1;
281 }
282 void CFX_DIBitmap::Clear(FX_DWORD color)
283 {
284 if (m_pBuffer == NULL) {
285 return;
286 }
287 switch (GetFormat()) {
288 case FXDIB_1bppMask:
289 FXSYS_memset(m_pBuffer, (color & 0xff000000) ? 0xff : 0, m_Pitch * m _Height);
290 break;
291 case FXDIB_1bppRgb: {
292 int index = FindPalette(color);
293 FXSYS_memset(m_pBuffer, index ? 0xff : 0, m_Pitch * m_Height);
294 break;
295 }
296 case FXDIB_8bppMask:
297 FXSYS_memset(m_pBuffer, color >> 24, m_Pitch * m_Height);
298 break;
299 case FXDIB_8bppRgb: {
300 int index = FindPalette(color);
301 FXSYS_memset(m_pBuffer, index, m_Pitch * m_Height);
302 break;
303 }
304 case FXDIB_Rgb:
305 case FXDIB_Rgba: {
306 int a, r, g, b;
307 ArgbDecode(color, a, r, g, b);
308 if (r == g && g == b) {
309 FXSYS_memset(m_pBuffer, r, m_Pitch * m_Height);
310 } else {
311 int byte_pos = 0;
312 for (int col = 0; col < m_Width; col ++) {
313 m_pBuffer[byte_pos++] = b;
314 m_pBuffer[byte_pos++] = g;
315 m_pBuffer[byte_pos++] = r;
316 }
317 for (int row = 1; row < m_Height; row ++) {
318 FXSYS_memcpy(m_pBuffer + row * m_Pitch, m_pBuffer, m_Pit ch);
319 }
320 }
321 break;
322 }
323 case FXDIB_Rgb32:
324 case FXDIB_Argb: {
325 color = IsCmykImage() ? FXCMYK_TODIB(color) : FXARGB_TODIB(color );
326 for (int i = 0; i < m_Width; i ++) {
327 ((FX_DWORD*)m_pBuffer)[i] = color;
328 }
329 for (int row = 1; row < m_Height; row ++) {
330 FXSYS_memcpy(m_pBuffer + row * m_Pitch, m_pBuffer, m_Pitch);
331 }
332 break;
333 }
334 default:
335 break;
336 }
337 }
338 void CFX_DIBSource::GetOverlapRect(int& dest_left, int& dest_top, int& width, in t& height,
339 int src_width, int src_height, int& src_left, int& src_top,
340 const CFX_ClipRgn* pClipRgn)
341 {
342 if (width == 0 || height == 0) {
343 return;
344 }
345 ASSERT(width > 0 && height > 0);
346 if (dest_left > m_Width || dest_top > m_Height) {
347 width = 0;
348 height = 0;
349 return;
350 }
351 int x_offset = dest_left - src_left;
352 int y_offset = dest_top - src_top;
353 FX_RECT src_rect(src_left, src_top, src_left + width, src_top + height);
354 FX_RECT src_bound(0, 0, src_width, src_height);
355 src_rect.Intersect(src_bound);
356 FX_RECT dest_rect(src_rect.left + x_offset, src_rect.top + y_offset,
357 src_rect.right + x_offset, src_rect.bottom + y_offset);
358 FX_RECT dest_bound(0, 0, m_Width, m_Height);
359 dest_rect.Intersect(dest_bound);
360 if (pClipRgn) {
361 dest_rect.Intersect(pClipRgn->GetBox());
362 }
363 dest_left = dest_rect.left;
364 dest_top = dest_rect.top;
365 src_left = dest_left - x_offset;
366 src_top = dest_top - y_offset;
367 width = dest_rect.right - dest_rect.left;
368 height = dest_rect.bottom - dest_rect.top;
369 }
370 FX_BOOL CFX_DIBitmap::TransferBitmap(int dest_left, int dest_top, int width, int height,
371 const CFX_DIBSource* pSrcBitmap, int src_le ft, int src_top, void* pIccTransform)
372 {
373 if (m_pBuffer == NULL) {
374 return FALSE;
375 }
376 GetOverlapRect(dest_left, dest_top, width, height, pSrcBitmap->GetWidth(), p SrcBitmap->GetHeight(), src_left, src_top, NULL);
377 if (width == 0 || height == 0) {
378 return TRUE;
379 }
380 FXDIB_Format dest_format = GetFormat();
381 FXDIB_Format src_format = pSrcBitmap->GetFormat();
382 if (dest_format == src_format && pIccTransform == NULL) {
383 if (GetBPP() == 1) {
384 for (int row = 0; row < height; row ++) {
385 uint8_t* dest_scan = m_pBuffer + (dest_top + row) * m_Pitch;
386 const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) ;
387 for (int col = 0; col < width; col ++) {
388 if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
389 dest_scan[(dest_left + col) / 8] |= 1 << (7 - (dest_left + col) % 8);
390 } else {
391 dest_scan[(dest_left + col) / 8] &= ~(1 << (7 - (dest_le ft + col) % 8));
392 }
393 }
394 }
395 } else {
396 int Bpp = GetBPP() / 8;
397 for (int row = 0; row < height; row ++) {
398 uint8_t* dest_scan = m_pBuffer + (dest_top + row) * m_Pitch + de st_left * Bpp;
399 const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * Bpp;
400 FXSYS_memcpy(dest_scan, src_scan, width * Bpp);
401 }
402 }
403 } else { 1676 } else {
404 if (m_pPalette) { 1677 if (m_BitmapAlpha != 255) {
405 return FALSE; 1678 pBitmap->MultiplyAlpha(m_BitmapAlpha);
406 } 1679 }
407 if (m_bpp == 8) { 1680 m_pDevice->CompositeBitmap(
408 dest_format = FXDIB_8bppMask; 1681 m_pTransformer->m_ResultLeft, m_pTransformer->m_ResultTop,
409 } 1682 pBitmap->GetWidth(), pBitmap->GetHeight(), pBitmap, 0, 0, m_BlendType,
410 uint8_t* dest_buf = m_pBuffer + dest_top * m_Pitch + dest_left * GetBPP( ) / 8; 1683 m_pClipRgn, m_bRgbByteOrder, m_pIccTransform);
411 FX_DWORD* d_plt = NULL; 1684 }
412 if(!ConvertBuffer(dest_format, dest_buf, m_Pitch, width, height, pSrcBit map, src_left, src_top, d_plt, pIccTransform)) { 1685 delete pBitmap;
413 return FALSE; 1686 return FALSE;
414 } 1687 }
415 } 1688 return FALSE;
416 return TRUE; 1689 }
417 } 1690 CFX_BitmapStorer::CFX_BitmapStorer() {
418 FX_BOOL CFX_DIBitmap::TransferMask(int dest_left, int dest_top, int width, int h eight, 1691 m_pBitmap = NULL;
419 const CFX_DIBSource* pMask, FX_DWORD color, i nt src_left, int src_top, int alpha_flag, void* pIccTransform) 1692 }
420 { 1693 CFX_BitmapStorer::~CFX_BitmapStorer() {
421 if (m_pBuffer == NULL) { 1694 delete m_pBitmap;
422 return FALSE; 1695 }
423 } 1696 CFX_DIBitmap* CFX_BitmapStorer::Detach() {
424 ASSERT(HasAlpha() && (m_bpp >= 24)); 1697 CFX_DIBitmap* pBitmap = m_pBitmap;
425 ASSERT(pMask->IsAlphaMask()); 1698 m_pBitmap = NULL;
426 if (!HasAlpha() || !pMask->IsAlphaMask() || m_bpp < 24) { 1699 return pBitmap;
427 return FALSE; 1700 }
428 } 1701 void CFX_BitmapStorer::Replace(CFX_DIBitmap* pBitmap) {
429 GetOverlapRect(dest_left, dest_top, width, height, pMask->GetWidth(), pMask- >GetHeight(), src_left, src_top, NULL); 1702 delete m_pBitmap;
430 if (width == 0 || height == 0) { 1703 m_pBitmap = pBitmap;
431 return TRUE; 1704 }
432 } 1705 void CFX_BitmapStorer::ComposeScanline(int line,
433 int src_bpp = pMask->GetBPP(); 1706 const uint8_t* scanline,
434 int alpha; 1707 const uint8_t* scan_extra_alpha) {
435 FX_DWORD dst_color; 1708 uint8_t* dest_buf = (uint8_t*)m_pBitmap->GetScanline(line);
436 if (alpha_flag >> 8) { 1709 uint8_t* dest_alpha_buf =
437 alpha = alpha_flag & 0xff; 1710 m_pBitmap->m_pAlphaMask
438 dst_color = FXCMYK_TODIB(color); 1711 ? (uint8_t*)m_pBitmap->m_pAlphaMask->GetScanline(line)
439 } else { 1712 : NULL;
440 alpha = FXARGB_A(color); 1713 if (dest_buf) {
441 dst_color = FXARGB_TODIB(color); 1714 FXSYS_memcpy(dest_buf, scanline, m_pBitmap->GetPitch());
442 } 1715 }
443 uint8_t* color_p = (uint8_t*)&dst_color; 1716 if (dest_alpha_buf) {
444 if (pIccTransform && CFX_GEModule::Get()->GetCodecModule() && CFX_GEModule:: Get()->GetCodecModule()->GetIccModule()) { 1717 FXSYS_memcpy(dest_alpha_buf, scan_extra_alpha,
445 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->Ge tIccModule(); 1718 m_pBitmap->m_pAlphaMask->GetPitch());
446 pIccModule->TranslateScanline(pIccTransform, color_p, color_p, 1); 1719 }
447 } else { 1720 }
448 if (alpha_flag >> 8 && !IsCmykImage()) 1721 FX_BOOL CFX_BitmapStorer::SetInfo(int width,
449 AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), F XSYS_GetYValue(color), FXSYS_GetKValue(color), 1722 int height,
450 color_p[2], color_p[1], color_p[0]); 1723 FXDIB_Format src_format,
451 else if (!(alpha_flag >> 8) && IsCmykImage()) { 1724 FX_DWORD* pSrcPalette) {
452 return FALSE; 1725 m_pBitmap = new CFX_DIBitmap;
453 } 1726 if (!m_pBitmap->Create(width, height, src_format)) {
454 } 1727 delete m_pBitmap;
455 if(!IsCmykImage()) {
456 color_p[3] = (uint8_t)alpha;
457 }
458 if (GetFormat() == FXDIB_Argb) {
459 for (int row = 0; row < height; row ++) {
460 FX_DWORD* dest_pos = (FX_DWORD*)(m_pBuffer + (dest_top + row) * m_Pi tch + dest_left * 4);
461 const uint8_t* src_scan = pMask->GetScanline(src_top + row);
462 if (src_bpp == 1) {
463 for (int col = 0; col < width; col ++) {
464 int src_bitpos = src_left + col;
465 if (src_scan[src_bitpos / 8] & (1 << (7 - src_bitpos % 8))) {
466 *dest_pos = dst_color;
467 } else {
468 *dest_pos = 0;
469 }
470 dest_pos ++;
471 }
472 } else {
473 src_scan += src_left;
474 dst_color = FXARGB_TODIB(dst_color);
475 dst_color &= 0xffffff;
476 for (int col = 0; col < width; col ++) {
477 FXARGB_SETDIB(dest_pos++, dst_color | ((alpha * (*src_scan++ ) / 255) << 24));
478 }
479 }
480 }
481 } else {
482 int comps = m_bpp / 8;
483 for (int row = 0; row < height; row ++) {
484 uint8_t* dest_color_pos = m_pBuffer + (dest_top + row) * m_Pitch + d est_left * comps;
485 uint8_t* dest_alpha_pos = (uint8_t*)m_pAlphaMask->GetScanline(dest_t op + row) + dest_left;
486 const uint8_t* src_scan = pMask->GetScanline(src_top + row);
487 if (src_bpp == 1) {
488 for (int col = 0; col < width; col ++) {
489 int src_bitpos = src_left + col;
490 if (src_scan[src_bitpos / 8] & (1 << (7 - src_bitpos % 8))) {
491 FXSYS_memcpy(dest_color_pos, color_p, comps);
492 *dest_alpha_pos = 0xff;
493 } else {
494 FXSYS_memset(dest_color_pos, 0, comps);
495 *dest_alpha_pos = 0;
496 }
497 dest_color_pos += comps;
498 dest_alpha_pos ++;
499 }
500 } else {
501 src_scan += src_left;
502 for (int col = 0; col < width; col ++) {
503 FXSYS_memcpy(dest_color_pos, color_p, comps);
504 dest_color_pos += comps;
505 *dest_alpha_pos++ = (alpha * (*src_scan++) / 255);
506 }
507 }
508 }
509 }
510 return TRUE;
511 }
512 void CFX_DIBSource::CopyPalette(const FX_DWORD* pSrc, FX_DWORD size)
513 {
514 if (pSrc == NULL || GetBPP() > 8) {
515 if (m_pPalette) {
516 FX_Free(m_pPalette);
517 }
518 m_pPalette = NULL;
519 } else {
520 FX_DWORD pal_size = 1 << GetBPP();
521 if (m_pPalette == NULL) {
522 m_pPalette = FX_Alloc(FX_DWORD, pal_size);
523 }
524 if (pal_size > size) {
525 pal_size = size;
526 }
527 FXSYS_memcpy(m_pPalette, pSrc, pal_size * sizeof(FX_DWORD));
528 }
529 }
530 void CFX_DIBSource::GetPalette(FX_DWORD* pal, int alpha) const
531 {
532 ASSERT(GetBPP() <= 8 && !IsCmykImage());
533 if (GetBPP() == 1) {
534 pal[0] = ((m_pPalette ? m_pPalette[0] : 0xff000000) & 0xffffff) | (alpha << 24);
535 pal[1] = ((m_pPalette ? m_pPalette[1] : 0xffffffff) & 0xffffff) | (alpha << 24);
536 return;
537 }
538 if (m_pPalette) {
539 for (int i = 0; i < 256; i ++) {
540 pal[i] = (m_pPalette[i] & 0x00ffffff) | (alpha << 24);
541 }
542 } else {
543 for (int i = 0; i < 256; i ++) {
544 pal[i] = (i * 0x10101) | (alpha << 24);
545 }
546 }
547 }
548 CFX_DIBitmap* CFX_DIBSource::GetAlphaMask(const FX_RECT* pClip) const
549 {
550 ASSERT(GetFormat() == FXDIB_Argb);
551 FX_RECT rect(0, 0, m_Width, m_Height);
552 if (pClip) {
553 rect.Intersect(*pClip);
554 if (rect.IsEmpty()) {
555 return NULL;
556 }
557 }
558 CFX_DIBitmap* pMask = new CFX_DIBitmap;
559 if (!pMask->Create(rect.Width(), rect.Height(), FXDIB_8bppMask)) {
560 delete pMask;
561 return NULL;
562 }
563 for (int row = rect.top; row < rect.bottom; row ++) {
564 const uint8_t* src_scan = GetScanline(row) + rect.left * 4 + 3;
565 uint8_t* dest_scan = (uint8_t*)pMask->GetScanline(row - rect.top);
566 for (int col = rect.left; col < rect.right; col ++) {
567 *dest_scan ++ = *src_scan;
568 src_scan += 4;
569 }
570 }
571 return pMask;
572 }
573 FX_BOOL CFX_DIBSource::CopyAlphaMask(const CFX_DIBSource* pAlphaMask, const FX_R ECT* pClip)
574 {
575 if (!HasAlpha() || GetFormat() == FXDIB_Argb) {
576 return FALSE;
577 }
578 if (pAlphaMask) {
579 FX_RECT rect(0, 0, pAlphaMask->m_Width, pAlphaMask->m_Height);
580 if (pClip) {
581 rect.Intersect(*pClip);
582 if (rect.IsEmpty() || rect.Width() != m_Width || rect.Height() != m_ Height) {
583 return FALSE;
584 }
585 } else {
586 if (pAlphaMask->m_Width != m_Width || pAlphaMask->m_Height != m_Heig ht) {
587 return FALSE;
588 }
589 }
590 for (int row = 0; row < m_Height; row ++)
591 FXSYS_memcpy((void*)m_pAlphaMask->GetScanline(row),
592 pAlphaMask->GetScanline(row + rect.top) + rect.left, m_pAlphaMask->m_Pitch);
593 } else {
594 m_pAlphaMask->Clear(0xff000000);
595 }
596 return TRUE;
597 }
598 const int g_ChannelOffset[] = {0, 2, 1, 0, 0, 1, 2, 3, 3};
599 FX_BOOL CFX_DIBitmap::LoadChannel(FXDIB_Channel destChannel, const CFX_DIBSource * pSrcBitmap, FXDIB_Channel srcChannel)
600 {
601 if (m_pBuffer == NULL) {
602 return FALSE;
603 }
604 CFX_DIBSource* pSrcClone = (CFX_DIBSource*)pSrcBitmap;
605 CFX_DIBitmap* pDst = this;
606 int destOffset, srcOffset;
607 if (srcChannel == FXDIB_Alpha) {
608 if (!pSrcBitmap->HasAlpha() && !pSrcBitmap->IsAlphaMask()) {
609 return FALSE;
610 }
611 if (pSrcBitmap->GetBPP() == 1) {
612 pSrcClone = pSrcBitmap->CloneConvert(FXDIB_8bppMask);
613 if (pSrcClone == NULL) {
614 return FALSE;
615 }
616 }
617 if(pSrcBitmap->GetFormat() == FXDIB_Argb) {
618 srcOffset = 3;
619 } else {
620 srcOffset = 0;
621 }
622 } else {
623 if (pSrcBitmap->IsAlphaMask()) {
624 return FALSE;
625 }
626 if (pSrcBitmap->GetBPP() < 24) {
627 if (pSrcBitmap->IsCmykImage()) {
628 pSrcClone = pSrcBitmap->CloneConvert((FXDIB_Format)((pSrcBitmap- >GetFormat() & 0xff00) | 0x20));
629 } else {
630 pSrcClone = pSrcBitmap->CloneConvert((FXDIB_Format)((pSrcBitmap- >GetFormat() & 0xff00) | 0x18));
631 }
632 if (pSrcClone == NULL) {
633 return FALSE;
634 }
635 }
636 srcOffset = g_ChannelOffset[srcChannel];
637 }
638 if (destChannel == FXDIB_Alpha) {
639 if (IsAlphaMask()) {
640 if(!ConvertFormat(FXDIB_8bppMask)) {
641 if (pSrcClone != pSrcBitmap) {
642 delete pSrcClone;
643 }
644 return FALSE;
645 }
646 destOffset = 0;
647 } else {
648 destOffset = 0;
649 if(!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) {
650 if (pSrcClone != pSrcBitmap) {
651 delete pSrcClone;
652 }
653 return FALSE;
654 }
655 if (GetFormat() == FXDIB_Argb) {
656 destOffset = 3;
657 }
658 }
659 } else {
660 if (IsAlphaMask()) {
661 if (pSrcClone != pSrcBitmap) {
662 delete pSrcClone;
663 }
664 return FALSE;
665 }
666 if (GetBPP() < 24) {
667 if (HasAlpha()) {
668 if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) {
669 if (pSrcClone != pSrcBitmap) {
670 delete pSrcClone;
671 }
672 return FALSE;
673 }
674 } else
675 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
676 if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb32)) {
677 #else
678 if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb)) {
679 #endif
680 if (pSrcClone != pSrcBitmap) {
681 delete pSrcClone;
682 }
683 return FALSE;
684 }
685 }
686 destOffset = g_ChannelOffset[destChannel];
687 }
688 if (srcChannel == FXDIB_Alpha && pSrcClone->m_pAlphaMask) {
689 CFX_DIBitmap* pAlphaMask = pSrcClone->m_pAlphaMask;
690 if (pSrcClone->GetWidth() != m_Width || pSrcClone->GetHeight() != m_Heig ht) {
691 if (pAlphaMask) {
692 pAlphaMask = pAlphaMask->StretchTo(m_Width, m_Height);
693 if (pAlphaMask == NULL) {
694 if (pSrcClone != pSrcBitmap) {
695 delete pSrcClone;
696 }
697 return FALSE;
698 }
699 }
700 }
701 if (pSrcClone != pSrcBitmap) {
702 pSrcClone->m_pAlphaMask = NULL;
703 delete pSrcClone;
704 }
705 pSrcClone = pAlphaMask;
706 srcOffset = 0;
707 } else if (pSrcClone->GetWidth() != m_Width || pSrcClone->GetHeight() != m_H eight) {
708 CFX_DIBitmap* pSrcMatched = pSrcClone->StretchTo(m_Width, m_Height);
709 if (pSrcClone != pSrcBitmap) {
710 delete pSrcClone;
711 }
712 if (pSrcMatched == NULL) {
713 return FALSE;
714 }
715 pSrcClone = pSrcMatched;
716 }
717 if (destChannel == FXDIB_Alpha && m_pAlphaMask) {
718 pDst = m_pAlphaMask;
719 destOffset = 0;
720 }
721 int srcBytes = pSrcClone->GetBPP() / 8;
722 int destBytes = pDst->GetBPP() / 8;
723 for (int row = 0; row < m_Height; row ++) {
724 uint8_t* dest_pos = (uint8_t*)pDst->GetScanline(row) + destOffset;
725 const uint8_t* src_pos = pSrcClone->GetScanline(row) + srcOffset;
726 for (int col = 0; col < m_Width; col ++) {
727 *dest_pos = *src_pos;
728 dest_pos += destBytes;
729 src_pos += srcBytes;
730 }
731 }
732 if (pSrcClone != pSrcBitmap && pSrcClone != pSrcBitmap->m_pAlphaMask) {
733 delete pSrcClone;
734 }
735 return TRUE;
736 }
737 FX_BOOL CFX_DIBitmap::LoadChannel(FXDIB_Channel destChannel, int value)
738 {
739 if (m_pBuffer == NULL) {
740 return FALSE;
741 }
742 int destOffset;
743 if (destChannel == FXDIB_Alpha) {
744 if (IsAlphaMask()) {
745 if(!ConvertFormat(FXDIB_8bppMask)) {
746 return FALSE;
747 }
748 destOffset = 0;
749 } else {
750 destOffset = 0;
751 if(!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) {
752 return FALSE;
753 }
754 if (GetFormat() == FXDIB_Argb) {
755 destOffset = 3;
756 }
757 }
758 } else {
759 if (IsAlphaMask()) {
760 return FALSE;
761 }
762 if (GetBPP() < 24) {
763 if (HasAlpha()) {
764 if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) {
765 return FALSE;
766 }
767 } else
768 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
769 if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb)) {
770 return FALSE;
771 }
772 #else
773 if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb32)) {
774 return FALSE;
775 }
776 #endif
777 }
778 destOffset = g_ChannelOffset[destChannel];
779 }
780 int Bpp = GetBPP() / 8;
781 if (Bpp == 1) {
782 FXSYS_memset(m_pBuffer, value, m_Height * m_Pitch);
783 return TRUE;
784 }
785 if (destChannel == FXDIB_Alpha && m_pAlphaMask) {
786 FXSYS_memset(m_pAlphaMask->GetBuffer(), value, m_pAlphaMask->GetHeight() *m_pAlphaMask->GetPitch());
787 return TRUE;
788 }
789 for (int row = 0; row < m_Height; row ++) {
790 uint8_t* scan_line = m_pBuffer + row * m_Pitch + destOffset;
791 for (int col = 0; col < m_Width; col ++) {
792 *scan_line = value;
793 scan_line += Bpp;
794 }
795 }
796 return TRUE;
797 }
798 FX_BOOL CFX_DIBitmap::MultiplyAlpha(const CFX_DIBSource* pSrcBitmap)
799 {
800 if (m_pBuffer == NULL) {
801 return FALSE;
802 }
803 ASSERT(pSrcBitmap->IsAlphaMask());
804 if (!pSrcBitmap->IsAlphaMask()) {
805 return FALSE;
806 }
807 if (!IsAlphaMask() && !HasAlpha()) {
808 return LoadChannel(FXDIB_Alpha, pSrcBitmap, FXDIB_Alpha);
809 }
810 CFX_DIBitmap* pSrcClone = (CFX_DIBitmap*)pSrcBitmap;
811 if (pSrcBitmap->GetWidth() != m_Width || pSrcBitmap->GetHeight() != m_Height ) {
812 pSrcClone = pSrcBitmap->StretchTo(m_Width, m_Height);
813 ASSERT(pSrcClone != NULL);
814 if (pSrcClone == NULL) {
815 return FALSE;
816 }
817 }
818 if (IsAlphaMask()) {
819 if(!ConvertFormat(FXDIB_8bppMask)) {
820 if (pSrcClone != pSrcBitmap) {
821 delete pSrcClone;
822 }
823 return FALSE;
824 }
825 for (int row = 0; row < m_Height; row ++) {
826 uint8_t* dest_scan = m_pBuffer + m_Pitch * row;
827 uint8_t* src_scan = pSrcClone->m_pBuffer + pSrcClone->m_Pitch * row;
828 if (pSrcClone->GetBPP() == 1) {
829 for (int col = 0; col < m_Width; col ++) {
830 if (!((1 << (7 - col % 8)) & src_scan[col / 8])) {
831 dest_scan[col] = 0;
832 }
833 }
834 } else {
835 for (int col = 0; col < m_Width; col ++) {
836 *dest_scan = (*dest_scan) * src_scan[col] / 255;
837 dest_scan ++;
838 }
839 }
840 }
841 } else {
842 if(GetFormat() == FXDIB_Argb) {
843 if (pSrcClone->GetBPP() == 1) {
844 if (pSrcClone != pSrcBitmap) {
845 delete pSrcClone;
846 }
847 return FALSE;
848 }
849 for (int row = 0; row < m_Height; row ++) {
850 uint8_t* dest_scan = m_pBuffer + m_Pitch * row + 3;
851 uint8_t* src_scan = pSrcClone->m_pBuffer + pSrcClone->m_Pitch * row;
852 for (int col = 0; col < m_Width; col ++) {
853 *dest_scan = (*dest_scan) * src_scan[col] / 255;
854 dest_scan += 4;
855 }
856 }
857 } else {
858 m_pAlphaMask->MultiplyAlpha(pSrcClone);
859 }
860 }
861 if (pSrcClone != pSrcBitmap) {
862 delete pSrcClone;
863 }
864 return TRUE;
865 }
866 FX_BOOL CFX_DIBitmap::GetGrayData(void* pIccTransform)
867 {
868 if (m_pBuffer == NULL) {
869 return FALSE;
870 }
871 switch (GetFormat()) {
872 case FXDIB_1bppRgb: {
873 if (m_pPalette == NULL) {
874 return FALSE;
875 }
876 uint8_t gray[2];
877 for (int i = 0; i < 2; i ++) {
878 int r = (uint8_t)(m_pPalette[i] >> 16);
879 int g = (uint8_t)(m_pPalette[i] >> 8);
880 int b = (uint8_t)m_pPalette[i];
881 gray[i] = (uint8_t)FXRGB2GRAY(r, g, b);
882 }
883 CFX_DIBitmap* pMask = new CFX_DIBitmap;
884 if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) {
885 delete pMask;
886 return FALSE;
887 }
888 FXSYS_memset(pMask->GetBuffer(), gray[0], pMask->GetPitch() * m_ Height);
889 for (int row = 0; row < m_Height; row ++) {
890 uint8_t* src_pos = m_pBuffer + row * m_Pitch;
891 uint8_t* dest_pos = (uint8_t*)pMask->GetScanline(row);
892 for (int col = 0; col < m_Width; col ++) {
893 if (src_pos[col / 8] & (1 << (7 - col % 8))) {
894 *dest_pos = gray[1];
895 }
896 dest_pos ++;
897 }
898 }
899 TakeOver(pMask);
900 delete pMask;
901 break;
902 }
903 case FXDIB_8bppRgb: {
904 if (m_pPalette == NULL) {
905 return FALSE;
906 }
907 uint8_t gray[256];
908 for (int i = 0; i < 256; i ++) {
909 int r = (uint8_t)(m_pPalette[i] >> 16);
910 int g = (uint8_t)(m_pPalette[i] >> 8);
911 int b = (uint8_t)m_pPalette[i];
912 gray[i] = (uint8_t)FXRGB2GRAY(r, g, b);
913 }
914 CFX_DIBitmap* pMask = new CFX_DIBitmap;
915 if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) {
916 delete pMask;
917 return FALSE;
918 }
919 for (int row = 0; row < m_Height; row ++) {
920 uint8_t* dest_pos = pMask->GetBuffer() + row * pMask->GetPit ch();
921 uint8_t* src_pos = m_pBuffer + row * m_Pitch;
922 for (int col = 0; col < m_Width; col ++) {
923 *dest_pos ++ = gray[*src_pos ++];
924 }
925 }
926 TakeOver(pMask);
927 delete pMask;
928 break;
929 }
930 case FXDIB_Rgb: {
931 CFX_DIBitmap* pMask = new CFX_DIBitmap;
932 if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) {
933 delete pMask;
934 return FALSE;
935 }
936 for (int row = 0; row < m_Height; row ++) {
937 uint8_t* src_pos = m_pBuffer + row * m_Pitch;
938 uint8_t* dest_pos = pMask->GetBuffer() + row * pMask->GetPit ch();
939 for (int col = 0; col < m_Width; col ++) {
940 *dest_pos ++ = FXRGB2GRAY(src_pos[2], src_pos[1], *src_p os);
941 src_pos += 3;
942 }
943 }
944 TakeOver(pMask);
945 delete pMask;
946 break;
947 }
948 case FXDIB_Rgb32: {
949 CFX_DIBitmap* pMask = new CFX_DIBitmap;
950 if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) {
951 delete pMask;
952 return FALSE;
953 }
954 for (int row = 0; row < m_Height; row ++) {
955 uint8_t* src_pos = m_pBuffer + row * m_Pitch;
956 uint8_t* dest_pos = pMask->GetBuffer() + row * pMask->GetPit ch();
957 for (int col = 0; col < m_Width; col ++) {
958 *dest_pos ++ = FXRGB2GRAY(src_pos[2], src_pos[1], *src_p os);
959 src_pos += 4;
960 }
961 }
962 TakeOver(pMask);
963 delete pMask;
964 break;
965 }
966 default:
967 return FALSE;
968 }
969 return TRUE;
970 }
971 FX_BOOL CFX_DIBitmap::MultiplyAlpha(int alpha)
972 {
973 if (m_pBuffer == NULL) {
974 return FALSE;
975 }
976 switch (GetFormat()) {
977 case FXDIB_1bppMask:
978 if (!ConvertFormat(FXDIB_8bppMask)) {
979 return FALSE;
980 }
981 MultiplyAlpha(alpha);
982 break;
983 case FXDIB_8bppMask: {
984 for (int row = 0; row < m_Height; row ++) {
985 uint8_t* scan_line = m_pBuffer + row * m_Pitch;
986 for (int col = 0; col < m_Width; col ++) {
987 scan_line[col] = scan_line[col] * alpha / 255;
988 }
989 }
990 break;
991 }
992 case FXDIB_Argb: {
993 for (int row = 0; row < m_Height; row ++) {
994 uint8_t* scan_line = m_pBuffer + row * m_Pitch + 3;
995 for (int col = 0; col < m_Width; col ++) {
996 *scan_line = (*scan_line) * alpha / 255;
997 scan_line += 4;
998 }
999 }
1000 break;
1001 }
1002 default:
1003 if (HasAlpha()) {
1004 m_pAlphaMask->MultiplyAlpha(alpha);
1005 } else if (IsCmykImage()) {
1006 if (!ConvertFormat((FXDIB_Format)(GetFormat() | 0x0200))) {
1007 return FALSE;
1008 }
1009 m_pAlphaMask->MultiplyAlpha(alpha);
1010 } else {
1011 if (!ConvertFormat(FXDIB_Argb)) {
1012 return FALSE;
1013 }
1014 MultiplyAlpha(alpha);
1015 }
1016 break;
1017 }
1018 return TRUE;
1019 }
1020 FX_DWORD CFX_DIBitmap::GetPixel(int x, int y) const
1021 {
1022 if (m_pBuffer == NULL) {
1023 return 0;
1024 }
1025 uint8_t* pos = m_pBuffer + y * m_Pitch + x * GetBPP() / 8;
1026 switch (GetFormat()) {
1027 case FXDIB_1bppMask: {
1028 if ((*pos) & (1 << (7 - x % 8))) {
1029 return 0xff000000;
1030 }
1031 return 0;
1032 }
1033 case FXDIB_1bppRgb: {
1034 if ((*pos) & (1 << (7 - x % 8))) {
1035 return m_pPalette ? m_pPalette[1] : 0xffffffff;
1036 }
1037 return m_pPalette ? m_pPalette[0] : 0xff000000;
1038 }
1039 case FXDIB_8bppMask:
1040 return (*pos) << 24;
1041 case FXDIB_8bppRgb:
1042 return m_pPalette ? m_pPalette[*pos] : (0xff000000 | ((*pos) * 0x101 01));
1043 case FXDIB_Rgb:
1044 case FXDIB_Rgba:
1045 case FXDIB_Rgb32:
1046 return FXARGB_GETDIB(pos) | 0xff000000;
1047 case FXDIB_Argb:
1048 return FXARGB_GETDIB(pos);
1049 default:
1050 break;
1051 }
1052 return 0;
1053 }
1054 void CFX_DIBitmap::SetPixel(int x, int y, FX_DWORD color)
1055 {
1056 if (m_pBuffer == NULL) {
1057 return;
1058 }
1059 if (x < 0 || x >= m_Width || y < 0 || y >= m_Height) {
1060 return;
1061 }
1062 uint8_t* pos = m_pBuffer + y * m_Pitch + x * GetBPP() / 8;
1063 switch (GetFormat()) {
1064 case FXDIB_1bppMask:
1065 if (color >> 24) {
1066 *pos |= 1 << (7 - x % 8);
1067 } else {
1068 *pos &= ~(1 << (7 - x % 8));
1069 }
1070 break;
1071 case FXDIB_1bppRgb:
1072 if (m_pPalette) {
1073 if (color == m_pPalette[1]) {
1074 *pos |= 1 << (7 - x % 8);
1075 } else {
1076 *pos &= ~(1 << (7 - x % 8));
1077 }
1078 } else {
1079 if (color == 0xffffffff) {
1080 *pos |= 1 << (7 - x % 8);
1081 } else {
1082 *pos &= ~(1 << (7 - x % 8));
1083 }
1084 }
1085 break;
1086 case FXDIB_8bppMask:
1087 *pos = (uint8_t)(color >> 24);
1088 break;
1089 case FXDIB_8bppRgb: {
1090 if (m_pPalette) {
1091 for (int i = 0; i < 256; i ++) {
1092 if (m_pPalette[i] == color) {
1093 *pos = (uint8_t)i;
1094 return;
1095 }
1096 }
1097 *pos = 0;
1098 } else {
1099 *pos = FXRGB2GRAY(FXARGB_R(color), FXARGB_G(color), FXARGB_B (color));
1100 }
1101 break;
1102 }
1103 case FXDIB_Rgb:
1104 case FXDIB_Rgb32: {
1105 int alpha = FXARGB_A(color);
1106 pos[0] = (FXARGB_B(color) * alpha + pos[0] * (255 - alpha)) / 25 5;
1107 pos[1] = (FXARGB_G(color) * alpha + pos[1] * (255 - alpha)) / 25 5;
1108 pos[2] = (FXARGB_R(color) * alpha + pos[2] * (255 - alpha)) / 25 5;
1109 break;
1110 }
1111 case FXDIB_Rgba: {
1112 pos[0] = FXARGB_B(color);
1113 pos[1] = FXARGB_G(color);
1114 pos[2] = FXARGB_R(color);
1115 break;
1116 }
1117 case FXDIB_Argb:
1118 FXARGB_SETDIB(pos, color);
1119 break;
1120 default:
1121 break;
1122 }
1123 }
1124 void CFX_DIBitmap::DownSampleScanline(int line, uint8_t* dest_scan, int dest_bpp ,
1125 int dest_width, FX_BOOL bFlipX, int clip_l eft, int clip_width) const
1126 {
1127 if (m_pBuffer == NULL) {
1128 return;
1129 }
1130 int src_Bpp = m_bpp / 8;
1131 uint8_t* scanline = m_pBuffer + line * m_Pitch;
1132 if (src_Bpp == 0) {
1133 for (int i = 0; i < clip_width; i ++) {
1134 FX_DWORD dest_x = clip_left + i;
1135 FX_DWORD src_x = dest_x * m_Width / dest_width;
1136 if (bFlipX) {
1137 src_x = m_Width - src_x - 1;
1138 }
1139 src_x %= m_Width;
1140 dest_scan[i] = (scanline[src_x / 8] & (1 << (7 - src_x % 8))) ? 255 : 0;
1141 }
1142 } else if (src_Bpp == 1) {
1143 for (int i = 0; i < clip_width; i ++) {
1144 FX_DWORD dest_x = clip_left + i;
1145 FX_DWORD src_x = dest_x * m_Width / dest_width;
1146 if (bFlipX) {
1147 src_x = m_Width - src_x - 1;
1148 }
1149 src_x %= m_Width;
1150 int dest_pos = i;
1151 if (m_pPalette) {
1152 if (!IsCmykImage()) {
1153 dest_pos *= 3;
1154 FX_ARGB argb = m_pPalette[scanline[src_x]];
1155 dest_scan[dest_pos] = FXARGB_B(argb);
1156 dest_scan[dest_pos + 1] = FXARGB_G(argb);
1157 dest_scan[dest_pos + 2] = FXARGB_R(argb);
1158 } else {
1159 dest_pos *= 4;
1160 FX_CMYK cmyk = m_pPalette[scanline[src_x]];
1161 dest_scan[dest_pos] = FXSYS_GetCValue(cmyk);
1162 dest_scan[dest_pos + 1] = FXSYS_GetMValue(cmyk);
1163 dest_scan[dest_pos + 2] = FXSYS_GetYValue(cmyk);
1164 dest_scan[dest_pos + 3] = FXSYS_GetKValue(cmyk);
1165 }
1166 } else {
1167 dest_scan[dest_pos] = scanline[src_x];
1168 }
1169 }
1170 } else {
1171 for (int i = 0; i < clip_width; i ++) {
1172 FX_DWORD dest_x = clip_left + i;
1173 FX_DWORD src_x = bFlipX ? (m_Width - dest_x * m_Width / dest_width - 1) * src_Bpp : (dest_x * m_Width / dest_width) * src_Bpp;
1174 src_x %= m_Width * src_Bpp;
1175 int dest_pos = i * src_Bpp;
1176 for (int b = 0; b < src_Bpp; b ++) {
1177 dest_scan[dest_pos + b] = scanline[src_x + b];
1178 }
1179 }
1180 }
1181 }
1182 FX_BOOL CFX_DIBitmap::ConvertColorScale(FX_DWORD forecolor, FX_DWORD backcolor)
1183 {
1184 ASSERT(!IsAlphaMask());
1185 if (m_pBuffer == NULL || IsAlphaMask()) {
1186 return FALSE;
1187 }
1188 int fc, fm, fy, fk, bc, bm, by, bk;
1189 int fr, fg, fb, br, bg, bb;
1190 FX_BOOL isCmykImage = IsCmykImage();
1191 if (isCmykImage) {
1192 fc = FXSYS_GetCValue(forecolor);
1193 fm = FXSYS_GetMValue(forecolor);
1194 fy = FXSYS_GetYValue(forecolor);
1195 fk = FXSYS_GetKValue(forecolor);
1196 bc = FXSYS_GetCValue(backcolor);
1197 bm = FXSYS_GetMValue(backcolor);
1198 by = FXSYS_GetYValue(backcolor);
1199 bk = FXSYS_GetKValue(backcolor);
1200 } else {
1201 fr = FXSYS_GetRValue(forecolor);
1202 fg = FXSYS_GetGValue(forecolor);
1203 fb = FXSYS_GetBValue(forecolor);
1204 br = FXSYS_GetRValue(backcolor);
1205 bg = FXSYS_GetGValue(backcolor);
1206 bb = FXSYS_GetBValue(backcolor);
1207 }
1208 if (m_bpp <= 8) {
1209 if (isCmykImage) {
1210 if (forecolor == 0xff && backcolor == 0 && m_pPalette == NULL) {
1211 return TRUE;
1212 }
1213 } else if (forecolor == 0 && backcolor == 0xffffff && m_pPalette == NULL ) {
1214 return TRUE;
1215 }
1216 if (m_pPalette == NULL) {
1217 BuildPalette();
1218 }
1219 int size = 1 << m_bpp;
1220 if (isCmykImage) {
1221 for (int i = 0; i < size; i ++) {
1222 uint8_t b, g, r;
1223 AdobeCMYK_to_sRGB1(FXSYS_GetCValue(m_pPalette[i]), FXSYS_GetMVal ue(m_pPalette[i]), FXSYS_GetYValue(m_pPalette[i]), FXSYS_GetKValue(m_pPalette[i] ),
1224 r, g, b);
1225 int gray = 255 - FXRGB2GRAY(r, g, b);
1226 m_pPalette[i] = CmykEncode(bc + (fc - bc) * gray / 255, bm + (fm - bm) * gray / 255,
1227 by + (fy - by) * gray / 255, bk + (fk - bk) * gray / 255);
1228 }
1229 } else
1230 for (int i = 0; i < size; i ++) {
1231 int gray = FXRGB2GRAY(FXARGB_R(m_pPalette[i]), FXARGB_G(m_pPalet te[i]), FXARGB_B(m_pPalette[i]));
1232 m_pPalette[i] = FXARGB_MAKE(0xff, br + (fr - br) * gray / 255, b g + (fg - bg) * gray / 255,
1233 bb + (fb - bb) * gray / 255);
1234 }
1235 return TRUE;
1236 }
1237 if (isCmykImage) {
1238 if (forecolor == 0xff && backcolor == 0x00) {
1239 for (int row = 0; row < m_Height; row ++) {
1240 uint8_t* scanline = m_pBuffer + row * m_Pitch;
1241 for (int col = 0; col < m_Width; col ++) {
1242 uint8_t b, g, r;
1243 AdobeCMYK_to_sRGB1(scanline[0], scanline[1], scanline[2], sc anline[3],
1244 r, g, b);
1245 *scanline ++ = 0;
1246 *scanline ++ = 0;
1247 *scanline ++ = 0;
1248 *scanline ++ = 255 - FXRGB2GRAY(r, g, b);
1249 }
1250 }
1251 return TRUE;
1252 }
1253 } else if (forecolor == 0 && backcolor == 0xffffff) {
1254 for (int row = 0; row < m_Height; row ++) {
1255 uint8_t* scanline = m_pBuffer + row * m_Pitch;
1256 int gap = m_bpp / 8 - 2;
1257 for (int col = 0; col < m_Width; col ++) {
1258 int gray = FXRGB2GRAY(scanline[2], scanline[1], scanline[0]);
1259 *scanline ++ = gray;
1260 *scanline ++ = gray;
1261 *scanline = gray;
1262 scanline += gap;
1263 }
1264 }
1265 return TRUE;
1266 }
1267 if (isCmykImage) {
1268 for (int row = 0; row < m_Height; row ++) {
1269 uint8_t* scanline = m_pBuffer + row * m_Pitch;
1270 for (int col = 0; col < m_Width; col ++) {
1271 uint8_t b, g, r;
1272 AdobeCMYK_to_sRGB1(scanline[0], scanline[1], scanline[2], scanli ne[3],
1273 r, g, b);
1274 int gray = 255 - FXRGB2GRAY(r, g, b);
1275 *scanline ++ = bc + (fc - bc) * gray / 255;
1276 *scanline ++ = bm + (fm - bm) * gray / 255;
1277 *scanline ++ = by + (fy - by) * gray / 255;
1278 *scanline ++ = bk + (fk - bk) * gray / 255;
1279 }
1280 }
1281 } else {
1282 for (int row = 0; row < m_Height; row ++) {
1283 uint8_t* scanline = m_pBuffer + row * m_Pitch;
1284 int gap = m_bpp / 8 - 2;
1285 for (int col = 0; col < m_Width; col ++) {
1286 int gray = FXRGB2GRAY(scanline[2], scanline[1], scanline[0]);
1287 *scanline ++ = bb + (fb - bb) * gray / 255;
1288 *scanline ++ = bg + (fg - bg) * gray / 255;
1289 *scanline = br + (fr - br) * gray / 255;
1290 scanline += gap;
1291 }
1292 }
1293 }
1294 return TRUE;
1295 }
1296 FX_BOOL CFX_DIBitmap::DitherFS(const FX_DWORD* pPalette, int pal_size, const FX_ RECT* pRect)
1297 {
1298 if (m_pBuffer == NULL) {
1299 return FALSE;
1300 }
1301 if (m_bpp != 8 && m_pPalette != NULL && m_AlphaFlag != 0) {
1302 return FALSE;
1303 }
1304 if (m_Width < 4 && m_Height < 4) {
1305 return FALSE;
1306 }
1307 FX_RECT rect(0, 0, m_Width, m_Height);
1308 if (pRect) {
1309 rect.Intersect(*pRect);
1310 }
1311 uint8_t translate[256];
1312 for (int i = 0; i < 256; i ++) {
1313 int err2 = 65536;
1314 for (int j = 0; j < pal_size; j ++) {
1315 uint8_t entry = (uint8_t)pPalette[j];
1316 int err = (int)entry - i;
1317 if (err * err < err2) {
1318 err2 = err * err;
1319 translate[i] = entry;
1320 }
1321 }
1322 }
1323 for (int row = rect.top; row < rect.bottom; row ++) {
1324 uint8_t* scan = m_pBuffer + row * m_Pitch;
1325 uint8_t* next_scan = m_pBuffer + (row + 1) * m_Pitch;
1326 for (int col = rect.left; col < rect.right; col ++) {
1327 int src_pixel = scan[col];
1328 int dest_pixel = translate[src_pixel];
1329 scan[col] = (uint8_t)dest_pixel;
1330 int error = -dest_pixel + src_pixel;
1331 if (col < rect.right - 1) {
1332 int src = scan[col + 1];
1333 src += error * 7 / 16;
1334 if (src > 255) {
1335 scan[col + 1] = 255;
1336 } else if (src < 0) {
1337 scan[col + 1] = 0;
1338 } else {
1339 scan[col + 1] = src;
1340 }
1341 }
1342 if (col < rect.right - 1 && row < rect.bottom - 1) {
1343 int src = next_scan[col + 1];
1344 src += error * 1 / 16;
1345 if (src > 255) {
1346 next_scan[col + 1] = 255;
1347 } else if (src < 0) {
1348 next_scan[col + 1] = 0;
1349 } else {
1350 next_scan[col + 1] = src;
1351 }
1352 }
1353 if (row < rect.bottom - 1) {
1354 int src = next_scan[col];
1355 src += error * 5 / 16;
1356 if (src > 255) {
1357 next_scan[col] = 255;
1358 } else if (src < 0) {
1359 next_scan[col] = 0;
1360 } else {
1361 next_scan[col] = src;
1362 }
1363 }
1364 if (col > rect.left && row < rect.bottom - 1) {
1365 int src = next_scan[col - 1];
1366 src += error * 3 / 16;
1367 if (src > 255) {
1368 next_scan[col - 1] = 255;
1369 } else if (src < 0) {
1370 next_scan[col - 1] = 0;
1371 } else {
1372 next_scan[col - 1] = src;
1373 }
1374 }
1375 }
1376 }
1377 return TRUE;
1378 }
1379 CFX_DIBitmap* CFX_DIBSource::FlipImage(FX_BOOL bXFlip, FX_BOOL bYFlip) const
1380 {
1381 CFX_DIBitmap* pFlipped = new CFX_DIBitmap;
1382 if (!pFlipped->Create(m_Width, m_Height, GetFormat())) {
1383 delete pFlipped;
1384 return NULL;
1385 }
1386 pFlipped->CopyPalette(m_pPalette);
1387 uint8_t* pDestBuffer = pFlipped->GetBuffer();
1388 int Bpp = m_bpp / 8;
1389 for (int row = 0; row < m_Height; row ++) {
1390 const uint8_t* src_scan = GetScanline(row);
1391 uint8_t* dest_scan = pDestBuffer + m_Pitch * (bYFlip ? (m_Height - row - 1) : row);
1392 if (!bXFlip) {
1393 FXSYS_memcpy(dest_scan, src_scan, m_Pitch);
1394 continue;
1395 }
1396 if (m_bpp == 1) {
1397 FXSYS_memset(dest_scan, 0, m_Pitch);
1398 for (int col = 0; col < m_Width; col ++)
1399 if (src_scan[col / 8] & (1 << (7 - col % 8))) {
1400 int dest_col = m_Width - col - 1;
1401 dest_scan[dest_col / 8] |= (1 << (7 - dest_col % 8));
1402 }
1403 } else {
1404 dest_scan += (m_Width - 1) * Bpp;
1405 if (Bpp == 1) {
1406 for (int col = 0; col < m_Width; col ++) {
1407 *dest_scan = *src_scan;
1408 dest_scan --;
1409 src_scan ++;
1410 }
1411 } else if (Bpp == 3) {
1412 for (int col = 0; col < m_Width; col ++) {
1413 dest_scan[0] = src_scan[0];
1414 dest_scan[1] = src_scan[1];
1415 dest_scan[2] = src_scan[2];
1416 dest_scan -= 3;
1417 src_scan += 3;
1418 }
1419 } else {
1420 ASSERT(Bpp == 4);
1421 for (int col = 0; col < m_Width; col ++) {
1422 *(FX_DWORD*)dest_scan = *(FX_DWORD*)src_scan;
1423 dest_scan -= 4;
1424 src_scan += 4;
1425 }
1426 }
1427 }
1428 }
1429 if (m_pAlphaMask) {
1430 pDestBuffer = pFlipped->m_pAlphaMask->GetBuffer();
1431 FX_DWORD dest_pitch = pFlipped->m_pAlphaMask->GetPitch();
1432 for (int row = 0; row < m_Height; row ++) {
1433 const uint8_t* src_scan = m_pAlphaMask->GetScanline(row);
1434 uint8_t* dest_scan = pDestBuffer + dest_pitch * (bYFlip ? (m_Height - row - 1) : row);
1435 if (!bXFlip) {
1436 FXSYS_memcpy(dest_scan, src_scan, dest_pitch);
1437 continue;
1438 }
1439 dest_scan += (m_Width - 1);
1440 for (int col = 0; col < m_Width; col ++) {
1441 *dest_scan = *src_scan;
1442 dest_scan --;
1443 src_scan ++;
1444 }
1445 }
1446 }
1447 return pFlipped;
1448 }
1449 CFX_DIBExtractor::CFX_DIBExtractor(const CFX_DIBSource* pSrc)
1450 {
1451 m_pBitmap = NULL; 1728 m_pBitmap = NULL;
1452 if (pSrc->GetBuffer() == NULL) { 1729 return FALSE;
1453 m_pBitmap = pSrc->Clone(); 1730 }
1454 } else { 1731 if (pSrcPalette) {
1455 m_pBitmap = new CFX_DIBitmap; 1732 m_pBitmap->CopyPalette(pSrcPalette);
1456 if (!m_pBitmap->Create(pSrc->GetWidth(), pSrc->GetHeight(), pSrc->GetFor mat(), pSrc->GetBuffer())) { 1733 }
1457 delete m_pBitmap; 1734 return TRUE;
1458 m_pBitmap = NULL; 1735 }
1459 return;
1460 }
1461 m_pBitmap->CopyPalette(pSrc->GetPalette());
1462 m_pBitmap->CopyAlphaMask(pSrc->m_pAlphaMask);
1463 }
1464 }
1465 CFX_DIBExtractor::~CFX_DIBExtractor()
1466 {
1467 delete m_pBitmap;
1468 }
1469 CFX_FilteredDIB::CFX_FilteredDIB()
1470 {
1471 m_pScanline = NULL;
1472 m_pSrc = NULL;
1473 }
1474 CFX_FilteredDIB::~CFX_FilteredDIB()
1475 {
1476 if (m_bAutoDropSrc) {
1477 delete m_pSrc;
1478 }
1479 if (m_pScanline) {
1480 FX_Free(m_pScanline);
1481 }
1482 }
1483 void CFX_FilteredDIB::LoadSrc(const CFX_DIBSource* pSrc, FX_BOOL bAutoDropSrc)
1484 {
1485 m_pSrc = pSrc;
1486 m_bAutoDropSrc = bAutoDropSrc;
1487 m_Width = pSrc->GetWidth();
1488 m_Height = pSrc->GetHeight();
1489 FXDIB_Format format = GetDestFormat();
1490 m_bpp = (uint8_t)format;
1491 m_AlphaFlag = (uint8_t)(format >> 8);
1492 m_Pitch = (m_Width * (format & 0xff) + 31) / 32 * 4;
1493 m_pPalette = GetDestPalette();
1494 m_pScanline = FX_Alloc(uint8_t, m_Pitch);
1495 }
1496 const uint8_t* CFX_FilteredDIB::GetScanline(int line) const
1497 {
1498 TranslateScanline(m_pScanline, m_pSrc->GetScanline(line));
1499 return m_pScanline;
1500 }
1501 void CFX_FilteredDIB::DownSampleScanline(int line, uint8_t* dest_scan, int dest_ bpp,
1502 int dest_width, FX_BOOL bFlipX, int clip_left, int clip_width) const
1503 {
1504 m_pSrc->DownSampleScanline(line, dest_scan, dest_bpp, dest_width, bFlipX, cl ip_left, clip_width);
1505 TranslateDownSamples(dest_scan, dest_scan, clip_width, dest_bpp);
1506 }
1507 CFX_ImageRenderer::CFX_ImageRenderer()
1508 {
1509 m_Status = 0;
1510 m_pTransformer = NULL;
1511 m_bRgbByteOrder = FALSE;
1512 m_BlendType = FXDIB_BLEND_NORMAL;
1513 }
1514 CFX_ImageRenderer::~CFX_ImageRenderer()
1515 {
1516 delete m_pTransformer;
1517 }
1518 extern FX_RECT _FXDIB_SwapClipBox(FX_RECT& clip, int width, int height, FX_BOOL bFlipX, FX_BOOL bFlipY);
1519 FX_BOOL CFX_ImageRenderer::Start(CFX_DIBitmap* pDevice, const CFX_ClipRgn* pClip Rgn,
1520 const CFX_DIBSource* pSource, int bitmap_alpha,
1521 FX_DWORD mask_color, const CFX_AffineMatrix* pM atrix,
1522 FX_DWORD dib_flags, FX_BOOL bRgbByteOrder,
1523 int alpha_flag, void* pIccTransform, int blend_ type)
1524 {
1525 m_Matrix = *pMatrix;
1526 CFX_FloatRect image_rect_f = m_Matrix.GetUnitRect();
1527 FX_RECT image_rect = image_rect_f.GetOutterRect();
1528 m_ClipBox = pClipRgn ? pClipRgn->GetBox() : FX_RECT(0, 0, pDevice->GetWidth( ), pDevice->GetHeight());
1529 m_ClipBox.Intersect(image_rect);
1530 if (m_ClipBox.IsEmpty()) {
1531 return FALSE;
1532 }
1533 m_pDevice = pDevice;
1534 m_pClipRgn = pClipRgn;
1535 m_MaskColor = mask_color;
1536 m_BitmapAlpha = bitmap_alpha;
1537 m_Matrix = *pMatrix;
1538 m_Flags = dib_flags;
1539 m_AlphaFlag = alpha_flag;
1540 m_pIccTransform = pIccTransform;
1541 m_bRgbByteOrder = bRgbByteOrder;
1542 m_BlendType = blend_type;
1543 FX_BOOL ret = TRUE;
1544 if ((FXSYS_fabs(m_Matrix.b) >= 0.5f || m_Matrix.a == 0) ||
1545 (FXSYS_fabs(m_Matrix.c) >= 0.5f || m_Matrix.d == 0) ) {
1546 if (FXSYS_fabs(m_Matrix.a) < FXSYS_fabs(m_Matrix.b) / 20 && FXSYS_fabs(m _Matrix.d) < FXSYS_fabs(m_Matrix.c) / 20 &&
1547 FXSYS_fabs(m_Matrix.a) < 0.5f && FXSYS_fabs(m_Matrix.d) < 0.5f) {
1548 int dest_width = image_rect.Width();
1549 int dest_height = image_rect.Height();
1550 FX_RECT bitmap_clip = m_ClipBox;
1551 bitmap_clip.Offset(-image_rect.left, -image_rect.top);
1552 bitmap_clip = _FXDIB_SwapClipBox(bitmap_clip, dest_width, dest_heigh t, m_Matrix.c > 0, m_Matrix.b < 0);
1553 m_Composer.Compose(pDevice, pClipRgn, bitmap_alpha, mask_color, m_Cl ipBox, TRUE,
1554 m_Matrix.c > 0, m_Matrix.b < 0, m_bRgbByteOrder, alpha_flag, pIccTransform, m_BlendType);
1555 if (!m_Stretcher.Start(&m_Composer, pSource, dest_height, dest_width , bitmap_clip, dib_flags)) {
1556 return FALSE;
1557 }
1558 m_Status = 1;
1559 return TRUE;
1560 }
1561 m_Status = 2;
1562 m_pTransformer = new CFX_ImageTransformer;
1563 m_pTransformer->Start(pSource, &m_Matrix, dib_flags, &m_ClipBox);
1564 return TRUE;
1565 }
1566 int dest_width = image_rect.Width();
1567 if (m_Matrix.a < 0) {
1568 dest_width = -dest_width;
1569 }
1570 int dest_height = image_rect.Height();
1571 if (m_Matrix.d > 0) {
1572 dest_height = -dest_height;
1573 }
1574 if (dest_width == 0 || dest_height == 0) {
1575 return FALSE;
1576 }
1577 FX_RECT bitmap_clip = m_ClipBox;
1578 bitmap_clip.Offset(-image_rect.left, -image_rect.top);
1579 m_Composer.Compose(pDevice, pClipRgn, bitmap_alpha, mask_color,
1580 m_ClipBox, FALSE, FALSE, FALSE, m_bRgbByteOrder, alpha_fl ag, pIccTransform, m_BlendType);
1581 m_Status = 1;
1582 ret = m_Stretcher.Start(&m_Composer, pSource, dest_width, dest_height, bitma p_clip, dib_flags);
1583 return ret;
1584 }
1585 FX_BOOL CFX_ImageRenderer::Continue(IFX_Pause* pPause)
1586 {
1587 if (m_Status == 1) {
1588 return m_Stretcher.Continue(pPause);
1589 }
1590 if (m_Status == 2) {
1591 if (m_pTransformer->Continue(pPause)) {
1592 return TRUE;
1593 }
1594 CFX_DIBitmap* pBitmap = m_pTransformer->m_Storer.Detach();
1595 if (pBitmap == NULL) {
1596 return FALSE;
1597 }
1598 if (pBitmap->GetBuffer() == NULL) {
1599 delete pBitmap;
1600 return FALSE;
1601 }
1602 if (pBitmap->IsAlphaMask()) {
1603 if (m_BitmapAlpha != 255) {
1604 if (m_AlphaFlag >> 8) {
1605 m_AlphaFlag = (((uint8_t)((m_AlphaFlag & 0xff) * m_BitmapAlp ha / 255)) | ((m_AlphaFlag >> 8) << 8));
1606 } else {
1607 m_MaskColor = FXARGB_MUL_ALPHA(m_MaskColor, m_BitmapAlpha);
1608 }
1609 }
1610 m_pDevice->CompositeMask(m_pTransformer->m_ResultLeft, m_pTransforme r->m_ResultTop,
1611 pBitmap->GetWidth(), pBitmap->GetHeight(), pBitmap, m_MaskColor,
1612 0, 0, m_BlendType, m_pClipRgn, m_bRgbByteOr der, m_AlphaFlag, m_pIccTransform);
1613 } else {
1614 if (m_BitmapAlpha != 255) {
1615 pBitmap->MultiplyAlpha(m_BitmapAlpha);
1616 }
1617 m_pDevice->CompositeBitmap(m_pTransformer->m_ResultLeft, m_pTransfor mer->m_ResultTop,
1618 pBitmap->GetWidth(), pBitmap->GetHeight() , pBitmap, 0, 0, m_BlendType, m_pClipRgn, m_bRgbByteOrder, m_pIccTransform);
1619 }
1620 delete pBitmap;
1621 return FALSE;
1622 }
1623 return FALSE;
1624 }
1625 CFX_BitmapStorer::CFX_BitmapStorer()
1626 {
1627 m_pBitmap = NULL;
1628 }
1629 CFX_BitmapStorer::~CFX_BitmapStorer()
1630 {
1631 delete m_pBitmap;
1632 }
1633 CFX_DIBitmap* CFX_BitmapStorer::Detach()
1634 {
1635 CFX_DIBitmap* pBitmap = m_pBitmap;
1636 m_pBitmap = NULL;
1637 return pBitmap;
1638 }
1639 void CFX_BitmapStorer::Replace(CFX_DIBitmap* pBitmap)
1640 {
1641 delete m_pBitmap;
1642 m_pBitmap = pBitmap;
1643 }
1644 void CFX_BitmapStorer::ComposeScanline(int line, const uint8_t* scanline, const uint8_t* scan_extra_alpha)
1645 {
1646 uint8_t* dest_buf = (uint8_t*)m_pBitmap->GetScanline(line);
1647 uint8_t* dest_alpha_buf = m_pBitmap->m_pAlphaMask ?
1648 (uint8_t*)m_pBitmap->m_pAlphaMask->GetScanline(li ne) : NULL;
1649 if (dest_buf) {
1650 FXSYS_memcpy(dest_buf, scanline, m_pBitmap->GetPitch());
1651 }
1652 if (dest_alpha_buf) {
1653 FXSYS_memcpy(dest_alpha_buf, scan_extra_alpha, m_pBitmap->m_pAlphaMask-> GetPitch());
1654 }
1655 }
1656 FX_BOOL CFX_BitmapStorer::SetInfo(int width, int height, FXDIB_Format src_format , FX_DWORD* pSrcPalette)
1657 {
1658 m_pBitmap = new CFX_DIBitmap;
1659 if (!m_pBitmap->Create(width, height, src_format)) {
1660 delete m_pBitmap;
1661 m_pBitmap = NULL;
1662 return FALSE;
1663 }
1664 if (pSrcPalette) {
1665 m_pBitmap->CopyPalette(pSrcPalette);
1666 }
1667 return TRUE;
1668 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698