Finally, here is the image library with the latest bug fix of lamer.

Many thanks to f0dder ,  El_Choni and lamer for the corrections.

Concering the functions BitmapFromFile and BitmapFromMemory, the statements :

invoke CoInitialize, NULL at the beginning of the source code

invoke CoUninitialize at the end of the source code

should be included to initialize and uninitiaize COM

EDIT : Look at my third post to download the attachment.
Posted on 2005-10-15 05:11:35 by Vortex
Based on dougiem's code, here is a GetOleImageFromMem function.

Posted on 2005-10-15 05:17:19 by Vortex
Hi Vortex

There is still bug in BitmapFromPicture.
The screen DC is not released. If you load and show enough pictures you will run out of DC's


;  BitmapFromPicture.ASM
;  Image file loading routines for the MASM32 library
;  This source and assosciated binary code is
;  Copyright © 2001 by M Stoller Enterprises
;  Written by Ernest Murphy
;  Not for commercial reproduction. No fee whatsoever may be imposed for
;  transfering this file. Source files may be coppied only for educational use
;  on a free basis.
;  Binary object files may be included in any work be it private, public or
;  a commercial application without payment necessary, however, it would be
;  appreciated to add a note to the effect "certain routines used in this program
;  were produced by Ernest Murphy" in the program documentation. Burried deep in
;  the help file is just fine.
;  There is no 'LZW' code contained in these routines.

.model flat,stdcall
option casemap:none

include \masm32\include\
include \masm32\include\
include \masm32\include\
include \masm32\include\
include \masm32\include\
include \masm32\include\
include \masm32\include\
include \masm32\include\


    ; IUnknown methods
    QueryInterface          DWORD  ?
    AddRef                  DWORD  ?
    Release                DWORD  ?
    ; IPicture methods
    get_Handle              DWORD  ?
    get_hPal                DWORD  ?
    get_Type                DWORD  ?
    get_Width              DWORD  ?
    get_Height              DWORD  ?
    Render                  DWORD  ?
    set_hPal                DWORD  ?
    get_CurDC              DWORD  ?
    SelectPicture          DWORD  ?
    get_KeepOriginalFormat  DWORD  ?
    put_KeepOriginalFormat  DWORD  ?
    PictureChanged          DWORD  ?
    SaveAsFile              DWORD  ?
    get_Attributes          DWORD  ?
IPicture ENDS

HIMETRIC_INCH      EQU    2540

