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
f178b143
Commit
f178b143
authored
Aug 21, 2007
by
Josh Coalson
Browse files
finish foreign metadata implemetation
parent
02f91ed9
Changes
7
Hide whitespace changes
Inline
Side-by-side
src/flac/decode.c
View file @
f178b143
...
...
@@ -70,6 +70,7 @@ typedef struct {
utils__CueSpecification
*
cue_specification
;
const
char
*
inbasefilename
;
const
char
*
infilename
;
const
char
*
outfilename
;
FLAC__uint64
samples_processed
;
...
...
@@ -98,6 +99,7 @@ typedef struct {
FILE
*
fout
;
foreign_metadata_t
*
foreign_metadata
;
/* NULL unless --keep-foreign-metadata requested */
off_t
fm_offset1
,
fm_offset2
,
fm_offset3
;
}
DecoderSession
;
...
...
@@ -115,6 +117,8 @@ static int DecoderSession_finish_ok(DecoderSession *d);
static
int
DecoderSession_finish_error
(
DecoderSession
*
d
);
static
FLAC__bool
canonicalize_until_specification
(
utils__SkipUntilSpecification
*
spec
,
const
char
*
inbasefilename
,
unsigned
sample_rate
,
FLAC__uint64
skip
,
FLAC__uint64
total_samples_in_input
);
static
FLAC__bool
write_iff_headers
(
FILE
*
f
,
DecoderSession
*
decoder_session
,
FLAC__uint64
samples
);
static
FLAC__bool
write_riff_wave_fmt_chunk
(
FILE
*
f
,
FLAC__bool
is_waveformatextensible
,
unsigned
bps
,
unsigned
channels
,
unsigned
sample_rate
,
FLAC__uint32
channel_mask
);
static
FLAC__bool
write_aiff_form_comm_chunk
(
FILE
*
f
,
FLAC__uint64
samples
,
unsigned
bps
,
unsigned
channels
,
unsigned
sample_rate
);
static
FLAC__bool
write_little_endian_uint16
(
FILE
*
f
,
FLAC__uint16
val
);
static
FLAC__bool
write_little_endian_uint32
(
FILE
*
f
,
FLAC__uint32
val
);
static
FLAC__bool
write_big_endian_uint16
(
FILE
*
f
,
FLAC__uint16
val
);
...
...
@@ -291,6 +295,7 @@ FLAC__bool DecoderSession_construct(DecoderSession *d, FLAC__bool is_ogg, FLAC__
d
->
cue_specification
=
cue_specification
;
d
->
inbasefilename
=
grabbag__file_get_basename
(
infilename
);
d
->
infilename
=
infilename
;
d
->
outfilename
=
outfilename
;
d
->
samples_processed
=
0
;
...
...
@@ -354,11 +359,13 @@ FLAC__bool DecoderSession_init_decoder(DecoderSession *decoder_session, const ch
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
;
if
(
!
decoder_session
->
analysis_mode
&&
!
decoder_session
->
test_only
&&
(
decoder_session
->
is_wave_out
||
decoder_session
->
is_aiff_out
))
{
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
;
}
}
}
...
...
@@ -515,9 +522,19 @@ int DecoderSession_finish_ok(DecoderSession *d)
flac__utils_printf
(
stderr
,
2
,
"
\r
%s: %s
\n
"
,
d
->
inbasefilename
,
d
->
test_only
?
"ok "
:
d
->
analysis_mode
?
"done "
:
"done"
);
}
DecoderSession_destroy
(
d
,
/*error_occurred=*/
!
ok
);
if
(
!
d
->
test_only
&&
(
d
->
is_wave_out
||
d
->
is_aiff_out
)
&&
(
d
->
iff_headers_need_fixup
||
(
!
d
->
got_stream_info
&&
strcmp
(
d
->
outfilename
,
"-"
))))
if
(
!
fixup_iff_headers
(
d
))
return
1
;
if
(
!
d
->
analysis_mode
&&
!
d
->
test_only
&&
(
d
->
is_wave_out
||
d
->
is_aiff_out
))
{
if
(
d
->
iff_headers_need_fixup
||
(
!
d
->
got_stream_info
&&
strcmp
(
d
->
outfilename
,
"-"
)))
{
if
(
!
fixup_iff_headers
(
d
))
return
1
;
}
if
(
d
->
foreign_metadata
)
{
const
char
*
error
;
if
(
!
flac__foreign_metadata_write_to_iff
(
d
->
foreign_metadata
,
d
->
infilename
,
d
->
outfilename
,
d
->
fm_offset1
,
d
->
fm_offset2
,
d
->
fm_offset3
,
&
error
))
{
flac__utils_printf
(
stderr
,
1
,
"ERROR updating foreign metadata from %s to %s: %s
\n
"
,
d
->
infilename
,
d
->
outfilename
,
error
);
return
1
;
}
}
}
return
ok
?
0
:
1
;
}
...
...
@@ -584,6 +601,11 @@ FLAC__bool write_iff_headers(FILE *f, DecoderSession *decoder_session, FLAC__uin
const
FLAC__bool
is_waveformatextensible
=
decoder_session
->
is_wave_out
&&
(
decoder_session
->
channel_mask
==
2
||
decoder_session
->
channel_mask
>
3
||
decoder_session
->
bps
%
8
||
decoder_session
->
channels
>
2
);
FLAC__uint64
data_size
=
samples
*
decoder_session
->
channels
*
((
decoder_session
->
bps
+
7
)
/
8
);
const
FLAC__uint32
aligned_data_size
=
(
FLAC__uint32
)((
data_size
+
1
)
&
(
~
1U
));
/* we'll check for overflow later */
unsigned
foreign_metadata_size
=
0
;
/* size of all non-audio non-fmt/COMM foreign metadata chunks */
foreign_metadata_t
*
fm
=
decoder_session
->
foreign_metadata
;
size_t
i
;
if
(
samples
==
0
)
{
if
(
f
==
stdout
)
{
flac__utils_printf
(
stderr
,
1
,
"%s: WARNING, don't have accurate sample count available for %s header.
\n
"
,
decoder_session
->
inbasefilename
,
fmt_desc
);
...
...
@@ -596,54 +618,58 @@ FLAC__bool write_iff_headers(FILE *f, DecoderSession *decoder_session, FLAC__uin
decoder_session
->
iff_headers_need_fixup
=
true
;
}
}
if
(
data_size
>=
0xFFFFFFDC
)
{
flac__utils_printf
(
stderr
,
1
,
"%s: ERROR: stream is too big to fit in a single %s file chunk
\n
"
,
decoder_session
->
inbasefilename
,
fmt_desc
);
if
(
fm
)
{
FLAC__ASSERT
(
fm
->
format_block
);
FLAC__ASSERT
(
fm
->
audio_block
);
FLAC__ASSERT
(
fm
->
format_block
<
fm
->
audio_block
);
/* calc foreign metadata size; for RIFF/AIFF we always skip the first chunk, format chunk, and sound chunk since we write our own */
for
(
i
=
1
;
i
<
fm
->
num_blocks
;
i
++
)
{
if
(
i
!=
fm
->
format_block
&&
i
!=
fm
->
audio_block
)
foreign_metadata_size
+=
fm
->
blocks
[
i
].
size
;
}
}
if
(
data_size
+
foreign_metadata_size
+
60
/*worst-case*/
>=
0xFFFFFFF4
)
{
flac__utils_printf
(
stderr
,
1
,
"%s: ERROR: stream is too big to fit in a single %s file
\n
"
,
decoder_session
->
inbasefilename
,
fmt_desc
);
return
false
;
}
if
(
decoder_session
->
is_wave_out
)
{
if
(
flac__utils_fwrite
(
"RIFF"
,
1
,
4
,
f
)
!=
4
)
return
false
;
if
(
!
write_little_endian_uint32
(
f
,
aligned_data_size
+
(
is_waveformatextensible
?
60
:
36
)))
/* filesize-8 */
return
false
;
if
(
flac__utils_fwrite
(
"WAVEfmt "
,
1
,
8
,
f
)
!=
8
)
return
false
;
if
(
!
write_little_endian_uint32
(
f
,
is_waveformatextensible
?
40
:
16
))
/* chunk size */
return
false
;
if
(
!
write_little_endian_uint16
(
f
,
(
FLAC__uint16
)(
is_waveformatextensible
?
65534
:
1
)))
/* compression code */
if
(
!
write_little_endian_uint32
(
f
,
foreign_metadata_size
+
aligned_data_size
+
(
is_waveformatextensible
?
60
:
36
)))
/* filesize-8 */
return
false
;
if
(
!
write_little_endian_uint16
(
f
,
(
FLAC__uint16
)(
decoder_session
->
channels
))
)
if
(
flac__utils_fwrite
(
"WAVE"
,
1
,
4
,
f
)
!=
4
)
return
false
;
if
(
!
write_little_endian_uint32
(
f
,
decoder_session
->
sample_rate
))
return
false
;
if
(
!
write_little_endian_uint32
(
f
,
decoder_session
->
sample_rate
*
decoder_session
->
channels
*
((
decoder_session
->
bps
+
7
)
/
8
)))
return
false
;
decoder_session
->
fm_offset1
=
ftello
(
f
);
if
(
!
write_little_endian_uint16
(
f
,
(
FLAC__uint16
)(
decoder_session
->
channels
*
((
decoder_session
->
bps
+
7
)
/
8
))))
/* block align */
return
false
;
if
(
fm
)
{
/* seek forward to {allocate} or {skip over already-written chunks} before "fmt " */
for
(
i
=
1
;
i
<
fm
->
format_block
;
i
++
)
{
if
(
fseeko
(
f
,
fm
->
blocks
[
i
].
size
,
SEEK_CUR
)
<
0
)
{
flac__utils_printf
(
stderr
,
1
,
"%s: ERROR: allocating/skipping foreign metadata before
\"
fmt
\"\n
"
,
decoder_session
->
inbasefilename
);
return
false
;
}
}
}
if
(
!
write_
little_endian_uint16
(
f
,
(
FLAC__uint16
)(((
decoder_session
->
bps
+
7
)
/
8
)
*
8
)))
/* bits per sample */
if
(
!
write_
riff_wave_fmt_chunk
(
f
,
is_waveformatextensible
,
decoder_session
->
bps
,
decoder_session
->
channels
,
decoder_session
->
sample_rate
,
decoder_session
->
channel_mask
))
return
false
;
if
(
is_waveformatextensible
)
{
if
(
!
write_little_endian_uint16
(
f
,
(
FLAC__uint16
)
22
))
/* cbSize */
return
false
;
if
(
!
write_little_endian_uint16
(
f
,
(
FLAC__uint16
)
decoder_session
->
bps
))
/* validBitsPerSample */
return
false
;
if
(
!
write_little_endian_uint32
(
f
,
decoder_session
->
channel_mask
))
return
false
;
decoder_session
->
fm_offset2
=
ftello
(
f
);
/* GUID = {0x00000001, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}} */
if
(
flac__utils_fwrite
(
"
\x01\x00\x00\x00\x00\x00\x10\x00\x80\x00\x00\xaa\x00\x38\x9b\x71
"
,
1
,
16
,
f
)
!=
16
)
return
false
;
if
(
fm
)
{
/* seek forward to {allocate} or {skip over already-written chunks} after "fmt " but before "data" */
for
(
i
=
fm
->
format_block
+
1
;
i
<
fm
->
audio_block
;
i
++
)
{
if
(
fseeko
(
f
,
fm
->
blocks
[
i
].
size
,
SEEK_CUR
)
<
0
)
{
flac__utils_printf
(
stderr
,
1
,
"%s: ERROR: allocating/skipping foreign metadata after
\"
fmt
\"\n
"
,
decoder_session
->
inbasefilename
);
return
false
;
}
}
}
if
(
flac__utils_fwrite
(
"data"
,
1
,
4
,
f
)
!=
4
)
...
...
@@ -651,48 +677,143 @@ FLAC__bool write_iff_headers(FILE *f, DecoderSession *decoder_session, FLAC__uin
if
(
!
write_little_endian_uint32
(
f
,
(
FLAC__uint32
)
data_size
))
/* data size */
return
false
;
decoder_session
->
fm_offset3
=
ftello
(
f
)
+
aligned_data_size
;
}
else
{
FLAC__uint32
ssnd_offset_size
=
(
fm
?
fm
->
ssnd_offset_size
:
0
);
if
(
flac__utils_fwrite
(
"FORM"
,
1
,
4
,
f
)
!=
4
)
return
false
;
if
(
!
write_big_endian_uint32
(
f
,
aligned_data_size
+
46
))
/* filesize-8 */
if
(
!
write_big_endian_uint32
(
f
,
foreign_metadata_size
+
aligned_data_size
+
46
+
ssnd_offset_size
))
/* filesize-8 */
return
false
;
if
(
flac__utils_fwrite
(
"AIFF
COMM
"
,
1
,
8
,
f
)
!=
8
)
if
(
flac__utils_fwrite
(
"AIFF"
,
1
,
4
,
f
)
!=
4
)
return
false
;
if
(
flac__utils_fwrite
(
"
\000\000\000\022
"
,
1
,
4
,
f
)
!=
4
)
/* chunk size = 18 */
decoder_session
->
fm_offset1
=
ftello
(
f
);
if
(
fm
)
{
/* seek forward to {allocate} or {skip over already-written chunks} before "COMM" */
for
(
i
=
1
;
i
<
fm
->
format_block
;
i
++
)
{
if
(
fseeko
(
f
,
fm
->
blocks
[
i
].
size
,
SEEK_CUR
)
<
0
)
{
flac__utils_printf
(
stderr
,
1
,
"%s: ERROR: allocating/skipping foreign metadata before
\"
COMM
\"\n
"
,
decoder_session
->
inbasefilename
);
return
false
;
}
}
}
if
(
!
write_aiff_form_comm_chunk
(
f
,
samples
,
decoder_session
->
bps
,
decoder_session
->
channels
,
decoder_session
->
sample_rate
))
return
false
;
if
(
!
write_big_endian_uint16
(
f
,
(
FLAC__uint16
)(
decoder_session
->
channels
)))
decoder_session
->
fm_offset2
=
ftello
(
f
);
if
(
fm
)
{
/* seek forward to {allocate} or {skip over already-written chunks} after "COMM" but before "SSND" */
for
(
i
=
fm
->
format_block
+
1
;
i
<
fm
->
audio_block
;
i
++
)
{
if
(
fseeko
(
f
,
fm
->
blocks
[
i
].
size
,
SEEK_CUR
)
<
0
)
{
flac__utils_printf
(
stderr
,
1
,
"%s: ERROR: allocating/skipping foreign metadata after
\"
COMM
\"\n
"
,
decoder_session
->
inbasefilename
);
return
false
;
}
}
}
if
(
flac__utils_fwrite
(
"SSND"
,
1
,
4
,
f
)
!=
4
)
return
false
;
if
(
!
write_big_endian_uint32
(
f
,
(
FLAC__uint32
)
samples
))
if
(
!
write_big_endian_uint32
(
f
,
(
FLAC__uint32
)
data_size
+
8
+
ssnd_offset_size
))
/* data size */
return
false
;
if
(
!
write_big_endian_uint
16
(
f
,
(
FLAC__uint16
)(
decoder_session
->
bps
)
))
if
(
!
write_big_endian_uint
32
(
f
,
ssnd_offset_size
))
return
false
;
if
(
!
write_
sane_extended
(
f
,
decoder_session
->
sample_rate
))
if
(
!
write_
big_endian_uint32
(
f
,
0
/*block_size*/
))
return
false
;
if
(
flac__utils_fwrite
(
"SSND"
,
1
,
4
,
f
)
!=
4
)
if
(
ssnd_offset_size
)
{
/* seek forward to {allocate} or {skip over already-written} SSND offset */
if
(
fseeko
(
f
,
ssnd_offset_size
,
SEEK_CUR
)
<
0
)
{
flac__utils_printf
(
stderr
,
1
,
"%s: ERROR: allocating/skipping
\"
SSND
\"
offset
\n
"
,
decoder_session
->
inbasefilename
);
return
false
;
}
}
decoder_session
->
fm_offset3
=
ftello
(
f
)
+
aligned_data_size
;
}
return
true
;
}
FLAC__bool
write_riff_wave_fmt_chunk
(
FILE
*
f
,
FLAC__bool
is_waveformatextensible
,
unsigned
bps
,
unsigned
channels
,
unsigned
sample_rate
,
FLAC__uint32
channel_mask
)
{
if
(
flac__utils_fwrite
(
"fmt "
,
1
,
4
,
f
)
!=
4
)
return
false
;
if
(
!
write_little_endian_uint32
(
f
,
is_waveformatextensible
?
40
:
16
))
/* chunk size */
return
false
;
if
(
!
write_little_endian_uint16
(
f
,
(
FLAC__uint16
)(
is_waveformatextensible
?
65534
:
1
)))
/* compression code */
return
false
;
if
(
!
write_little_endian_uint16
(
f
,
(
FLAC__uint16
)
channels
))
return
false
;
if
(
!
write_little_endian_uint32
(
f
,
sample_rate
))
return
false
;
if
(
!
write_little_endian_uint32
(
f
,
sample_rate
*
channels
*
((
bps
+
7
)
/
8
)))
return
false
;
if
(
!
write_little_endian_uint16
(
f
,
(
FLAC__uint16
)(
channels
*
((
bps
+
7
)
/
8
))))
/* block align */
return
false
;
if
(
!
write_little_endian_uint16
(
f
,
(
FLAC__uint16
)(((
bps
+
7
)
/
8
)
*
8
)))
/* bits per sample */
return
false
;
if
(
is_waveformatextensible
)
{
if
(
!
write_little_endian_uint16
(
f
,
(
FLAC__uint16
)
22
))
/* cbSize */
return
false
;
if
(
!
write_
big
_endian_uint
32
(
f
,
(
FLAC__uint
32
)
data_size
+
8
))
/* data siz
e */
if
(
!
write_
little
_endian_uint
16
(
f
,
(
FLAC__uint
16
)
bps
))
/* validBitsPerSampl
e */
return
false
;
if
(
!
write_
big
_endian_uint32
(
f
,
0
/*offset*/
))
if
(
!
write_
little
_endian_uint32
(
f
,
channel_mask
))
return
false
;
if
(
!
write_big_endian_uint32
(
f
,
0
/*block_size*/
))
/* GUID = {0x00000001, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}} */
if
(
flac__utils_fwrite
(
"
\x01\x00\x00\x00\x00\x00\x10\x00\x80\x00\x00\xaa\x00\x38\x9b\x71
"
,
1
,
16
,
f
)
!=
16
)
return
false
;
}
return
true
;
}
FLAC__bool
write_aiff_form_comm_chunk
(
FILE
*
f
,
FLAC__uint64
samples
,
unsigned
bps
,
unsigned
channels
,
unsigned
sample_rate
)
{
FLAC__ASSERT
(
samples
<=
0xffffffff
);
if
(
flac__utils_fwrite
(
"COMM"
,
1
,
4
,
f
)
!=
4
)
return
false
;
if
(
!
write_big_endian_uint32
(
f
,
18
))
/* chunk size = 18 */
return
false
;
if
(
!
write_big_endian_uint16
(
f
,
(
FLAC__uint16
)
channels
))
return
false
;
if
(
!
write_big_endian_uint32
(
f
,
(
FLAC__uint32
)
samples
))
return
false
;
if
(
!
write_big_endian_uint16
(
f
,
(
FLAC__uint16
)
bps
))
return
false
;
if
(
!
write_sane_extended
(
f
,
sample_rate
))
return
false
;
return
true
;
}
FLAC__bool
write_little_endian_uint16
(
FILE
*
f
,
FLAC__uint16
val
)
{
FLAC__byte
*
b
=
(
FLAC__byte
*
)(
&
val
);
...
...
src/flac/encode.c
View file @
f178b143
...
...
@@ -2098,7 +2098,7 @@ FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t optio
}
static_metadata_append
(
&
static_metadata
,
p
,
/*needs_delete=*/
true
);
static_metadata
.
metadata
[
static_metadata
.
num_metadata
-
1
]
->
length
=
FLAC__STREAM_METADATA_APPLICATION_ID_LEN
/
8
+
foreign_metadata
->
blocks
[
i
].
size
;
fprintf
(
stderr
,
"@@@@@@ add PADDING=%u
\n
"
,
static_metadata
.
metadata
[
static_metadata
.
num_metadata
-
1
]
->
length
);
/*
fprintf(stderr,"@@@@@@ add PADDING=%u\n",static_metadata.metadata[static_metadata.num_metadata-1]->length);
*/
}
}
if
(
options
.
padding
!=
0
)
{
...
...
src/flac/flac.dsp
View file @
f178b143
...
...
@@ -101,6 +101,10 @@ SOURCE=.\encode.c
# End Source File
# Begin Source File
SOURCE=.\foreign_metadata.c
# End Source File
# Begin Source File
SOURCE=.\main.c
# End Source File
# Begin Source File
...
...
@@ -133,6 +137,10 @@ SOURCE=.\encode.h
# End Source File
# Begin Source File
SOURCE=.\foreign_metadata.h
# End Source File
# Begin Source File
SOURCE=.\local_string_utils.h
# End Source File
# Begin Source File
...
...
src/flac/flac.vcproj
View file @
f178b143
...
...
@@ -199,6 +199,10 @@
RelativePath=
".\encode.h"
>
</File>
<File
RelativePath=
".\foreign_metadata.h"
>
</File>
<File
RelativePath=
".\local_string_utils.h"
>
...
...
@@ -229,6 +233,10 @@
RelativePath=
".\encode.c"
>
</File>
<File
RelativePath=
".\foreign_metadata.c"
>
</File>
<File
RelativePath=
".\local_string_utils.c"
>
...
...
src/flac/foreign_metadata.c
View file @
f178b143
...
...
@@ -40,7 +40,7 @@
#define min(x,y) ((x)<(y)?(x):(y))
static
const
char
*
FLAC__FOREIGN_METADATA_APPLICATION_ID
=
"FFMB"
;
/*@@@@@@ settle on an ID */
static
const
char
*
FLAC__FOREIGN_METADATA_APPLICATION_ID
[
2
]
=
{
"AIFF"
,
"RIFF"
};
static
FLAC__uint32
unpack32be_
(
const
FLAC__byte
*
b
)
{
...
...
@@ -52,6 +52,25 @@ 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
copy_data_
(
FILE
*
fin
,
FILE
*
fout
,
size_t
size
,
const
char
**
error
,
const
char
*
const
read_error
,
const
char
*
const
write_error
)
{
static
FLAC__byte
buffer
[
4096
];
size_t
left
;
for
(
left
=
size
;
left
>
0
;
)
{
size_t
need
=
min
(
sizeof
(
buffer
),
left
);
if
(
fread
(
buffer
,
1
,
need
,
fin
)
<
need
)
{
if
(
error
)
*
error
=
read_error
;
return
false
;
}
if
(
fwrite
(
buffer
,
1
,
need
,
fout
)
<
need
)
{
if
(
error
)
*
error
=
write_error
;
return
false
;
}
left
-=
need
;
}
return
true
;
}
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
));
...
...
@@ -60,6 +79,7 @@ static FLAC__bool append_block_(foreign_metadata_t *fm, off_t offset, FLAC__uint
fb
[
fm
->
num_blocks
].
size
=
size
;
fm
->
num_blocks
++
;
fm
->
blocks
=
fb
;
/*fprintf(stderr,"@@@@@@ appended: block#%u offset=%d size=%u\n",fm->num_blocks-1,(int)fm->blocks[fm->num_blocks-1].offset,(unsigned)fm->blocks[fm->num_blocks-1].size);*/
return
true
;
}
if
(
error
)
*
error
=
"out of memory"
;
...
...
@@ -81,8 +101,9 @@ static FLAC__bool read_from_aiff_(foreign_metadata_t *fm, FILE *f, const char **
if
(
!
append_block_
(
fm
,
offset
,
12
,
error
))
return
false
;
eof_offset
=
8
+
unpack32be_
(
buffer
+
4
);
/*fprintf(stderr,"@@@@@@ off=%d eof=%d\n",(int)offset,(int)eof_offset);*/
while
(
!
feof
(
f
))
{
FLAC__uint32
size
,
ssnd_offset_size
=
0
;
FLAC__uint32
size
;
if
((
offset
=
ftello
(
f
))
<
0
)
{
if
(
error
)
*
error
=
"ftello() error (003)"
;
return
false
;
...
...
@@ -102,43 +123,51 @@ static FLAC__bool read_from_aiff_(foreign_metadata_t *fm, FILE *f, const char **
if
(
error
)
*
error
=
"invalid AIFF file: multiple
\"
COMM
\"
chunks (005)"
;
return
false
;
}
if
(
fm
->
audio_block
)
{
if
(
error
)
*
error
=
"invalid AIFF file:
\"
SSND
\"
chunk before
\"
COMM
\"
chunk (006)"
;
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)"
;
if
(
error
)
*
error
=
"invalid AIFF file: multiple
\"
SSND
\"
chunks (007)"
;
return
false
;
}
if
(
!
fm
->
format_block
)
{
if
(
error
)
*
error
=
"invalid AIFF file:
\"
SSND
\"
chunk before
\"
COMM
\"
chunk (008)"
;
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 (00
7
)"
;
if
(
error
)
*
error
=
"invalid AIFF file (00
9
)"
;
return
false
;
}
ssnd_offset_size
=
unpack32be_
(
buffer
+
8
);
fm
->
ssnd_offset_size
=
unpack32be_
(
buffer
+
8
);
if
(
fseeko
(
f
,
-
4
,
SEEK_CUR
)
<
0
)
{
if
(
error
)
*
error
=
"invalid AIFF file: seek error (00
8
)"
;
if
(
error
)
*
error
=
"invalid AIFF file: seek error (0
1
0)"
;
return
false
;
}
}
if
(
!
append_block_
(
fm
,
offset
,
8
+
(
memcmp
(
buffer
,
"SSND"
,
4
)
?
size
:
8
+
ssnd_offset_size
),
error
))
if
(
!
append_block_
(
fm
,
offset
,
8
+
(
memcmp
(
buffer
,
"SSND"
,
4
)
?
size
:
8
+
fm
->
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
);
/*
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 (0
09
)"
;
if
(
error
)
*
error
=
"invalid AIFF file: seek error (0
11
)"
;
return
false
;
}
}
if
(
eof_offset
!=
ftello
(
f
))
{
if
(
error
)
*
error
=
"invalid AIFF file: unexpected EOF (01
0
)"
;
if
(
error
)
*
error
=
"invalid AIFF file: unexpected EOF (01
2
)"
;
return
false
;
}
if
(
!
fm
->
format_block
)
{
if
(
error
)
*
error
=
"invalid AIFF file: missing
\"
COMM
\"
chunk (01
1
)"
;
if
(
error
)
*
error
=
"invalid AIFF file: missing
\"
COMM
\"
chunk (01
3
)"
;
return
false
;
}
if
(
!
fm
->
audio_block
)
{
if
(
error
)
*
error
=
"invalid AIFF file: missing
\"
SSND
\"
chunk (01
2
)"
;
if
(
error
)
*
error
=
"invalid AIFF file: missing
\"
SSND
\"
chunk (01
4
)"
;
return
false
;
}
return
true
;
...
...
@@ -159,7 +188,7 @@ static FLAC__bool read_from_wave_(foreign_metadata_t *fm, FILE *f, const char **
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
);
/*
fprintf(stderr,"@@@@@@ off=%d eof=%d\n",(int)offset,(int)eof_offset);
*/
while
(
!
feof
(
f
))
{
FLAC__uint32
size
;
if
((
offset
=
ftello
(
f
))
<
0
)
{
...
...
@@ -181,33 +210,41 @@ fprintf(stderr,"@@@@@@ off=%d eof=%d\n",(int)offset,(int)eof_offset);
if
(
error
)
*
error
=
"invalid WAVE file: multiple
\"
fmt
\"
chunks (005)"
;
return
false
;
}
if
(
fm
->
audio_block
)
{
if
(
error
)
*
error
=
"invalid WAVE file:
\"
data
\"
chunk before
\"
fmt
\"
chunk (006)"
;
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)"
;
if
(
error
)
*
error
=
"invalid WAVE file: multiple
\"
data
\"
chunks (007)"
;
return
false
;
}
if
(
!
fm
->
format_block
)
{
if
(
error
)
*
error
=
"invalid WAVE file:
\"
data
\"
chunk before
\"
fmt
\"
chunk (008)"
;
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
);
/*
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 (00
7
)"
;
if
(
error
)
*
error
=
"invalid WAVE file: seek error (00
9
)"
;
return
false
;
}
}
if
(
eof_offset
!=
ftello
(
f
))
{
if
(
error
)
*
error
=
"invalid WAVE file: unexpected EOF (00
8
)"
;
if
(
error
)
*
error
=
"invalid WAVE file: unexpected EOF (0
1
0)"
;
return
false
;
}
if
(
!
fm
->
format_block
)
{
if
(
error
)
*
error
=
"invalid WAVE file: missing
\"
fmt
\"
chunk (0
09
)"
;
if
(
error
)
*
error
=
"invalid WAVE file: missing
\"
fmt
\"
chunk (0
11
)"
;
return
false
;
}
if
(
!
fm
->
audio_block
)
{
if
(
error
)
*
error
=
"invalid WAVE file: missing
\"
data
\"
chunk (01
0
)"
;
if
(
error
)
*
error
=
"invalid WAVE file: missing
\"
data
\"
chunk (01
2
)"
;
return
false
;
}
return
true
;
...
...
@@ -215,9 +252,9 @@ fprintf(stderr,"@@@@@@ chunk=%c%c%c%c offset=%d size=%d\n",buffer[0],buffer[1],b
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
[
4
096
];
FLAC__byte
buffer
[
4
];
const
unsigned
ID_LEN
=
FLAC__STREAM_METADATA_APPLICATION_ID_LEN
/
8
;
size_t
left
,
block_num
=
0
;
size_t
block_num
=
0
;
FLAC__ASSERT
(
sizeof
(
buffer
)
>=
ID_LEN
);
while
(
block_num
<
fm
->
num_blocks
)
{
/* find next matching padding block */
...
...
@@ -232,14 +269,14 @@ static FLAC__bool write_to_flac_(foreign_metadata_t *fm, FILE *fin, FILE *fout,
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
));
/*
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
(
fseek
o
(
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
(
fseek
o
(
fout
,
FLAC__metadata_simple_iterator_get_block_offset
(
it
),
SEEK_SET
)
<
0
)
{
if
(
error
)
*
error
=
"seek failed in FLAC file (007)"
;
return
false
;
}
...
...
@@ -248,41 +285,200 @@ fprintf(stderr,"@@@@@@ flac offset = %d\n",(int)FLAC__metadata_simple_iterator_g
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)"
;
if
(
error
)
*
error
=
"write failed in FLAC 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
(
fseek
o
(
fout
,
FLAC__STREAM_METADATA_LENGTH_LEN
/
8
,
SEEK_CUR
)
<
0
)
{
if
(
error
)
*
error
=
"seek failed in FLAC file (009)"
;
return
false
;
}