]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/mjpegdec.c
avfilter/vf_v360: adjustment out_pad and in_pad maximum value to 1/10
[ffmpeg] / libavcodec / mjpegdec.c
index a65bc8df15d3ad01bf0d5ed972af9284ac55a44d..cb5e2a9b9b0b02ec62c847107efe9ba8808916fc 100644 (file)
@@ -36,7 +36,7 @@
 #include "avcodec.h"
 #include "blockdsp.h"
 #include "copy_block.h"
-#include "hwaccel.h"
+#include "hwconfig.h"
 #include "idctdsp.h"
 #include "internal.h"
 #include "jpegtables.h"
@@ -412,6 +412,18 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
         return AVERROR_PATCHWELCOME;
     }
 
+    if (s->bayer) {
+        if (nb_components == 2) {
+            /* Bayer images embedded in DNGs can contain 2 interleaved components and the
+               width stored in their SOF3 markers is the width of each one.  We only output
+               a single component, therefore we need to adjust the output image width.  We
+               handle the deinterleaving (but not the debayering) in this file. */
+            width *= 2;
+        }
+        /* They can also contain 1 component, which is double the width and half the height
+            of the final image (rows are interleaved).  We don't handle the decoding in this
+            file, but leave that to the TIFF/DNG decoder. */
+    }
 
     /* if different size, realloc/alloc picture */
     if (width != s->width || height != s->height || bits != s->bits ||
@@ -488,6 +500,11 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
         }
 
         switch (pix_fmt_id) {
+        case 0x11110000: /* for bayer-encoded huffman lossless JPEGs embedded in DNGs */
+            if (!s->bayer)
+                goto unk_pixfmt;
+            s->avctx->pix_fmt = AV_PIX_FMT_GRAY16LE;
+            break;
         case 0x11111100:
             if (s->rgb)
                 s->avctx->pix_fmt = s->bits <= 9 ? AV_PIX_FMT_BGR24 : AV_PIX_FMT_BGR48;
@@ -538,11 +555,6 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
         case 0x22122100:
         case 0x21211100:
         case 0x22211200:
-            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;
-            break;
         case 0x22221100:
         case 0x22112200:
         case 0x11222200:
@@ -1041,17 +1053,24 @@ static int handle_rstn(MJpegDecodeContext *s, int nb_components)
     return reset;
 }
 
