mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-27 06:08:21 +01:00
Fix integer overflow in EmitFancyRGB.
+ enhance the assert in WebPCopyPlane() Change-Id: Id9b01d00a8dce6caf0d4721a6fbe8def40b8bb85
This commit is contained in:
parent
b3ff0bdec1
commit
e3c259a278
@ -25,21 +25,16 @@
|
|||||||
static int EmitYUV(const VP8Io* const io, WebPDecParams* const p) {
|
static int EmitYUV(const VP8Io* const io, WebPDecParams* const p) {
|
||||||
WebPDecBuffer* output = p->output;
|
WebPDecBuffer* output = p->output;
|
||||||
const WebPYUVABuffer* const buf = &output->u.YUVA;
|
const WebPYUVABuffer* const buf = &output->u.YUVA;
|
||||||
uint8_t* const y_dst = buf->y + io->mb_y * buf->y_stride;
|
uint8_t* const y_dst = buf->y + (size_t)io->mb_y * buf->y_stride;
|
||||||
uint8_t* const u_dst = buf->u + (io->mb_y >> 1) * buf->u_stride;
|
uint8_t* const u_dst = buf->u + (size_t)(io->mb_y >> 1) * buf->u_stride;
|
||||||
uint8_t* const v_dst = buf->v + (io->mb_y >> 1) * buf->v_stride;
|
uint8_t* const v_dst = buf->v + (size_t)(io->mb_y >> 1) * buf->v_stride;
|
||||||
const int mb_w = io->mb_w;
|
const int mb_w = io->mb_w;
|
||||||
const int mb_h = io->mb_h;
|
const int mb_h = io->mb_h;
|
||||||
const int uv_w = (mb_w + 1) / 2;
|
const int uv_w = (mb_w + 1) / 2;
|
||||||
const int uv_h = (mb_h + 1) / 2;
|
const int uv_h = (mb_h + 1) / 2;
|
||||||
int j;
|
WebPCopyPlane(io->y, io->y_stride, y_dst, buf->y_stride, mb_w, mb_h);
|
||||||
for (j = 0; j < mb_h; ++j) {
|
WebPCopyPlane(io->u, io->uv_stride, u_dst, buf->u_stride, uv_w, uv_h);
|
||||||
memcpy(y_dst + j * buf->y_stride, io->y + j * io->y_stride, mb_w);
|
WebPCopyPlane(io->v, io->uv_stride, v_dst, buf->v_stride, uv_w, uv_h);
|
||||||
}
|
|
||||||
for (j = 0; j < uv_h; ++j) {
|
|
||||||
memcpy(u_dst + j * buf->u_stride, io->u + j * io->uv_stride, uv_w);
|
|
||||||
memcpy(v_dst + j * buf->v_stride, io->v + j * io->uv_stride, uv_w);
|
|
||||||
}
|
|
||||||
return io->mb_h;
|
return io->mb_h;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,7 +42,7 @@ static int EmitYUV(const VP8Io* const io, WebPDecParams* const p) {
|
|||||||
static int EmitSampledRGB(const VP8Io* const io, WebPDecParams* const p) {
|
static int EmitSampledRGB(const VP8Io* const io, WebPDecParams* const p) {
|
||||||
WebPDecBuffer* const output = p->output;
|
WebPDecBuffer* const output = p->output;
|
||||||
WebPRGBABuffer* const buf = &output->u.RGBA;
|
WebPRGBABuffer* const buf = &output->u.RGBA;
|
||||||
uint8_t* const dst = buf->rgba + io->mb_y * buf->stride;
|
uint8_t* const dst = buf->rgba + (size_t)io->mb_y * buf->stride;
|
||||||
WebPSamplerProcessPlane(io->y, io->y_stride,
|
WebPSamplerProcessPlane(io->y, io->y_stride,
|
||||||
io->u, io->v, io->uv_stride,
|
io->u, io->v, io->uv_stride,
|
||||||
dst, buf->stride, io->mb_w, io->mb_h,
|
dst, buf->stride, io->mb_w, io->mb_h,
|
||||||
@ -62,7 +57,7 @@ static int EmitSampledRGB(const VP8Io* const io, WebPDecParams* const p) {
|
|||||||
static int EmitFancyRGB(const VP8Io* const io, WebPDecParams* const p) {
|
static int EmitFancyRGB(const VP8Io* const io, WebPDecParams* const p) {
|
||||||
int num_lines_out = io->mb_h; // a priori guess
|
int num_lines_out = io->mb_h; // a priori guess
|
||||||
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
||||||
uint8_t* dst = buf->rgba + io->mb_y * buf->stride;
|
uint8_t* dst = buf->rgba + (size_t)io->mb_y * buf->stride;
|
||||||
WebPUpsampleLinePairFunc upsample = WebPUpsamplers[p->output->colorspace];
|
WebPUpsampleLinePairFunc upsample = WebPUpsamplers[p->output->colorspace];
|
||||||
const uint8_t* cur_y = io->y;
|
const uint8_t* cur_y = io->y;
|
||||||
const uint8_t* cur_u = io->u;
|
const uint8_t* cur_u = io->u;
|
||||||
@ -133,7 +128,7 @@ static int EmitAlphaYUV(const VP8Io* const io, WebPDecParams* const p,
|
|||||||
const WebPYUVABuffer* const buf = &p->output->u.YUVA;
|
const WebPYUVABuffer* const buf = &p->output->u.YUVA;
|
||||||
const int mb_w = io->mb_w;
|
const int mb_w = io->mb_w;
|
||||||
const int mb_h = io->mb_h;
|
const int mb_h = io->mb_h;
|
||||||
uint8_t* dst = buf->a + io->mb_y * buf->a_stride;
|
uint8_t* dst = buf->a + (size_t)io->mb_y * buf->a_stride;
|
||||||
int j;
|
int j;
|
||||||
(void)expected_num_lines_out;
|
(void)expected_num_lines_out;
|
||||||
assert(expected_num_lines_out == mb_h);
|
assert(expected_num_lines_out == mb_h);
|
||||||
@ -186,7 +181,7 @@ static int EmitAlphaRGB(const VP8Io* const io, WebPDecParams* const p,
|
|||||||
(colorspace == MODE_ARGB || colorspace == MODE_Argb);
|
(colorspace == MODE_ARGB || colorspace == MODE_Argb);
|
||||||
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
||||||
int num_rows;
|
int num_rows;
|
||||||
const int start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
|
const size_t start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
|
||||||
uint8_t* const base_rgba = buf->rgba + start_y * buf->stride;
|
uint8_t* const base_rgba = buf->rgba + start_y * buf->stride;
|
||||||
uint8_t* const dst = base_rgba + (alpha_first ? 0 : 3);
|
uint8_t* const dst = base_rgba + (alpha_first ? 0 : 3);
|
||||||
const int has_alpha = WebPDispatchAlpha(alpha, io->width, mb_w,
|
const int has_alpha = WebPDispatchAlpha(alpha, io->width, mb_w,
|
||||||
@ -210,7 +205,7 @@ static int EmitAlphaRGBA4444(const VP8Io* const io, WebPDecParams* const p,
|
|||||||
const WEBP_CSP_MODE colorspace = p->output->colorspace;
|
const WEBP_CSP_MODE colorspace = p->output->colorspace;
|
||||||
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
||||||
int num_rows;
|
int num_rows;
|
||||||
const int start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
|
const size_t start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
|
||||||
uint8_t* const base_rgba = buf->rgba + start_y * buf->stride;
|
uint8_t* const base_rgba = buf->rgba + start_y * buf->stride;
|
||||||
#if (WEBP_SWAP_16BIT_CSP == 1)
|
#if (WEBP_SWAP_16BIT_CSP == 1)
|
||||||
uint8_t* alpha_dst = base_rgba;
|
uint8_t* alpha_dst = base_rgba;
|
||||||
@ -276,9 +271,9 @@ static int EmitRescaledYUV(const VP8Io* const io, WebPDecParams* const p) {
|
|||||||
static int EmitRescaledAlphaYUV(const VP8Io* const io, WebPDecParams* const p,
|
static int EmitRescaledAlphaYUV(const VP8Io* const io, WebPDecParams* const p,
|
||||||
int expected_num_lines_out) {
|
int expected_num_lines_out) {
|
||||||
const WebPYUVABuffer* const buf = &p->output->u.YUVA;
|
const WebPYUVABuffer* const buf = &p->output->u.YUVA;
|
||||||
uint8_t* const dst_a = buf->a + p->last_y * buf->a_stride;
|
uint8_t* const dst_a = buf->a + (size_t)p->last_y * buf->a_stride;
|
||||||
if (io->a != NULL) {
|
if (io->a != NULL) {
|
||||||
uint8_t* const dst_y = buf->y + p->last_y * buf->y_stride;
|
uint8_t* const dst_y = buf->y + (size_t)p->last_y * buf->y_stride;
|
||||||
const int num_lines_out = Rescale(io->a, io->width, io->mb_h, p->scaler_a);
|
const int num_lines_out = Rescale(io->a, io->width, io->mb_h, p->scaler_a);
|
||||||
assert(expected_num_lines_out == num_lines_out);
|
assert(expected_num_lines_out == num_lines_out);
|
||||||
if (num_lines_out > 0) { // unmultiply the Y
|
if (num_lines_out > 0) { // unmultiply the Y
|
||||||
@ -356,7 +351,7 @@ static int ExportRGB(WebPDecParams* const p, int y_pos) {
|
|||||||
const WebPYUV444Converter convert =
|
const WebPYUV444Converter convert =
|
||||||
WebPYUV444Converters[p->output->colorspace];
|
WebPYUV444Converters[p->output->colorspace];
|
||||||
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
||||||
uint8_t* dst = buf->rgba + y_pos * buf->stride;
|
uint8_t* dst = buf->rgba + (size_t)y_pos * buf->stride;
|
||||||
int num_lines_out = 0;
|
int num_lines_out = 0;
|
||||||
// For RGB rescaling, because of the YUV420, current scan position
|
// For RGB rescaling, because of the YUV420, current scan position
|
||||||
// U/V can be +1/-1 line from the Y one. Hence the double test.
|
// U/V can be +1/-1 line from the Y one. Hence the double test.
|
||||||
@ -383,15 +378,15 @@ static int EmitRescaledRGB(const VP8Io* const io, WebPDecParams* const p) {
|
|||||||
while (j < mb_h) {
|
while (j < mb_h) {
|
||||||
const int y_lines_in =
|
const int y_lines_in =
|
||||||
WebPRescalerImport(p->scaler_y, mb_h - j,
|
WebPRescalerImport(p->scaler_y, mb_h - j,
|
||||||
io->y + j * io->y_stride, io->y_stride);
|
io->y + (size_t)j * io->y_stride, io->y_stride);
|
||||||
j += y_lines_in;
|
j += y_lines_in;
|
||||||
if (WebPRescaleNeededLines(p->scaler_u, uv_mb_h - uv_j)) {
|
if (WebPRescaleNeededLines(p->scaler_u, uv_mb_h - uv_j)) {
|
||||||
const int u_lines_in =
|
const int u_lines_in = WebPRescalerImport(
|
||||||
WebPRescalerImport(p->scaler_u, uv_mb_h - uv_j,
|
p->scaler_u, uv_mb_h - uv_j, io->u + (size_t)uv_j * io->uv_stride,
|
||||||
io->u + uv_j * io->uv_stride, io->uv_stride);
|
io->uv_stride);
|
||||||
const int v_lines_in =
|
const int v_lines_in = WebPRescalerImport(
|
||||||
WebPRescalerImport(p->scaler_v, uv_mb_h - uv_j,
|
p->scaler_v, uv_mb_h - uv_j, io->v + (size_t)uv_j * io->uv_stride,
|
||||||
io->v + uv_j * io->uv_stride, io->uv_stride);
|
io->uv_stride);
|
||||||
(void)v_lines_in; // remove a gcc warning
|
(void)v_lines_in; // remove a gcc warning
|
||||||
assert(u_lines_in == v_lines_in);
|
assert(u_lines_in == v_lines_in);
|
||||||
uv_j += u_lines_in;
|
uv_j += u_lines_in;
|
||||||
@ -403,7 +398,7 @@ static int EmitRescaledRGB(const VP8Io* const io, WebPDecParams* const p) {
|
|||||||
|
|
||||||
static int ExportAlpha(WebPDecParams* const p, int y_pos, int max_lines_out) {
|
static int ExportAlpha(WebPDecParams* const p, int y_pos, int max_lines_out) {
|
||||||
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
||||||
uint8_t* const base_rgba = buf->rgba + y_pos * buf->stride;
|
uint8_t* const base_rgba = buf->rgba + (size_t)y_pos * buf->stride;
|
||||||
const WEBP_CSP_MODE colorspace = p->output->colorspace;
|
const WEBP_CSP_MODE colorspace = p->output->colorspace;
|
||||||
const int alpha_first =
|
const int alpha_first =
|
||||||
(colorspace == MODE_ARGB || colorspace == MODE_Argb);
|
(colorspace == MODE_ARGB || colorspace == MODE_Argb);
|
||||||
@ -431,7 +426,7 @@ static int ExportAlpha(WebPDecParams* const p, int y_pos, int max_lines_out) {
|
|||||||
static int ExportAlphaRGBA4444(WebPDecParams* const p, int y_pos,
|
static int ExportAlphaRGBA4444(WebPDecParams* const p, int y_pos,
|
||||||
int max_lines_out) {
|
int max_lines_out) {
|
||||||
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
||||||
uint8_t* const base_rgba = buf->rgba + y_pos * buf->stride;
|
uint8_t* const base_rgba = buf->rgba + (size_t)y_pos * buf->stride;
|
||||||
#if (WEBP_SWAP_16BIT_CSP == 1)
|
#if (WEBP_SWAP_16BIT_CSP == 1)
|
||||||
uint8_t* alpha_dst = base_rgba;
|
uint8_t* alpha_dst = base_rgba;
|
||||||
#else
|
#else
|
||||||
@ -470,7 +465,7 @@ static int EmitRescaledAlphaRGB(const VP8Io* const io, WebPDecParams* const p,
|
|||||||
int lines_left = expected_num_out_lines;
|
int lines_left = expected_num_out_lines;
|
||||||
const int y_end = p->last_y + lines_left;
|
const int y_end = p->last_y + lines_left;
|
||||||
while (lines_left > 0) {
|
while (lines_left > 0) {
|
||||||
const int row_offset = scaler->src_y - io->mb_y;
|
const size_t row_offset = scaler->src_y - io->mb_y;
|
||||||
WebPRescalerImport(scaler, io->mb_h + io->mb_y - scaler->src_y,
|
WebPRescalerImport(scaler, io->mb_h + io->mb_y - scaler->src_y,
|
||||||
io->a + row_offset * io->width, io->width);
|
io->a + row_offset * io->width, io->width);
|
||||||
lines_left -= p->emit_alpha_row(p, y_end - lines_left, lines_left);
|
lines_left -= p->emit_alpha_row(p, y_end - lines_left, lines_left);
|
||||||
|
@ -231,7 +231,7 @@ void WebPFree(void* ptr) {
|
|||||||
void WebPCopyPlane(const uint8_t* src, int src_stride,
|
void WebPCopyPlane(const uint8_t* src, int src_stride,
|
||||||
uint8_t* dst, int dst_stride, int width, int height) {
|
uint8_t* dst, int dst_stride, int width, int height) {
|
||||||
assert(src != NULL && dst != NULL);
|
assert(src != NULL && dst != NULL);
|
||||||
assert(src_stride >= width && dst_stride >= width);
|
assert(abs(src_stride) >= width && abs(dst_stride) >= width);
|
||||||
while (height-- > 0) {
|
while (height-- > 0) {
|
||||||
memcpy(dst, src, width);
|
memcpy(dst, src, width);
|
||||||
src += src_stride;
|
src += src_stride;
|
||||||
|
Loading…
Reference in New Issue
Block a user