[main]    [up]  

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: 
  [main]    [up]  
DaicasWeb v.1.50.0102  //   Daniel Käps  //   April 12, 2007  //   Impressum / Imprint 
http://www.daicas.net/WxExtLib/src/ImageMagickExtensions.c.html