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
00046 if (!avctx->width || !avctx->height ||
00047 (avctx->width & 7) || (avctx->height & 7)) {
00048 av_log(avctx, AV_LOG_ERROR, "Invalid video dimensions: %dx%d\n",
00049 avctx->width, avctx->height);
00050 return AVERROR(EINVAL);
00051 }
00052
00053 return 0;
00054 }
00055
00059 static inline void decode2x2(GetBitContext *gb, uint8_t *dst, int linesize)
00060 {
00061 int i, j, v[2];
00062
00063 switch (get_bits(gb, 2)) {
00064 case 1:
00065 v[0] = get_bits(gb, 8);
00066 for (j = 0; j < 2; j++)
00067 memset(dst + j*linesize, v[0], 2);
00068 break;
00069 case 2:
00070 v[0] = get_bits(gb, 8);
00071 v[1] = get_bits(gb, 8);
00072 for (j = 0; j < 2; j++)
00073 for (i = 0; i < 2; i++)
00074 dst[j*linesize + i] = v[get_bits1(gb)];
00075 break;
00076 case 3:
00077 for (j = 0; j < 2; j++)
00078 for (i = 0; i < 2; i++)
00079 dst[j*linesize + i] = get_bits(gb, 8);
00080 }
00081 }
00082
00086 static inline void decode4x4(GetBitContext *gb, uint8_t *dst, int linesize)
00087 {
00088 int i, j, v[2];
00089
00090 switch (get_bits(gb, 2)) {
00091 case 1:
00092 v[0] = get_bits(gb, 8);
00093 for (j = 0; j < 4; j++)
00094 memset(dst + j*linesize, v[0], 4);
00095 break;
00096 case 2:
00097 v[0] = get_bits(gb, 8);
00098 v[1] = get_bits(gb, 8);
00099 for (j = 2; j >= 0; j -= 2) {
00100 for (i = 0; i < 4; i++)
00101 dst[j*linesize + i] = v[get_bits1(gb)];
00102 for (i = 0; i < 4; i++)
00103 dst[(j+1)*linesize + i] = v[get_bits1(gb)];
00104 }
00105 break;
00106 case 3:
00107 for (j = 0; j < 4; j += 2)
00108 for (i = 0; i < 4; i += 2)
00109 decode2x2(gb, dst + j*linesize + i, linesize);
00110 }
00111 }
00112
00116 static inline void decode8x8(GetBitContext *gb, uint8_t *dst, int linesize, DSPContext *dsp)
00117 {
00118 int i, j, v[2];
00119
00120 switch (get_bits(gb, 2)) {
00121 case 1:
00122 v[0] = get_bits(gb, 8);
00123 dsp->fill_block_tab[1](dst, v[0], linesize, 8);
00124 break;
00125 case 2:
00126 v[0] = get_bits(gb, 8);
00127 v[1] = get_bits(gb, 8);
00128 for (j = 7; j >= 0; j--)
00129 for (i = 0; i < 8; i++)
00130 dst[j*linesize + i] = v[get_bits1(gb)];
00131 break;
00132 case 3:
00133 for (j = 0; j < 8; j += 4)
00134 for (i = 0; i < 8; i += 4)
00135 decode4x4(gb, dst + j*linesize + i, linesize);
00136 }
00137 }
00138
00139 static int decode_frame(AVCodecContext *avctx,
00140 void *data, int *data_size,
00141 AVPacket *avpkt)
00142 {
00143 JvContext *s = avctx->priv_data;
00144 int buf_size = avpkt->size;
00145 const uint8_t *buf = avpkt->data;
00146 const uint8_t *buf_end = buf + buf_size;
00147 int video_size, video_type, i, j;
00148
00149 video_size = AV_RL32(buf);
00150 video_type = buf[4];
00151 buf += 5;
00152
00153 if (video_size) {
00154 if (avctx->reget_buffer(avctx, &s->frame) < 0) {
00155 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00156 return -1;
00157 }
00158
00159 if (video_type == 0 || video_type == 1) {
00160 GetBitContext gb;
00161 init_get_bits(&gb, buf, 8 * FFMIN(video_size, buf_end - buf));
00162
00163 for (j = 0; j < avctx->height; j += 8)
00164 for (i = 0; i < avctx->width; i += 8)
00165 decode8x8(&gb, s->frame.data[0] + j*s->frame.linesize[0] + i,
00166 s->frame.linesize[0], &s->dsp);
00167
00168 buf += video_size;
00169 } else if (video_type == 2) {
00170 if (buf + 1 <= buf_end) {
00171 int v = *buf++;
00172 for (j = 0; j < avctx->height; j++)
00173 memset(s->frame.data[0] + j*s->frame.linesize[0], v, avctx->width);
00174 }
00175 } else {
00176 av_log(avctx, AV_LOG_WARNING, "unsupported frame type %i\n", video_type);
00177 return AVERROR_INVALIDDATA;
00178 }
00179 }
00180
00181 if (buf < buf_end) {
00182 for (i = 0; i < AVPALETTE_COUNT && buf + 3 <= buf_end; i++) {
00183 s->palette[i] = AV_RB24(buf) << 2;
00184 buf += 3;
00185 }
00186 s->palette_has_changed = 1;
00187 }
00188
00189 if (video_size) {
00190 s->frame.key_frame = 1;
00191 s->frame.pict_type = AV_PICTURE_TYPE_I;
00192 s->frame.palette_has_changed = s->palette_has_changed;
00193 s->palette_has_changed = 0;
00194 memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
00195
00196 *data_size = sizeof(AVFrame);
00197 *(AVFrame*)data = s->frame;
00198 }
00199
00200 return buf_size;
00201 }
00202
00203 static av_cold int decode_close(AVCodecContext *avctx)
00204 {
00205 JvContext *s = avctx->priv_data;
00206
00207 if(s->frame.data[0])
00208 avctx->release_buffer(avctx, &s->frame);
00209
00210 return 0;
00211 }
00212
00213 AVCodec ff_jv_decoder = {
00214 .name = "jv",
00215 .long_name = NULL_IF_CONFIG_SMALL("Bitmap Brothers JV video"),
00216 .type = AVMEDIA_TYPE_VIDEO,
00217 .id = CODEC_ID_JV,
00218 .priv_data_size = sizeof(JvContext),
00219 .init = decode_init,
00220 .close = decode_close,
00221 .decode = decode_frame,
00222 .capabilities = CODEC_CAP_DR1,
00223 };