opj_tcd_dc_level_shift_decode(): optimize lossy case

This commit is contained in:
Even Rouault 2017-09-01 16:31:04 +02:00
parent 470f3ed416
commit ae19001ba4
2 changed files with 29 additions and 5 deletions

View File

@ -124,6 +124,28 @@ static INLINE OPJ_INT32 opj_int_clamp(OPJ_INT32 a, OPJ_INT32 min,
} }
return a; return a;
} }
/**
Clamp an integer inside an interval
@return
<ul>
<li>Returns a if (min < a < max)
<li>Returns max if (a > max)
<li>Returns min if (a < min)
</ul>
*/
static INLINE OPJ_INT64 opj_int64_clamp(OPJ_INT64 a, OPJ_INT64 min,
OPJ_INT64 max)
{
if (a < min) {
return min;
}
if (a > max) {
return max;
}
return a;
}
/** /**
@return Get absolute value of integer @return Get absolute value of integer
*/ */

View File

@ -2112,6 +2112,7 @@ static OPJ_BOOL opj_tcd_dc_level_shift_decode(opj_tcd_t *p_tcd)
if (l_tccp->qmfbid == 1) { if (l_tccp->qmfbid == 1) {
for (j = 0; j < l_height; ++j) { for (j = 0; j < l_height; ++j) {
for (i = 0; i < l_width; ++i) { for (i = 0; i < l_width; ++i) {
/* TODO: do addition on int64 ? */
*l_current_ptr = opj_int_clamp(*l_current_ptr + l_tccp->m_dc_level_shift, l_min, *l_current_ptr = opj_int_clamp(*l_current_ptr + l_tccp->m_dc_level_shift, l_min,
l_max); l_max);
++l_current_ptr; ++l_current_ptr;
@ -2122,13 +2123,14 @@ static OPJ_BOOL opj_tcd_dc_level_shift_decode(opj_tcd_t *p_tcd)
for (j = 0; j < l_height; ++j) { for (j = 0; j < l_height; ++j) {
for (i = 0; i < l_width; ++i) { for (i = 0; i < l_width; ++i) {
OPJ_FLOAT32 l_value = *((OPJ_FLOAT32 *) l_current_ptr); OPJ_FLOAT32 l_value = *((OPJ_FLOAT32 *) l_current_ptr);
OPJ_INT32 l_value_int = (OPJ_INT32)opj_lrintf(l_value); if (l_value > INT_MAX) {
if (l_value > INT_MAX ||
(l_value_int > 0 && l_tccp->m_dc_level_shift > 0 &&
l_value_int > INT_MAX - l_tccp->m_dc_level_shift)) {
*l_current_ptr = l_max; *l_current_ptr = l_max;
} else if (l_value < INT_MIN) {
*l_current_ptr = l_min;
} else { } else {
*l_current_ptr = opj_int_clamp( /* Do addition on int64 to avoid overflows */
OPJ_INT64 l_value_int = (OPJ_INT64)opj_lrintf(l_value);
*l_current_ptr = (OPJ_INT32)opj_int64_clamp(
l_value_int + l_tccp->m_dc_level_shift, l_min, l_max); l_value_int + l_tccp->m_dc_level_shift, l_min, l_max);
} }
++l_current_ptr; ++l_current_ptr;