NO

Author Topic: Using GDI+  (Read 1944 times)

Offline HellOfMice

  • Member
  • *
  • Posts: 107
  • Never be pleased, always improve
Using GDI+
« on: November 03, 2024, 06:32:21 PM »
Hello the World

I load ab image using the flat api of GDI+ with GdipLoadImageFromFileICM(_wFileName,&_Image) or with GdipCreateHBITMAPFromBitmap(GdiPlusBitmap,&_hBitmap,0) ; and I would like to get a BITMAPINFOHEADER or a BITMAPV5HEADER from the GpImage or the GpBitmap.

With the HBITMAP given by GdipCreateHBITMAPFromBitmap if I call GetObject this function returns 0.
My solution is to call GdipLoadImageFromFileICM(_wFileName,&_Image) and retrieve the with and the height with GdipGetImageWidth and GdipGetImageHeight the frees the image and call GDIPlus_GetHBitmapFromFile to get the hbitmap. After I can initialize a BITMAPINFO structure and call GetDIBits.

Is there a better way to do that? If I can get a BITMAPINFOHEADER structure it is good I know how to do after. I don't want to load the file twice.

Please could you help me.

Thank You

Philippe RIO
« Last Edit: November 03, 2024, 06:37:07 PM by HellOfMice »
--------------------------------
Kenavo

Offline Vortex

  • Member
  • *
  • Posts: 865
    • http://www.vortex.masmcode.com
Re: Using GDI+
« Reply #1 on: November 03, 2024, 08:33:27 PM »
Hi HellOfMice,

Here is an example for you :

Code: [Select]
    .if uMsg == WM_CREATE

        mov     rax,OFFSET StartupInfo
        mov     GdiplusStartupInput.GdiplusVersion[rax],1

        invoke  GdiplusStartup,ADDR token,ADDR StartupInfo,0
        invoke  UnicodeStr,ADDR filename,ADDR UnicodeFileName

        invoke  GdipCreateBitmapFromFile,ADDR UnicodeFileName,\
                ADDR BmpImage

        invoke  GdipGetImageWidth,BmpImage,ADDR ImgWidth+rip
        invoke  GdipGetImageHeight,BmpImage,ADDR ImgHeight+rip

        invoke  GdipCreateHBITMAPFromBitmap,BmpImage,\
                ADDR hBitmap+rip,0

        invoke  GdipDisposeImage,BmpImage
« Last Edit: November 04, 2024, 08:23:12 PM by Vortex »
Code it... That's all...

Offline HellOfMice

  • Member
  • *
  • Posts: 107
  • Never be pleased, always improve
Re: Using GDI+
« Reply #2 on: November 03, 2024, 08:36:42 PM »
I am interfacing this example for making a standalone function
The GdiplusShutdown call is missing
« Last Edit: November 03, 2024, 09:02:21 PM by HellOfMice »
--------------------------------
Kenavo

Offline Vortex

  • Member
  • *
  • Posts: 865
    • http://www.vortex.masmcode.com
Re: Using GDI+
« Reply #3 on: November 03, 2024, 09:39:52 PM »
Hi HellOfMice,

Thanks, new upload at the top :

Code: [Select]
       invoke  GdipCreateHBITMAPFromBitmap,BmpImage,\
                ADDR hBitmap+rip,0

        invoke  GdipDisposeImage,BmpImage
       
        invoke  GdiplusShutdown,token
Code it... That's all...

Offline HellOfMice

  • Member
  • *
  • Posts: 107
  • Never be pleased, always improve
Re: Using GDI+
« Reply #4 on: November 04, 2024, 05:25:00 AM »
Hello Vortex

I have a problem calling GdiplusStartup, it crashes.
I copied from your source code which works well and mine crashes!

Could you help me please

Philippe RIO

Code: [Select]
includelib   "\Program Files\PellesC\Lib\Win64\GdiPlus.lib"

BITMAP STRUCT
  bmType        DWORD       ?
  bmWidth       DWORD       ?
  bmHeight      DWORD       ?
  bmWidthBytes  DWORD       ?
  bmPlanes      WORD        ?
  bmBitsPixel   WORD        ?
  padding       DWORD       ?
  bmBits        QWORD       ?
BITMAP ENDS

GdiplusStartupInput STRUCT
    GdiplusVersion              DWORD ?
    DebugEventCallback          DWORD ?                ;;   Should be QWORD I think
    SuppressBackgroundThread    DWORD ?
    SuppressExternalCodecs      DWORD ?
GdiplusStartupInput ENDS

GdipCreateBitmapFromFile   PROTO :QWORD,:QWORD
GdipCreateHBITMAPFromBitmap   PROTO :QWORD,:QWORD,:QWORD
GdipDisposeImage         PROTO :QWORD
GdiplusStartup            PROTO :QWORD,:QWORD,:QWORD
GdiplusShutdown            PROTO :QWORD

                     .Data?
StartupInfo               GdiplusStartupInput      <?>
GDIPlusToken            QWORD               ?         

                     .Code

                     ALIGN   16

UnicodeStr               PROC   Source:QWORD,Dest:QWORD PARMAREA=4*QWORD

                     xor      r8d,r8d
                     mov      r9d,1
                     xor      eax,eax
                     sub      rax,r9
@@:
                     add      rax,r9
                     mov      r8b,BYTE PTR [rcx + rax]
                     mov      WORD PTR [rdx + rax * 2],r8w

                     test   r8,r8
                     jnz      @b

                     ret
