⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tight.c

📁 远程桌面连接工具
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * tight.c * * Routines to implement Tight Encoding *//* *  Copyright (C) 2000, 2001 Const Kaplinsky.  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. */#include <stdio.h>#include "rfb.h"#include <jpeglib.h>/* Note: The following constant should not be changed. */#define TIGHT_MIN_TO_COMPRESS 12/* The parameters below may be adjusted. */#define MIN_SPLIT_RECT_SIZE     4096#define MIN_SOLID_SUBRECT_SIZE  2048#define MAX_SPLIT_TILE_SIZE       16/* May be set to TRUE with "-lazytight" Xvnc option. */Bool rfbTightDisableGradient = FALSE;/* This variable is set on every rfbSendRectEncodingTight() call. */static Bool usePixelFormat24;/* Compression level stuff. The following array contains various   encoder parameters for each of 10 compression levels (0..9).   Last three parameters correspond to JPEG quality levels (0..9). */typedef struct TIGHT_CONF_s {    int maxRectSize, maxRectWidth;    int monoMinRectSize, gradientMinRectSize;    int idxZlibLevel, monoZlibLevel, rawZlibLevel, gradientZlibLevel;    int gradientThreshold, gradientThreshold24;    int idxMaxColorsDivisor;    int jpegQuality, jpegThreshold, jpegThreshold24;} TIGHT_CONF;static TIGHT_CONF tightConf[10] = {    {   512,   32,   6, 65536, 0, 0, 0, 0,   0,   0,   4,  5, 10000, 23000 },    {  2048,  128,   6, 65536, 1, 1, 1, 0,   0,   0,   8, 10,  8000, 18000 },    {  6144,  256,   8, 65536, 3, 3, 2, 0,   0,   0,  24, 15,  6500, 15000 },    { 10240, 1024,  12, 65536, 5, 5, 3, 0,   0,   0,  32, 25,  5000, 12000 },    { 16384, 2048,  12, 65536, 6, 6, 4, 0,   0,   0,  32, 37,  4000, 10000 },    { 32768, 2048,  12,  4096, 7, 7, 5, 4, 150, 380,  32, 50,  3000,  8000 },    { 65536, 2048,  16,  4096, 7, 7, 6, 4, 170, 420,  48, 60,  2000,  5000 },    { 65536, 2048,  16,  4096, 8, 8, 7, 5, 180, 450,  64, 70,  1000,  2500 },    { 65536, 2048,  32,  8192, 9, 9, 8, 6, 190, 475,  64, 75,   500,  1200 },    { 65536, 2048,  32,  8192, 9, 9, 9, 6, 200, 500,  96, 80,   200,   500 }};static int compressLevel;static int qualityLevel;/* Stuff dealing with palettes. */typedef struct COLOR_LIST_s {    struct COLOR_LIST_s *next;    int idx;    CARD32 rgb;} COLOR_LIST;typedef struct PALETTE_ENTRY_s {    COLOR_LIST *listNode;    int numPixels;} PALETTE_ENTRY;typedef struct PALETTE_s {    PALETTE_ENTRY entry[256];    COLOR_LIST *hash[256];    COLOR_LIST list[256];} PALETTE;static int paletteNumColors, paletteMaxColors;static CARD32 monoBackground, monoForeground;static PALETTE palette;/* Pointers to dynamically-allocated buffers. */static int tightBeforeBufSize = 0;static char *tightBeforeBuf = NULL;static int tightAfterBufSize = 0;static char *tightAfterBuf = NULL;static int *prevRowBuf = NULL;/* Prototypes for static functions. */static void FindBestSolidArea (int x, int y, int w, int h,                               CARD32 colorValue, int *w_ptr, int *h_ptr);static void ExtendSolidArea   (int x, int y, int w, int h,                               CARD32 colorValue,                               int *x_ptr, int *y_ptr, int *w_ptr, int *h_ptr);static Bool CheckSolidTile    (int x, int y, int w, int h,                               CARD32 *colorPtr, Bool needSameColor);static Bool CheckSolidTile8   (int x, int y, int w, int h,                               CARD32 *colorPtr, Bool needSameColor);static Bool CheckSolidTile16  (int x, int y, int w, int h,                               CARD32 *colorPtr, Bool needSameColor);static Bool CheckSolidTile32  (int x, int y, int w, int h,                               CARD32 *colorPtr, Bool needSameColor);static Bool SendRectSimple    (rfbClientPtr cl, int x, int y, int w, int h);static Bool SendSubrect       (rfbClientPtr cl, int x, int y, int w, int h);static Bool SendTightHeader   (rfbClientPtr cl, int x, int y, int w, int h);static Bool SendSolidRect     (rfbClientPtr cl);static Bool SendMonoRect      (rfbClientPtr cl, int w, int h);static Bool SendIndexedRect   (rfbClientPtr cl, int w, int h);static Bool SendFullColorRect (rfbClientPtr cl, int w, int h);static Bool SendGradientRect  (rfbClientPtr cl, int w, int h);static Bool CompressData(rfbClientPtr cl, int streamId, int dataLen,                         int zlibLevel, int zlibStrategy);static Bool SendCompressedData(rfbClientPtr cl, int compressedLen);static void FillPalette8(int count);static void FillPalette16(int count);static void FillPalette32(int count);static void PaletteReset(void);static int PaletteInsert(CARD32 rgb, int numPixels, int bpp);static void Pack24(char *buf, rfbPixelFormat *fmt, int count);static void EncodeIndexedRect16(CARD8 *buf, int count);static void EncodeIndexedRect32(CARD8 *buf, int count);static void EncodeMonoRect8(CARD8 *buf, int w, int h);static void EncodeMonoRect16(CARD8 *buf, int w, int h);static void EncodeMonoRect32(CARD8 *buf, int w, int h);static void FilterGradient24(char *buf, rfbPixelFormat *fmt, int w, int h);static void FilterGradient16(CARD16 *buf, rfbPixelFormat *fmt, int w, int h);static void FilterGradient32(CARD32 *buf, rfbPixelFormat *fmt, int w, int h);static int DetectSmoothImage(rfbPixelFormat *fmt, int w, int h);static unsigned long DetectSmoothImage24(rfbPixelFormat *fmt, int w, int h);static unsigned long DetectSmoothImage16(rfbPixelFormat *fmt, int w, int h);static unsigned long DetectSmoothImage32(rfbPixelFormat *fmt, int w, int h);static Bool SendJpegRect(rfbClientPtr cl, int x, int y, int w, int h,                         int quality);static void PrepareRowForJpeg(CARD8 *dst, int x, int y, int count);static void PrepareRowForJpeg24(CARD8 *dst, int x, int y, int count);static void PrepareRowForJpeg16(CARD8 *dst, int x, int y, int count);static void PrepareRowForJpeg32(CARD8 *dst, int x, int y, int count);static void JpegInitDestination(j_compress_ptr cinfo);static boolean JpegEmptyOutputBuffer(j_compress_ptr cinfo);static void JpegTermDestination(j_compress_ptr cinfo);static void JpegSetDstManager(j_compress_ptr cinfo);/* * Tight encoding implementation. */intrfbNumCodedRectsTight(cl, x, y, w, h)    rfbClientPtr cl;    int x, y, w, h;{    int maxRectSize, maxRectWidth;    int subrectMaxWidth, subrectMaxHeight;    /* No matter how many rectangles we will send if LastRect markers       are used to terminate rectangle stream. */    if (cl->enableLastRectEncoding && w * h >= MIN_SPLIT_RECT_SIZE)      return 0;    maxRectSize = tightConf[cl->tightCompressLevel].maxRectSize;    maxRectWidth = tightConf[cl->tightCompressLevel].maxRectWidth;    if (w > maxRectWidth || w * h > maxRectSize) {        subrectMaxWidth = (w > maxRectWidth) ? maxRectWidth : w;        subrectMaxHeight = maxRectSize / subrectMaxWidth;        return (((w - 1) / maxRectWidth + 1) *                ((h - 1) / subrectMaxHeight + 1));    } else {        return 1;    }}BoolrfbSendRectEncodingTight(cl, x, y, w, h)    rfbClientPtr cl;    int x, y, w, h;{    int nMaxRows;    CARD32 colorValue;    int dx, dy, dw, dh;    int x_best, y_best, w_best, h_best;    char *fbptr;    compressLevel = cl->tightCompressLevel;    qualityLevel = cl->tightQualityLevel;    if ( cl->format.depth == 24 && cl->format.redMax == 0xFF &&         cl->format.greenMax == 0xFF && cl->format.blueMax == 0xFF ) {        usePixelFormat24 = TRUE;    } else {        usePixelFormat24 = FALSE;    }    if (!cl->enableLastRectEncoding || w * h < MIN_SPLIT_RECT_SIZE)        return SendRectSimple(cl, x, y, w, h);    /* Make sure we can write at least one pixel into tightBeforeBuf. */    if (tightBeforeBufSize < 4) {        tightBeforeBufSize = 4;        if (tightBeforeBuf == NULL)            tightBeforeBuf = (char *)xalloc(tightBeforeBufSize);        else            tightBeforeBuf = (char *)xrealloc(tightBeforeBuf,                                              tightBeforeBufSize);    }    /* Calculate maximum number of rows in one non-solid rectangle. */    {        int maxRectSize, maxRectWidth, nMaxWidth;        maxRectSize = tightConf[compressLevel].maxRectSize;        maxRectWidth = tightConf[compressLevel].maxRectWidth;        nMaxWidth = (w > maxRectWidth) ? maxRectWidth : w;        nMaxRows = maxRectSize / nMaxWidth;    }    /* Try to find large solid-color areas and send them separately. */    for (dy = y; dy < y + h; dy += MAX_SPLIT_TILE_SIZE) {        /* If a rectangle becomes too large, send its upper part now. */        if (dy - y >= nMaxRows) {            if (!SendRectSimple(cl, x, y, w, nMaxRows))                return 0;            y += nMaxRows;            h -= nMaxRows;        }        dh = (dy + MAX_SPLIT_TILE_SIZE <= y + h) ?            MAX_SPLIT_TILE_SIZE : (y + h - dy);        for (dx = x; dx < x + w; dx += MAX_SPLIT_TILE_SIZE) {            dw = (dx + MAX_SPLIT_TILE_SIZE <= x + w) ?                MAX_SPLIT_TILE_SIZE : (x + w - dx);            if (CheckSolidTile(dx, dy, dw, dh, &colorValue, FALSE)) {                /* Get dimensions of solid-color area. */                FindBestSolidArea(dx, dy, w - (dx - x), h - (dy - y),				  colorValue, &w_best, &h_best);                /* Make sure a solid rectangle is large enough                   (or the whole rectangle is of the same color). */                if ( w_best * h_best != w * h &&                     w_best * h_best < MIN_SOLID_SUBRECT_SIZE )                    continue;                /* Try to extend solid rectangle to maximum size. */                x_best = dx; y_best = dy;                ExtendSolidArea(x, y, w, h, colorValue,                                &x_best, &y_best, &w_best, &h_best);                /* Send rectangles at top and left to solid-color area. */                if ( y_best != y &&                     !SendRectSimple(cl, x, y, w, y_best-y) )                    return FALSE;                if ( x_best != x &&                     !rfbSendRectEncodingTight(cl, x, y_best,                                               x_best-x, h_best) )                    return FALSE;                /* Send solid-color rectangle. */                if (!SendTightHeader(cl, x_best, y_best, w_best, h_best))                    return FALSE;                fbptr = (rfbScreen.pfbMemory +                         (rfbScreen.paddedWidthInBytes * y_best) +                         (x_best * (rfbScreen.bitsPerPixel / 8)));                (*cl->translateFn)(cl->translateLookupTable, &rfbServerFormat,                                   &cl->format, fbptr, tightBeforeBuf,                                   rfbScreen.paddedWidthInBytes, 1, 1);                if (!SendSolidRect(cl))                    return FALSE;                /* Send remaining rectangles (at right and bottom). */                if ( x_best + w_best != x + w &&                     !rfbSendRectEncodingTight(cl, x_best+w_best, y_best,                                               w-(x_best-x)-w_best, h_best) )                    return FALSE;                if ( y_best + h_best != y + h &&                     !rfbSendRectEncodingTight(cl, x, y_best+h_best,                                               w, h-(y_best-y)-h_best) )                    return FALSE;                /* Return after all recursive calls are done. */                return TRUE;            }        }    }    /* No suitable solid-color rectangles found. */    return SendRectSimple(cl, x, y, w, h);}static voidFindBestSolidArea(x, y, w, h, colorValue, w_ptr, h_ptr)    int x, y, w, h;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -