|
Packit |
a38265 |
/*
|
|
Packit |
a38265 |
Copyright (C) 2003 Commonwealth Scientific and Industrial Research
|
|
Packit |
a38265 |
Organisation (CSIRO) Australia
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
Redistribution and use in source and binary forms, with or without
|
|
Packit |
a38265 |
modification, are permitted provided that the following conditions
|
|
Packit |
a38265 |
are met:
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
- Redistributions of source code must retain the above copyright
|
|
Packit |
a38265 |
notice, this list of conditions and the following disclaimer.
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
- Redistributions in binary form must reproduce the above copyright
|
|
Packit |
a38265 |
notice, this list of conditions and the following disclaimer in the
|
|
Packit |
a38265 |
documentation and/or other materials provided with the distribution.
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
- Neither the name of CSIRO Australia nor the names of its
|
|
Packit |
a38265 |
contributors may be used to endorse or promote products derived from
|
|
Packit |
a38265 |
this software without specific prior written permission.
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
Packit |
a38265 |
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
Packit |
a38265 |
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
Packit |
a38265 |
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
|
|
Packit |
a38265 |
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
Packit |
a38265 |
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
Packit |
a38265 |
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
Packit |
a38265 |
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
Packit |
a38265 |
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
Packit |
a38265 |
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
Packit |
a38265 |
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
a38265 |
*/
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
#include "config.h"
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
#include <stdio.h>
|
|
Packit |
a38265 |
#include <stdlib.h>
|
|
Packit |
a38265 |
#include <string.h>
|
|
Packit |
a38265 |
#include <fcntl.h>
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
#include <getopt.h>
|
|
Packit |
a38265 |
#include <errno.h>
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
#ifdef HAVE_INTTYPES_H
|
|
Packit |
a38265 |
# include <inttypes.h>
|
|
Packit |
a38265 |
#else
|
|
Packit |
a38265 |
# define PRId64 "I64d"
|
|
Packit |
a38265 |
#endif
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
#include "oggz/oggz.h"
|
|
Packit |
a38265 |
#include "oggz_tools.h"
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
#define READ_SIZE 4096
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
#define ALL_VORBIS_WARNING \
|
|
Packit |
a38265 |
"oggz-merge: WARNING: Merging Ogg Vorbis I files. The resulting file will\n" \
|
|
Packit |
a38265 |
" contain %d tracks in parallel, interleaved for simultaneous playback.\n"\
|
|
Packit |
a38265 |
" If you want to sequence these files one after another, use cat instead.\n"
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
static char * progname;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
static void
|
|
Packit |
a38265 |
usage (char * progname)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
printf ("Usage: %s [options] filename ...\n", progname);
|
|
Packit |
a38265 |
printf ("Merge Ogg files together, interleaving pages in order of presentation time.\n");
|
|
Packit |
a38265 |
printf ("\nMiscellaneous options\n");
|
|
Packit |
a38265 |
printf (" -o filename, --output filename\n");
|
|
Packit |
a38265 |
printf (" Specify output filename\n");
|
|
Packit |
a38265 |
printf (" -h, --help Display this help and exit\n");
|
|
Packit |
a38265 |
printf (" -v, --version Output version information and exit\n");
|
|
Packit |
a38265 |
printf (" -V, --verbose Verbose operation\n");
|
|
Packit |
a38265 |
printf ("\n");
|
|
Packit |
a38265 |
printf ("Please report bugs to <ogg-dev@xiph.org>\n");
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
static void
|
|
Packit |
a38265 |
exit_out_of_memory (void)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
fprintf (stderr, "%s: Out of memory\n", progname);
|
|
Packit |
a38265 |
exit (1);
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
static void
|
|
Packit |
a38265 |
checked_fwrite (const void *data, size_t size, size_t count, FILE *stream)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
int n = fwrite (data, size, count, stream);
|
|
Packit |
a38265 |
if ((size_t)n != count) {
|
|
Packit |
a38265 |
perror ("write failed");
|
|
Packit |
a38265 |
exit (1);
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
typedef struct _OMData OMData;
|
|
Packit |
a38265 |
typedef struct _OMInput OMInput;
|
|
Packit |
a38265 |
typedef struct _OMITrack OMITrack;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
struct _OMData {
|
|
Packit |
a38265 |
OggzTable * inputs;
|
|
Packit |
a38265 |
int verbose;
|
|
Packit |
a38265 |
};
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
struct _OMInput {
|
|
Packit |
a38265 |
OMData * omdata;
|
|
Packit |
a38265 |
OGGZ * reader;
|
|
Packit |
a38265 |
const ogg_page * og;
|
|
Packit |
a38265 |
};
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
struct _OMITrack {
|
|
Packit |
a38265 |
long output_serialno;
|
|
Packit |
a38265 |
};
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
static ogg_page *
|
|
Packit |
a38265 |
_ogg_page_copy (const ogg_page * og)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
ogg_page * new_og;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
new_og = malloc (sizeof (*og));
|
|
Packit |
a38265 |
if (new_og == NULL) return NULL;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
new_og->header = malloc (og->header_len);
|
|
Packit |
a38265 |
if (new_og->header == NULL) {
|
|
Packit |
a38265 |
free (new_og);
|
|
Packit |
a38265 |
return NULL;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
new_og->header_len = og->header_len;
|
|
Packit |
a38265 |
memcpy (new_og->header, og->header, og->header_len);
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
new_og->body = malloc (og->body_len);
|
|
Packit |
a38265 |
if (new_og->body == NULL) {
|
|
Packit |
a38265 |
free (new_og->header);
|
|
Packit |
a38265 |
free (new_og);
|
|
Packit |
a38265 |
return NULL;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
new_og->body_len = og->body_len;
|
|
Packit |
a38265 |
memcpy (new_og->body, og->body, og->body_len);
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return new_og;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
static int
|
|
Packit |
a38265 |
_ogg_page_free (const ogg_page * og)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
free (og->header);
|
|
Packit |
a38265 |
free (og->body);
|
|
Packit |
a38265 |
free ((ogg_page *)og);
|
|
Packit |
a38265 |
return 0;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
static void
|
|
Packit |
a38265 |
ominput_delete (OMInput * input)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
oggz_close (input->reader);
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
free (input);
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
static OMData *
|
|
Packit |
a38265 |
omdata_new (void)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
OMData * omdata;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
omdata = (OMData *) malloc (sizeof (OMData));
|
|
Packit |
a38265 |
if (omdata == NULL) return NULL;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
omdata->inputs = oggz_table_new ();
|
|
Packit |
a38265 |
omdata->verbose = 0;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return omdata;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
static void
|
|
Packit |
a38265 |
omdata_delete (OMData * omdata)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
OMInput * input;
|
|
Packit |
a38265 |
int i, ninputs;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
ninputs = oggz_table_size (omdata->inputs);
|
|
Packit |
a38265 |
for (i = 0; i < ninputs; i++) {
|
|
Packit |
a38265 |
input = (OMInput *) oggz_table_nth (omdata->inputs, i, NULL);
|
|
Packit |
a38265 |
ominput_delete (input);
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
oggz_table_delete (omdata->inputs);
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
free (omdata);
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
static int
|
|
Packit |
a38265 |
read_page (OGGZ * oggz, const ogg_page * og, long serialno, void * user_data)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
OMInput * input = (OMInput *) user_data;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
input->og = _ogg_page_copy (og);
|
|
Packit |
a38265 |
if (input->og == NULL) return OGGZ_STOP_ERR;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return OGGZ_STOP_OK;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
static int
|
|
Packit |
a38265 |
omdata_add_input (OMData * omdata, FILE * infile)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
OMInput * input;
|
|
Packit |
a38265 |
int nfiles;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
input = (OMInput *) malloc (sizeof (OMInput));
|
|
Packit |
a38265 |
if (input == NULL) return -1;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
input->omdata = omdata;
|
|
Packit |
a38265 |
input->reader = oggz_open_stdio (infile, OGGZ_READ|OGGZ_AUTO);
|
|
Packit |
a38265 |
input->og = NULL;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
oggz_set_read_page (input->reader, -1, read_page, input);
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
nfiles = oggz_table_size (omdata->inputs);
|
|
Packit |
a38265 |
if (!oggz_table_insert (omdata->inputs, nfiles++, input)) {
|
|
Packit |
a38265 |
ominput_delete (input);
|
|
Packit |
a38265 |
return -1;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return 0;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
static int
|
|
Packit |
a38265 |
oggz_merge (OMData * omdata, FILE * outfile)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
OMInput * input;
|
|
Packit |
a38265 |
int ninputs, i, min_i;
|
|
Packit |
a38265 |
long key, n;
|
|
Packit |
a38265 |
ogg_int64_t units, min_units;
|
|
Packit |
a38265 |
const ogg_page * og;
|
|
Packit |
a38265 |
int active;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
/* For theora+vorbis, or dirac+vorbis, ensure video bos is first */
|
|
Packit |
a38265 |
int careful_for_video = 0;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
/* If all input files are Ogg Vorbis I, warn that the output will not be
|
|
Packit |
a38265 |
* a valid Ogg Vorbis I file as it will be multitrack. This is in response
|
|
Packit |
a38265 |
* to Debian bug 280550: http://bugs.debian.org/280550
|
|
Packit |
a38265 |
*/
|
|
Packit |
a38265 |
int v, warn_all_vorbis = 1;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (oggz_table_size (omdata->inputs) == 2)
|
|
Packit |
a38265 |
careful_for_video = 1;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
while ((ninputs = oggz_table_size (omdata->inputs)) > 0) {
|
|
Packit |
a38265 |
min_units = -1;
|
|
Packit |
a38265 |
min_i = -1;
|
|
Packit |
a38265 |
active = 1;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (omdata->verbose)
|
|
Packit |
a38265 |
printf ("------------------------------------------------------------\n");
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
/* Reload all pages, and find the min (earliest) */
|
|
Packit |
a38265 |
for (i = 0; active && i < oggz_table_size (omdata->inputs); i++) {
|
|
Packit |
a38265 |
input = (OMInput *) oggz_table_nth (omdata->inputs, i, &key);
|
|
Packit |
a38265 |
if (input != NULL) {
|
|
Packit |
a38265 |
while (input && input->og == NULL) {
|
|
Packit |
a38265 |
n = oggz_read (input->reader, READ_SIZE);
|
|
Packit |
a38265 |
if (n == 0) {
|
|
Packit |
a38265 |
oggz_table_remove (omdata->inputs, key);
|
|
Packit |
a38265 |
ominput_delete (input);
|
|
Packit |
a38265 |
input = NULL;
|
|
Packit |
a38265 |
} else if (n == OGGZ_ERR_STOP_ERR) {
|
|
Packit |
a38265 |
exit_out_of_memory();
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
if (input && input->og) {
|
|
Packit |
a38265 |
if (ogg_page_bos ((ogg_page *)input->og)) {
|
|
Packit |
a38265 |
min_i = i;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (careful_for_video || warn_all_vorbis) {
|
|
Packit |
a38265 |
int is_vorbis;
|
|
Packit |
a38265 |
long serialno = ogg_page_serialno ((ogg_page *)input->og);
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
is_vorbis = (oggz_stream_get_content (input->reader, serialno) == OGGZ_CONTENT_VORBIS);
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (i == 0 && is_vorbis)
|
|
Packit |
a38265 |
careful_for_video = 0;
|
|
Packit |
a38265 |
else
|
|
Packit |
a38265 |
active = 0;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (!is_vorbis) warn_all_vorbis = 0;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
} else {
|
|
Packit |
a38265 |
active = 0;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
} else if (warn_all_vorbis) {
|
|
Packit |
a38265 |
int all_inputs_are_beyond_bos = 1;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
/* All BOS pages seen so far are Ogg Vorbis. The following loop
|
|
Packit |
a38265 |
* checks if all input files are single-track, ie. Ogg Vorbis I.
|
|
Packit |
a38265 |
* We can only rely on this information if all inputs are beyond
|
|
Packit |
a38265 |
* bos, ie. all BOS pages have been seen. */
|
|
Packit |
a38265 |
for (v = 0; v < oggz_table_size (omdata->inputs); v++) {
|
|
Packit |
a38265 |
OMInput * input_v;
|
|
Packit |
a38265 |
OGGZ * oggz;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
input_v = (OMInput *) oggz_table_nth (omdata->inputs, i, &key);
|
|
Packit |
a38265 |
oggz = input_v->reader;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (oggz_get_bos(oggz, -1)) all_inputs_are_beyond_bos = 0;
|
|
Packit |
a38265 |
else if (oggz_get_numtracks(oggz) > 1) warn_all_vorbis = 0;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (all_inputs_are_beyond_bos && warn_all_vorbis) {
|
|
Packit |
a38265 |
fprintf (stderr, ALL_VORBIS_WARNING, v);
|
|
Packit |
a38265 |
warn_all_vorbis = 0;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
units = oggz_tell_units (input->reader);
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (omdata->verbose) {
|
|
Packit |
a38265 |
ot_fprint_time (stdout, (double)units/1000);
|
|
Packit |
a38265 |
printf (": Got index %d serialno %010u %" PRId64 " units: ",
|
|
Packit |
a38265 |
i, ogg_page_serialno ((ogg_page *)input->og), units);
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (min_units == -1 || units == 0 ||
|
|
Packit |
a38265 |
(units > -1 && units < min_units)) {
|
|
Packit |
a38265 |
min_units = units;
|
|
Packit |
a38265 |
min_i = i;
|
|
Packit |
a38265 |
if (omdata->verbose)
|
|
Packit |
a38265 |
printf ("Min\n");
|
|
Packit |
a38265 |
} else {
|
|
Packit |
a38265 |
if (omdata->verbose)
|
|
Packit |
a38265 |
printf ("Moo\n");
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
} else if (omdata->verbose) {
|
|
Packit |
a38265 |
if (input == NULL) {
|
|
Packit |
a38265 |
printf ("*** index %d NULL\n", i);
|
|
Packit |
a38265 |
} else {
|
|
Packit |
a38265 |
printf ("*** No page from index %d\n", i);
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (omdata->verbose)
|
|
Packit |
a38265 |
printf ("Min index %d\n", min_i);
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
/* Write the earliest page */
|
|
Packit |
a38265 |
if (min_i != -1) {
|
|
Packit |
a38265 |
input = (OMInput *) oggz_table_nth (omdata->inputs, min_i, &key);
|
|
Packit |
a38265 |
og = input->og;
|
|
Packit |
a38265 |
checked_fwrite (og->header, 1, og->header_len, outfile);
|
|
Packit |
a38265 |
checked_fwrite (og->body, 1, og->body_len, outfile);
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
_ogg_page_free (og);
|
|
Packit |
a38265 |
input->og = NULL;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return 0;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
int
|
|
Packit |
a38265 |
main (int argc, char * argv[])
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
int show_version = 0;
|
|
Packit |
a38265 |
int show_help = 0;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
char * infilename = NULL, * outfilename = NULL;
|
|
Packit |
a38265 |
FILE * infile = NULL, * outfile = NULL;
|
|
Packit |
a38265 |
int used_stdin = 0; /* Flag usage of stdin, only use it once */
|
|
Packit |
a38265 |
OMData * omdata;
|
|
Packit |
a38265 |
int i;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
char * optstring = "hvVo:";
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
#ifdef HAVE_GETOPT_LONG
|
|
Packit |
a38265 |
static struct option long_options[] = {
|
|
Packit |
a38265 |
{"help", no_argument, 0, 'h'},
|
|
Packit |
a38265 |
{"version", no_argument, 0, 'v'},
|
|
Packit |
a38265 |
{"verbose", no_argument, 0, 'V'},
|
|
Packit |
a38265 |
{"output", required_argument, 0, 'o'},
|
|
Packit |
a38265 |
{0,0,0,0}
|
|
Packit |
a38265 |
};
|
|
Packit |
a38265 |
#endif
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
ot_init ();
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
progname = argv[0];
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (argc < 2) {
|
|
Packit |
a38265 |
usage (progname);
|
|
Packit |
a38265 |
return (1);
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (!strncmp (argv[1], "-?", 2)) {
|
|
Packit |
a38265 |
#ifdef HAVE_GETOPT_LONG
|
|
Packit |
a38265 |
ot_print_options (long_options, optstring);
|
|
Packit |
a38265 |
#else
|
|
Packit |
a38265 |
ot_print_short_options (optstring);
|
|
Packit |
a38265 |
#endif
|
|
Packit |
a38265 |
exit (0);
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
omdata = omdata_new();
|
|
Packit |
a38265 |
if (omdata == NULL)
|
|
Packit |
a38265 |
exit_out_of_memory();
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
while (1) {
|
|
Packit |
a38265 |
#ifdef HAVE_GETOPT_LONG
|
|
Packit |
a38265 |
i = getopt_long (argc, argv, optstring, long_options, NULL);
|
|
Packit |
a38265 |
#else
|
|
Packit |
a38265 |
i = getopt (argc, argv, optstring);
|
|
Packit |
a38265 |
#endif
|
|
Packit |
a38265 |
if (i == -1) break;
|
|
Packit |
a38265 |
if (i == ':') {
|
|
Packit |
a38265 |
usage (progname);
|
|
Packit |
a38265 |
goto exit_err;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
switch (i) {
|
|
Packit |
a38265 |
case 'h': /* help */
|
|
Packit |
a38265 |
show_help = 1;
|
|
Packit |
a38265 |
break;
|
|
Packit |
a38265 |
case 'v': /* version */
|
|
Packit |
a38265 |
show_version = 1;
|
|
Packit |
a38265 |
break;
|
|
Packit |
a38265 |
case 'o': /* output */
|
|
Packit |
a38265 |
outfilename = optarg;
|
|
Packit |
a38265 |
break;
|
|
Packit |
a38265 |
case 'V': /* verbose */
|
|
Packit |
a38265 |
omdata->verbose = 1;
|
|
Packit |
a38265 |
default:
|
|
Packit |
a38265 |
break;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (show_version) {
|
|
Packit |
a38265 |
printf ("%s version " VERSION "\n", progname);
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (show_help) {
|
|
Packit |
a38265 |
usage (progname);
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (show_version || show_help) {
|
|
Packit |
a38265 |
goto exit_ok;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (optind >= argc) {
|
|
Packit |
a38265 |
usage (progname);
|
|
Packit |
a38265 |
goto exit_err;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (optind >= argc) {
|
|
Packit |
a38265 |
usage (progname);
|
|
Packit |
a38265 |
goto exit_err;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
while (optind < argc) {
|
|
Packit |
a38265 |
infilename = argv[optind++];
|
|
Packit |
a38265 |
if (strcmp (infilename, "-") == 0) {
|
|
Packit |
a38265 |
if (used_stdin) continue;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
infile = stdin;
|
|
Packit |
a38265 |
used_stdin = 1;
|
|
Packit |
a38265 |
} else {
|
|
Packit |
a38265 |
infile = fopen (infilename, "rb");
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (infile == NULL) {
|
|
Packit |
a38265 |
fprintf (stderr, "%s: unable to open input file %s\n", progname,
|
|
Packit |
a38265 |
infilename);
|
|
Packit |
a38265 |
} else {
|
|
Packit |
a38265 |
if (omdata_add_input (omdata, infile) < 0)
|
|
Packit |
a38265 |
exit_out_of_memory();
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (outfilename == NULL) {
|
|
Packit |
a38265 |
outfile = stdout;
|
|
Packit |
a38265 |
} else {
|
|
Packit |
a38265 |
outfile = fopen (outfilename, "wb");
|
|
Packit |
a38265 |
if (outfile == NULL) {
|
|
Packit |
a38265 |
fprintf (stderr, "%s: unable to open output file %s\n",
|
|
Packit |
a38265 |
progname, outfilename);
|
|
Packit |
a38265 |
goto exit_err;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
oggz_merge (omdata, outfile);
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
exit_ok:
|
|
Packit |
a38265 |
omdata_delete (omdata);
|
|
Packit |
a38265 |
exit (0);
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
exit_err:
|
|
Packit |
a38265 |
omdata_delete (omdata);
|
|
Packit |
a38265 |
exit (1);
|
|
Packit |
a38265 |
}
|