Solved

CImage Load problem.

Posted on 2006-11-17
13
3,419 Views
Last Modified: 2013-11-20
Hello experts,

I have a program that allows people to load in picture files and then display them.  They can then save the document or file for my app and send it to someone else who opens and views the file for this reason i have chosen to implement CImage and the loading function is

HRESULT CImage::Load(IStream* pStream).

I have implemented it this way.
This works because the file is read into a buffer which we save.  This buffer is where the data is kept.


CFile file;
if( !file.Open( file_name, CFile::modeRead) )
      return FALSE;
m_buffer_size = (long)file.GetLength();
if ( alocate_buffer(m_buffer_size) == NULL )
      return FALSE;
if ( file.Read(m_buffer, m_buffer_size) != m_buffer_size )
      return FALSE;
file.Close();

CImage image;
image.Destroy();
if ( m_buffer == NULL )
        return;
CMemFile mem_file(m_buffer,m_buffer_size);
CArchiveStream stm (&ar);      
image.Load(&stm);
ar.Close();
mem_file.Detach ();
mem_file.Close();

The wierd part about this is it will work with some BMP's and not with others. sometimes it will crash and at other times it will simply not display.  For example.

for example the following bit map will work.

width: 350 pixels
height: 327 pixels
horizontal resolution: 95 dpi
vertical resolution: 95 dpi
bit depth: 24
frame count: 1

but this one will fail on the above call
"image.Load(&stm);"
producing the error message
"Unhandled exception at 0x006609f3 in myApp.exe: 0xC0000005: Access violation reading location 0x0000000c."

its properties are

width: 919 pixels
height: 690pixels
horizontal resolution: 96 dpi
vertical resolution: 96 dpi
bit depth: 32
frame count: 1

Please help!!!
0
Comment
Question by:wdhough
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
  • 3
  • +1
13 Comments
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 17965537
Possibly bad news for you.  Have a look at, specifically the final question
MSDN magazine, 2002, March, C++ Q & A, Paul DiLascia

CArchiveStream isn't an officially supported MFC class and may be buggy.
0
 

Author Comment

by:wdhough
ID: 17965942
Hi,

Thanks for your post i read the comment and yes your right it doesnt seem like good news does it!  Can u think of another way to achieve what i have mentioned above then?

Thanks.
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 17965991
There is an MFC sample <SimpleImage Sample: Loads, Resizes, Converts, and Saves Images > but I haven't looked at it.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 22

Expert Comment

by:mahesh1402
ID: 17970634
Using OleLoadPicture.

Rendering GIF, JPEG, Icon, or Bitmap Files with OleLoadPicture:http://www.codeproject.com/bitmap/render.asp

Displaying a JPG in your MFC Application :http://msdn.microsoft.com/msdnmag/issues/01/10/c/

-MAHESH
0
 
LVL 1

Accepted Solution

by:
Mazen earned 500 total points
ID: 17970842
Hello,

   I don't know much about CArchiveStream, but if the problem is in there, try using IStream instead. I have used it before with images alot and I didn't face a problem. Moreover, I use one huge IStream and load it wil alot of images (just to buffer) and then I copy each image alone to another Istream and load it, and the code works perfectly. Here's a sample code on how to use IStream :

CreateStreamOnHGlobal(NULL, TRUE, (LPSTREAM*)&pIstream);
ULARGE_INTEGER ulnSize;
ulnSize.QuadPart = m_buffer_size;
pIstream->SetSize(ulnSize);
LARGE_INTEGER lnOffset;
lnOffset.QuadPart = 0;      //starting location is 0
pIstream->Seek(lnOffset, STREAM_SEEK_SET, NULL);
ULONG mysize;
pIstream->Write(m_buffer,m_buffer_size,&mysize);
Y
ou can then compare mysize with m_buffer_size to check that all buffer has been copied correctly.
In the end you can load your image straight from the IStream

    Regards,

      Mazen
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 17970901
I've just tried loading/saving bitmaps with CImage using the file path.  Works fine here.

CImage img;
img.Load("C:\\x.bmp");
img.Save("C:\\y.bmp");   //now have a copy of x.bmp called y.bmp
0
 

Author Comment

by:wdhough
ID: 17978111
Hi Experts again.  

