开发者

libjpeg/CreateDIBSection problem

I'm writing a Win32-based application that displays jpeg images from a database. I picked libjpeg as the decoder, but most images display incorrectly. It can be fixed by increasing or decreasing the width of image by one, however, images that have been displayed correctly before display incorrectly after this fix. Here's part of my code (excluding RGB to BGR conversion):

int JpegToRaw(BYTE *input, int insize, BYTE *output, int &width, int &height)
{
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;

    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_decompress(&cinfo);

    jpeg_mem_src(&cinfo, input, insize);
    jpeg_read_header(&cinfo, TRUE);

    jpeg_start_decompress(&cinfo);

    //--cinfo.output_width; or ++cinfo.output_width;

开发者_StackOverflow中文版    int row_stride = cinfo.output_width * 3;
    int outsize = row_stride * cinfo.output_height;
    output = (BYTE *)malloc(outsize * sizeof(BYTE));
    BYTE *pos = output;

    while (cinfo.output_scanline < cinfo.output_height)
    {
        jpeg_read_scanlines(&cinfo, &pos, 1);
        pos += row_stride;
    }

    width = cinfo.output_width;
    height = cinfo.output_height;

    jpeg_finish_decompress(&cinfo);
    jpeg_destroy_decompress(&cinfo);
    return outsize;
}

HBITMAP RawToBitmap(BYTE *input, int size, int width, int height)
{
    BITMAPINFO bi;
    bi.bmiHeader.biSize        = sizeof(bi24BitInfo.bmiHeader);
    bi.bmiHeader.biWidth       = width;
    bi.bmiHeader.biHeight      = -height;
    bi.bmiHeader.biPlanes      = 1;
    bi.bmiHeader.biBitCount    = 24;
    bi.bmiHeader.biCompression = BI_RGB;

    HBITMAP hBitmap = CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, NULL, NULL, 0);
    SetBitmapBits(hBitmap, size, input);
    return hBitmap;
}

I'm sure I pass valid jpeg arrays to JpegToRaw(), but I have no idea why do the images display different. Can someone help me to get it?


The documentation about BITMAPINFO states this about a DIB:

[…] each scan line must be padded with zeroes to end on a LONG data-type boundary.

This means that row_stride must be a multiple of 4 bytes. Here's one way to calculate this:

int row_stride = (cinfo.output_width * 3 + 3) / 4 * 4;

Similarly, the size of a DDB row must be a multiple of 2.


For the Windows bitmaps, the scanlines need to be padded out to DWORD boundaries. Your test images might have an odd width.


You don't need libjpeg ! Jpeg is native in Windows (Shell), like all graphic formats

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