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 static inline DWORD
*get_pixel_ptr_32(const dib_info
*dib
, int x
, int y
)
32 return (DWORD
*)((BYTE
*)dib
->bits
.ptr
+ y
* dib
->stride
+ x
* 4);
35 static inline DWORD
*get_pixel_ptr_24_dword(const dib_info
*dib
, int x
, int y
)
37 return (DWORD
*)((BYTE
*)dib
->bits
.ptr
+ y
* dib
->stride
) + x
* 3 / 4;
40 static inline BYTE
*get_pixel_ptr_24(const dib_info
*dib
, int x
, int y
)
42 return (BYTE
*)dib
->bits
.ptr
+ y
* dib
->stride
+ x
* 3;
45 static inline WORD
*get_pixel_ptr_16(const dib_info
*dib
, int x
, int y
)
47 return (WORD
*)((BYTE
*)dib
->bits
.ptr
+ y
* dib
->stride
+ x
* 2);
50 static inline BYTE
*get_pixel_ptr_8(const dib_info
*dib
, int x
, int y
)
52 return (BYTE
*)dib
->bits
.ptr
+ y
* dib
->stride
+ x
;
55 static inline BYTE
*get_pixel_ptr_4(const dib_info
*dib
, int x
, int y
)
57 return (BYTE
*)dib
->bits
.ptr
+ y
* dib
->stride
+ x
/ 2;
60 static inline BYTE
*get_pixel_ptr_1(const dib_info
*dib
, int x
, int y
)
62 return (BYTE
*)dib
->bits
.ptr
+ y
* dib
->stride
+ x
/ 8;
65 static const BYTE pixel_masks_4
[2] = {0xf0, 0x0f};
66 static const BYTE pixel_masks_1
[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
68 static inline void do_rop_32(DWORD
*ptr
, DWORD
and, DWORD
xor)
70 *ptr
= (*ptr
& and) ^ xor;
73 static inline void do_rop_16(WORD
*ptr
, WORD
and, WORD
xor)
75 *ptr
= (*ptr
& and) ^ xor;
78 static inline void do_rop_8(BYTE
*ptr
, BYTE
and, BYTE
xor)
80 *ptr
= (*ptr
& and) ^ xor;
83 static inline void do_rop_mask_8(BYTE
*ptr
, BYTE
and, BYTE
xor, BYTE mask
)
85 *ptr
= (*ptr
& (and | ~mask
)) ^ (xor & mask
);
88 static inline void do_rop_codes_32(DWORD
*dst
, DWORD src
, struct rop_codes
*codes
)
90 do_rop_32( dst
, (src
& codes
->a1
) ^ codes
->a2
, (src
& codes
->x1
) ^ codes
->x2
);
93 static inline void do_rop_codes_16(WORD
*dst
, WORD src
, struct rop_codes
*codes
)
95 do_rop_16( dst
, (src
& codes
->a1
) ^ codes
->a2
, (src
& codes
->x1
) ^ codes
->x2
);
98 static inline void do_rop_codes_8(BYTE
*dst
, BYTE src
, struct rop_codes
*codes
)
100 do_rop_8( dst
, (src
& codes
->a1
) ^ codes
->a2
, (src
& codes
->x1
) ^ codes
->x2
);
103 static inline void do_rop_codes_mask_8(BYTE
*dst
, BYTE src
, struct rop_codes
*codes
, BYTE mask
)
105 do_rop_mask_8( dst
, (src
& codes
->a1
) ^ codes
->a2
, (src
& codes
->x1
) ^ codes
->x2
, mask
);
108 static inline void do_rop_codes_line_32(DWORD
*dst
, const DWORD
*src
, struct rop_codes
*codes
, int len
)
110 for (; len
> 0; len
--, src
++, dst
++) do_rop_codes_32( dst
, *src
, codes
);
113 static inline void do_rop_codes_line_rev_32(DWORD
*dst
, const DWORD
*src
, struct rop_codes
*codes
, int len
)
115 for (src
+= len
- 1, dst
+= len
- 1; len
> 0; len
--, src
--, dst
--)
116 do_rop_codes_32( dst
, *src
, codes
);
119 static inline void do_rop_codes_line_16(WORD
*dst
, const WORD
*src
, struct rop_codes
*codes
, int len
)
121 for (; len
> 0; len
--, src
++, dst
++) do_rop_codes_16( dst
, *src
, codes
);
124 static inline void do_rop_codes_line_rev_16(WORD
*dst
, const WORD
*src
, struct rop_codes
*codes
, int len
)
126 for (src
+= len
- 1, dst
+= len
- 1; len
> 0; len
--, src
--, dst
--)
127 do_rop_codes_16( dst
, *src
, codes
);
130 static inline void do_rop_codes_line_8(BYTE
*dst
, const BYTE
*src
, struct rop_codes
*codes
, int len
)
132 for (; len
> 0; len
--, src
++, dst
++) do_rop_codes_8( dst
, *src
, codes
);
135 static inline void do_rop_codes_line_rev_8(BYTE
*dst
, const BYTE
*src
, struct rop_codes
*codes
, int len
)
137 for (src
+= len
- 1, dst
+= len
- 1; len
> 0; len
--, src
--, dst
--)
138 do_rop_codes_8( dst
, *src
, codes
);
141 static inline void do_rop_codes_line_4(BYTE
*dst
, int dst_x
, const BYTE
*src
, int src_x
,
142 struct rop_codes
*codes
, int len
)
146 for (src
+= src_x
/ 2, dst
+= dst_x
/ 2; len
> 0; len
--, dst_x
++, src_x
++)
150 if (src_x
& 1) src_val
= *src
++;
151 else src_val
= *src
>> 4;
152 do_rop_codes_mask_8( dst
++, src_val
, codes
, 0x0f );
156 if (src_x
& 1) src_val
= *src
++ << 4;
158 do_rop_codes_mask_8( dst
, src_val
, codes
, 0xf0 );
163 static inline void do_rop_codes_line_rev_4(BYTE
*dst
, int dst_x
, const BYTE
*src
, int src_x
,
164 struct rop_codes
*codes
, int len
)
170 for (src
+= src_x
/ 2, dst
+= dst_x
/ 2; len
> 0; len
--, dst_x
--, src_x
--)
174 if (src_x
& 1) src_val
= *src
;
175 else src_val
= *src
-- >> 4;
176 do_rop_codes_mask_8( dst
, src_val
, codes
, 0x0f );
180 if (src_x
& 1) src_val
= *src
<< 4;
181 else src_val
= *src
--;
182 do_rop_codes_mask_8( dst
--, src_val
, codes
, 0xf0 );
187 static inline void do_rop_codes_line_1(BYTE
*dst
, int dst_x
, const BYTE
*src
, int src_x
,
188 struct rop_codes
*codes
, int len
)
192 for (src
+= src_x
/ 8, dst
+= dst_x
/ 8; len
> 0; len
--, dst_x
++, src_x
++)
194 src_val
= *src
& pixel_masks_1
[src_x
& 7] ? 0xff : 0;
195 do_rop_codes_mask_8( dst
, src_val
, codes
, pixel_masks_1
[dst_x
& 7] );
196 if ((src_x
& 7) == 7) src
++;
197 if ((dst_x
& 7) == 7) dst
++;
201 static inline void do_rop_codes_line_rev_1(BYTE
*dst
, int dst_x
, const BYTE
*src
, int src_x
,
202 struct rop_codes
*codes
, int len
)
208 for (src
+= src_x
/ 8, dst
+= dst_x
/ 8; len
> 0; len
--, dst_x
--, src_x
--)
210 src_val
= *src
& pixel_masks_1
[src_x
& 7] ? 0xff : 0;
211 do_rop_codes_mask_8( dst
, src_val
, codes
, pixel_masks_1
[dst_x
& 7] );
212 if ((src_x
& 7) == 0) src
--;
213 if ((dst_x
& 7) == 0) dst
--;
217 static void solid_rects_32(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
222 for(i
= 0; i
< num
; i
++, rc
++)
224 start
= get_pixel_ptr_32(dib
, rc
->left
, rc
->top
);
225 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
226 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
227 do_rop_32(ptr
++, and, xor);
231 static void solid_rects_24(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
234 BYTE
*byte_ptr
, *byte_start
;
236 DWORD and_masks
[3], xor_masks
[3];
238 and_masks
[0] = ( and & 0x00ffffff) | ((and << 24) & 0xff000000);
239 and_masks
[1] = ((and >> 8) & 0x0000ffff) | ((and << 16) & 0xffff0000);
240 and_masks
[2] = ((and >> 16) & 0x000000ff) | ((and << 8) & 0xffffff00);
241 xor_masks
[0] = ( xor & 0x00ffffff) | ((xor << 24) & 0xff000000);
242 xor_masks
[1] = ((xor >> 8) & 0x0000ffff) | ((xor << 16) & 0xffff0000);
243 xor_masks
[2] = ((xor >> 16) & 0x000000ff) | ((xor << 8) & 0xffffff00);
245 for(i
= 0; i
< num
; i
++, rc
++)
247 if(rc
->left
>= rc
->right
) continue;
249 if((rc
->left
& ~3) == (rc
->right
& ~3)) /* Special case for lines that start and end in the same DWORD triplet */
251 byte_start
= get_pixel_ptr_24(dib
, rc
->left
, rc
->top
);
252 for(y
= rc
->top
; y
< rc
->bottom
; y
++, byte_start
+= dib
->stride
)
254 for(x
= rc
->left
, byte_ptr
= byte_start
; x
< rc
->right
; x
++)
256 do_rop_8(byte_ptr
++, and_masks
[0] & 0xff, xor_masks
[0] & 0xff);
257 do_rop_8(byte_ptr
++, and_masks
[1] & 0xff, xor_masks
[1] & 0xff);
258 do_rop_8(byte_ptr
++, and_masks
[2] & 0xff, xor_masks
[2] & 0xff);
264 start
= get_pixel_ptr_24_dword(dib
, rc
->left
, rc
->top
);
265 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
272 do_rop_32(ptr
++, and_masks
[0] | 0x00ffffff, xor_masks
[0] & 0xff000000);
273 do_rop_32(ptr
++, and_masks
[1], xor_masks
[1]);
274 do_rop_32(ptr
++, and_masks
[2], xor_masks
[2]);
277 do_rop_32(ptr
++, and_masks
[1] | 0x0000ffff, xor_masks
[1] & 0xffff0000);
278 do_rop_32(ptr
++, and_masks
[2], xor_masks
[2]);
281 do_rop_32(ptr
++, and_masks
[2] | 0x000000ff, xor_masks
[2] & 0xffffff00);
285 for(x
= (rc
->left
+ 3) & ~3; x
< (rc
->right
& ~3); x
+= 4)
287 do_rop_32(ptr
++, and_masks
[0], xor_masks
[0]);
288 do_rop_32(ptr
++, and_masks
[1], xor_masks
[1]);
289 do_rop_32(ptr
++, and_masks
[2], xor_masks
[2]);
292 switch(rc
->right
& 3)
295 do_rop_32(ptr
, and_masks
[0] | 0xff000000, xor_masks
[0] & 0x00ffffff);
298 do_rop_32(ptr
++, and_masks
[0], xor_masks
[0]);
299 do_rop_32(ptr
, and_masks
[1] | 0xffff0000, xor_masks
[1] & 0x0000ffff);
302 do_rop_32(ptr
++, and_masks
[0], xor_masks
[0]);
303 do_rop_32(ptr
++, and_masks
[1], xor_masks
[1]);
304 do_rop_32(ptr
, and_masks
[2] | 0xffffff00, xor_masks
[2] & 0x000000ff);
312 static void solid_rects_16(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
317 for(i
= 0; i
< num
; i
++, rc
++)
319 start
= get_pixel_ptr_16(dib
, rc
->left
, rc
->top
);
320 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 2)
321 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
322 do_rop_16(ptr
++, and, xor);
326 static void solid_rects_8(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
331 for(i
= 0; i
< num
; i
++, rc
++)
333 start
= get_pixel_ptr_8(dib
, rc
->left
, rc
->top
);
334 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
335 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
336 do_rop_8(ptr
++, and, xor);
340 static void solid_rects_4(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
344 BYTE byte_and
= (and & 0xf) | ((and << 4) & 0xf0);
345 BYTE byte_xor
= (xor & 0xf) | ((xor << 4) & 0xf0);
347 for(i
= 0; i
< num
; i
++, rc
++)
349 if(rc
->left
>= rc
->right
) continue;
350 start
= get_pixel_ptr_4(dib
, rc
->left
, rc
->top
);
351 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
354 if(rc
->left
& 1) /* upper nibble untouched */
355 do_rop_8(ptr
++, byte_and
| 0xf0, byte_xor
& 0x0f);
357 for(x
= (rc
->left
+ 1) & ~1; x
< (rc
->right
& ~1); x
+= 2)
358 do_rop_8(ptr
++, byte_and
, byte_xor
);
360 if(rc
->right
& 1) /* lower nibble untouched */
361 do_rop_8(ptr
, byte_and
| 0x0f, byte_xor
& 0xf0);
366 static void solid_rects_1(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
370 BYTE byte_and
= (and & 1) ? 0xff : 0;
371 BYTE byte_xor
= (xor & 1) ? 0xff : 0;
372 BYTE start_and
, start_xor
, end_and
, end_xor
, mask
;
373 static const BYTE masks
[8] = {0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01};
375 for(i
= 0; i
< num
; i
++, rc
++)
377 if(rc
->left
>= rc
->right
) continue;
379 start
= get_pixel_ptr_1(dib
, rc
->left
, rc
->top
);
381 if((rc
->left
& ~7) == (rc
->right
& ~7)) /* Special case for lines that start and end in the same byte */
383 mask
= masks
[rc
->left
& 7] & ~masks
[rc
->right
& 7];
385 start_and
= byte_and
| ~mask
;
386 start_xor
= byte_xor
& mask
;
387 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
389 do_rop_8(start
, start_and
, start_xor
);
394 mask
= masks
[rc
->left
& 7];
395 start_and
= byte_and
| ~mask
;
396 start_xor
= byte_xor
& mask
;
398 mask
= masks
[rc
->right
& 7];
399 /* This is inverted wrt to start mask, so end_and/xor assignments reflect this */
400 end_and
= byte_and
| mask
;
401 end_xor
= byte_xor
& ~mask
;
403 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
408 do_rop_8(ptr
++, start_and
, start_xor
);
410 for(x
= (rc
->left
+ 7) & ~7; x
< (rc
->right
& ~7); x
+= 8)
411 do_rop_8(ptr
++, byte_and
, byte_xor
);
414 do_rop_8(ptr
, end_and
, end_xor
);
420 static void solid_rects_null(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
425 static void solid_line_32(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
426 DWORD
and, DWORD
xor)
428 DWORD
*ptr
= get_pixel_ptr_32( dib
, start
->x
, start
->y
);
429 int len
= params
->length
, err
= params
->err_start
;
430 int major_inc
, minor_inc
;
434 major_inc
= params
->x_inc
;
435 minor_inc
= (dib
->stride
* params
->y_inc
) / 4;
439 major_inc
= (dib
->stride
* params
->y_inc
) / 4;
440 minor_inc
= params
->x_inc
;
445 do_rop_32( ptr
, and, xor );
446 if (err
+ params
->bias
> 0)
449 err
+= params
->err_add_1
;
451 else err
+= params
->err_add_2
;
456 static void solid_line_24(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
457 DWORD
and, DWORD
xor)
459 BYTE
*ptr
= get_pixel_ptr_24( dib
, start
->x
, start
->y
);
460 int len
= params
->length
, err
= params
->err_start
;
461 int major_inc
, minor_inc
;
465 major_inc
= params
->x_inc
* 3;
466 minor_inc
= dib
->stride
* params
->y_inc
;
470 major_inc
= dib
->stride
* params
->y_inc
;
471 minor_inc
= params
->x_inc
* 3;
476 do_rop_8( ptr
, and, xor );
477 do_rop_8( ptr
+ 1, and >> 8, xor >> 8 );
478 do_rop_8( ptr
+ 2, and >> 16, xor >> 16 );
479 if (err
+ params
->bias
> 0)
482 err
+= params
->err_add_1
;
484 else err
+= params
->err_add_2
;
489 static void solid_line_16(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
490 DWORD
and, DWORD
xor)
492 WORD
*ptr
= get_pixel_ptr_16( dib
, start
->x
, start
->y
);
493 int len
= params
->length
, err
= params
->err_start
;
494 int major_inc
, minor_inc
;
498 major_inc
= params
->x_inc
;
499 minor_inc
= (dib
->stride
* params
->y_inc
) / 2;
503 major_inc
= (dib
->stride
* params
->y_inc
) / 2;
504 minor_inc
= params
->x_inc
;
509 do_rop_16( ptr
, and, xor );
510 if (err
+ params
->bias
> 0)
513 err
+= params
->err_add_1
;
515 else err
+= params
->err_add_2
;
520 static void solid_line_8(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
521 DWORD
and, DWORD
xor)
523 BYTE
*ptr
= get_pixel_ptr_8( dib
, start
->x
, start
->y
);
524 int len
= params
->length
, err
= params
->err_start
;
525 int major_inc
, minor_inc
;
529 major_inc
= params
->x_inc
;
530 minor_inc
= dib
->stride
* params
->y_inc
;
534 major_inc
= dib
->stride
* params
->y_inc
;
535 minor_inc
= params
->x_inc
;
540 do_rop_8( ptr
, and, xor );
541 if (err
+ params
->bias
> 0)
544 err
+= params
->err_add_1
;
546 else err
+= params
->err_add_2
;
551 static void solid_line_4(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
552 DWORD
and, DWORD
xor)
554 BYTE
*ptr
= get_pixel_ptr_4( dib
, start
->x
, start
->y
);
555 int len
= params
->length
, err
= params
->err_start
;
558 and = (and & 0x0f) | ((and << 4) & 0xf0);
559 xor = (xor & 0x0f) | ((xor << 4) & 0xf0);
565 do_rop_mask_8( ptr
, and, xor, pixel_masks_4
[ x
% 2 ] );
566 if (err
+ params
->bias
> 0)
568 ptr
+= dib
->stride
* params
->y_inc
;
569 err
+= params
->err_add_1
;
571 else err
+= params
->err_add_2
;
572 if ((x
/ 2) != ((x
+ params
->x_inc
) / 2))
573 ptr
+= params
->x_inc
;
581 do_rop_mask_8( ptr
, and, xor, pixel_masks_4
[ x
% 2 ] );
582 if (err
+ params
->bias
> 0)
584 if ((x
/ 2) != ((x
+ params
->x_inc
) / 2))
585 ptr
+= params
->x_inc
;
587 err
+= params
->err_add_1
;
589 else err
+= params
->err_add_2
;
590 ptr
+= dib
->stride
* params
->y_inc
;
595 static void solid_line_1(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
596 DWORD
and, DWORD
xor)
598 BYTE
*ptr
= get_pixel_ptr_1( dib
, start
->x
, start
->y
);
599 int len
= params
->length
, err
= params
->err_start
;
602 and = (and & 0x1) ? 0xff : 0;
603 xor = (xor & 0x1) ? 0xff : 0;
609 do_rop_mask_8( ptr
, and, xor, pixel_masks_1
[ x
% 8 ] );
610 if (err
+ params
->bias
> 0)
612 ptr
+= dib
->stride
* params
->y_inc
;
613 err
+= params
->err_add_1
;
615 else err
+= params
->err_add_2
;
616 if ((x
/ 8) != ((x
+ params
->x_inc
) / 8))
617 ptr
+= params
->x_inc
;
625 do_rop_mask_8( ptr
, and, xor, pixel_masks_1
[ x
% 8 ] );
626 if (err
+ params
->bias
> 0)
628 if ((x
/ 8) != ((x
+ params
->x_inc
) / 8))
629 ptr
+= params
->x_inc
;
631 err
+= params
->err_add_1
;
633 else err
+= params
->err_add_2
;
634 ptr
+= dib
->stride
* params
->y_inc
;
639 static void solid_line_null(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
640 DWORD
and, DWORD
xor)
645 static inline INT
calc_offset(INT edge
, INT size
, INT origin
)
649 if(edge
- origin
>= 0)
650 offset
= (edge
- origin
) % size
;
653 offset
= (origin
- edge
) % size
;
654 if(offset
) offset
= size
- offset
;
659 static inline POINT
calc_brush_offset(const RECT
*rc
, const dib_info
*brush
, const POINT
*origin
)
663 offset
.x
= calc_offset(rc
->left
, brush
->width
, origin
->x
);
664 offset
.y
= calc_offset(rc
->top
, brush
->height
, origin
->y
);
669 static void pattern_rects_32(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
670 const dib_info
*brush
, void *and_bits
, void *xor_bits
)
672 DWORD
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
676 for(i
= 0; i
< num
; i
++, rc
++)
678 offset
= calc_brush_offset(rc
, brush
, origin
);
680 start
= get_pixel_ptr_32(dib
, rc
->left
, rc
->top
);
681 start_and
= (DWORD
*)and_bits
+ offset
.y
* brush
->stride
/ 4;
682 start_xor
= (DWORD
*)xor_bits
+ offset
.y
* brush
->stride
/ 4;
684 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
686 and_ptr
= start_and
+ offset
.x
;
687 xor_ptr
= start_xor
+ offset
.x
;
689 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
691 do_rop_32(ptr
++, *and_ptr
++, *xor_ptr
++);
692 if(and_ptr
== start_and
+ brush
->width
)
700 if(offset
.y
== brush
->height
)
702 start_and
= and_bits
;
703 start_xor
= xor_bits
;
708 start_and
+= brush
->stride
/ 4;
709 start_xor
+= brush
->stride
/ 4;
715 static void pattern_rects_24(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
716 const dib_info
*brush
, void *and_bits
, void *xor_bits
)
718 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
722 for(i
= 0; i
< num
; i
++, rc
++)
724 offset
= calc_brush_offset(rc
, brush
, origin
);
726 start
= get_pixel_ptr_24(dib
, rc
->left
, rc
->top
);
727 start_and
= (BYTE
*)and_bits
+ offset
.y
* brush
->stride
;
728 start_xor
= (BYTE
*)xor_bits
+ offset
.y
* brush
->stride
;
730 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
732 and_ptr
= start_and
+ offset
.x
* 3;
733 xor_ptr
= start_xor
+ offset
.x
* 3;
735 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
737 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
738 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
739 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
740 if(and_ptr
== start_and
+ brush
->width
* 3)
748 if(offset
.y
== brush
->height
)
750 start_and
= and_bits
;
751 start_xor
= xor_bits
;
756 start_and
+= brush
->stride
;
757 start_xor
+= brush
->stride
;
763 static void pattern_rects_16(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
764 const dib_info
*brush
, void *and_bits
, void *xor_bits
)
766 WORD
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
770 for(i
= 0; i
< num
; i
++, rc
++)
772 offset
= calc_brush_offset(rc
, brush
, origin
);
774 start
= get_pixel_ptr_16(dib
, rc
->left
, rc
->top
);
775 start_and
= (WORD
*)and_bits
+ offset
.y
* brush
->stride
/ 2;
776 start_xor
= (WORD
*)xor_bits
+ offset
.y
* brush
->stride
/ 2;
778 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 2)
780 and_ptr
= start_and
+ offset
.x
;
781 xor_ptr
= start_xor
+ offset
.x
;
783 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
785 do_rop_16(ptr
++, *and_ptr
++, *xor_ptr
++);
786 if(and_ptr
== start_and
+ brush
->width
)
794 if(offset
.y
== brush
->height
)
796 start_and
= and_bits
;
797 start_xor
= xor_bits
;
802 start_and
+= brush
->stride
/ 2;
803 start_xor
+= brush
->stride
/ 2;
809 static void pattern_rects_8(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
810 const dib_info
*brush
, void *and_bits
, void *xor_bits
)
812 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
816 for(i
= 0; i
< num
; i
++, rc
++)
818 offset
= calc_brush_offset(rc
, brush
, origin
);
820 start
= get_pixel_ptr_8(dib
, rc
->left
, rc
->top
);
821 start_and
= (BYTE
*)and_bits
+ offset
.y
* brush
->stride
;
822 start_xor
= (BYTE
*)xor_bits
+ offset
.y
* brush
->stride
;
824 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
826 and_ptr
= start_and
+ offset
.x
;
827 xor_ptr
= start_xor
+ offset
.x
;
829 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
831 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
832 if(and_ptr
== start_and
+ brush
->width
)
840 if(offset
.y
== brush
->height
)
842 start_and
= and_bits
;
843 start_xor
= xor_bits
;
848 start_and
+= brush
->stride
;
849 start_xor
+= brush
->stride
;
855 static void pattern_rects_4(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
856 const dib_info
*brush
, void *and_bits
, void *xor_bits
)
858 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
862 for(i
= 0; i
< num
; i
++, rc
++)
864 offset
= calc_brush_offset(rc
, brush
, origin
);
866 start
= get_pixel_ptr_4(dib
, rc
->left
, rc
->top
);
867 start_and
= (BYTE
*)and_bits
+ offset
.y
* brush
->stride
;
868 start_xor
= (BYTE
*)xor_bits
+ offset
.y
* brush
->stride
;
870 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
872 INT brush_x
= offset
.x
;
873 BYTE byte_and
, byte_xor
;
875 and_ptr
= start_and
+ brush_x
/ 2;
876 xor_ptr
= start_xor
+ brush_x
/ 2;
878 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
880 /* FIXME: Two pixels at a time */
881 if(x
& 1) /* lower dst nibble */
883 if(brush_x
& 1) /* lower pat nibble */
885 byte_and
= *and_ptr
++ | 0xf0;
886 byte_xor
= *xor_ptr
++ & 0x0f;
888 else /* upper pat nibble */
890 byte_and
= (*and_ptr
>> 4) | 0xf0;
891 byte_xor
= (*xor_ptr
>> 4) & 0x0f;
894 else /* upper dst nibble */
896 if(brush_x
& 1) /* lower pat nibble */
898 byte_and
= (*and_ptr
++ << 4) | 0x0f;
899 byte_xor
= (*xor_ptr
++ << 4) & 0xf0;
901 else /* upper pat nibble */
903 byte_and
= *and_ptr
| 0x0f;
904 byte_xor
= *xor_ptr
& 0xf0;
907 do_rop_8(ptr
, byte_and
, byte_xor
);
911 if(++brush_x
== brush
->width
)
920 if(offset
.y
== brush
->height
)
922 start_and
= and_bits
;
923 start_xor
= xor_bits
;
928 start_and
+= brush
->stride
;
929 start_xor
+= brush
->stride
;
935 static void pattern_rects_1(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
936 const dib_info
*brush
, void *and_bits
, void *xor_bits
)
938 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
942 for(i
= 0; i
< num
; i
++, rc
++)
944 offset
= calc_brush_offset(rc
, brush
, origin
);
946 start
= get_pixel_ptr_1(dib
, rc
->left
, rc
->top
);
947 start_and
= (BYTE
*)and_bits
+ offset
.y
* brush
->stride
;
948 start_xor
= (BYTE
*)xor_bits
+ offset
.y
* brush
->stride
;
950 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
952 INT brush_x
= offset
.x
;
953 BYTE byte_and
, byte_xor
;
955 and_ptr
= start_and
+ brush_x
/ 8;
956 xor_ptr
= start_xor
+ brush_x
/ 8;
958 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
960 byte_and
= (*and_ptr
& pixel_masks_1
[brush_x
% 8]) ? 0xff : 0;
961 byte_and
|= ~pixel_masks_1
[x
% 8];
962 byte_xor
= (*xor_ptr
& pixel_masks_1
[brush_x
% 8]) ? 0xff : 0;
963 byte_xor
&= pixel_masks_1
[x
% 8];
965 do_rop_8(ptr
, byte_and
, byte_xor
);
967 if((x
& 7) == 7) ptr
++;
969 if((brush_x
& 7) == 7)
975 if(++brush_x
== brush
->width
)
984 if(offset
.y
== brush
->height
)
986 start_and
= and_bits
;
987 start_xor
= xor_bits
;
992 start_and
+= brush
->stride
;
993 start_xor
+= brush
->stride
;
999 static void pattern_rects_null(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
1000 const dib_info
*brush
, void *and_bits
, void *xor_bits
)
1005 static void copy_rect_32(const dib_info
*dst
, const RECT
*rc
,
1006 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1008 DWORD
*dst_start
, *src_start
;
1009 struct rop_codes codes
;
1010 int y
, dst_stride
, src_stride
;
1012 if (overlap
& OVERLAP_BELOW
)
1014 dst_start
= get_pixel_ptr_32(dst
, rc
->left
, rc
->bottom
- 1);
1015 src_start
= get_pixel_ptr_32(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1016 dst_stride
= -dst
->stride
/ 4;
1017 src_stride
= -src
->stride
/ 4;
1021 dst_start
= get_pixel_ptr_32(dst
, rc
->left
, rc
->top
);
1022 src_start
= get_pixel_ptr_32(src
, origin
->x
, origin
->y
);
1023 dst_stride
= dst
->stride
/ 4;
1024 src_stride
= src
->stride
/ 4;
1027 if (rop2
== R2_COPYPEN
)
1029 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1030 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) * 4 );
1034 get_rop_codes( rop2
, &codes
);
1035 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1037 if (overlap
& OVERLAP_RIGHT
)
1038 do_rop_codes_line_rev_32( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1040 do_rop_codes_line_32( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1044 static void copy_rect_24(const dib_info
*dst
, const RECT
*rc
,
1045 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1047 BYTE
*dst_start
, *src_start
;
1048 int y
, dst_stride
, src_stride
;
1049 struct rop_codes codes
;
1051 if (overlap
& OVERLAP_BELOW
)
1053 dst_start
= get_pixel_ptr_24(dst
, rc
->left
, rc
->bottom
- 1);
1054 src_start
= get_pixel_ptr_24(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1055 dst_stride
= -dst
->stride
;
1056 src_stride
= -src
->stride
;
1060 dst_start
= get_pixel_ptr_24(dst
, rc
->left
, rc
->top
);
1061 src_start
= get_pixel_ptr_24(src
, origin
->x
, origin
->y
);
1062 dst_stride
= dst
->stride
;
1063 src_stride
= src
->stride
;
1066 if (rop2
== R2_COPYPEN
)
1068 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1069 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) * 3 );
1073 get_rop_codes( rop2
, &codes
);
1074 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1076 if (overlap
& OVERLAP_RIGHT
)
1077 do_rop_codes_line_rev_8( dst_start
, src_start
, &codes
, (rc
->right
- rc
->left
) * 3 );
1079 do_rop_codes_line_8( dst_start
, src_start
, &codes
, (rc
->right
- rc
->left
) * 3 );
1083 static void copy_rect_16(const dib_info
*dst
, const RECT
*rc
,
1084 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1086 WORD
*dst_start
, *src_start
;
1087 int y
, dst_stride
, src_stride
;
1088 struct rop_codes codes
;
1090 if (overlap
& OVERLAP_BELOW
)
1092 dst_start
= get_pixel_ptr_16(dst
, rc
->left
, rc
->bottom
- 1);
1093 src_start
= get_pixel_ptr_16(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1094 dst_stride
= -dst
->stride
/ 2;
1095 src_stride
= -src
->stride
/ 2;
1099 dst_start
= get_pixel_ptr_16(dst
, rc
->left
, rc
->top
);
1100 src_start
= get_pixel_ptr_16(src
, origin
->x
, origin
->y
);
1101 dst_stride
= dst
->stride
/ 2;
1102 src_stride
= src
->stride
/ 2;
1105 if (rop2
== R2_COPYPEN
)
1107 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1108 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) * 2 );
1112 get_rop_codes( rop2
, &codes
);
1113 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1115 if (overlap
& OVERLAP_RIGHT
)
1116 do_rop_codes_line_rev_16( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1118 do_rop_codes_line_16( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1122 static void copy_rect_8(const dib_info
*dst
, const RECT
*rc
,
1123 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1125 BYTE
*dst_start
, *src_start
;
1126 int y
, dst_stride
, src_stride
;
1127 struct rop_codes codes
;
1129 if (overlap
& OVERLAP_BELOW
)
1131 dst_start
= get_pixel_ptr_8(dst
, rc
->left
, rc
->bottom
- 1);
1132 src_start
= get_pixel_ptr_8(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1133 dst_stride
= -dst
->stride
;
1134 src_stride
= -src
->stride
;
1138 dst_start
= get_pixel_ptr_8(dst
, rc
->left
, rc
->top
);
1139 src_start
= get_pixel_ptr_8(src
, origin
->x
, origin
->y
);
1140 dst_stride
= dst
->stride
;
1141 src_stride
= src
->stride
;
1144 if (rop2
== R2_COPYPEN
)
1146 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1147 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) );
1151 get_rop_codes( rop2
, &codes
);
1152 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1154 if (overlap
& OVERLAP_RIGHT
)
1155 do_rop_codes_line_rev_8( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1157 do_rop_codes_line_8( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1161 static void copy_rect_4(const dib_info
*dst
, const RECT
*rc
,
1162 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1164 BYTE
*dst_start
, *src_start
;
1165 int y
, dst_stride
, src_stride
;
1166 struct rop_codes codes
;
1168 if (overlap
& OVERLAP_BELOW
)
1170 dst_start
= get_pixel_ptr_4(dst
, 0, rc
->bottom
- 1);
1171 src_start
= get_pixel_ptr_4(src
, 0, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1172 dst_stride
= -dst
->stride
;
1173 src_stride
= -src
->stride
;
1177 dst_start
= get_pixel_ptr_4(dst
, 0, rc
->top
);
1178 src_start
= get_pixel_ptr_4(src
, 0, origin
->y
);
1179 dst_stride
= dst
->stride
;
1180 src_stride
= src
->stride
;
1183 if (rop2
== R2_COPYPEN
&& (rc
->left
& 1) == 0 && (origin
->x
& 1) == 0 && (rc
->right
& 1) == 0)
1185 dst_start
+= rc
->left
/ 2;
1186 src_start
+= origin
->x
/ 2;
1187 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1188 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) / 2 );
1192 get_rop_codes( rop2
, &codes
);
1193 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1195 if (overlap
& OVERLAP_RIGHT
)
1196 do_rop_codes_line_rev_4( dst_start
, rc
->left
, src_start
, origin
->x
, &codes
, rc
->right
- rc
->left
);
1198 do_rop_codes_line_4( dst_start
, rc
->left
, src_start
, origin
->x
, &codes
, rc
->right
- rc
->left
);
1202 static void copy_rect_1(const dib_info
*dst
, const RECT
*rc
,
1203 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1205 BYTE
*dst_start
, *src_start
;
1206 int y
, dst_stride
, src_stride
;
1207 struct rop_codes codes
;
1209 if (overlap
& OVERLAP_BELOW
)
1211 dst_start
= get_pixel_ptr_1(dst
, 0, rc
->bottom
- 1);
1212 src_start
= get_pixel_ptr_1(src
, 0, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1213 dst_stride
= -dst
->stride
;
1214 src_stride
= -src
->stride
;
1218 dst_start
= get_pixel_ptr_1(dst
, 0, rc
->top
);
1219 src_start
= get_pixel_ptr_1(src
, 0, origin
->y
);
1220 dst_stride
= dst
->stride
;
1221 src_stride
= src
->stride
;
1224 if (rop2
== R2_COPYPEN
&& (rc
->left
& 7) == 0 && (origin
->x
& 7) == 0 && (rc
->right
& 7) == 0)
1226 dst_start
+= rc
->left
/ 8;
1227 src_start
+= origin
->x
/ 8;
1228 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1229 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) / 8 );
1233 get_rop_codes( rop2
, &codes
);
1234 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1236 if (overlap
& OVERLAP_RIGHT
)
1237 do_rop_codes_line_rev_1( dst_start
, rc
->left
, src_start
, origin
->x
, &codes
, rc
->right
- rc
->left
);
1239 do_rop_codes_line_1( dst_start
, rc
->left
, src_start
, origin
->x
, &codes
, rc
->right
- rc
->left
);
1243 static void copy_rect_null(const dib_info
*dst
, const RECT
*rc
,
1244 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1249 static DWORD
get_pixel_32(const dib_info
*dib
, const POINT
*pt
)
1251 DWORD
*ptr
= get_pixel_ptr_32( dib
, pt
->x
, pt
->y
);
1255 static DWORD
get_pixel_24(const dib_info
*dib
, const POINT
*pt
)
1257 BYTE
*ptr
= get_pixel_ptr_24( dib
, pt
->x
, pt
->y
);
1258 return ptr
[0] | ((DWORD
)ptr
[1] << 8) | ((DWORD
)ptr
[2] << 16);
1261 static DWORD
get_pixel_16(const dib_info
*dib
, const POINT
*pt
)
1263 WORD
*ptr
= get_pixel_ptr_16( dib
, pt
->x
, pt
->y
);
1267 static DWORD
get_pixel_8(const dib_info
*dib
, const POINT
*pt
)
1269 BYTE
*ptr
= get_pixel_ptr_8( dib
, pt
->x
, pt
->y
);
1273 static DWORD
get_pixel_4(const dib_info
*dib
, const POINT
*pt
)
1275 BYTE
*ptr
= get_pixel_ptr_4( dib
, pt
->x
, pt
->y
);
1280 return (*ptr
>> 4) & 0x0f;
1283 static DWORD
get_pixel_1(const dib_info
*dib
, const POINT
*pt
)
1285 BYTE
*ptr
= get_pixel_ptr_1( dib
, pt
->x
, pt
->y
);
1286 return (*ptr
& pixel_masks_1
[pt
->x
& 0x7]) ? 1 : 0;
1289 static DWORD
get_pixel_null(const dib_info
*dib
, const POINT
*pt
)
1294 static DWORD
colorref_to_pixel_888(const dib_info
*dib
, COLORREF color
)
1296 return ( ((color
>> 16) & 0xff) | (color
& 0xff00) | ((color
<< 16) & 0xff0000) );
1299 static const DWORD field_masks
[33] =
1301 0x00, /* should never happen */
1302 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff,
1303 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1304 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1305 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1308 static inline DWORD
get_field(DWORD field
, int shift
, int len
)
1310 shift
= shift
- (8 - len
);
1315 field
&= field_masks
[len
];
1316 field
|= field
>> len
;
1320 static inline DWORD
put_field(DWORD field
, int shift
, int len
)
1322 shift
= shift
- (8 - len
);
1323 field
&= field_masks
[len
];
1331 static DWORD
colorref_to_pixel_masks(const dib_info
*dib
, COLORREF colour
)
1335 r
= GetRValue(colour
);
1336 g
= GetGValue(colour
);
1337 b
= GetBValue(colour
);
1339 return put_field(r
, dib
->red_shift
, dib
->red_len
) |
1340 put_field(g
, dib
->green_shift
, dib
->green_len
) |
1341 put_field(b
, dib
->blue_shift
, dib
->blue_len
);
1344 static DWORD
colorref_to_pixel_555(const dib_info
*dib
, COLORREF color
)
1346 return ( ((color
>> 19) & 0x1f) | ((color
>> 6) & 0x03e0) | ((color
<< 7) & 0x7c00) );
1349 static DWORD
rgb_to_pixel_colortable(const dib_info
*dib
, BYTE r
, BYTE g
, BYTE b
)
1351 int i
, best_index
= 0;
1352 DWORD diff
, best_diff
= 0xffffffff;
1354 /* special case for conversion to 1-bpp without a color table:
1355 * we get a 1-entry table containing the background color
1357 if (dib
->bit_count
== 1 && dib
->color_table_size
== 1)
1358 return (r
== dib
->color_table
[0].rgbRed
&&
1359 g
== dib
->color_table
[0].rgbGreen
&&
1360 b
== dib
->color_table
[0].rgbBlue
);
1362 for(i
= 0; i
< dib
->color_table_size
; i
++)
1364 RGBQUAD
*cur
= dib
->color_table
+ i
;
1365 diff
= (r
- cur
->rgbRed
) * (r
- cur
->rgbRed
)
1366 + (g
- cur
->rgbGreen
) * (g
- cur
->rgbGreen
)
1367 + (b
- cur
->rgbBlue
) * (b
- cur
->rgbBlue
);
1375 if(diff
< best_diff
)
1384 static DWORD
colorref_to_pixel_colortable(const dib_info
*dib
, COLORREF color
)
1386 return rgb_to_pixel_colortable( dib
, GetRValue(color
), GetGValue(color
), GetBValue(color
) );
1389 static DWORD
colorref_to_pixel_null(const dib_info
*dib
, COLORREF color
)
1394 static inline RGBQUAD
colortable_entry(const dib_info
*dib
, DWORD index
)
1396 static const RGBQUAD default_rgb
;
1397 if (index
< dib
->color_table_size
) return dib
->color_table
[index
];
1401 static COLORREF
pixel_to_colorref_888(const dib_info
*dib
, DWORD pixel
)
1403 return ( ((pixel
>> 16) & 0xff) | (pixel
& 0xff00) | ((pixel
<< 16) & 0xff0000) );
1406 static COLORREF
pixel_to_colorref_masks(const dib_info
*dib
, DWORD pixel
)
1408 return RGB( get_field( pixel
, dib
->red_shift
, dib
->red_len
),
1409 get_field( pixel
, dib
->green_shift
, dib
->green_len
),
1410 get_field( pixel
, dib
->blue_shift
, dib
->blue_len
) );
1413 static COLORREF
pixel_to_colorref_555(const dib_info
*dib
, DWORD pixel
)
1415 return RGB( ((pixel
>> 7) & 0xf8) | ((pixel
>> 12) & 0x07),
1416 ((pixel
>> 2) & 0xf8) | ((pixel
>> 7) & 0x07),
1417 ((pixel
<< 3) & 0xf8) | ((pixel
>> 2) & 0x07) );
1420 static COLORREF
pixel_to_colorref_colortable(const dib_info
*dib
, DWORD pixel
)
1422 RGBQUAD quad
= colortable_entry( dib
, pixel
);
1424 return RGB( quad
.rgbRed
, quad
.rgbGreen
, quad
.rgbBlue
);
1427 static COLORREF
pixel_to_colorref_null(const dib_info
*dib
, DWORD pixel
)
1432 static inline BOOL
bit_fields_match(const dib_info
*d1
, const dib_info
*d2
)
1434 assert( d1
->bit_count
> 8 && d1
->bit_count
== d2
->bit_count
);
1436 return d1
->red_mask
== d2
->red_mask
&&
1437 d1
->green_mask
== d2
->green_mask
&&
1438 d1
->blue_mask
== d2
->blue_mask
;
1441 static void convert_to_8888(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
1443 DWORD
*dst_start
= get_pixel_ptr_32(dst
, 0, 0), *dst_pixel
, src_val
;
1444 int x
, y
, pad_size
= (dst
->width
- (src_rect
->right
- src_rect
->left
)) * 4;
1446 switch(src
->bit_count
)
1450 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1451 if(src
->funcs
== &funcs_8888
)
1453 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
1454 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
1457 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1459 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 4);
1460 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
1461 dst_start
+= dst
->stride
/ 4;
1462 src_start
+= src
->stride
/ 4;
1466 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
1468 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1470 dst_pixel
= dst_start
;
1471 src_pixel
= src_start
;
1472 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1474 src_val
= *src_pixel
++;
1475 *dst_pixel
++ = (((src_val
>> src
->red_shift
) & 0xff) << 16) |
1476 (((src_val
>> src
->green_shift
) & 0xff) << 8) |
1477 ((src_val
>> src
->blue_shift
) & 0xff);
1479 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1480 dst_start
+= dst
->stride
/ 4;
1481 src_start
+= src
->stride
/ 4;
1486 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1488 dst_pixel
= dst_start
;
1489 src_pixel
= src_start
;
1490 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1492 src_val
= *src_pixel
++;
1493 *dst_pixel
++ = (get_field( src_val
, src
->red_shift
, src
->red_len
) << 16 |
1494 get_field( src_val
, src
->green_shift
, src
->green_len
) << 8 |
1495 get_field( src_val
, src
->blue_shift
, src
->blue_len
));
1497 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1498 dst_start
+= dst
->stride
/ 4;
1499 src_start
+= src
->stride
/ 4;
1507 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1509 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1511 dst_pixel
= dst_start
;
1512 src_pixel
= src_start
;
1513 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1516 rgb
.rgbBlue
= *src_pixel
++;
1517 rgb
.rgbGreen
= *src_pixel
++;
1518 rgb
.rgbRed
= *src_pixel
++;
1520 *dst_pixel
++ = ((rgb
.rgbRed
<< 16) & 0xff0000) | ((rgb
.rgbGreen
<< 8) & 0x00ff00) | (rgb
.rgbBlue
& 0x0000ff);
1522 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1523 dst_start
+= dst
->stride
/ 4;
1524 src_start
+= src
->stride
;
1531 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1532 if(src
->funcs
== &funcs_555
)
1534 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1536 dst_pixel
= dst_start
;
1537 src_pixel
= src_start
;
1538 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1540 src_val
= *src_pixel
++;
1541 *dst_pixel
++ = ((src_val
<< 9) & 0xf80000) | ((src_val
<< 4) & 0x070000) |
1542 ((src_val
<< 6) & 0x00f800) | ((src_val
<< 1) & 0x000700) |
1543 ((src_val
<< 3) & 0x0000f8) | ((src_val
>> 2) & 0x000007);
1545 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1546 dst_start
+= dst
->stride
/ 4;
1547 src_start
+= src
->stride
/ 2;
1550 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
1552 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1554 dst_pixel
= dst_start
;
1555 src_pixel
= src_start
;
1556 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1558 src_val
= *src_pixel
++;
1559 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 19) & 0xf80000) |
1560 (((src_val
>> src
->red_shift
) << 14) & 0x070000) |
1561 (((src_val
>> src
->green_shift
) << 11) & 0x00f800) |
1562 (((src_val
>> src
->green_shift
) << 6) & 0x000700) |
1563 (((src_val
>> src
->blue_shift
) << 3) & 0x0000f8) |
1564 (((src_val
>> src
->blue_shift
) >> 2) & 0x000007);
1566 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1567 dst_start
+= dst
->stride
/ 4;
1568 src_start
+= src
->stride
/ 2;
1571 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
1573 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1575 dst_pixel
= dst_start
;
1576 src_pixel
= src_start
;
1577 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1579 src_val
= *src_pixel
++;
1580 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 19) & 0xf80000) |
1581 (((src_val
>> src
->red_shift
) << 14) & 0x070000) |
1582 (((src_val
>> src
->green_shift
) << 10) & 0x00fc00) |
1583 (((src_val
>> src
->green_shift
) << 4) & 0x000300) |
1584 (((src_val
>> src
->blue_shift
) << 3) & 0x0000f8) |
1585 (((src_val
>> src
->blue_shift
) >> 2) & 0x000007);
1587 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1588 dst_start
+= dst
->stride
/ 4;
1589 src_start
+= src
->stride
/ 2;
1594 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1596 dst_pixel
= dst_start
;
1597 src_pixel
= src_start
;
1598 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1600 src_val
= *src_pixel
++;
1601 *dst_pixel
++ = (get_field( src_val
, src
->red_shift
, src
->red_len
) << 16 |
1602 get_field( src_val
, src
->green_shift
, src
->green_len
) << 8 |
1603 get_field( src_val
, src
->blue_shift
, src
->blue_len
));
1605 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1606 dst_start
+= dst
->stride
/ 4;
1607 src_start
+= src
->stride
/ 2;
1615 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1616 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1618 dst_pixel
= dst_start
;
1619 src_pixel
= src_start
;
1620 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1622 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
1623 *dst_pixel
++ = rgb
.rgbRed
<< 16 | rgb
.rgbGreen
<< 8 | rgb
.rgbBlue
;
1625 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1626 dst_start
+= dst
->stride
/ 4;
1627 src_start
+= src
->stride
;
1634 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1635 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1637 dst_pixel
= dst_start
;
1638 src_pixel
= src_start
;
1639 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1643 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
1645 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
1646 *dst_pixel
++ = rgb
.rgbRed
<< 16 | rgb
.rgbGreen
<< 8 | rgb
.rgbBlue
;
1648 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1649 dst_start
+= dst
->stride
/ 4;
1650 src_start
+= src
->stride
;
1657 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1658 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1660 dst_pixel
= dst_start
;
1661 src_pixel
= src_start
;
1662 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1665 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
1666 if((x
% 8) == 7) src_pixel
++;
1667 rgb
= src
->color_table
[src_val
];
1668 *dst_pixel
++ = rgb
.rgbRed
<< 16 | rgb
.rgbGreen
<< 8 | rgb
.rgbBlue
;
1670 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1671 dst_start
+= dst
->stride
/ 4;
1672 src_start
+= src
->stride
;
1679 static void convert_to_32(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
1681 DWORD
*dst_start
= get_pixel_ptr_32(dst
, 0, 0), *dst_pixel
, src_val
;
1682 int x
, y
, pad_size
= (dst
->width
- (src_rect
->right
- src_rect
->left
)) * 4;
1684 switch(src
->bit_count
)
1688 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1690 if(src
->funcs
== &funcs_8888
)
1692 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1694 dst_pixel
= dst_start
;
1695 src_pixel
= src_start
;
1696 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1698 src_val
= *src_pixel
++;
1699 *dst_pixel
++ = put_field(src_val
>> 16, dst
->red_shift
, dst
->red_len
) |
1700 put_field(src_val
>> 8, dst
->green_shift
, dst
->green_len
) |
1701 put_field(src_val
, dst
->blue_shift
, dst
->blue_len
);
1703 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1704 dst_start
+= dst
->stride
/ 4;
1705 src_start
+= src
->stride
/ 4;
1708 else if(bit_fields_match(src
, dst
))
1710 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
1711 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
1714 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1716 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 4);
1717 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
1718 dst_start
+= dst
->stride
/ 4;
1719 src_start
+= src
->stride
/ 4;
1723 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8 &&
1724 dst
->red_len
== 8 && dst
->green_len
== 8 && dst
->blue_len
== 8)
1726 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1728 dst_pixel
= dst_start
;
1729 src_pixel
= src_start
;
1730 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1732 src_val
= *src_pixel
++;
1733 *dst_pixel
++ = (((src_val
>> src
->red_shift
) & 0xff) << dst
->red_shift
) |
1734 (((src_val
>> src
->green_shift
) & 0xff) << dst
->green_shift
) |
1735 (((src_val
>> src
->blue_shift
) & 0xff) << dst
->blue_shift
);
1737 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1738 dst_start
+= dst
->stride
/ 4;
1739 src_start
+= src
->stride
/ 4;
1744 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1746 dst_pixel
= dst_start
;
1747 src_pixel
= src_start
;
1748 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1750 src_val
= *src_pixel
++;
1751 *dst_pixel
++ = put_field(get_field(src_val
, src
->red_shift
, src
->red_len
), dst
->red_shift
, dst
->red_len
) |
1752 put_field(get_field(src_val
, src
->green_shift
, src
->green_len
), dst
->green_shift
, dst
->green_len
) |
1753 put_field(get_field(src_val
, src
->blue_shift
, src
->blue_len
), dst
->blue_shift
, dst
->blue_len
);
1755 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1756 dst_start
+= dst
->stride
/ 4;
1757 src_start
+= src
->stride
/ 4;
1765 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1767 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1769 dst_pixel
= dst_start
;
1770 src_pixel
= src_start
;
1771 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1774 rgb
.rgbBlue
= *src_pixel
++;
1775 rgb
.rgbGreen
= *src_pixel
++;
1776 rgb
.rgbRed
= *src_pixel
++;
1778 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
1779 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
1780 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
1782 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1783 dst_start
+= dst
->stride
/ 4;
1784 src_start
+= src
->stride
;
1791 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1792 if(src
->funcs
== &funcs_555
)
1794 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1796 dst_pixel
= dst_start
;
1797 src_pixel
= src_start
;
1798 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1800 src_val
= *src_pixel
++;
1801 *dst_pixel
++ = put_field(((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07), dst
->red_shift
, dst
->red_len
) |
1802 put_field(((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07), dst
->green_shift
, dst
->green_len
) |
1803 put_field(((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
1805 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1806 dst_start
+= dst
->stride
/ 4;
1807 src_start
+= src
->stride
/ 2;
1810 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
1812 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1814 dst_pixel
= dst_start
;
1815 src_pixel
= src_start
;
1816 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1818 src_val
= *src_pixel
++;
1819 *dst_pixel
++ = put_field( (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
1820 (((src_val
>> src
->red_shift
) >> 2) & 0x07), dst
->red_shift
, dst
->red_len
) |
1821 put_field( (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
1822 (((src_val
>> src
->green_shift
) >> 2) & 0x07), dst
->green_shift
, dst
->green_len
) |
1823 put_field( (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
1824 (((src_val
>> src
->blue_shift
) >> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
1826 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1827 dst_start
+= dst
->stride
/ 4;
1828 src_start
+= src
->stride
/ 2;
1831 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
1833 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1835 dst_pixel
= dst_start
;
1836 src_pixel
= src_start
;
1837 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1839 src_val
= *src_pixel
++;
1840 *dst_pixel
++ = put_field( (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
1841 (((src_val
>> src
->red_shift
) >> 2) & 0x07), dst
->red_shift
, dst
->red_len
) |
1842 put_field( (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
1843 (((src_val
>> src
->green_shift
) >> 4) & 0x03), dst
->green_shift
, dst
->green_len
) |
1844 put_field( (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
1845 (((src_val
>> src
->blue_shift
) >> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
1847 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1848 dst_start
+= dst
->stride
/ 4;
1849 src_start
+= src
->stride
/ 2;
1854 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1856 dst_pixel
= dst_start
;
1857 src_pixel
= src_start
;
1858 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1860 src_val
= *src_pixel
++;
1861 *dst_pixel
++ = put_field(get_field(src_val
, src
->red_shift
, src
->red_len
), dst
->red_shift
, dst
->red_len
) |
1862 put_field(get_field(src_val
, src
->green_shift
, src
->green_len
), dst
->green_shift
, dst
->green_len
) |
1863 put_field(get_field(src_val
, src
->blue_shift
, src
->blue_len
), dst
->blue_shift
, dst
->blue_len
);
1865 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1866 dst_start
+= dst
->stride
/ 4;
1867 src_start
+= src
->stride
/ 2;
1875 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1876 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1878 dst_pixel
= dst_start
;
1879 src_pixel
= src_start
;
1880 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1882 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
1883 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
1884 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
1885 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
1887 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1888 dst_start
+= dst
->stride
/ 4;
1889 src_start
+= src
->stride
;
1896 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1897 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1899 dst_pixel
= dst_start
;
1900 src_pixel
= src_start
;
1901 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1905 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
1907 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
1908 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
1909 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
1910 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
1912 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1913 dst_start
+= dst
->stride
/ 4;
1914 src_start
+= src
->stride
;
1921 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1922 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1924 dst_pixel
= dst_start
;
1925 src_pixel
= src_start
;
1926 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1929 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
1930 if((x
% 8) == 7) src_pixel
++;
1931 rgb
= src
->color_table
[src_val
];
1932 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
1933 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
1934 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
1936 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1937 dst_start
+= dst
->stride
/ 4;
1938 src_start
+= src
->stride
;
1945 static void convert_to_24(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
1947 BYTE
*dst_start
= get_pixel_ptr_24(dst
, 0, 0), *dst_pixel
;
1949 int x
, y
, pad_size
= ((dst
->width
* 3 + 3) & ~3) - (src_rect
->right
- src_rect
->left
) * 3;
1951 switch(src
->bit_count
)
1955 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1956 if(src
->funcs
== &funcs_8888
)
1958 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1960 dst_pixel
= dst_start
;
1961 src_pixel
= src_start
;
1962 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1964 src_val
= *src_pixel
++;
1965 *dst_pixel
++ = src_val
& 0xff;
1966 *dst_pixel
++ = (src_val
>> 8) & 0xff;
1967 *dst_pixel
++ = (src_val
>> 16) & 0xff;
1969 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1970 dst_start
+= dst
->stride
;
1971 src_start
+= src
->stride
/ 4;
1974 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
1976 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1978 dst_pixel
= dst_start
;
1979 src_pixel
= src_start
;
1980 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1982 src_val
= *src_pixel
++;
1983 *dst_pixel
++ = (src_val
>> src
->blue_shift
) & 0xff;
1984 *dst_pixel
++ = (src_val
>> src
->green_shift
) & 0xff;
1985 *dst_pixel
++ = (src_val
>> src
->red_shift
) & 0xff;
1987 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1988 dst_start
+= dst
->stride
;
1989 src_start
+= src
->stride
/ 4;
1994 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1996 dst_pixel
= dst_start
;
1997 src_pixel
= src_start
;
1998 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2000 src_val
= *src_pixel
++;
2001 *dst_pixel
++ = get_field( src_val
, src
->blue_shift
, src
->blue_len
);
2002 *dst_pixel
++ = get_field( src_val
, src
->green_shift
, src
->green_len
);
2003 *dst_pixel
++ = get_field( src_val
, src
->red_shift
, src
->red_len
);
2005 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2006 dst_start
+= dst
->stride
;
2007 src_start
+= src
->stride
/ 4;
2015 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
);
2017 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
2018 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2021 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2023 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 3);
2024 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
) * 3, 0, pad_size
);
2025 dst_start
+= dst
->stride
;
2026 src_start
+= src
->stride
;
2034 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2035 if(src
->funcs
== &funcs_555
)
2037 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2039 dst_pixel
= dst_start
;
2040 src_pixel
= src_start
;
2041 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2043 src_val
= *src_pixel
++;
2044 *dst_pixel
++ = ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07);
2045 *dst_pixel
++ = ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07);
2046 *dst_pixel
++ = ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07);
2048 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2049 dst_start
+= dst
->stride
;
2050 src_start
+= src
->stride
/ 2;
2053 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2055 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2057 dst_pixel
= dst_start
;
2058 src_pixel
= src_start
;
2059 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2061 src_val
= *src_pixel
++;
2062 *dst_pixel
++ = (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2063 (((src_val
>> src
->blue_shift
) >> 2) & 0x07);
2064 *dst_pixel
++ = (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
2065 (((src_val
>> src
->green_shift
) >> 2) & 0x07);
2066 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2067 (((src_val
>> src
->red_shift
) >> 2) & 0x07);
2069 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2070 dst_start
+= dst
->stride
;
2071 src_start
+= src
->stride
/ 2;
2074 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2076 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2078 dst_pixel
= dst_start
;
2079 src_pixel
= src_start
;
2080 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2082 src_val
= *src_pixel
++;
2083 *dst_pixel
++ = (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2084 (((src_val
>> src
->blue_shift
) >> 2) & 0x07);
2085 *dst_pixel
++ = (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
2086 (((src_val
>> src
->green_shift
) >> 4) & 0x03);
2087 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2088 (((src_val
>> src
->red_shift
) >> 2) & 0x07);
2090 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2091 dst_start
+= dst
->stride
;
2092 src_start
+= src
->stride
/ 2;
2097 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2099 dst_pixel
= dst_start
;
2100 src_pixel
= src_start
;
2101 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2103 src_val
= *src_pixel
++;
2104 *dst_pixel
++ = get_field(src_val
, src
->blue_shift
, src
->blue_len
);
2105 *dst_pixel
++ = get_field(src_val
, src
->green_shift
, src
->green_len
);
2106 *dst_pixel
++ = get_field(src_val
, src
->red_shift
, src
->red_len
);
2108 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2109 dst_start
+= dst
->stride
;
2110 src_start
+= src
->stride
/ 2;
2118 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2119 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2121 dst_pixel
= dst_start
;
2122 src_pixel
= src_start
;
2123 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2125 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
2126 *dst_pixel
++ = rgb
.rgbBlue
;
2127 *dst_pixel
++ = rgb
.rgbGreen
;
2128 *dst_pixel
++ = rgb
.rgbRed
;
2130 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2131 dst_start
+= dst
->stride
;
2132 src_start
+= src
->stride
;
2139 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2140 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2142 dst_pixel
= dst_start
;
2143 src_pixel
= src_start
;
2144 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2148 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
2150 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
2151 *dst_pixel
++ = rgb
.rgbBlue
;
2152 *dst_pixel
++ = rgb
.rgbGreen
;
2153 *dst_pixel
++ = rgb
.rgbRed
;
2155 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2156 dst_start
+= dst
->stride
;
2157 src_start
+= src
->stride
;
2164 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2165 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2167 dst_pixel
= dst_start
;
2168 src_pixel
= src_start
;
2169 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2172 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
2173 if((x
% 8) == 7) src_pixel
++;
2174 rgb
= src
->color_table
[src_val
];
2175 *dst_pixel
++ = rgb
.rgbBlue
;
2176 *dst_pixel
++ = rgb
.rgbGreen
;
2177 *dst_pixel
++ = rgb
.rgbRed
;
2179 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2180 dst_start
+= dst
->stride
;
2181 src_start
+= src
->stride
;
2188 static void convert_to_555(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
2190 WORD
*dst_start
= get_pixel_ptr_16(dst
, 0, 0), *dst_pixel
;
2191 INT x
, y
, pad_size
= ((dst
->width
+ 1) & ~1) * 2 - (src_rect
->right
- src_rect
->left
) * 2;
2194 switch(src
->bit_count
)
2198 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2200 if(src
->funcs
== &funcs_8888
)
2202 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2204 dst_pixel
= dst_start
;
2205 src_pixel
= src_start
;
2206 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2208 src_val
= *src_pixel
++;
2209 *dst_pixel
++ = ((src_val
>> 9) & 0x7c00) |
2210 ((src_val
>> 6) & 0x03e0) |
2211 ((src_val
>> 3) & 0x001f);
2213 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2214 dst_start
+= dst
->stride
/ 2;
2215 src_start
+= src
->stride
/ 4;
2218 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
2220 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2222 dst_pixel
= dst_start
;
2223 src_pixel
= src_start
;
2224 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2226 src_val
= *src_pixel
++;
2227 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 7) & 0x7c00) |
2228 (((src_val
>> src
->green_shift
) << 2) & 0x03e0) |
2229 (((src_val
>> src
->blue_shift
) >> 3) & 0x001f);
2231 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2232 dst_start
+= dst
->stride
/ 2;
2233 src_start
+= src
->stride
/ 4;
2238 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2240 dst_pixel
= dst_start
;
2241 src_pixel
= src_start
;
2242 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2244 src_val
= *src_pixel
++;
2245 *dst_pixel
++ = (((get_field(src_val
, src
->red_shift
, src
->red_len
) << 7) & 0x7c00) |
2246 ((get_field(src_val
, src
->green_shift
, src
->green_len
) << 2) & 0x03e0) |
2247 ( get_field(src_val
, src
->blue_shift
, src
->blue_len
) >> 3));
2249 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2250 dst_start
+= dst
->stride
/ 2;
2251 src_start
+= src
->stride
/ 4;
2259 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2261 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2263 dst_pixel
= dst_start
;
2264 src_pixel
= src_start
;
2265 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2268 rgb
.rgbBlue
= *src_pixel
++;
2269 rgb
.rgbGreen
= *src_pixel
++;
2270 rgb
.rgbRed
= *src_pixel
++;
2272 *dst_pixel
++ = ((rgb
.rgbRed
<< 7) & 0x7c00) |
2273 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
2274 ((rgb
.rgbBlue
>> 3) & 0x001f);
2276 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2277 dst_start
+= dst
->stride
/ 2;
2278 src_start
+= src
->stride
;
2285 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2286 if(src
->funcs
== &funcs_555
)
2288 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
2289 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2292 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2294 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 2);
2295 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
2296 dst_start
+= dst
->stride
/ 2;
2297 src_start
+= src
->stride
/ 2;
2301 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2303 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2305 dst_pixel
= dst_start
;
2306 src_pixel
= src_start
;
2307 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2309 src_val
= *src_pixel
++;
2310 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 10) & 0x7c00) |
2311 (((src_val
>> src
->green_shift
) << 5) & 0x03e0) |
2312 ( (src_val
>> src
->blue_shift
) & 0x001f);
2314 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2315 dst_start
+= dst
->stride
/ 2;
2316 src_start
+= src
->stride
/ 2;
2319 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
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
++)
2327 src_val
= *src_pixel
++;
2328 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 10) & 0x7c00) |
2329 (((src_val
>> src
->green_shift
) << 4) & 0x03e0) |
2330 ( (src_val
>> src
->blue_shift
) & 0x001f);
2332 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2333 dst_start
+= dst
->stride
/ 2;
2334 src_start
+= src
->stride
/ 2;
2339 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2341 dst_pixel
= dst_start
;
2342 src_pixel
= src_start
;
2343 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2345 src_val
= *src_pixel
++;
2346 *dst_pixel
++ = (((get_field(src_val
, src
->red_shift
, src
->red_len
) << 7) & 0x7c00) |
2347 ((get_field(src_val
, src
->green_shift
, src
->green_len
) << 2) & 0x03e0) |
2348 ( get_field(src_val
, src
->blue_shift
, src
->blue_len
) >> 3));
2350 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2351 dst_start
+= dst
->stride
/ 2;
2352 src_start
+= src
->stride
/ 2;
2360 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2361 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2363 dst_pixel
= dst_start
;
2364 src_pixel
= src_start
;
2365 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2367 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
2368 *dst_pixel
++ = ((rgb
.rgbRed
<< 7) & 0x7c00) |
2369 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
2370 ((rgb
.rgbBlue
>> 3) & 0x001f);
2372 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2373 dst_start
+= dst
->stride
/ 2;
2374 src_start
+= src
->stride
;
2381 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2382 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2384 dst_pixel
= dst_start
;
2385 src_pixel
= src_start
;
2386 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2390 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
2392 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
2393 *dst_pixel
++ = ((rgb
.rgbRed
<< 7) & 0x7c00) |
2394 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
2395 ((rgb
.rgbBlue
>> 3) & 0x001f);
2397 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2398 dst_start
+= dst
->stride
/ 2;
2399 src_start
+= src
->stride
;
2406 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2407 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2409 dst_pixel
= dst_start
;
2410 src_pixel
= src_start
;
2411 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2414 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
2415 if((x
% 8) == 7) src_pixel
++;
2416 rgb
= src
->color_table
[src_val
];
2417 *dst_pixel
++ = ((rgb
.rgbRed
<< 7) & 0x7c00) |
2418 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
2419 ((rgb
.rgbBlue
>> 3) & 0x001f);
2421 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2422 dst_start
+= dst
->stride
/ 2;
2423 src_start
+= src
->stride
;
2430 static void convert_to_16(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
2432 WORD
*dst_start
= get_pixel_ptr_16(dst
, 0, 0), *dst_pixel
;
2433 INT x
, y
, pad_size
= ((dst
->width
+ 1) & ~1) * 2 - (src_rect
->right
- src_rect
->left
) * 2;
2436 switch(src
->bit_count
)
2440 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2442 if(src
->funcs
== &funcs_8888
)
2444 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2446 dst_pixel
= dst_start
;
2447 src_pixel
= src_start
;
2448 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2450 src_val
= *src_pixel
++;
2451 *dst_pixel
++ = put_field(src_val
>> 16, dst
->red_shift
, dst
->red_len
) |
2452 put_field(src_val
>> 8, dst
->green_shift
, dst
->green_len
) |
2453 put_field(src_val
, dst
->blue_shift
, dst
->blue_len
);
2455 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2456 dst_start
+= dst
->stride
/ 2;
2457 src_start
+= src
->stride
/ 4;
2460 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
2462 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2464 dst_pixel
= dst_start
;
2465 src_pixel
= src_start
;
2466 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2468 src_val
= *src_pixel
++;
2469 *dst_pixel
++ = put_field(src_val
>> src
->red_shift
, dst
->red_shift
, dst
->red_len
) |
2470 put_field(src_val
>> src
->green_shift
, dst
->green_shift
, dst
->green_len
) |
2471 put_field(src_val
>> src
->blue_shift
, dst
->blue_shift
, dst
->blue_len
);
2473 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2474 dst_start
+= dst
->stride
/ 2;
2475 src_start
+= src
->stride
/ 4;
2480 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2482 dst_pixel
= dst_start
;
2483 src_pixel
= src_start
;
2484 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2486 src_val
= *src_pixel
++;
2487 *dst_pixel
++ = put_field(get_field(src_val
, src
->red_shift
, src
->red_len
), dst
->red_shift
, dst
->red_len
) |
2488 put_field(get_field(src_val
, src
->green_shift
, src
->green_len
), dst
->green_shift
, dst
->green_len
) |
2489 put_field(get_field(src_val
, src
->blue_shift
, src
->blue_len
), dst
->blue_shift
, dst
->blue_len
);
2491 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2492 dst_start
+= dst
->stride
/ 2;
2493 src_start
+= src
->stride
/ 4;
2501 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2503 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2505 dst_pixel
= dst_start
;
2506 src_pixel
= src_start
;
2507 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2510 rgb
.rgbBlue
= *src_pixel
++;
2511 rgb
.rgbGreen
= *src_pixel
++;
2512 rgb
.rgbRed
= *src_pixel
++;
2514 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
2515 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
2516 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
2518 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2519 dst_start
+= dst
->stride
/ 2;
2520 src_start
+= src
->stride
;
2527 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2528 if(src
->funcs
== &funcs_555
)
2530 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2532 dst_pixel
= dst_start
;
2533 src_pixel
= src_start
;
2534 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2536 src_val
= *src_pixel
++;
2537 *dst_pixel
++ = put_field(((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07), dst
->red_shift
, dst
->red_len
) |
2538 put_field(((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07), dst
->green_shift
, dst
->green_len
) |
2539 put_field(((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
2541 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2542 dst_start
+= dst
->stride
/ 2;
2543 src_start
+= src
->stride
/ 2;
2546 else if(bit_fields_match(src
, dst
))
2548 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
2549 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2552 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2554 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 2);
2555 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
2556 dst_start
+= dst
->stride
/ 2;
2557 src_start
+= src
->stride
/ 2;
2561 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2563 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2565 dst_pixel
= dst_start
;
2566 src_pixel
= src_start
;
2567 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2569 src_val
= *src_pixel
++;
2570 *dst_pixel
++ = put_field( (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2571 (((src_val
>> src
->red_shift
) >> 2) & 0x07), dst
->red_shift
, dst
->red_len
) |
2572 put_field( (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
2573 (((src_val
>> src
->green_shift
) >> 2) & 0x07), dst
->green_shift
, dst
->green_len
) |
2574 put_field( (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2575 (((src_val
>> src
->blue_shift
) >> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
2577 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2578 dst_start
+= dst
->stride
/ 2;
2579 src_start
+= src
->stride
/ 2;
2582 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2584 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2586 dst_pixel
= dst_start
;
2587 src_pixel
= src_start
;
2588 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2590 src_val
= *src_pixel
++;
2591 *dst_pixel
++ = put_field( (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2592 (((src_val
>> src
->red_shift
) >> 2) & 0x07), dst
->red_shift
, dst
->red_len
) |
2593 put_field( (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
2594 (((src_val
>> src
->green_shift
) >> 4) & 0x03), dst
->green_shift
, dst
->green_len
) |
2595 put_field( (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2596 (((src_val
>> src
->blue_shift
) >> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
2598 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2599 dst_start
+= dst
->stride
/ 2;
2600 src_start
+= src
->stride
/ 2;
2605 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2607 dst_pixel
= dst_start
;
2608 src_pixel
= src_start
;
2609 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2611 src_val
= *src_pixel
++;
2612 *dst_pixel
++ = put_field(get_field(src_val
, src
->red_shift
, src
->red_len
), dst
->red_shift
, dst
->red_len
) |
2613 put_field(get_field(src_val
, src
->green_shift
, src
->green_len
), dst
->green_shift
, dst
->green_len
) |
2614 put_field(get_field(src_val
, src
->blue_shift
, src
->blue_len
), dst
->blue_shift
, dst
->blue_len
);
2616 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2617 dst_start
+= dst
->stride
/ 2;
2618 src_start
+= src
->stride
/ 2;
2626 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2627 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2629 dst_pixel
= dst_start
;
2630 src_pixel
= src_start
;
2631 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2633 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
2634 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
2635 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
2636 put_field(rgb
.rgbBlue
, 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
;
2647 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2648 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2650 dst_pixel
= dst_start
;
2651 src_pixel
= src_start
;
2652 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2656 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
2658 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
2659 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
2660 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
2661 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
2663 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2664 dst_start
+= dst
->stride
/ 2;
2665 src_start
+= src
->stride
;
2672 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2673 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2675 dst_pixel
= dst_start
;
2676 src_pixel
= src_start
;
2677 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2680 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
2681 if((x
% 8) == 7) src_pixel
++;
2682 rgb
= src
->color_table
[src_val
];
2683 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
2684 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
2685 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
2687 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2688 dst_start
+= dst
->stride
/ 2;
2689 src_start
+= src
->stride
;
2696 static inline BOOL
color_tables_match(const dib_info
*d1
, const dib_info
*d2
)
2698 assert(d1
->color_table_size
&& d2
->color_table_size
);
2700 if(d1
->color_table_size
!= d2
->color_table_size
) return FALSE
;
2701 return !memcmp(d1
->color_table
, d2
->color_table
, d1
->color_table_size
* sizeof(d1
->color_table
[0]));
2704 static inline DWORD
rgb_lookup_colortable(const dib_info
*dst
, BYTE r
, BYTE g
, BYTE b
)
2706 /* Windows reduces precision to 5 bits, probably in order to build some sort of lookup cache */
2707 return rgb_to_pixel_colortable( dst
, (r
& ~7) + 4, (g
& ~7) + 4, (b
& ~7) + 4 );
2710 static void convert_to_8(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
2712 BYTE
*dst_start
= get_pixel_ptr_8(dst
, 0, 0), *dst_pixel
;
2713 INT x
, y
, pad_size
= ((dst
->width
+ 3) & ~3) - (src_rect
->right
- src_rect
->left
);
2716 switch(src
->bit_count
)
2720 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2722 if(src
->funcs
== &funcs_8888
)
2724 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2726 dst_pixel
= dst_start
;
2727 src_pixel
= src_start
;
2728 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2730 src_val
= *src_pixel
++;
2731 *dst_pixel
++ = rgb_lookup_colortable(dst
, src_val
>> 16, src_val
>> 8, src_val
);
2733 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2734 dst_start
+= dst
->stride
;
2735 src_start
+= src
->stride
/ 4;
2738 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
2740 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2742 dst_pixel
= dst_start
;
2743 src_pixel
= src_start
;
2744 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2746 src_val
= *src_pixel
++;
2747 *dst_pixel
++ = rgb_lookup_colortable(dst
,
2748 src_val
>> src
->red_shift
,
2749 src_val
>> src
->green_shift
,
2750 src_val
>> src
->blue_shift
);
2752 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2753 dst_start
+= dst
->stride
;
2754 src_start
+= src
->stride
/ 4;
2759 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2761 dst_pixel
= dst_start
;
2762 src_pixel
= src_start
;
2763 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2765 src_val
= *src_pixel
++;
2766 *dst_pixel
++ = rgb_lookup_colortable(dst
,
2767 get_field(src_val
, src
->red_shift
, src
->red_len
),
2768 get_field(src_val
, src
->green_shift
, src
->green_len
),
2769 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
2771 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2772 dst_start
+= dst
->stride
;
2773 src_start
+= src
->stride
/ 4;
2781 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2783 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2785 dst_pixel
= dst_start
;
2786 src_pixel
= src_start
;
2787 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, src_pixel
+= 3)
2789 *dst_pixel
++ = rgb_lookup_colortable(dst
, src_pixel
[2], src_pixel
[1], src_pixel
[0] );
2791 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2792 dst_start
+= dst
->stride
;
2793 src_start
+= src
->stride
;
2800 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2801 if(src
->funcs
== &funcs_555
)
2803 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2805 dst_pixel
= dst_start
;
2806 src_pixel
= src_start
;
2807 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2809 src_val
= *src_pixel
++;
2810 *dst_pixel
++ = rgb_lookup_colortable(dst
,
2811 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
2812 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
2813 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07) );
2815 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2816 dst_start
+= dst
->stride
;
2817 src_start
+= src
->stride
/ 2;
2820 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2822 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2824 dst_pixel
= dst_start
;
2825 src_pixel
= src_start
;
2826 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2828 src_val
= *src_pixel
++;
2829 *dst_pixel
++ = rgb_lookup_colortable(dst
,
2830 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2831 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
2832 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
2833 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
2834 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2835 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
2837 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2838 dst_start
+= dst
->stride
;
2839 src_start
+= src
->stride
/ 2;
2842 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2844 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2846 dst_pixel
= dst_start
;
2847 src_pixel
= src_start
;
2848 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2850 src_val
= *src_pixel
++;
2851 *dst_pixel
++ = rgb_lookup_colortable(dst
,
2852 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2853 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
2854 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
2855 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
2856 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2857 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
2859 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2860 dst_start
+= dst
->stride
;
2861 src_start
+= src
->stride
/ 2;
2866 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2868 dst_pixel
= dst_start
;
2869 src_pixel
= src_start
;
2870 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2872 src_val
= *src_pixel
++;
2873 *dst_pixel
++ = rgb_lookup_colortable(dst
,
2874 get_field(src_val
, src
->red_shift
, src
->red_len
),
2875 get_field(src_val
, src
->green_shift
, src
->green_len
),
2876 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
2878 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2879 dst_start
+= dst
->stride
;
2880 src_start
+= src
->stride
/ 2;
2888 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2890 if(color_tables_match(dst
, src
))
2892 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
2893 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2896 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2898 memcpy(dst_start
, src_start
, src_rect
->right
- src_rect
->left
);
2899 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
2900 dst_start
+= dst
->stride
;
2901 src_start
+= src
->stride
;
2907 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2909 dst_pixel
= dst_start
;
2910 src_pixel
= src_start
;
2911 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2913 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
2914 *dst_pixel
++ = rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
2916 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2917 dst_start
+= dst
->stride
;
2918 src_start
+= src
->stride
;
2926 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2927 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2929 dst_pixel
= dst_start
;
2930 src_pixel
= src_start
;
2931 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2935 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
2937 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
2938 *dst_pixel
++ = rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
2940 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2941 dst_start
+= dst
->stride
;
2942 src_start
+= src
->stride
;
2949 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2950 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2952 dst_pixel
= dst_start
;
2953 src_pixel
= src_start
;
2954 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2957 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
2958 if((x
% 8) == 7) src_pixel
++;
2959 rgb
= src
->color_table
[src_val
];
2960 *dst_pixel
++ = rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
2962 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2963 dst_start
+= dst
->stride
;
2964 src_start
+= src
->stride
;
2971 static void convert_to_4(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
2973 BYTE
*dst_start
= get_pixel_ptr_4(dst
, 0, 0), *dst_pixel
, dst_val
;
2974 INT x
, y
, pad_size
= ((dst
->width
+ 7) & ~7) / 2 - (src_rect
->right
- src_rect
->left
+ 1) / 2;
2977 switch(src
->bit_count
)
2981 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2983 if(src
->funcs
== &funcs_8888
)
2985 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2987 dst_pixel
= dst_start
;
2988 src_pixel
= src_start
;
2989 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2991 src_val
= *src_pixel
++;
2992 dst_val
= rgb_to_pixel_colortable(dst
, src_val
>> 16, src_val
>> 8, src_val
);
2993 if((x
- src_rect
->left
) & 1)
2995 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
2999 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3003 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3004 memset(dst_pixel
, 0, pad_size
);
3006 dst_start
+= dst
->stride
;
3007 src_start
+= src
->stride
/ 4;
3010 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
3012 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3014 dst_pixel
= dst_start
;
3015 src_pixel
= src_start
;
3016 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3018 src_val
= *src_pixel
++;
3019 dst_val
= rgb_to_pixel_colortable(dst
,
3020 src_val
>> src
->red_shift
,
3021 src_val
>> src
->green_shift
,
3022 src_val
>> src
->blue_shift
);
3023 if((x
- src_rect
->left
) & 1)
3025 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3029 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3033 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3034 memset(dst_pixel
, 0, pad_size
);
3036 dst_start
+= dst
->stride
;
3037 src_start
+= src
->stride
/ 4;
3042 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3044 dst_pixel
= dst_start
;
3045 src_pixel
= src_start
;
3046 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3048 src_val
= *src_pixel
++;
3049 dst_val
= rgb_to_pixel_colortable(dst
,
3050 get_field(src_val
, src
->red_shift
, src
->red_len
),
3051 get_field(src_val
, src
->green_shift
, src
->green_len
),
3052 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3053 if((x
- src_rect
->left
) & 1)
3055 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3059 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3063 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3064 memset(dst_pixel
, 0, pad_size
);
3066 dst_start
+= dst
->stride
;
3067 src_start
+= src
->stride
/ 4;
3075 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3077 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3079 dst_pixel
= dst_start
;
3080 src_pixel
= src_start
;
3081 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, src_pixel
+= 3)
3083 dst_val
= rgb_to_pixel_colortable(dst
, src_pixel
[2], src_pixel
[1], src_pixel
[0]);
3085 if((x
- src_rect
->left
) & 1)
3087 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3091 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3095 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3096 memset(dst_pixel
, 0, pad_size
);
3098 dst_start
+= dst
->stride
;
3099 src_start
+= src
->stride
;
3106 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3107 if(src
->funcs
== &funcs_555
)
3109 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3111 dst_pixel
= dst_start
;
3112 src_pixel
= src_start
;
3113 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3115 src_val
= *src_pixel
++;
3116 dst_val
= rgb_to_pixel_colortable(dst
,
3117 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
3118 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
3119 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07) );
3120 if((x
- src_rect
->left
) & 1)
3122 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3126 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3130 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3131 memset(dst_pixel
, 0, pad_size
);
3133 dst_start
+= dst
->stride
;
3134 src_start
+= src
->stride
/ 2;
3137 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
3139 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3141 dst_pixel
= dst_start
;
3142 src_pixel
= src_start
;
3143 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3145 src_val
= *src_pixel
++;
3146 dst_val
= rgb_to_pixel_colortable(dst
,
3147 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3148 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3149 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
3150 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
3151 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3152 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
3153 if((x
- src_rect
->left
) & 1)
3155 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3159 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3163 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3164 memset(dst_pixel
, 0, pad_size
);
3166 dst_start
+= dst
->stride
;
3167 src_start
+= src
->stride
/ 2;
3170 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
3172 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3174 dst_pixel
= dst_start
;
3175 src_pixel
= src_start
;
3176 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3178 src_val
= *src_pixel
++;
3179 dst_val
= rgb_to_pixel_colortable(dst
,
3180 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3181 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3182 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
3183 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
3184 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3185 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
3186 if((x
- src_rect
->left
) & 1)
3188 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3192 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3196 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3197 memset(dst_pixel
, 0, pad_size
);
3199 dst_start
+= dst
->stride
;
3200 src_start
+= src
->stride
/ 2;
3205 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3207 dst_pixel
= dst_start
;
3208 src_pixel
= src_start
;
3209 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3211 src_val
= *src_pixel
++;
3212 dst_val
= rgb_to_pixel_colortable(dst
,
3213 get_field(src_val
, src
->red_shift
, src
->red_len
),
3214 get_field(src_val
, src
->green_shift
, src
->green_len
),
3215 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3216 if((x
- src_rect
->left
) & 1)
3218 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3222 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3226 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3227 memset(dst_pixel
, 0, pad_size
);
3229 dst_start
+= dst
->stride
;
3230 src_start
+= src
->stride
/ 2;
3238 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3240 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3242 dst_pixel
= dst_start
;
3243 src_pixel
= src_start
;
3244 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3246 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
3247 dst_val
= rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
3248 if((x
- src_rect
->left
) & 1)
3250 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3254 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3258 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3259 memset(dst_pixel
, 0, pad_size
);
3261 dst_start
+= dst
->stride
;
3262 src_start
+= src
->stride
;
3269 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3271 if(color_tables_match(dst
, src
) && (src_rect
->left
& 1) == 0)
3273 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
3274 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
3277 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3279 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
+ 1) / 2);
3280 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
+ 1) / 2, 0, pad_size
);
3281 dst_start
+= dst
->stride
;
3282 src_start
+= src
->stride
;
3288 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3290 dst_pixel
= dst_start
;
3291 src_pixel
= src_start
;
3292 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3296 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
3298 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
3299 dst_val
= rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
3300 if((x
- src_rect
->left
) & 1)
3302 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3306 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3310 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3311 memset(dst_pixel
, 0, pad_size
);
3313 dst_start
+= dst
->stride
;
3314 src_start
+= src
->stride
;
3322 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3323 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3325 dst_pixel
= dst_start
;
3326 src_pixel
= src_start
;
3327 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3330 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
3331 if((x
% 8) == 7) src_pixel
++;
3332 rgb
= src
->color_table
[src_val
];
3333 dst_val
= rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
3334 if((x
- src_rect
->left
) & 1)
3336 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3340 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3344 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3345 memset(dst_pixel
, 0, pad_size
);
3347 dst_start
+= dst
->stride
;
3348 src_start
+= src
->stride
;
3355 static void convert_to_1(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
3357 BYTE
*dst_start
= get_pixel_ptr_1(dst
, 0, 0), *dst_pixel
, dst_val
;
3358 INT x
, y
, pad_size
= ((dst
->width
+ 31) & ~31) / 8 - (src_rect
->right
- src_rect
->left
+ 7) / 8;
3362 /* FIXME: Brushes should be dithered. */
3364 switch(src
->bit_count
)
3368 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3370 if(src
->funcs
== &funcs_8888
)
3372 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3374 dst_pixel
= dst_start
;
3375 src_pixel
= src_start
;
3376 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3378 src_val
= *src_pixel
++;
3379 dst_val
= rgb_to_pixel_colortable(dst
, src_val
>> 16, src_val
>> 8, src_val
) ? 0xff : 0;
3381 if(bit_pos
== 0) *dst_pixel
= 0;
3382 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3392 if(bit_pos
!= 0) dst_pixel
++;
3393 memset(dst_pixel
, 0, pad_size
);
3395 dst_start
+= dst
->stride
;
3396 src_start
+= src
->stride
/ 4;
3399 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
3401 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3403 dst_pixel
= dst_start
;
3404 src_pixel
= src_start
;
3405 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3407 src_val
= *src_pixel
++;
3408 dst_val
= rgb_to_pixel_colortable(dst
,
3409 src_val
>> src
->red_shift
,
3410 src_val
>> src
->green_shift
,
3411 src_val
>> src
->blue_shift
) ? 0xff : 0;
3413 if(bit_pos
== 0) *dst_pixel
= 0;
3414 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3424 if(bit_pos
!= 0) dst_pixel
++;
3425 memset(dst_pixel
, 0, pad_size
);
3427 dst_start
+= dst
->stride
;
3428 src_start
+= src
->stride
/ 4;
3433 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3435 dst_pixel
= dst_start
;
3436 src_pixel
= src_start
;
3437 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3439 src_val
= *src_pixel
++;
3440 dst_val
= rgb_to_pixel_colortable(dst
,
3441 get_field(src_val
, src
->red_shift
, src
->red_len
),
3442 get_field(src_val
, src
->green_shift
, src
->green_len
),
3443 get_field(src_val
, src
->blue_shift
, src
->blue_len
)) ? 0xff : 0;
3445 if(bit_pos
== 0) *dst_pixel
= 0;
3446 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3456 if(bit_pos
!= 0) dst_pixel
++;
3457 memset(dst_pixel
, 0, pad_size
);
3459 dst_start
+= dst
->stride
;
3460 src_start
+= src
->stride
/ 4;
3468 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3470 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3472 dst_pixel
= dst_start
;
3473 src_pixel
= src_start
;
3474 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++, src_pixel
+= 3)
3476 dst_val
= rgb_to_pixel_colortable(dst
, src_pixel
[2], src_pixel
[1], src_pixel
[0]) ? 0xff : 0;
3478 if(bit_pos
== 0) *dst_pixel
= 0;
3479 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3489 if(bit_pos
!= 0) dst_pixel
++;
3490 memset(dst_pixel
, 0, pad_size
);
3492 dst_start
+= dst
->stride
;
3493 src_start
+= src
->stride
;
3500 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3501 if(src
->funcs
== &funcs_555
)
3503 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3505 dst_pixel
= dst_start
;
3506 src_pixel
= src_start
;
3507 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3509 src_val
= *src_pixel
++;
3510 dst_val
= rgb_to_pixel_colortable(dst
,
3511 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
3512 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
3513 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07) ) ? 0xff : 0;
3515 if(bit_pos
== 0) *dst_pixel
= 0;
3516 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3526 if(bit_pos
!= 0) dst_pixel
++;
3527 memset(dst_pixel
, 0, pad_size
);
3529 dst_start
+= dst
->stride
;
3530 src_start
+= src
->stride
/ 2;
3533 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
3535 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3537 dst_pixel
= dst_start
;
3538 src_pixel
= src_start
;
3539 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3541 src_val
= *src_pixel
++;
3542 dst_val
= rgb_to_pixel_colortable(dst
,
3543 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3544 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3545 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
3546 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
3547 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3548 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) ) ? 0xff : 0;
3549 if(bit_pos
== 0) *dst_pixel
= 0;
3550 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3560 if(bit_pos
!= 0) dst_pixel
++;
3561 memset(dst_pixel
, 0, pad_size
);
3563 dst_start
+= dst
->stride
;
3564 src_start
+= src
->stride
/ 2;
3567 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
3569 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3571 dst_pixel
= dst_start
;
3572 src_pixel
= src_start
;
3573 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3575 src_val
= *src_pixel
++;
3576 dst_val
= rgb_to_pixel_colortable(dst
,
3577 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3578 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3579 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
3580 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
3581 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3582 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) ) ? 0xff : 0;
3583 if(bit_pos
== 0) *dst_pixel
= 0;
3584 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3594 if(bit_pos
!= 0) dst_pixel
++;
3595 memset(dst_pixel
, 0, pad_size
);
3597 dst_start
+= dst
->stride
;
3598 src_start
+= src
->stride
/ 2;
3603 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3605 dst_pixel
= dst_start
;
3606 src_pixel
= src_start
;
3607 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3609 src_val
= *src_pixel
++;
3610 dst_val
= rgb_to_pixel_colortable(dst
,
3611 get_field(src_val
, src
->red_shift
, src
->red_len
),
3612 get_field(src_val
, src
->green_shift
, src
->green_len
),
3613 get_field(src_val
, src
->blue_shift
, src
->blue_len
)) ? 0xff : 0;
3614 if(bit_pos
== 0) *dst_pixel
= 0;
3615 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3625 if(bit_pos
!= 0) dst_pixel
++;
3626 memset(dst_pixel
, 0, pad_size
);
3628 dst_start
+= dst
->stride
;
3629 src_start
+= src
->stride
/ 2;
3637 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3639 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3641 dst_pixel
= dst_start
;
3642 src_pixel
= src_start
;
3643 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3645 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
3646 dst_val
= rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
) ? 0xff : 0;
3648 if(bit_pos
== 0) *dst_pixel
= 0;
3649 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3659 if(bit_pos
!= 0) dst_pixel
++;
3660 memset(dst_pixel
, 0, pad_size
);
3662 dst_start
+= dst
->stride
;
3663 src_start
+= src
->stride
;
3670 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3672 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3674 dst_pixel
= dst_start
;
3675 src_pixel
= src_start
;
3676 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3680 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
3682 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
3683 dst_val
= rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
) ? 0xff : 0;
3685 if(bit_pos
== 0) *dst_pixel
= 0;
3686 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3696 if(bit_pos
!= 0) dst_pixel
++;
3697 memset(dst_pixel
, 0, pad_size
);
3699 dst_start
+= dst
->stride
;
3700 src_start
+= src
->stride
;
3705 /* Note that while MSDN states that a 1 bpp dib brush -> mono dc
3706 uses text/bkgnd colours instead of the dib's colour table, this
3707 doesn't appear to be the case for a dc backed by a
3712 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3713 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3715 dst_pixel
= dst_start
;
3716 src_pixel
= src_start
;
3717 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3720 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
3721 if((x
% 8) == 7) src_pixel
++;
3722 rgb
= src
->color_table
[src_val
];
3723 dst_val
= rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
) ? 0xff : 0;
3725 if(bit_pos
== 0) *dst_pixel
= 0;
3726 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3736 if(bit_pos
!= 0) dst_pixel
++;
3737 memset(dst_pixel
, 0, pad_size
);
3739 dst_start
+= dst
->stride
;
3740 src_start
+= src
->stride
;
3747 static void convert_to_null(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
3751 static inline BYTE
blend_color(BYTE dst
, BYTE src
, DWORD alpha
)
3753 return (src
* alpha
+ dst
* (255 - alpha
) + 127) / 255;
3756 static inline DWORD
blend_argb( DWORD dst
, DWORD src
, DWORD alpha
)
3758 return (blend_color( dst
, src
, alpha
) |
3759 blend_color( dst
>> 8, src
>> 8, alpha
) << 8 |
3760 blend_color( dst
>> 16, src
>> 16, alpha
) << 16 |
3761 blend_color( dst
>> 24, src
>> 24, alpha
) << 24);
3764 static inline DWORD
blend_argb_alpha( DWORD dst
, DWORD src
, DWORD alpha
)
3766 BYTE b
= ((BYTE
)src
* alpha
+ 127) / 255;
3767 BYTE g
= ((BYTE
)(src
>> 8) * alpha
+ 127) / 255;
3768 BYTE r
= ((BYTE
)(src
>> 16) * alpha
+ 127) / 255;
3769 alpha
= ((BYTE
)(src
>> 24) * alpha
+ 127) / 255;
3770 return ((b
+ ((BYTE
)dst
* (255 - alpha
) + 127) / 255) |
3771 (g
+ ((BYTE
)(dst
>> 8) * (255 - alpha
) + 127) / 255) << 8 |
3772 (r
+ ((BYTE
)(dst
>> 16) * (255 - alpha
) + 127) / 255) << 16 |
3773 (alpha
+ ((BYTE
)(dst
>> 24) * (255 - alpha
) + 127) / 255) << 24);
3776 static inline DWORD
blend_rgb( BYTE dst_r
, BYTE dst_g
, BYTE dst_b
, DWORD src
, BLENDFUNCTION blend
)
3778 if (blend
.AlphaFormat
& AC_SRC_ALPHA
)
3780 DWORD alpha
= blend
.SourceConstantAlpha
;
3781 BYTE src_b
= ((BYTE
)src
* alpha
+ 127) / 255;
3782 BYTE src_g
= ((BYTE
)(src
>> 8) * alpha
+ 127) / 255;
3783 BYTE src_r
= ((BYTE
)(src
>> 16) * alpha
+ 127) / 255;
3784 alpha
= ((BYTE
)(src
>> 24) * alpha
+ 127) / 255;
3785 return ((src_b
+ (dst_b
* (255 - alpha
) + 127) / 255) |
3786 (src_g
+ (dst_g
* (255 - alpha
) + 127) / 255) << 8 |
3787 (src_r
+ (dst_r
* (255 - alpha
) + 127) / 255) << 16);
3789 return (blend_color( dst_b
, src
, blend
.SourceConstantAlpha
) |
3790 blend_color( dst_g
, src
>> 8, blend
.SourceConstantAlpha
) << 8 |
3791 blend_color( dst_r
, src
>> 16, blend
.SourceConstantAlpha
) << 16);
3794 static void blend_rect_8888(const dib_info
*dst
, const RECT
*rc
,
3795 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3797 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
3798 DWORD
*dst_ptr
= get_pixel_ptr_32( dst
, rc
->left
, rc
->top
);
3801 if (blend
.AlphaFormat
& AC_SRC_ALPHA
)
3802 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
3803 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3804 dst_ptr
[x
] = blend_argb_alpha( dst_ptr
[x
], src_ptr
[x
], blend
.SourceConstantAlpha
);
3806 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
3807 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3808 dst_ptr
[x
] = blend_argb( dst_ptr
[x
], src_ptr
[x
], blend
.SourceConstantAlpha
);
3811 static void blend_rect_32(const dib_info
*dst
, const RECT
*rc
,
3812 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3814 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
3815 DWORD
*dst_ptr
= get_pixel_ptr_32( dst
, rc
->left
, rc
->top
);
3818 if (dst
->red_len
== 8 && dst
->green_len
== 8 && dst
->blue_len
== 8)
3820 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
3822 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3824 DWORD val
= blend_rgb( dst_ptr
[x
] >> dst
->red_shift
,
3825 dst_ptr
[x
] >> dst
->green_shift
,
3826 dst_ptr
[x
] >> dst
->blue_shift
,
3827 src_ptr
[x
], blend
);
3828 dst_ptr
[x
] = ((( val
& 0xff) << dst
->blue_shift
) |
3829 (((val
>> 8) & 0xff) << dst
->green_shift
) |
3830 (((val
>> 16) & 0xff) << dst
->red_shift
));
3836 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
3838 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3840 DWORD val
= blend_rgb( get_field( dst_ptr
[x
], dst
->red_shift
, dst
->red_len
),
3841 get_field( dst_ptr
[x
], dst
->green_shift
, dst
->green_len
),
3842 get_field( dst_ptr
[x
], dst
->blue_shift
, dst
->blue_len
),
3843 src_ptr
[x
], blend
);
3844 dst_ptr
[x
] = (put_field( val
>> 16, dst
->red_shift
, dst
->red_len
) |
3845 put_field( val
>> 8, dst
->green_shift
, dst
->green_len
) |
3846 put_field( val
, dst
->blue_shift
, dst
->blue_len
));
3852 static void blend_rect_24(const dib_info
*dst
, const RECT
*rc
,
3853 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3855 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
3856 BYTE
*dst_ptr
= get_pixel_ptr_24( dst
, rc
->left
, rc
->top
);
3859 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
3861 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3863 DWORD val
= blend_rgb( dst_ptr
[x
* 3 + 2], dst_ptr
[x
* 3 + 1], dst_ptr
[x
* 3],
3864 src_ptr
[x
], blend
);
3865 dst_ptr
[x
* 3] = val
;
3866 dst_ptr
[x
* 3 + 1] = val
>> 8;
3867 dst_ptr
[x
* 3 + 2] = val
>> 16;
3872 static void blend_rect_555(const dib_info
*dst
, const RECT
*rc
,
3873 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3875 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
3876 WORD
*dst_ptr
= get_pixel_ptr_16( dst
, rc
->left
, rc
->top
);
3879 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 2, src_ptr
+= src
->stride
/ 4)
3881 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3883 DWORD val
= blend_rgb( ((dst_ptr
[x
] >> 7) & 0xf8) | ((dst_ptr
[x
] >> 12) & 0x07),
3884 ((dst_ptr
[x
] >> 2) & 0xf8) | ((dst_ptr
[x
] >> 7) & 0x07),
3885 ((dst_ptr
[x
] << 3) & 0xf8) | ((dst_ptr
[x
] >> 2) & 0x07),
3886 src_ptr
[x
], blend
);
3887 dst_ptr
[x
] = ((val
>> 9) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 3) & 0x001f);
3892 static void blend_rect_16(const dib_info
*dst
, const RECT
*rc
,
3893 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3895 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
3896 WORD
*dst_ptr
= get_pixel_ptr_16( dst
, rc
->left
, rc
->top
);
3899 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 2, src_ptr
+= src
->stride
/ 4)
3901 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3903 DWORD val
= blend_rgb( get_field( dst_ptr
[x
], dst
->red_shift
, dst
->red_len
),
3904 get_field( dst_ptr
[x
], dst
->green_shift
, dst
->green_len
),
3905 get_field( dst_ptr
[x
], dst
->blue_shift
, dst
->blue_len
),
3906 src_ptr
[x
], blend
);
3907 dst_ptr
[x
] = (put_field((val
>> 16), dst
->red_shift
, dst
->red_len
) |
3908 put_field((val
>> 8), dst
->green_shift
, dst
->green_len
) |
3909 put_field( val
, dst
->blue_shift
, dst
->blue_len
));
3914 static void blend_rect_8(const dib_info
*dst
, const RECT
*rc
,
3915 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3917 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
3918 BYTE
*dst_ptr
= get_pixel_ptr_8( dst
, rc
->left
, rc
->top
);
3921 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
3923 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3925 RGBQUAD rgb
= colortable_entry( dst
, dst_ptr
[x
] );
3926 DWORD val
= blend_rgb( rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
, src_ptr
[x
], blend
);
3927 dst_ptr
[x
] = rgb_lookup_colortable( dst
, val
>> 16, val
>> 8, val
);
3932 static void blend_rect_4(const dib_info
*dst
, const RECT
*rc
,
3933 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3935 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
- rc
->left
, origin
->y
);
3936 BYTE
*dst_ptr
= get_pixel_ptr_4( dst
, 0, rc
->top
);
3939 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
3941 for (x
= rc
->left
; x
< rc
->right
; x
++)
3943 DWORD val
= ((x
& 1) ? dst_ptr
[x
/ 2] : (dst_ptr
[x
/ 2] >> 4)) & 0x0f;
3944 RGBQUAD rgb
= colortable_entry( dst
, val
);
3945 val
= blend_rgb( rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
, src_ptr
[x
], blend
);
3946 val
= rgb_lookup_colortable( dst
, val
>> 16, val
>> 8, val
);
3948 dst_ptr
[x
/ 2] = val
| (dst_ptr
[x
/ 2] & 0xf0);
3950 dst_ptr
[x
/ 2] = (val
<< 4) | (dst_ptr
[x
/ 2] & 0x0f);
3955 static void blend_rect_1(const dib_info
*dst
, const RECT
*rc
,
3956 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3958 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
- rc
->left
, origin
->y
);
3959 BYTE
*dst_ptr
= get_pixel_ptr_1( dst
, 0, rc
->top
);
3962 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
3964 for (x
= rc
->left
; x
< rc
->right
; x
++)
3966 DWORD val
= (dst_ptr
[x
/ 8] & pixel_masks_1
[x
% 8]) ? 1 : 0;
3967 RGBQUAD rgb
= dst
->color_table
[val
];
3968 val
= blend_rgb( rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
, src_ptr
[x
], blend
);
3969 val
= rgb_to_pixel_colortable(dst
, val
>> 16, val
>> 8, val
) ? 0xff : 0;
3970 dst_ptr
[x
/ 8] = (dst_ptr
[x
/ 8] & ~pixel_masks_1
[x
% 8]) | (val
& pixel_masks_1
[x
% 8]);
3975 static void blend_rect_null(const dib_info
*dst
, const RECT
*rc
,
3976 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3980 static inline DWORD
gradient_rgb_8888( const TRIVERTEX
*v
, unsigned int pos
, unsigned int len
)
3983 r
= (v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 256;
3984 g
= (v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 256;
3985 b
= (v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 256;
3986 a
= (v
[0].Alpha
* (len
- pos
) + v
[1].Alpha
* pos
) / len
/ 256;
3987 return a
<< 24 | r
<< 16 | g
<< 8 | b
;
3990 static inline DWORD
gradient_rgb_24( const TRIVERTEX
*v
, unsigned int pos
, unsigned int len
)
3993 r
= (v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 256;
3994 g
= (v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 256;
3995 b
= (v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 256;
3996 return r
<< 16 | g
<< 8 | b
;
3999 static void gradient_rect_8888( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4001 DWORD
*ptr
= get_pixel_ptr_32( dib
, rc
->left
, rc
->top
);
4006 case GRADIENT_FILL_RECT_H
:
4007 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4008 ptr
[x
] = gradient_rgb_8888( v
, x
+ rc
->left
- v
[0].x
, v
[1].x
- v
[0].x
);
4010 for (y
= rc
->top
+ 1; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4011 memcpy( ptr
+ dib
->stride
/ 4, ptr
, (rc
->right
- rc
->left
) * 4 );
4014 case GRADIENT_FILL_RECT_V
:
4015 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
4017 DWORD val
= gradient_rgb_8888( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
4018 for (x
= 0; x
< rc
->right
- rc
->left
; x
++) ptr
[x
] = val
;
4019 ptr
+= dib
->stride
/ 4;
4025 static void gradient_rect_32( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4027 DWORD
*ptr
= get_pixel_ptr_32( dib
, rc
->left
, rc
->top
);
4032 case GRADIENT_FILL_RECT_H
:
4033 if (dib
->red_len
== 8 && dib
->green_len
== 8 && dib
->blue_len
== 8)
4035 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4037 DWORD val
= gradient_rgb_24( v
, x
+ rc
->left
- v
[0].x
, v
[1].x
- v
[0].x
);
4038 ptr
[x
] = ((( val
& 0xff) << dib
->blue_shift
) |
4039 (((val
>> 8) & 0xff) << dib
->green_shift
) |
4040 (((val
>> 16) & 0xff) << dib
->red_shift
));
4045 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4047 DWORD val
= gradient_rgb_24( v
, x
+ rc
->left
- v
[0].x
, v
[1].x
- v
[0].x
);
4048 ptr
[x
] = (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
4049 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
4050 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
4054 for (y
= rc
->top
+ 1; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4055 memcpy( ptr
+ dib
->stride
/ 4, ptr
, (rc
->right
- rc
->left
) * 4 );
4058 case GRADIENT_FILL_RECT_V
:
4059 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
4061 DWORD val
= gradient_rgb_24( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
4062 if (dib
->red_len
== 8 && dib
->green_len
== 8 && dib
->blue_len
== 8)
4063 val
= ((( val
& 0xff) << dib
->blue_shift
) |
4064 (((val
>> 8) & 0xff) << dib
->green_shift
) |
4065 (((val
>> 16) & 0xff) << dib
->red_shift
));
4067 val
= (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
4068 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
4069 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
4071 for (x
= 0; x
< rc
->right
- rc
->left
; x
++) ptr
[x
] = val
;
4072 ptr
+= dib
->stride
/ 4;
4078 static void gradient_rect_24( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4080 BYTE
*ptr
= get_pixel_ptr_24( dib
, rc
->left
, rc
->top
);
4085 case GRADIENT_FILL_RECT_H
:
4086 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4088 DWORD val
= gradient_rgb_24( v
, x
+ rc
->left
- v
[0].x
, v
[1].x
- v
[0].x
);
4090 ptr
[x
* 3 + 1] = val
>> 8;
4091 ptr
[x
* 3 + 2] = val
>> 16;
4094 for (y
= rc
->top
+ 1; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4095 memcpy( ptr
+ dib
->stride
, ptr
, (rc
->right
- rc
->left
) * 3 );
4098 case GRADIENT_FILL_RECT_V
:
4099 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
4101 DWORD val
= gradient_rgb_24( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
4102 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4105 ptr
[x
* 3 + 1] = val
>> 8;
4106 ptr
[x
* 3 + 2] = val
>> 16;
4114 static void gradient_rect_555( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4116 WORD
*ptr
= get_pixel_ptr_16( dib
, rc
->left
, rc
->top
);
4121 case GRADIENT_FILL_RECT_H
:
4122 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4124 DWORD val
= gradient_rgb_24( v
, x
+ rc
->left
- v
[0].x
, v
[1].x
- v
[0].x
);
4125 ptr
[x
] = ((val
>> 9) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 3) & 0x001f);
4128 for (y
= rc
->top
+ 1; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
4129 memcpy( ptr
+ dib
->stride
/ 2, ptr
, (rc
->right
- rc
->left
) * 2 );
4132 case GRADIENT_FILL_RECT_V
:
4133 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
4135 DWORD val
= gradient_rgb_24( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
4136 val
= ((val
>> 9) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 3) & 0x001f);
4137 for (x
= 0; x
< rc
->right
- rc
->left
; x
++) ptr
[x
] = val
;
4138 ptr
+= dib
->stride
/ 2;
4144 static void gradient_rect_16( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4146 WORD
*ptr
= get_pixel_ptr_16( dib
, rc
->left
, rc
->top
);
4151 case GRADIENT_FILL_RECT_H
:
4152 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4154 DWORD val
= gradient_rgb_24( v
, x
+ rc
->left
- v
[0].x
, v
[1].x
- v
[0].x
);
4155 ptr
[x
] = (put_field((val
>> 16), dib
->red_shift
, dib
->red_len
) |
4156 put_field((val
>> 8), dib
->green_shift
, dib
->green_len
) |
4157 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
4160 for (y
= rc
->top
+ 1; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
4161 memcpy( ptr
+ dib
->stride
/ 2, ptr
, (rc
->right
- rc
->left
) * 2 );
4164 case GRADIENT_FILL_RECT_V
:
4165 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
4167 DWORD val
= gradient_rgb_24( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
4168 val
= (put_field((val
>> 16), dib
->red_shift
, dib
->red_len
) |
4169 put_field((val
>> 8), dib
->green_shift
, dib
->green_len
) |
4170 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
4171 for (x
= 0; x
< rc
->right
- rc
->left
; x
++) ptr
[x
] = val
;
4172 ptr
+= dib
->stride
/ 2;
4178 static void gradient_rect_8( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4180 BYTE
*ptr
= get_pixel_ptr_8( dib
, rc
->left
, rc
->top
);
4185 case GRADIENT_FILL_RECT_H
:
4186 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4188 DWORD val
= gradient_rgb_24( v
, x
+ rc
->left
- v
[0].x
, v
[1].x
- v
[0].x
);
4189 ptr
[x
] = rgb_lookup_colortable( dib
, val
>> 16, val
>> 8, val
);
4192 for (y
= rc
->top
+ 1; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4193 memcpy( ptr
+ dib
->stride
, ptr
, rc
->right
- rc
->left
);
4196 case GRADIENT_FILL_RECT_V
:
4197 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
4199 DWORD val
= gradient_rgb_24( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
4200 val
= rgb_lookup_colortable( dib
, val
>> 16, val
>> 8, val
);
4201 for (x
= 0; x
< rc
->right
- rc
->left
; x
++) ptr
[x
] = val
;
4208 static void gradient_rect_4( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4210 BYTE
*ptr
= get_pixel_ptr_4( dib
, 0, rc
->top
);
4215 case GRADIENT_FILL_RECT_H
:
4216 for (x
= rc
->left
; x
< rc
->right
; x
++)
4218 DWORD val
= gradient_rgb_24( v
, x
- v
[0].x
, v
[1].x
- v
[0].x
);
4219 val
= rgb_lookup_colortable( dib
, val
>> 16, val
>> 8, val
);
4221 ptr
[x
/ 2] = val
| (ptr
[x
/ 2] & 0xf0);
4223 ptr
[x
/ 2] = (val
<< 4) | (ptr
[x
/ 2] & 0x0f);
4226 for (y
= rc
->top
+ 1; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4231 ptr
[dib
->stride
+ x
/ 2] = (ptr
[x
/ 2] & 0x0f) | (ptr
[dib
->stride
+ x
/ 2] & 0xf0);
4234 for (; x
< rc
->right
- 1; x
+= 2) ptr
[dib
->stride
+ x
/ 2] = ptr
[x
/ 2];
4236 ptr
[dib
->stride
+ x
/ 2] = (ptr
[dib
->stride
+ x
/ 2] & 0x0f) | (ptr
[x
/ 2] & 0xf0);
4240 case GRADIENT_FILL_RECT_V
:
4241 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
4243 DWORD val
= gradient_rgb_24( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
4244 val
= rgb_lookup_colortable( dib
, val
>> 16, val
>> 8, val
);
4248 ptr
[x
/ 2] = val
| (ptr
[x
/ 2] & 0xf0);
4251 for (; x
< rc
->right
- 1; x
+= 2) ptr
[x
/ 2] = (val
<< 4) | val
;
4252 if (x
< rc
->right
) ptr
[x
/ 2] = (ptr
[x
/ 2] & 0x0f) | (val
<< 4);
4259 static void gradient_rect_1( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4261 BYTE
*ptr
= get_pixel_ptr_1( dib
, 0, rc
->top
);
4266 case GRADIENT_FILL_RECT_H
:
4267 for (x
= rc
->left
; x
< rc
->right
; x
++)
4269 DWORD val
= gradient_rgb_24( v
, x
- v
[0].x
, v
[1].x
- v
[0].x
);
4270 val
= rgb_to_pixel_colortable( dib
, val
>> 16, val
>> 8, val
) ? 0xff : 0;
4271 ptr
[x
/ 8] = (ptr
[x
/ 8] & ~pixel_masks_1
[x
% 8]) | (val
& pixel_masks_1
[x
% 8]);
4274 for (y
= rc
->top
+ 1; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4275 for (x
= rc
->left
; x
< rc
->right
; x
++)
4276 ptr
[dib
->stride
+ x
/ 8] = (ptr
[dib
->stride
+ x
/ 8] & ~pixel_masks_1
[x
% 8]) |
4277 (ptr
[x
/ 8] & pixel_masks_1
[x
% 8]);
4280 case GRADIENT_FILL_RECT_V
:
4281 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
4283 DWORD val
= gradient_rgb_24( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
4284 val
= rgb_to_pixel_colortable( dib
, val
>> 16, val
>> 8, val
) ? 0xff : 0;
4285 for (x
= rc
->left
; x
< rc
->right
; x
++)
4286 ptr
[x
/ 8] = (ptr
[x
/ 8] & ~pixel_masks_1
[x
% 8]) | (val
& pixel_masks_1
[x
% 8]);
4293 static void gradient_rect_null( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4297 static inline BYTE
aa_color( BYTE dst
, BYTE text
, BYTE min_comp
, BYTE max_comp
)
4299 if (dst
== text
) return dst
;
4303 DWORD diff
= dst
- text
;
4304 DWORD range
= max_comp
- text
;
4305 dst
= text
+ (diff
* range
) / (0xff - text
);
4310 DWORD diff
= text
- dst
;
4311 DWORD range
= text
- min_comp
;
4312 dst
= text
- (diff
* range
) / text
;
4317 static inline DWORD
aa_rgb( BYTE r_dst
, BYTE g_dst
, BYTE b_dst
, DWORD text
, const struct intensity_range
*range
)
4319 return (aa_color( b_dst
, text
, range
->b_min
, range
->b_max
) |
4320 aa_color( g_dst
, text
>> 8, range
->g_min
, range
->g_max
) << 8 |
4321 aa_color( r_dst
, text
>> 16, range
->r_min
, range
->r_max
) << 16);
4324 static void draw_glyph_8888( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4325 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4327 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
4328 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
4331 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4333 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
4335 if (glyph_ptr
[x
] <= 1) continue;
4336 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
4337 dst_ptr
[x
] = aa_rgb( dst_ptr
[x
] >> 16, dst_ptr
[x
] >> 8, dst_ptr
[x
], text_pixel
, ranges
+ glyph_ptr
[x
] );
4339 dst_ptr
+= dib
->stride
/ 4;
4340 glyph_ptr
+= glyph
->stride
;
4344 static void draw_glyph_32( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4345 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4347 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
4348 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
4352 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
4353 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
4354 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
4356 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4358 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
4360 if (glyph_ptr
[x
] <= 1) continue;
4361 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
4362 val
= aa_rgb( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
4363 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
4364 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
4365 text
, ranges
+ glyph_ptr
[x
] );
4366 dst_ptr
[x
] = (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
4367 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
4368 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
4370 dst_ptr
+= dib
->stride
/ 4;
4371 glyph_ptr
+= glyph
->stride
;
4375 static void draw_glyph_24( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4376 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4378 BYTE
*dst_ptr
= get_pixel_ptr_24( dib
, rect
->left
, rect
->top
);
4379 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
4383 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4385 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
4387 if (glyph_ptr
[x
] <= 1) continue;
4388 if (glyph_ptr
[x
] >= 16)
4391 val
= aa_rgb( dst_ptr
[x
* 3 + 2], dst_ptr
[x
* 3 + 1], dst_ptr
[x
* 3],
4392 text_pixel
, ranges
+ glyph_ptr
[x
] );
4393 dst_ptr
[x
* 3] = val
;
4394 dst_ptr
[x
* 3 + 1] = val
>> 8;
4395 dst_ptr
[x
* 3 + 2] = val
>> 16;
4397 dst_ptr
+= dib
->stride
;
4398 glyph_ptr
+= glyph
->stride
;
4402 static void draw_glyph_555( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4403 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4405 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
4406 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
4410 text
= ((text_pixel
<< 9) & 0xf80000) | ((text_pixel
<< 4) & 0x070000) |
4411 ((text_pixel
<< 6) & 0x00f800) | ((text_pixel
<< 1) & 0x000700) |
4412 ((text_pixel
<< 3) & 0x0000f8) | ((text_pixel
>> 2) & 0x000007);
4414 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4416 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
4418 if (glyph_ptr
[x
] <= 1) continue;
4419 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
4420 val
= aa_rgb( ((dst_ptr
[x
] >> 7) & 0xf8) | ((dst_ptr
[x
] >> 12) & 0x07),
4421 ((dst_ptr
[x
] >> 2) & 0xf8) | ((dst_ptr
[x
] >> 7) & 0x07),
4422 ((dst_ptr
[x
] << 3) & 0xf8) | ((dst_ptr
[x
] >> 2) & 0x07),
4423 text
, ranges
+ glyph_ptr
[x
] );
4424 dst_ptr
[x
] = ((val
>> 9) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 3) & 0x001f);
4426 dst_ptr
+= dib
->stride
/ 2;
4427 glyph_ptr
+= glyph
->stride
;
4431 static void draw_glyph_16( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4432 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4434 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
4435 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
4439 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
4440 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
4441 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
4443 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4445 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
4447 if (glyph_ptr
[x
] <= 1) continue;
4448 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
4449 val
= aa_rgb( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
4450 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
4451 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
4452 text
, ranges
+ glyph_ptr
[x
] );
4453 dst_ptr
[x
] = (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
4454 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
4455 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
4457 dst_ptr
+= dib
->stride
/ 2;
4458 glyph_ptr
+= glyph
->stride
;
4462 static void draw_glyph_8( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4463 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4465 BYTE
*dst_ptr
= get_pixel_ptr_8( dib
, rect
->left
, rect
->top
);
4466 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
4469 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4471 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
4473 /* no antialiasing, glyph should only contain 0 or 16. */
4474 if (glyph_ptr
[x
] >= 16)
4475 dst_ptr
[x
] = text_pixel
;
4477 dst_ptr
+= dib
->stride
;
4478 glyph_ptr
+= glyph
->stride
;
4482 static void draw_glyph_4( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4483 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4485 BYTE
*dst_ptr
= get_pixel_ptr_4( dib
, 0, rect
->top
);
4486 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
- rect
->left
, origin
->y
);
4489 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4491 for (x
= rect
->left
; x
< rect
->right
; x
++)
4493 /* no antialiasing, glyph should only contain 0 or 16. */
4494 if (glyph_ptr
[x
] >= 16)
4497 dst_ptr
[x
/ 2] = text_pixel
| (dst_ptr
[x
/ 2] & 0xf0);
4499 dst_ptr
[x
/ 2] = (text_pixel
<< 4) | (dst_ptr
[x
/ 2] & 0x0f);
4502 dst_ptr
+= dib
->stride
;
4503 glyph_ptr
+= glyph
->stride
;
4507 static void draw_glyph_1( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4508 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4510 BYTE
*dst_ptr
= get_pixel_ptr_1( dib
, 0, rect
->top
);
4511 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
- rect
->left
, origin
->y
);
4513 BYTE text
= (text_pixel
& 1) ? 0xff : 0;
4515 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4517 for (x
= rect
->left
; x
< rect
->right
; x
++)
4519 /* no antialiasing, glyph should only contain 0 or 16. */
4520 if (glyph_ptr
[x
] >= 16)
4521 dst_ptr
[x
/ 8] = (dst_ptr
[x
/ 8] & ~pixel_masks_1
[x
% 8]) | (text
& pixel_masks_1
[x
% 8]);
4523 dst_ptr
+= dib
->stride
;
4524 glyph_ptr
+= glyph
->stride
;
4528 static void draw_glyph_null( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4529 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4534 static BOOL
create_rop_masks_32(const dib_info
*dib
, const dib_info
*hatch
, const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
4536 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
4537 DWORD mask_start
= 0, mask_offset
;
4538 DWORD
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
4541 for(y
= 0; y
< hatch
->height
; y
++)
4543 hatch_ptr
= hatch_start
;
4544 mask_offset
= mask_start
;
4545 for(x
= 0; x
< hatch
->width
; x
++)
4547 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
4549 and_bits
[mask_offset
] = fg
->and;
4550 xor_bits
[mask_offset
] = fg
->xor;
4554 and_bits
[mask_offset
] = bg
->and;
4555 xor_bits
[mask_offset
] = bg
->xor;
4557 if(x
% 8 == 7) hatch_ptr
++;
4560 hatch_start
+= hatch
->stride
;
4561 mask_start
+= dib
->stride
/ 4;
4567 static BOOL
create_rop_masks_24(const dib_info
*dib
, const dib_info
*hatch
, const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
4569 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
4570 DWORD mask_start
= 0, mask_offset
;
4571 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
4574 for(y
= 0; y
< hatch
->height
; y
++)
4576 hatch_ptr
= hatch_start
;
4577 mask_offset
= mask_start
;
4578 for(x
= 0; x
< hatch
->width
; x
++)
4580 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
4582 and_bits
[mask_offset
] = fg
->and & 0xff;
4583 xor_bits
[mask_offset
++] = fg
->xor & 0xff;
4584 and_bits
[mask_offset
] = (fg
->and >> 8) & 0xff;
4585 xor_bits
[mask_offset
++] = (fg
->xor >> 8) & 0xff;
4586 and_bits
[mask_offset
] = (fg
->and >> 16) & 0xff;
4587 xor_bits
[mask_offset
++] = (fg
->xor >> 16) & 0xff;
4591 and_bits
[mask_offset
] = bg
->and & 0xff;
4592 xor_bits
[mask_offset
++] = bg
->xor & 0xff;
4593 and_bits
[mask_offset
] = (bg
->and >> 8) & 0xff;
4594 xor_bits
[mask_offset
++] = (bg
->xor >> 8) & 0xff;
4595 and_bits
[mask_offset
] = (bg
->and >> 16) & 0xff;
4596 xor_bits
[mask_offset
++] = (bg
->xor >> 16) & 0xff;
4598 if(x
% 8 == 7) hatch_ptr
++;
4600 hatch_start
+= hatch
->stride
;
4601 mask_start
+= dib
->stride
;
4607 static BOOL
create_rop_masks_16(const dib_info
*dib
, const dib_info
*hatch
, const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
4609 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
4610 DWORD mask_start
= 0, mask_offset
;
4611 WORD
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
4614 for(y
= 0; y
< hatch
->height
; y
++)
4616 hatch_ptr
= hatch_start
;
4617 mask_offset
= mask_start
;
4618 for(x
= 0; x
< hatch
->width
; x
++)
4620 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
4622 and_bits
[mask_offset
] = fg
->and;
4623 xor_bits
[mask_offset
] = fg
->xor;
4627 and_bits
[mask_offset
] = bg
->and;
4628 xor_bits
[mask_offset
] = bg
->xor;
4630 if(x
% 8 == 7) hatch_ptr
++;
4633 hatch_start
+= hatch
->stride
;
4634 mask_start
+= dib
->stride
/ 2;
4640 static BOOL
create_rop_masks_8(const dib_info
*dib
, const dib_info
*hatch
, const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
4642 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
4643 DWORD mask_start
= 0, mask_offset
;
4644 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
4647 for(y
= 0; y
< hatch
->height
; y
++)
4649 hatch_ptr
= hatch_start
;
4650 mask_offset
= mask_start
;
4651 for(x
= 0; x
< hatch
->width
; x
++)
4653 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
4655 and_bits
[mask_offset
] = fg
->and;
4656 xor_bits
[mask_offset
] = fg
->xor;
4660 and_bits
[mask_offset
] = bg
->and;
4661 xor_bits
[mask_offset
] = bg
->xor;
4663 if(x
% 8 == 7) hatch_ptr
++;
4666 hatch_start
+= hatch
->stride
;
4667 mask_start
+= dib
->stride
;
4673 static BOOL
create_rop_masks_4(const dib_info
*dib
, const dib_info
*hatch
, const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
4675 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
4676 DWORD mask_start
= 0, mask_offset
;
4677 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
4678 const rop_mask
*rop_mask
;
4681 for(y
= 0; y
< hatch
->height
; y
++)
4683 hatch_ptr
= hatch_start
;
4684 mask_offset
= mask_start
;
4685 for(x
= 0; x
< hatch
->width
; x
++)
4687 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
4694 and_bits
[mask_offset
] = (rop_mask
->and & 0x0f) | (and_bits
[mask_offset
] & 0xf0);
4695 xor_bits
[mask_offset
] = (rop_mask
->xor & 0x0f) | (xor_bits
[mask_offset
] & 0xf0);
4700 and_bits
[mask_offset
] = (rop_mask
->and << 4) & 0xf0;
4701 xor_bits
[mask_offset
] = (rop_mask
->xor << 4) & 0xf0;
4704 if(x
% 8 == 7) hatch_ptr
++;
4706 hatch_start
+= hatch
->stride
;
4707 mask_start
+= dib
->stride
;
4713 static BOOL
create_rop_masks_1(const dib_info
*dib
, const dib_info
*hatch
, const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
4715 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
4716 DWORD mask_start
= 0, mask_offset
;
4717 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
4721 for(y
= 0; y
< hatch
->height
; y
++)
4723 hatch_ptr
= hatch_start
;
4724 mask_offset
= mask_start
;
4725 for(x
= 0, bit_pos
= 0; x
< hatch
->width
; x
++)
4727 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
4729 rop_mask
.and = (fg
->and & 1) ? 0xff : 0;
4730 rop_mask
.xor = (fg
->xor & 1) ? 0xff : 0;
4734 rop_mask
.and = (bg
->and & 1) ? 0xff : 0;
4735 rop_mask
.xor = (bg
->xor & 1) ? 0xff : 0;
4738 if(bit_pos
== 0) and_bits
[mask_offset
] = xor_bits
[mask_offset
] = 0;
4740 and_bits
[mask_offset
] = (rop_mask
.and & pixel_masks_1
[bit_pos
]) | (and_bits
[mask_offset
] & ~pixel_masks_1
[bit_pos
]);
4741 xor_bits
[mask_offset
] = (rop_mask
.xor & pixel_masks_1
[bit_pos
]) | (xor_bits
[mask_offset
] & ~pixel_masks_1
[bit_pos
]);
4750 hatch_start
+= hatch
->stride
;
4751 mask_start
+= dib
->stride
;
4757 static BOOL
create_rop_masks_null(const dib_info
*dib
, const dib_info
*hatch
, const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
4762 static inline void rop_codes_from_stretch_mode( int mode
, struct rop_codes
*codes
)
4767 case STRETCH_DELETESCANS
:
4768 get_rop_codes( R2_COPYPEN
, codes
);
4770 case STRETCH_ORSCANS
:
4771 get_rop_codes( R2_MERGEPEN
, codes
);
4773 case STRETCH_ANDSCANS
:
4774 get_rop_codes( R2_MASKPEN
, codes
);
4780 static void stretch_row_32(const dib_info
*dst_dib
, const POINT
*dst_start
,
4781 const dib_info
*src_dib
, const POINT
*src_start
,
4782 const struct stretch_params
*params
, int mode
,
4785 DWORD
*dst_ptr
= get_pixel_ptr_32( dst_dib
, dst_start
->x
, dst_start
->y
);
4786 DWORD
*src_ptr
= get_pixel_ptr_32( src_dib
, src_start
->x
, src_start
->y
);
4787 int err
= params
->err_start
;
4789 struct rop_codes codes
;
4791 rop_codes_from_stretch_mode( mode
, &codes
);
4792 for (width
= params
->length
; width
; width
--)
4794 do_rop_codes_32( dst_ptr
, *src_ptr
, &codes
);
4795 dst_ptr
+= params
->dst_inc
;
4798 src_ptr
+= params
->src_inc
;
4799 err
+= params
->err_add_1
;
4801 else err
+= params
->err_add_2
;
4805 static void stretch_row_24(const dib_info
*dst_dib
, const POINT
*dst_start
,
4806 const dib_info
*src_dib
, const POINT
*src_start
,
4807 const struct stretch_params
*params
, int mode
,
4810 BYTE
*dst_ptr
= get_pixel_ptr_24( dst_dib
, dst_start
->x
, dst_start
->y
);
4811 BYTE
*src_ptr
= get_pixel_ptr_24( src_dib
, src_start
->x
, src_start
->y
);
4812 int err
= params
->err_start
;
4814 struct rop_codes codes
;
4816 rop_codes_from_stretch_mode( mode
, &codes
);
4817 for (width
= params
->length
; width
; width
--)
4819 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
4820 do_rop_codes_8( dst_ptr
+ 1, *(src_ptr
+ 1), &codes
);
4821 do_rop_codes_8( dst_ptr
+ 2, *(src_ptr
+ 2), &codes
);
4822 dst_ptr
+= 3 * params
->dst_inc
;
4825 src_ptr
+= 3 * params
->src_inc
;
4826 err
+= params
->err_add_1
;
4828 else err
+= params
->err_add_2
;
4832 static void stretch_row_16(const dib_info
*dst_dib
, const POINT
*dst_start
,
4833 const dib_info
*src_dib
, const POINT
*src_start
,
4834 const struct stretch_params
*params
, int mode
,
4837 WORD
*dst_ptr
= get_pixel_ptr_16( dst_dib
, dst_start
->x
, dst_start
->y
);
4838 WORD
*src_ptr
= get_pixel_ptr_16( src_dib
, src_start
->x
, src_start
->y
);
4839 int err
= params
->err_start
;
4841 struct rop_codes codes
;
4843 rop_codes_from_stretch_mode( mode
, &codes
);
4844 for (width
= params
->length
; width
; width
--)
4846 do_rop_codes_16( dst_ptr
, *src_ptr
, &codes
);
4847 dst_ptr
+= params
->dst_inc
;
4850 src_ptr
+= params
->src_inc
;
4851 err
+= params
->err_add_1
;
4853 else err
+= params
->err_add_2
;
4857 static void stretch_row_8(const dib_info
*dst_dib
, const POINT
*dst_start
,
4858 const dib_info
*src_dib
, const POINT
*src_start
,
4859 const struct stretch_params
*params
, int mode
,
4862 BYTE
*dst_ptr
= get_pixel_ptr_8( dst_dib
, dst_start
->x
, dst_start
->y
);
4863 BYTE
*src_ptr
= get_pixel_ptr_8( src_dib
, src_start
->x
, src_start
->y
);
4864 int err
= params
->err_start
;
4866 struct rop_codes codes
;
4868 rop_codes_from_stretch_mode( mode
, &codes
);
4869 for (width
= params
->length
; width
; width
--)
4871 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
4872 dst_ptr
+= params
->dst_inc
;
4875 src_ptr
+= params
->src_inc
;
4876 err
+= params
->err_add_1
;
4878 else err
+= params
->err_add_2
;
4882 static void stretch_row_4(const dib_info
*dst_dib
, const POINT
*dst_start
,
4883 const dib_info
*src_dib
, const POINT
*src_start
,
4884 const struct stretch_params
*params
, int mode
,
4887 BYTE
*dst_ptr
= get_pixel_ptr_4( dst_dib
, dst_start
->x
, dst_start
->y
);
4888 BYTE
*src_ptr
= get_pixel_ptr_4( src_dib
, src_start
->x
, src_start
->y
);
4889 int err
= params
->err_start
;
4890 int width
, dst_x
= dst_start
->x
, src_x
= src_start
->x
;
4891 struct rop_codes codes
;
4894 rop_codes_from_stretch_mode( mode
, &codes
);
4895 for (width
= params
->length
; width
; width
--)
4897 if (src_x
& 1) src_val
= (*src_ptr
& 0x0f) | (*src_ptr
<< 4);
4898 else src_val
= (*src_ptr
& 0xf0) | (*src_ptr
>> 4);
4900 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, (dst_x
& 1) ? 0x0f : 0xf0 );
4902 if ((dst_x
& ~1) != ((dst_x
+ params
->dst_inc
) & ~1))
4903 dst_ptr
+= params
->dst_inc
;
4904 dst_x
+= params
->dst_inc
;
4908 if ((src_x
& ~1) != ((src_x
+ params
->src_inc
) & ~1))
4909 src_ptr
+= params
->src_inc
;
4910 src_x
+= params
->src_inc
;
4911 err
+= params
->err_add_1
;
4913 else err
+= params
->err_add_2
;
4917 static void stretch_row_1(const dib_info
*dst_dib
, const POINT
*dst_start
,
4918 const dib_info
*src_dib
, const POINT
*src_start
,
4919 const struct stretch_params
*params
, int mode
,
4922 BYTE
*dst_ptr
= get_pixel_ptr_1( dst_dib
, dst_start
->x
, dst_start
->y
);
4923 BYTE
*src_ptr
= get_pixel_ptr_1( src_dib
, src_start
->x
, src_start
->y
);
4924 int err
= params
->err_start
;
4925 int width
, dst_x
= dst_start
->x
, src_x
= src_start
->x
;
4926 struct rop_codes codes
;
4929 rop_codes_from_stretch_mode( mode
, &codes
);
4930 for (width
= params
->length
; width
; width
--)
4932 src_val
= *src_ptr
& pixel_masks_1
[src_x
% 8] ? 0xff : 0;
4933 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, pixel_masks_1
[dst_x
% 8] );
4935 if ((dst_x
& ~7) != ((dst_x
+ params
->dst_inc
) & ~7))
4936 dst_ptr
+= params
->dst_inc
;
4937 dst_x
+= params
->dst_inc
;
4941 if ((src_x
& ~7) != ((src_x
+ params
->src_inc
) & ~7))
4942 src_ptr
+= params
->src_inc
;
4943 src_x
+= params
->src_inc
;
4944 err
+= params
->err_add_1
;
4946 else err
+= params
->err_add_2
;
4950 static void stretch_row_null(const dib_info
*dst_dib
, const POINT
*dst_start
,
4951 const dib_info
*src_dib
, const POINT
*src_start
,
4952 const struct stretch_params
*params
, int mode
,
4955 FIXME("bit count %d\n", dst_dib
->bit_count
);
4959 static void shrink_row_32(const dib_info
*dst_dib
, const POINT
*dst_start
,
4960 const dib_info
*src_dib
, const POINT
*src_start
,
4961 const struct stretch_params
*params
, int mode
,
4964 DWORD
*dst_ptr
= get_pixel_ptr_32( dst_dib
, dst_start
->x
, dst_start
->y
);
4965 DWORD
*src_ptr
= get_pixel_ptr_32( src_dib
, src_start
->x
, src_start
->y
);
4966 int err
= params
->err_start
;
4968 struct rop_codes codes
;
4969 DWORD init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
4970 BOOL new_pix
= TRUE
;
4972 rop_codes_from_stretch_mode( mode
, &codes
);
4973 for (width
= params
->length
; width
; width
--)
4975 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
4976 do_rop_codes_32( dst_ptr
, *src_ptr
, &codes
);
4978 src_ptr
+= params
->src_inc
;
4981 dst_ptr
+= params
->dst_inc
;
4983 err
+= params
->err_add_1
;
4985 else err
+= params
->err_add_2
;
4989 static void shrink_row_24(const dib_info
*dst_dib
, const POINT
*dst_start
,
4990 const dib_info
*src_dib
, const POINT
*src_start
,
4991 const struct stretch_params
*params
, int mode
,
4994 BYTE
*dst_ptr
= get_pixel_ptr_24( dst_dib
, dst_start
->x
, dst_start
->y
);
4995 BYTE
*src_ptr
= get_pixel_ptr_24( src_dib
, src_start
->x
, src_start
->y
);
4996 int err
= params
->err_start
;
4998 struct rop_codes codes
;
4999 BYTE init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
5000 BOOL new_pix
= TRUE
;
5002 rop_codes_from_stretch_mode( mode
, &codes
);
5003 for (width
= params
->length
; width
; width
--)
5005 if (new_pix
&& !keep_dst
) memset( dst_ptr
, init_val
, 3 );
5006 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
5007 do_rop_codes_8( dst_ptr
+ 1, *(src_ptr
+ 1), &codes
);
5008 do_rop_codes_8( dst_ptr
+ 2, *(src_ptr
+ 2), &codes
);
5010 src_ptr
+= 3 * params
->src_inc
;
5013 dst_ptr
+= 3 * params
->dst_inc
;
5015 err
+= params
->err_add_1
;
5017 else err
+= params
->err_add_2
;
5021 static void shrink_row_16(const dib_info
*dst_dib
, const POINT
*dst_start
,
5022 const dib_info
*src_dib
, const POINT
*src_start
,
5023 const struct stretch_params
*params
, int mode
,
5026 WORD
*dst_ptr
= get_pixel_ptr_16( dst_dib
, dst_start
->x
, dst_start
->y
);
5027 WORD
*src_ptr
= get_pixel_ptr_16( src_dib
, src_start
->x
, src_start
->y
);
5028 int err
= params
->err_start
;
5030 struct rop_codes codes
;
5031 WORD init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
5032 BOOL new_pix
= TRUE
;
5034 rop_codes_from_stretch_mode( mode
, &codes
);
5035 for (width
= params
->length
; width
; width
--)
5037 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
5038 do_rop_codes_16( dst_ptr
, *src_ptr
, &codes
);
5040 src_ptr
+= params
->src_inc
;
5043 dst_ptr
+= params
->dst_inc
;
5045 err
+= params
->err_add_1
;
5047 else err
+= params
->err_add_2
;
5051 static void shrink_row_8(const dib_info
*dst_dib
, const POINT
*dst_start
,
5052 const dib_info
*src_dib
, const POINT
*src_start
,
5053 const struct stretch_params
*params
, int mode
,
5056 BYTE
*dst_ptr
= get_pixel_ptr_8( dst_dib
, dst_start
->x
, dst_start
->y
);
5057 BYTE
*src_ptr
= get_pixel_ptr_8( src_dib
, src_start
->x
, src_start
->y
);
5058 int err
= params
->err_start
;
5060 struct rop_codes codes
;
5061 BYTE init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
5062 BOOL new_pix
= TRUE
;
5064 rop_codes_from_stretch_mode( mode
, &codes
);
5065 for (width
= params
->length
; width
; width
--)
5067 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
5068 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
5070 src_ptr
+= params
->src_inc
;
5073 dst_ptr
+= params
->dst_inc
;
5075 err
+= params
->err_add_1
;
5077 else err
+= params
->err_add_2
;
5081 static void shrink_row_4(const dib_info
*dst_dib
, const POINT
*dst_start
,
5082 const dib_info
*src_dib
, const POINT
*src_start
,
5083 const struct stretch_params
*params
, int mode
,
5086 BYTE
*dst_ptr
= get_pixel_ptr_8( dst_dib
, dst_start
->x
, dst_start
->y
);
5087 BYTE
*src_ptr
= get_pixel_ptr_8( src_dib
, src_start
->x
, src_start
->y
);
5088 int err
= params
->err_start
;
5089 int width
, dst_x
= dst_start
->x
, src_x
= src_start
->x
;
5090 struct rop_codes codes
;
5091 BYTE src_val
, init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
5092 BOOL new_pix
= TRUE
;
5094 rop_codes_from_stretch_mode( mode
, &codes
);
5095 for (width
= params
->length
; width
; width
--)
5097 if (new_pix
&& !keep_dst
) do_rop_mask_8( dst_ptr
, 0, init_val
, (dst_x
& 1) ? 0xf0 : 0x0f );
5099 if (src_x
& 1) src_val
= (*src_ptr
& 0x0f) | (*src_ptr
<< 4);
5100 else src_val
= (*src_ptr
& 0xf0) | (*src_ptr
>> 4);
5102 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, (dst_x
& 1) ? 0xf0 : 0x0f );
5105 if ((src_x
& ~1) != ((src_x
+ params
->src_inc
) & ~1))
5106 src_ptr
+= params
->src_inc
;
5107 src_x
+= params
->src_inc
;
5111 if ((dst_x
& ~1) != ((dst_x
+ params
->dst_inc
) & ~1))
5112 dst_ptr
+= params
->dst_inc
;
5113 dst_x
+= params
->dst_inc
;
5115 err
+= params
->err_add_1
;
5117 else err
+= params
->err_add_2
;
5121 static void shrink_row_1(const dib_info
*dst_dib
, const POINT
*dst_start
,
5122 const dib_info
*src_dib
, const POINT
*src_start
,
5123 const struct stretch_params
*params
, int mode
,
5126 BYTE
*dst_ptr
= get_pixel_ptr_1( dst_dib
, dst_start
->x
, dst_start
->y
);
5127 BYTE
*src_ptr
= get_pixel_ptr_1( src_dib
, src_start
->x
, src_start
->y
);
5128 int err
= params
->err_start
;
5129 int width
, dst_x
= dst_start
->x
, src_x
= src_start
->x
;
5130 struct rop_codes codes
;
5131 BYTE src_val
, init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
5132 BOOL new_pix
= TRUE
;
5134 rop_codes_from_stretch_mode( mode
, &codes
);
5135 for (width
= params
->length
; width
; width
--)
5137 if (new_pix
&& !keep_dst
) do_rop_mask_8( dst_ptr
, 0, init_val
, pixel_masks_1
[dst_x
% 8] );
5138 src_val
= *src_ptr
& pixel_masks_1
[src_x
% 8] ? 0xff : 0;
5139 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, pixel_masks_1
[dst_x
% 8] );
5142 if ((src_x
& ~7) != ((src_x
+ params
->src_inc
) & ~7))
5143 src_ptr
+= params
->src_inc
;
5144 src_x
+= params
->src_inc
;
5148 if ((dst_x
& ~7) != ((dst_x
+ params
->dst_inc
) & ~7))
5149 dst_ptr
+= params
->dst_inc
;
5150 dst_x
+= params
->dst_inc
;
5152 err
+= params
->err_add_1
;
5154 else err
+= params
->err_add_2
;
5158 static void shrink_row_null(const dib_info
*dst_dib
, const POINT
*dst_start
,
5159 const dib_info
*src_dib
, const POINT
*src_start
,
5160 const struct stretch_params
*params
, int mode
,
5163 FIXME("bit count %d\n", dst_dib
->bit_count
);
5167 const primitive_funcs funcs_8888
=
5177 colorref_to_pixel_888
,
5178 pixel_to_colorref_888
,
5180 create_rop_masks_32
,
5185 const primitive_funcs funcs_32
=
5195 colorref_to_pixel_masks
,
5196 pixel_to_colorref_masks
,
5198 create_rop_masks_32
,
5203 const primitive_funcs funcs_24
=
5213 colorref_to_pixel_888
,
5214 pixel_to_colorref_888
,
5216 create_rop_masks_24
,
5221 const primitive_funcs funcs_555
=
5231 colorref_to_pixel_555
,
5232 pixel_to_colorref_555
,
5234 create_rop_masks_16
,
5239 const primitive_funcs funcs_16
=
5249 colorref_to_pixel_masks
,
5250 pixel_to_colorref_masks
,
5252 create_rop_masks_16
,
5257 const primitive_funcs funcs_8
=
5267 colorref_to_pixel_colortable
,
5268 pixel_to_colorref_colortable
,
5275 const primitive_funcs funcs_4
=
5285 colorref_to_pixel_colortable
,
5286 pixel_to_colorref_colortable
,
5293 const primitive_funcs funcs_1
=
5303 colorref_to_pixel_colortable
,
5304 pixel_to_colorref_colortable
,
5311 const primitive_funcs funcs_null
=
5321 colorref_to_pixel_null
,
5322 pixel_to_colorref_null
,
5324 create_rop_masks_null
,