BitmapFromPicture PROC pPicture:DWORD
    LOCAL tempDC:DWORD,  tempBitmap:DWORD,  OldBitmap:DWORD
    LOCAL dwWidth:DWORD, dwHeight:DWORD,    compDC:DWORD
    LOCAL hmWidth:DWORD, hmHeight:DWORD,    neghmHeight:DWORD

    ; check we have an object
    .IF pPicture == 0
        ; whoops, no object passed in
        invoke SetLastError, ERROR_INVALID_PARAMETER
        mov eax, 0
    ; get a DC to work with
    invoke GetDC, NULL          ; screen DC
    mov compDC, eax
    invoke CreateCompatibleDC, compDC
    .IF !eax
        ; whoops, didn't get a DC
        ; but at least we had SetLastError called for us
        invoke ReleaseDC,NULL,compDC
    mov tempDC, eax

    ; read out the width and height of the IPicture object
    ; (IPicture)pPicture::get_Width(*hmWidth)
    lea eax, hmWidth
    push eax
    mov eax, pPicture
    push eax
    mov eax,
    call .IPicture.get_Width

    ; (IPicture)pPicture::get_Height(*hmHeight)
    lea eax, hmHeight
    push eax
    mov eax, pPicture
    push eax
    mov eax,
    call .IPicture.get_Height

    ; convert himetric to pixels
    invoke GetDeviceCaps, compDC, LOGPIXELSX
    invoke MulDiv, hmWidth, eax, HIMETRIC_INCH
    mov dwWidth, eax

    invoke GetDeviceCaps, compDC, LOGPIXELSY
    invoke MulDiv, hmHeight, eax, HIMETRIC_INCH
    mov dwHeight, eax
    xor eax, eax
    sub eax, hmHeight
    mov neghmHeight, eax

    invoke CreateCompatibleBitmap, compDC, dwWidth, dwHeight
    .IF !eax
        ; whoops, didn't get a bitmap
        ; but at least we had SetLastError called for us\
        ; clean up the DC
        invoke ReleaseDC,NULL,compDC
        invoke DeleteDC, tempDC
    mov tempBitmap, eax

    invoke SelectObject, tempDC, tempBitmap
    .IF !eax
        ; whoops, didn't select our bitmap
        ; but at least we had SetLastError called for us
        invoke ReleaseDC,NULL,compDC
        invoke DeleteDC, tempDC
        invoke DeleteObject, tempBitmap
    mov OldBitmap, eax

    ; ok, now we have our bitmap mounted onto our temporary DC, let's blit to it
    ; (IPicture)pPicture::Render(hdc, x, y, cx, cy,                            \
    ;                            xpos_himetric, ypos_himetric,                \
    ;                            xsize_himetric, ysize_himetric, *rectBounds)
    push NULL  ; *rectBounds
    push neghmHeight
    push hmWidth
    push hmHeight
    push 0
    push dwHeight
    push dwWidth
    push 0
    push 0
    push tempDC
    mov eax, pPicture
    push eax
    mov eax,
    call .IPicture.Render
    test eax, eax
    .IF SIGN?
        ; the call failed!
        push eax
        ; do some clean up first
        invoke ReleaseDC,NULL,compDC
        invoke DeleteDC, tempDC
        invoke DeleteObject, tempBitmap
        pop eax
        ; need to parse out the return fail value
        .IF eax == E_FAIL
        .ELSEIF eax == E_INVALIDARG
        .ELSEIF eax == E_OUTOFMEMORY
        .ELSEIF eax == E_POINTER
        invoke SetLastError, eax
        mov eax, 0

    ; we now have the bitmap blitted, let's get it off the dc and clean up.
    ; we're not going to check for errors, cause we did our importaint thing
    ; and if these fail now, other things will fall apart anyway
    invoke ReleaseDC,NULL,compDC
    invoke SelectObject, tempDC, OldBitmap
    invoke DeleteDC, tempDC
    mov eax, tempBitmap    ; the bitmap handle is the return value
    ret                    ; we're all done

BitmapFromPicture ENDP               


Posted on 2005-10-17 07:33:40 by KetilO
Hi KetilO,

Many thanks for the bug fix. I added the line below to the source code :
invoke ReleaseDC,NULL,compDC

Here is the new attachment.
Posted on 2005-10-17 12:00:56 by Vortex
Hi friends,

Here is the revised package according to the suggestions of QvasiModo.
Posted on 2005-10-30 13:42:50 by Vortex
Here is the latest release with an example of using BitmapFromResource
Posted on 2005-11-03 12:37:44 by Vortex
Excellent work Vortex. Thanks for taking the time to correct all of this.
Posted on 2005-11-03 15:21:34 by JimmyClif
Hi JimmyClif,

Thanks for your kind words. Also, thanks to the members of the board for their suggestions and bug fixes.
Posted on 2005-11-04 06:51:56 by Vortex
Hi everybody.

I'm quite new to the board but I'm very impressed how often your posts on several topics could help me out.
Well I managed to get Ernst Murphy's image library compiled well and used the "BitmapFromFile" - function without a problem.

My Question:  Can I use the "image.lib" within "C"-projects? (I use Visual C++ 6.0) If I can, please spend a moment to write a little code snippet for the headers(?!) and includes(?!). I think the rest would be: "hBitmap = BitmapFromFile( myBitmapFilePath );" Am I right?

