LUT8(4), LUT8(5), LUT8(6), LUT8(7),
};
-#define LUT32(plane) { \
- 0, 0, 0, 0, \
- 0, 0, 0, 1 << plane, \
- 0, 0, 1 << plane, 0, \
- 0, 0, 1 << plane, 1 << plane, \
- 0, 1 << plane, 0, 0, \
- 0, 1 << plane, 0, 1 << plane, \
- 0, 1 << plane, 1 << plane, 0, \
- 0, 1 << plane, 1 << plane, 1 << plane, \
- 1 << plane, 0, 0, 0, \
- 1 << plane, 0, 0, 1 << plane, \
- 1 << plane, 0, 1 << plane, 0, \
- 1 << plane, 0, 1 << plane, 1 << plane, \
- 1 << plane, 1 << plane, 0, 0, \
- 1 << plane, 1 << plane, 0, 1 << plane, \
- 1 << plane, 1 << plane, 1 << plane, 0, \
- 1 << plane, 1 << plane, 1 << plane, 1 << plane, \
+#define LUT32(plane) { \
+ 0, 0, 0, 0, \
+ 0, 0, 0, 1U << plane, \
+ 0, 0, 1U << plane, 0, \
+ 0, 0, 1U << plane, 1U << plane, \
+ 0, 1U << plane, 0, 0, \
+ 0, 1U << plane, 0, 1U << plane, \
+ 0, 1U << plane, 1U << plane, 0, \
+ 0, 1U << plane, 1U << plane, 1U << plane, \
+ 1U << plane, 0, 0, 0, \
+ 1U << plane, 0, 0, 1U << plane, \
+ 1U << plane, 0, 1U << plane, 0, \
+ 1U << plane, 0, 1U << plane, 1U << plane, \
+ 1U << plane, 1U << plane, 0, 0, \
+ 1U << plane, 1U << plane, 0, 1U << plane, \
+ 1U << plane, 1U << plane, 1U << plane, 0, \
+ 1U << plane, 1U << plane, 1U << plane, 1U << plane, \
}
// 32 planes * 4-bit mask * 4 lookup tables each
pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
}
if (s->masking == MASK_HAS_MASK) {
+ if ((1 << avctx->bits_per_coded_sample) < count) {
+ avpriv_request_sample(avctx, "overlapping mask");
+ return AVERROR_PATCHWELCOME;
+ }
memcpy(pal + (1 << avctx->bits_per_coded_sample), pal, count * 4);
for (i = 0; i < count; i++)
pal[i] &= 0xFFFFFF;
av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
return AVERROR_INVALIDDATA;
}
+ if (s->video_size && s->planesize * s->bpp * avctx->height > s->video_size)
+ return AVERROR_INVALIDDATA;
av_freep(&s->ham_buf);
av_freep(&s->ham_palbuf);
int i, count = FFMIN(palette_size / 3, 1 << s->ham);
int ham_count;
const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
+ int extra_space = 1;
+
+ if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ') && s->ham == 4)
+ extra_space = 4;
s->ham_buf = av_malloc((s->planesize * 8) + AV_INPUT_BUFFER_PADDING_SIZE);
if (!s->ham_buf)
return AVERROR(ENOMEM);
ham_count = 8 * (1 << s->ham);
- s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
+ s->ham_palbuf = av_malloc(extra_space * (ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
if (!s->ham_palbuf) {
av_freep(&s->ham_buf);
return AVERROR(ENOMEM);
if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
s->video_size = FFALIGN(avctx->width, 2) * avctx->height * s->bpp;
+ if (!s->video_size)
+ return AVERROR_INVALIDDATA;
s->video[0] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
s->video[1] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
s->pal = av_calloc(256, sizeof(*s->pal));
*/
static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
{
- const uint64_t *lut = plane8_lut[plane];
+ const uint64_t *lut;
if (plane >= 8) {
av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
return;
}
+ lut = plane8_lut[plane];
do {
uint64_t v = AV_RN64A(dst) | lut[*buf++];
AV_WN64A(dst, v);
{
const uint8_t *src_end = src + src_size;
int x = 0, y = 0, i;
- while (src + 5 <= src_end) {
+ while (src_end - src >= 5) {
int opcode;
opcode = *(int8_t *)src++;
if (opcode >= 0) {
int size = opcode + 1;
for (i = 0; i < size; i++) {
- int length = FFMIN(size - i, width);
+ int length = FFMIN(size - i, width - x);
+ if (src_end - src < length * 4)
+ return;
memcpy(dst + y*linesize + x * 4, src, length * 4);
src += length * 4;
x += length;
x = bytestream2_get_be32(&dgb);
}
+ if (ofsdst + (opcode - 1LL) * dstpitch > bytestream2_size_p(&pb))
+ return;
+
while (opcode) {
bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
if (h && (j == (ncolumns - 1))) {
x = bytestream2_get_be32(&gb);
}
+ if (ofsdst + (opcode - 1LL) * dstpitch > bytestream2_size_p(&pb))
+ return;
+
while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
if (h && (j == ncolumns - 1))
bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
entries = bytestream2_get_be32(&gb);
+ if (entries * 8LL > bytestream2_get_bytes_left(&gb))
+ return;
+
while (entries && bytestream2_get_bytes_left(&gb) >= 8) {
int32_t opcode = bytestream2_get_be32(&gb);
unsigned offset = bytestream2_get_be32(&gb);
bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
if (opcode >= 0) {
uint32_t x = bytestream2_get_be32(&gb);
+ if (opcode && 4 + (opcode - 1LL) * pitch > bytestream2_get_bytes_left_p(&pb))
+ continue;
while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
bytestream2_put_be32(&pb, x);
bytestream2_skip_p(&pb, pitch - 4);
opcode--;
}
} else {
- opcode = -opcode;
while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
bytestream2_skip_p(&pb, pitch - 4);
- opcode--;
+ opcode++;
}
}
entries--;
}
#if CONFIG_IFF_ILBM_DECODER
-AVCodec ff_iff_ilbm_decoder = {
+const AVCodec ff_iff_ilbm_decoder = {
.name = "iff",
.long_name = NULL_IF_CONFIG_SMALL("IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN"),
.type = AVMEDIA_TYPE_VIDEO,