News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

My Code does not work anymore

Started by Farabi, June 10, 2010, 09:18:29 PM

Previous topic - Next topic

Farabi

Quote from: dedndave on June 11, 2010, 06:25:24 PM
Onan, does that routine give you the opportunity to set the "quality" and "smoothing" values for JFIF compression ?

No, not yet.
Those who had universe knowledges can control the world by a micro processor.
http://www.wix.com/farabio/firstpage

"Etos siperi elegi"

donkey

Hi Onan,

There really is no need whatsoever to search the codecs, it is a predefined CLSID for JPEG. Also you are doing a lot of unicode conversion which can be painfully slow, the shlwapi API can replace a bit of it. This should work in MASM though I have not tried it:

.CONST
sCLSID_JPEG textequ <{557cf401H, 1a04H, 11d3H,{09aH, 073H, 000H, 000H, 0f8H, 01eH, 0f3H, 02eH}}>

.DATA
CLSIDImageEncoderJPEG GUID sCLSID_JPEG
JPEGExt DB ".",0,"J",0,"P",0,"G",0,0,0

.CODE
; ...
invoke MultiByteToWideChar,0,0,lpFileName,-1,addr buff3,512
; no need to dereference this, it is the first member of the structure
mov    DWORD PTR gdipsi, 1
; start GDIPlus
invoke GdiplusStartup, ADDR token, offset gdipsi, NULL

; Load the image
invoke GdipLoadImageFromFile, addr buff3, ADDR image

; rename the extension
invoke PathRenameExtensionW, ADDR buff3,offset JPEGExt

; Save the image
invoke GdipSaveImageToFile, image, addr buff3,offset CLSIDImageEncoderJPEG, NULL

; Free the image
invoke GdipDisposeImage, image
; Release GDIPlus
invoke GdiplusShutdown, token
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

Vortex

Hi Onan,

Sorry for being late. OK, here is my code converting a bitmap image in memory to .jpg :


include    GDIpBmpToJPG.inc

.data
jpegFile            db 'test.jpg',0
ImgType             db 'image/jpeg',0
message             db 'BMP file converted to JPG',0
caption             db 'GDI+ demo',0
ImgQuality          dd  90
_EncoderQuality     GUID <01d5be4b5h,0fa4ah,0452dh,<09ch,0ddh,05dh,0b3h,051h,05h,0e7h,0ebh>>

.data?
StartupInfo         GdiplusStartupInput <?>
buffer              db 32 dup(?)
pImageCodecInfo     dd ?
token               dd ?
BmpImage            dd ?
eps                 EncoderParameters <?>

.code

start:

    mov         eax,OFFSET StartupInfo
    mov         GdiplusStartupInput.GdiplusVersion[eax],1
                                                 ; must be always seto to 1
    invoke      GdiplusStartup,ADDR token,ADDR StartupInfo,0

    mov         eax,OFFSET pImage
    mov         ecx,BITMAPFILEHEADER.bfOffBits[eax]
    lea         edx,[eax+ecx]                    ; points the array of bytes that contains the pixel data
    add         eax,SIZEOF BITMAPFILEHEADER      ; points the BITMAPINFO structure
    invoke      GdipCreateBitmapFromGdiDib,eax,edx,ADDR BmpImage
                                                 ; creates a Bitmap object based on a BITMAPINFO structure and
                                                 ; an array of pixel data

    invoke     UnicodeStr,ADDR jpegFile,ADDR buffer
    mov        esi,OFFSET eps
    mov        EncoderParameters.Count[esi],1
    lea        ecx,[esi+EncoderParameters.Parameter.pGUID]
    invoke     MemCopy,ADDR _EncoderQuality,ecx,16    ; copy the GUID ot the correct address
    mov        EncoderParameters.Parameter.vType[esi],EncoderParameterValueTypeLong
    mov        EncoderParameters.Parameter.NumberOfValues[esi],1
                                                ; we have only one EncoderParameter structure
    mov        EncoderParameters.Parameter.value[esi],OFFSET ImgQuality
                                                ; set the JPEG compression level
    invoke     GetEncoderClsid,ADDR ImgType,ADDR pImageCodecInfo
                                                ; get the class identifier (CLSID) of the encoder
                                                ; The encoder can be bmp,jpeg,gif,tiff or png

    invoke     GdipSaveImageToFile,BmpImage,ADDR buffer,eax,ADDR eps
                                                ; save the image file

    invoke     VirtualFree,pImageCodecInfo,0,MEM_RELEASE

    invoke     GdipDisposeImage,BmpImage        ; release the image
    invoke     GdiplusShutdown,token            ; shutdown the GDI+ system
    invoke     MessageBox,0,ADDR message,ADDR caption,MB_OK
    invoke     ExitProcess,0

