CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3

Thread: Decompress JPEG

  1. #1
    Join Date
    May 1999
    Posts
    12

    Decompress JPEG

    Can anybody point me in the right direction -
    I need to be able to decompress a jpg from memory. I am using Independent JPEG Group's JPEG library. They have examples on reading and decompressing a jpeg from a file but I want to read a jpg from a webserver into memory. In memory, I want to decompress the jpeg and do something with it. I know how to get the jpg from a webserver. Does anybody have any experience with do something like this? Independent JPEG Group's mentions that I have to create a custom source manager???


  2. #2
    Join Date
    Apr 1999
    Posts
    53

    Re: Decompress JPEG

    Dear Kevin,

    Take a look at "paintlib", which can be downloaded from the bitmap and graphics section of this site.

    I seem to recall that it had a way of reading a jpeg file and turning it into a bitmap for display.

    Hope this helps,
    Wes Rogers


  3. #3
    Join Date
    May 1999
    Posts
    10

    Re: Decompress JPEG

    Consult the decompression example in the example.c file from IJG -- using this code I was able to put together a simple decompression function to decompress from a jpeg to a 24 bpp dib, the code for which follows. The trick with converting jpegs to Windows dibs is that there are two big format differences between the two: (i) jpeg rows are ordered top to bottom, while in Windows dibs rows are ordered bottom to top and (ii) jpeg RGBs are in true RGB order, while Windows dib RGBs are actually in BGR order -- the "for" loop in the enclosed code does both reversals.

    This code is part of a simple 24 bpp DIB class I put together (which I assume you have, or can whip up, your own version of) and refers to several member variables and functions of that class -- m_Width (of new dib, in pixels), m_Height (of new dib, in pixels), m_pData (unsigned char* -- holds image RGB data) and Create (creates a new dib, given width, height and a name) -- of course, you will have to substitute the names for the analogous members from your class.

    What I have been working on is a class that takes a jpeg, converts it to a dib and then does the necessary byte reordering and sizing to be used as an OpenGL texture -- in OpenGL, for a dib to work as a texture, width and height pixel dimensions must both be powers of two, and the RGB byte ordering is true RGB (that is, like jpeg, not Windows dib). If I get it done anytime soon maybe I'll send it in. In working on the project I have found the following very helpful:

    1. The IJG materials you referred to -- especially the libjpeg text file (which provides an overview) and the example.c mentioned above.
    2. Wes Rogers' article on DIB to JPEG compression in CodeGuru's "Bitmaps & Palletes" section.
    3. Pierre Alliez's submission to CodeGuru's "OpenGL" section, which covers dibs and OpenGL (it does RGB reordering, but not power-of-two resizing), but does not cover jpeg.
    4. Dale Rogerson's OpenGL articles on MSDN (which cover OpenGL and dibs, but not jpeg).
    5. Chris Losinger of smalleranimals.com has made a number of useful submissions to CodeGuru and his site offers inexpensive as well as freewear image processing programs.
    6. Ulrich von Zadow's PaintLib (which is referenced in CodeGuru -- either in "Bitmaps & Palettes", "Misc" or "Links") is a very comprehensive image processing tool (supporting many formats), though I have not put in the effort to get it running.

    Note that someone may suggest using new Win 32 GDI extensions for the decompression. While I think this helps for the display of jpegs (and pngs), I do not think it can be used to decompress into a dib (see the following MSDN article):

    "JPEG and PNG Extensions for Specific Bitmap Functions and Structures
    Starting with the Microsoft® Windows® 98 and Windows NT® 5.0 operating systems, the StretchDIBits <bitmaps_1ppv.htm> and SetDIBitsToDevice <bitmaps_8e5h.htm> functions have been extended to allow JPEG and PNG images to be passed as the source image to printer devices. This extension is not intended as a means to supply general JPEG and PNG decompression to applications, but rather to allow applications to send JPEG- and PNG-compressed images directly to printers having hardware support for JPEG and PNG images.
    The BITMAPINFOHEADER <bitmaps_1rw2.htm>, BITMAPV4HEADER <bitmaps_2k1e.htm> and BITMAPV5HEADER <bitmaps_7c36.htm> structures are extended to allow specification of biCompression values indicating that the bitmap data is a JPEG or PNG image. These compression values are only valid for SetDIBitsToDevice and StretchDIBits when the hdc parameter specifies a printer device. To support metafile spooling of the printer, the application should not rely on the return value to determine whether the device supports the JPEG or PNG file. The application must issue QUERYESCSUPPORT with the corresponding escape before calling SetDIBitsToDevice and StretchDIBits. If the validation escape fails, the application must then fall back on its own JPEG or PNG support to decompress the image into a bitmap."

    I hope the foregoing is helpful.


    BOOL CTexture::CreateFromJpeg(CString csJpeg) //Pathname to jpeg file
    {
    if (csJpeg == "")
    {
    AfxMessageBox("Invalid input data.");
    return FALSE;
    }
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
    cinfo.err = jpeg_std_error(&jerr);
    FILE* pInFile; //Source JPEG file
    if ((pInFile = fopen(csJpeg, "rb")) == NULL)
    {
    AfxMessageBox("Cannot open " + csJpeg + ".");
    return FALSE;
    }
    jpeg_create_decompress(&cinfo);
    jpeg_stdio_src(&cinfo, pInFile);
    jpeg_read_header(&cinfo, TRUE);
    jpeg_start_decompress(&cinfo);
    //Create empty DIB of proper size
    CString csBmp = csJpeg.SpanExcluding(".");
    csBmp += ".bmp";
    Create(cinfo.output_width, cinfo.output_height, csBmp);
    //Allocate single row of JSAMPs
    JSAMPARRAY jsmpPixels = (*cinfo.mem->alloc_sarray)
    ((j_common_ptr) &cinfo,
    JPOOL_IMAGE,
    cinfo.image_width * cinfo.output_components,
    1);
    LPBYTE lpPixels = (LPBYTE)m_pData;
    unsigned int nBytesWide = (m_Width * 3);
    unsigned int nUnused = (((nBytesWide + 3) / 4) * 4) - nBytesWide;
    nBytesWide += nUnused;
    unsigned int q, nRow, nPixel;
    while (cinfo.output_scanline < cinfo.output_height)
    {
    jpeg_read_scanlines(&cinfo, jsmpPixels, 1);
    for (q=0; q < (nBytesWide-nUnused); q+=3)
    {
    nRow = (m_Height - cinfo.output_scanline) * nBytesWide;
    nPixel = nRow + q;
    lpPixels[nPixel+2] = jsmpPixels[0][q+0]; //Red
    lpPixels[nPixel+1] = jsmpPixels[0][q+1]; //Green
    lpPixels[nPixel+0] = jsmpPixels[0][q+2]; //Blue
    }
    }
    jpeg_finish_decompress(&cinfo);
    jpeg_destroy_decompress(&cinfo);
    fclose(pInFile);
    return TRUE;
    }





Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured