Mercurial > audlegacy-plugins
comparison src/flac/libflac/ogg_helper.c @ 722:454ad11020ec trunk
[svn] * Delete flac112
* Rename flac113 -> flac
* Change configure.ac
author | js |
---|---|
date | Sat, 24 Feb 2007 16:17:26 -0800 |
parents | src/flac113/libflac/ogg_helper.c@a9b178bc4ae4 |
children |
comparison
equal
deleted
inserted
replaced
721:574de61036a3 | 722:454ad11020ec |
---|---|
1 /* libFLAC - Free Lossless Audio Codec | |
2 * Copyright (C) 2004,2005,2006,2007 Josh Coalson | |
3 * | |
4 * Redistribution and use in source and binary forms, with or without | |
5 * modification, are permitted provided that the following conditions | |
6 * are met: | |
7 * | |
8 * - Redistributions of source code must retain the above copyright | |
9 * notice, this list of conditions and the following disclaimer. | |
10 * | |
11 * - Redistributions in binary form must reproduce the above copyright | |
12 * notice, this list of conditions and the following disclaimer in the | |
13 * documentation and/or other materials provided with the distribution. | |
14 * | |
15 * - Neither the name of the Xiph.org Foundation nor the names of its | |
16 * contributors may be used to endorse or promote products derived from | |
17 * this software without specific prior written permission. | |
18 * | |
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |
27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
30 */ | |
31 | |
32 #if HAVE_CONFIG_H | |
33 # include <config.h> | |
34 #endif | |
35 | |
36 #include <stdlib.h> /* for malloc() */ | |
37 #include <string.h> /* for memcmp(), memcpy() */ | |
38 #include "FLAC/assert.h" | |
39 #include "private/ogg_helper.h" | |
40 #include "protected/stream_encoder.h" | |
41 | |
42 | |
43 static FLAC__bool full_read_(FLAC__StreamEncoder *encoder, FLAC__byte *buffer, size_t bytes, FLAC__StreamEncoderReadCallback read_callback, void *client_data) | |
44 { | |
45 while(bytes > 0) { | |
46 size_t bytes_read = bytes; | |
47 switch(read_callback(encoder, buffer, &bytes_read, client_data)) { | |
48 case FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE: | |
49 bytes -= bytes_read; | |
50 buffer += bytes_read; | |
51 break; | |
52 case FLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM: | |
53 if(bytes_read == 0) { | |
54 encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR; | |
55 return false; | |
56 } | |
57 bytes -= bytes_read; | |
58 buffer += bytes_read; | |
59 break; | |
60 case FLAC__STREAM_ENCODER_READ_STATUS_ABORT: | |
61 encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; | |
62 return false; | |
63 case FLAC__STREAM_ENCODER_READ_STATUS_UNSUPPORTED: | |
64 return false; | |
65 default: | |
66 /* double protection: */ | |
67 FLAC__ASSERT(0); | |
68 encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; | |
69 return false; | |
70 } | |
71 } | |
72 | |
73 return true; | |
74 } | |
75 | |
76 void simple_ogg_page__init(ogg_page *page) | |
77 { | |
78 page->header = 0; | |
79 page->header_len = 0; | |
80 page->body = 0; | |
81 page->body_len = 0; | |
82 } | |
83 | |
84 void simple_ogg_page__clear(ogg_page *page) | |
85 { | |
86 if(page->header) | |
87 free(page->header); | |
88 if(page->body) | |
89 free(page->body); | |
90 simple_ogg_page__init(page); | |
91 } | |
92 | |
93 FLAC__bool simple_ogg_page__get_at(FLAC__StreamEncoder *encoder, FLAC__uint64 position, ogg_page *page, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderReadCallback read_callback, void *client_data) | |
94 { | |
95 static const unsigned OGG_HEADER_FIXED_PORTION_LEN = 27; | |
96 static const unsigned OGG_MAX_HEADER_LEN = 27/*OGG_HEADER_FIXED_PORTION_LEN*/ + 255; | |
97 FLAC__byte crc[4]; | |
98 FLAC__StreamEncoderSeekStatus seek_status; | |
99 | |
100 FLAC__ASSERT(page->header == 0); | |
101 FLAC__ASSERT(page->header_len == 0); | |
102 FLAC__ASSERT(page->body == 0); | |
103 FLAC__ASSERT(page->body_len == 0); | |
104 | |
105 /* move the stream pointer to the supposed beginning of the page */ | |
106 if(0 == seek_callback) | |
107 return false; | |
108 if((seek_status = seek_callback((FLAC__StreamEncoder*)encoder, position, client_data)) != FLAC__STREAM_ENCODER_SEEK_STATUS_OK) { | |
109 if(seek_status == FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR) | |
110 encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; | |
111 return false; | |
112 } | |
113 | |
114 /* allocate space for the page header */ | |
115 if(0 == (page->header = (unsigned char *)malloc(OGG_MAX_HEADER_LEN))) { | |
116 encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; | |
117 return false; | |
118 } | |
119 | |
120 /* read in the fixed part of the page header (up to but not including | |
121 * the segment table */ | |
122 if(!full_read_(encoder, page->header, OGG_HEADER_FIXED_PORTION_LEN, read_callback, client_data)) | |
123 return false; | |
124 | |
125 page->header_len = OGG_HEADER_FIXED_PORTION_LEN + page->header[26]; | |
126 | |
127 /* check to see if it's a correct, "simple" page (one packet only) */ | |
128 if( | |
129 memcmp(page->header, "OggS", 4) || /* doesn't start with OggS */ | |
130 (page->header[5] & 0x01) || /* continued packet */ | |
131 memcmp(page->header+6, "\0\0\0\0\0\0\0\0", 8) || /* granulepos is non-zero */ | |
132 page->header[26] == 0 /* packet is 0-size */ | |
133 ) { | |
134 encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR; | |
135 return false; | |
136 } | |
137 | |
138 /* read in the segment table */ | |
139 if(!full_read_(encoder, page->header + OGG_HEADER_FIXED_PORTION_LEN, page->header[26], read_callback, client_data)) | |
140 return false; | |
141 | |
142 { | |
143 unsigned i; | |
144 | |
145 /* check to see that it specifies a single packet */ | |
146 for(i = 0; i < (unsigned)page->header[26] - 1; i++) { | |
147 if(page->header[i + OGG_HEADER_FIXED_PORTION_LEN] != 255) { | |
148 encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR; | |
149 return false; | |
150 } | |
151 } | |
152 | |
153 page->body_len = 255 * i + page->header[i + OGG_HEADER_FIXED_PORTION_LEN]; | |
154 } | |
155 | |
156 /* allocate space for the page body */ | |
157 if(0 == (page->body = (unsigned char *)malloc(page->body_len))) { | |
158 encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; | |
159 return false; | |
160 } | |
161 | |
162 /* read in the page body */ | |
163 if(!full_read_(encoder, page->body, page->body_len, read_callback, client_data)) | |
164 return false; | |
165 | |
166 /* check the CRC */ | |
167 memcpy(crc, page->header+22, 4); | |
168 ogg_page_checksum_set(page); | |
169 if(memcmp(crc, page->header+22, 4)) { | |
170 encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR; | |
171 return false; | |
172 } | |
173 | |
174 return true; | |
175 } | |
176 | |
177 FLAC__bool simple_ogg_page__set_at(FLAC__StreamEncoder *encoder, FLAC__uint64 position, ogg_page *page, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderWriteCallback write_callback, void *client_data) | |
178 { | |
179 FLAC__StreamEncoderSeekStatus seek_status; | |
180 | |
181 FLAC__ASSERT(page->header != 0); | |
182 FLAC__ASSERT(page->header_len != 0); | |
183 FLAC__ASSERT(page->body != 0); | |
184 FLAC__ASSERT(page->body_len != 0); | |
185 | |
186 /* move the stream pointer to the supposed beginning of the page */ | |
187 if(0 == seek_callback) | |
188 return false; | |
189 if((seek_status = seek_callback((FLAC__StreamEncoder*)encoder, position, client_data)) != FLAC__STREAM_ENCODER_SEEK_STATUS_OK) { | |
190 if(seek_status == FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR) | |
191 encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; | |
192 return false; | |
193 } | |
194 | |
195 ogg_page_checksum_set(page); | |
196 | |
197 /* re-write the page */ | |
198 if(write_callback((FLAC__StreamEncoder*)encoder, page->header, page->header_len, 0, 0, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) { | |
199 encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; | |
200 return false; | |
201 } | |
202 if(write_callback((FLAC__StreamEncoder*)encoder, page->body, page->body_len, 0, 0, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) { | |
203 encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; | |
204 return false; | |
205 } | |
206 | |
207 return true; | |
208 } |