Leptonica 1.68
C Image Processing Library
|
00001 /*====================================================================* 00002 - Copyright (C) 2001 Leptonica. All rights reserved. 00003 - This software is distributed in the hope that it will be 00004 - useful, but with NO WARRANTY OF ANY KIND. 00005 - No author or distributor accepts responsibility to anyone for the 00006 - consequences of using this software, or for whether it serves any 00007 - particular purpose or works at all, unless he or she says so in 00008 - writing. Everyone is granted permission to copy, modify and 00009 - redistribute this source code, for commercial or non-commercial 00010 - purposes, with the following restrictions: (1) the origin of this 00011 - source code must not be misrepresented; (2) modified versions must 00012 - be plainly marked as such; and (3) this notice may not be removed 00013 - or altered from any source or modified source distribution. 00014 *====================================================================*/ 00015 00016 /* 00017 * leptwin.c 00018 * 00019 * This file contains Leptonica routines needed only on Microsoft Windows 00020 * 00021 * Currently it only contains one public function 00022 * (based on dibsectn.c by jmh, 03-30-98): 00023 * 00024 * HBITMAP pixGetWindowsHBITMAP(PIX *pix) 00025 */ 00026 00027 #ifdef _WIN32 00028 #include <stdlib.h> 00029 #include <string.h> 00030 #include "allheaders.h" 00031 #include "leptwin.h" 00032 00033 /* Macro to determine the number of bytes per line in the DIB bits. 00034 * This accounts for DWORD alignment by adding 31 bits, 00035 * then dividing by 32, then rounding up to the next highest 00036 * count of 4-bytes. Then, we multiply by 4 to get the total byte count. */ 00037 #define BYTESPERLINE(Width, BPP) ((l_int32)((((DWORD)(Width) * (DWORD)(BPP) + 31) >> 5)) << 2) 00038 00039 00040 /* ********************************************************************** 00041 DWORD DSImageBitsSize(LPBITMAPINFO pbmi) 00042 00043 PARAMETERS: 00044 LPBITMAPINFO - pointer to a BITMAPINFO describing a DIB 00045 00046 RETURNS: 00047 DWORD - the size, in bytes, of the DIB's image bits 00048 00049 REMARKS: 00050 Calculates and returns the size, in bytes, of the image bits for 00051 the DIB described by the BITMAPINFO. 00052 ********************************************************************** */ 00053 static DWORD 00054 DSImageBitsSize(LPBITMAPINFO pbmi) 00055 { 00056 switch(pbmi->bmiHeader.biCompression) 00057 { 00058 case BI_RLE8: /* wrong if haven't called DSCreateDIBSection or 00059 * CreateDIBSection with this pbmi */ 00060 case BI_RLE4: 00061 return pbmi->bmiHeader.biSizeImage; 00062 break; 00063 default: /* should not have to use "default" */ 00064 case BI_RGB: 00065 case BI_BITFIELDS: 00066 return BYTESPERLINE(pbmi->bmiHeader.biWidth, \ 00067 pbmi->bmiHeader.biBitCount * pbmi->bmiHeader.biPlanes) * 00068 pbmi->bmiHeader.biHeight; 00069 break; 00070 } 00071 return 0; 00072 } 00073 00074 /* ********************************************************************** 00075 DWORD ImageBitsSize(HBITMAP hbitmap) 00076 00077 PARAMETERS: 00078 HBITMAP - hbitmap 00079 00080 RETURNS: 00081 DWORD - the size, in bytes, of the HBITMAP's image bits 00082 00083 REMARKS: 00084 Calculates and returns the size, in bytes, of the image bits for 00085 the DIB described by the HBITMAP. 00086 ********************************************************************** */ 00087 static DWORD 00088 ImageBitsSize(HBITMAP hBitmap) 00089 { 00090 DIBSECTION ds; 00091 00092 GetObject(hBitmap, sizeof(DIBSECTION), &ds); 00093 switch( ds.dsBmih.biCompression ) 00094 { 00095 case BI_RLE8: /* wrong if haven't called DSCreateDIBSection or 00096 * CreateDIBSection with this pbmi */ 00097 case BI_RLE4: 00098 return ds.dsBmih.biSizeImage; 00099 break; 00100 default: /* should not have to use "default" */ 00101 case BI_RGB: 00102 case BI_BITFIELDS: 00103 return BYTESPERLINE(ds.dsBmih.biWidth, \ 00104 ds.dsBmih.biBitCount * ds.dsBmih.biPlanes) * 00105 ds.dsBmih.biHeight; 00106 break; 00107 } 00108 return 0; 00109 } 00110 00111 /*! 00112 * setColormap(LPBITMAPINFO pbmi, PIXCMAP *cmap) 00113 * 00114 * Input: pbmi (pointer to a BITMAPINFO describing a DIB) 00115 * cmap (leptonica colormap) 00116 * Return: number of colors in cmap 00117 */ 00118 static int 00119 setColormap(LPBITMAPINFO pbmi, 00120 PIXCMAP *cmap) 00121 { 00122 l_int32 i, nColors, rval, gval, bval; 00123 00124 nColors = pixcmapGetCount(cmap); 00125 for (i = 0; i < nColors; i++) { 00126 pixcmapGetColor(cmap, i, &rval, &gval, &bval); 00127 pbmi->bmiColors[i].rgbRed = rval; 00128 pbmi->bmiColors[i].rgbGreen = gval; 00129 pbmi->bmiColors[i].rgbBlue = bval; 00130 pbmi->bmiColors[i].rgbReserved = 0; 00131 } 00132 pbmi->bmiHeader.biClrUsed = nColors; 00133 return nColors; 00134 } 00135 00136 /* ********************************************************************** 00137 HBITMAP DSCreateBitmapInfo(l_int32 width, l_int32 height, l_int32 depth, 00138 PIXCMAP *cmap) 00139 00140 PARAMETERS: 00141 l_int32 width - Desired width of the DIBSection 00142 l_int32 height - Desired height of the DIBSection 00143 l_int32 depth - Desired bit-depth of the DIBSection 00144 PIXCMAP cmap - leptonica colormap for depths < 16 00145 00146 RETURNS: 00147 LPBITMAPINFO - a ptr to BITMAPINFO of the desired size and bit-depth 00148 NULL on failure 00149 00150 REMARKS: 00151 Creates a BITMAPINFO based on the criteria passed in as parameters. 00152 00153 ********************************************************************** */ 00154 static LPBITMAPINFO 00155 DSCreateBitmapInfo(l_int32 width, 00156 l_int32 height, 00157 l_int32 depth, 00158 PIXCMAP *cmap) 00159 { 00160 l_int32 nInfoSize; 00161 LPBITMAPINFO pbmi; 00162 LPDWORD pMasks; 00163 00164 nInfoSize = sizeof(BITMAPINFOHEADER); 00165 if( depth <= 8 ) 00166 nInfoSize += sizeof(RGBQUAD) * (1 << depth); 00167 if((depth == 16) || (depth == 32)) 00168 nInfoSize += (3 * sizeof(DWORD)); 00169 00170 /* Create the header big enough to contain color table and 00171 * bitmasks if needed. */ 00172 pbmi = (LPBITMAPINFO)malloc(nInfoSize); 00173 if (!pbmi) 00174 return NULL; 00175 00176 ZeroMemory(pbmi, nInfoSize); 00177 pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 00178 pbmi->bmiHeader.biWidth = width; 00179 pbmi->bmiHeader.biHeight = height; 00180 pbmi->bmiHeader.biPlanes = 1; 00181 pbmi->bmiHeader.biBitCount = depth; 00182 00183 /* override below for 16 and 32 bpp */ 00184 pbmi->bmiHeader.biCompression = BI_RGB; 00185 00186 /* ?? not sure if this is right? */ 00187 pbmi->bmiHeader.biSizeImage = DSImageBitsSize(pbmi); 00188 00189 pbmi->bmiHeader.biXPelsPerMeter = 0; 00190 pbmi->bmiHeader.biYPelsPerMeter = 0; 00191 pbmi->bmiHeader.biClrUsed = 0; /* override below */ 00192 pbmi->bmiHeader.biClrImportant = 0; 00193 00194 switch(depth) 00195 { 00196 case 24: 00197 /* 24bpp requires no special handling */ 00198 break; 00199 case 16: 00200 /* if it's 16bpp, fill in the masks and override the 00201 * compression. These are the default masks -- you 00202 * could change them if needed. */ 00203 pMasks = (LPDWORD)(pbmi->bmiColors); 00204 pMasks[0] = 0x00007c00; 00205 pMasks[1] = 0x000003e0; 00206 pMasks[2] = 0x0000001f; 00207 pbmi->bmiHeader.biCompression = BI_BITFIELDS; 00208 break; 00209 case 32: 00210 /* if it's 32 bpp, fill in the masks and override 00211 * the compression */ 00212 pMasks = (LPDWORD)(pbmi->bmiColors); 00213 /*pMasks[0] = 0x00ff0000; */ 00214 /*pMasks[1] = 0x0000ff00; */ 00215 /*pMasks[2] = 0x000000ff; */ 00216 pMasks[0] = 0xff000000; 00217 pMasks[1] = 0x00ff0000; 00218 pMasks[2] = 0x0000ff00; 00219 00220 pbmi->bmiHeader.biCompression = BI_BITFIELDS; 00221 break; 00222 case 8: 00223 case 4: 00224 case 1: 00225 setColormap(pbmi, cmap); 00226 break; 00227 } 00228 return pbmi; 00229 } 00230 00231 /* ********************************************************************** 00232 HBITMAP DSCreateDIBSection(l_int32 width, l_int32 height, l_int32 depth, 00233 PIXCMAP *cmap) 00234 00235 PARAMETERS: 00236 l_int32 width - Desired width of the DIBSection 00237 l_int32 height - Desired height of the DIBSection 00238 l_int32 depth - Desired bit-depth of the DIBSection 00239 PIXCMAP cmap - leptonica colormap for depths < 16 00240 00241 RETURNS: 00242 HBITMAP - a DIBSection HBITMAP of the desired size and bit-depth 00243 NULL on failure 00244 00245 REMARKS: 00246 Creates a DIBSection based on the criteria passed in as parameters. 00247 00248 ********************************************************************** */ 00249 static HBITMAP 00250 DSCreateDIBSection(l_int32 width, 00251 l_int32 height, 00252 l_int32 depth, 00253 PIXCMAP *cmap) 00254 { 00255 HBITMAP hBitmap; 00256 l_int32 nInfoSize; 00257 LPBITMAPINFO pbmi; 00258 HDC hRefDC; 00259 LPBYTE pBits; 00260 00261 pbmi = DSCreateBitmapInfo (width, height, depth, cmap); 00262 if (!pbmi) 00263 return NULL; 00264 00265 hRefDC = GetDC(NULL); 00266 hBitmap = CreateDIBSection(hRefDC, pbmi, DIB_RGB_COLORS, 00267 (void **) &pBits, NULL, 0); 00268 nInfoSize = GetLastError(); 00269 ReleaseDC(NULL, hRefDC); 00270 free(pbmi); 00271 00272 return hBitmap; 00273 } 00274 00275 00276 /*! 00277 * pixGetWindowsHBITMAP() 00278 * 00279 * Input: pix 00280 * Return: Windows hBitmap, or null on error 00281 * 00282 * Notes: 00283 * (1) It's the responsibility of the caller to destroy the 00284 * returned hBitmap with a call to DeleteObject (or with 00285 * something that eventually calls DeleteObject). 00286 */ 00287 HBITMAP 00288 pixGetWindowsHBITMAP(PIX *pix) 00289 { 00290 l_int32 width, height, depth; 00291 l_uint32 *data; 00292 HBITMAP hBitmap = NULL; 00293 BITMAP bm; 00294 DWORD imageBitsSize; 00295 PIX *pixt = NULL; 00296 PIXCMAP *cmap; 00297 00298 PROCNAME("pixGetWindowsHBITMAP"); 00299 if (!pix) 00300 return (HBITMAP)ERROR_PTR("pix not defined", procName, NULL); 00301 00302 pixGetDimensions(pix, &width, &height, &depth); 00303 cmap = pixGetColormap(pix); 00304 00305 if (depth == 24) depth = 32; 00306 if (depth == 2) { 00307 pixt = pixConvert2To8(pix, 0, 85, 170, 255, TRUE); 00308 if (!pixt) 00309 return (HBITMAP)ERROR_PTR("unable to convert pix from 2bpp to 8bpp", 00310 procName, NULL); 00311 depth = pixGetDepth(pixt); 00312 cmap = pixGetColormap(pixt); 00313 } 00314 00315 if (depth < 16) { 00316 if (!cmap) 00317 cmap = pixcmapCreateLinear(depth, 1<<depth); 00318 } 00319 00320 hBitmap = DSCreateDIBSection(width, height, depth, cmap); 00321 if (!hBitmap) 00322 return (HBITMAP)ERROR_PTR("Unable to create HBITMAP", procName, NULL); 00323 00324 /* By default, Windows assumes bottom up images */ 00325 if (pixt) 00326 pixt = pixFlipTB(pixt, pixt); 00327 else 00328 pixt = pixFlipTB(NULL, pix); 00329 00330 /* "standard" color table assumes bit off=black */ 00331 if (depth == 1) { 00332 pixInvert(pixt, pixt); 00333 } 00334 00335 /* Don't byte swap until done manipulating pix! */ 00336 if (depth <= 16) 00337 pixEndianByteSwap(pixt); 00338 00339 GetObject (hBitmap, sizeof(BITMAP), &bm); 00340 imageBitsSize = ImageBitsSize(hBitmap); 00341 data = pixGetData(pixt); 00342 if (data) { 00343 memcpy (bm.bmBits, data, imageBitsSize); 00344 } else { 00345 DeleteObject (hBitmap); 00346 hBitmap = NULL; 00347 } 00348 pixDestroy(&pixt); 00349 00350 return hBitmap; 00351 } 00352 00353 #endif /* _WIN32 */