WxExtLib - ImageMagickExtensions.c
00001:
00002: /*
00003: -------------------------------------------------------------------------
00004: This file is part of ImageMagickExtensions library.
00005: -------------------------------------------------------------------------
00006:
00007: ImageMagickExtensions library 0.0.1
00008: -----------------------------------
00009:
00010: COPYRIGHT NOTICE:
00011:
00012: ImageMagickExtensions library Copyright (c) 2004 Daniel Käps.
00013:
00014: The ImageMagickExtensions library and associated documentation files (the
00015: "Software") is provided "AS IS". The author(s) disclaim all
00016: warranties, expressed or implied, including, without limitation, the
00017: warranties of merchantability and of fitness for any purpose. The
00018: author(s) assume no liability for direct, indirect, incidental,
00019: special, exemplary, or consequential damages, which may result from
00020: the use of or other dealings in the Software, even if advised of the
00021: possibility of such damage.
00022:
00023: Permission is hereby granted, free of charge, to any person obtaining
00024: a copy of this Software, to deal in the Software without restriction,
00025: including without limitation the rights to use, copy, modify, merge,
00026: publish, distribute, sublicense, and/or sell copies of the Software,
00027: and to permit persons to whom the Software is furnished to do so,
00028: subject to the following conditions:
00029:
00030: 1. The origin of this source code must not be misrepresented.
00031: 2. Altered versions must be plainly marked as such and must not be
00032: misrepresented as being the original source.
00033: 3. This Copyright notice may not be removed or altered from any
00034: source or altered source distribution.
00035:
00036: End of ImageMagickExtensions library Copyright notice
00037:
00038: -------------------------------------------------------------------------
00039: */
00040:
00041: /*-----------------------------------------------------------------------*/
00042: /*
00043: * NOTES
00044: * - this is C only code, but sometimes "//" is used to start a comment line
00045: * (adapt to normal C comments if the used compiler should require it)
00046: */
00047: /*-----------------------------------------------------------------------*/
00048:
00049: /*
00050: Include declarations.
00051: */
00052: #include "magick/studio.h"
00053: #if defined(__WINDOWS__) || defined(__CYGWIN__)
00054: #define WIN32_LEAN_AND_MEAN
00055: #define VC_EXTRALEAN
00056: #include <windows.h>
00057: #include "magick/cache.h"
00058: #include "magick/colorspace.h"
00059: #include "magick/draw.h"
00060: #include "magick/error.h"
00061: #include "magick/hashmap.h"
00062: #include "magick/memory_.h"
00063: #include "magick/monitor.h"
00064: #include "magick/string_.h"
00065: #include "magick/token.h"
00066: #include "magick/utility.h"
00067: #include "magick/image.h"
00068: #include "magick/constitute.h"
00069: #include "ImageMagickExtensions.h"
00070:
00071: /*-----------------------------------------------------------------------*/
00072:
00073: /*
00074: * GetActualUsedColorCountInDIB():
00075: * - return numbers of colors used in a DIB palette
00076: *
00077: * NOTES
00078: * - the actually used color count may differ from field
00079: * BITMAPINFO::biClrUsed (see notes below)
00080: */
00081: int GetActualUsedColorCountInDIB (BITMAPINFOHEADER * BitmapInfoHeader)
00082: {
00083: int ColorsUsed = BitmapInfoHeader -> biClrUsed;
00084: // (for BI_RGB):
00085: // biClrUsed == 0 is interpreted differently depending on the
00086: // bit depth used:
00087: // - for color depths from 1..8 bpp: if biClrUsed is set to zero
00088: // this means that a palette for all possible colors is there
00089: // - for color depths 16, 24 or 32 bpp: if biClrUsed is set to
00090: // zero this means that no palette is used (but biClrUsed
00091: // may be set to non-zero if a palette is there for
00092: // output optimization purposes)
00093: if (BitmapInfoHeader -> biCompression == BI_RGB
00094: && ColorsUsed == 0
00095: && BitmapInfoHeader -> biBitCount >= 1
00096: && BitmapInfoHeader -> biBitCount <= 8)
00097: ColorsUsed = (1 << BitmapInfoHeader -> biBitCount);
00098:
00099: return ColorsUsed;
00100: }
00101:
00102: /*-----------------------------------------------------------------------*/
00103:
00104: int GetActualUsedColorCountInDIBHandle (HDIB DIBHandle)
00105: {
00106: BITMAPINFO
00107: * BitmapInfo;
00108:
00109: BITMAPINFOHEADER
00110: * BitmapInfoHeader;
00111:
00112: int
00113: ActualUsedColorCount;
00114:
00115: // obtain pointer to BITMAPINFO and BITMAPINFOHEADER
00116: if (DIBHandle == NULL)
00117: return 0;
00118: BitmapInfo = (BITMAPINFO *) GlobalLock (/* (HGLOBAL*) */ DIBHandle);
00119: if (BitmapInfo == NULL)
00120: return 0;
00121: BitmapInfoHeader = & BitmapInfo -> bmiHeader;
00122:
00123: ActualUsedColorCount = GetActualUsedColorCountInDIB (BitmapInfoHeader);
00124:
00125: GlobalUnlock (/* (HGLOBAL*) */ DIBHandle);
00126:
00127: return ActualUsedColorCount;
00128: }
00129:
00130: /*-----------------------------------------------------------------------*/
00131:
00132: /*
00133: * ExpandDIBPixelRow():
00134: * - expand palette or 16-Bit (15-Bit, actually) DIBs to 24 Bit DIB
00135: * - this function only handles a single pixel row with PixelCount pixels
00136: *
00137: * NOTES
00138: * - expansion of 1-Bit images will make the expanded image 32 times
00139: * as big and thus may lead to images consuming lots of memory
00140: */
00141: int ExpandDIBPixelRow (BITMAPINFOHEADER * BitmapInfoHeader,
00142: RGBQUAD * PaletteRGBAArray,
00143: unsigned long PixelCount,
00144: BYTE * DIBPixelDataPtr,
00145: BYTE * ExpandedPixelDataPtr)
00146: {
00147: unsigned long
00148: DIBBitsPerPixel,
00149: DIBBytesPerPixel,
00150: DIBPixelsPerByte,
00151: ExpandedBitsPerPixel,
00152: ExpandedBytesPerPixel,
00153: PixelIndex,
00154: IntraPixelByteIndex,
00155: PixelByteShift,
00156: PixelByteMask;
00157:
00158: unsigned char
00159: PaletteByteIndex;
00160:
00161: DIBBitsPerPixel = BitmapInfoHeader -> biBitCount;
00162: ExpandedBitsPerPixel = 32;
00163:
00164: DIBBytesPerPixel = DIBBitsPerPixel / 8;
00165: ExpandedBytesPerPixel = ExpandedBitsPerPixel / 8;
00166:
00167: if (DIBBitsPerPixel == 1
00168: /* || DIBBitsPerPixel == 2 -- probably not a valid Bit depth for a DIB but would work */
00169: || DIBBitsPerPixel == 4)
00170: {
00171: RGBQUAD PaletteRGBA;
00172: BYTE PixelByte;
00173:
00174: // the DIB has a palette and more than one pixel are represented in a byte
00175: DIBPixelsPerByte = 8 / DIBBitsPerPixel;
00176: PixelByteMask = (1 << DIBBitsPerPixel) - 1;
00177:
00178: for (PixelIndex=0; PixelIndex < PixelCount; ++PixelIndex)
00179: {
00180: // PERFORMANCE could avoid modulo and multiplications by incrementally
00181: // determining these values
00182: IntraPixelByteIndex = DIBPixelsPerByte - (PixelIndex % DIBPixelsPerByte) - 1;
00183: PixelByteShift = IntraPixelByteIndex * DIBBitsPerPixel;
00184:
00185: PixelByte = *DIBPixelDataPtr;
00186: PixelByte >>= PixelByteShift;
00187: PaletteByteIndex = PixelByte & PixelByteMask;
00188:
00189: PaletteRGBA = PaletteRGBAArray [PaletteByteIndex];
00190:
00191: *(ExpandedPixelDataPtr++) = PaletteRGBA.rgbBlue;
00192: *(ExpandedPixelDataPtr++) = PaletteRGBA.rgbGreen;
00193: *(ExpandedPixelDataPtr++) = PaletteRGBA.rgbRed;
00194: *(ExpandedPixelDataPtr++) = PaletteRGBA.rgbReserved;
00195:
00196: if (IntraPixelByteIndex == 0)
00197: DIBPixelDataPtr += sizeof(BYTE);
00198: }
00199: }
00200: else if (DIBBitsPerPixel == 8)
00201: {
00202: // the DIB has a palette and exactly one pixel is represented in a byte
00203: for (PixelIndex=0; PixelIndex < PixelCount; ++PixelIndex)
00204: {
00205: RGBQUAD PaletteRGBA;
00206: BYTE PaletteByteIndex;
00207:
00208: PaletteByteIndex = *DIBPixelDataPtr;
00209:
00210: PaletteRGBA = PaletteRGBAArray [PaletteByteIndex];
00211:
00212: *(ExpandedPixelDataPtr++) = PaletteRGBA.rgbBlue;
00213: *(ExpandedPixelDataPtr++) = PaletteRGBA.rgbGreen;
00214: *(ExpandedPixelDataPtr++) = PaletteRGBA.rgbRed;
00215: *(ExpandedPixelDataPtr++) = PaletteRGBA.rgbReserved;
00216:
00217: DIBPixelDataPtr += DIBBytesPerPixel;
00218: }
00219: }
00220: else if (DIBBitsPerPixel == 16)
00221: {
00222: // pixel color values are represented without palette as 16 Bit value
00223: // (5-5-5: Bits for Blue, Green, Red respectively). Highest order
00224: // bit is unused normally
00225: // exceptions:
00226: // - if 'biCompression' is set to BI_BITFIELDS, the ordering and
00227: // number of bits used for the three colors can be specified
00228: // differently by specifying bit masks to be used (they are specified
00229: // at the bmiColors memory position where normally can be a palette)
00230: // - some windows versions support only a subset of possible bit masks
00231: // so one could assume that these BI_BITFIELDS variants of 16-Bit
00232: // DIBs are rarely encountered in practice
00233:
00234: // WARN should check if WORD is actually 16 Bit wide
00235: // on the used compiler/platform
00236:
00237: WORD
00238: RedMask,
00239: RedShift,
00240: GreenMask,
00241: GreenShift,
00242: BlueMask,
00243: BlueShift;
00244:
00245: WORD
00246: * DIBPixelDoubleByteDataPtr;
00247:
00248: const int FiveBitToEightBitLookupTable [32] = {
00249: 0, 8, 16, 24, 32, 41, 49, 57, 65, 74, 82, 90, 98, 106, 115, 123,
00250: 131, 139, 148, 156, 164, 172, 180, 189, 197, 205, 213, 222, 230, 238, 246, 255};
00251:
00252: BlueMask = 0x001F;
00253: BlueShift = 0;
00254: GreenMask = 0x03E0;
00255: GreenShift = 5;
00256: RedMask = 0x7C00;
00257: RedShift = 10;
00258:
00259: DIBPixelDoubleByteDataPtr = (WORD *) DIBPixelDataPtr;
00260:
00261: for (PixelIndex=0; PixelIndex < PixelCount; ++PixelIndex)
00262: {
00263: // WARN should check if WORD is actually 16 Bit wide
00264: // on the used compiler/platform
00265: WORD PixelDoubleByte = *DIBPixelDoubleByteDataPtr;
00266:
00267: // convert from 5 to 8 Bit using a lookup table to avoid
00268: // multiplication with 255 and divison by 31
00269: *(ExpandedPixelDataPtr++)
00270: = FiveBitToEightBitLookupTable [(PixelDoubleByte & BlueMask) >> BlueShift];
00271: *(ExpandedPixelDataPtr++)
00272: = FiveBitToEightBitLookupTable [(PixelDoubleByte & GreenMask) >> GreenShift];
00273: *(ExpandedPixelDataPtr++)
00274: = FiveBitToEightBitLookupTable [(PixelDoubleByte & RedMask) >> RedShift];
00275: *(ExpandedPixelDataPtr++) = 0; // WARN or 255?
00276:
00277: ++DIBPixelDoubleByteDataPtr; // increment to next 16-Bit WORD
00278: }
00279: }
00280: else
00281: {
00282: return False;
00283: }
00284:
00285: return True;
00286: }
00287:
00288: /*-----------------------------------------------------------------------*/
00289:
00290: /*
00291: * DIBPaletteToImage()
00292: * - Transfers color values from a DIB palette to ImageMagick Image:
00293: * the whole palette is put into an image of size
00294: * (DIBColorPaletteEntryCount x 1).
00295: * - Returns True if the image has a palette, False if there is
00296: * no palette
00297: *
00298: * NOTES
00299: * - for converting the image content of a DIB image to an ImageMagick
00300: * image, see DIBToImage()
00301: *
00302: * BUGS
00303: * - error handling is partially missing
00304: */
00305: MagickExport int DIBPaletteToImage (HDIB DIBHandle, Image ** PaletteImage,
00306: ExceptionInfo * exceptionInfo)
00307: {
00308: long
00309: BitmapInfoHeaderSize,
00310: DIBColorPaletteEntryCount;
00311:
00312: BITMAPINFO
00313: * BitmapInfo;
00314:
00315: BITMAPINFOHEADER
00316: * BitmapInfoHeader;
00317:
00318: RGBQUAD
00319: * PaletteRGBAArray;
00320:
00321: Image
00322: * image;
00323:
00324: const char
00325: * MapString;
00326:
00327: // obtain pointer to BITMAPINFO and BITMAPINFOHEADER
00328: if (DIBHandle == NULL)
00329: return False;
00330: BitmapInfo = (BITMAPINFO *) GlobalLock (/* (HGLOBAL*) */ DIBHandle);
00331: if (BitmapInfo == NULL)
00332: return False;
00333: BitmapInfoHeader = & BitmapInfo -> bmiHeader;
00334:
00335: // setup sizes
00336: BitmapInfoHeaderSize = BitmapInfoHeader -> biSize; // should be 40 normally
00337:
00338: // extract needed information from BitmapInfoHeader:
00339: if (BitmapInfoHeader -> biPlanes != 1
00340: || BitmapInfoHeader -> biCompression != BI_RGB)
00341: {
00342: // currently no support for compressed DIB's
00343: // or anything exotic (e.g. plane count != 1) or with compression
00344: GlobalUnlock (/* (HGLOBAL*) */ DIBHandle);
00345: return False;
00346: }
00347: DIBColorPaletteEntryCount = GetActualUsedColorCountInDIB (BitmapInfoHeader);
00348:
00349: if (DIBColorPaletteEntryCount == 0)
00350: return False;
00351:
00352: // the entries of a color palette of a DIB always use 32 bit entries
00353: // (blue-green-red-reserved)
00354: MapString = "BGRA"; // or maybe RGBO
00355:
00356: PaletteRGBAArray = (RGBQUAD *) (((unsigned char *) BitmapInfo)
00357: + BitmapInfoHeaderSize);
00358:
00359: // transfer color values from palette to ImageMagick Image:
00360: // the whole palette is put into a single row with DIBColorPaletteEntryCount
00361: // "pixels"
00362: image = ConstituteImage (DIBColorPaletteEntryCount,
00363: /* Height */ 1,
00364: MapString,
00365: CharPixel,
00366: PaletteRGBAArray,
00367: exceptionInfo);
00368:
00369: GlobalUnlock (/* (HGLOBAL*) */ DIBHandle);
00370:
00371: * PaletteImage = image;
00372: return True;
00373: }
00374:
00375: /*-----------------------------------------------------------------------*/
00376:
00377: MagickExport int ImportExportColorPaletteIntoDIB (BYTE * ImportExportColorPaletteByteArray,
00378: int ImportExportColorPaletteEntryCount,
00379: HDIB DIBHandle,
00380: int IsImport)
00381: {
00382: long
00383: BitmapInfoHeaderSize,
00384: DIBColorPaletteEntryCount;
00385:
00386: BITMAPINFO
00387: * BitmapInfo;
00388:
00389: BITMAPINFOHEADER
00390: * BitmapInfoHeader;
00391:
00392: RGBQUAD
00393: * DIBColorPaletteRGBAArray;
00394:
00395: // obtain pointer to BITMAPINFO and BITMAPINFOHEADER
00396: if (DIBHandle == NULL)
00397: return False;
00398: BitmapInfo = (BITMAPINFO *) GlobalLock (/* (HGLOBAL*) */ DIBHandle);
00399: if (BitmapInfo == NULL)
00400: return False;
00401: BitmapInfoHeader = & BitmapInfo -> bmiHeader;
00402:
00403: // setup sizes
00404: BitmapInfoHeaderSize = BitmapInfoHeader -> biSize; // should be 40 normally
00405:
00406: // extract needed information from BitmapInfoHeader:
00407: if (BitmapInfoHeader -> biPlanes != 1
00408: || BitmapInfoHeader -> biCompression != BI_RGB)
00409: {
00410: // currently no support for compressed DIB's
00411: // or anything exotic (e.g. plane count != 1) or with compression
00412: GlobalUnlock (/* (HGLOBAL*) */ DIBHandle);
00413: return False;
00414: }
00415: DIBColorPaletteEntryCount = GetActualUsedColorCountInDIB (BitmapInfoHeader);
00416:
00417: if (DIBColorPaletteEntryCount == 0)
00418: {
00419: GlobalUnlock (/* (HGLOBAL*) */ DIBHandle);
00420: return False;
00421: }
00422:
00423: if (DIBColorPaletteEntryCount != ImportExportColorPaletteEntryCount)
00424: {
00425: GlobalUnlock (/* (HGLOBAL*) */ DIBHandle);
00426: return False;
00427: }
00428:
00429: DIBColorPaletteRGBAArray = (RGBQUAD *) (((unsigned char *) BitmapInfo)
00430: + BitmapInfoHeaderSize);
00431:
00432: if (IsImport)
00433: {
00434: memcpy (DIBColorPaletteRGBAArray,
00435: ImportExportColorPaletteByteArray,
00436: DIBColorPaletteEntryCount * sizeof(RGBQUAD));
00437: }
00438: else
00439: {
00440: memcpy (ImportExportColorPaletteByteArray,
00441: DIBColorPaletteRGBAArray,
00442: DIBColorPaletteEntryCount * sizeof(RGBQUAD));
00443: }
00444:
00445: GlobalUnlock (/* (HGLOBAL*) */ DIBHandle);
00446:
00447: return True;
00448: }
00449:
00450: /*-----------------------------------------------------------------------*/
00451:
00452: MagickExport int ImageToDIBPalette (Image* image, HDIB DIBHandle,
00453: ExceptionInfo * exceptionInfo)
00454: {
00455: long
00456: BitmapInfoHeaderSize,
00457: DIBColorPaletteEntryCount;
00458:
00459: BITMAPINFOHEADER
00460: * BitmapInfoHeader;
00461:
00462: BITMAPINFO
00463: * BitmapInfo;
00464:
00465: const char
00466: * MapString;
00467:
00468: RGBQUAD
00469: * ColorPaletteRGBAArray;
00470:
00471: int IsOk;
00472:
00473: // obtain pointer to BITMAPINFO and BITMAPINFOHEADER
00474: if (DIBHandle == NULL)
00475: return False;
00476: BitmapInfo = (BITMAPINFO *) GlobalLock (/* (HGLOBAL*) */ DIBHandle);
00477: if (BitmapInfo == NULL)
00478: return False;
00479: BitmapInfoHeader = & BitmapInfo -> bmiHeader;
00480:
00481: // read out BitmapInfoHeader and check if compatible
00482: // with the provided ImageMagick image
00483: BitmapInfoHeaderSize = BitmapInfoHeader -> biSize;
00484:
00485: if (BitmapInfoHeader -> biPlanes != 1
00486: || BitmapInfoHeader -> biCompression != BI_RGB)
00487: {
00488: // currently no support for compressed DIB's
00489: // or anything exotic (e.g. plane count != 1) or with compression
00490: // BI_BITFIELDS would be easy to support, though
00491: GlobalUnlock (/* (HGLOBAL*) */ DIBHandle);
00492: return False;
00493: }
00494:
00495: DIBColorPaletteEntryCount = GetActualUsedColorCountInDIB (BitmapInfoHeader);
00496: if (DIBColorPaletteEntryCount == 0
00497: || DIBColorPaletteEntryCount != image->columns
00498: || image->rows != 1)
00499: {
00500: GlobalUnlock (/* (HGLOBAL*) */ DIBHandle);
00501: return False;
00502: }
00503:
00504: // transfer "pixels" (colors) from image directly into the DIB palette
00505: MapString = "BGRA"; // or maybe RGBO
00506: ColorPaletteRGBAArray = (RGBQUAD *) (((unsigned char *) BitmapInfo)
00507: + BitmapInfoHeaderSize);
00508: IsOk = ExportImagePixels (image,
00509: 0,
00510: 0,
00511: image->columns,
00512: 1,
00513: MapString,
00514: CharPixel,
00515: ColorPaletteRGBAArray,
00516: exceptionInfo);
00517:
00518: if (IsOk == False)
00519: {
00520: GlobalUnlock (/* (HGLOBAL*) */ DIBHandle);
00521: return False;
00522: }
00523:
00524: GlobalUnlock (/* (HGLOBAL*) */ DIBHandle);
00525:
00526: return True;
00527: }
00528:
00529:
00530: /*-----------------------------------------------------------------------*/
00531:
00532: /*
00533: * DIBToImage():
00534: * - creates an IM Image from a Windows HDIB
00535: * Notes:
00536: * - currently, only uncompressed 24 Bit and 32 Bit DIB's are supported
00537: * as input DIB's
00538: */
00539: MagickExport Image * DIBToImage (HDIB DIBHandle,
00540: ExceptionInfo * exceptionInfo)
00541: {
00542: unsigned long
00543: DIBBitsPerPixel,
00544: ExpandedBitsPerPixel,
00545: RowIndex,
00546: Width,
00547: Height;
00548:
00549: long
00550: BitmapInfoHeaderSize,
00551: DIBColorPaletteSize,
00552: PaddedDIBPixelRowSize,
00553: DIBPixelDataSize,
00554: ExpandedPixelRowSize;
00555:
00556: BITMAPINFO
00557: * BitmapInfo;
00558:
00559: BITMAPINFOHEADER
00560: * BitmapInfoHeader;
00561:
00562: RGBQUAD
00563: * PaletteRGBAArray;
00564:
00565: BYTE
00566: * DIBPixelPtr,
00567: * ExpandedPixelRowPtr;
00568:
00569: Image
00570: * image;
00571:
00572: const char
00573: * MapString;
00574:
00575: int
00576: IsOk;
00577:
00578: // obtain pointer to BITMAPINFO and BITMAPINFOHEADER
00579: if (DIBHandle == NULL)
00580: return (NULL);
00581: BitmapInfo = (BITMAPINFO *) GlobalLock (/* (HGLOBAL*) */ DIBHandle);
00582: if (BitmapInfo == NULL)
00583: return (NULL);
00584: BitmapInfoHeader = & BitmapInfo -> bmiHeader;
00585:
00586: // setup sizes
00587: BitmapInfoHeaderSize = BitmapInfoHeader -> biSize; // should be 40 normally
00588:
00589: // extract needed information from BitmapInfoHeader:
00590: // some programs set biSizeImage != PaddedDIBPixelRowSize * Height, so
00591: // this field is not really useful (it is not needed here, anyway)
00592: DIBPixelDataSize = BitmapInfoHeader -> biSizeImage;
00593: Width = BitmapInfoHeader -> biWidth;
00594: Height = BitmapInfoHeader -> biHeight;
00595:
00596: if (BitmapInfoHeader -> biPlanes != 1
00597: || BitmapInfoHeader -> biCompression != BI_RGB)
00598: {
00599: // currently no support for compressed DIB's
00600: // or anything exotic (e.g. plane count != 1) or with compression
00601: // BI_BITFIELDS would be easy to support, though
00602: GlobalUnlock (/* (HGLOBAL*) */ DIBHandle);
00603: return (NULL);
00604: }
00605: DIBColorPaletteSize = GetActualUsedColorCountInDIB (BitmapInfoHeader) * sizeof(RGBQUAD);
00606: DIBBitsPerPixel = BitmapInfoHeader -> biBitCount;
00607: // padding of row sizes: formula first rounds bits to next byte, then to
00608: // next byte divisible by four
00609: // PaddedDIBPixelRowSize = ((((Width * DIBBitsPerPixel + 7) / 8) + 3) / 4) * 4;
00610: PaddedDIBPixelRowSize = ((Width * DIBBitsPerPixel + 31) / 32) * 4;
00611:
00612: // BitmapInfoHeader -> biXPelsPerMeter; // WARN should set corresponding field in image
00613: // BitmapInfoHeader -> biYPelsPerMeter; // WARN should set corresponding field in image
00614:
00615: if (DIBBitsPerPixel <= 16)
00616: {
00617: ExpandedBitsPerPixel = 32;
00618: }
00619: else
00620: {
00621: ExpandedBitsPerPixel = DIBBitsPerPixel;
00622: }
00623: ExpandedPixelRowSize = Width * (ExpandedBitsPerPixel / 8);
00624:
00625: switch (ExpandedBitsPerPixel)
00626: {
00627: case 24:
00628: MapString = "BGR";
00629: break;
00630: case 32:
00631: MapString = "BGRA"; // or maybe RGBO
00632: break;
00633: default:
00634: MapString = NULL;
00635: break;
00636: }
00637:
00638: PaletteRGBAArray = (RGBQUAD *) (((unsigned char *) BitmapInfo)
00639: + BitmapInfoHeaderSize);
00640:
00641: // transfer pixels from DIB to ImageMagick Image:
00642: DIBPixelPtr = (BYTE *) (((unsigned char *) BitmapInfo)
00643: + BitmapInfoHeaderSize
00644: + DIBColorPaletteSize);
00645:
00646: if (DIBBitsPerPixel == 24
00647: || DIBBitsPerPixel == 32)
00648: {
00649: image = ConstituteImage (Width, Height, MapString, CharPixel, DIBPixelPtr,
00650: exceptionInfo);
00651: }
00652: else
00653: {
00654: image = AllocateImage ((ImageInfo *) NULL);
00655: if (image == (Image *) NULL)
00656: return ((Image *) NULL);
00657:
00658: image -> columns = Width;
00659: image -> rows = Height;
00660: SetImage (image, OpaqueOpacity);
00661:
00662: // WARN should use ImageMagick provided alloc and free
00663: ExpandedPixelRowPtr = malloc (ExpandedPixelRowSize);
00664:
00665: if (ExpandedPixelRowPtr != NULL)
00666: {
00667: for (RowIndex = 0; RowIndex < image -> rows ; ++RowIndex)
00668: {
00669: IsOk = ExpandDIBPixelRow (BitmapInfoHeader,
00670: PaletteRGBAArray,
00671: Width,
00672: DIBPixelPtr,
00673: ExpandedPixelRowPtr);
00674: if (IsOk == False)
00675: {
00676: DestroyImage(image);
00677: image = NULL;
00678: break;
00679: }
00680:
00681: // WARN must check error handling
00682: IsOk = ImportImagePixels (image,
00683: 0,
00684: RowIndex,
00685: Width,
00686: 1,
00687: MapString,
00688: CharPixel,
00689: ExpandedPixelRowPtr);
00690: if (IsOk == False)
00691: {
00692: InheritException (exceptionInfo, &image->exception);
00693: DestroyImage(image);
00694: image = NULL;
00695: break;
00696: }
00697:
00698: DIBPixelPtr += PaddedDIBPixelRowSize;
00699: }
00700:
00701: // WARN should use ImageMagick provided alloc and free
00702: free (ExpandedPixelRowPtr);
00703: }
00704: }
00705:
00706: GlobalUnlock (/* (HGLOBAL*) */ DIBHandle);
00707:
00708: return image;
00709: }
00710:
00711:
00712: /*-----------------------------------------------------------------------*/
00713:
00714: /*
00715: * ImageToDIB():
00716: * - creates a Windows HDIB from an IM Image
00717: * - Notes:
00718: * - currently, DIBBitsPerPixel must either 24 or 32
00719: */
00720: MagickExport HDIB ImageToDIB (Image* image, int DIBBitsPerPixel,
00721: ExceptionInfo * exceptionInfo)
00722: {
00723: unsigned long
00724: RowIndex,
00725: Width,
00726: Height;
00727:
00728: const PixelPacket
00729: * PixelPacketPtr;
00730:
00731: HDIB
00732: DIBHandle;
00733:
00734: long
00735: BitmapInfoHeaderSize,
00736: DIBColorPaletteSize,
00737: DIBPixelDataSize,
00738: PaddedDIBPixelRowSize;
00739:
00740: BITMAPINFOHEADER
00741: * BitmapInfoHeader;
00742:
00743: BITMAPINFO
00744: * BitmapInfo;
00745:
00746: const char
00747: * MapString;
00748:
00749: BYTE
00750: * DIBDestPixelDataPtr;
00751:
00752: int IsOk;
00753:
00754: Width = image->columns;
00755: Height = image->rows;
00756:
00757: // setup sizes
00758: BitmapInfoHeaderSize = sizeof(BITMAPINFOHEADER);
00759: DIBColorPaletteSize = 0;
00760: // padding of row sizes: formula first rounds bits to next byte, then to
00761: // next byte divisible by four
00762: // PaddedDIBPixelRowSize = ((((Width * DIBBitsPerPixel + 7) / 8) + 3) / 4) * 4;
00763: PaddedDIBPixelRowSize = ((Width * DIBBitsPerPixel + 31) / 32) * 4;
00764: DIBPixelDataSize = PaddedDIBPixelRowSize * Height;
00765:
00766: // WARN don't know which GlobalAlloc flags should be really used here
00767: DIBHandle = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE,
00768: BitmapInfoHeaderSize
00769: + DIBColorPaletteSize
00770: + DIBPixelDataSize);
00771: if (DIBHandle == NULL)
00772: return(NULL);
00773:
00774: BitmapInfo = (BITMAPINFO *) GlobalLock (/* (HGLOBAL*) */ DIBHandle);
00775: BitmapInfoHeader = & BitmapInfo -> bmiHeader;
00776:
00777: // setup the BitmapInfoHeader:
00778: BitmapInfoHeader -> biSize = sizeof (BITMAPINFOHEADER);
00779: BitmapInfoHeader -> biWidth = Width;
00780: BitmapInfoHeader -> biHeight = Height;
00781: BitmapInfoHeader -> biPlanes = 1;
00782: BitmapInfoHeader -> biBitCount = DIBBitsPerPixel;
00783: BitmapInfoHeader -> biCompression = BI_RGB; // ==0, no compression
00784: BitmapInfoHeader -> biXPelsPerMeter = 0; // WARN should be set to corresponding field in image
00785: BitmapInfoHeader -> biYPelsPerMeter = 0; // WARN should be set to corresponding field in image
00786: BitmapInfoHeader -> biSizeImage = DIBPixelDataSize;
00787: BitmapInfoHeader -> biClrUsed = 0; // no palette for RGBA image
00788: BitmapInfoHeader -> biClrImportant = 0;
00789:
00790: // WARN SetImageColorspace necessary?
00791: SetImageColorspace(image, RGBColorspace);
00792:
00793: switch (DIBBitsPerPixel)
00794: {
00795: case 24:
00796: MapString = "BGR";
00797: break;
00798: case 32:
00799: MapString = "BGRA"; // or maybe RGBO
00800: break;
00801: default:
00802: MapString = NULL; break;
00803: }
00804:
00805: // transfer pixels from ImageMagick Image to DIB:
00806: DIBDestPixelDataPtr = (BYTE *) (((unsigned char *) BitmapInfo)
00807: + BitmapInfoHeaderSize
00808: + DIBColorPaletteSize);
00809:
00810: for (RowIndex = 0; RowIndex < image -> rows ; ++RowIndex)
00811: {
00812: PixelPacketPtr = AcquireImagePixels (image, 0, RowIndex, image->columns, 1,
00813: exceptionInfo);
00814: // WARN must add error handling
00815:
00816: if (QuantumDepth == 8
00817: && DIBBitsPerPixel == 32)
00818: {
00819: /* Form of PixelPacket is identical to RGBQUAD when QuantumDepth==8 */
00820: CopyMagickMemory ((void*) DIBDestPixelDataPtr,
00821: (const void*) PixelPacketPtr,
00822: sizeof(PixelPacket) * image -> columns);
00823: }
00824: else
00825: {
00826: IsOk = ExportImagePixels (image,
00827: 0,
00828: RowIndex,
00829: image->columns,
00830: 1,
00831: MapString,
00832: CharPixel,
00833: DIBDestPixelDataPtr,
00834: exceptionInfo);
00835:
00836: if (IsOk == False)
00837: break;
00838: }
00839:
00840: DIBDestPixelDataPtr += PaddedDIBPixelRowSize;
00841: }
00842:
00843: GlobalUnlock (/* (HGLOBAL) */ DIBHandle);
00844:
00845: if (IsOk == False)
00846: {
00847: GlobalFree (DIBHandle);
00848: DIBHandle = NULL;
00849: }
00850:
00851: return DIBHandle;
00852: }
00853:
00854: #endif
00855:
00856: /*-----------------------------------------------------------------------*/
00857:
00858: #ifdef M_UseIMUnresolvedExternalSymbolHack
00859:
00860: // HACK unresolved external symbol
00861: #if !defined(BuildMagickModules)
00862: void RegisterARTImage(void) { }
00863: void RegisterAVIImage(void) { }
00864: void RegisterAVSImage(void) { }
00865: void RegisterBMPImage(void) { }
00866: void RegisterCAPTIONImage(void) { }
00867: void RegisterCINImage(void) { }
00868: void RegisterCIPImage(void) { }
00869: void RegisterCLIPImage(void) { }
00870: void RegisterCLIPBOARDImage(void) { }
00871: void RegisterCMYKImage(void) { }
00872: void RegisterCUTImage(void) { }
00873: void RegisterDCMImage(void) { }
00874: void RegisterDIBImage(void) { }
00875: void RegisterDPSImage(void) { }
00876: void RegisterDPXImage(void) { }
00877: void RegisterEMFImage(void) { }
00878: void RegisterEPTImage(void) { }
00879: void RegisterFAXImage(void) { }
00880: void RegisterFITSImage(void) { }
00881: void RegisterFPXImage(void) { }
00882: void RegisterGIFImage(void) { }
00883: void RegisterGRAYImage(void) { }
00884: void RegisterGRADIENTImage(void) { }
00885: void RegisterHISTOGRAMImage(void) { }
00886: void RegisterHTMLImage(void) { }
00887: void RegisterICONImage(void) { }
00888: void RegisterJBIGImage(void) { }
00889: void RegisterJPEGImage(void) { }
00890: void RegisterJP2Image(void) { }
00891: void RegisterLABELImage(void) { }
00892: void RegisterMAGICKImage(void) { }
00893: void RegisterMAPImage(void) { }
00894: void RegisterMATImage(void) { }
00895: void RegisterMATTEImage(void) { }
00896: void RegisterMETAImage(void) { }
00897: void RegisterMIFFImage(void) { }
00898: void RegisterMONOImage(void) { }
00899: void RegisterMPCImage(void) { }
00900: void RegisterMPEGImage(void) { }
00901: void RegisterMPRImage(void) { }
00902: void RegisterMSLImage(void) { }
00903: void RegisterMTVImage(void) { }
00904: void RegisterMVGImage(void) { }
00905: void RegisterNULLImage(void) { }
00906: void RegisterOTBImage(void) { }
00907: void RegisterPALMImage(void) { }
00908: void RegisterPATTERNImage(void) { }
00909: void RegisterPCDImage(void) { }
00910: void RegisterPCLImage(void) { }
00911: void RegisterPCXImage(void) { }
00912: void RegisterPDBImage(void) { }
00913: void RegisterPDFImage(void) { }
00914: void RegisterPICTImage(void) { }
00915: void RegisterPIXImage(void) { }
00916: void RegisterPLASMAImage(void) { }
00917: void RegisterPNGImage(void) { }
00918: void RegisterPNMImage(void) { }
00919: void RegisterPREVIEWImage(void) { }
00920: void RegisterPSImage(void) { }
00921: void RegisterPS2Image(void) { }
00922: void RegisterPS3Image(void) { }
00923: void RegisterPSDImage(void) { }
00924: void RegisterPWPImage(void) { }
00925: void RegisterRAWImage(void) { }
00926: void RegisterRGBImage(void) { }
00927: void RegisterRLAImage(void) { }
00928: void RegisterRLEImage(void) { }
00929: void RegisterSCRImage(void) { }
00930: void RegisterSCTImage(void) { }
00931: void RegisterSFWImage(void) { }
00932: void RegisterSGIImage(void) { }
00933: void RegisterSTEGANOImage(void) { }
00934: void RegisterSUNImage(void) { }
00935: void RegisterSVGImage(void) { }
00936: void RegisterTGAImage(void) { }
00937: void RegisterTIFFImage(void) { }
00938: void RegisterTILEImage(void) { }
00939: void RegisterTIMImage(void) { }
00940: void RegisterTTFImage(void) { }
00941: void RegisterTXTImage(void) { }
00942: void RegisterUILImage(void) { }
00943: void RegisterURLImage(void) { }
00944: void RegisterUYVYImage(void) { }
00945: void RegisterVICARImage(void) { }
00946: void RegisterVIDImage(void) { }
00947: void RegisterVIFFImage(void) { }
00948: void RegisterWBMPImage(void) { }
00949: void RegisterWMFImage(void) { }
00950: void RegisterWPGImage(void) { }
00951: void RegisterXImage(void) { }
00952: void RegisterXBMImage(void) { }
00953: void RegisterXCImage(void) { }
00954: void RegisterXCFImage(void) { }
00955: void RegisterXPMImage(void) { }
00956: #if defined(_VISUALC_)
00957: void RegisterXTRNImage(void) { }
00958: #endif
00959: void RegisterXWDImage(void) { }
00960: void RegisterYUVImage(void) { }
00961: #endif
00962:
00963: /*-----------------------------------------------------------------------*/
00964:
00965: // HACK unresolved external symbol
00966: #if !defined(BuildMagickModules)
00967: void UnregisterARTImage(void) { }
00968: void UnregisterAVIImage(void) { }
00969: void UnregisterAVSImage(void) { }
00970: void UnregisterBMPImage(void) { }
00971: void UnregisterCAPTIONImage(void) { }
00972: void UnregisterCINImage(void) { }
00973: void UnregisterCIPImage(void) { }
00974: void UnregisterCLIPImage(void) { }
00975: void UnregisterCLIPBOARDImage(void) { }
00976: void UnregisterCMYKImage(void) { }
00977: void UnregisterCUTImage(void) { }
00978: void UnregisterDCMImage(void) { }
00979: void UnregisterDIBImage(void) { }
00980: void UnregisterDPSImage(void) { }
00981: void UnregisterDPXImage(void) { }
00982: void UnregisterEMFImage(void) { }
00983: void UnregisterEPTImage(void) { }
00984: void UnregisterFAXImage(void) { }
00985: void UnregisterFITSImage(void) { }
00986: void UnregisterFPXImage(void) { }
00987: void UnregisterGIFImage(void) { }
00988: void UnregisterGRAYImage(void) { }
00989: void UnregisterGRADIENTImage(void) { }
00990: void UnregisterHISTOGRAMImage(void) { }
00991: void UnregisterHTMLImage(void) { }
00992: void UnregisterICONImage(void) { }
00993: void UnregisterJBIGImage(void) { }
00994: void UnregisterJPEGImage(void) { }
00995: void UnregisterJP2Image(void) { }
00996: void UnregisterLABELImage(void) { }
00997: void UnregisterMAGICKImage(void) { }
00998: void UnregisterMAPImage(void) { }
00999: void UnregisterMATImage(void) { }
01000: void UnregisterMATTEImage(void) { }
01001: void UnregisterMETAImage(void) { }
01002: void UnregisterMIFFImage(void) { }
01003: void UnregisterMONOImage(void) { }
01004: void UnregisterMPCImage(void) { }
01005: void UnregisterMPEGImage(void) { }
01006: void UnregisterMPRImage(void) { }
01007: void UnregisterMSLImage(void) { }
01008: void UnregisterMTVImage(void) { }
01009: void UnregisterMVGImage(void) { }
01010: void UnregisterNULLImage(void) { }
01011: void UnregisterOTBImage(void) { }
01012: void UnregisterPALMImage(void) { }
01013: void UnregisterPATTERNImage(void) { }
01014: void UnregisterPCDImage(void) { }
01015: void UnregisterPCLImage(void) { }
01016: void UnregisterPCXImage(void) { }
01017: void UnregisterPDBImage(void) { }
01018: void UnregisterPDFImage(void) { }
01019: void UnregisterPICTImage(void) { }
01020: void UnregisterPIXImage(void) { }
01021: void UnregisterPLASMAImage(void) { }
01022: void UnregisterPNGImage(void) { }
01023: void UnregisterPNMImage(void) { }
01024: void UnregisterPREVIEWImage(void) { }
01025: void UnregisterPSImage(void) { }
01026: void UnregisterPS2Image(void) { }
01027: void UnregisterPS3Image(void) { }
01028: void UnregisterPSDImage(void) { }
01029: void UnregisterPWPImage(void) { }
01030: void UnregisterRAWImage(void) { }
01031: void UnregisterRGBImage(void) { }
01032: void UnregisterRLAImage(void) { }
01033: void UnregisterRLEImage(void) { }
01034: void UnregisterSCRImage(void) { }
01035: void UnregisterSCTImage(void) { }
01036: void UnregisterSFWImage(void) { }
01037: void UnregisterSGIImage(void) { }
01038: void UnregisterSTEGANOImage(void) { }
01039: void UnregisterSUNImage(void) { }
01040: void UnregisterSVGImage(void) { }
01041: void UnregisterTGAImage(void) { }
01042: void UnregisterTIFFImage(void) { }
01043: void UnregisterTILEImage(void) { }
01044: void UnregisterTIMImage(void) { }
01045: void UnregisterTTFImage(void) { }
01046: void UnregisterTXTImage(void) { }
01047: void UnregisterUILImage(void) { }
01048: void UnregisterURLImage(void) { }
01049: void UnregisterUYVYImage(void) { }
01050: void UnregisterVICARImage(void) { }
01051: void UnregisterVIDImage(void) { }
01052: void UnregisterVIFFImage(void) { }
01053: void UnregisterWBMPImage(void) { }
01054: void UnregisterWMFImage(void) { }
01055: void UnregisterWPGImage(void) { }
01056: void UnregisterXImage(void) { }
01057: void UnregisterXBMImage(void) { }
01058: void UnregisterXCImage(void) { }
01059: void UnregisterXCFImage(void) { }
01060: void UnregisterXPMImage(void) { }
01061: #if defined(_VISUALC_)
01062: void UnregisterXTRNImage(void) { }
01063: #endif
01064: void UnregisterXWDImage(void) { }
01065: void UnregisterYUVImage(void) { }
01066: #endif
01067:
01068: /*-----------------------------------------------------------------------*/
01069:
01070: // HACK unresolved external symbol
01071: extern unsigned int
01072: AnalyzeImage(Image ** imagep,const int integer,char ** charpp)
01073: {
01074: return 0;
01075: }
01076:
01077: #endif // M_UseIMUnresolvedExternalSymbolHack
01078:
01079: /*-----------------------------------------------------------------------*/
01080: