From afa564b4d739c088490a3dc8f50da48c6571a94a Mon Sep 17 00:00:00 2001 From: hidnplayr Date: Wed, 12 Aug 2015 16:01:13 +0000 Subject: [PATCH] VNC Viewer: Preliminary ZRLE support. git-svn-id: svn://kolibrios.org@5717 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/network/vncc/rre.inc | 14 +- programs/network/vncc/vncc.asm | 7 +- programs/network/vncc/zrle.inc | 534 +++++++++++++++++++++++++++++++++ 3 files changed, 547 insertions(+), 8 deletions(-) create mode 100644 programs/network/vncc/zrle.inc diff --git a/programs/network/vncc/rre.inc b/programs/network/vncc/rre.inc index 333c3e639a..fb10d18fd2 100644 --- a/programs/network/vncc/rre.inc +++ b/programs/network/vncc/rre.inc @@ -15,13 +15,13 @@ pixel_to_24bpp: ; returns in ecx push eax - @@: - lea eax, [esi+BYTES_PER_PIXEL] - cmp [datapointer], eax - jae @f - call read_data.more - jmp @b - @@: +; @@: +; lea eax, [esi+BYTES_PER_PIXEL] +; cmp [datapointer], eax +; jae @f +; call read_data.more +; jmp @b +; @@: if BITS_PER_PIXEL = 8 diff --git a/programs/network/vncc/vncc.asm b/programs/network/vncc/vncc.asm index 0a9661e1e4..ba16e4f889 100644 --- a/programs/network/vncc/vncc.asm +++ b/programs/network/vncc/vncc.asm @@ -94,6 +94,7 @@ include "raw.inc" include "copyrect.inc" include "rre.inc" include "trle.inc" +include "zrle.inc" include "des.inc" START: @@ -353,6 +354,10 @@ update_gui dd 0 mouse_dd dd 0 update_framebuffer dd 0 +deflate_buffer dd 0 +deflate_length dd ? +deflate_str dd ? + URLbox edit_box 235, 70, 20, 0xffffff, 0x6f9480, 0, 0, 0, 65535, serveraddr, mouse_dd, ed_focus, 0, 0 USERbox edit_box 215, 90, 10, 0xffffff, 0x6f9480, 0, 0, 0, 127, username, mouse_dd, ed_focus, 0, 0 PASSbox edit_box 215, 90, 30, 0xffffff, 0x6f9480, 0, 0, 0, 127, password, mouse_dd, ed_pass, 0, 0 @@ -407,7 +412,7 @@ import box_lib,\ scrollbar_h_mouse, "scrollbar_h_mouse" import archiver,\ - deflate_unpack, "deflate_unpack" + deflate_unpack2, "deflate_unpack2" name db "VNC viewer " .dash db 0, " " diff --git a/programs/network/vncc/zrle.inc b/programs/network/vncc/zrle.inc new file mode 100644 index 0000000000..ce49f5d208 --- /dev/null +++ b/programs/network/vncc/zrle.inc @@ -0,0 +1,534 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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_data+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: + ; load pixel value + call pixel_to_24bpp + +;;; + + ; 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 + +;;; + + DEBUGF 1, "RAW tile\n" + .raw_line: + mov ebx, [subrectangle.width] + .raw_pixel: + call pixel_to_24bpp + mov word[edi], cx + shr ecx, 16 + add edi, 2 + mov byte[edi], cl + inc edi + 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" + call pixel_to_24bpp + mov eax, ecx + shr eax, 16 + + mov [palettesize], 1 + mov [palette], ecx + + .solid_line: + mov ebx, [subrectangle.width] + .solid_pixel: + mov [edi], cx + add edi, 2 + mov [edi], al + 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 \ No newline at end of file