UnicodeStr               ENDP

GDIPlus_Init            PROC
                     mov      rax,OFFSET StartupInfo
                     mov      GdiplusStartupInput.GdiplusVersion[rax],1
                     mov      rcx,OFFSET GDIPlusToken
                     mov      rdx,OFFSET StartupInfo
                     xor      r8d,r8d
                     call   GdiplusStartup
;                     INVOKE   GdiplusStartup,ADDR GDIPlusToken,ADDR StartupInfo,0
                     ret
GDIPlus_Init            ENDP

GDIPlus_Exit            PROC
                     INVOKE   GdiplusShutdown,GDIPlusToken + rip
                     ret
GDIPlus_Exit            ENDP

GDIPlus_LoadFile         PROC   __hWnd:QWORD,__lpszFileName:QWORD PARMAREA=4*QWORD
                     LOCAL   _hBitmap:QWORD
                     LOCAL   _UniCodeFileName[64]:BYTE
                     LOCAL   _BmpImage:QWORD

                     INVOKE   UnicodeStr,__lpszFileName,ADDR _UniCodeFileName

                     INVOKE   GdipCreateBitmapFromFile,ADDR _UniCodeFileName,ADDR _BmpImage
                     INVOKE   GdipCreateHBITMAPFromBitmap,_BmpImage,ADDR _hBitmap,0

                     mov      rax,_hBitmap
                     ret
GDIPlus_LoadFile         ENDP

;   **********************************************************************************
;   *********************** F I N I S H E D **********************************************
;   **********************************************************************************

                     END
« Last Edit: November 04, 2024, 09:07:27 AM by HellOfMice »
--------------------------------
Kenavo

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2115
Re: Using GDI+
« Reply #5 on: November 04, 2024, 09:42:40 AM »
CALLBACK is QWORD size pointer in 64-bit code
Code: [Select]
typedef struct
{
    UINT32 GdiplusVersion ;
    void* DebugEventCallback ;
    BOOL SuppressBackgroundThread ;
    BOOL SuppressExternalCodecs ;
} GDIPLUSSTARTUPINPUT ;

EDIT:
Code: [Select]
GDIPLUSSTARTUPINPUT 16 10h bytes
GdiplusVersion   +0h 4h
DebugEventCallback +4h 4h
SuppressBackgroundThread +8h 4h
SuppressExternalCodecs +Ch 4h
Code: [Select]
GDIPLUSSTARTUPINPUT 24 18h bytes
GdiplusVersion   +0h 4h
DebugEventCallback +8h 8h
SuppressBackgroundThread +10h 4h
SuppressExternalCodecs +14h 4h
Code: [Select]
#define WIN32_LEAN_AND_MEAN
//#include <windows.h>
#include <richedit.h>
#include <stddef.h>
#include <stdio.h>
// http://www.catb.org/esr/structure-packing/
// http://stackoverflow.com/questions/1208954/c-struct-grabbing-data-by-offset
#ifndef offsetof
#define offsetof(ty,m)  ((size_t)&(((ty*)0)->m))
#endif
#define GET_FIELD_OFFSET(type, field)    ((size_t)&(((type *)0)->field))
#define GET_FIELD_SIZE(type, field)      (sizeof(((type *)0)->field))

#define PRINTSIZE(x)  printf("\n%-16s %d %Xh bytes\n",#x,sizeof(x),sizeof(x));
#define PRINTOFSSIZE(type,field) printf("%-16s +%Xh %Xh\n",#field,(LONG)&(((type *)0)->field),sizeof(((type *)0)->field));

typedef struct
{
    UINT32 GdiplusVersion ;
    void* DebugEventCallback ;
    BOOL SuppressBackgroundThread ;
    BOOL SuppressExternalCodecs ;
} GDIPLUSSTARTUPINPUT ;

int main(void)
{
PRINTSIZE(GDIPLUSSTARTUPINPUT);
PRINTOFSSIZE(GDIPLUSSTARTUPINPUT,GdiplusVersion);
PRINTOFSSIZE(GDIPLUSSTARTUPINPUT,DebugEventCallback);
PRINTOFSSIZE(GDIPLUSSTARTUPINPUT,SuppressBackgroundThread);
PRINTOFSSIZE(GDIPLUSSTARTUPINPUT,SuppressExternalCodecs);
return 0;
}
« Last Edit: November 05, 2024, 12:02:04 PM by TimoVJL »
May the source be with you

Offline Vortex

  • Member
  • *
  • Posts: 865
    • http://www.vortex.masmcode.com
Re: Using GDI+
« Reply #6 on: November 04, 2024, 08:22:47 PM »
Hi Philippe,

Please accept my apologies, Timo is right and I corrected the definition of the structure :

Code: [Select]
GdiplusStartupInput STRUCT
    GdiplusVersion              DWORD ?
                                DWORD ? ; padding DWORD
    DebugEventCallback          QWORD ?
    SuppressBackgroundThread    DWORD ?
    SuppressExternalCodecs      DWORD ?
GdiplusStartupInput ENDS

New zip file uploaded at the top.
Code it... That's all...

Offline HellOfMice

  • Member
  • *
  • Posts: 107
  • Never be pleased, always improve
Re: Using GDI+
« Reply #7 on: November 04, 2024, 08:28:45 PM »
I had thought to the QWORD but not at the padding bytes.
No problem Vortex you already are so nice to give one of your source.
I appreeciate
I will give you some news in the following days.


Thank You very much


Philippe
--------------------------------
Kenavo