shithub: sox

Download patch

ref: 788e9abe05be565060286f9ee1a9cbd7ed18d367
parent: 2502bcd9b570012e34e34166aefca9c116f06026
author: robs <robs>
date: Sat Dec 20 11:07:58 EST 2008

--ignore-length

--- a/src/aifc-fmt.c
+++ b/src/aifc-fmt.c
@@ -26,9 +26,9 @@
   static sox_format_handler_t const sox_aifc_format = {SOX_LIB_VERSION_CODE,
     "AIFF-C (not compressed, linear), defined in DAVIC 1.4 Part 9 Annex B",
     names, SOX_FILE_BIG_END,
-    lsx_aiffstartread, lsx_aiffread, lsx_aiffstopread,
-    lsx_aifcstartwrite, lsx_aiffwrite, lsx_aifcstopwrite,
-    lsx_aiffseek, write_encodings, NULL, sizeof(aiff_priv_t)
+    lsx_aiffstartread, lsx_rawread, lsx_aiffstopread,
+    lsx_aifcstartwrite, lsx_rawwrite, lsx_aifcstopwrite,
+    lsx_rawseek, write_encodings, NULL, 0
   };
   return &sox_aifc_format;
 }
--- a/src/aiff-fmt.c
+++ b/src/aiff-fmt.c
@@ -25,9 +25,9 @@
     SOX_ENCODING_SIGN2, 32, 24, 16, 8, 0, 0};
   static sox_format_handler_t const sox_aiff_format = {SOX_LIB_VERSION_CODE,
     "AIFF files used on Apple IIc/IIgs and SGI", names, SOX_FILE_BIG_END,
-    lsx_aiffstartread, lsx_aiffread, lsx_aiffstopread,
-    lsx_aiffstartwrite, lsx_aiffwrite, lsx_aiffstopwrite,
-    lsx_aiffseek, write_encodings, NULL, sizeof(aiff_priv_t)
+    lsx_aiffstartread, lsx_rawread, lsx_aiffstopread,
+    lsx_aiffstartwrite, lsx_rawwrite, lsx_aiffstopwrite,
+    lsx_rawseek, write_encodings, NULL, 0
   };
   return &sox_aiff_format;
 }
--- a/src/aiff.c
+++ b/src/aiff.c
@@ -35,446 +35,382 @@
 static int commentChunk(char **text, char *chunkDescription, sox_format_t * ft);
 static void reportInstrument(sox_format_t * ft);
 
-/* Private data used by writer */
-typedef aiff_priv_t priv_t;
-
-int lsx_aiffseek(sox_format_t * ft, uint64_t offset)
-{
-    priv_t * aiff = (priv_t *) ft->priv;
-    size_t new_offset, channel_block, alignment;
-    size_t size = ft->encoding.bits_per_sample >> 3;
-
-    new_offset = offset * size;
-    /* Make sure request aligns to a channel block (ie left+right) */
-    channel_block = ft->signal.channels * size;
-    alignment = new_offset % channel_block;
-    /* Most common mistaken is to compute something like
-     * "skip everthing upto and including this sample" so
-     * advance to next sample block in this case.
-     */
-    if (alignment != 0)
-        new_offset += (channel_block - alignment);
-    new_offset += aiff->dataStart;
-
-    ft->sox_errno = lsx_seeki(ft, (off_t)new_offset, SEEK_SET);
-
-    if (ft->sox_errno == SOX_SUCCESS)
-        aiff->nsamples = ft->signal.length - (new_offset / size);
-
-    return(ft->sox_errno);
-}
-
 int lsx_aiffstartread(sox_format_t * ft)
 {
-        priv_t * aiff = (priv_t *) ft->priv;
-        char buf[5];
-        uint32_t totalsize;
-        uint32_t chunksize;
-        unsigned short channels = 0;
-        uint32_t frames;
-        unsigned short bits = 0;
-        double rate = 0.0;
-        uint32_t offset = 0;
-        uint32_t blocksize = 0;
-        int foundcomm = 0, foundmark = 0, foundinstr = 0, is_sowt = 0;
-        struct mark {
-                unsigned short id;
-                uint32_t position;
-                char name[40];
-        } marks[32];
-        unsigned short looptype;
-        int i, j;
-        unsigned short nmarks = 0;
-        unsigned short sustainLoopBegin = 0, sustainLoopEnd = 0,
-                       releaseLoopBegin = 0, releaseLoopEnd = 0;
-        off_t seekto = 0;
-        size_t ssndsize = 0;
-        char *annotation;
-        char *author;
-        char *comment = NULL;
-        char *copyright;
-        char *nametext;
+  char buf[5];
+  uint32_t totalsize;
+  uint32_t chunksize;
+  unsigned short channels = 0;
+  uint32_t frames;
+  unsigned short bits = 0;
+  double rate = 0.0;
+  uint32_t offset = 0;
+  uint32_t blocksize = 0;
+  int foundcomm = 0, foundmark = 0, foundinstr = 0, is_sowt = 0;
+  struct mark {
+    unsigned short id;
+    uint32_t position;
+    char name[40];
+  } marks[32];
+  unsigned short looptype;
+  int i, j;
+  unsigned short nmarks = 0;
+  unsigned short sustainLoopBegin = 0, sustainLoopEnd = 0,
+                 releaseLoopBegin = 0, releaseLoopEnd = 0;
+  off_t seekto = 0;
+  size_t ssndsize = 0;
+  char *annotation;
+  char *author;
+  char *comment = NULL;
+  char *copyright;
+  char *nametext;
 
-        uint8_t trash8;
-        uint16_t trash16;
-        uint32_t trash32;
+  uint8_t trash8;
+  uint16_t trash16;
+  uint32_t trash32;
 
-        int rc;
+  int rc;
 
-        /* FORM chunk */
-        if (lsx_reads(ft, buf, (size_t)4) == SOX_EOF || strncmp(buf, "FORM", (size_t)4) != 0)
-        {
-                lsx_fail_errno(ft,SOX_EHDR,"AIFF header does not begin with magic word 'FORM'");
-                return(SOX_EOF);
-        }
-        lsx_readdw(ft, &totalsize);
-        if (lsx_reads(ft, buf, (size_t)4) == SOX_EOF || (strncmp(buf, "AIFF", (size_t)4) != 0 &&
-            strncmp(buf, "AIFC", (size_t)4) != 0))
-        {
-                lsx_fail_errno(ft,SOX_EHDR,"AIFF 'FORM' chunk does not specify 'AIFF' or 'AIFC' as type");
-                return(SOX_EOF);
-        }
+  /* FORM chunk */
+  if (lsx_reads(ft, buf, (size_t)4) == SOX_EOF || strncmp(buf, "FORM", (size_t)4) != 0) {
+    lsx_fail_errno(ft,SOX_EHDR,"AIFF header does not begin with magic word 'FORM'");
+    return(SOX_EOF);
+  }
+  lsx_readdw(ft, &totalsize);
+  if (lsx_reads(ft, buf, (size_t)4) == SOX_EOF || (strncmp(buf, "AIFF", (size_t)4) != 0 &&
+        strncmp(buf, "AIFC", (size_t)4) != 0)) {
+    lsx_fail_errno(ft,SOX_EHDR,"AIFF 'FORM' chunk does not specify 'AIFF' or 'AIFC' as type");
+    return(SOX_EOF);
+  }
 
 
-        /* Skip everything but the COMM chunk and the SSND chunk */
-        /* The SSND chunk must be the last in the file */
-        while (1) {
-                if (lsx_reads(ft, buf, (size_t)4) == SOX_EOF)
-                {
-                        if (ssndsize > 0)
-                        {
-                                break;
-                        }
-                        else
-                        {
-                                lsx_fail_errno(ft,SOX_EHDR,"Missing SSND chunk in AIFF file");
-                                return(SOX_EOF);
-                        }
-                }
-                if (strncmp(buf, "COMM", (size_t)4) == 0) {
-                        /* COMM chunk */
-                        lsx_readdw(ft, &chunksize);
-                        lsx_readw(ft, &channels);
-                        lsx_readdw(ft, &frames);
-                        lsx_readw(ft, &bits);
-                        rate = read_ieee_extended(ft);
-                        chunksize -= 18;
-                        if (chunksize > 0)
-                        {
-                            lsx_reads(ft, buf, (size_t)4);
-                            chunksize -= 4;
-                            if (strncmp(buf, "sowt", (size_t)4) == 0)
-                            {
-                                /* CD audio as read on Mac OS machines */
-                                /* Need to endian swap all the data */
-                                is_sowt = 1;
-                            }
-                            else if (strncmp(buf, "NONE", (size_t)4) != 0 &&
-                                     strncmp(buf, "twos", (size_t)4) != 0)
-                            {
-                                buf[4] = 0;
-                                lsx_fail_errno(ft,SOX_EHDR,"AIFC files that contain compressed data are not supported: %s",buf);
-                                return(SOX_EOF);
-                            }
-                        }
-                        while(chunksize-- > 0)
-                            lsx_readb(ft, &trash8);
-                        foundcomm = 1;
-                }
-                else if (strncmp(buf, "SSND", (size_t)4) == 0) {
-                        /* SSND chunk */
-                        lsx_readdw(ft, &chunksize);
-                        lsx_readdw(ft, &offset);
-                        lsx_readdw(ft, &blocksize);
-                        chunksize -= 8;
-                        ssndsize = chunksize;
-                        /* word-align chunksize in case it wasn't
-                         * done by writing application already.
-                         */
-                        chunksize += (chunksize % 2);
-                        /* if can't seek, just do sound now */
-                        if (!ft->seekable)
-                                break;
-                        /* else, seek to end of sound and hunt for more */
-                        seekto = lsx_tell(ft);
-                        lsx_seeki(ft, (off_t)chunksize, SEEK_CUR);
-                }
-                else if (strncmp(buf, "MARK", (size_t)4) == 0) {
-                        /* MARK chunk */
-                        lsx_readdw(ft, &chunksize);
-                        if (chunksize >= sizeof(nmarks)) {
-                          lsx_readw(ft, &nmarks);
-                          chunksize -= sizeof(nmarks);
-                        }
-                        else nmarks = 0;
+  /* Skip everything but the COMM chunk and the SSND chunk */
+  /* The SSND chunk must be the last in the file */
+  while (1) {
+    if (lsx_reads(ft, buf, (size_t)4) == SOX_EOF) {
+      if (ssndsize > 0)
+        break;
+      else {
+        lsx_fail_errno(ft,SOX_EHDR,"Missing SSND chunk in AIFF file");
+        return(SOX_EOF);
+      }
+    }
+    if (strncmp(buf, "COMM", (size_t)4) == 0) {
+      /* COMM chunk */
+      lsx_readdw(ft, &chunksize);
+      lsx_readw(ft, &channels);
+      lsx_readdw(ft, &frames);
+      lsx_readw(ft, &bits);
+      rate = read_ieee_extended(ft);
+      chunksize -= 18;
+      if (chunksize > 0) {
+        lsx_reads(ft, buf, (size_t)4);
+        chunksize -= 4;
+        if (strncmp(buf, "sowt", (size_t)4) == 0) {
+          /* CD audio as read on Mac OS machines */
+          /* Need to endian swap all the data */
+          is_sowt = 1;
+        }
+        else if (strncmp(buf, "NONE", (size_t)4) != 0 &&
+            strncmp(buf, "twos", (size_t)4) != 0) {
+          buf[4] = 0;
+          lsx_fail_errno(ft,SOX_EHDR,"AIFC files that contain compressed data are not supported: %s",buf);
+          return(SOX_EOF);
+        }
+      }
+      while(chunksize-- > 0)
+        lsx_readb(ft, &trash8);
+      foundcomm = 1;
+    }
+    else if (strncmp(buf, "SSND", (size_t)4) == 0) {
+      /* SSND chunk */
+      lsx_readdw(ft, &chunksize);
+      lsx_readdw(ft, &offset);
+      lsx_readdw(ft, &blocksize);
+      chunksize -= 8;
+      ssndsize = chunksize;
+      /* word-align chunksize in case it wasn't
+       * done by writing application already.
+       */
+      chunksize += (chunksize % 2);
+      /* if can't seek, just do sound now */
+      if (!ft->seekable)
+        break;
+      /* else, seek to end of sound and hunt for more */
+      seekto = lsx_tell(ft);
+      lsx_seeki(ft, (off_t)chunksize, SEEK_CUR);
+    }
+    else if (strncmp(buf, "MARK", (size_t)4) == 0) {
+      /* MARK chunk */
+      lsx_readdw(ft, &chunksize);
+      if (chunksize >= sizeof(nmarks)) {
+        lsx_readw(ft, &nmarks);
+        chunksize -= sizeof(nmarks);
+      }
+      else nmarks = 0;
 
-                        /* Some programs like to always have a MARK chunk
-                         * but will set number of marks to 0 and force
-                         * software to detect and ignore it.
-                         */
-                        if (nmarks == 0)
-                            foundmark = 0;
-                        else
-                            foundmark = 1;
+      /* Some programs like to always have a MARK chunk
+       * but will set number of marks to 0 and force
+       * software to detect and ignore it.
+       */
+      if (nmarks == 0)
+        foundmark = 0;
+      else
+        foundmark = 1;
 
-                        /* Make sure its not larger then we support */
-                        if (nmarks > 32)
-                            nmarks = 32;
+      /* Make sure its not larger then we support */
+      if (nmarks > 32)
+        nmarks = 32;
 
-                        for(i = 0; i < nmarks && chunksize; i++) {
-                                unsigned char len, read_len, tmp_c;
+      for(i = 0; i < nmarks && chunksize; i++) {
+        unsigned char len, read_len, tmp_c;
 
-                                if (chunksize < 6)
-                                    break;
-                                lsx_readw(ft, &(marks[i].id));
-                                lsx_readdw(ft, &(marks[i].position));
-                                chunksize -= 6;
-                                /* If error reading length then
-                                 * don't try to read more bytes
-                                 * based on that value.
-                                 */
-                                if (lsx_readb(ft, &len) != SOX_SUCCESS)
-                                    break;
-                                --chunksize;
-                                if (len > chunksize)
-                                    len = chunksize;
-                                read_len = len;
-                                if (read_len > 39)
-                                    read_len = 39;
-                                for(j = 0; j < len && chunksize; j++)
-                                {
-                                    lsx_readb(ft, &tmp_c);
-                                    if (j < read_len)
-                                        marks[i].name[j] = tmp_c;
-                                    chunksize--;
-                                }
-                                marks[i].name[read_len] = 0;
-                                if ((len & 1) == 0 && chunksize) {
-                                        chunksize--;
-                                        lsx_readb(ft, &trash8);
-                                }
-                        }
-                        /* HA HA!  Sound Designer (and others) makes */
-                        /* bogus files. It spits out bogus chunksize */
-                        /* for MARK field */
-                        while(chunksize-- > 0)
-                            lsx_readb(ft, &trash8);
-                }
-                else if (strncmp(buf, "INST", (size_t)4) == 0) {
-                        /* INST chunk */
-                        lsx_readdw(ft, &chunksize);
-                        lsx_readsb(ft, &(ft->oob.instr.MIDInote));
-                        lsx_readb(ft, &trash8);
-                        lsx_readsb(ft, &(ft->oob.instr.MIDIlow));
-                        lsx_readsb(ft, &(ft->oob.instr.MIDIhi));
-                        /* Low  velocity */
-                        lsx_readb(ft, &trash8);
-                        /* Hi  velocity */
-                        lsx_readb(ft, &trash8);
-                        lsx_readw(ft, &trash16);/* gain */
-                        lsx_readw(ft, &looptype); /* sustain loop */
-                        ft->oob.loops[0].type = looptype;
-                        lsx_readw(ft, &sustainLoopBegin); /* begin marker */
-                        lsx_readw(ft, &sustainLoopEnd);    /* end marker */
-                        lsx_readw(ft, &looptype); /* release loop */
-                        ft->oob.loops[1].type = looptype;
-                        lsx_readw(ft, &releaseLoopBegin);  /* begin marker */
-                        lsx_readw(ft, &releaseLoopEnd);    /* end marker */
-
-                        foundinstr = 1;
-                }
-                else if (strncmp(buf, "APPL", (size_t)4) == 0) {
-                        lsx_readdw(ft, &chunksize);
-                        /* word-align chunksize in case it wasn't
-                         * done by writing application already.
-                         */
-                        chunksize += (chunksize % 2);
-                        while(chunksize-- > 0)
-                            lsx_readb(ft, &trash8);
-                }
-                else if (strncmp(buf, "ALCH", (size_t)4) == 0) {
-                        /* I think this is bogus and gets grabbed by APPL */
-                        /* INST chunk */
-                        lsx_readdw(ft, &trash32);                /* ENVS - jeez! */
-                        lsx_readdw(ft, &chunksize);
-                        while(chunksize-- > 0)
-                            lsx_readb(ft, &trash8);
-                }
-                else if (strncmp(buf, "ANNO", (size_t)4) == 0) {
-                  rc = textChunk(&annotation, "Annotation:", ft);
-                  if (rc)
-                  {
-                    /* Fail already called in function */
-                    return(SOX_EOF);
-                  }
-                  if (annotation)
-                    sox_append_comments(&ft->oob.comments, annotation);
-                  free(annotation);
-                }
-                else if (strncmp(buf, "COMT", (size_t)4) == 0) {
-                  rc = commentChunk(&comment, "Comment:", ft);
-                  if (rc) {
-                    /* Fail already called in function */
-                    return(SOX_EOF);
-                  }
-                  if (comment)
-                    sox_append_comments(&ft->oob.comments, comment);
-                  free(comment);
-                }
-                else if (strncmp(buf, "AUTH", (size_t)4) == 0) {
-                  /* Author chunk */
-                  rc = textChunk(&author, "Author:", ft);
-                  if (rc)
-                  {
-                      /* Fail already called in function */
-                      return(SOX_EOF);
-                  }
-                  free(author);
-                }
-                else if (strncmp(buf, "NAME", (size_t)4) == 0) {
-                  /* Name chunk */
-                  rc = textChunk(&nametext, "Name:", ft);
-                  if (rc)
-                  {
-                      /* Fail already called in function */
-                      return(SOX_EOF);
-                  }
-                  free(nametext);
-                }
-                else if (strncmp(buf, "(c) ", (size_t)4) == 0) {
-                  /* Copyright chunk */
-                  rc = textChunk(&copyright, "Copyright:", ft);
-                  if (rc)
-                  {
-                      /* Fail already called in function */
-                      return(SOX_EOF);
-                  }
-                  free(copyright);
-                }
-                else {
-                        if (lsx_eof(ft))
-                                break;
-                        buf[4] = 0;
-                        lsx_debug("AIFFstartread: ignoring '%s' chunk", buf);
-                        lsx_readdw(ft, &chunksize);
-                        if (lsx_eof(ft))
-                                break;
-                        /* Skip the chunk using lsx_readb() so we may read
-                           from a pipe */
-                        while (chunksize-- > 0) {
-                            if (lsx_readb(ft, &trash8) == SOX_EOF)
-                                        break;
-                        }
-                }
-                if (lsx_eof(ft))
-                        break;
-        }
+        if (chunksize < 6)
+          break;
+        lsx_readw(ft, &(marks[i].id));
+        lsx_readdw(ft, &(marks[i].position));
+        chunksize -= 6;
+        /* If error reading length then
+         * don't try to read more bytes
+         * based on that value.
+         */
+        if (lsx_readb(ft, &len) != SOX_SUCCESS)
+          break;
+        --chunksize;
+        if (len > chunksize)
+          len = chunksize;
+        read_len = len;
+        if (read_len > 39)
+          read_len = 39;
+        for(j = 0; j < len && chunksize; j++) {
+          lsx_readb(ft, &tmp_c);
+          if (j < read_len)
+            marks[i].name[j] = tmp_c;
+          chunksize--;
+        }
+        marks[i].name[read_len] = 0;
+        if ((len & 1) == 0 && chunksize) {
+          chunksize--;
+          lsx_readb(ft, &trash8);
+        }
+      }
+      /* HA HA!  Sound Designer (and others) makes */
+      /* bogus files. It spits out bogus chunksize */
+      /* for MARK field */
+      while(chunksize-- > 0)
+        lsx_readb(ft, &trash8);
+    }
+    else if (strncmp(buf, "INST", (size_t)4) == 0) {
+      /* INST chunk */
+      lsx_readdw(ft, &chunksize);
+      lsx_readsb(ft, &(ft->oob.instr.MIDInote));
+      lsx_readb(ft, &trash8);
+      lsx_readsb(ft, &(ft->oob.instr.MIDIlow));
+      lsx_readsb(ft, &(ft->oob.instr.MIDIhi));
+      /* Low  velocity */
+      lsx_readb(ft, &trash8);
+      /* Hi  velocity */
+      lsx_readb(ft, &trash8);
+      lsx_readw(ft, &trash16);/* gain */
+      lsx_readw(ft, &looptype); /* sustain loop */
+      ft->oob.loops[0].type = looptype;
+      lsx_readw(ft, &sustainLoopBegin); /* begin marker */
+      lsx_readw(ft, &sustainLoopEnd);    /* end marker */
+      lsx_readw(ft, &looptype); /* release loop */
+      ft->oob.loops[1].type = looptype;
+      lsx_readw(ft, &releaseLoopBegin);  /* begin marker */
+      lsx_readw(ft, &releaseLoopEnd);    /* end marker */
+
+      foundinstr = 1;
+    }
+    else if (strncmp(buf, "APPL", (size_t)4) == 0) {
+      lsx_readdw(ft, &chunksize);
+      /* word-align chunksize in case it wasn't
+       * done by writing application already.
+       */
+      chunksize += (chunksize % 2);
+      while(chunksize-- > 0)
+        lsx_readb(ft, &trash8);
+    }
+    else if (strncmp(buf, "ALCH", (size_t)4) == 0) {
+      /* I think this is bogus and gets grabbed by APPL */
+      /* INST chunk */
+      lsx_readdw(ft, &trash32);                /* ENVS - jeez! */
+      lsx_readdw(ft, &chunksize);
+      while(chunksize-- > 0)
+        lsx_readb(ft, &trash8);
+    }
+    else if (strncmp(buf, "ANNO", (size_t)4) == 0) {
+      rc = textChunk(&annotation, "Annotation:", ft);
+      if (rc) {
+        /* Fail already called in function */
+        return(SOX_EOF);
+      }
+      if (annotation)
+        sox_append_comments(&ft->oob.comments, annotation);
+      free(annotation);
+    }
+    else if (strncmp(buf, "COMT", (size_t)4) == 0) {
+      rc = commentChunk(&comment, "Comment:", ft);
+      if (rc) {
+        /* Fail already called in function */
+        return(SOX_EOF);
+      }
+      if (comment)
+        sox_append_comments(&ft->oob.comments, comment);
+      free(comment);
+    }
+    else if (strncmp(buf, "AUTH", (size_t)4) == 0) {
+      /* Author chunk */
+      rc = textChunk(&author, "Author:", ft);
+      if (rc) {
+        /* Fail already called in function */
+        return(SOX_EOF);
+      }
+      free(author);
+    }
+    else if (strncmp(buf, "NAME", (size_t)4) == 0) {
+      /* Name chunk */
+      rc = textChunk(&nametext, "Name:", ft);
+      if (rc) {
+        /* Fail already called in function */
+        return(SOX_EOF);
+      }
+      free(nametext);
+    }
+    else if (strncmp(buf, "(c) ", (size_t)4) == 0) {
+      /* Copyright chunk */
+      rc = textChunk(&copyright, "Copyright:", ft);
+      if (rc) {
+        /* Fail already called in function */
+        return(SOX_EOF);
+      }
+      free(copyright);
+    }
+    else {
+      if (lsx_eof(ft))
+        break;
+      buf[4] = 0;
+      lsx_debug("AIFFstartread: ignoring '%s' chunk", buf);
+      lsx_readdw(ft, &chunksize);
+      if (lsx_eof(ft))
+        break;
+      /* Skip the chunk using lsx_readb() so we may read
+         from a pipe */
+      while (chunksize-- > 0) {
+        if (lsx_readb(ft, &trash8) == SOX_EOF)
+          break;
+      }
+    }
+    if (lsx_eof(ft))
+      break;
+  }
+
+  /*
+   * if a pipe, we lose all chunks after sound.
+   * Like, say, instrument loops.
+   */
+  if (ft->seekable) {
+    if (seekto > 0)
+      lsx_seeki(ft, seekto, SEEK_SET);
+    else {
+      lsx_fail_errno(ft,SOX_EOF,"AIFF: no sound data on input file");
+      return(SOX_EOF);
+    }
+  }
+  /* SSND chunk just read */
+  if (blocksize != 0)
+    lsx_warn("AIFF header has invalid blocksize.  Ignoring but expect a premature EOF");
+
+  ssndsize -= offset;
+  while (offset-- > 0) {
+    if (lsx_readb(ft, &trash8) == SOX_EOF) {
+      lsx_fail_errno(ft,errno,"unexpected EOF while skipping AIFF offset");
+      return(SOX_EOF);
+    }
+  }
 
-        /*
-         * if a pipe, we lose all chunks after sound.
-         * Like, say, instrument loops.
-         */
-        if (ft->seekable)
-        {
-                if (seekto > 0)
-                        lsx_seeki(ft, seekto, SEEK_SET);
-                else
-                {
-                        lsx_fail_errno(ft,SOX_EOF,"AIFF: no sound data on input file");
-                        return(SOX_EOF);
-                }
-        }
-        /* SSND chunk just read */
-        if (blocksize != 0)
-            lsx_warn("AIFF header has invalid blocksize.  Ignoring but expect a premature EOF");
-
-        ssndsize -= offset;
-        while (offset-- > 0) {
-                if (lsx_readb(ft, &trash8) == SOX_EOF)
-                {
-                        lsx_fail_errno(ft,errno,"unexpected EOF while skipping AIFF offset");
-                        return(SOX_EOF);
-                }
-        }
-
-        if (foundcomm) {
-                ft->signal.channels = channels;
-                ft->signal.rate = rate;
-                if (ft->encoding.encoding != SOX_ENCODING_UNKNOWN && ft->encoding.encoding != SOX_ENCODING_SIGN2)
-                    lsx_report("AIFF only supports signed data.  Forcing to signed.");
-                ft->encoding.encoding = SOX_ENCODING_SIGN2;
-                if (bits <= 8)
-                    ft->encoding.bits_per_sample = 8;
-                else if (bits <= 16)
-                    ft->encoding.bits_per_sample = 16;
-                else if (bits <= 24)
-                    ft->encoding.bits_per_sample = 24;
-                else if (bits <= 32)
-                    ft->encoding.bits_per_sample = 32;
-                else
-                {
-                    lsx_fail_errno(ft,SOX_EFMT,"unsupported sample size in AIFF header: %d", bits);
-                    return(SOX_EOF);
-                }
-        } else  {
-                if ((ft->signal.channels == 0)
-                        || (ft->signal.rate == 0)
-                        || (ft->encoding.encoding == SOX_ENCODING_UNKNOWN)
-                        || (ft->encoding.bits_per_sample == 0)) {
-                  lsx_report("You must specify # channels, sample rate, signed/unsigned,");
-                  lsx_report("and 8/16 on the command line.");
-                  lsx_fail_errno(ft,SOX_EFMT,"Bogus AIFF file: no COMM section.");
-                  return(SOX_EOF);
-                }
+  if (foundcomm) {
+    if (ft->encoding.encoding != SOX_ENCODING_UNKNOWN && ft->encoding.encoding != SOX_ENCODING_SIGN2)
+      lsx_report("AIFF only supports signed data.  Forcing to signed.");
+    ft->encoding.encoding = SOX_ENCODING_SIGN2;
+    if      (bits <=  8) bits = 8;
+    else if (bits <= 16) bits = 16;
+    else if (bits <= 24) bits = 24;
+    else if (bits <= 32) bits = 32;
+    else {
+      lsx_fail_errno(ft,SOX_EFMT,"unsupported sample size in AIFF header: %d", bits);
+      return(SOX_EOF);
+    }
+  } else  {
+    if ((ft->signal.channels == SOX_UNSPEC)
+        || (ft->signal.rate == SOX_UNSPEC)
+        || (ft->encoding.encoding == SOX_ENCODING_UNKNOWN)
+        || (ft->encoding.bits_per_sample == 0)) {
+      lsx_report("You must specify # channels, sample rate, signed/unsigned,");
+      lsx_report("and 8/16 on the command line.");
+      lsx_fail_errno(ft,SOX_EFMT,"Bogus AIFF file: no COMM section.");
+      return(SOX_EOF);
+    }
 
-        }
+  }
+  ssndsize /= bits >> 3;
 
-        aiff->nsamples = ssndsize / (ft->encoding.bits_per_sample >> 3);
+  /* Cope with 'sowt' CD tracks as read on Macs */
+  if (is_sowt)
+    ft->encoding.reverse_bytes = !ft->encoding.reverse_bytes;
 
-        /* Cope with 'sowt' CD tracks as read on Macs */
-        if (is_sowt)
-                ft->encoding.reverse_bytes = !ft->encoding.reverse_bytes;
+  if (foundmark && !foundinstr) {
+    lsx_debug("Ignoring MARK chunk since no INSTR found.");
+    foundmark = 0;
+  }
+  if (!foundmark && foundinstr) {
+    lsx_debug("Ignoring INSTR chunk since no MARK found.");
+    foundinstr = 0;
+  }
+  if (foundmark && foundinstr) {
+    int i;
+    int slbIndex = 0, sleIndex = 0;
+    int rlbIndex = 0, rleIndex = 0;
 
-        if (foundmark && !foundinstr)
-        {
-            lsx_debug("Ignoring MARK chunk since no INSTR found.");
-            foundmark = 0;
-        }
-        if (!foundmark && foundinstr)
-        {
-            lsx_debug("Ignoring INSTR chunk since no MARK found.");
-            foundinstr = 0;
-        }
-        if (foundmark && foundinstr) {
-                int i;
-                int slbIndex = 0, sleIndex = 0;
-                int rlbIndex = 0, rleIndex = 0;
+    /* find our loop markers and save their marker indexes */
+    for(i = 0; i < nmarks; i++) {
+      if(marks[i].id == sustainLoopBegin)
+        slbIndex = i;
+      if(marks[i].id == sustainLoopEnd)
+        sleIndex = i;
+      if(marks[i].id == releaseLoopBegin)
+        rlbIndex = i;
+      if(marks[i].id == releaseLoopEnd)
+        rleIndex = i;
+    }
 
-                /* find our loop markers and save their marker indexes */
-                for(i = 0; i < nmarks; i++) {
-                  if(marks[i].id == sustainLoopBegin)
-                    slbIndex = i;
-                  if(marks[i].id == sustainLoopEnd)
-                    sleIndex = i;
-                  if(marks[i].id == releaseLoopBegin)
-                    rlbIndex = i;
-                  if(marks[i].id == releaseLoopEnd)
-                    rleIndex = i;
-                }
+    ft->oob.instr.nloops = 0;
+    if (ft->oob.loops[0].type != 0) {
+      ft->oob.loops[0].start = marks[slbIndex].position;
+      ft->oob.loops[0].length =
+        marks[sleIndex].position - marks[slbIndex].position;
+      /* really the loop count should be infinite */
+      ft->oob.loops[0].count = 1;
+      ft->oob.instr.loopmode = SOX_LOOP_SUSTAIN_DECAY | ft->oob.loops[0].type;
+      ft->oob.instr.nloops++;
+    }
+    if (ft->oob.loops[1].type != 0) {
+      ft->oob.loops[1].start = marks[rlbIndex].position;
+      ft->oob.loops[1].length =
+        marks[rleIndex].position - marks[rlbIndex].position;
+      /* really the loop count should be infinite */
+      ft->oob.loops[1].count = 1;
+      ft->oob.instr.loopmode = SOX_LOOP_SUSTAIN_DECAY | ft->oob.loops[1].type;
+      ft->oob.instr.nloops++;
+    }
+  }
+  reportInstrument(ft);
 
-                ft->oob.instr.nloops = 0;
-                if (ft->oob.loops[0].type != 0) {
-                        ft->oob.loops[0].start = marks[slbIndex].position;
-                        ft->oob.loops[0].length =
-                            marks[sleIndex].position - marks[slbIndex].position;
-                        /* really the loop count should be infinite */
-                        ft->oob.loops[0].count = 1;
-                        ft->oob.instr.loopmode = SOX_LOOP_SUSTAIN_DECAY | ft->oob.loops[0].type;
-                        ft->oob.instr.nloops++;
-                }
-                if (ft->oob.loops[1].type != 0) {
-                        ft->oob.loops[1].start = marks[rlbIndex].position;
-                        ft->oob.loops[1].length =
-                            marks[rleIndex].position - marks[rlbIndex].position;
-                        /* really the loop count should be infinite */
-                        ft->oob.loops[1].count = 1;
-                        ft->oob.instr.loopmode = SOX_LOOP_SUSTAIN_DECAY | ft->oob.loops[1].type;
-                        ft->oob.instr.nloops++;
-                }
-        }
-        reportInstrument(ft);
+  return lsx_check_read_params(
+      ft, channels, rate, SOX_ENCODING_SIGN2, bits, (off_t)ssndsize, sox_false);
+}
 