(I hope that it's not a problem to append my post here.)

Greetings, Stephan.

Posted on 2005-11-14 21:21:26 by graphen_shua
Hi graphen_shua,

Welcome to the forum.

Here is an example coded with Pelle's C, notice that it uses an old version of the library, not the latest release :

Posted on 2005-11-15 00:47:46 by Vortex
This is a C/C++ header for the imagelib. Haven't tested it but I think it should work. I was unsure on how to define the IPicture interface pointer, maybe someone with more knowledge on C can tell if it's done right...

Couldn't compare it with Vortex's example because I have to register in the forum to see the attachments, and I didn't want to create a user I wouldn't use later.
Posted on 2005-11-15 10:07:21 by QvasiModo

Hello Vortex and QvasiModo,  :D

Wahoo! Thanx for replying so fast. I found the OLE - imageload version on the russian site AND
I wrote a little C testprog to see if it works with the imagelib.h.

First I copied the "imagelib.h" into the VC++ include folder, included it into the code and made the entry "image.lib"
under the LINK section of the project settings. I copied the "image.lib" into the lib folder of VC++.
After first try, I uncommented the BitmapFromPicture within the imagelib.h because it throws an error, but I don't need it.
But then unfortunately VC++ hits the error:

window_tests.obj : error LNK2001:
unresolved external symbol  "struct HBITMAP__ * __cdecl BitmapFromFile(char *)" (?BitmapFromFile@@YAPAUHBITMAP__@@PAD@Z)

I know this is not a C Language - Forum but the following code shows my imagelib test program
and maybe you can tell me why the symbol is unresolved.

// testing imagelib
#define STRICT
#include <windows.h>
#include "imagelib.h" // inside: BitmapFromPicture due to error uncommented, I don't need it
#include ...


// globals
const char szAppName[] = "My Window";
char szBitmap[] = "load.bmp";  // is in same directory as executable
HBITMAP hbitmap;

// entry
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hprevInstance, PTSTR szCmdLine,int iShowCmd)
return msg.wParam;

// message handling, react on user input

switch (message)
hbitmap = BitmapFromFile(szBitmap);

if(hbitmap == NULL)
                            MessageBox(NULL, "Could not load Bitmap!", "Error", MB_OK | MB_ICONEXCLAMATION);
return 0;
return DefWindowProc(hWnd, message, wParam, lParam);

Greetings, Stephan.
Posted on 2005-11-15 12:29:16 by graphen_shua
My guess is the header file was written for C programs but not C++ - can you post it here (as attachment), then I'll fix it up.

Posted on 2005-11-15 12:35:13 by f0dder
Hi fOdder,

ok I'll post the Imagelib.h from QvasiModo here, unchanged.

EDIT: sorry forgot the attachment  :roll:
Posted on 2005-11-15 12:42:22 by graphen_shua
Try this :)
Posted on 2005-11-15 12:57:11 by f0dder
Still won't work, the problem is by default the compiler assumes the C calling convention, and it should use the stdcall calling convention. Hopefully there will be no issues with the name mangling too.

I don't remember very well, but I think you have to append __stdcall before each line...
Posted on 2005-11-15 15:44:08 by QvasiModo

I don't remember very well, but I think you have to append __stdcall before each line...

%100 right. This is what I have done in my Jpgfromfile demo posted to Pelle's forum:

extern HBITMAP __stdcall BitmapFromFile(char *pszFileName);
Posted on 2005-11-16 00:36:05 by Vortex
ah, __stdcall as well - doh. Should've kept in mind that's the default most people use for their assembly.
Posted on 2005-11-16 00:39:50 by f0dder
Hi all!

My machine was down, so  couldn't answer immedeately.
I just tried the changes and violá everything works fine!
I don't have much time, but I consider appending the header file and
an example VC++ project for the people.

So at the moment THANK YOU all! You made me happy and I learned a lot.  :D
Greetings, Stephan.

This is what I have done in my Jpgfromfile demo posted to Pelle's forum:

@Vortex: Sorry didn't see the attachment, I wasn't registered.

Well, here's the file. I only put the fresh compiled "image.lib" into the lib folder of VC++ and the rest is self-explanatory. The code is commented of course.
Posted on 2005-11-16 12:44:29 by graphen_shua