Problem with bmp.biBitCount =24(or)8(or)16 + vc++

Questions and postings pertaining to the development of ImageMagick, feature enhancements, and ImageMagick internals. ImageMagick source code and algorithms are discussed here. Usage questions which are too arcane for the normal user list should also be posted here.
Post Reply
wizards
Posts: 46
Joined: 2008-12-05T06:31:55-07:00

Problem with bmp.biBitCount =24(or)8(or)16 + vc++

Post by wizards »

Hello All,

I am new to ImageMagick and doing a small application using VC++.
I have a problem with loading image.

Please observe the following VC++ code once.


#if (QuantumDepth == 8 )
#define ScaleQuantumToChar(quantum) ((unsigned char) (quantum))
#elif (QuantumDepth == 16)
#define ScaleQuantumToChar(quantum) ((unsigned char) ((quantum)/257))
#elif (QuantumDepth == 32)
#define ScaleQuantumToChar(quantum) ((unsigned char) ((quantum)/16843009UL))
#elif (QuantumDepth == 64)
#define ScaleQuantumToChar(quantum) \
((unsigned char) ((quantum)/71777214294589695))
#endif


PreparedDC (Image m_Image,int x, int y)
{



HBITMAP hBitmap;

BITMAPINFO bitinfo;
memset(&bitinfo, 0, sizeof(bitinfo));
BITMAPINFOHEADER bmi;
// make sure we're getting a valid image!
if (!m_Image.isValid())
{
return;
}

// if the view is dirty, dispose the old offscreen!
if ( mViewDirty == true ) {
delete mOffscreenDC;
mOffscreenDC = NULL;
}

// if we don't already have a ready offscreen, then prepare one
if ( !mOffscreenDC ) {
//
// Set up the Windows bitmap header
//
//BITMAPINFOHEADER bmi;
bmi.biSize = sizeof(BITMAPINFOHEADER); // Size of structure
bmi.biWidth = m_Image.columns(); // Bitmaps width in pixels
bmi.biHeight = (-1)*m_Image.rows(); // Bitmaps height n pixels
bmi.biPlanes = 1; // Number of planes in the image
bmi.biBitCount = 32; // The number of bits per pixel
bmi.biCompression = BI_RGB; // The type of compression used
bmi.biSizeImage = 0; // The size of the image in bytes
bmi.biXPelsPerMeter = 0; // Horizontal resolution
bmi.biYPelsPerMeter = 0; // Veritical resolution
bmi.biClrUsed = 0; // Number of colors actually used
bmi.biClrImportant = 0; // Colors most important
mBMI = bmi; // keep it for clipboard use...

mOffscreenDC = new CDC();

RGBQUAD *prgbaDIB = 0;
hBitmap = CreateDIBSection
(
mOffscreenDC->GetSafeHdc(), // handle to device context
(BITMAPINFO *)&bmi, // pointer to structure containing bitmap size, format, and color data
DIB_RGB_COLORS, // color data type indicator: RGB values or palette indices
(void**)&prgbaDIB, // pointer to variable to receive a pointer to the bitmap's bit values
NULL, // optional handle to a file mapping object
0 // offset to the bitmap bit values within the file mapping object
);

if ( !hBitmap )
{
CString message;
message.FormatMessage("Windows failed to allocate bitmap of size %1!d!x%2!d!!",
m_Image.rows(), m_Image.columns());
return;
}

//
// If image is non-opaque, create overlay the image on top of
// a pattern background so non-opaque regions become evident.
//

/*Magick::Image image=m_Image;
if (m_Image.matte())
{
Magick::Image matteImage;
matteImage.size(Magick::Geometry(m_Image.columns(), m_Image.rows()));
matteImage.read("pattern:checkerboard");
matteImage.composite(m_Image,0,0,AtopCompositeOp);
image=matteImage;
}*/

//
// Extract the pixels from Magick++ image object and convert to a DIB section
//

const unsigned int columns = m_Image.columns();
const unsigned int rows = m_Image.rows();

RGBQUAD *pDestPixel = prgbaDIB;

for( unsigned int row = 0 ; row < rows ; row++ )
{
const PixelPacket *pPixels = m_Image.getConstPixels(0,row,columns,1);
#if QuantumDepth == 8
// Form of PixelPacket is identical to RGBQUAD when QuantumDepth==8
memcpy((void*)pDestPixel,(const void*)pPixels,sizeof(PixelPacket)*columns);
pDestPixel += columns;

#else // 16 or 32 bit Quantum
// Transfer pixels, scaling to Quantum

for( unsigned long nPixelCount = columns; nPixelCount ; nPixelCount-- )
{
pDestPixel->rgbRed = ScaleQuantumToChar(pPixels->red);
pDestPixel->rgbGreen = ScaleQuantumToChar(pPixels->green);
pDestPixel->rgbBlue = ScaleQuantumToChar(pPixels->blue);
pDestPixel->rgbReserved = 0;
++pDestPixel;
++pPixels;
}
#endif
}

// Create a display surface

mOffscreenDC->CreateCompatibleDC( NULL );

// Now copy the bitmap to device
mOffscreenDC->SelectObject( hBitmap );
DeleteObject( hBitmap );
}


mViewDirty = false; // not any more!

}