-        /* Needed because of lsx_rawread() */
-        rc = lsx_rawstartread(ft);
-        if (rc)
-            return rc;
-
-        ft->signal.length = aiff->nsamples;    /* for seeking */
-        aiff->dataStart = lsx_tell(ft);
-
-        return(SOX_SUCCESS);
-}
-
 /* print out the MIDI key allocations, loop points, directions etc */
 static void reportInstrument(sox_format_t * ft)
 {
@@ -590,20 +526,6 @@
   return(SOX_SUCCESS);
 }
 
-size_t lsx_aiffread(sox_format_t * ft, sox_sample_t *buf, size_t len)
-{
-        priv_t * aiff = (priv_t *) ft->priv;
-        off_t done;
-
-        if ((size_t)len > aiff->nsamples)
-                len = aiff->nsamples;
-        done = lsx_rawread(ft, buf, len);
-        if (done == 0 && aiff->nsamples != 0)
-                lsx_warn("Premature EOF on AIFF input file");
-        aiff->nsamples -= done;
-        return done;
-}
-
 int lsx_aiffstopread(sox_format_t * ft)
 {
         char buf[5];
@@ -647,7 +569,6 @@
 
 int lsx_aiffstartwrite(sox_format_t * ft)
 {
-        priv_t * aiff = (priv_t *) ft->priv;
         int rc;
 
         /* Needed because lsx_rawwrite() */
@@ -655,8 +576,6 @@
         if (rc)
             return rc;
 
-        aiff->nsamples = 0;
-
         /* Compute the "very large number" so that a maximum number
            of samples can be transmitted through a pipe without the
            risk of causing overflow when calculating the number of bytes.
@@ -666,21 +585,11 @@
         return(aiffwriteheader(ft, (size_t) 0x7f000000 / ((ft->encoding.bits_per_sample>>3)*ft->signal.channels)));
 }
 
-size_t lsx_aiffwrite(sox_format_t * ft, const sox_sample_t *buf, size_t len)
-{
-        priv_t * aiff = (priv_t *) ft->priv;
-        aiff->nsamples += len;
-        lsx_rawwrite(ft, buf, len);
-        return(len);
-}
-
 int lsx_aiffstopwrite(sox_format_t * ft)
 {
-        priv_t * aiff = (priv_t *) ft->priv;
-
         /* If we've written an odd number of bytes, write a padding
            NUL */
-        if (aiff->nsamples % 2 == 1 && ft->encoding.bits_per_sample == 8 && ft->signal.channels == 1)
+        if (ft->olength % 2 == 1 && ft->encoding.bits_per_sample == 8 && ft->signal.channels == 1)
         {
             sox_sample_t buf = 0;
             lsx_rawwrite(ft, &buf, (size_t) 1);
@@ -696,7 +605,7 @@
                 lsx_fail_errno(ft,errno,"can't rewind output file to rewrite AIFF header");
                 return(SOX_EOF);
         }
-        return(aiffwriteheader(ft, aiff->nsamples / ft->signal.channels));
+        return(aiffwriteheader(ft, ft->olength / ft->signal.channels));
 }
 
 static int aiffwriteheader(sox_format_t * ft, size_t nframes)
@@ -844,7 +753,6 @@
 
 int lsx_aifcstartwrite(sox_format_t * ft)
 {
-        priv_t * aiff = (priv_t *) ft->priv;
         int rc;
 
         /* Needed because lsx_rawwrite() */
@@ -852,8 +760,6 @@
         if (rc)
             return rc;
 
-        aiff->nsamples = 0;
-
         /* Compute the "very large number" so that a maximum number
            of samples can be transmitted through a pipe without the
            risk of causing overflow when calculating the number of bytes.
@@ -865,11 +771,9 @@
 
 int lsx_aifcstopwrite(sox_format_t * ft)
 {
-        priv_t * aiff = (priv_t *) ft->priv;
-
         /* If we've written an odd number of bytes, write a padding
            NUL */
-        if (aiff->nsamples % 2 == 1 && ft->encoding.bits_per_sample == 8 && ft->signal.channels == 1)
+        if (ft->olength % 2 == 1 && ft->encoding.bits_per_sample == 8 && ft->signal.channels == 1)
         {
             sox_sample_t buf = 0;
             lsx_rawwrite(ft, &buf, (size_t) 1);
@@ -885,7 +789,7 @@
                 lsx_fail_errno(ft,errno,"can't rewind output file to rewrite AIFC header");
                 return(SOX_EOF);
         }
-        return(aifcwriteheader(ft, aiff->nsamples / ft->signal.channels));
+        return(aifcwriteheader(ft, ft->olength / ft->signal.channels));
 }
 
 static int aifcwriteheader(sox_format_t * ft, size_t nframes)
--- a/src/aiff.h
+++ b/src/aiff.h
@@ -14,18 +14,9 @@
  * (usable for japanese-data-broadcasting, specified by ARIB STD-B24.)
  */
 
-typedef struct {
-    size_t nsamples;  /* number of 1-channel samples read or written */
-                         /* Decrements for read increments for write */
-    size_t dataStart; /* need to for seeking */
-} aiff_priv_t;
-
-int lsx_aiffseek(sox_format_t * ft, uint64_t offset);
 int lsx_aiffstartread(sox_format_t * ft);
-size_t lsx_aiffread(sox_format_t * ft, sox_sample_t *buf, size_t len);
 int lsx_aiffstopread(sox_format_t * ft);
 int lsx_aiffstartwrite(sox_format_t * ft);
-size_t lsx_aiffwrite(sox_format_t * ft, const sox_sample_t *buf, size_t len);
 int lsx_aiffstopwrite(sox_format_t * ft);
 int lsx_aifcstartwrite(sox_format_t * ft);
 int lsx_aifcstopwrite(sox_format_t * ft);
--- a/src/au.c
+++ b/src/au.c
@@ -187,9 +187,9 @@
     free(buf);
   }
   if (data_size == SUN_UNSPEC)
-    data_size = 0;  /* libSoX uses 0 for unspecified */
-  return lsx_check_read_params(ft, channels, (sox_rate_t)rate,
-      encoding, bits_per_sample, div_bits(data_size, bits_per_sample));
+    data_size = SOX_UNSPEC;
+  return lsx_check_read_params(ft, channels, (sox_rate_t)rate, encoding,
+      bits_per_sample, div_bits(data_size, bits_per_sample), sox_true);
 }
 
 static int write_header(sox_format_t * ft)
@@ -202,7 +202,7 @@
   sox_bool error  = sox_false
   ||lsx_writechars(ft, id[i].str, sizeof(id[i].str))
   ||lsx_writedw(ft, FIXED_HDR + (unsigned)info_len)
-  ||lsx_writedw(ft, (unsigned) (size? size*(ft->encoding.bits_per_sample >> 3) : SUN_UNSPEC))
+  ||lsx_writedw(ft, (unsigned) (size != SOX_UNSPEC? size*(ft->encoding.bits_per_sample >> 3) : SUN_UNSPEC))
   ||lsx_writedw(ft, ft_enc(ft->encoding.bits_per_sample, ft->encoding.encoding))
   ||lsx_writedw(ft, (unsigned)(ft->signal.rate + .5))
   ||lsx_writedw(ft, ft->signal.channels)
