avcodec/mjpegdec: Support >8bpc color mjpeg

Fixes Ticket2939

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
Michael Niedermayer 2013-09-11 02:29:13 +02:00
parent 7bc9fb8cde
commit 64b6279d14
1 changed files with 27 additions and 17 deletions

View File

@ -265,12 +265,6 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
"bits/component or 16-bit gray"); "bits/component or 16-bit gray");
return AVERROR_PATCHWELCOME; return AVERROR_PATCHWELCOME;
} }
if (!s->lossless && !(s->bits <= 8 || nb_components == 1)) {
avpriv_report_missing_feature(s->avctx,
"lossy that is not <= 8 "
"bits/component or 16-bit gray");
return AVERROR_PATCHWELCOME;
}
s->nb_components = nb_components; s->nb_components = nb_components;
s->h_max = 1; s->h_max = 1;
s->v_max = 1; s->v_max = 1;
@ -366,9 +360,10 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
s->avctx->pix_fmt = AV_PIX_FMT_BGR24; s->avctx->pix_fmt = AV_PIX_FMT_BGR24;
else { else {
if (s->component_id[0] == 'Q' && s->component_id[1] == 'F' && s->component_id[2] == 'A') { if (s->component_id[0] == 'Q' && s->component_id[1] == 'F' && s->component_id[2] == 'A') {
s->avctx->pix_fmt = AV_PIX_FMT_GBR24P; s->avctx->pix_fmt = s->bits <= 8 ? AV_PIX_FMT_GBRP : AV_PIX_FMT_GBRP16;
} else { } else {
s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P; if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P;
else s->avctx->pix_fmt = AV_PIX_FMT_YUV444P16;
s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
} }
} }
@ -378,14 +373,16 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
if (s->rgb) if (s->rgb)
s->avctx->pix_fmt = AV_PIX_FMT_ABGR; s->avctx->pix_fmt = AV_PIX_FMT_ABGR;
else { else {
s->avctx->pix_fmt = /*s->cs_itu601 ?*/ AV_PIX_FMT_YUVA444P/* : AV_PIX_FMT_YUVJA444P*/; s->avctx->pix_fmt = s->bits <= 8 ? AV_PIX_FMT_YUVA444P : AV_PIX_FMT_YUVA444P16;
s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
} }
av_assert0(s->nb_components == 4); av_assert0(s->nb_components == 4);
break; break;
case 0x12121100: case 0x12121100:
case 0x22122100: case 0x22122100:
s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P; if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P;
else
goto unk_pixfmt;
s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
s->upscale_v = 2; s->upscale_v = 2;
s->upscale_h = (pix_fmt_id == 0x22122100); s->upscale_h = (pix_fmt_id == 0x22122100);
@ -393,14 +390,18 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
break; break;
case 0x21211100: case 0x21211100:
case 0x22211200: case 0x22211200:
s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P; if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P;
else
goto unk_pixfmt;
s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
s->upscale_v = (pix_fmt_id == 0x22211200); s->upscale_v = (pix_fmt_id == 0x22211200);
s->upscale_h = 2; s->upscale_h = 2;
s->chroma_height = s->height; s->chroma_height = s->height;
break; break;
case 0x22221100: case 0x22221100:
s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P; if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P;
else
goto unk_pixfmt;
s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
s->upscale_v = 2; s->upscale_v = 2;
s->upscale_h = 2; s->upscale_h = 2;
@ -423,30 +424,39 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
case 0x12111100: case 0x12111100:
case 0x22211100: case 0x22211100:
case 0x22112100: case 0x22112100:
s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV440P : AV_PIX_FMT_YUVJ440P; if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV440P : AV_PIX_FMT_YUVJ440P;
else
goto unk_pixfmt;
s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
s->upscale_h = (pix_fmt_id == 0x22211100) * 2 + (pix_fmt_id == 0x22112100); s->upscale_h = (pix_fmt_id == 0x22211100) * 2 + (pix_fmt_id == 0x22112100);
s->chroma_height = s->height / 2; s->chroma_height = s->height / 2;
break; break;
case 0x21111100: case 0x21111100:
s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV422P : AV_PIX_FMT_YUVJ422P; if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV422P : AV_PIX_FMT_YUVJ422P;
else s->avctx->pix_fmt = AV_PIX_FMT_YUV422P16;
s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
break; break;
case 0x22121100: case 0x22121100:
case 0x22111200: case 0x22111200:
s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV422P : AV_PIX_FMT_YUVJ422P; if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV422P : AV_PIX_FMT_YUVJ422P;
else
goto unk_pixfmt;
s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
s->upscale_v = (pix_fmt_id == 0x22121100) + 1; s->upscale_v = (pix_fmt_id == 0x22121100) + 1;
break; break;
case 0x22111100: case 0x22111100:
s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV420P : AV_PIX_FMT_YUVJ420P; if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV420P : AV_PIX_FMT_YUVJ420P;
else s->avctx->pix_fmt = AV_PIX_FMT_YUV420P16;
s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
break; break;
case 0x41111100: case 0x41111100:
s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV411P : AV_PIX_FMT_YUVJ411P; if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV411P : AV_PIX_FMT_YUVJ411P;
else
goto unk_pixfmt;
s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
break; break;
default: default:
unk_pixfmt:
av_log(s->avctx, AV_LOG_ERROR, "Unhandled pixel format 0x%x\n", pix_fmt_id); av_log(s->avctx, AV_LOG_ERROR, "Unhandled pixel format 0x%x\n", pix_fmt_id);
return AVERROR_PATCHWELCOME; return AVERROR_PATCHWELCOME;
} }