GIF support and new MAGIC magic that compiles to immediate values

This commit is contained in:
Mathias Panzenböck 2013-01-13 00:52:35 +01:00
parent b478068a4e
commit 7794518c0a
8 changed files with 329 additions and 128 deletions

View File

@ -26,7 +26,8 @@ OBJ=\
$(BUILDDIR)/smk.o \
$(BUILDDIR)/bmp.o \
$(BUILDDIR)/png.o \
$(BUILDDIR)/jpg.o
$(BUILDDIR)/jpg.o \
$(BUILDDIR)/gif.o
CC=gcc
LD=$(CC)
COMMON_CFLAGS=-Wall -Werror -Wextra -std=gnu99 -O2 -g $(INCLUDE) $(LIBDIRS) -D_FILE_OFFSET_BITS=64
@ -96,7 +97,8 @@ $(BUILDDIR)/mediaextract.o: src/mediaextract.c \
src/smk.h \
src/bmp.h \
src/png.h \
src/jpg.h
src/jpg.h \
src/gif.h
$(CC) $(CFLAGS) $< -o $@ -c $(LIBS)
$(BUILDDIR)/mediaextract_$(PLATFORM).o: src/mediaextract_$(PLATFORM).c src/mediaextract.h
@ -156,6 +158,9 @@ $(BUILDDIR)/png.o: src/png.c src/mediaextract.h src/png.h
$(BUILDDIR)/jpg.o: src/jpg.c src/mediaextract.h src/jpg.h
$(CC) $(CFLAGS) $< -o $@ -c $(LIBS)
$(BUILDDIR)/gif.o: src/gif.c src/mediaextract.h src/gif.h
$(CC) $(CFLAGS) $< -o $@ -c $(LIBS)
ifeq ($(PLATFORM),posix)
install: $(PREFIX)/bin/$(APPNAME)

View File

@ -20,7 +20,10 @@ Or (uses `x86_64-w64-mingw32-gcc`):
make TARGET=win64 builddir
make TARGET=win64
**NOTE:** 32bit binaries can only process 2 GB of a file at once. The rest of
**Warning:** This program only works correctly on platforms that allow unaligned
memory access (e.g. x86 and ARM, although it might be quite slow on the latter).
**Note:** 32bit binaries can only process 2 GB of a file at once. The rest of
bigger files will be ignored. You need to run this program several times with
different `--offset` values to process such a file whole.
@ -90,10 +93,11 @@ files.
Supported formats:
all all supported formats
default the default set of formats (AIFF, ASF, AU, BINK, BMP,
ID3v2, IT, JPG, MIDI, MP4, Ogg, PNG, RIFF, S3M, SMK, XM)
GIF, ID3v2, IT, JPG, MIDI, MP4, Ogg, PNG, RIFF, S3M,
SMK, XM)
audio all audio files (AIFF, ASF, AU, ID3v2, IT, MIDI, MP4,
Ogg, RIFF, S3M, XM)
image all image files (BMP, PNG, JPG)
image all image files (BMP, PNG, JPG, GIF)
tracker all tracker files (MOD, S3M, IT, XM)
video all video files (ASF, BINK, MP4, RIFF, SMK)
@ -102,6 +106,7 @@ files.
au Sun Microsystems audio file format (.au or .snd)
bink BINK files
bmp Windows Bitmap files
gif Graphics Interchange Format files
id3v2 MPEG layer 1/2/3 files with ID3v2 tags
it ImpulseTracker files
jpg JPEG Interchange Format files
@ -110,7 +115,7 @@ files.
mpg123 MPEG layer 1/2/3 files (MP1, MP2, MP3)
mp4 MP4 files (M4A, M4V, 3GPP etc.)
ogg Ogg files (Vorbis, Opus, Theora, etc.)
png Portable Network Graphics file
png Portable Network Graphics files
riff Resource Interchange File Format files (ANI, AVI, MMM,
PAL, RDI, RMI, WAV)
s3m ScreamTracker III files

110
src/gif.c Normal file
View File

