Mega Search
23.2 Million


Sign Up

Make a donation  
TStreamAdapter, GDI+ and C++ Builder  
News Group: borland.public.cppbuilder.language.cpp

Hello,

because someone had these problems before in 2004 and asked a lot of 
questions about it in newsgroups, I think it's helpful that I post my 
solution here for all people out there with the same problem: I wanted to 
load a JPEG file with GDI+ in an application built with Codegear's C++ 
Builder 2007 and got strange invalid pointer exceptions. The following code 
does NOT work and leads to exceptions when called more than once:

    TMemoryStream * mem_p;
    TStreamAdapter * streamadapter;
    IStream * mystream;

    mem = new TMemoryStream();
    mem_p->LoadFromFile("test.jpg");
    mem_p->Seek(0,0);
    streamadapter_p = new TStreamAdapter(mem_p, soReference);

    try{
     mystream_p = *streamadapter_p;
     gdi_image_p = new Gdiplus::Image(mystream_p, FALSE);
    // Do something with our image object
     delete gdi_image_p;
    }//endtry
    catch(const Exception &e){
     output(e.Message);
    }//entry

//    delete streamadapter;    // Don't try this. streamadapter is already 
freed by deleting gdi_image_p
    delete mem_p;

The following fix DOES work for me:

    [...]

    try{
     mystream_p = *streamadapter_p;
     mystream_p->AddRef();    // Fix: Increase reference counter
     gdi_image_p = new Gdiplus::Image(mystream_p, FALSE);
    // Do something with our image object
     delete gdi_image_p;
     mystream_p->Release();    // Fix: Free object
    }//endtry
    catch(const Exception &e){
     output(e.Message);
    }//entry

    [...]

The reference counter seems to do the trick.
I did not need to use the TFixedStreamAdapter, which can often be found in 
Delphi newsgroups and contains fixed code for the stat function, but if 
someone is interested in its C++ code, here it is:

class TFixedStreamAdapter : public TStreamAdapter {
 public:
  __fastcall TFixedStreamAdapter(TStream * pMemStream, TStreamOwnership 
OwnerShip) : TStreamAdapter(pMemStream, OwnerShip){}

  virtual __stdcall HRESULT Stat(/* out */ TStatStg &statstg, int 
grfStatFlag){
   memset((void *)&statstg, 0, sizeof(TStatStg));
   statstg.type = STGTY_STREAM;
   statstg.cbSize.HighPart = Stream->Size >> 32;
   statstg.cbSize.LowPart = Stream->Size;
   statstg.mtime = DateTimeToFileTime(Now());
   statstg.ctime = DateTimeToFileTime(Now());
   statstg.atime = DateTimeToFileTime(Now());
   statstg.grfLocksSupported = LOCK_WRITE;
   return S_OK;
  }

 private:

  TFileTime __fastcall DateTimeToFileTime(TDateTime DateTime){
   TFileTime FileTime;
   TSystemTime SystemTime;
   DateTimeToSystemTime(DateTime, SystemTime);
   SystemTimeToFileTime(&SystemTime, &FileTime);
   return FileTime;
  }
};

I hope that I could help someone with the same problems.

Bye, Eike 



Vote for best question.
Score: 0  # Vote:  0
Date Posted: 9-Jan-2008, at 2:18 PM EST
From: Eike Belgardt
 
Re: TStreamAdapter, GDI+ and C++ Builder  
News Group: borland.public.cppbuilder.language.cpp
Hello Darko,

well, it was just an example. In reality I'm getting the stream via HTTP 
from a webcam. This makes a difference. GDI+ is faster in JPEG decompression 
than the TJPEGImage class provided by Codegear.

Bye, Eike

"Darko Miletic"  schrieb im Newsbeitrag 
news:4784eff7$1@newsgroups.borland.com...
> Eike Belgardt wrote:
>> Hello,
>>
>> because someone had these problems before in 2004 and asked a lot of 
>> questions about it in newsgroups, I think it's helpful that I post my 
>> solution here for all people out there with the same problem: I wanted to 
>> load a JPEG file with GDI+ in an application built with Codegear's C++ 
>> Builder 2007 and got strange invalid pointer exceptions. The following 
>> code does NOT work and leads to exceptions when called more than once:
>
> You are complicating something that is extremely simple.
>
> Image class from gdi+ can receive name of the file directly. You do not 
> need this mumbo jumbo.
>
> Here you have a simple example of loading jpeg file:
>
> http://msdn2.microsoft.com/en-us/library/ms533830(VS.85).aspx
> 



Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 9-Jan-2008, at 6:39 PM EST
From: Eike Belgardt
 
Re: TStreamAdapter, GDI+ and C++ Builder  
News Group: borland.public.cppbuilder.language.cpp
Eike Belgardt wrote:
> Hello,
> 
> because someone had these problems before in 2004 and asked a lot of 
> questions about it in newsgroups, I think it's helpful that I post my 
> solution here for all people out there with the same problem: I wanted to 
> load a JPEG file with GDI+ in an application built with Codegear's C++ 
> Builder 2007 and got strange invalid pointer exceptions. The following code 
> does NOT work and leads to exceptions when called more than once:

You are complicating something that is extremely simple.

Image class from gdi+ can receive name of the file directly. You do not 
need this mumbo jumbo.

Here you have a simple example of loading jpeg file:

http://msdn2.microsoft.com/en-us/library/ms533830(VS.85).aspx


Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 9-Jan-2008, at 2:02 PM EST
From: Darko Miletic