00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00028 #include "avcodec.h"
00029 #include "dsputil.h"
00030 #include "get_bits.h"
00031 #include "libavutil/intreadwrite.h"
00032
00033 typedef struct JvContext {
00034 DSPContext dsp;
00035 AVFrame frame;
00036 uint32_t palette[AVPALETTE_COUNT];
00037 int palette_has_changed;
00038 } JvContext;
00039
00040 static av_cold int decode_init(AVCodecContext *avctx)
00041 {
00042 JvContext *s = avctx->priv_data;
00043 avctx->pix_fmt = PIX_FMT_PAL8;
00044 dsputil_init(&s->dsp, avctx);
00045 return 0;
00046 }
00047
00051 static inline void decode2x2(GetBitContext *gb, uint8_t *dst, int linesize)
00052 {
00053 int i, j, v[2];
00054
00055 switch (get_bits(gb, 2)) {
00056 case 1:
00057 v[0] = get_bits(gb, 8);
00058 for (j = 0; j < 2; j++)
00059 memset(dst + j*linesize, v[0], 2);
00060 break;
00061 case 2:
00062 v[0] = get_bits(gb, 8);
00063 v[1] = get_bits(gb, 8);
00064 for (j = 0; j < 2; j++)
00065 for (i = 0; i < 2; i++)
00066 dst[j*linesize + i] = v[get_bits1(gb)];
00067 break;
00068 case 3:
00069 for (j = 0; j < 2; j++)
00070 for (i = 0; i < 2; i++)
00071 dst[j*linesize + i] = get_bits(gb, 8);
00072 }
00073 }
00074
00078 static inline void decode4x4(GetBitContext *gb, uint8_t *dst, int linesize)
00079 {
00080 int i, j, v[2];
00081
00082 switch (get_bits(gb, 2)) {
00083 case 1:
00084 v[0] = get_bits(gb, 8);
00085 for (j = 0; j < 4; j++)
00086 memset(dst + j*linesize, v[0], 4);
00087 break;
00088 case 2:
00089 v[0] = get_bits(gb, 8);
00090 v[1] = get_bits(gb, 8);
00091 for (j = 2; j >= 0; j -= 2) {
00092 for (i = 0; i < 4; i++)
00093 dst[j*linesize + i] = v[get_bits1(gb)];
00094 for (i = 0; i < 4; i++)
00095 dst[(j+1)*linesize + i] = v[get_bits1(gb)];
00096 }
00097 break;
00098 case 3:
00099 for (j = 0; j < 4; j += 2)
00100 for (i = 0; i < 4; i += 2)
00101 decode2x2(gb, dst + j*linesize + i, linesize);
00102 }
00103 }
00104
00108 static inline void decode8x8(GetBitContext *gb, uint8_t *dst, int linesize, DSPContext *dsp)
00109 {
00110 int i, j, v[2];
00111
00112 switch (get_bits(gb, 2)) {
00113 case 1:
00114 v[0] = get_bits(gb, 8);
00115 dsp->fill_block_tab[1](dst, v[0], linesize, 8);
00116 break;
00117 case 2:
00118 v[0] = get_bits(gb, 8);
00119 v[1] = get_bits(gb, 8);
00120 for (j = 7; j >= 0; j--)
00121 for (i = 0; i < 8; i++)
00122 dst[j*linesize + i] = v[get_bits1(gb)];
00123 break;
00124 case 3:
00125 for (j = 0; j < 8; j += 4)
00126 for (i = 0; i < 8; i += 4)
00127 decode4x4(gb, dst + j*linesize + i, linesize);
00128 }
00129 }
00130
00131 static int decode_frame(AVCodecContext *avctx,
00132 void *data, int *data_size,
00133 AVPacket *avpkt)
00134 {
00135 JvContext *s = avctx->priv_data;
00136 int buf_size = avpkt->size;
00137 const uint8_t *buf = avpkt->data;
00138 const uint8_t *buf_end = buf + buf_size;
00139 int video_size, video_type, i, j;
00140
00141 video_size = AV_RL32(buf);
00142 video_type = buf[4];
00143 buf += 5;
00144
00145 if (video_size) {
00146 if(video_size < 0) {
00147 av_log(avctx, AV_LOG_ERROR, "video size %d invalid\n", video_size);
00148 return AVERROR_INVALIDDATA;
00149 }
00150 if (avctx->reget_buffer(avctx, &s->frame) < 0) {
00151 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00152 return -1;
00153 }
00154
00155 if (video_type == 0 || video_type == 1) {
00156 GetBitContext gb;
00157 init_get_bits(&gb, buf, 8 * FFMIN(video_size, buf_end - buf));
00158
00159 for (j = 0; j < avctx->height; j += 8)
00160 for (i = 0; i < avctx->width; i += 8)
00161 decode8x8(&gb, s->frame.data[0] + j*s->frame.linesize[0] + i,
00162 s->frame.linesize[0], &s->dsp);
00163
00164 buf += video_size;
00165 } else if (video_type == 2) {
00166 if (buf + 1 <= buf_end) {
00167 int v = *buf++;
00168 for (j = 0; j < avctx->height; j++)
00169 memset(s->frame.data[0] + j*s->frame.linesize[0], v, avctx->width);
00170 }
00171 } else {
00172 av_log(avctx, AV_LOG_WARNING, "unsupported frame type %i\n", video_type);
00173 return AVERROR_INVALIDDATA;
00174 }
00175 }
00176
00177 if (buf < buf_end) {
00178 for (i = 0; i < AVPALETTE_COUNT && buf + 3 <= buf_end; i++) {
00179 s->palette[i] = AV_RB24(buf) << 2;
00180 buf += 3;
00181 }
00182 s->palette_has_changed = 1;
00183 }
00184
00185 if (video_size) {
00186 s->frame.key_frame = 1;
00187 s->frame.pict_type = AV_PICTURE_TYPE_I;
00188 s->frame.palette_has_changed = s->palette_has_changed;
00189 s->palette_has_changed = 0;
00190 memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
00191
00192 *data_size = sizeof(AVFrame);
00193 *(AVFrame*)data = s->frame;
00194 }
00195
00196 return buf_size;
00197 }
00198
00199 static av_cold int decode_close(AVCodecContext *avctx)
00200 {
00201 JvContext *s = avctx->priv_data;
00202
00203 if(s->frame.data[0])
00204 avctx->release_buffer(avctx, &s->frame);
00205
00206 return 0;
00207 }
00208
00209 AVCodec ff_jv_decoder = {
00210 .name = "jv",
00211 .long_name = NULL_IF_CONFIG_SMALL("Bitmap Brothers JV video"),
00212 .type = AVMEDIA_TYPE_VIDEO,
00213 .id = CODEC_ID_JV,
00214 .priv_data_size = sizeof(JvContext),
00215 .init = decode_init,
00216 .close = decode_close,
00217 .decode = decode_frame,
00218 .capabilities = CODEC_CAP_DR1,
00219 };