From above code..
If i entered ....bmi.biBitCount = 32 (or) 64 (or) 128...
Its working good...
Otherwise if i entered ... bmi.biBitCount = 8 (or) 16 (or) 24....
It gives runtime error.

Please Help me....


Thanks in Advance...
el_supremo
Posts: 1015
Joined: 2005-03-21T21:16:57-07:00

Re: Problem with bmp.biBitCount =24(or)8(or)16 + vc++

Post by el_supremo »

- what is the version and quantumdepth of the ImageMagick you are compiling against?
- do you get any compiler warnings for this code?
- what is the runtime error?

Pete
Sorry, my ISP shutdown all personal webspace so my MagickWand Examples in C is offline.
See my message in this topic for a link to a zip of all the files.
wizards
Posts: 46
Joined: 2008-12-05T06:31:55-07:00

Re: Problem with bmp.biBitCount =24(or)8(or)16 + vc++

Post by wizards »

Hii..
Thanks for responding..
We are using ImageMagick-6.3.4 version..
And quantum depth 16 bit...
No Compiler warnings...

Im using the above code for displaying image...
While im loading image....
It gives " XXXXXX application has encountered a problem and needs to close. we are sorry for the inconvience" dialog box comes....And
Application will break...
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Problem with bmp.biBitCount =24(or)8(or)16 + vc++

Post by fmw42 »

Sorry to chime in here as I know little about your development environment. But your version of IM is extremely old. It is over 250 versions old compared to the current 6.6.0-5. Many bugs have been fixed and many new features added. Perhaps it is time to upgrade.
el_supremo
Posts: 1015
Joined: 2005-03-21T21:16:57-07:00

Re: Problem with bmp.biBitCount =24(or)8(or)16 + vc++

Post by el_supremo »

I don't think the problem is with IM, it's something to do with the structure of the bitmap header and how the colour information is stored.
The way that the colours are represented is dependent upon the value of biBitCount but your code only writes the info in one way which, since it doesn't crash, appears to be correct when bmi.biBitCount=32 but is wrong for other values.
See the description of biBitCount in http://msdn.microsoft.com/en-us/library ... 85%29.aspx You always write the colours into an array of RGBQUAD structs but that's not what is described in the docs. In particular, when biBitCount=24, the colours must be grouped in 3-byte triplets, not 4-byte quads.
You should also be careful that, if you fix this, it will only work correctly when using a Q16 version of IM. Your code does something different when compiled with IM Q8.

Pete
Sorry, my ISP shutdown all personal webspace so my MagickWand Examples in C is offline.
See my message in this topic for a link to a zip of all the files.
wizards
Posts: 46
Joined: 2008-12-05T06:31:55-07:00

Re: Problem with bmp.biBitCount =24(or)8(or)16 + vc++

Post by wizards »

Thanks for your reply....

Its working good....

I replaced RGBQUAD with RGBTRIPLE for bitBitCount=24.
Post Reply