Resource Interchange File Format
Puedes leer la última versión actualizada y corregida del artículo original en mi sitio web: jesustorres.es.
El Resource Interchange File Format o RIFF es un formato contenedor genérico diseñado para almacenar datos en forma de fragmentos etiquetados o chunks. Siendo usado en la actualidad como formato contenedor de los conocidos formatos de archivo AVI, ANI y WAV de Microsoft, es indudable que resulta especialmente útil para almacenar contenidos multimedia, aunque realmente puede almacenar cualquier tipo de información.
Tipos de fragmentos
Hay dos tipos de fragmentos en un archivo RIFF. El más básico son los chunks o fragmentos de datos propiamente dichos:
struct Chunk
{
uint32_t type;
uint32_t size;
uint8_t data[size]; // contiene datos en general
};
donde type
sirve para identificar el tipo y el formato de los datos que almacena el fragmento y size
para especificar su tamaño —sin incluir ni el tamaño del campo type
ni el de size
—.
El otro tipo de fragmento son las listas:
struct List
{
uint32_t type;
uint32_t size;
uint32_t listType;
uint8_t data[size-4]; // contiene otros Chunk o List
};
que son aquellos que contienen una colección de otros fragmentos o listas:
- Las listas se identifican y distinguen de otros fragmentos porque su campo
type
contiene o los 4 caracteres deRIFF
o los deLIST
. Pero hay que tener en cuenta que si bien en el archivo se almacenan entype
los caracteres'R'
,'R'
,'I'
,'F'
en ese orden, hay que tener en cuenta que al interpretarlo comouint32_t
en una máquina little-endian no veremos el número 0x52494646 sino 0x46464952. - Para este tipo de fragmentos el tamaño en el campo
size
incluye tanto el de los datos almacenados dentro del fragmento como el del campolistType
. - Dentro de la lista los fragmentos que contiene se disponen unos detrás de otros, pero siempre asegurando que cada fragmento comienza en una dirección par — es decir, que se alinean a 16 bits — .
El archivo contenedor en si mismo es una gran fragmento de lista tipo RIFF
que contiene otros fragmentos. Estos pueden ser chunks o listas de tipo LIST
. Por lo tanto en una archivo RIFF sólo existe una lista de este tipo, que hace las veces de contenedor de todos los fragmentos del archivo. El valor del campo listType
del fragmento RIFF
es una secuencia de 4 bytes que identifica el formato del archivo y se lo conoce como el FourCC del mismo.
Estructura general
Para hacernos una idea del formato este sería el esquema de un archivo AVI convencional:
RIFF ('AVI '
LIST ('hdr1'
AVIH (<cabecera principal del AVI>)
LIST ('str1'
STRH (<cabecera del flujo>)
STRF (<formato del flujo>)
...
)
...
)
LIST ('movi'
{Chunk | LIST ('rec '
Chunk1
Chunk2
...
)
...
}
...
)
[IDX1 (<índice AVI>)]
)
Donde los identificadores en mayúsculas denotan el valor del campo type
al comienzo de un fragmento. Este siempre es seguido por el campo size
, que no se muestra en el esquema anterior. Por otro lado el valor de los campos listType
de los fragmentos de tipo lista se indica entre comillas simples. Para observar una estructura real de archivo RIFF se puede utilizar el programa rifftree del paquete gigtools
con cualquier archivo .avi
o .wav
que tengamos a mano.
Mi rifftree
Para ilustrar lo comentado sobre los archivos RIFF, he publicado en GitHub mi propia versión de rifftree. Está desarrollada con Qt y hace uso del mapeo de archivos en memoria para simplificar el acceso al archivo RIFF.
Referencias
- Wikipedia — Resource Interchange File Format
- MSDN — AVI RIFF File Reference
- AVI File Format
- FourCC