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_INAM T('I', 'N', 'A', 'M')
|
||||||
#define RIFF_TYPE_IART T('I', 'A', 'R', 'T')
|
#define RIFF_TYPE_IART T('I', 'A', 'R', 'T')
|
||||||
#define RIFF_TYPE_icon T('i', 'c', 'o', 'n')
|
#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')
|
#define RIFF_NAME_ACON T('A', 'C', 'O', 'N')
|
||||||
|
|
||||||
|
@ -30,8 +33,25 @@ static const char *const _formats[] = { "ani" };
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned char nest;
|
unsigned char nest;
|
||||||
|
int nframes, nfsteps;
|
||||||
|
uint32_t *rates, *seq;
|
||||||
} riff_ctx_t;
|
} 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
|
static int
|
||||||
_load_embedded(ImlibImage * im, int load_data, const char *data,
|
_load_embedded(ImlibImage * im, int load_data, const char *data,
|
||||||
unsigned int size)
|
unsigned int size)
|
||||||
|
@ -72,10 +92,15 @@ _riff_parse(ImlibImage * im, riff_ctx_t * ctx, const char *fdata,
|
||||||
int rc;
|
int rc;
|
||||||
unsigned int type;
|
unsigned int type;
|
||||||
int size, avail;
|
int size, avail;
|
||||||
|
int fcount, i;
|
||||||
|
ImlibImageFrame *pf;
|
||||||
|
|
||||||
rc = LOAD_FAIL;
|
rc = LOAD_FAIL;
|
||||||
ctx->nest += 1;
|
ctx->nest += 1;
|
||||||
|
|
||||||
|
pf = NULL;
|
||||||
|
fcount = 0;
|
||||||
|
|
||||||
for (; rc == 0; fptr += 8 + size)
|
for (; rc == 0; fptr += 8 + size)
|
||||||
{
|
{
|
||||||
avail = fdata + fsize - fptr; /* Bytes left in chunk */
|
avail = fdata + fsize - fptr; /* Bytes left in chunk */
|
||||||
|
@ -128,8 +153,75 @@ _riff_parse(ImlibImage * im, riff_ctx_t * ctx, const char *fdata,
|
||||||
break;
|
break;
|
||||||
case RIFF_TYPE_icon:
|
case RIFF_TYPE_icon:
|
||||||
Dx("\n");
|
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);
|
rc = _load_embedded(im, 1, fptr + 8, size);
|
||||||
break;
|
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;
|
size = (size + 1) & ~1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue