Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Xiph.Org
flac
Commits
4b279f76
Commit
4b279f76
authored
Aug 14, 2007
by
Josh Coalson
Browse files
initial support for new --keep-foreign-metadata options, saving done, restoring TODO
parent
be2434fd
Changes
9
Expand all
Hide whitespace changes
Inline
Side-by-side
src/flac/Makefile.am
View file @
4b279f76
...
...
@@ -28,6 +28,7 @@ flac_SOURCES = \
analyze.c
\
decode.c
\
encode.c
\
foreign_metadata.c
\
main.c
\
local_string_utils.c
\
utils.c
\
...
...
@@ -35,6 +36,7 @@ flac_SOURCES = \
analyze.h
\
decode.h
\
encode.h
\
foreign_metadata.h
\
local_string_utils.h
\
utils.h
\
vorbiscomment.h
...
...
src/flac/Makefile.lite
View file @
4b279f76
...
...
@@ -36,6 +36,7 @@ SRCS_C = \
analyze.c
\
decode.c
\
encode.c
\
foreign_metadata.c
\
local_string_utils.c
\
main.c
\
utils.c
\
...
...
src/flac/decode.c
View file @
4b279f76
...
...
@@ -45,6 +45,8 @@
typedef
struct
{
#if FLAC__HAS_OGG
FLAC__bool
is_ogg
;
FLAC__bool
use_first_serial_number
;
long
serial_number
;
#endif
FLAC__bool
is_aiff_out
;
...
...
@@ -94,6 +96,8 @@ typedef struct {
FLAC__StreamDecoder
*
decoder
;
FILE
*
fout
;
foreign_metadata_t
*
foreign_metadata
;
/* NULL unless --keep-foreign-metadata requested */
}
DecoderSession
;
...
...
@@ -103,9 +107,9 @@ static FLAC__bool is_big_endian_host_;
/*
* local routines
*/
static
FLAC__bool
DecoderSession_construct
(
DecoderSession
*
d
,
FLAC__bool
is_ogg
,
FLAC__bool
is_aiff_out
,
FLAC__bool
is_wave_out
,
FLAC__bool
treat_warnings_as_errors
,
FLAC__bool
continue_through_decode_errors
,
FLAC__bool
channel_map_none
,
replaygain_synthesis_spec_t
replaygain_synthesis_spec
,
FLAC__bool
analysis_mode
,
analysis_options
aopts
,
utils__SkipUntilSpecification
*
skip_specification
,
utils__SkipUntilSpecification
*
until_specification
,
utils__CueSpecification
*
cue_specification
,
const
char
*
infilename
,
const
char
*
outfilename
);
static
FLAC__bool
DecoderSession_construct
(
DecoderSession
*
d
,
FLAC__bool
is_ogg
,
FLAC__bool
use_first_serial_number
,
long
serial_number
,
FLAC__bool
is_aiff_out
,
FLAC__bool
is_wave_out
,
FLAC__bool
treat_warnings_as_errors
,
FLAC__bool
continue_through_decode_errors
,
FLAC__bool
channel_map_none
,
replaygain_synthesis_spec_t
replaygain_synthesis_spec
,
FLAC__bool
analysis_mode
,
analysis_options
aopts
,
utils__SkipUntilSpecification
*
skip_specification
,
utils__SkipUntilSpecification
*
until_specification
,
utils__CueSpecification
*
cue_specification
,
foreign_metadata_t
*
foreign_metadata
,
const
char
*
infilename
,
const
char
*
outfilename
);
static
void
DecoderSession_destroy
(
DecoderSession
*
d
,
FLAC__bool
error_occurred
);
static
FLAC__bool
DecoderSession_init_decoder
(
DecoderSession
*
d
,
decode_options_t
decode_options
,
const
char
*
infilename
);
static
FLAC__bool
DecoderSession_init_decoder
(
DecoderSession
*
d
,
const
char
*
infilename
);
static
FLAC__bool
DecoderSession_process
(
DecoderSession
*
d
);
static
int
DecoderSession_finish_ok
(
DecoderSession
*
d
);
static
int
DecoderSession_finish_error
(
DecoderSession
*
d
);
...
...
@@ -137,8 +141,12 @@ int flac__decode_aiff(const char *infilename, const char *outfilename, FLAC__boo
&
decoder_session
,
#if FLAC__HAS_OGG
options
.
common
.
is_ogg
,
options
.
common
.
use_first_serial_number
,
options
.
common
.
serial_number
,
#else
/*is_ogg=*/
false
,
/*use_first_serial_number=*/
false
,
/*serial_number=*/
0
,
#endif
/*is_aiff_out=*/
true
,
/*is_wave_out=*/
false
,
...
...
@@ -151,13 +159,14 @@ int flac__decode_aiff(const char *infilename, const char *outfilename, FLAC__boo
&
options
.
common
.
skip_specification
,
&
options
.
common
.
until_specification
,
options
.
common
.
has_cue_specification
?
&
options
.
common
.
cue_specification
:
0
,
options
.
foreign_metadata
,
infilename
,
outfilename
)
)
return
1
;
if
(
!
DecoderSession_init_decoder
(
&
decoder_session
,
options
.
common
,
infilename
))
if
(
!
DecoderSession_init_decoder
(
&
decoder_session
,
infilename
))
return
DecoderSession_finish_error
(
&
decoder_session
);
if
(
!
DecoderSession_process
(
&
decoder_session
))
...
...
@@ -175,8 +184,12 @@ int flac__decode_wav(const char *infilename, const char *outfilename, FLAC__bool
&
decoder_session
,
#if FLAC__HAS_OGG
options
.
common
.
is_ogg
,
options
.
common
.
use_first_serial_number
,
options
.
common
.
serial_number
,
#else
/*is_ogg=*/
false
,
/*use_first_serial_number=*/
false
,
/*serial_number=*/
0
,
#endif
/*is_aiff_out=*/
false
,
/*is_wave_out=*/
true
,
...
...
@@ -189,13 +202,14 @@ int flac__decode_wav(const char *infilename, const char *outfilename, FLAC__bool
&
options
.
common
.
skip_specification
,
&
options
.
common
.
until_specification
,
options
.
common
.
has_cue_specification
?
&
options
.
common
.
cue_specification
:
0
,
options
.
foreign_metadata
,
infilename
,
outfilename
)
)
return
1
;
if
(
!
DecoderSession_init_decoder
(
&
decoder_session
,
options
.
common
,
infilename
))
if
(
!
DecoderSession_init_decoder
(
&
decoder_session
,
infilename
))
return
DecoderSession_finish_error
(
&
decoder_session
);
if
(
!
DecoderSession_process
(
&
decoder_session
))
...
...
@@ -216,8 +230,12 @@ int flac__decode_raw(const char *infilename, const char *outfilename, FLAC__bool
&
decoder_session
,
#if FLAC__HAS_OGG
options
.
common
.
is_ogg
,
options
.
common
.
use_first_serial_number
,
options
.
common
.
serial_number
,
#else
/*is_ogg=*/
false
,
/*use_first_serial_number=*/
false
,
/*serial_number=*/
0
,
#endif
/*is_aiff_out=*/
false
,
/*is_wave_out=*/
false
,
...
...
@@ -230,13 +248,14 @@ int flac__decode_raw(const char *infilename, const char *outfilename, FLAC__bool
&
options
.
common
.
skip_specification
,
&
options
.
common
.
until_specification
,
options
.
common
.
has_cue_specification
?
&
options
.
common
.
cue_specification
:
0
,
/*foreign_metadata=*/
NULL
,
infilename
,
outfilename
)
)
return
1
;
if
(
!
DecoderSession_init_decoder
(
&
decoder_session
,
options
.
common
,
infilename
))
if
(
!
DecoderSession_init_decoder
(
&
decoder_session
,
infilename
))
return
DecoderSession_finish_error
(
&
decoder_session
);
if
(
!
DecoderSession_process
(
&
decoder_session
))
...
...
@@ -245,10 +264,12 @@ int flac__decode_raw(const char *infilename, const char *outfilename, FLAC__bool
return
DecoderSession_finish_ok
(
&
decoder_session
);
}
FLAC__bool
DecoderSession_construct
(
DecoderSession
*
d
,
FLAC__bool
is_ogg
,
FLAC__bool
is_aiff_out
,
FLAC__bool
is_wave_out
,
FLAC__bool
treat_warnings_as_errors
,
FLAC__bool
continue_through_decode_errors
,
FLAC__bool
channel_map_none
,
replaygain_synthesis_spec_t
replaygain_synthesis_spec
,
FLAC__bool
analysis_mode
,
analysis_options
aopts
,
utils__SkipUntilSpecification
*
skip_specification
,
utils__SkipUntilSpecification
*
until_specification
,
utils__CueSpecification
*
cue_specification
,
const
char
*
infilename
,
const
char
*
outfilename
)
FLAC__bool
DecoderSession_construct
(
DecoderSession
*
d
,
FLAC__bool
is_ogg
,
FLAC__bool
use_first_serial_number
,
long
serial_number
,
FLAC__bool
is_aiff_out
,
FLAC__bool
is_wave_out
,
FLAC__bool
treat_warnings_as_errors
,
FLAC__bool
continue_through_decode_errors
,
FLAC__bool
channel_map_none
,
replaygain_synthesis_spec_t
replaygain_synthesis_spec
,
FLAC__bool
analysis_mode
,
analysis_options
aopts
,
utils__SkipUntilSpecification
*
skip_specification
,
utils__SkipUntilSpecification
*
until_specification
,
utils__CueSpecification
*
cue_specification
,
foreign_metadata_t
*
foreign_metadata
,
const
char
*
infilename
,
const
char
*
outfilename
)
{
#if FLAC__HAS_OGG
d
->
is_ogg
=
is_ogg
;
d
->
use_first_serial_number
=
use_first_serial_number
;
d
->
serial_number
=
serial_number
;
#else
(
void
)
is_ogg
;
#endif
...
...
@@ -294,6 +315,8 @@ FLAC__bool DecoderSession_construct(DecoderSession *d, FLAC__bool is_ogg, FLAC__
d
->
fout
=
0
;
/* initialized with an open file later if necessary */
d
->
foreign_metadata
=
foreign_metadata
;
FLAC__ASSERT
(
!
(
d
->
test_only
&&
d
->
analysis_mode
));
if
(
!
d
->
test_only
)
{
...
...
@@ -324,13 +347,21 @@ void DecoderSession_destroy(DecoderSession *d, FLAC__bool error_occurred)
}
}
FLAC__bool
DecoderSession_init_decoder
(
DecoderSession
*
decoder_session
,
decode_options_t
decode_options
,
const
char
*
infilename
)
FLAC__bool
DecoderSession_init_decoder
(
DecoderSession
*
decoder_session
,
const
char
*
infilename
)
{
FLAC__StreamDecoderInitStatus
init_status
;
FLAC__uint32
test
=
1
;
is_big_endian_host_
=
(
*
((
FLAC__byte
*
)(
&
test
)))
?
false
:
true
;
if
(
decoder_session
->
foreign_metadata
)
{
const
char
*
error
;
if
(
!
flac__foreign_metadata_read_from_flac
(
decoder_session
->
foreign_metadata
,
infilename
,
&
error
))
{
flac__utils_printf
(
stderr
,
1
,
"%s: ERROR reading foreign metadata: %s
\n
"
,
decoder_session
->
inbasefilename
,
error
);
return
false
;
}
}
decoder_session
->
decoder
=
FLAC__stream_decoder_new
();
if
(
0
==
decoder_session
->
decoder
)
{
...
...
@@ -346,8 +377,8 @@ FLAC__bool DecoderSession_init_decoder(DecoderSession *decoder_session, decode_o
#if FLAC__HAS_OGG
if
(
decoder_session
->
is_ogg
)
{
if
(
!
decode
_opt
ion
s
.
use_first_serial_number
)
FLAC__stream_decoder_set_ogg_serial_number
(
decoder_session
->
decoder
,
decode
_opt
ion
s
.
serial_number
);
if
(
!
decode
r_sess
ion
->
use_first_serial_number
)
FLAC__stream_decoder_set_ogg_serial_number
(
decoder_session
->
decoder
,
decode
r_sess
ion
->
serial_number
);
init_status
=
FLAC__stream_decoder_init_ogg_file
(
decoder_session
->
decoder
,
strcmp
(
infilename
,
"-"
)
?
infilename
:
0
,
write_callback
,
metadata_callback
,
error_callback
,
/*client_data=*/
decoder_session
);
}
else
...
...
src/flac/decode.h
View file @
4b279f76
...
...
@@ -19,13 +19,15 @@
#ifndef flac__decode_h
#define flac__decode_h
#if HAVE_CONFIG_H
# include <config.h>
#endif
#include "analyze.h"
#include "foreign_metadata.h"
#include "utils.h"
#include "share/replaygain_synthesis.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
typedef
struct
{
FLAC__bool
apply
;
...
...
@@ -54,6 +56,7 @@ typedef struct {
/* used for AIFF also */
typedef
struct
{
decode_options_t
common
;
foreign_metadata_t
*
foreign_metadata
;
/* NULL unless --keep-foreign-metadata requested */
}
wav_decode_options_t
;
typedef
struct
{
...
...
src/flac/encode.c
View file @
4b279f76
This diff is collapsed.
Click to expand it.
src/flac/encode.h
View file @
4b279f76
...
...
@@ -19,18 +19,14 @@
#ifndef flac__encode_h
#define flac__encode_h
/* needed because of off_t */
#if HAVE_CONFIG_H
# include <config.h>
#endif
#include "FLAC/metadata.h"
#include "foreign_metadata.h"
#include "utils.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
extern
const
int
FLAC_ENCODE__DEFAULT_PADDING
;
typedef
enum
{
...
...
@@ -101,6 +97,7 @@ typedef struct {
typedef
struct
{
encode_options_t
common
;
foreign_metadata_t
*
foreign_metadata
;
/* NULL unless --keep-foreign-metadata requested */
}
wav_encode_options_t
;
typedef
struct
{
...
...
src/flac/foreign_metadata.c
0 → 100644
View file @
4b279f76
/* flac - Command-line FLAC encoder/decoder
* Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#if HAVE_CONFIG_H
# include <config.h>
#endif
#if defined _MSC_VER || defined __MINGW32__
#include <sys/types.h>
/* for off_t */
#if _MSC_VER <= 1600
/* @@@ [2G limit] */
#define fseeko fseek
#define ftello ftell
#endif
#endif
#include <stdio.h>
/* for FILE etc. */
#include <stdlib.h>
/* for calloc() etc. */
#include <string.h>
/* for memcmp() etc. */
#include "FLAC/assert.h"
#include "FLAC/metadata.h"
#include "foreign_metadata.h"
#ifdef min
#undef min
#endif
#define min(x,y) ((x)<(y)?(x):(y))
static
const
char
*
FLAC__FOREIGN_METADATA_APPLICATION_ID
=
"FFMB"
;
/*@@@@@@ settle on an ID */
static
FLAC__uint32
unpack32be_
(
const
FLAC__byte
*
b
)
{
return
((
FLAC__uint32
)
b
[
0
]
<<
24
)
+
((
FLAC__uint32
)
b
[
1
]
<<
16
)
+
((
FLAC__uint32
)
b
[
2
]
<<
8
)
+
(
FLAC__uint32
)
b
[
3
];
}
static
FLAC__uint32
unpack32le_
(
const
FLAC__byte
*
b
)
{
return
(
FLAC__uint32
)
b
[
0
]
+
((
FLAC__uint32
)
b
[
1
]
<<
8
)
+
((
FLAC__uint32
)
b
[
2
]
<<
16
)
+
((
FLAC__uint32
)
b
[
3
]
<<
24
);
}
static
FLAC__bool
append_block_
(
foreign_metadata_t
*
fm
,
off_t
offset
,
FLAC__uint32
size
,
const
char
**
error
)
{
foreign_block_t
*
fb
=
realloc
(
fm
->
blocks
,
sizeof
(
foreign_block_t
)
*
(
fm
->
num_blocks
+
1
));
if
(
fb
)
{
fb
[
fm
->
num_blocks
].
offset
=
offset
;
fb
[
fm
->
num_blocks
].
size
=
size
;
fm
->
num_blocks
++
;
fm
->
blocks
=
fb
;
return
true
;
}
if
(
error
)
*
error
=
"out of memory"
;
return
false
;
}
static
FLAC__bool
read_from_aiff_
(
foreign_metadata_t
*
fm
,
FILE
*
f
,
const
char
**
error
)
{
FLAC__byte
buffer
[
12
];
off_t
offset
,
eof_offset
;
if
((
offset
=
ftello
(
f
))
<
0
)
{
if
(
error
)
*
error
=
"ftello() error (001)"
;
return
false
;
}
if
(
fread
(
buffer
,
1
,
12
,
f
)
<
12
||
memcmp
(
buffer
,
"FORM"
,
4
)
||
(
memcmp
(
buffer
+
8
,
"AIFF"
,
4
)
&&
memcmp
(
buffer
+
8
,
"AIFC"
,
4
)))
{
if
(
error
)
*
error
=
"unsupported FORM layout (002)"
;
return
false
;
}
if
(
!
append_block_
(
fm
,
offset
,
12
,
error
))
return
false
;
eof_offset
=
8
+
unpack32be_
(
buffer
+
4
);
while
(
!
feof
(
f
))
{
FLAC__uint32
size
,
ssnd_offset_size
=
0
;
if
((
offset
=
ftello
(
f
))
<
0
)
{
if
(
error
)
*
error
=
"ftello() error (003)"
;
return
false
;
}
if
((
size
=
fread
(
buffer
,
1
,
8
,
f
))
<
8
)
{
if
(
size
==
0
&&
feof
(
f
))
break
;
if
(
error
)
*
error
=
"invalid AIFF file (004)"
;
return
false
;
}
size
=
unpack32be_
(
buffer
+
4
);
/* check if pad byte needed */
if
(
size
&
1
)
size
++
;
if
(
!
memcmp
(
buffer
,
"COMM"
,
4
))
{
if
(
fm
->
format_block
)
{
if
(
error
)
*
error
=
"invalid AIFF file: multiple
\"
COMM
\"
chunks (005)"
;
return
false
;
}
fm
->
format_block
=
fm
->
num_blocks
;
}
else
if
(
!
memcmp
(
buffer
,
"SSND"
,
4
))
{
if
(
fm
->
audio_block
)
{
if
(
error
)
*
error
=
"invalid AIFF file: multiple
\"
SSND
\"
chunks (006)"
;
return
false
;
}
fm
->
audio_block
=
fm
->
num_blocks
;
/* read #offset bytes */
if
(
fread
(
buffer
+
8
,
1
,
4
,
f
)
<
4
)
{
if
(
error
)
*
error
=
"invalid AIFF file (007)"
;
return
false
;
}
ssnd_offset_size
=
unpack32be_
(
buffer
+
8
);
if
(
fseeko
(
f
,
-
4
,
SEEK_CUR
)
<
0
)
{
if
(
error
)
*
error
=
"invalid AIFF file: seek error (008)"
;
return
false
;
}
}
if
(
!
append_block_
(
fm
,
offset
,
8
+
(
memcmp
(
buffer
,
"SSND"
,
4
)
?
size
:
8
+
ssnd_offset_size
),
error
))
return
false
;
fprintf
(
stderr
,
"@@@@@@ chunk=%c%c%c%c offset=%d size=%d
\n
"
,
buffer
[
0
],
buffer
[
1
],
buffer
[
2
],
buffer
[
3
],(
int
)
offset
,
8
+
(
int
)
size
);
if
(
fseeko
(
f
,
size
,
SEEK_CUR
)
<
0
)
{
if
(
error
)
*
error
=
"invalid AIFF file: seek error (009)"
;
return
false
;
}
}
if
(
eof_offset
!=
ftello
(
f
))
{
if
(
error
)
*
error
=
"invalid AIFF file: unexpected EOF (010)"
;
return
false
;
}
if
(
!
fm
->
format_block
)
{
if
(
error
)
*
error
=
"invalid AIFF file: missing
\"
COMM
\"
chunk (011)"
;
return
false
;
}
if
(
!
fm
->
audio_block
)
{
if
(
error
)
*
error
=
"invalid AIFF file: missing
\"
SSND
\"
chunk (012)"
;
return
false
;
}
return
true
;
}
static
FLAC__bool
read_from_wave_
(
foreign_metadata_t
*
fm
,
FILE
*
f
,
const
char
**
error
)
{
FLAC__byte
buffer
[
12
];
off_t
offset
,
eof_offset
;
if
((
offset
=
ftello
(
f
))
<
0
)
{
if
(
error
)
*
error
=
"ftello() error (001)"
;
return
false
;
}
if
(
fread
(
buffer
,
1
,
12
,
f
)
<
12
||
memcmp
(
buffer
,
"RIFF"
,
4
)
||
memcmp
(
buffer
+
8
,
"WAVE"
,
4
))
{
if
(
error
)
*
error
=
"unsupported RIFF layout (002)"
;
return
false
;
}
if
(
!
append_block_
(
fm
,
offset
,
12
,
error
))
return
false
;
eof_offset
=
8
+
unpack32le_
(
buffer
+
4
);
fprintf
(
stderr
,
"@@@@@@ off=%d eof=%d
\n
"
,(
int
)
offset
,(
int
)
eof_offset
);
while
(
!
feof
(
f
))
{
FLAC__uint32
size
;
if
((
offset
=
ftello
(
f
))
<
0
)
{
if
(
error
)
*
error
=
"ftello() error (003)"
;
return
false
;
}
if
((
size
=
fread
(
buffer
,
1
,
8
,
f
))
<
8
)
{
if
(
size
==
0
&&
feof
(
f
))
break
;
if
(
error
)
*
error
=
"invalid WAVE file (004)"
;
return
false
;
}
size
=
unpack32le_
(
buffer
+
4
);
/* check if pad byte needed */
if
(
size
&
1
)
size
++
;
if
(
!
memcmp
(
buffer
,
"fmt "
,
4
))
{
if
(
fm
->
format_block
)
{
if
(
error
)
*
error
=
"invalid WAVE file: multiple
\"
fmt
\"
chunks (005)"
;
return
false
;
}
fm
->
format_block
=
fm
->
num_blocks
;
}
else
if
(
!
memcmp
(
buffer
,
"data"
,
4
))
{
if
(
fm
->
audio_block
)
{
if
(
error
)
*
error
=
"invalid WAVE file: multiple
\"
data
\"
chunks (006)"
;
return
false
;
}
fm
->
audio_block
=
fm
->
num_blocks
;
}
if
(
!
append_block_
(
fm
,
offset
,
8
+
(
memcmp
(
buffer
,
"data"
,
4
)
?
size
:
0
),
error
))
return
false
;
fprintf
(
stderr
,
"@@@@@@ chunk=%c%c%c%c offset=%d size=%d
\n
"
,
buffer
[
0
],
buffer
[
1
],
buffer
[
2
],
buffer
[
3
],(
int
)
offset
,
8
+
(
int
)
size
);
if
(
fseeko
(
f
,
size
,
SEEK_CUR
)
<
0
)
{
if
(
error
)
*
error
=
"invalid WAVE file: seek error (007)"
;
return
false
;
}
}
if
(
eof_offset
!=
ftello
(
f
))
{
if
(
error
)
*
error
=
"invalid WAVE file: unexpected EOF (008)"
;
return
false
;
}
if
(
!
fm
->
format_block
)
{
if
(
error
)
*
error
=
"invalid WAVE file: missing
\"
fmt
\"
chunk (009)"
;
return
false
;
}
if
(
!
fm
->
audio_block
)
{
if
(
error
)
*
error
=
"invalid WAVE file: missing
\"
data
\"
chunk (010)"
;
return
false
;
}
return
true
;
}
static
FLAC__bool
write_to_flac_
(
foreign_metadata_t
*
fm
,
FILE
*
fin
,
FILE
*
fout
,
FLAC__Metadata_SimpleIterator
*
it
,
const
char
**
error
)
{
static
FLAC__byte
buffer
[
4096
];
const
unsigned
ID_LEN
=
FLAC__STREAM_METADATA_APPLICATION_ID_LEN
/
8
;
size_t
left
,
block_num
=
0
;
FLAC__ASSERT
(
sizeof
(
buffer
)
>=
ID_LEN
);
while
(
block_num
<
fm
->
num_blocks
)
{
/* find next matching padding block */
do
{
/* even on the first chunk's loop there will be a skippable STREAMINFO block, on subsequent loops we are first moving past the PADDING we just used */
if
(
!
FLAC__metadata_simple_iterator_next
(
it
))
{
if
(
error
)
*
error
=
"no matching PADDING block found (004)"
;
return
false
;
}
}
while
(
FLAC__metadata_simple_iterator_get_block_type
(
it
)
!=
FLAC__METADATA_TYPE_PADDING
);
if
(
FLAC__metadata_simple_iterator_get_block_length
(
it
)
!=
ID_LEN
+
fm
->
blocks
[
block_num
].
size
)
{
if
(
error
)
*
error
=
"PADDING block with wrong size found (005)"
;
return
false
;
}
fprintf
(
stderr
,
"@@@@@@ flac offset = %d
\n
"
,(
int
)
FLAC__metadata_simple_iterator_get_block_offset
(
it
));
/* transfer chunk into APPLICATION block */
/* first set up the file pointers */
if
(
fseek
(
fin
,
fm
->
blocks
[
block_num
].
offset
,
SEEK_SET
)
<
0
)
{
if
(
error
)
*
error
=
"seek failed in WAVE/AIFF file (006)"
;
return
false
;
}
if
(
fseek
(
fout
,
FLAC__metadata_simple_iterator_get_block_offset
(
it
),
SEEK_SET
)
<
0
)
{
if
(
error
)
*
error
=
"seek failed in FLAC file (007)"
;
return
false
;
}
/* update the type */
buffer
[
0
]
=
FLAC__METADATA_TYPE_APPLICATION
;
if
(
FLAC__metadata_simple_iterator_is_last
(
it
))
buffer
[
0
]
|=
0x80
;
/*MAGIC number*/
if
(
fwrite
(
buffer
,
1
,
1
,
fout
)
<
1
)
{
if
(
error
)
*
error
=
"write failed in FLAC/AIFF file (008)"
;
return
false
;
}
/* length stays the same so skip over it */
if
(
fseek
(
fout
,
FLAC__STREAM_METADATA_LENGTH_LEN
/
8
,
SEEK_CUR
)
<
0
)
{
if
(
error
)
*
error
=
"seek failed in FLAC file (009)"
;
return
false
;
}
/* write the APPLICATION ID */
memcpy
(
buffer
,
FLAC__FOREIGN_METADATA_APPLICATION_ID
,
ID_LEN
);
if
(
fwrite
(
buffer
,
1
,
ID_LEN
,
fout
)
<
ID_LEN
)
{
if
(
error
)
*
error
=
"write failed in FLAC/AIFF file (010)"
;
return
false
;
}
/* transfer the foreign metadata */
for
(
left
=
fm
->
blocks
[
block_num
].
size
;
left
>
0
;
)
{
size_t
need
=
min
(
sizeof
(
buffer
),
left
);
if
(
fread
(
buffer
,
1
,
need
,
fin
)
<
need
)
{
if
(
error
)
*
error
=
"read failed in WAVE/AIFF file (011)"
;
return
false
;
}
if
(
fwrite
(
buffer
,
1
,
need
,
fout
)
<
need
)
{
if
(
error
)
*
error
=
"write failed in FLAC/AIFF file (012)"
;
return
false
;
}
left
-=
need
;
}
block_num
++
;
}
return
true
;
}
foreign_metadata_t
*
flac__foreign_metadata_new
(
void
)
{
return
(
foreign_metadata_t
*
)
calloc
(
sizeof
(
foreign_metadata_t
),
1
);
}
void
flac__foreign_metadata_delete
(
foreign_metadata_t
*
fm
)
{
if
(
fm
)
{
if
(
fm
->
blocks
)
free
(
fm
->
blocks
);
free
(
fm
);
}
}
FLAC__bool
flac__foreign_metadata_read_from_aiff
(
foreign_metadata_t
*
fm
,
const
char
*
filename
,
const
char
**
error
)
{
FLAC__bool
ok
;
FILE
*
f
=
fopen
(
filename
,
"rb"
);
if
(
!
f
)
{
if
(
error
)
*
error
=
"can't open AIFF file for reading (000)"
;
return
false
;
}
ok
=
read_from_aiff_
(
fm
,
f
,
error
);
fclose
(
f
);
return
ok
;
}
FLAC__bool
flac__foreign_metadata_read_from_wave
(
foreign_metadata_t
*
fm
,
const
char
*
filename
,
const
char
**
error
)
{
FLAC__bool
ok
;
FILE
*
f
=
fopen
(
filename
,
"rb"
);
if
(
!
f
)
{
if
(
error
)
*
error
=
"can't open WAVE file for reading (000)"
;
return
false
;
}
ok
=
read_from_wave_
(
fm
,
f
,
error
);
fclose
(
f
);
return
ok
;
}
FLAC__bool
flac__foreign_metadata_write_to_flac
(
foreign_metadata_t
*
fm
,
const
char
*
infilename
,
const
char
*
outfilename
,
const
char
**
error
)
{
FLAC__bool
ok
;
FILE
*
fin
,
*
fout
;
FLAC__Metadata_SimpleIterator
*
it
=
FLAC__metadata_simple_iterator_new
();
if
(
!
it
)
{
if
(
error
)
*
error
=
"out of memory (000)"
;
return
false
;
}
if
(
!
FLAC__metadata_simple_iterator_init
(
it
,
outfilename
,
/*read_only=*/
true
,
/*preserve_file_stats=*/
false
))
{
if
(
error
)
*
error
=
"can't initialize iterator (001)"
;
FLAC__metadata_simple_iterator_delete
(
it
);
return
false
;
}
if
(
0
==
(
fin
=
fopen
(
infilename
,
"rb"
)))
{
if
(
error
)
*
error
=
"can't open WAVE/AIFF file for reading (002)"
;
FLAC__metadata_simple_iterator_delete
(
it
);
return
false
;
}
if
(
0
==
(
fout
=
fopen
(
outfilename
,
"r+b"
)))
{
if
(
error
)
*
error
=
"can't open FLAC file for updating (003)"
;
FLAC__metadata_simple_iterator_delete
(
it
);
fclose
(
fin
);
return
false
;
}
ok
=
write_to_flac_
(
fm
,
fin
,
fout
,
it
,
error
);
FLAC__metadata_simple_iterator_delete
(
it
);
fclose
(
fin
);
fclose
(
fout
);
return
ok
;
}
FLAC__bool
flac__foreign_metadata_read_from_flac
(
foreign_metadata_t
*
fm
,
const
char
*
filename
,
const
char
**
error
)
{
}
FLAC__bool
flac__foreign_metadata_write_to_aiff
(
foreign_metadata_t
*
fm
,
const
char
*
infilename
,
const
char
*
outfilename
,
const
char
**
error
)