Author Topic: Has anyone done any work in GDI+ recently ?  (Read 8458 times)

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 5899
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: Has anyone done any work in GDI+ recently ?
« Reply #30 on: October 20, 2016, 12:39:34 AM »
Yes, that makes sense, thanks for the confirmation.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :biggrin:

mabdelouahab

  • Member
  • ***
  • Posts: 397
Re: Has anyone done any work in GDI+ recently ?
« Reply #31 on: October 20, 2016, 01:10:04 AM »
hutch--
Full Example: Crystal ball from resource without creating a temp file:crystal-ball.zip * It could not be included in the attachments because it is larger than 512

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 5899
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: Has anyone done any work in GDI+ recently ?
« Reply #32 on: October 20, 2016, 01:31:49 AM »
I downloaded it, its very well done.  :t
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :biggrin:

jj2007

  • Member
  • *****
  • Posts: 8840
  • Assembler is fun ;-)
    • MasmBasic
Re: Has anyone done any work in GDI+ recently ?
« Reply #33 on: October 20, 2016, 01:18:43 PM »
I took another road, work in progress (still severe memory leaks) but so far it looks OK, i.e. the exe runs on XP and Win7-64 alike. Grateful for tests with other OS versions :icon14:

It requires a hilarious workaround, though, to remain compatible with XP:
Quote
Prior to Windows Vista, SHCreateMemStream was not included in the public Shlwapi.h file, nor was it exported by name from Shlwapi.dll. To use it on earlier systems, you must call it directly from the Shlwapi.dll file as ordinal 12.

The original bmp file is 922270 bytes, the exe has 270kB.

GuruSR

  • Member
  • **
  • Posts: 116
  • Assembler (6500, 68k, Intel), C(all), VB6, no .Net
Re: Has anyone done any work in GDI+ recently ?
« Reply #34 on: October 20, 2016, 02:03:07 PM »
Just a thought, though have you looked on...  SourceForge for the FreeImage library?

GuruSR.
Learned 68k Motorola Asm instruction set in 30 minutes on the way to an Amiga Developer's Forum meeting.
Following week wrote a kernel level memory pool manager in 68k assembler for fun.

FORTRANS

  • Member
  • *****
  • Posts: 1033
Re: Has anyone done any work in GDI+ recently ?
« Reply #35 on: October 21, 2016, 12:02:15 AM »
Hi,

I took another road, work in progress (still severe memory leaks) but so far it looks OK, i.e. the exe runs on XP and Win7-64 alike. Grateful for tests with other OS versions

   Windows XP and 8.1.  There was an error message in the console
output on XP.  Output attached.  Didn't like my P-III as always. <g>

Regards,

Steve N.

HSE

  • Member
  • ****
  • Posts: 842
  • <AMD>< 7-32>
Re: Has anyone done any work in GDI+ recently ?
« Reply #36 on: October 21, 2016, 12:30:43 AM »
Hi JJ!! 7-32

Not skat.zip for recompilation.

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 5899
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: Has anyone done any work in GDI+ recently ?
« Reply #37 on: October 21, 2016, 01:24:04 AM »
I am actually happy enough with the technique of storing the PNG file as a resource, writing it as a file then loading the file with the GDI+ function. I have used the technique in the past and what makes it viable is the OS disk cache and the time lag between writing the file, reading it with the GDI+function then deleting the file is so short that it never reaches the disk, its a purely in memory operation that is easily fast enough.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :biggrin:

jj2007

  • Member
  • *****
  • Posts: 8840
  • Assembler is fun ;-)
    • MasmBasic
Re: Has anyone done any work in GDI+ recently ?
« Reply #38 on: October 21, 2016, 02:10:13 AM »
Just a thought, though have you looked on...  SourceForge for the FreeImage library?

A DLL with 5.5MB :dazzled:

I feel already ashamed for the 20k overhead of a MasmBasic hello world :redface:

@HSE+FORTRANS: Thanks for testing. I have to investigate into the SelectObject failure. Does the image show properly?

@Hutch: Correct but still, if you can avoid writing to a file, it would be even better. Zipping a BMP has about the same compression as converting to PNG, sometimes more, sometimes less. So unzipping to bmp in memory is a valid option imho. However, GdipCreateBitmapFromStream as used by mabdelouahab seems even better - compliments :t

@mabdelouahab: How (or rather: why) does this line work?
.invoke GdipCreateBitmapFromScan0,rect.right,rect.bottom,0,PixelFormat32bppPARGB,0,&bitmap

According to the docs, the 0 should be a pointer to the pixels ::)

FORTRANS

  • Member
  • *****
  • Posts: 1033
Re: Has anyone done any work in GDI+ recently ?
« Reply #39 on: October 21, 2016, 03:01:07 AM »
Hi,

@HSE+FORTRANS: Thanks for testing. I have to investigate into the SelectObject failure. Does the image show properly?

   I think so.  On the XP machine there was a lot of flickering when
