📄 imageprocess.asm
字号:
.686
.model flat,stdcall
option casemap:none
include windows.inc
include MyMacro.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include gdi32.inc
includelib gdi32.lib
.const
IniFileName db '.\Huffman.ini',0
LogFileName db '.\Huffman.log',0
SectionName db '图片',0
InputKeyName db '输入文件',0
OutputKeyName db '输出文件',0
DefaultInput db 'C:\WINDOWS\Web\Wallpaper\Bliss.bmp',0
DefaultOutput db '.\Bliss.huf',0
LogFileTitle db '符号 出现次数 Huffman码值 码长',13,10,0
LogFileContent db '%02x %d %08xh %d',13,10,0
HUFFMANNODE struct
Probability dword ?
union
HuffmanCode dword ?
LeftChild dword ?
ends
union
CodeLength dword ?
RightChild dword ?
ends
LeafNodeFlag dword ?
HUFFMANNODE ends
include HuffmanEncode.asm
.code
WinMain? proc
LOCAL @ResultFlag
LOCAL @SizeImage
LOCAL @ImageFileName[MAX_PATH],@EncodedFileName[MAX_PATH]
LOCAL @hInputFile,@hInputFileMap,@lpInputMemory
LOCAL @hOutputFile,@lpOutputFileBuffer,@NumberOfBytesWritten
LOCAL @HuffmanNode[256]:HUFFMANNODE
LOCAL @lpLogFileBuffer,@hLogFile
mov @ResultFlag,FALSE
invoke GetPrivateProfileString,offset SectionName,offset InputKeyName,offset DefaultInput,addr @ImageFileName,MAX_PATH,offset IniFileName
invoke CreateFile,addr @ImageFileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL
.if eax != INVALID_HANDLE_VALUE
mov @hInputFile,eax
invoke CreateFileMapping,@hInputFile,NULL,PAGE_READONLY,0,0,NULL
mov @hInputFileMap,eax
invoke MapViewOfFile,@hInputFileMap,FILE_MAP_READ,0,0,0
mov @lpInputMemory,eax
assume eax:ptr BITMAPFILEHEADER
.if [eax].bfType == 'MB'
assume esi:ptr BITMAPINFOHEADER
mov esi,eax
add esi,sizeof BITMAPFILEHEADER
m2m @SizeImage,[esi].biSizeImage
mov ebx,eax
add ebx,[eax].bfOffBits
.if [esi].biBitCount == 8
assume esi:nothing
mov ecx,0
.repeat
lea eax,[ecx*4]
mov @HuffmanNode[eax*4].Probability,0
inc ecx
.until ecx == 256
mov eax,0
mov ecx,0
.repeat
mov al,byte ptr [ebx+ecx]
lea edx,[eax*4]
inc @HuffmanNode[edx*4].Probability
inc ecx
.until ecx == @SizeImage
invoke HuffmanEncode?,256,addr @HuffmanNode
pusha
invoke GlobalAlloc,GMEM_FIXED or GMEM_ZEROINIT,10240
mov @lpLogFileBuffer,eax
mov edi,eax
mov esi,offset LogFileTitle
mov ecx,sizeof LogFileTitle
dec ecx
rep movsb
mov ebx,0
.repeat
lea eax,[ebx*4]
invoke wsprintf,edi,offset LogFileContent,ebx,\
@HuffmanNode[eax*4].Probability,\
@HuffmanNode[eax*4].HuffmanCode,\
@HuffmanNode[eax*4].CodeLength
add edi,eax
inc ebx
.until ebx == 256
sub edi,@lpLogFileBuffer
invoke CreateFile,offset LogFileName,GENERIC_READ or GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_ARCHIVE,NULL
mov @hLogFile,eax
invoke WriteFile,@hLogFile,@lpLogFileBuffer,edi,addr @NumberOfBytesWritten,NULL
invoke CloseHandle,@hLogFile
invoke GlobalFree,@lpLogFileBuffer
popa
invoke GetFileSize,@hInputFile,NULL
add eax,512+4
invoke GlobalAlloc,GMEM_FIXED or GMEM_ZEROINIT,eax
mov @lpOutputFileBuffer,eax
mov edi,eax
mov byte ptr [edi],'H'
mov byte ptr [edi+1],'U'
mov byte ptr [edi+2],'F'
add edi,4
mov ecx,0
.repeat
lea eax,[ecx*4]
m2m [edi][eax*2],@HuffmanNode[eax*4].HuffmanCode
m2m [edi][eax*2+4],@HuffmanNode[eax*4].CodeLength
inc ecx
.until ecx == 256
add edi,512*4
mov ecx,sizeof BITMAPINFOHEADER + 1024
rep movsb
mov edx,7
mov ecx,0
.repeat
movzx ebx,byte ptr [esi][ecx]
shl ebx,2
mov eax,@HuffmanNode[ebx*4].CodeLength
.repeat
dec eax
bt @HuffmanNode[ebx*4].HuffmanCode,eax
.if carry?
bts [edi],edx
.endif
dec edx
.if edx == -1
inc edi
mov edx,7
.endif
.until eax == 0
inc ecx
.until ecx == @SizeImage
.if edx != 7
inc edi
.endif
mov eax,@lpOutputFileBuffer
sub edi,eax
invoke GetPrivateProfileString,offset SectionName,offset OutputKeyName,offset DefaultOutput,addr @EncodedFileName,MAX_PATH,offset IniFileName
invoke CreateFile,addr @EncodedFileName,GENERIC_READ or GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_ARCHIVE,NULL
mov @hOutputFile,eax
invoke WriteFile,@hOutputFile,@lpOutputFileBuffer,edi,addr @NumberOfBytesWritten,NULL
.if edi == @NumberOfBytesWritten
mov @ResultFlag,TRUE
.endif
invoke CloseHandle,@hOutputFile
invoke GlobalFree,@lpOutputFileBuffer
.endif
.endif
assume eax:nothing
invoke UnmapViewOfFile,@lpInputMemory
invoke CloseHandle,@hInputFileMap
invoke CloseHandle,@hInputFile
.endif
mov eax,@ResultFlag
ret
WinMain? endp
start: invoke MessageBox,NULL,String('本程序对配置文件中指定的32位Bitmap文件进行Huffman编码'),String('提示'),MB_OK
invoke WinMain?
.if eax
invoke MessageBox,NULL,String('编码成功,运行HuffmanDecode.exe可对编码生成的文件进行解码'),String('提示'),MB_OK
.else
invoke MessageBox,NULL,String('编码失败,请检查配置文件内容'),String('错误提示'),MB_OK
.endif
invoke ExitProcess,NULL
end start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -