diff 3rdparty/compressor/fpaq0.h @ 0:a4671277546c tip

created the repository for the thymian project
author ferencd
date Tue, 17 Aug 2021 11:19:54 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/compressor/fpaq0.h	Tue Aug 17 11:19:54 2021 +0200
@@ -0,0 +1,101 @@
+#ifndef FPAQ0
+#define FPAQ0
+
+#include <vector>
+#include <string>
+#include <stdint.h>
+
+#include <string.h>
+
+class Archive
+{
+public:
+
+    Archive(const std::vector<unsigned char>& s) : content(s.begin(), s.end()), it(content.begin()) {}
+    Archive() : content(), it(content.begin()) {}
+
+    int getc() const
+    {
+        if(it == content.end())
+        {
+            return EOF;
+        }
+        int v = static_cast<int> (*it);
+        ++ it;
+        return v;
+    }
+
+    void putc(char c)
+    {
+        content.push_back(c);
+    }
+
+    std::vector<unsigned char> data() const
+    {
+        return content;
+    }
+
+private:
+    std::vector<unsigned char> content;         // Compressed data file
+    mutable std::vector<unsigned char>::iterator it;
+};
+
+//////////////////////////// Predictor /////////////////////////
+
+/* A Predictor estimates the probability that the next bit of
+   uncompressed data is 1.  Methods:
+   p() returns P(1) as a 12 bit number (0-4095).
+   update(y) trains the predictor with the actual bit (0 or 1).
+*/
+
+class Predictor
+{
+    int cxt;  // Context: last 0-8 bits with a leading 1
+    int ct[512][2];  // 0 and 1 counts in context cxt
+public:
+    Predictor(): cxt(1)
+    {
+        memset(ct, 0, sizeof(ct));
+    }
+
+    // Assume a stationary order 0 stream of 9-bit symbols
+    int p() const;
+
+    void update(int y);
+};
+
+
+//////////////////////////// Encoder ////////////////////////////
+
+/* An Encoder does arithmetic encoding.  Methods:
+   Encoder(COMPRESS, f) creates encoder for compression to archive f, which
+     must be open past any header for writing in binary mode
+   Encoder(DECOMPRESS, f) creates encoder for decompression from archive f,
+     which must be open past any header for reading in binary mode
+   encode(bit) in COMPRESS mode compresses bit to file f.
+   decode() in DECOMPRESS mode returns the next decompressed bit from file f.
+   flush() should be called when there is no more to compress.
+*/
+
+typedef enum {COMPRESS, DECOMPRESS} Mode;
+class Encoder
+{
+public:
+    Encoder(Mode m, Archive& archive);
+    void encode(int y);    // Compress bit y
+    int decode();          // Uncompress and return bit y
+    void flush();          // Call when done compressing
+private:
+    Predictor predictor;
+    const Mode mode;       // Compress or decompress?
+    Archive& archive;
+    uint32_t x1, x2;            // Range, initially [0, 1), scaled by 2^32
+    uint32_t x;                 // Last 4 input bytes of archive.
+};
+
+std::vector<unsigned char> compress(const std::string& s);
+
+std::string decompress(const std::vector<unsigned char>& v);
+
+#endif // FPAQ0
+