summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--eepg.c1
-rw-r--r--eit2.c5
-rw-r--r--eit2.h8
-rw-r--r--util.c117
-rw-r--r--util.h26
5 files changed, 151 insertions, 6 deletions
diff --git a/eepg.c b/eepg.c
index 1174681..c438969 100644
--- a/eepg.c
+++ b/eepg.c
@@ -45,6 +45,7 @@
#include "setupeepg.h"
#include "equivhandler.h"
#include "util.h"
+#include "eit2.h"
#include <map>
#include <string>
diff --git a/eit2.c b/eit2.c
index 5bd7cc4..6c88594 100644
--- a/eit2.c
+++ b/eit2.c
@@ -10,6 +10,7 @@
#include <vdr/config.h>
#include "log.h"
#include "util.h"
+#include "dish.h"
using namespace std;
using namespace util;
@@ -110,8 +111,8 @@ namespace SI
cComponents *Components = NULL;
-
- for (SI::Loop::Iterator it2; (d = SiEitEvent->eventDescriptors.getNext(it2)); )
+ DescriptorLoop dl = SiEitEvent->eventDescriptors;
+ for (SI::Loop::Iterator it2; (d = dl.getNext(it2)); )
{
if (ExternalData && d->getDescriptorTag() != SI::ComponentDescriptorTag)
{
diff --git a/eit2.h b/eit2.h
index 5d2e4bb..e052b2d 100644
--- a/eit2.h
+++ b/eit2.h
@@ -3,6 +3,7 @@
#include <libsi/section.h>
#include <libsi/descriptor.h>
#include <libsi/si.h>
+#include <vdr/epg.h>
namespace SI
{
@@ -28,10 +29,9 @@ public:
cEvent* ProcessEitEvent(cSchedule *Schedule, const SI::EIT::Event *EitEvent, uchar TableID, uchar Version);
private:
- void
- ProcessEventDescriptors(bool ExternalData,
- int Source, u_char Tid, const SI::EIT::Event* SiEitEvent, cEvent* pEvent,
- cSchedules* Schedules, cChannel* channel);
+ void ProcessEventDescriptors(bool ExternalData,
+ int Source, u_char Tid, const SI::EIT::Event* SiEitEvent, cEvent* pEvent,
+ cSchedules* Schedules, cChannel* channel);
private:
bool Empty;
diff --git a/util.c b/util.c
index 3d92dda..c1cc69d 100644
--- a/util.c
+++ b/util.c
@@ -204,6 +204,123 @@ void AddEvent(cEvent *Event, tChannelID ChannelID)
AddEventThread.Start();
}
+/** \brief Decode an EPG string as necessary
+ *
+ * \param src - Possibly encoded string
+ * \param size - Size of the buffer
+ *
+ * \retval NULL - Can't decode
+ * \return A decoded string
+ */
+char *freesat_huffman_decode (const unsigned char *src, size_t size)
+{
+ int tableid;
+// freesat_decode_error = 0;
+
+ if (src[0] == 0x1f && (src[1] == 1 || src[1] == 2)) {
+ int uncompressed_len = 30;
+ char *uncompressed = (char *) calloc (1, uncompressed_len + 1);
+ unsigned value = 0, byte = 2, bit = 0;
+ int p = 0;
+ unsigned char lastch = START;
+
+ tableid = src[1] - 1;
+ while (byte < 6 && byte < size) {
+ value |= src[byte] << ((5 - byte) * 8);
+ byte++;
+ }
+ //freesat_table_load (); /**< Load the tables as necessary */
+
+ do {
+ bool found = false;
+ unsigned bitShift = 0;
+ if (lastch == ESCAPE) {
+ char nextCh = (value >> 24) & 0xff;
+ found = true;
+ // Encoded in the next 8 bits.
+ // Terminated by the first ASCII character.
+ bitShift = 8;
+ if ((nextCh & 0x80) == 0)
+ lastch = nextCh;
+ if (p >= uncompressed_len) {
+ uncompressed_len += 10;
+ uncompressed = (char *) REALLOC (uncompressed, uncompressed_len + 1);
+ }
+ uncompressed[p++] = nextCh;
+ uncompressed[p] = 0;
+ } else {
+ int j;
+ for (j = 0; j < table_size[tableid][lastch]; j++) {
+ unsigned mask = 0, maskbit = 0x80000000;
+ short kk;
+ for (kk = 0; kk < tables[tableid][lastch][j].bits; kk++) {
+ mask |= maskbit;
+ maskbit >>= 1;
+ }
+ if ((value & mask) == tables[tableid][lastch][j].value) {
+ char nextCh = tables[tableid][lastch][j].next;
+ bitShift = tables[tableid][lastch][j].bits;
+ if (nextCh != STOP && nextCh != ESCAPE) {
+ if (p >= uncompressed_len) {
+ uncompressed_len += 10;
+ uncompressed = (char *) REALLOC (uncompressed, uncompressed_len + 1);
+ }
+ uncompressed[p++] = nextCh;
+ uncompressed[p] = 0;
+ }
+ found = true;
+ lastch = nextCh;
+ break;
+ }
+ }
+ }
+ if (found) {
+ // Shift up by the number of bits.
+ unsigned b;
+ for (b = 0; b < bitShift; b++) {
+ value = (value << 1) & 0xfffffffe;
+ if (byte < size)
+ value |= (src[byte] >> (7 - bit)) & 1;
+ if (bit == 7) {
+ bit = 0;
+ byte++;
+ } else
+ bit++;
+ }
+ } else {
+ LogE (0, prep("Missing table %d entry: <%s>"), tableid + 1, uncompressed);
+ // Entry missing in table.
+ return uncompressed;
+ }
+ } while (lastch != STOP && value != 0);
+
+ return uncompressed;
+ }
+ return NULL;
+}
+
+void decodeText2 (const unsigned char *from, int len, char *buffer, int buffsize)
+{
+ if (from[0] == 0x1f) {
+ char *temp = freesat_huffman_decode (from, len);
+ if (temp) {
+ len = strlen (temp);
+ len = len < buffsize - 1 ? len : buffsize - 1;
+ strncpy (buffer, temp, len);
+ buffer[len] = 0;
+ free (temp);
+ return;
+ }
+ }
+
+ SI::String convStr;
+ SI::CharArray charArray;
+ charArray.assign(from, len);
+ convStr.setData(charArray, len);
+ //LogE(5, prep("decodeText2 from %s - length %d"), from, len);
+ convStr.getText(buffer, buffsize);
+ //LogE(5, prep("decodeText2 buffer %s - buffsize %d"), buffer, buffsize);
+}
}
diff --git a/util.h b/util.h
index f15bce6..88e6c62 100644
--- a/util.h
+++ b/util.h
@@ -28,6 +28,32 @@ time_t LocalTime2UTC (time_t t);
time_t UTC2LocalTime (time_t t);
void GetLocalTimeOffset (void);
void CleanString (unsigned char *String);
+void decodeText2 (const unsigned char *from, int len, char *buffer, int buffsize);
+char *freesat_huffman_decode (const unsigned char *src, size_t size);
+
+struct sNode
+{
+ char *Value;
+ struct sNode *P0;
+ struct sNode *P1;
+};
+
+typedef struct sNode sNodeH;
+
+struct hufftab {
+ unsigned int value;
+ short bits;
+ char next;
+};
+
+#define START '\0'
+#define STOP '\0'
+#define ESCAPE '\1'
+
+static struct hufftab *tables[2][128];
+static int table_size[2][128];
+static sNodeH* sky_tables[2];
+
#define Asprintf(a, b, c...) void( asprintf(a, b, c) < 0 ? esyslog("memory allocation error - %s", b) : void() )