]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/mjpeg.c
Remove redundant #inclusion of common.h, avcodec.h already #includes it.
[ffmpeg] / libavcodec / mjpeg.c
index d52f75938d9182cdc61d1c8a4d527e7aa8fb0af9..214fc08a9e58561b30a346cd31a67673024e1850 100644 (file)
@@ -4,23 +4,25 @@
  * Copyright (c) 2003 Alex Beregszaszi
  * Copyright (c) 2003-2004 Michael Niedermayer
  *
- * This library is free software; you can redistribute it and/or
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * version 2.1 of the License, or (at your option) any later version.
  *
- * This library is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  *
  * Support for external huffman table, various fixes (AVID workaround),
  * aspecting, new decode_frame mechanism and apple mjpeg-b support
- *                                  by Alex Beregszaszi <alex@naxine.org>
+ *                                  by Alex Beregszaszi
  */
 
 /**
@@ -34,6 +36,7 @@
 #include "avcodec.h"
 #include "dsputil.h"
 #include "mpegvideo.h"
+#include "bytestream.h"
 
 /* use two quantizer tables (one for luminance and one for chrominance) */
 /* not yet working */
@@ -438,7 +441,7 @@ void mjpeg_picture_header(MpegEncContext *s)
     }
 
     put_bits(&s->pb, 16, 17);
-    if(lossless && s->avctx->pix_fmt == PIX_FMT_RGBA32)
+    if(lossless && s->avctx->pix_fmt == PIX_FMT_RGB32)
         put_bits(&s->pb, 8, 9); /* 9 bits/component RCT */
     else
         put_bits(&s->pb, 8, 8); /* 8 bits/component */
@@ -613,7 +616,7 @@ static void encode_block(MpegEncContext *s, DCTELEM *block, int n)
     uint16_t *huff_code_ac;
 
     /* DC coef */
