2 * DIB driver primitives.
4 * Copyright 2011 Huw Davies
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "gdi_private.h"
26 #include "wine/debug.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(dib
);
30 /* Bayer matrices for dithering */
32 static const BYTE bayer_4x4
[4][4] =
40 static const BYTE bayer_8x8
[8][8] =
42 { 0, 32, 8, 40, 2, 34, 10, 42 },
43 { 48, 16, 56, 24, 50, 18, 58, 26 },
44 { 12, 44, 4, 36, 14, 46, 6, 38 },
45 { 60, 28, 52, 20, 62, 30, 54, 22 },
46 { 3, 35, 11, 43, 1, 33, 9, 41 },
47 { 51, 19, 59, 27, 49, 17, 57, 25 },
48 { 15, 47, 7, 39, 13, 45, 5, 37 },
49 { 63, 31, 55, 23, 61, 29, 53, 21 }
52 static const BYTE bayer_16x16
[16][16] =
54 { 0, 128, 32, 160, 8, 136, 40, 168, 2, 130, 34, 162, 10, 138, 42, 170 },
55 { 192, 64, 224, 96, 200, 72, 232, 104, 194, 66, 226, 98, 202, 74, 234, 106 },
56 { 48, 176, 16, 144, 56, 184, 24, 152, 50, 178, 18, 146, 58, 186, 26, 154 },
57 { 240, 112, 208, 80, 248, 120, 216, 88, 242, 114, 210, 82, 250, 122, 218, 90 },
58 { 12, 140, 44, 172, 4, 132, 36, 164, 14, 142, 46, 174, 6, 134, 38, 166 },
59 { 204, 76, 236, 108, 196, 68, 228, 100, 206, 78, 238, 110, 198, 70, 230, 102 },
60 { 60, 188, 28, 156, 52, 180, 20, 148, 62, 190, 30, 158, 54, 182, 22, 150 },
61 { 252, 124, 220, 92, 244, 116, 212, 84, 254, 126, 222, 94, 246, 118, 214, 86 },
62 { 3, 131, 35, 163, 11, 139, 43, 171, 1, 129, 33, 161, 9, 137, 41, 169 },
63 { 195, 67, 227, 99, 203, 75, 235, 107, 193, 65, 225, 97, 201, 73, 233, 105 },
64 { 51, 179, 19, 147, 59, 187, 27, 155, 49, 177, 17, 145, 57, 185, 25, 153 },
65 { 243, 115, 211, 83, 251, 123, 219, 91, 241, 113, 209, 81, 249, 121, 217, 89 },
66 { 15, 143, 47, 175, 7, 135, 39, 167, 13, 141, 45, 173, 5, 133, 37, 165 },
67 { 207, 79, 239, 111, 199, 71, 231, 103, 205, 77, 237, 109, 197, 69, 229, 101 },
68 { 63, 191, 31, 159, 55, 183, 23, 151, 61, 189, 29, 157, 53, 181, 21, 149 },
69 { 255, 127, 223, 95, 247, 119, 215, 87, 253, 125, 221, 93, 245, 117, 213, 85 },
72 static inline DWORD
*get_pixel_ptr_32(const dib_info
*dib
, int x
, int y
)
74 return (DWORD
*)((BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
+ (dib
->rect
.left
+ x
) * 4);
77 static inline DWORD
*get_pixel_ptr_24_dword(const dib_info
*dib
, int x
, int y
)
79 return (DWORD
*)((BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
) + (dib
->rect
.left
+ x
) * 3 / 4;
82 static inline BYTE
*get_pixel_ptr_24(const dib_info
*dib
, int x
, int y
)
84 return (BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
+ (dib
->rect
.left
+ x
) * 3;
87 static inline WORD
*get_pixel_ptr_16(const dib_info
*dib
, int x
, int y
)
89 return (WORD
*)((BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
+ (dib
->rect
.left
+ x
) * 2);
92 static inline BYTE
*get_pixel_ptr_8(const dib_info
*dib
, int x
, int y
)
94 return (BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
+ dib
->rect
.left
+ x
;
97 static inline BYTE
*get_pixel_ptr_4(const dib_info
*dib
, int x
, int y
)
99 return (BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
+ (dib
->rect
.left
+ x
) / 2;
102 static inline BYTE
*get_pixel_ptr_1(const dib_info
*dib
, int x
, int y
)
104 return (BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
+ (dib
->rect
.left
+ x
) / 8;
107 static const BYTE pixel_masks_4
[2] = {0xf0, 0x0f};
108 static const BYTE pixel_masks_1
[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
109 static const BYTE edge_masks_1
[8] = {0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01};
111 #define FILTER_DIBINDEX(rgbquad,other_val) \
112 (HIWORD( *(DWORD *)(&rgbquad) ) == 0x10ff ? LOWORD( *(DWORD *)(&rgbquad) ) : (other_val))
114 #define ROPS_WITHOUT_COPY( _d, _s ) \
115 case R2_BLACK: LOOP( (_d) = 0 ) break; \
116 case R2_NOTMERGEPEN: LOOP( (_d) = ~((_d) | (_s)) ) break; \
117 case R2_MASKNOTPEN: LOOP( (_d) &= ~(_s) ) break; \
118 case R2_NOTCOPYPEN: LOOP( (_d) = ~(_s) ) break; \
119 case R2_MASKPENNOT: LOOP( (_d) = (~(_d) & (_s)) ) break; \
120 case R2_NOT: LOOP( (_d) = ~(_d) ) break; \
121 case R2_XORPEN: LOOP( (_d) ^= (_s) ) break; \
122 case R2_NOTMASKPEN: LOOP( (_d) = ~((_d) & (_s)) ) break; \
123 case R2_MASKPEN: LOOP( (_d) &= (_s) ) break; \
124 case R2_NOTXORPEN: LOOP( (_d) = ~((_d) ^ (_s)) ) break; \
125 case R2_NOP: break; \
126 case R2_MERGENOTPEN: LOOP( (_d) = ((_d) | ~(_s)) ) break; \
127 case R2_MERGEPENNOT: LOOP( (_d) = (~(_d) | (_s)) ) break; \
128 case R2_MERGEPEN: LOOP( (_d) |= (_s) ) break; \
129 case R2_WHITE: LOOP( (_d) = ~0 ) break;
131 #define ROPS_ALL( _d, _s ) \
132 case R2_COPYPEN: LOOP( (_d) = (_s) ) break; \
133 ROPS_WITHOUT_COPY( (_d), (_s) )
135 static inline void do_rop_32(DWORD
*ptr
, DWORD
and, DWORD
xor)
137 *ptr
= (*ptr
& and) ^ xor;
140 static inline void do_rop_16(WORD
*ptr
, WORD
and, WORD
xor)
142 *ptr
= (*ptr
& and) ^ xor;
145 static inline void do_rop_8(BYTE
*ptr
, BYTE
and, BYTE
xor)
147 *ptr
= (*ptr
& and) ^ xor;
150 static inline void do_rop_mask_8(BYTE
*ptr
, BYTE
and, BYTE
xor, BYTE mask
)
152 *ptr
= (*ptr
& (and | ~mask
)) ^ (xor & mask
);
155 static inline void do_rop_codes_32(DWORD
*dst
, DWORD src
, struct rop_codes
*codes
)
157 do_rop_32( dst
, (src
& codes
->a1
) ^ codes
->a2
, (src
& codes
->x1
) ^ codes
->x2
);
160 static inline void do_rop_codes_16(WORD
*dst
, WORD src
, struct rop_codes
*codes
)
162 do_rop_16( dst
, (src
& codes
->a1
) ^ codes
->a2
, (src
& codes
->x1
) ^ codes
->x2
);
165 static inline void do_rop_codes_8(BYTE
*dst
, BYTE src
, struct rop_codes
*codes
)
167 do_rop_8( dst
, (src
& codes
->a1
) ^ codes
->a2
, (src
& codes
->x1
) ^ codes
->x2
);
170 static inline void do_rop_codes_mask_8(BYTE
*dst
, BYTE src
, struct rop_codes
*codes
, BYTE mask
)
172 do_rop_mask_8( dst
, (src
& codes
->a1
) ^ codes
->a2
, (src
& codes
->x1
) ^ codes
->x2
, mask
);
175 static inline void do_rop_codes_line_16(WORD
*dst
, const WORD
*src
, struct rop_codes
*codes
, int len
)
177 for (; len
> 0; len
--, src
++, dst
++) do_rop_codes_16( dst
, *src
, codes
);
180 static inline void do_rop_codes_line_rev_16(WORD
*dst
, const WORD
*src
, struct rop_codes
*codes
, int len
)
182 for (src
+= len
- 1, dst
+= len
- 1; len
> 0; len
--, src
--, dst
--)
183 do_rop_codes_16( dst
, *src
, codes
);
186 static inline void do_rop_codes_line_8(BYTE
*dst
, const BYTE
*src
, struct rop_codes
*codes
, int len
)
188 for (; len
> 0; len
--, src
++, dst
++) do_rop_codes_8( dst
, *src
, codes
);
191 static inline void do_rop_codes_line_rev_8(BYTE
*dst
, const BYTE
*src
, struct rop_codes
*codes
, int len
)
193 for (src
+= len
- 1, dst
+= len
- 1; len
> 0; len
--, src
--, dst
--)
194 do_rop_codes_8( dst
, *src
, codes
);
197 static inline void do_rop_codes_line_4(BYTE
*dst
, int dst_x
, const BYTE
*src
, int src_x
,
198 struct rop_codes
*codes
, int len
)
202 for (src
+= src_x
/ 2, dst
+= dst_x
/ 2; len
> 0; len
--, dst_x
++, src_x
++)
206 if (src_x
& 1) src_val
= *src
++;
207 else src_val
= *src
>> 4;
208 do_rop_codes_mask_8( dst
++, src_val
, codes
, 0x0f );
212 if (src_x
& 1) src_val
= *src
++ << 4;
214 do_rop_codes_mask_8( dst
, src_val
, codes
, 0xf0 );
219 static inline void do_rop_codes_line_rev_4(BYTE
*dst
, int dst_x
, const BYTE
*src
, int src_x
,
220 struct rop_codes
*codes
, int len
)
226 for (src
+= src_x
/ 2, dst
+= dst_x
/ 2; len
> 0; len
--, dst_x
--, src_x
--)
230 if (src_x
& 1) src_val
= *src
;
231 else src_val
= *src
-- >> 4;
232 do_rop_codes_mask_8( dst
, src_val
, codes
, 0x0f );
236 if (src_x
& 1) src_val
= *src
<< 4;
237 else src_val
= *src
--;
238 do_rop_codes_mask_8( dst
--, src_val
, codes
, 0xf0 );
243 static inline void memset_32( DWORD
*start
, DWORD val
, DWORD size
)
245 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
247 __asm__
__volatile__( "cld; rep; stosl"
248 : "=c" (dummy
), "=D" (dummy
)
249 : "a" (val
), "0" (size
), "1" (start
) );
251 while (size
--) *start
++ = val
;
255 static inline void memset_16( WORD
*start
, WORD val
, DWORD size
)
257 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
259 __asm__
__volatile__( "cld; rep; stosw"
260 : "=c" (dummy
), "=D" (dummy
)
261 : "a" (val
), "0" (size
), "1" (start
) );
263 while (size
--) *start
++ = val
;
267 static void solid_rects_32(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
272 for(i
= 0; i
< num
; i
++, rc
++)
274 assert( !is_rect_empty( rc
));
276 start
= get_pixel_ptr_32(dib
, rc
->left
, rc
->top
);
278 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
279 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
280 do_rop_32(ptr
++, and, xor);
282 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
283 memset_32( start
, xor, rc
->right
- rc
->left
);
287 static void solid_rects_24(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
290 BYTE
*byte_ptr
, *byte_start
;
292 DWORD and_masks
[3], xor_masks
[3];
294 and_masks
[0] = ( and & 0x00ffffff) | ((and << 24) & 0xff000000);
295 and_masks
[1] = ((and >> 8) & 0x0000ffff) | ((and << 16) & 0xffff0000);
296 and_masks
[2] = ((and >> 16) & 0x000000ff) | ((and << 8) & 0xffffff00);
297 xor_masks
[0] = ( xor & 0x00ffffff) | ((xor << 24) & 0xff000000);
298 xor_masks
[1] = ((xor >> 8) & 0x0000ffff) | ((xor << 16) & 0xffff0000);
299 xor_masks
[2] = ((xor >> 16) & 0x000000ff) | ((xor << 8) & 0xffffff00);
301 for(i
= 0; i
< num
; i
++, rc
++)
303 int left
= dib
->rect
.left
+ rc
->left
;
304 int right
= dib
->rect
.left
+ rc
->right
;
306 assert( !is_rect_empty( rc
));
308 if ((left
& ~3) == (right
& ~3)) /* Special case for lines that start and end in the same DWORD triplet */
310 byte_start
= get_pixel_ptr_24(dib
, rc
->left
, rc
->top
);
311 for(y
= rc
->top
; y
< rc
->bottom
; y
++, byte_start
+= dib
->stride
)
313 for(x
= left
, byte_ptr
= byte_start
; x
< right
; x
++)
315 do_rop_8(byte_ptr
++, and_masks
[0] & 0xff, xor_masks
[0] & 0xff);
316 do_rop_8(byte_ptr
++, and_masks
[1] & 0xff, xor_masks
[1] & 0xff);
317 do_rop_8(byte_ptr
++, and_masks
[2] & 0xff, xor_masks
[2] & 0xff);
323 start
= get_pixel_ptr_24_dword(dib
, rc
->left
, rc
->top
);
324 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
331 do_rop_32(ptr
++, and_masks
[0] | 0x00ffffff, xor_masks
[0] & 0xff000000);
332 do_rop_32(ptr
++, and_masks
[1], xor_masks
[1]);
333 do_rop_32(ptr
++, and_masks
[2], xor_masks
[2]);
336 do_rop_32(ptr
++, and_masks
[1] | 0x0000ffff, xor_masks
[1] & 0xffff0000);
337 do_rop_32(ptr
++, and_masks
[2], xor_masks
[2]);
340 do_rop_32(ptr
++, and_masks
[2] | 0x000000ff, xor_masks
[2] & 0xffffff00);
344 for(x
= (left
+ 3) & ~3; x
< (right
& ~3); x
+= 4)
346 do_rop_32(ptr
++, and_masks
[0], xor_masks
[0]);
347 do_rop_32(ptr
++, and_masks
[1], xor_masks
[1]);
348 do_rop_32(ptr
++, and_masks
[2], xor_masks
[2]);
354 do_rop_32(ptr
, and_masks
[0] | 0xff000000, xor_masks
[0] & 0x00ffffff);
357 do_rop_32(ptr
++, and_masks
[0], xor_masks
[0]);
358 do_rop_32(ptr
, and_masks
[1] | 0xffff0000, xor_masks
[1] & 0x0000ffff);
361 do_rop_32(ptr
++, and_masks
[0], xor_masks
[0]);
362 do_rop_32(ptr
++, and_masks
[1], xor_masks
[1]);
363 do_rop_32(ptr
, and_masks
[2] | 0xffffff00, xor_masks
[2] & 0x000000ff);
370 start
= get_pixel_ptr_24_dword(dib
, rc
->left
, rc
->top
);
371 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
378 do_rop_32(ptr
++, 0x00ffffff, xor_masks
[0] & 0xff000000);
379 *ptr
++ = xor_masks
[1];
380 *ptr
++ = xor_masks
[2];
383 do_rop_32(ptr
++, 0x0000ffff, xor_masks
[1] & 0xffff0000);
384 *ptr
++ = xor_masks
[2];
387 do_rop_32(ptr
++, 0x000000ff, xor_masks
[2] & 0xffffff00);
391 for(x
= (left
+ 3) & ~3; x
< (right
& ~3); x
+= 4)
393 *ptr
++ = xor_masks
[0];
394 *ptr
++ = xor_masks
[1];
395 *ptr
++ = xor_masks
[2];
401 do_rop_32(ptr
, 0xff000000, xor_masks
[0] & 0x00ffffff);
404 *ptr
++ = xor_masks
[0];
405 do_rop_32(ptr
, 0xffff0000, xor_masks
[1] & 0x0000ffff);
408 *ptr
++ = xor_masks
[0];
409 *ptr
++ = xor_masks
[1];
410 do_rop_32(ptr
, 0xffffff00, xor_masks
[2] & 0x000000ff);
418 static void solid_rects_16(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
423 for(i
= 0; i
< num
; i
++, rc
++)
425 assert( !is_rect_empty( rc
));
427 start
= get_pixel_ptr_16(dib
, rc
->left
, rc
->top
);
429 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 2)
430 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
431 do_rop_16(ptr
++, and, xor);
433 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 2)
434 memset_16( start
, xor, rc
->right
- rc
->left
);
438 static void solid_rects_8(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
443 for(i
= 0; i
< num
; i
++, rc
++)
445 assert( !is_rect_empty( rc
));
447 start
= get_pixel_ptr_8(dib
, rc
->left
, rc
->top
);
449 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
450 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
451 do_rop_8(ptr
++, and, xor);
453 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
454 memset( start
, xor, rc
->right
- rc
->left
);
458 static void solid_rects_4(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
462 BYTE byte_and
= (and & 0xf) | ((and << 4) & 0xf0);
463 BYTE byte_xor
= (xor & 0xf) | ((xor << 4) & 0xf0);
465 for(i
= 0; i
< num
; i
++, rc
++)
467 int left
= dib
->rect
.left
+ rc
->left
;
468 int right
= dib
->rect
.left
+ rc
->right
;
470 assert( !is_rect_empty( rc
));
472 start
= get_pixel_ptr_4(dib
, rc
->left
, rc
->top
);
475 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
478 if(left
& 1) /* upper nibble untouched */
479 do_rop_8(ptr
++, byte_and
| 0xf0, byte_xor
& 0x0f);
481 for(x
= (left
+ 1) & ~1; x
< (right
& ~1); x
+= 2)
482 do_rop_8(ptr
++, byte_and
, byte_xor
);
484 if(right
& 1) /* lower nibble untouched */
485 do_rop_8(ptr
, byte_and
| 0x0f, byte_xor
& 0xf0);
490 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
492 unsigned int byte_len
= (right
- ((left
+ 1) & ~1)) / 2;
495 if(left
& 1) /* upper nibble untouched */
496 do_rop_8(ptr
++, 0xf0, byte_xor
& 0x0f);
498 memset( ptr
, byte_xor
, byte_len
);
500 if(right
& 1) /* lower nibble untouched */
501 do_rop_8(ptr
+ byte_len
, 0x0f, byte_xor
& 0xf0);
507 static void solid_rects_1(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
511 BYTE byte_and
= (and & 1) ? 0xff : 0;
512 BYTE byte_xor
= (xor & 1) ? 0xff : 0;
514 for(i
= 0; i
< num
; i
++, rc
++)
516 int left
= dib
->rect
.left
+ rc
->left
;
517 int right
= dib
->rect
.left
+ rc
->right
;
519 assert( !is_rect_empty( rc
));
521 start
= get_pixel_ptr_1(dib
, rc
->left
, rc
->top
);
523 if ((left
& ~7) == (right
& ~7)) /* Special case for lines that start and end in the same byte */
525 BYTE mask
= edge_masks_1
[left
& 7] & ~edge_masks_1
[right
& 7];
527 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
529 do_rop_8(start
, byte_and
| ~mask
, byte_xor
& mask
);
534 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
539 do_rop_8(ptr
++, byte_and
| ~edge_masks_1
[left
& 7], byte_xor
& edge_masks_1
[left
& 7]);
541 for(x
= (left
+ 7) & ~7; x
< (right
& ~7); x
+= 8)
542 do_rop_8(ptr
++, byte_and
, byte_xor
);
545 /* this is inverted wrt start mask */
546 do_rop_8(ptr
, byte_and
| edge_masks_1
[right
& 7], byte_xor
& ~edge_masks_1
[right
& 7]);
551 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
553 unsigned int byte_len
= (right
- ((left
+ 7) & ~7)) / 8;
558 do_rop_8(ptr
++, ~edge_masks_1
[left
& 7], byte_xor
& edge_masks_1
[left
& 7]);
560 memset( ptr
, byte_xor
, byte_len
);
563 do_rop_8(ptr
+ byte_len
, edge_masks_1
[right
& 7], byte_xor
& ~edge_masks_1
[right
& 7]);
569 static void solid_rects_null(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
574 static void solid_line_32(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
575 DWORD
and, DWORD
xor)
577 DWORD
*ptr
= get_pixel_ptr_32( dib
, start
->x
, start
->y
);
578 int len
= params
->length
, err
= params
->err_start
;
579 int major_inc
, minor_inc
;
583 major_inc
= params
->x_inc
;
584 minor_inc
= (dib
->stride
* params
->y_inc
) / 4;
588 major_inc
= (dib
->stride
* params
->y_inc
) / 4;
589 minor_inc
= params
->x_inc
;
594 do_rop_32( ptr
, and, xor );
595 if (err
+ params
->bias
> 0)
598 err
+= params
->err_add_1
;
600 else err
+= params
->err_add_2
;
605 static void solid_line_24(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
606 DWORD
and, DWORD
xor)
608 BYTE
*ptr
= get_pixel_ptr_24( dib
, start
->x
, start
->y
);
609 int len
= params
->length
, err
= params
->err_start
;
610 int major_inc
, minor_inc
;
614 major_inc
= params
->x_inc
* 3;
615 minor_inc
= dib
->stride
* params
->y_inc
;
619 major_inc
= dib
->stride
* params
->y_inc
;
620 minor_inc
= params
->x_inc
* 3;
625 do_rop_8( ptr
, and, xor );
626 do_rop_8( ptr
+ 1, and >> 8, xor >> 8 );
627 do_rop_8( ptr
+ 2, and >> 16, xor >> 16 );
628 if (err
+ params
->bias
> 0)
631 err
+= params
->err_add_1
;
633 else err
+= params
->err_add_2
;
638 static void solid_line_16(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
639 DWORD
and, DWORD
xor)
641 WORD
*ptr
= get_pixel_ptr_16( dib
, start
->x
, start
->y
);
642 int len
= params
->length
, err
= params
->err_start
;
643 int major_inc
, minor_inc
;
647 major_inc
= params
->x_inc
;
648 minor_inc
= (dib
->stride
* params
->y_inc
) / 2;
652 major_inc
= (dib
->stride
* params
->y_inc
) / 2;
653 minor_inc
= params
->x_inc
;
658 do_rop_16( ptr
, and, xor );
659 if (err
+ params
->bias
> 0)
662 err
+= params
->err_add_1
;
664 else err
+= params
->err_add_2
;
669 static void solid_line_8(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
670 DWORD
and, DWORD
xor)
672 BYTE
*ptr
= get_pixel_ptr_8( dib
, start
->x
, start
->y
);
673 int len
= params
->length
, err
= params
->err_start
;
674 int major_inc
, minor_inc
;
678 major_inc
= params
->x_inc
;
679 minor_inc
= dib
->stride
* params
->y_inc
;
683 major_inc
= dib
->stride
* params
->y_inc
;
684 minor_inc
= params
->x_inc
;
689 do_rop_8( ptr
, and, xor );
690 if (err
+ params
->bias
> 0)
693 err
+= params
->err_add_1
;
695 else err
+= params
->err_add_2
;
700 static void solid_line_4(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
701 DWORD
and, DWORD
xor)
703 BYTE
*ptr
= get_pixel_ptr_4( dib
, start
->x
, start
->y
);
704 int len
= params
->length
, err
= params
->err_start
;
705 int x
= dib
->rect
.left
+ start
->x
;
707 and = (and & 0x0f) | ((and << 4) & 0xf0);
708 xor = (xor & 0x0f) | ((xor << 4) & 0xf0);
714 do_rop_mask_8( ptr
, and, xor, pixel_masks_4
[ x
% 2 ] );
715 if (err
+ params
->bias
> 0)
717 ptr
+= dib
->stride
* params
->y_inc
;
718 err
+= params
->err_add_1
;
720 else err
+= params
->err_add_2
;
721 if ((x
/ 2) != ((x
+ params
->x_inc
) / 2))
722 ptr
+= params
->x_inc
;
730 do_rop_mask_8( ptr
, and, xor, pixel_masks_4
[ x
% 2 ] );
731 if (err
+ params
->bias
> 0)
733 if ((x
/ 2) != ((x
+ params
->x_inc
) / 2))
734 ptr
+= params
->x_inc
;
736 err
+= params
->err_add_1
;
738 else err
+= params
->err_add_2
;
739 ptr
+= dib
->stride
* params
->y_inc
;
744 static void solid_line_1(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
745 DWORD
and, DWORD
xor)
747 BYTE
*ptr
= get_pixel_ptr_1( dib
, start
->x
, start
->y
);
748 int len
= params
->length
, err
= params
->err_start
;
749 int x
= dib
->rect
.left
+ start
->x
;
751 and = (and & 0x1) ? 0xff : 0;
752 xor = (xor & 0x1) ? 0xff : 0;
758 do_rop_mask_8( ptr
, and, xor, pixel_masks_1
[ x
% 8 ] );
759 if (err
+ params
->bias
> 0)
761 ptr
+= dib
->stride
* params
->y_inc
;
762 err
+= params
->err_add_1
;
764 else err
+= params
->err_add_2
;
765 if ((x
/ 8) != ((x
+ params
->x_inc
) / 8))
766 ptr
+= params
->x_inc
;
774 do_rop_mask_8( ptr
, and, xor, pixel_masks_1
[ x
% 8 ] );
775 if (err
+ params
->bias
> 0)
777 if ((x
/ 8) != ((x
+ params
->x_inc
) / 8))
778 ptr
+= params
->x_inc
;
780 err
+= params
->err_add_1
;
782 else err
+= params
->err_add_2
;
783 ptr
+= dib
->stride
* params
->y_inc
;
788 static void solid_line_null(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
789 DWORD
and, DWORD
xor)
794 static inline INT
calc_offset(INT edge
, INT size
, INT origin
)
798 if(edge
- origin
>= 0)
799 offset
= (edge
- origin
) % size
;
802 offset
= (origin
- edge
) % size
;
803 if(offset
) offset
= size
- offset
;
808 static inline POINT
calc_brush_offset(const RECT
*rc
, const dib_info
*brush
, const POINT
*origin
)
812 offset
.x
= calc_offset(rc
->left
, brush
->width
, origin
->x
);
813 offset
.y
= calc_offset(rc
->top
, brush
->height
, origin
->y
);
818 static void pattern_rects_32(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
819 const dib_info
*brush
, const rop_mask_bits
*bits
)
821 DWORD
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
822 int x
, y
, i
, len
, brush_x
;
825 for(i
= 0; i
< num
; i
++, rc
++)
827 offset
= calc_brush_offset(rc
, brush
, origin
);
828 start
= get_pixel_ptr_32(dib
, rc
->left
, rc
->top
);
829 start_xor
= (DWORD
*)bits
->xor + offset
.y
* brush
->stride
/ 4;
833 start_and
= (DWORD
*)bits
->and + offset
.y
* brush
->stride
/ 4;
835 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
837 and_ptr
= start_and
+ offset
.x
;
838 xor_ptr
= start_xor
+ offset
.x
;
840 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
842 do_rop_32(ptr
++, *and_ptr
++, *xor_ptr
++);
843 if(and_ptr
== start_and
+ brush
->width
)
851 if(offset
.y
== brush
->height
)
853 start_and
= bits
->and;
854 start_xor
= bits
->xor;
859 start_and
+= brush
->stride
/ 4;
860 start_xor
+= brush
->stride
/ 4;
866 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
868 for (x
= rc
->left
, brush_x
= offset
.x
; x
< rc
->right
; x
+= len
)
870 len
= min( rc
->right
- x
, brush
->width
- brush_x
);
871 memcpy( start
+ x
- rc
->left
, start_xor
+ brush_x
, len
* 4 );
875 start_xor
+= brush
->stride
/ 4;
877 if(offset
.y
== brush
->height
)
879 start_xor
= bits
->xor;
887 static void pattern_rects_24(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
888 const dib_info
*brush
, const rop_mask_bits
*bits
)
890 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
891 int x
, y
, i
, len
, brush_x
;
894 for(i
= 0; i
< num
; i
++, rc
++)
896 offset
= calc_brush_offset(rc
, brush
, origin
);
898 start
= get_pixel_ptr_24(dib
, rc
->left
, rc
->top
);
899 start_xor
= (BYTE
*)bits
->xor + offset
.y
* brush
->stride
;
903 start_and
= (BYTE
*)bits
->and + offset
.y
* brush
->stride
;
904 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
906 and_ptr
= start_and
+ offset
.x
* 3;
907 xor_ptr
= start_xor
+ offset
.x
* 3;
909 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
911 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
912 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
913 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
914 if(and_ptr
== start_and
+ brush
->width
* 3)
922 if(offset
.y
== brush
->height
)
924 start_and
= bits
->and;
925 start_xor
= bits
->xor;
930 start_and
+= brush
->stride
;
931 start_xor
+= brush
->stride
;
937 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
939 for (x
= rc
->left
, brush_x
= offset
.x
; x
< rc
->right
; x
+= len
)
941 len
= min( rc
->right
- x
, brush
->width
- brush_x
);
942 memcpy( start
+ (x
- rc
->left
) * 3, start_xor
+ brush_x
* 3, len
* 3 );
946 start_xor
+= brush
->stride
;
948 if(offset
.y
== brush
->height
)
950 start_xor
= bits
->xor;
958 static void pattern_rects_16(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
959 const dib_info
*brush
, const rop_mask_bits
*bits
)
961 WORD
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
962 int x
, y
, i
, len
, brush_x
;
965 for(i
= 0; i
< num
; i
++, rc
++)
967 offset
= calc_brush_offset(rc
, brush
, origin
);
969 start
= get_pixel_ptr_16(dib
, rc
->left
, rc
->top
);
970 start_xor
= (WORD
*)bits
->xor + offset
.y
* brush
->stride
/ 2;
974 start_and
= (WORD
*)bits
->and + offset
.y
* brush
->stride
/ 2;
975 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 2)
977 and_ptr
= start_and
+ offset
.x
;
978 xor_ptr
= start_xor
+ offset
.x
;
980 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
982 do_rop_16(ptr
++, *and_ptr
++, *xor_ptr
++);
983 if(and_ptr
== start_and
+ brush
->width
)
991 if(offset
.y
== brush
->height
)
993 start_and
= bits
->and;
994 start_xor
= bits
->xor;
999 start_and
+= brush
->stride
/ 2;
1000 start_xor
+= brush
->stride
/ 2;
1006 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 2)
1008 for (x
= rc
->left
, brush_x
= offset
.x
; x
< rc
->right
; x
+= len
)
1010 len
= min( rc
->right
- x
, brush
->width
- brush_x
);
1011 memcpy( start
+ x
- rc
->left
, start_xor
+ brush_x
, len
* 2 );
1015 start_xor
+= brush
->stride
/ 2;
1017 if(offset
.y
== brush
->height
)
1019 start_xor
= bits
->xor;
1027 static void pattern_rects_8(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
1028 const dib_info
*brush
, const rop_mask_bits
*bits
)
1030 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
1031 int x
, y
, i
, len
, brush_x
;
1034 for(i
= 0; i
< num
; i
++, rc
++)
1036 offset
= calc_brush_offset(rc
, brush
, origin
);
1038 start
= get_pixel_ptr_8(dib
, rc
->left
, rc
->top
);
1039 start_xor
= (BYTE
*)bits
->xor + offset
.y
* brush
->stride
;
1043 start_and
= (BYTE
*)bits
->and + offset
.y
* brush
->stride
;
1044 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
1046 and_ptr
= start_and
+ offset
.x
;
1047 xor_ptr
= start_xor
+ offset
.x
;
1049 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
1051 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
1052 if(and_ptr
== start_and
+ brush
->width
)
1054 and_ptr
= start_and
;
1055 xor_ptr
= start_xor
;
1060 if(offset
.y
== brush
->height
)
1062 start_and
= bits
->and;
1063 start_xor
= bits
->xor;
1068 start_and
+= brush
->stride
;
1069 start_xor
+= brush
->stride
;
1075 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
1077 for (x
= rc
->left
, brush_x
= offset
.x
; x
< rc
->right
; x
+= len
)
1079 len
= min( rc
->right
- x
, brush
->width
- brush_x
);
1080 memcpy( start
+ x
- rc
->left
, start_xor
+ brush_x
, len
);
1084 start_xor
+= brush
->stride
;
1086 if(offset
.y
== brush
->height
)
1088 start_xor
= bits
->xor;
1096 static void pattern_rects_4(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
1097 const dib_info
*brush
, const rop_mask_bits
*bits
)
1099 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
1100 int x
, y
, i
, left
, right
;
1103 for(i
= 0; i
< num
; i
++, rc
++)
1105 offset
= calc_brush_offset(rc
, brush
, origin
);
1106 left
= dib
->rect
.left
+ rc
->left
;
1107 right
= dib
->rect
.left
+ rc
->right
;
1109 start
= get_pixel_ptr_4(dib
, rc
->left
, rc
->top
);
1110 start_xor
= (BYTE
*)bits
->xor + offset
.y
* brush
->stride
;
1114 start_and
= (BYTE
*)bits
->and + offset
.y
* brush
->stride
;
1115 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
1117 INT brush_x
= offset
.x
;
1118 BYTE byte_and
, byte_xor
;
1120 and_ptr
= start_and
+ brush_x
/ 2;
1121 xor_ptr
= start_xor
+ brush_x
/ 2;
1123 for(x
= left
, ptr
= start
; x
< right
; x
++)
1125 /* FIXME: Two pixels at a time */
1126 if(x
& 1) /* lower dst nibble */
1128 if(brush_x
& 1) /* lower pat nibble */
1130 byte_and
= *and_ptr
++ | 0xf0;
1131 byte_xor
= *xor_ptr
++ & 0x0f;
1133 else /* upper pat nibble */
1135 byte_and
= (*and_ptr
>> 4) | 0xf0;
1136 byte_xor
= (*xor_ptr
>> 4) & 0x0f;
1139 else /* upper dst nibble */
1141 if(brush_x
& 1) /* lower pat nibble */
1143 byte_and
= (*and_ptr
++ << 4) | 0x0f;
1144 byte_xor
= (*xor_ptr
++ << 4) & 0xf0;
1146 else /* upper pat nibble */
1148 byte_and
= *and_ptr
| 0x0f;
1149 byte_xor
= *xor_ptr
& 0xf0;
1152 do_rop_8(ptr
, byte_and
, byte_xor
);
1156 if(++brush_x
== brush
->width
)
1159 and_ptr
= start_and
;
1160 xor_ptr
= start_xor
;
1165 if(offset
.y
== brush
->height
)
1167 start_and
= bits
->and;
1168 start_xor
= bits
->xor;
1173 start_and
+= brush
->stride
;
1174 start_xor
+= brush
->stride
;
1180 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
1182 INT brush_x
= offset
.x
;
1185 xor_ptr
= start_xor
+ brush_x
/ 2;
1187 for(x
= left
, ptr
= start
; x
< right
; x
++)
1189 /* FIXME: Two pixels at a time */
1190 if(x
& 1) /* lower dst nibble */
1192 if(brush_x
& 1) /* lower pat nibble */
1193 byte_xor
= *xor_ptr
++ & 0x0f;
1194 else /* upper pat nibble */
1195 byte_xor
= (*xor_ptr
>> 4) & 0x0f;
1196 do_rop_8(ptr
, 0xf0, byte_xor
);
1198 else /* upper dst nibble */
1200 if(brush_x
& 1) /* lower pat nibble */
1201 byte_xor
= (*xor_ptr
++ << 4) & 0xf0;
1202 else /* upper pat nibble */
1203 byte_xor
= *xor_ptr
& 0xf0;
1204 do_rop_8(ptr
, 0x0f, byte_xor
);
1209 if(++brush_x
== brush
->width
)
1212 xor_ptr
= start_xor
;
1216 start_xor
+= brush
->stride
;
1218 if(offset
.y
== brush
->height
)
1220 start_xor
= bits
->xor;
1228 static void pattern_rects_1(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
1229 const dib_info
*brush
, const rop_mask_bits
*bits
)
1231 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
1232 int x
, y
, i
, left
, right
;
1235 for(i
= 0; i
< num
; i
++, rc
++)
1237 offset
= calc_brush_offset(rc
, brush
, origin
);
1238 left
= dib
->rect
.left
+ rc
->left
;
1239 right
= dib
->rect
.left
+ rc
->right
;
1241 start
= get_pixel_ptr_1(dib
, rc
->left
, rc
->top
);
1242 start_xor
= (BYTE
*)bits
->xor + offset
.y
* brush
->stride
;
1246 start_and
= (BYTE
*)bits
->and + offset
.y
* brush
->stride
;
1247 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
1249 INT brush_x
= offset
.x
;
1250 BYTE byte_and
, byte_xor
;
1252 and_ptr
= start_and
+ brush_x
/ 8;
1253 xor_ptr
= start_xor
+ brush_x
/ 8;
1255 for(x
= left
, ptr
= start
; x
< right
; x
++)
1257 byte_and
= (*and_ptr
& pixel_masks_1
[brush_x
% 8]) ? 0xff : 0;
1258 byte_and
|= ~pixel_masks_1
[x
% 8];
1259 byte_xor
= (*xor_ptr
& pixel_masks_1
[brush_x
% 8]) ? 0xff : 0;
1260 byte_xor
&= pixel_masks_1
[x
% 8];
1262 do_rop_8(ptr
, byte_and
, byte_xor
);
1264 if((x
& 7) == 7) ptr
++;
1266 if((brush_x
& 7) == 7)
1272 if(++brush_x
== brush
->width
)
1275 and_ptr
= start_and
;
1276 xor_ptr
= start_xor
;
1281 if(offset
.y
== brush
->height
)
1283 start_and
= bits
->and;
1284 start_xor
= bits
->xor;
1289 start_and
+= brush
->stride
;
1290 start_xor
+= brush
->stride
;
1296 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
1298 INT brush_x
= offset
.x
;
1300 xor_ptr
= start_xor
+ brush_x
/ 8;
1302 for(x
= left
, ptr
= start
; x
< right
; x
++)
1304 BYTE byte_xor
= (*xor_ptr
& pixel_masks_1
[brush_x
% 8]) ? 0xff : 0;
1305 byte_xor
&= pixel_masks_1
[x
% 8];
1307 do_rop_8(ptr
, ~pixel_masks_1
[x
% 8], byte_xor
);
1309 if((x
& 7) == 7) ptr
++;
1310 if((brush_x
& 7) == 7) xor_ptr
++;
1312 if(++brush_x
== brush
->width
)
1315 xor_ptr
= start_xor
;
1319 start_xor
+= brush
->stride
;
1321 if(offset
.y
== brush
->height
)
1323 start_xor
= bits
->xor;
1331 static void pattern_rects_null(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
1332 const dib_info
*brush
, const rop_mask_bits
*bits
)
1337 static inline void copy_rect_bits_32( DWORD
*dst_start
, const DWORD
*src_start
, const SIZE
*size
,
1338 int dst_stride
, int src_stride
, int rop2
)
1344 #define LOOP( op ) \
1345 for (y = 0; y < size->cy; y++, dst_start += dst_stride, src_start += src_stride) \
1346 for (x = 0, src = src_start, dst = dst_start; x < size->cx; x++, src++, dst++) \
1351 ROPS_WITHOUT_COPY( dst
[0], src
[0] )
1356 static inline void copy_rect_bits_rev_32( DWORD
*dst_start
, const DWORD
*src_start
, const SIZE
*size
,
1357 int dst_stride
, int src_stride
, int rop2
)
1363 src_start
+= size
->cx
- 1;
1364 dst_start
+= size
->cx
- 1;
1366 #define LOOP( op ) \
1367 for (y = 0; y < size->cy; y++, dst_start += dst_stride, src_start += src_stride) \
1368 for (x = 0, src = src_start, dst = dst_start; x < size->cx; x++, src--, dst--) \
1373 ROPS_WITHOUT_COPY( dst
[0], src
[0] )
1378 static void copy_rect_32(const dib_info
*dst
, const RECT
*rc
,
1379 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1381 DWORD
*dst_start
, *src_start
;
1382 int y
, dst_stride
, src_stride
;
1385 if (overlap
& OVERLAP_BELOW
)
1387 dst_start
= get_pixel_ptr_32(dst
, rc
->left
, rc
->bottom
- 1);
1388 src_start
= get_pixel_ptr_32(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1389 dst_stride
= -dst
->stride
/ 4;
1390 src_stride
= -src
->stride
/ 4;
1394 dst_start
= get_pixel_ptr_32(dst
, rc
->left
, rc
->top
);
1395 src_start
= get_pixel_ptr_32(src
, origin
->x
, origin
->y
);
1396 dst_stride
= dst
->stride
/ 4;
1397 src_stride
= src
->stride
/ 4;
1400 if (rop2
== R2_COPYPEN
)
1402 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1403 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) * 4 );
1407 size
.cx
= rc
->right
- rc
->left
;
1408 size
.cy
= rc
->bottom
- rc
->top
;
1410 if (overlap
& OVERLAP_RIGHT
)
1411 copy_rect_bits_rev_32( dst_start
, src_start
, &size
, dst_stride
, src_stride
, rop2
);
1413 copy_rect_bits_32( dst_start
, src_start
, &size
, dst_stride
, src_stride
, rop2
);
1416 static void copy_rect_24(const dib_info
*dst
, const RECT
*rc
,
1417 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1419 BYTE
*dst_start
, *src_start
;
1420 int y
, dst_stride
, src_stride
;
1421 struct rop_codes codes
;
1423 if (overlap
& OVERLAP_BELOW
)
1425 dst_start
= get_pixel_ptr_24(dst
, rc
->left
, rc
->bottom
- 1);
1426 src_start
= get_pixel_ptr_24(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1427 dst_stride
= -dst
->stride
;
1428 src_stride
= -src
->stride
;
1432 dst_start
= get_pixel_ptr_24(dst
, rc
->left
, rc
->top
);
1433 src_start
= get_pixel_ptr_24(src
, origin
->x
, origin
->y
);
1434 dst_stride
= dst
->stride
;
1435 src_stride
= src
->stride
;
1438 if (rop2
== R2_COPYPEN
)
1440 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1441 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) * 3 );
1445 get_rop_codes( rop2
, &codes
);
1446 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1448 if (overlap
& OVERLAP_RIGHT
)
1449 do_rop_codes_line_rev_8( dst_start
, src_start
, &codes
, (rc
->right
- rc
->left
) * 3 );
1451 do_rop_codes_line_8( dst_start
, src_start
, &codes
, (rc
->right
- rc
->left
) * 3 );
1455 static void copy_rect_16(const dib_info
*dst
, const RECT
*rc
,
1456 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1458 WORD
*dst_start
, *src_start
;
1459 int y
, dst_stride
, src_stride
;
1460 struct rop_codes codes
;
1462 if (overlap
& OVERLAP_BELOW
)
1464 dst_start
= get_pixel_ptr_16(dst
, rc
->left
, rc
->bottom
- 1);
1465 src_start
= get_pixel_ptr_16(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1466 dst_stride
= -dst
->stride
/ 2;
1467 src_stride
= -src
->stride
/ 2;
1471 dst_start
= get_pixel_ptr_16(dst
, rc
->left
, rc
->top
);
1472 src_start
= get_pixel_ptr_16(src
, origin
->x
, origin
->y
);
1473 dst_stride
= dst
->stride
/ 2;
1474 src_stride
= src
->stride
/ 2;
1477 if (rop2
== R2_COPYPEN
)
1479 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1480 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) * 2 );
1484 get_rop_codes( rop2
, &codes
);
1485 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1487 if (overlap
& OVERLAP_RIGHT
)
1488 do_rop_codes_line_rev_16( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1490 do_rop_codes_line_16( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1494 static void copy_rect_8(const dib_info
*dst
, const RECT
*rc
,
1495 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1497 BYTE
*dst_start
, *src_start
;
1498 int y
, dst_stride
, src_stride
;
1499 struct rop_codes codes
;
1501 if (overlap
& OVERLAP_BELOW
)
1503 dst_start
= get_pixel_ptr_8(dst
, rc
->left
, rc
->bottom
- 1);
1504 src_start
= get_pixel_ptr_8(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1505 dst_stride
= -dst
->stride
;
1506 src_stride
= -src
->stride
;
1510 dst_start
= get_pixel_ptr_8(dst
, rc
->left
, rc
->top
);
1511 src_start
= get_pixel_ptr_8(src
, origin
->x
, origin
->y
);
1512 dst_stride
= dst
->stride
;
1513 src_stride
= src
->stride
;
1516 if (rop2
== R2_COPYPEN
)
1518 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1519 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) );
1523 get_rop_codes( rop2
, &codes
);
1524 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1526 if (overlap
& OVERLAP_RIGHT
)
1527 do_rop_codes_line_rev_8( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1529 do_rop_codes_line_8( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1533 static void copy_rect_4(const dib_info
*dst
, const RECT
*rc
,
1534 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1536 BYTE
*dst_start
, *src_start
;
1537 int y
, dst_stride
, src_stride
;
1538 struct rop_codes codes
;
1539 int left
= dst
->rect
.left
+ rc
->left
;
1540 int right
= dst
->rect
.left
+ rc
->right
;
1541 int org_x
= src
->rect
.left
+ origin
->x
;
1543 if (overlap
& OVERLAP_BELOW
)
1545 dst_start
= get_pixel_ptr_4(dst
, rc
->left
, rc
->bottom
- 1);
1546 src_start
= get_pixel_ptr_4(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1547 dst_stride
= -dst
->stride
;
1548 src_stride
= -src
->stride
;
1552 dst_start
= get_pixel_ptr_4(dst
, rc
->left
, rc
->top
);
1553 src_start
= get_pixel_ptr_4(src
, origin
->x
, origin
->y
);
1554 dst_stride
= dst
->stride
;
1555 src_stride
= src
->stride
;
1558 if (rop2
== R2_COPYPEN
&& (left
& 1) == 0 && (org_x
& 1) == 0 && (right
& 1) == 0)
1560 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1561 memmove( dst_start
, src_start
, (right
- left
) / 2 );
1565 get_rop_codes( rop2
, &codes
);
1566 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1568 if (overlap
& OVERLAP_RIGHT
)
1569 do_rop_codes_line_rev_4( dst_start
, left
& 1, src_start
, org_x
& 1, &codes
, right
- left
);
1571 do_rop_codes_line_4( dst_start
, left
& 1, src_start
, org_x
& 1, &codes
, right
- left
);
1575 static inline void copy_rect_bits_partial_1( BYTE
*dst_start
, int dst_x
, const BYTE
*src_start
, int src_x
,
1576 const SIZE
*size
, int dst_stride
, int src_stride
, int rop2
)
1579 BYTE
*dst
, src_val
, mask
;
1580 int dst_end
= dst_x
+ size
->cx
, y
;
1581 int off
= (src_x
& 7) - (dst_x
& 7);
1582 struct rop_codes codes
;
1584 get_rop_codes( rop2
, &codes
);
1586 src_start
+= src_x
/ 8;
1587 dst_start
+= dst_x
/ 8;
1589 for (y
= 0; y
< size
->cy
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1597 src_val
= src
[0] << off
;
1598 if ((dst_end
& 7) + off
> 8)
1599 src_val
|= (src
[1] >> (8 - off
));
1602 src_val
= src
[0] >> -off
;
1604 mask
= edge_masks_1
[dst_x
& 7];
1606 mask
&= ~edge_masks_1
[dst_end
& 7];
1607 do_rop_codes_mask_8( dst
, src_val
, &codes
, mask
);
1611 static inline void copy_rect_bits_align_1( BYTE
*dst_start
, int dst_x
, const BYTE
*src_start
, int src_x
,
1612 const SIZE
*size
, int dst_stride
, int src_stride
, int rop2
)
1616 int y
, i
, full_bytes
, dst_end
= dst_x
+ size
->cx
;
1617 struct rop_codes codes
;
1619 get_rop_codes( rop2
, &codes
);
1621 src_start
+= src_x
/ 8;
1622 dst_start
+= dst_x
/ 8;
1623 full_bytes
= (dst_end
- ((dst_x
+ 7) & ~7)) / 8;
1628 for (y
= 0; y
< size
->cy
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1634 mask
= edge_masks_1
[dst_x
& 7];
1635 do_rop_codes_mask_8( dst
, src
[0], &codes
, mask
);
1639 memmove( dst
, src
, full_bytes
);
1644 mask
= ~edge_masks_1
[dst_end
& 7];
1645 do_rop_codes_mask_8( dst
, src
[0], &codes
, mask
);
1650 #define LOOP( op ) \
1651 for (y = 0; y < size->cy; y++, dst_start += dst_stride, src_start += src_stride) \
1657 mask = edge_masks_1[dst_x & 7]; \
1658 do_rop_codes_mask_8( dst, src[0], &codes, mask ); \
1662 for (i = 0; i < full_bytes; i++, src++, dst++) \
1666 mask = ~edge_masks_1[dst_end & 7]; \
1667 do_rop_codes_mask_8( dst, src[0], &codes, mask ); \
1671 ROPS_WITHOUT_COPY( dst
[0], src
[0] );
1676 static inline void copy_rect_bits_shl_1( BYTE
*dst_start
, int dst_x
, const BYTE
*src_start
, int src_x
,
1677 const SIZE
*size
, int dst_stride
, int src_stride
, int rop2
)
1680 BYTE
*dst
, mask
, src_val
;
1681 int y
, i
, full_bytes
, dst_end
= dst_x
+ size
->cx
;
1682 int off
= (src_x
& 7) - (dst_x
& 7);
1683 struct rop_codes codes
;
1685 get_rop_codes( rop2
, &codes
);
1687 src_start
+= src_x
/ 8;
1688 dst_start
+= dst_x
/ 8;
1689 full_bytes
= (dst_end
- ((dst_x
+ 7) & ~7)) / 8;
1691 #define LOOP( op ) \
1692 for (y = 0; y < size->cy; y++, dst_start += dst_stride, src_start += src_stride) \
1698 src_val = (src[0] << off) | (src[1] >> (8 - off)); \
1699 mask = edge_masks_1[dst_x & 7]; \
1700 do_rop_codes_mask_8( dst, src_val, &codes, mask ); \
1704 for (i = 0; i < full_bytes; i++, src++, dst++) \
1708 src_val = src[0] << off; \
1709 if ((dst_end & 7) + off > 8) \
1710 src_val |= (src[1] >> (8 - off)); \
1711 mask = ~edge_masks_1[dst_end & 7]; \
1712 do_rop_codes_mask_8( dst, src_val, &codes, mask ); \
1718 ROPS_ALL( dst
[0], ((src
[0] << off
) | (src
[1] >> (8 - off
))) );
1723 static inline void copy_rect_bits_shr_1( BYTE
*dst_start
, int dst_x
, const BYTE
*src_start
, int src_x
,
1724 const SIZE
*size
, int dst_stride
, int src_stride
, int rop2
)
1727 BYTE
*dst
, mask
, src_val
, last_src
;
1728 int y
, i
, full_bytes
, dst_end
= dst_x
+ size
->cx
;
1729 int off
= (src_x
& 7) - (dst_x
& 7);
1730 struct rop_codes codes
;
1732 get_rop_codes( rop2
, &codes
);
1734 src_start
+= src_x
/ 8;
1735 dst_start
+= dst_x
/ 8;
1736 full_bytes
= (dst_end
- ((dst_x
+ 7) & ~7)) / 8;
1738 #define LOOP( op ) \
1739 for (y = 0; y < size->cy; y++, dst_start += dst_stride, src_start += src_stride) \
1746 last_src = src[0]; \
1747 mask = edge_masks_1[dst_x & 7]; \
1748 do_rop_codes_mask_8( dst, src[0] >> -off, &codes, mask ); \
1752 for (i = 0; i < full_bytes; i++, src++, dst++) \
1754 src_val = (last_src << (8 + off)) | (src[0] >> -off); \
1755 last_src = src[0]; \
1760 src_val = last_src << (8 + off); \
1761 if ((dst_end & 7) + off > 0) \
1762 src_val |= (src[0] >> -off); \
1763 mask = ~edge_masks_1[dst_end & 7]; \
1764 do_rop_codes_mask_8( dst, src_val, &codes, mask ); \
1770 ROPS_ALL( dst
[0], src_val
)
1775 static inline void copy_rect_bits_rev_align_1( BYTE
*dst_start
, int dst_x
, const BYTE
*src_start
, int src_x
,
1776 const SIZE
*size
, int dst_stride
, int src_stride
, int rop2
)
1780 int y
, i
, full_bytes
, dst_end
= dst_x
+ size
->cx
, src_end
= src_x
+ size
->cx
;
1781 struct rop_codes codes
;
1783 get_rop_codes( rop2
, &codes
);
1785 src_start
+= (src_end
- 1) / 8;
1786 dst_start
+= (dst_end
- 1) / 8;
1787 full_bytes
= (dst_end
- ((dst_x
+ 7) & ~7)) / 8;
1792 for (y
= 0; y
< size
->cy
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1798 mask
= ~edge_masks_1
[dst_end
& 7];
1799 do_rop_codes_mask_8( dst
, src
[0], &codes
, mask
);
1803 memmove( dst
, src
, full_bytes
);
1808 mask
= edge_masks_1
[dst_x
& 7];
1809 do_rop_codes_mask_8( dst
, src
[0], &codes
, mask
);
1814 #define LOOP( op ) \
1815 for (y = 0; y < size->cy; y++, dst_start += dst_stride, src_start += src_stride) \
1821 mask = ~edge_masks_1[dst_end & 7]; \
1822 do_rop_codes_mask_8( dst, src[0], &codes, mask ); \
1826 for (i = 0; i < full_bytes; i++, src--, dst--) \
1830 mask = edge_masks_1[dst_x & 7]; \
1831 do_rop_codes_mask_8( dst, src[0], &codes, mask ); \
1835 ROPS_WITHOUT_COPY( dst
[0], src
[0] );
1840 static inline void copy_rect_bits_rev_shl_1( BYTE
*dst_start
, int dst_x
, const BYTE
*src_start
, int src_x
,
1841 const SIZE
*size
, int dst_stride
, int src_stride
, int rop2
)
1844 BYTE
*dst
, mask
, src_val
, last_src
;
1845 int y
, i
, full_bytes
, dst_end
= dst_x
+ size
->cx
, src_end
= src_x
+ size
->cx
;
1846 int off
= ((src_end
- 1) & 7) - ((dst_end
- 1) & 7);
1847 struct rop_codes codes
;
1849 get_rop_codes( rop2
, &codes
);
1851 src_start
+= (src_end
- 1) / 8;
1852 dst_start
+= (dst_end
- 1) / 8;
1853 full_bytes
= (dst_end
- ((dst_x
+ 7) & ~7)) / 8;
1855 #define LOOP( op ) \
1856 for (y = 0; y < size->cy; y++, dst_start += dst_stride, src_start += src_stride) \
1863 last_src = src[0]; \
1864 mask = ~edge_masks_1[dst_end & 7]; \
1865 do_rop_codes_mask_8( dst, src[0] << off, &codes, mask ); \
1869 for (i = 0; i < full_bytes; i++, src--, dst--) \
1871 src_val = (src[0] << off) | (last_src >> (8 - off)); \
1872 last_src = src[0]; \
1877 src_val = last_src >> (8 - off); \
1878 if ((dst_x & 7) + off < 8) \
1879 src_val |= (src[0] << off); \
1880 mask = edge_masks_1[dst_x & 7]; \
1881 do_rop_codes_mask_8( dst, src_val, &codes, mask ); \
1887 ROPS_ALL( dst
[0], src_val
);
1892 static inline void copy_rect_bits_rev_shr_1( BYTE
*dst_start
, int dst_x
, const BYTE
*src_start
, int src_x
,
1893 const SIZE
*size
, int dst_stride
, int src_stride
, int rop2
)
1896 BYTE
*dst
, mask
, src_val
;
1897 int y
, i
, full_bytes
, dst_end
= dst_x
+ size
->cx
, src_end
= src_x
+ size
->cx
;
1898 int off
= ((src_end
- 1) & 7) - ((dst_end
- 1) & 7);
1899 struct rop_codes codes
;
1901 get_rop_codes( rop2
, &codes
);
1903 src_start
+= (src_end
- 1) / 8;
1904 dst_start
+= (dst_end
- 1) / 8;
1905 full_bytes
= (dst_end
- ((dst_x
+ 7) & ~7)) / 8;
1907 #define LOOP( op ) \
1908 for (y = 0; y < size->cy; y++, dst_start += dst_stride, src_start += src_stride) \
1914 mask = edge_masks_1[dst_x & 7]; \
1915 do_rop_codes_mask_8( dst, (src[-1] << (8 + off)) | (src[0] >> -off), &codes, mask ); \
1919 for (i = 0; i < full_bytes; i++, src--, dst--) \
1923 src_val = src[0] >> -off; \
1924 if ((dst_x & 7) + off < 0) \
1925 src_val |= (src[-1] << (8 + off)); \
1926 mask = edge_masks_1[dst_x & 7]; \
1927 do_rop_codes_mask_8( dst, src_val, &codes, mask ); \
1933 ROPS_ALL( dst
[0], (src
[-1] << (8 + off
)) | (src
[0] >> -off
) );
1938 static void copy_rect_1(const dib_info
*dst
, const RECT
*rc
,
1939 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1941 BYTE
*dst_start
, *src_start
;
1942 int y
, dst_stride
, src_stride
;
1943 int left
= dst
->rect
.left
+ rc
->left
;
1944 int right
= dst
->rect
.left
+ rc
->right
;
1945 int org_x
= src
->rect
.left
+ origin
->x
;
1948 if (overlap
& OVERLAP_BELOW
)
1950 dst_start
= get_pixel_ptr_1(dst
, rc
->left
, rc
->bottom
- 1);
1951 src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1952 dst_stride
= -dst
->stride
;
1953 src_stride
= -src
->stride
;
1957 dst_start
= get_pixel_ptr_1(dst
, rc
->left
, rc
->top
);
1958 src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
);
1959 dst_stride
= dst
->stride
;
1960 src_stride
= src
->stride
;
1963 if (rop2
== R2_COPYPEN
&& (left
& 7) == 0 && (org_x
& 7) == 0 && (right
& 7) == 0)
1965 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1966 memmove( dst_start
, src_start
, (right
- left
) / 8 );
1970 size
.cx
= right
- left
;
1971 size
.cy
= rc
->bottom
- rc
->top
;
1973 /* Special case starting and finishing in same byte, neither on byte boundary */
1974 if ((left
& 7) && (right
& 7) && (left
& ~7) == (right
& ~7))
1975 copy_rect_bits_partial_1( dst_start
, left
& 7, src_start
, org_x
& 7, &size
, dst_stride
, src_stride
, rop2
);
1976 else if (overlap
& OVERLAP_RIGHT
)
1978 int off
= ((org_x
+ right
- left
- 1) & 7) - ((right
- 1) & 7);
1981 copy_rect_bits_rev_align_1( dst_start
, left
& 7, src_start
, org_x
& 7, &size
, dst_stride
, src_stride
, rop2
);
1983 copy_rect_bits_rev_shl_1( dst_start
, left
& 7, src_start
, org_x
& 7, &size
, dst_stride
, src_stride
, rop2
);
1985 copy_rect_bits_rev_shr_1( dst_start
, left
& 7, src_start
, org_x
& 7, &size
, dst_stride
, src_stride
, rop2
);
1989 int off
= (org_x
& 7) - (left
& 7);
1992 copy_rect_bits_align_1( dst_start
, left
& 7, src_start
, org_x
& 7, &size
, dst_stride
, src_stride
, rop2
);
1994 copy_rect_bits_shl_1( dst_start
, left
& 7, src_start
, org_x
& 7, &size
, dst_stride
, src_stride
, rop2
);
1996 copy_rect_bits_shr_1( dst_start
, left
& 7, src_start
, org_x
& 7, &size
, dst_stride
, src_stride
, rop2
);
2000 static void copy_rect_null(const dib_info
*dst
, const RECT
*rc
,
2001 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
2006 static DWORD
get_pixel_32(const dib_info
*dib
, int x
, int y
)
2008 DWORD
*ptr
= get_pixel_ptr_32( dib
, x
, y
);
2012 static DWORD
get_pixel_24(const dib_info
*dib
, int x
, int y
)
2014 BYTE
*ptr
= get_pixel_ptr_24( dib
, x
, y
);
2015 return ptr
[0] | ((DWORD
)ptr
[1] << 8) | ((DWORD
)ptr
[2] << 16);
2018 static DWORD
get_pixel_16(const dib_info
*dib
, int x
, int y
)
2020 WORD
*ptr
= get_pixel_ptr_16( dib
, x
, y
);
2024 static DWORD
get_pixel_8(const dib_info
*dib
, int x
, int y
)
2026 BYTE
*ptr
= get_pixel_ptr_8( dib
, x
, y
);
2030 static DWORD
get_pixel_4(const dib_info
*dib
, int x
, int y
)
2032 BYTE
*ptr
= get_pixel_ptr_4( dib
, x
, y
);
2034 if ((dib
->rect
.left
+ x
) & 1)
2037 return (*ptr
>> 4) & 0x0f;
2040 static DWORD
get_pixel_1(const dib_info
*dib
, int x
, int y
)
2042 BYTE
*ptr
= get_pixel_ptr_1( dib
, x
, y
);
2043 return (*ptr
& pixel_masks_1
[(dib
->rect
.left
+ x
) & 7]) ? 1 : 0;
2046 static DWORD
get_pixel_null(const dib_info
*dib
, int x
, int y
)
2051 static DWORD
colorref_to_pixel_888(const dib_info
*dib
, COLORREF color
)
2053 return ( ((color
>> 16) & 0xff) | (color
& 0xff00) | ((color
<< 16) & 0xff0000) );
2056 static const DWORD field_masks
[33] =
2058 0x00, /* should never happen */
2059 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff,
2060 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2061 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2062 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2065 static inline DWORD
get_field(DWORD field
, int shift
, int len
)
2067 shift
= shift
- (8 - len
);
2072 field
&= field_masks
[len
];
2073 field
|= field
>> len
;
2077 static inline DWORD
put_field(DWORD field
, int shift
, int len
)
2079 shift
= shift
- (8 - len
);
2080 field
&= field_masks
[len
];
2088 static DWORD
rgb_to_pixel_masks(const dib_info
*dib
, DWORD r
, DWORD g
, DWORD b
)
2090 return put_field(r
, dib
->red_shift
, dib
->red_len
) |
2091 put_field(g
, dib
->green_shift
, dib
->green_len
) |
2092 put_field(b
, dib
->blue_shift
, dib
->blue_len
);
2095 static DWORD
rgbquad_to_pixel_masks(const dib_info
*dib
, RGBQUAD rgb
)
2097 return rgb_to_pixel_masks(dib
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
2100 static DWORD
colorref_to_pixel_masks(const dib_info
*dib
, COLORREF colour
)
2102 return rgb_to_pixel_masks(dib
, GetRValue(colour
), GetGValue(colour
), GetBValue(colour
));
2105 static DWORD
colorref_to_pixel_555(const dib_info
*dib
, COLORREF color
)
2107 return ( ((color
>> 19) & 0x1f) | ((color
>> 6) & 0x03e0) | ((color
<< 7) & 0x7c00) );
2110 static DWORD
rgb_to_pixel_colortable(const dib_info
*dib
, BYTE r
, BYTE g
, BYTE b
)
2112 const RGBQUAD
*color_table
= get_dib_color_table( dib
);
2113 int size
= dib
->color_table
? dib
->color_table_size
: 1 << dib
->bit_count
;
2114 int i
, best_index
= 0;
2115 DWORD diff
, best_diff
= 0xffffffff;
2117 for(i
= 0; i
< size
; i
++)
2119 const RGBQUAD
*cur
= color_table
+ i
;
2120 diff
= (r
- cur
->rgbRed
) * (r
- cur
->rgbRed
)
2121 + (g
- cur
->rgbGreen
) * (g
- cur
->rgbGreen
)
2122 + (b
- cur
->rgbBlue
) * (b
- cur
->rgbBlue
);
2130 if(diff
< best_diff
)
2139 static DWORD
rgb_to_pixel_mono(const dib_info
*dib
, BOOL dither
, int x
, int y
,
2140 DWORD src_pixel
, DWORD bg_pixel
, BYTE r
, BYTE g
, BYTE b
)
2144 if (dib
->color_table_size
!= 1)
2148 if (((30 * r
+ 59 * g
+ 11 * b
) / 100 + bayer_16x16
[y
% 16][x
% 16]) > 255) r
= g
= b
= 255;
2151 ret
= rgb_to_pixel_colortable( dib
, r
, g
, b
);
2153 else ret
= (src_pixel
== bg_pixel
); /* only match raw pixel value */
2155 return ret
? 0xff : 0;
2158 static DWORD
rgbquad_to_pixel_colortable(const dib_info
*dib
, RGBQUAD rgb
)
2160 return rgb_to_pixel_colortable( dib
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
2163 static DWORD
colorref_to_pixel_colortable(const dib_info
*dib
, COLORREF color
)
2165 return rgb_to_pixel_colortable( dib
, GetRValue(color
), GetGValue(color
), GetBValue(color
) );
2168 static DWORD
colorref_to_pixel_null(const dib_info
*dib
, COLORREF color
)
2173 static COLORREF
pixel_to_colorref_888(const dib_info
*dib
, DWORD pixel
)
2175 return ( ((pixel
>> 16) & 0xff) | (pixel
& 0xff00) | ((pixel
<< 16) & 0xff0000) );
2178 static COLORREF
pixel_to_colorref_masks(const dib_info
*dib
, DWORD pixel
)
2180 return RGB( get_field( pixel
, dib
->red_shift
, dib
->red_len
),
2181 get_field( pixel
, dib
->green_shift
, dib
->green_len
),
2182 get_field( pixel
, dib
->blue_shift
, dib
->blue_len
) );
2185 static COLORREF
pixel_to_colorref_555(const dib_info
*dib
, DWORD pixel
)
2187 return RGB( ((pixel
>> 7) & 0xf8) | ((pixel
>> 12) & 0x07),
2188 ((pixel
>> 2) & 0xf8) | ((pixel
>> 7) & 0x07),
2189 ((pixel
<< 3) & 0xf8) | ((pixel
>> 2) & 0x07) );
2192 static COLORREF
pixel_to_colorref_colortable(const dib_info
*dib
, DWORD pixel
)
2194 const RGBQUAD
*color_table
= get_dib_color_table( dib
);
2196 if (!dib
->color_table
|| pixel
< dib
->color_table_size
)
2198 RGBQUAD quad
= color_table
[pixel
];
2199 return RGB( quad
.rgbRed
, quad
.rgbGreen
, quad
.rgbBlue
);
2204 static COLORREF
pixel_to_colorref_null(const dib_info
*dib
, DWORD pixel
)
2209 static inline BOOL
bit_fields_match(const dib_info
*d1
, const dib_info
*d2
)
2211 assert( d1
->bit_count
> 8 && d1
->bit_count
== d2
->bit_count
);
2213 return d1
->red_mask
== d2
->red_mask
&&
2214 d1
->green_mask
== d2
->green_mask
&&
2215 d1
->blue_mask
== d2
->blue_mask
;
2218 static void convert_to_8888(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
2220 DWORD
*dst_start
= get_pixel_ptr_32(dst
, 0, 0), *dst_pixel
, src_val
;
2221 int x
, y
, pad_size
= (dst
->width
- (src_rect
->right
- src_rect
->left
)) * 4;
2223 switch(src
->bit_count
)
2227 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2228 if(src
->funcs
== &funcs_8888
)
2230 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
2231 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2234 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2236 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 4);
2237 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
2238 dst_start
+= dst
->stride
/ 4;
2239 src_start
+= src
->stride
/ 4;
2243 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
2245 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2247 dst_pixel
= dst_start
;
2248 src_pixel
= src_start
;
2249 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2251 src_val
= *src_pixel
++;
2252 *dst_pixel
++ = (((src_val
>> src
->red_shift
) & 0xff) << 16) |
2253 (((src_val
>> src
->green_shift
) & 0xff) << 8) |
2254 ((src_val
>> src
->blue_shift
) & 0xff);
2256 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2257 dst_start
+= dst
->stride
/ 4;
2258 src_start
+= src
->stride
/ 4;
2263 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2265 dst_pixel
= dst_start
;
2266 src_pixel
= src_start
;
2267 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2269 src_val
= *src_pixel
++;
2270 *dst_pixel
++ = (get_field( src_val
, src
->red_shift
, src
->red_len
) << 16 |
2271 get_field( src_val
, src
->green_shift
, src
->green_len
) << 8 |
2272 get_field( src_val
, src
->blue_shift
, src
->blue_len
));
2274 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2275 dst_start
+= dst
->stride
/ 4;
2276 src_start
+= src
->stride
/ 4;
2284 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2286 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2288 dst_pixel
= dst_start
;
2289 src_pixel
= src_start
;
2290 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2293 rgb
.rgbBlue
= *src_pixel
++;
2294 rgb
.rgbGreen
= *src_pixel
++;
2295 rgb
.rgbRed
= *src_pixel
++;
2297 *dst_pixel
++ = ((rgb
.rgbRed
<< 16) & 0xff0000) | ((rgb
.rgbGreen
<< 8) & 0x00ff00) | (rgb
.rgbBlue
& 0x0000ff);
2299 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2300 dst_start
+= dst
->stride
/ 4;
2301 src_start
+= src
->stride
;
2308 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2309 if(src
->funcs
== &funcs_555
)
2311 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2313 dst_pixel
= dst_start
;
2314 src_pixel
= src_start
;
2315 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2317 src_val
= *src_pixel
++;
2318 *dst_pixel
++ = ((src_val
<< 9) & 0xf80000) | ((src_val
<< 4) & 0x070000) |
2319 ((src_val
<< 6) & 0x00f800) | ((src_val
<< 1) & 0x000700) |
2320 ((src_val
<< 3) & 0x0000f8) | ((src_val
>> 2) & 0x000007);
2322 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2323 dst_start
+= dst
->stride
/ 4;
2324 src_start
+= src
->stride
/ 2;
2327 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2329 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2331 dst_pixel
= dst_start
;
2332 src_pixel
= src_start
;
2333 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2335 src_val
= *src_pixel
++;
2336 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 19) & 0xf80000) |
2337 (((src_val
>> src
->red_shift
) << 14) & 0x070000) |
2338 (((src_val
>> src
->green_shift
) << 11) & 0x00f800) |
2339 (((src_val
>> src
->green_shift
) << 6) & 0x000700) |
2340 (((src_val
>> src
->blue_shift
) << 3) & 0x0000f8) |
2341 (((src_val
>> src
->blue_shift
) >> 2) & 0x000007);
2343 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2344 dst_start
+= dst
->stride
/ 4;
2345 src_start
+= src
->stride
/ 2;
2348 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2350 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2352 dst_pixel
= dst_start
;
2353 src_pixel
= src_start
;
2354 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2356 src_val
= *src_pixel
++;
2357 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 19) & 0xf80000) |
2358 (((src_val
>> src
->red_shift
) << 14) & 0x070000) |
2359 (((src_val
>> src
->green_shift
) << 10) & 0x00fc00) |
2360 (((src_val
>> src
->green_shift
) << 4) & 0x000300) |
2361 (((src_val
>> src
->blue_shift
) << 3) & 0x0000f8) |
2362 (((src_val
>> src
->blue_shift
) >> 2) & 0x000007);
2364 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2365 dst_start
+= dst
->stride
/ 4;
2366 src_start
+= src
->stride
/ 2;
2371 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2373 dst_pixel
= dst_start
;
2374 src_pixel
= src_start
;
2375 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2377 src_val
= *src_pixel
++;
2378 *dst_pixel
++ = (get_field( src_val
, src
->red_shift
, src
->red_len
) << 16 |
2379 get_field( src_val
, src
->green_shift
, src
->green_len
) << 8 |
2380 get_field( src_val
, src
->blue_shift
, src
->blue_len
));
2382 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2383 dst_start
+= dst
->stride
/ 4;
2384 src_start
+= src
->stride
/ 2;
2392 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2393 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2394 DWORD dst_colors
[256], i
;
2396 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
2397 dst_colors
[i
] = color_table
[i
].rgbRed
<< 16 | color_table
[i
].rgbGreen
<< 8 |
2398 color_table
[i
].rgbBlue
;
2400 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2402 dst_pixel
= dst_start
;
2403 src_pixel
= src_start
;
2404 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2405 *dst_pixel
++ = dst_colors
[*src_pixel
++];
2407 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2408 dst_start
+= dst
->stride
/ 4;
2409 src_start
+= src
->stride
;
2416 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2417 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2418 DWORD dst_colors
[16], i
;
2420 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
2421 dst_colors
[i
] = color_table
[i
].rgbRed
<< 16 | color_table
[i
].rgbGreen
<< 8 |
2422 color_table
[i
].rgbBlue
;
2424 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2426 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
2427 src_pixel
= src_start
;
2428 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2431 dst_start
[x
] = dst_colors
[*src_pixel
++ & 0xf];
2433 dst_start
[x
] = dst_colors
[*src_pixel
>> 4];
2435 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
2436 dst_start
+= dst
->stride
/ 4;
2437 src_start
+= src
->stride
;
2444 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2445 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
2446 DWORD dst_colors
[2], i
;
2448 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
2449 dst_colors
[i
] = color_table
[i
].rgbRed
<< 16 | color_table
[i
].rgbGreen
<< 8 |
2450 color_table
[i
].rgbBlue
;
2452 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2454 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
2455 for(x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2457 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
2458 dst_start
[x
] = dst_colors
[src_val
];
2460 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
2461 dst_start
+= dst
->stride
/ 4;
2462 src_start
+= src
->stride
;
2469 static void convert_to_32(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
2471 DWORD
*dst_start
= get_pixel_ptr_32(dst
, 0, 0), *dst_pixel
, src_val
;
2472 int x
, y
, pad_size
= (dst
->width
- (src_rect
->right
- src_rect
->left
)) * 4;
2474 switch(src
->bit_count
)
2478 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2480 if(src
->funcs
== &funcs_8888
)
2482 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2484 dst_pixel
= dst_start
;
2485 src_pixel
= src_start
;
2486 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2488 src_val
= *src_pixel
++;
2489 *dst_pixel
++ = rgb_to_pixel_masks(dst
, src_val
>> 16, src_val
>> 8, src_val
);
2491 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2492 dst_start
+= dst
->stride
/ 4;
2493 src_start
+= src
->stride
/ 4;
2496 else if(bit_fields_match(src
, dst
))
2498 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
2499 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2502 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2504 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 4);
2505 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
2506 dst_start
+= dst
->stride
/ 4;
2507 src_start
+= src
->stride
/ 4;
2511 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8 &&
2512 dst
->red_len
== 8 && dst
->green_len
== 8 && dst
->blue_len
== 8)
2514 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2516 dst_pixel
= dst_start
;
2517 src_pixel
= src_start
;
2518 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2520 src_val
= *src_pixel
++;
2521 *dst_pixel
++ = (((src_val
>> src
->red_shift
) & 0xff) << dst
->red_shift
) |
2522 (((src_val
>> src
->green_shift
) & 0xff) << dst
->green_shift
) |
2523 (((src_val
>> src
->blue_shift
) & 0xff) << dst
->blue_shift
);
2525 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2526 dst_start
+= dst
->stride
/ 4;
2527 src_start
+= src
->stride
/ 4;
2532 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2534 dst_pixel
= dst_start
;
2535 src_pixel
= src_start
;
2536 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2538 src_val
= *src_pixel
++;
2539 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
2540 get_field(src_val
, src
->red_shift
, src
->red_len
),
2541 get_field(src_val
, src
->green_shift
, src
->green_len
),
2542 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
2544 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2545 dst_start
+= dst
->stride
/ 4;
2546 src_start
+= src
->stride
/ 4;
2554 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2556 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2558 dst_pixel
= dst_start
;
2559 src_pixel
= src_start
;
2560 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, src_pixel
+= 3)
2561 *dst_pixel
++ = rgb_to_pixel_masks(dst
, src_pixel
[2], src_pixel
[1], src_pixel
[0]);
2562 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2563 dst_start
+= dst
->stride
/ 4;
2564 src_start
+= src
->stride
;
2571 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2572 if(src
->funcs
== &funcs_555
)
2574 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2576 dst_pixel
= dst_start
;
2577 src_pixel
= src_start
;
2578 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2580 src_val
= *src_pixel
++;
2581 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
2582 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
2583 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
2584 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07));
2586 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2587 dst_start
+= dst
->stride
/ 4;
2588 src_start
+= src
->stride
/ 2;
2591 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2593 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2595 dst_pixel
= dst_start
;
2596 src_pixel
= src_start
;
2597 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2599 src_val
= *src_pixel
++;
2600 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
2601 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2602 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
2603 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
2604 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
2605 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2606 (((src_val
>> src
->blue_shift
) >> 2) & 0x07));
2608 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2609 dst_start
+= dst
->stride
/ 4;
2610 src_start
+= src
->stride
/ 2;
2613 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2615 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2617 dst_pixel
= dst_start
;
2618 src_pixel
= src_start
;
2619 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2621 src_val
= *src_pixel
++;
2622 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
2623 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2624 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
2625 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
2626 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
2627 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2628 (((src_val
>> src
->blue_shift
) >> 2) & 0x07));
2630 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2631 dst_start
+= dst
->stride
/ 4;
2632 src_start
+= src
->stride
/ 2;
2637 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2639 dst_pixel
= dst_start
;
2640 src_pixel
= src_start
;
2641 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2643 src_val
= *src_pixel
++;
2644 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
2645 get_field(src_val
, src
->red_shift
, src
->red_len
),
2646 get_field(src_val
, src
->green_shift
, src
->green_len
),
2647 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
2649 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2650 dst_start
+= dst
->stride
/ 4;
2651 src_start
+= src
->stride
/ 2;
2659 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2660 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2661 DWORD dst_colors
[256], i
;
2663 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
2664 dst_colors
[i
] = rgbquad_to_pixel_masks(dst
, color_table
[i
]);
2666 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2668 dst_pixel
= dst_start
;
2669 src_pixel
= src_start
;
2670 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2671 *dst_pixel
++ = dst_colors
[*src_pixel
++];
2673 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2674 dst_start
+= dst
->stride
/ 4;
2675 src_start
+= src
->stride
;
2682 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2683 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2684 DWORD dst_colors
[16], i
;
2686 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
2687 dst_colors
[i
] = rgbquad_to_pixel_masks(dst
, color_table
[i
]);
2689 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2691 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
2692 src_pixel
= src_start
;
2693 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2696 dst_start
[x
] = dst_colors
[*src_pixel
++ & 0xf];
2698 dst_start
[x
] = dst_colors
[*src_pixel
>> 4];
2700 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
2701 dst_start
+= dst
->stride
/ 4;
2702 src_start
+= src
->stride
;
2709 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2710 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
2711 DWORD dst_colors
[2], i
;
2713 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
2714 dst_colors
[i
] = rgbquad_to_pixel_masks(dst
, color_table
[i
]);
2716 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2718 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
2719 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2721 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
2722 dst_start
[x
] = dst_colors
[src_val
];
2724 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
2725 dst_start
+= dst
->stride
/ 4;
2726 src_start
+= src
->stride
;
2733 static void convert_to_24(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
2735 BYTE
*dst_start
= get_pixel_ptr_24(dst
, 0, 0), *dst_pixel
;
2737 int x
, y
, pad_size
= ((dst
->width
* 3 + 3) & ~3) - (src_rect
->right
- src_rect
->left
) * 3;
2739 switch(src
->bit_count
)
2743 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2744 if(src
->funcs
== &funcs_8888
)
2746 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2748 dst_pixel
= dst_start
;
2749 src_pixel
= src_start
;
2750 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2752 src_val
= *src_pixel
++;
2753 *dst_pixel
++ = src_val
& 0xff;
2754 *dst_pixel
++ = (src_val
>> 8) & 0xff;
2755 *dst_pixel
++ = (src_val
>> 16) & 0xff;
2757 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2758 dst_start
+= dst
->stride
;
2759 src_start
+= src
->stride
/ 4;
2762 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
2764 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2766 dst_pixel
= dst_start
;
2767 src_pixel
= src_start
;
2768 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2770 src_val
= *src_pixel
++;
2771 *dst_pixel
++ = (src_val
>> src
->blue_shift
) & 0xff;
2772 *dst_pixel
++ = (src_val
>> src
->green_shift
) & 0xff;
2773 *dst_pixel
++ = (src_val
>> src
->red_shift
) & 0xff;
2775 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2776 dst_start
+= dst
->stride
;
2777 src_start
+= src
->stride
/ 4;
2782 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2784 dst_pixel
= dst_start
;
2785 src_pixel
= src_start
;
2786 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2788 src_val
= *src_pixel
++;
2789 *dst_pixel
++ = get_field( src_val
, src
->blue_shift
, src
->blue_len
);
2790 *dst_pixel
++ = get_field( src_val
, src
->green_shift
, src
->green_len
);
2791 *dst_pixel
++ = get_field( src_val
, src
->red_shift
, src
->red_len
);
2793 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2794 dst_start
+= dst
->stride
;
2795 src_start
+= src
->stride
/ 4;
2803 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
);
2805 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
2806 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2809 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2811 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 3);
2812 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
) * 3, 0, pad_size
);
2813 dst_start
+= dst
->stride
;
2814 src_start
+= src
->stride
;
2822 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2823 if(src
->funcs
== &funcs_555
)
2825 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2827 dst_pixel
= dst_start
;
2828 src_pixel
= src_start
;
2829 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2831 src_val
= *src_pixel
++;
2832 *dst_pixel
++ = ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07);
2833 *dst_pixel
++ = ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07);
2834 *dst_pixel
++ = ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07);
2836 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2837 dst_start
+= dst
->stride
;
2838 src_start
+= src
->stride
/ 2;
2841 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2843 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2845 dst_pixel
= dst_start
;
2846 src_pixel
= src_start
;
2847 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2849 src_val
= *src_pixel
++;
2850 *dst_pixel
++ = (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2851 (((src_val
>> src
->blue_shift
) >> 2) & 0x07);
2852 *dst_pixel
++ = (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
2853 (((src_val
>> src
->green_shift
) >> 2) & 0x07);
2854 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2855 (((src_val
>> src
->red_shift
) >> 2) & 0x07);
2857 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2858 dst_start
+= dst
->stride
;
2859 src_start
+= src
->stride
/ 2;
2862 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2864 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2866 dst_pixel
= dst_start
;
2867 src_pixel
= src_start
;
2868 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2870 src_val
= *src_pixel
++;
2871 *dst_pixel
++ = (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2872 (((src_val
>> src
->blue_shift
) >> 2) & 0x07);
2873 *dst_pixel
++ = (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
2874 (((src_val
>> src
->green_shift
) >> 4) & 0x03);
2875 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2876 (((src_val
>> src
->red_shift
) >> 2) & 0x07);
2878 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2879 dst_start
+= dst
->stride
;
2880 src_start
+= src
->stride
/ 2;
2885 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2887 dst_pixel
= dst_start
;
2888 src_pixel
= src_start
;
2889 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2891 src_val
= *src_pixel
++;
2892 *dst_pixel
++ = get_field(src_val
, src
->blue_shift
, src
->blue_len
);
2893 *dst_pixel
++ = get_field(src_val
, src
->green_shift
, src
->green_len
);
2894 *dst_pixel
++ = get_field(src_val
, src
->red_shift
, src
->red_len
);
2896 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2897 dst_start
+= dst
->stride
;
2898 src_start
+= src
->stride
/ 2;
2906 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2907 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2908 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2910 dst_pixel
= dst_start
;
2911 src_pixel
= src_start
;
2912 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2914 RGBQUAD rgb
= color_table
[*src_pixel
++];
2915 *dst_pixel
++ = rgb
.rgbBlue
;
2916 *dst_pixel
++ = rgb
.rgbGreen
;
2917 *dst_pixel
++ = rgb
.rgbRed
;
2919 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2920 dst_start
+= dst
->stride
;
2921 src_start
+= src
->stride
;
2928 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2929 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2930 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2932 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
2933 src_pixel
= src_start
;
2934 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2938 rgb
= color_table
[*src_pixel
++ & 0xf];
2940 rgb
= color_table
[*src_pixel
>> 4];
2941 dst_start
[x
* 3] = rgb
.rgbBlue
;
2942 dst_start
[x
* 3 + 1] = rgb
.rgbGreen
;
2943 dst_start
[x
* 3 + 2] = rgb
.rgbRed
;
2945 if(pad_size
) memset(dst_start
+ x
* 3, 0, pad_size
);
2946 dst_start
+= dst
->stride
;
2947 src_start
+= src
->stride
;
2954 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2955 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
2956 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2958 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
2959 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2962 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
2963 rgb
= color_table
[src_val
];
2964 dst_start
[x
* 3] = rgb
.rgbBlue
;
2965 dst_start
[x
* 3 + 1] = rgb
.rgbGreen
;
2966 dst_start
[x
* 3 + 2] = rgb
.rgbRed
;
2968 if(pad_size
) memset(dst_start
+ x
* 3, 0, pad_size
);
2969 dst_start
+= dst
->stride
;
2970 src_start
+= src
->stride
;
2977 static void convert_to_555(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
2979 WORD
*dst_start
= get_pixel_ptr_16(dst
, 0, 0), *dst_pixel
;
2980 INT x
, y
, pad_size
= ((dst
->width
+ 1) & ~1) * 2 - (src_rect
->right
- src_rect
->left
) * 2;
2983 switch(src
->bit_count
)
2987 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2989 if(src
->funcs
== &funcs_8888
)
2991 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2993 dst_pixel
= dst_start
;
2994 src_pixel
= src_start
;
2995 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2997 src_val
= *src_pixel
++;
2998 *dst_pixel
++ = ((src_val
>> 9) & 0x7c00) |
2999 ((src_val
>> 6) & 0x03e0) |
3000 ((src_val
>> 3) & 0x001f);
3002 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3003 dst_start
+= dst
->stride
/ 2;
3004 src_start
+= src
->stride
/ 4;
3007 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
3009 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3011 dst_pixel
= dst_start
;
3012 src_pixel
= src_start
;
3013 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3015 src_val
= *src_pixel
++;
3016 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 7) & 0x7c00) |
3017 (((src_val
>> src
->green_shift
) << 2) & 0x03e0) |
3018 (((src_val
>> src
->blue_shift
) >> 3) & 0x001f);
3020 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3021 dst_start
+= dst
->stride
/ 2;
3022 src_start
+= src
->stride
/ 4;
3027 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3029 dst_pixel
= dst_start
;
3030 src_pixel
= src_start
;
3031 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3033 src_val
= *src_pixel
++;
3034 *dst_pixel
++ = (((get_field(src_val
, src
->red_shift
, src
->red_len
) << 7) & 0x7c00) |
3035 ((get_field(src_val
, src
->green_shift
, src
->green_len
) << 2) & 0x03e0) |
3036 ( get_field(src_val
, src
->blue_shift
, src
->blue_len
) >> 3));
3038 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3039 dst_start
+= dst
->stride
/ 2;
3040 src_start
+= src
->stride
/ 4;
3048 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3050 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3052 dst_pixel
= dst_start
;
3053 src_pixel
= src_start
;
3054 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3057 rgb
.rgbBlue
= *src_pixel
++;
3058 rgb
.rgbGreen
= *src_pixel
++;
3059 rgb
.rgbRed
= *src_pixel
++;
3061 *dst_pixel
++ = ((rgb
.rgbRed
<< 7) & 0x7c00) |
3062 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
3063 ((rgb
.rgbBlue
>> 3) & 0x001f);
3065 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3066 dst_start
+= dst
->stride
/ 2;
3067 src_start
+= src
->stride
;
3074 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3075 if(src
->funcs
== &funcs_555
)
3077 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
3078 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
3081 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3083 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 2);
3084 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
3085 dst_start
+= dst
->stride
/ 2;
3086 src_start
+= src
->stride
/ 2;
3090 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
3092 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3094 dst_pixel
= dst_start
;
3095 src_pixel
= src_start
;
3096 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3098 src_val
= *src_pixel
++;
3099 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 10) & 0x7c00) |
3100 (((src_val
>> src
->green_shift
) << 5) & 0x03e0) |
3101 ( (src_val
>> src
->blue_shift
) & 0x001f);
3103 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3104 dst_start
+= dst
->stride
/ 2;
3105 src_start
+= src
->stride
/ 2;
3108 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
3110 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3112 dst_pixel
= dst_start
;
3113 src_pixel
= src_start
;
3114 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3116 src_val
= *src_pixel
++;
3117 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 10) & 0x7c00) |
3118 (((src_val
>> src
->green_shift
) << 4) & 0x03e0) |
3119 ( (src_val
>> src
->blue_shift
) & 0x001f);
3121 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3122 dst_start
+= dst
->stride
/ 2;
3123 src_start
+= src
->stride
/ 2;
3128 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3130 dst_pixel
= dst_start
;
3131 src_pixel
= src_start
;
3132 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3134 src_val
= *src_pixel
++;
3135 *dst_pixel
++ = (((get_field(src_val
, src
->red_shift
, src
->red_len
) << 7) & 0x7c00) |
3136 ((get_field(src_val
, src
->green_shift
, src
->green_len
) << 2) & 0x03e0) |
3137 ( get_field(src_val
, src
->blue_shift
, src
->blue_len
) >> 3));
3139 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3140 dst_start
+= dst
->stride
/ 2;
3141 src_start
+= src
->stride
/ 2;
3149 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3150 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3151 WORD dst_colors
[256];
3154 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
3155 dst_colors
[i
] = ((color_table
[i
].rgbRed
<< 7) & 0x7c00) |
3156 ((color_table
[i
].rgbGreen
<< 2) & 0x03e0) |
3157 ((color_table
[i
].rgbBlue
>> 3) & 0x001f);
3159 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3161 dst_pixel
= dst_start
;
3162 src_pixel
= src_start
;
3163 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3164 *dst_pixel
++ = dst_colors
[*src_pixel
++];
3166 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3167 dst_start
+= dst
->stride
/ 2;
3168 src_start
+= src
->stride
;
3175 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3176 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3177 WORD dst_colors
[16];
3180 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
3181 dst_colors
[i
] = ((color_table
[i
].rgbRed
<< 7) & 0x7c00) |
3182 ((color_table
[i
].rgbGreen
<< 2) & 0x03e0) |
3183 ((color_table
[i
].rgbBlue
>> 3) & 0x001f);
3185 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3187 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
3188 src_pixel
= src_start
;
3189 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
3192 dst_start
[x
] = dst_colors
[*src_pixel
++ & 0xf];
3194 dst_start
[x
] = dst_colors
[*src_pixel
>> 4];
3196 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3197 dst_start
+= dst
->stride
/ 2;
3198 src_start
+= src
->stride
;
3205 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3206 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
3210 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
3211 dst_colors
[i
] = ((color_table
[i
].rgbRed
<< 7) & 0x7c00) |
3212 ((color_table
[i
].rgbGreen
<< 2) & 0x03e0) |
3213 ((color_table
[i
].rgbBlue
>> 3) & 0x001f);
3215 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3217 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
3218 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
3220 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
3221 dst_start
[x
] = dst_colors
[src_val
];
3223 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3224 dst_start
+= dst
->stride
/ 2;
3225 src_start
+= src
->stride
;
3232 static void convert_to_16(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
3234 WORD
*dst_start
= get_pixel_ptr_16(dst
, 0, 0), *dst_pixel
;
3235 INT x
, y
, pad_size
= ((dst
->width
+ 1) & ~1) * 2 - (src_rect
->right
- src_rect
->left
) * 2;
3238 switch(src
->bit_count
)
3242 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3244 if(src
->funcs
== &funcs_8888
)
3246 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3248 dst_pixel
= dst_start
;
3249 src_pixel
= src_start
;
3250 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3252 src_val
= *src_pixel
++;
3253 *dst_pixel
++ = rgb_to_pixel_masks(dst
, src_val
>> 16, src_val
>> 8, src_val
);
3255 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3256 dst_start
+= dst
->stride
/ 2;
3257 src_start
+= src
->stride
/ 4;
3260 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
3262 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3264 dst_pixel
= dst_start
;
3265 src_pixel
= src_start
;
3266 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3268 src_val
= *src_pixel
++;
3269 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
3270 src_val
>> src
->red_shift
,
3271 src_val
>> src
->green_shift
,
3272 src_val
>> src
->blue_shift
);
3274 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3275 dst_start
+= dst
->stride
/ 2;
3276 src_start
+= src
->stride
/ 4;
3281 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3283 dst_pixel
= dst_start
;
3284 src_pixel
= src_start
;
3285 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3287 src_val
= *src_pixel
++;
3288 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
3289 get_field(src_val
, src
->red_shift
, src
->red_len
),
3290 get_field(src_val
, src
->green_shift
, src
->green_len
),
3291 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3293 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3294 dst_start
+= dst
->stride
/ 2;
3295 src_start
+= src
->stride
/ 4;
3303 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3305 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3307 dst_pixel
= dst_start
;
3308 src_pixel
= src_start
;
3309 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, src_pixel
+= 3)
3310 *dst_pixel
++ = rgb_to_pixel_masks(dst
, src_pixel
[2], src_pixel
[1], src_pixel
[0]);
3311 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3312 dst_start
+= dst
->stride
/ 2;
3313 src_start
+= src
->stride
;
3320 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3321 if(src
->funcs
== &funcs_555
)
3323 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3325 dst_pixel
= dst_start
;
3326 src_pixel
= src_start
;
3327 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3329 src_val
= *src_pixel
++;
3330 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
3331 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
3332 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
3333 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07));
3335 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3336 dst_start
+= dst
->stride
/ 2;
3337 src_start
+= src
->stride
/ 2;
3340 else if(bit_fields_match(src
, dst
))
3342 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
3343 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
3346 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3348 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 2);
3349 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
3350 dst_start
+= dst
->stride
/ 2;
3351 src_start
+= src
->stride
/ 2;
3355 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
3357 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3359 dst_pixel
= dst_start
;
3360 src_pixel
= src_start
;
3361 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3363 src_val
= *src_pixel
++;
3364 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
3365 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3366 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3367 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
3368 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
3369 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3370 (((src_val
>> src
->blue_shift
) >> 2) & 0x07));
3372 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3373 dst_start
+= dst
->stride
/ 2;
3374 src_start
+= src
->stride
/ 2;
3377 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
3379 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3381 dst_pixel
= dst_start
;
3382 src_pixel
= src_start
;
3383 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3385 src_val
= *src_pixel
++;
3386 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
3387 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3388 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3389 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
3390 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
3391 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3392 (((src_val
>> src
->blue_shift
) >> 2) & 0x07));
3394 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3395 dst_start
+= dst
->stride
/ 2;
3396 src_start
+= src
->stride
/ 2;
3401 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3403 dst_pixel
= dst_start
;
3404 src_pixel
= src_start
;
3405 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3407 src_val
= *src_pixel
++;
3408 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
3409 get_field(src_val
, src
->red_shift
, src
->red_len
),
3410 get_field(src_val
, src
->green_shift
, src
->green_len
),
3411 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3413 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3414 dst_start
+= dst
->stride
/ 2;
3415 src_start
+= src
->stride
/ 2;
3423 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3424 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3425 WORD dst_colors
[256];
3428 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
3429 dst_colors
[i
] = rgbquad_to_pixel_masks(dst
, color_table
[i
]);
3431 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3433 dst_pixel
= dst_start
;
3434 src_pixel
= src_start
;
3435 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3436 *dst_pixel
++ = dst_colors
[*src_pixel
++];
3438 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3439 dst_start
+= dst
->stride
/ 2;
3440 src_start
+= src
->stride
;
3447 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3448 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3449 WORD dst_colors
[16];
3452 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
3453 dst_colors
[i
] = rgbquad_to_pixel_masks(dst
, color_table
[i
]);
3455 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3457 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
3458 src_pixel
= src_start
;
3459 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
3462 dst_start
[x
] = dst_colors
[*src_pixel
++ & 0xf];
3464 dst_start
[x
] = dst_colors
[*src_pixel
>> 4];
3466 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3467 dst_start
+= dst
->stride
/ 2;
3468 src_start
+= src
->stride
;
3475 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3476 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
3480 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
3481 dst_colors
[i
] = rgbquad_to_pixel_masks(dst
, color_table
[i
]);
3483 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3485 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
3486 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
3488 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
3489 dst_start
[x
] = dst_colors
[src_val
];
3491 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3492 dst_start
+= dst
->stride
/ 2;
3493 src_start
+= src
->stride
;
3500 static inline BOOL
color_tables_match(const dib_info
*d1
, const dib_info
*d2
)
3502 if (!d1
->color_table
|| !d2
->color_table
) return (!d1
->color_table
&& !d2
->color_table
);
3503 return !memcmp(d1
->color_table
, d2
->color_table
, (1 << d1
->bit_count
) * sizeof(d1
->color_table
[0]));
3506 static inline DWORD
rgb_lookup_colortable(const dib_info
*dst
, BYTE r
, BYTE g
, BYTE b
)
3508 /* Windows reduces precision to 5 bits, probably in order to build some sort of lookup cache */
3509 return rgb_to_pixel_colortable( dst
, (r
& ~7) + 4, (g
& ~7) + 4, (b
& ~7) + 4 );
3512 static void convert_to_8(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
3514 BYTE
*dst_start
= get_pixel_ptr_8(dst
, 0, 0), *dst_pixel
;
3515 INT x
, y
, pad_size
= ((dst
->width
+ 3) & ~3) - (src_rect
->right
- src_rect
->left
);
3518 switch(src
->bit_count
)
3522 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3524 if(src
->funcs
== &funcs_8888
)
3526 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3528 dst_pixel
= dst_start
;
3529 src_pixel
= src_start
;
3530 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3532 src_val
= *src_pixel
++;
3533 *dst_pixel
++ = rgb_lookup_colortable(dst
, src_val
>> 16, src_val
>> 8, src_val
);
3535 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3536 dst_start
+= dst
->stride
;
3537 src_start
+= src
->stride
/ 4;
3540 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
3542 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3544 dst_pixel
= dst_start
;
3545 src_pixel
= src_start
;
3546 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3548 src_val
= *src_pixel
++;
3549 *dst_pixel
++ = rgb_lookup_colortable(dst
,
3550 src_val
>> src
->red_shift
,
3551 src_val
>> src
->green_shift
,
3552 src_val
>> src
->blue_shift
);
3554 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3555 dst_start
+= dst
->stride
;
3556 src_start
+= src
->stride
/ 4;
3561 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3563 dst_pixel
= dst_start
;
3564 src_pixel
= src_start
;
3565 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3567 src_val
= *src_pixel
++;
3568 *dst_pixel
++ = rgb_lookup_colortable(dst
,
3569 get_field(src_val
, src
->red_shift
, src
->red_len
),
3570 get_field(src_val
, src
->green_shift
, src
->green_len
),
3571 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3573 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3574 dst_start
+= dst
->stride
;
3575 src_start
+= src
->stride
/ 4;
3583 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3585 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3587 dst_pixel
= dst_start
;
3588 src_pixel
= src_start
;
3589 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, src_pixel
+= 3)
3591 *dst_pixel
++ = rgb_lookup_colortable(dst
, src_pixel
[2], src_pixel
[1], src_pixel
[0] );
3593 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3594 dst_start
+= dst
->stride
;
3595 src_start
+= src
->stride
;
3602 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3603 if(src
->funcs
== &funcs_555
)
3605 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3607 dst_pixel
= dst_start
;
3608 src_pixel
= src_start
;
3609 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3611 src_val
= *src_pixel
++;
3612 *dst_pixel
++ = rgb_lookup_colortable(dst
,
3613 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
3614 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
3615 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07) );
3617 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3618 dst_start
+= dst
->stride
;
3619 src_start
+= src
->stride
/ 2;
3622 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
3624 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3626 dst_pixel
= dst_start
;
3627 src_pixel
= src_start
;
3628 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3630 src_val
= *src_pixel
++;
3631 *dst_pixel
++ = rgb_lookup_colortable(dst
,
3632 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3633 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3634 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
3635 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
3636 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3637 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
3639 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3640 dst_start
+= dst
->stride
;
3641 src_start
+= src
->stride
/ 2;
3644 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
3646 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3648 dst_pixel
= dst_start
;
3649 src_pixel
= src_start
;
3650 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3652 src_val
= *src_pixel
++;
3653 *dst_pixel
++ = rgb_lookup_colortable(dst
,
3654 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3655 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3656 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
3657 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
3658 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3659 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
3661 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3662 dst_start
+= dst
->stride
;
3663 src_start
+= src
->stride
/ 2;
3668 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3670 dst_pixel
= dst_start
;
3671 src_pixel
= src_start
;
3672 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3674 src_val
= *src_pixel
++;
3675 *dst_pixel
++ = rgb_lookup_colortable(dst
,
3676 get_field(src_val
, src
->red_shift
, src
->red_len
),
3677 get_field(src_val
, src
->green_shift
, src
->green_len
),
3678 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3680 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3681 dst_start
+= dst
->stride
;
3682 src_start
+= src
->stride
/ 2;
3690 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3692 if(color_tables_match(dst
, src
))
3694 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
3695 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
3698 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3700 memcpy(dst_start
, src_start
, src_rect
->right
- src_rect
->left
);
3701 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
3702 dst_start
+= dst
->stride
;
3703 src_start
+= src
->stride
;
3709 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3710 BYTE dst_colors
[256];
3713 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
3714 dst_colors
[i
] = rgbquad_to_pixel_colortable(dst
, color_table
[i
]);
3716 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3718 dst_pixel
= dst_start
;
3719 src_pixel
= src_start
;
3720 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3721 *dst_pixel
++ = dst_colors
[*src_pixel
++];
3723 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3724 dst_start
+= dst
->stride
;
3725 src_start
+= src
->stride
;
3733 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3734 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3735 BYTE dst_colors
[16];
3738 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
3739 dst_colors
[i
] = rgbquad_to_pixel_colortable(dst
, color_table
[i
]);
3741 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3743 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
3744 src_pixel
= src_start
;
3745 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
3748 dst_start
[x
] = dst_colors
[*src_pixel
++ & 0xf];
3750 dst_start
[x
] = dst_colors
[*src_pixel
>> 4];
3752 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3753 dst_start
+= dst
->stride
;
3754 src_start
+= src
->stride
;
3761 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3762 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
3766 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
3767 dst_colors
[i
] = FILTER_DIBINDEX(color_table
[i
], rgbquad_to_pixel_colortable(dst
, color_table
[i
]));
3769 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3771 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
3772 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
3774 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
3775 dst_start
[x
] = dst_colors
[src_val
];
3777 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3778 dst_start
+= dst
->stride
;
3779 src_start
+= src
->stride
;
3786 static void convert_to_4(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
3788 BYTE
*dst_start
= get_pixel_ptr_4(dst
, 0, 0), *dst_pixel
, dst_val
;
3789 INT x
, y
, pad_size
= ((dst
->width
+ 7) & ~7) / 2 - (src_rect
->right
- src_rect
->left
+ 1) / 2;
3792 switch(src
->bit_count
)
3796 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3798 if(src
->funcs
== &funcs_8888
)
3800 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3802 dst_pixel
= dst_start
;
3803 src_pixel
= src_start
;
3804 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3806 src_val
= *src_pixel
++;
3807 dst_val
= rgb_to_pixel_colortable(dst
, src_val
>> 16, src_val
>> 8, src_val
);
3808 if((x
- src_rect
->left
) & 1)
3810 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3814 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3818 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3819 memset(dst_pixel
, 0, pad_size
);
3821 dst_start
+= dst
->stride
;
3822 src_start
+= src
->stride
/ 4;
3825 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
3827 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3829 dst_pixel
= dst_start
;
3830 src_pixel
= src_start
;
3831 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3833 src_val
= *src_pixel
++;
3834 dst_val
= rgb_to_pixel_colortable(dst
,
3835 src_val
>> src
->red_shift
,
3836 src_val
>> src
->green_shift
,
3837 src_val
>> src
->blue_shift
);
3838 if((x
- src_rect
->left
) & 1)
3840 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3844 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3848 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3849 memset(dst_pixel
, 0, pad_size
);
3851 dst_start
+= dst
->stride
;
3852 src_start
+= src
->stride
/ 4;
3857 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3859 dst_pixel
= dst_start
;
3860 src_pixel
= src_start
;
3861 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3863 src_val
= *src_pixel
++;
3864 dst_val
= rgb_to_pixel_colortable(dst
,
3865 get_field(src_val
, src
->red_shift
, src
->red_len
),
3866 get_field(src_val
, src
->green_shift
, src
->green_len
),
3867 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3868 if((x
- src_rect
->left
) & 1)
3870 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3874 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3878 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3879 memset(dst_pixel
, 0, pad_size
);
3881 dst_start
+= dst
->stride
;
3882 src_start
+= src
->stride
/ 4;
3890 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3892 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3894 dst_pixel
= dst_start
;
3895 src_pixel
= src_start
;
3896 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, src_pixel
+= 3)
3898 dst_val
= rgb_to_pixel_colortable(dst
, src_pixel
[2], src_pixel
[1], src_pixel
[0]);
3900 if((x
- src_rect
->left
) & 1)
3902 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3906 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3910 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3911 memset(dst_pixel
, 0, pad_size
);
3913 dst_start
+= dst
->stride
;
3914 src_start
+= src
->stride
;
3921 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3922 if(src
->funcs
== &funcs_555
)
3924 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3926 dst_pixel
= dst_start
;
3927 src_pixel
= src_start
;
3928 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3930 src_val
= *src_pixel
++;
3931 dst_val
= rgb_to_pixel_colortable(dst
,
3932 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
3933 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
3934 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07) );
3935 if((x
- src_rect
->left
) & 1)
3937 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3941 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3945 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3946 memset(dst_pixel
, 0, pad_size
);
3948 dst_start
+= dst
->stride
;
3949 src_start
+= src
->stride
/ 2;
3952 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
3954 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3956 dst_pixel
= dst_start
;
3957 src_pixel
= src_start
;
3958 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3960 src_val
= *src_pixel
++;
3961 dst_val
= rgb_to_pixel_colortable(dst
,
3962 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3963 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3964 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
3965 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
3966 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3967 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
3968 if((x
- src_rect
->left
) & 1)
3970 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3974 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3978 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3979 memset(dst_pixel
, 0, pad_size
);
3981 dst_start
+= dst
->stride
;
3982 src_start
+= src
->stride
/ 2;
3985 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
3987 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3989 dst_pixel
= dst_start
;
3990 src_pixel
= src_start
;
3991 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3993 src_val
= *src_pixel
++;
3994 dst_val
= rgb_to_pixel_colortable(dst
,
3995 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3996 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3997 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
3998 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
3999 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
4000 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
4001 if((x
- src_rect
->left
) & 1)
4003 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
4007 *dst_pixel
= (dst_val
<< 4) & 0xf0;
4011 if((x
- src_rect
->left
) & 1) dst_pixel
++;
4012 memset(dst_pixel
, 0, pad_size
);
4014 dst_start
+= dst
->stride
;
4015 src_start
+= src
->stride
/ 2;
4020 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4022 dst_pixel
= dst_start
;
4023 src_pixel
= src_start
;
4024 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
4026 src_val
= *src_pixel
++;
4027 dst_val
= rgb_to_pixel_colortable(dst
,
4028 get_field(src_val
, src
->red_shift
, src
->red_len
),
4029 get_field(src_val
, src
->green_shift
, src
->green_len
),
4030 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
4031 if((x
- src_rect
->left
) & 1)
4033 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
4037 *dst_pixel
= (dst_val
<< 4) & 0xf0;
4041 if((x
- src_rect
->left
) & 1) dst_pixel
++;
4042 memset(dst_pixel
, 0, pad_size
);
4044 dst_start
+= dst
->stride
;
4045 src_start
+= src
->stride
/ 2;
4053 const RGBQUAD
*color_table
= get_dib_color_table( src
);
4054 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
4055 BYTE dst_colors
[256];
4058 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
4059 dst_colors
[i
] = rgbquad_to_pixel_colortable(dst
, color_table
[i
]);
4061 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4063 dst_pixel
= dst_start
;
4064 src_pixel
= src_start
;
4065 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
4067 dst_val
= dst_colors
[*src_pixel
++];
4068 if((x
- src_rect
->left
) & 1)
4070 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
4074 *dst_pixel
= (dst_val
<< 4) & 0xf0;
4078 if((x
- src_rect
->left
) & 1) dst_pixel
++;
4079 memset(dst_pixel
, 0, pad_size
);
4081 dst_start
+= dst
->stride
;
4082 src_start
+= src
->stride
;
4089 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
4091 if(color_tables_match(dst
, src
) && ((src
->rect
.left
+ src_rect
->left
) & 1) == 0)
4093 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
4094 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
4097 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4099 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
+ 1) / 2);
4100 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
+ 1) / 2, 0, pad_size
);
4101 dst_start
+= dst
->stride
;
4102 src_start
+= src
->stride
;
4108 const RGBQUAD
*color_table
= get_dib_color_table( src
);
4109 BYTE dst_colors
[16];
4112 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
4113 dst_colors
[i
] = rgbquad_to_pixel_colortable(dst
, color_table
[i
]);
4115 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4117 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
4118 dst_pixel
= dst_start
;
4119 src_pixel
= src_start
;
4120 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, pos
++)
4123 dst_val
= dst_colors
[*src_pixel
++ & 0xf];
4125 dst_val
= dst_colors
[*src_pixel
>> 4];
4126 if((x
- src_rect
->left
) & 1)
4128 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
4132 *dst_pixel
= (dst_val
<< 4) & 0xf0;
4136 if((x
- src_rect
->left
) & 1) dst_pixel
++;
4137 memset(dst_pixel
, 0, pad_size
);
4139 dst_start
+= dst
->stride
;
4140 src_start
+= src
->stride
;
4148 const RGBQUAD
*color_table
= get_dib_color_table( src
);
4149 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
4153 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
4154 dst_colors
[i
] = FILTER_DIBINDEX(color_table
[i
], rgbquad_to_pixel_colortable(dst
, color_table
[i
]));
4156 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4158 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
4159 dst_pixel
= dst_start
;
4160 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, pos
++)
4162 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
4163 dst_val
= dst_colors
[src_val
];
4164 if((x
- src_rect
->left
) & 1)
4166 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
4170 *dst_pixel
= (dst_val
<< 4) & 0xf0;
4174 if((x
- src_rect
->left
) & 1) dst_pixel
++;
4175 memset(dst_pixel
, 0, pad_size
);
4177 dst_start
+= dst
->stride
;
4178 src_start
+= src
->stride
;
4185 static void convert_to_1(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
4187 BYTE
*dst_start
= get_pixel_ptr_1(dst
, 0, 0), *dst_pixel
, dst_val
;
4188 INT x
, y
, pad_size
= ((dst
->width
+ 31) & ~31) / 8 - (src_rect
->right
- src_rect
->left
+ 7) / 8;
4189 RGBQUAD rgb
, bg_entry
= *get_dib_color_table( dst
); /* entry 0 is the background color */
4193 switch(src
->bit_count
)
4197 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
4198 DWORD bg_pixel
= FILTER_DIBINDEX(bg_entry
, rgbquad_to_pixel_masks(src
, bg_entry
));
4200 if(src
->funcs
== &funcs_8888
)
4202 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4204 dst_pixel
= dst_start
;
4205 src_pixel
= src_start
;
4206 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4208 src_val
= *src_pixel
++;
4209 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
, bg_pixel
,
4210 src_val
>> 16, src_val
>> 8, src_val
);
4211 if(bit_pos
== 0) *dst_pixel
= 0;
4212 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4222 if(bit_pos
!= 0) dst_pixel
++;
4223 memset(dst_pixel
, 0, pad_size
);
4225 dst_start
+= dst
->stride
;
4226 src_start
+= src
->stride
/ 4;
4229 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
4231 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4233 dst_pixel
= dst_start
;
4234 src_pixel
= src_start
;
4235 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4237 src_val
= *src_pixel
++;
4238 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
, bg_pixel
,
4239 src_val
>> src
->red_shift
,
4240 src_val
>> src
->green_shift
,
4241 src_val
>> src
->blue_shift
);
4243 if(bit_pos
== 0) *dst_pixel
= 0;
4244 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4254 if(bit_pos
!= 0) dst_pixel
++;
4255 memset(dst_pixel
, 0, pad_size
);
4257 dst_start
+= dst
->stride
;
4258 src_start
+= src
->stride
/ 4;
4263 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4265 dst_pixel
= dst_start
;
4266 src_pixel
= src_start
;
4267 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4269 src_val
= *src_pixel
++;
4270 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
, bg_pixel
,
4271 get_field(src_val
, src
->red_shift
, src
->red_len
),
4272 get_field(src_val
, src
->green_shift
, src
->green_len
),
4273 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
4275 if(bit_pos
== 0) *dst_pixel
= 0;
4276 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4286 if(bit_pos
!= 0) dst_pixel
++;
4287 memset(dst_pixel
, 0, pad_size
);
4289 dst_start
+= dst
->stride
;
4290 src_start
+= src
->stride
/ 4;
4298 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
4299 DWORD bg_pixel
= FILTER_DIBINDEX(bg_entry
, RGB(bg_entry
.rgbRed
, bg_entry
.rgbGreen
, bg_entry
.rgbBlue
));
4301 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4303 dst_pixel
= dst_start
;
4304 src_pixel
= src_start
;
4305 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++, src_pixel
+= 3)
4307 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, RGB(src_pixel
[2], src_pixel
[1], src_pixel
[0]),
4308 bg_pixel
, src_pixel
[2], src_pixel
[1], src_pixel
[0]);
4310 if(bit_pos
== 0) *dst_pixel
= 0;
4311 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4321 if(bit_pos
!= 0) dst_pixel
++;
4322 memset(dst_pixel
, 0, pad_size
);
4324 dst_start
+= dst
->stride
;
4325 src_start
+= src
->stride
;
4332 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
4333 DWORD bg_pixel
= FILTER_DIBINDEX(bg_entry
, rgbquad_to_pixel_masks(src
, bg_entry
));
4335 if(src
->funcs
== &funcs_555
)
4337 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4339 dst_pixel
= dst_start
;
4340 src_pixel
= src_start
;
4341 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4343 src_val
= *src_pixel
++;
4344 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
, bg_pixel
,
4345 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
4346 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
4347 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07));
4349 if(bit_pos
== 0) *dst_pixel
= 0;
4350 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4360 if(bit_pos
!= 0) dst_pixel
++;
4361 memset(dst_pixel
, 0, pad_size
);
4363 dst_start
+= dst
->stride
;
4364 src_start
+= src
->stride
/ 2;
4367 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
4369 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4371 dst_pixel
= dst_start
;
4372 src_pixel
= src_start
;
4373 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4375 src_val
= *src_pixel
++;
4376 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
, bg_pixel
,
4377 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
4378 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
4379 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
4380 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
4381 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
4382 (((src_val
>> src
->blue_shift
) >> 2) & 0x07));
4383 if(bit_pos
== 0) *dst_pixel
= 0;
4384 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4394 if(bit_pos
!= 0) dst_pixel
++;
4395 memset(dst_pixel
, 0, pad_size
);
4397 dst_start
+= dst
->stride
;
4398 src_start
+= src
->stride
/ 2;
4401 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
4403 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4405 dst_pixel
= dst_start
;
4406 src_pixel
= src_start
;
4407 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4409 src_val
= *src_pixel
++;
4410 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
, bg_pixel
,
4411 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
4412 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
4413 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
4414 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
4415 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
4416 (((src_val
>> src
->blue_shift
) >> 2) & 0x07));
4417 if(bit_pos
== 0) *dst_pixel
= 0;
4418 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4428 if(bit_pos
!= 0) dst_pixel
++;
4429 memset(dst_pixel
, 0, pad_size
);
4431 dst_start
+= dst
->stride
;
4432 src_start
+= src
->stride
/ 2;
4437 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4439 dst_pixel
= dst_start
;
4440 src_pixel
= src_start
;
4441 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4443 src_val
= *src_pixel
++;
4444 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
, bg_pixel
,
4445 get_field(src_val
, src
->red_shift
, src
->red_len
),
4446 get_field(src_val
, src
->green_shift
, src
->green_len
),
4447 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
4448 if(bit_pos
== 0) *dst_pixel
= 0;
4449 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4459 if(bit_pos
!= 0) dst_pixel
++;
4460 memset(dst_pixel
, 0, pad_size
);
4462 dst_start
+= dst
->stride
;
4463 src_start
+= src
->stride
/ 2;
4471 const RGBQUAD
*color_table
= get_dib_color_table( src
);
4472 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
4473 DWORD bg_pixel
= FILTER_DIBINDEX(bg_entry
, rgbquad_to_pixel_colortable(src
, bg_entry
));
4475 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4477 dst_pixel
= dst_start
;
4478 src_pixel
= src_start
;
4479 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4481 BYTE src_val
= *src_pixel
++;
4482 rgb
= color_table
[src_val
];
4483 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
, bg_pixel
,
4484 rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
4486 if(bit_pos
== 0) *dst_pixel
= 0;
4487 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4497 if(bit_pos
!= 0) dst_pixel
++;
4498 memset(dst_pixel
, 0, pad_size
);
4500 dst_start
+= dst
->stride
;
4501 src_start
+= src
->stride
;
4508 const RGBQUAD
*color_table
= get_dib_color_table( src
);
4509 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
4510 DWORD bg_pixel
= FILTER_DIBINDEX(bg_entry
, rgbquad_to_pixel_colortable(src
, bg_entry
));
4512 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4514 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
4515 dst_pixel
= dst_start
;
4516 src_pixel
= src_start
;
4517 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++, pos
++)
4519 src_val
= (pos
& 1) ? *src_pixel
++ & 0xf : *src_pixel
>> 4;
4520 rgb
= color_table
[src_val
];
4521 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
, bg_pixel
,
4522 rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
4524 if(bit_pos
== 0) *dst_pixel
= 0;
4525 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4535 if(bit_pos
!= 0) dst_pixel
++;
4536 memset(dst_pixel
, 0, pad_size
);
4538 dst_start
+= dst
->stride
;
4539 src_start
+= src
->stride
;
4544 /* Note that while MSDN states that a 1 bpp dib brush -> mono dc
4545 uses text/bkgnd colours instead of the dib's colour table, this
4546 doesn't appear to be the case for a dc backed by a
4551 const RGBQUAD
*color_table
= get_dib_color_table( src
);
4552 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
4553 DWORD bg_pixel
= FILTER_DIBINDEX(bg_entry
, rgbquad_to_pixel_colortable(src
, bg_entry
));
4555 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4557 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
4558 dst_pixel
= dst_start
;
4559 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++, pos
++)
4561 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
4562 rgb
= color_table
[src_val
];
4563 dst_val
= FILTER_DIBINDEX(rgb
, rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
, bg_pixel
,
4564 rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
));
4565 if(bit_pos
== 0) *dst_pixel
= 0;
4566 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4576 if(bit_pos
!= 0) dst_pixel
++;
4577 memset(dst_pixel
, 0, pad_size
);
4579 dst_start
+= dst
->stride
;
4580 src_start
+= src
->stride
;
4587 static void convert_to_null(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
4591 static inline BYTE
blend_color(BYTE dst
, BYTE src
, DWORD alpha
)
4593 return (src
* alpha
+ dst
* (255 - alpha
) + 127) / 255;
4596 static inline DWORD
blend_argb_constant_alpha( DWORD dst
, DWORD src
, DWORD alpha
)
4598 return (blend_color( dst
, src
, alpha
) |
4599 blend_color( dst
>> 8, src
>> 8, alpha
) << 8 |
4600 blend_color( dst
>> 16, src
>> 16, alpha
) << 16 |
4601 blend_color( dst
>> 24, src
>> 24, alpha
) << 24);
4604 static inline DWORD
blend_argb_no_src_alpha( DWORD dst
, DWORD src
, DWORD alpha
)
4606 return (blend_color( dst
, src
, alpha
) |
4607 blend_color( dst
>> 8, src
>> 8, alpha
) << 8 |
4608 blend_color( dst
>> 16, src
>> 16, alpha
) << 16 |
4609 blend_color( dst
>> 24, 255, alpha
) << 24);
4612 static inline DWORD
blend_argb( DWORD dst
, DWORD src
)
4615 BYTE g
= (BYTE
)(src
>> 8);
4616 BYTE r
= (BYTE
)(src
>> 16);
4617 DWORD alpha
= (BYTE
)(src
>> 24);
4618 return ((b
+ ((BYTE
)dst
* (255 - alpha
) + 127) / 255) |
4619 (g
+ ((BYTE
)(dst
>> 8) * (255 - alpha
) + 127) / 255) << 8 |
4620 (r
+ ((BYTE
)(dst
>> 16) * (255 - alpha
) + 127) / 255) << 16 |
4621 (alpha
+ ((BYTE
)(dst
>> 24) * (255 - alpha
) + 127) / 255) << 24);
4624 static inline DWORD
blend_argb_alpha( DWORD dst
, DWORD src
, DWORD alpha
)
4626 BYTE b
= ((BYTE
)src
* alpha
+ 127) / 255;
4627 BYTE g
= ((BYTE
)(src
>> 8) * alpha
+ 127) / 255;
4628 BYTE r
= ((BYTE
)(src
>> 16) * alpha
+ 127) / 255;
4629 alpha
= ((BYTE
)(src
>> 24) * alpha
+ 127) / 255;
4630 return ((b
+ ((BYTE
)dst
* (255 - alpha
) + 127) / 255) |
4631 (g
+ ((BYTE
)(dst
>> 8) * (255 - alpha
) + 127) / 255) << 8 |
4632 (r
+ ((BYTE
)(dst
>> 16) * (255 - alpha
) + 127) / 255) << 16 |
4633 (alpha
+ ((BYTE
)(dst
>> 24) * (255 - alpha
) + 127) / 255) << 24);
4636 static inline DWORD
blend_rgb( BYTE dst_r
, BYTE dst_g
, BYTE dst_b
, DWORD src
, BLENDFUNCTION blend
)
4638 if (blend
.AlphaFormat
& AC_SRC_ALPHA
)
4640 DWORD alpha
= blend
.SourceConstantAlpha
;
4641 BYTE src_b
= ((BYTE
)src
* alpha
+ 127) / 255;
4642 BYTE src_g
= ((BYTE
)(src
>> 8) * alpha
+ 127) / 255;
4643 BYTE src_r
= ((BYTE
)(src
>> 16) * alpha
+ 127) / 255;
4644 alpha
= ((BYTE
)(src
>> 24) * alpha
+ 127) / 255;
4645 return ((src_b
+ (dst_b
* (255 - alpha
) + 127) / 255) |
4646 (src_g
+ (dst_g
* (255 - alpha
) + 127) / 255) << 8 |
4647 (src_r
+ (dst_r
* (255 - alpha
) + 127) / 255) << 16);
4649 return (blend_color( dst_b
, src
, blend
.SourceConstantAlpha
) |
4650 blend_color( dst_g
, src
>> 8, blend
.SourceConstantAlpha
) << 8 |
4651 blend_color( dst_r
, src
>> 16, blend
.SourceConstantAlpha
) << 16);
4654 static void blend_rect_8888(const dib_info
*dst
, const RECT
*rc
,
4655 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4657 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4658 DWORD
*dst_ptr
= get_pixel_ptr_32( dst
, rc
->left
, rc
->top
);
4661 if (blend
.AlphaFormat
& AC_SRC_ALPHA
)
4663 if (blend
.SourceConstantAlpha
== 255)
4664 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
4665 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4666 dst_ptr
[x
] = blend_argb( dst_ptr
[x
], src_ptr
[x
] );
4668 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
4669 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4670 dst_ptr
[x
] = blend_argb_alpha( dst_ptr
[x
], src_ptr
[x
], blend
.SourceConstantAlpha
);
4672 else if (src
->compression
== BI_RGB
)
4673 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
4674 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4675 dst_ptr
[x
] = blend_argb_constant_alpha( dst_ptr
[x
], src_ptr
[x
], blend
.SourceConstantAlpha
);
4677 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
4678 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4679 dst_ptr
[x
] = blend_argb_no_src_alpha( dst_ptr
[x
], src_ptr
[x
], blend
.SourceConstantAlpha
);
4682 static void blend_rect_32(const dib_info
*dst
, const RECT
*rc
,
4683 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4685 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4686 DWORD
*dst_ptr
= get_pixel_ptr_32( dst
, rc
->left
, rc
->top
);
4689 if (dst
->red_len
== 8 && dst
->green_len
== 8 && dst
->blue_len
== 8)
4691 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
4693 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4695 DWORD val
= blend_rgb( dst_ptr
[x
] >> dst
->red_shift
,
4696 dst_ptr
[x
] >> dst
->green_shift
,
4697 dst_ptr
[x
] >> dst
->blue_shift
,
4698 src_ptr
[x
], blend
);
4699 dst_ptr
[x
] = ((( val
& 0xff) << dst
->blue_shift
) |
4700 (((val
>> 8) & 0xff) << dst
->green_shift
) |
4701 (((val
>> 16) & 0xff) << dst
->red_shift
));
4707 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
4709 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4711 DWORD val
= blend_rgb( get_field( dst_ptr
[x
], dst
->red_shift
, dst
->red_len
),
4712 get_field( dst_ptr
[x
], dst
->green_shift
, dst
->green_len
),
4713 get_field( dst_ptr
[x
], dst
->blue_shift
, dst
->blue_len
),
4714 src_ptr
[x
], blend
);
4715 dst_ptr
[x
] = rgb_to_pixel_masks( dst
, val
>> 16, val
>> 8, val
);
4721 static void blend_rect_24(const dib_info
*dst
, const RECT
*rc
,
4722 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4724 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4725 BYTE
*dst_ptr
= get_pixel_ptr_24( dst
, rc
->left
, rc
->top
);
4728 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
4730 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4732 DWORD val
= blend_rgb( dst_ptr
[x
* 3 + 2], dst_ptr
[x
* 3 + 1], dst_ptr
[x
* 3],
4733 src_ptr
[x
], blend
);
4734 dst_ptr
[x
* 3] = val
;
4735 dst_ptr
[x
* 3 + 1] = val
>> 8;
4736 dst_ptr
[x
* 3 + 2] = val
>> 16;
4741 static void blend_rect_555(const dib_info
*dst
, const RECT
*rc
,
4742 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4744 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4745 WORD
*dst_ptr
= get_pixel_ptr_16( dst
, rc
->left
, rc
->top
);
4748 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 2, src_ptr
+= src
->stride
/ 4)
4750 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4752 DWORD val
= blend_rgb( ((dst_ptr
[x
] >> 7) & 0xf8) | ((dst_ptr
[x
] >> 12) & 0x07),
4753 ((dst_ptr
[x
] >> 2) & 0xf8) | ((dst_ptr
[x
] >> 7) & 0x07),
4754 ((dst_ptr
[x
] << 3) & 0xf8) | ((dst_ptr
[x
] >> 2) & 0x07),
4755 src_ptr
[x
], blend
);
4756 dst_ptr
[x
] = ((val
>> 9) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 3) & 0x001f);
4761 static void blend_rect_16(const dib_info
*dst
, const RECT
*rc
,
4762 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4764 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4765 WORD
*dst_ptr
= get_pixel_ptr_16( dst
, rc
->left
, rc
->top
);
4768 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 2, src_ptr
+= src
->stride
/ 4)
4770 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4772 DWORD val
= blend_rgb( get_field( dst_ptr
[x
], dst
->red_shift
, dst
->red_len
),
4773 get_field( dst_ptr
[x
], dst
->green_shift
, dst
->green_len
),
4774 get_field( dst_ptr
[x
], dst
->blue_shift
, dst
->blue_len
),
4775 src_ptr
[x
], blend
);
4776 dst_ptr
[x
] = rgb_to_pixel_masks( dst
, val
>> 16, val
>> 8, val
);
4781 static void blend_rect_8(const dib_info
*dst
, const RECT
*rc
,
4782 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4784 const RGBQUAD
*color_table
= get_dib_color_table( dst
);
4785 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4786 BYTE
*dst_ptr
= get_pixel_ptr_8( dst
, rc
->left
, rc
->top
);
4789 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
4791 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4793 RGBQUAD rgb
= color_table
[dst_ptr
[x
]];
4794 DWORD val
= blend_rgb( rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
, src_ptr
[x
], blend
);
4795 dst_ptr
[x
] = rgb_lookup_colortable( dst
, val
>> 16, val
>> 8, val
);
4800 static void blend_rect_4(const dib_info
*dst
, const RECT
*rc
,
4801 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4803 const RGBQUAD
*color_table
= get_dib_color_table( dst
);
4804 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4805 BYTE
*dst_ptr
= get_pixel_ptr_4( dst
, rc
->left
, rc
->top
);
4808 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
4810 for (i
= 0, x
= (dst
->rect
.left
+ rc
->left
) & 1; i
< rc
->right
- rc
->left
; i
++, x
++)
4812 DWORD val
= ((x
& 1) ? dst_ptr
[x
/ 2] : (dst_ptr
[x
/ 2] >> 4)) & 0x0f;
4813 RGBQUAD rgb
= color_table
[val
];
4814 val
= blend_rgb( rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
, src_ptr
[i
], blend
);
4815 val
= rgb_lookup_colortable( dst
, val
>> 16, val
>> 8, val
);
4817 dst_ptr
[x
/ 2] = val
| (dst_ptr
[x
/ 2] & 0xf0);
4819 dst_ptr
[x
/ 2] = (val
<< 4) | (dst_ptr
[x
/ 2] & 0x0f);
4824 static void blend_rect_1(const dib_info
*dst
, const RECT
*rc
,
4825 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4827 const RGBQUAD
*color_table
= get_dib_color_table( dst
);
4828 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4829 BYTE
*dst_ptr
= get_pixel_ptr_1( dst
, rc
->left
, rc
->top
);
4832 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
4834 for (i
= 0, x
= (dst
->rect
.left
+ rc
->left
) & 7; i
< rc
->right
- rc
->left
; i
++, x
++)
4836 DWORD val
= (dst_ptr
[x
/ 8] & pixel_masks_1
[x
% 8]) ? 1 : 0;
4837 RGBQUAD rgb
= color_table
[val
];
4838 val
= blend_rgb( rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
, src_ptr
[i
], blend
);
4839 val
= rgb_to_pixel_colortable(dst
, val
>> 16, val
>> 8, val
) ? 0xff : 0;
4840 dst_ptr
[x
/ 8] = (dst_ptr
[x
/ 8] & ~pixel_masks_1
[x
% 8]) | (val
& pixel_masks_1
[x
% 8]);
4845 static void blend_rect_null(const dib_info
*dst
, const RECT
*rc
,
4846 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4850 static inline DWORD
gradient_rgb_8888( const TRIVERTEX
*v
, unsigned int pos
, unsigned int len
)
4853 r
= (v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 256;
4854 g
= (v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 256;
4855 b
= (v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 256;
4856 a
= (v
[0].Alpha
* (len
- pos
) + v
[1].Alpha
* pos
) / len
/ 256;
4857 return a
<< 24 | r
<< 16 | g
<< 8 | b
;
4860 static inline DWORD
gradient_rgb_24( const TRIVERTEX
*v
, unsigned int pos
, unsigned int len
)
4863 r
= (v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 256;
4864 g
= (v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 256;
4865 b
= (v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 256;
4866 return r
<< 16 | g
<< 8 | b
;
4869 static inline WORD
gradient_rgb_555( const TRIVERTEX
*v
, unsigned int pos
, unsigned int len
,
4870 unsigned int x
, unsigned int y
)
4872 int r
= (v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4873 int g
= (v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4874 int b
= (v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4875 r
= min( 31, max( 0, r
/ 16 ));
4876 g
= min( 31, max( 0, g
/ 16 ));
4877 b
= min( 31, max( 0, b
/ 16 ));
4878 return (r
<< 10) | (g
<< 5) | b
;
4881 static inline BYTE
gradient_rgb_8( const dib_info
*dib
, const TRIVERTEX
*v
,
4882 unsigned int pos
, unsigned int len
, unsigned int x
, unsigned int y
)
4884 BYTE r
= ((v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4885 BYTE g
= ((v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4886 BYTE b
= ((v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4887 return rgb_to_pixel_colortable( dib
, r
* 127, g
* 127, b
* 127 );
4890 /* compute the left/right triangle limit for row y */
4891 static inline void triangle_coords( const TRIVERTEX
*v
, const RECT
*rc
, int y
, int *left
, int *right
)
4895 if (y
< v
[1].y
) x1
= edge_coord( y
, v
[0].x
, v
[0].y
, v
[1].x
, v
[1].y
);
4896 else x1
= edge_coord( y
, v
[1].x
, v
[1].y
, v
[2].x
, v
[2].y
);
4898 x2
= edge_coord( y
, v
[0].x
, v
[0].y
, v
[2].x
, v
[2].y
);
4900 *left
= max( rc
->left
, min( x1
, x2
) );
4901 *right
= min( rc
->right
, max( x1
, x2
) );
4904 /* compute the matrix determinant for triangular barycentric coordinates (constant across the triangle) */
4905 static inline int triangle_det( const TRIVERTEX
*v
)
4907 return (v
[2].y
- v
[1].y
) * (v
[2].x
- v
[0].x
) - (v
[2].x
- v
[1].x
) * (v
[2].y
- v
[0].y
);
4910 /* compute the barycentric weights for a given point inside the triangle */
4911 static inline void triangle_weights( const TRIVERTEX
*v
, int x
, int y
, INT64
*l1
, INT64
*l2
)
4913 *l1
= (v
[1].y
- v
[2].y
) * (x
- v
[2].x
) - (v
[1].x
- v
[2].x
) * (y
- v
[2].y
);
4914 *l2
= (v
[2].y
- v
[0].y
) * (x
- v
[2].x
) - (v
[2].x
- v
[0].x
) * (y
- v
[2].y
);
4917 static inline DWORD
gradient_triangle_8888( const TRIVERTEX
*v
, int x
, int y
, int det
)
4922 triangle_weights( v
, x
, y
, &l1
, &l2
);
4923 r
= (v
[0].Red
* l1
+ v
[1].Red
* l2
+ v
[2].Red
* (det
- l1
- l2
)) / det
/ 256;
4924 g
= (v
[0].Green
* l1
+ v
[1].Green
* l2
+ v
[2].Green
* (det
- l1
- l2
)) / det
/ 256;
4925 b
= (v
[0].Blue
* l1
+ v
[1].Blue
* l2
+ v
[2].Blue
* (det
- l1
- l2
)) / det
/ 256;
4926 a
= (v
[0].Alpha
* l1
+ v
[1].Alpha
* l2
+ v
[2].Alpha
* (det
- l1
- l2
)) / det
/ 256;
4927 return a
<< 24 | r
<< 16 | g
<< 8 | b
;
4930 static inline DWORD
gradient_triangle_24( const TRIVERTEX
*v
, int x
, int y
, int det
)
4935 triangle_weights( v
, x
, y
, &l1
, &l2
);
4936 r
= (v
[0].Red
* l1
+ v
[1].Red
* l2
+ v
[2].Red
* (det
- l1
- l2
)) / det
/ 256;
4937 g
= (v
[0].Green
* l1
+ v
[1].Green
* l2
+ v
[2].Green
* (det
- l1
- l2
)) / det
/ 256;
4938 b
= (v
[0].Blue
* l1
+ v
[1].Blue
* l2
+ v
[2].Blue
* (det
- l1
- l2
)) / det
/ 256;
4939 return r
<< 16 | g
<< 8 | b
;
4942 static inline DWORD
gradient_triangle_555( const TRIVERTEX
*v
, int x
, int y
, int det
)
4947 triangle_weights( v
, x
, y
, &l1
, &l2
);
4948 r
= (v
[0].Red
* l1
+ v
[1].Red
* l2
+ v
[2].Red
* (det
- l1
- l2
)) / det
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4949 g
= (v
[0].Green
* l1
+ v
[1].Green
* l2
+ v
[2].Green
* (det
- l1
- l2
)) / det
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4950 b
= (v
[0].Blue
* l1
+ v
[1].Blue
* l2
+ v
[2].Blue
* (det
- l1
- l2
)) / det
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4951 r
= min( 31, max( 0, r
/ 16 ));
4952 g
= min( 31, max( 0, g
/ 16 ));
4953 b
= min( 31, max( 0, b
/ 16 ));
4954 return (r
<< 10) | (g
<< 5) | b
;
4957 static inline DWORD
gradient_triangle_8( const dib_info
*dib
, const TRIVERTEX
*v
, int x
, int y
, int det
)
4962 triangle_weights( v
, x
, y
, &l1
, &l2
);
4963 r
= ((v
[0].Red
* l1
+ v
[1].Red
* l2
+ v
[2].Red
* (det
- l1
- l2
)) / det
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4964 g
= ((v
[0].Green
* l1
+ v
[1].Green
* l2
+ v
[2].Green
* (det
- l1
- l2
)) / det
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4965 b
= ((v
[0].Blue
* l1
+ v
[1].Blue
* l2
+ v
[2].Blue
* (det
- l1
- l2
)) / det
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4966 return rgb_to_pixel_colortable( dib
, r
* 127, g
* 127, b
* 127 );
4969 static BOOL
gradient_rect_8888( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4971 DWORD
*ptr
= get_pixel_ptr_32( dib
, rc
->left
, rc
->top
);
4972 int x
, y
, left
, right
, det
;
4976 case GRADIENT_FILL_RECT_H
:
4977 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4978 ptr
[x
] = gradient_rgb_8888( v
, rc
->left
+ x
- v
[0].x
, v
[1].x
- v
[0].x
);
4980 for (y
= rc
->top
+ 1; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4981 memcpy( ptr
+ dib
->stride
/ 4, ptr
, (rc
->right
- rc
->left
) * 4 );
4984 case GRADIENT_FILL_RECT_V
:
4985 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4987 DWORD val
= gradient_rgb_8888( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
4988 memset_32( ptr
, val
, rc
->right
- rc
->left
);
4992 case GRADIENT_FILL_TRIANGLE
:
4993 if (!(det
= triangle_det( v
))) return FALSE
;
4994 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4996 triangle_coords( v
, rc
, y
, &left
, &right
);
4997 for (x
= left
; x
< right
; x
++) ptr
[x
- rc
->left
] = gradient_triangle_8888( v
, x
, y
, det
);
5004 static BOOL
gradient_rect_32( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5006 DWORD
*ptr
= get_pixel_ptr_32( dib
, rc
->left
, rc
->top
);
5007 int x
, y
, left
, right
, det
;
5011 case GRADIENT_FILL_RECT_H
:
5012 if (dib
->red_len
== 8 && dib
->green_len
== 8 && dib
->blue_len
== 8)
5014 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
5016 DWORD val
= gradient_rgb_24( v
, rc
->left
+ x
- v
[0].x
, v
[1].x
- v
[0].x
);
5017 ptr
[x
] = ((( val
& 0xff) << dib
->blue_shift
) |
5018 (((val
>> 8) & 0xff) << dib
->green_shift
) |
5019 (((val
>> 16) & 0xff) << dib
->red_shift
));
5024 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
5026 DWORD val
= gradient_rgb_24( v
, rc
->left
+ x
- v
[0].x
, v
[1].x
- v
[0].x
);
5027 ptr
[x
] = rgb_to_pixel_masks( dib
, val
>> 16, val
>> 8, val
);
5031 for (y
= rc
->top
+ 1; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
5032 memcpy( ptr
+ dib
->stride
/ 4, ptr
, (rc
->right
- rc
->left
) * 4 );
5035 case GRADIENT_FILL_RECT_V
:
5036 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
5038 DWORD val
= gradient_rgb_24( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
5039 if (dib
->red_len
== 8 && dib
->green_len
== 8 && dib
->blue_len
== 8)
5040 val
= ((( val
& 0xff) << dib
->blue_shift
) |
5041 (((val
>> 8) & 0xff) << dib
->green_shift
) |
5042 (((val
>> 16) & 0xff) << dib
->red_shift
));
5044 val
= rgb_to_pixel_masks( dib
, val
>> 16, val
>> 8, val
);
5046 memset_32( ptr
, val
, rc
->right
- rc
->left
);
5050 case GRADIENT_FILL_TRIANGLE
:
5051 if (!(det
= triangle_det( v
))) return FALSE
;
5052 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
5054 triangle_coords( v
, rc
, y
, &left
, &right
);
5056 if (dib
->red_len
== 8 && dib
->green_len
== 8 && dib
->blue_len
== 8)
5057 for (x
= left
; x
< right
; x
++)
5059 DWORD val
= gradient_triangle_24( v
, x
, y
, det
);
5060 ptr
[x
- rc
->left
] = ((( val
& 0xff) << dib
->blue_shift
) |
5061 (((val
>> 8) & 0xff) << dib
->green_shift
) |
5062 (((val
>> 16) & 0xff) << dib
->red_shift
));
5065 for (x
= left
; x
< right
; x
++)
5067 DWORD val
= gradient_triangle_24( v
, x
, y
, det
);
5068 ptr
[x
- rc
->left
] = rgb_to_pixel_masks( dib
, val
>> 16, val
>> 8, val
);
5076 static BOOL
gradient_rect_24( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5078 BYTE
*ptr
= get_pixel_ptr_24( dib
, rc
->left
, rc
->top
);
5079 int x
, y
, left
, right
, det
;
5083 case GRADIENT_FILL_RECT_H
:
5084 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
5086 DWORD val
= gradient_rgb_24( v
, rc
->left
+ x
- v
[0].x
, v
[1].x
- v
[0].x
);
5088 ptr
[x
* 3 + 1] = val
>> 8;
5089 ptr
[x
* 3 + 2] = val
>> 16;
5092 for (y
= rc
->top
+ 1; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5093 memcpy( ptr
+ dib
->stride
, ptr
, (rc
->right
- rc
->left
) * 3 );
5096 case GRADIENT_FILL_RECT_V
:
5097 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5099 DWORD val
= gradient_rgb_24( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
5100 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
5103 ptr
[x
* 3 + 1] = val
>> 8;
5104 ptr
[x
* 3 + 2] = val
>> 16;
5109 case GRADIENT_FILL_TRIANGLE
:
5110 if (!(det
= triangle_det( v
))) return FALSE
;
5111 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5113 triangle_coords( v
, rc
, y
, &left
, &right
);
5114 for (x
= left
; x
< right
; x
++)
5116 DWORD val
= gradient_triangle_24( v
, x
, y
, det
);
5117 ptr
[(x
- rc
->left
) * 3] = val
;
5118 ptr
[(x
- rc
->left
) * 3 + 1] = val
>> 8;
5119 ptr
[(x
- rc
->left
) * 3 + 2] = val
>> 16;
5127 static BOOL
gradient_rect_555( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5129 WORD
*ptr
= get_pixel_ptr_16( dib
, rc
->left
, rc
->top
);
5130 int x
, y
, left
, right
, det
;
5134 case GRADIENT_FILL_RECT_H
:
5135 for (y
= rc
->top
; y
< min( rc
->top
+ 4, rc
->bottom
); y
++, ptr
+= dib
->stride
/ 2)
5136 for (x
= rc
->left
; x
< rc
->right
; x
++)
5137 ptr
[x
- rc
->left
] = gradient_rgb_555( v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
);
5138 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
5139 memcpy( ptr
, ptr
- dib
->stride
* 2, (rc
->right
- rc
->left
) * 2 );
5142 case GRADIENT_FILL_RECT_V
:
5143 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
5146 for (x
= 0; x
< 4; x
++) values
[x
] = gradient_rgb_555( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
);
5147 for (x
= rc
->left
; x
< rc
->right
; x
++) ptr
[x
- rc
->left
] = values
[x
% 4];
5151 case GRADIENT_FILL_TRIANGLE
:
5152 if (!(det
= triangle_det( v
))) return FALSE
;
5153 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
5155 triangle_coords( v
, rc
, y
, &left
, &right
);
5156 for (x
= left
; x
< right
; x
++) ptr
[x
- rc
->left
] = gradient_triangle_555( v
, x
, y
, det
);
5163 static BOOL
gradient_rect_16( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5165 WORD
*ptr
= get_pixel_ptr_16( dib
, rc
->left
, rc
->top
);
5166 int x
, y
, left
, right
, det
;
5170 case GRADIENT_FILL_RECT_H
:
5171 for (y
= rc
->top
; y
< min( rc
->top
+ 4, rc
->bottom
); y
++, ptr
+= dib
->stride
/ 2)
5172 for (x
= rc
->left
; x
< rc
->right
; x
++)
5174 WORD val
= gradient_rgb_555( v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
);
5175 ptr
[x
- rc
->left
] = rgb_to_pixel_masks( dib
,
5176 ((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07),
5177 ((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07),
5178 ((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07) );
5180 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
5181 memcpy( ptr
, ptr
- dib
->stride
* 2, (rc
->right
- rc
->left
) * 2 );
5184 case GRADIENT_FILL_RECT_V
:
5185 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
5188 for (x
= 0; x
< 4; x
++)
5190 WORD val
= gradient_rgb_555( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
);
5191 values
[x
] = rgb_to_pixel_masks( dib
,
5192 ((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07),
5193 ((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07),
5194 ((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07) );
5196 for (x
= rc
->left
; x
< rc
->right
; x
++) ptr
[x
- rc
->left
] = values
[x
% 4];
5200 case GRADIENT_FILL_TRIANGLE
:
5201 if (!(det
= triangle_det( v
))) return FALSE
;
5202 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
5204 triangle_coords( v
, rc
, y
, &left
, &right
);
5205 for (x
= left
; x
< right
; x
++)
5207 WORD val
= gradient_triangle_555( v
, x
, y
, det
);
5208 ptr
[x
- rc
->left
] = rgb_to_pixel_masks( dib
,
5209 ((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07),
5210 ((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07),
5211 ((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07) );
5219 static BOOL
gradient_rect_8( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5221 BYTE
*ptr
= get_pixel_ptr_8( dib
, rc
->left
, rc
->top
);
5222 int x
, y
, left
, right
, det
;
5226 case GRADIENT_FILL_RECT_H
:
5227 for (y
= rc
->top
; y
< min( rc
->top
+ 16, rc
->bottom
); y
++, ptr
+= dib
->stride
)
5228 for (x
= rc
->left
; x
< rc
->right
; x
++)
5229 ptr
[x
- rc
->left
] = gradient_rgb_8( dib
, v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
);
5230 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5231 memcpy( ptr
, ptr
- dib
->stride
* 16, rc
->right
- rc
->left
);
5234 case GRADIENT_FILL_RECT_V
:
5235 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5238 for (x
= 0; x
< 16; x
++)
5239 values
[x
] = gradient_rgb_8( dib
, v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
);
5240 for (x
= rc
->left
; x
< rc
->right
; x
++) ptr
[x
- rc
->left
] = values
[x
% 16];
5244 case GRADIENT_FILL_TRIANGLE
:
5245 if (!(det
= triangle_det( v
))) return FALSE
;
5246 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5248 triangle_coords( v
, rc
, y
, &left
, &right
);
5249 for (x
= left
; x
< right
; x
++) ptr
[x
- rc
->left
] = gradient_triangle_8( dib
, v
, x
, y
, det
);
5256 static BOOL
gradient_rect_4( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5258 BYTE
*ptr
= get_pixel_ptr_4( dib
, rc
->left
, rc
->top
);
5259 int x
, y
, left
, right
, det
, pos
;
5263 case GRADIENT_FILL_RECT_H
:
5264 for (y
= rc
->top
; y
< min( rc
->top
+ 16, rc
->bottom
); y
++, ptr
+= dib
->stride
)
5266 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 1; x
< rc
->right
; x
++, pos
++)
5268 BYTE val
= gradient_rgb_8( dib
, v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
);
5270 ptr
[pos
/ 2] = val
| (ptr
[pos
/ 2] & 0xf0);
5272 ptr
[pos
/ 2] = (val
<< 4) | (ptr
[pos
/ 2] & 0x0f);
5275 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5278 pos
= (dib
->rect
.left
+ rc
->left
) & 1;
5281 ptr
[0] = (ptr
[-16 * dib
->stride
] & 0x0f) | (ptr
[0] & 0xf0);
5285 for (; x
< rc
->right
- 1; x
+= 2, pos
+= 2) ptr
[pos
/ 2] = ptr
[pos
/ 2 - 16 * dib
->stride
];
5287 ptr
[pos
/ 2] = (ptr
[pos
/ 2] & 0x0f) | (ptr
[pos
/ 2 - 16 * dib
->stride
] & 0xf0);
5291 case GRADIENT_FILL_RECT_V
:
5292 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5295 for (x
= 0; x
< 16; x
++)
5296 values
[x
] = gradient_rgb_8( dib
, v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
);
5297 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 1; x
< rc
->right
; x
++, pos
++)
5299 ptr
[pos
/ 2] = values
[x
% 16] | (ptr
[pos
/ 2] & 0xf0);
5301 ptr
[pos
/ 2] = (values
[x
% 16] << 4) | (ptr
[pos
/ 2] & 0x0f);
5305 case GRADIENT_FILL_TRIANGLE
:
5306 if (!(det
= triangle_det( v
))) return FALSE
;
5307 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5309 triangle_coords( v
, rc
, y
, &left
, &right
);
5310 for (x
= left
, pos
= left
- rc
->left
+ ((dib
->rect
.left
+ rc
->left
) & 1); x
< right
; x
++, pos
++)
5312 BYTE val
= gradient_triangle_8( dib
, v
, x
, y
, det
);
5314 ptr
[pos
/ 2] = val
| (ptr
[pos
/ 2] & 0xf0);
5316 ptr
[pos
/ 2] = (val
<< 4) | (ptr
[pos
/ 2] & 0x0f);
5324 static BOOL
gradient_rect_1( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5326 BYTE
*ptr
= get_pixel_ptr_1( dib
, rc
->left
, rc
->top
);
5327 int x
, y
, left
, right
, det
, pos
;
5331 case GRADIENT_FILL_RECT_H
:
5332 for (y
= rc
->top
; y
< min( rc
->top
+ 16, rc
->bottom
); y
++, ptr
+= dib
->stride
)
5334 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 7; x
< rc
->right
; x
++, pos
++)
5336 BYTE val
= gradient_rgb_8( dib
, v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
) ? 0xff : 0;
5337 ptr
[pos
/ 8] = (ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) | (val
& pixel_masks_1
[pos
% 8]);
5340 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5341 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 7; x
< rc
->right
; x
++, pos
++)
5342 ptr
[pos
/ 8] = (ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) |
5343 (ptr
[pos
/ 8 - 16 * dib
->stride
] & pixel_masks_1
[pos
% 8]);
5346 case GRADIENT_FILL_RECT_V
:
5347 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5350 for (x
= 0; x
< 16; x
++)
5351 values
[x
] = gradient_rgb_8( dib
, v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
) ? 0xff : 0;
5352 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 7; x
< rc
->right
; x
++, pos
++)
5353 ptr
[pos
/ 8] = (ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) |
5354 (values
[x
% 16] & pixel_masks_1
[pos
% 8]);
5358 case GRADIENT_FILL_TRIANGLE
:
5359 if (!(det
= triangle_det( v
))) return FALSE
;
5360 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5362 triangle_coords( v
, rc
, y
, &left
, &right
);
5363 for (x
= left
, pos
= left
- rc
->left
+ ((dib
->rect
.left
+ rc
->left
) & 7); x
< right
; x
++, pos
++)
5365 BYTE val
= gradient_triangle_8( dib
, v
, x
, y
, det
) ? 0xff : 0;
5366 ptr
[pos
/ 8] = (ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) | (val
& pixel_masks_1
[pos
% 8]);
5374 static BOOL
gradient_rect_null( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5379 static void mask_rect_32( const dib_info
*dst
, const RECT
*rc
,
5380 const dib_info
*src
, const POINT
*origin
, int rop2
)
5382 DWORD
*dst_start
= get_pixel_ptr_32(dst
, rc
->left
, rc
->top
), dst_colors
[256];
5383 DWORD src_val
, bit_val
, i
, full
, pos
;
5384 int x
, y
, origin_end
= origin
->x
+ rc
->right
- rc
->left
;
5385 const RGBQUAD
*color_table
= get_dib_color_table( src
);
5386 BYTE
*src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
);
5388 if (dst
->funcs
== &funcs_8888
)
5389 for (i
= 0; i
< 2; i
++)
5390 dst_colors
[i
] = color_table
[i
].rgbRed
<< 16 | color_table
[i
].rgbGreen
<< 8 |
5391 color_table
[i
].rgbBlue
;
5393 for (i
= 0; i
< 2; i
++)
5394 dst_colors
[i
] = rgbquad_to_pixel_masks(dst
, color_table
[i
]);
5396 /* Creating a BYTE-sized table so we don't need to mask the lsb of bit_val */
5397 for (i
= 2; i
< ARRAY_SIZE(dst_colors
); i
++)
5398 dst_colors
[i
] = dst_colors
[i
& 1];
5400 /* Special case starting and finishing in same byte, neither on byte boundary */
5401 if ((origin
->x
& 7) && (origin_end
& 7) && (origin
->x
& ~7) == (origin_end
& ~7))
5403 struct rop_codes codes
;
5405 get_rop_codes( rop2
, &codes
);
5407 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
5409 pos
= origin
->x
& 7;
5410 for (x
= 0; x
< rc
->right
- rc
->left
; x
++, pos
++)
5412 bit_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
5413 do_rop_codes_32( dst_start
+ x
, dst_colors
[bit_val
], &codes
);
5415 dst_start
+= dst
->stride
/ 4;
5416 src_start
+= src
->stride
;
5421 full
= ((rc
->right
- rc
->left
) - ((8 - (origin
->x
& 7)) & 7)) / 8;
5423 #define LOOP( op ) \
5424 for (y = rc->top; y < rc->bottom; y++) \
5426 pos = origin->x & 7; \
5427 src_val = src_start[pos / 8]; \
5431 case 1: bit_val = src_val >> 6; op; x++; \
5432 /* fall through */ \
5433 case 2: bit_val = src_val >> 5; op; x++; \
5434 /* fall through */ \
5435 case 3: bit_val = src_val >> 4; op; x++; \
5436 /* fall through */ \
5437 case 4: bit_val = src_val >> 3; op; x++; \
5438 /* fall through */ \
5439 case 5: bit_val = src_val >> 2; op; x++; \
5440 /* fall through */ \
5441 case 6: bit_val = src_val >> 1; op; x++; \
5442 /* fall through */ \
5443 case 7: bit_val = src_val; op; x++; \
5444 pos = (pos + 7) & ~7; \
5446 for (i = 0; i < full; i++, pos += 8) \
5448 src_val = src_start[pos / 8]; \
5449 bit_val = src_val >> 7; op; x++; \
5450 bit_val = src_val >> 6; op; x++; \
5451 bit_val = src_val >> 5; op; x++; \
5452 bit_val = src_val >> 4; op; x++; \
5453 bit_val = src_val >> 3; op; x++; \
5454 bit_val = src_val >> 2; op; x++; \
5455 bit_val = src_val >> 1; op; x++; \
5456 bit_val = src_val; op; x++; \
5458 if (origin_end & 7) \
5460 src_val = src_start[pos / 8]; \
5461 x += (origin_end & 7) - 1; \
5462 switch (origin_end & 7) \
5464 case 7: bit_val = src_val >> 1; op; x--; \
5465 /* fall through */ \
5466 case 6: bit_val = src_val >> 2; op; x--; \
5467 /* fall through */ \
5468 case 5: bit_val = src_val >> 3; op; x--; \
5469 /* fall through */ \
5470 case 4: bit_val = src_val >> 4; op; x--; \
5471 /* fall through */ \
5472 case 3: bit_val = src_val >> 5; op; x--; \
5473 /* fall through */ \
5474 case 2: bit_val = src_val >> 6; op; x--; \
5475 /* fall through */ \
5476 case 1: bit_val = src_val >> 7; op; \
5479 dst_start += dst->stride / 4; \
5480 src_start += src->stride; \
5485 ROPS_ALL( dst_start
[x
], dst_colors
[bit_val
] )
5490 static void mask_rect_24( const dib_info
*dst
, const RECT
*rc
,
5491 const dib_info
*src
, const POINT
*origin
, int rop2
)
5493 BYTE
*dst_start
= get_pixel_ptr_24(dst
, rc
->left
, rc
->top
);
5494 DWORD src_val
, bit_val
, i
, full
, pos
;
5495 struct rop_codes codes
;
5496 int x
, y
, origin_end
= origin
->x
+ rc
->right
- rc
->left
;
5497 const RGBQUAD
*color_table
= get_dib_color_table( src
);
5498 BYTE
*src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
);
5501 get_rop_codes( rop2
, &codes
);
5503 /* Special case starting and finishing in same byte, neither on byte boundary */
5504 if ((origin
->x
& 7) && (origin_end
& 7) && (origin
->x
& ~7) == (origin_end
& ~7))
5506 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
5508 pos
= origin
->x
& 7;
5509 for (x
= 0; x
< rc
->right
- rc
->left
; x
++, pos
++)
5511 bit_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
5512 rgb
= color_table
[bit_val
];
5513 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5514 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5515 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5517 dst_start
+= dst
->stride
;
5518 src_start
+= src
->stride
;
5523 full
= ((rc
->right
- rc
->left
) - ((8 - (origin
->x
& 7)) & 7)) / 8;
5525 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
5527 pos
= origin
->x
& 7;
5528 src_val
= src_start
[pos
/ 8];
5534 bit_val
= (src_val
>> 6) & 1;
5535 rgb
= color_table
[bit_val
];
5536 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5537 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5538 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5542 bit_val
= (src_val
>> 5) & 1;
5543 rgb
= color_table
[bit_val
];
5544 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5545 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5546 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5550 bit_val
= (src_val
>> 4) & 1;
5551 rgb
= color_table
[bit_val
];
5552 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5553 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5554 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5558 bit_val
= (src_val
>> 3) & 1;
5559 rgb
= color_table
[bit_val
];
5560 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5561 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5562 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5566 bit_val
= (src_val
>> 2) & 1;
5567 rgb
= color_table
[bit_val
];
5568 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5569 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5570 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5574 bit_val
= (src_val
>> 1) & 1;
5575 rgb
= color_table
[bit_val
];
5576 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5577 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5578 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5582 bit_val
= src_val
& 1;
5583 rgb
= color_table
[bit_val
];
5584 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5585 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5586 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5588 pos
= (pos
+ 7) & ~7;
5591 for (i
= 0; i
< full
; i
++, pos
+= 8)
5593 src_val
= src_start
[pos
/ 8];
5595 bit_val
= (src_val
>> 7) & 1;
5596 rgb
= color_table
[bit_val
];
5597 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5598 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5599 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5602 bit_val
= (src_val
>> 6) & 1;
5603 rgb
= color_table
[bit_val
];
5604 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5605 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5606 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5609 bit_val
= (src_val
>> 5) & 1;
5610 rgb
= color_table
[bit_val
];
5611 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5612 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5613 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5616 bit_val
= (src_val
>> 4) & 1;
5617 rgb
= color_table
[bit_val
];
5618 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5619 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5620 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5623 bit_val
= (src_val
>> 3) & 1;
5624 rgb
= color_table
[bit_val
];
5625 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5626 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5627 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5630 bit_val
= (src_val
>> 2) & 1;
5631 rgb
= color_table
[bit_val
];
5632 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5633 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5634 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5637 bit_val
= (src_val
>> 1) & 1;
5638 rgb
= color_table
[bit_val
];
5639 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5640 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5641 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5644 bit_val
= src_val
& 1;
5645 rgb
= color_table
[bit_val
];
5646 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5647 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5648 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5654 src_val
= src_start
[pos
/ 8];
5655 x
+= (origin_end
& 7) - 1;
5657 switch (origin_end
& 7)
5660 bit_val
= (src_val
>> 1) & 1;
5661 rgb
= color_table
[bit_val
];
5662 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5663 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5664 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5668 bit_val
= (src_val
>> 2) & 1;
5669 rgb
= color_table
[bit_val
];
5670 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5671 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5672 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5676 bit_val
= (src_val
>> 3) & 1;
5677 rgb
= color_table
[bit_val
];
5678 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5679 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5680 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5684 bit_val
= (src_val
>> 4) & 1;
5685 rgb
= color_table
[bit_val
];
5686 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5687 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5688 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5692 bit_val
= (src_val
>> 5) & 1;
5693 rgb
= color_table
[bit_val
];
5694 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5695 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5696 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5700 bit_val
= (src_val
>> 6) & 1;
5701 rgb
= color_table
[bit_val
];
5702 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5703 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5704 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5708 bit_val
= (src_val
>> 7) & 1;
5709 rgb
= color_table
[bit_val
];
5710 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5711 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5712 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5716 dst_start
+= dst
->stride
;
5717 src_start
+= src
->stride
;
5721 static void mask_rect_16( const dib_info
*dst
, const RECT
*rc
,
5722 const dib_info
*src
, const POINT
*origin
, int rop2
)
5724 WORD
*dst_start
= get_pixel_ptr_16(dst
, rc
->left
, rc
->top
), dst_colors
[2];
5725 DWORD src_val
, bit_val
, i
, full
, pos
;
5726 struct rop_codes codes
;
5727 int x
, y
, origin_end
= origin
->x
+ rc
->right
- rc
->left
;
5728 const RGBQUAD
*color_table
= get_dib_color_table( src
);
5729 BYTE
*src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
);
5731 get_rop_codes( rop2
, &codes
);
5733 if (dst
->funcs
== &funcs_555
)
5734 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
5735 dst_colors
[i
] = ((color_table
[i
].rgbRed
<< 7) & 0x7c00) |
5736 ((color_table
[i
].rgbGreen
<< 2) & 0x03e0) |
5737 ((color_table
[i
].rgbBlue
>> 3) & 0x001f);
5739 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
5740 dst_colors
[i
] = rgbquad_to_pixel_masks(dst
, color_table
[i
]);
5742 /* Special case starting and finishing in same byte, neither on byte boundary */
5743 if ((origin
->x
& 7) && (origin_end
& 7) && (origin
->x
& ~7) == (origin_end
& ~7))
5745 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
5747 pos
= origin
->x
& 7;
5748 for (x
= 0; x
< rc
->right
- rc
->left
; x
++, pos
++)
5750 bit_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
5751 do_rop_codes_16( dst_start
+ x
, dst_colors
[bit_val
], &codes
);
5753 dst_start
+= dst
->stride
/ 2;
5754 src_start
+= src
->stride
;
5759 full
= ((rc
->right
- rc
->left
) - ((8 - (origin
->x
& 7)) & 7)) / 8;
5761 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
5763 pos
= origin
->x
& 7;
5764 src_val
= src_start
[pos
/ 8];
5770 bit_val
= (src_val
>> 6) & 1;
5771 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5774 bit_val
= (src_val
>> 5) & 1;
5775 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5778 bit_val
= (src_val
>> 4) & 1;
5779 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5782 bit_val
= (src_val
>> 3) & 1;
5783 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5786 bit_val
= (src_val
>> 2) & 1;
5787 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5790 bit_val
= (src_val
>> 1) & 1;
5791 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5794 bit_val
= src_val
& 1;
5795 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5796 pos
= (pos
+ 7) & ~7;
5799 for (i
= 0; i
< full
; i
++, pos
+= 8)
5801 src_val
= src_start
[pos
/ 8];
5803 bit_val
= (src_val
>> 7) & 1;
5804 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5805 bit_val
= (src_val
>> 6) & 1;
5806 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5807 bit_val
= (src_val
>> 5) & 1;
5808 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5809 bit_val
= (src_val
>> 4) & 1;
5810 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5811 bit_val
= (src_val
>> 3) & 1;
5812 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5813 bit_val
= (src_val
>> 2) & 1;
5814 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5815 bit_val
= (src_val
>> 1) & 1;
5816 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5817 bit_val
= src_val
& 1;
5818 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5823 src_val
= src_start
[pos
/ 8];
5824 x
+= (origin_end
& 7) - 1;
5826 switch (origin_end
& 7)
5829 bit_val
= (src_val
>> 1) & 1;
5830 do_rop_codes_16( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5833 bit_val
= (src_val
>> 2) & 1;
5834 do_rop_codes_16( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5837 bit_val
= (src_val
>> 3) & 1;
5838 do_rop_codes_16( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5841 bit_val
= (src_val
>> 4) & 1;
5842 do_rop_codes_16( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5845 bit_val
= (src_val
>> 5) & 1;
5846 do_rop_codes_16( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5849 bit_val
= (src_val
>> 6) & 1;
5850 do_rop_codes_16( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5853 bit_val
= (src_val
>> 7) & 1;
5854 do_rop_codes_16( dst_start
+ x
, dst_colors
[bit_val
], &codes
);
5858 dst_start
+= dst
->stride
/ 2;
5859 src_start
+= src
->stride
;
5863 static void mask_rect_8( const dib_info
*dst
, const RECT
*rc
,
5864 const dib_info
*src
, const POINT
*origin
, int rop2
)
5866 BYTE
*dst_start
= get_pixel_ptr_8(dst
, rc
->left
, rc
->top
), dst_colors
[2];
5867 DWORD src_val
, bit_val
, i
, full
, pos
;
5868 struct rop_codes codes
;
5869 int x
, y
, origin_end
= origin
->x
+ rc
->right
- rc
->left
;
5870 const RGBQUAD
*color_table
= get_dib_color_table( src
);
5871 BYTE
*src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
);
5873 get_rop_codes( rop2
, &codes
);
5875 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
5876 dst_colors
[i
] = FILTER_DIBINDEX(color_table
[i
], rgbquad_to_pixel_colortable(dst
, color_table
[i
]));
5878 /* Special case starting and finishing in same byte, neither on byte boundary */
5879 if ((origin
->x
& 7) && (origin_end
& 7) && (origin
->x
& ~7) == (origin_end
& ~7))
5881 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
5883 pos
= origin
->x
& 7;
5884 for (x
= 0; x
< rc
->right
- rc
->left
; x
++, pos
++)
5886 bit_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
5887 do_rop_codes_8( dst_start
+ x
, dst_colors
[bit_val
], &codes
);
5889 dst_start
+= dst
->stride
;
5890 src_start
+= src
->stride
;
5895 full
= ((rc
->right
- rc
->left
) - ((8 - (origin
->x
& 7)) & 7)) / 8;
5897 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
5899 pos
= origin
->x
& 7;
5900 src_val
= src_start
[pos
/ 8];
5906 bit_val
= (src_val
>> 6) & 1;
5907 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5910 bit_val
= (src_val
>> 5) & 1;
5911 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5914 bit_val
= (src_val
>> 4) & 1;
5915 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5918 bit_val
= (src_val
>> 3) & 1;
5919 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5922 bit_val
= (src_val
>> 2) & 1;
5923 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5926 bit_val
= (src_val
>> 1) & 1;
5927 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5930 bit_val
= src_val
& 1;
5931 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5932 pos
= (pos
+ 7) & ~7;
5935 for (i
= 0; i
< full
; i
++, pos
+= 8)
5937 src_val
= src_start
[pos
/ 8];
5939 bit_val
= (src_val
>> 7) & 1;
5940 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5941 bit_val
= (src_val
>> 6) & 1;
5942 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5943 bit_val
= (src_val
>> 5) & 1;
5944 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5945 bit_val
= (src_val
>> 4) & 1;
5946 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5947 bit_val
= (src_val
>> 3) & 1;
5948 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5949 bit_val
= (src_val
>> 2) & 1;
5950 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5951 bit_val
= (src_val
>> 1) & 1;
5952 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5953 bit_val
= src_val
& 1;
5954 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5959 src_val
= src_start
[pos
/ 8];
5960 x
+= (origin_end
& 7) - 1;
5962 switch (origin_end
& 7)
5965 bit_val
= (src_val
>> 1) & 1;
5966 do_rop_codes_8( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5969 bit_val
= (src_val
>> 2) & 1;
5970 do_rop_codes_8( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5973 bit_val
= (src_val
>> 3) & 1;
5974 do_rop_codes_8( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5977 bit_val
= (src_val
>> 4) & 1;
5978 do_rop_codes_8( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5981 bit_val
= (src_val
>> 5) & 1;
5982 do_rop_codes_8( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5985 bit_val
= (src_val
>> 6) & 1;
5986 do_rop_codes_8( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5989 bit_val
= (src_val
>> 7) & 1;
5990 do_rop_codes_8( dst_start
+ x
, dst_colors
[bit_val
], &codes
);
5994 dst_start
+= dst
->stride
;
5995 src_start
+= src
->stride
;
5999 static void mask_rect_4( const dib_info
*dst
, const RECT
*rc
,
6000 const dib_info
*src
, const POINT
*origin
, int rop2
)
6002 BYTE
*dst_start
= get_pixel_ptr_4(dst
, rc
->left
, rc
->top
), dst_colors
[2], *dst_ptr
;
6003 DWORD bit_val
, i
, pos
;
6004 struct rop_codes codes
;
6006 int left
= dst
->rect
.left
+ rc
->left
;
6007 int right
= dst
->rect
.left
+ rc
->right
;
6008 const RGBQUAD
*color_table
= get_dib_color_table( src
);
6009 BYTE
*src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
);
6011 get_rop_codes( rop2
, &codes
);
6013 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
6015 dst_colors
[i
] = FILTER_DIBINDEX(color_table
[i
],rgbquad_to_pixel_colortable(dst
, color_table
[i
]));
6016 /* Set high nibble to match so we don't need to shift it later. */
6017 dst_colors
[i
] |= dst_colors
[i
] << 4;
6020 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
6022 pos
= origin
->x
& 7;
6024 for (x
= left
, dst_ptr
= dst_start
; x
< right
; x
++, pos
++)
6026 bit_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
6028 do_rop_codes_mask_8( dst_ptr
++, dst_colors
[bit_val
], &codes
, 0x0f );
6030 do_rop_codes_mask_8( dst_ptr
, dst_colors
[bit_val
], &codes
, 0xf0 );
6032 dst_start
+= dst
->stride
;
6033 src_start
+= src
->stride
;
6037 static void mask_rect_null( const dib_info
*dst
, const RECT
*rc
,
6038 const dib_info
*src
, const POINT
*origin
, int rop2
)
6042 static inline BYTE
aa_color( BYTE dst
, BYTE text
, BYTE min_comp
, BYTE max_comp
)
6044 if (dst
== text
) return dst
;
6048 DWORD diff
= dst
- text
;
6049 DWORD range
= max_comp
- text
;
6050 dst
= text
+ (diff
* range
) / (0xff - text
);
6055 DWORD diff
= text
- dst
;
6056 DWORD range
= text
- min_comp
;
6057 dst
= text
- (diff
* range
) / text
;
6062 static inline DWORD
aa_rgb( BYTE r_dst
, BYTE g_dst
, BYTE b_dst
, DWORD text
, const struct intensity_range
*range
)
6064 return (aa_color( b_dst
, text
, range
->b_min
, range
->b_max
) |
6065 aa_color( g_dst
, text
>> 8, range
->g_min
, range
->g_max
) << 8 |
6066 aa_color( r_dst
, text
>> 16, range
->r_min
, range
->r_max
) << 16);
6069 static void draw_glyph_8888( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6070 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6072 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
6073 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6076 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6078 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6080 if (glyph_ptr
[x
] <= 1) continue;
6081 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
6082 dst_ptr
[x
] = aa_rgb( dst_ptr
[x
] >> 16, dst_ptr
[x
] >> 8, dst_ptr
[x
], text_pixel
, ranges
+ glyph_ptr
[x
] );
6084 dst_ptr
+= dib
->stride
/ 4;
6085 glyph_ptr
+= glyph
->stride
;
6089 static void draw_glyph_32( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6090 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6092 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
6093 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6097 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
6098 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
6099 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
6101 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6103 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6105 if (glyph_ptr
[x
] <= 1) continue;
6106 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
6107 val
= aa_rgb( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
6108 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
6109 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
6110 text
, ranges
+ glyph_ptr
[x
] );
6111 dst_ptr
[x
] = rgb_to_pixel_masks( dib
, val
>> 16, val
>> 8, val
);
6113 dst_ptr
+= dib
->stride
/ 4;
6114 glyph_ptr
+= glyph
->stride
;
6118 static void draw_glyph_24( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6119 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6121 BYTE
*dst_ptr
= get_pixel_ptr_24( dib
, rect
->left
, rect
->top
);
6122 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6126 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6128 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6130 if (glyph_ptr
[x
] <= 1) continue;
6131 if (glyph_ptr
[x
] >= 16)
6134 val
= aa_rgb( dst_ptr
[x
* 3 + 2], dst_ptr
[x
* 3 + 1], dst_ptr
[x
* 3],
6135 text_pixel
, ranges
+ glyph_ptr
[x
] );
6136 dst_ptr
[x
* 3] = val
;
6137 dst_ptr
[x
* 3 + 1] = val
>> 8;
6138 dst_ptr
[x
* 3 + 2] = val
>> 16;
6140 dst_ptr
+= dib
->stride
;
6141 glyph_ptr
+= glyph
->stride
;
6145 static void draw_glyph_555( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6146 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6148 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
6149 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6153 text
= ((text_pixel
<< 9) & 0xf80000) | ((text_pixel
<< 4) & 0x070000) |
6154 ((text_pixel
<< 6) & 0x00f800) | ((text_pixel
<< 1) & 0x000700) |
6155 ((text_pixel
<< 3) & 0x0000f8) | ((text_pixel
>> 2) & 0x000007);
6157 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6159 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6161 if (glyph_ptr
[x
] <= 1) continue;
6162 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
6163 val
= aa_rgb( ((dst_ptr
[x
] >> 7) & 0xf8) | ((dst_ptr
[x
] >> 12) & 0x07),
6164 ((dst_ptr
[x
] >> 2) & 0xf8) | ((dst_ptr
[x
] >> 7) & 0x07),
6165 ((dst_ptr
[x
] << 3) & 0xf8) | ((dst_ptr
[x
] >> 2) & 0x07),
6166 text
, ranges
+ glyph_ptr
[x
] );
6167 dst_ptr
[x
] = ((val
>> 9) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 3) & 0x001f);
6169 dst_ptr
+= dib
->stride
/ 2;
6170 glyph_ptr
+= glyph
->stride
;
6174 static void draw_glyph_16( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6175 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6177 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
6178 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6182 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
6183 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
6184 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
6186 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6188 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6190 if (glyph_ptr
[x
] <= 1) continue;
6191 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
6192 val
= aa_rgb( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
6193 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
6194 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
6195 text
, ranges
+ glyph_ptr
[x
] );
6196 dst_ptr
[x
] = rgb_to_pixel_masks( dib
, val
>> 16, val
>> 8, val
);
6198 dst_ptr
+= dib
->stride
/ 2;
6199 glyph_ptr
+= glyph
->stride
;
6203 static void draw_glyph_8( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6204 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6206 BYTE
*dst_ptr
= get_pixel_ptr_8( dib
, rect
->left
, rect
->top
);
6207 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6210 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6212 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6214 /* no antialiasing, glyph should only contain 0 or 16. */
6215 if (glyph_ptr
[x
] >= 16)
6216 dst_ptr
[x
] = text_pixel
;
6218 dst_ptr
+= dib
->stride
;
6219 glyph_ptr
+= glyph
->stride
;
6223 static void draw_glyph_4( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6224 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6226 BYTE
*dst_ptr
= get_pixel_ptr_4( dib
, rect
->left
, rect
->top
);
6227 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6230 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6232 for (x
= 0, pos
= (dib
->rect
.left
+ rect
->left
) & 1; x
< rect
->right
- rect
->left
; x
++, pos
++)
6234 /* no antialiasing, glyph should only contain 0 or 16. */
6235 if (glyph_ptr
[x
] >= 16)
6238 dst_ptr
[pos
/ 2] = text_pixel
| (dst_ptr
[pos
/ 2] & 0xf0);
6240 dst_ptr
[pos
/ 2] = (text_pixel
<< 4) | (dst_ptr
[pos
/ 2] & 0x0f);
6243 dst_ptr
+= dib
->stride
;
6244 glyph_ptr
+= glyph
->stride
;
6248 static void draw_glyph_1( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6249 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6251 BYTE
*dst_ptr
= get_pixel_ptr_1( dib
, rect
->left
, rect
->top
);
6252 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6254 BYTE text
= (text_pixel
& 1) ? 0xff : 0;
6256 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6258 for (x
= 0, pos
= (dib
->rect
.left
+ rect
->left
) & 7; x
< rect
->right
- rect
->left
; x
++, pos
++)
6260 /* no antialiasing, glyph should only contain 0 or 16. */
6261 if (glyph_ptr
[x
] >= 16)
6262 dst_ptr
[pos
/ 8] = (dst_ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) |
6263 (text
& pixel_masks_1
[pos
% 8]);
6265 dst_ptr
+= dib
->stride
;
6266 glyph_ptr
+= glyph
->stride
;
6270 static void draw_glyph_null( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6271 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6275 static inline BYTE
blend_color_gamma( BYTE dst
, BYTE text
, BYTE alpha
,
6276 const struct font_gamma_ramp
*gamma_ramp
)
6278 if (alpha
== 0) return dst
;
6279 if (alpha
== 255) return text
;
6280 if (dst
== text
) return dst
;
6282 return gamma_ramp
->encode
[ blend_color( gamma_ramp
->decode
[dst
],
6283 gamma_ramp
->decode
[text
],
6287 static inline DWORD
blend_subpixel( BYTE r
, BYTE g
, BYTE b
, DWORD text
, DWORD alpha
,
6288 const struct font_gamma_ramp
*gamma_ramp
)
6290 if (gamma_ramp
!= NULL
&& gamma_ramp
->gamma
!= 1000)
6292 return blend_color_gamma( r
, text
>> 16, (BYTE
)(alpha
>> 16), gamma_ramp
) << 16 |
6293 blend_color_gamma( g
, text
>> 8, (BYTE
)(alpha
>> 8), gamma_ramp
) << 8 |
6294 blend_color_gamma( b
, text
, (BYTE
) alpha
, gamma_ramp
);
6296 return blend_color( r
, text
>> 16, (BYTE
)(alpha
>> 16) ) << 16 |
6297 blend_color( g
, text
>> 8, (BYTE
)(alpha
>> 8) ) << 8 |
6298 blend_color( b
, text
, (BYTE
) alpha
);
6301 static void draw_subpixel_glyph_8888( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6302 const POINT
*origin
, DWORD text_pixel
,
6303 const struct font_gamma_ramp
*gamma_ramp
)
6305 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
6306 const DWORD
*glyph_ptr
= get_pixel_ptr_32( glyph
, origin
->x
, origin
->y
);
6309 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6311 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6313 if (glyph_ptr
[x
] == 0) continue;
6314 dst_ptr
[x
] = blend_subpixel( dst_ptr
[x
] >> 16, dst_ptr
[x
] >> 8, dst_ptr
[x
],
6315 text_pixel
, glyph_ptr
[x
], gamma_ramp
);
6317 dst_ptr
+= dib
->stride
/ 4;
6318 glyph_ptr
+= glyph
->stride
/ 4;
6322 static void draw_subpixel_glyph_32( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6323 const POINT
*origin
, DWORD text_pixel
,
6324 const struct font_gamma_ramp
*gamma_ramp
)
6326 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
6327 const DWORD
*glyph_ptr
= get_pixel_ptr_32( glyph
, origin
->x
, origin
->y
);
6331 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
6332 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
6333 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
6335 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6337 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6339 if (glyph_ptr
[x
] == 0) continue;
6340 val
= blend_subpixel( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
6341 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
6342 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
6343 text
, glyph_ptr
[x
], gamma_ramp
);
6344 dst_ptr
[x
] = rgb_to_pixel_masks( dib
, val
>> 16, val
>> 8, val
);
6346 dst_ptr
+= dib
->stride
/ 4;
6347 glyph_ptr
+= glyph
->stride
/ 4;
6351 static void draw_subpixel_glyph_24( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6352 const POINT
*origin
, DWORD text_pixel
,
6353 const struct font_gamma_ramp
*gamma_ramp
)
6355 BYTE
*dst_ptr
= get_pixel_ptr_24( dib
, rect
->left
, rect
->top
);
6356 const DWORD
*glyph_ptr
= get_pixel_ptr_32( glyph
, origin
->x
, origin
->y
);
6360 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6362 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6364 if (glyph_ptr
[x
] == 0) continue;
6365 val
= blend_subpixel( dst_ptr
[x
* 3 + 2], dst_ptr
[x
* 3 + 1], dst_ptr
[x
* 3],
6366 text_pixel
, glyph_ptr
[x
], gamma_ramp
);
6367 dst_ptr
[x
* 3] = val
;
6368 dst_ptr
[x
* 3 + 1] = val
>> 8;
6369 dst_ptr
[x
* 3 + 2] = val
>> 16;
6371 dst_ptr
+= dib
->stride
;
6372 glyph_ptr
+= glyph
->stride
/ 4;
6376 static void draw_subpixel_glyph_555( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6377 const POINT
*origin
, DWORD text_pixel
,
6378 const struct font_gamma_ramp
*gamma_ramp
)
6380 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
6381 const DWORD
*glyph_ptr
= get_pixel_ptr_32( glyph
, origin
->x
, origin
->y
);
6385 text
= ((text_pixel
<< 9) & 0xf80000) | ((text_pixel
<< 4) & 0x070000) |
6386 ((text_pixel
<< 6) & 0x00f800) | ((text_pixel
<< 1) & 0x000700) |
6387 ((text_pixel
<< 3) & 0x0000f8) | ((text_pixel
>> 2) & 0x000007);
6389 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6391 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6393 if (glyph_ptr
[x
] == 0) continue;
6394 val
= blend_subpixel( ((dst_ptr
[x
] >> 7) & 0xf8) | ((dst_ptr
[x
] >> 12) & 0x07),
6395 ((dst_ptr
[x
] >> 2) & 0xf8) | ((dst_ptr
[x
] >> 7) & 0x07),
6396 ((dst_ptr
[x
] << 3) & 0xf8) | ((dst_ptr
[x
] >> 2) & 0x07),
6397 text
, glyph_ptr
[x
], NULL
);
6398 dst_ptr
[x
] = ((val
>> 9) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 3) & 0x001f);
6400 dst_ptr
+= dib
->stride
/ 2;
6401 glyph_ptr
+= glyph
->stride
/ 4;
6405 static void draw_subpixel_glyph_16( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6406 const POINT
*origin
, DWORD text_pixel
,
6407 const struct font_gamma_ramp
*gamma_ramp
)
6409 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
6410 const DWORD
*glyph_ptr
= get_pixel_ptr_32( glyph
, origin
->x
, origin
->y
);
6414 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
6415 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
6416 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
6418 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6420 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6422 if (glyph_ptr
[x
] == 0) continue;
6423 val
= blend_subpixel( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
6424 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
6425 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
6426 text
, glyph_ptr
[x
], NULL
);
6427 dst_ptr
[x
] = rgb_to_pixel_masks( dib
, val
>> 16, val
>> 8, val
);
6429 dst_ptr
+= dib
->stride
/ 2;
6430 glyph_ptr
+= glyph
->stride
/ 4;
6434 static void draw_subpixel_glyph_null( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6435 const POINT
*origin
, DWORD text_pixel
,
6436 const struct font_gamma_ramp
*gamma_ramp
)
6441 static void create_rop_masks_32(const dib_info
*dib
, const BYTE
*hatch_ptr
,
6442 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
6444 DWORD
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6447 /* masks are always 8x8 */
6448 assert( dib
->width
== 8 );
6449 assert( dib
->height
== 8 );
6451 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
6453 for(x
= 0; x
< 8; x
++)
6455 if(*hatch_ptr
& pixel_masks_1
[x
])
6457 and_bits
[x
] = fg
->and;
6458 xor_bits
[x
] = fg
->xor;
6462 and_bits
[x
] = bg
->and;
6463 xor_bits
[x
] = bg
->xor;
6466 and_bits
+= dib
->stride
/ 4;
6467 xor_bits
+= dib
->stride
/ 4;
6471 static void create_rop_masks_24(const dib_info
*dib
, const BYTE
*hatch_ptr
,
6472 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
6474 DWORD mask_start
= 0, mask_offset
;
6475 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6478 /* masks are always 8x8 */
6479 assert( dib
->width
== 8 );
6480 assert( dib
->height
== 8 );
6482 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
6484 mask_offset
= mask_start
;
6485 for(x
= 0; x
< 8; x
++)
6487 if(*hatch_ptr
& pixel_masks_1
[x
])
6489 and_bits
[mask_offset
] = fg
->and & 0xff;
6490 xor_bits
[mask_offset
++] = fg
->xor & 0xff;
6491 and_bits
[mask_offset
] = (fg
->and >> 8) & 0xff;
6492 xor_bits
[mask_offset
++] = (fg
->xor >> 8) & 0xff;
6493 and_bits
[mask_offset
] = (fg
->and >> 16) & 0xff;
6494 xor_bits
[mask_offset
++] = (fg
->xor >> 16) & 0xff;
6498 and_bits
[mask_offset
] = bg
->and & 0xff;
6499 xor_bits
[mask_offset
++] = bg
->xor & 0xff;
6500 and_bits
[mask_offset
] = (bg
->and >> 8) & 0xff;
6501 xor_bits
[mask_offset
++] = (bg
->xor >> 8) & 0xff;
6502 and_bits
[mask_offset
] = (bg
->and >> 16) & 0xff;
6503 xor_bits
[mask_offset
++] = (bg
->xor >> 16) & 0xff;
6506 mask_start
+= dib
->stride
;
6510 static void create_rop_masks_16(const dib_info
*dib
, const BYTE
*hatch_ptr
,
6511 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
6513 WORD
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6516 /* masks are always 8x8 */
6517 assert( dib
->width
== 8 );
6518 assert( dib
->height
== 8 );
6520 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
6522 for(x
= 0; x
< 8; x
++)
6524 if(*hatch_ptr
& pixel_masks_1
[x
])
6526 and_bits
[x
] = fg
->and;
6527 xor_bits
[x
] = fg
->xor;
6531 and_bits
[x
] = bg
->and;
6532 xor_bits
[x
] = bg
->xor;
6535 and_bits
+= dib
->stride
/ 2;
6536 xor_bits
+= dib
->stride
/ 2;
6540 static void create_rop_masks_8(const dib_info
*dib
, const BYTE
*hatch_ptr
,
6541 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
6543 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6546 /* masks are always 8x8 */
6547 assert( dib
->width
== 8 );
6548 assert( dib
->height
== 8 );
6550 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
6552 for(x
= 0; x
< 8; x
++)
6554 if(*hatch_ptr
& pixel_masks_1
[x
])
6556 and_bits
[x
] = fg
->and;
6557 xor_bits
[x
] = fg
->xor;
6561 and_bits
[x
] = bg
->and;
6562 xor_bits
[x
] = bg
->xor;
6565 and_bits
+= dib
->stride
;
6566 xor_bits
+= dib
->stride
;
6570 static void create_rop_masks_4(const dib_info
*dib
, const BYTE
*hatch_ptr
,
6571 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
6574 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6575 const rop_mask
*rop_mask
;
6578 /* masks are always 8x8 */
6579 assert( dib
->width
== 8 );
6580 assert( dib
->height
== 8 );
6582 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
6584 for(x
= mask_offset
= 0; x
< 8; x
++)
6586 if(*hatch_ptr
& pixel_masks_1
[x
])
6593 and_bits
[mask_offset
] |= (rop_mask
->and & 0x0f);
6594 xor_bits
[mask_offset
] |= (rop_mask
->xor & 0x0f);
6599 and_bits
[mask_offset
] = (rop_mask
->and << 4) & 0xf0;
6600 xor_bits
[mask_offset
] = (rop_mask
->xor << 4) & 0xf0;
6603 and_bits
+= dib
->stride
;
6604 xor_bits
+= dib
->stride
;
6608 static void create_rop_masks_1(const dib_info
*dib
, const BYTE
*hatch_ptr
,
6609 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
6611 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6615 /* masks are always 8x8 */
6616 assert( dib
->width
== 8 );
6617 assert( dib
->height
== 8 );
6619 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
6621 *and_bits
= *xor_bits
= 0;
6622 for(x
= 0; x
< 8; x
++)
6624 if(*hatch_ptr
& pixel_masks_1
[x
])
6626 rop_mask
.and = (fg
->and & 1) ? 0xff : 0;
6627 rop_mask
.xor = (fg
->xor & 1) ? 0xff : 0;
6631 rop_mask
.and = (bg
->and & 1) ? 0xff : 0;
6632 rop_mask
.xor = (bg
->xor & 1) ? 0xff : 0;
6634 *and_bits
|= (rop_mask
.and & pixel_masks_1
[x
]);
6635 *xor_bits
|= (rop_mask
.xor & pixel_masks_1
[x
]);
6637 and_bits
+= dib
->stride
;
6638 xor_bits
+= dib
->stride
;
6642 static void create_rop_masks_null(const dib_info
*dib
, const BYTE
*hatch_ptr
,
6643 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
6647 static void create_dither_masks_8(const dib_info
*dib
, int rop2
, COLORREF color
, rop_mask_bits
*bits
)
6649 /* mapping between RGB triples and the default color table */
6650 static const BYTE mapping
[27] =
6652 0, /* 000000 -> 000000 */
6653 4, /* 00007f -> 000080 */
6654 252, /* 0000ff -> 0000ff */
6655 2, /* 007f00 -> 008000 */
6656 6, /* 007f7f -> 008080 */
6657 224, /* 007fff -> 0080c0 */
6658 250, /* 00ff00 -> 00ff00 */
6659 184, /* 00ff7f -> 00e080 */
6660 254, /* 00ffff -> 00ffff */
6661 1, /* 7f0000 -> 800000 */
6662 5, /* 7f007f -> 800080 */
6663 196, /* 7f00ff -> 8000c0 */
6664 3, /* 7f7f00 -> 808000 */
6665 248, /* 7f7f7f -> 808080 */
6666 228, /* 7f7fff -> 8080c0 */
6667 60, /* 7fff00 -> 80e000 */
6668 188, /* 7fff7f -> 80e080 */
6669 244, /* 7fffff -> 80c0c0 */
6670 249, /* ff0000 -> ff0000 */
6671 135, /* ff007f -> e00080 */
6672 253, /* ff00ff -> ff00ff */
6673 39, /* ff7f00 -> e08000 */
6674 167, /* ff7f7f -> e08080 */
6675 231, /* ff7fff -> e080c0 */
6676 251, /* ffff00 -> ffff00 */
6677 191, /* ffff7f -> e0e080 */
6678 255 /* ffffff -> ffffff */
6681 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6682 struct rop_codes codes
;
6685 /* masks are always 8x8 */
6686 assert( dib
->width
== 8 );
6687 assert( dib
->height
== 8 );
6689 get_rop_codes( rop2
, &codes
);
6691 for (y
= 0; y
< 8; y
++)
6693 for (x
= 0; x
< 8; x
++)
6695 DWORD r
= ((GetRValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
6696 DWORD g
= ((GetGValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
6697 DWORD b
= ((GetBValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
6698 DWORD pixel
= mapping
[r
* 9 + g
* 3 + b
];
6699 and_bits
[x
] = (pixel
& codes
.a1
) ^ codes
.a2
;
6700 xor_bits
[x
] = (pixel
& codes
.x1
) ^ codes
.x2
;
6702 and_bits
+= dib
->stride
;
6703 xor_bits
+= dib
->stride
;
6707 static void create_dither_masks_4(const dib_info
*dib
, int rop2
, COLORREF color
, rop_mask_bits
*bits
)
6709 /* mapping between RGB triples and the default color table */
6710 static const BYTE mapping
[27] =
6712 0, /* 000000 -> 000000 */
6713 4, /* 00007f -> 000080 */
6714 12, /* 0000ff -> 0000ff */
6715 2, /* 007f00 -> 008000 */
6716 6, /* 007f7f -> 008080 */
6717 6, /* 007fff -> 008080 */
6718 10, /* 00ff00 -> 00ff00 */
6719 6, /* 00ff7f -> 008080 */
6720 14, /* 00ffff -> 00ffff */
6721 1, /* 7f0000 -> 800000 */
6722 5, /* 7f007f -> 800080 */
6723 5, /* 7f00ff -> 800080 */
6724 3, /* 7f7f00 -> 808000 */
6725 7, /* 7f7f7f -> 808080 */
6726 8, /* 7f7fff -> c0c0c0 */
6727 3, /* 7fff00 -> 808000 */
6728 8, /* 7fff7f -> c0c0c0 */
6729 8, /* 7fffff -> c0c0c0 */
6730 9, /* ff0000 -> ff0000 */
6731 5, /* ff007f -> 800080 */
6732 13, /* ff00ff -> ff00ff */
6733 3, /* ff7f00 -> 808000 */
6734 8, /* ff7f7f -> c0c0c0 */
6735 8, /* ff7fff -> c0c0c0 */
6736 11, /* ffff00 -> ffff00 */
6737 8, /* ffff7f -> c0c0c0 */
6738 15 /* ffffff -> ffffff */
6741 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6742 struct rop_codes codes
;
6745 /* masks are always 8x8 */
6746 assert( dib
->width
== 8 );
6747 assert( dib
->height
== 8 );
6749 get_rop_codes( rop2
, &codes
);
6751 for (y
= 0; y
< 8; y
++)
6753 for (x
= 0; x
< 8; x
++)
6755 DWORD r
= ((GetRValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
6756 DWORD g
= ((GetGValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
6757 DWORD b
= ((GetBValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
6758 DWORD pixel
= mapping
[r
* 9 + g
* 3 + b
];
6761 and_bits
[x
/ 2] |= (pixel
& codes
.a1
) ^ codes
.a2
;
6762 xor_bits
[x
/ 2] |= (pixel
& codes
.x1
) ^ codes
.x2
;
6766 and_bits
[x
/ 2] = ((pixel
& codes
.a1
) ^ codes
.a2
) << 4;
6767 xor_bits
[x
/ 2] = ((pixel
& codes
.x1
) ^ codes
.x2
) << 4;
6770 and_bits
+= dib
->stride
;
6771 xor_bits
+= dib
->stride
;
6775 static void create_dither_masks_1(const dib_info
*dib
, int rop2
, COLORREF color
, rop_mask_bits
*bits
)
6777 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6778 struct rop_codes codes
;
6780 int x
, y
, grey
= (30 * GetRValue(color
) + 59 * GetGValue(color
) + 11 * GetBValue(color
) + 200) / 400;
6782 /* masks are always 8x8 */
6783 assert( dib
->width
== 8 );
6784 assert( dib
->height
== 8 );
6786 get_rop_codes( rop2
, &codes
);
6788 for (y
= 0; y
< 8; y
++)
6790 *and_bits
= *xor_bits
= 0;
6791 for (x
= 0; x
< 8; x
++)
6793 if (grey
+ bayer_8x8
[y
][x
] > 63)
6795 rop_mask
.and = (0xff & codes
.a1
) ^ codes
.a2
;
6796 rop_mask
.xor = (0xff & codes
.x1
) ^ codes
.x2
;
6800 rop_mask
.and = (0x00 & codes
.a1
) ^ codes
.a2
;
6801 rop_mask
.xor = (0x00 & codes
.x1
) ^ codes
.x2
;
6803 *and_bits
|= (rop_mask
.and & pixel_masks_1
[x
]);
6804 *xor_bits
|= (rop_mask
.xor & pixel_masks_1
[x
]);
6806 and_bits
+= dib
->stride
;
6807 xor_bits
+= dib
->stride
;
6811 static void create_dither_masks_null(const dib_info
*dib
, int rop2
, COLORREF color
, rop_mask_bits
*bits
)
6815 static inline void rop_codes_from_stretch_mode( int mode
, struct rop_codes
*codes
)
6820 case STRETCH_DELETESCANS
:
6821 get_rop_codes( R2_COPYPEN
, codes
);
6823 case STRETCH_ORSCANS
:
6824 get_rop_codes( R2_MERGEPEN
, codes
);
6826 case STRETCH_ANDSCANS
:
6827 get_rop_codes( R2_MASKPEN
, codes
);
6833 static void stretch_row_32(const dib_info
*dst_dib
, const POINT
*dst_start
,
6834 const dib_info
*src_dib
, const POINT
*src_start
,
6835 const struct stretch_params
*params
, int mode
,
6838 DWORD
*dst_ptr
= get_pixel_ptr_32( dst_dib
, dst_start
->x
, dst_start
->y
);
6839 DWORD
*src_ptr
= get_pixel_ptr_32( src_dib
, src_start
->x
, src_start
->y
);
6840 int err
= params
->err_start
;
6843 if (mode
== STRETCH_DELETESCANS
|| !keep_dst
)
6845 for (width
= params
->length
; width
; width
--)
6847 *dst_ptr
= *src_ptr
;
6848 dst_ptr
+= params
->dst_inc
;
6851 src_ptr
+= params
->src_inc
;
6852 err
+= params
->err_add_1
;
6854 else err
+= params
->err_add_2
;
6859 struct rop_codes codes
;
6861 rop_codes_from_stretch_mode( mode
, &codes
);
6862 for (width
= params
->length
; width
; width
--)
6864 do_rop_codes_32( dst_ptr
, *src_ptr
, &codes
);
6865 dst_ptr
+= params
->dst_inc
;
6868 src_ptr
+= params
->src_inc
;
6869 err
+= params
->err_add_1
;
6871 else err
+= params
->err_add_2
;
6876 static void stretch_row_24(const dib_info
*dst_dib
, const POINT
*dst_start
,
6877 const dib_info
*src_dib
, const POINT
*src_start
,
6878 const struct stretch_params
*params
, int mode
,
6881 BYTE
*dst_ptr
= get_pixel_ptr_24( dst_dib
, dst_start
->x
, dst_start
->y
);
6882 BYTE
*src_ptr
= get_pixel_ptr_24( src_dib
, src_start
->x
, src_start
->y
);
6883 int err
= params
->err_start
;
6886 if (mode
== STRETCH_DELETESCANS
|| !keep_dst
)
6888 for (width
= params
->length
; width
; width
--)
6890 dst_ptr
[0] = src_ptr
[0];
6891 dst_ptr
[1] = src_ptr
[1];
6892 dst_ptr
[2] = src_ptr
[2];
6893 dst_ptr
+= 3 * params
->dst_inc
;
6896 src_ptr
+= 3 * params
->src_inc
;
6897 err
+= params
->err_add_1
;
6899 else err
+= params
->err_add_2
;
6904 struct rop_codes codes
;
6906 rop_codes_from_stretch_mode( mode
, &codes
);
6907 for (width
= params
->length
; width
; width
--)
6909 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
6910 do_rop_codes_8( dst_ptr
+ 1, *(src_ptr
+ 1), &codes
);
6911 do_rop_codes_8( dst_ptr
+ 2, *(src_ptr
+ 2), &codes
);
6912 dst_ptr
+= 3 * params
->dst_inc
;
6915 src_ptr
+= 3 * params
->src_inc
;
6916 err
+= params
->err_add_1
;
6918 else err
+= params
->err_add_2
;
6923 static void stretch_row_16(const dib_info
*dst_dib
, const POINT
*dst_start
,
6924 const dib_info
*src_dib
, const POINT
*src_start
,
6925 const struct stretch_params
*params
, int mode
,
6928 WORD
*dst_ptr
= get_pixel_ptr_16( dst_dib
, dst_start
->x
, dst_start
->y
);
6929 WORD
*src_ptr
= get_pixel_ptr_16( src_dib
, src_start
->x
, src_start
->y
);
6930 int err
= params
->err_start
;
6933 if (mode
== STRETCH_DELETESCANS
|| !keep_dst
)
6935 for (width
= params
->length
; width
; width
--)
6937 *dst_ptr
= *src_ptr
;
6938 dst_ptr
+= params
->dst_inc
;
6941 src_ptr
+= params
->src_inc
;
6942 err
+= params
->err_add_1
;
6944 else err
+= params
->err_add_2
;
6949 struct rop_codes codes
;
6951 rop_codes_from_stretch_mode( mode
, &codes
);
6952 for (width
= params
->length
; width
; width
--)
6954 do_rop_codes_16( dst_ptr
, *src_ptr
, &codes
);
6955 dst_ptr
+= params
->dst_inc
;
6958 src_ptr
+= params
->src_inc
;
6959 err
+= params
->err_add_1
;
6961 else err
+= params
->err_add_2
;
6966 static void stretch_row_8(const dib_info
*dst_dib
, const POINT
*dst_start
,
6967 const dib_info
*src_dib
, const POINT
*src_start
,
6968 const struct stretch_params
*params
, int mode
,
6971 BYTE
*dst_ptr
= get_pixel_ptr_8( dst_dib
, dst_start
->x
, dst_start
->y
);
6972 BYTE
*src_ptr
= get_pixel_ptr_8( src_dib
, src_start
->x
, src_start
->y
);
6973 int err
= params
->err_start
;
6976 if (mode
== STRETCH_DELETESCANS
|| !keep_dst
)
6978 for (width
= params
->length
; width
; width
--)
6980 *dst_ptr
= *src_ptr
;
6981 dst_ptr
+= params
->dst_inc
;
6984 src_ptr
+= params
->src_inc
;
6985 err
+= params
->err_add_1
;
6987 else err
+= params
->err_add_2
;
6992 struct rop_codes codes
;
6994 rop_codes_from_stretch_mode( mode
, &codes
);
6995 for (width
= params
->length
; width
; width
--)
6997 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
6998 dst_ptr
+= params
->dst_inc
;
7001 src_ptr
+= params
->src_inc
;
7002 err
+= params
->err_add_1
;
7004 else err
+= params
->err_add_2
;
7009 static void stretch_row_4(const dib_info
*dst_dib
, const POINT
*dst_start
,
7010 const dib_info
*src_dib
, const POINT
*src_start
,
7011 const struct stretch_params
*params
, int mode
,
7014 BYTE
*dst_ptr
= get_pixel_ptr_4( dst_dib
, dst_start
->x
, dst_start
->y
);
7015 BYTE
*src_ptr
= get_pixel_ptr_4( src_dib
, src_start
->x
, src_start
->y
);
7016 int err
= params
->err_start
;
7017 int width
, dst_x
= dst_dib
->rect
.left
+ dst_start
->x
, src_x
= src_dib
->rect
.left
+ src_start
->x
;
7018 struct rop_codes codes
;
7021 if (!keep_dst
) mode
= STRETCH_DELETESCANS
;
7022 rop_codes_from_stretch_mode( mode
, &codes
);
7023 for (width
= params
->length
; width
; width
--)
7025 if (src_x
& 1) src_val
= (*src_ptr
& 0x0f) | (*src_ptr
<< 4);
7026 else src_val
= (*src_ptr
& 0xf0) | (*src_ptr
>> 4);
7028 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, (dst_x
& 1) ? 0x0f : 0xf0 );
7030 if ((dst_x
& ~1) != ((dst_x
+ params
->dst_inc
) & ~1))
7031 dst_ptr
+= params
->dst_inc
;
7032 dst_x
+= params
->dst_inc
;
7036 if ((src_x
& ~1) != ((src_x
+ params
->src_inc
) & ~1))
7037 src_ptr
+= params
->src_inc
;
7038 src_x
+= params
->src_inc
;
7039 err
+= params
->err_add_1
;
7041 else err
+= params
->err_add_2
;
7045 static void stretch_row_1(const dib_info
*dst_dib
, const POINT
*dst_start
,
7046 const dib_info
*src_dib
, const POINT
*src_start
,
7047 const struct stretch_params
*params
, int mode
,
7050 BYTE
*dst_ptr
= get_pixel_ptr_1( dst_dib
, dst_start
->x
, dst_start
->y
);
7051 BYTE
*src_ptr
= get_pixel_ptr_1( src_dib
, src_start
->x
, src_start
->y
);
7052 int err
= params
->err_start
;
7053 int width
, dst_x
= dst_dib
->rect
.left
+ dst_start
->x
, src_x
= src_dib
->rect
.left
+ src_start
->x
;
7054 struct rop_codes codes
;
7057 if (!keep_dst
) mode
= STRETCH_DELETESCANS
;
7058 rop_codes_from_stretch_mode( mode
, &codes
);
7059 for (width
= params
->length
; width
; width
--)
7061 src_val
= *src_ptr
& pixel_masks_1
[src_x
% 8] ? 0xff : 0;
7062 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, pixel_masks_1
[dst_x
% 8] );
7064 if ((dst_x
& ~7) != ((dst_x
+ params
->dst_inc
) & ~7))
7065 dst_ptr
+= params
->dst_inc
;
7066 dst_x
+= params
->dst_inc
;
7070 if ((src_x
& ~7) != ((src_x
+ params
->src_inc
) & ~7))
7071 src_ptr
+= params
->src_inc
;
7072 src_x
+= params
->src_inc
;
7073 err
+= params
->err_add_1
;
7075 else err
+= params
->err_add_2
;
7079 static void stretch_row_null(const dib_info
*dst_dib
, const POINT
*dst_start
,
7080 const dib_info
*src_dib
, const POINT
*src_start
,
7081 const struct stretch_params
*params
, int mode
,
7084 FIXME("bit count %d\n", dst_dib
->bit_count
);
7088 static void shrink_row_32(const dib_info
*dst_dib
, const POINT
*dst_start
,
7089 const dib_info
*src_dib
, const POINT
*src_start
,
7090 const struct stretch_params
*params
, int mode
,
7093 DWORD
*dst_ptr
= get_pixel_ptr_32( dst_dib
, dst_start
->x
, dst_start
->y
);
7094 DWORD
*src_ptr
= get_pixel_ptr_32( src_dib
, src_start
->x
, src_start
->y
);
7095 int err
= params
->err_start
;
7098 if (mode
== STRETCH_DELETESCANS
)
7100 for (width
= params
->length
; width
; width
--)
7102 *dst_ptr
= *src_ptr
;
7103 src_ptr
+= params
->src_inc
;
7106 dst_ptr
+= params
->dst_inc
;
7107 err
+= params
->err_add_1
;
7109 else err
+= params
->err_add_2
;
7114 struct rop_codes codes
;
7115 DWORD init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
7116 BOOL new_pix
= TRUE
;
7118 rop_codes_from_stretch_mode( mode
, &codes
);
7119 for (width
= params
->length
; width
; width
--)
7121 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
7122 do_rop_codes_32( dst_ptr
, *src_ptr
, &codes
);
7124 src_ptr
+= params
->src_inc
;
7127 dst_ptr
+= params
->dst_inc
;
7129 err
+= params
->err_add_1
;
7131 else err
+= params
->err_add_2
;
7136 static void shrink_row_24(const dib_info
*dst_dib
, const POINT
*dst_start
,
7137 const dib_info
*src_dib
, const POINT
*src_start
,
7138 const struct stretch_params
*params
, int mode
,
7141 BYTE
*dst_ptr
= get_pixel_ptr_24( dst_dib
, dst_start
->x
, dst_start
->y
);
7142 BYTE
*src_ptr
= get_pixel_ptr_24( src_dib
, src_start
->x
, src_start
->y
);
7143 int err
= params
->err_start
;
7146 if (mode
== STRETCH_DELETESCANS
)
7148 for (width
= params
->length
; width
; width
--)
7150 dst_ptr
[0] = src_ptr
[0];
7151 dst_ptr
[1] = src_ptr
[1];
7152 dst_ptr
[2] = src_ptr
[2];
7153 src_ptr
+= 3 * params
->src_inc
;
7156 dst_ptr
+= 3 * params
->dst_inc
;
7157 err
+= params
->err_add_1
;
7159 else err
+= params
->err_add_2
;
7164 struct rop_codes codes
;
7165 BYTE init_val
= (mode
== STRETCH_ANDSCANS
) ? 0xff : 0;
7166 BOOL new_pix
= TRUE
;
7168 rop_codes_from_stretch_mode( mode
, &codes
);
7169 for (width
= params
->length
; width
; width
--)
7171 if (new_pix
&& !keep_dst
) memset( dst_ptr
, init_val
, 3 );
7172 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
7173 do_rop_codes_8( dst_ptr
+ 1, *(src_ptr
+ 1), &codes
);
7174 do_rop_codes_8( dst_ptr
+ 2, *(src_ptr
+ 2), &codes
);
7176 src_ptr
+= 3 * params
->src_inc
;
7179 dst_ptr
+= 3 * params
->dst_inc
;
7181 err
+= params
->err_add_1
;
7183 else err
+= params
->err_add_2
;
7188 static void shrink_row_16(const dib_info
*dst_dib
, const POINT
*dst_start
,
7189 const dib_info
*src_dib
, const POINT
*src_start
,
7190 const struct stretch_params
*params
, int mode
,
7193 WORD
*dst_ptr
= get_pixel_ptr_16( dst_dib
, dst_start
->x
, dst_start
->y
);
7194 WORD
*src_ptr
= get_pixel_ptr_16( src_dib
, src_start
->x
, src_start
->y
);
7195 int err
= params
->err_start
;
7198 if (mode
== STRETCH_DELETESCANS
)
7200 for (width
= params
->length
; width
; width
--)
7202 *dst_ptr
= *src_ptr
;
7203 src_ptr
+= params
->src_inc
;
7206 dst_ptr
+= params
->dst_inc
;
7207 err
+= params
->err_add_1
;
7209 else err
+= params
->err_add_2
;
7214 struct rop_codes codes
;
7215 WORD init_val
= (mode
== STRETCH_ANDSCANS
) ? 0xffff : 0;
7216 BOOL new_pix
= TRUE
;
7218 rop_codes_from_stretch_mode( mode
, &codes
);
7219 for (width
= params
->length
; width
; width
--)
7221 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
7222 do_rop_codes_16( dst_ptr
, *src_ptr
, &codes
);
7224 src_ptr
+= params
->src_inc
;
7227 dst_ptr
+= params
->dst_inc
;
7229 err
+= params
->err_add_1
;
7231 else err
+= params
->err_add_2
;
7236 static void shrink_row_8(const dib_info
*dst_dib
, const POINT
*dst_start
,
7237 const dib_info
*src_dib
, const POINT
*src_start
,
7238 const struct stretch_params
*params
, int mode
,
7241 BYTE
*dst_ptr
= get_pixel_ptr_8( dst_dib
, dst_start
->x
, dst_start
->y
);
7242 BYTE
*src_ptr
= get_pixel_ptr_8( src_dib
, src_start
->x
, src_start
->y
);
7243 int err
= params
->err_start
;
7246 if (mode
== STRETCH_DELETESCANS
)
7248 for (width
= params
->length
; width
; width
--)
7250 *dst_ptr
= *src_ptr
;
7251 src_ptr
+= params
->src_inc
;
7254 dst_ptr
+= params
->dst_inc
;
7255 err
+= params
->err_add_1
;
7257 else err
+= params
->err_add_2
;
7262 struct rop_codes codes
;
7263 BYTE init_val
= (mode
== STRETCH_ANDSCANS
) ? 0xff : 0;
7264 BOOL new_pix
= TRUE
;
7266 rop_codes_from_stretch_mode( mode
, &codes
);
7267 for (width
= params
->length
; width
; width
--)
7269 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
7270 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
7272 src_ptr
+= params
->src_inc
;
7275 dst_ptr
+= params
->dst_inc
;
7277 err
+= params
->err_add_1
;
7279 else err
+= params
->err_add_2
;
7284 static void shrink_row_4(const dib_info
*dst_dib
, const POINT
*dst_start
,
7285 const dib_info
*src_dib
, const POINT
*src_start
,
7286 const struct stretch_params
*params
, int mode
,
7289 BYTE
*dst_ptr
= get_pixel_ptr_4( dst_dib
, dst_start
->x
, dst_start
->y
);
7290 BYTE
*src_ptr
= get_pixel_ptr_4( src_dib
, src_start
->x
, src_start
->y
);
7291 int err
= params
->err_start
;
7292 int width
, dst_x
= dst_dib
->rect
.left
+ dst_start
->x
, src_x
= src_dib
->rect
.left
+ src_start
->x
;
7293 struct rop_codes codes
;
7294 BYTE src_val
, init_val
= (mode
== STRETCH_ANDSCANS
) ? 0xff : 0;
7295 BOOL new_pix
= TRUE
;
7297 rop_codes_from_stretch_mode( mode
, &codes
);
7298 for (width
= params
->length
; width
; width
--)
7300 if (new_pix
&& !keep_dst
) do_rop_mask_8( dst_ptr
, 0, init_val
, (dst_x
& 1) ? 0x0f : 0xf0 );
7302 if (src_x
& 1) src_val
= (*src_ptr
& 0x0f) | (*src_ptr
<< 4);
7303 else src_val
= (*src_ptr
& 0xf0) | (*src_ptr
>> 4);
7305 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, (dst_x
& 1) ? 0x0f : 0xf0 );
7308 if ((src_x
& ~1) != ((src_x
+ params
->src_inc
) & ~1))
7309 src_ptr
+= params
->src_inc
;
7310 src_x
+= params
->src_inc
;
7314 if ((dst_x
& ~1) != ((dst_x
+ params
->dst_inc
) & ~1))
7315 dst_ptr
+= params
->dst_inc
;
7316 dst_x
+= params
->dst_inc
;
7318 err
+= params
->err_add_1
;
7320 else err
+= params
->err_add_2
;
7324 static void shrink_row_1(const dib_info
*dst_dib
, const POINT
*dst_start
,
7325 const dib_info
*src_dib
, const POINT
*src_start
,
7326 const struct stretch_params
*params
, int mode
,
7329 BYTE
*dst_ptr
= get_pixel_ptr_1( dst_dib
, dst_start
->x
, dst_start
->y
);
7330 BYTE
*src_ptr
= get_pixel_ptr_1( src_dib
, src_start
->x
, src_start
->y
);
7331 int err
= params
->err_start
;
7332 int width
, dst_x
= dst_dib
->rect
.left
+ dst_start
->x
, src_x
= src_dib
->rect
.left
+ src_start
->x
;
7333 struct rop_codes codes
;
7334 BYTE src_val
, init_val
= (mode
== STRETCH_ANDSCANS
) ? 0xff : 0;
7335 BOOL new_pix
= TRUE
;
7337 rop_codes_from_stretch_mode( mode
, &codes
);
7338 for (width
= params
->length
; width
; width
--)
7340 if (new_pix
&& !keep_dst
) do_rop_mask_8( dst_ptr
, 0, init_val
, pixel_masks_1
[dst_x
% 8] );
7341 src_val
= *src_ptr
& pixel_masks_1
[src_x
% 8] ? 0xff : 0;
7342 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, pixel_masks_1
[dst_x
% 8] );
7345 if ((src_x
& ~7) != ((src_x
+ params
->src_inc
) & ~7))
7346 src_ptr
+= params
->src_inc
;
7347 src_x
+= params
->src_inc
;
7351 if ((dst_x
& ~7) != ((dst_x
+ params
->dst_inc
) & ~7))
7352 dst_ptr
+= params
->dst_inc
;
7353 dst_x
+= params
->dst_inc
;
7355 err
+= params
->err_add_1
;
7357 else err
+= params
->err_add_2
;
7361 static void shrink_row_null(const dib_info
*dst_dib
, const POINT
*dst_start
,
7362 const dib_info
*src_dib
, const POINT
*src_start
,
7363 const struct stretch_params
*params
, int mode
,
7366 FIXME("bit count %d\n", dst_dib
->bit_count
);
7370 const primitive_funcs funcs_8888
=
7380 draw_subpixel_glyph_8888
,
7382 colorref_to_pixel_888
,
7383 pixel_to_colorref_888
,
7385 create_rop_masks_32
,
7386 create_dither_masks_null
,
7391 const primitive_funcs funcs_32
=
7401 draw_subpixel_glyph_32
,
7403 colorref_to_pixel_masks
,
7404 pixel_to_colorref_masks
,
7406 create_rop_masks_32
,
7407 create_dither_masks_null
,
7412 const primitive_funcs funcs_24
=
7422 draw_subpixel_glyph_24
,
7424 colorref_to_pixel_888
,
7425 pixel_to_colorref_888
,
7427 create_rop_masks_24
,
7428 create_dither_masks_null
,
7433 const primitive_funcs funcs_555
=
7443 draw_subpixel_glyph_555
,
7445 colorref_to_pixel_555
,
7446 pixel_to_colorref_555
,
7448 create_rop_masks_16
,
7449 create_dither_masks_null
,
7454 const primitive_funcs funcs_16
=
7464 draw_subpixel_glyph_16
,
7466 colorref_to_pixel_masks
,
7467 pixel_to_colorref_masks
,
7469 create_rop_masks_16
,
7470 create_dither_masks_null
,
7475 const primitive_funcs funcs_8
=
7485 draw_subpixel_glyph_null
,
7487 colorref_to_pixel_colortable
,
7488 pixel_to_colorref_colortable
,
7491 create_dither_masks_8
,
7496 const primitive_funcs funcs_4
=
7506 draw_subpixel_glyph_null
,
7508 colorref_to_pixel_colortable
,
7509 pixel_to_colorref_colortable
,
7512 create_dither_masks_4
,
7517 const primitive_funcs funcs_1
=
7527 draw_subpixel_glyph_null
,
7529 colorref_to_pixel_colortable
,
7530 pixel_to_colorref_colortable
,
7533 create_dither_masks_1
,
7538 const primitive_funcs funcs_null
=
7548 draw_subpixel_glyph_null
,
7550 colorref_to_pixel_null
,
7551 pixel_to_colorref_null
,
7553 create_rop_masks_null
,
7554 create_dither_masks_null
,