diff options
| author | jacqueline <me@jacqueline.id.au> | 2024-01-18 14:55:27 +1100 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2024-01-18 14:55:27 +1100 |
| commit | d1ae1a4230b413b6a92179936d431c83247c5fd2 (patch) | |
| tree | 3d209249d1829ff0e24660190035fad64fef050d /lib/faad2/frontend | |
| parent | 442c45d461ad4c81d01898962e3ad420d390495a (diff) | |
| download | tangara-fw-d1ae1a4230b413b6a92179936d431c83247c5fd2.tar.gz | |
on second thought, let's not violate patents. 'tis a silly system.
Diffstat (limited to 'lib/faad2/frontend')
| -rw-r--r-- | lib/faad2/frontend/audio.c | 512 | ||||
| -rw-r--r-- | lib/faad2/frontend/audio.h | 64 | ||||
| -rw-r--r-- | lib/faad2/frontend/faad.man | 85 | ||||
| -rw-r--r-- | lib/faad2/frontend/getopt.c | 725 | ||||
| -rw-r--r-- | lib/faad2/frontend/getopt.h | 130 | ||||
| -rw-r--r-- | lib/faad2/frontend/main.c | 1378 | ||||
| -rw-r--r-- | lib/faad2/frontend/mp4read.c | 1109 | ||||
| -rw-r--r-- | lib/faad2/frontend/mp4read.h | 78 | ||||
| -rw-r--r-- | lib/faad2/frontend/unicode_support.c | 172 | ||||
| -rw-r--r-- | lib/faad2/frontend/unicode_support.h | 44 |
10 files changed, 0 insertions, 4297 deletions
diff --git a/lib/faad2/frontend/audio.c b/lib/faad2/frontend/audio.c deleted file mode 100644 index 01da9518..00000000 --- a/lib/faad2/frontend/audio.c +++ /dev/null @@ -1,512 +0,0 @@ -/* -** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding -** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com -** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software -** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -** -** Any non-GPL usage of this software or parts of this software is strictly -** forbidden. -** -** The "appropriate copyright message" mentioned in section 2c of the GPLv2 -** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" -** -** Commercial non-GPL licensing of this software is possible. -** For more info contact Nero AG through Mpeg4AAClicense@nero.com. -** -** $Id: audio.c,v 1.30 2015/01/22 09:40:52 knik Exp $ -**/ - -#ifdef _WIN32 -#include <io.h> -#endif -#include <stdlib.h> -#include <stdio.h> -#include <fcntl.h> -#include <math.h> -#include <neaacdec.h> -#include <stdint.h> - -#include "unicode_support.h" -#include "audio.h" - -static size_t write_wav_header(audio_file *aufile); -static size_t write_wav_extensible_header(audio_file *aufile, long channelMask); -static size_t write_audio_16bit(audio_file *aufile, void *sample_buffer, - unsigned int samples); -static size_t write_audio_24bit(audio_file *aufile, void *sample_buffer, - unsigned int samples); -static size_t write_audio_32bit(audio_file *aufile, void *sample_buffer, - unsigned int samples); -static size_t write_audio_float(audio_file *aufile, void *sample_buffer, - unsigned int samples); - -audio_file *open_audio_file(char *infile, int samplerate, int channels, - int outputFormat, int fileType, long channelMask) -{ - audio_file *aufile = malloc(sizeof(audio_file)); - - aufile->outputFormat = outputFormat; - - aufile->samplerate = samplerate; - aufile->channels = channels; - aufile->total_samples = 0; - aufile->fileType = fileType; - aufile->channelMask = channelMask; - - switch (outputFormat) - { - case FAAD_FMT_16BIT: - aufile->bits_per_sample = 16; - break; - case FAAD_FMT_24BIT: - aufile->bits_per_sample = 24; - break; - case FAAD_FMT_32BIT: - case FAAD_FMT_FLOAT: - aufile->bits_per_sample = 32; - break; - default: - if (aufile) free(aufile); - return NULL; - } - - if(infile[0] == '-') - { -#ifdef _WIN32 - _setmode(_fileno(stdout), O_BINARY); -#endif - aufile->sndfile = stdout; - aufile->toStdio = 1; - } else { - aufile->toStdio = 0; - aufile->sndfile = faad_fopen(infile, "wb"); - } - - if (aufile->sndfile == NULL) - { - if (aufile) free(aufile); - return NULL; - } - - if (aufile->fileType == OUTPUT_WAV) - { - if (aufile->channelMask) - write_wav_extensible_header(aufile, aufile->channelMask); - else - write_wav_header(aufile); - } - - return aufile; -} - -size_t write_audio_file(audio_file *aufile, void *sample_buffer, int samples) -{ - char *buf = (char *)sample_buffer; - switch (aufile->outputFormat) - { - case FAAD_FMT_16BIT: - return write_audio_16bit(aufile, buf, samples); - case FAAD_FMT_24BIT: - return write_audio_24bit(aufile, buf, samples); - case FAAD_FMT_32BIT: - return write_audio_32bit(aufile, buf, samples); - case FAAD_FMT_FLOAT: - return write_audio_float(aufile, buf, samples); - default: - return 0; - } - // return 0; -} - -void close_audio_file(audio_file *aufile) -{ - if ((aufile->fileType == OUTPUT_WAV) && (aufile->toStdio == 0)) - { - fseek(aufile->sndfile, 0, SEEK_SET); - - if (aufile->channelMask) - write_wav_extensible_header(aufile, aufile->channelMask); - else - write_wav_header(aufile); - } - - if (aufile->toStdio == 0) - fclose(aufile->sndfile); - - if (aufile) free(aufile); -} - -static size_t write_wav_header(audio_file *aufile) -{ - unsigned char header[44]; - unsigned char* p = header; - unsigned int bytes = (aufile->bits_per_sample + 7) / 8; - float data_size = (float)bytes * aufile->total_samples; - unsigned long word32; - - *p++ = 'R'; *p++ = 'I'; *p++ = 'F'; *p++ = 'F'; - - word32 = (data_size + (44 - 8) < (float)MAXWAVESIZE) ? - (unsigned long)data_size + (44 - 8) : (unsigned long)MAXWAVESIZE; - *p++ = (unsigned char)(word32 >> 0); - *p++ = (unsigned char)(word32 >> 8); - *p++ = (unsigned char)(word32 >> 16); - *p++ = (unsigned char)(word32 >> 24); - - *p++ = 'W'; *p++ = 'A'; *p++ = 'V'; *p++ = 'E'; - - *p++ = 'f'; *p++ = 'm'; *p++ = 't'; *p++ = ' '; - - *p++ = 0x10; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00; - - if (aufile->outputFormat == FAAD_FMT_FLOAT) - { - *p++ = 0x03; *p++ = 0x00; - } else { - *p++ = 0x01; *p++ = 0x00; - } - - *p++ = (unsigned char)(aufile->channels >> 0); - *p++ = (unsigned char)(aufile->channels >> 8); - - word32 = (unsigned long)(aufile->samplerate + 0.5); - *p++ = (unsigned char)(word32 >> 0); - *p++ = (unsigned char)(word32 >> 8); - *p++ = (unsigned char)(word32 >> 16); - *p++ = (unsigned char)(word32 >> 24); - - word32 = aufile->samplerate * bytes * aufile->channels; - *p++ = (unsigned char)(word32 >> 0); - *p++ = (unsigned char)(word32 >> 8); - *p++ = (unsigned char)(word32 >> 16); - *p++ = (unsigned char)(word32 >> 24); - - word32 = bytes * aufile->channels; - *p++ = (unsigned char)(word32 >> 0); - *p++ = (unsigned char)(word32 >> 8); - - *p++ = (unsigned char)(aufile->bits_per_sample >> 0); - *p++ = (unsigned char)(aufile->bits_per_sample >> 8); - - *p++ = 'd'; *p++ = 'a'; *p++ = 't'; *p++ = 'a'; - - word32 = data_size < MAXWAVESIZE ? - (unsigned long)data_size : (unsigned long)MAXWAVESIZE; - *p++ = (unsigned char)(word32 >> 0); - *p++ = (unsigned char)(word32 >> 8); - *p++ = (unsigned char)(word32 >> 16); - *p++ = (unsigned char)(word32 >> 24); - - return fwrite(header, sizeof(header), 1, aufile->sndfile); -} - -static size_t write_wav_extensible_header(audio_file *aufile, long channelMask) -{ - unsigned char header[68]; - unsigned char* p = header; - unsigned int bytes = (aufile->bits_per_sample + 7) / 8; - float data_size = (float)bytes * aufile->total_samples; - unsigned long word32; - - *p++ = 'R'; *p++ = 'I'; *p++ = 'F'; *p++ = 'F'; - - word32 = (data_size + (68 - 8) < (float)MAXWAVESIZE) ? - (unsigned long)data_size + (68 - 8) : (unsigned long)MAXWAVESIZE; - *p++ = (unsigned char)(word32 >> 0); - *p++ = (unsigned char)(word32 >> 8); - *p++ = (unsigned char)(word32 >> 16); - *p++ = (unsigned char)(word32 >> 24); - - *p++ = 'W'; *p++ = 'A'; *p++ = 'V'; *p++ = 'E'; - - *p++ = 'f'; *p++ = 'm'; *p++ = 't'; *p++ = ' '; - - *p++ = /*0x10*/0x28; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00; - - /* WAVE_FORMAT_EXTENSIBLE */ - *p++ = 0xFE; *p++ = 0xFF; - - *p++ = (unsigned char)(aufile->channels >> 0); - *p++ = (unsigned char)(aufile->channels >> 8); - - word32 = (unsigned long)(aufile->samplerate + 0.5); - *p++ = (unsigned char)(word32 >> 0); - *p++ = (unsigned char)(word32 >> 8); - *p++ = (unsigned char)(word32 >> 16); - *p++ = (unsigned char)(word32 >> 24); - - word32 = aufile->samplerate * bytes * aufile->channels; - *p++ = (unsigned char)(word32 >> 0); - *p++ = (unsigned char)(word32 >> 8); - *p++ = (unsigned char)(word32 >> 16); - *p++ = (unsigned char)(word32 >> 24); - - word32 = bytes * aufile->channels; - *p++ = (unsigned char)(word32 >> 0); - *p++ = (unsigned char)(word32 >> 8); - - *p++ = (unsigned char)(aufile->bits_per_sample >> 0); - *p++ = (unsigned char)(aufile->bits_per_sample >> 8); - - /* cbSize */ - *p++ = (unsigned char)(22); - *p++ = (unsigned char)(0); - - /* WAVEFORMATEXTENSIBLE */ - - /* wValidBitsPerSample */ - *p++ = (unsigned char)(aufile->bits_per_sample >> 0); - *p++ = (unsigned char)(aufile->bits_per_sample >> 8); - - /* dwChannelMask */ - word32 = channelMask; - *p++ = (unsigned char)(word32 >> 0); - *p++ = (unsigned char)(word32 >> 8); - *p++ = (unsigned char)(word32 >> 16); - *p++ = (unsigned char)(word32 >> 24); - - /* SubFormat */ - if (aufile->outputFormat == FAAD_FMT_FLOAT) - { - /* KSDATAFORMAT_SUBTYPE_IEEE_FLOAT: 00000003-0000-0010-8000-00aa00389b71 */ - *p++ = 0x03; - *p++ = 0x00; - *p++ = 0x00; - *p++ = 0x00; - *p++ = 0x00; *p++ = 0x00; *p++ = 0x10; *p++ = 0x00; *p++ = 0x80; *p++ = 0x00; - *p++ = 0x00; *p++ = 0xaa; *p++ = 0x00; *p++ = 0x38; *p++ = 0x9b; *p++ = 0x71; - } else { - /* KSDATAFORMAT_SUBTYPE_PCM: 00000001-0000-0010-8000-00aa00389b71 */ - *p++ = 0x01; - *p++ = 0x00; - *p++ = 0x00; - *p++ = 0x00; - *p++ = 0x00; *p++ = 0x00; *p++ = 0x10; *p++ = 0x00; *p++ = 0x80; *p++ = 0x00; - *p++ = 0x00; *p++ = 0xaa; *p++ = 0x00; *p++ = 0x38; *p++ = 0x9b; *p++ = 0x71; - } - - /* end WAVEFORMATEXTENSIBLE */ - - *p++ = 'd'; *p++ = 'a'; *p++ = 't'; *p++ = 'a'; - - word32 = data_size < MAXWAVESIZE ? - (unsigned long)data_size : (unsigned long)MAXWAVESIZE; - *p++ = (unsigned char)(word32 >> 0); - *p++ = (unsigned char)(word32 >> 8); - *p++ = (unsigned char)(word32 >> 16); - *p++ = (unsigned char)(word32 >> 24); - - return fwrite(header, sizeof(header), 1, aufile->sndfile); -} - -static size_t write_audio_16bit(audio_file *aufile, void *sample_buffer, - unsigned int samples) -{ - size_t ret; - unsigned int i; - short *sample_buffer16 = (short*)sample_buffer; - char *data = malloc(samples*aufile->bits_per_sample*sizeof(char)/8); - - aufile->total_samples += samples; - - if (aufile->channels == 6 && aufile->channelMask) - { - for (i = 0; i < samples; i += aufile->channels) - { - short r1, r2, r3, r4, r5, r6; - r1 = sample_buffer16[i]; - r2 = sample_buffer16[i+1]; - r3 = sample_buffer16[i+2]; - r4 = sample_buffer16[i+3]; - r5 = sample_buffer16[i+4]; - r6 = sample_buffer16[i+5]; - sample_buffer16[i] = r2; - sample_buffer16[i+1] = r3; - sample_buffer16[i+2] = r1; - sample_buffer16[i+3] = r6; - sample_buffer16[i+4] = r4; - sample_buffer16[i+5] = r5; - } - } - - for (i = 0; i < samples; i++) - { - data[i*2] = (char)(sample_buffer16[i] & 0xFF); - data[i*2+1] = (char)((sample_buffer16[i] >> 8) & 0xFF); - } - - ret = fwrite(data, samples, aufile->bits_per_sample/8, aufile->sndfile); - - if (data) free(data); - - return ret; -} - -static size_t write_audio_24bit(audio_file *aufile, void *sample_buffer, - unsigned int samples) -{ - size_t ret; - unsigned int i; - int32_t *sample_buffer24 = (int32_t*)sample_buffer; - char *data = malloc(samples*aufile->bits_per_sample*sizeof(char)/8); - - aufile->total_samples += samples; - - if (aufile->channels == 6 && aufile->channelMask) - { - for (i = 0; i < samples; i += aufile->channels) - { - long r1, r2, r3, r4, r5, r6; - r1 = sample_buffer24[i]; - r2 = sample_buffer24[i+1]; - r3 = sample_buffer24[i+2]; - r4 = sample_buffer24[i+3]; - r5 = sample_buffer24[i+4]; - r6 = sample_buffer24[i+5]; - sample_buffer24[i] = r2; - sample_buffer24[i+1] = r3; - sample_buffer24[i+2] = r1; - sample_buffer24[i+3] = r6; - sample_buffer24[i+4] = r4; - sample_buffer24[i+5] = r5; - } - } - - for (i = 0; i < samples; i++) - { - data[i*3] = (char)(sample_buffer24[i] & 0xFF); - data[i*3+1] = (char)((sample_buffer24[i] >> 8) & 0xFF); - data[i*3+2] = (char)((sample_buffer24[i] >> 16) & 0xFF); - } - - ret = fwrite(data, samples, aufile->bits_per_sample/8, aufile->sndfile); - - if (data) free(data); - - return ret; -} - -static size_t write_audio_32bit(audio_file *aufile, void *sample_buffer, - unsigned int samples) -{ - size_t ret; - unsigned int i; - int32_t *sample_buffer32 = (int32_t*)sample_buffer; - char *data = malloc(samples*aufile->bits_per_sample*sizeof(char)/8); - - aufile->total_samples += samples; - - if (aufile->channels == 6 && aufile->channelMask) - { - for (i = 0; i < samples; i += aufile->channels) - { - long r1, r2, r3, r4, r5, r6; - r1 = sample_buffer32[i]; - r2 = sample_buffer32[i+1]; - r3 = sample_buffer32[i+2]; - r4 = sample_buffer32[i+3]; - r5 = sample_buffer32[i+4]; - r6 = sample_buffer32[i+5]; - sample_buffer32[i] = r2; - sample_buffer32[i+1] = r3; - sample_buffer32[i+2] = r1; - sample_buffer32[i+3] = r6; - sample_buffer32[i+4] = r4; - sample_buffer32[i+5] = r5; - } - } - - for (i = 0; i < samples; i++) - { - data[i*4] = (char)(sample_buffer32[i] & 0xFF); - data[i*4+1] = (char)((sample_buffer32[i] >> 8) & 0xFF); - data[i*4+2] = (char)((sample_buffer32[i] >> 16) & 0xFF); - data[i*4+3] = (char)((sample_buffer32[i] >> 24) & 0xFF); - } - - ret = fwrite(data, samples, aufile->bits_per_sample/8, aufile->sndfile); - - if (data) free(data); - - return ret; -} - -static size_t write_audio_float(audio_file *aufile, void *sample_buffer, - unsigned int samples) -{ - size_t ret; - unsigned int i; - float *sample_buffer_f = (float*)sample_buffer; - unsigned char *data = malloc(samples*aufile->bits_per_sample*sizeof(char)/8); - - aufile->total_samples += samples; - - if (aufile->channels == 6 && aufile->channelMask) - { - for (i = 0; i < samples; i += aufile->channels) - { - float r1, r2, r3, r4, r5, r6; - r1 = sample_buffer_f[i]; - r2 = sample_buffer_f[i+1]; - r3 = sample_buffer_f[i+2]; - r4 = sample_buffer_f[i+3]; - r5 = sample_buffer_f[i+4]; - r6 = sample_buffer_f[i+5]; - sample_buffer_f[i] = r2; - sample_buffer_f[i+1] = r3; - sample_buffer_f[i+2] = r1; - sample_buffer_f[i+3] = r6; - sample_buffer_f[i+4] = r4; - sample_buffer_f[i+5] = r5; - } - } - - for (i = 0; i < samples; i++) - { - int exponent, mantissa, negative = 0 ; - float in = sample_buffer_f[i]; - - data[i*4] = 0; data[i*4+1] = 0; data[i*4+2] = 0; data[i*4+3] = 0; - if (in == 0.0) - continue; - - if (in < 0.0) - { - in *= -1.0; - negative = 1; - } - in = (float)frexp(in, &exponent); - exponent += 126; - in *= (float)0x1000000; - mantissa = (((int)in) & 0x7FFFFF); - - if (negative) - data[i*4+3] |= 0x80; - - if (exponent & 0x01) - data[i*4+2] |= 0x80; - - data[i*4] = mantissa & 0xFF; - data[i*4+1] = (mantissa >> 8) & 0xFF; - data[i*4+2] |= (mantissa >> 16) & 0x7F; - data[i*4+3] |= (exponent >> 1) & 0x7F; - } - - ret = fwrite(data, samples, aufile->bits_per_sample/8, aufile->sndfile); - - if (data) free(data); - - return ret; -} diff --git a/lib/faad2/frontend/audio.h b/lib/faad2/frontend/audio.h deleted file mode 100644 index 5518105b..00000000 --- a/lib/faad2/frontend/audio.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding -** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com -** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software -** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -** -** Any non-GPL usage of this software or parts of this software is strictly -** forbidden. -** -** The "appropriate copyright message" mentioned in section 2c of the GPLv2 -** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" -** -** Commercial non-GPL licensing of this software is possible. -** For more info contact Nero AG through Mpeg4AAClicense@nero.com. -** -** $Id: audio.h,v 1.19 2007/11/01 12:33:29 menno Exp $ -**/ - -#ifndef AUDIO_H_INCLUDED -#define AUDIO_H_INCLUDED - -#ifdef __cplusplus -extern "C" { -#endif - -#define MAXWAVESIZE 4294967040LU - -#define OUTPUT_WAV 1 -#define OUTPUT_RAW 2 - -typedef struct -{ - int toStdio; - int outputFormat; - FILE *sndfile; - unsigned int fileType; - unsigned long samplerate; - unsigned int bits_per_sample; - unsigned int channels; - unsigned long total_samples; - long channelMask; -} audio_file; - -audio_file *open_audio_file(char *infile, int samplerate, int channels, - int outputFormat, int fileType, long channelMask); -size_t write_audio_file(audio_file *aufile, void *sample_buffer, int samples); -void close_audio_file(audio_file *aufile); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/lib/faad2/frontend/faad.man b/lib/faad2/frontend/faad.man deleted file mode 100644 index 96d4a29e..00000000 --- a/lib/faad2/frontend/faad.man +++ /dev/null @@ -1,85 +0,0 @@ -.TH FAAD "1" "October 2006" "faad 2.5" "" -.SH NAME -faad \(em Process an Advanced Audio Codec stream - -.SH "SYNOPSIS" -.B faad -[options] [\-w | \-o <output_filename> | \-a <output_filename>] input_filename - -.SH "DESCRIPTION" -This utility provides a command line interface to libfaad2. This program reads in MPEG\(hy4 AAC files, processes, and outputs them in either Microsoft WAV, MPEG\(hy4 AAC ADTS, or standard PCM formats. - -.SH "OPTIONS" -.TP -.BI \-a " <filename>" ", \-\^\-adtsout" " <filename>" -Sets the processing to output to the specified file in MPEG\(hy4 AAC ADTS format -.TP -.BI \-b " <number>" ", \-\^\-bits" " <number>" -Set the output (individual) sample format. The number takes one of the following values: -.RS -.RS -1: 16\(hybit PCM data (default). -.br -2: 24\(hybit PCM data. -.br -3: 32\(hybit PCM data. -.br -4: 32\(hybit floating\(hypoint data. -.br -5: 64\(hybit floating\(hypoint data. -.RE -.RE -.TP -.B \-d ", \-\^\-downmix" -Set the processing to downsample from 5.1 (surround sound and bass) channels to 2 channels (stereo). -.TP -.BI \-f " <number>" ", \-\^\-format" " <number>" -Set the output file format. The number takes one of the following values: -.RS -.RS -1: Microsoft WAV format (default). -.br -2: Raw PCM data. -.RE -.RE -.TP -.BI \-g -Set the processing to not perform gapless decoding. -.TP -.B \-h ", \-\^\-help" -Shows a usage summary. -.TP -.B \-i ", \-\^\-info" -Shows information about the about the input file. -.TP -.BI \-l " <number>" ", \-\^\-objecttype" " <number>" -Sets the MPEG\hy(4 profile and object type for the processing to use. The number takes one of the following values: -.RS -.RS -1: Main object type. -.br -2: Low Complexity (LC) object type (default). -.br -4: Long Term Prediction (LTP) object type. -.br -23: Low Delay (LD) object type. -.RE -.RE -.TP -.BI \-o " <filename>" ", \-\^\-outfile" " <number>" -Sets the filename for processing output. -.TP -.B \-q ", \-\^\-quiet" -Quiet \- Suppresses status messages during processing. -.TP -.B \-t ", \-\^\-oldformat" -Sets the processing to use the old MPEG\(hy4 AAC ADTS format when outputting in said format. -.TP -.B \-w ", \-\^\-stdio" -Sets the processing output to be sent to the standard out. - -.SH "AUTHOR" -Matthew W. S. Bell <matthew (at) bells23.org.uk> - -.SH "SEE ALSO" -\fBfaac\fP(1)
\ No newline at end of file diff --git a/lib/faad2/frontend/getopt.c b/lib/faad2/frontend/getopt.c deleted file mode 100644 index f069a5d1..00000000 --- a/lib/faad2/frontend/getopt.c +++ /dev/null @@ -1,725 +0,0 @@ -/* Getopt for GNU. - NOTE: getopt is now part of the C library, so if you don't know what - "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu - before changing it! - - Copyright (C) 1987, 88, 89, 90, 91, 92, 1993 - Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifndef __STDC__ -# ifndef const -# define const -# endif -#endif - -/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. */ -#ifndef _NO_PROTO -#define _NO_PROTO -#endif - -#include <stdio.h> -#include <string.h> - -/* Comment out all this code if we are using the GNU C Library, and are not - actually compiling the library itself. This code is part of the GNU C - Library, but also included in many other GNU distributions. Compiling - and linking in this code is a waste when using the GNU C library - (especially if it is a shared library). Rather than having every GNU - program understand `configure --with-gnu-libc' and omit the object files, - it is simpler to just do this in the source for each such file. */ - -#if defined (_LIBC) || !defined (__GNU_LIBRARY__) || !__MacOSX__ - - -/* This needs to come after some library #include - to get __GNU_LIBRARY__ defined. */ -#ifdef __GNU_LIBRARY__ -/* Don't include stdlib.h for non-GNU C libraries because some of them - contain conflicting prototypes for getopt. */ -#include <stdlib.h> -#endif /* GNU C library. */ - -/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a - long-named option. Because this is not POSIX.2 compliant, it is - being phased out. */ -/* #define GETOPT_COMPAT */ - -/* This version of `getopt' appears to the caller like standard Unix `getopt' - but it behaves differently for the user, since it allows the user - to intersperse the options with the other arguments. - - As `getopt' works, it permutes the elements of ARGV so that, - when it is done, all the options precede everything else. Thus - all application programs are extended to handle flexible argument order. - - Setting the environment variable POSIXLY_CORRECT disables permutation. - Then the behavior is completely standard. - - GNU application programs can use a third alternative mode in which - they can distinguish the relative order of options and other arguments. */ - -#include "getopt.h" - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -char *optarg = 0; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns EOF, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -/* XXX 1003.2 says this must be 1 before any call. */ -int optind = 0; - -/* The next char to be scanned in the option-element - in which the last option character we returned was found. - This allows us to pick up the scan where we left off. - - If this is zero, or a null string, it means resume the scan - by advancing to the next ARGV-element. */ - -static char *nextchar; - -/* Callers store zero here to inhibit the error message - for unrecognized options. */ - -int opterr = 1; - -/* Set to an option character which was unrecognized. - This must be initialized on some systems to avoid linking in the - system's own getopt implementation. */ - -#define BAD_OPTION '\0' -int optopt = BAD_OPTION; - -/* Describe how to deal with options that follow non-option ARGV-elements. - - If the caller did not specify anything, - the default is REQUIRE_ORDER if the environment variable - POSIXLY_CORRECT is defined, PERMUTE otherwise. - - REQUIRE_ORDER means don't recognize them as options; - stop option processing when the first non-option is seen. - This is what Unix does. - This mode of operation is selected by either setting the environment - variable POSIXLY_CORRECT, or using `+' as the first character - of the list of option characters. - - PERMUTE is the default. We permute the contents of ARGV as we scan, - so that eventually all the non-options are at the end. This allows options - to be given in any order, even with programs that were not written to - expect this. - - RETURN_IN_ORDER is an option available to programs that were written - to expect options and other ARGV-elements in any order and that care about - the ordering of the two. We describe each non-option ARGV-element - as if it were the argument of an option with character code 1. - Using `-' as the first character of the list of option characters - selects this mode of operation. - - The special argument `--' forces an end of option-scanning regardless - of the value of `ordering'. In the case of RETURN_IN_ORDER, only - `--' can cause `getopt' to return EOF with `optind' != ARGC. */ - -static enum -{ - REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER -} ordering; - -#ifdef __GNU_LIBRARY__ -/* We want to avoid inclusion of string.h with non-GNU libraries - because there are many ways it can cause trouble. - On some systems, it contains special magic macros that don't work - in GCC. */ -#include <string.h> -#define my_index strchr -#define my_strlen strlen -#else - -/* Avoid depending on library functions or files - whose names are inconsistent. */ - -#if __STDC__ || defined(PROTO) -extern char *getenv(const char *name); -extern int strcmp (const char *s1, const char *s2); - -static int my_strlen(const char *s); -static char *my_index (const char *str, int chr); -#else -extern char *getenv (const char *name); -#endif - -static int my_strlen(const char *str) { - int n = 0; - while (*str++) - n++; - return n; -} - -static char *my_index(const char *str, int chr) { - while (*str) - { - if (*str == chr) - return (char *) str; - str++; - } - return 0; -} - -#endif /* GNU C library. */ - -/* Handle permutation of arguments. */ - -/* Describe the part of ARGV that contains non-options that have - been skipped. `first_nonopt' is the index in ARGV of the first of them; - `last_nonopt' is the index after the last of them. */ - -static int first_nonopt; -static int last_nonopt; - -/* Exchange two adjacent subsequences of ARGV. - One subsequence is elements [first_nonopt,last_nonopt) - which contains all the non-options that have been skipped so far. - The other is elements [last_nonopt,optind), which contains all - the options processed since those non-options were skipped. - - `first_nonopt' and `last_nonopt' are relocated so that they describe - the new indices of the non-options in ARGV after they are moved. - - To perform the swap, we first reverse the order of all elements. So - all options now come before all non options, but they are in the - wrong order. So we put back the options and non options in original - order by reversing them again. For example: - original input: a b c -x -y - reverse all: -y -x c b a - reverse options: -x -y c b a - reverse non options: -x -y a b c -*/ - -#if __STDC__ || defined(PROTO) -static void exchange (char **argv); -#endif - -static void exchange (char **argv) { - char *temp, **first, **last; - - /* Reverse all the elements [first_nonopt, optind) */ - first = &argv[first_nonopt]; - last = &argv[optind-1]; - while (first < last) { - temp = *first; *first = *last; *last = temp; first++; last--; - } - /* Put back the options in order */ - first = &argv[first_nonopt]; - first_nonopt += (optind - last_nonopt); - last = &argv[first_nonopt - 1]; - while (first < last) { - temp = *first; *first = *last; *last = temp; first++; last--; - } - - /* Put back the non options in order */ - first = &argv[first_nonopt]; - last_nonopt = optind; - last = &argv[last_nonopt-1]; - while (first < last) { - temp = *first; *first = *last; *last = temp; first++; last--; - } -} - -/* Scan elements of ARGV (whose length is ARGC) for option characters - given in OPTSTRING. - - If an element of ARGV starts with '-', and is not exactly "-" or "--", - then it is an option element. The characters of this element - (aside from the initial '-') are option characters. If `getopt' - is called repeatedly, it returns successively each of the option characters - from each of the option elements. - - If `getopt' finds another option character, it returns that character, - updating `optind' and `nextchar' so that the next call to `getopt' can - resume the scan with the following option character or ARGV-element. - - If there are no more option characters, `getopt' returns `EOF'. - Then `optind' is the index in ARGV of the first ARGV-element - that is not an option. (The ARGV-elements have been permuted - so that those that are not options now come last.) - - OPTSTRING is a string containing the legitimate option characters. - If an option character is seen that is not listed in OPTSTRING, - return BAD_OPTION after printing an error message. If you set `opterr' to - zero, the error message is suppressed but we still return BAD_OPTION. - - If a char in OPTSTRING is followed by a colon, that means it wants an arg, - so the following text in the same ARGV-element, or the text of the following - ARGV-element, is returned in `optarg'. Two colons mean an option that - wants an optional arg; if there is text in the current ARGV-element, - it is returned in `optarg', otherwise `optarg' is set to zero. - - If OPTSTRING starts with `-' or `+', it requests different methods of - handling the non-option ARGV-elements. - See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. - - Long-named options begin with `--' instead of `-'. - Their names may be abbreviated as long as the abbreviation is unique - or is an exact match for some defined option. If they have an - argument, it follows the option name in the same ARGV-element, separated - from the option name by a `=', or else the in next ARGV-element. - When `getopt' finds a long-named option, it returns 0 if that option's - `flag' field is nonzero, the value of the option's `val' field - if the `flag' field is zero. - - The elements of ARGV aren't really const, because we permute them. - But we pretend they're const in the prototype to be compatible - with other systems. - - LONGOPTS is a vector of `struct option' terminated by an - element containing a name which is zero. - - LONGIND returns the index in LONGOPT of the long-named option found. - It is only valid when a long-named option has been found by the most - recent call. - - If LONG_ONLY is nonzero, '-' as well as '--' can introduce - long-named options. */ - -int _getopt_internal(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *longind, int long_only) { - int option_index; - - optarg = 0; - - /* Initialize the internal data when the first call is made. - Start processing options with ARGV-element 1 (since ARGV-element 0 - is the program name); the sequence of previously skipped - non-option ARGV-elements is empty. */ - - if (optind == 0) - { - first_nonopt = last_nonopt = optind = 1; - - nextchar = NULL; - - /* Determine how to handle the ordering of options and nonoptions. */ - - if (optstring[0] == '-') - { - ordering = RETURN_IN_ORDER; - ++optstring; - } - else if (optstring[0] == '+') - { - ordering = REQUIRE_ORDER; - ++optstring; - } - else if (getenv ("POSIXLY_CORRECT") != NULL) - ordering = REQUIRE_ORDER; - else - ordering = PERMUTE; - } - - if (nextchar == NULL || *nextchar == '\0') - { - if (ordering == PERMUTE) - { - /* If we have just processed some options following some non-options, - exchange them so that the options come first. */ - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (last_nonopt != optind) - first_nonopt = optind; - - /* Now skip any additional non-options - and extend the range of non-options previously skipped. */ - - while (optind < argc - && (argv[optind][0] != '-' || argv[optind][1] == '\0') -#ifdef GETOPT_COMPAT - && (longopts == NULL - || argv[optind][0] != '+' || argv[optind][1] == '\0') -#endif /* GETOPT_COMPAT */ - ) - optind++; - last_nonopt = optind; - } - - /* Special ARGV-element `--' means premature end of options. - Skip it like a null option, - then exchange with previous non-options as if it were an option, - then skip everything else like a non-option. */ - - if (optind != argc && !strcmp (argv[optind], "--")) - { - optind++; - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (first_nonopt == last_nonopt) - first_nonopt = optind; - last_nonopt = argc; - - optind = argc; - } - - /* If we have done all the ARGV-elements, stop the scan - and back over any non-options that we skipped and permuted. */ - - if (optind == argc) - { - /* Set the next-arg-index to point at the non-options - that we previously skipped, so the caller will digest them. */ - if (first_nonopt != last_nonopt) - optind = first_nonopt; - return EOF; - } - - /* If we have come to a non-option and did not permute it, - either stop the scan or describe it to the caller and pass it by. */ - - if ((argv[optind][0] != '-' || argv[optind][1] == '\0') -#ifdef GETOPT_COMPAT - && (longopts == NULL - || argv[optind][0] != '+' || argv[optind][1] == '\0') -#endif /* GETOPT_COMPAT */ - ) - { - if (ordering == REQUIRE_ORDER) - return EOF; - optarg = argv[optind++]; - return 1; - } - - /* We have found another option-ARGV-element. - Start decoding its characters. */ - - nextchar = (argv[optind] + 1 - + (longopts != NULL && argv[optind][1] == '-')); - } - - if (longopts != NULL - && ((argv[optind][0] == '-' - && (argv[optind][1] == '-' || long_only)) -#ifdef GETOPT_COMPAT - || argv[optind][0] == '+' -#endif /* GETOPT_COMPAT */ - )) - { - const struct option *p; - char *s = nextchar; - int exact = 0; - int ambig = 0; - const struct option *pfound = NULL; - int indfound = 0; - - while (*s && *s != '=') - s++; - - /* Test all options for either exact match or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; - p++, option_index++) - if (!strncmp (p->name, nextchar, s - nextchar)) - { - if (s - nextchar == my_strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else - /* Second nonexact match found. */ - ambig = 1; - } - - if (ambig && !exact) - { - if (opterr) - fprintf (stderr, "%s: option `%s' is ambiguous\n", - argv[0], argv[optind]); - nextchar += my_strlen (nextchar); - optind++; - return BAD_OPTION; - } - - if (pfound != NULL) - { - option_index = indfound; - optind++; - if (*s) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - optarg = s + 1; - else - { - if (opterr) - { - if (argv[optind - 1][1] == '-') - /* --option */ - fprintf (stderr, - "%s: option `--%s' doesn't allow an argument\n", - argv[0], pfound->name); - else - /* +option or -option */ - fprintf (stderr, - "%s: option `%c%s' doesn't allow an argument\n", - argv[0], argv[optind - 1][0], pfound->name); - } - nextchar += my_strlen (nextchar); - return BAD_OPTION; - } - } - else if (pfound->has_arg == 1) - { - if (optind < argc) - optarg = argv[optind++]; - else - { - if (opterr) - fprintf (stderr, "%s: option `%s' requires an argument\n", - argv[0], argv[optind - 1]); - nextchar += my_strlen (nextchar); - return optstring[0] == ':' ? ':' : BAD_OPTION; - } - } - nextchar += my_strlen (nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - /* Can't find it as a long option. If this is not getopt_long_only, - or the option starts with '--' or is not a valid short - option, then it's an error. - Otherwise interpret it as a short option. */ - if (!long_only || argv[optind][1] == '-' -#ifdef GETOPT_COMPAT - || argv[optind][0] == '+' -#endif /* GETOPT_COMPAT */ - || my_index (optstring, *nextchar) == NULL) - { - if (opterr) - { - if (argv[optind][1] == '-') - /* --option */ - fprintf (stderr, "%s: unrecognized option `--%s'\n", - argv[0], nextchar); - else - /* +option or -option */ - fprintf (stderr, "%s: unrecognized option `%c%s'\n", - argv[0], argv[optind][0], nextchar); - } - nextchar = (char *) ""; - optind++; - return BAD_OPTION; - } - } - - /* Look at and handle the next option-character. */ - - { - char c = *nextchar++; - char *temp = my_index (optstring, c); - - /* Increment `optind' when we start to process its last character. */ - if (*nextchar == '\0') - ++optind; - - if (temp == NULL || c == ':') - { - if (opterr) - { -#if 0 - if (c < 040 || c >= 0177) - fprintf (stderr, "%s: unrecognized option, character code 0%o\n", - argv[0], c); - else - fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c); -#else - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c); -#endif - } - optopt = c; - return BAD_OPTION; - } - if (temp[1] == ':') - { - if (temp[2] == ':') - { - /* This is an option that accepts an argument optionally. */ - if (*nextchar != '\0') - { - optarg = nextchar; - optind++; - } - else - optarg = 0; - nextchar = NULL; - } - else - { - /* This is an option that requires an argument. */ - if (*nextchar != '\0') - { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - optind++; - } - else if (optind == argc) - { - if (opterr) - { -#if 0 - fprintf (stderr, "%s: option `-%c' requires an argument\n", - argv[0], c); -#else - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, "%s: option requires an argument -- %c\n", - argv[0], c); -#endif - } - optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = BAD_OPTION; - } - else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - optarg = argv[optind++]; - nextchar = NULL; - } - } - return c; - } -} - -int getopt (int argc, char *const *argv, const char *optstring) { - return _getopt_internal (argc, argv, optstring, - (const struct option *) 0, - (int *) 0, - 0); -} - -int getopt_long(int argc, char *const *argv, const char *options, const struct option *long_options, int *opt_index) { - return _getopt_internal (argc, argv, options, long_options, opt_index, 0); -} - -#endif /* _LIBC or not __GNU_LIBRARY__. */ - -#ifdef TEST - -/* Compile with -DTEST to make an executable for use in testing - the above definition of `getopt'. */ - -int -main (argc, argv) - int argc; - char **argv; -{ - int c; - int digit_optind = 0; - - while (1) - { - int this_option_optind = optind ? optind : 1; - - c = getopt (argc, argv, "abc:d:0123456789"); - if (c == EOF) - break; - - switch (c) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; - - case 'a': - printf ("option a\n"); - break; - - case 'b': - printf ("option b\n"); - break; - - case 'c': - printf ("option c with value `%s'\n", optarg); - break; - - case BAD_OPTION: - break; - - default: - printf ("?? getopt returned character code 0%o ??\n", c); - } - } - - if (optind < argc) - { - printf ("non-option ARGV-elements: "); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - } - - exit (0); -} - -#endif /* TEST */ diff --git a/lib/faad2/frontend/getopt.h b/lib/faad2/frontend/getopt.h deleted file mode 100644 index 3fd12771..00000000 --- a/lib/faad2/frontend/getopt.h +++ /dev/null @@ -1,130 +0,0 @@ -/* Declarations for getopt. - Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef _GETOPT_H -#define _GETOPT_H 1 - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef __MacOSX__ - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -extern char *optarg; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns EOF, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -extern int optind; - -/* Callers store zero here to inhibit the error message `getopt' prints - for unrecognized options. */ - -extern int opterr; - -/* Set to an option character which was unrecognized. */ - -extern int optopt; -#endif - -/* Describe the long-named options requested by the application. - The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector - of `struct option' terminated by an element containing a name which is - zero. - - The field `has_arg' is: - no_argument (or 0) if the option does not take an argument, - required_argument (or 1) if the option requires an argument, - optional_argument (or 2) if the option takes an optional argument. - - If the field `flag' is not NULL, it points to a variable that is set - to the value given in the field `val' when the option is found, but - left unchanged if the option is not found. - - To have a long-named option do something other than set an `int' to - a compiled-in constant, such as set a value from `optarg', set the - option's `flag' field to zero and its `val' field to a nonzero - value (the equivalent single-letter option character, if there is - one). For long options that have a zero `flag' field, `getopt' - returns the contents of the `val' field. */ - -struct option -{ -#if __STDC__ - const char *name; -#else - char *name; -#endif - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; -}; - -/* Names for the values of the `has_arg' field of `struct option'. */ - -#define no_argument 0 -#define required_argument 1 -#define optional_argument 2 - -//#if __STDC__ || defined(PROTO) -#if defined(__GNU_LIBRARY__) -/* Many other libraries have conflicting prototypes for getopt, with - differences in the consts, in stdlib.h. To avoid compilation - errors, only prototype getopt for the GNU C library. */ -extern int getopt (int argc, char *const *argv, const char *shortopts); -#endif /* not __GNU_LIBRARY__ */ -extern int getopt_long (int argc, char *const *argv, const char *shortopts, - const struct option *longopts, int *longind); -extern int getopt_long_only (int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind); - -/* Internal only. Users should not call this directly. */ -extern int _getopt_internal (int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind, - int long_only); -//#else /* not __STDC__ */ -extern int getopt (int argc, char *const *argv, const char *shortopts); -//extern int getopt_long (); -//extern int getopt_long_only (); - -//extern int _getopt_internal (); -//#endif /* not __STDC__ */ - -#ifdef __cplusplus -} -#endif - -#endif /* _GETOPT_H */ diff --git a/lib/faad2/frontend/main.c b/lib/faad2/frontend/main.c deleted file mode 100644 index 6411bb1b..00000000 --- a/lib/faad2/frontend/main.c +++ /dev/null @@ -1,1378 +0,0 @@ -/* -** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding -** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com -** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software -** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -** -** Any non-GPL usage of this software or parts of this software is strictly -** forbidden. -** -** The "appropriate copyright message" mentioned in section 2c of the GPLv2 -** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" -** -** Commercial non-GPL licensing of this software is possible. -** For more info contact Nero AG through Mpeg4AAClicense@nero.com. -** -** $Id: main.c,v 1.89 2015/01/19 09:46:12 knik Exp $ -**/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef _WIN32 -#define _CRT_SECURE_NO_WARNINGS -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#include <io.h> -#ifndef __MINGW32__ -#define off_t __int64 -#endif -#else -#include <time.h> -#endif - -#include <fcntl.h> -#include <stdio.h> -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> -#include <getopt.h> - -#include <neaacdec.h> - -#include "unicode_support.h" -#include "audio.h" -#include "mp4read.h" - -#ifndef min -#define min(a,b) ( (a) < (b) ? (a) : (b) ) -#endif - -#define MAX_CHANNELS 6 /* make this higher to support files with - more channels */ - -#define MAX_PERCENTS 384 - -static int quiet = 0; - -static void faad_fprintf(FILE *stream, const char *fmt, ...) -{ - va_list ap; - - if (!quiet) - { - va_start(ap, fmt); - vfprintf(stream, fmt, ap); - va_end(ap); - } - -#ifdef _WIN32 - if (!_isatty(_fileno(stream))) - { - fflush(stream); /*ensure real-time progress output on Win32*/ - } -#endif -} - -/* FAAD file buffering routines */ -typedef struct { - unsigned long bytes_into_buffer; - unsigned long bytes_consumed; - unsigned long file_offset; - unsigned char *buffer; - FILE *infile; - int at_eof; -} aac_buffer; - - -static int fill_buffer(aac_buffer *b) -{ - unsigned long bread; - - if (b->bytes_consumed > 0) - { - if (b->bytes_into_buffer) - { - memmove((void*)b->buffer, (void*)(b->buffer + b->bytes_consumed), - b->bytes_into_buffer*sizeof(unsigned char)); - } - - if (!b->at_eof) - { - bread = (unsigned long)fread((void*)(b->buffer + b->bytes_into_buffer), 1, - b->bytes_consumed, b->infile); - - if (bread != b->bytes_consumed) - b->at_eof = 1; - - b->bytes_into_buffer += bread; - } - - b->bytes_consumed = 0; - - if (b->bytes_into_buffer > 3) - { - if (memcmp(b->buffer, "TAG", 3) == 0) - b->bytes_into_buffer = 0; - } - if (b->bytes_into_buffer > 11) - { - if (memcmp(b->buffer, "LYRICSBEGIN", 11) == 0) - b->bytes_into_buffer = 0; - } - if (b->bytes_into_buffer > 8) - { - if (memcmp(b->buffer, "APETAGEX", 8) == 0) - b->bytes_into_buffer = 0; - } - } - - return 1; -} - -static void advance_buffer(aac_buffer *b, unsigned int bytes) -{ - while ((b->bytes_into_buffer > 0) && (bytes > 0)) - { - unsigned int chunk = bytes; - if (b->bytes_into_buffer < chunk) - chunk = (unsigned int)b->bytes_into_buffer; - - bytes -= chunk; - b->file_offset += chunk; - b->bytes_consumed = chunk; - b->bytes_into_buffer -= chunk; - - if (b->bytes_into_buffer == 0) - fill_buffer(b); - } -} - -static void lookforheader(aac_buffer *b) -{ - int i = 0; - while (!b->at_eof ) - { - if (b->bytes_into_buffer > 4) - { - if( ((b->buffer[0+i] == 0xff) && ((b->buffer[1+i] & 0xf6) == 0xf0)) || - (b->buffer[0+i] == 'A' && b->buffer[1+i] == 'D' && b->buffer[2+i] == 'I' && b->buffer[3+i] == 'F')) - { - fill_buffer(b); - break; - } else { - i++; - b->file_offset += 1; - b->bytes_consumed += 1; - b->bytes_into_buffer -= 1; - } - } - else - { - fill_buffer(b); - i = 0; - } - } -} - -static int adts_sample_rates[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000,7350,0,0,0}; - -static int adts_parse(aac_buffer *b, int *bitrate, float *length) -{ - size_t frames; - unsigned int frame_length; - size_t t_framelength = 0; - int samplerate = 0; - float frames_per_sec, bytes_per_frame; - - /* Read all frames to ensure correct time and bitrate */ - for (frames = 0; /* */; frames++) - { - fill_buffer(b); - - if (b->bytes_into_buffer > 7) - { - /* check syncword */ - if (!((b->buffer[0] == 0xFF)&&((b->buffer[1] & 0xF6) == 0xF0))) - break; - - if (frames == 0) - samplerate = adts_sample_rates[(b->buffer[2]&0x3c)>>2]; - - frame_length = ((((unsigned int)b->buffer[3] & 0x3)) << 11) - | (((unsigned int)b->buffer[4]) << 3) | (b->buffer[5] >> 5); - if (frame_length == 0) - break; - - t_framelength += frame_length; - - if (frame_length > b->bytes_into_buffer) - break; - - advance_buffer(b, frame_length); - } else { - break; - } - } - - frames_per_sec = (float)samplerate/1024.0f; - if (frames != 0) - bytes_per_frame = (float)t_framelength/(float)(frames*1000); - else - bytes_per_frame = 0; - *bitrate = (int)(8. * bytes_per_frame * frames_per_sec + 0.5); - if (frames_per_sec != 0) - *length = (float)frames/frames_per_sec; - else - *length = 1; - - return 1; -} - -/* MicroSoft channel definitions */ -#define SPEAKER_FRONT_LEFT 0x1 -#define SPEAKER_FRONT_RIGHT 0x2 -#define SPEAKER_FRONT_CENTER 0x4 -#define SPEAKER_LOW_FREQUENCY 0x8 -#define SPEAKER_BACK_LEFT 0x10 -#define SPEAKER_BACK_RIGHT 0x20 -#define SPEAKER_FRONT_LEFT_OF_CENTER 0x40 -#define SPEAKER_FRONT_RIGHT_OF_CENTER 0x80 -#define SPEAKER_BACK_CENTER 0x100 -#define SPEAKER_SIDE_LEFT 0x200 -#define SPEAKER_SIDE_RIGHT 0x400 -#define SPEAKER_TOP_CENTER 0x800 -#define SPEAKER_TOP_FRONT_LEFT 0x1000 -#define SPEAKER_TOP_FRONT_CENTER 0x2000 -#define SPEAKER_TOP_FRONT_RIGHT 0x4000 -#define SPEAKER_TOP_BACK_LEFT 0x8000 -#define SPEAKER_TOP_BACK_CENTER 0x10000 -#define SPEAKER_TOP_BACK_RIGHT 0x20000 -#define SPEAKER_RESERVED 0x80000000 - -static long aacChannelConfig2wavexChannelMask(NeAACDecFrameInfo *hInfo) -{ - if (hInfo->channels == 6 && hInfo->num_lfe_channels) - { - return SPEAKER_FRONT_LEFT + SPEAKER_FRONT_RIGHT + - SPEAKER_FRONT_CENTER + SPEAKER_LOW_FREQUENCY + - SPEAKER_BACK_LEFT + SPEAKER_BACK_RIGHT; - } else { - return 0; - } -} - -static char *position2string(int position) -{ - switch (position) - { - case FRONT_CHANNEL_CENTER: return "Center front"; - case FRONT_CHANNEL_LEFT: return "Left front"; - case FRONT_CHANNEL_RIGHT: return "Right front"; - case SIDE_CHANNEL_LEFT: return "Left side"; - case SIDE_CHANNEL_RIGHT: return "Right side"; - case BACK_CHANNEL_LEFT: return "Left back"; - case BACK_CHANNEL_RIGHT: return "Right back"; - case BACK_CHANNEL_CENTER: return "Center back"; - case LFE_CHANNEL: return "LFE"; - case UNKNOWN_CHANNEL: return "Unknown"; - default: return ""; - } - - // return ""; -} - -static void print_channel_info(NeAACDecFrameInfo *frameInfo) -{ - /* print some channel info */ - int i; - long channelMask = aacChannelConfig2wavexChannelMask(frameInfo); - - faad_fprintf(stderr, " ---------------------\n"); - if (frameInfo->num_lfe_channels > 0) - { - faad_fprintf(stderr, " | Config: %2d.%d Ch |", frameInfo->channels-frameInfo->num_lfe_channels, frameInfo->num_lfe_channels); - } else { - faad_fprintf(stderr, " | Config: %2d Ch |", frameInfo->channels); - } - if (channelMask) - faad_fprintf(stderr, " WARNING: channels are reordered according to\n"); - else - faad_fprintf(stderr, "\n"); - faad_fprintf(stderr, " ---------------------"); - if (channelMask) - faad_fprintf(stderr, " MS defaults defined in WAVE_FORMAT_EXTENSIBLE\n"); - else - faad_fprintf(stderr, "\n"); - faad_fprintf(stderr, " | Ch | Position |\n"); - faad_fprintf(stderr, " ---------------------\n"); - for (i = 0; i < frameInfo->channels; i++) - { - faad_fprintf(stderr, " | %.2d | %-14s |\n", i, position2string((int)frameInfo->channel_position[i])); - } - faad_fprintf(stderr, " ---------------------\n"); - faad_fprintf(stderr, "\n"); -} - -static int FindAdtsSRIndex(int sr) -{ - int i; - - for (i = 0; i < 16; i++) - { - if (sr == adts_sample_rates[i]) - return i; - } - return 16 - 1; -} - -static unsigned char *MakeAdtsHeader(int *dataSize, NeAACDecFrameInfo *hInfo, unsigned char old_format) -{ - unsigned char *data; - int profile = (hInfo->object_type - 1) & 0x3; - int sr_index = ((hInfo->sbr == SBR_UPSAMPLED) || (hInfo->sbr == NO_SBR_UPSAMPLED)) ? - FindAdtsSRIndex(hInfo->samplerate / 2) : FindAdtsSRIndex(hInfo->samplerate); - int skip = (old_format) ? 8 : 7; - int framesize = skip + hInfo->bytesconsumed; - - if (hInfo->header_type == ADTS) - framesize -= skip; - - *dataSize = 7; - - data = malloc(*dataSize * sizeof(unsigned char)); - memset(data, 0, *dataSize * sizeof(unsigned char)); - - data[0] += 0xFF; /* 8b: syncword */ - - data[1] += 0xF0; /* 4b: syncword */ - /* 1b: mpeg id = 0 */ - /* 2b: layer = 0 */ - data[1] += 1; /* 1b: protection absent */ - - data[2] += ((profile << 6) & 0xC0); /* 2b: profile */ - data[2] += ((sr_index << 2) & 0x3C); /* 4b: sampling_frequency_index */ - /* 1b: private = 0 */ - data[2] += ((hInfo->channels >> 2) & 0x1); /* 1b: channel_configuration */ - - data[3] += ((hInfo->channels << 6) & 0xC0); /* 2b: channel_configuration */ - /* 1b: original */ - /* 1b: home */ - /* 1b: copyright_id */ - /* 1b: copyright_id_start */ - data[3] += ((framesize >> 11) & 0x3); /* 2b: aac_frame_length */ - - data[4] += ((framesize >> 3) & 0xFF); /* 8b: aac_frame_length */ - - data[5] += ((framesize << 5) & 0xE0); /* 3b: aac_frame_length */ - data[5] += ((0x7FF >> 6) & 0x1F); /* 5b: adts_buffer_fullness */ - - data[6] += ((0x7FF << 2) & 0x3F); /* 6b: adts_buffer_fullness */ - /* 2b: num_raw_data_blocks */ - - return data; -} - -/* globals */ -char *progName; - -static const char *file_ext[] = -{ - NULL, - ".wav", - ".aif", - ".au", - ".au", - ".pcm", - NULL -}; - -static void usage(void) -{ - faad_fprintf(stdout, "\nUsage:\n"); - faad_fprintf(stdout, "%s [options] infile.aac\n", progName); - faad_fprintf(stdout, "Options:\n"); - faad_fprintf(stdout, " -h Shows this help screen.\n"); - faad_fprintf(stdout, " -i Shows info about the input file.\n"); - faad_fprintf(stdout, " -a X Write MPEG-4 AAC ADTS output file.\n"); - faad_fprintf(stdout, " -t Assume old ADTS format.\n"); - faad_fprintf(stdout, " -o X Set output filename.\n"); - faad_fprintf(stdout, " -f X Set output format. Valid values for X are:\n"); - faad_fprintf(stdout, " 1: Microsoft WAV format (default).\n"); - faad_fprintf(stdout, " 2: RAW PCM data.\n"); - faad_fprintf(stdout, " -b X Set output sample format. Valid values for X are:\n"); - faad_fprintf(stdout, " 1: 16 bit PCM data (default).\n"); - faad_fprintf(stdout, " 2: 24 bit PCM data.\n"); - faad_fprintf(stdout, " 3: 32 bit PCM data.\n"); - faad_fprintf(stdout, " 4: 32 bit floating point data.\n"); - faad_fprintf(stdout, " 5: 64 bit floating point data.\n"); - faad_fprintf(stdout, " -s X Force the samplerate to X (for RAW files).\n"); - faad_fprintf(stdout, " -l X Set object type. Supported object types:\n"); - faad_fprintf(stdout, " 1: Main object type.\n"); - faad_fprintf(stdout, " 2: LC (Low Complexity) object type.\n"); - faad_fprintf(stdout, " 4: LTP (Long Term Prediction) object type.\n"); - faad_fprintf(stdout, " 23: LD (Low Delay) object type.\n"); - faad_fprintf(stdout, " -d Down matrix 5.1 to 2 channels\n"); - faad_fprintf(stdout, " -w Write output to stdio instead of a file.\n"); - faad_fprintf(stdout, " -g Disable gapless decoding.\n"); - faad_fprintf(stdout, " -q Quiet - suppresses status messages.\n"); - faad_fprintf(stdout, " -j X Jump - start output X seconds into track (MP4 files only).\n"); - faad_fprintf(stdout, "Example:\n"); - faad_fprintf(stdout, " %s infile.aac\n", progName); - faad_fprintf(stdout, " %s infile.mp4\n", progName); - faad_fprintf(stdout, " %s -o outfile.wav infile.aac\n", progName); - faad_fprintf(stdout, " %s -w infile.aac > outfile.wav\n", progName); - faad_fprintf(stdout, " %s -a outfile.aac infile.aac\n", progName); - return; -} - -static int decodeAACfile(char *aacfile, char *sndfile, char *adts_fn, int to_stdout, - int def_srate, unsigned char object_type, unsigned char outputFormat, int fileType, - unsigned char downMatrix, int infoOnly, int adts_out, unsigned char old_format, - float *song_length) -{ - int tagsize; - unsigned long samplerate; - unsigned char channels; - void *sample_buffer; - - audio_file *aufile = NULL; - - FILE *adtsFile = NULL; - unsigned char *adtsData; - int adtsDataSize; - - NeAACDecHandle hDecoder; - NeAACDecFrameInfo frameInfo; - NeAACDecConfigurationPtr config; - - char percents[MAX_PERCENTS]; - int percent, old_percent = -1; - int fileread; - unsigned long bread; - long bused; - int header_type = 0; - int bitrate = 0; - float length = 0; - - int first_time = 1; - int retval; - int streaminput = 0; - - aac_buffer b; - - memset(&b, 0, sizeof(aac_buffer)); - - if (adts_out) - { - adtsFile = faad_fopen(adts_fn, "wb"); - if (adtsFile == NULL) - { - faad_fprintf(stderr, "Error opening file: %s\n", adts_fn); - return 1; - } - } - - if (0 == strcmp(aacfile, "-")) - { - b.infile = stdin; -#ifdef _WIN32 - _setmode(_fileno(stdin), O_BINARY); -#endif - - } - else - { - b.infile = faad_fopen(aacfile, "rb"); - if (b.infile == NULL) - { - /* unable to open file */ - faad_fprintf(stderr, "Error opening file: %s\n", aacfile); - return 1; - } - } - - retval = fseek(b.infile, 0, SEEK_END); -#ifdef _WIN32 - if (0 == strcmp(aacfile, "-")) { - retval = -1; - } -#endif - if (retval ) - { - faad_fprintf(stderr, "Input not seekable %s\n", aacfile); - fileread = -1; - streaminput = 1; - } else { - fileread = ftell(b.infile); - fseek(b.infile, 0, SEEK_SET); - }; - - b.buffer = (unsigned char*)malloc(FAAD_MIN_STREAMSIZE*MAX_CHANNELS); - if (!b.buffer) - { - faad_fprintf(stderr, "Memory allocation error\n"); - return 0; - } - memset(b.buffer, 0, FAAD_MIN_STREAMSIZE*MAX_CHANNELS); - - bread = (unsigned long)fread(b.buffer, 1, FAAD_MIN_STREAMSIZE*MAX_CHANNELS, b.infile); - b.bytes_into_buffer = bread; - b.bytes_consumed = 0; - b.file_offset = 0; - - if (bread != FAAD_MIN_STREAMSIZE*MAX_CHANNELS) - b.at_eof = 1; - - tagsize = 0; - if (!memcmp(b.buffer, "ID3", 3)) - { - /* high bit is not used */ - tagsize = (b.buffer[6] << 21) | (b.buffer[7] << 14) | - (b.buffer[8] << 7) | (b.buffer[9] << 0); - - tagsize += 10; - advance_buffer(&b, tagsize); - fill_buffer(&b); - } - - hDecoder = NeAACDecOpen(); - - /* Set the default object type and samplerate */ - /* This is useful for RAW AAC files */ - config = NeAACDecGetCurrentConfiguration(hDecoder); - if (def_srate) - config->defSampleRate = def_srate; - config->defObjectType = object_type; - config->outputFormat = outputFormat; - config->downMatrix = downMatrix; - config->useOldADTSFormat = old_format; - //config->dontUpSampleImplicitSBR = 1; - NeAACDecSetConfiguration(hDecoder, config); - - /* get AAC infos for printing */ - header_type = 0; - if (streaminput == 1) - lookforheader(&b); - - if ((b.buffer[0] == 0xFF) && ((b.buffer[1] & 0xF6) == 0xF0)) - { - if (streaminput == 1) - { - int /*frames,*/ frame_length; - float frames_per_sec, bytes_per_frame; - channels = 2; - samplerate = adts_sample_rates[(b.buffer[2]&0x3c)>>2]; - frame_length = ((((unsigned int)b.buffer[3] & 0x3)) << 11) - | (((unsigned int)b.buffer[4]) << 3) | (b.buffer[5] >> 5); - frames_per_sec = (float)samplerate/1024.0f; - bytes_per_frame = (float)frame_length/(float)(1000); - bitrate = (int)(8. * bytes_per_frame * frames_per_sec + 0.5); - length = 1; - faad_fprintf(stderr, "Streamed input format samplerate %d channels %d.\n", samplerate, channels); - } else { - adts_parse(&b, &bitrate, &length); - fseek(b.infile, tagsize, SEEK_SET); - - bread = (unsigned long)fread(b.buffer, 1, FAAD_MIN_STREAMSIZE*MAX_CHANNELS, b.infile); - if (bread != FAAD_MIN_STREAMSIZE*MAX_CHANNELS) - b.at_eof = 1; - else - b.at_eof = 0; - b.bytes_into_buffer = bread; - b.bytes_consumed = 0; - b.file_offset = tagsize; - } - - header_type = 1; - } - else if (memcmp(b.buffer, "ADIF", 4) == 0) - { - int skip_size = (b.buffer[4] & 0x80) ? 9 : 0; - bitrate = ((unsigned int)(b.buffer[4 + skip_size] & 0x0F)<<19) | - ((unsigned int)b.buffer[5 + skip_size]<<11) | - ((unsigned int)b.buffer[6 + skip_size]<<3) | - ((unsigned int)b.buffer[7 + skip_size] & 0xE0); - - length = (float)fileread; - if (length != 0) - { - length = ((float)length*8.f)/((float)bitrate) + 0.5f; - } - - bitrate = (int)((float)bitrate/1000.0f + 0.5f); - - header_type = 2; - } - - *song_length = length; - - fill_buffer(&b); - bused = NeAACDecInit(hDecoder, b.buffer, b.bytes_into_buffer, &samplerate, &channels); - if (bused < 0) - { - /* If some error initializing occured, skip the file */ - faad_fprintf(stderr, "Error initializing decoder library.\n"); - if (b.buffer) - free(b.buffer); - NeAACDecClose(hDecoder); - if (b.infile != stdin) - fclose(b.infile); - return 1; - } - advance_buffer(&b, bused); - fill_buffer(&b); - - /* print AAC file info */ - faad_fprintf(stderr, "%s file info:\n", aacfile); - switch (header_type) - { - case 0: - faad_fprintf(stderr, "RAW\n\n"); - break; - case 1: - faad_fprintf(stderr, "ADTS, %.3f sec, %d kbps, %d Hz\n\n", - length, bitrate, samplerate); - break; - case 2: - faad_fprintf(stderr, "ADIF, %.3f sec, %d kbps, %d Hz\n\n", - length, bitrate, samplerate); - break; - } - - // Override the logic of skipping 0-th output frame. - NeAACDecPostSeekReset(hDecoder, 1); - - if (infoOnly) - { - NeAACDecClose(hDecoder); - if (b.infile != stdin) - fclose(b.infile); - if (b.buffer) - free(b.buffer); - return 0; - } - - do - { - sample_buffer = NeAACDecDecode(hDecoder, &frameInfo, - b.buffer, b.bytes_into_buffer); - - if (adts_out == 1) - { - int skip = (old_format) ? 8 : 7; - adtsData = MakeAdtsHeader(&adtsDataSize, &frameInfo, old_format); - - /* write the adts header */ - fwrite(adtsData, 1, adtsDataSize, adtsFile); - - /* write the frame data */ - if (frameInfo.header_type == ADTS) - fwrite(b.buffer + skip, 1, frameInfo.bytesconsumed - skip, adtsFile); - else - fwrite(b.buffer, 1, frameInfo.bytesconsumed, adtsFile); - } - - /* update buffer indices */ - advance_buffer(&b, frameInfo.bytesconsumed); - - /* check if the inconsistent number of channels */ - if (aufile != NULL && frameInfo.channels != aufile->channels) - frameInfo.error = 12; - - if (frameInfo.error > 0) - { - faad_fprintf(stderr, "Error: %s\n", - NeAACDecGetErrorMessage(frameInfo.error)); - } - - /* open the sound file now that the number of channels are known */ - if (first_time && !frameInfo.error) - { - /* print some channel info */ - print_channel_info(&frameInfo); - - if (!adts_out) - { - /* open output file */ - if (!to_stdout) - { - aufile = open_audio_file(sndfile, frameInfo.samplerate, frameInfo.channels, - (int)outputFormat, fileType, aacChannelConfig2wavexChannelMask(&frameInfo)); - } else { - aufile = open_audio_file("-", frameInfo.samplerate, frameInfo.channels, - (int)outputFormat, fileType, aacChannelConfig2wavexChannelMask(&frameInfo)); - } - if (aufile == NULL) - { - if (b.buffer) - free(b.buffer); - NeAACDecClose(hDecoder); - if (b.infile != stdin) - fclose(b.infile); - return 0; - } - } else { - faad_fprintf(stderr, "Writing output MPEG-4 AAC ADTS file.\n\n"); - } - first_time = 0; - } - - percent = min((int)(b.file_offset*100)/fileread, 100); - if (percent > old_percent) - { - old_percent = percent; - snprintf(percents, MAX_PERCENTS, "%d%% decoding %s.", percent, aacfile); - faad_fprintf(stderr, "%s\r", percents); -#ifdef _WIN32 - SetConsoleTitle(percents); -#endif - } - - if ((frameInfo.error == 0) && (frameInfo.samples > 0) && (!adts_out)) - { - if (write_audio_file(aufile, sample_buffer, frameInfo.samples) == 0) - break; - } - - /* fill buffer */ - fill_buffer(&b); - - if (b.bytes_into_buffer == 0) - sample_buffer = NULL; /* to make sure it stops now */ - - } while (sample_buffer != NULL); - - NeAACDecClose(hDecoder); - - if (adts_out == 1) - { - fclose(adtsFile); - } - - if (b.infile != stdin) - fclose(b.infile); - - if (!first_time && !adts_out) - close_audio_file(aufile); - - if (b.buffer) - free(b.buffer); - - return frameInfo.error; -} - -static int decodeMP4file(char *mp4file, char *sndfile, char *adts_fn, int to_stdout, - unsigned char outputFormat, int fileType, unsigned char downMatrix, int noGapless, - int infoOnly, int adts_out, float *song_length, float seek_to) -{ - /*int track;*/ - unsigned long samplerate; - unsigned char channels; - void *sample_buffer; - - uint32_t sampleId, startSampleId; - - audio_file *aufile = NULL; - - FILE *adtsFile = NULL; - unsigned char *adtsData; - int adtsDataSize; - - NeAACDecHandle hDecoder; - NeAACDecConfigurationPtr config; - NeAACDecFrameInfo frameInfo = {0}; // should no-frames situation be flagged as an error? - mp4AudioSpecificConfig mp4ASC = {0}; - - char percents[MAX_PERCENTS]; - int percent, old_percent = -1; - - int first_time = 1; - - /* for gapless decoding */ - unsigned int useAacLength = 1; - unsigned int framesize; - unsigned decoded; - - if (strcmp(mp4file, "-") == 0 ) { - faad_fprintf(stderr, "Cannot open stdin for MP4 input \n"); - return 1; - } - - if (!quiet) - { - mp4config.verbose.header = 1; - mp4config.verbose.tags = 1; - } - if (mp4read_open(mp4file)) - { - /* unable to open file */ - faad_fprintf(stderr, "Error opening file: %s\n", mp4file); - return 1; - } - - hDecoder = NeAACDecOpen(); - - /* Set configuration */ - config = NeAACDecGetCurrentConfiguration(hDecoder); - config->outputFormat = outputFormat; - config->downMatrix = downMatrix; - //config->dontUpSampleImplicitSBR = 1; - NeAACDecSetConfiguration(hDecoder, config); - - if (adts_out) - { - adtsFile = faad_fopen(adts_fn, "wb"); - if (adtsFile == NULL) - { - faad_fprintf(stderr, "Error opening file: %s\n", adts_fn); - return 1; - } - } - - if(NeAACDecInit2(hDecoder, mp4config.asc.buf, mp4config.asc.size, - &samplerate, &channels) < 0) - { - /* If some error initializing occured, skip the file */ - faad_fprintf(stderr, "Error initializing decoder library.\n"); - NeAACDecClose(hDecoder); - mp4read_close(); - return 1; - } - - framesize = 1024; - useAacLength = 0; - decoded = 0; - - if (mp4config.asc.size) - { - if (NeAACDecAudioSpecificConfig(mp4config.asc.buf, mp4config.asc.size, &mp4ASC) >= 0) - { - if (mp4ASC.frameLengthFlag == 1) framesize = 960; - if (mp4ASC.sbr_present_flag == 1 || mp4ASC.forceUpSampling) framesize *= 2; - } - } - - /* print some mp4 file info */ - faad_fprintf(stderr, "%s file info:\n\n", mp4file); - { - /*int k, j;*/ - char *ot[6] = { "NULL", "MAIN AAC", "LC AAC", "SSR AAC", "LTP AAC", "HE AAC" }; - float seconds; - seconds = (float)mp4config.samples/(float)mp4ASC.samplingFrequency; - - *song_length = seconds; - - faad_fprintf(stderr, "%s\t%.3f secs, %d ch, %d Hz\n\n", ot[(mp4ASC.objectTypeIndex > 5)?0:mp4ASC.objectTypeIndex], - seconds, mp4ASC.channelsConfiguration, mp4ASC.samplingFrequency); - } - - if (infoOnly) - { - NeAACDecClose(hDecoder); - mp4read_close(); - return 0; - } - - startSampleId = 0; - if (seek_to > 0.1) { - int64_t sample = (int64_t)(seek_to * mp4config.samplerate / framesize); - uint32_t limit = ~0u; - startSampleId = sample < limit ? (uint32_t)sample : limit; - } - - mp4read_seek(startSampleId); - for (sampleId = startSampleId; sampleId < mp4config.frame.nsamples; sampleId++) - { - /*int rc;*/ - unsigned long dur; - unsigned int sample_count; - - if (mp4read_frame()) - break; - - sample_buffer = NeAACDecDecode(hDecoder, &frameInfo, mp4config.bitbuf.data, mp4config.bitbuf.size); - - if (!sample_buffer) { - /* unable to decode file, abort */ - break; - } - - if (adts_out == 1) - { - adtsData = MakeAdtsHeader(&adtsDataSize, &frameInfo, 0); - - /* write the adts header */ - fwrite(adtsData, 1, adtsDataSize, adtsFile); - - fwrite(mp4config.bitbuf.data, 1, frameInfo.bytesconsumed, adtsFile); - } - - dur = frameInfo.samples / frameInfo.channels; - decoded += dur; - - if (decoded > mp4config.samples) - dur += mp4config.samples - decoded; - - if (dur > framesize) - { - faad_fprintf(stderr, "Warning: excess frame detected in MP4 file.\n"); - dur = framesize; - } - - if (!noGapless) - { - if (useAacLength || (mp4config.samplerate != samplerate)) { - sample_count = frameInfo.samples; - } else { - sample_count = (unsigned int)(dur * frameInfo.channels); - if (sample_count > frameInfo.samples) - sample_count = frameInfo.samples; - } - } else { - sample_count = frameInfo.samples; - } - - /* open the sound file now that the number of channels are known */ - if (first_time && !frameInfo.error) - { - /* print some channel info */ - print_channel_info(&frameInfo); - - if (!adts_out) - { - /* open output file */ - if(!to_stdout) - { - aufile = open_audio_file(sndfile, frameInfo.samplerate, frameInfo.channels, - (int)outputFormat, fileType, aacChannelConfig2wavexChannelMask(&frameInfo)); - } else { -#ifdef _WIN32 - _setmode(_fileno(stdout), O_BINARY); -#endif - aufile = open_audio_file("-", frameInfo.samplerate, frameInfo.channels, - (int)outputFormat, fileType, aacChannelConfig2wavexChannelMask(&frameInfo)); - } - if (aufile == NULL) - { - NeAACDecClose(hDecoder); - mp4read_close(); - return 0; - } - } - first_time = 0; - } - - percent = min((int)(sampleId*100)/mp4config.frame.nsamples, 100); - if (percent > old_percent) - { - old_percent = percent; - snprintf(percents, MAX_PERCENTS, "%d%% decoding %s.", percent, mp4file); - faad_fprintf(stderr, "%s\r", percents); -#ifdef _WIN32 - SetConsoleTitle(percents); -#endif - } - - if ((frameInfo.error == 0) && (sample_count > 0) && (!adts_out)) - { - if (write_audio_file(aufile, sample_buffer, sample_count) == 0) - break; - } - - if (frameInfo.error > 0) - { - faad_fprintf(stderr, "Warning: %s\n", - NeAACDecGetErrorMessage(frameInfo.error)); - } - } - - NeAACDecClose(hDecoder); - - if (adts_out == 1) - { - fclose(adtsFile); - } - - mp4read_close(); - - if (!first_time && !adts_out) - close_audio_file(aufile); - - return frameInfo.error; -} - -static int faad_main(int argc, char *argv[]) -{ - int result; - int infoOnly = 0; - int writeToStdio = 0; - int readFromStdin = 0; - unsigned char object_type = LC; - int def_srate = 0; - unsigned char downMatrix = 0; - int format = 1; - unsigned char outputFormat = FAAD_FMT_16BIT; - int outfile_set = 0; - int adts_out = 0; - unsigned char old_format = 0; - int showHelp = 0; - int mp4file = 0; - int noGapless = 0; - char *fnp; - char *aacFileName = NULL; - char *audioFileName = NULL; - char *adtsFileName = NULL; - float seekTo = 0; - unsigned char header[8]; - size_t bread; - float length = 0; - FILE *hMP4File; - char *faad_id_string; - char *faad_copyright_string; - -/* System dependant types */ -#ifdef _WIN32 - long begin; -#else - clock_t begin; -#endif - - unsigned long cap = NeAACDecGetCapabilities(); - - - /* begin process command line */ - progName = argv[0]; - while (1) { - int c = -1; - int option_index = 0; - static struct option long_options[] = { - { "quiet", 0, 0, 'q' }, - { "outfile", 0, 0, 'o' }, - { "adtsout", 0, 0, 'a' }, - { "oldformat", 0, 0, 't' }, - { "format", 0, 0, 'f' }, - { "bits", 0, 0, 'b' }, - { "samplerate", 0, 0, 's' }, - { "objecttype", 0, 0, 'l' }, - { "downmix", 0, 0, 'd' }, - { "info", 0, 0, 'i' }, - { "stdio", 0, 0, 'w' }, - { "stdio", 0, 0, 'g' }, - { "seek", 1, 0, 'j' }, - { "help", 0, 0, 'h' }, - { 0, 0, 0, 0 } - }; - - c = getopt_long(argc, argv, "o:a:s:f:b:l:j:wgdhitq", - long_options, &option_index); - - if (c == -1) - break; - - switch (c) { - case 'o': - if (optarg) - { - outfile_set = 1; - audioFileName = (char *) malloc(sizeof(char) * (strlen(optarg) + 1)); - if (audioFileName == NULL) - { - faad_fprintf(stderr, "Error allocating memory for audioFileName.\n"); - return 1; - } - strcpy(audioFileName, optarg); - } - break; - case 'a': - if (optarg) - { - adts_out = 1; - adtsFileName = (char *) malloc(sizeof(char) * (strlen(optarg) + 1)); - if (adtsFileName == NULL) - { - faad_fprintf(stderr, "Error allocating memory for adtsFileName.\n"); - return 1; - } - strcpy(adtsFileName, optarg); - } - break; - case 's': - if (optarg) - { - char dr[10]; - if (sscanf(optarg, "%s", dr) < 1) { - def_srate = 0; - } else { - def_srate = atoi(dr); - } - } - break; - case 'f': - if (optarg) - { - char dr[10]; - if (sscanf(optarg, "%s", dr) < 1) - { - format = 1; - } else { - format = atoi(dr); - if ((format < 1) || (format > 2)) - showHelp = 1; - } - } - break; - case 'b': - if (optarg) - { - char dr[10]; - if (sscanf(optarg, "%s", dr) < 1) - { - outputFormat = FAAD_FMT_16BIT; /* just use default */ - } else { - int val = atoi(dr); - if ((val < 1) || (val > 5)) - showHelp = 1; - if (val == 5) // Not yet unsupported by "audio". - showHelp = 1; - outputFormat = (unsigned char)val; - } - } - break; - case 'l': - if (optarg) - { - char dr[10]; - if (sscanf(optarg, "%s", dr) < 1) - { - object_type = LC; /* default */ - } else { - int val = atoi(dr); - if ((val != LC) && - (val != MAIN) && - (val != LTP) && - (val != LD)) - { - showHelp = 1; - } - object_type = (unsigned char)val; - } - } - break; - case 'j': - if (optarg) - { - seekTo = (float)atof(optarg); - } - break; - case 't': - old_format = 1; - break; - case 'd': - downMatrix = 1; - break; - case 'w': - writeToStdio = 1; - break; - case 'g': - noGapless = 1; - break; - case 'i': - infoOnly = 1; - break; - case 'h': - showHelp = 1; - break; - case 'q': - quiet = 1; - break; - default: - break; - } - } - - NeAACDecGetVersion(&faad_id_string, &faad_copyright_string); - - faad_fprintf(stderr, " *********** Ahead Software MPEG-4 AAC Decoder V%s ******************\n\n", faad_id_string); -#ifndef BUILD_DATE -#define BUILD_DATE __DATE__ -#endif - faad_fprintf(stderr, " Build: %s\n", BUILD_DATE); -#undef BUILD_DATE - faad_fprintf(stderr, "%s", faad_copyright_string); - if (cap & FIXED_POINT_CAP) - faad_fprintf(stderr, " Fixed point version\n"); - else - faad_fprintf(stderr, " Floating point version\n"); - faad_fprintf(stderr, "\n"); - faad_fprintf(stderr, " This program is free software; you can redistribute it and/or modify\n"); - faad_fprintf(stderr, " it under the terms of the GNU General Public License.\n"); - faad_fprintf(stderr, "\n"); - faad_fprintf(stderr, " **************************************************************************\n\n"); - - - /* check that we have at least two non-option arguments */ - /* Print help if requested */ - if (((argc - optind) < 1) || showHelp) - { - usage(); - return 1; - } - -#if 0 - /* only allow raw data on stdio */ - if (writeToStdio == 1) - { - format = 2; - } -#endif - - /* point to the specified file name */ - aacFileName = (char *) malloc(sizeof(char) * (strlen(argv[optind]) + 1)); - if (aacFileName == NULL) - { - faad_fprintf(stderr, "Error allocating memory for aacFileName.\n"); - return 1; - } - strcpy(aacFileName, argv[optind]); - -#ifdef _WIN32 - begin = GetTickCount(); -#else - begin = clock(); -#endif - - /* Only calculate the path and open the file for writing if - we are not writing to stdout. - */ - if(!writeToStdio && !outfile_set) - { - audioFileName = (char *) malloc(sizeof(char) * (strlen(aacFileName) + strlen(file_ext[format]) + 1)); - if (audioFileName == NULL) - { - faad_fprintf(stderr, "Error allocating memory for audioFileName.\n"); - return 1; - } - strcpy(audioFileName, aacFileName); - - fnp = (char *)strrchr(audioFileName,'.'); - - if (fnp) - fnp[0] = '\0'; - - strcat(audioFileName, file_ext[format]); - } - - /* check for mp4 file */ - if (0 == strcmp(aacFileName, "-")) { - faad_fprintf(stderr, "Reading from stdin: %s\n", aacFileName); - readFromStdin = 1; - hMP4File = stdin; -#ifdef _WIN32 - _setmode(_fileno(stdin), O_BINARY); -#endif - - } else { - - mp4file = 0; - hMP4File = faad_fopen(aacFileName, "rb"); - if (!hMP4File) - { - faad_fprintf(stderr, "Error opening file: %s\n", aacFileName); - return 1; - } - } - - bread = fread(header, 1, 8, hMP4File); - - if (! readFromStdin ) - fclose(hMP4File); - - if (bread != 8) { - faad_fprintf(stderr, "Error reading file.\n"); - return 1; - } - - if (header[4] == 'f' && header[5] == 't' && header[6] == 'y' && header[7] == 'p') - mp4file = 1; - - if (!mp4file && seekTo != 0) { - faad_fprintf(stderr, "Warning: can only seek in MP4 files\n"); - } - - if (mp4file) - { - result = decodeMP4file(aacFileName, audioFileName, adtsFileName, writeToStdio, - outputFormat, format, downMatrix, noGapless, infoOnly, adts_out, &length, seekTo); - } else { - - if (readFromStdin == 1) { - ungetc(header[7],hMP4File); - ungetc(header[6],hMP4File); - ungetc(header[5],hMP4File); - ungetc(header[4],hMP4File); - ungetc(header[3],hMP4File); - ungetc(header[2],hMP4File); - ungetc(header[1],hMP4File); - ungetc(header[0],hMP4File); - } - - result = decodeAACfile(aacFileName, audioFileName, adtsFileName, writeToStdio, - def_srate, object_type, outputFormat, format, downMatrix, infoOnly, adts_out, - old_format, &length); - } - - if (audioFileName != NULL) - free (audioFileName); - if (adtsFileName != NULL) - free (adtsFileName); - - if (!result && !infoOnly) - { -#ifdef _WIN32 - float dec_length = (float)(GetTickCount()-begin)/1000.0f; - SetConsoleTitle("FAAD"); -#else - /* clock() grabs time since the start of the app but when we decode - multiple files, each file has its own starttime (begin). - */ - float dec_length = (float)(clock() - begin)/(float)CLOCKS_PER_SEC; -#endif - faad_fprintf(stderr, "Decoding %s took: %5.2f sec. %5.2fx real-time.\n", aacFileName, - dec_length, (dec_length > 0.01) ? (length/dec_length) : 0.); - } - - free (aacFileName); - return 0; -} - -int main(int argc, char *argv[]) -{ -#if defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64 - int argc_utf8, exit_code; - char **argv_utf8; - (void)argc; - (void)argv; - init_console_utf8(stderr); - init_commandline_arguments_utf8(&argc_utf8, &argv_utf8); - exit_code = faad_main(argc_utf8, argv_utf8); - free_commandline_arguments_utf8(&argc_utf8, &argv_utf8); - uninit_console_utf8(); - return exit_code; -#else - return faad_main(argc, argv); -#endif -} diff --git a/lib/faad2/frontend/mp4read.c b/lib/faad2/frontend/mp4read.c deleted file mode 100644 index a157d7d6..00000000 --- a/lib/faad2/frontend/mp4read.c +++ /dev/null @@ -1,1109 +0,0 @@ -/**************************************************************************** - MP4 input module - - Copyright (C) 2017 Krzysztof Nikiel - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -****************************************************************************/ - -#define _CRT_SECURE_NO_WARNINGS - -#include <stdlib.h> -#include <stdio.h> -#include <stdint.h> -#include <string.h> -#include <time.h> -#include <limits.h> - -#include "unicode_support.h" -#include "mp4read.h" - -enum ATOM_TYPE -{ - ATOM_STOP = 0 /* end of atoms */ , - ATOM_NAME /* plain atom */ , - ATOM_DESCENT, /* starts group of children */ - ATOM_ASCENT, /* ends group */ - ATOM_DATA, -}; - -typedef int (*parse_t)(int); - -typedef struct -{ - uint16_t opcode; - const char *name; - parse_t parse; -} creator_t; - -#define STOP() {ATOM_STOP, NULL, NULL} -#define NAME(N) {ATOM_NAME, N, NULL} -#define DESCENT() {ATOM_DESCENT, NULL, NULL} -#define ASCENT() {ATOM_ASCENT, NULL, NULL} -#define DATA(N, F) {ATOM_NAME, N, NULL}, {ATOM_DATA, NULL, F} - -mp4config_t mp4config = { 0 }; - -static FILE *g_fin = NULL; - -enum {ERR_OK = 0, ERR_FAIL = -1, ERR_UNSUPPORTED = -2}; - -#define freeMem(A) if (*(A)) {free(*(A)); *(A) = NULL;} - -static size_t datain(void *data, size_t size) -{ - return fread(data, 1, size, g_fin); -} - -static int stringin(char *txt, int sizemax) -{ - int size; - for (size = 0; size < sizemax; size++) - { - if (fread(txt + size, 1, 1, g_fin) != 1) - return ERR_FAIL; - if (!txt[size]) - break; - } - txt[sizemax-1] = '\0'; - - return size; -} - -static uint32_t u32in(void) -{ - uint8_t u8[4]; - datain(&u8, 4); - return (uint32_t)u8[3] | ((uint32_t)u8[2] << 8) | ((uint32_t)u8[1] << 16) | ((uint32_t)u8[0] << 24); -} - -static uint16_t u16in(void) -{ - uint8_t u8[2]; - datain(&u8, 2); - return (uint16_t)u8[1] | ((uint16_t)u8[0] << 8); -} - -static int u8in(void) -{ - uint8_t u8; - datain(&u8, 1); - return u8; -} - -static int ftypin(int size) -{ - enum {BUFSIZE = 40}; - char buf[BUFSIZE]; - uint32_t u32; - - buf[4] = 0; - datain(buf, 4); - u32 = u32in(); - - if (mp4config.verbose.header) - fprintf(stderr, "Brand:\t\t\t%s(version %d)\n", buf, u32); - - stringin(buf, BUFSIZE); - - if (mp4config.verbose.header) - fprintf(stderr, "Compatible brands:\t%s\n", buf); - - return size; -} - -enum -{ SECSINDAY = 24 * 60 * 60 }; -static char *mp4time(time_t t) -{ - int y; - - // subtract some seconds from the start of 1904 to the start of 1970 - for (y = 1904; y < 1970; y++) - { - t -= 365 * SECSINDAY; - if (!(y & 3)) - t -= SECSINDAY; - } - return ctime(&t); -} - -static int mdhdin(int size) -{ - // version/flags - u32in(); - // Creation time - mp4config.ctime = u32in(); - // Modification time - mp4config.mtime = u32in(); - // Time scale - mp4config.samplerate = u32in(); - // Duration - mp4config.samples = u32in(); - // Language - u16in(); - // pre_defined - u16in(); - - return size; -} - -static int hdlr1in(int size) -{ - uint8_t buf[5]; - - buf[4] = 0; - // version/flags - u32in(); - // pre_defined - u32in(); - // Component subtype - datain(buf, 4); - if (mp4config.verbose.header) - fprintf(stderr, "*track media type: '%s': ", buf); - if (memcmp("soun", buf, 4)) - { - if (mp4config.verbose.header) - fprintf(stderr, "unsupported, skipping\n"); - return ERR_UNSUPPORTED; - } - else - { - if (mp4config.verbose.header) - fprintf(stderr, "OK\n"); - } - // reserved - u32in(); - u32in(); - u32in(); - // name - // null terminate - u8in(); - - return size; -} - -static int stsdin(int size) -{ - // version/flags - u32in(); - // Number of entries(one 'mp4a') - if (u32in() != 1) //fixme: error handling - return ERR_FAIL; - - return size; -} - -static int mp4ain(int size) -{ - // Reserved (6 bytes) - u32in(); - u16in(); - // Data reference index - u16in(); - // Version - u16in(); - // Revision level - u16in(); - // Vendor - u32in(); - // Number of channels - mp4config.channels = u16in(); - // Sample size (bits) - mp4config.bits = u16in(); - // Compression ID - u16in(); - // Packet size - u16in(); - // Sample rate (16.16) - // fractional framerate, probably not for audio - // rate integer part - u16in(); - // rate reminder part - u16in(); - - return size; -} - - -static uint32_t getsize(void) -{ - int cnt; - uint32_t size = 0; - for (cnt = 0; cnt < 4; cnt++) - { - int tmp = u8in(); - - size <<= 7; - size |= (tmp & 0x7f); - if (!(tmp & 0x80)) - break; - } - return size; -} - -static int esdsin(int size) -{ - // descriptor tree: - // MP4ES_Descriptor - // MP4DecoderConfigDescriptor - // MP4DecSpecificInfoDescriptor - // MP4SLConfigDescriptor - enum - { TAG_ES = 3, TAG_DC = 4, TAG_DSI = 5, TAG_SLC = 6 }; - - // version/flags - u32in(); - if (u8in() != TAG_ES) - return ERR_FAIL; - getsize(); - // ESID - u16in(); - // flags(url(bit 6); ocr(5); streamPriority (0-4)): - u8in(); - - if (u8in() != TAG_DC) - return ERR_FAIL; - getsize(); - if (u8in() != 0x40) /* not MPEG-4 audio */ - return ERR_FAIL; - // flags - u8in(); - // buffer size (24 bits) - mp4config.buffersize = u16in() << 8; - mp4config.buffersize |= u8in(); - // bitrate - mp4config.bitratemax = u32in(); - mp4config.bitrateavg = u32in(); - - if (u8in() != TAG_DSI) - return ERR_FAIL; - mp4config.asc.size = getsize(); - if (mp4config.asc.size > sizeof(mp4config.asc.buf)) - return ERR_FAIL; - // get AudioSpecificConfig - datain(mp4config.asc.buf, mp4config.asc.size); - - if (u8in() != TAG_SLC) - return ERR_FAIL; - getsize(); - // "predefined" (no idea) - u8in(); - - return size; -} - -/* stbl "Sample Table" layout: - * - stts "Time-to-Sample" - useless - * - stsc "Sample-to-Chunk" - condensed table chunk-to-num-samples - * - stsz "Sample Size" - size table - * - stco "Chunk Offset" - chunk starts - * - * When receiving stco we can combine stsc and stsz tables to produce final - * sample offsets. - */ - -static int sttsin(int size) -{ - uint32_t ntts; - - if (size < 8) - return ERR_FAIL; - - // version/flags - u32in(); - ntts = u32in(); - - if (ntts < 1) - return ERR_FAIL; - - /* 2 x uint32_t per entry */ - if (((size - 8u) / 8u) < ntts) - return ERR_FAIL; - - return size; -} - -static int stscin(int size) -{ - uint32_t i, tmp, firstchunk, prevfirstchunk, samplesperchunk; - - if (size < 8) - return ERR_FAIL; - - // version/flags - u32in(); - - mp4config.frame.nsclices = u32in(); - - tmp = sizeof(slice_info_t) * mp4config.frame.nsclices; - if (tmp < mp4config.frame.nsclices) - return ERR_FAIL; - mp4config.frame.map = malloc(tmp); - if (!mp4config.frame.map) - return ERR_FAIL; - - /* 3 x uint32_t per entry */ - if (((size - 8u) / 12u) < mp4config.frame.nsclices) - return ERR_FAIL; - - prevfirstchunk = 0; - for (i = 0; i < mp4config.frame.nsclices; ++i) { - firstchunk = u32in(); - samplesperchunk = u32in(); - // id - unused - u32in(); - if (firstchunk <= prevfirstchunk) - return ERR_FAIL; - if (samplesperchunk < 1) - return ERR_FAIL; - mp4config.frame.map[i].firstchunk = firstchunk; - mp4config.frame.map[i].samplesperchunk = samplesperchunk; - prevfirstchunk = firstchunk; - } - - return size; -} - -static int stszin(int size) -{ - uint32_t i, tmp; - - if (size < 12) - return ERR_FAIL; - - // version/flags - u32in(); - // (uniform) Sample size - // TODO(eustas): add uniform sample size support? - u32in(); - mp4config.frame.nsamples = u32in(); - - if (!mp4config.frame.nsamples) - return ERR_FAIL; - - tmp = sizeof(frame_info_t) * mp4config.frame.nsamples; - if (tmp < mp4config.frame.nsamples) - return ERR_FAIL; - mp4config.frame.info = malloc(tmp); - if (!mp4config.frame.info) - return ERR_FAIL; - - if ((size - 12u) / 4u < mp4config.frame.nsamples) - return ERR_FAIL; - - for (i = 0; i < mp4config.frame.nsamples; i++) - { - mp4config.frame.info[i].len = u32in(); - mp4config.frame.info[i].offset = 0; - if (mp4config.frame.maxsize < mp4config.frame.info[i].len) - mp4config.frame.maxsize = mp4config.frame.info[i].len; - } - - return size; -} - -static int stcoin(int size) -{ - uint32_t numchunks, chunkn, slicen, samplesleft, i, offset; - uint32_t nextoffset; - - if (size < 8) - return ERR_FAIL; - - // version/flags - u32in(); - - // Number of entries - numchunks = u32in(); - if ((numchunks < 1) || ((numchunks + 1) == 0)) - return ERR_FAIL; - - if ((size - 8u) / 4u < numchunks) - return ERR_FAIL; - - chunkn = 0; - samplesleft = 0; - slicen = 0; - offset = 0; - - for (i = 0; i < mp4config.frame.nsamples; ++i) { - if (samplesleft == 0) - { - chunkn++; - if (chunkn > numchunks) - return ERR_FAIL; - if (slicen < mp4config.frame.nsclices && - (slicen + 1) < mp4config.frame.nsclices) { - if (chunkn == mp4config.frame.map[slicen + 1].firstchunk) - slicen++; - } - samplesleft = mp4config.frame.map[slicen].samplesperchunk; - offset = u32in(); - } - mp4config.frame.info[i].offset = offset; - nextoffset = offset + mp4config.frame.info[i].len; - if (nextoffset < offset) - return ERR_FAIL; - offset = nextoffset; - samplesleft--; - } - - freeMem(&mp4config.frame.map); - - return size; -} - -#if 0 -static int tagtxt(char *tagname, const char *tagtxt) -{ - //int txtsize = strlen(tagtxt); - int size = 0; - //int datasize = txtsize + 16; - -#if 0 - size += u32out(datasize + 8); - size += dataout(tagname, 4); - size += u32out(datasize); - size += dataout("data", 4); - size += u32out(1); - size += u32out(0); - size += dataout(tagtxt, txtsize); -#endif - - return size; -} - -static int tagu32(char *tagname, int n /*number of stored fields*/) -{ - //int numsize = n * 4; - int size = 0; - //int datasize = numsize + 16; - -#if 0 - size += u32out(datasize + 8); - size += dataout(tagname, 4); - size += u32out(datasize); - size += dataout("data", 4); - size += u32out(0); - size += u32out(0); -#endif - - return size; -} -#endif - -static int metain(int size) -{ - (void)size; /* why not used? */ - // version/flags - u32in(); - - return ERR_OK; -} - -static int hdlr2in(int size) -{ - uint8_t buf[4]; - - // version/flags - u32in(); - // Predefined - u32in(); - // Handler type - datain(buf, 4); - if (memcmp(buf, "mdir", 4)) - return ERR_FAIL; - datain(buf, 4); - if (memcmp(buf, "appl", 4)) - return ERR_FAIL; - // Reserved - u32in(); - u32in(); - // null terminator - u8in(); - - return size; -} - -static int ilstin(int size) -{ - enum {NUMSET = 1, GENRE, EXTAG}; - int read = 0; - - static struct { - char *name; - char *id; - int flag; - } tags[] = { - {"Album ", "\xa9" "alb"}, - {"Album Artist", "aART"}, - {"Artist ", "\xa9" "ART"}, - {"Comment ", "\xa9" "cmt"}, - {"Cover image ", "covr"}, - {"Compilation ", "cpil"}, - {"Copyright ", "cprt"}, - {"Date ", "\xa9" "day"}, - {"Disc# ", "disk", NUMSET}, - {"Genre ", "gnre", GENRE}, - {"Grouping ", "\xa9" "grp"}, - {"Lyrics ", "\xa9" "lyr"}, - {"Title ", "\xa9" "nam"}, - {"Rating ", "rtng"}, - {"BPM ", "tmpo"}, - {"Encoder ", "\xa9" "too"}, - {"Track ", "trkn", NUMSET}, - {"Composer ", "\xa9" "wrt"}, - {0, "----", EXTAG}, - {0}, - }; - - static const char *genres[] = { - "Blues", "Classic Rock", "Country", "Dance", - "Disco", "Funk", "Grunge", "Hip-Hop", - "Jazz", "Metal", "New Age", "Oldies", - "Other", "Pop", "R&B", "Rap", - "Reggae", "Rock", "Techno", "Industrial", - "Alternative", "Ska", "Death Metal", "Pranks", - "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", - "Vocal", "Jazz+Funk", "Fusion", "Trance", - "Classical", "Instrumental", "Acid", "House", - "Game", "Sound Clip", "Gospel", "Noise", - "Alternative Rock", "Bass", "Soul", "Punk", - "Space", "Meditative", "Instrumental Pop", "Instrumental Rock", - "Ethnic", "Gothic", "Darkwave", "Techno-Industrial", - "Electronic", "Pop-Folk", "Eurodance", "Dream", - "Southern Rock", "Comedy", "Cult", "Gangsta", - "Top 40", "Christian Rap", "Pop/Funk", "Jungle", - "Native US", "Cabaret", "New Wave", "Psychadelic", - "Rave", "Showtunes", "Trailer", "Lo-Fi", - "Tribal", "Acid Punk", "Acid Jazz", "Polka", - "Retro", "Musical", "Rock & Roll", "Hard Rock", - "Folk", "Folk-Rock", "National Folk", "Swing", - "Fast Fusion", "Bebob", "Latin", "Revival", - "Celtic", "Bluegrass", "Avantgarde", "Gothic Rock", - "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock", - "Big Band", "Chorus", "Easy Listening", "Acoustic", - "Humour", "Speech", "Chanson", "Opera", - "Chamber Music", "Sonata", "Symphony", "Booty Bass", - "Primus", "Porn Groove", "Satire", "Slow Jam", - "Club", "Tango", "Samba", "Folklore", - "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle", - "Duet", "Punk Rock", "Drum Solo", "Acapella", - "Euro-House", "Dance Hall", "Goa", "Drum & Bass", - "Club - House", "Hardcore", "Terror", "Indie", - "BritPop", "Negerpunk", "Polsk Punk", "Beat", - "Christian Gangsta Rap", "Heavy Metal", "Black Metal", "Crossover", - "Contemporary Christian", "Christian Rock", "Merengue", "Salsa", - "Thrash Metal", "Anime", "JPop", "Synthpop", - "Unknown", - }; - - fprintf(stderr, "----------tag list-------------\n"); - while(read < size) - { - int asize, dsize; - uint8_t id[5]; - int cnt; - uint32_t type; - - id[4] = 0; - - asize = u32in(); - read += asize; - asize -= 4; - if (datain(id, 4) < 4) - return ERR_FAIL; - asize -= 4; - - for (cnt = 0; tags[cnt].id; cnt++) - { - if (!memcmp(id, tags[cnt].id, 4)) - break; - } - - if (tags[cnt].name) - fprintf(stderr, "%s : ", tags[cnt].name); - else - { - if (tags[cnt].flag != EXTAG) - fprintf(stderr, "'%s' : ", id); - } - - dsize = u32in(); - asize -= 4; - if (datain(id, 4) < 4) - return ERR_FAIL; - asize -= 4; - - if (tags[cnt].flag != EXTAG) - { - if (memcmp(id, "data", 4)) - return ERR_FAIL; - } - else - { - int spc; - - if (memcmp(id, "mean", 4)) - goto skip; - dsize -= 8; - while (dsize > 0) - { - u8in(); - asize--; - dsize--; - } - if (asize >= 8) - { - dsize = u32in() - 8; - asize -= 4; - if (datain(id, 4) < 4) - return ERR_FAIL; - asize -= 4; - if (memcmp(id, "name", 4)) - goto skip; - u32in(); - asize -= 4; - dsize -= 4; - } - spc = 13 - dsize; - if (spc < 0) spc = 0; - while (dsize > 0) - { - fprintf(stderr, "%c",u8in()); - asize--; - dsize--; - } - while (spc--) - fprintf(stderr, " "); - fprintf(stderr, ": "); - if (asize >= 8) - { - dsize = u32in() - 8; - asize -= 4; - if (datain(id, 4) < 4) - return ERR_FAIL; - asize -= 4; - if (memcmp(id, "data", 4)) - goto skip; - u32in(); - asize -= 4; - dsize -= 4; - } - while (dsize > 0) - { - fprintf(stderr, "%c",u8in()); - asize--; - dsize--; - } - fprintf(stderr, "\n"); - - goto skip; - } - type = u32in(); - asize -= 4; - u32in(); - asize -= 4; - - switch(type) - { - case 1: - while (asize > 0) - { - fprintf(stderr, "%c",u8in()); - asize--; - } - break; - case 0: - switch(tags[cnt].flag) - { - case NUMSET: - u16in(); - asize -= 2; - - fprintf(stderr, "%d", u16in()); - asize -= 2; - fprintf(stderr, "/%d", u16in()); - asize -= 2; - break; - case GENRE: - { - uint16_t gnum = u16in(); - asize -= 2; - if (!gnum) - goto skip; - gnum--; - if (gnum >= 147) - gnum = 147; - fprintf(stderr, "%s", genres[gnum]); - } - break; - default: - while(asize > 0) - { - fprintf(stderr, "%d/", u16in()); - asize-=2; - } - } - break; - case 0x15: - //fprintf(stderr, "(8bit data)"); - while(asize > 0) - { - fprintf(stderr, "%d", u8in()); - asize--; - if (asize) - fprintf(stderr, "/"); - } - break; - case 0xd: - fprintf(stderr, "(image data)"); - break; - default: - fprintf(stderr, "(unknown data type)"); - break; - } - fprintf(stderr, "\n"); - - skip: - // skip to the end of atom - while (asize > 0) - { - u8in(); - asize--; - } - } - fprintf(stderr, "-------------------------------\n"); - - return size; -} - -static creator_t *g_atom = 0; -static int parse(uint32_t *sizemax) -{ - long apos = 0; - long aposmax = ftell(g_fin) + *sizemax; - uint32_t size; - - if (g_atom->opcode != ATOM_NAME) - { - fprintf(stderr, "parse error: root is not a 'name' opcode\n"); - return ERR_FAIL; - } - //fprintf(stderr, "looking for '%s'\n", (char *)g_atom->name); - - // search for atom in the file - while (1) - { - char name[4]; - uint32_t tmp; - - apos = ftell(g_fin); - if (apos >= (aposmax - 8)) - { - fprintf(stderr, "parse error: atom '%s' not found\n", g_atom->name); - return ERR_FAIL; - } - if ((tmp = u32in()) < 8) - { - fprintf(stderr, "invalid atom size %x @%lx\n", tmp, ftell(g_fin)); - return ERR_FAIL; - } - - size = tmp; - if (datain(name, 4) != 4) - { - // EOF - fprintf(stderr, "can't read atom name @%lx\n", ftell(g_fin)); - return ERR_FAIL; - } - - //fprintf(stderr, "atom: '%c%c%c%c'(%x)", name[0],name[1],name[2],name[3], size); - - if (!memcmp(name, g_atom->name, 4)) - { - //fprintf(stderr, "OK\n"); - break; - } - //fprintf(stderr, "\n"); - - fseek(g_fin, apos + size, SEEK_SET); - } - *sizemax = size; - g_atom++; - if (g_atom->opcode == ATOM_DATA) - { - int err = g_atom->parse(size - 8); - if (err < ERR_OK) - { - fseek(g_fin, apos + size, SEEK_SET); - return err; - } - g_atom++; - } - if (g_atom->opcode == ATOM_DESCENT) - { - long apos2 = ftell(g_fin); - - //fprintf(stderr, "descent\n"); - g_atom++; - while (g_atom->opcode != ATOM_STOP) - { - uint32_t subsize = size - 8; - int ret; - if (g_atom->opcode == ATOM_ASCENT) - { - g_atom++; - break; - } - // TODO: does not feel well - we always return to the same point! - fseek(g_fin, apos2, SEEK_SET); - if ((ret = parse(&subsize)) < 0) - return ret; - } - //fprintf(stderr, "ascent\n"); - } - - fseek(g_fin, apos + size, SEEK_SET); - - return ERR_OK; -} - -static int moovin(int sizemax) -{ - long apos = ftell(g_fin); - uint32_t atomsize; - creator_t *old_atom = g_atom; - int err, ret = sizemax; - - static creator_t mvhd[] = { - NAME("mvhd"), - STOP() - }; - static creator_t trak[] = { - NAME("trak"), - DESCENT(), - NAME("tkhd"), - NAME("mdia"), - DESCENT(), - DATA("mdhd", mdhdin), - DATA("hdlr", hdlr1in), - NAME("minf"), - DESCENT(), - NAME("smhd"), - NAME("dinf"), - NAME("stbl"), - DESCENT(), - DATA("stsd", stsdin), - DESCENT(), - DATA("mp4a", mp4ain), - DESCENT(), - DATA("esds", esdsin), - ASCENT(), - ASCENT(), - DATA("stts", sttsin), - DATA("stsc", stscin), - DATA("stsz", stszin), - DATA("stco", stcoin), - STOP() - }; - - g_atom = mvhd; - atomsize = sizemax + apos - ftell(g_fin); - if (parse(&atomsize) < 0) { - g_atom = old_atom; - return ERR_FAIL; - } - - fseek(g_fin, apos, SEEK_SET); - - while (1) - { - //fprintf(stderr, "TRAK\n"); - g_atom = trak; - atomsize = sizemax + apos - ftell(g_fin); - if (atomsize < 8) - break; - //fprintf(stderr, "PARSE(%x)\n", atomsize); - err = parse(&atomsize); - //fprintf(stderr, "SIZE: %x/%x\n", atomsize, sizemax); - if (err >= 0) - break; - if (err != ERR_UNSUPPORTED) { - ret = err; - break; - } - //fprintf(stderr, "UNSUPP\n"); - } - - g_atom = old_atom; - return ret; -} - - -static creator_t g_head[] = { - DATA("ftyp", ftypin), - STOP() -}; - -static creator_t g_moov[] = { - DATA("moov", moovin), - //DESCENT(), - //NAME("mvhd"), - STOP() -}; - -static creator_t g_meta1[] = { - NAME("moov"), - DESCENT(), - NAME("udta"), - DESCENT(), - DATA("meta", metain), - DESCENT(), - DATA("hdlr", hdlr2in), - DATA("ilst", ilstin), - STOP() -}; - -static creator_t g_meta2[] = { - DATA("meta", metain), - DESCENT(), - DATA("hdlr", hdlr2in), - DATA("ilst", ilstin), - STOP() -}; - - -int mp4read_frame(void) -{ - if (mp4config.frame.current >= mp4config.frame.nsamples) - return ERR_FAIL; - - // TODO(eustas): avoid no-op seeks - mp4read_seek(mp4config.frame.current); - - mp4config.bitbuf.size = mp4config.frame.info[mp4config.frame.current].len; - - if (fread(mp4config.bitbuf.data, 1, mp4config.bitbuf.size, g_fin) - != mp4config.bitbuf.size) - { - fprintf(stderr, "can't read frame data(frame %d@0x%x)\n", - mp4config.frame.current, - mp4config.frame.info[mp4config.frame.current].offset); - - return ERR_FAIL; - } - - mp4config.frame.current++; - - return ERR_OK; -} - -int mp4read_seek(uint32_t framenum) -{ - if (framenum > mp4config.frame.nsamples) - return ERR_FAIL; - if (fseek(g_fin, mp4config.frame.info[framenum].offset, SEEK_SET)) - return ERR_FAIL; - - mp4config.frame.current = framenum; - - return ERR_OK; -} - -static void mp4info(void) -{ - fprintf(stderr, "Modification Time:\t\t%s\n", mp4time(mp4config.mtime)); - fprintf(stderr, "Samplerate:\t\t%d\n", mp4config.samplerate); - fprintf(stderr, "Total samples:\t\t%d\n", mp4config.samples); - fprintf(stderr, "Total channels:\t\t%d\n", mp4config.channels); - fprintf(stderr, "Bits per sample:\t%d\n", mp4config.bits); - fprintf(stderr, "Buffer size:\t\t%d\n", mp4config.buffersize); - fprintf(stderr, "Max bitrate:\t\t%d\n", mp4config.bitratemax); - fprintf(stderr, "Average bitrate:\t%d\n", mp4config.bitrateavg); - fprintf(stderr, "Frames:\t\t\t%d\n", mp4config.frame.nsamples); - fprintf(stderr, "ASC size:\t\t%d\n", mp4config.asc.size); - fprintf(stderr, "Duration:\t\t%.1f sec\n", (float)mp4config.samples/mp4config.samplerate); - if (mp4config.frame.nsamples) - fprintf(stderr, "Data offset:\t%x\n", mp4config.frame.info[0].offset); -} - -int mp4read_close(void) -{ - freeMem(&mp4config.frame.info); - freeMem(&mp4config.frame.map); - freeMem(&mp4config.bitbuf.data); - - return ERR_OK; -} - -int mp4read_open(char *name) -{ - uint32_t atomsize; - int ret; - - mp4read_close(); - - g_fin = faad_fopen(name, "rb"); - if (!g_fin) - return ERR_FAIL; - - if (mp4config.verbose.header) - fprintf(stderr, "**** MP4 header ****\n"); - g_atom = g_head; - atomsize = INT_MAX; - if (parse(&atomsize) < 0) - goto err; - g_atom = g_moov; - atomsize = INT_MAX; - rewind(g_fin); - if ((ret = parse(&atomsize)) < 0) - { - fprintf(stderr, "parse:%d\n", ret); - goto err; - } - - // alloc frame buffer - mp4config.bitbuf.data = malloc(mp4config.frame.maxsize); - - if (!mp4config.bitbuf.data) - goto err; - - if (mp4config.verbose.header) - { - mp4info(); - fprintf(stderr, "********************\n"); - } - - if (mp4config.verbose.tags) - { - rewind(g_fin); - g_atom = g_meta1; - atomsize = INT_MAX; - ret = parse(&atomsize); - if (ret < 0) - { - rewind(g_fin); - g_atom = g_meta2; - atomsize = INT_MAX; - ret = parse(&atomsize); - } - } - - return ERR_OK; -err: - mp4read_close(); - return ERR_FAIL; -} diff --git a/lib/faad2/frontend/mp4read.h b/lib/faad2/frontend/mp4read.h deleted file mode 100644 index e7b9f141..00000000 --- a/lib/faad2/frontend/mp4read.h +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** - MP4 input module - - Copyright (C) 2017 Krzysztof Nikiel - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -****************************************************************************/ - -#include <stdint.h> - -typedef struct -{ - uint32_t len; - uint32_t offset; -} frame_info_t; - -typedef struct -{ - uint32_t firstchunk; - uint32_t samplesperchunk; -} slice_info_t; - -typedef struct -{ - uint32_t ctime, mtime; - uint32_t samplerate; - // total sound samples - uint32_t samples; - uint32_t channels; - // sample depth - uint32_t bits; - // buffer config - uint32_t buffersize; - uint32_t bitratemax; - uint32_t bitrateavg; - // frame size / offsets - struct - { - frame_info_t *info; - slice_info_t *map; - uint32_t nsamples; - uint32_t nsclices; - uint32_t current; - uint32_t maxsize; - } frame; - // AudioSpecificConfig data: - struct - { - uint8_t buf[10]; - uint32_t size; - } asc; - struct { - uint32_t size; - uint8_t *data; - } bitbuf; - struct { - int header; - int tags; - } verbose; -} mp4config_t; - -extern mp4config_t mp4config; - -int mp4read_open(char *name); -int mp4read_seek(uint32_t framenum); -int mp4read_frame(void); -int mp4read_close(void); diff --git a/lib/faad2/frontend/unicode_support.c b/lib/faad2/frontend/unicode_support.c deleted file mode 100644 index d3f50ac6..00000000 --- a/lib/faad2/frontend/unicode_support.c +++ /dev/null @@ -1,172 +0,0 @@ -/* Copyright (c) 2004-2012 LoRd_MuldeR <mulder2@gmx.de> - File: unicode_support.c - - This file was originally part of a patch included with LameXP, - released under the same license as the original audio tools. - - 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. - - 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 FOUNDATION 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. -*/ - -#define _CRT_SECURE_NO_WARNINGS -#include <stdio.h> - -#if defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64 - -#include "unicode_support.h" - -#include <stdlib.h> - -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#include <shellapi.h> -#include <io.h> - -static UINT g_old_output_cp = ((UINT)-1); - -static char *utf16_to_utf8(const wchar_t *input) -{ - char *Buffer; - int BuffSize = 0, Result = 0; - - BuffSize = WideCharToMultiByte(CP_UTF8, 0, input, -1, NULL, 0, NULL, NULL); - Buffer = (char*) malloc(sizeof(char) * BuffSize); - if(Buffer) - { - Result = WideCharToMultiByte(CP_UTF8, 0, input, -1, Buffer, BuffSize, NULL, NULL); - } - - return ((Result > 0) && (Result <= BuffSize)) ? Buffer : NULL; -} - -static wchar_t *utf8_to_utf16(const char *input) -{ - wchar_t *Buffer; - int BuffSize = 0, Result = 0; - - BuffSize = MultiByteToWideChar(CP_UTF8, 0, input, -1, NULL, 0); - Buffer = (wchar_t*) malloc(sizeof(wchar_t) * BuffSize); - if(Buffer) - { - Result = MultiByteToWideChar(CP_UTF8, 0, input, -1, Buffer, BuffSize); - } - - return ((Result > 0) && (Result <= BuffSize)) ? Buffer : NULL; -} - -void init_commandline_arguments_utf8(int *argc, char ***argv) -{ - int i, nArgs; - LPWSTR *szArglist; - - szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs); - - if(NULL == szArglist) - { - fprintf(stderr, "\nFATAL: CommandLineToArgvW failed\n\n"); - exit(-1); - } - - *argv = (char**) malloc(sizeof(char*) * nArgs); - *argc = nArgs; - - if(NULL == *argv) - { - fprintf(stderr, "\nFATAL: Malloc failed\n\n"); - exit(-1); - } - - for(i = 0; i < nArgs; i++) - { - (*argv)[i] = utf16_to_utf8(szArglist[i]); - if(NULL == (*argv)[i]) - { - fprintf(stderr, "\nFATAL: utf16_to_utf8 failed\n\n"); - exit(-1); - } - } - - LocalFree(szArglist); -} - -void free_commandline_arguments_utf8(int *argc, char ***argv) -{ - int i = 0; - - if(*argv != NULL) - { - for(i = 0; i < *argc; i++) - { - if((*argv)[i] != NULL) - { - free((*argv)[i]); - (*argv)[i] = NULL; - } - } - free(*argv); - *argv = NULL; - } -} - -FILE *faad_fopen(const char *filename, const char *mode) -{ - FILE *ret = NULL; - wchar_t *filename_utf16 = utf8_to_utf16(filename); - wchar_t *mode_utf16 = utf8_to_utf16(mode); - - if(filename_utf16 && mode_utf16) - { - ret = _wfopen(filename_utf16, mode_utf16); - } - - if(filename_utf16) free(filename_utf16); - if(mode_utf16) free(mode_utf16); - - return ret; -} - -void init_console_utf8(FILE *const stream) -{ - if (_isatty(_fileno(stream))) - { - g_old_output_cp = GetConsoleOutputCP(); - SetConsoleOutputCP(CP_UTF8); - } -} - -void uninit_console_utf8(void) -{ - if(g_old_output_cp != ((UINT)-1)) - { - SetConsoleOutputCP(g_old_output_cp); - } -} - -#else - -FILE *faad_fopen(const char *filename, const char *mode) -{ - return fopen(filename, mode); -} - -#endif diff --git a/lib/faad2/frontend/unicode_support.h b/lib/faad2/frontend/unicode_support.h deleted file mode 100644 index 07dacc93..00000000 --- a/lib/faad2/frontend/unicode_support.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (c) 2004-2012 LoRd_MuldeR <mulder2@gmx.de> - File: unicode_support.h - - This file was originally part of a patch included with LameXP, - released under the same license as the original audio tools. - - 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. - - 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 FOUNDATION 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. -*/ -#ifndef UNICODE_SUPPORT_H_INCLUDED -#define UNICODE_SUPPORT_H_INCLUDED - -#include <stdio.h> - -#if defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64 -void init_commandline_arguments_utf8(int *argc, char ***argv); -void free_commandline_arguments_utf8(int *argc, char ***argv); -void init_console_utf8(FILE *const stream); -void uninit_console_utf8(void); -#endif - -FILE *faad_fopen(const char *filename, const char *mode); - -#endif //UNICODE_SUPPORT_H_INCLUDED |
