diff --git a/programs/develop/libraries/libs-dev/.test/004/gray_5x7.tiff b/programs/develop/libraries/libs-dev/.test/004/gray_5x7.tiff new file mode 100644 index 0000000000..5fd3b53cc2 Binary files /dev/null and b/programs/develop/libraries/libs-dev/.test/004/gray_5x7.tiff differ diff --git a/programs/develop/libraries/libs-dev/.test/004/test004.asm b/programs/develop/libraries/libs-dev/.test/004/test004.asm new file mode 100644 index 0000000000..325fe44af4 --- /dev/null +++ b/programs/develop/libraries/libs-dev/.test/004/test004.asm @@ -0,0 +1,186 @@ +use32 +org 0x0 + db 'MENUET01' + dd 0x01, START, I_END, E_END, E_END, 0, 0 + +;----------------------------------------------------------------------------- + +include '../../../../../proc32.inc' +include '../../../../../macros.inc' +include '../../../../../dll.inc' +;include '../../../../../debug.inc' + +include '../../libio/libio.inc' +include '../../libimg/libimg.inc' + +;----------------------------------------------------------------------------- + +START: + mcall 68, 11 + + stdcall dll.Load, @IMPORT + or eax, eax + jnz exit + + invoke file.open, input_file, O_READ + or eax, eax + jz exit + mov [fh], eax + + invoke file.size, input_file + mov [img_data_len], ebx + + stdcall mem.Alloc, ebx + or eax, eax + jz exit + mov [img_data], eax + + invoke file.read, [fh], eax, [img_data_len] + cmp eax, -1 + je exit + cmp eax, [img_data_len] + jne exit + + invoke file.close, [fh] + inc eax + jz exit + + invoke img.decode, [img_data], [img_data_len], 0 + or eax, eax + jz exit + mov [image_initial], eax + + stdcall mem.Free, [img_data] + test eax, eax + jz exit +;----------------------------------------------------------------------------- + +still: + mcall 10 + cmp eax, 1 + je .draw_window + cmp eax, 2 + je .key + cmp eax, 3 + je .button + jmp still + + + .draw_window: + mcall 12, 1 + mcall 0, <200, 150>, <200, 150>, 0x73FFFFFF, 0x00000000, window_title + call draw_image + mcall 12, 2 + jmp still + + .key: + mcall 2 + jmp still + + .button: + mcall 17 + shr eax, 8 + cmp eax, 1 + jne still + +exit: + cmp [image_initial], 0 + je @f + invoke img.destroy, [image_initial] + @@: + cmp [image_scaled], 0 + je @f + invoke img.destroy, [image_scaled] + @@: + mcall -1 + + +proc draw_image + + cmp [image_scaled], 0 + je @f + invoke img.destroy, [image_scaled] + @@: + + mcall 9, proc_info, -1 + + mov ecx, [proc_info.client_box.height] + inc ecx + mov edx, [proc_info.client_box.width] + inc edx + + mov ebx, [image_initial] +; invoke img.scale, ebx, 1, 2, 5, 5, 0, LIBIMG_SCALE_TYPE_STRETCH, LIBIMG_SCALE_ALG_BILINEAR, edx, ecx +; invoke img.scale, ebx, 1, 2, 5, 5, 0, LIBIMG_SCALE_TYPE_STRETCH, LIBIMG_SCALE_ALG_INTEGER, 3, 3 + invoke img.scale, ebx, 0, 0, [ebx + Image.Width], [ebx + Image.Height], 0, LIBIMG_SCALE_TYPE_STRETCH, LIBIMG_SCALE_ALG_BILINEAR, edx, ecx + +; proc img.scale _src, _crop_x, _crop_y, _crop_width, _crop_height, _dst, _scale_type, _scale_alg, _param1, _param2 +; see libimg.inc for available scale types and algorithms +; LIBIMG_SCALE_ALG_BILINEAR: _param1, _param2 -- width and height of rectangle to fit _src image to +; LIBIMG_SCALE_ALG_INTEGER: _param1 -- scale factor (i.e. 3 means scaling 7x7 to 21x21); _param2 ignored +; LIBIMG_SCALE_TYPE_*: just try and see, they are common STRETCH, FIT_BY_WIDTH etc. +; returns pointer to a scaled image + +; invoke img.scale, ebx, 0, 0, [ebx + Image.Width], [ebx + Image.Height], 0, LIBIMG_SCALE_TYPE_STRETCH, LIBIMG_SCALE_ALG_INTEGER, 3, 3 + test eax, eax + jz exit + mov [image_scaled], eax + + invoke img.draw, eax, 0, 0, [eax + Image.Width], [eax + Image.Height], 0, 0 + + ret +endp + +;----------------------------------------------------------------------------- + +window_title db 'img.scale example',0 + +input_file db '/hd0/1/gray_5x7.tiff',0 +;input_file db '/hd0/1/grayscale_123x123.tiff',0 +;input_file db '/hd0/1/grayscale_357x357.tiff',0 +;input_file db '/hd0/1/grayscale_620x620.tiff',0 +;input_file db '/hd0/1/rgb_220.jpg',0 +;input_file db '/hd0/1/rgba_217.tiff',0 +;input_file db '/hd0/1/rgb_7x9.tiff',0 +;input_file db '/hd0/1/rgba_7x9.tiff',0 +;input_file db '/hd0/1/gray_7x9.tiff',0 +;input_file db '/hd0/1/rgb_70x90.png',0 +;----------------------------------------------------------------------------- + +align 4 +@IMPORT: + +library \ + libio , 'libio.obj' , \ + libimg , 'libimg.obj' + +import libio , \ + libio.init , 'lib_init' , \ + file.size , 'file_size' , \ + file.open , 'file_open' , \ + file.read , 'file_read' , \ + file.close , 'file_close' + +import libimg , \ + libimg.init , 'lib_init' , \ + img.decode , 'img_decode' , \ + img.destroy , 'img_destroy' , \ + img.draw , 'img_draw' , \ + img.scale , 'img_scale' , \ + img.formats_table,'img_formats_table' + +;----------------------------------------------------------------------------- + +I_END: + +fh dd ? +img_data_len dd ? +img_data dd ? + +image_initial dd ? +image_scaled dd ? + +proc_info process_information + +rd 0x1000 ; stack +E_END: diff --git a/programs/develop/libraries/libs-dev/libimg/libimg.asm b/programs/develop/libraries/libs-dev/libimg/libimg.asm index 2445286e2b..713f5aa9c6 100644 --- a/programs/develop/libraries/libs-dev/libimg/libimg.asm +++ b/programs/develop/libraries/libs-dev/libimg/libimg.asm @@ -1,5 +1,5 @@ ;;================================================================================================;; -;;//// libimg.asm //// (c) mike.dld, 2007-2008, (c) diamond, 2009 ////////////////////////////////;; +;;//// libimg.asm //// (c) mike.dld, 2007-2008, (c) diamond, 2009, (c) dunkaist, 2011-2012 ///////;; ;;================================================================================================;; ;; ;; ;; This file is part of Common development libraries (Libs-Dev). ;; @@ -25,10 +25,11 @@ public @EXPORT as 'EXPORTS' include '../../../../struct.inc' include '../../../../proc32.inc' include '../../../../macros.inc' +include '../../../../config.inc' +;include '../../../../debug.inc' purge section,mov,add,sub include 'libimg.inc' -;include '../../../../system/board/trunk/debug.inc' section '.flat' code readable align 16 @@ -45,6 +46,10 @@ include 'tiff/tiff.asm' include 'pnm/pnm.asm' include 'wbmp/wbmp.asm' +include 'scale.asm' +;include 'convert.asm' +;include 'transform.asm' + ;;================================================================================================;; proc lib_init ;///////////////////////////////////////////////////////////////////////////////////;; ;;------------------------------------------------------------------------------------------------;; @@ -2200,6 +2205,7 @@ export \ img.rotate , 'img_rotate' , \ img.rotate.layer , 'img_rotate_layer' , \ img.draw , 'img_draw' , \ + img.scale , 'img_scale' , \ img.formats_table, 'img_formats_table' ; import from deflate unpacker diff --git a/programs/develop/libraries/libs-dev/libimg/libimg.inc b/programs/develop/libraries/libs-dev/libimg/libimg.inc index f18beb8a54..d560359ae3 100644 --- a/programs/develop/libraries/libs-dev/libimg/libimg.inc +++ b/programs/develop/libraries/libs-dev/libimg/libimg.inc @@ -1,5 +1,5 @@ ;;================================================================================================;; -;;//// libimg.inc //// (c) mike.dld, 2007-2008, (c) diamond, 2009 ////////////////////////////////;; +;;//// libimg.inc //// (c) mike.dld, 2007-2008, (c) diamond, 2009, (c) dunkaist, 2011-2012 ///////;; ;;================================================================================================;; ;; ;; ;; This file is part of Common development libraries (Libs-Dev). ;; @@ -32,18 +32,40 @@ LIBIMG_FORMAT_ID_PNM = 11 LIBIMG_FORMAT_ID_WBMP = 12 LIBIMG_FORMAT_ID_Z80 = 13 +; scale type +LIBIMG_SCALE_TYPE_STRETCH = 0 +LIBIMG_SCALE_TYPE_FIT_RECT = 1 +LIBIMG_SCALE_TYPE_FIT_WIDTH = 2 +LIBIMG_SCALE_TYPE_FIT_HEIGHT = 3 +LIBIMG_SCALE_TYPE_FIT_MAX = 4 +;LIBIMG_SCALE_TYPE_TILE = 5 + +; scale algorithm +;LIBIMG_SCALE_ALG_DEFAULT = 0 +LIBIMG_SCALE_ALG_INTEGER = 1 +LIBIMG_SCALE_ALG_BILINEAR = 2 +;LIBIMG_SCALE_ALG_BICUBIC = 3 +;LIBIMG_SCALE_ALG_LANCZOS = 4 + ; error codes -LIBIMG_ERROR_OUT_OF_MEMORY = 1 -LIBIMG_ERROR_FORMAT = 2 -LIBIMG_ERROR_CONDITIONS = 3 -LIBIMG_ERROR_BIT_DEPTH = 4 -LIBIMG_ERROR_ENCODER = 5 +LIBIMG_ERROR_OUT_OF_MEMORY = 1 +LIBIMG_ERROR_FORMAT = 2 +LIBIMG_ERROR_CONDITIONS = 3 +LIBIMG_ERROR_BIT_DEPTH = 4 +LIBIMG_ERROR_ENCODER = 5 +LIBIMG_ERROR_SRC_TYPE = 6 +LIBIMG_ERROR_SCALE_TYPE = 7 +LIBIMG_ERROR_SCALE_ALG = 8 +LIBIMG_ERROR_NOT_INPLEMENTED = 9 ; encode flags (byte 0x02 of _common option) -LIBIMG_ENCODE_STRICT_SPECIFIC = 0x01 -LIBIMG_ENCODE_STRICT_BIT_DEPTH = 0x02 -LIBIMG_ENCODE_DELETE_ALPHA = 0x08 -LIBIMG_ENCODE_FLUSH_ALPHA = 0x10 +LIBIMG_ENCODE_STRICT_SPECIFIC = 0x01 +LIBIMG_ENCODE_STRICT_BIT_DEPTH = 0x02 +LIBIMG_ENCODE_DELETE_ALPHA = 0x08 +LIBIMG_ENCODE_FLUSH_ALPHA = 0x10 + +; convert flags +LIBIMG_CONVERT_IN_PLACE = 0x01 ; do not create new image, store result in _src struct FormatsTableEntry Format_id dd ? @@ -78,6 +100,7 @@ Image.bpp1 = 6 Image.bpp8g = 7 ; grayscale Image.bpp8a = 8 ; grayscale with alpha channel; application layer only!!! kernel doesn't handle this image type, libimg can only create and destroy such images ;Image.bpp4 = 9 +;Image.bpp2 = 10 ; bits in Image.Flags Image.IsAnimated = 1 diff --git a/programs/develop/libraries/libs-dev/libimg/scale.asm b/programs/develop/libraries/libs-dev/libimg/scale.asm new file mode 100644 index 0000000000..dc8b4f1771 --- /dev/null +++ b/programs/develop/libraries/libs-dev/libimg/scale.asm @@ -0,0 +1,642 @@ +;;================================================================================================;; +;;//// scale.asm //// (c) dunkaist, 2012 /////////////////////////////////////////////////////////;; +;;================================================================================================;; +;; ;; +;; 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 . ;; +;; ;; +;;================================================================================================;; + +;;================================================================================================;; +proc img.scale _src, _crop_x, _crop_y, _crop_width, _crop_height, _dst, _scale_type, _scale_alg, _param1, _param2 ;; +;;------------------------------------------------------------------------------------------------;; +;? scale _image ;; +;;------------------------------------------------------------------------------------------------;; +;> [_src] = pointer to source image ;; +;> [_crop_x] = left coord of cropping rect ;; +;> [_crop_y] = top coord of cropping rect ;; +;> [_crop_width] = width of cropping rect ;; +;> [_crop_height] = height of cropping rect ;; +;> [_dst] = pointer to resulting image / 0 ;; +;> [_scale_type] = how to change width and height. see libimg.inc ;; +;> [_scale_alg] = algorithm to use. see libimg.inc ;; +;> [_param1] = the first argument passed to _scale_alg algorithm ;; +;> [_param2] = the second argument passed to _scale_alg algorithm ;; +;;------------------------------------------------------------------------------------------------;; +;< eax = 0 / pointer to scaled image ;; +;< ecx = error code / undefined ;; +;;================================================================================================;; +locals + src_type rd 1 + src_data rd 1 + dst_data rd 1 + + src_width_pixels rd 1 + src_width_bytes rd 1 + src_height_pixels rd 1 + + scl_width_pixels rd 1 + scl_width_pixels_inv rd 1 + scl_height_pixels rd 1 + scl_height_pixels_inv rd 1 + scl_width_bytes rd 1 + bytes_per_pixel rd 1 + + crop_width_pixels_m1 rd 1 + crop_height_pixels_m1 rd 1 +; bilinear + src_x rd 1 + src_y rd 1 + src_base rd 1 + dst_x rd 1 + dst_y rd 1 + rem_x rd 1 + rem_y rd 1 +endl + mov ebx, [_src] + push [ebx + Image.Width] + pop [src_width_pixels] + push [ebx + Image.Height] + pop [src_height_pixels] + push [ebx + Image.Type] + pop [src_type] + push [ebx + Image.Data] + pop [src_data] + + mov eax, [src_type] + mov ecx, [src_width_pixels] + mov edx, [src_width_pixels] + imul edx, [_crop_y] + add edx, [_crop_x] + cmp eax, Image.bpp32 + jne @f + mov [bytes_per_pixel], 4 + shl ecx, 2 + shl edx, 2 + jmp .lab1 + @@: + cmp eax, Image.bpp24 + jne @f + mov [bytes_per_pixel], 3 + lea ecx, [ecx*3] + lea edx, [ecx*3] + jmp .lab1 + @@: + cmp eax, Image.bpp8g + jne @f + mov [bytes_per_pixel], 1 + jmp .lab1 + @@: + mov ecx, LIBIMG_ERROR_BIT_DEPTH + jmp .error + .lab1: + mov [src_width_bytes], ecx + add [src_data], edx + + + mov eax, [_scale_alg] + cmp eax, LIBIMG_SCALE_ALG_INTEGER + je .integer + cmp eax, LIBIMG_SCALE_ALG_BILINEAR + je .bilinear + mov ecx, LIBIMG_ERROR_SCALE_ALG + jmp .error + + .integer: + mov eax, [_param1] + mov ecx, [_crop_width] + imul ecx, eax + mov [scl_width_pixels], ecx + mov edx, [_crop_height] + imul edx, eax + mov [scl_height_pixels], edx + + mov eax, [_dst] + test eax, eax + jnz @f + stdcall img.create, [scl_width_pixels], [scl_height_pixels], [src_type] + test eax, eax + jz .error + mov [_dst], eax + @@: + mov edi, [eax + Image.Data] + mov [dst_data], edi + + mov esi, [src_data] + mov eax, [src_type] + cmp eax, Image.bpp8g + je .integer.bpp8g + cmp eax, Image.bpp24 + je .integer.bpp24 + cmp eax, Image.bpp32 + je .integer.bpp32 + mov ecx, LIBIMG_ERROR_BIT_DEPTH + jmp .error + + .integer.bpp8g: + push [scl_width_pixels] + pop [scl_width_bytes] + mov ecx, [_param1] +; cmp ecx, 1 +; je .error + .integer.bpp8g.common: + mov edx, ecx + mov ebx, [_crop_height] + .integer.bpp8g.common.line: + push ebx + mov ebx, [_crop_width] + @@: + lodsb + mov ecx, edx + rep stosb + dec ebx + jnz @b + push esi + mov esi, edi + sub esi, [scl_width_bytes] + mov ecx, edx + dec ecx + imul ecx, [scl_width_bytes] + mov eax, ecx + shr ecx, 2 + and eax, 0x00000003 + rep movsd + mov ecx, eax + rep movsb + pop esi + mov eax, [src_width_pixels] + sub eax, [_crop_width] + add esi, eax + pop ebx + dec ebx + jnz .integer.bpp8g.common.line + mov eax, [_dst] + jmp .quit + + .integer.bpp24: + mov eax, [scl_width_pixels] + lea eax, [eax*3] + mov [scl_width_bytes], eax + mov ecx, [_param1] +; cmp ecx, 1 +; je .error + .integer.bpp24.common: + mov edx, ecx + mov ebx, [_crop_height] + .integer.bpp24.common.line: + push ebx + mov ebx, [_crop_width] + @@: + movsw + movsb + mov ecx, edx + push esi + mov esi, edi + sub esi, 3 + dec ecx + lea ecx, [ecx*3] + rep movsb + pop esi + dec ebx + jnz @b + push esi + mov esi, edi + sub esi, [scl_width_bytes] + mov ecx, edx + dec ecx + imul ecx, [scl_width_bytes] + mov eax, ecx + shr ecx, 2 + and eax, 0x00000003 + rep movsd + mov ecx, eax + rep movsb + pop esi + mov eax, [src_width_pixels] + sub eax, [_crop_width] + lea eax, [eax*3] + add esi, eax + pop ebx + dec ebx + jnz .integer.bpp24.common.line + mov eax, [_dst] + jmp .quit + + .integer.bpp32: + mov eax, [scl_width_pixels] + shl eax, 2 + mov [scl_width_bytes], eax + mov ecx, [_param1] +; cmp ecx, 1 +; je .error + .integer.bpp32.common: + mov edx, ecx + mov ebx, [_crop_height] + .integer.bpp32.common.line: + push ebx + mov ebx, [_crop_width] + @@: + lodsd + mov ecx, edx + rep stosd + dec ebx + jnz @b + push esi + mov esi, edi + sub esi, [scl_width_bytes] + mov ecx, edx + dec ecx + imul ecx, [scl_width_bytes] + shr ecx, 2 + rep movsd + pop esi + mov eax, [src_width_pixels] + sub eax, [_crop_width] + shl eax, 2 + add esi, eax + pop ebx + dec ebx + jnz .integer.bpp32.common.line + mov eax, [_dst] + jmp .quit + + + .bilinear: + mov eax, [_scale_type] + cmp eax, LIBIMG_SCALE_TYPE_FIT_RECT + je .bilinear.fit_rect + cmp eax, LIBIMG_SCALE_TYPE_FIT_WIDTH + je .bilinear.fit_width + cmp eax, LIBIMG_SCALE_TYPE_FIT_HEIGHT + je .bilinear.fit_height + cmp eax, LIBIMG_SCALE_TYPE_FIT_MAX + je .bilinear.fit_max + cmp eax, LIBIMG_SCALE_TYPE_STRETCH + je .bilinear.stretch + mov ecx, LIBIMG_ERROR_SCALE_TYPE + jmp .error + .bilinear.fit_rect: + mov eax, [_param1] + shl eax, 16 + add eax, 0x00008000 + xor edx, edx + div [src_width_pixels] + mov ebx, eax + mov eax, [_param2] + shl eax, 16 + add eax, 0x00008000 + xor edx, edx + div [src_height_pixels] + mov ecx, eax + cmp ebx, ecx + jb @f + mov ebx, ecx + @@: + jmp .bilinear.fit_common + .bilinear.fit_max: + mov eax, [_param1] + shl eax, 16 + add eax, 0x00008000 + xor edx, edx + div [src_width_pixels] + mov ebx, eax + mov eax, [_param2] + shl eax, 16 + add eax, 0x00008000 + xor edx, edx + div [src_height_pixels] + mov ecx, eax + cmp ebx, ecx + ja @f + mov ebx, ecx + @@: + jmp .bilinear.fit_common + .bilinear.fit_width: + mov eax, [_param1] + shl eax, 16 + add eax, 0x00008000 + xor edx, edx + div [src_width_pixels] + mov ebx, eax + jmp .bilinear.fit_common + .bilinear.fit_height: + mov eax, [_param2] + shl eax, 16 + add eax, 0x00008000 + xor edx, edx + div [src_height_pixels] + mov ebx, eax + jmp .bilinear.fit_common + .bilinear.fit_common: + mov eax, [src_width_pixels] + mul ebx + shr eax, 16 + mov [scl_width_pixels], eax + imul eax, [bytes_per_pixel] + mov [scl_width_bytes], eax + mov eax, [src_height_pixels] + mul ebx + shr eax, 16 + mov [scl_height_pixels], eax + jmp .bilinear.common + .bilinear.stretch: + mov eax, [_param1] + mov [scl_width_pixels], eax + imul eax, [bytes_per_pixel] + mov [scl_width_bytes], eax + mov ecx, [_param2] + mov [scl_height_pixels], ecx + jmp .bilinear.common + + .bilinear.common: + mov eax, [_dst] + test eax, eax + jnz @f + stdcall img.create, [scl_width_pixels], [scl_height_pixels], [src_type] + test eax, eax + jz .error + mov [_dst], eax + @@: + mov edi, [eax + Image.Data] + mov [dst_data], edi + + push [_crop_width] + pop [crop_width_pixels_m1] + sub [crop_width_pixels_m1], 1 + push [_crop_height] + pop [crop_height_pixels_m1] + sub [crop_height_pixels_m1], 1 + + mov eax, 0xffffffff + xor edx, edx + div [scl_width_pixels] + mov [scl_width_pixels_inv], eax + mov eax, 0xffffffff + xor edx, edx + div [scl_height_pixels] + mov [scl_height_pixels_inv], eax + + mov eax, [src_type] + cmp eax, Image.bpp8g + je .bilinear.bpp8g + cmp eax, Image.bpp24 + je .bilinear.bpp24 + cmp eax, Image.bpp32 + je .bilinear.bpp32 + mov ecx, LIBIMG_ERROR_BIT_DEPTH + jmp .error + + .bilinear.bpp8g: + mov esi, [src_data] + mov [dst_y], 0 + mov eax, 0 ; mov eax, [dst_y] + .bilinear.bpp8g.line: + mov esi, [src_data] + mov [dst_x], 0 + imul eax, [crop_height_pixels_m1] + xor edx, edx + div [scl_height_pixels] + mov [rem_y], edx + imul eax, [src_width_bytes] + add esi, eax + mov [src_base], esi + mov eax, 0 ; mov eax, [dst_x] + + .bilinear.bpp8g.pixel: + mov esi, [src_base] + + imul eax, [crop_width_pixels_m1] + xor edx, edx + div [scl_width_pixels] + add esi, eax + + mov ax, word[esi] + add esi, [src_width_pixels] + mov bx, word[esi] + mov esi, edx + movzx edx, ah + and eax, 0x000000ff + movzx ecx, bh + and ebx, 0x000000ff + + imul edx, esi + imul ecx, esi + neg esi + add esi, [scl_width_pixels] + imul eax, esi + imul ebx, esi + add eax, edx + add ebx, ecx + mov esi, [scl_width_pixels_inv] + mul esi + mov ecx, edx + mov eax, ebx + mul esi + mov eax, edx + + mov edx, [rem_y] + imul eax, edx + neg edx + add edx, [scl_height_pixels] + imul ecx, edx + add eax, ecx + mul [scl_height_pixels_inv] + mov byte[edi], dl + add edi, 1 + + add [dst_x], 1 + mov eax, [dst_x] + cmp eax, [scl_width_pixels] + jne .bilinear.bpp8g.pixel + + add [dst_y], 1 + mov eax, [dst_y] + cmp eax, [scl_height_pixels] + jne .bilinear.bpp8g.line + + mov eax, [_dst] + jmp .quit + + + .bilinear.bpp24: + mov esi, [src_data] + mov [dst_y], 0 + mov eax, 0 ; mov eax, [dst_y] + .bilinear.bpp24.line: + mov esi, [src_data] + mov [dst_x], 0 + imul eax, [crop_height_pixels_m1] + xor edx, edx + div [scl_height_pixels] + mov [rem_y], edx + imul eax, [src_width_bytes] + add esi, eax + mov [src_base], esi + mov eax, 0 ; mov eax, [dst_x] + + .bilinear.bpp24.pixel: + mov esi, [src_base] + + imul eax, [crop_width_pixels_m1] + xor edx, edx + div [scl_width_pixels] + lea eax, [eax*3] + add esi, eax + + mov [rem_x], edx + sub esi, 1 + mov [src_x], esi + +repeat 3 + mov edx, [rem_x] + add [src_x], 1 + mov esi, [src_x] + + mov al, byte[esi] + mov ah, byte[esi + 3] + add esi, [src_width_bytes] + movzx ebx, byte[esi] + movzx ecx, byte[esi + 3] + mov esi, edx + movzx edx, ah + and eax, 0x000000ff + + imul edx, esi + imul ecx, esi + neg esi + add esi, [scl_width_pixels] + imul eax, esi + imul ebx, esi + add eax, edx + add ebx, ecx + mov esi, [scl_width_pixels_inv] + mul esi + mov ecx, edx + mov eax, ebx + mul esi + mov eax, edx + + mov edx, [rem_y] + imul eax, edx + neg edx + add edx, [scl_height_pixels] + imul ecx, edx + add eax, ecx + mul [scl_height_pixels_inv] + mov byte[edi], dl + add edi, 1 +end repeat + + add [dst_x], 1 + mov eax, [dst_x] + cmp eax, [scl_width_pixels] + jne .bilinear.bpp24.pixel + + add [dst_y], 1 + mov eax, [dst_y] + cmp eax, [scl_height_pixels] + jne .bilinear.bpp24.line + + mov eax, [_dst] + jmp .quit + + .bilinear.bpp32: + mov esi, [src_data] + mov [dst_y], 0 + mov eax, 0 ; mov eax, [dst_y] + .bilinear.bpp32.line: + mov esi, [src_data] + mov [dst_x], 0 + imul eax, [crop_height_pixels_m1] + xor edx, edx + div [scl_height_pixels] + mov [rem_y], edx + imul eax, [src_width_bytes] + add esi, eax + mov [src_base], esi + mov eax, 0 ; mov eax, [dst_x] + + .bilinear.bpp32.pixel: + mov esi, [src_base] + + imul eax, [crop_width_pixels_m1] + xor edx, edx + div [scl_width_pixels] + shl eax, 2 + add esi, eax + + mov [rem_x], edx + sub esi, 1 + mov [src_x], esi + +repeat 4 + mov edx, [rem_x] + add [src_x], 1 + mov esi, [src_x] + + mov al, byte[esi] + mov ah, byte[esi + 4] + add esi, [src_width_bytes] + movzx ebx, byte[esi] + movzx ecx, byte[esi + 4] + mov esi, edx + movzx edx, ah + and eax, 0x000000ff + + imul edx, esi + imul ecx, esi + neg esi + add esi, [scl_width_pixels] + imul eax, esi + imul ebx, esi + add eax, edx + add ebx, ecx + mov esi, [scl_width_pixels_inv] + mul esi + mov ecx, edx + mov eax, ebx + mul esi + mov eax, edx + + mov edx, [rem_y] + imul eax, edx + neg edx + add edx, [scl_height_pixels] + imul ecx, edx + add eax, ecx + mul [scl_height_pixels_inv] + mov byte[edi], dl + add edi, 1 +end repeat + + add [dst_x], 1 + mov eax, [dst_x] + cmp eax, [scl_width_pixels] + jne .bilinear.bpp32.pixel + + add [dst_y], 1 + mov eax, [dst_y] + cmp eax, [scl_height_pixels] + jne .bilinear.bpp32.line + + mov eax, [_dst] + jmp .quit + + + .error: + xor eax, eax + .quit: + ret + +endp +