Sigrid Solveig Haflínudóttirfix warnings6bc6a9b3 years agoHistory
1361 lines · 42.6 KB · C
RawDownload
/* Implements the public API for using libSoX file formats. * All public functions & data are prefixed with sox_ . * * (c) 2005-8 Chris Bagwell and SoX contributors * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or (at * your option) any later version. * * This library 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 Lesser * General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA */ #define _GNU_SOURCE#include "sox_i.h" #include <assert.h>#include <ctype.h>#include <errno.h>#include <fcntl.h>#include <stdlib.h>#include <string.h>#include <sys/stat.h>#include <sys/types.h> #ifdef HAVE_IO_H  #include <io.h>#endif #if HAVE_MAGIC  #include <magic.h>#endif #ifdef HAVE_UNISTD_H#  include <unistd.h>#endif #define PIPE_AUTO_DETECT_SIZE 256 /* Only as much as we can rewind a pipe */#define AUTO_DETECT_SIZE 4096     /* For seekable file, so no restriction */ static char const * auto_detect_format(sox_format_t * ft, char const * ext){  char data[AUTO_DETECT_SIZE];  size_t len = lsx_readbuf(ft, data, ft->seekable? sizeof(data) : PIPE_AUTO_DETECT_SIZE);  #define CHECK(type, p2, l2, d2, p1, l1, d1) if (len >= p1 + l1 && \      !memcmp(data + p1, d1, (size_t)l1) && !memcmp(data + p2, d2, (size_t)l2)) return #type;  CHECK(voc   , 0, 0, ""     , 0, 20, "Creative Voice File\x1a")  CHECK(smp   , 0, 0, ""     , 0, 17, "SOUND SAMPLE DATA")  CHECK(wve   , 0, 0, ""     , 0, 15, "ALawSoundFile**")  CHECK(gsrt  , 0, 0, ""     , 16, 9, "ring.bin")  CHECK(amr-wb, 0, 0, ""     , 0,  9, "#!AMR-WB\n")  CHECK(prc   , 0, 0, ""     , 0,  8, "\x37\x00\x00\x10\x6d\x00\x00\x10")  CHECK(sph   , 0, 0, ""     , 0,  7, "NIST_1A")  CHECK(amr-nb, 0, 0, ""     , 0,  6, "#!AMR\n")  CHECK(txw   , 0, 0, ""     , 0,  6, "LM8953")  CHECK(sndt  , 0, 0, ""     , 0,  6, "SOUND\x1a")  CHECK(vorbis, 0, 4, "OggS" , 29, 6, "vorbis")  CHECK(opus  , 0, 4, "OggS" , 28, 8, "OpusHead")  CHECK(speex , 0, 4, "OggS" , 28, 6, "Speex")  CHECK(hcom  ,65, 4, "FSSD" , 128,4, "HCOM")  CHECK(wav   , 0, 4, "RIFF" , 8,  4, "WAVE")  CHECK(wav   , 0, 4, "RIFX" , 8,  4, "WAVE")  CHECK(wav   , 0, 4, "RF64" , 8,  4, "WAVE")  CHECK(aiff  , 0, 4, "FORM" , 8,  4, "AIFF")  CHECK(aifc  , 0, 4, "FORM" , 8,  4, "AIFC")  CHECK(8svx  , 0, 4, "FORM" , 8,  4, "8SVX")  CHECK(maud  , 0, 4, "FORM" , 8,  4, "MAUD")  CHECK(xa    , 0, 0, ""     , 0,  4, "XA\0\0")  CHECK(xa    , 0, 0, ""     , 0,  4, "XAI\0")  CHECK(xa    , 0, 0, ""     , 0,  4, "XAJ\0")  CHECK(au    , 0, 0, ""     , 0,  4, ".snd")  CHECK(au    , 0, 0, ""     , 0,  4, "dns.")  CHECK(au    , 0, 0, ""     , 0,  4, "\0ds.")  CHECK(au    , 0, 0, ""     , 0,  4, ".sd\0")  CHECK(flac  , 0, 0, ""     , 0,  4, "fLaC")  CHECK(avr   , 0, 0, ""     , 0,  4, "2BIT")  CHECK(caf   , 0, 0, ""     , 0,  4, "caff")  CHECK(wv    , 0, 0, ""     , 0,  4, "wvpk")  CHECK(paf   , 0, 0, ""     , 0,  4, " paf")  CHECK(sf    , 0, 0, ""     , 0,  4, "\144\243\001\0")  CHECK(sf    , 0, 0, ""     , 0,  4, "\0\001\243\144")  CHECK(sf    , 0, 0, ""     , 0,  4, "\144\243\002\0")  CHECK(sf    , 0, 0, ""     , 0,  4, "\0\002\243\144")  CHECK(sf    , 0, 0, ""     , 0,  4, "\144\243\003\0")  CHECK(sf    , 0, 0, ""     , 0,  4, "\0\003\243\144")  CHECK(sf    , 0, 0, ""     , 0,  4, "\144\243\004\0")  CHECK(sox   , 0, 0, ""     , 0,  4, ".SoX")  CHECK(sox   , 0, 0, ""     , 0,  4, "XoS.")   if (ext && !strcasecmp(ext, "snd"))  CHECK(sndr  , 7, 1, ""     , 0,  2, "\0")  #undef CHECK #if HAVE_MAGIC  if (sox_globals.use_magic) {    static magic_t magic;    char const * filetype = NULL;    if (!magic) {      magic = magic_open(MAGIC_MIME | MAGIC_SYMLINK);      if (magic)        magic_load(magic, NULL);    }    if (magic)      filetype = magic_buffer(magic, data, len);    if (filetype && strncmp(filetype, "application/octet-stream", (size_t)24) &&          !lsx_strends(filetype, "/unknown") &&          strncmp(filetype, "text/plain", (size_t)10) )      return filetype;    else if (filetype)      lsx_debug("libmagic detected %s", filetype);  }#endif  return NULL;} static sox_encodings_info_t const s_sox_encodings_info[] = {  {sox_encodings_none  , "n/a"          , "Unknown or not applicable"},  {sox_encodings_none  , "Signed PCM"   , "Signed Integer PCM"},  {sox_encodings_none  , "Unsigned PCM" , "Unsigned Integer PCM"},  {sox_encodings_none  , "F.P. PCM"     , "Floating Point PCM"},  {sox_encodings_none  , "F.P. PCM"     , "Floating Point (text) PCM"},  {sox_encodings_none  , "FLAC"         , "FLAC"},  {sox_encodings_none  , "HCOM"         , "HCOM"},  {sox_encodings_none  , "WavPack"      , "WavPack"},  {sox_encodings_none  , "F.P. WavPack" , "Floating Point WavPack"},  {sox_encodings_lossy1, "u-law"        , "u-law"},  {sox_encodings_lossy1, "A-law"        , "A-law"},  {sox_encodings_lossy1, "G.721 ADPCM"  , "G.721 ADPCM"},  {sox_encodings_lossy1, "G.723 ADPCM"  , "G.723 ADPCM"},  {sox_encodings_lossy1, "CL ADPCM (8)" , "CL ADPCM (from 8-bit)"},  {sox_encodings_lossy1, "CL ADPCM (16)", "CL ADPCM (from 16-bit)"},  {sox_encodings_lossy1, "MS ADPCM"     , "MS ADPCM"},  {sox_encodings_lossy1, "IMA ADPCM"    , "IMA ADPCM"},  {sox_encodings_lossy1, "OKI ADPCM"    , "OKI ADPCM"},  {sox_encodings_lossy1, "DPCM"         , "DPCM"},  {sox_encodings_none  , "DWVW"         , "DWVW"},  {sox_encodings_none  , "DWVWN"        , "DWVWN"},  {sox_encodings_lossy2, "GSM"          , "GSM"},  {sox_encodings_lossy2, "MPEG audio"   , "MPEG audio (layer I, II or III)"},  {sox_encodings_lossy2, "Vorbis"       , "Vorbis"},  {sox_encodings_lossy2, "AMR-WB"       , "AMR-WB"},  {sox_encodings_lossy2, "AMR-NB"       , "AMR-NB"},  {sox_encodings_lossy2, "CVSD"         , "CVSD"},  {sox_encodings_lossy2, "LPC10"        , "LPC10"},  {sox_encodings_lossy2, "Opus"         , "Opus"},}; assert_static(array_length(s_sox_encodings_info) == SOX_ENCODINGS,    SIZE_MISMATCH_BETWEEN_sox_encoding_t_AND_sox_encodings_info); sox_encodings_info_t const *sox_get_encodings_info(void){    return s_sox_encodings_info;} unsigned sox_precision(sox_encoding_t encoding, unsigned bits_per_sample){  switch (encoding) {    case SOX_ENCODING_DWVW:       return bits_per_sample;    case SOX_ENCODING_DWVWN:      return !bits_per_sample? 16: 0; /* ? */    case SOX_ENCODING_HCOM:       return !(bits_per_sample & 7) && (bits_per_sample >> 3) - 1 < 1? bits_per_sample: 0;    case SOX_ENCODING_WAVPACK:    case SOX_ENCODING_FLAC:       return !(bits_per_sample & 7) && (bits_per_sample >> 3) - 1 < 4? bits_per_sample: 0;    case SOX_ENCODING_SIGN2:      return bits_per_sample <= 32? bits_per_sample : 0;    case SOX_ENCODING_UNSIGNED:   return !(bits_per_sample & 7) && (bits_per_sample >> 3) - 1 < 4? bits_per_sample: 0;     case SOX_ENCODING_ALAW:       return bits_per_sample == 8? 13: 0;    case SOX_ENCODING_ULAW:       return bits_per_sample == 8? 14: 0;     case SOX_ENCODING_CL_ADPCM:   return bits_per_sample? 8: 0;    case SOX_ENCODING_CL_ADPCM16: return bits_per_sample == 4? 13: 0;    case SOX_ENCODING_MS_ADPCM:   return bits_per_sample == 4? 14: 0;    case SOX_ENCODING_IMA_ADPCM:  return bits_per_sample == 4? 13: 0;    case SOX_ENCODING_OKI_ADPCM:  return bits_per_sample == 4? 12: 0;    case SOX_ENCODING_G721:       return bits_per_sample == 4? 12: 0;    case SOX_ENCODING_G723:       return bits_per_sample == 3? 8:                                         bits_per_sample == 5? 14: 0;    case SOX_ENCODING_CVSD:       return bits_per_sample == 1? 16: 0;    case SOX_ENCODING_DPCM:       return bits_per_sample; /* ? */     case SOX_ENCODING_MP3:        return 0; /* Accept the precision returned by the format. */     case SOX_ENCODING_GSM:    case SOX_ENCODING_VORBIS:    case SOX_ENCODING_OPUS:    case SOX_ENCODING_AMR_WB:    case SOX_ENCODING_AMR_NB:    case SOX_ENCODING_LPC10:      return !bits_per_sample? 16: 0;     case SOX_ENCODING_WAVPACKF:    case SOX_ENCODING_FLOAT:      return bits_per_sample == 32 ? 25: bits_per_sample == 64 ? 54: 0;    case SOX_ENCODING_FLOAT_TEXT: return !bits_per_sample? 54: 0;     case SOX_ENCODINGS:    case SOX_ENCODING_UNKNOWN:    break;  }  return 0;} void sox_init_encodinginfo(sox_encodinginfo_t * e){  e->reverse_bytes = sox_option_default;  e->reverse_nibbles = sox_option_default;  e->reverse_bits = sox_option_default;  e->compression = HUGE_VAL;} /*--------------------------------- Comments ---------------------------------*/ size_t sox_num_comments(sox_comments_t comments){  size_t result = 0;  if (!comments)    return 0;  while (*comments++)    ++result;  return result;} void sox_append_comment(sox_comments_t * comments, char const * comment){  size_t n = sox_num_comments(*comments);  *comments = lsx_realloc(*comments, (n + 2) * sizeof(**comments));  assert(comment);  (*comments)[n++] = lsx_strdup(comment);  (*comments)[n] = 0;} void sox_append_comments(sox_comments_t * comments, char const * comment){  char * end;  if (comment) {    while ((end = strchr(comment, '\n'))) {      size_t len = end - comment;      char * c = lsx_malloc((len + 1) * sizeof(*c));      strncpy(c, comment, len);      c[len] = '\0';      sox_append_comment(comments, c);      comment += len + 1;      free(c);    }    if (*comment)      sox_append_comment(comments, comment);  }} sox_comments_t sox_copy_comments(sox_comments_t comments){  sox_comments_t result = 0;   if (comments) while (*comments)    sox_append_comment(&result, *comments++);  return result;} void sox_delete_comments(sox_comments_t * comments){  sox_comments_t p = *comments;   if (p) while (*p)    free(*p++);  free(*comments);  *comments = 0;} char * lsx_cat_comments(sox_comments_t comments){  sox_comments_t p = comments;  size_t len = 0;  char * result;   if (p) while (*p)    len += strlen(*p++) + 1;   result = lsx_calloc(len? len : 1, sizeof(*result));   if ((p = comments) && *p) {    strcpy(result, *p);    while (*++p)      strcat(strcat(result, "\n"), *p);  }  return result;} char const * sox_find_comment(sox_comments_t comments, char const * id){  size_t len = strlen(id);   if (comments) for (;*comments; ++comments)    if (!strncasecmp(*comments, id, len) && (*comments)[len] == '=')      return *comments + len + 1;  return NULL;} static void set_endiannesses(sox_format_t * ft){  if (ft->handler.flags & SOX_FILE_ENDIAN) {    sox_bool file_is_bigendian = !(ft->handler.flags & SOX_FILE_ENDBIG);     if (ft->encoding.opposite_endian) {      ft->encoding.reverse_bytes = file_is_bigendian != MACHINE_IS_BIGENDIAN;      lsx_report("`%s': overriding file-type byte-order", ft->filename);    } else if (ft->encoding.reverse_bytes == sox_option_default) {      ft->encoding.reverse_bytes = file_is_bigendian == MACHINE_IS_BIGENDIAN;    }  } else {    if (ft->encoding.opposite_endian) {      ft->encoding.reverse_bytes = sox_option_yes;      lsx_report("`%s': overriding machine byte-order", ft->filename);    } else if (ft->encoding.reverse_bytes == sox_option_default) {      ft->encoding.reverse_bytes = sox_option_no;    }  }   /* FIXME: Change reports to suitable warnings if trying   * to override something that can't be overridden. */   if (ft->encoding.reverse_bits == sox_option_default)    ft->encoding.reverse_bits = !!(ft->handler.flags & SOX_FILE_BIT_REV);  else if (ft->encoding.reverse_bits == !(ft->handler.flags & SOX_FILE_BIT_REV))      lsx_report("`%s': overriding file-type bit-order", ft->filename);   if (ft->encoding.reverse_nibbles == sox_option_default)    ft->encoding.reverse_nibbles = !!(ft->handler.flags & SOX_FILE_NIB_REV);  else    if (ft->encoding.reverse_nibbles == !(ft->handler.flags & SOX_FILE_NIB_REV))      lsx_report("`%s': overriding file-type nibble-order", ft->filename);} static sox_bool is_seekable(sox_format_t const * ft){  assert(ft);  if (!ft->fp)    return sox_false;   return !fseek(ft->fp, 0, SEEK_CUR);} /* check that all settings have been given */static int sox_checkformat(sox_format_t * ft){  ft->sox_errno = SOX_SUCCESS;   if (ft->signal.rate <= 0) {    lsx_fail_errno(ft, SOX_EFMT, "sample rate zero or negative");    return SOX_EOF;  }  if (!ft->signal.precision) {    lsx_fail_errno(ft,SOX_EFMT,"data encoding or sample size was not specified");    return SOX_EOF;  }  return SOX_SUCCESS;} static sox_bool is_url(char const * text) /* detects only wget-supported URLs */{  return !(      strncasecmp(text, "http:" , (size_t)5) &&      strncasecmp(text, "https:", (size_t)6) &&      strncasecmp(text, "ftp:"  , (size_t)4));} static int xfclose(FILE * file, lsx_io_type io_type){#ifndef HAVE_POPEN  USED(io_type);#endif  return#ifdef HAVE_POPEN    io_type != lsx_io_file? pclose(file) :#endif    fclose(file);} static void incr_pipe_size(FILE *f){/* * Linux 2.6.35 and later has the ability to expand the pipe buffer * Try to get it as big as possible to avoid stalls when SoX itself * is using big buffers */#if defined(F_GETPIPE_SZ) && defined(F_SETPIPE_SZ)  static long max_pipe_size;   /* read the maximum size of the pipe the first time this is called */  if (max_pipe_size == 0) {    const char path[] = "/proc/sys/fs/pipe-max-size";    int fd = open(path, O_RDONLY);     max_pipe_size = -1;    if (fd >= 0) {      char buf[80];      ssize_t r = read(fd, buf, sizeof(buf) - 1);       if (r > 0) {        buf[r] = 0;        max_pipe_size = strtol(buf, NULL, 10);         /* guard against obviously wrong values on messed up systems */        if (max_pipe_size <= PIPE_BUF || max_pipe_size > INT_MAX)          max_pipe_size = -1;      }      close(fd);    }  }   if (max_pipe_size > PIPE_BUF) {    int fd = fileno(f);     if (fcntl(fd, F_SETPIPE_SZ, max_pipe_size) >= 0)      lsx_debug("got pipe %ld bytes\n", max_pipe_size);    else      lsx_warn("couldn't set pipe size to %ld bytes: %s\n",               max_pipe_size, strerror(errno));  }#else  USED(f);#endif /* do nothing for platforms without F_{GET,SET}PIPE_SZ */} static FILE * xfopen(char const * identifier, char const * mode, lsx_io_type * io_type){  *io_type = lsx_io_file;   if (*identifier == '|') {    FILE * f = NULL;#ifdef HAVE_POPEN#ifndef POPEN_MODE#define POPEN_MODE "r"#endif    f = popen(identifier + 1, POPEN_MODE);    *io_type = lsx_io_pipe;    incr_pipe_size(f);#else    lsx_fail("this build of SoX cannot open pipes");#endif    return f;  }  else if (is_url(identifier)) {    FILE * f = NULL;#ifdef HAVE_POPEN    char const * const command_format = "wget --no-check-certificate -q -O- \"%s\"";    char * command = lsx_malloc(strlen(command_format) + strlen(identifier));    sprintf(command, command_format, identifier);    f = popen(command, POPEN_MODE);    incr_pipe_size(f);    free(command);    *io_type = lsx_io_url;#else    lsx_fail("this build of SoX cannot open URLs");#endif    return f;  }  return fopen(identifier, mode);} /* Hack to rewind pipes (a small amount). * Works by resetting the FILE buffer pointer */static void UNUSED rewind_pipe(FILE * fp){/* _FSTDIO is for Torek stdio (i.e. most BSD-derived libc's) * In theory, we no longer need to check _NEWLIB_VERSION or __APPLE__ */#if defined _FSTDIO || defined _NEWLIB_VERSION || defined __APPLE__  fp->_p -= PIPE_AUTO_DETECT_SIZE;  fp->_r += PIPE_AUTO_DETECT_SIZE;#elif defined __GLIBC__  fp->_IO_read_ptr = fp->_IO_read_base;#elif defined _MSC_VER && _MSC_VER >= 1900  #define NO_REWIND_PIPE#elif defined _MSC_VER || defined _WIN32 || defined _WIN64 || \      defined _ISO_STDIO_ISO_H || defined __sgi  fp->_ptr = fp->_base;#elif defined NO_REWIND_PIPE  USED(fp);#else  /* To fix this #error, either simply remove the #error line and live without   * file-type detection with pipes, or add support for your compiler in the   * lines above.  Test with cat monkey.wav | ./sox --info - */  #error FIX NEEDED HERE  #define NO_REWIND_PIPE  USED(fp);#endif} static sox_format_t * open_read(    char               const * path,    void                     * buffer UNUSED,    size_t                     buffer_size UNUSED,    sox_signalinfo_t   const * signal,    sox_encodinginfo_t const * encoding,    char               const * filetype){

Lines 1–500 of 1361.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t