Hi everyone,

I feel bad because i'm a frequent reader of this board, but seem to post very little these days, so in order to make amends here is a proc that will read a jpeg from a resource file, convert it to a bmp and return the handle to the bitmap.

It is based on some code from someone at this board - i forget who, and am too lazy to look it up - so thanks to ..... you know who you are. - update found the original writer - "Senf - 03.04.2001"
Anyway instead of reading from a disk jpeg, it reads from a resource one
call the resource type whatever you like - same as normal.

a little note in win 95/98 max bmp size is 16 meg - see note in code

hope this helps in some way



;################################################################################################

LoadJPEGResource PROC ResourceID:DWORD ;load a jpeg from the resource file

local hDCImage:DWORD
local mHDC:DWORD



;load in the resource data pointed to by the resource
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

invoke FindResource,hInstance,ResourceID,addr RsrcTypeJ ;call the resource whatever you want
mov RsrcHandJ, eax

invoke LoadResource,hInstance,eax
mov RsrcPointJ, eax

invoke SizeofResource,hInstance,RsrcHandJ
mov RsrcSizeJ, eax

invoke LockResource,RsrcPointJ
mov RsrcPointJ, eax

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; initalize Intel JPEG Library
invoke ijlInit, ADDR jcprops ; Intel JPEG Library initialization
.IF eax != IJL_OK

invoke MessageBox,NULL,addr CantInitLib,addr AppName,MB_OK


.ENDIF

; open JPEG file
mov eax, RsrcPointJ ;ResourceID
mov jcprops.JPGBytes, eax
mov eax,RsrcSizeJ
mov jcprops.JPGSizeBytes,eax
invoke ijlRead, ADDR jcprops,IJL_JBUFF_READPARAMS ; read parameters of JPEG file from a buffer - not file
.IF eax != IJL_OK
invoke MessageBox,NULL,addr badjpeg ,addr AppName,MB_OK


.ENDIF

; calculate size of buffer to hold 24bit image date & allocate memory
; determine the required size of 24bit buffer
mov eax, jcprops.JPGWidth ; width of JPEG to eax
add eax, 7
mov ebx, 24 ; bits per plane to ebx (24bit)
mul ebx ; multiply
add eax, 7 ; add 7
shr eax, 3 ; division by 8
mov ebx, jcprops.JPGHeight ; heigt of JPEG to eax
mul ebx
mov jbufsize24, eax
invoke GlobalAlloc, GHND, eax
.IF eax==FALSE

invoke MessageBox,NULL,addr nomem ,addr AppName,MB_OK

.ELSE
mov hjbuffer24, eax ; handle to allocated memory
.ENDIF
invoke GlobalLock, eax
mov jbuffer24, eax ; pointer to buffer

; fill DIB portion of the JPEG object
push jcprops.JPGWidth
pop jcprops.DIBWidth ; DIBWidth <- JPGWidth
push jcprops.JPGHeight ; implies a bottom-up DIB
pop jcprops.DIBHeight ; DIBHeight <- JPGHeight
mov jcprops.DIBChannels, 3 ; 3 channels
mov jcprops.DIBColor, IJL_BGR ; colors are in reversed order BGR instead of RGB

; calculate DIBPadBytes
mov eax, jcprops.JPGWidth ; JPEG width to eax
mov ebx, 3 ; number of channels to ebx
mul ebx ; multiply width with number of

channels
push eax ; store this value (IJL_DIB_UWIDTH)

add eax, IJL_DIB_ALIGN ; add IJL_DIB_ALIGN
mov ebx, IJL_DIB_ALIGN
not ebx
and eax, ebx ; AND with IJL_DIB_ALIGN
; eax holds IJL_DIB_AWIDTH
pop ebx ; restore IJL_DIB_UWIDTH to ebx
sub eax, ebx ; calculate IJL_DIB_PAD_BYTES
mov jcprops.DIBPadBytes, eax ; store value

push jbuffer24 ; push 24bit jpeg buffer address
pop jcprops.DIBBytes ; pop address

mov eax, jcprops.JPGChannels ; JPGChannels to eax
.IF eax==1 ; is it 1 ?
mov jcprops.JPGColor, IJL_G ; yes, then JPGColor is grayscale color space
.ELSEIF eax==3 ; is it 3 ?
mov jcprops.JPGColor, IJL_YCBCR ; yes, then JPGColor is luminance-chrominance color space
.ELSE
; This catches everything else, but no color twist will be
; performed by the IJL
mov jcprops.DIBColor, IJL_OTHER
mov jcprops.JPGColor, IJL_OTHER
.ENDIF

