Update to latest libasf (r107)

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37363 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
David McPaul
2010-07-03 06:12:56 +00:00
parent a775c1a432
commit affec393bc
21 changed files with 533 additions and 603 deletions
@@ -184,9 +184,9 @@ ASFFileReader::getVideoFormat(uint32 streamIndex, ASFVideoFormat *format)
format->extraData = videoHeader->data; format->extraData = videoHeader->data;
if (stream->flags & ASF_STREAM_FLAG_EXTENDED) { if (stream->flags & ASF_STREAM_FLAG_EXTENDED) {
format->FrameScale = stream->extended->avg_time_per_frame; format->FrameScale = stream->extended_properties->avg_time_per_frame;
format->FrameRate = 10000000L; format->FrameRate = 10000000L;
printf("num avg time per frame for video %Ld\n",stream->extended->avg_time_per_frame); printf("num avg time per frame for video %Ld\n",stream->extended_properties->avg_time_per_frame);
} }
return true; return true;
@@ -210,9 +210,9 @@ ASFFileReader::getStreamDuration(uint32 streamIndex)
if (stream) { if (stream) {
if (stream->flags & ASF_STREAM_FLAG_EXTENDED) { if (stream->flags & ASF_STREAM_FLAG_EXTENDED) {
printf("STREAM %ld end time %Ld, start time %Ld\n",streamIndex, stream->extended->end_time, stream->extended->start_time); printf("STREAM %ld end time %Ld, start time %Ld\n",streamIndex, stream->extended_properties->end_time, stream->extended_properties->start_time);
if (stream->extended->end_time - stream->extended->start_time > 0) { if (stream->extended_properties->end_time - stream->extended_properties->start_time > 0) {
return stream->extended->end_time - stream->extended->start_time; return stream->extended_properties->end_time - stream->extended_properties->start_time;
} }
} }
} }
@@ -6,9 +6,7 @@ StaticLibrary libasfreader.a :
asf.c asf.c
byteio.c byteio.c
data.c data.c
fileio.c
guid.c guid.c
header.c header.c
parse.c parse.c
utf.c
; ;
@@ -1,5 +1,5 @@
/* libasf - An Advanced Systems Format media file parser /* libasf - An Advanced Systems Format media file parser
* Copyright (C) 2006-2007 Juho Vähä-Herttua * Copyright (C) 2006-2010 Juho Vähä-Herttua
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -21,13 +21,31 @@
#include "asf.h" #include "asf.h"
#include "asfint.h" #include "asfint.h"
#include "fileio.h"
#include "byteio.h" #include "byteio.h"
#include "header.h" #include "header.h"
#include "parse.h" #include "parse.h"
#include "data.h" #include "data.h"
#include "debug.h" #include "debug.h"
static int
asf_fileio_read_cb(void *stream, void *buffer, int size)
{
int ret;
ret = fread(buffer, 1, size, stream);
if (!ret && !feof(stream))
return -1;
return ret;
}
static int64_t
asf_fileio_seek_cb(void *stream, int64_t offset)
{
return fseek(stream, offset, SEEK_SET);
}
asf_file_t * asf_file_t *
asf_open_file(const char *filename) asf_open_file(const char *filename)
{ {
@@ -35,12 +53,12 @@ asf_open_file(const char *filename)
asf_iostream_t stream; asf_iostream_t stream;
FILE *fstream; FILE *fstream;
fstream = fopen(filename, "r"); fstream = fopen(filename, "rb");
if (!fstream) if (!fstream)
return NULL; return NULL;
stream.read = asf_fileio_read_cb; stream.read = asf_fileio_read_cb;
stream.write = asf_fileio_write_cb; stream.write = NULL;
stream.seek = asf_fileio_seek_cb; stream.seek = asf_fileio_seek_cb;
stream.opaque = fstream; stream.opaque = fstream;
@@ -80,7 +98,7 @@ asf_open_cb(asf_iostream_t *iostream)
file->streams[i].type = ASF_STREAM_TYPE_NONE; file->streams[i].type = ASF_STREAM_TYPE_NONE;
file->streams[i].flags = ASF_STREAM_FLAG_NONE; file->streams[i].flags = ASF_STREAM_FLAG_NONE;
file->streams[i].properties = NULL; file->streams[i].properties = NULL;
file->streams[i].extended = NULL; file->streams[i].extended_properties = NULL;
} }
return file; return file;
@@ -96,7 +114,7 @@ asf_init(asf_file_t *file)
tmp = asf_parse_header(file); tmp = asf_parse_header(file);
if (tmp < 0) { if (tmp < 0) {
printf("error parsing header: %d\n", tmp); debug_printf("error parsing header: %d", tmp);
return tmp; return tmp;
} }
file->position += tmp; file->position += tmp;
@@ -104,7 +122,7 @@ asf_init(asf_file_t *file)
tmp = asf_parse_data(file); tmp = asf_parse_data(file);
if (tmp < 0) { if (tmp < 0) {
printf("error parsing data object: %d\n", tmp); debug_printf("error parsing data object: %d", tmp);
return tmp; return tmp;
} }
file->position += tmp; file->position += tmp;
@@ -124,7 +142,7 @@ asf_init(asf_file_t *file)
file->index_position < file->file_size && !file->index) { file->index_position < file->file_size && !file->index) {
tmp = asf_parse_index(file); tmp = asf_parse_index(file);
if (tmp < 0) { if (tmp < 0) {
printf("Error finding index object! %d\n", tmp); debug_printf("Error finding index object! %d", tmp);
break; break;
} }
@@ -152,7 +170,7 @@ asf_init(asf_file_t *file)
for (tmp = 0; tmp < ASF_MAX_STREAMS; tmp++) { for (tmp = 0; tmp < ASF_MAX_STREAMS; tmp++) {
if (file->streams[tmp].type != ASF_STREAM_TYPE_NONE) { if (file->streams[tmp].type != ASF_STREAM_TYPE_NONE) {
debug_printf("stream %d of type %s found!", tmp, file->streams[tmp].type == 1 ? "Audio" : file->streams[tmp].type == 2 ? "Video" : "Unknown"); debug_printf("stream %d of type %d found!", tmp, file->streams[tmp].type);
} }
} }
@@ -176,7 +194,7 @@ asf_close(asf_file_t *file)
for (i=0; i < ASF_MAX_STREAMS; i++) { for (i=0; i < ASF_MAX_STREAMS; i++) {
free(file->streams[i].properties); free(file->streams[i].properties);
free(file->streams[i].extended); free(file->streams[i].extended_properties);
} }
free(file); free(file);
+102 -99
View File
@@ -1,5 +1,5 @@
/* libasf - An Advanced Systems Format media file parser /* libasf - An Advanced Systems Format media file parser
* Copyright (C) 2006-2007 Juho Vähä-Herttua * Copyright (C) 2006-2010 Juho Vähä-Herttua
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -19,9 +19,8 @@
#ifndef ASF_H #ifndef ASF_H
#define ASF_H #define ASF_H
/* used int types for different platforms */ /* used int types for different platforms */
#if !defined(__MINGW_H) && defined(_WIN32) #if defined(WIN32) && !defined(__MINGW_H)
typedef char int8_t; typedef char int8_t;
typedef unsigned char uint8_t; typedef unsigned char uint8_t;
typedef short int16_t; typedef short int16_t;
@@ -35,13 +34,83 @@ typedef unsigned __int64 uint64_t;
#include <stdint.h> #include <stdint.h>
#endif #endif
struct asf_guid_s { #if defined(WIN32) && defined(DLL_EXPORT)
uint32_t v1; # define LIBASF_API __declspec(dllexport)
uint32_t v2; #else
uint16_t v3; # define LIBASF_API
uint8_t v4[8]; #endif
typedef enum {
/* fatal errors related to library function */
ASF_ERROR_INTERNAL = -100, /* incorrect input to API calls */
ASF_ERROR_OUTOFMEM = -101, /* some malloc inside program failed */
/* errors related to reading data from stream */
ASF_ERROR_NEEDS_BYTES = -200, /* not enough data from read */
ASF_ERROR_EOF = -201, /* end of file reached */
ASF_ERROR_IO = -202, /* error reading or writing to file */
/* errors related to file being corrupted */
ASF_ERROR_INVALID_LENGTH = -300, /* length value conflict in input data */
ASF_ERROR_INVALID_VALUE = -301, /* other value conflict in input data */
ASF_ERROR_INVALID_OBJECT = -302, /* ASF object missing or in wrong place */
ASF_ERROR_INVALID_OBJECT_SIZE = -303, /* invalid ASF object size (too small) */
/* errors related to seeking, usually non-fatal */
ASF_ERROR_SEEKABLE = -400, /* file not seekable */
ASF_ERROR_SEEK = -401 /* file is seekable but seeking failed */
} asf_error_t;
typedef enum {
ASF_STREAM_TYPE_NONE = 0x00,
ASF_STREAM_TYPE_AUDIO = 0x01,
ASF_STREAM_TYPE_VIDEO = 0x02,
ASF_STREAM_TYPE_COMMAND = 0x03,
ASF_STREAM_TYPE_UNKNOWN = 0xff
} asf_stream_type_t;
#define ASF_STREAM_FLAG_NONE 0x0000
#define ASF_STREAM_FLAG_AVAILABLE 0x0001
#define ASF_STREAM_FLAG_HIDDEN 0x0002
#define ASF_STREAM_FLAG_EXTENDED 0x0004
/* waveformatex fields specified in Microsoft documentation:
http://msdn2.microsoft.com/en-us/library/ms713497.aspx */
struct asf_waveformatex_s {
uint16_t wFormatTag;
uint16_t nChannels;
uint32_t nSamplesPerSec;
uint32_t nAvgBytesPerSec;
uint16_t nBlockAlign;
uint16_t wBitsPerSample;
uint16_t cbSize;
uint8_t *data;
}; };
typedef struct asf_guid_s asf_guid_t; typedef struct asf_waveformatex_s asf_waveformatex_t;
#define ASF_BITMAPINFOHEADER_SIZE 40
/* bitmapinfoheader fields specified in Microsoft documentation:
http://msdn2.microsoft.com/en-us/library/ms532290.aspx */
struct asf_bitmapinfoheader_s {
uint32_t biSize;
uint32_t biWidth;
uint32_t biHeight;
uint16_t biPlanes;
uint16_t biBitCount;
uint32_t biCompression;
uint32_t biSizeImage;
uint32_t biXPelsPerMeter;
uint32_t biYPelsPerMeter;
uint32_t biClrUsed;
uint32_t biClrImportant;
uint8_t *data;
};
typedef struct asf_bitmapinfoheader_s asf_bitmapinfoheader_t;
struct asf_iostream_s { struct asf_iostream_s {
/* read function, returns -1 on error, 0 on EOF and read bytes /* read function, returns -1 on error, 0 on EOF and read bytes
@@ -102,6 +171,7 @@ struct asf_packet_s {
uint8_t *ec_data; /* error correction data array */ uint8_t *ec_data; /* error correction data array */
uint32_t length; /* length of this packet, usually constant per stream */ uint32_t length; /* length of this packet, usually constant per stream */
uint32_t sequence; /* sequence value reserved for future use, should be ignored */
uint32_t padding_length; /* length of the padding after the data in this packet */ uint32_t padding_length; /* length of the padding after the data in this packet */
uint32_t send_time; /* send time of this packet in milliseconds */ uint32_t send_time; /* send time of this packet in milliseconds */
uint16_t duration; /* duration of this packet in milliseconds */ uint16_t duration; /* duration of this packet in milliseconds */
@@ -118,55 +188,7 @@ struct asf_packet_s {
}; };
typedef struct asf_packet_s asf_packet_t; typedef struct asf_packet_s asf_packet_t;
/* waveformatex fields specified in Microsoft documentation: struct asf_stream_extended_properties_s {
http://msdn2.microsoft.com/en-us/library/ms713497.aspx */
struct asf_waveformatex_s {
uint16_t wFormatTag;
uint16_t nChannels;
uint32_t nSamplesPerSec;
uint32_t nAvgBytesPerSec;
uint16_t nBlockAlign;
uint16_t wBitsPerSample;
uint16_t cbSize;
uint8_t *data;
};
typedef struct asf_waveformatex_s asf_waveformatex_t;
#define ASF_BITMAPINFOHEADER_SIZE 40
/* bitmapinfoheader fields specified in Microsoft documentation:
http://msdn2.microsoft.com/en-us/library/ms532290.aspx */
struct asf_bitmapinfoheader_s {
uint32_t biSize;
uint32_t biWidth;
uint32_t biHeight;
uint16_t biPlanes;
uint16_t biBitCount;
uint32_t biCompression;
uint32_t biSizeImage;
uint32_t biXPelsPerMeter;
uint32_t biYPelsPerMeter;
uint32_t biClrUsed;
uint32_t biClrImportant;
uint8_t *data;
};
typedef struct asf_bitmapinfoheader_s asf_bitmapinfoheader_t;
enum asf_stream_type_e {
ASF_STREAM_TYPE_NONE = 0x00,
ASF_STREAM_TYPE_AUDIO = 0x01,
ASF_STREAM_TYPE_VIDEO = 0x02,
ASF_STREAM_TYPE_COMMAND = 0x03,
ASF_STREAM_TYPE_UNKNOWN = 0xff
};
typedef enum asf_stream_type_e asf_stream_type_t;
#define ASF_STREAM_FLAG_NONE 0x0000
#define ASF_STREAM_FLAG_AVAILABLE 0x0001
#define ASF_STREAM_FLAG_HIDDEN 0x0002
#define ASF_STREAM_FLAG_EXTENDED 0x0004
struct asf_stream_extended_s {
uint64_t start_time; uint64_t start_time;
uint64_t end_time; uint64_t end_time;
uint32_t data_bitrate; uint32_t data_bitrate;
@@ -183,7 +205,7 @@ struct asf_stream_extended_s {
uint16_t stream_name_count; uint16_t stream_name_count;
uint16_t num_payload_ext; uint16_t num_payload_ext;
}; };
typedef struct asf_stream_extended_s asf_stream_extended_t; typedef struct asf_stream_extended_properties_s asf_stream_extended_properties_t;
struct asf_stream_s { struct asf_stream_s {
asf_stream_type_t type; /* type of this current stream */ asf_stream_type_t type; /* type of this current stream */
@@ -195,101 +217,82 @@ struct asf_stream_s {
/* pointer to extended properties of the stream if they specified /* pointer to extended properties of the stream if they specified
* only available if ASF_STREAM_FLAG_EXTENDED flag is set, otherwise NULL */ * only available if ASF_STREAM_FLAG_EXTENDED flag is set, otherwise NULL */
asf_stream_extended_t *extended; asf_stream_extended_properties_t *extended_properties;
}; };
typedef struct asf_stream_s asf_stream_t; typedef struct asf_stream_s asf_stream_t;
typedef struct asf_file_s asf_file_t; typedef struct asf_file_s asf_file_t;
enum asf_error_e {
ASF_ERROR_INTERNAL = -1, /* incorrect input to API calls */
ASF_ERROR_OUTOFMEM = -2, /* some malloc inside program failed */
ASF_ERROR_EOF = -3, /* unexpected end of file */
ASF_ERROR_IO = -4, /* error reading or writing to file */
ASF_ERROR_INVALID_LENGTH = -5, /* length value conflict in input data */
ASF_ERROR_INVALID_VALUE = -6, /* other value conflict in input data */
ASF_ERROR_INVALID_OBJECT = -7, /* ASF object missing or in wrong place */
ASF_ERROR_OBJECT_SIZE = -8, /* invalid ASF object size (too small) */
ASF_ERROR_SEEKABLE = -9, /* file not seekable */
ASF_ERROR_SEEK = -10 /* file is seekable but seeking failed */
};
struct asf_object_s {
asf_guid_t guid;
uint64_t size;
uint8_t *data;
};
typedef struct asf_object_s asf_object_t;
/* initialize the library using file on a local filesystem */ /* initialize the library using file on a local filesystem */
asf_file_t *asf_open_file(const char *filename); LIBASF_API asf_file_t *asf_open_file(const char *filename);
/* initialize the library using callbacks defined on a stream structure, /* initialize the library using callbacks defined on a stream structure,
the stream structure can be freed after calling this function */ the stream structure can be freed after calling this function */
asf_file_t *asf_open_cb(asf_iostream_t *iostream); LIBASF_API asf_file_t *asf_open_cb(asf_iostream_t *iostream);
/* close the library handle and free all allocated memory */ /* close the library handle and free all allocated memory */
void asf_close(asf_file_t *file); LIBASF_API void asf_close(asf_file_t *file);
/* initialize the library and read all header information of the ASF file */ /* initialize the library and read all header information of the ASF file */
int asf_init(asf_file_t *file); LIBASF_API int asf_init(asf_file_t *file);
/* create a packet structure for reading data packets */ /* create a packet structure for reading data packets */
asf_packet_t *asf_packet_create(); LIBASF_API asf_packet_t *asf_packet_create();
/* free the packet structure allocated earlier, need to be called only once */ /* free the packet structure allocated earlier, need to be called only once */
void asf_packet_destroy(asf_packet_t *packet); LIBASF_API void asf_packet_destroy(asf_packet_t *packet);
/* get next packet from the stream to the specified packet structure */ /* get next packet from the stream to the specified packet structure */
int asf_get_packet(asf_file_t *file, asf_packet_t *packet); LIBASF_API int asf_get_packet(asf_file_t *file, asf_packet_t *packet);
/* seek to the closest (key frame) packet specified by milliseconds position */ /* seek to the closest (key frame) packet specified by milliseconds position */
int64_t asf_seek_to_msec(asf_file_t *file, int64_t msec); LIBASF_API int64_t asf_seek_to_msec(asf_file_t *file, int64_t msec);
/* get metadata information of the ASF file handle */ /* get metadata information of the ASF file handle */
asf_metadata_t *asf_header_get_metadata(asf_file_t *file); LIBASF_API asf_metadata_t *asf_header_get_metadata(asf_file_t *file);
/* free metadata structure received from the library */ /* free metadata structure received from the library */
void asf_metadata_destroy(asf_metadata_t *metadata); LIBASF_API void asf_metadata_destroy(asf_metadata_t *metadata);
/* free all header information from the ASF file structure /* free all header information from the ASF file structure
* WARNING: after calling this function all asf_header_* * WARNING: after calling this function all asf_header_*
* functions will return NULL or failure!!! */ * functions will return NULL or failure!!! */
void asf_header_destroy(asf_file_t *file); LIBASF_API void asf_header_destroy(asf_file_t *file);
/* calculate how many streams are available in current ASF file */ /* calculate how many streams are available in current ASF file */
uint8_t asf_get_stream_count(asf_file_t *file); LIBASF_API uint8_t asf_get_stream_count(asf_file_t *file);
/* get info of a stream, the resulting pointer and its contents should NOT be freed */ /* get info of a stream, the resulting pointer and its contents should NOT be freed */
asf_stream_t *asf_get_stream(asf_file_t *file, uint8_t track); LIBASF_API asf_stream_t *asf_get_stream(asf_file_t *file, uint8_t track);
/* return non-zero if the file is broadcasted, 0 otherwise */ /* return non-zero if the file is broadcasted, 0 otherwise */
int asf_is_broadcast(asf_file_t *file); LIBASF_API int asf_is_broadcast(asf_file_t *file);
/* return non-zero if the file is seekable, 0 otherwise */ /* return non-zero if the file is seekable, 0 otherwise */
int asf_is_seekable(asf_file_t *file); LIBASF_API int asf_is_seekable(asf_file_t *file);
/* get size of the ASF file in bytes */ /* get size of the ASF file in bytes */
uint64_t asf_get_file_size(asf_file_t *file); LIBASF_API uint64_t asf_get_file_size(asf_file_t *file);
/* get creation date in 100-nanosecond units since Jan 1, 1601 GMT /* get creation date in 100-nanosecond units since Jan 1, 1601 GMT
this value should be ignored for broadcasts */ this value should be ignored for broadcasts */
uint64_t asf_get_creation_date(asf_file_t *file); LIBASF_API uint64_t asf_get_creation_date(asf_file_t *file);
/* get number of data packets available in this file /* get number of data packets available in this file
this value should be ignored for broadcasts */ this value should be ignored for broadcasts */
uint64_t asf_get_data_packets(asf_file_t *file); LIBASF_API uint64_t asf_get_data_packets(asf_file_t *file);
/* get play duration of the file in 100-nanosecond units, /* get play duration of the file in 100-nanosecond units,
this value should be ignored for broadcasts */ this value should be ignored for broadcasts */
uint64_t asf_get_duration(asf_file_t *file); LIBASF_API uint64_t asf_get_duration(asf_file_t *file);
/* maximum bitrate as bits per second in the entire file */ /* maximum bitrate as bits per second in the entire file */
uint32_t asf_get_max_bitrate(asf_file_t *file); LIBASF_API uint32_t asf_get_max_bitrate(asf_file_t *file);
#endif #endif
@@ -1,5 +1,5 @@
/* libasf - An Advanced Systems Format media file parser /* libasf - An Advanced Systems Format media file parser
* Copyright (C) 2006-2007 Juho Vähä-Herttua * Copyright (C) 2006-2010 Juho Vähä-Herttua
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -19,8 +19,28 @@
#ifndef ASFINT_H #ifndef ASFINT_H
#define ASFINT_H #define ASFINT_H
#include <string.h>
#include "asf.h" #include "asf.h"
#include "guid.h" #include "guid.h"
#include "compat.h"
static INLINE void
GetGUID(const void *pointer, asf_guid_t *guid)
{
const uint8_t *data = pointer;
guid->v1 = GetDWLE(data);
guid->v2 = GetWLE(data + 4);
guid->v3 = GetWLE(data + 6);
memcpy(guid->v4, data + 8, 8);
}
#define GETLEN2b(bits) (((bits) == 0x03) ? 4 : bits)
#define GETVALUE2b(bits, data) \
(((bits) != 0x03) ? ((bits) != 0x02) ? ((bits) != 0x01) ? \
0 : *((uint8_t *)data) : GetWLE(data) : GetDWLE(data))
/* DO NOT MODIFY THE FIRST 3 VARIABLES, BECAUSE THEY ARE /* DO NOT MODIFY THE FIRST 3 VARIABLES, BECAUSE THEY ARE
* ALSO DEFINED IN asf.h HEADER AND WILL BREAK THINGS */ * ALSO DEFINED IN asf.h HEADER AND WILL BREAK THINGS */
@@ -1,5 +1,5 @@
/* libasf - An Advanced Systems Format media file parser /* libasf - An Advanced Systems Format media file parser
* Copyright (C) 2006-2007 Juho Vähä-Herttua * Copyright (C) 2006-2010 Juho Vähä-Herttua
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -17,71 +17,12 @@
*/ */
#include <string.h> #include <string.h>
#include "asfint.h"
#include "byteio.h" #include "byteio.h"
uint16_t
asf_byteio_getWLE(uint8_t *data)
{
uint16_t ret;
int i;
for (i=1, ret=0; i>=0; i--) {
ret <<= 8;
ret |= data[i];
}
return ret;
}
uint32_t
asf_byteio_getDWLE(uint8_t *data)
{
uint32_t ret;
int i;
for (i=3, ret=0; i>=0; i--) {
ret <<= 8;
ret |= data[i];
}
return ret;
}
uint64_t
asf_byteio_getQWLE(uint8_t *data)
{
uint64_t ret;
int i;
for (i=7, ret=0; i>=0; i--) {
ret <<= 8;
ret |= data[i];
}
return ret;
}
void
asf_byteio_getGUID(asf_guid_t *guid, uint8_t *data)
{
guid->v1 = asf_byteio_getDWLE(data);
guid->v2 = asf_byteio_getWLE(data + 4);
guid->v3 = asf_byteio_getWLE(data + 6);
memcpy(guid->v4, data + 8, 8);
}
void
asf_byteio_get_string(uint16_t *string, uint16_t strlen, uint8_t *data)
{
int i;
for (i=0; i<strlen; i++) {
string[i] = asf_byteio_getWLE(data + i*2);
}
}
int int
asf_byteio_read(uint8_t *data, int size, asf_iostream_t *iostream) asf_byteio_read(asf_iostream_t *iostream, uint8_t *data, int size)
{ {
int read = 0, tmp; int read = 0, tmp;
@@ -91,12 +32,14 @@ asf_byteio_read(uint8_t *data, int size, asf_iostream_t *iostream)
while ((tmp = iostream->read(iostream->opaque, data+read, size-read)) > 0) { while ((tmp = iostream->read(iostream->opaque, data+read, size-read)) > 0) {
read += tmp; read += tmp;
if (read == size) { if (read == size) {
return read; return read;
} }
} }
/* FIXME: should return tmp if any bytes were read, but the
rest of the code needs to be fixed before that */
return (tmp == 0) ? ASF_ERROR_EOF : ASF_ERROR_IO; return (tmp == 0) ? ASF_ERROR_EOF : ASF_ERROR_IO;
} }
@@ -1,5 +1,5 @@
/* libasf - An Advanced Systems Format media file parser /* libasf - An Advanced Systems Format media file parser
* Copyright (C) 2006-2007 Juho Vähä-Herttua * Copyright (C) 2006-2010 Juho Vähä-Herttua
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -22,12 +22,6 @@
#include "asf.h" #include "asf.h"
#include "guid.h" #include "guid.h"
uint16_t asf_byteio_getWLE(uint8_t *data); int asf_byteio_read(asf_iostream_t *iostream, uint8_t *data, int size);
uint32_t asf_byteio_getDWLE(uint8_t *data);
uint64_t asf_byteio_getQWLE(uint8_t *data);
void asf_byteio_getGUID(asf_guid_t *guid, uint8_t *data);
void asf_byteio_get_string(uint16_t *string, uint16_t strlen, uint8_t *data);
int asf_byteio_read(uint8_t *data, int size, asf_iostream_t *iostream);
#endif #endif
@@ -0,0 +1,60 @@
/* libasf - An Advanced Systems Format media file parser
* Copyright (C) 2006-2010 Juho Vähä-Herttua
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef COMPAT_H
#define COMPAT_H
#ifdef __GNUC__
# define INLINE __inline__
#else
# define INLINE
#endif
static INLINE uint16_t
GetWLE(const void *pointer)
{
const uint8_t *data = pointer;
return ((uint16_t)data[1] << 8) |
((uint16_t)data[0]);
}
static INLINE uint32_t
GetDWLE(const void *pointer)
{
const uint8_t *data = pointer;
return ((uint32_t)data[3] << 24) |
((uint32_t)data[2] << 16) |
((uint32_t)data[1] << 8) |
((uint32_t)data[0]);
}
static INLINE uint64_t
GetQWLE(const void *pointer)
{
const uint8_t *data = pointer;
return ((uint64_t)data[7] << 56) |
((uint64_t)data[6] << 48) |
((uint64_t)data[5] << 40) |
((uint64_t)data[4] << 32) |
((uint64_t)data[3] << 24) |
((uint64_t)data[2] << 16) |
((uint64_t)data[1] << 8) |
((uint64_t)data[0]);
}
#endif
@@ -1,5 +1,5 @@
/* libasf - An Advanced Systems Format media file parser /* libasf - An Advanced Systems Format media file parser
* Copyright (C) 2006-2007 Juho Vähä-Herttua * Copyright (C) 2006-2010 Juho Vähä-Herttua
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -19,22 +19,15 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "asf.h"
#include "asfint.h" #include "asfint.h"
#include "byteio.h" #include "byteio.h"
#include "data.h" #include "data.h"
#include "parse.h" #include "parse.h"
#include "debug.h" #include "debug.h"
#define GETLEN2b(bits) (((bits) == 0x03) ? 4 : bits)
#define GETVALUE2b(bits, data) \
(((bits) != 0x03) ? ((bits) != 0x02) ? ((bits) != 0x01) ? \
0 : *(data) : asf_byteio_getWLE(data) : asf_byteio_getDWLE(data))
static int static int
asf_data_read_packet_data(asf_packet_t *packet, uint8_t flags, asf_data_read_packet_fields(asf_packet_t *packet, uint8_t flags,
uint8_t *data, uint32_t len) uint8_t *data, uint32_t len)
{ {
uint8_t datalen; uint8_t datalen;
@@ -48,21 +41,20 @@ asf_data_read_packet_data(asf_packet_t *packet, uint8_t flags,
packet->length = GETVALUE2b((flags >> 5) & 0x03, data); packet->length = GETVALUE2b((flags >> 5) & 0x03, data);
data += GETLEN2b((flags >> 5) & 0x03); data += GETLEN2b((flags >> 5) & 0x03);
/* sequence value should be never used anywhere */ packet->sequence = GETVALUE2b((flags >> 1) & 0x03, data);
GETVALUE2b((flags >> 1) & 0x03, data);
data += GETLEN2b((flags >> 1) & 0x03); data += GETLEN2b((flags >> 1) & 0x03);
packet->padding_length = GETVALUE2b((flags >> 3) & 0x03, data); packet->padding_length = GETVALUE2b((flags >> 3) & 0x03, data);
data += GETLEN2b((flags >> 3) & 0x03); data += GETLEN2b((flags >> 3) & 0x03);
packet->send_time = asf_byteio_getDWLE(data); packet->send_time = GetDWLE(data);
data += 4; data += 4;
packet->duration = asf_byteio_getWLE(data); packet->duration = GetWLE(data);
data += 2; data += 2;
return datalen; return datalen;
} }
static int static int
asf_data_read_payload_data(asf_payload_t *payload, uint8_t flags, uint8_t *data, int size) asf_data_read_payload_fields(asf_payload_t *payload, uint8_t flags, uint8_t *data, int size)
{ {
uint8_t datalen; uint8_t datalen;
@@ -88,24 +80,27 @@ static int
asf_data_read_payloads(asf_packet_t *packet, asf_data_read_payloads(asf_packet_t *packet,
uint64_t preroll, uint64_t preroll,
uint8_t multiple, uint8_t multiple,
uint8_t type,
uint8_t flags, uint8_t flags,
uint8_t *data, uint8_t *data,
uint32_t datalen) uint32_t datalen)
{ {
asf_payload_t pl; asf_payload_t pl;
int i, tmp, skip; uint32_t skip;
int i, tmp;
skip = 0, i = 0; skip = 0, i = 0;
while (i < packet->payload_count) { while (i < packet->payload_count) {
uint8_t pts_delta = 0; uint8_t pts_delta = 0;
int compressed = 0; int compressed = 0;
if (skip+1 > datalen) {
return ASF_ERROR_INVALID_LENGTH;
}
pl.stream_number = data[skip] & 0x7f; pl.stream_number = data[skip] & 0x7f;
pl.key_frame = !!(data[skip] & 0x80); pl.key_frame = !!(data[skip] & 0x80);
skip++; skip++;
tmp = asf_data_read_payload_data(&pl, flags, data + skip, datalen - skip); tmp = asf_data_read_payload_fields(&pl, flags, data + skip, datalen - skip);
if (tmp < 0) { if (tmp < 0) {
return tmp; return tmp;
} }
@@ -119,9 +114,9 @@ asf_data_read_payloads(asf_packet_t *packet,
pl.replicated_data = data + skip; pl.replicated_data = data + skip;
skip += pl.replicated_length; skip += pl.replicated_length;
pl.pts = asf_byteio_getDWLE(pl.replicated_data + 4); pl.pts = GetDWLE(pl.replicated_data + 4);
} else if (pl.replicated_length == 1) { } else if (pl.replicated_length == 1) {
if (skip >= datalen) { if (skip+1 > datalen) {
/* not enough data */ /* not enough data */
return ASF_ERROR_INVALID_LENGTH; return ASF_ERROR_INVALID_LENGTH;
} }
@@ -142,29 +137,26 @@ asf_data_read_payloads(asf_packet_t *packet,
} }
/* substract preroll value from pts since it's counted in */ /* substract preroll value from pts since it's counted in */
pl.pts -= preroll; if (pl.pts > preroll) {
/* FIXME: check that pts is positive */ pl.pts -= preroll;
} else {
pl.pts = 0;
}
if (multiple) { if (multiple) {
tmp = GETLEN2b(type); if (skip + 2 > datalen) {
if (tmp != 2) {
/* in multiple payloads datalen should be a word */
return ASF_ERROR_INVALID_VALUE;
}
if (skip + tmp > datalen) {
/* not enough data */ /* not enough data */
return ASF_ERROR_INVALID_LENGTH; return ASF_ERROR_INVALID_LENGTH;
} }
pl.datalen = GetWLE(data + skip);
pl.datalen = GETVALUE2b(type, data + skip); skip += 2;
skip += tmp;
} else { } else {
pl.datalen = datalen - skip; pl.datalen = datalen - skip;
} }
if (compressed) { if (compressed) {
int payloads, start = skip, used = 0; uint32_t start = skip, used = 0;
int payloads, idx;
/* count how many compressed payloads this payload includes */ /* count how many compressed payloads this payload includes */
for (payloads=0; used < pl.datalen; payloads++) { for (payloads=0; used < pl.datalen; payloads++) {
@@ -190,20 +182,22 @@ asf_data_read_payloads(asf_packet_t *packet,
packet->payloads_size = packet->payload_count; packet->payloads_size = packet->payload_count;
} }
while (skip < start + used) { for (idx = 0; idx < payloads; idx++) {
pl.datalen = data[skip]; pl.datalen = data[skip];
skip++; skip++;
/* Set data correctly */
pl.data = data + skip; pl.data = data + skip;
skip += pl.datalen; skip += pl.datalen;
pl.pts += pts_delta; /* Copy the final payload and update the PTS */
memcpy(&packet->payloads[i], &pl, sizeof(asf_payload_t)); memcpy(&packet->payloads[i], &pl, sizeof(asf_payload_t));
packet->payloads[i].pts = pl.pts + idx * pts_delta;
i++; i++;
debug_printf("payload(%d/%d) stream: %d, key frame: %d, object: %d, offset: %d, pts: %d, datalen: %d", debug_printf("payload(%d/%d) stream: %d, key frame: %d, object: %d, offset: %d, pts: %d, datalen: %d",
i, packet->payload_count, pl.stream_number, (int) pl.key_frame, pl.media_object_number, i, packet->payload_count, pl.stream_number, (int) pl.key_frame, pl.media_object_number,
pl.media_object_offset, pl.pts, pl.datalen); pl.media_object_offset, pl.pts + idx * pts_delta, pl.datalen);
} }
} else { } else {
pl.data = data + skip; pl.data = data + skip;
@@ -249,7 +243,7 @@ asf_data_get_packet(asf_packet_t *packet, asf_file_t *file)
{ {
asf_iostream_t *iostream; asf_iostream_t *iostream;
uint32_t read = 0; uint32_t read = 0;
int packet_flags, packet_property, payload_length_type; int packet_flags, packet_property;
void *tmpptr; void *tmpptr;
int tmp; int tmp;
@@ -268,9 +262,7 @@ asf_data_get_packet(asf_packet_t *packet, asf_file_t *file)
packet->data_size = file->packet_size; packet->data_size = file->packet_size;
} }
tmp = asf_byteio_read(packet->data, tmp = asf_byteio_read(iostream, packet->data, file->packet_size);
file->packet_size,
iostream);
if (tmp < 0) { if (tmp < 0) {
/* Error reading packet data */ /* Error reading packet data */
return tmp; return tmp;
@@ -298,6 +290,7 @@ asf_data_get_packet(asf_packet_t *packet, asf_file_t *file)
read += packet->ec_length; read += packet->ec_length;
} else { } else {
packet->ec_length = 0; packet->ec_length = 0;
packet->ec_data = NULL;
} }
if (read+2 > file->packet_size) { if (read+2 > file->packet_size) {
@@ -306,10 +299,9 @@ asf_data_get_packet(asf_packet_t *packet, asf_file_t *file)
packet_flags = packet->data[read++]; packet_flags = packet->data[read++];
packet_property = packet->data[read++]; packet_property = packet->data[read++];
tmp = asf_data_read_packet_data(packet, tmp = asf_data_read_packet_fields(packet, packet_flags,
packet_flags, packet->data + read,
&packet->data[read], file->packet_size - read);
file->packet_size - read);
if (tmp < 0) { if (tmp < 0) {
return tmp; return tmp;
} }
@@ -318,13 +310,13 @@ asf_data_get_packet(asf_packet_t *packet, asf_file_t *file)
/* this is really idiotic, packet length can (and often will) be /* this is really idiotic, packet length can (and often will) be
* undefined and we just have to use the header packet size as the size * undefined and we just have to use the header packet size as the size
* value */ * value */
if (!((packet_flags >> 5) & 0x03)) { if (((packet_flags >> 5) & 0x03) == 0) {
packet->length = file->packet_size; packet->length = file->packet_size;
} }
/* this is also really idiotic, if packet length is smaller than packet /* this is also really idiotic, if packet length is smaller than packet
* size, we need to manually add the additional bytes into padding length * size, we need to manually add the additional bytes into padding length
*/ * because the padding bytes only count up to packet length value */
if (packet->length < file->packet_size) { if (packet->length < file->packet_size) {
packet->padding_length += file->packet_size - packet->length; packet->padding_length += file->packet_size - packet->length;
packet->length = file->packet_size; packet->length = file->packet_size;
@@ -337,6 +329,8 @@ asf_data_get_packet(asf_packet_t *packet, asf_file_t *file)
/* check if we have multiple payloads */ /* check if we have multiple payloads */
if (packet_flags & 0x01) { if (packet_flags & 0x01) {
int payload_length_type;
if (read+1 > packet->length) { if (read+1 > packet->length) {
return ASF_ERROR_INVALID_LENGTH; return ASF_ERROR_INVALID_LENGTH;
} }
@@ -344,11 +338,19 @@ asf_data_get_packet(asf_packet_t *packet, asf_file_t *file)
packet->payload_count = tmp & 0x3f; packet->payload_count = tmp & 0x3f;
payload_length_type = (tmp >> 6) & 0x03; payload_length_type = (tmp >> 6) & 0x03;
if (packet->payload_count == 0) {
/* there should always be at least one payload */
return ASF_ERROR_INVALID_VALUE;
}
if (payload_length_type != 0x02) {
/* in multiple payloads datalen should always be a word */
return ASF_ERROR_INVALID_VALUE;
}
} else { } else {
packet->payload_count = 1; packet->payload_count = 1;
payload_length_type = 0x02; /* not used */
} }
packet->payload_data_len = packet->length - read; packet->payload_data_len = packet->length - read;
if (packet->payload_count > packet->payloads_size) { if (packet->payload_count > packet->payloads_size) {
@@ -363,11 +365,10 @@ asf_data_get_packet(asf_packet_t *packet, asf_file_t *file)
packet->payload_data = &packet->data[read]; packet->payload_data = &packet->data[read];
read += packet->payload_data_len; read += packet->payload_data_len;
/* The return value will be consumed bytes, not including the padding */ /* The return value will be consumed bytes, not including the padding */
tmp = asf_data_read_payloads(packet, file->preroll, packet_flags & 0x01, tmp = asf_data_read_payloads(packet, file->preroll, packet_flags & 0x01,
payload_length_type, packet_property, packet_property, packet->payload_data,
packet->payload_data,
packet->payload_data_len - packet->padding_length); packet->payload_data_len - packet->padding_length);
if (tmp < 0) { if (tmp < 0) {
return tmp; return tmp;
@@ -1,5 +1,5 @@
/* libasf - An Advanced Systems Format media file parser /* libasf - An Advanced Systems Format media file parser
* Copyright (C) 2006-2007 Juho Vähä-Herttua * Copyright (C) 2006-2010 Juho Vähä-Herttua
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -1,5 +1,5 @@
/* libasf - An Advanced Systems Format media file parser /* libasf - An Advanced Systems Format media file parser
* Copyright (C) 2006-2007 Juho Vähä-Herttua * Copyright (C) 2006-2010 Juho Vähä-Herttua
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -22,23 +22,24 @@
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#ifdef __GNUC__ #include "asfint.h"
# define INLINE static __inline__
#else
# define INLINE
#endif
INLINE void
#if defined(WIN32) && defined(DEBUG)
# define debug_printf printf
#else
static void
debug_printf(char *fmt, ...) debug_printf(char *fmt, ...)
{ {
#ifdef DEBUG # ifdef DEBUG
va_list argp; va_list argp;
va_start(argp, fmt); va_start(argp, fmt);
vfprintf(stderr, fmt, argp); vfprintf(stderr, fmt, argp);
va_end(argp); va_end(argp);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
#endif # endif
} }
#endif
#endif #endif
@@ -1,63 +0,0 @@
/* libasf - An Advanced Systems Format media file parser
* Copyright (C) 2006-2007 Juho Vähä-Herttua
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include "asf.h"
/**
* Implement callback functions for basic file I/O operations,
* so that users wouldn't need to reimplement them.
*/
int
asf_fileio_read_cb(FILE *stream, void *buffer, int size)
{
int ret;
ret = fread(buffer, 1, size, stream);
if (!ret && !feof(stream))
ret = -1;
return ret;
}
int
asf_fileio_write_cb(FILE *stream, void *buffer, int size)
{
int ret;
ret = fwrite(buffer, 1, size, stream);
if (!ret && !feof(stream))
ret = -1;
return ret;
}
int64_t
asf_fileio_seek_cb(FILE *stream, int64_t offset)
{
int ret;
ret = fseek(stream, offset, SEEK_SET);
if (ret < 0)
return -1;
return offset;
}
@@ -1,28 +0,0 @@
/* libasf - An Advanced Systems Format media file parser
* Copyright (C) 2006-2007 Juho Vähä-Herttua
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef FILEIO_H
#define FILEIO_H
#include "asf.h"
int asf_fileio_read_cb(void *stream, void *buffer, int size);
int asf_fileio_write_cb(void *stream, void *buffer, int size);
int64_t asf_fileio_seek_cb(void *stream, int64_t offset);
#endif
@@ -1,5 +1,5 @@
/* libasf - An Advanced Systems Format media file parser /* libasf - An Advanced Systems Format media file parser
* Copyright (C) 2006-2007 Juho Vähä-Herttua * Copyright (C) 2006-2010 Juho Vähä-Herttua
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -103,7 +103,7 @@ static const asf_guid_t asf_guid_stream_type_extended_audio =
int int
asf_guid_match(const asf_guid_t *guid1, const asf_guid_t *guid2) asf_guid_equals(const asf_guid_t *guid1, const asf_guid_t *guid2)
{ {
if((guid1->v1 != guid2->v1) || if((guid1->v1 != guid2->v1) ||
(guid1->v2 != guid2->v2) || (guid1->v2 != guid2->v2) ||
@@ -120,41 +120,41 @@ asf_guid_get_object_type(const asf_guid_t *guid)
{ {
guid_type_t ret = GUID_UNKNOWN; guid_type_t ret = GUID_UNKNOWN;
if (asf_guid_match(guid, &asf_guid_header)) if (asf_guid_equals(guid, &asf_guid_header))
ret = GUID_HEADER; ret = GUID_HEADER;
else if (asf_guid_match(guid, &asf_guid_data)) else if (asf_guid_equals(guid, &asf_guid_data))
ret = GUID_DATA; ret = GUID_DATA;
else if (asf_guid_match(guid, &asf_guid_index)) else if (asf_guid_equals(guid, &asf_guid_index))
ret = GUID_INDEX; ret = GUID_INDEX;
else if (asf_guid_match(guid, &asf_guid_file_properties)) else if (asf_guid_equals(guid, &asf_guid_file_properties))
ret = GUID_FILE_PROPERTIES; ret = GUID_FILE_PROPERTIES;
else if (asf_guid_match(guid, &asf_guid_stream_properties)) else if (asf_guid_equals(guid, &asf_guid_stream_properties))
ret = GUID_STREAM_PROPERTIES; ret = GUID_STREAM_PROPERTIES;
else if (asf_guid_match(guid, &asf_guid_content_description)) else if (asf_guid_equals(guid, &asf_guid_content_description))
ret = GUID_CONTENT_DESCRIPTION; ret = GUID_CONTENT_DESCRIPTION;
else if (asf_guid_match(guid, &asf_guid_header_extension)) else if (asf_guid_equals(guid, &asf_guid_header_extension))
ret = GUID_HEADER_EXTENSION; ret = GUID_HEADER_EXTENSION;
else if (asf_guid_match(guid, &asf_guid_marker)) else if (asf_guid_equals(guid, &asf_guid_marker))
ret = GUID_MARKER; ret = GUID_MARKER;
else if (asf_guid_match(guid, &asf_guid_codec_list)) else if (asf_guid_equals(guid, &asf_guid_codec_list))
ret = GUID_CODEC_LIST; ret = GUID_CODEC_LIST;
else if (asf_guid_match(guid, &asf_guid_stream_bitrate_properties)) else if (asf_guid_equals(guid, &asf_guid_stream_bitrate_properties))
ret = GUID_STREAM_BITRATE_PROPERTIES; ret = GUID_STREAM_BITRATE_PROPERTIES;
else if (asf_guid_match(guid, &asf_guid_padding)) else if (asf_guid_equals(guid, &asf_guid_padding))
ret = GUID_PADDING; ret = GUID_PADDING;
else if (asf_guid_match(guid, &asf_guid_extended_content_description)) else if (asf_guid_equals(guid, &asf_guid_extended_content_description))
ret = GUID_EXTENDED_CONTENT_DESCRIPTION; ret = GUID_EXTENDED_CONTENT_DESCRIPTION;
else if (asf_guid_match(guid, &asf_guid_metadata)) else if (asf_guid_equals(guid, &asf_guid_metadata))
ret = GUID_METADATA; ret = GUID_METADATA;
else if (asf_guid_match(guid, &asf_guid_language_list)) else if (asf_guid_equals(guid, &asf_guid_language_list))
ret = GUID_LANGUAGE_LIST; ret = GUID_LANGUAGE_LIST;
else if (asf_guid_match(guid, &asf_guid_extended_stream_properties)) else if (asf_guid_equals(guid, &asf_guid_extended_stream_properties))
ret = GUID_EXTENDED_STREAM_PROPERTIES; ret = GUID_EXTENDED_STREAM_PROPERTIES;
else if (asf_guid_match(guid, &asf_guid_advanced_mutual_exclusion)) else if (asf_guid_equals(guid, &asf_guid_advanced_mutual_exclusion))
ret = GUID_ADVANCED_MUTUAL_EXCLUSION; ret = GUID_ADVANCED_MUTUAL_EXCLUSION;
else if (asf_guid_match(guid, &asf_guid_stream_prioritization)) else if (asf_guid_equals(guid, &asf_guid_stream_prioritization))
ret = GUID_STREAM_PRIORITIZATION; ret = GUID_STREAM_PRIORITIZATION;
return ret; return ret;
@@ -165,15 +165,15 @@ asf_guid_get_stream_type(const asf_guid_t *guid)
{ {
guid_type_t ret = GUID_UNKNOWN; guid_type_t ret = GUID_UNKNOWN;
if (asf_guid_match(guid, &asf_guid_stream_type_audio)) if (asf_guid_equals(guid, &asf_guid_stream_type_audio))
ret = GUID_STREAM_TYPE_AUDIO; ret = GUID_STREAM_TYPE_AUDIO;
else if (asf_guid_match(guid, &asf_guid_stream_type_video)) else if (asf_guid_equals(guid, &asf_guid_stream_type_video))
ret = GUID_STREAM_TYPE_VIDEO; ret = GUID_STREAM_TYPE_VIDEO;
else if (asf_guid_match(guid, &asf_guid_stream_type_command)) else if (asf_guid_equals(guid, &asf_guid_stream_type_command))
ret = GUID_STREAM_TYPE_COMMAND; ret = GUID_STREAM_TYPE_COMMAND;
else if (asf_guid_match(guid, &asf_guid_stream_type_extended)) else if (asf_guid_equals(guid, &asf_guid_stream_type_extended))
ret = GUID_STREAM_TYPE_EXTENDED; ret = GUID_STREAM_TYPE_EXTENDED;
else if (asf_guid_match(guid, &asf_guid_stream_type_extended_audio)) else if (asf_guid_equals(guid, &asf_guid_stream_type_extended_audio))
ret = GUID_STREAM_TYPE_EXTENDED_AUDIO; ret = GUID_STREAM_TYPE_EXTENDED_AUDIO;
return ret; return ret;
@@ -1,5 +1,5 @@
/* libasf - An Advanced Systems Format media file parser /* libasf - An Advanced Systems Format media file parser
* Copyright (C) 2006-2007 Juho Vähä-Herttua * Copyright (C) 2006-2010 Juho Vähä-Herttua
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -21,7 +21,15 @@
#include "asf.h" #include "asf.h"
enum guid_type_e { struct asf_guid_s {
uint32_t v1;
uint32_t v2;
uint16_t v3;
uint8_t v4[8];
};
typedef struct asf_guid_s asf_guid_t;
typedef enum {
GUID_UNKNOWN, GUID_UNKNOWN,
GUID_HEADER, GUID_HEADER,
@@ -49,11 +57,10 @@ enum guid_type_e {
GUID_STREAM_TYPE_COMMAND, GUID_STREAM_TYPE_COMMAND,
GUID_STREAM_TYPE_EXTENDED, GUID_STREAM_TYPE_EXTENDED,
GUID_STREAM_TYPE_EXTENDED_AUDIO GUID_STREAM_TYPE_EXTENDED_AUDIO
}; } guid_type_t;
typedef enum guid_type_e guid_type_t;
int asf_guid_match(const asf_guid_t *guid1, const asf_guid_t *guid2); int asf_guid_equals(const asf_guid_t *guid1, const asf_guid_t *guid2);
guid_type_t asf_guid_get_object_type(const asf_guid_t *guid); guid_type_t asf_guid_get_object_type(const asf_guid_t *guid);
guid_type_t asf_guid_get_stream_type(const asf_guid_t *guid); guid_type_t asf_guid_get_stream_type(const asf_guid_t *guid);
guid_type_t asf_guid_get_type(const asf_guid_t *guid); guid_type_t asf_guid_get_type(const asf_guid_t *guid);
@@ -1,5 +1,5 @@
/* libasf - An Advanced Systems Format media file parser /* libasf - An Advanced Systems Format media file parser
* Copyright (C) 2006-2007 Juho Vähä-Herttua * Copyright (C) 2006-2010 Juho Vähä-Herttua
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "asf.h"
#include "asfint.h" #include "asfint.h"
#include "utf.h" #include "utf.h"
#include "header.h" #include "header.h"
@@ -68,10 +67,10 @@ asf_parse_header_stream_properties(asf_stream_t *stream,
return ASF_ERROR_INVALID_LENGTH; return ASF_ERROR_INVALID_LENGTH;
} }
asf_byteio_getGUID(&guid, objdata); GetGUID(objdata, &guid);
type = asf_guid_get_stream_type(&guid); type = asf_guid_get_stream_type(&guid);
datalen = asf_byteio_getDWLE(objdata + 40); datalen = GetDWLE(objdata + 40);
if (datalen > objsize - 78) { if (datalen > objsize - 78) {
return ASF_ERROR_INVALID_LENGTH; return ASF_ERROR_INVALID_LENGTH;
} }
@@ -87,7 +86,7 @@ asf_parse_header_stream_properties(asf_stream_t *stream,
datalen -= 64; datalen -= 64;
/* update the stream type with correct one */ /* update the stream type with correct one */
asf_byteio_getGUID(&guid, objdata); GetGUID(objdata, &guid);
type = asf_guid_get_stream_type(&guid); type = asf_guid_get_stream_type(&guid);
} }
@@ -102,7 +101,7 @@ asf_parse_header_stream_properties(asf_stream_t *stream,
if (datalen < 18) { if (datalen < 18) {
return ASF_ERROR_INVALID_LENGTH; return ASF_ERROR_INVALID_LENGTH;
} }
if (asf_byteio_getWLE(data + 16) > datalen - 16) { if (GetWLE(data + 16) > datalen - 16) {
return ASF_ERROR_INVALID_LENGTH; return ASF_ERROR_INVALID_LENGTH;
} }
@@ -113,13 +112,13 @@ asf_parse_header_stream_properties(asf_stream_t *stream,
stream->flags |= ASF_STREAM_FLAG_AVAILABLE; stream->flags |= ASF_STREAM_FLAG_AVAILABLE;
wfx = stream->properties; wfx = stream->properties;
wfx->wFormatTag = asf_byteio_getWLE(data); wfx->wFormatTag = GetWLE(data);
wfx->nChannels = asf_byteio_getWLE(data + 2); wfx->nChannels = GetWLE(data + 2);
wfx->nSamplesPerSec = asf_byteio_getDWLE(data + 4); wfx->nSamplesPerSec = GetDWLE(data + 4);
wfx->nAvgBytesPerSec = asf_byteio_getDWLE(data + 8); wfx->nAvgBytesPerSec = GetDWLE(data + 8);
wfx->nBlockAlign = asf_byteio_getWLE(data + 12); wfx->nBlockAlign = GetWLE(data + 12);
wfx->wBitsPerSample = asf_byteio_getWLE(data + 14); wfx->wBitsPerSample = GetWLE(data + 14);
wfx->cbSize = asf_byteio_getWLE(data + 16); wfx->cbSize = GetWLE(data + 16);
wfx->data = data + 18; wfx->data = data + 18;
if (wfx->cbSize > datalen - 18) { if (wfx->cbSize > datalen - 18) {
@@ -140,19 +139,19 @@ asf_parse_header_stream_properties(asf_stream_t *stream,
return ASF_ERROR_INVALID_LENGTH; return ASF_ERROR_INVALID_LENGTH;
} }
width = asf_byteio_getDWLE(data); width = GetDWLE(data);
height = asf_byteio_getDWLE(data + 4); height = GetDWLE(data + 4);
flags = data[8]; flags = data[8];
data_size = asf_byteio_getWLE(data + 9); data_size = GetWLE(data + 9);
data += 11; data += 11;
datalen -= 11; datalen -= 11;
if (asf_byteio_getDWLE(data) != datalen) { if (GetDWLE(data) != datalen) {
return ASF_ERROR_INVALID_LENGTH; return ASF_ERROR_INVALID_LENGTH;
} }
if (width != asf_byteio_getDWLE(data + 4) || if (width != GetDWLE(data + 4) ||
height != asf_byteio_getDWLE(data + 8) || height != GetDWLE(data + 8) ||
flags != 2) { flags != 2) {
return ASF_ERROR_INVALID_VALUE; return ASF_ERROR_INVALID_VALUE;
} }
@@ -164,17 +163,17 @@ asf_parse_header_stream_properties(asf_stream_t *stream,
stream->flags |= ASF_STREAM_FLAG_AVAILABLE; stream->flags |= ASF_STREAM_FLAG_AVAILABLE;
bmih = stream->properties; bmih = stream->properties;
bmih->biSize = asf_byteio_getDWLE(data); bmih->biSize = GetDWLE(data);
bmih->biWidth = asf_byteio_getDWLE(data + 4); bmih->biWidth = GetDWLE(data + 4);
bmih->biHeight = asf_byteio_getDWLE(data + 8); bmih->biHeight = GetDWLE(data + 8);
bmih->biPlanes = asf_byteio_getDWLE(data + 12); bmih->biPlanes = GetDWLE(data + 12);
bmih->biBitCount = asf_byteio_getDWLE(data + 14); bmih->biBitCount = GetDWLE(data + 14);
bmih->biCompression = asf_byteio_getDWLE(data + 16); bmih->biCompression = GetDWLE(data + 16);
bmih->biSizeImage = asf_byteio_getDWLE(data + 20); bmih->biSizeImage = GetDWLE(data + 20);
bmih->biXPelsPerMeter = asf_byteio_getDWLE(data + 24); bmih->biXPelsPerMeter = GetDWLE(data + 24);
bmih->biYPelsPerMeter = asf_byteio_getDWLE(data + 28); bmih->biYPelsPerMeter = GetDWLE(data + 28);
bmih->biClrUsed = asf_byteio_getDWLE(data + 32); bmih->biClrUsed = GetDWLE(data + 32);
bmih->biClrImportant = asf_byteio_getDWLE(data + 36); bmih->biClrImportant = GetDWLE(data + 36);
bmih->data = data + 40; bmih->data = data + 40;
if (bmih->biSize > datalen) { if (bmih->biSize > datalen) {
@@ -200,27 +199,27 @@ asf_parse_header_extended_stream_properties(asf_stream_t *stream,
uint8_t *objdata, uint8_t *objdata,
uint32_t objsize) uint32_t objsize)
{ {
asf_stream_extended_t ext; asf_stream_extended_properties_t ext;
uint32_t datalen; uint32_t datalen;
uint8_t *data; uint8_t *data;
uint16_t flags; uint16_t flags;
int i; int i;
ext.start_time = asf_byteio_getQWLE(objdata); ext.start_time = GetQWLE(objdata);
ext.end_time = asf_byteio_getQWLE(objdata + 8); ext.end_time = GetQWLE(objdata + 8);
ext.data_bitrate = asf_byteio_getDWLE(objdata + 16); ext.data_bitrate = GetDWLE(objdata + 16);
ext.buffer_size = asf_byteio_getDWLE(objdata + 20); ext.buffer_size = GetDWLE(objdata + 20);
ext.initial_buf_fullness = asf_byteio_getDWLE(objdata + 24); ext.initial_buf_fullness = GetDWLE(objdata + 24);
ext.data_bitrate2 = asf_byteio_getDWLE(objdata + 28); ext.data_bitrate2 = GetDWLE(objdata + 28);
ext.buffer_size2 = asf_byteio_getDWLE(objdata + 32); ext.buffer_size2 = GetDWLE(objdata + 32);
ext.initial_buf_fullness2 = asf_byteio_getDWLE(objdata + 36); ext.initial_buf_fullness2 = GetDWLE(objdata + 36);
ext.max_obj_size = asf_byteio_getDWLE(objdata + 40); ext.max_obj_size = GetDWLE(objdata + 40);
ext.flags = asf_byteio_getDWLE(objdata + 44); ext.flags = GetDWLE(objdata + 44);
ext.stream_num = asf_byteio_getWLE(objdata + 48); ext.stream_num = GetWLE(objdata + 48);
ext.lang_idx = asf_byteio_getWLE(objdata + 50); ext.lang_idx = GetWLE(objdata + 50);
ext.avg_time_per_frame = asf_byteio_getQWLE(objdata + 52); ext.avg_time_per_frame = GetQWLE(objdata + 52);
ext.stream_name_count = asf_byteio_getWLE(objdata + 60); ext.stream_name_count = GetWLE(objdata + 60);
ext.num_payload_ext = asf_byteio_getWLE(objdata + 62); ext.num_payload_ext = GetWLE(objdata + 62);
datalen = objsize - 88; datalen = objsize - 88;
data = objdata + 64; data = objdata + 64;
@@ -233,7 +232,7 @@ asf_parse_header_extended_stream_properties(asf_stream_t *stream,
return ASF_ERROR_INVALID_VALUE; return ASF_ERROR_INVALID_VALUE;
} }
strlen = asf_byteio_getWLE(data + 2); strlen = GetWLE(data + 2);
if (strlen > datalen) { if (strlen > datalen) {
return ASF_ERROR_INVALID_LENGTH; return ASF_ERROR_INVALID_LENGTH;
} }
@@ -251,7 +250,7 @@ asf_parse_header_extended_stream_properties(asf_stream_t *stream,
return ASF_ERROR_INVALID_VALUE; return ASF_ERROR_INVALID_VALUE;
} }
extsyslen = asf_byteio_getDWLE(data + 18); extsyslen = GetDWLE(data + 18);
if (extsyslen > datalen) { if (extsyslen > datalen) {
return ASF_ERROR_INVALID_LENGTH; return ASF_ERROR_INVALID_LENGTH;
} }
@@ -268,19 +267,19 @@ asf_parse_header_extended_stream_properties(asf_stream_t *stream,
/* this is almost same as in stream properties handler */ /* this is almost same as in stream properties handler */
if (datalen < 78) { if (datalen < 78) {
return ASF_ERROR_OBJECT_SIZE; return ASF_ERROR_INVALID_OBJECT_SIZE;
} }
/* check that we really have a stream properties object */ /* check that we really have a stream properties object */
asf_byteio_getGUID(&guid, data); GetGUID(data, &guid);
if (asf_guid_get_type(&guid) != GUID_STREAM_PROPERTIES) { if (asf_guid_get_type(&guid) != GUID_STREAM_PROPERTIES) {
return ASF_ERROR_INVALID_OBJECT; return ASF_ERROR_INVALID_OBJECT;
} }
if (asf_byteio_getQWLE(data + 16) != datalen) { if (GetQWLE(data + 16) != datalen) {
return ASF_ERROR_OBJECT_SIZE; return ASF_ERROR_INVALID_OBJECT_SIZE;
} }
flags = asf_byteio_getWLE(data + 72); flags = GetWLE(data + 72);
if ((flags & 0x7f) != ext.stream_num || stream->type) { if ((flags & 0x7f) != ext.stream_num || stream->type) {
/* only one stream object per stream allowed and /* only one stream object per stream allowed and
@@ -300,12 +299,12 @@ asf_parse_header_extended_stream_properties(asf_stream_t *stream,
} }
} }
stream->extended = malloc(sizeof(asf_stream_extended_t)); stream->extended_properties = malloc(sizeof(asf_stream_extended_properties_t));
if (!stream->extended) { if (!stream->extended_properties) {
return ASF_ERROR_OUTOFMEM; return ASF_ERROR_OUTOFMEM;
} }
stream->flags |= ASF_STREAM_FLAG_EXTENDED; stream->flags |= ASF_STREAM_FLAG_EXTENDED;
memcpy(stream->extended, &ext, sizeof(ext)); memcpy(stream->extended_properties, &ext, sizeof(ext));
return 0; return 0;
} }
@@ -333,7 +332,7 @@ asf_parse_header_validate(asf_file_t *file, asf_object_header_t *header)
{ {
uint32_t max_packet_size; uint32_t max_packet_size;
if (size < 104) if (size < 104)
return ASF_ERROR_OBJECT_SIZE; return ASF_ERROR_INVALID_OBJECT_SIZE;
if (fileprop) { if (fileprop) {
/* multiple file properties objects not allowed */ /* multiple file properties objects not allowed */
@@ -341,18 +340,18 @@ asf_parse_header_validate(asf_file_t *file, asf_object_header_t *header)
} }
fileprop = 1; fileprop = 1;
asf_byteio_getGUID(&file->file_id, current->data); GetGUID(current->data, &file->file_id);
file->file_size = asf_byteio_getQWLE(current->data + 16); file->file_size = GetQWLE(current->data + 16);
file->creation_date = asf_byteio_getQWLE(current->data + 24); file->creation_date = GetQWLE(current->data + 24);
file->data_packets_count = asf_byteio_getQWLE(current->data + 32); file->data_packets_count = GetQWLE(current->data + 32);
file->play_duration = asf_byteio_getQWLE(current->data + 40); file->play_duration = GetQWLE(current->data + 40);
file->send_duration = asf_byteio_getQWLE(current->data + 48); file->send_duration = GetQWLE(current->data + 48);
file->preroll = asf_byteio_getQWLE(current->data + 56); file->preroll = GetQWLE(current->data + 56);
file->flags = asf_byteio_getDWLE(current->data + 64); file->flags = GetDWLE(current->data + 64);
file->packet_size = asf_byteio_getDWLE(current->data + 68); file->packet_size = GetDWLE(current->data + 68);
file->max_bitrate = asf_byteio_getQWLE(current->data + 76); file->max_bitrate = GetQWLE(current->data + 76);
max_packet_size = asf_byteio_getDWLE(current->data + 72); max_packet_size = GetDWLE(current->data + 72);
if (file->packet_size != max_packet_size) { if (file->packet_size != max_packet_size) {
/* in ASF file minimum packet size and maximum /* in ASF file minimum packet size and maximum
* packet size have to be same apparently... * packet size have to be same apparently...
@@ -368,10 +367,10 @@ asf_parse_header_validate(asf_file_t *file, asf_object_header_t *header)
int ret; int ret;
if (size < 78) if (size < 78)
return ASF_ERROR_OBJECT_SIZE; return ASF_ERROR_INVALID_OBJECT_SIZE;
streamprop = 1; streamprop = 1;
flags = asf_byteio_getWLE(current->data + 48); flags = GetWLE(current->data + 48);
stream = &file->streams[flags & 0x7f]; stream = &file->streams[flags & 0x7f];
if (stream->type) { if (stream->type) {
@@ -393,13 +392,13 @@ asf_parse_header_validate(asf_file_t *file, asf_object_header_t *header)
uint32_t stringlen = 0; uint32_t stringlen = 0;
if (size < 34) if (size < 34)
return ASF_ERROR_OBJECT_SIZE; return ASF_ERROR_INVALID_OBJECT_SIZE;
stringlen += asf_byteio_getWLE(current->data); stringlen += GetWLE(current->data);
stringlen += asf_byteio_getWLE(current->data + 2); stringlen += GetWLE(current->data + 2);
stringlen += asf_byteio_getWLE(current->data + 4); stringlen += GetWLE(current->data + 4);
stringlen += asf_byteio_getWLE(current->data + 6); stringlen += GetWLE(current->data + 6);
stringlen += asf_byteio_getWLE(current->data + 8); stringlen += GetWLE(current->data + 8);
if (size < stringlen + 34) { if (size < stringlen + 34) {
/* invalid string length values */ /* invalid string length values */
@@ -411,17 +410,17 @@ asf_parse_header_validate(asf_file_t *file, asf_object_header_t *header)
break; break;
case GUID_CODEC_LIST: case GUID_CODEC_LIST:
if (size < 44) if (size < 44)
return ASF_ERROR_OBJECT_SIZE; return ASF_ERROR_INVALID_OBJECT_SIZE;
break; break;
case GUID_STREAM_BITRATE_PROPERTIES: case GUID_STREAM_BITRATE_PROPERTIES:
if (size < 26) if (size < 26)
return ASF_ERROR_OBJECT_SIZE; return ASF_ERROR_INVALID_OBJECT_SIZE;
break; break;
case GUID_PADDING: case GUID_PADDING:
break; break;
case GUID_EXTENDED_CONTENT_DESCRIPTION: case GUID_EXTENDED_CONTENT_DESCRIPTION:
if (size < 26) if (size < 26)
return ASF_ERROR_OBJECT_SIZE; return ASF_ERROR_INVALID_OBJECT_SIZE;
break; break;
case GUID_UNKNOWN: case GUID_UNKNOWN:
/* unknown guid type */ /* unknown guid type */
@@ -443,11 +442,11 @@ asf_parse_header_validate(asf_file_t *file, asf_object_header_t *header)
switch (current->type) { switch (current->type) {
case GUID_METADATA: case GUID_METADATA:
if (size < 26) if (size < 26)
return ASF_ERROR_OBJECT_SIZE; return ASF_ERROR_INVALID_OBJECT_SIZE;
break; break;
case GUID_LANGUAGE_LIST: case GUID_LANGUAGE_LIST:
if (size < 26) if (size < 26)
return ASF_ERROR_OBJECT_SIZE; return ASF_ERROR_INVALID_OBJECT_SIZE;
break; break;
case GUID_EXTENDED_STREAM_PROPERTIES: case GUID_EXTENDED_STREAM_PROPERTIES:
{ {
@@ -456,9 +455,9 @@ asf_parse_header_validate(asf_file_t *file, asf_object_header_t *header)
int ret; int ret;
if (size < 88) if (size < 88)
return ASF_ERROR_OBJECT_SIZE; return ASF_ERROR_INVALID_OBJECT_SIZE;
stream_num = asf_byteio_getWLE(current->data + 48); stream_num = GetWLE(current->data + 48);
stream = &file->streams[stream_num]; stream = &file->streams[stream_num];
ret = asf_parse_header_extended_stream_properties(stream, ret = asf_parse_header_extended_stream_properties(stream,
@@ -472,11 +471,11 @@ asf_parse_header_validate(asf_file_t *file, asf_object_header_t *header)
} }
case GUID_ADVANCED_MUTUAL_EXCLUSION: case GUID_ADVANCED_MUTUAL_EXCLUSION:
if (size < 42) if (size < 42)
return ASF_ERROR_OBJECT_SIZE; return ASF_ERROR_INVALID_OBJECT_SIZE;
break; break;
case GUID_STREAM_PRIORITIZATION: case GUID_STREAM_PRIORITIZATION:
if (size < 26) if (size < 26)
return ASF_ERROR_OBJECT_SIZE; return ASF_ERROR_INVALID_OBJECT_SIZE;
break; break;
case GUID_UNKNOWN: case GUID_UNKNOWN:
/* unknown guid type */ /* unknown guid type */
@@ -556,7 +555,7 @@ asf_header_metadata(asf_object_header_t *header)
/* The validity of the object is already checked so we can assume /* The validity of the object is already checked so we can assume
* there's always enough data to read and there are no overflows */ * there's always enough data to read and there are no overflows */
for (i=0; i<5; i++) { for (i=0; i<5; i++) {
strlen = asf_byteio_getWLE(current->data + i*2); strlen = GetWLE(current->data + i*2);
if (!strlen) if (!strlen)
continue; continue;
@@ -590,7 +589,7 @@ asf_header_metadata(asf_object_header_t *header)
if (current) { if (current) {
int i, j, position; int i, j, position;
ret->extended_count = asf_byteio_getWLE(current->data); ret->extended_count = GetWLE(current->data);
ret->extended = calloc(ret->extended_count, sizeof(asf_metadata_entry_t)); ret->extended = calloc(ret->extended_count, sizeof(asf_metadata_entry_t));
if (!ret->extended) { if (!ret->extended) {
/* Clean up the already allocated parts and return */ /* Clean up the already allocated parts and return */
@@ -608,16 +607,16 @@ asf_header_metadata(asf_object_header_t *header)
for (i=0; i<ret->extended_count; i++) { for (i=0; i<ret->extended_count; i++) {
uint16_t length, type; uint16_t length, type;
length = asf_byteio_getWLE(current->data + position); length = GetWLE(current->data + position);
position += 2; position += 2;
ret->extended[i].key = asf_utf8_from_utf16le(current->data + position, length); ret->extended[i].key = asf_utf8_from_utf16le(current->data + position, length);
position += length; position += length;
type = asf_byteio_getWLE(current->data + position); type = GetWLE(current->data + position);
position += 2; position += 2;
length = asf_byteio_getWLE(current->data + position); length = GetWLE(current->data + position);
position += 2; position += 2;
switch (type) { switch (type) {
@@ -645,19 +644,19 @@ asf_header_metadata(asf_object_header_t *header)
/* type of the value is a signed 32-bit integer */ /* type of the value is a signed 32-bit integer */
ret->extended[i].value = malloc(11 * sizeof(char)); ret->extended[i].value = malloc(11 * sizeof(char));
sprintf(ret->extended[i].value, "%u", sprintf(ret->extended[i].value, "%u",
asf_byteio_getDWLE(current->data + position)); GetDWLE(current->data + position));
break; break;
case 4: case 4:
/* FIXME: This doesn't print whole 64-bit integer */ /* FIXME: This doesn't print whole 64-bit integer */
ret->extended[i].value = malloc(21 * sizeof(char)); ret->extended[i].value = malloc(21 * sizeof(char));
sprintf(ret->extended[i].value, "%u", sprintf(ret->extended[i].value, "%u",
(uint32_t) asf_byteio_getQWLE(current->data + position)); (uint32_t) GetQWLE(current->data + position));
break; break;
case 5: case 5:
/* type of the value is a signed 16-bit integer */ /* type of the value is a signed 16-bit integer */
ret->extended[i].value = malloc(6 * sizeof(char)); ret->extended[i].value = malloc(6 * sizeof(char));
sprintf(ret->extended[i].value, "%u", sprintf(ret->extended[i].value, "%u",
asf_byteio_getWLE(current->data + position)); GetWLE(current->data + position));
break; break;
default: default:
/* Unknown value type... */ /* Unknown value type... */
@@ -1,5 +1,5 @@
/* libasf - An Advanced Systems Format media file parser /* libasf - An Advanced Systems Format media file parser
* Copyright (C) 2006-2007 Juho Vähä-Herttua * Copyright (C) 2006-2010 Juho Vähä-Herttua
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -1,5 +1,5 @@
/* libasf - An Advanced Systems Format media file parser /* libasf - An Advanced Systems Format media file parser
* Copyright (C) 2006-2007 Juho Vähä-Herttua * Copyright (C) 2006-2010 Juho Vähä-Herttua
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -22,7 +22,6 @@
#include "asf.h" #include "asf.h"
#include "asfint.h" #include "asfint.h"
#include "byteio.h" #include "byteio.h"
#include "utf.h"
#include "header.h" #include "header.h"
#include "guid.h" #include "guid.h"
#include "debug.h" #include "debug.h"
@@ -36,9 +35,9 @@
static void static void
asf_parse_read_object(asfint_object_t *obj, uint8_t *data) asf_parse_read_object(asfint_object_t *obj, uint8_t *data)
{ {
asf_byteio_getGUID(&obj->guid, data); GetGUID(data, &obj->guid);
obj->type = asf_guid_get_type(&obj->guid); obj->type = asf_guid_get_type(&obj->guid);
obj->size = asf_byteio_getQWLE(data + 16); obj->size = GetQWLE(data + 16);
obj->full_data = data; obj->full_data = data;
obj->datalen = 0; obj->datalen = 0;
obj->data = NULL; obj->data = NULL;
@@ -66,13 +65,13 @@ asf_parse_headerext(asf_object_headerext_t *header, uint8_t *buf, uint64_t bufle
if (header->size < 46) { if (header->size < 46) {
/* invalide size for headerext */ /* invalide size for headerext */
return ASF_ERROR_OBJECT_SIZE; return ASF_ERROR_INVALID_OBJECT_SIZE;
} }
/* Read reserved and datalen fields from the buffer */ /* Read reserved and datalen fields from the buffer */
asf_byteio_getGUID(&header->reserved1, buf + 24); GetGUID(buf + 24, &header->reserved1);
header->reserved2 = asf_byteio_getWLE(buf + 40); header->reserved2 = GetWLE(buf + 40);
header->datalen = asf_byteio_getDWLE(buf + 42); header->datalen = GetDWLE(buf + 42);
if (header->datalen != header->size - 46) { if (header->datalen != header->size - 46) {
/* invalid header extension data length value */ /* invalid header extension data length value */
@@ -149,7 +148,7 @@ asf_parse_header(asf_file_t *file)
/* object minimum is 24 bytes and header needs to have /* object minimum is 24 bytes and header needs to have
* the subobject count field and two reserved fields */ * the subobject count field and two reserved fields */
tmp = asf_byteio_read(hdata, 30, iostream); tmp = asf_byteio_read(iostream, hdata, 30);
if (tmp < 0) { if (tmp < 0) {
/* not enough data to read the header object */ /* not enough data to read the header object */
return tmp; return tmp;
@@ -165,11 +164,11 @@ asf_parse_header(asf_file_t *file)
asf_parse_read_object((asfint_object_t *) header, hdata); asf_parse_read_object((asfint_object_t *) header, hdata);
if (header->size < 30) { if (header->size < 30) {
/* invalid size for header object */ /* invalid size for header object */
return ASF_ERROR_OBJECT_SIZE; return ASF_ERROR_INVALID_OBJECT_SIZE;
} }
/* read header object specific compulsory fields */ /* read header object specific compulsory fields */
header->subobjects = asf_byteio_getDWLE(hdata + 24); header->subobjects = GetDWLE(hdata + 24);
header->reserved1 = hdata[28]; header->reserved1 = hdata[28];
header->reserved2 = hdata[29]; header->reserved2 = hdata[29];
@@ -185,7 +184,7 @@ asf_parse_header(asf_file_t *file)
return ASF_ERROR_OUTOFMEM; return ASF_ERROR_OUTOFMEM;
} }
tmp = asf_byteio_read(header->data, header->datalen, iostream); tmp = asf_byteio_read(iostream, header->data, header->datalen);
if (tmp < 0) { if (tmp < 0) {
return tmp; return tmp;
} }
@@ -300,7 +299,7 @@ asf_parse_data(asf_file_t *file)
/* object minimum is 24 bytes and data object needs to have /* object minimum is 24 bytes and data object needs to have
* 26 additional bytes for its internal fields */ * 26 additional bytes for its internal fields */
tmp = asf_byteio_read(ddata, 50, iostream); tmp = asf_byteio_read(iostream, ddata, 50);
if (tmp < 0) { if (tmp < 0) {
return tmp; return tmp;
} }
@@ -315,22 +314,22 @@ asf_parse_data(asf_file_t *file)
asf_parse_read_object((asfint_object_t *) data, ddata); asf_parse_read_object((asfint_object_t *) data, ddata);
if (data->size < 50) { if (data->size < 50) {
/* invalid size for data object */ /* invalid size for data object */
return ASF_ERROR_OBJECT_SIZE; return ASF_ERROR_INVALID_OBJECT_SIZE;
} }
/* read data object specific compulsory fields */ /* read data object specific compulsory fields */
asf_byteio_getGUID(&data->file_id, ddata + 24); GetGUID(ddata + 24, &data->file_id);
data->total_data_packets = asf_byteio_getQWLE(ddata + 40); data->total_data_packets = GetQWLE(ddata + 40);
data->reserved = asf_byteio_getWLE(ddata + 48); data->reserved = GetWLE(ddata + 48);
data->packets_position = file->position + 50; data->packets_position = file->position + 50;
/* If the file_id GUID in data object doesn't match the /* If the file_id GUID in data object doesn't match the
* file_id GUID in headers, the file is corrupted */ * file_id GUID in headers, the file is corrupted */
if (!asf_guid_match(&data->file_id, &file->file_id)) { if (!asf_guid_equals(&data->file_id, &file->file_id)) {
return ASF_ERROR_INVALID_VALUE; return ASF_ERROR_INVALID_VALUE;
} }
/* if data->total_data_packets is non-zero (not a iostream) and /* if data->total_data_packets is non-zero (not a stream) and
the data packets count doesn't match, return error */ the data packets count doesn't match, return error */
if (data->total_data_packets && if (data->total_data_packets &&
data->total_data_packets != file->data_packets_count) { data->total_data_packets != file->data_packets_count) {
@@ -361,7 +360,7 @@ asf_parse_index(asf_file_t *file)
iostream = &file->iostream; iostream = &file->iostream;
/* read the raw data of an index header */ /* read the raw data of an index header */
tmp = asf_byteio_read(idata, 56, iostream); tmp = asf_byteio_read(iostream, idata, 56);
if (tmp < 0) { if (tmp < 0) {
printf("Could not read index header\n"); printf("Could not read index header\n");
return tmp; return tmp;
@@ -385,13 +384,13 @@ asf_parse_index(asf_file_t *file)
if (index->size < 56) { if (index->size < 56) {
/* invalid size for index object */ /* invalid size for index object */
free(index); free(index);
return ASF_ERROR_OBJECT_SIZE; return ASF_ERROR_INVALID_OBJECT_SIZE;
} }
asf_byteio_getGUID(&index->file_id, idata + 24); GetGUID(idata + 24, &index->file_id);
index->entry_time_interval = asf_byteio_getQWLE(idata + 40); index->entry_time_interval = GetQWLE(idata + 40);
index->max_packet_count = asf_byteio_getDWLE(idata + 48); index->max_packet_count = GetDWLE(idata + 48);
index->entry_count = asf_byteio_getDWLE(idata + 52); index->entry_count = GetDWLE(idata + 52);
printf("INDEX\n"); printf("INDEX\n");
printf("Total Index Entries %d\n",index->entry_count); printf("Total Index Entries %d\n",index->entry_count);
@@ -416,8 +415,7 @@ asf_parse_index(asf_file_t *file)
free(index); free(index);
return ASF_ERROR_OUTOFMEM; return ASF_ERROR_OUTOFMEM;
} }
tmp = asf_byteio_read(iostream, entry_data, entry_data_size);
tmp = asf_byteio_read(entry_data, entry_data_size, iostream);
if (tmp < 0) { if (tmp < 0) {
printf("Could not read entry data\n"); printf("Could not read entry data\n");
free(index); free(index);
@@ -433,8 +431,8 @@ asf_parse_index(asf_file_t *file)
} }
for (i=0; i<index->entry_count; i++) { for (i=0; i<index->entry_count; i++) {
index->entries[i].packet_index = asf_byteio_getDWLE(entry_data + i*6); index->entries[i].packet_index = GetDWLE(entry_data + i*6);
index->entries[i].packet_count = asf_byteio_getWLE(entry_data + i*6 + 4); index->entries[i].packet_count = GetWLE(entry_data + i*6 + 4);
} }
free(entry_data); free(entry_data);
@@ -1,5 +1,5 @@
/* libasf - An Advanced Systems Format media file parser /* libasf - An Advanced Systems Format media file parser
* Copyright (C) 2006-2007 Juho Vähä-Herttua * Copyright (C) 2006-2010 Juho Vähä-Herttua
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -1,107 +0,0 @@
/* libasf - An Advanced Systems Format media file parser
* Copyright (C) 2006-2007 Juho Vähä-Herttua
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdlib.h>
#include "asf.h"
#include "byteio.h"
/**
* Decode UTF-16LE text from buffer of buflen size and
* allocate a new buffer containing the same string
* encoded as UTF-8. Supports characters outside of BMP
* encoded as an UTF-16 surrogate pair. Returns NULL in
* case of allocation failure or invalid surrogate pair.
* Buflen is in bytes.
*/
char *
asf_utf8_from_utf16le(uint8_t *buf, uint16_t buflen)
{
uint32_t length, pos;
char *ret;
int i;
length = 0;
for (i=0; i<buflen/2; i++) {
uint16_t wchar1, wchar2;
wchar1 = asf_byteio_getWLE(&buf[i*2]);
if (wchar1 >= 0xD800 && wchar1 < 0xDB00) {
i++;
if (i*2 >= buflen) {
/* unexpected end of buffer */
return NULL;
}
wchar2 = asf_byteio_getWLE(&buf[i*2]);
if (wchar2 < 0xDB00 || wchar2 > 0xDFFF) {
/* invalid surrogate pair */
return NULL;
}
length += 4;
} else if (wchar1 > 0x07FF) {
length += 3;
} else if (wchar1 > 0x7F) {
length += 2;
} else {
length++;
}
}
ret = malloc(length + 1);
if (!ret) {
return NULL;
}
pos = 0;
for (i=0; i<buflen/2; i++) {
uint16_t wchar1, wchar2;
uint32_t codepoint;
wchar1 = asf_byteio_getWLE(&buf[i*2]);
if (wchar1 >= 0xD800 && wchar1 < 0xDB00) {
i++;
wchar2 = asf_byteio_getWLE(&buf[i*2]);
codepoint = 0x10000;
codepoint += ((wchar1 & 0x03FF) << 10);
codepoint |= (wchar2 & 0x03FF);
} else {
codepoint = wchar1;
}
if (codepoint > 0xFFFF) {
ret[pos++] = 0xF0 | ((codepoint >> 18) & 0x07);
ret[pos++] = 0x80 | ((codepoint >> 12) & 0x3F);
ret[pos++] = 0x80 | ((codepoint >> 6) & 0x3F);
ret[pos++] = 0x80 | (codepoint & 0x3F);
} else if (codepoint > 0x07FF) {
ret[pos++] = 0xE0 | (codepoint >> 12);
ret[pos++] = 0x80 | ((codepoint >> 6) & 0x3F);
ret[pos++] = 0x80 | (codepoint & 0x3F);
} else if (codepoint > 0x7F) {
ret[pos++] = 0xC0 | (codepoint >> 6);
ret[pos++] = 0x80 | (codepoint & 0x3F);
} else {
ret[pos++] = codepoint;
}
}
ret[length] = '\0';
return ret;
}
@@ -1,5 +1,5 @@
/* libasf - An Advanced Systems Format media file parser /* libasf - An Advanced Systems Format media file parser
* Copyright (C) 2006-2007 Juho Vähä-Herttua * Copyright (C) 2006-2010 Juho Vähä-Herttua
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -19,6 +19,92 @@
#ifndef UTF_H #ifndef UTF_H
#define UTF_H #define UTF_H
char *asf_utf8_from_utf16le(uint8_t *buf, uint16_t buflen); #include <stdlib.h>
#include "asfint.h"
/**
* Decode UTF-16LE text from buffer of buflen size and
* allocate a new buffer containing the same string
* encoded as UTF-8. Supports characters outside of BMP
* encoded as an UTF-16 surrogate pair. Returns NULL in
* case of allocation failure or invalid surrogate pair.
* Buflen is in bytes.
*/
static char *
asf_utf8_from_utf16le(uint8_t *buf, uint16_t buflen)
{
uint32_t length, pos;
char *ret;
int i;
length = 0;
for (i=0; i<buflen/2; i++) {
uint16_t wchar1, wchar2;
wchar1 = buf[i*2] | (buf[i*2+1] << 8);
if (wchar1 >= 0xD800 && wchar1 < 0xDC00) {
i++;
if (i*2 >= buflen) {
/* unexpected end of buffer */
return NULL;
}
wchar2 = buf[i*2] | (buf[i*2+1] << 8);
if (wchar2 < 0xDB00 || wchar2 > 0xDFFF) {
/* invalid surrogate pair */
return NULL;
}
length += 4;
} else if (wchar1 > 0x07FF) {
length += 3;
} else if (wchar1 > 0x7F) {
length += 2;
} else {
length++;
}
}
ret = malloc(length + 1);
if (!ret) {
return NULL;
}
pos = 0;
for (i=0; i<buflen/2; i++) {
uint16_t wchar1, wchar2;
uint32_t codepoint;
wchar1 = buf[i*2] | (buf[i*2+1] << 8);
if (wchar1 >= 0xD800 && wchar1 < 0xDC00) {
i++;
wchar2 = buf[i*2] | (buf[i*2+1] << 8);
codepoint = 0x10000;
codepoint += ((wchar1 & 0x03FF) << 10);
codepoint |= (wchar2 & 0x03FF);
} else {
codepoint = wchar1;
}
if (codepoint > 0xFFFF) {
ret[pos++] = 0xF0 | ((codepoint >> 18) & 0x07);
ret[pos++] = 0x80 | ((codepoint >> 12) & 0x3F);
ret[pos++] = 0x80 | ((codepoint >> 6) & 0x3F);
ret[pos++] = 0x80 | (codepoint & 0x3F);
} else if (codepoint > 0x07FF) {
ret[pos++] = 0xE0 | (codepoint >> 12);
ret[pos++] = 0x80 | ((codepoint >> 6) & 0x3F);
ret[pos++] = 0x80 | (codepoint & 0x3F);
} else if (codepoint > 0x7F) {
ret[pos++] = 0xC0 | (codepoint >> 6);
ret[pos++] = 0x80 | (codepoint & 0x3F);
} else {
ret[pos++] = codepoint;
}
}
ret[length] = '\0';
return ret;
}
#endif #endif