Leptonica 1.68
C Image Processing Library

leptwin.c

Go to the documentation of this file.
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 */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines