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 + 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 + 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 + 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 + 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 + 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 + 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 + y * dib->stride + x / 8;
65 static const BYTE pixel_masks_1[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
67 static inline void do_rop_32(DWORD *ptr, DWORD and, DWORD xor)
69 *ptr = (*ptr & and) ^ xor;
72 static inline void do_rop_16(WORD *ptr, WORD and, WORD xor)
74 *ptr = (*ptr & and) ^ xor;
77 static inline void do_rop_8(BYTE *ptr, BYTE and, BYTE xor)
79 *ptr = (*ptr & and) ^ xor;
82 static inline void do_rop_mask_8(BYTE *ptr, BYTE and, BYTE xor, BYTE mask)
84 *ptr = (*ptr & (and | ~mask)) ^ (xor & mask);
87 static inline void do_rop_codes_32(DWORD *dst, DWORD src, struct rop_codes *codes)
89 do_rop_32( dst, (src & codes->a1) ^ codes->a2, (src & codes->x1) ^ codes->x2 );
92 static inline void do_rop_codes_16(WORD *dst, WORD src, struct rop_codes *codes)
94 do_rop_16( dst, (src & codes->a1) ^ codes->a2, (src & codes->x1) ^ codes->x2 );
97 static inline void do_rop_codes_8(BYTE *dst, BYTE src, struct rop_codes *codes)
99 do_rop_8( dst, (src & codes->a1) ^ codes->a2, (src & codes->x1) ^ codes->x2 );
102 static inline void do_rop_codes_mask_8(BYTE *dst, BYTE src, struct rop_codes *codes, BYTE mask)
104 do_rop_mask_8( dst, (src & codes->a1) ^ codes->a2, (src & codes->x1) ^ codes->x2, mask );
107 static void solid_rects_32(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
112 for(i = 0; i < num; i++, rc++)
114 start = get_pixel_ptr_32(dib, rc->left, rc->top);
115 for(y = rc->top; y < rc->bottom; y++, start += dib->stride / 4)
116 for(x = rc->left, ptr = start; x < rc->right; x++)
117 do_rop_32(ptr++, and, xor);
121 static void solid_rects_24(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
124 BYTE *byte_ptr, *byte_start;
126 DWORD and_masks[3], xor_masks[3];
128 and_masks[0] = ( and & 0x00ffffff) | ((and << 24) & 0xff000000);
129 and_masks[1] = ((and >> 8) & 0x0000ffff) | ((and << 16) & 0xffff0000);
130 and_masks[2] = ((and >> 16) & 0x000000ff) | ((and << 8) & 0xffffff00);
131 xor_masks[0] = ( xor & 0x00ffffff) | ((xor << 24) & 0xff000000);
132 xor_masks[1] = ((xor >> 8) & 0x0000ffff) | ((xor << 16) & 0xffff0000);
133 xor_masks[2] = ((xor >> 16) & 0x000000ff) | ((xor << 8) & 0xffffff00);
135 for(i = 0; i < num; i++, rc++)
137 if(rc->left >= rc->right) continue;
139 if((rc->left & ~3) == (rc->right & ~3)) /* Special case for lines that start and end in the same DWORD triplet */
141 byte_start = get_pixel_ptr_24(dib, rc->left, rc->top);
142 for(y = rc->top; y < rc->bottom; y++, byte_start += dib->stride)
144 for(x = rc->left, byte_ptr = byte_start; x < rc->right; x++)
146 do_rop_8(byte_ptr++, and_masks[0] & 0xff, xor_masks[0] & 0xff);
147 do_rop_8(byte_ptr++, and_masks[1] & 0xff, xor_masks[1] & 0xff);
148 do_rop_8(byte_ptr++, and_masks[2] & 0xff, xor_masks[2] & 0xff);
154 start = get_pixel_ptr_24_dword(dib, rc->left, rc->top);
155 for(y = rc->top; y < rc->bottom; y++, start += dib->stride / 4)
162 do_rop_32(ptr++, and_masks[0] | 0x00ffffff, xor_masks[0] & 0xff000000);
163 do_rop_32(ptr++, and_masks[1], xor_masks[1]);
164 do_rop_32(ptr++, and_masks[2], xor_masks[2]);
167 do_rop_32(ptr++, and_masks[1] | 0x0000ffff, xor_masks[1] & 0xffff0000);
168 do_rop_32(ptr++, and_masks[2], xor_masks[2]);
171 do_rop_32(ptr++, and_masks[2] | 0x000000ff, xor_masks[2] & 0xffffff00);
175 for(x = (rc->left + 3) & ~3; x < (rc->right & ~3); x += 4)
177 do_rop_32(ptr++, and_masks[0], xor_masks[0]);
178 do_rop_32(ptr++, and_masks[1], xor_masks[1]);
179 do_rop_32(ptr++, and_masks[2], xor_masks[2]);
182 switch(rc->right & 3)
185 do_rop_32(ptr, and_masks[0] | 0xff000000, xor_masks[0] & 0x00ffffff);
188 do_rop_32(ptr++, and_masks[0], xor_masks[0]);
189 do_rop_32(ptr, and_masks[1] | 0xffff0000, xor_masks[1] & 0x0000ffff);
192 do_rop_32(ptr++, and_masks[0], xor_masks[0]);
193 do_rop_32(ptr++, and_masks[1], xor_masks[1]);
194 do_rop_32(ptr, and_masks[2] | 0xffffff00, xor_masks[2] & 0x000000ff);
202 static void solid_rects_16(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
207 for(i = 0; i < num; i++, rc++)
209 start = get_pixel_ptr_16(dib, rc->left, rc->top);
210 for(y = rc->top; y < rc->bottom; y++, start += dib->stride / 2)
211 for(x = rc->left, ptr = start; x < rc->right; x++)
212 do_rop_16(ptr++, and, xor);
216 static void solid_rects_8(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
221 for(i = 0; i < num; i++, rc++)
223 start = get_pixel_ptr_8(dib, rc->left, rc->top);
224 for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
225 for(x = rc->left, ptr = start; x < rc->right; x++)
226 do_rop_8(ptr++, and, xor);
230 static void solid_rects_4(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
234 BYTE byte_and = (and & 0xf) | ((and << 4) & 0xf0);
235 BYTE byte_xor = (xor & 0xf) | ((xor << 4) & 0xf0);
237 for(i = 0; i < num; i++, rc++)
239 if(rc->left >= rc->right) continue;
240 start = get_pixel_ptr_4(dib, rc->left, rc->top);
241 for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
244 if(rc->left & 1) /* upper nibble untouched */
245 do_rop_8(ptr++, byte_and | 0xf0, byte_xor & 0x0f);
247 for(x = (rc->left + 1) & ~1; x < (rc->right & ~1); x += 2)
248 do_rop_8(ptr++, byte_and, byte_xor);
250 if(rc->right & 1) /* lower nibble untouched */
251 do_rop_8(ptr, byte_and | 0x0f, byte_xor & 0xf0);
256 static void solid_rects_1(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
260 BYTE byte_and = (and & 1) ? 0xff : 0;
261 BYTE byte_xor = (xor & 1) ? 0xff : 0;
262 BYTE start_and, start_xor, end_and, end_xor, mask;
263 static const BYTE masks[8] = {0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01};
265 for(i = 0; i < num; i++, rc++)
267 if(rc->left >= rc->right) continue;
269 start = get_pixel_ptr_1(dib, rc->left, rc->top);
271 if((rc->left & ~7) == (rc->right & ~7)) /* Special case for lines that start and end in the same byte */
273 mask = masks[rc->left & 7] & ~masks[rc->right & 7];
275 start_and = byte_and | ~mask;
276 start_xor = byte_xor & mask;
277 for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
279 do_rop_8(start, start_and, start_xor);
284 mask = masks[rc->left & 7];
285 start_and = byte_and | ~mask;
286 start_xor = byte_xor & mask;
288 mask = masks[rc->right & 7];
289 /* This is inverted wrt to start mask, so end_and/xor assignments reflect this */
290 end_and = byte_and | mask;
291 end_xor = byte_xor & ~mask;
293 for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
298 do_rop_8(ptr++, start_and, start_xor);
300 for(x = (rc->left + 7) & ~7; x < (rc->right & ~7); x += 8)
301 do_rop_8(ptr++, byte_and, byte_xor);
304 do_rop_8(ptr, end_and, end_xor);
310 static void solid_rects_null(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
315 static inline INT calc_offset(INT edge, INT size, INT origin)
319 if(edge - origin >= 0)
320 offset = (edge - origin) % size;
323 offset = (origin - edge) % size;
324 if(offset) offset = size - offset;
329 static inline POINT calc_brush_offset(const RECT *rc, const dib_info *brush, const POINT *origin)
333 offset.x = calc_offset(rc->left, brush->width, origin->x);
334 offset.y = calc_offset(rc->top, brush->height, origin->y);
339 static void pattern_rects_32(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
340 const dib_info *brush, void *and_bits, void *xor_bits)
342 DWORD *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
346 for(i = 0; i < num; i++, rc++)
348 offset = calc_brush_offset(rc, brush, origin);
350 start = get_pixel_ptr_32(dib, rc->left, rc->top);
351 start_and = (DWORD*)and_bits + offset.y * brush->stride / 4;
352 start_xor = (DWORD*)xor_bits + offset.y * brush->stride / 4;
354 for(y = rc->top; y < rc->bottom; y++, start += dib->stride / 4)
356 and_ptr = start_and + offset.x;
357 xor_ptr = start_xor + offset.x;
359 for(x = rc->left, ptr = start; x < rc->right; x++)
361 do_rop_32(ptr++, *and_ptr++, *xor_ptr++);
362 if(and_ptr == start_and + brush->width)
370 if(offset.y == brush->height)
372 start_and = and_bits;
373 start_xor = xor_bits;
378 start_and += brush->stride / 4;
379 start_xor += brush->stride / 4;
385 static void pattern_rects_24(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
386 const dib_info *brush, void *and_bits, void *xor_bits)
388 BYTE *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
392 for(i = 0; i < num; i++, rc++)
394 offset = calc_brush_offset(rc, brush, origin);
396 start = get_pixel_ptr_24(dib, rc->left, rc->top);
397 start_and = (BYTE*)and_bits + offset.y * brush->stride;
398 start_xor = (BYTE*)xor_bits + offset.y * brush->stride;
400 for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
402 and_ptr = start_and + offset.x * 3;
403 xor_ptr = start_xor + offset.x * 3;
405 for(x = rc->left, ptr = start; x < rc->right; x++)
407 do_rop_8(ptr++, *and_ptr++, *xor_ptr++);
408 do_rop_8(ptr++, *and_ptr++, *xor_ptr++);
409 do_rop_8(ptr++, *and_ptr++, *xor_ptr++);
410 if(and_ptr == start_and + brush->width * 3)
418 if(offset.y == brush->height)
420 start_and = and_bits;
421 start_xor = xor_bits;
426 start_and += brush->stride;
427 start_xor += brush->stride;
433 static void pattern_rects_16(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
434 const dib_info *brush, void *and_bits, void *xor_bits)
436 WORD *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
440 for(i = 0; i < num; i++, rc++)
442 offset = calc_brush_offset(rc, brush, origin);
444 start = get_pixel_ptr_16(dib, rc->left, rc->top);
445 start_and = (WORD*)and_bits + offset.y * brush->stride / 2;
446 start_xor = (WORD*)xor_bits + offset.y * brush->stride / 2;
448 for(y = rc->top; y < rc->bottom; y++, start += dib->stride / 2)
450 and_ptr = start_and + offset.x;
451 xor_ptr = start_xor + offset.x;
453 for(x = rc->left, ptr = start; x < rc->right; x++)
455 do_rop_16(ptr++, *and_ptr++, *xor_ptr++);
456 if(and_ptr == start_and + brush->width)
464 if(offset.y == brush->height)
466 start_and = and_bits;
467 start_xor = xor_bits;
472 start_and += brush->stride / 2;
473 start_xor += brush->stride / 2;
479 static void pattern_rects_8(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
480 const dib_info *brush, void *and_bits, void *xor_bits)
482 BYTE *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
486 for(i = 0; i < num; i++, rc++)
488 offset = calc_brush_offset(rc, brush, origin);
490 start = get_pixel_ptr_8(dib, rc->left, rc->top);
491 start_and = (BYTE*)and_bits + offset.y * brush->stride;
492 start_xor = (BYTE*)xor_bits + offset.y * brush->stride;
494 for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
496 and_ptr = start_and + offset.x;
497 xor_ptr = start_xor + offset.x;
499 for(x = rc->left, ptr = start; x < rc->right; x++)
501 do_rop_8(ptr++, *and_ptr++, *xor_ptr++);
502 if(and_ptr == start_and + brush->width)
510 if(offset.y == brush->height)
512 start_and = and_bits;
513 start_xor = xor_bits;
518 start_and += brush->stride;
519 start_xor += brush->stride;
525 static void pattern_rects_4(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
526 const dib_info *brush, void *and_bits, void *xor_bits)
528 BYTE *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
532 for(i = 0; i < num; i++, rc++)
534 offset = calc_brush_offset(rc, brush, origin);
536 start = get_pixel_ptr_4(dib, rc->left, rc->top);
537 start_and = (BYTE*)and_bits + offset.y * brush->stride;
538 start_xor = (BYTE*)xor_bits + offset.y * brush->stride;
540 for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
542 INT brush_x = offset.x;
543 BYTE byte_and, byte_xor;
545 and_ptr = start_and + brush_x / 2;
546 xor_ptr = start_xor + brush_x / 2;
548 for(x = rc->left, ptr = start; x < rc->right; x++)
550 /* FIXME: Two pixels at a time */
551 if(x & 1) /* lower dst nibble */
553 if(brush_x & 1) /* lower pat nibble */
555 byte_and = *and_ptr++ | 0xf0;
556 byte_xor = *xor_ptr++ & 0x0f;
558 else /* upper pat nibble */
560 byte_and = (*and_ptr >> 4) | 0xf0;
561 byte_xor = (*xor_ptr >> 4) & 0x0f;
564 else /* upper dst nibble */
566 if(brush_x & 1) /* lower pat nibble */
568 byte_and = (*and_ptr++ << 4) | 0x0f;
569 byte_xor = (*xor_ptr++ << 4) & 0xf0;
571 else /* upper pat nibble */
573 byte_and = *and_ptr | 0x0f;
574 byte_xor = *xor_ptr & 0xf0;
577 do_rop_8(ptr, byte_and, byte_xor);
581 if(++brush_x == brush->width)
590 if(offset.y == brush->height)
592 start_and = and_bits;
593 start_xor = xor_bits;
598 start_and += brush->stride;
599 start_xor += brush->stride;
605 static void pattern_rects_1(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
606 const dib_info *brush, void *and_bits, void *xor_bits)
608 BYTE *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
612 for(i = 0; i < num; i++, rc++)
614 offset = calc_brush_offset(rc, brush, origin);
616 start = get_pixel_ptr_1(dib, rc->left, rc->top);
617 start_and = (BYTE*)and_bits + offset.y * brush->stride;
618 start_xor = (BYTE*)xor_bits + offset.y * brush->stride;
620 for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
622 INT brush_x = offset.x;
623 BYTE byte_and, byte_xor;
625 and_ptr = start_and + brush_x / 8;
626 xor_ptr = start_xor + brush_x / 8;
628 for(x = rc->left, ptr = start; x < rc->right; x++)
630 byte_and = (*and_ptr & pixel_masks_1[brush_x % 8]) ? 0xff : 0;
631 byte_and |= ~pixel_masks_1[x % 8];
632 byte_xor = (*xor_ptr & pixel_masks_1[brush_x % 8]) ? 0xff : 0;
633 byte_xor &= pixel_masks_1[x % 8];
635 do_rop_8(ptr, byte_and, byte_xor);
637 if((x & 7) == 7) ptr++;
639 if((brush_x & 7) == 7)
645 if(++brush_x == brush->width)
654 if(offset.y == brush->height)
656 start_and = and_bits;
657 start_xor = xor_bits;
662 start_and += brush->stride;
663 start_xor += brush->stride;
669 static void pattern_rects_null(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
670 const dib_info *brush, void *and_bits, void *xor_bits)
675 static void copy_rect_32(const dib_info *dst, const RECT *rc,
676 const dib_info *src, const POINT *origin, int rop2)
678 DWORD *dst_start = get_pixel_ptr_32(dst, rc->left, rc->top);
679 DWORD *src_start = get_pixel_ptr_32(src, origin->x, origin->y);
680 DWORD *dst_ptr, *src_ptr;
681 DWORD and = 0, xor = 0;
682 struct rop_codes codes;
688 case R2_NOT: and = ~0u;
690 case R2_WHITE: xor = ~0u;
693 dst->funcs->solid_rects( dst, 1, rc, and, xor );
697 for (y = rc->top; y < rc->bottom; y++)
699 memcpy( dst_start, src_start, (rc->right - rc->left) * 4 );
700 dst_start += dst->stride / 4;
701 src_start += src->stride / 4;
706 get_rop_codes( rop2, &codes );
707 for (y = rc->top; y < rc->bottom; y++)
709 for (x = rc->left, dst_ptr = dst_start, src_ptr = src_start; x < rc->right; x++)
710 do_rop_codes_32( dst_ptr++, *src_ptr++, &codes );
712 dst_start += dst->stride / 4;
713 src_start += src->stride / 4;
719 static void copy_rect_24(const dib_info *dst, const RECT *rc,
720 const dib_info *src, const POINT *origin, int rop2)
722 BYTE *dst_start = get_pixel_ptr_24(dst, rc->left, rc->top);
723 BYTE *src_start = get_pixel_ptr_24(src, origin->x, origin->y);
724 BYTE *dst_ptr, *src_ptr;
725 DWORD and = 0, xor = 0;
727 struct rop_codes codes;
732 case R2_NOT: and = ~0u;
734 case R2_WHITE: xor = ~0u;
737 dst->funcs->solid_rects( dst, 1, rc, and, xor );
741 for (y = rc->top; y < rc->bottom; y++)
743 memcpy( dst_start, src_start, (rc->right - rc->left) * 3);
744 dst_start += dst->stride;
745 src_start += src->stride;
750 get_rop_codes( rop2, &codes );
751 for (y = rc->top; y < rc->bottom; y++)
753 for (x = rc->left, dst_ptr = dst_start, src_ptr = src_start; x < rc->right; x++)
755 do_rop_codes_8( dst_ptr++, *src_ptr++, &codes );
756 do_rop_codes_8( dst_ptr++, *src_ptr++, &codes );
757 do_rop_codes_8( dst_ptr++, *src_ptr++, &codes );
759 dst_start += dst->stride;
760 src_start += src->stride;
766 static void copy_rect_16(const dib_info *dst, const RECT *rc,
767 const dib_info *src, const POINT *origin, int rop2)
769 WORD *dst_start = get_pixel_ptr_16(dst, rc->left, rc->top);
770 WORD *src_start = get_pixel_ptr_16(src, origin->x, origin->y);
771 WORD *dst_ptr, *src_ptr;
772 DWORD and = 0, xor = 0;
774 struct rop_codes codes;
779 case R2_NOT: and = ~0u;
781 case R2_WHITE: xor = ~0u;
784 dst->funcs->solid_rects( dst, 1, rc, and, xor );
788 for (y = rc->top; y < rc->bottom; y++)
790 memcpy( dst_start, src_start, (rc->right - rc->left) * 2 );
791 dst_start += dst->stride / 2;
792 src_start += src->stride / 2;
797 get_rop_codes( rop2, &codes );
798 for (y = rc->top; y < rc->bottom; y++)
800 for (x = rc->left, dst_ptr = dst_start, src_ptr = src_start; x < rc->right; x++)
801 do_rop_codes_16( dst_ptr++, *src_ptr++, &codes );
803 dst_start += dst->stride / 2;
804 src_start += src->stride / 2;
810 static void copy_rect_8(const dib_info *dst, const RECT *rc,
811 const dib_info *src, const POINT *origin, int rop2)
813 BYTE *dst_start = get_pixel_ptr_8(dst, rc->left, rc->top);
814 BYTE *src_start = get_pixel_ptr_8(src, origin->x, origin->y);
815 BYTE *dst_ptr, *src_ptr;
816 DWORD and = 0, xor = 0;
818 struct rop_codes codes;
823 case R2_NOT: and = ~0u;
825 case R2_WHITE: xor = ~0u;
828 dst->funcs->solid_rects( dst, 1, rc, and, xor );
832 for (y = rc->top; y < rc->bottom; y++)
834 memcpy( dst_start, src_start, (rc->right - rc->left) );
835 dst_start += dst->stride;
836 src_start += src->stride;
841 get_rop_codes( rop2, &codes );
842 for (y = rc->top; y < rc->bottom; y++)
844 for (x = rc->left, dst_ptr = dst_start, src_ptr = src_start; x < rc->right; x++)
845 do_rop_codes_8( dst_ptr++, *src_ptr++, &codes );
847 dst_start += dst->stride;
848 src_start += src->stride;
854 static void copy_rect_4(const dib_info *dst, const RECT *rc,
855 const dib_info *src, const POINT *origin, int rop2)
857 BYTE *dst_start = get_pixel_ptr_4(dst, rc->left, rc->top);
858 BYTE *src_start = get_pixel_ptr_4(src, origin->x, origin->y);
859 BYTE *dst_ptr, *src_ptr, src_val;
860 DWORD and = 0, xor = 0;
862 struct rop_codes codes;
867 case R2_NOT: and = ~0u;
869 case R2_WHITE: xor = ~0u;
872 dst->funcs->solid_rects( dst, 1, rc, and, xor );
876 if ((rc->left & 1) == 0 && (origin->x & 1) == 0 && (rc->right & 1) == 0)
878 for (y = rc->top; y < rc->bottom; y++)
880 memcpy( dst_start, src_start, (rc->right - rc->left) / 2 );
881 dst_start += dst->stride;
882 src_start += src->stride;
888 get_rop_codes( rop2, &codes );
889 for (y = rc->top; y < rc->bottom; y++)
891 for (x = rc->left, src_x = origin->x, dst_ptr = dst_start, src_ptr = src_start; x < rc->right; x++, src_x++)
895 if (src_x & 1) src_val = *src_ptr++;
896 else src_val = *src_ptr >> 4;
897 do_rop_codes_mask_8( dst_ptr++, src_val, &codes, 0x0f );
901 if (src_x & 1) src_val = *src_ptr++ << 4;
902 else src_val = *src_ptr;
903 do_rop_codes_mask_8( dst_ptr, src_val, &codes, 0xf0 );
906 dst_start += dst->stride;
907 src_start += src->stride;
913 static void copy_rect_1(const dib_info *dst, const RECT *rc,
914 const dib_info *src, const POINT *origin, int rop2)
916 BYTE *dst_start = get_pixel_ptr_1(dst, rc->left, rc->top);
917 BYTE *src_start = get_pixel_ptr_1(src, origin->x, origin->y);
918 BYTE *dst_ptr, *src_ptr, src_val;
919 DWORD and = 0, xor = 0;
920 int x, y, dst_bitpos, src_bitpos;
921 struct rop_codes codes;
926 case R2_NOT: and = ~0u;
928 case R2_WHITE: xor = ~0u;
931 dst->funcs->solid_rects( dst, 1, rc, and, xor );
935 if ((rc->left & 7) == 0 && (origin->x & 7) == 0 && (rc->right & 7) == 0)
937 for (y = rc->top; y < rc->bottom; y++)
939 memcpy( dst_start, src_start, (rc->right - rc->left) / 8);
940 dst_start += dst->stride;
941 src_start += src->stride;
947 get_rop_codes( rop2, &codes );
948 for (y = rc->top; y < rc->bottom; y++)
950 dst_bitpos = rc->left & 7;
951 src_bitpos = origin->x & 7;
952 for (x = rc->left, dst_ptr = dst_start, src_ptr = src_start; x < rc->right; x++)
954 src_val = *src_ptr & pixel_masks_1[src_bitpos] ? 0xff : 0;
955 do_rop_codes_mask_8( dst_ptr, src_val, &codes, pixel_masks_1[dst_bitpos] );
956 if (dst_bitpos++ == 7) { dst_ptr++, dst_bitpos = 0; }
957 if (src_bitpos++ == 7) { src_ptr++, src_bitpos = 0; }
959 dst_start += dst->stride;
960 src_start += src->stride;
966 static void copy_rect_null(const dib_info *dst, const RECT *rc,
967 const dib_info *src, const POINT *origin, int rop2)
972 static DWORD colorref_to_pixel_888(const dib_info *dib, COLORREF color)
974 return ( ((color >> 16) & 0xff) | (color & 0xff00) | ((color << 16) & 0xff0000) );
977 static inline DWORD put_field(DWORD field, int shift, int len)
979 shift = shift - (8 - len);
981 field &= (((1 << len) - 1) << (8 - len));
989 static DWORD colorref_to_pixel_masks(const dib_info *dib, COLORREF colour)
993 r = GetRValue(colour);
994 g = GetGValue(colour);
995 b = GetBValue(colour);
997 return put_field(r, dib->red_shift, dib->red_len) |
998 put_field(g, dib->green_shift, dib->green_len) |
999 put_field(b, dib->blue_shift, dib->blue_len);
1002 static DWORD colorref_to_pixel_555(const dib_info *dib, COLORREF color)
1004 return ( ((color >> 19) & 0x1f) | ((color >> 6) & 0x03e0) | ((color << 7) & 0x7c00) );
1007 static DWORD colorref_to_pixel_colortable(const dib_info *dib, COLORREF color)
1009 int i, best_index = 0;
1011 DWORD diff, best_diff = 0xffffffff;
1013 rgb.rgbRed = GetRValue(color);
1014 rgb.rgbGreen = GetGValue(color);
1015 rgb.rgbBlue = GetBValue(color);
1017 /* special case for conversion to 1-bpp without a color table:
1018 * we get a 1-entry table containing the background color
1020 if (dib->bit_count == 1 && dib->color_table_size == 1)
1021 return (rgb.rgbRed == dib->color_table[0].rgbRed &&
1022 rgb.rgbGreen == dib->color_table[0].rgbGreen &&
1023 rgb.rgbBlue == dib->color_table[0].rgbBlue);
1025 for(i = 0; i < dib->color_table_size; i++)
1027 RGBQUAD *cur = dib->color_table + i;
1028 diff = (rgb.rgbRed - cur->rgbRed) * (rgb.rgbRed - cur->rgbRed)
1029 + (rgb.rgbGreen - cur->rgbGreen) * (rgb.rgbGreen - cur->rgbGreen)
1030 + (rgb.rgbBlue - cur->rgbBlue) * (rgb.rgbBlue - cur->rgbBlue);
1038 if(diff < best_diff)
1047 static DWORD colorref_to_pixel_null(const dib_info *dib, COLORREF color)
1052 static inline BOOL bit_fields_match(const dib_info *d1, const dib_info *d2)
1054 assert( d1->bit_count > 8 && d1->bit_count == d2->bit_count );
1056 return d1->red_mask == d2->red_mask &&
1057 d1->green_mask == d2->green_mask &&
1058 d1->blue_mask == d2->blue_mask;
1061 static BOOL convert_to_8888(dib_info *dst, const dib_info *src, const RECT *src_rect)
1063 DWORD *dst_start = dst->bits, *dst_pixel, src_val;
1064 int x, y, pad_size = (dst->width - (src_rect->right - src_rect->left)) * 4;
1066 switch(src->bit_count)
1070 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
1071 if(src->funcs == &funcs_8888)
1073 if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
1074 memcpy(dst->bits, src_start, (src_rect->bottom - src_rect->top) * src->stride);
1077 for(y = src_rect->top; y < src_rect->bottom; y++)
1079 memcpy(dst_start, src_start, (src_rect->right - src_rect->left) * 4);
1080 if(pad_size) memset(dst_start + (src_rect->right - src_rect->left), 0, pad_size);
1081 dst_start += dst->stride / 4;
1082 src_start += src->stride / 4;
1086 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
1088 for(y = src_rect->top; y < src_rect->bottom; y++)
1090 dst_pixel = dst_start;
1091 src_pixel = src_start;
1092 for(x = src_rect->left; x < src_rect->right; x++)
1094 src_val = *src_pixel++;
1095 *dst_pixel++ = (((src_val >> src->red_shift) & 0xff) << 16) |
1096 (((src_val >> src->green_shift) & 0xff) << 8) |
1097 ((src_val >> src->blue_shift) & 0xff);
1099 if(pad_size) memset(dst_pixel, 0, pad_size);
1100 dst_start += dst->stride / 4;
1101 src_start += src->stride / 4;
1106 FIXME("Unsupported conversion: 32 (%08x, %08x, %08x) -> 8888\n", src->red_mask, src->green_mask, src->blue_mask);
1114 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
1116 for(y = src_rect->top; y < src_rect->bottom; y++)
1118 dst_pixel = dst_start;
1119 src_pixel = src_start;
1120 for(x = src_rect->left; x < src_rect->right; x++)
1123 rgb.rgbBlue = *src_pixel++;
1124 rgb.rgbGreen = *src_pixel++;
1125 rgb.rgbRed = *src_pixel++;
1127 *dst_pixel++ = ((rgb.rgbRed << 16) & 0xff0000) | ((rgb.rgbGreen << 8) & 0x00ff00) | (rgb.rgbBlue & 0x0000ff);
1129 if(pad_size) memset(dst_pixel, 0, pad_size);
1130 dst_start += dst->stride / 4;
1131 src_start += src->stride;
1138 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
1139 if(src->funcs == &funcs_555)
1141 for(y = src_rect->top; y < src_rect->bottom; y++)
1143 dst_pixel = dst_start;
1144 src_pixel = src_start;
1145 for(x = src_rect->left; x < src_rect->right; x++)
1147 src_val = *src_pixel++;
1148 *dst_pixel++ = ((src_val << 9) & 0xf80000) | ((src_val << 4) & 0x070000) |
1149 ((src_val << 6) & 0x00f800) | ((src_val << 1) & 0x000700) |
1150 ((src_val << 3) & 0x0000f8) | ((src_val >> 2) & 0x000007);
1152 if(pad_size) memset(dst_pixel, 0, pad_size);
1153 dst_start += dst->stride / 4;
1154 src_start += src->stride / 2;
1157 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
1159 for(y = src_rect->top; y < src_rect->bottom; y++)
1161 dst_pixel = dst_start;
1162 src_pixel = src_start;
1163 for(x = src_rect->left; x < src_rect->right; x++)
1165 src_val = *src_pixel++;
1166 *dst_pixel++ = (((src_val >> src->red_shift) << 19) & 0xf80000) |
1167 (((src_val >> src->red_shift) << 14) & 0x070000) |
1168 (((src_val >> src->green_shift) << 11) & 0x00f800) |
1169 (((src_val >> src->green_shift) << 6) & 0x000700) |
1170 (((src_val >> src->blue_shift) << 3) & 0x0000f8) |
1171 (((src_val >> src->blue_shift) >> 2) & 0x000007);
1173 if(pad_size) memset(dst_pixel, 0, pad_size);
1174 dst_start += dst->stride / 4;
1175 src_start += src->stride / 2;
1178 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
1180 for(y = src_rect->top; y < src_rect->bottom; y++)
1182 dst_pixel = dst_start;
1183 src_pixel = src_start;
1184 for(x = src_rect->left; x < src_rect->right; x++)
1186 src_val = *src_pixel++;
1187 *dst_pixel++ = (((src_val >> src->red_shift) << 19) & 0xf80000) |
1188 (((src_val >> src->red_shift) << 14) & 0x070000) |
1189 (((src_val >> src->green_shift) << 10) & 0x00fc00) |
1190 (((src_val >> src->green_shift) << 4) & 0x000300) |
1191 (((src_val >> src->blue_shift) << 3) & 0x0000f8) |
1192 (((src_val >> src->blue_shift) >> 2) & 0x000007);
1194 if(pad_size) memset(dst_pixel, 0, pad_size);
1195 dst_start += dst->stride / 4;
1196 src_start += src->stride / 2;
1201 FIXME("Unsupported conversion: 16 (%08x, %08x, %08x) -> 8888\n", src->red_mask, src->green_mask, src->blue_mask);
1209 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
1210 for(y = src_rect->top; y < src_rect->bottom; y++)
1212 dst_pixel = dst_start;
1213 src_pixel = src_start;
1214 for(x = src_rect->left; x < src_rect->right; x++)
1217 src_val = *src_pixel++;
1218 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
1219 rgb = src->color_table[src_val];
1220 *dst_pixel++ = rgb.rgbRed << 16 | rgb.rgbGreen << 8 | rgb.rgbBlue;
1222 if(pad_size) memset(dst_pixel, 0, pad_size);
1223 dst_start += dst->stride / 4;
1224 src_start += src->stride;
1231 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
1232 for(y = src_rect->top; y < src_rect->bottom; y++)
1234 dst_pixel = dst_start;
1235 src_pixel = src_start;
1236 for(x = src_rect->left; x < src_rect->right; x++)
1240 src_val = *src_pixel++ & 0xf;
1242 src_val = (*src_pixel >> 4) & 0xf;
1243 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
1244 rgb = src->color_table[src_val];
1245 *dst_pixel++ = rgb.rgbRed << 16 | rgb.rgbGreen << 8 | rgb.rgbBlue;
1247 if(pad_size) memset(dst_pixel, 0, pad_size);
1248 dst_start += dst->stride / 4;
1249 src_start += src->stride;
1256 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
1257 for(y = src_rect->top; y < src_rect->bottom; y++)
1259 dst_pixel = dst_start;
1260 src_pixel = src_start;
1261 for(x = src_rect->left; x < src_rect->right; x++)
1264 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
1265 if((x % 8) == 7) src_pixel++;
1266 rgb = src->color_table[src_val];
1267 *dst_pixel++ = rgb.rgbRed << 16 | rgb.rgbGreen << 8 | rgb.rgbBlue;
1269 if(pad_size) memset(dst_pixel, 0, pad_size);
1270 dst_start += dst->stride / 4;
1271 src_start += src->stride;
1277 FIXME("Unsupported conversion: %d -> 8888\n", src->bit_count);
1284 static BOOL convert_to_32(dib_info *dst, const dib_info *src, const RECT *src_rect)
1286 DWORD *dst_start = dst->bits, *dst_pixel, src_val;
1287 int x, y, pad_size = (dst->width - (src_rect->right - src_rect->left)) * 4;
1289 switch(src->bit_count)
1293 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
1295 if(src->funcs == &funcs_8888)
1297 for(y = src_rect->top; y < src_rect->bottom; y++)
1299 dst_pixel = dst_start;
1300 src_pixel = src_start;
1301 for(x = src_rect->left; x < src_rect->right; x++)
1303 src_val = *src_pixel++;
1304 *dst_pixel++ = put_field((src_val >> 16) & 0xff, dst->red_shift, dst->red_len) |
1305 put_field((src_val >> 8) & 0xff, dst->green_shift, dst->green_len) |
1306 put_field( src_val & 0xff, dst->blue_shift, dst->blue_len);
1308 if(pad_size) memset(dst_pixel, 0, pad_size);
1309 dst_start += dst->stride / 4;
1310 src_start += src->stride / 4;
1313 else if(bit_fields_match(src, dst))
1315 if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
1316 memcpy(dst->bits, src_start, (src_rect->bottom - src_rect->top) * src->stride);
1319 for(y = src_rect->top; y < src_rect->bottom; y++)
1321 memcpy(dst_start, src_start, (src_rect->right - src_rect->left) * 4);
1322 if(pad_size) memset(dst_start + (src_rect->right - src_rect->left), 0, pad_size);
1323 dst_start += dst->stride / 4;
1324 src_start += src->stride / 4;
1328 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8 &&
1329 dst->red_len == 8 && dst->green_len == 8 && dst->blue_len == 8)
1331 for(y = src_rect->top; y < src_rect->bottom; y++)
1333 dst_pixel = dst_start;
1334 src_pixel = src_start;
1335 for(x = src_rect->left; x < src_rect->right; x++)
1337 src_val = *src_pixel++;
1338 *dst_pixel++ = (((src_val >> src->red_shift) & 0xff) << dst->red_shift) |
1339 (((src_val >> src->green_shift) & 0xff) << dst->green_shift) |
1340 (((src_val >> src->blue_shift) & 0xff) << dst->blue_shift);
1342 if(pad_size) memset(dst_pixel, 0, pad_size);
1343 dst_start += dst->stride / 4;
1344 src_start += src->stride / 4;
1349 FIXME("Unsupported conversion: 32 (%08x, %08x, %08x) -> 32 (%08x, %08x, %08x)\n",
1350 src->red_mask, src->green_mask, src->blue_mask, dst->red_mask, dst->green_mask, dst->blue_mask);
1358 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
1360 for(y = src_rect->top; y < src_rect->bottom; y++)
1362 dst_pixel = dst_start;
1363 src_pixel = src_start;
1364 for(x = src_rect->left; x < src_rect->right; x++)
1367 rgb.rgbBlue = *src_pixel++;
1368 rgb.rgbGreen = *src_pixel++;
1369 rgb.rgbRed = *src_pixel++;
1371 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
1372 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
1373 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
1375 if(pad_size) memset(dst_pixel, 0, pad_size);
1376 dst_start += dst->stride / 4;
1377 src_start += src->stride;
1384 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
1385 if(src->funcs == &funcs_555)
1387 for(y = src_rect->top; y < src_rect->bottom; y++)
1389 dst_pixel = dst_start;
1390 src_pixel = src_start;
1391 for(x = src_rect->left; x < src_rect->right; x++)
1393 src_val = *src_pixel++;
1394 *dst_pixel++ = put_field(((src_val >> 7) & 0xf8) | ((src_val >> 12) & 0x07), dst->red_shift, dst->red_len) |
1395 put_field(((src_val >> 2) & 0xf8) | ((src_val >> 7) & 0x07), dst->green_shift, dst->green_len) |
1396 put_field(((src_val << 3) & 0xf8) | ((src_val >> 2) & 0x07), dst->blue_shift, dst->blue_len);
1398 if(pad_size) memset(dst_pixel, 0, pad_size);
1399 dst_start += dst->stride / 4;
1400 src_start += src->stride / 2;
1403 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
1405 for(y = src_rect->top; y < src_rect->bottom; y++)
1407 dst_pixel = dst_start;
1408 src_pixel = src_start;
1409 for(x = src_rect->left; x < src_rect->right; x++)
1411 src_val = *src_pixel++;
1412 *dst_pixel++ = put_field( (((src_val >> src->red_shift) << 3) & 0xf8) |
1413 (((src_val >> src->red_shift) >> 2) & 0x07), dst->red_shift, dst->red_len ) |
1414 put_field( (((src_val >> src->green_shift) << 3) & 0xf8) |
1415 (((src_val >> src->green_shift) >> 2) & 0x07), dst->green_shift, dst->green_len ) |
1416 put_field( (((src_val >> src->blue_shift) << 3) & 0xf8) |
1417 (((src_val >> src->blue_shift) >> 2) & 0x07), dst->blue_shift, dst->blue_len);
1419 if(pad_size) memset(dst_pixel, 0, pad_size);
1420 dst_start += dst->stride / 4;
1421 src_start += src->stride / 2;
1424 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
1426 for(y = src_rect->top; y < src_rect->bottom; y++)
1428 dst_pixel = dst_start;
1429 src_pixel = src_start;
1430 for(x = src_rect->left; x < src_rect->right; x++)
1432 src_val = *src_pixel++;
1433 *dst_pixel++ = put_field( (((src_val >> src->red_shift) << 3) & 0xf8) |
1434 (((src_val >> src->red_shift) >> 2) & 0x07), dst->red_shift, dst->red_len ) |
1435 put_field( (((src_val >> src->green_shift) << 2) & 0xfc) |
1436 (((src_val >> src->green_shift) >> 4) & 0x03), dst->green_shift, dst->green_len ) |
1437 put_field( (((src_val >> src->blue_shift) << 3) & 0xf8) |
1438 (((src_val >> src->blue_shift) >> 2) & 0x07), dst->blue_shift, dst->blue_len);
1440 if(pad_size) memset(dst_pixel, 0, pad_size);
1441 dst_start += dst->stride / 4;
1442 src_start += src->stride / 2;
1447 FIXME("Unsupported conversion: 16 (%08x, %08x, %08x) -> 32\n", src->red_mask, src->green_mask, src->blue_mask);
1455 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
1456 for(y = src_rect->top; y < src_rect->bottom; y++)
1458 dst_pixel = dst_start;
1459 src_pixel = src_start;
1460 for(x = src_rect->left; x < src_rect->right; x++)
1463 src_val = *src_pixel++;
1464 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
1465 rgb = src->color_table[src_val];
1466 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
1467 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
1468 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
1470 if(pad_size) memset(dst_pixel, 0, pad_size);
1471 dst_start += dst->stride / 4;
1472 src_start += src->stride;
1479 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
1480 for(y = src_rect->top; y < src_rect->bottom; y++)
1482 dst_pixel = dst_start;
1483 src_pixel = src_start;
1484 for(x = src_rect->left; x < src_rect->right; x++)
1488 src_val = *src_pixel++ & 0xf;
1490 src_val = (*src_pixel >> 4) & 0xf;
1491 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
1492 rgb = src->color_table[src_val];
1493 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
1494 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
1495 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
1497 if(pad_size) memset(dst_pixel, 0, pad_size);
1498 dst_start += dst->stride / 4;
1499 src_start += src->stride;
1506 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
1507 for(y = src_rect->top; y < src_rect->bottom; y++)
1509 dst_pixel = dst_start;
1510 src_pixel = src_start;
1511 for(x = src_rect->left; x < src_rect->right; x++)
1514 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
1515 if((x % 8) == 7) src_pixel++;
1516 rgb = src->color_table[src_val];
1517 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
1518 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
1519 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
1521 if(pad_size) memset(dst_pixel, 0, pad_size);
1522 dst_start += dst->stride / 4;
1523 src_start += src->stride;
1529 FIXME("Unsupported conversion: %d -> 32\n", src->bit_count);
1536 static BOOL convert_to_24(dib_info *dst, const dib_info *src, const RECT *src_rect)
1538 BYTE *dst_start = dst->bits, *dst_pixel;
1540 int x, y, pad_size = ((dst->width * 3 + 3) & ~3) - (src_rect->right - src_rect->left) * 3;
1542 switch(src->bit_count)
1546 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
1547 if(src->funcs == &funcs_8888)
1549 for(y = src_rect->top; y < src_rect->bottom; y++)
1551 dst_pixel = dst_start;
1552 src_pixel = src_start;
1553 for(x = src_rect->left; x < src_rect->right; x++)
1555 src_val = *src_pixel++;
1556 *dst_pixel++ = src_val & 0xff;
1557 *dst_pixel++ = (src_val >> 8) & 0xff;
1558 *dst_pixel++ = (src_val >> 16) & 0xff;
1560 if(pad_size) memset(dst_pixel, 0, pad_size);
1561 dst_start += dst->stride;
1562 src_start += src->stride / 4;
1565 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
1567 for(y = src_rect->top; y < src_rect->bottom; y++)
1569 dst_pixel = dst_start;
1570 src_pixel = src_start;
1571 for(x = src_rect->left; x < src_rect->right; x++)
1573 src_val = *src_pixel++;
1574 *dst_pixel++ = (src_val >> src->blue_shift) & 0xff;
1575 *dst_pixel++ = (src_val >> src->green_shift) & 0xff;
1576 *dst_pixel++ = (src_val >> src->red_shift) & 0xff;
1578 if(pad_size) memset(dst_pixel, 0, pad_size);
1579 dst_start += dst->stride;
1580 src_start += src->stride / 4;
1585 FIXME("Unsupported conversion: 32 (%08x, %08x, %08x) -> 24\n", src->red_mask, src->green_mask, src->blue_mask);
1593 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top);
1595 if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
1596 memcpy(dst->bits, src_start, (src_rect->bottom - src_rect->top) * src->stride);
1599 for(y = src_rect->top; y < src_rect->bottom; y++)
1601 memcpy(dst_start, src_start, (src_rect->right - src_rect->left) * 3);
1602 if(pad_size) memset(dst_start + (src_rect->right - src_rect->left) * 3, 0, pad_size);
1603 dst_start += dst->stride;
1604 src_start += src->stride;
1612 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
1613 if(src->funcs == &funcs_555)
1615 for(y = src_rect->top; y < src_rect->bottom; y++)
1617 dst_pixel = dst_start;
1618 src_pixel = src_start;
1619 for(x = src_rect->left; x < src_rect->right; x++)
1621 src_val = *src_pixel++;
1622 *dst_pixel++ = ((src_val << 3) & 0xf8) | ((src_val >> 2) & 0x07);
1623 *dst_pixel++ = ((src_val >> 2) & 0xf8) | ((src_val >> 7) & 0x07);
1624 *dst_pixel++ = ((src_val >> 7) & 0xf8) | ((src_val >> 12) & 0x07);
1626 if(pad_size) memset(dst_pixel, 0, pad_size);
1627 dst_start += dst->stride;
1628 src_start += src->stride / 2;
1631 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
1633 for(y = src_rect->top; y < src_rect->bottom; y++)
1635 dst_pixel = dst_start;
1636 src_pixel = src_start;
1637 for(x = src_rect->left; x < src_rect->right; x++)
1639 src_val = *src_pixel++;
1640 *dst_pixel++ = (((src_val >> src->blue_shift) << 3) & 0xf8) |
1641 (((src_val >> src->blue_shift) >> 2) & 0x07);
1642 *dst_pixel++ = (((src_val >> src->green_shift) << 3) & 0xf8) |
1643 (((src_val >> src->green_shift) >> 2) & 0x07);
1644 *dst_pixel++ = (((src_val >> src->red_shift) << 3) & 0xf8) |
1645 (((src_val >> src->red_shift) >> 2) & 0x07);
1647 if(pad_size) memset(dst_pixel, 0, pad_size);
1648 dst_start += dst->stride;
1649 src_start += src->stride / 2;
1652 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
1654 for(y = src_rect->top; y < src_rect->bottom; y++)
1656 dst_pixel = dst_start;
1657 src_pixel = src_start;
1658 for(x = src_rect->left; x < src_rect->right; x++)
1660 src_val = *src_pixel++;
1661 *dst_pixel++ = (((src_val >> src->blue_shift) << 3) & 0xf8) |
1662 (((src_val >> src->blue_shift) >> 2) & 0x07);
1663 *dst_pixel++ = (((src_val >> src->green_shift) << 2) & 0xfc) |
1664 (((src_val >> src->green_shift) >> 4) & 0x03);
1665 *dst_pixel++ = (((src_val >> src->red_shift) << 3) & 0xf8) |
1666 (((src_val >> src->red_shift) >> 2) & 0x07);
1668 if(pad_size) memset(dst_pixel, 0, pad_size);
1669 dst_start += dst->stride;
1670 src_start += src->stride / 2;
1675 FIXME("Unsupported conversion: 16 (%08x, %08x, %08x) -> 24\n", src->red_mask, src->green_mask, src->blue_mask);
1683 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
1684 for(y = src_rect->top; y < src_rect->bottom; y++)
1686 dst_pixel = dst_start;
1687 src_pixel = src_start;
1688 for(x = src_rect->left; x < src_rect->right; x++)
1691 src_val = *src_pixel++;
1692 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
1693 rgb = src->color_table[src_val];
1694 *dst_pixel++ = rgb.rgbBlue;
1695 *dst_pixel++ = rgb.rgbGreen;
1696 *dst_pixel++ = rgb.rgbRed;
1698 if(pad_size) memset(dst_pixel, 0, pad_size);
1699 dst_start += dst->stride;
1700 src_start += src->stride;
1707 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
1708 for(y = src_rect->top; y < src_rect->bottom; y++)
1710 dst_pixel = dst_start;
1711 src_pixel = src_start;
1712 for(x = src_rect->left; x < src_rect->right; x++)
1716 src_val = *src_pixel++ & 0xf;
1718 src_val = (*src_pixel >> 4) & 0xf;
1719 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
1720 rgb = src->color_table[src_val];
1721 *dst_pixel++ = rgb.rgbBlue;
1722 *dst_pixel++ = rgb.rgbGreen;
1723 *dst_pixel++ = rgb.rgbRed;
1725 if(pad_size) memset(dst_pixel, 0, pad_size);
1726 dst_start += dst->stride;
1727 src_start += src->stride;
1734 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
1735 for(y = src_rect->top; y < src_rect->bottom; y++)
1737 dst_pixel = dst_start;
1738 src_pixel = src_start;
1739 for(x = src_rect->left; x < src_rect->right; x++)
1742 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
1743 if((x % 8) == 7) src_pixel++;
1744 rgb = src->color_table[src_val];
1745 *dst_pixel++ = rgb.rgbBlue;
1746 *dst_pixel++ = rgb.rgbGreen;
1747 *dst_pixel++ = rgb.rgbRed;
1749 if(pad_size) memset(dst_pixel, 0, pad_size);
1750 dst_start += dst->stride;
1751 src_start += src->stride;
1757 FIXME("Unsupported conversion: %d -> 24\n", src->bit_count);
1764 static BOOL convert_to_555(dib_info *dst, const dib_info *src, const RECT *src_rect)
1766 WORD *dst_start = dst->bits, *dst_pixel;
1767 INT x, y, pad_size = ((dst->width + 1) & ~1) * 2 - (src_rect->right - src_rect->left) * 2;
1770 switch(src->bit_count)
1774 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
1776 if(src->funcs == &funcs_8888)
1778 for(y = src_rect->top; y < src_rect->bottom; y++)
1780 dst_pixel = dst_start;
1781 src_pixel = src_start;
1782 for(x = src_rect->left; x < src_rect->right; x++)
1784 src_val = *src_pixel++;
1785 *dst_pixel++ = ((src_val >> 9) & 0x7c00) |
1786 ((src_val >> 6) & 0x03e0) |
1787 ((src_val >> 3) & 0x001f);
1789 if(pad_size) memset(dst_pixel, 0, pad_size);
1790 dst_start += dst->stride / 2;
1791 src_start += src->stride / 4;
1794 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
1796 for(y = src_rect->top; y < src_rect->bottom; y++)
1798 dst_pixel = dst_start;
1799 src_pixel = src_start;
1800 for(x = src_rect->left; x < src_rect->right; x++)
1802 src_val = *src_pixel++;
1803 *dst_pixel++ = (((src_val >> src->red_shift) << 7) & 0x7c00) |
1804 (((src_val >> src->green_shift) << 2) & 0x03e0) |
1805 (((src_val >> src->blue_shift) >> 3) & 0x001f);
1807 if(pad_size) memset(dst_pixel, 0, pad_size);
1808 dst_start += dst->stride / 2;
1809 src_start += src->stride / 4;
1814 FIXME("Unsupported conversion: 32 (%08x, %08x, %08x) -> 555\n", src->red_mask, src->green_mask, src->blue_mask);
1822 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
1824 for(y = src_rect->top; y < src_rect->bottom; y++)
1826 dst_pixel = dst_start;
1827 src_pixel = src_start;
1828 for(x = src_rect->left; x < src_rect->right; x++)
1831 rgb.rgbBlue = *src_pixel++;
1832 rgb.rgbGreen = *src_pixel++;
1833 rgb.rgbRed = *src_pixel++;
1835 *dst_pixel++ = ((rgb.rgbRed << 7) & 0x7c00) |
1836 ((rgb.rgbGreen << 2) & 0x03e0) |
1837 ((rgb.rgbBlue >> 3) & 0x001f);
1839 if(pad_size) memset(dst_pixel, 0, pad_size);
1840 dst_start += dst->stride / 2;
1841 src_start += src->stride;
1848 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
1849 if(src->funcs == &funcs_555)
1851 if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
1852 memcpy(dst->bits, src_start, (src_rect->bottom - src_rect->top) * src->stride);
1855 for(y = src_rect->top; y < src_rect->bottom; y++)
1857 memcpy(dst_start, src_start, (src_rect->right - src_rect->left) * 2);
1858 if(pad_size) memset(dst_start + (src_rect->right - src_rect->left), 0, pad_size);
1859 dst_start += dst->stride / 2;
1860 src_start += src->stride / 2;
1864 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
1866 for(y = src_rect->top; y < src_rect->bottom; y++)
1868 dst_pixel = dst_start;
1869 src_pixel = src_start;
1870 for(x = src_rect->left; x < src_rect->right; x++)
1872 src_val = *src_pixel++;
1873 *dst_pixel++ = (((src_val >> src->red_shift) << 10) & 0x7c00) |
1874 (((src_val >> src->green_shift) << 5) & 0x03e0) |
1875 ( (src_val >> src->blue_shift) & 0x001f);
1877 if(pad_size) memset(dst_pixel, 0, pad_size);
1878 dst_start += dst->stride / 2;
1879 src_start += src->stride / 2;
1882 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
1884 for(y = src_rect->top; y < src_rect->bottom; y++)
1886 dst_pixel = dst_start;
1887 src_pixel = src_start;
1888 for(x = src_rect->left; x < src_rect->right; x++)
1890 src_val = *src_pixel++;
1891 *dst_pixel++ = (((src_val >> src->red_shift) << 10) & 0x7c00) |
1892 (((src_val >> src->green_shift) << 4) & 0x03e0) |
1893 ( (src_val >> src->blue_shift) & 0x001f);
1895 if(pad_size) memset(dst_pixel, 0, pad_size);
1896 dst_start += dst->stride / 2;
1897 src_start += src->stride / 2;
1902 FIXME("Unsupported conversion: 16 (%08x, %08x, %08x) -> 555\n", src->red_mask, src->green_mask, src->blue_mask);
1910 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
1911 for(y = src_rect->top; y < src_rect->bottom; y++)
1913 dst_pixel = dst_start;
1914 src_pixel = src_start;
1915 for(x = src_rect->left; x < src_rect->right; x++)
1918 src_val = *src_pixel++;
1919 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
1920 rgb = src->color_table[src_val];
1921 *dst_pixel++ = ((rgb.rgbRed << 7) & 0x7c00) |
1922 ((rgb.rgbGreen << 2) & 0x03e0) |
1923 ((rgb.rgbBlue >> 3) & 0x001f);
1925 if(pad_size) memset(dst_pixel, 0, pad_size);
1926 dst_start += dst->stride / 2;
1927 src_start += src->stride;
1934 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
1935 for(y = src_rect->top; y < src_rect->bottom; y++)
1937 dst_pixel = dst_start;
1938 src_pixel = src_start;
1939 for(x = src_rect->left; x < src_rect->right; x++)
1943 src_val = *src_pixel++ & 0xf;
1945 src_val = (*src_pixel >> 4) & 0xf;
1946 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
1947 rgb = src->color_table[src_val];
1948 *dst_pixel++ = ((rgb.rgbRed << 7) & 0x7c00) |
1949 ((rgb.rgbGreen << 2) & 0x03e0) |
1950 ((rgb.rgbBlue >> 3) & 0x001f);
1952 if(pad_size) memset(dst_pixel, 0, pad_size);
1953 dst_start += dst->stride / 2;
1954 src_start += src->stride;
1961 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
1962 for(y = src_rect->top; y < src_rect->bottom; y++)
1964 dst_pixel = dst_start;
1965 src_pixel = src_start;
1966 for(x = src_rect->left; x < src_rect->right; x++)
1969 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
1970 if((x % 8) == 7) src_pixel++;
1971 rgb = src->color_table[src_val];
1972 *dst_pixel++ = ((rgb.rgbRed << 7) & 0x7c00) |
1973 ((rgb.rgbGreen << 2) & 0x03e0) |
1974 ((rgb.rgbBlue >> 3) & 0x001f);
1976 if(pad_size) memset(dst_pixel, 0, pad_size);
1977 dst_start += dst->stride / 2;
1978 src_start += src->stride;
1984 FIXME("Unsupported conversion: %d -> 555\n", src->bit_count);
1991 static BOOL convert_to_16(dib_info *dst, const dib_info *src, const RECT *src_rect)
1993 WORD *dst_start = dst->bits, *dst_pixel;
1994 INT x, y, pad_size = ((dst->width + 1) & ~1) * 2 - (src_rect->right - src_rect->left) * 2;
1997 switch(src->bit_count)
2001 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
2003 if(src->funcs == &funcs_8888)
2005 for(y = src_rect->top; y < src_rect->bottom; y++)
2007 dst_pixel = dst_start;
2008 src_pixel = src_start;
2009 for(x = src_rect->left; x < src_rect->right; x++)
2011 src_val = *src_pixel++;
2012 *dst_pixel++ = put_field((src_val >> 16) & 0xff, dst->red_shift, dst->red_len) |
2013 put_field((src_val >> 8) & 0xff, dst->green_shift, dst->green_len) |
2014 put_field( src_val & 0xff, dst->blue_shift, dst->blue_len);
2016 if(pad_size) memset(dst_pixel, 0, pad_size);
2017 dst_start += dst->stride / 2;
2018 src_start += src->stride / 4;
2021 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
2023 for(y = src_rect->top; y < src_rect->bottom; y++)
2025 dst_pixel = dst_start;
2026 src_pixel = src_start;
2027 for(x = src_rect->left; x < src_rect->right; x++)
2029 src_val = *src_pixel++;
2030 *dst_pixel++ = put_field((src_val >> src->red_shift) & 0xff, dst->red_shift, dst->red_len) |
2031 put_field((src_val >> src->green_shift) & 0xff, dst->green_shift, dst->green_len) |
2032 put_field((src_val >> src->blue_shift) & 0xff, dst->blue_shift, dst->blue_len);
2034 if(pad_size) memset(dst_pixel, 0, pad_size);
2035 dst_start += dst->stride / 2;
2036 src_start += src->stride / 4;
2041 FIXME("Unsupported conversion: 32 (%08x, %08x, %08x) -> 16\n", src->red_mask, src->green_mask, src->blue_mask);
2049 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
2051 for(y = src_rect->top; y < src_rect->bottom; y++)
2053 dst_pixel = dst_start;
2054 src_pixel = src_start;
2055 for(x = src_rect->left; x < src_rect->right; x++)
2058 rgb.rgbBlue = *src_pixel++;
2059 rgb.rgbGreen = *src_pixel++;
2060 rgb.rgbRed = *src_pixel++;
2062 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
2063 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
2064 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
2066 if(pad_size) memset(dst_pixel, 0, pad_size);
2067 dst_start += dst->stride / 2;
2068 src_start += src->stride;
2075 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
2076 if(src->funcs == &funcs_555)
2078 for(y = src_rect->top; y < src_rect->bottom; y++)
2080 dst_pixel = dst_start;
2081 src_pixel = src_start;
2082 for(x = src_rect->left; x < src_rect->right; x++)
2084 src_val = *src_pixel++;
2085 *dst_pixel++ = put_field(((src_val >> 7) & 0xf8) | ((src_val >> 12) & 0x07), dst->red_shift, dst->red_len) |
2086 put_field(((src_val >> 2) & 0xf8) | ((src_val >> 7) & 0x07), dst->green_shift, dst->green_len) |
2087 put_field(((src_val << 3) & 0xf8) | ((src_val >> 2) & 0x07), dst->blue_shift, dst->blue_len);
2089 if(pad_size) memset(dst_pixel, 0, pad_size);
2090 dst_start += dst->stride / 2;
2091 src_start += src->stride / 2;
2094 else if(bit_fields_match(src, dst))
2096 if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
2097 memcpy(dst->bits, src_start, (src_rect->bottom - src_rect->top) * src->stride);
2100 for(y = src_rect->top; y < src_rect->bottom; y++)
2102 memcpy(dst_start, src_start, (src_rect->right - src_rect->left) * 2);
2103 if(pad_size) memset(dst_start + (src_rect->right - src_rect->left), 0, pad_size);
2104 dst_start += dst->stride / 2;
2105 src_start += src->stride / 2;
2109 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
2111 for(y = src_rect->top; y < src_rect->bottom; y++)
2113 dst_pixel = dst_start;
2114 src_pixel = src_start;
2115 for(x = src_rect->left; x < src_rect->right; x++)
2117 src_val = *src_pixel++;
2118 *dst_pixel++ = put_field( (((src_val >> src->red_shift) << 3) & 0xf8) |
2119 (((src_val >> src->red_shift) >> 2) & 0x07), dst->red_shift, dst->red_len ) |
2120 put_field( (((src_val >> src->green_shift) << 3) & 0xf8) |
2121 (((src_val >> src->green_shift) >> 2) & 0x07), dst->green_shift, dst->green_len ) |
2122 put_field( (((src_val >> src->blue_shift) << 3) & 0xf8) |
2123 (((src_val >> src->blue_shift) >> 2) & 0x07), dst->blue_shift, dst->blue_len);
2125 if(pad_size) memset(dst_pixel, 0, pad_size);
2126 dst_start += dst->stride / 2;
2127 src_start += src->stride / 2;
2130 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
2132 for(y = src_rect->top; y < src_rect->bottom; y++)
2134 dst_pixel = dst_start;
2135 src_pixel = src_start;
2136 for(x = src_rect->left; x < src_rect->right; x++)
2138 src_val = *src_pixel++;
2139 *dst_pixel++ = put_field( (((src_val >> src->red_shift) << 3) & 0xf8) |
2140 (((src_val >> src->red_shift) >> 2) & 0x07), dst->red_shift, dst->red_len ) |
2141 put_field( (((src_val >> src->green_shift) << 2) & 0xfc) |
2142 (((src_val >> src->green_shift) >> 4) & 0x03), dst->green_shift, dst->green_len ) |
2143 put_field( (((src_val >> src->blue_shift) << 3) & 0xf8) |
2144 (((src_val >> src->blue_shift) >> 2) & 0x07), dst->blue_shift, dst->blue_len);
2146 if(pad_size) memset(dst_pixel, 0, pad_size);
2147 dst_start += dst->stride / 2;
2148 src_start += src->stride / 2;
2153 FIXME("Unsupported conversion: 16 (%08x, %08x, %08x) -> 16 (%08x, %08x, %08x)\n",
2154 src->red_mask, src->green_mask, src->blue_mask, dst->red_mask, dst->green_mask, dst->blue_mask);
2162 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
2163 for(y = src_rect->top; y < src_rect->bottom; y++)
2165 dst_pixel = dst_start;
2166 src_pixel = src_start;
2167 for(x = src_rect->left; x < src_rect->right; x++)
2170 src_val = *src_pixel++;
2171 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
2172 rgb = src->color_table[src_val];
2173 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
2174 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
2175 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
2177 if(pad_size) memset(dst_pixel, 0, pad_size);
2178 dst_start += dst->stride / 2;
2179 src_start += src->stride;
2186 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
2187 for(y = src_rect->top; y < src_rect->bottom; y++)
2189 dst_pixel = dst_start;
2190 src_pixel = src_start;
2191 for(x = src_rect->left; x < src_rect->right; x++)
2195 src_val = *src_pixel++ & 0xf;
2197 src_val = (*src_pixel >> 4) & 0xf;
2198 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
2199 rgb = src->color_table[src_val];
2200 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
2201 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
2202 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
2204 if(pad_size) memset(dst_pixel, 0, pad_size);
2205 dst_start += dst->stride / 2;
2206 src_start += src->stride;
2213 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
2214 for(y = src_rect->top; y < src_rect->bottom; y++)
2216 dst_pixel = dst_start;
2217 src_pixel = src_start;
2218 for(x = src_rect->left; x < src_rect->right; x++)
2221 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
2222 if((x % 8) == 7) src_pixel++;
2223 rgb = src->color_table[src_val];
2224 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
2225 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
2226 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
2228 if(pad_size) memset(dst_pixel, 0, pad_size);
2229 dst_start += dst->stride / 2;
2230 src_start += src->stride;
2236 FIXME("Unsupported conversion: %d -> 16\n", src->bit_count);
2243 static inline BOOL color_tables_match(const dib_info *d1, const dib_info *d2)
2245 assert(d1->color_table_size && d2->color_table_size);
2247 if(d1->color_table_size != d2->color_table_size) return FALSE;
2248 return !memcmp(d1->color_table, d2->color_table, d1->color_table_size * sizeof(d1->color_table[0]));
2251 static BOOL convert_to_8(dib_info *dst, const dib_info *src, const RECT *src_rect)
2253 BYTE *dst_start = dst->bits, *dst_pixel;
2254 INT x, y, pad_size = ((dst->width + 3) & ~3) - (src_rect->right - src_rect->left);
2257 switch(src->bit_count)
2261 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
2263 if(src->funcs == &funcs_8888)
2265 for(y = src_rect->top; y < src_rect->bottom; y++)
2267 dst_pixel = dst_start;
2268 src_pixel = src_start;
2269 for(x = src_rect->left; x < src_rect->right; x++)
2271 src_val = *src_pixel++;
2272 *dst_pixel++ = colorref_to_pixel_colortable(dst, ((src_val >> 16) & 0x0000ff) |
2273 ( src_val & 0x00ff00) |
2274 ((src_val << 16) & 0xff0000) );
2276 if(pad_size) memset(dst_pixel, 0, pad_size);
2277 dst_start += dst->stride;
2278 src_start += src->stride / 4;
2281 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
2283 for(y = src_rect->top; y < src_rect->bottom; y++)
2285 dst_pixel = dst_start;
2286 src_pixel = src_start;
2287 for(x = src_rect->left; x < src_rect->right; x++)
2289 src_val = *src_pixel++;
2290 *dst_pixel++ = colorref_to_pixel_colortable(dst, ( (src_val >> src->red_shift) & 0x0000ff) |
2291 (((src_val >> src->green_shift) << 8) & 0x00ff00) |
2292 (((src_val >> src->blue_shift) << 16) & 0xff0000) );
2294 if(pad_size) memset(dst_pixel, 0, pad_size);
2295 dst_start += dst->stride;
2296 src_start += src->stride / 4;
2301 FIXME("Unsupported conversion: 32 (%08x, %08x, %08x) -> 8\n", src->red_mask, src->green_mask, src->blue_mask);
2309 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
2311 for(y = src_rect->top; y < src_rect->bottom; y++)
2313 dst_pixel = dst_start;
2314 src_pixel = src_start;
2315 for(x = src_rect->left; x < src_rect->right; x++)
2318 rgb.rgbBlue = *src_pixel++;
2319 rgb.rgbGreen = *src_pixel++;
2320 rgb.rgbRed = *src_pixel++;
2322 *dst_pixel++ = colorref_to_pixel_colortable(dst, ( rgb.rgbRed & 0x0000ff) |
2323 ((rgb.rgbGreen << 8) & 0x00ff00) |
2324 ((rgb.rgbBlue << 16) & 0xff0000));
2326 if(pad_size) memset(dst_pixel, 0, pad_size);
2327 dst_start += dst->stride;
2328 src_start += src->stride;
2335 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
2336 if(src->funcs == &funcs_555)
2338 for(y = src_rect->top; y < src_rect->bottom; y++)
2340 dst_pixel = dst_start;
2341 src_pixel = src_start;
2342 for(x = src_rect->left; x < src_rect->right; x++)
2344 src_val = *src_pixel++;
2345 *dst_pixel++ = colorref_to_pixel_colortable(dst, ((src_val >> 7) & 0x0000f8) | ((src_val >> 12) & 0x000007) |
2346 ((src_val << 6) & 0x00f800) | ((src_val << 1) & 0x000700) |
2347 ((src_val << 19) & 0xf80000) | ((src_val << 14) & 0x070000) );
2349 if(pad_size) memset(dst_pixel, 0, pad_size);
2350 dst_start += dst->stride;
2351 src_start += src->stride / 2;
2354 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
2356 for(y = src_rect->top; y < src_rect->bottom; y++)
2358 dst_pixel = dst_start;
2359 src_pixel = src_start;
2360 for(x = src_rect->left; x < src_rect->right; x++)
2362 src_val = *src_pixel++;
2363 *dst_pixel++ = colorref_to_pixel_colortable(dst, (((src_val >> src->red_shift) << 3) & 0x0000f8) |
2364 (((src_val >> src->red_shift) >> 2) & 0x000007) |
2365 (((src_val >> src->green_shift) << 11) & 0x00f800) |
2366 (((src_val >> src->green_shift) << 6) & 0x000700) |
2367 (((src_val >> src->blue_shift) << 19) & 0xf80000) |
2368 (((src_val >> src->blue_shift) << 14) & 0x070000) );
2370 if(pad_size) memset(dst_pixel, 0, pad_size);
2371 dst_start += dst->stride;
2372 src_start += src->stride / 2;
2375 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
2377 for(y = src_rect->top; y < src_rect->bottom; y++)
2379 dst_pixel = dst_start;
2380 src_pixel = src_start;
2381 for(x = src_rect->left; x < src_rect->right; x++)
2383 src_val = *src_pixel++;
2384 *dst_pixel++ = colorref_to_pixel_colortable(dst, (((src_val >> src->red_shift) << 3) & 0x0000f8) |
2385 (((src_val >> src->red_shift) >> 2) & 0x000007) |
2386 (((src_val >> src->green_shift) << 10) & 0x00fc00) |
2387 (((src_val >> src->green_shift) << 4) & 0x000300) |
2388 (((src_val >> src->blue_shift) << 19) & 0xf80000) |
2389 (((src_val >> src->blue_shift) << 14) & 0x070000) );
2391 if(pad_size) memset(dst_pixel, 0, pad_size);
2392 dst_start += dst->stride;
2393 src_start += src->stride / 2;
2398 FIXME("Unsupported conversion: 16 (%08x, %08x, %08x) -> 8\n", src->red_mask, src->green_mask, src->blue_mask);
2406 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
2408 if(color_tables_match(dst, src))
2410 if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
2411 memcpy(dst->bits, src_start, (src_rect->bottom - src_rect->top) * src->stride);
2414 for(y = src_rect->top; y < src_rect->bottom; y++)
2416 memcpy(dst_start, src_start, src_rect->right - src_rect->left);
2417 if(pad_size) memset(dst_start + (src_rect->right - src_rect->left), 0, pad_size);
2418 dst_start += dst->stride;
2419 src_start += src->stride;
2425 for(y = src_rect->top; y < src_rect->bottom; y++)
2427 dst_pixel = dst_start;
2428 src_pixel = src_start;
2429 for(x = src_rect->left; x < src_rect->right; x++)
2432 src_val = *src_pixel++;
2433 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
2434 rgb = src->color_table[src_val];
2435 *dst_pixel++ = colorref_to_pixel_colortable(dst, RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue));
2437 if(pad_size) memset(dst_pixel, 0, pad_size);
2438 dst_start += dst->stride;
2439 src_start += src->stride;
2447 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
2448 for(y = src_rect->top; y < src_rect->bottom; y++)
2450 dst_pixel = dst_start;
2451 src_pixel = src_start;
2452 for(x = src_rect->left; x < src_rect->right; x++)
2456 src_val = *src_pixel++ & 0xf;
2458 src_val = (*src_pixel >> 4) & 0xf;
2459 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
2460 rgb = src->color_table[src_val];
2461 *dst_pixel++ = colorref_to_pixel_colortable(dst, RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue));
2463 if(pad_size) memset(dst_pixel, 0, pad_size);
2464 dst_start += dst->stride;
2465 src_start += src->stride;
2472 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
2473 for(y = src_rect->top; y < src_rect->bottom; y++)
2475 dst_pixel = dst_start;
2476 src_pixel = src_start;
2477 for(x = src_rect->left; x < src_rect->right; x++)
2480 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
2481 if((x % 8) == 7) src_pixel++;
2482 rgb = src->color_table[src_val];
2483 *dst_pixel++ = colorref_to_pixel_colortable(dst, RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue));
2485 if(pad_size) memset(dst_pixel, 0, pad_size);
2486 dst_start += dst->stride;
2487 src_start += src->stride;
2493 FIXME("Unsupported conversion: %d -> 8\n", src->bit_count);
2500 static BOOL convert_to_4(dib_info *dst, const dib_info *src, const RECT *src_rect)
2502 BYTE *dst_start = dst->bits, *dst_pixel, dst_val;
2503 INT x, y, pad_size = ((dst->width + 7) & ~7) / 2 - (src_rect->right - src_rect->left + 1) / 2;
2506 switch(src->bit_count)
2510 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
2512 if(src->funcs == &funcs_8888)
2514 for(y = src_rect->top; y < src_rect->bottom; y++)
2516 dst_pixel = dst_start;
2517 src_pixel = src_start;
2518 for(x = src_rect->left; x < src_rect->right; x++)
2520 src_val = *src_pixel++;
2521 dst_val = colorref_to_pixel_colortable(dst, ((src_val >> 16) & 0x0000ff) |
2522 ( src_val & 0x00ff00) |
2523 ((src_val << 16) & 0xff0000) );
2524 if((x - src_rect->left) & 1)
2526 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
2530 *dst_pixel = (dst_val << 4) & 0xf0;
2534 if((x - src_rect->left) & 1) dst_pixel++;
2535 memset(dst_pixel, 0, pad_size);
2537 dst_start += dst->stride;
2538 src_start += src->stride / 4;
2541 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
2543 for(y = src_rect->top; y < src_rect->bottom; y++)
2545 dst_pixel = dst_start;
2546 src_pixel = src_start;
2547 for(x = src_rect->left; x < src_rect->right; x++)
2549 src_val = *src_pixel++;
2550 dst_val = colorref_to_pixel_colortable(dst, ( (src_val >> src->red_shift) & 0x0000ff) |
2551 (((src_val >> src->green_shift) << 8) & 0x00ff00) |
2552 (((src_val >> src->blue_shift) << 16) & 0xff0000) );
2553 if((x - src_rect->left) & 1)
2555 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
2559 *dst_pixel = (dst_val << 4) & 0xf0;
2563 if((x - src_rect->left) & 1) dst_pixel++;
2564 memset(dst_pixel, 0, pad_size);
2566 dst_start += dst->stride;
2567 src_start += src->stride / 4;
2572 FIXME("Unsupported conversion: 32 (%08x, %08x, %08x) -> 4\n", src->red_mask, src->green_mask, src->blue_mask);
2580 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
2582 for(y = src_rect->top; y < src_rect->bottom; y++)
2584 dst_pixel = dst_start;
2585 src_pixel = src_start;
2586 for(x = src_rect->left; x < src_rect->right; x++)
2589 rgb.rgbBlue = *src_pixel++;
2590 rgb.rgbGreen = *src_pixel++;
2591 rgb.rgbRed = *src_pixel++;
2593 dst_val = colorref_to_pixel_colortable(dst, ( rgb.rgbRed & 0x0000ff) |
2594 ((rgb.rgbGreen << 8) & 0x00ff00) |
2595 ((rgb.rgbBlue << 16) & 0xff0000));
2597 if((x - src_rect->left) & 1)
2599 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
2603 *dst_pixel = (dst_val << 4) & 0xf0;
2607 if((x - src_rect->left) & 1) dst_pixel++;
2608 memset(dst_pixel, 0, pad_size);
2610 dst_start += dst->stride;
2611 src_start += src->stride;
2618 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
2619 if(src->funcs == &funcs_555)
2621 for(y = src_rect->top; y < src_rect->bottom; y++)
2623 dst_pixel = dst_start;
2624 src_pixel = src_start;
2625 for(x = src_rect->left; x < src_rect->right; x++)
2627 src_val = *src_pixel++;
2628 dst_val = colorref_to_pixel_colortable(dst, ((src_val >> 7) & 0x0000f8) | ((src_val >> 12) & 0x000007) |
2629 ((src_val << 6) & 0x00f800) | ((src_val << 1) & 0x000700) |
2630 ((src_val << 19) & 0xf80000) | ((src_val << 14) & 0x070000) );
2631 if((x - src_rect->left) & 1)
2633 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
2637 *dst_pixel = (dst_val << 4) & 0xf0;
2641 if((x - src_rect->left) & 1) dst_pixel++;
2642 memset(dst_pixel, 0, pad_size);
2644 dst_start += dst->stride;
2645 src_start += src->stride / 2;
2648 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
2650 for(y = src_rect->top; y < src_rect->bottom; y++)
2652 dst_pixel = dst_start;
2653 src_pixel = src_start;
2654 for(x = src_rect->left; x < src_rect->right; x++)
2656 src_val = *src_pixel++;
2657 dst_val = colorref_to_pixel_colortable(dst, (((src_val >> src->red_shift) << 3) & 0x0000f8) |
2658 (((src_val >> src->red_shift) >> 2) & 0x000007) |
2659 (((src_val >> src->green_shift) << 11) & 0x00f800) |
2660 (((src_val >> src->green_shift) << 6) & 0x000700) |
2661 (((src_val >> src->blue_shift) << 19) & 0xf80000) |
2662 (((src_val >> src->blue_shift) << 14) & 0x070000) );
2663 if((x - src_rect->left) & 1)
2665 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
2669 *dst_pixel = (dst_val << 4) & 0xf0;
2673 if((x - src_rect->left) & 1) dst_pixel++;
2674 memset(dst_pixel, 0, pad_size);
2676 dst_start += dst->stride;
2677 src_start += src->stride / 2;
2680 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
2682 for(y = src_rect->top; y < src_rect->bottom; y++)
2684 dst_pixel = dst_start;
2685 src_pixel = src_start;
2686 for(x = src_rect->left; x < src_rect->right; x++)
2688 src_val = *src_pixel++;
2689 dst_val = colorref_to_pixel_colortable(dst, (((src_val >> src->red_shift) << 3) & 0x0000f8) |
2690 (((src_val >> src->red_shift) >> 2) & 0x000007) |
2691 (((src_val >> src->green_shift) << 10) & 0x00fc00) |
2692 (((src_val >> src->green_shift) << 4) & 0x000300) |
2693 (((src_val >> src->blue_shift) << 19) & 0xf80000) |
2694 (((src_val >> src->blue_shift) << 14) & 0x070000) );
2695 if((x - src_rect->left) & 1)
2697 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
2701 *dst_pixel = (dst_val << 4) & 0xf0;
2705 if((x - src_rect->left) & 1) dst_pixel++;
2706 memset(dst_pixel, 0, pad_size);
2708 dst_start += dst->stride;
2709 src_start += src->stride / 2;
2714 FIXME("Unsupported conversion: 16 (%08x, %08x, %08x) -> 4\n", src->red_mask, src->green_mask, src->blue_mask);
2722 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
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++)
2731 src_val = *src_pixel++;
2732 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
2733 rgb = src->color_table[src_val];
2734 dst_val = colorref_to_pixel_colortable(dst, RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue));
2735 if((x - src_rect->left) & 1)
2737 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
2741 *dst_pixel = (dst_val << 4) & 0xf0;
2745 if((x - src_rect->left) & 1) dst_pixel++;
2746 memset(dst_pixel, 0, pad_size);
2748 dst_start += dst->stride;
2749 src_start += src->stride;
2756 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
2758 if(color_tables_match(dst, src) && (src_rect->left & 1) == 0)
2760 if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
2761 memcpy(dst->bits, src_start, (src_rect->bottom - src_rect->top) * src->stride);
2764 for(y = src_rect->top; y < src_rect->bottom; y++)
2766 memcpy(dst_start, src_start, (src_rect->right - src_rect->left + 1) / 2);
2767 if(pad_size) memset(dst_start + (src_rect->right - src_rect->left + 1) / 2, 0, pad_size);
2768 dst_start += dst->stride;
2769 src_start += src->stride;
2775 for(y = src_rect->top; y < src_rect->bottom; y++)
2777 dst_pixel = dst_start;
2778 src_pixel = src_start;
2779 for(x = src_rect->left; x < src_rect->right; x++)
2783 src_val = *src_pixel++ & 0xf;
2785 src_val = (*src_pixel >> 4) & 0xf;
2786 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
2787 rgb = src->color_table[src_val];
2788 dst_val = colorref_to_pixel_colortable(dst, RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue));
2789 if((x - src_rect->left) & 1)
2791 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
2795 *dst_pixel = (dst_val << 4) & 0xf0;
2799 if((x - src_rect->left) & 1) dst_pixel++;
2800 memset(dst_pixel, 0, pad_size);
2802 dst_start += dst->stride;
2803 src_start += src->stride;
2811 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
2812 for(y = src_rect->top; y < src_rect->bottom; y++)
2814 dst_pixel = dst_start;
2815 src_pixel = src_start;
2816 for(x = src_rect->left; x < src_rect->right; x++)
2819 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
2820 if((x % 8) == 7) src_pixel++;
2821 rgb = src->color_table[src_val];
2822 dst_val = colorref_to_pixel_colortable(dst, RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue));
2823 if((x - src_rect->left) & 1)
2825 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
2829 *dst_pixel = (dst_val << 4) & 0xf0;
2833 if((x - src_rect->left) & 1) dst_pixel++;
2834 memset(dst_pixel, 0, pad_size);
2836 dst_start += dst->stride;
2837 src_start += src->stride;
2843 FIXME("Unsupported conversion: %d -> 4\n", src->bit_count);
2851 static BOOL convert_to_1(dib_info *dst, const dib_info *src, const RECT *src_rect)
2853 BYTE *dst_start = dst->bits, *dst_pixel, dst_val;
2854 INT x, y, pad_size = ((dst->width + 31) & ~31) / 8 - (src_rect->right - src_rect->left + 7) / 8;
2858 /* FIXME: Brushes should be dithered. */
2860 switch(src->bit_count)
2864 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
2866 if(src->funcs == &funcs_8888)
2868 for(y = src_rect->top; y < src_rect->bottom; y++)
2870 dst_pixel = dst_start;
2871 src_pixel = src_start;
2872 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
2874 src_val = *src_pixel++;
2875 dst_val = colorref_to_pixel_colortable(dst, ((src_val >> 16) & 0x0000ff) |
2876 ( src_val & 0x00ff00) |
2877 ((src_val << 16) & 0xff0000) ) ? 0xff : 0;
2879 if(bit_pos == 0) *dst_pixel = 0;
2880 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
2890 if(bit_pos != 0) dst_pixel++;
2891 memset(dst_pixel, 0, pad_size);
2893 dst_start += dst->stride;
2894 src_start += src->stride / 4;
2897 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
2899 for(y = src_rect->top; y < src_rect->bottom; y++)
2901 dst_pixel = dst_start;
2902 src_pixel = src_start;
2903 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
2905 src_val = *src_pixel++;
2906 dst_val = colorref_to_pixel_colortable(dst, ( (src_val >> src->red_shift) & 0x0000ff) |
2907 (((src_val >> src->green_shift) << 8) & 0x00ff00) |
2908 (((src_val >> src->blue_shift) << 16) & 0xff0000) ) ? 0xff : 0;
2910 if(bit_pos == 0) *dst_pixel = 0;
2911 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
2921 if(bit_pos != 0) dst_pixel++;
2922 memset(dst_pixel, 0, pad_size);
2924 dst_start += dst->stride;
2925 src_start += src->stride / 4;
2930 FIXME("Unsupported conversion: 32 (%08x, %08x, %08x) -> 1\n", src->red_mask, src->green_mask, src->blue_mask);
2938 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
2940 for(y = src_rect->top; y < src_rect->bottom; y++)
2942 dst_pixel = dst_start;
2943 src_pixel = src_start;
2944 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
2947 rgb.rgbBlue = *src_pixel++;
2948 rgb.rgbGreen = *src_pixel++;
2949 rgb.rgbRed = *src_pixel++;
2951 dst_val = colorref_to_pixel_colortable(dst, ( rgb.rgbRed & 0x0000ff) |
2952 ((rgb.rgbGreen << 8) & 0x00ff00) |
2953 ((rgb.rgbBlue << 16) & 0xff0000)) ? 0xff : 0;
2955 if(bit_pos == 0) *dst_pixel = 0;
2956 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
2966 if(bit_pos != 0) dst_pixel++;
2967 memset(dst_pixel, 0, pad_size);
2969 dst_start += dst->stride;
2970 src_start += src->stride;
2977 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
2978 if(src->funcs == &funcs_555)
2980 for(y = src_rect->top; y < src_rect->bottom; y++)
2982 dst_pixel = dst_start;
2983 src_pixel = src_start;
2984 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
2986 src_val = *src_pixel++;
2987 dst_val = colorref_to_pixel_colortable(dst, ((src_val >> 7) & 0x0000f8) | ((src_val >> 12) & 0x000007) |
2988 ((src_val << 6) & 0x00f800) | ((src_val << 1) & 0x000700) |
2989 ((src_val << 19) & 0xf80000) | ((src_val << 14) & 0x070000) ) ? 0xff : 0;
2991 if(bit_pos == 0) *dst_pixel = 0;
2992 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
3002 if(bit_pos != 0) dst_pixel++;
3003 memset(dst_pixel, 0, pad_size);
3005 dst_start += dst->stride;
3006 src_start += src->stride / 2;
3009 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
3011 for(y = src_rect->top; y < src_rect->bottom; y++)
3013 dst_pixel = dst_start;
3014 src_pixel = src_start;
3015 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
3017 src_val = *src_pixel++;
3018 dst_val = colorref_to_pixel_colortable(dst, (((src_val >> src->red_shift) << 3) & 0x0000f8) |
3019 (((src_val >> src->red_shift) >> 2) & 0x000007) |
3020 (((src_val >> src->green_shift) << 11) & 0x00f800) |
3021 (((src_val >> src->green_shift) << 6) & 0x000700) |
3022 (((src_val >> src->blue_shift) << 19) & 0xf80000) |
3023 (((src_val >> src->blue_shift) << 14) & 0x070000) ) ? 0xff : 0;
3024 if(bit_pos == 0) *dst_pixel = 0;
3025 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
3035 if(bit_pos != 0) dst_pixel++;
3036 memset(dst_pixel, 0, pad_size);
3038 dst_start += dst->stride;
3039 src_start += src->stride / 2;
3042 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
3044 for(y = src_rect->top; y < src_rect->bottom; y++)
3046 dst_pixel = dst_start;
3047 src_pixel = src_start;
3048 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
3050 src_val = *src_pixel++;
3051 dst_val = colorref_to_pixel_colortable(dst, (((src_val >> src->red_shift) << 3) & 0x0000f8) |
3052 (((src_val >> src->red_shift) >> 2) & 0x000007) |
3053 (((src_val >> src->green_shift) << 10) & 0x00fc00) |
3054 (((src_val >> src->green_shift) << 4) & 0x000300) |
3055 (((src_val >> src->blue_shift) << 19) & 0xf80000) |
3056 (((src_val >> src->blue_shift) << 14) & 0x070000) );
3057 if(bit_pos == 0) *dst_pixel = 0;
3058 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
3068 if(bit_pos != 0) dst_pixel++;
3069 memset(dst_pixel, 0, pad_size);
3071 dst_start += dst->stride;
3072 src_start += src->stride / 2;
3077 FIXME("Unsupported conversion: 16 (%08x, %08x, %08x) -> 1\n", src->red_mask, src->green_mask, src->blue_mask);
3085 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
3087 for(y = src_rect->top; y < src_rect->bottom; y++)
3089 dst_pixel = dst_start;
3090 src_pixel = src_start;
3091 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
3094 src_val = *src_pixel++;
3095 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
3096 rgb = src->color_table[src_val];
3097 dst_val = colorref_to_pixel_colortable(dst, RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue)) ? 0xff : 0;
3099 if(bit_pos == 0) *dst_pixel = 0;
3100 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
3110 if(bit_pos != 0) dst_pixel++;
3111 memset(dst_pixel, 0, pad_size);
3113 dst_start += dst->stride;
3114 src_start += src->stride;
3121 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
3123 for(y = src_rect->top; y < src_rect->bottom; y++)
3125 dst_pixel = dst_start;
3126 src_pixel = src_start;
3127 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
3131 src_val = *src_pixel++ & 0xf;
3133 src_val = (*src_pixel >> 4) & 0xf;
3134 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
3135 rgb = src->color_table[src_val];
3136 dst_val = colorref_to_pixel_colortable(dst, RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue)) ? 0xff : 0;
3138 if(bit_pos == 0) *dst_pixel = 0;
3139 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
3149 if(bit_pos != 0) dst_pixel++;
3150 memset(dst_pixel, 0, pad_size);
3152 dst_start += dst->stride;
3153 src_start += src->stride;
3158 /* Note that while MSDN states that a 1 bpp dib brush -> mono dc
3159 uses text/bkgnd colours instead of the dib's colour table, this
3160 doesn't appear to be the case for a dc backed by a
3165 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
3166 for(y = src_rect->top; y < src_rect->bottom; y++)
3168 dst_pixel = dst_start;
3169 src_pixel = src_start;
3170 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
3173 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
3174 if((x % 8) == 7) src_pixel++;
3175 rgb = src->color_table[src_val];
3176 dst_val = colorref_to_pixel_colortable(dst, RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue)) ? 0xff : 0;
3178 if(bit_pos == 0) *dst_pixel = 0;
3179 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
3189 if(bit_pos != 0) dst_pixel++;
3190 memset(dst_pixel, 0, pad_size);
3192 dst_start += dst->stride;
3193 src_start += src->stride;
3199 FIXME("Unsupported conversion: %d -> 1\n", src->bit_count);
3206 static BOOL convert_to_null(dib_info *dst, const dib_info *src, const RECT *src_rect)
3211 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)
3213 BYTE *hatch_start = hatch->bits, *hatch_ptr;
3214 DWORD mask_start = 0, mask_offset;
3215 DWORD *and_bits = bits->and, *xor_bits = bits->xor;
3218 for(y = 0; y < hatch->height; y++)
3220 hatch_ptr = hatch_start;
3221 mask_offset = mask_start;
3222 for(x = 0; x < hatch->width; x++)
3224 if(*hatch_ptr & pixel_masks_1[x % 8])
3226 and_bits[mask_offset] = fg->and;
3227 xor_bits[mask_offset] = fg->xor;
3231 and_bits[mask_offset] = bg->and;
3232 xor_bits[mask_offset] = bg->xor;
3234 if(x % 8 == 7) hatch_ptr++;
3237 hatch_start += hatch->stride;
3238 mask_start += dib->stride / 4;
3244 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)
3246 BYTE *hatch_start = hatch->bits, *hatch_ptr;
3247 DWORD mask_start = 0, mask_offset;
3248 BYTE *and_bits = bits->and, *xor_bits = bits->xor;
3251 for(y = 0; y < hatch->height; y++)
3253 hatch_ptr = hatch_start;
3254 mask_offset = mask_start;
3255 for(x = 0; x < hatch->width; x++)
3257 if(*hatch_ptr & pixel_masks_1[x % 8])
3259 and_bits[mask_offset] = fg->and & 0xff;
3260 xor_bits[mask_offset++] = fg->xor & 0xff;
3261 and_bits[mask_offset] = (fg->and >> 8) & 0xff;
3262 xor_bits[mask_offset++] = (fg->xor >> 8) & 0xff;
3263 and_bits[mask_offset] = (fg->and >> 16) & 0xff;
3264 xor_bits[mask_offset++] = (fg->xor >> 16) & 0xff;
3268 and_bits[mask_offset] = bg->and & 0xff;
3269 xor_bits[mask_offset++] = bg->xor & 0xff;
3270 and_bits[mask_offset] = (bg->and >> 8) & 0xff;
3271 xor_bits[mask_offset++] = (bg->xor >> 8) & 0xff;
3272 and_bits[mask_offset] = (bg->and >> 16) & 0xff;
3273 xor_bits[mask_offset++] = (bg->xor >> 16) & 0xff;
3275 if(x % 8 == 7) hatch_ptr++;
3277 hatch_start += hatch->stride;
3278 mask_start += dib->stride;
3284 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)
3286 BYTE *hatch_start = hatch->bits, *hatch_ptr;
3287 DWORD mask_start = 0, mask_offset;
3288 WORD *and_bits = bits->and, *xor_bits = bits->xor;
3291 for(y = 0; y < hatch->height; y++)
3293 hatch_ptr = hatch_start;
3294 mask_offset = mask_start;
3295 for(x = 0; x < hatch->width; x++)
3297 if(*hatch_ptr & pixel_masks_1[x % 8])
3299 and_bits[mask_offset] = fg->and;
3300 xor_bits[mask_offset] = fg->xor;
3304 and_bits[mask_offset] = bg->and;
3305 xor_bits[mask_offset] = bg->xor;
3307 if(x % 8 == 7) hatch_ptr++;
3310 hatch_start += hatch->stride;
3311 mask_start += dib->stride / 2;
3317 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)
3319 BYTE *hatch_start = hatch->bits, *hatch_ptr;
3320 DWORD mask_start = 0, mask_offset;
3321 BYTE *and_bits = bits->and, *xor_bits = bits->xor;
3324 for(y = 0; y < hatch->height; y++)
3326 hatch_ptr = hatch_start;
3327 mask_offset = mask_start;
3328 for(x = 0; x < hatch->width; x++)
3330 if(*hatch_ptr & pixel_masks_1[x % 8])
3332 and_bits[mask_offset] = fg->and;
3333 xor_bits[mask_offset] = fg->xor;
3337 and_bits[mask_offset] = bg->and;
3338 xor_bits[mask_offset] = bg->xor;
3340 if(x % 8 == 7) hatch_ptr++;
3343 hatch_start += hatch->stride;
3344 mask_start += dib->stride;
3350 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)
3352 BYTE *hatch_start = hatch->bits, *hatch_ptr;
3353 DWORD mask_start = 0, mask_offset;
3354 BYTE *and_bits = bits->and, *xor_bits = bits->xor;
3355 const rop_mask *rop_mask;
3358 for(y = 0; y < hatch->height; y++)
3360 hatch_ptr = hatch_start;
3361 mask_offset = mask_start;
3362 for(x = 0; x < hatch->width; x++)
3364 if(*hatch_ptr & pixel_masks_1[x % 8])
3371 and_bits[mask_offset] = (rop_mask->and & 0x0f) | (and_bits[mask_offset] & 0xf0);
3372 xor_bits[mask_offset] = (rop_mask->xor & 0x0f) | (xor_bits[mask_offset] & 0xf0);
3377 and_bits[mask_offset] = (rop_mask->and << 4) & 0xf0;
3378 xor_bits[mask_offset] = (rop_mask->xor << 4) & 0xf0;
3381 if(x % 8 == 7) hatch_ptr++;
3383 hatch_start += hatch->stride;
3384 mask_start += dib->stride;
3390 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)
3392 BYTE *hatch_start = hatch->bits, *hatch_ptr;
3393 DWORD mask_start = 0, mask_offset;
3394 BYTE *and_bits = bits->and, *xor_bits = bits->xor;
3398 for(y = 0; y < hatch->height; y++)
3400 hatch_ptr = hatch_start;
3401 mask_offset = mask_start;
3402 for(x = 0, bit_pos = 0; x < hatch->width; x++)
3404 if(*hatch_ptr & pixel_masks_1[x % 8])
3406 rop_mask.and = (fg->and & 1) ? 0xff : 0;
3407 rop_mask.xor = (fg->xor & 1) ? 0xff : 0;
3411 rop_mask.and = (bg->and & 1) ? 0xff : 0;
3412 rop_mask.xor = (bg->xor & 1) ? 0xff : 0;
3415 if(bit_pos == 0) and_bits[mask_offset] = xor_bits[mask_offset] = 0;
3417 and_bits[mask_offset] = (rop_mask.and & pixel_masks_1[bit_pos]) | (and_bits[mask_offset] & ~pixel_masks_1[bit_pos]);
3418 xor_bits[mask_offset] = (rop_mask.xor & pixel_masks_1[bit_pos]) | (xor_bits[mask_offset] & ~pixel_masks_1[bit_pos]);
3427 hatch_start += hatch->stride;
3428 mask_start += dib->stride;
3434 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)
3439 const primitive_funcs funcs_8888 =
3444 colorref_to_pixel_888,
3449 const primitive_funcs funcs_32 =
3454 colorref_to_pixel_masks,
3459 const primitive_funcs funcs_24 =
3464 colorref_to_pixel_888,
3469 const primitive_funcs funcs_555 =
3474 colorref_to_pixel_555,
3479 const primitive_funcs funcs_16 =
3484 colorref_to_pixel_masks,
3489 const primitive_funcs funcs_8 =
3494 colorref_to_pixel_colortable,
3499 const primitive_funcs funcs_4 =
3504 colorref_to_pixel_colortable,
3509 const primitive_funcs funcs_1 =
3514 colorref_to_pixel_colortable,
3519 const primitive_funcs funcs_null =
3524 colorref_to_pixel_null,
3526 create_rop_masks_null