Commit 186479d6 authored by conrad's avatar conrad

add options to oggz_write.c to handle only the beginning (prefix) or end

(suffix) of a stream.
 + Add --prefix, --suffix and --partial options to oggz-validate
 + Update oggz-validate man page and --help text
 + Add tests for writing with OGGZ_SUFFIX and OGGZ_PREFIX
 + Bump shared version info to 3:0:2


git-svn-id: http://svn.annodex.net/liboggz/trunk@2015 8158c8cd-e7e1-0310-9fa4-c5954c97daef
parent 742fa79a
......@@ -9,7 +9,7 @@ AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE(liboggz, 0.9.3)
AM_CONFIG_HEADER(config.h)
SHARED_VERSION_INFO="2:0:1"
SHARED_VERSION_INFO="3:0:2"
SHLIB_VERSION_ARG=""
# Checks for programs.
......
......@@ -103,6 +103,29 @@ manpage.1: manpage.sgml
<para>
<command>&dhpackage;</command> accepts the following options:
</para>
<refsect2>
<title>Error suppression options</title>
<variablelist>
<varlistentry>
<term>-p, --prefix</term>
<listitem><para>Treat input as the prefix of a stream; suppress warnings about missing end-of-stream markers</para></listitem>
</varlistentry>
<varlistentry>
<term>-s, --suffix</term>
<listitem><para>Treat input as the suffix of a stream; suppress warnings about missing beginning-of-stream markers on the first chain</para></listitem>
</varlistentry>
<varlistentry>
<term>-P, --partial</term>
<listitem><para>Treat input as a the middle portion of a stream. Equivalent to both --prefix and --suffix</para></listitem>
</varlistentry>
</variablelist>
</refsect2>
<refsect2>
<title>Miscellaneous options</title>
......
......@@ -60,7 +60,18 @@ enum OggzFlags {
* \a flags = OGGZ_READ | OGGZ_AUTO will allow seeking on Speex,
* Vorbis, FLAC, Theora, CMML and all Annodex streams in units of
* milliseconds, once all bos pages have been delivered. */
OGGZ_AUTO = 0x20
OGGZ_AUTO = 0x20,
/**
* Prefix
*/
OGGZ_PREFIX = 0x40,
/**
* Suffix
*/
OGGZ_SUFFIX = 0x80
};
enum OggzStopCtl {
......
......@@ -201,7 +201,7 @@ oggz_write_feed (OGGZ * oggz, ogg_packet * op, long serialno, int flush,
ogg_packet * new_op;
unsigned char * new_buf;
int b_o_s, e_o_s, bos_auto;
int strict;
int strict, prefix, suffix;
#ifdef DEBUG
printf ("oggz_write_feed: IN\n");
......@@ -221,8 +221,10 @@ oggz_write_feed (OGGZ * oggz, ogg_packet * op, long serialno, int flush,
printf ("oggz_write_feed: (%010ld) FLUSH: %d\n", serialno, flush);
#endif
/* Cache strict */
/* Cache strict, prefix, suffix */
strict = !(oggz->flags & OGGZ_NONSTRICT);
prefix = (oggz->flags & OGGZ_PREFIX);
suffix = (oggz->flags & OGGZ_SUFFIX);
/* Set bos, eos to canonical values */
bos_auto = (op->b_o_s == -1) ? 1 : 0;
......@@ -237,7 +239,7 @@ oggz_write_feed (OGGZ * oggz, ogg_packet * op, long serialno, int flush,
return OGGZ_ERR_BOS;
}
if (b_o_s || !strict) {
if (b_o_s || !strict || suffix) {
stream = oggz_add_stream (oggz, serialno);
} else {
return OGGZ_ERR_BAD_SERIALNO;
......@@ -245,23 +247,24 @@ oggz_write_feed (OGGZ * oggz, ogg_packet * op, long serialno, int flush,
} else {
if (bos_auto) b_o_s = 0;
if (strict && stream->e_o_s)
if (!suffix && strict && stream->e_o_s)
return OGGZ_ERR_EOS;
}
/* Check packet against mapping restrictions */
if (strict) {
if (op->bytes < 0) return OGGZ_ERR_BAD_BYTES;
if (b_o_s != stream->b_o_s) return OGGZ_ERR_BAD_B_O_S;
if (!suffix && b_o_s != stream->b_o_s) return OGGZ_ERR_BAD_B_O_S;
if (op->granulepos != -1 && op->granulepos < stream->granulepos)
return OGGZ_ERR_BAD_GRANULEPOS;
/* Allow packetno == -1 to indicate oggz should fill it in; otherwise:
* if op is the first packet in the stream, initialize the stream's
* packetno to the given one, otherwise check it for strictness */
* packetno to the given one, otherwise check it for strictness.
* For stream suffixes, believe the packetno value */
if (op->packetno != -1) {
if (b_o_s) {
if (b_o_s || suffix) {
stream->packetno = op->packetno;
} else if (op->packetno <= stream->packetno) {
return OGGZ_ERR_BAD_PACKETNO;
......
......@@ -16,7 +16,7 @@ test: check
if OGGZ_CONFIG_WRITE
write_tests = write-bad-guard write-unmarked-guard write-recursive \
write-bad-bytes write-bad-bos write-dup-bos write-bad-eos \
write-bad-granulepos write-bad-packetno
write-bad-granulepos write-bad-packetno write-prefix write-suffix
endif
if OGGZ_CONFIG_READ
......@@ -67,6 +67,11 @@ write_bad_granulepos_LDADD = $(OGGZ_LIBS)
write_bad_packetno_SOURCES = write-bad-packetno.c
write_bad_packetno_LDADD = $(OGGZ_LIBS)
write_prefix_SOURCES = write-suffix.c
write_prefix_LDADD = $(OGGZ_LIBS)
write_suffix_SOURCES = write-suffix.c
write_suffix_LDADD = $(OGGZ_LIBS)
read_generated_SOURCES = read-generated.c
read_generated_LDADD = $(OGGZ_LIBS)
......
/*
Copyright (C) 2003 Commonwealth Scientific and Industrial Research
Organisation (CSIRO) Australia
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of CSIRO Australia nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <oggz/oggz.h>
#include "oggz_tests.h"
static long serialno1, serialno2;
static ogg_int64_t granulepos = 0;
static ogg_int64_t packetno = 0;
static int
hungry (OGGZ * oggz, int empty, void * user_data)
{
unsigned char buf[1];
ogg_packet op;
long serialno = serialno1;
long err;
buf[0] = 'x';
op.packet = buf;
op.bytes = 1;
op.granulepos = granulepos;
op.packetno = packetno;
switch (packetno) {
case 0:
INFO ("Feeding stream suffix");
op.b_o_s = 1;
op.e_o_s = 0;
serialno = serialno1;
break;
case 1:
op.b_o_s = 1;
op.e_o_s = 0;
serialno = serialno2;
break;
case 2:
op.b_o_s = 0;
op.e_o_s = 0;
serialno = serialno2;
break;
case 3:
op.b_o_s = 0;
op.e_o_s = 0;
serialno = serialno1;
break;
}
#ifdef DEBUG
fprintf (stderr, "Writing packet %d, serialno %d, bos=%d, eos=%d1\n",
packetno, (serialno==serialno1)?1:2, op.b_o_s, op.e_o_s);
#endif
err = oggz_write_feed (oggz, &op, serialno, 0, NULL);
if (err != 0) {
printf ("Error %d\n", err);
FAIL ("Could not feed OGGZ");
#if 0
switch (err) {
case OGGZ_ERR_BAD_SERIALNO:
FAIL ("Incorrect failure writing non-bos packet of new serialno");
break;
case OGGZ_ERR_EOS:
FAIL ("Incorrect failure writing eos packet of stream suffix");
break;
default:
FAIL ("Could not feed OGGZ");
break;
}
#endif
}
granulepos++;
packetno++;
if (packetno > 3) {
return OGGZ_STOP_OK; /* Cancel write */
} else {
return OGGZ_CONTINUE;
}
}
int
main (int argc, char * argv[])
{
OGGZ * oggz;
unsigned char buf[1];
long n;
oggz = oggz_new (OGGZ_WRITE|OGGZ_PREFIX);
if (oggz == NULL)
FAIL("newly created OGGZ == NULL");
serialno1 = oggz_serialno_new (oggz);
serialno2 = oggz_serialno_new (oggz);
if (oggz_write_set_hungry_callback (oggz, hungry, 1, NULL) != 0)
FAIL("Could not set hungry callback");
while ((n = oggz_write_output (oggz, buf, 1)) > 0);
if (oggz_close (oggz) != 0)
FAIL("Could not close OGGZ");
exit (0);
}
/*
Copyright (C) 2003 Commonwealth Scientific and Industrial Research
Organisation (CSIRO) Australia
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of CSIRO Australia nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <oggz/oggz.h>
#include "oggz_tests.h"
static long serialno1, serialno2;
static ogg_int64_t granulepos = 0;
static ogg_int64_t packetno = 0;
static int
hungry (OGGZ * oggz, int empty, void * user_data)
{
unsigned char buf[1];
ogg_packet op;
long serialno = serialno1;
long err;
buf[0] = 'x';
op.packet = buf;
op.bytes = 1;
op.granulepos = granulepos;
op.packetno = packetno;
switch (packetno) {
case 0:
INFO ("Feeding stream suffix");
op.b_o_s = 0;
op.e_o_s = 0;
serialno = serialno1;
break;
case 1:
op.b_o_s = 0;
op.e_o_s = 1;
serialno = serialno1;
break;
case 2:
op.b_o_s = 0;
op.e_o_s = 1;
serialno = serialno2;
break;
}
#ifdef DEBUG
fprintf (stderr, "Writing packet %d, serialno %d, bos=%d, eos=%d1\n",
packetno, (serialno==serialno1)?1:2, op.b_o_s, op.e_o_s);
#endif
err = oggz_write_feed (oggz, &op, serialno, 0, NULL);
if (err != 0) {
switch (err) {
case OGGZ_ERR_BAD_SERIALNO:
FAIL ("Incorrect failure writing non-bos packet of new serialno");
break;
case OGGZ_ERR_EOS:
FAIL ("Incorrect failure writing eos packet of stream suffix");
break;
default:
FAIL ("Could not feed OGGZ");
break;
}
}
granulepos++;
packetno++;
if (packetno > 2) {
return OGGZ_STOP_OK; /* Cancel write */
} else {
return OGGZ_CONTINUE;
}
}
int
main (int argc, char * argv[])
{
OGGZ * oggz;
unsigned char buf[1];
long n;
oggz = oggz_new (OGGZ_WRITE|OGGZ_SUFFIX);
if (oggz == NULL)
FAIL("newly created OGGZ == NULL");
serialno1 = oggz_serialno_new (oggz);
serialno2 = oggz_serialno_new (oggz);
if (oggz_write_set_hungry_callback (oggz, hungry, 1, NULL) != 0)
FAIL("Could not set hungry callback");
while ((n = oggz_write_output (oggz, buf, 1)) > 0);
if (oggz_close (oggz) != 0)
FAIL("Could not close OGGZ");
exit (0);
}
......@@ -71,6 +71,7 @@ static char * current_filename = NULL;
static timestamp_t current_timestamp = 0;
static int exit_status = 0;
static int nr_errors = 0;
static int prefix = 0, suffix = 0;
static void
list_errors (void)
......@@ -97,6 +98,15 @@ usage (char * progname)
list_errors ();
printf ("\nError suppression options\n");
printf (" -p, --prefix Treat input as the prefix of a stream; suppress\n");
printf (" warnings about missing end-of-stream markers\n");
printf (" -s, --suffix Treat input as the suffix of a stream; suppress\n");
printf (" warnings about missing beginning-of-stream markers\n");
printf (" on the first chain\n");
printf (" -P, --partial Treat input as a the middle portion of a stream;\n");
printf (" equivalent to both --prefix and --suffix\n");
printf ("\nMiscellaneous options\n");
printf (" -h, --help Display this help and exit\n");
printf (" -E, --help-errors List known types of error and exit\n");
......@@ -182,9 +192,15 @@ read_page (OGGZ * oggz, const ogg_page * og, long serialno, void * user_data)
static void
ovdata_init (OVData * ovdata)
{
int flags;
current_timestamp = 0;
if ((ovdata->writer = oggz_new (OGGZ_WRITE|OGGZ_AUTO)) == NULL) {
flags = OGGZ_WRITE|OGGZ_AUTO;
if (prefix) flags |= OGGZ_PREFIX;
if (suffix) flags |= OGGZ_SUFFIX;
if ((ovdata->writer = oggz_new (flags)) == NULL) {
fprintf (stderr, "oggz-validate: unable to create new writer\n");
exit (1);
}
......@@ -202,7 +218,7 @@ ovdata_clear (OVData * ovdata)
oggz_close (ovdata->writer);
if (nr_errors <= MAX_ERRORS) {
if (!prefix && nr_errors <= MAX_ERRORS) {
nr_missing_eos = oggz_table_size (ovdata->missing_eos);
for (i = 0; i < nr_missing_eos; i++) {
log_error ();
......@@ -226,12 +242,12 @@ read_packet (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
oggz_table_insert (ovdata->missing_eos, serialno, (void *)0x1);
}
if (oggz_table_lookup (ovdata->missing_eos, serialno) == NULL) {
if (!suffix && oggz_table_lookup (ovdata->missing_eos, serialno) == NULL) {
ret = log_error ();
fprintf (stderr, "serialno %010ld: missing *** bos\n", serialno);
}
if (op->e_o_s) {
if (!suffix && op->e_o_s) {
if (oggz_table_remove (ovdata->missing_eos, serialno) == -1) {
ret = log_error ();
fprintf (stderr, "serialno %010ld: *** eos marked but no bos\n",
......@@ -283,6 +299,7 @@ read_packet (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
if (op->e_o_s && oggz_table_size (ovdata->missing_eos) == 0) {
ovdata_clear (ovdata);
ovdata_init (ovdata);
suffix = 0;
}
return ret;
......@@ -346,6 +363,11 @@ main (int argc, char ** argv)
int show_version = 0;
int show_help = 0;
/* Cache the --prefix, --suffix options and reset before validating
* each input file */
int opt_prefix = 0;
int opt_suffix = 0;
char * progname;
char * filename;
int i = 1;
......@@ -360,10 +382,13 @@ main (int argc, char ** argv)
}
while (1) {
char * optstring = "hvE";
char * optstring = "psPhvE";
#ifdef HAVE_GETOPT_LONG
static struct option long_options[] = {
{"prefix", no_argument, 0, 'p'},
{"suffix", no_argument, 0, 's'},
{"partial", no_argument, 0, 'P'},
{"help", no_argument, 0, 'h'},
{"help-errors", no_argument, 0, 'E'},
{"version", no_argument, 0, 'v'},
......@@ -375,7 +400,6 @@ main (int argc, char ** argv)
i = getopt (argc, argv, optstring);
#endif
if (i == -1) {
i = 1;
break;
}
if (i == ':') {
......@@ -384,6 +408,16 @@ main (int argc, char ** argv)
}
switch (i) {
case 'p': /* prefix */
opt_prefix = 1;
break;
case 's': /* suffix */
opt_suffix = 1;
break;
case 'P': /* partial */
opt_prefix = 1;
opt_suffix = 1;
break;
case 'h': /* help */
show_help = 1;
break;
......@@ -419,8 +453,10 @@ main (int argc, char ** argv)
if (argc-i > 2) multifile = 1;
for (; i < argc; i++) {
for (i = optind; i < argc; i++) {
filename = argv[i];
prefix = opt_prefix;
suffix = opt_suffix;
if (validate (filename) == -1)
exit_status = 1;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment