]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
First stab at a huffman decoder that I can use for decoding opentv strings.
authorAdam Sutton <dev@adamsutton.me.uk>
Sat, 16 Jun 2012 19:28:30 +0000 (20:28 +0100)
committerAdam Sutton <dev@adamsutton.me.uk>
Mon, 30 Jul 2012 14:49:24 +0000 (15:49 +0100)
src/huffman.c [new file with mode: 0644]
src/huffman.h [new file with mode: 0644]

diff --git a/src/huffman.c b/src/huffman.c
new file mode 100644 (file)
index 0000000..fef49b3
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ *  TV headend - Huffman decoder
+ *  Copyb1 (C) 2012 Adam Sutton
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "huffman.h"
+#include "htsmsg.h"
+#include "settings.h"
+
+void huffman_tree_destroy ( huffman_node_t *n )
+{
+  if (!n) return;
+  huffman_tree_destroy(n->b0);
+  huffman_tree_destroy(n->b1);
+  if (n->data) free(n->data);
+  free(n);
+}
+
+huffman_node_t *huffman_tree_load ( const char *path )
+{
+  htsmsg_t *m;
+  if (!(m = hts_settings_load(path))) return NULL;
+  return huffman_tree_build(m);
+}
+
+huffman_node_t *huffman_tree_build ( htsmsg_t *m )
+{
+  const char *code, *data, *c;
+  htsmsg_t *e;
+  htsmsg_field_t *f;
+  huffman_node_t *root = calloc(1, sizeof(huffman_node_t));
+  HTSMSG_FOREACH(f, m) {
+    e = htsmsg_get_map_by_field(f);
+    c = code = htsmsg_get_str(e, "code");
+    data = htsmsg_get_str(e, "data");
+    if (code && data) {
+      huffman_node_t *node = root;
+      while (*c) {
+        if ( *c == '0' ) {
+          if (!node->b0) node->b0 = calloc(1, sizeof(huffman_node_t));
+          node = node->b0;
+        } else if ( *c == '1' ) {
+          if (!node->b1) node->b1 = calloc(1, sizeof(huffman_node_t));
+          node = node->b1;
+        } else {
+          htsmsg_destroy(m);
+          huffman_tree_destroy(root);
+          return NULL;
+        }
+        c++;
+      }
+      node->data = strdup(data);
+    }
+  }
+  
+  htsmsg_destroy(m);
+  return root; 
+}
+
+char *huffman_decode 
+  ( huffman_node_t *tree, const char *data, size_t len, uint8_t mask )
+{
+  char*           ret;
+  size_t          nalloc = len, nused = 0;
+  huffman_node_t *node = tree;
+  if (!len) return NULL;
+
+  ret    = malloc(nalloc);
+  ret[0] = '\0';
+  while (len) {
+    len--;
+    while (mask) {
+      if (*data & mask) {
+        node = node->b1;
+      } else {
+        node = node->b0;
+      }
+      mask >>= 1;
+      if (!node) return ret;
+      if (node->data) {
+        size_t l = strlen(node->data);
+        if ((nalloc - nused) < l) {
+          nalloc *= 2;
+          ret     = realloc(ret, nalloc);
+        }
+        strcat(ret, node->data);
+        node = tree;
+      }
+    }
+    mask = 0x80;
+  }
+  return ret;
+}
diff --git a/src/huffman.h b/src/huffman.h
new file mode 100644 (file)
index 0000000..08ce873
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *  TV headend - Huffman decoder
+ *  Copyright (C) 2012 Adam Sutton
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __TVH_HUFFMAN_H__
+#define __TVH_HUFFMAN_H__
+
+#include <sys/types.h>
+#include "htsmsg.h"
+
+typedef struct huffman_node
+{
+  struct huffman_node *b0;
+  struct huffman_node *b1;
+  char                *data;
+} huffman_node_t;
+
+void huffman_tree_destroy ( huffman_node_t *tree );
+huffman_node_t *huffman_tree_load  ( const char *path );
+huffman_node_t *huffman_tree_build ( htsmsg_t *codes );
+char *huffman_decode 
+  ( huffman_node_t *tree, const char *data, size_t len, uint8_t mask );
+
+#endif