📄 tight.c
字号:
} \ \ PaletteReset(); \ PaletteInsert (c0, (CARD32)n0, bpp); \ PaletteInsert (c1, (CARD32)n1, bpp); \ \ ni = 1; \ for (i++; i < count; i++) { \ if (data[i] == ci) { \ ni++; \ } else { \ if (!PaletteInsert (ci, (CARD32)ni, bpp)) \ return; \ ci = data[i]; \ ni = 1; \ } \ } \ PaletteInsert (ci, (CARD32)ni, bpp); \}DEFINE_FILL_PALETTE_FUNCTION(16)DEFINE_FILL_PALETTE_FUNCTION(32)/* * Functions to operate with palette structures. */#define HASH_FUNC16(rgb) ((int)((((rgb) >> 8) + (rgb)) & 0xFF))#define HASH_FUNC32(rgb) ((int)((((rgb) >> 16) + ((rgb) >> 8)) & 0xFF))static voidPaletteReset(void){ paletteNumColors = 0; memset(palette.hash, 0, 256 * sizeof(COLOR_LIST *));}static intPaletteInsert(rgb, numPixels, bpp) CARD32 rgb; int numPixels; int bpp;{ COLOR_LIST *pnode; COLOR_LIST *prev_pnode = NULL; int hash_key, idx, new_idx, count; hash_key = (bpp == 16) ? HASH_FUNC16(rgb) : HASH_FUNC32(rgb); pnode = palette.hash[hash_key]; while (pnode != NULL) { if (pnode->rgb == rgb) { /* Such palette entry already exists. */ new_idx = idx = pnode->idx; count = palette.entry[idx].numPixels + numPixels; if (new_idx && palette.entry[new_idx-1].numPixels < count) { do { palette.entry[new_idx] = palette.entry[new_idx-1]; palette.entry[new_idx].listNode->idx = new_idx; new_idx--; } while (new_idx && palette.entry[new_idx-1].numPixels < count); palette.entry[new_idx].listNode = pnode; pnode->idx = new_idx; } palette.entry[new_idx].numPixels = count; return paletteNumColors; } prev_pnode = pnode; pnode = pnode->next; } /* Check if palette is full. */ if (paletteNumColors == 256 || paletteNumColors == paletteMaxColors) { paletteNumColors = 0; return 0; } /* Move palette entries with lesser pixel counts. */ for ( idx = paletteNumColors; idx > 0 && palette.entry[idx-1].numPixels < numPixels; idx-- ) { palette.entry[idx] = palette.entry[idx-1]; palette.entry[idx].listNode->idx = idx; } /* Add new palette entry into the freed slot. */ pnode = &palette.list[paletteNumColors]; if (prev_pnode != NULL) { prev_pnode->next = pnode; } else { palette.hash[hash_key] = pnode; } pnode->next = NULL; pnode->idx = idx; pnode->rgb = rgb; palette.entry[idx].listNode = pnode; palette.entry[idx].numPixels = numPixels; return (++paletteNumColors);}/* * Converting 32-bit color samples into 24-bit colors. * Should be called only when redMax, greenMax and blueMax are 255. * Color components assumed to be byte-aligned. */static void Pack24(buf, fmt, count) char *buf; rfbPixelFormat *fmt; int count;{ CARD32 *buf32; CARD32 pix; int r_shift, g_shift, b_shift; buf32 = (CARD32 *)buf; if (!rfbServerFormat.bigEndian == !fmt->bigEndian) { r_shift = fmt->redShift; g_shift = fmt->greenShift; b_shift = fmt->blueShift; } else { r_shift = 24 - fmt->redShift; g_shift = 24 - fmt->greenShift; b_shift = 24 - fmt->blueShift; } while (count--) { pix = *buf32++; *buf++ = (char)(pix >> r_shift); *buf++ = (char)(pix >> g_shift); *buf++ = (char)(pix >> b_shift); }}/* * Converting truecolor samples into palette indices. */#define DEFINE_IDX_ENCODE_FUNCTION(bpp) \ \static void \EncodeIndexedRect##bpp(buf, count) \ CARD8 *buf; \ int count; \{ \ COLOR_LIST *pnode; \ CARD##bpp *src; \ CARD##bpp rgb; \ int rep = 0; \ \ src = (CARD##bpp *) buf; \ \ while (count--) { \ rgb = *src++; \ while (count && *src == rgb) { \ rep++, src++, count--; \ } \ pnode = palette.hash[HASH_FUNC##bpp(rgb)]; \ while (pnode != NULL) { \ if ((CARD##bpp)pnode->rgb == rgb) { \ *buf++ = (CARD8)pnode->idx; \ while (rep) { \ *buf++ = (CARD8)pnode->idx; \ rep--; \ } \ break; \ } \ pnode = pnode->next; \ } \ } \}DEFINE_IDX_ENCODE_FUNCTION(16)DEFINE_IDX_ENCODE_FUNCTION(32)#define DEFINE_MONO_ENCODE_FUNCTION(bpp) \ \static void \EncodeMonoRect##bpp(buf, w, h) \ CARD8 *buf; \ int w, h; \{ \ CARD##bpp *ptr; \ CARD##bpp bg; \ unsigned int value, mask; \ int aligned_width; \ int x, y, bg_bits; \ \ ptr = (CARD##bpp *) buf; \ bg = (CARD##bpp) monoBackground; \ aligned_width = w - w % 8; \ \ for (y = 0; y < h; y++) { \ for (x = 0; x < aligned_width; x += 8) { \ for (bg_bits = 0; bg_bits < 8; bg_bits++) { \ if (*ptr++ != bg) \ break; \ } \ if (bg_bits == 8) { \ *buf++ = 0; \ continue; \ } \ mask = 0x80 >> bg_bits; \ value = mask; \ for (bg_bits++; bg_bits < 8; bg_bits++) { \ mask >>= 1; \ if (*ptr++ != bg) { \ value |= mask; \ } \ } \ *buf++ = (CARD8)value; \ } \ \ mask = 0x80; \ value = 0; \ if (x >= w) \ continue; \ \ for (; x < w; x++) { \ if (*ptr++ != bg) { \ value |= mask; \ } \ mask >>= 1; \ } \ *buf++ = (CARD8)value; \ } \}DEFINE_MONO_ENCODE_FUNCTION(8)DEFINE_MONO_ENCODE_FUNCTION(16)DEFINE_MONO_ENCODE_FUNCTION(32)/* * ``Gradient'' filter for 24-bit color samples. * Should be called only when redMax, greenMax and blueMax are 255. * Color components assumed to be byte-aligned. */static voidFilterGradient24(buf, fmt, w, h) char *buf; rfbPixelFormat *fmt; int w, h;{ CARD32 *buf32; CARD32 pix32; int *prevRowPtr; int shiftBits[3]; int pixHere[3], pixUpper[3], pixLeft[3], pixUpperLeft[3]; int prediction; int x, y, c; buf32 = (CARD32 *)buf; memset (prevRowBuf, 0, w * 3 * sizeof(int)); if (!rfbServerFormat.bigEndian == !fmt->bigEndian) { shiftBits[0] = fmt->redShift; shiftBits[1] = fmt->greenShift; shiftBits[2] = fmt->blueShift; } else { shiftBits[0] = 24 - fmt->redShift; shiftBits[1] = 24 - fmt->greenShift; shiftBits[2] = 24 - fmt->blueShift; } for (y = 0; y < h; y++) { for (c = 0; c < 3; c++) { pixUpper[c] = 0; pixHere[c] = 0; } prevRowPtr = prevRowBuf; for (x = 0; x < w; x++) { pix32 = *buf32++; for (c = 0; c < 3; c++) { pixUpperLeft[c] = pixUpper[c]; pixLeft[c] = pixHere[c]; pixUpper[c] = *prevRowPtr; pixHere[c] = (int)(pix32 >> shiftBits[c] & 0xFF); *prevRowPtr++ = pixHere[c]; prediction = pixLeft[c] + pixUpper[c] - pixUpperLeft[c]; if (prediction < 0) { prediction = 0; } else if (prediction > 0xFF) { prediction = 0xFF; } *buf++ = (char)(pixHere[c] - prediction); } } }}/* * ``Gradient'' filter for other color depths. */#define DEFINE_GRADIENT_FILTER_FUNCTION(bpp) \ \static void \FilterGradient##bpp(buf, fmt, w, h) \ CARD##bpp *buf; \ rfbPixelFormat *fmt; \ int w, h; \{ \ CARD##bpp pix, diff; \ Bool endianMismatch; \ int *prevRowPtr; \ int maxColor[3], shiftBits[3]; \ int pixHere[3], pixUpper[3], pixLeft[3], pixUpperLeft[3]; \ int prediction; \ int x, y, c; \ \ memset (prevRowBuf, 0, w * 3 * sizeof(int)); \ \ 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; \ \ for (y = 0; y < h; y++) { \ for (c = 0; c < 3; c++) { \ pixUpper[c] = 0; \ pixHere[c] = 0; \ } \ prevRowPtr = prevRowBuf; \ for (x = 0; x < w; x++) { \ pix = *buf; \ if (endianMismatch) { \ pix = Swap##bpp(pix); \ } \ diff = 0; \ for (c = 0; c < 3; c++) { \ pixUpperLeft[c] = pixUpper[c]; \ pixLeft[c] = pixHere[c]; \ pixUpper[c] = *prevRowPtr; \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -