C Board  

Go Back   C Board > Platform Specific Boards > Windows Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 01-08-2009, 06:12 PM   #1
A10
Registered User
 
Join Date: Nov 2006
Posts: 83
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?
A10 is offline   Reply With Quote
Old 01-08-2009, 06:18 PM   #2
Kernel hacker
 
Join Date: Jul 2007
Location: Farncombe, Surrey, England
Posts: 15,686
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.
matsp is offline   Reply With Quote
Old 01-08-2009, 10:00 PM   #3
A10
Registered User
 
Join Date: Nov 2006
Posts: 83
Well that squashed all my hope

Do you know of any way to convert a jpg loaded as a BYTE* [] into a hbitmap?
A10 is offline   Reply With Quote
Old 01-08-2009, 11:35 PM   #4
A10
Registered User
 
Join Date: Nov 2006
Posts: 83
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 :(
}
A10 is offline   Reply With Quote
Old 01-09-2009, 03:12 AM   #5
train spotter
 
Join Date: Aug 2001
Location: near a computer
Posts: 3,359
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
novacain is offline   Reply With Quote
Old 01-09-2009, 03:41 AM   #6
Kernel hacker
 
Join Date: Jul 2007
Location: Farncombe, Surrey, England
Posts: 15,686
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.
matsp is offline   Reply With Quote
Old 01-09-2009, 04:36 PM   #7
Hat seller extraordinaire
 
Join Date: Apr 2008
Posts: 159
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;
}
adeyblue is offline   Reply With Quote
Old 01-09-2009, 08:26 PM   #8
Registered User
 
Join Date: Mar 2005
Location: Mountaintop, Pa
Posts: 1,054
Quote:
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.
BobS0327 is offline   Reply With Quote
Old 01-13-2009, 12:04 AM   #9
A10
Registered User
 
Join Date: Nov 2006
Posts: 83
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.

Quote:
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?

Quote:
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!
A10 is offline   Reply With Quote
Old 01-13-2009, 03:04 PM   #10
Registered User
 
Join Date: Mar 2005
Location: Mountaintop, Pa
Posts: 1,054
Quote:
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) ; 
}
BobS0327 is offline   Reply With Quote
Old 01-13-2009, 10:56 PM   #11
A10
Registered User
 
Join Date: Nov 2006
Posts: 83
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.
A10 is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

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


All times are GMT -6. The time now is 01:40 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22