2 * DIB driver bitmap objects
4 * Copyright 2007 Jesse Allen
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
26 #include "wine/debug.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(dibdrv
);
32 DIBFORMAT
BITMAP_GetFormat( WORD depth
, DWORD compression
)
37 if (compression
== BI_RGB
)
41 if (compression
== BI_RLE4
)
42 WARN("RLE compression not supported yet!\n");
43 else if (compression
== BI_RGB
)
47 if (compression
== BI_RLE8
)
48 WARN("RLE compression not supported yet!\n");
49 else if (compression
== BI_RGB
)
53 if (compression
== BI_BITFIELDS
)
55 else if (compression
== BI_RGB
)
56 return DIBFMT_X1B5G5R5
;
59 if (compression
== BI_RGB
)
63 if (compression
== BI_BITFIELDS
)
65 else if (compression
== BI_RGB
)
66 return DIBFMT_X8B8G8R8
;
69 ERR("unsupported dib format: depth=%d, compression=%d\n", depth
, compression
);
70 return DIBFMT_UNKNOWN
;
73 const DIBFUNCS
*BITMAP_GetDIBFuncs( DIBFORMAT format
)
77 case DIBFMT_DIB1
: return &DIB1_funcs
;
78 case DIBFMT_DIB4
: return &DIB4_funcs
;
79 case DIBFMT_DIB8
: return &DIB8_funcs
;
81 case DIBFMT_DIB16
: return &DIB16_funcs
;
82 case DIBFMT_DIB24
: return &DIB24_funcs
;
84 case DIBFMT_DIB32
: return &DIB32_funcs
;
87 ERR("no support for format %d!\n", format
);
92 const DIBCONVERT
*BITMAP_GetDIBConversions( DIBFORMAT format
)
96 case DIBFMT_DIB1
: return &DIB1_convs
;
97 case DIBFMT_DIB4
: return &DIB4_convs
;
98 case DIBFMT_DIB8
: return &DIB8_convs
;
100 case DIBFMT_DIB16
: return &DIB16_convs
;
101 case DIBFMT_DIB24
: return &DIB24_convs
;
102 case DIBFMT_X8B8G8R8
:
103 case DIBFMT_DIB32
: return &DIB32_convs
;
106 ERR("no support for format %d!\n", format
);
111 void BITMAP_CalcBitfields( DIBDRVBITMAP
*bmp
, WORD depth
)
114 for (i
= 0; i
< 3; i
++)
117 while (!((bmp
->bitfields
[i
] >> x
) & 1) && (x
< depth
))
120 while (((bmp
->bitfields
[i
] >> x
) & 1) && (x
< depth
))
122 bmp
->bf_size
[i
] = x
- bmp
->bf_pos
[i
];
123 if (bmp
->bf_size
[i
] > 8) bmp
->bf_pos
[i
] += 8;
124 bmp
->bf_shift
[i
] = bmp
->bf_size
[i
] < 8 ? 8 - bmp
->bf_size
[i
] : 0;
128 /* BITMAP_Alloc: Alloc DIBDRVBITMAP and initialize to passed-in values. Note: caller is
129 * responsible for proper handling of the color table.
131 DIBDRVBITMAP
*BITMAP_Alloc( DIBFORMAT format
, void *bits
, INT width
, INT height
, INT widthbytes
,
132 INT size
, RGBQUAD
*color_table
, UINT nb_colors
, DWORD
*bitfields
)
134 DIBDRVBITMAP
*bmp
= HeapAlloc( GetProcessHeap(), 0, sizeof(DIBDRVBITMAP
) );
135 if (!bmp
) return NULL
;
137 TRACE("%d %p %d %d %d %p %u %p\n", format
, bits
, width
, height
, widthbytes
, color_table
,
138 nb_colors
, bitfields
);
140 bmp
->format
= format
;
143 bmp
->height
= height
;
144 bmp
->widthbytes
= widthbytes
;
146 bmp
->color_table
= color_table
;
147 bmp
->nb_colors
= nb_colors
;
149 if (format
== DIBFMT_DIB16
|| format
== DIBFMT_DIB32
)
151 bmp
->bitfields
[0] = bitfields
[0];
152 bmp
->bitfields
[1] = bitfields
[1];
153 bmp
->bitfields
[2] = bitfields
[2];
154 BITMAP_CalcBitfields( bmp
, format
== DIBFMT_DIB16
? 16 : 32 );
156 else if (format
== DIBFMT_X1B5G5R5
)
158 bmp
->bitfields
[0] = 0x7c00;
159 bmp
->bitfields
[1] = 0x3e0;
160 bmp
->bitfields
[2] = 0x1f;
161 BITMAP_CalcBitfields( bmp
, 16 );
163 else if (format
== DIBFMT_X8B8G8R8
)
165 bmp
->bitfields
[0] = 0xff0000;
166 bmp
->bitfields
[1] = 0xff00;
167 bmp
->bitfields
[2] = 0xff;
168 BITMAP_CalcBitfields( bmp
, 32 );
174 /***********************************************************************
175 * BITMAP_GetDIBWidthBytes
177 * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
180 int BITMAP_GetDIBWidthBytes( int width
, int depth
)
186 case 1: words
= (width
+ 31) / 32; break;
187 case 4: words
= (width
+ 7) / 8; break;
188 case 8: words
= (width
+ 3) / 4; break;
190 case 16: words
= (width
+ 1) / 2; break;
191 case 24: words
= (width
* 3 + 3)/4; break;
194 WARN("(%d): Unsupported depth\n", depth
);
202 DIBDRVBITMAP
*BITMAP_CreateFromBmi( const BITMAPINFO
*bmi
, void *bits
)
204 DIBFORMAT fmt
= BITMAP_GetFormat( bmi
->bmiHeader
.biBitCount
, bmi
->bmiHeader
.biCompression
);
205 if (!fmt
) return NULL
;
206 return BITMAP_Alloc( fmt
, bits
, bmi
->bmiHeader
.biWidth
,
207 bmi
->bmiHeader
.biHeight
,
208 BITMAP_GetDIBWidthBytes( bmi
->bmiHeader
.biWidth
,
209 bmi
->bmiHeader
.biBitCount
),
210 bmi
->bmiHeader
.biSizeImage
,
211 (RGBQUAD
*)bmi
->bmiColors
,
212 bmi
->bmiHeader
.biClrUsed
,
213 (DWORD
*)bmi
->bmiColors
);
216 DIBDRVBITMAP
*BITMAP_CreateFromHBitmap( HBITMAP hbitmap
, RGBQUAD
*ct
, UINT nb_colors
)
220 if (!GetObjectW( hbitmap
, sizeof(dib
), &dib
)) return NULL
;
222 /* If we get an hbitmap from any GDI call this can mean a few things:
223 * 1) We got a bitmap that is really a DIB, so it's dependent on the DIB engine. This occurs
224 * during SelectBitmap for example, so we can use it then.
225 * 2) We may have gotten a bitmap that was really intended for an actual device, like
226 * winex11. If this does indeed ever happen, we will have to punt back.
227 * 3) The application really committed a fatal error and got DCs mixed up. We will simply have
229 * So we must perform a check whether this is a DDB no matter what we think it might be.
231 if (!dib
.dsBm
.bmBits
)
233 /* When this is a DDB, we don't handle it right now so we will print
234 * an error to inform the user, and fail.
236 ERR("hbitmap is actually a DDB and there is no way to handle this yet\n");
240 fmt
= BITMAP_GetFormat( dib
.dsBmih
.biBitCount
, dib
.dsBmih
.biCompression
);
241 if (!fmt
) return NULL
;
243 return BITMAP_Alloc( fmt
, dib
.dsBm
.bmBits
, dib
.dsBmih
.biWidth
, dib
.dsBmih
.biHeight
,
244 dib
.dsBm
.bmWidthBytes
, dib
.dsBmih
.biSizeImage
, ct
, nb_colors
,
248 /***********************************************************************
249 * DIBDRV_SelectBitmap
251 HBITMAP
DIBDRV_SelectBitmap( DIBDRVPHYSDEV
*physDev
, HBITMAP hbitmap
, RGBQUAD
*color_table
,
256 TRACE("%p, %p\n", physDev
, hbitmap
);
260 /* make a copy of the color table */
261 ct
= HeapAlloc( GetProcessHeap(), 0, sizeof(RGBQUAD
)*nb_colors
);
263 memcpy( ct
, color_table
, sizeof(RGBQUAD
)*nb_colors
);
267 bmp
= BITMAP_CreateFromHBitmap( hbitmap
, ct
, nb_colors
);
270 HeapFree( GetProcessHeap(), 0, ct
);
274 /* Since we have a valid DIB, we can now write over the old one */
275 physDev
->hbitmap
= hbitmap
;
278 if (physDev
->bmp
->color_table
)
279 HeapFree( GetProcessHeap(), 0, physDev
->bmp
->color_table
);
280 HeapFree( GetProcessHeap(), 0, physDev
->bmp
);
283 physDev
->funcs
= BITMAP_GetDIBFuncs( bmp
->format
);
284 physDev
->convs
= BITMAP_GetDIBConversions( bmp
->format
);
289 /****************************************************************************
290 * DIBDRV_CreateBitmap
292 BOOL
DIBDRV_CreateBitmap( DIBDRVPHYSDEV
*physDev
, HBITMAP hbitmap
, LPVOID bmBits
)
298 /***********************************************************************
299 * DIBDRV_DeleteBitmap
301 BOOL
DIBDRV_DeleteBitmap( HBITMAP hbitmap
)
307 /***********************************************************************
308 * DIBDRV_GetBitmapBits
310 LONG
DIBDRV_GetBitmapBits( HBITMAP hbitmap
, void *buffer
, LONG count
)
316 /******************************************************************************
317 * DIBDRV_SetBitmapBits
319 LONG
DIBDRV_SetBitmapBits( HBITMAP hbitmap
, const void *bits
, LONG count
)