Package: sox
Version: 12.17.9-1
Followup-For: Bug #382275

Sorry, I forgot to attach the patch before.

-- System Information:
Debian Release: testing/unstable
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: i386 (i686)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.17-2-686
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8)

Versions of packages sox depends on:
ii  libasound2                1.0.13-1       ALSA library
ii  libc6                     2.3.6.ds1-7    GNU C Library: Shared libraries
ii  libmad0                   0.15.1b-2.1    MPEG audio decoder library
ii  libogg0                   1.1.3-2        Ogg Bitstream Library
ii  libvorbis0a               1.1.2.dfsg-1.2 The Vorbis General Audio Compressi
ii  libvorbisenc2             1.1.2.dfsg-1.2 The Vorbis General Audio Compressi
ii  libvorbisfile3            1.1.2.dfsg-1.2 The Vorbis General Audio Compressi

sox recommends no packages.

-- no debconf information
--- sox-12.18.2/src/mp3.c	2006-11-06 05:59:08.000000000 +0000
+++ sox-12.18.2/src/mp3.c	2006-11-06 07:28:10.000000000 +0000
@@ -13,6 +13,7 @@
 #include "st_i.h"
 
 #include <string.h>
+#include <dlfcn.h>
 
 #if defined(HAVE_LIBMAD) || defined(HAVE_LAME)
 
@@ -47,6 +48,121 @@
 #endif /*HAVE_LAME*/
 };
 
+#if defined(HAVE_LIBMAD) 
+static void (*dl_mad_frame_init)(struct mad_frame *);
+static void (*dl_mad_frame_finish)(struct mad_frame *);
+static int (*dl_mad_frame_decode)(struct mad_frame *, struct mad_stream *);
+static void (*dl_mad_stream_init)(struct mad_stream *);
+static void (*dl_mad_stream_finish)(struct mad_stream *);
+static void (*dl_mad_stream_buffer)(struct mad_stream *, unsigned char const *, unsigned long);
+static char const *(*dl_mad_stream_errorstr)(struct mad_stream const *);
+static void (*dl_mad_stream_skip)(struct mad_stream *, unsigned long);
+static void (*dl_mad_synth_init)(struct mad_synth *);
+static void (*dl_mad_synth_frame)(struct mad_synth *, struct mad_frame const *);
+static void (*dl_mad_timer_add)(mad_timer_t *, mad_timer_t);
+
+#define dl_mad_timer_reset(timer) ((void) (*(timer) = *dl_mad_timer_zero))
+static mad_timer_t const *dl_mad_timer_zero;
+
+#define dl_mad_synth_finish(synth)  /* nothing */
+
+static int load_mad(void) {
+  static int loaded=0;
+  void *library;
+
+  if (loaded) return 0;
+
+  library = dlopen("libmad.so",RTLD_NOW);
+
+   if (!(dl_mad_frame_decode = dlsym(library,"mad_frame_decode")))
+    return -1;
+  if (!(dl_mad_frame_finish = dlsym(library,"mad_frame_finish")))
+    return -1;
+  if (!(dl_mad_frame_init = dlsym(library,"mad_frame_init")))
+    return -1;
+  if (!(dl_mad_stream_buffer = dlsym(library,"mad_stream_buffer")))
+    return -1;
+  if (!(dl_mad_stream_errorstr = dlsym(library,"mad_stream_errorstr")))
+    return -1;
+  if (!(dl_mad_stream_finish = dlsym(library,"mad_stream_finish")))
+    return -1;
+  if (!(dl_mad_stream_init = dlsym(library,"mad_stream_init")))
+    return -1;
+  if (!(dl_mad_stream_skip = dlsym(library,"mad_stream_skip")))
+    return -1;
+  if (!(dl_mad_synth_frame = dlsym(library,"mad_synth_frame")))
+    return -1;
+  if (!(dl_mad_synth_init = dlsym(library,"mad_synth_init")))
+    return -1;
+  if (!(dl_mad_timer_add = dlsym(library,"mad_timer_add")))
+    return -1;
+  if (!(dl_mad_timer_zero = dlsym(library,"mad_timer_zero")))
+    return -1;
+
+  loaded++;
+  return 0;
+}
+#endif 
+
+#if defined(HAVE_LAME)
+static int (*dl_lame_close)(lame_global_flags *);
+static int (*dl_lame_encode_buffer_long2)(
+        lame_global_flags*,      
+        const long     buffer_l [],
+        const long     buffer_r [],
+        const int           ,      
+        unsigned char*      ,       
+        const int           ); 
+static int (*dl_lame_encode_flush)(lame_global_flags *, unsigned char* , int);
+static lame_global_flags *(*dl_lame_init)(void);
+static int (*dl_lame_init_params)(lame_global_flags * const );
+static int (*dl_lame_set_bWriteVbrTag)(lame_global_flags *, int);
+static int (*dl_lame_set_errorf)(lame_global_flags *, void (*func)(const char *, va_list));
+static int (*dl_lame_set_debugf)(lame_global_flags *, void (*func)(const char *, va_list));
+static int (*dl_lame_set_msgf)(lame_global_flags *, void (*func)(const char *, va_list));
+static int (*dl_lame_set_in_samplerate)(lame_global_flags *, int);
+static int (*dl_lame_get_num_channels)(const lame_global_flags *);
+static int (*dl_lame_set_num_channels)(lame_global_flags *, int);
+
+static int load_lame(void)
+{
+  static int loaded=0;
+  void *library;
+
+  if (loaded) return 0;
+
+  library = dlopen("libmp3lame.so",RTLD_NOW);
+
+  if (!(dl_lame_close = dlsym (library, "lame_close")))
+    return -1;
+  if (!(dl_lame_encode_buffer_long2 = dlsym (library, "lame_encode_buffer_long2")))
+    return -1;
+  if (!(dl_lame_encode_flush = dlsym (library, "lame_encode_flush")))
+    return -1;
+  if (!(dl_lame_get_num_channels = dlsym (library, "lame_get_num_channels")))
+    return -1;
+  if (!(dl_lame_init = dlsym (library, "lame_init")))
+    return -1;
+  if (!(dl_lame_init_params = dlsym (library, "lame_init_params")))
+    return -1;
+  if (!(dl_lame_set_bWriteVbrTag = dlsym (library, "lame_set_bWriteVbrTag")))
+    return -1;
+  if (!(dl_lame_set_debugf = dlsym (library, "lame_set_debugf")))
+    return -1;
+  if (!(dl_lame_set_errorf = dlsym (library, "lame_set_errorf")))
+    return -1;
+  if (!(dl_lame_set_in_samplerate = dlsym (library, "lame_set_in_samplerate")))
+    return -1;
+  if (!(dl_lame_set_msgf = dlsym (library, "lame_set_msgf")))
+    return -1;
+  if (!(dl_lame_set_num_channels = dlsym (library, "lame_set_num_channels")))
+    return -1;
+
+  loaded++;
+  return 0;
+}
+#endif /*HAVE_LAME*/
+
 #if defined(HAVE_LIBMAD)
 
 /* This function merges the functions tagtype() and id3_tag_query()
@@ -82,6 +198,11 @@
         struct mp3priv *p = (struct mp3priv *) ft->priv;
         size_t ReadSize;
 
+        if (load_mad()) {
+          st_fail_errno(ft,ST_EOF,"SoX was compiled without MP3 decoding support");
+          return ST_EOF;
+        }
+
         p->Stream=(struct mad_stream *)malloc(sizeof(struct mad_stream));
         if (p->Stream == NULL){
           st_fail_errno(ft, ST_ENOMEM, "Could not allocate memory");
@@ -122,10 +243,10 @@
           return ST_EOF;
         }
         
-        mad_stream_init(p->Stream);
-        mad_frame_init(p->Frame);
-        mad_synth_init(p->Synth);
-        mad_timer_reset(p->Timer);
+        dl_mad_stream_init(p->Stream);
+        dl_mad_frame_init(p->Frame);
+        dl_mad_synth_init(p->Synth);
+        dl_mad_timer_reset(p->Timer);
 
         ft->info.encoding = ST_ENCODING_MP3;
         ft->info.size = ST_SIZE_WORD;
@@ -143,14 +264,14 @@
                 return(ST_EOF);
         }
         
-        mad_stream_buffer(p->Stream,p->InputBuffer,ReadSize);
+        dl_mad_stream_buffer(p->Stream,p->InputBuffer,ReadSize);
         p->Stream->error = 0;
 
         /* Find a valid frame before starting up.  This makes sure
          * that we have a valid MP3 and also skips past ID3v2 tags
          * at the beginning of the audio file.
          */
