Joined: Sun Oct 30, 2011 6:43 pm Posts: 1498
|
Leency, конкретно в моём ScreenShoter-е — самописанная функция. Но никто не мешает использовать libimg для этого, можно ещё даже в pnm сохранить. Просто в моём случае, как мне кажется, гораздо короче будет использовать самописное, чем грузить libimg только ради сохранения в bmp. Quote: В Колибри есть либа для этого дела? Ну вроде libimg для этого. Кстати, если ты помнишь, я делал ещё imgC для конвертирования, она тоже libimg использует. Там так Code: ; try to encode ; |------------------------------------------------- ; push 0 push dword [format_id] push dword [src] call [img_encode] А целиком вот Code: ; nasm -f bin "imgC.asm" -o "imgC.kex" ORG 0 BITS 32 ; ------------------------------------------------------------- ; PATH_SIZE equ 1024 PARAMS_SIZE equ 256 STACK_SIZE equ 2048 ; ------------------------------------------------------------- ; CANNOT_OPEN_SRC equ 1 SRC_NOT_AVAILABLE equ 2 DECODE_ERROR equ 3 OPTIONS_INCORRECT equ 4 NO_INPUT_PARAMS equ 5 NO_INPUT_SRC equ 6 SRC_IS_EMPTY equ 7 MEM_ALLOC_ERROR equ 8 ENCODE_ERROR equ 9 CANNOT_SAVE_DST equ 10 FLIP_ERROR equ 11 ROTATE_ERROR equ 12 ; ------------------------------------------------------------- ; FLIP_VERTICAL equ 1 FLIP_HORIZONTAL equ 2 FLIP_BOTH equ 3 ; ------------------------------------------------------------- ; ROTATE_90_CW equ 1 ROTATE_180 equ 2 ROTATE_270_CW equ 3 ROTATE_90_CCW equ ROTATE_270_CW ROTATE_270_CCW equ ROTATE_90_CW ; ------------------------------------------------------------- ; LIBIMG_SCALE_STRETCH equ 3 LIBIMG_INTER_BILINEAR equ 1 ; ------------------------------------------------------------- ; BPP8I equ 1 BPP24 equ 2 BPP32 equ 3 BPP15 equ 4 BPP16 equ 5 BPP1 equ 6 BPP8G equ 7 BPP2I equ 8 BPP4I equ 9 BPP8A equ 10 ; ------------------------------------------------------------- ; MENUET01 db 'MENUET01' version dd 1 program.start dd start_ program.end dd end_ program.memory dd end_ + PATH_SIZE + PARAMS_SIZE + STACK_SIZE program.stack dd end_ + PATH_SIZE + PARAMS_SIZE + STACK_SIZE program.params dd end_ + PATH_SIZE program.path dd end_ ; ------------------------------------------------------------- ; src dd 0 format_id dd 0 extension dd 0 options dd 0 flip dd 0 rotate dd 0 img_type dd 0 scale: dd 0 .width dd 0 .height dd 0 convert dd 0 ; ------------------------------------------------------------- ; formats: dd sz_bmp dd sz_ico dd sz_cur dd sz_gif dd sz_png dd sz_jpeg dd sz_tga dd sz_pcx dd sz_xcf dd sz_tiff dd sz_pnm dd sz_wbmp dd sz_z80 .end:
sz_bmp db "bmp",0 sz_ico db "ico",0 sz_cur db "cur",0 sz_gif db "gif",0 sz_png db "png",0 sz_jpeg db "jpeg",0 sz_tga db "tga",0 sz_pcx db "pcx",0 sz_xcf db "xcf",0 sz_tiff db "tiff",0 sz_pnm db "pnm",0 sz_wbmp db "wbmp",0 sz_z80 db "scr",0 ; ------------------------------------------------------------- ; libimg dd 0 libimg_init dd 0 img_decode dd 0 img_encode dd 0 img_scale dd 0 img_convert dd 0 img_flip dd 0 img_rotate dd 0 img_destroy dd 0 ; ------------------------------------------------------------- ; sz_libimg db "/sys/lib/libimg.obj",0 sz_img_decode db "img_decode",0 sz_lib_init db "lib_init",0 sz_img_destroy db "img_destroy",0 sz_img_encode db "img_encode",0 sz_img_scale db "img_scale",0 sz_img_convert db "img_convert",0 sz_img_flip db "img_flip",0 sz_img_rotate db "img_rotate",0 sz_notify db "/sys/@notify",0 ; ------------------------------------------------------------- ; srcpath dd 0 dstpath dd 0 ; ------------------------------------------------------------- ; errors: resd 1 dd sz_src_not_found dd sz_src_not_available dd sz_decode_error dd sz_options_incorrect dd sz_no_input_params dd sz_no_input_src dd sz_src_is_empty dd sz_mem_alloc_error dd sz_encode_error dd sz_cannot_save_dst dd sz_flip_error dd sz_rotate_error libimg_errors: resd 1 dd sz_out_of_memory dd sz_format dd sz_conditions dd sz_bit_depth dd sz_encoder dd sz_src_type dd sz_scale dd sz_inter dd sz_not_inplemented dd sz_invalid_input
sz_src_not_found db "cannot open source file",0 sz_src_not_available db "source file not available",0 sz_decode_error db "decode error",0 sz_options_incorrect db "options incorrect",0 sz_no_input_params db "no input parameters",0 sz_no_input_src db "no input source file",0 sz_src_is_empty db "source file is empty",0 sz_mem_alloc_error db "memory allocation error",0 sz_encode_error db "encode error",0 sz_cannot_save_dst db "cannot save dest. file",0 sz_flip_error db "flip error",0 sz_rotate_error db "rotate error",0
sz_out_of_memory db "out of memory",0 sz_format db "format is not supported",0 sz_conditions db "specific conditions cannot be satisfied",0 sz_bit_depth db "bit depth cannot be preserved",0 sz_encoder db "encoder",0 sz_src_type db "src type",0 sz_scale db "scale",0 sz_inter db "inter",0 sz_not_inplemented db "not inplemented",0 sz_invalid_input db "invalid input",0
; ------------------------------------------------------------- ; load.library: mov eax, 68 mov ebx, 19 mov ecx, [esp + 4] int 64 ret 4 ; ------------------------------------------------------------- ; getprocaddress: mov edx, [esp + 8] xor eax, eax test edx, edx jz .end .next: cmp [edx], dword 0 jz .end xor eax, eax mov esi, [edx] mov edi, [esp + 4] .next_: lodsb scasb jne .fail or al, al jnz .next_ jmp .ok .fail: add edx, 8 jmp .next .ok: mov eax, [edx + 4] .end: ret 8 ; ------------------------------------------------------------- ; %define lib_init [esp + 4 + 8 * 4] dll.init: pushad mov eax, memory.allocate mov ebx, memory.free mov ecx, memory.reallocate mov edx, .dll_load call lib_init popad ret 4 %undef lib_init .dll_load: push ebp mov ebp, esp mov esi, [ebp + 8] .next_lib: mov edx, [esi] or edx, edx jz .exit push esi mov esi, [esi + 4] mov edi, .lib_name .b: lodsb stosb or al, al jnz .b push .lib_path call load.library or eax, eax jz .fail mov ecx, [eax] cmp dword [ecx + 4], "init" jne .skip_init push dword [eax + 4] call dll.init .skip_init: mov ecx, eax mov ebx, edx test edx, edx jz .done .next: mov eax, [ebx] test eax, eax jz .done push ecx push eax call getprocaddress or eax, eax jz .f mov [ebx], eax add ebx, 4 jmp .next .f: mov [esp], eax .done: pop esi add esi, 8 jmp .next_lib .exit: xor eax, eax jmp .return .fail: pop esi inc eax .return: pop ebp ret 4 .lib_path: db "/sys/lib/" .lib_name: resb 32 ; ------------------------------------------------------------- ; file.read: mov eax, [esp + 12] mov edx, [esp + 8] mov ecx, [esp + 4] mov ebx, .file_info mov [.file_path], eax mov [.buffer], edx mov [.count], ecx mov eax, 70 int 64 ret 12 .file_info: dd 0 dd 0 dd 0 .count: dd 0 .buffer: dd 0 db 0 .file_path: dd 0 ; ------------------------------------------------------------- ; file.write: mov eax, [esp + 12] mov ecx, [esp + 8] mov edx, [esp + 4] mov ebx, .file_info mov [.file_path], eax mov [.buffer], ecx mov [.count], edx mov eax, 70 int 64 ret 12 .file_info: dd 2 dd 0 dd 0 .count: dd 0 .buffer: dd 0 db 0 .file_path: dd 0 ; ------------------------------------------------------------- ; file.run: mov eax, [esp + 8] mov ecx, [esp + 4] mov ebx, .file_info mov [.file_path], eax mov [.params], ecx mov eax, 70 int 64 ret 8 .file_info: dd 7 dd 0 .params: dd 0 dd 0 dd 0 db 0 .file_path: dd 0 ; ------------------------------------------------------------- ; memory.allocate: push ebx push ecx mov ecx, [esp + 12] mov eax, 68 mov ebx, 12 int 64 pop ecx pop ebx ret 4 ; ------------------------------------------------------------- ; memory.reallocate: push ebx push ecx push edx mov edx, [esp + 16] mov ecx, [esp + 20] mov eax, 68 mov ebx, 20 int 64 pop edx pop ecx pop ebx ret 8 ; ------------------------------------------------------------- ; memory.free: push ebx push ecx mov ecx, [esp + 12] mov eax, 68 mov ebx, 13 int 64 pop ecx pop ebx ret 4 ; ------------------------------------------------------------- ;
; ------------------------------------------------------------- ; ; ==========================| START |========================== ; ; ------------------------------------------------------------- ; start_: xor eax, eax mov esi, [program.params] ; check if params exists cmp [esi], byte 0 jne .params_exists mov [errors], dword NO_INPUT_PARAMS jmp .check_errors .params_exists: ; check if options exists cmp [esi], byte "/" jne .options_exists je .src_path_exists
.options_exists: mov [options], esi ; check if src path exists or eax, -1 .check_src: inc eax cmp [esi + eax], byte "/" je .src_path_exists cmp [esi + eax], byte 0 jne .check_src .src_path_not_exists: mov [errors], dword NO_INPUT_SRC jmp .check_errors .src_path_exists: mov [srcpath], esi add [srcpath], eax
or eax, -1 .find_end_src_path: inc eax cmp [esi + eax], byte ">" je .end_src_path_found cmp [esi + eax], byte 0 jne .find_end_src_path .end_src_path_found: mov [esi + eax], byte 0
add esi, eax inc esi
; check if dst path exists or eax, -1 .check_dst: inc eax cmp [esi + eax], byte "/" je .dst_path_exists cmp [esi + eax], byte 0 jne .check_dst .dst_path_not_exists: ; if not make it same as srcpath xor eax, eax mov esi, [srcpath] .dst_path_exists: mov [dstpath], esi add [dstpath], eax
; check dst extension or eax, -1 xor ecx, ecx .check_ext: inc eax cmp [esi + eax], byte "." jne .skip mov ecx, eax inc ecx .skip: cmp [esi + eax], byte 0 jne .check_ext jcxz .no_ext mov eax, ecx .no_ext: lea eax, [esi + eax] mov [extension], eax
; check if options correct
mov esi, [options] test esi, esi jz .options_correct .next_option: lodsb cmp al, "/" je .options_correct .flip: ; |-------------------------------------------- ; cmp al, "f" jne .rotate lodsb .fv: cmp al, "v" jne .fh or [flip], dword FLIP_VERTICAL jmp .next_option .fh: cmp al, "h" jne .fb or [flip], dword FLIP_HORIZONTAL jmp .next_option .fb: cmp al, "b" jne .options_incorrect or [flip], dword FLIP_BOTH jmp .next_option .rotate: ; |------------------------------------------- ; cmp al, "r" jne .scale lodsb .r90: cmp al, "9" jne .r180 lodsb cmp al, "0" jne .options_incorrect mov [rotate], dword ROTATE_90_CW jmp .next_option .r180: cmp al, "1" jne .r270 lodsb cmp al, "8" jne .options_incorrect lodsb cmp al, "0" jne .options_incorrect mov [rotate], dword ROTATE_180 jmp .next_option .r270: cmp al, "2" jne .options_incorrect lodsb cmp al, "7" jne .options_incorrect lodsb cmp al, "0" jne .options_incorrect mov [rotate], dword ROTATE_270_CW jmp .next_option .scale: ; |-------------------------------------------- ; cmp al, "s" jne .convert cmp [esi], byte "%" jne .no_percent mov [scale], byte "%" inc esi .no_percent: xor eax, eax xor ecx, ecx .next_w: lodsb sub al, 48 cmp al, 9 jnbe .done_w lea ecx, [ecx + ecx * 4] lea ecx, [eax + ecx * 2] jmp .next_w .done_w: mov [scale.width], ecx cmp al, "x" - 48 jne .options_incorrect xor eax, eax xor ecx, ecx .next_h: lodsb sub al, 48 cmp al, 9 jnbe .done_h lea ecx, [ecx + ecx * 4] lea ecx, [eax + ecx * 2] jmp .next_h .done_h: mov [scale.height], ecx jmp .next_option .convert: ; |-------------------------------------------- ; cmp al, "b" jne .space lodsw cmp ax, "pp" jne .options_incorrect lodsw .8i: cmp ax, "8i" jne .24 mov [convert], dword BPP8I jmp .next_option .24: cmp ax, "24" jne .32 mov [convert], dword BPP24 jmp .next_option .32: cmp ax, "32" jne .15 mov [convert], dword BPP32 jmp .next_option .15: cmp ax, "15" jne .16 mov [convert], dword BPP15 jmp .next_option .16: cmp ax, "16" jne .1 mov [convert], dword BPP16 jmp .next_option .1: cmp al, "1" jne .8g dec esi mov [convert], dword BPP1 jmp .next_option .8g: cmp ax, "8g" jne .2i mov [convert], dword BPP8G jmp .next_option .2i: cmp ax, "2i" jne .4i mov [convert], dword BPP2I jmp .next_option .4i: cmp ax, "4i" jne .8a mov [convert], dword BPP4I jmp .next_option .8a: cmp ax, "8a" jne .options_incorrect mov [convert], dword BPP8A jmp .next_option .space: ; |-------------------------------------------- ; cmp al, " " jne .options_incorrect jmp .next_option
.options_incorrect: mov [errors], dword OPTIONS_INCORRECT jmp .check_errors .options_correct:
; get format id by file extension mov esi, formats mov ecx, (formats.end - formats) / 4 mov edx, [extension] .find_format: lodsd mov eax, [eax] cmp [edx], eax je .format_found loop .find_format
.format_found: neg ecx add ecx, (formats.end - formats) / 4 inc ecx mov [format_id], ecx
; check if src path available mov [esp - (25 + 40) + 0], dword 5 mov [esp - (25 + 40) + 8], dword 0 mov [esp - (25 + 40) + 20], byte 0 lea eax, [esp - 40] mov [esp - (25 + 40) + 16], eax lea ebx, [esp - (25 + 40)] mov eax, [srcpath] mov [esp - (25 + 40) + 21], eax mov eax, 70 int 64 test eax, eax jz .src_available mov [errors], dword SRC_NOT_AVAILABLE jmp .check_errors .src_available: mov eax, [esp - (25 + 40) + 25 + 32] ; file.size test eax, eax jnz .src_not_empty mov [errors], dword SRC_IS_EMPTY jmp .check_errors .src_not_empty: push eax
; try to load libimg push sz_libimg call load.library test eax, eax jnz .libimg_loaded
.libimg_loaded: mov [libimg], eax mov ecx, eax mov ebx, getprocaddress push ecx push sz_img_decode call ebx mov [img_decode], eax push ecx push sz_img_destroy call ebx mov [img_destroy], eax push ecx push sz_img_encode call ebx mov [img_encode], eax push ecx push sz_img_scale call ebx mov [img_scale], eax push ecx push sz_img_convert call ebx mov [img_convert], eax push ecx push sz_img_flip call ebx mov [img_flip], eax push ecx push sz_img_rotate call ebx mov [img_rotate], eax push ecx push sz_lib_init call ebx push eax call dll.init
; if it loaded, open src image ; |----------------------------------- ;
pop ecx; file.size push ecx call memory.allocate test eax, eax jnz .allocated mov [errors], dword MEM_ALLOC_ERROR jmp .check_errors .allocated: mov edi, eax
push dword [srcpath] push eax push ecx call file.read test eax, eax jz .opened mov [errors], dword CANNOT_OPEN_SRC jmp .check_errors .opened: ; if it opened, try to decode ; |------------------------------------ ; push dword 0 push ecx push edi call [img_decode] test eax, eax jnz .decoded mov [errors], dword DECODE_ERROR jmp .check_errors .decoded: mov [src], eax
; if need flip then flip ; |----------------------------------------- ; cmp [flip], dword 0 je .flipped push dword [flip] push dword [src] call [img_flip] test eax, eax jnz .flipped mov [errors], dword FLIP_ERROR jmp .check_errors .flipped: ; if need rotate then rotate ; |------------------------------------- ; cmp [rotate], dword 0 je .rotated push dword [rotate] push dword [src] call [img_rotate] test eax, eax jnz .rotated mov [errors], dword ROTATE_ERROR jmp .check_errors .rotated: ; if need scale then scale ; |--------------------------------------- ; cmp [scale.height], dword 0 je .scaled cmp [scale.width], dword 0 je .scaled cmp [scale], byte "%" je .percent push dword [scale.height] push dword [scale.width] jmp .wh_pushed .percent: mov ecx, [src] mov ebx, 100 mov eax, [ecx + 8] mul dword [scale.height] div ebx push eax mov eax, [ecx + 4] mul dword [scale.width] div ebx push eax .wh_pushed: push dword LIBIMG_INTER_BILINEAR push dword LIBIMG_SCALE_STRETCH push dword 0 mov eax, [src] push dword [eax + 8] push dword [eax + 4] push dword 0 push dword 0 push dword [src] call [img_scale] mov [src], eax test eax, eax jnz .scaled lea eax, [(libimg_errors - errors) / 4 + ecx] mov [errors], eax jmp .check_errors .scaled: ; if need convert, try to convert; |--------------------------------- ; cmp [convert], dword 0 je .converted push dword 0 push dword [convert] push dword 0 push dword [src] call [img_convert] mov [src], eax test eax, eax jnz .converted lea eax, [(libimg_errors - errors) / 4 + ecx] mov [errors], eax jmp .check_errors .converted: ; try to encode ; |------------------------------------------------- ; push 0 push dword [format_id] push dword [src] call [img_encode] test eax, eax jnz .encoded lea eax, [(libimg_errors - errors) / 4 + ecx] mov [errors], eax;dword ENCODE_ERROR jmp .check_errors .encoded: ; if converted, try to save ; |-------------------------------------- ; push dword [dstpath] push eax push ecx call file.write test eax, eax jz .saved mov [errors], dword CANNOT_SAVE_DST jmp .check_errors .saved: ; if errors not occured, just exit .check_errors: mov eax, [errors] test eax, eax jz .just_exit ; else output error messages push sz_notify push dword [errors + eax*4] call file.run
.just_exit:
program.terminate: ; |-------------------------------------------- ; or eax, -1 int 64
; ------------------------------------------------------------- ; end_:
|
|