1
1
/* This program is licensed under the GNU Library General Public License, version 2,
2
2
* a copy of which is included with this program (LICENCE.LGPL).
4
* (c) 2000-2001 Michael Smith <msmith@labyrinth.net.au>
4
* (c) 2000-2001 Michael Smith <msmith@xiph.org>
7
7
* Comment editing backend, suitable for use by nice frontend interfaces.
9
* last modified: $Id: vcedit.c,v 1.16 2001/12/19 02:53:00 volsung Exp $
9
* last modified: $Id: vcedit.c,v 1.23 2003/09/03 07:58:05 calc Exp $
13
13
#include <stdlib.h>
14
14
#include <string.h>
15
16
#include <ogg/ogg.h>
16
17
#include <vorbis/codec.h>
18
19
#include "vcedit.h"
20
23
#define CHUNKSIZE 4096
40
43
static void vcedit_clear_internals(vcedit_state *state)
44
48
vorbis_comment_clear(state->vc);
50
53
ogg_stream_clear(state->os);
56
58
ogg_sync_clear(state->oy);
62
62
free(state->vendor);
68
vorbis_info_clear(state->vi);
72
tmp = state->lasterror;
73
memset(state, 0, sizeof(*state));
74
state->lasterror = tmp;
67
77
void vcedit_clear(vcedit_state *state)
123
133
op->granulepos=0;
135
oggpack_writeclear(&opb);
128
139
static int _blocksize(vcedit_state *s, ogg_packet *p)
130
int this = vorbis_packet_blocksize(&s->vi, p);
141
int this = vorbis_packet_blocksize(s->vi, p);
131
142
int ret = (this + s->prevW)/4;
201
213
state->oy = malloc(sizeof(ogg_sync_state));
202
214
ogg_sync_init(state->oy);
204
buffer = ogg_sync_buffer(state->oy, CHUNKSIZE);
205
bytes = state->read(buffer, 1, CHUNKSIZE, state->in);
207
ogg_sync_wrote(state->oy, bytes);
209
if(ogg_sync_pageout(state->oy, &og) != 1)
212
state->lasterror = "Input truncated or empty.";
214
state->lasterror = "Input is not an Ogg bitstream.";
218
buffer = ogg_sync_buffer(state->oy, CHUNKSIZE);
219
bytes = state->read(buffer, 1, CHUNKSIZE, state->in);
221
ogg_sync_wrote(state->oy, bytes);
223
if(ogg_sync_pageout(state->oy, &og) == 1)
226
if(chunks++ >= 10) /* Bail if we don't find data in the first 40 kB */
229
state->lasterror = _("Input truncated or empty.");
231
state->lasterror = _("Input is not an Ogg bitstream.");
218
236
state->serial = ogg_page_serialno(&og);
220
238
state->os = malloc(sizeof(ogg_stream_state));
221
239
ogg_stream_init(state->os, state->serial);
223
vorbis_info_init(&state->vi);
241
state->vi = malloc(sizeof(vorbis_info));
242
vorbis_info_init(state->vi);
225
244
state->vc = malloc(sizeof(vorbis_comment));
226
245
vorbis_comment_init(state->vc);
228
247
if(ogg_stream_pagein(state->os, &og) < 0)
230
state->lasterror = "Error reading first page of Ogg bitstream.";
249
state->lasterror = _("Error reading first page of Ogg bitstream.");
234
253
if(ogg_stream_packetout(state->os, &header_main) != 1)
236
state->lasterror = "Error reading initial header packet.";
255
state->lasterror = _("Error reading initial header packet.");
240
if(vorbis_synthesis_headerin(&state->vi, state->vc, &header_main) < 0)
259
if(vorbis_synthesis_headerin(state->vi, state->vc, &header_main) < 0)
242
state->lasterror = "Ogg bitstream does not contain vorbis data.";
261
state->lasterror = _("Ogg bitstream does not contain vorbis data.");
262
281
if(result == 0) break;
265
state->lasterror = "Corrupt secondary header.";
284
state->lasterror = _("Corrupt secondary header.");
268
vorbis_synthesis_headerin(&state->vi, state->vc, header);
287
vorbis_synthesis_headerin(state->vi, state->vc, header);
271
290
state->booklen = header->bytes;
283
302
bytes = state->read(buffer, 1, CHUNKSIZE, state->in);
284
303
if(bytes == 0 && i < 2)
286
state->lasterror = "EOF before end of vorbis headers.";
305
state->lasterror = _("EOF before end of vorbis headers.");
289
308
ogg_sync_wrote(state->oy, bytes);
418
/* FIXME: freeing this here probably leaks memory */
419
/* Done with this, now */
420
vorbis_info_clear(&state->vi);
422
437
if (state->extrapage)
424
439
if(state->write(ogin.header,1,ogin.header_len,
439
454
result = ogg_sync_pageout(state->oy, &ogout);
442
state->lasterror = "Corrupt or missing data, continuing...";
458
state->lasterror = _("Corrupt or missing data, continuing...");
445
461
/* Don't bother going through the rest, we can just
446
462
* write the page out now */
447
463
if(state->write(ogout.header,1,ogout.header_len,
448
out) != (size_t) ogout.header_len)
464
out) != (size_t) ogout.header_len) {
450
467
if(state->write(ogout.body,1,ogout.body_len, out) !=
451
(size_t) ogout.body_len)
468
(size_t) ogout.body_len) {
455
473
buffer = ogg_sync_buffer(state->oy, CHUNKSIZE);
470
488
free(state->mainbuf);
471
489
free(state->bookbuf);
490
state->mainbuf = state->bookbuf = NULL;
473
vcedit_clear_internals(state);
474
492
if(!state->eosin)
477
"Error writing stream to output. "
478
"Output stream may be corrupted or truncated.";
495
_("Error writing stream to output. "
496
"Output stream may be corrupted or truncated.");