avcodec/jpeglsdec: add PAL8 support
authorMichael Niedermayer <michaelni@gmx.at>
Tue, 1 Apr 2014 11:43:44 +0000 (13:43 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Tue, 1 Apr 2014 11:43:44 +0000 (13:43 +0200)
Fixes Ticket3478

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
libavcodec/jpeglsdec.c
libavcodec/mjpegdec.c
libavcodec/mjpegdec.h

index 190b9b6..003656f 100644 (file)
@@ -50,8 +50,9 @@
 int ff_jpegls_decode_lse(MJpegDecodeContext *s)
 {
     int id;
+    int tid, wt, maxtab, i, j;
 
-    skip_bits(&s->gb, 16);  /* length: FIXME: verify field validity */
+    int len = get_bits(&s->gb, 16);  /* length: FIXME: verify field validity */
     id = get_bits(&s->gb, 8);
 
     switch (id) {
@@ -66,9 +67,50 @@ int ff_jpegls_decode_lse(MJpegDecodeContext *s)
         //FIXME quant table?
         break;
     case 2:
+        s->palette_index = 0;
     case 3:
-        av_log(s->avctx, AV_LOG_ERROR, "palette not supported\n");
-        return AVERROR(ENOSYS);
+        tid= get_bits(&s->gb, 8);
+        wt = get_bits(&s->gb, 8);
+
+        if (len < 5)
+            return AVERROR_INVALIDDATA;
+
+        if (wt < 1 || wt > MAX_COMPONENTS) {
+            avpriv_request_sample(s->avctx, "wt %d", wt);
+            return AVERROR_PATCHWELCOME;
+        }
+
+        if ((5 + wt*(s->maxval+1)) < 65535)
+            maxtab = s->maxval;
+        else
+            maxtab = 65530/wt - 1;
+
+        if(s->avctx->debug & FF_DEBUG_PICT_INFO) {
+            av_log(s->avctx, AV_LOG_DEBUG, "LSE palette %d tid:%d wt:%d maxtab:%d\n", id, tid, wt, maxtab);
+        }
+        if (maxtab >= 256) {
+            avpriv_request_sample(s->avctx, ">8bit palette");
+            return AVERROR_PATCHWELCOME;
+        }
+        maxtab = FFMIN(maxtab, (len - 5) / wt + s->palette_index);
+
+        if (s->palette_index > maxtab)
+            return AVERROR_INVALIDDATA;
+
+        if ((s->avctx->pix_fmt == AV_PIX_FMT_GRAY8 || s->avctx->pix_fmt == AV_PIX_FMT_PAL8) &&
+            (s->picture_ptr->format == AV_PIX_FMT_GRAY8 || s->picture_ptr->format == AV_PIX_FMT_PAL8)) {
+            uint32_t *pal = s->picture_ptr->data[1];
+            s->picture_ptr->format =
+            s->avctx->pix_fmt = AV_PIX_FMT_PAL8;
+            for (i=s->palette_index; i<maxtab; i++) {
+                pal[i] = 0;
+                for (j=0; j<wt; j++) {
+                    pal[i] |= get_bits(&s->gb, 8) << (8*wt);
+                }
+            }
+            s->palette_index = i;
+        }
+        break;
     case 4:
         av_log(s->avctx, AV_LOG_ERROR, "oversize image not supported\n");
         return AVERROR(ENOSYS);
index 3c10395..9f7d08f 100644 (file)
@@ -517,6 +517,8 @@ unk_pixfmt:
         s->upscale_h = s->upscale_v = 0;
         if (s->nb_components > 1)
             s->avctx->pix_fmt = AV_PIX_FMT_RGB24;
+        else if (s->palette_index && s->bits <= 8)
+            s->avctx->pix_fmt = AV_PIX_FMT_PAL8;
         else if (s->bits <= 8)
             s->avctx->pix_fmt = AV_PIX_FMT_GRAY8;
         else
index 77bbfed..a947788 100644 (file)
@@ -102,6 +102,7 @@ typedef struct MJpegDecodeContext {
     int16_t (*blocks[MAX_COMPONENTS])[64]; ///< intermediate sums (progressive mode)
     uint8_t *last_nnz[MAX_COMPONENTS];
     uint64_t coefs_finished[MAX_COMPONENTS]; ///< bitmask of which coefs have been completely decoded (progressive mode)
+    int palette_index;
     ScanTable scantable;
     DSPContext dsp;
     HpelDSPContext hdsp;