If you are interested in converting uncompressed BITMAPs, please see this guide.
The most practical approach is to use a Magick::Blob. Although there is overhead associated with allocating extra memory, the overhead associated with decompressing the pixel data is likely much higher.
Here is the code:
//! Transfers the given windows DIB (BGR format, no compression) to a Magick++ Image
/*!
* bmiHeader specifies information about the bitmap image (may have color table entries at end)\n
* bmihLength specifies the length of the bitmap header (which may be longer than
* sizeof(BITMAPINFOHEADER) because of the optional color table entries at the end)\n
* pixels contains the pixel buffer of the bitmap. For maximal efficiency, it is assumed that no other process modifies these pixels while this function is running\n
* length specifies the length of the pixel buffer (pixels)\n
* mImage is a pointer to the Magick++ image that will get the bitmap data. It is assumed that no other process can modify the image while this function is running\n
* \n
* \n
* A Magick++ exception may be thrown
*/
void CompressedBitmapToMagick(const BITMAPINFOHEADER* bmiHeader, size_t bmihLength, const BYTE* restrict pixels, size_t length, Magick::Image* magickImage)
{
assert(bmiHeader->biCompression != BI_RGB); //use the functions specified in this guide for much higher efficiency
assert(bmiHeader->biSizeImage != 0); //must be specified for compressed images
//! Since compression is a big overhead and manually dealing with it is /extremely/ difficult, we just use a BLOB
//We need align the data so that bitmap header is directly before the bitmap data (in DIB format)
void* pDIB = malloc(bmihLength + length);
if (pDIB == NULL)
{ //ran out of memory
throw "out of memory";
}
memcpy(pDIB, bmiHeader, bmihLength);
memcpy((void*)((char*)pDIB + bmihLength), (void*)pixels, length); //copy the pixel data
//! Read the DIB via a blob
Magick::Blob blob;
//Let this Blob "steal" the memory we just allocated
blob.updateNoCopy(pDIB, bmihLength + length, Magick::Blob::Allocator(Magick::Blob::MallocAllocator));
magickImage->read(blob);
//Note that the Blob calls free() for us
return;
}
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.