-        while(mad_frame_decode(p->Frame,p->Stream)) {
+        while(dl_mad_frame_decode(p->Frame,p->Stream)) {
             int tagsize;
             size_t remaining;
 
@@ -166,7 +287,7 @@
                 }
 
                 remaining+=ReadSize;
-                mad_stream_buffer(p->Stream, p->InputBuffer, remaining);
+                dl_mad_stream_buffer(p->Stream, p->InputBuffer, remaining);
                 p->Stream->error = 0;
             }
 
@@ -200,7 +321,7 @@
                 goto more_data;
             }
 
-            mad_stream_skip(p->Stream, tagsize);
+            dl_mad_stream_skip(p->Stream, tagsize);
         }
 
         /* TODO: It would be nice to look for Xing VBR headers
@@ -226,8 +347,8 @@
         p->FrameCount=1;
         ft->info.rate=p->Frame->header.samplerate;
 
-        mad_timer_add(p->Timer,p->Frame->header.duration);
-        mad_synth_frame(p->Synth,p->Frame);
+        dl_mad_timer_add(p->Timer,p->Frame->header.duration);
+        dl_mad_synth_frame(p->Synth,p->Frame);
         p->cursamp = 0;
         p->eof     = 0;
 
@@ -248,6 +369,11 @@
   mad_fixed_t sample;
   int chan;
 
+  if (load_mad()) {
+    st_fail_errno(ft,ST_EOF,"SoX was compiled without MP3 decoding support");
+    return ST_EOF;
+  }
+
   do{
     donow=MIN(len,(p->Synth->pcm.length - p->cursamp)*ft->info.channels);
     i=0;
@@ -297,20 +423,20 @@
           ReadSize=MAD_BUFFER_GUARD;
         }
 
-        mad_stream_buffer(p->Stream,p->InputBuffer,ReadSize+Remaining);
+        dl_mad_stream_buffer(p->Stream,p->InputBuffer,ReadSize+Remaining);
         p->Stream->error = 0;
       }
 
-    if(mad_frame_decode(p->Frame,p->Stream)){
+    if(dl_mad_frame_decode(p->Frame,p->Stream)){
       if(MAD_RECOVERABLE(p->Stream->error))
         {
           int tagsize;
           if ( (tagsize=tagtype(p->Stream->this_frame, p->Stream->bufend - p->Stream->this_frame)) == 0){
             if (!p->eof)
               st_report("recoverable frame level error (%s).\n",
-                        mad_stream_errorstr(p->Stream));
+                        dl_mad_stream_errorstr(p->Stream));
           }
-          else mad_stream_skip(p->Stream,tagsize);
+          else dl_mad_stream_skip(p->Stream,tagsize);
           continue;
         }
       else
@@ -320,14 +446,14 @@
           else
             {
               st_report("unrecoverable frame level error (%s).\n",
-                        mad_stream_errorstr(p->Stream));
+                        dl_mad_stream_errorstr(p->Stream));
               return done;
             }
         }
     }
     p->FrameCount++;
-    mad_timer_add(p->Timer,p->Frame->header.duration);
-    mad_synth_frame(p->Synth,p->Frame);
+    dl_mad_timer_add(p->Timer,p->Frame->header.duration);
+    dl_mad_synth_frame(p->Synth,p->Frame);
     p->cursamp=0;
   }while(1);
 
@@ -338,9 +464,14 @@
 {
   struct mp3priv *p=(struct mp3priv*) ft->priv;
 
-  mad_synth_finish(p->Synth);
-  mad_frame_finish(p->Frame);
-  mad_stream_finish(p->Stream);
+  if (load_mad()) {
+    st_fail_errno(ft,ST_EOF,"SoX was compiled without MP3 decoding support");
+    return ST_EOF;
+  }
+
+  dl_mad_synth_finish(p->Synth);
+  dl_mad_frame_finish(p->Frame);
+  dl_mad_stream_finish(p->Stream);
 
   free(p->Stream);
   free(p->Frame);
@@ -378,6 +509,11 @@
 int st_mp3startwrite(ft_t ft)
 {
   struct mp3priv *p = (struct mp3priv *) ft->priv;
+
+  if (load_lame()) {
+    st_fail_errno(ft,ST_EOF,"Sorry, no MP3 encoding support");
+    return ST_EOF;
+  }
   
   if (ft->info.encoding != ST_ENCODING_MP3){
     if(ft->info.encoding != -1)
@@ -385,35 +521,35 @@
     ft->info.encoding = ST_ENCODING_MP3;
   }
 
-  p->gfp = lame_init();
+  p->gfp = dl_lame_init();
   if (p->gfp == NULL){
     st_fail_errno(ft,ST_EOF,"Initialization of LAME library failed");
     return(ST_EOF);
   }
 
   if (ft->info.channels != -1){
-    if ( (lame_set_num_channels(p->gfp,ft->info.channels)) < 0) {
+    if ( (dl_lame_set_num_channels(p->gfp,ft->info.channels)) < 0) {
         st_fail_errno(ft,ST_EOF,"Unsupported number of channels");
         return(ST_EOF);
     }
   }
   else
-    ft->info.channels = lame_get_num_channels(p->gfp); /* LAME default */
+    ft->info.channels = dl_lame_get_num_channels(p->gfp); /* LAME default */
 
