Skip to content
View in the app

A better way to browse. Learn more.

Tuts 4 You

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

How to convert webp to bitmap in memory?

Featured Replies

Hi guy's,

I did notice that I can't use the BitmapFromMemory function when having a webp image in memory. Does anyone know whether there is an update function which can also deal with that format? Otherwise, how can I convert the image webp data in memory into an bitmap or other format the BitmapFromMemory can work with? I'm using the BitmapControl lib from fearless.

PS: MASM

greetz

Hi LCF_AT

The issue is that BitmapFromMemory relies on GDI+, which doesn't natively support WebP. To fix this in MASM:Use libwebp.dll: It's the simplest way. Call WebPDecodeBGRA to get raw pixels from your memory buffer.Convert to HBITMAP: Once you have the raw BGRA pixels, use CreateBitmap or CreateDIBSection to make it compatible with Fearless's lib.WIC: Alternatively, use Windows Imaging Component (COM), but it's a headache in ASM.Quick logic: WebP Data -> WebPDecodeBGRA -> Raw Pixels -> CreateDIBSection -> Success!If you need the .inc prototypes for libwebp, let me know.

Price

h_h

  • Author

Hello @Price,

thanks for the info. I found that dll libwebp.dll & libsharpyuv.dll I need to have both to get it loaded. The question is how to decode the image bytes in memory? Are there some API parameters descriptions somewhere and a code which API I have to use minimal? I tried to debug the Fast Stone Capture tool which also has those dlls and if I drag an webp image into it it will not call that WebPDecodeBGRA function so it calls the WebPDecodeBGRInto function which holds the memory start address of the image bytes & size of it.

My way using BitmapControl functions is..

BitmapControlCreate
BitmapControlGetBitmap
BitmapFromMemory
BitmapControlSetBitmap

...to put images into and static control etc. Did work fine so far with jpg files etc. So is it possible to place the function you said before BitmapFromMemory to decode the image bytes / size and then call the BitmapFromMemory function with the new decode bytes? I think so. But I also need to know the API parameters I have to call with that decode function. On internet I didn't found it yet.Okay wait, I think here is something...

uint8_t* WebPDecodeRGBA(
    const uint8_t* data,
    size_t data_size,
    int* width,
    int* height
);
https://deepwiki.com/webmproject/libwebp/3.2-decoding-api

..do you have some clue or example for it? Oh yes, if you have the inc / lib files for it then upload them too next time. Thanks. )

greetz

Hi!

Yes, you've got the right API. In MASM, you should use WebPDecodeBGRA instead of WebPDecodeRGBA because Windows GDI/GDI+ uses the BGRA (Blue-Green-Red-Alpha) byte order.Here is the minimal setup for your code:

The Prototype (Include this in your .inc):

externdef WebPDecodeBGRA : proto :ptr byte, :size_t, :ptr dword, :ptr dword
externdef WebPFree : proto :ptr byte

The Logic: You cannot call BitmapFromMemory after decoding, because BitmapFromMemory expects a compressed file format (JPG/PNG). Since WebPDecodeBGRA returns raw pixels, you need to create the Bitmap object directly from those pixels.

Example Flow:

.data
    imgW    dd 0
    imgH    dd 0
    pPixels dd 0

.code
; 1. Get raw pixels from WebP memory buffer
invoke WebPDecodeBGRA, pMemoryBuffer, BufferSize, addr imgW, addr imgH
mov pPixels, eax
.if eax != 0
    ; 2. Create the GDI+ Bitmap from raw pixels (32bpp BGRA)
    ; Since you use Fearless's lib, check if he has a "BitmapFromRaw" 
    ; or use GdipCreateBitmapFromScan0 directly:
    mov edx, imgW
    imul edx, 4 ; Stride = Width * 4
    invoke GdipCreateBitmapFromScan0, imgW, imgH, edx, PixelFormat32bppARGB, pPixels, addr hBitmap
    
    ; 3. Use your BitmapControl functions with the new hBitmap
    invoke BitmapControlSetBitmap, hControl, hBitmap

    ; 4. Cleanup the buffer allocated by the DLL
    invoke WebPFree, pPixels
.endif

Note on DLLs: You only need libsharpyuv.dll if you are encoding. For decoding only, libwebp.dll is usually enough if it was compiled with static dependencies.I'll try to pack the .inc and .lib for you in my next post if you still need the pre-made files!

Price

h_h

  • Author

