Jpeg2000Cblk *cblk = prec->cblk + cblkno;
if (s->buf_end - s->buf < cblk->lengthinc)
return AVERROR(EINVAL);
- bytestream_get_buffer(&s->buf, cblk->data, cblk->lengthinc);
+ /* Code-block data can be empty. In that case initialize data
+ * with 0xFFFF. */
+ if (cblk->lengthinc > 0) {
+ bytestream_get_buffer(&s->buf, cblk->data, cblk->lengthinc);
+ } else {
+ cblk->data[0] = 0xFF;
+ cblk->data[1] = 0xFF;
+ }
cblk->length += cblk->lengthinc;
cblk->lengthinc = 0;
}
{
int passno = cblk->npasses, pass_t = 2, bpno = cblk->nonzerobits - 1, y;
- for (y = 0; y < height + 2; y++)
- memset(t1->flags[y], 0, (width + 2) * sizeof(width));
-
for (y = 0; y < height; y++)
memset(t1->data[y], 0, width * sizeof(width));
+ /* If code-block contains no compressed data: nothing to do. */
+ if (!cblk->length)
+ return 0;
+ for (y = 0; y < height + 2; y++)
+ memset(t1->flags[y], 0, (width + 2) * sizeof(width));
+
ff_mqc_initdec(&t1->mqc, cblk->data);
cblk->data[cblk->length] = 0xff;
cblk->data[cblk->length + 1] = 0xff;
// reduction factor, i.e number of resolution levels to skip
s->reduction_factor = s->lowres;
- ff_jpeg2000_init_tier1_luts();
-
if (s->buf_end - s->buf < 2)
return AVERROR(EINVAL);
"couldn't find jpeg2k codestream atom\n");
return -1;
}
+ } else if (AV_RB16(s->buf) != JPEG2000_SOC && AV_RB32(s->buf + 4) == JP2_CODESTREAM) {
+ s->buf += 8;
}
if (bytestream_get_be16(&s->buf) != JPEG2000_SOC) {
return -1;
}
if (ret = jpeg2000_read_main_headers(s))
- return ret;
+ goto end;
/* get picture buffer */
if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) {
av_log(avctx, AV_LOG_ERROR, "ff_thread_get_buffer() failed.\n");
- return ret;
+ goto end;
}
picture->pict_type = AV_PICTURE_TYPE_I;
picture->key_frame = 1;
if (ret = jpeg2000_read_bitstream_packets(s))
- return ret;
+ goto end;
for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++)
if (ret = jpeg2000_decode_tile(s, s->tile + tileno, picture))
- return ret;
+ goto end;
jpeg2000_dec_cleanup(s);
*got_frame = 1;
return s->buf - s->buf_start;
+end:
+ jpeg2000_dec_cleanup(s);
+ return ret;
+}
+
+static void jpeg2000_init_static_data(AVCodec *codec)
+{
+ ff_jpeg2000_init_tier1_luts();
}
#define OFFSET(x) offsetof(Jpeg2000DecoderContext, x)
};
AVCodec ff_jpeg2000_decoder = {
- .name = "jpeg2000",
- .long_name = NULL_IF_CONFIG_SMALL("JPEG 2000"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_JPEG2000,
- .capabilities = CODEC_CAP_FRAME_THREADS,
- .priv_data_size = sizeof(Jpeg2000DecoderContext),
- .decode = jpeg2000_decode_frame,
- .priv_class = &class,
- .pix_fmts = (enum PixelFormat[]) { AV_PIX_FMT_XYZ12,
- AV_PIX_FMT_GRAY8,
- -1 },
- .profiles = NULL_IF_CONFIG_SMALL(profiles)
+ .name = "jpeg2000",
+ .long_name = NULL_IF_CONFIG_SMALL("JPEG 2000"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_JPEG2000,
+ .capabilities = CODEC_CAP_FRAME_THREADS,
+ .priv_data_size = sizeof(Jpeg2000DecoderContext),
+ .init_static_data = jpeg2000_init_static_data,
+ .decode = jpeg2000_decode_frame,
+ .priv_class = &class,
+ .pix_fmts = (enum PixelFormat[]) { AV_PIX_FMT_XYZ12,
+ AV_PIX_FMT_GRAY8,
+ -1 },
+ .profiles = NULL_IF_CONFIG_SMALL(profiles)
};