[FFmpeg-cvslog] avcodec/mjpegdec: 12bit Grayscale support

Michael Niedermayer git at videolan.org
Fri Sep 6 01:26:04 CEST 2013


ffmpeg | branch: master | Michael Niedermayer <michaelni at gmx.at> | Fri Sep  6 00:57:50 2013 +0200| [c407c73457df8002142dfb043486a102e79b17b2] | committer: Michael Niedermayer

avcodec/mjpegdec: 12bit Grayscale support

Fixes part of Ticket2812

Signed-off-by: Michael Niedermayer <michaelni at gmx.at>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=c407c73457df8002142dfb043486a102e79b17b2
---

 libavcodec/mjpegdec.c |   20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 0d619ef..856947b 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -232,11 +232,6 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
     if (s->bits == 9 && !s->pegasus_rct)
         s->rct  = 1;    // FIXME ugly
 
-    if (s->bits != 8 && !s->lossless) {
-        av_log(s->avctx, AV_LOG_ERROR, "only 8 bits/component accepted\n");
-        return -1;
-    }
-
     if(s->lossless && s->avctx->lowres){
         av_log(s->avctx, AV_LOG_ERROR, "lowres is not possible with lossless jpeg\n");
         return -1;
@@ -270,6 +265,12 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
                                       "bits/component or 16-bit gray");
         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->h_max         = 1;
     s->v_max         = 1;
@@ -1052,6 +1053,7 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah,
     const uint8_t *reference_data[MAX_COMPONENTS];
     int linesize[MAX_COMPONENTS];
     GetBitContext mb_bitmask_gb;
+    int bytes_per_pixel = 1 + (s->bits > 8);
 
     if (mb_bitmask)
         init_get_bits(&mb_bitmask_gb, mb_bitmask, s->mb_width * s->mb_height);
@@ -1101,7 +1103,7 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah,
                 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);
+                                     (h * mb_x + x) * 8 * bytes_per_pixel) >> s->avctx->lowres);
 
                     if (s->interlaced && s->bottom_field)
                         block_offset += linesize[c] >> 1;
@@ -1123,9 +1125,15 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah,
                             s->dsp.idct_put(ptr, linesize[c], s->block);
                             if (s->bits & 7) {
                                 int block_x, block_y;
+                                if (s->bits > 8) {
+                                    for (block_y=0; block_y<8; block_y++)
+                                        for (block_x=0; block_x<8; block_x++)
+                                            *(uint16_t*)(ptr + 2*block_x + block_y*linesize[c]) <<= 16 - s->bits;
+                                } else {
                                     for (block_y=0; block_y<8; block_y++)
                                         for (block_x=0; block_x<8; block_x++)
                                             *(ptr + 2*block_x + block_y*linesize[c]) <<= 8 - s->bits;
+                                }
                             }
                         }
                     } else {



More information about the ffmpeg-cvslog mailing list