kmvc.c
Go to the documentation of this file.
1 /*
2  * KMVC decoder
3  * Copyright (c) 2006 Konstantin Shishkov
4  *
5  * This file is part of Libav.
6  *
7  * Libav is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * Libav is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with Libav; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
27 #include <stdio.h>
28 #include <stdlib.h>
29 
30 #include "avcodec.h"
31 #include "bytestream.h"
32 
33 #define KMVC_KEYFRAME 0x80
34 #define KMVC_PALETTE 0x40
35 #define KMVC_METHOD 0x0F
36 #define MAX_PALSIZE 256
37 
38 /*
39  * Decoder context
40  */
41 typedef struct KmvcContext {
44 
45  int setpal;
46  int palsize;
47  uint32_t pal[MAX_PALSIZE];
48  uint8_t *cur, *prev;
49  uint8_t *frm0, *frm1;
51 } KmvcContext;
52 
53 typedef struct BitBuf {
54  int bits;
55  int bitbuf;
56 } BitBuf;
57 
58 #define BLK(data, x, y) data[(x) + (y) * 320]
59 
60 #define kmvc_init_getbits(bb, g) bb.bits = 7; bb.bitbuf = bytestream2_get_byte(g);
61 
62 #define kmvc_getbit(bb, g, res) {\
63  res = 0; \
64  if (bb.bitbuf & (1 << bb.bits)) res = 1; \
65  bb.bits--; \
66  if(bb.bits == -1) { \
67  bb.bitbuf = bytestream2_get_byte(g); \
68  bb.bits = 7; \
69  } \
70 }
71 
72 static int kmvc_decode_intra_8x8(KmvcContext * ctx, int w, int h)
73 {
74  BitBuf bb;
75  int res, val;
76  int i, j;
77  int bx, by;
78  int l0x, l1x, l0y, l1y;
79  int mx, my;
80 
81  kmvc_init_getbits(bb, &ctx->g);
82 
83  for (by = 0; by < h; by += 8)
84  for (bx = 0; bx < w; bx += 8) {
85  if (!bytestream2_get_bytes_left(&ctx->g)) {
86  av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
87  return AVERROR_INVALIDDATA;
88  }
89  kmvc_getbit(bb, &ctx->g, res);
90  if (!res) { // fill whole 8x8 block
91  val = bytestream2_get_byte(&ctx->g);
92  for (i = 0; i < 64; i++)
93  BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) = val;
94  } else { // handle four 4x4 subblocks
95  for (i = 0; i < 4; i++) {
96  l0x = bx + (i & 1) * 4;
97  l0y = by + (i & 2) * 2;
98  kmvc_getbit(bb, &ctx->g, res);
99  if (!res) {
100  kmvc_getbit(bb, &ctx->g, res);
101  if (!res) { // fill whole 4x4 block
102  val = bytestream2_get_byte(&ctx->g);
103  for (j = 0; j < 16; j++)
104  BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) = val;
105  } else { // copy block from already decoded place
106  val = bytestream2_get_byte(&ctx->g);
107  mx = val & 0xF;
108  my = val >> 4;
109  for (j = 0; j < 16; j++)
110  BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) =
111  BLK(ctx->cur, l0x + (j & 3) - mx, l0y + (j >> 2) - my);
112  }
113  } else { // descend to 2x2 sub-sub-blocks
114  for (j = 0; j < 4; j++) {
115  l1x = l0x + (j & 1) * 2;
116  l1y = l0y + (j & 2);
117  kmvc_getbit(bb, &ctx->g, res);
118  if (!res) {
119  kmvc_getbit(bb, &ctx->g, res);
120  if (!res) { // fill whole 2x2 block
121  val = bytestream2_get_byte(&ctx->g);
122  BLK(ctx->cur, l1x, l1y) = val;
123  BLK(ctx->cur, l1x + 1, l1y) = val;
124  BLK(ctx->cur, l1x, l1y + 1) = val;
125  BLK(ctx->cur, l1x + 1, l1y + 1) = val;
126  } else { // copy block from already decoded place
127  val = bytestream2_get_byte(&ctx->g);
128  mx = val & 0xF;
129  my = val >> 4;
130  BLK(ctx->cur, l1x, l1y) = BLK(ctx->cur, l1x - mx, l1y - my);
131  BLK(ctx->cur, l1x + 1, l1y) =
132  BLK(ctx->cur, l1x + 1 - mx, l1y - my);
133  BLK(ctx->cur, l1x, l1y + 1) =
134  BLK(ctx->cur, l1x - mx, l1y + 1 - my);
135  BLK(ctx->cur, l1x + 1, l1y + 1) =
136  BLK(ctx->cur, l1x + 1 - mx, l1y + 1 - my);
137  }
138  } else { // read values for block
139  BLK(ctx->cur, l1x, l1y) = bytestream2_get_byte(&ctx->g);
140  BLK(ctx->cur, l1x + 1, l1y) = bytestream2_get_byte(&ctx->g);
141  BLK(ctx->cur, l1x, l1y + 1) = bytestream2_get_byte(&ctx->g);
142  BLK(ctx->cur, l1x + 1, l1y + 1) = bytestream2_get_byte(&ctx->g);
143  }
144  }
145  }
146  }
147  }
148  }
149 
150  return 0;
151 }
152 
153 static int kmvc_decode_inter_8x8(KmvcContext * ctx, int w, int h)
154 {
155  BitBuf bb;
156  int res, val;
157  int i, j;
158  int bx, by;
159  int l0x, l1x, l0y, l1y;
160  int mx, my;
161 
162  kmvc_init_getbits(bb, &ctx->g);
163 
164  for (by = 0; by < h; by += 8)
165  for (bx = 0; bx < w; bx += 8) {
166  kmvc_getbit(bb, &ctx->g, res);
167  if (!res) {
168  kmvc_getbit(bb, &ctx->g, res);
169  if (!res) { // fill whole 8x8 block
170  if (!bytestream2_get_bytes_left(&ctx->g)) {
171  av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
172  return AVERROR_INVALIDDATA;
173  }
174  val = bytestream2_get_byte(&ctx->g);
175  for (i = 0; i < 64; i++)
176  BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) = val;
177  } else { // copy block from previous frame
178  for (i = 0; i < 64; i++)
179  BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) =
180  BLK(ctx->prev, bx + (i & 0x7), by + (i >> 3));
181  }
182  } else { // handle four 4x4 subblocks
183  if (!bytestream2_get_bytes_left(&ctx->g)) {
184  av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
185  return AVERROR_INVALIDDATA;
186  }
187  for (i = 0; i < 4; i++) {
188  l0x = bx + (i & 1) * 4;
189  l0y = by + (i & 2) * 2;
190  kmvc_getbit(bb, &ctx->g, res);
191  if (!res) {
192  kmvc_getbit(bb, &ctx->g, res);
193  if (!res) { // fill whole 4x4 block
194  val = bytestream2_get_byte(&ctx->g);
195  for (j = 0; j < 16; j++)
196  BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) = val;
197  } else { // copy block
198  val = bytestream2_get_byte(&ctx->g);
199  mx = (val & 0xF) - 8;
200  my = (val >> 4) - 8;
201  for (j = 0; j < 16; j++)
202  BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) =
203  BLK(ctx->prev, l0x + (j & 3) + mx, l0y + (j >> 2) + my);
204  }
205  } else { // descend to 2x2 sub-sub-blocks
206  for (j = 0; j < 4; j++) {
207  l1x = l0x + (j & 1) * 2;
208  l1y = l0y + (j & 2);
209  kmvc_getbit(bb, &ctx->g, res);
210  if (!res) {
211  kmvc_getbit(bb, &ctx->g, res);
212  if (!res) { // fill whole 2x2 block
213  val = bytestream2_get_byte(&ctx->g);
214  BLK(ctx->cur, l1x, l1y) = val;
215  BLK(ctx->cur, l1x + 1, l1y) = val;
216  BLK(ctx->cur, l1x, l1y + 1) = val;
217  BLK(ctx->cur, l1x + 1, l1y + 1) = val;
218  } else { // copy block
219  val = bytestream2_get_byte(&ctx->g);
220  mx = (val & 0xF) - 8;
221  my = (val >> 4) - 8;
222  BLK(ctx->cur, l1x, l1y) = BLK(ctx->prev, l1x + mx, l1y + my);
223  BLK(ctx->cur, l1x + 1, l1y) =
224  BLK(ctx->prev, l1x + 1 + mx, l1y + my);
225  BLK(ctx->cur, l1x, l1y + 1) =
226  BLK(ctx->prev, l1x + mx, l1y + 1 + my);
227  BLK(ctx->cur, l1x + 1, l1y + 1) =
228  BLK(ctx->prev, l1x + 1 + mx, l1y + 1 + my);
229  }
230  } else { // read values for block
231  BLK(ctx->cur, l1x, l1y) = bytestream2_get_byte(&ctx->g);
232  BLK(ctx->cur, l1x + 1, l1y) = bytestream2_get_byte(&ctx->g);
233  BLK(ctx->cur, l1x, l1y + 1) = bytestream2_get_byte(&ctx->g);
234  BLK(ctx->cur, l1x + 1, l1y + 1) = bytestream2_get_byte(&ctx->g);
235  }
236  }
237  }
238  }
239  }
240  }
241 
242  return 0;
243 }
244 
245 static int decode_frame(AVCodecContext * avctx, void *data, int *data_size, AVPacket *avpkt)
246 {
247  KmvcContext *const ctx = avctx->priv_data;
248  uint8_t *out, *src;
249  int i;
250  int header;
251  int blocksize;
252  const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
253 
254  bytestream2_init(&ctx->g, avpkt->data, avpkt->size);
255  if (ctx->pic.data[0])
256  avctx->release_buffer(avctx, &ctx->pic);
257 
258  ctx->pic.reference = 1;
260  if (avctx->get_buffer(avctx, &ctx->pic) < 0) {
261  av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
262  return -1;
263  }
264 
265  header = bytestream2_get_byte(&ctx->g);
266 
267  /* blocksize 127 is really palette change event */
268  if (bytestream2_peek_byte(&ctx->g) == 127) {
269  bytestream2_skip(&ctx->g, 3);
270  for (i = 0; i < 127; i++) {
271  ctx->pal[i + (header & 0x81)] = bytestream2_get_be24(&ctx->g);
272  bytestream2_skip(&ctx->g, 1);
273  }
274  bytestream2_seek(&ctx->g, -127 * 4 - 3, SEEK_CUR);
275  }
276 
277  if (header & KMVC_KEYFRAME) {
278  ctx->pic.key_frame = 1;
280  } else {
281  ctx->pic.key_frame = 0;
283  }
284 
285  if (header & KMVC_PALETTE) {
286  ctx->pic.palette_has_changed = 1;
287  // palette starts from index 1 and has 127 entries
288  for (i = 1; i <= ctx->palsize; i++) {
289  ctx->pal[i] = bytestream2_get_be24(&ctx->g);
290  }
291  }
292 
293  if (pal) {
294  ctx->pic.palette_has_changed = 1;
295  memcpy(ctx->pal, pal, AVPALETTE_SIZE);
296  }
297 
298  if (ctx->setpal) {
299  ctx->setpal = 0;
300  ctx->pic.palette_has_changed = 1;
301  }
302 
303  /* make the palette available on the way out */
304  memcpy(ctx->pic.data[1], ctx->pal, 1024);
305 
306  blocksize = bytestream2_get_byte(&ctx->g);
307 
308  if (blocksize != 8 && blocksize != 127) {
309  av_log(avctx, AV_LOG_ERROR, "Block size = %i\n", blocksize);
310  return -1;
311  }
312  memset(ctx->cur, 0, 320 * 200);
313  switch (header & KMVC_METHOD) {
314  case 0:
315  case 1: // used in palette changed event
316  memcpy(ctx->cur, ctx->prev, 320 * 200);
317  break;
318  case 3:
319  kmvc_decode_intra_8x8(ctx, avctx->width, avctx->height);
320  break;
321  case 4:
322  kmvc_decode_inter_8x8(ctx, avctx->width, avctx->height);
323  break;
324  default:
325  av_log(avctx, AV_LOG_ERROR, "Unknown compression method %i\n", header & KMVC_METHOD);
326  return -1;
327  }
328 
329  out = ctx->pic.data[0];
330  src = ctx->cur;
331  for (i = 0; i < avctx->height; i++) {
332  memcpy(out, src, avctx->width);
333  src += 320;
334  out += ctx->pic.linesize[0];
335  }
336 
337  /* flip buffers */
338  if (ctx->cur == ctx->frm0) {
339  ctx->cur = ctx->frm1;
340  ctx->prev = ctx->frm0;
341  } else {
342  ctx->cur = ctx->frm0;
343  ctx->prev = ctx->frm1;
344  }
345 
346  *data_size = sizeof(AVFrame);
347  *(AVFrame *) data = ctx->pic;
348 
349  /* always report that the buffer was completely consumed */
350  return avpkt->size;
351 }
352 
353 
354 
355 /*
356  * Init kmvc decoder
357  */
358 static av_cold int decode_init(AVCodecContext * avctx)
359 {
360  KmvcContext *const c = avctx->priv_data;
361  int i;
362 
363  c->avctx = avctx;
364 
365  if (avctx->width > 320 || avctx->height > 200) {
366  av_log(avctx, AV_LOG_ERROR, "KMVC supports frames <= 320x200\n");
367  return -1;
368  }
369 
370  c->frm0 = av_mallocz(320 * 200);
371  c->frm1 = av_mallocz(320 * 200);
372  c->cur = c->frm0;
373  c->prev = c->frm1;
374 
375  for (i = 0; i < 256; i++) {
376  c->pal[i] = i * 0x10101;
377  }
378 
379  if (avctx->extradata_size < 12) {
380  av_log(NULL, 0, "Extradata missing, decoding may not work properly...\n");
381  c->palsize = 127;
382  } else {
383  c->palsize = AV_RL16(avctx->extradata + 10);
384  if (c->palsize >= MAX_PALSIZE) {
385  av_log(avctx, AV_LOG_ERROR, "KMVC palette too large\n");
386  return AVERROR_INVALIDDATA;
387  }
388  }
389 
390  if (avctx->extradata_size == 1036) { // palette in extradata
391  uint8_t *src = avctx->extradata + 12;
392  for (i = 0; i < 256; i++) {
393  c->pal[i] = AV_RL32(src);
394  src += 4;
395  }
396  c->setpal = 1;
397  }
398 
399  avctx->pix_fmt = PIX_FMT_PAL8;
400 
401  return 0;
402 }
403 
404 
405 
406 /*
407  * Uninit kmvc decoder
408  */
409 static av_cold int decode_end(AVCodecContext * avctx)
410 {
411  KmvcContext *const c = avctx->priv_data;
412 
413  av_freep(&c->frm0);
414  av_freep(&c->frm1);
415  if (c->pic.data[0])
416  avctx->release_buffer(avctx, &c->pic);
417 
418  return 0;
419 }
420 
422  .name = "kmvc",
423  .type = AVMEDIA_TYPE_VIDEO,
424  .id = CODEC_ID_KMVC,
425  .priv_data_size = sizeof(KmvcContext),
426  .init = decode_init,
427  .close = decode_end,
428  .decode = decode_frame,
429  .capabilities = CODEC_CAP_DR1,
430  .long_name = NULL_IF_CONFIG_SMALL("Karl Morton's video codec"),
431 };