Refactor code in wxQuantize() for MSVC to avoid crash

VC++ compilers (at least up to VS 2015) seem to generate incorrect code for the dithering code taken from libjpeg (pass2_fs_dither() function), where it is known to create problems too.
Refactor the code to avoid invalid optimization in this function and turn optimization on.

Closes #17764.
This commit is contained in:
Artur Wieczorek 2017-01-10 21:30:43 +01:00
parent 92f80a18c6
commit 6cef4eaa11
2 changed files with 22 additions and 14 deletions

View File

@ -119,6 +119,7 @@ All (GUI):
- Add wxDataViewRenderer::GetAccessibleDescription().
- Improve wxImage::Scale() handling of pixels with alpha channel (Tim Kosse).
- Fix parsing of RGBA strings in wxColour (Laurent Poujoulat).
- Refactor code in wxQuantize() for MSVC to avoid crash.
wxGTK:

View File

@ -1026,17 +1026,6 @@ pass2_no_dither (j_decompress_ptr cinfo,
}
}
#ifdef __VISUALC__
/*
for (yet) unknown reasons, the following code produces
bad results or even crashes if the code optimization is
enabled in VC++
disable optimization for now until the reason is discovered
*/
#pragma optimize ("", off)
#endif
void
pass2_fs_dither (j_decompress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)
@ -1137,7 +1126,18 @@ pass2_fs_dither (j_decompress_ptr cinfo,
bnexterr = cur0; /* Process component 0 */
delta = cur0 * 2;
/*
Calculating cur0, cur1, cur2 gives bad results if code
optimization is enabled in VC++. This is apparently caused
by some bug in the compiler.
Use refactored code until it is fixed.
*/
#ifdef __VISUALC__
/* Use refactored code to prevent invalid optimization. */
cur0 *= 3; /* form error * 3 */
#else
cur0 += delta; /* form error * 3 */
#endif
errorptr[0] = (FSERROR) (bpreverr0 + cur0);
cur0 += delta; /* form error * 5 */
bpreverr0 = belowerr0 + cur0;
@ -1145,7 +1145,12 @@ pass2_fs_dither (j_decompress_ptr cinfo,
cur0 += delta; /* form error * 7 */
bnexterr = cur1; /* Process component 1 */
delta = cur1 * 2;
#ifdef __VISUALC__
/* Use refactored code to prevent invalid optimization. */
cur1 *= 3; /* form error * 3 */
#else
cur1 += delta; /* form error * 3 */
#endif
errorptr[1] = (FSERROR) (bpreverr1 + cur1);
cur1 += delta; /* form error * 5 */
bpreverr1 = belowerr1 + cur1;
@ -1153,7 +1158,12 @@ pass2_fs_dither (j_decompress_ptr cinfo,
cur1 += delta; /* form error * 7 */
bnexterr = cur2; /* Process component 2 */
delta = cur2 * 2;
#ifdef __VISUALC__
/* Use refactored code to prevent invalid optimization. */
cur2 *= 3; /* form error * 3 */
#else
cur2 += delta; /* form error * 3 */
#endif
errorptr[2] = (FSERROR) (bpreverr2 + cur2);
cur2 += delta; /* form error * 5 */
bpreverr2 = belowerr2 + cur2;
@ -1177,9 +1187,6 @@ pass2_fs_dither (j_decompress_ptr cinfo,
errorptr[2] = (FSERROR) bpreverr2;
}
}
#ifdef __VISUALC__
#pragma optimize ("", on)
#endif
/*
* Initialize the error-limiting transfer function (lookup table).