diff --git a/libavcodec/exr.c b/libavcodec/exr.c index 363562e6b9..ac6b598777 100644 --- a/libavcodec/exr.c +++ b/libavcodec/exr.c @@ -103,6 +103,8 @@ typedef struct EXRThreadData { uint8_t *bitmap; uint16_t *lut; + + int ysize, xsize; } EXRThreadData; typedef struct EXRContext { @@ -119,7 +121,6 @@ typedef struct EXRContext { uint32_t xmax, xmin; uint32_t ymax, ymin; uint32_t xdelta, ydelta; - int ysize, xsize; uint64_t scan_line_size; int scan_lines_per_block; @@ -783,19 +784,19 @@ static int piz_uncompress(EXRContext *s, const uint8_t *src, int ssize, int size = channel->pixel_type; for (j = 0; j < size; j++) - wav_decode(ptr + j, s->xsize, size, s->ysize, - s->xsize * size, maxval); - ptr += s->xsize * s->ysize * size; + wav_decode(ptr + j, td->xsize, size, td->ysize, + td->xsize * size, maxval); + ptr += td->xsize * td->ysize * size; } apply_lut(td->lut, tmp, dsize / sizeof(uint16_t)); out = td->uncompressed_data; - for (i = 0; i < s->ysize; i++) + for (i = 0; i < td->ysize; i++) for (j = 0; j < s->nb_channels; j++) { - uint16_t *in = tmp + j * s->xsize * s->ysize + i * s->xsize; - memcpy(out, in, s->xsize * 2); - out += s->xsize * 2; + uint16_t *in = tmp + j * td->xsize * td->ysize + i * td->xsize; + memcpy(out, in, td->xsize * 2); + out += td->xsize * 2; } return 0; @@ -824,7 +825,7 @@ static int pxr24_uncompress(EXRContext *s, const uint8_t *src, } out = td->uncompressed_data; - for (i = 0; i < s->ysize; i++) + for (i = 0; i < td->ysize; i++) for (c = 0; c < s->nb_channels; c++) { EXRChannel *channel = &s->channels[c]; const uint8_t *ptr[4]; @@ -833,11 +834,11 @@ static int pxr24_uncompress(EXRContext *s, const uint8_t *src, switch (channel->pixel_type) { case EXR_FLOAT: ptr[0] = in; - ptr[1] = ptr[0] + s->xsize; - ptr[2] = ptr[1] + s->xsize; - in = ptr[2] + s->xsize; + ptr[1] = ptr[0] + td->xsize; + ptr[2] = ptr[1] + td->xsize; + in = ptr[2] + td->xsize; - for (j = 0; j < s->xsize; ++j) { + for (j = 0; j < td->xsize; ++j) { uint32_t diff = (*(ptr[0]++) << 24) | (*(ptr[1]++) << 16) | (*(ptr[2]++) << 8); @@ -847,9 +848,9 @@ static int pxr24_uncompress(EXRContext *s, const uint8_t *src, break; case EXR_HALF: ptr[0] = in; - ptr[1] = ptr[0] + s->xsize; - in = ptr[1] + s->xsize; - for (j = 0; j < s->xsize; j++) { + ptr[1] = ptr[0] + td->xsize; + in = ptr[1] + td->xsize; + for (j = 0; j < td->xsize; j++) { uint32_t diff = (*(ptr[0]++) << 8) | *(ptr[1]++); pixel += diff; @@ -925,12 +926,12 @@ static int b44_uncompress(EXRContext *s, const uint8_t *src, int compressed_size int c, iY, iX, y, x; /* calc B44 block count */ - nbB44BlockW = s->xsize / 4; - if ((s->xsize % 4) != 0) + nbB44BlockW = td->xsize / 4; + if ((td->xsize % 4) != 0) nbB44BlockW++; - nbB44BlockH = s->ysize / 4; - if ((s->ysize % 4) != 0) + nbB44BlockH = td->ysize / 4; + if ((td->ysize % 4) != 0) nbB44BlockH++; for (c = 0; c < s->nb_channels; c++) { @@ -959,9 +960,9 @@ static int b44_uncompress(EXRContext *s, const uint8_t *src, int compressed_size indexHgX = iX * 4; indexHgY = iY * 4; - for (y = indexHgY; y < FFMIN(indexHgY + 4, s->ysize); y++) { - for (x = indexHgX; x < FFMIN(indexHgX + 4, s->xsize); x++) { - indexOut = (c * s->xsize + y * s->xsize * s->nb_channels + x) * 2; + for (y = indexHgY; y < FFMIN(indexHgY + 4, td->ysize); y++) { + for (x = indexHgX; x < FFMIN(indexHgX + 4, td->xsize); x++) { + indexOut = (c * td->xsize + y * td->xsize * s->nb_channels + x) * 2; indexTmp = (y-indexHgY) * 4 + (x-indexHgX); td->uncompressed_data[indexOut] = tmpBuffer[indexTmp] & 0xff; td->uncompressed_data[indexOut + 1] = tmpBuffer[indexTmp] >> 8; @@ -1022,15 +1023,15 @@ static int decode_block(AVCodecContext *avctx, void *tdata, line = s->tile_attr.ySize * tileY; col = s->tile_attr.xSize * tileX; - s->ysize = FFMIN(s->tile_attr.ySize, s->ydelta - tileY * s->tile_attr.ySize); - s->xsize = FFMIN(s->tile_attr.xSize, s->xdelta - tileX * s->tile_attr.xSize); - uncompressed_size = s->current_channel_offset * s->ysize * s->xsize; + td->ysize = FFMIN(s->tile_attr.ySize, s->ydelta - tileY * s->tile_attr.ySize); + td->xsize = FFMIN(s->tile_attr.xSize, s->xdelta - tileX * s->tile_attr.xSize); + uncompressed_size = s->current_channel_offset * td->ysize * td->xsize; if (col) { /* not the first tile of the line */ bxmin = 0; axmax = 0; /* doesn't add pixel at the left of the datawindow */ } - if ((col + s->xsize) != s->xdelta)/* not the last tile of the line */ + if ((col + td->xsize) != s->xdelta)/* not the last tile of the line */ axmax = 0; /* doesn't add pixel at the right of the datawindow */ } else { if (line_offset > buf_size - 8) @@ -1038,6 +1039,7 @@ static int decode_block(AVCodecContext *avctx, void *tdata, src = buf + line_offset + 8; line = AV_RL32(src - 8); + if (line < s->ymin || line > s->ymax) return AVERROR_INVALIDDATA; @@ -1045,9 +1047,9 @@ static int decode_block(AVCodecContext *avctx, void *tdata, if (data_size <= 0 || data_size > buf_size) return AVERROR_INVALIDDATA; - s->ysize = FFMIN(s->scan_lines_per_block, s->ymax - line + 1); /* s->ydelta - line ?? */ - s->xsize = s->xdelta; - uncompressed_size = s->scan_line_size * s->ysize; + td->ysize = FFMIN(s->scan_lines_per_block, s->ymax - line + 1); /* s->ydelta - line ?? */ + td->xsize = s->xdelta; + uncompressed_size = s->scan_line_size * td->ysize; if ((s->compression == EXR_RAW && (data_size != uncompressed_size || line_offset > buf_size - uncompressed_size)) || (s->compression != EXR_RAW && (data_size > uncompressed_size || @@ -1098,25 +1100,25 @@ static int decode_block(AVCodecContext *avctx, void *tdata, if (s->is_tile) { indexSrc = 0; - channelLineSize = s->xsize * 2; + channelLineSize = td->xsize * 2; if (s->pixel_type == EXR_FLOAT) channelLineSize *= 2; /* reorganise tile data to have each channel one after the other instead of line by line */ - for (tY = 0; tY < s->ysize; tY ++) { + for (tY = 0; tY < td->ysize; tY ++) { for (tCh = 0; tCh < s->nb_channels; tCh++) { for (tX = 0; tX < channelLineSize; tX++) { - td->tmp[tCh * channelLineSize * s->ysize + tY * channelLineSize + tX] = src[indexSrc]; + td->tmp[tCh * channelLineSize * td->ysize + tY * channelLineSize + tX] = src[indexSrc]; indexSrc++; } } } - channel_buffer[0] = td->tmp + s->xsize * s->channel_offsets[0] * s->ysize; - channel_buffer[1] = td->tmp + s->xsize * s->channel_offsets[1] * s->ysize; - channel_buffer[2] = td->tmp + s->xsize * s->channel_offsets[2] * s->ysize; + channel_buffer[0] = td->tmp + td->xsize * s->channel_offsets[0] * td->ysize; + channel_buffer[1] = td->tmp + td->xsize * s->channel_offsets[1] * td->ysize; + channel_buffer[2] = td->tmp + td->xsize * s->channel_offsets[2] * td->ysize; if (s->channel_offsets[3] >= 0) - channel_buffer[3] = td->tmp + s->xsize * s->channel_offsets[3]; + channel_buffer[3] = td->tmp + td->xsize * s->channel_offsets[3]; } else { channel_buffer[0] = src + xdelta * s->channel_offsets[0]; channel_buffer[1] = src + xdelta * s->channel_offsets[1]; @@ -1128,7 +1130,7 @@ static int decode_block(AVCodecContext *avctx, void *tdata, ptr = p->data[0] + line * p->linesize[0] + (col * s->desc->nb_components * 2); for (i = 0; - i < s->ysize; i++, ptr += p->linesize[0]) { + i < td->ysize; i++, ptr += p->linesize[0]) { const uint8_t *r, *g, *b, *a; @@ -1147,7 +1149,7 @@ static int decode_block(AVCodecContext *avctx, void *tdata, if (s->pixel_type == EXR_FLOAT) { // 32-bit if (trc_func) { - for (x = 0; x < s->xsize; x++) { + for (x = 0; x < td->xsize; x++) { union av_intfloat32 t; t.i = bytestream_get_le32(&r); t.f = trc_func(t.f); @@ -1164,7 +1166,7 @@ static int decode_block(AVCodecContext *avctx, void *tdata, *ptr_x++ = exr_flt2uint(bytestream_get_le32(&a)); } } else { - for (x = 0; x < s->xsize; x++) { + for (x = 0; x < td->xsize; x++) { union av_intfloat32 t; t.i = bytestream_get_le32(&r); if (t.f > 0.0f) /* avoid negative values */ @@ -1186,7 +1188,7 @@ static int decode_block(AVCodecContext *avctx, void *tdata, } } else { // 16-bit - for (x = 0; x < s->xsize; x++) { + for (x = 0; x < td->xsize; x++) { *ptr_x++ = s->gamma_table[bytestream_get_le16(&r)]; *ptr_x++ = s->gamma_table[bytestream_get_le16(&g)]; *ptr_x++ = s->gamma_table[bytestream_get_le16(&b)];