@ -0,0 +1,110 @@
#include "gif.h"
// See: http://www.onicos.com/staff/iz/formats/gif.html
#pragma pack(push, 1)
struct gif_header {
uint8_t signature[GIF_SIGNATURE_SIZE];
uint16_t screenwidth;
uint16_t screenheight;
uint8_t flags;
uint8_t bgcolorindex;
uint8_t pxaspect;
};
struct gif_image_block {
uint8_t mark;
uint16_t left;
uint16_t top;
uint16_t width;
uint16_t height;
uint8_t flags;
};
#pragma pack(pop)
int gif_isfile(const uint8_t *data, size_t input_len, size_t *lengthptr)
{
if (input_len < GIF_MIN_SIZE || (
memcmp(data, GIF87a_SIGNATURE, GIF_SIGNATURE_SIZE) != 0 &&
memcmp(data, GIF89a_SIGNATURE, GIF_SIGNATURE_SIZE) != 0))
return 0;
const struct gif_header *header = (const struct gif_header *)data;
size_t length = GIF_HEADER_SIZE;
if (header->flags & GIF_CT_FLAG)
length += (2 << (header->flags & 7)) * 3;
for (;;)
{
if (length > input_len - 1)
return 0;
unsigned int marker = data[length];
if (marker == GIF_IMAGE_BLOCK)
{
if (length > input_len - GIF_IMAGE_BLOCK_SIZE)
return 0;
const struct gif_image_block *image = (struct gif_image_block *)(data + length);
length += GIF_IMAGE_BLOCK_SIZE;
if (image->flags & GIF_CT_FLAG)
{
size_t tblsize = (2 << (image->flags & 15)) * 3;
if (SIZE_MAX - tblsize < length)
return 0;
length += tblsize;
if (length > input_len)
return 0;
}
}
else if (marker == GIF_EXT)
{
if (length > input_len - 2)
return 0;
length += 2;
}
else if (marker == GIF_TRAILER)
{
++ length;
break;
}
else
{
return 0;
}
// parse data blocks until terminator (block of size 0)
for (;;)
{
size_t size = data[length];
if (size == 0)
{
if (length == SIZE_MAX)
return 0;
++ length;
break;
}
else if (SIZE_MAX - (size + 1) < length)
return 0;
length += size + 1;
if (length > input_len)
return 0;
}
}
if (lengthptr)
*lengthptr = length;
return 1;
}

23
src/gif.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef MEDIAEXTRACT_GIF_H__
#define MEDIAEXTRACT_GIF_H__
#include "mediaextract.h"
#define GIF87a_SIGNATURE "GIF87a"
#define GIF89a_SIGNATURE "GIF89a"
#define GIF_MAGIC MAGIC(GIF87a_SIGNATURE)
#define GIF_SIGNATURE_SIZE 6
#define GIF_HEADER_SIZE 13
#define GIF_IMAGE_BLOCK_SIZE 11
#define GIF_MIN_SIZE 14
#define GIF_IMAGE_BLOCK ','
#define GIF_EXT '!'
#define GIF_TRAILER ';'
#define GIF_CT_FLAG 0x80
int gif_isfile(const uint8_t *data, size_t input_len, size_t *lengthptr);
#endif /* MEDIAEXTRACT_GIF_H__ */

View File

