159 const uint8_t *buf = avpkt->
data;
160 const uint8_t *eod = avpkt->
data + avpkt->
size;
161 const int buf_size = avpkt->
size;
163 uint8_t background_color;
164 uint16_t sprite_count, sprite_offset;
165 uint8_t referenced_count;
169 int saw_embedded_sprites = 0;
180 frame_id = bytestream_get_be16(&buf);
183 background_color = bytestream_get_byte(&buf);
186 sprite_count = bytestream_get_be16(&buf);
187 sprite_offset = bytestream_get_be16(&buf);
189 referenced_count = bytestream_get_byte(&buf);
191 palette_id = bytestream_get_be16(&buf);
192 palette_set = bytestream_get_byte(&buf);
195 if (sprite_offset > buf_size)
199 buf = avpkt->
data + sprite_offset;
200 while (sprite_count--) {
207 sprite_id = bytestream_get_be16(&buf);
210 "Sprite ID %d is too high.\n", sprite_id);
213 if (
c->sprites[sprite_id].active) {
215 "Sprite ID %d is a duplicate.\n", sprite_id);
219 c->sprites[sprite_id].flags = bytestream_get_be16(&buf);
220 size = bytestream_get_be32(&buf);
223 "Sprite only has %d bytes of data.\n",
size);
227 c->sprites[sprite_id].size =
size;
228 c->sprites[sprite_id].owner_frame = frame_id;
229 c->sprites[sprite_id].start_frame = bytestream_get_be16(&buf);
230 c->sprites[sprite_id].end_frame = bytestream_get_be16(&buf);
233 if (
size > buf_size || buf +
size > eod)
237 if (!
c->sprites[sprite_id].data)
240 c->sprites[sprite_id].active = 1;
252 tag = bytestream_get_be32(&buf);
253 size = bytestream_get_be32(&buf);
256 if (buf + 10 > eod) {
260 diff_count = bytestream_get_be16(&buf);
262 for (
int i = 0;
i < diff_count;
i++) {
266 if (buf + 16 > eod) {
271 top = bytestream_get_be16(&buf);
272 left = bytestream_get_be16(&buf);
274 diff_size = bytestream_get_be32(&buf);
275 width = bytestream_get_be16(&buf);
276 height = bytestream_get_be16(&buf);
277 if (diff_size < 8 || diff_size - 4 > eod - buf) {
285 buf += diff_size - 4;
287 saw_embedded_sprites = 1;
299 if (saw_embedded_sprites)
304 eod = avpkt->
data + sprite_offset;
305 for (
int i = 0;
i < referenced_count;
i++) {
306 const uint8_t *block_data;
308 int16_t top,
left, right;
310 if (buf + 10 > eod) {
315 sprite_id = bytestream_get_be16(&buf);
316 top = bytestream_get_be16(&buf);
317 left = bytestream_get_be16(&buf);
319 right = bytestream_get_be16(&buf);
321 if ((
i == 0) && (sprite_id == 0)) {
323 memset(
c->frame->data[0], background_color,
324 c->frame->linesize[0] * avctx->
height);
331 "Sprite ID %d is too high.\n", sprite_id);
335 block_data =
c->sprites[sprite_id].data;
336 if (!
c->sprites[sprite_id].active) {
341 if (
c->sprites[sprite_id].size < 14) {
346 height = bytestream_get_be16(&block_data);
347 width = bytestream_get_be16(&block_data);
350 c->sprites[sprite_id].size - 14,
356 if (palette_id && (palette_id !=
c->last_pal_id)) {
359 "Palette ID %d is too high.\n", palette_id);
362 if (!
c->sprites[palette_id].active) {
365 "Palette ID %d is missing.\n", palette_id);
368 if (
c->sprites[palette_id].size != 256 * 2 * 3) {
370 "Palette ID %d is wrong size (%d).\n",
371 palette_id,
c->sprites[palette_id].size);
374 c->last_pal_id = palette_id;
376 uint8_t *palette_data =
c->sprites[palette_id].data;
377 for (
int i = 0;
i < 256;
i++) {
381 g = *(palette_data + 2);
382 b = *(palette_data + 4);
383 c->pal[
i] = (0xFFU << 24) | (
r << 16) | (
g << 8) |
b;
394 if (
c->sprites[
i].end_frame > frame_id)
396 c->sprites[
i].active = 0;
main external API structure.
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
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.