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_16x16
[16][16] =
42 { 0, 128, 32, 160, 8, 136, 40, 168, 2, 130, 34, 162, 10, 138, 42, 170 },
43 { 192, 64, 224, 96, 200, 72, 232, 104, 194, 66, 226, 98, 202, 74, 234, 106 },
44 { 48, 176, 16, 144, 56, 184, 24, 152, 50, 178, 18, 146, 58, 186, 26, 154 },
45 { 240, 112, 208, 80, 248, 120, 216, 88, 242, 114, 210, 82, 250, 122, 218, 90 },
46 { 12, 140, 44, 172, 4, 132, 36, 164, 14, 142, 46, 174, 6, 134, 38, 166 },
47 { 204, 76, 236, 108, 196, 68, 228, 100, 206, 78, 238, 110, 198, 70, 230, 102 },
48 { 60, 188, 28, 156, 52, 180, 20, 148, 62, 190, 30, 158, 54, 182, 22, 150 },
49 { 252, 124, 220, 92, 244, 116, 212, 84, 254, 126, 222, 94, 246, 118, 214, 86 },
50 { 3, 131, 35, 163, 11, 139, 43, 171, 1, 129, 33, 161, 9, 137, 41, 169 },
51 { 195, 67, 227, 99, 203, 75, 235, 107, 193, 65, 225, 97, 201, 73, 233, 105 },
52 { 51, 179, 19, 147, 59, 187, 27, 155, 49, 177, 17, 145, 57, 185, 25, 153 },
53 { 243, 115, 211, 83, 251, 123, 219, 91, 241, 113, 209, 81, 249, 121, 217, 89 },
54 { 15, 143, 47, 175, 7, 135, 39, 167, 13, 141, 45, 173, 5, 133, 37, 165 },
55 { 207, 79, 239, 111, 199, 71, 231, 103, 205, 77, 237, 109, 197, 69, 229, 101 },
56 { 63, 191, 31, 159, 55, 183, 23, 151, 61, 189, 29, 157, 53, 181, 21, 149 },
57 { 255, 127, 223, 95, 247, 119, 215, 87, 253, 125, 221, 93, 245, 117, 213, 85 },
60 static inline DWORD
*get_pixel_ptr_32(const dib_info
*dib
, int x
, int y
)
62 return (DWORD
*)((BYTE
*)dib
->bits
.ptr
+ y
* dib
->stride
+ x
* 4);
65 static inline DWORD
*get_pixel_ptr_24_dword(const dib_info
*dib
, int x
, int y
)
67 return (DWORD
*)((BYTE
*)dib
->bits
.ptr
+ y
* dib
->stride
) + x
* 3 / 4;
70 static inline BYTE
*get_pixel_ptr_24(const dib_info
*dib
, int x
, int y
)
72 return (BYTE
*)dib
->bits
.ptr
+ y
* dib
->stride
+ x
* 3;
75 static inline WORD
*get_pixel_ptr_16(const dib_info
*dib
, int x
, int y
)
77 return (WORD
*)((BYTE
*)dib
->bits
.ptr
+ y
* dib
->stride
+ x
* 2);
80 static inline BYTE
*get_pixel_ptr_8(const dib_info
*dib
, int x
, int y
)
82 return (BYTE
*)dib
->bits
.ptr
+ y
* dib
->stride
+ x
;
85 static inline BYTE
*get_pixel_ptr_4(const dib_info
*dib
, int x
, int y
)
87 return (BYTE
*)dib
->bits
.ptr
+ y
* dib
->stride
+ x
/ 2;
90 static inline BYTE
*get_pixel_ptr_1(const dib_info
*dib
, int x
, int y
)
92 return (BYTE
*)dib
->bits
.ptr
+ y
* dib
->stride
+ x
/ 8;
95 static const BYTE pixel_masks_4
[2] = {0xf0, 0x0f};
96 static const BYTE pixel_masks_1
[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
98 static inline void do_rop_32(DWORD
*ptr
, DWORD
and, DWORD
xor)
100 *ptr
= (*ptr
& and) ^ xor;
103 static inline void do_rop_16(WORD
*ptr
, WORD
and, WORD
xor)
105 *ptr
= (*ptr
& and) ^ xor;
108 static inline void do_rop_8(BYTE
*ptr
, BYTE
and, BYTE
xor)
110 *ptr
= (*ptr
& and) ^ xor;
113 static inline void do_rop_mask_8(BYTE
*ptr
, BYTE
and, BYTE
xor, BYTE mask
)
115 *ptr
= (*ptr
& (and | ~mask
)) ^ (xor & mask
);
118 static inline void do_rop_codes_32(DWORD
*dst
, DWORD src
, struct rop_codes
*codes
)
120 do_rop_32( dst
, (src
& codes
->a1
) ^ codes
->a2
, (src
& codes
->x1
) ^ codes
->x2
);
123 static inline void do_rop_codes_16(WORD
*dst
, WORD src
, struct rop_codes
*codes
)
125 do_rop_16( dst
, (src
& codes
->a1
) ^ codes
->a2
, (src
& codes
->x1
) ^ codes
->x2
);
128 static inline void do_rop_codes_8(BYTE
*dst
, BYTE src
, struct rop_codes
*codes
)
130 do_rop_8( dst
, (src
& codes
->a1
) ^ codes
->a2
, (src
& codes
->x1
) ^ codes
->x2
);
133 static inline void do_rop_codes_mask_8(BYTE
*dst
, BYTE src
, struct rop_codes
*codes
, BYTE mask
)
135 do_rop_mask_8( dst
, (src
& codes
->a1
) ^ codes
->a2
, (src
& codes
->x1
) ^ codes
->x2
, mask
);
138 static inline void do_rop_codes_line_32(DWORD
*dst
, const DWORD
*src
, struct rop_codes
*codes
, int len
)
140 for (; len
> 0; len
--, src
++, dst
++) do_rop_codes_32( dst
, *src
, codes
);
143 static inline void do_rop_codes_line_rev_32(DWORD
*dst
, const DWORD
*src
, struct rop_codes
*codes
, int len
)
145 for (src
+= len
- 1, dst
+= len
- 1; len
> 0; len
--, src
--, dst
--)
146 do_rop_codes_32( dst
, *src
, codes
);
149 static inline void do_rop_codes_line_16(WORD
*dst
, const WORD
*src
, struct rop_codes
*codes
, int len
)
151 for (; len
> 0; len
--, src
++, dst
++) do_rop_codes_16( dst
, *src
, codes
);
154 static inline void do_rop_codes_line_rev_16(WORD
*dst
, const WORD
*src
, struct rop_codes
*codes
, int len
)
156 for (src
+= len
- 1, dst
+= len
- 1; len
> 0; len
--, src
--, dst
--)
157 do_rop_codes_16( dst
, *src
, codes
);
160 static inline void do_rop_codes_line_8(BYTE
*dst
, const BYTE
*src
, struct rop_codes
*codes
, int len
)
162 for (; len
> 0; len
--, src
++, dst
++) do_rop_codes_8( dst
, *src
, codes
);
165 static inline void do_rop_codes_line_rev_8(BYTE
*dst
, const BYTE
*src
, struct rop_codes
*codes
, int len
)
167 for (src
+= len
- 1, dst
+= len
- 1; len
> 0; len
--, src
--, dst
--)
168 do_rop_codes_8( dst
, *src
, codes
);
171 static inline void do_rop_codes_line_4(BYTE
*dst
, int dst_x
, const BYTE
*src
, int src_x
,
172 struct rop_codes
*codes
, int len
)
176 for (src
+= src_x
/ 2, dst
+= dst_x
/ 2; len
> 0; len
--, dst_x
++, src_x
++)
180 if (src_x
& 1) src_val
= *src
++;
181 else src_val
= *src
>> 4;
182 do_rop_codes_mask_8( dst
++, src_val
, codes
, 0x0f );
186 if (src_x
& 1) src_val
= *src
++ << 4;
188 do_rop_codes_mask_8( dst
, src_val
, codes
, 0xf0 );
193 static inline void do_rop_codes_line_rev_4(BYTE
*dst
, int dst_x
, const BYTE
*src
, int src_x
,
194 struct rop_codes
*codes
, int len
)
200 for (src
+= src_x
/ 2, dst
+= dst_x
/ 2; len
> 0; len
--, dst_x
--, src_x
--)
204 if (src_x
& 1) src_val
= *src
;
205 else src_val
= *src
-- >> 4;
206 do_rop_codes_mask_8( dst
, src_val
, codes
, 0x0f );
210 if (src_x
& 1) src_val
= *src
<< 4;
211 else src_val
= *src
--;
212 do_rop_codes_mask_8( dst
--, src_val
, codes
, 0xf0 );
217 static inline void do_rop_codes_line_1(BYTE
*dst
, int dst_x
, const BYTE
*src
, int src_x
,
218 struct rop_codes
*codes
, int len
)
222 for (src
+= src_x
/ 8, dst
+= dst_x
/ 8; len
> 0; len
--, dst_x
++, src_x
++)
224 src_val
= *src
& pixel_masks_1
[src_x
& 7] ? 0xff : 0;
225 do_rop_codes_mask_8( dst
, src_val
, codes
, pixel_masks_1
[dst_x
& 7] );
226 if ((src_x
& 7) == 7) src
++;
227 if ((dst_x
& 7) == 7) dst
++;
231 static inline void do_rop_codes_line_rev_1(BYTE
*dst
, int dst_x
, const BYTE
*src
, int src_x
,
232 struct rop_codes
*codes
, int len
)
238 for (src
+= src_x
/ 8, dst
+= dst_x
/ 8; len
> 0; len
--, dst_x
--, src_x
--)
240 src_val
= *src
& pixel_masks_1
[src_x
& 7] ? 0xff : 0;
241 do_rop_codes_mask_8( dst
, src_val
, codes
, pixel_masks_1
[dst_x
& 7] );
242 if ((src_x
& 7) == 0) src
--;
243 if ((dst_x
& 7) == 0) dst
--;
247 static void solid_rects_32(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
252 for(i
= 0; i
< num
; i
++, rc
++)
254 start
= get_pixel_ptr_32(dib
, rc
->left
, rc
->top
);
255 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
256 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
257 do_rop_32(ptr
++, and, xor);
261 static void solid_rects_24(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
264 BYTE
*byte_ptr
, *byte_start
;
266 DWORD and_masks
[3], xor_masks
[3];
268 and_masks
[0] = ( and & 0x00ffffff) | ((and << 24) & 0xff000000);
269 and_masks
[1] = ((and >> 8) & 0x0000ffff) | ((and << 16) & 0xffff0000);
270 and_masks
[2] = ((and >> 16) & 0x000000ff) | ((and << 8) & 0xffffff00);
271 xor_masks
[0] = ( xor & 0x00ffffff) | ((xor << 24) & 0xff000000);
272 xor_masks
[1] = ((xor >> 8) & 0x0000ffff) | ((xor << 16) & 0xffff0000);
273 xor_masks
[2] = ((xor >> 16) & 0x000000ff) | ((xor << 8) & 0xffffff00);
275 for(i
= 0; i
< num
; i
++, rc
++)
277 if(rc
->left
>= rc
->right
) continue;
279 if((rc
->left
& ~3) == (rc
->right
& ~3)) /* Special case for lines that start and end in the same DWORD triplet */
281 byte_start
= get_pixel_ptr_24(dib
, rc
->left
, rc
->top
);
282 for(y
= rc
->top
; y
< rc
->bottom
; y
++, byte_start
+= dib
->stride
)
284 for(x
= rc
->left
, byte_ptr
= byte_start
; x
< rc
->right
; x
++)
286 do_rop_8(byte_ptr
++, and_masks
[0] & 0xff, xor_masks
[0] & 0xff);
287 do_rop_8(byte_ptr
++, and_masks
[1] & 0xff, xor_masks
[1] & 0xff);
288 do_rop_8(byte_ptr
++, and_masks
[2] & 0xff, xor_masks
[2] & 0xff);
294 start
= get_pixel_ptr_24_dword(dib
, rc
->left
, rc
->top
);
295 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
302 do_rop_32(ptr
++, and_masks
[0] | 0x00ffffff, xor_masks
[0] & 0xff000000);
303 do_rop_32(ptr
++, and_masks
[1], xor_masks
[1]);
304 do_rop_32(ptr
++, and_masks
[2], xor_masks
[2]);
307 do_rop_32(ptr
++, and_masks
[1] | 0x0000ffff, xor_masks
[1] & 0xffff0000);
308 do_rop_32(ptr
++, and_masks
[2], xor_masks
[2]);
311 do_rop_32(ptr
++, and_masks
[2] | 0x000000ff, xor_masks
[2] & 0xffffff00);
315 for(x
= (rc
->left
+ 3) & ~3; x
< (rc
->right
& ~3); x
+= 4)
317 do_rop_32(ptr
++, and_masks
[0], xor_masks
[0]);
318 do_rop_32(ptr
++, and_masks
[1], xor_masks
[1]);
319 do_rop_32(ptr
++, and_masks
[2], xor_masks
[2]);
322 switch(rc
->right
& 3)
325 do_rop_32(ptr
, and_masks
[0] | 0xff000000, xor_masks
[0] & 0x00ffffff);
328 do_rop_32(ptr
++, and_masks
[0], xor_masks
[0]);
329 do_rop_32(ptr
, and_masks
[1] | 0xffff0000, xor_masks
[1] & 0x0000ffff);
332 do_rop_32(ptr
++, and_masks
[0], xor_masks
[0]);
333 do_rop_32(ptr
++, and_masks
[1], xor_masks
[1]);
334 do_rop_32(ptr
, and_masks
[2] | 0xffffff00, xor_masks
[2] & 0x000000ff);
342 static void solid_rects_16(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
347 for(i
= 0; i
< num
; i
++, rc
++)
349 start
= get_pixel_ptr_16(dib
, rc
->left
, rc
->top
);
350 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 2)
351 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
352 do_rop_16(ptr
++, and, xor);
356 static void solid_rects_8(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
361 for(i
= 0; i
< num
; i
++, rc
++)
363 start
= get_pixel_ptr_8(dib
, rc
->left
, rc
->top
);
364 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
365 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
366 do_rop_8(ptr
++, and, xor);
370 static void solid_rects_4(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
374 BYTE byte_and
= (and & 0xf) | ((and << 4) & 0xf0);
375 BYTE byte_xor
= (xor & 0xf) | ((xor << 4) & 0xf0);
377 for(i
= 0; i
< num
; i
++, rc
++)
379 if(rc
->left
>= rc
->right
) continue;
380 start
= get_pixel_ptr_4(dib
, rc
->left
, rc
->top
);
381 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
384 if(rc
->left
& 1) /* upper nibble untouched */
385 do_rop_8(ptr
++, byte_and
| 0xf0, byte_xor
& 0x0f);
387 for(x
= (rc
->left
+ 1) & ~1; x
< (rc
->right
& ~1); x
+= 2)
388 do_rop_8(ptr
++, byte_and
, byte_xor
);
390 if(rc
->right
& 1) /* lower nibble untouched */
391 do_rop_8(ptr
, byte_and
| 0x0f, byte_xor
& 0xf0);
396 static void solid_rects_1(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
400 BYTE byte_and
= (and & 1) ? 0xff : 0;
401 BYTE byte_xor
= (xor & 1) ? 0xff : 0;
402 BYTE start_and
, start_xor
, end_and
, end_xor
, mask
;
403 static const BYTE masks
[8] = {0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01};
405 for(i
= 0; i
< num
; i
++, rc
++)
407 if(rc
->left
>= rc
->right
) continue;
409 start
= get_pixel_ptr_1(dib
, rc
->left
, rc
->top
);
411 if((rc
->left
& ~7) == (rc
->right
& ~7)) /* Special case for lines that start and end in the same byte */
413 mask
= masks
[rc
->left
& 7] & ~masks
[rc
->right
& 7];
415 start_and
= byte_and
| ~mask
;
416 start_xor
= byte_xor
& mask
;
417 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
419 do_rop_8(start
, start_and
, start_xor
);
424 mask
= masks
[rc
->left
& 7];
425 start_and
= byte_and
| ~mask
;
426 start_xor
= byte_xor
& mask
;
428 mask
= masks
[rc
->right
& 7];
429 /* This is inverted wrt to start mask, so end_and/xor assignments reflect this */
430 end_and
= byte_and
| mask
;
431 end_xor
= byte_xor
& ~mask
;
433 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
438 do_rop_8(ptr
++, start_and
, start_xor
);
440 for(x
= (rc
->left
+ 7) & ~7; x
< (rc
->right
& ~7); x
+= 8)
441 do_rop_8(ptr
++, byte_and
, byte_xor
);
444 do_rop_8(ptr
, end_and
, end_xor
);
450 static void solid_rects_null(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
455 static void solid_line_32(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
456 DWORD
and, DWORD
xor)
458 DWORD
*ptr
= get_pixel_ptr_32( dib
, start
->x
, start
->y
);
459 int len
= params
->length
, err
= params
->err_start
;
460 int major_inc
, minor_inc
;
464 major_inc
= params
->x_inc
;
465 minor_inc
= (dib
->stride
* params
->y_inc
) / 4;
469 major_inc
= (dib
->stride
* params
->y_inc
) / 4;
470 minor_inc
= params
->x_inc
;
475 do_rop_32( ptr
, and, xor );
476 if (err
+ params
->bias
> 0)
479 err
+= params
->err_add_1
;
481 else err
+= params
->err_add_2
;
486 static void solid_line_24(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
487 DWORD
and, DWORD
xor)
489 BYTE
*ptr
= get_pixel_ptr_24( dib
, start
->x
, start
->y
);
490 int len
= params
->length
, err
= params
->err_start
;
491 int major_inc
, minor_inc
;
495 major_inc
= params
->x_inc
* 3;
496 minor_inc
= dib
->stride
* params
->y_inc
;
500 major_inc
= dib
->stride
* params
->y_inc
;
501 minor_inc
= params
->x_inc
* 3;
506 do_rop_8( ptr
, and, xor );
507 do_rop_8( ptr
+ 1, and >> 8, xor >> 8 );
508 do_rop_8( ptr
+ 2, and >> 16, xor >> 16 );
509 if (err
+ params
->bias
> 0)
512 err
+= params
->err_add_1
;
514 else err
+= params
->err_add_2
;
519 static void solid_line_16(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
520 DWORD
and, DWORD
xor)
522 WORD
*ptr
= get_pixel_ptr_16( dib
, start
->x
, start
->y
);
523 int len
= params
->length
, err
= params
->err_start
;
524 int major_inc
, minor_inc
;
528 major_inc
= params
->x_inc
;
529 minor_inc
= (dib
->stride
* params
->y_inc
) / 2;
533 major_inc
= (dib
->stride
* params
->y_inc
) / 2;
534 minor_inc
= params
->x_inc
;
539 do_rop_16( ptr
, and, xor );
540 if (err
+ params
->bias
> 0)
543 err
+= params
->err_add_1
;
545 else err
+= params
->err_add_2
;
550 static void solid_line_8(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
551 DWORD
and, DWORD
xor)
553 BYTE
*ptr
= get_pixel_ptr_8( dib
, start
->x
, start
->y
);
554 int len
= params
->length
, err
= params
->err_start
;
555 int major_inc
, minor_inc
;
559 major_inc
= params
->x_inc
;
560 minor_inc
= dib
->stride
* params
->y_inc
;
564 major_inc
= dib
->stride
* params
->y_inc
;
565 minor_inc
= params
->x_inc
;
570 do_rop_8( ptr
, and, xor );
571 if (err
+ params
->bias
> 0)
574 err
+= params
->err_add_1
;
576 else err
+= params
->err_add_2
;
581 static void solid_line_4(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
582 DWORD
and, DWORD
xor)
584 BYTE
*ptr
= get_pixel_ptr_4( dib
, start
->x
, start
->y
);
585 int len
= params
->length
, err
= params
->err_start
;
588 and = (and & 0x0f) | ((and << 4) & 0xf0);
589 xor = (xor & 0x0f) | ((xor << 4) & 0xf0);
595 do_rop_mask_8( ptr
, and, xor, pixel_masks_4
[ x
% 2 ] );
596 if (err
+ params
->bias
> 0)
598 ptr
+= dib
->stride
* params
->y_inc
;
599 err
+= params
->err_add_1
;
601 else err
+= params
->err_add_2
;
602 if ((x
/ 2) != ((x
+ params
->x_inc
) / 2))
603 ptr
+= params
->x_inc
;
611 do_rop_mask_8( ptr
, and, xor, pixel_masks_4
[ x
% 2 ] );
612 if (err
+ params
->bias
> 0)
614 if ((x
/ 2) != ((x
+ params
->x_inc
) / 2))
615 ptr
+= params
->x_inc
;
617 err
+= params
->err_add_1
;
619 else err
+= params
->err_add_2
;
620 ptr
+= dib
->stride
* params
->y_inc
;
625 static void solid_line_1(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
626 DWORD
and, DWORD
xor)
628 BYTE
*ptr
= get_pixel_ptr_1( dib
, start
->x
, start
->y
);
629 int len
= params
->length
, err
= params
->err_start
;
632 and = (and & 0x1) ? 0xff : 0;
633 xor = (xor & 0x1) ? 0xff : 0;
639 do_rop_mask_8( ptr
, and, xor, pixel_masks_1
[ x
% 8 ] );
640 if (err
+ params
->bias
> 0)
642 ptr
+= dib
->stride
* params
->y_inc
;
643 err
+= params
->err_add_1
;
645 else err
+= params
->err_add_2
;
646 if ((x
/ 8) != ((x
+ params
->x_inc
) / 8))
647 ptr
+= params
->x_inc
;
655 do_rop_mask_8( ptr
, and, xor, pixel_masks_1
[ x
% 8 ] );
656 if (err
+ params
->bias
> 0)
658 if ((x
/ 8) != ((x
+ params
->x_inc
) / 8))
659 ptr
+= params
->x_inc
;
661 err
+= params
->err_add_1
;
663 else err
+= params
->err_add_2
;
664 ptr
+= dib
->stride
* params
->y_inc
;
669 static void solid_line_null(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
670 DWORD
and, DWORD
xor)
675 static inline INT
calc_offset(INT edge
, INT size
, INT origin
)
679 if(edge
- origin
>= 0)
680 offset
= (edge
- origin
) % size
;
683 offset
= (origin
- edge
) % size
;
684 if(offset
) offset
= size
- offset
;
689 static inline POINT
calc_brush_offset(const RECT
*rc
, const dib_info
*brush
, const POINT
*origin
)
693 offset
.x
= calc_offset(rc
->left
, brush
->width
, origin
->x
);
694 offset
.y
= calc_offset(rc
->top
, brush
->height
, origin
->y
);
699 static void pattern_rects_32(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
700 const dib_info
*brush
, void *and_bits
, void *xor_bits
)
702 DWORD
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
706 for(i
= 0; i
< num
; i
++, rc
++)
708 offset
= calc_brush_offset(rc
, brush
, origin
);
710 start
= get_pixel_ptr_32(dib
, rc
->left
, rc
->top
);
711 start_and
= (DWORD
*)and_bits
+ offset
.y
* brush
->stride
/ 4;
712 start_xor
= (DWORD
*)xor_bits
+ offset
.y
* brush
->stride
/ 4;
714 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
716 and_ptr
= start_and
+ offset
.x
;
717 xor_ptr
= start_xor
+ offset
.x
;
719 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
721 do_rop_32(ptr
++, *and_ptr
++, *xor_ptr
++);
722 if(and_ptr
== start_and
+ brush
->width
)
730 if(offset
.y
== brush
->height
)
732 start_and
= and_bits
;
733 start_xor
= xor_bits
;
738 start_and
+= brush
->stride
/ 4;
739 start_xor
+= brush
->stride
/ 4;
745 static void pattern_rects_24(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
746 const dib_info
*brush
, void *and_bits
, void *xor_bits
)
748 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
752 for(i
= 0; i
< num
; i
++, rc
++)
754 offset
= calc_brush_offset(rc
, brush
, origin
);
756 start
= get_pixel_ptr_24(dib
, rc
->left
, rc
->top
);
757 start_and
= (BYTE
*)and_bits
+ offset
.y
* brush
->stride
;
758 start_xor
= (BYTE
*)xor_bits
+ offset
.y
* brush
->stride
;
760 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
762 and_ptr
= start_and
+ offset
.x
* 3;
763 xor_ptr
= start_xor
+ offset
.x
* 3;
765 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
767 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
768 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
769 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
770 if(and_ptr
== start_and
+ brush
->width
* 3)
778 if(offset
.y
== brush
->height
)
780 start_and
= and_bits
;
781 start_xor
= xor_bits
;
786 start_and
+= brush
->stride
;
787 start_xor
+= brush
->stride
;
793 static void pattern_rects_16(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
794 const dib_info
*brush
, void *and_bits
, void *xor_bits
)
796 WORD
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
800 for(i
= 0; i
< num
; i
++, rc
++)
802 offset
= calc_brush_offset(rc
, brush
, origin
);
804 start
= get_pixel_ptr_16(dib
, rc
->left
, rc
->top
);
805 start_and
= (WORD
*)and_bits
+ offset
.y
* brush
->stride
/ 2;
806 start_xor
= (WORD
*)xor_bits
+ offset
.y
* brush
->stride
/ 2;
808 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 2)
810 and_ptr
= start_and
+ offset
.x
;
811 xor_ptr
= start_xor
+ offset
.x
;
813 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
815 do_rop_16(ptr
++, *and_ptr
++, *xor_ptr
++);
816 if(and_ptr
== start_and
+ brush
->width
)
824 if(offset
.y
== brush
->height
)
826 start_and
= and_bits
;
827 start_xor
= xor_bits
;
832 start_and
+= brush
->stride
/ 2;
833 start_xor
+= brush
->stride
/ 2;
839 static void pattern_rects_8(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
840 const dib_info
*brush
, void *and_bits
, void *xor_bits
)
842 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
846 for(i
= 0; i
< num
; i
++, rc
++)
848 offset
= calc_brush_offset(rc
, brush
, origin
);
850 start
= get_pixel_ptr_8(dib
, rc
->left
, rc
->top
);
851 start_and
= (BYTE
*)and_bits
+ offset
.y
* brush
->stride
;
852 start_xor
= (BYTE
*)xor_bits
+ offset
.y
* brush
->stride
;
854 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
856 and_ptr
= start_and
+ offset
.x
;
857 xor_ptr
= start_xor
+ offset
.x
;
859 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
861 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
862 if(and_ptr
== start_and
+ brush
->width
)
870 if(offset
.y
== brush
->height
)
872 start_and
= and_bits
;
873 start_xor
= xor_bits
;
878 start_and
+= brush
->stride
;
879 start_xor
+= brush
->stride
;
885 static void pattern_rects_4(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
886 const dib_info
*brush
, void *and_bits
, void *xor_bits
)
888 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
892 for(i
= 0; i
< num
; i
++, rc
++)
894 offset
= calc_brush_offset(rc
, brush
, origin
);
896 start
= get_pixel_ptr_4(dib
, rc
->left
, rc
->top
);
897 start_and
= (BYTE
*)and_bits
+ offset
.y
* brush
->stride
;
898 start_xor
= (BYTE
*)xor_bits
+ offset
.y
* brush
->stride
;
900 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
902 INT brush_x
= offset
.x
;
903 BYTE byte_and
, byte_xor
;
905 and_ptr
= start_and
+ brush_x
/ 2;
906 xor_ptr
= start_xor
+ brush_x
/ 2;
908 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
910 /* FIXME: Two pixels at a time */
911 if(x
& 1) /* lower dst nibble */
913 if(brush_x
& 1) /* lower pat nibble */
915 byte_and
= *and_ptr
++ | 0xf0;
916 byte_xor
= *xor_ptr
++ & 0x0f;
918 else /* upper pat nibble */
920 byte_and
= (*and_ptr
>> 4) | 0xf0;
921 byte_xor
= (*xor_ptr
>> 4) & 0x0f;
924 else /* upper dst nibble */
926 if(brush_x
& 1) /* lower pat nibble */
928 byte_and
= (*and_ptr
++ << 4) | 0x0f;
929 byte_xor
= (*xor_ptr
++ << 4) & 0xf0;
931 else /* upper pat nibble */
933 byte_and
= *and_ptr
| 0x0f;
934 byte_xor
= *xor_ptr
& 0xf0;
937 do_rop_8(ptr
, byte_and
, byte_xor
);
941 if(++brush_x
== brush
->width
)
950 if(offset
.y
== brush
->height
)
952 start_and
= and_bits
;
953 start_xor
= xor_bits
;
958 start_and
+= brush
->stride
;
959 start_xor
+= brush
->stride
;
965 static void pattern_rects_1(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
966 const dib_info
*brush
, void *and_bits
, void *xor_bits
)
968 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
972 for(i
= 0; i
< num
; i
++, rc
++)
974 offset
= calc_brush_offset(rc
, brush
, origin
);
976 start
= get_pixel_ptr_1(dib
, rc
->left
, rc
->top
);
977 start_and
= (BYTE
*)and_bits
+ offset
.y
* brush
->stride
;
978 start_xor
= (BYTE
*)xor_bits
+ offset
.y
* brush
->stride
;
980 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
982 INT brush_x
= offset
.x
;
983 BYTE byte_and
, byte_xor
;
985 and_ptr
= start_and
+ brush_x
/ 8;
986 xor_ptr
= start_xor
+ brush_x
/ 8;
988 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
990 byte_and
= (*and_ptr
& pixel_masks_1
[brush_x
% 8]) ? 0xff : 0;
991 byte_and
|= ~pixel_masks_1
[x
% 8];
992 byte_xor
= (*xor_ptr
& pixel_masks_1
[brush_x
% 8]) ? 0xff : 0;
993 byte_xor
&= pixel_masks_1
[x
% 8];
995 do_rop_8(ptr
, byte_and
, byte_xor
);
997 if((x
& 7) == 7) ptr
++;
999 if((brush_x
& 7) == 7)
1005 if(++brush_x
== brush
->width
)
1008 and_ptr
= start_and
;
1009 xor_ptr
= start_xor
;
1014 if(offset
.y
== brush
->height
)
1016 start_and
= and_bits
;
1017 start_xor
= xor_bits
;
1022 start_and
+= brush
->stride
;
1023 start_xor
+= brush
->stride
;
1029 static void pattern_rects_null(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
1030 const dib_info
*brush
, void *and_bits
, void *xor_bits
)
1035 static void copy_rect_32(const dib_info
*dst
, const RECT
*rc
,
1036 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1038 DWORD
*dst_start
, *src_start
;
1039 struct rop_codes codes
;
1040 int y
, dst_stride
, src_stride
;
1042 if (overlap
& OVERLAP_BELOW
)
1044 dst_start
= get_pixel_ptr_32(dst
, rc
->left
, rc
->bottom
- 1);
1045 src_start
= get_pixel_ptr_32(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1046 dst_stride
= -dst
->stride
/ 4;
1047 src_stride
= -src
->stride
/ 4;
1051 dst_start
= get_pixel_ptr_32(dst
, rc
->left
, rc
->top
);
1052 src_start
= get_pixel_ptr_32(src
, origin
->x
, origin
->y
);
1053 dst_stride
= dst
->stride
/ 4;
1054 src_stride
= src
->stride
/ 4;
1057 if (rop2
== R2_COPYPEN
)
1059 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1060 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) * 4 );
1064 get_rop_codes( rop2
, &codes
);
1065 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1067 if (overlap
& OVERLAP_RIGHT
)
1068 do_rop_codes_line_rev_32( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1070 do_rop_codes_line_32( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1074 static void copy_rect_24(const dib_info
*dst
, const RECT
*rc
,
1075 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1077 BYTE
*dst_start
, *src_start
;
1078 int y
, dst_stride
, src_stride
;
1079 struct rop_codes codes
;
1081 if (overlap
& OVERLAP_BELOW
)
1083 dst_start
= get_pixel_ptr_24(dst
, rc
->left
, rc
->bottom
- 1);
1084 src_start
= get_pixel_ptr_24(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1085 dst_stride
= -dst
->stride
;
1086 src_stride
= -src
->stride
;
1090 dst_start
= get_pixel_ptr_24(dst
, rc
->left
, rc
->top
);
1091 src_start
= get_pixel_ptr_24(src
, origin
->x
, origin
->y
);
1092 dst_stride
= dst
->stride
;
1093 src_stride
= src
->stride
;
1096 if (rop2
== R2_COPYPEN
)
1098 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1099 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) * 3 );
1103 get_rop_codes( rop2
, &codes
);
1104 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1106 if (overlap
& OVERLAP_RIGHT
)
1107 do_rop_codes_line_rev_8( dst_start
, src_start
, &codes
, (rc
->right
- rc
->left
) * 3 );
1109 do_rop_codes_line_8( dst_start
, src_start
, &codes
, (rc
->right
- rc
->left
) * 3 );
1113 static void copy_rect_16(const dib_info
*dst
, const RECT
*rc
,
1114 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1116 WORD
*dst_start
, *src_start
;
1117 int y
, dst_stride
, src_stride
;
1118 struct rop_codes codes
;
1120 if (overlap
& OVERLAP_BELOW
)
1122 dst_start
= get_pixel_ptr_16(dst
, rc
->left
, rc
->bottom
- 1);
1123 src_start
= get_pixel_ptr_16(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1124 dst_stride
= -dst
->stride
/ 2;
1125 src_stride
= -src
->stride
/ 2;
1129 dst_start
= get_pixel_ptr_16(dst
, rc
->left
, rc
->top
);
1130 src_start
= get_pixel_ptr_16(src
, origin
->x
, origin
->y
);
1131 dst_stride
= dst
->stride
/ 2;
1132 src_stride
= src
->stride
/ 2;
1135 if (rop2
== R2_COPYPEN
)
1137 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1138 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) * 2 );
1142 get_rop_codes( rop2
, &codes
);
1143 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1145 if (overlap
& OVERLAP_RIGHT
)
1146 do_rop_codes_line_rev_16( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1148 do_rop_codes_line_16( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1152 static void copy_rect_8(const dib_info
*dst
, const RECT
*rc
,
1153 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1155 BYTE
*dst_start
, *src_start
;
1156 int y
, dst_stride
, src_stride
;
1157 struct rop_codes codes
;
1159 if (overlap
& OVERLAP_BELOW
)
1161 dst_start
= get_pixel_ptr_8(dst
, rc
->left
, rc
->bottom
- 1);
1162 src_start
= get_pixel_ptr_8(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1163 dst_stride
= -dst
->stride
;
1164 src_stride
= -src
->stride
;
1168 dst_start
= get_pixel_ptr_8(dst
, rc
->left
, rc
->top
);
1169 src_start
= get_pixel_ptr_8(src
, origin
->x
, origin
->y
);
1170 dst_stride
= dst
->stride
;
1171 src_stride
= src
->stride
;
1174 if (rop2
== R2_COPYPEN
)
1176 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1177 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) );
1181 get_rop_codes( rop2
, &codes
);
1182 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1184 if (overlap
& OVERLAP_RIGHT
)
1185 do_rop_codes_line_rev_8( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1187 do_rop_codes_line_8( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1191 static void copy_rect_4(const dib_info
*dst
, const RECT
*rc
,
1192 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1194 BYTE
*dst_start
, *src_start
;
1195 int y
, dst_stride
, src_stride
;
1196 struct rop_codes codes
;
1198 if (overlap
& OVERLAP_BELOW
)
1200 dst_start
= get_pixel_ptr_4(dst
, 0, rc
->bottom
- 1);
1201 src_start
= get_pixel_ptr_4(src
, 0, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1202 dst_stride
= -dst
->stride
;
1203 src_stride
= -src
->stride
;
1207 dst_start
= get_pixel_ptr_4(dst
, 0, rc
->top
);
1208 src_start
= get_pixel_ptr_4(src
, 0, origin
->y
);
1209 dst_stride
= dst
->stride
;
1210 src_stride
= src
->stride
;
1213 if (rop2
== R2_COPYPEN
&& (rc
->left
& 1) == 0 && (origin
->x
& 1) == 0 && (rc
->right
& 1) == 0)
1215 dst_start
+= rc
->left
/ 2;
1216 src_start
+= origin
->x
/ 2;
1217 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1218 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) / 2 );
1222 get_rop_codes( rop2
, &codes
);
1223 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1225 if (overlap
& OVERLAP_RIGHT
)
1226 do_rop_codes_line_rev_4( dst_start
, rc
->left
, src_start
, origin
->x
, &codes
, rc
->right
- rc
->left
);
1228 do_rop_codes_line_4( dst_start
, rc
->left
, src_start
, origin
->x
, &codes
, rc
->right
- rc
->left
);
1232 static void copy_rect_1(const dib_info
*dst
, const RECT
*rc
,
1233 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1235 BYTE
*dst_start
, *src_start
;
1236 int y
, dst_stride
, src_stride
;
1237 struct rop_codes codes
;
1239 if (overlap
& OVERLAP_BELOW
)
1241 dst_start
= get_pixel_ptr_1(dst
, 0, rc
->bottom
- 1);
1242 src_start
= get_pixel_ptr_1(src
, 0, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1243 dst_stride
= -dst
->stride
;
1244 src_stride
= -src
->stride
;
1248 dst_start
= get_pixel_ptr_1(dst
, 0, rc
->top
);
1249 src_start
= get_pixel_ptr_1(src
, 0, origin
->y
);
1250 dst_stride
= dst
->stride
;
1251 src_stride
= src
->stride
;
1254 if (rop2
== R2_COPYPEN
&& (rc
->left
& 7) == 0 && (origin
->x
& 7) == 0 && (rc
->right
& 7) == 0)
1256 dst_start
+= rc
->left
/ 8;
1257 src_start
+= origin
->x
/ 8;
1258 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1259 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) / 8 );
1263 get_rop_codes( rop2
, &codes
);
1264 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1266 if (overlap
& OVERLAP_RIGHT
)
1267 do_rop_codes_line_rev_1( dst_start
, rc
->left
, src_start
, origin
->x
, &codes
, rc
->right
- rc
->left
);
1269 do_rop_codes_line_1( dst_start
, rc
->left
, src_start
, origin
->x
, &codes
, rc
->right
- rc
->left
);
1273 static void copy_rect_null(const dib_info
*dst
, const RECT
*rc
,
1274 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1279 static DWORD
get_pixel_32(const dib_info
*dib
, const POINT
*pt
)
1281 DWORD
*ptr
= get_pixel_ptr_32( dib
, pt
->x
, pt
->y
);
1285 static DWORD
get_pixel_24(const dib_info
*dib
, const POINT
*pt
)
1287 BYTE
*ptr
= get_pixel_ptr_24( dib
, pt
->x
, pt
->y
);
1288 return ptr
[0] | ((DWORD
)ptr
[1] << 8) | ((DWORD
)ptr
[2] << 16);
1291 static DWORD
get_pixel_16(const dib_info
*dib
, const POINT
*pt
)
1293 WORD
*ptr
= get_pixel_ptr_16( dib
, pt
->x
, pt
->y
);
1297 static DWORD
get_pixel_8(const dib_info
*dib
, const POINT
*pt
)
1299 BYTE
*ptr
= get_pixel_ptr_8( dib
, pt
->x
, pt
->y
);
1303 static DWORD
get_pixel_4(const dib_info
*dib
, const POINT
*pt
)
1305 BYTE
*ptr
= get_pixel_ptr_4( dib
, pt
->x
, pt
->y
);
1310 return (*ptr
>> 4) & 0x0f;
1313 static DWORD
get_pixel_1(const dib_info
*dib
, const POINT
*pt
)
1315 BYTE
*ptr
= get_pixel_ptr_1( dib
, pt
->x
, pt
->y
);
1316 return (*ptr
& pixel_masks_1
[pt
->x
& 0x7]) ? 1 : 0;
1319 static DWORD
get_pixel_null(const dib_info
*dib
, const POINT
*pt
)
1324 static DWORD
colorref_to_pixel_888(const dib_info
*dib
, COLORREF color
)
1326 return ( ((color
>> 16) & 0xff) | (color
& 0xff00) | ((color
<< 16) & 0xff0000) );
1329 static const DWORD field_masks
[33] =
1331 0x00, /* should never happen */
1332 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff,
1333 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1334 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1335 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1338 static inline DWORD
get_field(DWORD field
, int shift
, int len
)
1340 shift
= shift
- (8 - len
);
1345 field
&= field_masks
[len
];
1346 field
|= field
>> len
;
1350 static inline DWORD
put_field(DWORD field
, int shift
, int len
)
1352 shift
= shift
- (8 - len
);
1353 field
&= field_masks
[len
];
1361 static DWORD
colorref_to_pixel_masks(const dib_info
*dib
, COLORREF colour
)
1365 r
= GetRValue(colour
);
1366 g
= GetGValue(colour
);
1367 b
= GetBValue(colour
);
1369 return put_field(r
, dib
->red_shift
, dib
->red_len
) |
1370 put_field(g
, dib
->green_shift
, dib
->green_len
) |
1371 put_field(b
, dib
->blue_shift
, dib
->blue_len
);
1374 static DWORD
colorref_to_pixel_555(const dib_info
*dib
, COLORREF color
)
1376 return ( ((color
>> 19) & 0x1f) | ((color
>> 6) & 0x03e0) | ((color
<< 7) & 0x7c00) );
1379 static DWORD
rgb_to_pixel_colortable(const dib_info
*dib
, BYTE r
, BYTE g
, BYTE b
)
1381 int i
, best_index
= 0;
1382 DWORD diff
, best_diff
= 0xffffffff;
1384 /* special case for conversion to 1-bpp without a color table:
1385 * we get a 1-entry table containing the background color
1387 if (dib
->bit_count
== 1 && dib
->color_table_size
== 1)
1388 return (r
== dib
->color_table
[0].rgbRed
&&
1389 g
== dib
->color_table
[0].rgbGreen
&&
1390 b
== dib
->color_table
[0].rgbBlue
);
1392 for(i
= 0; i
< dib
->color_table_size
; i
++)
1394 RGBQUAD
*cur
= dib
->color_table
+ i
;
1395 diff
= (r
- cur
->rgbRed
) * (r
- cur
->rgbRed
)
1396 + (g
- cur
->rgbGreen
) * (g
- cur
->rgbGreen
)
1397 + (b
- cur
->rgbBlue
) * (b
- cur
->rgbBlue
);
1405 if(diff
< best_diff
)
1414 static DWORD
colorref_to_pixel_colortable(const dib_info
*dib
, COLORREF color
)
1416 return rgb_to_pixel_colortable( dib
, GetRValue(color
), GetGValue(color
), GetBValue(color
) );
1419 static DWORD
colorref_to_pixel_null(const dib_info
*dib
, COLORREF color
)
1424 static inline RGBQUAD
colortable_entry(const dib_info
*dib
, DWORD index
)
1426 static const RGBQUAD default_rgb
;
1427 if (index
< dib
->color_table_size
) return dib
->color_table
[index
];
1431 static COLORREF
pixel_to_colorref_888(const dib_info
*dib
, DWORD pixel
)
1433 return ( ((pixel
>> 16) & 0xff) | (pixel
& 0xff00) | ((pixel
<< 16) & 0xff0000) );
1436 static COLORREF
pixel_to_colorref_masks(const dib_info
*dib
, DWORD pixel
)
1438 return RGB( get_field( pixel
, dib
->red_shift
, dib
->red_len
),
1439 get_field( pixel
, dib
->green_shift
, dib
->green_len
),
1440 get_field( pixel
, dib
->blue_shift
, dib
->blue_len
) );
1443 static COLORREF
pixel_to_colorref_555(const dib_info
*dib
, DWORD pixel
)
1445 return RGB( ((pixel
>> 7) & 0xf8) | ((pixel
>> 12) & 0x07),
1446 ((pixel
>> 2) & 0xf8) | ((pixel
>> 7) & 0x07),
1447 ((pixel
<< 3) & 0xf8) | ((pixel
>> 2) & 0x07) );
1450 static COLORREF
pixel_to_colorref_colortable(const dib_info
*dib
, DWORD pixel
)
1452 RGBQUAD quad
= colortable_entry( dib
, pixel
);
1454 return RGB( quad
.rgbRed
, quad
.rgbGreen
, quad
.rgbBlue
);
1457 static COLORREF
pixel_to_colorref_null(const dib_info
*dib
, DWORD pixel
)
1462 static inline BOOL
bit_fields_match(const dib_info
*d1
, const dib_info
*d2
)
1464 assert( d1
->bit_count
> 8 && d1
->bit_count
== d2
->bit_count
);
1466 return d1
->red_mask
== d2
->red_mask
&&
1467 d1
->green_mask
== d2
->green_mask
&&
1468 d1
->blue_mask
== d2
->blue_mask
;
1471 static void convert_to_8888(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
1473 DWORD
*dst_start
= get_pixel_ptr_32(dst
, 0, 0), *dst_pixel
, src_val
;
1474 int x
, y
, pad_size
= (dst
->width
- (src_rect
->right
- src_rect
->left
)) * 4;
1476 switch(src
->bit_count
)
1480 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1481 if(src
->funcs
== &funcs_8888
)
1483 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
1484 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
1487 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1489 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 4);
1490 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
1491 dst_start
+= dst
->stride
/ 4;
1492 src_start
+= src
->stride
/ 4;
1496 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
1498 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1500 dst_pixel
= dst_start
;
1501 src_pixel
= src_start
;
1502 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1504 src_val
= *src_pixel
++;
1505 *dst_pixel
++ = (((src_val
>> src
->red_shift
) & 0xff) << 16) |
1506 (((src_val
>> src
->green_shift
) & 0xff) << 8) |
1507 ((src_val
>> src
->blue_shift
) & 0xff);
1509 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1510 dst_start
+= dst
->stride
/ 4;
1511 src_start
+= src
->stride
/ 4;
1516 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1518 dst_pixel
= dst_start
;
1519 src_pixel
= src_start
;
1520 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1522 src_val
= *src_pixel
++;
1523 *dst_pixel
++ = (get_field( src_val
, src
->red_shift
, src
->red_len
) << 16 |
1524 get_field( src_val
, src
->green_shift
, src
->green_len
) << 8 |
1525 get_field( src_val
, src
->blue_shift
, src
->blue_len
));
1527 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1528 dst_start
+= dst
->stride
/ 4;
1529 src_start
+= src
->stride
/ 4;
1537 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1539 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1541 dst_pixel
= dst_start
;
1542 src_pixel
= src_start
;
1543 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1546 rgb
.rgbBlue
= *src_pixel
++;
1547 rgb
.rgbGreen
= *src_pixel
++;
1548 rgb
.rgbRed
= *src_pixel
++;
1550 *dst_pixel
++ = ((rgb
.rgbRed
<< 16) & 0xff0000) | ((rgb
.rgbGreen
<< 8) & 0x00ff00) | (rgb
.rgbBlue
& 0x0000ff);
1552 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1553 dst_start
+= dst
->stride
/ 4;
1554 src_start
+= src
->stride
;
1561 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1562 if(src
->funcs
== &funcs_555
)
1564 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1566 dst_pixel
= dst_start
;
1567 src_pixel
= src_start
;
1568 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1570 src_val
= *src_pixel
++;
1571 *dst_pixel
++ = ((src_val
<< 9) & 0xf80000) | ((src_val
<< 4) & 0x070000) |
1572 ((src_val
<< 6) & 0x00f800) | ((src_val
<< 1) & 0x000700) |
1573 ((src_val
<< 3) & 0x0000f8) | ((src_val
>> 2) & 0x000007);
1575 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1576 dst_start
+= dst
->stride
/ 4;
1577 src_start
+= src
->stride
/ 2;
1580 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
1582 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1584 dst_pixel
= dst_start
;
1585 src_pixel
= src_start
;
1586 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1588 src_val
= *src_pixel
++;
1589 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 19) & 0xf80000) |
1590 (((src_val
>> src
->red_shift
) << 14) & 0x070000) |
1591 (((src_val
>> src
->green_shift
) << 11) & 0x00f800) |
1592 (((src_val
>> src
->green_shift
) << 6) & 0x000700) |
1593 (((src_val
>> src
->blue_shift
) << 3) & 0x0000f8) |
1594 (((src_val
>> src
->blue_shift
) >> 2) & 0x000007);
1596 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1597 dst_start
+= dst
->stride
/ 4;
1598 src_start
+= src
->stride
/ 2;
1601 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
1603 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1605 dst_pixel
= dst_start
;
1606 src_pixel
= src_start
;
1607 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1609 src_val
= *src_pixel
++;
1610 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 19) & 0xf80000) |
1611 (((src_val
>> src
->red_shift
) << 14) & 0x070000) |
1612 (((src_val
>> src
->green_shift
) << 10) & 0x00fc00) |
1613 (((src_val
>> src
->green_shift
) << 4) & 0x000300) |
1614 (((src_val
>> src
->blue_shift
) << 3) & 0x0000f8) |
1615 (((src_val
>> src
->blue_shift
) >> 2) & 0x000007);
1617 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1618 dst_start
+= dst
->stride
/ 4;
1619 src_start
+= src
->stride
/ 2;
1624 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1626 dst_pixel
= dst_start
;
1627 src_pixel
= src_start
;
1628 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1630 src_val
= *src_pixel
++;
1631 *dst_pixel
++ = (get_field( src_val
, src
->red_shift
, src
->red_len
) << 16 |
1632 get_field( src_val
, src
->green_shift
, src
->green_len
) << 8 |
1633 get_field( src_val
, src
->blue_shift
, src
->blue_len
));
1635 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1636 dst_start
+= dst
->stride
/ 4;
1637 src_start
+= src
->stride
/ 2;
1645 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1646 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1648 dst_pixel
= dst_start
;
1649 src_pixel
= src_start
;
1650 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1652 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
1653 *dst_pixel
++ = rgb
.rgbRed
<< 16 | rgb
.rgbGreen
<< 8 | rgb
.rgbBlue
;
1655 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1656 dst_start
+= dst
->stride
/ 4;
1657 src_start
+= src
->stride
;
1664 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1665 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1667 dst_pixel
= dst_start
;
1668 src_pixel
= src_start
;
1669 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1673 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
1675 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
1676 *dst_pixel
++ = rgb
.rgbRed
<< 16 | rgb
.rgbGreen
<< 8 | rgb
.rgbBlue
;
1678 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1679 dst_start
+= dst
->stride
/ 4;
1680 src_start
+= src
->stride
;
1687 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1688 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1690 dst_pixel
= dst_start
;
1691 src_pixel
= src_start
;
1692 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1695 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
1696 if((x
% 8) == 7) src_pixel
++;
1697 rgb
= src
->color_table
[src_val
];
1698 *dst_pixel
++ = rgb
.rgbRed
<< 16 | rgb
.rgbGreen
<< 8 | rgb
.rgbBlue
;
1700 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1701 dst_start
+= dst
->stride
/ 4;
1702 src_start
+= src
->stride
;
1709 static void convert_to_32(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
1711 DWORD
*dst_start
= get_pixel_ptr_32(dst
, 0, 0), *dst_pixel
, src_val
;
1712 int x
, y
, pad_size
= (dst
->width
- (src_rect
->right
- src_rect
->left
)) * 4;
1714 switch(src
->bit_count
)
1718 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1720 if(src
->funcs
== &funcs_8888
)
1722 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1724 dst_pixel
= dst_start
;
1725 src_pixel
= src_start
;
1726 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1728 src_val
= *src_pixel
++;
1729 *dst_pixel
++ = put_field(src_val
>> 16, dst
->red_shift
, dst
->red_len
) |
1730 put_field(src_val
>> 8, dst
->green_shift
, dst
->green_len
) |
1731 put_field(src_val
, dst
->blue_shift
, dst
->blue_len
);
1733 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1734 dst_start
+= dst
->stride
/ 4;
1735 src_start
+= src
->stride
/ 4;
1738 else if(bit_fields_match(src
, dst
))
1740 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
1741 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
1744 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1746 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 4);
1747 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
1748 dst_start
+= dst
->stride
/ 4;
1749 src_start
+= src
->stride
/ 4;
1753 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8 &&
1754 dst
->red_len
== 8 && dst
->green_len
== 8 && dst
->blue_len
== 8)
1756 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1758 dst_pixel
= dst_start
;
1759 src_pixel
= src_start
;
1760 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1762 src_val
= *src_pixel
++;
1763 *dst_pixel
++ = (((src_val
>> src
->red_shift
) & 0xff) << dst
->red_shift
) |
1764 (((src_val
>> src
->green_shift
) & 0xff) << dst
->green_shift
) |
1765 (((src_val
>> src
->blue_shift
) & 0xff) << dst
->blue_shift
);
1767 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1768 dst_start
+= dst
->stride
/ 4;
1769 src_start
+= src
->stride
/ 4;
1774 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1776 dst_pixel
= dst_start
;
1777 src_pixel
= src_start
;
1778 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1780 src_val
= *src_pixel
++;
1781 *dst_pixel
++ = put_field(get_field(src_val
, src
->red_shift
, src
->red_len
), dst
->red_shift
, dst
->red_len
) |
1782 put_field(get_field(src_val
, src
->green_shift
, src
->green_len
), dst
->green_shift
, dst
->green_len
) |
1783 put_field(get_field(src_val
, src
->blue_shift
, src
->blue_len
), dst
->blue_shift
, dst
->blue_len
);
1785 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1786 dst_start
+= dst
->stride
/ 4;
1787 src_start
+= src
->stride
/ 4;
1795 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1797 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1799 dst_pixel
= dst_start
;
1800 src_pixel
= src_start
;
1801 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1804 rgb
.rgbBlue
= *src_pixel
++;
1805 rgb
.rgbGreen
= *src_pixel
++;
1806 rgb
.rgbRed
= *src_pixel
++;
1808 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
1809 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
1810 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
1812 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1813 dst_start
+= dst
->stride
/ 4;
1814 src_start
+= src
->stride
;
1821 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1822 if(src
->funcs
== &funcs_555
)
1824 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1826 dst_pixel
= dst_start
;
1827 src_pixel
= src_start
;
1828 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1830 src_val
= *src_pixel
++;
1831 *dst_pixel
++ = put_field(((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07), dst
->red_shift
, dst
->red_len
) |
1832 put_field(((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07), dst
->green_shift
, dst
->green_len
) |
1833 put_field(((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
1835 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1836 dst_start
+= dst
->stride
/ 4;
1837 src_start
+= src
->stride
/ 2;
1840 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
1842 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1844 dst_pixel
= dst_start
;
1845 src_pixel
= src_start
;
1846 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1848 src_val
= *src_pixel
++;
1849 *dst_pixel
++ = put_field( (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
1850 (((src_val
>> src
->red_shift
) >> 2) & 0x07), dst
->red_shift
, dst
->red_len
) |
1851 put_field( (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
1852 (((src_val
>> src
->green_shift
) >> 2) & 0x07), dst
->green_shift
, dst
->green_len
) |
1853 put_field( (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
1854 (((src_val
>> src
->blue_shift
) >> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
1856 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1857 dst_start
+= dst
->stride
/ 4;
1858 src_start
+= src
->stride
/ 2;
1861 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
1863 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1865 dst_pixel
= dst_start
;
1866 src_pixel
= src_start
;
1867 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1869 src_val
= *src_pixel
++;
1870 *dst_pixel
++ = put_field( (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
1871 (((src_val
>> src
->red_shift
) >> 2) & 0x07), dst
->red_shift
, dst
->red_len
) |
1872 put_field( (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
1873 (((src_val
>> src
->green_shift
) >> 4) & 0x03), dst
->green_shift
, dst
->green_len
) |
1874 put_field( (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
1875 (((src_val
>> src
->blue_shift
) >> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
1877 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1878 dst_start
+= dst
->stride
/ 4;
1879 src_start
+= src
->stride
/ 2;
1884 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1886 dst_pixel
= dst_start
;
1887 src_pixel
= src_start
;
1888 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1890 src_val
= *src_pixel
++;
1891 *dst_pixel
++ = put_field(get_field(src_val
, src
->red_shift
, src
->red_len
), dst
->red_shift
, dst
->red_len
) |
1892 put_field(get_field(src_val
, src
->green_shift
, src
->green_len
), dst
->green_shift
, dst
->green_len
) |
1893 put_field(get_field(src_val
, src
->blue_shift
, src
->blue_len
), dst
->blue_shift
, dst
->blue_len
);
1895 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1896 dst_start
+= dst
->stride
/ 4;
1897 src_start
+= src
->stride
/ 2;
1905 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1906 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1908 dst_pixel
= dst_start
;
1909 src_pixel
= src_start
;
1910 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1912 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
1913 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
1914 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
1915 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
1917 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1918 dst_start
+= dst
->stride
/ 4;
1919 src_start
+= src
->stride
;
1926 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1927 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1929 dst_pixel
= dst_start
;
1930 src_pixel
= src_start
;
1931 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1935 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
1937 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
1938 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
1939 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
1940 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
1942 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1943 dst_start
+= dst
->stride
/ 4;
1944 src_start
+= src
->stride
;
1951 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1952 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1954 dst_pixel
= dst_start
;
1955 src_pixel
= src_start
;
1956 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1959 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
1960 if((x
% 8) == 7) src_pixel
++;
1961 rgb
= src
->color_table
[src_val
];
1962 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
1963 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
1964 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
1966 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1967 dst_start
+= dst
->stride
/ 4;
1968 src_start
+= src
->stride
;
1975 static void convert_to_24(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
1977 BYTE
*dst_start
= get_pixel_ptr_24(dst
, 0, 0), *dst_pixel
;
1979 int x
, y
, pad_size
= ((dst
->width
* 3 + 3) & ~3) - (src_rect
->right
- src_rect
->left
) * 3;
1981 switch(src
->bit_count
)
1985 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1986 if(src
->funcs
== &funcs_8888
)
1988 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1990 dst_pixel
= dst_start
;
1991 src_pixel
= src_start
;
1992 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1994 src_val
= *src_pixel
++;
1995 *dst_pixel
++ = src_val
& 0xff;
1996 *dst_pixel
++ = (src_val
>> 8) & 0xff;
1997 *dst_pixel
++ = (src_val
>> 16) & 0xff;
1999 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2000 dst_start
+= dst
->stride
;
2001 src_start
+= src
->stride
/ 4;
2004 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
2006 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2008 dst_pixel
= dst_start
;
2009 src_pixel
= src_start
;
2010 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2012 src_val
= *src_pixel
++;
2013 *dst_pixel
++ = (src_val
>> src
->blue_shift
) & 0xff;
2014 *dst_pixel
++ = (src_val
>> src
->green_shift
) & 0xff;
2015 *dst_pixel
++ = (src_val
>> src
->red_shift
) & 0xff;
2017 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2018 dst_start
+= dst
->stride
;
2019 src_start
+= src
->stride
/ 4;
2024 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2026 dst_pixel
= dst_start
;
2027 src_pixel
= src_start
;
2028 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2030 src_val
= *src_pixel
++;
2031 *dst_pixel
++ = get_field( src_val
, src
->blue_shift
, src
->blue_len
);
2032 *dst_pixel
++ = get_field( src_val
, src
->green_shift
, src
->green_len
);
2033 *dst_pixel
++ = get_field( src_val
, src
->red_shift
, src
->red_len
);
2035 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2036 dst_start
+= dst
->stride
;
2037 src_start
+= src
->stride
/ 4;
2045 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
);
2047 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
2048 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2051 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2053 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 3);
2054 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
) * 3, 0, pad_size
);
2055 dst_start
+= dst
->stride
;
2056 src_start
+= src
->stride
;
2064 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2065 if(src
->funcs
== &funcs_555
)
2067 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2069 dst_pixel
= dst_start
;
2070 src_pixel
= src_start
;
2071 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2073 src_val
= *src_pixel
++;
2074 *dst_pixel
++ = ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07);
2075 *dst_pixel
++ = ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07);
2076 *dst_pixel
++ = ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07);
2078 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2079 dst_start
+= dst
->stride
;
2080 src_start
+= src
->stride
/ 2;
2083 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2085 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2087 dst_pixel
= dst_start
;
2088 src_pixel
= src_start
;
2089 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2091 src_val
= *src_pixel
++;
2092 *dst_pixel
++ = (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2093 (((src_val
>> src
->blue_shift
) >> 2) & 0x07);
2094 *dst_pixel
++ = (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
2095 (((src_val
>> src
->green_shift
) >> 2) & 0x07);
2096 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2097 (((src_val
>> src
->red_shift
) >> 2) & 0x07);
2099 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2100 dst_start
+= dst
->stride
;
2101 src_start
+= src
->stride
/ 2;
2104 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2106 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2108 dst_pixel
= dst_start
;
2109 src_pixel
= src_start
;
2110 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2112 src_val
= *src_pixel
++;
2113 *dst_pixel
++ = (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2114 (((src_val
>> src
->blue_shift
) >> 2) & 0x07);
2115 *dst_pixel
++ = (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
2116 (((src_val
>> src
->green_shift
) >> 4) & 0x03);
2117 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2118 (((src_val
>> src
->red_shift
) >> 2) & 0x07);
2120 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2121 dst_start
+= dst
->stride
;
2122 src_start
+= src
->stride
/ 2;
2127 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2129 dst_pixel
= dst_start
;
2130 src_pixel
= src_start
;
2131 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2133 src_val
= *src_pixel
++;
2134 *dst_pixel
++ = get_field(src_val
, src
->blue_shift
, src
->blue_len
);
2135 *dst_pixel
++ = get_field(src_val
, src
->green_shift
, src
->green_len
);
2136 *dst_pixel
++ = get_field(src_val
, src
->red_shift
, src
->red_len
);
2138 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2139 dst_start
+= dst
->stride
;
2140 src_start
+= src
->stride
/ 2;
2148 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2149 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2151 dst_pixel
= dst_start
;
2152 src_pixel
= src_start
;
2153 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2155 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
2156 *dst_pixel
++ = rgb
.rgbBlue
;
2157 *dst_pixel
++ = rgb
.rgbGreen
;
2158 *dst_pixel
++ = rgb
.rgbRed
;
2160 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2161 dst_start
+= dst
->stride
;
2162 src_start
+= src
->stride
;
2169 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2170 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2172 dst_pixel
= dst_start
;
2173 src_pixel
= src_start
;
2174 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2178 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
2180 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
2181 *dst_pixel
++ = rgb
.rgbBlue
;
2182 *dst_pixel
++ = rgb
.rgbGreen
;
2183 *dst_pixel
++ = rgb
.rgbRed
;
2185 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2186 dst_start
+= dst
->stride
;
2187 src_start
+= src
->stride
;
2194 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2195 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2197 dst_pixel
= dst_start
;
2198 src_pixel
= src_start
;
2199 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2202 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
2203 if((x
% 8) == 7) src_pixel
++;
2204 rgb
= src
->color_table
[src_val
];
2205 *dst_pixel
++ = rgb
.rgbBlue
;
2206 *dst_pixel
++ = rgb
.rgbGreen
;
2207 *dst_pixel
++ = rgb
.rgbRed
;
2209 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2210 dst_start
+= dst
->stride
;
2211 src_start
+= src
->stride
;
2218 static void convert_to_555(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
2220 WORD
*dst_start
= get_pixel_ptr_16(dst
, 0, 0), *dst_pixel
;
2221 INT x
, y
, pad_size
= ((dst
->width
+ 1) & ~1) * 2 - (src_rect
->right
- src_rect
->left
) * 2;
2224 switch(src
->bit_count
)
2228 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2230 if(src
->funcs
== &funcs_8888
)
2232 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2234 dst_pixel
= dst_start
;
2235 src_pixel
= src_start
;
2236 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2238 src_val
= *src_pixel
++;
2239 *dst_pixel
++ = ((src_val
>> 9) & 0x7c00) |
2240 ((src_val
>> 6) & 0x03e0) |
2241 ((src_val
>> 3) & 0x001f);
2243 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2244 dst_start
+= dst
->stride
/ 2;
2245 src_start
+= src
->stride
/ 4;
2248 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
2250 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2252 dst_pixel
= dst_start
;
2253 src_pixel
= src_start
;
2254 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2256 src_val
= *src_pixel
++;
2257 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 7) & 0x7c00) |
2258 (((src_val
>> src
->green_shift
) << 2) & 0x03e0) |
2259 (((src_val
>> src
->blue_shift
) >> 3) & 0x001f);
2261 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2262 dst_start
+= dst
->stride
/ 2;
2263 src_start
+= src
->stride
/ 4;
2268 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2270 dst_pixel
= dst_start
;
2271 src_pixel
= src_start
;
2272 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2274 src_val
= *src_pixel
++;
2275 *dst_pixel
++ = (((get_field(src_val
, src
->red_shift
, src
->red_len
) << 7) & 0x7c00) |
2276 ((get_field(src_val
, src
->green_shift
, src
->green_len
) << 2) & 0x03e0) |
2277 ( get_field(src_val
, src
->blue_shift
, src
->blue_len
) >> 3));
2279 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2280 dst_start
+= dst
->stride
/ 2;
2281 src_start
+= src
->stride
/ 4;
2289 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2291 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2293 dst_pixel
= dst_start
;
2294 src_pixel
= src_start
;
2295 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2298 rgb
.rgbBlue
= *src_pixel
++;
2299 rgb
.rgbGreen
= *src_pixel
++;
2300 rgb
.rgbRed
= *src_pixel
++;
2302 *dst_pixel
++ = ((rgb
.rgbRed
<< 7) & 0x7c00) |
2303 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
2304 ((rgb
.rgbBlue
>> 3) & 0x001f);
2306 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2307 dst_start
+= dst
->stride
/ 2;
2308 src_start
+= src
->stride
;
2315 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2316 if(src
->funcs
== &funcs_555
)
2318 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
2319 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2322 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2324 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 2);
2325 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
2326 dst_start
+= dst
->stride
/ 2;
2327 src_start
+= src
->stride
/ 2;
2331 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2333 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2335 dst_pixel
= dst_start
;
2336 src_pixel
= src_start
;
2337 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2339 src_val
= *src_pixel
++;
2340 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 10) & 0x7c00) |
2341 (((src_val
>> src
->green_shift
) << 5) & 0x03e0) |
2342 ( (src_val
>> src
->blue_shift
) & 0x001f);
2344 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2345 dst_start
+= dst
->stride
/ 2;
2346 src_start
+= src
->stride
/ 2;
2349 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2351 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2353 dst_pixel
= dst_start
;
2354 src_pixel
= src_start
;
2355 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2357 src_val
= *src_pixel
++;
2358 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 10) & 0x7c00) |
2359 (((src_val
>> src
->green_shift
) << 4) & 0x03e0) |
2360 ( (src_val
>> src
->blue_shift
) & 0x001f);
2362 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2363 dst_start
+= dst
->stride
/ 2;
2364 src_start
+= src
->stride
/ 2;
2369 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2371 dst_pixel
= dst_start
;
2372 src_pixel
= src_start
;
2373 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2375 src_val
= *src_pixel
++;
2376 *dst_pixel
++ = (((get_field(src_val
, src
->red_shift
, src
->red_len
) << 7) & 0x7c00) |
2377 ((get_field(src_val
, src
->green_shift
, src
->green_len
) << 2) & 0x03e0) |
2378 ( get_field(src_val
, src
->blue_shift
, src
->blue_len
) >> 3));
2380 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2381 dst_start
+= dst
->stride
/ 2;
2382 src_start
+= src
->stride
/ 2;
2390 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2391 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2393 dst_pixel
= dst_start
;
2394 src_pixel
= src_start
;
2395 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2397 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
2398 *dst_pixel
++ = ((rgb
.rgbRed
<< 7) & 0x7c00) |
2399 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
2400 ((rgb
.rgbBlue
>> 3) & 0x001f);
2402 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2403 dst_start
+= dst
->stride
/ 2;
2404 src_start
+= src
->stride
;
2411 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2412 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2414 dst_pixel
= dst_start
;
2415 src_pixel
= src_start
;
2416 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2420 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
2422 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
2423 *dst_pixel
++ = ((rgb
.rgbRed
<< 7) & 0x7c00) |
2424 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
2425 ((rgb
.rgbBlue
>> 3) & 0x001f);
2427 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2428 dst_start
+= dst
->stride
/ 2;
2429 src_start
+= src
->stride
;
2436 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2437 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2439 dst_pixel
= dst_start
;
2440 src_pixel
= src_start
;
2441 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2444 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
2445 if((x
% 8) == 7) src_pixel
++;
2446 rgb
= src
->color_table
[src_val
];
2447 *dst_pixel
++ = ((rgb
.rgbRed
<< 7) & 0x7c00) |
2448 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
2449 ((rgb
.rgbBlue
>> 3) & 0x001f);
2451 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2452 dst_start
+= dst
->stride
/ 2;
2453 src_start
+= src
->stride
;
2460 static void convert_to_16(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
2462 WORD
*dst_start
= get_pixel_ptr_16(dst
, 0, 0), *dst_pixel
;
2463 INT x
, y
, pad_size
= ((dst
->width
+ 1) & ~1) * 2 - (src_rect
->right
- src_rect
->left
) * 2;
2466 switch(src
->bit_count
)
2470 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2472 if(src
->funcs
== &funcs_8888
)
2474 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2476 dst_pixel
= dst_start
;
2477 src_pixel
= src_start
;
2478 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2480 src_val
= *src_pixel
++;
2481 *dst_pixel
++ = put_field(src_val
>> 16, dst
->red_shift
, dst
->red_len
) |
2482 put_field(src_val
>> 8, dst
->green_shift
, dst
->green_len
) |
2483 put_field(src_val
, dst
->blue_shift
, dst
->blue_len
);
2485 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2486 dst_start
+= dst
->stride
/ 2;
2487 src_start
+= src
->stride
/ 4;
2490 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
2492 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2494 dst_pixel
= dst_start
;
2495 src_pixel
= src_start
;
2496 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2498 src_val
= *src_pixel
++;
2499 *dst_pixel
++ = put_field(src_val
>> src
->red_shift
, dst
->red_shift
, dst
->red_len
) |
2500 put_field(src_val
>> src
->green_shift
, dst
->green_shift
, dst
->green_len
) |
2501 put_field(src_val
>> src
->blue_shift
, dst
->blue_shift
, dst
->blue_len
);
2503 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2504 dst_start
+= dst
->stride
/ 2;
2505 src_start
+= src
->stride
/ 4;
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
++ = put_field(get_field(src_val
, src
->red_shift
, src
->red_len
), dst
->red_shift
, dst
->red_len
) |
2518 put_field(get_field(src_val
, src
->green_shift
, src
->green_len
), dst
->green_shift
, dst
->green_len
) |
2519 put_field(get_field(src_val
, src
->blue_shift
, src
->blue_len
), dst
->blue_shift
, dst
->blue_len
);
2521 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2522 dst_start
+= dst
->stride
/ 2;
2523 src_start
+= src
->stride
/ 4;
2531 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2533 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2535 dst_pixel
= dst_start
;
2536 src_pixel
= src_start
;
2537 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2540 rgb
.rgbBlue
= *src_pixel
++;
2541 rgb
.rgbGreen
= *src_pixel
++;
2542 rgb
.rgbRed
= *src_pixel
++;
2544 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
2545 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
2546 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
2548 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2549 dst_start
+= dst
->stride
/ 2;
2550 src_start
+= src
->stride
;
2557 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2558 if(src
->funcs
== &funcs_555
)
2560 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2562 dst_pixel
= dst_start
;
2563 src_pixel
= src_start
;
2564 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2566 src_val
= *src_pixel
++;
2567 *dst_pixel
++ = put_field(((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07), dst
->red_shift
, dst
->red_len
) |
2568 put_field(((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07), dst
->green_shift
, dst
->green_len
) |
2569 put_field(((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
2571 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2572 dst_start
+= dst
->stride
/ 2;
2573 src_start
+= src
->stride
/ 2;
2576 else if(bit_fields_match(src
, dst
))
2578 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
2579 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2582 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2584 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 2);
2585 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
2586 dst_start
+= dst
->stride
/ 2;
2587 src_start
+= src
->stride
/ 2;
2591 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2593 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2595 dst_pixel
= dst_start
;
2596 src_pixel
= src_start
;
2597 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2599 src_val
= *src_pixel
++;
2600 *dst_pixel
++ = put_field( (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2601 (((src_val
>> src
->red_shift
) >> 2) & 0x07), dst
->red_shift
, dst
->red_len
) |
2602 put_field( (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
2603 (((src_val
>> src
->green_shift
) >> 2) & 0x07), dst
->green_shift
, dst
->green_len
) |
2604 put_field( (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2605 (((src_val
>> src
->blue_shift
) >> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
2607 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2608 dst_start
+= dst
->stride
/ 2;
2609 src_start
+= src
->stride
/ 2;
2612 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2614 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2616 dst_pixel
= dst_start
;
2617 src_pixel
= src_start
;
2618 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2620 src_val
= *src_pixel
++;
2621 *dst_pixel
++ = put_field( (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2622 (((src_val
>> src
->red_shift
) >> 2) & 0x07), dst
->red_shift
, dst
->red_len
) |
2623 put_field( (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
2624 (((src_val
>> src
->green_shift
) >> 4) & 0x03), dst
->green_shift
, dst
->green_len
) |
2625 put_field( (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2626 (((src_val
>> src
->blue_shift
) >> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
2628 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2629 dst_start
+= dst
->stride
/ 2;
2630 src_start
+= src
->stride
/ 2;
2635 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2637 dst_pixel
= dst_start
;
2638 src_pixel
= src_start
;
2639 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2641 src_val
= *src_pixel
++;
2642 *dst_pixel
++ = put_field(get_field(src_val
, src
->red_shift
, src
->red_len
), dst
->red_shift
, dst
->red_len
) |
2643 put_field(get_field(src_val
, src
->green_shift
, src
->green_len
), dst
->green_shift
, dst
->green_len
) |
2644 put_field(get_field(src_val
, src
->blue_shift
, src
->blue_len
), dst
->blue_shift
, dst
->blue_len
);
2646 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2647 dst_start
+= dst
->stride
/ 2;
2648 src_start
+= src
->stride
/ 2;
2656 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2657 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2659 dst_pixel
= dst_start
;
2660 src_pixel
= src_start
;
2661 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2663 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
2664 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
2665 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
2666 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
2668 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2669 dst_start
+= dst
->stride
/ 2;
2670 src_start
+= src
->stride
;
2677 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2678 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2680 dst_pixel
= dst_start
;
2681 src_pixel
= src_start
;
2682 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2686 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
2688 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
2689 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
2690 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
2691 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
2693 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2694 dst_start
+= dst
->stride
/ 2;
2695 src_start
+= src
->stride
;
2702 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2703 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2705 dst_pixel
= dst_start
;
2706 src_pixel
= src_start
;
2707 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2710 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
2711 if((x
% 8) == 7) src_pixel
++;
2712 rgb
= src
->color_table
[src_val
];
2713 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
2714 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
2715 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
2717 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2718 dst_start
+= dst
->stride
/ 2;
2719 src_start
+= src
->stride
;
2726 static inline BOOL
color_tables_match(const dib_info
*d1
, const dib_info
*d2
)
2728 assert(d1
->color_table_size
&& d2
->color_table_size
);
2730 if(d1
->color_table_size
!= d2
->color_table_size
) return FALSE
;
2731 return !memcmp(d1
->color_table
, d2
->color_table
, d1
->color_table_size
* sizeof(d1
->color_table
[0]));
2734 static inline DWORD
rgb_lookup_colortable(const dib_info
*dst
, BYTE r
, BYTE g
, BYTE b
)
2736 /* Windows reduces precision to 5 bits, probably in order to build some sort of lookup cache */
2737 return rgb_to_pixel_colortable( dst
, (r
& ~7) + 4, (g
& ~7) + 4, (b
& ~7) + 4 );
2740 static void convert_to_8(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
2742 BYTE
*dst_start
= get_pixel_ptr_8(dst
, 0, 0), *dst_pixel
;
2743 INT x
, y
, pad_size
= ((dst
->width
+ 3) & ~3) - (src_rect
->right
- src_rect
->left
);
2746 switch(src
->bit_count
)
2750 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2752 if(src
->funcs
== &funcs_8888
)
2754 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2756 dst_pixel
= dst_start
;
2757 src_pixel
= src_start
;
2758 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2760 src_val
= *src_pixel
++;
2761 *dst_pixel
++ = rgb_lookup_colortable(dst
, src_val
>> 16, src_val
>> 8, src_val
);
2763 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2764 dst_start
+= dst
->stride
;
2765 src_start
+= src
->stride
/ 4;
2768 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
2770 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2772 dst_pixel
= dst_start
;
2773 src_pixel
= src_start
;
2774 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2776 src_val
= *src_pixel
++;
2777 *dst_pixel
++ = rgb_lookup_colortable(dst
,
2778 src_val
>> src
->red_shift
,
2779 src_val
>> src
->green_shift
,
2780 src_val
>> src
->blue_shift
);
2782 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2783 dst_start
+= dst
->stride
;
2784 src_start
+= src
->stride
/ 4;
2789 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2791 dst_pixel
= dst_start
;
2792 src_pixel
= src_start
;
2793 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2795 src_val
= *src_pixel
++;
2796 *dst_pixel
++ = rgb_lookup_colortable(dst
,
2797 get_field(src_val
, src
->red_shift
, src
->red_len
),
2798 get_field(src_val
, src
->green_shift
, src
->green_len
),
2799 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
2801 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2802 dst_start
+= dst
->stride
;
2803 src_start
+= src
->stride
/ 4;
2811 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2813 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2815 dst_pixel
= dst_start
;
2816 src_pixel
= src_start
;
2817 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, src_pixel
+= 3)
2819 *dst_pixel
++ = rgb_lookup_colortable(dst
, src_pixel
[2], src_pixel
[1], src_pixel
[0] );
2821 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2822 dst_start
+= dst
->stride
;
2823 src_start
+= src
->stride
;
2830 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2831 if(src
->funcs
== &funcs_555
)
2833 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2835 dst_pixel
= dst_start
;
2836 src_pixel
= src_start
;
2837 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2839 src_val
= *src_pixel
++;
2840 *dst_pixel
++ = rgb_lookup_colortable(dst
,
2841 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
2842 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
2843 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07) );
2845 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2846 dst_start
+= dst
->stride
;
2847 src_start
+= src
->stride
/ 2;
2850 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2852 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2854 dst_pixel
= dst_start
;
2855 src_pixel
= src_start
;
2856 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2858 src_val
= *src_pixel
++;
2859 *dst_pixel
++ = rgb_lookup_colortable(dst
,
2860 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2861 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
2862 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
2863 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
2864 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2865 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
2867 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2868 dst_start
+= dst
->stride
;
2869 src_start
+= src
->stride
/ 2;
2872 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2874 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2876 dst_pixel
= dst_start
;
2877 src_pixel
= src_start
;
2878 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2880 src_val
= *src_pixel
++;
2881 *dst_pixel
++ = rgb_lookup_colortable(dst
,
2882 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2883 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
2884 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
2885 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
2886 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2887 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
2889 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2890 dst_start
+= dst
->stride
;
2891 src_start
+= src
->stride
/ 2;
2896 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2898 dst_pixel
= dst_start
;
2899 src_pixel
= src_start
;
2900 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2902 src_val
= *src_pixel
++;
2903 *dst_pixel
++ = rgb_lookup_colortable(dst
,
2904 get_field(src_val
, src
->red_shift
, src
->red_len
),
2905 get_field(src_val
, src
->green_shift
, src
->green_len
),
2906 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
2908 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2909 dst_start
+= dst
->stride
;
2910 src_start
+= src
->stride
/ 2;
2918 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2920 if(color_tables_match(dst
, src
))
2922 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
2923 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2926 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2928 memcpy(dst_start
, src_start
, src_rect
->right
- src_rect
->left
);
2929 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
2930 dst_start
+= dst
->stride
;
2931 src_start
+= src
->stride
;
2937 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2939 dst_pixel
= dst_start
;
2940 src_pixel
= src_start
;
2941 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2943 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
2944 *dst_pixel
++ = rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
2946 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2947 dst_start
+= dst
->stride
;
2948 src_start
+= src
->stride
;
2956 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2957 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2959 dst_pixel
= dst_start
;
2960 src_pixel
= src_start
;
2961 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2965 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
2967 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
2968 *dst_pixel
++ = rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
2970 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2971 dst_start
+= dst
->stride
;
2972 src_start
+= src
->stride
;
2979 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2980 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2982 dst_pixel
= dst_start
;
2983 src_pixel
= src_start
;
2984 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2987 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
2988 if((x
% 8) == 7) src_pixel
++;
2989 rgb
= src
->color_table
[src_val
];
2990 *dst_pixel
++ = rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
2992 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2993 dst_start
+= dst
->stride
;
2994 src_start
+= src
->stride
;
3001 static void convert_to_4(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
3003 BYTE
*dst_start
= get_pixel_ptr_4(dst
, 0, 0), *dst_pixel
, dst_val
;
3004 INT x
, y
, pad_size
= ((dst
->width
+ 7) & ~7) / 2 - (src_rect
->right
- src_rect
->left
+ 1) / 2;
3007 switch(src
->bit_count
)
3011 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3013 if(src
->funcs
== &funcs_8888
)
3015 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3017 dst_pixel
= dst_start
;
3018 src_pixel
= src_start
;
3019 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3021 src_val
= *src_pixel
++;
3022 dst_val
= rgb_to_pixel_colortable(dst
, src_val
>> 16, src_val
>> 8, src_val
);
3023 if((x
- src_rect
->left
) & 1)
3025 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3029 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3033 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3034 memset(dst_pixel
, 0, pad_size
);
3036 dst_start
+= dst
->stride
;
3037 src_start
+= src
->stride
/ 4;
3040 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
3042 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3044 dst_pixel
= dst_start
;
3045 src_pixel
= src_start
;
3046 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3048 src_val
= *src_pixel
++;
3049 dst_val
= rgb_to_pixel_colortable(dst
,
3050 src_val
>> src
->red_shift
,
3051 src_val
>> src
->green_shift
,
3052 src_val
>> src
->blue_shift
);
3053 if((x
- src_rect
->left
) & 1)
3055 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3059 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3063 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3064 memset(dst_pixel
, 0, pad_size
);
3066 dst_start
+= dst
->stride
;
3067 src_start
+= src
->stride
/ 4;
3072 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3074 dst_pixel
= dst_start
;
3075 src_pixel
= src_start
;
3076 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3078 src_val
= *src_pixel
++;
3079 dst_val
= rgb_to_pixel_colortable(dst
,
3080 get_field(src_val
, src
->red_shift
, src
->red_len
),
3081 get_field(src_val
, src
->green_shift
, src
->green_len
),
3082 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3083 if((x
- src_rect
->left
) & 1)
3085 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3089 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3093 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3094 memset(dst_pixel
, 0, pad_size
);
3096 dst_start
+= dst
->stride
;
3097 src_start
+= src
->stride
/ 4;
3105 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3107 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3109 dst_pixel
= dst_start
;
3110 src_pixel
= src_start
;
3111 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, src_pixel
+= 3)
3113 dst_val
= rgb_to_pixel_colortable(dst
, src_pixel
[2], src_pixel
[1], src_pixel
[0]);
3115 if((x
- src_rect
->left
) & 1)
3117 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3121 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3125 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3126 memset(dst_pixel
, 0, pad_size
);
3128 dst_start
+= dst
->stride
;
3129 src_start
+= src
->stride
;
3136 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3137 if(src
->funcs
== &funcs_555
)
3139 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3141 dst_pixel
= dst_start
;
3142 src_pixel
= src_start
;
3143 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3145 src_val
= *src_pixel
++;
3146 dst_val
= rgb_to_pixel_colortable(dst
,
3147 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
3148 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
3149 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07) );
3150 if((x
- src_rect
->left
) & 1)
3152 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3156 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3160 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3161 memset(dst_pixel
, 0, pad_size
);
3163 dst_start
+= dst
->stride
;
3164 src_start
+= src
->stride
/ 2;
3167 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
3169 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3171 dst_pixel
= dst_start
;
3172 src_pixel
= src_start
;
3173 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3175 src_val
= *src_pixel
++;
3176 dst_val
= rgb_to_pixel_colortable(dst
,
3177 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3178 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3179 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
3180 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
3181 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3182 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
3183 if((x
- src_rect
->left
) & 1)
3185 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3189 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3193 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3194 memset(dst_pixel
, 0, pad_size
);
3196 dst_start
+= dst
->stride
;
3197 src_start
+= src
->stride
/ 2;
3200 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
3202 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3204 dst_pixel
= dst_start
;
3205 src_pixel
= src_start
;
3206 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3208 src_val
= *src_pixel
++;
3209 dst_val
= rgb_to_pixel_colortable(dst
,
3210 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3211 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3212 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
3213 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
3214 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3215 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
3216 if((x
- src_rect
->left
) & 1)
3218 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3222 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3226 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3227 memset(dst_pixel
, 0, pad_size
);
3229 dst_start
+= dst
->stride
;
3230 src_start
+= src
->stride
/ 2;
3235 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3237 dst_pixel
= dst_start
;
3238 src_pixel
= src_start
;
3239 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3241 src_val
= *src_pixel
++;
3242 dst_val
= rgb_to_pixel_colortable(dst
,
3243 get_field(src_val
, src
->red_shift
, src
->red_len
),
3244 get_field(src_val
, src
->green_shift
, src
->green_len
),
3245 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3246 if((x
- src_rect
->left
) & 1)
3248 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3252 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3256 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3257 memset(dst_pixel
, 0, pad_size
);
3259 dst_start
+= dst
->stride
;
3260 src_start
+= src
->stride
/ 2;
3268 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3270 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3272 dst_pixel
= dst_start
;
3273 src_pixel
= src_start
;
3274 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3276 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
3277 dst_val
= rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
3278 if((x
- src_rect
->left
) & 1)
3280 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3284 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3288 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3289 memset(dst_pixel
, 0, pad_size
);
3291 dst_start
+= dst
->stride
;
3292 src_start
+= src
->stride
;
3299 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3301 if(color_tables_match(dst
, src
) && (src_rect
->left
& 1) == 0)
3303 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
3304 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
3307 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3309 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
+ 1) / 2);
3310 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
+ 1) / 2, 0, pad_size
);
3311 dst_start
+= dst
->stride
;
3312 src_start
+= src
->stride
;
3318 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3320 dst_pixel
= dst_start
;
3321 src_pixel
= src_start
;
3322 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3326 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
3328 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
3329 dst_val
= rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
3330 if((x
- src_rect
->left
) & 1)
3332 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3336 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3340 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3341 memset(dst_pixel
, 0, pad_size
);
3343 dst_start
+= dst
->stride
;
3344 src_start
+= src
->stride
;
3352 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
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
++)
3360 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
3361 if((x
% 8) == 7) src_pixel
++;
3362 rgb
= src
->color_table
[src_val
];
3363 dst_val
= rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
3364 if((x
- src_rect
->left
) & 1)
3366 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3370 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3374 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3375 memset(dst_pixel
, 0, pad_size
);
3377 dst_start
+= dst
->stride
;
3378 src_start
+= src
->stride
;
3385 static void convert_to_1(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
3387 BYTE
*dst_start
= get_pixel_ptr_1(dst
, 0, 0), *dst_pixel
, dst_val
;
3388 INT x
, y
, pad_size
= ((dst
->width
+ 31) & ~31) / 8 - (src_rect
->right
- src_rect
->left
+ 7) / 8;
3392 /* FIXME: Brushes should be dithered. */
3394 switch(src
->bit_count
)
3398 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3400 if(src
->funcs
== &funcs_8888
)
3402 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3404 dst_pixel
= dst_start
;
3405 src_pixel
= src_start
;
3406 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3408 src_val
= *src_pixel
++;
3409 dst_val
= rgb_to_pixel_colortable(dst
, src_val
>> 16, src_val
>> 8, src_val
) ? 0xff : 0;
3411 if(bit_pos
== 0) *dst_pixel
= 0;
3412 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3422 if(bit_pos
!= 0) dst_pixel
++;
3423 memset(dst_pixel
, 0, pad_size
);
3425 dst_start
+= dst
->stride
;
3426 src_start
+= src
->stride
/ 4;
3429 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
3431 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3433 dst_pixel
= dst_start
;
3434 src_pixel
= src_start
;
3435 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3437 src_val
= *src_pixel
++;
3438 dst_val
= rgb_to_pixel_colortable(dst
,
3439 src_val
>> src
->red_shift
,
3440 src_val
>> src
->green_shift
,
3441 src_val
>> src
->blue_shift
) ? 0xff : 0;
3443 if(bit_pos
== 0) *dst_pixel
= 0;
3444 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3454 if(bit_pos
!= 0) dst_pixel
++;
3455 memset(dst_pixel
, 0, pad_size
);
3457 dst_start
+= dst
->stride
;
3458 src_start
+= src
->stride
/ 4;
3463 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3465 dst_pixel
= dst_start
;
3466 src_pixel
= src_start
;
3467 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3469 src_val
= *src_pixel
++;
3470 dst_val
= rgb_to_pixel_colortable(dst
,
3471 get_field(src_val
, src
->red_shift
, src
->red_len
),
3472 get_field(src_val
, src
->green_shift
, src
->green_len
),
3473 get_field(src_val
, src
->blue_shift
, src
->blue_len
)) ? 0xff : 0;
3475 if(bit_pos
== 0) *dst_pixel
= 0;
3476 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3486 if(bit_pos
!= 0) dst_pixel
++;
3487 memset(dst_pixel
, 0, pad_size
);
3489 dst_start
+= dst
->stride
;
3490 src_start
+= src
->stride
/ 4;
3498 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3500 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3502 dst_pixel
= dst_start
;
3503 src_pixel
= src_start
;
3504 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++, src_pixel
+= 3)
3506 dst_val
= rgb_to_pixel_colortable(dst
, src_pixel
[2], src_pixel
[1], src_pixel
[0]) ? 0xff : 0;
3508 if(bit_pos
== 0) *dst_pixel
= 0;
3509 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3519 if(bit_pos
!= 0) dst_pixel
++;
3520 memset(dst_pixel
, 0, pad_size
);
3522 dst_start
+= dst
->stride
;
3523 src_start
+= src
->stride
;
3530 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3531 if(src
->funcs
== &funcs_555
)
3533 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3535 dst_pixel
= dst_start
;
3536 src_pixel
= src_start
;
3537 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3539 src_val
= *src_pixel
++;
3540 dst_val
= rgb_to_pixel_colortable(dst
,
3541 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
3542 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
3543 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07) ) ? 0xff : 0;
3545 if(bit_pos
== 0) *dst_pixel
= 0;
3546 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3556 if(bit_pos
!= 0) dst_pixel
++;
3557 memset(dst_pixel
, 0, pad_size
);
3559 dst_start
+= dst
->stride
;
3560 src_start
+= src
->stride
/ 2;
3563 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
3565 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3567 dst_pixel
= dst_start
;
3568 src_pixel
= src_start
;
3569 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3571 src_val
= *src_pixel
++;
3572 dst_val
= rgb_to_pixel_colortable(dst
,
3573 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3574 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3575 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
3576 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
3577 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3578 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) ) ? 0xff : 0;
3579 if(bit_pos
== 0) *dst_pixel
= 0;
3580 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3590 if(bit_pos
!= 0) dst_pixel
++;
3591 memset(dst_pixel
, 0, pad_size
);
3593 dst_start
+= dst
->stride
;
3594 src_start
+= src
->stride
/ 2;
3597 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
3599 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3601 dst_pixel
= dst_start
;
3602 src_pixel
= src_start
;
3603 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3605 src_val
= *src_pixel
++;
3606 dst_val
= rgb_to_pixel_colortable(dst
,
3607 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3608 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3609 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
3610 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
3611 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3612 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) ) ? 0xff : 0;
3613 if(bit_pos
== 0) *dst_pixel
= 0;
3614 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3624 if(bit_pos
!= 0) dst_pixel
++;
3625 memset(dst_pixel
, 0, pad_size
);
3627 dst_start
+= dst
->stride
;
3628 src_start
+= src
->stride
/ 2;
3633 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3635 dst_pixel
= dst_start
;
3636 src_pixel
= src_start
;
3637 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3639 src_val
= *src_pixel
++;
3640 dst_val
= rgb_to_pixel_colortable(dst
,
3641 get_field(src_val
, src
->red_shift
, src
->red_len
),
3642 get_field(src_val
, src
->green_shift
, src
->green_len
),
3643 get_field(src_val
, src
->blue_shift
, src
->blue_len
)) ? 0xff : 0;
3644 if(bit_pos
== 0) *dst_pixel
= 0;
3645 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3655 if(bit_pos
!= 0) dst_pixel
++;
3656 memset(dst_pixel
, 0, pad_size
);
3658 dst_start
+= dst
->stride
;
3659 src_start
+= src
->stride
/ 2;
3667 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3669 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3671 dst_pixel
= dst_start
;
3672 src_pixel
= src_start
;
3673 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3675 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
3676 dst_val
= rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
) ? 0xff : 0;
3678 if(bit_pos
== 0) *dst_pixel
= 0;
3679 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3689 if(bit_pos
!= 0) dst_pixel
++;
3690 memset(dst_pixel
, 0, pad_size
);
3692 dst_start
+= dst
->stride
;
3693 src_start
+= src
->stride
;
3700 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3702 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3704 dst_pixel
= dst_start
;
3705 src_pixel
= src_start
;
3706 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3710 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
3712 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
3713 dst_val
= rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
) ? 0xff : 0;
3715 if(bit_pos
== 0) *dst_pixel
= 0;
3716 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3726 if(bit_pos
!= 0) dst_pixel
++;
3727 memset(dst_pixel
, 0, pad_size
);
3729 dst_start
+= dst
->stride
;
3730 src_start
+= src
->stride
;
3735 /* Note that while MSDN states that a 1 bpp dib brush -> mono dc
3736 uses text/bkgnd colours instead of the dib's colour table, this
3737 doesn't appear to be the case for a dc backed by a
3742 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3743 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3745 dst_pixel
= dst_start
;
3746 src_pixel
= src_start
;
3747 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3750 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
3751 if((x
% 8) == 7) src_pixel
++;
3752 rgb
= src
->color_table
[src_val
];
3753 dst_val
= rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
) ? 0xff : 0;
3755 if(bit_pos
== 0) *dst_pixel
= 0;
3756 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3766 if(bit_pos
!= 0) dst_pixel
++;
3767 memset(dst_pixel
, 0, pad_size
);
3769 dst_start
+= dst
->stride
;
3770 src_start
+= src
->stride
;
3777 static void convert_to_null(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
3781 static inline BYTE
blend_color(BYTE dst
, BYTE src
, DWORD alpha
)
3783 return (src
* alpha
+ dst
* (255 - alpha
) + 127) / 255;
3786 static inline DWORD
blend_argb( DWORD dst
, DWORD src
, DWORD alpha
)
3788 return (blend_color( dst
, src
, alpha
) |
3789 blend_color( dst
>> 8, src
>> 8, alpha
) << 8 |
3790 blend_color( dst
>> 16, src
>> 16, alpha
) << 16 |
3791 blend_color( dst
>> 24, src
>> 24, alpha
) << 24);
3794 static inline DWORD
blend_argb_alpha( DWORD dst
, DWORD src
, DWORD alpha
)
3796 BYTE b
= ((BYTE
)src
* alpha
+ 127) / 255;
3797 BYTE g
= ((BYTE
)(src
>> 8) * alpha
+ 127) / 255;
3798 BYTE r
= ((BYTE
)(src
>> 16) * alpha
+ 127) / 255;
3799 alpha
= ((BYTE
)(src
>> 24) * alpha
+ 127) / 255;
3800 return ((b
+ ((BYTE
)dst
* (255 - alpha
) + 127) / 255) |
3801 (g
+ ((BYTE
)(dst
>> 8) * (255 - alpha
) + 127) / 255) << 8 |
3802 (r
+ ((BYTE
)(dst
>> 16) * (255 - alpha
) + 127) / 255) << 16 |
3803 (alpha
+ ((BYTE
)(dst
>> 24) * (255 - alpha
) + 127) / 255) << 24);
3806 static inline DWORD
blend_rgb( BYTE dst_r
, BYTE dst_g
, BYTE dst_b
, DWORD src
, BLENDFUNCTION blend
)
3808 if (blend
.AlphaFormat
& AC_SRC_ALPHA
)
3810 DWORD alpha
= blend
.SourceConstantAlpha
;
3811 BYTE src_b
= ((BYTE
)src
* alpha
+ 127) / 255;
3812 BYTE src_g
= ((BYTE
)(src
>> 8) * alpha
+ 127) / 255;
3813 BYTE src_r
= ((BYTE
)(src
>> 16) * alpha
+ 127) / 255;
3814 alpha
= ((BYTE
)(src
>> 24) * alpha
+ 127) / 255;
3815 return ((src_b
+ (dst_b
* (255 - alpha
) + 127) / 255) |
3816 (src_g
+ (dst_g
* (255 - alpha
) + 127) / 255) << 8 |
3817 (src_r
+ (dst_r
* (255 - alpha
) + 127) / 255) << 16);
3819 return (blend_color( dst_b
, src
, blend
.SourceConstantAlpha
) |
3820 blend_color( dst_g
, src
>> 8, blend
.SourceConstantAlpha
) << 8 |
3821 blend_color( dst_r
, src
>> 16, blend
.SourceConstantAlpha
) << 16);
3824 static void blend_rect_8888(const dib_info
*dst
, const RECT
*rc
,
3825 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3827 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
3828 DWORD
*dst_ptr
= get_pixel_ptr_32( dst
, rc
->left
, rc
->top
);
3831 if (blend
.AlphaFormat
& AC_SRC_ALPHA
)
3832 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
3833 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3834 dst_ptr
[x
] = blend_argb_alpha( dst_ptr
[x
], src_ptr
[x
], blend
.SourceConstantAlpha
);
3836 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
3837 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3838 dst_ptr
[x
] = blend_argb( dst_ptr
[x
], src_ptr
[x
], blend
.SourceConstantAlpha
);
3841 static void blend_rect_32(const dib_info
*dst
, const RECT
*rc
,
3842 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3844 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
3845 DWORD
*dst_ptr
= get_pixel_ptr_32( dst
, rc
->left
, rc
->top
);
3848 if (dst
->red_len
== 8 && dst
->green_len
== 8 && dst
->blue_len
== 8)
3850 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
3852 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3854 DWORD val
= blend_rgb( dst_ptr
[x
] >> dst
->red_shift
,
3855 dst_ptr
[x
] >> dst
->green_shift
,
3856 dst_ptr
[x
] >> dst
->blue_shift
,
3857 src_ptr
[x
], blend
);
3858 dst_ptr
[x
] = ((( val
& 0xff) << dst
->blue_shift
) |
3859 (((val
>> 8) & 0xff) << dst
->green_shift
) |
3860 (((val
>> 16) & 0xff) << dst
->red_shift
));
3866 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
3868 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3870 DWORD val
= blend_rgb( get_field( dst_ptr
[x
], dst
->red_shift
, dst
->red_len
),
3871 get_field( dst_ptr
[x
], dst
->green_shift
, dst
->green_len
),
3872 get_field( dst_ptr
[x
], dst
->blue_shift
, dst
->blue_len
),
3873 src_ptr
[x
], blend
);
3874 dst_ptr
[x
] = (put_field( val
>> 16, dst
->red_shift
, dst
->red_len
) |
3875 put_field( val
>> 8, dst
->green_shift
, dst
->green_len
) |
3876 put_field( val
, dst
->blue_shift
, dst
->blue_len
));
3882 static void blend_rect_24(const dib_info
*dst
, const RECT
*rc
,
3883 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3885 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
3886 BYTE
*dst_ptr
= get_pixel_ptr_24( dst
, rc
->left
, rc
->top
);
3889 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
3891 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3893 DWORD val
= blend_rgb( dst_ptr
[x
* 3 + 2], dst_ptr
[x
* 3 + 1], dst_ptr
[x
* 3],
3894 src_ptr
[x
], blend
);
3895 dst_ptr
[x
* 3] = val
;
3896 dst_ptr
[x
* 3 + 1] = val
>> 8;
3897 dst_ptr
[x
* 3 + 2] = val
>> 16;
3902 static void blend_rect_555(const dib_info
*dst
, const RECT
*rc
,
3903 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3905 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
3906 WORD
*dst_ptr
= get_pixel_ptr_16( dst
, rc
->left
, rc
->top
);
3909 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 2, src_ptr
+= src
->stride
/ 4)
3911 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3913 DWORD val
= blend_rgb( ((dst_ptr
[x
] >> 7) & 0xf8) | ((dst_ptr
[x
] >> 12) & 0x07),
3914 ((dst_ptr
[x
] >> 2) & 0xf8) | ((dst_ptr
[x
] >> 7) & 0x07),
3915 ((dst_ptr
[x
] << 3) & 0xf8) | ((dst_ptr
[x
] >> 2) & 0x07),
3916 src_ptr
[x
], blend
);
3917 dst_ptr
[x
] = ((val
>> 9) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 3) & 0x001f);
3922 static void blend_rect_16(const dib_info
*dst
, const RECT
*rc
,
3923 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3925 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
3926 WORD
*dst_ptr
= get_pixel_ptr_16( dst
, rc
->left
, rc
->top
);
3929 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 2, src_ptr
+= src
->stride
/ 4)
3931 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3933 DWORD val
= blend_rgb( get_field( dst_ptr
[x
], dst
->red_shift
, dst
->red_len
),
3934 get_field( dst_ptr
[x
], dst
->green_shift
, dst
->green_len
),
3935 get_field( dst_ptr
[x
], dst
->blue_shift
, dst
->blue_len
),
3936 src_ptr
[x
], blend
);
3937 dst_ptr
[x
] = (put_field((val
>> 16), dst
->red_shift
, dst
->red_len
) |
3938 put_field((val
>> 8), dst
->green_shift
, dst
->green_len
) |
3939 put_field( val
, dst
->blue_shift
, dst
->blue_len
));
3944 static void blend_rect_8(const dib_info
*dst
, const RECT
*rc
,
3945 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3947 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
3948 BYTE
*dst_ptr
= get_pixel_ptr_8( dst
, rc
->left
, rc
->top
);
3951 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
3953 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3955 RGBQUAD rgb
= colortable_entry( dst
, dst_ptr
[x
] );
3956 DWORD val
= blend_rgb( rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
, src_ptr
[x
], blend
);
3957 dst_ptr
[x
] = rgb_lookup_colortable( dst
, val
>> 16, val
>> 8, val
);
3962 static void blend_rect_4(const dib_info
*dst
, const RECT
*rc
,
3963 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3965 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
- rc
->left
, origin
->y
);
3966 BYTE
*dst_ptr
= get_pixel_ptr_4( dst
, 0, rc
->top
);
3969 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
3971 for (x
= rc
->left
; x
< rc
->right
; x
++)
3973 DWORD val
= ((x
& 1) ? dst_ptr
[x
/ 2] : (dst_ptr
[x
/ 2] >> 4)) & 0x0f;
3974 RGBQUAD rgb
= colortable_entry( dst
, val
);
3975 val
= blend_rgb( rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
, src_ptr
[x
], blend
);
3976 val
= rgb_lookup_colortable( dst
, val
>> 16, val
>> 8, val
);
3978 dst_ptr
[x
/ 2] = val
| (dst_ptr
[x
/ 2] & 0xf0);
3980 dst_ptr
[x
/ 2] = (val
<< 4) | (dst_ptr
[x
/ 2] & 0x0f);
3985 static void blend_rect_1(const dib_info
*dst
, const RECT
*rc
,
3986 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3988 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
- rc
->left
, origin
->y
);
3989 BYTE
*dst_ptr
= get_pixel_ptr_1( dst
, 0, rc
->top
);
3992 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
3994 for (x
= rc
->left
; x
< rc
->right
; x
++)
3996 DWORD val
= (dst_ptr
[x
/ 8] & pixel_masks_1
[x
% 8]) ? 1 : 0;
3997 RGBQUAD rgb
= dst
->color_table
[val
];
3998 val
= blend_rgb( rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
, src_ptr
[x
], blend
);
3999 val
= rgb_to_pixel_colortable(dst
, val
>> 16, val
>> 8, val
) ? 0xff : 0;
4000 dst_ptr
[x
/ 8] = (dst_ptr
[x
/ 8] & ~pixel_masks_1
[x
% 8]) | (val
& pixel_masks_1
[x
% 8]);
4005 static void blend_rect_null(const dib_info
*dst
, const RECT
*rc
,
4006 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4010 static inline DWORD
gradient_rgb_8888( const TRIVERTEX
*v
, unsigned int pos
, unsigned int len
)
4013 r
= (v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 256;
4014 g
= (v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 256;
4015 b
= (v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 256;
4016 a
= (v
[0].Alpha
* (len
- pos
) + v
[1].Alpha
* pos
) / len
/ 256;
4017 return a
<< 24 | r
<< 16 | g
<< 8 | b
;
4020 static inline DWORD
gradient_rgb_24( const TRIVERTEX
*v
, unsigned int pos
, unsigned int len
)
4023 r
= (v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 256;
4024 g
= (v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 256;
4025 b
= (v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 256;
4026 return r
<< 16 | g
<< 8 | b
;
4029 static inline WORD
gradient_rgb_555( const TRIVERTEX
*v
, unsigned int pos
, unsigned int len
,
4030 unsigned int x
, unsigned int y
)
4032 int r
= (v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4033 int g
= (v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4034 int b
= (v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4035 r
= min( 31, max( 0, r
/ 16 ));
4036 g
= min( 31, max( 0, g
/ 16 ));
4037 b
= min( 31, max( 0, b
/ 16 ));
4038 return (r
<< 10) | (g
<< 5) | b
;
4041 static inline BYTE
gradient_rgb_8( const dib_info
*dib
, const TRIVERTEX
*v
,
4042 unsigned int pos
, unsigned int len
, unsigned int x
, unsigned int y
)
4044 BYTE r
= ((v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4045 BYTE g
= ((v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4046 BYTE b
= ((v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4047 return rgb_to_pixel_colortable( dib
, r
* 127, g
* 127, b
* 127 );
4050 /* compute the left/right triangle limit for row y */
4051 static inline void triangle_coords( const TRIVERTEX
*v
, const RECT
*rc
, int y
, int *left
, int *right
)
4055 if (y
< v
[1].y
) x1
= edge_coord( y
, v
[0].x
, v
[0].y
, v
[1].x
, v
[1].y
);
4056 else x1
= edge_coord( y
, v
[1].x
, v
[1].y
, v
[2].x
, v
[2].y
);
4058 x2
= edge_coord( y
, v
[0].x
, v
[0].y
, v
[2].x
, v
[2].y
);
4060 *left
= max( rc
->left
, min( x1
, x2
) );
4061 *right
= min( rc
->right
, max( x1
, x2
) );
4064 /* compute the matrix determinant for triangular barycentric coordinates (constant across the triangle) */
4065 static inline int triangle_det( const TRIVERTEX
*v
)
4067 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
);
4070 /* compute the barycentric weights for a given point inside the triangle */
4071 static inline void triangle_weights( const TRIVERTEX
*v
, int x
, int y
, INT64
*l1
, INT64
*l2
)
4073 *l1
= (v
[1].y
- v
[2].y
) * (x
- v
[2].x
) - (v
[1].x
- v
[2].x
) * (y
- v
[2].y
);
4074 *l2
= (v
[2].y
- v
[0].y
) * (x
- v
[2].x
) - (v
[2].x
- v
[0].x
) * (y
- v
[2].y
);
4077 static inline DWORD
gradient_triangle_8888( const TRIVERTEX
*v
, int x
, int y
, int det
)
4082 triangle_weights( v
, x
, y
, &l1
, &l2
);
4083 r
= (v
[0].Red
* l1
+ v
[1].Red
* l2
+ v
[2].Red
* (det
- l1
- l2
)) / det
/ 256;
4084 g
= (v
[0].Green
* l1
+ v
[1].Green
* l2
+ v
[2].Green
* (det
- l1
- l2
)) / det
/ 256;
4085 b
= (v
[0].Blue
* l1
+ v
[1].Blue
* l2
+ v
[2].Blue
* (det
- l1
- l2
)) / det
/ 256;
4086 a
= (v
[0].Alpha
* l1
+ v
[1].Alpha
* l2
+ v
[2].Alpha
* (det
- l1
- l2
)) / det
/ 256;
4087 return a
<< 24 | r
<< 16 | g
<< 8 | b
;
4090 static inline DWORD
gradient_triangle_24( const TRIVERTEX
*v
, int x
, int y
, int det
)
4095 triangle_weights( v
, x
, y
, &l1
, &l2
);
4096 r
= (v
[0].Red
* l1
+ v
[1].Red
* l2
+ v
[2].Red
* (det
- l1
- l2
)) / det
/ 256;
4097 g
= (v
[0].Green
* l1
+ v
[1].Green
* l2
+ v
[2].Green
* (det
- l1
- l2
)) / det
/ 256;
4098 b
= (v
[0].Blue
* l1
+ v
[1].Blue
* l2
+ v
[2].Blue
* (det
- l1
- l2
)) / det
/ 256;
4099 return r
<< 16 | g
<< 8 | b
;
4102 static inline DWORD
gradient_triangle_555( const TRIVERTEX
*v
, int x
, int y
, int det
)
4107 triangle_weights( v
, x
, y
, &l1
, &l2
);
4108 r
= (v
[0].Red
* l1
+ v
[1].Red
* l2
+ v
[2].Red
* (det
- l1
- l2
)) / det
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4109 g
= (v
[0].Green
* l1
+ v
[1].Green
* l2
+ v
[2].Green
* (det
- l1
- l2
)) / det
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4110 b
= (v
[0].Blue
* l1
+ v
[1].Blue
* l2
+ v
[2].Blue
* (det
- l1
- l2
)) / det
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4111 r
= min( 31, max( 0, r
/ 16 ));
4112 g
= min( 31, max( 0, g
/ 16 ));
4113 b
= min( 31, max( 0, b
/ 16 ));
4114 return (r
<< 10) | (g
<< 5) | b
;
4117 static inline DWORD
gradient_triangle_8( const dib_info
*dib
, const TRIVERTEX
*v
, int x
, int y
, int det
)
4122 triangle_weights( v
, x
, y
, &l1
, &l2
);
4123 r
= ((v
[0].Red
* l1
+ v
[1].Red
* l2
+ v
[2].Red
* (det
- l1
- l2
)) / det
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4124 g
= ((v
[0].Green
* l1
+ v
[1].Green
* l2
+ v
[2].Green
* (det
- l1
- l2
)) / det
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4125 b
= ((v
[0].Blue
* l1
+ v
[1].Blue
* l2
+ v
[2].Blue
* (det
- l1
- l2
)) / det
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4126 return rgb_to_pixel_colortable( dib
, r
* 127, g
* 127, b
* 127 );
4129 static BOOL
gradient_rect_8888( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4131 DWORD
*ptr
= get_pixel_ptr_32( dib
, 0, rc
->top
);
4132 int x
, y
, left
, right
, det
;
4136 case GRADIENT_FILL_RECT_H
:
4137 for (x
= rc
->left
; x
< rc
->right
; x
++)
4138 ptr
[x
] = gradient_rgb_8888( v
, x
- v
[0].x
, v
[1].x
- v
[0].x
);
4140 for (y
= rc
->top
+ 1, ptr
+= rc
->left
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4141 memcpy( ptr
+ dib
->stride
/ 4, ptr
, (rc
->right
- rc
->left
) * 4 );
4144 case GRADIENT_FILL_RECT_V
:
4145 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4147 DWORD val
= gradient_rgb_8888( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
4148 for (x
= rc
->left
; x
< rc
->right
; x
++) ptr
[x
] = val
;
4152 case GRADIENT_FILL_TRIANGLE
:
4153 if (!(det
= triangle_det( v
))) return FALSE
;
4154 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4156 triangle_coords( v
, rc
, y
, &left
, &right
);
4157 for (x
= left
; x
< right
; x
++) ptr
[x
] = gradient_triangle_8888( v
, x
, y
, det
);
4164 static BOOL
gradient_rect_32( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4166 DWORD
*ptr
= get_pixel_ptr_32( dib
, 0, rc
->top
);
4167 int x
, y
, left
, right
, det
;
4171 case GRADIENT_FILL_RECT_H
:
4172 if (dib
->red_len
== 8 && dib
->green_len
== 8 && dib
->blue_len
== 8)
4174 for (x
= rc
->left
; x
< rc
->right
; x
++)
4176 DWORD val
= gradient_rgb_24( v
, x
- v
[0].x
, v
[1].x
- v
[0].x
);
4177 ptr
[x
] = ((( val
& 0xff) << dib
->blue_shift
) |
4178 (((val
>> 8) & 0xff) << dib
->green_shift
) |
4179 (((val
>> 16) & 0xff) << dib
->red_shift
));
4184 for (x
= rc
->left
; x
< rc
->right
; x
++)
4186 DWORD val
= gradient_rgb_24( v
, x
- v
[0].x
, v
[1].x
- v
[0].x
);
4187 ptr
[x
] = (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
4188 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
4189 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
4193 for (y
= rc
->top
+ 1, ptr
+= rc
->left
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4194 memcpy( ptr
+ dib
->stride
/ 4, ptr
, (rc
->right
- rc
->left
) * 4 );
4197 case GRADIENT_FILL_RECT_V
:
4198 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
4200 DWORD val
= gradient_rgb_24( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
4201 if (dib
->red_len
== 8 && dib
->green_len
== 8 && dib
->blue_len
== 8)
4202 val
= ((( val
& 0xff) << dib
->blue_shift
) |
4203 (((val
>> 8) & 0xff) << dib
->green_shift
) |
4204 (((val
>> 16) & 0xff) << dib
->red_shift
));
4206 val
= (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
4207 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
4208 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
4210 for (x
= rc
->left
; x
< rc
->right
; x
++) ptr
[x
] = val
;
4211 ptr
+= dib
->stride
/ 4;
4215 case GRADIENT_FILL_TRIANGLE
:
4216 if (!(det
= triangle_det( v
))) return FALSE
;
4217 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4219 triangle_coords( v
, rc
, y
, &left
, &right
);
4221 if (dib
->red_len
== 8 && dib
->green_len
== 8 && dib
->blue_len
== 8)
4222 for (x
= left
; x
< right
; x
++)
4224 DWORD val
= gradient_triangle_24( v
, x
, y
, det
);
4225 ptr
[x
] = ((( val
& 0xff) << dib
->blue_shift
) |
4226 (((val
>> 8) & 0xff) << dib
->green_shift
) |
4227 (((val
>> 16) & 0xff) << dib
->red_shift
));
4230 for (x
= left
; x
< right
; x
++)
4232 DWORD val
= gradient_triangle_24( v
, x
, y
, det
);
4233 ptr
[x
] = (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
4234 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
4235 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
4243 static BOOL
gradient_rect_24( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4245 BYTE
*ptr
= get_pixel_ptr_24( dib
, 0, rc
->top
);
4246 int x
, y
, left
, right
, det
;
4250 case GRADIENT_FILL_RECT_H
:
4251 for (x
= rc
->left
; x
< rc
->right
; x
++)
4253 DWORD val
= gradient_rgb_24( v
, x
- v
[0].x
, v
[1].x
- v
[0].x
);
4255 ptr
[x
* 3 + 1] = val
>> 8;
4256 ptr
[x
* 3 + 2] = val
>> 16;
4259 for (y
= rc
->top
+ 1, ptr
+= rc
->left
* 3; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4260 memcpy( ptr
+ dib
->stride
, ptr
, (rc
->right
- rc
->left
) * 3 );
4263 case GRADIENT_FILL_RECT_V
:
4264 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4266 DWORD val
= gradient_rgb_24( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
4267 for (x
= rc
->left
; x
< rc
->right
; x
++)
4270 ptr
[x
* 3 + 1] = val
>> 8;
4271 ptr
[x
* 3 + 2] = val
>> 16;
4276 case GRADIENT_FILL_TRIANGLE
:
4277 if (!(det
= triangle_det( v
))) return FALSE
;
4278 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4280 triangle_coords( v
, rc
, y
, &left
, &right
);
4281 for (x
= left
; x
< right
; x
++)
4283 DWORD val
= gradient_triangle_24( v
, x
, y
, det
);
4285 ptr
[x
* 3 + 1] = val
>> 8;
4286 ptr
[x
* 3 + 2] = val
>> 16;
4294 static BOOL
gradient_rect_555( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4296 WORD
*ptr
= get_pixel_ptr_16( dib
, 0, rc
->top
);
4297 int x
, y
, left
, right
, det
;
4301 case GRADIENT_FILL_RECT_H
:
4302 for (y
= rc
->top
; y
< min( rc
->top
+ 4, rc
->bottom
); y
++, ptr
+= dib
->stride
/ 2)
4303 for (x
= rc
->left
; x
< rc
->right
; x
++)
4304 ptr
[x
] = gradient_rgb_555( v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
);
4305 for (ptr
+= rc
->left
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
4306 memcpy( ptr
, ptr
- dib
->stride
* 2, (rc
->right
- rc
->left
) * 2 );
4309 case GRADIENT_FILL_RECT_V
:
4310 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
4313 for (x
= 0; x
< 4; x
++) values
[x
] = gradient_rgb_555( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
);
4314 for (x
= rc
->left
; x
< rc
->right
; x
++) ptr
[x
] = values
[x
% 4];
4318 case GRADIENT_FILL_TRIANGLE
:
4319 if (!(det
= triangle_det( v
))) return FALSE
;
4320 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
4322 triangle_coords( v
, rc
, y
, &left
, &right
);
4323 for (x
= left
; x
< right
; x
++) ptr
[x
] = gradient_triangle_555( v
, x
, y
, det
);
4330 static BOOL
gradient_rect_16( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4332 WORD
*ptr
= get_pixel_ptr_16( dib
, 0, rc
->top
);
4333 int x
, y
, left
, right
, det
;
4337 case GRADIENT_FILL_RECT_H
:
4338 for (y
= rc
->top
; y
< min( rc
->top
+ 4, rc
->bottom
); y
++, ptr
+= dib
->stride
/ 2)
4339 for (x
= rc
->left
; x
< rc
->right
; x
++)
4341 WORD val
= gradient_rgb_555( v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
);
4342 ptr
[x
] = (put_field(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07), dib
->red_shift
, dib
->red_len
) |
4343 put_field(((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07), dib
->green_shift
, dib
->green_len
) |
4344 put_field(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07), dib
->blue_shift
, dib
->blue_len
));
4346 for (ptr
+= rc
->left
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
4347 memcpy( ptr
, ptr
- dib
->stride
* 2, (rc
->right
- rc
->left
) * 2 );
4350 case GRADIENT_FILL_RECT_V
:
4351 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
4354 for (x
= 0; x
< 4; x
++)
4356 WORD val
= gradient_rgb_555( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
);
4357 values
[x
] = (put_field(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07), dib
->red_shift
, dib
->red_len
) |
4358 put_field(((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07), dib
->green_shift
, dib
->green_len
) |
4359 put_field(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07), dib
->blue_shift
, dib
->blue_len
));
4361 for (x
= rc
->left
; x
< rc
->right
; x
++) ptr
[x
] = values
[x
% 4];
4365 case GRADIENT_FILL_TRIANGLE
:
4366 if (!(det
= triangle_det( v
))) return FALSE
;
4367 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
4369 triangle_coords( v
, rc
, y
, &left
, &right
);
4370 for (x
= left
; x
< right
; x
++)
4372 WORD val
= gradient_triangle_555( v
, x
, y
, det
);
4373 ptr
[x
] = (put_field(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07), dib
->red_shift
, dib
->red_len
) |
4374 put_field(((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07), dib
->green_shift
, dib
->green_len
) |
4375 put_field(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07), dib
->blue_shift
, dib
->blue_len
));
4383 static BOOL
gradient_rect_8( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4385 BYTE
*ptr
= get_pixel_ptr_8( dib
, 0, rc
->top
);
4386 int x
, y
, left
, right
, det
;
4390 case GRADIENT_FILL_RECT_H
:
4391 for (y
= rc
->top
; y
< min( rc
->top
+ 16, rc
->bottom
); y
++, ptr
+= dib
->stride
)
4392 for (x
= rc
->left
; x
< rc
->right
; x
++)
4393 ptr
[x
] = gradient_rgb_8( dib
, v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
);
4394 for (ptr
+= rc
->left
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4395 memcpy( ptr
, ptr
- dib
->stride
* 16, rc
->right
- rc
->left
);
4398 case GRADIENT_FILL_RECT_V
:
4399 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4402 for (x
= 0; x
< 16; x
++)
4403 values
[x
] = gradient_rgb_8( dib
, v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
);
4404 for (x
= rc
->left
; x
< rc
->right
; x
++) ptr
[x
] = values
[x
% 16];
4408 case GRADIENT_FILL_TRIANGLE
:
4409 if (!(det
= triangle_det( v
))) return FALSE
;
4410 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4412 triangle_coords( v
, rc
, y
, &left
, &right
);
4413 for (x
= left
; x
< right
; x
++) ptr
[x
] = gradient_triangle_8( dib
, v
, x
, y
, det
);
4420 static BOOL
gradient_rect_4( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4422 BYTE
*ptr
= get_pixel_ptr_4( dib
, 0, rc
->top
);
4423 int x
, y
, left
, right
, det
;
4427 case GRADIENT_FILL_RECT_H
:
4428 for (y
= rc
->top
; y
< min( rc
->top
+ 16, rc
->bottom
); y
++, ptr
+= dib
->stride
)
4430 for (x
= rc
->left
; x
< rc
->right
; x
++)
4432 BYTE val
= gradient_rgb_8( dib
, v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
);
4434 ptr
[x
/ 2] = val
| (ptr
[x
/ 2] & 0xf0);
4436 ptr
[x
/ 2] = (val
<< 4) | (ptr
[x
/ 2] & 0x0f);
4439 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4444 ptr
[x
/ 2] = (ptr
[x
/ 2 - 16 * dib
->stride
] & 0x0f) | (ptr
[x
/ 2] & 0xf0);
4447 for (; x
< rc
->right
- 1; x
+= 2) ptr
[x
/ 2] = ptr
[x
/ 2 - 16 * dib
->stride
];
4449 ptr
[x
/ 2] = (ptr
[x
/ 2] & 0x0f) | (ptr
[x
/ 2 - 16 * dib
->stride
] & 0xf0);
4453 case GRADIENT_FILL_RECT_V
:
4454 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4457 for (x
= 0; x
< 16; x
++)
4458 values
[x
] = gradient_rgb_8( dib
, v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
);
4459 for (x
= rc
->left
; x
< rc
->right
; x
++)
4461 ptr
[x
/ 2] = values
[x
% 16] | (ptr
[x
/ 2] & 0xf0);
4463 ptr
[x
/ 2] = (values
[x
% 16] << 4) | (ptr
[x
/ 2] & 0x0f);
4467 case GRADIENT_FILL_TRIANGLE
:
4468 if (!(det
= triangle_det( v
))) return FALSE
;
4469 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4471 triangle_coords( v
, rc
, y
, &left
, &right
);
4472 for (x
= left
; x
< right
; x
++)
4474 BYTE val
= gradient_triangle_8( dib
, v
, x
, y
, det
);
4476 ptr
[x
/ 2] = val
| (ptr
[x
/ 2] & 0xf0);
4478 ptr
[x
/ 2] = (val
<< 4) | (ptr
[x
/ 2] & 0x0f);
4486 static BOOL
gradient_rect_1( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4488 BYTE
*ptr
= get_pixel_ptr_1( dib
, 0, rc
->top
);
4489 int x
, y
, left
, right
, det
;
4493 case GRADIENT_FILL_RECT_H
:
4494 for (x
= rc
->left
; x
< rc
->right
; x
++)
4496 DWORD val
= gradient_rgb_24( v
, x
- v
[0].x
, v
[1].x
- v
[0].x
);
4497 val
= rgb_to_pixel_colortable( dib
, val
>> 16, val
>> 8, val
) ? 0xff : 0;
4498 ptr
[x
/ 8] = (ptr
[x
/ 8] & ~pixel_masks_1
[x
% 8]) | (val
& pixel_masks_1
[x
% 8]);
4501 for (y
= rc
->top
+ 1; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4502 for (x
= rc
->left
; x
< rc
->right
; x
++)
4503 ptr
[dib
->stride
+ x
/ 8] = (ptr
[dib
->stride
+ x
/ 8] & ~pixel_masks_1
[x
% 8]) |
4504 (ptr
[x
/ 8] & pixel_masks_1
[x
% 8]);
4507 case GRADIENT_FILL_RECT_V
:
4508 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
4510 DWORD val
= gradient_rgb_24( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
4511 val
= rgb_to_pixel_colortable( dib
, val
>> 16, val
>> 8, val
) ? 0xff : 0;
4512 for (x
= rc
->left
; x
< rc
->right
; x
++)
4513 ptr
[x
/ 8] = (ptr
[x
/ 8] & ~pixel_masks_1
[x
% 8]) | (val
& pixel_masks_1
[x
% 8]);
4518 case GRADIENT_FILL_TRIANGLE
:
4519 if (!(det
= triangle_det( v
))) return FALSE
;
4520 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4522 triangle_coords( v
, rc
, y
, &left
, &right
);
4523 for (x
= left
; x
< right
; x
++)
4525 DWORD val
= gradient_triangle_24( v
, x
, y
, det
);
4526 val
= rgb_to_pixel_colortable( dib
, val
>> 16, val
>> 8, val
) ? 0xff : 0;
4527 ptr
[x
/ 8] = (ptr
[x
/ 8] & ~pixel_masks_1
[x
% 8]) | (val
& pixel_masks_1
[x
% 8]);
4535 static BOOL
gradient_rect_null( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4540 static inline BYTE
aa_color( BYTE dst
, BYTE text
, BYTE min_comp
, BYTE max_comp
)
4542 if (dst
== text
) return dst
;
4546 DWORD diff
= dst
- text
;
4547 DWORD range
= max_comp
- text
;
4548 dst
= text
+ (diff
* range
) / (0xff - text
);
4553 DWORD diff
= text
- dst
;
4554 DWORD range
= text
- min_comp
;
4555 dst
= text
- (diff
* range
) / text
;
4560 static inline DWORD
aa_rgb( BYTE r_dst
, BYTE g_dst
, BYTE b_dst
, DWORD text
, const struct intensity_range
*range
)
4562 return (aa_color( b_dst
, text
, range
->b_min
, range
->b_max
) |
4563 aa_color( g_dst
, text
>> 8, range
->g_min
, range
->g_max
) << 8 |
4564 aa_color( r_dst
, text
>> 16, range
->r_min
, range
->r_max
) << 16);
4567 static void draw_glyph_8888( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4568 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4570 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
4571 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
4574 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4576 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
4578 if (glyph_ptr
[x
] <= 1) continue;
4579 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
4580 dst_ptr
[x
] = aa_rgb( dst_ptr
[x
] >> 16, dst_ptr
[x
] >> 8, dst_ptr
[x
], text_pixel
, ranges
+ glyph_ptr
[x
] );
4582 dst_ptr
+= dib
->stride
/ 4;
4583 glyph_ptr
+= glyph
->stride
;
4587 static void draw_glyph_32( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4588 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4590 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
4591 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
4595 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
4596 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
4597 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
4599 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4601 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
4603 if (glyph_ptr
[x
] <= 1) continue;
4604 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
4605 val
= aa_rgb( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
4606 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
4607 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
4608 text
, ranges
+ glyph_ptr
[x
] );
4609 dst_ptr
[x
] = (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
4610 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
4611 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
4613 dst_ptr
+= dib
->stride
/ 4;
4614 glyph_ptr
+= glyph
->stride
;
4618 static void draw_glyph_24( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4619 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4621 BYTE
*dst_ptr
= get_pixel_ptr_24( dib
, rect
->left
, rect
->top
);
4622 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
4626 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4628 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
4630 if (glyph_ptr
[x
] <= 1) continue;
4631 if (glyph_ptr
[x
] >= 16)
4634 val
= aa_rgb( dst_ptr
[x
* 3 + 2], dst_ptr
[x
* 3 + 1], dst_ptr
[x
* 3],
4635 text_pixel
, ranges
+ glyph_ptr
[x
] );
4636 dst_ptr
[x
* 3] = val
;
4637 dst_ptr
[x
* 3 + 1] = val
>> 8;
4638 dst_ptr
[x
* 3 + 2] = val
>> 16;
4640 dst_ptr
+= dib
->stride
;
4641 glyph_ptr
+= glyph
->stride
;
4645 static void draw_glyph_555( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4646 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4648 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
4649 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
4653 text
= ((text_pixel
<< 9) & 0xf80000) | ((text_pixel
<< 4) & 0x070000) |
4654 ((text_pixel
<< 6) & 0x00f800) | ((text_pixel
<< 1) & 0x000700) |
4655 ((text_pixel
<< 3) & 0x0000f8) | ((text_pixel
>> 2) & 0x000007);
4657 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4659 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
4661 if (glyph_ptr
[x
] <= 1) continue;
4662 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
4663 val
= aa_rgb( ((dst_ptr
[x
] >> 7) & 0xf8) | ((dst_ptr
[x
] >> 12) & 0x07),
4664 ((dst_ptr
[x
] >> 2) & 0xf8) | ((dst_ptr
[x
] >> 7) & 0x07),
4665 ((dst_ptr
[x
] << 3) & 0xf8) | ((dst_ptr
[x
] >> 2) & 0x07),
4666 text
, ranges
+ glyph_ptr
[x
] );
4667 dst_ptr
[x
] = ((val
>> 9) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 3) & 0x001f);
4669 dst_ptr
+= dib
->stride
/ 2;
4670 glyph_ptr
+= glyph
->stride
;
4674 static void draw_glyph_16( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4675 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4677 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
4678 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
4682 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
4683 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
4684 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
4686 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4688 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
4690 if (glyph_ptr
[x
] <= 1) continue;
4691 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
4692 val
= aa_rgb( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
4693 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
4694 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
4695 text
, ranges
+ glyph_ptr
[x
] );
4696 dst_ptr
[x
] = (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
4697 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
4698 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
4700 dst_ptr
+= dib
->stride
/ 2;
4701 glyph_ptr
+= glyph
->stride
;
4705 static void draw_glyph_8( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4706 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4708 BYTE
*dst_ptr
= get_pixel_ptr_8( dib
, rect
->left
, rect
->top
);
4709 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
4712 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4714 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
4716 /* no antialiasing, glyph should only contain 0 or 16. */
4717 if (glyph_ptr
[x
] >= 16)
4718 dst_ptr
[x
] = text_pixel
;
4720 dst_ptr
+= dib
->stride
;
4721 glyph_ptr
+= glyph
->stride
;
4725 static void draw_glyph_4( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4726 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4728 BYTE
*dst_ptr
= get_pixel_ptr_4( dib
, 0, rect
->top
);
4729 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
- rect
->left
, origin
->y
);
4732 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4734 for (x
= rect
->left
; x
< rect
->right
; x
++)
4736 /* no antialiasing, glyph should only contain 0 or 16. */
4737 if (glyph_ptr
[x
] >= 16)
4740 dst_ptr
[x
/ 2] = text_pixel
| (dst_ptr
[x
/ 2] & 0xf0);
4742 dst_ptr
[x
/ 2] = (text_pixel
<< 4) | (dst_ptr
[x
/ 2] & 0x0f);
4745 dst_ptr
+= dib
->stride
;
4746 glyph_ptr
+= glyph
->stride
;
4750 static void draw_glyph_1( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4751 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4753 BYTE
*dst_ptr
= get_pixel_ptr_1( dib
, 0, rect
->top
);
4754 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
- rect
->left
, origin
->y
);
4756 BYTE text
= (text_pixel
& 1) ? 0xff : 0;
4758 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4760 for (x
= rect
->left
; x
< rect
->right
; x
++)
4762 /* no antialiasing, glyph should only contain 0 or 16. */
4763 if (glyph_ptr
[x
] >= 16)
4764 dst_ptr
[x
/ 8] = (dst_ptr
[x
/ 8] & ~pixel_masks_1
[x
% 8]) | (text
& pixel_masks_1
[x
% 8]);
4766 dst_ptr
+= dib
->stride
;
4767 glyph_ptr
+= glyph
->stride
;
4771 static void draw_glyph_null( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4772 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4777 static BOOL
create_rop_masks_32(const dib_info
*dib
, const dib_info
*hatch
, const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
4779 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
4780 DWORD mask_start
= 0, mask_offset
;
4781 DWORD
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
4784 for(y
= 0; y
< hatch
->height
; y
++)
4786 hatch_ptr
= hatch_start
;
4787 mask_offset
= mask_start
;
4788 for(x
= 0; x
< hatch
->width
; x
++)
4790 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
4792 and_bits
[mask_offset
] = fg
->and;
4793 xor_bits
[mask_offset
] = fg
->xor;
4797 and_bits
[mask_offset
] = bg
->and;
4798 xor_bits
[mask_offset
] = bg
->xor;
4800 if(x
% 8 == 7) hatch_ptr
++;
4803 hatch_start
+= hatch
->stride
;
4804 mask_start
+= dib
->stride
/ 4;
4810 static BOOL
create_rop_masks_24(const dib_info
*dib
, const dib_info
*hatch
, const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
4812 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
4813 DWORD mask_start
= 0, mask_offset
;
4814 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
4817 for(y
= 0; y
< hatch
->height
; y
++)
4819 hatch_ptr
= hatch_start
;
4820 mask_offset
= mask_start
;
4821 for(x
= 0; x
< hatch
->width
; x
++)
4823 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
4825 and_bits
[mask_offset
] = fg
->and & 0xff;
4826 xor_bits
[mask_offset
++] = fg
->xor & 0xff;
4827 and_bits
[mask_offset
] = (fg
->and >> 8) & 0xff;
4828 xor_bits
[mask_offset
++] = (fg
->xor >> 8) & 0xff;
4829 and_bits
[mask_offset
] = (fg
->and >> 16) & 0xff;
4830 xor_bits
[mask_offset
++] = (fg
->xor >> 16) & 0xff;
4834 and_bits
[mask_offset
] = bg
->and & 0xff;
4835 xor_bits
[mask_offset
++] = bg
->xor & 0xff;
4836 and_bits
[mask_offset
] = (bg
->and >> 8) & 0xff;
4837 xor_bits
[mask_offset
++] = (bg
->xor >> 8) & 0xff;
4838 and_bits
[mask_offset
] = (bg
->and >> 16) & 0xff;
4839 xor_bits
[mask_offset
++] = (bg
->xor >> 16) & 0xff;
4841 if(x
% 8 == 7) hatch_ptr
++;
4843 hatch_start
+= hatch
->stride
;
4844 mask_start
+= dib
->stride
;
4850 static BOOL
create_rop_masks_16(const dib_info
*dib
, const dib_info
*hatch
, const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
4852 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
4853 DWORD mask_start
= 0, mask_offset
;
4854 WORD
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
4857 for(y
= 0; y
< hatch
->height
; y
++)
4859 hatch_ptr
= hatch_start
;
4860 mask_offset
= mask_start
;
4861 for(x
= 0; x
< hatch
->width
; x
++)
4863 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
4865 and_bits
[mask_offset
] = fg
->and;
4866 xor_bits
[mask_offset
] = fg
->xor;
4870 and_bits
[mask_offset
] = bg
->and;
4871 xor_bits
[mask_offset
] = bg
->xor;
4873 if(x
% 8 == 7) hatch_ptr
++;
4876 hatch_start
+= hatch
->stride
;
4877 mask_start
+= dib
->stride
/ 2;
4883 static BOOL
create_rop_masks_8(const dib_info
*dib
, const dib_info
*hatch
, const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
4885 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
4886 DWORD mask_start
= 0, mask_offset
;
4887 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
4890 for(y
= 0; y
< hatch
->height
; y
++)
4892 hatch_ptr
= hatch_start
;
4893 mask_offset
= mask_start
;
4894 for(x
= 0; x
< hatch
->width
; x
++)
4896 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
4898 and_bits
[mask_offset
] = fg
->and;
4899 xor_bits
[mask_offset
] = fg
->xor;
4903 and_bits
[mask_offset
] = bg
->and;
4904 xor_bits
[mask_offset
] = bg
->xor;
4906 if(x
% 8 == 7) hatch_ptr
++;
4909 hatch_start
+= hatch
->stride
;
4910 mask_start
+= dib
->stride
;
4916 static BOOL
create_rop_masks_4(const dib_info
*dib
, const dib_info
*hatch
, const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
4918 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
4919 DWORD mask_start
= 0, mask_offset
;
4920 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
4921 const rop_mask
*rop_mask
;
4924 for(y
= 0; y
< hatch
->height
; y
++)
4926 hatch_ptr
= hatch_start
;
4927 mask_offset
= mask_start
;
4928 for(x
= 0; x
< hatch
->width
; x
++)
4930 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
4937 and_bits
[mask_offset
] = (rop_mask
->and & 0x0f) | (and_bits
[mask_offset
] & 0xf0);
4938 xor_bits
[mask_offset
] = (rop_mask
->xor & 0x0f) | (xor_bits
[mask_offset
] & 0xf0);
4943 and_bits
[mask_offset
] = (rop_mask
->and << 4) & 0xf0;
4944 xor_bits
[mask_offset
] = (rop_mask
->xor << 4) & 0xf0;
4947 if(x
% 8 == 7) hatch_ptr
++;
4949 hatch_start
+= hatch
->stride
;
4950 mask_start
+= dib
->stride
;
4956 static BOOL
create_rop_masks_1(const dib_info
*dib
, const dib_info
*hatch
, const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
4958 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
4959 DWORD mask_start
= 0, mask_offset
;
4960 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
4964 for(y
= 0; y
< hatch
->height
; y
++)
4966 hatch_ptr
= hatch_start
;
4967 mask_offset
= mask_start
;
4968 for(x
= 0, bit_pos
= 0; x
< hatch
->width
; x
++)
4970 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
4972 rop_mask
.and = (fg
->and & 1) ? 0xff : 0;
4973 rop_mask
.xor = (fg
->xor & 1) ? 0xff : 0;
4977 rop_mask
.and = (bg
->and & 1) ? 0xff : 0;
4978 rop_mask
.xor = (bg
->xor & 1) ? 0xff : 0;
4981 if(bit_pos
== 0) and_bits
[mask_offset
] = xor_bits
[mask_offset
] = 0;
4983 and_bits
[mask_offset
] = (rop_mask
.and & pixel_masks_1
[bit_pos
]) | (and_bits
[mask_offset
] & ~pixel_masks_1
[bit_pos
]);
4984 xor_bits
[mask_offset
] = (rop_mask
.xor & pixel_masks_1
[bit_pos
]) | (xor_bits
[mask_offset
] & ~pixel_masks_1
[bit_pos
]);
4993 hatch_start
+= hatch
->stride
;
4994 mask_start
+= dib
->stride
;
5000 static BOOL
create_rop_masks_null(const dib_info
*dib
, const dib_info
*hatch
, const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
5005 static inline void rop_codes_from_stretch_mode( int mode
, struct rop_codes
*codes
)
5010 case STRETCH_DELETESCANS
:
5011 get_rop_codes( R2_COPYPEN
, codes
);
5013 case STRETCH_ORSCANS
:
5014 get_rop_codes( R2_MERGEPEN
, codes
);
5016 case STRETCH_ANDSCANS
:
5017 get_rop_codes( R2_MASKPEN
, codes
);
5023 static void stretch_row_32(const dib_info
*dst_dib
, const POINT
*dst_start
,
5024 const dib_info
*src_dib
, const POINT
*src_start
,
5025 const struct stretch_params
*params
, int mode
,
5028 DWORD
*dst_ptr
= get_pixel_ptr_32( dst_dib
, dst_start
->x
, dst_start
->y
);
5029 DWORD
*src_ptr
= get_pixel_ptr_32( src_dib
, src_start
->x
, src_start
->y
);
5030 int err
= params
->err_start
;
5032 struct rop_codes codes
;
5034 rop_codes_from_stretch_mode( mode
, &codes
);
5035 for (width
= params
->length
; width
; width
--)
5037 do_rop_codes_32( dst_ptr
, *src_ptr
, &codes
);
5038 dst_ptr
+= params
->dst_inc
;
5041 src_ptr
+= params
->src_inc
;
5042 err
+= params
->err_add_1
;
5044 else err
+= params
->err_add_2
;
5048 static void stretch_row_24(const dib_info
*dst_dib
, const POINT
*dst_start
,
5049 const dib_info
*src_dib
, const POINT
*src_start
,
5050 const struct stretch_params
*params
, int mode
,
5053 BYTE
*dst_ptr
= get_pixel_ptr_24( dst_dib
, dst_start
->x
, dst_start
->y
);
5054 BYTE
*src_ptr
= get_pixel_ptr_24( src_dib
, src_start
->x
, src_start
->y
);
5055 int err
= params
->err_start
;
5057 struct rop_codes codes
;
5059 rop_codes_from_stretch_mode( mode
, &codes
);
5060 for (width
= params
->length
; width
; width
--)
5062 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
5063 do_rop_codes_8( dst_ptr
+ 1, *(src_ptr
+ 1), &codes
);
5064 do_rop_codes_8( dst_ptr
+ 2, *(src_ptr
+ 2), &codes
);
5065 dst_ptr
+= 3 * params
->dst_inc
;
5068 src_ptr
+= 3 * params
->src_inc
;
5069 err
+= params
->err_add_1
;
5071 else err
+= params
->err_add_2
;
5075 static void stretch_row_16(const dib_info
*dst_dib
, const POINT
*dst_start
,
5076 const dib_info
*src_dib
, const POINT
*src_start
,
5077 const struct stretch_params
*params
, int mode
,
5080 WORD
*dst_ptr
= get_pixel_ptr_16( dst_dib
, dst_start
->x
, dst_start
->y
);
5081 WORD
*src_ptr
= get_pixel_ptr_16( src_dib
, src_start
->x
, src_start
->y
);
5082 int err
= params
->err_start
;
5084 struct rop_codes codes
;
5086 rop_codes_from_stretch_mode( mode
, &codes
);
5087 for (width
= params
->length
; width
; width
--)
5089 do_rop_codes_16( dst_ptr
, *src_ptr
, &codes
);
5090 dst_ptr
+= params
->dst_inc
;
5093 src_ptr
+= params
->src_inc
;
5094 err
+= params
->err_add_1
;
5096 else err
+= params
->err_add_2
;
5100 static void stretch_row_8(const dib_info
*dst_dib
, const POINT
*dst_start
,
5101 const dib_info
*src_dib
, const POINT
*src_start
,
5102 const struct stretch_params
*params
, int mode
,
5105 BYTE
*dst_ptr
= get_pixel_ptr_8( dst_dib
, dst_start
->x
, dst_start
->y
);
5106 BYTE
*src_ptr
= get_pixel_ptr_8( src_dib
, src_start
->x
, src_start
->y
);
5107 int err
= params
->err_start
;
5109 struct rop_codes codes
;
5111 rop_codes_from_stretch_mode( mode
, &codes
);
5112 for (width
= params
->length
; width
; width
--)
5114 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
5115 dst_ptr
+= params
->dst_inc
;
5118 src_ptr
+= params
->src_inc
;
5119 err
+= params
->err_add_1
;
5121 else err
+= params
->err_add_2
;
5125 static void stretch_row_4(const dib_info
*dst_dib
, const POINT
*dst_start
,
5126 const dib_info
*src_dib
, const POINT
*src_start
,
5127 const struct stretch_params
*params
, int mode
,
5130 BYTE
*dst_ptr
= get_pixel_ptr_4( dst_dib
, dst_start
->x
, dst_start
->y
);
5131 BYTE
*src_ptr
= get_pixel_ptr_4( src_dib
, src_start
->x
, src_start
->y
);
5132 int err
= params
->err_start
;
5133 int width
, dst_x
= dst_start
->x
, src_x
= src_start
->x
;
5134 struct rop_codes codes
;
5137 rop_codes_from_stretch_mode( mode
, &codes
);
5138 for (width
= params
->length
; width
; width
--)
5140 if (src_x
& 1) src_val
= (*src_ptr
& 0x0f) | (*src_ptr
<< 4);
5141 else src_val
= (*src_ptr
& 0xf0) | (*src_ptr
>> 4);
5143 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, (dst_x
& 1) ? 0x0f : 0xf0 );
5145 if ((dst_x
& ~1) != ((dst_x
+ params
->dst_inc
) & ~1))
5146 dst_ptr
+= params
->dst_inc
;
5147 dst_x
+= params
->dst_inc
;
5151 if ((src_x
& ~1) != ((src_x
+ params
->src_inc
) & ~1))
5152 src_ptr
+= params
->src_inc
;
5153 src_x
+= params
->src_inc
;
5154 err
+= params
->err_add_1
;
5156 else err
+= params
->err_add_2
;
5160 static void stretch_row_1(const dib_info
*dst_dib
, const POINT
*dst_start
,
5161 const dib_info
*src_dib
, const POINT
*src_start
,
5162 const struct stretch_params
*params
, int mode
,
5165 BYTE
*dst_ptr
= get_pixel_ptr_1( dst_dib
, dst_start
->x
, dst_start
->y
);
5166 BYTE
*src_ptr
= get_pixel_ptr_1( src_dib
, src_start
->x
, src_start
->y
);
5167 int err
= params
->err_start
;
5168 int width
, dst_x
= dst_start
->x
, src_x
= src_start
->x
;
5169 struct rop_codes codes
;
5172 rop_codes_from_stretch_mode( mode
, &codes
);
5173 for (width
= params
->length
; width
; width
--)
5175 src_val
= *src_ptr
& pixel_masks_1
[src_x
% 8] ? 0xff : 0;
5176 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, pixel_masks_1
[dst_x
% 8] );
5178 if ((dst_x
& ~7) != ((dst_x
+ params
->dst_inc
) & ~7))
5179 dst_ptr
+= params
->dst_inc
;
5180 dst_x
+= params
->dst_inc
;
5184 if ((src_x
& ~7) != ((src_x
+ params
->src_inc
) & ~7))
5185 src_ptr
+= params
->src_inc
;
5186 src_x
+= params
->src_inc
;
5187 err
+= params
->err_add_1
;
5189 else err
+= params
->err_add_2
;
5193 static void stretch_row_null(const dib_info
*dst_dib
, const POINT
*dst_start
,
5194 const dib_info
*src_dib
, const POINT
*src_start
,
5195 const struct stretch_params
*params
, int mode
,
5198 FIXME("bit count %d\n", dst_dib
->bit_count
);
5202 static void shrink_row_32(const dib_info
*dst_dib
, const POINT
*dst_start
,
5203 const dib_info
*src_dib
, const POINT
*src_start
,
5204 const struct stretch_params
*params
, int mode
,
5207 DWORD
*dst_ptr
= get_pixel_ptr_32( dst_dib
, dst_start
->x
, dst_start
->y
);
5208 DWORD
*src_ptr
= get_pixel_ptr_32( src_dib
, src_start
->x
, src_start
->y
);
5209 int err
= params
->err_start
;
5211 struct rop_codes codes
;
5212 DWORD init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
5213 BOOL new_pix
= TRUE
;
5215 rop_codes_from_stretch_mode( mode
, &codes
);
5216 for (width
= params
->length
; width
; width
--)
5218 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
5219 do_rop_codes_32( dst_ptr
, *src_ptr
, &codes
);
5221 src_ptr
+= params
->src_inc
;
5224 dst_ptr
+= params
->dst_inc
;
5226 err
+= params
->err_add_1
;
5228 else err
+= params
->err_add_2
;
5232 static void shrink_row_24(const dib_info
*dst_dib
, const POINT
*dst_start
,
5233 const dib_info
*src_dib
, const POINT
*src_start
,
5234 const struct stretch_params
*params
, int mode
,
5237 BYTE
*dst_ptr
= get_pixel_ptr_24( dst_dib
, dst_start
->x
, dst_start
->y
);
5238 BYTE
*src_ptr
= get_pixel_ptr_24( src_dib
, src_start
->x
, src_start
->y
);
5239 int err
= params
->err_start
;
5241 struct rop_codes codes
;
5242 BYTE init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
5243 BOOL new_pix
= TRUE
;
5245 rop_codes_from_stretch_mode( mode
, &codes
);
5246 for (width
= params
->length
; width
; width
--)
5248 if (new_pix
&& !keep_dst
) memset( dst_ptr
, init_val
, 3 );
5249 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
5250 do_rop_codes_8( dst_ptr
+ 1, *(src_ptr
+ 1), &codes
);
5251 do_rop_codes_8( dst_ptr
+ 2, *(src_ptr
+ 2), &codes
);
5253 src_ptr
+= 3 * params
->src_inc
;
5256 dst_ptr
+= 3 * params
->dst_inc
;
5258 err
+= params
->err_add_1
;
5260 else err
+= params
->err_add_2
;
5264 static void shrink_row_16(const dib_info
*dst_dib
, const POINT
*dst_start
,
5265 const dib_info
*src_dib
, const POINT
*src_start
,
5266 const struct stretch_params
*params
, int mode
,
5269 WORD
*dst_ptr
= get_pixel_ptr_16( dst_dib
, dst_start
->x
, dst_start
->y
);
5270 WORD
*src_ptr
= get_pixel_ptr_16( src_dib
, src_start
->x
, src_start
->y
);
5271 int err
= params
->err_start
;
5273 struct rop_codes codes
;
5274 WORD init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
5275 BOOL new_pix
= TRUE
;
5277 rop_codes_from_stretch_mode( mode
, &codes
);
5278 for (width
= params
->length
; width
; width
--)
5280 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
5281 do_rop_codes_16( dst_ptr
, *src_ptr
, &codes
);
5283 src_ptr
+= params
->src_inc
;
5286 dst_ptr
+= params
->dst_inc
;
5288 err
+= params
->err_add_1
;
5290 else err
+= params
->err_add_2
;
5294 static void shrink_row_8(const dib_info
*dst_dib
, const POINT
*dst_start
,
5295 const dib_info
*src_dib
, const POINT
*src_start
,
5296 const struct stretch_params
*params
, int mode
,
5299 BYTE
*dst_ptr
= get_pixel_ptr_8( dst_dib
, dst_start
->x
, dst_start
->y
);
5300 BYTE
*src_ptr
= get_pixel_ptr_8( src_dib
, src_start
->x
, src_start
->y
);
5301 int err
= params
->err_start
;
5303 struct rop_codes codes
;
5304 BYTE init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
5305 BOOL new_pix
= TRUE
;
5307 rop_codes_from_stretch_mode( mode
, &codes
);
5308 for (width
= params
->length
; width
; width
--)
5310 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
5311 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
5313 src_ptr
+= params
->src_inc
;
5316 dst_ptr
+= params
->dst_inc
;
5318 err
+= params
->err_add_1
;
5320 else err
+= params
->err_add_2
;
5324 static void shrink_row_4(const dib_info
*dst_dib
, const POINT
*dst_start
,
5325 const dib_info
*src_dib
, const POINT
*src_start
,
5326 const struct stretch_params
*params
, int mode
,
5329 BYTE
*dst_ptr
= get_pixel_ptr_8( dst_dib
, dst_start
->x
, dst_start
->y
);
5330 BYTE
*src_ptr
= get_pixel_ptr_8( src_dib
, src_start
->x
, src_start
->y
);
5331 int err
= params
->err_start
;
5332 int width
, dst_x
= dst_start
->x
, src_x
= src_start
->x
;
5333 struct rop_codes codes
;
5334 BYTE src_val
, init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
5335 BOOL new_pix
= TRUE
;
5337 rop_codes_from_stretch_mode( mode
, &codes
);
5338 for (width
= params
->length
; width
; width
--)
5340 if (new_pix
&& !keep_dst
) do_rop_mask_8( dst_ptr
, 0, init_val
, (dst_x
& 1) ? 0xf0 : 0x0f );
5342 if (src_x
& 1) src_val
= (*src_ptr
& 0x0f) | (*src_ptr
<< 4);
5343 else src_val
= (*src_ptr
& 0xf0) | (*src_ptr
>> 4);
5345 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, (dst_x
& 1) ? 0xf0 : 0x0f );
5348 if ((src_x
& ~1) != ((src_x
+ params
->src_inc
) & ~1))
5349 src_ptr
+= params
->src_inc
;
5350 src_x
+= params
->src_inc
;
5354 if ((dst_x
& ~1) != ((dst_x
+ params
->dst_inc
) & ~1))
5355 dst_ptr
+= params
->dst_inc
;
5356 dst_x
+= params
->dst_inc
;
5358 err
+= params
->err_add_1
;
5360 else err
+= params
->err_add_2
;
5364 static void shrink_row_1(const dib_info
*dst_dib
, const POINT
*dst_start
,
5365 const dib_info
*src_dib
, const POINT
*src_start
,
5366 const struct stretch_params
*params
, int mode
,
5369 BYTE
*dst_ptr
= get_pixel_ptr_1( dst_dib
, dst_start
->x
, dst_start
->y
);
5370 BYTE
*src_ptr
= get_pixel_ptr_1( src_dib
, src_start
->x
, src_start
->y
);
5371 int err
= params
->err_start
;
5372 int width
, dst_x
= dst_start
->x
, src_x
= src_start
->x
;
5373 struct rop_codes codes
;
5374 BYTE src_val
, init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
5375 BOOL new_pix
= TRUE
;
5377 rop_codes_from_stretch_mode( mode
, &codes
);
5378 for (width
= params
->length
; width
; width
--)
5380 if (new_pix
&& !keep_dst
) do_rop_mask_8( dst_ptr
, 0, init_val
, pixel_masks_1
[dst_x
% 8] );
5381 src_val
= *src_ptr
& pixel_masks_1
[src_x
% 8] ? 0xff : 0;
5382 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, pixel_masks_1
[dst_x
% 8] );
5385 if ((src_x
& ~7) != ((src_x
+ params
->src_inc
) & ~7))
5386 src_ptr
+= params
->src_inc
;
5387 src_x
+= params
->src_inc
;
5391 if ((dst_x
& ~7) != ((dst_x
+ params
->dst_inc
) & ~7))
5392 dst_ptr
+= params
->dst_inc
;
5393 dst_x
+= params
->dst_inc
;
5395 err
+= params
->err_add_1
;
5397 else err
+= params
->err_add_2
;
5401 static void shrink_row_null(const dib_info
*dst_dib
, const POINT
*dst_start
,
5402 const dib_info
*src_dib
, const POINT
*src_start
,
5403 const struct stretch_params
*params
, int mode
,
5406 FIXME("bit count %d\n", dst_dib
->bit_count
);
5410 const primitive_funcs funcs_8888
=
5420 colorref_to_pixel_888
,
5421 pixel_to_colorref_888
,
5423 create_rop_masks_32
,
5428 const primitive_funcs funcs_32
=
5438 colorref_to_pixel_masks
,
5439 pixel_to_colorref_masks
,
5441 create_rop_masks_32
,
5446 const primitive_funcs funcs_24
=
5456 colorref_to_pixel_888
,
5457 pixel_to_colorref_888
,
5459 create_rop_masks_24
,
5464 const primitive_funcs funcs_555
=
5474 colorref_to_pixel_555
,
5475 pixel_to_colorref_555
,
5477 create_rop_masks_16
,
5482 const primitive_funcs funcs_16
=
5492 colorref_to_pixel_masks
,
5493 pixel_to_colorref_masks
,
5495 create_rop_masks_16
,
5500 const primitive_funcs funcs_8
=
5510 colorref_to_pixel_colortable
,
5511 pixel_to_colorref_colortable
,
5518 const primitive_funcs funcs_4
=
5528 colorref_to_pixel_colortable
,
5529 pixel_to_colorref_colortable
,
5536 const primitive_funcs funcs_1
=
5546 colorref_to_pixel_colortable
,
5547 pixel_to_colorref_colortable
,
5554 const primitive_funcs funcs_null
=
5564 colorref_to_pixel_null
,
5565 pixel_to_colorref_null
,
5567 create_rop_masks_null
,