GetEncoderClsid PROC USES ebx edi sMimeType:DWORD,pMem:DWORD

LOCAL numEncoders:DWORD
LOCAL nSize:DWORD
LOCAL _buffer[32]:BYTE

    invoke     GdipGetImageEncodersSize,ADDR numEncoders,ADDR nSize
    invoke     VirtualAlloc,0,nSize,MEM_COMMIT,PAGE_READWRITE
    mov        edi,eax
    mov        eax,pMem                             ; = pImageCodecInfo
    mov        DWORD PTR [eax],edi
    invoke     GdipGetImageEncoders,numEncoders,nSize,edi
    invoke     UnicodeStr,sMimeType,ADDR _buffer
    mov        ebx,numEncoders
@@:
    invoke     StrCmpW,ADDR _buffer,ImageCodecInfo.MimeType[edi]
    test       eax,eax
    jnz        @f
    sub        ebx,1
    add        edi,SIZEOF ImageCodecInfo
    jmp        @b
@@:
    mov        eax,edi                              ; = lea    eax,[edi+ImageCodecInfo.Clsid]
    ret

GetEncoderClsid ENDP

END start


Vortex

Hi Onan,

My code can set the convertion quality of the .jpg but donkey's code is preferable as it's easier to maintain and use. Coding the codecs part of my application was not an easy task.

donkey

Hi Vortex,

Nice code, have you thought about allowing for a change in color depth as well ? I do it in some of my GDIP proggies. Here's the appropriate code segment for changing it (in GoAsm syntax - sorry). Allowable values for bitdepth are 8, 16,24, 32, 48 and 64 as well as -1 for no conversion, some depths are only available to bitmaps see the comments for details.

// The largest palette size is 1024 bytes so we allocate that
invoke GdipAlloc,1024 + SIZEOF ColorPalette
mov [pPal],eax

cmp D[bitdepth],-1
je >>.NoConvert

cmp D[bitdepth],8
jne >
// Since this is an indexed type use a large palette to find the closest colors
// it will be reduced to 256 colors by the conversion function
mov D[PalType],PaletteTypeFixedHalftone27
mov D[ImgFmt],PixelFormat8bppIndexed
jmp >>.Convert
:
cmp D[bitdepth],24
jne >
mov D[PalType],PaletteTypeFixedHalftone27
mov D[ImgFmt],PixelFormat24bppRGB
jmp >>.Convert
:
cmp D[bitdepth],32
jne >
mov D[PalType],PaletteTypeFixedHalftone256
mov D[ImgFmt],PixelFormat32bppRGB
jmp >>.Convert
:

cmp D[format],GDIP_IMAGE_BMP
jne >>.NoConvert
// Bitmap only color depths
cmp D[bitdepth],16
jne >
// There is no standard 16Bpp palette so we use a 24 Bpp. It's not optimal but easier.
mov D[PalType],PaletteTypeFixedHalftone27
mov D[ImgFmt],PixelFormat16bppRGB555
jmp >>.Convert
:
cmp D[bitdepth],48
jne >
mov D[PalType],PaletteTypeFixedHalftone256
mov D[ImgFmt],PixelFormat48bppRGB
:
cmp D[bitdepth],64
jne >.NoConvert
mov D[PalType],PaletteTypeFixedHalftone256
mov D[ImgFmt],PixelFormat64bppARGB

.Convert
invoke GdipInitializePalette,[pPal], [PalType], 0, TRUE, NULL

invoke GdipBitmapConvertFormat,[pImage],[ImgFmt], DitherTypeNone,[PalType],[pPal],50.0

.NoConvert


The PalletteType enumeration is found in GdiplusPixelFormats.h of the header project include gdiplus.h. This segment requires GDIP version 1.1.

Edgar
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

Vortex

Hi donkey,

Thanks for your code. The color depth is another important parameter and GDI+ can set this value. No problem with the syntax, it's fine :U

Farabi

Well I guess I will put all of this into one function named "fSaveFileAs".
It can save from one format to another format.
Those who had universe knowledges can control the world by a micro processor.
http://www.wix.com/farabio/firstpage

"Etos siperi elegi"