shithub: sox

Download patch

ref: 1f10ca1069d145f9d77575375b1f7a0bbd548c42
parent: 39c1f29555cf6a4607d4d975767d54154fdda7a6
author: rrt <rrt>
date: Sun Dec 17 18:53:12 EST 2006

Make the code a bit more robust, and make the compression arrays local
to compress, as only it and its direct callees need them.

--- a/src/hcom.c
+++ b/src/hcom.c
@@ -48,10 +48,7 @@
         uint32_t current;
         short sample;
         /* Dictionary */
-        dictent *newdict;
         dictent *de;
-        long *codes;
-        long *codesize;
         int32_t new_checksum;
         int nbits;
         int32_t curword;
@@ -300,27 +297,26 @@
   return len;
 }
 
-static void makecodes(ft_t ft, int e, int c, int s, int b)
+static void makecodes(int e, int c, int s, int b, dictent newdict[511], long codes[256], long codesize[256])
 {
-  struct readpriv *p = (struct readpriv *)ft->priv;
-  if(p->newdict[e].dict_leftson < 0) {
-    p->codes[p->newdict[e].dict_rightson] = c;
-    p->codesize[p->newdict[e].dict_rightson] = s;
+  assert(b);                    /* Prevent stack overflow */
+  if (newdict[e].dict_leftson < 0) {
+    codes[newdict[e].dict_rightson] = c;
+    codesize[newdict[e].dict_rightson] = s;
   } else {
-    makecodes(ft, p->newdict[e].dict_leftson, c, s + 1, b << 1);
-    makecodes(ft, p->newdict[e].dict_rightson, c + b, s + 1, b << 1);
+    makecodes(newdict[e].dict_leftson, c, s + 1, b << 1, newdict, codes, codesize);
+    makecodes(newdict[e].dict_rightson, c + b, s + 1, b << 1, newdict, codes, codesize);
   }
 }
 
-
-static void putcode(ft_t ft, unsigned char c, unsigned char **df)
+static void putcode(ft_t ft, long codes[256], long codesize[256], unsigned char c, unsigned char **df)
 {
   struct readpriv *p = (struct readpriv *) ft->priv;
   long code, size;
   int i;
 
-  code = p->codes[c];
-  size = p->codesize[c];
+  code = codes[c];
+  size = codesize[c];
   for(i = 0; i < size; i++) {
     p->curword <<= 1;
     if (code & 1)
@@ -344,14 +340,16 @@
   unsigned char *ddf, *dfp;
   short dictsize;
   int frequtable[256];
+  long codes[256], codesize[256];
+  dictent newdict[511];
   int i, sample, j, k, d, l, frequcount;
 
-  p->newdict = (dictent *)xmalloc(511 * sizeof(dictent));
-  p->codes = (long *)xcalloc(256, sizeof(long));
-  p->codesize = (long *)xcalloc(256, sizeof(long));
-  
   sample = *datafork;
-  memset(frequtable, 0, sizeof(int) * 256);
+  memset(frequtable, 0, sizeof(frequtable));
+  memset(codes, 0, sizeof(codes));
+  memset(codesize, 0, sizeof(codesize));
+  memset(newdict, 0, sizeof(newdict));
+  
   for (i = 1; i < *dl; i++) {
     d = (datafork[i] - (sample & 0xff)) & 0xff; /* creates absolute entries LMS */
     sample = datafork[i];
@@ -359,7 +357,7 @@
     assert(d >= 0 && d <= 255); /* check our table is accessed correctly */
     frequtable[d]++;
   }
-  p->de = p->newdict;
+  p->de = newdict;
   for (i = 0; i < 256; i++)
     if (frequtable[i] != 0) {
       p->de->frequ = -frequtable[i];
@@ -367,42 +365,42 @@
       p->de->dict_rightson = i;
       p->de++;
     }
-  frequcount = p->de - p->newdict;
+  frequcount = p->de - newdict;
   for (i = 0; i < frequcount; i++) {
     for (j = i + 1; j < frequcount; j++) {
-      if (p->newdict[i].frequ > p->newdict[j].frequ) {
-        k = p->newdict[i].frequ;
-        p->newdict[i].frequ = p->newdict[j].frequ;
-        p->newdict[j].frequ = k;
-        k = p->newdict[i].dict_leftson;
-        p->newdict[i].dict_leftson = p->newdict[j].dict_leftson;
-        p->newdict[j].dict_leftson = k;
-        k = p->newdict[i].dict_rightson;
-        p->newdict[i].dict_rightson = p->newdict[j].dict_rightson;
-        p->newdict[j].dict_rightson = k;
+      if (newdict[i].frequ > newdict[j].frequ) {
+        k = newdict[i].frequ;
+        newdict[i].frequ = newdict[j].frequ;
+        newdict[j].frequ = k;
+        k = newdict[i].dict_leftson;
+        newdict[i].dict_leftson = newdict[j].dict_leftson;
+        newdict[j].dict_leftson = k;
+        k = newdict[i].dict_rightson;
+        newdict[i].dict_rightson = newdict[j].dict_rightson;
+        newdict[j].dict_rightson = k;
       }
     }
   }
   while (frequcount > 1) {
     j = frequcount - 1;
-    p->de->frequ = p->newdict[j - 1].frequ;
-    p->de->dict_leftson = p->newdict[j - 1].dict_leftson;
-    p->de->dict_rightson = p->newdict[j - 1].dict_rightson;
-    l = p->newdict[j - 1].frequ + p->newdict[j].frequ;
-    for (i = j - 2; i >= 0 && l < p->newdict[i].frequ; i--)
-      p->newdict[i + 1] = p->newdict[i];
+    p->de->frequ = newdict[j - 1].frequ;
+    p->de->dict_leftson = newdict[j - 1].dict_leftson;
+    p->de->dict_rightson = newdict[j - 1].dict_rightson;
+    l = newdict[j - 1].frequ + newdict[j].frequ;
+    for (i = j - 2; i >= 0 && l < newdict[i].frequ; i--)
+      newdict[i + 1] = newdict[i];
     i = i + 1;
-    p->newdict[i].frequ = l;
-    p->newdict[i].dict_leftson = j;
-    p->newdict[i].dict_rightson = p->de - p->newdict;
+    newdict[i].frequ = l;
+    newdict[i].dict_leftson = j;
+    newdict[i].dict_rightson = p->de - newdict;
     p->de++;
     frequcount--;
   }
-  dictsize = p->de - p->newdict;
-  makecodes(ft, 0, 0, 0, 1);
+  dictsize = p->de - newdict;
+  makecodes(0, 0, 0, 1, newdict, codes, codesize);
   l = 0;
   for (i = 0; i < 256; i++)
-    l += frequtable[i] * p->codesize[i];
+    l += frequtable[i] * codesize[i];
   l = (((l + 31) >> 5) << 2) + 24 + dictsize * 4;
   st_debug("  Original size: %6d bytes", *dl);
   st_debug("Compressed size: %6d bytes", l);
@@ -409,8 +407,8 @@
   datafork = (unsigned char *)xmalloc((unsigned)l);
   ddf = datafork + 22;
   for(i = 0; i < dictsize; i++) {
-    put16_be(&ddf, p->newdict[i].dict_leftson);
-    put16_be(&ddf, p->newdict[i].dict_rightson);
+    put16_be(&ddf, newdict[i].dict_leftson);
+    put16_be(&ddf, newdict[i].dict_rightson);
   }
   *ddf++ = 0;
   *ddf++ = *(*df)++;
@@ -418,11 +416,11 @@
   p->nbits = 0;
   p->curword = 0;
   for (i = 1; i < *dl; i++)
-    putcode(ft, *(*df)++, &ddf);
+    putcode(ft, codes, codesize, *(*df)++, &ddf);
   if (p->nbits != 0) {
-    p->codes[0] = 0;
-    p->codesize[0] = 32 - p->nbits;
-    putcode(ft, 0, &ddf);
+    codes[0] = 0;
+    codesize[0] = 32 - p->nbits;
+    putcode(ft, codes, codesize, 0, &ddf);
   }
   strncpy((char *)datafork, "HCOM", 4);
   dfp = datafork + 4;
@@ -434,10 +432,6 @@
   put16_be(&dfp, dictsize);
   *df = datafork;               /* reassign passed pointer to new datafork */
   *dl = l;                      /* and its compressed length */
-
-  free(p->newdict);
-  free(p->codes);
-  free(p->codesize);
 }
 
 /* End of hcom utility routines */
@@ -450,8 +444,9 @@
   int rc = ST_SUCCESS;
 
   /* Compress it all at once */
-  compress(ft, &compressed_data, (int32_t *)&compressed_len, (double) ft->info.rate);
-  free((char *) p->data);
+  if (compressed_len)
+    compress(ft, &compressed_data, (int32_t *)&compressed_len, (double) ft->info.rate);
+  free((char *)p->data);
 
   /* Write the header */
   st_writebuf(ft, (void *)"\000\001A", 1, 3); /* Dummy file name "A" */
@@ -473,7 +468,7 @@
 
   if (rc == ST_SUCCESS)
     /* Pad the compressed_data fork to a multiple of 128 bytes */
-    st_padbytes(ft, 128 - (int) (compressed_len%128));
+    st_padbytes(ft, 128 - (int) (compressed_len % 128));
 
   return rc;
 }