modified varicode decoder to retain state between calls so it can be interrupted...
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sun, 25 Nov 2012 09:27:04 +0000 (09:27 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sun, 25 Nov 2012 09:27:04 +0000 (09:27 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1064 01035d8c-6547-0410-b346-abe4f91aad63

fdmdv2/src/varicode.c
fdmdv2/src/varicode.h

index 31c64e22ec6cffe3ff583ade6d2d84624dbb4020..165f9b33e253a0ce3a8241010782a95406c75355 100644 (file)
@@ -81,79 +81,116 @@ int varicode_encode(int varicode_out[], char ascii_in[], int max_out, int n_in)
     return n_out;
 }
 
-int varicode_decode(char ascii_out[], int varicode_in[], int max_out, int n_in) {
-    int            i, n_out, n_zeros, found, v_len;
-    unsigned short byte1, byte2, packed;
+void varicode_decode_init(struct VARICODE_DEC *dec_states)
+{
+    dec_states->n_zeros = 0;
+    dec_states->v_len = 0;
+    dec_states->packed = 0;
+}
 
-    n_out = 0;
+static int decode_one_bit(struct VARICODE_DEC *s, char *single_ascii, int varicode_in)
+{
+    int            found, i;
+    unsigned short byte1, byte2;
 
-    //printf("max_out: %d n_in: %d\n", max_out, n_in);
-    while(n_in && (n_out < max_out)) {
-        
-        n_zeros = 0;
-        v_len = 0;
-        packed = 0;
-        while ((n_zeros < 2) && n_in && (v_len <= VARICODE_MAX_BITS)) {
-            if (*varicode_in++) {
-                packed |= (0x8000 >> v_len);
-                n_zeros = 0;
-            }
-            else {
-                n_zeros++;
-            }
-            n_in--;
-            v_len++;
-        }
-        
-        //printf("packed: 0x%x n_zeros: %d v_len: %d n_in: %d\n", packed, n_zeros, v_len, n_in);
-      
-        /* v_len might be > VARICODE_MAX_BITS is an error condition */
+    if (varicode_in) {
+        s->packed |= (0x8000 >> s->v_len);
+        s->n_zeros = 0;
+    }
+    else {
+        s->n_zeros++;
+    }
+    s->v_len++;
 
-        if (v_len && (v_len <= VARICODE_MAX_BITS)) {
-            byte1 = packed >> 8;
-            byte2 = packed & 0xff;
+    found = 0;
+
+    /* end of character code */
+
+    if (s->n_zeros == 2) {
+        if (s->v_len) {
+            byte1 = s->packed >> 8;
+            byte2 = s->packed & 0xff;
+
+            /* run thru table but note with bit errors means we might
+               not actually find a match */
 
-            found = 0;
             for(i=0; i<128; i++) {
                 if ((byte1 == varicode_table[2*i]) && (byte2 == varicode_table[2*i+1])) {
                     found = 1;
-                    //printf("%c\n", (char)i);
-                    *ascii_out++ = i;
+                    *single_ascii = i;
                 }
             }
-            if (found == 1)
-                n_out++;
         }
-        //printf("n_out: %d n_in: %d\n", n_out, n_in);
+        varicode_decode_init(s);
+    }
+
+    /* code can run too long if we have a bit error */
+
+    if (s->v_len > VARICODE_MAX_BITS)
+        varicode_decode_init(s);
+  
+    return found;
+}
+
+int varicode_decode(struct VARICODE_DEC *dec_states, char ascii_out[], int varicode_in[], int max_out, int n_in) {
+    int            output, n_out;
+    char           single_ascii;
+
+    n_out = 0;
+
+    printf("varicode_decode: n_in: %d\n", n_in);
+
+    while(n_in && (n_out < max_out)) {
+        output = decode_one_bit(dec_states, &single_ascii, *varicode_in);
+        varicode_in++;
+        n_in--;
+        if (output) {
+            *ascii_out++ = single_ascii;
+            n_out++;
+        }            
     }
 
     return n_out;
 }
 
+
 #ifdef VARICODE_UNITTEST
 int main(void) {
     char *ascii_in;
     int *varicode;
-    int  i, n_varicode_bits_out, n_ascii_chars_out;
+    int  i, n_varicode_bits_out, n_ascii_chars_out, length, half;
     char *ascii_out;
+    struct VARICODE_DEC dec_states;
 
-    ascii_in = (char*)malloc(sizeof(varicode_table)/2);
-    varicode = (int*)malloc(VARICODE_MAX_BITS*sizeof(int)*strlen(ascii_in));
-    ascii_out = (char*)malloc(strlen(ascii_in)+1);
+    length = sizeof(varicode_table)/2;
+
+    ascii_in = (char*)malloc(length);
+    varicode = (int*)malloc(VARICODE_MAX_BITS*sizeof(int)*length);
+    ascii_out = (char*)malloc(length);
     
-    for(i=0; i<sizeof(varicode_table)/2; i++)
+    for(i=0; i<length; i++)
         ascii_in[i] = (char)i;
-    n_varicode_bits_out = varicode_encode(varicode, ascii_in, VARICODE_MAX_BITS*strlen(ascii_in), strlen(ascii_in));
-    n_ascii_chars_out = varicode_decode(ascii_out, varicode, strlen(ascii_in), n_varicode_bits_out);
-    assert(n_ascii_chars_out == strlen(ascii_in));
-    ascii_out[n_ascii_chars_out] = 0;
+    n_varicode_bits_out = varicode_encode(varicode, ascii_in, VARICODE_MAX_BITS*length, length);
+
+    printf("n_varicode_bits_out: %d\n", n_varicode_bits_out);
+
+    varicode_decode_init(&dec_states);
+    half = n_varicode_bits_out/2;
+    n_ascii_chars_out  = varicode_decode(&dec_states, ascii_out, varicode, length, half);
+    printf("n_ascii_chars_out: %d\n", n_ascii_chars_out);
+
+    n_ascii_chars_out += varicode_decode(&dec_states, &ascii_out[n_ascii_chars_out], 
+                                         &varicode[half], length-n_ascii_chars_out, n_varicode_bits_out - half);
+    printf("n_ascii_chars_out: %d\n", n_ascii_chars_out);
+
+    assert(n_ascii_chars_out == length);
 
     //for(i=0; i<n_varicode_bits_out; i++) {
     //    printf("%d \n", varicode[i]);
     //}
 
     //printf("ascii_out: %s\n", ascii_out);
-    if (strcmp(ascii_in, ascii_out) == 0)
+    if (memcmp(ascii_in, ascii_out, length) == 0)
         printf("Pass\n");
     else
         printf("Fail\n");
@@ -161,6 +198,7 @@ int main(void) {
     free(ascii_in);
     free(ascii_out);
     free(varicode);
+
     return 0;
 }
 #endif
index b40b695a12a6faf08eff958ce8a0d2d5415ad89f..591339f328024f03ccf1e4c5798eb393b76900e6 100644 (file)
 extern "C" {
 
 #endif
+
+struct VARICODE_DEC {
+    int            n_zeros;
+    int            v_len;
+    unsigned short packed;
+};
+    
 int varicode_encode(int varicode_out[], char ascii_in[], int max_out, int n_in);
-int varicode_decode(char ascii_out[], int varicode_in[], int max_out, int n_in);
+void varicode_decode_init(struct VARICODE_DEC *dec_states);
+int varicode_decode(struct VARICODE_DEC *dec_states, char ascii_out[], int varicode_in[], int max_out, int n_in);
 
 #ifdef __cplusplus
 }