-  lame_set_in_samplerate(p->gfp,ft->info.rate);
+  dl_lame_set_in_samplerate(p->gfp,ft->info.rate);
 
-  lame_set_bWriteVbrTag(p->gfp, 0); /* disable writing VBR tag */
+  dl_lame_set_bWriteVbrTag(p->gfp, 0); /* disable writing VBR tag */
 
   /* The bitrate, mode, quality and other settings are the default ones,
      since SoX's command line options do not allow to set them */
 
-  if (lame_init_params(p->gfp) < 0){
+  if (dl_lame_init_params(p->gfp) < 0){
         st_fail_errno(ft,ST_EOF,"LAME initialization failed");
         return(ST_EOF);
   }
-  lame_set_errorf(p->gfp,null_error_func);
-  lame_set_debugf(p->gfp,null_error_func);
-  lame_set_msgf  (p->gfp,null_error_func);
+  dl_lame_set_errorf(p->gfp,null_error_func);
+  dl_lame_set_debugf(p->gfp,null_error_func);
+  dl_lame_set_msgf  (p->gfp,null_error_func);
 
   return(ST_SUCCESS);
 }
@@ -429,6 +565,11 @@
   st_ssize_t done = 0;
   int written;
 
+  if (load_lame()) {
+    st_fail_errno(ft,ST_EOF,"Sorry, no MP3 encoding support");
+    return ST_EOF;
+  }
+
   if ( (buffer_r=(long*)malloc(nsamples*sizeof(long))) == NULL){
     st_fail_errno(ft,ST_ENOMEM,"Memory allocation failed");
     goto end4;
@@ -456,7 +597,7 @@
     goto end2;
   }
  
-  if ( (written = lame_encode_buffer_long2(p->gfp,
+  if ( (written = dl_lame_encode_buffer_long2(p->gfp,
                                            buffer_l,
                                            buffer_r,
                                            nsamples,
@@ -489,15 +630,20 @@
   struct mp3priv *p = (struct mp3priv *) ft->priv;
   char mp3buffer[7200];
   int written;
+
+  if (load_lame()) {
+    st_fail_errno(ft,ST_EOF,"Sorry, no MP3 encoding support");
+    return ST_EOF;
+  }
   
-  if ( (written=lame_encode_flush(p->gfp, (unsigned char *)mp3buffer, 7200)) <0){
+  if ( (written=dl_lame_encode_flush(p->gfp, (unsigned char *)mp3buffer, 7200)) <0){
     st_fail_errno(ft,ST_EOF,"Encoding failed");
   }
   else if (st_writebuf(ft, mp3buffer, 1, written) < written){
     st_fail_errno(ft,ST_EOF,"File write failed");
   }
 
-  lame_close(p->gfp);
+  dl_lame_close(p->gfp);
   return ST_SUCCESS;
 }
 

Reply via email to