diff options
Diffstat (limited to 'meta/recipes-graphics/jpeg/files/CVE-2020-35538-2.patch')
-rw-r--r-- | meta/recipes-graphics/jpeg/files/CVE-2020-35538-2.patch | 400 |
1 files changed, 400 insertions, 0 deletions
diff --git a/meta/recipes-graphics/jpeg/files/CVE-2020-35538-2.patch b/meta/recipes-graphics/jpeg/files/CVE-2020-35538-2.patch new file mode 100644 index 0000000000..f86175dff0 --- /dev/null +++ b/meta/recipes-graphics/jpeg/files/CVE-2020-35538-2.patch | |||
@@ -0,0 +1,400 @@ | |||
1 | From a46c111d9f3642f0ef3819e7298846ccc61869e0 Mon Sep 17 00:00:00 2001 | ||
2 | From: DRC <information@libjpeg-turbo.org> | ||
3 | Date: Mon, 27 Jul 2020 14:21:23 -0500 | ||
4 | Subject: [PATCH] Further jpeg_skip_scanlines() fixes | ||
5 | |||
6 | - Introduce a partial image decompression regression test script that | ||
7 | validates the correctness of jpeg_skip_scanlines() and | ||
8 | jpeg_crop_scanlines() for a variety of cropping regions and libjpeg | ||
9 | settings. | ||
10 | |||
11 | This regression test catches the following issues: | ||
12 | #182, fixed in 5bc43c7 | ||
13 | #237, fixed in 6e95c08 | ||
14 | #244, fixed in 398c1e9 | ||
15 | #441, fully fixed in this commit | ||
16 | |||
17 | It does not catch the following issues: | ||
18 | #194, fixed in 773040f | ||
19 | #244 (additional segfault), fixed in | ||
20 | 9120a24 | ||
21 | |||
22 | - Modify the libjpeg-turbo regression test suite (make test) so that it | ||
23 | checks for the issue reported in #441 (segfault in | ||
24 | jpeg_skip_scanlines() when used with 4:2:0 merged upsampling/color | ||
25 | conversion.) | ||
26 | |||
27 | - Fix issues in jpeg_skip_scanlines() that caused incorrect output with | ||
28 | h2v2 (4:2:0) merged upsampling/color conversion. The previous commit | ||
29 | fixed the segfault reported in #441, but that was a symptom of a | ||
30 | larger problem. Because merged 4:2:0 upsampling uses a "spare row" | ||
31 | buffer, it is necessary to allow the upsampler to run when skipping | ||
32 | rows (fancy 4:2:0 upsampling, which uses context rows, also requires | ||
33 | this.) Otherwise, if skipping starts at an odd-numbered row, the | ||
34 | output image will be incorrect. | ||
35 | |||
36 | - Throw an error if jpeg_skip_scanlines() is called with two-pass color | ||
37 | quantization enabled. With two-pass color quantization, the first | ||
38 | pass occurs within jpeg_start_decompress(), so subsequent calls to | ||
39 | jpeg_skip_scanlines() interfere with the multipass state and prevent | ||
40 | the second pass from occurring during subsequent calls to | ||
41 | jpeg_read_scanlines(). | ||
42 | |||
43 | Upstream-Status: Backport [https://github.com/libjpeg-turbo/libjpeg-turbo/commit/a46c111d9f3642f0ef3819e7298846ccc61869e0] | ||
44 | CVE: CVE-2020-35538 | ||
45 | Signed-off-by: Vijay Anusuri <vanusuri@mvista.com> | ||
46 | --- | ||
47 | CMakeLists.txt | 9 +++-- | ||
48 | ChangeLog.md | 15 +++++--- | ||
49 | croptest.in | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++ | ||
50 | jdapistd.c | 70 +++++++++++-------------------------- | ||
51 | libjpeg.txt | 6 ++-- | ||
52 | 5 files changed, 136 insertions(+), 59 deletions(-) | ||
53 | create mode 100755 croptest.in | ||
54 | |||
55 | diff --git a/CMakeLists.txt b/CMakeLists.txt | ||
56 | index aee74c9..de451f4 100644 | ||
57 | --- a/CMakeLists.txt | ||
58 | +++ b/CMakeLists.txt | ||
59 | @@ -753,7 +753,7 @@ else() | ||
60 | set(MD5_PPM_3x2_IFAST fd283664b3b49127984af0a7f118fccd) | ||
61 | set(MD5_JPEG_420_ISLOW_ARI e986fb0a637a8d833d96e8a6d6d84ea1) | ||
62 | set(MD5_JPEG_444_ISLOW_PROGARI 0a8f1c8f66e113c3cf635df0a475a617) | ||
63 | - set(MD5_PPM_420M_IFAST_ARI 72b59a99bcf1de24c5b27d151bde2437) | ||
64 | + set(MD5_PPM_420M_IFAST_ARI 57251da28a35b46eecb7177d82d10e0e) | ||
65 | set(MD5_JPEG_420_ISLOW 9a68f56bc76e466aa7e52f415d0f4a5f) | ||
66 | set(MD5_PPM_420M_ISLOW_2_1 9f9de8c0612f8d06869b960b05abf9c9) | ||
67 | set(MD5_PPM_420M_ISLOW_15_8 b6875bc070720b899566cc06459b63b7) | ||
68 | @@ -1131,7 +1131,7 @@ foreach(libtype ${TEST_LIBTYPES}) | ||
69 | |||
70 | if(WITH_ARITH_DEC) | ||
71 | # CC: RGB->YCC SAMP: h2v2 merged IDCT: ifast ENT: arith | ||
72 | - add_bittest(djpeg 420m-ifast-ari "-fast;-ppm" | ||
73 | + add_bittest(djpeg 420m-ifast-ari "-fast;-skip;1,20;-ppm" | ||
74 | testout_420m_ifast_ari.ppm ${TESTIMAGES}/testimgari.jpg | ||
75 | ${MD5_PPM_420M_IFAST_ARI}) | ||
76 | |||
77 | @@ -1266,6 +1266,11 @@ endforeach() | ||
78 | add_custom_target(testclean COMMAND ${CMAKE_COMMAND} -P | ||
79 | ${CMAKE_CURRENT_SOURCE_DIR}/cmakescripts/testclean.cmake) | ||
80 | |||
81 | +configure_file(croptest.in croptest @ONLY) | ||
82 | +add_custom_target(croptest | ||
83 | + COMMAND echo croptest | ||
84 | + COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/croptest) | ||
85 | + | ||
86 | if(WITH_TURBOJPEG) | ||
87 | configure_file(tjbenchtest.in tjbenchtest @ONLY) | ||
88 | configure_file(tjexampletest.in tjexampletest @ONLY) | ||
89 | diff --git a/ChangeLog.md b/ChangeLog.md | ||
90 | index 19d18fa..4562eff 100644 | ||
91 | --- a/ChangeLog.md | ||
92 | +++ b/ChangeLog.md | ||
93 | @@ -54,11 +54,16 @@ a 16-bit binary PGM file into an RGB image buffer. | ||
94 | generated when using the `tjLoadImage()` function to load a 16-bit binary PPM | ||
95 | file into an extended RGB image buffer. | ||
96 | |||
97 | -2. Fixed segfaults or "Corrupt JPEG data: premature end of data segment" errors | ||
98 | -in `jpeg_skip_scanlines()` that occurred when decompressing 4:2:2 or 4:2:0 JPEG | ||
99 | -images using the merged (non-fancy) upsampling algorithms (that is, when | ||
100 | -setting `cinfo.do_fancy_upsampling` to `FALSE`.) 2.0.0[6] was a similar fix, | ||
101 | -but it did not cover all cases. | ||
102 | +2. Fixed or worked around multiple issues with `jpeg_skip_scanlines()`: | ||
103 | + | ||
104 | + - Fixed segfaults or "Corrupt JPEG data: premature end of data segment" | ||
105 | +errors in `jpeg_skip_scanlines()` that occurred when decompressing 4:2:2 or | ||
106 | +4:2:0 JPEG images using merged (non-fancy) upsampling/color conversion (that | ||
107 | +is, when setting `cinfo.do_fancy_upsampling` to `FALSE`.) 2.0.0[6] was a | ||
108 | +similar fix, but it did not cover all cases. | ||
109 | + - `jpeg_skip_scanlines()` now throws an error if two-pass color | ||
110 | +quantization is enabled. Two-pass color quantization never worked properly | ||
111 | +with `jpeg_skip_scanlines()`, and the issues could not readily be fixed. | ||
112 | |||
113 | |||
114 | 2.0.3 | ||
115 | diff --git a/croptest.in b/croptest.in | ||
116 | new file mode 100755 | ||
117 | index 0000000..7e3c293 | ||
118 | --- /dev/null | ||
119 | +++ b/croptest.in | ||
120 | @@ -0,0 +1,95 @@ | ||
121 | +#!/bin/bash | ||
122 | + | ||
123 | +set -u | ||
124 | +set -e | ||
125 | +trap onexit INT | ||
126 | +trap onexit TERM | ||
127 | +trap onexit EXIT | ||
128 | + | ||
129 | +onexit() | ||
130 | +{ | ||
131 | + if [ -d $OUTDIR ]; then | ||
132 | + rm -rf $OUTDIR | ||
133 | + fi | ||
134 | +} | ||
135 | + | ||
136 | +runme() | ||
137 | +{ | ||
138 | + echo \*\*\* $* | ||
139 | + $* | ||
140 | +} | ||
141 | + | ||
142 | +IMAGE=vgl_6548_0026a.bmp | ||
143 | +WIDTH=128 | ||
144 | +HEIGHT=95 | ||
145 | +IMGDIR=@CMAKE_CURRENT_SOURCE_DIR@/testimages | ||
146 | +OUTDIR=`mktemp -d /tmp/__croptest_output.XXXXXX` | ||
147 | +EXEDIR=@CMAKE_CURRENT_BINARY_DIR@ | ||
148 | + | ||
149 | +if [ -d $OUTDIR ]; then | ||
150 | + rm -rf $OUTDIR | ||
151 | +fi | ||
152 | +mkdir -p $OUTDIR | ||
153 | + | ||
154 | +exec >$EXEDIR/croptest.log | ||
155 | + | ||
156 | +echo "============================================================" | ||
157 | +echo "$IMAGE ($WIDTH x $HEIGHT)" | ||
158 | +echo "============================================================" | ||
159 | +echo | ||
160 | + | ||
161 | +for PROGARG in "" -progressive; do | ||
162 | + | ||
163 | + cp $IMGDIR/$IMAGE $OUTDIR | ||
164 | + basename=`basename $IMAGE .bmp` | ||
165 | + echo "------------------------------------------------------------" | ||
166 | + echo "Generating test images" | ||
167 | + echo "------------------------------------------------------------" | ||
168 | + echo | ||
169 | + runme $EXEDIR/cjpeg $PROGARG -grayscale -outfile $OUTDIR/${basename}_GRAY.jpg $IMGDIR/${basename}.bmp | ||
170 | + runme $EXEDIR/cjpeg $PROGARG -sample 2x2 -outfile $OUTDIR/${basename}_420.jpg $IMGDIR/${basename}.bmp | ||
171 | + runme $EXEDIR/cjpeg $PROGARG -sample 2x1 -outfile $OUTDIR/${basename}_422.jpg $IMGDIR/${basename}.bmp | ||
172 | + runme $EXEDIR/cjpeg $PROGARG -sample 1x2 -outfile $OUTDIR/${basename}_440.jpg $IMGDIR/${basename}.bmp | ||
173 | + runme $EXEDIR/cjpeg $PROGARG -sample 1x1 -outfile $OUTDIR/${basename}_444.jpg $IMGDIR/${basename}.bmp | ||
174 | + echo | ||
175 | + | ||
176 | + for NSARG in "" -nosmooth; do | ||
177 | + | ||
178 | + for COLORSARG in "" "-colors 256 -dither none -onepass"; do | ||
179 | + | ||
180 | + for Y in {0..16}; do | ||
181 | + | ||
182 | + for H in {1..16}; do | ||
183 | + | ||
184 | + X=$(( (Y*16)%128 )) | ||
185 | + W=$(( WIDTH-X-7 )) | ||
186 | + if [ $Y -le 15 ]; then | ||
187 | + CROPSPEC="${W}x${H}+${X}+${Y}" | ||
188 | + else | ||
189 | + Y2=$(( HEIGHT-H )); | ||
190 | + CROPSPEC="${W}x${H}+${X}+${Y2}" | ||
191 | + fi | ||
192 | + | ||
193 | + echo "------------------------------------------------------------" | ||
194 | + echo $PROGARG $NSARG $COLORSARG -crop $CROPSPEC | ||
195 | + echo "------------------------------------------------------------" | ||
196 | + echo | ||
197 | + for samp in GRAY 420 422 440 444; do | ||
198 | + $EXEDIR/djpeg $NSARG $COLORSARG -rgb -outfile $OUTDIR/${basename}_${samp}_full.ppm $OUTDIR/${basename}_${samp}.jpg | ||
199 | + convert -crop $CROPSPEC $OUTDIR/${basename}_${samp}_full.ppm $OUTDIR/${basename}_${samp}_ref.ppm | ||
200 | + runme $EXEDIR/djpeg $NSARG $COLORSARG -crop $CROPSPEC -rgb -outfile $OUTDIR/${basename}_${samp}.ppm $OUTDIR/${basename}_${samp}.jpg | ||
201 | + runme cmp $OUTDIR/${basename}_${samp}.ppm $OUTDIR/${basename}_${samp}_ref.ppm | ||
202 | + done | ||
203 | + echo | ||
204 | + | ||
205 | + done | ||
206 | + | ||
207 | + done | ||
208 | + | ||
209 | + done | ||
210 | + | ||
211 | + done | ||
212 | + | ||
213 | +done | ||
214 | + | ||
215 | +echo SUCCESS! | ||
216 | diff --git a/jdapistd.c b/jdapistd.c | ||
217 | index 91da642..c502909 100644 | ||
218 | --- a/jdapistd.c | ||
219 | +++ b/jdapistd.c | ||
220 | @@ -306,16 +306,6 @@ noop_quantize(j_decompress_ptr cinfo, JSAMPARRAY input_buf, | ||
221 | } | ||
222 | |||
223 | |||
224 | -/* Dummy postprocessing function used by jpeg_skip_scanlines() */ | ||
225 | -LOCAL(void) | ||
226 | -noop_post_process (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, | ||
227 | - JDIMENSION *in_row_group_ctr, | ||
228 | - JDIMENSION in_row_groups_avail, JSAMPARRAY output_buf, | ||
229 | - JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail) | ||
230 | -{ | ||
231 | -} | ||
232 | - | ||
233 | - | ||
234 | /* | ||
235 | * In some cases, it is best to call jpeg_read_scanlines() and discard the | ||
236 | * output, rather than skipping the scanlines, because this allows us to | ||
237 | @@ -329,16 +319,12 @@ read_and_discard_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines) | ||
238 | { | ||
239 | JDIMENSION n; | ||
240 | my_master_ptr master = (my_master_ptr)cinfo->master; | ||
241 | + JSAMPARRAY scanlines = NULL; | ||
242 | void (*color_convert) (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, | ||
243 | JDIMENSION input_row, JSAMPARRAY output_buf, | ||
244 | int num_rows) = NULL; | ||
245 | void (*color_quantize) (j_decompress_ptr cinfo, JSAMPARRAY input_buf, | ||
246 | JSAMPARRAY output_buf, int num_rows) = NULL; | ||
247 | - void (*post_process_data) (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, | ||
248 | - JDIMENSION *in_row_group_ctr, | ||
249 | - JDIMENSION in_row_groups_avail, | ||
250 | - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, | ||
251 | - JDIMENSION out_rows_avail) = NULL; | ||
252 | |||
253 | if (cinfo->cconvert && cinfo->cconvert->color_convert) { | ||
254 | color_convert = cinfo->cconvert->color_convert; | ||
255 | @@ -350,23 +336,19 @@ read_and_discard_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines) | ||
256 | cinfo->cquantize->color_quantize = noop_quantize; | ||
257 | } | ||
258 | |||
259 | - if (master->using_merged_upsample && cinfo->post && | ||
260 | - cinfo->post->post_process_data) { | ||
261 | - post_process_data = cinfo->post->post_process_data; | ||
262 | - cinfo->post->post_process_data = noop_post_process; | ||
263 | + if (master->using_merged_upsample && cinfo->max_v_samp_factor == 2) { | ||
264 | + my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample; | ||
265 | + scanlines = &upsample->spare_row; | ||
266 | } | ||
267 | |||
268 | for (n = 0; n < num_lines; n++) | ||
269 | - jpeg_read_scanlines(cinfo, NULL, 1); | ||
270 | + jpeg_read_scanlines(cinfo, scanlines, 1); | ||
271 | |||
272 | if (color_convert) | ||
273 | cinfo->cconvert->color_convert = color_convert; | ||
274 | |||
275 | if (color_quantize) | ||
276 | cinfo->cquantize->color_quantize = color_quantize; | ||
277 | - | ||
278 | - if (post_process_data) | ||
279 | - cinfo->post->post_process_data = post_process_data; | ||
280 | } | ||
281 | |||
282 | |||
283 | @@ -380,6 +362,12 @@ increment_simple_rowgroup_ctr(j_decompress_ptr cinfo, JDIMENSION rows) | ||
284 | { | ||
285 | JDIMENSION rows_left; | ||
286 | my_main_ptr main_ptr = (my_main_ptr)cinfo->main; | ||
287 | + my_master_ptr master = (my_master_ptr)cinfo->master; | ||
288 | + | ||
289 | + if (master->using_merged_upsample && cinfo->max_v_samp_factor == 2) { | ||
290 | + read_and_discard_scanlines(cinfo, rows); | ||
291 | + return; | ||
292 | + } | ||
293 | |||
294 | /* Increment the counter to the next row group after the skipped rows. */ | ||
295 | main_ptr->rowgroup_ctr += rows / cinfo->max_v_samp_factor; | ||
296 | @@ -410,11 +398,16 @@ jpeg_skip_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines) | ||
297 | my_main_ptr main_ptr = (my_main_ptr)cinfo->main; | ||
298 | my_coef_ptr coef = (my_coef_ptr)cinfo->coef; | ||
299 | my_master_ptr master = (my_master_ptr)cinfo->master; | ||
300 | + my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample; | ||
301 | JDIMENSION i, x; | ||
302 | int y; | ||
303 | JDIMENSION lines_per_iMCU_row, lines_left_in_iMCU_row, lines_after_iMCU_row; | ||
304 | JDIMENSION lines_to_skip, lines_to_read; | ||
305 | |||
306 | + /* Two-pass color quantization is not supported. */ | ||
307 | + if (cinfo->quantize_colors && cinfo->two_pass_quantize) | ||
308 | + ERREXIT(cinfo, JERR_NOTIMPL); | ||
309 | + | ||
310 | if (cinfo->global_state != DSTATE_SCANNING) | ||
311 | ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); | ||
312 | |||
313 | @@ -472,13 +465,7 @@ jpeg_skip_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines) | ||
314 | main_ptr->buffer_full = FALSE; | ||
315 | main_ptr->rowgroup_ctr = 0; | ||
316 | main_ptr->context_state = CTX_PREPARE_FOR_IMCU; | ||
317 | - if (master->using_merged_upsample) { | ||
318 | - my_merged_upsample_ptr upsample = | ||
319 | - (my_merged_upsample_ptr)cinfo->upsample; | ||
320 | - upsample->spare_full = FALSE; | ||
321 | - upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline; | ||
322 | - } else { | ||
323 | - my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample; | ||
324 | + if (!master->using_merged_upsample) { | ||
325 | upsample->next_row_out = cinfo->max_v_samp_factor; | ||
326 | upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline; | ||
327 | } | ||
328 | @@ -493,13 +480,7 @@ jpeg_skip_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines) | ||
329 | cinfo->output_scanline += lines_left_in_iMCU_row; | ||
330 | main_ptr->buffer_full = FALSE; | ||
331 | main_ptr->rowgroup_ctr = 0; | ||
332 | - if (master->using_merged_upsample) { | ||
333 | - my_merged_upsample_ptr upsample = | ||
334 | - (my_merged_upsample_ptr)cinfo->upsample; | ||
335 | - upsample->spare_full = FALSE; | ||
336 | - upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline; | ||
337 | - } else { | ||
338 | - my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample; | ||
339 | + if (!master->using_merged_upsample) { | ||
340 | upsample->next_row_out = cinfo->max_v_samp_factor; | ||
341 | upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline; | ||
342 | } | ||
343 | @@ -537,14 +518,8 @@ jpeg_skip_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines) | ||
344 | cinfo->output_iMCU_row += lines_to_skip / lines_per_iMCU_row; | ||
345 | increment_simple_rowgroup_ctr(cinfo, lines_to_read); | ||
346 | } | ||
347 | - if (master->using_merged_upsample) { | ||
348 | - my_merged_upsample_ptr upsample = | ||
349 | - (my_merged_upsample_ptr)cinfo->upsample; | ||
350 | - upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline; | ||
351 | - } else { | ||
352 | - my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample; | ||
353 | + if (!master->using_merged_upsample) | ||
354 | upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline; | ||
355 | - } | ||
356 | return num_lines; | ||
357 | } | ||
358 | |||
359 | @@ -585,13 +560,8 @@ jpeg_skip_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines) | ||
360 | * bit odd, since "rows_to_go" seems to be redundantly keeping track of | ||
361 | * output_scanline. | ||
362 | */ | ||
363 | - if (master->using_merged_upsample) { | ||
364 | - my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample; | ||
365 | + if (!master->using_merged_upsample) | ||
366 | upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline; | ||
367 | - } else { | ||
368 | - my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample; | ||
369 | - upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline; | ||
370 | - } | ||
371 | |||
372 | /* Always skip the requested number of lines. */ | ||
373 | return num_lines; | ||
374 | diff --git a/libjpeg.txt b/libjpeg.txt | ||
375 | index c50cf90..c233ecb 100644 | ||
376 | --- a/libjpeg.txt | ||
377 | +++ b/libjpeg.txt | ||
378 | @@ -3,7 +3,7 @@ USING THE IJG JPEG LIBRARY | ||
379 | This file was part of the Independent JPEG Group's software: | ||
380 | Copyright (C) 1994-2013, Thomas G. Lane, Guido Vollbeding. | ||
381 | libjpeg-turbo Modifications: | ||
382 | -Copyright (C) 2010, 2014-2018, D. R. Commander. | ||
383 | +Copyright (C) 2010, 2014-2018, 2020, D. R. Commander. | ||
384 | Copyright (C) 2015, Google, Inc. | ||
385 | For conditions of distribution and use, see the accompanying README.ijg file. | ||
386 | |||
387 | @@ -750,7 +750,9 @@ multiple rows in the JPEG image. | ||
388 | |||
389 | Suspending data sources are not supported by this function. Calling | ||
390 | jpeg_skip_scanlines() with a suspending data source will result in undefined | ||
391 | -behavior. | ||
392 | +behavior. Two-pass color quantization is also not supported by this function. | ||
393 | +Calling jpeg_skip_scanlines() with two-pass color quantization enabled will | ||
394 | +result in an error. | ||
395 | |||
396 | jpeg_skip_scanlines() will not allow skipping past the bottom of the image. If | ||
397 | the value of num_lines is large enough to skip past the bottom of the image, | ||
398 | -- | ||
399 | 2.25.1 | ||
400 | |||