Built SDL2_image and _mixer static
This commit is contained in:
30
libsdl2_mixer/external/flac-1.3.2/src/share/grabbag/Makefile.lite
vendored
Normal file
30
libsdl2_mixer/external/flac-1.3.2/src/share/grabbag/Makefile.lite
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
# grabbag - Convenience lib for various routines common to several tools
|
||||
|
||||
#
|
||||
# GNU makefile
|
||||
#
|
||||
|
||||
topdir = ../../..
|
||||
libdir = $(topdir)/objs/$(BUILD)/lib
|
||||
|
||||
ifeq ($(OS),Darwin)
|
||||
EXPLICIT_LIBS = $(libdir)/libFLAC.a $(libdir)/libreplaygain_analysis.a $(OGG_EXPLICIT_LIBS) -lm
|
||||
else
|
||||
LIBS = -lFLAC -lreplaygain_analysis $(OGG_LIBS) -lm
|
||||
endif
|
||||
|
||||
LIB_NAME = libgrabbag
|
||||
INCLUDES = -I$(topdir)/include
|
||||
|
||||
SRCS_C = \
|
||||
alloc.c \
|
||||
cuesheet.c \
|
||||
file.c \
|
||||
picture.c \
|
||||
replaygain.c \
|
||||
seektable.c \
|
||||
snprintf.c
|
||||
|
||||
include $(topdir)/build/lib.mk
|
||||
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||
48
libsdl2_mixer/external/flac-1.3.2/src/share/grabbag/alloc.c
vendored
Normal file
48
libsdl2_mixer/external/flac-1.3.2/src/share/grabbag/alloc.c
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
/* alloc - Convenience routines for safely allocating memory
|
||||
* Copyright (C) 2007-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "share/alloc.h"
|
||||
|
||||
void *safe_malloc_mul_2op_(size_t size1, size_t size2)
|
||||
{
|
||||
if(!size1 || !size2)
|
||||
return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
|
||||
if(size1 > SIZE_MAX / size2)
|
||||
return 0;
|
||||
return malloc(size1*size2);
|
||||
}
|
||||
656
libsdl2_mixer/external/flac-1.3.2/src/share/grabbag/cuesheet.c
vendored
Normal file
656
libsdl2_mixer/external/flac-1.3.2/src/share/grabbag/cuesheet.c
vendored
Normal file
@@ -0,0 +1,656 @@
|
||||
/* grabbag - Convenience lib for various routines common to several tools
|
||||
* Copyright (C) 2002-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "FLAC/assert.h"
|
||||
#include "share/compat.h"
|
||||
#include "share/grabbag.h"
|
||||
#include "share/safe_str.h"
|
||||
|
||||
unsigned grabbag__cuesheet_msf_to_frame(unsigned minutes, unsigned seconds, unsigned frames)
|
||||
{
|
||||
return ((minutes * 60) + seconds) * 75 + frames;
|
||||
}
|
||||
|
||||
void grabbag__cuesheet_frame_to_msf(unsigned frame, unsigned *minutes, unsigned *seconds, unsigned *frames)
|
||||
{
|
||||
*frames = frame % 75;
|
||||
frame /= 75;
|
||||
*seconds = frame % 60;
|
||||
frame /= 60;
|
||||
*minutes = frame;
|
||||
}
|
||||
|
||||
/* since we only care about values >= 0 or error, returns < 0 for any illegal string, else value */
|
||||
static int local__parse_int_(const char *s)
|
||||
{
|
||||
int ret = 0;
|
||||
char c;
|
||||
|
||||
if(*s == '\0')
|
||||
return -1;
|
||||
|
||||
while('\0' != (c = *s++))
|
||||
if(c >= '0' && c <= '9')
|
||||
ret = ret * 10 + (c - '0');
|
||||
else
|
||||
return -1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* since we only care about values >= 0 or error, returns < 0 for any illegal string, else value */
|
||||
static FLAC__int64 local__parse_int64_(const char *s)
|
||||
{
|
||||
FLAC__int64 ret = 0;
|
||||
char c;
|
||||
|
||||
if(*s == '\0')
|
||||
return -1;
|
||||
|
||||
while('\0' != (c = *s++))
|
||||
if(c >= '0' && c <= '9')
|
||||
ret = ret * 10 + (c - '0');
|
||||
else
|
||||
return -1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* accept minute:second:frame syntax of '[0-9]+:[0-9][0-9]?:[0-9][0-9]?', but max second of 59 and max frame of 74, e.g. 0:0:0, 123:45:67
|
||||
* return sample number or <0 for error
|
||||
* WATCHOUT: if sample rate is not evenly divisible by 75, the resulting sample number will be approximate
|
||||
*/
|
||||
static FLAC__int64 local__parse_msf_(const char *s, unsigned sample_rate)
|
||||
{
|
||||
FLAC__int64 ret, field;
|
||||
char c;
|
||||
|
||||
c = *s++;
|
||||
if(c >= '0' && c <= '9')
|
||||
field = (c - '0');
|
||||
else
|
||||
return -1;
|
||||
while(':' != (c = *s++)) {
|
||||
if(c >= '0' && c <= '9')
|
||||
field = field * 10 + (c - '0');
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = field * 60 * sample_rate;
|
||||
|
||||
c = *s++;
|
||||
if(c >= '0' && c <= '9')
|
||||
field = (c - '0');
|
||||
else
|
||||
return -1;
|
||||
if(':' != (c = *s++)) {
|
||||
if(c >= '0' && c <= '9') {
|
||||
field = field * 10 + (c - '0');
|
||||
c = *s++;
|
||||
if(c != ':')
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(field >= 60)
|
||||
return -1;
|
||||
|
||||
ret += field * sample_rate;
|
||||
|
||||
c = *s++;
|
||||
if(c >= '0' && c <= '9')
|
||||
field = (c - '0');
|
||||
else
|
||||
return -1;
|
||||
if('\0' != (c = *s++)) {
|
||||
if(c >= '0' && c <= '9') {
|
||||
field = field * 10 + (c - '0');
|
||||
c = *s++;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(c != '\0')
|
||||
return -1;
|
||||
|
||||
if(field >= 75)
|
||||
return -1;
|
||||
|
||||
ret += field * (sample_rate / 75);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* accept minute:second syntax of '[0-9]+:[0-9][0-9]?{,.[0-9]+}', but second < 60, e.g. 0:0.0, 3:5, 15:31.731
|
||||
* return sample number or <0 for error
|
||||
* WATCHOUT: depending on the sample rate, the resulting sample number may be approximate with fractional seconds
|
||||
*/
|
||||
static FLAC__int64 local__parse_ms_(const char *s, unsigned sample_rate)
|
||||
{
|
||||
FLAC__int64 ret, field;
|
||||
double x;
|
||||
char c, *end;
|
||||
|
||||
c = *s++;
|
||||
if(c >= '0' && c <= '9')
|
||||
field = (c - '0');
|
||||
else
|
||||
return -1;
|
||||
while(':' != (c = *s++)) {
|
||||
if(c >= '0' && c <= '9')
|
||||
field = field * 10 + (c - '0');
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = field * 60 * sample_rate;
|
||||
|
||||
s++; /* skip the ':' */
|
||||
if(strspn(s, "0123456789.") != strlen(s))
|
||||
return -1;
|
||||
x = strtod(s, &end);
|
||||
if(*end || end == s)
|
||||
return -1;
|
||||
if(x < 0.0 || x >= 60.0)
|
||||
return -1;
|
||||
|
||||
ret += (FLAC__int64)(x * sample_rate);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *local__get_field_(char **s, FLAC__bool allow_quotes)
|
||||
{
|
||||
FLAC__bool has_quote = false;
|
||||
char *p;
|
||||
|
||||
FLAC__ASSERT(0 != s);
|
||||
|
||||
if(0 == *s)
|
||||
return 0;
|
||||
|
||||
/* skip leading whitespace */
|
||||
while(**s && 0 != strchr(" \t\r\n", **s))
|
||||
(*s)++;
|
||||
|
||||
if(**s == 0) {
|
||||
*s = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(allow_quotes && (**s == '"')) {
|
||||
has_quote = true;
|
||||
(*s)++;
|
||||
if(**s == 0) {
|
||||
*s = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
p = *s;
|
||||
|
||||
if(has_quote) {
|
||||
*s = strchr(*s, '\"');
|
||||
/* if there is no matching end quote, it's an error */
|
||||
if(0 == *s)
|
||||
p = *s = 0;
|
||||
else {
|
||||
**s = '\0';
|
||||
(*s)++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
while(**s && 0 == strchr(" \t\r\n", **s))
|
||||
(*s)++;
|
||||
if(**s) {
|
||||
**s = '\0';
|
||||
(*s)++;
|
||||
}
|
||||
else
|
||||
*s = 0;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
static FLAC__bool local__cuesheet_parse_(FILE *file, const char **error_message, unsigned *last_line_read, FLAC__StreamMetadata *cuesheet, unsigned sample_rate, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset)
|
||||
{
|
||||
char buffer[4096], *line, *field;
|
||||
unsigned forced_leadout_track_num = 0;
|
||||
FLAC__uint64 forced_leadout_track_offset = 0;
|
||||
int in_track_num = -1, in_index_num = -1;
|
||||
FLAC__bool disc_has_catalog = false, track_has_flags = false, track_has_isrc = false, has_forced_leadout = false;
|
||||
FLAC__StreamMetadata_CueSheet *cs = &cuesheet->data.cue_sheet;
|
||||
|
||||
FLAC__ASSERT(!is_cdda || sample_rate == 44100);
|
||||
/* double protection */
|
||||
if(is_cdda && sample_rate != 44100) {
|
||||
*error_message = "CD-DA cuesheet only allowed with 44.1kHz sample rate";
|
||||
return false;
|
||||
}
|
||||
|
||||
cs->lead_in = is_cdda? 2 * 44100 /* The default lead-in size for CD-DA */ : 0;
|
||||
cs->is_cd = is_cdda;
|
||||
|
||||
while(0 != fgets(buffer, sizeof(buffer), file)) {
|
||||
(*last_line_read)++;
|
||||
line = buffer;
|
||||
|
||||
{
|
||||
size_t linelen = strlen(line);
|
||||
if((linelen == sizeof(buffer)-1) && line[linelen-1] != '\n') {
|
||||
*error_message = "line too long";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(0 != (field = local__get_field_(&line, /*allow_quotes=*/false))) {
|
||||
if(0 == FLAC__STRCASECMP(field, "CATALOG")) {
|
||||
if(disc_has_catalog) {
|
||||
*error_message = "found multiple CATALOG commands";
|
||||
return false;
|
||||
}
|
||||
if(0 == (field = local__get_field_(&line, /*allow_quotes=*/true))) {
|
||||
*error_message = "CATALOG is missing catalog number";
|
||||
return false;
|
||||
}
|
||||
if(strlen(field) >= sizeof(cs->media_catalog_number)) {
|
||||
*error_message = "CATALOG number is too long";
|
||||
return false;
|
||||
}
|
||||
if(is_cdda && (strlen(field) != 13 || strspn(field, "0123456789") != 13)) {
|
||||
*error_message = "CD-DA CATALOG number must be 13 decimal digits";
|
||||
return false;
|
||||
}
|
||||
safe_strncpy(cs->media_catalog_number, field, sizeof(cs->media_catalog_number));
|
||||
disc_has_catalog = true;
|
||||
}
|
||||
else if(0 == FLAC__STRCASECMP(field, "FLAGS")) {
|
||||
if(track_has_flags) {
|
||||
*error_message = "found multiple FLAGS commands";
|
||||
return false;
|
||||
}
|
||||
if(in_track_num < 0 || in_index_num >= 0) {
|
||||
*error_message = "FLAGS command must come after TRACK but before INDEX";
|
||||
return false;
|
||||
}
|
||||
while(0 != (field = local__get_field_(&line, /*allow_quotes=*/false))) {
|
||||
if(0 == FLAC__STRCASECMP(field, "PRE"))
|
||||
cs->tracks[cs->num_tracks-1].pre_emphasis = 1;
|
||||
}
|
||||
track_has_flags = true;
|
||||
}
|
||||
else if(0 == FLAC__STRCASECMP(field, "INDEX")) {
|
||||
FLAC__int64 xx;
|
||||
FLAC__StreamMetadata_CueSheet_Track *track = &cs->tracks[cs->num_tracks-1];
|
||||
if(in_track_num < 0) {
|
||||
*error_message = "found INDEX before any TRACK";
|
||||
return false;
|
||||
}
|
||||
if(0 == (field = local__get_field_(&line, /*allow_quotes=*/false))) {
|
||||
*error_message = "INDEX is missing index number";
|
||||
return false;
|
||||
}
|
||||
in_index_num = local__parse_int_(field);
|
||||
if(in_index_num < 0) {
|
||||
*error_message = "INDEX has invalid index number";
|
||||
return false;
|
||||
}
|
||||
FLAC__ASSERT(cs->num_tracks > 0);
|
||||
if(track->num_indices == 0) {
|
||||
/* it's the first index point of the track */
|
||||
if(in_index_num > 1) {
|
||||
*error_message = "first INDEX number of a TRACK must be 0 or 1";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(in_index_num != track->indices[track->num_indices-1].number + 1) {
|
||||
*error_message = "INDEX numbers must be sequential";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(is_cdda && in_index_num > 99) {
|
||||
*error_message = "CD-DA INDEX number must be between 0 and 99, inclusive";
|
||||
return false;
|
||||
}
|
||||
/*@@@ search for duplicate track number? */
|
||||
if(0 == (field = local__get_field_(&line, /*allow_quotes=*/false))) {
|
||||
*error_message = "INDEX is missing an offset after the index number";
|
||||
return false;
|
||||
}
|
||||
/* first parse as minute:second:frame format */
|
||||
xx = local__parse_msf_(field, sample_rate);
|
||||
if(xx < 0) {
|
||||
/* CD-DA must use only MM:SS:FF format */
|
||||
if(is_cdda) {
|
||||
*error_message = "illegal INDEX offset (not of the form MM:SS:FF)";
|
||||
return false;
|
||||
}
|
||||
/* as an extension for non-CD-DA we allow MM:SS.SS or raw sample number */
|
||||
xx = local__parse_ms_(field, sample_rate);
|
||||
if(xx < 0) {
|
||||
xx = local__parse_int64_(field);
|
||||
if(xx < 0) {
|
||||
*error_message = "illegal INDEX offset";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(sample_rate % 75 && xx) {
|
||||
/* only sample zero is exact */
|
||||
*error_message = "illegal INDEX offset (MM:SS:FF form not allowed if sample rate is not a multiple of 75)";
|
||||
return false;
|
||||
}
|
||||
if(is_cdda && cs->num_tracks == 1 && cs->tracks[0].num_indices == 0 && xx != 0) {
|
||||
*error_message = "first INDEX of first TRACK must have an offset of 00:00:00";
|
||||
return false;
|
||||
}
|
||||
if(is_cdda && track->num_indices > 0 && (FLAC__uint64)xx <= track->indices[track->num_indices-1].offset) {
|
||||
*error_message = "CD-DA INDEX offsets must increase in time";
|
||||
return false;
|
||||
}
|
||||
/* fill in track offset if it's the first index of the track */
|
||||
if(track->num_indices == 0)
|
||||
track->offset = (FLAC__uint64)xx;
|
||||
if(is_cdda && cs->num_tracks > 1) {
|
||||
const FLAC__StreamMetadata_CueSheet_Track *prev = &cs->tracks[cs->num_tracks-2];
|
||||
if((FLAC__uint64)xx <= prev->offset + prev->indices[prev->num_indices-1].offset) {
|
||||
*error_message = "CD-DA INDEX offsets must increase in time";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(!FLAC__metadata_object_cuesheet_track_insert_blank_index(cuesheet, cs->num_tracks-1, track->num_indices)) {
|
||||
*error_message = "memory allocation error";
|
||||
return false;
|
||||
}
|
||||
track->indices[track->num_indices-1].offset = (FLAC__uint64)xx - track->offset;
|
||||
track->indices[track->num_indices-1].number = in_index_num;
|
||||
}
|
||||
else if(0 == FLAC__STRCASECMP(field, "ISRC")) {
|
||||
char *l, *r;
|
||||
if(track_has_isrc) {
|
||||
*error_message = "found multiple ISRC commands";
|
||||
return false;
|
||||
}
|
||||
if(in_track_num < 0 || in_index_num >= 0) {
|
||||
*error_message = "ISRC command must come after TRACK but before INDEX";
|
||||
return false;
|
||||
}
|
||||
if(0 == (field = local__get_field_(&line, /*allow_quotes=*/true))) {
|
||||
*error_message = "ISRC is missing ISRC number";
|
||||
return false;
|
||||
}
|
||||
/* strip out dashes */
|
||||
for(l = r = field; *r; r++) {
|
||||
if(*r != '-')
|
||||
*l++ = *r;
|
||||
}
|
||||
*l = '\0';
|
||||
if(strlen(field) != 12 || strspn(field, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") < 5 || strspn(field+5, "1234567890") != 7) {
|
||||
*error_message = "invalid ISRC number";
|
||||
return false;
|
||||
}
|
||||
safe_strncpy(cs->tracks[cs->num_tracks-1].isrc, field, sizeof(cs->tracks[cs->num_tracks-1].isrc));
|
||||
track_has_isrc = true;
|
||||
}
|
||||
else if(0 == FLAC__STRCASECMP(field, "TRACK")) {
|
||||
if(cs->num_tracks > 0) {
|
||||
const FLAC__StreamMetadata_CueSheet_Track *prev = &cs->tracks[cs->num_tracks-1];
|
||||
if(
|
||||
prev->num_indices == 0 ||
|
||||
(
|
||||
is_cdda &&
|
||||
(
|
||||
(prev->num_indices == 1 && prev->indices[0].number != 1) ||
|
||||
(prev->num_indices == 2 && prev->indices[0].number != 1 && prev->indices[1].number != 1)
|
||||
)
|
||||
)
|
||||
) {
|
||||
*error_message = is_cdda?
|
||||
"previous TRACK must specify at least one INDEX 01" :
|
||||
"previous TRACK must specify at least one INDEX";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(0 == (field = local__get_field_(&line, /*allow_quotes=*/false))) {
|
||||
*error_message = "TRACK is missing track number";
|
||||
return false;
|
||||
}
|
||||
in_track_num = local__parse_int_(field);
|
||||
if(in_track_num < 0) {
|
||||
*error_message = "TRACK has invalid track number";
|
||||
return false;
|
||||
}
|
||||
if(in_track_num == 0) {
|
||||
*error_message = "TRACK number must be greater than 0";
|
||||
return false;
|
||||
}
|
||||
if(is_cdda) {
|
||||
if(in_track_num > 99) {
|
||||
*error_message = "CD-DA TRACK number must be between 1 and 99, inclusive";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(in_track_num == 255) {
|
||||
*error_message = "TRACK number 255 is reserved for the lead-out";
|
||||
return false;
|
||||
}
|
||||
else if(in_track_num > 255) {
|
||||
*error_message = "TRACK number must be between 1 and 254, inclusive";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(is_cdda && cs->num_tracks > 0 && in_track_num != cs->tracks[cs->num_tracks-1].number + 1) {
|
||||
*error_message = "CD-DA TRACK numbers must be sequential";
|
||||
return false;
|
||||
}
|
||||
/*@@@ search for duplicate track number? */
|
||||
if(0 == (field = local__get_field_(&line, /*allow_quotes=*/false))) {
|
||||
*error_message = "TRACK is missing a track type after the track number";
|
||||
return false;
|
||||
}
|
||||
if(!FLAC__metadata_object_cuesheet_insert_blank_track(cuesheet, cs->num_tracks)) {
|
||||
*error_message = "memory allocation error";
|
||||
return false;
|
||||
}
|
||||
cs->tracks[cs->num_tracks-1].number = in_track_num;
|
||||
cs->tracks[cs->num_tracks-1].type = (0 == FLAC__STRCASECMP(field, "AUDIO"))? 0 : 1; /*@@@ should we be more strict with the value here? */
|
||||
in_index_num = -1;
|
||||
track_has_flags = false;
|
||||
track_has_isrc = false;
|
||||
}
|
||||
else if(0 == FLAC__STRCASECMP(field, "REM")) {
|
||||
if(0 != (field = local__get_field_(&line, /*allow_quotes=*/false))) {
|
||||
if(0 == strcmp(field, "FLAC__lead-in")) {
|
||||
FLAC__int64 xx;
|
||||
if(0 == (field = local__get_field_(&line, /*allow_quotes=*/false))) {
|
||||
*error_message = "FLAC__lead-in is missing offset";
|
||||
return false;
|
||||
}
|
||||
xx = local__parse_int64_(field);
|
||||
if(xx < 0) {
|
||||
*error_message = "illegal FLAC__lead-in offset";
|
||||
return false;
|
||||
}
|
||||
if(is_cdda && xx % 588 != 0) {
|
||||
*error_message = "illegal CD-DA FLAC__lead-in offset, must be even multiple of 588 samples";
|
||||
return false;
|
||||
}
|
||||
cs->lead_in = (FLAC__uint64)xx;
|
||||
}
|
||||
else if(0 == strcmp(field, "FLAC__lead-out")) {
|
||||
int track_num;
|
||||
FLAC__int64 offset;
|
||||
if(has_forced_leadout) {
|
||||
*error_message = "multiple FLAC__lead-out commands";
|
||||
return false;
|
||||
}
|
||||
if(0 == (field = local__get_field_(&line, /*allow_quotes=*/false))) {
|
||||
*error_message = "FLAC__lead-out is missing track number";
|
||||
return false;
|
||||
}
|
||||
track_num = local__parse_int_(field);
|
||||
if(track_num < 0) {
|
||||
*error_message = "illegal FLAC__lead-out track number";
|
||||
return false;
|
||||
}
|
||||
forced_leadout_track_num = (unsigned)track_num;
|
||||
/*@@@ search for duplicate track number? */
|
||||
if(0 == (field = local__get_field_(&line, /*allow_quotes=*/false))) {
|
||||
*error_message = "FLAC__lead-out is missing offset";
|
||||
return false;
|
||||
}
|
||||
offset = local__parse_int64_(field);
|
||||
if(offset < 0) {
|
||||
*error_message = "illegal FLAC__lead-out offset";
|
||||
return false;
|
||||
}
|
||||
forced_leadout_track_offset = (FLAC__uint64)offset;
|
||||
if(forced_leadout_track_offset != lead_out_offset) {
|
||||
*error_message = "FLAC__lead-out offset does not match end-of-stream offset";
|
||||
return false;
|
||||
}
|
||||
has_forced_leadout = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(cs->num_tracks == 0) {
|
||||
*error_message = "there must be at least one TRACK command";
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
const FLAC__StreamMetadata_CueSheet_Track *prev = &cs->tracks[cs->num_tracks-1];
|
||||
if(
|
||||
prev->num_indices == 0 ||
|
||||
(
|
||||
is_cdda &&
|
||||
(
|
||||
(prev->num_indices == 1 && prev->indices[0].number != 1) ||
|
||||
(prev->num_indices == 2 && prev->indices[0].number != 1 && prev->indices[1].number != 1)
|
||||
)
|
||||
)
|
||||
) {
|
||||
*error_message = is_cdda?
|
||||
"previous TRACK must specify at least one INDEX 01" :
|
||||
"previous TRACK must specify at least one INDEX";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(!has_forced_leadout) {
|
||||
forced_leadout_track_num = is_cdda? 170 : 255;
|
||||
forced_leadout_track_offset = lead_out_offset;
|
||||
}
|
||||
if(!FLAC__metadata_object_cuesheet_insert_blank_track(cuesheet, cs->num_tracks)) {
|
||||
*error_message = "memory allocation error";
|
||||
return false;
|
||||
}
|
||||
cs->tracks[cs->num_tracks-1].number = forced_leadout_track_num;
|
||||
cs->tracks[cs->num_tracks-1].offset = forced_leadout_track_offset;
|
||||
|
||||
if(!feof(file)) {
|
||||
*error_message = "read error";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC__StreamMetadata *grabbag__cuesheet_parse(FILE *file, const char **error_message, unsigned *last_line_read, unsigned sample_rate, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset)
|
||||
{
|
||||
FLAC__StreamMetadata *cuesheet;
|
||||
|
||||
FLAC__ASSERT(0 != file);
|
||||
FLAC__ASSERT(0 != error_message);
|
||||
FLAC__ASSERT(0 != last_line_read);
|
||||
|
||||
*last_line_read = 0;
|
||||
cuesheet = FLAC__metadata_object_new(FLAC__METADATA_TYPE_CUESHEET);
|
||||
|
||||
if(0 == cuesheet) {
|
||||
*error_message = "memory allocation error";
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!local__cuesheet_parse_(file, error_message, last_line_read, cuesheet, sample_rate, is_cdda, lead_out_offset)) {
|
||||
FLAC__metadata_object_delete(cuesheet);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return cuesheet;
|
||||
}
|
||||
|
||||
void grabbag__cuesheet_emit(FILE *file, const FLAC__StreamMetadata *cuesheet, const char *file_reference)
|
||||
{
|
||||
const FLAC__StreamMetadata_CueSheet *cs;
|
||||
unsigned track_num, index_num;
|
||||
|
||||
FLAC__ASSERT(0 != file);
|
||||
FLAC__ASSERT(0 != cuesheet);
|
||||
FLAC__ASSERT(cuesheet->type == FLAC__METADATA_TYPE_CUESHEET);
|
||||
|
||||
cs = &cuesheet->data.cue_sheet;
|
||||
|
||||
if(*(cs->media_catalog_number))
|
||||
fprintf(file, "CATALOG %s\n", cs->media_catalog_number);
|
||||
fprintf(file, "FILE %s\n", file_reference);
|
||||
|
||||
for(track_num = 0; track_num < cs->num_tracks-1; track_num++) {
|
||||
const FLAC__StreamMetadata_CueSheet_Track *track = cs->tracks + track_num;
|
||||
|
||||
fprintf(file, " TRACK %02u %s\n", (unsigned)track->number, track->type == 0? "AUDIO" : "DATA");
|
||||
|
||||
if(track->pre_emphasis)
|
||||
fprintf(file, " FLAGS PRE\n");
|
||||
if(*(track->isrc))
|
||||
fprintf(file, " ISRC %s\n", track->isrc);
|
||||
|
||||
for(index_num = 0; index_num < track->num_indices; index_num++) {
|
||||
const FLAC__StreamMetadata_CueSheet_Index *indx = track->indices + index_num;
|
||||
|
||||
fprintf(file, " INDEX %02u ", (unsigned)indx->number);
|
||||
if(cs->is_cd) {
|
||||
const unsigned logical_frame = (unsigned)((track->offset + indx->offset) / (44100 / 75));
|
||||
unsigned m, s, f;
|
||||
grabbag__cuesheet_frame_to_msf(logical_frame, &m, &s, &f);
|
||||
fprintf(file, "%02u:%02u:%02u\n", m, s, f);
|
||||
}
|
||||
else
|
||||
fprintf(file, "%" PRIu64 "\n", (track->offset + indx->offset));
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(file, "REM FLAC__lead-in %" PRIu64 "\n", cs->lead_in);
|
||||
fprintf(file, "REM FLAC__lead-out %u %" PRIu64 "\n", (unsigned)cs->tracks[track_num].number, cs->tracks[track_num].offset);
|
||||
}
|
||||
193
libsdl2_mixer/external/flac-1.3.2/src/share/grabbag/file.c
vendored
Normal file
193
libsdl2_mixer/external/flac-1.3.2/src/share/grabbag/file.c
vendored
Normal file
@@ -0,0 +1,193 @@
|
||||
/* grabbag - Convenience lib for various routines common to several tools
|
||||
* Copyright (C) 2002-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#if defined _MSC_VER || defined __MINGW32__
|
||||
#include <sys/utime.h> /* for utime() */
|
||||
#include <io.h> /* for chmod(), _setmode(), unlink() */
|
||||
#include <fcntl.h> /* for _O_BINARY */
|
||||
#else
|
||||
#include <sys/types.h> /* some flavors of BSD (like OS X) require this to get time_t */
|
||||
#include <utime.h> /* for utime() */
|
||||
#endif
|
||||
#if defined __CYGWIN__ || defined __EMX__
|
||||
#include <io.h> /* for setmode(), O_BINARY */
|
||||
#include <fcntl.h> /* for _O_BINARY */
|
||||
#endif
|
||||
#include <sys/stat.h> /* for stat(), maybe chmod() */
|
||||
#if defined _WIN32 && !defined __CYGWIN__
|
||||
#else
|
||||
#include <unistd.h> /* for unlink() */
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h> /* for strrchr() */
|
||||
#if defined _WIN32 && !defined __CYGWIN__
|
||||
// for GetFileInformationByHandle() etc
|
||||
#include <windows.h>
|
||||
#include <winbase.h>
|
||||
#endif
|
||||
#include "share/grabbag.h"
|
||||
|
||||
|
||||
void grabbag__file_copy_metadata(const char *srcpath, const char *destpath)
|
||||
{
|
||||
struct flac_stat_s srcstat;
|
||||
struct utimbuf srctime;
|
||||
|
||||
if(0 == flac_stat(srcpath, &srcstat)) {
|
||||
srctime.actime = srcstat.st_atime;
|
||||
srctime.modtime = srcstat.st_mtime;
|
||||
(void)flac_chmod(destpath, srcstat.st_mode);
|
||||
(void)flac_utime(destpath, &srctime);
|
||||
}
|
||||
}
|
||||
|
||||
FLAC__off_t grabbag__file_get_filesize(const char *srcpath)
|
||||
{
|
||||
struct flac_stat_s srcstat;
|
||||
|
||||
if(0 == flac_stat(srcpath, &srcstat))
|
||||
return srcstat.st_size;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *grabbag__file_get_basename(const char *srcpath)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
p = strrchr(srcpath, '/');
|
||||
if(0 == p) {
|
||||
p = strrchr(srcpath, '\\');
|
||||
if(0 == p)
|
||||
return srcpath;
|
||||
}
|
||||
return ++p;
|
||||
}
|
||||
|
||||
FLAC__bool grabbag__file_change_stats(const char *filename, FLAC__bool read_only)
|
||||
{
|
||||
struct flac_stat_s stats;
|
||||
|
||||
if(0 == flac_stat(filename, &stats)) {
|
||||
#if !defined _MSC_VER && !defined __MINGW32__
|
||||
if(read_only) {
|
||||
stats.st_mode &= ~S_IWUSR;
|
||||
stats.st_mode &= ~S_IWGRP;
|
||||
stats.st_mode &= ~S_IWOTH;
|
||||
}
|
||||
else {
|
||||
stats.st_mode |= S_IWUSR;
|
||||
}
|
||||
#else
|
||||
if(read_only)
|
||||
stats.st_mode &= ~S_IWRITE;
|
||||
else
|
||||
stats.st_mode |= S_IWRITE;
|
||||
#endif
|
||||
if(0 != flac_chmod(filename, stats.st_mode))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC__bool grabbag__file_are_same(const char *f1, const char *f2)
|
||||
{
|
||||
#if defined _MSC_VER || defined __MINGW32__
|
||||
/* see
|
||||
* http://www.hydrogenaudio.org/forums/index.php?showtopic=49439&pid=444300&st=0
|
||||
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/getfileinformationbyhandle.asp
|
||||
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/by_handle_file_information_str.asp
|
||||
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/createfile.asp
|
||||
* apparently both the files have to be open at the same time for the comparison to work
|
||||
*/
|
||||
FLAC__bool same = false;
|
||||
BY_HANDLE_FILE_INFORMATION info1, info2;
|
||||
HANDLE h1, h2;
|
||||
BOOL ok = 1;
|
||||
h1 = CreateFile_utf8(f1, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
h2 = CreateFile_utf8(f2, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if(h1 == INVALID_HANDLE_VALUE || h2 == INVALID_HANDLE_VALUE)
|
||||
ok = 0;
|
||||
ok &= GetFileInformationByHandle(h1, &info1);
|
||||
ok &= GetFileInformationByHandle(h2, &info2);
|
||||
if(ok)
|
||||
same =
|
||||
info1.dwVolumeSerialNumber == info2.dwVolumeSerialNumber &&
|
||||
info1.nFileIndexHigh == info2.nFileIndexHigh &&
|
||||
info1.nFileIndexLow == info2.nFileIndexLow
|
||||
;
|
||||
if(h1 != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(h1);
|
||||
if(h2 != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(h2);
|
||||
return same;
|
||||
#else
|
||||
struct flac_stat_s s1, s2;
|
||||
return f1 && f2 && flac_stat(f1, &s1) == 0 && flac_stat(f2, &s2) == 0 && s1.st_ino == s2.st_ino && s1.st_dev == s2.st_dev;
|
||||
#endif
|
||||
}
|
||||
|
||||
FLAC__bool grabbag__file_remove_file(const char *filename)
|
||||
{
|
||||
return grabbag__file_change_stats(filename, /*read_only=*/false) && 0 == flac_unlink(filename);
|
||||
}
|
||||
|
||||
FILE *grabbag__file_get_binary_stdin(void)
|
||||
{
|
||||
/* if something breaks here it is probably due to the presence or
|
||||
* absence of an underscore before the identifiers 'setmode',
|
||||
* 'fileno', and/or 'O_BINARY'; check your system header files.
|
||||
*/
|
||||
#if defined _MSC_VER || defined __MINGW32__
|
||||
_setmode(_fileno(stdin), _O_BINARY);
|
||||
#elif defined __CYGWIN__
|
||||
/* almost certainly not needed for any modern Cygwin, but let's be safe... */
|
||||
setmode(_fileno(stdin), _O_BINARY);
|
||||
#elif defined __EMX__
|
||||
setmode(fileno(stdin), O_BINARY);
|
||||
#endif
|
||||
|
||||
return stdin;
|
||||
}
|
||||
|
||||
FILE *grabbag__file_get_binary_stdout(void)
|
||||
{
|
||||
/* if something breaks here it is probably due to the presence or
|
||||
* absence of an underscore before the identifiers 'setmode',
|
||||
* 'fileno', and/or 'O_BINARY'; check your system header files.
|
||||
*/
|
||||
#if defined _MSC_VER || defined __MINGW32__
|
||||
_setmode(_fileno(stdout), _O_BINARY);
|
||||
#elif defined __CYGWIN__
|
||||
/* almost certainly not needed for any modern Cygwin, but let's be safe... */
|
||||
setmode(_fileno(stdout), _O_BINARY);
|
||||
#elif defined __EMX__
|
||||
setmode(fileno(stdout), O_BINARY);
|
||||
#endif
|
||||
|
||||
return stdout;
|
||||
}
|
||||
228
libsdl2_mixer/external/flac-1.3.2/src/share/grabbag/grabbag_static.vcproj
vendored
Normal file
228
libsdl2_mixer/external/flac-1.3.2/src/share/grabbag/grabbag_static.vcproj
vendored
Normal file
@@ -0,0 +1,228 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="grabbag_static"
|
||||
ProjectGUID="{4cefbc81-c215-11db-8314-0800200c9a66}"
|
||||
RootNamespace="grabbag_static"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=".\include;..\..\..\include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="0"
|
||||
DisableSpecificWarnings="4267;4996"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="true"
|
||||
WholeProgramOptimization="true"
|
||||
AdditionalIncludeDirectories=".\include;..\..\..\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;FLAC__NO_DLL"
|
||||
RuntimeLibrary="0"
|
||||
BufferSecurityCheck="false"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="0"
|
||||
DisableSpecificWarnings="4267;4996"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\alloc.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\cuesheet.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\file.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\picture.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\replaygain.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\seektable.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\snprintf.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Public Header Files"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\..\include\share\grabbag.h"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="grabbag"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\..\include\share\grabbag\cuesheet.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\include\share\grabbag\file.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\include\share\grabbag\picture.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\include\share\grabbag\replaygain.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\include\share\grabbag\seektable.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
161
libsdl2_mixer/external/flac-1.3.2/src/share/grabbag/grabbag_static.vcxproj
vendored
Normal file
161
libsdl2_mixer/external/flac-1.3.2/src/share/grabbag/grabbag_static.vcxproj
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{4cefbc81-c215-11db-8314-0800200c9a66}</ProjectGuid>
|
||||
<RootNamespace>grabbag_static</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>12.0.30501.0</_ProjectFileVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CompileAs>Default</CompileAs>
|
||||
<DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CompileAs>Default</CompileAs>
|
||||
<DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;FLAC__NO_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CompileAs>Default</CompileAs>
|
||||
<DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;FLAC__NO_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CompileAs>Default</CompileAs>
|
||||
<DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="alloc.c" />
|
||||
<ClCompile Include="cuesheet.c" />
|
||||
<ClCompile Include="file.c" />
|
||||
<ClCompile Include="picture.c" />
|
||||
<ClCompile Include="replaygain.c" />
|
||||
<ClCompile Include="seektable.c" />
|
||||
<ClCompile Include="snprintf.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\include\share\grabbag.h" />
|
||||
<ClInclude Include="..\..\..\include\share\grabbag\cuesheet.h" />
|
||||
<ClInclude Include="..\..\..\include\share\grabbag\file.h" />
|
||||
<ClInclude Include="..\..\..\include\share\grabbag\picture.h" />
|
||||
<ClInclude Include="..\..\..\include\share\grabbag\replaygain.h" />
|
||||
<ClInclude Include="..\..\..\include\share\grabbag\seektable.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\libFLAC\libFLAC_static.vcxproj">
|
||||
<Project>{4cefbc84-c215-11db-8314-0800200c9a66}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\replaygain_analysis\replaygain_analysis_static.vcxproj">
|
||||
<Project>{4cefbc89-c215-11db-8314-0800200c9a66}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
62
libsdl2_mixer/external/flac-1.3.2/src/share/grabbag/grabbag_static.vcxproj.filters
vendored
Normal file
62
libsdl2_mixer/external/flac-1.3.2/src/share/grabbag/grabbag_static.vcxproj.filters
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Public Header Files">
|
||||
<UniqueIdentifier>{d4e83ff0-6406-4b76-bd64-6192e6b8e47a}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Public Header Files\grabbag">
|
||||
<UniqueIdentifier>{82df5da8-3a2c-402e-a7cd-a88de1a7be91}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="alloc.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="cuesheet.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="file.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="picture.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="replaygain.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="seektable.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="snprintf.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\include\share\grabbag.h">
|
||||
<Filter>Public Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\include\share\grabbag\cuesheet.h">
|
||||
<Filter>Public Header Files\grabbag</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\include\share\grabbag\file.h">
|
||||
<Filter>Public Header Files\grabbag</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\include\share\grabbag\picture.h">
|
||||
<Filter>Public Header Files\grabbag</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\include\share\grabbag\replaygain.h">
|
||||
<Filter>Public Header Files\grabbag</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\include\share\grabbag\seektable.h">
|
||||
<Filter>Public Header Files\grabbag</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
508
libsdl2_mixer/external/flac-1.3.2/src/share/grabbag/picture.c
vendored
Normal file
508
libsdl2_mixer/external/flac-1.3.2/src/share/grabbag/picture.c
vendored
Normal file
@@ -0,0 +1,508 @@
|
||||
/* grabbag - Convenience lib for various routines common to several tools
|
||||
* Copyright (C) 2006-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "share/alloc.h"
|
||||
#include "share/grabbag.h"
|
||||
#include "FLAC/assert.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "share/compat.h"
|
||||
#include "share/safe_str.h"
|
||||
|
||||
/* slightly different that strndup(): this always copies 'size' bytes starting from s into a NUL-terminated string. */
|
||||
static char *local__strndup_(const char *s, size_t size)
|
||||
{
|
||||
char *x = safe_malloc_add_2op_(size, /*+*/1);
|
||||
if(x) {
|
||||
memcpy(x, s, size);
|
||||
x[size] = '\0';
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
static FLAC__bool local__parse_type_(const char *s, size_t len, FLAC__StreamMetadata_Picture *picture)
|
||||
{
|
||||
size_t i;
|
||||
FLAC__uint32 val = 0;
|
||||
|
||||
picture->type = FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER;
|
||||
|
||||
if(len == 0)
|
||||
return true; /* empty string implies default to 'front cover' */
|
||||
|
||||
for(i = 0; i < len; i++) {
|
||||
if(s[i] >= '0' && s[i] <= '9')
|
||||
val = 10*val + (FLAC__uint32)(s[i] - '0');
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
if(i == len)
|
||||
picture->type = val;
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static FLAC__bool local__parse_resolution_(const char *s, size_t len, FLAC__StreamMetadata_Picture *picture)
|
||||
{
|
||||
int state = 0;
|
||||
size_t i;
|
||||
FLAC__uint32 val = 0;
|
||||
|
||||
picture->width = picture->height = picture->depth = picture->colors = 0;
|
||||
|
||||
if(len == 0)
|
||||
return true; /* empty string implies client wants to get info from the file itself */
|
||||
|
||||
for(i = 0; i < len; i++) {
|
||||
if(s[i] == 'x') {
|
||||
if(state == 0)
|
||||
picture->width = val;
|
||||
else if(state == 1)
|
||||
picture->height = val;
|
||||
else
|
||||
return false;
|
||||
state++;
|
||||
val = 0;
|
||||
}
|
||||
else if(s[i] == '/') {
|
||||
if(state == 2)
|
||||
picture->depth = val;
|
||||
else
|
||||
return false;
|
||||
state++;
|
||||
val = 0;
|
||||
}
|
||||
else if(s[i] >= '0' && s[i] <= '9')
|
||||
val = 10*val + (FLAC__uint32)(s[i] - '0');
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
if(state < 2)
|
||||
return false;
|
||||
else if(state == 2)
|
||||
picture->depth = val;
|
||||
else if(state == 3)
|
||||
picture->colors = val;
|
||||
else
|
||||
return false;
|
||||
if(picture->depth < 32 && 1u<<picture->depth < picture->colors)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static FLAC__bool local__extract_mime_type_(FLAC__StreamMetadata *obj)
|
||||
{
|
||||
if(obj->data.picture.data_length >= 8 && 0 == memcmp(obj->data.picture.data, "\x89PNG\x0d\x0a\x1a\x0a", 8))
|
||||
return FLAC__metadata_object_picture_set_mime_type(obj, "image/png", /*copy=*/true);
|
||||
else if(obj->data.picture.data_length >= 6 && (0 == memcmp(obj->data.picture.data, "GIF87a", 6) || 0 == memcmp(obj->data.picture.data, "GIF89a", 6)))
|
||||
return FLAC__metadata_object_picture_set_mime_type(obj, "image/gif", /*copy=*/true);
|
||||
else if(obj->data.picture.data_length >= 2 && 0 == memcmp(obj->data.picture.data, "\xff\xd8", 2))
|
||||
return FLAC__metadata_object_picture_set_mime_type(obj, "image/jpeg", /*copy=*/true);
|
||||
return false;
|
||||
}
|
||||
|
||||
static FLAC__bool local__extract_resolution_color_info_(FLAC__StreamMetadata_Picture *picture)
|
||||
{
|
||||
const FLAC__byte *data = picture->data;
|
||||
FLAC__uint32 len = picture->data_length;
|
||||
|
||||
if(0 == strcmp(picture->mime_type, "image/png")) {
|
||||
/* c.f. http://www.w3.org/TR/PNG/ */
|
||||
FLAC__bool need_palette = false; /* if IHDR has color_type=3, we need to also read the PLTE chunk to get the #colors */
|
||||
if(len < 8 || memcmp(data, "\x89PNG\x0d\x0a\x1a\x0a", 8))
|
||||
return false;
|
||||
/* try to find IHDR chunk */
|
||||
data += 8;
|
||||
len -= 8;
|
||||
while(len > 12) { /* every PNG chunk must be at least 12 bytes long */
|
||||
const FLAC__uint32 clen = (FLAC__uint32)data[0] << 24 | (FLAC__uint32)data[1] << 16 | (FLAC__uint32)data[2] << 8 | (FLAC__uint32)data[3];
|
||||
if(0 == memcmp(data+4, "IHDR", 4) && clen == 13) {
|
||||
unsigned color_type = data[17];
|
||||
picture->width = (FLAC__uint32)data[8] << 24 | (FLAC__uint32)data[9] << 16 | (FLAC__uint32)data[10] << 8 | (FLAC__uint32)data[11];
|
||||
picture->height = (FLAC__uint32)data[12] << 24 | (FLAC__uint32)data[13] << 16 | (FLAC__uint32)data[14] << 8 | (FLAC__uint32)data[15];
|
||||
if(color_type == 3) {
|
||||
/* even though the bit depth for color_type==3 can be 1,2,4,or 8,
|
||||
* the spec in 11.2.2 of http://www.w3.org/TR/PNG/ says that the
|
||||
* sample depth is always 8
|
||||
*/
|
||||
picture->depth = 8 * 3u;
|
||||
need_palette = true;
|
||||
data += 12 + clen;
|
||||
len -= 12 + clen;
|
||||
}
|
||||
else {
|
||||
if(color_type == 0) /* greyscale, 1 sample per pixel */
|
||||
picture->depth = (FLAC__uint32)data[16];
|
||||
if(color_type == 2) /* truecolor, 3 samples per pixel */
|
||||
picture->depth = (FLAC__uint32)data[16] * 3u;
|
||||
if(color_type == 4) /* greyscale+alpha, 2 samples per pixel */
|
||||
picture->depth = (FLAC__uint32)data[16] * 2u;
|
||||
if(color_type == 6) /* truecolor+alpha, 4 samples per pixel */
|
||||
picture->depth = (FLAC__uint32)data[16] * 4u;
|
||||
picture->colors = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if(need_palette && 0 == memcmp(data+4, "PLTE", 4)) {
|
||||
picture->colors = clen / 3u;
|
||||
return true;
|
||||
}
|
||||
else if(clen + 12 > len)
|
||||
return false;
|
||||
else {
|
||||
data += 12 + clen;
|
||||
len -= 12 + clen;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(0 == strcmp(picture->mime_type, "image/jpeg")) {
|
||||
/* c.f. http://www.w3.org/Graphics/JPEG/itu-t81.pdf and Q22 of http://www.faqs.org/faqs/jpeg-faq/part1/ */
|
||||
if(len < 2 || memcmp(data, "\xff\xd8", 2))
|
||||
return false;
|
||||
data += 2;
|
||||
len -= 2;
|
||||
while(1) {
|
||||
/* look for sync FF byte */
|
||||
for( ; len > 0; data++, len--) {
|
||||
if(*data == 0xff)
|
||||
break;
|
||||
}
|
||||
if(len == 0)
|
||||
return false;
|
||||
/* eat any extra pad FF bytes before marker */
|
||||
for( ; len > 0; data++, len--) {
|
||||
if(*data != 0xff)
|
||||
break;
|
||||
}
|
||||
if(len == 0)
|
||||
return false;
|
||||
/* if we hit SOS or EOI, bail */
|
||||
if(*data == 0xda || *data == 0xd9)
|
||||
return false;
|
||||
/* looking for some SOFn */
|
||||
else if(memchr("\xc0\xc1\xc2\xc3\xc5\xc6\xc7\xc9\xca\xcb\xcd\xce\xcf", *data, 13)) {
|
||||
data++; len--; /* skip marker byte */
|
||||
if(len < 2)
|
||||
return false;
|
||||
else {
|
||||
const FLAC__uint32 clen = (FLAC__uint32)data[0] << 8 | (FLAC__uint32)data[1];
|
||||
if(clen < 8 || len < clen)
|
||||
return false;
|
||||
picture->width = (FLAC__uint32)data[5] << 8 | (FLAC__uint32)data[6];
|
||||
picture->height = (FLAC__uint32)data[3] << 8 | (FLAC__uint32)data[4];
|
||||
picture->depth = (FLAC__uint32)data[2] * (FLAC__uint32)data[7];
|
||||
picture->colors = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/* else skip it */
|
||||
else {
|
||||
data++; len--; /* skip marker byte */
|
||||
if(len < 2)
|
||||
return false;
|
||||
else {
|
||||
const FLAC__uint32 clen = (FLAC__uint32)data[0] << 8 | (FLAC__uint32)data[1];
|
||||
if(clen < 2 || len < clen)
|
||||
return false;
|
||||
data += clen;
|
||||
len -= clen;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(0 == strcmp(picture->mime_type, "image/gif")) {
|
||||
/* c.f. http://www.w3.org/Graphics/GIF/spec-gif89a.txt */
|
||||
if(len < 14)
|
||||
return false;
|
||||
if(memcmp(data, "GIF87a", 6) && memcmp(data, "GIF89a", 6))
|
||||
return false;
|
||||
#if 0
|
||||
/* according to the GIF spec, even if the GCTF is 0, the low 3 bits should still tell the total # colors used */
|
||||
if(data[10] & 0x80 == 0)
|
||||
return false;
|
||||
#endif
|
||||
picture->width = (FLAC__uint32)data[6] | ((FLAC__uint32)data[7] << 8);
|
||||
picture->height = (FLAC__uint32)data[8] | ((FLAC__uint32)data[9] << 8);
|
||||
#if 0
|
||||
/* this value doesn't seem to be reliable... */
|
||||
picture->depth = (((FLAC__uint32)(data[10] & 0x70) >> 4) + 1) * 3u;
|
||||
#else
|
||||
/* ...just pessimistically assume it's 24-bit color without scanning all the color tables */
|
||||
picture->depth = 8u * 3u;
|
||||
#endif
|
||||
picture->colors = 1u << ((FLAC__uint32)(data[10] & 0x07) + 1u);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static const char *error_messages[] = {
|
||||
"memory allocation error",
|
||||
"invalid picture specification",
|
||||
"invalid picture specification: can't parse resolution/color part",
|
||||
"unable to extract resolution and color info from URL, user must set explicitly",
|
||||
"unable to extract resolution and color info from file, user must set explicitly",
|
||||
"error opening picture file",
|
||||
"error reading picture file",
|
||||
"invalid picture type",
|
||||
"unable to guess MIME type from file, user must set explicitly",
|
||||
"type 1 icon must be a 32x32 pixel PNG",
|
||||
"file not found", /* currently unused */
|
||||
"file is too large"
|
||||
};
|
||||
|
||||
static const char * read_file (const char * filepath, FLAC__StreamMetadata * obj)
|
||||
{
|
||||
const FLAC__off_t size = grabbag__file_get_filesize(filepath);
|
||||
FLAC__byte *buffer;
|
||||
FILE *file;
|
||||
const char *error_message=NULL;
|
||||
|
||||
if (size < 0)
|
||||
return error_messages[5];
|
||||
|
||||
if (size >= (1u << FLAC__STREAM_METADATA_LENGTH_LEN)) /* actual limit is less because of other fields in the PICTURE metadata block */
|
||||
return error_messages[11];
|
||||
|
||||
if ((buffer = safe_malloc_(size)) == NULL)
|
||||
return error_messages[0];
|
||||
|
||||
if ((file = flac_fopen(filepath, "rb")) == NULL) {
|
||||
free(buffer);
|
||||
return error_messages[5];
|
||||
}
|
||||
|
||||
if (fread(buffer, 1, size, file) != (size_t) size) {
|
||||
fclose(file);
|
||||
free(buffer);
|
||||
return error_messages[6];
|
||||
}
|
||||
fclose(file);
|
||||
|
||||
if (!FLAC__metadata_object_picture_set_data(obj, buffer, size, /*copy=*/false))
|
||||
error_message = error_messages[6];
|
||||
/* try to extract MIME type if user left it blank */
|
||||
else if (*obj->data.picture.mime_type == '\0' && !local__extract_mime_type_(obj))
|
||||
error_message = error_messages[8];
|
||||
/* try to extract resolution/color info if user left it blank */
|
||||
else if ((obj->data.picture.width == 0 || obj->data.picture.height == 0 || obj->data.picture.depth == 0) && !local__extract_resolution_color_info_(&obj->data.picture))
|
||||
error_message = error_messages[4];
|
||||
/* check metadata block size */
|
||||
else if (obj->length >= (1u << FLAC__STREAM_METADATA_LENGTH_LEN))
|
||||
error_message = error_messages[11];
|
||||
|
||||
return error_message;
|
||||
}
|
||||
|
||||
FLAC__StreamMetadata *grabbag__picture_parse_specification(const char *spec, const char **error_message)
|
||||
{
|
||||
FLAC__StreamMetadata *obj;
|
||||
int state = 0;
|
||||
|
||||
FLAC__ASSERT(0 != spec);
|
||||
FLAC__ASSERT(0 != error_message);
|
||||
|
||||
/* double protection */
|
||||
if(0 == spec)
|
||||
return 0;
|
||||
if(0 == error_message)
|
||||
return 0;
|
||||
|
||||
*error_message = 0;
|
||||
|
||||
if(0 == (obj = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PICTURE))) {
|
||||
*error_message = error_messages[0];
|
||||
return obj;
|
||||
}
|
||||
|
||||
if(strchr(spec, '|')) { /* full format */
|
||||
const char *p;
|
||||
char *q;
|
||||
for(p = spec; *error_message==0 && *p; ) {
|
||||
if(*p == '|') {
|
||||
switch(state) {
|
||||
case 0: /* type */
|
||||
if(!local__parse_type_(spec, p-spec, &obj->data.picture))
|
||||
*error_message = error_messages[7];
|
||||
break;
|
||||
case 1: /* mime type */
|
||||
if(p-spec) { /* if blank, we'll try to guess later from the picture data */
|
||||
if(0 == (q = local__strndup_(spec, p-spec)))
|
||||
*error_message = error_messages[0];
|
||||
else if(!FLAC__metadata_object_picture_set_mime_type(obj, q, /*copy=*/false))
|
||||
*error_message = error_messages[0];
|
||||
}
|
||||
break;
|
||||
case 2: /* description */
|
||||
if(0 == (q = local__strndup_(spec, p-spec)))
|
||||
*error_message = error_messages[0];
|
||||
else if(!FLAC__metadata_object_picture_set_description(obj, (FLAC__byte*)q, /*copy=*/false))
|
||||
*error_message = error_messages[0];
|
||||
break;
|
||||
case 3: /* resolution/color (e.g. [300x300x16[/1234]] */
|
||||
if(!local__parse_resolution_(spec, p-spec, &obj->data.picture))
|
||||
*error_message = error_messages[2];
|
||||
break;
|
||||
default:
|
||||
*error_message = error_messages[1];
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
spec = p;
|
||||
state++;
|
||||
}
|
||||
else
|
||||
p++;
|
||||
}
|
||||
}
|
||||
else { /* simple format, filename only, everything else guessed */
|
||||
if(!local__parse_type_("", 0, &obj->data.picture)) /* use default picture type */
|
||||
*error_message = error_messages[7];
|
||||
/* leave MIME type to be filled in later */
|
||||
/* leave description empty */
|
||||
/* leave the rest to be filled in later: */
|
||||
else if(!local__parse_resolution_("", 0, &obj->data.picture))
|
||||
*error_message = error_messages[2];
|
||||
else
|
||||
state = 4;
|
||||
}
|
||||
|
||||
/* parse filename, read file, try to extract resolution/color info if needed */
|
||||
if(*error_message == 0) {
|
||||
if(state != 4)
|
||||
*error_message = error_messages[1];
|
||||
else { /* 'spec' points to filename/URL */
|
||||
if(0 == strcmp(obj->data.picture.mime_type, "-->")) { /* magic MIME type means URL */
|
||||
if(!FLAC__metadata_object_picture_set_data(obj, (FLAC__byte*)spec, strlen(spec), /*copy=*/true))
|
||||
*error_message = error_messages[0];
|
||||
else if(obj->data.picture.width == 0 || obj->data.picture.height == 0 || obj->data.picture.depth == 0)
|
||||
*error_message = error_messages[3];
|
||||
}
|
||||
else { /* regular picture file */
|
||||
*error_message = read_file (spec, obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(*error_message == 0) {
|
||||
if(
|
||||
obj->data.picture.type == FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD &&
|
||||
(
|
||||
(strcmp(obj->data.picture.mime_type, "image/png") && strcmp(obj->data.picture.mime_type, "-->")) ||
|
||||
obj->data.picture.width != 32 ||
|
||||
obj->data.picture.height != 32
|
||||
)
|
||||
)
|
||||
*error_message = error_messages[9];
|
||||
}
|
||||
|
||||
if(*error_message && obj) {
|
||||
FLAC__metadata_object_delete(obj);
|
||||
obj = 0;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
FLAC__StreamMetadata *grabbag__picture_from_specification(int type, const char *mime_type_in, const char * description,
|
||||
const PictureResolution * res, const char * filepath, const char **error_message)
|
||||
{
|
||||
|
||||
FLAC__StreamMetadata *obj;
|
||||
char mime_type [64] ;
|
||||
|
||||
if (error_message == 0)
|
||||
return 0;
|
||||
|
||||
safe_strncpy(mime_type, mime_type_in, sizeof (mime_type));
|
||||
|
||||
*error_message = 0;
|
||||
|
||||
if ((obj = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PICTURE)) == 0) {
|
||||
*error_message = error_messages[0];
|
||||
return obj;
|
||||
}
|
||||
|
||||
/* Picture type if known. */
|
||||
obj->data.picture.type = type >= 0 ? type : FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER;
|
||||
|
||||
/* Mime type if known. */
|
||||
if (mime_type_in && ! FLAC__metadata_object_picture_set_mime_type(obj, mime_type, /*copy=*/true)) {
|
||||
*error_message = error_messages[0];
|
||||
return obj;
|
||||
}
|
||||
|
||||
/* Description if present. */
|
||||
if (description && ! FLAC__metadata_object_picture_set_description(obj, (FLAC__byte*) description, /*copy=*/true)) {
|
||||
*error_message = error_messages[0];
|
||||
return obj;
|
||||
}
|
||||
|
||||
if (res == NULL) {
|
||||
obj->data.picture.width = 0;
|
||||
obj->data.picture.height = 0;
|
||||
obj->data.picture.depth = 0;
|
||||
obj->data.picture.colors = 0;
|
||||
}
|
||||
else {
|
||||
obj->data.picture.width = res->width;
|
||||
obj->data.picture.height = res->height;
|
||||
obj->data.picture.depth = res->depth;
|
||||
obj->data.picture.colors = res->colors;
|
||||
}
|
||||
|
||||
if (strcmp(obj->data.picture.mime_type, "-->") == 0) { /* magic MIME type means URL */
|
||||
if (!FLAC__metadata_object_picture_set_data(obj, (FLAC__byte*)filepath, strlen(filepath), /*copy=*/true))
|
||||
*error_message = error_messages[0];
|
||||
else if (obj->data.picture.width == 0 || obj->data.picture.height == 0 || obj->data.picture.depth == 0)
|
||||
*error_message = error_messages[3];
|
||||
}
|
||||
else {
|
||||
*error_message = read_file (filepath, obj);
|
||||
}
|
||||
|
||||
if (*error_message == NULL) {
|
||||
if (
|
||||
obj->data.picture.type == FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD &&
|
||||
(
|
||||
(strcmp(obj->data.picture.mime_type, "image/png") && strcmp(obj->data.picture.mime_type, "-->")) ||
|
||||
obj->data.picture.width != 32 ||
|
||||
obj->data.picture.height != 32
|
||||
)
|
||||
)
|
||||
*error_message = error_messages[9];
|
||||
}
|
||||
|
||||
if (*error_message && obj) {
|
||||
FLAC__metadata_object_delete(obj);
|
||||
obj = 0;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
668
libsdl2_mixer/external/flac-1.3.2/src/share/grabbag/replaygain.c
vendored
Normal file
668
libsdl2_mixer/external/flac-1.3.2/src/share/grabbag/replaygain.c
vendored
Normal file
@@ -0,0 +1,668 @@
|
||||
/* grabbag - Convenience lib for various routines common to several tools
|
||||
* Copyright (C) 2002-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <locale.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#if defined _MSC_VER || defined __MINGW32__
|
||||
#include <io.h> /* for chmod() */
|
||||
#endif
|
||||
#include <sys/stat.h> /* for stat(), maybe chmod() */
|
||||
|
||||
#include "FLAC/assert.h"
|
||||
#include "FLAC/metadata.h"
|
||||
#include "FLAC/stream_decoder.h"
|
||||
#include "share/grabbag.h"
|
||||
#include "share/replaygain_analysis.h"
|
||||
#include "share/safe_str.h"
|
||||
|
||||
#ifdef local_min
|
||||
#undef local_min
|
||||
#endif
|
||||
#define local_min(a,b) ((a)<(b)?(a):(b))
|
||||
|
||||
#ifdef local_max
|
||||
#undef local_max
|
||||
#endif
|
||||
#define local_max(a,b) ((a)>(b)?(a):(b))
|
||||
|
||||
static const char *reference_format_ = "%s=%2.1f dB";
|
||||
static const char *gain_format_ = "%s=%+2.2f dB";
|
||||
static const char *peak_format_ = "%s=%1.8f";
|
||||
|
||||
static double album_peak_, title_peak_;
|
||||
|
||||
const unsigned GRABBAG__REPLAYGAIN_MAX_TAG_SPACE_REQUIRED = 190;
|
||||
/*
|
||||
FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN/8 + 29 + 1 + 8 +
|
||||
FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN/8 + 21 + 1 + 10 +
|
||||
FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN/8 + 21 + 1 + 12 +
|
||||
FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN/8 + 21 + 1 + 10 +
|
||||
FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN/8 + 21 + 1 + 12
|
||||
*/
|
||||
|
||||
const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_REFERENCE_LOUDNESS = (const FLAC__byte * const)"REPLAYGAIN_REFERENCE_LOUDNESS";
|
||||
const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_TITLE_GAIN = (const FLAC__byte * const)"REPLAYGAIN_TRACK_GAIN";
|
||||
const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_TITLE_PEAK = (const FLAC__byte * const)"REPLAYGAIN_TRACK_PEAK";
|
||||
const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_ALBUM_GAIN = (const FLAC__byte * const)"REPLAYGAIN_ALBUM_GAIN";
|
||||
const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_ALBUM_PEAK = (const FLAC__byte * const)"REPLAYGAIN_ALBUM_PEAK";
|
||||
|
||||
|
||||
static FLAC__bool get_file_stats_(const char *filename, struct flac_stat_s *stats)
|
||||
{
|
||||
FLAC__ASSERT(0 != filename);
|
||||
FLAC__ASSERT(0 != stats);
|
||||
return (0 == flac_stat(filename, stats));
|
||||
}
|
||||
|
||||
static void set_file_stats_(const char *filename, struct flac_stat_s *stats)
|
||||
{
|
||||
FLAC__ASSERT(0 != filename);
|
||||
FLAC__ASSERT(0 != stats);
|
||||
|
||||
(void)flac_chmod(filename, stats->st_mode);
|
||||
}
|
||||
|
||||
static FLAC__bool append_tag_(FLAC__StreamMetadata *block, const char *format, const FLAC__byte *name, float value)
|
||||
{
|
||||
char buffer[256];
|
||||
char *saved_locale;
|
||||
FLAC__StreamMetadata_VorbisComment_Entry entry;
|
||||
|
||||
FLAC__ASSERT(0 != block);
|
||||
FLAC__ASSERT(block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT);
|
||||
FLAC__ASSERT(0 != format);
|
||||
FLAC__ASSERT(0 != name);
|
||||
|
||||
buffer[sizeof(buffer)-1] = '\0';
|
||||
/*
|
||||
* We need to save the old locale and switch to "C" because the locale
|
||||
* influences the formatting of %f and we want it a certain way.
|
||||
*/
|
||||
saved_locale = strdup(setlocale(LC_ALL, 0));
|
||||
if (0 == saved_locale)
|
||||
return false;
|
||||
setlocale(LC_ALL, "C");
|
||||
flac_snprintf(buffer, sizeof(buffer), format, name, value);
|
||||
setlocale(LC_ALL, saved_locale);
|
||||
free(saved_locale);
|
||||
|
||||
entry.entry = (FLAC__byte *)buffer;
|
||||
entry.length = strlen(buffer);
|
||||
|
||||
return FLAC__metadata_object_vorbiscomment_append_comment(block, entry, /*copy=*/true);
|
||||
}
|
||||
|
||||
FLAC__bool grabbag__replaygain_is_valid_sample_frequency(unsigned sample_frequency)
|
||||
{
|
||||
return ValidGainFrequency( sample_frequency );
|
||||
}
|
||||
|
||||
FLAC__bool grabbag__replaygain_init(unsigned sample_frequency)
|
||||
{
|
||||
title_peak_ = album_peak_ = 0.0;
|
||||
return InitGainAnalysis((long)sample_frequency) == INIT_GAIN_ANALYSIS_OK;
|
||||
}
|
||||
|
||||
FLAC__bool grabbag__replaygain_analyze(const FLAC__int32 * const input[], FLAC__bool is_stereo, unsigned bps, unsigned samples)
|
||||
{
|
||||
/* using a small buffer improves data locality; we'd like it to fit easily in the dcache */
|
||||
static flac_float_t lbuffer[2048], rbuffer[2048];
|
||||
static const unsigned nbuffer = sizeof(lbuffer) / sizeof(lbuffer[0]);
|
||||
FLAC__int32 block_peak = 0, s;
|
||||
unsigned i, j;
|
||||
|
||||
FLAC__ASSERT(bps >= 4 && bps <= FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE);
|
||||
FLAC__ASSERT(FLAC__MIN_BITS_PER_SAMPLE == 4);
|
||||
/*
|
||||
* We use abs() on a FLAC__int32 which is undefined for the most negative value.
|
||||
* If the reference codec ever handles 32bps we will have to write a special
|
||||
* case here.
|
||||
*/
|
||||
FLAC__ASSERT(FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE < 32);
|
||||
|
||||
if(bps == 16) {
|
||||
if(is_stereo) {
|
||||
j = 0;
|
||||
while(samples > 0) {
|
||||
const unsigned n = local_min(samples, nbuffer);
|
||||
for(i = 0; i < n; i++, j++) {
|
||||
s = input[0][j];
|
||||
lbuffer[i] = (flac_float_t)s;
|
||||
s = abs(s);
|
||||
block_peak = local_max(block_peak, s);
|
||||
|
||||
s = input[1][j];
|
||||
rbuffer[i] = (flac_float_t)s;
|
||||
s = abs(s);
|
||||
block_peak = local_max(block_peak, s);
|
||||
}
|
||||
samples -= n;
|
||||
if(AnalyzeSamples(lbuffer, rbuffer, n, 2) != GAIN_ANALYSIS_OK)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
j = 0;
|
||||
while(samples > 0) {
|
||||
const unsigned n = local_min(samples, nbuffer);
|
||||
for(i = 0; i < n; i++, j++) {
|
||||
s = input[0][j];
|
||||
lbuffer[i] = (flac_float_t)s;
|
||||
s = abs(s);
|
||||
block_peak = local_max(block_peak, s);
|
||||
}
|
||||
samples -= n;
|
||||
if(AnalyzeSamples(lbuffer, 0, n, 1) != GAIN_ANALYSIS_OK)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else { /* bps must be < 32 according to above assertion */
|
||||
const double scale = (
|
||||
(bps > 16)?
|
||||
(double)1. / (double)(1u << (bps - 16)) :
|
||||
(double)(1u << (16 - bps))
|
||||
);
|
||||
|
||||
if(is_stereo) {
|
||||
j = 0;
|
||||
while(samples > 0) {
|
||||
const unsigned n = local_min(samples, nbuffer);
|
||||
for(i = 0; i < n; i++, j++) {
|
||||
s = input[0][j];
|
||||
lbuffer[i] = (flac_float_t)(scale * (double)s);
|
||||
s = abs(s);
|
||||
block_peak = local_max(block_peak, s);
|
||||
|
||||
s = input[1][j];
|
||||
rbuffer[i] = (flac_float_t)(scale * (double)s);
|
||||
s = abs(s);
|
||||
block_peak = local_max(block_peak, s);
|
||||
}
|
||||
samples -= n;
|
||||
if(AnalyzeSamples(lbuffer, rbuffer, n, 2) != GAIN_ANALYSIS_OK)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
j = 0;
|
||||
while(samples > 0) {
|
||||
const unsigned n = local_min(samples, nbuffer);
|
||||
for(i = 0; i < n; i++, j++) {
|
||||
s = input[0][j];
|
||||
lbuffer[i] = (flac_float_t)(scale * (double)s);
|
||||
s = abs(s);
|
||||
block_peak = local_max(block_peak, s);
|
||||
}
|
||||
samples -= n;
|
||||
if(AnalyzeSamples(lbuffer, 0, n, 1) != GAIN_ANALYSIS_OK)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const double peak_scale = (double)(1u << (bps - 1));
|
||||
double peak = (double)block_peak / peak_scale;
|
||||
if(peak > title_peak_)
|
||||
title_peak_ = peak;
|
||||
if(peak > album_peak_)
|
||||
album_peak_ = peak;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void grabbag__replaygain_get_album(float *gain, float *peak)
|
||||
{
|
||||
*gain = (float)GetAlbumGain();
|
||||
*peak = (float)album_peak_;
|
||||
album_peak_ = 0.0;
|
||||
}
|
||||
|
||||
void grabbag__replaygain_get_title(float *gain, float *peak)
|
||||
{
|
||||
*gain = (float)GetTitleGain();
|
||||
*peak = (float)title_peak_;
|
||||
title_peak_ = 0.0;
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned channels;
|
||||
unsigned bits_per_sample;
|
||||
unsigned sample_rate;
|
||||
FLAC__bool error;
|
||||
} DecoderInstance;
|
||||
|
||||
static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
|
||||
{
|
||||
DecoderInstance *instance = (DecoderInstance*)client_data;
|
||||
const unsigned bits_per_sample = frame->header.bits_per_sample;
|
||||
const unsigned channels = frame->header.channels;
|
||||
const unsigned sample_rate = frame->header.sample_rate;
|
||||
const unsigned samples = frame->header.blocksize;
|
||||
|
||||
(void)decoder;
|
||||
|
||||
if(
|
||||
!instance->error &&
|
||||
(channels == 2 || channels == 1) &&
|
||||
bits_per_sample == instance->bits_per_sample &&
|
||||
channels == instance->channels &&
|
||||
sample_rate == instance->sample_rate
|
||||
) {
|
||||
instance->error = !grabbag__replaygain_analyze(buffer, channels==2, bits_per_sample, samples);
|
||||
}
|
||||
else {
|
||||
instance->error = true;
|
||||
}
|
||||
|
||||
if(!instance->error)
|
||||
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
|
||||
else
|
||||
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
|
||||
}
|
||||
|
||||
static void metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
|
||||
{
|
||||
DecoderInstance *instance = (DecoderInstance*)client_data;
|
||||
|
||||
(void)decoder;
|
||||
|
||||
if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
|
||||
instance->bits_per_sample = metadata->data.stream_info.bits_per_sample;
|
||||
instance->channels = metadata->data.stream_info.channels;
|
||||
instance->sample_rate = metadata->data.stream_info.sample_rate;
|
||||
|
||||
if(instance->channels != 1 && instance->channels != 2) {
|
||||
instance->error = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if(!grabbag__replaygain_is_valid_sample_frequency(instance->sample_rate)) {
|
||||
instance->error = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
|
||||
{
|
||||
DecoderInstance *instance = (DecoderInstance*)client_data;
|
||||
|
||||
(void)decoder, (void)status;
|
||||
|
||||
instance->error = true;
|
||||
}
|
||||
|
||||
const char *grabbag__replaygain_analyze_file(const char *filename, float *title_gain, float *title_peak)
|
||||
{
|
||||
DecoderInstance instance;
|
||||
FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new();
|
||||
|
||||
if(0 == decoder)
|
||||
return "memory allocation error";
|
||||
|
||||
instance.error = false;
|
||||
|
||||
/* It does these three by default but lets be explicit: */
|
||||
FLAC__stream_decoder_set_md5_checking(decoder, false);
|
||||
FLAC__stream_decoder_set_metadata_ignore_all(decoder);
|
||||
FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_STREAMINFO);
|
||||
|
||||
if(FLAC__stream_decoder_init_file(decoder, filename, write_callback_, metadata_callback_, error_callback_, &instance) != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
|
||||
FLAC__stream_decoder_delete(decoder);
|
||||
return "initializing decoder";
|
||||
}
|
||||
|
||||
if(!FLAC__stream_decoder_process_until_end_of_stream(decoder) || instance.error) {
|
||||
FLAC__stream_decoder_delete(decoder);
|
||||
return "decoding file";
|
||||
}
|
||||
|
||||
FLAC__stream_decoder_delete(decoder);
|
||||
|
||||
grabbag__replaygain_get_title(title_gain, title_peak);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *grabbag__replaygain_store_to_vorbiscomment(FLAC__StreamMetadata *block, float album_gain, float album_peak, float title_gain, float title_peak)
|
||||
{
|
||||
const char *error;
|
||||
|
||||
if(0 != (error = grabbag__replaygain_store_to_vorbiscomment_reference(block)))
|
||||
return error;
|
||||
|
||||
if(0 != (error = grabbag__replaygain_store_to_vorbiscomment_title(block, title_gain, title_peak)))
|
||||
return error;
|
||||
|
||||
if(0 != (error = grabbag__replaygain_store_to_vorbiscomment_album(block, album_gain, album_peak)))
|
||||
return error;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *grabbag__replaygain_store_to_vorbiscomment_reference(FLAC__StreamMetadata *block)
|
||||
{
|
||||
FLAC__ASSERT(0 != block);
|
||||
FLAC__ASSERT(block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT);
|
||||
|
||||
if(FLAC__metadata_object_vorbiscomment_remove_entries_matching(block, (const char *)GRABBAG__REPLAYGAIN_TAG_REFERENCE_LOUDNESS) < 0)
|
||||
return "memory allocation error";
|
||||
|
||||
if(!append_tag_(block, reference_format_, GRABBAG__REPLAYGAIN_TAG_REFERENCE_LOUDNESS, ReplayGainReferenceLoudness))
|
||||
return "memory allocation error";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *grabbag__replaygain_store_to_vorbiscomment_album(FLAC__StreamMetadata *block, float album_gain, float album_peak)
|
||||
{
|
||||
FLAC__ASSERT(0 != block);
|
||||
FLAC__ASSERT(block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT);
|
||||
|
||||
if(
|
||||
FLAC__metadata_object_vorbiscomment_remove_entries_matching(block, (const char *)GRABBAG__REPLAYGAIN_TAG_ALBUM_GAIN) < 0 ||
|
||||
FLAC__metadata_object_vorbiscomment_remove_entries_matching(block, (const char *)GRABBAG__REPLAYGAIN_TAG_ALBUM_PEAK) < 0
|
||||
)
|
||||
return "memory allocation error";
|
||||
|
||||
if(
|
||||
!append_tag_(block, gain_format_, GRABBAG__REPLAYGAIN_TAG_ALBUM_GAIN, album_gain) ||
|
||||
!append_tag_(block, peak_format_, GRABBAG__REPLAYGAIN_TAG_ALBUM_PEAK, album_peak)
|
||||
)
|
||||
return "memory allocation error";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *grabbag__replaygain_store_to_vorbiscomment_title(FLAC__StreamMetadata *block, float title_gain, float title_peak)
|
||||
{
|
||||
FLAC__ASSERT(0 != block);
|
||||
FLAC__ASSERT(block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT);
|
||||
|
||||
if(
|
||||
FLAC__metadata_object_vorbiscomment_remove_entries_matching(block, (const char *)GRABBAG__REPLAYGAIN_TAG_TITLE_GAIN) < 0 ||
|
||||
FLAC__metadata_object_vorbiscomment_remove_entries_matching(block, (const char *)GRABBAG__REPLAYGAIN_TAG_TITLE_PEAK) < 0
|
||||
)
|
||||
return "memory allocation error";
|
||||
|
||||
if(
|
||||
!append_tag_(block, gain_format_, GRABBAG__REPLAYGAIN_TAG_TITLE_GAIN, title_gain) ||
|
||||
!append_tag_(block, peak_format_, GRABBAG__REPLAYGAIN_TAG_TITLE_PEAK, title_peak)
|
||||
)
|
||||
return "memory allocation error";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *store_to_file_pre_(const char *filename, FLAC__Metadata_Chain **chain, FLAC__StreamMetadata **block)
|
||||
{
|
||||
FLAC__Metadata_Iterator *iterator;
|
||||
const char *error;
|
||||
FLAC__bool found_vc_block = false;
|
||||
|
||||
if(0 == (*chain = FLAC__metadata_chain_new()))
|
||||
return "memory allocation error";
|
||||
|
||||
if(!FLAC__metadata_chain_read(*chain, filename)) {
|
||||
error = FLAC__Metadata_ChainStatusString[FLAC__metadata_chain_status(*chain)];
|
||||
FLAC__metadata_chain_delete(*chain);
|
||||
return error;
|
||||
}
|
||||
|
||||
if(0 == (iterator = FLAC__metadata_iterator_new())) {
|
||||
FLAC__metadata_chain_delete(*chain);
|
||||
return "memory allocation error";
|
||||
}
|
||||
|
||||
FLAC__metadata_iterator_init(iterator, *chain);
|
||||
|
||||
do {
|
||||
*block = FLAC__metadata_iterator_get_block(iterator);
|
||||
if((*block)->type == FLAC__METADATA_TYPE_VORBIS_COMMENT)
|
||||
found_vc_block = true;
|
||||
} while(!found_vc_block && FLAC__metadata_iterator_next(iterator));
|
||||
|
||||
if(!found_vc_block) {
|
||||
/* create a new block */
|
||||
*block = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT);
|
||||
if(0 == *block) {
|
||||
FLAC__metadata_chain_delete(*chain);
|
||||
FLAC__metadata_iterator_delete(iterator);
|
||||
return "memory allocation error";
|
||||
}
|
||||
while(FLAC__metadata_iterator_next(iterator))
|
||||
;
|
||||
if(!FLAC__metadata_iterator_insert_block_after(iterator, *block)) {
|
||||
error = FLAC__Metadata_ChainStatusString[FLAC__metadata_chain_status(*chain)];
|
||||
FLAC__metadata_chain_delete(*chain);
|
||||
FLAC__metadata_iterator_delete(iterator);
|
||||
return error;
|
||||
}
|
||||
/* iterator is left pointing to new block */
|
||||
FLAC__ASSERT(FLAC__metadata_iterator_get_block(iterator) == *block);
|
||||
}
|
||||
|
||||
FLAC__metadata_iterator_delete(iterator);
|
||||
|
||||
FLAC__ASSERT(0 != *block);
|
||||
FLAC__ASSERT((*block)->type == FLAC__METADATA_TYPE_VORBIS_COMMENT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *store_to_file_post_(const char *filename, FLAC__Metadata_Chain *chain, FLAC__bool preserve_modtime)
|
||||
{
|
||||
struct flac_stat_s stats;
|
||||
const FLAC__bool have_stats = get_file_stats_(filename, &stats);
|
||||
|
||||
(void)grabbag__file_change_stats(filename, /*read_only=*/false);
|
||||
|
||||
FLAC__metadata_chain_sort_padding(chain);
|
||||
if(!FLAC__metadata_chain_write(chain, /*use_padding=*/true, preserve_modtime)) {
|
||||
const char *error;
|
||||
error = FLAC__Metadata_ChainStatusString[FLAC__metadata_chain_status(chain)];
|
||||
FLAC__metadata_chain_delete(chain);
|
||||
return error;
|
||||
}
|
||||
|
||||
FLAC__metadata_chain_delete(chain);
|
||||
|
||||
if(have_stats)
|
||||
set_file_stats_(filename, &stats);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *grabbag__replaygain_store_to_file(const char *filename, float album_gain, float album_peak, float title_gain, float title_peak, FLAC__bool preserve_modtime)
|
||||
{
|
||||
FLAC__Metadata_Chain *chain;
|
||||
FLAC__StreamMetadata *block = NULL;
|
||||
const char *error;
|
||||
|
||||
if(0 != (error = store_to_file_pre_(filename, &chain, &block)))
|
||||
return error;
|
||||
|
||||
if(0 != (error = grabbag__replaygain_store_to_vorbiscomment(block, album_gain, album_peak, title_gain, title_peak))) {
|
||||
FLAC__metadata_chain_delete(chain);
|
||||
return error;
|
||||
}
|
||||
|
||||
if(0 != (error = store_to_file_post_(filename, chain, preserve_modtime)))
|
||||
return error;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *grabbag__replaygain_store_to_file_reference(const char *filename, FLAC__bool preserve_modtime)
|
||||
{
|
||||
FLAC__Metadata_Chain *chain;
|
||||
FLAC__StreamMetadata *block = NULL;
|
||||
const char *error;
|
||||
|
||||
if(0 != (error = store_to_file_pre_(filename, &chain, &block)))
|
||||
return error;
|
||||
|
||||
if(0 != (error = grabbag__replaygain_store_to_vorbiscomment_reference(block))) {
|
||||
FLAC__metadata_chain_delete(chain);
|
||||
return error;
|
||||
}
|
||||
|
||||
if(0 != (error = store_to_file_post_(filename, chain, preserve_modtime)))
|
||||
return error;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *grabbag__replaygain_store_to_file_album(const char *filename, float album_gain, float album_peak, FLAC__bool preserve_modtime)
|
||||
{
|
||||
FLAC__Metadata_Chain *chain;
|
||||
FLAC__StreamMetadata *block = NULL;
|
||||
const char *error;
|
||||
|
||||
if(0 != (error = store_to_file_pre_(filename, &chain, &block)))
|
||||
return error;
|
||||
|
||||
if(0 != (error = grabbag__replaygain_store_to_vorbiscomment_album(block, album_gain, album_peak))) {
|
||||
FLAC__metadata_chain_delete(chain);
|
||||
return error;
|
||||
}
|
||||
|
||||
if(0 != (error = store_to_file_post_(filename, chain, preserve_modtime)))
|
||||
return error;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *grabbag__replaygain_store_to_file_title(const char *filename, float title_gain, float title_peak, FLAC__bool preserve_modtime)
|
||||
{
|
||||
FLAC__Metadata_Chain *chain;
|
||||
FLAC__StreamMetadata *block = NULL;
|
||||
const char *error;
|
||||
|
||||
if(0 != (error = store_to_file_pre_(filename, &chain, &block)))
|
||||
return error;
|
||||
|
||||
if(0 != (error = grabbag__replaygain_store_to_vorbiscomment_title(block, title_gain, title_peak))) {
|
||||
FLAC__metadata_chain_delete(chain);
|
||||
return error;
|
||||
}
|
||||
|
||||
if(0 != (error = store_to_file_post_(filename, chain, preserve_modtime)))
|
||||
return error;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FLAC__bool parse_double_(const FLAC__StreamMetadata_VorbisComment_Entry *entry, double *val)
|
||||
{
|
||||
char s[32], *end;
|
||||
const char *p, *q;
|
||||
double v;
|
||||
|
||||
FLAC__ASSERT(0 != entry);
|
||||
FLAC__ASSERT(0 != val);
|
||||
|
||||
p = (const char *)entry->entry;
|
||||
q = strchr(p, '=');
|
||||
if(0 == q)
|
||||
return false;
|
||||
q++;
|
||||
safe_strncpy(s, q, local_min(sizeof(s), (size_t) (entry->length - (q-p))));
|
||||
|
||||
v = strtod(s, &end);
|
||||
if(end == s)
|
||||
return false;
|
||||
|
||||
*val = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC__bool grabbag__replaygain_load_from_vorbiscomment(const FLAC__StreamMetadata *block, FLAC__bool album_mode, FLAC__bool strict, double *reference, double *gain, double *peak)
|
||||
{
|
||||
int reference_offset, gain_offset, peak_offset;
|
||||
char *saved_locale;
|
||||
FLAC__bool res = true;
|
||||
|
||||
FLAC__ASSERT(0 != block);
|
||||
FLAC__ASSERT(0 != reference);
|
||||
FLAC__ASSERT(0 != gain);
|
||||
FLAC__ASSERT(0 != peak);
|
||||
FLAC__ASSERT(block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT);
|
||||
|
||||
/* Default to current level until overridden by a detected tag; this
|
||||
* will always be true until we change replaygain_analysis.c
|
||||
*/
|
||||
*reference = ReplayGainReferenceLoudness;
|
||||
|
||||
/*
|
||||
* We need to save the old locale and switch to "C" because the locale
|
||||
* influences the behaviour of strtod and we want it a certain way.
|
||||
*/
|
||||
saved_locale = strdup(setlocale(LC_ALL, 0));
|
||||
if (0 == saved_locale)
|
||||
return false;
|
||||
setlocale(LC_ALL, "C");
|
||||
|
||||
if(0 <= (reference_offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block, /*offset=*/0, (const char *)GRABBAG__REPLAYGAIN_TAG_REFERENCE_LOUDNESS)))
|
||||
(void)parse_double_(block->data.vorbis_comment.comments + reference_offset, reference);
|
||||
|
||||
if(0 > (gain_offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block, /*offset=*/0, (const char *)(album_mode? GRABBAG__REPLAYGAIN_TAG_ALBUM_GAIN : GRABBAG__REPLAYGAIN_TAG_TITLE_GAIN))))
|
||||
res = false;
|
||||
if(0 > (peak_offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block, /*offset=*/0, (const char *)(album_mode? GRABBAG__REPLAYGAIN_TAG_ALBUM_PEAK : GRABBAG__REPLAYGAIN_TAG_TITLE_PEAK))))
|
||||
res = false;
|
||||
|
||||
if(res && !parse_double_(block->data.vorbis_comment.comments + gain_offset, gain))
|
||||
res = false;
|
||||
if(res && !parse_double_(block->data.vorbis_comment.comments + peak_offset, peak))
|
||||
res = false;
|
||||
|
||||
setlocale(LC_ALL, saved_locale);
|
||||
free(saved_locale);
|
||||
|
||||
/* something failed; retry with strict */
|
||||
if (!res && !strict)
|
||||
res = grabbag__replaygain_load_from_vorbiscomment(block, !album_mode, /*strict=*/true, reference, gain, peak);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
double grabbag__replaygain_compute_scale_factor(double peak, double gain, double preamp, FLAC__bool prevent_clipping)
|
||||
{
|
||||
double scale;
|
||||
FLAC__ASSERT(peak >= 0.0);
|
||||
gain += preamp;
|
||||
scale = (float) pow(10.0, gain * 0.05);
|
||||
if(prevent_clipping && peak > 0.0) {
|
||||
const double max_scale = (float)(1.0 / peak);
|
||||
if(scale > max_scale)
|
||||
scale = max_scale;
|
||||
}
|
||||
return scale;
|
||||
}
|
||||
106
libsdl2_mixer/external/flac-1.3.2/src/share/grabbag/seektable.c
vendored
Normal file
106
libsdl2_mixer/external/flac-1.3.2/src/share/grabbag/seektable.c
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
/* grabbag - Convenience lib for various routines common to several tools
|
||||
* Copyright (C) 2002-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "share/grabbag.h"
|
||||
#include "share/compat.h"
|
||||
#include "FLAC/assert.h"
|
||||
#include <stdlib.h> /* for atoi() */
|
||||
#include <string.h>
|
||||
|
||||
FLAC__bool grabbag__seektable_convert_specification_to_template(const char *spec, FLAC__bool only_explicit_placeholders, FLAC__uint64 total_samples_to_encode, unsigned sample_rate, FLAC__StreamMetadata *seektable_template, FLAC__bool *spec_has_real_points)
|
||||
{
|
||||
unsigned i;
|
||||
const char *pt;
|
||||
|
||||
FLAC__ASSERT(0 != spec);
|
||||
FLAC__ASSERT(0 != seektable_template);
|
||||
FLAC__ASSERT(seektable_template->type == FLAC__METADATA_TYPE_SEEKTABLE);
|
||||
|
||||
if(0 != spec_has_real_points)
|
||||
*spec_has_real_points = false;
|
||||
|
||||
for(pt = spec, i = 0; pt && *pt; i++) {
|
||||
const char *q = strchr(pt, ';');
|
||||
FLAC__ASSERT(0 != q);
|
||||
|
||||
if(q > pt) {
|
||||
if(0 == strncmp(pt, "X;", 2)) { /* -S X */
|
||||
if(!FLAC__metadata_object_seektable_template_append_placeholders(seektable_template, 1))
|
||||
return false;
|
||||
}
|
||||
else if(q[-1] == 'x') { /* -S #x */
|
||||
if(total_samples_to_encode > 0) { /* we can only do these if we know the number of samples to encode up front */
|
||||
if(0 != spec_has_real_points)
|
||||
*spec_has_real_points = true;
|
||||
if(!only_explicit_placeholders) {
|
||||
const int n = (unsigned)atoi(pt);
|
||||
if(n > 0)
|
||||
if(!FLAC__metadata_object_seektable_template_append_spaced_points(seektable_template, (unsigned)n, total_samples_to_encode))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(q[-1] == 's') { /* -S #s */
|
||||
if(total_samples_to_encode > 0) { /* we can only do these if we know the number of samples to encode up front */
|
||||
FLAC__ASSERT(sample_rate > 0);
|
||||
if(0 != spec_has_real_points)
|
||||
*spec_has_real_points = true;
|
||||
if(!only_explicit_placeholders) {
|
||||
const double sec = atof(pt);
|
||||
if(sec > 0.0) {
|
||||
unsigned samples = (unsigned)(sec * (double)sample_rate);
|
||||
/* Restrict seekpoints to two per second of audio. */
|
||||
samples = samples < sample_rate / 2 ? sample_rate / 2 : samples;
|
||||
if(samples > 0) {
|
||||
/* +1 for the initial point at sample 0 */
|
||||
if(!FLAC__metadata_object_seektable_template_append_spaced_points_by_samples(seektable_template, samples, total_samples_to_encode))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else { /* -S # */
|
||||
if(0 != spec_has_real_points)
|
||||
*spec_has_real_points = true;
|
||||
if(!only_explicit_placeholders) {
|
||||
char *endptr;
|
||||
const FLAC__int64 n = (FLAC__int64)strtoll(pt, &endptr, 10);
|
||||
if(
|
||||
(n > 0 || (endptr > pt && *endptr == ';')) && /* is a valid number (extra check needed for "0") */
|
||||
(total_samples_to_encode == 0 || (FLAC__uint64)n < total_samples_to_encode) /* number is not >= the known total_samples_to_encode */
|
||||
)
|
||||
if(!FLAC__metadata_object_seektable_template_append_point(seektable_template, (FLAC__uint64)n))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pt = ++q;
|
||||
}
|
||||
|
||||
if(!FLAC__metadata_object_seektable_template_sort(seektable_template, /*compact=*/true))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
101
libsdl2_mixer/external/flac-1.3.2/src/share/grabbag/snprintf.c
vendored
Normal file
101
libsdl2_mixer/external/flac-1.3.2/src/share/grabbag/snprintf.c
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
/* grabbag - Convenience lib for various routines common to several tools
|
||||
* Copyright (C) 2013-2016 Xiph.org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "share/compat.h"
|
||||
|
||||
/*
|
||||
* FLAC needs to compile and work correctly on systems with a normal ISO C99
|
||||
* snprintf as well as Microsoft Visual Studio which has an non-standards
|
||||
* conformant snprint_s function.
|
||||
*
|
||||
* The important difference occurs when the resultant string (plus string
|
||||
* terminator) would have been longer than the supplied size parameter. When
|
||||
* this happens, ISO C's snprintf returns the length of resultant string, but
|
||||
* does not over-write the end of the buffer. MS's snprintf_s in this case
|
||||
* returns -1.
|
||||
*
|
||||
* The _MSC_VER code below attempts to modify the return code for vsnprintf_s
|
||||
* to something that is more compatible with the behaviour of the ISO C version.
|
||||
*/
|
||||
|
||||
int
|
||||
flac_snprintf(char *str, size_t size, const char *fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
int rc;
|
||||
|
||||
#if defined _MSC_VER
|
||||
if (size == 0)
|
||||
return 1024;
|
||||
#endif
|
||||
|
||||
va_start (va, fmt);
|
||||
|
||||
#if defined _MSC_VER
|
||||
rc = vsnprintf_s (str, size, _TRUNCATE, fmt, va);
|
||||
if (rc < 0)
|
||||
rc = size - 1;
|
||||
#elif defined __MINGW32__
|
||||
rc = __mingw_vsnprintf (str, size, fmt, va);
|
||||
#else
|
||||
rc = vsnprintf (str, size, fmt, va);
|
||||
#endif
|
||||
va_end (va);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
flac_vsnprintf(char *str, size_t size, const char *fmt, va_list va)
|
||||
{
|
||||
int rc;
|
||||
|
||||
#if defined _MSC_VER
|
||||
if (size == 0)
|
||||
return 1024;
|
||||
rc = vsnprintf_s (str, size, _TRUNCATE, fmt, va);
|
||||
if (rc < 0)
|
||||
rc = size - 1;
|
||||
#elif defined __MINGW32__
|
||||
rc = __mingw_vsnprintf (str, size, fmt, va);
|
||||
#else
|
||||
rc = vsnprintf (str, size, fmt, va);
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
Reference in New Issue
Block a user