Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/leptonica/src/leptwin.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 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 | |
| 27 /*! | |
| 28 * \file leptwin.c | |
| 29 * <pre> | |
| 30 * | |
| 31 * This file contains Leptonica routines needed only on Microsoft Windows | |
| 32 * | |
| 33 * Currently it only contains one public function | |
| 34 * (based on dibsectn.c by jmh, 03-30-98): | |
| 35 * | |
| 36 * HBITMAP pixGetWindowsHBITMAP(PIX *pix) | |
| 37 * </pre> | |
| 38 */ | |
| 39 | |
| 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 ********************************************************************** */ | |
| 66 static DWORD | |
| 67 DSImageBitsSize(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 | |
| 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 } | |
| 83 } | |
| 84 | |
| 85 /* ********************************************************************** | |
| 86 DWORD ImageBitsSize(HBITMAP hbitmap) | |
| 87 | |
| 88 PARAMETERS: | |
| 89 HBITMAP - hbitmap | |
| 90 | |
| 91 RETURNS: | |
| 92 DWORD - the size, in bytes, of the HBITMAP's image bits | |
| 93 | |
| 94 REMARKS: | |
| 95 Calculates and returns the size, in bytes, of the image bits for | |
| 96 the DIB described by the HBITMAP. | |
| 97 ********************************************************************** */ | |
| 98 static DWORD | |
| 99 ImageBitsSize(HBITMAP hBitmap) | |
| 100 { | |
| 101 DIBSECTION ds; | |
| 102 | |
| 103 GetObject(hBitmap, sizeof(DIBSECTION), &ds); | |
| 104 switch( ds.dsBmih.biCompression ) | |
| 105 { | |
| 106 case BI_RLE8: /* wrong if haven't called DSCreateDIBSection or | |
| 107 * CreateDIBSection with this pbmi */ | |
| 108 case BI_RLE4: | |
| 109 return ds.dsBmih.biSizeImage; | |
| 110 | |
| 111 default: /* should not have to use "default" */ | |
| 112 case BI_RGB: | |
| 113 case BI_BITFIELDS: | |
| 114 return BYTESPERLINE(ds.dsBmih.biWidth, \ | |
| 115 ds.dsBmih.biBitCount * ds.dsBmih.biPlanes) * | |
| 116 ds.dsBmih.biHeight; | |
| 117 } | |
| 118 } | |
| 119 | |
| 120 /*! | |
| 121 * \brief setColormap(LPBITMAPINFO pbmi, PIXCMAP *cmap) | |
| 122 * | |
| 123 * \param[in] pbmi pointer to a BITMAPINFO describing a DIB | |
| 124 * \param[in] cmap leptonica colormap | |
| 125 * \return number of colors in cmap | |
| 126 */ | |
| 127 static int | |
| 128 setColormap(LPBITMAPINFO pbmi, | |
| 129 PIXCMAP *cmap) | |
| 130 { | |
| 131 l_int32 i, nColors, rval, gval, bval; | |
| 132 | |
| 133 nColors = pixcmapGetCount(cmap); | |
| 134 for (i = 0; i < nColors; i++) { | |
| 135 pixcmapGetColor(cmap, i, &rval, &gval, &bval); | |
| 136 pbmi->bmiColors[i].rgbRed = rval; | |
| 137 pbmi->bmiColors[i].rgbGreen = gval; | |
| 138 pbmi->bmiColors[i].rgbBlue = bval; | |
| 139 pbmi->bmiColors[i].rgbReserved = 0; | |
| 140 } | |
| 141 pbmi->bmiHeader.biClrUsed = nColors; | |
| 142 return nColors; | |
| 143 } | |
| 144 | |
| 145 /* ********************************************************************** | |
| 146 HBITMAP DSCreateBitmapInfo(l_int32 width, l_int32 height, l_int32 depth, | |
| 147 PIXCMAP *cmap) | |
| 148 | |
| 149 PARAMETERS: | |
| 150 l_int32 width - Desired width of the DIBSection | |
| 151 l_int32 height - Desired height of the DIBSection | |
| 152 l_int32 depth - Desired bit-depth of the DIBSection | |
| 153 PIXCMAP cmap - leptonica colormap for depths < 16 | |
| 154 | |
| 155 RETURNS: | |
| 156 LPBITMAPINFO - a ptr to BITMAPINFO of the desired size and bit-depth | |
| 157 NULL on failure | |
| 158 | |
| 159 REMARKS: | |
| 160 Creates a BITMAPINFO based on the criteria passed in as parameters. | |
| 161 | |
| 162 ********************************************************************** */ | |
| 163 static LPBITMAPINFO | |
| 164 DSCreateBitmapInfo(l_int32 width, | |
| 165 l_int32 height, | |
| 166 l_int32 depth, | |
| 167 PIXCMAP *cmap) | |
| 168 { | |
| 169 l_int32 nInfoSize; | |
| 170 LPBITMAPINFO pbmi; | |
| 171 LPDWORD pMasks; | |
| 172 | |
| 173 nInfoSize = sizeof(BITMAPINFOHEADER); | |
| 174 if( depth <= 8 ) | |
| 175 nInfoSize += sizeof(RGBQUAD) * (1 << depth); | |
| 176 if((depth == 16) || (depth == 32)) | |
| 177 nInfoSize += (3 * sizeof(DWORD)); | |
| 178 | |
| 179 /* Create the header big enough to contain color table and | |
| 180 * bitmasks if needed. */ | |
| 181 pbmi = (LPBITMAPINFO)malloc(nInfoSize); | |
| 182 if (!pbmi) | |
| 183 return NULL; | |
| 184 | |
| 185 ZeroMemory(pbmi, nInfoSize); | |
| 186 pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); | |
| 187 pbmi->bmiHeader.biWidth = width; | |
| 188 pbmi->bmiHeader.biHeight = height; | |
| 189 pbmi->bmiHeader.biPlanes = 1; | |
| 190 pbmi->bmiHeader.biBitCount = depth; | |
| 191 | |
| 192 /* override below for 16 and 32 bpp */ | |
| 193 pbmi->bmiHeader.biCompression = BI_RGB; | |
| 194 | |
| 195 /* ?? not sure if this is right? */ | |
| 196 pbmi->bmiHeader.biSizeImage = DSImageBitsSize(pbmi); | |
| 197 | |
| 198 pbmi->bmiHeader.biXPelsPerMeter = 0; | |
| 199 pbmi->bmiHeader.biYPelsPerMeter = 0; | |
| 200 pbmi->bmiHeader.biClrUsed = 0; /* override below */ | |
| 201 pbmi->bmiHeader.biClrImportant = 0; | |
| 202 | |
| 203 switch(depth) | |
| 204 { | |
| 205 case 24: | |
| 206 /* 24bpp requires no special handling */ | |
| 207 break; | |
| 208 case 16: | |
| 209 /* if it's 16bpp, fill in the masks and override the | |
| 210 * compression. These are the default masks -- you | |
| 211 * could change them if needed. */ | |
| 212 pMasks = (LPDWORD)(pbmi->bmiColors); | |
| 213 pMasks[0] = 0x00007c00; | |
| 214 pMasks[1] = 0x000003e0; | |
| 215 pMasks[2] = 0x0000001f; | |
| 216 pbmi->bmiHeader.biCompression = BI_BITFIELDS; | |
| 217 break; | |
| 218 case 32: | |
| 219 /* if it's 32 bpp, fill in the masks and override | |
| 220 * the compression */ | |
| 221 pMasks = (LPDWORD)(pbmi->bmiColors); | |
| 222 /*pMasks[0] = 0x00ff0000; */ | |
| 223 /*pMasks[1] = 0x0000ff00; */ | |
| 224 /*pMasks[2] = 0x000000ff; */ | |
| 225 pMasks[0] = 0xff000000; | |
| 226 pMasks[1] = 0x00ff0000; | |
| 227 pMasks[2] = 0x0000ff00; | |
| 228 | |
| 229 pbmi->bmiHeader.biCompression = BI_BITFIELDS; | |
| 230 break; | |
| 231 case 8: | |
| 232 case 4: | |
| 233 case 1: | |
| 234 setColormap(pbmi, cmap); | |
| 235 break; | |
| 236 } | |
| 237 return pbmi; | |
| 238 } | |
| 239 | |
| 240 /* ********************************************************************** | |
| 241 HBITMAP DSCreateDIBSection(l_int32 width, l_int32 height, l_int32 depth, | |
| 242 PIXCMAP *cmap) | |
| 243 | |
| 244 PARAMETERS: | |
| 245 l_int32 width - Desired width of the DIBSection | |
| 246 l_int32 height - Desired height of the DIBSection | |
| 247 l_int32 depth - Desired bit-depth of the DIBSection | |
| 248 PIXCMAP cmap - leptonica colormap for depths < 16 | |
| 249 | |
| 250 RETURNS: | |
| 251 HBITMAP - a DIBSection HBITMAP of the desired size and bit-depth | |
| 252 NULL on failure | |
| 253 | |
| 254 REMARKS: | |
| 255 Creates a DIBSection based on the criteria passed in as parameters. | |
| 256 | |
| 257 ********************************************************************** */ | |
| 258 static HBITMAP | |
| 259 DSCreateDIBSection(l_int32 width, | |
| 260 l_int32 height, | |
| 261 l_int32 depth, | |
| 262 PIXCMAP *cmap) | |
| 263 { | |
| 264 HBITMAP hBitmap; | |
| 265 l_int32 nInfoSize; | |
| 266 LPBITMAPINFO pbmi; | |
| 267 HDC hRefDC; | |
| 268 LPBYTE pBits; | |
| 269 | |
| 270 pbmi = DSCreateBitmapInfo (width, height, depth, cmap); | |
| 271 if (!pbmi) | |
| 272 return NULL; | |
| 273 | |
| 274 hRefDC = GetDC(NULL); | |
| 275 hBitmap = CreateDIBSection(hRefDC, pbmi, DIB_RGB_COLORS, | |
| 276 (void **) &pBits, NULL, 0); | |
| 277 nInfoSize = GetLastError(); | |
| 278 ReleaseDC(NULL, hRefDC); | |
| 279 free(pbmi); | |
| 280 | |
| 281 return hBitmap; | |
| 282 } | |
| 283 | |
| 284 | |
| 285 /*! | |
| 286 * \brief pixGetWindowsHBITMAP() | |
| 287 * | |
| 288 * \param[in] pix | |
| 289 * \return Windows hBitmap, or NULL on error | |
| 290 * | |
| 291 * <pre> | |
| 292 * Notes: | |
| 293 * (1) It's the responsibility of the caller to destroy the | |
| 294 * returned hBitmap with a call to DeleteObject (or with | |
| 295 * something that eventually calls DeleteObject). | |
| 296 * </pre> | |
| 297 */ | |
| 298 HBITMAP | |
| 299 pixGetWindowsHBITMAP(PIX *pix) | |
| 300 { | |
| 301 l_int32 width, height, depth; | |
| 302 l_uint32 *data; | |
| 303 HBITMAP hBitmap = NULL; | |
| 304 BITMAP bm; | |
| 305 DWORD imageBitsSize; | |
| 306 PIX *pixt = NULL; | |
| 307 PIXCMAP *cmap; | |
| 308 | |
| 309 if (!pix) | |
| 310 return (HBITMAP)ERROR_PTR("pix not defined", __func__, NULL); | |
| 311 | |
| 312 pixGetDimensions(pix, &width, &height, &depth); | |
| 313 cmap = pixGetColormap(pix); | |
| 314 | |
| 315 if (depth == 24) depth = 32; | |
| 316 if (depth == 2) { | |
| 317 pixt = pixConvert2To8(pix, 0, 85, 170, 255, TRUE); | |
| 318 if (!pixt) | |
| 319 return (HBITMAP)ERROR_PTR("unable to convert pix from 2bpp to 8bpp", | |
| 320 __func__, NULL); | |
| 321 depth = pixGetDepth(pixt); | |
| 322 cmap = pixGetColormap(pixt); | |
| 323 } | |
| 324 | |
| 325 if (depth < 16) { | |
| 326 if (!cmap) | |
| 327 cmap = pixcmapCreateLinear(depth, 1<<depth); | |
| 328 } | |
| 329 | |
| 330 hBitmap = DSCreateDIBSection(width, height, depth, cmap); | |
| 331 if (!hBitmap) | |
| 332 return (HBITMAP)ERROR_PTR("Unable to create HBITMAP", __func__, NULL); | |
| 333 | |
| 334 /* By default, Windows assumes bottom up images */ | |
| 335 if (pixt) | |
| 336 pixt = pixFlipTB(pixt, pixt); | |
| 337 else | |
| 338 pixt = pixFlipTB(NULL, pix); | |
| 339 | |
| 340 /* "standard" color table assumes bit off=black */ | |
| 341 if (depth == 1) { | |
| 342 pixInvert(pixt, pixt); | |
| 343 } | |
| 344 | |
| 345 /* Don't byte swap until done manipulating pix! */ | |
| 346 if (depth <= 16) | |
| 347 pixEndianByteSwap(pixt); | |
| 348 | |
| 349 GetObject (hBitmap, sizeof(BITMAP), &bm); | |
| 350 imageBitsSize = ImageBitsSize(hBitmap); | |
| 351 data = pixGetData(pixt); | |
| 352 if (data) { | |
| 353 memcpy (bm.bmBits, data, imageBitsSize); | |
| 354 } else { | |
| 355 DeleteObject (hBitmap); | |
| 356 hBitmap = NULL; | |
| 357 } | |
| 358 pixDestroy(&pixt); | |
| 359 | |
| 360 return hBitmap; | |
| 361 } | |
| 362 | |
| 363 #endif /* _WIN32 */ |
