Keep the generic stream classes clean and general.tags/v1.3.90
@@ -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. | |||
@@ -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. | |||
@@ -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; | |||
} |
@@ -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); |
@@ -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); | |||
} | |||
} | |||
} |
@@ -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); |
@@ -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) |
@@ -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 |
@@ -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"); | |||
} |
@@ -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) |
@@ -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 { |
@@ -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)); |