Ok thanks, so I tried this but does not work yet. I don't get any hBitmap value back just 0 at this address. I have this code...

Invoke BitmapControlCreate, IMAGESTATIC_HANDLE, 00, 00, 450, 253, IDC_IMAGESTATIC
mov hBMC, eax
invoke BitmapControlGetBitmap, hBMC

push  offset imgH
push  offset imgW
push filesize_image
push section_bak
call [_WebPDecodeBGRA]
mov pPixels, eax
mov edx, imgW
imul edx, 4  ; <--- for whats that good for?
invoke GdipCreateBitmapFromScan0, imgW, imgH, edx, PixelFormat32bppARGB, pPixels, addr hBitmap
mov eax, hBitmap ; <--- 0

Invoke BitmapControlSetBitmap, hBMC, eax, TRUE

...pretty harsh code now but just for testing. Any clue? I'm pretty rusty and can't remember anymore so much even forget some basic API's already. ) There is no BitmapFromRaw function.

greetz

The reason hBitmap is returning 0 is because GdipCreateBitmapFromScan0 doesn't return a Windows handle—it returns a GdiPlus Object Pointer. To make it work with a standard control, you need a "bridge" to convert that object into a real HBITMAP.

Here is the corrected flow for your code:

The "Stride" (edx)

The imul edx, 4 is mandatory. It tells GDI+ that each row of pixels is Width * 4 bytes long (32-bit BGRA). If this value is 0 or incorrect, the function will fail with error 2 in EAX.

The conversion Bridge,

You need to call GdipCreateHBITMAPFromBitmap to get a handle that BitmapControlSetBitmap can actually understand.

; 1. Create the GDI+ Object from raw WebP pixels
invoke GdipCreateBitmapFromScan0, imgW, imgH, edx, PixelFormat32bppARGB, pPixels, addr pGdiObj

.if eax == 0 ; Check if GDI+ returned 'Ok'
    ; 2. Convert GDI+ Object -> Standard Windows HBITMAP
    invoke GdipCreateHBITMAPFromBitmap, pGdiObj, addr hBitmap, 0
    
    ; 3. Use the hBitmap (now it won't be 0!)
    invoke BitmapControlSetBitmap, hBMC, hBitmap, TRUE
    
    ; 4. Clean up the GDI+ object (the hBitmap stays valid)
    invoke GdipDisposeImage, pGdiObj
.else
    ; If EAX is 1: GDI+ is not initialized
    ; If EAX is 2: Invalid Parameter (check imgW/imgH/Stride)
.endif

; 5. Don't forget to free the WebP DLL buffer
push pPixels
call [_WebPFree]

Make sure your lib calls GdiplusStartup before this.Double check that PixelFormat32bppARGB is defined as 0026200Ah.Always check EAX right after the call to see the specific error code.

Price

h_h

Edited by Price
update post

Its been ages since I wrote that bitmap control. Couldnt even remember it, had to go look up the source.

Compiled libwebp.lib with standard call. Created the include file, and some definition files for WinASM and RadASM.

Example RadASM project included. Loads a webp image that is stored as a resource.

The bitmap control thing made the image a bit funny with the StretchBlt so i took out all that stuff and just sent the hBitmap to a SS_BITMAP static control instead using STM_SETIMAGE message.

Probably best to use a static SS_BITMAP control or see if there is some other bitmap control as that one is old and probably could do with rewrite or fixing.

Edit: Actually I realized that I had created a static control and also used the bitmap create control and thus is was clipped behind the static control, so I thought it wasn't working properly, and was only showing a small part of it, when the static control was covering the other control. So should be fine to use that control library if you wanted.

libWebPTest.zip

Edited by fearless

  • Author

Hey guys,

thank you very much for the new input and also the lib inc files with a text example @fearless. ) So I tested it first manually as you said @Price and it did work correctly now to get the image data displayed on static control. Even I really forgot to add the startup GDI function. So the test did work now so far.

Now I tried to test your lib file / functions fearless but I get some error about the module type..

/SUBSYSTEM:WINDOWS /DEBUG /DEBUGTYPE:CV /VERSION:4.0 /INCREMENTAL:NO /DYNAMICBASE:NO ...
LIBCMT.lib(_chkstk_.obj) : fatal error LNK1112: module machine type 'x64' conflicts with target machine type 'X86'

...so is that lib only for x64? So you know I'm still just using x86. Or is it anything else? How to fix that?

PS: Just can admit the statement on the image. One guy ruins everything and fornications up in its own dimension. But even the leaders in the UK got totally inside already by building walls of restrictions following Idiots ideas. Such a damn stupid nonsense what's going on these days.

greetz

Hi!

That LNK1112 error is a classic: you are trying to link a 64-bit library into a 32-bit (x86) project.

If the .lib file Fearless sent you was compiled for x64, it will never work in your x86 environment. You need the x86 version of the library.

How to fix it:

  1. Check the Lib: Ask Fearless if he has the 32-bit (x86) version of his library and libwebp.lib.

  2. Linker Settings: Ensure your build script has /MACHINE:X86 and isn't pointing to any x64 or amd64 folders in your SDK/VC paths.

  3. The _chkstk error: This usually happens because the library was built with a C compiler (Visual Studio) and expects the C Runtime (LIBCMT). If you want to bypass it in pure ASM, you can add a dummy stub:

    public __chkstk
    __chkstk:
    ret
    

It's a pain when simple image handling turns into a battle of architectures, especially with all the "modern" restrictions piling up.

Another:

I’m hitting a brick wall with the target from your topic and the dongle protection is driving me crazy.Would you be open to helping me one more time to achieve a 100% clean unpack or a way to emulate it? Your expertise would mean the world to me.😚😚🤭

Price

h_h

The library was compiled for x86.

You probably are using older visual c libs.

Make sure you have the latest all in one Visual C++ Redistributable: https://www.techpowerup.com/download/visual-c-redistributable-runtime-package-all-in-one/

and also the Windows Universal C Runtime (CRT) : https://www.microsoft.com/en-us/download/details.aspx?id=50410

I took the libs from Visual Studio 2022 or Visual Studio Build Tools 2019

Backup any existing libs before overwriting them in case you need the old ones for older code.

I uploaded both versions - Im using the 2019 ones from what I remember, but just in case i uploaded the 2022 one.

Make sure you are using a more modern linker, rc etc - not the older one that comes with masm32 sdk.

  • Author

Hi @Price,

so that means the lib from @fearless is just for x64? But the project files he attached are x86. Hm. Wrong lib included then or what? I'm using WinASM (still) and only make x86 stuff. My assembler setting..

/Zi /Zd /c /coff /Cp /nologo
/SUBSYSTEM:WINDOWS /DEBUG /DEBUGTYPE:CV /VERSION:4.0 /INCREMENTAL:NO /DYNAMICBASE:NO

...so that's all I have to build a debug version. Okay, seem I have to waif for @fearless to upload the x86 lib version. ) I also have a tool called dll to lib to build static libs from dll files. I tried to create a lib of that libwebp.dll x86 version but I also forgot how to use the app / adjust code to make it work. Damn! (

PS: I have seen the TM app you still working on it. I'm out of knowledge already to handle it. wheelchair ) Just hope that anyone else who is still on it can help you with that.

@fearless

Thanks for the files but still isn't working and I get that same error. I put the lib files from 2019 into MASM32 lib folder and it only did overwrite the msvcrt.lib I had. What now?

LIBCMT.lib(_chkstk_.obj) : fatal error LNK1112: module machine type 'x64' conflicts with target machine type 'X86'

What a modern linker rc? No clue, I didn't code for a longer while and forgot what that all means. Maybe just send me the files I need to get that working to compile etc. )

greetz

I checked libwebp.lib and its definitely compiled for x86:

Microsoft Windows [Version 10.0.19045.7058]
(c) Microsoft Corporation. All rights reserved.
M:\radasm\Masm\projects\Test Projects\_Graphics Projects\libWebPTest>dumpbin /headers libwebp.lib | findstr machine
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
             14C machine (x86)
M:\radasm\Masm\projects\Test Projects\_Graphics Projects\libWebPTest>

For the linker im using:

Microsoft (R) Incremental Linker Version 12.00.31101.0
Copyright (C) Microsoft Corporation.  All rights reserved.

Not sure what else to suggest. Maybe take out the debug stuff from the link command to test and add a libpath

LINK.EXE /SUBSYSTEM:WINDOWS /RELEASE /VERSION:4.0 /LIBPATH:"x:\masm32\lib"

Edited by fearless

  • Author

Hey again @fearless and thanks again.

Do you mean that ML.exe? Mine has no version info only 364KB. Another one I found has a version 8.0. Can you send me the files I need to put into bin folder of masm32? Adding libpah does not work too. The path is already in options to find. So why the heck doesn't it want to compile that stuff?

greetz

Create an account or sign in to comment

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.