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 = AV_PIX_FMT_PAL8;
00044 ff_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 *got_frame,
00133 AVPacket *avpkt)
00134 {
00135 JvContext *s = avctx->priv_data;
00136 const uint8_t *buf = avpkt->data;
00137 const uint8_t *buf_end = buf + avpkt->size;
00138 int video_size, video_type, ret, i, j;
00139
00140 if (avpkt->size < 6)
00141 return AVERROR_INVALIDDATA;
00142
00143 video_size = AV_RL32(buf);
00144 video_type = buf[4];
00145 buf += 5;
00146
00147 if (video_size) {
00148 if (video_size < 0 || video_size > avpkt->size - 5) {
00149 av_log(avctx, AV_LOG_ERROR, "video size %d invalid\n", video_size);
00150 return AVERROR_INVALIDDATA;
00151 }
00152 if ((ret = avctx->reget_buffer(avctx, &s->frame)) < 0) {
00153 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00154 return ret;
00155 }
00156
00157 if (video_type == 0 || video_type == 1) {
00158 GetBitContext gb;
00159 init_get_bits(&gb, buf, 8 * video_size);
00160
00161 for (j = 0; j < avctx->height; j += 8)
00162 for (i = 0; i < avctx->width; i += 8)
00163 decode8x8(&gb, s->frame.data[0] + j*s->frame.linesize[0] + i,
00164 s->frame.linesize[0], &s->dsp);
00165
00166 buf += video_size;
00167 } else if (video_type == 2) {
00168 int v = *buf++;
00169 for (j = 0; j < avctx->height; j++)
00170 memset(s->frame.data[0] + j*s->frame.linesize[0], v, avctx->width);
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_end - buf >= AVPALETTE_COUNT * 3) {
00178 for (i = 0; i < AVPALETTE_COUNT; i++) {
00179 uint32_t pal = AV_RB24(buf);
00180 s->palette[i] = 0xFFU << 24 | pal << 2 | ((pal >> 4) & 0x30303);
00181 buf += 3;
00182 }
00183 s->palette_has_changed = 1;
00184 }
00185
00186 if (video_size) {
00187 s->frame.key_frame = 1;
00188 s->frame.pict_type = AV_PICTURE_TYPE_I;
00189 s->frame.palette_has_changed = s->palette_has_changed;
00190 s->palette_has_changed = 0;
00191 memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
00192
00193 *got_frame = 1;
00194 *(AVFrame*)data = s->frame;
00195 }
00196
00197 return avpkt->size;
00198 }
00199
00200 static av_cold int decode_close(AVCodecContext *avctx)
00201 {
00202 JvContext *s = avctx->priv_data;
00203
00204 if(s->frame.data[0])
00205 avctx->release_buffer(avctx, &s->frame);
00206
00207 return 0;
00208 }
00209
00210 AVCodec ff_jv_decoder = {
00211 .name = "jv",
00212 .long_name = NULL_IF_CONFIG_SMALL("Bitmap Brothers JV video"),
00213 .type = AVMEDIA_TYPE_VIDEO,
00214 .id = AV_CODEC_ID_JV,
00215 .priv_data_size = sizeof(JvContext),
00216 .init = decode_init,
00217 .close = decode_close,
00218 .decode = decode_frame,
00219 .capabilities = CODEC_CAP_DR1,
00220 };