News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Dimensions of a bitmap

Started by clamicun, June 14, 2017, 01:53:15 AM

Previous topic - Next topic

raymond

Quoteso it is not safe to only check for FF C0

Agree, in the context of JPEG files. If you looked at the wiki reference (obviously faster than trying to digest the entire jpeg specification), there are two major jpeg variants, 'base line' and 'progressive'.

The latter variant is for specific purposes and rarely used. In that case, the dimensions would be located in a block marked as FF C2.

If you are interesred in GIF images, a quick description of its format can also be found on Wikipedia at https://en.wikipedia.org/wiki/GIF#File_format.
Whenever you assume something, you risk being wrong half the time.
http://www.ray.masmcode.com

JoeBr

Hey there - just signed up.  I've been working with Assembler (mainly masm in the beginning, and later 64-bit with HJWasm and now Uasm).  Most assembly for me has been dealing with GDI and GDI-Plus.  General background is database programming in various languages, a LITTLE C and C++/C-Sharp, and VB.Net.  My apologies if this isn't in the right place for a 'New Member Posting' - looking around and couldn't see a New Member Posting area - again sorry if I missed it.

So far as the dimensions and a more 'general approach' - maybe something like -
         invoke MultiByteToWideChar, CP_ACP,0, psPath,-1, addr sPathWide, 128
         invoke GdipCreateBitmapFromFile,addr sPathWide, addr hbmp
...
         invoke GdipGetImageWidth,hbmp,pdSrcW
         invoke GdipGetImageHeight,hbmp,pdSrcH

?
(This is the basic I've come up with in all my coding - and as I understand it GdipCreateBitmapFromFile will work with multiple image formats)


And thank you all for all of the help I've vicariously gleaned from the forum.

HTH
Joe




jj2007

Here is another one, works with most image formats including animated GIFs:include \masm32\MasmBasic\Res\MbGui.asm
Event Paint
  GuiImage CL$(), fit ; drag an image over the exe
  GuiTextBox 100.0-99, 9, 90, 32, Cat$(Str$("Original size is %ix", GdiSI.jjWidth)+Str$(GdiSI.jjHeight))
GuiEnd


Displays the image and, in the upper right corner, a text box showing its original dimensions. Attached an example, including a beautiful Japanese image ;-)

@Joe: Welcome :icon14:
Btw there are some situations where GdipCreateBitmapFromStream is the better choice.

P.S.: Hutch will kill me for wasting server space, but check the second attachment: A 1859 colours animated GIF file 8)

Siekmanski

You have been fooled, there are only 256 colors in that frame.  :biggrin:
Creative coders use backward thinking techniques as a strategy.

jj2007

Your feedback is very precise as usual, Marinus :badgrin:

hutch--

No problems Joe, it makes life easier when new members post as we then know they are not bots.

clamicun

Fortrans,
I do not understand the readfile proc

DWORD PTR [esp+4] until DWORD PTR [esp+48] might be very professional, but names are certainly more understandable.
Anyway, it seems that the program only works with .bmp and I am only interested in .jpgs
Thank you for your work.

HSE

Hi Clamicum!

You are losing your mind with that crazy bitmaps :biggrin:

ReadFile.asm it's from Vortex!

I'm making some easy program with images, but BMP. Very soon. :t
Equations in Assembly: SmplMath

Vortex

Hi clamicun,

The ReadFileToMem function has no stack frame and this is why it looks complicated. JoeBr's suggestion is nice as you can use GDI+ to get the required information :

include     GetImageSize.inc

.data

msg1        db 'Usage : GetImageSize.exe imagefile.ext',13,10,0
msg2        db 'Width = %u',13,10
            db 'Height = %u',0

.data?

hBitmap     dd ?
BmpImage    dd ?
token       dd ?
ImgWidth    dd ?
ImgHeight   dd ?
buffer1     db 1024 dup(?)
buffer2     db 32 dup(?)
StartupInfo GdiplusStartupInput <?>

.code

start:

    call    main
    invoke  ExitProcess,0

main PROC uses esi
       
    mov     esi,OFFSET buffer1
    invoke  ParseCmdLineW,esi
    cmp     eax,1+1
    je      @f
       
    invoke  StdOut,ADDR msg1
    ret
@@:

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

    invoke  GdiplusStartup,ADDR token,ADDR StartupInfo,0

    invoke  GdipCreateBitmapFromFile,DWORD PTR [esi+4],\
            ADDR BmpImage

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

    invoke  wsprintf,ADDR buffer2,ADDR msg2,ImgWidth,\
            ImgHeight

    invoke  StdOut,ADDR buffer2

    invoke  GdipDisposeImage,BmpImage
    invoke  GdiplusShutdown,token
    ret

main ENDP

END start


GetImageSize.exe Test.JPG
Width = 116
Height = 80


The tool can read information from .gif and .tif images. The advantage of the GDI+ method is that you don't need to know anything about the image format.

Hi JoeBr,

Thanks for your idea and welcome to the forum :t

clamicun

Vortex,
excuse me for confusing names.
Yes, seems to be the easiest method to get height and width.
Thank you

Not too different from my first idea...

INVOKE MultiByteToWideChar,CP_ACP,MB_PRECOMPOSED,offset image_path,-1,ADDR UnicodeFileName,MAX_PATH-1
INVOKE GdipCreateBitmapFromFile,ADDR UnicodeFileName,ADDR BmpImage
INVOKE GdipCreateHBITMAPFromBitmap,BmpImage,ADDR hBitmap,0

INVOKE CreateCompatibleDC,0
mov hMemDC,eax

INVOKE SelectObject,hMemDC,hBitmap
INVOKE GetObject,hBitmap,sizeof(BITMAP),ADDR bm
lea edx,bm

mov eax,BITMAP.bmWidth[edx]
mov image_width,eax

mov eax,BITMAP.bmHeight[edx]
mov image_height,eax
------
but  simpler

clamicun

Vortex,
finally..
I would understand the program without  the "parse proc"... (absolutely ununderstandable) ... not one comment.

My program reads the jpg filename out of an array.
So I need names.

invoke  GdipCreateBitmapFromFile,DWORD PTR [esi+4],ADDR BmpImage
changed to
invoke  GdipCreateBitmapFromFile,offset file_name,ADDR BmpImage 
does not do it ??

JoeBr

Thanks Hutch, JJ, Vortex, and everyone.  Been reading the forum for 2 or 3 years, first-time posting (just learning via personal projects and reading for a while now... now (maybe?) to the point of actually being able to help, albeit I'm still quite the noob compared to you guys).  Coming from VB.Net, had to suffer for maybe a couple of weeks trying to understand the elementary(?) level of control going into assembly, that I think for me was the worst part (then it kinda just 'clicked' one day).  And 64, more fun there.... and then the convention finally sunk in.  This forum is quite the resource for those interested in the POWER of it all, amazing at the speed with the AVX etc ops, and the level of control in Assembler.  And so many ways to write the same piece of code.

Thanks again  :t
Joe

clamicun

Thanks to all,
everything is ok now