Added a return value (error) to the *ctl functions, added re-allocation
authorjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Wed, 8 Jan 2003 21:59:00 +0000 (21:59 +0000)
committerjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Wed, 8 Jan 2003 21:59:00 +0000 (21:59 +0000)
to SpeexBits when buffer is too small.

git-svn-id: http://svn.xiph.org/trunk/speex@4217 0101bb08-14d6-0310-b084-bc0e0c8e3800

libspeex/bits.c
libspeex/misc.c
libspeex/misc.h
libspeex/modes.c
libspeex/nb_celp.c
libspeex/nb_celp.h
libspeex/sb_celp.c
libspeex/sb_celp.h
libspeex/speex.h
libspeex/speex_bits.h
src/speexdec.c

index cd48254..4578b10 100644 (file)
@@ -39,8 +39,9 @@ void speex_bits_init(SpeexBits *bits)
 {
    int i;
    bits->bytes = (char*)speex_alloc(MAX_BYTES_PER_FRAME);
+   bits->buf_size = MAX_BYTES_PER_FRAME;
 
-   for (i=0;i<MAX_BYTES_PER_FRAME;i++)
+   for (i=0;i<bits->buf_size;i++)
       bits->bytes[i]=0;
    bits->nbBits=0;
    bits->bytePtr=0;
@@ -49,12 +50,13 @@ void speex_bits_init(SpeexBits *bits)
    bits->overflow=0;
 }
 
-void speex_bits_init_buffer(SpeexBits *bits, void *buff)
+void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size)
 {
    int i;
    bits->bytes = (char*)buff;
+   bits->buf_size = buf_size;
 
-   for (i=0;i<MAX_BYTES_PER_FRAME;i++)
+   for (i=0;i<buf_size;i++)
       bits->bytes[i]=0;
    bits->nbBits=0;
    bits->bytePtr=0;
@@ -73,7 +75,7 @@ void speex_bits_destroy(SpeexBits *bits)
 void speex_bits_reset(SpeexBits *bits)
 {
    int i;
-   for (i=0;i<MAX_BYTES_PER_FRAME;i++)
+   for (i=0;i<bits->buf_size;i++)
       bits->bytes[i]=0;
    bits->nbBits=0;
    bits->bytePtr=0;
@@ -91,9 +93,24 @@ void speex_bits_rewind(SpeexBits *bits)
 void speex_bits_read_from(SpeexBits *bits, char *bytes, int len)
 {
    int i;
-   if (len > MAX_BYTES_PER_FRAME)
+   if (len > bits->buf_size)
    {
-      speex_error ("Trying to init frame with too many bits");
+      speex_warning_int("Packet if larger than allocated buffer: ", len);
+      if (bits->owner)
+      {
+         char *tmp = speex_realloc(bits->bytes, len);
+         if (tmp)
+         {
+            bits->buf_size=len;
+            bits->bytes=tmp;
+         } else {
+            len=bits->buf_size;
+            speex_warning("Could not resize input buffer: truncating input");
+         }
+      } else {
+         speex_warning("Do not own input buffer: truncating input");
+         len=bits->buf_size;
+      }
    }
    for (i=0;i<len;i++)
       bits->bytes[i]=bytes[i];
@@ -118,6 +135,7 @@ void speex_bits_flush(SpeexBits *bits)
 void speex_bits_read_whole_bytes(SpeexBits *bits, char *bytes, int len)
 {
    int i,pos;
+   /*FIXME: check for overflow*/
    speex_bits_flush(bits);
    pos=bits->nbBits>>3;
    for (i=0;i<len;i++)
@@ -158,6 +176,7 @@ int speex_bits_write_whole_bytes(SpeexBits *bits, char *bytes, int max_len)
 void speex_bits_pack(SpeexBits *bits, int data, int nbBits)
 {
    unsigned int d=data;
+   /*FIXME: check for overflow*/
    while(nbBits)
    {
       int bit;
index 6a33043..f84e0f6 100644 (file)
@@ -95,6 +95,11 @@ void *speex_alloc (int size)
    return calloc(size,1);
 }
 
+void *speex_realloc (void *ptr, int size)
+{
+   return realloc(ptr, size);
+}
+
 void speex_free (void *ptr)
 {
    free(ptr);
index 0e81126..cb702e3 100644 (file)
@@ -50,10 +50,13 @@ unsigned int le_int(unsigned int i);
 unsigned short be_short(unsigned short s);
 unsigned short le_short(unsigned short s);
 
-/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function and speex_free */
+/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_free */
 void *speex_alloc (int size);
 
-/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function and speex_alloc */
+/** Speex wrapper for realloc. To do your own dynamic allocation, all you need to do is replace this function, speex_alloc and speex_free */
+void *speex_realloc (void *ptr, int size);
+
+/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_alloc */
 void speex_free (void *ptr);
 
 /** Speex wrapper for mem_move */
index 024dec5..2e02216 100644 (file)
@@ -58,8 +58,8 @@ extern float exc_10_32_table[];
 extern float exc_10_16_table[];
 extern float hexc_10_32_table[];
 
-static void nb_mode_query(void *mode, int request, void *ptr);
-static void wb_mode_query(void *mode, int request, void *ptr);
+static int nb_mode_query(void *mode, int request, void *ptr);
+static int wb_mode_query(void *mode, int request, void *ptr);
 
 /* Parameters for Long-Term Prediction (LTP)*/
 static ltp_params ltp_params_nb = {
@@ -549,19 +549,19 @@ int speex_decode(void *state, SpeexBits *bits, float *out)
 }
 
 
-void speex_encoder_ctl(void *state, int request, void *ptr)
+int speex_encoder_ctl(void *state, int request, void *ptr)
 {
-   (*((SpeexMode**)state))->enc_ctl(state, request, ptr);
+   return (*((SpeexMode**)state))->enc_ctl(state, request, ptr);
 }
 
-void speex_decoder_ctl(void *state, int request, void *ptr)
+int speex_decoder_ctl(void *state, int request, void *ptr)
 {
-   (*((SpeexMode**)state))->dec_ctl(state, request, ptr);
+   return (*((SpeexMode**)state))->dec_ctl(state, request, ptr);
 }
 
 
 
-static void nb_mode_query(void *mode, int request, void *ptr)
+static int nb_mode_query(void *mode, int request, void *ptr)
 {
    SpeexNBMode *m = (SpeexNBMode*)mode;
    
@@ -580,11 +580,12 @@ static void nb_mode_query(void *mode, int request, void *ptr)
       break;
    default:
       speex_warning_int("Unknown nb_mode_query request: ", request);
+      return -1;
    }
-
+   return 0;
 }
 
-static void wb_mode_query(void *mode, int request, void *ptr)
+static int wb_mode_query(void *mode, int request, void *ptr)
 {
    SpeexSBMode *m = (SpeexSBMode*)mode;
 
@@ -603,11 +604,13 @@ static void wb_mode_query(void *mode, int request, void *ptr)
       break;
    default:
       speex_warning_int("Unknown wb_mode_query request: ", request);
+      return -1;
    }
+   return 0;
 }
 
 
-void speex_mode_query(SpeexMode *mode, int request, void *ptr)
+int speex_mode_query(SpeexMode *mode, int request, void *ptr)
 {
-   mode->query(mode->mode, request, ptr);
+   return mode->query(mode->mode, request, ptr);
 }
index d72a81d..51ca5de 100644 (file)
@@ -1086,6 +1086,7 @@ int nb_decode(void *state, SpeexBits *bits, float *out)
                return ret;
          } else if (m>7) /* Invalid mode */
          {
+            speex_warning("Invalid mode encountered: corrupted stream?");
             return -2;
          }
       
@@ -1458,7 +1459,7 @@ int nb_decode(void *state, SpeexBits *bits, float *out)
    return 0;
 }
 
-void nb_encoder_ctl(void *state, int request, void *ptr)
+int nb_encoder_ctl(void *state, int request, void *ptr)
 {
    EncState *st;
    st=(EncState*)state;     
@@ -1613,10 +1614,12 @@ void nb_encoder_ctl(void *state, int request, void *ptr)
       break;
    default:
       speex_warning_int("Unknown nb_ctl request: ", request);
+      return -1;
    }
+   return 0;
 }
 
-void nb_decoder_ctl(void *state, int request, void *ptr)
+int nb_decoder_ctl(void *state, int request, void *ptr)
 {
    DecState *st;
    st=(DecState*)state;
@@ -1701,5 +1704,7 @@ void nb_decoder_ctl(void *state, int request, void *ptr)
       break;
    default:
       speex_warning_int("Unknown nb_ctl request: ", request);
+      return -1;
    }
+   return 0;
 }
index 0ac1275..71f8a9d 100644 (file)
@@ -193,10 +193,10 @@ void nb_decoder_destroy(void *state);
 int nb_decode(void *state, SpeexBits *bits, float *out);
 
 /** ioctl-like function for controlling a narrowband encoder */
-void nb_encoder_ctl(void *state, int request, void *ptr);
+int nb_encoder_ctl(void *state, int request, void *ptr);
 
 /** ioctl-like function for controlling a narrowband decoder */
-void nb_decoder_ctl(void *state, int request, void *ptr);
+int nb_decoder_ctl(void *state, int request, void *ptr);
 
 
 #endif
index de36390..c1c2142 100644 (file)
@@ -844,7 +844,11 @@ int sb_decode(void *state, SpeexBits *bits, float *out)
       /*Was a narrowband frame, set "null submode"*/
       st->submodeID = 0;
    }
-   /*FIXME: Check for valid submodeID */
+   if (st->submodeID != 0 && st->submodes[st->submodeID] == NULL)
+   {
+      speex_warning("Invalid mode encountered: corrupted stream?");
+      return -2;
+   }
 
    /* If null mode (no transmission), just set a couple things to zero*/
    if (st->submodes[st->submodeID] == NULL)
@@ -1043,7 +1047,7 @@ int sb_decode(void *state, SpeexBits *bits, float *out)
 }
 
 
-void sb_encoder_ctl(void *state, int request, void *ptr)
+int sb_encoder_ctl(void *state, int request, void *ptr)
 {
    SBEncState *st;
    st=(SBEncState*)state;
@@ -1230,11 +1234,12 @@ void sb_encoder_ctl(void *state, int request, void *ptr)
       break;
    default:
       speex_warning_int("Unknown nb_ctl request: ", request);
+      return -1;
    }
-
+   return 0;
 }
 
-void sb_decoder_ctl(void *state, int request, void *ptr)
+int sb_decoder_ctl(void *state, int request, void *ptr)
 {
    SBDecState *st;
    st=(SBDecState*)state;
@@ -1316,6 +1321,7 @@ void sb_decoder_ctl(void *state, int request, void *ptr)
       break;
    default:
       speex_warning_int("Unknown nb_ctl request: ", request);
+      return -1;
    }
-
+   return 0;
 }
index 00184f5..64b23ee 100644 (file)
@@ -160,8 +160,8 @@ void sb_decoder_destroy(void *state);
 /**Decodes one frame*/
 int sb_decode(void *state, SpeexBits *bits, float *out);
 
-void sb_encoder_ctl(void *state, int request, void *ptr);
+int sb_encoder_ctl(void *state, int request, void *ptr);
 
-void sb_decoder_ctl(void *state, int request, void *ptr);
+int sb_decoder_ctl(void *state, int request, void *ptr);
 
 #endif
index 2646f76..46a1c46 100644 (file)
@@ -171,7 +171,7 @@ typedef void (*encoder_destroy_func)(void *st);
 typedef int (*encode_func)(void *state, float *in, SpeexBits *bits);
 
 /** Function for controlling the encoder options */
-typedef void (*encoder_ctl_func)(void *state, int request, void *ptr);
+typedef int (*encoder_ctl_func)(void *state, int request, void *ptr);
 
 /** Decoder state initialization function */
 typedef void *(*decoder_init_func)(struct SpeexMode *mode);
@@ -183,11 +183,11 @@ typedef void (*decoder_destroy_func)(void *st);
 typedef int  (*decode_func)(void *state, SpeexBits *bits, float *out);
 
 /** Function for controlling the decoder options */
-typedef void (*decoder_ctl_func)(void *state, int request, void *ptr);
+typedef int (*decoder_ctl_func)(void *state, int request, void *ptr);
 
 
 /** Query function for a mode */
-typedef void (*mode_query_func)(void *mode, int request, void *ptr);
+typedef int (*mode_query_func)(void *mode, int request, void *ptr);
 
 /** Struct defining a Speex mode */ 
 typedef struct SpeexMode {
@@ -263,7 +263,7 @@ int speex_encode(void *state, float *in, SpeexBits *bits);
  * @param ptr Data exchanged to-from function
  * @return 0 if frame needs not be transmitted (DTX only), 1 otherwise
  */
-void speex_encoder_ctl(void *state, int request, void *ptr);
+int speex_encoder_ctl(void *state, int request, void *ptr);
 
 
 /** Returns a handle to a newly created decoder state structure. For now, 
@@ -299,7 +299,7 @@ int speex_decode(void *state, SpeexBits *bits, float *out);
  * @param ptr Data exchanged to-from function
  * @return 0 for no error, 1 if a terminator is reached, 2 for another error
  */
-void speex_decoder_ctl(void *state, int request, void *ptr);
+int speex_decoder_ctl(void *state, int request, void *ptr);
 
 
 /** Query function for mode information
@@ -308,7 +308,7 @@ void speex_decoder_ctl(void *state, int request, void *ptr);
  * @param request ioctl-type request (one of the SPEEX_* macros)
  * @param ptr Data exchanged to-from function
  */
-void speex_mode_query(SpeexMode *mode, int request, void *ptr);
+int speex_mode_query(SpeexMode *mode, int request, void *ptr);
 
 
 /** Default narrowband mode */
index 22416e3..18898a4 100644 (file)
@@ -51,13 +51,14 @@ typedef struct SpeexBits {
    int   bitPtr;  /**< Position of the bit "cursor" within the current byte */
    int   owner;   /**< Does the struct "own" the "raw" buffer (member "bytes") */
    int   overflow;/**< Set to one if we try to read past the valid data */
+   int   buf_size;/**< Allocated size for buffer */
 } SpeexBits;
 
 /** Initializes and allocates resources for a SpeexBits struct */
 void speex_bits_init(SpeexBits *bits);
 
 /** Initializes SpeexBits struct using a pre-allocated buffer*/
-void speex_bits_init_buffer(SpeexBits *bits, void *buff);
+void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size);
 
 /** Frees all resources assiociated to a SpeexBits struct. Right now this does nothing since no resources are allocated, but this could change in the future.*/
 void speex_bits_destroy(SpeexBits *bits);
index b5b8c1b..cac216b 100644 (file)
@@ -272,7 +272,7 @@ static void *process_header(ogg_packet *op, int enh_enabled, int *frame_size, in
    }
    if (header->mode >= SPEEX_NB_MODES)
    {
-      fprintf (stderr, "Mode number %d does not (any longer) exist in this version\n", 
+      fprintf (stderr, "Mode number %d does not (yet/any longer) exist in this version\n", 
                header->mode);
       return NULL;
    }
@@ -325,10 +325,15 @@ static void *process_header(ogg_packet *op, int enh_enabled, int *frame_size, in
    fprintf (stderr, "Decoding %d Hz audio using %s mode", 
             *rate, mode->modeName);
 
+   if (*channels==1)
+      fprintf (stderr, " (mono");
+   else
+      fprintf (stderr, " (stereo");
+      
    if (header->vbr)
-      fprintf (stderr, " (VBR)\n");
+      fprintf (stderr, "VBR)\n");
    else
-      fprintf(stderr, "\n");
+      fprintf(stderr, ")\n");
    /*fprintf (stderr, "Decoding %d Hz audio at %d bps using %s mode\n", 
     *rate, mode->bitrate, mode->modeName);*/