ImportYUVAFromRGBA: use relative pointer offsets
avoids int rollover when working with large input
BUG=webp:312
Change-Id: I3d7b689be8d5751248a82d1021243d80d3f67203
(cherry picked from commit deb1b83199
)
This commit is contained in:
parent
c284780f0a
commit
9daad4598b
@ -830,10 +830,10 @@ static WEBP_INLINE void ConvertRowsToUV(const uint16_t* rgb,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ImportYUVAFromRGBA(const uint8_t* const r_ptr,
|
static int ImportYUVAFromRGBA(const uint8_t* r_ptr,
|
||||||
const uint8_t* const g_ptr,
|
const uint8_t* g_ptr,
|
||||||
const uint8_t* const b_ptr,
|
const uint8_t* b_ptr,
|
||||||
const uint8_t* const a_ptr,
|
const uint8_t* a_ptr,
|
||||||
int step, // bytes per pixel
|
int step, // bytes per pixel
|
||||||
int rgb_stride, // bytes per scanline
|
int rgb_stride, // bytes per scanline
|
||||||
float dithering,
|
float dithering,
|
||||||
@ -900,36 +900,34 @@ static int ImportYUVAFromRGBA(const uint8_t* const r_ptr,
|
|||||||
// Downsample Y/U/V planes, two rows at a time
|
// Downsample Y/U/V planes, two rows at a time
|
||||||
for (y = 0; y < (height >> 1); ++y) {
|
for (y = 0; y < (height >> 1); ++y) {
|
||||||
int rows_have_alpha = has_alpha;
|
int rows_have_alpha = has_alpha;
|
||||||
const int off1 = (2 * y + 0) * rgb_stride;
|
|
||||||
const int off2 = (2 * y + 1) * rgb_stride;
|
|
||||||
if (use_dsp) {
|
if (use_dsp) {
|
||||||
if (is_rgb) {
|
if (is_rgb) {
|
||||||
WebPConvertRGB24ToY(r_ptr + off1, dst_y, width);
|
WebPConvertRGB24ToY(r_ptr, dst_y, width);
|
||||||
WebPConvertRGB24ToY(r_ptr + off2, dst_y + picture->y_stride, width);
|
WebPConvertRGB24ToY(r_ptr + rgb_stride,
|
||||||
|
dst_y + picture->y_stride, width);
|
||||||
} else {
|
} else {
|
||||||
WebPConvertBGR24ToY(b_ptr + off1, dst_y, width);
|
WebPConvertBGR24ToY(b_ptr, dst_y, width);
|
||||||
WebPConvertBGR24ToY(b_ptr + off2, dst_y + picture->y_stride, width);
|
WebPConvertBGR24ToY(b_ptr + rgb_stride,
|
||||||
|
dst_y + picture->y_stride, width);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ConvertRowToY(r_ptr + off1, g_ptr + off1, b_ptr + off1, step,
|
ConvertRowToY(r_ptr, g_ptr, b_ptr, step, dst_y, width, rg);
|
||||||
dst_y, width, rg);
|
ConvertRowToY(r_ptr + rgb_stride,
|
||||||
ConvertRowToY(r_ptr + off2, g_ptr + off2, b_ptr + off2, step,
|
g_ptr + rgb_stride,
|
||||||
|
b_ptr + rgb_stride, step,
|
||||||
dst_y + picture->y_stride, width, rg);
|
dst_y + picture->y_stride, width, rg);
|
||||||
}
|
}
|
||||||
dst_y += 2 * picture->y_stride;
|
dst_y += 2 * picture->y_stride;
|
||||||
if (has_alpha) {
|
if (has_alpha) {
|
||||||
rows_have_alpha &= !WebPExtractAlpha(a_ptr + off1, rgb_stride,
|
rows_have_alpha &= !WebPExtractAlpha(a_ptr, rgb_stride, width, 2,
|
||||||
width, 2,
|
|
||||||
dst_a, picture->a_stride);
|
dst_a, picture->a_stride);
|
||||||
dst_a += 2 * picture->a_stride;
|
dst_a += 2 * picture->a_stride;
|
||||||
}
|
}
|
||||||
// Collect averaged R/G/B(/A)
|
// Collect averaged R/G/B(/A)
|
||||||
if (!rows_have_alpha) {
|
if (!rows_have_alpha) {
|
||||||
AccumulateRGB(r_ptr + off1, g_ptr + off1, b_ptr + off1,
|
AccumulateRGB(r_ptr, g_ptr, b_ptr, step, rgb_stride, tmp_rgb, width);
|
||||||
step, rgb_stride, tmp_rgb, width);
|
|
||||||
} else {
|
} else {
|
||||||
AccumulateRGBA(r_ptr + off1, g_ptr + off1, b_ptr + off1, a_ptr + off1,
|
AccumulateRGBA(r_ptr, g_ptr, b_ptr, a_ptr, rgb_stride, tmp_rgb, width);
|
||||||
rgb_stride, tmp_rgb, width);
|
|
||||||
}
|
}
|
||||||
// Convert to U/V
|
// Convert to U/V
|
||||||
if (rg == NULL) {
|
if (rg == NULL) {
|
||||||
@ -939,31 +937,33 @@ static int ImportYUVAFromRGBA(const uint8_t* const r_ptr,
|
|||||||
}
|
}
|
||||||
dst_u += picture->uv_stride;
|
dst_u += picture->uv_stride;
|
||||||
dst_v += picture->uv_stride;
|
dst_v += picture->uv_stride;
|
||||||
|
r_ptr += 2 * rgb_stride;
|
||||||
|
b_ptr += 2 * rgb_stride;
|
||||||
|
g_ptr += 2 * rgb_stride;
|
||||||
|
if (has_alpha) a_ptr += 2 * rgb_stride;
|
||||||
}
|
}
|
||||||
if (height & 1) { // extra last row
|
if (height & 1) { // extra last row
|
||||||
const int off = 2 * y * rgb_stride;
|
|
||||||
int row_has_alpha = has_alpha;
|
int row_has_alpha = has_alpha;
|
||||||
if (use_dsp) {
|
if (use_dsp) {
|
||||||
if (r_ptr < b_ptr) {
|
if (r_ptr < b_ptr) {
|
||||||
WebPConvertRGB24ToY(r_ptr + off, dst_y, width);
|
WebPConvertRGB24ToY(r_ptr, dst_y, width);
|
||||||
} else {
|
} else {
|
||||||
WebPConvertBGR24ToY(b_ptr + off, dst_y, width);
|
WebPConvertBGR24ToY(b_ptr, dst_y, width);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ConvertRowToY(r_ptr + off, g_ptr + off, b_ptr + off, step,
|
ConvertRowToY(r_ptr, g_ptr, b_ptr, step, dst_y, width, rg);
|
||||||
dst_y, width, rg);
|
|
||||||
}
|
}
|
||||||
if (row_has_alpha) {
|
if (row_has_alpha) {
|
||||||
row_has_alpha &= !WebPExtractAlpha(a_ptr + off, 0, width, 1, dst_a, 0);
|
row_has_alpha &= !WebPExtractAlpha(a_ptr, 0, width, 1, dst_a, 0);
|
||||||
}
|
}
|
||||||
// Collect averaged R/G/B(/A)
|
// Collect averaged R/G/B(/A)
|
||||||
if (!row_has_alpha) {
|
if (!row_has_alpha) {
|
||||||
// Collect averaged R/G/B
|
// Collect averaged R/G/B
|
||||||
AccumulateRGB(r_ptr + off, g_ptr + off, b_ptr + off,
|
AccumulateRGB(r_ptr, g_ptr, b_ptr, step, /* rgb_stride = */ 0,
|
||||||
step, /* rgb_stride = */ 0, tmp_rgb, width);
|
tmp_rgb, width);
|
||||||
} else {
|
} else {
|
||||||
AccumulateRGBA(r_ptr + off, g_ptr + off, b_ptr + off, a_ptr + off,
|
AccumulateRGBA(r_ptr, g_ptr, b_ptr, a_ptr, /* rgb_stride = */ 0,
|
||||||
/* rgb_stride = */ 0, tmp_rgb, width);
|
tmp_rgb, width);
|
||||||
}
|
}
|
||||||
if (rg == NULL) {
|
if (rg == NULL) {
|
||||||
WebPConvertRGBA32ToUV(tmp_rgb, dst_u, dst_v, uv_width);
|
WebPConvertRGBA32ToUV(tmp_rgb, dst_u, dst_v, uv_width);
|
||||||
|
Loading…
Reference in New Issue
Block a user