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 void solid_rects_32(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
87 for(i = 0; i < num; i++, rc++)
89 start = get_pixel_ptr_32(dib, rc->left, rc->top);
90 for(y = rc->top; y < rc->bottom; y++, start += dib->stride / 4)
91 for(x = rc->left, ptr = start; x < rc->right; x++)
92 do_rop_32(ptr++, and, xor);
96 static void solid_rects_24(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
99 BYTE *byte_ptr, *byte_start;
101 DWORD and_masks[3], xor_masks[3];
103 and_masks[0] = ( and & 0x00ffffff) | ((and << 24) & 0xff000000);
104 and_masks[1] = ((and >> 8) & 0x0000ffff) | ((and << 16) & 0xffff0000);
105 and_masks[2] = ((and >> 16) & 0x000000ff) | ((and << 8) & 0xffffff00);
106 xor_masks[0] = ( xor & 0x00ffffff) | ((xor << 24) & 0xff000000);
107 xor_masks[1] = ((xor >> 8) & 0x0000ffff) | ((xor << 16) & 0xffff0000);
108 xor_masks[2] = ((xor >> 16) & 0x000000ff) | ((xor << 8) & 0xffffff00);
110 for(i = 0; i < num; i++, rc++)
112 if(rc->left >= rc->right) continue;
114 if((rc->left & ~3) == (rc->right & ~3)) /* Special case for lines that start and end in the same DWORD triplet */
116 byte_start = get_pixel_ptr_24(dib, rc->left, rc->top);
117 for(y = rc->top; y < rc->bottom; y++, byte_start += dib->stride)
119 for(x = rc->left, byte_ptr = byte_start; x < rc->right; x++)
121 do_rop_8(byte_ptr++, and_masks[0] & 0xff, xor_masks[0] & 0xff);
122 do_rop_8(byte_ptr++, and_masks[1] & 0xff, xor_masks[1] & 0xff);
123 do_rop_8(byte_ptr++, and_masks[2] & 0xff, xor_masks[2] & 0xff);
129 start = get_pixel_ptr_24_dword(dib, rc->left, rc->top);
130 for(y = rc->top; y < rc->bottom; y++, start += dib->stride / 4)
137 do_rop_32(ptr++, and_masks[0] | 0x00ffffff, xor_masks[0] & 0xff000000);
138 do_rop_32(ptr++, and_masks[1], xor_masks[1]);
139 do_rop_32(ptr++, and_masks[2], xor_masks[2]);
142 do_rop_32(ptr++, and_masks[1] | 0x0000ffff, xor_masks[1] & 0xffff0000);
143 do_rop_32(ptr++, and_masks[2], xor_masks[2]);
146 do_rop_32(ptr++, and_masks[2] | 0x000000ff, xor_masks[2] & 0xffffff00);
150 for(x = (rc->left + 3) & ~3; x < (rc->right & ~3); x += 4)
152 do_rop_32(ptr++, and_masks[0], xor_masks[0]);
153 do_rop_32(ptr++, and_masks[1], xor_masks[1]);
154 do_rop_32(ptr++, and_masks[2], xor_masks[2]);
157 switch(rc->right & 3)
160 do_rop_32(ptr, and_masks[0] | 0xff000000, xor_masks[0] & 0x00ffffff);
163 do_rop_32(ptr++, and_masks[0], xor_masks[0]);
164 do_rop_32(ptr, and_masks[1] | 0xffff0000, xor_masks[1] & 0x0000ffff);
167 do_rop_32(ptr++, and_masks[0], xor_masks[0]);
168 do_rop_32(ptr++, and_masks[1], xor_masks[1]);
169 do_rop_32(ptr, and_masks[2] | 0xffffff00, xor_masks[2] & 0x000000ff);
177 static void solid_rects_16(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
182 for(i = 0; i < num; i++, rc++)
184 start = get_pixel_ptr_16(dib, rc->left, rc->top);
185 for(y = rc->top; y < rc->bottom; y++, start += dib->stride / 2)
186 for(x = rc->left, ptr = start; x < rc->right; x++)
187 do_rop_16(ptr++, and, xor);
191 static void solid_rects_8(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
196 for(i = 0; i < num; i++, rc++)
198 start = get_pixel_ptr_8(dib, rc->left, rc->top);
199 for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
200 for(x = rc->left, ptr = start; x < rc->right; x++)
201 do_rop_8(ptr++, and, xor);
205 static void solid_rects_4(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
209 BYTE byte_and = (and & 0xf) | ((and << 4) & 0xf0);
210 BYTE byte_xor = (xor & 0xf) | ((xor << 4) & 0xf0);
212 for(i = 0; i < num; i++, rc++)
214 if(rc->left >= rc->right) continue;
215 start = get_pixel_ptr_4(dib, rc->left, rc->top);
216 for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
219 if(rc->left & 1) /* upper nibble untouched */
220 do_rop_8(ptr++, byte_and | 0xf0, byte_xor & 0x0f);
222 for(x = (rc->left + 1) & ~1; x < (rc->right & ~1); x += 2)
223 do_rop_8(ptr++, byte_and, byte_xor);
225 if(rc->right & 1) /* lower nibble untouched */
226 do_rop_8(ptr, byte_and | 0x0f, byte_xor & 0xf0);
231 static void solid_rects_1(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
235 BYTE byte_and = (and & 1) ? 0xff : 0;
236 BYTE byte_xor = (xor & 1) ? 0xff : 0;
237 BYTE start_and, start_xor, end_and, end_xor, mask;
238 static const BYTE masks[8] = {0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01};
240 for(i = 0; i < num; i++, rc++)
242 if(rc->left >= rc->right) continue;
244 start = get_pixel_ptr_1(dib, rc->left, rc->top);
246 if((rc->left & ~7) == (rc->right & ~7)) /* Special case for lines that start and end in the same byte */
248 mask = masks[rc->left & 7] & ~masks[rc->right & 7];
250 start_and = byte_and | ~mask;
251 start_xor = byte_xor & mask;
252 for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
254 do_rop_8(start, start_and, start_xor);
259 mask = masks[rc->left & 7];
260 start_and = byte_and | ~mask;
261 start_xor = byte_xor & mask;
263 mask = masks[rc->right & 7];
264 /* This is inverted wrt to start mask, so end_and/xor assignments reflect this */
265 end_and = byte_and | mask;
266 end_xor = byte_xor & ~mask;
268 for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
273 do_rop_8(ptr++, start_and, start_xor);
275 for(x = (rc->left + 7) & ~7; x < (rc->right & ~7); x += 8)
276 do_rop_8(ptr++, byte_and, byte_xor);
279 do_rop_8(ptr, end_and, end_xor);
285 static void solid_rects_null(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
290 static inline INT calc_offset(INT edge, INT size, INT origin)
294 if(edge - origin >= 0)
295 offset = (edge - origin) % size;
298 offset = (origin - edge) % size;
299 if(offset) offset = size - offset;
304 static inline POINT calc_brush_offset(const RECT *rc, const dib_info *brush, const POINT *origin)
308 offset.x = calc_offset(rc->left, brush->width, origin->x);
309 offset.y = calc_offset(rc->top, brush->height, origin->y);
314 static void pattern_rects_32(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
315 const dib_info *brush, void *and_bits, void *xor_bits)
317 DWORD *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
321 for(i = 0; i < num; i++, rc++)
323 offset = calc_brush_offset(rc, brush, origin);
325 start = get_pixel_ptr_32(dib, rc->left, rc->top);
326 start_and = (DWORD*)and_bits + offset.y * brush->stride / 4;
327 start_xor = (DWORD*)xor_bits + offset.y * brush->stride / 4;
329 for(y = rc->top; y < rc->bottom; y++, start += dib->stride / 4)
331 and_ptr = start_and + offset.x;
332 xor_ptr = start_xor + offset.x;
334 for(x = rc->left, ptr = start; x < rc->right; x++)
336 do_rop_32(ptr++, *and_ptr++, *xor_ptr++);
337 if(and_ptr == start_and + brush->width)
345 if(offset.y == brush->height)
347 start_and = and_bits;
348 start_xor = xor_bits;
353 start_and += brush->stride / 4;
354 start_xor += brush->stride / 4;
360 static void pattern_rects_24(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
361 const dib_info *brush, void *and_bits, void *xor_bits)
363 BYTE *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
367 for(i = 0; i < num; i++, rc++)
369 offset = calc_brush_offset(rc, brush, origin);
371 start = get_pixel_ptr_24(dib, rc->left, rc->top);
372 start_and = (BYTE*)and_bits + offset.y * brush->stride;
373 start_xor = (BYTE*)xor_bits + offset.y * brush->stride;
375 for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
377 and_ptr = start_and + offset.x * 3;
378 xor_ptr = start_xor + offset.x * 3;
380 for(x = rc->left, ptr = start; x < rc->right; x++)
382 do_rop_8(ptr++, *and_ptr++, *xor_ptr++);
383 do_rop_8(ptr++, *and_ptr++, *xor_ptr++);
384 do_rop_8(ptr++, *and_ptr++, *xor_ptr++);
385 if(and_ptr == start_and + brush->width * 3)
393 if(offset.y == brush->height)
395 start_and = and_bits;
396 start_xor = xor_bits;
401 start_and += brush->stride;
402 start_xor += brush->stride;
408 static void pattern_rects_16(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
409 const dib_info *brush, void *and_bits, void *xor_bits)
411 WORD *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
415 for(i = 0; i < num; i++, rc++)
417 offset = calc_brush_offset(rc, brush, origin);
419 start = get_pixel_ptr_16(dib, rc->left, rc->top);
420 start_and = (WORD*)and_bits + offset.y * brush->stride / 2;
421 start_xor = (WORD*)xor_bits + offset.y * brush->stride / 2;
423 for(y = rc->top; y < rc->bottom; y++, start += dib->stride / 2)
425 and_ptr = start_and + offset.x;
426 xor_ptr = start_xor + offset.x;
428 for(x = rc->left, ptr = start; x < rc->right; x++)
430 do_rop_16(ptr++, *and_ptr++, *xor_ptr++);
431 if(and_ptr == start_and + brush->width)
439 if(offset.y == brush->height)
441 start_and = and_bits;
442 start_xor = xor_bits;
447 start_and += brush->stride / 2;
448 start_xor += brush->stride / 2;
454 static void pattern_rects_8(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
455 const dib_info *brush, void *and_bits, void *xor_bits)
457 BYTE *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
461 for(i = 0; i < num; i++, rc++)
463 offset = calc_brush_offset(rc, brush, origin);
465 start = get_pixel_ptr_8(dib, rc->left, rc->top);
466 start_and = (BYTE*)and_bits + offset.y * brush->stride;
467 start_xor = (BYTE*)xor_bits + offset.y * brush->stride;
469 for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
471 and_ptr = start_and + offset.x;
472 xor_ptr = start_xor + offset.x;
474 for(x = rc->left, ptr = start; x < rc->right; x++)
476 do_rop_8(ptr++, *and_ptr++, *xor_ptr++);
477 if(and_ptr == start_and + brush->width)
485 if(offset.y == brush->height)
487 start_and = and_bits;
488 start_xor = xor_bits;
493 start_and += brush->stride;
494 start_xor += brush->stride;
500 static void pattern_rects_4(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
501 const dib_info *brush, void *and_bits, void *xor_bits)
503 BYTE *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
507 for(i = 0; i < num; i++, rc++)
509 offset = calc_brush_offset(rc, brush, origin);
511 start = get_pixel_ptr_4(dib, rc->left, rc->top);
512 start_and = (BYTE*)and_bits + offset.y * brush->stride;
513 start_xor = (BYTE*)xor_bits + offset.y * brush->stride;
515 for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
517 INT brush_x = offset.x;
518 BYTE byte_and, byte_xor;
520 and_ptr = start_and + brush_x / 2;
521 xor_ptr = start_xor + brush_x / 2;
523 for(x = rc->left, ptr = start; x < rc->right; x++)
525 /* FIXME: Two pixels at a time */
526 if(x & 1) /* lower dst nibble */
528 if(brush_x & 1) /* lower pat nibble */
530 byte_and = *and_ptr++ | 0xf0;
531 byte_xor = *xor_ptr++ & 0x0f;
533 else /* upper pat nibble */
535 byte_and = (*and_ptr >> 4) | 0xf0;
536 byte_xor = (*xor_ptr >> 4) & 0x0f;
539 else /* upper dst nibble */
541 if(brush_x & 1) /* lower pat nibble */
543 byte_and = (*and_ptr++ << 4) | 0x0f;
544 byte_xor = (*xor_ptr++ << 4) & 0xf0;
546 else /* upper pat nibble */
548 byte_and = *and_ptr | 0x0f;
549 byte_xor = *xor_ptr & 0xf0;
552 do_rop_8(ptr, byte_and, byte_xor);
556 if(++brush_x == brush->width)
565 if(offset.y == brush->height)
567 start_and = and_bits;
568 start_xor = xor_bits;
573 start_and += brush->stride;
574 start_xor += brush->stride;
580 static void pattern_rects_1(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
581 const dib_info *brush, void *and_bits, void *xor_bits)
583 BYTE *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
587 for(i = 0; i < num; i++, rc++)
589 offset = calc_brush_offset(rc, brush, origin);
591 start = get_pixel_ptr_1(dib, rc->left, rc->top);
592 start_and = (BYTE*)and_bits + offset.y * brush->stride;
593 start_xor = (BYTE*)xor_bits + offset.y * brush->stride;
595 for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
597 INT brush_x = offset.x;
598 BYTE byte_and, byte_xor;
600 and_ptr = start_and + brush_x / 8;
601 xor_ptr = start_xor + brush_x / 8;
603 for(x = rc->left, ptr = start; x < rc->right; x++)
605 byte_and = (*and_ptr & pixel_masks_1[brush_x % 8]) ? 0xff : 0;
606 byte_and |= ~pixel_masks_1[x % 8];
607 byte_xor = (*xor_ptr & pixel_masks_1[brush_x % 8]) ? 0xff : 0;
608 byte_xor &= pixel_masks_1[x % 8];
610 do_rop_8(ptr, byte_and, byte_xor);
612 if((x & 7) == 7) ptr++;
614 if((brush_x & 7) == 7)
620 if(++brush_x == brush->width)
629 if(offset.y == brush->height)
631 start_and = and_bits;
632 start_xor = xor_bits;
637 start_and += brush->stride;
638 start_xor += brush->stride;
644 static void pattern_rects_null(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
645 const dib_info *brush, void *and_bits, void *xor_bits)
650 static DWORD colorref_to_pixel_888(const dib_info *dib, COLORREF color)
652 return ( ((color >> 16) & 0xff) | (color & 0xff00) | ((color << 16) & 0xff0000) );
655 static inline DWORD put_field(DWORD field, int shift, int len)
657 shift = shift - (8 - len);
659 field &= (((1 << len) - 1) << (8 - len));
667 static DWORD colorref_to_pixel_masks(const dib_info *dib, COLORREF colour)
671 r = GetRValue(colour);
672 g = GetGValue(colour);
673 b = GetBValue(colour);
675 return put_field(r, dib->red_shift, dib->red_len) |
676 put_field(g, dib->green_shift, dib->green_len) |
677 put_field(b, dib->blue_shift, dib->blue_len);
680 static DWORD colorref_to_pixel_555(const dib_info *dib, COLORREF color)
682 return ( ((color >> 19) & 0x1f) | ((color >> 6) & 0x03e0) | ((color << 7) & 0x7c00) );
685 static DWORD colorref_to_pixel_colortable(const dib_info *dib, COLORREF color)
687 int i, best_index = 0;
689 DWORD diff, best_diff = 0xffffffff;
691 rgb.rgbRed = GetRValue(color);
692 rgb.rgbGreen = GetGValue(color);
693 rgb.rgbBlue = GetBValue(color);
695 for(i = 0; i < dib->color_table_size; i++)
697 RGBQUAD *cur = dib->color_table + i;
698 diff = (rgb.rgbRed - cur->rgbRed) * (rgb.rgbRed - cur->rgbRed)
699 + (rgb.rgbGreen - cur->rgbGreen) * (rgb.rgbGreen - cur->rgbGreen)
700 + (rgb.rgbBlue - cur->rgbBlue) * (rgb.rgbBlue - cur->rgbBlue);
717 static DWORD colorref_to_pixel_null(const dib_info *dib, COLORREF color)
722 static inline BOOL bit_fields_match(const dib_info *d1, const dib_info *d2)
724 assert( d1->bit_count > 8 && d1->bit_count == d2->bit_count );
726 return d1->red_mask == d2->red_mask &&
727 d1->green_mask == d2->green_mask &&
728 d1->blue_mask == d2->blue_mask;
731 static BOOL convert_to_8888(dib_info *dst, const dib_info *src, const RECT *src_rect)
733 DWORD *dst_start = dst->bits, *dst_pixel, src_val;
734 int x, y, pad_size = (dst->width - (src_rect->right - src_rect->left)) * 4;
736 switch(src->bit_count)
740 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
741 if(src->funcs == &funcs_8888)
743 if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
744 memcpy(dst->bits, src_start, (src_rect->bottom - src_rect->top) * src->stride);
747 for(y = src_rect->top; y < src_rect->bottom; y++)
749 memcpy(dst_start, src_start, (src_rect->right - src_rect->left) * 4);
750 if(pad_size) memset(dst_start + (src_rect->right - src_rect->left), 0, pad_size);
751 dst_start += dst->stride / 4;
752 src_start += src->stride / 4;
756 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
758 for(y = src_rect->top; y < src_rect->bottom; y++)
760 dst_pixel = dst_start;
761 src_pixel = src_start;
762 for(x = src_rect->left; x < src_rect->right; x++)
764 src_val = *src_pixel++;
765 *dst_pixel++ = (((src_val >> src->red_shift) & 0xff) << 16) |
766 (((src_val >> src->green_shift) & 0xff) << 8) |
767 ((src_val >> src->blue_shift) & 0xff);
769 if(pad_size) memset(dst_pixel, 0, pad_size);
770 dst_start += dst->stride / 4;
771 src_start += src->stride / 4;
776 FIXME("Unsupported conversion: 32 (%08x, %08x, %08x) -> 8888\n", src->red_mask, src->green_mask, src->blue_mask);
784 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
786 for(y = src_rect->top; y < src_rect->bottom; y++)
788 dst_pixel = dst_start;
789 src_pixel = src_start;
790 for(x = src_rect->left; x < src_rect->right; x++)
793 rgb.rgbBlue = *src_pixel++;
794 rgb.rgbGreen = *src_pixel++;
795 rgb.rgbRed = *src_pixel++;
797 *dst_pixel++ = ((rgb.rgbRed << 16) & 0xff0000) | ((rgb.rgbGreen << 8) & 0x00ff00) | (rgb.rgbBlue & 0x0000ff);
799 if(pad_size) memset(dst_pixel, 0, pad_size);
800 dst_start += dst->stride / 4;
801 src_start += src->stride;
808 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
809 if(src->funcs == &funcs_555)
811 for(y = src_rect->top; y < src_rect->bottom; y++)
813 dst_pixel = dst_start;
814 src_pixel = src_start;
815 for(x = src_rect->left; x < src_rect->right; x++)
817 src_val = *src_pixel++;
818 *dst_pixel++ = ((src_val << 9) & 0xf80000) | ((src_val << 4) & 0x070000) |
819 ((src_val << 6) & 0x00f800) | ((src_val << 1) & 0x000700) |
820 ((src_val << 3) & 0x0000f8) | ((src_val >> 2) & 0x000007);
822 if(pad_size) memset(dst_pixel, 0, pad_size);
823 dst_start += dst->stride / 4;
824 src_start += src->stride / 2;
827 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
829 for(y = src_rect->top; y < src_rect->bottom; y++)
831 dst_pixel = dst_start;
832 src_pixel = src_start;
833 for(x = src_rect->left; x < src_rect->right; x++)
835 src_val = *src_pixel++;
836 *dst_pixel++ = (((src_val >> src->red_shift) << 19) & 0xf80000) |
837 (((src_val >> src->red_shift) << 14) & 0x070000) |
838 (((src_val >> src->green_shift) << 11) & 0x00f800) |
839 (((src_val >> src->green_shift) << 6) & 0x000700) |
840 (((src_val >> src->blue_shift) << 3) & 0x0000f8) |
841 (((src_val >> src->blue_shift) >> 2) & 0x000007);
843 if(pad_size) memset(dst_pixel, 0, pad_size);
844 dst_start += dst->stride / 4;
845 src_start += src->stride / 2;
848 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
850 for(y = src_rect->top; y < src_rect->bottom; y++)
852 dst_pixel = dst_start;
853 src_pixel = src_start;
854 for(x = src_rect->left; x < src_rect->right; x++)
856 src_val = *src_pixel++;
857 *dst_pixel++ = (((src_val >> src->red_shift) << 19) & 0xf80000) |
858 (((src_val >> src->red_shift) << 14) & 0x070000) |
859 (((src_val >> src->green_shift) << 10) & 0x00fc00) |
860 (((src_val >> src->green_shift) << 4) & 0x000300) |
861 (((src_val >> src->blue_shift) << 3) & 0x0000f8) |
862 (((src_val >> src->blue_shift) >> 2) & 0x000007);
864 if(pad_size) memset(dst_pixel, 0, pad_size);
865 dst_start += dst->stride / 4;
866 src_start += src->stride / 2;
871 FIXME("Unsupported conversion: 16 (%08x, %08x, %08x) -> 8888\n", src->red_mask, src->green_mask, src->blue_mask);
879 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
880 for(y = src_rect->top; y < src_rect->bottom; y++)
882 dst_pixel = dst_start;
883 src_pixel = src_start;
884 for(x = src_rect->left; x < src_rect->right; x++)
887 src_val = *src_pixel++;
888 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
889 rgb = src->color_table[src_val];
890 *dst_pixel++ = rgb.rgbRed << 16 | rgb.rgbGreen << 8 | rgb.rgbBlue;
892 if(pad_size) memset(dst_pixel, 0, pad_size);
893 dst_start += dst->stride / 4;
894 src_start += src->stride;
901 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
902 for(y = src_rect->top; y < src_rect->bottom; y++)
904 dst_pixel = dst_start;
905 src_pixel = src_start;
906 for(x = src_rect->left; x < src_rect->right; x++)
910 src_val = *src_pixel++ & 0xf;
912 src_val = (*src_pixel >> 4) & 0xf;
913 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
914 rgb = src->color_table[src_val];
915 *dst_pixel++ = rgb.rgbRed << 16 | rgb.rgbGreen << 8 | rgb.rgbBlue;
917 if(pad_size) memset(dst_pixel, 0, pad_size);
918 dst_start += dst->stride / 4;
919 src_start += src->stride;
926 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
927 for(y = src_rect->top; y < src_rect->bottom; y++)
929 dst_pixel = dst_start;
930 src_pixel = src_start;
931 for(x = src_rect->left; x < src_rect->right; x++)
934 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
935 if((x % 8) == 7) src_pixel++;
936 rgb = src->color_table[src_val];
937 *dst_pixel++ = rgb.rgbRed << 16 | rgb.rgbGreen << 8 | rgb.rgbBlue;
939 if(pad_size) memset(dst_pixel, 0, pad_size);
940 dst_start += dst->stride / 4;
941 src_start += src->stride;
947 FIXME("Unsupported conversion: %d -> 8888\n", src->bit_count);
954 static BOOL convert_to_32(dib_info *dst, const dib_info *src, const RECT *src_rect)
956 DWORD *dst_start = dst->bits, *dst_pixel, src_val;
957 int x, y, pad_size = (dst->width - (src_rect->right - src_rect->left)) * 4;
959 switch(src->bit_count)
963 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
965 if(src->funcs == &funcs_8888)
967 for(y = src_rect->top; y < src_rect->bottom; y++)
969 dst_pixel = dst_start;
970 src_pixel = src_start;
971 for(x = src_rect->left; x < src_rect->right; x++)
973 src_val = *src_pixel++;
974 *dst_pixel++ = put_field((src_val >> 16) & 0xff, dst->red_shift, dst->red_len) |
975 put_field((src_val >> 8) & 0xff, dst->green_shift, dst->green_len) |
976 put_field( src_val & 0xff, dst->blue_shift, dst->blue_len);
978 if(pad_size) memset(dst_pixel, 0, pad_size);
979 dst_start += dst->stride / 4;
980 src_start += src->stride / 4;
983 else if(bit_fields_match(src, dst))
985 if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
986 memcpy(dst->bits, src_start, (src_rect->bottom - src_rect->top) * src->stride);
989 for(y = src_rect->top; y < src_rect->bottom; y++)
991 memcpy(dst_start, src_start, (src_rect->right - src_rect->left) * 4);
992 if(pad_size) memset(dst_start + (src_rect->right - src_rect->left), 0, pad_size);
993 dst_start += dst->stride / 4;
994 src_start += src->stride / 4;
998 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8 &&
999 dst->red_len == 8 && dst->green_len == 8 && dst->blue_len == 8)
1001 for(y = src_rect->top; y < src_rect->bottom; y++)
1003 dst_pixel = dst_start;
1004 src_pixel = src_start;
1005 for(x = src_rect->left; x < src_rect->right; x++)
1007 src_val = *src_pixel++;
1008 *dst_pixel++ = (((src_val >> src->red_shift) & 0xff) << dst->red_shift) |
1009 (((src_val >> src->green_shift) & 0xff) << dst->green_shift) |
1010 (((src_val >> src->blue_shift) & 0xff) << dst->blue_shift);
1012 if(pad_size) memset(dst_pixel, 0, pad_size);
1013 dst_start += dst->stride / 4;
1014 src_start += src->stride / 4;
1019 FIXME("Unsupported conversion: 32 (%08x, %08x, %08x) -> 32 (%08x, %08x, %08x)\n",
1020 src->red_mask, src->green_mask, src->blue_mask, dst->red_mask, dst->green_mask, dst->blue_mask);
1028 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
1030 for(y = src_rect->top; y < src_rect->bottom; y++)
1032 dst_pixel = dst_start;
1033 src_pixel = src_start;
1034 for(x = src_rect->left; x < src_rect->right; x++)
1037 rgb.rgbBlue = *src_pixel++;
1038 rgb.rgbGreen = *src_pixel++;
1039 rgb.rgbRed = *src_pixel++;
1041 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
1042 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
1043 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
1045 if(pad_size) memset(dst_pixel, 0, pad_size);
1046 dst_start += dst->stride / 4;
1047 src_start += src->stride;
1054 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
1055 if(src->funcs == &funcs_555)
1057 for(y = src_rect->top; y < src_rect->bottom; y++)
1059 dst_pixel = dst_start;
1060 src_pixel = src_start;
1061 for(x = src_rect->left; x < src_rect->right; x++)
1063 src_val = *src_pixel++;
1064 *dst_pixel++ = put_field(((src_val >> 7) & 0xf8) | ((src_val >> 12) & 0x07), dst->red_shift, dst->red_len) |
1065 put_field(((src_val >> 2) & 0xf8) | ((src_val >> 7) & 0x07), dst->green_shift, dst->green_len) |
1066 put_field(((src_val << 3) & 0xf8) | ((src_val >> 2) & 0x07), dst->blue_shift, dst->blue_len);
1068 if(pad_size) memset(dst_pixel, 0, pad_size);
1069 dst_start += dst->stride / 4;
1070 src_start += src->stride / 2;
1073 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
1075 for(y = src_rect->top; y < src_rect->bottom; y++)
1077 dst_pixel = dst_start;
1078 src_pixel = src_start;
1079 for(x = src_rect->left; x < src_rect->right; x++)
1081 src_val = *src_pixel++;
1082 *dst_pixel++ = put_field( (((src_val >> src->red_shift) << 3) & 0xf8) |
1083 (((src_val >> src->red_shift) >> 2) & 0x07), dst->red_shift, dst->red_len ) |
1084 put_field( (((src_val >> src->green_shift) << 3) & 0xf8) |
1085 (((src_val >> src->green_shift) >> 2) & 0x07), dst->green_shift, dst->green_len ) |
1086 put_field( (((src_val >> src->blue_shift) << 3) & 0xf8) |
1087 (((src_val >> src->blue_shift) >> 2) & 0x07), dst->blue_shift, dst->blue_len);
1089 if(pad_size) memset(dst_pixel, 0, pad_size);
1090 dst_start += dst->stride / 4;
1091 src_start += src->stride / 2;
1094 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
1096 for(y = src_rect->top; y < src_rect->bottom; y++)
1098 dst_pixel = dst_start;
1099 src_pixel = src_start;
1100 for(x = src_rect->left; x < src_rect->right; x++)
1102 src_val = *src_pixel++;
1103 *dst_pixel++ = put_field( (((src_val >> src->red_shift) << 3) & 0xf8) |
1104 (((src_val >> src->red_shift) >> 2) & 0x07), dst->red_shift, dst->red_len ) |
1105 put_field( (((src_val >> src->green_shift) << 2) & 0xfc) |
1106 (((src_val >> src->green_shift) >> 4) & 0x03), dst->green_shift, dst->green_len ) |
1107 put_field( (((src_val >> src->blue_shift) << 3) & 0xf8) |
1108 (((src_val >> src->blue_shift) >> 2) & 0x07), dst->blue_shift, dst->blue_len);
1110 if(pad_size) memset(dst_pixel, 0, pad_size);
1111 dst_start += dst->stride / 4;
1112 src_start += src->stride / 2;
1117 FIXME("Unsupported conversion: 16 (%08x, %08x, %08x) -> 32\n", src->red_mask, src->green_mask, src->blue_mask);
1125 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
1126 for(y = src_rect->top; y < src_rect->bottom; y++)
1128 dst_pixel = dst_start;
1129 src_pixel = src_start;
1130 for(x = src_rect->left; x < src_rect->right; x++)
1133 src_val = *src_pixel++;
1134 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
1135 rgb = src->color_table[src_val];
1136 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
1137 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
1138 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
1140 if(pad_size) memset(dst_pixel, 0, pad_size);
1141 dst_start += dst->stride / 4;
1142 src_start += src->stride;
1149 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
1150 for(y = src_rect->top; y < src_rect->bottom; y++)
1152 dst_pixel = dst_start;
1153 src_pixel = src_start;
1154 for(x = src_rect->left; x < src_rect->right; x++)
1158 src_val = *src_pixel++ & 0xf;
1160 src_val = (*src_pixel >> 4) & 0xf;
1161 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
1162 rgb = src->color_table[src_val];
1163 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
1164 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
1165 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
1167 if(pad_size) memset(dst_pixel, 0, pad_size);
1168 dst_start += dst->stride / 4;
1169 src_start += src->stride;
1176 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
1177 for(y = src_rect->top; y < src_rect->bottom; y++)
1179 dst_pixel = dst_start;
1180 src_pixel = src_start;
1181 for(x = src_rect->left; x < src_rect->right; x++)
1184 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
1185 if((x % 8) == 7) src_pixel++;
1186 rgb = src->color_table[src_val];
1187 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
1188 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
1189 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
1191 if(pad_size) memset(dst_pixel, 0, pad_size);
1192 dst_start += dst->stride / 4;
1193 src_start += src->stride;
1199 FIXME("Unsupported conversion: %d -> 32\n", src->bit_count);
1206 static BOOL convert_to_24(dib_info *dst, const dib_info *src, const RECT *src_rect)
1208 BYTE *dst_start = dst->bits, *dst_pixel;
1210 int x, y, pad_size = ((dst->width * 3 + 3) & ~3) - (src_rect->right - src_rect->left) * 3;
1212 switch(src->bit_count)
1216 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
1217 if(src->funcs == &funcs_8888)
1219 for(y = src_rect->top; y < src_rect->bottom; y++)
1221 dst_pixel = dst_start;
1222 src_pixel = src_start;
1223 for(x = src_rect->left; x < src_rect->right; x++)
1225 src_val = *src_pixel++;
1226 *dst_pixel++ = src_val & 0xff;
1227 *dst_pixel++ = (src_val >> 8) & 0xff;
1228 *dst_pixel++ = (src_val >> 16) & 0xff;
1230 if(pad_size) memset(dst_pixel, 0, pad_size);
1231 dst_start += dst->stride;
1232 src_start += src->stride / 4;
1235 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
1237 for(y = src_rect->top; y < src_rect->bottom; y++)
1239 dst_pixel = dst_start;
1240 src_pixel = src_start;
1241 for(x = src_rect->left; x < src_rect->right; x++)
1243 src_val = *src_pixel++;
1244 *dst_pixel++ = (src_val >> src->blue_shift) & 0xff;
1245 *dst_pixel++ = (src_val >> src->green_shift) & 0xff;
1246 *dst_pixel++ = (src_val >> src->red_shift) & 0xff;
1248 if(pad_size) memset(dst_pixel, 0, pad_size);
1249 dst_start += dst->stride;
1250 src_start += src->stride / 4;
1255 FIXME("Unsupported conversion: 32 (%08x, %08x, %08x) -> 24\n", src->red_mask, src->green_mask, src->blue_mask);
1263 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top);
1265 if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
1266 memcpy(dst->bits, src_start, (src_rect->bottom - src_rect->top) * src->stride);
1269 for(y = src_rect->top; y < src_rect->bottom; y++)
1271 memcpy(dst_start, src_start, (src_rect->right - src_rect->left) * 3);
1272 if(pad_size) memset(dst_start + (src_rect->right - src_rect->left) * 3, 0, pad_size);
1273 dst_start += dst->stride;
1274 src_start += src->stride;
1282 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
1283 if(src->funcs == &funcs_555)
1285 for(y = src_rect->top; y < src_rect->bottom; y++)
1287 dst_pixel = dst_start;
1288 src_pixel = src_start;
1289 for(x = src_rect->left; x < src_rect->right; x++)
1291 src_val = *src_pixel++;
1292 *dst_pixel++ = ((src_val << 3) & 0xf8) | ((src_val >> 2) & 0x07);
1293 *dst_pixel++ = ((src_val >> 2) & 0xf8) | ((src_val >> 7) & 0x07);
1294 *dst_pixel++ = ((src_val >> 7) & 0xf8) | ((src_val >> 12) & 0x07);
1296 if(pad_size) memset(dst_pixel, 0, pad_size);
1297 dst_start += dst->stride;
1298 src_start += src->stride / 2;
1301 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
1303 for(y = src_rect->top; y < src_rect->bottom; y++)
1305 dst_pixel = dst_start;
1306 src_pixel = src_start;
1307 for(x = src_rect->left; x < src_rect->right; x++)
1309 src_val = *src_pixel++;
1310 *dst_pixel++ = (((src_val >> src->blue_shift) << 3) & 0xf8) |
1311 (((src_val >> src->blue_shift) >> 2) & 0x07);
1312 *dst_pixel++ = (((src_val >> src->green_shift) << 3) & 0xf8) |
1313 (((src_val >> src->green_shift) >> 2) & 0x07);
1314 *dst_pixel++ = (((src_val >> src->red_shift) << 3) & 0xf8) |
1315 (((src_val >> src->red_shift) >> 2) & 0x07);
1317 if(pad_size) memset(dst_pixel, 0, pad_size);
1318 dst_start += dst->stride;
1319 src_start += src->stride / 2;
1322 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
1324 for(y = src_rect->top; y < src_rect->bottom; y++)
1326 dst_pixel = dst_start;
1327 src_pixel = src_start;
1328 for(x = src_rect->left; x < src_rect->right; x++)
1330 src_val = *src_pixel++;
1331 *dst_pixel++ = (((src_val >> src->blue_shift) << 3) & 0xf8) |
1332 (((src_val >> src->blue_shift) >> 2) & 0x07);
1333 *dst_pixel++ = (((src_val >> src->green_shift) << 2) & 0xfc) |
1334 (((src_val >> src->green_shift) >> 4) & 0x03);
1335 *dst_pixel++ = (((src_val >> src->red_shift) << 3) & 0xf8) |
1336 (((src_val >> src->red_shift) >> 2) & 0x07);
1338 if(pad_size) memset(dst_pixel, 0, pad_size);
1339 dst_start += dst->stride;
1340 src_start += src->stride / 2;
1345 FIXME("Unsupported conversion: 16 (%08x, %08x, %08x) -> 24\n", src->red_mask, src->green_mask, src->blue_mask);
1353 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
1354 for(y = src_rect->top; y < src_rect->bottom; y++)
1356 dst_pixel = dst_start;
1357 src_pixel = src_start;
1358 for(x = src_rect->left; x < src_rect->right; x++)
1361 src_val = *src_pixel++;
1362 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
1363 rgb = src->color_table[src_val];
1364 *dst_pixel++ = rgb.rgbBlue;
1365 *dst_pixel++ = rgb.rgbGreen;
1366 *dst_pixel++ = rgb.rgbRed;
1368 if(pad_size) memset(dst_pixel, 0, pad_size);
1369 dst_start += dst->stride;
1370 src_start += src->stride;
1377 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
1378 for(y = src_rect->top; y < src_rect->bottom; y++)
1380 dst_pixel = dst_start;
1381 src_pixel = src_start;
1382 for(x = src_rect->left; x < src_rect->right; x++)
1386 src_val = *src_pixel++ & 0xf;
1388 src_val = (*src_pixel >> 4) & 0xf;
1389 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
1390 rgb = src->color_table[src_val];
1391 *dst_pixel++ = rgb.rgbBlue;
1392 *dst_pixel++ = rgb.rgbGreen;
1393 *dst_pixel++ = rgb.rgbRed;
1395 if(pad_size) memset(dst_pixel, 0, pad_size);
1396 dst_start += dst->stride;
1397 src_start += src->stride;
1404 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
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++)
1412 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
1413 if((x % 8) == 7) src_pixel++;
1414 rgb = src->color_table[src_val];
1415 *dst_pixel++ = rgb.rgbBlue;
1416 *dst_pixel++ = rgb.rgbGreen;
1417 *dst_pixel++ = rgb.rgbRed;
1419 if(pad_size) memset(dst_pixel, 0, pad_size);
1420 dst_start += dst->stride;
1421 src_start += src->stride;
1427 FIXME("Unsupported conversion: %d -> 24\n", src->bit_count);
1434 static BOOL convert_to_555(dib_info *dst, const dib_info *src, const RECT *src_rect)
1436 WORD *dst_start = dst->bits, *dst_pixel;
1437 INT x, y, pad_size = ((dst->width + 1) & ~1) * 2 - (src_rect->right - src_rect->left) * 2;
1440 switch(src->bit_count)
1444 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
1446 if(src->funcs == &funcs_8888)
1448 for(y = src_rect->top; y < src_rect->bottom; y++)
1450 dst_pixel = dst_start;
1451 src_pixel = src_start;
1452 for(x = src_rect->left; x < src_rect->right; x++)
1454 src_val = *src_pixel++;
1455 *dst_pixel++ = ((src_val >> 9) & 0x7c00) |
1456 ((src_val >> 6) & 0x03e0) |
1457 ((src_val >> 3) & 0x001f);
1459 if(pad_size) memset(dst_pixel, 0, pad_size);
1460 dst_start += dst->stride / 2;
1461 src_start += src->stride / 4;
1464 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
1466 for(y = src_rect->top; y < src_rect->bottom; y++)
1468 dst_pixel = dst_start;
1469 src_pixel = src_start;
1470 for(x = src_rect->left; x < src_rect->right; x++)
1472 src_val = *src_pixel++;
1473 *dst_pixel++ = (((src_val >> src->red_shift) << 7) & 0x7c00) |
1474 (((src_val >> src->green_shift) << 2) & 0x03e0) |
1475 (((src_val >> src->blue_shift) >> 3) & 0x001f);
1477 if(pad_size) memset(dst_pixel, 0, pad_size);
1478 dst_start += dst->stride / 2;
1479 src_start += src->stride / 4;
1484 FIXME("Unsupported conversion: 32 (%08x, %08x, %08x) -> 555\n", src->red_mask, src->green_mask, src->blue_mask);
1492 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
1494 for(y = src_rect->top; y < src_rect->bottom; y++)
1496 dst_pixel = dst_start;
1497 src_pixel = src_start;
1498 for(x = src_rect->left; x < src_rect->right; x++)
1501 rgb.rgbBlue = *src_pixel++;
1502 rgb.rgbGreen = *src_pixel++;
1503 rgb.rgbRed = *src_pixel++;
1505 *dst_pixel++ = ((rgb.rgbRed << 7) & 0x7c00) |
1506 ((rgb.rgbGreen << 2) & 0x03e0) |
1507 ((rgb.rgbBlue >> 3) & 0x001f);
1509 if(pad_size) memset(dst_pixel, 0, pad_size);
1510 dst_start += dst->stride / 2;
1511 src_start += src->stride;
1518 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
1519 if(src->funcs == &funcs_555)
1521 if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
1522 memcpy(dst->bits, src_start, (src_rect->bottom - src_rect->top) * src->stride);
1525 for(y = src_rect->top; y < src_rect->bottom; y++)
1527 memcpy(dst_start, src_start, (src_rect->right - src_rect->left) * 2);
1528 if(pad_size) memset(dst_start + (src_rect->right - src_rect->left), 0, pad_size);
1529 dst_start += dst->stride / 2;
1530 src_start += src->stride / 2;
1534 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
1536 for(y = src_rect->top; y < src_rect->bottom; y++)
1538 dst_pixel = dst_start;
1539 src_pixel = src_start;
1540 for(x = src_rect->left; x < src_rect->right; x++)
1542 src_val = *src_pixel++;
1543 *dst_pixel++ = (((src_val >> src->red_shift) << 10) & 0x7c00) |
1544 (((src_val >> src->green_shift) << 5) & 0x03e0) |
1545 ( (src_val >> src->blue_shift) & 0x001f);
1547 if(pad_size) memset(dst_pixel, 0, pad_size);
1548 dst_start += dst->stride / 2;
1549 src_start += src->stride / 2;
1552 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
1554 for(y = src_rect->top; y < src_rect->bottom; y++)
1556 dst_pixel = dst_start;
1557 src_pixel = src_start;
1558 for(x = src_rect->left; x < src_rect->right; x++)
1560 src_val = *src_pixel++;
1561 *dst_pixel++ = (((src_val >> src->red_shift) << 10) & 0x7c00) |
1562 (((src_val >> src->green_shift) << 4) & 0x03e0) |
1563 ( (src_val >> src->blue_shift) & 0x001f);
1565 if(pad_size) memset(dst_pixel, 0, pad_size);
1566 dst_start += dst->stride / 2;
1567 src_start += src->stride / 2;
1572 FIXME("Unsupported conversion: 16 (%08x, %08x, %08x) -> 555\n", src->red_mask, src->green_mask, src->blue_mask);
1580 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
1581 for(y = src_rect->top; y < src_rect->bottom; y++)
1583 dst_pixel = dst_start;
1584 src_pixel = src_start;
1585 for(x = src_rect->left; x < src_rect->right; x++)
1588 src_val = *src_pixel++;
1589 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
1590 rgb = src->color_table[src_val];
1591 *dst_pixel++ = ((rgb.rgbRed << 7) & 0x7c00) |
1592 ((rgb.rgbGreen << 2) & 0x03e0) |
1593 ((rgb.rgbBlue >> 3) & 0x001f);
1595 if(pad_size) memset(dst_pixel, 0, pad_size);
1596 dst_start += dst->stride / 2;
1597 src_start += src->stride;
1604 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
1605 for(y = src_rect->top; y < src_rect->bottom; y++)
1607 dst_pixel = dst_start;
1608 src_pixel = src_start;
1609 for(x = src_rect->left; x < src_rect->right; x++)
1613 src_val = *src_pixel++ & 0xf;
1615 src_val = (*src_pixel >> 4) & 0xf;
1616 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
1617 rgb = src->color_table[src_val];
1618 *dst_pixel++ = ((rgb.rgbRed << 7) & 0x7c00) |
1619 ((rgb.rgbGreen << 2) & 0x03e0) |
1620 ((rgb.rgbBlue >> 3) & 0x001f);
1622 if(pad_size) memset(dst_pixel, 0, pad_size);
1623 dst_start += dst->stride / 2;
1624 src_start += src->stride;
1631 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
1632 for(y = src_rect->top; y < src_rect->bottom; y++)
1634 dst_pixel = dst_start;
1635 src_pixel = src_start;
1636 for(x = src_rect->left; x < src_rect->right; x++)
1639 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
1640 if((x % 8) == 7) src_pixel++;
1641 rgb = src->color_table[src_val];
1642 *dst_pixel++ = ((rgb.rgbRed << 7) & 0x7c00) |
1643 ((rgb.rgbGreen << 2) & 0x03e0) |
1644 ((rgb.rgbBlue >> 3) & 0x001f);
1646 if(pad_size) memset(dst_pixel, 0, pad_size);
1647 dst_start += dst->stride / 2;
1648 src_start += src->stride;
1654 FIXME("Unsupported conversion: %d -> 555\n", src->bit_count);
1661 static BOOL convert_to_16(dib_info *dst, const dib_info *src, const RECT *src_rect)
1663 WORD *dst_start = dst->bits, *dst_pixel;
1664 INT x, y, pad_size = ((dst->width + 1) & ~1) * 2 - (src_rect->right - src_rect->left) * 2;
1667 switch(src->bit_count)
1671 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
1673 if(src->funcs == &funcs_8888)
1675 for(y = src_rect->top; y < src_rect->bottom; y++)
1677 dst_pixel = dst_start;
1678 src_pixel = src_start;
1679 for(x = src_rect->left; x < src_rect->right; x++)
1681 src_val = *src_pixel++;
1682 *dst_pixel++ = put_field((src_val >> 16) & 0xff, dst->red_shift, dst->red_len) |
1683 put_field((src_val >> 8) & 0xff, dst->green_shift, dst->green_len) |
1684 put_field( src_val & 0xff, dst->blue_shift, dst->blue_len);
1686 if(pad_size) memset(dst_pixel, 0, pad_size);
1687 dst_start += dst->stride / 2;
1688 src_start += src->stride / 4;
1691 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
1693 for(y = src_rect->top; y < src_rect->bottom; y++)
1695 dst_pixel = dst_start;
1696 src_pixel = src_start;
1697 for(x = src_rect->left; x < src_rect->right; x++)
1699 src_val = *src_pixel++;
1700 *dst_pixel++ = put_field((src_val >> src->red_shift) & 0xff, dst->red_shift, dst->red_len) |
1701 put_field((src_val >> src->green_shift) & 0xff, dst->green_shift, dst->green_len) |
1702 put_field((src_val >> src->blue_shift) & 0xff, dst->blue_shift, dst->blue_len);
1704 if(pad_size) memset(dst_pixel, 0, pad_size);
1705 dst_start += dst->stride / 2;
1706 src_start += src->stride / 4;
1711 FIXME("Unsupported conversion: 32 (%08x, %08x, %08x) -> 16\n", src->red_mask, src->green_mask, src->blue_mask);
1719 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
1721 for(y = src_rect->top; y < src_rect->bottom; y++)
1723 dst_pixel = dst_start;
1724 src_pixel = src_start;
1725 for(x = src_rect->left; x < src_rect->right; x++)
1728 rgb.rgbBlue = *src_pixel++;
1729 rgb.rgbGreen = *src_pixel++;
1730 rgb.rgbRed = *src_pixel++;
1732 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
1733 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
1734 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
1736 if(pad_size) memset(dst_pixel, 0, pad_size);
1737 dst_start += dst->stride / 2;
1738 src_start += src->stride;
1745 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
1746 if(src->funcs == &funcs_555)
1748 for(y = src_rect->top; y < src_rect->bottom; y++)
1750 dst_pixel = dst_start;
1751 src_pixel = src_start;
1752 for(x = src_rect->left; x < src_rect->right; x++)
1754 src_val = *src_pixel++;
1755 *dst_pixel++ = put_field(((src_val >> 7) & 0xf8) | ((src_val >> 12) & 0x07), dst->red_shift, dst->red_len) |
1756 put_field(((src_val >> 2) & 0xf8) | ((src_val >> 7) & 0x07), dst->green_shift, dst->green_len) |
1757 put_field(((src_val << 3) & 0xf8) | ((src_val >> 2) & 0x07), dst->blue_shift, dst->blue_len);
1759 if(pad_size) memset(dst_pixel, 0, pad_size);
1760 dst_start += dst->stride / 2;
1761 src_start += src->stride / 2;
1764 else if(bit_fields_match(src, dst))
1766 if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
1767 memcpy(dst->bits, src_start, (src_rect->bottom - src_rect->top) * src->stride);
1770 for(y = src_rect->top; y < src_rect->bottom; y++)
1772 memcpy(dst_start, src_start, (src_rect->right - src_rect->left) * 2);
1773 if(pad_size) memset(dst_start + (src_rect->right - src_rect->left), 0, pad_size);
1774 dst_start += dst->stride / 2;
1775 src_start += src->stride / 2;
1779 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
1781 for(y = src_rect->top; y < src_rect->bottom; y++)
1783 dst_pixel = dst_start;
1784 src_pixel = src_start;
1785 for(x = src_rect->left; x < src_rect->right; x++)
1787 src_val = *src_pixel++;
1788 *dst_pixel++ = put_field( (((src_val >> src->red_shift) << 3) & 0xf8) |
1789 (((src_val >> src->red_shift) >> 2) & 0x07), dst->red_shift, dst->red_len ) |
1790 put_field( (((src_val >> src->green_shift) << 3) & 0xf8) |
1791 (((src_val >> src->green_shift) >> 2) & 0x07), dst->green_shift, dst->green_len ) |
1792 put_field( (((src_val >> src->blue_shift) << 3) & 0xf8) |
1793 (((src_val >> src->blue_shift) >> 2) & 0x07), dst->blue_shift, dst->blue_len);
1795 if(pad_size) memset(dst_pixel, 0, pad_size);
1796 dst_start += dst->stride / 2;
1797 src_start += src->stride / 2;
1800 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
1802 for(y = src_rect->top; y < src_rect->bottom; y++)
1804 dst_pixel = dst_start;
1805 src_pixel = src_start;
1806 for(x = src_rect->left; x < src_rect->right; x++)
1808 src_val = *src_pixel++;
1809 *dst_pixel++ = put_field( (((src_val >> src->red_shift) << 3) & 0xf8) |
1810 (((src_val >> src->red_shift) >> 2) & 0x07), dst->red_shift, dst->red_len ) |
1811 put_field( (((src_val >> src->green_shift) << 2) & 0xfc) |
1812 (((src_val >> src->green_shift) >> 4) & 0x03), dst->green_shift, dst->green_len ) |
1813 put_field( (((src_val >> src->blue_shift) << 3) & 0xf8) |
1814 (((src_val >> src->blue_shift) >> 2) & 0x07), dst->blue_shift, dst->blue_len);
1816 if(pad_size) memset(dst_pixel, 0, pad_size);
1817 dst_start += dst->stride / 2;
1818 src_start += src->stride / 2;
1823 FIXME("Unsupported conversion: 16 (%08x, %08x, %08x) -> 16 (%08x, %08x, %08x)\n",
1824 src->red_mask, src->green_mask, src->blue_mask, dst->red_mask, dst->green_mask, dst->blue_mask);
1832 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
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++)
1840 src_val = *src_pixel++;
1841 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
1842 rgb = src->color_table[src_val];
1843 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
1844 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
1845 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
1847 if(pad_size) memset(dst_pixel, 0, pad_size);
1848 dst_start += dst->stride / 2;
1849 src_start += src->stride;
1856 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
1857 for(y = src_rect->top; y < src_rect->bottom; y++)
1859 dst_pixel = dst_start;
1860 src_pixel = src_start;
1861 for(x = src_rect->left; x < src_rect->right; x++)
1865 src_val = *src_pixel++ & 0xf;
1867 src_val = (*src_pixel >> 4) & 0xf;
1868 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
1869 rgb = src->color_table[src_val];
1870 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
1871 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
1872 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
1874 if(pad_size) memset(dst_pixel, 0, pad_size);
1875 dst_start += dst->stride / 2;
1876 src_start += src->stride;
1883 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
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++)
1891 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
1892 if((x % 8) == 7) src_pixel++;
1893 rgb = src->color_table[src_val];
1894 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
1895 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
1896 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
1898 if(pad_size) memset(dst_pixel, 0, pad_size);
1899 dst_start += dst->stride / 2;
1900 src_start += src->stride;
1906 FIXME("Unsupported conversion: %d -> 16\n", src->bit_count);
1913 static inline BOOL color_tables_match(const dib_info *d1, const dib_info *d2)
1915 assert(d1->color_table_size && d2->color_table_size);
1917 if(d1->color_table_size != d2->color_table_size) return FALSE;
1918 return !memcmp(d1->color_table, d2->color_table, d1->color_table_size * sizeof(d1->color_table[0]));
1921 static BOOL convert_to_8(dib_info *dst, const dib_info *src, const RECT *src_rect)
1923 BYTE *dst_start = dst->bits, *dst_pixel;
1924 INT x, y, pad_size = ((dst->width + 3) & ~3) - (src_rect->right - src_rect->left);
1927 switch(src->bit_count)
1931 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
1933 if(src->funcs == &funcs_8888)
1935 for(y = src_rect->top; y < src_rect->bottom; y++)
1937 dst_pixel = dst_start;
1938 src_pixel = src_start;
1939 for(x = src_rect->left; x < src_rect->right; x++)
1941 src_val = *src_pixel++;
1942 *dst_pixel++ = colorref_to_pixel_colortable(dst, ((src_val >> 16) & 0x0000ff) |
1943 ( src_val & 0x00ff00) |
1944 ((src_val << 16) & 0xff0000) );
1946 if(pad_size) memset(dst_pixel, 0, pad_size);
1947 dst_start += dst->stride;
1948 src_start += src->stride / 4;
1951 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
1953 for(y = src_rect->top; y < src_rect->bottom; y++)
1955 dst_pixel = dst_start;
1956 src_pixel = src_start;
1957 for(x = src_rect->left; x < src_rect->right; x++)
1959 src_val = *src_pixel++;
1960 *dst_pixel++ = colorref_to_pixel_colortable(dst, ( (src_val >> src->red_shift) & 0x0000ff) |
1961 (((src_val >> src->green_shift) << 8) & 0x00ff00) |
1962 (((src_val >> src->blue_shift) << 16) & 0xff0000) );
1964 if(pad_size) memset(dst_pixel, 0, pad_size);
1965 dst_start += dst->stride;
1966 src_start += src->stride / 4;
1971 FIXME("Unsupported conversion: 32 (%08x, %08x, %08x) -> 8\n", src->red_mask, src->green_mask, src->blue_mask);
1979 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
1981 for(y = src_rect->top; y < src_rect->bottom; y++)
1983 dst_pixel = dst_start;
1984 src_pixel = src_start;
1985 for(x = src_rect->left; x < src_rect->right; x++)
1988 rgb.rgbBlue = *src_pixel++;
1989 rgb.rgbGreen = *src_pixel++;
1990 rgb.rgbRed = *src_pixel++;
1992 *dst_pixel++ = colorref_to_pixel_colortable(dst, ( rgb.rgbRed & 0x0000ff) |
1993 ((rgb.rgbGreen << 8) & 0x00ff00) |
1994 ((rgb.rgbBlue << 16) & 0xff0000));
1996 if(pad_size) memset(dst_pixel, 0, pad_size);
1997 dst_start += dst->stride;
1998 src_start += src->stride;
2005 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
2006 if(src->funcs == &funcs_555)
2008 for(y = src_rect->top; y < src_rect->bottom; y++)
2010 dst_pixel = dst_start;
2011 src_pixel = src_start;
2012 for(x = src_rect->left; x < src_rect->right; x++)
2014 src_val = *src_pixel++;
2015 *dst_pixel++ = colorref_to_pixel_colortable(dst, ((src_val >> 7) & 0x0000f8) | ((src_val >> 12) & 0x000007) |
2016 ((src_val << 6) & 0x00f800) | ((src_val << 1) & 0x000700) |
2017 ((src_val << 19) & 0xf80000) | ((src_val << 14) & 0x070000) );
2019 if(pad_size) memset(dst_pixel, 0, pad_size);
2020 dst_start += dst->stride;
2021 src_start += src->stride / 2;
2024 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
2026 for(y = src_rect->top; y < src_rect->bottom; y++)
2028 dst_pixel = dst_start;
2029 src_pixel = src_start;
2030 for(x = src_rect->left; x < src_rect->right; x++)
2032 src_val = *src_pixel++;
2033 *dst_pixel++ = colorref_to_pixel_colortable(dst, (((src_val >> src->red_shift) << 3) & 0x0000f8) |
2034 (((src_val >> src->red_shift) >> 2) & 0x000007) |
2035 (((src_val >> src->green_shift) << 11) & 0x00f800) |
2036 (((src_val >> src->green_shift) << 6) & 0x000700) |
2037 (((src_val >> src->blue_shift) << 19) & 0xf80000) |
2038 (((src_val >> src->blue_shift) << 14) & 0x070000) );
2040 if(pad_size) memset(dst_pixel, 0, pad_size);
2041 dst_start += dst->stride;
2042 src_start += src->stride / 2;
2045 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
2047 for(y = src_rect->top; y < src_rect->bottom; y++)
2049 dst_pixel = dst_start;
2050 src_pixel = src_start;
2051 for(x = src_rect->left; x < src_rect->right; x++)
2053 src_val = *src_pixel++;
2054 *dst_pixel++ = colorref_to_pixel_colortable(dst, (((src_val >> src->red_shift) << 3) & 0x0000f8) |
2055 (((src_val >> src->red_shift) >> 2) & 0x000007) |
2056 (((src_val >> src->green_shift) << 10) & 0x00fc00) |
2057 (((src_val >> src->green_shift) << 4) & 0x000300) |
2058 (((src_val >> src->blue_shift) << 19) & 0xf80000) |
2059 (((src_val >> src->blue_shift) << 14) & 0x070000) );
2061 if(pad_size) memset(dst_pixel, 0, pad_size);
2062 dst_start += dst->stride;
2063 src_start += src->stride / 2;
2068 FIXME("Unsupported conversion: 16 (%08x, %08x, %08x) -> 8\n", src->red_mask, src->green_mask, src->blue_mask);
2076 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
2078 if(color_tables_match(dst, src))
2080 if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
2081 memcpy(dst->bits, src_start, (src_rect->bottom - src_rect->top) * src->stride);
2084 for(y = src_rect->top; y < src_rect->bottom; y++)
2086 memcpy(dst_start, src_start, src_rect->right - src_rect->left);
2087 if(pad_size) memset(dst_start + (src_rect->right - src_rect->left), 0, pad_size);
2088 dst_start += dst->stride;
2089 src_start += src->stride;
2095 for(y = src_rect->top; y < src_rect->bottom; y++)
2097 dst_pixel = dst_start;
2098 src_pixel = src_start;
2099 for(x = src_rect->left; x < src_rect->right; x++)
2102 src_val = *src_pixel++;
2103 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
2104 rgb = src->color_table[src_val];
2105 *dst_pixel++ = colorref_to_pixel_colortable(dst, RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue));
2107 if(pad_size) memset(dst_pixel, 0, pad_size);
2108 dst_start += dst->stride;
2109 src_start += src->stride;
2117 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
2118 for(y = src_rect->top; y < src_rect->bottom; y++)
2120 dst_pixel = dst_start;
2121 src_pixel = src_start;
2122 for(x = src_rect->left; x < src_rect->right; x++)
2126 src_val = *src_pixel++ & 0xf;
2128 src_val = (*src_pixel >> 4) & 0xf;
2129 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
2130 rgb = src->color_table[src_val];
2131 *dst_pixel++ = colorref_to_pixel_colortable(dst, RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue));
2133 if(pad_size) memset(dst_pixel, 0, pad_size);
2134 dst_start += dst->stride;
2135 src_start += src->stride;
2142 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
2143 for(y = src_rect->top; y < src_rect->bottom; y++)
2145 dst_pixel = dst_start;
2146 src_pixel = src_start;
2147 for(x = src_rect->left; x < src_rect->right; x++)
2150 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
2151 if((x % 8) == 7) src_pixel++;
2152 rgb = src->color_table[src_val];
2153 *dst_pixel++ = colorref_to_pixel_colortable(dst, RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue));
2155 if(pad_size) memset(dst_pixel, 0, pad_size);
2156 dst_start += dst->stride;
2157 src_start += src->stride;
2163 FIXME("Unsupported conversion: %d -> 8\n", src->bit_count);
2170 static BOOL convert_to_4(dib_info *dst, const dib_info *src, const RECT *src_rect)
2172 BYTE *dst_start = dst->bits, *dst_pixel, dst_val;
2173 INT x, y, pad_size = ((dst->width + 7) & ~7) / 2 - (src_rect->right - src_rect->left + 1) / 2;
2176 switch(src->bit_count)
2180 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
2182 if(src->funcs == &funcs_8888)
2184 for(y = src_rect->top; y < src_rect->bottom; y++)
2186 dst_pixel = dst_start;
2187 src_pixel = src_start;
2188 for(x = src_rect->left; x < src_rect->right; x++)
2190 src_val = *src_pixel++;
2191 dst_val = colorref_to_pixel_colortable(dst, ((src_val >> 16) & 0x0000ff) |
2192 ( src_val & 0x00ff00) |
2193 ((src_val << 16) & 0xff0000) );
2194 if((x - src_rect->left) & 1)
2196 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
2200 *dst_pixel = (dst_val << 4) & 0xf0;
2204 if((x - src_rect->left) & 1) dst_pixel++;
2205 memset(dst_pixel, 0, pad_size);
2207 dst_start += dst->stride;
2208 src_start += src->stride / 4;
2211 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
2213 for(y = src_rect->top; y < src_rect->bottom; y++)
2215 dst_pixel = dst_start;
2216 src_pixel = src_start;
2217 for(x = src_rect->left; x < src_rect->right; x++)
2219 src_val = *src_pixel++;
2220 dst_val = colorref_to_pixel_colortable(dst, ( (src_val >> src->red_shift) & 0x0000ff) |
2221 (((src_val >> src->green_shift) << 8) & 0x00ff00) |
2222 (((src_val >> src->blue_shift) << 16) & 0xff0000) );
2223 if((x - src_rect->left) & 1)
2225 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
2229 *dst_pixel = (dst_val << 4) & 0xf0;
2233 if((x - src_rect->left) & 1) dst_pixel++;
2234 memset(dst_pixel, 0, pad_size);
2236 dst_start += dst->stride;
2237 src_start += src->stride / 4;
2242 FIXME("Unsupported conversion: 32 (%08x, %08x, %08x) -> 4\n", src->red_mask, src->green_mask, src->blue_mask);
2250 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
2252 for(y = src_rect->top; y < src_rect->bottom; y++)
2254 dst_pixel = dst_start;
2255 src_pixel = src_start;
2256 for(x = src_rect->left; x < src_rect->right; x++)
2259 rgb.rgbBlue = *src_pixel++;
2260 rgb.rgbGreen = *src_pixel++;
2261 rgb.rgbRed = *src_pixel++;
2263 dst_val = colorref_to_pixel_colortable(dst, ( rgb.rgbRed & 0x0000ff) |
2264 ((rgb.rgbGreen << 8) & 0x00ff00) |
2265 ((rgb.rgbBlue << 16) & 0xff0000));
2267 if((x - src_rect->left) & 1)
2269 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
2273 *dst_pixel = (dst_val << 4) & 0xf0;
2277 if((x - src_rect->left) & 1) dst_pixel++;
2278 memset(dst_pixel, 0, pad_size);
2280 dst_start += dst->stride;
2281 src_start += src->stride;
2288 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
2289 if(src->funcs == &funcs_555)
2291 for(y = src_rect->top; y < src_rect->bottom; y++)
2293 dst_pixel = dst_start;
2294 src_pixel = src_start;
2295 for(x = src_rect->left; x < src_rect->right; x++)
2297 src_val = *src_pixel++;
2298 dst_val = colorref_to_pixel_colortable(dst, ((src_val >> 7) & 0x0000f8) | ((src_val >> 12) & 0x000007) |
2299 ((src_val << 6) & 0x00f800) | ((src_val << 1) & 0x000700) |
2300 ((src_val << 19) & 0xf80000) | ((src_val << 14) & 0x070000) );
2301 if((x - src_rect->left) & 1)
2303 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
2307 *dst_pixel = (dst_val << 4) & 0xf0;
2311 if((x - src_rect->left) & 1) dst_pixel++;
2312 memset(dst_pixel, 0, pad_size);
2314 dst_start += dst->stride;
2315 src_start += src->stride / 2;
2318 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
2320 for(y = src_rect->top; y < src_rect->bottom; y++)
2322 dst_pixel = dst_start;
2323 src_pixel = src_start;
2324 for(x = src_rect->left; x < src_rect->right; x++)
2326 src_val = *src_pixel++;
2327 dst_val = colorref_to_pixel_colortable(dst, (((src_val >> src->red_shift) << 3) & 0x0000f8) |
2328 (((src_val >> src->red_shift) >> 2) & 0x000007) |
2329 (((src_val >> src->green_shift) << 11) & 0x00f800) |
2330 (((src_val >> src->green_shift) << 6) & 0x000700) |
2331 (((src_val >> src->blue_shift) << 19) & 0xf80000) |
2332 (((src_val >> src->blue_shift) << 14) & 0x070000) );
2333 if((x - src_rect->left) & 1)
2335 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
2339 *dst_pixel = (dst_val << 4) & 0xf0;
2343 if((x - src_rect->left) & 1) dst_pixel++;
2344 memset(dst_pixel, 0, pad_size);
2346 dst_start += dst->stride;
2347 src_start += src->stride / 2;
2350 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
2352 for(y = src_rect->top; y < src_rect->bottom; y++)
2354 dst_pixel = dst_start;
2355 src_pixel = src_start;
2356 for(x = src_rect->left; x < src_rect->right; x++)
2358 src_val = *src_pixel++;
2359 dst_val = colorref_to_pixel_colortable(dst, (((src_val >> src->red_shift) << 3) & 0x0000f8) |
2360 (((src_val >> src->red_shift) >> 2) & 0x000007) |
2361 (((src_val >> src->green_shift) << 10) & 0x00fc00) |
2362 (((src_val >> src->green_shift) << 4) & 0x000300) |
2363 (((src_val >> src->blue_shift) << 19) & 0xf80000) |
2364 (((src_val >> src->blue_shift) << 14) & 0x070000) );
2365 if((x - src_rect->left) & 1)
2367 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
2371 *dst_pixel = (dst_val << 4) & 0xf0;
2375 if((x - src_rect->left) & 1) dst_pixel++;
2376 memset(dst_pixel, 0, pad_size);
2378 dst_start += dst->stride;
2379 src_start += src->stride / 2;
2384 FIXME("Unsupported conversion: 16 (%08x, %08x, %08x) -> 4\n", src->red_mask, src->green_mask, src->blue_mask);
2392 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
2394 for(y = src_rect->top; y < src_rect->bottom; y++)
2396 dst_pixel = dst_start;
2397 src_pixel = src_start;
2398 for(x = src_rect->left; x < src_rect->right; x++)
2401 src_val = *src_pixel++;
2402 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
2403 rgb = src->color_table[src_val];
2404 dst_val = colorref_to_pixel_colortable(dst, RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue));
2405 if((x - src_rect->left) & 1)
2407 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
2411 *dst_pixel = (dst_val << 4) & 0xf0;
2415 if((x - src_rect->left) & 1) dst_pixel++;
2416 memset(dst_pixel, 0, pad_size);
2418 dst_start += dst->stride;
2419 src_start += src->stride;
2426 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
2428 if(color_tables_match(dst, src) && (src_rect->left & 1) == 0)
2430 if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
2431 memcpy(dst->bits, src_start, (src_rect->bottom - src_rect->top) * src->stride);
2434 for(y = src_rect->top; y < src_rect->bottom; y++)
2436 memcpy(dst_start, src_start, (src_rect->right - src_rect->left + 1) / 2);
2437 if(pad_size) memset(dst_start + (src_rect->right - src_rect->left + 1) / 2, 0, pad_size);
2438 dst_start += dst->stride;
2439 src_start += src->stride;
2445 for(y = src_rect->top; y < src_rect->bottom; y++)
2447 dst_pixel = dst_start;
2448 src_pixel = src_start;
2449 for(x = src_rect->left; x < src_rect->right; x++)
2453 src_val = *src_pixel++ & 0xf;
2455 src_val = (*src_pixel >> 4) & 0xf;
2456 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
2457 rgb = src->color_table[src_val];
2458 dst_val = colorref_to_pixel_colortable(dst, RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue));
2459 if((x - src_rect->left) & 1)
2461 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
2465 *dst_pixel = (dst_val << 4) & 0xf0;
2469 if((x - src_rect->left) & 1) dst_pixel++;
2470 memset(dst_pixel, 0, pad_size);
2472 dst_start += dst->stride;
2473 src_start += src->stride;
2481 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
2482 for(y = src_rect->top; y < src_rect->bottom; y++)
2484 dst_pixel = dst_start;
2485 src_pixel = src_start;
2486 for(x = src_rect->left; x < src_rect->right; x++)
2489 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
2490 if((x % 8) == 7) src_pixel++;
2491 rgb = src->color_table[src_val];
2492 dst_val = colorref_to_pixel_colortable(dst, RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue));
2493 if((x - src_rect->left) & 1)
2495 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
2499 *dst_pixel = (dst_val << 4) & 0xf0;
2503 if((x - src_rect->left) & 1) dst_pixel++;
2504 memset(dst_pixel, 0, pad_size);
2506 dst_start += dst->stride;
2507 src_start += src->stride;
2513 FIXME("Unsupported conversion: %d -> 4\n", src->bit_count);
2521 static BOOL convert_to_1(dib_info *dst, const dib_info *src, const RECT *src_rect)
2523 BYTE *dst_start = dst->bits, *dst_pixel, dst_val;
2524 INT x, y, pad_size = ((dst->width + 31) & ~31) / 8 - (src_rect->right - src_rect->left + 7) / 8;
2528 /* FIXME: Brushes should be dithered. */
2530 switch(src->bit_count)
2534 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
2536 if(src->funcs == &funcs_8888)
2538 for(y = src_rect->top; y < src_rect->bottom; y++)
2540 dst_pixel = dst_start;
2541 src_pixel = src_start;
2542 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
2544 src_val = *src_pixel++;
2545 dst_val = colorref_to_pixel_colortable(dst, ((src_val >> 16) & 0x0000ff) |
2546 ( src_val & 0x00ff00) |
2547 ((src_val << 16) & 0xff0000) ) ? 0xff : 0;
2549 if(bit_pos == 0) *dst_pixel = 0;
2550 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
2560 if(bit_pos != 0) dst_pixel++;
2561 memset(dst_pixel, 0, pad_size);
2563 dst_start += dst->stride;
2564 src_start += src->stride / 4;
2567 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
2569 for(y = src_rect->top; y < src_rect->bottom; y++)
2571 dst_pixel = dst_start;
2572 src_pixel = src_start;
2573 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
2575 src_val = *src_pixel++;
2576 dst_val = colorref_to_pixel_colortable(dst, ( (src_val >> src->red_shift) & 0x0000ff) |
2577 (((src_val >> src->green_shift) << 8) & 0x00ff00) |
2578 (((src_val >> src->blue_shift) << 16) & 0xff0000) ) ? 0xff : 0;
2580 if(bit_pos == 0) *dst_pixel = 0;
2581 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
2591 if(bit_pos != 0) dst_pixel++;
2592 memset(dst_pixel, 0, pad_size);
2594 dst_start += dst->stride;
2595 src_start += src->stride / 4;
2600 FIXME("Unsupported conversion: 32 (%08x, %08x, %08x) -> 1\n", src->red_mask, src->green_mask, src->blue_mask);
2608 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
2610 for(y = src_rect->top; y < src_rect->bottom; y++)
2612 dst_pixel = dst_start;
2613 src_pixel = src_start;
2614 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
2617 rgb.rgbBlue = *src_pixel++;
2618 rgb.rgbGreen = *src_pixel++;
2619 rgb.rgbRed = *src_pixel++;
2621 dst_val = colorref_to_pixel_colortable(dst, ( rgb.rgbRed & 0x0000ff) |
2622 ((rgb.rgbGreen << 8) & 0x00ff00) |
2623 ((rgb.rgbBlue << 16) & 0xff0000)) ? 0xff : 0;
2625 if(bit_pos == 0) *dst_pixel = 0;
2626 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
2636 if(bit_pos != 0) dst_pixel++;
2637 memset(dst_pixel, 0, pad_size);
2639 dst_start += dst->stride;
2640 src_start += src->stride;
2647 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
2648 if(src->funcs == &funcs_555)
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, bit_pos = 0; x < src_rect->right; x++)
2656 src_val = *src_pixel++;
2657 dst_val = colorref_to_pixel_colortable(dst, ((src_val >> 7) & 0x0000f8) | ((src_val >> 12) & 0x000007) |
2658 ((src_val << 6) & 0x00f800) | ((src_val << 1) & 0x000700) |
2659 ((src_val << 19) & 0xf80000) | ((src_val << 14) & 0x070000) ) ? 0xff : 0;
2661 if(bit_pos == 0) *dst_pixel = 0;
2662 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
2672 if(bit_pos != 0) dst_pixel++;
2673 memset(dst_pixel, 0, pad_size);
2675 dst_start += dst->stride;
2676 src_start += src->stride / 2;
2679 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
2681 for(y = src_rect->top; y < src_rect->bottom; y++)
2683 dst_pixel = dst_start;
2684 src_pixel = src_start;
2685 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
2687 src_val = *src_pixel++;
2688 dst_val = colorref_to_pixel_colortable(dst, (((src_val >> src->red_shift) << 3) & 0x0000f8) |
2689 (((src_val >> src->red_shift) >> 2) & 0x000007) |
2690 (((src_val >> src->green_shift) << 11) & 0x00f800) |
2691 (((src_val >> src->green_shift) << 6) & 0x000700) |
2692 (((src_val >> src->blue_shift) << 19) & 0xf80000) |
2693 (((src_val >> src->blue_shift) << 14) & 0x070000) ) ? 0xff : 0;
2694 if(bit_pos == 0) *dst_pixel = 0;
2695 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
2705 if(bit_pos != 0) dst_pixel++;
2706 memset(dst_pixel, 0, pad_size);
2708 dst_start += dst->stride;
2709 src_start += src->stride / 2;
2712 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
2714 for(y = src_rect->top; y < src_rect->bottom; y++)
2716 dst_pixel = dst_start;
2717 src_pixel = src_start;
2718 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
2720 src_val = *src_pixel++;
2721 dst_val = colorref_to_pixel_colortable(dst, (((src_val >> src->red_shift) << 3) & 0x0000f8) |
2722 (((src_val >> src->red_shift) >> 2) & 0x000007) |
2723 (((src_val >> src->green_shift) << 10) & 0x00fc00) |
2724 (((src_val >> src->green_shift) << 4) & 0x000300) |
2725 (((src_val >> src->blue_shift) << 19) & 0xf80000) |
2726 (((src_val >> src->blue_shift) << 14) & 0x070000) );
2727 if(bit_pos == 0) *dst_pixel = 0;
2728 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
2738 if(bit_pos != 0) dst_pixel++;
2739 memset(dst_pixel, 0, pad_size);
2741 dst_start += dst->stride;
2742 src_start += src->stride / 2;
2747 FIXME("Unsupported conversion: 16 (%08x, %08x, %08x) -> 1\n", src->red_mask, src->green_mask, src->blue_mask);
2755 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
2757 for(y = src_rect->top; y < src_rect->bottom; y++)
2759 dst_pixel = dst_start;
2760 src_pixel = src_start;
2761 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
2764 src_val = *src_pixel++;
2765 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
2766 rgb = src->color_table[src_val];
2767 dst_val = colorref_to_pixel_colortable(dst, RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue)) ? 0xff : 0;
2769 if(bit_pos == 0) *dst_pixel = 0;
2770 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
2780 if(bit_pos != 0) dst_pixel++;
2781 memset(dst_pixel, 0, pad_size);
2783 dst_start += dst->stride;
2784 src_start += src->stride;
2791 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
2793 for(y = src_rect->top; y < src_rect->bottom; y++)
2795 dst_pixel = dst_start;
2796 src_pixel = src_start;
2797 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
2801 src_val = *src_pixel++ & 0xf;
2803 src_val = (*src_pixel >> 4) & 0xf;
2804 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
2805 rgb = src->color_table[src_val];
2806 dst_val = colorref_to_pixel_colortable(dst, RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue)) ? 0xff : 0;
2808 if(bit_pos == 0) *dst_pixel = 0;
2809 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
2819 if(bit_pos != 0) dst_pixel++;
2820 memset(dst_pixel, 0, pad_size);
2822 dst_start += dst->stride;
2823 src_start += src->stride;
2828 /* Note that while MSDN states that a 1 bpp dib brush -> mono dc
2829 uses text/bkgnd colours instead of the dib's colour table, this
2830 doesn't appear to be the case for a dc backed by a
2835 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
2836 for(y = src_rect->top; y < src_rect->bottom; y++)
2838 dst_pixel = dst_start;
2839 src_pixel = src_start;
2840 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
2843 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
2844 if((x % 8) == 7) src_pixel++;
2845 rgb = src->color_table[src_val];
2846 dst_val = colorref_to_pixel_colortable(dst, RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue)) ? 0xff : 0;
2848 if(bit_pos == 0) *dst_pixel = 0;
2849 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
2859 if(bit_pos != 0) dst_pixel++;
2860 memset(dst_pixel, 0, pad_size);
2862 dst_start += dst->stride;
2863 src_start += src->stride;
2869 FIXME("Unsupported conversion: %d -> 1\n", src->bit_count);
2876 static BOOL convert_to_null(dib_info *dst, const dib_info *src, const RECT *src_rect)
2881 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)
2883 BYTE *hatch_start = hatch->bits, *hatch_ptr;
2884 DWORD mask_start = 0, mask_offset;
2885 DWORD *and_bits = bits->and, *xor_bits = bits->xor;
2888 for(y = 0; y < hatch->height; y++)
2890 hatch_ptr = hatch_start;
2891 mask_offset = mask_start;
2892 for(x = 0; x < hatch->width; x++)
2894 if(*hatch_ptr & pixel_masks_1[x % 8])
2896 and_bits[mask_offset] = fg->and;
2897 xor_bits[mask_offset] = fg->xor;
2901 and_bits[mask_offset] = bg->and;
2902 xor_bits[mask_offset] = bg->xor;
2904 if(x % 8 == 7) hatch_ptr++;
2907 hatch_start += hatch->stride;
2908 mask_start += dib->stride / 4;
2914 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)
2916 BYTE *hatch_start = hatch->bits, *hatch_ptr;
2917 DWORD mask_start = 0, mask_offset;
2918 BYTE *and_bits = bits->and, *xor_bits = bits->xor;
2921 for(y = 0; y < hatch->height; y++)
2923 hatch_ptr = hatch_start;
2924 mask_offset = mask_start;
2925 for(x = 0; x < hatch->width; x++)
2927 if(*hatch_ptr & pixel_masks_1[x % 8])
2929 and_bits[mask_offset] = fg->and & 0xff;
2930 xor_bits[mask_offset++] = fg->xor & 0xff;
2931 and_bits[mask_offset] = (fg->and >> 8) & 0xff;
2932 xor_bits[mask_offset++] = (fg->xor >> 8) & 0xff;
2933 and_bits[mask_offset] = (fg->and >> 16) & 0xff;
2934 xor_bits[mask_offset++] = (fg->xor >> 16) & 0xff;
2938 and_bits[mask_offset] = bg->and & 0xff;
2939 xor_bits[mask_offset++] = bg->xor & 0xff;
2940 and_bits[mask_offset] = (bg->and >> 8) & 0xff;
2941 xor_bits[mask_offset++] = (bg->xor >> 8) & 0xff;
2942 and_bits[mask_offset] = (bg->and >> 16) & 0xff;
2943 xor_bits[mask_offset++] = (bg->xor >> 16) & 0xff;
2945 if(x % 8 == 7) hatch_ptr++;
2947 hatch_start += hatch->stride;
2948 mask_start += dib->stride;
2954 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)
2956 BYTE *hatch_start = hatch->bits, *hatch_ptr;
2957 DWORD mask_start = 0, mask_offset;
2958 WORD *and_bits = bits->and, *xor_bits = bits->xor;
2961 for(y = 0; y < hatch->height; y++)
2963 hatch_ptr = hatch_start;
2964 mask_offset = mask_start;
2965 for(x = 0; x < hatch->width; x++)
2967 if(*hatch_ptr & pixel_masks_1[x % 8])
2969 and_bits[mask_offset] = fg->and;
2970 xor_bits[mask_offset] = fg->xor;
2974 and_bits[mask_offset] = bg->and;
2975 xor_bits[mask_offset] = bg->xor;
2977 if(x % 8 == 7) hatch_ptr++;
2980 hatch_start += hatch->stride;
2981 mask_start += dib->stride / 2;
2987 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)
2989 BYTE *hatch_start = hatch->bits, *hatch_ptr;
2990 DWORD mask_start = 0, mask_offset;
2991 BYTE *and_bits = bits->and, *xor_bits = bits->xor;
2994 for(y = 0; y < hatch->height; y++)
2996 hatch_ptr = hatch_start;
2997 mask_offset = mask_start;
2998 for(x = 0; x < hatch->width; x++)
3000 if(*hatch_ptr & pixel_masks_1[x % 8])
3002 and_bits[mask_offset] = fg->and;
3003 xor_bits[mask_offset] = fg->xor;
3007 and_bits[mask_offset] = bg->and;
3008 xor_bits[mask_offset] = bg->xor;
3010 if(x % 8 == 7) hatch_ptr++;
3013 hatch_start += hatch->stride;
3014 mask_start += dib->stride;
3020 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)
3022 BYTE *hatch_start = hatch->bits, *hatch_ptr;
3023 DWORD mask_start = 0, mask_offset;
3024 BYTE *and_bits = bits->and, *xor_bits = bits->xor;
3025 const rop_mask *rop_mask;
3028 for(y = 0; y < hatch->height; y++)
3030 hatch_ptr = hatch_start;
3031 mask_offset = mask_start;
3032 for(x = 0; x < hatch->width; x++)
3034 if(*hatch_ptr & pixel_masks_1[x % 8])
3041 and_bits[mask_offset] = (rop_mask->and & 0x0f) | (and_bits[mask_offset] & 0xf0);
3042 xor_bits[mask_offset] = (rop_mask->xor & 0x0f) | (xor_bits[mask_offset] & 0xf0);
3047 and_bits[mask_offset] = (rop_mask->and << 4) & 0xf0;
3048 xor_bits[mask_offset] = (rop_mask->xor << 4) & 0xf0;
3051 if(x % 8 == 7) hatch_ptr++;
3053 hatch_start += hatch->stride;
3054 mask_start += dib->stride;
3060 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)
3062 BYTE *hatch_start = hatch->bits, *hatch_ptr;
3063 DWORD mask_start = 0, mask_offset;
3064 BYTE *and_bits = bits->and, *xor_bits = bits->xor;
3068 for(y = 0; y < hatch->height; y++)
3070 hatch_ptr = hatch_start;
3071 mask_offset = mask_start;
3072 for(x = 0, bit_pos = 0; x < hatch->width; x++)
3074 if(*hatch_ptr & pixel_masks_1[x % 8])
3076 rop_mask.and = (fg->and & 1) ? 0xff : 0;
3077 rop_mask.xor = (fg->xor & 1) ? 0xff : 0;
3081 rop_mask.and = (bg->and & 1) ? 0xff : 0;
3082 rop_mask.xor = (bg->xor & 1) ? 0xff : 0;
3085 if(bit_pos == 0) and_bits[mask_offset] = xor_bits[mask_offset] = 0;
3087 and_bits[mask_offset] = (rop_mask.and & pixel_masks_1[bit_pos]) | (and_bits[mask_offset] & ~pixel_masks_1[bit_pos]);
3088 xor_bits[mask_offset] = (rop_mask.xor & pixel_masks_1[bit_pos]) | (xor_bits[mask_offset] & ~pixel_masks_1[bit_pos]);
3097 hatch_start += hatch->stride;
3098 mask_start += dib->stride;
3104 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)
3109 const primitive_funcs funcs_8888 =
3113 colorref_to_pixel_888,
3118 const primitive_funcs funcs_32 =
3122 colorref_to_pixel_masks,
3127 const primitive_funcs funcs_24 =
3131 colorref_to_pixel_888,
3136 const primitive_funcs funcs_555 =
3140 colorref_to_pixel_555,
3145 const primitive_funcs funcs_16 =
3149 colorref_to_pixel_masks,
3154 const primitive_funcs funcs_8 =
3158 colorref_to_pixel_colortable,
3163 const primitive_funcs funcs_4 =
3167 colorref_to_pixel_colortable,
3172 const primitive_funcs funcs_1 =
3176 colorref_to_pixel_colortable,
3181 const primitive_funcs funcs_null =
3185 colorref_to_pixel_null,
3187 create_rop_masks_null