fix overflow in large image transformations
This commit is contained in:
@@ -13,6 +13,7 @@
|
|||||||
- Fix setting local style property multiple times
|
- Fix setting local style property multiple times
|
||||||
- Add missing background drawing and radius handling to image button
|
- Add missing background drawing and radius handling to image button
|
||||||
- Allow adding extra label to list buttons
|
- Allow adding extra label to list buttons
|
||||||
|
- Fix overflow in large image transformations
|
||||||
|
|
||||||
## v7.3.0 (04.08.2020)
|
## v7.3.0 (04.08.2020)
|
||||||
|
|
||||||
|
|||||||
@@ -435,6 +435,10 @@ void _lv_img_buf_transform_init(lv_img_transform_dsc_t * dsc)
|
|||||||
dsc->tmp.sinma = (s1 * (10 - angle_rem) + s2 * angle_rem) / 10;
|
dsc->tmp.sinma = (s1 * (10 - angle_rem) + s2 * angle_rem) / 10;
|
||||||
dsc->tmp.cosma = (c1 * (10 - angle_rem) + c2 * angle_rem) / 10;
|
dsc->tmp.cosma = (c1 * (10 - angle_rem) + c2 * angle_rem) / 10;
|
||||||
|
|
||||||
|
/*Use smaller value to avoid overflow*/
|
||||||
|
dsc->tmp.sinma = dsc->tmp.sinma >> (LV_TRIGO_SHIFT - _LV_TRANSFORM_TRIGO_SHIFT);
|
||||||
|
dsc->tmp.cosma = dsc->tmp.cosma >> (LV_TRIGO_SHIFT - _LV_TRANSFORM_TRIGO_SHIFT);
|
||||||
|
|
||||||
dsc->tmp.chroma_keyed = lv_img_cf_is_chroma_keyed(dsc->cfg.cf) ? 1 : 0;
|
dsc->tmp.chroma_keyed = lv_img_cf_is_chroma_keyed(dsc->cfg.cf) ? 1 : 0;
|
||||||
dsc->tmp.has_alpha = lv_img_cf_has_alpha(dsc->cfg.cf) ? 1 : 0;
|
dsc->tmp.has_alpha = lv_img_cf_has_alpha(dsc->cfg.cf) ? 1 : 0;
|
||||||
if(dsc->cfg.cf == LV_IMG_CF_TRUE_COLOR || dsc->cfg.cf == LV_IMG_CF_TRUE_COLOR_ALPHA ||
|
if(dsc->cfg.cf == LV_IMG_CF_TRUE_COLOR || dsc->cfg.cf == LV_IMG_CF_TRUE_COLOR_ALPHA ||
|
||||||
@@ -493,6 +497,10 @@ void _lv_img_buf_get_transformed_area(lv_area_t * res, lv_coord_t w, lv_coord_t
|
|||||||
int32_t sinma = (s1 * (10 - angle_rem) + s2 * angle_rem) / 10;
|
int32_t sinma = (s1 * (10 - angle_rem) + s2 * angle_rem) / 10;
|
||||||
int32_t cosma = (c1 * (10 - angle_rem) + c2 * angle_rem) / 10;
|
int32_t cosma = (c1 * (10 - angle_rem) + c2 * angle_rem) / 10;
|
||||||
|
|
||||||
|
/*Use smaller value to avoid overflow*/
|
||||||
|
sinma = sinma >> (LV_TRIGO_SHIFT - _LV_TRANSFORM_TRIGO_SHIFT);
|
||||||
|
cosma = cosma >> (LV_TRIGO_SHIFT - _LV_TRANSFORM_TRIGO_SHIFT);
|
||||||
|
|
||||||
lv_point_t lt;
|
lv_point_t lt;
|
||||||
lv_point_t rt;
|
lv_point_t rt;
|
||||||
lv_point_t lb;
|
lv_point_t lb;
|
||||||
@@ -509,23 +517,23 @@ void _lv_img_buf_get_transformed_area(lv_area_t * res, lv_coord_t w, lv_coord_t
|
|||||||
|
|
||||||
xt = a.x1;
|
xt = a.x1;
|
||||||
yt = a.y1;
|
yt = a.y1;
|
||||||
lt.x = ((cosma * xt - sinma * yt) >> LV_TRIGO_SHIFT) + pivot->x;
|
lt.x = ((cosma * xt - sinma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->x;
|
||||||
lt.y = ((sinma * xt + cosma * yt) >> LV_TRIGO_SHIFT) + pivot->y;
|
lt.y = ((sinma * xt + cosma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->y;
|
||||||
|
|
||||||
xt = a.x2;
|
xt = a.x2;
|
||||||
yt = a.y1;
|
yt = a.y1;
|
||||||
rt.x = ((cosma * xt - sinma * yt) >> LV_TRIGO_SHIFT) + pivot->x;
|
rt.x = ((cosma * xt - sinma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->x;
|
||||||
rt.y = ((sinma * xt + cosma * yt) >> LV_TRIGO_SHIFT) + pivot->y;
|
rt.y = ((sinma * xt + cosma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->y;
|
||||||
|
|
||||||
xt = a.x1;
|
xt = a.x1;
|
||||||
yt = a.y2;
|
yt = a.y2;
|
||||||
lb.x = ((cosma * xt - sinma * yt) >> LV_TRIGO_SHIFT) + pivot->x;
|
lb.x = ((cosma * xt - sinma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->x;
|
||||||
lb.y = ((sinma * xt + cosma * yt) >> LV_TRIGO_SHIFT) + pivot->y;
|
lb.y = ((sinma * xt + cosma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->y;
|
||||||
|
|
||||||
xt = a.x2;
|
xt = a.x2;
|
||||||
yt = a.y2;
|
yt = a.y2;
|
||||||
rb.x = ((cosma * xt - sinma * yt) >> LV_TRIGO_SHIFT) + pivot->x;
|
rb.x = ((cosma * xt - sinma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->x;
|
||||||
rb.y = ((sinma * xt + cosma * yt) >> LV_TRIGO_SHIFT) + pivot->y;
|
rb.y = ((sinma * xt + cosma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->y;
|
||||||
|
|
||||||
res->x1 = LV_MATH_MIN4(lb.x, lt.x, rb.x, rt.x);
|
res->x1 = LV_MATH_MIN4(lb.x, lt.x, rb.x, rt.x);
|
||||||
res->x2 = LV_MATH_MAX4(lb.x, lt.x, rb.x, rt.x);
|
res->x2 = LV_MATH_MAX4(lb.x, lt.x, rb.x, rt.x);
|
||||||
|
|||||||
@@ -48,6 +48,8 @@ extern "C" {
|
|||||||
|
|
||||||
#define LV_IMG_ZOOM_NONE 256
|
#define LV_IMG_ZOOM_NONE 256
|
||||||
|
|
||||||
|
#define _LV_TRANSFORM_TRIGO_SHIFT 10
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
**********************/
|
**********************/
|
||||||
@@ -301,8 +303,8 @@ static inline bool _lv_img_buf_transform(lv_img_transform_dsc_t * dsc, lv_coord_
|
|||||||
int32_t ys;
|
int32_t ys;
|
||||||
if(dsc->cfg.zoom == LV_IMG_ZOOM_NONE) {
|
if(dsc->cfg.zoom == LV_IMG_ZOOM_NONE) {
|
||||||
/*Get the source pixel from the upscaled image*/
|
/*Get the source pixel from the upscaled image*/
|
||||||
xs = ((dsc->tmp.cosma * xt - dsc->tmp.sinma * yt) >> (LV_TRIGO_SHIFT - 8)) + dsc->tmp.pivot_x_256;
|
xs = ((dsc->tmp.cosma * xt - dsc->tmp.sinma * yt) >> (_LV_TRANSFORM_TRIGO_SHIFT - 8)) + dsc->tmp.pivot_x_256;
|
||||||
ys = ((dsc->tmp.sinma * xt + dsc->tmp.cosma * yt) >> (LV_TRIGO_SHIFT - 8)) + dsc->tmp.pivot_y_256;
|
ys = ((dsc->tmp.sinma * xt + dsc->tmp.cosma * yt) >> (_LV_TRANSFORM_TRIGO_SHIFT - 8)) + dsc->tmp.pivot_y_256;
|
||||||
}
|
}
|
||||||
else if(dsc->cfg.angle == 0) {
|
else if(dsc->cfg.angle == 0) {
|
||||||
xt *= dsc->tmp.zoom_inv;
|
xt *= dsc->tmp.zoom_inv;
|
||||||
@@ -313,8 +315,8 @@ static inline bool _lv_img_buf_transform(lv_img_transform_dsc_t * dsc, lv_coord_
|
|||||||
else {
|
else {
|
||||||
xt *= dsc->tmp.zoom_inv;
|
xt *= dsc->tmp.zoom_inv;
|
||||||
yt *= dsc->tmp.zoom_inv;
|
yt *= dsc->tmp.zoom_inv;
|
||||||
xs = ((dsc->tmp.cosma * xt - dsc->tmp.sinma * yt) >> (LV_TRIGO_SHIFT)) + dsc->tmp.pivot_x_256;
|
xs = ((dsc->tmp.cosma * xt - dsc->tmp.sinma * yt) >> (_LV_TRANSFORM_TRIGO_SHIFT)) + dsc->tmp.pivot_x_256;
|
||||||
ys = ((dsc->tmp.sinma * xt + dsc->tmp.cosma * yt) >> (LV_TRIGO_SHIFT)) + dsc->tmp.pivot_y_256;
|
ys = ((dsc->tmp.sinma * xt + dsc->tmp.cosma * yt) >> (_LV_TRANSFORM_TRIGO_SHIFT)) + dsc->tmp.pivot_y_256;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Get the integer part of the source pixel*/
|
/*Get the integer part of the source pixel*/
|
||||||
|
|||||||
Reference in New Issue
Block a user