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 BOOL
convert_to_8888(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
724 DWORD
*dst_start
= dst
->bits
, *dst_pixel
, src_val
;
727 switch(src
->bit_count
)
731 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
);
732 if(src
->funcs
== &funcs_8888
)
734 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
735 memcpy(dst
->bits
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
738 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
740 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 4);
741 dst_start
+= dst
->stride
/ 4;
742 src_start
+= src
->stride
/ 4;
748 FIXME("Unsupported conversion: 32 -> 8888\n");
756 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
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
++)
765 rgb
.rgbBlue
= *src_pixel
++;
766 rgb
.rgbGreen
= *src_pixel
++;
767 rgb
.rgbRed
= *src_pixel
++;
769 *dst_pixel
++ = ((rgb
.rgbRed
<< 16) & 0xff0000) | ((rgb
.rgbGreen
<< 8) & 0x00ff00) | (rgb
.rgbBlue
& 0x0000ff);
771 dst_start
+= dst
->stride
/ 4;
772 src_start
+= src
->stride
;
779 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
780 if(src
->funcs
== &funcs_555
)
782 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
784 dst_pixel
= dst_start
;
785 src_pixel
= src_start
;
786 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
788 src_val
= *src_pixel
++;
789 *dst_pixel
++ = ((src_val
<< 9) & 0xf80000) | ((src_val
<< 4) & 0x070000) |
790 ((src_val
<< 6) & 0x00f800) | ((src_val
<< 1) & 0x000700) |
791 ((src_val
<< 3) & 0x0000f8) | ((src_val
>> 2) & 0x000007);
793 dst_start
+= dst
->stride
/ 4;
794 src_start
+= src
->stride
/ 2;
799 FIXME("Unsupported conversion: 16 -> 8888\n");
807 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
808 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
810 dst_pixel
= dst_start
;
811 src_pixel
= src_start
;
812 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
815 src_val
= *src_pixel
++;
816 if(src_val
>= src
->color_table_size
) src_val
= src
->color_table_size
- 1;
817 rgb
= src
->color_table
[src_val
];
818 *dst_pixel
++ = rgb
.rgbRed
<< 16 | rgb
.rgbGreen
<< 8 | rgb
.rgbBlue
;
820 dst_start
+= dst
->stride
/ 4;
821 src_start
+= src
->stride
;
828 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
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
++)
837 src_val
= *src_pixel
++ & 0xf;
839 src_val
= (*src_pixel
>> 4) & 0xf;
840 if(src_val
>= src
->color_table_size
) src_val
= src
->color_table_size
- 1;
841 rgb
= src
->color_table
[src_val
];
842 *dst_pixel
++ = rgb
.rgbRed
<< 16 | rgb
.rgbGreen
<< 8 | rgb
.rgbBlue
;
844 dst_start
+= dst
->stride
/ 4;
845 src_start
+= src
->stride
;
852 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
853 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
855 dst_pixel
= dst_start
;
856 src_pixel
= src_start
;
857 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
860 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
861 if((x
% 8) == 7) src_pixel
++;
862 rgb
= src
->color_table
[src_val
];
863 *dst_pixel
++ = rgb
.rgbRed
<< 16 | rgb
.rgbGreen
<< 8 | rgb
.rgbBlue
;
865 dst_start
+= dst
->stride
/ 4;
866 src_start
+= src
->stride
;
872 FIXME("Unsupported conversion: %d -> 8888\n", src
->bit_count
);
879 static BOOL
convert_to_32(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
881 DWORD
*dst_start
= dst
->bits
, *dst_pixel
, src_val
;
884 switch(src
->bit_count
)
888 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
890 if(src
->funcs
== &funcs_8888
)
892 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
894 dst_pixel
= dst_start
;
895 src_pixel
= src_start
;
896 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
898 src_val
= *src_pixel
++;
899 *dst_pixel
++ = put_field((src_val
>> 16) & 0xff, dst
->red_shift
, dst
->red_len
) |
900 put_field((src_val
>> 8) & 0xff, dst
->green_shift
, dst
->green_len
) |
901 put_field( src_val
& 0xff, dst
->blue_shift
, dst
->blue_len
);
903 dst_start
+= dst
->stride
/ 4;
904 src_start
+= src
->stride
/ 4;
909 FIXME("Unsupported conversion: 32 -> 32\n");
917 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
919 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
921 dst_pixel
= dst_start
;
922 src_pixel
= src_start
;
923 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
926 rgb
.rgbBlue
= *src_pixel
++;
927 rgb
.rgbGreen
= *src_pixel
++;
928 rgb
.rgbRed
= *src_pixel
++;
930 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
931 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
932 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
934 dst_start
+= dst
->stride
/ 4;
935 src_start
+= src
->stride
;
942 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
943 if(src
->funcs
== &funcs_555
)
945 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
947 dst_pixel
= dst_start
;
948 src_pixel
= src_start
;
949 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
951 src_val
= *src_pixel
++;
952 *dst_pixel
++ = put_field(((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07), dst
->red_shift
, dst
->red_len
) |
953 put_field(((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07), dst
->green_shift
, dst
->green_len
) |
954 put_field(((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
956 dst_start
+= dst
->stride
/ 4;
957 src_start
+= src
->stride
/ 2;
962 FIXME("Unsupported conversion: 16 -> 8888\n");
970 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
971 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
973 dst_pixel
= dst_start
;
974 src_pixel
= src_start
;
975 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
978 src_val
= *src_pixel
++;
979 if(src_val
>= src
->color_table_size
) src_val
= src
->color_table_size
- 1;
980 rgb
= src
->color_table
[src_val
];
981 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
982 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
983 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
985 dst_start
+= dst
->stride
/ 4;
986 src_start
+= src
->stride
;
993 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
994 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
996 dst_pixel
= dst_start
;
997 src_pixel
= src_start
;
998 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1002 src_val
= *src_pixel
++ & 0xf;
1004 src_val
= (*src_pixel
>> 4) & 0xf;
1005 if(src_val
>= src
->color_table_size
) src_val
= src
->color_table_size
- 1;
1006 rgb
= src
->color_table
[src_val
];
1007 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
1008 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
1009 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
1011 dst_start
+= dst
->stride
/ 4;
1012 src_start
+= src
->stride
;
1019 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1020 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1022 dst_pixel
= dst_start
;
1023 src_pixel
= src_start
;
1024 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1027 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
1028 if((x
% 8) == 7) src_pixel
++;
1029 rgb
= src
->color_table
[src_val
];
1030 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
1031 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
1032 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
1034 dst_start
+= dst
->stride
/ 4;
1035 src_start
+= src
->stride
;
1041 FIXME("Unsupported conversion: %d -> 32\n", src
->bit_count
);
1048 static BOOL
convert_to_24(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
1050 BYTE
*dst_start
= dst
->bits
, *dst_pixel
;
1054 switch(src
->bit_count
)
1058 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1059 if(src
->funcs
== &funcs_8888
)
1061 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1063 dst_pixel
= dst_start
;
1064 src_pixel
= src_start
;
1065 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1067 src_val
= *src_pixel
++;
1068 *dst_pixel
++ = src_val
& 0xff;
1069 *dst_pixel
++ = (src_val
>> 8) & 0xff;
1070 *dst_pixel
++ = (src_val
>> 16) & 0xff;
1072 dst_start
+= dst
->stride
;
1073 src_start
+= src
->stride
/ 4;
1078 FIXME("Unsupported conversion: 32 -> 24\n");
1086 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
);
1088 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
1089 memcpy(dst
->bits
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
1092 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1094 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 3);
1095 dst_start
+= dst
->stride
;
1096 src_start
+= src
->stride
;
1104 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1105 if(src
->funcs
== &funcs_555
)
1107 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1109 dst_pixel
= dst_start
;
1110 src_pixel
= src_start
;
1111 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1113 src_val
= *src_pixel
++;
1114 *dst_pixel
++ = ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07);
1115 *dst_pixel
++ = ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07);
1116 *dst_pixel
++ = ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07);
1118 dst_start
+= dst
->stride
;
1119 src_start
+= src
->stride
/ 2;
1124 FIXME("Unsupported conversion: 16 -> 24\n");
1132 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1133 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1135 dst_pixel
= dst_start
;
1136 src_pixel
= src_start
;
1137 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1140 src_val
= *src_pixel
++;
1141 if(src_val
>= src
->color_table_size
) src_val
= src
->color_table_size
- 1;
1142 rgb
= src
->color_table
[src_val
];
1143 *dst_pixel
++ = rgb
.rgbBlue
;
1144 *dst_pixel
++ = rgb
.rgbGreen
;
1145 *dst_pixel
++ = rgb
.rgbRed
;
1147 dst_start
+= dst
->stride
;
1148 src_start
+= src
->stride
;
1155 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1156 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1158 dst_pixel
= dst_start
;
1159 src_pixel
= src_start
;
1160 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1164 src_val
= *src_pixel
++ & 0xf;
1166 src_val
= (*src_pixel
>> 4) & 0xf;
1167 if(src_val
>= src
->color_table_size
) src_val
= src
->color_table_size
- 1;
1168 rgb
= src
->color_table
[src_val
];
1169 *dst_pixel
++ = rgb
.rgbBlue
;
1170 *dst_pixel
++ = rgb
.rgbGreen
;
1171 *dst_pixel
++ = rgb
.rgbRed
;
1173 dst_start
+= dst
->stride
;
1174 src_start
+= src
->stride
;
1181 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1182 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1184 dst_pixel
= dst_start
;
1185 src_pixel
= src_start
;
1186 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1189 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
1190 if((x
% 8) == 7) src_pixel
++;
1191 rgb
= src
->color_table
[src_val
];
1192 *dst_pixel
++ = rgb
.rgbBlue
;
1193 *dst_pixel
++ = rgb
.rgbGreen
;
1194 *dst_pixel
++ = rgb
.rgbRed
;
1196 dst_start
+= dst
->stride
;
1197 src_start
+= src
->stride
;
1203 FIXME("Unsupported conversion: %d -> 24\n", src
->bit_count
);
1210 static BOOL
convert_to_555(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
1212 WORD
*dst_start
= dst
->bits
, *dst_pixel
;
1216 switch(src
->bit_count
)
1220 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1222 if(src
->funcs
== &funcs_8888
)
1224 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1226 dst_pixel
= dst_start
;
1227 src_pixel
= src_start
;
1228 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1230 src_val
= *src_pixel
++;
1231 *dst_pixel
++ = ((src_val
>> 9) & 0x7c00) |
1232 ((src_val
>> 6) & 0x03e0) |
1233 ((src_val
>> 3) & 0x001f);
1235 dst_start
+= dst
->stride
/ 2;
1236 src_start
+= src
->stride
/ 4;
1241 FIXME("Unsupported conversion: 32 -> 555\n");
1249 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1251 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1253 dst_pixel
= dst_start
;
1254 src_pixel
= src_start
;
1255 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1258 rgb
.rgbBlue
= *src_pixel
++;
1259 rgb
.rgbGreen
= *src_pixel
++;
1260 rgb
.rgbRed
= *src_pixel
++;
1262 *dst_pixel
++ = ((rgb
.rgbRed
<< 7) & 0x7c00) |
1263 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
1264 ((rgb
.rgbBlue
>> 3) & 0x001f);
1266 dst_start
+= dst
->stride
/ 2;
1267 src_start
+= src
->stride
;
1274 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
);
1275 if(src
->funcs
== &funcs_555
)
1277 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
1278 memcpy(dst
->bits
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
1281 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1283 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 2);
1284 dst_start
+= dst
->stride
/ 2;
1285 src_start
+= src
->stride
/ 2;
1291 FIXME("Unsupported conversion: 16 -> 555\n");
1299 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1300 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1302 dst_pixel
= dst_start
;
1303 src_pixel
= src_start
;
1304 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1307 src_val
= *src_pixel
++;
1308 if(src_val
>= src
->color_table_size
) src_val
= src
->color_table_size
- 1;
1309 rgb
= src
->color_table
[src_val
];
1310 *dst_pixel
++ = ((rgb
.rgbRed
<< 7) & 0x7c00) |
1311 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
1312 ((rgb
.rgbBlue
>> 3) & 0x001f);
1314 dst_start
+= dst
->stride
/ 2;
1315 src_start
+= src
->stride
;
1322 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1323 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1325 dst_pixel
= dst_start
;
1326 src_pixel
= src_start
;
1327 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1331 src_val
= *src_pixel
++ & 0xf;
1333 src_val
= (*src_pixel
>> 4) & 0xf;
1334 if(src_val
>= src
->color_table_size
) src_val
= src
->color_table_size
- 1;
1335 rgb
= src
->color_table
[src_val
];
1336 *dst_pixel
++ = ((rgb
.rgbRed
<< 7) & 0x7c00) |
1337 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
1338 ((rgb
.rgbBlue
>> 3) & 0x001f);
1340 dst_start
+= dst
->stride
/ 2;
1341 src_start
+= src
->stride
;
1348 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1349 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1351 dst_pixel
= dst_start
;
1352 src_pixel
= src_start
;
1353 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1356 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
1357 if((x
% 8) == 7) src_pixel
++;
1358 rgb
= src
->color_table
[src_val
];
1359 *dst_pixel
++ = ((rgb
.rgbRed
<< 7) & 0x7c00) |
1360 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
1361 ((rgb
.rgbBlue
>> 3) & 0x001f);
1363 dst_start
+= dst
->stride
/ 2;
1364 src_start
+= src
->stride
;
1370 FIXME("Unsupported conversion: %d -> 555\n", src
->bit_count
);
1377 static BOOL
convert_to_16(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
1379 WORD
*dst_start
= dst
->bits
, *dst_pixel
;
1383 switch(src
->bit_count
)
1387 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1389 if(src
->funcs
== &funcs_8888
)
1391 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1393 dst_pixel
= dst_start
;
1394 src_pixel
= src_start
;
1395 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1397 src_val
= *src_pixel
++;
1398 *dst_pixel
++ = put_field((src_val
>> 16) & 0xff, dst
->red_shift
, dst
->red_len
) |
1399 put_field((src_val
>> 8) & 0xff, dst
->green_shift
, dst
->green_len
) |
1400 put_field( src_val
& 0xff, dst
->blue_shift
, dst
->blue_len
);
1402 dst_start
+= dst
->stride
/ 2;
1403 src_start
+= src
->stride
/ 4;
1408 FIXME("Unsupported conversion: 32 -> 16\n");
1416 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1418 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1420 dst_pixel
= dst_start
;
1421 src_pixel
= src_start
;
1422 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1425 rgb
.rgbBlue
= *src_pixel
++;
1426 rgb
.rgbGreen
= *src_pixel
++;
1427 rgb
.rgbRed
= *src_pixel
++;
1429 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
1430 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
1431 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
1433 dst_start
+= dst
->stride
/ 2;
1434 src_start
+= src
->stride
;
1441 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1442 if(src
->funcs
== &funcs_555
)
1444 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1446 dst_pixel
= dst_start
;
1447 src_pixel
= src_start
;
1448 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1450 src_val
= *src_pixel
++;
1451 *dst_pixel
++ = put_field(((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07), dst
->red_shift
, dst
->red_len
) |
1452 put_field(((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07), dst
->green_shift
, dst
->green_len
) |
1453 put_field(((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
1455 dst_start
+= dst
->stride
/ 2;
1456 src_start
+= src
->stride
/ 2;
1461 FIXME("Unsupported conversion: 16 -> 16\n");
1469 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1470 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1472 dst_pixel
= dst_start
;
1473 src_pixel
= src_start
;
1474 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1477 src_val
= *src_pixel
++;
1478 if(src_val
>= src
->color_table_size
) src_val
= src
->color_table_size
- 1;
1479 rgb
= src
->color_table
[src_val
];
1480 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
1481 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
1482 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
1484 dst_start
+= dst
->stride
/ 2;
1485 src_start
+= src
->stride
;
1492 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1493 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1495 dst_pixel
= dst_start
;
1496 src_pixel
= src_start
;
1497 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1501 src_val
= *src_pixel
++ & 0xf;
1503 src_val
= (*src_pixel
>> 4) & 0xf;
1504 if(src_val
>= src
->color_table_size
) src_val
= src
->color_table_size
- 1;
1505 rgb
= src
->color_table
[src_val
];
1506 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
1507 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
1508 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
1510 dst_start
+= dst
->stride
/ 2;
1511 src_start
+= src
->stride
;
1518 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1519 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1521 dst_pixel
= dst_start
;
1522 src_pixel
= src_start
;
1523 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1526 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
1527 if((x
% 8) == 7) src_pixel
++;
1528 rgb
= src
->color_table
[src_val
];
1529 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
1530 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
1531 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
1533 dst_start
+= dst
->stride
/ 2;
1534 src_start
+= src
->stride
;
1540 FIXME("Unsupported conversion: %d -> 16\n", src
->bit_count
);
1547 static inline BOOL
color_tables_match(const dib_info
*d1
, const dib_info
*d2
)
1549 assert(d1
->color_table_size
&& d2
->color_table_size
);
1551 if(d1
->color_table_size
!= d2
->color_table_size
) return FALSE
;
1552 return !memcmp(d1
->color_table
, d2
->color_table
, d1
->color_table_size
* sizeof(d1
->color_table
[0]));
1555 static BOOL
convert_to_8(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
1557 BYTE
*dst_start
= dst
->bits
, *dst_pixel
;
1561 switch(src
->bit_count
)
1565 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1567 if(src
->funcs
== &funcs_8888
)
1569 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1571 dst_pixel
= dst_start
;
1572 src_pixel
= src_start
;
1573 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1575 src_val
= *src_pixel
++;
1576 *dst_pixel
++ = colorref_to_pixel_colortable(dst
, ((src_val
>> 16) & 0x0000ff) |
1577 ( src_val
& 0x00ff00) |
1578 ((src_val
<< 16) & 0xff0000) );
1580 dst_start
+= dst
->stride
;
1581 src_start
+= src
->stride
/ 4;
1586 FIXME("Unsupported conversion: 32 -> 8\n");
1594 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1596 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1598 dst_pixel
= dst_start
;
1599 src_pixel
= src_start
;
1600 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1603 rgb
.rgbBlue
= *src_pixel
++;
1604 rgb
.rgbGreen
= *src_pixel
++;
1605 rgb
.rgbRed
= *src_pixel
++;
1607 *dst_pixel
++ = colorref_to_pixel_colortable(dst
, ( rgb
.rgbRed
& 0x0000ff) |
1608 ((rgb
.rgbGreen
<< 8) & 0x00ff00) |
1609 ((rgb
.rgbBlue
<< 16) & 0xff0000));
1611 dst_start
+= dst
->stride
;
1612 src_start
+= src
->stride
;
1619 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1620 if(src
->funcs
== &funcs_555
)
1622 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1624 dst_pixel
= dst_start
;
1625 src_pixel
= src_start
;
1626 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1628 src_val
= *src_pixel
++;
1629 *dst_pixel
++ = colorref_to_pixel_colortable(dst
, ((src_val
>> 7) & 0x0000f8) | ((src_val
>> 12) & 0x000007) |
1630 ((src_val
<< 6) & 0x00f800) | ((src_val
<< 1) & 0x000700) |
1631 ((src_val
<< 19) & 0xf80000) | ((src_val
<< 14) & 0x070000) );
1633 dst_start
+= dst
->stride
;
1634 src_start
+= src
->stride
/ 2;
1639 FIXME("Unsupported conversion: 16 -> 8\n");
1647 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1649 if(color_tables_match(dst
, src
))
1651 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
1652 memcpy(dst
->bits
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
1655 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1657 memcpy(dst_start
, src_start
, src_rect
->right
- src_rect
->left
);
1658 dst_start
+= dst
->stride
;
1659 src_start
+= src
->stride
;
1665 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1667 dst_pixel
= dst_start
;
1668 src_pixel
= src_start
;
1669 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1672 src_val
= *src_pixel
++;
1673 if(src_val
>= src
->color_table_size
) src_val
= src
->color_table_size
- 1;
1674 rgb
= src
->color_table
[src_val
];
1675 *dst_pixel
++ = colorref_to_pixel_colortable(dst
, RGB(rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
));
1677 dst_start
+= dst
->stride
;
1678 src_start
+= src
->stride
;
1686 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1687 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1689 dst_pixel
= dst_start
;
1690 src_pixel
= src_start
;
1691 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1695 src_val
= *src_pixel
++ & 0xf;
1697 src_val
= (*src_pixel
>> 4) & 0xf;
1698 if(src_val
>= src
->color_table_size
) src_val
= src
->color_table_size
- 1;
1699 rgb
= src
->color_table
[src_val
];
1700 *dst_pixel
++ = colorref_to_pixel_colortable(dst
, RGB(rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
));
1702 dst_start
+= dst
->stride
;
1703 src_start
+= src
->stride
;
1710 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1711 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1713 dst_pixel
= dst_start
;
1714 src_pixel
= src_start
;
1715 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1718 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
1719 if((x
% 8) == 7) src_pixel
++;
1720 rgb
= src
->color_table
[src_val
];
1721 *dst_pixel
++ = colorref_to_pixel_colortable(dst
, RGB(rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
));
1723 dst_start
+= dst
->stride
;
1724 src_start
+= src
->stride
;
1730 FIXME("Unsupported conversion: %d -> 8\n", src
->bit_count
);
1737 static BOOL
convert_to_4(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
1739 BYTE
*dst_start
= dst
->bits
, *dst_pixel
, dst_val
;
1743 switch(src
->bit_count
)
1747 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1749 if(src
->funcs
== &funcs_8888
)
1751 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1753 dst_pixel
= dst_start
;
1754 src_pixel
= src_start
;
1755 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1757 src_val
= *src_pixel
++;
1758 dst_val
= colorref_to_pixel_colortable(dst
, ((src_val
>> 16) & 0x0000ff) |
1759 ( src_val
& 0x00ff00) |
1760 ((src_val
<< 16) & 0xff0000) );
1761 if((x
- src_rect
->left
) & 1)
1763 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
1767 *dst_pixel
= (dst_val
<< 4) & 0xf0;
1769 dst_start
+= dst
->stride
;
1770 src_start
+= src
->stride
/ 4;
1775 FIXME("Unsupported conversion: 32 -> 4\n");
1783 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1785 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1787 dst_pixel
= dst_start
;
1788 src_pixel
= src_start
;
1789 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1792 rgb
.rgbBlue
= *src_pixel
++;
1793 rgb
.rgbGreen
= *src_pixel
++;
1794 rgb
.rgbRed
= *src_pixel
++;
1796 dst_val
= colorref_to_pixel_colortable(dst
, ( rgb
.rgbRed
& 0x0000ff) |
1797 ((rgb
.rgbGreen
<< 8) & 0x00ff00) |
1798 ((rgb
.rgbBlue
<< 16) & 0xff0000));
1800 if((x
- src_rect
->left
) & 1)
1802 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
1806 *dst_pixel
= (dst_val
<< 4) & 0xf0;
1808 dst_start
+= dst
->stride
;
1809 src_start
+= src
->stride
;
1816 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1817 if(src
->funcs
== &funcs_555
)
1819 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1821 dst_pixel
= dst_start
;
1822 src_pixel
= src_start
;
1823 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1825 src_val
= *src_pixel
++;
1826 dst_val
= colorref_to_pixel_colortable(dst
, ((src_val
>> 7) & 0x0000f8) | ((src_val
>> 12) & 0x000007) |
1827 ((src_val
<< 6) & 0x00f800) | ((src_val
<< 1) & 0x000700) |
1828 ((src_val
<< 19) & 0xf80000) | ((src_val
<< 14) & 0x070000) );
1829 if((x
- src_rect
->left
) & 1)
1831 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
1835 *dst_pixel
= (dst_val
<< 4) & 0xf0;
1837 dst_start
+= dst
->stride
;
1838 src_start
+= src
->stride
/ 2;
1843 FIXME("Unsupported conversion: 16 -> 4\n");
1851 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1853 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1855 dst_pixel
= dst_start
;
1856 src_pixel
= src_start
;
1857 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1860 src_val
= *src_pixel
++;
1861 if(src_val
>= src
->color_table_size
) src_val
= src
->color_table_size
- 1;
1862 rgb
= src
->color_table
[src_val
];
1863 dst_val
= colorref_to_pixel_colortable(dst
, RGB(rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
));
1864 if((x
- src_rect
->left
) & 1)
1866 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
1870 *dst_pixel
= (dst_val
<< 4) & 0xf0;
1872 dst_start
+= dst
->stride
;
1873 src_start
+= src
->stride
;
1880 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1882 if(color_tables_match(dst
, src
) && (src_rect
->left
& 1) == 0)
1884 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
1885 memcpy(dst
->bits
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
1888 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1890 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
+ 1) / 2);
1891 dst_start
+= dst
->stride
;
1892 src_start
+= src
->stride
;
1898 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1900 dst_pixel
= dst_start
;
1901 src_pixel
= src_start
;
1902 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1906 src_val
= *src_pixel
++ & 0xf;
1908 src_val
= (*src_pixel
>> 4) & 0xf;
1909 if(src_val
>= src
->color_table_size
) src_val
= src
->color_table_size
- 1;
1910 rgb
= src
->color_table
[src_val
];
1911 dst_val
= colorref_to_pixel_colortable(dst
, RGB(rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
));
1912 if((x
- src_rect
->left
) & 1)
1914 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
1918 *dst_pixel
= (dst_val
<< 4) & 0xf0;
1920 dst_start
+= dst
->stride
;
1921 src_start
+= src
->stride
;
1929 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1930 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1932 dst_pixel
= dst_start
;
1933 src_pixel
= src_start
;
1934 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1937 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
1938 if((x
% 8) == 7) src_pixel
++;
1939 rgb
= src
->color_table
[src_val
];
1940 dst_val
= colorref_to_pixel_colortable(dst
, RGB(rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
));
1941 if((x
- src_rect
->left
) & 1)
1943 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
1947 *dst_pixel
= (dst_val
<< 4) & 0xf0;
1949 dst_start
+= dst
->stride
;
1950 src_start
+= src
->stride
;
1956 FIXME("Unsupported conversion: %d -> 4\n", src
->bit_count
);
1964 static BOOL
convert_to_1(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
1966 BYTE
*dst_start
= dst
->bits
, *dst_pixel
, dst_val
;
1971 /* FIXME: Brushes should be dithered. */
1973 switch(src
->bit_count
)
1977 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1979 if(src
->funcs
== &funcs_8888
)
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
, bit_pos
= 0; x
< src_rect
->right
; x
++)
1987 src_val
= *src_pixel
++;
1988 dst_val
= colorref_to_pixel_colortable(dst
, ((src_val
>> 16) & 0x0000ff) |
1989 ( src_val
& 0x00ff00) |
1990 ((src_val
<< 16) & 0xff0000) ) ? 0xff : 0;
1992 if(bit_pos
== 0) *dst_pixel
= 0;
1993 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
2001 dst_start
+= dst
->stride
;
2002 src_start
+= src
->stride
/ 4;
2007 FIXME("Unsupported conversion: 32 -> 1\n");
2015 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2017 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2019 dst_pixel
= dst_start
;
2020 src_pixel
= src_start
;
2021 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
2024 rgb
.rgbBlue
= *src_pixel
++;
2025 rgb
.rgbGreen
= *src_pixel
++;
2026 rgb
.rgbRed
= *src_pixel
++;
2028 dst_val
= colorref_to_pixel_colortable(dst
, ( rgb
.rgbRed
& 0x0000ff) |
2029 ((rgb
.rgbGreen
<< 8) & 0x00ff00) |
2030 ((rgb
.rgbBlue
<< 16) & 0xff0000)) ? 0xff : 0;
2032 if(bit_pos
== 0) *dst_pixel
= 0;
2033 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
2041 dst_start
+= dst
->stride
;
2042 src_start
+= src
->stride
;
2049 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2050 if(src
->funcs
== &funcs_555
)
2052 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2054 dst_pixel
= dst_start
;
2055 src_pixel
= src_start
;
2056 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
2058 src_val
= *src_pixel
++;
2059 dst_val
= colorref_to_pixel_colortable(dst
, ((src_val
>> 7) & 0x0000f8) | ((src_val
>> 12) & 0x000007) |
2060 ((src_val
<< 6) & 0x00f800) | ((src_val
<< 1) & 0x000700) |
2061 ((src_val
<< 19) & 0xf80000) | ((src_val
<< 14) & 0x070000) ) ? 0xff : 0;
2063 if(bit_pos
== 0) *dst_pixel
= 0;
2064 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
2072 dst_start
+= dst
->stride
;
2073 src_start
+= src
->stride
/ 2;
2078 FIXME("Unsupported conversion: 16 -> 1\n");
2086 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2088 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2090 dst_pixel
= dst_start
;
2091 src_pixel
= src_start
;
2092 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
2095 src_val
= *src_pixel
++;
2096 if(src_val
>= src
->color_table_size
) src_val
= src
->color_table_size
- 1;
2097 rgb
= src
->color_table
[src_val
];
2098 dst_val
= colorref_to_pixel_colortable(dst
, RGB(rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
)) ? 0xff : 0;
2100 if(bit_pos
== 0) *dst_pixel
= 0;
2101 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
2109 dst_start
+= dst
->stride
;
2110 src_start
+= src
->stride
;
2117 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2119 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2121 dst_pixel
= dst_start
;
2122 src_pixel
= src_start
;
2123 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
2127 src_val
= *src_pixel
++ & 0xf;
2129 src_val
= (*src_pixel
>> 4) & 0xf;
2130 if(src_val
>= src
->color_table_size
) src_val
= src
->color_table_size
- 1;
2131 rgb
= src
->color_table
[src_val
];
2132 dst_val
= colorref_to_pixel_colortable(dst
, RGB(rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
)) ? 0xff : 0;
2134 if(bit_pos
== 0) *dst_pixel
= 0;
2135 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
2143 dst_start
+= dst
->stride
;
2144 src_start
+= src
->stride
;
2149 /* Note that while MSDN states that a 1 bpp dib brush -> mono dc
2150 uses text/bkgnd colours instead of the dib's colour table, this
2151 doesn't appear to be the case for a dc backed by a
2156 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2157 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2159 dst_pixel
= dst_start
;
2160 src_pixel
= src_start
;
2161 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
2164 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
2165 if((x
% 8) == 7) src_pixel
++;
2166 rgb
= src
->color_table
[src_val
];
2167 dst_val
= colorref_to_pixel_colortable(dst
, RGB(rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
)) ? 0xff : 0;
2169 if(bit_pos
== 0) *dst_pixel
= 0;
2170 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
2178 dst_start
+= dst
->stride
;
2179 src_start
+= src
->stride
;
2185 FIXME("Unsupported conversion: %d -> 1\n", src
->bit_count
);
2192 static BOOL
convert_to_null(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
2197 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
)
2199 BYTE
*hatch_start
= hatch
->bits
, *hatch_ptr
;
2200 DWORD mask_start
= 0, mask_offset
;
2201 DWORD
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
2204 for(y
= 0; y
< hatch
->height
; y
++)
2206 hatch_ptr
= hatch_start
;
2207 mask_offset
= mask_start
;
2208 for(x
= 0; x
< hatch
->width
; x
++)
2210 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
2212 and_bits
[mask_offset
] = fg
->and;
2213 xor_bits
[mask_offset
] = fg
->xor;
2217 and_bits
[mask_offset
] = bg
->and;
2218 xor_bits
[mask_offset
] = bg
->xor;
2220 if(x
% 8 == 7) hatch_ptr
++;
2223 hatch_start
+= hatch
->stride
;
2224 mask_start
+= dib
->stride
/ 4;
2230 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
)
2232 BYTE
*hatch_start
= hatch
->bits
, *hatch_ptr
;
2233 DWORD mask_start
= 0, mask_offset
;
2234 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
2237 for(y
= 0; y
< hatch
->height
; y
++)
2239 hatch_ptr
= hatch_start
;
2240 mask_offset
= mask_start
;
2241 for(x
= 0; x
< hatch
->width
; x
++)
2243 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
2245 and_bits
[mask_offset
] = fg
->and & 0xff;
2246 xor_bits
[mask_offset
++] = fg
->xor & 0xff;
2247 and_bits
[mask_offset
] = (fg
->and >> 8) & 0xff;
2248 xor_bits
[mask_offset
++] = (fg
->xor >> 8) & 0xff;
2249 and_bits
[mask_offset
] = (fg
->and >> 16) & 0xff;
2250 xor_bits
[mask_offset
++] = (fg
->xor >> 16) & 0xff;
2254 and_bits
[mask_offset
] = bg
->and & 0xff;
2255 xor_bits
[mask_offset
++] = bg
->xor & 0xff;
2256 and_bits
[mask_offset
] = (bg
->and >> 8) & 0xff;
2257 xor_bits
[mask_offset
++] = (bg
->xor >> 8) & 0xff;
2258 and_bits
[mask_offset
] = (bg
->and >> 16) & 0xff;
2259 xor_bits
[mask_offset
++] = (bg
->xor >> 16) & 0xff;
2261 if(x
% 8 == 7) hatch_ptr
++;
2263 hatch_start
+= hatch
->stride
;
2264 mask_start
+= dib
->stride
;
2270 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
)
2272 BYTE
*hatch_start
= hatch
->bits
, *hatch_ptr
;
2273 DWORD mask_start
= 0, mask_offset
;
2274 WORD
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
2277 for(y
= 0; y
< hatch
->height
; y
++)
2279 hatch_ptr
= hatch_start
;
2280 mask_offset
= mask_start
;
2281 for(x
= 0; x
< hatch
->width
; x
++)
2283 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
2285 and_bits
[mask_offset
] = fg
->and;
2286 xor_bits
[mask_offset
] = fg
->xor;
2290 and_bits
[mask_offset
] = bg
->and;
2291 xor_bits
[mask_offset
] = bg
->xor;
2293 if(x
% 8 == 7) hatch_ptr
++;
2296 hatch_start
+= hatch
->stride
;
2297 mask_start
+= dib
->stride
/ 2;
2303 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
)
2305 BYTE
*hatch_start
= hatch
->bits
, *hatch_ptr
;
2306 DWORD mask_start
= 0, mask_offset
;
2307 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
2310 for(y
= 0; y
< hatch
->height
; y
++)
2312 hatch_ptr
= hatch_start
;
2313 mask_offset
= mask_start
;
2314 for(x
= 0; x
< hatch
->width
; x
++)
2316 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
2318 and_bits
[mask_offset
] = fg
->and;
2319 xor_bits
[mask_offset
] = fg
->xor;
2323 and_bits
[mask_offset
] = bg
->and;
2324 xor_bits
[mask_offset
] = bg
->xor;
2326 if(x
% 8 == 7) hatch_ptr
++;
2329 hatch_start
+= hatch
->stride
;
2330 mask_start
+= dib
->stride
;
2336 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
)
2338 BYTE
*hatch_start
= hatch
->bits
, *hatch_ptr
;
2339 DWORD mask_start
= 0, mask_offset
;
2340 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
2341 const rop_mask
*rop_mask
;
2344 for(y
= 0; y
< hatch
->height
; y
++)
2346 hatch_ptr
= hatch_start
;
2347 mask_offset
= mask_start
;
2348 for(x
= 0; x
< hatch
->width
; x
++)
2350 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
2357 and_bits
[mask_offset
] = (rop_mask
->and & 0x0f) | (and_bits
[mask_offset
] & 0xf0);
2358 xor_bits
[mask_offset
] = (rop_mask
->xor & 0x0f) | (xor_bits
[mask_offset
] & 0xf0);
2363 and_bits
[mask_offset
] = (rop_mask
->and << 4) & 0xf0;
2364 xor_bits
[mask_offset
] = (rop_mask
->xor << 4) & 0xf0;
2367 if(x
% 8 == 7) hatch_ptr
++;
2369 hatch_start
+= hatch
->stride
;
2370 mask_start
+= dib
->stride
;
2376 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
)
2378 BYTE
*hatch_start
= hatch
->bits
, *hatch_ptr
;
2379 DWORD mask_start
= 0, mask_offset
;
2380 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
2384 for(y
= 0; y
< hatch
->height
; y
++)
2386 hatch_ptr
= hatch_start
;
2387 mask_offset
= mask_start
;
2388 for(x
= 0, bit_pos
= 0; x
< hatch
->width
; x
++)
2390 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
2392 rop_mask
.and = (fg
->and & 1) ? 0xff : 0;
2393 rop_mask
.xor = (fg
->xor & 1) ? 0xff : 0;
2397 rop_mask
.and = (bg
->and & 1) ? 0xff : 0;
2398 rop_mask
.xor = (bg
->xor & 1) ? 0xff : 0;
2401 if(bit_pos
== 0) and_bits
[mask_offset
] = xor_bits
[mask_offset
] = 0;
2403 and_bits
[mask_offset
] = (rop_mask
.and & pixel_masks_1
[bit_pos
]) | (and_bits
[mask_offset
] & ~pixel_masks_1
[bit_pos
]);
2404 xor_bits
[mask_offset
] = (rop_mask
.xor & pixel_masks_1
[bit_pos
]) | (xor_bits
[mask_offset
] & ~pixel_masks_1
[bit_pos
]);
2413 hatch_start
+= hatch
->stride
;
2414 mask_start
+= dib
->stride
;
2420 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
)
2425 const primitive_funcs funcs_8888
=
2429 colorref_to_pixel_888
,
2434 const primitive_funcs funcs_32
=
2438 colorref_to_pixel_masks
,
2443 const primitive_funcs funcs_24
=
2447 colorref_to_pixel_888
,
2452 const primitive_funcs funcs_555
=
2456 colorref_to_pixel_555
,
2461 const primitive_funcs funcs_16
=
2465 colorref_to_pixel_masks
,
2470 const primitive_funcs funcs_8
=
2474 colorref_to_pixel_colortable
,
2479 const primitive_funcs funcs_4
=
2483 colorref_to_pixel_colortable
,
2488 const primitive_funcs funcs_1
=
2492 colorref_to_pixel_colortable
,
2497 const primitive_funcs funcs_null
=
2501 colorref_to_pixel_null
,
2503 create_rop_masks_null