;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; Copyright (C) KolibriOS team 2010-2015. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;; VNC client for KolibriOS ;; ;; ;; ;; Written by hidnplayr@kolibrios.org ;; ;; ;; ;; GNU GENERAL PUBLIC LICENSE ;; ;; Version 2, June 1991 ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; deflate_callback: mov eax, [deflate_length] mov ecx, [esp+8] mov [ecx], eax mov eax, [deflate_buffer] ret 8 encoding_ZRLE: DEBUGF 2, "ZRLE\n" @@: lea eax, [esi+4] cmp [datapointer], eax jae @f call read_data.more jmp @b @@: lodsd bswap eax ; number of packed bytes DEBUGF 2, "packed length=%u bytes\n", eax @@: push eax add eax, esi cmp [datapointer], eax jae @f call read_data.more pop eax jmp @b @@: pop ecx lea eax, [esi+ecx] push eax ; end of data ptr cmp [deflate_buffer], 0 ; first chunk of the stream? jne @f lodsw ; load zlib header cmp ax, 0x9c78 ; default compression? jne .deflate_fail sub ecx, 2 ; subtract 2 byte header ; invoke deflate_init ; mov [deflate_str], eax @@: sub ecx, 4 ; subtract 4 byte check value trailer mov [deflate_buffer], esi mov [deflate_length], ecx ; mov eax, [deflate_str] push eax ; allocate place on stack invoke deflate_unpack2, deflate_callback, 0, esp ; unpack the data pop ecx ; get size in ecx test eax, eax jz .deflate_fail push eax DEBUGF 2, "%u bytes unpacked succesfully\n", ecx test ecx, ecx jz .fail mov esi, eax mov [subrectangle.x], 0 mov [subrectangle.y], 0 .tile: mov eax, [rectangle.width] sub eax, [subrectangle.x] cmp eax, 64 jb @f mov eax, 64 @@: mov [subrectangle.width], eax mov edx, [rectangle.height] sub edx, [subrectangle.y] cmp edx, 64 jb @f mov edx, 64 @@: mov [subrectangle.height], edx DEBUGF 1, "Subrectangle: x=%u y=%u width=%u height=%u ", \ [subrectangle.x], [subrectangle.y], [subrectangle.width], [subrectangle.height] ; Calculate first pixel pos mov eax, [rectangle.y] add eax, [subrectangle.y] movzx ebx, [screen.width] mul ebx add eax, [rectangle.x] add eax, [subrectangle.x] lea edi, [framebuffer+eax*3] ; Calculate offset between two rows of pixels movzx eax, [screen.width] sub eax, [subrectangle.width] lea ebp, [eax*3] mov edx, [subrectangle.height] ;;;; lodsb ; subencoding type DEBUGF 1, "encoding=%u\n", al test al, al jz .raw cmp al, 1 je .solid cmp al, 16 jbe .palette_packed cmp al, 127 je .reuse_palette jb .invalid and al, 0x7f jz .plain_rle cmp al, 1 je .prle_reuse_palette ; Palette Run Length Encoded tile mov [palettesize], al call create_palette .prle_reuse_palette: DEBUGF 1, "Pallete RLE tile\n" mov eax, 1 .prle_line: mov ebx, [subrectangle.width] .prle_pixel: dec eax jz .prle_reload mov word[edi], cx rol ecx, 16 add edi, 2 mov byte[edi], cl rol ecx, 16 inc edi dec ebx jnz .prle_pixel add edi, ebp dec edx jnz .prle_line jmp .next_tile .prle_reload: ;;; ; load palette index and get color from palette xor eax, eax lodsb push ebx mov bl, al and al, 0x7f mov ecx, [palette+eax*4] ; run length follows? xor eax, eax test bl, 0x80 pop ebx jz .plength_ok ;;; ; load runlength push ebx xor eax, eax xor ebx, ebx @@: lodsb cmp al, 255 jne @f add ebx, eax jmp @b @@: add eax, ebx pop ebx .plength_ok: add eax, 2 jmp .prle_pixel ; Run Length Encoded tile .plain_rle: DEBUGF 1, "Plain RLE tile\n" mov eax, 1 .rle_line: mov ebx, [subrectangle.width] .rle_pixel: dec eax jz .rle_reload mov word[edi], cx rol ecx, 16 add edi, 2 mov byte[edi], cl rol ecx, 16 inc edi dec ebx jnz .rle_pixel add edi, ebp dec edx jnz .rle_line jmp .next_tile .rle_reload: ; TODO: check for buffer underrun ; load pixel value call load_cpixel mov ecx, eax ; load length xor eax, eax push ebx xor ebx, ebx @@: lodsb cmp al, 255 jne @f add ebx, eax jmp @b @@: add eax, ebx add eax, 2 pop ebx jmp .rle_pixel .reuse_palette: cmp [palettesize], 1 jne .reuse_palette_ mov ecx, [palette] mov eax, ecx shr eax, 16 jmp .solid_line ; Palette packed tile .palette_packed: DEBUGF 1, "Palette packed tile\n" mov [palettesize], al call create_palette .reuse_palette_: cmp [palettesize], 2 je .palette_1bit cmp [palettesize], 4 jbe .palette_2bit jmp .palette_4bit .palette_1bit: DEBUGF 1, "1-bit palette\n" .palette_1bit_line: mov ebx, [subrectangle.width] .palette_1bit_byte: lodsb rol al, 1 mov ecx, eax and eax, 0x1 mov eax, [palette+4*eax] stosw shr eax, 16 stosb dec ebx jz .palette_1bit_next_line rol cl, 1 mov eax, ecx and eax, 0x1 mov eax, [palette+4*eax] stosw shr eax, 16 stosb dec ebx jz .palette_1bit_next_line rol cl, 1 mov eax, ecx and eax, 0x1 mov eax, [palette+4*eax] stosw shr eax, 16 stosb dec ebx jz .palette_1bit_next_line rol cl, 1 mov eax, ecx and eax, 0x1 mov eax, [palette+4*eax] stosw shr eax, 16 stosb dec ebx jz .palette_1bit_next_line rol cl, 1 mov eax, ecx and eax, 0x1 mov eax, [palette+4*eax] stosw shr eax, 16 stosb dec ebx jz .palette_1bit_next_line rol cl, 1 mov eax, ecx and eax, 0x1 mov eax, [palette+4*eax] stosw shr eax, 16 stosb dec ebx jz .palette_1bit_next_line rol cl, 1 mov eax, ecx and eax, 0x1 mov eax, [palette+4*eax] stosw shr eax, 16 stosb dec ebx jz .palette_1bit_next_line rol cl, 1 and ecx, 0x1 mov eax, [palette+4*ecx] stosw shr eax, 16 stosb dec ebx jnz .palette_1bit_byte .palette_1bit_next_line: add edi, ebp dec edx jnz .palette_1bit_line jmp .next_tile .palette_2bit: DEBUGF 1, "2-bit palette\n" .palette_2bit_line: mov ebx, [subrectangle.width] .palette_2bit_byte: lodsb mov ecx, eax and eax, 0xc0 shr eax, 4 mov eax, [palette+eax] stosw shr eax, 16 stosb dec ebx jz .palette_2bit_next_line mov eax, ecx and eax, 0x30 shr eax, 2 mov eax, [palette+eax] stosw shr eax, 16 stosb dec ebx jz .palette_2bit_next_line mov eax, ecx and eax, 0x0c mov eax, [palette+eax] stosw shr eax, 16 stosb dec ebx jz .palette_2bit_next_line and ecx, 0x03 mov eax, [palette+4*ecx] stosw shr eax, 16 stosb dec ebx jnz .palette_2bit_byte .palette_2bit_next_line: add edi, ebp dec edx jnz .palette_2bit_line jmp .next_tile .palette_4bit: DEBUGF 1, "4-bit palette\n" .palette_4bit_line: mov ebx, [subrectangle.width] .palette_4bit_byte: lodsb mov cl, al and eax, 0xf0 shr eax, 2 mov eax, [palette+eax] stosw shr eax, 16 stosb dec ebx jz .palette_4bit_next_line and ecx, 0x0f shl ecx, 2 mov eax, [palette+ecx] stosw shr eax, 16 stosb dec ebx jnz .palette_4bit_byte .palette_4bit_next_line: add edi, ebp dec edx jnz .palette_4bit_line jmp .next_tile ; RAW tile .raw: push edx mov eax, [subrectangle.width] mul [subrectangle.height] lea eax, [eax*3] pop edx ; TODO: check for buffer underrun DEBUGF 1, "RAW tile\n" .raw_line: mov ebx, [subrectangle.width] .raw_pixel: call load_cpixel stosw shr eax, 16 stosb dec ebx jnz .raw_pixel add edi, ebp dec edx jnz .raw_line jmp .next_tile ; Single color tile .solid: DEBUGF 1, "Solid tile\n" ; TODO: check for buffer underrun call load_cpixel mov ecx, eax shr ecx, 16 mov [palettesize], 1 mov [palette], eax .solid_line: mov ebx, [subrectangle.width] .solid_pixel: stosw mov [edi], cl inc edi dec ebx jnz .solid_pixel add edi, ebp dec edx jnz .solid_line ; jmp .next_tile ; Go to the next tile .next_tile: mov eax, [subrectangle.x] add eax, 64 cmp eax, [rectangle.width] jae .next_row mov [subrectangle.x], eax jmp .tile .next_row: mov [subrectangle.x], 0 mov eax, [subrectangle.y] add eax, 64 cmp eax, [rectangle.height] jae .done mov [subrectangle.y], eax jmp .tile .done: DEBUGF 1, "ZRLE complete!\n" pop ecx mcall 68, 13 ; free the unpacked data pop esi jmp next_rectangle .invalid: DEBUGF 2, "Invalid subencoding type!\n" .fail: DEBUGF 2, "ZRLE failed!\n" pop ecx mcall 68, 13 ; free unpacked data pop esi jmp next_rectangle .deflate_fail: DEBUGF 2,"Unpacking failed!\n" pop esi jmp next_rectangle