2 * DIB driver primitives.
4 * Copyright 2011 Huw Davies
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "gdi_private.h"
26 #include "wine/debug.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(dib
);
30 static inline DWORD
*get_pixel_ptr_32(const dib_info
*dib
, int x
, int y
)
32 return (DWORD
*)((BYTE
*)dib
->bits
.ptr
+ y
* dib
->stride
+ x
* 4);
35 static inline DWORD
*get_pixel_ptr_24_dword(const dib_info
*dib
, int x
, int y
)
37 return (DWORD
*)((BYTE
*)dib
->bits
.ptr
+ y
* dib
->stride
) + x
* 3 / 4;
40 static inline BYTE
*get_pixel_ptr_24(const dib_info
*dib
, int x
, int y
)
42 return (BYTE
*)dib
->bits
.ptr
+ y
* dib
->stride
+ x
* 3;
45 static inline WORD
*get_pixel_ptr_16(const dib_info
*dib
, int x
, int y
)
47 return (WORD
*)((BYTE
*)dib
->bits
.ptr
+ y
* dib
->stride
+ x
* 2);
50 static inline BYTE
*get_pixel_ptr_8(const dib_info
*dib
, int x
, int y
)
52 return (BYTE
*)dib
->bits
.ptr
+ y
* dib
->stride
+ x
;
55 static inline BYTE
*get_pixel_ptr_4(const dib_info
*dib
, int x
, int y
)
57 return (BYTE
*)dib
->bits
.ptr
+ y
* dib
->stride
+ x
/ 2;
60 static inline BYTE
*get_pixel_ptr_1(const dib_info
*dib
, int x
, int y
)
62 return (BYTE
*)dib
->bits
.ptr
+ y
* dib
->stride
+ x
/ 8;
65 static const BYTE pixel_masks_1
[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
67 static inline void do_rop_32(DWORD
*ptr
, DWORD
and, DWORD
xor)
69 *ptr
= (*ptr
& and) ^ xor;
72 static inline void do_rop_16(WORD
*ptr
, WORD
and, WORD
xor)
74 *ptr
= (*ptr
& and) ^ xor;
77 static inline void do_rop_8(BYTE
*ptr
, BYTE
and, BYTE
xor)
79 *ptr
= (*ptr
& and) ^ xor;
82 static inline void do_rop_mask_8(BYTE
*ptr
, BYTE
and, BYTE
xor, BYTE mask
)
84 *ptr
= (*ptr
& (and | ~mask
)) ^ (xor & mask
);
87 static inline void do_rop_codes_32(DWORD
*dst
, DWORD src
, struct rop_codes
*codes
)
89 do_rop_32( dst
, (src
& codes
->a1
) ^ codes
->a2
, (src
& codes
->x1
) ^ codes
->x2
);
92 static inline void do_rop_codes_16(WORD
*dst
, WORD src
, struct rop_codes
*codes
)
94 do_rop_16( dst
, (src
& codes
->a1
) ^ codes
->a2
, (src
& codes
->x1
) ^ codes
->x2
);
97 static inline void do_rop_codes_8(BYTE
*dst
, BYTE src
, struct rop_codes
*codes
)
99 do_rop_8( dst
, (src
& codes
->a1
) ^ codes
->a2
, (src
& codes
->x1
) ^ codes
->x2
);
102 static inline void do_rop_codes_mask_8(BYTE
*dst
, BYTE src
, struct rop_codes
*codes
, BYTE mask
)
104 do_rop_mask_8( dst
, (src
& codes
->a1
) ^ codes
->a2
, (src
& codes
->x1
) ^ codes
->x2
, mask
);
107 static inline void do_rop_codes_line_32(DWORD
*dst
, const DWORD
*src
, struct rop_codes
*codes
, int len
)
109 for (; len
> 0; len
--, src
++, dst
++) do_rop_codes_32( dst
, *src
, codes
);
112 static inline void do_rop_codes_line_rev_32(DWORD
*dst
, const DWORD
*src
, struct rop_codes
*codes
, int len
)
114 for (src
+= len
- 1, dst
+= len
- 1; len
> 0; len
--, src
--, dst
--)
115 do_rop_codes_32( dst
, *src
, codes
);
118 static inline void do_rop_codes_line_16(WORD
*dst
, const WORD
*src
, struct rop_codes
*codes
, int len
)
120 for (; len
> 0; len
--, src
++, dst
++) do_rop_codes_16( dst
, *src
, codes
);
123 static inline void do_rop_codes_line_rev_16(WORD
*dst
, const WORD
*src
, struct rop_codes
*codes
, int len
)
125 for (src
+= len
- 1, dst
+= len
- 1; len
> 0; len
--, src
--, dst
--)
126 do_rop_codes_16( dst
, *src
, codes
);
129 static inline void do_rop_codes_line_8(BYTE
*dst
, const BYTE
*src
, struct rop_codes
*codes
, int len
)
131 for (; len
> 0; len
--, src
++, dst
++) do_rop_codes_8( dst
, *src
, codes
);
134 static inline void do_rop_codes_line_rev_8(BYTE
*dst
, const BYTE
*src
, struct rop_codes
*codes
, int len
)
136 for (src
+= len
- 1, dst
+= len
- 1; len
> 0; len
--, src
--, dst
--)
137 do_rop_codes_8( dst
, *src
, codes
);
140 static inline void do_rop_codes_line_4(BYTE
*dst
, int dst_x
, const BYTE
*src
, int src_x
,
141 struct rop_codes
*codes
, int len
)
145 for (src
+= src_x
/ 2, dst
+= dst_x
/ 2; len
> 0; len
--, dst_x
++, src_x
++)
149 if (src_x
& 1) src_val
= *src
++;
150 else src_val
= *src
>> 4;
151 do_rop_codes_mask_8( dst
++, src_val
, codes
, 0x0f );
155 if (src_x
& 1) src_val
= *src
++ << 4;
157 do_rop_codes_mask_8( dst
, src_val
, codes
, 0xf0 );
162 static inline void do_rop_codes_line_rev_4(BYTE
*dst
, int dst_x
, const BYTE
*src
, int src_x
,
163 struct rop_codes
*codes
, int len
)
169 for (src
+= src_x
/ 2, dst
+= dst_x
/ 2; len
> 0; len
--, dst_x
--, src_x
--)
173 if (src_x
& 1) src_val
= *src
;
174 else src_val
= *src
-- >> 4;
175 do_rop_codes_mask_8( dst
, src_val
, codes
, 0x0f );
179 if (src_x
& 1) src_val
= *src
<< 4;
180 else src_val
= *src
--;
181 do_rop_codes_mask_8( dst
--, src_val
, codes
, 0xf0 );
186 static inline void do_rop_codes_line_1(BYTE
*dst
, int dst_x
, const BYTE
*src
, int src_x
,
187 struct rop_codes
*codes
, int len
)
191 for (src
+= src_x
/ 8, dst
+= dst_x
/ 8; len
> 0; len
--, dst_x
++, src_x
++)
193 src_val
= *src
& pixel_masks_1
[src_x
& 7] ? 0xff : 0;
194 do_rop_codes_mask_8( dst
, src_val
, codes
, pixel_masks_1
[dst_x
& 7] );
195 if ((src_x
& 7) == 7) src
++;
196 if ((dst_x
& 7) == 7) dst
++;
200 static inline void do_rop_codes_line_rev_1(BYTE
*dst
, int dst_x
, const BYTE
*src
, int src_x
,
201 struct rop_codes
*codes
, int len
)
207 for (src
+= src_x
/ 8, dst
+= dst_x
/ 8; len
> 0; len
--, dst_x
--, src_x
--)
209 src_val
= *src
& pixel_masks_1
[src_x
& 7] ? 0xff : 0;
210 do_rop_codes_mask_8( dst
, src_val
, codes
, pixel_masks_1
[dst_x
& 7] );
211 if ((src_x
& 7) == 0) src
--;
212 if ((dst_x
& 7) == 0) dst
--;
216 static void solid_rects_32(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
221 for(i
= 0; i
< num
; i
++, rc
++)
223 start
= get_pixel_ptr_32(dib
, rc
->left
, rc
->top
);
224 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
225 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
226 do_rop_32(ptr
++, and, xor);
230 static void solid_rects_24(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
233 BYTE
*byte_ptr
, *byte_start
;
235 DWORD and_masks
[3], xor_masks
[3];
237 and_masks
[0] = ( and & 0x00ffffff) | ((and << 24) & 0xff000000);
238 and_masks
[1] = ((and >> 8) & 0x0000ffff) | ((and << 16) & 0xffff0000);
239 and_masks
[2] = ((and >> 16) & 0x000000ff) | ((and << 8) & 0xffffff00);
240 xor_masks
[0] = ( xor & 0x00ffffff) | ((xor << 24) & 0xff000000);
241 xor_masks
[1] = ((xor >> 8) & 0x0000ffff) | ((xor << 16) & 0xffff0000);
242 xor_masks
[2] = ((xor >> 16) & 0x000000ff) | ((xor << 8) & 0xffffff00);
244 for(i
= 0; i
< num
; i
++, rc
++)
246 if(rc
->left
>= rc
->right
) continue;
248 if((rc
->left
& ~3) == (rc
->right
& ~3)) /* Special case for lines that start and end in the same DWORD triplet */
250 byte_start
= get_pixel_ptr_24(dib
, rc
->left
, rc
->top
);
251 for(y
= rc
->top
; y
< rc
->bottom
; y
++, byte_start
+= dib
->stride
)
253 for(x
= rc
->left
, byte_ptr
= byte_start
; x
< rc
->right
; x
++)
255 do_rop_8(byte_ptr
++, and_masks
[0] & 0xff, xor_masks
[0] & 0xff);
256 do_rop_8(byte_ptr
++, and_masks
[1] & 0xff, xor_masks
[1] & 0xff);
257 do_rop_8(byte_ptr
++, and_masks
[2] & 0xff, xor_masks
[2] & 0xff);
263 start
= get_pixel_ptr_24_dword(dib
, rc
->left
, rc
->top
);
264 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
271 do_rop_32(ptr
++, and_masks
[0] | 0x00ffffff, xor_masks
[0] & 0xff000000);
272 do_rop_32(ptr
++, and_masks
[1], xor_masks
[1]);
273 do_rop_32(ptr
++, and_masks
[2], xor_masks
[2]);
276 do_rop_32(ptr
++, and_masks
[1] | 0x0000ffff, xor_masks
[1] & 0xffff0000);
277 do_rop_32(ptr
++, and_masks
[2], xor_masks
[2]);
280 do_rop_32(ptr
++, and_masks
[2] | 0x000000ff, xor_masks
[2] & 0xffffff00);
284 for(x
= (rc
->left
+ 3) & ~3; x
< (rc
->right
& ~3); x
+= 4)
286 do_rop_32(ptr
++, and_masks
[0], xor_masks
[0]);
287 do_rop_32(ptr
++, and_masks
[1], xor_masks
[1]);
288 do_rop_32(ptr
++, and_masks
[2], xor_masks
[2]);
291 switch(rc
->right
& 3)
294 do_rop_32(ptr
, and_masks
[0] | 0xff000000, xor_masks
[0] & 0x00ffffff);
297 do_rop_32(ptr
++, and_masks
[0], xor_masks
[0]);
298 do_rop_32(ptr
, and_masks
[1] | 0xffff0000, xor_masks
[1] & 0x0000ffff);
301 do_rop_32(ptr
++, and_masks
[0], xor_masks
[0]);
302 do_rop_32(ptr
++, and_masks
[1], xor_masks
[1]);
303 do_rop_32(ptr
, and_masks
[2] | 0xffffff00, xor_masks
[2] & 0x000000ff);
311 static void solid_rects_16(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
316 for(i
= 0; i
< num
; i
++, rc
++)
318 start
= get_pixel_ptr_16(dib
, rc
->left
, rc
->top
);
319 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 2)
320 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
321 do_rop_16(ptr
++, and, xor);
325 static void solid_rects_8(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
330 for(i
= 0; i
< num
; i
++, rc
++)
332 start
= get_pixel_ptr_8(dib
, rc
->left
, rc
->top
);
333 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
334 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
335 do_rop_8(ptr
++, and, xor);
339 static void solid_rects_4(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
343 BYTE byte_and
= (and & 0xf) | ((and << 4) & 0xf0);
344 BYTE byte_xor
= (xor & 0xf) | ((xor << 4) & 0xf0);
346 for(i
= 0; i
< num
; i
++, rc
++)
348 if(rc
->left
>= rc
->right
) continue;
349 start
= get_pixel_ptr_4(dib
, rc
->left
, rc
->top
);
350 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
353 if(rc
->left
& 1) /* upper nibble untouched */
354 do_rop_8(ptr
++, byte_and
| 0xf0, byte_xor
& 0x0f);
356 for(x
= (rc
->left
+ 1) & ~1; x
< (rc
->right
& ~1); x
+= 2)
357 do_rop_8(ptr
++, byte_and
, byte_xor
);
359 if(rc
->right
& 1) /* lower nibble untouched */
360 do_rop_8(ptr
, byte_and
| 0x0f, byte_xor
& 0xf0);
365 static void solid_rects_1(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
369 BYTE byte_and
= (and & 1) ? 0xff : 0;
370 BYTE byte_xor
= (xor & 1) ? 0xff : 0;
371 BYTE start_and
, start_xor
, end_and
, end_xor
, mask
;
372 static const BYTE masks
[8] = {0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01};
374 for(i
= 0; i
< num
; i
++, rc
++)
376 if(rc
->left
>= rc
->right
) continue;
378 start
= get_pixel_ptr_1(dib
, rc
->left
, rc
->top
);
380 if((rc
->left
& ~7) == (rc
->right
& ~7)) /* Special case for lines that start and end in the same byte */
382 mask
= masks
[rc
->left
& 7] & ~masks
[rc
->right
& 7];
384 start_and
= byte_and
| ~mask
;
385 start_xor
= byte_xor
& mask
;
386 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
388 do_rop_8(start
, start_and
, start_xor
);
393 mask
= masks
[rc
->left
& 7];
394 start_and
= byte_and
| ~mask
;
395 start_xor
= byte_xor
& mask
;
397 mask
= masks
[rc
->right
& 7];
398 /* This is inverted wrt to start mask, so end_and/xor assignments reflect this */
399 end_and
= byte_and
| mask
;
400 end_xor
= byte_xor
& ~mask
;
402 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
407 do_rop_8(ptr
++, start_and
, start_xor
);
409 for(x
= (rc
->left
+ 7) & ~7; x
< (rc
->right
& ~7); x
+= 8)
410 do_rop_8(ptr
++, byte_and
, byte_xor
);
413 do_rop_8(ptr
, end_and
, end_xor
);
419 static void solid_rects_null(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
424 static inline INT
calc_offset(INT edge
, INT size
, INT origin
)
428 if(edge
- origin
>= 0)
429 offset
= (edge
- origin
) % size
;
432 offset
= (origin
- edge
) % size
;
433 if(offset
) offset
= size
- offset
;
438 static inline POINT
calc_brush_offset(const RECT
*rc
, const dib_info
*brush
, const POINT
*origin
)
442 offset
.x
= calc_offset(rc
->left
, brush
->width
, origin
->x
);
443 offset
.y
= calc_offset(rc
->top
, brush
->height
, origin
->y
);
448 static void pattern_rects_32(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
449 const dib_info
*brush
, void *and_bits
, void *xor_bits
)
451 DWORD
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
455 for(i
= 0; i
< num
; i
++, rc
++)
457 offset
= calc_brush_offset(rc
, brush
, origin
);
459 start
= get_pixel_ptr_32(dib
, rc
->left
, rc
->top
);
460 start_and
= (DWORD
*)and_bits
+ offset
.y
* brush
->stride
/ 4;
461 start_xor
= (DWORD
*)xor_bits
+ offset
.y
* brush
->stride
/ 4;
463 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
465 and_ptr
= start_and
+ offset
.x
;
466 xor_ptr
= start_xor
+ offset
.x
;
468 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
470 do_rop_32(ptr
++, *and_ptr
++, *xor_ptr
++);
471 if(and_ptr
== start_and
+ brush
->width
)
479 if(offset
.y
== brush
->height
)
481 start_and
= and_bits
;
482 start_xor
= xor_bits
;
487 start_and
+= brush
->stride
/ 4;
488 start_xor
+= brush
->stride
/ 4;
494 static void pattern_rects_24(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
495 const dib_info
*brush
, void *and_bits
, void *xor_bits
)
497 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
501 for(i
= 0; i
< num
; i
++, rc
++)
503 offset
= calc_brush_offset(rc
, brush
, origin
);
505 start
= get_pixel_ptr_24(dib
, rc
->left
, rc
->top
);
506 start_and
= (BYTE
*)and_bits
+ offset
.y
* brush
->stride
;
507 start_xor
= (BYTE
*)xor_bits
+ offset
.y
* brush
->stride
;
509 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
511 and_ptr
= start_and
+ offset
.x
* 3;
512 xor_ptr
= start_xor
+ offset
.x
* 3;
514 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
516 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
517 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
518 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
519 if(and_ptr
== start_and
+ brush
->width
* 3)
527 if(offset
.y
== brush
->height
)
529 start_and
= and_bits
;
530 start_xor
= xor_bits
;
535 start_and
+= brush
->stride
;
536 start_xor
+= brush
->stride
;
542 static void pattern_rects_16(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
543 const dib_info
*brush
, void *and_bits
, void *xor_bits
)
545 WORD
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
549 for(i
= 0; i
< num
; i
++, rc
++)
551 offset
= calc_brush_offset(rc
, brush
, origin
);
553 start
= get_pixel_ptr_16(dib
, rc
->left
, rc
->top
);
554 start_and
= (WORD
*)and_bits
+ offset
.y
* brush
->stride
/ 2;
555 start_xor
= (WORD
*)xor_bits
+ offset
.y
* brush
->stride
/ 2;
557 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 2)
559 and_ptr
= start_and
+ offset
.x
;
560 xor_ptr
= start_xor
+ offset
.x
;
562 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
564 do_rop_16(ptr
++, *and_ptr
++, *xor_ptr
++);
565 if(and_ptr
== start_and
+ brush
->width
)
573 if(offset
.y
== brush
->height
)
575 start_and
= and_bits
;
576 start_xor
= xor_bits
;
581 start_and
+= brush
->stride
/ 2;
582 start_xor
+= brush
->stride
/ 2;
588 static void pattern_rects_8(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
589 const dib_info
*brush
, void *and_bits
, void *xor_bits
)
591 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
595 for(i
= 0; i
< num
; i
++, rc
++)
597 offset
= calc_brush_offset(rc
, brush
, origin
);
599 start
= get_pixel_ptr_8(dib
, rc
->left
, rc
->top
);
600 start_and
= (BYTE
*)and_bits
+ offset
.y
* brush
->stride
;
601 start_xor
= (BYTE
*)xor_bits
+ offset
.y
* brush
->stride
;
603 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
605 and_ptr
= start_and
+ offset
.x
;
606 xor_ptr
= start_xor
+ offset
.x
;
608 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
610 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
611 if(and_ptr
== start_and
+ brush
->width
)
619 if(offset
.y
== brush
->height
)
621 start_and
= and_bits
;
622 start_xor
= xor_bits
;
627 start_and
+= brush
->stride
;
628 start_xor
+= brush
->stride
;
634 static void pattern_rects_4(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
635 const dib_info
*brush
, void *and_bits
, void *xor_bits
)
637 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
641 for(i
= 0; i
< num
; i
++, rc
++)
643 offset
= calc_brush_offset(rc
, brush
, origin
);
645 start
= get_pixel_ptr_4(dib
, rc
->left
, rc
->top
);
646 start_and
= (BYTE
*)and_bits
+ offset
.y
* brush
->stride
;
647 start_xor
= (BYTE
*)xor_bits
+ offset
.y
* brush
->stride
;
649 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
651 INT brush_x
= offset
.x
;
652 BYTE byte_and
, byte_xor
;
654 and_ptr
= start_and
+ brush_x
/ 2;
655 xor_ptr
= start_xor
+ brush_x
/ 2;
657 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
659 /* FIXME: Two pixels at a time */
660 if(x
& 1) /* lower dst nibble */
662 if(brush_x
& 1) /* lower pat nibble */
664 byte_and
= *and_ptr
++ | 0xf0;
665 byte_xor
= *xor_ptr
++ & 0x0f;
667 else /* upper pat nibble */
669 byte_and
= (*and_ptr
>> 4) | 0xf0;
670 byte_xor
= (*xor_ptr
>> 4) & 0x0f;
673 else /* upper dst nibble */
675 if(brush_x
& 1) /* lower pat nibble */
677 byte_and
= (*and_ptr
++ << 4) | 0x0f;
678 byte_xor
= (*xor_ptr
++ << 4) & 0xf0;
680 else /* upper pat nibble */
682 byte_and
= *and_ptr
| 0x0f;
683 byte_xor
= *xor_ptr
& 0xf0;
686 do_rop_8(ptr
, byte_and
, byte_xor
);
690 if(++brush_x
== brush
->width
)
699 if(offset
.y
== brush
->height
)
701 start_and
= and_bits
;
702 start_xor
= xor_bits
;
707 start_and
+= brush
->stride
;
708 start_xor
+= brush
->stride
;
714 static void pattern_rects_1(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
715 const dib_info
*brush
, void *and_bits
, void *xor_bits
)
717 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
721 for(i
= 0; i
< num
; i
++, rc
++)
723 offset
= calc_brush_offset(rc
, brush
, origin
);
725 start
= get_pixel_ptr_1(dib
, rc
->left
, rc
->top
);
726 start_and
= (BYTE
*)and_bits
+ offset
.y
* brush
->stride
;
727 start_xor
= (BYTE
*)xor_bits
+ offset
.y
* brush
->stride
;
729 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
731 INT brush_x
= offset
.x
;
732 BYTE byte_and
, byte_xor
;
734 and_ptr
= start_and
+ brush_x
/ 8;
735 xor_ptr
= start_xor
+ brush_x
/ 8;
737 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
739 byte_and
= (*and_ptr
& pixel_masks_1
[brush_x
% 8]) ? 0xff : 0;
740 byte_and
|= ~pixel_masks_1
[x
% 8];
741 byte_xor
= (*xor_ptr
& pixel_masks_1
[brush_x
% 8]) ? 0xff : 0;
742 byte_xor
&= pixel_masks_1
[x
% 8];
744 do_rop_8(ptr
, byte_and
, byte_xor
);
746 if((x
& 7) == 7) ptr
++;
748 if((brush_x
& 7) == 7)
754 if(++brush_x
== brush
->width
)
763 if(offset
.y
== brush
->height
)
765 start_and
= and_bits
;
766 start_xor
= xor_bits
;
771 start_and
+= brush
->stride
;
772 start_xor
+= brush
->stride
;
778 static void pattern_rects_null(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
779 const dib_info
*brush
, void *and_bits
, void *xor_bits
)
784 static void copy_rect_32(const dib_info
*dst
, const RECT
*rc
,
785 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
787 DWORD
*dst_start
, *src_start
;
788 struct rop_codes codes
;
789 int y
, dst_stride
, src_stride
;
791 if (overlap
& OVERLAP_BELOW
)
793 dst_start
= get_pixel_ptr_32(dst
, rc
->left
, rc
->bottom
- 1);
794 src_start
= get_pixel_ptr_32(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
795 dst_stride
= -dst
->stride
/ 4;
796 src_stride
= -src
->stride
/ 4;
800 dst_start
= get_pixel_ptr_32(dst
, rc
->left
, rc
->top
);
801 src_start
= get_pixel_ptr_32(src
, origin
->x
, origin
->y
);
802 dst_stride
= dst
->stride
/ 4;
803 src_stride
= src
->stride
/ 4;
806 if (rop2
== R2_COPYPEN
)
808 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
809 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) * 4 );
813 get_rop_codes( rop2
, &codes
);
814 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
816 if (overlap
& OVERLAP_RIGHT
)
817 do_rop_codes_line_rev_32( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
819 do_rop_codes_line_32( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
823 static void copy_rect_24(const dib_info
*dst
, const RECT
*rc
,
824 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
826 BYTE
*dst_start
, *src_start
;
827 int y
, dst_stride
, src_stride
;
828 struct rop_codes codes
;
830 if (overlap
& OVERLAP_BELOW
)
832 dst_start
= get_pixel_ptr_24(dst
, rc
->left
, rc
->bottom
- 1);
833 src_start
= get_pixel_ptr_24(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
834 dst_stride
= -dst
->stride
;
835 src_stride
= -src
->stride
;
839 dst_start
= get_pixel_ptr_24(dst
, rc
->left
, rc
->top
);
840 src_start
= get_pixel_ptr_24(src
, origin
->x
, origin
->y
);
841 dst_stride
= dst
->stride
;
842 src_stride
= src
->stride
;
845 if (rop2
== R2_COPYPEN
)
847 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
848 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) * 3 );
852 get_rop_codes( rop2
, &codes
);
853 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
855 if (overlap
& OVERLAP_RIGHT
)
856 do_rop_codes_line_rev_8( dst_start
, src_start
, &codes
, (rc
->right
- rc
->left
) * 3 );
858 do_rop_codes_line_8( dst_start
, src_start
, &codes
, (rc
->right
- rc
->left
) * 3 );
862 static void copy_rect_16(const dib_info
*dst
, const RECT
*rc
,
863 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
865 WORD
*dst_start
, *src_start
;
866 int y
, dst_stride
, src_stride
;
867 struct rop_codes codes
;
869 if (overlap
& OVERLAP_BELOW
)
871 dst_start
= get_pixel_ptr_16(dst
, rc
->left
, rc
->bottom
- 1);
872 src_start
= get_pixel_ptr_16(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
873 dst_stride
= -dst
->stride
/ 2;
874 src_stride
= -src
->stride
/ 2;
878 dst_start
= get_pixel_ptr_16(dst
, rc
->left
, rc
->top
);
879 src_start
= get_pixel_ptr_16(src
, origin
->x
, origin
->y
);
880 dst_stride
= dst
->stride
/ 2;
881 src_stride
= src
->stride
/ 2;
884 if (rop2
== R2_COPYPEN
)
886 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
887 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) * 2 );
891 get_rop_codes( rop2
, &codes
);
892 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
894 if (overlap
& OVERLAP_RIGHT
)
895 do_rop_codes_line_rev_16( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
897 do_rop_codes_line_16( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
901 static void copy_rect_8(const dib_info
*dst
, const RECT
*rc
,
902 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
904 BYTE
*dst_start
, *src_start
;
905 int y
, dst_stride
, src_stride
;
906 struct rop_codes codes
;
908 if (overlap
& OVERLAP_BELOW
)
910 dst_start
= get_pixel_ptr_8(dst
, rc
->left
, rc
->bottom
- 1);
911 src_start
= get_pixel_ptr_8(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
912 dst_stride
= -dst
->stride
;
913 src_stride
= -src
->stride
;
917 dst_start
= get_pixel_ptr_8(dst
, rc
->left
, rc
->top
);
918 src_start
= get_pixel_ptr_8(src
, origin
->x
, origin
->y
);
919 dst_stride
= dst
->stride
;
920 src_stride
= src
->stride
;
923 if (rop2
== R2_COPYPEN
)
925 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
926 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) );
930 get_rop_codes( rop2
, &codes
);
931 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
933 if (overlap
& OVERLAP_RIGHT
)
934 do_rop_codes_line_rev_8( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
936 do_rop_codes_line_8( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
940 static void copy_rect_4(const dib_info
*dst
, const RECT
*rc
,
941 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
943 BYTE
*dst_start
, *src_start
;
944 int y
, dst_stride
, src_stride
;
945 struct rop_codes codes
;
947 if (overlap
& OVERLAP_BELOW
)
949 dst_start
= get_pixel_ptr_4(dst
, 0, rc
->bottom
- 1);
950 src_start
= get_pixel_ptr_4(src
, 0, origin
->y
+ rc
->bottom
- rc
->top
- 1);
951 dst_stride
= -dst
->stride
;
952 src_stride
= -src
->stride
;
956 dst_start
= get_pixel_ptr_4(dst
, 0, rc
->top
);
957 src_start
= get_pixel_ptr_4(src
, 0, origin
->y
);
958 dst_stride
= dst
->stride
;
959 src_stride
= src
->stride
;
962 if (rop2
== R2_COPYPEN
&& (rc
->left
& 1) == 0 && (origin
->x
& 1) == 0 && (rc
->right
& 1) == 0)
964 dst_start
+= rc
->left
/ 2;
965 src_start
+= origin
->x
/ 2;
966 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
967 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) / 2 );
971 get_rop_codes( rop2
, &codes
);
972 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
974 if (overlap
& OVERLAP_RIGHT
)
975 do_rop_codes_line_rev_4( dst_start
, rc
->left
, src_start
, origin
->x
, &codes
, rc
->right
- rc
->left
);
977 do_rop_codes_line_4( dst_start
, rc
->left
, src_start
, origin
->x
, &codes
, rc
->right
- rc
->left
);
981 static void copy_rect_1(const dib_info
*dst
, const RECT
*rc
,
982 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
984 BYTE
*dst_start
, *src_start
;
985 int y
, dst_stride
, src_stride
;
986 struct rop_codes codes
;
988 if (overlap
& OVERLAP_BELOW
)
990 dst_start
= get_pixel_ptr_1(dst
, 0, rc
->bottom
- 1);
991 src_start
= get_pixel_ptr_1(src
, 0, origin
->y
+ rc
->bottom
- rc
->top
- 1);
992 dst_stride
= -dst
->stride
;
993 src_stride
= -src
->stride
;
997 dst_start
= get_pixel_ptr_1(dst
, 0, rc
->top
);
998 src_start
= get_pixel_ptr_1(src
, 0, origin
->y
);
999 dst_stride
= dst
->stride
;
1000 src_stride
= src
->stride
;
1003 if (rop2
== R2_COPYPEN
&& (rc
->left
& 7) == 0 && (origin
->x
& 7) == 0 && (rc
->right
& 7) == 0)
1005 dst_start
+= rc
->left
/ 8;
1006 src_start
+= origin
->x
/ 8;
1007 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1008 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) / 8 );
1012 get_rop_codes( rop2
, &codes
);
1013 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1015 if (overlap
& OVERLAP_RIGHT
)
1016 do_rop_codes_line_rev_1( dst_start
, rc
->left
, src_start
, origin
->x
, &codes
, rc
->right
- rc
->left
);
1018 do_rop_codes_line_1( dst_start
, rc
->left
, src_start
, origin
->x
, &codes
, rc
->right
- rc
->left
);
1022 static void copy_rect_null(const dib_info
*dst
, const RECT
*rc
,
1023 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1028 static DWORD
get_pixel_32(const dib_info
*dib
, const POINT
*pt
)
1030 DWORD
*ptr
= get_pixel_ptr_32( dib
, pt
->x
, pt
->y
);
1034 static DWORD
get_pixel_24(const dib_info
*dib
, const POINT
*pt
)
1036 BYTE
*ptr
= get_pixel_ptr_24( dib
, pt
->x
, pt
->y
);
1037 return ptr
[0] | ((DWORD
)ptr
[1] << 8) | ((DWORD
)ptr
[2] << 16);
1040 static DWORD
get_pixel_16(const dib_info
*dib
, const POINT
*pt
)
1042 WORD
*ptr
= get_pixel_ptr_16( dib
, pt
->x
, pt
->y
);
1046 static DWORD
get_pixel_8(const dib_info
*dib
, const POINT
*pt
)
1048 BYTE
*ptr
= get_pixel_ptr_8( dib
, pt
->x
, pt
->y
);
1052 static DWORD
get_pixel_4(const dib_info
*dib
, const POINT
*pt
)
1054 BYTE
*ptr
= get_pixel_ptr_4( dib
, pt
->x
, pt
->y
);
1059 return (*ptr
>> 4) & 0x0f;
1062 static DWORD
get_pixel_1(const dib_info
*dib
, const POINT
*pt
)
1064 BYTE
*ptr
= get_pixel_ptr_1( dib
, pt
->x
, pt
->y
);
1065 return (*ptr
& pixel_masks_1
[pt
->x
& 0x7]) ? 1 : 0;
1068 static DWORD
get_pixel_null(const dib_info
*dib
, const POINT
*pt
)
1073 static DWORD
colorref_to_pixel_888(const dib_info
*dib
, COLORREF color
)
1075 return ( ((color
>> 16) & 0xff) | (color
& 0xff00) | ((color
<< 16) & 0xff0000) );
1078 static const DWORD field_masks
[33] =
1080 0x00, /* should never happen */
1081 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff,
1082 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1083 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1084 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1087 static inline DWORD
get_field(DWORD field
, int shift
, int len
)
1089 shift
= shift
- (8 - len
);
1094 field
&= field_masks
[len
];
1095 field
|= field
>> len
;
1099 static inline DWORD
put_field(DWORD field
, int shift
, int len
)
1101 shift
= shift
- (8 - len
);
1102 field
&= field_masks
[len
];
1110 static DWORD
colorref_to_pixel_masks(const dib_info
*dib
, COLORREF colour
)
1114 r
= GetRValue(colour
);
1115 g
= GetGValue(colour
);
1116 b
= GetBValue(colour
);
1118 return put_field(r
, dib
->red_shift
, dib
->red_len
) |
1119 put_field(g
, dib
->green_shift
, dib
->green_len
) |
1120 put_field(b
, dib
->blue_shift
, dib
->blue_len
);
1123 static DWORD
colorref_to_pixel_555(const dib_info
*dib
, COLORREF color
)
1125 return ( ((color
>> 19) & 0x1f) | ((color
>> 6) & 0x03e0) | ((color
<< 7) & 0x7c00) );
1128 static DWORD
rgb_to_pixel_colortable(const dib_info
*dib
, BYTE r
, BYTE g
, BYTE b
)
1130 int i
, best_index
= 0;
1131 DWORD diff
, best_diff
= 0xffffffff;
1133 /* special case for conversion to 1-bpp without a color table:
1134 * we get a 1-entry table containing the background color
1136 if (dib
->bit_count
== 1 && dib
->color_table_size
== 1)
1137 return (r
== dib
->color_table
[0].rgbRed
&&
1138 g
== dib
->color_table
[0].rgbGreen
&&
1139 b
== dib
->color_table
[0].rgbBlue
);
1141 for(i
= 0; i
< dib
->color_table_size
; i
++)
1143 RGBQUAD
*cur
= dib
->color_table
+ i
;
1144 diff
= (r
- cur
->rgbRed
) * (r
- cur
->rgbRed
)
1145 + (g
- cur
->rgbGreen
) * (g
- cur
->rgbGreen
)
1146 + (b
- cur
->rgbBlue
) * (b
- cur
->rgbBlue
);
1154 if(diff
< best_diff
)
1163 static DWORD
colorref_to_pixel_colortable(const dib_info
*dib
, COLORREF color
)
1165 return rgb_to_pixel_colortable( dib
, GetRValue(color
), GetGValue(color
), GetBValue(color
) );
1168 static DWORD
colorref_to_pixel_null(const dib_info
*dib
, COLORREF color
)
1173 static inline RGBQUAD
colortable_entry(const dib_info
*dib
, DWORD index
)
1175 static const RGBQUAD default_rgb
;
1176 if (index
< dib
->color_table_size
) return dib
->color_table
[index
];
1180 static COLORREF
pixel_to_colorref_888(const dib_info
*dib
, DWORD pixel
)
1182 return ( ((pixel
>> 16) & 0xff) | (pixel
& 0xff00) | ((pixel
<< 16) & 0xff0000) );
1185 static COLORREF
pixel_to_colorref_masks(const dib_info
*dib
, DWORD pixel
)
1187 return RGB( get_field( pixel
, dib
->red_shift
, dib
->red_len
),
1188 get_field( pixel
, dib
->green_shift
, dib
->green_len
),
1189 get_field( pixel
, dib
->blue_shift
, dib
->blue_len
) );
1192 static COLORREF
pixel_to_colorref_555(const dib_info
*dib
, DWORD pixel
)
1194 return RGB( ((pixel
>> 7) & 0xf8) | ((pixel
>> 12) & 0x07),
1195 ((pixel
>> 2) & 0xf8) | ((pixel
>> 7) & 0x07),
1196 ((pixel
<< 3) & 0xf8) | ((pixel
>> 2) & 0x07) );
1199 static COLORREF
pixel_to_colorref_colortable(const dib_info
*dib
, DWORD pixel
)
1201 RGBQUAD quad
= colortable_entry( dib
, pixel
);
1203 return RGB( quad
.rgbRed
, quad
.rgbGreen
, quad
.rgbBlue
);
1206 static COLORREF
pixel_to_colorref_null(const dib_info
*dib
, DWORD pixel
)
1211 static inline BOOL
bit_fields_match(const dib_info
*d1
, const dib_info
*d2
)
1213 assert( d1
->bit_count
> 8 && d1
->bit_count
== d2
->bit_count
);
1215 return d1
->red_mask
== d2
->red_mask
&&
1216 d1
->green_mask
== d2
->green_mask
&&
1217 d1
->blue_mask
== d2
->blue_mask
;
1220 static void convert_to_8888(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
1222 DWORD
*dst_start
= get_pixel_ptr_32(dst
, 0, 0), *dst_pixel
, src_val
;
1223 int x
, y
, pad_size
= (dst
->width
- (src_rect
->right
- src_rect
->left
)) * 4;
1225 switch(src
->bit_count
)
1229 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1230 if(src
->funcs
== &funcs_8888
)
1232 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
1233 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
1236 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1238 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 4);
1239 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
1240 dst_start
+= dst
->stride
/ 4;
1241 src_start
+= src
->stride
/ 4;
1245 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
1247 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1249 dst_pixel
= dst_start
;
1250 src_pixel
= src_start
;
1251 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1253 src_val
= *src_pixel
++;
1254 *dst_pixel
++ = (((src_val
>> src
->red_shift
) & 0xff) << 16) |
1255 (((src_val
>> src
->green_shift
) & 0xff) << 8) |
1256 ((src_val
>> src
->blue_shift
) & 0xff);
1258 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1259 dst_start
+= dst
->stride
/ 4;
1260 src_start
+= src
->stride
/ 4;
1265 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1267 dst_pixel
= dst_start
;
1268 src_pixel
= src_start
;
1269 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1271 src_val
= *src_pixel
++;
1272 *dst_pixel
++ = (get_field( src_val
, src
->red_shift
, src
->red_len
) << 16 |
1273 get_field( src_val
, src
->green_shift
, src
->green_len
) << 8 |
1274 get_field( src_val
, src
->blue_shift
, src
->blue_len
));
1276 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1277 dst_start
+= dst
->stride
/ 4;
1278 src_start
+= src
->stride
/ 4;
1286 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1288 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1290 dst_pixel
= dst_start
;
1291 src_pixel
= src_start
;
1292 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1295 rgb
.rgbBlue
= *src_pixel
++;
1296 rgb
.rgbGreen
= *src_pixel
++;
1297 rgb
.rgbRed
= *src_pixel
++;
1299 *dst_pixel
++ = ((rgb
.rgbRed
<< 16) & 0xff0000) | ((rgb
.rgbGreen
<< 8) & 0x00ff00) | (rgb
.rgbBlue
& 0x0000ff);
1301 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1302 dst_start
+= dst
->stride
/ 4;
1303 src_start
+= src
->stride
;
1310 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1311 if(src
->funcs
== &funcs_555
)
1313 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1315 dst_pixel
= dst_start
;
1316 src_pixel
= src_start
;
1317 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1319 src_val
= *src_pixel
++;
1320 *dst_pixel
++ = ((src_val
<< 9) & 0xf80000) | ((src_val
<< 4) & 0x070000) |
1321 ((src_val
<< 6) & 0x00f800) | ((src_val
<< 1) & 0x000700) |
1322 ((src_val
<< 3) & 0x0000f8) | ((src_val
>> 2) & 0x000007);
1324 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1325 dst_start
+= dst
->stride
/ 4;
1326 src_start
+= src
->stride
/ 2;
1329 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
1331 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1333 dst_pixel
= dst_start
;
1334 src_pixel
= src_start
;
1335 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1337 src_val
= *src_pixel
++;
1338 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 19) & 0xf80000) |
1339 (((src_val
>> src
->red_shift
) << 14) & 0x070000) |
1340 (((src_val
>> src
->green_shift
) << 11) & 0x00f800) |
1341 (((src_val
>> src
->green_shift
) << 6) & 0x000700) |
1342 (((src_val
>> src
->blue_shift
) << 3) & 0x0000f8) |
1343 (((src_val
>> src
->blue_shift
) >> 2) & 0x000007);
1345 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1346 dst_start
+= dst
->stride
/ 4;
1347 src_start
+= src
->stride
/ 2;
1350 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
1352 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1354 dst_pixel
= dst_start
;
1355 src_pixel
= src_start
;
1356 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1358 src_val
= *src_pixel
++;
1359 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 19) & 0xf80000) |
1360 (((src_val
>> src
->red_shift
) << 14) & 0x070000) |
1361 (((src_val
>> src
->green_shift
) << 10) & 0x00fc00) |
1362 (((src_val
>> src
->green_shift
) << 4) & 0x000300) |
1363 (((src_val
>> src
->blue_shift
) << 3) & 0x0000f8) |
1364 (((src_val
>> src
->blue_shift
) >> 2) & 0x000007);
1366 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1367 dst_start
+= dst
->stride
/ 4;
1368 src_start
+= src
->stride
/ 2;
1373 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1375 dst_pixel
= dst_start
;
1376 src_pixel
= src_start
;
1377 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1379 src_val
= *src_pixel
++;
1380 *dst_pixel
++ = (get_field( src_val
, src
->red_shift
, src
->red_len
) << 16 |
1381 get_field( src_val
, src
->green_shift
, src
->green_len
) << 8 |
1382 get_field( src_val
, src
->blue_shift
, src
->blue_len
));
1384 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1385 dst_start
+= dst
->stride
/ 4;
1386 src_start
+= src
->stride
/ 2;
1394 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1395 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1397 dst_pixel
= dst_start
;
1398 src_pixel
= src_start
;
1399 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1401 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
1402 *dst_pixel
++ = rgb
.rgbRed
<< 16 | rgb
.rgbGreen
<< 8 | rgb
.rgbBlue
;
1404 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1405 dst_start
+= dst
->stride
/ 4;
1406 src_start
+= src
->stride
;
1413 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1414 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1416 dst_pixel
= dst_start
;
1417 src_pixel
= src_start
;
1418 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1422 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
1424 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
1425 *dst_pixel
++ = rgb
.rgbRed
<< 16 | rgb
.rgbGreen
<< 8 | rgb
.rgbBlue
;
1427 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1428 dst_start
+= dst
->stride
/ 4;
1429 src_start
+= src
->stride
;
1436 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1437 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1439 dst_pixel
= dst_start
;
1440 src_pixel
= src_start
;
1441 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1444 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
1445 if((x
% 8) == 7) src_pixel
++;
1446 rgb
= src
->color_table
[src_val
];
1447 *dst_pixel
++ = rgb
.rgbRed
<< 16 | rgb
.rgbGreen
<< 8 | rgb
.rgbBlue
;
1449 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1450 dst_start
+= dst
->stride
/ 4;
1451 src_start
+= src
->stride
;
1458 static void convert_to_32(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
1460 DWORD
*dst_start
= get_pixel_ptr_32(dst
, 0, 0), *dst_pixel
, src_val
;
1461 int x
, y
, pad_size
= (dst
->width
- (src_rect
->right
- src_rect
->left
)) * 4;
1463 switch(src
->bit_count
)
1467 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1469 if(src
->funcs
== &funcs_8888
)
1471 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1473 dst_pixel
= dst_start
;
1474 src_pixel
= src_start
;
1475 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1477 src_val
= *src_pixel
++;
1478 *dst_pixel
++ = put_field(src_val
>> 16, dst
->red_shift
, dst
->red_len
) |
1479 put_field(src_val
>> 8, dst
->green_shift
, dst
->green_len
) |
1480 put_field(src_val
, dst
->blue_shift
, dst
->blue_len
);
1482 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1483 dst_start
+= dst
->stride
/ 4;
1484 src_start
+= src
->stride
/ 4;
1487 else if(bit_fields_match(src
, dst
))
1489 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
1490 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
1493 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1495 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 4);
1496 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
1497 dst_start
+= dst
->stride
/ 4;
1498 src_start
+= src
->stride
/ 4;
1502 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8 &&
1503 dst
->red_len
== 8 && dst
->green_len
== 8 && dst
->blue_len
== 8)
1505 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1507 dst_pixel
= dst_start
;
1508 src_pixel
= src_start
;
1509 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1511 src_val
= *src_pixel
++;
1512 *dst_pixel
++ = (((src_val
>> src
->red_shift
) & 0xff) << dst
->red_shift
) |
1513 (((src_val
>> src
->green_shift
) & 0xff) << dst
->green_shift
) |
1514 (((src_val
>> src
->blue_shift
) & 0xff) << dst
->blue_shift
);
1516 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1517 dst_start
+= dst
->stride
/ 4;
1518 src_start
+= src
->stride
/ 4;
1523 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1525 dst_pixel
= dst_start
;
1526 src_pixel
= src_start
;
1527 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1529 src_val
= *src_pixel
++;
1530 *dst_pixel
++ = put_field(get_field(src_val
, src
->red_shift
, src
->red_len
), dst
->red_shift
, dst
->red_len
) |
1531 put_field(get_field(src_val
, src
->green_shift
, src
->green_len
), dst
->green_shift
, dst
->green_len
) |
1532 put_field(get_field(src_val
, src
->blue_shift
, src
->blue_len
), dst
->blue_shift
, dst
->blue_len
);
1534 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1535 dst_start
+= dst
->stride
/ 4;
1536 src_start
+= src
->stride
/ 4;
1544 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1546 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1548 dst_pixel
= dst_start
;
1549 src_pixel
= src_start
;
1550 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1553 rgb
.rgbBlue
= *src_pixel
++;
1554 rgb
.rgbGreen
= *src_pixel
++;
1555 rgb
.rgbRed
= *src_pixel
++;
1557 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
1558 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
1559 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
1561 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1562 dst_start
+= dst
->stride
/ 4;
1563 src_start
+= src
->stride
;
1570 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1571 if(src
->funcs
== &funcs_555
)
1573 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1575 dst_pixel
= dst_start
;
1576 src_pixel
= src_start
;
1577 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1579 src_val
= *src_pixel
++;
1580 *dst_pixel
++ = put_field(((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07), dst
->red_shift
, dst
->red_len
) |
1581 put_field(((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07), dst
->green_shift
, dst
->green_len
) |
1582 put_field(((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
1584 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1585 dst_start
+= dst
->stride
/ 4;
1586 src_start
+= src
->stride
/ 2;
1589 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
1591 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1593 dst_pixel
= dst_start
;
1594 src_pixel
= src_start
;
1595 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1597 src_val
= *src_pixel
++;
1598 *dst_pixel
++ = put_field( (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
1599 (((src_val
>> src
->red_shift
) >> 2) & 0x07), dst
->red_shift
, dst
->red_len
) |
1600 put_field( (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
1601 (((src_val
>> src
->green_shift
) >> 2) & 0x07), dst
->green_shift
, dst
->green_len
) |
1602 put_field( (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
1603 (((src_val
>> src
->blue_shift
) >> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
1605 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1606 dst_start
+= dst
->stride
/ 4;
1607 src_start
+= src
->stride
/ 2;
1610 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
1612 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1614 dst_pixel
= dst_start
;
1615 src_pixel
= src_start
;
1616 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1618 src_val
= *src_pixel
++;
1619 *dst_pixel
++ = put_field( (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
1620 (((src_val
>> src
->red_shift
) >> 2) & 0x07), dst
->red_shift
, dst
->red_len
) |
1621 put_field( (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
1622 (((src_val
>> src
->green_shift
) >> 4) & 0x03), dst
->green_shift
, dst
->green_len
) |
1623 put_field( (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
1624 (((src_val
>> src
->blue_shift
) >> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
1626 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1627 dst_start
+= dst
->stride
/ 4;
1628 src_start
+= src
->stride
/ 2;
1633 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1635 dst_pixel
= dst_start
;
1636 src_pixel
= src_start
;
1637 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1639 src_val
= *src_pixel
++;
1640 *dst_pixel
++ = put_field(get_field(src_val
, src
->red_shift
, src
->red_len
), dst
->red_shift
, dst
->red_len
) |
1641 put_field(get_field(src_val
, src
->green_shift
, src
->green_len
), dst
->green_shift
, dst
->green_len
) |
1642 put_field(get_field(src_val
, src
->blue_shift
, src
->blue_len
), dst
->blue_shift
, dst
->blue_len
);
1644 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1645 dst_start
+= dst
->stride
/ 4;
1646 src_start
+= src
->stride
/ 2;
1654 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1655 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1657 dst_pixel
= dst_start
;
1658 src_pixel
= src_start
;
1659 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1661 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
1662 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
1663 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
1664 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
1666 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1667 dst_start
+= dst
->stride
/ 4;
1668 src_start
+= src
->stride
;
1675 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1676 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1678 dst_pixel
= dst_start
;
1679 src_pixel
= src_start
;
1680 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1684 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
1686 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
1687 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
1688 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
1689 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
1691 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1692 dst_start
+= dst
->stride
/ 4;
1693 src_start
+= src
->stride
;
1700 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
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
++)
1708 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
1709 if((x
% 8) == 7) src_pixel
++;
1710 rgb
= src
->color_table
[src_val
];
1711 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
1712 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
1713 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
1715 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1716 dst_start
+= dst
->stride
/ 4;
1717 src_start
+= src
->stride
;
1724 static void convert_to_24(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
1726 BYTE
*dst_start
= get_pixel_ptr_24(dst
, 0, 0), *dst_pixel
;
1728 int x
, y
, pad_size
= ((dst
->width
* 3 + 3) & ~3) - (src_rect
->right
- src_rect
->left
) * 3;
1730 switch(src
->bit_count
)
1734 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1735 if(src
->funcs
== &funcs_8888
)
1737 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1739 dst_pixel
= dst_start
;
1740 src_pixel
= src_start
;
1741 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1743 src_val
= *src_pixel
++;
1744 *dst_pixel
++ = src_val
& 0xff;
1745 *dst_pixel
++ = (src_val
>> 8) & 0xff;
1746 *dst_pixel
++ = (src_val
>> 16) & 0xff;
1748 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1749 dst_start
+= dst
->stride
;
1750 src_start
+= src
->stride
/ 4;
1753 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
1755 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1757 dst_pixel
= dst_start
;
1758 src_pixel
= src_start
;
1759 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1761 src_val
= *src_pixel
++;
1762 *dst_pixel
++ = (src_val
>> src
->blue_shift
) & 0xff;
1763 *dst_pixel
++ = (src_val
>> src
->green_shift
) & 0xff;
1764 *dst_pixel
++ = (src_val
>> src
->red_shift
) & 0xff;
1766 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1767 dst_start
+= dst
->stride
;
1768 src_start
+= src
->stride
/ 4;
1773 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1775 dst_pixel
= dst_start
;
1776 src_pixel
= src_start
;
1777 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1779 src_val
= *src_pixel
++;
1780 *dst_pixel
++ = get_field( src_val
, src
->blue_shift
, src
->blue_len
);
1781 *dst_pixel
++ = get_field( src_val
, src
->green_shift
, src
->green_len
);
1782 *dst_pixel
++ = get_field( src_val
, src
->red_shift
, src
->red_len
);
1784 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1785 dst_start
+= dst
->stride
;
1786 src_start
+= src
->stride
/ 4;
1794 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
);
1796 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
1797 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
1800 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1802 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 3);
1803 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
) * 3, 0, pad_size
);
1804 dst_start
+= dst
->stride
;
1805 src_start
+= src
->stride
;
1813 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1814 if(src
->funcs
== &funcs_555
)
1816 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1818 dst_pixel
= dst_start
;
1819 src_pixel
= src_start
;
1820 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1822 src_val
= *src_pixel
++;
1823 *dst_pixel
++ = ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07);
1824 *dst_pixel
++ = ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07);
1825 *dst_pixel
++ = ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07);
1827 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1828 dst_start
+= dst
->stride
;
1829 src_start
+= src
->stride
/ 2;
1832 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
1834 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1836 dst_pixel
= dst_start
;
1837 src_pixel
= src_start
;
1838 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1840 src_val
= *src_pixel
++;
1841 *dst_pixel
++ = (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
1842 (((src_val
>> src
->blue_shift
) >> 2) & 0x07);
1843 *dst_pixel
++ = (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
1844 (((src_val
>> src
->green_shift
) >> 2) & 0x07);
1845 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
1846 (((src_val
>> src
->red_shift
) >> 2) & 0x07);
1848 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1849 dst_start
+= dst
->stride
;
1850 src_start
+= src
->stride
/ 2;
1853 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
1855 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1857 dst_pixel
= dst_start
;
1858 src_pixel
= src_start
;
1859 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1861 src_val
= *src_pixel
++;
1862 *dst_pixel
++ = (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
1863 (((src_val
>> src
->blue_shift
) >> 2) & 0x07);
1864 *dst_pixel
++ = (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
1865 (((src_val
>> src
->green_shift
) >> 4) & 0x03);
1866 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
1867 (((src_val
>> src
->red_shift
) >> 2) & 0x07);
1869 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1870 dst_start
+= dst
->stride
;
1871 src_start
+= src
->stride
/ 2;
1876 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1878 dst_pixel
= dst_start
;
1879 src_pixel
= src_start
;
1880 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1882 src_val
= *src_pixel
++;
1883 *dst_pixel
++ = get_field(src_val
, src
->blue_shift
, src
->blue_len
);
1884 *dst_pixel
++ = get_field(src_val
, src
->green_shift
, src
->green_len
);
1885 *dst_pixel
++ = get_field(src_val
, src
->red_shift
, src
->red_len
);
1887 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1888 dst_start
+= dst
->stride
;
1889 src_start
+= src
->stride
/ 2;
1897 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
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
++)
1904 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
1905 *dst_pixel
++ = rgb
.rgbBlue
;
1906 *dst_pixel
++ = rgb
.rgbGreen
;
1907 *dst_pixel
++ = rgb
.rgbRed
;
1909 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1910 dst_start
+= dst
->stride
;
1911 src_start
+= src
->stride
;
1918 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1919 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1921 dst_pixel
= dst_start
;
1922 src_pixel
= src_start
;
1923 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1927 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
1929 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
1930 *dst_pixel
++ = rgb
.rgbBlue
;
1931 *dst_pixel
++ = rgb
.rgbGreen
;
1932 *dst_pixel
++ = rgb
.rgbRed
;
1934 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1935 dst_start
+= dst
->stride
;
1936 src_start
+= src
->stride
;
1943 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1944 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1946 dst_pixel
= dst_start
;
1947 src_pixel
= src_start
;
1948 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1951 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
1952 if((x
% 8) == 7) src_pixel
++;
1953 rgb
= src
->color_table
[src_val
];
1954 *dst_pixel
++ = rgb
.rgbBlue
;
1955 *dst_pixel
++ = rgb
.rgbGreen
;
1956 *dst_pixel
++ = rgb
.rgbRed
;
1958 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1959 dst_start
+= dst
->stride
;
1960 src_start
+= src
->stride
;
1967 static void convert_to_555(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
1969 WORD
*dst_start
= get_pixel_ptr_16(dst
, 0, 0), *dst_pixel
;
1970 INT x
, y
, pad_size
= ((dst
->width
+ 1) & ~1) * 2 - (src_rect
->right
- src_rect
->left
) * 2;
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
; x
< src_rect
->right
; x
++)
1987 src_val
= *src_pixel
++;
1988 *dst_pixel
++ = ((src_val
>> 9) & 0x7c00) |
1989 ((src_val
>> 6) & 0x03e0) |
1990 ((src_val
>> 3) & 0x001f);
1992 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1993 dst_start
+= dst
->stride
/ 2;
1994 src_start
+= src
->stride
/ 4;
1997 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
1999 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2001 dst_pixel
= dst_start
;
2002 src_pixel
= src_start
;
2003 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2005 src_val
= *src_pixel
++;
2006 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 7) & 0x7c00) |
2007 (((src_val
>> src
->green_shift
) << 2) & 0x03e0) |
2008 (((src_val
>> src
->blue_shift
) >> 3) & 0x001f);
2010 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2011 dst_start
+= dst
->stride
/ 2;
2012 src_start
+= src
->stride
/ 4;
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
; x
< src_rect
->right
; x
++)
2023 src_val
= *src_pixel
++;
2024 *dst_pixel
++ = (((get_field(src_val
, src
->red_shift
, src
->red_len
) << 7) & 0x7c00) |
2025 ((get_field(src_val
, src
->green_shift
, src
->green_len
) << 2) & 0x03e0) |
2026 ( get_field(src_val
, src
->blue_shift
, src
->blue_len
) >> 3));
2028 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2029 dst_start
+= dst
->stride
/ 2;
2030 src_start
+= src
->stride
/ 4;
2038 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2040 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2042 dst_pixel
= dst_start
;
2043 src_pixel
= src_start
;
2044 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2047 rgb
.rgbBlue
= *src_pixel
++;
2048 rgb
.rgbGreen
= *src_pixel
++;
2049 rgb
.rgbRed
= *src_pixel
++;
2051 *dst_pixel
++ = ((rgb
.rgbRed
<< 7) & 0x7c00) |
2052 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
2053 ((rgb
.rgbBlue
>> 3) & 0x001f);
2055 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2056 dst_start
+= dst
->stride
/ 2;
2057 src_start
+= src
->stride
;
2064 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2065 if(src
->funcs
== &funcs_555
)
2067 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
2068 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2071 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2073 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 2);
2074 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
2075 dst_start
+= dst
->stride
/ 2;
2076 src_start
+= src
->stride
/ 2;
2080 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2082 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2084 dst_pixel
= dst_start
;
2085 src_pixel
= src_start
;
2086 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2088 src_val
= *src_pixel
++;
2089 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 10) & 0x7c00) |
2090 (((src_val
>> src
->green_shift
) << 5) & 0x03e0) |
2091 ( (src_val
>> src
->blue_shift
) & 0x001f);
2093 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2094 dst_start
+= dst
->stride
/ 2;
2095 src_start
+= src
->stride
/ 2;
2098 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2100 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2102 dst_pixel
= dst_start
;
2103 src_pixel
= src_start
;
2104 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2106 src_val
= *src_pixel
++;
2107 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 10) & 0x7c00) |
2108 (((src_val
>> src
->green_shift
) << 4) & 0x03e0) |
2109 ( (src_val
>> src
->blue_shift
) & 0x001f);
2111 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2112 dst_start
+= dst
->stride
/ 2;
2113 src_start
+= src
->stride
/ 2;
2118 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2120 dst_pixel
= dst_start
;
2121 src_pixel
= src_start
;
2122 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2124 src_val
= *src_pixel
++;
2125 *dst_pixel
++ = (((get_field(src_val
, src
->red_shift
, src
->red_len
) << 7) & 0x7c00) |
2126 ((get_field(src_val
, src
->green_shift
, src
->green_len
) << 2) & 0x03e0) |
2127 ( get_field(src_val
, src
->blue_shift
, src
->blue_len
) >> 3));
2129 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2130 dst_start
+= dst
->stride
/ 2;
2131 src_start
+= src
->stride
/ 2;
2139 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2140 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2142 dst_pixel
= dst_start
;
2143 src_pixel
= src_start
;
2144 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2146 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
2147 *dst_pixel
++ = ((rgb
.rgbRed
<< 7) & 0x7c00) |
2148 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
2149 ((rgb
.rgbBlue
>> 3) & 0x001f);
2151 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2152 dst_start
+= dst
->stride
/ 2;
2153 src_start
+= src
->stride
;
2160 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2161 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2163 dst_pixel
= dst_start
;
2164 src_pixel
= src_start
;
2165 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2169 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
2171 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
2172 *dst_pixel
++ = ((rgb
.rgbRed
<< 7) & 0x7c00) |
2173 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
2174 ((rgb
.rgbBlue
>> 3) & 0x001f);
2176 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2177 dst_start
+= dst
->stride
/ 2;
2178 src_start
+= src
->stride
;
2185 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2186 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2188 dst_pixel
= dst_start
;
2189 src_pixel
= src_start
;
2190 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2193 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
2194 if((x
% 8) == 7) src_pixel
++;
2195 rgb
= src
->color_table
[src_val
];
2196 *dst_pixel
++ = ((rgb
.rgbRed
<< 7) & 0x7c00) |
2197 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
2198 ((rgb
.rgbBlue
>> 3) & 0x001f);
2200 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2201 dst_start
+= dst
->stride
/ 2;
2202 src_start
+= src
->stride
;
2209 static void convert_to_16(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
2211 WORD
*dst_start
= get_pixel_ptr_16(dst
, 0, 0), *dst_pixel
;
2212 INT x
, y
, pad_size
= ((dst
->width
+ 1) & ~1) * 2 - (src_rect
->right
- src_rect
->left
) * 2;
2215 switch(src
->bit_count
)
2219 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2221 if(src
->funcs
== &funcs_8888
)
2223 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2225 dst_pixel
= dst_start
;
2226 src_pixel
= src_start
;
2227 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2229 src_val
= *src_pixel
++;
2230 *dst_pixel
++ = put_field(src_val
>> 16, dst
->red_shift
, dst
->red_len
) |
2231 put_field(src_val
>> 8, dst
->green_shift
, dst
->green_len
) |
2232 put_field(src_val
, dst
->blue_shift
, dst
->blue_len
);
2234 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2235 dst_start
+= dst
->stride
/ 2;
2236 src_start
+= src
->stride
/ 4;
2239 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
2241 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2243 dst_pixel
= dst_start
;
2244 src_pixel
= src_start
;
2245 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2247 src_val
= *src_pixel
++;
2248 *dst_pixel
++ = put_field(src_val
>> src
->red_shift
, dst
->red_shift
, dst
->red_len
) |
2249 put_field(src_val
>> src
->green_shift
, dst
->green_shift
, dst
->green_len
) |
2250 put_field(src_val
>> src
->blue_shift
, dst
->blue_shift
, dst
->blue_len
);
2252 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2253 dst_start
+= dst
->stride
/ 2;
2254 src_start
+= src
->stride
/ 4;
2259 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2261 dst_pixel
= dst_start
;
2262 src_pixel
= src_start
;
2263 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2265 src_val
= *src_pixel
++;
2266 *dst_pixel
++ = put_field(get_field(src_val
, src
->red_shift
, src
->red_len
), dst
->red_shift
, dst
->red_len
) |
2267 put_field(get_field(src_val
, src
->green_shift
, src
->green_len
), dst
->green_shift
, dst
->green_len
) |
2268 put_field(get_field(src_val
, src
->blue_shift
, src
->blue_len
), dst
->blue_shift
, dst
->blue_len
);
2270 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2271 dst_start
+= dst
->stride
/ 2;
2272 src_start
+= src
->stride
/ 4;
2280 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2282 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2284 dst_pixel
= dst_start
;
2285 src_pixel
= src_start
;
2286 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2289 rgb
.rgbBlue
= *src_pixel
++;
2290 rgb
.rgbGreen
= *src_pixel
++;
2291 rgb
.rgbRed
= *src_pixel
++;
2293 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
2294 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
2295 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
2297 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2298 dst_start
+= dst
->stride
/ 2;
2299 src_start
+= src
->stride
;
2306 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2307 if(src
->funcs
== &funcs_555
)
2309 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2311 dst_pixel
= dst_start
;
2312 src_pixel
= src_start
;
2313 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2315 src_val
= *src_pixel
++;
2316 *dst_pixel
++ = put_field(((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07), dst
->red_shift
, dst
->red_len
) |
2317 put_field(((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07), dst
->green_shift
, dst
->green_len
) |
2318 put_field(((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
2320 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2321 dst_start
+= dst
->stride
/ 2;
2322 src_start
+= src
->stride
/ 2;
2325 else if(bit_fields_match(src
, dst
))
2327 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
2328 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2331 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2333 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 2);
2334 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
2335 dst_start
+= dst
->stride
/ 2;
2336 src_start
+= src
->stride
/ 2;
2340 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2342 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2344 dst_pixel
= dst_start
;
2345 src_pixel
= src_start
;
2346 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2348 src_val
= *src_pixel
++;
2349 *dst_pixel
++ = put_field( (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2350 (((src_val
>> src
->red_shift
) >> 2) & 0x07), dst
->red_shift
, dst
->red_len
) |
2351 put_field( (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
2352 (((src_val
>> src
->green_shift
) >> 2) & 0x07), dst
->green_shift
, dst
->green_len
) |
2353 put_field( (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2354 (((src_val
>> src
->blue_shift
) >> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
2356 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2357 dst_start
+= dst
->stride
/ 2;
2358 src_start
+= src
->stride
/ 2;
2361 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2363 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2365 dst_pixel
= dst_start
;
2366 src_pixel
= src_start
;
2367 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2369 src_val
= *src_pixel
++;
2370 *dst_pixel
++ = put_field( (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2371 (((src_val
>> src
->red_shift
) >> 2) & 0x07), dst
->red_shift
, dst
->red_len
) |
2372 put_field( (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
2373 (((src_val
>> src
->green_shift
) >> 4) & 0x03), dst
->green_shift
, dst
->green_len
) |
2374 put_field( (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2375 (((src_val
>> src
->blue_shift
) >> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
2377 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2378 dst_start
+= dst
->stride
/ 2;
2379 src_start
+= src
->stride
/ 2;
2384 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2386 dst_pixel
= dst_start
;
2387 src_pixel
= src_start
;
2388 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2390 src_val
= *src_pixel
++;
2391 *dst_pixel
++ = put_field(get_field(src_val
, src
->red_shift
, src
->red_len
), dst
->red_shift
, dst
->red_len
) |
2392 put_field(get_field(src_val
, src
->green_shift
, src
->green_len
), dst
->green_shift
, dst
->green_len
) |
2393 put_field(get_field(src_val
, src
->blue_shift
, src
->blue_len
), dst
->blue_shift
, dst
->blue_len
);
2395 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2396 dst_start
+= dst
->stride
/ 2;
2397 src_start
+= src
->stride
/ 2;
2405 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2406 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2408 dst_pixel
= dst_start
;
2409 src_pixel
= src_start
;
2410 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2412 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
2413 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
2414 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
2415 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
2417 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2418 dst_start
+= dst
->stride
/ 2;
2419 src_start
+= src
->stride
;
2426 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2427 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2429 dst_pixel
= dst_start
;
2430 src_pixel
= src_start
;
2431 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2435 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
2437 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
2438 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
2439 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
2440 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
2442 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2443 dst_start
+= dst
->stride
/ 2;
2444 src_start
+= src
->stride
;
2451 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2452 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2454 dst_pixel
= dst_start
;
2455 src_pixel
= src_start
;
2456 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2459 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
2460 if((x
% 8) == 7) src_pixel
++;
2461 rgb
= src
->color_table
[src_val
];
2462 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
2463 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
2464 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
2466 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2467 dst_start
+= dst
->stride
/ 2;
2468 src_start
+= src
->stride
;
2475 static inline BOOL
color_tables_match(const dib_info
*d1
, const dib_info
*d2
)
2477 assert(d1
->color_table_size
&& d2
->color_table_size
);
2479 if(d1
->color_table_size
!= d2
->color_table_size
) return FALSE
;
2480 return !memcmp(d1
->color_table
, d2
->color_table
, d1
->color_table_size
* sizeof(d1
->color_table
[0]));
2483 static inline DWORD
rgb_lookup_colortable(const dib_info
*dst
, BYTE r
, BYTE g
, BYTE b
)
2485 /* Windows reduces precision to 5 bits, probably in order to build some sort of lookup cache */
2486 return rgb_to_pixel_colortable( dst
, (r
& ~7) + 4, (g
& ~7) + 4, (b
& ~7) + 4 );
2489 static void convert_to_8(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
2491 BYTE
*dst_start
= get_pixel_ptr_8(dst
, 0, 0), *dst_pixel
;
2492 INT x
, y
, pad_size
= ((dst
->width
+ 3) & ~3) - (src_rect
->right
- src_rect
->left
);
2495 switch(src
->bit_count
)
2499 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2501 if(src
->funcs
== &funcs_8888
)
2503 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2505 dst_pixel
= dst_start
;
2506 src_pixel
= src_start
;
2507 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2509 src_val
= *src_pixel
++;
2510 *dst_pixel
++ = rgb_lookup_colortable(dst
, src_val
>> 16, src_val
>> 8, src_val
);
2512 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2513 dst_start
+= dst
->stride
;
2514 src_start
+= src
->stride
/ 4;
2517 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
2519 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2521 dst_pixel
= dst_start
;
2522 src_pixel
= src_start
;
2523 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2525 src_val
= *src_pixel
++;
2526 *dst_pixel
++ = rgb_lookup_colortable(dst
,
2527 src_val
>> src
->red_shift
,
2528 src_val
>> src
->green_shift
,
2529 src_val
>> src
->blue_shift
);
2531 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2532 dst_start
+= dst
->stride
;
2533 src_start
+= src
->stride
/ 4;
2538 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2540 dst_pixel
= dst_start
;
2541 src_pixel
= src_start
;
2542 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2544 src_val
= *src_pixel
++;
2545 *dst_pixel
++ = rgb_lookup_colortable(dst
,
2546 get_field(src_val
, src
->red_shift
, src
->red_len
),
2547 get_field(src_val
, src
->green_shift
, src
->green_len
),
2548 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
2550 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2551 dst_start
+= dst
->stride
;
2552 src_start
+= src
->stride
/ 4;
2560 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2562 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2564 dst_pixel
= dst_start
;
2565 src_pixel
= src_start
;
2566 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, src_pixel
+= 3)
2568 *dst_pixel
++ = rgb_lookup_colortable(dst
, src_pixel
[2], src_pixel
[1], src_pixel
[0] );
2570 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2571 dst_start
+= dst
->stride
;
2572 src_start
+= src
->stride
;
2579 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2580 if(src
->funcs
== &funcs_555
)
2582 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2584 dst_pixel
= dst_start
;
2585 src_pixel
= src_start
;
2586 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2588 src_val
= *src_pixel
++;
2589 *dst_pixel
++ = rgb_lookup_colortable(dst
,
2590 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
2591 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
2592 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07) );
2594 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2595 dst_start
+= dst
->stride
;
2596 src_start
+= src
->stride
/ 2;
2599 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2601 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2603 dst_pixel
= dst_start
;
2604 src_pixel
= src_start
;
2605 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2607 src_val
= *src_pixel
++;
2608 *dst_pixel
++ = rgb_lookup_colortable(dst
,
2609 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2610 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
2611 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
2612 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
2613 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2614 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
2616 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2617 dst_start
+= dst
->stride
;
2618 src_start
+= src
->stride
/ 2;
2621 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2623 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2625 dst_pixel
= dst_start
;
2626 src_pixel
= src_start
;
2627 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2629 src_val
= *src_pixel
++;
2630 *dst_pixel
++ = rgb_lookup_colortable(dst
,
2631 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2632 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
2633 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
2634 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
2635 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2636 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
2638 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2639 dst_start
+= dst
->stride
;
2640 src_start
+= src
->stride
/ 2;
2645 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2647 dst_pixel
= dst_start
;
2648 src_pixel
= src_start
;
2649 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2651 src_val
= *src_pixel
++;
2652 *dst_pixel
++ = rgb_lookup_colortable(dst
,
2653 get_field(src_val
, src
->red_shift
, src
->red_len
),
2654 get_field(src_val
, src
->green_shift
, src
->green_len
),
2655 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
2657 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2658 dst_start
+= dst
->stride
;
2659 src_start
+= src
->stride
/ 2;
2667 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2669 if(color_tables_match(dst
, src
))
2671 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
2672 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2675 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2677 memcpy(dst_start
, src_start
, src_rect
->right
- src_rect
->left
);
2678 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
2679 dst_start
+= dst
->stride
;
2680 src_start
+= src
->stride
;
2686 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2688 dst_pixel
= dst_start
;
2689 src_pixel
= src_start
;
2690 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2692 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
2693 *dst_pixel
++ = rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
2695 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2696 dst_start
+= dst
->stride
;
2697 src_start
+= src
->stride
;
2705 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2706 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2708 dst_pixel
= dst_start
;
2709 src_pixel
= src_start
;
2710 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2714 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
2716 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
2717 *dst_pixel
++ = rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
2719 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2720 dst_start
+= dst
->stride
;
2721 src_start
+= src
->stride
;
2728 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2729 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2731 dst_pixel
= dst_start
;
2732 src_pixel
= src_start
;
2733 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2736 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
2737 if((x
% 8) == 7) src_pixel
++;
2738 rgb
= src
->color_table
[src_val
];
2739 *dst_pixel
++ = rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
2741 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2742 dst_start
+= dst
->stride
;
2743 src_start
+= src
->stride
;
2750 static void convert_to_4(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
2752 BYTE
*dst_start
= get_pixel_ptr_4(dst
, 0, 0), *dst_pixel
, dst_val
;
2753 INT x
, y
, pad_size
= ((dst
->width
+ 7) & ~7) / 2 - (src_rect
->right
- src_rect
->left
+ 1) / 2;
2756 switch(src
->bit_count
)
2760 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2762 if(src
->funcs
== &funcs_8888
)
2764 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2766 dst_pixel
= dst_start
;
2767 src_pixel
= src_start
;
2768 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2770 src_val
= *src_pixel
++;
2771 dst_val
= rgb_to_pixel_colortable(dst
, src_val
>> 16, src_val
>> 8, src_val
);
2772 if((x
- src_rect
->left
) & 1)
2774 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
2778 *dst_pixel
= (dst_val
<< 4) & 0xf0;
2782 if((x
- src_rect
->left
) & 1) dst_pixel
++;
2783 memset(dst_pixel
, 0, pad_size
);
2785 dst_start
+= dst
->stride
;
2786 src_start
+= src
->stride
/ 4;
2789 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
2791 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2793 dst_pixel
= dst_start
;
2794 src_pixel
= src_start
;
2795 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2797 src_val
= *src_pixel
++;
2798 dst_val
= rgb_to_pixel_colortable(dst
,
2799 src_val
>> src
->red_shift
,
2800 src_val
>> src
->green_shift
,
2801 src_val
>> src
->blue_shift
);
2802 if((x
- src_rect
->left
) & 1)
2804 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
2808 *dst_pixel
= (dst_val
<< 4) & 0xf0;
2812 if((x
- src_rect
->left
) & 1) dst_pixel
++;
2813 memset(dst_pixel
, 0, pad_size
);
2815 dst_start
+= dst
->stride
;
2816 src_start
+= src
->stride
/ 4;
2821 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2823 dst_pixel
= dst_start
;
2824 src_pixel
= src_start
;
2825 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2827 src_val
= *src_pixel
++;
2828 dst_val
= rgb_to_pixel_colortable(dst
,
2829 get_field(src_val
, src
->red_shift
, src
->red_len
),
2830 get_field(src_val
, src
->green_shift
, src
->green_len
),
2831 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
2832 if((x
- src_rect
->left
) & 1)
2834 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
2838 *dst_pixel
= (dst_val
<< 4) & 0xf0;
2842 if((x
- src_rect
->left
) & 1) dst_pixel
++;
2843 memset(dst_pixel
, 0, pad_size
);
2845 dst_start
+= dst
->stride
;
2846 src_start
+= src
->stride
/ 4;
2854 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2856 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2858 dst_pixel
= dst_start
;
2859 src_pixel
= src_start
;
2860 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, src_pixel
+= 3)
2862 dst_val
= rgb_to_pixel_colortable(dst
, src_pixel
[2], src_pixel
[1], src_pixel
[0]);
2864 if((x
- src_rect
->left
) & 1)
2866 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
2870 *dst_pixel
= (dst_val
<< 4) & 0xf0;
2874 if((x
- src_rect
->left
) & 1) dst_pixel
++;
2875 memset(dst_pixel
, 0, pad_size
);
2877 dst_start
+= dst
->stride
;
2878 src_start
+= src
->stride
;
2885 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2886 if(src
->funcs
== &funcs_555
)
2888 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2890 dst_pixel
= dst_start
;
2891 src_pixel
= src_start
;
2892 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2894 src_val
= *src_pixel
++;
2895 dst_val
= rgb_to_pixel_colortable(dst
,
2896 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
2897 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
2898 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07) );
2899 if((x
- src_rect
->left
) & 1)
2901 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
2905 *dst_pixel
= (dst_val
<< 4) & 0xf0;
2909 if((x
- src_rect
->left
) & 1) dst_pixel
++;
2910 memset(dst_pixel
, 0, pad_size
);
2912 dst_start
+= dst
->stride
;
2913 src_start
+= src
->stride
/ 2;
2916 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2918 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2920 dst_pixel
= dst_start
;
2921 src_pixel
= src_start
;
2922 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2924 src_val
= *src_pixel
++;
2925 dst_val
= rgb_to_pixel_colortable(dst
,
2926 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2927 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
2928 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
2929 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
2930 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2931 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
2932 if((x
- src_rect
->left
) & 1)
2934 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
2938 *dst_pixel
= (dst_val
<< 4) & 0xf0;
2942 if((x
- src_rect
->left
) & 1) dst_pixel
++;
2943 memset(dst_pixel
, 0, pad_size
);
2945 dst_start
+= dst
->stride
;
2946 src_start
+= src
->stride
/ 2;
2949 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2951 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2953 dst_pixel
= dst_start
;
2954 src_pixel
= src_start
;
2955 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2957 src_val
= *src_pixel
++;
2958 dst_val
= rgb_to_pixel_colortable(dst
,
2959 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2960 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
2961 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
2962 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
2963 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2964 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
2965 if((x
- src_rect
->left
) & 1)
2967 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
2971 *dst_pixel
= (dst_val
<< 4) & 0xf0;
2975 if((x
- src_rect
->left
) & 1) dst_pixel
++;
2976 memset(dst_pixel
, 0, pad_size
);
2978 dst_start
+= dst
->stride
;
2979 src_start
+= src
->stride
/ 2;
2984 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2986 dst_pixel
= dst_start
;
2987 src_pixel
= src_start
;
2988 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2990 src_val
= *src_pixel
++;
2991 dst_val
= rgb_to_pixel_colortable(dst
,
2992 get_field(src_val
, src
->red_shift
, src
->red_len
),
2993 get_field(src_val
, src
->green_shift
, src
->green_len
),
2994 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
2995 if((x
- src_rect
->left
) & 1)
2997 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3001 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3005 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3006 memset(dst_pixel
, 0, pad_size
);
3008 dst_start
+= dst
->stride
;
3009 src_start
+= src
->stride
/ 2;
3017 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3019 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3021 dst_pixel
= dst_start
;
3022 src_pixel
= src_start
;
3023 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3025 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
3026 dst_val
= rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
3027 if((x
- src_rect
->left
) & 1)
3029 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3033 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3037 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3038 memset(dst_pixel
, 0, pad_size
);
3040 dst_start
+= dst
->stride
;
3041 src_start
+= src
->stride
;
3048 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3050 if(color_tables_match(dst
, src
) && (src_rect
->left
& 1) == 0)
3052 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
3053 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
3056 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3058 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
+ 1) / 2);
3059 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
+ 1) / 2, 0, pad_size
);
3060 dst_start
+= dst
->stride
;
3061 src_start
+= src
->stride
;
3067 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3069 dst_pixel
= dst_start
;
3070 src_pixel
= src_start
;
3071 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3075 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
3077 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
3078 dst_val
= rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
3079 if((x
- src_rect
->left
) & 1)
3081 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3085 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3089 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3090 memset(dst_pixel
, 0, pad_size
);
3092 dst_start
+= dst
->stride
;
3093 src_start
+= src
->stride
;
3101 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3102 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3104 dst_pixel
= dst_start
;
3105 src_pixel
= src_start
;
3106 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3109 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
3110 if((x
% 8) == 7) src_pixel
++;
3111 rgb
= src
->color_table
[src_val
];
3112 dst_val
= rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
3113 if((x
- src_rect
->left
) & 1)
3115 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3119 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3123 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3124 memset(dst_pixel
, 0, pad_size
);
3126 dst_start
+= dst
->stride
;
3127 src_start
+= src
->stride
;
3134 static void convert_to_1(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
3136 BYTE
*dst_start
= get_pixel_ptr_1(dst
, 0, 0), *dst_pixel
, dst_val
;
3137 INT x
, y
, pad_size
= ((dst
->width
+ 31) & ~31) / 8 - (src_rect
->right
- src_rect
->left
+ 7) / 8;
3141 /* FIXME: Brushes should be dithered. */
3143 switch(src
->bit_count
)
3147 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3149 if(src
->funcs
== &funcs_8888
)
3151 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3153 dst_pixel
= dst_start
;
3154 src_pixel
= src_start
;
3155 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3157 src_val
= *src_pixel
++;
3158 dst_val
= rgb_to_pixel_colortable(dst
, src_val
>> 16, src_val
>> 8, src_val
) ? 0xff : 0;
3160 if(bit_pos
== 0) *dst_pixel
= 0;
3161 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3171 if(bit_pos
!= 0) dst_pixel
++;
3172 memset(dst_pixel
, 0, pad_size
);
3174 dst_start
+= dst
->stride
;
3175 src_start
+= src
->stride
/ 4;
3178 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
3180 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3182 dst_pixel
= dst_start
;
3183 src_pixel
= src_start
;
3184 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3186 src_val
= *src_pixel
++;
3187 dst_val
= rgb_to_pixel_colortable(dst
,
3188 src_val
>> src
->red_shift
,
3189 src_val
>> src
->green_shift
,
3190 src_val
>> src
->blue_shift
) ? 0xff : 0;
3192 if(bit_pos
== 0) *dst_pixel
= 0;
3193 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3203 if(bit_pos
!= 0) dst_pixel
++;
3204 memset(dst_pixel
, 0, pad_size
);
3206 dst_start
+= dst
->stride
;
3207 src_start
+= src
->stride
/ 4;
3212 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3214 dst_pixel
= dst_start
;
3215 src_pixel
= src_start
;
3216 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3218 src_val
= *src_pixel
++;
3219 dst_val
= rgb_to_pixel_colortable(dst
,
3220 get_field(src_val
, src
->red_shift
, src
->red_len
),
3221 get_field(src_val
, src
->green_shift
, src
->green_len
),
3222 get_field(src_val
, src
->blue_shift
, src
->blue_len
)) ? 0xff : 0;
3224 if(bit_pos
== 0) *dst_pixel
= 0;
3225 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3235 if(bit_pos
!= 0) dst_pixel
++;
3236 memset(dst_pixel
, 0, pad_size
);
3238 dst_start
+= dst
->stride
;
3239 src_start
+= src
->stride
/ 4;
3247 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3249 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3251 dst_pixel
= dst_start
;
3252 src_pixel
= src_start
;
3253 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++, src_pixel
+= 3)
3255 dst_val
= rgb_to_pixel_colortable(dst
, src_pixel
[2], src_pixel
[1], src_pixel
[0]) ? 0xff : 0;
3257 if(bit_pos
== 0) *dst_pixel
= 0;
3258 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3268 if(bit_pos
!= 0) dst_pixel
++;
3269 memset(dst_pixel
, 0, pad_size
);
3271 dst_start
+= dst
->stride
;
3272 src_start
+= src
->stride
;
3279 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3280 if(src
->funcs
== &funcs_555
)
3282 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3284 dst_pixel
= dst_start
;
3285 src_pixel
= src_start
;
3286 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3288 src_val
= *src_pixel
++;
3289 dst_val
= rgb_to_pixel_colortable(dst
,
3290 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
3291 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
3292 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07) ) ? 0xff : 0;
3294 if(bit_pos
== 0) *dst_pixel
= 0;
3295 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3305 if(bit_pos
!= 0) dst_pixel
++;
3306 memset(dst_pixel
, 0, pad_size
);
3308 dst_start
+= dst
->stride
;
3309 src_start
+= src
->stride
/ 2;
3312 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
3314 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3316 dst_pixel
= dst_start
;
3317 src_pixel
= src_start
;
3318 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3320 src_val
= *src_pixel
++;
3321 dst_val
= rgb_to_pixel_colortable(dst
,
3322 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3323 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3324 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
3325 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
3326 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3327 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) ) ? 0xff : 0;
3328 if(bit_pos
== 0) *dst_pixel
= 0;
3329 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3339 if(bit_pos
!= 0) dst_pixel
++;
3340 memset(dst_pixel
, 0, pad_size
);
3342 dst_start
+= dst
->stride
;
3343 src_start
+= src
->stride
/ 2;
3346 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
3348 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3350 dst_pixel
= dst_start
;
3351 src_pixel
= src_start
;
3352 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3354 src_val
= *src_pixel
++;
3355 dst_val
= rgb_to_pixel_colortable(dst
,
3356 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3357 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3358 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
3359 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
3360 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3361 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) ) ? 0xff : 0;
3362 if(bit_pos
== 0) *dst_pixel
= 0;
3363 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3373 if(bit_pos
!= 0) dst_pixel
++;
3374 memset(dst_pixel
, 0, pad_size
);
3376 dst_start
+= dst
->stride
;
3377 src_start
+= src
->stride
/ 2;
3382 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3384 dst_pixel
= dst_start
;
3385 src_pixel
= src_start
;
3386 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3388 src_val
= *src_pixel
++;
3389 dst_val
= rgb_to_pixel_colortable(dst
,
3390 get_field(src_val
, src
->red_shift
, src
->red_len
),
3391 get_field(src_val
, src
->green_shift
, src
->green_len
),
3392 get_field(src_val
, src
->blue_shift
, src
->blue_len
)) ? 0xff : 0;
3393 if(bit_pos
== 0) *dst_pixel
= 0;
3394 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3404 if(bit_pos
!= 0) dst_pixel
++;
3405 memset(dst_pixel
, 0, pad_size
);
3407 dst_start
+= dst
->stride
;
3408 src_start
+= src
->stride
/ 2;
3416 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3418 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3420 dst_pixel
= dst_start
;
3421 src_pixel
= src_start
;
3422 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3424 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
3425 dst_val
= rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
) ? 0xff : 0;
3427 if(bit_pos
== 0) *dst_pixel
= 0;
3428 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3438 if(bit_pos
!= 0) dst_pixel
++;
3439 memset(dst_pixel
, 0, pad_size
);
3441 dst_start
+= dst
->stride
;
3442 src_start
+= src
->stride
;
3449 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3451 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3453 dst_pixel
= dst_start
;
3454 src_pixel
= src_start
;
3455 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3459 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
3461 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
3462 dst_val
= rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
) ? 0xff : 0;
3464 if(bit_pos
== 0) *dst_pixel
= 0;
3465 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3475 if(bit_pos
!= 0) dst_pixel
++;
3476 memset(dst_pixel
, 0, pad_size
);
3478 dst_start
+= dst
->stride
;
3479 src_start
+= src
->stride
;
3484 /* Note that while MSDN states that a 1 bpp dib brush -> mono dc
3485 uses text/bkgnd colours instead of the dib's colour table, this
3486 doesn't appear to be the case for a dc backed by a
3491 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3492 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3494 dst_pixel
= dst_start
;
3495 src_pixel
= src_start
;
3496 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3499 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
3500 if((x
% 8) == 7) src_pixel
++;
3501 rgb
= src
->color_table
[src_val
];
3502 dst_val
= rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
) ? 0xff : 0;
3504 if(bit_pos
== 0) *dst_pixel
= 0;
3505 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3515 if(bit_pos
!= 0) dst_pixel
++;
3516 memset(dst_pixel
, 0, pad_size
);
3518 dst_start
+= dst
->stride
;
3519 src_start
+= src
->stride
;
3526 static void convert_to_null(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
3530 static inline BYTE
blend_color(BYTE dst
, BYTE src
, DWORD alpha
)
3532 return (src
* alpha
+ dst
* (255 - alpha
) + 127) / 255;
3535 static inline DWORD
blend_argb( DWORD dst
, DWORD src
, DWORD alpha
)
3537 return (blend_color( dst
, src
, alpha
) |
3538 blend_color( dst
>> 8, src
>> 8, alpha
) << 8 |
3539 blend_color( dst
>> 16, src
>> 16, alpha
) << 16 |
3540 blend_color( dst
>> 24, src
>> 24, alpha
) << 24);
3543 static inline DWORD
blend_argb_alpha( DWORD dst
, DWORD src
, DWORD alpha
)
3545 BYTE b
= ((BYTE
)src
* alpha
+ 127) / 255;
3546 BYTE g
= ((BYTE
)(src
>> 8) * alpha
+ 127) / 255;
3547 BYTE r
= ((BYTE
)(src
>> 16) * alpha
+ 127) / 255;
3548 alpha
= ((BYTE
)(src
>> 24) * alpha
+ 127) / 255;
3549 return ((b
+ ((BYTE
)dst
* (255 - alpha
) + 127) / 255) |
3550 (g
+ ((BYTE
)(dst
>> 8) * (255 - alpha
) + 127) / 255) << 8 |
3551 (r
+ ((BYTE
)(dst
>> 16) * (255 - alpha
) + 127) / 255) << 16 |
3552 (alpha
+ ((BYTE
)(dst
>> 24) * (255 - alpha
) + 127) / 255) << 24);
3555 static inline DWORD
blend_rgb( BYTE dst_r
, BYTE dst_g
, BYTE dst_b
, DWORD src
, BLENDFUNCTION blend
)
3557 if (blend
.AlphaFormat
& AC_SRC_ALPHA
)
3559 DWORD alpha
= blend
.SourceConstantAlpha
;
3560 BYTE src_b
= ((BYTE
)src
* alpha
+ 127) / 255;
3561 BYTE src_g
= ((BYTE
)(src
>> 8) * alpha
+ 127) / 255;
3562 BYTE src_r
= ((BYTE
)(src
>> 16) * alpha
+ 127) / 255;
3563 alpha
= ((BYTE
)(src
>> 24) * alpha
+ 127) / 255;
3564 return ((src_b
+ (dst_b
* (255 - alpha
) + 127) / 255) |
3565 (src_g
+ (dst_g
* (255 - alpha
) + 127) / 255) << 8 |
3566 (src_r
+ (dst_r
* (255 - alpha
) + 127) / 255) << 16);
3568 return (blend_color( dst_b
, src
, blend
.SourceConstantAlpha
) |
3569 blend_color( dst_g
, src
>> 8, blend
.SourceConstantAlpha
) << 8 |
3570 blend_color( dst_r
, src
>> 16, blend
.SourceConstantAlpha
) << 16);
3573 static void blend_rect_8888(const dib_info
*dst
, const RECT
*rc
,
3574 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3576 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
3577 DWORD
*dst_ptr
= get_pixel_ptr_32( dst
, rc
->left
, rc
->top
);
3580 if (blend
.AlphaFormat
& AC_SRC_ALPHA
)
3581 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
3582 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3583 dst_ptr
[x
] = blend_argb_alpha( dst_ptr
[x
], src_ptr
[x
], blend
.SourceConstantAlpha
);
3585 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
3586 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3587 dst_ptr
[x
] = blend_argb( dst_ptr
[x
], src_ptr
[x
], blend
.SourceConstantAlpha
);
3590 static void blend_rect_32(const dib_info
*dst
, const RECT
*rc
,
3591 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3593 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
3594 DWORD
*dst_ptr
= get_pixel_ptr_32( dst
, rc
->left
, rc
->top
);
3597 if (dst
->red_len
== 8 && dst
->green_len
== 8 && dst
->blue_len
== 8)
3599 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
3601 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3603 DWORD val
= blend_rgb( dst_ptr
[x
] >> dst
->red_shift
,
3604 dst_ptr
[x
] >> dst
->green_shift
,
3605 dst_ptr
[x
] >> dst
->blue_shift
,
3606 src_ptr
[x
], blend
);
3607 dst_ptr
[x
] = ((( val
& 0xff) << dst
->blue_shift
) |
3608 (((val
>> 8) & 0xff) << dst
->green_shift
) |
3609 (((val
>> 16) & 0xff) << dst
->red_shift
));
3615 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
3617 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3619 DWORD val
= blend_rgb( get_field( dst_ptr
[x
], dst
->red_shift
, dst
->red_len
),
3620 get_field( dst_ptr
[x
], dst
->green_shift
, dst
->green_len
),
3621 get_field( dst_ptr
[x
], dst
->blue_shift
, dst
->blue_len
),
3622 src_ptr
[x
], blend
);
3623 dst_ptr
[x
] = (put_field( val
>> 16, dst
->red_shift
, dst
->red_len
) |
3624 put_field( val
>> 8, dst
->green_shift
, dst
->green_len
) |
3625 put_field( val
, dst
->blue_shift
, dst
->blue_len
));
3631 static void blend_rect_24(const dib_info
*dst
, const RECT
*rc
,
3632 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3634 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
3635 BYTE
*dst_ptr
= get_pixel_ptr_24( dst
, rc
->left
, rc
->top
);
3638 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
3640 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3642 DWORD val
= blend_rgb( dst_ptr
[x
* 3 + 2], dst_ptr
[x
* 3 + 1], dst_ptr
[x
* 3],
3643 src_ptr
[x
], blend
);
3644 dst_ptr
[x
* 3] = val
;
3645 dst_ptr
[x
* 3 + 1] = val
>> 8;
3646 dst_ptr
[x
* 3 + 2] = val
>> 16;
3651 static void blend_rect_555(const dib_info
*dst
, const RECT
*rc
,
3652 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3654 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
3655 WORD
*dst_ptr
= get_pixel_ptr_16( dst
, rc
->left
, rc
->top
);
3658 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 2, src_ptr
+= src
->stride
/ 4)
3660 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3662 DWORD val
= blend_rgb( ((dst_ptr
[x
] >> 7) & 0xf8) | ((dst_ptr
[x
] >> 12) & 0x07),
3663 ((dst_ptr
[x
] >> 2) & 0xf8) | ((dst_ptr
[x
] >> 7) & 0x07),
3664 ((dst_ptr
[x
] << 3) & 0xf8) | ((dst_ptr
[x
] >> 2) & 0x07),
3665 src_ptr
[x
], blend
);
3666 dst_ptr
[x
] = ((val
>> 9) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 3) & 0x001f);
3671 static void blend_rect_16(const dib_info
*dst
, const RECT
*rc
,
3672 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3674 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
3675 WORD
*dst_ptr
= get_pixel_ptr_16( dst
, rc
->left
, rc
->top
);
3678 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 2, src_ptr
+= src
->stride
/ 4)
3680 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3682 DWORD val
= blend_rgb( get_field( dst_ptr
[x
], dst
->red_shift
, dst
->red_len
),
3683 get_field( dst_ptr
[x
], dst
->green_shift
, dst
->green_len
),
3684 get_field( dst_ptr
[x
], dst
->blue_shift
, dst
->blue_len
),
3685 src_ptr
[x
], blend
);
3686 dst_ptr
[x
] = (put_field((val
>> 16), dst
->red_shift
, dst
->red_len
) |
3687 put_field((val
>> 8), dst
->green_shift
, dst
->green_len
) |
3688 put_field( val
, dst
->blue_shift
, dst
->blue_len
));
3693 static void blend_rect_8(const dib_info
*dst
, const RECT
*rc
,
3694 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3696 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
3697 BYTE
*dst_ptr
= get_pixel_ptr_8( dst
, rc
->left
, rc
->top
);
3700 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
3702 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
3704 RGBQUAD rgb
= colortable_entry( dst
, dst_ptr
[x
] );
3705 DWORD val
= blend_rgb( rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
, src_ptr
[x
], blend
);
3706 dst_ptr
[x
] = rgb_lookup_colortable( dst
, val
>> 16, val
>> 8, val
);
3711 static void blend_rect_4(const dib_info
*dst
, const RECT
*rc
,
3712 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3714 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
- rc
->left
, origin
->y
);
3715 BYTE
*dst_ptr
= get_pixel_ptr_4( dst
, 0, rc
->top
);
3718 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
3720 for (x
= rc
->left
; x
< rc
->right
; x
++)
3722 DWORD val
= ((x
& 1) ? dst_ptr
[x
/ 2] : (dst_ptr
[x
/ 2] >> 4)) & 0x0f;
3723 RGBQUAD rgb
= colortable_entry( dst
, val
);
3724 val
= blend_rgb( rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
, src_ptr
[x
], blend
);
3725 val
= rgb_lookup_colortable( dst
, val
>> 16, val
>> 8, val
);
3727 dst_ptr
[x
/ 2] = val
| (dst_ptr
[x
/ 2] & 0xf0);
3729 dst_ptr
[x
/ 2] = (val
<< 4) | (dst_ptr
[x
/ 2] & 0x0f);
3734 static void blend_rect_1(const dib_info
*dst
, const RECT
*rc
,
3735 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3737 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
- rc
->left
, origin
->y
);
3738 BYTE
*dst_ptr
= get_pixel_ptr_1( dst
, 0, rc
->top
);
3741 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
3743 for (x
= rc
->left
; x
< rc
->right
; x
++)
3745 DWORD val
= (dst_ptr
[x
/ 8] & pixel_masks_1
[x
% 8]) ? 1 : 0;
3746 RGBQUAD rgb
= dst
->color_table
[val
];
3747 val
= blend_rgb( rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
, src_ptr
[x
], blend
);
3748 val
= rgb_to_pixel_colortable(dst
, val
>> 16, val
>> 8, val
) ? 0xff : 0;
3749 dst_ptr
[x
/ 8] = (dst_ptr
[x
/ 8] & ~pixel_masks_1
[x
% 8]) | (val
& pixel_masks_1
[x
% 8]);
3754 static void blend_rect_null(const dib_info
*dst
, const RECT
*rc
,
3755 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
3759 static inline BYTE
aa_color( BYTE dst
, BYTE text
, BYTE min_comp
, BYTE max_comp
)
3761 if (dst
== text
) return dst
;
3765 DWORD diff
= dst
- text
;
3766 DWORD range
= max_comp
- text
;
3767 dst
= text
+ (diff
* range
) / (0xff - text
);
3772 DWORD diff
= text
- dst
;
3773 DWORD range
= text
- min_comp
;
3774 dst
= text
- (diff
* range
) / text
;
3779 static inline DWORD
aa_rgb( BYTE r_dst
, BYTE g_dst
, BYTE b_dst
, DWORD text
, const struct intensity_range
*range
)
3781 return (aa_color( b_dst
, text
, range
->b_min
, range
->b_max
) |
3782 aa_color( g_dst
, text
>> 8, range
->g_min
, range
->g_max
) << 8 |
3783 aa_color( r_dst
, text
>> 16, range
->r_min
, range
->r_max
) << 16);
3786 static void draw_glyph_8888( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
3787 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
3789 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
3790 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
3793 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
3795 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
3797 if (glyph_ptr
[x
] <= 1) continue;
3798 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
3799 dst_ptr
[x
] = aa_rgb( dst_ptr
[x
] >> 16, dst_ptr
[x
] >> 8, dst_ptr
[x
], text_pixel
, ranges
+ glyph_ptr
[x
] );
3801 dst_ptr
+= dib
->stride
/ 4;
3802 glyph_ptr
+= glyph
->stride
;
3806 static void draw_glyph_32( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
3807 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
3809 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
3810 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
3814 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
3815 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
3816 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
3818 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
3820 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
3822 if (glyph_ptr
[x
] <= 1) continue;
3823 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
3824 val
= aa_rgb( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
3825 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
3826 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
3827 text
, ranges
+ glyph_ptr
[x
] );
3828 dst_ptr
[x
] = (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
3829 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
3830 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
3832 dst_ptr
+= dib
->stride
/ 4;
3833 glyph_ptr
+= glyph
->stride
;
3837 static void draw_glyph_24( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
3838 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
3840 BYTE
*dst_ptr
= get_pixel_ptr_24( dib
, rect
->left
, rect
->top
);
3841 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
3845 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
3847 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
3849 if (glyph_ptr
[x
] <= 1) continue;
3850 if (glyph_ptr
[x
] >= 16)
3853 val
= aa_rgb( dst_ptr
[x
* 3 + 2], dst_ptr
[x
* 3 + 1], dst_ptr
[x
* 3],
3854 text_pixel
, ranges
+ glyph_ptr
[x
] );
3855 dst_ptr
[x
* 3] = val
;
3856 dst_ptr
[x
* 3 + 1] = val
>> 8;
3857 dst_ptr
[x
* 3 + 2] = val
>> 16;
3859 dst_ptr
+= dib
->stride
;
3860 glyph_ptr
+= glyph
->stride
;
3864 static void draw_glyph_555( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
3865 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
3867 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
3868 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
3872 text
= ((text_pixel
<< 9) & 0xf80000) | ((text_pixel
<< 4) & 0x070000) |
3873 ((text_pixel
<< 6) & 0x00f800) | ((text_pixel
<< 1) & 0x000700) |
3874 ((text_pixel
<< 3) & 0x0000f8) | ((text_pixel
>> 2) & 0x000007);
3876 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
3878 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
3880 if (glyph_ptr
[x
] <= 1) continue;
3881 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
3882 val
= aa_rgb( ((dst_ptr
[x
] >> 7) & 0xf8) | ((dst_ptr
[x
] >> 12) & 0x07),
3883 ((dst_ptr
[x
] >> 2) & 0xf8) | ((dst_ptr
[x
] >> 7) & 0x07),
3884 ((dst_ptr
[x
] << 3) & 0xf8) | ((dst_ptr
[x
] >> 2) & 0x07),
3885 text
, ranges
+ glyph_ptr
[x
] );
3886 dst_ptr
[x
] = ((val
>> 9) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 3) & 0x001f);
3888 dst_ptr
+= dib
->stride
/ 2;
3889 glyph_ptr
+= glyph
->stride
;
3893 static void draw_glyph_16( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
3894 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
3896 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
3897 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
3901 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
3902 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
3903 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
3905 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
3907 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
3909 if (glyph_ptr
[x
] <= 1) continue;
3910 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
3911 val
= aa_rgb( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
3912 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
3913 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
3914 text
, ranges
+ glyph_ptr
[x
] );
3915 dst_ptr
[x
] = (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
3916 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
3917 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
3919 dst_ptr
+= dib
->stride
/ 2;
3920 glyph_ptr
+= glyph
->stride
;
3924 static void draw_glyph_8( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
3925 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
3927 BYTE
*dst_ptr
= get_pixel_ptr_8( dib
, rect
->left
, rect
->top
);
3928 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
3931 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
3933 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
3935 /* no antialiasing, glyph should only contain 0 or 16. */
3936 if (glyph_ptr
[x
] >= 16)
3937 dst_ptr
[x
] = text_pixel
;
3939 dst_ptr
+= dib
->stride
;
3940 glyph_ptr
+= glyph
->stride
;
3944 static void draw_glyph_4( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
3945 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
3947 BYTE
*dst_ptr
= get_pixel_ptr_4( dib
, 0, rect
->top
);
3948 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
- rect
->left
, origin
->y
);
3951 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
3953 for (x
= rect
->left
; x
< rect
->right
; x
++)
3955 /* no antialiasing, glyph should only contain 0 or 16. */
3956 if (glyph_ptr
[x
] >= 16)
3959 dst_ptr
[x
/ 2] = text_pixel
| (dst_ptr
[x
/ 2] & 0xf0);
3961 dst_ptr
[x
/ 2] = (text_pixel
<< 4) | (dst_ptr
[x
/ 2] & 0x0f);
3964 dst_ptr
+= dib
->stride
;
3965 glyph_ptr
+= glyph
->stride
;
3969 static void draw_glyph_1( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
3970 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
3972 BYTE
*dst_ptr
= get_pixel_ptr_1( dib
, 0, rect
->top
);
3973 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
- rect
->left
, origin
->y
);
3975 BYTE text
= (text_pixel
& 1) ? 0xff : 0;
3977 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
3979 for (x
= rect
->left
; x
< rect
->right
; x
++)
3981 /* no antialiasing, glyph should only contain 0 or 16. */
3982 if (glyph_ptr
[x
] >= 16)
3983 dst_ptr
[x
/ 8] = (dst_ptr
[x
/ 8] & ~pixel_masks_1
[x
% 8]) | (text
& pixel_masks_1
[x
% 8]);
3985 dst_ptr
+= dib
->stride
;
3986 glyph_ptr
+= glyph
->stride
;
3990 static void draw_glyph_null( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
3991 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
3996 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
)
3998 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
3999 DWORD mask_start
= 0, mask_offset
;
4000 DWORD
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
4003 for(y
= 0; y
< hatch
->height
; y
++)
4005 hatch_ptr
= hatch_start
;
4006 mask_offset
= mask_start
;
4007 for(x
= 0; x
< hatch
->width
; x
++)
4009 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
4011 and_bits
[mask_offset
] = fg
->and;
4012 xor_bits
[mask_offset
] = fg
->xor;
4016 and_bits
[mask_offset
] = bg
->and;
4017 xor_bits
[mask_offset
] = bg
->xor;
4019 if(x
% 8 == 7) hatch_ptr
++;
4022 hatch_start
+= hatch
->stride
;
4023 mask_start
+= dib
->stride
/ 4;
4029 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
)
4031 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
4032 DWORD mask_start
= 0, mask_offset
;
4033 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
4036 for(y
= 0; y
< hatch
->height
; y
++)
4038 hatch_ptr
= hatch_start
;
4039 mask_offset
= mask_start
;
4040 for(x
= 0; x
< hatch
->width
; x
++)
4042 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
4044 and_bits
[mask_offset
] = fg
->and & 0xff;
4045 xor_bits
[mask_offset
++] = fg
->xor & 0xff;
4046 and_bits
[mask_offset
] = (fg
->and >> 8) & 0xff;
4047 xor_bits
[mask_offset
++] = (fg
->xor >> 8) & 0xff;
4048 and_bits
[mask_offset
] = (fg
->and >> 16) & 0xff;
4049 xor_bits
[mask_offset
++] = (fg
->xor >> 16) & 0xff;
4053 and_bits
[mask_offset
] = bg
->and & 0xff;
4054 xor_bits
[mask_offset
++] = bg
->xor & 0xff;
4055 and_bits
[mask_offset
] = (bg
->and >> 8) & 0xff;
4056 xor_bits
[mask_offset
++] = (bg
->xor >> 8) & 0xff;
4057 and_bits
[mask_offset
] = (bg
->and >> 16) & 0xff;
4058 xor_bits
[mask_offset
++] = (bg
->xor >> 16) & 0xff;
4060 if(x
% 8 == 7) hatch_ptr
++;
4062 hatch_start
+= hatch
->stride
;
4063 mask_start
+= dib
->stride
;
4069 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
)
4071 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
4072 DWORD mask_start
= 0, mask_offset
;
4073 WORD
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
4076 for(y
= 0; y
< hatch
->height
; y
++)
4078 hatch_ptr
= hatch_start
;
4079 mask_offset
= mask_start
;
4080 for(x
= 0; x
< hatch
->width
; x
++)
4082 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
4084 and_bits
[mask_offset
] = fg
->and;
4085 xor_bits
[mask_offset
] = fg
->xor;
4089 and_bits
[mask_offset
] = bg
->and;
4090 xor_bits
[mask_offset
] = bg
->xor;
4092 if(x
% 8 == 7) hatch_ptr
++;
4095 hatch_start
+= hatch
->stride
;
4096 mask_start
+= dib
->stride
/ 2;
4102 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
)
4104 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
4105 DWORD mask_start
= 0, mask_offset
;
4106 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
4109 for(y
= 0; y
< hatch
->height
; y
++)
4111 hatch_ptr
= hatch_start
;
4112 mask_offset
= mask_start
;
4113 for(x
= 0; x
< hatch
->width
; x
++)
4115 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
4117 and_bits
[mask_offset
] = fg
->and;
4118 xor_bits
[mask_offset
] = fg
->xor;
4122 and_bits
[mask_offset
] = bg
->and;
4123 xor_bits
[mask_offset
] = bg
->xor;
4125 if(x
% 8 == 7) hatch_ptr
++;
4128 hatch_start
+= hatch
->stride
;
4129 mask_start
+= dib
->stride
;
4135 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
)
4137 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
4138 DWORD mask_start
= 0, mask_offset
;
4139 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
4140 const rop_mask
*rop_mask
;
4143 for(y
= 0; y
< hatch
->height
; y
++)
4145 hatch_ptr
= hatch_start
;
4146 mask_offset
= mask_start
;
4147 for(x
= 0; x
< hatch
->width
; x
++)
4149 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
4156 and_bits
[mask_offset
] = (rop_mask
->and & 0x0f) | (and_bits
[mask_offset
] & 0xf0);
4157 xor_bits
[mask_offset
] = (rop_mask
->xor & 0x0f) | (xor_bits
[mask_offset
] & 0xf0);
4162 and_bits
[mask_offset
] = (rop_mask
->and << 4) & 0xf0;
4163 xor_bits
[mask_offset
] = (rop_mask
->xor << 4) & 0xf0;
4166 if(x
% 8 == 7) hatch_ptr
++;
4168 hatch_start
+= hatch
->stride
;
4169 mask_start
+= dib
->stride
;
4175 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
)
4177 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
4178 DWORD mask_start
= 0, mask_offset
;
4179 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
4183 for(y
= 0; y
< hatch
->height
; y
++)
4185 hatch_ptr
= hatch_start
;
4186 mask_offset
= mask_start
;
4187 for(x
= 0, bit_pos
= 0; x
< hatch
->width
; x
++)
4189 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
4191 rop_mask
.and = (fg
->and & 1) ? 0xff : 0;
4192 rop_mask
.xor = (fg
->xor & 1) ? 0xff : 0;
4196 rop_mask
.and = (bg
->and & 1) ? 0xff : 0;
4197 rop_mask
.xor = (bg
->xor & 1) ? 0xff : 0;
4200 if(bit_pos
== 0) and_bits
[mask_offset
] = xor_bits
[mask_offset
] = 0;
4202 and_bits
[mask_offset
] = (rop_mask
.and & pixel_masks_1
[bit_pos
]) | (and_bits
[mask_offset
] & ~pixel_masks_1
[bit_pos
]);
4203 xor_bits
[mask_offset
] = (rop_mask
.xor & pixel_masks_1
[bit_pos
]) | (xor_bits
[mask_offset
] & ~pixel_masks_1
[bit_pos
]);
4212 hatch_start
+= hatch
->stride
;
4213 mask_start
+= dib
->stride
;
4219 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
)
4224 static inline void rop_codes_from_stretch_mode( int mode
, struct rop_codes
*codes
)
4229 case STRETCH_DELETESCANS
:
4230 get_rop_codes( R2_COPYPEN
, codes
);
4232 case STRETCH_ORSCANS
:
4233 get_rop_codes( R2_MERGEPEN
, codes
);
4235 case STRETCH_ANDSCANS
:
4236 get_rop_codes( R2_MASKPEN
, codes
);
4242 static void stretch_row_32(const dib_info
*dst_dib
, const POINT
*dst_start
,
4243 const dib_info
*src_dib
, const POINT
*src_start
,
4244 const struct stretch_params
*params
, int mode
,
4247 DWORD
*dst_ptr
= get_pixel_ptr_32( dst_dib
, dst_start
->x
, dst_start
->y
);
4248 DWORD
*src_ptr
= get_pixel_ptr_32( src_dib
, src_start
->x
, src_start
->y
);
4249 int err
= params
->err_start
;
4251 struct rop_codes codes
;
4253 rop_codes_from_stretch_mode( mode
, &codes
);
4254 for (width
= params
->length
; width
; width
--)
4256 do_rop_codes_32( dst_ptr
, *src_ptr
, &codes
);
4257 dst_ptr
+= params
->dst_inc
;
4260 src_ptr
+= params
->src_inc
;
4261 err
+= params
->err_add_1
;
4263 else err
+= params
->err_add_2
;
4267 static void stretch_row_24(const dib_info
*dst_dib
, const POINT
*dst_start
,
4268 const dib_info
*src_dib
, const POINT
*src_start
,
4269 const struct stretch_params
*params
, int mode
,
4272 BYTE
*dst_ptr
= get_pixel_ptr_24( dst_dib
, dst_start
->x
, dst_start
->y
);
4273 BYTE
*src_ptr
= get_pixel_ptr_24( src_dib
, src_start
->x
, src_start
->y
);
4274 int err
= params
->err_start
;
4276 struct rop_codes codes
;
4278 rop_codes_from_stretch_mode( mode
, &codes
);
4279 for (width
= params
->length
; width
; width
--)
4281 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
4282 do_rop_codes_8( dst_ptr
+ 1, *(src_ptr
+ 1), &codes
);
4283 do_rop_codes_8( dst_ptr
+ 2, *(src_ptr
+ 2), &codes
);
4284 dst_ptr
+= 3 * params
->dst_inc
;
4287 src_ptr
+= 3 * params
->src_inc
;
4288 err
+= params
->err_add_1
;
4290 else err
+= params
->err_add_2
;
4294 static void stretch_row_16(const dib_info
*dst_dib
, const POINT
*dst_start
,
4295 const dib_info
*src_dib
, const POINT
*src_start
,
4296 const struct stretch_params
*params
, int mode
,
4299 WORD
*dst_ptr
= get_pixel_ptr_16( dst_dib
, dst_start
->x
, dst_start
->y
);
4300 WORD
*src_ptr
= get_pixel_ptr_16( src_dib
, src_start
->x
, src_start
->y
);
4301 int err
= params
->err_start
;
4303 struct rop_codes codes
;
4305 rop_codes_from_stretch_mode( mode
, &codes
);
4306 for (width
= params
->length
; width
; width
--)
4308 do_rop_codes_16( dst_ptr
, *src_ptr
, &codes
);
4309 dst_ptr
+= params
->dst_inc
;
4312 src_ptr
+= params
->src_inc
;
4313 err
+= params
->err_add_1
;
4315 else err
+= params
->err_add_2
;
4319 static void stretch_row_8(const dib_info
*dst_dib
, const POINT
*dst_start
,
4320 const dib_info
*src_dib
, const POINT
*src_start
,
4321 const struct stretch_params
*params
, int mode
,
4324 BYTE
*dst_ptr
= get_pixel_ptr_8( dst_dib
, dst_start
->x
, dst_start
->y
);
4325 BYTE
*src_ptr
= get_pixel_ptr_8( src_dib
, src_start
->x
, src_start
->y
);
4326 int err
= params
->err_start
;
4328 struct rop_codes codes
;
4330 rop_codes_from_stretch_mode( mode
, &codes
);
4331 for (width
= params
->length
; width
; width
--)
4333 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
4334 dst_ptr
+= params
->dst_inc
;
4337 src_ptr
+= params
->src_inc
;
4338 err
+= params
->err_add_1
;
4340 else err
+= params
->err_add_2
;
4344 static void stretch_row_4(const dib_info
*dst_dib
, const POINT
*dst_start
,
4345 const dib_info
*src_dib
, const POINT
*src_start
,
4346 const struct stretch_params
*params
, int mode
,
4349 BYTE
*dst_ptr
= get_pixel_ptr_4( dst_dib
, dst_start
->x
, dst_start
->y
);
4350 BYTE
*src_ptr
= get_pixel_ptr_4( src_dib
, src_start
->x
, src_start
->y
);
4351 int err
= params
->err_start
;
4352 int width
, dst_x
= dst_start
->x
, src_x
= src_start
->x
;
4353 struct rop_codes codes
;
4356 rop_codes_from_stretch_mode( mode
, &codes
);
4357 for (width
= params
->length
; width
; width
--)
4359 if (src_x
& 1) src_val
= (*src_ptr
& 0x0f) | (*src_ptr
<< 4);
4360 else src_val
= (*src_ptr
& 0xf0) | (*src_ptr
>> 4);
4362 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, (dst_x
& 1) ? 0x0f : 0xf0 );
4364 if ((dst_x
& ~1) != ((dst_x
+ params
->dst_inc
) & ~1))
4365 dst_ptr
+= params
->dst_inc
;
4366 dst_x
+= params
->dst_inc
;
4370 if ((src_x
& ~1) != ((src_x
+ params
->src_inc
) & ~1))
4371 src_ptr
+= params
->src_inc
;
4372 src_x
+= params
->src_inc
;
4373 err
+= params
->err_add_1
;
4375 else err
+= params
->err_add_2
;
4379 static void stretch_row_1(const dib_info
*dst_dib
, const POINT
*dst_start
,
4380 const dib_info
*src_dib
, const POINT
*src_start
,
4381 const struct stretch_params
*params
, int mode
,
4384 BYTE
*dst_ptr
= get_pixel_ptr_1( dst_dib
, dst_start
->x
, dst_start
->y
);
4385 BYTE
*src_ptr
= get_pixel_ptr_1( src_dib
, src_start
->x
, src_start
->y
);
4386 int err
= params
->err_start
;
4387 int width
, dst_x
= dst_start
->x
, src_x
= src_start
->x
;
4388 struct rop_codes codes
;
4391 rop_codes_from_stretch_mode( mode
, &codes
);
4392 for (width
= params
->length
; width
; width
--)
4394 src_val
= *src_ptr
& pixel_masks_1
[src_x
% 8] ? 0xff : 0;
4395 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, pixel_masks_1
[dst_x
% 8] );
4397 if ((dst_x
& ~7) != ((dst_x
+ params
->dst_inc
) & ~7))
4398 dst_ptr
+= params
->dst_inc
;
4399 dst_x
+= params
->dst_inc
;
4403 if ((src_x
& ~7) != ((src_x
+ params
->src_inc
) & ~7))
4404 src_ptr
+= params
->src_inc
;
4405 src_x
+= params
->src_inc
;
4406 err
+= params
->err_add_1
;
4408 else err
+= params
->err_add_2
;
4412 static void stretch_row_null(const dib_info
*dst_dib
, const POINT
*dst_start
,
4413 const dib_info
*src_dib
, const POINT
*src_start
,
4414 const struct stretch_params
*params
, int mode
,
4417 FIXME("bit count %d\n", dst_dib
->bit_count
);
4421 static void shrink_row_32(const dib_info
*dst_dib
, const POINT
*dst_start
,
4422 const dib_info
*src_dib
, const POINT
*src_start
,
4423 const struct stretch_params
*params
, int mode
,
4426 DWORD
*dst_ptr
= get_pixel_ptr_32( dst_dib
, dst_start
->x
, dst_start
->y
);
4427 DWORD
*src_ptr
= get_pixel_ptr_32( src_dib
, src_start
->x
, src_start
->y
);
4428 int err
= params
->err_start
;
4430 struct rop_codes codes
;
4431 DWORD init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
4432 BOOL new_pix
= TRUE
;
4434 rop_codes_from_stretch_mode( mode
, &codes
);
4435 for (width
= params
->length
; width
; width
--)
4437 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
4438 do_rop_codes_32( dst_ptr
, *src_ptr
, &codes
);
4440 src_ptr
+= params
->src_inc
;
4443 dst_ptr
+= params
->dst_inc
;
4445 err
+= params
->err_add_1
;
4447 else err
+= params
->err_add_2
;
4451 static void shrink_row_24(const dib_info
*dst_dib
, const POINT
*dst_start
,
4452 const dib_info
*src_dib
, const POINT
*src_start
,
4453 const struct stretch_params
*params
, int mode
,
4456 BYTE
*dst_ptr
= get_pixel_ptr_24( dst_dib
, dst_start
->x
, dst_start
->y
);
4457 BYTE
*src_ptr
= get_pixel_ptr_24( src_dib
, src_start
->x
, src_start
->y
);
4458 int err
= params
->err_start
;
4460 struct rop_codes codes
;
4461 BYTE init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
4462 BOOL new_pix
= TRUE
;
4464 rop_codes_from_stretch_mode( mode
, &codes
);
4465 for (width
= params
->length
; width
; width
--)
4467 if (new_pix
&& !keep_dst
) memset( dst_ptr
, init_val
, 3 );
4468 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
4469 do_rop_codes_8( dst_ptr
+ 1, *(src_ptr
+ 1), &codes
);
4470 do_rop_codes_8( dst_ptr
+ 2, *(src_ptr
+ 2), &codes
);
4472 src_ptr
+= 3 * params
->src_inc
;
4475 dst_ptr
+= 3 * params
->dst_inc
;
4477 err
+= params
->err_add_1
;
4479 else err
+= params
->err_add_2
;
4483 static void shrink_row_16(const dib_info
*dst_dib
, const POINT
*dst_start
,
4484 const dib_info
*src_dib
, const POINT
*src_start
,
4485 const struct stretch_params
*params
, int mode
,
4488 WORD
*dst_ptr
= get_pixel_ptr_16( dst_dib
, dst_start
->x
, dst_start
->y
);
4489 WORD
*src_ptr
= get_pixel_ptr_16( src_dib
, src_start
->x
, src_start
->y
);
4490 int err
= params
->err_start
;
4492 struct rop_codes codes
;
4493 WORD init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
4494 BOOL new_pix
= TRUE
;
4496 rop_codes_from_stretch_mode( mode
, &codes
);
4497 for (width
= params
->length
; width
; width
--)
4499 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
4500 do_rop_codes_16( dst_ptr
, *src_ptr
, &codes
);
4502 src_ptr
+= params
->src_inc
;
4505 dst_ptr
+= params
->dst_inc
;
4507 err
+= params
->err_add_1
;
4509 else err
+= params
->err_add_2
;
4513 static void shrink_row_8(const dib_info
*dst_dib
, const POINT
*dst_start
,
4514 const dib_info
*src_dib
, const POINT
*src_start
,
4515 const struct stretch_params
*params
, int mode
,
4518 BYTE
*dst_ptr
= get_pixel_ptr_8( dst_dib
, dst_start
->x
, dst_start
->y
);
4519 BYTE
*src_ptr
= get_pixel_ptr_8( src_dib
, src_start
->x
, src_start
->y
);
4520 int err
= params
->err_start
;
4522 struct rop_codes codes
;
4523 BYTE init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
4524 BOOL new_pix
= TRUE
;
4526 rop_codes_from_stretch_mode( mode
, &codes
);
4527 for (width
= params
->length
; width
; width
--)
4529 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
4530 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
4532 src_ptr
+= params
->src_inc
;
4535 dst_ptr
+= params
->dst_inc
;
4537 err
+= params
->err_add_1
;
4539 else err
+= params
->err_add_2
;
4543 static void shrink_row_4(const dib_info
*dst_dib
, const POINT
*dst_start
,
4544 const dib_info
*src_dib
, const POINT
*src_start
,
4545 const struct stretch_params
*params
, int mode
,
4548 BYTE
*dst_ptr
= get_pixel_ptr_8( dst_dib
, dst_start
->x
, dst_start
->y
);
4549 BYTE
*src_ptr
= get_pixel_ptr_8( src_dib
, src_start
->x
, src_start
->y
);
4550 int err
= params
->err_start
;
4551 int width
, dst_x
= dst_start
->x
, src_x
= src_start
->x
;
4552 struct rop_codes codes
;
4553 BYTE src_val
, init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
4554 BOOL new_pix
= TRUE
;
4556 rop_codes_from_stretch_mode( mode
, &codes
);
4557 for (width
= params
->length
; width
; width
--)
4559 if (new_pix
&& !keep_dst
) do_rop_mask_8( dst_ptr
, 0, init_val
, (dst_x
& 1) ? 0xf0 : 0x0f );
4561 if (src_x
& 1) src_val
= (*src_ptr
& 0x0f) | (*src_ptr
<< 4);
4562 else src_val
= (*src_ptr
& 0xf0) | (*src_ptr
>> 4);
4564 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, (dst_x
& 1) ? 0xf0 : 0x0f );
4567 if ((src_x
& ~1) != ((src_x
+ params
->src_inc
) & ~1))
4568 src_ptr
+= params
->src_inc
;
4569 src_x
+= params
->src_inc
;
4573 if ((dst_x
& ~1) != ((dst_x
+ params
->dst_inc
) & ~1))
4574 dst_ptr
+= params
->dst_inc
;
4575 dst_x
+= params
->dst_inc
;
4577 err
+= params
->err_add_1
;
4579 else err
+= params
->err_add_2
;
4583 static void shrink_row_1(const dib_info
*dst_dib
, const POINT
*dst_start
,
4584 const dib_info
*src_dib
, const POINT
*src_start
,
4585 const struct stretch_params
*params
, int mode
,
4588 BYTE
*dst_ptr
= get_pixel_ptr_1( dst_dib
, dst_start
->x
, dst_start
->y
);
4589 BYTE
*src_ptr
= get_pixel_ptr_1( src_dib
, src_start
->x
, src_start
->y
);
4590 int err
= params
->err_start
;
4591 int width
, dst_x
= dst_start
->x
, src_x
= src_start
->x
;
4592 struct rop_codes codes
;
4593 BYTE src_val
, init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
4594 BOOL new_pix
= TRUE
;
4596 rop_codes_from_stretch_mode( mode
, &codes
);
4597 for (width
= params
->length
; width
; width
--)
4599 if (new_pix
&& !keep_dst
) do_rop_mask_8( dst_ptr
, 0, init_val
, pixel_masks_1
[dst_x
% 8] );
4600 src_val
= *src_ptr
& pixel_masks_1
[src_x
% 8] ? 0xff : 0;
4601 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, pixel_masks_1
[dst_x
% 8] );
4604 if ((src_x
& ~7) != ((src_x
+ params
->src_inc
) & ~7))
4605 src_ptr
+= params
->src_inc
;
4606 src_x
+= params
->src_inc
;
4610 if ((dst_x
& ~7) != ((dst_x
+ params
->dst_inc
) & ~7))
4611 dst_ptr
+= params
->dst_inc
;
4612 dst_x
+= params
->dst_inc
;
4614 err
+= params
->err_add_1
;
4616 else err
+= params
->err_add_2
;
4620 static void shrink_row_null(const dib_info
*dst_dib
, const POINT
*dst_start
,
4621 const dib_info
*src_dib
, const POINT
*src_start
,
4622 const struct stretch_params
*params
, int mode
,
4625 FIXME("bit count %d\n", dst_dib
->bit_count
);
4629 const primitive_funcs funcs_8888
=
4637 colorref_to_pixel_888
,
4638 pixel_to_colorref_888
,
4640 create_rop_masks_32
,
4645 const primitive_funcs funcs_32
=
4653 colorref_to_pixel_masks
,
4654 pixel_to_colorref_masks
,
4656 create_rop_masks_32
,
4661 const primitive_funcs funcs_24
=
4669 colorref_to_pixel_888
,
4670 pixel_to_colorref_888
,
4672 create_rop_masks_24
,
4677 const primitive_funcs funcs_555
=
4685 colorref_to_pixel_555
,
4686 pixel_to_colorref_555
,
4688 create_rop_masks_16
,
4693 const primitive_funcs funcs_16
=
4701 colorref_to_pixel_masks
,
4702 pixel_to_colorref_masks
,
4704 create_rop_masks_16
,
4709 const primitive_funcs funcs_8
=
4717 colorref_to_pixel_colortable
,
4718 pixel_to_colorref_colortable
,
4725 const primitive_funcs funcs_4
=
4733 colorref_to_pixel_colortable
,
4734 pixel_to_colorref_colortable
,
4741 const primitive_funcs funcs_1
=
4749 colorref_to_pixel_colortable
,
4750 pixel_to_colorref_colortable
,
4757 const primitive_funcs funcs_null
=
4765 colorref_to_pixel_null
,
4766 pixel_to_colorref_null
,
4768 create_rop_masks_null
,