Revision d1af0e05 ui/vnc-enc-tight.c
b/ui/vnc-enc-tight.c | ||
---|---|---|
93 | 93 |
|
94 | 94 |
static bool tight_can_send_png_rect(VncState *vs, int w, int h) |
95 | 95 |
{ |
96 |
if (vs->tight_type != VNC_ENCODING_TIGHT_PNG) {
|
|
96 |
if (vs->tight.type != VNC_ENCODING_TIGHT_PNG) {
|
|
97 | 97 |
return false; |
98 | 98 |
} |
99 | 99 |
|
... | ... | |
121 | 121 |
int pixels = 0; |
122 | 122 |
int pix, left[3]; |
123 | 123 |
uint errors; |
124 |
unsigned char *buf = vs->tight.buffer; |
|
124 |
unsigned char *buf = vs->tight.tight.buffer;
|
|
125 | 125 |
|
126 | 126 |
/* |
127 | 127 |
* If client is big-endian, color samples begin from the second |
... | ... | |
188 | 188 |
int pixels = 0; \ |
189 | 189 |
int sample, sum, left[3]; \ |
190 | 190 |
uint errors; \ |
191 |
unsigned char *buf = vs->tight.buffer; \
|
|
191 |
unsigned char *buf = vs->tight.tight.buffer; \
|
|
192 | 192 |
\ |
193 | 193 |
endian = ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) != \ |
194 | 194 |
(vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG)); \ |
... | ... | |
268 | 268 |
tight_detect_smooth_image(VncState *vs, int w, int h) |
269 | 269 |
{ |
270 | 270 |
uint errors; |
271 |
int compression = vs->tight_compression;
|
|
272 |
int quality = vs->tight_quality;
|
|
271 |
int compression = vs->tight.compression;
|
|
272 |
int quality = vs->tight.quality;
|
|
273 | 273 |
|
274 | 274 |
if (!vs->vd->lossy) { |
275 | 275 |
return 0; |
... | ... | |
281 | 281 |
return 0; |
282 | 282 |
} |
283 | 283 |
|
284 |
if (vs->tight_quality != -1) {
|
|
284 |
if (vs->tight.quality != -1) {
|
|
285 | 285 |
if (w * h < VNC_TIGHT_JPEG_MIN_RECT_SIZE) { |
286 | 286 |
return 0; |
287 | 287 |
} |
... | ... | |
292 | 292 |
} |
293 | 293 |
|
294 | 294 |
if (vs->clientds.pf.bytes_per_pixel == 4) { |
295 |
if (vs->tight_pixel24) {
|
|
295 |
if (vs->tight.pixel24) {
|
|
296 | 296 |
errors = tight_detect_smooth_image24(vs, w, h); |
297 |
if (vs->tight_quality != -1) {
|
|
297 |
if (vs->tight.quality != -1) {
|
|
298 | 298 |
return (errors < tight_conf[quality].jpeg_threshold24); |
299 | 299 |
} |
300 | 300 |
return (errors < tight_conf[compression].gradient_threshold24); |
... | ... | |
324 | 324 |
uint##bpp##_t c0, c1, ci; \ |
325 | 325 |
int i, n0, n1; \ |
326 | 326 |
\ |
327 |
data = (uint##bpp##_t *)vs->tight.buffer; \
|
|
327 |
data = (uint##bpp##_t *)vs->tight.tight.buffer; \
|
|
328 | 328 |
\ |
329 | 329 |
c0 = data[0]; \ |
330 | 330 |
i = 1; \ |
... | ... | |
395 | 395 |
{ |
396 | 396 |
int max; |
397 | 397 |
|
398 |
max = count / tight_conf[vs->tight_compression].idx_max_colors_divisor;
|
|
398 |
max = count / tight_conf[vs->tight.compression].idx_max_colors_divisor;
|
|
399 | 399 |
if (max < 2 && |
400 |
count >= tight_conf[vs->tight_compression].mono_min_rect_size) {
|
|
400 |
count >= tight_conf[vs->tight.compression].mono_min_rect_size) {
|
|
401 | 401 |
max = 2; |
402 | 402 |
} |
403 | 403 |
if (max >= 256) { |
... | ... | |
529 | 529 |
int x, y, c; |
530 | 530 |
|
531 | 531 |
buf32 = (uint32_t *)buf; |
532 |
memset(vs->tight_gradient.buffer, 0, w * 3 * sizeof(int));
|
|
532 |
memset(vs->tight.gradient.buffer, 0, w * 3 * sizeof(int));
|
|
533 | 533 |
|
534 | 534 |
if ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) == |
535 | 535 |
(vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG)) { |
... | ... | |
547 | 547 |
upper[c] = 0; |
548 | 548 |
here[c] = 0; |
549 | 549 |
} |
550 |
prev = (int *)vs->tight_gradient.buffer;
|
|
550 |
prev = (int *)vs->tight.gradient.buffer;
|
|
551 | 551 |
for (x = 0; x < w; x++) { |
552 | 552 |
pix32 = *buf32++; |
553 | 553 |
for (c = 0; c < 3; c++) { |
... | ... | |
587 | 587 |
int prediction; \ |
588 | 588 |
int x, y, c; \ |
589 | 589 |
\ |
590 |
memset (vs->tight_gradient.buffer, 0, w * 3 * sizeof(int)); \
|
|
590 |
memset (vs->tight.gradient.buffer, 0, w * 3 * sizeof(int)); \
|
|
591 | 591 |
\ |
592 | 592 |
endian = ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) != \ |
593 | 593 |
(vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG)); \ |
... | ... | |
604 | 604 |
upper[c] = 0; \ |
605 | 605 |
here[c] = 0; \ |
606 | 606 |
} \ |
607 |
prev = (int *)vs->tight_gradient.buffer; \
|
|
607 |
prev = (int *)vs->tight.gradient.buffer; \
|
|
608 | 608 |
for (x = 0; x < w; x++) { \ |
609 | 609 |
pix = *buf; \ |
610 | 610 |
if (endian) { \ |
... | ... | |
774 | 774 |
static int tight_init_stream(VncState *vs, int stream_id, |
775 | 775 |
int level, int strategy) |
776 | 776 |
{ |
777 |
z_streamp zstream = &vs->tight_stream[stream_id];
|
|
777 |
z_streamp zstream = &vs->tight.stream[stream_id];
|
|
778 | 778 |
|
779 | 779 |
if (zstream->opaque == NULL) { |
780 | 780 |
int err; |
... | ... | |
792 | 792 |
return -1; |
793 | 793 |
} |
794 | 794 |
|
795 |
vs->tight_levels[stream_id] = level;
|
|
795 |
vs->tight.levels[stream_id] = level;
|
|
796 | 796 |
zstream->opaque = vs; |
797 | 797 |
} |
798 | 798 |
|
799 |
if (vs->tight_levels[stream_id] != level) {
|
|
799 |
if (vs->tight.levels[stream_id] != level) {
|
|
800 | 800 |
if (deflateParams(zstream, level, strategy) != Z_OK) { |
801 | 801 |
return -1; |
802 | 802 |
} |
803 |
vs->tight_levels[stream_id] = level;
|
|
803 |
vs->tight.levels[stream_id] = level;
|
|
804 | 804 |
} |
805 | 805 |
return 0; |
806 | 806 |
} |
... | ... | |
828 | 828 |
static int tight_compress_data(VncState *vs, int stream_id, size_t bytes, |
829 | 829 |
int level, int strategy) |
830 | 830 |
{ |
831 |
z_streamp zstream = &vs->tight_stream[stream_id];
|
|
831 |
z_streamp zstream = &vs->tight.stream[stream_id];
|
|
832 | 832 |
int previous_out; |
833 | 833 |
|
834 | 834 |
if (bytes < VNC_TIGHT_MIN_TO_COMPRESS) { |
835 |
vnc_write(vs, vs->tight.buffer, vs->tight.offset);
|
|
835 |
vnc_write(vs, vs->tight.tight.buffer, vs->tight.tight.offset);
|
|
836 | 836 |
return bytes; |
837 | 837 |
} |
838 | 838 |
|
... | ... | |
841 | 841 |
} |
842 | 842 |
|
843 | 843 |
/* reserve memory in output buffer */ |
844 |
buffer_reserve(&vs->tight_zlib, bytes + 64);
|
|
844 |
buffer_reserve(&vs->tight.zlib, bytes + 64);
|
|
845 | 845 |
|
846 | 846 |
/* set pointers */ |
847 |
zstream->next_in = vs->tight.buffer; |
|
848 |
zstream->avail_in = vs->tight.offset; |
|
849 |
zstream->next_out = vs->tight_zlib.buffer + vs->tight_zlib.offset;
|
|
850 |
zstream->avail_out = vs->tight_zlib.capacity - vs->tight_zlib.offset;
|
|
847 |
zstream->next_in = vs->tight.tight.buffer;
|
|
848 |
zstream->avail_in = vs->tight.tight.offset;
|
|
849 |
zstream->next_out = vs->tight.zlib.buffer + vs->tight.zlib.offset;
|
|
850 |
zstream->avail_out = vs->tight.zlib.capacity - vs->tight.zlib.offset;
|
|
851 | 851 |
zstream->data_type = Z_BINARY; |
852 | 852 |
previous_out = zstream->total_out; |
853 | 853 |
|
... | ... | |
857 | 857 |
return -1; |
858 | 858 |
} |
859 | 859 |
|
860 |
vs->tight_zlib.offset = vs->tight_zlib.capacity - zstream->avail_out;
|
|
860 |
vs->tight.zlib.offset = vs->tight.zlib.capacity - zstream->avail_out;
|
|
861 | 861 |
bytes = zstream->total_out - previous_out; |
862 | 862 |
|
863 | 863 |
tight_send_compact_size(vs, bytes); |
864 |
vnc_write(vs, vs->tight_zlib.buffer, bytes);
|
|
864 |
vnc_write(vs, vs->tight.zlib.buffer, bytes);
|
|
865 | 865 |
|
866 |
buffer_reset(&vs->tight_zlib);
|
|
866 |
buffer_reset(&vs->tight.zlib);
|
|
867 | 867 |
|
868 | 868 |
return bytes; |
869 | 869 |
} |
... | ... | |
915 | 915 |
|
916 | 916 |
vnc_write_u8(vs, stream << 4); /* no flushing, no filter */ |
917 | 917 |
|
918 |
if (vs->tight_pixel24) {
|
|
919 |
tight_pack24(vs, vs->tight.buffer, w * h, &vs->tight.offset);
|
|
918 |
if (vs->tight.pixel24) {
|
|
919 |
tight_pack24(vs, vs->tight.tight.buffer, w * h, &vs->tight.tight.offset);
|
|
920 | 920 |
bytes = 3; |
921 | 921 |
} else { |
922 | 922 |
bytes = vs->clientds.pf.bytes_per_pixel; |
923 | 923 |
} |
924 | 924 |
|
925 | 925 |
bytes = tight_compress_data(vs, stream, w * h * bytes, |
926 |
tight_conf[vs->tight_compression].raw_zlib_level,
|
|
926 |
tight_conf[vs->tight.compression].raw_zlib_level,
|
|
927 | 927 |
Z_DEFAULT_STRATEGY); |
928 | 928 |
|
929 | 929 |
return (bytes >= 0); |
... | ... | |
935 | 935 |
|
936 | 936 |
vnc_write_u8(vs, VNC_TIGHT_FILL << 4); /* no flushing, no filter */ |
937 | 937 |
|
938 |
if (vs->tight_pixel24) {
|
|
939 |
tight_pack24(vs, vs->tight.buffer, 1, &vs->tight.offset);
|
|
938 |
if (vs->tight.pixel24) {
|
|
939 |
tight_pack24(vs, vs->tight.tight.buffer, 1, &vs->tight.tight.offset);
|
|
940 | 940 |
bytes = 3; |
941 | 941 |
} else { |
942 | 942 |
bytes = vs->clientds.pf.bytes_per_pixel; |
943 | 943 |
} |
944 | 944 |
|
945 |
vnc_write(vs, vs->tight.buffer, bytes); |
|
945 |
vnc_write(vs, vs->tight.tight.buffer, bytes);
|
|
946 | 946 |
return 1; |
947 | 947 |
} |
948 | 948 |
|
... | ... | |
951 | 951 |
{ |
952 | 952 |
size_t bytes; |
953 | 953 |
int stream = 1; |
954 |
int level = tight_conf[vs->tight_compression].mono_zlib_level;
|
|
954 |
int level = tight_conf[vs->tight.compression].mono_zlib_level;
|
|
955 | 955 |
|
956 | 956 |
#ifdef CONFIG_VNC_PNG |
957 | 957 |
if (tight_can_send_png_rect(vs, w, h)) { |
... | ... | |
979 | 979 |
uint32_t buf[2] = {bg, fg}; |
980 | 980 |
size_t ret = sizeof (buf); |
981 | 981 |
|
982 |
if (vs->tight_pixel24) {
|
|
982 |
if (vs->tight.pixel24) {
|
|
983 | 983 |
tight_pack24(vs, (unsigned char*)buf, 2, &ret); |
984 | 984 |
} |
985 | 985 |
vnc_write(vs, buf, ret); |
986 | 986 |
|
987 |
tight_encode_mono_rect32(vs->tight.buffer, w, h, bg, fg); |
|
987 |
tight_encode_mono_rect32(vs->tight.tight.buffer, w, h, bg, fg);
|
|
988 | 988 |
break; |
989 | 989 |
} |
990 | 990 |
case 2: |
991 | 991 |
vnc_write(vs, &bg, 2); |
992 | 992 |
vnc_write(vs, &fg, 2); |
993 |
tight_encode_mono_rect16(vs->tight.buffer, w, h, bg, fg); |
|
993 |
tight_encode_mono_rect16(vs->tight.tight.buffer, w, h, bg, fg);
|
|
994 | 994 |
break; |
995 | 995 |
default: |
996 | 996 |
vnc_write_u8(vs, bg); |
997 | 997 |
vnc_write_u8(vs, fg); |
998 |
tight_encode_mono_rect8(vs->tight.buffer, w, h, bg, fg); |
|
998 |
tight_encode_mono_rect8(vs->tight.tight.buffer, w, h, bg, fg);
|
|
999 | 999 |
break; |
1000 | 1000 |
} |
1001 |
vs->tight.offset = bytes; |
|
1001 |
vs->tight.tight.offset = bytes;
|
|
1002 | 1002 |
|
1003 | 1003 |
bytes = tight_compress_data(vs, stream, bytes, level, Z_DEFAULT_STRATEGY); |
1004 | 1004 |
return (bytes >= 0); |
... | ... | |
1028 | 1028 |
static bool send_gradient_rect(VncState *vs, int x, int y, int w, int h) |
1029 | 1029 |
{ |
1030 | 1030 |
int stream = 3; |
1031 |
int level = tight_conf[vs->tight_compression].gradient_zlib_level;
|
|
1031 |
int level = tight_conf[vs->tight.compression].gradient_zlib_level;
|
|
1032 | 1032 |
size_t bytes; |
1033 | 1033 |
|
1034 | 1034 |
if (vs->clientds.pf.bytes_per_pixel == 1) |
... | ... | |
1037 | 1037 |
vnc_write_u8(vs, (stream | VNC_TIGHT_EXPLICIT_FILTER) << 4); |
1038 | 1038 |
vnc_write_u8(vs, VNC_TIGHT_FILTER_GRADIENT); |
1039 | 1039 |
|
1040 |
buffer_reserve(&vs->tight_gradient, w * 3 * sizeof (int));
|
|
1040 |
buffer_reserve(&vs->tight.gradient, w * 3 * sizeof (int));
|
|
1041 | 1041 |
|
1042 |
if (vs->tight_pixel24) {
|
|
1043 |
tight_filter_gradient24(vs, vs->tight.buffer, w, h); |
|
1042 |
if (vs->tight.pixel24) {
|
|
1043 |
tight_filter_gradient24(vs, vs->tight.tight.buffer, w, h);
|
|
1044 | 1044 |
bytes = 3; |
1045 | 1045 |
} else if (vs->clientds.pf.bytes_per_pixel == 4) { |
1046 |
tight_filter_gradient32(vs, (uint32_t *)vs->tight.buffer, w, h); |
|
1046 |
tight_filter_gradient32(vs, (uint32_t *)vs->tight.tight.buffer, w, h);
|
|
1047 | 1047 |
bytes = 4; |
1048 | 1048 |
} else { |
1049 |
tight_filter_gradient16(vs, (uint16_t *)vs->tight.buffer, w, h); |
|
1049 |
tight_filter_gradient16(vs, (uint16_t *)vs->tight.tight.buffer, w, h);
|
|
1050 | 1050 |
bytes = 2; |
1051 | 1051 |
} |
1052 | 1052 |
|
1053 |
buffer_reset(&vs->tight_gradient);
|
|
1053 |
buffer_reset(&vs->tight.gradient);
|
|
1054 | 1054 |
|
1055 | 1055 |
bytes = w * h * bytes; |
1056 |
vs->tight.offset = bytes; |
|
1056 |
vs->tight.tight.offset = bytes;
|
|
1057 | 1057 |
|
1058 | 1058 |
bytes = tight_compress_data(vs, stream, bytes, |
1059 | 1059 |
level, Z_FILTERED); |
... | ... | |
1064 | 1064 |
int w, int h, VncPalette *palette) |
1065 | 1065 |
{ |
1066 | 1066 |
int stream = 2; |
1067 |
int level = tight_conf[vs->tight_compression].idx_zlib_level;
|
|
1067 |
int level = tight_conf[vs->tight.compression].idx_zlib_level;
|
|
1068 | 1068 |
int colors; |
1069 | 1069 |
size_t bytes; |
1070 | 1070 |
|
... | ... | |
1091 | 1091 |
palette_iter(palette, write_palette, &priv); |
1092 | 1092 |
vnc_write(vs, header, sizeof(header)); |
1093 | 1093 |
|
1094 |
if (vs->tight_pixel24) {
|
|
1094 |
if (vs->tight.pixel24) {
|
|
1095 | 1095 |
tight_pack24(vs, vs->output.buffer + old_offset, colors, &offset); |
1096 | 1096 |
vs->output.offset = old_offset + offset; |
1097 | 1097 |
} |
1098 | 1098 |
|
1099 |
tight_encode_indexed_rect32(vs->tight.buffer, w * h, palette); |
|
1099 |
tight_encode_indexed_rect32(vs->tight.tight.buffer, w * h, palette);
|
|
1100 | 1100 |
break; |
1101 | 1101 |
} |
1102 | 1102 |
case 2: |
... | ... | |
1106 | 1106 |
|
1107 | 1107 |
palette_iter(palette, write_palette, &priv); |
1108 | 1108 |
vnc_write(vs, header, sizeof(header)); |
1109 |
tight_encode_indexed_rect16(vs->tight.buffer, w * h, palette); |
|
1109 |
tight_encode_indexed_rect16(vs->tight.tight.buffer, w * h, palette);
|
|
1110 | 1110 |
break; |
1111 | 1111 |
} |
1112 | 1112 |
default: |
... | ... | |
1114 | 1114 |
break; |
1115 | 1115 |
} |
1116 | 1116 |
bytes = w * h; |
1117 |
vs->tight.offset = bytes; |
|
1117 |
vs->tight.tight.offset = bytes;
|
|
1118 | 1118 |
|
1119 | 1119 |
bytes = tight_compress_data(vs, stream, bytes, |
1120 | 1120 |
level, Z_DEFAULT_STRATEGY); |
... | ... | |
1180 | 1180 |
static void rgb_prepare_row(VncState *vs, uint8_t *dst, int x, int y, |
1181 | 1181 |
int count) |
1182 | 1182 |
{ |
1183 |
if (vs->tight_pixel24)
|
|
1183 |
if (vs->tight.pixel24)
|
|
1184 | 1184 |
rgb_prepare_row24(vs, dst, x, y, count); |
1185 | 1185 |
else if (ds_get_bytes_per_pixel(vs->ds) == 4) |
1186 | 1186 |
rgb_prepare_row32(vs, dst, x, y, count); |
... | ... | |
1201 | 1201 |
static void jpeg_init_destination(j_compress_ptr cinfo) |
1202 | 1202 |
{ |
1203 | 1203 |
VncState *vs = cinfo->client_data; |
1204 |
Buffer *buffer = &vs->tight_jpeg;
|
|
1204 |
Buffer *buffer = &vs->tight.jpeg;
|
|
1205 | 1205 |
|
1206 | 1206 |
cinfo->dest->next_output_byte = (JOCTET *)buffer->buffer + buffer->offset; |
1207 | 1207 |
cinfo->dest->free_in_buffer = (size_t)(buffer->capacity - buffer->offset); |
... | ... | |
1211 | 1211 |
static boolean jpeg_empty_output_buffer(j_compress_ptr cinfo) |
1212 | 1212 |
{ |
1213 | 1213 |
VncState *vs = cinfo->client_data; |
1214 |
Buffer *buffer = &vs->tight_jpeg;
|
|
1214 |
Buffer *buffer = &vs->tight.jpeg;
|
|
1215 | 1215 |
|
1216 | 1216 |
buffer->offset = buffer->capacity; |
1217 | 1217 |
buffer_reserve(buffer, 2048); |
... | ... | |
1223 | 1223 |
static void jpeg_term_destination(j_compress_ptr cinfo) |
1224 | 1224 |
{ |
1225 | 1225 |
VncState *vs = cinfo->client_data; |
1226 |
Buffer *buffer = &vs->tight_jpeg;
|
|
1226 |
Buffer *buffer = &vs->tight.jpeg;
|
|
1227 | 1227 |
|
1228 | 1228 |
buffer->offset = buffer->capacity - cinfo->dest->free_in_buffer; |
1229 | 1229 |
} |
... | ... | |
1240 | 1240 |
if (ds_get_bytes_per_pixel(vs->ds) == 1) |
1241 | 1241 |
return send_full_color_rect(vs, x, y, w, h); |
1242 | 1242 |
|
1243 |
buffer_reserve(&vs->tight_jpeg, 2048);
|
|
1243 |
buffer_reserve(&vs->tight.jpeg, 2048);
|
|
1244 | 1244 |
|
1245 | 1245 |
cinfo.err = jpeg_std_error(&jerr); |
1246 | 1246 |
jpeg_create_compress(&cinfo); |
... | ... | |
1274 | 1274 |
|
1275 | 1275 |
vnc_write_u8(vs, VNC_TIGHT_JPEG << 4); |
1276 | 1276 |
|
1277 |
tight_send_compact_size(vs, vs->tight_jpeg.offset);
|
|
1278 |
vnc_write(vs, vs->tight_jpeg.buffer, vs->tight_jpeg.offset);
|
|
1279 |
buffer_reset(&vs->tight_jpeg);
|
|
1277 |
tight_send_compact_size(vs, vs->tight.jpeg.offset);
|
|
1278 |
vnc_write(vs, vs->tight.jpeg.buffer, vs->tight.jpeg.offset);
|
|
1279 |
buffer_reset(&vs->tight.jpeg);
|
|
1280 | 1280 |
|
1281 | 1281 |
return 1; |
1282 | 1282 |
} |
... | ... | |
1292 | 1292 |
VncState *vs = priv->vs; |
1293 | 1293 |
png_colorp color = &priv->png_palette[idx]; |
1294 | 1294 |
|
1295 |
if (vs->tight_pixel24)
|
|
1295 |
if (vs->tight.pixel24)
|
|
1296 | 1296 |
{ |
1297 | 1297 |
color->red = (pix >> vs->clientds.pf.rshift) & vs->clientds.pf.rmax; |
1298 | 1298 |
color->green = (pix >> vs->clientds.pf.gshift) & vs->clientds.pf.gmax; |
... | ... | |
1319 | 1319 |
{ |
1320 | 1320 |
VncState *vs = png_get_io_ptr(png_ptr); |
1321 | 1321 |
|
1322 |
buffer_reserve(&vs->tight_png, vs->tight_png.offset + length);
|
|
1323 |
memcpy(vs->tight_png.buffer + vs->tight_png.offset, data, length);
|
|
1322 |
buffer_reserve(&vs->tight.png, vs->tight.png.offset + length);
|
|
1323 |
memcpy(vs->tight.png.buffer + vs->tight.png.offset, data, length);
|
|
1324 | 1324 |
|
1325 |
vs->tight_png.offset += length;
|
|
1325 |
vs->tight.png.offset += length;
|
|
1326 | 1326 |
} |
1327 | 1327 |
|
1328 | 1328 |
static void png_flush_data(png_structp png_ptr) |
... | ... | |
1347 | 1347 |
png_infop info_ptr; |
1348 | 1348 |
png_colorp png_palette = NULL; |
1349 | 1349 |
size_t offset; |
1350 |
int level = tight_png_conf[vs->tight_compression].png_zlib_level;
|
|
1351 |
int filters = tight_png_conf[vs->tight_compression].png_filters;
|
|
1350 |
int level = tight_png_conf[vs->tight.compression].png_zlib_level;
|
|
1351 |
int filters = tight_png_conf[vs->tight.compression].png_filters;
|
|
1352 | 1352 |
uint8_t *buf; |
1353 | 1353 |
int dy; |
1354 | 1354 |
|
... | ... | |
1391 | 1391 |
|
1392 | 1392 |
png_set_PLTE(png_ptr, info_ptr, png_palette, palette_size(palette)); |
1393 | 1393 |
|
1394 |
offset = vs->tight.offset; |
|
1394 |
offset = vs->tight.tight.offset;
|
|
1395 | 1395 |
if (vs->clientds.pf.bytes_per_pixel == 4) { |
1396 |
tight_encode_indexed_rect32(vs->tight.buffer, w * h, palette); |
|
1396 |
tight_encode_indexed_rect32(vs->tight.tight.buffer, w * h, palette);
|
|
1397 | 1397 |
} else { |
1398 |
tight_encode_indexed_rect16(vs->tight.buffer, w * h, palette); |
|
1398 |
tight_encode_indexed_rect16(vs->tight.tight.buffer, w * h, palette);
|
|
1399 | 1399 |
} |
1400 | 1400 |
} |
1401 | 1401 |
|
1402 | 1402 |
png_write_info(png_ptr, info_ptr); |
1403 | 1403 |
|
1404 |
buffer_reserve(&vs->tight_png, 2048);
|
|
1404 |
buffer_reserve(&vs->tight.png, 2048);
|
|
1405 | 1405 |
buf = qemu_malloc(w * 3); |
1406 | 1406 |
for (dy = 0; dy < h; dy++) |
1407 | 1407 |
{ |
1408 | 1408 |
if (color_type == PNG_COLOR_TYPE_PALETTE) { |
1409 |
memcpy(buf, vs->tight.buffer + (dy * w), w); |
|
1409 |
memcpy(buf, vs->tight.tight.buffer + (dy * w), w);
|
|
1410 | 1410 |
} else { |
1411 | 1411 |
rgb_prepare_row(vs, buf, x, y + dy, w); |
1412 | 1412 |
} |
... | ... | |
1424 | 1424 |
|
1425 | 1425 |
vnc_write_u8(vs, VNC_TIGHT_PNG << 4); |
1426 | 1426 |
|
1427 |
tight_send_compact_size(vs, vs->tight_png.offset);
|
|
1428 |
vnc_write(vs, vs->tight_png.buffer, vs->tight_png.offset);
|
|
1429 |
buffer_reset(&vs->tight_png);
|
|
1427 |
tight_send_compact_size(vs, vs->tight.png.offset);
|
|
1428 |
vnc_write(vs, vs->tight.png.buffer, vs->tight.png.offset);
|
|
1429 |
buffer_reset(&vs->tight.png);
|
|
1430 | 1430 |
return 1; |
1431 | 1431 |
} |
1432 | 1432 |
#endif /* CONFIG_VNC_PNG */ |
1433 | 1433 |
|
1434 | 1434 |
static void vnc_tight_start(VncState *vs) |
1435 | 1435 |
{ |
1436 |
buffer_reset(&vs->tight); |
|
1436 |
buffer_reset(&vs->tight.tight);
|
|
1437 | 1437 |
|
1438 | 1438 |
// make the output buffer be the zlib buffer, so we can compress it later |
1439 |
vs->tight_tmp = vs->output;
|
|
1440 |
vs->output = vs->tight; |
|
1439 |
vs->tight.tmp = vs->output;
|
|
1440 |
vs->output = vs->tight.tight;
|
|
1441 | 1441 |
} |
1442 | 1442 |
|
1443 | 1443 |
static void vnc_tight_stop(VncState *vs) |
1444 | 1444 |
{ |
1445 | 1445 |
// switch back to normal output/zlib buffers |
1446 |
vs->tight = vs->output; |
|
1447 |
vs->output = vs->tight_tmp;
|
|
1446 |
vs->tight.tight = vs->output;
|
|
1447 |
vs->output = vs->tight.tmp;
|
|
1448 | 1448 |
} |
1449 | 1449 |
|
1450 | 1450 |
static int send_sub_rect(VncState *vs, int x, int y, int w, int h) |
... | ... | |
1454 | 1454 |
int colors; |
1455 | 1455 |
int ret = 0; |
1456 | 1456 |
|
1457 |
vnc_framebuffer_update(vs, x, y, w, h, vs->tight_type);
|
|
1457 |
vnc_framebuffer_update(vs, x, y, w, h, vs->tight.type);
|
|
1458 | 1458 |
|
1459 | 1459 |
vnc_tight_start(vs); |
1460 | 1460 |
vnc_raw_send_framebuffer_update(vs, x, y, w, h); |
... | ... | |
1464 | 1464 |
|
1465 | 1465 |
if (colors == 0) { |
1466 | 1466 |
if (tight_detect_smooth_image(vs, w, h)) { |
1467 |
if (vs->tight_quality == -1) {
|
|
1467 |
if (vs->tight.quality == -1) {
|
|
1468 | 1468 |
ret = send_gradient_rect(vs, x, y, w, h); |
1469 | 1469 |
} else { |
1470 | 1470 |
#ifdef CONFIG_VNC_JPEG |
1471 |
int quality = tight_conf[vs->tight_quality].jpeg_quality;
|
|
1471 |
int quality = tight_conf[vs->tight.quality].jpeg_quality;
|
|
1472 | 1472 |
|
1473 | 1473 |
ret = send_jpeg_rect(vs, x, y, w, h, quality); |
1474 | 1474 |
#else |
... | ... | |
1484 | 1484 |
ret = send_mono_rect(vs, x, y, w, h, bg, fg); |
1485 | 1485 |
} else if (colors <= 256) { |
1486 | 1486 |
#ifdef CONFIG_VNC_JPEG |
1487 |
if (colors > 96 && vs->tight_quality != -1 && vs->tight_quality <= 3 &&
|
|
1487 |
if (colors > 96 && vs->tight.quality != -1 && vs->tight.quality <= 3 &&
|
|
1488 | 1488 |
tight_detect_smooth_image(vs, w, h)) { |
1489 |
int quality = tight_conf[vs->tight_quality].jpeg_quality;
|
|
1489 |
int quality = tight_conf[vs->tight.quality].jpeg_quality;
|
|
1490 | 1490 |
|
1491 | 1491 |
ret = send_jpeg_rect(vs, x, y, w, h, quality); |
1492 | 1492 |
} else { |
... | ... | |
1502 | 1502 |
|
1503 | 1503 |
static int send_sub_rect_solid(VncState *vs, int x, int y, int w, int h) |
1504 | 1504 |
{ |
1505 |
vnc_framebuffer_update(vs, x, y, w, h, vs->tight_type);
|
|
1505 |
vnc_framebuffer_update(vs, x, y, w, h, vs->tight.type);
|
|
1506 | 1506 |
|
1507 | 1507 |
vnc_tight_start(vs); |
1508 | 1508 |
vnc_raw_send_framebuffer_update(vs, x, y, w, h); |
... | ... | |
1519 | 1519 |
int rw, rh; |
1520 | 1520 |
int n = 0; |
1521 | 1521 |
|
1522 |
max_size = tight_conf[vs->tight_compression].max_rect_size;
|
|
1523 |
max_width = tight_conf[vs->tight_compression].max_rect_width;
|
|
1522 |
max_size = tight_conf[vs->tight.compression].max_rect_size;
|
|
1523 |
max_width = tight_conf[vs->tight.compression].max_rect_width;
|
|
1524 | 1524 |
|
1525 | 1525 |
if (w > max_width || w * h > max_size) { |
1526 | 1526 |
max_sub_width = (w > max_width) ? max_width : w; |
... | ... | |
1629 | 1629 |
|
1630 | 1630 |
if (vs->clientds.pf.bytes_per_pixel == 4 && vs->clientds.pf.rmax == 0xFF && |
1631 | 1631 |
vs->clientds.pf.bmax == 0xFF && vs->clientds.pf.gmax == 0xFF) { |
1632 |
vs->tight_pixel24 = true;
|
|
1632 |
vs->tight.pixel24 = true;
|
|
1633 | 1633 |
} else { |
1634 |
vs->tight_pixel24 = false;
|
|
1634 |
vs->tight.pixel24 = false;
|
|
1635 | 1635 |
} |
1636 | 1636 |
|
1637 | 1637 |
if (w * h < VNC_TIGHT_MIN_SPLIT_RECT_SIZE) |
... | ... | |
1639 | 1639 |
|
1640 | 1640 |
/* Calculate maximum number of rows in one non-solid rectangle. */ |
1641 | 1641 |
|
1642 |
max_rows = tight_conf[vs->tight_compression].max_rect_size;
|
|
1643 |
max_rows /= MIN(tight_conf[vs->tight_compression].max_rect_width, w);
|
|
1642 |
max_rows = tight_conf[vs->tight.compression].max_rect_size;
|
|
1643 |
max_rows /= MIN(tight_conf[vs->tight.compression].max_rect_width, w);
|
|
1644 | 1644 |
|
1645 | 1645 |
return find_large_solid_color_rect(vs, x, y, w, h, max_rows); |
1646 | 1646 |
} |
... | ... | |
1648 | 1648 |
int vnc_tight_send_framebuffer_update(VncState *vs, int x, int y, |
1649 | 1649 |
int w, int h) |
1650 | 1650 |
{ |
1651 |
vs->tight_type = VNC_ENCODING_TIGHT;
|
|
1651 |
vs->tight.type = VNC_ENCODING_TIGHT;
|
|
1652 | 1652 |
return tight_send_framebuffer_update(vs, x, y, w, h); |
1653 | 1653 |
} |
1654 | 1654 |
|
1655 | 1655 |
int vnc_tight_png_send_framebuffer_update(VncState *vs, int x, int y, |
1656 | 1656 |
int w, int h) |
1657 | 1657 |
{ |
1658 |
vs->tight_type = VNC_ENCODING_TIGHT_PNG;
|
|
1658 |
vs->tight.type = VNC_ENCODING_TIGHT_PNG;
|
|
1659 | 1659 |
return tight_send_framebuffer_update(vs, x, y, w, h); |
1660 | 1660 |
} |
1661 | 1661 |
|
1662 | 1662 |
void vnc_tight_clear(VncState *vs) |
1663 | 1663 |
{ |
1664 | 1664 |
int i; |
1665 |
for (i=0; i<ARRAY_SIZE(vs->tight_stream); i++) {
|
|
1666 |
if (vs->tight_stream[i].opaque) {
|
|
1667 |
deflateEnd(&vs->tight_stream[i]);
|
|
1665 |
for (i=0; i<ARRAY_SIZE(vs->tight.stream); i++) {
|
|
1666 |
if (vs->tight.stream[i].opaque) {
|
|
1667 |
deflateEnd(&vs->tight.stream[i]);
|
|
1668 | 1668 |
} |
1669 | 1669 |
} |
1670 | 1670 |
|
1671 |
buffer_free(&vs->tight); |
|
1672 |
buffer_free(&vs->tight_zlib);
|
|
1673 |
buffer_free(&vs->tight_gradient);
|
|
1671 |
buffer_free(&vs->tight.tight);
|
|
1672 |
buffer_free(&vs->tight.zlib);
|
|
1673 |
buffer_free(&vs->tight.gradient);
|
|
1674 | 1674 |
#ifdef CONFIG_VNC_JPEG |
1675 |
buffer_free(&vs->tight_jpeg);
|
|
1675 |
buffer_free(&vs->tight.jpeg);
|
|
1676 | 1676 |
#endif |
1677 | 1677 |
} |
Also available in: Unified diff