2

I'm using c++ to do some image work and I'd like to be able to work with jpeg compressed files. The GDI+ library appears to have what I need, and specifically the Gdiplus::Bitmap::GetPixel() routine is what I'd ultimately like to use.

There are several Gdiplus::Bitmap constructors, and the one I'd like to use takes in a BITMAPINFO structure and a pointer to the image bits. Bitmap.Bitmap(const BITMAPINFO* lpbmi, VOID* lpbits) I already have this information from a hooked StretchDIBits() So I'm not even creating the original BITMAP, its being given to me. But the compression is set for JPEG on the bitmap (BITMAPINFO.BITMAPINFOHEADER.biCompression = BI_JPEG) , so its not easy to parse, and I don't know how, or want to write a jpeg decompression algorithm.

The following is the code i'm using to try to leverage the GDI+ libraries to allow me to look at individual pixels in a jpeg compressed image:

// lpbmi and lpBits come from a hooked StretchDIBits call. I did not generate this data.
// The following is some sample data that i've seen go in and not work:
//
// lpbmi->bmiHeader.biSize = 40 
// lpbmi->bmiHeader.biWidth = 1299 
// lpbmi->bmiHeader.biHeight = -1 
// lpbmi->bmiHeader.biPlanes = 1 
// lpbmi->bmiHeader.biBitCount = 0 
// lpbmi->bmiHeader.biCompression = 4        // resolves to BI_JPEG 
// lpbmi->bmiHeader.biSizeImage = 955 
// lpbmi->bmiHeader.biXpelsPerMeter = 0 
// lpbmi->bmiHeader.biYpelsPerMeter = 0 
// lpbmi->bmiHeader.biClrUsed = 0 
// lpbmi->bmiHeader.biClrImportant = 0 
//
// This data looks valid to me, so i don't know why nothing happens when trying to convert
// it into a Gdiplus::Bitmap
void SomeMethod(const BITMAPINFO * lpbmi, const void * lpBits)
{
    // Apparently, this is needed before using GDI+ libraries. I experimented
    // without this and nothing different happend.  Not even a crash.
    GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR gdiplusToken;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

    // Because the BitmapClass doesn't take in a (const void *), I have to copy the data
    // into another array.  Not much i can do about it because i'm given lpBits as a
    // (const void *)
    void * data = malloc(lpbmi->bmiHeader.biSizeImage);
    memcpy(data, lpBits, lpbmi->bmiHeader.biSizeImage);

    // I "expect" that this bascially reads in the data provided and creates our
    // Bitmap class.
    Bitmap bitmap(lpbmi, data);

    // The problem is, Width and Height are always 0.  Can't figure out why.
    UINT Width = bitmap->GetWidth();        // Why always 0????
    UINT Height = bitmap->GetHeight();      // Why always 0????

    //////////////////////
    // Some more code ...
    //////////////////////
}

Anyone have any ideas why the Gdiplus::Bitmap class isn't doing anything with the data I'm giving it?

Ultratrunks
  • 2,464
  • 5
  • 28
  • 48
  • Check out functions in `GdiPlusImageCodec.h` to get the encoding and create the bitmap. I found it's also somewhat easier to [create the bitmap from a stream](http://stackoverflow.com/questions/4598872/creating-hbitmap-from-memory-buffer) when I had trouble. – AJG85 Apr 26 '12 at 23:57

0 Answers0