Thread: Istream::Release access violation? [C++]

  1. #1
    Registered User
    Join Date
    Nov 2006
    Posts
    85

    Istream::Release access violation? [C++]

    I'm trying to convert a jpg image acquired from the internet into an HBITMAP. I'd like to be able to check the pixel by pixel values of the image (specifically I'm looking for blue pixels in a jpg image)

    I successfully grap the JPG image from the internet with this function:
    Code:
    HBITMAP Internet::getFromInternet(std::string gal)
    {
         hInternet = InternetOpen( "GINA: Version 0.1", INTERNET_OPEN_TYPE_DIRECT, NULL, 0,0);
         
         std::string temp = gal  + ".overview.jpg";
         gal = "http://www.imperialconflict.com/images/Galaxies/";
         gal += temp;
         MessageBox(NULL,gal.c_str(),"",MB_OK);
         
         //get size of file
         hFile = InternetOpenUrl(hInternet, gal.c_str(), NULL, 0, 0, 0);
         DWORD sizeBuffer;
         DWORD length = sizeof(sizeBuffer);
         BYTE *buffer = NULL;
         
         bool succeeds = HttpQueryInfo(hFile, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, (LPVOID)&sizeBuffer, &length, NULL);
         if (!succeeds)
         {
            throw "Unable to fetch map";
            return (HBITMAP) NULL;
         }
         buffer = new BYTE[sizeBuffer];
         
         //initialize all elements to 0
         for (int i = 0; i < sizeBuffer; i++)
             buffer[i] = 0;
              
         //get file     
         DWORD bytesRead;
         DWORD bytesToRead = sizeBuffer;
         if (hFile)
         {
                   InternetReadFile(hFile, buffer, bytesToRead, &bytesRead);
         }
         else
             throw "Unable to grab overview image";
         InternetCloseHandle(hFile);
         InternetCloseHandle(hInternet);
         return loadImage(buffer);
    }
    It calls this function loadImage(BYTE*)
    Code:
    HBITMAP Internet::loadImage(BYTE* jpgData)
    {
            /* TODO (#1#): Fix access violaion in code below.
            May have something to do with how I'm passing jpgData*/
            MessageBox(NULL,"Load Image 1", "", NULL); 
            IPicture* pic = 0;
            IStream* stream = 0;
            IPersistStream* ps = 0; 
            void* pp = (void*)jpgData;
            MessageBox(NULL,"Load Image 3", "", NULL); 
            OleLoadPicture(stream,0,false,IID_IPicture,(void**)&pic);
            MessageBox(NULL,"Load Image 4", "", NULL);
            stream->Release(); //access violation here?
            MessageBox(NULL,"Load Image 5", "", NULL);
            HBITMAP hB = 0;
            MessageBox(NULL,"Load Image 6", "", NULL);
            pic->get_Handle((unsigned int*)&hB);
            MessageBox(NULL,"Load Image 7", "", NULL);
            // Copy the image. Necessary
            HBITMAP hBB = (HBITMAP)CopyImage(hB,IMAGE_BITMAP,0,0,LR_COPYRETURNORG);
            pic->Release();
            delete [] jpgData; //IMPORTANT
            return hBB;
    }
    stream->Release() causes an access violation. I have no idea why and googling hasn't revealed any answers.

    Is their another way to check the data at a pixel without converting a jpg into an HBITMAP? Maybe some incredibly magical libraries?

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Aren't you supposed to open the IStream with the file that contains the JPEG?

    This page indicates so:
    http://msdn.microsoft.com/en-us/libr...24(VS.85).aspx

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Nov 2006
    Posts
    85
    Well that squashed all my hope

    Do you know of any way to convert a jpg loaded as a BYTE* [] into a hbitmap?

  4. #4
    Registered User
    Join Date
    Nov 2006
    Posts
    85
    Well, I've been looking into libjpeg and I've found plenty of examples on how to convert a jpeg from a file into an HBITMAP but none describing how to change the source from a file handle to a BYTE [].

    So sloppily pasting one of the examples into my function, I have this:
    Code:
    HBITMAP Internet::loadImage(BYTE* jpgData)
    {
            char *filename = "Something";
        	unsigned char *raw_image = NULL;
        	/* these are standard libjpeg structures for reading(decompression) */
        	struct jpeg_decompress_struct cinfo;
        	struct jpeg_error_mgr jerr;
        	/* libjpeg data structure for storing one row, that is, scanline of an image */
        	JSAMPROW row_pointer[1];
        	
        	FILE *infile = fopen( filename, "rb" );
        	unsigned long location = 0;
        	int i = 0;
        	
        	if ( !infile )
        	{
               throw "Anything. I know that the file name is bad.";
       		   return (HBITMAP) 0;
        	}
        	/* here we set up the standard libjpeg error handler */
        	cinfo.err = jpeg_std_error( &jerr );
        	/* setup decompression process and source, then read JPEG header */
        	jpeg_create_decompress( &cinfo );
        	/* this makes the library read from infile */
        	jpeg_stdio_src( &cinfo, infile );      //The source should be jpgData!
        	/* reading the image header which contains image information */
        	jpeg_read_header( &cinfo, TRUE );
        	/* Start decompression jpeg here */
        	jpeg_start_decompress( &cinfo );
        
        	/* allocate memory to hold the uncompressed image */
        	raw_image = (unsigned char*)malloc( cinfo.output_width*cinfo.output_height*cinfo.num_components );
        	/* now actually read the jpeg into the raw buffer */
        	row_pointer[0] = (unsigned char *)malloc( cinfo.output_width*cinfo.num_components );
        	/* read one scan line at a time */
        	while( cinfo.output_scanline < cinfo.image_height )
        	{
        		jpeg_read_scanlines( &cinfo, row_pointer, 1 );
        		for( i=0; i<cinfo.image_width*cinfo.num_components;i++) 
        			raw_image[location++] = row_pointer[0][i];
        	}
        	/* wrap up decompression, destroy objects, free pointers and close open files */
        	jpeg_finish_decompress( &cinfo );
        	jpeg_destroy_decompress( &cinfo );
        	free( row_pointer[0] );
        	fclose( infile );
        	/* yup, we succeeded! */
        	return (HBITMAP) 0;  //No we didn't :(
    }

  5. #5
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Quote Originally Posted by A10 View Post
    Well, I've been looking into libjpeg and I've found plenty of examples on how to convert a jpeg from a file into an HBITMAP
    If you had a HBITMAP you could;

    Create a temp DC ( CreateCompatibleDC(NULL) )
    Select the HBITMAP into the DC (catching the returned default HBITMAP) with SelectObject()
    loop thru the pixels with GetPixel(),
    testing if each is 'blue' by using GetBValue(), GetRValue() and GetGValue()

    clean up by
    Selecting the default HBITMAP back into the DC
    then DeleteDC() on the mem DC
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    And what is wrong with LoadImage() with LR_LOADFROMFILE as the fuLoad parameter?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    Quote Originally Posted by matsp View Post
    And what is wrong with LoadImage() with LR_LOADFROMFILE as the fuLoad parameter?
    It only loads bmp files, nothing else. GDI+ on the other hand can load more of the "exotic" standard image formats such as JPG, PNG, TIFF and GIF.

    Code:
    #include <windows.h>
    #include <gdiplus.h>
    #include <cstdlib>
    #include <vector>
    #include <string>
    #include <stdexcept>
    
    // wrapper around GDI+ startup and shutdown
    struct ScopedGDI
    {
        ULONG_PTR token;
    public:
        ScopedGDI()
        {
            Gdiplus::GdiplusStartupInput gdiInput;
            Gdiplus::GdiplusStartup(&token, &gdiInput, NULL);
        }
        ~ScopedGDI()
        {
            Gdiplus::GdiplusShutdown(token);
        }
    };
    
    std::wstring ConvertToWString(const std::string& narrowString)
    {
        size_t sizeRequired = mbstowcs(NULL, file.c_str(), file.length());
        if(sizeRequired != static_cast<size_t>(-1))
        {
            std::vector<WCHAR> wideBuffer(sizeRequired);
            mbstowcs(&wideBuffer[0], file.c_str(), file.length());
            return std::wstring(wideBuffer.begin(), wideBuffer.end());
        }
        else throw std::invalid_argument(std::string("Cannot convert ") + narrowString);
    }
    
    HBITMAP GetHBitmapFromFile(const std::string& file)
    {
        HBITMAP hBM = NULL;
        std::wstring wideFile = ConvertToWString(file);
    
        using namespace Gdiplus;
        ScopedGDI gdi; // initialize GDI+
        Color background; // colour to make any transparent sections - defaults to black
        Bitmap bm(wideFile.c_str()); // create a bitmap object for the file
        bm.GetHBITMAP(background, &hBM); // grab the image as a hbitmap
        return hBM;
    }
    An alternative to using a hbitmap (assuming you don't want it for anything else) is to use the LockBits method of the Bitmap class and look through those rather than making an extra copy. You would have to refactor the lifetime of the bitmap object if you went that route though.

    If a file in undesirable, then the Bitmap class provides an IStream* constructor too. You'd have to change your getFromInternet function to use GlobalAlloc(GHND, size) instead of new, and GlobalLock/GlobalUnlock to get a pointer you can InternetReadFile into. Then you can use this to get the HBitmap

    Code:
    #include <ole2.h>
    
    HBITMAP GetHBitmapFromHGlobal(HGLOBAL hMem)
    {
        HBITMAP hBM = NULL;
        IStream* stream = NULL;
        if(SUCCEEDED(CreateStreamOnHGlobal(hMem, FALSE, &stream)))
        {
            using namespace Gdiplus;
            ScopedGDI gdi;
            Color background;
            {
                Bitmap bm(stream);
                bm.GetHBITMAP(background, &hBM);
                // bitmap must be dsestructed before the stream is released
            }
            stream->Release();
        }
        return hBM;
    }

  8. #8
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    I'm trying to convert a jpg image acquired from the internet into an HBITMAP. I'd like to be able to check the pixel by pixel values of the image (specifically I'm looking for blue pixels in a jpg image)
    Give this a try...

    Code:
    LPPICTURE gpPicture; 
    
    
    HBITMAP getFromInternet(std::string gal)
    {
    
        HBITMAP    hBitmap;
        HINTERNET      hInternet = InternetOpen( "GINA: Version 0.1", INTERNET_OPEN_TYPE_DIRECT, NULL, 0,0);
    
        std::string temp = gal  + ".overview.jpg";
        gal = "http://www.imperialconflict.com/images/Galaxies/";
        gal += temp;
        MessageBox(NULL,gal.c_str(),"",MB_OK);
        //get size of file
        HINTERNET     hFile = InternetOpenUrl(hInternet, gal.c_str(), NULL, 0, 0, 0);
        DWORD sizeBuffer;
        DWORD length = sizeof(sizeBuffer);
        BYTE *buffer = NULL;
    
        bool succeeds = HttpQueryInfo(hFile, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, (LPVOID)&sizeBuffer, &length, NULL);
        if (!succeeds)
        {
            throw "Unable to fetch map";
            return (HBITMAP) NULL;
        }
        buffer = new BYTE[sizeBuffer];
    
        //initialize all elements to 0
        for (int i = 0; i < sizeBuffer; i++)
            buffer[i] = 0;
    
        LPVOID pvData = NULL; 
        HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, sizeBuffer); 
        pvData = GlobalLock(hGlobal); 
        DWORD bytesRead;
        DWORD bytesToRead = sizeBuffer;
        if (hFile)
        {
            InternetReadFile(hFile, pvData, bytesToRead, &bytesRead);
        }
        else
            throw "Unable to grab overview image";
    
        GlobalUnlock(hGlobal); 
        CloseHandle(hFile); 
        LPSTREAM pstm = NULL; 
        // create IStream* from global memory 
        HRESULT hr = CreateStreamOnHGlobal(hGlobal, TRUE, &pstm); 
        // Create IPicture from image file 
        if (gpPicture) 
            gpPicture->Release(); 
        hr = OleLoadPicture(pstm, sizeBuffer, FALSE, IID_IPicture, (LPVOID *)&gpPicture); 
        pstm->Release(); 
        gpPicture-> get_Handle ((OLE_HANDLE *) & hBitmap); 
        hBitmap = (HBITMAP) CopyImage (hBitmap, IMAGE_BITMAP, 0,0,0); 
        InternetCloseHandle(hFile);
        InternetCloseHandle(hInternet);
        return hBitmap;
    }
    Be advised that reading the pixels is not as simple and straighforward as you may think it is.

  9. #9
    Registered User
    Join Date
    Nov 2006
    Posts
    85
    Quote Originally Posted by BobS0327 View Post
    Give this a try...

    Code:
    LPPICTURE gpPicture; 
    
    
    HBITMAP getFromInternet(std::string gal)
    {
    
        HBITMAP    hBitmap;
        HINTERNET      hInternet = InternetOpen( "GINA: Version 0.1", INTERNET_OPEN_TYPE_DIRECT, NULL, 0,0);
    
        std::string temp = gal  + ".overview.jpg";
        gal = "http://www.imperialconflict.com/images/Galaxies/";
        gal += temp;
        MessageBox(NULL,gal.c_str(),"",MB_OK);
        //get size of file
        HINTERNET     hFile = InternetOpenUrl(hInternet, gal.c_str(), NULL, 0, 0, 0);
        DWORD sizeBuffer;
        DWORD length = sizeof(sizeBuffer);
        BYTE *buffer = NULL;
    
        bool succeeds = HttpQueryInfo(hFile, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, (LPVOID)&sizeBuffer, &length, NULL);
        if (!succeeds)
        {
            throw "Unable to fetch map";
            return (HBITMAP) NULL;
        }
        buffer = new BYTE[sizeBuffer];
    
        //initialize all elements to 0
        for (int i = 0; i < sizeBuffer; i++)
            buffer[i] = 0;
    
        LPVOID pvData = NULL; 
        HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, sizeBuffer); 
        pvData = GlobalLock(hGlobal); 
        DWORD bytesRead;
        DWORD bytesToRead = sizeBuffer;
        if (hFile)
        {
            InternetReadFile(hFile, pvData, bytesToRead, &bytesRead);
        }
        else
            throw "Unable to grab overview image";
    
        GlobalUnlock(hGlobal); 
        CloseHandle(hFile); 
        LPSTREAM pstm = NULL; 
        // create IStream* from global memory 
        HRESULT hr = CreateStreamOnHGlobal(hGlobal, TRUE, &pstm); 
        // Create IPicture from image file 
        if (gpPicture) 
            gpPicture->Release(); 
        hr = OleLoadPicture(pstm, sizeBuffer, FALSE, IID_IPicture, (LPVOID *)&gpPicture); 
        pstm->Release(); 
        gpPicture-> get_Handle ((OLE_HANDLE *) & hBitmap); 
        hBitmap = (HBITMAP) CopyImage (hBitmap, IMAGE_BITMAP, 0,0,0); 
        InternetCloseHandle(hFile);
        InternetCloseHandle(hInternet);
        return hBitmap;
    }
    Be advised that reading the pixels is not as simple and straighforward as you may think it is.


    Wow these have all been great responses. Unfortunately I've been away for a while as my system was rootkit-ed. It's been quite a battle to remove it. It disabled all current antivirus software and prevented the installation of new antivirus/antirootkit software.

    Anyways I originally had something that looked like the above. Then I read on msnd that OleLoadPicture only supports bitmaps, gifs, and icons. That led me to libjpeg.

    If you had a HBITMAP you could;

    Create a temp DC ( CreateCompatibleDC(NULL) )
    Select the HBITMAP into the DC (catching the returned default HBITMAP) with SelectObject()
    loop thru the pixels with GetPixel(),
    testing if each is 'blue' by using GetBValue(), GetRValue() and GetGValue()

    clean up by
    Selecting the default HBITMAP back into the DC
    then DeleteDC() on the mem DC
    That's perfect. I heard that GetPixel() can be a bit slow though. I'd need to check all the pixels in under 2 seconds. Do you think I could do that with a GetPixel() routine?

    GDI+ on the other hand can load more of the "exotic" standard image formats such as JPG, PNG, TIFF and GIF.
    Very very good post. I'd rather avoid GDI+. No particular reason. Just makes me 'icky'.

    I'm still experimenting with source managers and libjpeg. I found a source manager at http://www.groupsrv.com/science/about102031.html but I don't know of it's licensing so I'm writing my own with that one as a reference.

    I'll will post an update tomorrow. Thank you!

  10. #10
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    Anyways I originally had something that looked like the above. Then I read on msnd that OleLoadPicture only supports bitmaps, gifs, and icons. That led me to libjpeg.
    Proof of concept code that proves OleLoadPicture supports jpeg. Right click on the image to change all the totally black pixels to totally white pixels.

    Code:
    #pragma comment( lib, "user32.lib" )
    #pragma comment( lib, "olepro32.lib" )
    #pragma comment( lib, "gdi32.lib" )
    #pragma comment( lib, "ole32.lib" )
    #pragma comment( lib, "Wininet.lib" )
    
    #include <windows.h> 
    #include <Wininet.h>
    #include <olectl.h> 
    
    #define COLORREF2RGB(Color) (Color & 0xff00) | ((Color >> 16) & 0xff) \
                                    | ((Color << 16) & 0xff0000)
    
    LPPICTURE gpPicture; 
    HBITMAP hbm;
    
    HBITMAP ChangePixels(HBITMAP hBmp,COLORREF cOldColor,COLORREF cNewColor,HDC hBitmapDC)
    {
        HBITMAP hReturnBitmap = NULL;
        if (hBmp)
        {   
            HDC BufferDC=CreateCompatibleDC(NULL); 
            if (BufferDC)
            {
                HBITMAP hTempBitmap = (HBITMAP) NULL;
                if (hBitmapDC)
                    if (hBmp == (HBITMAP)GetCurrentObject(hBitmapDC, OBJ_BITMAP))
                    {
                        hTempBitmap = CreateBitmap(1, 1, 1, 1, NULL);
                        SelectObject(hBitmapDC, hTempBitmap);
                    }
                HGDIOBJ PreviousBuffer=SelectObject(BufferDC,hBmp);
                HDC DirectDC=CreateCompatibleDC(NULL); 
                if (DirectDC)
                {
                    BITMAP bm;
                    GetObject(hBmp, sizeof(bm), &bm);
                    BITMAPINFO BitmapInfo; 
                    ZeroMemory(&BitmapInfo,sizeof(BITMAPINFO));
                    BitmapInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
                    BitmapInfo.bmiHeader.biWidth=bm.bmWidth;
                    BitmapInfo.bmiHeader.biHeight=bm.bmHeight;
                    BitmapInfo.bmiHeader.biPlanes = 1;
                    BitmapInfo.bmiHeader.biBitCount = 32;
                    UINT * upPixels; 
                    HBITMAP DirectBitmap= CreateDIBSection(DirectDC, (BITMAPINFO *)&BitmapInfo, DIB_RGB_COLORS,(void **)&upPixels, NULL, 0);
                    if (DirectBitmap)
                    {
                        HGDIOBJ PreviousObject=SelectObject(DirectDC, DirectBitmap);
                        BitBlt(DirectDC,0,0,bm.bmWidth,bm.bmHeight,BufferDC,0,0,SRCCOPY);                   
                        char   cNewColorRef=COLORREF2RGB(cNewColor);
                        for (int iIndex = ((bm.bmWidth*bm.bmHeight) - 1); iIndex >= 0; iIndex--)
                            if (upPixels[iIndex] == cOldColor) upPixels[iIndex] = cNewColorRef;
                        SelectObject(DirectDC,PreviousObject);
                        hReturnBitmap=DirectBitmap;
                    }
                    DeleteDC(DirectDC);
                }           
                if (hTempBitmap)
                {
                    SelectObject(hBitmapDC, hBmp);
                    DeleteObject(hTempBitmap);
                }
                SelectObject(BufferDC,PreviousBuffer);
                DeleteDC(BufferDC);
            }
        }
        return hReturnBitmap;
    }
    
    HBITMAP getFromInternet(char *pURL)
    {
        HBITMAP    hBitmap;
        HINTERNET      hInternet = InternetOpen( "GINA: Version 0.1", INTERNET_OPEN_TYPE_DIRECT, NULL, 0,0);
        HINTERNET     hFile = InternetOpenUrl(hInternet, pURL, NULL, 0, 0, 0);
        DWORD sizeBuffer;
        DWORD length = sizeof(sizeBuffer);
    
        bool succeeds = HttpQueryInfo(hFile, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, (LPVOID)&sizeBuffer, &length, NULL);
        if (!succeeds)
        {
            throw "Unable to fetch map";
            return (HBITMAP) NULL;
        }
        LPVOID pvData = NULL; 
        HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, sizeBuffer); 
        pvData = GlobalLock(hGlobal); 
        DWORD bytesRead;
        DWORD bytesToRead = sizeBuffer;
        if (hFile)
        {
            InternetReadFile(hFile, pvData, bytesToRead, &bytesRead);
        }
        else
            throw "Unable to grab overview image";
        GlobalUnlock(hGlobal); 
        CloseHandle(hFile); 
        LPSTREAM pstm = NULL; 
        // create IStream* from global memory 
        HRESULT hr = CreateStreamOnHGlobal(hGlobal, TRUE, &pstm); 
        // Create IPicture from image file 
        if (gpPicture) 
            gpPicture->Release(); 
        hr = OleLoadPicture(pstm, sizeBuffer, FALSE, IID_IPicture, (LPVOID *)&gpPicture); 
        pstm->Release(); 
        gpPicture-> get_Handle ((OLE_HANDLE *) & hBitmap); 
        hBitmap = (HBITMAP) CopyImage (hBitmap, IMAGE_BITMAP, 0,0,0); 
        InternetCloseHandle(hFile);
        InternetCloseHandle(hInternet);
        return hBitmap;
    }
    
    LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; 
    
    
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) 
    { 
        static char szAppName[] = "JpegExample" ; 
        HWND hwnd; 
        MSG msg; 
        WNDCLASSEX wndclass; 
    
        int WinSize = 500; 
        int Left = 200; 
        int Top = 100; 
    
        wndclass.cbSize = sizeof (wndclass) ; 
        wndclass.style = CS_HREDRAW | CS_VREDRAW; 
        wndclass.lpfnWndProc = WndProc ; 
        wndclass.cbClsExtra = 0 ; 
        wndclass.cbWndExtra = 0 ; 
        wndclass.hInstance = hInstance ; 
        wndclass.hIcon = NULL ; 
        wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; 
        wndclass.hbrBackground = (HBRUSH) (COLOR_WINDOW) ; 
        wndclass.lpszMenuName = NULL ; 
        wndclass.lpszClassName = szAppName ; 
        wndclass.hIconSm = NULL ; 
    
        RegisterClassEx (&wndclass) ; 
    
        hwnd = CreateWindow ( 
            szAppName, 
            "Jpeg Example",
            WS_OVERLAPPEDWINDOW, 
            Left, 
            Top , 
            WinSize, 
            WinSize, 
            NULL, 
            NULL, 
            hInstance, 
            NULL 
            ) ; 
    
        ShowWindow (hwnd, iCmdShow); 
        UpdateWindow (hwnd); 
    
        while (GetMessage (&msg, NULL, 0, 0)) 
        { 
            TranslateMessage (&msg) ; 
            DispatchMessage (&msg) ; 
        } 
        return msg.wParam ; 
    } 
    
    
    LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) 
    { 
        HDC hdc,hMemDC; 
        PAINTSTRUCT ps; 
        BITMAP bm;
        RECT MainRc;
        POINT pt;
        COLORREF colNew, colOld;
    
        switch (iMsg) 
        { 
            case WM_RBUTTONDOWN:
                colNew            = RGB(255,255,255);
                colOld            = RGB(0,0,0);
                hbm =  ChangePixels(hbm,colOld,colNew,NULL);
                InvalidateRect(hwnd, NULL, TRUE); 
                return 0;
            case WM_CREATE : 
                hbm = getFromInternet("http://www.imperialconflict.com/images/Galaxies/Capricorn.overview.jpg");
                return 0 ; 
            case WM_PAINT: 
                hdc = BeginPaint(hwnd, &ps); 
                GetClientRect(hwnd,&MainRc);
                hMemDC =  CreateCompatibleDC(hdc);
                SelectObject(hMemDC,hbm);
                GetObject(hbm,sizeof(BITMAP),&bm);
                pt.x = MainRc.right;
                pt.y = MainRc.bottom;
                SetStretchBltMode(hdc,COLORONCOLOR);
                StretchBlt(hdc,0,0,pt.x,pt.y,hMemDC,0,0,800,600,SRCCOPY);
                DeleteDC(hMemDC);
                EndPaint(hwnd, &ps);     
                return 0 ; 
            case WM_DESTROY : 
                PostQuitMessage (0) ; 
                return 0 ; 
        } 
        return DefWindowProc (hwnd, iMsg, wParam, lParam) ; 
    }

  11. #11
    Registered User
    Join Date
    Nov 2006
    Posts
    85

    Cool

    Quote Originally Posted by BobS0327 View Post
    Proof of concept code that proves OleLoadPicture supports jpeg. Right click on the image to change all the totally black pixels to totally white pixels.
    . . .
    !!!
    You proved this page completely wrong! Edit: For anyone else reading this after, your example also needed uuid.lib linked
    http://msdn.microsoft.com/en-us/libr...24(VS.85).aspx

    Unless is there a provision for icons to use jpeg compression?

    Anyways this comes after I got a working solution with Libjpeg.

    The important part is the source manager here
    Code:
    #ifndef jpegSourceManager_H
    #define jpegSourceManager_H
    
    //modified from http://www.groupsrv.com/science/about102031.html
    
    #include <jpeglib.h>
    
    typedef struct MemSource
    {
           struct jpeg_source_mgr jsm;
           JOCTET * next_input_byte;
           size_t bytes_in_buffer;          
    }MemSource;
    
    static void initSource (j_decompress_ptr cinfo)
    {    
    }
    static boolean fillInputBuffer ( j_decompress_ptr cinfo)
    {
        //should never get here. Jpeg is bad if this happens
        throw "FillInputBuffer called. Jpeg Bad";
        return true;
    }
    static void skipInputData (j_decompress_ptr cinfo, long skipBytes)
    {
        //skipping bytes in stream that libjpeg doesn't care for
        MemSource *msm = (MemSource *)cinfo->src;
        msm->jsm.bytes_in_buffer = msm->bytes_in_buffer - skipBytes;
        msm->jsm.next_input_byte += skipBytes;            
    }
    static void doneWithSource (j_decompress_ptr cinfo)
    {}
    
    static void setUpSource( j_decompress_ptr cinfo, unsigned char *imageData, int length)
    {
           static MemSource mS;
           if (cinfo->src == NULL)
              cinfo->src = (struct jpeg_source_mgr *) &mS;
           MemSource *msm = (MemSource *)cinfo->src;
           msm->jsm.next_input_byte =         imageData;       
           msm->jsm.init_source =             initSource;
           msm->jsm.fill_input_buffer =       fillInputBuffer;
           msm->jsm.skip_input_data =         skipInputData;
           msm->jsm.term_source =             doneWithSource;
           msm->jsm.resync_to_restart =       jpeg_resync_to_restart; //provided by libjpeg
           msm->bytes_in_buffer =             msm->jsm.bytes_in_buffer = length;
           msm->next_input_byte =             imageData;
    }
    
    #endif
    Then the image is decompressed here.
    Note
    Code:
    #define ROW_SIZE     cinfo.output_width * 3
    Code:
    void Internet::loadImage(unsigned char* jpgData, int length)
    {
        	unsigned char *rawImage = NULL;
        	unsigned char *rawBuffer = NULL;
        	MapFile map;
        	/* these are standard libjpeg structures for reading(decompression) */
        	struct jpeg_decompress_struct cinfo;
        	struct jpeg_error_mgr jerr;
        	/* libjpeg data structure for storing one row, that is, scanline of an image */
        	cinfo.err = jpeg_std_error( &jerr );
        	jpeg_create_decompress( &cinfo );
        	//set up source manager so we can read from memory
        	setUpSource( &cinfo, jpgData, length );
        	jpeg_read_header( &cinfo, TRUE );
        	jpeg_start_decompress( &cinfo );
            
        	rawImage = new unsigned char[cinfo.output_height * ROW_SIZE];
        	rawBuffer = new unsigned char[ROW_SIZE];
        	
        	while (cinfo.output_scanline < cinfo.output_height)
            {
                  jpeg_read_scanlines( &cinfo, &rawBuffer, 1 );
                  memcpy(&rawImage[cinfo.output_scanline * ROW_SIZE], rawBuffer, ROW_SIZE);
            }
            
            //get image dimensions
            pMap->width = (cinfo.output_width - 8) / 8; //8 pixel border, 8 pixels per unit
            pMap->height = (cinfo.output_height - 8) / 8;
            char temp[50];
            MessageBox(NULL,itoa(pMap->height, temp, 10),"",MB_OK);
        	/* wrap up decompression, destroy objects, free pointers*/
        	jpeg_finish_decompress( &cinfo );
        	jpeg_destroy_decompress( &cinfo );
        	
        	delete [] rawImage;
        	delete [] rawBuffer;
        	delete [] jpgData;
        	return;
    }
    Last edited by A10; 01-14-2009 at 12:39 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Access Violation using memcmp?
    By someprogr in forum C Programming
    Replies: 3
    Last Post: 12-31-2007, 01:45 AM
  2. Access violation... can't figure it out...
    By Raigne in forum C++ Programming
    Replies: 7
    Last Post: 10-11-2007, 10:52 AM
  3. FtpFileFind access violation with MS VC++ 6.0
    By earth_angel in forum C++ Programming
    Replies: 3
    Last Post: 09-22-2005, 07:02 PM
  4. Strange access violation
    By jimmy_anttila in forum Windows Programming
    Replies: 2
    Last Post: 04-11-2004, 03:10 AM
  5. 0xC0000005: Access Violation
    By Strider in forum Windows Programming
    Replies: 3
    Last Post: 11-07-2001, 02:46 PM