add --warnings-as-errors option to flac; for picture importing, allow MIME type in specification to be blank and filled in automatically; allow specification to be just the filename, with other fields filled in automatically

This commit is contained in:
Josh Coalson
2007-02-06 01:43:58 +00:00
parent 559321c710
commit b05d4ee337
9 changed files with 191 additions and 46 deletions

View File

@@ -83,6 +83,8 @@
<ul> <ul>
<li>Improved compression with no impact on format or decoding speed.</li> <li>Improved compression with no impact on format or decoding speed.</li>
<li>Encoding and decoding speedups across the board. Encoding at -8 is twice as fast.</li> <li>Encoding and decoding speedups across the board. Encoding at -8 is twice as fast.</li>
<li>Added a new option <span class="argument"><a href="documentation_tools_flac.html#flac_options_warnings_as_errors">-w,-@@@@@@-warnings-as-errors</a></span> for treating all warnings as errors.</li>
<li>Allow <span class="argument"><a href="documentation_tools_flac.html#flac_options_picture">-@@@@@@-picture</a></span> option to take only a filename, and have all other attributes extracted from the file itself.</li>
<li>Fixed a bug that caused suboptimal default compression settings in some locales (<a href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1608883&amp;group_id=13478&amp;atid=113478">SF #1608883</a>).</li> <li>Fixed a bug that caused suboptimal default compression settings in some locales (<a href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1608883&amp;group_id=13478&amp;atid=113478">SF #1608883</a>).</li>
<li>Fixed a bug where FLAC-to-FLAC transcoding of a corrupted FLAC file would truncate the transcoded file at the first error (<a href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1615019&amp;group_id=13478&amp;atid=113478">SF #1615019</a>).</li> <li>Fixed a bug where FLAC-to-FLAC transcoding of a corrupted FLAC file would truncate the transcoded file at the first error (<a href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1615019&amp;group_id=13478&amp;atid=113478">SF #1615019</a>).</li>
<li>Fixed a bug where using <span class="argument"><a href="documentation_tools_flac.html#flac_options_decode_through_errors">-F</a></span> with FLAC-to-FLAC transcoding of a corrupted FLAC would have no effect (<a href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1615391&amp;group_id=13478&amp;atid=113478">SF #1615391</a>).</li> <li>Fixed a bug where using <span class="argument"><a href="documentation_tools_flac.html#flac_options_decode_through_errors">-F</a></span> with FLAC-to-FLAC transcoding of a corrupted FLAC would have no effect (<a href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1615391&amp;group_id=13478&amp;atid=113478">SF #1615391</a>).</li>
@@ -92,6 +94,7 @@
<li> <li>
metaflac: metaflac:
<ul> <ul>
<li>Allow <span class="argument"><a href="documentation_tools_metaflac.html#metaflac_shorthand_import_picture_from">-@@@@@@-import-picture-from</a></span> option to take only a filename, and have all other attributes extracted from the file itself.</li>
<li>(none)</li> <li>(none)</li>
</ul> </ul>
</li> </li>

View File

@@ -210,6 +210,15 @@
Do not print anything of any kind, including warnings or errors. The exit code will be the only way to determine successful completion. Do not print anything of any kind, including warnings or errors. The exit code will be the only way to determine successful completion.
</td> </td>
</tr> </tr>
<tr>
<td nowrap="nowrap" align="right" valign="top" bgcolor="#F4F4CC">
<a name="flac_options_warnings_as_errors" />
<span class="argument">-w</span>, <span class="argument">--warnings-as-errors</span>
</td>
<td>
Treat all warnings as errors (which cause <span class="commandname">flac</span> to terminate with a non-zero exit code).
</td>
</tr>
<tr> <tr>
<td nowrap="nowrap" align="right" valign="top" bgcolor="#F4F4CC"> <td nowrap="nowrap" align="right" valign="top" bgcolor="#F4F4CC">
<a name="flac_options_force" /> <a name="flac_options_force" />
@@ -465,12 +474,12 @@
<tr> <tr>
<td nowrap="nowrap" align="right" valign="top" bgcolor="#F4F4CC"> <td nowrap="nowrap" align="right" valign="top" bgcolor="#F4F4CC">
<a name="flac_options_picture" /> <a name="flac_options_picture" />
<span class="argument">--picture=SPECIFICATION</span> <span class="argument">--picture={FILENAME|SPECIFICATION}</span>
</td> </td>
<td> <td>
Import a picture and store it in a <a href="format.html#def_PICTURE"><span class="code">PICTURE</span></a> metadata block. More than one <span class="argument">--picture</span> command can be specified. The <span class="argument">SPECIFICATION</span> is a string whose parts are separated by <span class="argument">|</span> (pipe) characters. Some parts may be left empty to invoke default values. The format of <span class="argument">SPECIFICATION</span> is<br /> Import a picture and store it in a <a href="format.html#def_PICTURE"><span class="code">PICTURE</span></a> metadata block. More than one <span class="argument">--picture</span> command can be specified. Either a filename for the picture file or a more complete specification form can be used. The <span class="argument">SPECIFICATION</span> is a string whose parts are separated by | (pipe) characters. Some parts may be left empty to invoke default values. <span class="argument">FILENAME</span> is just shorthand for <span class="argument">||||FILENAME</span>. The format of <span class="argument">SPECIFICATION</span> is<br />
<br /> <br />
<tt>&nbsp;&nbsp;[TYPE]|MIME-TYPE|[DESCRIPTION]|[WIDTHxHEIGHTxDEPTH[/COLORS]]|FILE</tt><br /> <tt>&nbsp;&nbsp;[TYPE]|[MIME-TYPE]|[DESCRIPTION]|[WIDTHxHEIGHTxDEPTH[/COLORS]]|FILE</tt><br />
<br /> <br />
<span class="argument">TYPE</span> is optional; it is a number from one of:<br /> <span class="argument">TYPE</span> is optional; it is a number from one of:<br />
<ul> <ul>
@@ -498,7 +507,7 @@
</ul> </ul>
The default is 3 (front cover). There may only be one picture each of type 1 and 2 in a file.<br/> The default is 3 (front cover). There may only be one picture each of type 1 and 2 in a file.<br/>
<br /> <br />
<span class="argument">MIME-TYPE</span> is mandatory; for best compatibility with players, use pictures with MIME type <tt>image/jpeg</tt> or <tt>image/png</tt>. The MIME type can also be --&gt; to mean that <span class="argument">FILE</span> is actually a URL to an image, though this use is discouraged.<br /> <span class="argument">MIME-TYPE</span> is optional; if left blank, it will be detected from the file. For best compatibility with players, use pictures with MIME type <tt>image/jpeg</tt> or <tt>image/png</tt>. The MIME type can also be --&gt; to mean that <span class="argument">FILE</span> is actually a URL to an image, though this use is discouraged.<br />
<br /> <br />
<span class="argument">DESCRIPTION</span> is optional; the default is an empty string.<br /> <span class="argument">DESCRIPTION</span> is optional; the default is an empty string.<br />
<br /> <br />
@@ -887,6 +896,7 @@
<span class="argument">--no-seektable</span><br /> <span class="argument">--no-seektable</span><br />
<span class="argument">--no-silent</span><br /> <span class="argument">--no-silent</span><br />
<span class="argument">--no-verify</span> <span class="argument">--no-verify</span>
<span class="argument">--no-warnings-as-errors</span>
</td> </td>
<td> <td>
Can all be used to turn off a particular option. Can all be used to turn off a particular option.
@@ -972,6 +982,7 @@
<a href="#negative_options" /><span class="argument">--no-seektable</span></a><br /> <a href="#negative_options" /><span class="argument">--no-seektable</span></a><br />
<a href="#negative_options" /><span class="argument">--no-silent</span></a><br /> <a href="#negative_options" /><span class="argument">--no-silent</span></a><br />
<a href="#negative_options" /><span class="argument">--no-verify</span></a><br /> <a href="#negative_options" /><span class="argument">--no-verify</span></a><br />
<a href="#negative_options" /><span class="argument">--no-warnings-as-errors</span></a><br />
<a href="#flac_options_output_name" /><span class="argument">-o</span></a><br /> <a href="#flac_options_output_name" /><span class="argument">-o</span></a><br />
<a href="#flac_options_ogg" /><span class="argument">--ogg</span></a><br /> <a href="#flac_options_ogg" /><span class="argument">--ogg</span></a><br />
<a href="#flac_options_output_name" /><span class="argument">--output-name</span></a><br /> <a href="#flac_options_output_name" /><span class="argument">--output-name</span></a><br />
@@ -1008,6 +1019,8 @@
<a href="#flac_options_verify" /><span class="argument">-V</span></a><br /> <a href="#flac_options_verify" /><span class="argument">-V</span></a><br />
<a href="#flac_options_version" /><span class="argument">-v</span></a><br /> <a href="#flac_options_version" /><span class="argument">-v</span></a><br />
<a href="#flac_options_verify" /><span class="argument">--verify</span></a><br /> <a href="#flac_options_verify" /><span class="argument">--verify</span></a><br />
<a href="#flac_options_warnings_as_errors" /><span class="argument">-w</span></a><br />
<a href="#flac_options_warnings_as_errors" /><span class="argument">--warnings-as-errors</span></a><br />
<a href="#flac_options_version" /><span class="argument">--version</span></a><br /> <a href="#flac_options_version" /><span class="argument">--version</span></a><br />
</div> </div>

View File

@@ -329,7 +329,7 @@
<tr> <tr>
<td nowrap="nowrap" align="right" valign="top" bgcolor="#F4F4CC"> <td nowrap="nowrap" align="right" valign="top" bgcolor="#F4F4CC">
<a name="metaflac_shorthand_import_picture_from" /> <a name="metaflac_shorthand_import_picture_from" />
<span class="argument">--import-picture-from=SPECIFICATION</span> <span class="argument">--import-picture-from={FILENAME|SPECIFICATION}</span>
</td> </td>
<td> <td>
Import a picture and store it in a <a href="format.html#def_PICTURE"><span class="code">PICTURE</span></a> metadata block. See the <span class="commandname">flac</span> option <span class="argument"><a href="documentation_tools_flac.html#flac_options_picture">--picture</a></span> for an explanation of the <span class="argument">SPECIFICATION</span> syntax. Import a picture and store it in a <a href="format.html#def_PICTURE"><span class="code">PICTURE</span></a> metadata block. See the <span class="commandname">flac</span> option <span class="argument"><a href="documentation_tools_flac.html#flac_options_picture">--picture</a></span> for an explanation of the <span class="argument">SPECIFICATION</span> syntax.

View File

@@ -157,6 +157,14 @@
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>-w</option>, <option>--warnings-as-errors</option>
</term>
<listitem>
<para>Treat all warnings as errors (which cause flac to terminate with a non-zero exit code).</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><option>-f</option>, <option>--force</option> <term><option>-f</option>, <option>--force</option>
</term> </term>
@@ -303,11 +311,11 @@
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><option>--picture</option>=<replaceable>SPECIFICATION</replaceable></term> <term><option>--picture</option>={<replaceable>FILENAME</replaceable>|<replaceable>SPECIFICATION</replaceable>}</term>
<listitem> <listitem>
<para>Import a picture and store it in a PICTURE metadata block. More than one --picture command can be specified. The SPECIFICATION is a string whose parts are separated by | (pipe) characters. Some parts may be left empty to invoke default values. The format of SPECIFICATION is</para> <para>Import a picture and store it in a PICTURE metadata block. More than one --picture command can be specified. Either a filename for the picture file or a more complete specification form can be used. The SPECIFICATION is a string whose parts are separated by | (pipe) characters. Some parts may be left empty to invoke default values. FILENAME is just shorthand for "||||FILENAME". The format of SPECIFICATION is</para>
<para>[TYPE]|MIME-TYPE|[DESCRIPTION]|[WIDTHxHEIGHTxDEPTH[/COLORS]]|FILE</para> <para>[TYPE]|[MIME-TYPE]|[DESCRIPTION]|[WIDTHxHEIGHTxDEPTH[/COLORS]]|FILE</para>
<para>TYPE is optional; it is a number from one of:</para> <para>TYPE is optional; it is a number from one of:</para>
<para>0: Other</para> <para>0: Other</para>
<para>1: 32x32 pixels 'file icon' (PNG only)</para> <para>1: 32x32 pixels 'file icon' (PNG only)</para>
@@ -332,7 +340,7 @@
<para>20: Publisher/Studio logotype</para> <para>20: Publisher/Studio logotype</para>
<para>The default is 3 (front cover). There may only be one picture each of type 1 and 2 in a file.</para> <para>The default is 3 (front cover). There may only be one picture each of type 1 and 2 in a file.</para>
<para>MIME-TYPE is mandatory; for best compatibility with players, use pictures with MIME type image/jpeg or image/png. The MIME type can also be --&gt; to mean that FILE is actually a URL to an image, though this use is discouraged.</para> <para>MIME-TYPE is optional; if left blank, it will be detected from the file. For best compatibility with players, use pictures with MIME type image/jpeg or image/png. The MIME type can also be --&gt; to mean that FILE is actually a URL to an image, though this use is discouraged.</para>
<para>DESCRIPTION is optional; the default is an empty string.</para> <para>DESCRIPTION is optional; the default is an empty string.</para>
@@ -656,6 +664,7 @@
<term><option>--no-seektable</option></term> <term><option>--no-seektable</option></term>
<term><option>--no-silent</option></term> <term><option>--no-silent</option></term>
<term><option>--no-verify</option></term> <term><option>--no-verify</option></term>
<term><option>--no-warnings-as-errors</option></term>
<listitem> <listitem>
<para>These flags can be used to invert the sense of the corresponding normal option.</para> <para>These flags can be used to invert the sense of the corresponding normal option.</para>
</listitem> </listitem>

View File

@@ -49,6 +49,7 @@ typedef struct {
FLAC__bool is_aiff_out; FLAC__bool is_aiff_out;
FLAC__bool is_wave_out; FLAC__bool is_wave_out;
FLAC__bool treat_warnings_as_errors;
FLAC__bool continue_through_decode_errors; FLAC__bool continue_through_decode_errors;
FLAC__bool channel_map_none; FLAC__bool channel_map_none;
@@ -102,7 +103,7 @@ static FLAC__bool is_big_endian_host_;
/* /*
* local routines * 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 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 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 void DecoderSession_destroy(DecoderSession *d, FLAC__bool error_occurred); 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, decode_options_t decode_options, const char *infilename);
static FLAC__bool DecoderSession_process(DecoderSession *d); static FLAC__bool DecoderSession_process(DecoderSession *d);
@@ -141,6 +142,7 @@ int flac__decode_aiff(const char *infilename, const char *outfilename, FLAC__boo
#endif #endif
/*is_aiff_out=*/true, /*is_aiff_out=*/true,
/*is_wave_out=*/false, /*is_wave_out=*/false,
options.common.treat_warnings_as_errors,
options.common.continue_through_decode_errors, options.common.continue_through_decode_errors,
options.common.channel_map_none, options.common.channel_map_none,
options.common.replaygain_synthesis_spec, options.common.replaygain_synthesis_spec,
@@ -178,6 +180,7 @@ int flac__decode_wav(const char *infilename, const char *outfilename, FLAC__bool
#endif #endif
/*is_aiff_out=*/false, /*is_aiff_out=*/false,
/*is_wave_out=*/true, /*is_wave_out=*/true,
options.common.treat_warnings_as_errors,
options.common.continue_through_decode_errors, options.common.continue_through_decode_errors,
options.common.channel_map_none, options.common.channel_map_none,
options.common.replaygain_synthesis_spec, options.common.replaygain_synthesis_spec,
@@ -218,6 +221,7 @@ int flac__decode_raw(const char *infilename, const char *outfilename, FLAC__bool
#endif #endif
/*is_aiff_out=*/false, /*is_aiff_out=*/false,
/*is_wave_out=*/false, /*is_wave_out=*/false,
options.common.treat_warnings_as_errors,
options.common.continue_through_decode_errors, options.common.continue_through_decode_errors,
options.common.channel_map_none, options.common.channel_map_none,
options.common.replaygain_synthesis_spec, options.common.replaygain_synthesis_spec,
@@ -241,7 +245,7 @@ int flac__decode_raw(const char *infilename, const char *outfilename, FLAC__bool
return DecoderSession_finish_ok(&decoder_session); 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 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 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)
{ {
#if FLAC__HAS_OGG #if FLAC__HAS_OGG
d->is_ogg = is_ogg; d->is_ogg = is_ogg;
@@ -251,6 +255,7 @@ FLAC__bool DecoderSession_construct(DecoderSession *d, FLAC__bool is_ogg, FLAC__
d->is_aiff_out = is_aiff_out; d->is_aiff_out = is_aiff_out;
d->is_wave_out = is_wave_out; d->is_wave_out = is_wave_out;
d->treat_warnings_as_errors = treat_warnings_as_errors;
d->continue_through_decode_errors = continue_through_decode_errors; d->continue_through_decode_errors = continue_through_decode_errors;
d->channel_map_none = channel_map_none; d->channel_map_none = channel_map_none;
d->replaygain.spec = replaygain_synthesis_spec; d->replaygain.spec = replaygain_synthesis_spec;
@@ -470,9 +475,11 @@ int DecoderSession_finish_ok(DecoderSession *d)
else { else {
if(!d->got_stream_info) { if(!d->got_stream_info) {
flac__utils_printf(stderr, 1, "\r%s: WARNING, cannot check MD5 signature since there was no STREAMINFO\n", d->inbasefilename); flac__utils_printf(stderr, 1, "\r%s: WARNING, cannot check MD5 signature since there was no STREAMINFO\n", d->inbasefilename);
ok = !d->treat_warnings_as_errors;
} }
else if(!d->has_md5sum) { else if(!d->has_md5sum) {
flac__utils_printf(stderr, 1, "\r%s: WARNING, cannot check MD5 signature since it was unset in the STREAMINFO\n", d->inbasefilename); flac__utils_printf(stderr, 1, "\r%s: WARNING, cannot check MD5 signature since it was unset in the STREAMINFO\n", d->inbasefilename);
ok = !d->treat_warnings_as_errors;
} }
flac__utils_printf(stderr, 2, "\r%s: %s \n", d->inbasefilename, d->test_only? "ok ":d->analysis_mode?"done ":"done"); flac__utils_printf(stderr, 2, "\r%s: %s \n", d->inbasefilename, d->test_only? "ok ":d->analysis_mode?"done ":"done");
} }
@@ -551,6 +558,8 @@ FLAC__bool write_iff_headers(FILE *f, DecoderSession *decoder_session, FLAC__uin
flac__utils_printf(stderr, 1, "%s: WARNING, don't have accurate sample count available for %s header.\n", decoder_session->inbasefilename, fmt_desc); flac__utils_printf(stderr, 1, "%s: WARNING, don't have accurate sample count available for %s header.\n", decoder_session->inbasefilename, fmt_desc);
flac__utils_printf(stderr, 1, " Generated %s file will have a data chunk size of 0. Try\n", fmt_desc); flac__utils_printf(stderr, 1, " Generated %s file will have a data chunk size of 0. Try\n", fmt_desc);
flac__utils_printf(stderr, 1, " decoding directly to a file instead.\n"); flac__utils_printf(stderr, 1, " decoding directly to a file instead.\n");
if(decoder_session->treat_warnings_as_errors)
return false;
} }
else { else {
decoder_session->iff_headers_need_fixup = true; decoder_session->iff_headers_need_fixup = true;
@@ -1076,6 +1085,10 @@ void metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMet
double reference, gain, peak; double reference, gain, peak;
if (!(decoder_session->replaygain.apply = grabbag__replaygain_load_from_vorbiscomment(metadata, decoder_session->replaygain.spec.use_album_gain, /*strict=*/false, &reference, &gain, &peak))) { if (!(decoder_session->replaygain.apply = grabbag__replaygain_load_from_vorbiscomment(metadata, decoder_session->replaygain.spec.use_album_gain, /*strict=*/false, &reference, &gain, &peak))) {
flac__utils_printf(stderr, 1, "%s: WARNING: can't get %s (or even %s) ReplayGain tags\n", decoder_session->inbasefilename, decoder_session->replaygain.spec.use_album_gain? "album":"track", decoder_session->replaygain.spec.use_album_gain? "track":"album"); flac__utils_printf(stderr, 1, "%s: WARNING: can't get %s (or even %s) ReplayGain tags\n", decoder_session->inbasefilename, decoder_session->replaygain.spec.use_album_gain? "album":"track", decoder_session->replaygain.spec.use_album_gain? "track":"album");
if(decoder_session->treat_warnings_as_errors) {
decoder_session->abort_flag = true;
return;
}
} }
else { else {
const char *ls[] = { "no", "peak", "hard" }; const char *ls[] = { "no", "peak", "hard" };
@@ -1085,6 +1098,7 @@ void metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMet
FLAC__replaygain_synthesis__init_dither_context(&decoder_session->replaygain.dither_context, decoder_session->bps, decoder_session->replaygain.spec.noise_shaping); FLAC__replaygain_synthesis__init_dither_context(&decoder_session->replaygain.dither_context, decoder_session->bps, decoder_session->replaygain.spec.noise_shaping);
flac__utils_printf(stderr, 1, "%s: INFO: applying %s ReplayGain (gain=%0.2fdB+preamp=%0.1fdB, %s noise shaping, %s limiting) to output\n", decoder_session->inbasefilename, decoder_session->replaygain.spec.use_album_gain? "album":"track", gain, decoder_session->replaygain.spec.preamp, ns[decoder_session->replaygain.spec.noise_shaping], ls[decoder_session->replaygain.spec.limiter]); flac__utils_printf(stderr, 1, "%s: INFO: applying %s ReplayGain (gain=%0.2fdB+preamp=%0.1fdB, %s noise shaping, %s limiting) to output\n", decoder_session->inbasefilename, decoder_session->replaygain.spec.use_album_gain? "album":"track", gain, decoder_session->replaygain.spec.preamp, ns[decoder_session->replaygain.spec.noise_shaping], ls[decoder_session->replaygain.spec.limiter]);
flac__utils_printf(stderr, 1, "%s: WARNING: applying ReplayGain is not lossless\n", decoder_session->inbasefilename); flac__utils_printf(stderr, 1, "%s: WARNING: applying ReplayGain is not lossless\n", decoder_session->inbasefilename);
/* don't check if(decoder_session->treat_warnings_as_errors) because the user explicitly asked for it */
} }
} }
(void)flac__utils_get_channel_mask_tag(metadata, &decoder_session->channel_mask); (void)flac__utils_get_channel_mask_tag(metadata, &decoder_session->channel_mask);

View File

@@ -36,6 +36,7 @@ typedef struct {
} replaygain_synthesis_spec_t; } replaygain_synthesis_spec_t;
typedef struct { typedef struct {
FLAC__bool treat_warnings_as_errors;
FLAC__bool continue_through_decode_errors; FLAC__bool continue_through_decode_errors;
replaygain_synthesis_spec_t replaygain_synthesis_spec; replaygain_synthesis_spec_t replaygain_synthesis_spec;
#if FLAC__HAS_OGG #if FLAC__HAS_OGG

View File

@@ -67,6 +67,7 @@ typedef struct {
FLAC__uint64 skip; FLAC__uint64 skip;
FLAC__uint64 until; /* a value of 0 mean end-of-stream (i.e. --until=-0) */ FLAC__uint64 until; /* a value of 0 mean end-of-stream (i.e. --until=-0) */
FLAC__bool treat_warnings_as_errors;
FLAC__bool continue_through_decode_errors; FLAC__bool continue_through_decode_errors;
FLAC__bool replay_gain; FLAC__bool replay_gain;
unsigned channels; unsigned channels;
@@ -119,7 +120,7 @@ extern FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEn
/* /*
* local routines * local routines
*/ */
static FLAC__bool EncoderSession_construct(EncoderSession *e, FLAC__bool use_ogg, FLAC__bool verify, FLAC__bool continue_through_decode_errors, FILE *infile, const char *infilename, const char *outfilename); static FLAC__bool EncoderSession_construct(EncoderSession *e, FLAC__bool use_ogg, FLAC__bool verify, FLAC__bool treat_warnings_as_errors, FLAC__bool continue_through_decode_errors, FILE *infile, const char *infilename, const char *outfilename);
static void EncoderSession_destroy(EncoderSession *e); static void EncoderSession_destroy(EncoderSession *e);
static int EncoderSession_finish_ok(EncoderSession *e, int info_align_carry, int info_align_zero); static int EncoderSession_finish_ok(EncoderSession *e, int info_align_carry, int info_align_zero);
static int EncoderSession_finish_error(EncoderSession *e); static int EncoderSession_finish_error(EncoderSession *e);
@@ -138,7 +139,7 @@ static FLAC__bool flac_decoder_eof_callback(const FLAC__StreamDecoder *decoder,
static FLAC__StreamDecoderWriteStatus flac_decoder_write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); static FLAC__StreamDecoderWriteStatus flac_decoder_write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
static void flac_decoder_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data); static void flac_decoder_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
static void flac_decoder_error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); static void flac_decoder_error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
static FLAC__bool parse_cuesheet(FLAC__StreamMetadata **cuesheet, const char *cuesheet_filename, const char *inbasefilename, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset); static FLAC__bool parse_cuesheet(FLAC__StreamMetadata **cuesheet, const char *cuesheet_filename, const char *inbasefilename, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset, FLAC__bool treat_warnings_as_errors);
static void print_stats(const EncoderSession *encoder_session); static void print_stats(const EncoderSession *encoder_session);
static void print_error_with_init_status(const EncoderSession *e, const char *message, FLAC__StreamEncoderInitStatus init_status); static void print_error_with_init_status(const EncoderSession *e, const char *message, FLAC__StreamEncoderInitStatus init_status);
static void print_error_with_state(const EncoderSession *e, const char *message); static void print_error_with_state(const EncoderSession *e, const char *message);
@@ -179,6 +180,7 @@ int flac__encode_aif(FILE *infile, off_t infilesize, const char *infilename, con
/*use_ogg=*/false, /*use_ogg=*/false,
#endif #endif
options.common.verify, options.common.verify,
options.common.treat_warnings_as_errors,
options.common.continue_through_decode_errors, options.common.continue_through_decode_errors,
infile, infile,
infilename, infilename,
@@ -221,6 +223,8 @@ int flac__encode_aif(FILE *infile, off_t infilesize, const char *infilename, con
} }
else if(!is_aifc && xx!=minimum_comm_size) { else if(!is_aifc && xx!=minimum_comm_size) {
flac__utils_printf(stderr, 1, "%s: WARNING: non-standard %s 'COMM' chunk has length = %u, expected %u\n", encoder_session.inbasefilename, is_aifc? "AIFF-C" : "AIFF", (unsigned int)xx, minimum_comm_size); flac__utils_printf(stderr, 1, "%s: WARNING: non-standard %s 'COMM' chunk has length = %u, expected %u\n", encoder_session.inbasefilename, is_aifc? "AIFF-C" : "AIFF", (unsigned int)xx, minimum_comm_size);
if(encoder_session.treat_warnings_as_errors)
return EncoderSession_finish_error(&encoder_session);
} }
skip= (xx-minimum_comm_size)+(xx & 1U); skip= (xx-minimum_comm_size)+(xx & 1U);
@@ -451,6 +455,8 @@ int flac__encode_aif(FILE *infile, off_t infilesize, const char *infilename, con
} }
else if(feof(infile)) { else if(feof(infile)) {
flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned int)encoder_session.total_samples_to_encode, (unsigned int)encoder_session.samples_written); flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned int)encoder_session.total_samples_to_encode, (unsigned int)encoder_session.samples_written);
if(encoder_session.treat_warnings_as_errors)
return EncoderSession_finish_error(&encoder_session);
data_bytes= 0; data_bytes= 0;
} }
} }
@@ -511,6 +517,8 @@ int flac__encode_aif(FILE *infile, off_t infilesize, const char *infilename, con
} }
else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_frame) { else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_frame) {
flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; read %u bytes; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned int)bytes_read, (unsigned int)encoder_session.total_samples_to_encode, (unsigned int)encoder_session.samples_written); flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; read %u bytes; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned int)bytes_read, (unsigned int)encoder_session.total_samples_to_encode, (unsigned int)encoder_session.samples_written);
if(encoder_session.treat_warnings_as_errors)
return EncoderSession_finish_error(&encoder_session);
} }
else { else {
info_align_carry= *options.common.align_reservoir_samples; info_align_carry= *options.common.align_reservoir_samples;
@@ -535,12 +543,18 @@ int flac__encode_aif(FILE *infile, off_t infilesize, const char *infilename, con
else { /* other chunk */ else { /* other chunk */
if(!memcmp(chunk_id, "COMM", 4)) { if(!memcmp(chunk_id, "COMM", 4)) {
flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'COMM' chunk\n", encoder_session.inbasefilename); flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'COMM' chunk\n", encoder_session.inbasefilename);
if(encoder_session.treat_warnings_as_errors)
return EncoderSession_finish_error(&encoder_session);
} }
else if(!memcmp(chunk_id, "SSND", 4)) { else if(!memcmp(chunk_id, "SSND", 4)) {
flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'SSND' chunk\n", encoder_session.inbasefilename); flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'SSND' chunk\n", encoder_session.inbasefilename);
if(encoder_session.treat_warnings_as_errors)
return EncoderSession_finish_error(&encoder_session);
} }
else { else {
flac__utils_printf(stderr, 1, "%s: WARNING: skipping unknown chunk '%s'\n", encoder_session.inbasefilename, chunk_id); flac__utils_printf(stderr, 1, "%s: WARNING: skipping unknown chunk '%s'\n", encoder_session.inbasefilename, chunk_id);
if(encoder_session.treat_warnings_as_errors)
return EncoderSession_finish_error(&encoder_session);
} }
/* chunk size */ /* chunk size */
@@ -592,6 +606,7 @@ int flac__encode_wav(FILE *infile, off_t infilesize, const char *infilename, con
/*use_ogg=*/false, /*use_ogg=*/false,
#endif #endif
options.common.verify, options.common.verify,
options.common.treat_warnings_as_errors,
options.common.continue_through_decode_errors, options.common.continue_through_decode_errors,
infile, infile,
infilename, infilename,
@@ -705,6 +720,8 @@ int flac__encode_wav(FILE *infile, off_t infilesize, const char *infilename, con
if(bps == 24 || bps == 32) { if(bps == 24 || bps == 32) {
/* let these slide with a warning since they're unambiguous */ /* let these slide with a warning since they're unambiguous */
flac__utils_printf(stderr, 1, "%s: WARNING: legacy WAVE file has format type %u but bits-per-sample=%u\n", encoder_session.inbasefilename, (unsigned)format, bps); flac__utils_printf(stderr, 1, "%s: WARNING: legacy WAVE file has format type %u but bits-per-sample=%u\n", encoder_session.inbasefilename, (unsigned)format, bps);
if(encoder_session.treat_warnings_as_errors)
return EncoderSession_finish_error(&encoder_session);
} }
else { else {
/* @@@ we could add an option to specify left- or right-justified blocks so we knew how to set 'shift' */ /* @@@ we could add an option to specify left- or right-justified blocks so we knew how to set 'shift' */
@@ -717,6 +734,8 @@ int flac__encode_wav(FILE *infile, off_t infilesize, const char *infilename, con
if(bps % 8) { if(bps % 8) {
/* assume legacy file is byte aligned with some LSBs zero; this is double-checked in format_input() */ /* assume legacy file is byte aligned with some LSBs zero; this is double-checked in format_input() */
flac__utils_printf(stderr, 1, "%s: WARNING: legacy WAVE file (format type %d) has block alignment=%u, bits-per-sample=%u, channels=%u\n", encoder_session.inbasefilename, (unsigned)format, block_align, bps, channels); flac__utils_printf(stderr, 1, "%s: WARNING: legacy WAVE file (format type %d) has block alignment=%u, bits-per-sample=%u, channels=%u\n", encoder_session.inbasefilename, (unsigned)format, block_align, bps, channels);
if(encoder_session.treat_warnings_as_errors)
return EncoderSession_finish_error(&encoder_session);
shift = 8 - (bps % 8); shift = 8 - (bps % 8);
bps += shift; bps += shift;
} }
@@ -972,6 +991,8 @@ int flac__encode_wav(FILE *infile, off_t infilesize, const char *infilename, con
} }
else if(feof(infile)) { else if(feof(infile)) {
flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned)encoder_session.total_samples_to_encode, (unsigned)encoder_session.samples_written); flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned)encoder_session.total_samples_to_encode, (unsigned)encoder_session.samples_written);
if(encoder_session.treat_warnings_as_errors)
return EncoderSession_finish_error(&encoder_session);
data_bytes = 0; data_bytes = 0;
} }
} }
@@ -1031,6 +1052,8 @@ int flac__encode_wav(FILE *infile, off_t infilesize, const char *infilename, con
} }
else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_wide_sample) { else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_wide_sample) {
flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; read %u bytes; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned)bytes_read, (unsigned)encoder_session.total_samples_to_encode, (unsigned)encoder_session.samples_written); flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; read %u bytes; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned)bytes_read, (unsigned)encoder_session.total_samples_to_encode, (unsigned)encoder_session.samples_written);
if(encoder_session.treat_warnings_as_errors)
return EncoderSession_finish_error(&encoder_session);
} }
else { else {
info_align_carry = *options.common.align_reservoir_samples; info_align_carry = *options.common.align_reservoir_samples;
@@ -1055,10 +1078,14 @@ int flac__encode_wav(FILE *infile, off_t infilesize, const char *infilename, con
else { else {
if(xx == 0x20746d66 && got_fmt_chunk) { /* "fmt " */ if(xx == 0x20746d66 && got_fmt_chunk) { /* "fmt " */
flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'fmt ' sub-chunk\n", encoder_session.inbasefilename); flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'fmt ' sub-chunk\n", encoder_session.inbasefilename);
if(encoder_session.treat_warnings_as_errors)
return EncoderSession_finish_error(&encoder_session);
} }
else if(xx == 0x61746164) { /* "data" */ else if(xx == 0x61746164) { /* "data" */
if(got_data_chunk) { if(got_data_chunk) {
flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'data' sub-chunk\n", encoder_session.inbasefilename); flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'data' sub-chunk\n", encoder_session.inbasefilename);
if(encoder_session.treat_warnings_as_errors)
return EncoderSession_finish_error(&encoder_session);
} }
else if(!got_fmt_chunk) { else if(!got_fmt_chunk) {
flac__utils_printf(stderr, 1, "%s: ERROR: got 'data' sub-chunk before 'fmt' sub-chunk\n", encoder_session.inbasefilename); flac__utils_printf(stderr, 1, "%s: ERROR: got 'data' sub-chunk before 'fmt' sub-chunk\n", encoder_session.inbasefilename);
@@ -1070,6 +1097,8 @@ int flac__encode_wav(FILE *infile, off_t infilesize, const char *infilename, con
} }
else { else {
flac__utils_printf(stderr, 1, "%s: WARNING: skipping unknown sub-chunk '%c%c%c%c'\n", encoder_session.inbasefilename, (char)(xx&255), (char)((xx>>8)&255), (char)((xx>>16)&255), (char)(xx>>24)); flac__utils_printf(stderr, 1, "%s: WARNING: skipping unknown sub-chunk '%c%c%c%c'\n", encoder_session.inbasefilename, (char)(xx&255), (char)((xx>>8)&255), (char)((xx>>16)&255), (char)(xx>>24));
if(encoder_session.treat_warnings_as_errors)
return EncoderSession_finish_error(&encoder_session);
} }
/* sub-chunk size */ /* sub-chunk size */
if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename)) if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
@@ -1114,6 +1143,7 @@ int flac__encode_raw(FILE *infile, off_t infilesize, const char *infilename, con
/*use_ogg=*/false, /*use_ogg=*/false,
#endif #endif
options.common.verify, options.common.verify,
options.common.treat_warnings_as_errors,
options.common.continue_through_decode_errors, options.common.continue_through_decode_errors,
infile, infile,
infilename, infilename,
@@ -1287,6 +1317,8 @@ int flac__encode_raw(FILE *infile, off_t infilesize, const char *infilename, con
} }
else if(feof(infile)) { else if(feof(infile)) {
flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned)encoder_session.total_samples_to_encode, (unsigned)encoder_session.samples_written); flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned)encoder_session.total_samples_to_encode, (unsigned)encoder_session.samples_written);
if(encoder_session.treat_warnings_as_errors)
return EncoderSession_finish_error(&encoder_session);
total_input_bytes_read = max_input_bytes; total_input_bytes_read = max_input_bytes;
} }
} }
@@ -1339,6 +1371,8 @@ int flac__encode_raw(FILE *infile, off_t infilesize, const char *infilename, con
} }
else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_wide_sample) { else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_wide_sample) {
flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; read %u bytes; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned)bytes_read, (unsigned)encoder_session.total_samples_to_encode, (unsigned)encoder_session.samples_written); flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; read %u bytes; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned)bytes_read, (unsigned)encoder_session.total_samples_to_encode, (unsigned)encoder_session.samples_written);
if(encoder_session.treat_warnings_as_errors)
return EncoderSession_finish_error(&encoder_session);
} }
else { else {
info_align_carry = *options.common.align_reservoir_samples; info_align_carry = *options.common.align_reservoir_samples;
@@ -1369,6 +1403,7 @@ int flac__encode_flac(FILE *infile, off_t infilesize, const char *infilename, co
/*use_ogg=*/false, /*use_ogg=*/false,
#endif #endif
options.common.verify, options.common.verify,
options.common.treat_warnings_as_errors,
options.common.continue_through_decode_errors, options.common.continue_through_decode_errors,
infile, infile,
infilename, infilename,
@@ -1518,7 +1553,7 @@ fubar1:
return EncoderSession_finish_error(&encoder_session); return EncoderSession_finish_error(&encoder_session);
} }
FLAC__bool EncoderSession_construct(EncoderSession *e, FLAC__bool use_ogg, FLAC__bool verify, FLAC__bool continue_through_decode_errors, FILE *infile, const char *infilename, const char *outfilename) FLAC__bool EncoderSession_construct(EncoderSession *e, FLAC__bool use_ogg, FLAC__bool verify, FLAC__bool treat_warnings_as_errors, FLAC__bool continue_through_decode_errors, FILE *infile, const char *infilename, const char *outfilename)
{ {
unsigned i; unsigned i;
FLAC__uint32 test = 1; FLAC__uint32 test = 1;
@@ -1543,6 +1578,7 @@ FLAC__bool EncoderSession_construct(EncoderSession *e, FLAC__bool use_ogg, FLAC_
(void)use_ogg; (void)use_ogg;
#endif #endif
e->verify = verify; e->verify = verify;
e->treat_warnings_as_errors = treat_warnings_as_errors;
e->continue_through_decode_errors = continue_through_decode_errors; e->continue_through_decode_errors = continue_through_decode_errors;
e->is_stdout = (0 == strcmp(outfilename, "-")); e->is_stdout = (0 == strcmp(outfilename, "-"));
@@ -1688,7 +1724,7 @@ FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t optio
} }
} }
if(!parse_cuesheet(&cuesheet, options.cuesheet_filename, e->inbasefilename, is_cdda, e->total_samples_to_encode)) if(!parse_cuesheet(&cuesheet, options.cuesheet_filename, e->inbasefilename, is_cdda, e->total_samples_to_encode, e->treat_warnings_as_errors))
return false; return false;
if(!convert_to_seek_table_template(options.requested_seek_points, options.num_requested_seek_points, options.cued_seekpoints? cuesheet : 0, e)) { if(!convert_to_seek_table_template(options.requested_seek_points, options.num_requested_seek_points, options.cued_seekpoints? cuesheet : 0, e)) {
@@ -1736,6 +1772,11 @@ FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t optio
if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_VORBIS_COMMENT && options.vorbis_comment->data.vorbis_comment.num_comments > 0) { if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_VORBIS_COMMENT && options.vorbis_comment->data.vorbis_comment.num_comments > 0) {
(void) flac__utils_get_channel_mask_tag(flac_decoder_data->metadata_blocks[i], &channel_mask); (void) flac__utils_get_channel_mask_tag(flac_decoder_data->metadata_blocks[i], &channel_mask);
flac__utils_printf(stderr, 1, "%s: WARNING, replacing tags from input FLAC file with those given on the command-line\n", e->inbasefilename); flac__utils_printf(stderr, 1, "%s: WARNING, replacing tags from input FLAC file with those given on the command-line\n", e->inbasefilename);
if(e->treat_warnings_as_errors) {
if(0 != cuesheet)
FLAC__metadata_object_delete(cuesheet);
return false;
}
FLAC__metadata_object_delete(flac_decoder_data->metadata_blocks[i]); FLAC__metadata_object_delete(flac_decoder_data->metadata_blocks[i]);
flac_decoder_data->metadata_blocks[i] = 0; flac_decoder_data->metadata_blocks[i] = 0;
} }
@@ -1772,16 +1813,31 @@ FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t optio
const FLAC__StreamMetadata_CueSheet *cs = &flac_decoder_data->metadata_blocks[i]->data.cue_sheet; const FLAC__StreamMetadata_CueSheet *cs = &flac_decoder_data->metadata_blocks[i]->data.cue_sheet;
if(e->total_samples_to_encode == 0) { if(e->total_samples_to_encode == 0) {
flac__utils_printf(stderr, 1, "%s: WARNING, cuesheet in input FLAC file cannot be kept if input size is not known, dropping it...\n", e->inbasefilename); flac__utils_printf(stderr, 1, "%s: WARNING, cuesheet in input FLAC file cannot be kept if input size is not known, dropping it...\n", e->inbasefilename);
if(e->treat_warnings_as_errors) {
if(0 != cuesheet)
FLAC__metadata_object_delete(cuesheet);
return false;
}
existing_cuesheet_is_bad = true; existing_cuesheet_is_bad = true;
} }
else if(e->total_samples_to_encode != cs->tracks[cs->num_tracks-1].offset) { else if(e->total_samples_to_encode != cs->tracks[cs->num_tracks-1].offset) {
flac__utils_printf(stderr, 1, "%s: WARNING, lead-out offset of cuesheet in input FLAC file does not match input length, dropping existing cuesheet...\n", e->inbasefilename); flac__utils_printf(stderr, 1, "%s: WARNING, lead-out offset of cuesheet in input FLAC file does not match input length, dropping existing cuesheet...\n", e->inbasefilename);
if(e->treat_warnings_as_errors) {
if(0 != cuesheet)
FLAC__metadata_object_delete(cuesheet);
return false;
}
existing_cuesheet_is_bad = true; existing_cuesheet_is_bad = true;
} }
} }
if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_CUESHEET && (existing_cuesheet_is_bad || 0 != cuesheet)) { if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_CUESHEET && (existing_cuesheet_is_bad || 0 != cuesheet)) {
if(0 != cuesheet) if(0 != cuesheet) {
flac__utils_printf(stderr, 1, "%s: WARNING, replacing cuesheet in input FLAC file with the one given on the command-line\n", e->inbasefilename); flac__utils_printf(stderr, 1, "%s: WARNING, replacing cuesheet in input FLAC file with the one given on the command-line\n", e->inbasefilename);
if(e->treat_warnings_as_errors) {
FLAC__metadata_object_delete(cuesheet);
return false;
}
}
FLAC__metadata_object_delete(flac_decoder_data->metadata_blocks[i]); FLAC__metadata_object_delete(flac_decoder_data->metadata_blocks[i]);
flac_decoder_data->metadata_blocks[i] = 0; flac_decoder_data->metadata_blocks[i] = 0;
} }
@@ -1823,12 +1879,24 @@ FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t optio
if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_SEEKTABLE) if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_SEEKTABLE)
existing_seektable = true; existing_seektable = true;
if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_SEEKTABLE && (e->total_samples_to_encode != flac_decoder_data->metadata_blocks[0]->data.stream_info.total_samples || options.num_requested_seek_points >= 0)) { if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_SEEKTABLE && (e->total_samples_to_encode != flac_decoder_data->metadata_blocks[0]->data.stream_info.total_samples || options.num_requested_seek_points >= 0)) {
if(options.num_requested_seek_points > 0) if(options.num_requested_seek_points > 0) {
flac__utils_printf(stderr, 1, "%s: WARNING, replacing seektable in input FLAC file with the one given on the command-line\n", e->inbasefilename); flac__utils_printf(stderr, 1, "%s: WARNING, replacing seektable in input FLAC file with the one given on the command-line\n", e->inbasefilename);
if(e->treat_warnings_as_errors) {
if(0 != cuesheet)
FLAC__metadata_object_delete(cuesheet);
return false;
}
}
else if(options.num_requested_seek_points == 0) else if(options.num_requested_seek_points == 0)
; /* no warning, silently delete existing SEEKTABLE since user specified --no-seektable (-S-) */ ; /* no warning, silently delete existing SEEKTABLE since user specified --no-seektable (-S-) */
else else {
flac__utils_printf(stderr, 1, "%s: WARNING, can't use existing seektable in input FLAC since the input size is changing or unknown, dropping existing SEEKTABLE block...\n", e->inbasefilename); flac__utils_printf(stderr, 1, "%s: WARNING, can't use existing seektable in input FLAC since the input size is changing or unknown, dropping existing SEEKTABLE block...\n", e->inbasefilename);
if(e->treat_warnings_as_errors) {
if(0 != cuesheet)
FLAC__metadata_object_delete(cuesheet);
return false;
}
}
FLAC__metadata_object_delete(flac_decoder_data->metadata_blocks[i]); FLAC__metadata_object_delete(flac_decoder_data->metadata_blocks[i]);
flac_decoder_data->metadata_blocks[i] = 0; flac_decoder_data->metadata_blocks[i] = 0;
existing_seektable = false; existing_seektable = false;
@@ -2045,6 +2113,8 @@ FLAC__bool EncoderSession_process(EncoderSession *e, const FLAC__int32 * const b
if(e->replay_gain) { if(e->replay_gain) {
if(!grabbag__replaygain_analyze(buffer, e->channels==2, e->bits_per_sample, samples)) { if(!grabbag__replaygain_analyze(buffer, e->channels==2, e->bits_per_sample, samples)) {
flac__utils_printf(stderr, 1, "%s: WARNING, error while calculating ReplayGain\n", e->inbasefilename); flac__utils_printf(stderr, 1, "%s: WARNING, error while calculating ReplayGain\n", e->inbasefilename);
if(e->treat_warnings_as_errors)
return false;
} }
} }
@@ -2088,6 +2158,8 @@ FLAC__bool convert_to_seek_table_template(const char *requested_seek_points, int
if(has_real_points) { if(has_real_points) {
if(e->is_stdout) { if(e->is_stdout) {
flac__utils_printf(stderr, 1, "%s: WARNING, cannot write back seekpoints when encoding to stdout\n", e->inbasefilename); flac__utils_printf(stderr, 1, "%s: WARNING, cannot write back seekpoints when encoding to stdout\n", e->inbasefilename);
if(e->treat_warnings_as_errors)
return false;
} }
} }
@@ -2412,7 +2484,7 @@ void flac_decoder_error_callback(const FLAC__StreamDecoder *decoder, FLAC__Strea
data->fatal_error = true; data->fatal_error = true;
} }
FLAC__bool parse_cuesheet(FLAC__StreamMetadata **cuesheet, const char *cuesheet_filename, const char *inbasefilename, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset) FLAC__bool parse_cuesheet(FLAC__StreamMetadata **cuesheet, const char *cuesheet_filename, const char *inbasefilename, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset, FLAC__bool treat_warnings_as_errors)
{ {
FILE *f; FILE *f;
unsigned last_line_read; unsigned last_line_read;
@@ -2448,6 +2520,8 @@ FLAC__bool parse_cuesheet(FLAC__StreamMetadata **cuesheet, const char *cuesheet_
/* if we're expecting CDDA, warn about non-compliance */ /* if we're expecting CDDA, warn about non-compliance */
if(is_cdda && !FLAC__format_cuesheet_is_legal(&(*cuesheet)->data.cue_sheet, /*check_cd_da_subset=*/true, &error_message)) { if(is_cdda && !FLAC__format_cuesheet_is_legal(&(*cuesheet)->data.cue_sheet, /*check_cd_da_subset=*/true, &error_message)) {
flac__utils_printf(stderr, 1, "%s: WARNING cuesheet \"%s\" is not audio CD compliant: %s\n", inbasefilename, cuesheet_filename, error_message); flac__utils_printf(stderr, 1, "%s: WARNING cuesheet \"%s\" is not audio CD compliant: %s\n", inbasefilename, cuesheet_filename, error_message);
if(treat_warnings_as_errors)
return false;
(*cuesheet)->data.cue_sheet.is_cd = false; (*cuesheet)->data.cue_sheet.is_cd = false;
} }

View File

@@ -73,6 +73,7 @@ typedef struct {
char *requested_seek_points; char *requested_seek_points;
int num_requested_seek_points; int num_requested_seek_points;
const char *cuesheet_filename; const char *cuesheet_filename;
FLAC__bool treat_warnings_as_errors;
FLAC__bool continue_through_decode_errors; /* currently only obeyed when encoding from FLAC or Ogg FLAC */ FLAC__bool continue_through_decode_errors; /* currently only obeyed when encoding from FLAC or Ogg FLAC */
FLAC__bool cued_seekpoints; FLAC__bool cued_seekpoints;
FLAC__bool channel_map_none; /* --channel-map=none specified, eventually will expand to take actual channel map */ FLAC__bool channel_map_none; /* --channel-map=none specified, eventually will expand to take actual channel map */

View File

@@ -108,8 +108,9 @@ static struct share__option long_options_[] = {
{ "stdout" , share__no_argument, 0, 'c' }, { "stdout" , share__no_argument, 0, 'c' },
{ "silent" , share__no_argument, 0, 's' }, { "silent" , share__no_argument, 0, 's' },
{ "totally-silent" , share__no_argument, 0, 0 }, { "totally-silent" , share__no_argument, 0, 0 },
{ "warnings-as-errors", share__no_argument, 0, 'w' },
{ "force" , share__no_argument, 0, 'f' }, { "force" , share__no_argument, 0, 'f' },
{ "delete-input-file", share__no_argument, 0, 0 }, { "delete-input-file" , share__no_argument, 0, 0 },
{ "output-prefix" , share__required_argument, 0, 0 }, { "output-prefix" , share__required_argument, 0, 0 },
{ "output-name" , share__required_argument, 0, 'o' }, { "output-name" , share__required_argument, 0, 'o' },
{ "skip" , share__required_argument, 0, 0 }, { "skip" , share__required_argument, 0, 0 },
@@ -197,6 +198,7 @@ static struct share__option long_options_[] = {
{ "no-qlp-coeff-prec-search" , share__no_argument, 0, 0 }, { "no-qlp-coeff-prec-search" , share__no_argument, 0, 0 },
{ "no-padding" , share__no_argument, 0, 0 }, { "no-padding" , share__no_argument, 0, 0 },
{ "no-verify" , share__no_argument, 0, 0 }, { "no-verify" , share__no_argument, 0, 0 },
{ "no-warnings-as-errors" , share__no_argument, 0, 0 },
{ "no-residual-gnuplot" , share__no_argument, 0, 0 }, { "no-residual-gnuplot" , share__no_argument, 0, 0 },
{ "no-residual-text" , share__no_argument, 0, 0 }, { "no-residual-text" , share__no_argument, 0, 0 },
/* /*
@@ -220,6 +222,7 @@ static struct {
FLAC__bool show_version; FLAC__bool show_version;
FLAC__bool mode_decode; FLAC__bool mode_decode;
FLAC__bool verify; FLAC__bool verify;
FLAC__bool treat_warnings_as_errors;
FLAC__bool force_file_overwrite; FLAC__bool force_file_overwrite;
FLAC__bool continue_through_decode_errors; FLAC__bool continue_through_decode_errors;
replaygain_synthesis_spec_t replaygain_synthesis_spec; replaygain_synthesis_spec_t replaygain_synthesis_spec;
@@ -501,6 +504,7 @@ FLAC__bool init_options(void)
option_values.show_explain = false; option_values.show_explain = false;
option_values.mode_decode = false; option_values.mode_decode = false;
option_values.verify = false; option_values.verify = false;
option_values.treat_warnings_as_errors = false;
option_values.force_file_overwrite = false; option_values.force_file_overwrite = false;
option_values.continue_through_decode_errors = false; option_values.continue_through_decode_errors = false;
option_values.replaygain_synthesis_spec.apply = false; option_values.replaygain_synthesis_spec.apply = false;
@@ -562,7 +566,7 @@ int parse_options(int argc, char *argv[])
int short_option; int short_option;
int option_index = 1; int option_index = 1;
FLAC__bool had_error = false; FLAC__bool had_error = false;
const char *short_opts = "0123456789aA:b:cdefFhHl:mMo:pP:q:r:sS:tT:vV"; const char *short_opts = "0123456789aA:b:cdefFhHl:mMo:pP:q:r:sS:tT:vVw";
while ((short_option = share__getopt_long(argc, argv, short_opts, long_options_, &option_index)) != -1) { while ((short_option = share__getopt_long(argc, argv, short_opts, long_options_, &option_index)) != -1) {
switch (short_option) { switch (short_option) {
@@ -812,6 +816,9 @@ int parse_option(int short_option, const char *long_option, const char *option_a
else if(0 == strcmp(long_option, "no-verify")) { else if(0 == strcmp(long_option, "no-verify")) {
option_values.verify = false; option_values.verify = false;
} }
else if(0 == strcmp(long_option, "no-warnings-as-errors")) {
option_values.treat_warnings_as_errors = false;
}
else if(0 == strcmp(long_option, "no-residual-gnuplot")) { else if(0 == strcmp(long_option, "no-residual-gnuplot")) {
option_values.aopts.do_residual_gnuplot = false; option_values.aopts.do_residual_gnuplot = false;
} }
@@ -887,6 +894,9 @@ int parse_option(int short_option, const char *long_option, const char *option_a
case 'V': case 'V':
option_values.verify = true; option_values.verify = true;
break; break;
case 'w':
option_values.treat_warnings_as_errors = true;
break;
case 'S': case 'S':
FLAC__ASSERT(0 != option_argument); FLAC__ASSERT(0 != option_argument);
if(0 == strcmp(option_argument, "-")) { if(0 == strcmp(option_argument, "-")) {
@@ -1122,6 +1132,7 @@ void show_help(void)
printf(" -c, --stdout Write output to stdout\n"); printf(" -c, --stdout Write output to stdout\n");
printf(" -s, --silent Do not write runtime encode/decode statistics\n"); printf(" -s, --silent Do not write runtime encode/decode statistics\n");
printf(" --totally-silent Do not print anything, including errors\n"); printf(" --totally-silent Do not print anything, including errors\n");
printf(" -w, --warnings-as-errors Treat all warnings as errors\n");
printf(" -f, --force Force overwriting of output files\n"); printf(" -f, --force Force overwriting of output files\n");
printf(" -o, --output-name=FILENAME Force the output file name\n"); printf(" -o, --output-name=FILENAME Force the output file name\n");
printf(" --output-prefix=STRING Prepend STRING to output names\n"); printf(" --output-prefix=STRING Prepend STRING to output names\n");
@@ -1196,6 +1207,7 @@ void show_help(void)
printf(" --no-silent\n"); printf(" --no-silent\n");
printf(" --no-force\n"); printf(" --no-force\n");
printf(" --no-verify\n"); printf(" --no-verify\n");
printf(" --no-warnings-as-errors\n");
} }
void show_explain(void) void show_explain(void)
@@ -1234,6 +1246,7 @@ void show_explain(void)
printf(" --totally-silent Do not print anything of any kind, including\n"); printf(" --totally-silent Do not print anything of any kind, including\n");
printf(" warnings or errors. The exit code will be the\n"); printf(" warnings or errors. The exit code will be the\n");
printf(" only way to determine successful completion.\n"); printf(" only way to determine successful completion.\n");
printf(" -w, --warnings-as-errors Treat all warnings as errors\n");
printf(" -f, --force Force overwriting of output files\n"); printf(" -f, --force Force overwriting of output files\n");
printf(" -o, --output-name=FILENAME Force the output file name; usually flac just\n"); printf(" -o, --output-name=FILENAME Force the output file name; usually flac just\n");
printf(" changes the extension. May only be used when\n"); printf(" changes the extension. May only be used when\n");
@@ -1330,10 +1343,13 @@ void show_explain(void)
printf(" --no-cued-seekpoints is specified.\n"); printf(" --no-cued-seekpoints is specified.\n");
printf(" --picture=SPECIFICATION Import a picture and store it in a PICTURE block.\n"); printf(" --picture=SPECIFICATION Import a picture and store it in a PICTURE block.\n");
printf(" More than one --picture command can be specified.\n"); printf(" More than one --picture command can be specified.\n");
printf(" The SPECIFICATION is a string whose parts are\n"); printf(" The SPECIFICATION can either be a simple filename\n");
printf(" separated by | characters. Some parts may be\n"); printf(" for the picture file, or a complete specification\n");
printf(" left empty to invoke default values. The format:\n"); printf(" whose parts are separated by | characters. Some\n");
printf(" [TYPE]|MIME-TYPE|[DESCRIPTION]|[WIDTHxHEIGHTxDEPTH[/COLORS]]|FILE\n"); printf(" parts may be left empty to invoke default values.\n");
printf(" Using a filename is shorthand for \"||||FILE\".\n");
printf(" The SPECIFICATION format is:\n");
printf(" [TYPE]|[MIME-TYPE]|[DESCRIPTION]|[WIDTHxHEIGHTxDEPTH[/COLORS]]|FILE\n");
printf(" TYPE is optional; it is a number from one of:\n"); printf(" TYPE is optional; it is a number from one of:\n");
printf(" 0: Other\n"); printf(" 0: Other\n");
printf(" 1: 32x32 pixels 'file icon' (PNG only)\n"); printf(" 1: 32x32 pixels 'file icon' (PNG only)\n");
@@ -1358,10 +1374,11 @@ void show_explain(void)
printf(" 20: Publisher/Studio logotype\n"); printf(" 20: Publisher/Studio logotype\n");
printf(" The default is 3 (front cover). There may only be one picture each\n"); printf(" The default is 3 (front cover). There may only be one picture each\n");
printf(" of type 1 and 2 in a file.\n"); printf(" of type 1 and 2 in a file.\n");
printf(" MIME-TYPE is mandatory; for best compatibility with players, use\n"); printf(" MIME-TYPE is optional; if left blank, it will be detected from the\n");
printf(" pictures with MIME type image/jpeg or image/png. The MIME type can\n"); printf(" file. For best compatibility with players, use pictures with MIME\n");
printf(" also be --> to mean that FILE is actually a URL to an image, though\n"); printf(" type image/jpeg or image/png. The MIME type can also be --> to\n");
printf(" this use is discouraged.\n"); printf(" mean that FILE is actually a URL to an image, though this use is\n");
printf(" discouraged.\n");
printf(" DESCRIPTION is optional; the default is an empty string\n"); printf(" DESCRIPTION is optional; the default is an empty string\n");
printf(" The next part specfies the resolution and color information. If\n"); printf(" The next part specfies the resolution and color information. If\n");
printf(" the MIME-TYPE is image/jpeg, image/png, or image/gif, you can\n"); printf(" the MIME-TYPE is image/jpeg, image/png, or image/gif, you can\n");
@@ -1497,6 +1514,7 @@ void show_explain(void)
printf(" --no-silent\n"); printf(" --no-silent\n");
printf(" --no-force\n"); printf(" --no-force\n");
printf(" --no-verify\n"); printf(" --no-verify\n");
printf(" --no-warnings-as-errors\n");
} }
void format_mistake(const char *infilename, FileFormat wrong, FileFormat right) void format_mistake(const char *infilename, FileFormat wrong, FileFormat right)
@@ -1552,8 +1570,13 @@ int encode_file(const char *infilename, FLAC__bool is_first_file, FLAC__bool is_
/* attempt to guess the file type based on the first 12 bytes */ /* attempt to guess the file type based on the first 12 bytes */
if((lookahead_length = fread(lookahead, 1, 12, encode_infile)) < 12) { if((lookahead_length = fread(lookahead, 1, 12, encode_infile)) < 12) {
if(fmt != RAW) if(fmt != RAW) {
format_mistake(infilename, fmt, RAW); format_mistake(infilename, fmt, RAW);
if(option_values.treat_warnings_as_errors) {
conditional_fclose(encode_infile);
return 1;
}
}
fmt= RAW; fmt= RAW;
} }
else { else {
@@ -1575,8 +1598,13 @@ int encode_file(const char *infilename, FLAC__bool is_first_file, FLAC__bool is_
else if(!memcmp(lookahead, "OggS", 4)) else if(!memcmp(lookahead, "OggS", 4))
fmt= OGGFLAC; fmt= OGGFLAC;
else { else {
if(fmt != RAW) if(fmt != RAW) {
format_mistake(infilename, fmt, RAW); format_mistake(infilename, fmt, RAW);
if(option_values.treat_warnings_as_errors) {
conditional_fclose(encode_infile);
return 1;
}
}
fmt= RAW; fmt= RAW;
} }
} }
@@ -1669,6 +1697,7 @@ int encode_file(const char *infilename, FLAC__bool is_first_file, FLAC__bool is_
common_options.until_specification.is_relative = true; common_options.until_specification.is_relative = true;
common_options.verify = option_values.verify; common_options.verify = option_values.verify;
common_options.treat_warnings_as_errors = option_values.treat_warnings_as_errors;
#if FLAC__HAS_OGG #if FLAC__HAS_OGG
common_options.use_ogg = option_values.use_ogg; common_options.use_ogg = option_values.use_ogg;
/* set a random serial number if one has not yet been specified */ /* set a random serial number if one has not yet been specified */
@@ -1851,6 +1880,7 @@ int decode_file(const char *infilename)
else else
common_options.has_cue_specification = false; common_options.has_cue_specification = false;
common_options.treat_warnings_as_errors = option_values.treat_warnings_as_errors;
common_options.continue_through_decode_errors = option_values.continue_through_decode_errors; common_options.continue_through_decode_errors = option_values.continue_through_decode_errors;
common_options.replaygain_synthesis_spec = option_values.replaygain_synthesis_spec; common_options.replaygain_synthesis_spec = option_values.replaygain_synthesis_spec;
#if FLAC__HAS_OGG #if FLAC__HAS_OGG