mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 480521 - Update libfishsound to e98a05 and liboggz to ef3b0e. rs=roc
This commit is contained in:
parent
968e728351
commit
0614eb4541
@ -4,6 +4,9 @@ Conrad Parker <conrad@metadecks.org>
|
||||
|
||||
Tobias Gehrig
|
||||
- FLAC support
|
||||
|
||||
Michel Salim
|
||||
- libFLAC 1.1.3 support
|
||||
|
||||
Silvia Pfeiffer <silvia@annodex.net>
|
||||
- MS Windows porting, general packaging.
|
||||
|
@ -1,10 +1,11 @@
|
||||
The source from this directory was copied from the libfishsound-0.9.1
|
||||
source distribution using the update.sh script. The only changes made
|
||||
The source from this directory was copied from the libfishsound git
|
||||
distribution using the update.sh script. The only changes made
|
||||
were those applied by update.sh and the addition/upate of Makefile.in
|
||||
files for the Mozilla build system.
|
||||
|
||||
Some files are renamed during the copy to prevent clashes with object
|
||||
file names with other Mozilla libraries.
|
||||
|
||||
The git commit id used was e98a05 from git://git.xiph.org/libfishsound.git
|
||||
|
||||
endian.patch is applied to fix Bug 45269.
|
||||
bu481601.patch is applied to fix bug 481601.
|
||||
|
@ -35,7 +35,7 @@
|
||||
/* #undef HAVE_SPEEX_1_1 */
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
/* #define HAVE_STDINT_H 1 */
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
@ -106,6 +106,9 @@ typedef enum _FishSoundError {
|
||||
/** The requested operation is not suitable for this FishSound* handle */
|
||||
FISH_SOUND_ERR_INVALID = -3,
|
||||
|
||||
/** Out of memory */
|
||||
FISH_SOUND_ERR_OUT_OF_MEMORY = -4,
|
||||
|
||||
/** Functionality disabled at build time */
|
||||
FISH_SOUND_ERR_DISABLED = -10,
|
||||
|
||||
|
@ -79,7 +79,9 @@ typedef int (*FishSoundDecoded_FloatIlv) (FishSound * fsound, float ** pcm,
|
||||
* \param fsound A FishSound* handle (created with mode FISH_SOUND_DECODE)
|
||||
* \param decoded The callback to call
|
||||
* \param user_data Arbitrary user data to pass to the callback
|
||||
* \returns 0 on success, -1 on failure
|
||||
* \retval 0 Success
|
||||
* \retval FISH_SOUND_ERR_BAD Not a valid FishSound* handle
|
||||
* \retval FISH_SOUND_ERR_OUT_OF_MEMORY Out of memory
|
||||
*/
|
||||
int fish_sound_set_decoded_float (FishSound * fsound,
|
||||
FishSoundDecoded_Float decoded,
|
||||
@ -91,7 +93,9 @@ int fish_sound_set_decoded_float (FishSound * fsound,
|
||||
* \param fsound A FishSound* handle (created with mode FISH_SOUND_DECODE)
|
||||
* \param decoded The callback to call
|
||||
* \param user_data Arbitrary user data to pass to the callback
|
||||
* \returns 0 on success, -1 on failure
|
||||
* \retval 0 Success
|
||||
* \retval FISH_SOUND_ERR_BAD Not a valid FishSound* handle
|
||||
* \retval FISH_SOUND_ERR_OUT_OF_MEMORY Out of memory
|
||||
*/
|
||||
int fish_sound_set_decoded_float_ilv (FishSound * fsound,
|
||||
FishSoundDecoded_FloatIlv decoded,
|
||||
@ -113,6 +117,8 @@ int fish_sound_set_decoded_float_ilv (FishSound * fsound,
|
||||
* callback returning FISH_SOUND_STOP_ERR before any input bytes were consumed.
|
||||
* This will occur when PCM is decoded from previously buffered input, and
|
||||
* stopping is immediately requested.
|
||||
* \retval FISH_SOUND_ERR_BAD Not a valid FishSound* handle
|
||||
* \retval FISH_SOUND_ERR_OUT_OF_MEMORY Out of memory
|
||||
*/
|
||||
long fish_sound_decode (FishSound * fsound, unsigned char * buf, long bytes);
|
||||
|
||||
|
@ -41,27 +41,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* DEPRECATED FUNCTION.
|
||||
* Set the PCM format used by a FishSound object. The default value is
|
||||
* non-interleaved.
|
||||
* Prior to libfishsound 0.7.0, you would (optionally) specify whether you
|
||||
* wanted to receive interleaved or per-channel PCM data using
|
||||
* fish_sound_set_interleave(), the default being per-channel
|
||||
* (non-interleaved) PCM.
|
||||
* Whether or not your decoded callback expects interleaved or
|
||||
* non-interleaved data is now implied by the particular
|
||||
* fish_sound_set_decoded_TYPE() method you use to set it, such as
|
||||
* fish_sound_set_decoded_float() or fish_sound_set_decode_float_ilv().
|
||||
*
|
||||
* \param fsound A FishSound* handle
|
||||
* \param interleave Whether to use interleaved PCM or not. Valid values are
|
||||
* 0 for non-interleaved, and 1 for interleaved.
|
||||
* \retval 0 Success
|
||||
* \retval -1 Invalid \a fsound
|
||||
*/
|
||||
int fish_sound_set_interleave (FishSound * fsound, int interleave);
|
||||
|
||||
/**
|
||||
* DEPRECATED TYPE.
|
||||
* Signature of a callback for libfishsound to call when it has decoded
|
||||
@ -99,7 +78,7 @@ int fish_sound_set_decoded_callback (FishSound * fsound,
|
||||
* Whether or not your decoded callback expects interleaved or
|
||||
* non-interleaved data is now implied by the particular
|
||||
* fish_sound_set_decoded_TYPE() method you use to set it, such as
|
||||
* fish_sound_set_decoded_float() or fish_sound_set_decode_float_ilv().
|
||||
* fish_sound_set_decoded_float() or fish_sound_set_decoded_float_ilv().
|
||||
*
|
||||
* \param fsound A FishSound* handle
|
||||
* \param interleave Whether to use interleaved PCM or not. Valid values are
|
||||
|
@ -505,7 +505,7 @@ int fish_sound_command (FishSound * fsound, int command, void * data,
|
||||
* \param fsound A FishSound* handle
|
||||
* \retval 0 \a fsound uses non-interleaved PCM
|
||||
* \retval 1 \a fsound uses interleaved PCM
|
||||
* \retval -1 Invalid \a fsound
|
||||
* \retval -1 Invalid \a fsound, or out of memory.
|
||||
*/
|
||||
int fish_sound_get_interleave (FishSound * fsound);
|
||||
|
||||
|
@ -35,7 +35,7 @@
|
||||
/* #undef HAVE_SPEEX_1_1 */
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
/* #define HAVE_STDINT_H 1 */
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
@ -70,7 +70,7 @@ fish_sound_set_format (FishSound * fsound, int format)
|
||||
}
|
||||
|
||||
if (fsound->codec && fsound->codec->init)
|
||||
fsound->codec->init (fsound);
|
||||
if (fsound->codec->init (fsound) == NULL) return -1;
|
||||
|
||||
fsound->info.format = format;
|
||||
|
||||
@ -105,6 +105,7 @@ fish_sound_new (int mode, FishSoundInfo * fsinfo)
|
||||
}
|
||||
|
||||
fsound = fs_malloc (sizeof (FishSound));
|
||||
if (fsound == NULL) return NULL;
|
||||
|
||||
fsound->mode = mode;
|
||||
fsound->interleave = 0;
|
||||
|
@ -35,27 +35,50 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h> /* ULONG_MAX */
|
||||
#ifndef WIN32
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#include "private.h"
|
||||
|
||||
/*#define DEBUG*/
|
||||
|
||||
/* Ensure comment vector length can be expressed in 32 bits
|
||||
* including space for the trailing NUL */
|
||||
#define MAX_COMMENT_LENGTH 0xFFFFFFFE
|
||||
#define fs_comment_clamp(c) MIN((c),MAX_COMMENT_LENGTH)
|
||||
|
||||
static size_t
|
||||
fs_comment_len (const char * s)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
if (s == NULL) return 0;
|
||||
|
||||
len = strlen (s);
|
||||
return fs_comment_clamp(len);
|
||||
}
|
||||
|
||||
static char *
|
||||
fs_strdup (const char * s)
|
||||
{
|
||||
char * ret;
|
||||
if (s == NULL) return NULL;
|
||||
ret = fs_malloc (strlen(s) + 1);
|
||||
ret = fs_malloc (fs_comment_len(s) + 1);
|
||||
if (ret == NULL) return NULL;
|
||||
return strcpy (ret, s);
|
||||
}
|
||||
|
||||
static char *
|
||||
fs_strdup_len (const char * s, int len)
|
||||
fs_strdup_len (const char * s, size_t len)
|
||||
{
|
||||
char * ret;
|
||||
if (s == NULL) return NULL;
|
||||
if (len == 0) return NULL;
|
||||
len = fs_comment_clamp(len);
|
||||
ret = fs_malloc (len + 1);
|
||||
if (ret == NULL) return NULL;
|
||||
if (strncpy (ret, s, len) == NULL) {
|
||||
fs_free (ret);
|
||||
return NULL;
|
||||
@ -79,11 +102,6 @@ fs_index_len (const char * s, char c, int len)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void comment_init(char **comments, int* length, char *vendor_string);
|
||||
static void comment_add(char **comments, int* length, char *tag, char *val);
|
||||
#endif
|
||||
|
||||
/*
|
||||
Comments will be stored in the Vorbis style.
|
||||
It is describled in the "Structure" section of
|
||||
@ -114,47 +132,6 @@ The comment header is decoded as follows:
|
||||
buf[base]=(val)&0xff; \
|
||||
}while(0)
|
||||
|
||||
#if 0
|
||||
static void
|
||||
comment_init(char **comments, int* length, char *vendor_string)
|
||||
{
|
||||
int vendor_length=strlen(vendor_string);
|
||||
int user_comment_list_length=0;
|
||||
int len=4+vendor_length+4;
|
||||
char *p=(char*)fs_malloc(len);
|
||||
if(p==NULL){
|
||||
}
|
||||
writeint(p, 0, vendor_length);
|
||||
memcpy(p+4, vendor_string, vendor_length);
|
||||
writeint(p, 4+vendor_length, user_comment_list_length);
|
||||
*length=len;
|
||||
*comments=p;
|
||||
}
|
||||
|
||||
static void
|
||||
comment_add(char **comments, int* length, char *tag, char *val)
|
||||
{
|
||||
char* p=*comments;
|
||||
int vendor_length=readint(p, 0);
|
||||
int user_comment_list_length=readint(p, 4+vendor_length);
|
||||
int tag_len=(tag?strlen(tag):0);
|
||||
int val_len=strlen(val);
|
||||
int len=(*length)+4+tag_len+val_len;
|
||||
|
||||
p=(char*)fs_realloc(p, len);
|
||||
if(p==NULL){
|
||||
}
|
||||
|
||||
writeint(p, *length, tag_len+val_len); /* length of comment */
|
||||
if(tag) memcpy(p+*length+4, tag, tag_len); /* comment */
|
||||
memcpy(p+*length+4+tag_len, val, val_len); /* comment */
|
||||
writeint(p, 4+vendor_length, user_comment_list_length+1);
|
||||
|
||||
*comments=p;
|
||||
*length=len;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
fs_comment_validate_byname (const char * name, const char * value)
|
||||
{
|
||||
@ -182,10 +159,23 @@ fs_comment_new (const char * name, const char * value)
|
||||
FishSoundComment * comment;
|
||||
|
||||
if (!fs_comment_validate_byname (name, value)) return NULL;
|
||||
/* Ensures that name != NULL, value != NULL, and validates strings */
|
||||
|
||||
comment = fs_malloc (sizeof (FishSoundComment));
|
||||
if (comment == NULL) return NULL;
|
||||
|
||||
comment->name = fs_strdup (name);
|
||||
if (comment->name == NULL) {
|
||||
fs_free (comment);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
comment->value = fs_strdup (value);
|
||||
if (comment->value == NULL) {
|
||||
fs_free (comment->name);
|
||||
fs_free (comment);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return comment;
|
||||
}
|
||||
@ -211,6 +201,19 @@ fs_comment_cmp (const FishSoundComment * comment1, const FishSoundComment * comm
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
fish_sound_comment_set_vendor (FishSound * fsound, const char * vendor_string)
|
||||
{
|
||||
if (fsound == NULL) return FISH_SOUND_ERR_BAD;
|
||||
|
||||
if (fsound->vendor) fs_free (fsound->vendor);
|
||||
|
||||
if ((fsound->vendor = fs_strdup (vendor_string)) == NULL)
|
||||
return FISH_SOUND_ERR_OUT_OF_MEMORY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Public API */
|
||||
|
||||
const char *
|
||||
@ -221,18 +224,6 @@ fish_sound_comment_get_vendor (FishSound * fsound)
|
||||
return fsound->vendor;
|
||||
}
|
||||
|
||||
int
|
||||
fish_sound_comment_set_vendor (FishSound * fsound, const char * vendor_string)
|
||||
{
|
||||
if (fsound == NULL) return FISH_SOUND_ERR_BAD;
|
||||
|
||||
if (fsound->vendor) fs_free (fsound->vendor);
|
||||
|
||||
fsound->vendor = fs_strdup (vendor_string);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const FishSoundComment *
|
||||
fish_sound_comment_first (FishSound * fsound)
|
||||
{
|
||||
@ -311,11 +302,13 @@ fish_sound_comment_add (FishSound * fsound, FishSoundComment * comment)
|
||||
if (!fs_comment_validate_byname (comment->name, comment->value))
|
||||
return FISH_SOUND_ERR_COMMENT_INVALID;
|
||||
|
||||
new_comment = fs_comment_new (comment->name, comment->value);
|
||||
if ((new_comment = fs_comment_new (comment->name, comment->value)) == NULL)
|
||||
return FISH_SOUND_ERR_OUT_OF_MEMORY;
|
||||
|
||||
_fs_comment_add (fsound, new_comment);
|
||||
if (_fs_comment_add (fsound, new_comment) == NULL)
|
||||
return FISH_SOUND_ERR_OUT_OF_MEMORY;
|
||||
|
||||
return 0;
|
||||
return FISH_SOUND_OK;
|
||||
#else
|
||||
return FISH_SOUND_ERR_DISABLED;
|
||||
#endif
|
||||
@ -336,9 +329,13 @@ fish_sound_comment_add_byname (FishSound * fsound, const char * name,
|
||||
if (!fs_comment_validate_byname (name, value))
|
||||
return FISH_SOUND_ERR_COMMENT_INVALID;
|
||||
|
||||
comment = fs_comment_new (name, value);
|
||||
if ((comment = fs_comment_new (name, value)) == NULL)
|
||||
return FISH_SOUND_ERR_OUT_OF_MEMORY;
|
||||
|
||||
_fs_comment_add (fsound, comment);
|
||||
if (_fs_comment_add (fsound, comment) == NULL)
|
||||
return FISH_SOUND_ERR_OUT_OF_MEMORY;
|
||||
|
||||
return FISH_SOUND_OK;
|
||||
|
||||
return 0;
|
||||
|
||||
@ -429,7 +426,8 @@ fish_sound_comments_decode (FishSound * fsound, unsigned char * comments,
|
||||
long length)
|
||||
{
|
||||
char *c= (char *)comments;
|
||||
int len, i, nb_fields, n;
|
||||
int i, nb_fields, n;
|
||||
size_t len;
|
||||
char *end;
|
||||
char * name, * value, * nvalue = NULL;
|
||||
FishSoundComment * comment;
|
||||
@ -439,14 +437,20 @@ fish_sound_comments_decode (FishSound * fsound, unsigned char * comments,
|
||||
|
||||
end = c+length;
|
||||
len=readint(c, 0);
|
||||
if (len<0) return -1;
|
||||
|
||||
c+=4;
|
||||
if (c+len>end) return -1;
|
||||
if (len>end-c) return -1;
|
||||
|
||||
/* Vendor */
|
||||
nvalue = fs_strdup_len (c, len);
|
||||
fish_sound_comment_set_vendor (fsound, nvalue);
|
||||
if (nvalue) fs_free (nvalue);
|
||||
if (len > 0) {
|
||||
if ((nvalue = fs_strdup_len (c, len)) == NULL)
|
||||
return FISH_SOUND_ERR_OUT_OF_MEMORY;
|
||||
if (fish_sound_comment_set_vendor (fsound, nvalue) == FISH_SOUND_ERR_OUT_OF_MEMORY)
|
||||
return FISH_SOUND_ERR_OUT_OF_MEMORY;
|
||||
|
||||
fs_free (nvalue);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
fwrite(c, 1, len, stderr); fputc ('\n', stderr);
|
||||
#endif
|
||||
@ -454,6 +458,8 @@ fish_sound_comments_decode (FishSound * fsound, unsigned char * comments,
|
||||
|
||||
if (c+4>end) return -1;
|
||||
|
||||
/* This value gets checked effectively by the 'for' condition
|
||||
and the checks within the loop for c running off the end. */
|
||||
nb_fields=readint(c, 0);
|
||||
#ifdef DEBUG
|
||||
printf ("fish_sound_comments_decode: %d comments\n", nb_fields);
|
||||
@ -468,9 +474,10 @@ fish_sound_comments_decode (FishSound * fsound, unsigned char * comments,
|
||||
#ifdef DEBUG
|
||||
printf ("fish_sound_comments_decode: [%d] len %d\n", i, len);
|
||||
#endif
|
||||
if (len<0) return -1;
|
||||
|
||||
c+=4;
|
||||
if (c+len>end) return -1;
|
||||
if (len>end-c) return -1;
|
||||
|
||||
name = c;
|
||||
value = fs_index_len (c, '=', len);
|
||||
@ -479,22 +486,33 @@ fish_sound_comments_decode (FishSound * fsound, unsigned char * comments,
|
||||
value++;
|
||||
|
||||
n = c+len - value;
|
||||
nvalue = fs_strdup_len (value, n);
|
||||
if ((nvalue = fs_strdup_len (value, n)) == NULL)
|
||||
return FISH_SOUND_ERR_OUT_OF_MEMORY;
|
||||
#ifdef DEBUG
|
||||
printf ("fish_sound_comments_decode: %s -> %s (length %d)\n",
|
||||
name, nvalue, n);
|
||||
#endif
|
||||
comment = fs_comment_new (name, nvalue);
|
||||
_fs_comment_add (fsound, comment);
|
||||
if ((comment = fs_comment_new (name, nvalue)) == NULL)
|
||||
return FISH_SOUND_ERR_OUT_OF_MEMORY;
|
||||
|
||||
if (_fs_comment_add (fsound, comment) == NULL)
|
||||
return FISH_SOUND_ERR_OUT_OF_MEMORY;
|
||||
|
||||
fs_free (nvalue);
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
printf ("fish_sound_comments_decode: [%d] %s (no value)\n",
|
||||
i, name, len);
|
||||
#endif
|
||||
nvalue = fs_strdup_len (name, len);
|
||||
comment = fs_comment_new (nvalue, NULL);
|
||||
_fs_comment_add (fsound, comment);
|
||||
if ((nvalue = fs_strdup_len (name, len)) == NULL)
|
||||
return FISH_SOUND_ERR_OUT_OF_MEMORY;
|
||||
|
||||
if ((comment = fs_comment_new (nvalue, NULL)) == NULL)
|
||||
return FISH_SOUND_ERR_OUT_OF_MEMORY;
|
||||
|
||||
if (_fs_comment_add (fsound, comment) == NULL)
|
||||
return FISH_SOUND_ERR_OUT_OF_MEMORY;
|
||||
|
||||
fs_free (nvalue);
|
||||
}
|
||||
|
||||
@ -505,7 +523,28 @@ fish_sound_comments_decode (FishSound * fsound, unsigned char * comments,
|
||||
printf ("fish_sound_comments_decode: done\n");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
return FISH_SOUND_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pre-condition: at least one of accum, delta are non-zero,
|
||||
* ie. don't call accum_length (0, 0);
|
||||
* \retval 0 Failure: integer overflow
|
||||
*/
|
||||
static unsigned long
|
||||
accum_length (unsigned long * accum, unsigned long delta)
|
||||
{
|
||||
/* Pre-condition: don't call accum_length (0, 0) */
|
||||
if (*accum == 0 && delta == 0)
|
||||
return 0;
|
||||
|
||||
/* Check for integer overflow */
|
||||
if (delta > ULONG_MAX - (*accum))
|
||||
return 0;
|
||||
|
||||
*accum += delta;
|
||||
|
||||
return *accum;
|
||||
}
|
||||
|
||||
long
|
||||
@ -514,21 +553,29 @@ fish_sound_comments_encode (FishSound * fsound, unsigned char * buf,
|
||||
{
|
||||
char * c = (char *)buf;
|
||||
const FishSoundComment * comment;
|
||||
int nb_fields = 0, vendor_length, field_length;
|
||||
long actual_length, remaining = length;
|
||||
int nb_fields = 0, vendor_length = 0;
|
||||
unsigned long actual_length = 0, remaining = length, field_length;
|
||||
|
||||
/* Vendor string */
|
||||
vendor_length = strlen (fsound->vendor);
|
||||
actual_length = 4 + vendor_length;
|
||||
if (fsound->vendor)
|
||||
vendor_length = fs_comment_len (fsound->vendor);
|
||||
if (accum_length (&actual_length, 4 + vendor_length) == 0)
|
||||
return 0;
|
||||
|
||||
/* user comment list length */
|
||||
actual_length += 4;
|
||||
if (accum_length (&actual_length, 4) == 0)
|
||||
return 0;
|
||||
|
||||
for (comment = fish_sound_comment_first (fsound); comment;
|
||||
comment = fish_sound_comment_next (fsound, comment)) {
|
||||
actual_length += 4 + strlen (comment->name); /* [size]"name" */
|
||||
if (comment->value)
|
||||
actual_length += 1 + strlen (comment->value); /* "=value" */
|
||||
/* [size]"name" */
|
||||
if (accum_length (&actual_length, 4 + fs_comment_len (comment->name)) == 0)
|
||||
return 0;
|
||||
if (comment->value) {
|
||||
/* "=value" */
|
||||
if (accum_length (&actual_length, 1 + fs_comment_len (comment->value)) == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("fish_sound_comments_encode: %s = %s\n",
|
||||
@ -538,7 +585,11 @@ fish_sound_comments_encode (FishSound * fsound, unsigned char * buf,
|
||||
nb_fields++;
|
||||
}
|
||||
|
||||
actual_length++; /* framing bit */
|
||||
/* framing bit */
|
||||
if (accum_length (&actual_length, 1) == 0)
|
||||
return 0;
|
||||
|
||||
/* NB. actual_length is not modified from here onwards */
|
||||
|
||||
if (buf == NULL) return actual_length;
|
||||
|
||||
@ -547,10 +598,12 @@ fish_sound_comments_encode (FishSound * fsound, unsigned char * buf,
|
||||
writeint (c, 0, vendor_length);
|
||||
c += 4;
|
||||
|
||||
field_length = strlen (fsound->vendor);
|
||||
memcpy (c, fsound->vendor, MIN (field_length, remaining));
|
||||
c += field_length; remaining -= field_length;
|
||||
if (remaining <= 0 ) return actual_length;
|
||||
if (fsound->vendor) {
|
||||
field_length = fs_comment_len (fsound->vendor);
|
||||
memcpy (c, fsound->vendor, MIN (field_length, remaining));
|
||||
c += field_length; remaining -= field_length;
|
||||
if (remaining <= 0) return actual_length;
|
||||
}
|
||||
|
||||
remaining -= 4;
|
||||
if (remaining <= 0) return actual_length;
|
||||
@ -560,16 +613,16 @@ fish_sound_comments_encode (FishSound * fsound, unsigned char * buf,
|
||||
for (comment = fish_sound_comment_first (fsound); comment;
|
||||
comment = fish_sound_comment_next (fsound, comment)) {
|
||||
|
||||
field_length = strlen (comment->name); /* [size]"name" */
|
||||
field_length = fs_comment_len (comment->name); /* [size]"name" */
|
||||
if (comment->value)
|
||||
field_length += 1 + strlen (comment->value); /* "=value" */
|
||||
field_length += 1 + fs_comment_len (comment->value); /* "=value" */
|
||||
|
||||
remaining -= 4;
|
||||
if (remaining <= 0) return actual_length;
|
||||
writeint (c, 0, field_length);
|
||||
c += 4;
|
||||
|
||||
field_length = strlen (comment->name);
|
||||
field_length = fs_comment_len (comment->name);
|
||||
memcpy (c, comment->name, MIN (field_length, remaining));
|
||||
c += field_length; remaining -= field_length;
|
||||
if (remaining <= 0) return actual_length;
|
||||
@ -580,7 +633,7 @@ fish_sound_comments_encode (FishSound * fsound, unsigned char * buf,
|
||||
*c = '=';
|
||||
c++;
|
||||
|
||||
field_length = strlen (comment->value);
|
||||
field_length = fs_comment_len (comment->value);
|
||||
memcpy (c, comment->value, MIN (field_length, remaining));
|
||||
c += field_length; remaining -= field_length;
|
||||
if (remaining <= 0) return actual_length;
|
||||
|
@ -58,7 +58,7 @@ int fish_sound_set_decoded_float (FishSound * fsound,
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (fsound == NULL) return -1;
|
||||
if (fsound == NULL) return FISH_SOUND_ERR_BAD;
|
||||
|
||||
#if FS_DECODE
|
||||
ret = fs_decode_update (fsound, 0);
|
||||
@ -80,7 +80,7 @@ int fish_sound_set_decoded_float_ilv (FishSound * fsound,
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (fsound == NULL) return -1;
|
||||
if (fsound == NULL) return FISH_SOUND_ERR_BAD;
|
||||
|
||||
#if FS_DECODE
|
||||
ret = fs_decode_update (fsound, 1);
|
||||
@ -101,7 +101,7 @@ fish_sound_decode (FishSound * fsound, unsigned char * buf, long bytes)
|
||||
{
|
||||
int format;
|
||||
|
||||
if (fsound == NULL) return -1;
|
||||
if (fsound == NULL) return FISH_SOUND_ERR_BAD;
|
||||
|
||||
#if FS_DECODE
|
||||
if (fsound->info.format == FISH_SOUND_UNKNOWN) {
|
||||
|
@ -141,6 +141,7 @@ fs_flac_write_callback(const FLAC__StreamDecoder *decoder,
|
||||
FishSound* fsound = (FishSound*)client_data;
|
||||
FishSoundFlacInfo* fi = (FishSoundFlacInfo *)fsound->codec_data;
|
||||
int i, j, channels, blocksize, offset;
|
||||
float * ipcm;
|
||||
|
||||
channels = frame->header.channels;
|
||||
blocksize = frame->header.blocksize;
|
||||
@ -158,7 +159,10 @@ fs_flac_write_callback(const FLAC__StreamDecoder *decoder,
|
||||
FishSoundDecoded_FloatIlv dfi;
|
||||
float* retpcm;
|
||||
|
||||
fi->ipcm = realloc(fi->ipcm, sizeof(float) * channels * blocksize);
|
||||
if ((ipcm = realloc(fi->ipcm, sizeof(float) * channels * blocksize)) == NULL)
|
||||
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
|
||||
|
||||
fi->ipcm = ipcm;
|
||||
retpcm = (float*) fi->ipcm;
|
||||
for (i = 0; i < blocksize; i++) {
|
||||
offset = i * channels;
|
||||
@ -173,7 +177,9 @@ fs_flac_write_callback(const FLAC__StreamDecoder *decoder,
|
||||
float *d; /* de-interleave dest */
|
||||
|
||||
for (j = 0; j < channels; j++) {
|
||||
fi->pcm_out[j] = realloc(fi->pcm_out[j], sizeof(float) * blocksize);
|
||||
if ((ipcm = realloc(fi->pcm_out[j], sizeof(float) * blocksize)) == NULL)
|
||||
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
|
||||
fi->pcm_out[j] = ipcm;
|
||||
}
|
||||
for (i = 0; i < blocksize; i++)
|
||||
for (j = 0; j < channels; j++) {
|
||||
@ -231,6 +237,8 @@ static void*
|
||||
fs_flac_decode_header (FishSound * fsound, unsigned char *buf, long bytes)
|
||||
{
|
||||
FishSoundFlacInfo *fi = fsound->codec_data;
|
||||
|
||||
if (bytes < 9) return NULL;
|
||||
if (buf[0] != 0x7f) return NULL;
|
||||
if (strncmp((char *)buf+1, "FLAC", 4) != 0) return NULL;
|
||||
fi->version.major = buf[5];
|
||||
@ -252,6 +260,7 @@ fs_flac_decode_header (FishSound * fsound, unsigned char *buf, long bytes)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined (HAVE_FLAC_1_1_2)
|
||||
FLAC__stream_decoder_set_read_callback(fi->fsd, fs_flac_read_callback);
|
||||
FLAC__stream_decoder_set_write_callback(fi->fsd, fs_flac_write_callback);
|
||||
FLAC__stream_decoder_set_metadata_callback(fi->fsd, fs_flac_meta_callback);
|
||||
@ -260,6 +269,21 @@ fs_flac_decode_header (FishSound * fsound, unsigned char *buf, long bytes)
|
||||
|
||||
if (FLAC__stream_decoder_init(fi->fsd) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA)
|
||||
return NULL;
|
||||
#elif defined (HAVE_FLAC_1_1_3)
|
||||
if (FLAC__stream_decoder_init_stream
|
||||
(fi->fsd,
|
||||
fs_flac_read_callback,
|
||||
NULL, /* seek callback */
|
||||
NULL, /* tell callback */
|
||||
NULL, /* length callback */
|
||||
NULL, /* EOF callback */
|
||||
fs_flac_write_callback,
|
||||
fs_flac_meta_callback,
|
||||
fs_flac_error_callback,
|
||||
fsound
|
||||
) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA)
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
return fi->fsd;
|
||||
}
|
||||
@ -280,12 +304,14 @@ fs_flac_decode (FishSound * fsound, unsigned char * buf, long bytes)
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
fi->buffer = fs_malloc(sizeof(unsigned char)*bytes);
|
||||
if ((fi->buffer = fs_malloc(sizeof(unsigned char)*bytes)) == NULL)
|
||||
return FISH_SOUND_ERR_OUT_OF_MEMORY;
|
||||
|
||||
memcpy(fi->buffer, buf+9, bytes-9);
|
||||
fi->bufferlength = bytes-9;
|
||||
}
|
||||
else if (fi->packetno <= fi->header_packets){
|
||||
unsigned char* tmp = fs_malloc(sizeof(unsigned char)*(fi->bufferlength+bytes));
|
||||
unsigned char* tmp;
|
||||
#ifdef DEBUG
|
||||
printf("fs_flac_decode: handling header (fi->header_packets = %d)\n",
|
||||
fi->header_packets);
|
||||
@ -300,26 +326,44 @@ fs_flac_decode (FishSound * fsound, unsigned char * buf, long bytes)
|
||||
#ifdef DEBUG
|
||||
printf ("fs_flac_decode: got vorbiscomments len %d\n", len);
|
||||
#endif
|
||||
fish_sound_comments_decode (fsound, buf+4, len);
|
||||
if (fish_sound_comments_decode (fsound, buf+4, len) == FISH_SOUND_ERR_OUT_OF_MEMORY) {
|
||||
fi->packetno++;
|
||||
return FISH_SOUND_ERR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
if ((tmp = fs_malloc(sizeof(unsigned char)*(fi->bufferlength+bytes))) == NULL)
|
||||
return FISH_SOUND_ERR_OUT_OF_MEMORY;
|
||||
|
||||
memcpy(tmp, fi->buffer, fi->bufferlength);
|
||||
memcpy(tmp+fi->bufferlength, buf, bytes);
|
||||
fi->bufferlength += bytes;
|
||||
fs_free(fi->buffer);
|
||||
fi->buffer = tmp;
|
||||
if (fi->packetno == fi->header_packets) {
|
||||
FLAC__stream_decoder_process_until_end_of_metadata(fi->fsd);
|
||||
if (FLAC__stream_decoder_process_until_end_of_metadata(fi->fsd) == false) {
|
||||
goto dec_err;
|
||||
}
|
||||
fs_free(fi->buffer);
|
||||
}
|
||||
} else {
|
||||
fi->buffer = buf;
|
||||
fi->bufferlength = bytes;
|
||||
FLAC__stream_decoder_process_single(fi->fsd);
|
||||
if (FLAC__stream_decoder_process_single(fi->fsd) == false) {
|
||||
goto dec_err;
|
||||
}
|
||||
}
|
||||
fi->packetno++;
|
||||
|
||||
return 0;
|
||||
|
||||
dec_err:
|
||||
switch (FLAC__stream_decoder_get_state(fi->fsd)) {
|
||||
case FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR:
|
||||
return FISH_SOUND_ERR_OUT_OF_MEMORY;
|
||||
default:
|
||||
return FISH_SOUND_ERR_GENERIC;
|
||||
}
|
||||
}
|
||||
#else /* !FS_DECODE */
|
||||
|
||||
@ -353,7 +397,9 @@ fs_flac_enc_write_callback(const FLAC__StreamEncoder *encoder,
|
||||
printf("fs_flac_enc_write_callback: generating FLAC header packet: "
|
||||
"%c%c%c%c\n", buffer[0], buffer[1], buffer[2], buffer[3]);
|
||||
#endif
|
||||
fi->buffer = (unsigned char*)malloc(sizeof(unsigned char)*(bytes+9));
|
||||
if ((fi->buffer = (unsigned char*)fs_malloc(sizeof(unsigned char)*(bytes+9))) == NULL)
|
||||
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
|
||||
|
||||
fi->buffer[0] = 0x7f;
|
||||
fi->buffer[1] = 0x46; /* 'F' */
|
||||
fi->buffer[2] = 0x4c; /* 'L' */
|
||||
@ -371,7 +417,11 @@ fs_flac_enc_write_callback(const FLAC__StreamEncoder *encoder,
|
||||
/* Make a temporary copy of the metadata header to pass to the user
|
||||
* callback.
|
||||
*/
|
||||
unsigned char* tmp = (unsigned char*)malloc(sizeof(unsigned char)*(bytes+fi->bufferlength));
|
||||
unsigned char* tmp;
|
||||
|
||||
if ((tmp = (unsigned char*)fs_malloc(sizeof(unsigned char)*(bytes+fi->bufferlength))) == NULL)
|
||||
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
|
||||
|
||||
memcpy (tmp, fi->buffer, fi->bufferlength);
|
||||
memcpy (tmp+fi->bufferlength, buffer, bytes);
|
||||
fs_free(fi->buffer);
|
||||
@ -462,7 +512,8 @@ fs_flac_encode_vcentry (const FishSoundComment * comment)
|
||||
length += value_len + 1;
|
||||
}
|
||||
|
||||
entry = fs_malloc (length);
|
||||
if ((entry = fs_malloc (length)) == NULL)
|
||||
return NULL;
|
||||
|
||||
/* We assume that comment->name, value are NUL terminated, as they were
|
||||
* produced by our own comments.c */
|
||||
@ -482,7 +533,7 @@ static FLAC__StreamMetadata *
|
||||
fs_flac_encode_vorbiscomments (FishSound * fsound)
|
||||
{
|
||||
FishSoundFlacInfo * fi = fsound->codec_data;
|
||||
FLAC__StreamMetadata * metadata;
|
||||
FLAC__StreamMetadata * metadata = NULL;
|
||||
const FishSoundComment * comment;
|
||||
unsigned int i=0, length=0, total_length;
|
||||
FLAC__VCEntry * comments;
|
||||
@ -502,11 +553,13 @@ fs_flac_encode_vorbiscomments (FishSound * fsound)
|
||||
|
||||
if (length == 0) return NULL;
|
||||
|
||||
comments = (FLAC__VCEntry *)fs_malloc (sizeof(FLAC__VCEntry) * length);
|
||||
if ((comments = (FLAC__VCEntry *)fs_malloc (sizeof(FLAC__VCEntry) * length)) == NULL)
|
||||
goto encode_vc_oom;
|
||||
|
||||
for (comment = fish_sound_comment_first (fsound); comment;
|
||||
comment = fish_sound_comment_next (fsound, comment)) {
|
||||
comments[i].entry = fs_flac_encode_vcentry (comment);
|
||||
if ((comments[i].entry = fs_flac_encode_vcentry (comment)) == NULL) {
|
||||
}
|
||||
comments[i].length = strlen((char *)comments[i].entry);
|
||||
|
||||
/* In the generated vorbiscomment data, each entry is preceded by a
|
||||
@ -515,7 +568,9 @@ fs_flac_encode_vorbiscomments (FishSound * fsound)
|
||||
i++;
|
||||
}
|
||||
|
||||
metadata = (FLAC__StreamMetadata *) fs_malloc (sizeof (*metadata));
|
||||
if ((metadata = (FLAC__StreamMetadata *) fs_malloc (sizeof (*metadata))) == NULL)
|
||||
goto encode_vc_oom;
|
||||
|
||||
metadata->type = FLAC__METADATA_TYPE_VORBIS_COMMENT;
|
||||
metadata->is_last = true;
|
||||
metadata->length = total_length;
|
||||
@ -527,6 +582,21 @@ fs_flac_encode_vorbiscomments (FishSound * fsound)
|
||||
fi->enc_vc_metadata = metadata;
|
||||
|
||||
return metadata;
|
||||
|
||||
encode_vc_oom:
|
||||
if (metadata != NULL)
|
||||
fs_free (metadata);
|
||||
|
||||
/* Unwind allocated comment entries */
|
||||
for (i--; i >= 0; i--) {
|
||||
if (comments[i].entry != NULL)
|
||||
fs_free (comments[i].entry);
|
||||
}
|
||||
|
||||
if (comments != NULL)
|
||||
fs_free (comments);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static FishSound *
|
||||
@ -539,26 +609,51 @@ fs_flac_enc_headers (FishSound * fsound)
|
||||
FLAC__stream_encoder_set_channels(fi->fse, fsound->info.channels);
|
||||
FLAC__stream_encoder_set_sample_rate(fi->fse, fsound->info.samplerate);
|
||||
FLAC__stream_encoder_set_bits_per_sample(fi->fse, BITS_PER_SAMPLE);
|
||||
|
||||
#if defined (HAVE_FLAC_1_1_2)
|
||||
FLAC__stream_encoder_set_write_callback(fi->fse, fs_flac_enc_write_callback);
|
||||
FLAC__stream_encoder_set_metadata_callback(fi->fse, fs_flac_enc_meta_callback);
|
||||
FLAC__stream_encoder_set_client_data(fi->fse, fsound);
|
||||
#endif
|
||||
|
||||
metadata = fs_flac_encode_vorbiscomments (fsound);
|
||||
if (metadata != NULL)
|
||||
FLAC__stream_encoder_set_metadata (fi->fse, &metadata, 1);
|
||||
|
||||
/* FLAC__stream_encoder_set_total_samples_estimate(fi->fse, ...);*/
|
||||
|
||||
#if defined (HAVE_FLAC_1_1_2)
|
||||
if (FLAC__stream_encoder_init(fi->fse) != FLAC__STREAM_ENCODER_OK)
|
||||
return NULL;
|
||||
#elif defined (HAVE_FLAC_1_1_3)
|
||||
if (FLAC__stream_encoder_init_stream
|
||||
(fi->fse,
|
||||
fs_flac_enc_write_callback,
|
||||
NULL, /* seek callback */
|
||||
NULL, /* tell callback */
|
||||
fs_flac_enc_meta_callback,
|
||||
fsound
|
||||
) != FLAC__STREAM_ENCODER_OK)
|
||||
return NULL;
|
||||
|
||||
#endif
|
||||
|
||||
return fsound;
|
||||
}
|
||||
|
||||
static long
|
||||
fs_flac_encode_fatal (FishSoundFlacInfo *fi, long err)
|
||||
{
|
||||
FLAC__stream_encoder_delete (fi->fse);
|
||||
fi->fse = NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
static long
|
||||
fs_flac_encode_f (FishSound * fsound, float * pcm[], long frames)
|
||||
{
|
||||
FishSoundFlacInfo *fi = fsound->codec_data;
|
||||
FLAC__int32 *buffer;
|
||||
FLAC__int32 *buffer, *ipcm;
|
||||
float * p, norm = (1 << (BITS_PER_SAMPLE - 1));
|
||||
long i;
|
||||
int j, channels = fsound->info.channels;
|
||||
@ -567,7 +662,10 @@ fs_flac_encode_f (FishSound * fsound, float * pcm[], long frames)
|
||||
printf("fs_flac_encode_f: IN, frames = %ld\n", frames);
|
||||
#endif
|
||||
|
||||
fi->ipcm = realloc(fi->ipcm, sizeof(FLAC__int32) * channels * frames);
|
||||
if ((ipcm = realloc(fi->ipcm, sizeof(FLAC__int32) * channels * frames)) == NULL)
|
||||
return FISH_SOUND_ERR_OUT_OF_MEMORY;
|
||||
|
||||
fi->ipcm = ipcm;
|
||||
buffer = (FLAC__int32*) fi->ipcm;
|
||||
for (i = 0; i < frames; i++) {
|
||||
for (j = 0; j < channels; j++) {
|
||||
@ -581,7 +679,17 @@ fs_flac_encode_f (FishSound * fsound, float * pcm[], long frames)
|
||||
|
||||
/* We could have used FLAC__stream_encoder_process() and a more direct
|
||||
* conversion loop above, rather than converting and interleaving. */
|
||||
FLAC__stream_encoder_process_interleaved(fi->fse, buffer, frames);
|
||||
if (FLAC__stream_encoder_process_interleaved(fi->fse, buffer, frames) == false) {
|
||||
switch (FLAC__stream_encoder_get_state (fi->fse)) {
|
||||
case FLAC__STREAM_ENCODER_OK:
|
||||
case FLAC__STREAM_ENCODER_UNINITIALIZED:
|
||||
break;
|
||||
case FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR:
|
||||
return fs_flac_encode_fatal (fi, FISH_SOUND_ERR_OUT_OF_MEMORY);
|
||||
default:
|
||||
return fs_flac_encode_fatal (fi, FISH_SOUND_ERR_GENERIC);
|
||||
}
|
||||
}
|
||||
|
||||
fi->packetno++;
|
||||
|
||||
@ -592,7 +700,7 @@ static long
|
||||
fs_flac_encode_f_ilv (FishSound * fsound, float ** pcm, long frames)
|
||||
{
|
||||
FishSoundFlacInfo *fi = fsound->codec_data;
|
||||
FLAC__int32 *buffer;
|
||||
FLAC__int32 *buffer, *ipcm;
|
||||
float * p = (float*)pcm, norm = (1 << (BITS_PER_SAMPLE - 1));
|
||||
long i, length = frames * fsound->info.channels;
|
||||
|
||||
@ -600,7 +708,10 @@ fs_flac_encode_f_ilv (FishSound * fsound, float ** pcm, long frames)
|
||||
printf("fs_flac_encode_f_ilv: IN, frames = %ld\n", frames);
|
||||
#endif
|
||||
|
||||
fi->ipcm = realloc(fi->ipcm, sizeof(FLAC__int32)*fsound->info.channels*frames);
|
||||
if ((ipcm = realloc(fi->ipcm, sizeof(FLAC__int32)*fsound->info.channels*frames)) == NULL)
|
||||
return FISH_SOUND_ERR_OUT_OF_MEMORY;
|
||||
|
||||
fi->ipcm = ipcm;
|
||||
buffer = (FLAC__int32*) fi->ipcm;
|
||||
for (i=0; i<length; i++)
|
||||
buffer[i] = p[i] * norm;
|
||||
@ -608,7 +719,17 @@ fs_flac_encode_f_ilv (FishSound * fsound, float ** pcm, long frames)
|
||||
if (fi->packetno == 0)
|
||||
fs_flac_enc_headers (fsound);
|
||||
|
||||
FLAC__stream_encoder_process_interleaved(fi->fse, buffer, frames);
|
||||
if (FLAC__stream_encoder_process_interleaved(fi->fse, buffer, frames) == false) {
|
||||
switch (FLAC__stream_encoder_get_state (fi->fse)) {
|
||||
case FLAC__STREAM_ENCODER_OK:
|
||||
case FLAC__STREAM_ENCODER_UNINITIALIZED:
|
||||
break;
|
||||
case FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR:
|
||||
return fs_flac_encode_fatal (fi, FISH_SOUND_ERR_OUT_OF_MEMORY);
|
||||
default:
|
||||
return fs_flac_encode_fatal (fi, FISH_SOUND_ERR_GENERIC);
|
||||
}
|
||||
}
|
||||
|
||||
fi->packetno++;
|
||||
|
||||
@ -738,6 +859,7 @@ fish_sound_flac_codec (void)
|
||||
FishSoundCodec * codec;
|
||||
|
||||
codec = (FishSoundCodec *) fs_malloc (sizeof (FishSoundCodec));
|
||||
if (codec == NULL) return NULL;
|
||||
|
||||
codec->format.format = FISH_SOUND_FLAC;
|
||||
codec->format.name = "Flac (Xiph.Org)";
|
||||
|
@ -36,6 +36,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "private.h"
|
||||
@ -132,59 +136,46 @@ process_header(unsigned char * buf, long bytes, int enh_enabled,
|
||||
|
||||
header = speex_packet_to_header((char*)buf, (int)bytes);
|
||||
if (!header) {
|
||||
/*info_dialog_new ("Speex error", NULL, "Speex: cannot read header");*/
|
||||
/* cannot read header */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (header->mode >= SPEEX_NB_MODES || header->mode < 0) {
|
||||
/*
|
||||
info_dialog_new ("Speex error", NULL,
|
||||
"Mode number %d does not (any longer) exist in this version\n",
|
||||
header->mode);
|
||||
*/
|
||||
/* Mode number does not (any longer) exist in this version */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
modeID = header->mode;
|
||||
if (forceMode!=-1)
|
||||
modeID = forceMode;
|
||||
|
||||
#if HAVE_SPEEX_LIB_GET_MODE
|
||||
mode = (SpeexMode *) speex_lib_get_mode (modeID);
|
||||
#else
|
||||
/* speex_mode_list[] is declared const in speex 1.1.x, hence the cast */
|
||||
mode = (SpeexMode *)speex_mode_list[modeID];
|
||||
#endif
|
||||
|
||||
if (header->speex_version_id > 1) {
|
||||
/*
|
||||
info_dialog_new ("Speex error", NULL,
|
||||
"This file was encoded with Speex bit-stream version %d, "
|
||||
"which I don't know how to decode\n",
|
||||
header->speex_version_id);
|
||||
*/
|
||||
/* Unknown bitstream version */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (mode->bitstream_version < header->mode_bitstream_version) {
|
||||
/*
|
||||
info_dialog_new ("Speex error", NULL,
|
||||
"The file was encoded with a newer version of Speex. "
|
||||
"You need to upgrade in order to play it.\n");
|
||||
*/
|
||||
/* The file was encoded with a newer version of Speex,
|
||||
* need to upgrade in order to play it */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (mode->bitstream_version > header->mode_bitstream_version) {
|
||||
/*
|
||||
info_dialog_new ("Speex error", NULL,
|
||||
"The file was encoded with an older version of Speex. "
|
||||
"You would need to downgrade the version in order to play it.\n");
|
||||
*/
|
||||
/* The file was encoded with an older version of Speex.
|
||||
* You would need to downgrade the version in order to play it */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
st = speex_decoder_init(mode);
|
||||
if (!st) {
|
||||
/*
|
||||
info_dialog_new ("Speex error", NULL,
|
||||
"Decoder initialization failed.\n");
|
||||
*/
|
||||
/* Decoder initialization failed */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -292,7 +283,8 @@ fs_speex_decode (FishSound * fsound, unsigned char * buf, long bytes)
|
||||
&fss->extra_headers);
|
||||
|
||||
if (fss->st == NULL) {
|
||||
/* XXX: error */
|
||||
/* TODO: Return more specific error identifiers for invalid header fields */
|
||||
return FISH_SOUND_ERR_GENERIC;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -302,20 +294,50 @@ fs_speex_decode (FishSound * fsound, unsigned char * buf, long bytes)
|
||||
fsound->info.samplerate = rate;
|
||||
fsound->info.channels = channels;
|
||||
|
||||
/* Sanity check the channels value, as we will use it to determine buffer
|
||||
sizes below.
|
||||
*/
|
||||
if (channels < 1 || channels > 2)
|
||||
return FISH_SOUND_ERR_GENERIC;
|
||||
|
||||
#if HAVE_UINTPTR_T
|
||||
/* Sanity check: frame_size is not so large that the buffer size calculations
|
||||
* would wrap. In reality, frame_size is set by libspeex according to the
|
||||
* mode index specified in the file header, and is usually equal to 320.
|
||||
*/
|
||||
if (fss->frame_size > UINTPTR_MAX / (sizeof(float) * channels))
|
||||
return FISH_SOUND_ERR_GENERIC;
|
||||
#endif
|
||||
|
||||
fss->ipcm = fs_malloc (sizeof (float) * fss->frame_size * channels);
|
||||
if (fss->ipcm == NULL) {
|
||||
return FISH_SOUND_ERR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if (channels == 1) {
|
||||
fss->pcm[0] = fss->ipcm;
|
||||
} else if (channels == 2) {
|
||||
fss->pcm[0] = fs_malloc (sizeof (float) * fss->frame_size);
|
||||
if (fss->pcm[0] == NULL) {
|
||||
fs_free (fss->ipcm);
|
||||
return FISH_SOUND_ERR_OUT_OF_MEMORY;
|
||||
}
|
||||
fss->pcm[1] = fs_malloc (sizeof (float) * fss->frame_size);
|
||||
if (fss->pcm[1] == NULL) {
|
||||
fs_free (fss->pcm[0]);
|
||||
fs_free (fss->ipcm);
|
||||
return FISH_SOUND_ERR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
if (fss->nframes == 0) fss->nframes = 1;
|
||||
|
||||
} else if (fss->packetno == 1) {
|
||||
/* Comments */
|
||||
fish_sound_comments_decode (fsound, buf, bytes);
|
||||
if (fish_sound_comments_decode (fsound, buf, bytes) == FISH_SOUND_ERR_OUT_OF_MEMORY) {
|
||||
fss->packetno++;
|
||||
return FISH_SOUND_ERR_OUT_OF_MEMORY;
|
||||
}
|
||||
} else if (fss->packetno <= 1+fss->extra_headers) {
|
||||
/* Unknown extra headers */
|
||||
} else {
|
||||
@ -363,15 +385,21 @@ static FishSound *
|
||||
fs_speex_enc_headers (FishSound * fsound)
|
||||
{
|
||||
FishSoundSpeexInfo * fss = (FishSoundSpeexInfo *)fsound->codec_data;
|
||||
int modeID;
|
||||
SpeexMode * mode = NULL;
|
||||
SpeexHeader header;
|
||||
unsigned char * buf;
|
||||
int bytes;
|
||||
unsigned char * header_buf = NULL, * comments_buf = NULL;
|
||||
int header_bytes, comments_bytes;
|
||||
size_t buflen;
|
||||
|
||||
/* XXX: set wb, nb, uwb modes */
|
||||
/* These modes are declared const in speex 1.1.x, hence the explicit cast */
|
||||
mode = (SpeexMode *)&speex_wb_mode;
|
||||
modeID = 1;
|
||||
|
||||
#if HAVE_SPEEX_LIB_GET_MODE
|
||||
mode = (SpeexMode *) speex_lib_get_mode (modeID);
|
||||
#else
|
||||
/* speex_mode_list[] is declared const in speex 1.1.x, hence the cast */
|
||||
mode = (SpeexMode *)speex_mode_list[modeID];
|
||||
#endif
|
||||
|
||||
speex_init_header (&header, fsound->info.samplerate, 1, mode);
|
||||
header.frames_per_packet = fss->nframes; /* XXX: frames per packet */
|
||||
@ -381,24 +409,26 @@ fs_speex_enc_headers (FishSound * fsound)
|
||||
fss->st = speex_encoder_init (mode);
|
||||
|
||||
if (fsound->callback.encoded) {
|
||||
FishSoundEncoded encoded = (FishSoundEncoded)fsound->callback.encoded;
|
||||
char vendor_string[128];
|
||||
|
||||
/* header */
|
||||
buf = (unsigned char *) speex_header_to_packet (&header, &bytes);
|
||||
encoded (fsound, buf, (long)bytes, fsound->user_data);
|
||||
fss->packetno++;
|
||||
fs_free (buf);
|
||||
/* Allocate and create header */
|
||||
header_buf = (unsigned char *) speex_header_to_packet (&header, &header_bytes);
|
||||
if (header_buf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* comments */
|
||||
/* Allocate and create comments */
|
||||
snprintf (vendor_string, 128, VENDOR_FORMAT, header.speex_version);
|
||||
fish_sound_comment_set_vendor (fsound, vendor_string);
|
||||
bytes = fish_sound_comments_encode (fsound, NULL, 0);
|
||||
buf = fs_malloc (bytes);
|
||||
bytes = fish_sound_comments_encode (fsound, buf, bytes);
|
||||
encoded (fsound, buf, (long)bytes, fsound->user_data);
|
||||
fss->packetno++;
|
||||
fs_free (buf);
|
||||
if (fish_sound_comment_set_vendor (fsound, vendor_string) == FISH_SOUND_ERR_OUT_OF_MEMORY) {
|
||||
fs_free (header_buf);
|
||||
return NULL;
|
||||
}
|
||||
comments_bytes = fish_sound_comments_encode (fsound, NULL, 0);
|
||||
comments_buf = fs_malloc (comments_bytes);
|
||||
if (comments_buf == NULL) {
|
||||
fs_free (header_buf);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
speex_encoder_ctl (fss->st, SPEEX_SET_SAMPLING_RATE,
|
||||
@ -410,12 +440,33 @@ fs_speex_enc_headers (FishSound * fsound)
|
||||
printf ("got frame size %d\n", fss->frame_size);
|
||||
#endif
|
||||
|
||||
/* XXX: blah blah blah ... set VBR etc. */
|
||||
/* XXX: set VBR etc. */
|
||||
|
||||
buflen = fss->frame_size * fsound->info.channels * sizeof (float);
|
||||
fss->ipcm = fs_malloc (buflen);
|
||||
if (fss->ipcm == NULL) {
|
||||
if (comments_buf) fs_free (comments_buf);
|
||||
if (header_buf) fs_free (header_buf);
|
||||
return NULL;
|
||||
}
|
||||
memset (fss->ipcm, 0, buflen);
|
||||
|
||||
/* Allocations succeeded, actually call encoded callback for headers */
|
||||
if (fsound->callback.encoded) {
|
||||
FishSoundEncoded encoded = (FishSoundEncoded)fsound->callback.encoded;
|
||||
|
||||
/* header */
|
||||
encoded (fsound, header_buf, (long)header_bytes, fsound->user_data);
|
||||
fss->packetno++;
|
||||
fs_free (header_buf);
|
||||
|
||||
/* comments */
|
||||
comments_bytes = fish_sound_comments_encode (fsound, comments_buf, comments_bytes);
|
||||
encoded (fsound, comments_buf, (long)comments_bytes, fsound->user_data);
|
||||
fss->packetno++;
|
||||
fs_free (comments_buf);
|
||||
}
|
||||
|
||||
return fsound;
|
||||
}
|
||||
|
||||
@ -593,10 +644,13 @@ fs_speex_update (FishSound * fsound, int interleave)
|
||||
{
|
||||
FishSoundSpeexInfo * fss = (FishSoundSpeexInfo *)fsound->codec_data;
|
||||
size_t pcm_size = sizeof (float);
|
||||
float *ipcm_new, *pcm0, *pcm1;
|
||||
|
||||
fss->ipcm = (float *)
|
||||
fs_realloc (fss->ipcm,
|
||||
pcm_size * fss->frame_size * fsound->info.channels);
|
||||
ipcm_new = (float *)fs_realloc (fss->ipcm,
|
||||
pcm_size * fss->frame_size * fsound->info.channels);
|
||||
if (ipcm_new == NULL) return FISH_SOUND_ERR_OUT_OF_MEMORY;
|
||||
|
||||
fss->ipcm = ipcm_new;
|
||||
|
||||
if (interleave) {
|
||||
/* if transitioning from non-interleave to interleave,
|
||||
@ -611,8 +665,28 @@ fs_speex_update (FishSound * fsound, int interleave)
|
||||
if (fsound->info.channels == 1) {
|
||||
fss->pcm[0] = (float *) fss->ipcm;
|
||||
} else if (fsound->info.channels == 2) {
|
||||
fss->pcm[0] = fs_realloc (fss->pcm[0], pcm_size * fss->frame_size);
|
||||
fss->pcm[1] = fs_realloc (fss->pcm[1], pcm_size * fss->frame_size);
|
||||
#if HAVE_UINTPTR_T
|
||||
/* Sanity check: frame_size is not so large that the buffer size calculations
|
||||
* would wrap. In reality, frame_size is set by libspeex according to the
|
||||
* mode index specified in the file header, and is usually equal to 320.
|
||||
*/
|
||||
if (fss->frame_size > UINTPTR_MAX / pcm_size)
|
||||
return FISH_SOUND_ERR_GENERIC;
|
||||
#endif
|
||||
|
||||
pcm0 = fs_realloc (fss->pcm[0], pcm_size * fss->frame_size);
|
||||
if (pcm0 == NULL) {
|
||||
return FISH_SOUND_ERR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pcm1 = fs_realloc (fss->pcm[1], pcm_size * fss->frame_size);
|
||||
if (pcm1 == NULL) {
|
||||
fs_free (pcm0);
|
||||
return FISH_SOUND_ERR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
fss->pcm[0] = pcm0;
|
||||
fss->pcm[1] = pcm1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -694,6 +768,7 @@ fish_sound_speex_codec (void)
|
||||
FishSoundCodec * codec;
|
||||
|
||||
codec = (FishSoundCodec *) fs_malloc (sizeof (FishSoundCodec));
|
||||
if (codec == NULL) return NULL;
|
||||
|
||||
codec->format.format = FISH_SOUND_SPEEX;
|
||||
codec->format.name = "Speex (Xiph.Org)";
|
||||
|
@ -115,6 +115,7 @@ fs_vorbis_decode (FishSound * fsound, unsigned char * buf, long bytes)
|
||||
FishSoundVorbisInfo * fsv = (FishSoundVorbisInfo *)fsound->codec_data;
|
||||
ogg_packet op;
|
||||
long samples;
|
||||
float * pcm_new;
|
||||
int ret;
|
||||
|
||||
/* Make an ogg_packet structure to pass the data to libvorbis */
|
||||
@ -142,7 +143,10 @@ fs_vorbis_decode (FishSound * fsound, unsigned char * buf, long bytes)
|
||||
* start of vorbiscomment packet. */
|
||||
if (fsv->packetno == 1 && bytes > 7 && buf[0] == 0x03 &&
|
||||
!strncmp ((char *)&buf[1], "vorbis", 6)) {
|
||||
fish_sound_comments_decode (fsound, buf+7, bytes-7);
|
||||
if (fish_sound_comments_decode (fsound, buf+7, bytes-7) == FISH_SOUND_ERR_OUT_OF_MEMORY) {
|
||||
fsv->packetno++;
|
||||
return FISH_SOUND_ERR_OUT_OF_MEMORY;
|
||||
}
|
||||
} else if (fsv->packetno == 2) {
|
||||
vorbis_synthesis_init (&fsv->vd, &fsv->vi);
|
||||
vorbis_block_init (&fsv->vd, &fsv->vb);
|
||||
@ -162,9 +166,15 @@ fs_vorbis_decode (FishSound * fsound, unsigned char * buf, long bytes)
|
||||
|
||||
if (fsound->interleave) {
|
||||
if (samples > fsv->max_pcm) {
|
||||
fsv->ipcm = realloc (fsv->ipcm, sizeof(float) * samples *
|
||||
fsound->info.channels);
|
||||
fsv->max_pcm = samples;
|
||||
pcm_new = realloc (fsv->ipcm, sizeof(float) * samples *
|
||||
fsound->info.channels);
|
||||
if (pcm_new == NULL) {
|
||||
/* Allocation failure; just truncate here, fail gracefully elsewhere */
|
||||
samples = fsv->max_pcm;
|
||||
} else {
|
||||
fsv->ipcm = pcm_new;
|
||||
fsv->max_pcm = samples;
|
||||
}
|
||||
}
|
||||
_fs_interleave (fsv->pcm, (float **)fsv->ipcm, samples,
|
||||
fsound->info.channels, 1.0);
|
||||
@ -204,12 +214,14 @@ fs_vorbis_enc_headers (FishSound * fsound)
|
||||
ogg_packet header_comm;
|
||||
ogg_packet header_code;
|
||||
|
||||
/* Vorbis streams begin with three headers; the initial header (with
|
||||
most of the codec setup parameters) which is mandated by the Ogg
|
||||
bitstream spec. The second header holds any comment fields. The
|
||||
third header holds the bitstream codebook. We merely need to
|
||||
make the headers, then pass them to libvorbis one at a time;
|
||||
libvorbis handles the additional Ogg bitstream constraints */
|
||||
/* Vorbis streams begin with three headers:
|
||||
* 1. The initial header (with most of the codec setup parameters),
|
||||
* which is mandated by the Ogg bitstream spec,
|
||||
* 2. The second header which holds any comment fields,
|
||||
* 3. The third header which contains the bitstream codebook.
|
||||
* We merely need to make the headers, then pass them to libvorbis one at
|
||||
* a time; libvorbis handles the additional Ogg bitstream constraints.
|
||||
*/
|
||||
|
||||
/* Update the comments */
|
||||
for (comment = fish_sound_comment_first (fsound); comment;
|
||||
@ -333,7 +345,6 @@ fs_vorbis_encode_f (FishSound * fsound, float * pcm[], long frames)
|
||||
float ** vpcm;
|
||||
long len, remaining = frames;
|
||||
int i;
|
||||
float ** ppcm = alloca (sizeof (float *) * fsound->info.channels);
|
||||
|
||||
if (fsv->packetno == 0) {
|
||||
fs_vorbis_enc_headers (fsound);
|
||||
@ -344,10 +355,6 @@ fs_vorbis_encode_f (FishSound * fsound, float * pcm[], long frames)
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < fsound->info.channels; i++) {
|
||||
ppcm[i] = pcm[i];
|
||||
}
|
||||
|
||||
while (remaining > 0) {
|
||||
len = MIN (1024, remaining);
|
||||
|
||||
@ -359,7 +366,7 @@ fs_vorbis_encode_f (FishSound * fsound, float * pcm[], long frames)
|
||||
vpcm = vorbis_analysis_buffer (&fsv->vd, 1024);
|
||||
|
||||
for (i = 0; i < fsound->info.channels; i++) {
|
||||
memcpy (vpcm[i], ppcm[i], sizeof (float) * len);
|
||||
memcpy (vpcm[i], pcm[i], sizeof (float) * len);
|
||||
}
|
||||
|
||||
fs_vorbis_encode_write (fsound, len);
|
||||
@ -428,7 +435,7 @@ fs_vorbis_init (FishSound * fsound)
|
||||
fsv->finished = 0;
|
||||
vorbis_info_init (&fsv->vi);
|
||||
vorbis_comment_init (&fsv->vc);
|
||||
vorbis_dsp_init (&fsv->vd);
|
||||
memset(&fsv->vd, 0, sizeof(fsv->vd));
|
||||
vorbis_block_init (&fsv->vd, &fsv->vb);
|
||||
fsv->pcm = NULL;
|
||||
fsv->ipcm = NULL;
|
||||
@ -475,6 +482,7 @@ fish_sound_vorbis_codec (void)
|
||||
FishSoundCodec * codec;
|
||||
|
||||
codec = (FishSoundCodec *) fs_malloc (sizeof (FishSoundCodec));
|
||||
if (codec == NULL) return NULL;
|
||||
|
||||
codec->format.format = FISH_SOUND_VORBIS;
|
||||
codec->format.name = "Vorbis (Xiph.Org)";
|
||||
|
@ -58,6 +58,7 @@ fs_vector_new (FishSoundCmpFunc cmp)
|
||||
FishSoundVector * vector;
|
||||
|
||||
vector = fs_malloc (sizeof (FishSoundVector));
|
||||
if (vector == NULL) return NULL;
|
||||
|
||||
vector->max_elements = 0;
|
||||
vector->nr_elements = 0;
|
||||
@ -176,6 +177,8 @@ fs_vector_grow (FishSoundVector * vector)
|
||||
void *
|
||||
fs_vector_insert (FishSoundVector * vector, void * data)
|
||||
{
|
||||
if (vector == NULL) return NULL;
|
||||
|
||||
if (fs_vector_grow (vector) == NULL)
|
||||
return NULL;
|
||||
|
||||
|
@ -38,5 +38,4 @@ cp $1/src/libfishsound/fs_vector.h ./src/libfishsound/fs_vector.h
|
||||
cp $1/src/libfishsound/fs_vector.c ./src/libfishsound/fs_vector.c
|
||||
cp $1/src/libfishsound/convert.h ./src/libfishsound/convert.h
|
||||
cp $1/AUTHORS ./AUTHORS
|
||||
patch -p4 <endian.patch
|
||||
patch -p3 <bug481601.patch
|
||||
patch -p3 <endian.patch
|
||||
|
@ -104,36 +104,41 @@ and mux and demux examples can be read online at:
|
||||
|
||||
http://www.annodex.net/software/liboggz/html/
|
||||
|
||||
Tools
|
||||
-----
|
||||
oggz tool
|
||||
---------
|
||||
|
||||
The Oggz source tarball also contains the following command-line tools,
|
||||
which are useful for debugging and testing Ogg bitstreams:
|
||||
Usage: oggz <subcommand> [options] filename ...
|
||||
|
||||
* oggz-chop: Extract the part of an Ogg file between given start
|
||||
and/or end times.
|
||||
oggz is a commandline tool for manipulating Ogg files. It supports
|
||||
multiplexed files conformant with RFC3533. Oggz can parse headers for
|
||||
CELT, CMML, FLAC, Kate, PCM, Speex, Theora and Vorbis, and can read and write
|
||||
Ogg Skeleton logical bitstreams.
|
||||
|
||||
* oggz-comment: List or edit comments in an Ogg file.
|
||||
Commands:
|
||||
help Display help for a specific subcommand (eg. "oggz help chop")
|
||||
|
||||
* oggz-diff: Hexdump the packets of two Ogg files and output
|
||||
differences.
|
||||
Reporting:
|
||||
diff Hexdump the packets of two Ogg files and output differences.
|
||||
dump Hexdump packets of an Ogg file, or revert an Ogg file from
|
||||
such a hexdump.
|
||||
info Display information about one or more Ogg files and their
|
||||
bitstreams.
|
||||
scan Scan an Ogg file and output characteristic landmarks.
|
||||
validate Validate the Ogg framing of one or more files.
|
||||
|
||||
* oggz-dump: Hexdump packets of an Ogg file, or revert an Ogg file
|
||||
from such a hexdump.
|
||||
Extraction:
|
||||
rip Extract one or more logical bitstreams from an Ogg file.
|
||||
|
||||
* oggz-info: Display information about one or more Ogg files and
|
||||
their bitstreams.
|
||||
Editing:
|
||||
chop Extract the part of an Ogg file between given start and/or
|
||||
end times.
|
||||
comment List or edit comments in an Ogg file.
|
||||
merge Merge Ogg files together, interleaving pages in order of
|
||||
presentation time.
|
||||
sort Sort the pages of an Ogg file in order of presentation time.
|
||||
|
||||
* oggz-merge: Merge Ogg files together, interleaving pages in order
|
||||
of presentation time.
|
||||
|
||||
* oggz-rip: Extract one or more logical bitstreams from an Ogg file.
|
||||
|
||||
* oggz-scan: Scan an Ogg file and output characteristic landmarks.
|
||||
|
||||
* oggz-sort: Sort the pages of an Ogg file in order of presentation time.
|
||||
|
||||
* oggz-validate: Validate the Ogg framing of one or more files.
|
||||
Miscellaneous:
|
||||
known-codecs List codecs known by this version of oggz
|
||||
|
||||
The script bash-completion/oggz enables completion of tool options and codec
|
||||
names when using the bash shell. Source it from your .profile, or install it
|
||||
|
@ -1,15 +1,12 @@
|
||||
The source from this directory was copied from the liboggz svn
|
||||
The source from this directory was copied from the liboggz git
|
||||
source repository using the update.sh script. The only changes made
|
||||
were those applied by update.sh, which applies patches described
|
||||
below, and the addition/upate of Makefile.in files for the
|
||||
Mozilla build system.
|
||||
|
||||
The svn revision number used was r3867.
|
||||
The git commit id used was ef3b0e from git://git.xiph.org/liboggz.git
|
||||
|
||||
The wince.patch addresses the lack of posix file IO support on windows ce,
|
||||
see bug 461844 for details.
|
||||
|
||||
endian.patch is applied to fix bug 452698.
|
||||
|
||||
oggz-seek-crash-fix.patch is applied to fix the crash reported in
|
||||
bug 475441 comment #44.
|
||||
|
@ -135,5 +135,4 @@
|
||||
/* Define for MSVC as <stdint.h> is unavailable there */
|
||||
typedef unsigned char uint8_t;
|
||||
|
||||
#define inline __inline // MSVC
|
||||
#undef DEBUG
|
||||
#define inline __inline // MSVC#undef DEBUG
|
||||
|
@ -158,6 +158,7 @@ int oggz_set_read_page (OGGZ * oggz, long serialno,
|
||||
* returning OGGZ_STOP_OK
|
||||
* \retval OGGZ_ERR_STOP_ERR Reading was stopped by a user callback
|
||||
* returning OGGZ_STOP_ERR
|
||||
* \retval OGGZ_ERR_HOLE_IN_DATA Hole (sequence number gap) detected in input data
|
||||
* \retval OGGZ_ERR_OUT_OF_MEMORY Out of memory
|
||||
*/
|
||||
long oggz_read (OGGZ * oggz, long n);
|
||||
@ -174,6 +175,8 @@ long oggz_read (OGGZ * oggz, long n);
|
||||
* returning OGGZ_STOP_OK
|
||||
* \retval OGGZ_ERR_STOP_ERR Reading was stopped by a user callback
|
||||
* returning OGGZ_STOP_ERR
|
||||
* \retval OGGZ_ERR_HOLE_IN_DATA Hole (sequence number gap) detected in input data
|
||||
* \retval OGGZ_ERR_OUT_OF_MEMORY Out of memory
|
||||
*/
|
||||
long oggz_read_input (OGGZ * oggz, unsigned char * buf, long n);
|
||||
|
||||
|
@ -1,22 +0,0 @@
|
||||
diff --git a/media/liboggz/src/liboggz/oggz_seek.c b/media/liboggz/src/liboggz/oggz_seek.c
|
||||
--- a/media/liboggz/src/liboggz/oggz_seek.c
|
||||
+++ b/media/liboggz/src/liboggz/oggz_seek.c
|
||||
@@ -717,17 +717,17 @@ oggz_seek_set (OGGZ * oggz, ogg_int64_t
|
||||
&serialno);
|
||||
unit_end = oggz_get_unit (oggz, serialno, granule_at);
|
||||
#ifdef DEBUG
|
||||
printf ("oggz_seek_set: [C] offset_next @%" PRI_OGGZ_OFF_T "d, g%lld, (s%ld)\n",
|
||||
offset_next, granule_at, serialno);
|
||||
printf ("oggz_seek_set: [c] u%lld\n",
|
||||
oggz_get_unit (oggz, serialno, granule_at));
|
||||
#endif
|
||||
- } else {
|
||||
+ } else if (offset_next >= 0) {
|
||||
serialno = ogg_page_serialno (og);
|
||||
granule_at = ogg_page_granulepos (og);
|
||||
}
|
||||
|
||||
if (offset_next < 0) {
|
||||
goto notfound;
|
||||
}
|
||||
|
@ -638,7 +638,7 @@ oggz_map_return_value_to_error (int cb_ret)
|
||||
case OGGZ_STOP_ERR:
|
||||
return OGGZ_ERR_STOP_ERR;
|
||||
default:
|
||||
return OGGZ_ERR_STOP_ERR;
|
||||
return cb_ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -375,11 +375,6 @@ auto_dirac (OGGZ * oggz, long serialno, unsigned char * data, long length, void
|
||||
|
||||
dirac_parse_info(info, data, length);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("Got dirac fps %d/%d granule_shift %d\n",
|
||||
fps_numerator, fps_denominator, granule_shift);
|
||||
#endif
|
||||
|
||||
/* the granulerate is twice the frame rate (in order to handle interlace) */
|
||||
oggz_set_granulerate (oggz, serialno,
|
||||
2 * (ogg_int64_t)info->fps_numerator,
|
||||
@ -558,8 +553,7 @@ auto_calc_celt (ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
|
||||
* are marked by a set 2MSB in the first byte. Intra packets (keyframes)
|
||||
* are any that are left over ;-)
|
||||
*
|
||||
* (see http://www.theora.org/doc/Theora_I_spec.pdf for the theora
|
||||
* specification)
|
||||
* (see http://theora.org/doc/Theora.pdf for the theora specification)
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
@ -695,6 +689,7 @@ static ogg_int64_t
|
||||
auto_calc_vorbis(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
|
||||
|
||||
auto_calc_vorbis_info_t *info;
|
||||
int ii;
|
||||
|
||||
if (stream->calculate_data == NULL) {
|
||||
/*
|
||||
@ -830,19 +825,32 @@ auto_calc_vorbis(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
|
||||
|
||||
}
|
||||
|
||||
if (offset > 4) {
|
||||
size_check = (current_pos[0] >> (offset - 5)) & 0x3F;
|
||||
} else {
|
||||
/* mask part of byte from current_pos */
|
||||
size_check = (current_pos[0] & ((1 << (offset + 1)) - 1));
|
||||
/* shift to appropriate position */
|
||||
size_check <<= (5 - offset);
|
||||
/* or in part of byte from current_pos - 1 */
|
||||
size_check |= (current_pos[-1] & ~((1 << (offset + 3)) - 1)) >>
|
||||
(offset + 3);
|
||||
/* Give ourselves a chance to recover if we went back too far by using
|
||||
* the size check. */
|
||||
for (ii=0; ii < 2; ii++) {
|
||||
if (offset > 4) {
|
||||
size_check = (current_pos[0] >> (offset - 5)) & 0x3F;
|
||||
} else {
|
||||
/* mask part of byte from current_pos */
|
||||
size_check = (current_pos[0] & ((1 << (offset + 1)) - 1));
|
||||
/* shift to appropriate position */
|
||||
size_check <<= (5 - offset);
|
||||
/* or in part of byte from current_pos - 1 */
|
||||
size_check |= (current_pos[-1] & ~((1 << (offset + 3)) - 1)) >>
|
||||
(offset + 3);
|
||||
}
|
||||
|
||||
size_check += 1;
|
||||
if (size_check == size) {
|
||||
break;
|
||||
}
|
||||
offset = (offset + 1) % 8;
|
||||
if (offset == 0)
|
||||
current_pos += 1;
|
||||
current_pos += 5;
|
||||
size -= 1;
|
||||
}
|
||||
|
||||
size_check += 1;
|
||||
#ifdef DEBUG
|
||||
if (size_check != size)
|
||||
{
|
||||
|
@ -57,9 +57,12 @@
|
||||
#define strcasecmp _stricmp
|
||||
#endif
|
||||
|
||||
/* Ensure comment vector length can be expressed in 32 bits
|
||||
* including space for the trailing NUL */
|
||||
#define MAX_COMMENT_LENGTH 0xFFFFFFFE
|
||||
#define oggz_comment_clamp(c) MIN((c),MAX_COMMENT_LENGTH)
|
||||
|
||||
/* Ensure comment vector length can be expressed in 32 bits */
|
||||
static unsigned long
|
||||
static size_t
|
||||
oggz_comment_len (const char * s)
|
||||
{
|
||||
size_t len;
|
||||
@ -67,7 +70,7 @@ oggz_comment_len (const char * s)
|
||||
if (s == NULL) return 0;
|
||||
|
||||
len = strlen (s);
|
||||
return (unsigned long) MIN(len, 0xFFFFFFFF);
|
||||
return oggz_comment_clamp(len);
|
||||
}
|
||||
|
||||
static char *
|
||||
@ -82,11 +85,12 @@ oggz_strdup (const char * s)
|
||||
}
|
||||
|
||||
static char *
|
||||
oggz_strdup_len (const char * s, int len)
|
||||
oggz_strdup_len (const char * s, size_t len)
|
||||
{
|
||||
char * ret;
|
||||
if (s == NULL) return NULL;
|
||||
if (len == 0) return NULL;
|
||||
len = oggz_comment_clamp(len);
|
||||
ret = oggz_malloc (len + 1);
|
||||
if (!ret) return NULL;
|
||||
if (strncpy (ret, s, len) == NULL) {
|
||||
@ -173,12 +177,23 @@ oggz_comment_new (const char * name, const char * value)
|
||||
OggzComment * comment;
|
||||
|
||||
if (!oggz_comment_validate_byname (name, value)) return NULL;
|
||||
/* Ensures that name != NULL, value != NULL, and validates strings */
|
||||
|
||||
comment = oggz_malloc (sizeof (OggzComment));
|
||||
if (comment == NULL) return NULL;
|
||||
|
||||
comment->name = oggz_strdup (name);
|
||||
if (comment->name == NULL) {
|
||||
oggz_free (comment);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
comment->value = oggz_strdup (value);
|
||||
if (comment->value == NULL) {
|
||||
oggz_free (comment->name);
|
||||
oggz_free (comment);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return comment;
|
||||
}
|
||||
@ -217,7 +232,8 @@ _oggz_comment_set_vendor (OGGZ * oggz, long serialno,
|
||||
|
||||
if (stream->vendor) oggz_free (stream->vendor);
|
||||
|
||||
stream->vendor = oggz_strdup (vendor_string);
|
||||
if ((stream->vendor = oggz_strdup (vendor_string)) == NULL)
|
||||
return OGGZ_ERR_OUT_OF_MEMORY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -364,9 +380,11 @@ oggz_comment_add (OGGZ * oggz, long serialno, const OggzComment * comment)
|
||||
if (!oggz_comment_validate_byname (comment->name, comment->value))
|
||||
return OGGZ_ERR_COMMENT_INVALID;
|
||||
|
||||
new_comment = oggz_comment_new (comment->name, comment->value);
|
||||
if ((new_comment = oggz_comment_new (comment->name, comment->value)) == NULL)
|
||||
return OGGZ_ERR_OUT_OF_MEMORY;
|
||||
|
||||
_oggz_comment_add (stream, new_comment);
|
||||
if (_oggz_comment_add (stream, new_comment) == NULL)
|
||||
return OGGZ_ERR_OUT_OF_MEMORY;
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
@ -398,9 +416,11 @@ oggz_comment_add_byname (OGGZ * oggz, long serialno,
|
||||
if (!oggz_comment_validate_byname (name, value))
|
||||
return OGGZ_ERR_COMMENT_INVALID;
|
||||
|
||||
new_comment = oggz_comment_new (name, value);
|
||||
if ((new_comment = oggz_comment_new (name, value)) == NULL)
|
||||
return OGGZ_ERR_OUT_OF_MEMORY;
|
||||
|
||||
_oggz_comment_add (stream, new_comment);
|
||||
if (_oggz_comment_add (stream, new_comment) == NULL)
|
||||
return OGGZ_ERR_OUT_OF_MEMORY;
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
@ -531,7 +551,8 @@ oggz_comments_decode (OGGZ * oggz, long serialno,
|
||||
{
|
||||
oggz_stream_t * stream;
|
||||
char *c= (char *)comments;
|
||||
int len, i, nb_fields, n;
|
||||
int i, nb_fields, n;
|
||||
size_t len;
|
||||
char *end;
|
||||
char * name, * value, * nvalue = NULL;
|
||||
OggzComment * comment;
|
||||
@ -543,16 +564,22 @@ oggz_comments_decode (OGGZ * oggz, long serialno,
|
||||
len=readint(c, 0);
|
||||
|
||||
c+=4;
|
||||
if (c+len>end) return -1;
|
||||
if (len>(size_t)(end-c)) return -1;
|
||||
|
||||
stream = oggz_get_stream (oggz, serialno);
|
||||
if (stream == NULL) return OGGZ_ERR_BAD_SERIALNO;
|
||||
|
||||
/* Vendor */
|
||||
nvalue = oggz_strdup_len (c, len);
|
||||
if (!nvalue) return -1;
|
||||
_oggz_comment_set_vendor (oggz, serialno, nvalue);
|
||||
if (nvalue) oggz_free (nvalue);
|
||||
if (len > 0) {
|
||||
if ((nvalue = oggz_strdup_len (c, len)) == NULL)
|
||||
return OGGZ_ERR_OUT_OF_MEMORY;
|
||||
|
||||
if (_oggz_comment_set_vendor (oggz, serialno, nvalue) == OGGZ_ERR_OUT_OF_MEMORY)
|
||||
return OGGZ_ERR_OUT_OF_MEMORY;
|
||||
|
||||
oggz_free (nvalue);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
fwrite(c, 1, len, stderr); fputc ('\n', stderr);
|
||||
#endif
|
||||
@ -560,6 +587,8 @@ oggz_comments_decode (OGGZ * oggz, long serialno,
|
||||
|
||||
if (c+4>end) return -1;
|
||||
|
||||
/* This value gets checked effectively by the 'for' condition
|
||||
and the checks within the loop for c running off the end. */
|
||||
nb_fields=readint(c, 0);
|
||||
c+=4;
|
||||
for (i=0;i<nb_fields;i++) {
|
||||
@ -568,7 +597,7 @@ oggz_comments_decode (OGGZ * oggz, long serialno,
|
||||
len=readint(c, 0);
|
||||
|
||||
c+=4;
|
||||
if (c+len>end) return -1;
|
||||
if (len>(size_t)(end-c)) return -1;
|
||||
|
||||
name = c;
|
||||
value = oggz_index_len (c, '=', len);
|
||||
@ -577,18 +606,30 @@ oggz_comments_decode (OGGZ * oggz, long serialno,
|
||||
value++;
|
||||
|
||||
n = c+len - value;
|
||||
nvalue = oggz_strdup_len (value, n);
|
||||
if ((nvalue = oggz_strdup_len (value, n)) == NULL)
|
||||
return OGGZ_ERR_OUT_OF_MEMORY;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("oggz_comments_decode: %s -> %s (length %d)\n",
|
||||
name, nvalue, n);
|
||||
#endif
|
||||
comment = oggz_comment_new (name, nvalue);
|
||||
_oggz_comment_add (stream, comment);
|
||||
if ((comment = oggz_comment_new (name, nvalue)) == NULL)
|
||||
return OGGZ_ERR_OUT_OF_MEMORY;
|
||||
|
||||
if (_oggz_comment_add (stream, comment) == NULL)
|
||||
return OGGZ_ERR_OUT_OF_MEMORY;
|
||||
|
||||
oggz_free (nvalue);
|
||||
} else {
|
||||
nvalue = oggz_strdup_len (name, len);
|
||||
comment = oggz_comment_new (nvalue, NULL);
|
||||
_oggz_comment_add (stream, comment);
|
||||
if ((nvalue = oggz_strdup_len (name, len)) == NULL)
|
||||
return OGGZ_ERR_OUT_OF_MEMORY;
|
||||
|
||||
if ((comment = oggz_comment_new (nvalue, NULL)) == NULL)
|
||||
return OGGZ_ERR_OUT_OF_MEMORY;
|
||||
|
||||
if (_oggz_comment_add (stream, comment) == NULL)
|
||||
return OGGZ_ERR_OUT_OF_MEMORY;
|
||||
|
||||
oggz_free (nvalue);
|
||||
}
|
||||
|
||||
@ -648,7 +689,9 @@ oggz_comments_encode (OGGZ * oggz, long serialno,
|
||||
#endif
|
||||
|
||||
/* user comment list length */
|
||||
actual_length += 4;
|
||||
if (accum_length (&actual_length, 4) == 0)
|
||||
return 0;
|
||||
|
||||
|
||||
for (comment = oggz_comment_first (oggz, serialno); comment;
|
||||
comment = oggz_comment_next (oggz, serialno, comment)) {
|
||||
@ -686,7 +729,7 @@ oggz_comments_encode (OGGZ * oggz, long serialno,
|
||||
field_length = oggz_comment_len (stream->vendor);
|
||||
memcpy (c, stream->vendor, MIN (field_length, remaining));
|
||||
c += field_length; remaining -= field_length;
|
||||
if (remaining <= 0 ) return actual_length;
|
||||
if (remaining <= 0) return actual_length;
|
||||
}
|
||||
|
||||
remaining -= 4;
|
||||
|
@ -47,4 +47,3 @@ cp $1/AUTHORS ./AUTHORS
|
||||
patch -p3 <wince.patch
|
||||
patch -p3 <endian.patch
|
||||
patch -p4 <seek.patch
|
||||
patch -p3 <seek-error-fix.patch
|
||||
|
Loading…
Reference in New Issue
Block a user