From 6537174613f683213c6d8302152e6d79515fdc86 Mon Sep 17 00:00:00 2001 From: Ivan Baravy Date: Mon, 2 May 2011 17:26:50 +0000 Subject: [PATCH] libimg: basic xcf support (reading) git-svn-id: svn://kolibrios.org@1921 a494cfbc-eb01-0410-851d-a64ba20cac60 --- .../libraries/libs-dev/libimg/libimg.asm | 2 + .../libraries/libs-dev/libimg/libimg.inc | 2 +- .../libraries/libs-dev/libimg/pcx/pcx.asm | 6 +- .../libs-dev/libimg/xcf/composite_mmx.inc | 828 +++++++++ .../libraries/libs-dev/libimg/xcf/xcf.asm | 1573 +++++++++++++++++ .../libraries/libs-dev/libimg/xcf/xcf.inc | 42 + 6 files changed, 2449 insertions(+), 4 deletions(-) create mode 100644 programs/develop/libraries/libs-dev/libimg/xcf/composite_mmx.inc create mode 100644 programs/develop/libraries/libs-dev/libimg/xcf/xcf.asm create mode 100644 programs/develop/libraries/libs-dev/libimg/xcf/xcf.inc diff --git a/programs/develop/libraries/libs-dev/libimg/libimg.asm b/programs/develop/libraries/libs-dev/libimg/libimg.asm index 5acc435630..012d174df6 100644 --- a/programs/develop/libraries/libs-dev/libimg/libimg.asm +++ b/programs/develop/libraries/libs-dev/libimg/libimg.asm @@ -39,6 +39,7 @@ include 'tga/tga.asm' include 'z80/z80.asm' include 'ico_cur/ico_cur.asm' include 'pcx/pcx.asm' +include 'xcf/xcf.asm' ;;================================================================================================;; proc lib_init ;///////////////////////////////////////////////////////////////////////////////////;; @@ -1997,6 +1998,7 @@ img._.formats_table: .jpg dd img.is.jpg, img.decode.jpg, img.encode.jpg .tga dd img.is.tga, img.decode.tga, img.encode.tga .pcx dd img.is.pcx, img.decode.pcx, img.encode.pcx + .xcf dd img.is.xcf, img.decode.xcf, img.encode.xcf .z80 dd img.is.z80, img.decode.z80, img.encode.z80 ;this must be the last entry as there are no ;signatures in z80 screens at all dd 0 diff --git a/programs/develop/libraries/libs-dev/libimg/libimg.inc b/programs/develop/libraries/libs-dev/libimg/libimg.inc index 248662cbc4..2e8b979ef6 100644 --- a/programs/develop/libraries/libs-dev/libimg/libimg.inc +++ b/programs/develop/libraries/libs-dev/libimg/libimg.inc @@ -32,7 +32,7 @@ struct Image Previous dd ? Type dd ? ; one of Image.bppN Data dd ? - Palette dd ? ; used iff Type eq Image.bpp8 + Palette dd ? ; used iff Type eq Image.bpp8 or Image.bpp1 Extended dd ? Flags dd ? ; bitfield Delay dd ? ; used iff Image.IsAnimated is set in Flags diff --git a/programs/develop/libraries/libs-dev/libimg/pcx/pcx.asm b/programs/develop/libraries/libs-dev/libimg/pcx/pcx.asm index 0230665981..29e7fff75a 100644 --- a/programs/develop/libraries/libs-dev/libimg/pcx/pcx.asm +++ b/programs/develop/libraries/libs-dev/libimg/pcx/pcx.asm @@ -23,7 +23,7 @@ include 'pcx.inc' ;;================================================================================================;; proc img.is.pcx _data, _length ;//////////////////////////////////////////////////////////////////;; ;;------------------------------------------------------------------------------------------------;; -;? Determine if raw data could be decoded (is in Targa format) ;; +;? Determine if raw data could be decoded (is in pcx format) ;; ;;------------------------------------------------------------------------------------------------;; ;> _data = raw data as read from file/stream ;; ;> _length = data length ;; @@ -65,7 +65,7 @@ endp ;;================================================================================================;; proc img.decode.pcx _data, _length, _options ;////////////////////////////////////////////////////;; ;;------------------------------------------------------------------------------------------------;; -;? Decode data into image if it contains correctly formed raw data in Targa format ;; +;? Decode data into image if it contains correctly formed raw data in pcx format ;; ;;------------------------------------------------------------------------------------------------;; ;> _data = raw data as read from file/stream ;; ;> _length = data length ;; @@ -290,7 +290,7 @@ endp ;;================================================================================================;; proc img.encode.pcx _img, _p_length, _options ;///////////////////////////////////////////////////;; ;;------------------------------------------------------------------------------------------------;; -;? Encode image into raw data in Targa format ;; +;? Encode image into raw data in pcx format ;; ;;------------------------------------------------------------------------------------------------;; ;> _img = pointer to image ;; ;;------------------------------------------------------------------------------------------------;; diff --git a/programs/develop/libraries/libs-dev/libimg/xcf/composite_mmx.inc b/programs/develop/libraries/libs-dev/libimg/xcf/composite_mmx.inc new file mode 100644 index 0000000000..57284ad032 --- /dev/null +++ b/programs/develop/libraries/libs-dev/libimg/xcf/composite_mmx.inc @@ -0,0 +1,828 @@ +proc blend_rgb + + xchg al, bh + mov ah, bh + neg ax + add ax, 0xffff + mul ah + neg ah + add ah, 0xff + xchg ah, bh + + mov al, 0xff + cmp ah, bh + je @f + not al + div bh +@@: + + mov ah, al + movd mm1, eax +; pxor mm0, mm0 ; already xor'ed in composite function + punpcklbw mm1, mm1 + punpcklbw mm1, mm0 +; punpcklbw mm3, mm0 + + movq mm7, mm1 + psrlw mm7, 7 + paddw mm1, mm7 + + psubw mm3, mm2 + pmullw mm3, mm1 + psllw mm2, 8 + paddw mm3, mm2 + pinsrw mm3, ebx, 3 + psrlw mm3, 8 + packuswb mm3, mm0 + movd eax, mm3 + + ret +endp + + +proc blend_gray + + xchg al, bh + mov ah, bh + neg ax + add ax, 0xffff + mul ah + neg ah + add ah, 0xff + xchg ah, bh + + mov al, 0xff + cmp ah, bh + je @f + not al + div bh +@@: + + mov ah, al + movd mm1, eax +; pxor mm0, mm0 ; already xor'ed in composite function + punpcklbw mm1, mm1 + punpcklbw mm1, mm0 +; punpcklbw mm3, mm0 + + movq mm7, mm1 + psrlw mm7, 7 + paddw mm1, mm7 + + psubw mm3, mm2 + pmullw mm3, mm1 + psllw mm2, 8 + paddw mm3, mm2 + pinsrw mm3, ebx, 1 + psrlw mm3, 8 + packuswb mm3, mm0 + movd eax, mm3 + + ret +endp + + +proc merge_32 _copy_width, _copy_height, _img_total_bpl, _bottom_total_bpl +.rgb_line: + mov ecx, [_copy_width] +.rgb_pixel: + mov ebx, [edi] + lodsd + + movd mm2, ebx + movd mm3, eax + shr eax, 24 + shr ebx, 16 + cmp al, bh + jna @f + mov al, bh +@@: pxor mm0, mm0 + call edx + call blend_rgb + stosd + dec ecx + jnz .rgb_pixel + add esi, [_img_total_bpl] + add edi, [_bottom_total_bpl] + dec [_copy_height] + jnz .rgb_line + emms + ret +endp + + +proc merge_8a _copy_width, _copy_height, _img_total_bpl, _bottom_total_bpl +.gray_line: + mov ecx, [_copy_width] +.gray_pixel: + mov bx, word[edi] + lodsw + movd mm2, ebx + movd mm3, eax + shr eax, 8 + cmp al, bh + jna @f + mov al, bh +@@: pxor mm0, mm0 + call edx + call blend_gray + stosw + dec ecx + jnz .gray_pixel + add esi, [_img_total_bpl] + add edi, [_bottom_total_bpl] + dec [_copy_height] + jnz .gray_line + emms + ret +endp + + +proc composite_rgb_00 _copy_width, _copy_height, _bottom_total_bpl, _img_total_bpl + +.line: mov ecx, [_copy_width] +.pixel: mov ebx, [edi] + lodsd + movd mm2, ebx + movd mm3, eax + + shr eax, 24 + shr ebx, 16 + + xchg al, bh + mov ah, bh + neg ax + add ax, 0xffff + mul ah + neg ah + add ah, 0xff + xchg ah, bh + + mov al, 0xff + cmp ah, bh + je @f + not al + div bh +@@: + + mov ah, al + movd mm1, eax + pxor mm0, mm0 + punpcklbw mm1, mm1 + punpcklbw mm1, mm0 + punpcklbw mm2, mm0 + punpcklbw mm3, mm0 + + psubsw mm3, mm2 + pmullw mm3, mm1 + psllw mm2, 8 + paddw mm3, mm2 + pinsrw mm3, ebx, 3 + psrlw mm3, 8 + packuswb mm3, mm0 + movd eax, mm3 + stosd + + dec ecx + jnz .pixel + add esi, [_img_total_bpl] + add edi, [_bottom_total_bpl] + dec [_copy_height] + jnz .line + + ret +endp + + +proc composite_gray_00 _copy_width, _copy_height, _bottom_total_bpl, _img_total_bpl + +.line: mov ecx, [_copy_width] +.pixel: mov bx, [edi] + lodsw + movd mm2, ebx + movd mm3, eax + + shr eax, 8 + + xchg al, bh + mov ah, bh + neg ax + add ax, 0xffff + mul ah + neg ah + add ah, 0xff + xchg ah, bh + + mov al, 0xff + cmp ah, bh + je @f + not al + div bh +@@: + + mov ah, al + movd mm1, eax + pxor mm0, mm0 + punpcklbw mm1, mm1 + punpcklbw mm1, mm0 + punpcklbw mm2, mm0 + punpcklbw mm3, mm0 + + psubw mm3, mm2 + pmullw mm3, mm1 + psllw mm2, 8 + paddw mm3, mm2 + pinsrw mm3, ebx, 1 + psrlw mm3, 8 + packuswb mm3, mm0 + movd eax, mm3 + stosw + + dec ecx + jnz .pixel + add esi, [_img_total_bpl] + add edi, [_bottom_total_bpl] + dec [_copy_height] + jnz .line + + ret +endp + + +proc composite_indexed_00 _copy_width, _copy_height, _bottom_total_bpl, _img_total_bpl + +.line: mov ecx, [_copy_width] +.pixel: mov bx, [edi] + lodsw + + or ah, 0x7f + test ah, 0x80 + jnz @f + mov ax, bx +@@: stosw + + dec ecx + jnz .pixel + add esi, [_img_total_bpl] + add edi, [_bottom_total_bpl] + dec [_copy_height] + jnz .line + ret +endp + + +proc composite_rgb_01 _copy_width, _copy_height, _bottom_total_bpl, _img_total_bpl + pushad + + pxor mm4, mm4 + movd mm4, [random_b] + movd mm1, [random_a] + movd mm2, [random_c] + +.line: mov ecx, [_copy_width] +.pixel: mov ebx, [edi] + lodsd + + movq mm0, mm4 + pmuludq mm0, mm1 + paddq mm0, mm2 + movd edx, mm0 + movd mm4, edx + pxor mm0, mm0 + + rol eax, 8 + test al, al + jz @f + shr edx, 17 + cmp dl, al + ja @f + ror eax, 8 + or eax, 0xff000000 + jmp .done +@@: mov eax, ebx +.done: stosd + dec ecx + jnz .pixel + add esi, [_img_total_bpl] + add edi, [_bottom_total_bpl] + dec [_copy_height] + jnz .line + +.quit: popad + ret +endp + + +proc composite_gray_01 _copy_width, _copy_height, _bottom_total_bpl, _img_total_bpl + pushad + + pxor mm4, mm4 + movd mm4, [random_b] + movd mm1, [random_a] + movd mm2, [random_c] + +.line: mov ecx, [_copy_width] +.pixel: mov ebx, [edi] + lodsw + + movq mm0, mm4 + pmuludq mm0, mm1 + paddq mm0, mm2 + movd edx, mm0 + movd mm4, edx + pxor mm0, mm0 + + test ah, ah + jz @f + shr edx, 17 + cmp dl, ah + ja @f + or ax, 0xff00 + jmp .done +@@: mov eax, ebx +.done: stosw + dec ecx + jnz .pixel + add esi, [_img_total_bpl] + add edi, [_bottom_total_bpl] + dec [_copy_height] + jnz .line + +.quit: popad + ret +endp + + +;proc composite_indexed_01 _copy_width, _copy_height, _bottom_total_bpl, _img_total_bpl +; pushad +; +; pxor mm4, mm4 +; movd mm4, [random_b] +; movd mm1, [random_a] +; movd mm2, [random_c] +; +;.line: mov ecx, [_copy_width] +;.pixel: mov ebx, [edi] +; lodsw +; +; movq mm0, mm4 +; pmuludq mm0, mm1 +; paddq mm0, mm2 +; movd edx, mm0 +; movd mm4, edx +; pxor mm0, mm0 +; +; test ah, ah +; jz @f +; shr edx, 17 +; cmp dl, ah +; ja @f +; or ax, 0xff00 +; jmp .done +;@@: mov eax, ebx +;.done: stosw +; dec ecx +; jnz .pixel +; add esi, [_img_total_bpl] +; add edi, [_bottom_total_bpl] +; dec [_copy_height] +; jnz .line +; +;.quit: popad +; ret +;endp + + +proc composite_rgb_03 ; Multiply + + punpcklbw mm2, mm0 + punpcklbw mm3, mm0 + pmullw mm3, mm2 + psrlw mm3, 8 + + ret +endp + + +proc composite_rgb_04 ; Screen + + punpcklbw mm2, mm0 + punpcklbw mm3, mm0 + movq mm4, [mmx_00ff] + movq mm5, mm4 + psubw mm4, mm2 + psubw mm5, mm3 + pmullw mm4, mm5 + psrlw mm4, 8 + movq mm3, [mmx_00ff] + psubw mm3, mm4 + + ret +endp + + +proc composite_rgb_05 ; Overlay + + punpcklbw mm2, mm0 + punpcklbw mm3, mm0 + movq mm4, [mmx_00ff] + psubw mm4, mm2 + pmullw mm3, mm4 + psrlw mm3, 7 + paddw mm3, mm2 + pmullw mm3, mm2 + psrlw mm3, 8 + + ret +endp + + +proc composite_rgb_06 ; Difference + + movq mm4, mm3 + pminub mm4, mm2 + pmaxub mm3, mm2 + psubusb mm3, mm4 + punpcklbw mm2, mm0 + punpcklbw mm3, mm0 + + ret +endp + + +proc composite_rgb_07 ; Addition + + paddusb mm3, mm2 + punpcklbw mm2, mm0 + punpcklbw mm3, mm0 + + ret +endp + + +proc composite_rgb_08 ; Subtract + + movq mm4, mm2 + psubusb mm4, mm3 + movq mm3, mm4 + punpcklbw mm2, mm0 + punpcklbw mm3, mm0 + + ret +endp + + +proc composite_rgb_09 ; Darken Only + + pminub mm3, mm2 + punpcklbw mm2, mm0 + punpcklbw mm3, mm0 + + ret +endp + + +proc composite_rgb_10 ; Lighten Only + + pmaxub mm3, mm2 + punpcklbw mm2, mm0 + punpcklbw mm3, mm0 + + ret +endp + + +proc composite_rgb_11 ; Hue (H of HSV) + push eax ebx ecx edx + + movd eax, mm3 + movd ebx, mm2 + + call pixel_rgb2hsv + xchg eax, ebx + call pixel_rgb2hsv + xchg eax, ebx + + test ah, ah + jnz @f + ror eax, 8 + ror ebx, 8 + mov ah, bh + rol eax, 8 + rol ebx, 8 +@@: + mov ax, bx + + call pixel_hsv2rgb + + + movd mm3, eax + + punpcklbw mm2, mm0 + punpcklbw mm3, mm0 + +.quit: + pop edx ecx ebx eax + ret +endp + + +proc composite_rgb_12 ; Saturation (S of HSV) + push eax ebx ecx edx + + movd eax, mm3 + movd ebx, mm2 + + call pixel_rgb2hsv + xchg eax, ebx + call pixel_rgb2hsv + xchg eax, ebx + + ror eax, 8 + ror ebx, 8 + mov ah, bh + rol eax, 8 + rol ebx, 8 + mov al, bl + + call pixel_hsv2rgb + + + movd mm3, eax + + punpcklbw mm2, mm0 + punpcklbw mm3, mm0 + +.quit: + pop edx ecx ebx eax + ret +endp + + +proc composite_rgb_13 ; Color (H and S of HSL) + push eax ebx ecx edx + + movd eax, mm3 + movd ebx, mm2 + + call pixel_rgb2hsl + xchg eax, ebx + call pixel_rgb2hsl + xchg eax, ebx + + mov al, bl + + call pixel_hsl2rgb + + + movd mm3, eax + + punpcklbw mm2, mm0 + punpcklbw mm3, mm0 + +.quit: + pop edx ecx ebx eax + ret +endp + + +proc composite_rgb_14 ; Value (V of HSV) + push eax ebx ecx edx + + movd eax, mm3 + movd ebx, mm2 + + call pixel_rgb2hsv + xchg eax, ebx + call pixel_rgb2hsv + xchg eax, ebx + + ror eax, 8 + ror ebx, 8 + mov ax, bx + rol eax, 8 + rol ebx, 8 + + call pixel_hsv2rgb + + + movd mm3, eax + + punpcklbw mm2, mm0 + punpcklbw mm3, mm0 + +.quit: + pop edx ecx ebx eax + ret +endp + + +proc composite_rgb_15 ; Divide + push eax ebx ecx + + movd eax, mm3 + movd ebx, mm2 + + rol eax, 8 + rol ebx, 8 + + xchg eax, ebx + + mov ecx, 3 + +.color: rol eax, 8 + rol ebx, 8 + shl ax, 8 + test bl, bl + jz .clamp1 + cmp ah, bl + jae .clamp2 + div bl + jmp .done +.clamp1:mov al, 0xff + test ah, ah + jnz @f + not al +@@: jmp .done +.clamp2:mov al, 0xff + jmp .done +.done: mov ah, al + loop .color + + ror eax, 8 + movd mm3, eax + + punpcklbw mm2, mm0 + punpcklbw mm3, mm0 + + pop ecx ebx eax + ret +endp + + +proc composite_rgb_16 ; Dodge + push eax ebx ecx + + movd eax, mm3 + movd ebx, mm2 + + rol eax, 8 + rol ebx, 8 + + xchg eax, ebx + + mov ecx, 3 + +.color: rol eax, 8 + rol ebx, 8 + shl ax, 8 + neg bl + add bl, 0xff + test bl, bl + jz .clamp1 + cmp ah, bl + jae .clamp2 + div bl + jmp .done +.clamp1:mov al, 0xff + test ah, ah + jnz @f + not al +@@: jmp .done +.clamp2:mov al, 0xff + jmp .done +.done: mov ah, al + loop .color + + ror eax, 8 + movd mm3, eax + + punpcklbw mm2, mm0 + punpcklbw mm3, mm0 + + pop ecx ebx eax + ret +endp + + +proc composite_rgb_17 ; Burn + push eax ebx ecx + + movd eax, mm3 + movd ebx, mm2 + + rol eax, 8 + rol ebx, 8 + + xchg eax, ebx + + mov ecx, 3 + +.color: rol eax, 8 + rol ebx, 8 + shl ax, 8 + neg ah + add ah, 0xff + test bl, bl + jz .clamp1 + cmp ah, bl + jae .clamp2 + div bl + jmp .done +.clamp1:mov al, 0xff + test ah, ah + jnz @f + not al +@@: jmp .done +.clamp2:mov al, 0xff + jmp .done +.done: mov ah, al + neg ah + add ah, 0xff + loop .color + + ror eax, 8 + movd mm3, eax + + punpcklbw mm2, mm0 + punpcklbw mm3, mm0 + + pop ecx ebx eax + ret +endp + + +proc composite_rgb_18 ; Hard Light + push eax ebx ecx + + movd eax, mm3 + movd ebx, mm2 + + rol eax, 8 + rol ebx, 8 + + mov ecx, 3 + +.color: rol eax, 8 + rol ebx, 8 + cmp al, 127 + jna .part1 + mov ah, 0xff + sub ah, bl + neg al + add al, 0xff + mul ah + shl ax, 1 + neg ah + add ah, 0xff + jmp .done +.part1: + mul bl + shl ax, 1 +.done: loop .color + + ror eax, 8 + movd mm3, eax + + punpcklbw mm2, mm0 + punpcklbw mm3, mm0 + + pop ecx ebx eax + ret +endp + + +proc composite_rgb_20 ; Grain Extract + + movq mm4, [mmx_0080] + punpcklbw mm2, mm0 + punpcklbw mm3, mm0 + movq mm5, mm2 + psubw mm3, mm4 + psubsw mm5, mm3 + packuswb mm5, mm0 + punpcklbw mm5, mm0 + movq mm3, mm5 + + ret +endp + + +proc composite_rgb_21 ; Grain Merge + + movq mm4, [mmx_0080] + punpcklbw mm2, mm0 + punpcklbw mm3, mm0 + movq mm5, mm2 + psubw mm5, mm4 + paddsw mm3, mm5 + packuswb mm3, mm0 + punpcklbw mm3, mm0 + + ret +endp + + +mmx_0080 dq 0x0080008000800080 +mmx_00ff dq 0x00ff00ff00ff00ff +mmx_0100 dq 0x0100010001000100 \ No newline at end of file diff --git a/programs/develop/libraries/libs-dev/libimg/xcf/xcf.asm b/programs/develop/libraries/libs-dev/libimg/xcf/xcf.asm new file mode 100644 index 0000000000..d88fb12136 --- /dev/null +++ b/programs/develop/libraries/libs-dev/libimg/xcf/xcf.asm @@ -0,0 +1,1573 @@ +;;================================================================================================;; +;;//// xcf.asm //// (c) dunkaist, 2011 ///////////////////////////////////////////////////////////;; +;;================================================================================================;; +;; ;; +;; This file is part of Common development libraries (Libs-Dev). ;; +;; ;; +;; Libs-Dev is free software: you can redistribute it and/or modify it under the terms of the GNU ;; +;; Lesser General Public License as published by the Free Software Foundation, either version 2.1 ;; +;; of the License, or (at your option) any later version. ;; +;; ;; +;; Libs-Dev is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without ;; +;; even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;; +;; Lesser General Public License for more details. ;; +;; ;; +;; You should have received a copy of the GNU Lesser General Public License along with Libs-Dev. ;; +;; If not, see . ;; +;; ;; +;;================================================================================================;; +;; ;; +;; References: ;; +;; 1. "SPECIFICATION OF THE XCF FILE FORMAT" ;; +;; by Henning Makholm ;; +;; http://svn.gnome.org/viewvc/gimp/trunk/devel-docs/xcf.txt?view=markup ;; +;; 2. "Layer Modes" ;; +;; from docs.gimp.org ;; +;; http://docs.gimp.org/en/gimp-concepts-layer-modes.html ;; +;; ;; +;;================================================================================================;; +include 'xcf.inc' +;include '../../../../system/board/trunk/debug.inc' + +COMPOSITE_MODE equ MMX + +MAX_LAYERS equ 255 + +DEBUG_STANDARD equ TRUE +DEBUG_FBOUNDS equ FALSE + +;;================================================================================================;; +proc img.is.xcf _data, _length ;//////////////////////////////////////////////////////////////////;; +;;------------------------------------------------------------------------------------------------;; +;? Determine if raw data could be decoded (is in xcf format) ;; +;;------------------------------------------------------------------------------------------------;; +;> _data = raw data as read from file/stream ;; +;> _length = data length ;; +;;------------------------------------------------------------------------------------------------;; +;< eax = false / true ;; +;;================================================================================================;; + + push edi + xor eax, eax + + mov edi, [_data] + + cmp dword[edi+xcf_header.magic_string], 'gimp' + jne .is_not_xcf + cmp dword[edi+xcf_header.magic_string+4], ' xcf' + jne .is_not_xcf + + cmp [edi+xcf_header.version], 'file' + je @f + cmp [edi+xcf_header.version], 'v001' + je @f + cmp [edi+xcf_header.version], 'v002' + je @f + jmp .is_not_xcf +@@: + + cmp byte[edi+xcf_header.reserved], 0 + jne .is_not_xcf + +.is_xcf: + inc eax + +.is_not_xcf: + pop edi + ret + +endp + +;;================================================================================================;; +proc img.decode.xcf _data, _length, _options ;////////////////////////////////////////////////////;; +;;------------------------------------------------------------------------------------------------;; +;? Decode data into image if it contains correctly formed raw data in xcf format ;; +;;------------------------------------------------------------------------------------------------;; +;> _data = raw data as read from file/stream ;; +;> _length = data length ;; +;;------------------------------------------------------------------------------------------------;; +;< eax = 0 (error) or pointer to image ;; +;;================================================================================================;; +locals +count rd 1 +retvalue rd 1 ; 0 (error) or pointer to image +endl + + push ebx esi edi + + mov esi, [_data] + add esi, xcf_header.width + + lodsd + bswap eax + mov ebx, eax + lodsd + bswap eax + mov edx, eax + + lodsd + bswap eax + test eax, eax + jz .process_rgb + dec eax + jz .process_grayscale + dec eax + jz .process_indexed + jmp .error + + +.process_rgb: + + stdcall img.create, ebx, edx, Image.bpp32 + mov [retvalue], eax + test eax, eax + jz .error + + mov ebx, eax + + mov edx, XCF_BASETYPE_RGB + + jmp .common_process + +.process_grayscale: + + stdcall img.create, ebx, edx, Image.bpp8 + mov [retvalue], eax + test eax, eax + jz .error + + mov ebx, eax + + mov eax, [ebx + Image.Width] + imul [ebx + Image.Height] + shl eax, 1 + mov [ebx+Image.Palette], eax + add eax, 256*4 + invoke mem.realloc, [ebx + Image.Data], eax + mov [ebx + Image.Data], eax + add [ebx + Image.Palette], eax + + mov edi, [ebx+Image.Palette] + mov eax, 0xff000000 +@@: stosd + add eax, 0x00010101 + jnc @b + + mov edx, XCF_BASETYPE_GRAY + + jmp .common_process + + +.process_indexed: + + stdcall img.create, ebx, edx, Image.bpp8 + mov [retvalue], eax + test eax, eax + jz .error + + mov ebx, eax + + mov eax, [ebx + Image.Width] + imul [ebx + Image.Height] + shl eax, 1 + mov [ebx+Image.Palette], eax + add eax, 256*4 + invoke mem.realloc, [ebx + Image.Data], eax + mov [ebx + Image.Data], eax + add [ebx + Image.Palette], eax + + mov edx, XCF_BASETYPE_INDEXED +; jmp .common_process + +.common_process: + + invoke mem.alloc, sizeof.xcf_ext + or eax, eax + jz .error + mov [ebx+Image.Extended], eax + mov [eax+xcf_ext.opacity], 0xffffffff + mov [eax+xcf_ext.type], edx + + stdcall parse_properties, ebx + + mov edi, esi + mov eax, 0 + mov ecx, MAX_LAYERS + mov [count], MAX_LAYERS-1 + repne scasd + sub [count], ecx + mov esi, edi + mov ecx, 0 + +.still: sub esi, 8 + lodsd + bswap eax + + push ecx + stdcall decode_layer, eax, [_data] + pop ecx + test eax, eax + jz @f + push ecx + stdcall merge_down, eax, [retvalue], ecx + pop ecx + add ecx, 1 +@@: dec [count] + jnz .still +; jmp .quit + + + cmp [ebx+Image.Type], Image.bpp8 + jne .quit + stdcall pack_8a, ebx + jmp .quit + +.error: mov [retvalue], 0 +.quit: pop edi esi ebx + mov eax, [retvalue] + ret +endp + + + +;;================================================================================================;; +proc img.encode.xcf _img, _p_length, _options ;///////////////////////////////////////////////////;; +;;------------------------------------------------------------------------------------------------;; +;? Encode image into raw data in xcf format ;; +;;------------------------------------------------------------------------------------------------;; +;> _img = pointer to image ;; +;;------------------------------------------------------------------------------------------------;; +;< eax = 0 (error) or pointer to encoded data ;; +;< _p_length = encoded data length ;; +;;================================================================================================;; + xor eax, eax + ret +endp + + +;;================================================================================================;; +;;////////////////////////////////////////////////////////////////////////////////////////////////;; +;;================================================================================================;; +;! Below are private procs you should never call directly from your code ;; +;;================================================================================================;; +;;////////////////////////////////////////////////////////////////////////////////////////////////;; +;;================================================================================================;; +proc parse_properties _img + + mov ebx, [_img] +.begin: + lodsd + bswap eax + + mov ecx, (xcf_prop_table_end-xcf_prop_table_begin)/8 + mov edi, xcf_prop_table_begin + +.still: + cmp eax, [edi] + jne @f + jmp dword[edi+4] +@@: + add edi, 8 + dec ecx + jnz .still + lodsd ; skip + bswap eax ; uninteresting + add esi, eax ; property + jmp .begin + +parse_prop_00: ; PROP_END + lodsd + ret + +parse_prop_01: ; PROP_COLORMAP + lodsd + mov ecx, [ebx+Image.Extended] + cmp [ecx+xcf_ext.type], XCF_BASETYPE_INDEXED + je @f + bswap eax + add esi, eax + jmp parse_properties.begin +@@: + lodsd + bswap eax + mov ecx, eax + mov edi, [ebx+Image.Palette] + +@@: lodsd + sub esi, 1 + bswap eax + shr eax, 8 + or eax, 0xff000000 + stosd + dec ecx + jnz @b + jmp parse_properties.begin + +parse_prop_06: ; PROP_OPACITY + lodsd + lodsd + bswap eax + mov ecx, [ebx+Image.Extended] + mov [ecx+xcf_ext.opacity], eax + jmp parse_properties.begin + +parse_prop_07: ; PROP_MODE + lodsd + lodsd + bswap eax + mov ecx, [ebx+Image.Extended] + mov [ecx+xcf_ext.layer_mode], eax + jmp parse_properties.begin + +parse_prop_08: ; PROP_VISIBLE + lodsd + lodsd + bswap eax + mov ecx, [ebx+Image.Extended] + mov [ecx+xcf_ext.visible], eax + jmp parse_properties.begin + +parse_prop_11: ; PROP_APPLY_MASK + lodsd + lodsd + bswap eax + mov ecx, [ebx+Image.Extended] + mov [ecx+xcf_ext.apply_mask], eax + jmp parse_properties.begin + +parse_prop_15: ; PROP_OFFSETS + lodsd + lodsd + mov ecx, [ebx+Image.Extended] + bswap eax + mov [ecx+xcf_ext.offset_x], eax + lodsd + bswap eax + mov [ecx+xcf_ext.offset_y], eax + jmp parse_properties.begin +endp + + +proc decode_channel _channel_begin, _data +locals +channel_width rd 1 +channel_height rd 1 +planes_todo rd 1 +total_bpl rd 1 +endl + + push ebx esi edi + mov esi, [_channel_begin] + add esi, [_data] + lodsd + bswap eax + mov [channel_width], eax + mov [total_bpl], eax + lodsd + bswap eax + mov [channel_height], eax + lodsd + bswap eax + add esi, eax + + stdcall img.create, [channel_width], [channel_height], Image.bpp8 + mov ebx, eax + test ebx, ebx + jz .quit + invoke mem.alloc, sizeof.xcf_ext + or eax, eax + jz .error + mov [ebx+Image.Extended], eax + + stdcall parse_properties, ebx + + lodsd + bswap eax + mov esi, eax + add esi, [_data] + lodsd + lodsd + lodsd + bswap eax + mov [planes_todo], eax + lodsd + bswap eax + mov esi, eax + add esi, [_data] + lodsd + lodsd + + mov edi, [ebx+Image.Data] + mov ecx, 0 +@@: lodsd + test eax, eax + jz .quit + bswap eax + add eax, [_data] + stdcall decode_tile, eax, [channel_width], [channel_height], [total_bpl], [planes_todo], 1 + add ecx, 1 + jmp @b + +.error: stdcall img.destroy, ebx + mov ebx, 0 +.quit: mov eax, ebx + pop edi esi ebx + ret +endp + + +proc decode_layer _layer_begin, _data +locals +layer_width rd 1 +layer_height rd 1 +planes_todo rd 1 +total_bpl rd 1 +color_step rd 1 +endl + + push ebx esi edi + mov esi, [_layer_begin] + add esi, [_data] + lodsd + bswap eax + mov [layer_width], eax + mov [total_bpl], eax + shl [total_bpl], 1 + lodsd + bswap eax + mov [layer_height], eax + lodsd + bswap eax + mov edx, Image.bpp16 + mov [color_step], 1 + cmp eax, 2 + jge @f + mov [color_step], 3 + mov edx, Image.bpp32 + shl [total_bpl], 1 +@@: stdcall img.create, [layer_width], [layer_height], edx + mov ebx, eax + test ebx, ebx + jz .quit + invoke mem.alloc, sizeof.xcf_ext + or eax, eax + jz .error + mov [ebx+Image.Extended], eax + + lodsd + bswap eax + add esi, eax + stdcall parse_properties, ebx + mov edx, [ebx+Image.Extended] + or [edx+xcf_ext.visible], 0 + jz .unvisible + + lodsd + bswap eax + push esi + mov esi, eax + add esi, [_data] + lodsd + lodsd + lodsd + bswap eax + mov [planes_todo], eax +; mov ecx, [ebx+Image.Extended] +; mov [ecx+xcf_ext.planes], eax + lodsd + bswap eax + mov esi, eax + add esi, [_data] + lodsd + lodsd + + mov edi, [ebx+Image.Data] + mov ecx, 0 +@@: lodsd + test eax, eax + jz @f + bswap eax + add eax, [_data] + stdcall decode_tile, eax, [layer_width], [layer_height], [total_bpl], [planes_todo], 0 + add ecx, 1 + jmp @b +@@: + + stdcall apply_opacity, ebx, [color_step] + + pop esi + lodsd + bswap eax + test eax, eax + jz .quit + + stdcall decode_channel, eax, [_data] + test eax, eax + jz .error + + mov edx, [ebx+Image.Extended] + cmp [edx+xcf_ext.apply_mask], 0 + je .quit + + stdcall apply_alpha_mask, ebx, eax, [color_step] + jmp .quit + +.unvisible: +.error: stdcall img.destroy, ebx + mov ebx, 0 +.quit: mov eax, ebx + pop edi esi ebx + ret +endp + + +proc decode_tile _tile_data, _width, _height, _total_bpl, _bytes_pp, _is_channel +locals +tile_x rd 1 +tile_y rd 1 +tile_width rd 1 +tile_height rd 1 +planes_todo rd 1 +color_step rd 1 +endl + + push ebx ecx edx esi edi + pushd [_bytes_pp] + popd [planes_todo] + + cmp [_is_channel], 1 + je @f + test [_bytes_pp], 0x01 + jz @f + add [_bytes_pp], 1 +@@: + mov ebx, [_bytes_pp] + sub ebx, 1 + mov [color_step], ebx + + mov esi, [_tile_data] + mov eax, ecx + mov ebx, [_width] + dec ebx + shr ebx, 6 + inc ebx + mov edx, 0 + div bx + mov [tile_x], edx + mov [tile_y], eax + + mov [tile_width], 64 + mov ebx, [_width] + test ebx, 0x0000003F + jz @f + dec ebx + shr ebx, 6 + cmp ebx, [tile_x] + jne @f + mov ebx, [_width] + and ebx, 0x0000003F + mov [tile_width], ebx +@@: + + mov [tile_height], 64 + mov ebx, [_height] + test ebx, 0x0000003F + jz @f + dec ebx + shr ebx, 6 + cmp ebx, [tile_y] + jne @f + mov ebx, [_height] + and ebx, 0x0000003F + mov [tile_height], ebx +@@: + + + mov eax, [_total_bpl] + shl eax, 6 + mul [tile_y] + add edi, eax + + mov eax, [tile_x] + shl eax, 6 + imul eax, [_bytes_pp] + add edi, eax + + cmp [_is_channel], 1 + jne @f + stdcall decode_color, [tile_width], [tile_height], [color_step], [_total_bpl], [_bytes_pp] + jmp .quit +@@: + mov eax, [planes_todo] + dec eax + jz .p1 + dec eax + jz .p2 + dec eax + jz .p3 + jmp .p4 +.p1: + stdcall decode_color, [tile_width], [tile_height], [color_step], [_total_bpl], [_bytes_pp] + add edi, 1 + stdcall fill_color, [tile_width], [tile_height], [_total_bpl], [_bytes_pp], [color_step] + jmp .quit +.p2: + stdcall decode_color, [tile_width], [tile_height], [color_step], [_total_bpl], [_bytes_pp] + add edi, 1 + stdcall decode_color, [tile_width], [tile_height], [color_step], [_total_bpl], [_bytes_pp] + jmp .quit +.p3: + add edi, 2 + stdcall decode_color, [tile_width], [tile_height], [color_step], [_total_bpl], [_bytes_pp] + sub edi, 1 + stdcall decode_color, [tile_width], [tile_height], [color_step], [_total_bpl], [_bytes_pp] + sub edi, 1 + stdcall decode_color, [tile_width], [tile_height], [color_step], [_total_bpl], [_bytes_pp] + add edi, 3 + stdcall fill_color, [tile_width], [tile_height], [_total_bpl], [_bytes_pp], [color_step] + jmp .quit +.p4: + add edi, 2 + stdcall decode_color, [tile_width], [tile_height], [color_step], [_total_bpl], [_bytes_pp] + sub edi, 1 + stdcall decode_color, [tile_width], [tile_height], [color_step], [_total_bpl], [_bytes_pp] + sub edi, 1 + stdcall decode_color, [tile_width], [tile_height], [color_step], [_total_bpl], [_bytes_pp] + add edi, 3 + stdcall decode_color, [tile_width], [tile_height], [color_step], [_total_bpl], [_bytes_pp] +; jmp .quit + +.quit: pop edi esi edx ecx ebx + ret +endp + + +proc fill_color _tile_width, _tile_height, _total_bpl, _bytes_pp, _color_step + push ebx + mov edx, [_color_step] + mov ebx, [_total_bpl] + mov eax, [_bytes_pp] + mul byte[_tile_width] + sub ebx, eax + + mov ch, byte[_tile_height] + mov al, 0xff +.still: mov cl, byte[_tile_width] +@@: stosb + add edi, edx + dec cl + jnz @b + add edi, ebx + dec ch + jnz .still + pop ebx + ret +endp + + +proc decode_color _tile_width, _tile_height, _color_step, _total_bpl, _bytes_pp +locals +level_width rd 1 +level_height rd 1 +line_step rd 1 ; [_total_bpl]-[_tile_width]*[_bytes_pp] +endl + + push edi + + mov ebx, [_total_bpl] + movzx eax, byte[_bytes_pp] + mul byte[_tile_width] + sub ebx, eax + mov [line_step], ebx + mov ebx, [_tile_height] + mov edx, [_tile_width] + +.decode:lodsb + cmp al, 127 + je .long_identical + jb .short_identical + test al, 0x7f + jz .long_different + jmp .short_different + +.short_identical: + movzx ecx, al + add ecx, 1 + lodsb + jmp .step1 +.long_identical: + mov ecx, 0 + lodsw + mov cx, ax + xchg cl, ch + lodsb +.step1: cmp cx, dx + je .step2 + jl .step3 + xchg cx, dx + sub dx, cx + sub bx, 1 +@@: stosb + add edi, [_color_step] + loop @b + mov cx, dx + mov edx, [_tile_width] + add edi, [line_step] + jmp .step1 + +.step2: +@@: stosb + add edi, [_color_step] + loop @b + mov edx, [_tile_width] + add edi, [line_step] + dec bx + jz .quit + jmp .decode +.step3: sub dx, cx +@@: stosb + add edi, [_color_step] + loop @b + jmp .decode + + +.short_different: + movzx ecx, al + neg cx + add cx, 256 + jmp .step4 +.long_different: + mov ecx, 0 + lodsb + mov ch, al + lodsb + mov cl, al +.step4: cmp cx, dx + je .step5 + jl .step6 + xchg cx, dx + sub dx, cx + sub bx, 1 +@@: movsb + add edi, [_color_step] + loop @b + mov cx, dx + mov edx, [_tile_width] + add edi, [line_step] + jmp .step4 + +.step5: +@@: movsb + add edi, [_color_step] + loop @b + mov edx, [_tile_width] + add edi, [line_step] + dec bx + jz .quit + jmp .decode + +.step6: sub dx, cx +@@: movsb + add edi, [_color_step] + loop @b + jmp .decode + +.quit: pop edi + ret +endp + + +proc merge_down _img, _bottom, _layer_number +locals +copy_width rd 1 +copy_height rd 1 +img_x1 rd 1 +img_y1 rd 1 +bottom_x1 rd 1 +bottom_y1 rd 1 +img_total_bpl rd 1 +bottom_total_bpl rd 1 +img_length rd 1 +bottom_length rd 1 +endl + push ebx esi edi + + mov ebx, [_bottom] + mov edx, [_img] + + mov [img_x1], 0 + push [edx+Image.Width] + pop [img_length] + + mov [bottom_x1], 0 + mov ecx, [ebx+Image.Width] + mov [bottom_length], ecx + + mov eax, [edx+Image.Extended] + movsx eax, word[eax+xcf_ext.offset_x] + cmp eax, 0 + jg .greater_x + jl .lesser_x + mov [copy_width], ecx + jmp .done_x +.greater_x: + add [bottom_x1], eax + sub [bottom_length], eax + jns .label_x + mov [copy_width], 0 + jmp .done_x +.lesser_x: + sub [img_x1], eax + add [img_length], eax + jns .label_x + mov [copy_width], 0 + jmp .done_x +.label_x: + mov ecx, [img_length] + cmp ecx, [bottom_length] + jng @f + mov ecx, [bottom_length] +@@: + mov [copy_width], ecx +.done_x: + + + mov [img_y1], 0 + push [edx+Image.Height] + pop [img_length] + + mov [bottom_y1], 0 + mov ecx, [ebx+Image.Height] + mov [bottom_length], ecx + + mov eax, [edx+Image.Extended] + movsx eax, word[eax+xcf_ext.offset_y] + cmp eax, 0 + jg .greater_y + jl .lesser_y + mov [copy_height], ecx + jmp .done_y +.greater_y: + add [bottom_y1], eax + sub [bottom_length], eax + jns .label_y + mov [copy_height], 0 + jmp .done_y +.lesser_y: + sub [img_y1], eax + add [img_length], eax + jns .label_y + mov [copy_height], 0 + jmp .done_y +.label_y: + mov ecx, [img_length] + cmp ecx, [bottom_length] + jng @f + mov ecx, [bottom_length] +@@: + mov [copy_height], ecx +.done_y: + + mov esi, [edx+Image.Data] + mov edi, [ebx+Image.Data] + + mov eax, [edx+Image.Width] + imul eax, [img_y1] + add eax, [img_x1] + shl eax, 1 + cmp [edx+Image.Width], Image.bpp16 + je @f + shl eax, 1 +@@: add esi, eax + + mov eax, [ebx+Image.Width] + imul eax, [bottom_y1] + add eax, [bottom_x1] + shl eax, 1 + cmp [ebx+Image.Width], Image.bpp8 + je @f + shl eax, 1 +@@: add edi, eax + + + mov eax, [edx+Image.Width] + sub eax, [copy_width] + shl eax, 1 + cmp [edx+Image.Width], Image.bpp16 + je @f + shl eax, 1 +@@: mov [img_total_bpl], eax + + mov eax, [ebx+Image.Width] + sub eax, [copy_width] + shl eax, 1 + cmp [ebx+Image.Width], Image.bpp8 + je @f + shl eax, 1 +@@: mov [bottom_total_bpl], eax + + cmp [_layer_number], 0 + jne .not_first + mov ecx, [copy_width] + imul ecx, [copy_height] + cmp [ebx+Image.Type], Image.bpp8 + je .bpp8 +.bpp32: rep movsd + jmp .done +.bpp8: rep movsw + jmp .done +.not_first: + + push edi + mov ecx, [edx+Image.Extended] + mov eax, [ecx+xcf_ext.layer_mode] + + mov ecx, [ebx+Image.Extended] + mov ecx, [ecx+xcf_ext.type] + + cmp ecx, XCF_BASETYPE_RGB + jne @f + mov edx, 4 + jmp .type_defined +@@: + cmp ecx, XCF_BASETYPE_GRAY + jne @f + mov edx, 8 + jmp .type_defined +@@: + mov edx, 12 +.type_defined: + mov ecx, (composite_table_end-composite_table_begin)/8 + mov edi, composite_table_begin + +.still: + cmp eax, [edi] + jne @f + add edi, edx + mov edx, [edi] + jmp .composite_found +@@: + add edi, 16 + dec ecx + jnz .still + +.composite_found: + pop edi + + mov ecx, [ebx+Image.Extended] + cmp [ecx+xcf_ext.type], XCF_BASETYPE_INDEXED + jne @f + stdcall edx, [copy_width], [copy_height], [bottom_total_bpl], [img_total_bpl] + jmp .done +@@: + cmp eax, 1 + ja @f + stdcall edx, [copy_width], [copy_height], [bottom_total_bpl], [img_total_bpl] + jmp .done +@@: + + + cmp [ebx+Image.Type], Image.bpp8 + jne @f + stdcall merge_8a, [copy_width], [copy_height], [img_total_bpl], [bottom_total_bpl] + jmp .done +@@: stdcall merge_32, [copy_width], [copy_height], [img_total_bpl], [bottom_total_bpl] +; jmp .done +.done: + stdcall img.destroy, [_img] + pop edi esi ebx + ret +endp + + +proc pack_8a _img + mov ebx, [_img] + mov esi, [ebx+Image.Data] + mov edi, [ebx+Image.Data] + mov ecx, [ebx+Image.Width] + mov edx, [ebx+Image.Height] + imul ecx, edx +@@: lodsw + stosb + dec ecx + jnz @b + ret +endp + + +proc apply_opacity _img, _color_step + + push ebx + + mov edx, [ebx+Image.Extended] + mov edx, [edx+xcf_ext.opacity] + cmp dl, 0xff + je .quit + + mov ecx, [ebx+Image.Width] + imul ecx, [ebx+Image.Height] + mov esi, [ebx+Image.Data] + mov ebx, [_color_step] + add esi, ebx + mov edi, esi +@@: lodsb + mul dl + shr ax, 8 + stosb + add esi, ebx + add edi, ebx + dec ecx + jnz @b + +.quit: pop ebx + ret +endp + + +proc apply_alpha_mask _img, _mask, _color_step + + push ebx + + mov ebx, [_img] + mov esi, [_mask] + mov esi, [esi+Image.Data] + mov edi, [ebx+Image.Data] + mov ecx, [ebx+Image.Width] + imul ecx, [ebx+Image.Height] + mov ebx, [_color_step] + add edi, ebx +@@: + lodsb + mul byte[edi] + shr ax, 8 + stosb + add edi, ebx + dec ecx + jnz @b + + stdcall img.destroy, [_mask] + pop ebx + ret +endp + + +proc pixel_rgb2hsv +locals +vsha rd 1 +max rd 1 +min rd 1 +med rd 1 +endl + push ebx ecx edx + + mov [vsha], eax + movzx eax, byte[vsha] ; eax = al = blue + movzx ecx, byte[vsha+1] ; ecx = cl = green + movzx edx, byte[vsha+2] ; edx = dl = red + + cmp al, cl + jne @f + cmp al, dl + jne @f + ror eax, 8 + mov ax, 0 + rol eax, 8 + jmp .quit + +@@: cmp dl, cl + ja @f + cmp dl, al + ja @f + mov byte[min], dl + jmp .min_found +@@: cmp cl, al + ja @f + cmp cl, dl + ja @f + mov byte[min], cl + jmp .min_found +@@: mov byte[min], al +; jmp .min_found +.min_found: + + cmp dl, cl + jb @f + cmp dl, al + jb @f + mov byte[max], dl + sub cx, ax + mov dx, cx + mov cx, 0 + jmp .max_found +@@: cmp cl, al + jb @f + cmp cl, dl + jb @f + mov byte[max], cl + sub ax, dx + mov dx, ax + mov cx, 85 + jmp .max_found +@@: mov byte[max], al + sub dx, cx + mov cx, 171 +; jmp .max_found +.max_found: + + mov al, byte[max] + sub al, byte[min] + mov byte[med], al + + + imul dx, 43 + movsx eax, dx + ror eax, 16 + mov dx, ax + rol eax, 16 + mov byte[med+1], 0 + idiv word[med] + add al, cl + mov byte[vsha+2], al + + mov al, byte[max] + mov byte[vsha], al + + mov byte[vsha+1], 0 + test al, al + jz @f + mov byte[vsha+1], 0xff + cmp al, byte[med] + je @f + mov al, byte[med] + shl ax, 8 + div byte[max] + mov byte[vsha+1], al +@@: + mov eax, [vsha] + +.quit: pop edx ecx ebx + ret +endp + + +proc pixel_hsv2rgb +locals +vsha rd 1 +f rb 1 +c rb 1 +x rb 1 +endl + + push ebx ecx edx + + + mov [vsha], eax + mov bl, byte[vsha+1] + mul bl + mov byte[c], ah + + movzx eax, byte[vsha+2] + cmp eax, 43 + ja @f + lea eax, [eax*3] + shl eax, 1 + mov ebx, eax + shr ebx, 7 + sub eax, ebx + shr ebx, 1 + sub eax, ebx + jmp .ok + +@@: cmp eax, 86 + ja @f + sub eax, 44 + lea eax, [eax*3] + shl eax, 1 + neg al + add al, 0xff + jmp .ok + +@@: cmp eax, 129 + ja @f + sub eax, 87 + lea eax, [eax*3] + shl eax, 1 + jmp .ok + +@@: cmp eax, 171 + ja @f + sub eax, 130 + lea eax, [eax*3] + shl eax, 1 + neg al + add al, 0xff + jmp .ok + +@@: cmp eax, 214 + ja @f + sub eax, 172 + lea eax, [eax*3] + shl eax, 1 + jmp .ok +@@: + sub eax, 215 + lea eax, [eax*3] + shl eax, 1 + neg al + add al, 0xff +; jmp .ok +.ok: + + neg al + add al, 0xff + neg al + add al, 0xff +; shr ax, 8 + mul byte[c] + mov byte[x], ah + + + + mov al, byte[vsha+2] + cmp al, 43 + jae @f + mov eax, [vsha] + shr eax, 8 + mov ah, byte[c] + shl eax, 8 + mov ah, byte[x] + mov al, 0 + jmp .done + +@@: cmp al, 86 + jae @f + mov eax, [vsha] + shr eax, 8 + mov ah, byte[x] + shl eax, 8 + mov ah, byte[c] + mov al, 0 + jmp .done + +@@: cmp al, 129 + jae @f + mov eax, [vsha] + shr eax, 8 + mov ah, 0 + shl eax, 8 + mov ah, byte[c] + mov al, byte[x] + jmp .done + +@@: cmp al, 171 + jae @f + mov eax, [vsha] + shr eax, 8 + mov ah, 0 + shl eax, 8 + mov ah, byte[x] + mov al, byte[c] + jmp .done + +@@: cmp al, 214 + jae @f + mov eax, [vsha] + shr eax, 8 + mov ah, byte[x] + shl eax, 8 + mov ah, 0 + mov al, byte[c] + jmp .done + +@@: mov eax, [vsha] + shr eax, 8 + mov ah, byte[c] + shl eax, 8 + mov ah, 0 + mov al, byte[x] +; jmp .done + +.done: + mov bl, byte[vsha] + sub bl, byte[c] + ror eax, 8 + add ah, bl + rol eax, 8 + add ah, bl + add al, bl + +.quit: pop edx ecx ebx + ret +endp + + +proc pixel_rgb2hsl +; http://www.asmcommunity.net/board/index.php?topic=7425 +; iblis: "I don't know what X-Filez is, but yes you may use it however you wish. That's why I made this post, to share." +; so pixel_rgb2hsl procedure is based on code by Greg Hoyer (iblis). thanks! +;--------------------------------------------------------------; +; By Greg Hoyer aka "Iblis" ; +; ; +; RGB2HSL converts a COLORREF oriented dword filled with 8bit ; +; Red/Green/Blue values (00ggbbrr) to a similarly oriented ; +; dword filled with Hue/Saturation/Luminance values (00llsshh) ; +; This procedure returns the full range, from 0-255. This ; +; offers slightly more precision over Windows' "color picker" ; +; common dialog, which displays HSL values ranging from 0-240. ; +; ; +; It is important to note that true HSL values are normally ; +; represented as floating point fractions from 0.0 to 1.0. ; +; As such, this algorithm cannot be used to do the precise, ; +; consistent conversions that may be required by heavy-duty ; +; graphics applications. To get the decimal fraction for ; +; the returned values, convert the Hue, Saturation, and/or ; +; Luminance values to floating point, and then divide by 255. ; +;--------------------------------------------------------------; +locals +bgra rd 1 +endl + push ebx esi edi + + mov [bgra], eax + + movzx esi, byte[bgra+0] + movzx edi, byte[bgra+1] + movzx ebx, byte[bgra+2] + mov cl, -1 + cmp esi, edi + ja .cmp1 + xchg esi, edi + neg cl + shl cl, 1 +.cmp1: cmp edi, ebx + jb .cmp2 + xchg edi, ebx + neg cl +.cmp2: cmp esi, ebx + ja .cmp3 + xchg esi, ebx + not cl +.cmp3: neg ebx + add ebx, esi + mov eax, edi + add edi, esi + jz .done + sub esi, eax + jz .done + mov eax, esi + shl eax, 8 + sub eax, esi + push edi + cmp edi, 0xff + jbe .csat + neg edi + add edi, 510 +.csat: xor edx, edx + div edi + pop edi + shr edi, 1 + shl eax, 8 + or edi, eax + add cl, 3 + jnc .noneg + neg ebx +.noneg: shl cl, 2 + mov eax, 0x13135db9 + shr eax, cl + and eax, 7 + mul esi + add eax, ebx + mov ebx, eax + shl eax, 8 + sub eax, ebx + mov ebx, esi + shl esi, 1 + lea ebx, [ebx*4+esi] + xor edx, edx + div ebx + shl eax, 16 + or eax, edi +.done: bswap eax + shr eax, 8 + + mov bl, byte[bgra+3] + bswap eax + mov al, bl + ror eax, 8 + + + pop edi esi ebx + ret +endp + + +proc pixel_hsl2rgb +; http://www.asmcommunity.net/board/index.php?topic=7425 +; iblis: "I don't know what X-Filez is, but yes you may use it however you wish. That's why I made this post, to share." +; so pixel_hsl2rgb procedure is based on code by Greg Hoyer (iblis). thanks! +;--------------------------------------------------------------; +; By Greg Hoyer aka "Iblis" ; +; ; +; HSL2RGB does the opposite of RGB2HSL. It converts a ; +; Hue/Saturation/Luminance (00llsshh) dword back into its ; +; corresponding RGB COLORREF (00bbggrr). This function is ; +; intented to be used exclusively with RGB2HSL (see above) ; +; ; +; If you're using this for your own custom color-chooser ; +; dialog, remember that the values are in the range of 0-255. ; +; If you MUST emulate the Windows' color-chooser, convert HSL ; +; values this way before you display them: ; +; ; +; display_value = ( x * 240 ) / 255 ; +; ; +; ...where x represents any one of the HSL values. ; +;--------------------------------------------------------------; +locals +lsha rd 1 +endl + + push ebx esi edi + + mov [lsha], eax + + movzx ebx, byte[lsha+0] + lea esi, [ebx*2] + movzx edi, byte[lsha+1] + xor eax, eax + mov cl, 1 + cmp bl, 0x7f + ja .lcase + dec al + xor ecx, ecx +.lcase: add eax, edi + mul ebx + or ecx, ecx + jz .scase + neg eax + mov ecx, ebx + add ecx, edi + mov edx, ecx + shl ecx, 8 + sub ecx, edx + add eax, ecx +.scase: xor edx, edx + xor ecx, ecx + dec cl + mov edi, ecx + div ecx + jz .done + mov ecx, eax + sub esi, eax + movzx eax, byte[lsha+2] + mov ebx, eax + shl eax, 1 + lea eax, [ebx*4+eax] + xor edx, edx + div edi + mov ebx, eax + mov eax, ecx + sub eax, esi + mul edx + push ebx + mov ebx, ecx + shl ebx, 8 + sub ebx, ecx + sub ebx, eax + xchg eax, ebx + xor edx, edx + div edi + shl eax, 24 + or ecx, eax + mov eax, esi + shl eax, 8 + sub eax, esi + shl esi, 16 + or ecx, esi + add eax, ebx + xor edx, edx + div edi + mov ch, al + mov eax, ecx + pop ecx + cmp cl, 6 + jz .done + or ecx, ecx + jz .done + bswap eax + rol eax, 8 + xchg ah, al + dec ecx + jz .done + ror eax, 8 + xchg ah, al + dec ecx + jz .done + rol eax, 8 + xchg ah, al + dec ecx + jz .done + bswap eax + rol eax, 8 + xchg ah, al + dec ecx + jz .done + ror eax, 8 + xchg ah, al +.done: and eax, 0x00ffffff + + mov bl, byte[lsha+3] + bswap eax + mov al, bl + ror eax, 8 + + pop edi esi ebx + ret +endp + + +match =MMX,COMPOSITE_MODE{include 'composite_mmx.inc'} +;;================================================================================================;; +;;////////////////////////////////////////////////////////////////////////////////////////////////;; +;;================================================================================================;; +;! Below is private data you should never use directly from your code ;; +;;================================================================================================;; +;;////////////////////////////////////////////////////////////////////////////////////////////////;; +;;================================================================================================;; +xcf_prop_table_begin: +dd 00, parse_prop_00 +dd 01, parse_prop_01 +dd 06, parse_prop_06 +dd 07, parse_prop_07 +dd 08, parse_prop_08 +dd 11, parse_prop_11 +dd 15, parse_prop_15 +xcf_prop_table_end: + +composite_table_begin: +.p00 dd 00, composite_rgb_00, composite_gray_00, composite_indexed_00 ; Normal +.p01 dd 01, composite_rgb_01, composite_gray_01, composite_gray_01 ; Dissolve : random dithering to discrete alpha +;.p02 dd 02, composite_rgb_02, 0, composite_indexed_02 ; Behind : not selectable in the GIMP UI. not implemented +.p03 dd 03, composite_rgb_03, composite_rgb_03, composite_indexed_00 ; Multiply +.p04 dd 04, composite_rgb_04, composite_rgb_04, composite_indexed_00 ; Screen +.p05 dd 05, composite_rgb_05, composite_rgb_05, composite_indexed_00 ; Overlay +.p06 dd 06, composite_rgb_06, composite_rgb_06, composite_indexed_00 ; Difference +.p07 dd 07, composite_rgb_07, composite_rgb_07, composite_indexed_00 ; Addition +.p08 dd 08, composite_rgb_08, composite_rgb_08, composite_indexed_00 ; Subtract +.p09 dd 09, composite_rgb_09, composite_rgb_09, composite_indexed_00 ; Darken Only +.p10 dd 10, composite_rgb_10, composite_rgb_10, composite_indexed_00 ; Lighten Only +.p11 dd 11, composite_rgb_11, composite_gray_00, composite_indexed_00 ; Hue (H of HSV) +.p12 dd 12, composite_rgb_12, composite_gray_00, composite_indexed_00 ; Saturation (S of HSV) +.p13 dd 13, composite_rgb_13, composite_gray_00, composite_indexed_00 ; Color (H and S of HSL) +.p14 dd 14, composite_rgb_14, composite_gray_00, composite_indexed_00 ; Value (V of HSV) +.p15 dd 15, composite_rgb_15, composite_rgb_15, composite_indexed_00 ; Divide +.p16 dd 16, composite_rgb_16, composite_rgb_16, composite_indexed_00 ; Dodge +.p17 dd 17, composite_rgb_17, composite_rgb_17, composite_indexed_00 ; Burn +.p18 dd 18, composite_rgb_18, composite_rgb_18, composite_indexed_00 ; Hard Light +.p19 dd 19, composite_rgb_05, composite_rgb_05, composite_indexed_00 ; Soft Light : XCF version >= 2 only ('soft light' == 'overlay') +.p20 dd 20, composite_rgb_20, composite_rgb_20, composite_indexed_00 ; Grain Extract : XCF version >= 2 only +.p21 dd 21, composite_rgb_21, composite_rgb_21, composite_indexed_00 ; Grain Merge : XCF version >= 2 only +composite_table_end: + +random_a dd 1103515245 +random_b dd 777 +random_c dd 12345 \ No newline at end of file diff --git a/programs/develop/libraries/libs-dev/libimg/xcf/xcf.inc b/programs/develop/libraries/libs-dev/libimg/xcf/xcf.inc new file mode 100644 index 0000000000..2c521df8f7 --- /dev/null +++ b/programs/develop/libraries/libs-dev/libimg/xcf/xcf.inc @@ -0,0 +1,42 @@ +;;================================================================================================;; +;;//// xcf.inc //// (c) dunkaist, 2011 ///////////////////////////////////////////////////////////;; +;;================================================================================================;; +;; ;; +;; This file is part of Common development libraries (Libs-Dev). ;; +;; ;; +;; Libs-Dev is free software: you can redistribute it and/or modify it under the terms of the GNU ;; +;; Lesser General Public License as published by the Free Software Foundation, either version 2.1 ;; +;; of the License, or (at your option) any later version. ;; +;; ;; +;; Libs-Dev is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without ;; +;; even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;; +;; Lesser General Public License for more details. ;; +;; ;; +;; You should have received a copy of the GNU Lesser General Public License along with Libs-Dev. ;; +;; If not, see . ;; +;; ;; +;;================================================================================================;; + +struct xcf_header + magic_string rb 9 + version rd 1 + reserved rb 1 + width rd 1 + height rd 1 + base_type rd 1 +ends + +XCF_BASETYPE_RGB equ 0 +XCF_BASETYPE_GRAY equ 1 +XCF_BASETYPE_INDEXED equ 2 + +struct xcf_ext + visible rd 1 + layer_mode rd 1 + offset_x rd 1 + offset_y rd 1 + opacity rd 1 + apply_mask rd 1 + type rd 1 + planes rd 1 +ends \ No newline at end of file