the window was moved.  But it is a slower machine.

HTH,

Steve N.

HSE

  • Member
  • ****
  • Posts: 842
  • <AMD>< 7-32>
Re: Has anyone done any work in GDI+ recently ?
« Reply #40 on: October 21, 2016, 03:06:47 AM »
JJ : image look good. I can't see As column. It's no posible to increase window size beyond Kings.

jj2007

  • Member
  • *****
  • Posts: 8840
  • Assembler is fun ;-)
    • MasmBasic
Re: Has anyone done any work in GDI+ recently ?
« Reply #41 on: October 22, 2016, 11:15:53 AM »
Thanks. The images show, so it's working in principle. I've spent some time on a weird problem:
Code: [Select]
  if 1 ; ##### no leak but bmp doesn't work, and jpg fails often #####
push rv(SizeofResource, 0, esi)
push rv(LoadResource, 0, esi) ; src
mov hGlobal, rv(GlobalAlloc, GMEM_MOVEABLE, stack[4]) ; dest
invoke GlobalLock, eax
push eax
call MbCopy ; invoke MbCopy, dest, src, bytes
invoke GlobalUnlock, hGlobal
invoke CreateStreamOnHGlobal, hGlobal, 0, addr iStream
invoke GdipCreateBitmapFromStream, iStream, ebx ; addr hBitmap; GdipBitmapLockBits?
invoke GlobalFree, hGlobal
  else ; ##### bmp works, but leaks approx size of bitmaps #####
push rv(SizeofResource, 0, esi) ; invoke ShlWapi:SHCreateMemStream, pBuffer, bytes
push rv(LoadResource, 0, esi)
call GdiSI.jjMemStream ; get *IStream; use global GdiSI because ebx points to bitmap
invoke GdipCreateBitmapFromStream, eax, ebx ; addr hBitmap; GdipBitmapLockBits
  endif

The upper version works fine with png, and it doesn't leak, but it fails always with bmp and sometimes with jpg.
The lower version works great, but to prevent leaking, the stream needs to be released in the right moment (MS Social):
Quote
Unfortunately GDI+ does tend to hold files open for images for the duration of the image.  This is because GDI+ lazy decompresses the image (i.e. it doesn't actually decompress the image until the DrawImage call), which means it keeps your stream open.

There is a related post by Siekmanski that inspired me :t

Siekmanski

  • Member
  • *****
  • Posts: 1684
Re: Has anyone done any work in GDI+ recently ?
« Reply #42 on: October 22, 2016, 12:27:11 PM »
iStream pointer must be empty before use.
I use some kind of a SAFE_RELEASE,

Code: [Select]
.if iStream != 0
mov   ecx,iStream
push  ecx
mov   eax,[ecx]
call  DWORD PTR [eax + 8] ; IUnknown::Release
mov   iStream,0
.endif
.
Creative coders use backward thinking techniques as a strategy.

jj2007

  • Member
  • *****
  • Posts: 8840
  • Assembler is fun ;-)
    • MasmBasic
Re: Has anyone done any work in GDI+ recently ?
« Reply #43 on: October 22, 2016, 06:29:22 PM »
Yes, that did the trick. Just tested it on my XP VM, and noticed that in one occasion, SelectObject oldpen returns 0, which was flagged by my debugging routine. GetLastError reveals that there was no error, though (meaning XP has initially no pen selected). So I got curious and found this in Raymond Chen's What are the dire consequences of not selecting objects out of my DC?:
Quote
GDI will sometimes (not always) lie and say, "Sure, I deleted your object." It didn't actually delete it, because it's still selected into a DC, but it also ties a string around its finger, and when the object is finally deselected, GDI will say, "Oh, wait, I was supposed to delete this object," and perform the deletion.
::)

Vortex

  • Member
  • *****
  • Posts: 1864
Re: Has anyone done any work in GDI+ recently ?
« Reply #44 on: June 07, 2018, 04:40:42 AM »
Here is my GdipCreateBitmapFromStream example. It displays a PNG image loaded from file into memory :

Code: [Select]
    .IF uMsg==WM_CREATE

        invoke  GlobalAlloc,GMEM_MOVEABLE,PNG_IMG_SIZE
        mov     hMem,eax

        invoke  GlobalLock,eax
        mov     pMem,eax

        invoke  ReadFileToMem,ADDR filename,eax

        mov     eax,OFFSET StartupInfo
        mov     GdiplusStartupInput.GdiplusVersion[eax],1
        mov     GdiplusStatus,eax

        invoke  GdiplusStartup,ADDR token,ADDR StartupInfo,0
        invoke  CreateStreamOnHGlobal,hMem,FALSE,ADDR pStream
        invoke  GdipCreateBitmapFromStream,pStream,ADDR BmpImage

        invoke  GdipCreateHBITMAPFromBitmap,BmpImage,ADDR hBitmap,0