Browse Source

Merge further fixes to Zlib encoder from 1.1 branch


git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4623 3789f03b-4d11-0410-bbf8-ca57d06f2519
tags/v1.1.90
DRC 13 years ago
parent
commit
ff5ca2da00
3 changed files with 35 additions and 11 deletions
  1. 26
    6
      common/rdr/ZlibOutStream.cxx
  2. 2
    0
      common/rdr/ZlibOutStream.h
  3. 7
    5
      common/rfb/tightEncode.h

+ 26
- 6
common/rdr/ZlibOutStream.cxx View File



ZlibOutStream::ZlibOutStream(OutStream* os, int bufSize_, int compressLevel) ZlibOutStream::ZlibOutStream(OutStream* os, int bufSize_, int compressLevel)
: underlying(os), compressionLevel(compressLevel), newLevel(compressLevel), : underlying(os), compressionLevel(compressLevel), newLevel(compressLevel),
bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0)
bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0),
newBehavior(false)
{ {
zs = new z_stream; zs = new z_stream;
zs->zalloc = Z_NULL; zs->zalloc = Z_NULL;
} }
ptr = start = new U8[bufSize]; ptr = start = new U8[bufSize];
end = start + bufSize; end = start + bufSize;
const char *version = zlibVersion();
if (strcmp(version, "1.2.3") > 0) newBehavior = true;
} }


ZlibOutStream::~ZlibOutStream() ZlibOutStream::~ZlibOutStream()


// fprintf(stderr,"zos flush: avail_in %d\n",zs->avail_in); // fprintf(stderr,"zos flush: avail_in %d\n",zs->avail_in);


if (!underlying)
throw Exception("ZlibOutStream: underlying OutStream has not been set");

while (zs->avail_in != 0) { while (zs->avail_in != 0) {


do { do {
if (itemSize > bufSize) if (itemSize > bufSize)
throw Exception("ZlibOutStream overrun: max itemSize exceeded"); throw Exception("ZlibOutStream overrun: max itemSize exceeded");


if (!underlying)
throw Exception("ZlibOutStream: underlying OutStream has not been set");

while (end - ptr < itemSize) { while (end - ptr < itemSize) {
zs->next_in = start; zs->next_in = start;
zs->avail_in = ptr - start; zs->avail_in = ptr - start;
// fprintf(stderr,"zos overrun: calling deflate, avail_in %d, avail_out %d\n", // fprintf(stderr,"zos overrun: calling deflate, avail_in %d, avail_out %d\n",
// zs->avail_in,zs->avail_out); // zs->avail_in,zs->avail_out);


checkCompressionLevel();
if (zs->avail_in != 0) {
int rc = deflate(zs, 0);
if (rc != Z_OK) throw Exception("ZlibOutStream: deflate failed");
}
checkCompressionLevel();
if (zs->avail_in != 0) {
int rc = deflate(zs, 0);
if (rc != Z_OK) throw Exception("ZlibOutStream: deflate failed");
}


// fprintf(stderr,"zos overrun: after deflate: %d bytes\n", // fprintf(stderr,"zos overrun: after deflate: %d bytes\n",
// zs->next_out-underlying->getptr()); // zs->next_out-underlying->getptr());
void ZlibOutStream::checkCompressionLevel() void ZlibOutStream::checkCompressionLevel()
{ {
if (newLevel != compressionLevel) { if (newLevel != compressionLevel) {

// This is a horrible hack, but after many hours of trying, I couldn't find
// a better way to make this class work properly with both Zlib 1.2.3 and
// 1.2.5. 1.2.3 does a Z_PARTIAL_FLUSH in the body of deflateParams() if
// the compression level has changed, and 1.2.5 does a Z_BLOCK flush.

if (newBehavior) {
int rc = deflate(zs, Z_SYNC_FLUSH);
if (rc != Z_OK) throw Exception("ZlibOutStream: deflate failed");
}

if (deflateParams (zs, newLevel, Z_DEFAULT_STRATEGY) != Z_OK) { if (deflateParams (zs, newLevel, Z_DEFAULT_STRATEGY) != Z_OK) {
throw Exception("ZlibOutStream: deflateParams failed"); throw Exception("ZlibOutStream: deflateParams failed");
} }

+ 2
- 0
common/rdr/ZlibOutStream.h View File

/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
* Copyright (C) 2011 D. R. Commander. 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
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
int offset; int offset;
z_stream_s* zs; z_stream_s* zs;
U8* start; U8* start;
bool newBehavior;
}; };


} // end of namespace rdr } // end of namespace rdr

+ 7
- 5
common/rfb/tightEncode.h View File

// //


static void compressData(rdr::OutStream *os, rdr::ZlibOutStream *zos, static void compressData(rdr::OutStream *os, rdr::ZlibOutStream *zos,
const void *buf, unsigned int length, int zlibLevel)
const void *buf, const PixelFormat& pf,
unsigned int length, int zlibLevel)
{ {
if (length < TIGHT_MIN_TO_COMPRESS) { if (length < TIGHT_MIN_TO_COMPRESS) {
os->writeBytes(buf, length); os->writeBytes(buf, length);
} else { } else {
// FIXME: Using a temporary MemOutStream may be not efficient. // FIXME: Using a temporary MemOutStream may be not efficient.
// Maybe use the same static object used in the JPEG coder? // Maybe use the same static object used in the JPEG coder?
int maxBeforeSize = s_pconf->maxRectSize * (BPP / 8);
int maxBeforeSize = s_pconf->maxRectSize * (pf.bpp / 8);
int maxAfterSize = maxBeforeSize + (maxBeforeSize + 99) / 100 + 12; int maxAfterSize = maxBeforeSize + (maxBeforeSize + 99) / 100 + 12;
rdr::MemOutStream mem_os(maxAfterSize); rdr::MemOutStream mem_os(maxAfterSize);
zos->setUnderlying(&mem_os); zos->setUnderlying(&mem_os);
zos->setCompressionLevel(zlibLevel); zos->setCompressionLevel(zlibLevel);
zos->writeBytes(buf, length); zos->writeBytes(buf, length);
zos->flush(); zos->flush();
zos->setUnderlying(NULL);
os->writeCompactLength(mem_os.length()); os->writeCompactLength(mem_os.length());
os->writeBytes(mem_os.data(), mem_os.length()); os->writeBytes(mem_os.data(), mem_os.length());
} }
os->writeU8(streamId << 4); os->writeU8(streamId << 4);


int length = PACK_PIXELS(buf, r.area(), pf); int length = PACK_PIXELS(buf, r.area(), pf);
compressData(os, &zos[streamId], buf, length, s_pconf->rawZlibLevel);
compressData(os, &zos[streamId], buf, pf, length, s_pconf->rawZlibLevel);
} }


static void ENCODE_MONO_RECT (rdr::OutStream *os, rdr::ZlibOutStream zos[4], static void ENCODE_MONO_RECT (rdr::OutStream *os, rdr::ZlibOutStream zos[4],
// Write the data // Write the data
int length = (w + 7) / 8; int length = (w + 7) / 8;
length *= h; length *= h;
compressData(os, &zos[streamId], buf, length, s_pconf->monoZlibLevel);
compressData(os, &zos[streamId], buf, pf, length, s_pconf->monoZlibLevel);
} }


#if (BPP != 8) #if (BPP != 8)
} }


// Write the data // Write the data
compressData(os, &zos[streamId], buf, r.area(), s_pconf->idxZlibLevel);
compressData(os, &zos[streamId], buf, pf, r.area(), s_pconf->idxZlibLevel);
} }
#endif // #if (BPP != 8) #endif // #if (BPP != 8)



Loading…
Cancel
Save