@ -33,6 +33,7 @@
#include "bmp.h"
#include "png.h"
#include "jpg.h"
#include "gif.h"
#if defined(__WINDOWS__) && !defined(__CYGWIN__)
# ifdef _WIN64
@ -68,15 +69,16 @@ enum fileformat {
SMK = 0x4000,
BMP = 0x8000,
PNG = 0x10000,
JPEG = 0x20000
JPEG = 0x20000,
GIF = 0x40000
};
#define TRACKER_FORMATS (MOD | S3M | IT | XM)
#define AUDIO_FORMATS (OGG | RIFF | AIFF | MPG123 | MP4 | ID3v2 | MIDI | MOD | S3M | IT | XM | ASF | AU)
#define VIDEO_FORMATS (MP4 | RIFF | ASF | BINK | SMK)
#define IMAGE_FORMATS (BMP | PNG | JPEG)
#define ALL_FORMATS (OGG | RIFF | AIFF | MPG123 | MP4 | ID3v2 | MIDI | MOD | S3M | IT | XM | ASF | BINK | AU | SMK | BMP | PNG | JPEG)
#define DEFAULT_FORMATS (OGG | RIFF | AIFF | MP4 | ID3v2 | MIDI | S3M | IT | XM | ASF | BINK | AU | SMK | BMP | PNG | JPEG)
#define IMAGE_FORMATS (BMP | PNG | JPEG | GIF)
#define ALL_FORMATS (OGG | RIFF | AIFF | MPG123 | MP4 | ID3v2 | MIDI | MOD | S3M | IT | XM | ASF | BINK | AU | SMK | BMP | PNG | JPEG | GIF)
#define DEFAULT_FORMATS (OGG | RIFF | AIFF | MP4 | ID3v2 | MIDI | S3M | IT | XM | ASF | BINK | AU | SMK | BMP | PNG | JPEG | GIF)
static int usage(int argc, char **argv);
static const char *basename(const char *path);
@ -148,10 +150,11 @@ static int usage(int argc, char **argv)
" Supported formats:\n"
" all all supported formats\n"
" default the default set of formats (AIFF, ASF, AU, BINK, BMP,\n"
" ID3v2, IT, JPG, MIDI, MP4, Ogg, PNG, RIFF, S3M, SMK, XM)\n"
" GIF, ID3v2, IT, JPG, MIDI, MP4, Ogg, PNG, RIFF, S3M,\n"
" SMK, XM)\n"
" audio all audio files (AIFF, ASF, AU, ID3v2, IT, MIDI, MP4,\n"
" Ogg, RIFF, S3M, XM)\n"
" image all image files (BMP, PNG, JPG)\n"
" image all image files (BMP, PNG, JPG, GIF)\n"
" tracker all tracker files (MOD, S3M, IT, XM)\n"
" video all video files (ASF, BINK, MP4, RIFF, SMK)\n"
"\n"
@ -160,6 +163,7 @@ static int usage(int argc, char **argv)
" au Sun Microsystems audio file format (.au or .snd)\n"
" bink BINK files\n"
" bmp Windows Bitmap files\n"
" gif Graphics Interchange Format files\n"
" id3v2 MPEG layer 1/2/3 files with ID3v2 tags\n"
" it ImpulseTracker files\n"
" jpg JPEG Interchange Format files\n"
@ -168,7 +172,7 @@ static int usage(int argc, char **argv)
" mpg123 MPEG layer 1/2/3 files (MP1, MP2, MP3)\n"
" mp4 MP4 files (M4A, M4V, 3GPP etc.)\n"
" ogg Ogg files (Vorbis, Opus, Theora, etc.)\n"
" png Portable Network Graphics file\n"
" png Portable Network Graphics files\n"
" riff Resource Interchange File Format files (ANI, AVI, MMM,\n"
" PAL, RDI, RMI, WAV)\n"
" s3m ScreamTracker III files\n"
@ -445,7 +449,14 @@ int do_extract(const uint8_t *filedata, size_t filesize, const struct extract_op
ptr += length;
continue;
}
if (formats & GIF && magic == GIF_MAGIC && gif_isfile(ptr, input_len, &length))
{
WRITE_FILE(ptr, length, "gif");
ptr += length;
continue;
}
if (formats & JPEG && IS_JPG_MAGIC(magic) && jpg_isfile(ptr, input_len, &length))
{
WRITE_FILE(ptr, length, "jpg");
@ -613,6 +624,10 @@ int parse_formats(const char *formats)
{
mask = JPEG;
}
else if (strncasecmp("gif", start, len) == 0)
{
mask = GIF;
}
else if (strncasecmp("audio", start, len) == 0)
{
mask = AUDIO_FORMATS;

View File

@ -35,6 +35,11 @@
# define be64toh OSSwapBigToHostInt64
# define le64toh OSSwapLittleToHostInt64
# define __BYTE_ORDER BYTE_ORDER
# define __BIG_ENDIAN BIG_ENDIAN
# define __LITTLE_ENDIAN LITTLE_ENDIAN
# define __PDP_ENDIAN PDP_ENDIAN
#elif defined(__OpenBSD__)
# include <sys/endian.h>
@ -94,13 +99,18 @@
# else
# error "byte order not supported"
# error byte order not supported
# endif
# define __BYTE_ORDER BYTE_ORDER
# define __BIG_ENDIAN BIG_ENDIAN
# define __LITTLE_ENDIAN LITTLE_ENDIAN
# define __PDP_ENDIAN PDP_ENDIAN
#else
# error "platform not supported"
# error platform not supported
#endif
@ -114,7 +124,34 @@
#endif
#define _CMAGIC(C1,C2,C3,C4) (uint32_t)(((C1) << 24) | ((C2) << 16) | ((C3) << 8) | (C4))
#if __BYTE_ORDER == __LITTLE_ENDIAN
# define CMAGIC(C1,C2,C3,C4) _CMAGIC(C4,C3,C2,C1)
#elif __BYTE_ORDER == __BIG_ENDIAN
# define CMAGIC(C1,C2,C3,C4) _CMAGIC(C1,C2,C3,C4)
#elif __BYTE_ORDER == __PDP_ENDIAN
# define CMAGIC(C1,C2,C3,C4) _CMAGIC(C3,C4,C1,C2)
#else
# error unsupported byte order
#endif
#if 0
#define MAGIC(STR) (*(const uint32_t*)(STR))
#else
#define _MAGIC(B) CMAGIC((B)[0], (B)[1], (B)[2], (B)[3])
#define MAGIC(S) _MAGIC((const uint8_t *)(S))
#endif
struct file_info {
size_t length;

192
src/mp4.c
View File

@ -1,102 +1,108 @@
#include "mp4.h"
struct ftyp {
const char *brand;
uint32_t brand;
const char *ext;
};
static const struct ftyp mp4_ftyps[] = {
{ "3g2a", "3g2" },
{ "3g2b", "3g2" },
{ "3g2c", "3g2" },
{ "3ge6", "3gp" },
{ "3ge7", "3gp" },
{ "3gg6", "3gp" },
{ "3gp1", "3gp" },
{ "3gp2", "3gp" },
{ "3gp3", "3gp" },
{ "3gp4", "3gp" },
{ "3gp5", "3gp" },
{ "3gp6", "3gp" },
{ "3gp6", "3gp" },
{ "3gp6", "3gp" },
{ "3gs7", "3gp" },
{ "avc1", 0 },
{ "CAEP", 0 },
{ "caqv", 0 },
{ "CDes", 0 },
{ "da0a", 0 },
{ "da0b", 0 },
{ "da1a", 0 },
{ "da1b", 0 },
{ "da2a", 0 },
{ "da2b", 0 },
{ "da3a", 0 },
{ "da3b", 0 },
{ "dmb1", 0 },
{ "dmpf", 0 },
{ "drc1", "mp4" },
{ "dv1a", 0 },
{ "dv1b", 0 },
{ "dv2a", 0 },
{ "dv2b", 0 },
{ "dv3a", 0 },
{ "dv3b", 0 },
{ "dvr1", "dvb" },
{ "dvt1", "dvb" },
{ "F4V ", "f4v" },
{ "F4P ", "f4p" },
{ "F4A ", "f4a" },
{ "F4B ", "f4b" },
{ "isc2", 0 },
{ "iso2", "mp4" },
{ "isom", "mp4" },
{ "JP2 ", "jp2" },
{ "JP20", "jp2" },
{ "jpm ", "jpm" },
{ "jpx ", "jpx" },
{ "KDDI", "3gp" },
{ "M4A ", "m4a" },
{ "M4B ", "m4b" },
{ "M4P ", "m4p" },
{ "M4V ", "m4v" },
{ "M4VH", "m4v" },
{ "M4VP", "m4v" },
{ "mj2s", "jp2" },
{ "mjp2", "jp2" },
{ "mmp4", "mp4" },
{ "mp21", 0 },
{ "mp41", "mp4" },
{ "mp42", "mp4" },
{ "mp71", "mp4" },
{ "MPPI", 0 },
{ "mqt ", "mqv" },
{ "MSNV", "mp4" },
{ "NDAS", 0 },
{ "NDSC", "mp4" },
{ "NDSH", "mp4" },
{ "NDSM", "mp4" },
{ "NDSP", "mp4" },
{ "NDSS", "mp4" },
{ "NDXC", "mp4" },
{ "NDXH", "mp4" },
{ "NDXM", "mp4" },
{ "NDXP", "mp4" },
{ "NDXS", "mp4" },
{ "odcf", 0 },
{ "opf2", 0 },
{ "opx2", 0 },
{ "pana", 0 },
{ "qt ", "mov" },
{ "ROSS", 0 },
{ "sdv ", 0 },
{ "ssc1", 0 },
{ "ssc2", 0 },
{ 0 , 0 }
{ CMAGIC('3','g','2','a'), "3g2" },
{ CMAGIC('3','g','2','b'), "3g2" },
{ CMAGIC('3','g','2','c'), "3g2" },
{ CMAGIC('3','g','e','6'), "3gp" },
{ CMAGIC('3','g','e','7'), "3gp" },
{ CMAGIC('3','g','g','6'), "3gp" },
{ CMAGIC('3','g','p','1'), "3gp" },
{ CMAGIC('3','g','p','2'), "3gp" },
{ CMAGIC('3','g','p','3'), "3gp" },
{ CMAGIC('3','g','p','4'), "3gp" },
{ CMAGIC('3','g','p','5'), "3gp" },
{ CMAGIC('3','g','p','6'), "3gp" },
{ CMAGIC('3','g','p','6'), "3gp" },
{ CMAGIC('3','g','p','6'), "3gp" },
{ CMAGIC('3','g','s','7'), "3gp" },
{ CMAGIC('a','v','c','1'), 0 },
{ CMAGIC('C','A','E','P'), 0 },
{ CMAGIC('c','a','q','v'), 0 },
{ CMAGIC('C','D','e','s'), 0 },
{ CMAGIC('d','a','0','a'), 0 },
{ CMAGIC('d','a','0','b'), 0 },
{ CMAGIC('d','a','1','a'), 0 },
{ CMAGIC('d','a','1','b'), 0 },
{ CMAGIC('d','a','2','a'), 0 },
{ CMAGIC('d','a','2','b'), 0 },
{ CMAGIC('d','a','3','a'), 0 },
{ CMAGIC('d','a','3','b'), 0 },
{ CMAGIC('d','m','b','1'), 0 },
{ CMAGIC('d','m','p','f'), 0 },
{ CMAGIC('d','r','c','1'), "mp4" },
{ CMAGIC('d','v','1','a'), 0 },
{ CMAGIC('d','v','1','b'), 0 },
{ CMAGIC('d','v','2','a'), 0 },
{ CMAGIC('d','v','2','b'), 0 },
{ CMAGIC('d','v','3','a'), 0 },
{ CMAGIC('d','v','3','b'), 0 },
{ CMAGIC('d','v','r','1'), "dvb" },
{ CMAGIC('d','v','t','1'), "dvb" },
{ CMAGIC('F','4','V',' '), "f4v" },
{ CMAGIC('F','4','P',' '), "f4p" },
{ CMAGIC('F','4','A',' '), "f4a" },
{ CMAGIC('F','4','B',' '), "f4b" },
{ CMAGIC('i','s','c','2'), 0 },
{ CMAGIC('i','s','o','2'), "mp4" },
{ CMAGIC('i','s','o','m'), "mp4" },
{ CMAGIC('J','P','2',' '), "jp2" },
{ CMAGIC('J','P','2','0'), "jp2" },
{ CMAGIC('j','p','m',' '), "jpm" },
{ CMAGIC('j','p','x',' '), "jpx" },
{ CMAGIC('K','D','D','I'), "3gp" },
{ CMAGIC('M','4','A',' '), "m4a" },
{ CMAGIC('M','4','B',' '), "m4b" },
{ CMAGIC('M','4','P',' '), "m4p" },
{ CMAGIC('M','4','V',' '), "m4v" },
{ CMAGIC('M','4','V','H'), "m4v" },
{ CMAGIC('M','4','V','P'), "m4v" },
{ CMAGIC('m','j','2','s'), "jp2" },
{ CMAGIC('m','j','p','2'), "jp2" },
{ CMAGIC('m','m','p','4'), "mp4" },
{ CMAGIC('m','p','2','1'), 0 },
{ CMAGIC('m','p','4','1'), "mp4" },
{ CMAGIC('m','p','4','2'), "mp4" },
{ CMAGIC('m','p','7','1'), "mp4" },
{ CMAGIC('M','P','P','I'), 0 },
{ CMAGIC('m','q','t',' '), "mqv" },
{ CMAGIC('M','S','N','V'), "mp4" },
{ CMAGIC('N','D','A','S'), 0 },
{ CMAGIC('N','D','S','C'), "mp4" },
{ CMAGIC('N','D','S','H'), "mp4" },
{ CMAGIC('N','D','S','M'), "mp4" },
{ CMAGIC('N','D','S','P'), "mp4" },
{ CMAGIC('N','D','S','S'), "mp4" },
{ CMAGIC('N','D','X','C'), "mp4" },
{ CMAGIC('N','D','X','H'), "mp4" },
{ CMAGIC('N','D','X','M'), "mp4" },
{ CMAGIC('N','D','X','P'), "mp4" },
{ CMAGIC('N','D','X','S'), "mp4" },
{ CMAGIC('o','d','c','f'), 0 },
{ CMAGIC('o','p','f','2'), 0 },
{ CMAGIC('o','p','x','2'), 0 },
{ CMAGIC('p','a','n','a'), 0 },
{ CMAGIC('q','t',' ',' '), "mov" },
{ CMAGIC('R','O','S','S'), 0 },
{ CMAGIC('s','d','v',' '), 0 },
{ CMAGIC('s','s','c','1'), 0 },
{ CMAGIC('s','s','c','2'), 0 },
{ 0 , 0 }
};
static const char *mp4_bodyatom_types[] = {
"moov", "mdat", "free", "skip", "wide", "pnot", 0
static const uint32_t mp4_bodyatom_types[] = {
CMAGIC('m','o','o','v'),
CMAGIC('m','d','a','t'),
CMAGIC('f','r','e','e'),
CMAGIC('s','k','i','p'),
CMAGIC('w','i','d','e'),
CMAGIC('p','n','o','t'),
0
};
struct mp4_atom_head {
@ -116,7 +122,7 @@ static const char *mp4_find_ext(uint32_t brand)
{
for (const struct ftyp *ftyp = mp4_ftyps; ftyp->brand; ++ ftyp)
{
if (MAGIC(ftyp->brand) == brand)
if (ftyp->brand == brand)
{
if (!ftyp->ext) return "mp4";
return ftyp->ext;
@ -127,9 +133,9 @@ static const char *mp4_find_ext(uint32_t brand)
static int mp4_isbodyatom_type(uint32_t type)
{
for (const char **atom = mp4_bodyatom_types; *atom; ++ atom)
for (const uint32_t *atom = mp4_bodyatom_types; *atom; ++ atom)
{
if (MAGIC(atom) == type)
if (*atom == type)
{
return 1;
}

View File

@ -3,7 +3,7 @@
/* see: http://www.johnloomis.org/cpe102/asgn/asgn1/riff.html */
struct riff_chunk_spec {
const char *type;
uint32_t type;
const struct riff_chunk_spec *body;
int required;
};
@ -19,7 +19,7 @@ static const struct riff_chunk_spec riff_empty_body[] = {
/* WAVE */
static const struct riff_chunk_spec riff_wav_body[] = {
{ "fmt ", 0, 1 },
{ CMAGIC('f','m','t',' '), 0, 1 },
{ 0, 0, 0 }
};
@ -27,43 +27,43 @@ static const struct riff_chunk_spec riff_wav_body[] = {
// TODO: AVI 2.0? only makes sense for files > 4 GB
// http://www.the-labs.com/Video/odmlff2-avidef.pdf
static const struct riff_chunk_spec riff_avi_hdrl_body[] = {
{ "avih", 0, 1 },
{ CMAGIC('a','v','i','h'), 0, 1 },
{ 0, 0, 0 }
};
static const struct riff_chunk_spec riff_avi_body[] = {
{ "hdrl", 0, 1 },
{ "movi", 0, 1 },
{ CMAGIC('h','d','r','l'), 0, 1 },
{ CMAGIC('m','o','v','i'), 0, 1 },
{ 0, 0, 0 }
};
/* ACON */
static const struct riff_chunk_spec riff_ani_fram_body[] = {
{ "icon", 0, 1 },
{ CMAGIC('i','c','o','n'), 0, 1 },
{ 0, 0, 0 }
};
static const struct riff_chunk_spec riff_ani_body[] = {
{ "INFO", riff_empty_body, 0 },
{ "anih", 0, 1 },
{ "fram", riff_ani_fram_body, 1 },
{ CMAGIC('I','N','F','O'), riff_empty_body, 0 },
{ CMAGIC('a','n','i','h'), 0, 1 },
{ CMAGIC('f','r','a','m'), riff_ani_fram_body, 1 },
{ 0, 0, 0 }
};
/* PAL */
static const struct riff_chunk_spec riff_pal_body[] = {
{ "data", 0, 1 },
{ CMAGIC('d','a','t','a'), 0, 1 },
{ 0, 0, 0 }
};
static const struct riff_file_spec riff_file_specs[] = {
{ { "WAVE", riff_wav_body, 1 }, "wav" },
{ { "AVI ", riff_avi_body, 1 }, "avi" },
{ { "ACON", riff_ani_body, 1 }, "ani" },
{ { "RMID", riff_empty_body, 1 }, "rmi" },
{ { "PAL ", riff_pal_body, 1 }, "pal" },
{ { "RDIB", riff_empty_body, 1 }, "rdi" },
{ { "RMMP", riff_empty_body, 1 }, "mmm" },
{ { CMAGIC('W','A','V','E'), riff_wav_body, 1 }, "wav" },
{ { CMAGIC('A','V','I',' '), riff_avi_body, 1 }, "avi" },
{ { CMAGIC('A','C','O','N'), riff_ani_body, 1 }, "ani" },
{ { CMAGIC('R','M','I','D'), riff_empty_body, 1 }, "rmi" },
{ { CMAGIC('P','A','L',' '), riff_pal_body, 1 }, "pal" },
{ { CMAGIC('R','D','I','B'), riff_empty_body, 1 }, "rdi" },
{ { CMAGIC('R','M','M','P'), riff_empty_body, 1 }, "mmm" },
{ { 0, 0, 0 }, 0 }
};
@ -78,7 +78,7 @@ const uint8_t *riff_match(const uint8_t *data, size_t size,
uint32_t chunk_size = le32toh(*(const uint32_t *)(data + 4));
uint32_t type = MAGIC(data + 8);
if (type != MAGIC(spec->type))
if (type != spec->type)
return NULL;
if (chunk_size > size - 8)
@ -164,7 +164,7 @@ const uint8_t *riff_match(const uint8_t *data, size_t size,
}
else
{
if (size < 8 || MAGIC(data) != MAGIC(spec->type))
if (size < 8 || MAGIC(data) != spec->type)
return NULL;
uint32_t chunk_size = le32toh(*(const uint32_t *)(data + 4));