libavcodec/anm.c
Go to the documentation of this file.
1 /*
2  * Deluxe Paint Animation decoder
3  * Copyright (c) 2009 Peter Ross
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  * Deluxe Paint Animation decoder
25  */
26 
27 #include "avcodec.h"
28 #include "bytestream.h"
29 #include "internal.h"
30 
31 typedef struct AnmContext {
35  int x; ///< x coordinate position
36 } AnmContext;
37 
39 {
40  AnmContext *s = avctx->priv_data;
41  int i;
42 
43  avctx->pix_fmt = AV_PIX_FMT_PAL8;
44 
45  s->frame = av_frame_alloc();
46  if (!s->frame)
47  return AVERROR(ENOMEM);
48 
49  bytestream2_init(&s->gb, avctx->extradata, avctx->extradata_size);
50  if (bytestream2_get_bytes_left(&s->gb) < 16 * 8 + 4 * 256)
51  return AVERROR_INVALIDDATA;
52 
53  bytestream2_skipu(&s->gb, 16 * 8);
54  for (i = 0; i < 256; i++)
55  s->palette[i] = bytestream2_get_le32u(&s->gb);
56 
57  return 0;
58 }
59 
60 /**
61  * Perform decode operation
62  * @param dst pointer to destination image buffer
63  * @param dst_end pointer to end of destination image buffer
64  * @param gb GetByteContext (optional, see below)
65  * @param pixel Fill color (optional, see below)
66  * @param count Pixel count
67  * @param x Pointer to x-axis counter
68  * @param width Image width
69  * @param linesize Destination image buffer linesize
70  * @return non-zero if destination buffer is exhausted
71  *
72  * a copy operation is achieved when 'gb' is set
73  * a fill operation is achieved when 'gb' is null and pixel is >= 0
74  * a skip operation is achieved when 'gb' is null and pixel is < 0
75  */
76 static inline int op(uint8_t **dst, const uint8_t *dst_end,
78  int pixel, int count,
79  int *x, int width, int linesize)
80 {
81  int remaining = width - *x;
82  while(count > 0) {
83  int striplen = FFMIN(count, remaining);
84  if (gb) {
85  if (bytestream2_get_bytes_left(gb) < striplen)
86  goto exhausted;
87  bytestream2_get_bufferu(gb, *dst, striplen);
88  } else if (pixel >= 0)
89  memset(*dst, pixel, striplen);
90  *dst += striplen;
91  remaining -= striplen;
92  count -= striplen;
93  if (remaining <= 0) {
94  *dst += linesize - width;
95  remaining = width;
96  }
97  if (linesize > 0) {
98  if (*dst >= dst_end) goto exhausted;
99  } else {
100  if (*dst <= dst_end) goto exhausted;
101  }
102  }
103  *x = width - remaining;
104  return 0;
105 
106 exhausted:
107  *x = width - remaining;
108  return 1;
109 }
110 
111 static int decode_frame(AVCodecContext *avctx,
112  void *data, int *got_frame,
113  AVPacket *avpkt)
114 {
115  AnmContext *s = avctx->priv_data;
116  const int buf_size = avpkt->size;
117  uint8_t *dst, *dst_end;
118  int count, ret;
119 
120  if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
121  return ret;
122  dst = s->frame->data[0];
123  dst_end = s->frame->data[0] + s->frame->linesize[0]*avctx->height;
124 
125  bytestream2_init(&s->gb, avpkt->data, buf_size);
126 
127  if (bytestream2_get_byte(&s->gb) != 0x42) {
128  avpriv_request_sample(avctx, "Unknown record type");
129  return AVERROR_INVALIDDATA;
130  }
131  if (bytestream2_get_byte(&s->gb)) {
132  avpriv_request_sample(avctx, "Padding bytes");
133  return AVERROR_PATCHWELCOME;
134  }
135  bytestream2_skip(&s->gb, 2);
136 
137  s->x = 0;
138  do {
139  /* if statements are ordered by probability */
140 #define OP(gb, pixel, count) \
141  op(&dst, dst_end, (gb), (pixel), (count), &s->x, avctx->width, s->frame->linesize[0])
142 
143  int type = bytestream2_get_byte(&s->gb);
144  count = type & 0x7F;
145  type >>= 7;
146  if (count) {
147  if (OP(type ? NULL : &s->gb, -1, count)) break;
148  } else if (!type) {
149  int pixel;
150  count = bytestream2_get_byte(&s->gb); /* count==0 gives nop */
151  pixel = bytestream2_get_byte(&s->gb);
152  if (OP(NULL, pixel, count)) break;
153  } else {
154  int pixel;
155  type = bytestream2_get_le16(&s->gb);
156  count = type & 0x3FFF;
157  type >>= 14;
158  if (!count) {
159  if (type == 0)
160  break; // stop
161  if (type == 2) {
162  avpriv_request_sample(avctx, "Unknown opcode");
163  return AVERROR_PATCHWELCOME;
164  }
165  continue;
166  }
167  pixel = type == 3 ? bytestream2_get_byte(&s->gb) : -1;
168  if (type == 1) count += 0x4000;
169  if (OP(type == 2 ? &s->gb : NULL, pixel, count)) break;
170  }
171  } while (bytestream2_get_bytes_left(&s->gb) > 0);
172 
173  memcpy(s->frame->data[1], s->palette, AVPALETTE_SIZE);
174 
175  *got_frame = 1;
176  if ((ret = av_frame_ref(data, s->frame)) < 0)
177  return ret;
178 
179  return buf_size;
180 }
181 
183 {
184  AnmContext *s = avctx->priv_data;
185 
186  av_frame_free(&s->frame);
187  return 0;
188 }
189 
191  .name = "anm",
192  .type = AVMEDIA_TYPE_VIDEO,
193  .id = AV_CODEC_ID_ANM,
194  .priv_data_size = sizeof(AnmContext),
195  .init = decode_init,
196  .close = decode_end,
197  .decode = decode_frame,
198  .capabilities = CODEC_CAP_DR1,
199  .long_name = NULL_IF_CONFIG_SMALL("Deluxe Paint Animation"),
200 };
const char * s
Definition: avisynth_c.h:668
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
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
static av_always_inline unsigned int bytestream2_get_bufferu(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:268
#define OP(gb, pixel, count)
void void avpriv_request_sample(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
uint8_t
#define av_cold
Definition: attributes.h:78
8 bit with PIX_FMT_RGB32 palette
Definition: pixfmt.h:79
#define AVPALETTE_SIZE
Definition: pixfmt.h:33
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
static av_always_inline void bytestream2_skipu(GetByteContext *g, unsigned int size)
Definition: bytestream.h:165
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_bytes_left(GetByteContext *g)
Definition: bytestream.h:149
const char * name
Name of the codec implementation.
external API header
int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame)
Identical in function to av_frame_make_writable(), except it uses ff_get_buffer() to allocate the buf...
#define FFMIN(a, b)
Definition: common.h:58
ret
Definition: avfilter.c:821
AVCodec ff_anm_decoder
AVFrame * frame
static av_cold int decode_init(AVCodecContext *avctx)
int palette[AVPALETTE_COUNT]
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
NULL
Definition: eval.c:55
static int width
Definition: tests/utils.c:158
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:101
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
main external API structure.
static void close(AVCodecParserContext *s)
Definition: h264_parser.c:375
synthesis window for stochastic i
GetByteContext gb
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
#define type
uint8_t pixel
Definition: tiny_ssim.c:40
#define AVPALETTE_COUNT
Definition: pixfmt.h:34
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:95
int av_frame_ref(AVFrame *dst, AVFrame *src)
Setup a new reference to the data described by an given frame.
Definition: frame.c:228
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:87
static int op(uint8_t **dst, const uint8_t *dst_end, GetByteContext *gb, int pixel, int count, int *x, int width, int linesize)
Perform decode operation.
common internal api header.
int x
x coordinate position
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:108
static av_cold int decode_end(AVCodecContext *avctx)
struct AnmContext AnmContext
else dst[i][x+y *dst_stride[i]]
Definition: vf_mcdeint.c:160
void INT64 INT64 count
Definition: avisynth_c.h:594
static int decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: crystalhd.c:868
This structure stores compressed data.