Leptonica 1.82.0
Image processing and image analysis suite
leptwin.c
Go to the documentation of this file.
1/*====================================================================*
2 - Copyright (C) 2001 Leptonica. All rights reserved.
3 -
4 - Redistribution and use in source and binary forms, with or without
5 - modification, are permitted provided that the following conditions
6 - are met:
7 - 1. Redistributions of source code must retain the above copyright
8 - notice, this list of conditions and the following disclaimer.
9 - 2. Redistributions in binary form must reproduce the above
10 - copyright notice, this list of conditions and the following
11 - disclaimer in the documentation and/or other materials
12 - provided with the distribution.
13 -
14 - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
18 - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *====================================================================*/
26
40#ifdef _WIN32
41#include <stdlib.h>
42#include <string.h>
43#include "allheaders.h"
44#include "leptwin.h"
45
46/* Macro to determine the number of bytes per line in the DIB bits.
47 * This accounts for DWORD alignment by adding 31 bits,
48 * then dividing by 32, then rounding up to the next highest
49 * count of 4-bytes. Then, we multiply by 4 to get the total byte count. */
50#define BYTESPERLINE(Width, BPP) ((l_int32)((((DWORD)(Width) * (DWORD)(BPP) + 31) >> 5)) << 2)
51
52
53/* **********************************************************************
54 DWORD DSImageBitsSize(LPBITMAPINFO pbmi)
55
56 PARAMETERS:
57 LPBITMAPINFO - pointer to a BITMAPINFO describing a DIB
58
59 RETURNS:
60 DWORD - the size, in bytes, of the DIB's image bits
61
62 REMARKS:
63 Calculates and returns the size, in bytes, of the image bits for
64 the DIB described by the BITMAPINFO.
65********************************************************************** */
66static DWORD
67DSImageBitsSize(LPBITMAPINFO pbmi)
68{
69 switch(pbmi->bmiHeader.biCompression)
70 {
71 case BI_RLE8: /* wrong if haven't called DSCreateDIBSection or
72 * CreateDIBSection with this pbmi */
73 case BI_RLE4:
74 return pbmi->bmiHeader.biSizeImage;
75 break;
76 default: /* should not have to use "default" */
77 case BI_RGB:
78 case BI_BITFIELDS:
79 return BYTESPERLINE(pbmi->bmiHeader.biWidth, \
80 pbmi->bmiHeader.biBitCount * pbmi->bmiHeader.biPlanes) *
81 pbmi->bmiHeader.biHeight;
82 break;
83 }
84 return 0;
85}
86
87/* **********************************************************************
88 DWORD ImageBitsSize(HBITMAP hbitmap)
89
90 PARAMETERS:
91 HBITMAP - hbitmap
92
93 RETURNS:
94 DWORD - the size, in bytes, of the HBITMAP's image bits
95
96 REMARKS:
97 Calculates and returns the size, in bytes, of the image bits for
98 the DIB described by the HBITMAP.
99********************************************************************** */
100static DWORD
101ImageBitsSize(HBITMAP hBitmap)
102{
103 DIBSECTION ds;
104
105 GetObject(hBitmap, sizeof(DIBSECTION), &ds);
106 switch( ds.dsBmih.biCompression )
107 {
108 case BI_RLE8: /* wrong if haven't called DSCreateDIBSection or
109 * CreateDIBSection with this pbmi */
110 case BI_RLE4:
111 return ds.dsBmih.biSizeImage;
112 break;
113 default: /* should not have to use "default" */
114 case BI_RGB:
115 case BI_BITFIELDS:
116 return BYTESPERLINE(ds.dsBmih.biWidth, \
117 ds.dsBmih.biBitCount * ds.dsBmih.biPlanes) *
118 ds.dsBmih.biHeight;
119 break;
120 }
121 return 0;
122}
123
131static int
132setColormap(LPBITMAPINFO pbmi,
133 PIXCMAP *cmap)
134{
135l_int32 i, nColors, rval, gval, bval;
136
137 nColors = pixcmapGetCount(cmap);
138 for (i = 0; i < nColors; i++) {
139 pixcmapGetColor(cmap, i, &rval, &gval, &bval);
140 pbmi->bmiColors[i].rgbRed = rval;
141 pbmi->bmiColors[i].rgbGreen = gval;
142 pbmi->bmiColors[i].rgbBlue = bval;
143 pbmi->bmiColors[i].rgbReserved = 0;
144 }
145 pbmi->bmiHeader.biClrUsed = nColors;
146 return nColors;
147}
148
149/* **********************************************************************
150 HBITMAP DSCreateBitmapInfo(l_int32 width, l_int32 height, l_int32 depth,
151 PIXCMAP *cmap)
152
153 PARAMETERS:
154 l_int32 width - Desired width of the DIBSection
155 l_int32 height - Desired height of the DIBSection
156 l_int32 depth - Desired bit-depth of the DIBSection
157 PIXCMAP cmap - leptonica colormap for depths < 16
158
159 RETURNS:
160 LPBITMAPINFO - a ptr to BITMAPINFO of the desired size and bit-depth
161 NULL on failure
162
163 REMARKS:
164 Creates a BITMAPINFO based on the criteria passed in as parameters.
165
166********************************************************************** */
167static LPBITMAPINFO
168DSCreateBitmapInfo(l_int32 width,
169 l_int32 height,
170 l_int32 depth,
171 PIXCMAP *cmap)
172{
173l_int32 nInfoSize;
174LPBITMAPINFO pbmi;
175LPDWORD pMasks;
176
177 nInfoSize = sizeof(BITMAPINFOHEADER);
178 if( depth <= 8 )
179 nInfoSize += sizeof(RGBQUAD) * (1 << depth);
180 if((depth == 16) || (depth == 32))
181 nInfoSize += (3 * sizeof(DWORD));
182
183 /* Create the header big enough to contain color table and
184 * bitmasks if needed. */
185 pbmi = (LPBITMAPINFO)malloc(nInfoSize);
186 if (!pbmi)
187 return NULL;
188
189 ZeroMemory(pbmi, nInfoSize);
190 pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
191 pbmi->bmiHeader.biWidth = width;
192 pbmi->bmiHeader.biHeight = height;
193 pbmi->bmiHeader.biPlanes = 1;
194 pbmi->bmiHeader.biBitCount = depth;
195
196 /* override below for 16 and 32 bpp */
197 pbmi->bmiHeader.biCompression = BI_RGB;
198
199 /* ?? not sure if this is right? */
200 pbmi->bmiHeader.biSizeImage = DSImageBitsSize(pbmi);
201
202 pbmi->bmiHeader.biXPelsPerMeter = 0;
203 pbmi->bmiHeader.biYPelsPerMeter = 0;
204 pbmi->bmiHeader.biClrUsed = 0; /* override below */
205 pbmi->bmiHeader.biClrImportant = 0;
206
207 switch(depth)
208 {
209 case 24:
210 /* 24bpp requires no special handling */
211 break;
212 case 16:
213 /* if it's 16bpp, fill in the masks and override the
214 * compression. These are the default masks -- you
215 * could change them if needed. */
216 pMasks = (LPDWORD)(pbmi->bmiColors);
217 pMasks[0] = 0x00007c00;
218 pMasks[1] = 0x000003e0;
219 pMasks[2] = 0x0000001f;
220 pbmi->bmiHeader.biCompression = BI_BITFIELDS;
221 break;
222 case 32:
223 /* if it's 32 bpp, fill in the masks and override
224 * the compression */
225 pMasks = (LPDWORD)(pbmi->bmiColors);
226 /*pMasks[0] = 0x00ff0000; */
227 /*pMasks[1] = 0x0000ff00; */
228 /*pMasks[2] = 0x000000ff; */
229 pMasks[0] = 0xff000000;
230 pMasks[1] = 0x00ff0000;
231 pMasks[2] = 0x0000ff00;
232
233 pbmi->bmiHeader.biCompression = BI_BITFIELDS;
234 break;
235 case 8:
236 case 4:
237 case 1:
238 setColormap(pbmi, cmap);
239 break;
240 }
241 return pbmi;
242}
243
244/* **********************************************************************
245 HBITMAP DSCreateDIBSection(l_int32 width, l_int32 height, l_int32 depth,
246 PIXCMAP *cmap)
247
248 PARAMETERS:
249 l_int32 width - Desired width of the DIBSection
250 l_int32 height - Desired height of the DIBSection
251 l_int32 depth - Desired bit-depth of the DIBSection
252 PIXCMAP cmap - leptonica colormap for depths < 16
253
254 RETURNS:
255 HBITMAP - a DIBSection HBITMAP of the desired size and bit-depth
256 NULL on failure
257
258 REMARKS:
259 Creates a DIBSection based on the criteria passed in as parameters.
260
261********************************************************************** */
262static HBITMAP
263DSCreateDIBSection(l_int32 width,
264 l_int32 height,
265 l_int32 depth,
266 PIXCMAP *cmap)
267{
268HBITMAP hBitmap;
269l_int32 nInfoSize;
270LPBITMAPINFO pbmi;
271HDC hRefDC;
272LPBYTE pBits;
273
274 pbmi = DSCreateBitmapInfo (width, height, depth, cmap);
275 if (!pbmi)
276 return NULL;
277
278 hRefDC = GetDC(NULL);
279 hBitmap = CreateDIBSection(hRefDC, pbmi, DIB_RGB_COLORS,
280 (void **) &pBits, NULL, 0);
281 nInfoSize = GetLastError();
282 ReleaseDC(NULL, hRefDC);
283 free(pbmi);
284
285 return hBitmap;
286}
287
288
302HBITMAP
303pixGetWindowsHBITMAP(PIX *pix)
304{
305l_int32 width, height, depth;
306l_uint32 *data;
307HBITMAP hBitmap = NULL;
308BITMAP bm;
309DWORD imageBitsSize;
310PIX *pixt = NULL;
311PIXCMAP *cmap;
312
313 PROCNAME("pixGetWindowsHBITMAP");
314 if (!pix)
315 return (HBITMAP)ERROR_PTR("pix not defined", procName, NULL);
316
317 pixGetDimensions(pix, &width, &height, &depth);
318 cmap = pixGetColormap(pix);
319
320 if (depth == 24) depth = 32;
321 if (depth == 2) {
322 pixt = pixConvert2To8(pix, 0, 85, 170, 255, TRUE);
323 if (!pixt)
324 return (HBITMAP)ERROR_PTR("unable to convert pix from 2bpp to 8bpp",
325 procName, NULL);
326 depth = pixGetDepth(pixt);
327 cmap = pixGetColormap(pixt);
328 }
329
330 if (depth < 16) {
331 if (!cmap)
332 cmap = pixcmapCreateLinear(depth, 1<<depth);
333 }
334
335 hBitmap = DSCreateDIBSection(width, height, depth, cmap);
336 if (!hBitmap)
337 return (HBITMAP)ERROR_PTR("Unable to create HBITMAP", procName, NULL);
338
339 /* By default, Windows assumes bottom up images */
340 if (pixt)
341 pixt = pixFlipTB(pixt, pixt);
342 else
343 pixt = pixFlipTB(NULL, pix);
344
345 /* "standard" color table assumes bit off=black */
346 if (depth == 1) {
347 pixInvert(pixt, pixt);
348 }
349
350 /* Don't byte swap until done manipulating pix! */
351 if (depth <= 16)
352 pixEndianByteSwap(pixt);
353
354 GetObject (hBitmap, sizeof(BITMAP), &bm);
355 imageBitsSize = ImageBitsSize(hBitmap);
356 data = pixGetData(pixt);
357 if (data) {
358 memcpy (bm.bmBits, data, imageBitsSize);
359 } else {
360 DeleteObject (hBitmap);
361 hBitmap = NULL;
362 }
363 pixDestroy(&pixt);
364
365 return hBitmap;
366}
367
368#endif /* _WIN32 */
l_int32 pixcmapGetCount(const PIXCMAP *cmap)
pixcmapGetCount()
Definition: colormap.c:708
PIXCMAP * pixcmapCreateLinear(l_int32 d, l_int32 nlevels)
pixcmapCreateLinear()
Definition: colormap.c:218
l_ok pixcmapGetColor(PIXCMAP *cmap, l_int32 index, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
pixcmapGetColor()
Definition: colormap.c:824
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:621
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1113
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1763
l_ok pixEndianByteSwap(PIX *pixs)
pixEndianByteSwap()
Definition: pix2.c:3074
PIX * pixInvert(PIX *pixd, PIX *pixs)
pixInvert()
Definition: pix3.c:1509
PIX * pixConvert2To8(PIX *pixs, l_uint8 val0, l_uint8 val1, l_uint8 val2, l_uint8 val3, l_int32 cmapflag)
pixConvert2To8()
Definition: pixconv.c:2492
PIX * pixFlipTB(PIX *pixd, PIX *pixs)
pixFlipTB()
Definition: rotateorth.c:605
Definition: pix.h:139