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