From 23b7fbd318b1a3269a7b7392c26a327b29fdd760 Mon Sep 17 00:00:00 2001 From: Ivan Baravy Date: Wed, 25 Aug 2010 14:59:27 +0000 Subject: [PATCH] libimg: 1bpp (monochrome) images support, pcx.asm now uses 1bpp functions too, pcx code optimization git-svn-id: svn://kolibrios.org@1593 a494cfbc-eb01-0410-851d-a64ba20cac60 --- .../libraries/libs-dev/libimg/libimg.asm | 317 +++++++++++++++- .../libraries/libs-dev/libimg/libimg.inc | 11 +- .../libraries/libs-dev/libimg/pcx/pcx.asm | 358 ++++++------------ 3 files changed, 438 insertions(+), 248 deletions(-) diff --git a/programs/develop/libraries/libs-dev/libimg/libimg.asm b/programs/develop/libraries/libs-dev/libimg/libimg.asm index 493544a8ef..5acc435630 100644 --- a/programs/develop/libraries/libs-dev/libimg/libimg.asm +++ b/programs/develop/libraries/libs-dev/libimg/libimg.asm @@ -503,6 +503,46 @@ align 16 @@: ret +align 16 +.bpp1: + push ebx edx + mov ebx, esi + mov esi, [ebx + Image.Data] + mov ecx, [ebx + Image.Height] + .bpp1.pre: + mov edx, [ebx + Image.Width] + mov eax, 7 + .bpp1.begin: + push ecx esi + xor cx, cx + bt [esi], eax + setc cl + mov esi, [ebx + Image.Palette] + jcxz @f + add esi, 4 + @@: + mov ecx, 3 + cld + rep movsb + pop esi ecx + dec edx + jz .bpp1.end_line + dec eax + jns .bpp1.begin + mov eax, 7 + inc esi + jmp .bpp1.begin + + .bpp1.end_line: + dec ecx + jz .bpp1.quit + inc esi + jmp .bpp1.pre + + .bpp1.quit: + pop edx ebx + ret + endp ;;================================================================================================;; @@ -891,6 +931,61 @@ endl add edi, [scanline_len] dec ecx jnz .next_line_horz24 + jmp .exit + +.bpp1_horz: + push eax edx + mov edi, [scanline_len] + mov edx, [ebx+Image.Width] + and edx, 0x07 + neg dl + add dl, 8 + and dl, 0x07 ; clear if cl=8 +.bpp1_horz.begin: + push ebx ecx edx esi + mov eax, 7 + add edi, esi + sub edi, 1 + mov ebx, [ebx+Image.Width] + shr ebx, 1 +.bpp1_horz.flip_line: + xor ecx, ecx + bt [esi], eax + setc cl + bt [edi], edx + jc .bpp1_horz.one + .bpp1_horz.zero: + btr [esi], eax + jmp @f + .bpp1_horz.one: + bts [esi], eax + @@: + jecxz .bpp1_horz.reset + .bpp1_horz.set: + bts [edi], edx + jmp @f + .bpp1_horz.reset: + btr [edi], edx + @@: + inc edx + and edx, 0x07 + jnz @f + dec edi + @@: + dec eax + jns @f + mov eax, 7 + inc esi + @@: + dec ebx + jnz .bpp1_horz.flip_line + + pop esi edx ecx ebx + add esi, [scanline_len] + mov edi, [scanline_len] + dec ecx + jnz .bpp1_horz.begin + pop edx eax .exit: xor eax, eax @@ -990,6 +1085,8 @@ endl add eax, [ebx + Image.Data] mov [pixels_ptr], eax + cmp [ebx + Image.Type], Image.bpp1 + jz .rotate_ccw1 cmp [ebx + Image.Type], Image.bpp8 jz .rotate_ccw8 cmp [ebx + Image.Type], Image.bpp24 @@ -1182,6 +1279,83 @@ endl pop ecx jmp .next_column_ccw_low24 +.rotate_ccw1: + push ecx edx + + mov eax, [ebx+Image.Height] + add eax, 7 + shr eax, 3 + mul word[ebx+Image.Width] + shl eax, 16 + shrd eax, edx, 16 + push eax ; save new data size + + invoke mem.alloc, eax + or eax, eax + jz .error + push eax ; save pointer to new data + + mov ecx, [ebx+Image.Width] + and ecx, 0x07 + neg cl + add cl, 8 + and cl, 0x07 ; clear if cl=8 + + mov esi, eax + mov edi, [ebx+Image.Data] + mov eax, 7 + mov edx, [scanline_len_old] + dec edx + add edi, edx + + .rotate_ccw1.begin: + bt [edi], ecx + jc .rotate_ccw1.one + .rotate_ccw1.zero: + btr [esi], eax + jmp @f + .rotate_ccw1.one: + bts [esi], eax + @@: + add edi, [scanline_len_old] + dec [scanline_pixels_new] + jz .rotate_ccw1.end_of_line + dec eax + jns .rotate_ccw1.begin + mov eax, 7 + inc esi + jmp .rotate_ccw1.begin + + .rotate_ccw1.end_of_line: + inc esi + mov eax, 7 + mov edi, [ebx+Image.Height] + mov [scanline_pixels_new], edi + inc ecx + and cl, 0x07 + jz @f + mov edi, [ebx+Image.Data] + add edi, edx + jmp .rotate_ccw1.begin + @@: + dec edx + js .rotate_ccw1.quit + mov edi, [ebx+Image.Data] + add edi, edx + jmp .rotate_ccw1.begin + + .rotate_ccw1.quit: + pop eax ; get pointer to new data + mov esi, eax + mov edi, [ebx + Image.Data] + pop ecx ; get new data size + rep movsb + + invoke mem.free, eax + + pop edx ecx + jmp .exchange_dims + .rotate_cw_low: mov eax, [ebx + Image.Height] mov [scanline_pixels_new], eax @@ -1203,6 +1377,8 @@ endl add eax, [ebx + Image.Data] mov [pixels_ptr], eax + cmp [ebx + Image.Type], Image.bpp1 + jz .rotate_cw1 cmp [ebx + Image.Type], Image.bpp8 jz .rotate_cw8 cmp [ebx + Image.Type], Image.bpp24 @@ -1405,6 +1581,93 @@ endl pop ecx jmp .next_column_cw_low24 +.rotate_cw1: + push ecx edx + + mov eax, [ebx+Image.Height] + add eax, 7 + shr eax, 3 + mul word[ebx+Image.Width] + shl eax, 16 + shrd eax, edx, 16 + + push eax ; save new data size + + invoke mem.alloc, eax + or eax, eax + jz .error + push eax ; save pointer to new data + + mov ecx, 7 + + mov edx, [ebx+Image.Width] + mov [pixels_ptr], edx ; we don't use pixels_ptr as it do other procedures, we save there [ebx+Image.Width] + mov esi, eax + mov edi, [ebx+Image.Data] + mov eax, [ebx+Image.Height] + dec eax + mul [scanline_len_old] + add edi, eax + mov eax, 7 + mov edx, 0 + + .rotate_cw1.begin: + bt [edi], ecx + jc .rotate_cw1.one + .rotate_cw1.zero: + btr [esi], eax + jmp @f + .rotate_cw1.one: + bts [esi], eax + @@: + sub edi, [scanline_len_old] + dec [scanline_pixels_new] + jz .rotate_cw1.end_of_line + dec eax + jns .rotate_cw1.begin + mov eax, 7 + inc esi + jmp .rotate_cw1.begin + + .rotate_cw1.end_of_line: + dec [pixels_ptr] + jz .rotate_cw1.quit + inc esi + mov eax, [ebx+Image.Height] + mov [scanline_pixels_new], eax + mov eax, 7 + dec ecx + js @f + mov edi, [ebx+Image.Height] + dec edi + imul edi, [scanline_len_old] + add edi, [ebx+Image.Data] + add edi, edx + jmp .rotate_cw1.begin + @@: + mov ecx, 7 + inc edx + cmp edx, [scanline_len_old] + je .rotate_cw1.quit + mov edi, [ebx+Image.Height] + dec edi + imul edi, [scanline_len_old] + add edi, [ebx+Image.Data] + add edi, edx + jmp .rotate_cw1.begin + + .rotate_cw1.quit: + pop eax ; get pointer to new data + mov esi, eax + mov edi, [ebx + Image.Data] + pop ecx ; get new data size + rep movsb + + invoke mem.free, eax + + pop edx ecx + jmp .exchange_dims + .flip: jmp .exit @@ -1613,6 +1876,8 @@ proc img._.resize_data _img, _width, _height ;////////////////////////////////// ; do not allow images which require too many memory cmp eax, 4000000h jae .error + cmp [ebx + Image.Type], Image.bpp1 + jz .bpp1 cmp [ebx + Image.Type], Image.bpp8 jz .bpp8 cmp [ebx + Image.Type], Image.bpp24 @@ -1625,6 +1890,34 @@ proc img._.resize_data _img, _width, _height ;////////////////////////////////// jmp @f .bpp8: add eax, 256*4 ; for palette + jmp @f +.bpp1: + mov eax, [_width] + add eax, 7 + shr eax, 3 + mul word[_height] + shl eax, 16 + mov ax, dx + ror eax, 16 + + push ebx + mov ebx, eax + + mov eax, [_height] + add eax, 7 + shr eax, 3 + mul word[_width] + shl eax, 16 + mov ax, dx + ror eax, 16 + + cmp eax, ebx + jge .bpp1.skip + mov eax, ebx + .bpp1.skip: + pop ebx + + add eax, 2*4 ; for palette @@: mov esi, eax invoke mem.realloc, [ebx + Image.Data], eax @@ -1637,10 +1930,16 @@ proc img._.resize_data _img, _width, _height ;////////////////////////////////// push [_height] pop [ebx + Image.Height] cmp [ebx + Image.Type], Image.bpp8 - jnz .ret + jnz @f lea esi, [eax + esi - 256*4] mov [ebx + Image.Palette], esi jmp .ret +@@: + cmp [ebx + Image.Type], Image.bpp1 + jnz .ret + lea esi, [eax + esi - 2*4] + mov [ebx + Image.Palette], esi + jmp .ret .error: xor eax, eax @@ -1658,19 +1957,25 @@ img._.get_scanline_len: ;/////////////////////////////////////////////////////// ;;------------------------------------------------------------------------------------------------;; ;< --- TBD --- ;; ;;================================================================================================;; + cmp [ebx + Image.Type], Image.bpp1 + jz .bpp1.1 cmp [ebx + Image.Type], Image.bpp8 jz .bpp8.1 cmp [ebx + Image.Type], Image.bpp24 jz .bpp24.1 add eax, eax cmp [ebx + Image.Type], Image.bpp32 - jnz @f + jnz .quit add eax, eax - jmp @f + jmp .quit .bpp24.1: lea eax, [eax*3] + jmp .quit +.bpp1.1: + add eax, 7 + shr eax, 3 .bpp8.1: -@@: +.quit: ret @@ -1697,13 +2002,14 @@ img._.formats_table: dd 0 align 4 -type2bpp dd 8, 24, 32, 15, 16 +type2bpp dd 8, 24, 32, 15, 16, 1 img._.do_rgb.handlers: dd img._.do_rgb.bpp8 dd img._.do_rgb.bpp24 dd img._.do_rgb.bpp32 dd img._.do_rgb.bpp15.amd ; can be overwritten in lib_init dd img._.do_rgb.bpp16.amd ; can be overwritten in lib_init + dd img._.do_rgb.bpp1 img.flip.layer.handlers_horz: dd img.flip.layer.bpp8_horz @@ -1711,6 +2017,7 @@ img.flip.layer.handlers_horz: dd img.flip.layer.bpp32_horz dd img.flip.layer.bpp1x_horz dd img.flip.layer.bpp1x_horz + dd img.flip.layer.bpp1_horz ;;================================================================================================;; ;;////////////////////////////////////////////////////////////////////////////////////////////////;; diff --git a/programs/develop/libraries/libs-dev/libimg/libimg.inc b/programs/develop/libraries/libs-dev/libimg/libimg.inc index 66d30445a0..248662cbc4 100644 --- a/programs/develop/libraries/libs-dev/libimg/libimg.inc +++ b/programs/develop/libraries/libs-dev/libimg/libimg.inc @@ -19,7 +19,7 @@ struct FormatsTableEntry - Is dd ? + Is dd ? Decode dd ? Encode dd ? ends @@ -28,10 +28,10 @@ struct Image Checksum dd ? ; ((Width ROL 16) OR Height) XOR Data[0] Width dd ? Height dd ? - Next dd ? + Next dd ? Previous dd ? Type dd ? ; one of Image.bppN - Data dd ? + Data dd ? Palette dd ? ; used iff Type eq Image.bpp8 Extended dd ? Flags dd ? ; bitfield @@ -45,6 +45,7 @@ Image.bpp24 = 2 Image.bpp32 = 3 Image.bpp15 = 4 Image.bpp16 = 5 +Image.bpp1 = 6 ; bits in Image.Flags Image.IsAnimated = 1 @@ -54,9 +55,9 @@ struct ImageDecodeOptions BackgroundColor dd ? ; used for transparent images as background ends -FLIP_VERTICAL = 0x01 +FLIP_VERTICAL = 0x01 FLIP_HORIZONTAL = 0x02 -FLIP_BOTH = FLIP_VERTICAL or FLIP_HORIZONTAL +FLIP_BOTH = FLIP_VERTICAL or FLIP_HORIZONTAL ROTATE_90_CW = 0x01 ROTATE_180 = 0x02 diff --git a/programs/develop/libraries/libs-dev/libimg/pcx/pcx.asm b/programs/develop/libraries/libs-dev/libimg/pcx/pcx.asm index 3fa53504e2..14b714af10 100644 --- a/programs/develop/libraries/libs-dev/libimg/pcx/pcx.asm +++ b/programs/develop/libraries/libs-dev/libimg/pcx/pcx.asm @@ -73,38 +73,26 @@ proc img.decode.pcx _data, _length, _options ;////////////////////////////////// ;< eax = 0 (error) or pointer to image ;; ;;================================================================================================;; locals -; IMGwidth dd ? -; IMGheight dd ? -; IMGbpp dd ? -buf rb 1 nplanes rd 1 xsize rw 1 ysize rw 1 -stxsize rw 1 -stysize rw 1 +bpl rw 1 total_bpl rd 1 -total_bpl_tmp rd 1 line_begin rd 1 -retvalue rd 1 - +retvalue rd 1 ; 0 (error) or pointer to image endl pusha mov esi, [_data] - - cmp [esi+pcx_header.bpp], 1 - jz monochrome - cmp byte[esi+pcx_header.nplanes], 3 - jnz indexed - - - - _24bit: - xor eax, eax - mov al, byte[esi+pcx_header.nplanes] + movzx eax, byte[esi+pcx_header.nplanes] mov [nplanes], eax - mul word[esi+pcx_header.bpl] + mov bx, word[esi+pcx_header.bpl] + mov [bpl], bx + mul bx + shl eax, 16 + mov ax, dx + ror eax, 16 mov [total_bpl], eax movzx eax, word[esi+pcx_header.xmax] @@ -117,6 +105,15 @@ endl sub bx, word[esi+pcx_header.ymin] mov [ysize], bx + + cmp [esi+pcx_header.bpp], 1 + jz .monochrome + cmp byte[esi+pcx_header.nplanes], 3 + jnz .indexed + + + ._24bit: + stdcall img.create, eax, ebx, Image.bpp24 mov [retvalue], eax test eax, eax @@ -134,107 +131,107 @@ endl mov esi, [_data] add esi, 128 - mov edi, [retvalue] - mov edi, [edi+Image.Data] +; mov edi, [retvalue] + mov edi, [eax+Image.Data] add edi, 2 mov [line_begin], edi mov ebx, [total_bpl] - .begin: - mov eax, [_data] - mov ax, word[eax+pcx_header.bpl] - .decode: - mov dl, byte[esi] - inc esi - mov [buf], dl - and dl, 0xC0 - cmp dl, 0xC0 - jne @f - mov dl, byte[buf] - and dl, 0x3F - mov dh, [esi] - inc esi - - .write_sequence: - mov [edi], dh + ._24bit.begin: + mov ax, word[bpl] + ._24bit.decode: + call get_byte + ._24bit.write_sequence: + mov [edi], dl dec ax - dec ebx add edi, [nplanes] - dec dl - test dl, dl - jnz .write_sequence + dec dh + jnz ._24bit.write_sequence test ax, ax - jz .end_color_line - jmp .decode - @@: - mov dl, byte[buf] - mov [edi], dl - add edi, [nplanes] - dec ebx - dec ax - jz .end_color_line - jmp .decode + jz ._24bit.end_color_line + jmp ._24bit.decode - .end_color_line: + ._24bit.end_color_line: test ebx, ebx - jz .end_full_line + jz ._24bit.end_full_line dec [line_begin] mov edi, [line_begin] - jmp .begin + jmp ._24bit.begin - .end_full_line: + ._24bit.end_full_line: dec word[ysize] jz .quit mov ebx, [total_bpl] add edi, 2 mov [line_begin], edi - jmp .begin + jmp ._24bit.begin - .quit: - popa - mov eax, [retvalue] - ret - indexed: - - xor eax, eax - mov al, byte[esi+pcx_header.nplanes] - mov [nplanes], eax - mul word[esi+pcx_header.bpl] - mov [total_bpl], eax - - movzx eax, word[esi+pcx_header.xmax] - inc ax - sub ax, word[esi+pcx_header.xmin] - mov [xsize], ax - - movzx ebx, word[esi+pcx_header.ymax] - inc bx - sub bx, word[esi+pcx_header.ymin] - mov [ysize], bx + .indexed: stdcall img.create, eax, ebx, Image.bpp8 mov [retvalue], eax test eax, eax jz .quit + movzx ebx, [xsize] + movzx ecx, [ysize] + mov edx, [eax+Image.Data] + + rol ebx, 16 + or ebx, ecx + xor ebx, [edx] + mov [eax+Image.Checksum], ebx + mov esi, [_data] add esi, [_length] sub esi, 768 mov edi, [eax+Image.Palette] - mov ecx, 256 + mov cx, 256 @@: mov ebx, [esi] - and ebx, 0x00ffffff bswap ebx shr ebx, 8 mov [edi], ebx add edi, 4 add esi, 3 - dec ecx + dec cx jnz @b + mov esi, [_data] + add esi, 128 +; mov edi, [retvalue] + mov edi, [eax+Image.Data] + + .indexed.begin: + mov ax, word[bpl] + .indexed.decode: + call get_byte + .indexed.write_sequence: + mov [edi], dl + inc edi + dec ax + dec dh + jnz .indexed.write_sequence + + test ax, ax + jz .indexed.end_line + jmp .indexed.decode + + .indexed.end_line: + dec word[ysize] + jz .quit + jmp .indexed.begin + + + .monochrome: + + stdcall img.create, eax, ebx, Image.bpp1 + mov [retvalue], eax + test eax, eax + jz .quit + movzx ebx, [xsize] movzx ecx, [ysize] mov edx, [eax+Image.Data] @@ -244,175 +241,42 @@ endl xor ebx, [edx] mov [eax+Image.Checksum], ebx - - mov esi, [_data] - add esi, 128 - mov edi, [retvalue] - mov edi, [edi+Image.Data] - - .begin: - mov eax, [_data] - mov ax, word[eax+pcx_header.bpl] - .decode: - mov dl, byte[esi] - inc esi - mov [buf], dl - and dl, 0xC0 - cmp dl, 0xC0 - jne @f - mov dl, [buf] - and dl, 0x3F - mov dh, [esi] - inc esi - - .write_sequence: - mov [edi], dh - inc edi - dec ax - dec dl - jnz .write_sequence - - test ax, ax - jz .end_line - jmp .decode - @@: - mov dl, byte[buf] - mov [edi], dl - inc edi - dec ax - jz .end_line - jmp .decode - - .end_line: - dec word[ysize] - jz .quit - jmp .begin - - .quit: - popa - mov eax, [retvalue] - ret - - - monochrome: - - xor eax, eax - mov ax, word[esi+pcx_header.bpl] - mov [total_bpl], eax - - movzx eax, word[esi+pcx_header.xmax] - inc ax - sub ax, word[esi+pcx_header.xmin] - mov [xsize], ax - - movzx ebx, word[esi+pcx_header.ymax] - inc bx - sub bx, word[esi+pcx_header.ymin] - mov [ysize], bx - - stdcall img.create, eax, ebx, Image.bpp8 - mov [retvalue], eax - test eax, eax - jz .quit - mov edi, [eax+Image.Palette] mov [edi], dword 0x00000000 mov [edi+4], dword 0x00ffffff - movzx ebx, [xsize] - movzx ecx, [ysize] - mov edx, [eax+Image.Data] - - rol ebx, 16 - or ebx, ecx - xor ebx, [edx] - mov [eax+Image.Checksum], ebx - - mov esi, [_data] add esi, 128 - mov edi, [retvalue] - mov edi, [edi+Image.Data] +; mov edi, [retvalue] + mov edi, [eax+Image.Data] - .begin: - mov eax, [total_bpl] - mov [total_bpl_tmp], eax + + .monochrome.begin: + mov ebx, [total_bpl] mov ax, [xsize] - .decode: - - mov dh, byte[esi] - inc esi - mov [buf], dh - and dh, 0xC0 - cmp dh, 0xC0 - je .cycle1 - mov dh, 1 - mov dl, [buf] - jmp .exit1 - .cycle1: - mov dh, [buf] - and dh, 0x3F - mov dl, byte[esi] - inc esi - .exit1: - push eax - xor eax, eax - mov al, dh - sub [total_bpl_tmp], eax - pop eax - - - .write_sequence: - mov ecx, 7 - .go: - bt edx, ecx - jnc @f - mov [edi], byte 0x01 - jmp .later - @@: - mov [edi], byte 0x00 - .later: + .monochrome.decode: + call get_byte + .monochrome.write_sequence: + mov [edi], dl inc edi - dec ax - jnz .lol - @@: - cmp [total_bpl_tmp], 0 + cmp ax, 8 + jng .monochrome.is_last_byte_in_line + sub ax, 8 + dec dh + jnz .monochrome.write_sequence + jmp .monochrome.decode + + .monochrome.is_last_byte_in_line: + test ebx, ebx jng @f - - mov dh, byte[esi] - inc esi - mov [buf], dh - and dh, 0xC0 - cmp dh, 0xC0 - je .cycle2 - mov dh, 1 - mov dl, [buf] - jmp .exit2 - .cycle2: - mov dh, [buf] - and dh, 0x3F - mov dl, byte[esi] - inc esi - .exit2: - push eax - xor eax, eax - mov al, dh - sub [total_bpl_tmp], eax - pop eax - - jmp @b + call get_byte + jmp .monochrome.is_last_byte_in_line @@: dec word[ysize] - jnz .begin + jnz .monochrome.begin jmp .quit - .lol: - dec ecx - cmp ecx, -1 - jne .go - dec dh - jnz .write_sequence - jmp .decode + .quit: popa @@ -445,7 +309,25 @@ endp ;;================================================================================================;; ;;////////////////////////////////////////////////////////////////////////////////////////////////;; ;;================================================================================================;; +proc get_byte + mov dh, byte[esi] + inc esi + cmp dh, 0xC0 + jnb .cycle1 + mov dl, dh + mov dh, 1 + jmp .exit1 + .cycle1: + and dh, 0x3F + mov dl, byte[esi] + inc esi + .exit1: + movzx ecx, dh + sub ebx, ecx + + ret +endp ;;================================================================================================;; ;;////////////////////////////////////////////////////////////////////////////////////////////////;; ;;================================================================================================;;