; Read in image from file
invoke ijlRead, ADDR jcprops,IJL_JBUFF_READWHOLEIMAGE ; IJL_JFILE_READWHOLEIMAGE
.IF eax != IJL_OK

invoke MessageBox,NULL,addr badjpeg ,addr AppName,MB_OK

.ENDIF

; no, then once again



; create the bitmap and get a handle to it
invoke CreateBitmap, jcprops.JPGWidth, jcprops.JPGHeight, 1, 24, jcprops.DIBBytes
.IF eax==NULL


;from msdn "Windows 95/98: The created bitmap cannot exceed 16MB in size."

invoke MessageBox,NULL,addr nocreate ,addr AppName,MB_OK

.ELSE
mov hBitmap, eax ; save handle of bitmap
.ENDIF

; delete bitmap



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
invoke GetDC,TWND ;TWND is the window handle, should actually be passed into this proc
mov mHDC,eax



mov bmi.bmiHeader.biSize, 40
mov eax, jcprops.DIBWidth
mov bmi.bmiHeader.biWidth, eax
mov eax, jcprops.DIBHeight
neg eax
mov bmi.bmiHeader.biHeight, eax
mov bmi.bmiHeader.biPlanes, 1
mov bmi.bmiHeader.biBitCount, 24
mov bmi.bmiHeader.biCompression, BI_RGB

INVOKE CreateDIBitmap, mHDC, ADDR bmi, CBM_INIT, jcprops.DIBBytes, ADDR bmi, DIB_RGB_COLORS

.IF eax==NULL

invoke MessageBox,NULL,addr cantmakebitmap,addr AppName,MB_OK

.ELSE
mov hBitmap, eax ; save handle of bitmap


.ENDIF

;max size seems about 6 or 8 meg





; free memory of JPEG buffers
invoke GlobalUnlock, jbuffer24
invoke GlobalFree, hjbuffer24


; release Intel JPEG Library Object
invoke ijlFree, ADDR jcprops

mov eax,hBitmap




ret
LoadJPEGResource ENDP



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


I just added the
 
tags to make the code easier to read.
Posted on 2003-02-12 07:32:10 by Terab
Nice pice of code. :)
(It would look even nicer if you put it in "[ CODE ]"-tags w/o the spaces inbetween )
Posted on 2003-02-12 08:12:48 by scientica

Nice pice of code. :)
(It would look even nicer if you put it in "[ CODE ]"-tags w/o the spaces inbetween )



i didnt know about the code /code tags :)

i use the above in most of my projects to keep the size down, as invariably a jpeg is small than aplibing a bmp - although for small images the aplib is better.

another trick is to arrange all the little images on one big jpeg and then chop it up into pieces at run time.

i'm currently working on a wavelet image compression in asm - although its gonna take some time.... a LOT of time :grin:
Posted on 2003-02-12 08:17:18 by Terab

i didnt know about the code /code tags :)
...
i'm currently working on a wavelet image compression in asm - although its gonna take some time.... a LOT of time :grin:

Well, there's always something to learn in the begining, for instance, it took me a while before i found the new posts function. the code tags can be added like the other tags (it's the buttonw with the "#", maybee we should ask Hiro to change the label to "Code" instead)

Wavelet, isn't that some image compression/storage techinque that compresses images good? I read some paper on it but didn't understand what it's all about...
Posted on 2003-02-12 08:27:31 by scientica
basically for the same file size as a jpeg your quality is much better - which implies you can use a smaller file :-)

you can also control exactly what you want you bpp to be and hence control the filesize.

i looked into laurawaves c-sdk but at $2500 / license / per project its not really an option.

there are a lot of wavelet resources out there so i dont think it going to be too dificult to make my own - famous last words :-)
Posted on 2003-02-12 08:38:48 by Terab
Hey cool... my department head asked me to do a research project... and I decided on wavelets as my topic.... (no specific application yet though, maybe speech/phoneme recognition)

Anyway wavelets (the 'continuous wavelet transform' or CWT at least) are kinda similar to Fourier transform, except you get both time and frequency info. Of course Short Term Fourier Transform (STFT, which is simply that you split your signal into equal-time chunks and fourier each chunk) can also get you both time and frequency info, but wavelets are more flexible.

