/*
 * zlib.c
 *
 * Routines to implement zlib based encoding (deflate).
 */

/*
 *  Copyright (C) 2000 Tridia Corporation.  All Rights Reserved.
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  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.
 *
 * For the latest source code, please check:
 *
 * http://www.developVNC.org/
 *
 * or send email to feedback@developvnc.org.
 */

#include <rfb/rfb.h>

/*
 * zlibBeforeBuf contains pixel data in the client's format.
 * zlibAfterBuf contains the zlib (deflated) encoding version.
 * If the zlib compressed/encoded version is
 * larger than the raw data or if it exceeds zlibAfterBufSize then
 * raw encoding is used instead.
 */

/*
 * Out of lazyiness, we use thread local storage for zlib as we did for
 * tight.  N.B. ZRLE does it the traditional way with per-client storage
 * (and so at least ZRLE will work threaded on older systems.)
 */
#if LIBVNCSERVER_HAVE_LIBPTHREAD && LIBVNCSERVER_HAVE_TLS && !defined(TLS) && defined(__linux__)
#define TLS __thread
#endif
#ifndef TLS
#define TLS
#endif

static TLS int zlibBeforeBufSize = 0;
static TLS char *zlibBeforeBuf = NULL;

static TLS int zlibAfterBufSize = 0;
static TLS char *zlibAfterBuf = NULL;
static TLS int zlibAfterBufLen = 0;

void rfbZlibCleanup(rfbScreenInfoPtr screen)
{
  if (zlibBeforeBufSize) {
    free(zlibBeforeBuf);
    zlibBeforeBufSize=0;
  }
  if (zlibAfterBufSize) {
    zlibAfterBufSize=0;
    free(zlibAfterBuf);
  }
}


/*
 * rfbSendOneRectEncodingZlib - send a given rectangle using one Zlib
 *                              rectangle encoding.
 */