+/* Handles 1 to 4 components */
 static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int predictor, int point_transform)
 {
     int i, mb_x, mb_y;
+    unsigned width;
     uint16_t (*buffer)[4];
     int left[4], top[4], topleft[4];
     const int linesize = s->linesize[0];
     const int mask     = ((1 << s->bits) - 1) << point_transform;
     int resync_mb_y = 0;
     int resync_mb_x = 0;
+    int vpred[6];
 
-    if (s->nb_components != 3 && s->nb_components != 4)
+    if (!s->bayer && s->nb_components < 3)
+        return AVERROR_INVALIDDATA;
+    if (s->bayer && s->nb_components > 2)
+        return AVERROR_INVALIDDATA;
+    if (s->nb_components <= 0 || s->nb_components > 4)
         return AVERROR_INVALIDDATA;
     if (s->v_max != 1 || s->h_max != 1 || !s->lossless)
         return AVERROR_INVALIDDATA;
@@ -1059,8 +1078,15 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int p
 
     s->restart_count = s->restart_interval;
 
-    av_fast_malloc(&s->ljpeg_buffer, &s->ljpeg_buffer_size,
-                   (unsigned)s->mb_width * 4 * sizeof(s->ljpeg_buffer[0][0]));
+    if (s->restart_interval == 0)
+        s->restart_interval = INT_MAX;
+
+    if (s->bayer)
+        width = s->mb_width / nb_components; /* Interleaved, width stored is the total so need to divide */
+    else
+        width = s->mb_width;
+
+    av_fast_malloc(&s->ljpeg_buffer, &s->ljpeg_buffer_size, width * 4 * sizeof(s->ljpeg_buffer[0][0]));
     if (!s->ljpeg_buffer)
         return AVERROR(ENOMEM);
 
@@ -1078,7 +1104,12 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int p
         for (i = 0; i < 4; i++)
             top[i] = left[i] = topleft[i] = buffer[0][i];
 
-        for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
+        if ((mb_y * s->width) % s->restart_interval == 0) {
+            for (i = 0; i < 6; i++)
+                vpred[i] = 1 << (s->bits-1);
+        }
+
+        for (mb_x = 0; mb_x < width; mb_x++) {
             int modified_predictor = predictor;
 
             if (get_bits_left(&s->gb) < 1) {
@@ -1102,12 +1133,19 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int p
                 topleft[i] = top[i];
                 top[i]     = buffer[mb_x][i];
 
-                PREDICT(pred, topleft[i], top[i], left[i], modified_predictor);
-
                 dc = mjpeg_decode_dc(s, s->dc_index[i]);
                 if(dc == 0xFFFFF)
                     return -1;
 
+                if (!s->bayer || mb_x) {
+                    pred = left[i];
+                } else { /* This path runs only for the first line in bayer images */
+                    vpred[i] += dc;
+                    pred = vpred[i] - dc;
+                }
+
+                PREDICT(pred, topleft[i], top[i], pred, modified_predictor);
+
                 left[i] = buffer[mb_x][i] =
                     mask & (pred + (unsigned)(dc * (1 << point_transform)));
             }
@@ -1151,6 +1189,17 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int p
                 ptr[3*mb_x + 0] = buffer[mb_x][1] + ptr[3*mb_x + 1];
                 ptr[3*mb_x + 2] = buffer[mb_x][2] + ptr[3*mb_x + 1];
             }
+        } else if (s->bayer) {
+            if (nb_components == 1) {
+                /* Leave decoding to the TIFF/DNG decoder (see comment in ff_mjpeg_decode_sof) */
+                for (mb_x = 0; mb_x < width; mb_x++)
+                    ((uint16_t*)ptr)[mb_x] = buffer[mb_x][0];
+            } else if (nb_components == 2) {
+                for (mb_x = 0; mb_x < width; mb_x++) {
+                    ((uint16_t*)ptr)[2*mb_x + 0] = buffer[mb_x][0];
+                    ((uint16_t*)ptr)[2*mb_x + 1] = buffer[mb_x][1];
+                }
+            }
         } else {
             for(i=0; i<nb_components; i++) {
                 int c= s->comp_index[i];
@@ -1695,7 +1744,7 @@ next_field:
                                                 point_transform, ilv)) < 0)
                 return ret;
         } else {
-            if (s->rgb) {
+            if (s->rgb || s->bayer) {
                 if ((ret = ljpeg_decode_rgb_scan(s, nb_components, predictor, point_transform)) < 0)
                     return ret;
             } else {
@@ -1759,8 +1808,15 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
     int len, id, i;
 
     len = get_bits(&s->gb, 16);
-    if (len < 6)
-        return AVERROR_INVALIDDATA;
+    if (len < 6) {
+        if (s->bayer) {
+            // Pentax K-1 (digital camera) JPEG images embedded in DNG images contain unknown APP0 markers
+            av_log(s->avctx, AV_LOG_WARNING, "skipping APPx (len=%"PRId32") for bayer-encoded image\n", len);
+            skip_bits(&s->gb, len);
+            return 0;
+        } else
+            return AVERROR_INVALIDDATA;
+    }
     if (8 * len > get_bits_left(&s->gb))
         return AVERROR_INVALIDDATA;
 
@@ -1993,7 +2049,7 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
         unsigned nummarkers;
 
         id   = get_bits_long(&s->gb, 32);
-        id2  = get_bits_long(&s->gb, 24);
+        id2  = get_bits(&s->gb, 24);
         len -= 7;
         if (id != AV_RB32("PROF") || id2 != AV_RB24("ILE")) {
             av_log(s->avctx, AV_LOG_WARNING, "Invalid ICC_PROFILE header in APP2\n");