f8f87ce9220f4b2014e5d4a2beeab470d0897087
2 * DIB Engine conversions Primitives
4 * Copyright 2009 Massimo Del Fedele
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
22 #include "wine/port.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(dibdrv
);
28 static inline COLORREF
SwapColors(DWORD c
)
30 return ((c
& 0x0000ff) << 16) | (c
& 0x00ff00) | ((c
& 0xff0000) >> 16);
34 /* ----------------------------------------------------------------*/
35 /* CONVERT PRIMITIVES */
36 /* converts (part of) line of any DIB format from/to DIB32_RGB one */
37 BOOL
_DIBDRV_GetLine32_RGB(const DIBDRVBITMAP
*bmp
, INT line
, INT startx
, int width
, void *buf
)
39 DWORD
*dwBuf
= (DWORD
*)buf
;
42 #ifdef DIBDRV_CHECK_RANGES
44 if(line
< 0 || line
>= bmp
->height
)
52 if(startx
+ width
> bmp
->width
)
53 width
= bmp
->width
- startx
;
58 src
= (DWORD
*)((BYTE
*)bmp
->bits
+ line
* bmp
->stride
+ 4 * startx
);
64 BOOL
_DIBDRV_GetLine32_BITFIELDS(const DIBDRVBITMAP
*bmp
, INT line
, INT startx
, int width
, void *buf
)
66 BYTE
*bBuf
= (BYTE
*)buf
;
69 #ifdef DIBDRV_CHECK_RANGES
71 if(line
< 0 || line
>= bmp
->height
)
79 if(startx
+ width
> bmp
->width
)
80 width
= bmp
->width
- startx
;
85 src
= (DWORD
*)((BYTE
*)bmp
->bits
+ line
* bmp
->stride
+ 4 * startx
);
86 for(; width
; width
--)
88 *bBuf
++ = (*src
& bmp
->blueMask
) >> bmp
->blueShift
;
89 *bBuf
++ = (*src
& bmp
->greenMask
) >> bmp
->greenShift
;
90 *bBuf
++ = (*src
& bmp
->redMask
) >> bmp
->redShift
;
97 BOOL
_DIBDRV_GetLine24(const DIBDRVBITMAP
*bmp
, INT line
, INT startx
, int width
, void *buf
)
99 BYTE
*bBuf
= (BYTE
*)buf
;
102 #ifdef DIBDRV_CHECK_RANGES
104 if(line
< 0 || line
>= bmp
->height
)
112 if(startx
+ width
> bmp
->width
)
113 width
= bmp
->width
- startx
;
118 src
= ((BYTE
*)bmp
->bits
+ line
* bmp
->stride
+ 3 * startx
);
119 for(; width
; width
--)
129 BOOL
_DIBDRV_GetLine16_RGB(const DIBDRVBITMAP
*bmp
, INT line
, INT startx
, int width
, void *buf
)
131 DWORD
*dwBuf
= (DWORD
*)buf
;
135 #ifdef DIBDRV_CHECK_RANGES
137 if(line
< 0 || line
>= bmp
->height
)
145 if(startx
+ width
> bmp
->width
)
146 width
= bmp
->width
- startx
;
151 src
= (WORD
*)((BYTE
*)bmp
->bits
+ line
* bmp
->stride
+ 2 * startx
);
152 for(; width
; width
--)
155 /* 0RRR|RRGG|GGGB|BBBB */
156 *dwBuf
++ = ((b
& 0x1f) << 3) | ((b
& 0x3e0) << 6) | ((b
& 0x7c00) << 9);
161 BOOL
_DIBDRV_GetLine16_BITFIELDS(const DIBDRVBITMAP
*bmp
, INT line
, INT startx
, int width
, void *buf
)
163 DWORD
*dwBuf
= (DWORD
*)buf
;
167 #ifdef DIBDRV_CHECK_RANGES
169 if(line
< 0 || line
>= bmp
->height
)
177 if(startx
+ width
> bmp
->width
)
178 width
= bmp
->width
- startx
;
183 src
= (WORD
*)((BYTE
*)bmp
->bits
+ line
* bmp
->stride
+ 2 * startx
);
184 for(; width
; width
--)
187 *dwBuf
++ =((( b
& bmp
->blueMask
) >> bmp
->blueShift
) << ( 8 - bmp
->blueLen
)) |
188 (((b
& bmp
->greenMask
) >> bmp
->greenShift
) << (16 - bmp
->greenLen
)) |
189 (((b
& bmp
->redMask
) >> bmp
->redShift
) << (24 - bmp
->redLen
));
194 BOOL
_DIBDRV_GetLine8(const DIBDRVBITMAP
*bmp
, INT line
, INT startx
, int width
, void *buf
)
196 DWORD
*dwBuf
= (DWORD
*)buf
;
199 #ifdef DIBDRV_CHECK_RANGES
201 if(line
< 0 || line
>= bmp
->height
)
209 if(startx
+ width
> bmp
->width
)
210 width
= bmp
->width
- startx
;
215 src
= ((BYTE
*)bmp
->bits
+ line
* bmp
->stride
+ startx
);
216 for(; width
; width
--)
217 *dwBuf
++ = *((DWORD
*)bmp
->colorTable
+ *src
++);
221 BOOL
_DIBDRV_GetLine4(const DIBDRVBITMAP
*bmp
, INT line
, INT startx
, int width
, void *buf
)
223 DWORD
*dwBuf
= (DWORD
*)buf
;
226 #ifdef DIBDRV_CHECK_RANGES
228 if(line
< 0 || line
>= bmp
->height
)
236 if(startx
+ width
> bmp
->width
)
237 width
= bmp
->width
- startx
;
242 ERR("Called with uninitialized color table\n");
247 src
= ((BYTE
*)bmp
->bits
+ line
* bmp
->stride
+ (startx
>> 1));
248 /* if startx is odd, get first nibble */
251 *dwBuf
++ = *((DWORD
*)bmp
->colorTable
+ (*src
++ & 0x0f));
255 /* then gets all full image bytes */
256 for( ; width
> 1 ; width
-= 2)
258 *dwBuf
++ = *((DWORD
*)bmp
->colorTable
+ ((*src
>> 4) & 0x0f));
259 *dwBuf
++ = *((DWORD
*)bmp
->colorTable
+ (*src
++ & 0x0f));
262 /* last nibble, if any */
264 *dwBuf
++ = *((DWORD
*)bmp
->colorTable
+ ((*src
>> 4) & 0x0f));
268 BOOL
_DIBDRV_GetLine1(const DIBDRVBITMAP
*bmp
, INT line
, INT startx
, int width
, void *buf
)
270 DWORD
*dwBuf
= (DWORD
*)buf
;
274 DWORD pixOn
= *((DWORD
*)bmp
->colorTable
+ 1);
275 DWORD pixOff
= *(DWORD
*)bmp
->colorTable
;
277 #ifdef DIBDRV_CHECK_RANGES
279 if(line
< 0 || line
>= bmp
->height
)
287 if(startx
+ width
> bmp
->width
)
288 width
= bmp
->width
- startx
;
293 src
= ((BYTE
*)bmp
->bits
+ line
* bmp
->stride
+ (startx
>> 3));
294 /* get first partial byte, if any */
295 startx
= (8 - (startx
& 0x07)) & 0x07;
299 b
= *src
++ << (8 - startx
);
310 /* then gets full next bytes */
311 for( ; width
> 7 ; width
-= 8)
314 for(i
= 0 ; i
< 8 ; i
++)
324 /* last partial byte, if any */
340 BOOL
_DIBDRV_PutLine32_RGB(const DIBDRVBITMAP
*bmp
, INT line
, INT startx
, int width
, void *buf
)
342 DWORD
*dwBuf
= (DWORD
*)buf
;
343 DWORD
*dst
= (DWORD
*)((BYTE
*)bmp
->bits
+ line
* bmp
->stride
+ 4 * startx
);
344 for(; width
; width
--)
349 BOOL
_DIBDRV_PutLine32_BITFIELDS(const DIBDRVBITMAP
*bmp
, INT line
, INT startx
, int width
, void *buf
)
351 DWORD
*dwBuf
= (DWORD
*)buf
;
352 DWORD
*dst
= (DWORD
*)((BYTE
*)bmp
->bits
+ line
* bmp
->stride
+ 4 * startx
);
354 for(; width
; width
--)
358 ((( c
& 0x000000ff) << bmp
->blueShift
) & bmp
->blueMask
) |
359 ((((c
& 0x0000ff00) >> 8) << bmp
->greenShift
) & bmp
->greenMask
) |
360 ((((c
& 0x00ff0000) >> 16) << bmp
->redShift
) & bmp
->redMask
);
365 BOOL
_DIBDRV_PutLine24(const DIBDRVBITMAP
*bmp
, INT line
, INT startx
, int width
, void *buf
)
367 DWORD
*dwBuf
= (DWORD
*)buf
;
368 BYTE
*dst
= ((BYTE
*)bmp
->bits
+ line
* bmp
->stride
+ 3 * startx
);
370 for(; width
; width
--)
373 *dst
++ = c
& 0x000000ff;
374 *dst
++ = (c
& 0x0000ff00) >> 8;
375 *dst
++ = (c
& 0x00ff0000) >> 16;
380 BOOL
_DIBDRV_PutLine16_RGB(const DIBDRVBITMAP
*bmp
, INT line
, INT startx
, int width
, void *buf
)
382 DWORD
*dwBuf
= (DWORD
*)buf
;
383 WORD
*dst
= (WORD
*)((BYTE
*)bmp
->bits
+ line
* bmp
->stride
+ 2 * startx
);
385 for(; width
; width
--)
389 ((c
& 0x000000f8) >> 3) |
390 ((c
& 0x0000f800) >> 6) |
391 ((c
& 0x00f80000) >> 9);
396 BOOL
_DIBDRV_PutLine16_BITFIELDS(const DIBDRVBITMAP
*bmp
, INT line
, INT startx
, int width
, void *buf
)
398 DWORD
*dwBuf
= (DWORD
*)buf
;
399 WORD
*dst
= (WORD
*)((BYTE
*)bmp
->bits
+ line
* bmp
->stride
+ 2 * startx
);
402 BYTE bShift
= 8 - bmp
->blueLen
;
403 BYTE gShift
= 16 - bmp
->greenLen
;
404 BYTE rShift
= 24 - bmp
->redLen
;
405 for(; width
; width
--)
409 ((((c
& 0x000000ff) >> bShift
) << bmp
->blueShift
) & bmp
->blueMask
) |
410 ((((c
& 0x0000ff00) >> gShift
) << bmp
->greenShift
) & bmp
->greenMask
) |
411 ((((c
& 0x00ff0000) >> rShift
) << bmp
->redShift
) & bmp
->redMask
);
416 BOOL
_DIBDRV_PutLine8(const DIBDRVBITMAP
*bmp
, INT line
, INT startx
, int width
, void *buf
)
418 DWORD
*dwBuf
= (DWORD
*)buf
;
419 BYTE
*dst
= ((BYTE
*)bmp
->bits
+ line
* bmp
->stride
+ startx
);
421 DWORD last_color
= 0xffffffff;
424 for(; width
; width
--)
428 /* slight optimization, as images often have many
429 consecutive pixels with same color */
430 if(last_index
== -1 || c
!= last_color
)
432 last_index
= bmp
->funcs
->ColorToPixel(bmp
, SwapColors(c
));
440 BOOL
_DIBDRV_PutLine4(const DIBDRVBITMAP
*bmp
, INT line
, INT startx
, int width
, void *buf
)
442 DWORD
*dwBuf
= (DWORD
*)buf
;
443 BYTE
*dst
= ((BYTE
*)bmp
->bits
+ line
* bmp
->stride
+ (startx
>> 1));
445 DWORD last_color
= 0xffffffff;
448 /* if startx is odd, put first nibble */
453 last_index
= bmp
->funcs
->ColorToPixel(bmp
, SwapColors(c
));
455 *dst
= (*dst
& 0xf0) | last_index
;
460 /* then gets all full image bytes */
461 for( ; width
> 1 ; width
-= 2)
465 /* slight optimization, as images often have many
466 consecutive pixels with same color */
467 if(last_index
== -1 || c
!= last_color
)
469 last_index
= bmp
->funcs
->ColorToPixel(bmp
, SwapColors(c
));
472 *dst
= last_index
<< 4;
476 /* slight optimization, as images often have many
477 consecutive pixels with same color */
478 if(last_index
== -1 || c
!= last_color
)
480 last_index
= bmp
->funcs
->ColorToPixel(bmp
, SwapColors(c
));
483 *dst
++ |= last_index
;
486 /* last nibble, if any */
491 /* slight optimization, as images often have many
492 consecutive pixels with same color */
493 if(last_index
== -1 || c
!= last_color
)
494 last_index
= bmp
->funcs
->ColorToPixel(bmp
, SwapColors(c
));
495 *dst
= (*dst
& 0x0f) | (last_index
<< 4);
500 BOOL
_DIBDRV_PutLine1(const DIBDRVBITMAP
*bmp
, INT line
, INT startx
, int width
, void *buf
)
502 DWORD
*dwBuf
= (DWORD
*)buf
;
503 BYTE
*dst
= ((BYTE
*)bmp
->bits
+ line
* bmp
->stride
+ (startx
>> 3));
508 /* get foreground color */
509 DWORD fore
= *((DWORD
*)bmp
->colorTable
+ 1) & 0x00ffffff;
511 /* put first partial byte, if any */
513 mask
= 0x80 >> startx
;
514 startx
= (8 - startx
) & 0x07;
521 c
= *dwBuf
++ & 0x00ffffff;
522 if(c
== 0x00ffffff || c
== fore
)
531 /* then puts full next bytes */
532 for( ; width
> 7 ; width
-= 8)
536 for(i
= 0 ; i
< 8 ; i
++)
538 c
= *dwBuf
++ & 0x00ffffff;
539 if(c
== 0x00ffffff || c
== fore
)
546 /* last partial byte, if any */
553 c
= *dwBuf
++ & 0x00ffffff;
554 if(c
== 0x00ffffff || c
== fore
)