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 BYTE
aa_color( BYTE dst
, BYTE text
, BYTE min_comp
, BYTE max_comp
)
3982 if (dst
== text
) return dst
;
3986 DWORD diff
= dst
- text
;
3987 DWORD range
= max_comp
- text
;
3988 dst
= text
+ (diff
* range
) / (0xff - text
);
3993 DWORD diff
= text
- dst
;
3994 DWORD range
= text
- min_comp
;
3995 dst
= text
- (diff
* range
) / text
;
4000 static inline DWORD
aa_rgb( BYTE r_dst
, BYTE g_dst
, BYTE b_dst
, DWORD text
, const struct intensity_range
*range
)
4002 return (aa_color( b_dst
, text
, range
->b_min
, range
->b_max
) |
4003 aa_color( g_dst
, text
>> 8, range
->g_min
, range
->g_max
) << 8 |
4004 aa_color( r_dst
, text
>> 16, range
->r_min
, range
->r_max
) << 16);
4007 static void draw_glyph_8888( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4008 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4010 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
4011 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
4014 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4016 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
4018 if (glyph_ptr
[x
] <= 1) continue;
4019 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
4020 dst_ptr
[x
] = aa_rgb( dst_ptr
[x
] >> 16, dst_ptr
[x
] >> 8, dst_ptr
[x
], text_pixel
, ranges
+ glyph_ptr
[x
] );
4022 dst_ptr
+= dib
->stride
/ 4;
4023 glyph_ptr
+= glyph
->stride
;
4027 static void draw_glyph_32( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4028 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4030 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
4031 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
4035 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
4036 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
4037 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
4039 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4041 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
4043 if (glyph_ptr
[x
] <= 1) continue;
4044 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
4045 val
= aa_rgb( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
4046 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
4047 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
4048 text
, ranges
+ glyph_ptr
[x
] );
4049 dst_ptr
[x
] = (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
4050 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
4051 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
4053 dst_ptr
+= dib
->stride
/ 4;
4054 glyph_ptr
+= glyph
->stride
;
4058 static void draw_glyph_24( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4059 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4061 BYTE
*dst_ptr
= get_pixel_ptr_24( dib
, rect
->left
, rect
->top
);
4062 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
4066 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4068 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
4070 if (glyph_ptr
[x
] <= 1) continue;
4071 if (glyph_ptr
[x
] >= 16)
4074 val
= aa_rgb( dst_ptr
[x
* 3 + 2], dst_ptr
[x
* 3 + 1], dst_ptr
[x
* 3],
4075 text_pixel
, ranges
+ glyph_ptr
[x
] );
4076 dst_ptr
[x
* 3] = val
;
4077 dst_ptr
[x
* 3 + 1] = val
>> 8;
4078 dst_ptr
[x
* 3 + 2] = val
>> 16;
4080 dst_ptr
+= dib
->stride
;
4081 glyph_ptr
+= glyph
->stride
;
4085 static void draw_glyph_555( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4086 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4088 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
4089 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
4093 text
= ((text_pixel
<< 9) & 0xf80000) | ((text_pixel
<< 4) & 0x070000) |
4094 ((text_pixel
<< 6) & 0x00f800) | ((text_pixel
<< 1) & 0x000700) |
4095 ((text_pixel
<< 3) & 0x0000f8) | ((text_pixel
>> 2) & 0x000007);
4097 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4099 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
4101 if (glyph_ptr
[x
] <= 1) continue;
4102 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
4103 val
= aa_rgb( ((dst_ptr
[x
] >> 7) & 0xf8) | ((dst_ptr
[x
] >> 12) & 0x07),
4104 ((dst_ptr
[x
] >> 2) & 0xf8) | ((dst_ptr
[x
] >> 7) & 0x07),
4105 ((dst_ptr
[x
] << 3) & 0xf8) | ((dst_ptr
[x
] >> 2) & 0x07),
4106 text
, ranges
+ glyph_ptr
[x
] );
4107 dst_ptr
[x
] = ((val
>> 9) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 3) & 0x001f);
4109 dst_ptr
+= dib
->stride
/ 2;
4110 glyph_ptr
+= glyph
->stride
;
4114 static void draw_glyph_16( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4115 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4117 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
4118 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
4122 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
4123 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
4124 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
4126 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4128 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
4130 if (glyph_ptr
[x
] <= 1) continue;
4131 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
4132 val
= aa_rgb( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
4133 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
4134 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
4135 text
, ranges
+ glyph_ptr
[x
] );
4136 dst_ptr
[x
] = (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
4137 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
4138 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
4140 dst_ptr
+= dib
->stride
/ 2;
4141 glyph_ptr
+= glyph
->stride
;
4145 static void draw_glyph_8( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4146 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4148 BYTE
*dst_ptr
= get_pixel_ptr_8( dib
, rect
->left
, rect
->top
);
4149 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
4152 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4154 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
4156 /* no antialiasing, glyph should only contain 0 or 16. */
4157 if (glyph_ptr
[x
] >= 16)
4158 dst_ptr
[x
] = text_pixel
;
4160 dst_ptr
+= dib
->stride
;
4161 glyph_ptr
+= glyph
->stride
;
4165 static void draw_glyph_4( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4166 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4168 BYTE
*dst_ptr
= get_pixel_ptr_4( dib
, 0, rect
->top
);
4169 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
- rect
->left
, origin
->y
);
4172 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4174 for (x
= rect
->left
; x
< rect
->right
; x
++)
4176 /* no antialiasing, glyph should only contain 0 or 16. */
4177 if (glyph_ptr
[x
] >= 16)
4180 dst_ptr
[x
/ 2] = text_pixel
| (dst_ptr
[x
/ 2] & 0xf0);
4182 dst_ptr
[x
/ 2] = (text_pixel
<< 4) | (dst_ptr
[x
/ 2] & 0x0f);
4185 dst_ptr
+= dib
->stride
;
4186 glyph_ptr
+= glyph
->stride
;
4190 static void draw_glyph_1( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4191 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4193 BYTE
*dst_ptr
= get_pixel_ptr_1( dib
, 0, rect
->top
);
4194 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
- rect
->left
, origin
->y
);
4196 BYTE text
= (text_pixel
& 1) ? 0xff : 0;
4198 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4200 for (x
= rect
->left
; x
< rect
->right
; x
++)
4202 /* no antialiasing, glyph should only contain 0 or 16. */
4203 if (glyph_ptr
[x
] >= 16)
4204 dst_ptr
[x
/ 8] = (dst_ptr
[x
/ 8] & ~pixel_masks_1
[x
% 8]) | (text
& pixel_masks_1
[x
% 8]);
4206 dst_ptr
+= dib
->stride
;
4207 glyph_ptr
+= glyph
->stride
;
4211 static void draw_glyph_null( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4212 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4217 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
)
4219 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
4220 DWORD mask_start
= 0, mask_offset
;
4221 DWORD
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
4224 for(y
= 0; y
< hatch
->height
; y
++)
4226 hatch_ptr
= hatch_start
;
4227 mask_offset
= mask_start
;
4228 for(x
= 0; x
< hatch
->width
; x
++)
4230 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
4232 and_bits
[mask_offset
] = fg
->and;
4233 xor_bits
[mask_offset
] = fg
->xor;
4237 and_bits
[mask_offset
] = bg
->and;
4238 xor_bits
[mask_offset
] = bg
->xor;
4240 if(x
% 8 == 7) hatch_ptr
++;
4243 hatch_start
+= hatch
->stride
;
4244 mask_start
+= dib
->stride
/ 4;
4250 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
)
4252 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
4253 DWORD mask_start
= 0, mask_offset
;
4254 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
4257 for(y
= 0; y
< hatch
->height
; y
++)
4259 hatch_ptr
= hatch_start
;
4260 mask_offset
= mask_start
;
4261 for(x
= 0; x
< hatch
->width
; x
++)
4263 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
4265 and_bits
[mask_offset
] = fg
->and & 0xff;
4266 xor_bits
[mask_offset
++] = fg
->xor & 0xff;
4267 and_bits
[mask_offset
] = (fg
->and >> 8) & 0xff;
4268 xor_bits
[mask_offset
++] = (fg
->xor >> 8) & 0xff;
4269 and_bits
[mask_offset
] = (fg
->and >> 16) & 0xff;
4270 xor_bits
[mask_offset
++] = (fg
->xor >> 16) & 0xff;
4274 and_bits
[mask_offset
] = bg
->and & 0xff;
4275 xor_bits
[mask_offset
++] = bg
->xor & 0xff;
4276 and_bits
[mask_offset
] = (bg
->and >> 8) & 0xff;
4277 xor_bits
[mask_offset
++] = (bg
->xor >> 8) & 0xff;
4278 and_bits
[mask_offset
] = (bg
->and >> 16) & 0xff;
4279 xor_bits
[mask_offset
++] = (bg
->xor >> 16) & 0xff;
4281 if(x
% 8 == 7) hatch_ptr
++;
4283 hatch_start
+= hatch
->stride
;
4284 mask_start
+= dib
->stride
;
4290 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
)
4292 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
4293 DWORD mask_start
= 0, mask_offset
;
4294 WORD
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
4297 for(y
= 0; y
< hatch
->height
; y
++)
4299 hatch_ptr
= hatch_start
;
4300 mask_offset
= mask_start
;
4301 for(x
= 0; x
< hatch
->width
; x
++)
4303 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
4305 and_bits
[mask_offset
] = fg
->and;
4306 xor_bits
[mask_offset
] = fg
->xor;
4310 and_bits
[mask_offset
] = bg
->and;
4311 xor_bits
[mask_offset
] = bg
->xor;
4313 if(x
% 8 == 7) hatch_ptr
++;
4316 hatch_start
+= hatch
->stride
;
4317 mask_start
+= dib
->stride
/ 2;
4323 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
)
4325 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
4326 DWORD mask_start
= 0, mask_offset
;
4327 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
4330 for(y
= 0; y
< hatch
->height
; y
++)
4332 hatch_ptr
= hatch_start
;
4333 mask_offset
= mask_start
;
4334 for(x
= 0; x
< hatch
->width
; x
++)
4336 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
4338 and_bits
[mask_offset
] = fg
->and;
4339 xor_bits
[mask_offset
] = fg
->xor;
4343 and_bits
[mask_offset
] = bg
->and;
4344 xor_bits
[mask_offset
] = bg
->xor;
4346 if(x
% 8 == 7) hatch_ptr
++;
4349 hatch_start
+= hatch
->stride
;
4350 mask_start
+= dib
->stride
;
4356 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
)
4358 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
4359 DWORD mask_start
= 0, mask_offset
;
4360 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
4361 const rop_mask
*rop_mask
;
4364 for(y
= 0; y
< hatch
->height
; y
++)
4366 hatch_ptr
= hatch_start
;
4367 mask_offset
= mask_start
;
4368 for(x
= 0; x
< hatch
->width
; x
++)
4370 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
4377 and_bits
[mask_offset
] = (rop_mask
->and & 0x0f) | (and_bits
[mask_offset
] & 0xf0);
4378 xor_bits
[mask_offset
] = (rop_mask
->xor & 0x0f) | (xor_bits
[mask_offset
] & 0xf0);
4383 and_bits
[mask_offset
] = (rop_mask
->and << 4) & 0xf0;
4384 xor_bits
[mask_offset
] = (rop_mask
->xor << 4) & 0xf0;
4387 if(x
% 8 == 7) hatch_ptr
++;
4389 hatch_start
+= hatch
->stride
;
4390 mask_start
+= dib
->stride
;
4396 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
)
4398 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
4399 DWORD mask_start
= 0, mask_offset
;
4400 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
4404 for(y
= 0; y
< hatch
->height
; y
++)
4406 hatch_ptr
= hatch_start
;
4407 mask_offset
= mask_start
;
4408 for(x
= 0, bit_pos
= 0; x
< hatch
->width
; x
++)
4410 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
4412 rop_mask
.and = (fg
->and & 1) ? 0xff : 0;
4413 rop_mask
.xor = (fg
->xor & 1) ? 0xff : 0;
4417 rop_mask
.and = (bg
->and & 1) ? 0xff : 0;
4418 rop_mask
.xor = (bg
->xor & 1) ? 0xff : 0;
4421 if(bit_pos
== 0) and_bits
[mask_offset
] = xor_bits
[mask_offset
] = 0;
4423 and_bits
[mask_offset
] = (rop_mask
.and & pixel_masks_1
[bit_pos
]) | (and_bits
[mask_offset
] & ~pixel_masks_1
[bit_pos
]);
4424 xor_bits
[mask_offset
] = (rop_mask
.xor & pixel_masks_1
[bit_pos
]) | (xor_bits
[mask_offset
] & ~pixel_masks_1
[bit_pos
]);
4433 hatch_start
+= hatch
->stride
;
4434 mask_start
+= dib
->stride
;
4440 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
)
4445 static inline void rop_codes_from_stretch_mode( int mode
, struct rop_codes
*codes
)
4450 case STRETCH_DELETESCANS
:
4451 get_rop_codes( R2_COPYPEN
, codes
);
4453 case STRETCH_ORSCANS
:
4454 get_rop_codes( R2_MERGEPEN
, codes
);
4456 case STRETCH_ANDSCANS
:
4457 get_rop_codes( R2_MASKPEN
, codes
);
4463 static void stretch_row_32(const dib_info
*dst_dib
, const POINT
*dst_start
,
4464 const dib_info
*src_dib
, const POINT
*src_start
,
4465 const struct stretch_params
*params
, int mode
,
4468 DWORD
*dst_ptr
= get_pixel_ptr_32( dst_dib
, dst_start
->x
, dst_start
->y
);
4469 DWORD
*src_ptr
= get_pixel_ptr_32( src_dib
, src_start
->x
, src_start
->y
);
4470 int err
= params
->err_start
;
4472 struct rop_codes codes
;
4474 rop_codes_from_stretch_mode( mode
, &codes
);
4475 for (width
= params
->length
; width
; width
--)
4477 do_rop_codes_32( dst_ptr
, *src_ptr
, &codes
);
4478 dst_ptr
+= params
->dst_inc
;
4481 src_ptr
+= params
->src_inc
;
4482 err
+= params
->err_add_1
;
4484 else err
+= params
->err_add_2
;
4488 static void stretch_row_24(const dib_info
*dst_dib
, const POINT
*dst_start
,
4489 const dib_info
*src_dib
, const POINT
*src_start
,
4490 const struct stretch_params
*params
, int mode
,
4493 BYTE
*dst_ptr
= get_pixel_ptr_24( dst_dib
, dst_start
->x
, dst_start
->y
);
4494 BYTE
*src_ptr
= get_pixel_ptr_24( src_dib
, src_start
->x
, src_start
->y
);
4495 int err
= params
->err_start
;
4497 struct rop_codes codes
;
4499 rop_codes_from_stretch_mode( mode
, &codes
);
4500 for (width
= params
->length
; width
; width
--)
4502 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
4503 do_rop_codes_8( dst_ptr
+ 1, *(src_ptr
+ 1), &codes
);
4504 do_rop_codes_8( dst_ptr
+ 2, *(src_ptr
+ 2), &codes
);
4505 dst_ptr
+= 3 * params
->dst_inc
;
4508 src_ptr
+= 3 * params
->src_inc
;
4509 err
+= params
->err_add_1
;
4511 else err
+= params
->err_add_2
;
4515 static void stretch_row_16(const dib_info
*dst_dib
, const POINT
*dst_start
,
4516 const dib_info
*src_dib
, const POINT
*src_start
,
4517 const struct stretch_params
*params
, int mode
,
4520 WORD
*dst_ptr
= get_pixel_ptr_16( dst_dib
, dst_start
->x
, dst_start
->y
);
4521 WORD
*src_ptr
= get_pixel_ptr_16( src_dib
, src_start
->x
, src_start
->y
);
4522 int err
= params
->err_start
;
4524 struct rop_codes codes
;
4526 rop_codes_from_stretch_mode( mode
, &codes
);
4527 for (width
= params
->length
; width
; width
--)
4529 do_rop_codes_16( dst_ptr
, *src_ptr
, &codes
);
4530 dst_ptr
+= params
->dst_inc
;
4533 src_ptr
+= params
->src_inc
;
4534 err
+= params
->err_add_1
;
4536 else err
+= params
->err_add_2
;
4540 static void stretch_row_8(const dib_info
*dst_dib
, const POINT
*dst_start
,
4541 const dib_info
*src_dib
, const POINT
*src_start
,
4542 const struct stretch_params
*params
, int mode
,
4545 BYTE
*dst_ptr
= get_pixel_ptr_8( dst_dib
, dst_start
->x
, dst_start
->y
);
4546 BYTE
*src_ptr
= get_pixel_ptr_8( src_dib
, src_start
->x
, src_start
->y
);
4547 int err
= params
->err_start
;
4549 struct rop_codes codes
;
4551 rop_codes_from_stretch_mode( mode
, &codes
);
4552 for (width
= params
->length
; width
; width
--)
4554 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
4555 dst_ptr
+= params
->dst_inc
;
4558 src_ptr
+= params
->src_inc
;
4559 err
+= params
->err_add_1
;
4561 else err
+= params
->err_add_2
;
4565 static void stretch_row_4(const dib_info
*dst_dib
, const POINT
*dst_start
,
4566 const dib_info
*src_dib
, const POINT
*src_start
,
4567 const struct stretch_params
*params
, int mode
,
4570 BYTE
*dst_ptr
= get_pixel_ptr_4( dst_dib
, dst_start
->x
, dst_start
->y
);
4571 BYTE
*src_ptr
= get_pixel_ptr_4( src_dib
, src_start
->x
, src_start
->y
);
4572 int err
= params
->err_start
;
4573 int width
, dst_x
= dst_start
->x
, src_x
= src_start
->x
;
4574 struct rop_codes codes
;
4577 rop_codes_from_stretch_mode( mode
, &codes
);
4578 for (width
= params
->length
; width
; width
--)
4580 if (src_x
& 1) src_val
= (*src_ptr
& 0x0f) | (*src_ptr
<< 4);
4581 else src_val
= (*src_ptr
& 0xf0) | (*src_ptr
>> 4);
4583 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, (dst_x
& 1) ? 0x0f : 0xf0 );
4585 if ((dst_x
& ~1) != ((dst_x
+ params
->dst_inc
) & ~1))
4586 dst_ptr
+= params
->dst_inc
;
4587 dst_x
+= params
->dst_inc
;
4591 if ((src_x
& ~1) != ((src_x
+ params
->src_inc
) & ~1))
4592 src_ptr
+= params
->src_inc
;
4593 src_x
+= params
->src_inc
;
4594 err
+= params
->err_add_1
;
4596 else err
+= params
->err_add_2
;
4600 static void stretch_row_1(const dib_info
*dst_dib
, const POINT
*dst_start
,
4601 const dib_info
*src_dib
, const POINT
*src_start
,
4602 const struct stretch_params
*params
, int mode
,
4605 BYTE
*dst_ptr
= get_pixel_ptr_1( dst_dib
, dst_start
->x
, dst_start
->y
);
4606 BYTE
*src_ptr
= get_pixel_ptr_1( src_dib
, src_start
->x
, src_start
->y
);
4607 int err
= params
->err_start
;
4608 int width
, dst_x
= dst_start
->x
, src_x
= src_start
->x
;
4609 struct rop_codes codes
;
4612 rop_codes_from_stretch_mode( mode
, &codes
);
4613 for (width
= params
->length
; width
; width
--)
4615 src_val
= *src_ptr
& pixel_masks_1
[src_x
% 8] ? 0xff : 0;
4616 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, pixel_masks_1
[dst_x
% 8] );
4618 if ((dst_x
& ~7) != ((dst_x
+ params
->dst_inc
) & ~7))
4619 dst_ptr
+= params
->dst_inc
;
4620 dst_x
+= params
->dst_inc
;
4624 if ((src_x
& ~7) != ((src_x
+ params
->src_inc
) & ~7))
4625 src_ptr
+= params
->src_inc
;
4626 src_x
+= params
->src_inc
;
4627 err
+= params
->err_add_1
;
4629 else err
+= params
->err_add_2
;
4633 static void stretch_row_null(const dib_info
*dst_dib
, const POINT
*dst_start
,
4634 const dib_info
*src_dib
, const POINT
*src_start
,
4635 const struct stretch_params
*params
, int mode
,
4638 FIXME("bit count %d\n", dst_dib
->bit_count
);
4642 static void shrink_row_32(const dib_info
*dst_dib
, const POINT
*dst_start
,
4643 const dib_info
*src_dib
, const POINT
*src_start
,
4644 const struct stretch_params
*params
, int mode
,
4647 DWORD
*dst_ptr
= get_pixel_ptr_32( dst_dib
, dst_start
->x
, dst_start
->y
);
4648 DWORD
*src_ptr
= get_pixel_ptr_32( src_dib
, src_start
->x
, src_start
->y
);
4649 int err
= params
->err_start
;
4651 struct rop_codes codes
;
4652 DWORD init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
4653 BOOL new_pix
= TRUE
;
4655 rop_codes_from_stretch_mode( mode
, &codes
);
4656 for (width
= params
->length
; width
; width
--)
4658 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
4659 do_rop_codes_32( dst_ptr
, *src_ptr
, &codes
);
4661 src_ptr
+= params
->src_inc
;
4664 dst_ptr
+= params
->dst_inc
;
4666 err
+= params
->err_add_1
;
4668 else err
+= params
->err_add_2
;
4672 static void shrink_row_24(const dib_info
*dst_dib
, const POINT
*dst_start
,
4673 const dib_info
*src_dib
, const POINT
*src_start
,
4674 const struct stretch_params
*params
, int mode
,
4677 BYTE
*dst_ptr
= get_pixel_ptr_24( dst_dib
, dst_start
->x
, dst_start
->y
);
4678 BYTE
*src_ptr
= get_pixel_ptr_24( src_dib
, src_start
->x
, src_start
->y
);
4679 int err
= params
->err_start
;
4681 struct rop_codes codes
;
4682 BYTE init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
4683 BOOL new_pix
= TRUE
;
4685 rop_codes_from_stretch_mode( mode
, &codes
);
4686 for (width
= params
->length
; width
; width
--)
4688 if (new_pix
&& !keep_dst
) memset( dst_ptr
, init_val
, 3 );
4689 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
4690 do_rop_codes_8( dst_ptr
+ 1, *(src_ptr
+ 1), &codes
);
4691 do_rop_codes_8( dst_ptr
+ 2, *(src_ptr
+ 2), &codes
);
4693 src_ptr
+= 3 * params
->src_inc
;
4696 dst_ptr
+= 3 * params
->dst_inc
;
4698 err
+= params
->err_add_1
;
4700 else err
+= params
->err_add_2
;
4704 static void shrink_row_16(const dib_info
*dst_dib
, const POINT
*dst_start
,
4705 const dib_info
*src_dib
, const POINT
*src_start
,
4706 const struct stretch_params
*params
, int mode
,
4709 WORD
*dst_ptr
= get_pixel_ptr_16( dst_dib
, dst_start
->x
, dst_start
->y
);
4710 WORD
*src_ptr
= get_pixel_ptr_16( src_dib
, src_start
->x
, src_start
->y
);
4711 int err
= params
->err_start
;
4713 struct rop_codes codes
;
4714 WORD init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
4715 BOOL new_pix
= TRUE
;
4717 rop_codes_from_stretch_mode( mode
, &codes
);
4718 for (width
= params
->length
; width
; width
--)
4720 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
4721 do_rop_codes_16( dst_ptr
, *src_ptr
, &codes
);
4723 src_ptr
+= params
->src_inc
;
4726 dst_ptr
+= params
->dst_inc
;
4728 err
+= params
->err_add_1
;
4730 else err
+= params
->err_add_2
;
4734 static void shrink_row_8(const dib_info
*dst_dib
, const POINT
*dst_start
,
4735 const dib_info
*src_dib
, const POINT
*src_start
,
4736 const struct stretch_params
*params
, int mode
,
4739 BYTE
*dst_ptr
= get_pixel_ptr_8( dst_dib
, dst_start
->x
, dst_start
->y
);
4740 BYTE
*src_ptr
= get_pixel_ptr_8( src_dib
, src_start
->x
, src_start
->y
);
4741 int err
= params
->err_start
;
4743 struct rop_codes codes
;
4744 BYTE init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
4745 BOOL new_pix
= TRUE
;
4747 rop_codes_from_stretch_mode( mode
, &codes
);
4748 for (width
= params
->length
; width
; width
--)
4750 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
4751 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
4753 src_ptr
+= params
->src_inc
;
4756 dst_ptr
+= params
->dst_inc
;
4758 err
+= params
->err_add_1
;
4760 else err
+= params
->err_add_2
;
4764 static void shrink_row_4(const dib_info
*dst_dib
, const POINT
*dst_start
,
4765 const dib_info
*src_dib
, const POINT
*src_start
,
4766 const struct stretch_params
*params
, int mode
,
4769 BYTE
*dst_ptr
= get_pixel_ptr_8( dst_dib
, dst_start
->x
, dst_start
->y
);
4770 BYTE
*src_ptr
= get_pixel_ptr_8( src_dib
, src_start
->x
, src_start
->y
);
4771 int err
= params
->err_start
;
4772 int width
, dst_x
= dst_start
->x
, src_x
= src_start
->x
;
4773 struct rop_codes codes
;
4774 BYTE src_val
, init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
4775 BOOL new_pix
= TRUE
;
4777 rop_codes_from_stretch_mode( mode
, &codes
);
4778 for (width
= params
->length
; width
; width
--)
4780 if (new_pix
&& !keep_dst
) do_rop_mask_8( dst_ptr
, 0, init_val
, (dst_x
& 1) ? 0xf0 : 0x0f );
4782 if (src_x
& 1) src_val
= (*src_ptr
& 0x0f) | (*src_ptr
<< 4);
4783 else src_val
= (*src_ptr
& 0xf0) | (*src_ptr
>> 4);
4785 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, (dst_x
& 1) ? 0xf0 : 0x0f );
4788 if ((src_x
& ~1) != ((src_x
+ params
->src_inc
) & ~1))
4789 src_ptr
+= params
->src_inc
;
4790 src_x
+= params
->src_inc
;
4794 if ((dst_x
& ~1) != ((dst_x
+ params
->dst_inc
) & ~1))
4795 dst_ptr
+= params
->dst_inc
;
4796 dst_x
+= params
->dst_inc
;
4798 err
+= params
->err_add_1
;
4800 else err
+= params
->err_add_2
;
4804 static void shrink_row_1(const dib_info
*dst_dib
, const POINT
*dst_start
,
4805 const dib_info
*src_dib
, const POINT
*src_start
,
4806 const struct stretch_params
*params
, int mode
,
4809 BYTE
*dst_ptr
= get_pixel_ptr_1( dst_dib
, dst_start
->x
, dst_start
->y
);
4810 BYTE
*src_ptr
= get_pixel_ptr_1( src_dib
, src_start
->x
, src_start
->y
);
4811 int err
= params
->err_start
;
4812 int width
, dst_x
= dst_start
->x
, src_x
= src_start
->x
;
4813 struct rop_codes codes
;
4814 BYTE src_val
, init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
4815 BOOL new_pix
= TRUE
;
4817 rop_codes_from_stretch_mode( mode
, &codes
);
4818 for (width
= params
->length
; width
; width
--)
4820 if (new_pix
&& !keep_dst
) do_rop_mask_8( dst_ptr
, 0, init_val
, pixel_masks_1
[dst_x
% 8] );
4821 src_val
= *src_ptr
& pixel_masks_1
[src_x
% 8] ? 0xff : 0;
4822 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, pixel_masks_1
[dst_x
% 8] );
4825 if ((src_x
& ~7) != ((src_x
+ params
->src_inc
) & ~7))
4826 src_ptr
+= params
->src_inc
;
4827 src_x
+= params
->src_inc
;
4831 if ((dst_x
& ~7) != ((dst_x
+ params
->dst_inc
) & ~7))
4832 dst_ptr
+= params
->dst_inc
;
4833 dst_x
+= params
->dst_inc
;
4835 err
+= params
->err_add_1
;
4837 else err
+= params
->err_add_2
;
4841 static void shrink_row_null(const dib_info
*dst_dib
, const POINT
*dst_start
,
4842 const dib_info
*src_dib
, const POINT
*src_start
,
4843 const struct stretch_params
*params
, int mode
,
4846 FIXME("bit count %d\n", dst_dib
->bit_count
);
4850 const primitive_funcs funcs_8888
=
4859 colorref_to_pixel_888
,
4860 pixel_to_colorref_888
,
4862 create_rop_masks_32
,
4867 const primitive_funcs funcs_32
=
4876 colorref_to_pixel_masks
,
4877 pixel_to_colorref_masks
,
4879 create_rop_masks_32
,
4884 const primitive_funcs funcs_24
=
4893 colorref_to_pixel_888
,
4894 pixel_to_colorref_888
,
4896 create_rop_masks_24
,
4901 const primitive_funcs funcs_555
=
4910 colorref_to_pixel_555
,
4911 pixel_to_colorref_555
,
4913 create_rop_masks_16
,
4918 const primitive_funcs funcs_16
=
4927 colorref_to_pixel_masks
,
4928 pixel_to_colorref_masks
,
4930 create_rop_masks_16
,
4935 const primitive_funcs funcs_8
=
4944 colorref_to_pixel_colortable
,
4945 pixel_to_colorref_colortable
,
4952 const primitive_funcs funcs_4
=
4961 colorref_to_pixel_colortable
,
4962 pixel_to_colorref_colortable
,
4969 const primitive_funcs funcs_1
=
4978 colorref_to_pixel_colortable
,
4979 pixel_to_colorref_colortable
,
4986 const primitive_funcs funcs_null
=
4995 colorref_to_pixel_null
,
4996 pixel_to_colorref_null
,
4998 create_rop_masks_null
,