36 #define CDTOONS_HEADER_SIZE 44
37 #define CDTOONS_MAX_SPRITES 1200
67 int skip = 0, to_skip, x;
82 for (
int y = 0; y <
height; y++) {
87 line_size = bytestream_get_be16(&
data);
88 if (end -
data < line_size)
90 next_line =
data + line_size;
94 dest =
c->frame->data[0] + (dst_y + y) *
c->frame->linesize[0] + dst_x;
98 while (x <
width - skip) {
105 val = bytestream_get_byte(&
data);
110 if (to_skip >=
size) {
117 if (next_line -
data < step)
121 }
else if (to_skip) {
124 if (next_line -
data < to_skip)
159 const int buf_size = avpkt->
size;
162 uint16_t sprite_count, sprite_offset;
167 int saw_embedded_sprites = 0;
178 frame_id = bytestream_get_be16(&buf);
181 background_color = bytestream_get_byte(&buf);
184 sprite_count = bytestream_get_be16(&buf);
185 sprite_offset = bytestream_get_be16(&buf);
187 referenced_count = bytestream_get_byte(&buf);
189 palette_id = bytestream_get_be16(&buf);
190 palette_set = bytestream_get_byte(&buf);
193 if (sprite_offset > buf_size)
197 buf = avpkt->
data + sprite_offset;
198 while (sprite_count--) {
205 sprite_id = bytestream_get_be16(&buf);
208 "Sprite ID %d is too high.\n", sprite_id);
211 if (
c->sprites[sprite_id].active) {
213 "Sprite ID %d is a duplicate.\n", sprite_id);
217 c->sprites[sprite_id].flags = bytestream_get_be16(&buf);
218 size = bytestream_get_be32(&buf);
221 "Sprite only has %d bytes of data.\n",
size);
225 c->sprites[sprite_id].size =
size;
226 c->sprites[sprite_id].owner_frame = frame_id;
227 c->sprites[sprite_id].start_frame = bytestream_get_be16(&buf);
228 c->sprites[sprite_id].end_frame = bytestream_get_be16(&buf);
231 if (
size > buf_size || buf +
size > eod)
235 if (!
c->sprites[sprite_id].data)
238 c->sprites[sprite_id].active = 1;
250 tag = bytestream_get_be32(&buf);
251 size = bytestream_get_be32(&buf);
254 if (buf + 10 > eod) {
258 diff_count = bytestream_get_be16(&buf);
260 for (
int i = 0;
i < diff_count;
i++) {
264 if (buf + 16 > eod) {
269 top = bytestream_get_be16(&buf);
270 left = bytestream_get_be16(&buf);
272 diff_size = bytestream_get_be32(&buf);
273 width = bytestream_get_be16(&buf);
274 height = bytestream_get_be16(&buf);
275 if (diff_size < 8 || diff_size - 4 > eod - buf) {
283 buf += diff_size - 4;
285 saw_embedded_sprites = 1;
288 if (size < 8 || size - 8 > eod - buf) {
297 if (saw_embedded_sprites)
302 eod = avpkt->
data + sprite_offset;
303 for (
int i = 0;
i < referenced_count;
i++) {
306 int16_t top, left, right;
308 if (buf + 10 > eod) {
313 sprite_id = bytestream_get_be16(&buf);
314 top = bytestream_get_be16(&buf);
315 left = bytestream_get_be16(&buf);
317 right = bytestream_get_be16(&buf);
319 if ((
i == 0) && (sprite_id == 0)) {
321 memset(
c->frame->data[0], background_color,
322 c->frame->linesize[0] * avctx->
height);
329 "Sprite ID %d is too high.\n", sprite_id);
333 block_data =
c->sprites[sprite_id].data;
334 if (!
c->sprites[sprite_id].active) {
339 if (
c->sprites[sprite_id].size < 14) {
344 height = bytestream_get_be16(&block_data);
345 width = bytestream_get_be16(&block_data);
348 c->sprites[sprite_id].size - 14,
354 if (palette_id && (palette_id !=
c->last_pal_id)) {
357 "Palette ID %d is too high.\n", palette_id);
360 if (!
c->sprites[palette_id].active) {
363 "Palette ID %d is missing.\n", palette_id);
366 if (
c->sprites[palette_id].size != 256 * 2 * 3) {
368 "Palette ID %d is wrong size (%d).\n",
369 palette_id,
c->sprites[palette_id].size);
372 c->last_pal_id = palette_id;
374 uint8_t *palette_data =
c->sprites[palette_id].data;
375 for (
int i = 0;
i < 256;
i++) {
379 g = *(palette_data + 2);
380 b = *(palette_data + 4);
381 c->pal[
i] = (0xFFU << 24) | (
r << 16) | (
g << 8) |
b;
386 c->frame->palette_has_changed = 1;
393 if (
c->sprites[
i].end_frame > frame_id)
395 c->sprites[
i].active = 0;
428 c->sprites[
i].active = 0;
437 c->sprites[
i].active = 0;
static void flush(AVCodecContext *avctx)
static double val(void *priv, double ch)
Macro definitions for various function/variable attributes.
Libavcodec external API header.
static av_cold int init(AVCodecContext *avctx)
static av_always_inline unsigned int bytestream_get_buffer(const uint8_t **b, uint8_t *dst, unsigned int size)
static av_cold int cdtoons_decode_init(AVCodecContext *avctx)
#define CDTOONS_HEADER_SIZE
static int cdtoons_render_sprite(AVCodecContext *avctx, const uint8_t *data, uint32_t data_size, int dst_x, int dst_y, int width, int height)
#define CDTOONS_MAX_SPRITES
AVCodec ff_cdtoons_decoder
static av_cold int cdtoons_decode_end(AVCodecContext *avctx)
static int cdtoons_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
static void cdtoons_flush(AVCodecContext *avctx)
#define MKBETAG(a, b, c, d)
int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Identical in function to ff_get_buffer(), except it reuses the existing buffer if available.
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size)
Same behaviour av_fast_malloc but the buffer has additional AV_INPUT_BUFFER_PADDING_SIZE at the end w...
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
#define AV_LOG_WARNING
Something somehow does not look correct.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
main external API structure.
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
int width
picture width / height.
const char * name
Name of the codec implementation.
This structure describes decoded (raw) audio or video data.
This structure stores compressed data.
CDToonsSprite sprites[CDTOONS_MAX_SPRITES]
uint16_t last_pal_id
The index of the active palette sprite.
uint32_t pal[256]
The currently-used palette data.