This is because you have a Heidenberg uncertainty principle at work here too, more time accuracy=less freq accuracy, more freq accuracy=less time accuracy. With STFT you get a constant time and freq accuracy, but with CWT you get better time accuracy with higher frequencies (and because of the logarithmic nature of all things, slight differences in high frequencies are not noticeable and therefore inaccuracies at high frequencies are OK), and get better frequency accuracy with low frequencies (and slight differences in low frequencies are more noticeable).

DWT or Discrete Wavelet Transform, however, is used for image compression, not CWT. The maths looks WAY different for the two (at least in my research), but the tradeoff remains: better time accuracy for high frequencies, better freq. accuracy for low frequencies.


To view this in the image compression thing, just think of a plain green field with flowers. The green field is a 'low frequency' thing: it's the background, and between most pixels it hardly changes. However it's very noticeable if the green background is off the proper shade in the original picture. Now the flowers will be little splotches of color on the green field. They are high frequencies things, and in most pixels the exact shades will change quite a bit. However if the flowers are small enough, the exact color they have may not be all that noticeable, so a slight inaccuracy in their color is not too bad. However, their proper position will be noticed, and if they are off position a couple of pixels, the image is seen as different from the original.

Anyway... I suspect that wavelets would be VERY appropriate for encoding stuff like MIPMAPS... MIPMAPS are versions of a texture that are smaller than the original texture, and are less accurate. These are used if the surface being projected is small. However, if the surface being projected is larger than the original texture, the renderer may interpolate the pixels using pixels from the main texture and one or more of the mipmaps to fill in the pixels between.

(dang, that was kinda longer than I thought....)
Posted on 2003-02-14 04:56:58 by AmkG
Terab,nice work!:alright:
Posted on 2003-02-14 04:58:57 by Vortex
Good idea on using wavelet compression for texture maps...

The DWT looks quite tricky to implement in asm, you gotta split all the channels and do some pretty funky maths.

still in the end it will be worth it - maybe license it to nvidia for new texture mapping engine :grin: :grin:
Posted on 2003-02-14 07:04:17 by Terab
Ernie Murphy has made a really good library that do that using only Win API functions (no external library like the Intel one)...

It is somewhere on the board and there is an example in the latest MASM32 package.
Posted on 2003-02-14 07:37:04 by JCP

Good idea on using wavelet compression for texture maps...

The DWT looks quite tricky to implement in asm, you gotta split all the channels and do some pretty funky maths.


Well by 'split'... isn't this simply done by filtering? At least that's how the site I'm referring to explains it: two filters, one high-pass, one low pass, output of high-pass is decimated and saved, output of low pass is decimated and passed through the two filters again, until you end up with a two 2-length signals. Results are concatenated from the final low-pass output, then the last high-pass output to the first high-pass output.

http://engineering.rowan.edu/~polikar/WAVELETS/WTtutorial.html

AFAIK the filters needed for this are FIR ones, so you can simply convolve it. Then decimate the outputs of the filters by 1/2. Repeat for the next channel...

I don't see how difficult this is.... but maybe you see something I don't....


BTW in preparation for my research project I am building a set of asm macros to help work with matrices... one of the macro kits will do convolution... He he he I wonder if my department head will understand asm ha ha ha, well I'm gonna have to make the macro kit look as HLL as possible...



still in the end it will be worth it - maybe license it to nvidia for new texture mapping engine :grin: :grin:


He he he.... but would nvidia want it...??


P.S.
You know what, I suddenly realized how in the heck DWT and CWT are the same.

The IMPULSE RESPONSE of the filter is DA WAVELET in reverse (or FOLDED).

In CWT you do correlation with the scaled mother wavelet to the signal.

In DWT you do convolution with the impulse response of the filter.

And Convolution=correlation, except you fold one of the signals in convolution.

Dang.

You're really a friend Terab....
Posted on 2003-02-15 03:15:39 by AmkG
Hi,


mov jcprops.JPGSizeBytes,eax
invoke ijlRead, ADDR jcprops,IJL_JBUFF_READPARAMS ; read parameters of JPEG file from a buffer - not file
.IF eax != IJL_OK
invoke MessageBox,NULL,addr badjpeg ,addr AppName,MB_OK



ehm, where is this ijlRead function? I suupose everybody know, since they have congrats. Anyhow, thanks.
Posted on 2003-02-19 19:52:16 by cakmak
The intel jpeg library contains all these functions - ijl(version number).dll

i think the masm install has the inc and the lib for them.


hope this helps
Posted on 2003-02-20 02:14:37 by Terab
If you mean by "masm install" MASM32 - no
It doesn't have the lib and include.
Posted on 2003-02-28 19:33:35 by The Svin