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:
@@ -184,9 +184,9 @@ ASFFileReader::getVideoFormat(uint32 streamIndex, ASFVideoFormat *format)
|
||||
format->extraData = videoHeader->data;
|
||||
|
||||
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;
|
||||
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;
|
||||
@@ -210,9 +210,9 @@ ASFFileReader::getStreamDuration(uint32 streamIndex)
|
||||
|
||||
if (stream) {
|
||||
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);
|
||||
if (stream->extended->end_time - stream->extended->start_time > 0) {
|
||||
return 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_properties->end_time - stream->extended_properties->start_time > 0) {
|
||||
return stream->extended_properties->end_time - stream->extended_properties->start_time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,7 @@ StaticLibrary libasfreader.a :
|
||||
asf.c
|
||||
byteio.c
|
||||
data.c
|
||||
fileio.c
|
||||
guid.c
|
||||
header.c
|
||||
parse.c
|
||||
utf.c
|
||||
;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* 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
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -21,13 +21,31 @@
|
||||
|
||||
#include "asf.h"
|
||||
#include "asfint.h"
|
||||
#include "fileio.h"
|
||||
#include "byteio.h"
|
||||
#include "header.h"
|
||||
#include "parse.h"
|
||||
#include "data.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_open_file(const char *filename)
|
||||
{
|
||||
@@ -35,12 +53,12 @@ asf_open_file(const char *filename)
|
||||
asf_iostream_t stream;
|
||||
FILE *fstream;
|
||||
|
||||
fstream = fopen(filename, "r");
|
||||
fstream = fopen(filename, "rb");
|
||||
if (!fstream)
|
||||
return NULL;
|
||||
|
||||
stream.read = asf_fileio_read_cb;
|
||||
stream.write = asf_fileio_write_cb;
|
||||
stream.write = NULL;
|
||||
stream.seek = asf_fileio_seek_cb;
|
||||
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].flags = ASF_STREAM_FLAG_NONE;
|
||||
file->streams[i].properties = NULL;
|
||||
file->streams[i].extended = NULL;
|
||||
file->streams[i].extended_properties = NULL;
|
||||
}
|
||||
|
||||
return file;
|
||||
@@ -96,7 +114,7 @@ asf_init(asf_file_t *file)
|
||||
|
||||
tmp = asf_parse_header(file);
|
||||
if (tmp < 0) {
|
||||
printf("error parsing header: %d\n", tmp);
|
||||
debug_printf("error parsing header: %d", tmp);
|
||||
return tmp;
|
||||
}
|
||||
file->position += tmp;
|
||||
@@ -104,7 +122,7 @@ asf_init(asf_file_t *file)
|
||||
|
||||
tmp = asf_parse_data(file);
|
||||
if (tmp < 0) {
|
||||
printf("error parsing data object: %d\n", tmp);
|
||||
debug_printf("error parsing data object: %d", tmp);
|
||||
return tmp;
|
||||
}
|
||||
file->position += tmp;
|
||||
@@ -124,7 +142,7 @@ asf_init(asf_file_t *file)
|
||||
file->index_position < file->file_size && !file->index) {
|
||||
tmp = asf_parse_index(file);
|
||||
if (tmp < 0) {
|
||||
printf("Error finding index object! %d\n", tmp);
|
||||
debug_printf("Error finding index object! %d", tmp);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -152,7 +170,7 @@ asf_init(asf_file_t *file)
|
||||
|
||||
for (tmp = 0; tmp < ASF_MAX_STREAMS; tmp++) {
|
||||
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++) {
|
||||
free(file->streams[i].properties);
|
||||
free(file->streams[i].extended);
|
||||
free(file->streams[i].extended_properties);
|
||||
}
|
||||
|
||||
free(file);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* 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
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -19,9 +19,8 @@
|
||||
#ifndef ASF_H
|
||||
#define ASF_H
|
||||
|
||||
|
||||
/* used int types for different platforms */
|
||||
#if !defined(__MINGW_H) && defined(_WIN32)
|
||||
#if defined(WIN32) && !defined(__MINGW_H)
|
||||
typedef char int8_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef short int16_t;
|
||||
@@ -35,13 +34,83 @@ typedef unsigned __int64 uint64_t;
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
struct asf_guid_s {
|
||||
uint32_t v1;
|
||||
uint32_t v2;
|
||||
uint16_t v3;
|
||||
uint8_t v4[8];
|
||||
#if defined(WIN32) && defined(DLL_EXPORT)
|
||||
# define LIBASF_API __declspec(dllexport)
|
||||
#else
|
||||
# define LIBASF_API
|
||||
#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 {
|
||||
/* 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 */
|
||||
|
||||
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 send_time; /* send time 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;
|
||||
|
||||
/* 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_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 {
|
||||
struct asf_stream_extended_properties_s {
|
||||
uint64_t start_time;
|
||||
uint64_t end_time;
|
||||
uint32_t data_bitrate;
|
||||
@@ -183,7 +205,7 @@ struct asf_stream_extended_s {
|
||||
uint16_t stream_name_count;
|
||||
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 {
|
||||
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
|
||||
* 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_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 */
|
||||
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,
|
||||
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 */
|
||||
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 */
|
||||
int asf_init(asf_file_t *file);
|
||||
LIBASF_API int asf_init(asf_file_t *file);
|
||||
|
||||
|
||||
/* 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 */
|
||||
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 */
|
||||
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 */
|
||||
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 */
|
||||
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 */
|
||||
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
|
||||
* WARNING: after calling this function all asf_header_*
|
||||
* 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 */
|
||||
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 */
|
||||
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 */
|
||||
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 */
|
||||
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 */
|
||||
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
|
||||
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
|
||||
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,
|
||||
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 */
|
||||
uint32_t asf_get_max_bitrate(asf_file_t *file);
|
||||
LIBASF_API uint32_t asf_get_max_bitrate(asf_file_t *file);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* 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
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -19,8 +19,28 @@
|
||||
#ifndef ASFINT_H
|
||||
#define ASFINT_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "asf.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
|
||||
* ALSO DEFINED IN asf.h HEADER AND WILL BREAK THINGS */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* 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
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -17,71 +17,12 @@
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "asfint.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
|
||||
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;
|
||||
|
||||
@@ -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) {
|
||||
read += tmp;
|
||||
|
||||
if (read == size) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* 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
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -22,12 +22,6 @@
|
||||
#include "asf.h"
|
||||
#include "guid.h"
|
||||
|
||||
uint16_t asf_byteio_getWLE(uint8_t *data);
|
||||
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);
|
||||
int asf_byteio_read(asf_iostream_t *iostream, uint8_t *data, int size);
|
||||
|
||||
#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
|
||||
* 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
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -19,22 +19,15 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "asf.h"
|
||||
#include "asfint.h"
|
||||
#include "byteio.h"
|
||||
#include "data.h"
|
||||
#include "parse.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
|
||||
asf_data_read_packet_data(asf_packet_t *packet, uint8_t flags,
|
||||
uint8_t *data, uint32_t len)
|
||||
asf_data_read_packet_fields(asf_packet_t *packet, uint8_t flags,
|
||||
uint8_t *data, uint32_t len)
|
||||
{
|
||||
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);
|
||||
data += GETLEN2b((flags >> 5) & 0x03);
|
||||
/* sequence value should be never used anywhere */
|
||||
GETVALUE2b((flags >> 1) & 0x03, data);
|
||||
packet->sequence = GETVALUE2b((flags >> 1) & 0x03, data);
|
||||
data += GETLEN2b((flags >> 1) & 0x03);
|
||||
packet->padding_length = GETVALUE2b((flags >> 3) & 0x03, data);
|
||||
data += GETLEN2b((flags >> 3) & 0x03);
|
||||
packet->send_time = asf_byteio_getDWLE(data);
|
||||
packet->send_time = GetDWLE(data);
|
||||
data += 4;
|
||||
packet->duration = asf_byteio_getWLE(data);
|
||||
packet->duration = GetWLE(data);
|
||||
data += 2;
|
||||
|
||||
return datalen;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@@ -88,24 +80,27 @@ static int
|
||||
asf_data_read_payloads(asf_packet_t *packet,
|
||||
uint64_t preroll,
|
||||
uint8_t multiple,
|
||||
uint8_t type,
|
||||
uint8_t flags,
|
||||
uint8_t *data,
|
||||
uint32_t datalen)
|
||||
{
|
||||
asf_payload_t pl;
|
||||
int i, tmp, skip;
|
||||
uint32_t skip;
|
||||
int i, tmp;
|
||||
|
||||
skip = 0, i = 0;
|
||||
while (i < packet->payload_count) {
|
||||
uint8_t pts_delta = 0;
|
||||
int compressed = 0;
|
||||
|
||||
if (skip+1 > datalen) {
|
||||
return ASF_ERROR_INVALID_LENGTH;
|
||||
}
|
||||
pl.stream_number = data[skip] & 0x7f;
|
||||
pl.key_frame = !!(data[skip] & 0x80);
|
||||
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) {
|
||||
return tmp;
|
||||
}
|
||||
@@ -119,9 +114,9 @@ asf_data_read_payloads(asf_packet_t *packet,
|
||||
pl.replicated_data = data + skip;
|
||||
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) {
|
||||
if (skip >= datalen) {
|
||||
if (skip+1 > datalen) {
|
||||
/* not enough data */
|
||||
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 */
|
||||
pl.pts -= preroll;
|
||||
/* FIXME: check that pts is positive */
|
||||
if (pl.pts > preroll) {
|
||||
pl.pts -= preroll;
|
||||
} else {
|
||||
pl.pts = 0;
|
||||
}
|
||||
|
||||
if (multiple) {
|
||||
tmp = GETLEN2b(type);
|
||||
|
||||
if (tmp != 2) {
|
||||
/* in multiple payloads datalen should be a word */
|
||||
return ASF_ERROR_INVALID_VALUE;
|
||||
}
|
||||
if (skip + tmp > datalen) {
|
||||
if (skip + 2 > datalen) {
|
||||
/* not enough data */
|
||||
return ASF_ERROR_INVALID_LENGTH;
|
||||
}
|
||||
|
||||
pl.datalen = GETVALUE2b(type, data + skip);
|
||||
skip += tmp;
|
||||
pl.datalen = GetWLE(data + skip);
|
||||
skip += 2;
|
||||
} else {
|
||||
pl.datalen = datalen - skip;
|
||||
}
|
||||
|
||||
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 */
|
||||
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;
|
||||
}
|
||||
|
||||
while (skip < start + used) {
|
||||
for (idx = 0; idx < payloads; idx++) {
|
||||
pl.datalen = data[skip];
|
||||
skip++;
|
||||
|
||||
/* Set data correctly */
|
||||
pl.data = data + skip;
|
||||
skip += pl.datalen;
|
||||
|
||||
pl.pts += pts_delta;
|
||||
/* Copy the final payload and update the PTS */
|
||||
memcpy(&packet->payloads[i], &pl, sizeof(asf_payload_t));
|
||||
packet->payloads[i].pts = pl.pts + idx * pts_delta;
|
||||
i++;
|
||||
|
||||
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,
|
||||
pl.media_object_offset, pl.pts, pl.datalen);
|
||||
pl.media_object_offset, pl.pts + idx * pts_delta, pl.datalen);
|
||||
}
|
||||
} else {
|
||||
pl.data = data + skip;
|
||||
@@ -249,7 +243,7 @@ asf_data_get_packet(asf_packet_t *packet, asf_file_t *file)
|
||||
{
|
||||
asf_iostream_t *iostream;
|
||||
uint32_t read = 0;
|
||||
int packet_flags, packet_property, payload_length_type;
|
||||
int packet_flags, packet_property;
|
||||
void *tmpptr;
|
||||
int tmp;
|
||||
|
||||
@@ -268,9 +262,7 @@ asf_data_get_packet(asf_packet_t *packet, asf_file_t *file)
|
||||
packet->data_size = file->packet_size;
|
||||
}
|
||||
|
||||
tmp = asf_byteio_read(packet->data,
|
||||
file->packet_size,
|
||||
iostream);
|
||||
tmp = asf_byteio_read(iostream, packet->data, file->packet_size);
|
||||
if (tmp < 0) {
|
||||
/* Error reading packet data */
|
||||
return tmp;
|
||||
@@ -298,6 +290,7 @@ asf_data_get_packet(asf_packet_t *packet, asf_file_t *file)
|
||||
read += packet->ec_length;
|
||||
} else {
|
||||
packet->ec_length = 0;
|
||||
packet->ec_data = NULL;
|
||||
}
|
||||
|
||||
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_property = packet->data[read++];
|
||||
|
||||
tmp = asf_data_read_packet_data(packet,
|
||||
packet_flags,
|
||||
&packet->data[read],
|
||||
file->packet_size - read);
|
||||
tmp = asf_data_read_packet_fields(packet, packet_flags,
|
||||
packet->data + read,
|
||||
file->packet_size - read);
|
||||
if (tmp < 0) {
|
||||
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
|
||||
* undefined and we just have to use the header packet size as the size
|
||||
* value */
|
||||
if (!((packet_flags >> 5) & 0x03)) {
|
||||
if (((packet_flags >> 5) & 0x03) == 0) {
|
||||
packet->length = file->packet_size;
|
||||
}
|
||||
|
||||
/* this is also really idiotic, if packet length is smaller than packet
|
||||
* 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) {
|
||||
packet->padding_length += file->packet_size - packet->length;
|
||||
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 */
|
||||
if (packet_flags & 0x01) {
|
||||
int payload_length_type;
|
||||
|
||||
if (read+1 > packet->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;
|
||||
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 {
|
||||
packet->payload_count = 1;
|
||||
payload_length_type = 0x02; /* not used */
|
||||
}
|
||||
|
||||
packet->payload_data_len = packet->length - read;
|
||||
|
||||
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];
|
||||
read += packet->payload_data_len;
|
||||
|
||||
|
||||
/* The return value will be consumed bytes, not including the padding */
|
||||
tmp = asf_data_read_payloads(packet, file->preroll, packet_flags & 0x01,
|
||||
payload_length_type, packet_property,
|
||||
packet->payload_data,
|
||||
packet_property, packet->payload_data,
|
||||
packet->payload_data_len - packet->padding_length);
|
||||
if (tmp < 0) {
|
||||
return tmp;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* 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
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* 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
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -22,23 +22,24 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define INLINE static __inline__
|
||||
#else
|
||||
# define INLINE
|
||||
#endif
|
||||
#include "asfint.h"
|
||||
|
||||
INLINE void
|
||||
|
||||
#if defined(WIN32) && defined(DEBUG)
|
||||
# define debug_printf printf
|
||||
#else
|
||||
static void
|
||||
debug_printf(char *fmt, ...)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
# ifdef DEBUG
|
||||
va_list argp;
|
||||
|
||||
va_start(argp, fmt);
|
||||
vfprintf(stderr, fmt, argp);
|
||||
va_end(argp);
|
||||
fprintf(stderr, "\n");
|
||||
#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
|
||||
* 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
|
||||
* 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
|
||||
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) ||
|
||||
(guid1->v2 != guid2->v2) ||
|
||||
@@ -120,41 +120,41 @@ asf_guid_get_object_type(const asf_guid_t *guid)
|
||||
{
|
||||
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;
|
||||
else if (asf_guid_match(guid, &asf_guid_data))
|
||||
else if (asf_guid_equals(guid, &asf_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;
|
||||
|
||||
else if (asf_guid_match(guid, &asf_guid_file_properties))
|
||||
else if (asf_guid_equals(guid, &asf_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;
|
||||
else if (asf_guid_match(guid, &asf_guid_content_description))
|
||||
else if (asf_guid_equals(guid, &asf_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;
|
||||
else if (asf_guid_match(guid, &asf_guid_marker))
|
||||
else if (asf_guid_equals(guid, &asf_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;
|
||||
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;
|
||||
else if (asf_guid_match(guid, &asf_guid_padding))
|
||||
else if (asf_guid_equals(guid, &asf_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;
|
||||
|
||||
else if (asf_guid_match(guid, &asf_guid_metadata))
|
||||
else if (asf_guid_equals(guid, &asf_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;
|
||||
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;
|
||||
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;
|
||||
else if (asf_guid_match(guid, &asf_guid_stream_prioritization))
|
||||
else if (asf_guid_equals(guid, &asf_guid_stream_prioritization))
|
||||
ret = GUID_STREAM_PRIORITIZATION;
|
||||
|
||||
return ret;
|
||||
@@ -165,15 +165,15 @@ asf_guid_get_stream_type(const asf_guid_t *guid)
|
||||
{
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* 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
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -21,7 +21,15 @@
|
||||
|
||||
#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_HEADER,
|
||||
@@ -49,11 +57,10 @@ enum guid_type_e {
|
||||
GUID_STREAM_TYPE_COMMAND,
|
||||
GUID_STREAM_TYPE_EXTENDED,
|
||||
GUID_STREAM_TYPE_EXTENDED_AUDIO
|
||||
};
|
||||
typedef enum guid_type_e guid_type_t;
|
||||
} 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_stream_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
|
||||
* 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
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -20,7 +20,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "asf.h"
|
||||
#include "asfint.h"
|
||||
#include "utf.h"
|
||||
#include "header.h"
|
||||
@@ -68,10 +67,10 @@ asf_parse_header_stream_properties(asf_stream_t *stream,
|
||||
return ASF_ERROR_INVALID_LENGTH;
|
||||
}
|
||||
|
||||
asf_byteio_getGUID(&guid, objdata);
|
||||
GetGUID(objdata, &guid);
|
||||
type = asf_guid_get_stream_type(&guid);
|
||||
|
||||
datalen = asf_byteio_getDWLE(objdata + 40);
|
||||
datalen = GetDWLE(objdata + 40);
|
||||
if (datalen > objsize - 78) {
|
||||
return ASF_ERROR_INVALID_LENGTH;
|
||||
}
|
||||
@@ -87,7 +86,7 @@ asf_parse_header_stream_properties(asf_stream_t *stream,
|
||||
datalen -= 64;
|
||||
|
||||
/* update the stream type with correct one */
|
||||
asf_byteio_getGUID(&guid, objdata);
|
||||
GetGUID(objdata, &guid);
|
||||
type = asf_guid_get_stream_type(&guid);
|
||||
}
|
||||
|
||||
@@ -102,7 +101,7 @@ asf_parse_header_stream_properties(asf_stream_t *stream,
|
||||
if (datalen < 18) {
|
||||
return ASF_ERROR_INVALID_LENGTH;
|
||||
}
|
||||
if (asf_byteio_getWLE(data + 16) > datalen - 16) {
|
||||
if (GetWLE(data + 16) > datalen - 16) {
|
||||
return ASF_ERROR_INVALID_LENGTH;
|
||||
}
|
||||
|
||||
@@ -113,13 +112,13 @@ asf_parse_header_stream_properties(asf_stream_t *stream,
|
||||
stream->flags |= ASF_STREAM_FLAG_AVAILABLE;
|
||||
|
||||
wfx = stream->properties;
|
||||
wfx->wFormatTag = asf_byteio_getWLE(data);
|
||||
wfx->nChannels = asf_byteio_getWLE(data + 2);
|
||||
wfx->nSamplesPerSec = asf_byteio_getDWLE(data + 4);
|
||||
wfx->nAvgBytesPerSec = asf_byteio_getDWLE(data + 8);
|
||||
wfx->nBlockAlign = asf_byteio_getWLE(data + 12);
|
||||
wfx->wBitsPerSample = asf_byteio_getWLE(data + 14);
|
||||
wfx->cbSize = asf_byteio_getWLE(data + 16);
|
||||
wfx->wFormatTag = GetWLE(data);
|
||||
wfx->nChannels = GetWLE(data + 2);
|
||||
wfx->nSamplesPerSec = GetDWLE(data + 4);
|
||||
wfx->nAvgBytesPerSec = GetDWLE(data + 8);
|
||||
wfx->nBlockAlign = GetWLE(data + 12);
|
||||
wfx->wBitsPerSample = GetWLE(data + 14);
|
||||
wfx->cbSize = GetWLE(data + 16);
|
||||
wfx->data = data + 18;
|
||||
|
||||
if (wfx->cbSize > datalen - 18) {
|
||||
@@ -140,19 +139,19 @@ asf_parse_header_stream_properties(asf_stream_t *stream,
|
||||
return ASF_ERROR_INVALID_LENGTH;
|
||||
}
|
||||
|
||||
width = asf_byteio_getDWLE(data);
|
||||
height = asf_byteio_getDWLE(data + 4);
|
||||
width = GetDWLE(data);
|
||||
height = GetDWLE(data + 4);
|
||||
flags = data[8];
|
||||
data_size = asf_byteio_getWLE(data + 9);
|
||||
data_size = GetWLE(data + 9);
|
||||
|
||||
data += 11;
|
||||
datalen -= 11;
|
||||
|
||||
if (asf_byteio_getDWLE(data) != datalen) {
|
||||
if (GetDWLE(data) != datalen) {
|
||||
return ASF_ERROR_INVALID_LENGTH;
|
||||
}
|
||||
if (width != asf_byteio_getDWLE(data + 4) ||
|
||||
height != asf_byteio_getDWLE(data + 8) ||
|
||||
if (width != GetDWLE(data + 4) ||
|
||||
height != GetDWLE(data + 8) ||
|
||||
flags != 2) {
|
||||
return ASF_ERROR_INVALID_VALUE;
|
||||
}
|
||||
@@ -164,17 +163,17 @@ asf_parse_header_stream_properties(asf_stream_t *stream,
|
||||
stream->flags |= ASF_STREAM_FLAG_AVAILABLE;
|
||||
|
||||
bmih = stream->properties;
|
||||
bmih->biSize = asf_byteio_getDWLE(data);
|
||||
bmih->biWidth = asf_byteio_getDWLE(data + 4);
|
||||
bmih->biHeight = asf_byteio_getDWLE(data + 8);
|
||||
bmih->biPlanes = asf_byteio_getDWLE(data + 12);
|
||||
bmih->biBitCount = asf_byteio_getDWLE(data + 14);
|
||||
bmih->biCompression = asf_byteio_getDWLE(data + 16);
|
||||
bmih->biSizeImage = asf_byteio_getDWLE(data + 20);
|
||||
bmih->biXPelsPerMeter = asf_byteio_getDWLE(data + 24);
|
||||
bmih->biYPelsPerMeter = asf_byteio_getDWLE(data + 28);
|
||||
bmih->biClrUsed = asf_byteio_getDWLE(data + 32);
|
||||
bmih->biClrImportant = asf_byteio_getDWLE(data + 36);
|
||||
bmih->biSize = GetDWLE(data);
|
||||
bmih->biWidth = GetDWLE(data + 4);
|
||||
bmih->biHeight = GetDWLE(data + 8);
|
||||
bmih->biPlanes = GetDWLE(data + 12);
|
||||
bmih->biBitCount = GetDWLE(data + 14);
|
||||
bmih->biCompression = GetDWLE(data + 16);
|
||||
bmih->biSizeImage = GetDWLE(data + 20);
|
||||
bmih->biXPelsPerMeter = GetDWLE(data + 24);
|
||||
bmih->biYPelsPerMeter = GetDWLE(data + 28);
|
||||
bmih->biClrUsed = GetDWLE(data + 32);
|
||||
bmih->biClrImportant = GetDWLE(data + 36);
|
||||
bmih->data = data + 40;
|
||||
|
||||
if (bmih->biSize > datalen) {
|
||||
@@ -200,27 +199,27 @@ asf_parse_header_extended_stream_properties(asf_stream_t *stream,
|
||||
uint8_t *objdata,
|
||||
uint32_t objsize)
|
||||
{
|
||||
asf_stream_extended_t ext;
|
||||
asf_stream_extended_properties_t ext;
|
||||
uint32_t datalen;
|
||||
uint8_t *data;
|
||||
uint16_t flags;
|
||||
int i;
|
||||
|
||||
ext.start_time = asf_byteio_getQWLE(objdata);
|
||||
ext.end_time = asf_byteio_getQWLE(objdata + 8);
|
||||
ext.data_bitrate = asf_byteio_getDWLE(objdata + 16);
|
||||
ext.buffer_size = asf_byteio_getDWLE(objdata + 20);
|
||||
ext.initial_buf_fullness = asf_byteio_getDWLE(objdata + 24);
|
||||
ext.data_bitrate2 = asf_byteio_getDWLE(objdata + 28);
|
||||
ext.buffer_size2 = asf_byteio_getDWLE(objdata + 32);
|
||||
ext.initial_buf_fullness2 = asf_byteio_getDWLE(objdata + 36);
|
||||
ext.max_obj_size = asf_byteio_getDWLE(objdata + 40);
|
||||
ext.flags = asf_byteio_getDWLE(objdata + 44);
|
||||
ext.stream_num = asf_byteio_getWLE(objdata + 48);
|
||||
ext.lang_idx = asf_byteio_getWLE(objdata + 50);
|
||||
ext.avg_time_per_frame = asf_byteio_getQWLE(objdata + 52);
|
||||
ext.stream_name_count = asf_byteio_getWLE(objdata + 60);
|
||||
ext.num_payload_ext = asf_byteio_getWLE(objdata + 62);
|
||||
ext.start_time = GetQWLE(objdata);
|
||||
ext.end_time = GetQWLE(objdata + 8);
|
||||
ext.data_bitrate = GetDWLE(objdata + 16);
|
||||
ext.buffer_size = GetDWLE(objdata + 20);
|
||||
ext.initial_buf_fullness = GetDWLE(objdata + 24);
|
||||
ext.data_bitrate2 = GetDWLE(objdata + 28);
|
||||
ext.buffer_size2 = GetDWLE(objdata + 32);
|
||||
ext.initial_buf_fullness2 = GetDWLE(objdata + 36);
|
||||
ext.max_obj_size = GetDWLE(objdata + 40);
|
||||
ext.flags = GetDWLE(objdata + 44);
|
||||
ext.stream_num = GetWLE(objdata + 48);
|
||||
ext.lang_idx = GetWLE(objdata + 50);
|
||||
ext.avg_time_per_frame = GetQWLE(objdata + 52);
|
||||
ext.stream_name_count = GetWLE(objdata + 60);
|
||||
ext.num_payload_ext = GetWLE(objdata + 62);
|
||||
|
||||
datalen = objsize - 88;
|
||||
data = objdata + 64;
|
||||
@@ -233,7 +232,7 @@ asf_parse_header_extended_stream_properties(asf_stream_t *stream,
|
||||
return ASF_ERROR_INVALID_VALUE;
|
||||
}
|
||||
|
||||
strlen = asf_byteio_getWLE(data + 2);
|
||||
strlen = GetWLE(data + 2);
|
||||
if (strlen > datalen) {
|
||||
return ASF_ERROR_INVALID_LENGTH;
|
||||
}
|
||||
@@ -251,7 +250,7 @@ asf_parse_header_extended_stream_properties(asf_stream_t *stream,
|
||||
return ASF_ERROR_INVALID_VALUE;
|
||||
}
|
||||
|
||||
extsyslen = asf_byteio_getDWLE(data + 18);
|
||||
extsyslen = GetDWLE(data + 18);
|
||||
if (extsyslen > datalen) {
|
||||
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 */
|
||||
if (datalen < 78) {
|
||||
return ASF_ERROR_OBJECT_SIZE;
|
||||
return ASF_ERROR_INVALID_OBJECT_SIZE;
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
return ASF_ERROR_INVALID_OBJECT;
|
||||
}
|
||||
if (asf_byteio_getQWLE(data + 16) != datalen) {
|
||||
return ASF_ERROR_OBJECT_SIZE;
|
||||
if (GetQWLE(data + 16) != datalen) {
|
||||
return ASF_ERROR_INVALID_OBJECT_SIZE;
|
||||
}
|
||||
|
||||
flags = asf_byteio_getWLE(data + 72);
|
||||
flags = GetWLE(data + 72);
|
||||
|
||||
if ((flags & 0x7f) != ext.stream_num || stream->type) {
|
||||
/* 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));
|
||||
if (!stream->extended) {
|
||||
stream->extended_properties = malloc(sizeof(asf_stream_extended_properties_t));
|
||||
if (!stream->extended_properties) {
|
||||
return ASF_ERROR_OUTOFMEM;
|
||||
}
|
||||
stream->flags |= ASF_STREAM_FLAG_EXTENDED;
|
||||
memcpy(stream->extended, &ext, sizeof(ext));
|
||||
memcpy(stream->extended_properties, &ext, sizeof(ext));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -333,7 +332,7 @@ asf_parse_header_validate(asf_file_t *file, asf_object_header_t *header)
|
||||
{
|
||||
uint32_t max_packet_size;
|
||||
if (size < 104)
|
||||
return ASF_ERROR_OBJECT_SIZE;
|
||||
return ASF_ERROR_INVALID_OBJECT_SIZE;
|
||||
|
||||
if (fileprop) {
|
||||
/* 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;
|
||||
asf_byteio_getGUID(&file->file_id, current->data);
|
||||
file->file_size = asf_byteio_getQWLE(current->data + 16);
|
||||
file->creation_date = asf_byteio_getQWLE(current->data + 24);
|
||||
file->data_packets_count = asf_byteio_getQWLE(current->data + 32);
|
||||
file->play_duration = asf_byteio_getQWLE(current->data + 40);
|
||||
file->send_duration = asf_byteio_getQWLE(current->data + 48);
|
||||
file->preroll = asf_byteio_getQWLE(current->data + 56);
|
||||
file->flags = asf_byteio_getDWLE(current->data + 64);
|
||||
file->packet_size = asf_byteio_getDWLE(current->data + 68);
|
||||
file->max_bitrate = asf_byteio_getQWLE(current->data + 76);
|
||||
GetGUID(current->data, &file->file_id);
|
||||
file->file_size = GetQWLE(current->data + 16);
|
||||
file->creation_date = GetQWLE(current->data + 24);
|
||||
file->data_packets_count = GetQWLE(current->data + 32);
|
||||
file->play_duration = GetQWLE(current->data + 40);
|
||||
file->send_duration = GetQWLE(current->data + 48);
|
||||
file->preroll = GetQWLE(current->data + 56);
|
||||
file->flags = GetDWLE(current->data + 64);
|
||||
file->packet_size = GetDWLE(current->data + 68);
|
||||
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) {
|
||||
/* in ASF file minimum packet size and maximum
|
||||
* 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;
|
||||
|
||||
if (size < 78)
|
||||
return ASF_ERROR_OBJECT_SIZE;
|
||||
return ASF_ERROR_INVALID_OBJECT_SIZE;
|
||||
|
||||
streamprop = 1;
|
||||
flags = asf_byteio_getWLE(current->data + 48);
|
||||
flags = GetWLE(current->data + 48);
|
||||
stream = &file->streams[flags & 0x7f];
|
||||
|
||||
if (stream->type) {
|
||||
@@ -393,13 +392,13 @@ asf_parse_header_validate(asf_file_t *file, asf_object_header_t *header)
|
||||
uint32_t stringlen = 0;
|
||||
|
||||
if (size < 34)
|
||||
return ASF_ERROR_OBJECT_SIZE;
|
||||
return ASF_ERROR_INVALID_OBJECT_SIZE;
|
||||
|
||||
stringlen += asf_byteio_getWLE(current->data);
|
||||
stringlen += asf_byteio_getWLE(current->data + 2);
|
||||
stringlen += asf_byteio_getWLE(current->data + 4);
|
||||
stringlen += asf_byteio_getWLE(current->data + 6);
|
||||
stringlen += asf_byteio_getWLE(current->data + 8);
|
||||
stringlen += GetWLE(current->data);
|
||||
stringlen += GetWLE(current->data + 2);
|
||||
stringlen += GetWLE(current->data + 4);
|
||||
stringlen += GetWLE(current->data + 6);
|
||||
stringlen += GetWLE(current->data + 8);
|
||||
|
||||
if (size < stringlen + 34) {
|
||||
/* invalid string length values */
|
||||
@@ -411,17 +410,17 @@ asf_parse_header_validate(asf_file_t *file, asf_object_header_t *header)
|
||||
break;
|
||||
case GUID_CODEC_LIST:
|
||||
if (size < 44)
|
||||
return ASF_ERROR_OBJECT_SIZE;
|
||||
return ASF_ERROR_INVALID_OBJECT_SIZE;
|
||||
break;
|
||||
case GUID_STREAM_BITRATE_PROPERTIES:
|
||||
if (size < 26)
|
||||
return ASF_ERROR_OBJECT_SIZE;
|
||||
return ASF_ERROR_INVALID_OBJECT_SIZE;
|
||||
break;
|
||||
case GUID_PADDING:
|
||||
break;
|
||||
case GUID_EXTENDED_CONTENT_DESCRIPTION:
|
||||
if (size < 26)
|
||||
return ASF_ERROR_OBJECT_SIZE;
|
||||
return ASF_ERROR_INVALID_OBJECT_SIZE;
|
||||
break;
|
||||
case GUID_UNKNOWN:
|
||||
/* unknown guid type */
|
||||
@@ -443,11 +442,11 @@ asf_parse_header_validate(asf_file_t *file, asf_object_header_t *header)
|
||||
switch (current->type) {
|
||||
case GUID_METADATA:
|
||||
if (size < 26)
|
||||
return ASF_ERROR_OBJECT_SIZE;
|
||||
return ASF_ERROR_INVALID_OBJECT_SIZE;
|
||||
break;
|
||||
case GUID_LANGUAGE_LIST:
|
||||
if (size < 26)
|
||||
return ASF_ERROR_OBJECT_SIZE;
|
||||
return ASF_ERROR_INVALID_OBJECT_SIZE;
|
||||
break;
|
||||
case GUID_EXTENDED_STREAM_PROPERTIES:
|
||||
{
|
||||
@@ -456,9 +455,9 @@ asf_parse_header_validate(asf_file_t *file, asf_object_header_t *header)
|
||||
int ret;
|
||||
|
||||
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];
|
||||
|
||||
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:
|
||||
if (size < 42)
|
||||
return ASF_ERROR_OBJECT_SIZE;
|
||||
return ASF_ERROR_INVALID_OBJECT_SIZE;
|
||||
break;
|
||||
case GUID_STREAM_PRIORITIZATION:
|
||||
if (size < 26)
|
||||
return ASF_ERROR_OBJECT_SIZE;
|
||||
return ASF_ERROR_INVALID_OBJECT_SIZE;
|
||||
break;
|
||||
case GUID_UNKNOWN:
|
||||
/* 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
|
||||
* there's always enough data to read and there are no overflows */
|
||||
for (i=0; i<5; i++) {
|
||||
strlen = asf_byteio_getWLE(current->data + i*2);
|
||||
strlen = GetWLE(current->data + i*2);
|
||||
if (!strlen)
|
||||
continue;
|
||||
|
||||
@@ -590,7 +589,7 @@ asf_header_metadata(asf_object_header_t *header)
|
||||
if (current) {
|
||||
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));
|
||||
if (!ret->extended) {
|
||||
/* 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++) {
|
||||
uint16_t length, type;
|
||||
|
||||
length = asf_byteio_getWLE(current->data + position);
|
||||
length = GetWLE(current->data + position);
|
||||
position += 2;
|
||||
|
||||
ret->extended[i].key = asf_utf8_from_utf16le(current->data + position, length);
|
||||
position += length;
|
||||
|
||||
type = asf_byteio_getWLE(current->data + position);
|
||||
type = GetWLE(current->data + position);
|
||||
position += 2;
|
||||
|
||||
length = asf_byteio_getWLE(current->data + position);
|
||||
length = GetWLE(current->data + position);
|
||||
position += 2;
|
||||
|
||||
switch (type) {
|
||||
@@ -645,19 +644,19 @@ asf_header_metadata(asf_object_header_t *header)
|
||||
/* type of the value is a signed 32-bit integer */
|
||||
ret->extended[i].value = malloc(11 * sizeof(char));
|
||||
sprintf(ret->extended[i].value, "%u",
|
||||
asf_byteio_getDWLE(current->data + position));
|
||||
GetDWLE(current->data + position));
|
||||
break;
|
||||
case 4:
|
||||
/* FIXME: This doesn't print whole 64-bit integer */
|
||||
ret->extended[i].value = malloc(21 * sizeof(char));
|
||||
sprintf(ret->extended[i].value, "%u",
|
||||
(uint32_t) asf_byteio_getQWLE(current->data + position));
|
||||
(uint32_t) GetQWLE(current->data + position));
|
||||
break;
|
||||
case 5:
|
||||
/* type of the value is a signed 16-bit integer */
|
||||
ret->extended[i].value = malloc(6 * sizeof(char));
|
||||
sprintf(ret->extended[i].value, "%u",
|
||||
asf_byteio_getWLE(current->data + position));
|
||||
GetWLE(current->data + position));
|
||||
break;
|
||||
default:
|
||||
/* Unknown value type... */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* 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
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* 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
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -22,7 +22,6 @@
|
||||
#include "asf.h"
|
||||
#include "asfint.h"
|
||||
#include "byteio.h"
|
||||
#include "utf.h"
|
||||
#include "header.h"
|
||||
#include "guid.h"
|
||||
#include "debug.h"
|
||||
@@ -36,9 +35,9 @@
|
||||
static void
|
||||
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->size = asf_byteio_getQWLE(data + 16);
|
||||
obj->size = GetQWLE(data + 16);
|
||||
obj->full_data = data;
|
||||
obj->datalen = 0;
|
||||
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) {
|
||||
/* invalide size for headerext */
|
||||
return ASF_ERROR_OBJECT_SIZE;
|
||||
return ASF_ERROR_INVALID_OBJECT_SIZE;
|
||||
}
|
||||
|
||||
/* Read reserved and datalen fields from the buffer */
|
||||
asf_byteio_getGUID(&header->reserved1, buf + 24);
|
||||
header->reserved2 = asf_byteio_getWLE(buf + 40);
|
||||
header->datalen = asf_byteio_getDWLE(buf + 42);
|
||||
GetGUID(buf + 24, &header->reserved1);
|
||||
header->reserved2 = GetWLE(buf + 40);
|
||||
header->datalen = GetDWLE(buf + 42);
|
||||
|
||||
if (header->datalen != header->size - 46) {
|
||||
/* 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
|
||||
* 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) {
|
||||
/* not enough data to read the header object */
|
||||
return tmp;
|
||||
@@ -165,11 +164,11 @@ asf_parse_header(asf_file_t *file)
|
||||
asf_parse_read_object((asfint_object_t *) header, hdata);
|
||||
if (header->size < 30) {
|
||||
/* invalid size for header object */
|
||||
return ASF_ERROR_OBJECT_SIZE;
|
||||
return ASF_ERROR_INVALID_OBJECT_SIZE;
|
||||
}
|
||||
|
||||
/* read header object specific compulsory fields */
|
||||
header->subobjects = asf_byteio_getDWLE(hdata + 24);
|
||||
header->subobjects = GetDWLE(hdata + 24);
|
||||
header->reserved1 = hdata[28];
|
||||
header->reserved2 = hdata[29];
|
||||
|
||||
@@ -185,7 +184,7 @@ asf_parse_header(asf_file_t *file)
|
||||
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) {
|
||||
return tmp;
|
||||
}
|
||||
@@ -300,7 +299,7 @@ asf_parse_data(asf_file_t *file)
|
||||
|
||||
/* object minimum is 24 bytes and data object needs to have
|
||||
* 26 additional bytes for its internal fields */
|
||||
tmp = asf_byteio_read(ddata, 50, iostream);
|
||||
tmp = asf_byteio_read(iostream, ddata, 50);
|
||||
if (tmp < 0) {
|
||||
return tmp;
|
||||
}
|
||||
@@ -315,22 +314,22 @@ asf_parse_data(asf_file_t *file)
|
||||
asf_parse_read_object((asfint_object_t *) data, ddata);
|
||||
if (data->size < 50) {
|
||||
/* invalid size for data object */
|
||||
return ASF_ERROR_OBJECT_SIZE;
|
||||
return ASF_ERROR_INVALID_OBJECT_SIZE;
|
||||
}
|
||||
|
||||
/* read data object specific compulsory fields */
|
||||
asf_byteio_getGUID(&data->file_id, ddata + 24);
|
||||
data->total_data_packets = asf_byteio_getQWLE(ddata + 40);
|
||||
data->reserved = asf_byteio_getWLE(ddata + 48);
|
||||
GetGUID(ddata + 24, &data->file_id);
|
||||
data->total_data_packets = GetQWLE(ddata + 40);
|
||||
data->reserved = GetWLE(ddata + 48);
|
||||
data->packets_position = file->position + 50;
|
||||
|
||||
/* If the file_id GUID in data object doesn't match the
|
||||
* 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;
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
if (data->total_data_packets &&
|
||||
data->total_data_packets != file->data_packets_count) {
|
||||
@@ -361,7 +360,7 @@ asf_parse_index(asf_file_t *file)
|
||||
iostream = &file->iostream;
|
||||
|
||||
/* 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) {
|
||||
printf("Could not read index header\n");
|
||||
return tmp;
|
||||
@@ -385,13 +384,13 @@ asf_parse_index(asf_file_t *file)
|
||||
if (index->size < 56) {
|
||||
/* invalid size for index object */
|
||||
free(index);
|
||||
return ASF_ERROR_OBJECT_SIZE;
|
||||
return ASF_ERROR_INVALID_OBJECT_SIZE;
|
||||
}
|
||||
|
||||
asf_byteio_getGUID(&index->file_id, idata + 24);
|
||||
index->entry_time_interval = asf_byteio_getQWLE(idata + 40);
|
||||
index->max_packet_count = asf_byteio_getDWLE(idata + 48);
|
||||
index->entry_count = asf_byteio_getDWLE(idata + 52);
|
||||
GetGUID(idata + 24, &index->file_id);
|
||||
index->entry_time_interval = GetQWLE(idata + 40);
|
||||
index->max_packet_count = GetDWLE(idata + 48);
|
||||
index->entry_count = GetDWLE(idata + 52);
|
||||
|
||||
printf("INDEX\n");
|
||||
printf("Total Index Entries %d\n",index->entry_count);
|
||||
@@ -416,8 +415,7 @@ asf_parse_index(asf_file_t *file)
|
||||
free(index);
|
||||
return ASF_ERROR_OUTOFMEM;
|
||||
}
|
||||
|
||||
tmp = asf_byteio_read(entry_data, entry_data_size, iostream);
|
||||
tmp = asf_byteio_read(iostream, entry_data, entry_data_size);
|
||||
if (tmp < 0) {
|
||||
printf("Could not read entry data\n");
|
||||
free(index);
|
||||
@@ -433,8 +431,8 @@ asf_parse_index(asf_file_t *file)
|
||||
}
|
||||
|
||||
for (i=0; i<index->entry_count; i++) {
|
||||
index->entries[i].packet_index = asf_byteio_getDWLE(entry_data + i*6);
|
||||
index->entries[i].packet_count = asf_byteio_getWLE(entry_data + i*6 + 4);
|
||||
index->entries[i].packet_index = GetDWLE(entry_data + i*6);
|
||||
index->entries[i].packet_count = GetWLE(entry_data + i*6 + 4);
|
||||
}
|
||||
|
||||
free(entry_data);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* 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
|
||||
* 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
|
||||
* 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
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -19,6 +19,92 @@
|
||||
#ifndef 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
|
||||
|
||||
Reference in New Issue
Block a user