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:
@@ -119,6 +119,7 @@ All (GUI):
|
|||||||
- Add wxDataViewRenderer::GetAccessibleDescription().
|
- Add wxDataViewRenderer::GetAccessibleDescription().
|
||||||
- Improve wxImage::Scale() handling of pixels with alpha channel (Tim Kosse).
|
- Improve wxImage::Scale() handling of pixels with alpha channel (Tim Kosse).
|
||||||
- Fix parsing of RGBA strings in wxColour (Laurent Poujoulat).
|
- Fix parsing of RGBA strings in wxColour (Laurent Poujoulat).
|
||||||
|
- Refactor code in wxQuantize() for MSVC to avoid crash.
|
||||||
|
|
||||||
wxGTK:
|
wxGTK:
|
||||||
|
|
||||||
|
@@ -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
|
void
|
||||||
pass2_fs_dither (j_decompress_ptr cinfo,
|
pass2_fs_dither (j_decompress_ptr cinfo,
|
||||||
JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)
|
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 */
|
bnexterr = cur0; /* Process component 0 */
|
||||||
delta = cur0 * 2;
|
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 */
|
cur0 += delta; /* form error * 3 */
|
||||||
|
#endif
|
||||||
errorptr[0] = (FSERROR) (bpreverr0 + cur0);
|
errorptr[0] = (FSERROR) (bpreverr0 + cur0);
|
||||||
cur0 += delta; /* form error * 5 */
|
cur0 += delta; /* form error * 5 */
|
||||||
bpreverr0 = belowerr0 + cur0;
|
bpreverr0 = belowerr0 + cur0;
|
||||||
@@ -1145,7 +1145,12 @@ pass2_fs_dither (j_decompress_ptr cinfo,
|
|||||||
cur0 += delta; /* form error * 7 */
|
cur0 += delta; /* form error * 7 */
|
||||||
bnexterr = cur1; /* Process component 1 */
|
bnexterr = cur1; /* Process component 1 */
|
||||||
delta = cur1 * 2;
|
delta = cur1 * 2;
|
||||||
|
#ifdef __VISUALC__
|
||||||
|
/* Use refactored code to prevent invalid optimization. */
|
||||||
|
cur1 *= 3; /* form error * 3 */
|
||||||
|
#else
|
||||||
cur1 += delta; /* form error * 3 */
|
cur1 += delta; /* form error * 3 */
|
||||||
|
#endif
|
||||||
errorptr[1] = (FSERROR) (bpreverr1 + cur1);
|
errorptr[1] = (FSERROR) (bpreverr1 + cur1);
|
||||||
cur1 += delta; /* form error * 5 */
|
cur1 += delta; /* form error * 5 */
|
||||||
bpreverr1 = belowerr1 + cur1;
|
bpreverr1 = belowerr1 + cur1;
|
||||||
@@ -1153,7 +1158,12 @@ pass2_fs_dither (j_decompress_ptr cinfo,
|
|||||||
cur1 += delta; /* form error * 7 */
|
cur1 += delta; /* form error * 7 */
|
||||||
bnexterr = cur2; /* Process component 2 */
|
bnexterr = cur2; /* Process component 2 */
|
||||||
delta = cur2 * 2;
|
delta = cur2 * 2;
|
||||||
|
#ifdef __VISUALC__
|
||||||
|
/* Use refactored code to prevent invalid optimization. */
|
||||||
|
cur2 *= 3; /* form error * 3 */
|
||||||
|
#else
|
||||||
cur2 += delta; /* form error * 3 */
|
cur2 += delta; /* form error * 3 */
|
||||||
|
#endif
|
||||||
errorptr[2] = (FSERROR) (bpreverr2 + cur2);
|
errorptr[2] = (FSERROR) (bpreverr2 + cur2);
|
||||||
cur2 += delta; /* form error * 5 */
|
cur2 += delta; /* form error * 5 */
|
||||||
bpreverr2 = belowerr2 + cur2;
|
bpreverr2 = belowerr2 + cur2;
|
||||||
@@ -1177,9 +1187,6 @@ pass2_fs_dither (j_decompress_ptr cinfo,
|
|||||||
errorptr[2] = (FSERROR) bpreverr2;
|
errorptr[2] = (FSERROR) bpreverr2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef __VISUALC__
|
|
||||||
#pragma optimize ("", on)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the error-limiting transfer function (lookup table).
|
* Initialize the error-limiting transfer function (lookup table).
|
||||||
|
Reference in New Issue
Block a user