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

📄 tight.c

📁 远程桌面连接工具
💻 C
📖 第 1 页 / 共 5 页
字号:
                pixHere[c] = (int)(pix >> shiftBits[c] & maxColor[c]);   \                *prevRowPtr++ = pixHere[c];                              \                                                                         \                prediction = pixLeft[c] + pixUpper[c] - pixUpperLeft[c]; \                if (prediction < 0) {                                    \                    prediction = 0;                                      \                } else if (prediction > maxColor[c]) {                   \                    prediction = maxColor[c];                            \                }                                                        \                diff |= ((pixHere[c] - prediction) & maxColor[c])        \                    << shiftBits[c];                                     \            }                                                            \            if (endianMismatch) {                                        \                diff = Swap##bpp(diff);                                  \            }                                                            \            *buf++ = diff;                                               \        }                                                                \    }                                                                    \}DEFINE_GRADIENT_FILTER_FUNCTION(16)DEFINE_GRADIENT_FILTER_FUNCTION(32)/* * Code to guess if given rectangle is suitable for smooth image * compression (by applying "gradient" filter or JPEG coder). */#define JPEG_MIN_RECT_SIZE  4096#define DETECT_SUBROW_WIDTH    7#define DETECT_MIN_WIDTH       8#define DETECT_MIN_HEIGHT      8static intDetectSmoothImage (fmt, w, h)    rfbPixelFormat *fmt;    int w, h;{    unsigned long avgError;    if ( rfbServerFormat.bitsPerPixel == 8 || fmt->bitsPerPixel == 8 ||         w < DETECT_MIN_WIDTH || h < DETECT_MIN_HEIGHT ) {        return 0;    }    if (qualityLevel != -1) {        if (w * h < JPEG_MIN_RECT_SIZE) {            return 0;        }    } else {        if ( rfbTightDisableGradient ||             w * h < tightConf[compressLevel].gradientMinRectSize ) {            return 0;        }    }    if (fmt->bitsPerPixel == 32) {        if (usePixelFormat24) {            avgError = DetectSmoothImage24(fmt, w, h);            if (qualityLevel != -1) {                return (avgError < tightConf[qualityLevel].jpegThreshold24);            }            return (avgError < tightConf[compressLevel].gradientThreshold24);        } else {            avgError = DetectSmoothImage32(fmt, w, h);        }    } else {        avgError = DetectSmoothImage16(fmt, w, h);    }    if (qualityLevel != -1) {        return (avgError < tightConf[qualityLevel].jpegThreshold);    }    return (avgError < tightConf[compressLevel].gradientThreshold);}static unsigned longDetectSmoothImage24 (fmt, w, h)    rfbPixelFormat *fmt;    int w, h;{    int off;    int x, y, d, dx, c;    int diffStat[256];    int pixelCount = 0;    int pix, left[3];    unsigned long avgError;    /* If client is big-endian, color samples begin from the second       byte (offset 1) of a 32-bit pixel value. */    off = (fmt->bigEndian != 0);    memset(diffStat, 0, 256*sizeof(int));    y = 0, x = 0;    while (y < h && x < w) {        for (d = 0; d < h - y && d < w - x - DETECT_SUBROW_WIDTH; d++) {            for (c = 0; c < 3; c++) {                left[c] = (int)tightBeforeBuf[((y+d)*w+x+d)*4+off+c] & 0xFF;            }            for (dx = 1; dx <= DETECT_SUBROW_WIDTH; dx++) {                for (c = 0; c < 3; c++) {                    pix = (int)tightBeforeBuf[((y+d)*w+x+d+dx)*4+off+c] & 0xFF;                    diffStat[abs(pix - left[c])]++;                    left[c] = pix;                }                pixelCount++;            }        }        if (w > h) {            x += h;            y = 0;        } else {            x = 0;            y += w;        }    }    if (diffStat[0] * 33 / pixelCount >= 95)        return 0;    avgError = 0;    for (c = 1; c < 8; c++) {        avgError += (unsigned long)diffStat[c] * (unsigned long)(c * c);        if (diffStat[c] == 0 || diffStat[c] > diffStat[c-1] * 2)            return 0;    }    for (; c < 256; c++) {        avgError += (unsigned long)diffStat[c] * (unsigned long)(c * c);    }    avgError /= (pixelCount * 3 - diffStat[0]);    return avgError;}#define DEFINE_DETECT_FUNCTION(bpp)                                          \                                                                             \static unsigned long                                                         \DetectSmoothImage##bpp (fmt, w, h)                                           \    rfbPixelFormat *fmt;                                                     \    int w, h;                                                                \{                                                                            \    Bool endianMismatch;                                                     \    CARD##bpp pix;                                                           \    int maxColor[3], shiftBits[3];                                           \    int x, y, d, dx, c;                                                      \    int diffStat[256];                                                       \    int pixelCount = 0;                                                      \    int sample, sum, left[3];                                                \    unsigned long avgError;                                                  \                                                                             \    endianMismatch = (!rfbServerFormat.bigEndian != !fmt->bigEndian);        \                                                                             \    maxColor[0] = fmt->redMax;                                               \    maxColor[1] = fmt->greenMax;                                             \    maxColor[2] = fmt->blueMax;                                              \    shiftBits[0] = fmt->redShift;                                            \    shiftBits[1] = fmt->greenShift;                                          \    shiftBits[2] = fmt->blueShift;                                           \                                                                             \    memset(diffStat, 0, 256*sizeof(int));                                    \                                                                             \    y = 0, x = 0;                                                            \    while (y < h && x < w) {                                                 \        for (d = 0; d < h - y && d < w - x - DETECT_SUBROW_WIDTH; d++) {     \            pix = ((CARD##bpp *)tightBeforeBuf)[(y+d)*w+x+d];                \            if (endianMismatch) {                                            \                pix = Swap##bpp(pix);                                        \            }                                                                \            for (c = 0; c < 3; c++) {                                        \                left[c] = (int)(pix >> shiftBits[c] & maxColor[c]);          \            }                                                                \            for (dx = 1; dx <= DETECT_SUBROW_WIDTH; dx++) {                  \                pix = ((CARD##bpp *)tightBeforeBuf)[(y+d)*w+x+d+dx];         \                if (endianMismatch) {                                        \                    pix = Swap##bpp(pix);                                    \                }                                                            \                sum = 0;                                                     \                for (c = 0; c < 3; c++) {                                    \                    sample = (int)(pix >> shiftBits[c] & maxColor[c]);       \                    sum += abs(sample - left[c]);                            \                    left[c] = sample;                                        \                }                                                            \                if (sum > 255)                                               \                    sum = 255;                                               \                diffStat[sum]++;                                             \                pixelCount++;                                                \            }                                                                \        }                                                                    \        if (w > h) {                                                         \            x += h;                                                          \            y = 0;                                                           \        } else {                                                             \            x = 0;                                                           \            y += w;                                                          \        }                                                                    \    }                                                                        \                                                                             \    if ((diffStat[0] + diffStat[1]) * 100 / pixelCount >= 90)                \        return 0;                                                            \                                                                             \    avgError = 0;                                                            \    for (c = 1; c < 8; c++) {                                                \        avgError += (unsigned long)diffStat[c] * (unsigned long)(c * c);     \        if (diffStat[c] == 0 || diffStat[c] > diffStat[c-1] * 2)             \            return 0;                                                        \    }                                                                        \    for (; c < 256; c++) {                                                   \        avgError += (unsigned long)diffStat[c] * (unsigned long)(c * c);     \    }                                                                        \    avgError /= (pixelCount - diffStat[0]);                                  \                                                                             \    return avgError;                                                         \}DEFINE_DETECT_FUNCTION(16)DEFINE_DETECT_FUNCTION(32)/* * JPEG compression stuff. */static struct jpeg_destination_mgr jpegDstManager;static Bool jpegError;static int jpegDstDataLen;static BoolSendJpegRect(cl, x, y, w, h, quality)    rfbClientPtr cl;    int x, y, w, h;    int quality;{    struct jpeg_compress_struct cinfo;    struct jpeg_error_mgr jerr;    CARD8 *srcBuf;    JSAMPROW rowPointer[1];    int dy;    if (rfbServerFormat.bitsPerPixel == 8)        return SendFullColorRect(cl, w, h);    srcBuf = (CARD8 *)xalloc(w * 3);    if (srcBuf == NULL) {        return SendFullColorRect(cl, w, h);    }    rowPointer[0] = srcBuf;    cinfo.err = jpeg_std_error(&jerr);    jpeg_create_compress(&cinfo);    cinfo.image_width = w;    cinfo.image_height = h;    cinfo.input_components = 3;    cinfo.in_color_space = JCS_RGB;    jpeg_set_defaults(&cinfo);    jpeg_set_quality(&cinfo, quality, TRUE);    JpegSetDstManager (&cinfo);    jpeg_start_compress(&cinfo, TRUE);    for (dy = 0; dy < h; dy++) {        PrepareRowForJpeg(srcBuf, x, y + dy, w);        jpeg_write_scanlines(&cinfo, rowPointer, 1);        if (jpegError)            break;    }    if (!jpegError)        jpeg_finish_compress(&cinfo);    jpeg_destroy_compress(&cinfo);    xfree((char *)srcBuf);    if (jpegError)        return SendFullColorRect(cl, w, h);    if (ublen + TIGHT_MIN_TO_COMPRESS + 1 > UPDATE_BUF_SIZE) {        if (!rfbSendUpdateBuf(cl))            return FALSE;    }    updateBuf[ublen++] = (char)(rfbTightJpeg << 4);    cl->rfbBytesSent[rfbEncodingTight]++;    return SendCompressedData(cl, jpegDstDataLen);}static voidPrepareRowForJpeg(dst, x, y, count)    CARD8 *dst;    int x, y, count;{    if (rfbServerFormat.bitsPerPixel == 32) {        if ( rfbServerFormat.redMax == 0xFF &&             rfbServerFormat.greenMax == 0xFF &&             rfbServerFormat.blueMax == 0xFF ) {            PrepareRowForJpeg24(dst, x, y, count);        } else {            PrepareRowForJpeg32(dst, x, y, count);        }    } else {        /* 16 bpp assumed. */        PrepareRowForJpeg16(dst, x, y, count);    }}static voidPrepareRowForJpeg24(dst, x, y, count)    CARD8 *dst;    int x, y, count;{    CARD32 *fbptr;    CARD32 pix;    fbptr = (CARD32 *)        &rfbScreen.pfbMemory[y * rfbScreen.paddedWidthInBytes + x * 4];    while (count--) {        pix = *fbptr++;        *dst++ = (CARD8)(pix >> rfbServerFormat.redShift);        *dst++ = (CARD8)(pix >> rfbServerFormat.greenShift);        *dst++ = (CARD8)(pix >> rfbServerFormat.blueShift);    }}#define DEFINE_JPEG_GET_ROW_FUNCTION(bpp)                                   \                                                                            \static void                                                                 \PrepareRowForJpeg##bpp(dst, x, y, count)                                    \    CARD8 *dst;                                                             \    int x, y, count;                                                        \{                                                                           \    CARD##bpp *fbptr;                                                       \    CARD##bpp pix;                                                          \    int inRed, inGreen, inBlue;                                             \                                                                            \    fbptr = (CARD##bpp *)                                                   \        &rfbScreen.pfbMemory[y * rfbScreen.paddedWidthInBytes +             \                             x * (bpp / 8)];                                \                                                                            \    while (count--) {                       

⌨️ 快捷键说明

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