static rfbBool
rfbSendOneRectEncodingZlib(rfbClientPtr cl,
                           int x,
                           int y,
                           int w,
                           int h)
{
    rfbFramebufferUpdateRectHeader rect;
    rfbZlibHeader hdr;
    int deflateResult;
    int previousOut;
    int i;
    char *fbptr = (cl->scaledScreen->frameBuffer + (cl->scaledScreen->paddedWidthInBytes * y)
    	   + (x * (cl->scaledScreen->bitsPerPixel / 8)));

    int maxRawSize;
    int maxCompSize;

    maxRawSize = (cl->scaledScreen->width * cl->scaledScreen->height
                  * (cl->format.bitsPerPixel / 8));

    if (zlibBeforeBufSize < maxRawSize) {
	zlibBeforeBufSize = maxRawSize;
	if (zlibBeforeBuf == NULL)
	    zlibBeforeBuf = (char *)malloc(zlibBeforeBufSize);
	else
	    zlibBeforeBuf = (char *)realloc(zlibBeforeBuf, zlibBeforeBufSize);
    }

    /* zlib compression is not useful for very small data sets.
     * So, we just send these raw without any compression.
     */
    if (( w * h * (cl->scaledScreen->bitsPerPixel / 8)) <
          VNC_ENCODE_ZLIB_MIN_COMP_SIZE ) {

        int result;

        /* The translation function (used also by the in raw encoding)
         * requires 4/2/1 byte alignment in the output buffer (which is
         * updateBuf for the raw encoding) based on the bitsPerPixel of
         * the viewer/client.  This prevents SIGBUS errors on some
         * architectures like SPARC, PARISC...
         */
        if (( cl->format.bitsPerPixel > 8 ) &&
            ( cl->ublen % ( cl->format.bitsPerPixel / 8 )) != 0 ) {
            if (!rfbSendUpdateBuf(cl))
                return FALSE;
        }

        result = rfbSendRectEncodingRaw(cl, x, y, w, h);

        return result;

    }

    /*
     * zlib requires output buffer to be slightly larger than the input
     * buffer, in the worst case.
     */
    maxCompSize = maxRawSize + (( maxRawSize + 99 ) / 100 ) + 12;

    if (zlibAfterBufSize < maxCompSize) {
	zlibAfterBufSize = maxCompSize;
	if (zlibAfterBuf == NULL)
	    zlibAfterBuf = (char *)malloc(zlibAfterBufSize);
	else
	    zlibAfterBuf = (char *)realloc(zlibAfterBuf, zlibAfterBufSize);
    }


    /* 
     * Convert pixel data to client format.
     */
    (*cl->translateFn)(cl->translateLookupTable, &cl->screen->serverFormat,
		       &cl->format, fbptr, zlibBeforeBuf,
		       cl->scaledScreen->paddedWidthInBytes, w, h);

    cl->compStream.next_in = ( Bytef * )zlibBeforeBuf;
    cl->compStream.avail_in = w * h * (cl->format.bitsPerPixel / 8);
    cl->compStream.next_out = ( Bytef * )zlibAfterBuf;
    cl->compStream.avail_out = maxCompSize;
    cl->compStream.data_type = Z_BINARY;

    /* Initialize the deflation state. */
    if ( cl->compStreamInited == FALSE ) {

        cl->compStream.total_in = 0;
        cl->compStream.total_out = 0;
        cl->compStream.zalloc = Z_NULL;
        cl->compStream.zfree = Z_NULL;
        cl->compStream.opaque = Z_NULL;

        deflateInit2( &(cl->compStream),
                        cl->zlibCompressLevel,
                        Z_DEFLATED,
                        MAX_WBITS,
                        MAX_MEM_LEVEL,
                        Z_DEFAULT_STRATEGY );
        /* deflateInit( &(cl->compStream), Z_BEST_COMPRESSION ); */
        /* deflateInit( &(cl->compStream), Z_BEST_SPEED ); */
        cl->compStreamInited = TRUE;

    }

    previousOut = cl->compStream.total_out;

    /* Perform the compression here. */
    deflateResult = deflate( &(cl->compStream), Z_SYNC_FLUSH );

    /* Find the total size of the resulting compressed data. */
    zlibAfterBufLen = cl->compStream.total_out - previousOut;

    if ( deflateResult != Z_OK ) {
        rfbErr("zlib deflation error: %s\n", cl->compStream.msg);
        return FALSE;
    }

    /* Note that it is not possible to switch zlib parameters based on
     * the results of the compression pass.  The reason is
     * that we rely on the compressor and decompressor states being
     * in sync.  Compressing and then discarding the results would
     * cause lose of synchronization.
     */

    /* Update statics */
    rfbStatRecordEncodingSent(cl, rfbEncodingZlib, sz_rfbFramebufferUpdateRectHeader + sz_rfbZlibHeader + zlibAfterBufLen,
        + w * (cl->format.bitsPerPixel / 8) * h);

    if (cl->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbZlibHeader
	> 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(rfbEncodingZlib);

    memcpy(&cl->updateBuf[cl->ublen], (char *)&rect,
	   sz_rfbFramebufferUpdateRectHeader);
    cl->ublen += sz_rfbFramebufferUpdateRectHeader;

    hdr.nBytes = Swap32IfLE(zlibAfterBufLen);

    memcpy(&cl->updateBuf[cl->ublen], (char *)&hdr, sz_rfbZlibHeader);
    cl->ublen += sz_rfbZlibHeader;

    for (i = 0; i < zlibAfterBufLen;) {

	int bytesToCopy = UPDATE_BUF_SIZE - cl->ublen;

	if (i + bytesToCopy > zlibAfterBufLen) {
	    bytesToCopy = zlibAfterBufLen - i;
	}

	memcpy(&cl->updateBuf[cl->ublen], &zlibAfterBuf[i], bytesToCopy);

	cl->ublen += bytesToCopy;
	i += bytesToCopy;

	if (cl->ublen == UPDATE_BUF_SIZE) {
	    if (!rfbSendUpdateBuf(cl))
		return FALSE;
	}
    }

    return TRUE;

}


/*
 * rfbSendRectEncodingZlib - send a given rectangle using one or more
 *                           Zlib encoding rectangles.
 */

rfbBool
rfbSendRectEncodingZlib(rfbClientPtr cl,
                        int x,
                        int y,
                        int w,
                        int h)
{
    int  maxLines;
    int  linesRemaining;
    rfbRectangle partialRect;

    partialRect.x = x;
    partialRect.y = y;
    partialRect.w = w;
    partialRect.h = h;

    /* Determine maximum pixel/scan lines allowed per rectangle. */
    maxLines = ( ZLIB_MAX_SIZE(w) / w );

    /* Initialize number of scan lines left to do. */
    linesRemaining = h;

    /* Loop until all work is done. */
    while ( linesRemaining > 0 ) {

        int linesToComp;

        if ( maxLines < linesRemaining )
            linesToComp = maxLines;
        else
            linesToComp = linesRemaining;

        partialRect.h = linesToComp;

        /* Encode (compress) and send the next rectangle. */
        if ( ! rfbSendOneRectEncodingZlib( cl,
                                           partialRect.x,
                                           partialRect.y,
                                           partialRect.w,
                                           partialRect.h )) {

            return FALSE;
        }

        /* Technically, flushing the buffer here is not extrememly
         * efficient.  However, this improves the overall throughput
         * of the system over very slow networks.  By flushing
         * the buffer with every maximum size zlib rectangle, we
         * improve the pipelining usage of the server CPU, network,
         * and viewer CPU components.  Insuring that these components
         * are working in parallel actually improves the performance
         * seen by the user.
         * Since, zlib is most useful for slow networks, this flush
         * is appropriate for the desired behavior of the zlib encoding.
         */
        if (( cl->ublen > 0 ) &&
            ( linesToComp == maxLines )) {
            if (!rfbSendUpdateBuf(cl)) {

                return FALSE;
            }
        }

        /* Update remaining and incremental rectangle location. */
        linesRemaining -= linesToComp;
        partialRect.y += linesToComp;

    }

    return TRUE;

}