Actually I have just loaded in a picture that is
175 by 246 pixels
and 96dpi
bit depth 8
 and frame count 1.

The image just turns up black.  It doesnt crash which my original post was about, but does anyone know why I get black or rather how i can get the picture instead.  When i used the load function with the filename instead it worked!  Oh dear!

thanks
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 17978150
You can make a comment in community support with a link to this question asking for it to be reopened (or any other change you wish).
0
 
LVL 1

Expert Comment

by:Mazen
ID: 17978186
Can you post the new code you are using starting from the line where you buffer the image till you load it?

   Mazen
0
 

Author Comment

by:wdhough
ID: 17978221
Sure no worries.

CFile file;
if( !file.Open( file_name, CFile::modeRead) )
      return FALSE;

m_buffer_size = (long)file.GetLength();
if ( alocate_buffer(m_buffer_size) == NULL )
      return FALSE;

if ( file.Read(m_buffer, m_buffer_size) != m_buffer_size )
      return FALSE;
file.Close();
      

IStream *pIstream;
CreateStreamOnHGlobal(NULL, TRUE, (LPSTREAM*)&pIstream);
ULARGE_INTEGER ulnSize;
ulnSize.QuadPart = m_buffer_size;
pIstream->SetSize(ulnSize);
LARGE_INTEGER lnOffset;
lnOffset.QuadPart = 0;      //starting location is 0
pIstream->Seek(lnOffset, STREAM_SEEK_SET, NULL);
ULONG mysize;
pIstream->Write(m_buffer,m_buffer_size,&mysize);
      
image.Load(pIstream);

thats the code.  Try using it with a file thats 8 bits depth i think that may be the problem. if its turning up black its just not loading properly i would imagine

thanks for your help with this.
0
 

Author Comment

by:wdhough
ID: 17978271
Hi, just some more infor for the problem.  If you go to MSPaint and create a picture, something with some coloured shapes on is what i am using.  And save 3 versions of the file.  These are the results.

1. 24-bit Bitmap  - This works fine
2. 16 color Bitmap  - this turns up black
3. 256 color Bitmap - this turns up black

Thanks
0
 
LVL 1

Expert Comment

by:Mazen
ID: 17978640
Hi,
  I did a test on all types of BMPs (even monochrome) and I didn't face a problem.

- Is the image you are trying to load created with MSPaint or by your application, maybe something went wrong with the way you saved the image (incase it was created by your application)
 - Try checking if "mysize"  is equal to "m_buffer_size" to see if the whole file has been loaded into the IStream.

- How can I get the images you are perfroming your tests on? Can you email them to mazen@realtechdesign.com ?

Here's the code that I have tried:

CImage image;
HDC dc = GetWindowDC()->GetSafeHdc();
BYTE *m_buffer;
CFile file;
if( !file.Open( "c:/image1.bmp", CFile::modeRead) )
    return ;
long m_buffer_size = (long)file.GetLength();
m_buffer = new BYTE[m_buffer_size];
if ( file.Read(m_buffer, m_buffer_size) != m_buffer_size )
      return ;
file.Close();
IStream *pIstream;
CreateStreamOnHGlobal(NULL, TRUE, (LPSTREAM*)&pIstream);
ULARGE_INTEGER ulnSize;
ulnSize.QuadPart = m_buffer_size;
pIstream->SetSize(ulnSize);
LARGE_INTEGER lnOffset;
lnOffset.QuadPart = 0;      //starting location is 0
pIstream->Seek(lnOffset, STREAM_SEEK_SET, NULL);
ULONG mysize;
pIstream->Write(m_buffer,m_buffer_size,&mysize);
image.Load(pIstream);
image.Draw(dc,0,0);

     Mazen
0
 

Author Comment

by:wdhough
ID: 17979142
Hi,

Thanks after trying your code and getting it working, i realise the problem must be in my own code and found the problem.  Thank you very much for your help the original accepted answer is the correct one.

Thank you
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
In this post we will learn different types of Android Layout and some basics of an Android App.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
In this video, viewers are given an introduction to using the Windows 10 Snipping Tool, how to quickly locate it when it's needed and also how make it always available with a single click of a mouse button, by pinning it to the Desktop Task Bar. Int…

729 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question