From 7b5c069d2e7eaa1748507a03697c14900258e507 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 17 Mar 2014 14:35:51 +0100 Subject: [PATCH] Push encoding specific formats into the encoders and decoders Keep the generic stream classes clean and general. --- common/rdr/InStream.h | 23 ----------------------- common/rdr/OutStream.h | 25 ------------------------- common/rfb/TightDecoder.cxx | 19 +++++++++++++++++++ common/rfb/TightDecoder.h | 2 ++ common/rfb/TightEncoder.cxx | 18 ++++++++++++++++++ common/rfb/TightEncoder.h | 2 ++ common/rfb/ZRLEDecoder.cxx | 20 ++++++++++++++++++++ common/rfb/ZRLEEncoder.cxx | 15 +++++++++++++++ common/rfb/tightDecode.h | 4 ++-- common/rfb/tightEncode.h | 4 ++-- common/rfb/zrleDecode.h | 10 +++++----- common/rfb/zrleEncode.h | 12 ++++++------ 12 files changed, 91 insertions(+), 63 deletions(-) diff --git a/common/rdr/InStream.h b/common/rdr/InStream.h index 6d22ac6a..760fb3dc 100644 --- a/common/rdr/InStream.h +++ b/common/rdr/InStream.h @@ -71,23 +71,6 @@ namespace rdr { inline S16 readS16() { return (S16)readU16(); } inline S32 readS32() { return (S32)readU32(); } - // readCompactLength() reads 1..3 bytes representing length of the data - // following. This method is used by the Tight decoder. - - inline unsigned int readCompactLength() { - U8 b = readU8(); - int result = (int)b & 0x7F; - if (b & 0x80) { - b = readU8(); - result |= ((int)b & 0x7F) << 7; - if (b & 0x80) { - b = readU8(); - result |= ((int)b & 0xFF) << 14; - } - } - return result; - } - // readString() reads a string - a U32 length followed by the data. // Returns a null-terminated string - the caller should delete[] it // afterwards. @@ -128,12 +111,6 @@ namespace rdr { inline U32 readOpaque32() { check(4); U32 r; ((U8*)&r)[0] = *ptr++; ((U8*)&r)[1] = *ptr++; ((U8*)&r)[2] = *ptr++; ((U8*)&r)[3] = *ptr++; return r; } - inline U32 readOpaque24A() { check(3); U32 r=0; ((U8*)&r)[0] = *ptr++; - ((U8*)&r)[1] = *ptr++; ((U8*)&r)[2] = *ptr++; - return r; } - inline U32 readOpaque24B() { check(3); U32 r=0; ((U8*)&r)[1] = *ptr++; - ((U8*)&r)[2] = *ptr++; ((U8*)&r)[3] = *ptr++; - return r; } // pos() returns the position in the stream. diff --git a/common/rdr/OutStream.h b/common/rdr/OutStream.h index aed2eea1..4afd4bfb 100644 --- a/common/rdr/OutStream.h +++ b/common/rdr/OutStream.h @@ -65,25 +65,6 @@ namespace rdr { inline void writeS16(S16 s) { writeU16((U16)s); } inline void writeS32(S32 s) { writeU32((U32)s); } - // writeCompactLength() writes 1..3 bytes representing length of the data - // following. This method is used by the Tight encoder. - - inline void writeCompactLength(unsigned int len) { - U8 b = len & 0x7F; - if (len <= 0x7F) { - writeU8(b); - } else { - writeU8(b | 0x80); - b = len >> 7 & 0x7F; - if (len <= 0x3FFF) { - writeU8(b); - } else { - writeU8(b | 0x80); - writeU8(len >> 14 & 0xFF); - } - } - } - // writeString() writes a string - a U32 length followed by the data. The // given string should be null-terminated (but the terminating null is not // written to the stream). @@ -128,12 +109,6 @@ namespace rdr { *ptr++ = ((U8*)&u)[1]; *ptr++ = ((U8*)&u)[2]; *ptr++ = ((U8*)&u)[3]; } - inline void writeOpaque24A(U32 u) { check(3); *ptr++ = ((U8*)&u)[0]; - *ptr++ = ((U8*)&u)[1]; - *ptr++ = ((U8*)&u)[2]; } - inline void writeOpaque24B(U32 u) { check(3); *ptr++ = ((U8*)&u)[1]; - *ptr++ = ((U8*)&u)[2]; - *ptr++ = ((U8*)&u)[3]; } // length() returns the length of the stream. diff --git a/common/rfb/TightDecoder.cxx b/common/rfb/TightDecoder.cxx index 83e84f70..635df551 100644 --- a/common/rfb/TightDecoder.cxx +++ b/common/rfb/TightDecoder.cxx @@ -69,3 +69,22 @@ void TightDecoder::readRect(const Rect& r, CMsgHandler* handler) tightDecode32(r); break; } } + +rdr::U32 TightDecoder::readCompact(rdr::InStream* is) +{ + rdr::U8 b; + rdr::U32 result; + + b = is->readU8(); + result = (int)b & 0x7F; + if (b & 0x80) { + b = is->readU8(); + result |= ((int)b & 0x7F) << 7; + if (b & 0x80) { + b = is->readU8(); + result |= ((int)b & 0xFF) << 14; + } + } + + return result; +} diff --git a/common/rfb/TightDecoder.h b/common/rfb/TightDecoder.h index 0b915f92..18b01f8a 100644 --- a/common/rfb/TightDecoder.h +++ b/common/rfb/TightDecoder.h @@ -33,6 +33,8 @@ namespace rfb { virtual void readRect(const Rect& r, CMsgHandler* handler); private: + rdr::U32 readCompact(rdr::InStream* is); + void tightDecode8(const Rect& r); void tightDecode16(const Rect& r); void tightDecode32(const Rect& r); diff --git a/common/rfb/TightEncoder.cxx b/common/rfb/TightEncoder.cxx index 622dc3d4..b94b53e3 100644 --- a/common/rfb/TightEncoder.cxx +++ b/common/rfb/TightEncoder.cxx @@ -410,3 +410,21 @@ void TightEncoder::writeSubrect(const Rect& r, bool forceSolid) os->writeBytes(mos.data(), mos.length()); writer->endRect(); } + +void TightEncoder::writeCompact(rdr::OutStream* os, rdr::U32 value) +{ + rdr::U8 b; + b = value & 0x7F; + if (value <= 0x7F) { + os->writeU8(b); + } else { + os->writeU8(b | 0x80); + b = value >> 7 & 0x7F; + if (value <= 0x3FFF) { + os->writeU8(b); + } else { + os->writeU8(b | 0x80); + os->writeU8(value >> 14 & 0xFF); + } + } +} diff --git a/common/rfb/TightEncoder.h b/common/rfb/TightEncoder.h index a876b6f6..b633512f 100644 --- a/common/rfb/TightEncoder.h +++ b/common/rfb/TightEncoder.h @@ -74,6 +74,8 @@ namespace rfb { void sendRectSimple(const Rect& r); void writeSubrect(const Rect& r, bool forceSolid = false); + void writeCompact(rdr::OutStream* os, rdr::U32 value); + void compressData(const void *buf, unsigned int length, rdr::ZlibOutStream *zos, int zlibLevel, rdr::OutStream *os); diff --git a/common/rfb/ZRLEDecoder.cxx b/common/rfb/ZRLEDecoder.cxx index 20fe853c..ffc24e3c 100644 --- a/common/rfb/ZRLEDecoder.cxx +++ b/common/rfb/ZRLEDecoder.cxx @@ -21,6 +21,26 @@ using namespace rfb; +static inline rdr::U32 readOpaque24A(rdr::InStream* is) +{ + is->check(3); + rdr::U32 r=0; + ((rdr::U8*)&r)[0] = is->readU8(); + ((rdr::U8*)&r)[1] = is->readU8(); + ((rdr::U8*)&r)[2] = is->readU8(); + return r; + +} +static inline rdr::U32 readOpaque24B(rdr::InStream* is) +{ + is->check(3); + rdr::U32 r=0; + ((rdr::U8*)&r)[1] = is->readU8(); + ((rdr::U8*)&r)[2] = is->readU8(); + ((rdr::U8*)&r)[3] = is->readU8(); + return r; +} + #define EXTRA_ARGS CMsgHandler* handler #define FILL_RECT(r, p) handler->fillRect(r, p) #define IMAGE_RECT(r, p) handler->imageRect(r, p) diff --git a/common/rfb/ZRLEEncoder.cxx b/common/rfb/ZRLEEncoder.cxx index df7cfbdb..840af6be 100644 --- a/common/rfb/ZRLEEncoder.cxx +++ b/common/rfb/ZRLEEncoder.cxx @@ -28,6 +28,21 @@ using namespace rfb; IntParameter zlibLevel("ZlibLevel","Zlib compression level",-1); +static inline void writeOpaque24A(rdr::OutStream* os, rdr::U32 u) +{ + os->check(3); + os->writeU8(((rdr::U8*)&u)[0]); + os->writeU8(((rdr::U8*)&u)[1]); + os->writeU8(((rdr::U8*)&u)[2]); +} +static inline void writeOpaque24B(rdr::OutStream* os, rdr::U32 u) +{ + os->check(3); + os->writeU8(((rdr::U8*)&u)[1]); + os->writeU8(((rdr::U8*)&u)[2]); + os->writeU8(((rdr::U8*)&u)[3]); +} + #define EXTRA_ARGS ImageGetter* ig #define GET_IMAGE_INTO_BUF(r,buf) ig->getImage(buf, r); #define BPP 8 diff --git a/common/rfb/tightDecode.h b/common/rfb/tightDecode.h index 06c84775..e1399431 100644 --- a/common/rfb/tightDecode.h +++ b/common/rfb/tightDecode.h @@ -141,7 +141,7 @@ void TIGHT_DECODE (const Rect& r) if (dataSize < TIGHT_MIN_TO_COMPRESS) { input = is; } else { - int length = is->readCompactLength(); + int length = readCompact(is); streamId = comp_ctl & 0x03; zis[streamId].setUnderlying(is, length); input = &zis[streamId]; @@ -242,7 +242,7 @@ void DECOMPRESS_JPEG_RECT(const Rect& r) { // Read length - int compressedLen = is->readCompactLength(); + int compressedLen = readCompact(is); if (compressedLen <= 0) { throw Exception("Incorrect data received from the server.\n"); } diff --git a/common/rfb/tightEncode.h b/common/rfb/tightEncode.h index 62665300..1fd0f530 100644 --- a/common/rfb/tightEncode.h +++ b/common/rfb/tightEncode.h @@ -76,7 +76,7 @@ void TightEncoder::compressData(const void *buf, unsigned int length, zos->writeBytes(buf, length); zos->flush(); zos->setUnderlying(NULL); - os->writeCompactLength(mem_os.length()); + writeCompact(os, mem_os.length()); os->writeBytes(mem_os.data(), mem_os.length()); } } @@ -336,7 +336,7 @@ void ENCODE_JPEG_RECT (PIXEL_T *buf, int stride, const Rect& r, jc.compress((rdr::U8 *)buf, stride, r, clientpf, jpegQuality, jpegSubsampling); os->writeU8(0x09 << 4); - os->writeCompactLength(jc.length()); + writeCompact(os, jc.length()); os->writeBytes(jc.data(), jc.length()); } #endif // #if (BPP != 8) diff --git a/common/rfb/zrleDecode.h b/common/rfb/zrleDecode.h index d26d4d3e..207a6c74 100644 --- a/common/rfb/zrleDecode.h +++ b/common/rfb/zrleDecode.h @@ -41,11 +41,11 @@ namespace rfb { #ifdef CPIXEL #define PIXEL_T rdr::CONCAT2E(U,BPP) -#define READ_PIXEL CONCAT2E(readOpaque,CPIXEL) +#define READ_PIXEL(is) CONCAT2E(readOpaque,CPIXEL)(is) #define ZRLE_DECODE CONCAT2E(zrleDecode,CPIXEL) #else #define PIXEL_T rdr::CONCAT2E(U,BPP) -#define READ_PIXEL CONCAT2E(readOpaque,BPP) +#define READ_PIXEL(is) is->CONCAT2E(readOpaque,BPP)() #define ZRLE_DECODE CONCAT2E(zrleDecode,BPP) #endif @@ -74,7 +74,7 @@ void ZRLE_DECODE (const Rect& r, rdr::InStream* is, PIXEL_T palette[128]; for (int i = 0; i < palSize; i++) { - palette[i] = zis->READ_PIXEL(); + palette[i] = READ_PIXEL(zis); } if (palSize == 1) { @@ -90,7 +90,7 @@ void ZRLE_DECODE (const Rect& r, rdr::InStream* is, #ifdef CPIXEL for (PIXEL_T* ptr = buf; ptr < buf+t.area(); ptr++) { - *ptr = zis->READ_PIXEL(); + *ptr = READ_PIXEL(zis); } #else zis->readBytes(buf, t.area() * (BPP / 8)); @@ -130,7 +130,7 @@ void ZRLE_DECODE (const Rect& r, rdr::InStream* is, PIXEL_T* ptr = buf; PIXEL_T* end = ptr + t.area(); while (ptr < end) { - PIXEL_T pix = zis->READ_PIXEL(); + PIXEL_T pix = READ_PIXEL(zis); int len = 1; int b; do { diff --git a/common/rfb/zrleEncode.h b/common/rfb/zrleEncode.h index 34b5c675..cfc2a469 100644 --- a/common/rfb/zrleEncode.h +++ b/common/rfb/zrleEncode.h @@ -45,13 +45,13 @@ namespace rfb { #ifdef CPIXEL #define PIXEL_T rdr::CONCAT2E(U,BPP) -#define WRITE_PIXEL CONCAT2E(writeOpaque,CPIXEL) +#define WRITE_PIXEL(os, u) CONCAT2E(writeOpaque,CPIXEL)(os, u) #define ZRLE_ENCODE CONCAT2E(zrleEncode,CPIXEL) #define ZRLE_ENCODE_TILE CONCAT2E(zrleEncodeTile,CPIXEL) #define BPPOUT 24 #else #define PIXEL_T rdr::CONCAT2E(U,BPP) -#define WRITE_PIXEL CONCAT2E(writeOpaque,BPP) +#define WRITE_PIXEL(os, u) os->CONCAT2E(writeOpaque,BPP)(u) #define ZRLE_ENCODE CONCAT2E(zrleEncode,BPP) #define ZRLE_ENCODE_TILE CONCAT2E(zrleEncodeTile,BPP) #define BPPOUT BPP @@ -129,7 +129,7 @@ void ZRLE_ENCODE_TILE (PIXEL_T* data, int w, int h, rdr::OutStream* os) if (palette.size() == 1) { os->writeU8(1); - os->WRITE_PIXEL(palette.getColour(0)); + WRITE_PIXEL(os, palette.getColour(0)); return; } @@ -176,7 +176,7 @@ void ZRLE_ENCODE_TILE (PIXEL_T* data, int w, int h, rdr::OutStream* os) os->writeU8((useRle ? 128 : 0) | palette.size()); for (int i = 0; i < palette.size(); i++) { - os->WRITE_PIXEL(palette.getColour(i)); + WRITE_PIXEL(os, palette.getColour(i)); } if (useRle) { @@ -202,7 +202,7 @@ void ZRLE_ENCODE_TILE (PIXEL_T* data, int w, int h, rdr::OutStream* os) int index = palette.lookup(pix); os->writeU8(index | 128); } else { - os->WRITE_PIXEL(pix); + WRITE_PIXEL(os, pix); } len -= 1; while (len >= 255) { @@ -253,7 +253,7 @@ void ZRLE_ENCODE_TILE (PIXEL_T* data, int w, int h, rdr::OutStream* os) #ifdef CPIXEL for (PIXEL_T* ptr = data; ptr < data+w*h; ptr++) { - os->WRITE_PIXEL(*ptr); + WRITE_PIXEL(os, *ptr); } #else os->writeBytes(data, w*h*(BPP/8)); -- 2.39.5