forked from old/legacy-imlib2
ANI loader: Multiframe suport
This commit is contained in:
parent
7e7eae168a
commit
03e4460c17
|
@ -23,6 +23,9 @@
|
|||
#define RIFF_TYPE_INAM T('I', 'N', 'A', 'M')
|
||||
#define RIFF_TYPE_IART T('I', 'A', 'R', 'T')
|
||||
#define RIFF_TYPE_icon T('i', 'c', 'o', 'n')
|
||||
#define RIFF_TYPE_anih T('a', 'n', 'i', 'h')
|
||||
#define RIFF_TYPE_rate T('r', 'a', 't', 'e')
|
||||
#define RIFF_TYPE_seq T('s', 'e', 'q', ' ')
|
||||
|
||||
#define RIFF_NAME_ACON T('A', 'C', 'O', 'N')
|
||||
|
||||
|
@ -30,8 +33,25 @@ static const char *const _formats[] = { "ani" };
|
|||
|
||||
typedef struct {
|
||||
unsigned char nest;
|
||||
int nframes, nfsteps;
|
||||
uint32_t *rates, *seq;
|
||||
} riff_ctx_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t size; // Size of chunk data (=36)
|
||||
uint32_t frames; // Number of frames in file
|
||||
uint32_t steps; // Number of steps in animation sequence
|
||||
uint32_t width; // Image width (raw data only?)
|
||||
uint32_t height; // Image height (raw data only?)
|
||||
uint32_t bpp; // Bits per pixel (raw data only?)
|
||||
uint32_t planes; // N. planes (raw data only?)
|
||||
uint32_t rate; // Default rate in 1/60s
|
||||
uint32_t flags; // Flags: ANIH_FLAG_...
|
||||
} anih_data_t;
|
||||
|
||||
#define ANIH_FLAG_ICO 0x01 // Frames are icons or cursors (otherwiwe raw - bmp?)
|
||||
#define ANIH_FLAG_SEQ 0x02 // Image contains seq chunk
|
||||
|
||||
static int
|
||||
_load_embedded(ImlibImage * im, int load_data, const char *data,
|
||||
unsigned int size)
|
||||
|
@ -72,10 +92,15 @@ _riff_parse(ImlibImage * im, riff_ctx_t * ctx, const char *fdata,
|
|||
int rc;
|
||||
unsigned int type;
|
||||
int size, avail;
|
||||
int fcount, i;
|
||||
ImlibImageFrame *pf;
|
||||
|
||||
rc = LOAD_FAIL;
|
||||
ctx->nest += 1;
|
||||
|
||||
pf = NULL;
|
||||
fcount = 0;
|
||||
|
||||
for (; rc == 0; fptr += 8 + size)
|
||||
{
|
||||
avail = fdata + fsize - fptr; /* Bytes left in chunk */
|
||||
|
@ -128,8 +153,75 @@ _riff_parse(ImlibImage * im, riff_ctx_t * ctx, const char *fdata,
|
|||
break;
|
||||
case RIFF_TYPE_icon:
|
||||
Dx("\n");
|
||||
fcount++;
|
||||
if (im->frame > 0)
|
||||
{
|
||||
i = (ctx->seq) ?
|
||||
(int)SWAP_LE_32(ctx->seq[im->frame - 1]) + 1 : im->frame;
|
||||
if (i != fcount)
|
||||
break;
|
||||
}
|
||||
if (pf && ctx->rates)
|
||||
pf->frame_delay =
|
||||
(1000 * SWAP_LE_32(ctx->rates[im->frame - 1])) / 60;
|
||||
rc = _load_embedded(im, 1, fptr + 8, size);
|
||||
break;
|
||||
case RIFF_TYPE_anih:
|
||||
#define AH ((const anih_data_t*)(fptr + 8))
|
||||
/**INDENT-OFF**/
|
||||
Dx("sz=%u nf=%u/%u WxH=%ux%u bc=%u np=%u dr=%u fl=%u\n",
|
||||
SWAP_LE_32(AH->size), SWAP_LE_32(AH->frames), SWAP_LE_32(AH->steps),
|
||||
SWAP_LE_32(AH->width), SWAP_LE_32(AH->height),
|
||||
SWAP_LE_32(AH->bpp), SWAP_LE_32(AH->planes),
|
||||
SWAP_LE_32(AH->rate), SWAP_LE_32(AH->flags));
|
||||
/**INDENT-ON**/
|
||||
ctx->nframes = SWAP_LE_32(AH->frames);
|
||||
ctx->nfsteps = SWAP_LE_32(AH->steps);
|
||||
if (im->frame <= 0)
|
||||
break;
|
||||
if (ctx->nfsteps < ctx->nframes)
|
||||
ctx->nfsteps = ctx->nframes;
|
||||
if (im->frame > ctx->nfsteps)
|
||||
return LOAD_BADFRAME;
|
||||
pf = __imlib_GetFrame(im);
|
||||
if (!pf)
|
||||
{
|
||||
rc = LOAD_OOM;
|
||||
break;
|
||||
}
|
||||
pf->frame_count = ctx->nfsteps;
|
||||
if (ctx->nframes > 1)
|
||||
pf->frame_flags = FF_IMAGE_ANIMATED;
|
||||
pf->frame_delay = (1000 * SWAP_LE_32(AH->rate)) / 60;
|
||||
break;
|
||||
case RIFF_TYPE_rate:
|
||||
ctx->rates = (uint32_t *) (fptr + 8);
|
||||
if ((int)size != 4 * ctx->nfsteps)
|
||||
{
|
||||
D("rate chunk size mismatch: %d != %d\n", size,
|
||||
4 * ctx->nfsteps);
|
||||
break;
|
||||
}
|
||||
#if IMLIB2_DEBUG
|
||||
for (i = 0; i < ctx->nfsteps; i++)
|
||||
Dx(" %d", SWAP_LE_32(ctx->rates[i]));
|
||||
#endif
|
||||
Dx("\n");
|
||||
break;
|
||||
case RIFF_TYPE_seq:
|
||||
ctx->seq = (uint32_t *) (fptr + 8);
|
||||
if ((int)size != 4 * ctx->nfsteps)
|
||||
{
|
||||
D("seq chunk size mismatch: %d != %d\n", size,
|
||||
4 * ctx->nfsteps);
|
||||
break;
|
||||
}
|
||||
#if IMLIB2_DEBUG
|
||||
for (i = 0; i < ctx->nfsteps; i++)
|
||||
Dx(" %d", SWAP_LE_32(ctx->seq[i]));
|
||||
#endif
|
||||
Dx("\n");
|
||||
break;
|
||||
}
|
||||
size = (size + 1) & ~1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue