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
colorref_to_pixel_888(const dib_info
*dib
, COLORREF color
)
1030 return ( ((color
>> 16) & 0xff) | (color
& 0xff00) | ((color
<< 16) & 0xff0000) );
1033 static const DWORD field_masks
[33] =
1035 0x00, /* should never happen */
1036 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff,
1037 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1038 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1039 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1042 static inline DWORD
get_field(DWORD field
, int shift
, int len
)
1044 shift
= shift
- (8 - len
);
1049 field
&= field_masks
[len
];
1050 field
|= field
>> len
;
1054 static inline DWORD
put_field(DWORD field
, int shift
, int len
)
1056 shift
= shift
- (8 - len
);
1057 field
&= field_masks
[len
];
1065 static DWORD
colorref_to_pixel_masks(const dib_info
*dib
, COLORREF colour
)
1069 r
= GetRValue(colour
);
1070 g
= GetGValue(colour
);
1071 b
= GetBValue(colour
);
1073 return put_field(r
, dib
->red_shift
, dib
->red_len
) |
1074 put_field(g
, dib
->green_shift
, dib
->green_len
) |
1075 put_field(b
, dib
->blue_shift
, dib
->blue_len
);
1078 static DWORD
colorref_to_pixel_555(const dib_info
*dib
, COLORREF color
)
1080 return ( ((color
>> 19) & 0x1f) | ((color
>> 6) & 0x03e0) | ((color
<< 7) & 0x7c00) );
1083 static DWORD
rgb_to_pixel_colortable(const dib_info
*dib
, BYTE r
, BYTE g
, BYTE b
)
1085 int i
, best_index
= 0;
1086 DWORD diff
, best_diff
= 0xffffffff;
1088 /* special case for conversion to 1-bpp without a color table:
1089 * we get a 1-entry table containing the background color
1091 if (dib
->bit_count
== 1 && dib
->color_table_size
== 1)
1092 return (r
== dib
->color_table
[0].rgbRed
&&
1093 g
== dib
->color_table
[0].rgbGreen
&&
1094 b
== dib
->color_table
[0].rgbBlue
);
1096 for(i
= 0; i
< dib
->color_table_size
; i
++)
1098 RGBQUAD
*cur
= dib
->color_table
+ i
;
1099 diff
= (r
- cur
->rgbRed
) * (r
- cur
->rgbRed
)
1100 + (g
- cur
->rgbGreen
) * (g
- cur
->rgbGreen
)
1101 + (b
- cur
->rgbBlue
) * (b
- cur
->rgbBlue
);
1109 if(diff
< best_diff
)
1118 static DWORD
colorref_to_pixel_colortable(const dib_info
*dib
, COLORREF color
)
1120 return rgb_to_pixel_colortable( dib
, GetRValue(color
), GetGValue(color
), GetBValue(color
) );
1123 static DWORD
colorref_to_pixel_null(const dib_info
*dib
, COLORREF color
)
1128 static inline RGBQUAD
colortable_entry(const dib_info
*dib
, DWORD index
)
1130 static const RGBQUAD default_rgb
;
1131 if (index
< dib
->color_table_size
) return dib
->color_table
[index
];
1135 static inline BOOL
bit_fields_match(const dib_info
*d1
, const dib_info
*d2
)
1137 assert( d1
->bit_count
> 8 && d1
->bit_count
== d2
->bit_count
);
1139 return d1
->red_mask
== d2
->red_mask
&&
1140 d1
->green_mask
== d2
->green_mask
&&
1141 d1
->blue_mask
== d2
->blue_mask
;
1144 static void convert_to_8888(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
1146 DWORD
*dst_start
= get_pixel_ptr_32(dst
, 0, 0), *dst_pixel
, src_val
;
1147 int x
, y
, pad_size
= (dst
->width
- (src_rect
->right
- src_rect
->left
)) * 4;
1149 switch(src
->bit_count
)
1153 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1154 if(src
->funcs
== &funcs_8888
)
1156 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
1157 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
1160 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1162 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 4);
1163 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
1164 dst_start
+= dst
->stride
/ 4;
1165 src_start
+= src
->stride
/ 4;
1169 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
1171 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1173 dst_pixel
= dst_start
;
1174 src_pixel
= src_start
;
1175 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1177 src_val
= *src_pixel
++;
1178 *dst_pixel
++ = (((src_val
>> src
->red_shift
) & 0xff) << 16) |
1179 (((src_val
>> src
->green_shift
) & 0xff) << 8) |
1180 ((src_val
>> src
->blue_shift
) & 0xff);
1182 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1183 dst_start
+= dst
->stride
/ 4;
1184 src_start
+= src
->stride
/ 4;
1189 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1191 dst_pixel
= dst_start
;
1192 src_pixel
= src_start
;
1193 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1195 src_val
= *src_pixel
++;
1196 *dst_pixel
++ = (get_field( src_val
, src
->red_shift
, src
->red_len
) << 16 |
1197 get_field( src_val
, src
->green_shift
, src
->green_len
) << 8 |
1198 get_field( src_val
, src
->blue_shift
, src
->blue_len
));
1200 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1201 dst_start
+= dst
->stride
/ 4;
1202 src_start
+= src
->stride
/ 4;
1210 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1212 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1214 dst_pixel
= dst_start
;
1215 src_pixel
= src_start
;
1216 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1219 rgb
.rgbBlue
= *src_pixel
++;
1220 rgb
.rgbGreen
= *src_pixel
++;
1221 rgb
.rgbRed
= *src_pixel
++;
1223 *dst_pixel
++ = ((rgb
.rgbRed
<< 16) & 0xff0000) | ((rgb
.rgbGreen
<< 8) & 0x00ff00) | (rgb
.rgbBlue
& 0x0000ff);
1225 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1226 dst_start
+= dst
->stride
/ 4;
1227 src_start
+= src
->stride
;
1234 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1235 if(src
->funcs
== &funcs_555
)
1237 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1239 dst_pixel
= dst_start
;
1240 src_pixel
= src_start
;
1241 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1243 src_val
= *src_pixel
++;
1244 *dst_pixel
++ = ((src_val
<< 9) & 0xf80000) | ((src_val
<< 4) & 0x070000) |
1245 ((src_val
<< 6) & 0x00f800) | ((src_val
<< 1) & 0x000700) |
1246 ((src_val
<< 3) & 0x0000f8) | ((src_val
>> 2) & 0x000007);
1248 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1249 dst_start
+= dst
->stride
/ 4;
1250 src_start
+= src
->stride
/ 2;
1253 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
1255 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1257 dst_pixel
= dst_start
;
1258 src_pixel
= src_start
;
1259 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1261 src_val
= *src_pixel
++;
1262 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 19) & 0xf80000) |
1263 (((src_val
>> src
->red_shift
) << 14) & 0x070000) |
1264 (((src_val
>> src
->green_shift
) << 11) & 0x00f800) |
1265 (((src_val
>> src
->green_shift
) << 6) & 0x000700) |
1266 (((src_val
>> src
->blue_shift
) << 3) & 0x0000f8) |
1267 (((src_val
>> src
->blue_shift
) >> 2) & 0x000007);
1269 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1270 dst_start
+= dst
->stride
/ 4;
1271 src_start
+= src
->stride
/ 2;
1274 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
1276 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1278 dst_pixel
= dst_start
;
1279 src_pixel
= src_start
;
1280 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1282 src_val
= *src_pixel
++;
1283 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 19) & 0xf80000) |
1284 (((src_val
>> src
->red_shift
) << 14) & 0x070000) |
1285 (((src_val
>> src
->green_shift
) << 10) & 0x00fc00) |
1286 (((src_val
>> src
->green_shift
) << 4) & 0x000300) |
1287 (((src_val
>> src
->blue_shift
) << 3) & 0x0000f8) |
1288 (((src_val
>> src
->blue_shift
) >> 2) & 0x000007);
1290 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1291 dst_start
+= dst
->stride
/ 4;
1292 src_start
+= src
->stride
/ 2;
1297 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1299 dst_pixel
= dst_start
;
1300 src_pixel
= src_start
;
1301 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1303 src_val
= *src_pixel
++;
1304 *dst_pixel
++ = (get_field( src_val
, src
->red_shift
, src
->red_len
) << 16 |
1305 get_field( src_val
, src
->green_shift
, src
->green_len
) << 8 |
1306 get_field( src_val
, src
->blue_shift
, src
->blue_len
));
1308 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1309 dst_start
+= dst
->stride
/ 4;
1310 src_start
+= src
->stride
/ 2;
1318 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1319 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1321 dst_pixel
= dst_start
;
1322 src_pixel
= src_start
;
1323 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1325 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
1326 *dst_pixel
++ = rgb
.rgbRed
<< 16 | rgb
.rgbGreen
<< 8 | rgb
.rgbBlue
;
1328 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1329 dst_start
+= dst
->stride
/ 4;
1330 src_start
+= src
->stride
;
1337 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1338 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1340 dst_pixel
= dst_start
;
1341 src_pixel
= src_start
;
1342 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1346 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
1348 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
1349 *dst_pixel
++ = rgb
.rgbRed
<< 16 | rgb
.rgbGreen
<< 8 | rgb
.rgbBlue
;
1351 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1352 dst_start
+= dst
->stride
/ 4;
1353 src_start
+= src
->stride
;
1360 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1361 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1363 dst_pixel
= dst_start
;
1364 src_pixel
= src_start
;
1365 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1368 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
1369 if((x
% 8) == 7) src_pixel
++;
1370 rgb
= src
->color_table
[src_val
];
1371 *dst_pixel
++ = rgb
.rgbRed
<< 16 | rgb
.rgbGreen
<< 8 | rgb
.rgbBlue
;
1373 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1374 dst_start
+= dst
->stride
/ 4;
1375 src_start
+= src
->stride
;
1382 static void convert_to_32(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
1384 DWORD
*dst_start
= get_pixel_ptr_32(dst
, 0, 0), *dst_pixel
, src_val
;
1385 int x
, y
, pad_size
= (dst
->width
- (src_rect
->right
- src_rect
->left
)) * 4;
1387 switch(src
->bit_count
)
1391 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1393 if(src
->funcs
== &funcs_8888
)
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 src_val
= *src_pixel
++;
1402 *dst_pixel
++ = put_field(src_val
>> 16, dst
->red_shift
, dst
->red_len
) |
1403 put_field(src_val
>> 8, dst
->green_shift
, dst
->green_len
) |
1404 put_field(src_val
, dst
->blue_shift
, dst
->blue_len
);
1406 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1407 dst_start
+= dst
->stride
/ 4;
1408 src_start
+= src
->stride
/ 4;
1411 else if(bit_fields_match(src
, dst
))
1413 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
1414 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
1417 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1419 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 4);
1420 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
1421 dst_start
+= dst
->stride
/ 4;
1422 src_start
+= src
->stride
/ 4;
1426 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8 &&
1427 dst
->red_len
== 8 && dst
->green_len
== 8 && dst
->blue_len
== 8)
1429 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1431 dst_pixel
= dst_start
;
1432 src_pixel
= src_start
;
1433 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1435 src_val
= *src_pixel
++;
1436 *dst_pixel
++ = (((src_val
>> src
->red_shift
) & 0xff) << dst
->red_shift
) |
1437 (((src_val
>> src
->green_shift
) & 0xff) << dst
->green_shift
) |
1438 (((src_val
>> src
->blue_shift
) & 0xff) << dst
->blue_shift
);
1440 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1441 dst_start
+= dst
->stride
/ 4;
1442 src_start
+= src
->stride
/ 4;
1447 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1449 dst_pixel
= dst_start
;
1450 src_pixel
= src_start
;
1451 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1453 src_val
= *src_pixel
++;
1454 *dst_pixel
++ = put_field(get_field(src_val
, src
->red_shift
, src
->red_len
), dst
->red_shift
, dst
->red_len
) |
1455 put_field(get_field(src_val
, src
->green_shift
, src
->green_len
), dst
->green_shift
, dst
->green_len
) |
1456 put_field(get_field(src_val
, src
->blue_shift
, src
->blue_len
), dst
->blue_shift
, dst
->blue_len
);
1458 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1459 dst_start
+= dst
->stride
/ 4;
1460 src_start
+= src
->stride
/ 4;
1468 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1470 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1472 dst_pixel
= dst_start
;
1473 src_pixel
= src_start
;
1474 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1477 rgb
.rgbBlue
= *src_pixel
++;
1478 rgb
.rgbGreen
= *src_pixel
++;
1479 rgb
.rgbRed
= *src_pixel
++;
1481 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
1482 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
1483 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
1485 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1486 dst_start
+= dst
->stride
/ 4;
1487 src_start
+= src
->stride
;
1494 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1495 if(src
->funcs
== &funcs_555
)
1497 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1499 dst_pixel
= dst_start
;
1500 src_pixel
= src_start
;
1501 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1503 src_val
= *src_pixel
++;
1504 *dst_pixel
++ = put_field(((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07), dst
->red_shift
, dst
->red_len
) |
1505 put_field(((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07), dst
->green_shift
, dst
->green_len
) |
1506 put_field(((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
1508 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1509 dst_start
+= dst
->stride
/ 4;
1510 src_start
+= src
->stride
/ 2;
1513 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
1515 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1517 dst_pixel
= dst_start
;
1518 src_pixel
= src_start
;
1519 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1521 src_val
= *src_pixel
++;
1522 *dst_pixel
++ = put_field( (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
1523 (((src_val
>> src
->red_shift
) >> 2) & 0x07), dst
->red_shift
, dst
->red_len
) |
1524 put_field( (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
1525 (((src_val
>> src
->green_shift
) >> 2) & 0x07), dst
->green_shift
, dst
->green_len
) |
1526 put_field( (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
1527 (((src_val
>> src
->blue_shift
) >> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
1529 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1530 dst_start
+= dst
->stride
/ 4;
1531 src_start
+= src
->stride
/ 2;
1534 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
1536 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1538 dst_pixel
= dst_start
;
1539 src_pixel
= src_start
;
1540 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1542 src_val
= *src_pixel
++;
1543 *dst_pixel
++ = put_field( (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
1544 (((src_val
>> src
->red_shift
) >> 2) & 0x07), dst
->red_shift
, dst
->red_len
) |
1545 put_field( (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
1546 (((src_val
>> src
->green_shift
) >> 4) & 0x03), dst
->green_shift
, dst
->green_len
) |
1547 put_field( (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
1548 (((src_val
>> src
->blue_shift
) >> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
1550 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1551 dst_start
+= dst
->stride
/ 4;
1552 src_start
+= src
->stride
/ 2;
1557 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1559 dst_pixel
= dst_start
;
1560 src_pixel
= src_start
;
1561 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1563 src_val
= *src_pixel
++;
1564 *dst_pixel
++ = put_field(get_field(src_val
, src
->red_shift
, src
->red_len
), dst
->red_shift
, dst
->red_len
) |
1565 put_field(get_field(src_val
, src
->green_shift
, src
->green_len
), dst
->green_shift
, dst
->green_len
) |
1566 put_field(get_field(src_val
, src
->blue_shift
, src
->blue_len
), dst
->blue_shift
, dst
->blue_len
);
1568 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1569 dst_start
+= dst
->stride
/ 4;
1570 src_start
+= src
->stride
/ 2;
1578 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1579 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1581 dst_pixel
= dst_start
;
1582 src_pixel
= src_start
;
1583 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1585 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
1586 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
1587 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
1588 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
1590 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1591 dst_start
+= dst
->stride
/ 4;
1592 src_start
+= src
->stride
;
1599 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1600 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1602 dst_pixel
= dst_start
;
1603 src_pixel
= src_start
;
1604 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1608 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
1610 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
1611 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
1612 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
1613 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
1615 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1616 dst_start
+= dst
->stride
/ 4;
1617 src_start
+= src
->stride
;
1624 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1625 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1627 dst_pixel
= dst_start
;
1628 src_pixel
= src_start
;
1629 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1632 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
1633 if((x
% 8) == 7) src_pixel
++;
1634 rgb
= src
->color_table
[src_val
];
1635 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
1636 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
1637 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
1639 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1640 dst_start
+= dst
->stride
/ 4;
1641 src_start
+= src
->stride
;
1648 static void convert_to_24(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
1650 BYTE
*dst_start
= get_pixel_ptr_24(dst
, 0, 0), *dst_pixel
;
1652 int x
, y
, pad_size
= ((dst
->width
* 3 + 3) & ~3) - (src_rect
->right
- src_rect
->left
) * 3;
1654 switch(src
->bit_count
)
1658 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1659 if(src
->funcs
== &funcs_8888
)
1661 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1663 dst_pixel
= dst_start
;
1664 src_pixel
= src_start
;
1665 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1667 src_val
= *src_pixel
++;
1668 *dst_pixel
++ = src_val
& 0xff;
1669 *dst_pixel
++ = (src_val
>> 8) & 0xff;
1670 *dst_pixel
++ = (src_val
>> 16) & 0xff;
1672 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1673 dst_start
+= dst
->stride
;
1674 src_start
+= src
->stride
/ 4;
1677 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
1679 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1681 dst_pixel
= dst_start
;
1682 src_pixel
= src_start
;
1683 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1685 src_val
= *src_pixel
++;
1686 *dst_pixel
++ = (src_val
>> src
->blue_shift
) & 0xff;
1687 *dst_pixel
++ = (src_val
>> src
->green_shift
) & 0xff;
1688 *dst_pixel
++ = (src_val
>> src
->red_shift
) & 0xff;
1690 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1691 dst_start
+= dst
->stride
;
1692 src_start
+= src
->stride
/ 4;
1697 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1699 dst_pixel
= dst_start
;
1700 src_pixel
= src_start
;
1701 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1703 src_val
= *src_pixel
++;
1704 *dst_pixel
++ = get_field( src_val
, src
->blue_shift
, src
->blue_len
);
1705 *dst_pixel
++ = get_field( src_val
, src
->green_shift
, src
->green_len
);
1706 *dst_pixel
++ = get_field( src_val
, src
->red_shift
, src
->red_len
);
1708 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1709 dst_start
+= dst
->stride
;
1710 src_start
+= src
->stride
/ 4;
1718 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
);
1720 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
1721 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
1724 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1726 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 3);
1727 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
) * 3, 0, pad_size
);
1728 dst_start
+= dst
->stride
;
1729 src_start
+= src
->stride
;
1737 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1738 if(src
->funcs
== &funcs_555
)
1740 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1742 dst_pixel
= dst_start
;
1743 src_pixel
= src_start
;
1744 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1746 src_val
= *src_pixel
++;
1747 *dst_pixel
++ = ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07);
1748 *dst_pixel
++ = ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07);
1749 *dst_pixel
++ = ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07);
1751 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1752 dst_start
+= dst
->stride
;
1753 src_start
+= src
->stride
/ 2;
1756 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
1758 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1760 dst_pixel
= dst_start
;
1761 src_pixel
= src_start
;
1762 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1764 src_val
= *src_pixel
++;
1765 *dst_pixel
++ = (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
1766 (((src_val
>> src
->blue_shift
) >> 2) & 0x07);
1767 *dst_pixel
++ = (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
1768 (((src_val
>> src
->green_shift
) >> 2) & 0x07);
1769 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
1770 (((src_val
>> src
->red_shift
) >> 2) & 0x07);
1772 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1773 dst_start
+= dst
->stride
;
1774 src_start
+= src
->stride
/ 2;
1777 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
1779 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1781 dst_pixel
= dst_start
;
1782 src_pixel
= src_start
;
1783 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1785 src_val
= *src_pixel
++;
1786 *dst_pixel
++ = (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
1787 (((src_val
>> src
->blue_shift
) >> 2) & 0x07);
1788 *dst_pixel
++ = (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
1789 (((src_val
>> src
->green_shift
) >> 4) & 0x03);
1790 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
1791 (((src_val
>> src
->red_shift
) >> 2) & 0x07);
1793 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1794 dst_start
+= dst
->stride
;
1795 src_start
+= src
->stride
/ 2;
1800 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1802 dst_pixel
= dst_start
;
1803 src_pixel
= src_start
;
1804 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1806 src_val
= *src_pixel
++;
1807 *dst_pixel
++ = get_field(src_val
, src
->blue_shift
, src
->blue_len
);
1808 *dst_pixel
++ = get_field(src_val
, src
->green_shift
, src
->green_len
);
1809 *dst_pixel
++ = get_field(src_val
, src
->red_shift
, src
->red_len
);
1811 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1812 dst_start
+= dst
->stride
;
1813 src_start
+= src
->stride
/ 2;
1821 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1822 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1824 dst_pixel
= dst_start
;
1825 src_pixel
= src_start
;
1826 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1828 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
1829 *dst_pixel
++ = rgb
.rgbBlue
;
1830 *dst_pixel
++ = rgb
.rgbGreen
;
1831 *dst_pixel
++ = rgb
.rgbRed
;
1833 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1834 dst_start
+= dst
->stride
;
1835 src_start
+= src
->stride
;
1842 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1843 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1845 dst_pixel
= dst_start
;
1846 src_pixel
= src_start
;
1847 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1851 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
1853 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
1854 *dst_pixel
++ = rgb
.rgbBlue
;
1855 *dst_pixel
++ = rgb
.rgbGreen
;
1856 *dst_pixel
++ = rgb
.rgbRed
;
1858 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1859 dst_start
+= dst
->stride
;
1860 src_start
+= src
->stride
;
1867 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1868 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1870 dst_pixel
= dst_start
;
1871 src_pixel
= src_start
;
1872 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1875 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
1876 if((x
% 8) == 7) src_pixel
++;
1877 rgb
= src
->color_table
[src_val
];
1878 *dst_pixel
++ = rgb
.rgbBlue
;
1879 *dst_pixel
++ = rgb
.rgbGreen
;
1880 *dst_pixel
++ = rgb
.rgbRed
;
1882 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1883 dst_start
+= dst
->stride
;
1884 src_start
+= src
->stride
;
1891 static void convert_to_555(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
1893 WORD
*dst_start
= get_pixel_ptr_16(dst
, 0, 0), *dst_pixel
;
1894 INT x
, y
, pad_size
= ((dst
->width
+ 1) & ~1) * 2 - (src_rect
->right
- src_rect
->left
) * 2;
1897 switch(src
->bit_count
)
1901 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1903 if(src
->funcs
== &funcs_8888
)
1905 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1907 dst_pixel
= dst_start
;
1908 src_pixel
= src_start
;
1909 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1911 src_val
= *src_pixel
++;
1912 *dst_pixel
++ = ((src_val
>> 9) & 0x7c00) |
1913 ((src_val
>> 6) & 0x03e0) |
1914 ((src_val
>> 3) & 0x001f);
1916 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1917 dst_start
+= dst
->stride
/ 2;
1918 src_start
+= src
->stride
/ 4;
1921 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
1923 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1925 dst_pixel
= dst_start
;
1926 src_pixel
= src_start
;
1927 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1929 src_val
= *src_pixel
++;
1930 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 7) & 0x7c00) |
1931 (((src_val
>> src
->green_shift
) << 2) & 0x03e0) |
1932 (((src_val
>> src
->blue_shift
) >> 3) & 0x001f);
1934 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1935 dst_start
+= dst
->stride
/ 2;
1936 src_start
+= src
->stride
/ 4;
1941 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1943 dst_pixel
= dst_start
;
1944 src_pixel
= src_start
;
1945 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1947 src_val
= *src_pixel
++;
1948 *dst_pixel
++ = (((get_field(src_val
, src
->red_shift
, src
->red_len
) << 7) & 0x7c00) |
1949 ((get_field(src_val
, src
->green_shift
, src
->green_len
) << 2) & 0x03e0) |
1950 ( get_field(src_val
, src
->blue_shift
, src
->blue_len
) >> 3));
1952 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1953 dst_start
+= dst
->stride
/ 2;
1954 src_start
+= src
->stride
/ 4;
1962 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1964 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1966 dst_pixel
= dst_start
;
1967 src_pixel
= src_start
;
1968 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1971 rgb
.rgbBlue
= *src_pixel
++;
1972 rgb
.rgbGreen
= *src_pixel
++;
1973 rgb
.rgbRed
= *src_pixel
++;
1975 *dst_pixel
++ = ((rgb
.rgbRed
<< 7) & 0x7c00) |
1976 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
1977 ((rgb
.rgbBlue
>> 3) & 0x001f);
1979 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1980 dst_start
+= dst
->stride
/ 2;
1981 src_start
+= src
->stride
;
1988 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1989 if(src
->funcs
== &funcs_555
)
1991 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
1992 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
1995 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1997 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 2);
1998 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
1999 dst_start
+= dst
->stride
/ 2;
2000 src_start
+= src
->stride
/ 2;
2004 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2006 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2008 dst_pixel
= dst_start
;
2009 src_pixel
= src_start
;
2010 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2012 src_val
= *src_pixel
++;
2013 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 10) & 0x7c00) |
2014 (((src_val
>> src
->green_shift
) << 5) & 0x03e0) |
2015 ( (src_val
>> src
->blue_shift
) & 0x001f);
2017 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2018 dst_start
+= dst
->stride
/ 2;
2019 src_start
+= src
->stride
/ 2;
2022 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2024 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2026 dst_pixel
= dst_start
;
2027 src_pixel
= src_start
;
2028 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2030 src_val
= *src_pixel
++;
2031 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 10) & 0x7c00) |
2032 (((src_val
>> src
->green_shift
) << 4) & 0x03e0) |
2033 ( (src_val
>> src
->blue_shift
) & 0x001f);
2035 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2036 dst_start
+= dst
->stride
/ 2;
2037 src_start
+= src
->stride
/ 2;
2042 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2044 dst_pixel
= dst_start
;
2045 src_pixel
= src_start
;
2046 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2048 src_val
= *src_pixel
++;
2049 *dst_pixel
++ = (((get_field(src_val
, src
->red_shift
, src
->red_len
) << 7) & 0x7c00) |
2050 ((get_field(src_val
, src
->green_shift
, src
->green_len
) << 2) & 0x03e0) |
2051 ( get_field(src_val
, src
->blue_shift
, src
->blue_len
) >> 3));
2053 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2054 dst_start
+= dst
->stride
/ 2;
2055 src_start
+= src
->stride
/ 2;
2063 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2064 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2066 dst_pixel
= dst_start
;
2067 src_pixel
= src_start
;
2068 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2070 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
2071 *dst_pixel
++ = ((rgb
.rgbRed
<< 7) & 0x7c00) |
2072 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
2073 ((rgb
.rgbBlue
>> 3) & 0x001f);
2075 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2076 dst_start
+= dst
->stride
/ 2;
2077 src_start
+= src
->stride
;
2084 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2085 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2087 dst_pixel
= dst_start
;
2088 src_pixel
= src_start
;
2089 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2093 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
2095 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
2096 *dst_pixel
++ = ((rgb
.rgbRed
<< 7) & 0x7c00) |
2097 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
2098 ((rgb
.rgbBlue
>> 3) & 0x001f);
2100 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2101 dst_start
+= dst
->stride
/ 2;
2102 src_start
+= src
->stride
;
2109 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2110 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2112 dst_pixel
= dst_start
;
2113 src_pixel
= src_start
;
2114 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2117 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
2118 if((x
% 8) == 7) src_pixel
++;
2119 rgb
= src
->color_table
[src_val
];
2120 *dst_pixel
++ = ((rgb
.rgbRed
<< 7) & 0x7c00) |
2121 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
2122 ((rgb
.rgbBlue
>> 3) & 0x001f);
2124 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2125 dst_start
+= dst
->stride
/ 2;
2126 src_start
+= src
->stride
;
2133 static void convert_to_16(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
2135 WORD
*dst_start
= get_pixel_ptr_16(dst
, 0, 0), *dst_pixel
;
2136 INT x
, y
, pad_size
= ((dst
->width
+ 1) & ~1) * 2 - (src_rect
->right
- src_rect
->left
) * 2;
2139 switch(src
->bit_count
)
2143 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2145 if(src
->funcs
== &funcs_8888
)
2147 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2149 dst_pixel
= dst_start
;
2150 src_pixel
= src_start
;
2151 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2153 src_val
= *src_pixel
++;
2154 *dst_pixel
++ = put_field(src_val
>> 16, dst
->red_shift
, dst
->red_len
) |
2155 put_field(src_val
>> 8, dst
->green_shift
, dst
->green_len
) |
2156 put_field(src_val
, dst
->blue_shift
, dst
->blue_len
);
2158 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2159 dst_start
+= dst
->stride
/ 2;
2160 src_start
+= src
->stride
/ 4;
2163 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
2165 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2167 dst_pixel
= dst_start
;
2168 src_pixel
= src_start
;
2169 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2171 src_val
= *src_pixel
++;
2172 *dst_pixel
++ = put_field(src_val
>> src
->red_shift
, dst
->red_shift
, dst
->red_len
) |
2173 put_field(src_val
>> src
->green_shift
, dst
->green_shift
, dst
->green_len
) |
2174 put_field(src_val
>> src
->blue_shift
, dst
->blue_shift
, dst
->blue_len
);
2176 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2177 dst_start
+= dst
->stride
/ 2;
2178 src_start
+= src
->stride
/ 4;
2183 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2185 dst_pixel
= dst_start
;
2186 src_pixel
= src_start
;
2187 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2189 src_val
= *src_pixel
++;
2190 *dst_pixel
++ = put_field(get_field(src_val
, src
->red_shift
, src
->red_len
), dst
->red_shift
, dst
->red_len
) |
2191 put_field(get_field(src_val
, src
->green_shift
, src
->green_len
), dst
->green_shift
, dst
->green_len
) |
2192 put_field(get_field(src_val
, src
->blue_shift
, src
->blue_len
), dst
->blue_shift
, dst
->blue_len
);
2194 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2195 dst_start
+= dst
->stride
/ 2;
2196 src_start
+= src
->stride
/ 4;
2204 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2206 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2208 dst_pixel
= dst_start
;
2209 src_pixel
= src_start
;
2210 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2213 rgb
.rgbBlue
= *src_pixel
++;
2214 rgb
.rgbGreen
= *src_pixel
++;
2215 rgb
.rgbRed
= *src_pixel
++;
2217 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
2218 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
2219 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
2221 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2222 dst_start
+= dst
->stride
/ 2;
2223 src_start
+= src
->stride
;
2230 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2231 if(src
->funcs
== &funcs_555
)
2233 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2235 dst_pixel
= dst_start
;
2236 src_pixel
= src_start
;
2237 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2239 src_val
= *src_pixel
++;
2240 *dst_pixel
++ = put_field(((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07), dst
->red_shift
, dst
->red_len
) |
2241 put_field(((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07), dst
->green_shift
, dst
->green_len
) |
2242 put_field(((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
2244 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2245 dst_start
+= dst
->stride
/ 2;
2246 src_start
+= src
->stride
/ 2;
2249 else if(bit_fields_match(src
, dst
))
2251 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
2252 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2255 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2257 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 2);
2258 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
2259 dst_start
+= dst
->stride
/ 2;
2260 src_start
+= src
->stride
/ 2;
2264 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2266 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2268 dst_pixel
= dst_start
;
2269 src_pixel
= src_start
;
2270 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2272 src_val
= *src_pixel
++;
2273 *dst_pixel
++ = put_field( (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2274 (((src_val
>> src
->red_shift
) >> 2) & 0x07), dst
->red_shift
, dst
->red_len
) |
2275 put_field( (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
2276 (((src_val
>> src
->green_shift
) >> 2) & 0x07), dst
->green_shift
, dst
->green_len
) |
2277 put_field( (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2278 (((src_val
>> src
->blue_shift
) >> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
2280 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2281 dst_start
+= dst
->stride
/ 2;
2282 src_start
+= src
->stride
/ 2;
2285 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2287 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2289 dst_pixel
= dst_start
;
2290 src_pixel
= src_start
;
2291 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2293 src_val
= *src_pixel
++;
2294 *dst_pixel
++ = put_field( (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2295 (((src_val
>> src
->red_shift
) >> 2) & 0x07), dst
->red_shift
, dst
->red_len
) |
2296 put_field( (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
2297 (((src_val
>> src
->green_shift
) >> 4) & 0x03), dst
->green_shift
, dst
->green_len
) |
2298 put_field( (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2299 (((src_val
>> src
->blue_shift
) >> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
2301 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2302 dst_start
+= dst
->stride
/ 2;
2303 src_start
+= src
->stride
/ 2;
2308 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2310 dst_pixel
= dst_start
;
2311 src_pixel
= src_start
;
2312 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2314 src_val
= *src_pixel
++;
2315 *dst_pixel
++ = put_field(get_field(src_val
, src
->red_shift
, src
->red_len
), dst
->red_shift
, dst
->red_len
) |
2316 put_field(get_field(src_val
, src
->green_shift
, src
->green_len
), dst
->green_shift
, dst
->green_len
) |
2317 put_field(get_field(src_val
, src
->blue_shift
, src
->blue_len
), dst
->blue_shift
, dst
->blue_len
);
2319 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2320 dst_start
+= dst
->stride
/ 2;
2321 src_start
+= src
->stride
/ 2;
2329 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2330 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2332 dst_pixel
= dst_start
;
2333 src_pixel
= src_start
;
2334 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2336 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
2337 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
2338 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
2339 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
2341 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2342 dst_start
+= dst
->stride
/ 2;
2343 src_start
+= src
->stride
;
2350 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2351 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2353 dst_pixel
= dst_start
;
2354 src_pixel
= src_start
;
2355 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2359 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
2361 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
2362 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
2363 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
2364 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
2366 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2367 dst_start
+= dst
->stride
/ 2;
2368 src_start
+= src
->stride
;
2375 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2376 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2378 dst_pixel
= dst_start
;
2379 src_pixel
= src_start
;
2380 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2383 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
2384 if((x
% 8) == 7) src_pixel
++;
2385 rgb
= src
->color_table
[src_val
];
2386 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
2387 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
2388 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
2390 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2391 dst_start
+= dst
->stride
/ 2;
2392 src_start
+= src
->stride
;
2399 static inline BOOL
color_tables_match(const dib_info
*d1
, const dib_info
*d2
)
2401 assert(d1
->color_table_size
&& d2
->color_table_size
);
2403 if(d1
->color_table_size
!= d2
->color_table_size
) return FALSE
;
2404 return !memcmp(d1
->color_table
, d2
->color_table
, d1
->color_table_size
* sizeof(d1
->color_table
[0]));
2407 static void convert_to_8(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
2409 BYTE
*dst_start
= get_pixel_ptr_8(dst
, 0, 0), *dst_pixel
;
2410 INT x
, y
, pad_size
= ((dst
->width
+ 3) & ~3) - (src_rect
->right
- src_rect
->left
);
2413 switch(src
->bit_count
)
2417 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2419 if(src
->funcs
== &funcs_8888
)
2421 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2423 dst_pixel
= dst_start
;
2424 src_pixel
= src_start
;
2425 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2427 src_val
= *src_pixel
++;
2428 *dst_pixel
++ = rgb_to_pixel_colortable(dst
, src_val
>> 16, src_val
>> 8, src_val
);
2430 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2431 dst_start
+= dst
->stride
;
2432 src_start
+= src
->stride
/ 4;
2435 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
2437 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2439 dst_pixel
= dst_start
;
2440 src_pixel
= src_start
;
2441 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2443 src_val
= *src_pixel
++;
2444 *dst_pixel
++ = rgb_to_pixel_colortable(dst
,
2445 src_val
>> src
->red_shift
,
2446 src_val
>> src
->green_shift
,
2447 src_val
>> src
->blue_shift
);
2449 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2450 dst_start
+= dst
->stride
;
2451 src_start
+= src
->stride
/ 4;
2456 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2458 dst_pixel
= dst_start
;
2459 src_pixel
= src_start
;
2460 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2462 src_val
= *src_pixel
++;
2463 *dst_pixel
++ = rgb_to_pixel_colortable(dst
,
2464 get_field(src_val
, src
->red_shift
, src
->red_len
),
2465 get_field(src_val
, src
->green_shift
, src
->green_len
),
2466 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
2468 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2469 dst_start
+= dst
->stride
;
2470 src_start
+= src
->stride
/ 4;
2478 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2480 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2482 dst_pixel
= dst_start
;
2483 src_pixel
= src_start
;
2484 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, src_pixel
+= 3)
2486 *dst_pixel
++ = rgb_to_pixel_colortable(dst
, src_pixel
[2], src_pixel
[1], src_pixel
[0] );
2488 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2489 dst_start
+= dst
->stride
;
2490 src_start
+= src
->stride
;
2497 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2498 if(src
->funcs
== &funcs_555
)
2500 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2502 dst_pixel
= dst_start
;
2503 src_pixel
= src_start
;
2504 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2506 src_val
= *src_pixel
++;
2507 *dst_pixel
++ = rgb_to_pixel_colortable(dst
,
2508 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
2509 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
2510 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07) );
2512 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2513 dst_start
+= dst
->stride
;
2514 src_start
+= src
->stride
/ 2;
2517 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
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_to_pixel_colortable(dst
,
2527 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2528 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
2529 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
2530 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
2531 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2532 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
2534 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2535 dst_start
+= dst
->stride
;
2536 src_start
+= src
->stride
/ 2;
2539 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2541 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2543 dst_pixel
= dst_start
;
2544 src_pixel
= src_start
;
2545 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2547 src_val
= *src_pixel
++;
2548 *dst_pixel
++ = rgb_to_pixel_colortable(dst
,
2549 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2550 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
2551 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
2552 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
2553 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2554 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
2556 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2557 dst_start
+= dst
->stride
;
2558 src_start
+= src
->stride
/ 2;
2563 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2565 dst_pixel
= dst_start
;
2566 src_pixel
= src_start
;
2567 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2569 src_val
= *src_pixel
++;
2570 *dst_pixel
++ = rgb_to_pixel_colortable(dst
,
2571 get_field(src_val
, src
->red_shift
, src
->red_len
),
2572 get_field(src_val
, src
->green_shift
, src
->green_len
),
2573 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
2575 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2576 dst_start
+= dst
->stride
;
2577 src_start
+= src
->stride
/ 2;
2585 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2587 if(color_tables_match(dst
, src
))
2589 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
2590 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2593 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2595 memcpy(dst_start
, src_start
, src_rect
->right
- src_rect
->left
);
2596 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
2597 dst_start
+= dst
->stride
;
2598 src_start
+= src
->stride
;
2604 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2606 dst_pixel
= dst_start
;
2607 src_pixel
= src_start
;
2608 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2610 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
2611 *dst_pixel
++ = rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
2613 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2614 dst_start
+= dst
->stride
;
2615 src_start
+= src
->stride
;
2623 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2624 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2626 dst_pixel
= dst_start
;
2627 src_pixel
= src_start
;
2628 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2632 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
2634 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
2635 *dst_pixel
++ = rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
2637 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2638 dst_start
+= dst
->stride
;
2639 src_start
+= src
->stride
;
2646 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2647 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2649 dst_pixel
= dst_start
;
2650 src_pixel
= src_start
;
2651 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2654 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
2655 if((x
% 8) == 7) src_pixel
++;
2656 rgb
= src
->color_table
[src_val
];
2657 *dst_pixel
++ = rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
2659 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2660 dst_start
+= dst
->stride
;
2661 src_start
+= src
->stride
;
2668 static void convert_to_4(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
2670 BYTE
*dst_start
= get_pixel_ptr_4(dst
, 0, 0), *dst_pixel
, dst_val
;
2671 INT x
, y
, pad_size
= ((dst
->width
+ 7) & ~7) / 2 - (src_rect
->right
- src_rect
->left
+ 1) / 2;
2674 switch(src
->bit_count
)
2678 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2680 if(src
->funcs
== &funcs_8888
)
2682 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2684 dst_pixel
= dst_start
;
2685 src_pixel
= src_start
;
2686 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2688 src_val
= *src_pixel
++;
2689 dst_val
= rgb_to_pixel_colortable(dst
, src_val
>> 16, src_val
>> 8, src_val
);
2690 if((x
- src_rect
->left
) & 1)
2692 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
2696 *dst_pixel
= (dst_val
<< 4) & 0xf0;
2700 if((x
- src_rect
->left
) & 1) dst_pixel
++;
2701 memset(dst_pixel
, 0, pad_size
);
2703 dst_start
+= dst
->stride
;
2704 src_start
+= src
->stride
/ 4;
2707 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
2709 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2711 dst_pixel
= dst_start
;
2712 src_pixel
= src_start
;
2713 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2715 src_val
= *src_pixel
++;
2716 dst_val
= rgb_to_pixel_colortable(dst
,
2717 src_val
>> src
->red_shift
,
2718 src_val
>> src
->green_shift
,
2719 src_val
>> src
->blue_shift
);
2720 if((x
- src_rect
->left
) & 1)
2722 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
2726 *dst_pixel
= (dst_val
<< 4) & 0xf0;
2730 if((x
- src_rect
->left
) & 1) dst_pixel
++;
2731 memset(dst_pixel
, 0, pad_size
);
2733 dst_start
+= dst
->stride
;
2734 src_start
+= src
->stride
/ 4;
2739 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2741 dst_pixel
= dst_start
;
2742 src_pixel
= src_start
;
2743 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2745 src_val
= *src_pixel
++;
2746 dst_val
= rgb_to_pixel_colortable(dst
,
2747 get_field(src_val
, src
->red_shift
, src
->red_len
),
2748 get_field(src_val
, src
->green_shift
, src
->green_len
),
2749 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
2750 if((x
- src_rect
->left
) & 1)
2752 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
2756 *dst_pixel
= (dst_val
<< 4) & 0xf0;
2760 if((x
- src_rect
->left
) & 1) dst_pixel
++;
2761 memset(dst_pixel
, 0, pad_size
);
2763 dst_start
+= dst
->stride
;
2764 src_start
+= src
->stride
/ 4;
2772 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2774 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2776 dst_pixel
= dst_start
;
2777 src_pixel
= src_start
;
2778 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, src_pixel
+= 3)
2780 dst_val
= rgb_to_pixel_colortable(dst
, src_pixel
[2], src_pixel
[1], src_pixel
[0]);
2782 if((x
- src_rect
->left
) & 1)
2784 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
2788 *dst_pixel
= (dst_val
<< 4) & 0xf0;
2792 if((x
- src_rect
->left
) & 1) dst_pixel
++;
2793 memset(dst_pixel
, 0, pad_size
);
2795 dst_start
+= dst
->stride
;
2796 src_start
+= src
->stride
;
2803 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2804 if(src
->funcs
== &funcs_555
)
2806 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2808 dst_pixel
= dst_start
;
2809 src_pixel
= src_start
;
2810 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2812 src_val
= *src_pixel
++;
2813 dst_val
= rgb_to_pixel_colortable(dst
,
2814 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
2815 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
2816 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07) );
2817 if((x
- src_rect
->left
) & 1)
2819 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
2823 *dst_pixel
= (dst_val
<< 4) & 0xf0;
2827 if((x
- src_rect
->left
) & 1) dst_pixel
++;
2828 memset(dst_pixel
, 0, pad_size
);
2830 dst_start
+= dst
->stride
;
2831 src_start
+= src
->stride
/ 2;
2834 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2836 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2838 dst_pixel
= dst_start
;
2839 src_pixel
= src_start
;
2840 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2842 src_val
= *src_pixel
++;
2843 dst_val
= rgb_to_pixel_colortable(dst
,
2844 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2845 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
2846 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
2847 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
2848 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2849 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
2850 if((x
- src_rect
->left
) & 1)
2852 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
2856 *dst_pixel
= (dst_val
<< 4) & 0xf0;
2860 if((x
- src_rect
->left
) & 1) dst_pixel
++;
2861 memset(dst_pixel
, 0, pad_size
);
2863 dst_start
+= dst
->stride
;
2864 src_start
+= src
->stride
/ 2;
2867 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2869 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2871 dst_pixel
= dst_start
;
2872 src_pixel
= src_start
;
2873 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2875 src_val
= *src_pixel
++;
2876 dst_val
= rgb_to_pixel_colortable(dst
,
2877 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2878 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
2879 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
2880 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
2881 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2882 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
2883 if((x
- src_rect
->left
) & 1)
2885 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
2889 *dst_pixel
= (dst_val
<< 4) & 0xf0;
2893 if((x
- src_rect
->left
) & 1) dst_pixel
++;
2894 memset(dst_pixel
, 0, pad_size
);
2896 dst_start
+= dst
->stride
;
2897 src_start
+= src
->stride
/ 2;
2902 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2904 dst_pixel
= dst_start
;
2905 src_pixel
= src_start
;
2906 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2908 src_val
= *src_pixel
++;
2909 dst_val
= rgb_to_pixel_colortable(dst
,
2910 get_field(src_val
, src
->red_shift
, src
->red_len
),
2911 get_field(src_val
, src
->green_shift
, src
->green_len
),
2912 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
2913 if((x
- src_rect
->left
) & 1)
2915 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
2919 *dst_pixel
= (dst_val
<< 4) & 0xf0;
2923 if((x
- src_rect
->left
) & 1) dst_pixel
++;
2924 memset(dst_pixel
, 0, pad_size
);
2926 dst_start
+= dst
->stride
;
2927 src_start
+= src
->stride
/ 2;
2935 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2937 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2939 dst_pixel
= dst_start
;
2940 src_pixel
= src_start
;
2941 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2943 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
2944 dst_val
= rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
2945 if((x
- src_rect
->left
) & 1)
2947 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
2951 *dst_pixel
= (dst_val
<< 4) & 0xf0;
2955 if((x
- src_rect
->left
) & 1) dst_pixel
++;
2956 memset(dst_pixel
, 0, pad_size
);
2958 dst_start
+= dst
->stride
;
2959 src_start
+= src
->stride
;
2966 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2968 if(color_tables_match(dst
, src
) && (src_rect
->left
& 1) == 0)
2970 if(src
->stride
> 0 && dst
->stride
> 0 && src_rect
->left
== 0 && src_rect
->right
== src
->width
)
2971 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2974 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2976 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
+ 1) / 2);
2977 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
+ 1) / 2, 0, pad_size
);
2978 dst_start
+= dst
->stride
;
2979 src_start
+= src
->stride
;
2985 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2987 dst_pixel
= dst_start
;
2988 src_pixel
= src_start
;
2989 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2993 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
2995 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
2996 dst_val
= rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
2997 if((x
- src_rect
->left
) & 1)
2999 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3003 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3007 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3008 memset(dst_pixel
, 0, pad_size
);
3010 dst_start
+= dst
->stride
;
3011 src_start
+= src
->stride
;
3019 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3020 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3022 dst_pixel
= dst_start
;
3023 src_pixel
= src_start
;
3024 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3027 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
3028 if((x
% 8) == 7) src_pixel
++;
3029 rgb
= src
->color_table
[src_val
];
3030 dst_val
= rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
3031 if((x
- src_rect
->left
) & 1)
3033 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3037 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3041 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3042 memset(dst_pixel
, 0, pad_size
);
3044 dst_start
+= dst
->stride
;
3045 src_start
+= src
->stride
;
3052 static void convert_to_1(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
3054 BYTE
*dst_start
= get_pixel_ptr_1(dst
, 0, 0), *dst_pixel
, dst_val
;
3055 INT x
, y
, pad_size
= ((dst
->width
+ 31) & ~31) / 8 - (src_rect
->right
- src_rect
->left
+ 7) / 8;
3059 /* FIXME: Brushes should be dithered. */
3061 switch(src
->bit_count
)
3065 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3067 if(src
->funcs
== &funcs_8888
)
3069 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3071 dst_pixel
= dst_start
;
3072 src_pixel
= src_start
;
3073 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3075 src_val
= *src_pixel
++;
3076 dst_val
= rgb_to_pixel_colortable(dst
, src_val
>> 16, src_val
>> 8, src_val
) ? 0xff : 0;
3078 if(bit_pos
== 0) *dst_pixel
= 0;
3079 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3089 if(bit_pos
!= 0) dst_pixel
++;
3090 memset(dst_pixel
, 0, pad_size
);
3092 dst_start
+= dst
->stride
;
3093 src_start
+= src
->stride
/ 4;
3096 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
3098 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3100 dst_pixel
= dst_start
;
3101 src_pixel
= src_start
;
3102 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3104 src_val
= *src_pixel
++;
3105 dst_val
= rgb_to_pixel_colortable(dst
,
3106 src_val
>> src
->red_shift
,
3107 src_val
>> src
->green_shift
,
3108 src_val
>> src
->blue_shift
) ? 0xff : 0;
3110 if(bit_pos
== 0) *dst_pixel
= 0;
3111 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3121 if(bit_pos
!= 0) dst_pixel
++;
3122 memset(dst_pixel
, 0, pad_size
);
3124 dst_start
+= dst
->stride
;
3125 src_start
+= src
->stride
/ 4;
3130 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3132 dst_pixel
= dst_start
;
3133 src_pixel
= src_start
;
3134 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3136 src_val
= *src_pixel
++;
3137 dst_val
= rgb_to_pixel_colortable(dst
,
3138 get_field(src_val
, src
->red_shift
, src
->red_len
),
3139 get_field(src_val
, src
->green_shift
, src
->green_len
),
3140 get_field(src_val
, src
->blue_shift
, src
->blue_len
)) ? 0xff : 0;
3142 if(bit_pos
== 0) *dst_pixel
= 0;
3143 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3153 if(bit_pos
!= 0) dst_pixel
++;
3154 memset(dst_pixel
, 0, pad_size
);
3156 dst_start
+= dst
->stride
;
3157 src_start
+= src
->stride
/ 4;
3165 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3167 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3169 dst_pixel
= dst_start
;
3170 src_pixel
= src_start
;
3171 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++, src_pixel
+= 3)
3173 dst_val
= rgb_to_pixel_colortable(dst
, src_pixel
[2], src_pixel
[1], src_pixel
[0]) ? 0xff : 0;
3175 if(bit_pos
== 0) *dst_pixel
= 0;
3176 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3186 if(bit_pos
!= 0) dst_pixel
++;
3187 memset(dst_pixel
, 0, pad_size
);
3189 dst_start
+= dst
->stride
;
3190 src_start
+= src
->stride
;
3197 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3198 if(src
->funcs
== &funcs_555
)
3200 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3202 dst_pixel
= dst_start
;
3203 src_pixel
= src_start
;
3204 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3206 src_val
= *src_pixel
++;
3207 dst_val
= rgb_to_pixel_colortable(dst
,
3208 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
3209 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
3210 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07) ) ? 0xff : 0;
3212 if(bit_pos
== 0) *dst_pixel
= 0;
3213 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3223 if(bit_pos
!= 0) dst_pixel
++;
3224 memset(dst_pixel
, 0, pad_size
);
3226 dst_start
+= dst
->stride
;
3227 src_start
+= src
->stride
/ 2;
3230 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
3232 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3234 dst_pixel
= dst_start
;
3235 src_pixel
= src_start
;
3236 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3238 src_val
= *src_pixel
++;
3239 dst_val
= rgb_to_pixel_colortable(dst
,
3240 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3241 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3242 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
3243 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
3244 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3245 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) ) ? 0xff : 0;
3246 if(bit_pos
== 0) *dst_pixel
= 0;
3247 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3257 if(bit_pos
!= 0) dst_pixel
++;
3258 memset(dst_pixel
, 0, pad_size
);
3260 dst_start
+= dst
->stride
;
3261 src_start
+= src
->stride
/ 2;
3264 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
3266 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3268 dst_pixel
= dst_start
;
3269 src_pixel
= src_start
;
3270 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3272 src_val
= *src_pixel
++;
3273 dst_val
= rgb_to_pixel_colortable(dst
,
3274 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3275 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3276 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
3277 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
3278 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3279 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) ) ? 0xff : 0;
3280 if(bit_pos
== 0) *dst_pixel
= 0;
3281 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3291 if(bit_pos
!= 0) dst_pixel
++;
3292 memset(dst_pixel
, 0, pad_size
);
3294 dst_start
+= dst
->stride
;
3295 src_start
+= src
->stride
/ 2;
3300 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3302 dst_pixel
= dst_start
;
3303 src_pixel
= src_start
;
3304 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3306 src_val
= *src_pixel
++;
3307 dst_val
= rgb_to_pixel_colortable(dst
,
3308 get_field(src_val
, src
->red_shift
, src
->red_len
),
3309 get_field(src_val
, src
->green_shift
, src
->green_len
),
3310 get_field(src_val
, src
->blue_shift
, src
->blue_len
)) ? 0xff : 0;
3311 if(bit_pos
== 0) *dst_pixel
= 0;
3312 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3322 if(bit_pos
!= 0) dst_pixel
++;
3323 memset(dst_pixel
, 0, pad_size
);
3325 dst_start
+= dst
->stride
;
3326 src_start
+= src
->stride
/ 2;
3334 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3336 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3338 dst_pixel
= dst_start
;
3339 src_pixel
= src_start
;
3340 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3342 RGBQUAD rgb
= colortable_entry( src
, *src_pixel
++ );
3343 dst_val
= rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
) ? 0xff : 0;
3345 if(bit_pos
== 0) *dst_pixel
= 0;
3346 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3356 if(bit_pos
!= 0) dst_pixel
++;
3357 memset(dst_pixel
, 0, pad_size
);
3359 dst_start
+= dst
->stride
;
3360 src_start
+= src
->stride
;
3367 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3369 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3371 dst_pixel
= dst_start
;
3372 src_pixel
= src_start
;
3373 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3377 rgb
= colortable_entry( src
, *src_pixel
++ & 0xf );
3379 rgb
= colortable_entry( src
, *src_pixel
>> 4 );
3380 dst_val
= rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
) ? 0xff : 0;
3382 if(bit_pos
== 0) *dst_pixel
= 0;
3383 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3393 if(bit_pos
!= 0) dst_pixel
++;
3394 memset(dst_pixel
, 0, pad_size
);
3396 dst_start
+= dst
->stride
;
3397 src_start
+= src
->stride
;
3402 /* Note that while MSDN states that a 1 bpp dib brush -> mono dc
3403 uses text/bkgnd colours instead of the dib's colour table, this
3404 doesn't appear to be the case for a dc backed by a
3409 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3410 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3412 dst_pixel
= dst_start
;
3413 src_pixel
= src_start
;
3414 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3417 src_val
= (*src_pixel
& pixel_masks_1
[x
% 8]) ? 1 : 0;
3418 if((x
% 8) == 7) src_pixel
++;
3419 rgb
= src
->color_table
[src_val
];
3420 dst_val
= rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
) ? 0xff : 0;
3422 if(bit_pos
== 0) *dst_pixel
= 0;
3423 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3433 if(bit_pos
!= 0) dst_pixel
++;
3434 memset(dst_pixel
, 0, pad_size
);
3436 dst_start
+= dst
->stride
;
3437 src_start
+= src
->stride
;
3444 static void convert_to_null(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
)
3448 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
)
3450 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
3451 DWORD mask_start
= 0, mask_offset
;
3452 DWORD
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
3455 for(y
= 0; y
< hatch
->height
; y
++)
3457 hatch_ptr
= hatch_start
;
3458 mask_offset
= mask_start
;
3459 for(x
= 0; x
< hatch
->width
; x
++)
3461 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
3463 and_bits
[mask_offset
] = fg
->and;
3464 xor_bits
[mask_offset
] = fg
->xor;
3468 and_bits
[mask_offset
] = bg
->and;
3469 xor_bits
[mask_offset
] = bg
->xor;
3471 if(x
% 8 == 7) hatch_ptr
++;
3474 hatch_start
+= hatch
->stride
;
3475 mask_start
+= dib
->stride
/ 4;
3481 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
)
3483 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
3484 DWORD mask_start
= 0, mask_offset
;
3485 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
3488 for(y
= 0; y
< hatch
->height
; y
++)
3490 hatch_ptr
= hatch_start
;
3491 mask_offset
= mask_start
;
3492 for(x
= 0; x
< hatch
->width
; x
++)
3494 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
3496 and_bits
[mask_offset
] = fg
->and & 0xff;
3497 xor_bits
[mask_offset
++] = fg
->xor & 0xff;
3498 and_bits
[mask_offset
] = (fg
->and >> 8) & 0xff;
3499 xor_bits
[mask_offset
++] = (fg
->xor >> 8) & 0xff;
3500 and_bits
[mask_offset
] = (fg
->and >> 16) & 0xff;
3501 xor_bits
[mask_offset
++] = (fg
->xor >> 16) & 0xff;
3505 and_bits
[mask_offset
] = bg
->and & 0xff;
3506 xor_bits
[mask_offset
++] = bg
->xor & 0xff;
3507 and_bits
[mask_offset
] = (bg
->and >> 8) & 0xff;
3508 xor_bits
[mask_offset
++] = (bg
->xor >> 8) & 0xff;
3509 and_bits
[mask_offset
] = (bg
->and >> 16) & 0xff;
3510 xor_bits
[mask_offset
++] = (bg
->xor >> 16) & 0xff;
3512 if(x
% 8 == 7) hatch_ptr
++;
3514 hatch_start
+= hatch
->stride
;
3515 mask_start
+= dib
->stride
;
3521 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
)
3523 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
3524 DWORD mask_start
= 0, mask_offset
;
3525 WORD
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
3528 for(y
= 0; y
< hatch
->height
; y
++)
3530 hatch_ptr
= hatch_start
;
3531 mask_offset
= mask_start
;
3532 for(x
= 0; x
< hatch
->width
; x
++)
3534 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
3536 and_bits
[mask_offset
] = fg
->and;
3537 xor_bits
[mask_offset
] = fg
->xor;
3541 and_bits
[mask_offset
] = bg
->and;
3542 xor_bits
[mask_offset
] = bg
->xor;
3544 if(x
% 8 == 7) hatch_ptr
++;
3547 hatch_start
+= hatch
->stride
;
3548 mask_start
+= dib
->stride
/ 2;
3554 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
)
3556 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
3557 DWORD mask_start
= 0, mask_offset
;
3558 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
3561 for(y
= 0; y
< hatch
->height
; y
++)
3563 hatch_ptr
= hatch_start
;
3564 mask_offset
= mask_start
;
3565 for(x
= 0; x
< hatch
->width
; x
++)
3567 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
3569 and_bits
[mask_offset
] = fg
->and;
3570 xor_bits
[mask_offset
] = fg
->xor;
3574 and_bits
[mask_offset
] = bg
->and;
3575 xor_bits
[mask_offset
] = bg
->xor;
3577 if(x
% 8 == 7) hatch_ptr
++;
3580 hatch_start
+= hatch
->stride
;
3581 mask_start
+= dib
->stride
;
3587 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
)
3589 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
3590 DWORD mask_start
= 0, mask_offset
;
3591 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
3592 const rop_mask
*rop_mask
;
3595 for(y
= 0; y
< hatch
->height
; y
++)
3597 hatch_ptr
= hatch_start
;
3598 mask_offset
= mask_start
;
3599 for(x
= 0; x
< hatch
->width
; x
++)
3601 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
3608 and_bits
[mask_offset
] = (rop_mask
->and & 0x0f) | (and_bits
[mask_offset
] & 0xf0);
3609 xor_bits
[mask_offset
] = (rop_mask
->xor & 0x0f) | (xor_bits
[mask_offset
] & 0xf0);
3614 and_bits
[mask_offset
] = (rop_mask
->and << 4) & 0xf0;
3615 xor_bits
[mask_offset
] = (rop_mask
->xor << 4) & 0xf0;
3618 if(x
% 8 == 7) hatch_ptr
++;
3620 hatch_start
+= hatch
->stride
;
3621 mask_start
+= dib
->stride
;
3627 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
)
3629 BYTE
*hatch_start
= get_pixel_ptr_1(hatch
, 0, 0), *hatch_ptr
;
3630 DWORD mask_start
= 0, mask_offset
;
3631 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
3635 for(y
= 0; y
< hatch
->height
; y
++)
3637 hatch_ptr
= hatch_start
;
3638 mask_offset
= mask_start
;
3639 for(x
= 0, bit_pos
= 0; x
< hatch
->width
; x
++)
3641 if(*hatch_ptr
& pixel_masks_1
[x
% 8])
3643 rop_mask
.and = (fg
->and & 1) ? 0xff : 0;
3644 rop_mask
.xor = (fg
->xor & 1) ? 0xff : 0;
3648 rop_mask
.and = (bg
->and & 1) ? 0xff : 0;
3649 rop_mask
.xor = (bg
->xor & 1) ? 0xff : 0;
3652 if(bit_pos
== 0) and_bits
[mask_offset
] = xor_bits
[mask_offset
] = 0;
3654 and_bits
[mask_offset
] = (rop_mask
.and & pixel_masks_1
[bit_pos
]) | (and_bits
[mask_offset
] & ~pixel_masks_1
[bit_pos
]);
3655 xor_bits
[mask_offset
] = (rop_mask
.xor & pixel_masks_1
[bit_pos
]) | (xor_bits
[mask_offset
] & ~pixel_masks_1
[bit_pos
]);
3664 hatch_start
+= hatch
->stride
;
3665 mask_start
+= dib
->stride
;
3671 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
)
3676 static inline void rop_codes_from_stretch_mode( int mode
, struct rop_codes
*codes
)
3681 case STRETCH_DELETESCANS
:
3682 get_rop_codes( R2_COPYPEN
, codes
);
3684 case STRETCH_ORSCANS
:
3685 get_rop_codes( R2_MERGEPEN
, codes
);
3687 case STRETCH_ANDSCANS
:
3688 get_rop_codes( R2_MASKPEN
, codes
);
3694 static void stretch_row_32(const dib_info
*dst_dib
, const POINT
*dst_start
,
3695 const dib_info
*src_dib
, const POINT
*src_start
,
3696 const struct stretch_params
*params
, int mode
,
3699 DWORD
*dst_ptr
= get_pixel_ptr_32( dst_dib
, dst_start
->x
, dst_start
->y
);
3700 DWORD
*src_ptr
= get_pixel_ptr_32( src_dib
, src_start
->x
, src_start
->y
);
3701 int err
= params
->err_start
;
3703 struct rop_codes codes
;
3705 rop_codes_from_stretch_mode( mode
, &codes
);
3706 for (width
= params
->length
; width
; width
--)
3708 do_rop_codes_32( dst_ptr
, *src_ptr
, &codes
);
3709 dst_ptr
+= params
->dst_inc
;
3712 src_ptr
+= params
->src_inc
;
3713 err
+= params
->err_add_1
;
3715 else err
+= params
->err_add_2
;
3719 static void stretch_row_24(const dib_info
*dst_dib
, const POINT
*dst_start
,
3720 const dib_info
*src_dib
, const POINT
*src_start
,
3721 const struct stretch_params
*params
, int mode
,
3724 BYTE
*dst_ptr
= get_pixel_ptr_24( dst_dib
, dst_start
->x
, dst_start
->y
);
3725 BYTE
*src_ptr
= get_pixel_ptr_24( src_dib
, src_start
->x
, src_start
->y
);
3726 int err
= params
->err_start
;
3728 struct rop_codes codes
;
3730 rop_codes_from_stretch_mode( mode
, &codes
);
3731 for (width
= params
->length
; width
; width
--)
3733 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
3734 do_rop_codes_8( dst_ptr
+ 1, *(src_ptr
+ 1), &codes
);
3735 do_rop_codes_8( dst_ptr
+ 2, *(src_ptr
+ 2), &codes
);
3736 dst_ptr
+= 3 * params
->dst_inc
;
3739 src_ptr
+= 3 * params
->src_inc
;
3740 err
+= params
->err_add_1
;
3742 else err
+= params
->err_add_2
;
3746 static void stretch_row_16(const dib_info
*dst_dib
, const POINT
*dst_start
,
3747 const dib_info
*src_dib
, const POINT
*src_start
,
3748 const struct stretch_params
*params
, int mode
,
3751 WORD
*dst_ptr
= get_pixel_ptr_16( dst_dib
, dst_start
->x
, dst_start
->y
);
3752 WORD
*src_ptr
= get_pixel_ptr_16( src_dib
, src_start
->x
, src_start
->y
);
3753 int err
= params
->err_start
;
3755 struct rop_codes codes
;
3757 rop_codes_from_stretch_mode( mode
, &codes
);
3758 for (width
= params
->length
; width
; width
--)
3760 do_rop_codes_16( dst_ptr
, *src_ptr
, &codes
);
3761 dst_ptr
+= params
->dst_inc
;
3764 src_ptr
+= params
->src_inc
;
3765 err
+= params
->err_add_1
;
3767 else err
+= params
->err_add_2
;
3771 static void stretch_row_8(const dib_info
*dst_dib
, const POINT
*dst_start
,
3772 const dib_info
*src_dib
, const POINT
*src_start
,
3773 const struct stretch_params
*params
, int mode
,
3776 BYTE
*dst_ptr
= get_pixel_ptr_8( dst_dib
, dst_start
->x
, dst_start
->y
);
3777 BYTE
*src_ptr
= get_pixel_ptr_8( src_dib
, src_start
->x
, src_start
->y
);
3778 int err
= params
->err_start
;
3780 struct rop_codes codes
;
3782 rop_codes_from_stretch_mode( mode
, &codes
);
3783 for (width
= params
->length
; width
; width
--)
3785 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
3786 dst_ptr
+= params
->dst_inc
;
3789 src_ptr
+= params
->src_inc
;
3790 err
+= params
->err_add_1
;
3792 else err
+= params
->err_add_2
;
3796 static void stretch_row_4(const dib_info
*dst_dib
, const POINT
*dst_start
,
3797 const dib_info
*src_dib
, const POINT
*src_start
,
3798 const struct stretch_params
*params
, int mode
,
3801 BYTE
*dst_ptr
= get_pixel_ptr_4( dst_dib
, dst_start
->x
, dst_start
->y
);
3802 BYTE
*src_ptr
= get_pixel_ptr_4( src_dib
, src_start
->x
, src_start
->y
);
3803 int err
= params
->err_start
;
3804 int width
, dst_x
= dst_start
->x
, src_x
= src_start
->x
;
3805 struct rop_codes codes
;
3808 rop_codes_from_stretch_mode( mode
, &codes
);
3809 for (width
= params
->length
; width
; width
--)
3811 if (src_x
& 1) src_val
= (*src_ptr
& 0x0f) | (*src_ptr
<< 4);
3812 else src_val
= (*src_ptr
& 0xf0) | (*src_ptr
>> 4);
3814 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, (dst_x
& 1) ? 0x0f : 0xf0 );
3816 if ((dst_x
& ~1) != ((dst_x
+ params
->dst_inc
) & ~1))
3817 dst_ptr
+= params
->dst_inc
;
3818 dst_x
+= params
->dst_inc
;
3822 if ((src_x
& ~1) != ((src_x
+ params
->src_inc
) & ~1))
3823 src_ptr
+= params
->src_inc
;
3824 src_x
+= params
->src_inc
;
3825 err
+= params
->err_add_1
;
3827 else err
+= params
->err_add_2
;
3831 static void stretch_row_1(const dib_info
*dst_dib
, const POINT
*dst_start
,
3832 const dib_info
*src_dib
, const POINT
*src_start
,
3833 const struct stretch_params
*params
, int mode
,
3836 BYTE
*dst_ptr
= get_pixel_ptr_1( dst_dib
, dst_start
->x
, dst_start
->y
);
3837 BYTE
*src_ptr
= get_pixel_ptr_1( src_dib
, src_start
->x
, src_start
->y
);
3838 int err
= params
->err_start
;
3839 int width
, dst_x
= dst_start
->x
, src_x
= src_start
->x
;
3840 struct rop_codes codes
;
3843 rop_codes_from_stretch_mode( mode
, &codes
);
3844 for (width
= params
->length
; width
; width
--)
3846 src_val
= *src_ptr
& pixel_masks_1
[src_x
% 8] ? 0xff : 0;
3847 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, pixel_masks_1
[dst_x
% 8] );
3849 if ((dst_x
& ~7) != ((dst_x
+ params
->dst_inc
) & ~7))
3850 dst_ptr
+= params
->dst_inc
;
3851 dst_x
+= params
->dst_inc
;
3855 if ((src_x
& ~7) != ((src_x
+ params
->src_inc
) & ~7))
3856 src_ptr
+= params
->src_inc
;
3857 src_x
+= params
->src_inc
;
3858 err
+= params
->err_add_1
;
3860 else err
+= params
->err_add_2
;
3864 static void stretch_row_null(const dib_info
*dst_dib
, const POINT
*dst_start
,
3865 const dib_info
*src_dib
, const POINT
*src_start
,
3866 const struct stretch_params
*params
, int mode
,
3869 FIXME("bit count %d\n", dst_dib
->bit_count
);
3873 static void shrink_row_32(const dib_info
*dst_dib
, const POINT
*dst_start
,
3874 const dib_info
*src_dib
, const POINT
*src_start
,
3875 const struct stretch_params
*params
, int mode
,
3878 DWORD
*dst_ptr
= get_pixel_ptr_32( dst_dib
, dst_start
->x
, dst_start
->y
);
3879 DWORD
*src_ptr
= get_pixel_ptr_32( src_dib
, src_start
->x
, src_start
->y
);
3880 int err
= params
->err_start
;
3882 struct rop_codes codes
;
3883 DWORD init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
3884 BOOL new_pix
= TRUE
;
3886 rop_codes_from_stretch_mode( mode
, &codes
);
3887 for (width
= params
->length
; width
; width
--)
3889 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
3890 do_rop_codes_32( dst_ptr
, *src_ptr
, &codes
);
3892 src_ptr
+= params
->src_inc
;
3895 dst_ptr
+= params
->dst_inc
;
3897 err
+= params
->err_add_1
;
3899 else err
+= params
->err_add_2
;
3903 static void shrink_row_24(const dib_info
*dst_dib
, const POINT
*dst_start
,
3904 const dib_info
*src_dib
, const POINT
*src_start
,
3905 const struct stretch_params
*params
, int mode
,
3908 BYTE
*dst_ptr
= get_pixel_ptr_24( dst_dib
, dst_start
->x
, dst_start
->y
);
3909 BYTE
*src_ptr
= get_pixel_ptr_24( src_dib
, src_start
->x
, src_start
->y
);
3910 int err
= params
->err_start
;
3912 struct rop_codes codes
;
3913 BYTE init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
3914 BOOL new_pix
= TRUE
;
3916 rop_codes_from_stretch_mode( mode
, &codes
);
3917 for (width
= params
->length
; width
; width
--)
3919 if (new_pix
&& !keep_dst
) memset( dst_ptr
, init_val
, 3 );
3920 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
3921 do_rop_codes_8( dst_ptr
+ 1, *(src_ptr
+ 1), &codes
);
3922 do_rop_codes_8( dst_ptr
+ 2, *(src_ptr
+ 2), &codes
);
3924 src_ptr
+= 3 * params
->src_inc
;
3927 dst_ptr
+= 3 * params
->dst_inc
;
3929 err
+= params
->err_add_1
;
3931 else err
+= params
->err_add_2
;
3935 static void shrink_row_16(const dib_info
*dst_dib
, const POINT
*dst_start
,
3936 const dib_info
*src_dib
, const POINT
*src_start
,
3937 const struct stretch_params
*params
, int mode
,
3940 WORD
*dst_ptr
= get_pixel_ptr_16( dst_dib
, dst_start
->x
, dst_start
->y
);
3941 WORD
*src_ptr
= get_pixel_ptr_16( src_dib
, src_start
->x
, src_start
->y
);
3942 int err
= params
->err_start
;
3944 struct rop_codes codes
;
3945 WORD init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
3946 BOOL new_pix
= TRUE
;
3948 rop_codes_from_stretch_mode( mode
, &codes
);
3949 for (width
= params
->length
; width
; width
--)
3951 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
3952 do_rop_codes_16( dst_ptr
, *src_ptr
, &codes
);
3954 src_ptr
+= params
->src_inc
;
3957 dst_ptr
+= params
->dst_inc
;
3959 err
+= params
->err_add_1
;
3961 else err
+= params
->err_add_2
;
3965 static void shrink_row_8(const dib_info
*dst_dib
, const POINT
*dst_start
,
3966 const dib_info
*src_dib
, const POINT
*src_start
,
3967 const struct stretch_params
*params
, int mode
,
3970 BYTE
*dst_ptr
= get_pixel_ptr_8( dst_dib
, dst_start
->x
, dst_start
->y
);
3971 BYTE
*src_ptr
= get_pixel_ptr_8( src_dib
, src_start
->x
, src_start
->y
);
3972 int err
= params
->err_start
;
3974 struct rop_codes codes
;
3975 BYTE init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
3976 BOOL new_pix
= TRUE
;
3978 rop_codes_from_stretch_mode( mode
, &codes
);
3979 for (width
= params
->length
; width
; width
--)
3981 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
3982 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
3984 src_ptr
+= params
->src_inc
;
3987 dst_ptr
+= params
->dst_inc
;
3989 err
+= params
->err_add_1
;
3991 else err
+= params
->err_add_2
;
3995 static void shrink_row_4(const dib_info
*dst_dib
, const POINT
*dst_start
,
3996 const dib_info
*src_dib
, const POINT
*src_start
,
3997 const struct stretch_params
*params
, int mode
,
4000 BYTE
*dst_ptr
= get_pixel_ptr_8( dst_dib
, dst_start
->x
, dst_start
->y
);
4001 BYTE
*src_ptr
= get_pixel_ptr_8( src_dib
, src_start
->x
, src_start
->y
);
4002 int err
= params
->err_start
;
4003 int width
, dst_x
= dst_start
->x
, src_x
= src_start
->x
;
4004 struct rop_codes codes
;
4005 BYTE src_val
, init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
4006 BOOL new_pix
= TRUE
;
4008 rop_codes_from_stretch_mode( mode
, &codes
);
4009 for (width
= params
->length
; width
; width
--)
4011 if (new_pix
&& !keep_dst
) do_rop_mask_8( dst_ptr
, 0, init_val
, (dst_x
& 1) ? 0xf0 : 0x0f );
4013 if (src_x
& 1) src_val
= (*src_ptr
& 0x0f) | (*src_ptr
<< 4);
4014 else src_val
= (*src_ptr
& 0xf0) | (*src_ptr
>> 4);
4016 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, (dst_x
& 1) ? 0xf0 : 0x0f );
4019 if ((src_x
& ~1) != ((src_x
+ params
->src_inc
) & ~1))
4020 src_ptr
+= params
->src_inc
;
4021 src_x
+= params
->src_inc
;
4025 if ((dst_x
& ~1) != ((dst_x
+ params
->dst_inc
) & ~1))
4026 dst_ptr
+= params
->dst_inc
;
4027 dst_x
+= params
->dst_inc
;
4029 err
+= params
->err_add_1
;
4031 else err
+= params
->err_add_2
;
4035 static void shrink_row_1(const dib_info
*dst_dib
, const POINT
*dst_start
,
4036 const dib_info
*src_dib
, const POINT
*src_start
,
4037 const struct stretch_params
*params
, int mode
,
4040 BYTE
*dst_ptr
= get_pixel_ptr_1( dst_dib
, dst_start
->x
, dst_start
->y
);
4041 BYTE
*src_ptr
= get_pixel_ptr_1( src_dib
, src_start
->x
, src_start
->y
);
4042 int err
= params
->err_start
;
4043 int width
, dst_x
= dst_start
->x
, src_x
= src_start
->x
;
4044 struct rop_codes codes
;
4045 BYTE src_val
, init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
4046 BOOL new_pix
= TRUE
;
4048 rop_codes_from_stretch_mode( mode
, &codes
);
4049 for (width
= params
->length
; width
; width
--)
4051 if (new_pix
&& !keep_dst
) do_rop_mask_8( dst_ptr
, 0, init_val
, pixel_masks_1
[dst_x
% 8] );
4052 src_val
= *src_ptr
& pixel_masks_1
[src_x
% 8] ? 0xff : 0;
4053 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, pixel_masks_1
[dst_x
% 8] );
4056 if ((src_x
& ~7) != ((src_x
+ params
->src_inc
) & ~7))
4057 src_ptr
+= params
->src_inc
;
4058 src_x
+= params
->src_inc
;
4062 if ((dst_x
& ~7) != ((dst_x
+ params
->dst_inc
) & ~7))
4063 dst_ptr
+= params
->dst_inc
;
4064 dst_x
+= params
->dst_inc
;
4066 err
+= params
->err_add_1
;
4068 else err
+= params
->err_add_2
;
4072 static void shrink_row_null(const dib_info
*dst_dib
, const POINT
*dst_start
,
4073 const dib_info
*src_dib
, const POINT
*src_start
,
4074 const struct stretch_params
*params
, int mode
,
4077 FIXME("bit count %d\n", dst_dib
->bit_count
);
4081 const primitive_funcs funcs_8888
=
4086 colorref_to_pixel_888
,
4088 create_rop_masks_32
,
4093 const primitive_funcs funcs_32
=
4098 colorref_to_pixel_masks
,
4100 create_rop_masks_32
,
4105 const primitive_funcs funcs_24
=
4110 colorref_to_pixel_888
,
4112 create_rop_masks_24
,
4117 const primitive_funcs funcs_555
=
4122 colorref_to_pixel_555
,
4124 create_rop_masks_16
,
4129 const primitive_funcs funcs_16
=
4134 colorref_to_pixel_masks
,
4136 create_rop_masks_16
,
4141 const primitive_funcs funcs_8
=
4146 colorref_to_pixel_colortable
,
4153 const primitive_funcs funcs_4
=
4158 colorref_to_pixel_colortable
,
4165 const primitive_funcs funcs_1
=
4170 colorref_to_pixel_colortable
,
4177 const primitive_funcs funcs_null
=
4182 colorref_to_pixel_null
,
4184 create_rop_masks_null
,