[FFmpeg-devel] [RFC][PATCH 2/2] libopenjpegdec: rewrite check_image_attributes()
Paul B Mahol
onemda at gmail.com
Mon Mar 26 04:42:41 CEST 2012
Previous one was prone to segfaults and misdetection.
Signed-off-by: Paul B Mahol <onemda at gmail.com>
---
libavcodec/libopenjpegdec.c | 118 ++++++++++++++++++++----------------------
1 files changed, 56 insertions(+), 62 deletions(-)
diff --git a/libavcodec/libopenjpegdec.c b/libavcodec/libopenjpegdec.c
index 2744713..4dd8129 100644
--- a/libavcodec/libopenjpegdec.c
+++ b/libavcodec/libopenjpegdec.c
@@ -24,6 +24,8 @@
* JPEG 2000 decoder using libopenjpeg
*/
+#define DEBUG
+
#include "libavutil/imgutils.h"
#include "libavutil/pixfmt.h"
#include "avcodec.h"
@@ -42,66 +44,66 @@ typedef struct {
static enum PixelFormat check_image_attributes(AVCodecContext *avctx, opj_image_t *image)
{
- opj_image_comp_t c0 = image->comps[0];
- opj_image_comp_t c1 = image->comps[1];
- opj_image_comp_t c2 = image->comps[2];
- int compRatio = 0;
- compRatio |= c0.dx << 15 | c0.dy << 12;
- compRatio |= c1.dx << 9 | c1.dy << 6;
- compRatio |= c2.dx << 3 | c2.dy;
+ enum PixelFormat fmt = PIX_FMT_NONE;
+ AVPixFmtDescriptor pixdesc = { 0 };
+ int i, color_space;
+ int numcomps = image->numcomps;
- if (image->numcomps == 4) {
- if (c0.prec == 8) {
- if (compRatio == 0112222 &&
- image->comps[3].dx == 1 && image->comps[3].dy == 1) {
- return PIX_FMT_YUVA420P;
- } else {
- return PIX_FMT_RGBA;
- }
- } else {
- return PIX_FMT_RGBA64;
- }
- }
+ if (numcomps < 1 || numcomps > 4)
+ goto fail;
+ if ((image->comps[0].dx != 1) || (image->comps[0].dy != 1))
+ goto fail;
+ if ((numcomps > 2) && (image->comps[1].dy != image->comps[2].dy))
+ goto fail;
+ if ((numcomps > 3) && (image->comps[3].dx != 1 || image->comps[3].dy != 1))
+ goto fail;
- switch (compRatio) {
- case 0111111: goto libopenjpeg_yuv444_rgb;
- case 0111212: return PIX_FMT_YUV440P;
- case 0112121: goto libopenjpeg_yuv422;
- case 0112222: goto libopenjpeg_yuv420;
- default: goto libopenjpeg_rgb;
+ av_dlog(avctx, "numcomps %d\n", numcomps);
+ for (i = 0; i < numcomps; i++) {
+ pixdesc.comp[i].depth_minus1 = image->comps[i].prec - 1;
+ av_dlog(avctx, "%d prec %d dx %d dy %d\n", i, image->comps[i].prec, image->comps[i].dx, image->comps[i].dy);
}
-libopenjpeg_yuv420:
- switch (c0.prec) {
- case 8: return PIX_FMT_YUV420P;
- case 9: return PIX_FMT_YUV420P9;
- case 10: return PIX_FMT_YUV420P10;
- case 16: return PIX_FMT_YUV420P16;
- }
+ pixdesc.nb_components = image->numcomps;
+ pixdesc.log2_chroma_w = image->comps[1].dx >> 1;
+ pixdesc.log2_chroma_h = image->comps[1].dy >> 1;
-libopenjpeg_yuv422:
- switch (c0.prec) {
- case 8: return PIX_FMT_YUV422P;
- case 9: return PIX_FMT_YUV422P9;
- case 10: return PIX_FMT_YUV422P10;
- case 16: return PIX_FMT_YUV422P16;
+ color_space = image->color_space;
+ if (color_space == CLRSPC_UNSPECIFIED) {
+ av_log(avctx, AV_LOG_WARNING, "colorspace unspecified, guessing...\n");
+ if (numcomps < 3)
+ color_space = CLRSPC_GRAY;
+ else
+ color_space = CLRSPC_SYCC;
}
-
-libopenjpeg_yuv444_rgb:
- switch (c0.prec) {
- case 8: return PIX_FMT_RGB24;
- case 9: return PIX_FMT_YUV444P9;
- case 10: return PIX_FMT_YUV444P10;
- case 16: return PIX_FMT_YUV444P16;
+ switch (color_space) {
+ case CLRSPC_SRGB:
+ pixdesc.flags |= PIX_FMT_RGB;
+ for (i = 0; i < numcomps; i++)
+ pixdesc.comp[i].offset_plus1 = 1 + i * image->comps[i].prec / 8;
+ fmt = av_find_pix_fmt(&pixdesc, 16 | 4);
+ break;
+ case CLRSPC_GRAY:
+ if (numcomps == 1 && image->comps[0].prec == 8)
+ fmt = PIX_FMT_GRAY8;
+ else if (numcomps == 2 && image->comps[0].prec == 8)
+ fmt = PIX_FMT_GRAY8A;
+ else if (numcomps == 1 && image->comps[0].prec == 16)
+ fmt = PIX_FMT_GRAY16;
+ break;
+ case CLRSPC_SYCC:
+ pixdesc.flags |= PIX_FMT_PLANAR;
+ for (i = 0; i < numcomps; i++)
+ pixdesc.comp[i].offset_plus1 = 1;
+ fmt = av_find_pix_fmt(&pixdesc, 16 | 4);
+ break;
}
-libopenjpeg_rgb:
- switch (c0.prec) {
- case 8: return PIX_FMT_RGB24;
- default: return PIX_FMT_RGB48;
- }
+ if (fmt == PIX_FMT_NONE)
+fail:
+ av_log_ask_for_sample(avctx, "unsupported pixel format\n");
- return PIX_FMT_RGB24;
+ return fmt;
}
static inline int libopenjpeg_ispacked(enum PixelFormat pix_fmt) {
@@ -265,17 +267,9 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
}
avcodec_set_dimensions(avctx, width, height);
- switch (image->numcomps) {
- case 1: avctx->pix_fmt = (image->comps[0].bpp == 8) ? PIX_FMT_GRAY8 : PIX_FMT_GRAY16;
- break;
- case 2: avctx->pix_fmt = PIX_FMT_GRAY8A;
- break;
- case 3:
- case 4: avctx->pix_fmt = check_image_attributes(avctx, image);
- break;
- default: av_log(avctx, AV_LOG_ERROR, "%d components unsupported.\n", image->numcomps);
- goto done;
- }
+ avctx->pix_fmt = check_image_attributes(avctx, image);
+ if (avctx->pix_fmt == PIX_FMT_NONE)
+ goto done;
if(picture->data[0])
ff_thread_release_buffer(avctx, picture);
--
1.7.7
More information about the ffmpeg-devel
mailing list