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
)
2145 ret
= ((30 * r
+ 59 * g
+ 11 * b
) / 100 + bayer_16x16
[y
% 16][x
% 16]) > 255;
2146 else if (dib
->color_table_size
== 1)
2147 ret
= (src_pixel
== bg_pixel
);
2149 ret
= rgb_to_pixel_colortable( dib
, r
, g
, b
);
2151 return ret
? 0xff : 0;
2154 static DWORD
rgbquad_to_pixel_colortable(const dib_info
*dib
, RGBQUAD rgb
)
2156 return rgb_to_pixel_colortable( dib
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
2159 static DWORD
colorref_to_pixel_colortable(const dib_info
*dib
, COLORREF color
)
2161 return rgb_to_pixel_colortable( dib
, GetRValue(color
), GetGValue(color
), GetBValue(color
) );
2164 static DWORD
colorref_to_pixel_null(const dib_info
*dib
, COLORREF color
)
2169 static COLORREF
pixel_to_colorref_888(const dib_info
*dib
, DWORD pixel
)
2171 return ( ((pixel
>> 16) & 0xff) | (pixel
& 0xff00) | ((pixel
<< 16) & 0xff0000) );
2174 static COLORREF
pixel_to_colorref_masks(const dib_info
*dib
, DWORD pixel
)
2176 return RGB( get_field( pixel
, dib
->red_shift
, dib
->red_len
),
2177 get_field( pixel
, dib
->green_shift
, dib
->green_len
),
2178 get_field( pixel
, dib
->blue_shift
, dib
->blue_len
) );
2181 static COLORREF
pixel_to_colorref_555(const dib_info
*dib
, DWORD pixel
)
2183 return RGB( ((pixel
>> 7) & 0xf8) | ((pixel
>> 12) & 0x07),
2184 ((pixel
>> 2) & 0xf8) | ((pixel
>> 7) & 0x07),
2185 ((pixel
<< 3) & 0xf8) | ((pixel
>> 2) & 0x07) );
2188 static COLORREF
pixel_to_colorref_colortable(const dib_info
*dib
, DWORD pixel
)
2190 const RGBQUAD
*color_table
= get_dib_color_table( dib
);
2192 if (!dib
->color_table
|| pixel
< dib
->color_table_size
)
2194 RGBQUAD quad
= color_table
[pixel
];
2195 return RGB( quad
.rgbRed
, quad
.rgbGreen
, quad
.rgbBlue
);
2200 static COLORREF
pixel_to_colorref_null(const dib_info
*dib
, DWORD pixel
)
2205 static inline BOOL
bit_fields_match(const dib_info
*d1
, const dib_info
*d2
)
2207 assert( d1
->bit_count
> 8 && d1
->bit_count
== d2
->bit_count
);
2209 return d1
->red_mask
== d2
->red_mask
&&
2210 d1
->green_mask
== d2
->green_mask
&&
2211 d1
->blue_mask
== d2
->blue_mask
;
2214 static void convert_to_8888(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
2216 DWORD
*dst_start
= get_pixel_ptr_32(dst
, 0, 0), *dst_pixel
, src_val
;
2217 int x
, y
, pad_size
= (dst
->width
- (src_rect
->right
- src_rect
->left
)) * 4;
2219 switch(src
->bit_count
)
2223 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2224 if(src
->funcs
== &funcs_8888
)
2226 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
2227 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2230 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2232 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 4);
2233 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
2234 dst_start
+= dst
->stride
/ 4;
2235 src_start
+= src
->stride
/ 4;
2239 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
2241 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2243 dst_pixel
= dst_start
;
2244 src_pixel
= src_start
;
2245 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2247 src_val
= *src_pixel
++;
2248 *dst_pixel
++ = (((src_val
>> src
->red_shift
) & 0xff) << 16) |
2249 (((src_val
>> src
->green_shift
) & 0xff) << 8) |
2250 ((src_val
>> src
->blue_shift
) & 0xff);
2252 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2253 dst_start
+= dst
->stride
/ 4;
2254 src_start
+= src
->stride
/ 4;
2259 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2261 dst_pixel
= dst_start
;
2262 src_pixel
= src_start
;
2263 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2265 src_val
= *src_pixel
++;
2266 *dst_pixel
++ = (get_field( src_val
, src
->red_shift
, src
->red_len
) << 16 |
2267 get_field( src_val
, src
->green_shift
, src
->green_len
) << 8 |
2268 get_field( src_val
, src
->blue_shift
, src
->blue_len
));
2270 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2271 dst_start
+= dst
->stride
/ 4;
2272 src_start
+= src
->stride
/ 4;
2280 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2282 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2284 dst_pixel
= dst_start
;
2285 src_pixel
= src_start
;
2286 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2289 rgb
.rgbBlue
= *src_pixel
++;
2290 rgb
.rgbGreen
= *src_pixel
++;
2291 rgb
.rgbRed
= *src_pixel
++;
2293 *dst_pixel
++ = ((rgb
.rgbRed
<< 16) & 0xff0000) | ((rgb
.rgbGreen
<< 8) & 0x00ff00) | (rgb
.rgbBlue
& 0x0000ff);
2295 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2296 dst_start
+= dst
->stride
/ 4;
2297 src_start
+= src
->stride
;
2304 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2305 if(src
->funcs
== &funcs_555
)
2307 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2309 dst_pixel
= dst_start
;
2310 src_pixel
= src_start
;
2311 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2313 src_val
= *src_pixel
++;
2314 *dst_pixel
++ = ((src_val
<< 9) & 0xf80000) | ((src_val
<< 4) & 0x070000) |
2315 ((src_val
<< 6) & 0x00f800) | ((src_val
<< 1) & 0x000700) |
2316 ((src_val
<< 3) & 0x0000f8) | ((src_val
>> 2) & 0x000007);
2318 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2319 dst_start
+= dst
->stride
/ 4;
2320 src_start
+= src
->stride
/ 2;
2323 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2325 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2327 dst_pixel
= dst_start
;
2328 src_pixel
= src_start
;
2329 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2331 src_val
= *src_pixel
++;
2332 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 19) & 0xf80000) |
2333 (((src_val
>> src
->red_shift
) << 14) & 0x070000) |
2334 (((src_val
>> src
->green_shift
) << 11) & 0x00f800) |
2335 (((src_val
>> src
->green_shift
) << 6) & 0x000700) |
2336 (((src_val
>> src
->blue_shift
) << 3) & 0x0000f8) |
2337 (((src_val
>> src
->blue_shift
) >> 2) & 0x000007);
2339 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2340 dst_start
+= dst
->stride
/ 4;
2341 src_start
+= src
->stride
/ 2;
2344 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2346 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2348 dst_pixel
= dst_start
;
2349 src_pixel
= src_start
;
2350 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2352 src_val
= *src_pixel
++;
2353 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 19) & 0xf80000) |
2354 (((src_val
>> src
->red_shift
) << 14) & 0x070000) |
2355 (((src_val
>> src
->green_shift
) << 10) & 0x00fc00) |
2356 (((src_val
>> src
->green_shift
) << 4) & 0x000300) |
2357 (((src_val
>> src
->blue_shift
) << 3) & 0x0000f8) |
2358 (((src_val
>> src
->blue_shift
) >> 2) & 0x000007);
2360 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2361 dst_start
+= dst
->stride
/ 4;
2362 src_start
+= src
->stride
/ 2;
2367 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2369 dst_pixel
= dst_start
;
2370 src_pixel
= src_start
;
2371 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2373 src_val
= *src_pixel
++;
2374 *dst_pixel
++ = (get_field( src_val
, src
->red_shift
, src
->red_len
) << 16 |
2375 get_field( src_val
, src
->green_shift
, src
->green_len
) << 8 |
2376 get_field( src_val
, src
->blue_shift
, src
->blue_len
));
2378 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2379 dst_start
+= dst
->stride
/ 4;
2380 src_start
+= src
->stride
/ 2;
2388 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2389 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2390 DWORD dst_colors
[256], i
;
2392 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
2393 dst_colors
[i
] = color_table
[i
].rgbRed
<< 16 | color_table
[i
].rgbGreen
<< 8 |
2394 color_table
[i
].rgbBlue
;
2396 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2398 dst_pixel
= dst_start
;
2399 src_pixel
= src_start
;
2400 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2401 *dst_pixel
++ = dst_colors
[*src_pixel
++];
2403 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2404 dst_start
+= dst
->stride
/ 4;
2405 src_start
+= src
->stride
;
2412 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2413 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2414 DWORD dst_colors
[16], i
;
2416 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
2417 dst_colors
[i
] = color_table
[i
].rgbRed
<< 16 | color_table
[i
].rgbGreen
<< 8 |
2418 color_table
[i
].rgbBlue
;
2420 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2422 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
2423 src_pixel
= src_start
;
2424 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2427 dst_start
[x
] = dst_colors
[*src_pixel
++ & 0xf];
2429 dst_start
[x
] = dst_colors
[*src_pixel
>> 4];
2431 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
2432 dst_start
+= dst
->stride
/ 4;
2433 src_start
+= src
->stride
;
2440 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2441 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
2442 DWORD dst_colors
[2], i
;
2444 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
2445 dst_colors
[i
] = color_table
[i
].rgbRed
<< 16 | color_table
[i
].rgbGreen
<< 8 |
2446 color_table
[i
].rgbBlue
;
2448 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2450 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
2451 for(x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2453 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
2454 dst_start
[x
] = dst_colors
[src_val
];
2456 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
2457 dst_start
+= dst
->stride
/ 4;
2458 src_start
+= src
->stride
;
2465 static void convert_to_32(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
2467 DWORD
*dst_start
= get_pixel_ptr_32(dst
, 0, 0), *dst_pixel
, src_val
;
2468 int x
, y
, pad_size
= (dst
->width
- (src_rect
->right
- src_rect
->left
)) * 4;
2470 switch(src
->bit_count
)
2474 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2476 if(src
->funcs
== &funcs_8888
)
2478 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2480 dst_pixel
= dst_start
;
2481 src_pixel
= src_start
;
2482 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2484 src_val
= *src_pixel
++;
2485 *dst_pixel
++ = rgb_to_pixel_masks(dst
, src_val
>> 16, src_val
>> 8, src_val
);
2487 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2488 dst_start
+= dst
->stride
/ 4;
2489 src_start
+= src
->stride
/ 4;
2492 else if(bit_fields_match(src
, dst
))
2494 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
2495 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2498 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2500 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 4);
2501 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
2502 dst_start
+= dst
->stride
/ 4;
2503 src_start
+= src
->stride
/ 4;
2507 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8 &&
2508 dst
->red_len
== 8 && dst
->green_len
== 8 && dst
->blue_len
== 8)
2510 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2512 dst_pixel
= dst_start
;
2513 src_pixel
= src_start
;
2514 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2516 src_val
= *src_pixel
++;
2517 *dst_pixel
++ = (((src_val
>> src
->red_shift
) & 0xff) << dst
->red_shift
) |
2518 (((src_val
>> src
->green_shift
) & 0xff) << dst
->green_shift
) |
2519 (((src_val
>> src
->blue_shift
) & 0xff) << dst
->blue_shift
);
2521 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2522 dst_start
+= dst
->stride
/ 4;
2523 src_start
+= src
->stride
/ 4;
2528 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2530 dst_pixel
= dst_start
;
2531 src_pixel
= src_start
;
2532 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2534 src_val
= *src_pixel
++;
2535 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
2536 get_field(src_val
, src
->red_shift
, src
->red_len
),
2537 get_field(src_val
, src
->green_shift
, src
->green_len
),
2538 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
2540 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2541 dst_start
+= dst
->stride
/ 4;
2542 src_start
+= src
->stride
/ 4;
2550 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2552 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2554 dst_pixel
= dst_start
;
2555 src_pixel
= src_start
;
2556 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, src_pixel
+= 3)
2557 *dst_pixel
++ = rgb_to_pixel_masks(dst
, src_pixel
[2], src_pixel
[1], src_pixel
[0]);
2558 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2559 dst_start
+= dst
->stride
/ 4;
2560 src_start
+= src
->stride
;
2567 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2568 if(src
->funcs
== &funcs_555
)
2570 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2572 dst_pixel
= dst_start
;
2573 src_pixel
= src_start
;
2574 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2576 src_val
= *src_pixel
++;
2577 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
2578 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
2579 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
2580 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07));
2582 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2583 dst_start
+= dst
->stride
/ 4;
2584 src_start
+= src
->stride
/ 2;
2587 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2589 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2591 dst_pixel
= dst_start
;
2592 src_pixel
= src_start
;
2593 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2595 src_val
= *src_pixel
++;
2596 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
2597 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2598 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
2599 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
2600 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
2601 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2602 (((src_val
>> src
->blue_shift
) >> 2) & 0x07));
2604 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2605 dst_start
+= dst
->stride
/ 4;
2606 src_start
+= src
->stride
/ 2;
2609 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2611 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2613 dst_pixel
= dst_start
;
2614 src_pixel
= src_start
;
2615 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2617 src_val
= *src_pixel
++;
2618 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
2619 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2620 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
2621 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
2622 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
2623 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2624 (((src_val
>> src
->blue_shift
) >> 2) & 0x07));
2626 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2627 dst_start
+= dst
->stride
/ 4;
2628 src_start
+= src
->stride
/ 2;
2633 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2635 dst_pixel
= dst_start
;
2636 src_pixel
= src_start
;
2637 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2639 src_val
= *src_pixel
++;
2640 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
2641 get_field(src_val
, src
->red_shift
, src
->red_len
),
2642 get_field(src_val
, src
->green_shift
, src
->green_len
),
2643 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
2645 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2646 dst_start
+= dst
->stride
/ 4;
2647 src_start
+= src
->stride
/ 2;
2655 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2656 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2657 DWORD dst_colors
[256], i
;
2659 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
2660 dst_colors
[i
] = rgbquad_to_pixel_masks(dst
, color_table
[i
]);
2662 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2664 dst_pixel
= dst_start
;
2665 src_pixel
= src_start
;
2666 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2667 *dst_pixel
++ = dst_colors
[*src_pixel
++];
2669 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2670 dst_start
+= dst
->stride
/ 4;
2671 src_start
+= src
->stride
;
2678 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2679 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2680 DWORD dst_colors
[16], i
;
2682 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
2683 dst_colors
[i
] = rgbquad_to_pixel_masks(dst
, color_table
[i
]);
2685 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2687 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
2688 src_pixel
= src_start
;
2689 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2692 dst_start
[x
] = dst_colors
[*src_pixel
++ & 0xf];
2694 dst_start
[x
] = dst_colors
[*src_pixel
>> 4];
2696 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
2697 dst_start
+= dst
->stride
/ 4;
2698 src_start
+= src
->stride
;
2705 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2706 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
2707 DWORD dst_colors
[2], i
;
2709 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
2710 dst_colors
[i
] = rgbquad_to_pixel_masks(dst
, color_table
[i
]);
2712 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2714 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
2715 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2717 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
2718 dst_start
[x
] = dst_colors
[src_val
];
2720 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
2721 dst_start
+= dst
->stride
/ 4;
2722 src_start
+= src
->stride
;
2729 static void convert_to_24(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
2731 BYTE
*dst_start
= get_pixel_ptr_24(dst
, 0, 0), *dst_pixel
;
2733 int x
, y
, pad_size
= ((dst
->width
* 3 + 3) & ~3) - (src_rect
->right
- src_rect
->left
) * 3;
2735 switch(src
->bit_count
)
2739 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2740 if(src
->funcs
== &funcs_8888
)
2742 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2744 dst_pixel
= dst_start
;
2745 src_pixel
= src_start
;
2746 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2748 src_val
= *src_pixel
++;
2749 *dst_pixel
++ = src_val
& 0xff;
2750 *dst_pixel
++ = (src_val
>> 8) & 0xff;
2751 *dst_pixel
++ = (src_val
>> 16) & 0xff;
2753 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2754 dst_start
+= dst
->stride
;
2755 src_start
+= src
->stride
/ 4;
2758 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
2760 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2762 dst_pixel
= dst_start
;
2763 src_pixel
= src_start
;
2764 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2766 src_val
= *src_pixel
++;
2767 *dst_pixel
++ = (src_val
>> src
->blue_shift
) & 0xff;
2768 *dst_pixel
++ = (src_val
>> src
->green_shift
) & 0xff;
2769 *dst_pixel
++ = (src_val
>> src
->red_shift
) & 0xff;
2771 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2772 dst_start
+= dst
->stride
;
2773 src_start
+= src
->stride
/ 4;
2778 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2780 dst_pixel
= dst_start
;
2781 src_pixel
= src_start
;
2782 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2784 src_val
= *src_pixel
++;
2785 *dst_pixel
++ = get_field( src_val
, src
->blue_shift
, src
->blue_len
);
2786 *dst_pixel
++ = get_field( src_val
, src
->green_shift
, src
->green_len
);
2787 *dst_pixel
++ = get_field( src_val
, src
->red_shift
, src
->red_len
);
2789 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2790 dst_start
+= dst
->stride
;
2791 src_start
+= src
->stride
/ 4;
2799 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
);
2801 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
2802 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2805 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2807 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 3);
2808 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
) * 3, 0, pad_size
);
2809 dst_start
+= dst
->stride
;
2810 src_start
+= src
->stride
;
2818 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2819 if(src
->funcs
== &funcs_555
)
2821 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2823 dst_pixel
= dst_start
;
2824 src_pixel
= src_start
;
2825 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2827 src_val
= *src_pixel
++;
2828 *dst_pixel
++ = ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07);
2829 *dst_pixel
++ = ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07);
2830 *dst_pixel
++ = ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07);
2832 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2833 dst_start
+= dst
->stride
;
2834 src_start
+= src
->stride
/ 2;
2837 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2839 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2841 dst_pixel
= dst_start
;
2842 src_pixel
= src_start
;
2843 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2845 src_val
= *src_pixel
++;
2846 *dst_pixel
++ = (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2847 (((src_val
>> src
->blue_shift
) >> 2) & 0x07);
2848 *dst_pixel
++ = (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
2849 (((src_val
>> src
->green_shift
) >> 2) & 0x07);
2850 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2851 (((src_val
>> src
->red_shift
) >> 2) & 0x07);
2853 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2854 dst_start
+= dst
->stride
;
2855 src_start
+= src
->stride
/ 2;
2858 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2860 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2862 dst_pixel
= dst_start
;
2863 src_pixel
= src_start
;
2864 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2866 src_val
= *src_pixel
++;
2867 *dst_pixel
++ = (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2868 (((src_val
>> src
->blue_shift
) >> 2) & 0x07);
2869 *dst_pixel
++ = (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
2870 (((src_val
>> src
->green_shift
) >> 4) & 0x03);
2871 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2872 (((src_val
>> src
->red_shift
) >> 2) & 0x07);
2874 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2875 dst_start
+= dst
->stride
;
2876 src_start
+= src
->stride
/ 2;
2881 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2883 dst_pixel
= dst_start
;
2884 src_pixel
= src_start
;
2885 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2887 src_val
= *src_pixel
++;
2888 *dst_pixel
++ = get_field(src_val
, src
->blue_shift
, src
->blue_len
);
2889 *dst_pixel
++ = get_field(src_val
, src
->green_shift
, src
->green_len
);
2890 *dst_pixel
++ = get_field(src_val
, src
->red_shift
, src
->red_len
);
2892 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2893 dst_start
+= dst
->stride
;
2894 src_start
+= src
->stride
/ 2;
2902 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2903 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2904 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2906 dst_pixel
= dst_start
;
2907 src_pixel
= src_start
;
2908 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2910 RGBQUAD rgb
= color_table
[*src_pixel
++];
2911 *dst_pixel
++ = rgb
.rgbBlue
;
2912 *dst_pixel
++ = rgb
.rgbGreen
;
2913 *dst_pixel
++ = rgb
.rgbRed
;
2915 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2916 dst_start
+= dst
->stride
;
2917 src_start
+= src
->stride
;
2924 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2925 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2926 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2928 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
2929 src_pixel
= src_start
;
2930 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2934 rgb
= color_table
[*src_pixel
++ & 0xf];
2936 rgb
= color_table
[*src_pixel
>> 4];
2937 dst_start
[x
* 3] = rgb
.rgbBlue
;
2938 dst_start
[x
* 3 + 1] = rgb
.rgbGreen
;
2939 dst_start
[x
* 3 + 2] = rgb
.rgbRed
;
2941 if(pad_size
) memset(dst_start
+ x
* 3, 0, pad_size
);
2942 dst_start
+= dst
->stride
;
2943 src_start
+= src
->stride
;
2950 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2951 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
2952 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2954 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
2955 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2958 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
2959 rgb
= color_table
[src_val
];
2960 dst_start
[x
* 3] = rgb
.rgbBlue
;
2961 dst_start
[x
* 3 + 1] = rgb
.rgbGreen
;
2962 dst_start
[x
* 3 + 2] = rgb
.rgbRed
;
2964 if(pad_size
) memset(dst_start
+ x
* 3, 0, pad_size
);
2965 dst_start
+= dst
->stride
;
2966 src_start
+= src
->stride
;
2973 static void convert_to_555(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
2975 WORD
*dst_start
= get_pixel_ptr_16(dst
, 0, 0), *dst_pixel
;
2976 INT x
, y
, pad_size
= ((dst
->width
+ 1) & ~1) * 2 - (src_rect
->right
- src_rect
->left
) * 2;
2979 switch(src
->bit_count
)
2983 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2985 if(src
->funcs
== &funcs_8888
)
2987 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2989 dst_pixel
= dst_start
;
2990 src_pixel
= src_start
;
2991 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2993 src_val
= *src_pixel
++;
2994 *dst_pixel
++ = ((src_val
>> 9) & 0x7c00) |
2995 ((src_val
>> 6) & 0x03e0) |
2996 ((src_val
>> 3) & 0x001f);
2998 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2999 dst_start
+= dst
->stride
/ 2;
3000 src_start
+= src
->stride
/ 4;
3003 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
3005 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3007 dst_pixel
= dst_start
;
3008 src_pixel
= src_start
;
3009 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3011 src_val
= *src_pixel
++;
3012 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 7) & 0x7c00) |
3013 (((src_val
>> src
->green_shift
) << 2) & 0x03e0) |
3014 (((src_val
>> src
->blue_shift
) >> 3) & 0x001f);
3016 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3017 dst_start
+= dst
->stride
/ 2;
3018 src_start
+= src
->stride
/ 4;
3023 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3025 dst_pixel
= dst_start
;
3026 src_pixel
= src_start
;
3027 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3029 src_val
= *src_pixel
++;
3030 *dst_pixel
++ = (((get_field(src_val
, src
->red_shift
, src
->red_len
) << 7) & 0x7c00) |
3031 ((get_field(src_val
, src
->green_shift
, src
->green_len
) << 2) & 0x03e0) |
3032 ( get_field(src_val
, src
->blue_shift
, src
->blue_len
) >> 3));
3034 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3035 dst_start
+= dst
->stride
/ 2;
3036 src_start
+= src
->stride
/ 4;
3044 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3046 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3048 dst_pixel
= dst_start
;
3049 src_pixel
= src_start
;
3050 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3053 rgb
.rgbBlue
= *src_pixel
++;
3054 rgb
.rgbGreen
= *src_pixel
++;
3055 rgb
.rgbRed
= *src_pixel
++;
3057 *dst_pixel
++ = ((rgb
.rgbRed
<< 7) & 0x7c00) |
3058 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
3059 ((rgb
.rgbBlue
>> 3) & 0x001f);
3061 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3062 dst_start
+= dst
->stride
/ 2;
3063 src_start
+= src
->stride
;
3070 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3071 if(src
->funcs
== &funcs_555
)
3073 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
3074 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
3077 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3079 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 2);
3080 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
3081 dst_start
+= dst
->stride
/ 2;
3082 src_start
+= src
->stride
/ 2;
3086 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
3088 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3090 dst_pixel
= dst_start
;
3091 src_pixel
= src_start
;
3092 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3094 src_val
= *src_pixel
++;
3095 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 10) & 0x7c00) |
3096 (((src_val
>> src
->green_shift
) << 5) & 0x03e0) |
3097 ( (src_val
>> src
->blue_shift
) & 0x001f);
3099 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3100 dst_start
+= dst
->stride
/ 2;
3101 src_start
+= src
->stride
/ 2;
3104 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
3106 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3108 dst_pixel
= dst_start
;
3109 src_pixel
= src_start
;
3110 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3112 src_val
= *src_pixel
++;
3113 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 10) & 0x7c00) |
3114 (((src_val
>> src
->green_shift
) << 4) & 0x03e0) |
3115 ( (src_val
>> src
->blue_shift
) & 0x001f);
3117 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3118 dst_start
+= dst
->stride
/ 2;
3119 src_start
+= src
->stride
/ 2;
3124 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3126 dst_pixel
= dst_start
;
3127 src_pixel
= src_start
;
3128 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3130 src_val
= *src_pixel
++;
3131 *dst_pixel
++ = (((get_field(src_val
, src
->red_shift
, src
->red_len
) << 7) & 0x7c00) |
3132 ((get_field(src_val
, src
->green_shift
, src
->green_len
) << 2) & 0x03e0) |
3133 ( get_field(src_val
, src
->blue_shift
, src
->blue_len
) >> 3));
3135 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3136 dst_start
+= dst
->stride
/ 2;
3137 src_start
+= src
->stride
/ 2;
3145 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3146 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3147 WORD dst_colors
[256];
3150 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
3151 dst_colors
[i
] = ((color_table
[i
].rgbRed
<< 7) & 0x7c00) |
3152 ((color_table
[i
].rgbGreen
<< 2) & 0x03e0) |
3153 ((color_table
[i
].rgbBlue
>> 3) & 0x001f);
3155 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3157 dst_pixel
= dst_start
;
3158 src_pixel
= src_start
;
3159 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3160 *dst_pixel
++ = dst_colors
[*src_pixel
++];
3162 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3163 dst_start
+= dst
->stride
/ 2;
3164 src_start
+= src
->stride
;
3171 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3172 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3173 WORD dst_colors
[16];
3176 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
3177 dst_colors
[i
] = ((color_table
[i
].rgbRed
<< 7) & 0x7c00) |
3178 ((color_table
[i
].rgbGreen
<< 2) & 0x03e0) |
3179 ((color_table
[i
].rgbBlue
>> 3) & 0x001f);
3181 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3183 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
3184 src_pixel
= src_start
;
3185 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
3188 dst_start
[x
] = dst_colors
[*src_pixel
++ & 0xf];
3190 dst_start
[x
] = dst_colors
[*src_pixel
>> 4];
3192 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3193 dst_start
+= dst
->stride
/ 2;
3194 src_start
+= src
->stride
;
3201 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3202 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
3206 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
3207 dst_colors
[i
] = ((color_table
[i
].rgbRed
<< 7) & 0x7c00) |
3208 ((color_table
[i
].rgbGreen
<< 2) & 0x03e0) |
3209 ((color_table
[i
].rgbBlue
>> 3) & 0x001f);
3211 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3213 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
3214 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
3216 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
3217 dst_start
[x
] = dst_colors
[src_val
];
3219 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3220 dst_start
+= dst
->stride
/ 2;
3221 src_start
+= src
->stride
;
3228 static void convert_to_16(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
3230 WORD
*dst_start
= get_pixel_ptr_16(dst
, 0, 0), *dst_pixel
;
3231 INT x
, y
, pad_size
= ((dst
->width
+ 1) & ~1) * 2 - (src_rect
->right
- src_rect
->left
) * 2;
3234 switch(src
->bit_count
)
3238 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3240 if(src
->funcs
== &funcs_8888
)
3242 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3244 dst_pixel
= dst_start
;
3245 src_pixel
= src_start
;
3246 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3248 src_val
= *src_pixel
++;
3249 *dst_pixel
++ = rgb_to_pixel_masks(dst
, src_val
>> 16, src_val
>> 8, src_val
);
3251 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3252 dst_start
+= dst
->stride
/ 2;
3253 src_start
+= src
->stride
/ 4;
3256 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
3258 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3260 dst_pixel
= dst_start
;
3261 src_pixel
= src_start
;
3262 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3264 src_val
= *src_pixel
++;
3265 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
3266 src_val
>> src
->red_shift
,
3267 src_val
>> src
->green_shift
,
3268 src_val
>> src
->blue_shift
);
3270 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3271 dst_start
+= dst
->stride
/ 2;
3272 src_start
+= src
->stride
/ 4;
3277 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3279 dst_pixel
= dst_start
;
3280 src_pixel
= src_start
;
3281 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3283 src_val
= *src_pixel
++;
3284 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
3285 get_field(src_val
, src
->red_shift
, src
->red_len
),
3286 get_field(src_val
, src
->green_shift
, src
->green_len
),
3287 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3289 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3290 dst_start
+= dst
->stride
/ 2;
3291 src_start
+= src
->stride
/ 4;
3299 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3301 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3303 dst_pixel
= dst_start
;
3304 src_pixel
= src_start
;
3305 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, src_pixel
+= 3)
3306 *dst_pixel
++ = rgb_to_pixel_masks(dst
, src_pixel
[2], src_pixel
[1], src_pixel
[0]);
3307 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3308 dst_start
+= dst
->stride
/ 2;
3309 src_start
+= src
->stride
;
3316 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3317 if(src
->funcs
== &funcs_555
)
3319 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3321 dst_pixel
= dst_start
;
3322 src_pixel
= src_start
;
3323 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3325 src_val
= *src_pixel
++;
3326 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
3327 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
3328 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
3329 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07));
3331 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3332 dst_start
+= dst
->stride
/ 2;
3333 src_start
+= src
->stride
/ 2;
3336 else if(bit_fields_match(src
, dst
))
3338 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
3339 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
3342 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3344 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 2);
3345 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
3346 dst_start
+= dst
->stride
/ 2;
3347 src_start
+= src
->stride
/ 2;
3351 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
3353 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3355 dst_pixel
= dst_start
;
3356 src_pixel
= src_start
;
3357 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3359 src_val
= *src_pixel
++;
3360 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
3361 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3362 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3363 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
3364 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
3365 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3366 (((src_val
>> src
->blue_shift
) >> 2) & 0x07));
3368 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3369 dst_start
+= dst
->stride
/ 2;
3370 src_start
+= src
->stride
/ 2;
3373 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
3375 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3377 dst_pixel
= dst_start
;
3378 src_pixel
= src_start
;
3379 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3381 src_val
= *src_pixel
++;
3382 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
3383 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3384 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3385 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
3386 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
3387 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3388 (((src_val
>> src
->blue_shift
) >> 2) & 0x07));
3390 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3391 dst_start
+= dst
->stride
/ 2;
3392 src_start
+= src
->stride
/ 2;
3397 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3399 dst_pixel
= dst_start
;
3400 src_pixel
= src_start
;
3401 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3403 src_val
= *src_pixel
++;
3404 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
3405 get_field(src_val
, src
->red_shift
, src
->red_len
),
3406 get_field(src_val
, src
->green_shift
, src
->green_len
),
3407 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3409 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3410 dst_start
+= dst
->stride
/ 2;
3411 src_start
+= src
->stride
/ 2;
3419 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3420 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3421 WORD dst_colors
[256];
3424 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
3425 dst_colors
[i
] = rgbquad_to_pixel_masks(dst
, color_table
[i
]);
3427 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3429 dst_pixel
= dst_start
;
3430 src_pixel
= src_start
;
3431 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3432 *dst_pixel
++ = dst_colors
[*src_pixel
++];
3434 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3435 dst_start
+= dst
->stride
/ 2;
3436 src_start
+= src
->stride
;
3443 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3444 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3445 WORD dst_colors
[16];
3448 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
3449 dst_colors
[i
] = rgbquad_to_pixel_masks(dst
, color_table
[i
]);
3451 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3453 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
3454 src_pixel
= src_start
;
3455 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
3458 dst_start
[x
] = dst_colors
[*src_pixel
++ & 0xf];
3460 dst_start
[x
] = dst_colors
[*src_pixel
>> 4];
3462 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3463 dst_start
+= dst
->stride
/ 2;
3464 src_start
+= src
->stride
;
3471 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3472 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
3476 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
3477 dst_colors
[i
] = rgbquad_to_pixel_masks(dst
, color_table
[i
]);
3479 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3481 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
3482 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
3484 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
3485 dst_start
[x
] = dst_colors
[src_val
];
3487 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3488 dst_start
+= dst
->stride
/ 2;
3489 src_start
+= src
->stride
;
3496 static inline BOOL
color_tables_match(const dib_info
*d1
, const dib_info
*d2
)
3498 if (!d1
->color_table
|| !d2
->color_table
) return (!d1
->color_table
&& !d2
->color_table
);
3499 return !memcmp(d1
->color_table
, d2
->color_table
, (1 << d1
->bit_count
) * sizeof(d1
->color_table
[0]));
3502 static inline DWORD
rgb_lookup_colortable(const dib_info
*dst
, BYTE r
, BYTE g
, BYTE b
)
3504 /* Windows reduces precision to 5 bits, probably in order to build some sort of lookup cache */
3505 return rgb_to_pixel_colortable( dst
, (r
& ~7) + 4, (g
& ~7) + 4, (b
& ~7) + 4 );
3508 static void convert_to_8(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
3510 BYTE
*dst_start
= get_pixel_ptr_8(dst
, 0, 0), *dst_pixel
;
3511 INT x
, y
, pad_size
= ((dst
->width
+ 3) & ~3) - (src_rect
->right
- src_rect
->left
);
3514 switch(src
->bit_count
)
3518 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3520 if(src
->funcs
== &funcs_8888
)
3522 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3524 dst_pixel
= dst_start
;
3525 src_pixel
= src_start
;
3526 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3528 src_val
= *src_pixel
++;
3529 *dst_pixel
++ = rgb_lookup_colortable(dst
, src_val
>> 16, src_val
>> 8, src_val
);
3531 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3532 dst_start
+= dst
->stride
;
3533 src_start
+= src
->stride
/ 4;
3536 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
3538 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3540 dst_pixel
= dst_start
;
3541 src_pixel
= src_start
;
3542 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3544 src_val
= *src_pixel
++;
3545 *dst_pixel
++ = rgb_lookup_colortable(dst
,
3546 src_val
>> src
->red_shift
,
3547 src_val
>> src
->green_shift
,
3548 src_val
>> src
->blue_shift
);
3550 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3551 dst_start
+= dst
->stride
;
3552 src_start
+= src
->stride
/ 4;
3557 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3559 dst_pixel
= dst_start
;
3560 src_pixel
= src_start
;
3561 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3563 src_val
= *src_pixel
++;
3564 *dst_pixel
++ = rgb_lookup_colortable(dst
,
3565 get_field(src_val
, src
->red_shift
, src
->red_len
),
3566 get_field(src_val
, src
->green_shift
, src
->green_len
),
3567 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3569 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3570 dst_start
+= dst
->stride
;
3571 src_start
+= src
->stride
/ 4;
3579 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3581 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3583 dst_pixel
= dst_start
;
3584 src_pixel
= src_start
;
3585 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, src_pixel
+= 3)
3587 *dst_pixel
++ = rgb_lookup_colortable(dst
, src_pixel
[2], src_pixel
[1], src_pixel
[0] );
3589 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3590 dst_start
+= dst
->stride
;
3591 src_start
+= src
->stride
;
3598 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3599 if(src
->funcs
== &funcs_555
)
3601 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3603 dst_pixel
= dst_start
;
3604 src_pixel
= src_start
;
3605 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3607 src_val
= *src_pixel
++;
3608 *dst_pixel
++ = rgb_lookup_colortable(dst
,
3609 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
3610 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
3611 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07) );
3613 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3614 dst_start
+= dst
->stride
;
3615 src_start
+= src
->stride
/ 2;
3618 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
3620 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3622 dst_pixel
= dst_start
;
3623 src_pixel
= src_start
;
3624 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3626 src_val
= *src_pixel
++;
3627 *dst_pixel
++ = rgb_lookup_colortable(dst
,
3628 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3629 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3630 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
3631 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
3632 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3633 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
3635 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3636 dst_start
+= dst
->stride
;
3637 src_start
+= src
->stride
/ 2;
3640 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
3642 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3644 dst_pixel
= dst_start
;
3645 src_pixel
= src_start
;
3646 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3648 src_val
= *src_pixel
++;
3649 *dst_pixel
++ = rgb_lookup_colortable(dst
,
3650 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3651 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3652 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
3653 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
3654 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3655 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
3657 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3658 dst_start
+= dst
->stride
;
3659 src_start
+= src
->stride
/ 2;
3664 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3666 dst_pixel
= dst_start
;
3667 src_pixel
= src_start
;
3668 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3670 src_val
= *src_pixel
++;
3671 *dst_pixel
++ = rgb_lookup_colortable(dst
,
3672 get_field(src_val
, src
->red_shift
, src
->red_len
),
3673 get_field(src_val
, src
->green_shift
, src
->green_len
),
3674 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3676 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3677 dst_start
+= dst
->stride
;
3678 src_start
+= src
->stride
/ 2;
3686 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3688 if(color_tables_match(dst
, src
))
3690 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
3691 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
3694 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3696 memcpy(dst_start
, src_start
, src_rect
->right
- src_rect
->left
);
3697 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
3698 dst_start
+= dst
->stride
;
3699 src_start
+= src
->stride
;
3705 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3706 BYTE dst_colors
[256];
3709 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
3710 dst_colors
[i
] = rgbquad_to_pixel_colortable(dst
, color_table
[i
]);
3712 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3714 dst_pixel
= dst_start
;
3715 src_pixel
= src_start
;
3716 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3717 *dst_pixel
++ = dst_colors
[*src_pixel
++];
3719 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3720 dst_start
+= dst
->stride
;
3721 src_start
+= src
->stride
;
3729 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3730 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3731 BYTE dst_colors
[16];
3734 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
3735 dst_colors
[i
] = rgbquad_to_pixel_colortable(dst
, color_table
[i
]);
3737 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3739 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
3740 src_pixel
= src_start
;
3741 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
3744 dst_start
[x
] = dst_colors
[*src_pixel
++ & 0xf];
3746 dst_start
[x
] = dst_colors
[*src_pixel
>> 4];
3748 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3749 dst_start
+= dst
->stride
;
3750 src_start
+= src
->stride
;
3757 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3758 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
3762 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
3763 dst_colors
[i
] = FILTER_DIBINDEX(color_table
[i
], rgbquad_to_pixel_colortable(dst
, color_table
[i
]));
3765 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3767 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
3768 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
3770 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
3771 dst_start
[x
] = dst_colors
[src_val
];
3773 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3774 dst_start
+= dst
->stride
;
3775 src_start
+= src
->stride
;
3782 static void convert_to_4(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
3784 BYTE
*dst_start
= get_pixel_ptr_4(dst
, 0, 0), *dst_pixel
, dst_val
;
3785 INT x
, y
, pad_size
= ((dst
->width
+ 7) & ~7) / 2 - (src_rect
->right
- src_rect
->left
+ 1) / 2;
3788 switch(src
->bit_count
)
3792 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3794 if(src
->funcs
== &funcs_8888
)
3796 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3798 dst_pixel
= dst_start
;
3799 src_pixel
= src_start
;
3800 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3802 src_val
= *src_pixel
++;
3803 dst_val
= rgb_to_pixel_colortable(dst
, src_val
>> 16, src_val
>> 8, src_val
);
3804 if((x
- src_rect
->left
) & 1)
3806 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3810 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3814 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3815 memset(dst_pixel
, 0, pad_size
);
3817 dst_start
+= dst
->stride
;
3818 src_start
+= src
->stride
/ 4;
3821 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
3823 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3825 dst_pixel
= dst_start
;
3826 src_pixel
= src_start
;
3827 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3829 src_val
= *src_pixel
++;
3830 dst_val
= rgb_to_pixel_colortable(dst
,
3831 src_val
>> src
->red_shift
,
3832 src_val
>> src
->green_shift
,
3833 src_val
>> src
->blue_shift
);
3834 if((x
- src_rect
->left
) & 1)
3836 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3840 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3844 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3845 memset(dst_pixel
, 0, pad_size
);
3847 dst_start
+= dst
->stride
;
3848 src_start
+= src
->stride
/ 4;
3853 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3855 dst_pixel
= dst_start
;
3856 src_pixel
= src_start
;
3857 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3859 src_val
= *src_pixel
++;
3860 dst_val
= rgb_to_pixel_colortable(dst
,
3861 get_field(src_val
, src
->red_shift
, src
->red_len
),
3862 get_field(src_val
, src
->green_shift
, src
->green_len
),
3863 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3864 if((x
- src_rect
->left
) & 1)
3866 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3870 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3874 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3875 memset(dst_pixel
, 0, pad_size
);
3877 dst_start
+= dst
->stride
;
3878 src_start
+= src
->stride
/ 4;
3886 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3888 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3890 dst_pixel
= dst_start
;
3891 src_pixel
= src_start
;
3892 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, src_pixel
+= 3)
3894 dst_val
= rgb_to_pixel_colortable(dst
, src_pixel
[2], src_pixel
[1], src_pixel
[0]);
3896 if((x
- src_rect
->left
) & 1)
3898 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3902 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3906 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3907 memset(dst_pixel
, 0, pad_size
);
3909 dst_start
+= dst
->stride
;
3910 src_start
+= src
->stride
;
3917 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3918 if(src
->funcs
== &funcs_555
)
3920 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3922 dst_pixel
= dst_start
;
3923 src_pixel
= src_start
;
3924 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3926 src_val
= *src_pixel
++;
3927 dst_val
= rgb_to_pixel_colortable(dst
,
3928 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
3929 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
3930 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07) );
3931 if((x
- src_rect
->left
) & 1)
3933 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3937 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3941 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3942 memset(dst_pixel
, 0, pad_size
);
3944 dst_start
+= dst
->stride
;
3945 src_start
+= src
->stride
/ 2;
3948 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
3950 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3952 dst_pixel
= dst_start
;
3953 src_pixel
= src_start
;
3954 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3956 src_val
= *src_pixel
++;
3957 dst_val
= rgb_to_pixel_colortable(dst
,
3958 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3959 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3960 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
3961 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
3962 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3963 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
3964 if((x
- src_rect
->left
) & 1)
3966 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3970 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3974 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3975 memset(dst_pixel
, 0, pad_size
);
3977 dst_start
+= dst
->stride
;
3978 src_start
+= src
->stride
/ 2;
3981 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
3983 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3985 dst_pixel
= dst_start
;
3986 src_pixel
= src_start
;
3987 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3989 src_val
= *src_pixel
++;
3990 dst_val
= rgb_to_pixel_colortable(dst
,
3991 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3992 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3993 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
3994 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
3995 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3996 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
3997 if((x
- src_rect
->left
) & 1)
3999 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
4003 *dst_pixel
= (dst_val
<< 4) & 0xf0;
4007 if((x
- src_rect
->left
) & 1) dst_pixel
++;
4008 memset(dst_pixel
, 0, pad_size
);
4010 dst_start
+= dst
->stride
;
4011 src_start
+= src
->stride
/ 2;
4016 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4018 dst_pixel
= dst_start
;
4019 src_pixel
= src_start
;
4020 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
4022 src_val
= *src_pixel
++;
4023 dst_val
= rgb_to_pixel_colortable(dst
,
4024 get_field(src_val
, src
->red_shift
, src
->red_len
),
4025 get_field(src_val
, src
->green_shift
, src
->green_len
),
4026 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
4027 if((x
- src_rect
->left
) & 1)
4029 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
4033 *dst_pixel
= (dst_val
<< 4) & 0xf0;
4037 if((x
- src_rect
->left
) & 1) dst_pixel
++;
4038 memset(dst_pixel
, 0, pad_size
);
4040 dst_start
+= dst
->stride
;
4041 src_start
+= src
->stride
/ 2;
4049 const RGBQUAD
*color_table
= get_dib_color_table( src
);
4050 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
4051 BYTE dst_colors
[256];
4054 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
4055 dst_colors
[i
] = rgbquad_to_pixel_colortable(dst
, color_table
[i
]);
4057 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4059 dst_pixel
= dst_start
;
4060 src_pixel
= src_start
;
4061 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
4063 dst_val
= dst_colors
[*src_pixel
++];
4064 if((x
- src_rect
->left
) & 1)
4066 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
4070 *dst_pixel
= (dst_val
<< 4) & 0xf0;
4074 if((x
- src_rect
->left
) & 1) dst_pixel
++;
4075 memset(dst_pixel
, 0, pad_size
);
4077 dst_start
+= dst
->stride
;
4078 src_start
+= src
->stride
;
4085 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
4087 if(color_tables_match(dst
, src
) && ((src
->rect
.left
+ src_rect
->left
) & 1) == 0)
4089 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
4090 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
4093 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4095 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
+ 1) / 2);
4096 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
+ 1) / 2, 0, pad_size
);
4097 dst_start
+= dst
->stride
;
4098 src_start
+= src
->stride
;
4104 const RGBQUAD
*color_table
= get_dib_color_table( src
);
4105 BYTE dst_colors
[16];
4108 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
4109 dst_colors
[i
] = rgbquad_to_pixel_colortable(dst
, color_table
[i
]);
4111 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4113 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
4114 dst_pixel
= dst_start
;
4115 src_pixel
= src_start
;
4116 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, pos
++)
4119 dst_val
= dst_colors
[*src_pixel
++ & 0xf];
4121 dst_val
= dst_colors
[*src_pixel
>> 4];
4122 if((x
- src_rect
->left
) & 1)
4124 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
4128 *dst_pixel
= (dst_val
<< 4) & 0xf0;
4132 if((x
- src_rect
->left
) & 1) dst_pixel
++;
4133 memset(dst_pixel
, 0, pad_size
);
4135 dst_start
+= dst
->stride
;
4136 src_start
+= src
->stride
;
4144 const RGBQUAD
*color_table
= get_dib_color_table( src
);
4145 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
4149 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
4150 dst_colors
[i
] = FILTER_DIBINDEX(color_table
[i
], rgbquad_to_pixel_colortable(dst
, color_table
[i
]));
4152 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4154 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
4155 dst_pixel
= dst_start
;
4156 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, pos
++)
4158 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
4159 dst_val
= dst_colors
[src_val
];
4160 if((x
- src_rect
->left
) & 1)
4162 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
4166 *dst_pixel
= (dst_val
<< 4) & 0xf0;
4170 if((x
- src_rect
->left
) & 1) dst_pixel
++;
4171 memset(dst_pixel
, 0, pad_size
);
4173 dst_start
+= dst
->stride
;
4174 src_start
+= src
->stride
;
4181 static void convert_to_1(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
4183 BYTE
*dst_start
= get_pixel_ptr_1(dst
, 0, 0), *dst_pixel
, dst_val
;
4184 INT x
, y
, pad_size
= ((dst
->width
+ 31) & ~31) / 8 - (src_rect
->right
- src_rect
->left
+ 7) / 8;
4185 RGBQUAD rgb
, bg_entry
= *get_dib_color_table( dst
); /* entry 0 is the background color */
4189 switch(src
->bit_count
)
4193 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
4194 DWORD bg_pixel
= FILTER_DIBINDEX(bg_entry
, rgbquad_to_pixel_masks(src
, bg_entry
));
4196 if(src
->funcs
== &funcs_8888
)
4198 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4200 dst_pixel
= dst_start
;
4201 src_pixel
= src_start
;
4202 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4204 src_val
= *src_pixel
++;
4205 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
, bg_pixel
,
4206 src_val
>> 16, src_val
>> 8, src_val
);
4207 if(bit_pos
== 0) *dst_pixel
= 0;
4208 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4218 if(bit_pos
!= 0) dst_pixel
++;
4219 memset(dst_pixel
, 0, pad_size
);
4221 dst_start
+= dst
->stride
;
4222 src_start
+= src
->stride
/ 4;
4225 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
4227 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4229 dst_pixel
= dst_start
;
4230 src_pixel
= src_start
;
4231 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4233 src_val
= *src_pixel
++;
4234 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
, bg_pixel
,
4235 src_val
>> src
->red_shift
,
4236 src_val
>> src
->green_shift
,
4237 src_val
>> src
->blue_shift
);
4239 if(bit_pos
== 0) *dst_pixel
= 0;
4240 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4250 if(bit_pos
!= 0) dst_pixel
++;
4251 memset(dst_pixel
, 0, pad_size
);
4253 dst_start
+= dst
->stride
;
4254 src_start
+= src
->stride
/ 4;
4259 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4261 dst_pixel
= dst_start
;
4262 src_pixel
= src_start
;
4263 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4265 src_val
= *src_pixel
++;
4266 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
, bg_pixel
,
4267 get_field(src_val
, src
->red_shift
, src
->red_len
),
4268 get_field(src_val
, src
->green_shift
, src
->green_len
),
4269 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
4271 if(bit_pos
== 0) *dst_pixel
= 0;
4272 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4282 if(bit_pos
!= 0) dst_pixel
++;
4283 memset(dst_pixel
, 0, pad_size
);
4285 dst_start
+= dst
->stride
;
4286 src_start
+= src
->stride
/ 4;
4294 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
4295 DWORD bg_pixel
= FILTER_DIBINDEX(bg_entry
, RGB(bg_entry
.rgbRed
, bg_entry
.rgbGreen
, bg_entry
.rgbBlue
));
4297 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4299 dst_pixel
= dst_start
;
4300 src_pixel
= src_start
;
4301 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++, src_pixel
+= 3)
4303 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, RGB(src_pixel
[2], src_pixel
[1], src_pixel
[0]),
4304 bg_pixel
, src_pixel
[2], src_pixel
[1], src_pixel
[0]);
4306 if(bit_pos
== 0) *dst_pixel
= 0;
4307 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4317 if(bit_pos
!= 0) dst_pixel
++;
4318 memset(dst_pixel
, 0, pad_size
);
4320 dst_start
+= dst
->stride
;
4321 src_start
+= src
->stride
;
4328 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
4329 DWORD bg_pixel
= FILTER_DIBINDEX(bg_entry
, rgbquad_to_pixel_masks(src
, bg_entry
));
4331 if(src
->funcs
== &funcs_555
)
4333 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4335 dst_pixel
= dst_start
;
4336 src_pixel
= src_start
;
4337 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4339 src_val
= *src_pixel
++;
4340 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
, bg_pixel
,
4341 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
4342 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
4343 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07));
4345 if(bit_pos
== 0) *dst_pixel
= 0;
4346 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4356 if(bit_pos
!= 0) dst_pixel
++;
4357 memset(dst_pixel
, 0, pad_size
);
4359 dst_start
+= dst
->stride
;
4360 src_start
+= src
->stride
/ 2;
4363 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
4365 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4367 dst_pixel
= dst_start
;
4368 src_pixel
= src_start
;
4369 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4371 src_val
= *src_pixel
++;
4372 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
, bg_pixel
,
4373 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
4374 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
4375 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
4376 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
4377 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
4378 (((src_val
>> src
->blue_shift
) >> 2) & 0x07));
4379 if(bit_pos
== 0) *dst_pixel
= 0;
4380 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4390 if(bit_pos
!= 0) dst_pixel
++;
4391 memset(dst_pixel
, 0, pad_size
);
4393 dst_start
+= dst
->stride
;
4394 src_start
+= src
->stride
/ 2;
4397 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
4399 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4401 dst_pixel
= dst_start
;
4402 src_pixel
= src_start
;
4403 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4405 src_val
= *src_pixel
++;
4406 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
, bg_pixel
,
4407 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
4408 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
4409 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
4410 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
4411 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
4412 (((src_val
>> src
->blue_shift
) >> 2) & 0x07));
4413 if(bit_pos
== 0) *dst_pixel
= 0;
4414 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4424 if(bit_pos
!= 0) dst_pixel
++;
4425 memset(dst_pixel
, 0, pad_size
);
4427 dst_start
+= dst
->stride
;
4428 src_start
+= src
->stride
/ 2;
4433 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4435 dst_pixel
= dst_start
;
4436 src_pixel
= src_start
;
4437 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4439 src_val
= *src_pixel
++;
4440 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
, bg_pixel
,
4441 get_field(src_val
, src
->red_shift
, src
->red_len
),
4442 get_field(src_val
, src
->green_shift
, src
->green_len
),
4443 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
4444 if(bit_pos
== 0) *dst_pixel
= 0;
4445 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4455 if(bit_pos
!= 0) dst_pixel
++;
4456 memset(dst_pixel
, 0, pad_size
);
4458 dst_start
+= dst
->stride
;
4459 src_start
+= src
->stride
/ 2;
4467 const RGBQUAD
*color_table
= get_dib_color_table( src
);
4468 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
4469 DWORD bg_pixel
= FILTER_DIBINDEX(bg_entry
, rgbquad_to_pixel_colortable(src
, bg_entry
));
4471 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4473 dst_pixel
= dst_start
;
4474 src_pixel
= src_start
;
4475 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4477 BYTE src_val
= *src_pixel
++;
4478 rgb
= color_table
[src_val
];
4479 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
, bg_pixel
,
4480 rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
4482 if(bit_pos
== 0) *dst_pixel
= 0;
4483 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4493 if(bit_pos
!= 0) dst_pixel
++;
4494 memset(dst_pixel
, 0, pad_size
);
4496 dst_start
+= dst
->stride
;
4497 src_start
+= src
->stride
;
4504 const RGBQUAD
*color_table
= get_dib_color_table( src
);
4505 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
4506 DWORD bg_pixel
= FILTER_DIBINDEX(bg_entry
, rgbquad_to_pixel_colortable(src
, bg_entry
));
4508 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4510 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
4511 dst_pixel
= dst_start
;
4512 src_pixel
= src_start
;
4513 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++, pos
++)
4515 src_val
= (pos
& 1) ? *src_pixel
++ & 0xf : *src_pixel
>> 4;
4516 rgb
= color_table
[src_val
];
4517 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
, bg_pixel
,
4518 rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
4520 if(bit_pos
== 0) *dst_pixel
= 0;
4521 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4531 if(bit_pos
!= 0) dst_pixel
++;
4532 memset(dst_pixel
, 0, pad_size
);
4534 dst_start
+= dst
->stride
;
4535 src_start
+= src
->stride
;
4540 /* Note that while MSDN states that a 1 bpp dib brush -> mono dc
4541 uses text/bkgnd colours instead of the dib's colour table, this
4542 doesn't appear to be the case for a dc backed by a
4547 const RGBQUAD
*color_table
= get_dib_color_table( src
);
4548 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
4549 DWORD bg_pixel
= FILTER_DIBINDEX(bg_entry
, rgbquad_to_pixel_colortable(src
, bg_entry
));
4551 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4553 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
4554 dst_pixel
= dst_start
;
4555 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++, pos
++)
4557 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
4558 rgb
= color_table
[src_val
];
4559 dst_val
= FILTER_DIBINDEX(rgb
, rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
, bg_pixel
,
4560 rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
));
4561 if(bit_pos
== 0) *dst_pixel
= 0;
4562 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4572 if(bit_pos
!= 0) dst_pixel
++;
4573 memset(dst_pixel
, 0, pad_size
);
4575 dst_start
+= dst
->stride
;
4576 src_start
+= src
->stride
;
4583 static void convert_to_null(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
4587 static inline BYTE
blend_color(BYTE dst
, BYTE src
, DWORD alpha
)
4589 return (src
* alpha
+ dst
* (255 - alpha
) + 127) / 255;
4592 static inline DWORD
blend_argb_constant_alpha( DWORD dst
, DWORD src
, DWORD alpha
)
4594 return (blend_color( dst
, src
, alpha
) |
4595 blend_color( dst
>> 8, src
>> 8, alpha
) << 8 |
4596 blend_color( dst
>> 16, src
>> 16, alpha
) << 16 |
4597 blend_color( dst
>> 24, src
>> 24, alpha
) << 24);
4600 static inline DWORD
blend_argb_no_src_alpha( DWORD dst
, DWORD src
, DWORD alpha
)
4602 return (blend_color( dst
, src
, alpha
) |
4603 blend_color( dst
>> 8, src
>> 8, alpha
) << 8 |
4604 blend_color( dst
>> 16, src
>> 16, alpha
) << 16 |
4605 blend_color( dst
>> 24, 255, alpha
) << 24);
4608 static inline DWORD
blend_argb( DWORD dst
, DWORD src
)
4611 BYTE g
= (BYTE
)(src
>> 8);
4612 BYTE r
= (BYTE
)(src
>> 16);
4613 DWORD alpha
= (BYTE
)(src
>> 24);
4614 return ((b
+ ((BYTE
)dst
* (255 - alpha
) + 127) / 255) |
4615 (g
+ ((BYTE
)(dst
>> 8) * (255 - alpha
) + 127) / 255) << 8 |
4616 (r
+ ((BYTE
)(dst
>> 16) * (255 - alpha
) + 127) / 255) << 16 |
4617 (alpha
+ ((BYTE
)(dst
>> 24) * (255 - alpha
) + 127) / 255) << 24);
4620 static inline DWORD
blend_argb_alpha( DWORD dst
, DWORD src
, DWORD alpha
)
4622 BYTE b
= ((BYTE
)src
* alpha
+ 127) / 255;
4623 BYTE g
= ((BYTE
)(src
>> 8) * alpha
+ 127) / 255;
4624 BYTE r
= ((BYTE
)(src
>> 16) * alpha
+ 127) / 255;
4625 alpha
= ((BYTE
)(src
>> 24) * alpha
+ 127) / 255;
4626 return ((b
+ ((BYTE
)dst
* (255 - alpha
) + 127) / 255) |
4627 (g
+ ((BYTE
)(dst
>> 8) * (255 - alpha
) + 127) / 255) << 8 |
4628 (r
+ ((BYTE
)(dst
>> 16) * (255 - alpha
) + 127) / 255) << 16 |
4629 (alpha
+ ((BYTE
)(dst
>> 24) * (255 - alpha
) + 127) / 255) << 24);
4632 static inline DWORD
blend_rgb( BYTE dst_r
, BYTE dst_g
, BYTE dst_b
, DWORD src
, BLENDFUNCTION blend
)
4634 if (blend
.AlphaFormat
& AC_SRC_ALPHA
)
4636 DWORD alpha
= blend
.SourceConstantAlpha
;
4637 BYTE src_b
= ((BYTE
)src
* alpha
+ 127) / 255;
4638 BYTE src_g
= ((BYTE
)(src
>> 8) * alpha
+ 127) / 255;
4639 BYTE src_r
= ((BYTE
)(src
>> 16) * alpha
+ 127) / 255;
4640 alpha
= ((BYTE
)(src
>> 24) * alpha
+ 127) / 255;
4641 return ((src_b
+ (dst_b
* (255 - alpha
) + 127) / 255) |
4642 (src_g
+ (dst_g
* (255 - alpha
) + 127) / 255) << 8 |
4643 (src_r
+ (dst_r
* (255 - alpha
) + 127) / 255) << 16);
4645 return (blend_color( dst_b
, src
, blend
.SourceConstantAlpha
) |
4646 blend_color( dst_g
, src
>> 8, blend
.SourceConstantAlpha
) << 8 |
4647 blend_color( dst_r
, src
>> 16, blend
.SourceConstantAlpha
) << 16);
4650 static void blend_rect_8888(const dib_info
*dst
, const RECT
*rc
,
4651 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4653 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4654 DWORD
*dst_ptr
= get_pixel_ptr_32( dst
, rc
->left
, rc
->top
);
4657 if (blend
.AlphaFormat
& AC_SRC_ALPHA
)
4659 if (blend
.SourceConstantAlpha
== 255)
4660 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
4661 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4662 dst_ptr
[x
] = blend_argb( dst_ptr
[x
], src_ptr
[x
] );
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_alpha( dst_ptr
[x
], src_ptr
[x
], blend
.SourceConstantAlpha
);
4668 else if (src
->compression
== BI_RGB
)
4669 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
4670 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4671 dst_ptr
[x
] = blend_argb_constant_alpha( dst_ptr
[x
], src_ptr
[x
], blend
.SourceConstantAlpha
);
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_no_src_alpha( dst_ptr
[x
], src_ptr
[x
], blend
.SourceConstantAlpha
);
4678 static void blend_rect_32(const dib_info
*dst
, const RECT
*rc
,
4679 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4681 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4682 DWORD
*dst_ptr
= get_pixel_ptr_32( dst
, rc
->left
, rc
->top
);
4685 if (dst
->red_len
== 8 && dst
->green_len
== 8 && dst
->blue_len
== 8)
4687 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
4689 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4691 DWORD val
= blend_rgb( dst_ptr
[x
] >> dst
->red_shift
,
4692 dst_ptr
[x
] >> dst
->green_shift
,
4693 dst_ptr
[x
] >> dst
->blue_shift
,
4694 src_ptr
[x
], blend
);
4695 dst_ptr
[x
] = ((( val
& 0xff) << dst
->blue_shift
) |
4696 (((val
>> 8) & 0xff) << dst
->green_shift
) |
4697 (((val
>> 16) & 0xff) << dst
->red_shift
));
4703 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
4705 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4707 DWORD val
= blend_rgb( get_field( dst_ptr
[x
], dst
->red_shift
, dst
->red_len
),
4708 get_field( dst_ptr
[x
], dst
->green_shift
, dst
->green_len
),
4709 get_field( dst_ptr
[x
], dst
->blue_shift
, dst
->blue_len
),
4710 src_ptr
[x
], blend
);
4711 dst_ptr
[x
] = rgb_to_pixel_masks( dst
, val
>> 16, val
>> 8, val
);
4717 static void blend_rect_24(const dib_info
*dst
, const RECT
*rc
,
4718 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4720 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4721 BYTE
*dst_ptr
= get_pixel_ptr_24( dst
, rc
->left
, rc
->top
);
4724 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
4726 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4728 DWORD val
= blend_rgb( dst_ptr
[x
* 3 + 2], dst_ptr
[x
* 3 + 1], dst_ptr
[x
* 3],
4729 src_ptr
[x
], blend
);
4730 dst_ptr
[x
* 3] = val
;
4731 dst_ptr
[x
* 3 + 1] = val
>> 8;
4732 dst_ptr
[x
* 3 + 2] = val
>> 16;
4737 static void blend_rect_555(const dib_info
*dst
, const RECT
*rc
,
4738 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4740 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4741 WORD
*dst_ptr
= get_pixel_ptr_16( dst
, rc
->left
, rc
->top
);
4744 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 2, src_ptr
+= src
->stride
/ 4)
4746 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4748 DWORD val
= blend_rgb( ((dst_ptr
[x
] >> 7) & 0xf8) | ((dst_ptr
[x
] >> 12) & 0x07),
4749 ((dst_ptr
[x
] >> 2) & 0xf8) | ((dst_ptr
[x
] >> 7) & 0x07),
4750 ((dst_ptr
[x
] << 3) & 0xf8) | ((dst_ptr
[x
] >> 2) & 0x07),
4751 src_ptr
[x
], blend
);
4752 dst_ptr
[x
] = ((val
>> 9) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 3) & 0x001f);
4757 static void blend_rect_16(const dib_info
*dst
, const RECT
*rc
,
4758 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4760 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4761 WORD
*dst_ptr
= get_pixel_ptr_16( dst
, rc
->left
, rc
->top
);
4764 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 2, src_ptr
+= src
->stride
/ 4)
4766 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4768 DWORD val
= blend_rgb( get_field( dst_ptr
[x
], dst
->red_shift
, dst
->red_len
),
4769 get_field( dst_ptr
[x
], dst
->green_shift
, dst
->green_len
),
4770 get_field( dst_ptr
[x
], dst
->blue_shift
, dst
->blue_len
),
4771 src_ptr
[x
], blend
);
4772 dst_ptr
[x
] = rgb_to_pixel_masks( dst
, val
>> 16, val
>> 8, val
);
4777 static void blend_rect_8(const dib_info
*dst
, const RECT
*rc
,
4778 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4780 const RGBQUAD
*color_table
= get_dib_color_table( dst
);
4781 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4782 BYTE
*dst_ptr
= get_pixel_ptr_8( dst
, rc
->left
, rc
->top
);
4785 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
4787 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4789 RGBQUAD rgb
= color_table
[dst_ptr
[x
]];
4790 DWORD val
= blend_rgb( rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
, src_ptr
[x
], blend
);
4791 dst_ptr
[x
] = rgb_lookup_colortable( dst
, val
>> 16, val
>> 8, val
);
4796 static void blend_rect_4(const dib_info
*dst
, const RECT
*rc
,
4797 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4799 const RGBQUAD
*color_table
= get_dib_color_table( dst
);
4800 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4801 BYTE
*dst_ptr
= get_pixel_ptr_4( dst
, rc
->left
, rc
->top
);
4804 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
4806 for (i
= 0, x
= (dst
->rect
.left
+ rc
->left
) & 1; i
< rc
->right
- rc
->left
; i
++, x
++)
4808 DWORD val
= ((x
& 1) ? dst_ptr
[x
/ 2] : (dst_ptr
[x
/ 2] >> 4)) & 0x0f;
4809 RGBQUAD rgb
= color_table
[val
];
4810 val
= blend_rgb( rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
, src_ptr
[i
], blend
);
4811 val
= rgb_lookup_colortable( dst
, val
>> 16, val
>> 8, val
);
4813 dst_ptr
[x
/ 2] = val
| (dst_ptr
[x
/ 2] & 0xf0);
4815 dst_ptr
[x
/ 2] = (val
<< 4) | (dst_ptr
[x
/ 2] & 0x0f);
4820 static void blend_rect_1(const dib_info
*dst
, const RECT
*rc
,
4821 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4823 const RGBQUAD
*color_table
= get_dib_color_table( dst
);
4824 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4825 BYTE
*dst_ptr
= get_pixel_ptr_1( dst
, rc
->left
, rc
->top
);
4828 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
4830 for (i
= 0, x
= (dst
->rect
.left
+ rc
->left
) & 7; i
< rc
->right
- rc
->left
; i
++, x
++)
4832 DWORD val
= (dst_ptr
[x
/ 8] & pixel_masks_1
[x
% 8]) ? 1 : 0;
4833 RGBQUAD rgb
= color_table
[val
];
4834 val
= blend_rgb( rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
, src_ptr
[i
], blend
);
4835 val
= rgb_to_pixel_colortable(dst
, val
>> 16, val
>> 8, val
) ? 0xff : 0;
4836 dst_ptr
[x
/ 8] = (dst_ptr
[x
/ 8] & ~pixel_masks_1
[x
% 8]) | (val
& pixel_masks_1
[x
% 8]);
4841 static void blend_rect_null(const dib_info
*dst
, const RECT
*rc
,
4842 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4846 static inline DWORD
gradient_rgb_8888( const TRIVERTEX
*v
, unsigned int pos
, unsigned int len
)
4849 r
= (v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 256;
4850 g
= (v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 256;
4851 b
= (v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 256;
4852 a
= (v
[0].Alpha
* (len
- pos
) + v
[1].Alpha
* pos
) / len
/ 256;
4853 return a
<< 24 | r
<< 16 | g
<< 8 | b
;
4856 static inline DWORD
gradient_rgb_24( const TRIVERTEX
*v
, unsigned int pos
, unsigned int len
)
4859 r
= (v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 256;
4860 g
= (v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 256;
4861 b
= (v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 256;
4862 return r
<< 16 | g
<< 8 | b
;
4865 static inline WORD
gradient_rgb_555( const TRIVERTEX
*v
, unsigned int pos
, unsigned int len
,
4866 unsigned int x
, unsigned int y
)
4868 int r
= (v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4869 int g
= (v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4870 int b
= (v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4871 r
= min( 31, max( 0, r
/ 16 ));
4872 g
= min( 31, max( 0, g
/ 16 ));
4873 b
= min( 31, max( 0, b
/ 16 ));
4874 return (r
<< 10) | (g
<< 5) | b
;
4877 static inline BYTE
gradient_rgb_8( const dib_info
*dib
, const TRIVERTEX
*v
,
4878 unsigned int pos
, unsigned int len
, unsigned int x
, unsigned int y
)
4880 BYTE r
= ((v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4881 BYTE g
= ((v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4882 BYTE b
= ((v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4883 return rgb_to_pixel_colortable( dib
, r
* 127, g
* 127, b
* 127 );
4886 /* compute the left/right triangle limit for row y */
4887 static inline void triangle_coords( const TRIVERTEX
*v
, const RECT
*rc
, int y
, int *left
, int *right
)
4891 if (y
< v
[1].y
) x1
= edge_coord( y
, v
[0].x
, v
[0].y
, v
[1].x
, v
[1].y
);
4892 else x1
= edge_coord( y
, v
[1].x
, v
[1].y
, v
[2].x
, v
[2].y
);
4894 x2
= edge_coord( y
, v
[0].x
, v
[0].y
, v
[2].x
, v
[2].y
);
4896 *left
= max( rc
->left
, min( x1
, x2
) );
4897 *right
= min( rc
->right
, max( x1
, x2
) );
4900 /* compute the matrix determinant for triangular barycentric coordinates (constant across the triangle) */
4901 static inline int triangle_det( const TRIVERTEX
*v
)
4903 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
);
4906 /* compute the barycentric weights for a given point inside the triangle */
4907 static inline void triangle_weights( const TRIVERTEX
*v
, int x
, int y
, INT64
*l1
, INT64
*l2
)
4909 *l1
= (v
[1].y
- v
[2].y
) * (x
- v
[2].x
) - (v
[1].x
- v
[2].x
) * (y
- v
[2].y
);
4910 *l2
= (v
[2].y
- v
[0].y
) * (x
- v
[2].x
) - (v
[2].x
- v
[0].x
) * (y
- v
[2].y
);
4913 static inline DWORD
gradient_triangle_8888( const TRIVERTEX
*v
, int x
, int y
, int det
)
4918 triangle_weights( v
, x
, y
, &l1
, &l2
);
4919 r
= (v
[0].Red
* l1
+ v
[1].Red
* l2
+ v
[2].Red
* (det
- l1
- l2
)) / det
/ 256;
4920 g
= (v
[0].Green
* l1
+ v
[1].Green
* l2
+ v
[2].Green
* (det
- l1
- l2
)) / det
/ 256;
4921 b
= (v
[0].Blue
* l1
+ v
[1].Blue
* l2
+ v
[2].Blue
* (det
- l1
- l2
)) / det
/ 256;
4922 a
= (v
[0].Alpha
* l1
+ v
[1].Alpha
* l2
+ v
[2].Alpha
* (det
- l1
- l2
)) / det
/ 256;
4923 return a
<< 24 | r
<< 16 | g
<< 8 | b
;
4926 static inline DWORD
gradient_triangle_24( const TRIVERTEX
*v
, int x
, int y
, int det
)
4931 triangle_weights( v
, x
, y
, &l1
, &l2
);
4932 r
= (v
[0].Red
* l1
+ v
[1].Red
* l2
+ v
[2].Red
* (det
- l1
- l2
)) / det
/ 256;
4933 g
= (v
[0].Green
* l1
+ v
[1].Green
* l2
+ v
[2].Green
* (det
- l1
- l2
)) / det
/ 256;
4934 b
= (v
[0].Blue
* l1
+ v
[1].Blue
* l2
+ v
[2].Blue
* (det
- l1
- l2
)) / det
/ 256;
4935 return r
<< 16 | g
<< 8 | b
;
4938 static inline DWORD
gradient_triangle_555( const TRIVERTEX
*v
, int x
, int y
, int det
)
4943 triangle_weights( v
, x
, y
, &l1
, &l2
);
4944 r
= (v
[0].Red
* l1
+ v
[1].Red
* l2
+ v
[2].Red
* (det
- l1
- l2
)) / det
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4945 g
= (v
[0].Green
* l1
+ v
[1].Green
* l2
+ v
[2].Green
* (det
- l1
- l2
)) / det
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4946 b
= (v
[0].Blue
* l1
+ v
[1].Blue
* l2
+ v
[2].Blue
* (det
- l1
- l2
)) / det
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4947 r
= min( 31, max( 0, r
/ 16 ));
4948 g
= min( 31, max( 0, g
/ 16 ));
4949 b
= min( 31, max( 0, b
/ 16 ));
4950 return (r
<< 10) | (g
<< 5) | b
;
4953 static inline DWORD
gradient_triangle_8( const dib_info
*dib
, const TRIVERTEX
*v
, int x
, int y
, int det
)
4958 triangle_weights( v
, x
, y
, &l1
, &l2
);
4959 r
= ((v
[0].Red
* l1
+ v
[1].Red
* l2
+ v
[2].Red
* (det
- l1
- l2
)) / det
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4960 g
= ((v
[0].Green
* l1
+ v
[1].Green
* l2
+ v
[2].Green
* (det
- l1
- l2
)) / det
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4961 b
= ((v
[0].Blue
* l1
+ v
[1].Blue
* l2
+ v
[2].Blue
* (det
- l1
- l2
)) / det
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4962 return rgb_to_pixel_colortable( dib
, r
* 127, g
* 127, b
* 127 );
4965 static BOOL
gradient_rect_8888( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4967 DWORD
*ptr
= get_pixel_ptr_32( dib
, rc
->left
, rc
->top
);
4968 int x
, y
, left
, right
, det
;
4972 case GRADIENT_FILL_RECT_H
:
4973 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4974 ptr
[x
] = gradient_rgb_8888( v
, rc
->left
+ x
- v
[0].x
, v
[1].x
- v
[0].x
);
4976 for (y
= rc
->top
+ 1; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4977 memcpy( ptr
+ dib
->stride
/ 4, ptr
, (rc
->right
- rc
->left
) * 4 );
4980 case GRADIENT_FILL_RECT_V
:
4981 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4983 DWORD val
= gradient_rgb_8888( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
4984 memset_32( ptr
, val
, rc
->right
- rc
->left
);
4988 case GRADIENT_FILL_TRIANGLE
:
4989 if (!(det
= triangle_det( v
))) return FALSE
;
4990 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4992 triangle_coords( v
, rc
, y
, &left
, &right
);
4993 for (x
= left
; x
< right
; x
++) ptr
[x
- rc
->left
] = gradient_triangle_8888( v
, x
, y
, det
);
5000 static BOOL
gradient_rect_32( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5002 DWORD
*ptr
= get_pixel_ptr_32( dib
, rc
->left
, rc
->top
);
5003 int x
, y
, left
, right
, det
;
5007 case GRADIENT_FILL_RECT_H
:
5008 if (dib
->red_len
== 8 && dib
->green_len
== 8 && dib
->blue_len
== 8)
5010 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
5012 DWORD val
= gradient_rgb_24( v
, rc
->left
+ x
- v
[0].x
, v
[1].x
- v
[0].x
);
5013 ptr
[x
] = ((( val
& 0xff) << dib
->blue_shift
) |
5014 (((val
>> 8) & 0xff) << dib
->green_shift
) |
5015 (((val
>> 16) & 0xff) << dib
->red_shift
));
5020 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
5022 DWORD val
= gradient_rgb_24( v
, rc
->left
+ x
- v
[0].x
, v
[1].x
- v
[0].x
);
5023 ptr
[x
] = rgb_to_pixel_masks( dib
, val
>> 16, val
>> 8, val
);
5027 for (y
= rc
->top
+ 1; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
5028 memcpy( ptr
+ dib
->stride
/ 4, ptr
, (rc
->right
- rc
->left
) * 4 );
5031 case GRADIENT_FILL_RECT_V
:
5032 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
5034 DWORD val
= gradient_rgb_24( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
5035 if (dib
->red_len
== 8 && dib
->green_len
== 8 && dib
->blue_len
== 8)
5036 val
= ((( val
& 0xff) << dib
->blue_shift
) |
5037 (((val
>> 8) & 0xff) << dib
->green_shift
) |
5038 (((val
>> 16) & 0xff) << dib
->red_shift
));
5040 val
= rgb_to_pixel_masks( dib
, val
>> 16, val
>> 8, val
);
5042 memset_32( ptr
, val
, rc
->right
- rc
->left
);
5046 case GRADIENT_FILL_TRIANGLE
:
5047 if (!(det
= triangle_det( v
))) return FALSE
;
5048 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
5050 triangle_coords( v
, rc
, y
, &left
, &right
);
5052 if (dib
->red_len
== 8 && dib
->green_len
== 8 && dib
->blue_len
== 8)
5053 for (x
= left
; x
< right
; x
++)
5055 DWORD val
= gradient_triangle_24( v
, x
, y
, det
);
5056 ptr
[x
- rc
->left
] = ((( val
& 0xff) << dib
->blue_shift
) |
5057 (((val
>> 8) & 0xff) << dib
->green_shift
) |
5058 (((val
>> 16) & 0xff) << dib
->red_shift
));
5061 for (x
= left
; x
< right
; x
++)
5063 DWORD val
= gradient_triangle_24( v
, x
, y
, det
);
5064 ptr
[x
- rc
->left
] = rgb_to_pixel_masks( dib
, val
>> 16, val
>> 8, val
);
5072 static BOOL
gradient_rect_24( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5074 BYTE
*ptr
= get_pixel_ptr_24( dib
, rc
->left
, rc
->top
);
5075 int x
, y
, left
, right
, det
;
5079 case GRADIENT_FILL_RECT_H
:
5080 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
5082 DWORD val
= gradient_rgb_24( v
, rc
->left
+ x
- v
[0].x
, v
[1].x
- v
[0].x
);
5084 ptr
[x
* 3 + 1] = val
>> 8;
5085 ptr
[x
* 3 + 2] = val
>> 16;
5088 for (y
= rc
->top
+ 1; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5089 memcpy( ptr
+ dib
->stride
, ptr
, (rc
->right
- rc
->left
) * 3 );
5092 case GRADIENT_FILL_RECT_V
:
5093 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5095 DWORD val
= gradient_rgb_24( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
5096 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
5099 ptr
[x
* 3 + 1] = val
>> 8;
5100 ptr
[x
* 3 + 2] = val
>> 16;
5105 case GRADIENT_FILL_TRIANGLE
:
5106 if (!(det
= triangle_det( v
))) return FALSE
;
5107 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5109 triangle_coords( v
, rc
, y
, &left
, &right
);
5110 for (x
= left
; x
< right
; x
++)
5112 DWORD val
= gradient_triangle_24( v
, x
, y
, det
);
5113 ptr
[(x
- rc
->left
) * 3] = val
;
5114 ptr
[(x
- rc
->left
) * 3 + 1] = val
>> 8;
5115 ptr
[(x
- rc
->left
) * 3 + 2] = val
>> 16;
5123 static BOOL
gradient_rect_555( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5125 WORD
*ptr
= get_pixel_ptr_16( dib
, rc
->left
, rc
->top
);
5126 int x
, y
, left
, right
, det
;
5130 case GRADIENT_FILL_RECT_H
:
5131 for (y
= rc
->top
; y
< min( rc
->top
+ 4, rc
->bottom
); y
++, ptr
+= dib
->stride
/ 2)
5132 for (x
= rc
->left
; x
< rc
->right
; x
++)
5133 ptr
[x
- rc
->left
] = gradient_rgb_555( v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
);
5134 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
5135 memcpy( ptr
, ptr
- dib
->stride
* 2, (rc
->right
- rc
->left
) * 2 );
5138 case GRADIENT_FILL_RECT_V
:
5139 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
5142 for (x
= 0; x
< 4; x
++) values
[x
] = gradient_rgb_555( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
);
5143 for (x
= rc
->left
; x
< rc
->right
; x
++) ptr
[x
- rc
->left
] = values
[x
% 4];
5147 case GRADIENT_FILL_TRIANGLE
:
5148 if (!(det
= triangle_det( v
))) return FALSE
;
5149 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
5151 triangle_coords( v
, rc
, y
, &left
, &right
);
5152 for (x
= left
; x
< right
; x
++) ptr
[x
- rc
->left
] = gradient_triangle_555( v
, x
, y
, det
);
5159 static BOOL
gradient_rect_16( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5161 WORD
*ptr
= get_pixel_ptr_16( dib
, rc
->left
, rc
->top
);
5162 int x
, y
, left
, right
, det
;
5166 case GRADIENT_FILL_RECT_H
:
5167 for (y
= rc
->top
; y
< min( rc
->top
+ 4, rc
->bottom
); y
++, ptr
+= dib
->stride
/ 2)
5168 for (x
= rc
->left
; x
< rc
->right
; x
++)
5170 WORD val
= gradient_rgb_555( v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
);
5171 ptr
[x
- rc
->left
] = rgb_to_pixel_masks( dib
,
5172 ((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07),
5173 ((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07),
5174 ((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07) );
5176 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
5177 memcpy( ptr
, ptr
- dib
->stride
* 2, (rc
->right
- rc
->left
) * 2 );
5180 case GRADIENT_FILL_RECT_V
:
5181 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
5184 for (x
= 0; x
< 4; x
++)
5186 WORD val
= gradient_rgb_555( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
);
5187 values
[x
] = rgb_to_pixel_masks( dib
,
5188 ((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07),
5189 ((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07),
5190 ((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07) );
5192 for (x
= rc
->left
; x
< rc
->right
; x
++) ptr
[x
- rc
->left
] = values
[x
% 4];
5196 case GRADIENT_FILL_TRIANGLE
:
5197 if (!(det
= triangle_det( v
))) return FALSE
;
5198 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
5200 triangle_coords( v
, rc
, y
, &left
, &right
);
5201 for (x
= left
; x
< right
; x
++)
5203 WORD val
= gradient_triangle_555( v
, x
, y
, det
);
5204 ptr
[x
- rc
->left
] = rgb_to_pixel_masks( dib
,
5205 ((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07),
5206 ((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07),
5207 ((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07) );
5215 static BOOL
gradient_rect_8( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5217 BYTE
*ptr
= get_pixel_ptr_8( dib
, rc
->left
, rc
->top
);
5218 int x
, y
, left
, right
, det
;
5222 case GRADIENT_FILL_RECT_H
:
5223 for (y
= rc
->top
; y
< min( rc
->top
+ 16, rc
->bottom
); y
++, ptr
+= dib
->stride
)
5224 for (x
= rc
->left
; x
< rc
->right
; x
++)
5225 ptr
[x
- rc
->left
] = gradient_rgb_8( dib
, v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
);
5226 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5227 memcpy( ptr
, ptr
- dib
->stride
* 16, rc
->right
- rc
->left
);
5230 case GRADIENT_FILL_RECT_V
:
5231 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5234 for (x
= 0; x
< 16; x
++)
5235 values
[x
] = gradient_rgb_8( dib
, v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
);
5236 for (x
= rc
->left
; x
< rc
->right
; x
++) ptr
[x
- rc
->left
] = values
[x
% 16];
5240 case GRADIENT_FILL_TRIANGLE
:
5241 if (!(det
= triangle_det( v
))) return FALSE
;
5242 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5244 triangle_coords( v
, rc
, y
, &left
, &right
);
5245 for (x
= left
; x
< right
; x
++) ptr
[x
- rc
->left
] = gradient_triangle_8( dib
, v
, x
, y
, det
);
5252 static BOOL
gradient_rect_4( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5254 BYTE
*ptr
= get_pixel_ptr_4( dib
, rc
->left
, rc
->top
);
5255 int x
, y
, left
, right
, det
, pos
;
5259 case GRADIENT_FILL_RECT_H
:
5260 for (y
= rc
->top
; y
< min( rc
->top
+ 16, rc
->bottom
); y
++, ptr
+= dib
->stride
)
5262 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 1; x
< rc
->right
; x
++, pos
++)
5264 BYTE val
= gradient_rgb_8( dib
, v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
);
5266 ptr
[pos
/ 2] = val
| (ptr
[pos
/ 2] & 0xf0);
5268 ptr
[pos
/ 2] = (val
<< 4) | (ptr
[pos
/ 2] & 0x0f);
5271 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5274 pos
= (dib
->rect
.left
+ rc
->left
) & 1;
5277 ptr
[0] = (ptr
[-16 * dib
->stride
] & 0x0f) | (ptr
[0] & 0xf0);
5281 for (; x
< rc
->right
- 1; x
+= 2, pos
+= 2) ptr
[pos
/ 2] = ptr
[pos
/ 2 - 16 * dib
->stride
];
5283 ptr
[pos
/ 2] = (ptr
[pos
/ 2] & 0x0f) | (ptr
[pos
/ 2 - 16 * dib
->stride
] & 0xf0);
5287 case GRADIENT_FILL_RECT_V
:
5288 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5291 for (x
= 0; x
< 16; x
++)
5292 values
[x
] = gradient_rgb_8( dib
, v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
);
5293 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 1; x
< rc
->right
; x
++, pos
++)
5295 ptr
[pos
/ 2] = values
[x
% 16] | (ptr
[pos
/ 2] & 0xf0);
5297 ptr
[pos
/ 2] = (values
[x
% 16] << 4) | (ptr
[pos
/ 2] & 0x0f);
5301 case GRADIENT_FILL_TRIANGLE
:
5302 if (!(det
= triangle_det( v
))) return FALSE
;
5303 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5305 triangle_coords( v
, rc
, y
, &left
, &right
);
5306 for (x
= left
, pos
= left
- rc
->left
+ ((dib
->rect
.left
+ rc
->left
) & 1); x
< right
; x
++, pos
++)
5308 BYTE val
= gradient_triangle_8( dib
, v
, x
, y
, det
);
5310 ptr
[pos
/ 2] = val
| (ptr
[pos
/ 2] & 0xf0);
5312 ptr
[pos
/ 2] = (val
<< 4) | (ptr
[pos
/ 2] & 0x0f);
5320 static BOOL
gradient_rect_1( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5322 BYTE
*ptr
= get_pixel_ptr_1( dib
, rc
->left
, rc
->top
);
5323 int x
, y
, left
, right
, det
, pos
;
5327 case GRADIENT_FILL_RECT_H
:
5328 for (y
= rc
->top
; y
< min( rc
->top
+ 16, rc
->bottom
); y
++, ptr
+= dib
->stride
)
5330 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 7; x
< rc
->right
; x
++, pos
++)
5332 BYTE val
= gradient_rgb_8( dib
, v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
) ? 0xff : 0;
5333 ptr
[pos
/ 8] = (ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) | (val
& pixel_masks_1
[pos
% 8]);
5336 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5337 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 7; x
< rc
->right
; x
++, pos
++)
5338 ptr
[pos
/ 8] = (ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) |
5339 (ptr
[pos
/ 8 - 16 * dib
->stride
] & pixel_masks_1
[pos
% 8]);
5342 case GRADIENT_FILL_RECT_V
:
5343 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5346 for (x
= 0; x
< 16; x
++)
5347 values
[x
] = gradient_rgb_8( dib
, v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
) ? 0xff : 0;
5348 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 7; x
< rc
->right
; x
++, pos
++)
5349 ptr
[pos
/ 8] = (ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) |
5350 (values
[x
% 16] & pixel_masks_1
[pos
% 8]);
5354 case GRADIENT_FILL_TRIANGLE
:
5355 if (!(det
= triangle_det( v
))) return FALSE
;
5356 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5358 triangle_coords( v
, rc
, y
, &left
, &right
);
5359 for (x
= left
, pos
= left
- rc
->left
+ ((dib
->rect
.left
+ rc
->left
) & 7); x
< right
; x
++, pos
++)
5361 BYTE val
= gradient_triangle_8( dib
, v
, x
, y
, det
) ? 0xff : 0;
5362 ptr
[pos
/ 8] = (ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) | (val
& pixel_masks_1
[pos
% 8]);
5370 static BOOL
gradient_rect_null( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5375 static void mask_rect_32( const dib_info
*dst
, const RECT
*rc
,
5376 const dib_info
*src
, const POINT
*origin
, int rop2
)
5378 DWORD
*dst_start
= get_pixel_ptr_32(dst
, rc
->left
, rc
->top
), dst_colors
[256];
5379 DWORD src_val
, bit_val
, i
, full
, pos
;
5380 int x
, y
, origin_end
= origin
->x
+ rc
->right
- rc
->left
;
5381 const RGBQUAD
*color_table
= get_dib_color_table( src
);
5382 BYTE
*src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
);
5384 if (dst
->funcs
== &funcs_8888
)
5385 for (i
= 0; i
< 2; i
++)
5386 dst_colors
[i
] = color_table
[i
].rgbRed
<< 16 | color_table
[i
].rgbGreen
<< 8 |
5387 color_table
[i
].rgbBlue
;
5389 for (i
= 0; i
< 2; i
++)
5390 dst_colors
[i
] = rgbquad_to_pixel_masks(dst
, color_table
[i
]);
5392 /* Creating a BYTE-sized table so we don't need to mask the lsb of bit_val */
5393 for (i
= 2; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
5394 dst_colors
[i
] = dst_colors
[i
& 1];
5396 /* Special case starting and finishing in same byte, neither on byte boundary */
5397 if ((origin
->x
& 7) && (origin_end
& 7) && (origin
->x
& ~7) == (origin_end
& ~7))
5399 struct rop_codes codes
;
5401 get_rop_codes( rop2
, &codes
);
5403 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
5405 pos
= origin
->x
& 7;
5406 for (x
= 0; x
< rc
->right
- rc
->left
; x
++, pos
++)
5408 bit_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
5409 do_rop_codes_32( dst_start
+ x
, dst_colors
[bit_val
], &codes
);
5411 dst_start
+= dst
->stride
/ 4;
5412 src_start
+= src
->stride
;
5417 full
= ((rc
->right
- rc
->left
) - ((8 - (origin
->x
& 7)) & 7)) / 8;
5419 #define LOOP( op ) \
5420 for (y = rc->top; y < rc->bottom; y++) \
5422 pos = origin->x & 7; \
5423 src_val = src_start[pos / 8]; \
5427 case 1: bit_val = src_val >> 6; op; x++; \
5428 /* fall through */ \
5429 case 2: bit_val = src_val >> 5; op; x++; \
5430 /* fall through */ \
5431 case 3: bit_val = src_val >> 4; op; x++; \
5432 /* fall through */ \
5433 case 4: bit_val = src_val >> 3; op; x++; \
5434 /* fall through */ \
5435 case 5: bit_val = src_val >> 2; op; x++; \
5436 /* fall through */ \
5437 case 6: bit_val = src_val >> 1; op; x++; \
5438 /* fall through */ \
5439 case 7: bit_val = src_val; op; x++; \
5440 pos = (pos + 7) & ~7; \
5442 for (i = 0; i < full; i++, pos += 8) \
5444 src_val = src_start[pos / 8]; \
5445 bit_val = src_val >> 7; op; x++; \
5446 bit_val = src_val >> 6; op; x++; \
5447 bit_val = src_val >> 5; op; x++; \
5448 bit_val = src_val >> 4; op; x++; \
5449 bit_val = src_val >> 3; op; x++; \
5450 bit_val = src_val >> 2; op; x++; \
5451 bit_val = src_val >> 1; op; x++; \
5452 bit_val = src_val; op; x++; \
5454 if (origin_end & 7) \
5456 src_val = src_start[pos / 8]; \
5457 x += (origin_end & 7) - 1; \
5458 switch (origin_end & 7) \
5460 case 7: bit_val = src_val >> 1; op; x--; \
5461 /* fall through */ \
5462 case 6: bit_val = src_val >> 2; op; x--; \
5463 /* fall through */ \
5464 case 5: bit_val = src_val >> 3; op; x--; \
5465 /* fall through */ \
5466 case 4: bit_val = src_val >> 4; op; x--; \
5467 /* fall through */ \
5468 case 3: bit_val = src_val >> 5; op; x--; \
5469 /* fall through */ \
5470 case 2: bit_val = src_val >> 6; op; x--; \
5471 /* fall through */ \
5472 case 1: bit_val = src_val >> 7; op; \
5475 dst_start += dst->stride / 4; \
5476 src_start += src->stride; \
5481 ROPS_ALL( dst_start
[x
], dst_colors
[bit_val
] )
5486 static void mask_rect_24( const dib_info
*dst
, const RECT
*rc
,
5487 const dib_info
*src
, const POINT
*origin
, int rop2
)
5489 BYTE
*dst_start
= get_pixel_ptr_24(dst
, rc
->left
, rc
->top
);
5490 DWORD src_val
, bit_val
, i
, full
, pos
;
5491 struct rop_codes codes
;
5492 int x
, y
, origin_end
= origin
->x
+ rc
->right
- rc
->left
;
5493 const RGBQUAD
*color_table
= get_dib_color_table( src
);
5494 BYTE
*src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
);
5497 get_rop_codes( rop2
, &codes
);
5499 /* Special case starting and finishing in same byte, neither on byte boundary */
5500 if ((origin
->x
& 7) && (origin_end
& 7) && (origin
->x
& ~7) == (origin_end
& ~7))
5502 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
5504 pos
= origin
->x
& 7;
5505 for (x
= 0; x
< rc
->right
- rc
->left
; x
++, pos
++)
5507 bit_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
5508 rgb
= color_table
[bit_val
];
5509 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5510 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5511 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5513 dst_start
+= dst
->stride
;
5514 src_start
+= src
->stride
;
5519 full
= ((rc
->right
- rc
->left
) - ((8 - (origin
->x
& 7)) & 7)) / 8;
5521 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
5523 pos
= origin
->x
& 7;
5524 src_val
= src_start
[pos
/ 8];
5530 bit_val
= (src_val
>> 6) & 1;
5531 rgb
= color_table
[bit_val
];
5532 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5533 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5534 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5538 bit_val
= (src_val
>> 5) & 1;
5539 rgb
= color_table
[bit_val
];
5540 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5541 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5542 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5546 bit_val
= (src_val
>> 4) & 1;
5547 rgb
= color_table
[bit_val
];
5548 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5549 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5550 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5554 bit_val
= (src_val
>> 3) & 1;
5555 rgb
= color_table
[bit_val
];
5556 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5557 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5558 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5562 bit_val
= (src_val
>> 2) & 1;
5563 rgb
= color_table
[bit_val
];
5564 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5565 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5566 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5570 bit_val
= (src_val
>> 1) & 1;
5571 rgb
= color_table
[bit_val
];
5572 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5573 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5574 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5578 bit_val
= src_val
& 1;
5579 rgb
= color_table
[bit_val
];
5580 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5581 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5582 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5584 pos
= (pos
+ 7) & ~7;
5587 for (i
= 0; i
< full
; i
++, pos
+= 8)
5589 src_val
= src_start
[pos
/ 8];
5591 bit_val
= (src_val
>> 7) & 1;
5592 rgb
= color_table
[bit_val
];
5593 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5594 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5595 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5598 bit_val
= (src_val
>> 6) & 1;
5599 rgb
= color_table
[bit_val
];
5600 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5601 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5602 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5605 bit_val
= (src_val
>> 5) & 1;
5606 rgb
= color_table
[bit_val
];
5607 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5608 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5609 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5612 bit_val
= (src_val
>> 4) & 1;
5613 rgb
= color_table
[bit_val
];
5614 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5615 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5616 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5619 bit_val
= (src_val
>> 3) & 1;
5620 rgb
= color_table
[bit_val
];
5621 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5622 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5623 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5626 bit_val
= (src_val
>> 2) & 1;
5627 rgb
= color_table
[bit_val
];
5628 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5629 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5630 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5633 bit_val
= (src_val
>> 1) & 1;
5634 rgb
= color_table
[bit_val
];
5635 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5636 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5637 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5640 bit_val
= src_val
& 1;
5641 rgb
= color_table
[bit_val
];
5642 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5643 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5644 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5650 src_val
= src_start
[pos
/ 8];
5651 x
+= (origin_end
& 7) - 1;
5653 switch (origin_end
& 7)
5656 bit_val
= (src_val
>> 1) & 1;
5657 rgb
= color_table
[bit_val
];
5658 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5659 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5660 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5664 bit_val
= (src_val
>> 2) & 1;
5665 rgb
= color_table
[bit_val
];
5666 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5667 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5668 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5672 bit_val
= (src_val
>> 3) & 1;
5673 rgb
= color_table
[bit_val
];
5674 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5675 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5676 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5680 bit_val
= (src_val
>> 4) & 1;
5681 rgb
= color_table
[bit_val
];
5682 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5683 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5684 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5688 bit_val
= (src_val
>> 5) & 1;
5689 rgb
= color_table
[bit_val
];
5690 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5691 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5692 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5696 bit_val
= (src_val
>> 6) & 1;
5697 rgb
= color_table
[bit_val
];
5698 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5699 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5700 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5704 bit_val
= (src_val
>> 7) & 1;
5705 rgb
= color_table
[bit_val
];
5706 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5707 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5708 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5712 dst_start
+= dst
->stride
;
5713 src_start
+= src
->stride
;
5717 static void mask_rect_16( const dib_info
*dst
, const RECT
*rc
,
5718 const dib_info
*src
, const POINT
*origin
, int rop2
)
5720 WORD
*dst_start
= get_pixel_ptr_16(dst
, rc
->left
, rc
->top
), dst_colors
[2];
5721 DWORD src_val
, bit_val
, i
, full
, pos
;
5722 struct rop_codes codes
;
5723 int x
, y
, origin_end
= origin
->x
+ rc
->right
- rc
->left
;
5724 const RGBQUAD
*color_table
= get_dib_color_table( src
);
5725 BYTE
*src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
);
5727 get_rop_codes( rop2
, &codes
);
5729 if (dst
->funcs
== &funcs_555
)
5730 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
5731 dst_colors
[i
] = ((color_table
[i
].rgbRed
<< 7) & 0x7c00) |
5732 ((color_table
[i
].rgbGreen
<< 2) & 0x03e0) |
5733 ((color_table
[i
].rgbBlue
>> 3) & 0x001f);
5735 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
5736 dst_colors
[i
] = rgbquad_to_pixel_masks(dst
, color_table
[i
]);
5738 /* Special case starting and finishing in same byte, neither on byte boundary */
5739 if ((origin
->x
& 7) && (origin_end
& 7) && (origin
->x
& ~7) == (origin_end
& ~7))
5741 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
5743 pos
= origin
->x
& 7;
5744 for (x
= 0; x
< rc
->right
- rc
->left
; x
++, pos
++)
5746 bit_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
5747 do_rop_codes_16( dst_start
+ x
, dst_colors
[bit_val
], &codes
);
5749 dst_start
+= dst
->stride
/ 2;
5750 src_start
+= src
->stride
;
5755 full
= ((rc
->right
- rc
->left
) - ((8 - (origin
->x
& 7)) & 7)) / 8;
5757 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
5759 pos
= origin
->x
& 7;
5760 src_val
= src_start
[pos
/ 8];
5766 bit_val
= (src_val
>> 6) & 1;
5767 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5770 bit_val
= (src_val
>> 5) & 1;
5771 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5774 bit_val
= (src_val
>> 4) & 1;
5775 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5778 bit_val
= (src_val
>> 3) & 1;
5779 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5782 bit_val
= (src_val
>> 2) & 1;
5783 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5786 bit_val
= (src_val
>> 1) & 1;
5787 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5790 bit_val
= src_val
& 1;
5791 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5792 pos
= (pos
+ 7) & ~7;
5795 for (i
= 0; i
< full
; i
++, pos
+= 8)
5797 src_val
= src_start
[pos
/ 8];
5799 bit_val
= (src_val
>> 7) & 1;
5800 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5801 bit_val
= (src_val
>> 6) & 1;
5802 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5803 bit_val
= (src_val
>> 5) & 1;
5804 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5805 bit_val
= (src_val
>> 4) & 1;
5806 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5807 bit_val
= (src_val
>> 3) & 1;
5808 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5809 bit_val
= (src_val
>> 2) & 1;
5810 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5811 bit_val
= (src_val
>> 1) & 1;
5812 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5813 bit_val
= src_val
& 1;
5814 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5819 src_val
= src_start
[pos
/ 8];
5820 x
+= (origin_end
& 7) - 1;
5822 switch (origin_end
& 7)
5825 bit_val
= (src_val
>> 1) & 1;
5826 do_rop_codes_16( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5829 bit_val
= (src_val
>> 2) & 1;
5830 do_rop_codes_16( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5833 bit_val
= (src_val
>> 3) & 1;
5834 do_rop_codes_16( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5837 bit_val
= (src_val
>> 4) & 1;
5838 do_rop_codes_16( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5841 bit_val
= (src_val
>> 5) & 1;
5842 do_rop_codes_16( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5845 bit_val
= (src_val
>> 6) & 1;
5846 do_rop_codes_16( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5849 bit_val
= (src_val
>> 7) & 1;
5850 do_rop_codes_16( dst_start
+ x
, dst_colors
[bit_val
], &codes
);
5854 dst_start
+= dst
->stride
/ 2;
5855 src_start
+= src
->stride
;
5859 static void mask_rect_8( const dib_info
*dst
, const RECT
*rc
,
5860 const dib_info
*src
, const POINT
*origin
, int rop2
)
5862 BYTE
*dst_start
= get_pixel_ptr_8(dst
, rc
->left
, rc
->top
), dst_colors
[2];
5863 DWORD src_val
, bit_val
, i
, full
, pos
;
5864 struct rop_codes codes
;
5865 int x
, y
, origin_end
= origin
->x
+ rc
->right
- rc
->left
;
5866 const RGBQUAD
*color_table
= get_dib_color_table( src
);
5867 BYTE
*src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
);
5869 get_rop_codes( rop2
, &codes
);
5871 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
5872 dst_colors
[i
] = FILTER_DIBINDEX(color_table
[i
], rgbquad_to_pixel_colortable(dst
, color_table
[i
]));
5874 /* Special case starting and finishing in same byte, neither on byte boundary */
5875 if ((origin
->x
& 7) && (origin_end
& 7) && (origin
->x
& ~7) == (origin_end
& ~7))
5877 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
5879 pos
= origin
->x
& 7;
5880 for (x
= 0; x
< rc
->right
- rc
->left
; x
++, pos
++)
5882 bit_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
5883 do_rop_codes_8( dst_start
+ x
, dst_colors
[bit_val
], &codes
);
5885 dst_start
+= dst
->stride
;
5886 src_start
+= src
->stride
;
5891 full
= ((rc
->right
- rc
->left
) - ((8 - (origin
->x
& 7)) & 7)) / 8;
5893 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
5895 pos
= origin
->x
& 7;
5896 src_val
= src_start
[pos
/ 8];
5902 bit_val
= (src_val
>> 6) & 1;
5903 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5906 bit_val
= (src_val
>> 5) & 1;
5907 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5910 bit_val
= (src_val
>> 4) & 1;
5911 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5914 bit_val
= (src_val
>> 3) & 1;
5915 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5918 bit_val
= (src_val
>> 2) & 1;
5919 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5922 bit_val
= (src_val
>> 1) & 1;
5923 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5926 bit_val
= src_val
& 1;
5927 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5928 pos
= (pos
+ 7) & ~7;
5931 for (i
= 0; i
< full
; i
++, pos
+= 8)
5933 src_val
= src_start
[pos
/ 8];
5935 bit_val
= (src_val
>> 7) & 1;
5936 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5937 bit_val
= (src_val
>> 6) & 1;
5938 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5939 bit_val
= (src_val
>> 5) & 1;
5940 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5941 bit_val
= (src_val
>> 4) & 1;
5942 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5943 bit_val
= (src_val
>> 3) & 1;
5944 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5945 bit_val
= (src_val
>> 2) & 1;
5946 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5947 bit_val
= (src_val
>> 1) & 1;
5948 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5949 bit_val
= src_val
& 1;
5950 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5955 src_val
= src_start
[pos
/ 8];
5956 x
+= (origin_end
& 7) - 1;
5958 switch (origin_end
& 7)
5961 bit_val
= (src_val
>> 1) & 1;
5962 do_rop_codes_8( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5965 bit_val
= (src_val
>> 2) & 1;
5966 do_rop_codes_8( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5969 bit_val
= (src_val
>> 3) & 1;
5970 do_rop_codes_8( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5973 bit_val
= (src_val
>> 4) & 1;
5974 do_rop_codes_8( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5977 bit_val
= (src_val
>> 5) & 1;
5978 do_rop_codes_8( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5981 bit_val
= (src_val
>> 6) & 1;
5982 do_rop_codes_8( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5985 bit_val
= (src_val
>> 7) & 1;
5986 do_rop_codes_8( dst_start
+ x
, dst_colors
[bit_val
], &codes
);
5990 dst_start
+= dst
->stride
;
5991 src_start
+= src
->stride
;
5995 static void mask_rect_4( const dib_info
*dst
, const RECT
*rc
,
5996 const dib_info
*src
, const POINT
*origin
, int rop2
)
5998 BYTE
*dst_start
= get_pixel_ptr_4(dst
, rc
->left
, rc
->top
), dst_colors
[2], *dst_ptr
;
5999 DWORD bit_val
, i
, pos
;
6000 struct rop_codes codes
;
6002 int left
= dst
->rect
.left
+ rc
->left
;
6003 int right
= dst
->rect
.left
+ rc
->right
;
6004 const RGBQUAD
*color_table
= get_dib_color_table( src
);
6005 BYTE
*src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
);
6007 get_rop_codes( rop2
, &codes
);
6009 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
6011 dst_colors
[i
] = FILTER_DIBINDEX(color_table
[i
],rgbquad_to_pixel_colortable(dst
, color_table
[i
]));
6012 /* Set high nibble to match so we don't need to shift it later. */
6013 dst_colors
[i
] |= dst_colors
[i
] << 4;
6016 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
6018 pos
= origin
->x
& 7;
6020 for (x
= left
, dst_ptr
= dst_start
; x
< right
; x
++, pos
++)
6022 bit_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
6024 do_rop_codes_mask_8( dst_ptr
++, dst_colors
[bit_val
], &codes
, 0x0f );
6026 do_rop_codes_mask_8( dst_ptr
, dst_colors
[bit_val
], &codes
, 0xf0 );
6028 dst_start
+= dst
->stride
;
6029 src_start
+= src
->stride
;
6033 static void mask_rect_null( const dib_info
*dst
, const RECT
*rc
,
6034 const dib_info
*src
, const POINT
*origin
, int rop2
)
6038 static inline BYTE
aa_color( BYTE dst
, BYTE text
, BYTE min_comp
, BYTE max_comp
)
6040 if (dst
== text
) return dst
;
6044 DWORD diff
= dst
- text
;
6045 DWORD range
= max_comp
- text
;
6046 dst
= text
+ (diff
* range
) / (0xff - text
);
6051 DWORD diff
= text
- dst
;
6052 DWORD range
= text
- min_comp
;
6053 dst
= text
- (diff
* range
) / text
;
6058 static inline DWORD
aa_rgb( BYTE r_dst
, BYTE g_dst
, BYTE b_dst
, DWORD text
, const struct intensity_range
*range
)
6060 return (aa_color( b_dst
, text
, range
->b_min
, range
->b_max
) |
6061 aa_color( g_dst
, text
>> 8, range
->g_min
, range
->g_max
) << 8 |
6062 aa_color( r_dst
, text
>> 16, range
->r_min
, range
->r_max
) << 16);
6065 static void draw_glyph_8888( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6066 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6068 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
6069 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6072 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6074 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6076 if (glyph_ptr
[x
] <= 1) continue;
6077 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
6078 dst_ptr
[x
] = aa_rgb( dst_ptr
[x
] >> 16, dst_ptr
[x
] >> 8, dst_ptr
[x
], text_pixel
, ranges
+ glyph_ptr
[x
] );
6080 dst_ptr
+= dib
->stride
/ 4;
6081 glyph_ptr
+= glyph
->stride
;
6085 static void draw_glyph_32( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6086 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6088 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
6089 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6093 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
6094 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
6095 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
6097 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6099 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6101 if (glyph_ptr
[x
] <= 1) continue;
6102 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
6103 val
= aa_rgb( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
6104 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
6105 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
6106 text
, ranges
+ glyph_ptr
[x
] );
6107 dst_ptr
[x
] = rgb_to_pixel_masks( dib
, val
>> 16, val
>> 8, val
);
6109 dst_ptr
+= dib
->stride
/ 4;
6110 glyph_ptr
+= glyph
->stride
;
6114 static void draw_glyph_24( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6115 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6117 BYTE
*dst_ptr
= get_pixel_ptr_24( dib
, rect
->left
, rect
->top
);
6118 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6122 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6124 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6126 if (glyph_ptr
[x
] <= 1) continue;
6127 if (glyph_ptr
[x
] >= 16)
6130 val
= aa_rgb( dst_ptr
[x
* 3 + 2], dst_ptr
[x
* 3 + 1], dst_ptr
[x
* 3],
6131 text_pixel
, ranges
+ glyph_ptr
[x
] );
6132 dst_ptr
[x
* 3] = val
;
6133 dst_ptr
[x
* 3 + 1] = val
>> 8;
6134 dst_ptr
[x
* 3 + 2] = val
>> 16;
6136 dst_ptr
+= dib
->stride
;
6137 glyph_ptr
+= glyph
->stride
;
6141 static void draw_glyph_555( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6142 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6144 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
6145 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6149 text
= ((text_pixel
<< 9) & 0xf80000) | ((text_pixel
<< 4) & 0x070000) |
6150 ((text_pixel
<< 6) & 0x00f800) | ((text_pixel
<< 1) & 0x000700) |
6151 ((text_pixel
<< 3) & 0x0000f8) | ((text_pixel
>> 2) & 0x000007);
6153 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6155 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6157 if (glyph_ptr
[x
] <= 1) continue;
6158 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
6159 val
= aa_rgb( ((dst_ptr
[x
] >> 7) & 0xf8) | ((dst_ptr
[x
] >> 12) & 0x07),
6160 ((dst_ptr
[x
] >> 2) & 0xf8) | ((dst_ptr
[x
] >> 7) & 0x07),
6161 ((dst_ptr
[x
] << 3) & 0xf8) | ((dst_ptr
[x
] >> 2) & 0x07),
6162 text
, ranges
+ glyph_ptr
[x
] );
6163 dst_ptr
[x
] = ((val
>> 9) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 3) & 0x001f);
6165 dst_ptr
+= dib
->stride
/ 2;
6166 glyph_ptr
+= glyph
->stride
;
6170 static void draw_glyph_16( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6171 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6173 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
6174 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6178 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
6179 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
6180 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
6182 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6184 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6186 if (glyph_ptr
[x
] <= 1) continue;
6187 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
6188 val
= aa_rgb( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
6189 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
6190 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
6191 text
, ranges
+ glyph_ptr
[x
] );
6192 dst_ptr
[x
] = rgb_to_pixel_masks( dib
, val
>> 16, val
>> 8, val
);
6194 dst_ptr
+= dib
->stride
/ 2;
6195 glyph_ptr
+= glyph
->stride
;
6199 static void draw_glyph_8( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6200 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6202 BYTE
*dst_ptr
= get_pixel_ptr_8( dib
, rect
->left
, rect
->top
);
6203 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6206 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6208 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6210 /* no antialiasing, glyph should only contain 0 or 16. */
6211 if (glyph_ptr
[x
] >= 16)
6212 dst_ptr
[x
] = text_pixel
;
6214 dst_ptr
+= dib
->stride
;
6215 glyph_ptr
+= glyph
->stride
;
6219 static void draw_glyph_4( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6220 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6222 BYTE
*dst_ptr
= get_pixel_ptr_4( dib
, rect
->left
, rect
->top
);
6223 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6226 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6228 for (x
= 0, pos
= (dib
->rect
.left
+ rect
->left
) & 1; x
< rect
->right
- rect
->left
; x
++, pos
++)
6230 /* no antialiasing, glyph should only contain 0 or 16. */
6231 if (glyph_ptr
[x
] >= 16)
6234 dst_ptr
[pos
/ 2] = text_pixel
| (dst_ptr
[pos
/ 2] & 0xf0);
6236 dst_ptr
[pos
/ 2] = (text_pixel
<< 4) | (dst_ptr
[pos
/ 2] & 0x0f);
6239 dst_ptr
+= dib
->stride
;
6240 glyph_ptr
+= glyph
->stride
;
6244 static void draw_glyph_1( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6245 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6247 BYTE
*dst_ptr
= get_pixel_ptr_1( dib
, rect
->left
, rect
->top
);
6248 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6250 BYTE text
= (text_pixel
& 1) ? 0xff : 0;
6252 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6254 for (x
= 0, pos
= (dib
->rect
.left
+ rect
->left
) & 7; x
< rect
->right
- rect
->left
; x
++, pos
++)
6256 /* no antialiasing, glyph should only contain 0 or 16. */
6257 if (glyph_ptr
[x
] >= 16)
6258 dst_ptr
[pos
/ 8] = (dst_ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) |
6259 (text
& pixel_masks_1
[pos
% 8]);
6261 dst_ptr
+= dib
->stride
;
6262 glyph_ptr
+= glyph
->stride
;
6266 static void draw_glyph_null( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6267 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6272 static inline DWORD
blend_subpixel( BYTE r
, BYTE g
, BYTE b
, DWORD text
, DWORD alpha
)
6274 return blend_color( r
, text
>> 16, (BYTE
)(alpha
>> 16) ) << 16 |
6275 blend_color( g
, text
>> 8, (BYTE
)(alpha
>> 8) ) << 8 |
6276 blend_color( b
, text
, (BYTE
) alpha
);
6279 static void draw_subpixel_glyph_8888( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6280 const POINT
*origin
, DWORD text_pixel
)
6282 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
6283 const DWORD
*glyph_ptr
= get_pixel_ptr_32( glyph
, origin
->x
, origin
->y
);
6286 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6288 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6290 if (glyph_ptr
[x
] == 0) continue;
6291 dst_ptr
[x
] = blend_subpixel( dst_ptr
[x
] >> 16, dst_ptr
[x
] >> 8, dst_ptr
[x
], text_pixel
, glyph_ptr
[x
] );
6293 dst_ptr
+= dib
->stride
/ 4;
6294 glyph_ptr
+= glyph
->stride
/ 4;
6298 static void draw_subpixel_glyph_32( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6299 const POINT
*origin
, DWORD text_pixel
)
6301 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
6302 const DWORD
*glyph_ptr
= get_pixel_ptr_32( glyph
, origin
->x
, origin
->y
);
6306 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
6307 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
6308 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
6310 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6312 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6314 if (glyph_ptr
[x
] == 0) continue;
6315 val
= blend_subpixel( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
6316 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
6317 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
6318 text
, glyph_ptr
[x
] );
6319 dst_ptr
[x
] = rgb_to_pixel_masks( dib
, val
>> 16, val
>> 8, val
);
6321 dst_ptr
+= dib
->stride
/ 4;
6322 glyph_ptr
+= glyph
->stride
/ 4;
6326 static void draw_subpixel_glyph_24( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6327 const POINT
*origin
, DWORD text_pixel
)
6329 BYTE
*dst_ptr
= get_pixel_ptr_24( dib
, rect
->left
, rect
->top
);
6330 const DWORD
*glyph_ptr
= get_pixel_ptr_32( glyph
, origin
->x
, origin
->y
);
6334 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6336 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6338 if (glyph_ptr
[x
] == 0) continue;
6339 val
= blend_subpixel( dst_ptr
[x
* 3 + 2], dst_ptr
[x
* 3 + 1], dst_ptr
[x
* 3],
6340 text_pixel
, glyph_ptr
[x
] );
6341 dst_ptr
[x
* 3] = val
;
6342 dst_ptr
[x
* 3 + 1] = val
>> 8;
6343 dst_ptr
[x
* 3 + 2] = val
>> 16;
6345 dst_ptr
+= dib
->stride
;
6346 glyph_ptr
+= glyph
->stride
/ 4;
6350 static void draw_subpixel_glyph_555( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6351 const POINT
*origin
, DWORD text_pixel
)
6353 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
6354 const DWORD
*glyph_ptr
= get_pixel_ptr_32( glyph
, origin
->x
, origin
->y
);
6358 text
= ((text_pixel
<< 9) & 0xf80000) | ((text_pixel
<< 4) & 0x070000) |
6359 ((text_pixel
<< 6) & 0x00f800) | ((text_pixel
<< 1) & 0x000700) |
6360 ((text_pixel
<< 3) & 0x0000f8) | ((text_pixel
>> 2) & 0x000007);
6362 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6364 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6366 if (glyph_ptr
[x
] == 0) continue;
6367 val
= blend_subpixel( ((dst_ptr
[x
] >> 7) & 0xf8) | ((dst_ptr
[x
] >> 12) & 0x07),
6368 ((dst_ptr
[x
] >> 2) & 0xf8) | ((dst_ptr
[x
] >> 7) & 0x07),
6369 ((dst_ptr
[x
] << 3) & 0xf8) | ((dst_ptr
[x
] >> 2) & 0x07),
6370 text
, glyph_ptr
[x
] );
6371 dst_ptr
[x
] = ((val
>> 9) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 3) & 0x001f);
6373 dst_ptr
+= dib
->stride
/ 2;
6374 glyph_ptr
+= glyph
->stride
/ 4;
6378 static void draw_subpixel_glyph_16( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6379 const POINT
*origin
, DWORD text_pixel
)
6381 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
6382 const DWORD
*glyph_ptr
= get_pixel_ptr_32( glyph
, origin
->x
, origin
->y
);
6386 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
6387 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
6388 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
6390 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6392 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6394 if (glyph_ptr
[x
] == 0) continue;
6395 val
= blend_subpixel( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
6396 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
6397 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
6398 text
, glyph_ptr
[x
] );
6399 dst_ptr
[x
] = rgb_to_pixel_masks( dib
, val
>> 16, val
>> 8, val
);
6401 dst_ptr
+= dib
->stride
/ 2;
6402 glyph_ptr
+= glyph
->stride
/ 4;
6406 static void draw_subpixel_glyph_null( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6407 const POINT
*origin
, DWORD text_pixel
)
6412 static void create_rop_masks_32(const dib_info
*dib
, const BYTE
*hatch_ptr
,
6413 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
6415 DWORD
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6418 /* masks are always 8x8 */
6419 assert( dib
->width
== 8 );
6420 assert( dib
->height
== 8 );
6422 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
6424 for(x
= 0; x
< 8; x
++)
6426 if(*hatch_ptr
& pixel_masks_1
[x
])
6428 and_bits
[x
] = fg
->and;
6429 xor_bits
[x
] = fg
->xor;
6433 and_bits
[x
] = bg
->and;
6434 xor_bits
[x
] = bg
->xor;
6437 and_bits
+= dib
->stride
/ 4;
6438 xor_bits
+= dib
->stride
/ 4;
6442 static void create_rop_masks_24(const dib_info
*dib
, const BYTE
*hatch_ptr
,
6443 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
6445 DWORD mask_start
= 0, mask_offset
;
6446 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6449 /* masks are always 8x8 */
6450 assert( dib
->width
== 8 );
6451 assert( dib
->height
== 8 );
6453 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
6455 mask_offset
= mask_start
;
6456 for(x
= 0; x
< 8; x
++)
6458 if(*hatch_ptr
& pixel_masks_1
[x
])
6460 and_bits
[mask_offset
] = fg
->and & 0xff;
6461 xor_bits
[mask_offset
++] = fg
->xor & 0xff;
6462 and_bits
[mask_offset
] = (fg
->and >> 8) & 0xff;
6463 xor_bits
[mask_offset
++] = (fg
->xor >> 8) & 0xff;
6464 and_bits
[mask_offset
] = (fg
->and >> 16) & 0xff;
6465 xor_bits
[mask_offset
++] = (fg
->xor >> 16) & 0xff;
6469 and_bits
[mask_offset
] = bg
->and & 0xff;
6470 xor_bits
[mask_offset
++] = bg
->xor & 0xff;
6471 and_bits
[mask_offset
] = (bg
->and >> 8) & 0xff;
6472 xor_bits
[mask_offset
++] = (bg
->xor >> 8) & 0xff;
6473 and_bits
[mask_offset
] = (bg
->and >> 16) & 0xff;
6474 xor_bits
[mask_offset
++] = (bg
->xor >> 16) & 0xff;
6477 mask_start
+= dib
->stride
;
6481 static void create_rop_masks_16(const dib_info
*dib
, const BYTE
*hatch_ptr
,
6482 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
6484 WORD
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6487 /* masks are always 8x8 */
6488 assert( dib
->width
== 8 );
6489 assert( dib
->height
== 8 );
6491 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
6493 for(x
= 0; x
< 8; x
++)
6495 if(*hatch_ptr
& pixel_masks_1
[x
])
6497 and_bits
[x
] = fg
->and;
6498 xor_bits
[x
] = fg
->xor;
6502 and_bits
[x
] = bg
->and;
6503 xor_bits
[x
] = bg
->xor;
6506 and_bits
+= dib
->stride
/ 2;
6507 xor_bits
+= dib
->stride
/ 2;
6511 static void create_rop_masks_8(const dib_info
*dib
, const BYTE
*hatch_ptr
,
6512 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
6514 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6517 /* masks are always 8x8 */
6518 assert( dib
->width
== 8 );
6519 assert( dib
->height
== 8 );
6521 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
6523 for(x
= 0; x
< 8; x
++)
6525 if(*hatch_ptr
& pixel_masks_1
[x
])
6527 and_bits
[x
] = fg
->and;
6528 xor_bits
[x
] = fg
->xor;
6532 and_bits
[x
] = bg
->and;
6533 xor_bits
[x
] = bg
->xor;
6536 and_bits
+= dib
->stride
;
6537 xor_bits
+= dib
->stride
;
6541 static void create_rop_masks_4(const dib_info
*dib
, const BYTE
*hatch_ptr
,
6542 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
6545 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6546 const rop_mask
*rop_mask
;
6549 /* masks are always 8x8 */
6550 assert( dib
->width
== 8 );
6551 assert( dib
->height
== 8 );
6553 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
6555 for(x
= mask_offset
= 0; x
< 8; x
++)
6557 if(*hatch_ptr
& pixel_masks_1
[x
])
6564 and_bits
[mask_offset
] |= (rop_mask
->and & 0x0f);
6565 xor_bits
[mask_offset
] |= (rop_mask
->xor & 0x0f);
6570 and_bits
[mask_offset
] = (rop_mask
->and << 4) & 0xf0;
6571 xor_bits
[mask_offset
] = (rop_mask
->xor << 4) & 0xf0;
6574 and_bits
+= dib
->stride
;
6575 xor_bits
+= dib
->stride
;
6579 static void create_rop_masks_1(const dib_info
*dib
, const BYTE
*hatch_ptr
,
6580 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
6582 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6586 /* masks are always 8x8 */
6587 assert( dib
->width
== 8 );
6588 assert( dib
->height
== 8 );
6590 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
6592 *and_bits
= *xor_bits
= 0;
6593 for(x
= 0; x
< 8; x
++)
6595 if(*hatch_ptr
& pixel_masks_1
[x
])
6597 rop_mask
.and = (fg
->and & 1) ? 0xff : 0;
6598 rop_mask
.xor = (fg
->xor & 1) ? 0xff : 0;
6602 rop_mask
.and = (bg
->and & 1) ? 0xff : 0;
6603 rop_mask
.xor = (bg
->xor & 1) ? 0xff : 0;
6605 *and_bits
|= (rop_mask
.and & pixel_masks_1
[x
]);
6606 *xor_bits
|= (rop_mask
.xor & pixel_masks_1
[x
]);
6608 and_bits
+= dib
->stride
;
6609 xor_bits
+= dib
->stride
;
6613 static void create_rop_masks_null(const dib_info
*dib
, const BYTE
*hatch_ptr
,
6614 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
6618 static void create_dither_masks_8(const dib_info
*dib
, int rop2
, COLORREF color
, rop_mask_bits
*bits
)
6620 /* mapping between RGB triples and the default color table */
6621 static const BYTE mapping
[27] =
6623 0, /* 000000 -> 000000 */
6624 4, /* 00007f -> 000080 */
6625 252, /* 0000ff -> 0000ff */
6626 2, /* 007f00 -> 008000 */
6627 6, /* 007f7f -> 008080 */
6628 224, /* 007fff -> 0080c0 */
6629 250, /* 00ff00 -> 00ff00 */
6630 184, /* 00ff7f -> 00e080 */
6631 254, /* 00ffff -> 00ffff */
6632 1, /* 7f0000 -> 800000 */
6633 5, /* 7f007f -> 800080 */
6634 196, /* 7f00ff -> 8000c0 */
6635 3, /* 7f7f00 -> 808000 */
6636 248, /* 7f7f7f -> 808080 */
6637 228, /* 7f7fff -> 8080c0 */
6638 60, /* 7fff00 -> 80e000 */
6639 188, /* 7fff7f -> 80e080 */
6640 244, /* 7fffff -> 80c0c0 */
6641 249, /* ff0000 -> ff0000 */
6642 135, /* ff007f -> e00080 */
6643 253, /* ff00ff -> ff00ff */
6644 39, /* ff7f00 -> e08000 */
6645 167, /* ff7f7f -> e08080 */
6646 231, /* ff7fff -> e080c0 */
6647 251, /* ffff00 -> ffff00 */
6648 191, /* ffff7f -> e0e080 */
6649 255 /* ffffff -> ffffff */
6652 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6653 struct rop_codes codes
;
6656 /* masks are always 8x8 */
6657 assert( dib
->width
== 8 );
6658 assert( dib
->height
== 8 );
6660 get_rop_codes( rop2
, &codes
);
6662 for (y
= 0; y
< 8; y
++)
6664 for (x
= 0; x
< 8; x
++)
6666 DWORD r
= ((GetRValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
6667 DWORD g
= ((GetGValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
6668 DWORD b
= ((GetBValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
6669 DWORD pixel
= mapping
[r
* 9 + g
* 3 + b
];
6670 and_bits
[x
] = (pixel
& codes
.a1
) ^ codes
.a2
;
6671 xor_bits
[x
] = (pixel
& codes
.x1
) ^ codes
.x2
;
6673 and_bits
+= dib
->stride
;
6674 xor_bits
+= dib
->stride
;
6678 static void create_dither_masks_4(const dib_info
*dib
, int rop2
, COLORREF color
, rop_mask_bits
*bits
)
6680 /* mapping between RGB triples and the default color table */
6681 static const BYTE mapping
[27] =
6683 0, /* 000000 -> 000000 */
6684 4, /* 00007f -> 000080 */
6685 12, /* 0000ff -> 0000ff */
6686 2, /* 007f00 -> 008000 */
6687 6, /* 007f7f -> 008080 */
6688 6, /* 007fff -> 008080 */
6689 10, /* 00ff00 -> 00ff00 */
6690 6, /* 00ff7f -> 008080 */
6691 14, /* 00ffff -> 00ffff */
6692 1, /* 7f0000 -> 800000 */
6693 5, /* 7f007f -> 800080 */
6694 5, /* 7f00ff -> 800080 */
6695 3, /* 7f7f00 -> 808000 */
6696 7, /* 7f7f7f -> 808080 */
6697 8, /* 7f7fff -> c0c0c0 */
6698 3, /* 7fff00 -> 808000 */
6699 8, /* 7fff7f -> c0c0c0 */
6700 8, /* 7fffff -> c0c0c0 */
6701 9, /* ff0000 -> ff0000 */
6702 5, /* ff007f -> 800080 */
6703 13, /* ff00ff -> ff00ff */
6704 3, /* ff7f00 -> 808000 */
6705 8, /* ff7f7f -> c0c0c0 */
6706 8, /* ff7fff -> c0c0c0 */
6707 11, /* ffff00 -> ffff00 */
6708 8, /* ffff7f -> c0c0c0 */
6709 15 /* ffffff -> ffffff */
6712 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6713 struct rop_codes codes
;
6716 /* masks are always 8x8 */
6717 assert( dib
->width
== 8 );
6718 assert( dib
->height
== 8 );
6720 get_rop_codes( rop2
, &codes
);
6722 for (y
= 0; y
< 8; y
++)
6724 for (x
= 0; x
< 8; x
++)
6726 DWORD r
= ((GetRValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
6727 DWORD g
= ((GetGValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
6728 DWORD b
= ((GetBValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
6729 DWORD pixel
= mapping
[r
* 9 + g
* 3 + b
];
6732 and_bits
[x
/ 2] |= (pixel
& codes
.a1
) ^ codes
.a2
;
6733 xor_bits
[x
/ 2] |= (pixel
& codes
.x1
) ^ codes
.x2
;
6737 and_bits
[x
/ 2] = ((pixel
& codes
.a1
) ^ codes
.a2
) << 4;
6738 xor_bits
[x
/ 2] = ((pixel
& codes
.x1
) ^ codes
.x2
) << 4;
6741 and_bits
+= dib
->stride
;
6742 xor_bits
+= dib
->stride
;
6746 static void create_dither_masks_1(const dib_info
*dib
, int rop2
, COLORREF color
, rop_mask_bits
*bits
)
6748 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6749 struct rop_codes codes
;
6751 int x
, y
, grey
= (30 * GetRValue(color
) + 59 * GetGValue(color
) + 11 * GetBValue(color
) + 200) / 400;
6753 /* masks are always 8x8 */
6754 assert( dib
->width
== 8 );
6755 assert( dib
->height
== 8 );
6757 get_rop_codes( rop2
, &codes
);
6759 for (y
= 0; y
< 8; y
++)
6761 *and_bits
= *xor_bits
= 0;
6762 for (x
= 0; x
< 8; x
++)
6764 if (grey
+ bayer_8x8
[y
][x
] > 63)
6766 rop_mask
.and = (0xff & codes
.a1
) ^ codes
.a2
;
6767 rop_mask
.xor = (0xff & codes
.x1
) ^ codes
.x2
;
6771 rop_mask
.and = (0x00 & codes
.a1
) ^ codes
.a2
;
6772 rop_mask
.xor = (0x00 & codes
.x1
) ^ codes
.x2
;
6774 *and_bits
|= (rop_mask
.and & pixel_masks_1
[x
]);
6775 *xor_bits
|= (rop_mask
.xor & pixel_masks_1
[x
]);
6777 and_bits
+= dib
->stride
;
6778 xor_bits
+= dib
->stride
;
6782 static void create_dither_masks_null(const dib_info
*dib
, int rop2
, COLORREF color
, rop_mask_bits
*bits
)
6786 static inline void rop_codes_from_stretch_mode( int mode
, struct rop_codes
*codes
)
6791 case STRETCH_DELETESCANS
:
6792 get_rop_codes( R2_COPYPEN
, codes
);
6794 case STRETCH_ORSCANS
:
6795 get_rop_codes( R2_MERGEPEN
, codes
);
6797 case STRETCH_ANDSCANS
:
6798 get_rop_codes( R2_MASKPEN
, codes
);
6804 static void stretch_row_32(const dib_info
*dst_dib
, const POINT
*dst_start
,
6805 const dib_info
*src_dib
, const POINT
*src_start
,
6806 const struct stretch_params
*params
, int mode
,
6809 DWORD
*dst_ptr
= get_pixel_ptr_32( dst_dib
, dst_start
->x
, dst_start
->y
);
6810 DWORD
*src_ptr
= get_pixel_ptr_32( src_dib
, src_start
->x
, src_start
->y
);
6811 int err
= params
->err_start
;
6814 if (mode
== STRETCH_DELETESCANS
|| !keep_dst
)
6816 for (width
= params
->length
; width
; width
--)
6818 *dst_ptr
= *src_ptr
;
6819 dst_ptr
+= params
->dst_inc
;
6822 src_ptr
+= params
->src_inc
;
6823 err
+= params
->err_add_1
;
6825 else err
+= params
->err_add_2
;
6830 struct rop_codes codes
;
6832 rop_codes_from_stretch_mode( mode
, &codes
);
6833 for (width
= params
->length
; width
; width
--)
6835 do_rop_codes_32( dst_ptr
, *src_ptr
, &codes
);
6836 dst_ptr
+= params
->dst_inc
;
6839 src_ptr
+= params
->src_inc
;
6840 err
+= params
->err_add_1
;
6842 else err
+= params
->err_add_2
;
6847 static void stretch_row_24(const dib_info
*dst_dib
, const POINT
*dst_start
,
6848 const dib_info
*src_dib
, const POINT
*src_start
,
6849 const struct stretch_params
*params
, int mode
,
6852 BYTE
*dst_ptr
= get_pixel_ptr_24( dst_dib
, dst_start
->x
, dst_start
->y
);
6853 BYTE
*src_ptr
= get_pixel_ptr_24( src_dib
, src_start
->x
, src_start
->y
);
6854 int err
= params
->err_start
;
6857 if (mode
== STRETCH_DELETESCANS
|| !keep_dst
)
6859 for (width
= params
->length
; width
; width
--)
6861 dst_ptr
[0] = src_ptr
[0];
6862 dst_ptr
[1] = src_ptr
[1];
6863 dst_ptr
[2] = src_ptr
[2];
6864 dst_ptr
+= 3 * params
->dst_inc
;
6867 src_ptr
+= 3 * params
->src_inc
;
6868 err
+= params
->err_add_1
;
6870 else err
+= params
->err_add_2
;
6875 struct rop_codes codes
;
6877 rop_codes_from_stretch_mode( mode
, &codes
);
6878 for (width
= params
->length
; width
; width
--)
6880 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
6881 do_rop_codes_8( dst_ptr
+ 1, *(src_ptr
+ 1), &codes
);
6882 do_rop_codes_8( dst_ptr
+ 2, *(src_ptr
+ 2), &codes
);
6883 dst_ptr
+= 3 * params
->dst_inc
;
6886 src_ptr
+= 3 * params
->src_inc
;
6887 err
+= params
->err_add_1
;
6889 else err
+= params
->err_add_2
;
6894 static void stretch_row_16(const dib_info
*dst_dib
, const POINT
*dst_start
,
6895 const dib_info
*src_dib
, const POINT
*src_start
,
6896 const struct stretch_params
*params
, int mode
,
6899 WORD
*dst_ptr
= get_pixel_ptr_16( dst_dib
, dst_start
->x
, dst_start
->y
);
6900 WORD
*src_ptr
= get_pixel_ptr_16( src_dib
, src_start
->x
, src_start
->y
);
6901 int err
= params
->err_start
;
6904 if (mode
== STRETCH_DELETESCANS
|| !keep_dst
)
6906 for (width
= params
->length
; width
; width
--)
6908 *dst_ptr
= *src_ptr
;
6909 dst_ptr
+= params
->dst_inc
;
6912 src_ptr
+= params
->src_inc
;
6913 err
+= params
->err_add_1
;
6915 else err
+= params
->err_add_2
;
6920 struct rop_codes codes
;
6922 rop_codes_from_stretch_mode( mode
, &codes
);
6923 for (width
= params
->length
; width
; width
--)
6925 do_rop_codes_16( dst_ptr
, *src_ptr
, &codes
);
6926 dst_ptr
+= params
->dst_inc
;
6929 src_ptr
+= params
->src_inc
;
6930 err
+= params
->err_add_1
;
6932 else err
+= params
->err_add_2
;
6937 static void stretch_row_8(const dib_info
*dst_dib
, const POINT
*dst_start
,
6938 const dib_info
*src_dib
, const POINT
*src_start
,
6939 const struct stretch_params
*params
, int mode
,
6942 BYTE
*dst_ptr
= get_pixel_ptr_8( dst_dib
, dst_start
->x
, dst_start
->y
);
6943 BYTE
*src_ptr
= get_pixel_ptr_8( src_dib
, src_start
->x
, src_start
->y
);
6944 int err
= params
->err_start
;
6947 if (mode
== STRETCH_DELETESCANS
|| !keep_dst
)
6949 for (width
= params
->length
; width
; width
--)
6951 *dst_ptr
= *src_ptr
;
6952 dst_ptr
+= params
->dst_inc
;
6955 src_ptr
+= params
->src_inc
;
6956 err
+= params
->err_add_1
;
6958 else err
+= params
->err_add_2
;
6963 struct rop_codes codes
;
6965 rop_codes_from_stretch_mode( mode
, &codes
);
6966 for (width
= params
->length
; width
; width
--)
6968 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
6969 dst_ptr
+= params
->dst_inc
;
6972 src_ptr
+= params
->src_inc
;
6973 err
+= params
->err_add_1
;
6975 else err
+= params
->err_add_2
;
6980 static void stretch_row_4(const dib_info
*dst_dib
, const POINT
*dst_start
,
6981 const dib_info
*src_dib
, const POINT
*src_start
,
6982 const struct stretch_params
*params
, int mode
,
6985 BYTE
*dst_ptr
= get_pixel_ptr_4( dst_dib
, dst_start
->x
, dst_start
->y
);
6986 BYTE
*src_ptr
= get_pixel_ptr_4( src_dib
, src_start
->x
, src_start
->y
);
6987 int err
= params
->err_start
;
6988 int width
, dst_x
= dst_dib
->rect
.left
+ dst_start
->x
, src_x
= src_dib
->rect
.left
+ src_start
->x
;
6989 struct rop_codes codes
;
6992 if (!keep_dst
) mode
= STRETCH_DELETESCANS
;
6993 rop_codes_from_stretch_mode( mode
, &codes
);
6994 for (width
= params
->length
; width
; width
--)
6996 if (src_x
& 1) src_val
= (*src_ptr
& 0x0f) | (*src_ptr
<< 4);
6997 else src_val
= (*src_ptr
& 0xf0) | (*src_ptr
>> 4);
6999 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, (dst_x
& 1) ? 0x0f : 0xf0 );
7001 if ((dst_x
& ~1) != ((dst_x
+ params
->dst_inc
) & ~1))
7002 dst_ptr
+= params
->dst_inc
;
7003 dst_x
+= params
->dst_inc
;
7007 if ((src_x
& ~1) != ((src_x
+ params
->src_inc
) & ~1))
7008 src_ptr
+= params
->src_inc
;
7009 src_x
+= params
->src_inc
;
7010 err
+= params
->err_add_1
;
7012 else err
+= params
->err_add_2
;
7016 static void stretch_row_1(const dib_info
*dst_dib
, const POINT
*dst_start
,
7017 const dib_info
*src_dib
, const POINT
*src_start
,
7018 const struct stretch_params
*params
, int mode
,
7021 BYTE
*dst_ptr
= get_pixel_ptr_1( dst_dib
, dst_start
->x
, dst_start
->y
);
7022 BYTE
*src_ptr
= get_pixel_ptr_1( src_dib
, src_start
->x
, src_start
->y
);
7023 int err
= params
->err_start
;
7024 int width
, dst_x
= dst_dib
->rect
.left
+ dst_start
->x
, src_x
= src_dib
->rect
.left
+ src_start
->x
;
7025 struct rop_codes codes
;
7028 if (!keep_dst
) mode
= STRETCH_DELETESCANS
;
7029 rop_codes_from_stretch_mode( mode
, &codes
);
7030 for (width
= params
->length
; width
; width
--)
7032 src_val
= *src_ptr
& pixel_masks_1
[src_x
% 8] ? 0xff : 0;
7033 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, pixel_masks_1
[dst_x
% 8] );
7035 if ((dst_x
& ~7) != ((dst_x
+ params
->dst_inc
) & ~7))
7036 dst_ptr
+= params
->dst_inc
;
7037 dst_x
+= params
->dst_inc
;
7041 if ((src_x
& ~7) != ((src_x
+ params
->src_inc
) & ~7))
7042 src_ptr
+= params
->src_inc
;
7043 src_x
+= params
->src_inc
;
7044 err
+= params
->err_add_1
;
7046 else err
+= params
->err_add_2
;
7050 static void stretch_row_null(const dib_info
*dst_dib
, const POINT
*dst_start
,
7051 const dib_info
*src_dib
, const POINT
*src_start
,
7052 const struct stretch_params
*params
, int mode
,
7055 FIXME("bit count %d\n", dst_dib
->bit_count
);
7059 static void shrink_row_32(const dib_info
*dst_dib
, const POINT
*dst_start
,
7060 const dib_info
*src_dib
, const POINT
*src_start
,
7061 const struct stretch_params
*params
, int mode
,
7064 DWORD
*dst_ptr
= get_pixel_ptr_32( dst_dib
, dst_start
->x
, dst_start
->y
);
7065 DWORD
*src_ptr
= get_pixel_ptr_32( src_dib
, src_start
->x
, src_start
->y
);
7066 int err
= params
->err_start
;
7069 if (mode
== STRETCH_DELETESCANS
)
7071 for (width
= params
->length
; width
; width
--)
7073 *dst_ptr
= *src_ptr
;
7074 src_ptr
+= params
->src_inc
;
7077 dst_ptr
+= params
->dst_inc
;
7078 err
+= params
->err_add_1
;
7080 else err
+= params
->err_add_2
;
7085 struct rop_codes codes
;
7086 DWORD init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
7087 BOOL new_pix
= TRUE
;
7089 rop_codes_from_stretch_mode( mode
, &codes
);
7090 for (width
= params
->length
; width
; width
--)
7092 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
7093 do_rop_codes_32( dst_ptr
, *src_ptr
, &codes
);
7095 src_ptr
+= params
->src_inc
;
7098 dst_ptr
+= params
->dst_inc
;
7100 err
+= params
->err_add_1
;
7102 else err
+= params
->err_add_2
;
7107 static void shrink_row_24(const dib_info
*dst_dib
, const POINT
*dst_start
,
7108 const dib_info
*src_dib
, const POINT
*src_start
,
7109 const struct stretch_params
*params
, int mode
,
7112 BYTE
*dst_ptr
= get_pixel_ptr_24( dst_dib
, dst_start
->x
, dst_start
->y
);
7113 BYTE
*src_ptr
= get_pixel_ptr_24( src_dib
, src_start
->x
, src_start
->y
);
7114 int err
= params
->err_start
;
7117 if (mode
== STRETCH_DELETESCANS
)
7119 for (width
= params
->length
; width
; width
--)
7121 dst_ptr
[0] = src_ptr
[0];
7122 dst_ptr
[1] = src_ptr
[1];
7123 dst_ptr
[2] = src_ptr
[2];
7124 src_ptr
+= 3 * params
->src_inc
;
7127 dst_ptr
+= 3 * params
->dst_inc
;
7128 err
+= params
->err_add_1
;
7130 else err
+= params
->err_add_2
;
7135 struct rop_codes codes
;
7136 BYTE init_val
= (mode
== STRETCH_ANDSCANS
) ? 0xff : 0;
7137 BOOL new_pix
= TRUE
;
7139 rop_codes_from_stretch_mode( mode
, &codes
);
7140 for (width
= params
->length
; width
; width
--)
7142 if (new_pix
&& !keep_dst
) memset( dst_ptr
, init_val
, 3 );
7143 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
7144 do_rop_codes_8( dst_ptr
+ 1, *(src_ptr
+ 1), &codes
);
7145 do_rop_codes_8( dst_ptr
+ 2, *(src_ptr
+ 2), &codes
);
7147 src_ptr
+= 3 * params
->src_inc
;
7150 dst_ptr
+= 3 * params
->dst_inc
;
7152 err
+= params
->err_add_1
;
7154 else err
+= params
->err_add_2
;
7159 static void shrink_row_16(const dib_info
*dst_dib
, const POINT
*dst_start
,
7160 const dib_info
*src_dib
, const POINT
*src_start
,
7161 const struct stretch_params
*params
, int mode
,
7164 WORD
*dst_ptr
= get_pixel_ptr_16( dst_dib
, dst_start
->x
, dst_start
->y
);
7165 WORD
*src_ptr
= get_pixel_ptr_16( src_dib
, src_start
->x
, src_start
->y
);
7166 int err
= params
->err_start
;
7169 if (mode
== STRETCH_DELETESCANS
)
7171 for (width
= params
->length
; width
; width
--)
7173 *dst_ptr
= *src_ptr
;
7174 src_ptr
+= params
->src_inc
;
7177 dst_ptr
+= params
->dst_inc
;
7178 err
+= params
->err_add_1
;
7180 else err
+= params
->err_add_2
;
7185 struct rop_codes codes
;
7186 WORD init_val
= (mode
== STRETCH_ANDSCANS
) ? 0xffff : 0;
7187 BOOL new_pix
= TRUE
;
7189 rop_codes_from_stretch_mode( mode
, &codes
);
7190 for (width
= params
->length
; width
; width
--)
7192 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
7193 do_rop_codes_16( dst_ptr
, *src_ptr
, &codes
);
7195 src_ptr
+= params
->src_inc
;
7198 dst_ptr
+= params
->dst_inc
;
7200 err
+= params
->err_add_1
;
7202 else err
+= params
->err_add_2
;
7207 static void shrink_row_8(const dib_info
*dst_dib
, const POINT
*dst_start
,
7208 const dib_info
*src_dib
, const POINT
*src_start
,
7209 const struct stretch_params
*params
, int mode
,
7212 BYTE
*dst_ptr
= get_pixel_ptr_8( dst_dib
, dst_start
->x
, dst_start
->y
);
7213 BYTE
*src_ptr
= get_pixel_ptr_8( src_dib
, src_start
->x
, src_start
->y
);
7214 int err
= params
->err_start
;
7217 if (mode
== STRETCH_DELETESCANS
)
7219 for (width
= params
->length
; width
; width
--)
7221 *dst_ptr
= *src_ptr
;
7222 src_ptr
+= params
->src_inc
;
7225 dst_ptr
+= params
->dst_inc
;
7226 err
+= params
->err_add_1
;
7228 else err
+= params
->err_add_2
;
7233 struct rop_codes codes
;
7234 BYTE init_val
= (mode
== STRETCH_ANDSCANS
) ? 0xff : 0;
7235 BOOL new_pix
= TRUE
;
7237 rop_codes_from_stretch_mode( mode
, &codes
);
7238 for (width
= params
->length
; width
; width
--)
7240 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
7241 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
7243 src_ptr
+= params
->src_inc
;
7246 dst_ptr
+= params
->dst_inc
;
7248 err
+= params
->err_add_1
;
7250 else err
+= params
->err_add_2
;
7255 static void shrink_row_4(const dib_info
*dst_dib
, const POINT
*dst_start
,
7256 const dib_info
*src_dib
, const POINT
*src_start
,
7257 const struct stretch_params
*params
, int mode
,
7260 BYTE
*dst_ptr
= get_pixel_ptr_4( dst_dib
, dst_start
->x
, dst_start
->y
);
7261 BYTE
*src_ptr
= get_pixel_ptr_4( src_dib
, src_start
->x
, src_start
->y
);
7262 int err
= params
->err_start
;
7263 int width
, dst_x
= dst_dib
->rect
.left
+ dst_start
->x
, src_x
= src_dib
->rect
.left
+ src_start
->x
;
7264 struct rop_codes codes
;
7265 BYTE src_val
, init_val
= (mode
== STRETCH_ANDSCANS
) ? 0xff : 0;
7266 BOOL new_pix
= TRUE
;
7268 rop_codes_from_stretch_mode( mode
, &codes
);
7269 for (width
= params
->length
; width
; width
--)
7271 if (new_pix
&& !keep_dst
) do_rop_mask_8( dst_ptr
, 0, init_val
, (dst_x
& 1) ? 0x0f : 0xf0 );
7273 if (src_x
& 1) src_val
= (*src_ptr
& 0x0f) | (*src_ptr
<< 4);
7274 else src_val
= (*src_ptr
& 0xf0) | (*src_ptr
>> 4);
7276 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, (dst_x
& 1) ? 0x0f : 0xf0 );
7279 if ((src_x
& ~1) != ((src_x
+ params
->src_inc
) & ~1))
7280 src_ptr
+= params
->src_inc
;
7281 src_x
+= params
->src_inc
;
7285 if ((dst_x
& ~1) != ((dst_x
+ params
->dst_inc
) & ~1))
7286 dst_ptr
+= params
->dst_inc
;
7287 dst_x
+= params
->dst_inc
;
7289 err
+= params
->err_add_1
;
7291 else err
+= params
->err_add_2
;
7295 static void shrink_row_1(const dib_info
*dst_dib
, const POINT
*dst_start
,
7296 const dib_info
*src_dib
, const POINT
*src_start
,
7297 const struct stretch_params
*params
, int mode
,
7300 BYTE
*dst_ptr
= get_pixel_ptr_1( dst_dib
, dst_start
->x
, dst_start
->y
);
7301 BYTE
*src_ptr
= get_pixel_ptr_1( src_dib
, src_start
->x
, src_start
->y
);
7302 int err
= params
->err_start
;
7303 int width
, dst_x
= dst_dib
->rect
.left
+ dst_start
->x
, src_x
= src_dib
->rect
.left
+ src_start
->x
;
7304 struct rop_codes codes
;
7305 BYTE src_val
, init_val
= (mode
== STRETCH_ANDSCANS
) ? 0xff : 0;
7306 BOOL new_pix
= TRUE
;
7308 rop_codes_from_stretch_mode( mode
, &codes
);
7309 for (width
= params
->length
; width
; width
--)
7311 if (new_pix
&& !keep_dst
) do_rop_mask_8( dst_ptr
, 0, init_val
, pixel_masks_1
[dst_x
% 8] );
7312 src_val
= *src_ptr
& pixel_masks_1
[src_x
% 8] ? 0xff : 0;
7313 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, pixel_masks_1
[dst_x
% 8] );
7316 if ((src_x
& ~7) != ((src_x
+ params
->src_inc
) & ~7))
7317 src_ptr
+= params
->src_inc
;
7318 src_x
+= params
->src_inc
;
7322 if ((dst_x
& ~7) != ((dst_x
+ params
->dst_inc
) & ~7))
7323 dst_ptr
+= params
->dst_inc
;
7324 dst_x
+= params
->dst_inc
;
7326 err
+= params
->err_add_1
;
7328 else err
+= params
->err_add_2
;
7332 static void shrink_row_null(const dib_info
*dst_dib
, const POINT
*dst_start
,
7333 const dib_info
*src_dib
, const POINT
*src_start
,
7334 const struct stretch_params
*params
, int mode
,
7337 FIXME("bit count %d\n", dst_dib
->bit_count
);
7341 const primitive_funcs funcs_8888
=
7351 draw_subpixel_glyph_8888
,
7353 colorref_to_pixel_888
,
7354 pixel_to_colorref_888
,
7356 create_rop_masks_32
,
7357 create_dither_masks_null
,
7362 const primitive_funcs funcs_32
=
7372 draw_subpixel_glyph_32
,
7374 colorref_to_pixel_masks
,
7375 pixel_to_colorref_masks
,
7377 create_rop_masks_32
,
7378 create_dither_masks_null
,
7383 const primitive_funcs funcs_24
=
7393 draw_subpixel_glyph_24
,
7395 colorref_to_pixel_888
,
7396 pixel_to_colorref_888
,
7398 create_rop_masks_24
,
7399 create_dither_masks_null
,
7404 const primitive_funcs funcs_555
=
7414 draw_subpixel_glyph_555
,
7416 colorref_to_pixel_555
,
7417 pixel_to_colorref_555
,
7419 create_rop_masks_16
,
7420 create_dither_masks_null
,
7425 const primitive_funcs funcs_16
=
7435 draw_subpixel_glyph_16
,
7437 colorref_to_pixel_masks
,
7438 pixel_to_colorref_masks
,
7440 create_rop_masks_16
,
7441 create_dither_masks_null
,
7446 const primitive_funcs funcs_8
=
7456 draw_subpixel_glyph_null
,
7458 colorref_to_pixel_colortable
,
7459 pixel_to_colorref_colortable
,
7462 create_dither_masks_8
,
7467 const primitive_funcs funcs_4
=
7477 draw_subpixel_glyph_null
,
7479 colorref_to_pixel_colortable
,
7480 pixel_to_colorref_colortable
,
7483 create_dither_masks_4
,
7488 const primitive_funcs funcs_1
=
7498 draw_subpixel_glyph_null
,
7500 colorref_to_pixel_colortable
,
7501 pixel_to_colorref_colortable
,
7504 create_dither_masks_1
,
7509 const primitive_funcs funcs_null
=
7519 draw_subpixel_glyph_null
,
7521 colorref_to_pixel_null
,
7522 pixel_to_colorref_null
,
7524 create_rop_masks_null
,
7525 create_dither_masks_null
,