--- a/src/cdr.c
+++ b/src/cdr.c
@@ -20,7 +20,7 @@
 
 static int start(sox_format_t * ft)
 {
-  return lsx_check_read_params(ft, 2, 44100., SOX_ENCODING_SIGN2, 16, (off_t)0);
+  return lsx_check_read_params(ft, 2, 44100., SOX_ENCODING_SIGN2, 16, (off_t)0, sox_false);
 }
 
 static int stopwrite(sox_format_t * ft)
--- a/src/formats.c
+++ b/src/formats.c
@@ -808,15 +808,20 @@
 
 size_t sox_read(sox_format_t * ft, sox_sample_t * buf, size_t len)
 {
-  size_t actual = ft->handler.read? (*ft->handler.read)(ft, buf, len) : 0;
-  return (actual > len? 0 : actual);
+  size_t actual;
+  if (ft->signal.length != SOX_UNSPEC)
+    len = min(len, ft->signal.length - ft->olength);
+  actual = ft->handler.read? (*ft->handler.read)(ft, buf, len) : 0;
+  actual = actual > len? 0 : actual;
+  ft->olength += actual;
+  return actual;
 }
 
 size_t sox_write(sox_format_t * ft, const sox_sample_t *buf, size_t len)
 {
-  size_t ret = ft->handler.write? (*ft->handler.write)(ft, buf, len) : 0;
-  ft->olength += ret;
-  return ret;
+  size_t actual = ft->handler.write? (*ft->handler.write)(ft, buf, len) : 0;
+  ft->olength += actual;
+  return actual;
 }
 
 int sox_close(sox_format_t * ft)
--- a/src/formats_i.c
+++ b/src/formats_i.c
@@ -47,9 +47,10 @@
 }
 
 int lsx_check_read_params(sox_format_t * ft, unsigned channels,
-    sox_rate_t rate, sox_encoding_t encoding, unsigned bits_per_sample, off_t length)
+    sox_rate_t rate, sox_encoding_t encoding, unsigned bits_per_sample,
+    off_t num_samples, sox_bool check_length)
 {
-  ft->signal.length = length;
+  ft->signal.length = ft->signal.length == SOX_IGNORE_LENGTH? SOX_UNSPEC : num_samples;
 
   if (ft->seekable)
     ft->data_start = lsx_tell(ft);
@@ -70,12 +71,12 @@
     lsx_warn("`%s': overriding encoding size", ft->filename);
   ft->encoding.bits_per_sample = bits_per_sample;
 
-  if (ft->encoding.bits_per_sample && lsx_filelength(ft)) {
+  if (check_length && ft->encoding.bits_per_sample && lsx_filelength(ft)) {
     off_t calculated_length = div_bits(lsx_filelength(ft) - ft->data_start, ft->encoding.bits_per_sample);
     if (!ft->signal.length)
       ft->signal.length = calculated_length;
-    else if (length != calculated_length)
-      lsx_warn("`%s': file header gives the total number of samples as %u but file length indicates the number is in fact %u", ft->filename, (unsigned)length, (unsigned)calculated_length); /* FIXME: casts */
+    else if (num_samples != calculated_length)
+      lsx_warn("`%s': file header gives the total number of samples as %u but file length indicates the number is in fact %u", ft->filename, (unsigned)num_samples, (unsigned)calculated_length); /* FIXME: casts */
   }
 
   if (sox_precision(ft->encoding.encoding, ft->encoding.bits_per_sample))
@@ -171,6 +172,7 @@
 void lsx_rewind(sox_format_t * ft)
 {
   rewind(ft->fp);
+  ft->tell_off = 0;
 }
 
 void lsx_clearerr(sox_format_t * ft)
--- a/src/htk.c
+++ b/src/htk.c
@@ -42,8 +42,8 @@
     lsx_fail_errno(ft, SOX_EFMT, "unsupported HTK type `%s' (0%o)", str[n], parmKind);
     return SOX_EOF;
   }
-  return lsx_check_read_params(ft, 1, 1e7 / period_100ns,
-      SOX_ENCODING_SIGN2, (unsigned)bytes_per_sample << 3, (off_t)num_samples);
+  return lsx_check_read_params(ft, 1, 1e7 / period_100ns, SOX_ENCODING_SIGN2,
+      (unsigned)bytes_per_sample << 3, (off_t)num_samples, sox_true);
 }
 
 static int write_header(sox_format_t * ft)