-    component = (n <= 3 ? 0 : n - 4 + 1);
+    component = (n <= 3 ? 0 : (n&1) + 1);
     dc = block[0]; /* overflow is impossible */
     val = dc - s->last_dc[component];
     if (n < 4) {
@@ -666,9 +669,16 @@ void mjpeg_encode_mb(MpegEncContext *s,
                      DCTELEM block[6][64])
 {
     int i;
-    for(i=0;i<6;i++) {
+    for(i=0;i<5;i++) {
         encode_block(s, block[i], i);
     }
+    if (s->chroma_format == CHROMA_420) {
+        encode_block(s, block[5], 5);
+    } else {
+        encode_block(s, block[6], 6);
+        encode_block(s, block[5], 5);
+        encode_block(s, block[7], 7);
+    }
 }
 
 static int encode_picture_lossless(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
@@ -690,7 +700,7 @@ static int encode_picture_lossless(AVCodecContext *avctx, unsigned char *buf, in
 
     s->header_bits= put_bits_count(&s->pb);
 
-    if(avctx->pix_fmt == PIX_FMT_RGBA32){
+    if(avctx->pix_fmt == PIX_FMT_RGB32){
         int x, y, i;
         const int linesize= p->linesize[0];
         uint16_t (*buffer)[4]= (void *) s->rd_scratchpad;
@@ -829,7 +839,6 @@ static int encode_picture_lossless(AVCodecContext *avctx, unsigned char *buf, in
 typedef struct MJpegDecodeContext {
     AVCodecContext *avctx;
     GetBitContext gb;
-    int mpeg_enc_ctx_allocated; /* true if decoding context allocated */
 
     int start_code; /* current start code */
     int buffer_size;
@@ -845,6 +854,7 @@ typedef struct MJpegDecodeContext {
     int bottom_field;   /* true if bottom field */
     int lossless;
     int ls;
+    int progressive;
     int rgb;
     int rct;            /* standard rct */
     int pegasus_rct;    /* pegasus reversible colorspace transform */
@@ -873,9 +883,9 @@ typedef struct MJpegDecodeContext {
     AVFrame picture; /* picture structure */
     int linesize[MAX_COMPONENTS];                   ///< linesize << interlaced
     int8_t *qscale_table;
-    DCTELEM block[64] __align8;
+    DECLARE_ALIGNED_8(DCTELEM, block[64]);
     ScanTable scantable;
-    void (*idct_put)(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/);
+    DSPContext dsp;
 
     int restart_interval;
     int restart_count;
@@ -885,53 +895,53 @@ typedef struct MJpegDecodeContext {
     int interlace_polarity;
 
     int mjpb_skiptosod;
+
+    int cur_scan; /* current scan, used by JPEG-LS */
 } MJpegDecodeContext;
 
-#include "jpeg_ls.c" //FIXME make jpeg-ls more independant
+#include "jpeg_ls.c" //FIXME make jpeg-ls more independent
 
 static int mjpeg_decode_dht(MJpegDecodeContext *s);
 
 static int build_vlc(VLC *vlc, const uint8_t *bits_table, const uint8_t *val_table,
-                      int nb_codes, int use_static)
+                      int nb_codes, int use_static, int is_ac)
 {
-    uint8_t huff_size[256];
-    uint16_t huff_code[256];
+    uint8_t huff_size[256+16];
+    uint16_t huff_code[256+16];
+
+    assert(nb_codes <= 256);
 
     memset(huff_size, 0, sizeof(huff_size));
     build_huffman_codes(huff_size, huff_code, bits_table, val_table);
 
+    if(is_ac){
+        memmove(huff_size+16, huff_size, sizeof(uint8_t)*nb_codes);
+        memmove(huff_code+16, huff_code, sizeof(uint16_t)*nb_codes);
+        memset(huff_size, 0, sizeof(uint8_t)*16);
+        memset(huff_code, 0, sizeof(uint16_t)*16);
+        nb_codes += 16;
+    }
+
     return init_vlc(vlc, 9, nb_codes, huff_size, 1, 1, huff_code, 2, 2, use_static);
 }
 
 static int mjpeg_decode_init(AVCodecContext *avctx)
 {
     MJpegDecodeContext *s = avctx->priv_data;
-    MpegEncContext s2;
-    memset(s, 0, sizeof(MJpegDecodeContext));
 
     s->avctx = avctx;
-
-    /* ugly way to get the idct & scantable FIXME */
-    memset(&s2, 0, sizeof(MpegEncContext));
-    s2.avctx= avctx;
-//    s2->out_format = FMT_MJPEG;
-    dsputil_init(&s2.dsp, avctx);
-    DCT_common_init(&s2);
-
-    s->scantable= s2.intra_scantable;
-    s->idct_put= s2.dsp.idct_put;
-
-    s->mpeg_enc_ctx_allocated = 0;
+    dsputil_init(&s->dsp, avctx);
+    ff_init_scantable(s->dsp.idct_permutation, &s->scantable, ff_zigzag_direct);
     s->buffer_size = 0;
     s->buffer = NULL;
     s->start_code = -1;
     s->first_picture = 1;
     s->org_height = avctx->coded_height;
 
-    build_vlc(&s->vlcs[0][0], bits_dc_luminance, val_dc_luminance, 12, 0);
-    build_vlc(&s->vlcs[0][1], bits_dc_chrominance, val_dc_chrominance, 12, 0);
-    build_vlc(&s->vlcs[1][0], bits_ac_luminance, val_ac_luminance, 251, 0);
-    build_vlc(&s->vlcs[1][1], bits_ac_chrominance, val_ac_chrominance, 251, 0);
+    build_vlc(&s->vlcs[0][0], bits_dc_luminance, val_dc_luminance, 12, 0, 0);
+    build_vlc(&s->vlcs[0][1], bits_dc_chrominance, val_dc_chrominance, 12, 0, 0);
+    build_vlc(&s->vlcs[1][0], bits_ac_luminance, val_ac_luminance, 251, 0, 1);
+    build_vlc(&s->vlcs[1][1], bits_ac_chrominance, val_ac_chrominance, 251, 0, 1);
 
     if (avctx->flags & CODEC_FLAG_EXTERN_HUFF)
     {
@@ -940,6 +950,13 @@ static int mjpeg_decode_init(AVCodecContext *avctx)
         mjpeg_decode_dht(s);
         /* should check for error - but dunno */
     }
+    if (avctx->extradata_size > 9 &&
+        AV_RL32(avctx->extradata + 4) == MKTAG('f','i','e','l')) {
+        if (avctx->extradata[9] == 6) { /* quicktime icefloe 019 */
+            s->interlace_polarity = 1; /* bottom field first */
+            av_log(avctx, AV_LOG_DEBUG, "mjpeg bottom field first\n");
+        }
+    }
 
     return 0;
 }
@@ -988,7 +1005,7 @@ static int find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){
 
 static int jpeg_parse(AVCodecParserContext *s,
                            AVCodecContext *avctx,
-                           uint8_t **poutbuf, int *poutbuf_size,
+                           const uint8_t **poutbuf, int *poutbuf_size,
                            const uint8_t *buf, int buf_size)
 {
     ParseContext *pc = s->priv_data;
@@ -996,13 +1013,13 @@ static int jpeg_parse(AVCodecParserContext *s,
 
     next= find_frame_end(pc, buf, buf_size);
 
-    if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) {
+    if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
         *poutbuf = NULL;
         *poutbuf_size = 0;
         return buf_size;
     }
 
-    *poutbuf = (uint8_t *)buf;
+    *poutbuf = buf;
     *poutbuf_size = buf_size;
     return next;
 }
@@ -1018,13 +1035,13 @@ static int mjpeg_decode_dqt(MJpegDecodeContext *s)
         /* only 8 bit precision handled */
         if (get_bits(&s->gb, 4) != 0)
         {
-            dprintf("dqt: 16bit precision\n");
+            av_log(s->avctx, AV_LOG_ERROR, "dqt: 16bit precision\n");
             return -1;
         }
         index = get_bits(&s->gb, 4);
         if (index >= 4)
             return -1;
-        dprintf("index=%d\n", index);
+        av_log(s->avctx, AV_LOG_DEBUG, "index=%d\n", index);
         /* read quant table */
         for(i=0;i<64;i++) {
             j = s->scantable.permutated[i];
@@ -1035,7 +1052,7 @@ static int mjpeg_decode_dqt(MJpegDecodeContext *s)
         s->qscale[index]= FFMAX(
             s->quant_matrixes[index][s->scantable.permutated[1]],
             s->quant_matrixes[index][s->scantable.permutated[8]]) >> 1;
-        dprintf("qscale[%d]: %d\n", index, s->qscale[index]);
+        av_log(s->avctx, AV_LOG_DEBUG, "qscale[%d]: %d\n", index, s->qscale[index]);
         len -= 65;
     }
 
@@ -1080,9 +1097,9 @@ static int mjpeg_decode_dht(MJpegDecodeContext *s)
 
         /* build VLC and flush previous vlc if present */
         free_vlc(&s->vlcs[class][index]);
-        dprintf("class=%d index=%d nb_codes=%d\n",
+        av_log(s->avctx, AV_LOG_DEBUG, "class=%d index=%d nb_codes=%d\n",
                class, index, code_max + 1);
-        if(build_vlc(&s->vlcs[class][index], bits_table, val_table, code_max + 1, 0) < 0){
+        if(build_vlc(&s->vlcs[class][index], bits_table, val_table, code_max + 1, 0, class > 0) < 0){
             return -1;
         }
     }
@@ -1091,7 +1108,7 @@ static int mjpeg_decode_dht(MJpegDecodeContext *s)
 
 static int mjpeg_decode_sof(MJpegDecodeContext *s)
 {
-    int len, nb_components, i, width, height;
+    int len, nb_components, i, width, height, pix_fmt_id;
 
     /* XXX: verify len field validity */
     len = get_bits(&s->gb, 16);
@@ -1104,10 +1121,15 @@ static int mjpeg_decode_sof(MJpegDecodeContext *s)
         av_log(s->avctx, AV_LOG_ERROR, "only 8 bits/component accepted\n");
         return -1;
     }
+
     height = get_bits(&s->gb, 16);
     width = get_bits(&s->gb, 16);
 
-    dprintf("sof0: picture: %dx%d\n", width, height);
+    //HACK for odd_height.mov
+    if(s->interlaced && s->width == width && s->height == height + 1)
+        height= s->height;
+
+    av_log(s->avctx, AV_LOG_DEBUG, "sof0: picture: %dx%d\n", width, height);
     if(avcodec_check_dimensions(s->avctx, width, height))
         return -1;
 
@@ -1115,6 +1137,10 @@ static int mjpeg_decode_sof(MJpegDecodeContext *s)
     if (nb_components <= 0 ||
         nb_components > MAX_COMPONENTS)
         return -1;
+    if (s->ls && !(s->bits <= 8 || nb_components == 1)){
+        av_log(s->avctx, AV_LOG_ERROR, "only <= 8 bits/component or 16-bit gray accepted for JPEG-LS\n");
+        return -1;
+    }
     s->nb_components = nb_components;
     s->h_max = 1;
     s->v_max = 1;
@@ -1131,8 +1157,13 @@ static int mjpeg_decode_sof(MJpegDecodeContext *s)
         s->quant_index[i] = get_bits(&s->gb, 8);
         if (s->quant_index[i] >= 4)
             return -1;
-        dprintf("component %d %d:%d id: %d quant:%d\n", i, s->h_count[i],
-            s->v_count[i], s->component_id[i], s->quant_index[i]);
+        av_log(s->avctx, AV_LOG_DEBUG, "component %d %d:%d id: %d quant:%d\n", i, s->h_count[i],
+               s->v_count[i], s->component_id[i], s->quant_index[i]);
+    }
+
+    if(s->ls && (s->h_max > 1 || s->v_max > 1)) {
+        av_log(s->avctx, AV_LOG_ERROR, "Subsampling in JPEG-LS is not supported.\n");
+        return -1;
     }
 
     if(s->v_max==1 && s->h_max==1 && s->lossless==1) s->rgb=1;
@@ -1144,44 +1175,61 @@ static int mjpeg_decode_sof(MJpegDecodeContext *s)
 
         s->width = width;
         s->height = height;
-        avcodec_set_dimensions(s->avctx, width, height);
+        s->interlaced = 0;
 
         /* test interlaced mode */
         if (s->first_picture &&
             s->org_height != 0 &&
             s->height < ((s->org_height * 3) / 4)) {
             s->interlaced = 1;
-//            s->bottom_field = (s->interlace_polarity) ? 1 : 0;
-            s->bottom_field = 0;
-            s->avctx->height *= 2;
+            s->bottom_field = s->interlace_polarity;
+            s->picture.interlaced_frame = 1;
+            s->picture.top_field_first = !s->interlace_polarity;
+            height *= 2;
         }
 
+        avcodec_set_dimensions(s->avctx, width, height);
+
         s->qscale_table= av_mallocz((s->width+15)/16);
 
         s->first_picture = 0;
     }
 
-    if(s->interlaced && s->bottom_field)
+    if(s->interlaced && (s->bottom_field == !s->interlace_polarity))
         return 0;
 
     /* XXX: not complete test ! */
-    switch((s->h_count[0] << 4) | s->v_count[0]) {
-    case 0x11:
+    pix_fmt_id = (s->h_count[0] << 20) | (s->v_count[0] << 16) |
+                 (s->h_count[1] << 12) | (s->v_count[1] <<  8) |
+                 (s->h_count[2] <<  4) |  s->v_count[2];
+    av_log(s->avctx, AV_LOG_DEBUG, "pix fmt id %x\n", pix_fmt_id);
+    switch(pix_fmt_id){
+    case 0x222222:
+    case 0x111111:
         if(s->rgb){
-            s->avctx->pix_fmt = PIX_FMT_RGBA32;
+            s->avctx->pix_fmt = PIX_FMT_RGB32;
         }else if(s->nb_components==3)
             s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV444P : PIX_FMT_YUVJ444P;
         else
             s->avctx->pix_fmt = PIX_FMT_GRAY8;
         break;
-    case 0x21:
+    case 0x211111:
+    case 0x221212:
         s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV422P : PIX_FMT_YUVJ422P;
         break;
     default:
-    case 0x22:
+    case 0x221111:
         s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV420P : PIX_FMT_YUVJ420P;
         break;
     }
+    if(s->ls){
+        if(s->nb_components > 1)
+            s->avctx->pix_fmt = PIX_FMT_RGB24;
+        else if(s->bits <= 8)
+            s->avctx->pix_fmt = PIX_FMT_GRAY8;
+        else
+            s->avctx->pix_fmt = PIX_FMT_GRAY16;
+    }
 
     if(s->picture.data[0])
         s->avctx->release_buffer(s->avctx, &s->picture);
@@ -1202,9 +1250,15 @@ static int mjpeg_decode_sof(MJpegDecodeContext *s)
 
     if (len != (8+(3*nb_components)))
     {
-        dprintf("decode_sof0: error, len(%d) mismatch\n", len);
+        av_log(s->avctx, AV_LOG_DEBUG, "decode_sof0: error, len(%d) mismatch\n", len);
     }
 
+    /* totally blank picture as progressive JPEG will only add details to it */
+    if(s->progressive){
+        memset(s->picture.data[0], 0, s->picture.linesize[0] * s->height);
+        memset(s->picture.data[1], 0, s->picture.linesize[1] * s->height >> (s->v_max - s->v_count[1]));
+        memset(s->picture.data[2], 0, s->picture.linesize[2] * s->height >> (s->v_max - s->v_count[2]));
+    }
     return 0;
 }
 
@@ -1214,8 +1268,8 @@ static inline int mjpeg_decode_dc(MJpegDecodeContext *s, int dc_index)
     code = get_vlc2(&s->gb, s->vlcs[0][dc_index].table, 9, 2);
     if (code < 0)
     {
-        dprintf("mjpeg_decode_dc: bad vlc: %d:%d (%p)\n", 0, dc_index,
-                &s->vlcs[0][dc_index]);
+        av_log(s->avctx, AV_LOG_WARNING, "mjpeg_decode_dc: bad vlc: %d:%d (%p)\n", 0, dc_index,
+               &s->vlcs[0][dc_index]);
         return 0xffff;
     }
 
@@ -1227,51 +1281,135 @@ static inline int mjpeg_decode_dc(MJpegDecodeContext *s, int dc_index)
 
 /* decode block and dequantize */
 static int decode_block(MJpegDecodeContext *s, DCTELEM *block,
-                        int component, int dc_index, int ac_index, int quant_index)
+                        int component, int dc_index, int ac_index, int16_t *quant_matrix)
 {
     int code, i, j, level, val;
-    VLC *ac_vlc;
-    int16_t *quant_matrix;
 
     /* DC coef */
     val = mjpeg_decode_dc(s, dc_index);
     if (val == 0xffff) {
-        dprintf("error dc\n");
+        av_log(s->avctx, AV_LOG_ERROR, "error dc\n");
         return -1;
     }
-    quant_matrix = s->quant_matrixes[quant_index];
     val = val * quant_matrix[0] + s->last_dc[component];
     s->last_dc[component] = val;
     block[0] = val;
     /* AC coefs */
-    ac_vlc = &s->vlcs[1][ac_index];
-    i = 1;
+    i = 0;
+    {OPEN_READER(re, &s->gb)
     for(;;) {
-        code = get_vlc2(&s->gb, s->vlcs[1][ac_index].table, 9, 2);
+        UPDATE_CACHE(re, &s->gb);
+        GET_VLC(code, re, &s->gb, s->vlcs[1][ac_index].table, 9, 2)
 
-        if (code < 0) {
-            dprintf("error ac\n");
-            return -1;
-        }
         /* EOB */
-        if (code == 0)
+        if (code == 0x10)
             break;
-        if (code == 0xf0) {
-            i += 16;
-        } else {
-            level = get_xbits(&s->gb, code & 0xf);
-            i += code >> 4;
-            if (i >= 64) {
-                dprintf("error count: %d\n", i);
+        i += ((unsigned)code) >> 4;
+        if(code != 0x100){
+            code &= 0xf;
+            if(code > MIN_CACHE_BITS - 16){
+                UPDATE_CACHE(re, &s->gb)
+            }
+            {
+                int cache=GET_CACHE(re,&s->gb);
+                int sign=(~cache)>>31;
+                level = (NEG_USR32(sign ^ cache,code) ^ sign) - sign;
+            }
+
+            LAST_SKIP_BITS(re, &s->gb, code)
+
+            if (i >= 63) {
+                if(i == 63){
+                    j = s->scantable.permutated[63];
+                    block[j] = level * quant_matrix[j];
+                    break;
+                }
+                av_log(s->avctx, AV_LOG_ERROR, "error count: %d\n", i);
                 return -1;
             }
             j = s->scantable.permutated[i];
             block[j] = level * quant_matrix[j];
-            i++;
-            if (i >= 64)
+        }
+    }
+    CLOSE_READER(re, &s->gb)}
+
+    return 0;
+}
+
+/* decode block and dequantize - progressive JPEG version */
+static int decode_block_progressive(MJpegDecodeContext *s, DCTELEM *block,
+                        int component, int dc_index, int ac_index, int16_t *quant_matrix,
+                        int ss, int se, int Ah, int Al, int *EOBRUN)
+{
+    int code, i, j, level, val, run;
+
+    /* DC coef */
+    if(!ss){
+        val = mjpeg_decode_dc(s, dc_index);
+        if (val == 0xffff) {
+            av_log(s->avctx, AV_LOG_ERROR, "error dc\n");
+            return -1;
+        }
+        val = (val * quant_matrix[0] << Al) + s->last_dc[component];
+    }else
+        val = 0;
+    s->last_dc[component] = val;
+    block[0] = val;
+    if(!se) return 0;
+    /* AC coefs */
+    if(*EOBRUN){
+        (*EOBRUN)--;
+        return 0;
+    }
+    {OPEN_READER(re, &s->gb)
+    for(i=ss;;i++) {
+        UPDATE_CACHE(re, &s->gb);
+        GET_VLC(code, re, &s->gb, s->vlcs[1][ac_index].table, 9, 2)
+        /* Progressive JPEG use AC coeffs from zero and this decoder sets offset 16 by default */
+        code -= 16;
+        if(code & 0xF) {
+            i += ((unsigned) code) >> 4;
+            code &= 0xf;
+            if(code > MIN_CACHE_BITS - 16){
+                UPDATE_CACHE(re, &s->gb)
+            }
+            {
+                int cache=GET_CACHE(re,&s->gb);
+                int sign=(~cache)>>31;
+                level = (NEG_USR32(sign ^ cache,code) ^ sign) - sign;
+            }
+
+            LAST_SKIP_BITS(re, &s->gb, code)
+
+            if (i >= se) {
+                if(i == se){
+                    j = s->scantable.permutated[se];
+                    block[j] = level * quant_matrix[j] << Al;
+                    break;
+                }
+                av_log(s->avctx, AV_LOG_ERROR, "error count: %d\n", i);
+                return -1;
+            }
+            j = s->scantable.permutated[i];
+            block[j] = level * quant_matrix[j] << Al;
+        }else{
+            run = ((unsigned) code) >> 4;
+            if(run == 0xF){// ZRL - skip 15 coefficients
+                i += 15;
+            }else{
+                val = run;
+                run = (1 << run);
+                UPDATE_CACHE(re, &s->gb);
+                run += (GET_CACHE(re, &s->gb) >> (32 - val)) & (run - 1);
+                if(val)
+                    LAST_SKIP_BITS(re, &s->gb, val);
+                *EOBRUN = run - 1;
                 break;
+            }
         }
     }
+    CLOSE_READER(re, &s->gb)}
+
     return 0;
 }
 
@@ -1426,10 +1564,11 @@ static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor, int point
     return 0;
 }
 
-static int mjpeg_decode_scan(MJpegDecodeContext *s){
+static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int ss, int se, int Ah, int Al){
     int i, mb_x, mb_y;
-    const int nb_components=3;
+    int EOBRUN = 0;
 
+    if(Ah) return 0; /* TODO decode refinement planes too */
     for(mb_y = 0; mb_y < s->mb_height; mb_y++) {
         for(mb_x = 0; mb_x < s->mb_width; mb_x++) {
             if (s->restart_interval && !s->restart_count)
@@ -1446,20 +1585,29 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s){
                 y = 0;
                 for(j=0;j<n;j++) {
                     memset(s->block, 0, sizeof(s->block));
-                    if (decode_block(s, s->block, i,
+                    if (!s->progressive && decode_block(s, s->block, i,
                                      s->dc_index[i], s->ac_index[i],
-                                     s->quant_index[c]) < 0) {
-                        dprintf("error y=%d x=%d\n", mb_y, mb_x);
+                                     s->quant_matrixes[ s->quant_index[c] ]) < 0) {
+                        av_log(s->avctx, AV_LOG_ERROR, "error y=%d x=%d\n", mb_y, mb_x);
                         return -1;
                     }
-//                    dprintf("mb: %d %d processed\n", mb_y, mb_x);
+                    if (s->progressive && decode_block_progressive(s, s->block, i,
+                                     s->dc_index[i], s->ac_index[i],
+                                     s->quant_matrixes[ s->quant_index[c] ], ss, se, Ah, Al, &EOBRUN) < 0) {
+                        av_log(s->avctx, AV_LOG_ERROR, "error y=%d x=%d\n", mb_y, mb_x);
+                        return -1;
+                    }
+//                    av_log(s->avctx, AV_LOG_DEBUG, "mb: %d %d processed\n", mb_y, mb_x);
                     ptr = s->picture.data[c] +
                         (((s->linesize[c] * (v * mb_y + y) * 8) +
                         (h * mb_x + x) * 8) >> s->avctx->lowres);
                     if (s->interlaced && s->bottom_field)
                         ptr += s->linesize[c] >> 1;
 //av_log(NULL, AV_LOG_DEBUG, "%d %d %d %d %d %d %d %d \n", mb_x, mb_y, x, y, c, s->bottom_field, (v * mb_y + y) * 8, (h * mb_x + x) * 8);
-                    s->idct_put(ptr, s->linesize[c], s->block);
+                    if(!s->progressive)
+                        s->dsp.idct_put(ptr, s->linesize[c], s->block);
+                    else
+                        s->dsp.idct_add(ptr, s->linesize[c], s->block);
                     if (++x == h) {
                         x = 0;
                         y++;
@@ -1484,34 +1632,28 @@ static int mjpeg_decode_sos(MJpegDecodeContext *s)
     int len, nb_components, i, h, v, predictor, point_transform;
     int vmax, hmax, index, id;
     const int block_size= s->lossless ? 1 : 8;
-    int ilv;
+    int ilv, prev_shift;
 
     /* XXX: verify len field validity */
     len = get_bits(&s->gb, 16);
     nb_components = get_bits(&s->gb, 8);
     if (len != 6+2*nb_components)
     {
-        dprintf("decode_sos: invalid len (%d)\n", len);
-        return -1;
-    }
-    /* XXX: only interleaved scan accepted */
-    if (nb_components != s->nb_components)
-    {
-        dprintf("decode_sos: components(%d) mismatch\n", nb_components);
+        av_log(s->avctx, AV_LOG_ERROR, "decode_sos: invalid len (%d)\n", len);
         return -1;
     }
     vmax = 0;
     hmax = 0;
     for(i=0;i<nb_components;i++) {
         id = get_bits(&s->gb, 8) - 1;
-        dprintf("component: %d\n", id);
+        av_log(s->avctx, AV_LOG_DEBUG, "component: %d\n", id);
         /* find component index */
         for(index=0;index<s->nb_components;index++)
             if (id == s->component_id[index])
                 break;
         if (index == s->nb_components)
         {
-            dprintf("decode_sos: index(%d) out of components\n", index);
+            av_log(s->avctx, AV_LOG_ERROR, "decode_sos: index(%d) out of components\n", index);
             return -1;
         }
 
@@ -1549,7 +1691,7 @@ static int mjpeg_decode_sos(MJpegDecodeContext *s)
 
     predictor= get_bits(&s->gb, 8); /* JPEG Ss / lossless JPEG predictor /JPEG-LS NEAR */
     ilv= get_bits(&s->gb, 8);    /* JPEG Se / JPEG-LS ILV */
-    skip_bits(&s->gb, 4); /* Ah */
+    prev_shift = get_bits(&s->gb, 4); /* Ah */
     point_transform= get_bits(&s->gb, 4); /* Al */
 
     for(i=0;i<nb_components;i++)
@@ -1559,9 +1701,9 @@ static int mjpeg_decode_sos(MJpegDecodeContext *s)
         /* interleaved stream */
         s->mb_width  = (s->width  + s->h_max * block_size - 1) / (s->h_max * block_size);
         s->mb_height = (s->height + s->v_max * block_size - 1) / (s->v_max * block_size);
-    } else {
-        h = s->h_max / s->h_scount[s->comp_index[0]];
-        v = s->v_max / s->v_scount[s->comp_index[0]];
+    } else if(!s->ls) { /* skip this for JPEG-LS */
+        h = s->h_max / s->h_scount[0];
+        v = s->v_max / s->v_scount[0];
         s->mb_width  = (s->width  + h * block_size - 1) / (h * block_size);
         s->mb_height = (s->height + v * block_size - 1) / (v * block_size);
         s->nb_blocks[0] = 1;
@@ -1582,6 +1724,9 @@ static int mjpeg_decode_sos(MJpegDecodeContext *s)
     if(s->lossless){
         if(s->ls){
 //            for(){
+//            reset_ls_coding_parameters(s, 0);
+
+            ls_decode_picture(s, predictor, point_transform, ilv);
         }else{
             if(s->rgb){
                 if(ljpeg_decode_rgb_scan(s, predictor, point_transform) < 0)
@@ -1592,13 +1737,13 @@ static int mjpeg_decode_sos(MJpegDecodeContext *s)
             }
         }
     }else{
-        if(mjpeg_decode_scan(s) < 0)
+        if(mjpeg_decode_scan(s, nb_components, predictor, ilv, prev_shift, point_transform) < 0)
             return -1;
     }
     emms_c();
     return 0;
  out_of_range:
-    dprintf("decode_sos: ac/dc index out of range\n");
+    av_log(s->avctx, AV_LOG_ERROR, "decode_sos: ac/dc index out of range\n");
     return -1;
 }
 
@@ -1608,14 +1753,14 @@ static int mjpeg_decode_dri(MJpegDecodeContext *s)
         return -1;
     s->restart_interval = get_bits(&s->gb, 16);
     s->restart_count = 0;
-    dprintf("restart interval: %d\n", s->restart_interval);
+    av_log(s->avctx, AV_LOG_DEBUG, "restart interval: %d\n", s->restart_interval);
 
     return 0;
 }
 
 static int mjpeg_decode_app(MJpegDecodeContext *s)
 {
-    int len, id;
+    int len, id, i;
 
     len = get_bits(&s->gb, 16);
     if (len < 5)
@@ -1646,7 +1791,9 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
             s->buggy_avid = 1;
 //        if (s->first_picture)
 //            printf("mjpeg: workarounding buggy AVID\n");
-        s->interlace_polarity = get_bits(&s->gb, 8);
+        i = get_bits(&s->gb, 8);
+        if     (i==2) s->bottom_field= 1;
+        else if(i==1) s->bottom_field= 0;
 #if 0
         skip_bits(&s->gb, 8);
         skip_bits(&s->gb, 32);
@@ -1762,7 +1909,7 @@ static int mjpeg_decode_com(MJpegDecodeContext *s)
 {
     int len = get_bits(&s->gb, 16);
     if (len >= 2 && 8*len - 16 + get_bits_count(&s->gb) <= s->gb.size_in_bits) {
-        uint8_t *cbuf = av_malloc(len - 1);
+        char *cbuf = av_malloc(len - 1);
         if (cbuf) {
             int i;
             for (i = 0; i < len - 2; i++)
@@ -1842,7 +1989,7 @@ static int find_marker(uint8_t **pbuf_ptr, uint8_t *buf_end)
     val = -1;
 found:
 #ifdef DEBUG
-    dprintf("find_marker skipped %d bytes\n", skipped);
+    av_log(NULL, AV_LOG_VERBOSE, "find_marker skipped %d bytes\n", skipped);
 #endif
     *pbuf_ptr = buf_ptr;
     return val;
@@ -1867,19 +2014,19 @@ static int mjpeg_decode_frame(AVCodecContext *avctx,
             if (start_code < 0) {
                 goto the_end;
             } else {
-                dprintf("marker=%x avail_size_in_buf=%d\n", start_code, buf_end - buf_ptr);
+                av_log(avctx, AV_LOG_DEBUG, "marker=%x avail_size_in_buf=%d\n", start_code, buf_end - buf_ptr);
 
                 if ((buf_end - buf_ptr) > s->buffer_size)
                 {
                     av_free(s->buffer);
                     s->buffer_size = buf_end-buf_ptr;
                     s->buffer = av_malloc(s->buffer_size + FF_INPUT_BUFFER_PADDING_SIZE);
-                    dprintf("buffer too small, expanding to %d bytes\n",
+                    av_log(avctx, AV_LOG_DEBUG, "buffer too small, expanding to %d bytes\n",
                         s->buffer_size);
                 }
 
-                /* unescape buffer of SOS */
-                if (start_code == SOS)
+                /* unescape buffer of SOS, use special treatment for JPEG-LS */
+                if (start_code == SOS && !s->ls)
                 {
                     uint8_t *src = buf_ptr;
                     uint8_t *dst = s->buffer;
@@ -1889,33 +2036,74 @@ static int mjpeg_decode_frame(AVCodecContext *avctx,
                         uint8_t x = *(src++);
 
                         *(dst++) = x;
-                        if (x == 0xff)
+                        if (avctx->codec_id != CODEC_ID_THP)
                         {
-                            while(src<buf_end && x == 0xff)
-                                x = *(src++);
+                            if (x == 0xff) {
+                                while (src < buf_end && x == 0xff)
+                                    x = *(src++);
+
+                                if (x >= 0xd0 && x <= 0xd7)
+                                    *(dst++) = x;
+                                else if (x)
+                                    break;
+                            }
+                        }
+                    }
+                    init_get_bits(&s->gb, s->buffer, (dst - s->buffer)*8);
 
-                            if (x >= 0xd0 && x <= 0xd7)
-                                *(dst++) = x;
-                            else if (x)
+                    av_log(avctx, AV_LOG_DEBUG, "escaping removed %d bytes\n",
+                           (buf_end - buf_ptr) - (dst - s->buffer));
+                }
+                else if(start_code == SOS && s->ls){
+                    uint8_t *src = buf_ptr;
+                    uint8_t *dst = s->buffer;
+                    int bit_count = 0;
+                    int t = 0, b = 0;
+                    PutBitContext pb;
+
+                    s->cur_scan++;
+
+                    /* find marker */
+                    while (src + t < buf_end){
+                        uint8_t x = src[t++];
+                        if (x == 0xff){
+                            while((src + t < buf_end) && x == 0xff)
+                                x = src[t++];
+                            if (x & 0x80) {
+                                t -= 2;
                                 break;
+                            }
                         }
                     }
-                    init_get_bits(&s->gb, s->buffer, (dst - s->buffer)*8);
+                    bit_count = t * 8;
+
+                    init_put_bits(&pb, dst, t);
+
+                    /* unescape bitstream */
+                    while(b < t){
+                        uint8_t x = src[b++];
+                        put_bits(&pb, 8, x);
+                        if(x == 0xFF){
+                            x = src[b++];
+                            put_bits(&pb, 7, x);
+                            bit_count--;
+                        }
+                    }
+                    flush_put_bits(&pb);
 
-                    dprintf("escaping removed %d bytes\n",
-                        (buf_end - buf_ptr) - (dst - s->buffer));
+                    init_get_bits(&s->gb, dst, bit_count);
                 }
                 else
                     init_get_bits(&s->gb, buf_ptr, (buf_end - buf_ptr)*8);
 
                 s->start_code = start_code;
                 if(s->avctx->debug & FF_DEBUG_STARTCODE){
-                    av_log(s->avctx, AV_LOG_DEBUG, "startcode: %X\n", start_code);
+                    av_log(avctx, AV_LOG_DEBUG, "startcode: %X\n", start_code);
                 }
 
                 /* process markers */
                 if (start_code >= 0xd0 && start_code <= 0xd7) {
-                    dprintf("restart marker: %d\n", start_code&0x0f);
+                    av_log(avctx, AV_LOG_DEBUG, "restart marker: %d\n", start_code&0x0f);
                     /* APP fields */
                 } else if (start_code >= APP0 && start_code <= APP15) {
                     mjpeg_decode_app(s);
@@ -1927,7 +2115,6 @@ static int mjpeg_decode_frame(AVCodecContext *avctx,
                 switch(start_code) {
                 case SOI:
                     s->restart_interval = 0;
-                    reset_ls_coding_parameters(s, 1);
 
                     s->restart_count = 0;
                     /* nothing to do on SOI */
@@ -1937,23 +2124,35 @@ static int mjpeg_decode_frame(AVCodecContext *avctx,
                     break;
                 case DHT:
                     if(mjpeg_decode_dht(s) < 0){
-                        av_log(s->avctx, AV_LOG_ERROR, "huffman table decode error\n");
+                        av_log(avctx, AV_LOG_ERROR, "huffman table decode error\n");
                         return -1;
                     }
                     break;
                 case SOF0:
                     s->lossless=0;
+                    s->ls=0;
+                    s->progressive=0;
+                    if (mjpeg_decode_sof(s) < 0)
+                        return -1;
+                    break;
+                case SOF2:
+                    s->lossless=0;
+                    s->ls=0;
+                    s->progressive=1;
                     if (mjpeg_decode_sof(s) < 0)
                         return -1;
                     break;
                 case SOF3:
                     s->lossless=1;
+                    s->ls=0;
+                    s->progressive=0;
                     if (mjpeg_decode_sof(s) < 0)
                         return -1;
                     break;
                 case SOF48:
                     s->lossless=1;
                     s->ls=1;
+                    s->progressive=0;
                     if (mjpeg_decode_sof(s) < 0)
                         return -1;
                     break;
@@ -1962,6 +2161,7 @@ static int mjpeg_decode_frame(AVCodecContext *avctx,
                         return -1;
                     break;
                 case EOI:
+                    s->cur_scan = 0;
                     if ((s->buggy_avid && !s->interlaced) || s->restart_interval)
                         break;
 eoi_parser:
@@ -1969,7 +2169,7 @@ eoi_parser:
                         if (s->interlaced) {
                             s->bottom_field ^= 1;
                             /* if not bottom field, do not output image yet */
-                            if (s->bottom_field)
+                            if (s->bottom_field == !s->interlace_polarity)
                                 goto not_the_end;
                         }
                         *picture = s->picture;
@@ -1981,7 +2181,7 @@ eoi_parser:
                             picture->qscale_table= s->qscale_table;
                             memset(picture->qscale_table, picture->quality, (s->width+15)/16);
                             if(avctx->debug & FF_DEBUG_QP)
-                                av_log(s->avctx, AV_LOG_DEBUG, "QP: %d\n", picture->quality);
+                                av_log(avctx, AV_LOG_DEBUG, "QP: %d\n", picture->quality);
                             picture->quality*= FF_QP2LAMBDA;
                         }
 
@@ -1999,7 +2199,6 @@ eoi_parser:
                     mjpeg_decode_dri(s);
                     break;
                 case SOF1:
-                case SOF2:
                 case SOF5:
                 case SOF6:
                 case SOF7:
@@ -2010,7 +2209,7 @@ eoi_parser:
                 case SOF14:
                 case SOF15:
                 case JPG:
-                    av_log(s->avctx, AV_LOG_ERROR, "mjpeg: unsupported coding type (%x)\n", start_code);
+                    av_log(avctx, AV_LOG_ERROR, "mjpeg: unsupported coding type (%x)\n", start_code);
                     break;
 //                default:
 //                    printf("mjpeg: unsupported marker (%x)\n", start_code);
@@ -2020,13 +2219,13 @@ eoi_parser:
 not_the_end:
                 /* eof process start code */
                 buf_ptr += (get_bits_count(&s->gb)+7)/8;
-                dprintf("marker parser used %d bytes (%d bits)\n",
-                    (get_bits_count(&s->gb)+7)/8, get_bits_count(&s->gb));
+                av_log(avctx, AV_LOG_DEBUG, "marker parser used %d bytes (%d bits)\n",
+                       (get_bits_count(&s->gb)+7)/8, get_bits_count(&s->gb));
             }
         }
     }
 the_end:
-    dprintf("mjpeg decode frame unused %d bytes\n", buf_end - buf_ptr);
+    av_log(avctx, AV_LOG_DEBUG, "mjpeg decode frame unused %d bytes\n", buf_end - buf_ptr);
 //    return buf_end - buf_ptr;
     return buf_ptr - buf;
 }
@@ -2055,22 +2254,20 @@ read_header:
 
     skip_bits(&hgb, 32); /* reserved zeros */
 
-    if (get_bits_long(&hgb, 32) != be2me_32(ff_get_fourcc("mjpg")))
+    if (get_bits_long(&hgb, 32) != MKBETAG('m','j','p','g'))
     {
-        dprintf("not mjpeg-b (bad fourcc)\n");
+        av_log(avctx, AV_LOG_WARNING, "not mjpeg-b (bad fourcc)\n");
         return 0;
     }
 
     field_size = get_bits_long(&hgb, 32); /* field size */
-    dprintf("field size: 0x%x\n", field_size);
+    av_log(avctx, AV_LOG_DEBUG, "field size: 0x%x\n", field_size);
     skip_bits(&hgb, 32); /* padded field size */
     second_field_offs = get_bits_long(&hgb, 32);
-    dprintf("second field offs: 0x%x\n", second_field_offs);
-    if (second_field_offs)
-        s->interlaced = 1;
+    av_log(avctx, AV_LOG_DEBUG, "second field offs: 0x%x\n", second_field_offs);
 
     dqt_offs = get_bits_long(&hgb, 32);
-    dprintf("dqt offs: 0x%x\n", dqt_offs);
+    av_log(avctx, AV_LOG_DEBUG, "dqt offs: 0x%x\n", dqt_offs);
     if (dqt_offs)
     {
         init_get_bits(&s->gb, buf+dqt_offs, (buf_end - (buf+dqt_offs))*8);
@@ -2079,7 +2276,7 @@ read_header:
     }
 
     dht_offs = get_bits_long(&hgb, 32);
-    dprintf("dht offs: 0x%x\n", dht_offs);
+    av_log(avctx, AV_LOG_DEBUG, "dht offs: 0x%x\n", dht_offs);
     if (dht_offs)
     {
         init_get_bits(&s->gb, buf+dht_offs, (buf_end - (buf+dht_offs))*8);
@@ -2088,7 +2285,7 @@ read_header:
     }
 
     sof_offs = get_bits_long(&hgb, 32);
-    dprintf("sof offs: 0x%x\n", sof_offs);
+    av_log(avctx, AV_LOG_DEBUG, "sof offs: 0x%x\n", sof_offs);
     if (sof_offs)
     {
         init_get_bits(&s->gb, buf+sof_offs, (buf_end - (buf+sof_offs))*8);
@@ -2098,9 +2295,9 @@ read_header:
     }
 
     sos_offs = get_bits_long(&hgb, 32);
-    dprintf("sos offs: 0x%x\n", sos_offs);
+    av_log(avctx, AV_LOG_DEBUG, "sos offs: 0x%x\n", sos_offs);
     sod_offs = get_bits_long(&hgb, 32);
-    dprintf("sod offs: 0x%x\n", sod_offs);
+    av_log(avctx, AV_LOG_DEBUG, "sod offs: 0x%x\n", sod_offs);
     if (sos_offs)
     {
 //        init_get_bits(&s->gb, buf+sos_offs, (buf_end - (buf+sos_offs))*8);
@@ -2310,6 +2507,61 @@ static int mjpeg_decode_end(AVCodecContext *avctx)
     return 0;
 }
 
+static int mjpega_dump_header(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args,
+                              uint8_t **poutbuf, int *poutbuf_size,
+                              const uint8_t *buf, int buf_size, int keyframe)
+{
+    uint8_t *poutbufp;
+    int i;
+
+    if (avctx->codec_id != CODEC_ID_MJPEG) {
+        av_log(avctx, AV_LOG_ERROR, "mjpega bitstream filter only applies to mjpeg codec\n");
+        return 0;
+    }
+
+    *poutbuf_size = 0;
+    *poutbuf = av_malloc(buf_size + 44 + FF_INPUT_BUFFER_PADDING_SIZE);
+    poutbufp = *poutbuf;
+    bytestream_put_byte(&poutbufp, 0xff);
+    bytestream_put_byte(&poutbufp, SOI);
+    bytestream_put_byte(&poutbufp, 0xff);
+    bytestream_put_byte(&poutbufp, APP1);
+    bytestream_put_be16(&poutbufp, 42); /* size */
+    bytestream_put_be32(&poutbufp, 0);
+    bytestream_put_buffer(&poutbufp, "mjpg", 4);
+    bytestream_put_be32(&poutbufp, buf_size + 44); /* field size */
+    bytestream_put_be32(&poutbufp, buf_size + 44); /* pad field size */
+    bytestream_put_be32(&poutbufp, 0);             /* next ptr */
+
+    for (i = 0; i < buf_size - 1; i++) {
+        if (buf[i] == 0xff) {
+            switch (buf[i + 1]) {
+            case DQT:  /* quant off */
+            case DHT:  /* huff  off */
+            case SOF0: /* image off */
+                bytestream_put_be32(&poutbufp, i + 46);
+                break;
+            case SOS:
+                bytestream_put_be32(&poutbufp, i + 46); /* scan off */
+                bytestream_put_be32(&poutbufp, i + 46 + AV_RB16(buf + i + 2)); /* data off */
+                bytestream_put_buffer(&poutbufp, buf + 2, buf_size - 2); /* skip already written SOI */
+                *poutbuf_size = poutbufp - *poutbuf;
+                return 1;
+            case APP1:
+                if (i + 8 < buf_size && AV_RL32(buf + i + 8) == ff_get_fourcc("mjpg")) {
+                    av_log(avctx, AV_LOG_ERROR, "bitstream already formatted\n");
+                    memcpy(*poutbuf, buf, buf_size);
+                    *poutbuf_size = buf_size;
+                    return 1;
+                }
+            }
+        }
+    }
+    av_freep(poutbuf);
+    av_log(avctx, AV_LOG_ERROR, "could not find SOS marker in bitstream\n");
+    return 0;
+}
+
 AVCodec mjpeg_decoder = {
     "mjpeg",
     CODEC_TYPE_VIDEO,
@@ -2323,6 +2575,19 @@ AVCodec mjpeg_decoder = {
     NULL
 };
 
+AVCodec thp_decoder = {
+    "thp",
+    CODEC_TYPE_VIDEO,
+    CODEC_ID_THP,
+    sizeof(MJpegDecodeContext),
+    mjpeg_decode_init,
+    NULL,
+    mjpeg_decode_end,
+    mjpeg_decode_frame,
+    CODEC_CAP_DR1,
+    NULL
+};
+
 AVCodec mjpegb_decoder = {
     "mjpegb",
     CODEC_TYPE_VIDEO,
@@ -2361,6 +2626,7 @@ AVCodec ljpeg_encoder = { //FIXME avoid MPV_* lossless jpeg shouldnt need them
 };
 #endif
 
+#ifdef CONFIG_MJPEG_PARSER
 AVCodecParser mjpeg_parser = {
     { CODEC_ID_MJPEG },
     sizeof(ParseContext),
@@ -2368,4 +2634,10 @@ AVCodecParser mjpeg_parser = {
     jpeg_parse,
     ff_parse_close,
 };
+#endif
 
+AVBitStreamFilter mjpega_dump_header_bsf = {
+    "mjpegadump",
+    0,
+    mjpega_dump_header,
+};