Commit 937b906f authored by dscho's avatar dscho

ZRLE no longer uses C++, but C

parent f41eee75
......@@ -22,7 +22,8 @@ Occasional important patches were sent by (in order I found the names in my
archives and please don't beat me, if I forgot you, but just send me an
email!): Akira Hatakeyama, Karl J. Runge, Justin "Zippy" Dearing,
Oliver Mihatsch, Greg Sternberg, Werner Hofer, Giampiero Giancipoli,
Glenn Mabutt, Paul Kreiner, Erik Kunze, Mike Frysinger.
Glenn Mabutt, Paul Kreiner, Erik Kunze, Mike Frysinger, Martin Waitz,
Mark McLoughlin.
Probably I forgot quite a few people sending a patch here and there, which
really made a difference. Without those, some obscure bugs still would
......
Mark sent me patches to no longer need C++ for ZRLE encoding!
added --disable-cxx Option for configure
x11vnc changes from Karl Runge:
- Changed all those whimpy printf(...)'s into manly fprintf(stdxxx,...)'s.
......
CFLAGS=-g
CFLAGS=-g -Wall
SUBDIRS=. examples contrib vncterm classes libvncclient test
DIST_SUBDIRS=examples contrib vncterm classes libvncclient test
......@@ -11,28 +11,20 @@ includedir=$(prefix)/include/rfb
include_HEADERS=rfb/rfb.h rfb/rfbconfig.h rfb/rfbint.h rfb/rfbproto.h \
rfb/keysym.h rfb/rfbregion.h rfb/rfbclient.h
noinst_HEADERS=d3des.h zrleDecode.h zrleEncode.h rfb/default8x16.h \
rdr/Exception.h rdr/FdInStream.h rdr/FdOutStream.h \
rdr/FixedMemOutStream.h rdr/InStream.h rdr/MemInStream.h \
rdr/MemOutStream.h rdr/NullOutStream.h rdr/OutStream.h \
rdr/ZlibInStream.h rdr/ZlibOutStream.h rdr/types.h
ZRLE_SRCS=zrle.cxx rdr/FdInStream.cxx rdr/FdOutStream.cxx rdr/InStream.cxx \
rdr/NullOutStream.cxx rdr/ZlibInStream.cxx rdr/ZlibOutStream.cxx
noinst_HEADERS=d3des.h rfb/default8x16.h zrleoutstream.h \
zrlepalettehelper.h zrletypes.h
EXTRA_DIST=tableinit24.c tableinittctemplate.c tabletranstemplate.c \
tableinitcmtemplate.c tabletrans24template.c $(ZRLE_SRCS)
tableinitcmtemplate.c tabletrans24template.c \
zrleencodetemplate.c
LIB_SRCS = main.c rfbserver.c rfbregion.c auth.c sockets.c \
stats.c corre.c hextile.c rre.c translate.c cutpaste.c \
zlib.c tight.c httpd.c cursor.c font.c \
draw.c selbox.c d3des.c vncauth.c cargs.c
draw.c selbox.c d3des.c vncauth.c cargs.c \
zrle.c zrleoutstream.c zrlepalettehelper.c
if HAVE_CXX
libvncserver_a_SOURCES=$(LIB_SRCS) $(ZRLE_SRCS)
else
libvncserver_a_SOURCES=$(LIB_SRCS)
endif
lib_LIBRARIES=libvncserver.a
......
This diff is collapsed.
#! /bin/sh
# Run this to generate all the initial makefiles, etc.
srcdir=`dirname $0`
test -z "$srcdir" && srcdir=.
DIE=0
AUTOMAKE=automake-1.4
ACLOCAL=aclocal-1.4
($AUTOMAKE --version) < /dev/null > /dev/null 2>&1 || {
AUTOMAKE=automake
ACLOCAL=aclocal
}
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have autoconf installed to compile libvncserver."
echo "Download the appropriate package for your distribution,"
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
DIE=1
}
($AUTOMAKE --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have automake installed to compile libvncserver."
echo "Get ftp://sourceware.cygnus.com/pub/automake/automake-1.4.tar.gz"
echo "(or a newer version if it is available)"
DIE=1
}
if test "$DIE" -eq 1; then
exit 1
fi
(test -f $srcdir/rfb/rfb.h) || {
echo "You must run this script in the top-level libvncserver directory"
exit 1
}
if test -z "$*"; then
echo "I am going to run ./configure with no arguments - if you wish "
echo "to pass any to it, please specify them on the $0 command line."
fi
$ACLOCAL $ACLOCAL_FLAGS
autoheader
$AUTOMAKE --add-missing --copy
autoconf
echo "Running ./configure --enable-maintainer-mode" "$@"
$srcdir/configure --enable-maintainer-mode "$@"
echo "Now type 'make' to compile libvncserver."
......@@ -65,8 +65,6 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
AMTAR = @AMTAR@
AWK = @AWK@
CC = @CC@
CCLD = @CCLD@
CXX = @CXX@
DEPDIR = @DEPDIR@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
PACKAGE = @PACKAGE@
......
......@@ -155,9 +155,6 @@
/* Define to 1 if `vfork' works. */
#undef HAVE_WORKING_VFORK
/* Use zrle compression; needs a c++ compiler */
#undef HAVE_ZRLE
/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
slash. */
#undef LSTAT_FOLLOWS_SLASHED_SYMLINK
......
This diff is collapsed.
# Process this file with autoconf to produce a configure script.
AC_INIT(LibVNCServer, 0.6pre, http://sourceforge.net/projects/libvncserver)
AM_INIT_AUTOMAKE(LibVNCServer, 0.6pre)
AM_CONFIG_HEADER([config.h])
AM_CONFIG_HEADER(config.h)
AX_PREFIX_CONFIG_H([rfb/rfbconfig.h])
# Checks for programs.
......@@ -62,42 +62,17 @@ AC_ARG_WITH(libz,
if test "x$with_zlib" = "xyes" -a "x$with_libz" = "xyes"; then
AC_CHECK_HEADER(zlib.h, HAVE_ZLIB_H="true")
fi
if test ! -z "$HAVE_PTHREAD_H"; then
AC_CHECK_LIB(pthread, pthread_mutex_lock)
AC_CHECK_LIB(pthread, pthread_mutex_lock, HAVE_LIBPTHREAD="true")
fi
AM_CONDITIONAL(HAVE_LIBPTHREAD, test ! -z "$HAVE_LIBPTHREAD")
AC_ARG_ENABLE(cxx,
[ --disable-cxx disable use of c++],
[ disable_cxx=yes],)
if test -z "$disable_cxx"; then
AC_CHECK_PROGS(CXX,[g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC],none)
AC_PROG_CXX
else
CXX=none
fi
if test ! -z "$HAVE_ZLIB_H"; then
AC_CHECK_LIB(z, deflate, , HAVE_ZLIB_H="")
if test ! -z "$HAVE_JPEGLIB_H" -a ! -z "$HAVE_ZLIB_H"; then
AC_CHECK_LIB(jpeg, jpeg_CreateCompress)
fi
if test ! -z "$HAVE_ZLIB_H"; then
# check for c++, but don't fail if not found
AH_TEMPLATE(HAVE_ZRLE, [Use zrle compression; needs a c++ compiler])
if test x$CXX != xnone; then
AC_DEFINE(HAVE_ZRLE)
if test -z "$CXX"; then
CCLD="\$(CXX)"
else
CCLD="$CXX"
fi
fi
fi
else
CXX=none
fi
AM_CONDITIONAL(HAVE_CXX, test x$CXX != xnone -a ! -z "$HAVE_ZLIB_H")
AC_SUBST(CCLD)
if test ! -z "$HAVE_PTHREAD_H"; then
AC_CHECK_LIB(pthread, pthread_mutex_lock)
AC_CHECK_LIB(pthread, pthread_mutex_lock, HAVE_LIBPTHREAD="true")
fi
AM_CONDITIONAL(HAVE_LIBPTHREAD, test ! -z "$HAVE_LIBPTHREAD")
# Checks for header files.
AC_HEADER_STDC
......
......@@ -65,8 +65,6 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
AMTAR = @AMTAR@
AWK = @AWK@
CC = @CC@
CCLD = @CCLD@
CXX = @CXX@
DEPDIR = @DEPDIR@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
PACKAGE = @PACKAGE@
......@@ -122,6 +120,7 @@ am__depfiles_maybe = depfiles
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/x11vnc.Po ./$(DEPDIR)/zippy.Po
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
DIST_SOURCES = $(x11vnc_SOURCES) $(zippy_SOURCES)
DIST_COMMON = ChangeLog Makefile.am Makefile.in
......
......@@ -65,8 +65,6 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
AMTAR = @AMTAR@
AWK = @AWK@
CC = @CC@
CCLD = @CCLD@
CXX = @CXX@
DEPDIR = @DEPDIR@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
PACKAGE = @PACKAGE@
......@@ -218,6 +216,7 @@ am__depfiles_maybe = depfiles
@AMDEP_TRUE@ ./$(DEPDIR)/vncev.Po
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
DIST_SOURCES = blooptest.c colourmaptest.c example.c fontsel.c mac.c \
pnmshow.c pnmshow24.c regiontest.c simple.c simple15.c \
......
......@@ -65,8 +65,6 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
AMTAR = @AMTAR@
AWK = @AWK@
CC = @CC@
CCLD = @CCLD@
CXX = @CXX@
DEPDIR = @DEPDIR@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
PACKAGE = @PACKAGE@
......@@ -126,6 +124,7 @@ am__depfiles_maybe = depfiles
@AMDEP_TRUE@ ./$(DEPDIR)/sockets.Po ./$(DEPDIR)/vncviewer.Po
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
DIST_SOURCES = $(libvncclient_a_SOURCES) $(client_test_SOURCES)
DIST_COMMON = Makefile.am Makefile.in
......
......@@ -89,13 +89,13 @@ extern "C"
the library and your application (at least the parts including rfb.h)
with the same support for pthreads. */
#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
#ifdef LIBVNCSERVER_HAVE_ZRLE
#ifdef LIBVNCSERVER_HAVE_LIBZ
#define rfbInitServer rfbInitServerWithPthreadsAndZRLE
#else
#define rfbInitServer rfbInitServerWithPthreadsButWithoutZRLE
#endif
#else
#ifdef LIBVNCSERVER_HAVE_ZRLE
#ifdef LIBVNCSERVER_HAVE_LIBZ
#define rfbInitServer rfbInitServerWithoutPthreadsButWithZRLE
#else
#define rfbInitServer rfbInitServerWithoutPthreadsAndZRLE
......@@ -464,7 +464,7 @@ typedef struct _rfbClientRec {
COND(updateCond);
#endif
#ifdef LIBVNCSERVER_HAVE_ZRLE
#ifdef LIBVNCSERVER_HAVE_LIBZ
void* zrleData;
#endif
......@@ -661,7 +661,7 @@ extern void rfbSetCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr c,rfbBool freeO
extern void defaultPtrAddEvent(int buttonMask,int x,int y,rfbClientPtr cl);
/* zrle.c */
#ifdef LIBVNCSERVER_HAVE_ZRLE
#ifdef LIBVNCSERVER_HAVE_LIBZ
extern rfbBool rfbSendRectEncodingZRLE(rfbClientPtr cl, int x, int y, int w,int h);
extern void FreeZrleData(rfbClientPtr cl);
#endif
......
......@@ -347,7 +347,7 @@ typedef struct {
#ifdef LIBVNCSERVER_BACKCHANNEL
#define rfbEncodingBackChannel 15
#endif
#ifdef LIBVNCSERVER_HAVE_ZRLE
#ifdef LIBVNCSERVER_HAVE_LIBZ
#define rfbEncodingZRLE 16
#endif
......
......@@ -283,7 +283,7 @@ rfbNewTCPOrUDPClient(rfbScreen,sock,isUDP)
cl->preferredEncoding = rfbEncodingRaw;
cl->correMaxWidth = 48;
cl->correMaxHeight = 48;
#ifdef LIBVNCSERVER_HAVE_ZRLE
#ifdef LIBVNCSERVER_HAVE_LIBZ
cl->zrleData = 0;
#endif
......@@ -406,7 +406,7 @@ rfbClientConnectionGone(cl)
if (cl->next)
cl->next->prev = cl->prev;
#ifdef LIBVNCSERVER_HAVE_ZRLE
#ifdef LIBVNCSERVER_HAVE_LIBZ
FreeZrleData(cl);
#endif
......@@ -843,7 +843,7 @@ rfbProcessClientNormalMessage(cl)
}
break;
#endif
#ifdef LIBVNCSERVER_HAVE_ZRLE
#ifdef LIBVNCSERVER_HAVE_LIBZ
case rfbEncodingZRLE:
if (cl->preferredEncoding == -1) {
cl->preferredEncoding = enc;
......@@ -1309,7 +1309,7 @@ rfbSendFramebufferUpdate(cl, givenUpdateRegion)
break;
#endif
#endif
#ifdef LIBVNCSERVER_HAVE_ZRLE
#ifdef LIBVNCSERVER_HAVE_LIBZ
case rfbEncodingZRLE:
if (!rfbSendRectEncodingZRLE(cl, x, y, w, h)) {
sraRgnDestroy(updateRegion);
......
......@@ -65,8 +65,6 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
AMTAR = @AMTAR@
AWK = @AWK@
CC = @CC@
CCLD = @CCLD@
CXX = @CXX@
DEPDIR = @DEPDIR@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
PACKAGE = @PACKAGE@
......@@ -109,6 +107,7 @@ am__depfiles_maybe = depfiles
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/tight-1.Po
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
DIST_SOURCES = tight-1.c
DIST_COMMON = Makefile.am Makefile.in
......
......@@ -65,8 +65,6 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
AMTAR = @AMTAR@
AWK = @AWK@
CC = @CC@
CCLD = @CCLD@
CXX = @CXX@
DEPDIR = @DEPDIR@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
PACKAGE = @PACKAGE@
......@@ -105,18 +103,18 @@ CONFIG_CLEAN_FILES =
noinst_PROGRAMS = VNCommand$(EXEEXT) example$(EXEEXT)
PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
am__objects_1 = VNConsole.$(OBJEXT)
@LINUX_TRUE@am_LinuxVNC_OBJECTS = LinuxVNC.$(OBJEXT) $(am__objects_1)
am__objects_2 = VNConsole.$(OBJEXT)
@LINUX_TRUE@am_LinuxVNC_OBJECTS = LinuxVNC.$(OBJEXT) $(am__objects_2)
LinuxVNC_OBJECTS = $(am_LinuxVNC_OBJECTS)
LinuxVNC_LDADD = $(LDADD)
LinuxVNC_DEPENDENCIES = ../libvncserver.a
LinuxVNC_LDFLAGS =
am_VNCommand_OBJECTS = VNCommand.$(OBJEXT) $(am__objects_1)
am_VNCommand_OBJECTS = VNCommand.$(OBJEXT) $(am__objects_2)
VNCommand_OBJECTS = $(am_VNCommand_OBJECTS)
VNCommand_LDADD = $(LDADD)
VNCommand_DEPENDENCIES = ../libvncserver.a
VNCommand_LDFLAGS =
am_example_OBJECTS = example.$(OBJEXT) $(am__objects_1)
am_example_OBJECTS = example.$(OBJEXT) $(am__objects_2)
example_OBJECTS = $(am_example_OBJECTS)
example_LDADD = $(LDADD)
example_DEPENDENCIES = ../libvncserver.a
......@@ -133,6 +131,7 @@ am__depfiles_maybe = depfiles
@AMDEP_TRUE@ ./$(DEPDIR)/VNConsole.Po ./$(DEPDIR)/example.Po
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
DIST_SOURCES = $(LinuxVNC_SOURCES) $(VNCommand_SOURCES) \
$(example_SOURCES)
......
/*
* Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
* Copyright (C) 2003 Sun Microsystems, Inc.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
/*
* zrle.c
*
* Routines to implement Zlib Run-length Encoding (ZRLE).
*/
#include <rfb/rfb.h>
#include <zrleoutstream.h>
#define GET_IMAGE_INTO_BUF(tx,ty,tw,th,buf) \
char *fbptr = (cl->screen->frameBuffer \
+ (cl->screen->paddedWidthInBytes * ty) \
+ (tx * (cl->screen->bitsPerPixel / 8))); \
\
(*cl->translateFn)(cl->translateLookupTable, &cl->screen->rfbServerFormat,\
&cl->format, fbptr, (char*)buf, \
cl->screen->paddedWidthInBytes, tw, th);
#define EXTRA_ARGS , rfbClientPtr cl
#define BPP 8
#include <zrleencodetemplate.c>
#undef BPP
#define BPP 16
#include <zrleencodetemplate.c>
#undef BPP
#define BPP 32
#include <zrleencodetemplate.c>
#define CPIXEL 24A
#include <zrleencodetemplate.c>
#undef CPIXEL
#define CPIXEL 24B
#include <zrleencodetemplate.c>
#undef CPIXEL
#undef BPP
/*
* zrleBeforeBuf contains pixel data in the client's format. It must be at
* least one pixel bigger than the largest tile of pixel data, since the
* ZRLE encoding algorithm writes to the position one past the end of the pixel
* data.
*/
static char zrleBeforeBuf[rfbZRLETileWidth * rfbZRLETileHeight * 4 + 4];
/*
* rfbSendRectEncodingZRLE - send a given rectangle using ZRLE encoding.
*/
rfbBool rfbSendRectEncodingZRLE(rfbClientPtr cl, int x, int y, int w, int h)
{
zrleOutStream* zos;
rfbFramebufferUpdateRectHeader rect;
rfbZRLEHeader hdr;
int i;
if (!cl->zrleData)
cl->zrleData = zrleOutStreamNew();
zos = cl->zrleData;
zos->in.ptr = zos->in.start;
zos->out.ptr = zos->out.start;
switch (cl->format.bitsPerPixel) {
case 8:
zrleEncode8( x, y, w, h, zos, zrleBeforeBuf, cl);
break;
case 16:
zrleEncode16(x, y, w, h, zos, zrleBeforeBuf, cl);
break;
case 32: {
rfbBool fitsInLS3Bytes
= ((cl->format.redMax << cl->format.redShift) < (1<<24) &&
(cl->format.greenMax << cl->format.greenShift) < (1<<24) &&
(cl->format.blueMax << cl->format.blueShift) < (1<<24));
rfbBool fitsInMS3Bytes = (cl->format.redShift > 7 &&
cl->format.greenShift > 7 &&
cl->format.blueShift > 7);
if ((fitsInLS3Bytes && !cl->format.bigEndian) ||
(fitsInMS3Bytes && cl->format.bigEndian))
{
zrleEncode24A(x, y, w, h, zos, zrleBeforeBuf, cl);
}
else if ((fitsInLS3Bytes && cl->format.bigEndian) ||
(fitsInMS3Bytes && !cl->format.bigEndian))
{
zrleEncode24B(x, y, w, h, zos, zrleBeforeBuf, cl);
}
else
{
zrleEncode32(x, y, w, h, zos, zrleBeforeBuf, cl);
}
}
break;
}
cl->rfbRectanglesSent[rfbEncodingZRLE]++;
cl->rfbBytesSent[rfbEncodingZRLE] += (sz_rfbFramebufferUpdateRectHeader
+ sz_rfbZRLEHeader + ZRLE_BUFFER_LENGTH(&zos->out));
if (cl->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbZRLEHeader
> UPDATE_BUF_SIZE)
{
if (!rfbSendUpdateBuf(cl))
return FALSE;
}
rect.r.x = Swap16IfLE(x);
rect.r.y = Swap16IfLE(y);
rect.r.w = Swap16IfLE(w);
rect.r.h = Swap16IfLE(h);
rect.encoding = Swap32IfLE(rfbEncodingZRLE);
memcpy(cl->updateBuf+cl->ublen, (char *)&rect,
sz_rfbFramebufferUpdateRectHeader);
cl->ublen += sz_rfbFramebufferUpdateRectHeader;
hdr.length = Swap32IfLE(ZRLE_BUFFER_LENGTH(&zos->out));
memcpy(cl->updateBuf+cl->ublen, (char *)&hdr, sz_rfbZRLEHeader);
cl->ublen += sz_rfbZRLEHeader;
/* copy into updateBuf and send from there. Maybe should send directly? */
for (i = 0; i < ZRLE_BUFFER_LENGTH(&zos->out);) {
int bytesToCopy = UPDATE_BUF_SIZE - cl->ublen;
if (i + bytesToCopy > ZRLE_BUFFER_LENGTH(&zos->out)) {
bytesToCopy = ZRLE_BUFFER_LENGTH(&zos->out) - i;
}
memcpy(cl->updateBuf+cl->ublen, (uint8_t*)zos->out.start + i, bytesToCopy);
cl->ublen += bytesToCopy;
i += bytesToCopy;
if (cl->ublen == UPDATE_BUF_SIZE) {
if (!rfbSendUpdateBuf(cl))
return FALSE;
}
}
return TRUE;
}
void FreeZrleData(rfbClientPtr cl)
{
if (cl->zrleData)
zrleOutStreamFree(cl->zrleData);
cl->zrleData = NULL;
}
/*
* Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
* Copyright (C) 2003 Sun Microsystems, Inc.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
/*
* Before including this file, you must define a number of CPP macros.
*
* BPP should be 8, 16 or 32 depending on the bits per pixel.
* GET_IMAGE_INTO_BUF should be some code which gets a rectangle of pixel data
* into the given buffer. EXTRA_ARGS can be defined to pass any other
* arguments needed by GET_IMAGE_INTO_BUF.
*
* Note that the buf argument to ZRLE_ENCODE needs to be at least one pixel
* bigger than the largest tile of pixel data, since the ZRLE encoding
* algorithm writes to the position one past the end of the pixel data.
*/
#include <zrleoutstream.h>
#include <zrlepalettehelper.h>
#include <assert.h>
/* __RFB_CONCAT2 concatenates its two arguments. __RFB_CONCAT2E does the same
but also expands its arguments if they are macros */
#ifndef __RFB_CONCAT2E
#define __RFB_CONCAT2(a,b) a##b
#define __RFB_CONCAT2E(a,b) __RFB_CONCAT2(a,b)
#endif
#ifdef CPIXEL
#define PIXEL_T __RFB_CONCAT2E(zrle_U,BPP)
#define zrleOutStreamWRITE_PIXEL __RFB_CONCAT2E(zrleOutStreamWriteOpaque,CPIXEL)
#define ZRLE_ENCODE __RFB_CONCAT2E(zrleEncode,CPIXEL)
#define ZRLE_ENCODE_TILE __RFB_CONCAT2E(zrleEncodeTile,CPIXEL)
#define BPPOUT 24
#else
#define PIXEL_T __RFB_CONCAT2E(zrle_U,BPP)
#define zrleOutStreamWRITE_PIXEL __RFB_CONCAT2E(zrleOutStreamWriteOpaque,BPP)
#define ZRLE_ENCODE __RFB_CONCAT2E(zrleEncode,BPP)
#define ZRLE_ENCODE_TILE __RFB_CONCAT2E(zrleEncodeTile,BPP)
#define BPPOUT BPP
#endif
#ifndef ZRLE_ONCE
#define ZRLE_ONCE
static const int bitsPerPackedPixel[] = {
0, 1, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
};
static zrlePaletteHelper paletteHelper;
#endif /* ZRLE_ONCE */
void ZRLE_ENCODE_TILE (PIXEL_T* data, int w, int h, zrleOutStream* os);
void ZRLE_ENCODE (int x, int y, int w, int h,
zrleOutStream* os, void* buf
EXTRA_ARGS
)
{
int ty;
for (ty = y; ty < y+h; ty += rfbZRLETileHeight) {
int tx, th = rfbZRLETileHeight;
if (th > y+h-ty) th = y+h-ty;
for (tx = x; tx < x+w; tx += rfbZRLETileWidth) {
int tw = rfbZRLETileWidth;
if (tw > x+w-tx) tw = x+w-tx;
GET_IMAGE_INTO_BUF(tx,ty,tw,th,buf);
ZRLE_ENCODE_TILE((PIXEL_T*)buf, tw, th, os);
}
}
zrleOutStreamFlush(os);
}
void ZRLE_ENCODE_TILE (PIXEL_T* data, int w, int h, zrleOutStream* os)
{
/* First find the palette and the number of runs */
zrlePaletteHelper *ph;
int runs = 0;
int singlePixels = 0;
rfbBool useRle;
rfbBool usePalette;
int estimatedBytes;
int plainRleBytes;
int i;
PIXEL_T* ptr = data;
PIXEL_T* end = ptr + h * w;
*end = ~*(end-1); /* one past the end is different so the while loop ends */
ph = &paletteHelper;
zrlePaletteHelperInit(ph);
while (ptr < end) {
PIXEL_T pix = *ptr;
if (*++ptr != pix) {
singlePixels++;
} else {
while (*++ptr == pix) ;
runs++;
}
zrlePaletteHelperInsert(ph, pix);
}
/* Solid tile is a special case */
if (ph->size == 1) {
zrleOutStreamWriteU8(os, 1);
zrleOutStreamWRITE_PIXEL(os, ph->palette[0]);
return;
}
// Try to work out whether to use RLE and/or a palette. We do this by
// estimating the number of bytes which will be generated and picking the
// method which results in the fewest bytes. Of course this may not result
// in the fewest bytes after compression...
useRle = FALSE;
usePalette = FALSE;
estimatedBytes = w * h * (BPPOUT/8); // start assuming raw
plainRleBytes = ((BPPOUT/8)+1) * (runs + singlePixels);
if (plainRleBytes < estimatedBytes) {
useRle = TRUE;
estimatedBytes = plainRleBytes;
}
if (ph->size < 128) {
int paletteRleBytes = (BPPOUT/8) * ph->size + 2 * runs + singlePixels;
if (paletteRleBytes < estimatedBytes) {
useRle = TRUE;
usePalette = TRUE;
estimatedBytes = paletteRleBytes;
}
if (ph->size < 17) {
int packedBytes = ((BPPOUT/8) * ph->size +
w * h * bitsPerPackedPixel[ph->size-1] / 8);
if (packedBytes < estimatedBytes) {
useRle = FALSE;
usePalette = TRUE;
estimatedBytes = packedBytes;
}
}
}
if (!usePalette) ph->size = 0;
zrleOutStreamWriteU8(os, (useRle ? 128 : 0) | ph->size);
for (i = 0; i < ph->size; i++) {
zrleOutStreamWRITE_PIXEL(os, ph->palette[i]);
}
if (useRle) {
PIXEL_T* ptr = data;
PIXEL_T* end = ptr + w * h;
PIXEL_T* runStart;
PIXEL_T pix;
while (ptr < end) {
int len;
runStart = ptr;
pix = *ptr++;
while (*ptr == pix && ptr < end)
ptr++;
len = ptr - runStart;
if (len <= 2 && usePalette) {
int index = zrlePaletteHelperLookup(ph, pix);
if (len == 2)
zrleOutStreamWriteU8(os, index);
zrleOutStreamWriteU8(os, index);
continue;
}
if (usePalette) {
int index = zrlePaletteHelperLookup(ph, pix);
zrleOutStreamWriteU8(os, index | 128);
} else {
zrleOutStreamWRITE_PIXEL(os, pix);
}
len -= 1;
while (len >= 255) {
zrleOutStreamWriteU8(os, 255);
len -= 255;
}
zrleOutStreamWriteU8(os, len);
}
} else {
// no RLE
if (usePalette) {
int bppp;
PIXEL_T* ptr = data;
// packed pixels
assert (ph->size < 17);
bppp = bitsPerPackedPixel[ph->size-1];
for (i = 0; i < h; i++) {
zrle_U8 nbits = 0;
zrle_U8 byte = 0;
PIXEL_T* eol = ptr + w;
while (ptr < eol) {
PIXEL_T pix = *ptr++;
zrle_U8 index = zrlePaletteHelperLookup(ph, pix);
byte = (byte << bppp) | index;
nbits += bppp;
if (nbits >= 8) {
zrleOutStreamWriteU8(os, byte);
nbits = 0;
}
}
if (nbits > 0) {
byte <<= 8 - nbits;
zrleOutStreamWriteU8(os, byte);
}
}
} else {
// raw
#ifdef CPIXEL
PIXEL_T *ptr;
for (ptr = data; ptr < data+w*h; ptr++) {
zrleOutStreamWRITE_PIXEL(os, *ptr);
}
#else
zrleOutStreamWriteBytes(os, (zrle_U8 *)data, w*h*(BPP/8));
#endif
}
}
}
#undef PIXEL_T
#undef zrleOutStreamWRITE_PIXEL
#undef ZRLE_ENCODE
#undef ZRLE_ENCODE_TILE
#undef BPPOUT
/*
* Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
* Copyright (C) 2003 Sun Microsystems, Inc.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include <zrleoutstream.h>
#include <stdlib.h>
#define ZRLE_IN_BUFFER_SIZE 16384
#define ZRLE_OUT_BUFFER_SIZE 1024
#undef ZRLE_DEBUG
static rfbBool zrleBufferAlloc(zrleBuffer *buffer, int size)
{
buffer->ptr = buffer->start = malloc(size);
if (buffer->start == NULL) {
buffer->end = NULL;
return FALSE;
}
buffer->end = buffer->start + size;
return TRUE;
}
static void zrleBufferFree(zrleBuffer *buffer)
{
if (buffer->start)
free(buffer->start);
buffer->start = buffer->ptr = buffer->end = NULL;
}
static rfbBool zrleBufferGrow(zrleBuffer *buffer, int size)
{
int offset;
size += buffer->end - buffer->start;
offset = ZRLE_BUFFER_LENGTH (buffer);
buffer->start = realloc(buffer->start, size);
if (!buffer->start) {
return FALSE;
}
buffer->end = buffer->start + size;
buffer->ptr = buffer->start + offset;
return TRUE;
}
zrleOutStream *zrleOutStreamNew(void)
{
zrleOutStream *os;
os = malloc(sizeof(zrleOutStream));
if (os == NULL)
return NULL;
if (!zrleBufferAlloc(&os->in, ZRLE_IN_BUFFER_SIZE)) {
free(os);
return NULL;
}
if (!zrleBufferAlloc(&os->out, ZRLE_OUT_BUFFER_SIZE)) {
zrleBufferFree(&os->in);
free(os);
return NULL;
}
os->zs.zalloc = Z_NULL;
os->zs.zfree = Z_NULL;
os->zs.opaque = Z_NULL;
if (deflateInit(&os->zs, Z_DEFAULT_COMPRESSION) != Z_OK) {
zrleBufferFree(&os->in);
free(os);
return NULL;
}
return os;
}
void zrleOutStreamFree (zrleOutStream *os)
{
deflateEnd(&os->zs);
zrleBufferFree(&os->in);
zrleBufferFree(&os->out);
free(os);
}
rfbBool zrleOutStreamFlush(zrleOutStream *os)
{
os->zs.next_in = os->in.start;
os->zs.avail_in = ZRLE_BUFFER_LENGTH (&os->in);
#ifdef ZRLE_DEBUG
rfbLog("zrleOutStreamFlush: avail_in %d\n", os->zs.avail_in);
#endif
while (os->zs.avail_in != 0) {
do {
int ret;
if (os->out.ptr >= os->out.end &&
!zrleBufferGrow(&os->out, os->out.end - os->out.start)) {
rfbLog("zrleOutStreamFlush: failed to grow output buffer\n");
return FALSE;
}
os->zs.next_out = os->out.ptr;
os->zs.avail_out = os->out.end - os->out.ptr;
#ifdef ZRLE_DEBUG
rfbLog("zrleOutStreamFlush: calling deflate, avail_in %d, avail_out %d\n",
os->zs.avail_in, os->zs.avail_out);
#endif
if ((ret = deflate(&os->zs, Z_SYNC_FLUSH)) != Z_OK) {
rfbLog("zrleOutStreamFlush: deflate failed with error code %d\n", ret);
return FALSE;
}
#ifdef ZRLE_DEBUG
rfbLog("zrleOutStreamFlush: after deflate: %d bytes\n",
os->zs.next_out - os->out.ptr);
#endif
os->out.ptr = os->zs.next_out;
} while (os->zs.avail_out == 0);
}
os->in.ptr = os->in.start;
return TRUE;
}
static int zrleOutStreamOverrun(zrleOutStream *os,
int size)
{
#ifdef ZRLE_DEBUG
rfbLog("zrleOutStreamOverrun\n");
#endif
while (os->in.end - os->in.ptr < size && os->in.ptr > os->in.start) {
os->zs.next_in = os->in.start;
os->zs.avail_in = ZRLE_BUFFER_LENGTH (&os->in);
do {
int ret;
if (os->out.ptr >= os->out.end &&
!zrleBufferGrow(&os->out, os->out.end - os->out.start)) {
rfbLog("zrleOutStreamOverrun: failed to grow output buffer\n");
return FALSE;
}
os->zs.next_out = os->out.ptr;
os->zs.avail_out = os->out.end - os->out.ptr;
#ifdef ZRLE_DEBUG
rfbLog("zrleOutStreamOverrun: calling deflate, avail_in %d, avail_out %d\n",
os->zs.avail_in, os->zs.avail_out);
#endif
if ((ret = deflate(&os->zs, 0)) != Z_OK) {
rfbLog("zrleOutStreamOverrun: deflate failed with error code %d\n", ret);
return 0;
}
#ifdef ZRLE_DEBUG
rfbLog("zrleOutStreamOverrun: after deflate: %d bytes\n",
os->zs.next_out - os->out.ptr);
#endif
os->out.ptr = os->zs.next_out;
} while (os->zs.avail_out == 0);
/* output buffer not full */
if (os->zs.avail_in == 0) {
os->in.ptr = os->in.start;
} else {
/* but didn't consume all the data? try shifting what's left to the
* start of the buffer.
*/
rfbLog("zrleOutStreamOverrun: out buf not full, but in data not consumed\n");
memmove(os->in.start, os->zs.next_in, os->in.ptr - os->zs.next_in);
os->in.ptr -= os->zs.next_in - os->in.start;
}
}
if (size > os->in.end - os->in.ptr)
size = os->in.end - os->in.ptr;
return size;
}
static inline int zrleOutStreamCheck(zrleOutStream *os,
int size)
{
if (os->in.ptr + size > os->in.end) {
return zrleOutStreamOverrun(os, size);
}
return size;
}
void zrleOutStreamWriteBytes(zrleOutStream *os,
const zrle_U8 *data,
int length)
{
const zrle_U8* dataEnd = data + length;
while (data < dataEnd) {
int n = zrleOutStreamCheck(os, dataEnd - data);
memcpy(os->in.ptr, data, n);
os->in.ptr += n;
data += n;
}
}
void zrleOutStreamWriteU8(zrleOutStream *os, zrle_U8 u)
{
zrleOutStreamCheck(os, 1);
*os->in.ptr++ = u;
}
void zrleOutStreamWriteOpaque8(zrleOutStream *os, zrle_U8 u)
{
zrleOutStreamCheck(os, 1);
*os->in.ptr++ = u;
}
void zrleOutStreamWriteOpaque16 (zrleOutStream *os, zrle_U16 u)
{
zrleOutStreamCheck(os, 2);
*os->in.ptr++ = ((zrle_U8*)&u)[0];
*os->in.ptr++ = ((zrle_U8*)&u)[1];
}
void zrleOutStreamWriteOpaque32 (zrleOutStream *os, zrle_U32 u)
{
zrleOutStreamCheck(os, 4);
*os->in.ptr++ = ((zrle_U8*)&u)[0];
*os->in.ptr++ = ((zrle_U8*)&u)[1];
*os->in.ptr++ = ((zrle_U8*)&u)[2];
*os->in.ptr++ = ((zrle_U8*)&u)[3];
}
void zrleOutStreamWriteOpaque24A(zrleOutStream *os, zrle_U32 u)
{
zrleOutStreamCheck(os, 3);
*os->in.ptr++ = ((zrle_U8*)&u)[0];
*os->in.ptr++ = ((zrle_U8*)&u)[1];
*os->in.ptr++ = ((zrle_U8*)&u)[2];
}
void zrleOutStreamWriteOpaque24B(zrleOutStream *os, zrle_U32 u)
{
zrleOutStreamCheck(os, 3);
*os->in.ptr++ = ((zrle_U8*)&u)[1];
*os->in.ptr++ = ((zrle_U8*)&u)[2];
*os->in.ptr++ = ((zrle_U8*)&u)[3];
}
/*
* Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
* Copyright (C) 2003 Sun Microsystems, Inc.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#ifndef __ZRLE_OUT_STREAM_H__
#define __ZRLE_OUT_STREAM_H__
#include <zlib.h>
#include <zrletypes.h>
#include <rfb/rfb.h>
typedef struct {
zrle_U8 *start;
zrle_U8 *ptr;
zrle_U8 *end;
} zrleBuffer;
typedef struct {
zrleBuffer in;
zrleBuffer out;
z_stream zs;
} zrleOutStream;
#define ZRLE_BUFFER_LENGTH(b) ((b)->ptr - (b)->start)
zrleOutStream *zrleOutStreamNew (void);
void zrleOutStreamFree (zrleOutStream *os);
rfbBool zrleOutStreamFlush (zrleOutStream *os);
void zrleOutStreamWriteBytes (zrleOutStream *os,
const zrle_U8 *data,
int length);
void zrleOutStreamWriteU8 (zrleOutStream *os,
zrle_U8 u);
void zrleOutStreamWriteOpaque8 (zrleOutStream *os,
zrle_U8 u);
void zrleOutStreamWriteOpaque16 (zrleOutStream *os,
zrle_U16 u);
void zrleOutStreamWriteOpaque32 (zrleOutStream *os,
zrle_U32 u);
void zrleOutStreamWriteOpaque24A(zrleOutStream *os,
zrle_U32 u);
void zrleOutStreamWriteOpaque24B(zrleOutStream *os,
zrle_U32 u);
#endif /* __ZRLE_OUT_STREAM_H__ */
/*
* Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
* Copyright (C) 2003 Sun Microsystems, Inc.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include <zrlepalettehelper.h>
#include <assert.h>
#include <string.h>
#define ZRLE_HASH(pix) (((pix) ^ ((pix) >> 17)) & 4095)
void zrlePaletteHelperInit(zrlePaletteHelper *helper)
{
memset(helper->palette, 0, sizeof(helper->palette));
memset(helper->index, 255, sizeof(helper->index));
memset(helper->key, 0, sizeof(helper->key));
helper->size = 0;
}
void zrlePaletteHelperInsert(zrlePaletteHelper *helper, zrle_U32 pix)
{
if (helper->size < ZRLE_PALETTE_MAX_SIZE) {
int i = ZRLE_HASH(pix);
while (helper->index[i] != 255 && helper->key[i] != pix)
i++;
if (helper->index[i] != 255) return;
helper->index[i] = helper->size;
helper->key[i] = pix;
helper->palette[helper->size] = pix;
}
helper->size++;
}
int zrlePaletteHelperLookup(zrlePaletteHelper *helper, zrle_U32 pix)
{
int i = ZRLE_HASH(pix);
assert(helper->size <= ZRLE_PALETTE_MAX_SIZE);
while (helper->index[i] != 255 && helper->key[i] != pix)
i++;
if (helper->index[i] != 255) return helper->index[i];
return -1;
}
/*
* Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
* Copyright (C) 2003 Sun Microsystems, Inc.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
/*
* The PaletteHelper class helps us build up the palette from pixel data by
* storing a reverse index using a simple hash-table
*/
#ifndef __ZRLE_PALETTE_HELPER_H__
#define __ZRLE_PALETTE_HELPER_H__
#include <zrletypes.h>
#define ZRLE_PALETTE_MAX_SIZE 127
typedef struct {
zrle_U32 palette[ZRLE_PALETTE_MAX_SIZE];
zrle_U8 index[ZRLE_PALETTE_MAX_SIZE + 4096];
zrle_U32 key[ZRLE_PALETTE_MAX_SIZE + 4096];
int size;
} zrlePaletteHelper;
void zrlePaletteHelperInit (zrlePaletteHelper *helper);
void zrlePaletteHelperInsert(zrlePaletteHelper *helper,
zrle_U32 pix);
int zrlePaletteHelperLookup(zrlePaletteHelper *helper,
zrle_U32 pix);
#endif /* __ZRLE_PALETTE_HELPER_H__ */
/*
* Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#ifndef __ZRLE_TYPES_H__
#define __ZRLE_TYPES_H__
typedef unsigned char zrle_U8;
typedef unsigned short zrle_U16;
typedef unsigned int zrle_U32;
typedef signed char zrle_S8;
typedef signed short zrle_S16;
typedef signed int zrle_S32;
#endif /* __ZRLE_TYPES_H__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment