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 /* special case for conversion to 1-bpp without a color table:
696 * we get a 1-entry table containing the background color
698 if (dib->bit_count == 1 && dib->color_table_size == 1)
699 return (rgb.rgbRed == dib->color_table[0].rgbRed &&
700 rgb.rgbGreen == dib->color_table[0].rgbGreen &&
701 rgb.rgbBlue == dib->color_table[0].rgbBlue);
703 for(i = 0; i < dib->color_table_size; i++)
705 RGBQUAD *cur = dib->color_table + i;
706 diff = (rgb.rgbRed - cur->rgbRed) * (rgb.rgbRed - cur->rgbRed)
707 + (rgb.rgbGreen - cur->rgbGreen) * (rgb.rgbGreen - cur->rgbGreen)
708 + (rgb.rgbBlue - cur->rgbBlue) * (rgb.rgbBlue - cur->rgbBlue);
725 static DWORD colorref_to_pixel_null(const dib_info *dib, COLORREF color)
730 static inline BOOL bit_fields_match(const dib_info *d1, const dib_info *d2)
732 assert( d1->bit_count > 8 && d1->bit_count == d2->bit_count );
734 return d1->red_mask == d2->red_mask &&
735 d1->green_mask == d2->green_mask &&
736 d1->blue_mask == d2->blue_mask;
739 static BOOL convert_to_8888(dib_info *dst, const dib_info *src, const RECT *src_rect)
741 DWORD *dst_start = dst->bits, *dst_pixel, src_val;
742 int x, y, pad_size = (dst->width - (src_rect->right - src_rect->left)) * 4;
744 switch(src->bit_count)
748 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
749 if(src->funcs == &funcs_8888)
751 if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
752 memcpy(dst->bits, src_start, (src_rect->bottom - src_rect->top) * src->stride);
755 for(y = src_rect->top; y < src_rect->bottom; y++)
757 memcpy(dst_start, src_start, (src_rect->right - src_rect->left) * 4);
758 if(pad_size) memset(dst_start + (src_rect->right - src_rect->left), 0, pad_size);
759 dst_start += dst->stride / 4;
760 src_start += src->stride / 4;
764 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
766 for(y = src_rect->top; y < src_rect->bottom; y++)
768 dst_pixel = dst_start;
769 src_pixel = src_start;
770 for(x = src_rect->left; x < src_rect->right; x++)
772 src_val = *src_pixel++;
773 *dst_pixel++ = (((src_val >> src->red_shift) & 0xff) << 16) |
774 (((src_val >> src->green_shift) & 0xff) << 8) |
775 ((src_val >> src->blue_shift) & 0xff);
777 if(pad_size) memset(dst_pixel, 0, pad_size);
778 dst_start += dst->stride / 4;
779 src_start += src->stride / 4;
784 FIXME("Unsupported conversion: 32 (%08x, %08x, %08x) -> 8888\n", src->red_mask, src->green_mask, src->blue_mask);
792 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
794 for(y = src_rect->top; y < src_rect->bottom; y++)
796 dst_pixel = dst_start;
797 src_pixel = src_start;
798 for(x = src_rect->left; x < src_rect->right; x++)
801 rgb.rgbBlue = *src_pixel++;
802 rgb.rgbGreen = *src_pixel++;
803 rgb.rgbRed = *src_pixel++;
805 *dst_pixel++ = ((rgb.rgbRed << 16) & 0xff0000) | ((rgb.rgbGreen << 8) & 0x00ff00) | (rgb.rgbBlue & 0x0000ff);
807 if(pad_size) memset(dst_pixel, 0, pad_size);
808 dst_start += dst->stride / 4;
809 src_start += src->stride;
816 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
817 if(src->funcs == &funcs_555)
819 for(y = src_rect->top; y < src_rect->bottom; y++)
821 dst_pixel = dst_start;
822 src_pixel = src_start;
823 for(x = src_rect->left; x < src_rect->right; x++)
825 src_val = *src_pixel++;
826 *dst_pixel++ = ((src_val << 9) & 0xf80000) | ((src_val << 4) & 0x070000) |
827 ((src_val << 6) & 0x00f800) | ((src_val << 1) & 0x000700) |
828 ((src_val << 3) & 0x0000f8) | ((src_val >> 2) & 0x000007);
830 if(pad_size) memset(dst_pixel, 0, pad_size);
831 dst_start += dst->stride / 4;
832 src_start += src->stride / 2;
835 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
837 for(y = src_rect->top; y < src_rect->bottom; y++)
839 dst_pixel = dst_start;
840 src_pixel = src_start;
841 for(x = src_rect->left; x < src_rect->right; x++)
843 src_val = *src_pixel++;
844 *dst_pixel++ = (((src_val >> src->red_shift) << 19) & 0xf80000) |
845 (((src_val >> src->red_shift) << 14) & 0x070000) |
846 (((src_val >> src->green_shift) << 11) & 0x00f800) |
847 (((src_val >> src->green_shift) << 6) & 0x000700) |
848 (((src_val >> src->blue_shift) << 3) & 0x0000f8) |
849 (((src_val >> src->blue_shift) >> 2) & 0x000007);
851 if(pad_size) memset(dst_pixel, 0, pad_size);
852 dst_start += dst->stride / 4;
853 src_start += src->stride / 2;
856 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
858 for(y = src_rect->top; y < src_rect->bottom; y++)
860 dst_pixel = dst_start;
861 src_pixel = src_start;
862 for(x = src_rect->left; x < src_rect->right; x++)
864 src_val = *src_pixel++;
865 *dst_pixel++ = (((src_val >> src->red_shift) << 19) & 0xf80000) |
866 (((src_val >> src->red_shift) << 14) & 0x070000) |
867 (((src_val >> src->green_shift) << 10) & 0x00fc00) |
868 (((src_val >> src->green_shift) << 4) & 0x000300) |
869 (((src_val >> src->blue_shift) << 3) & 0x0000f8) |
870 (((src_val >> src->blue_shift) >> 2) & 0x000007);
872 if(pad_size) memset(dst_pixel, 0, pad_size);
873 dst_start += dst->stride / 4;
874 src_start += src->stride / 2;
879 FIXME("Unsupported conversion: 16 (%08x, %08x, %08x) -> 8888\n", src->red_mask, src->green_mask, src->blue_mask);
887 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
888 for(y = src_rect->top; y < src_rect->bottom; y++)
890 dst_pixel = dst_start;
891 src_pixel = src_start;
892 for(x = src_rect->left; x < src_rect->right; x++)
895 src_val = *src_pixel++;
896 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
897 rgb = src->color_table[src_val];
898 *dst_pixel++ = rgb.rgbRed << 16 | rgb.rgbGreen << 8 | rgb.rgbBlue;
900 if(pad_size) memset(dst_pixel, 0, pad_size);
901 dst_start += dst->stride / 4;
902 src_start += src->stride;
909 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
910 for(y = src_rect->top; y < src_rect->bottom; y++)
912 dst_pixel = dst_start;
913 src_pixel = src_start;
914 for(x = src_rect->left; x < src_rect->right; x++)
918 src_val = *src_pixel++ & 0xf;
920 src_val = (*src_pixel >> 4) & 0xf;
921 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
922 rgb = src->color_table[src_val];
923 *dst_pixel++ = rgb.rgbRed << 16 | rgb.rgbGreen << 8 | rgb.rgbBlue;
925 if(pad_size) memset(dst_pixel, 0, pad_size);
926 dst_start += dst->stride / 4;
927 src_start += src->stride;
934 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
935 for(y = src_rect->top; y < src_rect->bottom; y++)
937 dst_pixel = dst_start;
938 src_pixel = src_start;
939 for(x = src_rect->left; x < src_rect->right; x++)
942 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
943 if((x % 8) == 7) src_pixel++;
944 rgb = src->color_table[src_val];
945 *dst_pixel++ = rgb.rgbRed << 16 | rgb.rgbGreen << 8 | rgb.rgbBlue;
947 if(pad_size) memset(dst_pixel, 0, pad_size);
948 dst_start += dst->stride / 4;
949 src_start += src->stride;
955 FIXME("Unsupported conversion: %d -> 8888\n", src->bit_count);
962 static BOOL convert_to_32(dib_info *dst, const dib_info *src, const RECT *src_rect)
964 DWORD *dst_start = dst->bits, *dst_pixel, src_val;
965 int x, y, pad_size = (dst->width - (src_rect->right - src_rect->left)) * 4;
967 switch(src->bit_count)
971 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
973 if(src->funcs == &funcs_8888)
975 for(y = src_rect->top; y < src_rect->bottom; y++)
977 dst_pixel = dst_start;
978 src_pixel = src_start;
979 for(x = src_rect->left; x < src_rect->right; x++)
981 src_val = *src_pixel++;
982 *dst_pixel++ = put_field((src_val >> 16) & 0xff, dst->red_shift, dst->red_len) |
983 put_field((src_val >> 8) & 0xff, dst->green_shift, dst->green_len) |
984 put_field( src_val & 0xff, dst->blue_shift, dst->blue_len);
986 if(pad_size) memset(dst_pixel, 0, pad_size);
987 dst_start += dst->stride / 4;
988 src_start += src->stride / 4;
991 else if(bit_fields_match(src, dst))
993 if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
994 memcpy(dst->bits, src_start, (src_rect->bottom - src_rect->top) * src->stride);
997 for(y = src_rect->top; y < src_rect->bottom; y++)
999 memcpy(dst_start, src_start, (src_rect->right - src_rect->left) * 4);
1000 if(pad_size) memset(dst_start + (src_rect->right - src_rect->left), 0, pad_size);
1001 dst_start += dst->stride / 4;
1002 src_start += src->stride / 4;
1006 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8 &&
1007 dst->red_len == 8 && dst->green_len == 8 && dst->blue_len == 8)
1009 for(y = src_rect->top; y < src_rect->bottom; y++)
1011 dst_pixel = dst_start;
1012 src_pixel = src_start;
1013 for(x = src_rect->left; x < src_rect->right; x++)
1015 src_val = *src_pixel++;
1016 *dst_pixel++ = (((src_val >> src->red_shift) & 0xff) << dst->red_shift) |
1017 (((src_val >> src->green_shift) & 0xff) << dst->green_shift) |
1018 (((src_val >> src->blue_shift) & 0xff) << dst->blue_shift);
1020 if(pad_size) memset(dst_pixel, 0, pad_size);
1021 dst_start += dst->stride / 4;
1022 src_start += src->stride / 4;
1027 FIXME("Unsupported conversion: 32 (%08x, %08x, %08x) -> 32 (%08x, %08x, %08x)\n",
1028 src->red_mask, src->green_mask, src->blue_mask, dst->red_mask, dst->green_mask, dst->blue_mask);
1036 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
1038 for(y = src_rect->top; y < src_rect->bottom; y++)
1040 dst_pixel = dst_start;
1041 src_pixel = src_start;
1042 for(x = src_rect->left; x < src_rect->right; x++)
1045 rgb.rgbBlue = *src_pixel++;
1046 rgb.rgbGreen = *src_pixel++;
1047 rgb.rgbRed = *src_pixel++;
1049 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
1050 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
1051 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
1053 if(pad_size) memset(dst_pixel, 0, pad_size);
1054 dst_start += dst->stride / 4;
1055 src_start += src->stride;
1062 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
1063 if(src->funcs == &funcs_555)
1065 for(y = src_rect->top; y < src_rect->bottom; y++)
1067 dst_pixel = dst_start;
1068 src_pixel = src_start;
1069 for(x = src_rect->left; x < src_rect->right; x++)
1071 src_val = *src_pixel++;
1072 *dst_pixel++ = put_field(((src_val >> 7) & 0xf8) | ((src_val >> 12) & 0x07), dst->red_shift, dst->red_len) |
1073 put_field(((src_val >> 2) & 0xf8) | ((src_val >> 7) & 0x07), dst->green_shift, dst->green_len) |
1074 put_field(((src_val << 3) & 0xf8) | ((src_val >> 2) & 0x07), dst->blue_shift, dst->blue_len);
1076 if(pad_size) memset(dst_pixel, 0, pad_size);
1077 dst_start += dst->stride / 4;
1078 src_start += src->stride / 2;
1081 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
1083 for(y = src_rect->top; y < src_rect->bottom; y++)
1085 dst_pixel = dst_start;
1086 src_pixel = src_start;
1087 for(x = src_rect->left; x < src_rect->right; x++)
1089 src_val = *src_pixel++;
1090 *dst_pixel++ = put_field( (((src_val >> src->red_shift) << 3) & 0xf8) |
1091 (((src_val >> src->red_shift) >> 2) & 0x07), dst->red_shift, dst->red_len ) |
1092 put_field( (((src_val >> src->green_shift) << 3) & 0xf8) |
1093 (((src_val >> src->green_shift) >> 2) & 0x07), dst->green_shift, dst->green_len ) |
1094 put_field( (((src_val >> src->blue_shift) << 3) & 0xf8) |
1095 (((src_val >> src->blue_shift) >> 2) & 0x07), dst->blue_shift, dst->blue_len);
1097 if(pad_size) memset(dst_pixel, 0, pad_size);
1098 dst_start += dst->stride / 4;
1099 src_start += src->stride / 2;
1102 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
1104 for(y = src_rect->top; y < src_rect->bottom; y++)
1106 dst_pixel = dst_start;
1107 src_pixel = src_start;
1108 for(x = src_rect->left; x < src_rect->right; x++)
1110 src_val = *src_pixel++;
1111 *dst_pixel++ = put_field( (((src_val >> src->red_shift) << 3) & 0xf8) |
1112 (((src_val >> src->red_shift) >> 2) & 0x07), dst->red_shift, dst->red_len ) |
1113 put_field( (((src_val >> src->green_shift) << 2) & 0xfc) |
1114 (((src_val >> src->green_shift) >> 4) & 0x03), dst->green_shift, dst->green_len ) |
1115 put_field( (((src_val >> src->blue_shift) << 3) & 0xf8) |
1116 (((src_val >> src->blue_shift) >> 2) & 0x07), dst->blue_shift, dst->blue_len);
1118 if(pad_size) memset(dst_pixel, 0, pad_size);
1119 dst_start += dst->stride / 4;
1120 src_start += src->stride / 2;
1125 FIXME("Unsupported conversion: 16 (%08x, %08x, %08x) -> 32\n", src->red_mask, src->green_mask, src->blue_mask);
1133 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
1134 for(y = src_rect->top; y < src_rect->bottom; y++)
1136 dst_pixel = dst_start;
1137 src_pixel = src_start;
1138 for(x = src_rect->left; x < src_rect->right; x++)
1141 src_val = *src_pixel++;
1142 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
1143 rgb = src->color_table[src_val];
1144 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
1145 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
1146 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
1148 if(pad_size) memset(dst_pixel, 0, pad_size);
1149 dst_start += dst->stride / 4;
1150 src_start += src->stride;
1157 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
1158 for(y = src_rect->top; y < src_rect->bottom; y++)
1160 dst_pixel = dst_start;
1161 src_pixel = src_start;
1162 for(x = src_rect->left; x < src_rect->right; x++)
1166 src_val = *src_pixel++ & 0xf;
1168 src_val = (*src_pixel >> 4) & 0xf;
1169 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
1170 rgb = src->color_table[src_val];
1171 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
1172 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
1173 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
1175 if(pad_size) memset(dst_pixel, 0, pad_size);
1176 dst_start += dst->stride / 4;
1177 src_start += src->stride;
1184 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
1185 for(y = src_rect->top; y < src_rect->bottom; y++)
1187 dst_pixel = dst_start;
1188 src_pixel = src_start;
1189 for(x = src_rect->left; x < src_rect->right; x++)
1192 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
1193 if((x % 8) == 7) src_pixel++;
1194 rgb = src->color_table[src_val];
1195 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
1196 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
1197 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
1199 if(pad_size) memset(dst_pixel, 0, pad_size);
1200 dst_start += dst->stride / 4;
1201 src_start += src->stride;
1207 FIXME("Unsupported conversion: %d -> 32\n", src->bit_count);
1214 static BOOL convert_to_24(dib_info *dst, const dib_info *src, const RECT *src_rect)
1216 BYTE *dst_start = dst->bits, *dst_pixel;
1218 int x, y, pad_size = ((dst->width * 3 + 3) & ~3) - (src_rect->right - src_rect->left) * 3;
1220 switch(src->bit_count)
1224 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
1225 if(src->funcs == &funcs_8888)
1227 for(y = src_rect->top; y < src_rect->bottom; y++)
1229 dst_pixel = dst_start;
1230 src_pixel = src_start;
1231 for(x = src_rect->left; x < src_rect->right; x++)
1233 src_val = *src_pixel++;
1234 *dst_pixel++ = src_val & 0xff;
1235 *dst_pixel++ = (src_val >> 8) & 0xff;
1236 *dst_pixel++ = (src_val >> 16) & 0xff;
1238 if(pad_size) memset(dst_pixel, 0, pad_size);
1239 dst_start += dst->stride;
1240 src_start += src->stride / 4;
1243 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
1245 for(y = src_rect->top; y < src_rect->bottom; y++)
1247 dst_pixel = dst_start;
1248 src_pixel = src_start;
1249 for(x = src_rect->left; x < src_rect->right; x++)
1251 src_val = *src_pixel++;
1252 *dst_pixel++ = (src_val >> src->blue_shift) & 0xff;
1253 *dst_pixel++ = (src_val >> src->green_shift) & 0xff;
1254 *dst_pixel++ = (src_val >> src->red_shift) & 0xff;
1256 if(pad_size) memset(dst_pixel, 0, pad_size);
1257 dst_start += dst->stride;
1258 src_start += src->stride / 4;
1263 FIXME("Unsupported conversion: 32 (%08x, %08x, %08x) -> 24\n", src->red_mask, src->green_mask, src->blue_mask);
1271 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top);
1273 if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
1274 memcpy(dst->bits, src_start, (src_rect->bottom - src_rect->top) * src->stride);
1277 for(y = src_rect->top; y < src_rect->bottom; y++)
1279 memcpy(dst_start, src_start, (src_rect->right - src_rect->left) * 3);
1280 if(pad_size) memset(dst_start + (src_rect->right - src_rect->left) * 3, 0, pad_size);
1281 dst_start += dst->stride;
1282 src_start += src->stride;
1290 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
1291 if(src->funcs == &funcs_555)
1293 for(y = src_rect->top; y < src_rect->bottom; y++)
1295 dst_pixel = dst_start;
1296 src_pixel = src_start;
1297 for(x = src_rect->left; x < src_rect->right; x++)
1299 src_val = *src_pixel++;
1300 *dst_pixel++ = ((src_val << 3) & 0xf8) | ((src_val >> 2) & 0x07);
1301 *dst_pixel++ = ((src_val >> 2) & 0xf8) | ((src_val >> 7) & 0x07);
1302 *dst_pixel++ = ((src_val >> 7) & 0xf8) | ((src_val >> 12) & 0x07);
1304 if(pad_size) memset(dst_pixel, 0, pad_size);
1305 dst_start += dst->stride;
1306 src_start += src->stride / 2;
1309 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
1311 for(y = src_rect->top; y < src_rect->bottom; y++)
1313 dst_pixel = dst_start;
1314 src_pixel = src_start;
1315 for(x = src_rect->left; x < src_rect->right; x++)
1317 src_val = *src_pixel++;
1318 *dst_pixel++ = (((src_val >> src->blue_shift) << 3) & 0xf8) |
1319 (((src_val >> src->blue_shift) >> 2) & 0x07);
1320 *dst_pixel++ = (((src_val >> src->green_shift) << 3) & 0xf8) |
1321 (((src_val >> src->green_shift) >> 2) & 0x07);
1322 *dst_pixel++ = (((src_val >> src->red_shift) << 3) & 0xf8) |
1323 (((src_val >> src->red_shift) >> 2) & 0x07);
1325 if(pad_size) memset(dst_pixel, 0, pad_size);
1326 dst_start += dst->stride;
1327 src_start += src->stride / 2;
1330 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
1332 for(y = src_rect->top; y < src_rect->bottom; y++)
1334 dst_pixel = dst_start;
1335 src_pixel = src_start;
1336 for(x = src_rect->left; x < src_rect->right; x++)
1338 src_val = *src_pixel++;
1339 *dst_pixel++ = (((src_val >> src->blue_shift) << 3) & 0xf8) |
1340 (((src_val >> src->blue_shift) >> 2) & 0x07);
1341 *dst_pixel++ = (((src_val >> src->green_shift) << 2) & 0xfc) |
1342 (((src_val >> src->green_shift) >> 4) & 0x03);
1343 *dst_pixel++ = (((src_val >> src->red_shift) << 3) & 0xf8) |
1344 (((src_val >> src->red_shift) >> 2) & 0x07);
1346 if(pad_size) memset(dst_pixel, 0, pad_size);
1347 dst_start += dst->stride;
1348 src_start += src->stride / 2;
1353 FIXME("Unsupported conversion: 16 (%08x, %08x, %08x) -> 24\n", src->red_mask, src->green_mask, src->blue_mask);
1361 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
1362 for(y = src_rect->top; y < src_rect->bottom; y++)
1364 dst_pixel = dst_start;
1365 src_pixel = src_start;
1366 for(x = src_rect->left; x < src_rect->right; x++)
1369 src_val = *src_pixel++;
1370 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
1371 rgb = src->color_table[src_val];
1372 *dst_pixel++ = rgb.rgbBlue;
1373 *dst_pixel++ = rgb.rgbGreen;
1374 *dst_pixel++ = rgb.rgbRed;
1376 if(pad_size) memset(dst_pixel, 0, pad_size);
1377 dst_start += dst->stride;
1378 src_start += src->stride;
1385 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
1386 for(y = src_rect->top; y < src_rect->bottom; y++)
1388 dst_pixel = dst_start;
1389 src_pixel = src_start;
1390 for(x = src_rect->left; x < src_rect->right; x++)
1394 src_val = *src_pixel++ & 0xf;
1396 src_val = (*src_pixel >> 4) & 0xf;
1397 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
1398 rgb = src->color_table[src_val];
1399 *dst_pixel++ = rgb.rgbBlue;
1400 *dst_pixel++ = rgb.rgbGreen;
1401 *dst_pixel++ = rgb.rgbRed;
1403 if(pad_size) memset(dst_pixel, 0, pad_size);
1404 dst_start += dst->stride;
1405 src_start += src->stride;
1412 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
1413 for(y = src_rect->top; y < src_rect->bottom; y++)
1415 dst_pixel = dst_start;
1416 src_pixel = src_start;
1417 for(x = src_rect->left; x < src_rect->right; x++)
1420 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
1421 if((x % 8) == 7) src_pixel++;
1422 rgb = src->color_table[src_val];
1423 *dst_pixel++ = rgb.rgbBlue;
1424 *dst_pixel++ = rgb.rgbGreen;
1425 *dst_pixel++ = rgb.rgbRed;
1427 if(pad_size) memset(dst_pixel, 0, pad_size);
1428 dst_start += dst->stride;
1429 src_start += src->stride;
1435 FIXME("Unsupported conversion: %d -> 24\n", src->bit_count);
1442 static BOOL convert_to_555(dib_info *dst, const dib_info *src, const RECT *src_rect)
1444 WORD *dst_start = dst->bits, *dst_pixel;
1445 INT x, y, pad_size = ((dst->width + 1) & ~1) * 2 - (src_rect->right - src_rect->left) * 2;
1448 switch(src->bit_count)
1452 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
1454 if(src->funcs == &funcs_8888)
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++)
1462 src_val = *src_pixel++;
1463 *dst_pixel++ = ((src_val >> 9) & 0x7c00) |
1464 ((src_val >> 6) & 0x03e0) |
1465 ((src_val >> 3) & 0x001f);
1467 if(pad_size) memset(dst_pixel, 0, pad_size);
1468 dst_start += dst->stride / 2;
1469 src_start += src->stride / 4;
1472 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
1474 for(y = src_rect->top; y < src_rect->bottom; y++)
1476 dst_pixel = dst_start;
1477 src_pixel = src_start;
1478 for(x = src_rect->left; x < src_rect->right; x++)
1480 src_val = *src_pixel++;
1481 *dst_pixel++ = (((src_val >> src->red_shift) << 7) & 0x7c00) |
1482 (((src_val >> src->green_shift) << 2) & 0x03e0) |
1483 (((src_val >> src->blue_shift) >> 3) & 0x001f);
1485 if(pad_size) memset(dst_pixel, 0, pad_size);
1486 dst_start += dst->stride / 2;
1487 src_start += src->stride / 4;
1492 FIXME("Unsupported conversion: 32 (%08x, %08x, %08x) -> 555\n", src->red_mask, src->green_mask, src->blue_mask);
1500 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
1502 for(y = src_rect->top; y < src_rect->bottom; y++)
1504 dst_pixel = dst_start;
1505 src_pixel = src_start;
1506 for(x = src_rect->left; x < src_rect->right; x++)
1509 rgb.rgbBlue = *src_pixel++;
1510 rgb.rgbGreen = *src_pixel++;
1511 rgb.rgbRed = *src_pixel++;
1513 *dst_pixel++ = ((rgb.rgbRed << 7) & 0x7c00) |
1514 ((rgb.rgbGreen << 2) & 0x03e0) |
1515 ((rgb.rgbBlue >> 3) & 0x001f);
1517 if(pad_size) memset(dst_pixel, 0, pad_size);
1518 dst_start += dst->stride / 2;
1519 src_start += src->stride;
1526 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
1527 if(src->funcs == &funcs_555)
1529 if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
1530 memcpy(dst->bits, src_start, (src_rect->bottom - src_rect->top) * src->stride);
1533 for(y = src_rect->top; y < src_rect->bottom; y++)
1535 memcpy(dst_start, src_start, (src_rect->right - src_rect->left) * 2);
1536 if(pad_size) memset(dst_start + (src_rect->right - src_rect->left), 0, pad_size);
1537 dst_start += dst->stride / 2;
1538 src_start += src->stride / 2;
1542 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
1544 for(y = src_rect->top; y < src_rect->bottom; y++)
1546 dst_pixel = dst_start;
1547 src_pixel = src_start;
1548 for(x = src_rect->left; x < src_rect->right; x++)
1550 src_val = *src_pixel++;
1551 *dst_pixel++ = (((src_val >> src->red_shift) << 10) & 0x7c00) |
1552 (((src_val >> src->green_shift) << 5) & 0x03e0) |
1553 ( (src_val >> src->blue_shift) & 0x001f);
1555 if(pad_size) memset(dst_pixel, 0, pad_size);
1556 dst_start += dst->stride / 2;
1557 src_start += src->stride / 2;
1560 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
1562 for(y = src_rect->top; y < src_rect->bottom; y++)
1564 dst_pixel = dst_start;
1565 src_pixel = src_start;
1566 for(x = src_rect->left; x < src_rect->right; x++)
1568 src_val = *src_pixel++;
1569 *dst_pixel++ = (((src_val >> src->red_shift) << 10) & 0x7c00) |
1570 (((src_val >> src->green_shift) << 4) & 0x03e0) |
1571 ( (src_val >> src->blue_shift) & 0x001f);
1573 if(pad_size) memset(dst_pixel, 0, pad_size);
1574 dst_start += dst->stride / 2;
1575 src_start += src->stride / 2;
1580 FIXME("Unsupported conversion: 16 (%08x, %08x, %08x) -> 555\n", src->red_mask, src->green_mask, src->blue_mask);
1588 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
1589 for(y = src_rect->top; y < src_rect->bottom; y++)
1591 dst_pixel = dst_start;
1592 src_pixel = src_start;
1593 for(x = src_rect->left; x < src_rect->right; x++)
1596 src_val = *src_pixel++;
1597 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
1598 rgb = src->color_table[src_val];
1599 *dst_pixel++ = ((rgb.rgbRed << 7) & 0x7c00) |
1600 ((rgb.rgbGreen << 2) & 0x03e0) |
1601 ((rgb.rgbBlue >> 3) & 0x001f);
1603 if(pad_size) memset(dst_pixel, 0, pad_size);
1604 dst_start += dst->stride / 2;
1605 src_start += src->stride;
1612 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
1613 for(y = src_rect->top; y < src_rect->bottom; y++)
1615 dst_pixel = dst_start;
1616 src_pixel = src_start;
1617 for(x = src_rect->left; x < src_rect->right; x++)
1621 src_val = *src_pixel++ & 0xf;
1623 src_val = (*src_pixel >> 4) & 0xf;
1624 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
1625 rgb = src->color_table[src_val];
1626 *dst_pixel++ = ((rgb.rgbRed << 7) & 0x7c00) |
1627 ((rgb.rgbGreen << 2) & 0x03e0) |
1628 ((rgb.rgbBlue >> 3) & 0x001f);
1630 if(pad_size) memset(dst_pixel, 0, pad_size);
1631 dst_start += dst->stride / 2;
1632 src_start += src->stride;
1639 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
1640 for(y = src_rect->top; y < src_rect->bottom; y++)
1642 dst_pixel = dst_start;
1643 src_pixel = src_start;
1644 for(x = src_rect->left; x < src_rect->right; x++)
1647 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
1648 if((x % 8) == 7) src_pixel++;
1649 rgb = src->color_table[src_val];
1650 *dst_pixel++ = ((rgb.rgbRed << 7) & 0x7c00) |
1651 ((rgb.rgbGreen << 2) & 0x03e0) |
1652 ((rgb.rgbBlue >> 3) & 0x001f);
1654 if(pad_size) memset(dst_pixel, 0, pad_size);
1655 dst_start += dst->stride / 2;
1656 src_start += src->stride;
1662 FIXME("Unsupported conversion: %d -> 555\n", src->bit_count);
1669 static BOOL convert_to_16(dib_info *dst, const dib_info *src, const RECT *src_rect)
1671 WORD *dst_start = dst->bits, *dst_pixel;
1672 INT x, y, pad_size = ((dst->width + 1) & ~1) * 2 - (src_rect->right - src_rect->left) * 2;
1675 switch(src->bit_count)
1679 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
1681 if(src->funcs == &funcs_8888)
1683 for(y = src_rect->top; y < src_rect->bottom; y++)
1685 dst_pixel = dst_start;
1686 src_pixel = src_start;
1687 for(x = src_rect->left; x < src_rect->right; x++)
1689 src_val = *src_pixel++;
1690 *dst_pixel++ = put_field((src_val >> 16) & 0xff, dst->red_shift, dst->red_len) |
1691 put_field((src_val >> 8) & 0xff, dst->green_shift, dst->green_len) |
1692 put_field( src_val & 0xff, dst->blue_shift, dst->blue_len);
1694 if(pad_size) memset(dst_pixel, 0, pad_size);
1695 dst_start += dst->stride / 2;
1696 src_start += src->stride / 4;
1699 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
1701 for(y = src_rect->top; y < src_rect->bottom; y++)
1703 dst_pixel = dst_start;
1704 src_pixel = src_start;
1705 for(x = src_rect->left; x < src_rect->right; x++)
1707 src_val = *src_pixel++;
1708 *dst_pixel++ = put_field((src_val >> src->red_shift) & 0xff, dst->red_shift, dst->red_len) |
1709 put_field((src_val >> src->green_shift) & 0xff, dst->green_shift, dst->green_len) |
1710 put_field((src_val >> src->blue_shift) & 0xff, dst->blue_shift, dst->blue_len);
1712 if(pad_size) memset(dst_pixel, 0, pad_size);
1713 dst_start += dst->stride / 2;
1714 src_start += src->stride / 4;
1719 FIXME("Unsupported conversion: 32 (%08x, %08x, %08x) -> 16\n", src->red_mask, src->green_mask, src->blue_mask);
1727 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
1729 for(y = src_rect->top; y < src_rect->bottom; y++)
1731 dst_pixel = dst_start;
1732 src_pixel = src_start;
1733 for(x = src_rect->left; x < src_rect->right; x++)
1736 rgb.rgbBlue = *src_pixel++;
1737 rgb.rgbGreen = *src_pixel++;
1738 rgb.rgbRed = *src_pixel++;
1740 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
1741 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
1742 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
1744 if(pad_size) memset(dst_pixel, 0, pad_size);
1745 dst_start += dst->stride / 2;
1746 src_start += src->stride;
1753 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
1754 if(src->funcs == &funcs_555)
1756 for(y = src_rect->top; y < src_rect->bottom; y++)
1758 dst_pixel = dst_start;
1759 src_pixel = src_start;
1760 for(x = src_rect->left; x < src_rect->right; x++)
1762 src_val = *src_pixel++;
1763 *dst_pixel++ = put_field(((src_val >> 7) & 0xf8) | ((src_val >> 12) & 0x07), dst->red_shift, dst->red_len) |
1764 put_field(((src_val >> 2) & 0xf8) | ((src_val >> 7) & 0x07), dst->green_shift, dst->green_len) |
1765 put_field(((src_val << 3) & 0xf8) | ((src_val >> 2) & 0x07), dst->blue_shift, dst->blue_len);
1767 if(pad_size) memset(dst_pixel, 0, pad_size);
1768 dst_start += dst->stride / 2;
1769 src_start += src->stride / 2;
1772 else if(bit_fields_match(src, dst))
1774 if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
1775 memcpy(dst->bits, src_start, (src_rect->bottom - src_rect->top) * src->stride);
1778 for(y = src_rect->top; y < src_rect->bottom; y++)
1780 memcpy(dst_start, src_start, (src_rect->right - src_rect->left) * 2);
1781 if(pad_size) memset(dst_start + (src_rect->right - src_rect->left), 0, pad_size);
1782 dst_start += dst->stride / 2;
1783 src_start += src->stride / 2;
1787 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
1789 for(y = src_rect->top; y < src_rect->bottom; y++)
1791 dst_pixel = dst_start;
1792 src_pixel = src_start;
1793 for(x = src_rect->left; x < src_rect->right; x++)
1795 src_val = *src_pixel++;
1796 *dst_pixel++ = put_field( (((src_val >> src->red_shift) << 3) & 0xf8) |
1797 (((src_val >> src->red_shift) >> 2) & 0x07), dst->red_shift, dst->red_len ) |
1798 put_field( (((src_val >> src->green_shift) << 3) & 0xf8) |
1799 (((src_val >> src->green_shift) >> 2) & 0x07), dst->green_shift, dst->green_len ) |
1800 put_field( (((src_val >> src->blue_shift) << 3) & 0xf8) |
1801 (((src_val >> src->blue_shift) >> 2) & 0x07), dst->blue_shift, dst->blue_len);
1803 if(pad_size) memset(dst_pixel, 0, pad_size);
1804 dst_start += dst->stride / 2;
1805 src_start += src->stride / 2;
1808 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
1810 for(y = src_rect->top; y < src_rect->bottom; y++)
1812 dst_pixel = dst_start;
1813 src_pixel = src_start;
1814 for(x = src_rect->left; x < src_rect->right; x++)
1816 src_val = *src_pixel++;
1817 *dst_pixel++ = put_field( (((src_val >> src->red_shift) << 3) & 0xf8) |
1818 (((src_val >> src->red_shift) >> 2) & 0x07), dst->red_shift, dst->red_len ) |
1819 put_field( (((src_val >> src->green_shift) << 2) & 0xfc) |
1820 (((src_val >> src->green_shift) >> 4) & 0x03), dst->green_shift, dst->green_len ) |
1821 put_field( (((src_val >> src->blue_shift) << 3) & 0xf8) |
1822 (((src_val >> src->blue_shift) >> 2) & 0x07), dst->blue_shift, dst->blue_len);
1824 if(pad_size) memset(dst_pixel, 0, pad_size);
1825 dst_start += dst->stride / 2;
1826 src_start += src->stride / 2;
1831 FIXME("Unsupported conversion: 16 (%08x, %08x, %08x) -> 16 (%08x, %08x, %08x)\n",
1832 src->red_mask, src->green_mask, src->blue_mask, dst->red_mask, dst->green_mask, dst->blue_mask);
1840 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
1841 for(y = src_rect->top; y < src_rect->bottom; y++)
1843 dst_pixel = dst_start;
1844 src_pixel = src_start;
1845 for(x = src_rect->left; x < src_rect->right; x++)
1848 src_val = *src_pixel++;
1849 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
1850 rgb = src->color_table[src_val];
1851 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
1852 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
1853 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
1855 if(pad_size) memset(dst_pixel, 0, pad_size);
1856 dst_start += dst->stride / 2;
1857 src_start += src->stride;
1864 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
1865 for(y = src_rect->top; y < src_rect->bottom; y++)
1867 dst_pixel = dst_start;
1868 src_pixel = src_start;
1869 for(x = src_rect->left; x < src_rect->right; x++)
1873 src_val = *src_pixel++ & 0xf;
1875 src_val = (*src_pixel >> 4) & 0xf;
1876 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
1877 rgb = src->color_table[src_val];
1878 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
1879 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
1880 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
1882 if(pad_size) memset(dst_pixel, 0, pad_size);
1883 dst_start += dst->stride / 2;
1884 src_start += src->stride;
1891 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
1892 for(y = src_rect->top; y < src_rect->bottom; y++)
1894 dst_pixel = dst_start;
1895 src_pixel = src_start;
1896 for(x = src_rect->left; x < src_rect->right; x++)
1899 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
1900 if((x % 8) == 7) src_pixel++;
1901 rgb = src->color_table[src_val];
1902 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
1903 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
1904 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
1906 if(pad_size) memset(dst_pixel, 0, pad_size);
1907 dst_start += dst->stride / 2;
1908 src_start += src->stride;
1914 FIXME("Unsupported conversion: %d -> 16\n", src->bit_count);
1921 static inline BOOL color_tables_match(const dib_info *d1, const dib_info *d2)
1923 assert(d1->color_table_size && d2->color_table_size);
1925 if(d1->color_table_size != d2->color_table_size) return FALSE;
1926 return !memcmp(d1->color_table, d2->color_table, d1->color_table_size * sizeof(d1->color_table[0]));
1929 static BOOL convert_to_8(dib_info *dst, const dib_info *src, const RECT *src_rect)
1931 BYTE *dst_start = dst->bits, *dst_pixel;
1932 INT x, y, pad_size = ((dst->width + 3) & ~3) - (src_rect->right - src_rect->left);
1935 switch(src->bit_count)
1939 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
1941 if(src->funcs == &funcs_8888)
1943 for(y = src_rect->top; y < src_rect->bottom; y++)
1945 dst_pixel = dst_start;
1946 src_pixel = src_start;
1947 for(x = src_rect->left; x < src_rect->right; x++)
1949 src_val = *src_pixel++;
1950 *dst_pixel++ = colorref_to_pixel_colortable(dst, ((src_val >> 16) & 0x0000ff) |
1951 ( src_val & 0x00ff00) |
1952 ((src_val << 16) & 0xff0000) );
1954 if(pad_size) memset(dst_pixel, 0, pad_size);
1955 dst_start += dst->stride;
1956 src_start += src->stride / 4;
1959 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
1961 for(y = src_rect->top; y < src_rect->bottom; y++)
1963 dst_pixel = dst_start;
1964 src_pixel = src_start;
1965 for(x = src_rect->left; x < src_rect->right; x++)
1967 src_val = *src_pixel++;
1968 *dst_pixel++ = colorref_to_pixel_colortable(dst, ( (src_val >> src->red_shift) & 0x0000ff) |
1969 (((src_val >> src->green_shift) << 8) & 0x00ff00) |
1970 (((src_val >> src->blue_shift) << 16) & 0xff0000) );
1972 if(pad_size) memset(dst_pixel, 0, pad_size);
1973 dst_start += dst->stride;
1974 src_start += src->stride / 4;
1979 FIXME("Unsupported conversion: 32 (%08x, %08x, %08x) -> 8\n", src->red_mask, src->green_mask, src->blue_mask);
1987 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
1989 for(y = src_rect->top; y < src_rect->bottom; y++)
1991 dst_pixel = dst_start;
1992 src_pixel = src_start;
1993 for(x = src_rect->left; x < src_rect->right; x++)
1996 rgb.rgbBlue = *src_pixel++;
1997 rgb.rgbGreen = *src_pixel++;
1998 rgb.rgbRed = *src_pixel++;
2000 *dst_pixel++ = colorref_to_pixel_colortable(dst, ( rgb.rgbRed & 0x0000ff) |
2001 ((rgb.rgbGreen << 8) & 0x00ff00) |
2002 ((rgb.rgbBlue << 16) & 0xff0000));
2004 if(pad_size) memset(dst_pixel, 0, pad_size);
2005 dst_start += dst->stride;
2006 src_start += src->stride;
2013 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
2014 if(src->funcs == &funcs_555)
2016 for(y = src_rect->top; y < src_rect->bottom; y++)
2018 dst_pixel = dst_start;
2019 src_pixel = src_start;
2020 for(x = src_rect->left; x < src_rect->right; x++)
2022 src_val = *src_pixel++;
2023 *dst_pixel++ = colorref_to_pixel_colortable(dst, ((src_val >> 7) & 0x0000f8) | ((src_val >> 12) & 0x000007) |
2024 ((src_val << 6) & 0x00f800) | ((src_val << 1) & 0x000700) |
2025 ((src_val << 19) & 0xf80000) | ((src_val << 14) & 0x070000) );
2027 if(pad_size) memset(dst_pixel, 0, pad_size);
2028 dst_start += dst->stride;
2029 src_start += src->stride / 2;
2032 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
2034 for(y = src_rect->top; y < src_rect->bottom; y++)
2036 dst_pixel = dst_start;
2037 src_pixel = src_start;
2038 for(x = src_rect->left; x < src_rect->right; x++)
2040 src_val = *src_pixel++;
2041 *dst_pixel++ = colorref_to_pixel_colortable(dst, (((src_val >> src->red_shift) << 3) & 0x0000f8) |
2042 (((src_val >> src->red_shift) >> 2) & 0x000007) |
2043 (((src_val >> src->green_shift) << 11) & 0x00f800) |
2044 (((src_val >> src->green_shift) << 6) & 0x000700) |
2045 (((src_val >> src->blue_shift) << 19) & 0xf80000) |
2046 (((src_val >> src->blue_shift) << 14) & 0x070000) );
2048 if(pad_size) memset(dst_pixel, 0, pad_size);
2049 dst_start += dst->stride;
2050 src_start += src->stride / 2;
2053 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
2055 for(y = src_rect->top; y < src_rect->bottom; y++)
2057 dst_pixel = dst_start;
2058 src_pixel = src_start;
2059 for(x = src_rect->left; x < src_rect->right; x++)
2061 src_val = *src_pixel++;
2062 *dst_pixel++ = colorref_to_pixel_colortable(dst, (((src_val >> src->red_shift) << 3) & 0x0000f8) |
2063 (((src_val >> src->red_shift) >> 2) & 0x000007) |
2064 (((src_val >> src->green_shift) << 10) & 0x00fc00) |
2065 (((src_val >> src->green_shift) << 4) & 0x000300) |
2066 (((src_val >> src->blue_shift) << 19) & 0xf80000) |
2067 (((src_val >> src->blue_shift) << 14) & 0x070000) );
2069 if(pad_size) memset(dst_pixel, 0, pad_size);
2070 dst_start += dst->stride;
2071 src_start += src->stride / 2;
2076 FIXME("Unsupported conversion: 16 (%08x, %08x, %08x) -> 8\n", src->red_mask, src->green_mask, src->blue_mask);
2084 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
2086 if(color_tables_match(dst, src))
2088 if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
2089 memcpy(dst->bits, src_start, (src_rect->bottom - src_rect->top) * src->stride);
2092 for(y = src_rect->top; y < src_rect->bottom; y++)
2094 memcpy(dst_start, src_start, src_rect->right - src_rect->left);
2095 if(pad_size) memset(dst_start + (src_rect->right - src_rect->left), 0, pad_size);
2096 dst_start += dst->stride;
2097 src_start += src->stride;
2103 for(y = src_rect->top; y < src_rect->bottom; y++)
2105 dst_pixel = dst_start;
2106 src_pixel = src_start;
2107 for(x = src_rect->left; x < src_rect->right; x++)
2110 src_val = *src_pixel++;
2111 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
2112 rgb = src->color_table[src_val];
2113 *dst_pixel++ = colorref_to_pixel_colortable(dst, RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue));
2115 if(pad_size) memset(dst_pixel, 0, pad_size);
2116 dst_start += dst->stride;
2117 src_start += src->stride;
2125 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
2126 for(y = src_rect->top; y < src_rect->bottom; y++)
2128 dst_pixel = dst_start;
2129 src_pixel = src_start;
2130 for(x = src_rect->left; x < src_rect->right; x++)
2134 src_val = *src_pixel++ & 0xf;
2136 src_val = (*src_pixel >> 4) & 0xf;
2137 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
2138 rgb = src->color_table[src_val];
2139 *dst_pixel++ = colorref_to_pixel_colortable(dst, RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue));
2141 if(pad_size) memset(dst_pixel, 0, pad_size);
2142 dst_start += dst->stride;
2143 src_start += src->stride;
2150 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
2151 for(y = src_rect->top; y < src_rect->bottom; y++)
2153 dst_pixel = dst_start;
2154 src_pixel = src_start;
2155 for(x = src_rect->left; x < src_rect->right; x++)
2158 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
2159 if((x % 8) == 7) src_pixel++;
2160 rgb = src->color_table[src_val];
2161 *dst_pixel++ = colorref_to_pixel_colortable(dst, RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue));
2163 if(pad_size) memset(dst_pixel, 0, pad_size);
2164 dst_start += dst->stride;
2165 src_start += src->stride;
2171 FIXME("Unsupported conversion: %d -> 8\n", src->bit_count);
2178 static BOOL convert_to_4(dib_info *dst, const dib_info *src, const RECT *src_rect)
2180 BYTE *dst_start = dst->bits, *dst_pixel, dst_val;
2181 INT x, y, pad_size = ((dst->width + 7) & ~7) / 2 - (src_rect->right - src_rect->left + 1) / 2;
2184 switch(src->bit_count)
2188 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
2190 if(src->funcs == &funcs_8888)
2192 for(y = src_rect->top; y < src_rect->bottom; y++)
2194 dst_pixel = dst_start;
2195 src_pixel = src_start;
2196 for(x = src_rect->left; x < src_rect->right; x++)
2198 src_val = *src_pixel++;
2199 dst_val = colorref_to_pixel_colortable(dst, ((src_val >> 16) & 0x0000ff) |
2200 ( src_val & 0x00ff00) |
2201 ((src_val << 16) & 0xff0000) );
2202 if((x - src_rect->left) & 1)
2204 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
2208 *dst_pixel = (dst_val << 4) & 0xf0;
2212 if((x - src_rect->left) & 1) dst_pixel++;
2213 memset(dst_pixel, 0, pad_size);
2215 dst_start += dst->stride;
2216 src_start += src->stride / 4;
2219 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
2221 for(y = src_rect->top; y < src_rect->bottom; y++)
2223 dst_pixel = dst_start;
2224 src_pixel = src_start;
2225 for(x = src_rect->left; x < src_rect->right; x++)
2227 src_val = *src_pixel++;
2228 dst_val = colorref_to_pixel_colortable(dst, ( (src_val >> src->red_shift) & 0x0000ff) |
2229 (((src_val >> src->green_shift) << 8) & 0x00ff00) |
2230 (((src_val >> src->blue_shift) << 16) & 0xff0000) );
2231 if((x - src_rect->left) & 1)
2233 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
2237 *dst_pixel = (dst_val << 4) & 0xf0;
2241 if((x - src_rect->left) & 1) dst_pixel++;
2242 memset(dst_pixel, 0, pad_size);
2244 dst_start += dst->stride;
2245 src_start += src->stride / 4;
2250 FIXME("Unsupported conversion: 32 (%08x, %08x, %08x) -> 4\n", src->red_mask, src->green_mask, src->blue_mask);
2258 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
2260 for(y = src_rect->top; y < src_rect->bottom; y++)
2262 dst_pixel = dst_start;
2263 src_pixel = src_start;
2264 for(x = src_rect->left; x < src_rect->right; x++)
2267 rgb.rgbBlue = *src_pixel++;
2268 rgb.rgbGreen = *src_pixel++;
2269 rgb.rgbRed = *src_pixel++;
2271 dst_val = colorref_to_pixel_colortable(dst, ( rgb.rgbRed & 0x0000ff) |
2272 ((rgb.rgbGreen << 8) & 0x00ff00) |
2273 ((rgb.rgbBlue << 16) & 0xff0000));
2275 if((x - src_rect->left) & 1)
2277 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
2281 *dst_pixel = (dst_val << 4) & 0xf0;
2285 if((x - src_rect->left) & 1) dst_pixel++;
2286 memset(dst_pixel, 0, pad_size);
2288 dst_start += dst->stride;
2289 src_start += src->stride;
2296 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
2297 if(src->funcs == &funcs_555)
2299 for(y = src_rect->top; y < src_rect->bottom; y++)
2301 dst_pixel = dst_start;
2302 src_pixel = src_start;
2303 for(x = src_rect->left; x < src_rect->right; x++)
2305 src_val = *src_pixel++;
2306 dst_val = colorref_to_pixel_colortable(dst, ((src_val >> 7) & 0x0000f8) | ((src_val >> 12) & 0x000007) |
2307 ((src_val << 6) & 0x00f800) | ((src_val << 1) & 0x000700) |
2308 ((src_val << 19) & 0xf80000) | ((src_val << 14) & 0x070000) );
2309 if((x - src_rect->left) & 1)
2311 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
2315 *dst_pixel = (dst_val << 4) & 0xf0;
2319 if((x - src_rect->left) & 1) dst_pixel++;
2320 memset(dst_pixel, 0, pad_size);
2322 dst_start += dst->stride;
2323 src_start += src->stride / 2;
2326 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
2328 for(y = src_rect->top; y < src_rect->bottom; y++)
2330 dst_pixel = dst_start;
2331 src_pixel = src_start;
2332 for(x = src_rect->left; x < src_rect->right; x++)
2334 src_val = *src_pixel++;
2335 dst_val = colorref_to_pixel_colortable(dst, (((src_val >> src->red_shift) << 3) & 0x0000f8) |
2336 (((src_val >> src->red_shift) >> 2) & 0x000007) |
2337 (((src_val >> src->green_shift) << 11) & 0x00f800) |
2338 (((src_val >> src->green_shift) << 6) & 0x000700) |
2339 (((src_val >> src->blue_shift) << 19) & 0xf80000) |
2340 (((src_val >> src->blue_shift) << 14) & 0x070000) );
2341 if((x - src_rect->left) & 1)
2343 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
2347 *dst_pixel = (dst_val << 4) & 0xf0;
2351 if((x - src_rect->left) & 1) dst_pixel++;
2352 memset(dst_pixel, 0, pad_size);
2354 dst_start += dst->stride;
2355 src_start += src->stride / 2;
2358 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
2360 for(y = src_rect->top; y < src_rect->bottom; y++)
2362 dst_pixel = dst_start;
2363 src_pixel = src_start;
2364 for(x = src_rect->left; x < src_rect->right; x++)
2366 src_val = *src_pixel++;
2367 dst_val = colorref_to_pixel_colortable(dst, (((src_val >> src->red_shift) << 3) & 0x0000f8) |
2368 (((src_val >> src->red_shift) >> 2) & 0x000007) |
2369 (((src_val >> src->green_shift) << 10) & 0x00fc00) |
2370 (((src_val >> src->green_shift) << 4) & 0x000300) |
2371 (((src_val >> src->blue_shift) << 19) & 0xf80000) |
2372 (((src_val >> src->blue_shift) << 14) & 0x070000) );
2373 if((x - src_rect->left) & 1)
2375 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
2379 *dst_pixel = (dst_val << 4) & 0xf0;
2383 if((x - src_rect->left) & 1) dst_pixel++;
2384 memset(dst_pixel, 0, pad_size);
2386 dst_start += dst->stride;
2387 src_start += src->stride / 2;
2392 FIXME("Unsupported conversion: 16 (%08x, %08x, %08x) -> 4\n", src->red_mask, src->green_mask, src->blue_mask);
2400 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
2402 for(y = src_rect->top; y < src_rect->bottom; y++)
2404 dst_pixel = dst_start;
2405 src_pixel = src_start;
2406 for(x = src_rect->left; x < src_rect->right; x++)
2409 src_val = *src_pixel++;
2410 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
2411 rgb = src->color_table[src_val];
2412 dst_val = colorref_to_pixel_colortable(dst, RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue));
2413 if((x - src_rect->left) & 1)
2415 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
2419 *dst_pixel = (dst_val << 4) & 0xf0;
2423 if((x - src_rect->left) & 1) dst_pixel++;
2424 memset(dst_pixel, 0, pad_size);
2426 dst_start += dst->stride;
2427 src_start += src->stride;
2434 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
2436 if(color_tables_match(dst, src) && (src_rect->left & 1) == 0)
2438 if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
2439 memcpy(dst->bits, src_start, (src_rect->bottom - src_rect->top) * src->stride);
2442 for(y = src_rect->top; y < src_rect->bottom; y++)
2444 memcpy(dst_start, src_start, (src_rect->right - src_rect->left + 1) / 2);
2445 if(pad_size) memset(dst_start + (src_rect->right - src_rect->left + 1) / 2, 0, pad_size);
2446 dst_start += dst->stride;
2447 src_start += src->stride;
2453 for(y = src_rect->top; y < src_rect->bottom; y++)
2455 dst_pixel = dst_start;
2456 src_pixel = src_start;
2457 for(x = src_rect->left; x < src_rect->right; x++)
2461 src_val = *src_pixel++ & 0xf;
2463 src_val = (*src_pixel >> 4) & 0xf;
2464 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
2465 rgb = src->color_table[src_val];
2466 dst_val = colorref_to_pixel_colortable(dst, RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue));
2467 if((x - src_rect->left) & 1)
2469 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
2473 *dst_pixel = (dst_val << 4) & 0xf0;
2477 if((x - src_rect->left) & 1) dst_pixel++;
2478 memset(dst_pixel, 0, pad_size);
2480 dst_start += dst->stride;
2481 src_start += src->stride;
2489 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
2490 for(y = src_rect->top; y < src_rect->bottom; y++)
2492 dst_pixel = dst_start;
2493 src_pixel = src_start;
2494 for(x = src_rect->left; x < src_rect->right; x++)
2497 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
2498 if((x % 8) == 7) src_pixel++;
2499 rgb = src->color_table[src_val];
2500 dst_val = colorref_to_pixel_colortable(dst, RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue));
2501 if((x - src_rect->left) & 1)
2503 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
2507 *dst_pixel = (dst_val << 4) & 0xf0;
2511 if((x - src_rect->left) & 1) dst_pixel++;
2512 memset(dst_pixel, 0, pad_size);
2514 dst_start += dst->stride;
2515 src_start += src->stride;
2521 FIXME("Unsupported conversion: %d -> 4\n", src->bit_count);
2529 static BOOL convert_to_1(dib_info *dst, const dib_info *src, const RECT *src_rect)
2531 BYTE *dst_start = dst->bits, *dst_pixel, dst_val;
2532 INT x, y, pad_size = ((dst->width + 31) & ~31) / 8 - (src_rect->right - src_rect->left + 7) / 8;
2536 /* FIXME: Brushes should be dithered. */
2538 switch(src->bit_count)
2542 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
2544 if(src->funcs == &funcs_8888)
2546 for(y = src_rect->top; y < src_rect->bottom; y++)
2548 dst_pixel = dst_start;
2549 src_pixel = src_start;
2550 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
2552 src_val = *src_pixel++;
2553 dst_val = colorref_to_pixel_colortable(dst, ((src_val >> 16) & 0x0000ff) |
2554 ( src_val & 0x00ff00) |
2555 ((src_val << 16) & 0xff0000) ) ? 0xff : 0;
2557 if(bit_pos == 0) *dst_pixel = 0;
2558 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
2568 if(bit_pos != 0) dst_pixel++;
2569 memset(dst_pixel, 0, pad_size);
2571 dst_start += dst->stride;
2572 src_start += src->stride / 4;
2575 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
2577 for(y = src_rect->top; y < src_rect->bottom; y++)
2579 dst_pixel = dst_start;
2580 src_pixel = src_start;
2581 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
2583 src_val = *src_pixel++;
2584 dst_val = colorref_to_pixel_colortable(dst, ( (src_val >> src->red_shift) & 0x0000ff) |
2585 (((src_val >> src->green_shift) << 8) & 0x00ff00) |
2586 (((src_val >> src->blue_shift) << 16) & 0xff0000) ) ? 0xff : 0;
2588 if(bit_pos == 0) *dst_pixel = 0;
2589 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
2599 if(bit_pos != 0) dst_pixel++;
2600 memset(dst_pixel, 0, pad_size);
2602 dst_start += dst->stride;
2603 src_start += src->stride / 4;
2608 FIXME("Unsupported conversion: 32 (%08x, %08x, %08x) -> 1\n", src->red_mask, src->green_mask, src->blue_mask);
2616 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
2618 for(y = src_rect->top; y < src_rect->bottom; y++)
2620 dst_pixel = dst_start;
2621 src_pixel = src_start;
2622 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
2625 rgb.rgbBlue = *src_pixel++;
2626 rgb.rgbGreen = *src_pixel++;
2627 rgb.rgbRed = *src_pixel++;
2629 dst_val = colorref_to_pixel_colortable(dst, ( rgb.rgbRed & 0x0000ff) |
2630 ((rgb.rgbGreen << 8) & 0x00ff00) |
2631 ((rgb.rgbBlue << 16) & 0xff0000)) ? 0xff : 0;
2633 if(bit_pos == 0) *dst_pixel = 0;
2634 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
2644 if(bit_pos != 0) dst_pixel++;
2645 memset(dst_pixel, 0, pad_size);
2647 dst_start += dst->stride;
2648 src_start += src->stride;
2655 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
2656 if(src->funcs == &funcs_555)
2658 for(y = src_rect->top; y < src_rect->bottom; y++)
2660 dst_pixel = dst_start;
2661 src_pixel = src_start;
2662 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
2664 src_val = *src_pixel++;
2665 dst_val = colorref_to_pixel_colortable(dst, ((src_val >> 7) & 0x0000f8) | ((src_val >> 12) & 0x000007) |
2666 ((src_val << 6) & 0x00f800) | ((src_val << 1) & 0x000700) |
2667 ((src_val << 19) & 0xf80000) | ((src_val << 14) & 0x070000) ) ? 0xff : 0;
2669 if(bit_pos == 0) *dst_pixel = 0;
2670 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
2680 if(bit_pos != 0) dst_pixel++;
2681 memset(dst_pixel, 0, pad_size);
2683 dst_start += dst->stride;
2684 src_start += src->stride / 2;
2687 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
2689 for(y = src_rect->top; y < src_rect->bottom; y++)
2691 dst_pixel = dst_start;
2692 src_pixel = src_start;
2693 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
2695 src_val = *src_pixel++;
2696 dst_val = colorref_to_pixel_colortable(dst, (((src_val >> src->red_shift) << 3) & 0x0000f8) |
2697 (((src_val >> src->red_shift) >> 2) & 0x000007) |
2698 (((src_val >> src->green_shift) << 11) & 0x00f800) |
2699 (((src_val >> src->green_shift) << 6) & 0x000700) |
2700 (((src_val >> src->blue_shift) << 19) & 0xf80000) |
2701 (((src_val >> src->blue_shift) << 14) & 0x070000) ) ? 0xff : 0;
2702 if(bit_pos == 0) *dst_pixel = 0;
2703 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
2713 if(bit_pos != 0) dst_pixel++;
2714 memset(dst_pixel, 0, pad_size);
2716 dst_start += dst->stride;
2717 src_start += src->stride / 2;
2720 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
2722 for(y = src_rect->top; y < src_rect->bottom; y++)
2724 dst_pixel = dst_start;
2725 src_pixel = src_start;
2726 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
2728 src_val = *src_pixel++;
2729 dst_val = colorref_to_pixel_colortable(dst, (((src_val >> src->red_shift) << 3) & 0x0000f8) |
2730 (((src_val >> src->red_shift) >> 2) & 0x000007) |
2731 (((src_val >> src->green_shift) << 10) & 0x00fc00) |
2732 (((src_val >> src->green_shift) << 4) & 0x000300) |
2733 (((src_val >> src->blue_shift) << 19) & 0xf80000) |
2734 (((src_val >> src->blue_shift) << 14) & 0x070000) );
2735 if(bit_pos == 0) *dst_pixel = 0;
2736 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
2746 if(bit_pos != 0) dst_pixel++;
2747 memset(dst_pixel, 0, pad_size);
2749 dst_start += dst->stride;
2750 src_start += src->stride / 2;
2755 FIXME("Unsupported conversion: 16 (%08x, %08x, %08x) -> 1\n", src->red_mask, src->green_mask, src->blue_mask);
2763 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
2765 for(y = src_rect->top; y < src_rect->bottom; y++)
2767 dst_pixel = dst_start;
2768 src_pixel = src_start;
2769 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
2772 src_val = *src_pixel++;
2773 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
2774 rgb = src->color_table[src_val];
2775 dst_val = colorref_to_pixel_colortable(dst, RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue)) ? 0xff : 0;
2777 if(bit_pos == 0) *dst_pixel = 0;
2778 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
2788 if(bit_pos != 0) dst_pixel++;
2789 memset(dst_pixel, 0, pad_size);
2791 dst_start += dst->stride;
2792 src_start += src->stride;
2799 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
2801 for(y = src_rect->top; y < src_rect->bottom; y++)
2803 dst_pixel = dst_start;
2804 src_pixel = src_start;
2805 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
2809 src_val = *src_pixel++ & 0xf;
2811 src_val = (*src_pixel >> 4) & 0xf;
2812 if(src_val >= src->color_table_size) src_val = src->color_table_size - 1;
2813 rgb = src->color_table[src_val];
2814 dst_val = colorref_to_pixel_colortable(dst, RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue)) ? 0xff : 0;
2816 if(bit_pos == 0) *dst_pixel = 0;
2817 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
2827 if(bit_pos != 0) dst_pixel++;
2828 memset(dst_pixel, 0, pad_size);
2830 dst_start += dst->stride;
2831 src_start += src->stride;
2836 /* Note that while MSDN states that a 1 bpp dib brush -> mono dc
2837 uses text/bkgnd colours instead of the dib's colour table, this
2838 doesn't appear to be the case for a dc backed by a
2843 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
2844 for(y = src_rect->top; y < src_rect->bottom; y++)
2846 dst_pixel = dst_start;
2847 src_pixel = src_start;
2848 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
2851 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
2852 if((x % 8) == 7) src_pixel++;
2853 rgb = src->color_table[src_val];
2854 dst_val = colorref_to_pixel_colortable(dst, RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue)) ? 0xff : 0;
2856 if(bit_pos == 0) *dst_pixel = 0;
2857 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
2867 if(bit_pos != 0) dst_pixel++;
2868 memset(dst_pixel, 0, pad_size);
2870 dst_start += dst->stride;
2871 src_start += src->stride;
2877 FIXME("Unsupported conversion: %d -> 1\n", src->bit_count);
2884 static BOOL convert_to_null(dib_info *dst, const dib_info *src, const RECT *src_rect)
2889 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)
2891 BYTE *hatch_start = hatch->bits, *hatch_ptr;
2892 DWORD mask_start = 0, mask_offset;
2893 DWORD *and_bits = bits->and, *xor_bits = bits->xor;
2896 for(y = 0; y < hatch->height; y++)
2898 hatch_ptr = hatch_start;
2899 mask_offset = mask_start;
2900 for(x = 0; x < hatch->width; x++)
2902 if(*hatch_ptr & pixel_masks_1[x % 8])
2904 and_bits[mask_offset] = fg->and;
2905 xor_bits[mask_offset] = fg->xor;
2909 and_bits[mask_offset] = bg->and;
2910 xor_bits[mask_offset] = bg->xor;
2912 if(x % 8 == 7) hatch_ptr++;
2915 hatch_start += hatch->stride;
2916 mask_start += dib->stride / 4;
2922 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)
2924 BYTE *hatch_start = hatch->bits, *hatch_ptr;
2925 DWORD mask_start = 0, mask_offset;
2926 BYTE *and_bits = bits->and, *xor_bits = bits->xor;
2929 for(y = 0; y < hatch->height; y++)
2931 hatch_ptr = hatch_start;
2932 mask_offset = mask_start;
2933 for(x = 0; x < hatch->width; x++)
2935 if(*hatch_ptr & pixel_masks_1[x % 8])
2937 and_bits[mask_offset] = fg->and & 0xff;
2938 xor_bits[mask_offset++] = fg->xor & 0xff;
2939 and_bits[mask_offset] = (fg->and >> 8) & 0xff;
2940 xor_bits[mask_offset++] = (fg->xor >> 8) & 0xff;
2941 and_bits[mask_offset] = (fg->and >> 16) & 0xff;
2942 xor_bits[mask_offset++] = (fg->xor >> 16) & 0xff;
2946 and_bits[mask_offset] = bg->and & 0xff;
2947 xor_bits[mask_offset++] = bg->xor & 0xff;
2948 and_bits[mask_offset] = (bg->and >> 8) & 0xff;
2949 xor_bits[mask_offset++] = (bg->xor >> 8) & 0xff;
2950 and_bits[mask_offset] = (bg->and >> 16) & 0xff;
2951 xor_bits[mask_offset++] = (bg->xor >> 16) & 0xff;
2953 if(x % 8 == 7) hatch_ptr++;
2955 hatch_start += hatch->stride;
2956 mask_start += dib->stride;
2962 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)
2964 BYTE *hatch_start = hatch->bits, *hatch_ptr;
2965 DWORD mask_start = 0, mask_offset;
2966 WORD *and_bits = bits->and, *xor_bits = bits->xor;
2969 for(y = 0; y < hatch->height; y++)
2971 hatch_ptr = hatch_start;
2972 mask_offset = mask_start;
2973 for(x = 0; x < hatch->width; x++)
2975 if(*hatch_ptr & pixel_masks_1[x % 8])
2977 and_bits[mask_offset] = fg->and;
2978 xor_bits[mask_offset] = fg->xor;
2982 and_bits[mask_offset] = bg->and;
2983 xor_bits[mask_offset] = bg->xor;
2985 if(x % 8 == 7) hatch_ptr++;
2988 hatch_start += hatch->stride;
2989 mask_start += dib->stride / 2;
2995 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)
2997 BYTE *hatch_start = hatch->bits, *hatch_ptr;
2998 DWORD mask_start = 0, mask_offset;
2999 BYTE *and_bits = bits->and, *xor_bits = bits->xor;
3002 for(y = 0; y < hatch->height; y++)
3004 hatch_ptr = hatch_start;
3005 mask_offset = mask_start;
3006 for(x = 0; x < hatch->width; x++)
3008 if(*hatch_ptr & pixel_masks_1[x % 8])
3010 and_bits[mask_offset] = fg->and;
3011 xor_bits[mask_offset] = fg->xor;
3015 and_bits[mask_offset] = bg->and;
3016 xor_bits[mask_offset] = bg->xor;
3018 if(x % 8 == 7) hatch_ptr++;
3021 hatch_start += hatch->stride;
3022 mask_start += dib->stride;
3028 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)
3030 BYTE *hatch_start = hatch->bits, *hatch_ptr;
3031 DWORD mask_start = 0, mask_offset;
3032 BYTE *and_bits = bits->and, *xor_bits = bits->xor;
3033 const rop_mask *rop_mask;
3036 for(y = 0; y < hatch->height; y++)
3038 hatch_ptr = hatch_start;
3039 mask_offset = mask_start;
3040 for(x = 0; x < hatch->width; x++)
3042 if(*hatch_ptr & pixel_masks_1[x % 8])
3049 and_bits[mask_offset] = (rop_mask->and & 0x0f) | (and_bits[mask_offset] & 0xf0);
3050 xor_bits[mask_offset] = (rop_mask->xor & 0x0f) | (xor_bits[mask_offset] & 0xf0);
3055 and_bits[mask_offset] = (rop_mask->and << 4) & 0xf0;
3056 xor_bits[mask_offset] = (rop_mask->xor << 4) & 0xf0;
3059 if(x % 8 == 7) hatch_ptr++;
3061 hatch_start += hatch->stride;
3062 mask_start += dib->stride;
3068 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)
3070 BYTE *hatch_start = hatch->bits, *hatch_ptr;
3071 DWORD mask_start = 0, mask_offset;
3072 BYTE *and_bits = bits->and, *xor_bits = bits->xor;
3076 for(y = 0; y < hatch->height; y++)
3078 hatch_ptr = hatch_start;
3079 mask_offset = mask_start;
3080 for(x = 0, bit_pos = 0; x < hatch->width; x++)
3082 if(*hatch_ptr & pixel_masks_1[x % 8])
3084 rop_mask.and = (fg->and & 1) ? 0xff : 0;
3085 rop_mask.xor = (fg->xor & 1) ? 0xff : 0;
3089 rop_mask.and = (bg->and & 1) ? 0xff : 0;
3090 rop_mask.xor = (bg->xor & 1) ? 0xff : 0;
3093 if(bit_pos == 0) and_bits[mask_offset] = xor_bits[mask_offset] = 0;
3095 and_bits[mask_offset] = (rop_mask.and & pixel_masks_1[bit_pos]) | (and_bits[mask_offset] & ~pixel_masks_1[bit_pos]);
3096 xor_bits[mask_offset] = (rop_mask.xor & pixel_masks_1[bit_pos]) | (xor_bits[mask_offset] & ~pixel_masks_1[bit_pos]);
3105 hatch_start += hatch->stride;
3106 mask_start += dib->stride;
3112 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)
3117 const primitive_funcs funcs_8888 =
3121 colorref_to_pixel_888,
3126 const primitive_funcs funcs_32 =
3130 colorref_to_pixel_masks,
3135 const primitive_funcs funcs_24 =
3139 colorref_to_pixel_888,
3144 const primitive_funcs funcs_555 =
3148 colorref_to_pixel_555,
3153 const primitive_funcs funcs_16 =
3157 colorref_to_pixel_masks,
3162 const primitive_funcs funcs_8 =
3166 colorref_to_pixel_colortable,
3171 const primitive_funcs funcs_4 =
3175 colorref_to_pixel_colortable,
3180 const primitive_funcs funcs_1 =
3184 colorref_to_pixel_colortable,
3189 const primitive_funcs funcs_null =
3193 colorref_to_pixel_null,
3195 create_rop_masks_null