libavcodec/bfi.c
Go to the documentation of this file.
1 /*
2  * Brute Force & Ignorance (BFI) video decoder
3  * Copyright (c) 2008 Sisir Koppaka
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg 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  * FFmpeg 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 FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 /**
23  * @file
24  * @brief Brute Force & Ignorance (.bfi) video decoder
25  * @author Sisir Koppaka ( sisir.koppaka at gmail dot com )
26  * @see http://wiki.multimedia.cx/index.php?title=BFI
27  */
28 
29 #include "libavutil/common.h"
30 #include "avcodec.h"
31 #include "bytestream.h"
32 #include "internal.h"
33 
34 typedef struct BFIContext {
37  uint32_t pal[256];
38 } BFIContext;
39 
41 {
42  BFIContext *bfi = avctx->priv_data;
43  avctx->pix_fmt = AV_PIX_FMT_PAL8;
44  bfi->dst = av_mallocz(avctx->width * avctx->height);
45  return 0;
46 }
47 
49  int *got_frame, AVPacket *avpkt)
50 {
51  AVFrame *frame = data;
53  int buf_size = avpkt->size;
54  BFIContext *bfi = avctx->priv_data;
55  uint8_t *dst = bfi->dst;
56  uint8_t *src, *dst_offset, colour1, colour2;
57  uint8_t *frame_end = bfi->dst + avctx->width * avctx->height;
58  uint32_t *pal;
59  int i, j, ret, height = avctx->height;
60 
61  if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
62  return ret;
63 
64  bytestream2_init(&g, avpkt->data, buf_size);
65 
66  /* Set frame parameters and palette, if necessary */
67  if (!avctx->frame_number) {
69  frame->key_frame = 1;
70  /* Setting the palette */
71  if (avctx->extradata_size > 768) {
72  av_log(NULL, AV_LOG_ERROR, "Palette is too large.\n");
73  return AVERROR_INVALIDDATA;
74  }
75  pal = (uint32_t *)frame->data[1];
76  for (i = 0; i < avctx->extradata_size / 3; i++) {
77  int shift = 16;
78  *pal = 0xFFU << 24;
79  for (j = 0; j < 3; j++, shift -= 8)
80  *pal += ((avctx->extradata[i * 3 + j] << 2) |
81  (avctx->extradata[i * 3 + j] >> 4)) << shift;
82  pal++;
83  }
84  memcpy(bfi->pal, frame->data[1], sizeof(bfi->pal));
85  frame->palette_has_changed = 1;
86  } else {
88  frame->key_frame = 0;
89  frame->palette_has_changed = 0;
90  memcpy(frame->data[1], bfi->pal, sizeof(bfi->pal));
91  }
92 
93  bytestream2_skip(&g, 4); // Unpacked size, not required.
94 
95  while (dst != frame_end) {
96  static const uint8_t lentab[4] = { 0, 2, 0, 1 };
97  unsigned int byte = bytestream2_get_byte(&g), av_uninit(offset);
98  unsigned int code = byte >> 6;
99  unsigned int length = byte & ~0xC0;
100 
101  if (!bytestream2_get_bytes_left(&g)) {
102  av_log(avctx, AV_LOG_ERROR,
103  "Input resolution larger than actual frame.\n");
104  return AVERROR_INVALIDDATA;
105  }
106 
107  /* Get length and offset (if required) */
108  if (length == 0) {
109  if (code == 1) {
110  length = bytestream2_get_byte(&g);
111  offset = bytestream2_get_le16(&g);
112  } else {
113  length = bytestream2_get_le16(&g);
114  if (code == 2 && length == 0)
115  break;
116  }
117  } else {
118  if (code == 1)
119  offset = bytestream2_get_byte(&g);
120  }
121 
122  /* Do boundary check */
123  if (dst + (length << lentab[code]) > frame_end)
124  break;
125 
126  switch (code) {
127  case 0: // normal chain
128  if (length >= bytestream2_get_bytes_left(&g)) {
129  av_log(avctx, AV_LOG_ERROR, "Frame larger than buffer.\n");
130  return AVERROR_INVALIDDATA;
131  }
132  bytestream2_get_buffer(&g, dst, length);
133  dst += length;
134  break;
135  case 1: // back chain
136  dst_offset = dst - offset;
137  length *= 4; // Convert dwords to bytes.
138  if (dst_offset < bfi->dst)
139  break;
140  while (length--)
141  *dst++ = *dst_offset++;
142  break;
143  case 2: // skip chain
144  dst += length;
145  break;
146  case 3: // fill chain
147  colour1 = bytestream2_get_byte(&g);
148  colour2 = bytestream2_get_byte(&g);
149  while (length--) {
150  *dst++ = colour1;
151  *dst++ = colour2;
152  }
153  break;
154  }
155  }
156 
157  src = bfi->dst;
158  dst = frame->data[0];
159  while (height--) {
160  memcpy(dst, src, avctx->width);
161  src += avctx->width;
162  dst += frame->linesize[0];
163  }
164  *got_frame = 1;
165 
166  return buf_size;
167 }
168 
170 {
171  BFIContext *bfi = avctx->priv_data;
172  av_free(bfi->dst);
173  return 0;
174 }
175 
177  .name = "bfi",
178  .type = AVMEDIA_TYPE_VIDEO,
179  .id = AV_CODEC_ID_BFI,
180  .priv_data_size = sizeof(BFIContext),
184  .capabilities = CODEC_CAP_DR1,
185  .long_name = NULL_IF_CONFIG_SMALL("Brute Force & Ignorance"),
186 };
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:205
struct BFIContext BFIContext
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
static int shift(int a, int b)
Definition: sonic.c:86
This structure describes decoded (raw) audio or video data.
Definition: frame.h:76
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:130
AVCodec ff_bfi_decoder
uint8_t
#define av_cold
Definition: attributes.h:78
8 bit with PIX_FMT_RGB32 palette
Definition: pixfmt.h:79
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
#define CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
uint8_t * data
frame
Definition: stft.m:14
#define U(x)
uint32_t pal[256]
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:183
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:159
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Spectrum Plot time data
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:258
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:149
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
const char * name
Name of the codec implementation.
uint8_t * dst
static const uint8_t offset[127][2]
Definition: vf_spp.c:70
external API header
FFT buffer for g
Definition: stft_peak.m:17
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:144
static av_cold int bfi_decode_close(AVCodecContext *avctx)
ret
Definition: avfilter.c:821
int width
picture width / height.
NULL
Definition: eval.c:55
or the Software in violation of any applicable export control laws in any jurisdiction Except as provided by mandatorily applicable UPF has no obligation to provide you with source code to the Software In the event Software contains any source code
AVS_Value src
Definition: avisynth_c.h:523
AVCodecContext * avctx
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:101
static av_cold int bfi_decode_init(AVCodecContext *avctx)
main external API structure.
static void close(AVCodecParserContext *s)
Definition: h264_parser.c:375
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
BYTE int const BYTE int int int height
Definition: avisynth_c.h:713
synthesis window for stochastic i
int palette_has_changed
Tell user application that palette has changed from previous frame.
Definition: frame.h:280
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:87
common internal api header.
common internal and external API header
static int bfi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:139
#define av_uninit(x)
Definition: attributes.h:137
int frame_number
Frame counter, set by libavcodec.
static int decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: crystalhd.c:868
const char int length
Definition: avisynth_c.h:668
This structure stores compressed data.
for(j=16;j >0;--j)
Predicted.
Definition: avutil.h:217