Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
L
libvncserver
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
rasky
libvncserver
Commits
af85e5fe
Commit
af85e5fe
authored
Oct 22, 2002
by
dscho
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
updated to vnc-3.3.4 (ZRLE encoding)
parent
5a5c22ff
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
836 additions
and
40 deletions
+836
-40
Makefile
Makefile
+22
-6
corre.c
corre.c
+7
-8
cvs_update_anonymously
cvs_update_anonymously
+2
-1
httpd.c
httpd.c
+17
-22
main.c
main.c
+0
-1
rfb.h
rfb.h
+9
-1
rfbproto.h
rfbproto.h
+16
-0
rfbserver.c
rfbserver.c
+23
-0
stats.c
stats.c
+9
-1
zrle.cc
zrle.cc
+180
-0
zrleDecode.h
zrleDecode.h
+241
-0
zrleEncode.h
zrleEncode.h
+310
-0
No files found.
Makefile
View file @
af85e5fe
INCLUDES
=
-I
.
INCLUDES
=
-I
.
VNCSERVERLIB
=
-L
.
-lvncserver
-L
/usr/local/lib
-lz
-ljpeg
VNCSERVERLIB
=
-L
.
-lvncserver
-L
/usr/local/lib
-lz
-ljpeg
# for Solaris
CXX
=
g++
CC
=
gcc
CC
=
gcc
# for Solaris
#EXTRALIBS=-lsocket -lnsl -L/usr/X/lib
#EXTRALIBS=-lsocket -lnsl -L/usr/X/lib
# for FreeBSD
# for FreeBSD
...
@@ -18,11 +20,8 @@ FLAG24 = -DALLOW24BPP
...
@@ -18,11 +20,8 @@ FLAG24 = -DALLOW24BPP
OPTFLAGS
=
-g
-Wall
-pedantic
OPTFLAGS
=
-g
-Wall
-pedantic
#OPTFLAGS=-O2 -Wall
#OPTFLAGS=-O2 -Wall
CFLAGS
=
$(OPTFLAGS)
$(PTHREADDEF)
$(FLAG24)
$(INCLUDES)
$(EXTRAINCLUDES)
-DBACKCHANNEL
RANLIB
=
ranlib
RANLIB
=
ranlib
LIBS
=
$(LDFLAGS)
$(VNCSERVERLIB)
$(PTHREADLIB)
$(EXTRALIBS)
# for Mac OS X
# for Mac OS X
OSX_LIBS
=
-framework
ApplicationServices
-framework
Carbon
-framework
IOKit
OSX_LIBS
=
-framework
ApplicationServices
-framework
Carbon
-framework
IOKit
...
@@ -30,14 +29,31 @@ OSX_LIBS = -framework ApplicationServices -framework Carbon -framework IOKit
...
@@ -30,14 +29,31 @@ OSX_LIBS = -framework ApplicationServices -framework Carbon -framework IOKit
#XLIBS = -L/usr/X11R6/lib -lXtst -lXext -lX11
#XLIBS = -L/usr/X11R6/lib -lXtst -lXext -lX11
XLIBS
=
-L
/usr/X11R6/lib
-L
/usr/lib32
-lXtst
-lXext
-lX11
XLIBS
=
-L
/usr/X11R6/lib
-L
/usr/lib32
-lXtst
-lXext
-lX11
ifdef
CXX
ZRLE_SRCS
=
zrle.cc rdr/FdInStream.cxx rdr/FdOutStream.cxx rdr/InStream.cxx
\
rdr/NullOutStream.cxx rdr/ZlibInStream.cxx rdr/ZlibOutStream.cxx
ZRLE_OBJS
=
zrle.o rdr/FdInStream.o rdr/FdOutStream.o rdr/InStream.o
\
rdr/NullOutStream.o rdr/ZlibInStream.o rdr/ZlibOutStream.o
ZRLE_DEF
=
-DHAVE_ZRLE
%.o
:
%.cxx
$(CXX)
$(CXXFLAGS)
-c
-o
$@
$<
endif
CFLAGS
=
$(OPTFLAGS)
$(PTHREADDEF)
$(FLAG24)
$(INCLUDES)
$(EXTRAINCLUDES)
$(ZRLE_DEF)
-DBACKCHANNEL
CXXFLAGS
=
$(OPTFLAGS)
$(PTHREADDEF)
$(FLAG24)
$(INCLUDES)
$(EXTRAINCLUDES)
$(ZRLE_DEF)
-DBACKCHANNEL
LIBS
=
$(LDFLAGS)
$(VNCSERVERLIB)
$(PTHREADLIB)
$(EXTRALIBS)
SOURCES
=
main.c rfbserver.c sraRegion.c auth.c sockets.c
\
SOURCES
=
main.c rfbserver.c sraRegion.c auth.c sockets.c
\
stats.c corre.c hextile.c rre.c translate.c cutpaste.c
\
stats.c corre.c hextile.c rre.c translate.c cutpaste.c
\
zlib.c tight.c httpd.c cursor.c font.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_SRCS)
OBJS
=
main.o rfbserver.o sraRegion.o auth.o sockets.o
\
OBJS
=
main.o rfbserver.o sraRegion.o auth.o sockets.o
\
stats.o corre.o hextile.o rre.o translate.o cutpaste.o
\
stats.o corre.o hextile.o rre.o translate.o cutpaste.o
\
zlib.o tight.o httpd.o cursor.o font.o
\
zlib.o tight.o httpd.o cursor.o font.o
\
draw.o selbox.o d3des.o vncauth.o cargs.o
draw.o selbox.o d3des.o vncauth.o cargs.o
$(ZRLE_OBJS)
INSTALLHEADER
=
rfb.h rfbproto.h sraRegion.h keysym.h
INSTALLHEADER
=
rfb.h rfbproto.h sraRegion.h keysym.h
all
:
example pnmshow storepasswd
all
:
example pnmshow storepasswd
...
...
corre.c
View file @
af85e5fe
...
@@ -6,6 +6,7 @@
...
@@ -6,6 +6,7 @@
*/
*/
/*
/*
* Copyright (C) 2002 RealVNC Ltd.
* OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
* OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
* Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.
* Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.
* All Rights Reserved.
* All Rights Reserved.
...
@@ -63,17 +64,15 @@ rfbSendRectEncodingCoRRE(cl, x, y, w, h)
...
@@ -63,17 +64,15 @@ rfbSendRectEncodingCoRRE(cl, x, y, w, h)
int
x
,
y
,
w
,
h
;
int
x
,
y
,
w
,
h
;
{
{
if
(
h
>
cl
->
correMaxHeight
)
{
if
(
h
>
cl
->
correMaxHeight
)
{
rfbSendRectEncodingCoRRE
(
cl
,
x
,
y
,
w
,
cl
->
correMaxHeight
);
return
(
rfbSendRectEncodingCoRRE
(
cl
,
x
,
y
,
w
,
cl
->
correMaxHeight
)
&&
rfbSendRectEncodingCoRRE
(
cl
,
x
,
y
+
cl
->
correMaxHeight
,
w
,
rfbSendRectEncodingCoRRE
(
cl
,
x
,
y
+
cl
->
correMaxHeight
,
w
,
h
-
cl
->
correMaxHeight
);
h
-
cl
->
correMaxHeight
));
return
FALSE
;
}
}
if
(
w
>
cl
->
correMaxWidth
)
{
if
(
w
>
cl
->
correMaxWidth
)
{
rfbSendRectEncodingCoRRE
(
cl
,
x
,
y
,
cl
->
correMaxWidth
,
h
);
return
(
rfbSendRectEncodingCoRRE
(
cl
,
x
,
y
,
cl
->
correMaxWidth
,
h
)
&&
rfbSendRectEncodingCoRRE
(
cl
,
x
+
cl
->
correMaxWidth
,
y
,
rfbSendRectEncodingCoRRE
(
cl
,
x
+
cl
->
correMaxWidth
,
y
,
w
-
cl
->
correMaxWidth
,
h
);
w
-
cl
->
correMaxWidth
,
h
));
return
FALSE
;
}
}
rfbSendSmallRectEncodingCoRRE
(
cl
,
x
,
y
,
w
,
h
);
rfbSendSmallRectEncodingCoRRE
(
cl
,
x
,
y
,
w
,
h
);
...
...
cvs_update_anonymously
View file @
af85e5fe
if [ a"$1" = adiff ]; then
if [ a"$1" = adiff ]; then
cmd=diff
cmd=diff
shift
else
else
cmd=update
cmd=update
fi
fi
cvs -z3 -d :pserver:anonymous@cvs.libvncserver.sf.net:/cvsroot/libvncserver $cmd
cvs -z3 -d :pserver:anonymous@cvs.libvncserver.sf.net:/cvsroot/libvncserver $cmd
"$@"
httpd.c
View file @
af85e5fe
...
@@ -3,6 +3,7 @@
...
@@ -3,6 +3,7 @@
*/
*/
/*
/*
* Copyright (C) 2002 RealVNC Ltd.
* Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
* Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
*
*
* This is free software; you can redistribute it and/or modify
* This is free software; you can redistribute it and/or modify
...
@@ -47,30 +48,21 @@
...
@@ -47,30 +48,21 @@
#include "rfb.h"
#include "rfb.h"
#define NOT_FOUND_STR "HTTP/1.0 404 Not found\
n
\n" \
#define NOT_FOUND_STR "HTTP/1.0 404 Not found\
r\n\r
\n" \
"<HEAD><TITLE>File Not Found</TITLE></HEAD>\n" \
"<HEAD><TITLE>File Not Found</TITLE></HEAD>\n" \
"<BODY><H1>File Not Found</H1></BODY>\n"
"<BODY><H1>File Not Found</H1></BODY>\n"
#define INVALID_REQUEST_STR "HTTP/1.0 400 Invalid Request\
n
\n" \
#define INVALID_REQUEST_STR "HTTP/1.0 400 Invalid Request\
r\n\r
\n" \
"<HEAD><TITLE>Invalid Request</TITLE></HEAD>\n" \
"<HEAD><TITLE>Invalid Request</TITLE></HEAD>\n" \
"<BODY><H1>Invalid request</H1></BODY>\n"
"<BODY><H1>Invalid request</H1></BODY>\n"
#define OK_STR "HTTP/1.0 200 OK\nContent-Type: text/html\
n
\n"
#define OK_STR "HTTP/1.0 200 OK\nContent-Type: text/html\
r\n\r
\n"
static
void
httpProcessInput
();
static
void
httpProcessInput
();
static
Bool
compareAndSkip
(
char
**
ptr
,
const
char
*
str
);
static
Bool
compareAndSkip
(
char
**
ptr
,
const
char
*
str
);
static
Bool
parseParams
(
const
char
*
request
,
char
*
result
,
int
max_bytes
);
static
Bool
parseParams
(
const
char
*
request
,
char
*
result
,
int
max_bytes
);
static
Bool
validateString
(
char
*
str
);
static
Bool
validateString
(
char
*
str
);
/*
int httpPort = 0;
char *httpDir = NULL;
int httpListenSock = -1;
int httpSock = -1;
FILE* httpFP = NULL;
*/
#define BUF_SIZE 32768
#define BUF_SIZE 32768
static
char
buf
[
BUF_SIZE
];
static
char
buf
[
BUF_SIZE
];
...
@@ -163,8 +155,10 @@ httpCheckFds(rfbScreenInfoPtr rfbScreen)
...
@@ -163,8 +155,10 @@ httpCheckFds(rfbScreenInfoPtr rfbScreen)
rfbLog
(
"Rejected HTTP connection from client %s
\n
"
,
rfbLog
(
"Rejected HTTP connection from client %s
\n
"
,
inet_ntoa
(
addr
.
sin_addr
));
inet_ntoa
(
addr
.
sin_addr
));
#else
#else
if
((
rfbScreen
->
httpFP
=
fdopen
(
rfbScreen
->
httpSock
,
"r+"
))
==
NULL
)
{
flags
=
fcntl
(
rfbScreen
->
httpSock
,
F_SETFL
);
rfbLogPerror
(
"httpCheckFds: fdopen"
);
if
(
flags
<
0
||
fcntl
(
rfbScreen
->
httpSock
,
F_SETFL
,
flags
|
O_NONBLOCK
)
==
-
1
)
{
rfbLogPerror
(
"httpCheckFds: fcntl"
);
#endif
#endif
close
(
rfbScreen
->
httpSock
);
close
(
rfbScreen
->
httpSock
);
rfbScreen
->
httpSock
=
-
1
;
rfbScreen
->
httpSock
=
-
1
;
...
@@ -187,9 +181,6 @@ httpCheckFds(rfbScreenInfoPtr rfbScreen)
...
@@ -187,9 +181,6 @@ httpCheckFds(rfbScreenInfoPtr rfbScreen)
static
void
static
void
httpCloseSock
(
rfbScreenInfoPtr
rfbScreen
)
httpCloseSock
(
rfbScreenInfoPtr
rfbScreen
)
{
{
fclose
(
rfbScreen
->
httpFP
);
rfbScreen
->
httpFP
=
NULL
;
/*RemoveEnabledDevice(httpSock);*/
rfbScreen
->
httpSock
=
-
1
;
rfbScreen
->
httpSock
=
-
1
;
}
}
...
@@ -231,7 +222,15 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen)
...
@@ -231,7 +222,15 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen)
/* Read data from the HTTP client until we get a complete request. */
/* Read data from the HTTP client until we get a complete request. */
while
(
1
)
{
while
(
1
)
{
ssize_t
got
=
read
(
rfbScreen
->
httpSock
,
buf
+
buf_filled
,
ssize_t
got
;
if
(
buf_filled
>
sizeof
(
buf
))
{
rfbLog
(
"httpProcessInput: HTTP request is too long
\n
"
);
httpCloseSock
(
rfbScreen
);
return
;
}
got
=
read
(
rfbScreen
->
httpSock
,
buf
+
buf_filled
,
sizeof
(
buf
)
-
buf_filled
-
1
);
sizeof
(
buf
)
-
buf_filled
-
1
);
if
(
got
<=
0
)
{
if
(
got
<=
0
)
{
...
@@ -271,8 +270,6 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen)
...
@@ -271,8 +270,6 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen)
rfbLog
(
"httpd: client asked for CONNECT
\n
"
);
rfbLog
(
"httpd: client asked for CONNECT
\n
"
);
WriteExact
(
&
cl
,
PROXY_OK_STR
,
strlen
(
PROXY_OK_STR
));
WriteExact
(
&
cl
,
PROXY_OK_STR
,
strlen
(
PROXY_OK_STR
));
rfbNewClientConnection
(
rfbScreen
,
rfbScreen
->
httpSock
);
rfbNewClientConnection
(
rfbScreen
,
rfbScreen
->
httpSock
);
// don't fclose(rfbScreen->httpFP), because this would kill the connection
rfbScreen
->
httpFP
=
NULL
;
rfbScreen
->
httpSock
=
-
1
;
rfbScreen
->
httpSock
=
-
1
;
return
;
return
;
}
}
...
@@ -281,8 +278,6 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen)
...
@@ -281,8 +278,6 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen)
rfbLog
(
"httpd: client asked for /proxied.connection
\n
"
);
rfbLog
(
"httpd: client asked for /proxied.connection
\n
"
);
WriteExact
(
&
cl
,
PROXY_OK_STR
,
strlen
(
PROXY_OK_STR
));
WriteExact
(
&
cl
,
PROXY_OK_STR
,
strlen
(
PROXY_OK_STR
));
rfbNewClientConnection
(
rfbScreen
,
rfbScreen
->
httpSock
);
rfbNewClientConnection
(
rfbScreen
,
rfbScreen
->
httpSock
);
// don't fclose(rfbScreen->httpFP), because this would kill the connection
rfbScreen
->
httpFP
=
NULL
;
rfbScreen
->
httpSock
=
-
1
;
rfbScreen
->
httpSock
=
-
1
;
return
;
return
;
}
}
...
...
main.c
View file @
af85e5fe
...
@@ -549,7 +549,6 @@ rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv,
...
@@ -549,7 +549,6 @@ rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv,
rfbScreen
->
httpDir
=
NULL
;
rfbScreen
->
httpDir
=
NULL
;
rfbScreen
->
httpListenSock
=-
1
;
rfbScreen
->
httpListenSock
=-
1
;
rfbScreen
->
httpSock
=-
1
;
rfbScreen
->
httpSock
=-
1
;
rfbScreen
->
httpFP
=
NULL
;
rfbScreen
->
desktopName
=
"LibVNCServer"
;
rfbScreen
->
desktopName
=
"LibVNCServer"
;
rfbScreen
->
rfbAlwaysShared
=
FALSE
;
rfbScreen
->
rfbAlwaysShared
=
FALSE
;
...
...
rfb.h
View file @
af85e5fe
...
@@ -6,6 +6,7 @@
...
@@ -6,6 +6,7 @@
*/
*/
/*
/*
* Copyright (C) 2002 RealVNC Ltd.
* OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
* OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
* Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.
* Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.
* All Rights Reserved.
* All Rights Reserved.
...
@@ -297,7 +298,6 @@ typedef struct _rfbScreenInfo
...
@@ -297,7 +298,6 @@ typedef struct _rfbScreenInfo
char
*
httpDir
;
char
*
httpDir
;
SOCKET
httpListenSock
;
SOCKET
httpListenSock
;
SOCKET
httpSock
;
SOCKET
httpSock
;
FILE
*
httpFP
;
PasswordCheckProcPtr
passwordCheck
;
PasswordCheckProcPtr
passwordCheck
;
void
*
rfbAuthPasswdData
;
void
*
rfbAuthPasswdData
;
...
@@ -409,6 +409,9 @@ typedef struct _rfbClientRec {
...
@@ -409,6 +409,9 @@ typedef struct _rfbClientRec {
Bool
useCopyRect
;
Bool
useCopyRect
;
int
preferredEncoding
;
int
preferredEncoding
;
int
correMaxWidth
,
correMaxHeight
;
int
correMaxWidth
,
correMaxHeight
;
#ifdef HAVE_ZRLE
void
*
zrleData
;
#endif
/* The following member is only used during VNC authentication */
/* The following member is only used during VNC authentication */
CARD8
authChallenge
[
CHALLENGESIZE
];
CARD8
authChallenge
[
CHALLENGESIZE
];
...
@@ -716,6 +719,11 @@ extern void rfbSetCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr c,Bool freeOld)
...
@@ -716,6 +719,11 @@ extern void rfbSetCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr c,Bool freeOld)
/* cursor handling for the pointer */
/* cursor handling for the pointer */
extern
void
defaultPtrAddEvent
(
int
buttonMask
,
int
x
,
int
y
,
rfbClientPtr
cl
);
extern
void
defaultPtrAddEvent
(
int
buttonMask
,
int
x
,
int
y
,
rfbClientPtr
cl
);
/* zrle.c */
extern
Bool
rfbSendRectEncodingZRLE
(
rfbClientPtr
cl
,
int
x
,
int
y
,
int
w
,
int
h
);
extern
void
FreeZrleData
(
rfbClientPtr
cl
);
/* stats.c */
/* stats.c */
extern
void
rfbResetStats
(
rfbClientPtr
cl
);
extern
void
rfbResetStats
(
rfbClientPtr
cl
);
...
...
rfbproto.h
View file @
af85e5fe
...
@@ -302,6 +302,7 @@ typedef struct {
...
@@ -302,6 +302,7 @@ typedef struct {
#ifdef BACKCHANNEL
#ifdef BACKCHANNEL
#define rfbEncodingBackChannel 15
#define rfbEncodingBackChannel 15
#endif
#endif
#define rfbEncodingZRLE 16
/*
/*
* Special encoding numbers:
* Special encoding numbers:
...
@@ -559,6 +560,21 @@ typedef struct {
...
@@ -559,6 +560,21 @@ typedef struct {
*/
*/
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* ZRLE - encoding combining Zlib compression, tiling, palettisation and
* run-length encoding.
*/
typedef
struct
{
CARD32
length
;
}
rfbZRLEHeader
;
#define sz_rfbZRLEHeader 4
#define rfbZRLETileWidth 64
#define rfbZRLETileHeight 64
/*-----------------------------------------------------------------------------
/*-----------------------------------------------------------------------------
* SetColourMapEntries - these messages are only sent if the pixel
* SetColourMapEntries - these messages are only sent if the pixel
* format uses a "colour map" (i.e. trueColour false) and the client has not
* format uses a "colour map" (i.e. trueColour false) and the client has not
...
...
rfbserver.c
View file @
af85e5fe
...
@@ -3,6 +3,7 @@
...
@@ -3,6 +3,7 @@
*/
*/
/*
/*
* Copyright (C) 2002 RealVNC Ltd.
* OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
* OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
* Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.
* Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.
* All Rights Reserved.
* All Rights Reserved.
...
@@ -257,6 +258,7 @@ rfbNewTCPOrUDPClient(rfbScreen,sock,isUDP)
...
@@ -257,6 +258,7 @@ rfbNewTCPOrUDPClient(rfbScreen,sock,isUDP)
cl
->
preferredEncoding
=
rfbEncodingRaw
;
cl
->
preferredEncoding
=
rfbEncodingRaw
;
cl
->
correMaxWidth
=
48
;
cl
->
correMaxWidth
=
48
;
cl
->
correMaxHeight
=
48
;
cl
->
correMaxHeight
=
48
;
cl
->
zrleData
=
0
;
cl
->
copyRegion
=
sraRgnCreate
();
cl
->
copyRegion
=
sraRgnCreate
();
cl
->
copyDX
=
0
;
cl
->
copyDX
=
0
;
...
@@ -372,6 +374,10 @@ rfbClientConnectionGone(cl)
...
@@ -372,6 +374,10 @@ rfbClientConnectionGone(cl)
if
(
cl
->
next
)
if
(
cl
->
next
)
cl
->
next
->
prev
=
cl
->
prev
;
cl
->
next
->
prev
=
cl
->
prev
;
#ifdef HAVE_ZRLE
FreeZrleData
(
cl
);
#endif
#ifdef HAVE_PTHREADS
#ifdef HAVE_PTHREADS
LOCK
(
cl
->
refCountMutex
);
LOCK
(
cl
->
refCountMutex
);
if
(
cl
->
refCount
)
{
if
(
cl
->
refCount
)
{
...
@@ -786,6 +792,15 @@ rfbProcessClientNormalMessage(cl)
...
@@ -786,6 +792,15 @@ rfbProcessClientNormalMessage(cl)
cl
->
enableBackChannel
=
TRUE
;
cl
->
enableBackChannel
=
TRUE
;
}
}
break
;
break
;
#endif
#ifdef HAVE_ZRLE
case
rfbEncodingZRLE
:
if
(
cl
->
preferredEncoding
==
-
1
)
{
cl
->
preferredEncoding
=
enc
;
rfbLog
(
"Using ZRLE encoding for client %s
\n
"
,
cl
->
host
);
}
break
;
#endif
#endif
default
:
default
:
if
(
enc
>=
(
CARD32
)
rfbEncodingCompressLevel0
&&
if
(
enc
>=
(
CARD32
)
rfbEncodingCompressLevel0
&&
...
@@ -1187,6 +1202,14 @@ rfbSendFramebufferUpdate(cl, givenUpdateRegion)
...
@@ -1187,6 +1202,14 @@ rfbSendFramebufferUpdate(cl, givenUpdateRegion)
return
FALSE
;
return
FALSE
;
}
}
break
;
break
;
#ifdef HAVE_ZRLE
case
rfbEncodingZRLE
:
if
(
!
rfbSendRectEncodingZRLE
(
cl
,
x
,
y
,
w
,
h
))
{
sraRgnDestroy
(
updateRegion
);
return
FALSE
;
}
break
;
#endif
}
}
}
}
sraRgnReleaseIterator
(
i
);
sraRgnReleaseIterator
(
i
);
...
...
stats.c
View file @
af85e5fe
...
@@ -3,6 +3,7 @@
...
@@ -3,6 +3,7 @@
*/
*/
/*
/*
* Copyright (C) 2002 RealVNC Ltd.
* OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
* OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
* Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.
* Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.
* All Rights Reserved.
* All Rights Reserved.
...
@@ -29,7 +30,14 @@
...
@@ -29,7 +30,14 @@
static
const
char
*
encNames
[]
=
{
static
const
char
*
encNames
[]
=
{
"raw"
,
"copyRect"
,
"RRE"
,
"[encoding 3]"
,
"CoRRE"
,
"hextile"
,
"raw"
,
"copyRect"
,
"RRE"
,
"[encoding 3]"
,
"CoRRE"
,
"hextile"
,
"zlib"
,
"tight"
,
"[encoding 8]"
,
"[encoding 9]"
"zlib"
,
"tight"
,
"[encoding 8]"
,
"[encoding 9]"
,
"[encoding 10]"
,
"[encoding 11]"
,
"[encoding 12]"
,
"[encoding 13]"
,
"[encoding 14]"
,
#ifdef BACKCHANNEL
"BackChannel"
,
#else
"[encoding 15]"
,
#endif
"ZRLE"
,
"[encoding 17]"
,
"[encoding 18]"
,
"[encoding 19]"
,
"[encoding 20]"
};
};
...
...
zrle.cc
0 → 100644
View file @
af85e5fe
//
// 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.
//
//
// zrle.cc
//
// Routines to implement Zlib Run-length Encoding (ZRLE).
//
#include <stdio.h>
extern
"C"
{
#include "rfb.h"
}
#include <rdr/MemOutStream.h>
#include <rdr/ZlibOutStream.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 <zrleEncode.h>
#undef BPP
#define BPP 16
#include <zrleEncode.h>
#undef BPP
#define BPP 32
#include <zrleEncode.h>
#define CPIXEL 24A
#include <zrleEncode.h>
#undef CPIXEL
#define CPIXEL 24B
#include <zrleEncode.h>
#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
];
static
rdr
::
MemOutStream
mos
;
/*
* rfbSendRectEncodingZRLE - send a given rectangle using ZRLE encoding.
*/
Bool
rfbSendRectEncodingZRLE
(
rfbClientPtr
cl
,
int
x
,
int
y
,
int
w
,
int
h
)
{
if
(
!
cl
->
zrleData
)
cl
->
zrleData
=
new
rdr
::
ZlibOutStream
;
rdr
::
ZlibOutStream
*
zos
=
(
rdr
::
ZlibOutStream
*
)
cl
->
zrleData
;
mos
.
clear
();
switch
(
cl
->
format
.
bitsPerPixel
)
{
case
8
:
zrleEncode8
(
x
,
y
,
w
,
h
,
&
mos
,
zos
,
zrleBeforeBuf
,
cl
);
break
;
case
16
:
zrleEncode16
(
x
,
y
,
w
,
h
,
&
mos
,
zos
,
zrleBeforeBuf
,
cl
);
break
;
case
32
:
bool
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
));
bool
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
,
&
mos
,
zos
,
zrleBeforeBuf
,
cl
);
}
else
if
((
fitsInLS3Bytes
&&
cl
->
format
.
bigEndian
)
||
(
fitsInMS3Bytes
&&
!
cl
->
format
.
bigEndian
))
{
zrleEncode24B
(
x
,
y
,
w
,
h
,
&
mos
,
zos
,
zrleBeforeBuf
,
cl
);
}
else
{
zrleEncode32
(
x
,
y
,
w
,
h
,
&
mos
,
zos
,
zrleBeforeBuf
,
cl
);
}
break
;
}
cl
->
rfbRectanglesSent
[
rfbEncodingZRLE
]
++
;
cl
->
rfbBytesSent
[
rfbEncodingZRLE
]
+=
(
sz_rfbFramebufferUpdateRectHeader
+
sz_rfbZRLEHeader
+
mos
.
length
());
if
(
cl
->
ublen
+
sz_rfbFramebufferUpdateRectHeader
+
sz_rfbZRLEHeader
>
UPDATE_BUF_SIZE
)
{
if
(
!
rfbSendUpdateBuf
(
cl
))
return
FALSE
;
}
rfbFramebufferUpdateRectHeader
rect
;
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
;
rfbZRLEHeader
hdr
;
hdr
.
length
=
Swap32IfLE
(
mos
.
length
());
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
(
int
i
=
0
;
i
<
mos
.
length
();)
{
int
bytesToCopy
=
UPDATE_BUF_SIZE
-
cl
->
ublen
;
if
(
i
+
bytesToCopy
>
mos
.
length
())
{
bytesToCopy
=
mos
.
length
()
-
i
;
}
memcpy
(
cl
->
updateBuf
+
cl
->
ublen
,
(
CARD8
*
)
mos
.
data
()
+
i
,
bytesToCopy
);
cl
->
ublen
+=
bytesToCopy
;
i
+=
bytesToCopy
;
if
(
cl
->
ublen
==
UPDATE_BUF_SIZE
)
{
if
(
!
rfbSendUpdateBuf
(
cl
))
return
FALSE
;
}
}
return
TRUE
;
}
void
FreeZrleData
(
rfbClientPtr
cl
)
{
delete
(
rdr
::
ZlibOutStream
*
)
cl
->
zrleData
;
}
zrleDecode.h
0 → 100644
View file @
af85e5fe
//
// 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.
//
// zrleDecode.h - zrle decoding function.
//
// 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.
// FILL_RECT
// IMAGE_RECT
#include <rdr/ZlibInStream.h>
#include <rdr/InStream.h>
#include <assert.h>
using
namespace
rdr
;
/* __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(rdr::U,BPP)
#define READ_PIXEL __RFB_CONCAT2E(readOpaque,CPIXEL)
#define ZRLE_DECODE_BPP __RFB_CONCAT2E(zrleDecode,CPIXEL)
#else
#define PIXEL_T __RFB_CONCAT2E(rdr::U,BPP)
#define READ_PIXEL __RFB_CONCAT2E(readOpaque,BPP)
#define ZRLE_DECODE_BPP __RFB_CONCAT2E(zrleDecode,BPP)
#endif
void
ZRLE_DECODE_BPP
(
int
x
,
int
y
,
int
w
,
int
h
,
rdr
::
InStream
*
is
,
rdr
::
ZlibInStream
*
zis
,
PIXEL_T
*
buf
)
{
int
length
=
is
->
readU32
();
zis
->
setUnderlying
(
is
,
length
);
for
(
int
ty
=
y
;
ty
<
y
+
h
;
ty
+=
rfbZRLETileHeight
)
{
int
th
=
rfbZRLETileHeight
;
if
(
th
>
y
+
h
-
ty
)
th
=
y
+
h
-
ty
;
for
(
int
tx
=
x
;
tx
<
x
+
w
;
tx
+=
rfbZRLETileWidth
)
{
int
tw
=
rfbZRLETileWidth
;
if
(
tw
>
x
+
w
-
tx
)
tw
=
x
+
w
-
tx
;
int
mode
=
zis
->
readU8
();
bool
rle
=
mode
&
128
;
int
palSize
=
mode
&
127
;
PIXEL_T
palette
[
128
];
// fprintf(stderr,"rle %d palSize %d\n",rle,palSize);
for
(
int
i
=
0
;
i
<
palSize
;
i
++
)
{
palette
[
i
]
=
zis
->
READ_PIXEL
();
}
if
(
palSize
==
1
)
{
PIXEL_T
pix
=
palette
[
0
];
FILL_RECT
(
tx
,
ty
,
tw
,
th
,
pix
);
continue
;
}
if
(
!
rle
)
{
if
(
palSize
==
0
)
{
// raw
#ifdef CPIXEL
for
(
PIXEL_T
*
ptr
=
buf
;
ptr
<
buf
+
tw
*
th
;
ptr
++
)
{
*
ptr
=
zis
->
READ_PIXEL
();
}
#else
zis
->
readBytes
(
buf
,
tw
*
th
*
(
BPP
/
8
));
#endif
}
else
{
// packed pixels
int
bppp
=
((
palSize
>
16
)
?
8
:
((
palSize
>
4
)
?
4
:
((
palSize
>
2
)
?
2
:
1
)));
PIXEL_T
*
ptr
=
buf
;
for
(
int
i
=
0
;
i
<
th
;
i
++
)
{
PIXEL_T
*
eol
=
ptr
+
tw
;
U8
byte
=
0
;
U8
nbits
=
0
;
while
(
ptr
<
eol
)
{
if
(
nbits
==
0
)
{
byte
=
zis
->
readU8
();
nbits
=
8
;
}
nbits
-=
bppp
;
U8
index
=
(
byte
>>
nbits
)
&
((
1
<<
bppp
)
-
1
)
&
127
;
*
ptr
++
=
palette
[
index
];
}
}
}
#ifdef FAVOUR_FILL_RECT
//fprintf(stderr,"copying data to screen %dx%d at %d,%d\n",tw,th,tx,ty);
IMAGE_RECT
(
tx
,
ty
,
tw
,
th
,
buf
);
#endif
}
else
{
if
(
palSize
==
0
)
{
// plain RLE
PIXEL_T
*
ptr
=
buf
;
PIXEL_T
*
end
=
ptr
+
th
*
tw
;
while
(
ptr
<
end
)
{
PIXEL_T
pix
=
zis
->
READ_PIXEL
();
int
len
=
1
;
int
b
;
do
{
b
=
zis
->
readU8
();
len
+=
b
;
}
while
(
b
==
255
);
assert
(
len
<=
end
-
ptr
);
#ifdef FAVOUR_FILL_RECT
int
i
=
ptr
-
buf
;
ptr
+=
len
;
int
runX
=
i
%
tw
;
int
runY
=
i
/
tw
;
if
(
runX
+
len
>
tw
)
{
if
(
runX
!=
0
)
{
FILL_RECT
(
tx
+
runX
,
ty
+
runY
,
tw
-
runX
,
1
,
pix
);
len
-=
tw
-
runX
;
runX
=
0
;
runY
++
;
}
if
(
len
>
tw
)
{
FILL_RECT
(
tx
,
ty
+
runY
,
tw
,
len
/
tw
,
pix
);
runY
+=
len
/
tw
;
len
=
len
%
tw
;
}
}
if
(
len
!=
0
)
{
FILL_RECT
(
tx
+
runX
,
ty
+
runY
,
len
,
1
,
pix
);
}
#else
while
(
len
--
>
0
)
*
ptr
++
=
pix
;
#endif
}
}
else
{
// palette RLE
PIXEL_T
*
ptr
=
buf
;
PIXEL_T
*
end
=
ptr
+
th
*
tw
;
while
(
ptr
<
end
)
{
int
index
=
zis
->
readU8
();
int
len
=
1
;
if
(
index
&
128
)
{
int
b
;
do
{
b
=
zis
->
readU8
();
len
+=
b
;
}
while
(
b
==
255
);
assert
(
len
<=
end
-
ptr
);
}
index
&=
127
;
PIXEL_T
pix
=
palette
[
index
];
#ifdef FAVOUR_FILL_RECT
int
i
=
ptr
-
buf
;
ptr
+=
len
;
int
runX
=
i
%
tw
;
int
runY
=
i
/
tw
;
if
(
runX
+
len
>
tw
)
{
if
(
runX
!=
0
)
{
FILL_RECT
(
tx
+
runX
,
ty
+
runY
,
tw
-
runX
,
1
,
pix
);
len
-=
tw
-
runX
;
runX
=
0
;
runY
++
;
}
if
(
len
>
tw
)
{
FILL_RECT
(
tx
,
ty
+
runY
,
tw
,
len
/
tw
,
pix
);
runY
+=
len
/
tw
;
len
=
len
%
tw
;
}
}
if
(
len
!=
0
)
{
FILL_RECT
(
tx
+
runX
,
ty
+
runY
,
len
,
1
,
pix
);
}
#else
while
(
len
--
>
0
)
*
ptr
++
=
pix
;
#endif
}
}
}
#ifndef FAVOUR_FILL_RECT
//fprintf(stderr,"copying data to screen %dx%d at %d,%d\n",tw,th,tx,ty);
IMAGE_RECT
(
tx
,
ty
,
tw
,
th
,
buf
);
#endif
}
}
zis
->
reset
();
}
#undef ZRLE_DECODE_BPP
#undef READ_PIXEL
#undef PIXEL_T
zrleEncode.h
0 → 100644
View file @
af85e5fe
//
// 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.
//
// zrleEncode.h - zrle encoding function.
//
// 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 <rdr/OutStream.h>
#include <assert.h>
using
namespace
rdr
;
/* __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(rdr::U,BPP)
#define WRITE_PIXEL __RFB_CONCAT2E(writeOpaque,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(rdr::U,BPP)
#define WRITE_PIXEL __RFB_CONCAT2E(writeOpaque,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
};
// The PaletteHelper class helps us build up the palette from pixel data by
// storing a reverse index using a simple hash-table
class
PaletteHelper
{
public
:
enum
{
MAX_SIZE
=
127
};
PaletteHelper
()
{
memset
(
index
,
255
,
sizeof
(
index
));
size
=
0
;
}
inline
int
hash
(
rdr
::
U32
pix
)
{
return
(
pix
^
(
pix
>>
17
))
&
4095
;
}
inline
void
insert
(
rdr
::
U32
pix
)
{
if
(
size
<
MAX_SIZE
)
{
int
i
=
hash
(
pix
);
while
(
index
[
i
]
!=
255
&&
key
[
i
]
!=
pix
)
i
++
;
if
(
index
[
i
]
!=
255
)
return
;
index
[
i
]
=
size
;
key
[
i
]
=
pix
;
palette
[
size
]
=
pix
;
}
size
++
;
}
inline
int
lookup
(
rdr
::
U32
pix
)
{
assert
(
size
<=
MAX_SIZE
);
int
i
=
hash
(
pix
);
while
(
index
[
i
]
!=
255
&&
key
[
i
]
!=
pix
)
i
++
;
if
(
index
[
i
]
!=
255
)
return
index
[
i
];
return
-
1
;
}
rdr
::
U32
palette
[
MAX_SIZE
];
rdr
::
U8
index
[
4096
+
MAX_SIZE
];
rdr
::
U32
key
[
4096
+
MAX_SIZE
];
int
size
;
};
#endif
void
ZRLE_ENCODE_TILE
(
PIXEL_T
*
data
,
int
w
,
int
h
,
rdr
::
OutStream
*
os
);
void
ZRLE_ENCODE
(
int
x
,
int
y
,
int
w
,
int
h
,
rdr
::
OutStream
*
os
,
rdr
::
ZlibOutStream
*
zos
,
void
*
buf
EXTRA_ARGS
)
{
zos
->
setUnderlying
(
os
);
for
(
int
ty
=
y
;
ty
<
y
+
h
;
ty
+=
rfbZRLETileHeight
)
{
int
th
=
rfbZRLETileHeight
;
if
(
th
>
y
+
h
-
ty
)
th
=
y
+
h
-
ty
;
for
(
int
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
,
zos
);
}
}
zos
->
flush
();
}
void
ZRLE_ENCODE_TILE
(
PIXEL_T
*
data
,
int
w
,
int
h
,
rdr
::
OutStream
*
os
)
{
// First find the palette and the number of runs
PaletteHelper
ph
;
int
runs
=
0
;
int
singlePixels
=
0
;
PIXEL_T
*
ptr
=
data
;
PIXEL_T
*
end
=
ptr
+
h
*
w
;
*
end
=
~*
(
end
-
1
);
// one past the end is different so the while loop ends
while
(
ptr
<
end
)
{
PIXEL_T
pix
=
*
ptr
;
if
(
*++
ptr
!=
pix
)
{
singlePixels
++
;
}
else
{
while
(
*++
ptr
==
pix
)
;
runs
++
;
}
ph
.
insert
(
pix
);
}
//fprintf(stderr,"runs %d, single pixels %d, paletteSize %d\n",
// runs, singlePixels, ph.size);
// Solid tile is a special case
if
(
ph
.
size
==
1
)
{
os
->
writeU8
(
1
);
os
->
WRITE_PIXEL
(
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...
bool
useRle
=
false
;
bool
usePalette
=
false
;
int
estimatedBytes
=
w
*
h
*
(
BPPOUT
/
8
);
// start assuming raw
int
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
;
os
->
writeU8
((
useRle
?
128
:
0
)
|
ph
.
size
);
for
(
int
i
=
0
;
i
<
ph
.
size
;
i
++
)
{
os
->
WRITE_PIXEL
(
ph
.
palette
[
i
]);
}
if
(
useRle
)
{
PIXEL_T
*
ptr
=
data
;
PIXEL_T
*
end
=
ptr
+
w
*
h
;
PIXEL_T
*
runStart
;
PIXEL_T
pix
;
while
(
ptr
<
end
)
{
runStart
=
ptr
;
pix
=
*
ptr
++
;
while
(
*
ptr
==
pix
&&
ptr
<
end
)
ptr
++
;
int
len
=
ptr
-
runStart
;
if
(
len
<=
2
&&
usePalette
)
{
int
index
=
ph
.
lookup
(
pix
);
if
(
len
==
2
)
os
->
writeU8
(
index
);
os
->
writeU8
(
index
);
continue
;
}
if
(
usePalette
)
{
int
index
=
ph
.
lookup
(
pix
);
os
->
writeU8
(
index
|
128
);
}
else
{
os
->
WRITE_PIXEL
(
pix
);
}
len
-=
1
;
while
(
len
>=
255
)
{
os
->
writeU8
(
255
);
len
-=
255
;
}
os
->
writeU8
(
len
);
}
}
else
{
// no RLE
if
(
usePalette
)
{
// packed pixels
assert
(
ph
.
size
<
17
);
int
bppp
=
bitsPerPackedPixel
[
ph
.
size
-
1
];
PIXEL_T
*
ptr
=
data
;
for
(
int
i
=
0
;
i
<
h
;
i
++
)
{
U8
nbits
=
0
;
U8
byte
=
0
;
PIXEL_T
*
eol
=
ptr
+
w
;
while
(
ptr
<
eol
)
{
PIXEL_T
pix
=
*
ptr
++
;
U8
index
=
ph
.
lookup
(
pix
);
byte
=
(
byte
<<
bppp
)
|
index
;
nbits
+=
bppp
;
if
(
nbits
>=
8
)
{
os
->
writeU8
(
byte
);
nbits
=
0
;
}
}
if
(
nbits
>
0
)
{
byte
<<=
8
-
nbits
;
os
->
writeU8
(
byte
);
}
}
}
else
{
// raw
#ifdef CPIXEL
for
(
PIXEL_T
*
ptr
=
data
;
ptr
<
data
+
w
*
h
;
ptr
++
)
{
os
->
WRITE_PIXEL
(
*
ptr
);
}
#else
os
->
writeBytes
(
data
,
w
*
h
*
(
BPP
/
8
));
#endif
}
}
}
#undef PIXEL_T
#undef WRITE_PIXEL
#undef ZRLE_ENCODE
#undef ZRLE_ENCODE_TILE
#undef BPPOUT
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment