file_decoder.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:26k
源码类别:

Windows CE

开发平台:

C/C++

  1. /* libOggFLAC - Free Lossless Audio Codec + Ogg library
  2.  * Copyright (C) 2002,2003,2004,2005  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. #include <stdio.h>
  32. #include <stdlib.h> /* for malloc() */
  33. #include <string.h> /* for strcmp() */
  34. #include <sys/stat.h> /* for stat() */
  35. #if defined _MSC_VER || defined __MINGW32__
  36. #include <io.h> /* for _setmode() */
  37. #include <fcntl.h> /* for _O_BINARY */
  38. #elif defined __CYGWIN__
  39. #include <io.h> /* for setmode(), O_BINARY */
  40. #include <fcntl.h> /* for _O_BINARY */
  41. #endif
  42. #include "FLAC/assert.h"
  43. #include "protected/file_decoder.h"
  44. #include "protected/seekable_stream_decoder.h"
  45. /***********************************************************************
  46.  *
  47.  * Private class method prototypes
  48.  *
  49.  ***********************************************************************/
  50. static void set_defaults_(OggFLAC__FileDecoder *decoder);
  51. static FILE *get_binary_stdin_();
  52. static OggFLAC__SeekableStreamDecoderReadStatus read_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
  53. static OggFLAC__SeekableStreamDecoderSeekStatus seek_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
  54. static OggFLAC__SeekableStreamDecoderTellStatus tell_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
  55. static OggFLAC__SeekableStreamDecoderLengthStatus length_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
  56. static FLAC__bool eof_callback_(const OggFLAC__SeekableStreamDecoder *decoder, void *client_data);
  57. static FLAC__StreamDecoderWriteStatus write_callback_(const OggFLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
  58. static void metadata_callback_(const OggFLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
  59. static void error_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
  60. /***********************************************************************
  61.  *
  62.  * Private class data
  63.  *
  64.  ***********************************************************************/
  65. typedef struct OggFLAC__FileDecoderPrivate {
  66. OggFLAC__FileDecoderWriteCallback write_callback;
  67. OggFLAC__FileDecoderMetadataCallback metadata_callback;
  68. OggFLAC__FileDecoderErrorCallback error_callback;
  69. void *client_data;
  70. FILE *file;
  71. char *filename; /* == NULL if stdin */
  72. OggFLAC__SeekableStreamDecoder *seekable_stream_decoder;
  73. } OggFLAC__FileDecoderPrivate;
  74. /***********************************************************************
  75.  *
  76.  * Public static class data
  77.  *
  78.  ***********************************************************************/
  79. OggFLAC_API const char * const OggFLAC__FileDecoderStateString[] = {
  80. "OggFLAC__FILE_DECODER_OK",
  81. "OggFLAC__FILE_DECODER_END_OF_FILE",
  82. "OggFLAC__FILE_DECODER_ERROR_OPENING_FILE",
  83. "OggFLAC__FILE_DECODER_SEEK_ERROR",
  84. "OggFLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR",
  85. "OggFLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR",
  86. "OggFLAC__FILE_DECODER_ALREADY_INITIALIZED",
  87. "OggFLAC__FILE_DECODER_INVALID_CALLBACK",
  88. "OggFLAC__FILE_DECODER_UNINITIALIZED"
  89. };
  90. /***********************************************************************
  91.  *
  92.  * Class constructor/destructor
  93.  *
  94.  ***********************************************************************/
  95. OggFLAC_API OggFLAC__FileDecoder *OggFLAC__file_decoder_new()
  96. {
  97. OggFLAC__FileDecoder *decoder;
  98. FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
  99. decoder = (OggFLAC__FileDecoder*)calloc(1, sizeof(OggFLAC__FileDecoder));
  100. if(decoder == 0) {
  101. return 0;
  102. }
  103. decoder->protected_ = (OggFLAC__FileDecoderProtected*)calloc(1, sizeof(OggFLAC__FileDecoderProtected));
  104. if(decoder->protected_ == 0) {
  105. free(decoder);
  106. return 0;
  107. }
  108. decoder->private_ = (OggFLAC__FileDecoderPrivate*)calloc(1, sizeof(OggFLAC__FileDecoderPrivate));
  109. if(decoder->private_ == 0) {
  110. free(decoder->protected_);
  111. free(decoder);
  112. return 0;
  113. }
  114. decoder->private_->seekable_stream_decoder = OggFLAC__seekable_stream_decoder_new();
  115. if(0 == decoder->private_->seekable_stream_decoder) {
  116. free(decoder->private_);
  117. free(decoder->protected_);
  118. free(decoder);
  119. return 0;
  120. }
  121. decoder->private_->file = 0;
  122. set_defaults_(decoder);
  123. decoder->protected_->state = OggFLAC__FILE_DECODER_UNINITIALIZED;
  124. return decoder;
  125. }
  126. OggFLAC_API void OggFLAC__file_decoder_delete(OggFLAC__FileDecoder *decoder)
  127. {
  128. FLAC__ASSERT(0 != decoder);
  129. FLAC__ASSERT(0 != decoder->protected_);
  130. FLAC__ASSERT(0 != decoder->private_);
  131. FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
  132. (void)OggFLAC__file_decoder_finish(decoder);
  133. OggFLAC__seekable_stream_decoder_delete(decoder->private_->seekable_stream_decoder);
  134. free(decoder->private_);
  135. free(decoder->protected_);
  136. free(decoder);
  137. }
  138. /***********************************************************************
  139.  *
  140.  * Public class methods
  141.  *
  142.  ***********************************************************************/
  143. OggFLAC_API OggFLAC__FileDecoderState OggFLAC__file_decoder_init(OggFLAC__FileDecoder *decoder)
  144. {
  145. FLAC__ASSERT(0 != decoder);
  146. if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
  147. return decoder->protected_->state = OggFLAC__FILE_DECODER_ALREADY_INITIALIZED;
  148. if(0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback)
  149. return decoder->protected_->state = OggFLAC__FILE_DECODER_INVALID_CALLBACK;
  150. if(0 == decoder->private_->filename)
  151. decoder->private_->file = get_binary_stdin_();
  152. else
  153. decoder->private_->file = fopen(decoder->private_->filename, "rb");
  154. if(decoder->private_->file == 0)
  155. return decoder->protected_->state = OggFLAC__FILE_DECODER_ERROR_OPENING_FILE;
  156. OggFLAC__seekable_stream_decoder_set_read_callback(decoder->private_->seekable_stream_decoder, read_callback_);
  157. OggFLAC__seekable_stream_decoder_set_seek_callback(decoder->private_->seekable_stream_decoder, seek_callback_);
  158. OggFLAC__seekable_stream_decoder_set_tell_callback(decoder->private_->seekable_stream_decoder, tell_callback_);
  159. OggFLAC__seekable_stream_decoder_set_length_callback(decoder->private_->seekable_stream_decoder, length_callback_);
  160. OggFLAC__seekable_stream_decoder_set_eof_callback(decoder->private_->seekable_stream_decoder, eof_callback_);
  161. OggFLAC__seekable_stream_decoder_set_write_callback(decoder->private_->seekable_stream_decoder, write_callback_);
  162. OggFLAC__seekable_stream_decoder_set_metadata_callback(decoder->private_->seekable_stream_decoder, metadata_callback_);
  163. OggFLAC__seekable_stream_decoder_set_error_callback(decoder->private_->seekable_stream_decoder, error_callback_);
  164. OggFLAC__seekable_stream_decoder_set_client_data(decoder->private_->seekable_stream_decoder, decoder);
  165. if(OggFLAC__seekable_stream_decoder_init(decoder->private_->seekable_stream_decoder) != OggFLAC__SEEKABLE_STREAM_DECODER_OK)
  166. return decoder->protected_->state = OggFLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
  167. return decoder->protected_->state = OggFLAC__FILE_DECODER_OK;
  168. }
  169. OggFLAC_API FLAC__bool OggFLAC__file_decoder_finish(OggFLAC__FileDecoder *decoder)
  170. {
  171. FLAC__ASSERT(0 != decoder);
  172. if(decoder->protected_->state == OggFLAC__FILE_DECODER_UNINITIALIZED)
  173. return true;
  174. FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
  175. if(0 != decoder->private_->file && decoder->private_->file != stdin) {
  176. fclose(decoder->private_->file);
  177. decoder->private_->file = 0;
  178. }
  179. if(0 != decoder->private_->filename) {
  180. free(decoder->private_->filename);
  181. decoder->private_->filename = 0;
  182. }
  183. set_defaults_(decoder);
  184. decoder->protected_->state = OggFLAC__FILE_DECODER_UNINITIALIZED;
  185. return OggFLAC__seekable_stream_decoder_finish(decoder->private_->seekable_stream_decoder);
  186. }
  187. OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_md5_checking(OggFLAC__FileDecoder *decoder, FLAC__bool value)
  188. {
  189. FLAC__ASSERT(0 != decoder);
  190. FLAC__ASSERT(0 != decoder->private_);
  191. FLAC__ASSERT(0 != decoder->protected_);
  192. FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
  193. if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
  194. return false;
  195. return OggFLAC__seekable_stream_decoder_set_md5_checking(decoder->private_->seekable_stream_decoder, value);
  196. }
  197. OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_filename(OggFLAC__FileDecoder *decoder, const char *value)
  198. {
  199. FLAC__ASSERT(0 != decoder);
  200. FLAC__ASSERT(0 != decoder->private_);
  201. FLAC__ASSERT(0 != decoder->protected_);
  202. FLAC__ASSERT(0 != value);
  203. if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
  204. return false;
  205. if(0 != decoder->private_->filename) {
  206. free(decoder->private_->filename);
  207. decoder->private_->filename = 0;
  208. }
  209. if(0 != strcmp(value, "-")) {
  210. if(0 == (decoder->private_->filename = (char*)malloc(strlen(value)+1))) {
  211. decoder->protected_->state = OggFLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR;
  212. return false;
  213. }
  214. strcpy(decoder->private_->filename, value);
  215. }
  216. return true;
  217. }
  218. OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_write_callback(OggFLAC__FileDecoder *decoder, OggFLAC__FileDecoderWriteCallback value)
  219. {
  220. FLAC__ASSERT(0 != decoder);
  221. FLAC__ASSERT(0 != decoder->private_);
  222. FLAC__ASSERT(0 != decoder->protected_);
  223. if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
  224. return false;
  225. decoder->private_->write_callback = value;
  226. return true;
  227. }
  228. OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_metadata_callback(OggFLAC__FileDecoder *decoder, OggFLAC__FileDecoderMetadataCallback value)
  229. {
  230. FLAC__ASSERT(0 != decoder);
  231. FLAC__ASSERT(0 != decoder->private_);
  232. FLAC__ASSERT(0 != decoder->protected_);
  233. if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
  234. return false;
  235. decoder->private_->metadata_callback = value;
  236. return true;
  237. }
  238. OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_error_callback(OggFLAC__FileDecoder *decoder, OggFLAC__FileDecoderErrorCallback value)
  239. {
  240. FLAC__ASSERT(0 != decoder);
  241. FLAC__ASSERT(0 != decoder->private_);
  242. FLAC__ASSERT(0 != decoder->protected_);
  243. if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
  244. return false;
  245. decoder->private_->error_callback = value;
  246. return true;
  247. }
  248. OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_client_data(OggFLAC__FileDecoder *decoder, void *value)
  249. {
  250. FLAC__ASSERT(0 != decoder);
  251. FLAC__ASSERT(0 != decoder->private_);
  252. FLAC__ASSERT(0 != decoder->protected_);
  253. if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
  254. return false;
  255. decoder->private_->client_data = value;
  256. return true;
  257. }
  258. OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_serial_number(OggFLAC__FileDecoder *decoder, long value)
  259. {
  260. FLAC__ASSERT(0 != decoder);
  261. FLAC__ASSERT(0 != decoder->private_);
  262. FLAC__ASSERT(0 != decoder->protected_);
  263. if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
  264. return false;
  265. OggFLAC__seekable_stream_decoder_set_serial_number(decoder->private_->seekable_stream_decoder, value);
  266. return true;
  267. }
  268. OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_metadata_respond(OggFLAC__FileDecoder *decoder, FLAC__MetadataType type)
  269. {
  270. FLAC__ASSERT(0 != decoder);
  271. FLAC__ASSERT(0 != decoder->private_);
  272. FLAC__ASSERT(0 != decoder->protected_);
  273. FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
  274. if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
  275. return false;
  276. return OggFLAC__seekable_stream_decoder_set_metadata_respond(decoder->private_->seekable_stream_decoder, type);
  277. }
  278. OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_metadata_respond_application(OggFLAC__FileDecoder *decoder, const FLAC__byte id[4])
  279. {
  280. FLAC__ASSERT(0 != decoder);
  281. FLAC__ASSERT(0 != decoder->private_);
  282. FLAC__ASSERT(0 != decoder->protected_);
  283. FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
  284. if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
  285. return false;
  286. return OggFLAC__seekable_stream_decoder_set_metadata_respond_application(decoder->private_->seekable_stream_decoder, id);
  287. }
  288. OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_metadata_respond_all(OggFLAC__FileDecoder *decoder)
  289. {
  290. FLAC__ASSERT(0 != decoder);
  291. FLAC__ASSERT(0 != decoder->private_);
  292. FLAC__ASSERT(0 != decoder->protected_);
  293. FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
  294. if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
  295. return false;
  296. return OggFLAC__seekable_stream_decoder_set_metadata_respond_all(decoder->private_->seekable_stream_decoder);
  297. }
  298. OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_metadata_ignore(OggFLAC__FileDecoder *decoder, FLAC__MetadataType type)
  299. {
  300. FLAC__ASSERT(0 != decoder);
  301. FLAC__ASSERT(0 != decoder->private_);
  302. FLAC__ASSERT(0 != decoder->protected_);
  303. FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
  304. if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
  305. return false;
  306. return OggFLAC__seekable_stream_decoder_set_metadata_ignore(decoder->private_->seekable_stream_decoder, type);
  307. }
  308. OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_metadata_ignore_application(OggFLAC__FileDecoder *decoder, const FLAC__byte id[4])
  309. {
  310. FLAC__ASSERT(0 != decoder);
  311. FLAC__ASSERT(0 != decoder->private_);
  312. FLAC__ASSERT(0 != decoder->protected_);
  313. FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
  314. if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
  315. return false;
  316. return OggFLAC__seekable_stream_decoder_set_metadata_ignore_application(decoder->private_->seekable_stream_decoder, id);
  317. }
  318. OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_metadata_ignore_all(OggFLAC__FileDecoder *decoder)
  319. {
  320. FLAC__ASSERT(0 != decoder);
  321. FLAC__ASSERT(0 != decoder->private_);
  322. FLAC__ASSERT(0 != decoder->protected_);
  323. FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
  324. if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
  325. return false;
  326. return OggFLAC__seekable_stream_decoder_set_metadata_ignore_all(decoder->private_->seekable_stream_decoder);
  327. }
  328. OggFLAC_API OggFLAC__FileDecoderState OggFLAC__file_decoder_get_state(const OggFLAC__FileDecoder *decoder)
  329. {
  330. FLAC__ASSERT(0 != decoder);
  331. FLAC__ASSERT(0 != decoder->protected_);
  332. return decoder->protected_->state;
  333. }
  334. OggFLAC_API OggFLAC__SeekableStreamDecoderState OggFLAC__file_decoder_get_seekable_stream_decoder_state(const OggFLAC__FileDecoder *decoder)
  335. {
  336. FLAC__ASSERT(0 != decoder);
  337. FLAC__ASSERT(0 != decoder->private_);
  338. return OggFLAC__seekable_stream_decoder_get_state(decoder->private_->seekable_stream_decoder);
  339. }
  340. OggFLAC_API OggFLAC__StreamDecoderState OggFLAC__file_decoder_get_stream_decoder_state(const OggFLAC__FileDecoder *decoder)
  341. {
  342. FLAC__ASSERT(0 != decoder);
  343. FLAC__ASSERT(0 != decoder->private_);
  344. return OggFLAC__seekable_stream_decoder_get_stream_decoder_state(decoder->private_->seekable_stream_decoder);
  345. }
  346. OggFLAC_API FLAC__StreamDecoderState OggFLAC__file_decoder_get_FLAC_stream_decoder_state(const OggFLAC__FileDecoder *decoder)
  347. {
  348. FLAC__ASSERT(0 != decoder);
  349. FLAC__ASSERT(0 != decoder->private_);
  350. return OggFLAC__seekable_stream_decoder_get_FLAC_stream_decoder_state(decoder->private_->seekable_stream_decoder);
  351. }
  352. OggFLAC_API const char *OggFLAC__file_decoder_get_resolved_state_string(const OggFLAC__FileDecoder *decoder)
  353. {
  354. if(decoder->protected_->state != OggFLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR)
  355. return OggFLAC__FileDecoderStateString[decoder->protected_->state];
  356. else
  357. return OggFLAC__seekable_stream_decoder_get_resolved_state_string(decoder->private_->seekable_stream_decoder);
  358. }
  359. OggFLAC_API FLAC__bool OggFLAC__file_decoder_get_md5_checking(const OggFLAC__FileDecoder *decoder)
  360. {
  361. FLAC__ASSERT(0 != decoder);
  362. FLAC__ASSERT(0 != decoder->private_);
  363. return OggFLAC__seekable_stream_decoder_get_md5_checking(decoder->private_->seekable_stream_decoder);
  364. }
  365. OggFLAC_API unsigned OggFLAC__file_decoder_get_channels(const OggFLAC__FileDecoder *decoder)
  366. {
  367. FLAC__ASSERT(0 != decoder);
  368. FLAC__ASSERT(0 != decoder->private_);
  369. return OggFLAC__seekable_stream_decoder_get_channels(decoder->private_->seekable_stream_decoder);
  370. }
  371. OggFLAC_API FLAC__ChannelAssignment OggFLAC__file_decoder_get_channel_assignment(const OggFLAC__FileDecoder *decoder)
  372. {
  373. FLAC__ASSERT(0 != decoder);
  374. FLAC__ASSERT(0 != decoder->private_);
  375. return OggFLAC__seekable_stream_decoder_get_channel_assignment(decoder->private_->seekable_stream_decoder);
  376. }
  377. OggFLAC_API unsigned OggFLAC__file_decoder_get_bits_per_sample(const OggFLAC__FileDecoder *decoder)
  378. {
  379. FLAC__ASSERT(0 != decoder);
  380. FLAC__ASSERT(0 != decoder->private_);
  381. return OggFLAC__seekable_stream_decoder_get_bits_per_sample(decoder->private_->seekable_stream_decoder);
  382. }
  383. OggFLAC_API unsigned OggFLAC__file_decoder_get_sample_rate(const OggFLAC__FileDecoder *decoder)
  384. {
  385. FLAC__ASSERT(0 != decoder);
  386. FLAC__ASSERT(0 != decoder->private_);
  387. return OggFLAC__seekable_stream_decoder_get_sample_rate(decoder->private_->seekable_stream_decoder);
  388. }
  389. OggFLAC_API unsigned OggFLAC__file_decoder_get_blocksize(const OggFLAC__FileDecoder *decoder)
  390. {
  391. FLAC__ASSERT(0 != decoder);
  392. FLAC__ASSERT(0 != decoder->private_);
  393. return OggFLAC__seekable_stream_decoder_get_blocksize(decoder->private_->seekable_stream_decoder);
  394. }
  395. OggFLAC_API FLAC__bool OggFLAC__file_decoder_process_single(OggFLAC__FileDecoder *decoder)
  396. {
  397. FLAC__bool ret;
  398. FLAC__ASSERT(0 != decoder);
  399. if(decoder->private_->seekable_stream_decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
  400. decoder->protected_->state = OggFLAC__FILE_DECODER_END_OF_FILE;
  401. if(decoder->protected_->state == OggFLAC__FILE_DECODER_END_OF_FILE)
  402. return true;
  403. FLAC__ASSERT(decoder->protected_->state == OggFLAC__FILE_DECODER_OK);
  404. ret = OggFLAC__seekable_stream_decoder_process_single(decoder->private_->seekable_stream_decoder);
  405. if(!ret)
  406. decoder->protected_->state = OggFLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
  407. return ret;
  408. }
  409. OggFLAC_API FLAC__bool OggFLAC__file_decoder_process_until_end_of_metadata(OggFLAC__FileDecoder *decoder)
  410. {
  411. FLAC__bool ret;
  412. FLAC__ASSERT(0 != decoder);
  413. if(decoder->private_->seekable_stream_decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
  414. decoder->protected_->state = OggFLAC__FILE_DECODER_END_OF_FILE;
  415. if(decoder->protected_->state == OggFLAC__FILE_DECODER_END_OF_FILE)
  416. return true;
  417. FLAC__ASSERT(decoder->protected_->state == OggFLAC__FILE_DECODER_OK);
  418. ret = OggFLAC__seekable_stream_decoder_process_until_end_of_metadata(decoder->private_->seekable_stream_decoder);
  419. if(!ret)
  420. decoder->protected_->state = OggFLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
  421. return ret;
  422. }
  423. OggFLAC_API FLAC__bool OggFLAC__file_decoder_process_until_end_of_file(OggFLAC__FileDecoder *decoder)
  424. {
  425. FLAC__bool ret;
  426. FLAC__ASSERT(0 != decoder);
  427. if(decoder->private_->seekable_stream_decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
  428. decoder->protected_->state = OggFLAC__FILE_DECODER_END_OF_FILE;
  429. if(decoder->protected_->state == OggFLAC__FILE_DECODER_END_OF_FILE)
  430. return true;
  431. FLAC__ASSERT(decoder->protected_->state == OggFLAC__FILE_DECODER_OK);
  432. ret = OggFLAC__seekable_stream_decoder_process_until_end_of_stream(decoder->private_->seekable_stream_decoder);
  433. if(!ret)
  434. decoder->protected_->state = OggFLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
  435. return ret;
  436. }
  437. OggFLAC_API FLAC__bool OggFLAC__file_decoder_seek_absolute(OggFLAC__FileDecoder *decoder, FLAC__uint64 sample)
  438. {
  439. FLAC__ASSERT(0 != decoder);
  440. FLAC__ASSERT(decoder->protected_->state == OggFLAC__FILE_DECODER_OK || decoder->protected_->state == OggFLAC__FILE_DECODER_END_OF_FILE);
  441. if(decoder->private_->filename == 0) { /* means the file is stdin... */
  442. decoder->protected_->state = OggFLAC__FILE_DECODER_SEEK_ERROR;
  443. return false;
  444. }
  445. if(!OggFLAC__seekable_stream_decoder_seek_absolute(decoder->private_->seekable_stream_decoder, sample)) {
  446. decoder->protected_->state = OggFLAC__FILE_DECODER_SEEK_ERROR;
  447. return false;
  448. }
  449. else {
  450. decoder->protected_->state = OggFLAC__FILE_DECODER_OK;
  451. return true;
  452. }
  453. }
  454. /***********************************************************************
  455.  *
  456.  * Private class methods
  457.  *
  458.  ***********************************************************************/
  459. void set_defaults_(OggFLAC__FileDecoder *decoder)
  460. {
  461. FLAC__ASSERT(0 != decoder);
  462. FLAC__ASSERT(0 != decoder->private_);
  463. decoder->private_->filename = 0;
  464. decoder->private_->write_callback = 0;
  465. decoder->private_->metadata_callback = 0;
  466. decoder->private_->error_callback = 0;
  467. decoder->private_->client_data = 0;
  468. }
  469. /*
  470.  * This will forcibly set stdin to binary mode (for OSes that require it)
  471.  */
  472. FILE *get_binary_stdin_()
  473. {
  474. /* if something breaks here it is probably due to the presence or
  475.  * absence of an underscore before the identifiers 'setmode',
  476.  * 'fileno', and/or 'O_BINARY'; check your system header files.
  477.  */
  478. #if defined _MSC_VER || defined __MINGW32__
  479. _setmode(_fileno(stdin), _O_BINARY);
  480. #elif defined __CYGWIN__
  481. /* almost certainly not needed for any modern Cygwin, but let's be safe... */
  482. setmode(_fileno(stdin), _O_BINARY);
  483. #endif
  484. return stdin;
  485. }
  486. OggFLAC__SeekableStreamDecoderReadStatus read_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
  487. {
  488. OggFLAC__FileDecoder *file_decoder = (OggFLAC__FileDecoder *)client_data;
  489. (void)decoder;
  490. if(*bytes > 0) {
  491. *bytes = (unsigned)fread(buffer, sizeof(FLAC__byte), *bytes, file_decoder->private_->file);
  492. if(ferror(file_decoder->private_->file)) {
  493. return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
  494. }
  495. else {
  496. return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
  497. }
  498. }
  499. else
  500. return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; /* abort to avoid a deadlock */
  501. }
  502. OggFLAC__SeekableStreamDecoderSeekStatus seek_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
  503. {
  504. OggFLAC__FileDecoder *file_decoder = (OggFLAC__FileDecoder *)client_data;
  505. (void)decoder;
  506. if(fseek(file_decoder->private_->file, (long)absolute_byte_offset, SEEK_SET) < 0)
  507. return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
  508. else
  509. return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
  510. }
  511. OggFLAC__SeekableStreamDecoderTellStatus tell_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
  512. {
  513. OggFLAC__FileDecoder *file_decoder = (OggFLAC__FileDecoder *)client_data;
  514. long pos;
  515. (void)decoder;
  516. if((pos = ftell(file_decoder->private_->file)) < 0)
  517. return OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
  518. else {
  519. *absolute_byte_offset = (FLAC__uint64)pos;
  520. return OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
  521. }
  522. }
  523. OggFLAC__SeekableStreamDecoderLengthStatus length_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
  524. {
  525. OggFLAC__FileDecoder *file_decoder = (OggFLAC__FileDecoder *)client_data;
  526. struct stat filestats;
  527. (void)decoder;
  528. if(0 == file_decoder->private_->filename || stat(file_decoder->private_->filename, &filestats) != 0)
  529. return OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
  530. else {
  531. *stream_length = (FLAC__uint64)filestats.st_size;
  532. return OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
  533. }
  534. }
  535. FLAC__bool eof_callback_(const OggFLAC__SeekableStreamDecoder *decoder, void *client_data)
  536. {
  537. OggFLAC__FileDecoder *file_decoder = (OggFLAC__FileDecoder *)client_data;
  538. (void)decoder;
  539. return feof(file_decoder->private_->file)? true : false;
  540. }
  541. FLAC__StreamDecoderWriteStatus write_callback_(const OggFLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
  542. {
  543. OggFLAC__FileDecoder *file_decoder = (OggFLAC__FileDecoder *)client_data;
  544. (void)decoder;
  545. return file_decoder->private_->write_callback(file_decoder, frame, buffer, file_decoder->private_->client_data);
  546. }
  547. void metadata_callback_(const OggFLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
  548. {
  549. OggFLAC__FileDecoder *file_decoder = (OggFLAC__FileDecoder *)client_data;
  550. (void)decoder;
  551. file_decoder->private_->metadata_callback(file_decoder, metadata, file_decoder->private_->client_data);
  552. }
  553. void error_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
  554. {
  555. OggFLAC__FileDecoder *file_decoder = (OggFLAC__FileDecoder *)client_data;
  556. (void)decoder;
  557. file_decoder->private_->error_callback(file_decoder, status, file_decoder->private_->client_data);
  558. }