const uint8_t *val_table, int nb_codes,
int use_static, int is_ac)
{
- uint8_t huff_size[256];
+ uint8_t huff_size[256] = { 0 };
uint16_t huff_code[256];
uint16_t huff_sym[256];
int i;
assert(nb_codes <= 256);
- memset(huff_size, 0, sizeof(huff_size));
ff_mjpeg_build_huffman_codes(huff_size, huff_code, bits_table, val_table);
for (i = 0; i < 256; i++)
static void build_basic_mjpeg_vlc(MJpegDecodeContext *s)
{
- build_vlc(&s->vlcs[0][0], ff_mjpeg_bits_dc_luminance,
- ff_mjpeg_val_dc, 12, 0, 0);
- build_vlc(&s->vlcs[0][1], ff_mjpeg_bits_dc_chrominance,
- ff_mjpeg_val_dc, 12, 0, 0);
- build_vlc(&s->vlcs[1][0], ff_mjpeg_bits_ac_luminance,
- ff_mjpeg_val_ac_luminance, 251, 0, 1);
- build_vlc(&s->vlcs[1][1], ff_mjpeg_bits_ac_chrominance,
- ff_mjpeg_val_ac_chrominance, 251, 0, 1);
- build_vlc(&s->vlcs[2][0], ff_mjpeg_bits_ac_luminance,
- ff_mjpeg_val_ac_luminance, 251, 0, 0);
- build_vlc(&s->vlcs[2][1], ff_mjpeg_bits_ac_chrominance,
- ff_mjpeg_val_ac_chrominance, 251, 0, 0);
+ build_vlc(&s->vlcs[0][0], avpriv_mjpeg_bits_dc_luminance,
+ avpriv_mjpeg_val_dc, 12, 0, 0);
+ build_vlc(&s->vlcs[0][1], avpriv_mjpeg_bits_dc_chrominance,
+ avpriv_mjpeg_val_dc, 12, 0, 0);
+ build_vlc(&s->vlcs[1][0], avpriv_mjpeg_bits_ac_luminance,
+ avpriv_mjpeg_val_ac_luminance, 251, 0, 1);
+ build_vlc(&s->vlcs[1][1], avpriv_mjpeg_bits_ac_chrominance,
+ avpriv_mjpeg_val_ac_chrominance, 251, 0, 1);
+ build_vlc(&s->vlcs[2][0], avpriv_mjpeg_bits_ac_luminance,
+ avpriv_mjpeg_val_ac_luminance, 251, 0, 0);
+ build_vlc(&s->vlcs[2][1], avpriv_mjpeg_bits_ac_chrominance,
+ avpriv_mjpeg_val_ac_chrominance, 251, 0, 0);
}
av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx)
build_basic_mjpeg_vlc(s);
if (s->extern_huff) {
+ int ret;
av_log(avctx, AV_LOG_INFO, "mjpeg: using external huffman table\n");
init_get_bits(&s->gb, avctx->extradata, avctx->extradata_size * 8);
- if (ff_mjpeg_decode_dht(s)) {
+ if ((ret = ff_mjpeg_decode_dht(s))) {
av_log(avctx, AV_LOG_ERROR,
"mjpeg: error using external huffman table\n");
- return AVERROR_INVALIDDATA;
+ return ret;
}
}
if (avctx->field_order == AV_FIELD_BB) { /* quicktime icefloe 019 */
s->interlace_polarity = 1; /* bottom field first */
av_log(avctx, AV_LOG_DEBUG, "mjpeg bottom field first\n");
}
- if (avctx->codec->id == CODEC_ID_AMV)
+ if (avctx->codec->id == AV_CODEC_ID_AMV)
s->flipped = 1;
return 0;
int len, index, i, class, n, v, code_max;
uint8_t bits_table[17];
uint8_t val_table[256];
+ int ret = 0;
len = get_bits(&s->gb, 16) - 2;
while (len > 0) {
if (len < 17)
- return -1;
+ return AVERROR_INVALIDDATA;
class = get_bits(&s->gb, 4);
if (class >= 2)
- return -1;
+ return AVERROR_INVALIDDATA;
index = get_bits(&s->gb, 4);
if (index >= 4)
- return -1;
+ return AVERROR_INVALIDDATA;
n = 0;
for (i = 1; i <= 16; i++) {
bits_table[i] = get_bits(&s->gb, 8);
}
len -= 17;
if (len < n || n > 256)
- return -1;
+ return AVERROR_INVALIDDATA;
code_max = 0;
for (i = 0; i < n; i++) {
ff_free_vlc(&s->vlcs[class][index]);
av_log(s->avctx, AV_LOG_DEBUG, "class=%d index=%d nb_codes=%d\n",
class, index, code_max + 1);
- if (build_vlc(&s->vlcs[class][index], bits_table, val_table,
- code_max + 1, 0, class > 0) < 0)
- return -1;
+ if ((ret = build_vlc(&s->vlcs[class][index], bits_table, val_table,
+ code_max + 1, 0, class > 0)) < 0)
+ return ret;
if (class > 0) {
ff_free_vlc(&s->vlcs[2][index]);
- if (build_vlc(&s->vlcs[2][index], bits_table, val_table,
- code_max + 1, 0, 0) < 0)
- return -1;
+ if ((ret = build_vlc(&s->vlcs[2][index], bits_table, val_table,
+ code_max + 1, 0, 0)) < 0)
+ return ret;
}
}
return 0;
av_log(s->avctx, AV_LOG_DEBUG, "sof0: picture: %dx%d\n", width, height);
if (av_image_check_size(width, height, 0, s->avctx))
- return -1;
+ return AVERROR_INVALIDDATA;
nb_components = get_bits(&s->gb, 8);
if (nb_components <= 0 ||
nb_components > MAX_COMPONENTS)
return -1;
if (s->ls && !(s->bits <= 8 || nb_components == 1)) {
- av_log(s->avctx, AV_LOG_ERROR,
- "only <= 8 bits/component or 16-bit gray accepted for JPEG-LS\n");
- return -1;
+ av_log_missing_feature(s->avctx,
+ "only <= 8 bits/component or "
+ "16-bit gray accepted for JPEG-LS\n", 0);
+ return AVERROR_PATCHWELCOME;
}
s->nb_components = nb_components;
s->h_max = 1;
s->v_max = s->v_count[i];
s->quant_index[i] = get_bits(&s->gb, 8);
if (s->quant_index[i] >= 4)
- return -1;
+ return AVERROR_INVALIDDATA;
av_log(s->avctx, AV_LOG_DEBUG, "component %d %d:%d id: %d quant:%d\n",
i, s->h_count[i], s->v_count[i],
s->component_id[i], s->quant_index[i]);
}
if (s->ls && (s->h_max > 1 || s->v_max > 1)) {
- av_log(s->avctx, AV_LOG_ERROR,
- "Subsampling in JPEG-LS is not supported.\n");
- return -1;
+ av_log_missing_feature(s->avctx,
+ "Subsampling in JPEG-LS is not supported.\n", 0);
+ return AVERROR_PATCHWELCOME;
}
if (s->v_max == 1 && s->h_max == 1 && s->lossless == 1)
s->first_picture = 0;
}
- if (s->interlaced && (s->bottom_field == !s->interlace_polarity))
- return 0;
-
+ if (!(s->interlaced && (s->bottom_field == !s->interlace_polarity))) {
/* XXX: not complete test ! */
pix_fmt_id = (s->h_count[0] << 28) | (s->v_count[0] << 24) |
(s->h_count[1] << 20) | (s->v_count[1] << 16) |
break;
default:
av_log(s->avctx, AV_LOG_ERROR, "Unhandled pixel format 0x%x\n", pix_fmt_id);
- return -1;
+ return AVERROR_PATCHWELCOME;
}
if (s->ls) {
if (s->nb_components > 1)
for (i = 0; i < 3; i++)
s->linesize[i] = s->picture_ptr->linesize[i] << s->interlaced;
-// printf("%d %d %d %d %d %d\n",
-// s->width, s->height, s->linesize[0], s->linesize[1],
-// s->interlaced, s->avctx->height);
+ av_dlog(s->avctx, "%d %d %d %d %d %d\n",
+ s->width, s->height, s->linesize[0], s->linesize[1],
+ s->interlaced, s->avctx->height);
if (len != (8 + (3 * nb_components)))
av_log(s->avctx, AV_LOG_DEBUG, "decode_sof0: error, len(%d) mismatch\n", len);
+ }
/* totally blank picture as progressive JPEG will only add details to it */
if (s->progressive) {
val = mjpeg_decode_dc(s, dc_index);
if (val == 0xffff) {
av_log(s->avctx, AV_LOG_ERROR, "error dc\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
val = val * quant_matrix[0] + s->last_dc[component];
s->last_dc[component] = val;
if (i > 63) {
av_log(s->avctx, AV_LOG_ERROR, "error count: %d\n", i);
- return -1;
+ return AVERROR_INVALIDDATA;
}
j = s->scantable.permutated[i];
block[j] = level * quant_matrix[j];
val = mjpeg_decode_dc(s, dc_index);
if (val == 0xffff) {
av_log(s->avctx, AV_LOG_ERROR, "error dc\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
val = (val * quant_matrix[0] << Al) + s->last_dc[component];
s->last_dc[component] = val;
break;
}
av_log(s->avctx, AV_LOG_ERROR, "error count: %d\n", i);
- return -1;
+ return AVERROR_INVALIDDATA;
}
j = s->scantable.permutated[i];
block[j] = level * quant_matrix[j] << Al;
i += 15;
if (i >= se) {
av_log(s->avctx, AV_LOG_ERROR, "ZRL overflow: %d\n", i);
- return -1;
+ return AVERROR_INVALIDDATA;
}
} else {
val = (1 << run);
return 0;
}
-static av_always_inline void mjpeg_copy_block(uint8_t *dst, const uint8_t *src,
- int linesize, int lowres)
-{
- switch (lowres) {
- case 0: copy_block8(dst, src, linesize, linesize, 8);
- break;
- case 1: copy_block4(dst, src, linesize, linesize, 4);
- break;
- case 2: copy_block2(dst, src, linesize, linesize, 2);
- break;
- case 3: *dst = *src;
- break;
- }
-}
-
static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah,
int Al, const uint8_t *mb_bitmask,
const AVFrame *reference)
if (get_bits_left(&s->gb) < 0) {
av_log(s->avctx, AV_LOG_ERROR, "overread %d\n",
-get_bits_left(&s->gb));
- return -1;
+ return AVERROR_INVALIDDATA;
}
for (i = 0; i < nb_components; i++) {
uint8_t *ptr;
x = 0;
y = 0;
for (j = 0; j < n; j++) {
- block_offset = (((linesize[c] * (v * mb_y + y) * 8) +
- (h * mb_x + x) * 8) >> s->avctx->lowres);
+ block_offset = ((linesize[c] * (v * mb_y + y) * 8) +
+ (h * mb_x + x) * 8);
if (s->interlaced && s->bottom_field)
block_offset += linesize[c] >> 1;
ptr = data[c] + block_offset;
if (!s->progressive) {
if (copy_mb)
- mjpeg_copy_block(ptr, reference_data[c] + block_offset,
- linesize[c], s->avctx->lowres);
+ copy_block8(ptr, reference_data[c] + block_offset,
+ linesize[c], linesize[c], 8);
else {
s->dsp.clear_block(s->block);
if (decode_block(s, s->block, i,
s->quant_matrixes[s->quant_index[c]]) < 0) {
av_log(s->avctx, AV_LOG_ERROR,
"error y=%d x=%d\n", mb_y, mb_x);
- return -1;
+ return AVERROR_INVALIDDATA;
}
s->dsp.idct_put(ptr, linesize[c], s->block);
}
Al) < 0) {
av_log(s->avctx, AV_LOG_ERROR,
"error y=%d x=%d\n", mb_y, mb_x);
- return -1;
+ return AVERROR_INVALIDDATA;
}
}
- // av_log(s->avctx, AV_LOG_DEBUG, "mb: %d %d processed\n",
- // mb_y, mb_x);
- // av_log(NULL, AV_LOG_DEBUG, "%d %d %d %d %d %d %d %d \n",
- // mb_x, mb_y, x, y, c, s->bottom_field,
- // (v * mb_y + y) * 8, (h * mb_x + x) * 8);
+ av_dlog(s->avctx, "mb: %d %d processed\n", mb_y, mb_x);
+ av_dlog(s->avctx, "%d %d %d %d %d %d %d %d \n",
+ mb_x, mb_y, x, y, c, s->bottom_field,
+ (v * mb_y + y) * 8, (h * mb_x + x) * 8);
if (++x == h) {
x = 0;
y++;
}
for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
- int block_offset = (mb_y * linesize * 8 >> s->avctx->lowres);
+ int block_offset = mb_y * linesize * 8;
uint8_t *ptr = data + block_offset;
int block_idx = mb_y * s->block_stride[c];
DCTELEM (*block)[64] = &s->blocks[c][block_idx];
if (ret < 0) {
av_log(s->avctx, AV_LOG_ERROR,
"error y=%d x=%d\n", mb_y, mb_x);
- return -1;
+ return AVERROR_INVALIDDATA;
}
}
if (last_scan) {
if (copy_mb) {
- mjpeg_copy_block(ptr, reference_data + block_offset,
- linesize, s->avctx->lowres);
+ copy_block8(ptr, reference_data + block_offset,
+ linesize, linesize, 8);
} else {
s->dsp.idct_put(ptr, linesize, *block);
- ptr += 8 >> s->avctx->lowres;
+ ptr += 8;
}
}
}
const AVFrame *reference)
{
int len, nb_components, i, h, v, predictor, point_transform;
- int index, id;
+ int index, id, ret;
const int block_size = s->lossless ? 1 : 8;
int ilv, prev_shift;
if (nb_components == 0 || nb_components > MAX_COMPONENTS) {
av_log(s->avctx, AV_LOG_ERROR,
"decode_sos: nb_components (%d) unsupported\n", nb_components);
- return -1;
+ return AVERROR_PATCHWELCOME;
}
if (len != 6 + 2 * nb_components) {
av_log(s->avctx, AV_LOG_ERROR, "decode_sos: invalid len (%d)\n", len);
- return -1;
+ return AVERROR_INVALIDDATA;
}
for (i = 0; i < nb_components; i++) {
id = get_bits(&s->gb, 8) - 1;
if (index == s->nb_components) {
av_log(s->avctx, AV_LOG_ERROR,
"decode_sos: index(%d) out of components\n", index);
- return -1;
+ return AVERROR_INVALIDDATA;
}
/* Metasoft MJPEG codec has Cb and Cr swapped */
if (s->avctx->codec_tag == MKTAG('M', 'T', 'S', 'J')
prev_shift = get_bits(&s->gb, 4); /* Ah */
point_transform = get_bits(&s->gb, 4); /* Al */
- for (i = 0; i < nb_components; i++)
- s->last_dc[i] = 1024;
-
if (nb_components > 1) {
/* interleaved stream */
s->mb_width = (s->width + s->h_max * block_size - 1) / (s->h_max * block_size);
for (i = s->mjpb_skiptosod; i > 0; i--)
skip_bits(&s->gb, 8);
+next_field:
+ for (i = 0; i < nb_components; i++)
+ s->last_dc[i] = 1024;
+
if (s->lossless) {
if (CONFIG_JPEGLS_DECODER && s->ls) {
// for () {
// reset_ls_coding_parameters(s, 0);
- if (ff_jpegls_decode_picture(s, predictor, point_transform, ilv) < 0)
- return -1;
+ if ((ret = ff_jpegls_decode_picture(s, predictor,
+ point_transform, ilv)) < 0)
+ return ret;
} else {
if (s->rgb) {
- if (ljpeg_decode_rgb_scan(s, predictor, point_transform) < 0)
- return -1;
+ if ((ret = ljpeg_decode_rgb_scan(s, predictor,
+ point_transform)) < 0)
+ return ret;
} else {
- if (ljpeg_decode_yuv_scan(s, predictor, point_transform) < 0)
- return -1;
+ if ((ret = ljpeg_decode_yuv_scan(s, predictor,
+ point_transform)) < 0)
+ return ret;
}
}
} else {
if (s->progressive && predictor) {
- if (mjpeg_decode_scan_progressive_ac(s, predictor, ilv, prev_shift,
- point_transform,
- mb_bitmask, reference) < 0)
- return -1;
+ if ((ret = mjpeg_decode_scan_progressive_ac(s, predictor,
+ ilv, prev_shift,
+ point_transform,
+ mb_bitmask,
+ reference)) < 0)
+ return ret;
} else {
- if (mjpeg_decode_scan(s, nb_components, prev_shift, point_transform,
- mb_bitmask, reference) < 0)
- return -1;
+ if ((ret = mjpeg_decode_scan(s, nb_components,
+ prev_shift, point_transform,
+ mb_bitmask, reference)) < 0)
+ return ret;
+ }
+ }
+
+ if (s->interlaced &&
+ get_bits_left(&s->gb) > 32 &&
+ show_bits(&s->gb, 8) == 0xFF) {
+ GetBitContext bak = s->gb;
+ align_get_bits(&bak);
+ if (show_bits(&bak, 16) == 0xFFD1) {
+ av_dlog(s->avctx, "AVRn interlaced picture marker found\n");
+ s->gb = bak;
+ skip_bits(&s->gb, 16);
+ s->bottom_field ^= 1;
+
+ goto next_field;
}
}
+
emms_c();
return 0;
out_of_range:
av_log(s->avctx, AV_LOG_ERROR, "decode_sos: ac/dc index out of range\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
static int mjpeg_decode_dri(MJpegDecodeContext *s)
{
if (get_bits(&s->gb, 16) != 4)
- return -1;
+ return AVERROR_INVALIDDATA;
s->restart_interval = get_bits(&s->gb, 16);
s->restart_count = 0;
av_log(s->avctx, AV_LOG_DEBUG, "restart interval: %d\n",
len = get_bits(&s->gb, 16);
if (len < 5)
- return -1;
+ return AVERROR_INVALIDDATA;
if (8 * len > get_bits_left(&s->gb))
- return -1;
+ return AVERROR_INVALIDDATA;
id = get_bits_long(&s->gb, 32);
id = av_be2ne32(id);
4bytes field_size_less_padding
*/
s->buggy_avid = 1;
-// if (s->first_picture)
-// printf("mjpeg: workarounding buggy AVID\n");
i = get_bits(&s->gb, 8);
if (i == 2)
s->bottom_field = 1;
skip_bits(&s->gb, 32);
len -= 10;
#endif
-// if (s->interlace_polarity)
-// printf("mjpeg: interlace polarity: %d\n", s->interlace_polarity);
goto out;
}
/* buggy avid, it puts EOI only at every 10th frame */
if (!strcmp(cbuf, "AVID")) {
s->buggy_avid = 1;
- // if (s->first_picture)
- // printf("mjpeg: workarounding buggy AVID\n");
} else if (!strcmp(cbuf, "CS=ITU601"))
s->cs_itu601 = 1;
else if ((len > 20 && !strncmp(cbuf, "Intel(R) JPEG Library", 21)) ||
uint8_t x = *(src++);
*(dst++) = x;
- if (s->avctx->codec_id != CODEC_ID_THP) {
+ if (s->avctx->codec_id != AV_CODEC_ID_THP) {
if (x == 0xff) {
while (src < buf_end && x == 0xff)
x = *(src++);
const uint8_t *unescaped_buf_ptr;
int unescaped_buf_size;
int start_code;
+ int ret = 0;
AVFrame *picture = data;
s->got_picture = 0; // picture from previous image can not be reused
ff_mjpeg_decode_dqt(s);
break;
case DHT:
- if (ff_mjpeg_decode_dht(s) < 0) {
+ if ((ret = ff_mjpeg_decode_dht(s)) < 0) {
av_log(avctx, AV_LOG_ERROR, "huffman table decode error\n");
- return -1;
+ return ret;
}
break;
case SOF0:
s->lossless = 0;
s->ls = 0;
s->progressive = 0;
- if (ff_mjpeg_decode_sof(s) < 0)
- return -1;
+ if ((ret = ff_mjpeg_decode_sof(s)) < 0)
+ return ret;
break;
case SOF2:
s->lossless = 0;
s->ls = 0;
s->progressive = 1;
- if (ff_mjpeg_decode_sof(s) < 0)
- return -1;
+ if ((ret = ff_mjpeg_decode_sof(s)) < 0)
+ return ret;
break;
case SOF3:
s->lossless = 1;
s->ls = 0;
s->progressive = 0;
- if (ff_mjpeg_decode_sof(s) < 0)
- return -1;
+ if ((ret = ff_mjpeg_decode_sof(s)) < 0)
+ return ret;
break;
case SOF48:
s->lossless = 1;
s->ls = 1;
s->progressive = 0;
- if (ff_mjpeg_decode_sof(s) < 0)
- return -1;
+ if ((ret = ff_mjpeg_decode_sof(s)) < 0)
+ return ret;
break;
case LSE:
- if (!CONFIG_JPEGLS_DECODER || ff_jpegls_decode_lse(s) < 0)
- return -1;
+ if (!CONFIG_JPEGLS_DECODER ||
+ (ret = ff_jpegls_decode_lse(s)) < 0)
+ return ret;
break;
case EOI:
s->cur_scan = 0;
"Can not process SOS before SOF, skipping\n");
break;
}
- if (ff_mjpeg_decode_sos(s, NULL, NULL) < 0 &&
+ if ((ret = ff_mjpeg_decode_sos(s, NULL, NULL)) < 0 &&
(avctx->err_recognition & AV_EF_EXPLODE))
- return AVERROR_INVALIDDATA;
+ return ret;
/* buggy avid puts EOI every 10-20th frame */
/* if restart period is over process EOI */
if ((s->buggy_avid && !s->interlaced) || s->restart_interval)
av_log(avctx, AV_LOG_ERROR,
"mjpeg: unsupported coding type (%x)\n", start_code);
break;
-// default:
-// printf("mjpeg: unsupported marker (%x)\n", start_code);
-// break;
}
not_the_end:
goto eoi_parser;
}
av_log(avctx, AV_LOG_FATAL, "No JPEG data found in image\n");
- return -1;
+ return AVERROR_INVALIDDATA;
the_end:
av_log(avctx, AV_LOG_DEBUG, "mjpeg decode frame unused %td bytes\n",
buf_end - buf_ptr);
#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
static const AVOption options[] = {
{ "extern_huff", "Use external huffman table.",
- OFFSET(extern_huff), AV_OPT_TYPE_INT, { 0 }, 0, 1, VD },
+ OFFSET(extern_huff), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VD },
{ NULL },
};
AVCodec ff_mjpeg_decoder = {
.name = "mjpeg",
.type = AVMEDIA_TYPE_VIDEO,
- .id = CODEC_ID_MJPEG,
+ .id = AV_CODEC_ID_MJPEG,
.priv_data_size = sizeof(MJpegDecodeContext),
.init = ff_mjpeg_decode_init,
.close = ff_mjpeg_decode_end,
.decode = ff_mjpeg_decode_frame,
.capabilities = CODEC_CAP_DR1,
- .max_lowres = 3,
.long_name = NULL_IF_CONFIG_SMALL("MJPEG (Motion JPEG)"),
.priv_class = &mjpegdec_class,
};
AVCodec ff_thp_decoder = {
.name = "thp",
.type = AVMEDIA_TYPE_VIDEO,
- .id = CODEC_ID_THP,
+ .id = AV_CODEC_ID_THP,
.priv_data_size = sizeof(MJpegDecodeContext),
.init = ff_mjpeg_decode_init,
.close = ff_mjpeg_decode_end,
.decode = ff_mjpeg_decode_frame,
.capabilities = CODEC_CAP_DR1,
- .max_lowres = 3,
.long_name = NULL_IF_CONFIG_SMALL("Nintendo Gamecube THP video"),
};