File: | ui/vnc-enc-zrle.c |
Location: | line 165, column 17 |
Description: | Value stored to 'estimated_bytes' is never read |
1 | /* |
2 | * QEMU VNC display driver: Zlib Run-length Encoding (ZRLE) |
3 | * |
4 | * From libvncserver/libvncserver/zrle.c |
5 | * Copyright (C) 2002 RealVNC Ltd. All Rights Reserved. |
6 | * Copyright (C) 2003 Sun Microsystems, Inc. |
7 | * |
8 | * Copyright (C) 2010 Corentin Chary <corentin.chary@gmail.com> |
9 | * |
10 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
11 | * of this software and associated documentation files (the "Software"), to deal |
12 | * in the Software without restriction, including without limitation the rights |
13 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
14 | * copies of the Software, and to permit persons to whom the Software is |
15 | * furnished to do so, subject to the following conditions: |
16 | * |
17 | * The above copyright notice and this permission notice shall be included in |
18 | * all copies or substantial portions of the Software. |
19 | * |
20 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
21 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
22 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
23 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
24 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
25 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
26 | * THE SOFTWARE. |
27 | */ |
28 | |
29 | #include "vnc.h" |
30 | #include "vnc-enc-zrle.h" |
31 | |
32 | static const int bits_per_packed_pixel[] = { |
33 | 0, 1, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 |
34 | }; |
35 | |
36 | |
37 | static void vnc_zrle_start(VncState *vs) |
38 | { |
39 | buffer_reset(&vs->zrle.zrle); |
40 | |
41 | /* make the output buffer be the zlib buffer, so we can compress it later */ |
42 | vs->zrle.tmp = vs->output; |
43 | vs->output = vs->zrle.zrle; |
44 | } |
45 | |
46 | static void vnc_zrle_stop(VncState *vs) |
47 | { |
48 | /* switch back to normal output/zlib buffers */ |
49 | vs->zrle.zrle = vs->output; |
50 | vs->output = vs->zrle.tmp; |
51 | } |
52 | |
53 | static void *zrle_convert_fb(VncState *vs, int x, int y, int w, int h, |
54 | int bpp) |
55 | { |
56 | Buffer tmp; |
57 | |
58 | buffer_reset(&vs->zrle.fb); |
59 | buffer_reserve(&vs->zrle.fb, w * h * bpp + bpp); |
60 | |
61 | tmp = vs->output; |
62 | vs->output = vs->zrle.fb; |
63 | |
64 | vnc_raw_send_framebuffer_update(vs, x, y, w, h); |
65 | |
66 | vs->zrle.fb = vs->output; |
67 | vs->output = tmp; |
68 | return vs->zrle.fb.buffer; |
69 | } |
70 | |
71 | static int zrle_compress_data(VncState *vs, int level) |
72 | { |
73 | z_streamp zstream = &vs->zrle.stream; |
74 | |
75 | buffer_reset(&vs->zrle.zlib); |
76 | |
77 | if (zstream->opaque != vs) { |
78 | int err; |
79 | |
80 | zstream->zalloc = vnc_zlib_zalloc; |
81 | zstream->zfree = vnc_zlib_zfree; |
82 | |
83 | err = deflateInit2(zstream, level, Z_DEFLATED, MAX_WBITS,deflateInit2_((zstream),(level),(8),(15),(9), (0), "1.2.3.4", sizeof(z_stream)) |
84 | MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY)deflateInit2_((zstream),(level),(8),(15),(9), (0), "1.2.3.4", sizeof(z_stream)); |
85 | |
86 | if (err != Z_OK0) { |
87 | fprintf(stderrstderr, "VNC: error initializing zlib\n"); |
88 | return -1; |
89 | } |
90 | |
91 | zstream->opaque = vs; |
92 | } |
93 | |
94 | /* reserve memory in output buffer */ |
95 | buffer_reserve(&vs->zrle.zlib, vs->zrle.zrle.offset + 64); |
96 | |
97 | /* set pointers */ |
98 | zstream->next_in = vs->zrle.zrle.buffer; |
99 | zstream->avail_in = vs->zrle.zrle.offset; |
100 | zstream->next_out = vs->zrle.zlib.buffer + vs->zrle.zlib.offset; |
101 | zstream->avail_out = vs->zrle.zlib.capacity - vs->zrle.zlib.offset; |
102 | zstream->data_type = Z_BINARY0; |
103 | |
104 | /* start encoding */ |
105 | if (deflate(zstream, Z_SYNC_FLUSH2) != Z_OK0) { |
106 | fprintf(stderrstderr, "VNC: error during zrle compression\n"); |
107 | return -1; |
108 | } |
109 | |
110 | vs->zrle.zlib.offset = vs->zrle.zlib.capacity - zstream->avail_out; |
111 | return vs->zrle.zlib.offset; |
112 | } |
113 | |
114 | /* Try to work out whether to use RLE and/or a palette. We do this by |
115 | * estimating the number of bytes which will be generated and picking the |
116 | * method which results in the fewest bytes. Of course this may not result |
117 | * in the fewest bytes after compression... */ |
118 | static void zrle_choose_palette_rle(VncState *vs, int w, int h, |
119 | VncPalette *palette, int bpp_out, |
120 | int runs, int single_pixels, |
121 | int zywrle_level, |
122 | bool_Bool *use_rle, bool_Bool *use_palette) |
123 | { |
124 | size_t estimated_bytes; |
125 | size_t plain_rle_bytes; |
126 | |
127 | *use_palette = *use_rle = false0; |
128 | |
129 | estimated_bytes = w * h * (bpp_out / 8); /* start assuming raw */ |
130 | |
131 | if (bpp_out != 8) { |
132 | if (zywrle_level > 0 && !(zywrle_level & 0x80)) |
133 | estimated_bytes >>= zywrle_level; |
134 | } |
135 | |
136 | plain_rle_bytes = ((bpp_out / 8) + 1) * (runs + single_pixels); |
137 | |
138 | if (plain_rle_bytes < estimated_bytes) { |
139 | *use_rle = true1; |
140 | estimated_bytes = plain_rle_bytes; |
141 | } |
142 | |
143 | if (palette_size(palette) < 128) { |
144 | int palette_rle_bytes; |
145 | |
146 | palette_rle_bytes = (bpp_out / 8) * palette_size(palette); |
147 | palette_rle_bytes += 2 * runs + single_pixels; |
148 | |
149 | if (palette_rle_bytes < estimated_bytes) { |
150 | *use_rle = true1; |
151 | *use_palette = true1; |
152 | estimated_bytes = palette_rle_bytes; |
153 | } |
154 | |
155 | if (palette_size(palette) < 17) { |
156 | int packed_bytes; |
157 | |
158 | packed_bytes = (bpp_out / 8) * palette_size(palette); |
159 | packed_bytes += w * h * |
160 | bits_per_packed_pixel[palette_size(palette)-1] / 8; |
161 | |
162 | if (packed_bytes < estimated_bytes) { |
163 | *use_rle = false0; |
164 | *use_palette = true1; |
165 | estimated_bytes = packed_bytes; |
Value stored to 'estimated_bytes' is never read | |
166 | } |
167 | } |
168 | } |
169 | } |
170 | |
171 | static void zrle_write_u32(VncState *vs, uint32_t value) |
172 | { |
173 | vnc_write(vs, (uint8_t *)&value, 4); |
174 | } |
175 | |
176 | static void zrle_write_u24a(VncState *vs, uint32_t value) |
177 | { |
178 | vnc_write(vs, (uint8_t *)&value, 3); |
179 | } |
180 | |
181 | static void zrle_write_u24b(VncState *vs, uint32_t value) |
182 | { |
183 | vnc_write(vs, ((uint8_t *)&value) + 1, 3); |
184 | } |
185 | |
186 | static void zrle_write_u16(VncState *vs, uint16_t value) |
187 | { |
188 | vnc_write(vs, (uint8_t *)&value, 2); |
189 | } |
190 | |
191 | static void zrle_write_u8(VncState *vs, uint8_t value) |
192 | { |
193 | vnc_write_u8(vs, value); |
194 | } |
195 | |
196 | #define ENDIAN_LITTLE0 0 |
197 | #define ENDIAN_BIG1 1 |
198 | #define ENDIAN_NO2 2 |
199 | |
200 | #define ZRLE_BPP 8 |
201 | #define ZYWRLE_ENDIAN1 ENDIAN_NO2 |
202 | #include "vnc-enc-zrle-template.c" |
203 | #undef ZRLE_BPP |
204 | |
205 | #define ZRLE_BPP 15 |
206 | #undef ZYWRLE_ENDIAN1 |
207 | #define ZYWRLE_ENDIAN1 ENDIAN_LITTLE0 |
208 | #include "vnc-enc-zrle-template.c" |
209 | |
210 | #undef ZYWRLE_ENDIAN1 |
211 | #define ZYWRLE_ENDIAN1 ENDIAN_BIG1 |
212 | #include "vnc-enc-zrle-template.c" |
213 | |
214 | #undef ZRLE_BPP |
215 | #define ZRLE_BPP 16 |
216 | #undef ZYWRLE_ENDIAN1 |
217 | #define ZYWRLE_ENDIAN1 ENDIAN_LITTLE0 |
218 | #include "vnc-enc-zrle-template.c" |
219 | |
220 | #undef ZYWRLE_ENDIAN1 |
221 | #define ZYWRLE_ENDIAN1 ENDIAN_BIG1 |
222 | #include "vnc-enc-zrle-template.c" |
223 | |
224 | #undef ZRLE_BPP |
225 | #define ZRLE_BPP 32 |
226 | #undef ZYWRLE_ENDIAN1 |
227 | #define ZYWRLE_ENDIAN1 ENDIAN_LITTLE0 |
228 | #include "vnc-enc-zrle-template.c" |
229 | |
230 | #undef ZYWRLE_ENDIAN1 |
231 | #define ZYWRLE_ENDIAN1 ENDIAN_BIG1 |
232 | #include "vnc-enc-zrle-template.c" |
233 | |
234 | #define ZRLE_COMPACT_PIXEL 24a |
235 | #undef ZYWRLE_ENDIAN1 |
236 | #define ZYWRLE_ENDIAN1 ENDIAN_LITTLE0 |
237 | #include "vnc-enc-zrle-template.c" |
238 | |
239 | #undef ZYWRLE_ENDIAN1 |
240 | #define ZYWRLE_ENDIAN1 ENDIAN_BIG1 |
241 | #include "vnc-enc-zrle-template.c" |
242 | |
243 | #undef ZRLE_COMPACT_PIXEL |
244 | #define ZRLE_COMPACT_PIXEL 24b |
245 | #undef ZYWRLE_ENDIAN1 |
246 | #define ZYWRLE_ENDIAN1 ENDIAN_LITTLE0 |
247 | #include "vnc-enc-zrle-template.c" |
248 | |
249 | #undef ZYWRLE_ENDIAN1 |
250 | #define ZYWRLE_ENDIAN1 ENDIAN_BIG1 |
251 | #include "vnc-enc-zrle-template.c" |
252 | #undef ZRLE_COMPACT_PIXEL |
253 | #undef ZRLE_BPP |
254 | |
255 | static int zrle_send_framebuffer_update(VncState *vs, int x, int y, |
256 | int w, int h) |
257 | { |
258 | bool_Bool be = !!(vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG0x01); |
259 | size_t bytes; |
260 | int zywrle_level; |
261 | |
262 | if (vs->zrle.type == VNC_ENCODING_ZYWRLE0x00000011) { |
263 | if (!vs->vd->lossy || vs->tight.quality == (uint8_t)-1 |
264 | || vs->tight.quality == 9) { |
265 | zywrle_level = 0; |
266 | vs->zrle.type = VNC_ENCODING_ZRLE0x00000010; |
267 | } else if (vs->tight.quality < 3) { |
268 | zywrle_level = 3; |
269 | } else if (vs->tight.quality < 6) { |
270 | zywrle_level = 2; |
271 | } else { |
272 | zywrle_level = 1; |
273 | } |
274 | } else { |
275 | zywrle_level = 0; |
276 | } |
277 | |
278 | vnc_zrle_start(vs); |
279 | |
280 | switch(vs->clientds.pf.bytes_per_pixel) { |
281 | case 1: |
282 | zrle_encode_8ne(vs, x, y, w, h, zywrle_level); |
283 | break; |
284 | |
285 | case 2: |
286 | if (vs->clientds.pf.gmax > 0x1F) { |
287 | if (be) { |
288 | zrle_encode_16be(vs, x, y, w, h, zywrle_level); |
289 | } else { |
290 | zrle_encode_16le(vs, x, y, w, h, zywrle_level); |
291 | } |
292 | } else { |
293 | if (be) { |
294 | zrle_encode_15be(vs, x, y, w, h, zywrle_level); |
295 | } else { |
296 | zrle_encode_15le(vs, x, y, w, h, zywrle_level); |
297 | } |
298 | } |
299 | break; |
300 | |
301 | case 4: |
302 | { |
303 | bool_Bool fits_in_ls3bytes; |
304 | bool_Bool fits_in_ms3bytes; |
305 | |
306 | fits_in_ls3bytes = |
307 | ((vs->clientds.pf.rmax << vs->clientds.pf.rshift) < (1 << 24) && |
308 | (vs->clientds.pf.gmax << vs->clientds.pf.gshift) < (1 << 24) && |
309 | (vs->clientds.pf.bmax << vs->clientds.pf.bshift) < (1 << 24)); |
310 | |
311 | fits_in_ms3bytes = (vs->clientds.pf.rshift > 7 && |
312 | vs->clientds.pf.gshift > 7 && |
313 | vs->clientds.pf.bshift > 7); |
314 | |
315 | if ((fits_in_ls3bytes && !be) || (fits_in_ms3bytes && be)) { |
316 | if (be) { |
317 | zrle_encode_24abe(vs, x, y, w, h, zywrle_level); |
318 | } else { |
319 | zrle_encode_24ale(vs, x, y, w, h, zywrle_level); |
320 | } |
321 | } else if ((fits_in_ls3bytes && be) || (fits_in_ms3bytes && !be)) { |
322 | if (be) { |
323 | zrle_encode_24bbe(vs, x, y, w, h, zywrle_level); |
324 | } else { |
325 | zrle_encode_24ble(vs, x, y, w, h, zywrle_level); |
326 | } |
327 | } else { |
328 | if (be) { |
329 | zrle_encode_32be(vs, x, y, w, h, zywrle_level); |
330 | } else { |
331 | zrle_encode_32le(vs, x, y, w, h, zywrle_level); |
332 | } |
333 | } |
334 | } |
335 | break; |
336 | } |
337 | |
338 | vnc_zrle_stop(vs); |
339 | bytes = zrle_compress_data(vs, Z_DEFAULT_COMPRESSION(-1)); |
340 | vnc_framebuffer_update(vs, x, y, w, h, vs->zrle.type); |
341 | vnc_write_u32(vs, bytes); |
342 | vnc_write(vs, vs->zrle.zlib.buffer, vs->zrle.zlib.offset); |
343 | return 1; |
344 | } |
345 | |
346 | int vnc_zrle_send_framebuffer_update(VncState *vs, int x, int y, int w, int h) |
347 | { |
348 | vs->zrle.type = VNC_ENCODING_ZRLE0x00000010; |
349 | return zrle_send_framebuffer_update(vs, x, y, w, h); |
350 | } |
351 | |
352 | int vnc_zywrle_send_framebuffer_update(VncState *vs, int x, int y, int w, int h) |
353 | { |
354 | vs->zrle.type = VNC_ENCODING_ZYWRLE0x00000011; |
355 | return zrle_send_framebuffer_update(vs, x, y, w, h); |
356 | } |
357 | |
358 | void vnc_zrle_clear(VncState *vs) |
359 | { |
360 | if (vs->zrle.stream.opaque) { |
361 | deflateEnd(&vs->zrle.stream); |
362 | } |
363 | buffer_free(&vs->zrle.zrle); |
364 | buffer_free(&vs->zrle.fb); |
365 | buffer_free(&vs->zrle.zlib); |
366 | } |