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
+ (dib
->rect
.top
+ y
) * dib
->stride
+ (dib
->rect
.left
+ 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
+ (dib
->rect
.top
+ y
) * dib
->stride
) + (dib
->rect
.left
+ 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
+ (dib
->rect
.top
+ y
) * dib
->stride
+ (dib
->rect
.left
+ 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
+ (dib
->rect
.top
+ y
) * dib
->stride
+ (dib
->rect
.left
+ x
) * 2);
80 static inline BYTE
*get_pixel_ptr_8(const dib_info
*dib
, int x
, int y
)
82 return (BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
+ dib
->rect
.left
+ x
;
85 static inline BYTE
*get_pixel_ptr_4(const dib_info
*dib
, int x
, int y
)
87 return (BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
+ (dib
->rect
.left
+ x
) / 2;
90 static inline BYTE
*get_pixel_ptr_1(const dib_info
*dib
, int x
, int y
)
92 return (BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
+ (dib
->rect
.left
+ 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 int left
= dib
->rect
.left
+ rc
->left
;
278 int right
= dib
->rect
.left
+ rc
->right
;
280 if (left
>= right
) continue;
282 if ((left
& ~3) == (right
& ~3)) /* Special case for lines that start and end in the same DWORD triplet */
284 byte_start
= get_pixel_ptr_24(dib
, rc
->left
, rc
->top
);
285 for(y
= rc
->top
; y
< rc
->bottom
; y
++, byte_start
+= dib
->stride
)
287 for(x
= left
, byte_ptr
= byte_start
; x
< right
; x
++)
289 do_rop_8(byte_ptr
++, and_masks
[0] & 0xff, xor_masks
[0] & 0xff);
290 do_rop_8(byte_ptr
++, and_masks
[1] & 0xff, xor_masks
[1] & 0xff);
291 do_rop_8(byte_ptr
++, and_masks
[2] & 0xff, xor_masks
[2] & 0xff);
297 start
= get_pixel_ptr_24_dword(dib
, rc
->left
, rc
->top
);
298 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
305 do_rop_32(ptr
++, and_masks
[0] | 0x00ffffff, xor_masks
[0] & 0xff000000);
306 do_rop_32(ptr
++, and_masks
[1], xor_masks
[1]);
307 do_rop_32(ptr
++, and_masks
[2], xor_masks
[2]);
310 do_rop_32(ptr
++, and_masks
[1] | 0x0000ffff, xor_masks
[1] & 0xffff0000);
311 do_rop_32(ptr
++, and_masks
[2], xor_masks
[2]);
314 do_rop_32(ptr
++, and_masks
[2] | 0x000000ff, xor_masks
[2] & 0xffffff00);
318 for(x
= (left
+ 3) & ~3; x
< (right
& ~3); x
+= 4)
320 do_rop_32(ptr
++, and_masks
[0], xor_masks
[0]);
321 do_rop_32(ptr
++, and_masks
[1], xor_masks
[1]);
322 do_rop_32(ptr
++, and_masks
[2], xor_masks
[2]);
328 do_rop_32(ptr
, and_masks
[0] | 0xff000000, xor_masks
[0] & 0x00ffffff);
331 do_rop_32(ptr
++, and_masks
[0], xor_masks
[0]);
332 do_rop_32(ptr
, and_masks
[1] | 0xffff0000, xor_masks
[1] & 0x0000ffff);
335 do_rop_32(ptr
++, and_masks
[0], xor_masks
[0]);
336 do_rop_32(ptr
++, and_masks
[1], xor_masks
[1]);
337 do_rop_32(ptr
, and_masks
[2] | 0xffffff00, xor_masks
[2] & 0x000000ff);
345 static void solid_rects_16(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
350 for(i
= 0; i
< num
; i
++, rc
++)
352 start
= get_pixel_ptr_16(dib
, rc
->left
, rc
->top
);
353 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 2)
354 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
355 do_rop_16(ptr
++, and, xor);
359 static void solid_rects_8(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
364 for(i
= 0; i
< num
; i
++, rc
++)
366 start
= get_pixel_ptr_8(dib
, rc
->left
, rc
->top
);
367 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
368 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
369 do_rop_8(ptr
++, and, xor);
373 static void solid_rects_4(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
377 BYTE byte_and
= (and & 0xf) | ((and << 4) & 0xf0);
378 BYTE byte_xor
= (xor & 0xf) | ((xor << 4) & 0xf0);
380 for(i
= 0; i
< num
; i
++, rc
++)
382 int left
= dib
->rect
.left
+ rc
->left
;
383 int right
= dib
->rect
.left
+ rc
->right
;
385 if (left
>= right
) continue;
386 start
= get_pixel_ptr_4(dib
, rc
->left
, rc
->top
);
387 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
390 if(left
& 1) /* upper nibble untouched */
391 do_rop_8(ptr
++, byte_and
| 0xf0, byte_xor
& 0x0f);
393 for(x
= (left
+ 1) & ~1; x
< (right
& ~1); x
+= 2)
394 do_rop_8(ptr
++, byte_and
, byte_xor
);
396 if(right
& 1) /* lower nibble untouched */
397 do_rop_8(ptr
, byte_and
| 0x0f, byte_xor
& 0xf0);
402 static void solid_rects_1(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
406 BYTE byte_and
= (and & 1) ? 0xff : 0;
407 BYTE byte_xor
= (xor & 1) ? 0xff : 0;
408 BYTE start_and
, start_xor
, end_and
, end_xor
, mask
;
409 static const BYTE masks
[8] = {0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01};
411 for(i
= 0; i
< num
; i
++, rc
++)
413 int left
= dib
->rect
.left
+ rc
->left
;
414 int right
= dib
->rect
.left
+ rc
->right
;
416 if (left
>= right
) continue;
418 start
= get_pixel_ptr_1(dib
, rc
->left
, rc
->top
);
420 if ((left
& ~7) == (right
& ~7)) /* Special case for lines that start and end in the same byte */
422 mask
= masks
[left
& 7] & ~masks
[right
& 7];
424 start_and
= byte_and
| ~mask
;
425 start_xor
= byte_xor
& mask
;
426 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
428 do_rop_8(start
, start_and
, start_xor
);
433 mask
= masks
[left
& 7];
434 start_and
= byte_and
| ~mask
;
435 start_xor
= byte_xor
& mask
;
437 mask
= masks
[right
& 7];
438 /* This is inverted wrt to start mask, so end_and/xor assignments reflect this */
439 end_and
= byte_and
| mask
;
440 end_xor
= byte_xor
& ~mask
;
442 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
447 do_rop_8(ptr
++, start_and
, start_xor
);
449 for(x
= (left
+ 7) & ~7; x
< (right
& ~7); x
+= 8)
450 do_rop_8(ptr
++, byte_and
, byte_xor
);
453 do_rop_8(ptr
, end_and
, end_xor
);
459 static void solid_rects_null(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
464 static void solid_line_32(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
465 DWORD
and, DWORD
xor)
467 DWORD
*ptr
= get_pixel_ptr_32( dib
, start
->x
, start
->y
);
468 int len
= params
->length
, err
= params
->err_start
;
469 int major_inc
, minor_inc
;
473 major_inc
= params
->x_inc
;
474 minor_inc
= (dib
->stride
* params
->y_inc
) / 4;
478 major_inc
= (dib
->stride
* params
->y_inc
) / 4;
479 minor_inc
= params
->x_inc
;
484 do_rop_32( ptr
, and, xor );
485 if (err
+ params
->bias
> 0)
488 err
+= params
->err_add_1
;
490 else err
+= params
->err_add_2
;
495 static void solid_line_24(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
496 DWORD
and, DWORD
xor)
498 BYTE
*ptr
= get_pixel_ptr_24( dib
, start
->x
, start
->y
);
499 int len
= params
->length
, err
= params
->err_start
;
500 int major_inc
, minor_inc
;
504 major_inc
= params
->x_inc
* 3;
505 minor_inc
= dib
->stride
* params
->y_inc
;
509 major_inc
= dib
->stride
* params
->y_inc
;
510 minor_inc
= params
->x_inc
* 3;
515 do_rop_8( ptr
, and, xor );
516 do_rop_8( ptr
+ 1, and >> 8, xor >> 8 );
517 do_rop_8( ptr
+ 2, and >> 16, xor >> 16 );
518 if (err
+ params
->bias
> 0)
521 err
+= params
->err_add_1
;
523 else err
+= params
->err_add_2
;
528 static void solid_line_16(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
529 DWORD
and, DWORD
xor)
531 WORD
*ptr
= get_pixel_ptr_16( dib
, start
->x
, start
->y
);
532 int len
= params
->length
, err
= params
->err_start
;
533 int major_inc
, minor_inc
;
537 major_inc
= params
->x_inc
;
538 minor_inc
= (dib
->stride
* params
->y_inc
) / 2;
542 major_inc
= (dib
->stride
* params
->y_inc
) / 2;
543 minor_inc
= params
->x_inc
;
548 do_rop_16( ptr
, and, xor );
549 if (err
+ params
->bias
> 0)
552 err
+= params
->err_add_1
;
554 else err
+= params
->err_add_2
;
559 static void solid_line_8(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
560 DWORD
and, DWORD
xor)
562 BYTE
*ptr
= get_pixel_ptr_8( dib
, start
->x
, start
->y
);
563 int len
= params
->length
, err
= params
->err_start
;
564 int major_inc
, minor_inc
;
568 major_inc
= params
->x_inc
;
569 minor_inc
= dib
->stride
* params
->y_inc
;
573 major_inc
= dib
->stride
* params
->y_inc
;
574 minor_inc
= params
->x_inc
;
579 do_rop_8( ptr
, and, xor );
580 if (err
+ params
->bias
> 0)
583 err
+= params
->err_add_1
;
585 else err
+= params
->err_add_2
;
590 static void solid_line_4(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
591 DWORD
and, DWORD
xor)
593 BYTE
*ptr
= get_pixel_ptr_4( dib
, start
->x
, start
->y
);
594 int len
= params
->length
, err
= params
->err_start
;
595 int x
= dib
->rect
.left
+ start
->x
;
597 and = (and & 0x0f) | ((and << 4) & 0xf0);
598 xor = (xor & 0x0f) | ((xor << 4) & 0xf0);
604 do_rop_mask_8( ptr
, and, xor, pixel_masks_4
[ x
% 2 ] );
605 if (err
+ params
->bias
> 0)
607 ptr
+= dib
->stride
* params
->y_inc
;
608 err
+= params
->err_add_1
;
610 else err
+= params
->err_add_2
;
611 if ((x
/ 2) != ((x
+ params
->x_inc
) / 2))
612 ptr
+= params
->x_inc
;
620 do_rop_mask_8( ptr
, and, xor, pixel_masks_4
[ x
% 2 ] );
621 if (err
+ params
->bias
> 0)
623 if ((x
/ 2) != ((x
+ params
->x_inc
) / 2))
624 ptr
+= params
->x_inc
;
626 err
+= params
->err_add_1
;
628 else err
+= params
->err_add_2
;
629 ptr
+= dib
->stride
* params
->y_inc
;
634 static void solid_line_1(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
635 DWORD
and, DWORD
xor)
637 BYTE
*ptr
= get_pixel_ptr_1( dib
, start
->x
, start
->y
);
638 int len
= params
->length
, err
= params
->err_start
;
639 int x
= dib
->rect
.left
+ start
->x
;
641 and = (and & 0x1) ? 0xff : 0;
642 xor = (xor & 0x1) ? 0xff : 0;
648 do_rop_mask_8( ptr
, and, xor, pixel_masks_1
[ x
% 8 ] );
649 if (err
+ params
->bias
> 0)
651 ptr
+= dib
->stride
* params
->y_inc
;
652 err
+= params
->err_add_1
;
654 else err
+= params
->err_add_2
;
655 if ((x
/ 8) != ((x
+ params
->x_inc
) / 8))
656 ptr
+= params
->x_inc
;
664 do_rop_mask_8( ptr
, and, xor, pixel_masks_1
[ x
% 8 ] );
665 if (err
+ params
->bias
> 0)
667 if ((x
/ 8) != ((x
+ params
->x_inc
) / 8))
668 ptr
+= params
->x_inc
;
670 err
+= params
->err_add_1
;
672 else err
+= params
->err_add_2
;
673 ptr
+= dib
->stride
* params
->y_inc
;
678 static void solid_line_null(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
679 DWORD
and, DWORD
xor)
684 static inline INT
calc_offset(INT edge
, INT size
, INT origin
)
688 if(edge
- origin
>= 0)
689 offset
= (edge
- origin
) % size
;
692 offset
= (origin
- edge
) % size
;
693 if(offset
) offset
= size
- offset
;
698 static inline POINT
calc_brush_offset(const RECT
*rc
, const dib_info
*brush
, const POINT
*origin
)
702 offset
.x
= calc_offset(rc
->left
, brush
->width
, origin
->x
);
703 offset
.y
= calc_offset(rc
->top
, brush
->height
, origin
->y
);
708 static void pattern_rects_32(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
709 const dib_info
*brush
, const rop_mask_bits
*bits
)
711 DWORD
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
715 for(i
= 0; i
< num
; i
++, rc
++)
717 offset
= calc_brush_offset(rc
, brush
, origin
);
719 start
= get_pixel_ptr_32(dib
, rc
->left
, rc
->top
);
720 start_and
= (DWORD
*)bits
->and + offset
.y
* brush
->stride
/ 4;
721 start_xor
= (DWORD
*)bits
->xor + offset
.y
* brush
->stride
/ 4;
723 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
725 and_ptr
= start_and
+ offset
.x
;
726 xor_ptr
= start_xor
+ offset
.x
;
728 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
730 do_rop_32(ptr
++, *and_ptr
++, *xor_ptr
++);
731 if(and_ptr
== start_and
+ brush
->width
)
739 if(offset
.y
== brush
->height
)
741 start_and
= bits
->and;
742 start_xor
= bits
->xor;
747 start_and
+= brush
->stride
/ 4;
748 start_xor
+= brush
->stride
/ 4;
754 static void pattern_rects_24(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
755 const dib_info
*brush
, const rop_mask_bits
*bits
)
757 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
761 for(i
= 0; i
< num
; i
++, rc
++)
763 offset
= calc_brush_offset(rc
, brush
, origin
);
765 start
= get_pixel_ptr_24(dib
, rc
->left
, rc
->top
);
766 start_and
= (BYTE
*)bits
->and + offset
.y
* brush
->stride
;
767 start_xor
= (BYTE
*)bits
->xor + offset
.y
* brush
->stride
;
769 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
771 and_ptr
= start_and
+ offset
.x
* 3;
772 xor_ptr
= start_xor
+ offset
.x
* 3;
774 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
776 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
777 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
778 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
779 if(and_ptr
== start_and
+ brush
->width
* 3)
787 if(offset
.y
== brush
->height
)
789 start_and
= bits
->and;
790 start_xor
= bits
->xor;
795 start_and
+= brush
->stride
;
796 start_xor
+= brush
->stride
;
802 static void pattern_rects_16(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
803 const dib_info
*brush
, const rop_mask_bits
*bits
)
805 WORD
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
809 for(i
= 0; i
< num
; i
++, rc
++)
811 offset
= calc_brush_offset(rc
, brush
, origin
);
813 start
= get_pixel_ptr_16(dib
, rc
->left
, rc
->top
);
814 start_and
= (WORD
*)bits
->and + offset
.y
* brush
->stride
/ 2;
815 start_xor
= (WORD
*)bits
->xor + offset
.y
* brush
->stride
/ 2;
817 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 2)
819 and_ptr
= start_and
+ offset
.x
;
820 xor_ptr
= start_xor
+ offset
.x
;
822 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
824 do_rop_16(ptr
++, *and_ptr
++, *xor_ptr
++);
825 if(and_ptr
== start_and
+ brush
->width
)
833 if(offset
.y
== brush
->height
)
835 start_and
= bits
->and;
836 start_xor
= bits
->xor;
841 start_and
+= brush
->stride
/ 2;
842 start_xor
+= brush
->stride
/ 2;
848 static void pattern_rects_8(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
849 const dib_info
*brush
, const rop_mask_bits
*bits
)
851 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
855 for(i
= 0; i
< num
; i
++, rc
++)
857 offset
= calc_brush_offset(rc
, brush
, origin
);
859 start
= get_pixel_ptr_8(dib
, rc
->left
, rc
->top
);
860 start_and
= (BYTE
*)bits
->and + offset
.y
* brush
->stride
;
861 start_xor
= (BYTE
*)bits
->xor + offset
.y
* brush
->stride
;
863 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
865 and_ptr
= start_and
+ offset
.x
;
866 xor_ptr
= start_xor
+ offset
.x
;
868 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
870 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
871 if(and_ptr
== start_and
+ brush
->width
)
879 if(offset
.y
== brush
->height
)
881 start_and
= bits
->and;
882 start_xor
= bits
->xor;
887 start_and
+= brush
->stride
;
888 start_xor
+= brush
->stride
;
894 static void pattern_rects_4(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
895 const dib_info
*brush
, const rop_mask_bits
*bits
)
897 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
898 int x
, y
, i
, left
, right
;
901 for(i
= 0; i
< num
; i
++, rc
++)
903 offset
= calc_brush_offset(rc
, brush
, origin
);
904 left
= dib
->rect
.left
+ rc
->left
;
905 right
= dib
->rect
.left
+ rc
->right
;
907 start
= get_pixel_ptr_4(dib
, rc
->left
, rc
->top
);
908 start_and
= (BYTE
*)bits
->and + offset
.y
* brush
->stride
;
909 start_xor
= (BYTE
*)bits
->xor + offset
.y
* brush
->stride
;
911 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
913 INT brush_x
= offset
.x
;
914 BYTE byte_and
, byte_xor
;
916 and_ptr
= start_and
+ brush_x
/ 2;
917 xor_ptr
= start_xor
+ brush_x
/ 2;
919 for(x
= left
, ptr
= start
; x
< right
; x
++)
921 /* FIXME: Two pixels at a time */
922 if(x
& 1) /* lower dst nibble */
924 if(brush_x
& 1) /* lower pat nibble */
926 byte_and
= *and_ptr
++ | 0xf0;
927 byte_xor
= *xor_ptr
++ & 0x0f;
929 else /* upper pat nibble */
931 byte_and
= (*and_ptr
>> 4) | 0xf0;
932 byte_xor
= (*xor_ptr
>> 4) & 0x0f;
935 else /* upper dst nibble */
937 if(brush_x
& 1) /* lower pat nibble */
939 byte_and
= (*and_ptr
++ << 4) | 0x0f;
940 byte_xor
= (*xor_ptr
++ << 4) & 0xf0;
942 else /* upper pat nibble */
944 byte_and
= *and_ptr
| 0x0f;
945 byte_xor
= *xor_ptr
& 0xf0;
948 do_rop_8(ptr
, byte_and
, byte_xor
);
952 if(++brush_x
== brush
->width
)
961 if(offset
.y
== brush
->height
)
963 start_and
= bits
->and;
964 start_xor
= bits
->xor;
969 start_and
+= brush
->stride
;
970 start_xor
+= brush
->stride
;
976 static void pattern_rects_1(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
977 const dib_info
*brush
, const rop_mask_bits
*bits
)
979 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
980 int x
, y
, i
, left
, right
;
983 for(i
= 0; i
< num
; i
++, rc
++)
985 offset
= calc_brush_offset(rc
, brush
, origin
);
986 left
= dib
->rect
.left
+ rc
->left
;
987 right
= dib
->rect
.left
+ rc
->right
;
989 start
= get_pixel_ptr_1(dib
, rc
->left
, rc
->top
);
990 start_and
= (BYTE
*)bits
->and + offset
.y
* brush
->stride
;
991 start_xor
= (BYTE
*)bits
->xor + offset
.y
* brush
->stride
;
993 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
995 INT brush_x
= offset
.x
;
996 BYTE byte_and
, byte_xor
;
998 and_ptr
= start_and
+ brush_x
/ 8;
999 xor_ptr
= start_xor
+ brush_x
/ 8;
1001 for(x
= left
, ptr
= start
; x
< right
; x
++)
1003 byte_and
= (*and_ptr
& pixel_masks_1
[brush_x
% 8]) ? 0xff : 0;
1004 byte_and
|= ~pixel_masks_1
[x
% 8];
1005 byte_xor
= (*xor_ptr
& pixel_masks_1
[brush_x
% 8]) ? 0xff : 0;
1006 byte_xor
&= pixel_masks_1
[x
% 8];
1008 do_rop_8(ptr
, byte_and
, byte_xor
);
1010 if((x
& 7) == 7) ptr
++;
1012 if((brush_x
& 7) == 7)
1018 if(++brush_x
== brush
->width
)
1021 and_ptr
= start_and
;
1022 xor_ptr
= start_xor
;
1027 if(offset
.y
== brush
->height
)
1029 start_and
= bits
->and;
1030 start_xor
= bits
->xor;
1035 start_and
+= brush
->stride
;
1036 start_xor
+= brush
->stride
;
1042 static void pattern_rects_null(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
1043 const dib_info
*brush
, const rop_mask_bits
*bits
)
1048 static void copy_rect_32(const dib_info
*dst
, const RECT
*rc
,
1049 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1051 DWORD
*dst_start
, *src_start
;
1052 struct rop_codes codes
;
1053 int y
, dst_stride
, src_stride
;
1055 if (overlap
& OVERLAP_BELOW
)
1057 dst_start
= get_pixel_ptr_32(dst
, rc
->left
, rc
->bottom
- 1);
1058 src_start
= get_pixel_ptr_32(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1059 dst_stride
= -dst
->stride
/ 4;
1060 src_stride
= -src
->stride
/ 4;
1064 dst_start
= get_pixel_ptr_32(dst
, rc
->left
, rc
->top
);
1065 src_start
= get_pixel_ptr_32(src
, origin
->x
, origin
->y
);
1066 dst_stride
= dst
->stride
/ 4;
1067 src_stride
= src
->stride
/ 4;
1070 if (rop2
== R2_COPYPEN
)
1072 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1073 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) * 4 );
1077 get_rop_codes( rop2
, &codes
);
1078 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1080 if (overlap
& OVERLAP_RIGHT
)
1081 do_rop_codes_line_rev_32( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1083 do_rop_codes_line_32( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1087 static void copy_rect_24(const dib_info
*dst
, const RECT
*rc
,
1088 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1090 BYTE
*dst_start
, *src_start
;
1091 int y
, dst_stride
, src_stride
;
1092 struct rop_codes codes
;
1094 if (overlap
& OVERLAP_BELOW
)
1096 dst_start
= get_pixel_ptr_24(dst
, rc
->left
, rc
->bottom
- 1);
1097 src_start
= get_pixel_ptr_24(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1098 dst_stride
= -dst
->stride
;
1099 src_stride
= -src
->stride
;
1103 dst_start
= get_pixel_ptr_24(dst
, rc
->left
, rc
->top
);
1104 src_start
= get_pixel_ptr_24(src
, origin
->x
, origin
->y
);
1105 dst_stride
= dst
->stride
;
1106 src_stride
= src
->stride
;
1109 if (rop2
== R2_COPYPEN
)
1111 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1112 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) * 3 );
1116 get_rop_codes( rop2
, &codes
);
1117 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1119 if (overlap
& OVERLAP_RIGHT
)
1120 do_rop_codes_line_rev_8( dst_start
, src_start
, &codes
, (rc
->right
- rc
->left
) * 3 );
1122 do_rop_codes_line_8( dst_start
, src_start
, &codes
, (rc
->right
- rc
->left
) * 3 );
1126 static void copy_rect_16(const dib_info
*dst
, const RECT
*rc
,
1127 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1129 WORD
*dst_start
, *src_start
;
1130 int y
, dst_stride
, src_stride
;
1131 struct rop_codes codes
;
1133 if (overlap
& OVERLAP_BELOW
)
1135 dst_start
= get_pixel_ptr_16(dst
, rc
->left
, rc
->bottom
- 1);
1136 src_start
= get_pixel_ptr_16(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1137 dst_stride
= -dst
->stride
/ 2;
1138 src_stride
= -src
->stride
/ 2;
1142 dst_start
= get_pixel_ptr_16(dst
, rc
->left
, rc
->top
);
1143 src_start
= get_pixel_ptr_16(src
, origin
->x
, origin
->y
);
1144 dst_stride
= dst
->stride
/ 2;
1145 src_stride
= src
->stride
/ 2;
1148 if (rop2
== R2_COPYPEN
)
1150 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1151 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) * 2 );
1155 get_rop_codes( rop2
, &codes
);
1156 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1158 if (overlap
& OVERLAP_RIGHT
)
1159 do_rop_codes_line_rev_16( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1161 do_rop_codes_line_16( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1165 static void copy_rect_8(const dib_info
*dst
, const RECT
*rc
,
1166 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1168 BYTE
*dst_start
, *src_start
;
1169 int y
, dst_stride
, src_stride
;
1170 struct rop_codes codes
;
1172 if (overlap
& OVERLAP_BELOW
)
1174 dst_start
= get_pixel_ptr_8(dst
, rc
->left
, rc
->bottom
- 1);
1175 src_start
= get_pixel_ptr_8(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1176 dst_stride
= -dst
->stride
;
1177 src_stride
= -src
->stride
;
1181 dst_start
= get_pixel_ptr_8(dst
, rc
->left
, rc
->top
);
1182 src_start
= get_pixel_ptr_8(src
, origin
->x
, origin
->y
);
1183 dst_stride
= dst
->stride
;
1184 src_stride
= src
->stride
;
1187 if (rop2
== R2_COPYPEN
)
1189 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1190 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) );
1194 get_rop_codes( rop2
, &codes
);
1195 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1197 if (overlap
& OVERLAP_RIGHT
)
1198 do_rop_codes_line_rev_8( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1200 do_rop_codes_line_8( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1204 static void copy_rect_4(const dib_info
*dst
, const RECT
*rc
,
1205 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1207 BYTE
*dst_start
, *src_start
;
1208 int y
, dst_stride
, src_stride
;
1209 struct rop_codes codes
;
1210 int left
= dst
->rect
.left
+ rc
->left
;
1211 int right
= dst
->rect
.left
+ rc
->right
;
1212 int org_x
= src
->rect
.left
+ origin
->x
;
1214 if (overlap
& OVERLAP_BELOW
)
1216 dst_start
= get_pixel_ptr_4(dst
, rc
->left
, rc
->bottom
- 1);
1217 src_start
= get_pixel_ptr_4(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1218 dst_stride
= -dst
->stride
;
1219 src_stride
= -src
->stride
;
1223 dst_start
= get_pixel_ptr_4(dst
, rc
->left
, rc
->top
);
1224 src_start
= get_pixel_ptr_4(src
, origin
->x
, origin
->y
);
1225 dst_stride
= dst
->stride
;
1226 src_stride
= src
->stride
;
1229 if (rop2
== R2_COPYPEN
&& (left
& 1) == 0 && (org_x
& 1) == 0 && (right
& 1) == 0)
1231 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1232 memmove( dst_start
, src_start
, (right
- left
) / 2 );
1236 get_rop_codes( rop2
, &codes
);
1237 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1239 if (overlap
& OVERLAP_RIGHT
)
1240 do_rop_codes_line_rev_4( dst_start
, left
& 1, src_start
, org_x
& 1, &codes
, right
- left
);
1242 do_rop_codes_line_4( dst_start
, left
& 1, src_start
, org_x
& 1, &codes
, right
- left
);
1246 static void copy_rect_1(const dib_info
*dst
, const RECT
*rc
,
1247 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1249 BYTE
*dst_start
, *src_start
;
1250 int y
, dst_stride
, src_stride
;
1251 struct rop_codes codes
;
1252 int left
= dst
->rect
.left
+ rc
->left
;
1253 int right
= dst
->rect
.left
+ rc
->right
;
1254 int org_x
= src
->rect
.left
+ origin
->x
;
1256 if (overlap
& OVERLAP_BELOW
)
1258 dst_start
= get_pixel_ptr_1(dst
, rc
->left
, rc
->bottom
- 1);
1259 src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1260 dst_stride
= -dst
->stride
;
1261 src_stride
= -src
->stride
;
1265 dst_start
= get_pixel_ptr_1(dst
, rc
->left
, rc
->top
);
1266 src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
);
1267 dst_stride
= dst
->stride
;
1268 src_stride
= src
->stride
;
1271 if (rop2
== R2_COPYPEN
&& (left
& 7) == 0 && (org_x
& 7) == 0 && (right
& 7) == 0)
1273 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1274 memmove( dst_start
, src_start
, (right
- left
) / 8 );
1278 get_rop_codes( rop2
, &codes
);
1279 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1281 if (overlap
& OVERLAP_RIGHT
)
1282 do_rop_codes_line_rev_1( dst_start
, left
& 7, src_start
, org_x
& 7, &codes
, right
- left
);
1284 do_rop_codes_line_1( dst_start
, left
& 7, src_start
, org_x
& 7, &codes
, right
- left
);
1288 static void copy_rect_null(const dib_info
*dst
, const RECT
*rc
,
1289 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1294 static DWORD
get_pixel_32(const dib_info
*dib
, int x
, int y
)
1296 DWORD
*ptr
= get_pixel_ptr_32( dib
, x
, y
);
1300 static DWORD
get_pixel_24(const dib_info
*dib
, int x
, int y
)
1302 BYTE
*ptr
= get_pixel_ptr_24( dib
, x
, y
);
1303 return ptr
[0] | ((DWORD
)ptr
[1] << 8) | ((DWORD
)ptr
[2] << 16);
1306 static DWORD
get_pixel_16(const dib_info
*dib
, int x
, int y
)
1308 WORD
*ptr
= get_pixel_ptr_16( dib
, x
, y
);
1312 static DWORD
get_pixel_8(const dib_info
*dib
, int x
, int y
)
1314 BYTE
*ptr
= get_pixel_ptr_8( dib
, x
, y
);
1318 static DWORD
get_pixel_4(const dib_info
*dib
, int x
, int y
)
1320 BYTE
*ptr
= get_pixel_ptr_4( dib
, x
, y
);
1322 if ((dib
->rect
.left
+ x
) & 1)
1325 return (*ptr
>> 4) & 0x0f;
1328 static DWORD
get_pixel_1(const dib_info
*dib
, int x
, int y
)
1330 BYTE
*ptr
= get_pixel_ptr_1( dib
, x
, y
);
1331 return (*ptr
& pixel_masks_1
[(dib
->rect
.left
+ x
) & 7]) ? 1 : 0;
1334 static DWORD
get_pixel_null(const dib_info
*dib
, int x
, int y
)
1339 static DWORD
colorref_to_pixel_888(const dib_info
*dib
, COLORREF color
)
1341 return ( ((color
>> 16) & 0xff) | (color
& 0xff00) | ((color
<< 16) & 0xff0000) );
1344 static const DWORD field_masks
[33] =
1346 0x00, /* should never happen */
1347 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff,
1348 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1349 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1350 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1353 static inline DWORD
get_field(DWORD field
, int shift
, int len
)
1355 shift
= shift
- (8 - len
);
1360 field
&= field_masks
[len
];
1361 field
|= field
>> len
;
1365 static inline DWORD
put_field(DWORD field
, int shift
, int len
)
1367 shift
= shift
- (8 - len
);
1368 field
&= field_masks
[len
];
1376 static DWORD
colorref_to_pixel_masks(const dib_info
*dib
, COLORREF colour
)
1380 r
= GetRValue(colour
);
1381 g
= GetGValue(colour
);
1382 b
= GetBValue(colour
);
1384 return put_field(r
, dib
->red_shift
, dib
->red_len
) |
1385 put_field(g
, dib
->green_shift
, dib
->green_len
) |
1386 put_field(b
, dib
->blue_shift
, dib
->blue_len
);
1389 static DWORD
colorref_to_pixel_555(const dib_info
*dib
, COLORREF color
)
1391 return ( ((color
>> 19) & 0x1f) | ((color
>> 6) & 0x03e0) | ((color
<< 7) & 0x7c00) );
1394 static DWORD
rgb_to_pixel_colortable(const dib_info
*dib
, BYTE r
, BYTE g
, BYTE b
)
1396 const RGBQUAD
*color_table
= get_dib_color_table( dib
);
1397 int size
= dib
->color_table
? dib
->color_table_size
: 1 << dib
->bit_count
;
1398 int i
, best_index
= 0;
1399 DWORD diff
, best_diff
= 0xffffffff;
1401 /* special case for conversion to 1-bpp without a color table:
1402 * we get a 1-entry table containing the background color
1404 if (dib
->bit_count
== 1 && size
== 1)
1405 return (r
== color_table
[0].rgbRed
&&
1406 g
== color_table
[0].rgbGreen
&&
1407 b
== color_table
[0].rgbBlue
);
1409 for(i
= 0; i
< size
; i
++)
1411 const RGBQUAD
*cur
= color_table
+ i
;
1412 diff
= (r
- cur
->rgbRed
) * (r
- cur
->rgbRed
)
1413 + (g
- cur
->rgbGreen
) * (g
- cur
->rgbGreen
)
1414 + (b
- cur
->rgbBlue
) * (b
- cur
->rgbBlue
);
1422 if(diff
< best_diff
)
1431 static DWORD
rgb_to_pixel_mono(const dib_info
*dib
, BOOL dither
, int x
, int y
, BYTE r
, BYTE g
, BYTE b
)
1436 ret
= rgb_to_pixel_colortable( dib
, r
, g
, b
);
1438 ret
= ((30 * r
+ 59 * g
+ 11 * b
) / 100 + bayer_16x16
[y
% 16][x
% 16]) > 255;
1440 return ret
? 0xff : 0;
1443 static DWORD
colorref_to_pixel_colortable(const dib_info
*dib
, COLORREF color
)
1445 return rgb_to_pixel_colortable( dib
, GetRValue(color
), GetGValue(color
), GetBValue(color
) );
1448 static DWORD
colorref_to_pixel_null(const dib_info
*dib
, COLORREF color
)
1453 static COLORREF
pixel_to_colorref_888(const dib_info
*dib
, DWORD pixel
)
1455 return ( ((pixel
>> 16) & 0xff) | (pixel
& 0xff00) | ((pixel
<< 16) & 0xff0000) );
1458 static COLORREF
pixel_to_colorref_masks(const dib_info
*dib
, DWORD pixel
)
1460 return RGB( get_field( pixel
, dib
->red_shift
, dib
->red_len
),
1461 get_field( pixel
, dib
->green_shift
, dib
->green_len
),
1462 get_field( pixel
, dib
->blue_shift
, dib
->blue_len
) );
1465 static COLORREF
pixel_to_colorref_555(const dib_info
*dib
, DWORD pixel
)
1467 return RGB( ((pixel
>> 7) & 0xf8) | ((pixel
>> 12) & 0x07),
1468 ((pixel
>> 2) & 0xf8) | ((pixel
>> 7) & 0x07),
1469 ((pixel
<< 3) & 0xf8) | ((pixel
>> 2) & 0x07) );
1472 static COLORREF
pixel_to_colorref_colortable(const dib_info
*dib
, DWORD pixel
)
1474 const RGBQUAD
*color_table
= get_dib_color_table( dib
);
1476 if (!dib
->color_table
|| pixel
< dib
->color_table_size
)
1478 RGBQUAD quad
= color_table
[pixel
];
1479 return RGB( quad
.rgbRed
, quad
.rgbGreen
, quad
.rgbBlue
);
1484 static COLORREF
pixel_to_colorref_null(const dib_info
*dib
, DWORD pixel
)
1489 static inline BOOL
bit_fields_match(const dib_info
*d1
, const dib_info
*d2
)
1491 assert( d1
->bit_count
> 8 && d1
->bit_count
== d2
->bit_count
);
1493 return d1
->red_mask
== d2
->red_mask
&&
1494 d1
->green_mask
== d2
->green_mask
&&
1495 d1
->blue_mask
== d2
->blue_mask
;
1498 static void convert_to_8888(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
1500 DWORD
*dst_start
= get_pixel_ptr_32(dst
, 0, 0), *dst_pixel
, src_val
;
1501 int x
, y
, pad_size
= (dst
->width
- (src_rect
->right
- src_rect
->left
)) * 4;
1503 switch(src
->bit_count
)
1507 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1508 if(src
->funcs
== &funcs_8888
)
1510 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
1511 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
1514 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1516 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 4);
1517 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
1518 dst_start
+= dst
->stride
/ 4;
1519 src_start
+= src
->stride
/ 4;
1523 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
1525 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1527 dst_pixel
= dst_start
;
1528 src_pixel
= src_start
;
1529 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1531 src_val
= *src_pixel
++;
1532 *dst_pixel
++ = (((src_val
>> src
->red_shift
) & 0xff) << 16) |
1533 (((src_val
>> src
->green_shift
) & 0xff) << 8) |
1534 ((src_val
>> src
->blue_shift
) & 0xff);
1536 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1537 dst_start
+= dst
->stride
/ 4;
1538 src_start
+= src
->stride
/ 4;
1543 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1545 dst_pixel
= dst_start
;
1546 src_pixel
= src_start
;
1547 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1549 src_val
= *src_pixel
++;
1550 *dst_pixel
++ = (get_field( src_val
, src
->red_shift
, src
->red_len
) << 16 |
1551 get_field( src_val
, src
->green_shift
, src
->green_len
) << 8 |
1552 get_field( src_val
, src
->blue_shift
, src
->blue_len
));
1554 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1555 dst_start
+= dst
->stride
/ 4;
1556 src_start
+= src
->stride
/ 4;
1564 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1566 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1568 dst_pixel
= dst_start
;
1569 src_pixel
= src_start
;
1570 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1573 rgb
.rgbBlue
= *src_pixel
++;
1574 rgb
.rgbGreen
= *src_pixel
++;
1575 rgb
.rgbRed
= *src_pixel
++;
1577 *dst_pixel
++ = ((rgb
.rgbRed
<< 16) & 0xff0000) | ((rgb
.rgbGreen
<< 8) & 0x00ff00) | (rgb
.rgbBlue
& 0x0000ff);
1579 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1580 dst_start
+= dst
->stride
/ 4;
1581 src_start
+= src
->stride
;
1588 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1589 if(src
->funcs
== &funcs_555
)
1591 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1593 dst_pixel
= dst_start
;
1594 src_pixel
= src_start
;
1595 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1597 src_val
= *src_pixel
++;
1598 *dst_pixel
++ = ((src_val
<< 9) & 0xf80000) | ((src_val
<< 4) & 0x070000) |
1599 ((src_val
<< 6) & 0x00f800) | ((src_val
<< 1) & 0x000700) |
1600 ((src_val
<< 3) & 0x0000f8) | ((src_val
>> 2) & 0x000007);
1602 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1603 dst_start
+= dst
->stride
/ 4;
1604 src_start
+= src
->stride
/ 2;
1607 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
1609 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1611 dst_pixel
= dst_start
;
1612 src_pixel
= src_start
;
1613 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1615 src_val
= *src_pixel
++;
1616 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 19) & 0xf80000) |
1617 (((src_val
>> src
->red_shift
) << 14) & 0x070000) |
1618 (((src_val
>> src
->green_shift
) << 11) & 0x00f800) |
1619 (((src_val
>> src
->green_shift
) << 6) & 0x000700) |
1620 (((src_val
>> src
->blue_shift
) << 3) & 0x0000f8) |
1621 (((src_val
>> src
->blue_shift
) >> 2) & 0x000007);
1623 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1624 dst_start
+= dst
->stride
/ 4;
1625 src_start
+= src
->stride
/ 2;
1628 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
1630 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1632 dst_pixel
= dst_start
;
1633 src_pixel
= src_start
;
1634 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1636 src_val
= *src_pixel
++;
1637 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 19) & 0xf80000) |
1638 (((src_val
>> src
->red_shift
) << 14) & 0x070000) |
1639 (((src_val
>> src
->green_shift
) << 10) & 0x00fc00) |
1640 (((src_val
>> src
->green_shift
) << 4) & 0x000300) |
1641 (((src_val
>> src
->blue_shift
) << 3) & 0x0000f8) |
1642 (((src_val
>> src
->blue_shift
) >> 2) & 0x000007);
1644 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1645 dst_start
+= dst
->stride
/ 4;
1646 src_start
+= src
->stride
/ 2;
1651 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1653 dst_pixel
= dst_start
;
1654 src_pixel
= src_start
;
1655 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1657 src_val
= *src_pixel
++;
1658 *dst_pixel
++ = (get_field( src_val
, src
->red_shift
, src
->red_len
) << 16 |
1659 get_field( src_val
, src
->green_shift
, src
->green_len
) << 8 |
1660 get_field( src_val
, src
->blue_shift
, src
->blue_len
));
1662 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1663 dst_start
+= dst
->stride
/ 4;
1664 src_start
+= src
->stride
/ 2;
1672 const RGBQUAD
*color_table
= get_dib_color_table( src
);
1673 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1674 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1676 dst_pixel
= dst_start
;
1677 src_pixel
= src_start
;
1678 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1680 RGBQUAD rgb
= color_table
[*src_pixel
++];
1681 *dst_pixel
++ = rgb
.rgbRed
<< 16 | rgb
.rgbGreen
<< 8 | rgb
.rgbBlue
;
1683 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1684 dst_start
+= dst
->stride
/ 4;
1685 src_start
+= src
->stride
;
1692 const RGBQUAD
*color_table
= get_dib_color_table( src
);
1693 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1694 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1696 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
1697 src_pixel
= src_start
;
1698 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
1702 rgb
= color_table
[*src_pixel
++ & 0xf];
1704 rgb
= color_table
[*src_pixel
>> 4];
1705 dst_start
[x
] = rgb
.rgbRed
<< 16 | rgb
.rgbGreen
<< 8 | rgb
.rgbBlue
;
1707 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
1708 dst_start
+= dst
->stride
/ 4;
1709 src_start
+= src
->stride
;
1716 const RGBQUAD
*color_table
= get_dib_color_table( src
);
1717 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
1718 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1720 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
1721 for(x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
1724 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
1725 rgb
= color_table
[src_val
];
1726 dst_start
[x
] = rgb
.rgbRed
<< 16 | rgb
.rgbGreen
<< 8 | rgb
.rgbBlue
;
1728 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
1729 dst_start
+= dst
->stride
/ 4;
1730 src_start
+= src
->stride
;
1737 static void convert_to_32(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
1739 DWORD
*dst_start
= get_pixel_ptr_32(dst
, 0, 0), *dst_pixel
, src_val
;
1740 int x
, y
, pad_size
= (dst
->width
- (src_rect
->right
- src_rect
->left
)) * 4;
1742 switch(src
->bit_count
)
1746 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1748 if(src
->funcs
== &funcs_8888
)
1750 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1752 dst_pixel
= dst_start
;
1753 src_pixel
= src_start
;
1754 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1756 src_val
= *src_pixel
++;
1757 *dst_pixel
++ = put_field(src_val
>> 16, dst
->red_shift
, dst
->red_len
) |
1758 put_field(src_val
>> 8, dst
->green_shift
, dst
->green_len
) |
1759 put_field(src_val
, dst
->blue_shift
, dst
->blue_len
);
1761 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1762 dst_start
+= dst
->stride
/ 4;
1763 src_start
+= src
->stride
/ 4;
1766 else if(bit_fields_match(src
, dst
))
1768 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
1769 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
1772 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1774 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 4);
1775 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
1776 dst_start
+= dst
->stride
/ 4;
1777 src_start
+= src
->stride
/ 4;
1781 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8 &&
1782 dst
->red_len
== 8 && dst
->green_len
== 8 && dst
->blue_len
== 8)
1784 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1786 dst_pixel
= dst_start
;
1787 src_pixel
= src_start
;
1788 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1790 src_val
= *src_pixel
++;
1791 *dst_pixel
++ = (((src_val
>> src
->red_shift
) & 0xff) << dst
->red_shift
) |
1792 (((src_val
>> src
->green_shift
) & 0xff) << dst
->green_shift
) |
1793 (((src_val
>> src
->blue_shift
) & 0xff) << dst
->blue_shift
);
1795 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1796 dst_start
+= dst
->stride
/ 4;
1797 src_start
+= src
->stride
/ 4;
1802 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1804 dst_pixel
= dst_start
;
1805 src_pixel
= src_start
;
1806 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1808 src_val
= *src_pixel
++;
1809 *dst_pixel
++ = put_field(get_field(src_val
, src
->red_shift
, src
->red_len
), dst
->red_shift
, dst
->red_len
) |
1810 put_field(get_field(src_val
, src
->green_shift
, src
->green_len
), dst
->green_shift
, dst
->green_len
) |
1811 put_field(get_field(src_val
, src
->blue_shift
, src
->blue_len
), dst
->blue_shift
, dst
->blue_len
);
1813 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1814 dst_start
+= dst
->stride
/ 4;
1815 src_start
+= src
->stride
/ 4;
1823 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1825 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1827 dst_pixel
= dst_start
;
1828 src_pixel
= src_start
;
1829 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1832 rgb
.rgbBlue
= *src_pixel
++;
1833 rgb
.rgbGreen
= *src_pixel
++;
1834 rgb
.rgbRed
= *src_pixel
++;
1836 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
1837 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
1838 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
1840 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1841 dst_start
+= dst
->stride
/ 4;
1842 src_start
+= src
->stride
;
1849 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1850 if(src
->funcs
== &funcs_555
)
1852 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1854 dst_pixel
= dst_start
;
1855 src_pixel
= src_start
;
1856 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1858 src_val
= *src_pixel
++;
1859 *dst_pixel
++ = put_field(((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07), dst
->red_shift
, dst
->red_len
) |
1860 put_field(((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07), dst
->green_shift
, dst
->green_len
) |
1861 put_field(((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
1863 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1864 dst_start
+= dst
->stride
/ 4;
1865 src_start
+= src
->stride
/ 2;
1868 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
1870 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1872 dst_pixel
= dst_start
;
1873 src_pixel
= src_start
;
1874 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1876 src_val
= *src_pixel
++;
1877 *dst_pixel
++ = put_field( (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
1878 (((src_val
>> src
->red_shift
) >> 2) & 0x07), dst
->red_shift
, dst
->red_len
) |
1879 put_field( (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
1880 (((src_val
>> src
->green_shift
) >> 2) & 0x07), dst
->green_shift
, dst
->green_len
) |
1881 put_field( (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
1882 (((src_val
>> src
->blue_shift
) >> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
1884 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1885 dst_start
+= dst
->stride
/ 4;
1886 src_start
+= src
->stride
/ 2;
1889 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
1891 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1893 dst_pixel
= dst_start
;
1894 src_pixel
= src_start
;
1895 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1897 src_val
= *src_pixel
++;
1898 *dst_pixel
++ = put_field( (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
1899 (((src_val
>> src
->red_shift
) >> 2) & 0x07), dst
->red_shift
, dst
->red_len
) |
1900 put_field( (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
1901 (((src_val
>> src
->green_shift
) >> 4) & 0x03), dst
->green_shift
, dst
->green_len
) |
1902 put_field( (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
1903 (((src_val
>> src
->blue_shift
) >> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
1905 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1906 dst_start
+= dst
->stride
/ 4;
1907 src_start
+= src
->stride
/ 2;
1912 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1914 dst_pixel
= dst_start
;
1915 src_pixel
= src_start
;
1916 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1918 src_val
= *src_pixel
++;
1919 *dst_pixel
++ = put_field(get_field(src_val
, src
->red_shift
, src
->red_len
), dst
->red_shift
, dst
->red_len
) |
1920 put_field(get_field(src_val
, src
->green_shift
, src
->green_len
), dst
->green_shift
, dst
->green_len
) |
1921 put_field(get_field(src_val
, src
->blue_shift
, src
->blue_len
), dst
->blue_shift
, dst
->blue_len
);
1923 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1924 dst_start
+= dst
->stride
/ 4;
1925 src_start
+= src
->stride
/ 2;
1933 const RGBQUAD
*color_table
= get_dib_color_table( src
);
1934 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1935 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1937 dst_pixel
= dst_start
;
1938 src_pixel
= src_start
;
1939 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1941 RGBQUAD rgb
= color_table
[*src_pixel
++];
1942 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
1943 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
1944 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
1946 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1947 dst_start
+= dst
->stride
/ 4;
1948 src_start
+= src
->stride
;
1955 const RGBQUAD
*color_table
= get_dib_color_table( src
);
1956 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1957 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1959 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
1960 src_pixel
= src_start
;
1961 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
1965 rgb
= color_table
[*src_pixel
++ & 0xf];
1967 rgb
= color_table
[*src_pixel
>> 4];
1968 dst_start
[x
] = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
1969 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
1970 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
1972 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
1973 dst_start
+= dst
->stride
/ 4;
1974 src_start
+= src
->stride
;
1981 const RGBQUAD
*color_table
= get_dib_color_table( src
);
1982 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
1983 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1985 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
1986 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
1989 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
1990 rgb
= color_table
[src_val
];
1991 dst_start
[x
] = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
1992 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
1993 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
1995 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
1996 dst_start
+= dst
->stride
/ 4;
1997 src_start
+= src
->stride
;
2004 static void convert_to_24(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
2006 BYTE
*dst_start
= get_pixel_ptr_24(dst
, 0, 0), *dst_pixel
;
2008 int x
, y
, pad_size
= ((dst
->width
* 3 + 3) & ~3) - (src_rect
->right
- src_rect
->left
) * 3;
2010 switch(src
->bit_count
)
2014 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2015 if(src
->funcs
== &funcs_8888
)
2017 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2019 dst_pixel
= dst_start
;
2020 src_pixel
= src_start
;
2021 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2023 src_val
= *src_pixel
++;
2024 *dst_pixel
++ = src_val
& 0xff;
2025 *dst_pixel
++ = (src_val
>> 8) & 0xff;
2026 *dst_pixel
++ = (src_val
>> 16) & 0xff;
2028 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2029 dst_start
+= dst
->stride
;
2030 src_start
+= src
->stride
/ 4;
2033 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
2035 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2037 dst_pixel
= dst_start
;
2038 src_pixel
= src_start
;
2039 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2041 src_val
= *src_pixel
++;
2042 *dst_pixel
++ = (src_val
>> src
->blue_shift
) & 0xff;
2043 *dst_pixel
++ = (src_val
>> src
->green_shift
) & 0xff;
2044 *dst_pixel
++ = (src_val
>> src
->red_shift
) & 0xff;
2046 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2047 dst_start
+= dst
->stride
;
2048 src_start
+= src
->stride
/ 4;
2053 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2055 dst_pixel
= dst_start
;
2056 src_pixel
= src_start
;
2057 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2059 src_val
= *src_pixel
++;
2060 *dst_pixel
++ = get_field( src_val
, src
->blue_shift
, src
->blue_len
);
2061 *dst_pixel
++ = get_field( src_val
, src
->green_shift
, src
->green_len
);
2062 *dst_pixel
++ = get_field( src_val
, src
->red_shift
, src
->red_len
);
2064 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2065 dst_start
+= dst
->stride
;
2066 src_start
+= src
->stride
/ 4;
2074 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
);
2076 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
2077 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2080 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2082 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 3);
2083 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
) * 3, 0, pad_size
);
2084 dst_start
+= dst
->stride
;
2085 src_start
+= src
->stride
;
2093 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2094 if(src
->funcs
== &funcs_555
)
2096 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2098 dst_pixel
= dst_start
;
2099 src_pixel
= src_start
;
2100 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2102 src_val
= *src_pixel
++;
2103 *dst_pixel
++ = ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07);
2104 *dst_pixel
++ = ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07);
2105 *dst_pixel
++ = ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07);
2107 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2108 dst_start
+= dst
->stride
;
2109 src_start
+= src
->stride
/ 2;
2112 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2114 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2116 dst_pixel
= dst_start
;
2117 src_pixel
= src_start
;
2118 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2120 src_val
= *src_pixel
++;
2121 *dst_pixel
++ = (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2122 (((src_val
>> src
->blue_shift
) >> 2) & 0x07);
2123 *dst_pixel
++ = (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
2124 (((src_val
>> src
->green_shift
) >> 2) & 0x07);
2125 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2126 (((src_val
>> src
->red_shift
) >> 2) & 0x07);
2128 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2129 dst_start
+= dst
->stride
;
2130 src_start
+= src
->stride
/ 2;
2133 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2135 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2137 dst_pixel
= dst_start
;
2138 src_pixel
= src_start
;
2139 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2141 src_val
= *src_pixel
++;
2142 *dst_pixel
++ = (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2143 (((src_val
>> src
->blue_shift
) >> 2) & 0x07);
2144 *dst_pixel
++ = (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
2145 (((src_val
>> src
->green_shift
) >> 4) & 0x03);
2146 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2147 (((src_val
>> src
->red_shift
) >> 2) & 0x07);
2149 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2150 dst_start
+= dst
->stride
;
2151 src_start
+= src
->stride
/ 2;
2156 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2158 dst_pixel
= dst_start
;
2159 src_pixel
= src_start
;
2160 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2162 src_val
= *src_pixel
++;
2163 *dst_pixel
++ = get_field(src_val
, src
->blue_shift
, src
->blue_len
);
2164 *dst_pixel
++ = get_field(src_val
, src
->green_shift
, src
->green_len
);
2165 *dst_pixel
++ = get_field(src_val
, src
->red_shift
, src
->red_len
);
2167 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2168 dst_start
+= dst
->stride
;
2169 src_start
+= src
->stride
/ 2;
2177 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2178 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2179 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2181 dst_pixel
= dst_start
;
2182 src_pixel
= src_start
;
2183 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2185 RGBQUAD rgb
= color_table
[*src_pixel
++];
2186 *dst_pixel
++ = rgb
.rgbBlue
;
2187 *dst_pixel
++ = rgb
.rgbGreen
;
2188 *dst_pixel
++ = rgb
.rgbRed
;
2190 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2191 dst_start
+= dst
->stride
;
2192 src_start
+= src
->stride
;
2199 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2200 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2201 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2203 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
2204 src_pixel
= src_start
;
2205 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2209 rgb
= color_table
[*src_pixel
++ & 0xf];
2211 rgb
= color_table
[*src_pixel
>> 4];
2212 dst_start
[x
* 3] = rgb
.rgbBlue
;
2213 dst_start
[x
* 3 + 1] = rgb
.rgbGreen
;
2214 dst_start
[x
* 3 + 2] = rgb
.rgbRed
;
2216 if(pad_size
) memset(dst_start
+ x
* 3, 0, pad_size
);
2217 dst_start
+= dst
->stride
;
2218 src_start
+= src
->stride
;
2225 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2226 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
2227 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2229 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
2230 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2233 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
2234 rgb
= color_table
[src_val
];
2235 dst_start
[x
* 3] = rgb
.rgbBlue
;
2236 dst_start
[x
* 3 + 1] = rgb
.rgbGreen
;
2237 dst_start
[x
* 3 + 2] = rgb
.rgbRed
;
2239 if(pad_size
) memset(dst_start
+ x
* 3, 0, pad_size
);
2240 dst_start
+= dst
->stride
;
2241 src_start
+= src
->stride
;
2248 static void convert_to_555(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
2250 WORD
*dst_start
= get_pixel_ptr_16(dst
, 0, 0), *dst_pixel
;
2251 INT x
, y
, pad_size
= ((dst
->width
+ 1) & ~1) * 2 - (src_rect
->right
- src_rect
->left
) * 2;
2254 switch(src
->bit_count
)
2258 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2260 if(src
->funcs
== &funcs_8888
)
2262 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2264 dst_pixel
= dst_start
;
2265 src_pixel
= src_start
;
2266 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2268 src_val
= *src_pixel
++;
2269 *dst_pixel
++ = ((src_val
>> 9) & 0x7c00) |
2270 ((src_val
>> 6) & 0x03e0) |
2271 ((src_val
>> 3) & 0x001f);
2273 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2274 dst_start
+= dst
->stride
/ 2;
2275 src_start
+= src
->stride
/ 4;
2278 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
2280 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2282 dst_pixel
= dst_start
;
2283 src_pixel
= src_start
;
2284 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2286 src_val
= *src_pixel
++;
2287 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 7) & 0x7c00) |
2288 (((src_val
>> src
->green_shift
) << 2) & 0x03e0) |
2289 (((src_val
>> src
->blue_shift
) >> 3) & 0x001f);
2291 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2292 dst_start
+= dst
->stride
/ 2;
2293 src_start
+= src
->stride
/ 4;
2298 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2300 dst_pixel
= dst_start
;
2301 src_pixel
= src_start
;
2302 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2304 src_val
= *src_pixel
++;
2305 *dst_pixel
++ = (((get_field(src_val
, src
->red_shift
, src
->red_len
) << 7) & 0x7c00) |
2306 ((get_field(src_val
, src
->green_shift
, src
->green_len
) << 2) & 0x03e0) |
2307 ( get_field(src_val
, src
->blue_shift
, src
->blue_len
) >> 3));
2309 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2310 dst_start
+= dst
->stride
/ 2;
2311 src_start
+= src
->stride
/ 4;
2319 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2321 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2323 dst_pixel
= dst_start
;
2324 src_pixel
= src_start
;
2325 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2328 rgb
.rgbBlue
= *src_pixel
++;
2329 rgb
.rgbGreen
= *src_pixel
++;
2330 rgb
.rgbRed
= *src_pixel
++;
2332 *dst_pixel
++ = ((rgb
.rgbRed
<< 7) & 0x7c00) |
2333 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
2334 ((rgb
.rgbBlue
>> 3) & 0x001f);
2336 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2337 dst_start
+= dst
->stride
/ 2;
2338 src_start
+= src
->stride
;
2345 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2346 if(src
->funcs
== &funcs_555
)
2348 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
2349 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2352 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2354 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 2);
2355 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
2356 dst_start
+= dst
->stride
/ 2;
2357 src_start
+= src
->stride
/ 2;
2361 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2363 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2365 dst_pixel
= dst_start
;
2366 src_pixel
= src_start
;
2367 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2369 src_val
= *src_pixel
++;
2370 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 10) & 0x7c00) |
2371 (((src_val
>> src
->green_shift
) << 5) & 0x03e0) |
2372 ( (src_val
>> src
->blue_shift
) & 0x001f);
2374 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2375 dst_start
+= dst
->stride
/ 2;
2376 src_start
+= src
->stride
/ 2;
2379 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2381 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2383 dst_pixel
= dst_start
;
2384 src_pixel
= src_start
;
2385 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2387 src_val
= *src_pixel
++;
2388 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 10) & 0x7c00) |
2389 (((src_val
>> src
->green_shift
) << 4) & 0x03e0) |
2390 ( (src_val
>> src
->blue_shift
) & 0x001f);
2392 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2393 dst_start
+= dst
->stride
/ 2;
2394 src_start
+= src
->stride
/ 2;
2399 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2401 dst_pixel
= dst_start
;
2402 src_pixel
= src_start
;
2403 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2405 src_val
= *src_pixel
++;
2406 *dst_pixel
++ = (((get_field(src_val
, src
->red_shift
, src
->red_len
) << 7) & 0x7c00) |
2407 ((get_field(src_val
, src
->green_shift
, src
->green_len
) << 2) & 0x03e0) |
2408 ( get_field(src_val
, src
->blue_shift
, src
->blue_len
) >> 3));
2410 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2411 dst_start
+= dst
->stride
/ 2;
2412 src_start
+= src
->stride
/ 2;
2420 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2421 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2422 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2424 dst_pixel
= dst_start
;
2425 src_pixel
= src_start
;
2426 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2428 RGBQUAD rgb
= color_table
[*src_pixel
++];
2429 *dst_pixel
++ = ((rgb
.rgbRed
<< 7) & 0x7c00) |
2430 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
2431 ((rgb
.rgbBlue
>> 3) & 0x001f);
2433 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2434 dst_start
+= dst
->stride
/ 2;
2435 src_start
+= src
->stride
;
2442 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2443 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2444 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2446 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
2447 src_pixel
= src_start
;
2448 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2452 rgb
= color_table
[*src_pixel
++ & 0xf];
2454 rgb
= color_table
[*src_pixel
>> 4];
2455 dst_start
[x
] = ((rgb
.rgbRed
<< 7) & 0x7c00) |
2456 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
2457 ((rgb
.rgbBlue
>> 3) & 0x001f);
2459 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
2460 dst_start
+= dst
->stride
/ 2;
2461 src_start
+= src
->stride
;
2468 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2469 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
2470 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2472 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
2473 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2476 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
2477 rgb
= color_table
[src_val
];
2478 dst_start
[x
] = ((rgb
.rgbRed
<< 7) & 0x7c00) |
2479 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
2480 ((rgb
.rgbBlue
>> 3) & 0x001f);
2482 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
2483 dst_start
+= dst
->stride
/ 2;
2484 src_start
+= src
->stride
;
2491 static void convert_to_16(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
2493 WORD
*dst_start
= get_pixel_ptr_16(dst
, 0, 0), *dst_pixel
;
2494 INT x
, y
, pad_size
= ((dst
->width
+ 1) & ~1) * 2 - (src_rect
->right
- src_rect
->left
) * 2;
2497 switch(src
->bit_count
)
2501 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2503 if(src
->funcs
== &funcs_8888
)
2505 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2507 dst_pixel
= dst_start
;
2508 src_pixel
= src_start
;
2509 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2511 src_val
= *src_pixel
++;
2512 *dst_pixel
++ = put_field(src_val
>> 16, dst
->red_shift
, dst
->red_len
) |
2513 put_field(src_val
>> 8, dst
->green_shift
, dst
->green_len
) |
2514 put_field(src_val
, dst
->blue_shift
, dst
->blue_len
);
2516 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2517 dst_start
+= dst
->stride
/ 2;
2518 src_start
+= src
->stride
/ 4;
2521 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
2523 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2525 dst_pixel
= dst_start
;
2526 src_pixel
= src_start
;
2527 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2529 src_val
= *src_pixel
++;
2530 *dst_pixel
++ = put_field(src_val
>> src
->red_shift
, dst
->red_shift
, dst
->red_len
) |
2531 put_field(src_val
>> src
->green_shift
, dst
->green_shift
, dst
->green_len
) |
2532 put_field(src_val
>> src
->blue_shift
, dst
->blue_shift
, dst
->blue_len
);
2534 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2535 dst_start
+= dst
->stride
/ 2;
2536 src_start
+= src
->stride
/ 4;
2541 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2543 dst_pixel
= dst_start
;
2544 src_pixel
= src_start
;
2545 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2547 src_val
= *src_pixel
++;
2548 *dst_pixel
++ = put_field(get_field(src_val
, src
->red_shift
, src
->red_len
), dst
->red_shift
, dst
->red_len
) |
2549 put_field(get_field(src_val
, src
->green_shift
, src
->green_len
), dst
->green_shift
, dst
->green_len
) |
2550 put_field(get_field(src_val
, src
->blue_shift
, src
->blue_len
), dst
->blue_shift
, dst
->blue_len
);
2552 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2553 dst_start
+= dst
->stride
/ 2;
2554 src_start
+= src
->stride
/ 4;
2562 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2564 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2566 dst_pixel
= dst_start
;
2567 src_pixel
= src_start
;
2568 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2571 rgb
.rgbBlue
= *src_pixel
++;
2572 rgb
.rgbGreen
= *src_pixel
++;
2573 rgb
.rgbRed
= *src_pixel
++;
2575 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
2576 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
2577 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
2579 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2580 dst_start
+= dst
->stride
/ 2;
2581 src_start
+= src
->stride
;
2588 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2589 if(src
->funcs
== &funcs_555
)
2591 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2593 dst_pixel
= dst_start
;
2594 src_pixel
= src_start
;
2595 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2597 src_val
= *src_pixel
++;
2598 *dst_pixel
++ = put_field(((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07), dst
->red_shift
, dst
->red_len
) |
2599 put_field(((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07), dst
->green_shift
, dst
->green_len
) |
2600 put_field(((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
2602 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2603 dst_start
+= dst
->stride
/ 2;
2604 src_start
+= src
->stride
/ 2;
2607 else if(bit_fields_match(src
, dst
))
2609 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
2610 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2613 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2615 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 2);
2616 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
2617 dst_start
+= dst
->stride
/ 2;
2618 src_start
+= src
->stride
/ 2;
2622 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2624 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2626 dst_pixel
= dst_start
;
2627 src_pixel
= src_start
;
2628 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2630 src_val
= *src_pixel
++;
2631 *dst_pixel
++ = put_field( (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2632 (((src_val
>> src
->red_shift
) >> 2) & 0x07), dst
->red_shift
, dst
->red_len
) |
2633 put_field( (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
2634 (((src_val
>> src
->green_shift
) >> 2) & 0x07), dst
->green_shift
, dst
->green_len
) |
2635 put_field( (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2636 (((src_val
>> src
->blue_shift
) >> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
2638 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2639 dst_start
+= dst
->stride
/ 2;
2640 src_start
+= src
->stride
/ 2;
2643 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2645 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2647 dst_pixel
= dst_start
;
2648 src_pixel
= src_start
;
2649 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2651 src_val
= *src_pixel
++;
2652 *dst_pixel
++ = put_field( (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2653 (((src_val
>> src
->red_shift
) >> 2) & 0x07), dst
->red_shift
, dst
->red_len
) |
2654 put_field( (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
2655 (((src_val
>> src
->green_shift
) >> 4) & 0x03), dst
->green_shift
, dst
->green_len
) |
2656 put_field( (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2657 (((src_val
>> src
->blue_shift
) >> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
2659 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2660 dst_start
+= dst
->stride
/ 2;
2661 src_start
+= src
->stride
/ 2;
2666 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2668 dst_pixel
= dst_start
;
2669 src_pixel
= src_start
;
2670 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2672 src_val
= *src_pixel
++;
2673 *dst_pixel
++ = put_field(get_field(src_val
, src
->red_shift
, src
->red_len
), dst
->red_shift
, dst
->red_len
) |
2674 put_field(get_field(src_val
, src
->green_shift
, src
->green_len
), dst
->green_shift
, dst
->green_len
) |
2675 put_field(get_field(src_val
, src
->blue_shift
, src
->blue_len
), dst
->blue_shift
, dst
->blue_len
);
2677 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2678 dst_start
+= dst
->stride
/ 2;
2679 src_start
+= src
->stride
/ 2;
2687 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2688 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2689 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2691 dst_pixel
= dst_start
;
2692 src_pixel
= src_start
;
2693 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2695 RGBQUAD rgb
= color_table
[*src_pixel
++];
2696 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
2697 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
2698 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
2700 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2701 dst_start
+= dst
->stride
/ 2;
2702 src_start
+= src
->stride
;
2709 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2710 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2711 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2713 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
2714 src_pixel
= src_start
;
2715 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2719 rgb
= color_table
[*src_pixel
++ & 0xf];
2721 rgb
= color_table
[*src_pixel
>> 4];
2722 dst_start
[x
] = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
2723 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
2724 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
2726 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
2727 dst_start
+= dst
->stride
/ 2;
2728 src_start
+= src
->stride
;
2735 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2736 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
2737 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2739 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
2740 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2743 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
2744 rgb
= color_table
[src_val
];
2745 dst_start
[x
] = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
2746 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
2747 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
2749 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
2750 dst_start
+= dst
->stride
/ 2;
2751 src_start
+= src
->stride
;
2758 static inline BOOL
color_tables_match(const dib_info
*d1
, const dib_info
*d2
)
2760 if (!d1
->color_table
|| !d2
->color_table
) return (!d1
->color_table
&& !d2
->color_table
);
2761 return !memcmp(d1
->color_table
, d2
->color_table
, (1 << d1
->bit_count
) * sizeof(d1
->color_table
[0]));
2764 static inline DWORD
rgb_lookup_colortable(const dib_info
*dst
, BYTE r
, BYTE g
, BYTE b
)
2766 /* Windows reduces precision to 5 bits, probably in order to build some sort of lookup cache */
2767 return rgb_to_pixel_colortable( dst
, (r
& ~7) + 4, (g
& ~7) + 4, (b
& ~7) + 4 );
2770 static void convert_to_8(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
2772 BYTE
*dst_start
= get_pixel_ptr_8(dst
, 0, 0), *dst_pixel
;
2773 INT x
, y
, pad_size
= ((dst
->width
+ 3) & ~3) - (src_rect
->right
- src_rect
->left
);
2776 switch(src
->bit_count
)
2780 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2782 if(src
->funcs
== &funcs_8888
)
2784 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2786 dst_pixel
= dst_start
;
2787 src_pixel
= src_start
;
2788 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2790 src_val
= *src_pixel
++;
2791 *dst_pixel
++ = rgb_lookup_colortable(dst
, src_val
>> 16, src_val
>> 8, src_val
);
2793 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2794 dst_start
+= dst
->stride
;
2795 src_start
+= src
->stride
/ 4;
2798 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
2800 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2802 dst_pixel
= dst_start
;
2803 src_pixel
= src_start
;
2804 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2806 src_val
= *src_pixel
++;
2807 *dst_pixel
++ = rgb_lookup_colortable(dst
,
2808 src_val
>> src
->red_shift
,
2809 src_val
>> src
->green_shift
,
2810 src_val
>> src
->blue_shift
);
2812 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2813 dst_start
+= dst
->stride
;
2814 src_start
+= src
->stride
/ 4;
2819 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2821 dst_pixel
= dst_start
;
2822 src_pixel
= src_start
;
2823 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2825 src_val
= *src_pixel
++;
2826 *dst_pixel
++ = rgb_lookup_colortable(dst
,
2827 get_field(src_val
, src
->red_shift
, src
->red_len
),
2828 get_field(src_val
, src
->green_shift
, src
->green_len
),
2829 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
2831 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2832 dst_start
+= dst
->stride
;
2833 src_start
+= src
->stride
/ 4;
2841 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2843 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2845 dst_pixel
= dst_start
;
2846 src_pixel
= src_start
;
2847 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, src_pixel
+= 3)
2849 *dst_pixel
++ = rgb_lookup_colortable(dst
, src_pixel
[2], src_pixel
[1], src_pixel
[0] );
2851 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2852 dst_start
+= dst
->stride
;
2853 src_start
+= src
->stride
;
2860 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2861 if(src
->funcs
== &funcs_555
)
2863 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2865 dst_pixel
= dst_start
;
2866 src_pixel
= src_start
;
2867 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2869 src_val
= *src_pixel
++;
2870 *dst_pixel
++ = rgb_lookup_colortable(dst
,
2871 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
2872 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
2873 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07) );
2875 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2876 dst_start
+= dst
->stride
;
2877 src_start
+= src
->stride
/ 2;
2880 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2882 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2884 dst_pixel
= dst_start
;
2885 src_pixel
= src_start
;
2886 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2888 src_val
= *src_pixel
++;
2889 *dst_pixel
++ = rgb_lookup_colortable(dst
,
2890 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2891 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
2892 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
2893 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
2894 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2895 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
2897 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2898 dst_start
+= dst
->stride
;
2899 src_start
+= src
->stride
/ 2;
2902 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2904 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2906 dst_pixel
= dst_start
;
2907 src_pixel
= src_start
;
2908 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2910 src_val
= *src_pixel
++;
2911 *dst_pixel
++ = rgb_lookup_colortable(dst
,
2912 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2913 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
2914 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
2915 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
2916 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2917 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
2919 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2920 dst_start
+= dst
->stride
;
2921 src_start
+= src
->stride
/ 2;
2926 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2928 dst_pixel
= dst_start
;
2929 src_pixel
= src_start
;
2930 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2932 src_val
= *src_pixel
++;
2933 *dst_pixel
++ = rgb_lookup_colortable(dst
,
2934 get_field(src_val
, src
->red_shift
, src
->red_len
),
2935 get_field(src_val
, src
->green_shift
, src
->green_len
),
2936 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
2938 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2939 dst_start
+= dst
->stride
;
2940 src_start
+= src
->stride
/ 2;
2948 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2950 if(color_tables_match(dst
, src
))
2952 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
2953 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2956 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2958 memcpy(dst_start
, src_start
, src_rect
->right
- src_rect
->left
);
2959 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
2960 dst_start
+= dst
->stride
;
2961 src_start
+= src
->stride
;
2967 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2968 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2970 dst_pixel
= dst_start
;
2971 src_pixel
= src_start
;
2972 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2974 RGBQUAD rgb
= color_table
[*src_pixel
++];
2975 *dst_pixel
++ = rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
2977 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2978 dst_start
+= dst
->stride
;
2979 src_start
+= src
->stride
;
2987 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2988 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2989 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2991 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
2992 src_pixel
= src_start
;
2993 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2997 rgb
= color_table
[*src_pixel
++ & 0xf];
2999 rgb
= color_table
[*src_pixel
>> 4];
3000 dst_start
[x
] = rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
3002 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3003 dst_start
+= dst
->stride
;
3004 src_start
+= src
->stride
;
3011 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3012 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
3013 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3015 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
3016 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
3019 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
3020 rgb
= color_table
[src_val
];
3021 dst_start
[x
] = rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
3023 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3024 dst_start
+= dst
->stride
;
3025 src_start
+= src
->stride
;
3032 static void convert_to_4(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
3034 BYTE
*dst_start
= get_pixel_ptr_4(dst
, 0, 0), *dst_pixel
, dst_val
;
3035 INT x
, y
, pad_size
= ((dst
->width
+ 7) & ~7) / 2 - (src_rect
->right
- src_rect
->left
+ 1) / 2;
3038 switch(src
->bit_count
)
3042 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3044 if(src
->funcs
== &funcs_8888
)
3046 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3048 dst_pixel
= dst_start
;
3049 src_pixel
= src_start
;
3050 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3052 src_val
= *src_pixel
++;
3053 dst_val
= rgb_to_pixel_colortable(dst
, src_val
>> 16, src_val
>> 8, src_val
);
3054 if((x
- src_rect
->left
) & 1)
3056 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3060 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3064 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3065 memset(dst_pixel
, 0, pad_size
);
3067 dst_start
+= dst
->stride
;
3068 src_start
+= src
->stride
/ 4;
3071 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
3073 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3075 dst_pixel
= dst_start
;
3076 src_pixel
= src_start
;
3077 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3079 src_val
= *src_pixel
++;
3080 dst_val
= rgb_to_pixel_colortable(dst
,
3081 src_val
>> src
->red_shift
,
3082 src_val
>> src
->green_shift
,
3083 src_val
>> src
->blue_shift
);
3084 if((x
- src_rect
->left
) & 1)
3086 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3090 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3094 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3095 memset(dst_pixel
, 0, pad_size
);
3097 dst_start
+= dst
->stride
;
3098 src_start
+= src
->stride
/ 4;
3103 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3105 dst_pixel
= dst_start
;
3106 src_pixel
= src_start
;
3107 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3109 src_val
= *src_pixel
++;
3110 dst_val
= rgb_to_pixel_colortable(dst
,
3111 get_field(src_val
, src
->red_shift
, src
->red_len
),
3112 get_field(src_val
, src
->green_shift
, src
->green_len
),
3113 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3114 if((x
- src_rect
->left
) & 1)
3116 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3120 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3124 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3125 memset(dst_pixel
, 0, pad_size
);
3127 dst_start
+= dst
->stride
;
3128 src_start
+= src
->stride
/ 4;
3136 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3138 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3140 dst_pixel
= dst_start
;
3141 src_pixel
= src_start
;
3142 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, src_pixel
+= 3)
3144 dst_val
= rgb_to_pixel_colortable(dst
, src_pixel
[2], src_pixel
[1], src_pixel
[0]);
3146 if((x
- src_rect
->left
) & 1)
3148 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3152 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3156 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3157 memset(dst_pixel
, 0, pad_size
);
3159 dst_start
+= dst
->stride
;
3160 src_start
+= src
->stride
;
3167 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3168 if(src
->funcs
== &funcs_555
)
3170 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3172 dst_pixel
= dst_start
;
3173 src_pixel
= src_start
;
3174 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3176 src_val
= *src_pixel
++;
3177 dst_val
= rgb_to_pixel_colortable(dst
,
3178 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
3179 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
3180 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07) );
3181 if((x
- src_rect
->left
) & 1)
3183 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3187 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3191 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3192 memset(dst_pixel
, 0, pad_size
);
3194 dst_start
+= dst
->stride
;
3195 src_start
+= src
->stride
/ 2;
3198 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
3200 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3202 dst_pixel
= dst_start
;
3203 src_pixel
= src_start
;
3204 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3206 src_val
= *src_pixel
++;
3207 dst_val
= rgb_to_pixel_colortable(dst
,
3208 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3209 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3210 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
3211 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
3212 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3213 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
3214 if((x
- src_rect
->left
) & 1)
3216 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3220 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3224 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3225 memset(dst_pixel
, 0, pad_size
);
3227 dst_start
+= dst
->stride
;
3228 src_start
+= src
->stride
/ 2;
3231 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
3233 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3235 dst_pixel
= dst_start
;
3236 src_pixel
= src_start
;
3237 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3239 src_val
= *src_pixel
++;
3240 dst_val
= rgb_to_pixel_colortable(dst
,
3241 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3242 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3243 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
3244 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
3245 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3246 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
3247 if((x
- src_rect
->left
) & 1)
3249 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3253 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3257 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3258 memset(dst_pixel
, 0, pad_size
);
3260 dst_start
+= dst
->stride
;
3261 src_start
+= src
->stride
/ 2;
3266 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3268 dst_pixel
= dst_start
;
3269 src_pixel
= src_start
;
3270 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3272 src_val
= *src_pixel
++;
3273 dst_val
= rgb_to_pixel_colortable(dst
,
3274 get_field(src_val
, src
->red_shift
, src
->red_len
),
3275 get_field(src_val
, src
->green_shift
, src
->green_len
),
3276 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3277 if((x
- src_rect
->left
) & 1)
3279 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3283 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3287 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3288 memset(dst_pixel
, 0, pad_size
);
3290 dst_start
+= dst
->stride
;
3291 src_start
+= src
->stride
/ 2;
3299 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3300 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3302 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3304 dst_pixel
= dst_start
;
3305 src_pixel
= src_start
;
3306 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3308 RGBQUAD rgb
= color_table
[*src_pixel
++];
3309 dst_val
= rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
3310 if((x
- src_rect
->left
) & 1)
3312 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3316 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3320 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3321 memset(dst_pixel
, 0, pad_size
);
3323 dst_start
+= dst
->stride
;
3324 src_start
+= src
->stride
;
3331 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3333 if(color_tables_match(dst
, src
) && ((src
->rect
.left
+ src_rect
->left
) & 1) == 0)
3335 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
3336 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
3339 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3341 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
+ 1) / 2);
3342 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
+ 1) / 2, 0, pad_size
);
3343 dst_start
+= dst
->stride
;
3344 src_start
+= src
->stride
;
3350 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3351 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3353 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
3354 dst_pixel
= dst_start
;
3355 src_pixel
= src_start
;
3356 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, pos
++)
3360 rgb
= color_table
[*src_pixel
++ & 0xf];
3362 rgb
= color_table
[*src_pixel
>> 4];
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
;
3386 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3387 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
3388 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3390 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
3391 dst_pixel
= dst_start
;
3392 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, pos
++)
3395 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
3396 rgb
= color_table
[src_val
];
3397 dst_val
= rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
3398 if((x
- src_rect
->left
) & 1)
3400 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3404 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3408 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3409 memset(dst_pixel
, 0, pad_size
);
3411 dst_start
+= dst
->stride
;
3412 src_start
+= src
->stride
;
3419 static void convert_to_1(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
3421 BYTE
*dst_start
= get_pixel_ptr_1(dst
, 0, 0), *dst_pixel
, dst_val
;
3422 INT x
, y
, pad_size
= ((dst
->width
+ 31) & ~31) / 8 - (src_rect
->right
- src_rect
->left
+ 7) / 8;
3426 switch(src
->bit_count
)
3430 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3432 if(src
->funcs
== &funcs_8888
)
3434 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3436 dst_pixel
= dst_start
;
3437 src_pixel
= src_start
;
3438 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3440 src_val
= *src_pixel
++;
3441 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
>> 16, src_val
>> 8, src_val
);
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;
3461 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
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_mono(dst
, dither
, x
, y
,
3471 src_val
>> src
->red_shift
,
3472 src_val
>> src
->green_shift
,
3473 src_val
>> src
->blue_shift
);
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;
3495 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3497 dst_pixel
= dst_start
;
3498 src_pixel
= src_start
;
3499 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3501 src_val
= *src_pixel
++;
3502 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
,
3503 get_field(src_val
, src
->red_shift
, src
->red_len
),
3504 get_field(src_val
, src
->green_shift
, src
->green_len
),
3505 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3507 if(bit_pos
== 0) *dst_pixel
= 0;
3508 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3518 if(bit_pos
!= 0) dst_pixel
++;
3519 memset(dst_pixel
, 0, pad_size
);
3521 dst_start
+= dst
->stride
;
3522 src_start
+= src
->stride
/ 4;
3530 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3532 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3534 dst_pixel
= dst_start
;
3535 src_pixel
= src_start
;
3536 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++, src_pixel
+= 3)
3538 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_pixel
[2], src_pixel
[1], src_pixel
[0]);
3540 if(bit_pos
== 0) *dst_pixel
= 0;
3541 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3551 if(bit_pos
!= 0) dst_pixel
++;
3552 memset(dst_pixel
, 0, pad_size
);
3554 dst_start
+= dst
->stride
;
3555 src_start
+= src
->stride
;
3562 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3563 if(src
->funcs
== &funcs_555
)
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_mono(dst
, dither
, x
, y
,
3573 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
3574 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
3575 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07));
3577 if(bit_pos
== 0) *dst_pixel
= 0;
3578 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3588 if(bit_pos
!= 0) dst_pixel
++;
3589 memset(dst_pixel
, 0, pad_size
);
3591 dst_start
+= dst
->stride
;
3592 src_start
+= src
->stride
/ 2;
3595 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
3597 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3599 dst_pixel
= dst_start
;
3600 src_pixel
= src_start
;
3601 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3603 src_val
= *src_pixel
++;
3604 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
,
3605 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3606 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3607 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
3608 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
3609 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3610 (((src_val
>> src
->blue_shift
) >> 2) & 0x07));
3611 if(bit_pos
== 0) *dst_pixel
= 0;
3612 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3622 if(bit_pos
!= 0) dst_pixel
++;
3623 memset(dst_pixel
, 0, pad_size
);
3625 dst_start
+= dst
->stride
;
3626 src_start
+= src
->stride
/ 2;
3629 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
3631 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3633 dst_pixel
= dst_start
;
3634 src_pixel
= src_start
;
3635 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3637 src_val
= *src_pixel
++;
3638 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
,
3639 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3640 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3641 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
3642 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
3643 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3644 (((src_val
>> src
->blue_shift
) >> 2) & 0x07));
3645 if(bit_pos
== 0) *dst_pixel
= 0;
3646 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3656 if(bit_pos
!= 0) dst_pixel
++;
3657 memset(dst_pixel
, 0, pad_size
);
3659 dst_start
+= dst
->stride
;
3660 src_start
+= src
->stride
/ 2;
3665 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3667 dst_pixel
= dst_start
;
3668 src_pixel
= src_start
;
3669 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3671 src_val
= *src_pixel
++;
3672 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
,
3673 get_field(src_val
, src
->red_shift
, src
->red_len
),
3674 get_field(src_val
, src
->green_shift
, src
->green_len
),
3675 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3676 if(bit_pos
== 0) *dst_pixel
= 0;
3677 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3687 if(bit_pos
!= 0) dst_pixel
++;
3688 memset(dst_pixel
, 0, pad_size
);
3690 dst_start
+= dst
->stride
;
3691 src_start
+= src
->stride
/ 2;
3699 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3700 BYTE
*src_start
= get_pixel_ptr_8(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
++)
3708 RGBQUAD rgb
= color_table
[*src_pixel
++];
3709 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
3711 if(bit_pos
== 0) *dst_pixel
= 0;
3712 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3722 if(bit_pos
!= 0) dst_pixel
++;
3723 memset(dst_pixel
, 0, pad_size
);
3725 dst_start
+= dst
->stride
;
3726 src_start
+= src
->stride
;
3733 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3734 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3736 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3738 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
3739 dst_pixel
= dst_start
;
3740 src_pixel
= src_start
;
3741 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++, pos
++)
3745 rgb
= color_table
[*src_pixel
++ & 0xf];
3747 rgb
= color_table
[*src_pixel
>> 4];
3748 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
3750 if(bit_pos
== 0) *dst_pixel
= 0;
3751 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3761 if(bit_pos
!= 0) dst_pixel
++;
3762 memset(dst_pixel
, 0, pad_size
);
3764 dst_start
+= dst
->stride
;
3765 src_start
+= src
->stride
;
3770 /* Note that while MSDN states that a 1 bpp dib brush -> mono dc
3771 uses text/bkgnd colours instead of the dib's colour table, this
3772 doesn't appear to be the case for a dc backed by a
3777 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3778 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
3779 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3781 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
3782 dst_pixel
= dst_start
;
3783 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++, pos
++)
3786 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
3787 rgb
= color_table
[src_val
];
3788 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
3790 if(bit_pos
== 0) *dst_pixel
= 0;
3791 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3801 if(bit_pos
!= 0) dst_pixel
++;
3802 memset(dst_pixel
, 0, pad_size
);
3804 dst_start
+= dst
->stride
;
3805 src_start
+= src
->stride
;
3812 static void convert_to_null(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
3816 static inline BYTE
blend_color(BYTE dst
, BYTE src
, DWORD alpha
)
3818 return (src
* alpha
+ dst
* (255 - alpha
) + 127) / 255;
3821 static inline DWORD
blend_argb_constant_alpha( DWORD dst
, DWORD src
, DWORD alpha
)
3823 return (blend_color( dst
, src
, alpha
) |
3824 blend_color( dst
>> 8, src
>> 8, alpha
) << 8 |
3825 blend_color( dst
>> 16, src
>> 16, alpha
) << 16 |
3826 blend_color( dst
>> 24, src
>> 24, alpha
) << 24);
3829 static inline DWORD
blend_argb( DWORD dst
, DWORD src
)
3832 BYTE g
= (BYTE
)(src
>> 8);
3833 BYTE r
= (BYTE
)(src
>> 16);
3834 DWORD alpha
= (BYTE
)(src
>> 24);
3835 return ((b
+ ((BYTE
)dst
* (255 - alpha
) + 127) / 255) |
3836 (g
+ ((BYTE
)(dst
>> 8) * (255 - alpha
) + 127) / 255) << 8 |
3837 (r
+ ((BYTE
)(dst
>> 16) * (255 - alpha
) + 127) / 255) << 16 |
3838 (alpha
+ ((BYTE
)(dst
>> 24) * (255 - alpha
) + 127) / 255) << 24);
3841 static inline DWORD
blend_argb_alpha( DWORD dst
, DWORD src
, DWORD alpha
)
3843 BYTE b
= ((BYTE
)src
* alpha
+ 127) / 255;
3844 BYTE g
= ((BYTE
)(src
>> 8) * alpha
+ 127) / 255;
3845 BYTE r
= ((BYTE
)(src
>> 16) * alpha
+ 127) / 255;
3846 alpha
= ((BYTE
)(src
>> 24) * alpha
+ 127) / 255;
3847 return ((b
+ ((BYTE
)dst
* (255 - alpha
) + 127) / 255) |
3848 (g
+ ((BYTE
)(dst
>> 8) * (255 - alpha
) + 127) / 255) << 8 |
3849 (r
+ ((BYTE
)(dst
>> 16) * (255 - alpha
) + 127) / 255) << 16 |
3850 (alpha
+ ((BYTE
)(dst
>> 24) * (255 - alpha
) + 127) / 255) << 24);
3853 static inline DWORD
blend_rgb( BYTE dst_r
, BYTE dst_g
, BYTE dst_b
, DWORD src
, BLENDFUNCTION blend
)
3855 if (blend
.AlphaFormat
& AC_SRC_ALPHA
)
3857 DWORD alpha
= blend
.SourceConstantAlpha
;
3858 BYTE src_b
= ((BYTE
)src
* alpha
+ 127) / 255;
3859 BYTE src_g
= ((BYTE
)(src
>> 8) * alpha
+ 127) / 255;
3860 BYTE src_r
= ((BYTE
)(src
>> 16) * alpha
+ 127) / 255;
3861 alpha
= ((BYTE
)(src
>> 24) * alpha
+ 127) / 255;
3862 return ((src_b
+ (dst_b
* (255 - alpha
) + 127) / 255) |
3863 (src_g
+ (dst_g
* (255 - alpha
) + 127) / 255) << 8 |
3864 (src_r
+ (dst_r
* (255 - alpha
) + 127) / 255) << 16);
3866 return (blend_color( dst_b
, src
, blend
.SourceConstantAlpha
) |
3867 blend_color( dst_g
, src
>> 8, blend
.SourceConstantAlpha
) << 8 |
3868 blend_color( dst_r
, src
>> 16, blend
.SourceConstantAlpha
) << 16);
3871 static void blend_rect_8888(const dib_info
*dst
, const RECT
*rc
,
3872 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3874 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
3875 DWORD
*dst_ptr
= get_pixel_ptr_32( dst
, rc
->left
, rc
->top
);
3878 if (blend
.AlphaFormat
& AC_SRC_ALPHA
)
3880 if (blend
.SourceConstantAlpha
== 255)
3881 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
3882 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3883 dst_ptr
[x
] = blend_argb( dst_ptr
[x
], src_ptr
[x
] );
3885 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
3886 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3887 dst_ptr
[x
] = blend_argb_alpha( dst_ptr
[x
], src_ptr
[x
], blend
.SourceConstantAlpha
);
3890 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
3891 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3892 dst_ptr
[x
] = blend_argb_constant_alpha( dst_ptr
[x
], src_ptr
[x
], blend
.SourceConstantAlpha
);
3895 static void blend_rect_32(const dib_info
*dst
, const RECT
*rc
,
3896 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3898 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
3899 DWORD
*dst_ptr
= get_pixel_ptr_32( dst
, rc
->left
, rc
->top
);
3902 if (dst
->red_len
== 8 && dst
->green_len
== 8 && dst
->blue_len
== 8)
3904 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
3906 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3908 DWORD val
= blend_rgb( dst_ptr
[x
] >> dst
->red_shift
,
3909 dst_ptr
[x
] >> dst
->green_shift
,
3910 dst_ptr
[x
] >> dst
->blue_shift
,
3911 src_ptr
[x
], blend
);
3912 dst_ptr
[x
] = ((( val
& 0xff) << dst
->blue_shift
) |
3913 (((val
>> 8) & 0xff) << dst
->green_shift
) |
3914 (((val
>> 16) & 0xff) << dst
->red_shift
));
3920 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
3922 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3924 DWORD val
= blend_rgb( get_field( dst_ptr
[x
], dst
->red_shift
, dst
->red_len
),
3925 get_field( dst_ptr
[x
], dst
->green_shift
, dst
->green_len
),
3926 get_field( dst_ptr
[x
], dst
->blue_shift
, dst
->blue_len
),
3927 src_ptr
[x
], blend
);
3928 dst_ptr
[x
] = (put_field( val
>> 16, dst
->red_shift
, dst
->red_len
) |
3929 put_field( val
>> 8, dst
->green_shift
, dst
->green_len
) |
3930 put_field( val
, dst
->blue_shift
, dst
->blue_len
));
3936 static void blend_rect_24(const dib_info
*dst
, const RECT
*rc
,
3937 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3939 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
3940 BYTE
*dst_ptr
= get_pixel_ptr_24( dst
, rc
->left
, rc
->top
);
3943 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
3945 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3947 DWORD val
= blend_rgb( dst_ptr
[x
* 3 + 2], dst_ptr
[x
* 3 + 1], dst_ptr
[x
* 3],
3948 src_ptr
[x
], blend
);
3949 dst_ptr
[x
* 3] = val
;
3950 dst_ptr
[x
* 3 + 1] = val
>> 8;
3951 dst_ptr
[x
* 3 + 2] = val
>> 16;
3956 static void blend_rect_555(const dib_info
*dst
, const RECT
*rc
,
3957 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3959 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
3960 WORD
*dst_ptr
= get_pixel_ptr_16( dst
, rc
->left
, rc
->top
);
3963 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 2, src_ptr
+= src
->stride
/ 4)
3965 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3967 DWORD val
= blend_rgb( ((dst_ptr
[x
] >> 7) & 0xf8) | ((dst_ptr
[x
] >> 12) & 0x07),
3968 ((dst_ptr
[x
] >> 2) & 0xf8) | ((dst_ptr
[x
] >> 7) & 0x07),
3969 ((dst_ptr
[x
] << 3) & 0xf8) | ((dst_ptr
[x
] >> 2) & 0x07),
3970 src_ptr
[x
], blend
);
3971 dst_ptr
[x
] = ((val
>> 9) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 3) & 0x001f);
3976 static void blend_rect_16(const dib_info
*dst
, const RECT
*rc
,
3977 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3979 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
3980 WORD
*dst_ptr
= get_pixel_ptr_16( dst
, rc
->left
, rc
->top
);
3983 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 2, src_ptr
+= src
->stride
/ 4)
3985 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3987 DWORD val
= blend_rgb( get_field( dst_ptr
[x
], dst
->red_shift
, dst
->red_len
),
3988 get_field( dst_ptr
[x
], dst
->green_shift
, dst
->green_len
),
3989 get_field( dst_ptr
[x
], dst
->blue_shift
, dst
->blue_len
),
3990 src_ptr
[x
], blend
);
3991 dst_ptr
[x
] = (put_field((val
>> 16), dst
->red_shift
, dst
->red_len
) |
3992 put_field((val
>> 8), dst
->green_shift
, dst
->green_len
) |
3993 put_field( val
, dst
->blue_shift
, dst
->blue_len
));
3998 static void blend_rect_8(const dib_info
*dst
, const RECT
*rc
,
3999 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4001 const RGBQUAD
*color_table
= get_dib_color_table( dst
);
4002 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4003 BYTE
*dst_ptr
= get_pixel_ptr_8( dst
, rc
->left
, rc
->top
);
4006 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
4008 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4010 RGBQUAD rgb
= color_table
[dst_ptr
[x
]];
4011 DWORD val
= blend_rgb( rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
, src_ptr
[x
], blend
);
4012 dst_ptr
[x
] = rgb_lookup_colortable( dst
, val
>> 16, val
>> 8, val
);
4017 static void blend_rect_4(const dib_info
*dst
, const RECT
*rc
,
4018 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4020 const RGBQUAD
*color_table
= get_dib_color_table( dst
);
4021 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4022 BYTE
*dst_ptr
= get_pixel_ptr_4( dst
, rc
->left
, rc
->top
);
4025 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
4027 for (i
= 0, x
= (dst
->rect
.left
+ rc
->left
) & 1; i
< rc
->right
- rc
->left
; i
++, x
++)
4029 DWORD val
= ((x
& 1) ? dst_ptr
[x
/ 2] : (dst_ptr
[x
/ 2] >> 4)) & 0x0f;
4030 RGBQUAD rgb
= color_table
[val
];
4031 val
= blend_rgb( rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
, src_ptr
[i
], blend
);
4032 val
= rgb_lookup_colortable( dst
, val
>> 16, val
>> 8, val
);
4034 dst_ptr
[x
/ 2] = val
| (dst_ptr
[x
/ 2] & 0xf0);
4036 dst_ptr
[x
/ 2] = (val
<< 4) | (dst_ptr
[x
/ 2] & 0x0f);
4041 static void blend_rect_1(const dib_info
*dst
, const RECT
*rc
,
4042 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4044 const RGBQUAD
*color_table
= get_dib_color_table( dst
);
4045 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4046 BYTE
*dst_ptr
= get_pixel_ptr_1( dst
, rc
->left
, rc
->top
);
4049 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
4051 for (i
= 0, x
= (dst
->rect
.left
+ rc
->left
) & 7; i
< rc
->right
- rc
->left
; i
++, x
++)
4053 DWORD val
= (dst_ptr
[x
/ 8] & pixel_masks_1
[x
% 8]) ? 1 : 0;
4054 RGBQUAD rgb
= color_table
[val
];
4055 val
= blend_rgb( rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
, src_ptr
[i
], blend
);
4056 val
= rgb_to_pixel_colortable(dst
, val
>> 16, val
>> 8, val
) ? 0xff : 0;
4057 dst_ptr
[x
/ 8] = (dst_ptr
[x
/ 8] & ~pixel_masks_1
[x
% 8]) | (val
& pixel_masks_1
[x
% 8]);
4062 static void blend_rect_null(const dib_info
*dst
, const RECT
*rc
,
4063 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4067 static inline DWORD
gradient_rgb_8888( const TRIVERTEX
*v
, unsigned int pos
, unsigned int len
)
4070 r
= (v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 256;
4071 g
= (v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 256;
4072 b
= (v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 256;
4073 a
= (v
[0].Alpha
* (len
- pos
) + v
[1].Alpha
* pos
) / len
/ 256;
4074 return a
<< 24 | r
<< 16 | g
<< 8 | b
;
4077 static inline DWORD
gradient_rgb_24( const TRIVERTEX
*v
, unsigned int pos
, unsigned int len
)
4080 r
= (v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 256;
4081 g
= (v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 256;
4082 b
= (v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 256;
4083 return r
<< 16 | g
<< 8 | b
;
4086 static inline WORD
gradient_rgb_555( const TRIVERTEX
*v
, unsigned int pos
, unsigned int len
,
4087 unsigned int x
, unsigned int y
)
4089 int r
= (v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4090 int g
= (v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4091 int b
= (v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4092 r
= min( 31, max( 0, r
/ 16 ));
4093 g
= min( 31, max( 0, g
/ 16 ));
4094 b
= min( 31, max( 0, b
/ 16 ));
4095 return (r
<< 10) | (g
<< 5) | b
;
4098 static inline BYTE
gradient_rgb_8( const dib_info
*dib
, const TRIVERTEX
*v
,
4099 unsigned int pos
, unsigned int len
, unsigned int x
, unsigned int y
)
4101 BYTE r
= ((v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4102 BYTE g
= ((v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4103 BYTE b
= ((v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4104 return rgb_to_pixel_colortable( dib
, r
* 127, g
* 127, b
* 127 );
4107 /* compute the left/right triangle limit for row y */
4108 static inline void triangle_coords( const TRIVERTEX
*v
, const RECT
*rc
, int y
, int *left
, int *right
)
4112 if (y
< v
[1].y
) x1
= edge_coord( y
, v
[0].x
, v
[0].y
, v
[1].x
, v
[1].y
);
4113 else x1
= edge_coord( y
, v
[1].x
, v
[1].y
, v
[2].x
, v
[2].y
);
4115 x2
= edge_coord( y
, v
[0].x
, v
[0].y
, v
[2].x
, v
[2].y
);
4117 *left
= max( rc
->left
, min( x1
, x2
) );
4118 *right
= min( rc
->right
, max( x1
, x2
) );
4121 /* compute the matrix determinant for triangular barycentric coordinates (constant across the triangle) */
4122 static inline int triangle_det( const TRIVERTEX
*v
)
4124 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
);
4127 /* compute the barycentric weights for a given point inside the triangle */
4128 static inline void triangle_weights( const TRIVERTEX
*v
, int x
, int y
, INT64
*l1
, INT64
*l2
)
4130 *l1
= (v
[1].y
- v
[2].y
) * (x
- v
[2].x
) - (v
[1].x
- v
[2].x
) * (y
- v
[2].y
);
4131 *l2
= (v
[2].y
- v
[0].y
) * (x
- v
[2].x
) - (v
[2].x
- v
[0].x
) * (y
- v
[2].y
);
4134 static inline DWORD
gradient_triangle_8888( const TRIVERTEX
*v
, int x
, int y
, int det
)
4139 triangle_weights( v
, x
, y
, &l1
, &l2
);
4140 r
= (v
[0].Red
* l1
+ v
[1].Red
* l2
+ v
[2].Red
* (det
- l1
- l2
)) / det
/ 256;
4141 g
= (v
[0].Green
* l1
+ v
[1].Green
* l2
+ v
[2].Green
* (det
- l1
- l2
)) / det
/ 256;
4142 b
= (v
[0].Blue
* l1
+ v
[1].Blue
* l2
+ v
[2].Blue
* (det
- l1
- l2
)) / det
/ 256;
4143 a
= (v
[0].Alpha
* l1
+ v
[1].Alpha
* l2
+ v
[2].Alpha
* (det
- l1
- l2
)) / det
/ 256;
4144 return a
<< 24 | r
<< 16 | g
<< 8 | b
;
4147 static inline DWORD
gradient_triangle_24( const TRIVERTEX
*v
, int x
, int y
, int det
)
4152 triangle_weights( v
, x
, y
, &l1
, &l2
);
4153 r
= (v
[0].Red
* l1
+ v
[1].Red
* l2
+ v
[2].Red
* (det
- l1
- l2
)) / det
/ 256;
4154 g
= (v
[0].Green
* l1
+ v
[1].Green
* l2
+ v
[2].Green
* (det
- l1
- l2
)) / det
/ 256;
4155 b
= (v
[0].Blue
* l1
+ v
[1].Blue
* l2
+ v
[2].Blue
* (det
- l1
- l2
)) / det
/ 256;
4156 return r
<< 16 | g
<< 8 | b
;
4159 static inline DWORD
gradient_triangle_555( const TRIVERTEX
*v
, int x
, int y
, int det
)
4164 triangle_weights( v
, x
, y
, &l1
, &l2
);
4165 r
= (v
[0].Red
* l1
+ v
[1].Red
* l2
+ v
[2].Red
* (det
- l1
- l2
)) / det
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4166 g
= (v
[0].Green
* l1
+ v
[1].Green
* l2
+ v
[2].Green
* (det
- l1
- l2
)) / det
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4167 b
= (v
[0].Blue
* l1
+ v
[1].Blue
* l2
+ v
[2].Blue
* (det
- l1
- l2
)) / det
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4168 r
= min( 31, max( 0, r
/ 16 ));
4169 g
= min( 31, max( 0, g
/ 16 ));
4170 b
= min( 31, max( 0, b
/ 16 ));
4171 return (r
<< 10) | (g
<< 5) | b
;
4174 static inline DWORD
gradient_triangle_8( const dib_info
*dib
, const TRIVERTEX
*v
, int x
, int y
, int det
)
4179 triangle_weights( v
, x
, y
, &l1
, &l2
);
4180 r
= ((v
[0].Red
* l1
+ v
[1].Red
* l2
+ v
[2].Red
* (det
- l1
- l2
)) / det
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4181 g
= ((v
[0].Green
* l1
+ v
[1].Green
* l2
+ v
[2].Green
* (det
- l1
- l2
)) / det
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4182 b
= ((v
[0].Blue
* l1
+ v
[1].Blue
* l2
+ v
[2].Blue
* (det
- l1
- l2
)) / det
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4183 return rgb_to_pixel_colortable( dib
, r
* 127, g
* 127, b
* 127 );
4186 static BOOL
gradient_rect_8888( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4188 DWORD
*ptr
= get_pixel_ptr_32( dib
, rc
->left
, rc
->top
);
4189 int x
, y
, left
, right
, det
;
4193 case GRADIENT_FILL_RECT_H
:
4194 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4195 ptr
[x
] = gradient_rgb_8888( v
, rc
->left
+ x
- v
[0].x
, v
[1].x
- v
[0].x
);
4197 for (y
= rc
->top
+ 1; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4198 memcpy( ptr
+ dib
->stride
/ 4, ptr
, (rc
->right
- rc
->left
) * 4 );
4201 case GRADIENT_FILL_RECT_V
:
4202 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4204 DWORD val
= gradient_rgb_8888( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
4205 for (x
= 0; x
< rc
->right
- rc
->left
; x
++) ptr
[x
] = val
;
4209 case GRADIENT_FILL_TRIANGLE
:
4210 if (!(det
= triangle_det( v
))) return FALSE
;
4211 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4213 triangle_coords( v
, rc
, y
, &left
, &right
);
4214 for (x
= left
; x
< right
; x
++) ptr
[x
- rc
->left
] = gradient_triangle_8888( v
, x
, y
, det
);
4221 static BOOL
gradient_rect_32( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4223 DWORD
*ptr
= get_pixel_ptr_32( dib
, rc
->left
, rc
->top
);
4224 int x
, y
, left
, right
, det
;
4228 case GRADIENT_FILL_RECT_H
:
4229 if (dib
->red_len
== 8 && dib
->green_len
== 8 && dib
->blue_len
== 8)
4231 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4233 DWORD val
= gradient_rgb_24( v
, rc
->left
+ x
- v
[0].x
, v
[1].x
- v
[0].x
);
4234 ptr
[x
] = ((( val
& 0xff) << dib
->blue_shift
) |
4235 (((val
>> 8) & 0xff) << dib
->green_shift
) |
4236 (((val
>> 16) & 0xff) << dib
->red_shift
));
4241 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4243 DWORD val
= gradient_rgb_24( v
, rc
->left
+ x
- v
[0].x
, v
[1].x
- v
[0].x
);
4244 ptr
[x
] = (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
4245 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
4246 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
4250 for (y
= rc
->top
+ 1; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4251 memcpy( ptr
+ dib
->stride
/ 4, ptr
, (rc
->right
- rc
->left
) * 4 );
4254 case GRADIENT_FILL_RECT_V
:
4255 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
4257 DWORD val
= gradient_rgb_24( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
4258 if (dib
->red_len
== 8 && dib
->green_len
== 8 && dib
->blue_len
== 8)
4259 val
= ((( val
& 0xff) << dib
->blue_shift
) |
4260 (((val
>> 8) & 0xff) << dib
->green_shift
) |
4261 (((val
>> 16) & 0xff) << dib
->red_shift
));
4263 val
= (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
4264 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
4265 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
4267 for (x
= 0; x
< rc
->right
- rc
->left
; x
++) ptr
[x
] = val
;
4268 ptr
+= dib
->stride
/ 4;
4272 case GRADIENT_FILL_TRIANGLE
:
4273 if (!(det
= triangle_det( v
))) return FALSE
;
4274 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4276 triangle_coords( v
, rc
, y
, &left
, &right
);
4278 if (dib
->red_len
== 8 && dib
->green_len
== 8 && dib
->blue_len
== 8)
4279 for (x
= left
; x
< right
; x
++)
4281 DWORD val
= gradient_triangle_24( v
, x
, y
, det
);
4282 ptr
[x
- rc
->left
] = ((( val
& 0xff) << dib
->blue_shift
) |
4283 (((val
>> 8) & 0xff) << dib
->green_shift
) |
4284 (((val
>> 16) & 0xff) << dib
->red_shift
));
4287 for (x
= left
; x
< right
; x
++)
4289 DWORD val
= gradient_triangle_24( v
, x
, y
, det
);
4290 ptr
[x
- rc
->left
] = (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
4291 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
4292 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
4300 static BOOL
gradient_rect_24( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4302 BYTE
*ptr
= get_pixel_ptr_24( dib
, rc
->left
, rc
->top
);
4303 int x
, y
, left
, right
, det
;
4307 case GRADIENT_FILL_RECT_H
:
4308 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4310 DWORD val
= gradient_rgb_24( v
, rc
->left
+ x
- v
[0].x
, v
[1].x
- v
[0].x
);
4312 ptr
[x
* 3 + 1] = val
>> 8;
4313 ptr
[x
* 3 + 2] = val
>> 16;
4316 for (y
= rc
->top
+ 1; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4317 memcpy( ptr
+ dib
->stride
, ptr
, (rc
->right
- rc
->left
) * 3 );
4320 case GRADIENT_FILL_RECT_V
:
4321 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4323 DWORD val
= gradient_rgb_24( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
4324 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4327 ptr
[x
* 3 + 1] = val
>> 8;
4328 ptr
[x
* 3 + 2] = val
>> 16;
4333 case GRADIENT_FILL_TRIANGLE
:
4334 if (!(det
= triangle_det( v
))) return FALSE
;
4335 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4337 triangle_coords( v
, rc
, y
, &left
, &right
);
4338 for (x
= left
; x
< right
; x
++)
4340 DWORD val
= gradient_triangle_24( v
, x
, y
, det
);
4341 ptr
[(x
- rc
->left
) * 3] = val
;
4342 ptr
[(x
- rc
->left
) * 3 + 1] = val
>> 8;
4343 ptr
[(x
- rc
->left
) * 3 + 2] = val
>> 16;
4351 static BOOL
gradient_rect_555( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4353 WORD
*ptr
= get_pixel_ptr_16( dib
, rc
->left
, rc
->top
);
4354 int x
, y
, left
, right
, det
;
4358 case GRADIENT_FILL_RECT_H
:
4359 for (y
= rc
->top
; y
< min( rc
->top
+ 4, rc
->bottom
); y
++, ptr
+= dib
->stride
/ 2)
4360 for (x
= rc
->left
; x
< rc
->right
; x
++)
4361 ptr
[x
- rc
->left
] = gradient_rgb_555( v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
);
4362 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
4363 memcpy( ptr
, ptr
- dib
->stride
* 2, (rc
->right
- rc
->left
) * 2 );
4366 case GRADIENT_FILL_RECT_V
:
4367 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
4370 for (x
= 0; x
< 4; x
++) values
[x
] = gradient_rgb_555( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
);
4371 for (x
= rc
->left
; x
< rc
->right
; x
++) ptr
[x
- rc
->left
] = values
[x
% 4];
4375 case GRADIENT_FILL_TRIANGLE
:
4376 if (!(det
= triangle_det( v
))) return FALSE
;
4377 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
4379 triangle_coords( v
, rc
, y
, &left
, &right
);
4380 for (x
= left
; x
< right
; x
++) ptr
[x
- rc
->left
] = gradient_triangle_555( v
, x
, y
, det
);
4387 static BOOL
gradient_rect_16( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4389 WORD
*ptr
= get_pixel_ptr_16( dib
, rc
->left
, rc
->top
);
4390 int x
, y
, left
, right
, det
;
4394 case GRADIENT_FILL_RECT_H
:
4395 for (y
= rc
->top
; y
< min( rc
->top
+ 4, rc
->bottom
); y
++, ptr
+= dib
->stride
/ 2)
4396 for (x
= rc
->left
; x
< rc
->right
; x
++)
4398 WORD val
= gradient_rgb_555( v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
);
4399 ptr
[x
- rc
->left
] = (put_field(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07), dib
->red_shift
, dib
->red_len
) |
4400 put_field(((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07), dib
->green_shift
, dib
->green_len
) |
4401 put_field(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07), dib
->blue_shift
, dib
->blue_len
));
4403 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
4404 memcpy( ptr
, ptr
- dib
->stride
* 2, (rc
->right
- rc
->left
) * 2 );
4407 case GRADIENT_FILL_RECT_V
:
4408 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
4411 for (x
= 0; x
< 4; x
++)
4413 WORD val
= gradient_rgb_555( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
);
4414 values
[x
] = (put_field(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07), dib
->red_shift
, dib
->red_len
) |
4415 put_field(((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07), dib
->green_shift
, dib
->green_len
) |
4416 put_field(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07), dib
->blue_shift
, dib
->blue_len
));
4418 for (x
= rc
->left
; x
< rc
->right
; x
++) ptr
[x
- rc
->left
] = values
[x
% 4];
4422 case GRADIENT_FILL_TRIANGLE
:
4423 if (!(det
= triangle_det( v
))) return FALSE
;
4424 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
4426 triangle_coords( v
, rc
, y
, &left
, &right
);
4427 for (x
= left
; x
< right
; x
++)
4429 WORD val
= gradient_triangle_555( v
, x
, y
, det
);
4430 ptr
[x
- rc
->left
] = (put_field(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07), dib
->red_shift
, dib
->red_len
) |
4431 put_field(((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07), dib
->green_shift
, dib
->green_len
) |
4432 put_field(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07), dib
->blue_shift
, dib
->blue_len
));
4440 static BOOL
gradient_rect_8( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4442 BYTE
*ptr
= get_pixel_ptr_8( dib
, rc
->left
, rc
->top
);
4443 int x
, y
, left
, right
, det
;
4447 case GRADIENT_FILL_RECT_H
:
4448 for (y
= rc
->top
; y
< min( rc
->top
+ 16, rc
->bottom
); y
++, ptr
+= dib
->stride
)
4449 for (x
= rc
->left
; x
< rc
->right
; x
++)
4450 ptr
[x
- rc
->left
] = gradient_rgb_8( dib
, v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
);
4451 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4452 memcpy( ptr
, ptr
- dib
->stride
* 16, rc
->right
- rc
->left
);
4455 case GRADIENT_FILL_RECT_V
:
4456 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4459 for (x
= 0; x
< 16; x
++)
4460 values
[x
] = gradient_rgb_8( dib
, v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
);
4461 for (x
= rc
->left
; x
< rc
->right
; x
++) ptr
[x
- rc
->left
] = values
[x
% 16];
4465 case GRADIENT_FILL_TRIANGLE
:
4466 if (!(det
= triangle_det( v
))) return FALSE
;
4467 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4469 triangle_coords( v
, rc
, y
, &left
, &right
);
4470 for (x
= left
; x
< right
; x
++) ptr
[x
- rc
->left
] = gradient_triangle_8( dib
, v
, x
, y
, det
);
4477 static BOOL
gradient_rect_4( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4479 BYTE
*ptr
= get_pixel_ptr_4( dib
, rc
->left
, rc
->top
);
4480 int x
, y
, left
, right
, det
, pos
;
4484 case GRADIENT_FILL_RECT_H
:
4485 for (y
= rc
->top
; y
< min( rc
->top
+ 16, rc
->bottom
); y
++, ptr
+= dib
->stride
)
4487 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 1; x
< rc
->right
; x
++, pos
++)
4489 BYTE val
= gradient_rgb_8( dib
, v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
);
4491 ptr
[pos
/ 2] = val
| (ptr
[pos
/ 2] & 0xf0);
4493 ptr
[pos
/ 2] = (val
<< 4) | (ptr
[pos
/ 2] & 0x0f);
4496 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4499 pos
= (dib
->rect
.left
+ rc
->left
) & 1;
4502 ptr
[0] = (ptr
[-16 * dib
->stride
] & 0x0f) | (ptr
[0] & 0xf0);
4506 for (; x
< rc
->right
- 1; x
+= 2, pos
+= 2) ptr
[pos
/ 2] = ptr
[pos
/ 2 - 16 * dib
->stride
];
4508 ptr
[pos
/ 2] = (ptr
[pos
/ 2] & 0x0f) | (ptr
[pos
/ 2 - 16 * dib
->stride
] & 0xf0);
4512 case GRADIENT_FILL_RECT_V
:
4513 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4516 for (x
= 0; x
< 16; x
++)
4517 values
[x
] = gradient_rgb_8( dib
, v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
);
4518 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 1; x
< rc
->right
; x
++, pos
++)
4520 ptr
[pos
/ 2] = values
[x
% 16] | (ptr
[pos
/ 2] & 0xf0);
4522 ptr
[pos
/ 2] = (values
[x
% 16] << 4) | (ptr
[pos
/ 2] & 0x0f);
4526 case GRADIENT_FILL_TRIANGLE
:
4527 if (!(det
= triangle_det( v
))) return FALSE
;
4528 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4530 triangle_coords( v
, rc
, y
, &left
, &right
);
4531 for (x
= left
, pos
= left
- rc
->left
+ ((dib
->rect
.left
+ rc
->left
) & 1); x
< right
; x
++, pos
++)
4533 BYTE val
= gradient_triangle_8( dib
, v
, x
, y
, det
);
4535 ptr
[pos
/ 2] = val
| (ptr
[pos
/ 2] & 0xf0);
4537 ptr
[pos
/ 2] = (val
<< 4) | (ptr
[pos
/ 2] & 0x0f);
4545 static BOOL
gradient_rect_1( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4547 BYTE
*ptr
= get_pixel_ptr_1( dib
, rc
->left
, rc
->top
);
4548 int x
, y
, left
, right
, det
, pos
;
4552 case GRADIENT_FILL_RECT_H
:
4553 for (y
= rc
->top
; y
< min( rc
->top
+ 16, rc
->bottom
); y
++, ptr
+= dib
->stride
)
4555 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 7; x
< rc
->right
; x
++, pos
++)
4557 BYTE val
= gradient_rgb_8( dib
, v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
) ? 0xff : 0;
4558 ptr
[pos
/ 8] = (ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) | (val
& pixel_masks_1
[pos
% 8]);
4561 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4562 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 7; x
< rc
->right
; x
++, pos
++)
4563 ptr
[pos
/ 8] = (ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) |
4564 (ptr
[pos
/ 8 - 16 * dib
->stride
] & pixel_masks_1
[pos
% 8]);
4567 case GRADIENT_FILL_RECT_V
:
4568 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4571 for (x
= 0; x
< 16; x
++)
4572 values
[x
] = gradient_rgb_8( dib
, v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
) ? 0xff : 0;
4573 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 7; x
< rc
->right
; x
++, pos
++)
4574 ptr
[pos
/ 8] = (ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) |
4575 (values
[x
% 16] & pixel_masks_1
[pos
% 8]);
4579 case GRADIENT_FILL_TRIANGLE
:
4580 if (!(det
= triangle_det( v
))) return FALSE
;
4581 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4583 triangle_coords( v
, rc
, y
, &left
, &right
);
4584 for (x
= left
, pos
= left
- rc
->left
+ ((dib
->rect
.left
+ rc
->left
) & 7); x
< right
; x
++, pos
++)
4586 BYTE val
= gradient_triangle_8( dib
, v
, x
, y
, det
) ? 0xff : 0;
4587 ptr
[pos
/ 8] = (ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) | (val
& pixel_masks_1
[pos
% 8]);
4595 static BOOL
gradient_rect_null( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4600 static inline BYTE
aa_color( BYTE dst
, BYTE text
, BYTE min_comp
, BYTE max_comp
)
4602 if (dst
== text
) return dst
;
4606 DWORD diff
= dst
- text
;
4607 DWORD range
= max_comp
- text
;
4608 dst
= text
+ (diff
* range
) / (0xff - text
);
4613 DWORD diff
= text
- dst
;
4614 DWORD range
= text
- min_comp
;
4615 dst
= text
- (diff
* range
) / text
;
4620 static inline DWORD
aa_rgb( BYTE r_dst
, BYTE g_dst
, BYTE b_dst
, DWORD text
, const struct intensity_range
*range
)
4622 return (aa_color( b_dst
, text
, range
->b_min
, range
->b_max
) |
4623 aa_color( g_dst
, text
>> 8, range
->g_min
, range
->g_max
) << 8 |
4624 aa_color( r_dst
, text
>> 16, range
->r_min
, range
->r_max
) << 16);
4627 static void draw_glyph_8888( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4628 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4630 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
4631 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
4634 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4636 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
4638 if (glyph_ptr
[x
] <= 1) continue;
4639 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
4640 dst_ptr
[x
] = aa_rgb( dst_ptr
[x
] >> 16, dst_ptr
[x
] >> 8, dst_ptr
[x
], text_pixel
, ranges
+ glyph_ptr
[x
] );
4642 dst_ptr
+= dib
->stride
/ 4;
4643 glyph_ptr
+= glyph
->stride
;
4647 static void draw_glyph_32( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4648 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4650 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
4651 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
4655 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
4656 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
4657 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
4659 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4661 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
4663 if (glyph_ptr
[x
] <= 1) continue;
4664 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
4665 val
= aa_rgb( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
4666 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
4667 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
4668 text
, ranges
+ glyph_ptr
[x
] );
4669 dst_ptr
[x
] = (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
4670 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
4671 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
4673 dst_ptr
+= dib
->stride
/ 4;
4674 glyph_ptr
+= glyph
->stride
;
4678 static void draw_glyph_24( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4679 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4681 BYTE
*dst_ptr
= get_pixel_ptr_24( dib
, rect
->left
, rect
->top
);
4682 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
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)
4694 val
= aa_rgb( dst_ptr
[x
* 3 + 2], dst_ptr
[x
* 3 + 1], dst_ptr
[x
* 3],
4695 text_pixel
, ranges
+ glyph_ptr
[x
] );
4696 dst_ptr
[x
* 3] = val
;
4697 dst_ptr
[x
* 3 + 1] = val
>> 8;
4698 dst_ptr
[x
* 3 + 2] = val
>> 16;
4700 dst_ptr
+= dib
->stride
;
4701 glyph_ptr
+= glyph
->stride
;
4705 static void draw_glyph_555( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4706 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4708 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
4709 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
4713 text
= ((text_pixel
<< 9) & 0xf80000) | ((text_pixel
<< 4) & 0x070000) |
4714 ((text_pixel
<< 6) & 0x00f800) | ((text_pixel
<< 1) & 0x000700) |
4715 ((text_pixel
<< 3) & 0x0000f8) | ((text_pixel
>> 2) & 0x000007);
4717 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4719 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
4721 if (glyph_ptr
[x
] <= 1) continue;
4722 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
4723 val
= aa_rgb( ((dst_ptr
[x
] >> 7) & 0xf8) | ((dst_ptr
[x
] >> 12) & 0x07),
4724 ((dst_ptr
[x
] >> 2) & 0xf8) | ((dst_ptr
[x
] >> 7) & 0x07),
4725 ((dst_ptr
[x
] << 3) & 0xf8) | ((dst_ptr
[x
] >> 2) & 0x07),
4726 text
, ranges
+ glyph_ptr
[x
] );
4727 dst_ptr
[x
] = ((val
>> 9) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 3) & 0x001f);
4729 dst_ptr
+= dib
->stride
/ 2;
4730 glyph_ptr
+= glyph
->stride
;
4734 static void draw_glyph_16( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4735 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4737 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
4738 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
4742 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
4743 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
4744 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
4746 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4748 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
4750 if (glyph_ptr
[x
] <= 1) continue;
4751 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
4752 val
= aa_rgb( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
4753 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
4754 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
4755 text
, ranges
+ glyph_ptr
[x
] );
4756 dst_ptr
[x
] = (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
4757 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
4758 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
4760 dst_ptr
+= dib
->stride
/ 2;
4761 glyph_ptr
+= glyph
->stride
;
4765 static void draw_glyph_8( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4766 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4768 BYTE
*dst_ptr
= get_pixel_ptr_8( dib
, rect
->left
, rect
->top
);
4769 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
4772 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4774 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
4776 /* no antialiasing, glyph should only contain 0 or 16. */
4777 if (glyph_ptr
[x
] >= 16)
4778 dst_ptr
[x
] = text_pixel
;
4780 dst_ptr
+= dib
->stride
;
4781 glyph_ptr
+= glyph
->stride
;
4785 static void draw_glyph_4( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4786 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4788 BYTE
*dst_ptr
= get_pixel_ptr_4( dib
, rect
->left
, rect
->top
);
4789 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
4792 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4794 for (x
= 0, pos
= (dib
->rect
.left
+ rect
->left
) & 1; x
< rect
->right
- rect
->left
; x
++, pos
++)
4796 /* no antialiasing, glyph should only contain 0 or 16. */
4797 if (glyph_ptr
[x
] >= 16)
4800 dst_ptr
[pos
/ 2] = text_pixel
| (dst_ptr
[pos
/ 2] & 0xf0);
4802 dst_ptr
[pos
/ 2] = (text_pixel
<< 4) | (dst_ptr
[pos
/ 2] & 0x0f);
4805 dst_ptr
+= dib
->stride
;
4806 glyph_ptr
+= glyph
->stride
;
4810 static void draw_glyph_1( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4811 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4813 BYTE
*dst_ptr
= get_pixel_ptr_1( dib
, rect
->left
, rect
->top
);
4814 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
4816 BYTE text
= (text_pixel
& 1) ? 0xff : 0;
4818 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4820 for (x
= 0, pos
= (dib
->rect
.left
+ rect
->left
) & 7; x
< rect
->right
- rect
->left
; x
++, pos
++)
4822 /* no antialiasing, glyph should only contain 0 or 16. */
4823 if (glyph_ptr
[x
] >= 16)
4824 dst_ptr
[pos
/ 8] = (dst_ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) |
4825 (text
& pixel_masks_1
[pos
% 8]);
4827 dst_ptr
+= dib
->stride
;
4828 glyph_ptr
+= glyph
->stride
;
4832 static void draw_glyph_null( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4833 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4838 static void create_rop_masks_32(const dib_info
*dib
, const BYTE
*hatch_ptr
,
4839 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
4841 DWORD
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
4844 /* masks are always 8x8 */
4845 assert( dib
->width
== 8 );
4846 assert( dib
->height
== 8 );
4848 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
4850 for(x
= 0; x
< 8; x
++)
4852 if(*hatch_ptr
& pixel_masks_1
[x
])
4854 and_bits
[x
] = fg
->and;
4855 xor_bits
[x
] = fg
->xor;
4859 and_bits
[x
] = bg
->and;
4860 xor_bits
[x
] = bg
->xor;
4863 and_bits
+= dib
->stride
/ 4;
4864 xor_bits
+= dib
->stride
/ 4;
4868 static void create_rop_masks_24(const dib_info
*dib
, const BYTE
*hatch_ptr
,
4869 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
4871 DWORD mask_start
= 0, mask_offset
;
4872 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
4875 /* masks are always 8x8 */
4876 assert( dib
->width
== 8 );
4877 assert( dib
->height
== 8 );
4879 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
4881 mask_offset
= mask_start
;
4882 for(x
= 0; x
< 8; x
++)
4884 if(*hatch_ptr
& pixel_masks_1
[x
])
4886 and_bits
[mask_offset
] = fg
->and & 0xff;
4887 xor_bits
[mask_offset
++] = fg
->xor & 0xff;
4888 and_bits
[mask_offset
] = (fg
->and >> 8) & 0xff;
4889 xor_bits
[mask_offset
++] = (fg
->xor >> 8) & 0xff;
4890 and_bits
[mask_offset
] = (fg
->and >> 16) & 0xff;
4891 xor_bits
[mask_offset
++] = (fg
->xor >> 16) & 0xff;
4895 and_bits
[mask_offset
] = bg
->and & 0xff;
4896 xor_bits
[mask_offset
++] = bg
->xor & 0xff;
4897 and_bits
[mask_offset
] = (bg
->and >> 8) & 0xff;
4898 xor_bits
[mask_offset
++] = (bg
->xor >> 8) & 0xff;
4899 and_bits
[mask_offset
] = (bg
->and >> 16) & 0xff;
4900 xor_bits
[mask_offset
++] = (bg
->xor >> 16) & 0xff;
4903 mask_start
+= dib
->stride
;
4907 static void create_rop_masks_16(const dib_info
*dib
, const BYTE
*hatch_ptr
,
4908 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
4910 WORD
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
4913 /* masks are always 8x8 */
4914 assert( dib
->width
== 8 );
4915 assert( dib
->height
== 8 );
4917 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
4919 for(x
= 0; x
< 8; x
++)
4921 if(*hatch_ptr
& pixel_masks_1
[x
])
4923 and_bits
[x
] = fg
->and;
4924 xor_bits
[x
] = fg
->xor;
4928 and_bits
[x
] = bg
->and;
4929 xor_bits
[x
] = bg
->xor;
4932 and_bits
+= dib
->stride
/ 2;
4933 xor_bits
+= dib
->stride
/ 2;
4937 static void create_rop_masks_8(const dib_info
*dib
, const BYTE
*hatch_ptr
,
4938 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
4940 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
4943 /* masks are always 8x8 */
4944 assert( dib
->width
== 8 );
4945 assert( dib
->height
== 8 );
4947 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
4949 for(x
= 0; x
< 8; x
++)
4951 if(*hatch_ptr
& pixel_masks_1
[x
])
4953 and_bits
[x
] = fg
->and;
4954 xor_bits
[x
] = fg
->xor;
4958 and_bits
[x
] = bg
->and;
4959 xor_bits
[x
] = bg
->xor;
4962 and_bits
+= dib
->stride
;
4963 xor_bits
+= dib
->stride
;
4967 static void create_rop_masks_4(const dib_info
*dib
, const BYTE
*hatch_ptr
,
4968 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
4971 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
4972 const rop_mask
*rop_mask
;
4975 /* masks are always 8x8 */
4976 assert( dib
->width
== 8 );
4977 assert( dib
->height
== 8 );
4979 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
4981 for(x
= mask_offset
= 0; x
< 8; x
++)
4983 if(*hatch_ptr
& pixel_masks_1
[x
])
4990 and_bits
[mask_offset
] |= (rop_mask
->and & 0x0f);
4991 xor_bits
[mask_offset
] |= (rop_mask
->xor & 0x0f);
4996 and_bits
[mask_offset
] = (rop_mask
->and << 4) & 0xf0;
4997 xor_bits
[mask_offset
] = (rop_mask
->xor << 4) & 0xf0;
5000 and_bits
+= dib
->stride
;
5001 xor_bits
+= dib
->stride
;
5005 static void create_rop_masks_1(const dib_info
*dib
, const BYTE
*hatch_ptr
,
5006 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
5008 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
5012 /* masks are always 8x8 */
5013 assert( dib
->width
== 8 );
5014 assert( dib
->height
== 8 );
5016 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
5018 *and_bits
= *xor_bits
= 0;
5019 for(x
= 0; x
< 8; x
++)
5021 if(*hatch_ptr
& pixel_masks_1
[x
])
5023 rop_mask
.and = (fg
->and & 1) ? 0xff : 0;
5024 rop_mask
.xor = (fg
->xor & 1) ? 0xff : 0;
5028 rop_mask
.and = (bg
->and & 1) ? 0xff : 0;
5029 rop_mask
.xor = (bg
->xor & 1) ? 0xff : 0;
5031 *and_bits
|= (rop_mask
.and & pixel_masks_1
[x
]);
5032 *xor_bits
|= (rop_mask
.xor & pixel_masks_1
[x
]);
5034 and_bits
+= dib
->stride
;
5035 xor_bits
+= dib
->stride
;
5039 static void create_rop_masks_null(const dib_info
*dib
, const BYTE
*hatch_ptr
,
5040 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
5044 static inline void rop_codes_from_stretch_mode( int mode
, struct rop_codes
*codes
)
5049 case STRETCH_DELETESCANS
:
5050 get_rop_codes( R2_COPYPEN
, codes
);
5052 case STRETCH_ORSCANS
:
5053 get_rop_codes( R2_MERGEPEN
, codes
);
5055 case STRETCH_ANDSCANS
:
5056 get_rop_codes( R2_MASKPEN
, codes
);
5062 static void stretch_row_32(const dib_info
*dst_dib
, const POINT
*dst_start
,
5063 const dib_info
*src_dib
, const POINT
*src_start
,
5064 const struct stretch_params
*params
, int mode
,
5067 DWORD
*dst_ptr
= get_pixel_ptr_32( dst_dib
, dst_start
->x
, dst_start
->y
);
5068 DWORD
*src_ptr
= get_pixel_ptr_32( src_dib
, src_start
->x
, src_start
->y
);
5069 int err
= params
->err_start
;
5071 struct rop_codes codes
;
5073 rop_codes_from_stretch_mode( mode
, &codes
);
5074 for (width
= params
->length
; width
; width
--)
5076 do_rop_codes_32( dst_ptr
, *src_ptr
, &codes
);
5077 dst_ptr
+= params
->dst_inc
;
5080 src_ptr
+= params
->src_inc
;
5081 err
+= params
->err_add_1
;
5083 else err
+= params
->err_add_2
;
5087 static void stretch_row_24(const dib_info
*dst_dib
, const POINT
*dst_start
,
5088 const dib_info
*src_dib
, const POINT
*src_start
,
5089 const struct stretch_params
*params
, int mode
,
5092 BYTE
*dst_ptr
= get_pixel_ptr_24( dst_dib
, dst_start
->x
, dst_start
->y
);
5093 BYTE
*src_ptr
= get_pixel_ptr_24( src_dib
, src_start
->x
, src_start
->y
);
5094 int err
= params
->err_start
;
5096 struct rop_codes codes
;
5098 rop_codes_from_stretch_mode( mode
, &codes
);
5099 for (width
= params
->length
; width
; width
--)
5101 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
5102 do_rop_codes_8( dst_ptr
+ 1, *(src_ptr
+ 1), &codes
);
5103 do_rop_codes_8( dst_ptr
+ 2, *(src_ptr
+ 2), &codes
);
5104 dst_ptr
+= 3 * params
->dst_inc
;
5107 src_ptr
+= 3 * params
->src_inc
;
5108 err
+= params
->err_add_1
;
5110 else err
+= params
->err_add_2
;
5114 static void stretch_row_16(const dib_info
*dst_dib
, const POINT
*dst_start
,
5115 const dib_info
*src_dib
, const POINT
*src_start
,
5116 const struct stretch_params
*params
, int mode
,
5119 WORD
*dst_ptr
= get_pixel_ptr_16( dst_dib
, dst_start
->x
, dst_start
->y
);
5120 WORD
*src_ptr
= get_pixel_ptr_16( src_dib
, src_start
->x
, src_start
->y
);
5121 int err
= params
->err_start
;
5123 struct rop_codes codes
;
5125 rop_codes_from_stretch_mode( mode
, &codes
);
5126 for (width
= params
->length
; width
; width
--)
5128 do_rop_codes_16( dst_ptr
, *src_ptr
, &codes
);
5129 dst_ptr
+= params
->dst_inc
;
5132 src_ptr
+= params
->src_inc
;
5133 err
+= params
->err_add_1
;
5135 else err
+= params
->err_add_2
;
5139 static void stretch_row_8(const dib_info
*dst_dib
, const POINT
*dst_start
,
5140 const dib_info
*src_dib
, const POINT
*src_start
,
5141 const struct stretch_params
*params
, int mode
,
5144 BYTE
*dst_ptr
= get_pixel_ptr_8( dst_dib
, dst_start
->x
, dst_start
->y
);
5145 BYTE
*src_ptr
= get_pixel_ptr_8( src_dib
, src_start
->x
, src_start
->y
);
5146 int err
= params
->err_start
;
5148 struct rop_codes codes
;
5150 rop_codes_from_stretch_mode( mode
, &codes
);
5151 for (width
= params
->length
; width
; width
--)
5153 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
5154 dst_ptr
+= params
->dst_inc
;
5157 src_ptr
+= params
->src_inc
;
5158 err
+= params
->err_add_1
;
5160 else err
+= params
->err_add_2
;
5164 static void stretch_row_4(const dib_info
*dst_dib
, const POINT
*dst_start
,
5165 const dib_info
*src_dib
, const POINT
*src_start
,
5166 const struct stretch_params
*params
, int mode
,
5169 BYTE
*dst_ptr
= get_pixel_ptr_4( dst_dib
, dst_start
->x
, dst_start
->y
);
5170 BYTE
*src_ptr
= get_pixel_ptr_4( src_dib
, src_start
->x
, src_start
->y
);
5171 int err
= params
->err_start
;
5172 int width
, dst_x
= dst_dib
->rect
.left
+ dst_start
->x
, src_x
= src_dib
->rect
.left
+ src_start
->x
;
5173 struct rop_codes codes
;
5176 rop_codes_from_stretch_mode( mode
, &codes
);
5177 for (width
= params
->length
; width
; width
--)
5179 if (src_x
& 1) src_val
= (*src_ptr
& 0x0f) | (*src_ptr
<< 4);
5180 else src_val
= (*src_ptr
& 0xf0) | (*src_ptr
>> 4);
5182 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, (dst_x
& 1) ? 0x0f : 0xf0 );
5184 if ((dst_x
& ~1) != ((dst_x
+ params
->dst_inc
) & ~1))
5185 dst_ptr
+= params
->dst_inc
;
5186 dst_x
+= params
->dst_inc
;
5190 if ((src_x
& ~1) != ((src_x
+ params
->src_inc
) & ~1))
5191 src_ptr
+= params
->src_inc
;
5192 src_x
+= params
->src_inc
;
5193 err
+= params
->err_add_1
;
5195 else err
+= params
->err_add_2
;
5199 static void stretch_row_1(const dib_info
*dst_dib
, const POINT
*dst_start
,
5200 const dib_info
*src_dib
, const POINT
*src_start
,
5201 const struct stretch_params
*params
, int mode
,
5204 BYTE
*dst_ptr
= get_pixel_ptr_1( dst_dib
, dst_start
->x
, dst_start
->y
);
5205 BYTE
*src_ptr
= get_pixel_ptr_1( src_dib
, src_start
->x
, src_start
->y
);
5206 int err
= params
->err_start
;
5207 int width
, dst_x
= dst_dib
->rect
.left
+ dst_start
->x
, src_x
= src_dib
->rect
.left
+ src_start
->x
;
5208 struct rop_codes codes
;
5211 rop_codes_from_stretch_mode( mode
, &codes
);
5212 for (width
= params
->length
; width
; width
--)
5214 src_val
= *src_ptr
& pixel_masks_1
[src_x
% 8] ? 0xff : 0;
5215 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, pixel_masks_1
[dst_x
% 8] );
5217 if ((dst_x
& ~7) != ((dst_x
+ params
->dst_inc
) & ~7))
5218 dst_ptr
+= params
->dst_inc
;
5219 dst_x
+= params
->dst_inc
;
5223 if ((src_x
& ~7) != ((src_x
+ params
->src_inc
) & ~7))
5224 src_ptr
+= params
->src_inc
;
5225 src_x
+= params
->src_inc
;
5226 err
+= params
->err_add_1
;
5228 else err
+= params
->err_add_2
;
5232 static void stretch_row_null(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 FIXME("bit count %d\n", dst_dib
->bit_count
);
5241 static void shrink_row_32(const dib_info
*dst_dib
, const POINT
*dst_start
,
5242 const dib_info
*src_dib
, const POINT
*src_start
,
5243 const struct stretch_params
*params
, int mode
,
5246 DWORD
*dst_ptr
= get_pixel_ptr_32( dst_dib
, dst_start
->x
, dst_start
->y
);
5247 DWORD
*src_ptr
= get_pixel_ptr_32( src_dib
, src_start
->x
, src_start
->y
);
5248 int err
= params
->err_start
;
5250 struct rop_codes codes
;
5251 DWORD init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
5252 BOOL new_pix
= TRUE
;
5254 rop_codes_from_stretch_mode( mode
, &codes
);
5255 for (width
= params
->length
; width
; width
--)
5257 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
5258 do_rop_codes_32( dst_ptr
, *src_ptr
, &codes
);
5260 src_ptr
+= params
->src_inc
;
5263 dst_ptr
+= params
->dst_inc
;
5265 err
+= params
->err_add_1
;
5267 else err
+= params
->err_add_2
;
5271 static void shrink_row_24(const dib_info
*dst_dib
, const POINT
*dst_start
,
5272 const dib_info
*src_dib
, const POINT
*src_start
,
5273 const struct stretch_params
*params
, int mode
,
5276 BYTE
*dst_ptr
= get_pixel_ptr_24( dst_dib
, dst_start
->x
, dst_start
->y
);
5277 BYTE
*src_ptr
= get_pixel_ptr_24( src_dib
, src_start
->x
, src_start
->y
);
5278 int err
= params
->err_start
;
5280 struct rop_codes codes
;
5281 BYTE init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
5282 BOOL new_pix
= TRUE
;
5284 rop_codes_from_stretch_mode( mode
, &codes
);
5285 for (width
= params
->length
; width
; width
--)
5287 if (new_pix
&& !keep_dst
) memset( dst_ptr
, init_val
, 3 );
5288 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
5289 do_rop_codes_8( dst_ptr
+ 1, *(src_ptr
+ 1), &codes
);
5290 do_rop_codes_8( dst_ptr
+ 2, *(src_ptr
+ 2), &codes
);
5292 src_ptr
+= 3 * params
->src_inc
;
5295 dst_ptr
+= 3 * params
->dst_inc
;
5297 err
+= params
->err_add_1
;
5299 else err
+= params
->err_add_2
;
5303 static void shrink_row_16(const dib_info
*dst_dib
, const POINT
*dst_start
,
5304 const dib_info
*src_dib
, const POINT
*src_start
,
5305 const struct stretch_params
*params
, int mode
,
5308 WORD
*dst_ptr
= get_pixel_ptr_16( dst_dib
, dst_start
->x
, dst_start
->y
);
5309 WORD
*src_ptr
= get_pixel_ptr_16( src_dib
, src_start
->x
, src_start
->y
);
5310 int err
= params
->err_start
;
5312 struct rop_codes codes
;
5313 WORD init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
5314 BOOL new_pix
= TRUE
;
5316 rop_codes_from_stretch_mode( mode
, &codes
);
5317 for (width
= params
->length
; width
; width
--)
5319 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
5320 do_rop_codes_16( dst_ptr
, *src_ptr
, &codes
);
5322 src_ptr
+= params
->src_inc
;
5325 dst_ptr
+= params
->dst_inc
;
5327 err
+= params
->err_add_1
;
5329 else err
+= params
->err_add_2
;
5333 static void shrink_row_8(const dib_info
*dst_dib
, const POINT
*dst_start
,
5334 const dib_info
*src_dib
, const POINT
*src_start
,
5335 const struct stretch_params
*params
, int mode
,
5338 BYTE
*dst_ptr
= get_pixel_ptr_8( dst_dib
, dst_start
->x
, dst_start
->y
);
5339 BYTE
*src_ptr
= get_pixel_ptr_8( src_dib
, src_start
->x
, src_start
->y
);
5340 int err
= params
->err_start
;
5342 struct rop_codes codes
;
5343 BYTE init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
5344 BOOL new_pix
= TRUE
;
5346 rop_codes_from_stretch_mode( mode
, &codes
);
5347 for (width
= params
->length
; width
; width
--)
5349 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
5350 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
5352 src_ptr
+= params
->src_inc
;
5355 dst_ptr
+= params
->dst_inc
;
5357 err
+= params
->err_add_1
;
5359 else err
+= params
->err_add_2
;
5363 static void shrink_row_4(const dib_info
*dst_dib
, const POINT
*dst_start
,
5364 const dib_info
*src_dib
, const POINT
*src_start
,
5365 const struct stretch_params
*params
, int mode
,
5368 BYTE
*dst_ptr
= get_pixel_ptr_4( dst_dib
, dst_start
->x
, dst_start
->y
);
5369 BYTE
*src_ptr
= get_pixel_ptr_4( src_dib
, src_start
->x
, src_start
->y
);
5370 int err
= params
->err_start
;
5371 int width
, dst_x
= dst_dib
->rect
.left
+ dst_start
->x
, src_x
= src_dib
->rect
.left
+ src_start
->x
;
5372 struct rop_codes codes
;
5373 BYTE src_val
, init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
5374 BOOL new_pix
= TRUE
;
5376 rop_codes_from_stretch_mode( mode
, &codes
);
5377 for (width
= params
->length
; width
; width
--)
5379 if (new_pix
&& !keep_dst
) do_rop_mask_8( dst_ptr
, 0, init_val
, (dst_x
& 1) ? 0x0f : 0xf0 );
5381 if (src_x
& 1) src_val
= (*src_ptr
& 0x0f) | (*src_ptr
<< 4);
5382 else src_val
= (*src_ptr
& 0xf0) | (*src_ptr
>> 4);
5384 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, (dst_x
& 1) ? 0x0f : 0xf0 );
5387 if ((src_x
& ~1) != ((src_x
+ params
->src_inc
) & ~1))
5388 src_ptr
+= params
->src_inc
;
5389 src_x
+= params
->src_inc
;
5393 if ((dst_x
& ~1) != ((dst_x
+ params
->dst_inc
) & ~1))
5394 dst_ptr
+= params
->dst_inc
;
5395 dst_x
+= params
->dst_inc
;
5397 err
+= params
->err_add_1
;
5399 else err
+= params
->err_add_2
;
5403 static void shrink_row_1(const dib_info
*dst_dib
, const POINT
*dst_start
,
5404 const dib_info
*src_dib
, const POINT
*src_start
,
5405 const struct stretch_params
*params
, int mode
,
5408 BYTE
*dst_ptr
= get_pixel_ptr_1( dst_dib
, dst_start
->x
, dst_start
->y
);
5409 BYTE
*src_ptr
= get_pixel_ptr_1( src_dib
, src_start
->x
, src_start
->y
);
5410 int err
= params
->err_start
;
5411 int width
, dst_x
= dst_dib
->rect
.left
+ dst_start
->x
, src_x
= src_dib
->rect
.left
+ src_start
->x
;
5412 struct rop_codes codes
;
5413 BYTE src_val
, init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
5414 BOOL new_pix
= TRUE
;
5416 rop_codes_from_stretch_mode( mode
, &codes
);
5417 for (width
= params
->length
; width
; width
--)
5419 if (new_pix
&& !keep_dst
) do_rop_mask_8( dst_ptr
, 0, init_val
, pixel_masks_1
[dst_x
% 8] );
5420 src_val
= *src_ptr
& pixel_masks_1
[src_x
% 8] ? 0xff : 0;
5421 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, pixel_masks_1
[dst_x
% 8] );
5424 if ((src_x
& ~7) != ((src_x
+ params
->src_inc
) & ~7))
5425 src_ptr
+= params
->src_inc
;
5426 src_x
+= params
->src_inc
;
5430 if ((dst_x
& ~7) != ((dst_x
+ params
->dst_inc
) & ~7))
5431 dst_ptr
+= params
->dst_inc
;
5432 dst_x
+= params
->dst_inc
;
5434 err
+= params
->err_add_1
;
5436 else err
+= params
->err_add_2
;
5440 static void shrink_row_null(const dib_info
*dst_dib
, const POINT
*dst_start
,
5441 const dib_info
*src_dib
, const POINT
*src_start
,
5442 const struct stretch_params
*params
, int mode
,
5445 FIXME("bit count %d\n", dst_dib
->bit_count
);
5449 const primitive_funcs funcs_8888
=
5459 colorref_to_pixel_888
,
5460 pixel_to_colorref_888
,
5462 create_rop_masks_32
,
5467 const primitive_funcs funcs_32
=
5477 colorref_to_pixel_masks
,
5478 pixel_to_colorref_masks
,
5480 create_rop_masks_32
,
5485 const primitive_funcs funcs_24
=
5495 colorref_to_pixel_888
,
5496 pixel_to_colorref_888
,
5498 create_rop_masks_24
,
5503 const primitive_funcs funcs_555
=
5513 colorref_to_pixel_555
,
5514 pixel_to_colorref_555
,
5516 create_rop_masks_16
,
5521 const primitive_funcs funcs_16
=
5531 colorref_to_pixel_masks
,
5532 pixel_to_colorref_masks
,
5534 create_rop_masks_16
,
5539 const primitive_funcs funcs_8
=
5549 colorref_to_pixel_colortable
,
5550 pixel_to_colorref_colortable
,
5557 const primitive_funcs funcs_4
=
5567 colorref_to_pixel_colortable
,
5568 pixel_to_colorref_colortable
,
5575 const primitive_funcs funcs_1
=
5585 colorref_to_pixel_colortable
,
5586 pixel_to_colorref_colortable
,
5593 const primitive_funcs funcs_null
=
5603 colorref_to_pixel_null
,
5604 pixel_to_colorref_null
,
5606 create_rop_masks_null
,