--- a/src/lpc10.c
+++ b/src/lpc10.c
@@ -131,7 +131,7 @@
     return SOX_EOF;
   }
   lpc->samples = LPC10_SAMPLES_PER_FRAME;
-  return lsx_check_read_params(ft, 1, 8000., SOX_ENCODING_LPC10, 0, (off_t)0);
+  return lsx_check_read_params(ft, 1, 8000., SOX_ENCODING_LPC10, 0, (off_t)0, sox_false);
 }
 
 static int startwrite(sox_format_t * ft)
--- a/src/sf.c
+++ b/src/sf.c
@@ -112,7 +112,7 @@
   if (lsx_skipbytes(ft, FIXED_HDR - (size_t)lsx_tell(ft)))
     return SOX_EOF;
 
-  return lsx_check_read_params(ft, channels, rate, encoding, bits_per_sample, (off_t)0);
+  return lsx_check_read_params(ft, channels, rate, encoding, bits_per_sample, (off_t)0, sox_false);
 }
 
 static int write_header(sox_format_t * ft)
--- a/src/sounder.c
+++ b/src/sounder.c
@@ -28,7 +28,7 @@
     lsx_fail_errno(ft, SOX_EHDR, "invalid Sounder header");
     return SOX_EOF;
   }
-  return lsx_check_read_params(ft, 1, (sox_rate_t)rate, SOX_ENCODING_UNSIGNED, 8, (off_t)0);
+  return lsx_check_read_params(ft, 1, (sox_rate_t)rate, SOX_ENCODING_UNSIGNED, 8, (off_t)0, sox_false);
 }
 
 static int write_header(sox_format_t * ft)
--- a/src/soundtool.c
+++ b/src/soundtool.c
@@ -39,7 +39,7 @@
   }
   comments[text_field_len] = '\0'; /* Be defensive against incorrect files */
   sox_append_comments(&ft->oob.comments, comments);
-  return lsx_check_read_params(ft, 1, (sox_rate_t)rate, SOX_ENCODING_UNSIGNED, 8, (off_t)0);
+  return lsx_check_read_params(ft, 1, (sox_rate_t)rate, SOX_ENCODING_UNSIGNED, 8, (off_t)nsamples, sox_true);
 }
 
 static int write_header(sox_format_t * ft)
--- a/src/sox-fmt.c
+++ b/src/sox-fmt.c
@@ -68,7 +68,7 @@
   lsx_seeki(ft, (off_t)(headers_bytes - FIXED_HDR - comments_bytes), SEEK_CUR);
 
   return lsx_check_read_params(
-      ft, num_channels, rate, SOX_ENCODING_SIGN2, 32, (off_t)num_samples);
+      ft, num_channels, rate, SOX_ENCODING_SIGN2, 32, (off_t)num_samples, sox_true);
 }
 
 static int write_header(sox_format_t * ft)
--- a/src/sox.c
+++ b/src/sox.c
@@ -1641,6 +1641,7 @@
 "overriden by any of various means including providing output format options.",
 "",
 "-v|--volume FACTOR       Input file volume adjustment factor (real number)",
+"--ignore-length          Ignore input file length given in header; read to EOF",
 "-t|--type FILETYPE       File type of audio",
 "-s/-u/-f/-U/-A/-i/-a/-g  Encoding type=signed-integer/unsigned-integer/floating-",
 "                         point/mu-law/a-law/ima-adpcm/ms-adpcm/gsm-full-rate",
@@ -1830,6 +1831,7 @@
     {"effects-file"    , required_argument, NULL, 0},
     {"temp"            , required_argument, NULL, 0},
     {"single-threaded" ,       no_argument, NULL, 0},
+    {"ignore-length"   ,       no_argument, NULL, 0},
 
     {"bits"            , required_argument, NULL, 'b'},
     {"channels"        , required_argument, NULL, 'c'},
@@ -2020,6 +2022,10 @@
 
       case 17:
         single_threaded = sox_true;
+        break;
+
+      case 18:
+        f->signal.length = SOX_IGNORE_LENGTH;
         break;
 
       }
--- a/src/sox.h
+++ b/src/sox.h
@@ -191,11 +191,13 @@
 
 typedef double sox_rate_t;
 
-typedef struct { /* Signal parameters; 0 if unknown */
+#define SOX_UNSPEC 0
+#define SOX_IGNORE_LENGTH (size_t)(-1)
+typedef struct { /* Signal parameters; SOX_UNSPEC if unknown */
   sox_rate_t       rate;         /* sampling rate */
   unsigned         channels;     /* number of sound channels */
   unsigned         precision;    /* in bits */
-  size_t       length;       /* samples * chans in file; 0 if unknown */
+  size_t           length;       /* samples * chans in file */
 } sox_signalinfo_t;
 
 typedef enum {
--- a/src/sox_i.h
+++ b/src/sox_i.h
@@ -215,7 +215,7 @@
 
 int lsx_check_read_params(sox_format_t * ft, unsigned channels,
     sox_rate_t rate, sox_encoding_t encoding, unsigned bits_per_sample,
-    off_t num_samples);
+    off_t num_samples, sox_bool check_length);
 sox_sample_t lsx_sample_max(sox_encodinginfo_t const * encoding);
 #define SOX_FORMAT_HANDLER(name) \
 sox_format_handler_t const * sox_##name##_format_fn(void); \
--- a/src/sphere.c
+++ b/src/sphere.c
@@ -133,7 +133,7 @@
 
   num_samples = num_samples_ul;
   return lsx_check_read_params(ft, channels, (sox_rate_t)rate, encoding,
-      bytes_per_sample << 3, (off_t)(num_samples * channels));
+      bytes_per_sample << 3, (off_t)(num_samples * channels), sox_true);
 }
 
 static int write_header(sox_format_t * ft)
--- a/src/wav.c
+++ b/src/wav.c
@@ -439,7 +439,7 @@
     uint32_t      dwLoopPos;
 
     ft->sox_errno = SOX_SUCCESS;
-    wav->ignoreSize = 0;
+    wav->ignoreSize = ft->signal.length == SOX_IGNORE_LENGTH;
 
     if (lsx_reads(ft, magic, (size_t)4) == SOX_EOF || (strncmp("RIFF", magic, (size_t)4) != 0 &&
                                              strncmp("RIFX", magic, (size_t)4) != 0))
@@ -844,7 +844,7 @@
      * not mistakenly depend on it.
      */
     if (wav->ignoreSize)
-      ft->signal.length = 0;
+      ft->signal.length = SOX_UNSPEC;
 
     lsx_debug("Reading Wave file: %s format, %d channel%s, %d samp/sec",
            wav_format_str(wav->formatTag), ft->signal.channels,
--- a/src/wve.c
+++ b/src/wve.c
@@ -35,7 +35,7 @@
     lsx_fail_errno(ft, SOX_EHDR, "wve: can't find Psion identifier");
     return SOX_EOF;
   }
-  return lsx_check_read_params(ft, 1, 8000., SOX_ENCODING_ALAW, 8, (off_t)num_samples);
+  return lsx_check_read_params(ft, 1, 8000., SOX_ENCODING_ALAW, 8, (off_t)num_samples, sox_true);
 }
 
 static int write_header(sox_format_t * ft)