Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] Subject: [PATCH 01/17] avcodec/vlc: Merge VLCElem and RL_VLC_ELEM
@ 2025-03-14 10:53 Andreas Rheinhardt
  2025-03-16  3:50 ` Andreas Rheinhardt
  0 siblings, 1 reply; 2+ messages in thread
From: Andreas Rheinhardt @ 2025-03-14 10:53 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

[-- Attachment #1: Type: text/plain, Size: 29 bytes --]

Patches attached.

- Andreas

[-- Attachment #2: 0001-avcodec-vlc-Merge-VLCElem-and-RL_VLC_ELEM.patch --]
[-- Type: text/x-patch, Size: 9188 bytes --]

From ef55dc925fd82cd5811108ae59bdac532470eb11 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Fri, 7 Mar 2025 16:12:42 +0100
Subject: [PATCH 01/17] avcodec/vlc: Merge VLCElem and RL_VLC_ELEM

It will simplify creating RL-VLCs (which until now used
a stack-based VLC as temporary buffer).

Notice that there would be another option to merge them, namely:
struct VLCElem {
    union {
        VLCBaseType sym;
        int16_t level;
    };
    int8_t len;
    uint8_t run;
};

The main difference to the current patch is that this would change
the type of the length field of VLCElem to int8_t from int16_t.
It turns out that that this would entail additional sign extensions
on ppc, see https://godbolt.org/z/behWYEYE7. I have therefore refrained
from doing so, although it would make the patch simpler.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/cfhd.h     |  2 +-
 libavcodec/cfhddata.c | 10 +++++-----
 libavcodec/dvdec.c    | 12 ++++++------
 libavcodec/get_bits.h |  6 +++---
 libavcodec/mpeg12.c   |  2 +-
 libavcodec/rl.c       |  2 +-
 libavcodec/vlc.h      | 22 +++++++++++++++-------
 7 files changed, 32 insertions(+), 24 deletions(-)

diff --git a/libavcodec/cfhd.h b/libavcodec/cfhd.h
index 9b09c91262..586d3360b6 100644
--- a/libavcodec/cfhd.h
+++ b/libavcodec/cfhd.h
@@ -98,7 +98,7 @@ enum CFHDParam {
 
 typedef struct CFHD_RL_VLC_ELEM {
     int16_t level;
-    int8_t len;
+    int8_t len8;
     uint16_t run;
 } CFHD_RL_VLC_ELEM;
 
diff --git a/libavcodec/cfhddata.c b/libavcodec/cfhddata.c
index a3948a14ca..72b14baf27 100644
--- a/libavcodec/cfhddata.c
+++ b/libavcodec/cfhddata.c
@@ -136,22 +136,22 @@ static av_cold int cfhd_init_vlc(CFHD_RL_VLC_ELEM out[], unsigned out_size,
     /** Similar to dv.c, generate signed VLC tables **/
 
     for (unsigned i = j = 0; i < table_size; i++, j++) {
-        tmp[j].len   = table_vlc[i].len;
+        tmp[j].len8  = table_vlc[i].len;
         tmp[j].run   = table_vlc[i].run;
         tmp[j].level = table_vlc[i].level;
 
         /* Don't include the zero level nor escape bits */
         if (table_vlc[i].level && table_vlc[i].run) {
-            tmp[j].len++;
+            tmp[j].len8++;
             j++;
-            tmp[j].len   =  table_vlc[i].len + 1;
+            tmp[j].len8  =  table_vlc[i].len + 1;
             tmp[j].run   =  table_vlc[i].run;
             tmp[j].level = -table_vlc[i].level;
         }
     }
 
     ret = ff_vlc_init_from_lengths(&vlc, VLC_BITS, j,
-                                   &tmp[0].len, sizeof(tmp[0]),
+                                   &tmp[0].len8, sizeof(tmp[0]),
                                    NULL, 0, 0, 0, 0, logctx);
     if (ret < 0)
         return ret;
@@ -169,7 +169,7 @@ static av_cold int cfhd_init_vlc(CFHD_RL_VLC_ELEM out[], unsigned out_size,
             run   = tmp[code].run;
             level = tmp[code].level;
         }
-        out[i].len   = len;
+        out[i].len8  = len;
         out[i].level = level;
         out[i].run   = run;
     }
diff --git a/libavcodec/dvdec.c b/libavcodec/dvdec.c
index 8297b6d2f3..242708c70a 100644
--- a/libavcodec/dvdec.c
+++ b/libavcodec/dvdec.c
@@ -159,15 +159,15 @@ static av_cold void dv_init_static(void)
 
     /* it's faster to include sign bit in a generic VLC parsing scheme */
     for (i = 0, j = 0; i < NB_DV_VLC; i++, j++) {
-        tmp[j].len   = ff_dv_vlc_len[i];
+        tmp[j].len8  = ff_dv_vlc_len[i];
         tmp[j].run   = ff_dv_vlc_run[i];
         tmp[j].level = ff_dv_vlc_level[i];
 
         if (ff_dv_vlc_level[i]) {
-            tmp[j].len++;
+            tmp[j].len8++;
 
             j++;
-            tmp[j].len   =  ff_dv_vlc_len[i] + 1;
+            tmp[j].len8  =  ff_dv_vlc_len[i] + 1;
             tmp[j].run   =  ff_dv_vlc_run[i];
             tmp[j].level = -ff_dv_vlc_level[i];
         }
@@ -176,7 +176,7 @@ static av_cold void dv_init_static(void)
     /* NOTE: as a trick, we use the fact the no codes are unused
      * to accelerate the parsing of partial codes */
     ff_vlc_init_from_lengths(&dv_vlc, TEX_VLC_BITS, j,
-                             &tmp[0].len, sizeof(tmp[0]),
+                             &tmp[0].len8, sizeof(tmp[0]),
                              NULL, 0, 0, 0, VLC_INIT_USE_STATIC, NULL);
     av_assert1(dv_vlc.table_size == 1664);
 
@@ -193,7 +193,7 @@ static av_cold void dv_init_static(void)
             run   = tmp[code].run + 1;
             level = tmp[code].level;
         }
-        dv_rl_vlc[i].len   = len;
+        dv_rl_vlc[i].len8  = len;
         dv_rl_vlc[i].level = level;
         dv_rl_vlc[i].run   = run;
     }
@@ -301,7 +301,7 @@ static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, int16_t *block)
                 pos, SHOW_UBITS(re, gb, 16), re_index);
         /* our own optimized GET_RL_VLC */
         index   = NEG_USR32(re_cache, TEX_VLC_BITS);
-        vlc_len = dv_rl_vlc[index].len;
+        vlc_len = dv_rl_vlc[index].len8;
         if (vlc_len < 0) {
             index = NEG_USR32((unsigned) re_cache << TEX_VLC_BITS, -vlc_len) +
                     dv_rl_vlc[index].level;
diff --git a/libavcodec/get_bits.h b/libavcodec/get_bits.h
index 39d8e5bc1e..1954296569 100644
--- a/libavcodec/get_bits.h
+++ b/libavcodec/get_bits.h
@@ -594,7 +594,7 @@ static inline const uint8_t *align_get_bits(GetBitContext *s)
                                                                 \
         index = SHOW_UBITS(name, gb, bits);                     \
         level = table[index].level;                             \
-        n     = table[index].len;                               \
+        n     = table[index].len8;                              \
                                                                 \
         if (max_depth > 1 && n < 0) {                           \
             SKIP_BITS(name, gb, bits);                          \
@@ -606,7 +606,7 @@ static inline const uint8_t *align_get_bits(GetBitContext *s)
                                                                 \
             index = SHOW_UBITS(name, gb, nb_bits) + level;      \
             level = table[index].level;                         \
-            n     = table[index].len;                           \
+            n     = table[index].len8;                          \
             if (max_depth > 2 && n < 0) {                       \
                 LAST_SKIP_BITS(name, gb, nb_bits);              \
                 if (need_update) {                              \
@@ -616,7 +616,7 @@ static inline const uint8_t *align_get_bits(GetBitContext *s)
                                                                 \
                 index = SHOW_UBITS(name, gb, nb_bits) + level;  \
                 level = table[index].level;                     \
-                n     = table[index].len;                       \
+                n     = table[index].len8;                      \
             }                                                   \
         }                                                       \
         run = table[index].run;                                 \
diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c
index 444ea83f3c..0d4a36be04 100644
--- a/libavcodec/mpeg12.c
+++ b/libavcodec/mpeg12.c
@@ -119,7 +119,7 @@ av_cold void ff_init_2d_vlc_rl(const uint16_t table_vlc[][2], RL_VLC_ELEM rl_vlc
                 level = table_level[code];
             }
         }
-        rl_vlc[i].len   = len;
+        rl_vlc[i].len8  = len;
         rl_vlc[i].level = level;
         rl_vlc[i].run   = run;
     }
diff --git a/libavcodec/rl.c b/libavcodec/rl.c
index a78242d488..b45cf117c1 100644
--- a/libavcodec/rl.c
+++ b/libavcodec/rl.c
@@ -118,7 +118,7 @@ av_cold void ff_rl_init_vlc(RLTable *rl, unsigned static_size)
                     if (code >= rl->last) run += 192;
                 }
             }
-            rl->rl_vlc[q][i].len   = len;
+            rl->rl_vlc[q][i].len8  = len;
             rl->rl_vlc[q][i].level = level;
             rl->rl_vlc[q][i].run   = run;
         }
diff --git a/libavcodec/vlc.h b/libavcodec/vlc.h
index bf7b0e65b4..7eecd9651f 100644
--- a/libavcodec/vlc.h
+++ b/libavcodec/vlc.h
@@ -30,9 +30,23 @@
 typedef int16_t VLCBaseType;
 
 typedef struct VLCElem {
-    VLCBaseType sym, len;
+    union {
+        /// The struct is for use as ordinary VLC (with get_vlc2())
+        struct {
+            VLCBaseType sym;
+            VLCBaseType len;
+        };
+        /// This struct is for use as run-length VLC (with GET_RL_VLC)
+        struct {
+            int16_t level;
+            int8_t   len8;
+            uint8_t   run;
+        };
+    };
 } VLCElem;
 
+typedef VLCElem RL_VLC_ELEM;
+
 typedef struct VLC {
     int bits;
     VLCElem *table;
@@ -53,12 +67,6 @@ typedef struct VLC_MULTI {
     int table_size, table_allocated;
 } VLC_MULTI;
 
-typedef struct RL_VLC_ELEM {
-    int16_t level;
-    int8_t len;
-    uint8_t run;
-} RL_VLC_ELEM;
-
 #define vlc_init(vlc, nb_bits, nb_codes,                \
                  bits, bits_wrap, bits_size,            \
                  codes, codes_wrap, codes_size,         \
-- 
2.45.2


[-- Attachment #3: 0002-avcodec-mpeg12-Avoid-temporary-stack-VLC-array-durin.patch --]
[-- Type: text/x-patch, Size: 2651 bytes --]

From f5ca51a0f0ac187471200f5cbb24f3b847792865 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Fri, 7 Mar 2025 16:37:43 +0100
Subject: [PATCH 02/17] avcodec/mpeg12: Avoid temporary stack VLC array during
 RL VLC init

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg12.c | 27 ++++++++++++---------------
 1 file changed, 12 insertions(+), 15 deletions(-)

diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c
index 0d4a36be04..3056c53c7c 100644
--- a/libavcodec/mpeg12.c
+++ b/libavcodec/mpeg12.c
@@ -28,7 +28,6 @@
 #define UNCHECKED_BITSTREAM_READER 1
 
 #include "libavutil/attributes.h"
-#include "libavutil/avassert.h"
 #include "libavutil/thread.h"
 
 #include "mpegvideo.h"
@@ -90,15 +89,13 @@ av_cold void ff_init_2d_vlc_rl(const uint16_t table_vlc[][2], RL_VLC_ELEM rl_vlc
                                const int8_t table_run[], const uint8_t table_level[],
                                int n, unsigned static_size, int flags)
 {
-    int i;
-    VLCElem table[680] = { 0 };
-    VLC vlc = { .table = table, .table_allocated = static_size };
-    av_assert0(static_size <= FF_ARRAY_ELEMS(table));
-    vlc_init(&vlc, TEX_VLC_BITS, n + 2, &table_vlc[0][1], 4, 2, &table_vlc[0][0], 4, 2, VLC_INIT_USE_STATIC | flags);
-
-    for (i = 0; i < vlc.table_size; i++) {
-        int code = vlc.table[i].sym;
-        int len  = vlc.table[i].len;
+    ff_vlc_init_table_sparse(rl_vlc, static_size, TEX_VLC_BITS, n + 2,
+                             &table_vlc[0][1], 4, 2, &table_vlc[0][0], 4, 2,
+                             NULL, 0, 0, flags);
+
+    for (unsigned i = 0; i < static_size; i++) {
+        int idx = rl_vlc[i].sym;
+        int len = rl_vlc[i].len;
         int level, run;
 
         if (len == 0) { // illegal code
@@ -106,17 +103,17 @@ av_cold void ff_init_2d_vlc_rl(const uint16_t table_vlc[][2], RL_VLC_ELEM rl_vlc
             level = MAX_LEVEL;
         } else if (len<0) { //more bits needed
             run   = 0;
-            level = code;
+            level = idx;
         } else {
-            if (code == n) { //esc
+            if (idx == n) { //esc
                 run   = 65;
                 level = 0;
-            } else if (code == n + 1) { //eob
+            } else if (idx == n + 1) { //eob
                 run   = 0;
                 level = 127;
             } else {
-                run   = table_run  [code] + 1;
-                level = table_level[code];
+                run   = table_run  [idx] + 1;
+                level = table_level[idx];
             }
         }
         rl_vlc[i].len8  = len;
-- 
2.45.2


[-- Attachment #4: 0003-avcodec-rl-Avoid-temporary-stack-VLC-array-during-RL.patch --]
[-- Type: text/x-patch, Size: 2995 bytes --]

From bdca8f02ea4adee9c52d96a3b4dfd5eb8ff67b93 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Fri, 7 Mar 2025 17:08:08 +0100
Subject: [PATCH 03/17] avcodec/rl: Avoid temporary stack VLC array during RL
 VLC init

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/rl.c | 37 +++++++++++++++++++------------------
 1 file changed, 19 insertions(+), 18 deletions(-)

diff --git a/libavcodec/rl.c b/libavcodec/rl.c
index b45cf117c1..af304c5f87 100644
--- a/libavcodec/rl.c
+++ b/libavcodec/rl.c
@@ -20,7 +20,6 @@
 #include <string.h>
 
 #include "libavutil/attributes.h"
-#include "libavutil/avassert.h"
 
 #include "rl.h"
 
@@ -78,28 +77,30 @@ av_cold void ff_rl_init(RLTable *rl,
 
 av_cold void ff_rl_init_vlc(RLTable *rl, unsigned static_size)
 {
-    int i, q;
-    VLCElem table[1500] = { 0 };
-    VLC vlc = { .table = table, .table_allocated = static_size };
-    av_assert0(static_size <= FF_ARRAY_ELEMS(table));
-    vlc_init(&vlc, 9, rl->n + 1,
-             &rl->table_vlc[0][1], 4, 2,
-             &rl->table_vlc[0][0], 4, 2, VLC_INIT_USE_STATIC);
+    VLCElem *vlc;
 
-    for (q = 0; q < 32; q++) {
+    ff_vlc_init_table_sparse(rl->rl_vlc[0], static_size, 9, rl->n + 1,
+                             &rl->table_vlc[0][1], 4, 2,
+                             &rl->table_vlc[0][0], 4, 2,
+                             NULL, 0, 0, 0);
+
+    vlc = rl->rl_vlc[0];
+
+    // We count down to avoid trashing the first RL-VLC
+    for (int q = 32; --q >= 0;) {
         int qmul = q * 2;
         int qadd = (q - 1) | 1;
 
         if (!rl->rl_vlc[q])
-            return;
+            continue;
 
         if (q == 0) {
             qmul = 1;
             qadd = 0;
         }
-        for (i = 0; i < vlc.table_size; i++) {
-            int code = vlc.table[i].sym;
-            int len  = vlc.table[i].len;
+        for (unsigned i = 0; i < static_size; i++) {
+            int idx  = vlc[i].sym;
+            int len  = vlc[i].len;
             int level, run;
 
             if (len == 0) { // illegal code
@@ -107,15 +108,15 @@ av_cold void ff_rl_init_vlc(RLTable *rl, unsigned static_size)
                 level = MAX_LEVEL;
             } else if (len < 0) { // more bits needed
                 run   = 0;
-                level = code;
+                level = idx;
             } else {
-                if (code == rl->n) { // esc
+                if (idx == rl->n) { // esc
                     run   = 66;
                     level =  0;
                 } else {
-                    run   = rl->table_run[code] + 1;
-                    level = rl->table_level[code] * qmul + qadd;
-                    if (code >= rl->last) run += 192;
+                    run   = rl->table_run[idx] + 1;
+                    level = rl->table_level[idx] * qmul + qadd;
+                    if (idx >= rl->last) run += 192;
                 }
             }
             rl->rl_vlc[q][i].len8  = len;
-- 
2.45.2


[-- Attachment #5: 0004-avcodec-hqxvlc-Avoid-hardcoded-RL-VLC-table.patch --]
[-- Type: text/x-patch, Size: 143764 bytes --]

From 34de878e3dc5fe3ed75a1253c5bdd1aae1e658a0 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu, 13 Mar 2025 10:57:56 +0100
Subject: [PATCH 04/17] avcodec/hqxvlc: Avoid hardcoded RL VLC table

hqxvlc.c contains sort-of run-length VLCs in hardcoded form;
they amount to 26688 elements, taking 104KiB. These tables contain
many duplicated entries (they are partially created via a RPT_1024
macro). There are actually only 3039 different codes in all tables
combined, making this very wasteful.

This commit changes this by extracting the underlying entries
and creating a (static) RL-VLC. This only costs 3*3039 bytes
of .rodata. The resulting table needs only 15630 entries,
because our VLC init code uses smaller subtables when possible
(for an incomplete code, the negative of the length stored in
the VLC code is the number of bits the subtable uses; the hardcoded
tables uses a worst-case per table value).

Using GET_RL_VLC also gets rid of an unnecessary reload in case
a code is too long to be parsed in the first stage.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/hqx.c    |   21 +-
 libavcodec/hqx.h    |   12 +-
 libavcodec/hqxvlc.c | 2226 ++++++++++++++++---------------------------
 3 files changed, 829 insertions(+), 1430 deletions(-)

diff --git a/libavcodec/hqx.c b/libavcodec/hqx.c
index ee6c5a6622..b31c35bbcc 100644
--- a/libavcodec/hqx.c
+++ b/libavcodec/hqx.c
@@ -97,19 +97,16 @@ static inline void put_blocks(HQXContext *ctx, int plane,
 }
 
 static inline void hqx_get_ac(GetBitContext *gb, const HQXAC *ac,
-                              int *run, int *lev)
+                              int *runp, int *lev)
 {
-    int val;
-
-    val = show_bits(gb, ac->lut_bits);
-    if (ac->lut[val].bits == -1) {
-        GetBitContext gb2 = *gb;
-        skip_bits(&gb2, ac->lut_bits);
-        val = ac->lut[val].lev + show_bits(&gb2, ac->extra_bits);
-    }
-    *run = ac->lut[val].run;
-    *lev = ac->lut[val].lev;
-    skip_bits(gb, ac->lut[val].bits);
+    int level, run;
+    OPEN_READER(re, gb);
+
+    UPDATE_CACHE(re, gb);
+    GET_RL_VLC(level, run, re, gb, ac->lut, ac->bits, 2, 0);
+    CLOSE_READER(re, gb);
+    *runp = run;
+    *lev  = level;
 }
 
 static int decode_block(GetBitContext *gb, VLC *vlc,
diff --git a/libavcodec/hqx.h b/libavcodec/hqx.h
index 155ec7f84f..4f313a1dc3 100644
--- a/libavcodec/hqx.h
+++ b/libavcodec/hqx.h
@@ -39,15 +39,9 @@ enum HQXACMode {
     NUM_HQX_AC
 };
 
-typedef struct HQXLUT {
-    int16_t lev;
-    uint8_t run;
-    int8_t  bits;
-} HQXLUT;
-
 typedef struct HQXAC {
-    int lut_bits, extra_bits;
-    const HQXLUT *lut;
+    int bits;
+    const RL_VLC_ELEM *lut;
 } HQXAC;
 
 struct HQXContext;
@@ -81,7 +75,7 @@ typedef struct HQXContext {
 #define HQX_CBP_VLC_BITS 5
 #define HQX_DC_VLC_BITS 9
 
-extern const HQXAC ff_hqx_ac[NUM_HQX_AC];
+extern HQXAC ff_hqx_ac[NUM_HQX_AC];
 
 int ff_hqx_init_vlcs(HQXContext *ctx);
 
diff --git a/libavcodec/hqxvlc.c b/libavcodec/hqxvlc.c
index 1eeda4fcce..94ab21724c 100644
--- a/libavcodec/hqxvlc.c
+++ b/libavcodec/hqxvlc.c
@@ -19,6 +19,7 @@
  */
 
 #include "hqx.h"
+#include "libavutil/thread.h"
 
 static const uint8_t cbp_vlc_bits[16] = {
     0x04, 0x1C, 0x1D, 0x09, 0x1E, 0x0B, 0x1B, 0x08,
@@ -719,1424 +720,790 @@ static const uint8_t dc11_vlc_lens[2048] = {
      8,  8,  8,  8,  8,  8,  8,  8,  7,  7,  7,  7,  7,  7,  7,  7,
 };
 
-#define RPT_2(a, b, c)    { a, b, c }, { a, b, c }
-#define RPT_4(a, b, c)    RPT_2(  a, b, c), RPT_2(  a, b, c)
-#define RPT_8(a, b, c)    RPT_4(  a, b, c), RPT_4(  a, b, c)
-#define RPT_16(a, b, c)   RPT_8(  a, b, c), RPT_8(  a, b, c)
-#define RPT_32(a, b, c)   RPT_16( a, b, c), RPT_16( a, b, c)
-#define RPT_64(a, b, c)   RPT_32( a, b, c), RPT_32( a, b, c)
-#define RPT_128(a, b, c)  RPT_64( a, b, c), RPT_64( a, b, c)
-#define RPT_256(a, b, c)  RPT_128(a, b, c), RPT_128(a, b, c)
-#define RPT_512(a, b, c)  RPT_256(a, b, c), RPT_256(a, b, c)
-#define RPT_1024(a, b, c) RPT_512(a, b, c), RPT_512(a, b, c)
 
-static const HQXLUT ac0_lut[] = {
-    RPT_64  (   1,  0,  4 ), RPT_64  (  -1,  0,  4 ),
-    RPT_64  (   2,  0,  4 ), RPT_64  (  -2,  0,  4 ),
-    RPT_32  (   3,  0,  5 ), RPT_32  (  -3,  0,  5 ),
-    RPT_32  (   4,  0,  5 ), RPT_32  (  -4,  0,  5 ),
-    RPT_32  (   1,  1,  5 ), RPT_32  (  -1,  1,  5 ),
-    RPT_16  (   5,  0,  6 ), RPT_16  (  -5,  0,  6 ),
-    RPT_16  (   6,  0,  6 ), RPT_16  (  -6,  0,  6 ),
-    RPT_16  (   7,  0,  6 ), RPT_16  (  -7,  0,  6 ),
-    RPT_16  (   8,  0,  6 ), RPT_16  (  -8,  0,  6 ),
-    { 1024,  0, -1 }, { 1056,  0, -1 }, { 1088,  0, -1 }, { 1120,  0, -1 },
-    { 1152,  0, -1 }, { 1184,  0, -1 }, { 1216,  0, -1 }, { 1248,  0, -1 },
-    { 1280,  0, -1 }, { 1312,  0, -1 }, { 1344,  0, -1 }, { 1376,  0, -1 },
-    { 1408,  0, -1 }, { 1440,  0, -1 }, { 1472,  0, -1 }, { 1504,  0, -1 },
-    { 1536,  0, -1 }, { 1568,  0, -1 }, { 1600,  0, -1 }, { 1632,  0, -1 },
-    { 1664,  0, -1 }, { 1696,  0, -1 }, { 1728,  0, -1 }, { 1760,  0, -1 },
-    { 1792,  0, -1 }, { 1824,  0, -1 }, { 1856,  0, -1 }, { 1888,  0, -1 },
-    { 1920,  0, -1 }, { 1952,  0, -1 }, { 1984,  0, -1 }, { 2016,  0, -1 },
-    RPT_32  (   0, 64,  5 ), RPT_8   (   9,  0,  7 ),
-    RPT_8   (  -9,  0,  7 ), RPT_8   (  10,  0,  7 ),
-    RPT_8   ( -10,  0,  7 ), RPT_8   (  11,  0,  7 ),
-    RPT_8   ( -11,  0,  7 ), RPT_8   (  12,  0,  7 ),
-    RPT_8   ( -12,  0,  7 ), RPT_8   (  13,  0,  7 ),
-    RPT_8   ( -13,  0,  7 ), RPT_8   (  14,  0,  7 ),
-    RPT_8   ( -14,  0,  7 ), RPT_8   (   2,  1,  7 ),
-    RPT_8   (  -2,  1,  7 ), RPT_8   (   1,  2,  7 ),
-    RPT_8   (  -1,  2,  7 ), RPT_4   (  15,  0,  8 ),
-    RPT_4   ( -15,  0,  8 ), RPT_4   (  16,  0,  8 ),
-    RPT_4   ( -16,  0,  8 ), RPT_4   (  17,  0,  8 ),
-    RPT_4   ( -17,  0,  8 ), RPT_4   (  18,  0,  8 ),
-    RPT_4   ( -18,  0,  8 ), RPT_4   (  19,  0,  8 ),
-    RPT_4   ( -19,  0,  8 ), RPT_4   (  20,  0,  8 ),
-    RPT_4   ( -20,  0,  8 ), RPT_4   (  21,  0,  8 ),
-    RPT_4   ( -21,  0,  8 ), RPT_4   (   3,  1,  8 ),
-    RPT_4   (  -3,  1,  8 ), RPT_4   (   4,  1,  8 ),
-    RPT_4   (  -4,  1,  8 ), RPT_4   (   1,  3,  8 ),
-    RPT_4   (  -1,  3,  8 ), RPT_4   (   1,  4,  8 ),
-    RPT_4   (  -1,  4,  8 ), RPT_4   (   0,  0,  8 ),
-    RPT_2   (  22,  0,  9 ), RPT_2   ( -22,  0,  9 ),
-    RPT_2   (  23,  0,  9 ), RPT_2   ( -23,  0,  9 ),
-    RPT_2   (  24,  0,  9 ), RPT_2   ( -24,  0,  9 ),
-    RPT_2   (  25,  0,  9 ), RPT_2   ( -25,  0,  9 ),
-    RPT_2   (  26,  0,  9 ), RPT_2   ( -26,  0,  9 ),
-    RPT_2   (  27,  0,  9 ), RPT_2   ( -27,  0,  9 ),
-    RPT_2   (  28,  0,  9 ), RPT_2   ( -28,  0,  9 ),
-    RPT_2   (  29,  0,  9 ), RPT_2   ( -29,  0,  9 ),
-    RPT_2   (  30,  0,  9 ), RPT_2   ( -30,  0,  9 ),
-    RPT_2   (  31,  0,  9 ), RPT_2   ( -31,  0,  9 ),
-    RPT_2   (  32,  0,  9 ), RPT_2   ( -32,  0,  9 ),
-    RPT_2   (  33,  0,  9 ), RPT_2   ( -33,  0,  9 ),
-    RPT_2   (   5,  1,  9 ), RPT_2   (  -5,  1,  9 ),
-    RPT_2   (   6,  1,  9 ), RPT_2   (  -6,  1,  9 ),
-    RPT_2   (   2,  2,  9 ), RPT_2   (  -2,  2,  9 ),
-    RPT_2   (   1,  5,  9 ), RPT_2   (  -1,  5,  9 ),
-    RPT_2   (   1,  6,  9 ), RPT_2   (  -1,  6,  9 ),
-    {   34,  0, 10 }, {  -34,  0, 10 }, {   35,  0, 10 }, {  -35,  0, 10 },
-    {   36,  0, 10 }, {  -36,  0, 10 }, {   37,  0, 10 }, {  -37,  0, 10 },
-    {   38,  0, 10 }, {  -38,  0, 10 }, {   39,  0, 10 }, {  -39,  0, 10 },
-    {   40,  0, 10 }, {  -40,  0, 10 }, {   41,  0, 10 }, {  -41,  0, 10 },
-    {   42,  0, 10 }, {  -42,  0, 10 }, {   43,  0, 10 }, {  -43,  0, 10 },
-    {   44,  0, 10 }, {  -44,  0, 10 }, {   45,  0, 10 }, {  -45,  0, 10 },
-    {   46,  0, 10 }, {  -46,  0, 10 }, {   47,  0, 10 }, {  -47,  0, 10 },
-    {   48,  0, 10 }, {  -48,  0, 10 }, {   49,  0, 10 }, {  -49,  0, 10 },
-    {   50,  0, 10 }, {  -50,  0, 10 }, RPT_2   (   0,  1,  9 ),
-    {    7,  1, 10 }, {   -7,  1, 10 }, {    8,  1, 10 }, {   -8,  1, 10 },
-    {    9,  1, 10 }, {   -9,  1, 10 }, {   10,  1, 10 }, {  -10,  1, 10 },
-    RPT_2   (   0,  2,  9 ), {    3,  2, 10 }, {   -3,  2, 10 },
-    RPT_2   (   0,  3,  9 ), {    2,  3, 10 }, {   -2,  3, 10 },
-    {    1,  7, 10 }, {   -1,  7, 10 }, {    1,  8, 10 }, {   -1,  8, 10 },
-    { 2048,  0, -1 }, { 2080,  0, -1 }, { 2112,  0, -1 }, { 2144,  0, -1 },
-    { 2176,  0, -1 }, { 2208,  0, -1 }, { 2240,  0, -1 }, { 2272,  0, -1 },
-    { 2304,  0, -1 }, { 2336,  0, -1 }, { 2368,  0, -1 }, { 2400,  0, -1 },
-    { 2432,  0, -1 }, { 2464,  0, -1 }, { 2496,  0, -1 }, { 2528,  0, -1 },
-    { 2560,  0, -1 }, { 2592,  0, -1 }, { 2624,  0, -1 }, { 2656,  0, -1 },
-    { 2688,  0, -1 }, { 2720,  0, -1 }, { 2752,  0, -1 }, {    0,  4, 10 },
-    { 2784,  0, -1 }, {    0,  5, 10 }, {    0,  6, 10 }, { 2816,  0, -1 },
-    { 2848,  0, -1 }, { 2880,  0, -1 }, { 2912,  0, -1 }, { 2944,  0, -1 },
-    { 2976,  0, -1 }, { 3008,  0, -1 }, { 3040,  0, -1 }, { 3072,  0, -1 },
-    { 3104,  0, -1 }, { 3136,  0, -1 }, { 3168,  0, -1 }, { 3200,  0, -1 },
-    RPT_4   (   0,  0, 13 ), RPT_2   (   1,  0, 14 ),
-    RPT_2   (  -1,  0, 14 ), RPT_2   (   2,  0, 14 ),
-    RPT_2   (  -2,  0, 14 ), RPT_2   (   3,  0, 14 ),
-    RPT_2   (  -3,  0, 14 ), RPT_2   (   4,  0, 14 ),
-    RPT_2   (  -4,  0, 14 ), RPT_2   (   5,  0, 14 ),
-    RPT_2   (  -5,  0, 14 ), RPT_2   (   6,  0, 14 ),
-    RPT_2   (  -6,  0, 14 ), RPT_2   (   7,  0, 14 ),
-    RPT_2   (  -7,  0, 14 ), RPT_2   (   8,  0, 14 ),
-    RPT_2   (  -8,  0, 14 ), RPT_2   (   9,  0, 14 ),
-    RPT_2   (  -9,  0, 14 ), RPT_2   (  10,  0, 14 ),
-    RPT_2   ( -10,  0, 14 ), RPT_2   (  11,  0, 14 ),
-    RPT_2   ( -11,  0, 14 ), RPT_2   (  12,  0, 14 ),
-    RPT_2   ( -12,  0, 14 ), RPT_2   (  13,  0, 14 ),
-    RPT_2   ( -13,  0, 14 ), RPT_2   (  14,  0, 14 ),
-    RPT_2   ( -14,  0, 14 ), RPT_2   (  15,  0, 14 ),
-    RPT_2   ( -15,  0, 14 ), RPT_2   (  16,  0, 14 ),
-    RPT_2   ( -16,  0, 14 ), RPT_2   (  17,  0, 14 ),
-    RPT_2   ( -17,  0, 14 ), RPT_2   (  18,  0, 14 ),
-    RPT_2   ( -18,  0, 14 ), RPT_2   (  19,  0, 14 ),
-    RPT_2   ( -19,  0, 14 ), RPT_2   (  20,  0, 14 ),
-    RPT_2   ( -20,  0, 14 ), RPT_2   (  21,  0, 14 ),
-    RPT_2   ( -21,  0, 14 ), RPT_2   (  22,  0, 14 ),
-    RPT_2   ( -22,  0, 14 ), RPT_2   (  23,  0, 14 ),
-    RPT_2   ( -23,  0, 14 ), RPT_2   (  24,  0, 14 ),
-    RPT_2   ( -24,  0, 14 ), RPT_2   (  25,  0, 14 ),
-    RPT_2   ( -25,  0, 14 ), RPT_2   (  26,  0, 14 ),
-    RPT_2   ( -26,  0, 14 ), RPT_2   (  27,  0, 14 ),
-    RPT_2   ( -27,  0, 14 ), RPT_2   (  28,  0, 14 ),
-    RPT_2   ( -28,  0, 14 ), RPT_2   (  29,  0, 14 ),
-    RPT_2   ( -29,  0, 14 ), RPT_2   (  30,  0, 14 ),
-    RPT_2   ( -30,  0, 14 ), RPT_2   (  31,  0, 14 ),
-    RPT_2   ( -31,  0, 14 ), RPT_2   (  32,  0, 14 ),
-    RPT_2   ( -32,  0, 14 ), RPT_2   (  33,  0, 14 ),
-    RPT_2   ( -33,  0, 14 ), RPT_2   (  34,  0, 14 ),
-    RPT_2   ( -34,  0, 14 ), RPT_2   (  35,  0, 14 ),
-    RPT_2   ( -35,  0, 14 ), RPT_2   (  36,  0, 14 ),
-    RPT_2   ( -36,  0, 14 ), RPT_2   (  37,  0, 14 ),
-    RPT_2   ( -37,  0, 14 ), RPT_2   (  38,  0, 14 ),
-    RPT_2   ( -38,  0, 14 ), RPT_2   (  39,  0, 14 ),
-    RPT_2   ( -39,  0, 14 ), RPT_2   (  40,  0, 14 ),
-    RPT_2   ( -40,  0, 14 ), RPT_2   (  41,  0, 14 ),
-    RPT_2   ( -41,  0, 14 ), RPT_2   (  42,  0, 14 ),
-    RPT_2   ( -42,  0, 14 ), RPT_2   (  43,  0, 14 ),
-    RPT_2   ( -43,  0, 14 ), RPT_2   (  44,  0, 14 ),
-    RPT_2   ( -44,  0, 14 ), RPT_2   (  45,  0, 14 ),
-    RPT_2   ( -45,  0, 14 ), RPT_2   (  46,  0, 14 ),
-    RPT_2   ( -46,  0, 14 ), RPT_2   (  47,  0, 14 ),
-    RPT_2   ( -47,  0, 14 ), RPT_2   (  48,  0, 14 ),
-    RPT_2   ( -48,  0, 14 ), RPT_2   (  49,  0, 14 ),
-    RPT_2   ( -49,  0, 14 ), RPT_2   (  50,  0, 14 ),
-    RPT_2   ( -50,  0, 14 ), RPT_2   (  51,  0, 14 ),
-    RPT_2   ( -51,  0, 14 ), RPT_2   (  52,  0, 14 ),
-    RPT_2   ( -52,  0, 14 ), RPT_2   (  53,  0, 14 ),
-    RPT_2   ( -53,  0, 14 ), RPT_2   (  54,  0, 14 ),
-    RPT_2   ( -54,  0, 14 ), RPT_2   (  55,  0, 14 ),
-    RPT_2   ( -55,  0, 14 ), RPT_2   (  56,  0, 14 ),
-    RPT_2   ( -56,  0, 14 ), RPT_2   (  57,  0, 14 ),
-    RPT_2   ( -57,  0, 14 ), RPT_2   (  58,  0, 14 ),
-    RPT_2   ( -58,  0, 14 ), RPT_2   (  59,  0, 14 ),
-    RPT_2   ( -59,  0, 14 ), RPT_2   (  60,  0, 14 ),
-    RPT_2   ( -60,  0, 14 ), RPT_2   (  61,  0, 14 ),
-    RPT_2   ( -61,  0, 14 ), RPT_2   (  62,  0, 14 ),
-    RPT_2   ( -62,  0, 14 ), RPT_2   (  63,  0, 14 ),
-    RPT_2   ( -63,  0, 14 ), RPT_2   (  64,  0, 14 ),
-    RPT_2   ( -64,  0, 14 ), RPT_2   (  65,  0, 14 ),
-    RPT_2   ( -65,  0, 14 ), RPT_2   (  66,  0, 14 ),
-    RPT_2   ( -66,  0, 14 ), RPT_2   (  67,  0, 14 ),
-    RPT_2   ( -67,  0, 14 ), RPT_2   (  68,  0, 14 ),
-    RPT_2   ( -68,  0, 14 ), RPT_2   (  69,  0, 14 ),
-    RPT_2   ( -69,  0, 14 ), RPT_2   (  70,  0, 14 ),
-    RPT_2   ( -70,  0, 14 ), RPT_2   (  71,  0, 14 ),
-    RPT_2   ( -71,  0, 14 ), RPT_2   (  72,  0, 14 ),
-    RPT_2   ( -72,  0, 14 ), RPT_2   (  73,  0, 14 ),
-    RPT_2   ( -73,  0, 14 ), RPT_2   (  74,  0, 14 ),
-    RPT_2   ( -74,  0, 14 ), RPT_2   (  75,  0, 14 ),
-    RPT_2   ( -75,  0, 14 ), RPT_2   (  76,  0, 14 ),
-    RPT_2   ( -76,  0, 14 ), RPT_2   (  77,  0, 14 ),
-    RPT_2   ( -77,  0, 14 ), RPT_2   (  78,  0, 14 ),
-    RPT_2   ( -78,  0, 14 ), RPT_2   (  79,  0, 14 ),
-    RPT_2   ( -79,  0, 14 ), RPT_2   (  80,  0, 14 ),
-    RPT_2   ( -80,  0, 14 ), RPT_2   (  81,  0, 14 ),
-    RPT_2   ( -81,  0, 14 ), RPT_2   (  82,  0, 14 ),
-    RPT_2   ( -82,  0, 14 ), RPT_2   (  83,  0, 14 ),
-    RPT_2   ( -83,  0, 14 ), RPT_2   (  84,  0, 14 ),
-    RPT_2   ( -84,  0, 14 ), RPT_2   (  85,  0, 14 ),
-    RPT_2   ( -85,  0, 14 ), RPT_2   (  86,  0, 14 ),
-    RPT_2   ( -86,  0, 14 ), RPT_2   (  87,  0, 14 ),
-    RPT_2   ( -87,  0, 14 ), RPT_2   (  88,  0, 14 ),
-    RPT_2   ( -88,  0, 14 ), RPT_2   (  89,  0, 14 ),
-    RPT_2   ( -89,  0, 14 ), RPT_2   (  90,  0, 14 ),
-    RPT_2   ( -90,  0, 14 ), RPT_2   (  91,  0, 14 ),
-    RPT_2   ( -91,  0, 14 ), RPT_2   (  92,  0, 14 ),
-    RPT_2   ( -92,  0, 14 ), RPT_2   (  93,  0, 14 ),
-    RPT_2   ( -93,  0, 14 ), RPT_2   (  94,  0, 14 ),
-    RPT_2   ( -94,  0, 14 ), RPT_2   (  95,  0, 14 ),
-    RPT_2   ( -95,  0, 14 ), RPT_2   (  96,  0, 14 ),
-    RPT_2   ( -96,  0, 14 ), RPT_2   (  97,  0, 14 ),
-    RPT_2   ( -97,  0, 14 ), RPT_2   (  98,  0, 14 ),
-    RPT_2   ( -98,  0, 14 ), RPT_2   (  99,  0, 14 ),
-    RPT_2   ( -99,  0, 14 ), RPT_2   ( 100,  0, 14 ),
-    RPT_2   (-100,  0, 14 ), RPT_2   ( 101,  0, 14 ),
-    RPT_2   (-101,  0, 14 ), RPT_2   ( 102,  0, 14 ),
-    RPT_2   (-102,  0, 14 ), RPT_2   ( 103,  0, 14 ),
-    RPT_2   (-103,  0, 14 ), RPT_2   ( 104,  0, 14 ),
-    RPT_2   (-104,  0, 14 ), RPT_2   ( 105,  0, 14 ),
-    RPT_2   (-105,  0, 14 ), RPT_2   ( 106,  0, 14 ),
-    RPT_2   (-106,  0, 14 ), RPT_2   ( 107,  0, 14 ),
-    RPT_2   (-107,  0, 14 ), RPT_2   ( 108,  0, 14 ),
-    RPT_2   (-108,  0, 14 ), RPT_2   ( 109,  0, 14 ),
-    RPT_2   (-109,  0, 14 ), RPT_2   ( 110,  0, 14 ),
-    RPT_2   (-110,  0, 14 ), RPT_2   ( 111,  0, 14 ),
-    RPT_2   (-111,  0, 14 ), RPT_2   ( 112,  0, 14 ),
-    RPT_2   (-112,  0, 14 ), RPT_2   ( 113,  0, 14 ),
-    RPT_2   (-113,  0, 14 ), RPT_2   ( 114,  0, 14 ),
-    RPT_2   (-114,  0, 14 ), RPT_2   ( 115,  0, 14 ),
-    RPT_2   (-115,  0, 14 ), RPT_2   ( 116,  0, 14 ),
-    RPT_2   (-116,  0, 14 ), RPT_2   ( 117,  0, 14 ),
-    RPT_2   (-117,  0, 14 ), RPT_2   ( 118,  0, 14 ),
-    RPT_2   (-118,  0, 14 ), RPT_2   ( 119,  0, 14 ),
-    RPT_2   (-119,  0, 14 ), RPT_2   ( 120,  0, 14 ),
-    RPT_2   (-120,  0, 14 ), RPT_2   ( 121,  0, 14 ),
-    RPT_2   (-121,  0, 14 ), RPT_2   ( 122,  0, 14 ),
-    RPT_2   (-122,  0, 14 ), RPT_2   ( 123,  0, 14 ),
-    RPT_2   (-123,  0, 14 ), RPT_2   ( 124,  0, 14 ),
-    RPT_2   (-124,  0, 14 ), RPT_2   ( 125,  0, 14 ),
-    RPT_2   (-125,  0, 14 ), RPT_2   ( 126,  0, 14 ),
-    RPT_2   (-126,  0, 14 ), RPT_2   ( 127,  0, 14 ),
-    RPT_2   (-127,  0, 14 ), RPT_2   ( 128,  0, 14 ),
-    RPT_2   (-128,  0, 14 ), RPT_2   ( 129,  0, 14 ),
-    RPT_2   (-129,  0, 14 ), RPT_2   ( 130,  0, 14 ),
-    RPT_2   (-130,  0, 14 ), RPT_2   ( 131,  0, 14 ),
-    RPT_2   (-131,  0, 14 ), RPT_2   ( 132,  0, 14 ),
-    RPT_2   (-132,  0, 14 ), RPT_2   ( 133,  0, 14 ),
-    RPT_2   (-133,  0, 14 ), RPT_2   ( 134,  0, 14 ),
-    RPT_2   (-134,  0, 14 ), RPT_2   ( 135,  0, 14 ),
-    RPT_2   (-135,  0, 14 ), RPT_2   ( 136,  0, 14 ),
-    RPT_2   (-136,  0, 14 ), RPT_2   ( 137,  0, 14 ),
-    RPT_2   (-137,  0, 14 ), RPT_2   ( 138,  0, 14 ),
-    RPT_2   (-138,  0, 14 ), RPT_2   ( 139,  0, 14 ),
-    RPT_2   (-139,  0, 14 ), RPT_2   ( 140,  0, 14 ),
-    RPT_2   (-140,  0, 14 ), RPT_2   ( 141,  0, 14 ),
-    RPT_2   (-141,  0, 14 ), RPT_2   ( 142,  0, 14 ),
-    RPT_2   (-142,  0, 14 ), RPT_2   ( 143,  0, 14 ),
-    RPT_2   (-143,  0, 14 ), RPT_2   ( 144,  0, 14 ),
-    RPT_2   (-144,  0, 14 ), RPT_2   ( 145,  0, 14 ),
-    RPT_2   (-145,  0, 14 ), RPT_2   ( 146,  0, 14 ),
-    RPT_2   (-146,  0, 14 ), RPT_2   ( 147,  0, 14 ),
-    RPT_2   (-147,  0, 14 ), RPT_2   ( 148,  0, 14 ),
-    RPT_2   (-148,  0, 14 ), RPT_2   ( 149,  0, 14 ),
-    RPT_2   (-149,  0, 14 ), RPT_2   ( 150,  0, 14 ),
-    RPT_2   (-150,  0, 14 ), RPT_2   ( 151,  0, 14 ),
-    RPT_2   (-151,  0, 14 ), RPT_2   ( 152,  0, 14 ),
-    RPT_2   (-152,  0, 14 ), RPT_2   ( 153,  0, 14 ),
-    RPT_2   (-153,  0, 14 ), RPT_2   ( 154,  0, 14 ),
-    RPT_2   (-154,  0, 14 ), RPT_2   ( 155,  0, 14 ),
-    RPT_2   (-155,  0, 14 ), RPT_2   ( 156,  0, 14 ),
-    RPT_2   (-156,  0, 14 ), RPT_2   ( 157,  0, 14 ),
-    RPT_2   (-157,  0, 14 ), RPT_2   ( 158,  0, 14 ),
-    RPT_2   (-158,  0, 14 ), RPT_2   ( 159,  0, 14 ),
-    RPT_2   (-159,  0, 14 ), RPT_2   ( 160,  0, 14 ),
-    RPT_2   (-160,  0, 14 ), RPT_2   ( 161,  0, 14 ),
-    RPT_2   (-161,  0, 14 ), RPT_2   ( 162,  0, 14 ),
-    RPT_2   (-162,  0, 14 ), RPT_2   ( 163,  0, 14 ),
-    RPT_2   (-163,  0, 14 ), RPT_2   ( 164,  0, 14 ),
-    RPT_2   (-164,  0, 14 ), RPT_2   ( 165,  0, 14 ),
-    RPT_2   (-165,  0, 14 ), RPT_2   ( 166,  0, 14 ),
-    RPT_2   (-166,  0, 14 ), RPT_2   ( 167,  0, 14 ),
-    RPT_2   (-167,  0, 14 ), RPT_2   ( 168,  0, 14 ),
-    RPT_2   (-168,  0, 14 ), RPT_2   ( 169,  0, 14 ),
-    RPT_2   (-169,  0, 14 ), RPT_2   ( 170,  0, 14 ),
-    RPT_2   (-170,  0, 14 ), RPT_2   ( 171,  0, 14 ),
-    RPT_2   (-171,  0, 14 ), RPT_2   ( 172,  0, 14 ),
-    RPT_2   (-172,  0, 14 ), RPT_2   ( 173,  0, 14 ),
-    RPT_2   (-173,  0, 14 ), RPT_2   ( 174,  0, 14 ),
-    RPT_2   (-174,  0, 14 ), RPT_2   ( 175,  0, 14 ),
-    RPT_2   (-175,  0, 14 ), RPT_2   ( 176,  0, 14 ),
-    RPT_2   (-176,  0, 14 ), RPT_2   ( 177,  0, 14 ),
-    RPT_2   (-177,  0, 14 ), RPT_2   ( 178,  0, 14 ),
-    RPT_2   (-178,  0, 14 ), RPT_2   ( 179,  0, 14 ),
-    RPT_2   (-179,  0, 14 ), RPT_2   ( 180,  0, 14 ),
-    RPT_2   (-180,  0, 14 ), RPT_2   ( 181,  0, 14 ),
-    RPT_2   (-181,  0, 14 ), RPT_2   ( 182,  0, 14 ),
-    RPT_2   (-182,  0, 14 ), RPT_2   ( 183,  0, 14 ),
-    RPT_2   (-183,  0, 14 ), RPT_2   ( 184,  0, 14 ),
-    RPT_2   (-184,  0, 14 ), RPT_2   ( 185,  0, 14 ),
-    RPT_2   (-185,  0, 14 ), RPT_2   ( 186,  0, 14 ),
-    RPT_2   (-186,  0, 14 ), RPT_2   ( 187,  0, 14 ),
-    RPT_2   (-187,  0, 14 ), RPT_2   ( 188,  0, 14 ),
-    RPT_2   (-188,  0, 14 ), RPT_2   ( 189,  0, 14 ),
-    RPT_2   (-189,  0, 14 ), RPT_2   ( 190,  0, 14 ),
-    RPT_2   (-190,  0, 14 ), RPT_2   ( 191,  0, 14 ),
-    RPT_2   (-191,  0, 14 ), RPT_2   ( 192,  0, 14 ),
-    RPT_2   (-192,  0, 14 ), RPT_2   ( 193,  0, 14 ),
-    RPT_2   (-193,  0, 14 ), RPT_2   ( 194,  0, 14 ),
-    RPT_2   (-194,  0, 14 ), RPT_2   ( 195,  0, 14 ),
-    RPT_2   (-195,  0, 14 ), RPT_2   ( 196,  0, 14 ),
-    RPT_2   (-196,  0, 14 ), RPT_2   ( 197,  0, 14 ),
-    RPT_2   (-197,  0, 14 ), RPT_2   ( 198,  0, 14 ),
-    RPT_2   (-198,  0, 14 ), RPT_2   ( 199,  0, 14 ),
-    RPT_2   (-199,  0, 14 ), RPT_2   ( 200,  0, 14 ),
-    RPT_2   (-200,  0, 14 ), RPT_2   ( 201,  0, 14 ),
-    RPT_2   (-201,  0, 14 ), RPT_2   ( 202,  0, 14 ),
-    RPT_2   (-202,  0, 14 ), RPT_2   ( 203,  0, 14 ),
-    RPT_2   (-203,  0, 14 ), RPT_2   ( 204,  0, 14 ),
-    RPT_2   (-204,  0, 14 ), RPT_2   ( 205,  0, 14 ),
-    RPT_2   (-205,  0, 14 ), RPT_2   ( 206,  0, 14 ),
-    RPT_2   (-206,  0, 14 ), RPT_2   ( 207,  0, 14 ),
-    RPT_2   (-207,  0, 14 ), RPT_2   ( 208,  0, 14 ),
-    RPT_2   (-208,  0, 14 ), RPT_2   ( 209,  0, 14 ),
-    RPT_2   (-209,  0, 14 ), RPT_2   ( 210,  0, 14 ),
-    RPT_2   (-210,  0, 14 ), RPT_2   ( 211,  0, 14 ),
-    RPT_2   (-211,  0, 14 ), RPT_2   ( 212,  0, 14 ),
-    RPT_2   (-212,  0, 14 ), RPT_2   ( 213,  0, 14 ),
-    RPT_2   (-213,  0, 14 ), RPT_2   ( 214,  0, 14 ),
-    RPT_2   (-214,  0, 14 ), RPT_2   ( 215,  0, 14 ),
-    RPT_2   (-215,  0, 14 ), RPT_2   ( 216,  0, 14 ),
-    RPT_2   (-216,  0, 14 ), RPT_2   ( 217,  0, 14 ),
-    RPT_2   (-217,  0, 14 ), RPT_2   ( 218,  0, 14 ),
-    RPT_2   (-218,  0, 14 ), RPT_2   ( 219,  0, 14 ),
-    RPT_2   (-219,  0, 14 ), RPT_2   ( 220,  0, 14 ),
-    RPT_2   (-220,  0, 14 ), RPT_2   ( 221,  0, 14 ),
-    RPT_2   (-221,  0, 14 ), RPT_2   ( 222,  0, 14 ),
-    RPT_2   (-222,  0, 14 ), RPT_2   ( 223,  0, 14 ),
-    RPT_2   (-223,  0, 14 ), RPT_2   ( 224,  0, 14 ),
-    RPT_2   (-224,  0, 14 ), RPT_2   ( 225,  0, 14 ),
-    RPT_2   (-225,  0, 14 ), RPT_2   ( 226,  0, 14 ),
-    RPT_2   (-226,  0, 14 ), RPT_2   ( 227,  0, 14 ),
-    RPT_2   (-227,  0, 14 ), RPT_2   ( 228,  0, 14 ),
-    RPT_2   (-228,  0, 14 ), RPT_2   ( 229,  0, 14 ),
-    RPT_2   (-229,  0, 14 ), RPT_2   ( 230,  0, 14 ),
-    RPT_2   (-230,  0, 14 ), RPT_2   ( 231,  0, 14 ),
-    RPT_2   (-231,  0, 14 ), RPT_2   ( 232,  0, 14 ),
-    RPT_2   (-232,  0, 14 ), RPT_2   ( 233,  0, 14 ),
-    RPT_2   (-233,  0, 14 ), RPT_2   ( 234,  0, 14 ),
-    RPT_2   (-234,  0, 14 ), RPT_2   ( 235,  0, 14 ),
-    RPT_2   (-235,  0, 14 ), RPT_2   ( 236,  0, 14 ),
-    RPT_2   (-236,  0, 14 ), RPT_2   ( 237,  0, 14 ),
-    RPT_2   (-237,  0, 14 ), RPT_2   ( 238,  0, 14 ),
-    RPT_2   (-238,  0, 14 ), RPT_2   ( 239,  0, 14 ),
-    RPT_2   (-239,  0, 14 ), RPT_2   ( 240,  0, 14 ),
-    RPT_2   (-240,  0, 14 ), RPT_2   ( 241,  0, 14 ),
-    RPT_2   (-241,  0, 14 ), RPT_2   ( 242,  0, 14 ),
-    RPT_2   (-242,  0, 14 ), RPT_2   ( 243,  0, 14 ),
-    RPT_2   (-243,  0, 14 ), RPT_2   ( 244,  0, 14 ),
-    RPT_2   (-244,  0, 14 ), RPT_2   ( 245,  0, 14 ),
-    RPT_2   (-245,  0, 14 ), RPT_2   ( 246,  0, 14 ),
-    RPT_2   (-246,  0, 14 ), RPT_2   ( 247,  0, 14 ),
-    RPT_2   (-247,  0, 14 ), RPT_2   ( 248,  0, 14 ),
-    RPT_2   (-248,  0, 14 ), RPT_2   ( 249,  0, 14 ),
-    RPT_2   (-249,  0, 14 ), RPT_2   ( 250,  0, 14 ),
-    RPT_2   (-250,  0, 14 ), RPT_2   ( 251,  0, 14 ),
-    RPT_2   (-251,  0, 14 ), RPT_2   ( 252,  0, 14 ),
-    RPT_2   (-252,  0, 14 ), RPT_2   ( 253,  0, 14 ),
-    RPT_2   (-253,  0, 14 ), RPT_2   ( 254,  0, 14 ),
-    RPT_2   (-254,  0, 14 ), RPT_2   ( 255,  0, 14 ),
-    RPT_2   (-255,  0, 14 ), {    0,  0, 15 }, {    0,  1, 15 },
-    {    0,  2, 15 }, {    0,  3, 15 }, {    0,  4, 15 }, {    0,  5, 15 },
-    {    0,  6, 15 }, {    0,  7, 15 }, {    0,  8, 15 }, {    0,  9, 15 },
-    {    0, 10, 15 }, {    0, 11, 15 }, {    0, 12, 15 }, {    0, 13, 15 },
-    {    0, 14, 15 }, {    0, 15, 15 }, {    0, 16, 15 }, {    0, 17, 15 },
-    {    0, 18, 15 }, {    0, 19, 15 }, {    0, 20, 15 }, {    0, 21, 15 },
-    {    0, 22, 15 }, {    0, 23, 15 }, {    0, 24, 15 }, {    0, 25, 15 },
-    {    0, 26, 15 }, {    0, 27, 15 }, {    0, 28, 15 }, {    0, 29, 15 },
-    {    0, 30, 15 }, {    0, 31, 15 }, {    0, 32, 15 }, {    0, 33, 15 },
-    {    0, 34, 15 }, {    0, 35, 15 }, {    0, 36, 15 }, {    0, 37, 15 },
-    {    0, 38, 15 }, {    0, 39, 15 }, {    0, 40, 15 }, {    0, 41, 15 },
-    {    0, 42, 15 }, {    0, 43, 15 }, {    0, 44, 15 }, {    0, 45, 15 },
-    {    0, 46, 15 }, {    0, 47, 15 }, {    0, 48, 15 }, {    0, 49, 15 },
-    {    0, 50, 15 }, {    0, 51, 15 }, {    0, 52, 15 }, {    0, 53, 15 },
-    {    0, 54, 15 }, {    0, 55, 15 }, {    0, 56, 15 }, {    0, 57, 15 },
-    {    0, 58, 15 }, {    0, 59, 15 }, {    0, 60, 15 }, {    0, 61, 15 },
-    {    0, 62, 15 }, {    0, 63, 15 }, RPT_16  (  51,  0, 11 ),
-    RPT_16  ( -51,  0, 11 ), RPT_16  (  52,  0, 11 ),
-    RPT_16  ( -52,  0, 11 ), RPT_16  (  53,  0, 11 ),
-    RPT_16  ( -53,  0, 11 ), RPT_16  (  54,  0, 11 ),
-    RPT_16  ( -54,  0, 11 ), RPT_16  (  55,  0, 11 ),
-    RPT_16  ( -55,  0, 11 ), RPT_16  (  56,  0, 11 ),
-    RPT_16  ( -56,  0, 11 ), RPT_16  (  57,  0, 11 ),
-    RPT_16  ( -57,  0, 11 ), RPT_16  (  58,  0, 11 ),
-    RPT_16  ( -58,  0, 11 ), RPT_16  (  59,  0, 11 ),
-    RPT_16  ( -59,  0, 11 ), RPT_16  (  60,  0, 11 ),
-    RPT_16  ( -60,  0, 11 ), RPT_16  (  61,  0, 11 ),
-    RPT_16  ( -61,  0, 11 ), RPT_16  (  62,  0, 11 ),
-    RPT_16  ( -62,  0, 11 ), RPT_16  (  63,  0, 11 ),
-    RPT_16  ( -63,  0, 11 ), RPT_16  (  11,  1, 11 ),
-    RPT_16  ( -11,  1, 11 ), RPT_16  (  12,  1, 11 ),
-    RPT_16  ( -12,  1, 11 ), RPT_16  (  13,  1, 11 ),
-    RPT_16  ( -13,  1, 11 ), RPT_16  (  14,  1, 11 ),
-    RPT_16  ( -14,  1, 11 ), RPT_16  (   4,  2, 11 ),
-    RPT_16  (  -4,  2, 11 ), RPT_16  (   5,  2, 11 ),
-    RPT_16  (  -5,  2, 11 ), RPT_16  (   6,  2, 11 ),
-    RPT_16  (  -6,  2, 11 ), RPT_16  (   3,  3, 11 ),
-    RPT_16  (  -3,  3, 11 ), RPT_16  (   2,  4, 11 ),
-    RPT_16  (  -2,  4, 11 ), RPT_16  (   1,  9, 11 ),
-    RPT_16  (  -1,  9, 11 ), RPT_16  (   1, 10, 11 ),
-    RPT_16  (  -1, 10, 11 ), RPT_8   (  15,  1, 12 ),
-    RPT_8   ( -15,  1, 12 ), RPT_8   (  16,  1, 12 ),
-    RPT_8   ( -16,  1, 12 ), RPT_8   (  17,  1, 12 ),
-    RPT_8   ( -17,  1, 12 ), RPT_8   (  18,  1, 12 ),
-    RPT_8   ( -18,  1, 12 ), RPT_8   (   7,  2, 12 ),
-    RPT_8   (  -7,  2, 12 ), RPT_8   (   8,  2, 12 ),
-    RPT_8   (  -8,  2, 12 ), RPT_8   (   9,  2, 12 ),
-    RPT_8   (  -9,  2, 12 ), RPT_8   (  10,  2, 12 ),
-    RPT_8   ( -10,  2, 12 ), RPT_8   (   4,  3, 12 ),
-    RPT_8   (  -4,  3, 12 ), RPT_8   (   5,  3, 12 ),
-    RPT_8   (  -5,  3, 12 ), RPT_8   (   6,  3, 12 ),
-    RPT_8   (  -6,  3, 12 ), RPT_8   (   2,  5, 12 ),
-    RPT_8   (  -2,  5, 12 ), RPT_16  (   0,  7, 11 ),
-    RPT_16  (   0,  8, 11 ), RPT_16  (   0,  9, 11 ),
-    RPT_16  (   0, 10, 11 ), RPT_8   (   1, 11, 12 ),
-    RPT_8   (  -1, 11, 12 ), RPT_8   (   1, 12, 12 ),
-    RPT_8   (  -1, 12, 12 ), RPT_8   (   1, 13, 12 ),
-    RPT_8   (  -1, 13, 12 ), RPT_8   (   1, 14, 12 ),
-    RPT_8   (  -1, 14, 12 ), RPT_4   (  19,  1, 13 ),
-    RPT_4   ( -19,  1, 13 ), RPT_4   (  20,  1, 13 ),
-    RPT_4   ( -20,  1, 13 ), RPT_4   (   3,  4, 13 ),
-    RPT_4   (  -3,  4, 13 ), RPT_4   (   2,  6, 13 ),
-    RPT_4   (  -2,  6, 13 ),
+HQXAC ff_hqx_ac[NUM_HQX_AC] = {
+    { 10 }, { 11 }, { 11 }, { 11 }, { 12 }, { 11 },
 };
 
-static const HQXLUT ac8_lut[] = {
-    RPT_128 (   1,  0,  4 ), RPT_128 (  -1,  0,  4 ),
-    RPT_128 (   2,  0,  4 ), RPT_128 (  -2,  0,  4 ),
-    RPT_64  (   3,  0,  5 ), RPT_64  (  -3,  0,  5 ),
-    RPT_64  (   4,  0,  5 ), RPT_64  (  -4,  0,  5 ),
-    RPT_128 (   0, 64,  4 ), RPT_32  (   5,  0,  6 ),
-    RPT_32  (  -5,  0,  6 ), RPT_32  (   6,  0,  6 ),
-    RPT_32  (  -6,  0,  6 ), RPT_32  (   7,  0,  6 ),
-    RPT_32  (  -7,  0,  6 ), RPT_32  (   8,  0,  6 ),
-    RPT_32  (  -8,  0,  6 ), RPT_32  (   1,  1,  6 ),
-    RPT_32  (  -1,  1,  6 ), RPT_32  (   2,  1,  6 ),
-    RPT_32  (  -2,  1,  6 ), RPT_16  (   9,  0,  7 ),
-    RPT_16  (  -9,  0,  7 ), RPT_16  (  10,  0,  7 ),
-    RPT_16  ( -10,  0,  7 ), RPT_16  (  11,  0,  7 ),
-    RPT_16  ( -11,  0,  7 ), RPT_16  (  12,  0,  7 ),
-    RPT_16  ( -12,  0,  7 ), RPT_16  (   3,  1,  7 ),
-    RPT_16  (  -3,  1,  7 ), RPT_16  (   4,  1,  7 ),
-    RPT_16  (  -4,  1,  7 ), RPT_16  (   1,  2,  7 ),
-    RPT_16  (  -1,  2,  7 ), { 2048,  0, -1 }, { 2112,  0, -1 },
-    { 2176,  0, -1 }, { 2240,  0, -1 }, { 2304,  0, -1 }, { 2368,  0, -1 },
-    { 2432,  0, -1 }, { 2496,  0, -1 }, { 2560,  0, -1 }, { 2624,  0, -1 },
-    { 2688,  0, -1 }, { 2752,  0, -1 }, { 2816,  0, -1 }, { 2880,  0, -1 },
-    { 2944,  0, -1 }, { 3008,  0, -1 }, { 3072,  0, -1 }, { 3136,  0, -1 },
-    { 3200,  0, -1 }, { 3264,  0, -1 }, { 3328,  0, -1 }, { 3392,  0, -1 },
-    { 3456,  0, -1 }, { 3520,  0, -1 }, { 3584,  0, -1 }, { 3648,  0, -1 },
-    { 3712,  0, -1 }, { 3776,  0, -1 }, { 3840,  0, -1 }, { 3904,  0, -1 },
-    { 3968,  0, -1 }, { 4032,  0, -1 }, RPT_8   (  13,  0,  8 ),
-    RPT_8   ( -13,  0,  8 ), RPT_8   (  14,  0,  8 ),
-    RPT_8   ( -14,  0,  8 ), RPT_8   (  15,  0,  8 ),
-    RPT_8   ( -15,  0,  8 ), RPT_8   (  16,  0,  8 ),
-    RPT_8   ( -16,  0,  8 ), RPT_8   (  17,  0,  8 ),
-    RPT_8   ( -17,  0,  8 ), RPT_8   (  18,  0,  8 ),
-    RPT_8   ( -18,  0,  8 ), RPT_8   (   5,  1,  8 ),
-    RPT_8   (  -5,  1,  8 ), RPT_8   (   6,  1,  8 ),
-    RPT_8   (  -6,  1,  8 ), RPT_8   (   2,  2,  8 ),
-    RPT_8   (  -2,  2,  8 ), RPT_8   (   1,  3,  8 ),
-    RPT_8   (  -1,  3,  8 ), RPT_8   (   0,  0,  8 ),
-    RPT_4   (  19,  0,  9 ), RPT_4   ( -19,  0,  9 ),
-    RPT_4   (  20,  0,  9 ), RPT_4   ( -20,  0,  9 ),
-    RPT_4   (  21,  0,  9 ), RPT_4   ( -21,  0,  9 ),
-    RPT_4   (  22,  0,  9 ), RPT_4   ( -22,  0,  9 ),
-    RPT_4   (  23,  0,  9 ), RPT_4   ( -23,  0,  9 ),
-    RPT_4   (  24,  0,  9 ), RPT_4   ( -24,  0,  9 ),
-    RPT_4   (  25,  0,  9 ), RPT_4   ( -25,  0,  9 ),
-    RPT_4   (   7,  1,  9 ), RPT_4   (  -7,  1,  9 ),
-    RPT_4   (   8,  1,  9 ), RPT_4   (  -8,  1,  9 ),
-    RPT_4   (   3,  2,  9 ), RPT_4   (  -3,  2,  9 ),
-    RPT_4   (   2,  3,  9 ), RPT_4   (  -2,  3,  9 ),
-    RPT_4   (   1,  4,  9 ), RPT_4   (  -1,  4,  9 ),
-    RPT_4   (   1,  5,  9 ), RPT_4   (  -1,  5,  9 ),
-    RPT_2   (  26,  0, 10 ), RPT_2   ( -26,  0, 10 ),
-    RPT_2   (  27,  0, 10 ), RPT_2   ( -27,  0, 10 ),
-    RPT_2   (  28,  0, 10 ), RPT_2   ( -28,  0, 10 ),
-    RPT_2   (  29,  0, 10 ), RPT_2   ( -29,  0, 10 ),
-    RPT_2   (  30,  0, 10 ), RPT_2   ( -30,  0, 10 ),
-    RPT_2   (  31,  0, 10 ), RPT_2   ( -31,  0, 10 ),
-    RPT_2   (  32,  0, 10 ), RPT_2   ( -32,  0, 10 ),
-    RPT_2   (  33,  0, 10 ), RPT_2   ( -33,  0, 10 ),
-    RPT_2   (  34,  0, 10 ), RPT_2   ( -34,  0, 10 ),
-    RPT_2   (  35,  0, 10 ), RPT_2   ( -35,  0, 10 ),
-    RPT_2   (  36,  0, 10 ), RPT_2   ( -36,  0, 10 ),
-    RPT_4   (   0,  1,  9 ), RPT_2   (   9,  1, 10 ),
-    RPT_2   (  -9,  1, 10 ), RPT_2   (  10,  1, 10 ),
-    RPT_2   ( -10,  1, 10 ), RPT_2   (  11,  1, 10 ),
-    RPT_2   ( -11,  1, 10 ), RPT_2   (  12,  1, 10 ),
-    RPT_2   ( -12,  1, 10 ), RPT_4   (   0,  2,  9 ),
-    RPT_2   (   4,  2, 10 ), RPT_2   (  -4,  2, 10 ),
-    RPT_2   (   5,  2, 10 ), RPT_2   (  -5,  2, 10 ),
-    RPT_2   (   6,  2, 10 ), RPT_2   (  -6,  2, 10 ),
-    RPT_4   (   0,  3,  9 ), RPT_2   (   3,  3, 10 ),
-    RPT_2   (  -3,  3, 10 ), RPT_2   (   4,  3, 10 ),
-    RPT_2   (  -4,  3, 10 ), RPT_4   (   0,  4,  9 ),
-    RPT_2   (   2,  4, 10 ), RPT_2   (  -2,  4, 10 ),
-    RPT_4   (   0,  5,  9 ), RPT_2   (   1,  6, 10 ),
-    RPT_2   (  -1,  6, 10 ), RPT_2   (   1,  7, 10 ),
-    RPT_2   (  -1,  7, 10 ), RPT_2   (   1,  8, 10 ),
-    RPT_2   (  -1,  8, 10 ), {   37,  0, 11 }, {  -37,  0, 11 },
-    {   38,  0, 11 }, {  -38,  0, 11 }, {   39,  0, 11 }, {  -39,  0, 11 },
-    {   40,  0, 11 }, {  -40,  0, 11 }, {   41,  0, 11 }, {  -41,  0, 11 },
-    {   42,  0, 11 }, {  -42,  0, 11 }, {   43,  0, 11 }, {  -43,  0, 11 },
-    {   44,  0, 11 }, {  -44,  0, 11 }, {   45,  0, 11 }, {  -45,  0, 11 },
-    {   46,  0, 11 }, {  -46,  0, 11 }, {   47,  0, 11 }, {  -47,  0, 11 },
-    {   48,  0, 11 }, {  -48,  0, 11 }, {   13,  1, 11 }, {  -13,  1, 11 },
-    {   14,  1, 11 }, {  -14,  1, 11 }, {   15,  1, 11 }, {  -15,  1, 11 },
-    {   16,  1, 11 }, {  -16,  1, 11 }, {    7,  2, 11 }, {   -7,  2, 11 },
-    {    8,  2, 11 }, {   -8,  2, 11 }, {    5,  3, 11 }, {   -5,  3, 11 },
-    {    6,  3, 11 }, {   -6,  3, 11 }, {    3,  4, 11 }, {   -3,  4, 11 },
-    {    4,  4, 11 }, {   -4,  4, 11 }, {    2,  5, 11 }, {   -2,  5, 11 },
-    RPT_2   (   0,  6, 10 ), {    2,  6, 11 }, {   -2,  6, 11 },
-    RPT_2   (   0,  7, 10 ), RPT_2   (   0,  8, 10 ),
-    RPT_2   (   0,  9, 10 ), {    1,  9, 11 }, {   -1,  9, 11 },
-    {    1, 10, 11 }, {   -1, 10, 11 }, {    1, 11, 11 }, {   -1, 11, 11 },
-    {    1, 12, 11 }, {   -1, 12, 11 }, { 4096,  0, -1 }, { 4160,  0, -1 },
-    { 4224,  0, -1 }, { 4288,  0, -1 }, { 4352,  0, -1 }, { 4416,  0, -1 },
-    { 4480,  0, -1 }, { 4544,  0, -1 }, { 4608,  0, -1 }, { 4672,  0, -1 },
-    { 4736,  0, -1 }, { 4800,  0, -1 }, { 4864,  0, -1 }, { 4928,  0, -1 },
-    { 4992,  0, -1 }, { 5056,  0, -1 }, { 5120,  0, -1 }, { 5184,  0, -1 },
-    { 5248,  0, -1 }, { 5312,  0, -1 }, { 5376,  0, -1 }, { 5440,  0, -1 },
-    { 5504,  0, -1 }, { 5568,  0, -1 }, { 5632,  0, -1 }, { 5696,  0, -1 },
-    { 5760,  0, -1 }, { 5824,  0, -1 }, { 5888,  0, -1 }, { 5952,  0, -1 },
-    { 6016,  0, -1 }, { 6080,  0, -1 }, { 6144,  0, -1 }, { 6208,  0, -1 },
-    { 6272,  0, -1 }, { 6336,  0, -1 }, { 6400,  0, -1 }, { 6464,  0, -1 },
-    { 6528,  0, -1 }, { 6592,  0, -1 }, {    0, 10, 11 }, { 6656,  0, -1 },
-    {    0, 11, 11 }, {    0, 12, 11 }, {    0, 13, 11 }, { 6720,  0, -1 },
-    { 6784,  0, -1 }, { 6848,  0, -1 }, { 6912,  0, -1 }, { 6976,  0, -1 },
-    { 7040,  0, -1 }, { 7104,  0, -1 }, { 7168,  0, -1 }, { 7232,  0, -1 },
-    { 7296,  0, -1 }, { 7360,  0, -1 }, { 7424,  0, -1 }, { 7488,  0, -1 },
-    { 7552,  0, -1 }, { 7616,  0, -1 }, RPT_8   (   0,  0, 14 ),
-    RPT_4   (   1,  0, 15 ), RPT_4   (  -1,  0, 15 ),
-    RPT_4   (   2,  0, 15 ), RPT_4   (  -2,  0, 15 ),
-    RPT_4   (   3,  0, 15 ), RPT_4   (  -3,  0, 15 ),
-    RPT_4   (   4,  0, 15 ), RPT_4   (  -4,  0, 15 ),
-    RPT_4   (   5,  0, 15 ), RPT_4   (  -5,  0, 15 ),
-    RPT_4   (   6,  0, 15 ), RPT_4   (  -6,  0, 15 ),
-    RPT_4   (   7,  0, 15 ), RPT_4   (  -7,  0, 15 ),
-    RPT_4   (   8,  0, 15 ), RPT_4   (  -8,  0, 15 ),
-    RPT_4   (   9,  0, 15 ), RPT_4   (  -9,  0, 15 ),
-    RPT_4   (  10,  0, 15 ), RPT_4   ( -10,  0, 15 ),
-    RPT_4   (  11,  0, 15 ), RPT_4   ( -11,  0, 15 ),
-    RPT_4   (  12,  0, 15 ), RPT_4   ( -12,  0, 15 ),
-    RPT_4   (  13,  0, 15 ), RPT_4   ( -13,  0, 15 ),
-    RPT_4   (  14,  0, 15 ), RPT_4   ( -14,  0, 15 ),
-    RPT_4   (  15,  0, 15 ), RPT_4   ( -15,  0, 15 ),
-    RPT_4   (  16,  0, 15 ), RPT_4   ( -16,  0, 15 ),
-    RPT_4   (  17,  0, 15 ), RPT_4   ( -17,  0, 15 ),
-    RPT_4   (  18,  0, 15 ), RPT_4   ( -18,  0, 15 ),
-    RPT_4   (  19,  0, 15 ), RPT_4   ( -19,  0, 15 ),
-    RPT_4   (  20,  0, 15 ), RPT_4   ( -20,  0, 15 ),
-    RPT_4   (  21,  0, 15 ), RPT_4   ( -21,  0, 15 ),
-    RPT_4   (  22,  0, 15 ), RPT_4   ( -22,  0, 15 ),
-    RPT_4   (  23,  0, 15 ), RPT_4   ( -23,  0, 15 ),
-    RPT_4   (  24,  0, 15 ), RPT_4   ( -24,  0, 15 ),
-    RPT_4   (  25,  0, 15 ), RPT_4   ( -25,  0, 15 ),
-    RPT_4   (  26,  0, 15 ), RPT_4   ( -26,  0, 15 ),
-    RPT_4   (  27,  0, 15 ), RPT_4   ( -27,  0, 15 ),
-    RPT_4   (  28,  0, 15 ), RPT_4   ( -28,  0, 15 ),
-    RPT_4   (  29,  0, 15 ), RPT_4   ( -29,  0, 15 ),
-    RPT_4   (  30,  0, 15 ), RPT_4   ( -30,  0, 15 ),
-    RPT_4   (  31,  0, 15 ), RPT_4   ( -31,  0, 15 ),
-    RPT_4   (  32,  0, 15 ), RPT_4   ( -32,  0, 15 ),
-    RPT_4   (  33,  0, 15 ), RPT_4   ( -33,  0, 15 ),
-    RPT_4   (  34,  0, 15 ), RPT_4   ( -34,  0, 15 ),
-    RPT_4   (  35,  0, 15 ), RPT_4   ( -35,  0, 15 ),
-    RPT_4   (  36,  0, 15 ), RPT_4   ( -36,  0, 15 ),
-    RPT_4   (  37,  0, 15 ), RPT_4   ( -37,  0, 15 ),
-    RPT_4   (  38,  0, 15 ), RPT_4   ( -38,  0, 15 ),
-    RPT_4   (  39,  0, 15 ), RPT_4   ( -39,  0, 15 ),
-    RPT_4   (  40,  0, 15 ), RPT_4   ( -40,  0, 15 ),
-    RPT_4   (  41,  0, 15 ), RPT_4   ( -41,  0, 15 ),
-    RPT_4   (  42,  0, 15 ), RPT_4   ( -42,  0, 15 ),
-    RPT_4   (  43,  0, 15 ), RPT_4   ( -43,  0, 15 ),
-    RPT_4   (  44,  0, 15 ), RPT_4   ( -44,  0, 15 ),
-    RPT_4   (  45,  0, 15 ), RPT_4   ( -45,  0, 15 ),
-    RPT_4   (  46,  0, 15 ), RPT_4   ( -46,  0, 15 ),
-    RPT_4   (  47,  0, 15 ), RPT_4   ( -47,  0, 15 ),
-    RPT_4   (  48,  0, 15 ), RPT_4   ( -48,  0, 15 ),
-    RPT_4   (  49,  0, 15 ), RPT_4   ( -49,  0, 15 ),
-    RPT_4   (  50,  0, 15 ), RPT_4   ( -50,  0, 15 ),
-    RPT_4   (  51,  0, 15 ), RPT_4   ( -51,  0, 15 ),
-    RPT_4   (  52,  0, 15 ), RPT_4   ( -52,  0, 15 ),
-    RPT_4   (  53,  0, 15 ), RPT_4   ( -53,  0, 15 ),
-    RPT_4   (  54,  0, 15 ), RPT_4   ( -54,  0, 15 ),
-    RPT_4   (  55,  0, 15 ), RPT_4   ( -55,  0, 15 ),
-    RPT_4   (  56,  0, 15 ), RPT_4   ( -56,  0, 15 ),
-    RPT_4   (  57,  0, 15 ), RPT_4   ( -57,  0, 15 ),
-    RPT_4   (  58,  0, 15 ), RPT_4   ( -58,  0, 15 ),
-    RPT_4   (  59,  0, 15 ), RPT_4   ( -59,  0, 15 ),
-    RPT_4   (  60,  0, 15 ), RPT_4   ( -60,  0, 15 ),
-    RPT_4   (  61,  0, 15 ), RPT_4   ( -61,  0, 15 ),
-    RPT_4   (  62,  0, 15 ), RPT_4   ( -62,  0, 15 ),
-    RPT_4   (  63,  0, 15 ), RPT_4   ( -63,  0, 15 ),
-    RPT_4   (  64,  0, 15 ), RPT_4   ( -64,  0, 15 ),
-    RPT_4   (  65,  0, 15 ), RPT_4   ( -65,  0, 15 ),
-    RPT_4   (  66,  0, 15 ), RPT_4   ( -66,  0, 15 ),
-    RPT_4   (  67,  0, 15 ), RPT_4   ( -67,  0, 15 ),
-    RPT_4   (  68,  0, 15 ), RPT_4   ( -68,  0, 15 ),
-    RPT_4   (  69,  0, 15 ), RPT_4   ( -69,  0, 15 ),
-    RPT_4   (  70,  0, 15 ), RPT_4   ( -70,  0, 15 ),
-    RPT_4   (  71,  0, 15 ), RPT_4   ( -71,  0, 15 ),
-    RPT_4   (  72,  0, 15 ), RPT_4   ( -72,  0, 15 ),
-    RPT_4   (  73,  0, 15 ), RPT_4   ( -73,  0, 15 ),
-    RPT_4   (  74,  0, 15 ), RPT_4   ( -74,  0, 15 ),
-    RPT_4   (  75,  0, 15 ), RPT_4   ( -75,  0, 15 ),
-    RPT_4   (  76,  0, 15 ), RPT_4   ( -76,  0, 15 ),
-    RPT_4   (  77,  0, 15 ), RPT_4   ( -77,  0, 15 ),
-    RPT_4   (  78,  0, 15 ), RPT_4   ( -78,  0, 15 ),
-    RPT_4   (  79,  0, 15 ), RPT_4   ( -79,  0, 15 ),
-    RPT_4   (  80,  0, 15 ), RPT_4   ( -80,  0, 15 ),
-    RPT_4   (  81,  0, 15 ), RPT_4   ( -81,  0, 15 ),
-    RPT_4   (  82,  0, 15 ), RPT_4   ( -82,  0, 15 ),
-    RPT_4   (  83,  0, 15 ), RPT_4   ( -83,  0, 15 ),
-    RPT_4   (  84,  0, 15 ), RPT_4   ( -84,  0, 15 ),
-    RPT_4   (  85,  0, 15 ), RPT_4   ( -85,  0, 15 ),
-    RPT_4   (  86,  0, 15 ), RPT_4   ( -86,  0, 15 ),
-    RPT_4   (  87,  0, 15 ), RPT_4   ( -87,  0, 15 ),
-    RPT_4   (  88,  0, 15 ), RPT_4   ( -88,  0, 15 ),
-    RPT_4   (  89,  0, 15 ), RPT_4   ( -89,  0, 15 ),
-    RPT_4   (  90,  0, 15 ), RPT_4   ( -90,  0, 15 ),
-    RPT_4   (  91,  0, 15 ), RPT_4   ( -91,  0, 15 ),
-    RPT_4   (  92,  0, 15 ), RPT_4   ( -92,  0, 15 ),
-    RPT_4   (  93,  0, 15 ), RPT_4   ( -93,  0, 15 ),
-    RPT_4   (  94,  0, 15 ), RPT_4   ( -94,  0, 15 ),
-    RPT_4   (  95,  0, 15 ), RPT_4   ( -95,  0, 15 ),
-    RPT_4   (  96,  0, 15 ), RPT_4   ( -96,  0, 15 ),
-    RPT_4   (  97,  0, 15 ), RPT_4   ( -97,  0, 15 ),
-    RPT_4   (  98,  0, 15 ), RPT_4   ( -98,  0, 15 ),
-    RPT_4   (  99,  0, 15 ), RPT_4   ( -99,  0, 15 ),
-    RPT_4   ( 100,  0, 15 ), RPT_4   (-100,  0, 15 ),
-    RPT_4   ( 101,  0, 15 ), RPT_4   (-101,  0, 15 ),
-    RPT_4   ( 102,  0, 15 ), RPT_4   (-102,  0, 15 ),
-    RPT_4   ( 103,  0, 15 ), RPT_4   (-103,  0, 15 ),
-    RPT_4   ( 104,  0, 15 ), RPT_4   (-104,  0, 15 ),
-    RPT_4   ( 105,  0, 15 ), RPT_4   (-105,  0, 15 ),
-    RPT_4   ( 106,  0, 15 ), RPT_4   (-106,  0, 15 ),
-    RPT_4   ( 107,  0, 15 ), RPT_4   (-107,  0, 15 ),
-    RPT_4   ( 108,  0, 15 ), RPT_4   (-108,  0, 15 ),
-    RPT_4   ( 109,  0, 15 ), RPT_4   (-109,  0, 15 ),
-    RPT_4   ( 110,  0, 15 ), RPT_4   (-110,  0, 15 ),
-    RPT_4   ( 111,  0, 15 ), RPT_4   (-111,  0, 15 ),
-    RPT_4   ( 112,  0, 15 ), RPT_4   (-112,  0, 15 ),
-    RPT_4   ( 113,  0, 15 ), RPT_4   (-113,  0, 15 ),
-    RPT_4   ( 114,  0, 15 ), RPT_4   (-114,  0, 15 ),
-    RPT_4   ( 115,  0, 15 ), RPT_4   (-115,  0, 15 ),
-    RPT_4   ( 116,  0, 15 ), RPT_4   (-116,  0, 15 ),
-    RPT_4   ( 117,  0, 15 ), RPT_4   (-117,  0, 15 ),
-    RPT_4   ( 118,  0, 15 ), RPT_4   (-118,  0, 15 ),
-    RPT_4   ( 119,  0, 15 ), RPT_4   (-119,  0, 15 ),
-    RPT_4   ( 120,  0, 15 ), RPT_4   (-120,  0, 15 ),
-    RPT_4   ( 121,  0, 15 ), RPT_4   (-121,  0, 15 ),
-    RPT_4   ( 122,  0, 15 ), RPT_4   (-122,  0, 15 ),
-    RPT_4   ( 123,  0, 15 ), RPT_4   (-123,  0, 15 ),
-    RPT_4   ( 124,  0, 15 ), RPT_4   (-124,  0, 15 ),
-    RPT_4   ( 125,  0, 15 ), RPT_4   (-125,  0, 15 ),
-    RPT_4   ( 126,  0, 15 ), RPT_4   (-126,  0, 15 ),
-    RPT_4   ( 127,  0, 15 ), RPT_4   (-127,  0, 15 ),
-    RPT_4   ( 128,  0, 15 ), RPT_4   (-128,  0, 15 ),
-    RPT_4   ( 129,  0, 15 ), RPT_4   (-129,  0, 15 ),
-    RPT_4   ( 130,  0, 15 ), RPT_4   (-130,  0, 15 ),
-    RPT_4   ( 131,  0, 15 ), RPT_4   (-131,  0, 15 ),
-    RPT_4   ( 132,  0, 15 ), RPT_4   (-132,  0, 15 ),
-    RPT_4   ( 133,  0, 15 ), RPT_4   (-133,  0, 15 ),
-    RPT_4   ( 134,  0, 15 ), RPT_4   (-134,  0, 15 ),
-    RPT_4   ( 135,  0, 15 ), RPT_4   (-135,  0, 15 ),
-    RPT_4   ( 136,  0, 15 ), RPT_4   (-136,  0, 15 ),
-    RPT_4   ( 137,  0, 15 ), RPT_4   (-137,  0, 15 ),
-    RPT_4   ( 138,  0, 15 ), RPT_4   (-138,  0, 15 ),
-    RPT_4   ( 139,  0, 15 ), RPT_4   (-139,  0, 15 ),
-    RPT_4   ( 140,  0, 15 ), RPT_4   (-140,  0, 15 ),
-    RPT_4   ( 141,  0, 15 ), RPT_4   (-141,  0, 15 ),
-    RPT_4   ( 142,  0, 15 ), RPT_4   (-142,  0, 15 ),
-    RPT_4   ( 143,  0, 15 ), RPT_4   (-143,  0, 15 ),
-    RPT_4   ( 144,  0, 15 ), RPT_4   (-144,  0, 15 ),
-    RPT_4   ( 145,  0, 15 ), RPT_4   (-145,  0, 15 ),
-    RPT_4   ( 146,  0, 15 ), RPT_4   (-146,  0, 15 ),
-    RPT_4   ( 147,  0, 15 ), RPT_4   (-147,  0, 15 ),
-    RPT_4   ( 148,  0, 15 ), RPT_4   (-148,  0, 15 ),
-    RPT_4   ( 149,  0, 15 ), RPT_4   (-149,  0, 15 ),
-    RPT_4   ( 150,  0, 15 ), RPT_4   (-150,  0, 15 ),
-    RPT_4   ( 151,  0, 15 ), RPT_4   (-151,  0, 15 ),
-    RPT_4   ( 152,  0, 15 ), RPT_4   (-152,  0, 15 ),
-    RPT_4   ( 153,  0, 15 ), RPT_4   (-153,  0, 15 ),
-    RPT_4   ( 154,  0, 15 ), RPT_4   (-154,  0, 15 ),
-    RPT_4   ( 155,  0, 15 ), RPT_4   (-155,  0, 15 ),
-    RPT_4   ( 156,  0, 15 ), RPT_4   (-156,  0, 15 ),
-    RPT_4   ( 157,  0, 15 ), RPT_4   (-157,  0, 15 ),
-    RPT_4   ( 158,  0, 15 ), RPT_4   (-158,  0, 15 ),
-    RPT_4   ( 159,  0, 15 ), RPT_4   (-159,  0, 15 ),
-    RPT_4   ( 160,  0, 15 ), RPT_4   (-160,  0, 15 ),
-    RPT_4   ( 161,  0, 15 ), RPT_4   (-161,  0, 15 ),
-    RPT_4   ( 162,  0, 15 ), RPT_4   (-162,  0, 15 ),
-    RPT_4   ( 163,  0, 15 ), RPT_4   (-163,  0, 15 ),
-    RPT_4   ( 164,  0, 15 ), RPT_4   (-164,  0, 15 ),
-    RPT_4   ( 165,  0, 15 ), RPT_4   (-165,  0, 15 ),
-    RPT_4   ( 166,  0, 15 ), RPT_4   (-166,  0, 15 ),
-    RPT_4   ( 167,  0, 15 ), RPT_4   (-167,  0, 15 ),
-    RPT_4   ( 168,  0, 15 ), RPT_4   (-168,  0, 15 ),
-    RPT_4   ( 169,  0, 15 ), RPT_4   (-169,  0, 15 ),
-    RPT_4   ( 170,  0, 15 ), RPT_4   (-170,  0, 15 ),
-    RPT_4   ( 171,  0, 15 ), RPT_4   (-171,  0, 15 ),
-    RPT_4   ( 172,  0, 15 ), RPT_4   (-172,  0, 15 ),
-    RPT_4   ( 173,  0, 15 ), RPT_4   (-173,  0, 15 ),
-    RPT_4   ( 174,  0, 15 ), RPT_4   (-174,  0, 15 ),
-    RPT_4   ( 175,  0, 15 ), RPT_4   (-175,  0, 15 ),
-    RPT_4   ( 176,  0, 15 ), RPT_4   (-176,  0, 15 ),
-    RPT_4   ( 177,  0, 15 ), RPT_4   (-177,  0, 15 ),
-    RPT_4   ( 178,  0, 15 ), RPT_4   (-178,  0, 15 ),
-    RPT_4   ( 179,  0, 15 ), RPT_4   (-179,  0, 15 ),
-    RPT_4   ( 180,  0, 15 ), RPT_4   (-180,  0, 15 ),
-    RPT_4   ( 181,  0, 15 ), RPT_4   (-181,  0, 15 ),
-    RPT_4   ( 182,  0, 15 ), RPT_4   (-182,  0, 15 ),
-    RPT_4   ( 183,  0, 15 ), RPT_4   (-183,  0, 15 ),
-    RPT_4   ( 184,  0, 15 ), RPT_4   (-184,  0, 15 ),
-    RPT_4   ( 185,  0, 15 ), RPT_4   (-185,  0, 15 ),
-    RPT_4   ( 186,  0, 15 ), RPT_4   (-186,  0, 15 ),
-    RPT_4   ( 187,  0, 15 ), RPT_4   (-187,  0, 15 ),
-    RPT_4   ( 188,  0, 15 ), RPT_4   (-188,  0, 15 ),
-    RPT_4   ( 189,  0, 15 ), RPT_4   (-189,  0, 15 ),
-    RPT_4   ( 190,  0, 15 ), RPT_4   (-190,  0, 15 ),
-    RPT_4   ( 191,  0, 15 ), RPT_4   (-191,  0, 15 ),
-    RPT_4   ( 192,  0, 15 ), RPT_4   (-192,  0, 15 ),
-    RPT_4   ( 193,  0, 15 ), RPT_4   (-193,  0, 15 ),
-    RPT_4   ( 194,  0, 15 ), RPT_4   (-194,  0, 15 ),
-    RPT_4   ( 195,  0, 15 ), RPT_4   (-195,  0, 15 ),
-    RPT_4   ( 196,  0, 15 ), RPT_4   (-196,  0, 15 ),
-    RPT_4   ( 197,  0, 15 ), RPT_4   (-197,  0, 15 ),
-    RPT_4   ( 198,  0, 15 ), RPT_4   (-198,  0, 15 ),
-    RPT_4   ( 199,  0, 15 ), RPT_4   (-199,  0, 15 ),
-    RPT_4   ( 200,  0, 15 ), RPT_4   (-200,  0, 15 ),
-    RPT_4   ( 201,  0, 15 ), RPT_4   (-201,  0, 15 ),
-    RPT_4   ( 202,  0, 15 ), RPT_4   (-202,  0, 15 ),
-    RPT_4   ( 203,  0, 15 ), RPT_4   (-203,  0, 15 ),
-    RPT_4   ( 204,  0, 15 ), RPT_4   (-204,  0, 15 ),
-    RPT_4   ( 205,  0, 15 ), RPT_4   (-205,  0, 15 ),
-    RPT_4   ( 206,  0, 15 ), RPT_4   (-206,  0, 15 ),
-    RPT_4   ( 207,  0, 15 ), RPT_4   (-207,  0, 15 ),
-    RPT_4   ( 208,  0, 15 ), RPT_4   (-208,  0, 15 ),
-    RPT_4   ( 209,  0, 15 ), RPT_4   (-209,  0, 15 ),
-    RPT_4   ( 210,  0, 15 ), RPT_4   (-210,  0, 15 ),
-    RPT_4   ( 211,  0, 15 ), RPT_4   (-211,  0, 15 ),
-    RPT_4   ( 212,  0, 15 ), RPT_4   (-212,  0, 15 ),
-    RPT_4   ( 213,  0, 15 ), RPT_4   (-213,  0, 15 ),
-    RPT_4   ( 214,  0, 15 ), RPT_4   (-214,  0, 15 ),
-    RPT_4   ( 215,  0, 15 ), RPT_4   (-215,  0, 15 ),
-    RPT_4   ( 216,  0, 15 ), RPT_4   (-216,  0, 15 ),
-    RPT_4   ( 217,  0, 15 ), RPT_4   (-217,  0, 15 ),
-    RPT_4   ( 218,  0, 15 ), RPT_4   (-218,  0, 15 ),
-    RPT_4   ( 219,  0, 15 ), RPT_4   (-219,  0, 15 ),
-    RPT_4   ( 220,  0, 15 ), RPT_4   (-220,  0, 15 ),
-    RPT_4   ( 221,  0, 15 ), RPT_4   (-221,  0, 15 ),
-    RPT_4   ( 222,  0, 15 ), RPT_4   (-222,  0, 15 ),
-    RPT_4   ( 223,  0, 15 ), RPT_4   (-223,  0, 15 ),
-    RPT_4   ( 224,  0, 15 ), RPT_4   (-224,  0, 15 ),
-    RPT_4   ( 225,  0, 15 ), RPT_4   (-225,  0, 15 ),
-    RPT_4   ( 226,  0, 15 ), RPT_4   (-226,  0, 15 ),
-    RPT_4   ( 227,  0, 15 ), RPT_4   (-227,  0, 15 ),
-    RPT_4   ( 228,  0, 15 ), RPT_4   (-228,  0, 15 ),
-    RPT_4   ( 229,  0, 15 ), RPT_4   (-229,  0, 15 ),
-    RPT_4   ( 230,  0, 15 ), RPT_4   (-230,  0, 15 ),
-    RPT_4   ( 231,  0, 15 ), RPT_4   (-231,  0, 15 ),
-    RPT_4   ( 232,  0, 15 ), RPT_4   (-232,  0, 15 ),
-    RPT_4   ( 233,  0, 15 ), RPT_4   (-233,  0, 15 ),
-    RPT_4   ( 234,  0, 15 ), RPT_4   (-234,  0, 15 ),
-    RPT_4   ( 235,  0, 15 ), RPT_4   (-235,  0, 15 ),
-    RPT_4   ( 236,  0, 15 ), RPT_4   (-236,  0, 15 ),
-    RPT_4   ( 237,  0, 15 ), RPT_4   (-237,  0, 15 ),
-    RPT_4   ( 238,  0, 15 ), RPT_4   (-238,  0, 15 ),
-    RPT_4   ( 239,  0, 15 ), RPT_4   (-239,  0, 15 ),
-    RPT_4   ( 240,  0, 15 ), RPT_4   (-240,  0, 15 ),
-    RPT_4   ( 241,  0, 15 ), RPT_4   (-241,  0, 15 ),
-    RPT_4   ( 242,  0, 15 ), RPT_4   (-242,  0, 15 ),
-    RPT_4   ( 243,  0, 15 ), RPT_4   (-243,  0, 15 ),
-    RPT_4   ( 244,  0, 15 ), RPT_4   (-244,  0, 15 ),
-    RPT_4   ( 245,  0, 15 ), RPT_4   (-245,  0, 15 ),
-    RPT_4   ( 246,  0, 15 ), RPT_4   (-246,  0, 15 ),
-    RPT_4   ( 247,  0, 15 ), RPT_4   (-247,  0, 15 ),
-    RPT_4   ( 248,  0, 15 ), RPT_4   (-248,  0, 15 ),
-    RPT_4   ( 249,  0, 15 ), RPT_4   (-249,  0, 15 ),
-    RPT_4   ( 250,  0, 15 ), RPT_4   (-250,  0, 15 ),
-    RPT_4   ( 251,  0, 15 ), RPT_4   (-251,  0, 15 ),
-    RPT_4   ( 252,  0, 15 ), RPT_4   (-252,  0, 15 ),
-    RPT_4   ( 253,  0, 15 ), RPT_4   (-253,  0, 15 ),
-    RPT_4   ( 254,  0, 15 ), RPT_4   (-254,  0, 15 ),
-    RPT_4   ( 255,  0, 15 ), RPT_4   (-255,  0, 15 ),
-    RPT_32  (  49,  0, 12 ), RPT_32  ( -49,  0, 12 ),
-    RPT_32  (  50,  0, 12 ), RPT_32  ( -50,  0, 12 ),
-    RPT_32  (  51,  0, 12 ), RPT_32  ( -51,  0, 12 ),
-    RPT_32  (  52,  0, 12 ), RPT_32  ( -52,  0, 12 ),
-    RPT_32  (  53,  0, 12 ), RPT_32  ( -53,  0, 12 ),
-    RPT_32  (  54,  0, 12 ), RPT_32  ( -54,  0, 12 ),
-    RPT_32  (  55,  0, 12 ), RPT_32  ( -55,  0, 12 ),
-    RPT_32  (  56,  0, 12 ), RPT_32  ( -56,  0, 12 ),
-    RPT_32  (  57,  0, 12 ), RPT_32  ( -57,  0, 12 ),
-    RPT_32  (  58,  0, 12 ), RPT_32  ( -58,  0, 12 ),
-    RPT_32  (  59,  0, 12 ), RPT_32  ( -59,  0, 12 ),
-    RPT_32  (  60,  0, 12 ), RPT_32  ( -60,  0, 12 ),
-    RPT_32  (  61,  0, 12 ), RPT_32  ( -61,  0, 12 ),
-    RPT_32  (  62,  0, 12 ), RPT_32  ( -62,  0, 12 ),
-    RPT_32  (  63,  0, 12 ), RPT_32  ( -63,  0, 12 ),
-    RPT_32  (  17,  1, 12 ), RPT_32  ( -17,  1, 12 ),
-    RPT_32  (  18,  1, 12 ), RPT_32  ( -18,  1, 12 ),
-    RPT_32  (  19,  1, 12 ), RPT_32  ( -19,  1, 12 ),
-    RPT_32  (  20,  1, 12 ), RPT_32  ( -20,  1, 12 ),
-    RPT_32  (  21,  1, 12 ), RPT_32  ( -21,  1, 12 ),
-    RPT_32  (  22,  1, 12 ), RPT_32  ( -22,  1, 12 ),
-    RPT_32  (  23,  1, 12 ), RPT_32  ( -23,  1, 12 ),
-    RPT_32  (  24,  1, 12 ), RPT_32  ( -24,  1, 12 ),
-    RPT_32  (   9,  2, 12 ), RPT_32  (  -9,  2, 12 ),
-    RPT_32  (  10,  2, 12 ), RPT_32  ( -10,  2, 12 ),
-    RPT_32  (  11,  2, 12 ), RPT_32  ( -11,  2, 12 ),
-    RPT_32  (  12,  2, 12 ), RPT_32  ( -12,  2, 12 ),
-    RPT_32  (   7,  3, 12 ), RPT_32  (  -7,  3, 12 ),
-    RPT_32  (   8,  3, 12 ), RPT_32  (  -8,  3, 12 ),
-    RPT_32  (   5,  4, 12 ), RPT_32  (  -5,  4, 12 ),
-    RPT_32  (   6,  4, 12 ), RPT_32  (  -6,  4, 12 ),
-    RPT_32  (   3,  5, 12 ), RPT_32  (  -3,  5, 12 ),
-    RPT_32  (   4,  5, 12 ), RPT_32  (  -4,  5, 12 ),
-    RPT_32  (   5,  5, 12 ), RPT_32  (  -5,  5, 12 ),
-    RPT_32  (   6,  5, 12 ), RPT_32  (  -6,  5, 12 ),
-    RPT_32  (   3,  6, 12 ), RPT_32  (  -3,  6, 12 ),
-    RPT_32  (   4,  6, 12 ), RPT_32  (  -4,  6, 12 ),
-    RPT_32  (   2,  7, 12 ), RPT_32  (  -2,  7, 12 ),
-    RPT_32  (   2,  8, 12 ), RPT_32  (  -2,  8, 12 ),
-    RPT_32  (   2,  9, 12 ), RPT_32  (  -2,  9, 12 ),
-    RPT_32  (   2, 10, 12 ), RPT_32  (  -2, 10, 12 ),
-    RPT_32  (   1, 13, 12 ), RPT_32  (  -1, 13, 12 ),
-    RPT_32  (   1, 14, 12 ), RPT_32  (  -1, 14, 12 ),
-    {    0,  0, 17 }, {    0,  1, 17 }, {    0,  2, 17 }, {    0,  3, 17 },
-    {    0,  4, 17 }, {    0,  5, 17 }, {    0,  6, 17 }, {    0,  7, 17 },
-    {    0,  8, 17 }, {    0,  9, 17 }, {    0, 10, 17 }, {    0, 11, 17 },
-    {    0, 12, 17 }, {    0, 13, 17 }, {    0, 14, 17 }, {    0, 15, 17 },
-    {    0, 16, 17 }, {    0, 17, 17 }, {    0, 18, 17 }, {    0, 19, 17 },
-    {    0, 20, 17 }, {    0, 21, 17 }, {    0, 22, 17 }, {    0, 23, 17 },
-    {    0, 24, 17 }, {    0, 25, 17 }, {    0, 26, 17 }, {    0, 27, 17 },
-    {    0, 28, 17 }, {    0, 29, 17 }, {    0, 30, 17 }, {    0, 31, 17 },
-    {    0, 32, 17 }, {    0, 33, 17 }, {    0, 34, 17 }, {    0, 35, 17 },
-    {    0, 36, 17 }, {    0, 37, 17 }, {    0, 38, 17 }, {    0, 39, 17 },
-    {    0, 40, 17 }, {    0, 41, 17 }, {    0, 42, 17 }, {    0, 43, 17 },
-    {    0, 44, 17 }, {    0, 45, 17 }, {    0, 46, 17 }, {    0, 47, 17 },
-    {    0, 48, 17 }, {    0, 49, 17 }, {    0, 50, 17 }, {    0, 51, 17 },
-    {    0, 52, 17 }, {    0, 53, 17 }, {    0, 54, 17 }, {    0, 55, 17 },
-    {    0, 56, 17 }, {    0, 57, 17 }, {    0, 58, 17 }, {    0, 59, 17 },
-    {    0, 60, 17 }, {    0, 61, 17 }, {    0, 62, 17 }, {    0, 63, 17 },
-    RPT_16  (  25,  1, 13 ), RPT_16  ( -25,  1, 13 ),
-    RPT_16  (  26,  1, 13 ), RPT_16  ( -26,  1, 13 ),
-    RPT_16  (  27,  1, 13 ), RPT_16  ( -27,  1, 13 ),
-    RPT_16  (  28,  1, 13 ), RPT_16  ( -28,  1, 13 ),
-    RPT_16  (  29,  1, 13 ), RPT_16  ( -29,  1, 13 ),
-    RPT_16  (  30,  1, 13 ), RPT_16  ( -30,  1, 13 ),
-    RPT_16  (  31,  1, 13 ), RPT_16  ( -31,  1, 13 ),
-    RPT_16  (  32,  1, 13 ), RPT_16  ( -32,  1, 13 ),
-    RPT_16  (  13,  2, 13 ), RPT_16  ( -13,  2, 13 ),
-    RPT_16  (  14,  2, 13 ), RPT_16  ( -14,  2, 13 ),
-    RPT_16  (  15,  2, 13 ), RPT_16  ( -15,  2, 13 ),
-    RPT_16  (  16,  2, 13 ), RPT_16  ( -16,  2, 13 ),
-    RPT_16  (   9,  3, 13 ), RPT_16  (  -9,  3, 13 ),
-    RPT_16  (  10,  3, 13 ), RPT_16  ( -10,  3, 13 ),
-    RPT_16  (  11,  3, 13 ), RPT_16  ( -11,  3, 13 ),
-    RPT_16  (   7,  4, 13 ), RPT_16  (  -7,  4, 13 ),
-    RPT_16  (   3,  7, 13 ), RPT_16  (  -3,  7, 13 ),
-    RPT_16  (   4,  7, 13 ), RPT_16  (  -4,  7, 13 ),
-    RPT_16  (   3,  8, 13 ), RPT_16  (  -3,  8, 13 ),
-    RPT_16  (   4,  8, 13 ), RPT_16  (  -4,  8, 13 ),
-    RPT_16  (   3,  9, 13 ), RPT_16  (  -3,  9, 13 ),
-    RPT_16  (   2, 11, 13 ), RPT_16  (  -2, 11, 13 ),
-    RPT_16  (   2, 12, 13 ), RPT_16  (  -2, 12, 13 ),
-    RPT_32  (   0, 14, 12 ),
-};
+// level is in -255..255 range, run 0..64, so it fits into 16 bits.
+#define E(level, run) ((level * 128) | run)
 
-static const HQXLUT ac16_lut[] = {
-    RPT_256 (   1,  0,  3 ), RPT_256 (  -1,  0,  3 ),
-    RPT_128 (   2,  0,  4 ), RPT_128 (  -2,  0,  4 ),
-    RPT_64  (   3,  0,  5 ), RPT_64  (  -3,  0,  5 ),
-    RPT_64  (   4,  0,  5 ), RPT_64  (  -4,  0,  5 ),
-    RPT_64  (   1,  1,  5 ), RPT_64  (  -1,  1,  5 ),
-    RPT_128 (   0, 64,  4 ), RPT_32  (   5,  0,  6 ),
-    RPT_32  (  -5,  0,  6 ), RPT_32  (   6,  0,  6 ),
-    RPT_32  (  -6,  0,  6 ), RPT_32  (   2,  1,  6 ),
-    RPT_32  (  -2,  1,  6 ), RPT_32  (   1,  2,  6 ),
-    RPT_32  (  -1,  2,  6 ), RPT_16  (   7,  0,  7 ),
-    RPT_16  (  -7,  0,  7 ), RPT_16  (   8,  0,  7 ),
-    RPT_16  (  -8,  0,  7 ), RPT_16  (   9,  0,  7 ),
-    RPT_16  (  -9,  0,  7 ), RPT_16  (   3,  1,  7 ),
-    RPT_16  (  -3,  1,  7 ), RPT_16  (   1,  3,  7 ),
-    RPT_16  (  -1,  3,  7 ), RPT_16  (   1,  4,  7 ),
-    RPT_16  (  -1,  4,  7 ), RPT_8   (  10,  0,  8 ),
-    RPT_8   ( -10,  0,  8 ), RPT_8   (  11,  0,  8 ),
-    RPT_8   ( -11,  0,  8 ), RPT_8   (  12,  0,  8 ),
-    RPT_8   ( -12,  0,  8 ), RPT_8   (   4,  1,  8 ),
-    RPT_8   (  -4,  1,  8 ), RPT_8   (   2,  2,  8 ),
-    RPT_8   (  -2,  2,  8 ), RPT_8   (   1,  5,  8 ),
-    RPT_8   (  -1,  5,  8 ), RPT_8   (   1,  6,  8 ),
-    RPT_8   (  -1,  6,  8 ), RPT_4   (  13,  0,  9 ),
-    RPT_4   ( -13,  0,  9 ), RPT_4   (  14,  0,  9 ),
-    RPT_4   ( -14,  0,  9 ), RPT_4   (  15,  0,  9 ),
-    RPT_4   ( -15,  0,  9 ), RPT_4   (  16,  0,  9 ),
-    RPT_4   ( -16,  0,  9 ), RPT_4   (  17,  0,  9 ),
-    RPT_4   ( -17,  0,  9 ), RPT_4   (   5,  1,  9 ),
-    RPT_4   (  -5,  1,  9 ), RPT_4   (   2,  3,  9 ),
-    RPT_4   (  -2,  3,  9 ), RPT_4   (   1,  7,  9 ),
-    RPT_4   (  -1,  7,  9 ), RPT_4   (   1,  8,  9 ),
-    RPT_4   (  -1,  8,  9 ), RPT_4   (   1,  9,  9 ),
-    RPT_4   (  -1,  9,  9 ), RPT_4   (   1, 10,  9 ),
-    RPT_4   (  -1, 10,  9 ), RPT_4   (   0,  0,  9 ),
-    RPT_2   (  18,  0, 10 ), RPT_2   ( -18,  0, 10 ),
-    RPT_2   (  19,  0, 10 ), RPT_2   ( -19,  0, 10 ),
-    RPT_2   (  20,  0, 10 ), RPT_2   ( -20,  0, 10 ),
-    RPT_2   (  21,  0, 10 ), RPT_2   ( -21,  0, 10 ),
-    RPT_2   (  22,  0, 10 ), RPT_2   ( -22,  0, 10 ),
-    RPT_2   (   6,  1, 10 ), RPT_2   (  -6,  1, 10 ),
-    RPT_2   (   7,  1, 10 ), RPT_2   (  -7,  1, 10 ),
-    RPT_2   (   3,  2, 10 ), RPT_2   (  -3,  2, 10 ),
-    RPT_2   (   2,  4, 10 ), RPT_2   (  -2,  4, 10 ),
-    RPT_2   (   2,  5, 10 ), RPT_2   (  -2,  5, 10 ),
-    RPT_2   (   1, 11, 10 ), RPT_2   (  -1, 11, 10 ),
-    RPT_2   (   1, 12, 10 ), RPT_2   (  -1, 12, 10 ),
-    RPT_2   (   1, 13, 10 ), RPT_2   (  -1, 13, 10 ),
-    { 2048,  0, -1 }, { 2112,  0, -1 }, { 2176,  0, -1 }, { 2240,  0, -1 },
-    { 2304,  0, -1 }, { 2368,  0, -1 }, { 2432,  0, -1 }, { 2496,  0, -1 },
-    {   23,  0, 11 }, {  -23,  0, 11 }, {   24,  0, 11 }, {  -24,  0, 11 },
-    {   25,  0, 11 }, {  -25,  0, 11 }, {   26,  0, 11 }, {  -26,  0, 11 },
-    {   27,  0, 11 }, {  -27,  0, 11 }, {   28,  0, 11 }, {  -28,  0, 11 },
-    {    8,  1, 11 }, {   -8,  1, 11 }, {    9,  1, 11 }, {   -9,  1, 11 },
-    {    4,  2, 11 }, {   -4,  2, 11 }, {    3,  3, 11 }, {   -3,  3, 11 },
-    {    3,  4, 11 }, {   -3,  4, 11 }, {    2,  6, 11 }, {   -2,  6, 11 },
-    {    2,  7, 11 }, {   -2,  7, 11 }, { 2560,  0, -1 }, { 2624,  0, -1 },
-    { 2688,  0, -1 }, { 2752,  0, -1 }, { 2816,  0, -1 }, { 2880,  0, -1 },
-    { 2944,  0, -1 }, {    0,  1, 11 }, { 3008,  0, -1 }, { 3072,  0, -1 },
-    { 3136,  0, -1 }, {    0,  2, 11 }, { 3200,  0, -1 }, {    0,  3, 11 },
-    { 3264,  0, -1 }, { 3328,  0, -1 }, { 3392,  0, -1 }, { 3456,  0, -1 },
-    { 3520,  0, -1 }, { 3584,  0, -1 }, { 3648,  0, -1 }, { 3712,  0, -1 },
-    { 3776,  0, -1 }, { 3840,  0, -1 }, { 3904,  0, -1 }, { 3968,  0, -1 },
-    { 4032,  0, -1 }, { 4096,  0, -1 }, { 4160,  0, -1 }, { 4224,  0, -1 },
-    RPT_4   (   0,  0, 15 ), RPT_4   (   0,  1, 15 ),
-    RPT_4   (   0,  2, 15 ), RPT_4   (   0,  3, 15 ),
-    RPT_4   (   0,  4, 15 ), RPT_4   (   0,  5, 15 ),
-    RPT_4   (   0,  6, 15 ), RPT_4   (   0,  7, 15 ),
-    RPT_4   (   0,  8, 15 ), RPT_4   (   0,  9, 15 ),
-    RPT_4   (   0, 10, 15 ), RPT_4   (   0, 11, 15 ),
-    RPT_4   (   0, 12, 15 ), RPT_4   (   0, 13, 15 ),
-    RPT_4   (   0, 14, 15 ), RPT_4   (   0, 15, 15 ),
-    RPT_4   (   0, 16, 15 ), RPT_4   (   0, 17, 15 ),
-    RPT_4   (   0, 18, 15 ), RPT_4   (   0, 19, 15 ),
-    RPT_4   (   0, 20, 15 ), RPT_4   (   0, 21, 15 ),
-    RPT_4   (   0, 22, 15 ), RPT_4   (   0, 23, 15 ),
-    RPT_4   (   0, 24, 15 ), RPT_4   (   0, 25, 15 ),
-    RPT_4   (   0, 26, 15 ), RPT_4   (   0, 27, 15 ),
-    RPT_4   (   0, 28, 15 ), RPT_4   (   0, 29, 15 ),
-    RPT_4   (   0, 30, 15 ), RPT_4   (   0, 31, 15 ),
-    RPT_4   (   0, 32, 15 ), RPT_4   (   0, 33, 15 ),
-    RPT_4   (   0, 34, 15 ), RPT_4   (   0, 35, 15 ),
-    RPT_4   (   0, 36, 15 ), RPT_4   (   0, 37, 15 ),
-    RPT_4   (   0, 38, 15 ), RPT_4   (   0, 39, 15 ),
-    RPT_4   (   0, 40, 15 ), RPT_4   (   0, 41, 15 ),
-    RPT_4   (   0, 42, 15 ), RPT_4   (   0, 43, 15 ),
-    RPT_4   (   0, 44, 15 ), RPT_4   (   0, 45, 15 ),
-    RPT_4   (   0, 46, 15 ), RPT_4   (   0, 47, 15 ),
-    RPT_4   (   0, 48, 15 ), RPT_4   (   0, 49, 15 ),
-    RPT_4   (   0, 50, 15 ), RPT_4   (   0, 51, 15 ),
-    RPT_4   (   0, 52, 15 ), RPT_4   (   0, 53, 15 ),
-    RPT_4   (   0, 54, 15 ), RPT_4   (   0, 55, 15 ),
-    RPT_4   (   0, 56, 15 ), RPT_4   (   0, 57, 15 ),
-    RPT_4   (   0, 58, 15 ), RPT_4   (   0, 59, 15 ),
-    RPT_4   (   0, 60, 15 ), RPT_4   (   0, 61, 15 ),
-    RPT_4   (   0, 62, 15 ), RPT_4   (   0, 63, 15 ),
-    RPT_2   (   0,  0, 16 ), {    1,  0, 17 }, {   -1,  0, 17 },
-    {    2,  0, 17 }, {   -2,  0, 17 }, {    3,  0, 17 }, {   -3,  0, 17 },
-    {    4,  0, 17 }, {   -4,  0, 17 }, {    5,  0, 17 }, {   -5,  0, 17 },
-    {    6,  0, 17 }, {   -6,  0, 17 }, {    7,  0, 17 }, {   -7,  0, 17 },
-    {    8,  0, 17 }, {   -8,  0, 17 }, {    9,  0, 17 }, {   -9,  0, 17 },
-    {   10,  0, 17 }, {  -10,  0, 17 }, {   11,  0, 17 }, {  -11,  0, 17 },
-    {   12,  0, 17 }, {  -12,  0, 17 }, {   13,  0, 17 }, {  -13,  0, 17 },
-    {   14,  0, 17 }, {  -14,  0, 17 }, {   15,  0, 17 }, {  -15,  0, 17 },
-    {   16,  0, 17 }, {  -16,  0, 17 }, {   17,  0, 17 }, {  -17,  0, 17 },
-    {   18,  0, 17 }, {  -18,  0, 17 }, {   19,  0, 17 }, {  -19,  0, 17 },
-    {   20,  0, 17 }, {  -20,  0, 17 }, {   21,  0, 17 }, {  -21,  0, 17 },
-    {   22,  0, 17 }, {  -22,  0, 17 }, {   23,  0, 17 }, {  -23,  0, 17 },
-    {   24,  0, 17 }, {  -24,  0, 17 }, {   25,  0, 17 }, {  -25,  0, 17 },
-    {   26,  0, 17 }, {  -26,  0, 17 }, {   27,  0, 17 }, {  -27,  0, 17 },
-    {   28,  0, 17 }, {  -28,  0, 17 }, {   29,  0, 17 }, {  -29,  0, 17 },
-    {   30,  0, 17 }, {  -30,  0, 17 }, {   31,  0, 17 }, {  -31,  0, 17 },
-    {   32,  0, 17 }, {  -32,  0, 17 }, {   33,  0, 17 }, {  -33,  0, 17 },
-    {   34,  0, 17 }, {  -34,  0, 17 }, {   35,  0, 17 }, {  -35,  0, 17 },
-    {   36,  0, 17 }, {  -36,  0, 17 }, {   37,  0, 17 }, {  -37,  0, 17 },
-    {   38,  0, 17 }, {  -38,  0, 17 }, {   39,  0, 17 }, {  -39,  0, 17 },
-    {   40,  0, 17 }, {  -40,  0, 17 }, {   41,  0, 17 }, {  -41,  0, 17 },
-    {   42,  0, 17 }, {  -42,  0, 17 }, {   43,  0, 17 }, {  -43,  0, 17 },
-    {   44,  0, 17 }, {  -44,  0, 17 }, {   45,  0, 17 }, {  -45,  0, 17 },
-    {   46,  0, 17 }, {  -46,  0, 17 }, {   47,  0, 17 }, {  -47,  0, 17 },
-    {   48,  0, 17 }, {  -48,  0, 17 }, {   49,  0, 17 }, {  -49,  0, 17 },
-    {   50,  0, 17 }, {  -50,  0, 17 }, {   51,  0, 17 }, {  -51,  0, 17 },
-    {   52,  0, 17 }, {  -52,  0, 17 }, {   53,  0, 17 }, {  -53,  0, 17 },
-    {   54,  0, 17 }, {  -54,  0, 17 }, {   55,  0, 17 }, {  -55,  0, 17 },
-    {   56,  0, 17 }, {  -56,  0, 17 }, {   57,  0, 17 }, {  -57,  0, 17 },
-    {   58,  0, 17 }, {  -58,  0, 17 }, {   59,  0, 17 }, {  -59,  0, 17 },
-    {   60,  0, 17 }, {  -60,  0, 17 }, {   61,  0, 17 }, {  -61,  0, 17 },
-    {   62,  0, 17 }, {  -62,  0, 17 }, {   63,  0, 17 }, {  -63,  0, 17 },
-    {   64,  0, 17 }, {  -64,  0, 17 }, {   65,  0, 17 }, {  -65,  0, 17 },
-    {   66,  0, 17 }, {  -66,  0, 17 }, {   67,  0, 17 }, {  -67,  0, 17 },
-    {   68,  0, 17 }, {  -68,  0, 17 }, {   69,  0, 17 }, {  -69,  0, 17 },
-    {   70,  0, 17 }, {  -70,  0, 17 }, {   71,  0, 17 }, {  -71,  0, 17 },
-    {   72,  0, 17 }, {  -72,  0, 17 }, {   73,  0, 17 }, {  -73,  0, 17 },
-    {   74,  0, 17 }, {  -74,  0, 17 }, {   75,  0, 17 }, {  -75,  0, 17 },
-    {   76,  0, 17 }, {  -76,  0, 17 }, {   77,  0, 17 }, {  -77,  0, 17 },
-    {   78,  0, 17 }, {  -78,  0, 17 }, {   79,  0, 17 }, {  -79,  0, 17 },
-    {   80,  0, 17 }, {  -80,  0, 17 }, {   81,  0, 17 }, {  -81,  0, 17 },
-    {   82,  0, 17 }, {  -82,  0, 17 }, {   83,  0, 17 }, {  -83,  0, 17 },
-    {   84,  0, 17 }, {  -84,  0, 17 }, {   85,  0, 17 }, {  -85,  0, 17 },
-    {   86,  0, 17 }, {  -86,  0, 17 }, {   87,  0, 17 }, {  -87,  0, 17 },
-    {   88,  0, 17 }, {  -88,  0, 17 }, {   89,  0, 17 }, {  -89,  0, 17 },
-    {   90,  0, 17 }, {  -90,  0, 17 }, {   91,  0, 17 }, {  -91,  0, 17 },
-    {   92,  0, 17 }, {  -92,  0, 17 }, {   93,  0, 17 }, {  -93,  0, 17 },
-    {   94,  0, 17 }, {  -94,  0, 17 }, {   95,  0, 17 }, {  -95,  0, 17 },
-    {   96,  0, 17 }, {  -96,  0, 17 }, {   97,  0, 17 }, {  -97,  0, 17 },
-    {   98,  0, 17 }, {  -98,  0, 17 }, {   99,  0, 17 }, {  -99,  0, 17 },
-    {  100,  0, 17 }, { -100,  0, 17 }, {  101,  0, 17 }, { -101,  0, 17 },
-    {  102,  0, 17 }, { -102,  0, 17 }, {  103,  0, 17 }, { -103,  0, 17 },
-    {  104,  0, 17 }, { -104,  0, 17 }, {  105,  0, 17 }, { -105,  0, 17 },
-    {  106,  0, 17 }, { -106,  0, 17 }, {  107,  0, 17 }, { -107,  0, 17 },
-    {  108,  0, 17 }, { -108,  0, 17 }, {  109,  0, 17 }, { -109,  0, 17 },
-    {  110,  0, 17 }, { -110,  0, 17 }, {  111,  0, 17 }, { -111,  0, 17 },
-    {  112,  0, 17 }, { -112,  0, 17 }, {  113,  0, 17 }, { -113,  0, 17 },
-    {  114,  0, 17 }, { -114,  0, 17 }, {  115,  0, 17 }, { -115,  0, 17 },
-    {  116,  0, 17 }, { -116,  0, 17 }, {  117,  0, 17 }, { -117,  0, 17 },
-    {  118,  0, 17 }, { -118,  0, 17 }, {  119,  0, 17 }, { -119,  0, 17 },
-    {  120,  0, 17 }, { -120,  0, 17 }, {  121,  0, 17 }, { -121,  0, 17 },
-    {  122,  0, 17 }, { -122,  0, 17 }, {  123,  0, 17 }, { -123,  0, 17 },
-    {  124,  0, 17 }, { -124,  0, 17 }, {  125,  0, 17 }, { -125,  0, 17 },
-    {  126,  0, 17 }, { -126,  0, 17 }, {  127,  0, 17 }, { -127,  0, 17 },
-    RPT_32  (  29,  0, 12 ), RPT_32  ( -29,  0, 12 ),
-    RPT_32  (  30,  0, 12 ), RPT_32  ( -30,  0, 12 ),
-    RPT_32  (  31,  0, 12 ), RPT_32  ( -31,  0, 12 ),
-    RPT_32  (  32,  0, 12 ), RPT_32  ( -32,  0, 12 ),
-    RPT_32  (  33,  0, 12 ), RPT_32  ( -33,  0, 12 ),
-    RPT_32  (  34,  0, 12 ), RPT_32  ( -34,  0, 12 ),
-    RPT_32  (  35,  0, 12 ), RPT_32  ( -35,  0, 12 ),
-    RPT_32  (  10,  1, 12 ), RPT_32  ( -10,  1, 12 ),
-    RPT_32  (  11,  1, 12 ), RPT_32  ( -11,  1, 12 ),
-    RPT_32  (  12,  1, 12 ), RPT_32  ( -12,  1, 12 ),
-    RPT_32  (   5,  2, 12 ), RPT_32  (  -5,  2, 12 ),
-    RPT_32  (   4,  3, 12 ), RPT_32  (  -4,  3, 12 ),
-    RPT_32  (   3,  5, 12 ), RPT_32  (  -3,  5, 12 ),
-    RPT_32  (   2,  8, 12 ), RPT_32  (  -2,  8, 12 ),
-    RPT_32  (   2,  9, 12 ), RPT_32  (  -2,  9, 12 ),
-    RPT_32  (   1, 14, 12 ), RPT_32  (  -1, 14, 12 ),
-    RPT_32  (   1, 15, 12 ), RPT_32  (  -1, 15, 12 ),
-    RPT_16  (  36,  0, 13 ), RPT_16  ( -36,  0, 13 ),
-    RPT_16  (  37,  0, 13 ), RPT_16  ( -37,  0, 13 ),
-    RPT_16  (  38,  0, 13 ), RPT_16  ( -38,  0, 13 ),
-    RPT_16  (  39,  0, 13 ), RPT_16  ( -39,  0, 13 ),
-    RPT_16  (  40,  0, 13 ), RPT_16  ( -40,  0, 13 ),
-    RPT_16  (  13,  1, 13 ), RPT_16  ( -13,  1, 13 ),
-    RPT_16  (  14,  1, 13 ), RPT_16  ( -14,  1, 13 ),
-    RPT_16  (  15,  1, 13 ), RPT_16  ( -15,  1, 13 ),
-    RPT_16  (   6,  2, 13 ), RPT_16  (  -6,  2, 13 ),
-    RPT_16  (   7,  2, 13 ), RPT_16  (  -7,  2, 13 ),
-    RPT_16  (   5,  3, 13 ), RPT_16  (  -5,  3, 13 ),
-    RPT_32  (   0,  4, 12 ), RPT_16  (   4,  4, 13 ),
-    RPT_16  (  -4,  4, 13 ), RPT_32  (   0,  5, 12 ),
-    RPT_32  (   0,  6, 12 ), RPT_16  (   3,  6, 13 ),
-    RPT_16  (  -3,  6, 13 ), RPT_32  (   0,  7, 12 ),
-    RPT_16  (   3,  7, 13 ), RPT_16  (  -3,  7, 13 ),
-    RPT_16  (   2, 10, 13 ), RPT_16  (  -2, 10, 13 ),
-    RPT_16  (   1, 16, 13 ), RPT_16  (  -1, 16, 13 ),
+static const int16_t hqx_ac_run_level[] = {
+    // AC table Q0 - 815 elements
+    E(   1,  0), E(  -1,  0), E(   2,  0), E(  -2,  0), E(   3,  0),
+    E(  -3,  0), E(   4,  0), E(  -4,  0), E(   1,  1), E(  -1,  1),
+    E(   5,  0), E(  -5,  0), E(   6,  0), E(  -6,  0), E(   7,  0),
+    E(  -7,  0), E(   8,  0), E(  -8,  0), E(   0,  0), E(   1,  0),
+    E(  -1,  0), E(   2,  0), E(  -2,  0), E(   3,  0), E(  -3,  0),
+    E(   4,  0), E(  -4,  0), E(   5,  0), E(  -5,  0), E(   6,  0),
+    E(  -6,  0), E(   7,  0), E(  -7,  0), E(   8,  0), E(  -8,  0),
+    E(   9,  0), E(  -9,  0), E(  10,  0), E( -10,  0), E(  11,  0),
+    E( -11,  0), E(  12,  0), E( -12,  0), E(  13,  0), E( -13,  0),
+    E(  14,  0), E( -14,  0), E(  15,  0), E( -15,  0), E(  16,  0),
+    E( -16,  0), E(  17,  0), E( -17,  0), E(  18,  0), E( -18,  0),
+    E(  19,  0), E( -19,  0), E(  20,  0), E( -20,  0), E(  21,  0),
+    E( -21,  0), E(  22,  0), E( -22,  0), E(  23,  0), E( -23,  0),
+    E(  24,  0), E( -24,  0), E(  25,  0), E( -25,  0), E(  26,  0),
+    E( -26,  0), E(  27,  0), E( -27,  0), E(  28,  0), E( -28,  0),
+    E(  29,  0), E( -29,  0), E(  30,  0), E( -30,  0), E(  31,  0),
+    E( -31,  0), E(  32,  0), E( -32,  0), E(  33,  0), E( -33,  0),
+    E(  34,  0), E( -34,  0), E(  35,  0), E( -35,  0), E(  36,  0),
+    E( -36,  0), E(  37,  0), E( -37,  0), E(  38,  0), E( -38,  0),
+    E(  39,  0), E( -39,  0), E(  40,  0), E( -40,  0), E(  41,  0),
+    E( -41,  0), E(  42,  0), E( -42,  0), E(  43,  0), E( -43,  0),
+    E(  44,  0), E( -44,  0), E(  45,  0), E( -45,  0), E(  46,  0),
+    E( -46,  0), E(  47,  0), E( -47,  0), E(  48,  0), E( -48,  0),
+    E(  49,  0), E( -49,  0), E(  50,  0), E( -50,  0), E(  51,  0),
+    E( -51,  0), E(  52,  0), E( -52,  0), E(  53,  0), E( -53,  0),
+    E(  54,  0), E( -54,  0), E(  55,  0), E( -55,  0), E(  56,  0),
+    E( -56,  0), E(  57,  0), E( -57,  0), E(  58,  0), E( -58,  0),
+    E(  59,  0), E( -59,  0), E(  60,  0), E( -60,  0), E(  61,  0),
+    E( -61,  0), E(  62,  0), E( -62,  0), E(  63,  0), E( -63,  0),
+    E(  64,  0), E( -64,  0), E(  65,  0), E( -65,  0), E(  66,  0),
+    E( -66,  0), E(  67,  0), E( -67,  0), E(  68,  0), E( -68,  0),
+    E(  69,  0), E( -69,  0), E(  70,  0), E( -70,  0), E(  71,  0),
+    E( -71,  0), E(  72,  0), E( -72,  0), E(  73,  0), E( -73,  0),
+    E(  74,  0), E( -74,  0), E(  75,  0), E( -75,  0), E(  76,  0),
+    E( -76,  0), E(  77,  0), E( -77,  0), E(  78,  0), E( -78,  0),
+    E(  79,  0), E( -79,  0), E(  80,  0), E( -80,  0), E(  81,  0),
+    E( -81,  0), E(  82,  0), E( -82,  0), E(  83,  0), E( -83,  0),
+    E(  84,  0), E( -84,  0), E(  85,  0), E( -85,  0), E(  86,  0),
+    E( -86,  0), E(  87,  0), E( -87,  0), E(  88,  0), E( -88,  0),
+    E(  89,  0), E( -89,  0), E(  90,  0), E( -90,  0), E(  91,  0),
+    E( -91,  0), E(  92,  0), E( -92,  0), E(  93,  0), E( -93,  0),
+    E(  94,  0), E( -94,  0), E(  95,  0), E( -95,  0), E(  96,  0),
+    E( -96,  0), E(  97,  0), E( -97,  0), E(  98,  0), E( -98,  0),
+    E(  99,  0), E( -99,  0), E( 100,  0), E(-100,  0), E( 101,  0),
+    E(-101,  0), E( 102,  0), E(-102,  0), E( 103,  0), E(-103,  0),
+    E( 104,  0), E(-104,  0), E( 105,  0), E(-105,  0), E( 106,  0),
+    E(-106,  0), E( 107,  0), E(-107,  0), E( 108,  0), E(-108,  0),
+    E( 109,  0), E(-109,  0), E( 110,  0), E(-110,  0), E( 111,  0),
+    E(-111,  0), E( 112,  0), E(-112,  0), E( 113,  0), E(-113,  0),
+    E( 114,  0), E(-114,  0), E( 115,  0), E(-115,  0), E( 116,  0),
+    E(-116,  0), E( 117,  0), E(-117,  0), E( 118,  0), E(-118,  0),
+    E( 119,  0), E(-119,  0), E( 120,  0), E(-120,  0), E( 121,  0),
+    E(-121,  0), E( 122,  0), E(-122,  0), E( 123,  0), E(-123,  0),
+    E( 124,  0), E(-124,  0), E( 125,  0), E(-125,  0), E( 126,  0),
+    E(-126,  0), E( 127,  0), E(-127,  0), E( 128,  0), E(-128,  0),
+    E( 129,  0), E(-129,  0), E( 130,  0), E(-130,  0), E( 131,  0),
+    E(-131,  0), E( 132,  0), E(-132,  0), E( 133,  0), E(-133,  0),
+    E( 134,  0), E(-134,  0), E( 135,  0), E(-135,  0), E( 136,  0),
+    E(-136,  0), E( 137,  0), E(-137,  0), E( 138,  0), E(-138,  0),
+    E( 139,  0), E(-139,  0), E( 140,  0), E(-140,  0), E( 141,  0),
+    E(-141,  0), E( 142,  0), E(-142,  0), E( 143,  0), E(-143,  0),
+    E( 144,  0), E(-144,  0), E( 145,  0), E(-145,  0), E( 146,  0),
+    E(-146,  0), E( 147,  0), E(-147,  0), E( 148,  0), E(-148,  0),
+    E( 149,  0), E(-149,  0), E( 150,  0), E(-150,  0), E( 151,  0),
+    E(-151,  0), E( 152,  0), E(-152,  0), E( 153,  0), E(-153,  0),
+    E( 154,  0), E(-154,  0), E( 155,  0), E(-155,  0), E( 156,  0),
+    E(-156,  0), E( 157,  0), E(-157,  0), E( 158,  0), E(-158,  0),
+    E( 159,  0), E(-159,  0), E( 160,  0), E(-160,  0), E( 161,  0),
+    E(-161,  0), E( 162,  0), E(-162,  0), E( 163,  0), E(-163,  0),
+    E( 164,  0), E(-164,  0), E( 165,  0), E(-165,  0), E( 166,  0),
+    E(-166,  0), E( 167,  0), E(-167,  0), E( 168,  0), E(-168,  0),
+    E( 169,  0), E(-169,  0), E( 170,  0), E(-170,  0), E( 171,  0),
+    E(-171,  0), E( 172,  0), E(-172,  0), E( 173,  0), E(-173,  0),
+    E( 174,  0), E(-174,  0), E( 175,  0), E(-175,  0), E( 176,  0),
+    E(-176,  0), E( 177,  0), E(-177,  0), E( 178,  0), E(-178,  0),
+    E( 179,  0), E(-179,  0), E( 180,  0), E(-180,  0), E( 181,  0),
+    E(-181,  0), E( 182,  0), E(-182,  0), E( 183,  0), E(-183,  0),
+    E( 184,  0), E(-184,  0), E( 185,  0), E(-185,  0), E( 186,  0),
+    E(-186,  0), E( 187,  0), E(-187,  0), E( 188,  0), E(-188,  0),
+    E( 189,  0), E(-189,  0), E( 190,  0), E(-190,  0), E( 191,  0),
+    E(-191,  0), E( 192,  0), E(-192,  0), E( 193,  0), E(-193,  0),
+    E( 194,  0), E(-194,  0), E( 195,  0), E(-195,  0), E( 196,  0),
+    E(-196,  0), E( 197,  0), E(-197,  0), E( 198,  0), E(-198,  0),
+    E( 199,  0), E(-199,  0), E( 200,  0), E(-200,  0), E( 201,  0),
+    E(-201,  0), E( 202,  0), E(-202,  0), E( 203,  0), E(-203,  0),
+    E( 204,  0), E(-204,  0), E( 205,  0), E(-205,  0), E( 206,  0),
+    E(-206,  0), E( 207,  0), E(-207,  0), E( 208,  0), E(-208,  0),
+    E( 209,  0), E(-209,  0), E( 210,  0), E(-210,  0), E( 211,  0),
+    E(-211,  0), E( 212,  0), E(-212,  0), E( 213,  0), E(-213,  0),
+    E( 214,  0), E(-214,  0), E( 215,  0), E(-215,  0), E( 216,  0),
+    E(-216,  0), E( 217,  0), E(-217,  0), E( 218,  0), E(-218,  0),
+    E( 219,  0), E(-219,  0), E( 220,  0), E(-220,  0), E( 221,  0),
+    E(-221,  0), E( 222,  0), E(-222,  0), E( 223,  0), E(-223,  0),
+    E( 224,  0), E(-224,  0), E( 225,  0), E(-225,  0), E( 226,  0),
+    E(-226,  0), E( 227,  0), E(-227,  0), E( 228,  0), E(-228,  0),
+    E( 229,  0), E(-229,  0), E( 230,  0), E(-230,  0), E( 231,  0),
+    E(-231,  0), E( 232,  0), E(-232,  0), E( 233,  0), E(-233,  0),
+    E( 234,  0), E(-234,  0), E( 235,  0), E(-235,  0), E( 236,  0),
+    E(-236,  0), E( 237,  0), E(-237,  0), E( 238,  0), E(-238,  0),
+    E( 239,  0), E(-239,  0), E( 240,  0), E(-240,  0), E( 241,  0),
+    E(-241,  0), E( 242,  0), E(-242,  0), E( 243,  0), E(-243,  0),
+    E( 244,  0), E(-244,  0), E( 245,  0), E(-245,  0), E( 246,  0),
+    E(-246,  0), E( 247,  0), E(-247,  0), E( 248,  0), E(-248,  0),
+    E( 249,  0), E(-249,  0), E( 250,  0), E(-250,  0), E( 251,  0),
+    E(-251,  0), E( 252,  0), E(-252,  0), E( 253,  0), E(-253,  0),
+    E( 254,  0), E(-254,  0), E( 255,  0), E(-255,  0), E(   0, 64),
+    E(   9,  0), E(  -9,  0), E(  10,  0), E( -10,  0), E(  11,  0),
+    E( -11,  0), E(  12,  0), E( -12,  0), E(  13,  0), E( -13,  0),
+    E(  14,  0), E( -14,  0), E(   2,  1), E(  -2,  1), E(   1,  2),
+    E(  -1,  2), E(  15,  0), E( -15,  0), E(  16,  0), E( -16,  0),
+    E(  17,  0), E( -17,  0), E(  18,  0), E( -18,  0), E(  19,  0),
+    E( -19,  0), E(  20,  0), E( -20,  0), E(  21,  0), E( -21,  0),
+    E(   3,  1), E(  -3,  1), E(   4,  1), E(  -4,  1), E(   1,  3),
+    E(  -1,  3), E(   1,  4), E(  -1,  4), E(   0,  0), E(  22,  0),
+    E( -22,  0), E(  23,  0), E( -23,  0), E(  24,  0), E( -24,  0),
+    E(  25,  0), E( -25,  0), E(  26,  0), E( -26,  0), E(  27,  0),
+    E( -27,  0), E(  28,  0), E( -28,  0), E(  29,  0), E( -29,  0),
+    E(  30,  0), E( -30,  0), E(  31,  0), E( -31,  0), E(  32,  0),
+    E( -32,  0), E(  33,  0), E( -33,  0), E(   5,  1), E(  -5,  1),
+    E(   6,  1), E(  -6,  1), E(   2,  2), E(  -2,  2), E(   1,  5),
+    E(  -1,  5), E(   1,  6), E(  -1,  6), E(  34,  0), E( -34,  0),
+    E(  35,  0), E( -35,  0), E(  36,  0), E( -36,  0), E(  37,  0),
+    E( -37,  0), E(  38,  0), E( -38,  0), E(  39,  0), E( -39,  0),
+    E(  40,  0), E( -40,  0), E(  41,  0), E( -41,  0), E(  42,  0),
+    E( -42,  0), E(  43,  0), E( -43,  0), E(  44,  0), E( -44,  0),
+    E(  45,  0), E( -45,  0), E(  46,  0), E( -46,  0), E(  47,  0),
+    E( -47,  0), E(  48,  0), E( -48,  0), E(  49,  0), E( -49,  0),
+    E(  50,  0), E( -50,  0), E(   0,  1), E(   7,  1), E(  -7,  1),
+    E(   8,  1), E(  -8,  1), E(   9,  1), E(  -9,  1), E(  10,  1),
+    E( -10,  1), E(   0,  2), E(   3,  2), E(  -3,  2), E(   0,  3),
+    E(   2,  3), E(  -2,  3), E(   1,  7), E(  -1,  7), E(   1,  8),
+    E(  -1,  8), E(   0,  0), E(   0,  1), E(   0,  2), E(   0,  3),
+    E(   0,  4), E(   0,  5), E(   0,  6), E(   0,  7), E(   0,  8),
+    E(   0,  9), E(   0, 10), E(   0, 11), E(   0, 12), E(   0, 13),
+    E(   0, 14), E(   0, 15), E(   0, 16), E(   0, 17), E(   0, 18),
+    E(   0, 19), E(   0, 20), E(   0, 21), E(   0, 22), E(   0, 23),
+    E(   0, 24), E(   0, 25), E(   0, 26), E(   0, 27), E(   0, 28),
+    E(   0, 29), E(   0, 30), E(   0, 31), E(   0, 32), E(   0, 33),
+    E(   0, 34), E(   0, 35), E(   0, 36), E(   0, 37), E(   0, 38),
+    E(   0, 39), E(   0, 40), E(   0, 41), E(   0, 42), E(   0, 43),
+    E(   0, 44), E(   0, 45), E(   0, 46), E(   0, 47), E(   0, 48),
+    E(   0, 49), E(   0, 50), E(   0, 51), E(   0, 52), E(   0, 53),
+    E(   0, 54), E(   0, 55), E(   0, 56), E(   0, 57), E(   0, 58),
+    E(   0, 59), E(   0, 60), E(   0, 61), E(   0, 62), E(   0, 63),
+    E(  51,  0), E( -51,  0), E(  52,  0), E( -52,  0), E(  53,  0),
+    E( -53,  0), E(  54,  0), E( -54,  0), E(  55,  0), E( -55,  0),
+    E(  56,  0), E( -56,  0), E(  57,  0), E( -57,  0), E(  58,  0),
+    E( -58,  0), E(  59,  0), E( -59,  0), E(  60,  0), E( -60,  0),
+    E(  61,  0), E( -61,  0), E(  62,  0), E( -62,  0), E(  63,  0),
+    E( -63,  0), E(  11,  1), E( -11,  1), E(  12,  1), E( -12,  1),
+    E(  13,  1), E( -13,  1), E(  14,  1), E( -14,  1), E(   4,  2),
+    E(  -4,  2), E(   5,  2), E(  -5,  2), E(   6,  2), E(  -6,  2),
+    E(   3,  3), E(  -3,  3), E(   0,  4), E(   2,  4), E(  -2,  4),
+    E(   0,  5), E(   0,  6), E(   1,  9), E(  -1,  9), E(   1, 10),
+    E(  -1, 10), E(  15,  1), E( -15,  1), E(  16,  1), E( -16,  1),
+    E(  17,  1), E( -17,  1), E(  18,  1), E( -18,  1), E(   7,  2),
+    E(  -7,  2), E(   8,  2), E(  -8,  2), E(   9,  2), E(  -9,  2),
+    E(  10,  2), E( -10,  2), E(   4,  3), E(  -4,  3), E(   5,  3),
+    E(  -5,  3), E(   6,  3), E(  -6,  3), E(   2,  5), E(  -2,  5),
+    E(   0,  7), E(   0,  8), E(   0,  9), E(   0, 10), E(   1, 11),
+    E(  -1, 11), E(   1, 12), E(  -1, 12), E(   1, 13), E(  -1, 13),
+    E(   1, 14), E(  -1, 14), E(  19,  1), E( -19,  1), E(  20,  1),
+    E( -20,  1), E(   3,  4), E(  -3,  4), E(   2,  6), E(  -2,  6),
+    // AC table Q8 - 907 elements
+    E(   1,  0), E(  -1,  0), E(   2,  0), E(  -2,  0), E(   3,  0),
+    E(  -3,  0), E(   4,  0), E(  -4,  0), E(   0, 64), E(   5,  0),
+    E(  -5,  0), E(   6,  0), E(  -6,  0), E(   7,  0), E(  -7,  0),
+    E(   8,  0), E(  -8,  0), E(   1,  1), E(  -1,  1), E(   2,  1),
+    E(  -2,  1), E(   9,  0), E(  -9,  0), E(  10,  0), E( -10,  0),
+    E(  11,  0), E( -11,  0), E(  12,  0), E( -12,  0), E(   3,  1),
+    E(  -3,  1), E(   4,  1), E(  -4,  1), E(   1,  2), E(  -1,  2),
+    E(   0,  0), E(   1,  0), E(  -1,  0), E(   2,  0), E(  -2,  0),
+    E(   3,  0), E(  -3,  0), E(   4,  0), E(  -4,  0), E(   5,  0),
+    E(  -5,  0), E(   6,  0), E(  -6,  0), E(   7,  0), E(  -7,  0),
+    E(   8,  0), E(  -8,  0), E(   9,  0), E(  -9,  0), E(  10,  0),
+    E( -10,  0), E(  11,  0), E( -11,  0), E(  12,  0), E( -12,  0),
+    E(  13,  0), E( -13,  0), E(  14,  0), E( -14,  0), E(  15,  0),
+    E( -15,  0), E(  16,  0), E( -16,  0), E(  17,  0), E( -17,  0),
+    E(  18,  0), E( -18,  0), E(  19,  0), E( -19,  0), E(  20,  0),
+    E( -20,  0), E(  21,  0), E( -21,  0), E(  22,  0), E( -22,  0),
+    E(  23,  0), E( -23,  0), E(  24,  0), E( -24,  0), E(  25,  0),
+    E( -25,  0), E(  26,  0), E( -26,  0), E(  27,  0), E( -27,  0),
+    E(  28,  0), E( -28,  0), E(  29,  0), E( -29,  0), E(  30,  0),
+    E( -30,  0), E(  31,  0), E( -31,  0), E(  32,  0), E( -32,  0),
+    E(  33,  0), E( -33,  0), E(  34,  0), E( -34,  0), E(  35,  0),
+    E( -35,  0), E(  36,  0), E( -36,  0), E(  37,  0), E( -37,  0),
+    E(  38,  0), E( -38,  0), E(  39,  0), E( -39,  0), E(  40,  0),
+    E( -40,  0), E(  41,  0), E( -41,  0), E(  42,  0), E( -42,  0),
+    E(  43,  0), E( -43,  0), E(  44,  0), E( -44,  0), E(  45,  0),
+    E( -45,  0), E(  46,  0), E( -46,  0), E(  47,  0), E( -47,  0),
+    E(  48,  0), E( -48,  0), E(  49,  0), E( -49,  0), E(  50,  0),
+    E( -50,  0), E(  51,  0), E( -51,  0), E(  52,  0), E( -52,  0),
+    E(  53,  0), E( -53,  0), E(  54,  0), E( -54,  0), E(  55,  0),
+    E( -55,  0), E(  56,  0), E( -56,  0), E(  57,  0), E( -57,  0),
+    E(  58,  0), E( -58,  0), E(  59,  0), E( -59,  0), E(  60,  0),
+    E( -60,  0), E(  61,  0), E( -61,  0), E(  62,  0), E( -62,  0),
+    E(  63,  0), E( -63,  0), E(  64,  0), E( -64,  0), E(  65,  0),
+    E( -65,  0), E(  66,  0), E( -66,  0), E(  67,  0), E( -67,  0),
+    E(  68,  0), E( -68,  0), E(  69,  0), E( -69,  0), E(  70,  0),
+    E( -70,  0), E(  71,  0), E( -71,  0), E(  72,  0), E( -72,  0),
+    E(  73,  0), E( -73,  0), E(  74,  0), E( -74,  0), E(  75,  0),
+    E( -75,  0), E(  76,  0), E( -76,  0), E(  77,  0), E( -77,  0),
+    E(  78,  0), E( -78,  0), E(  79,  0), E( -79,  0), E(  80,  0),
+    E( -80,  0), E(  81,  0), E( -81,  0), E(  82,  0), E( -82,  0),
+    E(  83,  0), E( -83,  0), E(  84,  0), E( -84,  0), E(  85,  0),
+    E( -85,  0), E(  86,  0), E( -86,  0), E(  87,  0), E( -87,  0),
+    E(  88,  0), E( -88,  0), E(  89,  0), E( -89,  0), E(  90,  0),
+    E( -90,  0), E(  91,  0), E( -91,  0), E(  92,  0), E( -92,  0),
+    E(  93,  0), E( -93,  0), E(  94,  0), E( -94,  0), E(  95,  0),
+    E( -95,  0), E(  96,  0), E( -96,  0), E(  97,  0), E( -97,  0),
+    E(  98,  0), E( -98,  0), E(  99,  0), E( -99,  0), E( 100,  0),
+    E(-100,  0), E( 101,  0), E(-101,  0), E( 102,  0), E(-102,  0),
+    E( 103,  0), E(-103,  0), E( 104,  0), E(-104,  0), E( 105,  0),
+    E(-105,  0), E( 106,  0), E(-106,  0), E( 107,  0), E(-107,  0),
+    E( 108,  0), E(-108,  0), E( 109,  0), E(-109,  0), E( 110,  0),
+    E(-110,  0), E( 111,  0), E(-111,  0), E( 112,  0), E(-112,  0),
+    E( 113,  0), E(-113,  0), E( 114,  0), E(-114,  0), E( 115,  0),
+    E(-115,  0), E( 116,  0), E(-116,  0), E( 117,  0), E(-117,  0),
+    E( 118,  0), E(-118,  0), E( 119,  0), E(-119,  0), E( 120,  0),
+    E(-120,  0), E( 121,  0), E(-121,  0), E( 122,  0), E(-122,  0),
+    E( 123,  0), E(-123,  0), E( 124,  0), E(-124,  0), E( 125,  0),
+    E(-125,  0), E( 126,  0), E(-126,  0), E( 127,  0), E(-127,  0),
+    E( 128,  0), E(-128,  0), E( 129,  0), E(-129,  0), E( 130,  0),
+    E(-130,  0), E( 131,  0), E(-131,  0), E( 132,  0), E(-132,  0),
+    E( 133,  0), E(-133,  0), E( 134,  0), E(-134,  0), E( 135,  0),
+    E(-135,  0), E( 136,  0), E(-136,  0), E( 137,  0), E(-137,  0),
+    E( 138,  0), E(-138,  0), E( 139,  0), E(-139,  0), E( 140,  0),
+    E(-140,  0), E( 141,  0), E(-141,  0), E( 142,  0), E(-142,  0),
+    E( 143,  0), E(-143,  0), E( 144,  0), E(-144,  0), E( 145,  0),
+    E(-145,  0), E( 146,  0), E(-146,  0), E( 147,  0), E(-147,  0),
+    E( 148,  0), E(-148,  0), E( 149,  0), E(-149,  0), E( 150,  0),
+    E(-150,  0), E( 151,  0), E(-151,  0), E( 152,  0), E(-152,  0),
+    E( 153,  0), E(-153,  0), E( 154,  0), E(-154,  0), E( 155,  0),
+    E(-155,  0), E( 156,  0), E(-156,  0), E( 157,  0), E(-157,  0),
+    E( 158,  0), E(-158,  0), E( 159,  0), E(-159,  0), E( 160,  0),
+    E(-160,  0), E( 161,  0), E(-161,  0), E( 162,  0), E(-162,  0),
+    E( 163,  0), E(-163,  0), E( 164,  0), E(-164,  0), E( 165,  0),
+    E(-165,  0), E( 166,  0), E(-166,  0), E( 167,  0), E(-167,  0),
+    E( 168,  0), E(-168,  0), E( 169,  0), E(-169,  0), E( 170,  0),
+    E(-170,  0), E( 171,  0), E(-171,  0), E( 172,  0), E(-172,  0),
+    E( 173,  0), E(-173,  0), E( 174,  0), E(-174,  0), E( 175,  0),
+    E(-175,  0), E( 176,  0), E(-176,  0), E( 177,  0), E(-177,  0),
+    E( 178,  0), E(-178,  0), E( 179,  0), E(-179,  0), E( 180,  0),
+    E(-180,  0), E( 181,  0), E(-181,  0), E( 182,  0), E(-182,  0),
+    E( 183,  0), E(-183,  0), E( 184,  0), E(-184,  0), E( 185,  0),
+    E(-185,  0), E( 186,  0), E(-186,  0), E( 187,  0), E(-187,  0),
+    E( 188,  0), E(-188,  0), E( 189,  0), E(-189,  0), E( 190,  0),
+    E(-190,  0), E( 191,  0), E(-191,  0), E( 192,  0), E(-192,  0),
+    E( 193,  0), E(-193,  0), E( 194,  0), E(-194,  0), E( 195,  0),
+    E(-195,  0), E( 196,  0), E(-196,  0), E( 197,  0), E(-197,  0),
+    E( 198,  0), E(-198,  0), E( 199,  0), E(-199,  0), E( 200,  0),
+    E(-200,  0), E( 201,  0), E(-201,  0), E( 202,  0), E(-202,  0),
+    E( 203,  0), E(-203,  0), E( 204,  0), E(-204,  0), E( 205,  0),
+    E(-205,  0), E( 206,  0), E(-206,  0), E( 207,  0), E(-207,  0),
+    E( 208,  0), E(-208,  0), E( 209,  0), E(-209,  0), E( 210,  0),
+    E(-210,  0), E( 211,  0), E(-211,  0), E( 212,  0), E(-212,  0),
+    E( 213,  0), E(-213,  0), E( 214,  0), E(-214,  0), E( 215,  0),
+    E(-215,  0), E( 216,  0), E(-216,  0), E( 217,  0), E(-217,  0),
+    E( 218,  0), E(-218,  0), E( 219,  0), E(-219,  0), E( 220,  0),
+    E(-220,  0), E( 221,  0), E(-221,  0), E( 222,  0), E(-222,  0),
+    E( 223,  0), E(-223,  0), E( 224,  0), E(-224,  0), E( 225,  0),
+    E(-225,  0), E( 226,  0), E(-226,  0), E( 227,  0), E(-227,  0),
+    E( 228,  0), E(-228,  0), E( 229,  0), E(-229,  0), E( 230,  0),
+    E(-230,  0), E( 231,  0), E(-231,  0), E( 232,  0), E(-232,  0),
+    E( 233,  0), E(-233,  0), E( 234,  0), E(-234,  0), E( 235,  0),
+    E(-235,  0), E( 236,  0), E(-236,  0), E( 237,  0), E(-237,  0),
+    E( 238,  0), E(-238,  0), E( 239,  0), E(-239,  0), E( 240,  0),
+    E(-240,  0), E( 241,  0), E(-241,  0), E( 242,  0), E(-242,  0),
+    E( 243,  0), E(-243,  0), E( 244,  0), E(-244,  0), E( 245,  0),
+    E(-245,  0), E( 246,  0), E(-246,  0), E( 247,  0), E(-247,  0),
+    E( 248,  0), E(-248,  0), E( 249,  0), E(-249,  0), E( 250,  0),
+    E(-250,  0), E( 251,  0), E(-251,  0), E( 252,  0), E(-252,  0),
+    E( 253,  0), E(-253,  0), E( 254,  0), E(-254,  0), E( 255,  0),
+    E(-255,  0), E(  13,  0), E( -13,  0), E(  14,  0), E( -14,  0),
+    E(  15,  0), E( -15,  0), E(  16,  0), E( -16,  0), E(  17,  0),
+    E( -17,  0), E(  18,  0), E( -18,  0), E(   5,  1), E(  -5,  1),
+    E(   6,  1), E(  -6,  1), E(   2,  2), E(  -2,  2), E(   1,  3),
+    E(  -1,  3), E(   0,  0), E(  19,  0), E( -19,  0), E(  20,  0),
+    E( -20,  0), E(  21,  0), E( -21,  0), E(  22,  0), E( -22,  0),
+    E(  23,  0), E( -23,  0), E(  24,  0), E( -24,  0), E(  25,  0),
+    E( -25,  0), E(   7,  1), E(  -7,  1), E(   8,  1), E(  -8,  1),
+    E(   3,  2), E(  -3,  2), E(   2,  3), E(  -2,  3), E(   1,  4),
+    E(  -1,  4), E(   1,  5), E(  -1,  5), E(  26,  0), E( -26,  0),
+    E(  27,  0), E( -27,  0), E(  28,  0), E( -28,  0), E(  29,  0),
+    E( -29,  0), E(  30,  0), E( -30,  0), E(  31,  0), E( -31,  0),
+    E(  32,  0), E( -32,  0), E(  33,  0), E( -33,  0), E(  34,  0),
+    E( -34,  0), E(  35,  0), E( -35,  0), E(  36,  0), E( -36,  0),
+    E(   0,  1), E(   9,  1), E(  -9,  1), E(  10,  1), E( -10,  1),
+    E(  11,  1), E( -11,  1), E(  12,  1), E( -12,  1), E(   0,  2),
+    E(   4,  2), E(  -4,  2), E(   5,  2), E(  -5,  2), E(   6,  2),
+    E(  -6,  2), E(   0,  3), E(   3,  3), E(  -3,  3), E(   4,  3),
+    E(  -4,  3), E(   0,  4), E(   2,  4), E(  -2,  4), E(   0,  5),
+    E(   1,  6), E(  -1,  6), E(   1,  7), E(  -1,  7), E(   1,  8),
+    E(  -1,  8), E(  37,  0), E( -37,  0), E(  38,  0), E( -38,  0),
+    E(  39,  0), E( -39,  0), E(  40,  0), E( -40,  0), E(  41,  0),
+    E( -41,  0), E(  42,  0), E( -42,  0), E(  43,  0), E( -43,  0),
+    E(  44,  0), E( -44,  0), E(  45,  0), E( -45,  0), E(  46,  0),
+    E( -46,  0), E(  47,  0), E( -47,  0), E(  48,  0), E( -48,  0),
+    E(  13,  1), E( -13,  1), E(  14,  1), E( -14,  1), E(  15,  1),
+    E( -15,  1), E(  16,  1), E( -16,  1), E(   7,  2), E(  -7,  2),
+    E(   8,  2), E(  -8,  2), E(   5,  3), E(  -5,  3), E(   6,  3),
+    E(  -6,  3), E(   3,  4), E(  -3,  4), E(   4,  4), E(  -4,  4),
+    E(   2,  5), E(  -2,  5), E(   0,  6), E(   2,  6), E(  -2,  6),
+    E(   0,  7), E(   0,  8), E(   0,  9), E(   1,  9), E(  -1,  9),
+    E(   1, 10), E(  -1, 10), E(   1, 11), E(  -1, 11), E(   1, 12),
+    E(  -1, 12), E(  49,  0), E( -49,  0), E(  50,  0), E( -50,  0),
+    E(  51,  0), E( -51,  0), E(  52,  0), E( -52,  0), E(  53,  0),
+    E( -53,  0), E(  54,  0), E( -54,  0), E(  55,  0), E( -55,  0),
+    E(  56,  0), E( -56,  0), E(  57,  0), E( -57,  0), E(  58,  0),
+    E( -58,  0), E(  59,  0), E( -59,  0), E(  60,  0), E( -60,  0),
+    E(  61,  0), E( -61,  0), E(  62,  0), E( -62,  0), E(  63,  0),
+    E( -63,  0), E(  17,  1), E( -17,  1), E(  18,  1), E( -18,  1),
+    E(  19,  1), E( -19,  1), E(  20,  1), E( -20,  1), E(  21,  1),
+    E( -21,  1), E(  22,  1), E( -22,  1), E(  23,  1), E( -23,  1),
+    E(  24,  1), E( -24,  1), E(   9,  2), E(  -9,  2), E(  10,  2),
+    E( -10,  2), E(  11,  2), E( -11,  2), E(  12,  2), E( -12,  2),
+    E(   7,  3), E(  -7,  3), E(   8,  3), E(  -8,  3), E(   5,  4),
+    E(  -5,  4), E(   6,  4), E(  -6,  4), E(   3,  5), E(  -3,  5),
+    E(   4,  5), E(  -4,  5), E(   5,  5), E(  -5,  5), E(   6,  5),
+    E(  -6,  5), E(   3,  6), E(  -3,  6), E(   4,  6), E(  -4,  6),
+    E(   2,  7), E(  -2,  7), E(   2,  8), E(  -2,  8), E(   2,  9),
+    E(  -2,  9), E(   0, 10), E(   2, 10), E(  -2, 10), E(   0, 11),
+    E(   0, 12), E(   0, 13), E(   1, 13), E(  -1, 13), E(   1, 14),
+    E(  -1, 14), E(   0,  0), E(   0,  1), E(   0,  2), E(   0,  3),
+    E(   0,  4), E(   0,  5), E(   0,  6), E(   0,  7), E(   0,  8),
+    E(   0,  9), E(   0, 10), E(   0, 11), E(   0, 12), E(   0, 13),
+    E(   0, 14), E(   0, 15), E(   0, 16), E(   0, 17), E(   0, 18),
+    E(   0, 19), E(   0, 20), E(   0, 21), E(   0, 22), E(   0, 23),
+    E(   0, 24), E(   0, 25), E(   0, 26), E(   0, 27), E(   0, 28),
+    E(   0, 29), E(   0, 30), E(   0, 31), E(   0, 32), E(   0, 33),
+    E(   0, 34), E(   0, 35), E(   0, 36), E(   0, 37), E(   0, 38),
+    E(   0, 39), E(   0, 40), E(   0, 41), E(   0, 42), E(   0, 43),
+    E(   0, 44), E(   0, 45), E(   0, 46), E(   0, 47), E(   0, 48),
+    E(   0, 49), E(   0, 50), E(   0, 51), E(   0, 52), E(   0, 53),
+    E(   0, 54), E(   0, 55), E(   0, 56), E(   0, 57), E(   0, 58),
+    E(   0, 59), E(   0, 60), E(   0, 61), E(   0, 62), E(   0, 63),
+    E(  25,  1), E( -25,  1), E(  26,  1), E( -26,  1), E(  27,  1),
+    E( -27,  1), E(  28,  1), E( -28,  1), E(  29,  1), E( -29,  1),
+    E(  30,  1), E( -30,  1), E(  31,  1), E( -31,  1), E(  32,  1),
+    E( -32,  1), E(  13,  2), E( -13,  2), E(  14,  2), E( -14,  2),
+    E(  15,  2), E( -15,  2), E(  16,  2), E( -16,  2), E(   9,  3),
+    E(  -9,  3), E(  10,  3), E( -10,  3), E(  11,  3), E( -11,  3),
+    E(   7,  4), E(  -7,  4), E(   3,  7), E(  -3,  7), E(   4,  7),
+    E(  -4,  7), E(   3,  8), E(  -3,  8), E(   4,  8), E(  -4,  8),
+    E(   3,  9), E(  -3,  9), E(   2, 11), E(  -2, 11), E(   2, 12),
+    E(  -2, 12), E(   0, 14),
+    // AC table Q16 - 512 elements
+    E(   1,  0), E(  -1,  0), E(   2,  0), E(  -2,  0), E(   3,  0),
+    E(  -3,  0), E(   4,  0), E(  -4,  0), E(   1,  1), E(  -1,  1),
+    E(   0, 64), E(   5,  0), E(  -5,  0), E(   6,  0), E(  -6,  0),
+    E(   2,  1), E(  -2,  1), E(   1,  2), E(  -1,  2), E(   7,  0),
+    E(  -7,  0), E(   8,  0), E(  -8,  0), E(   9,  0), E(  -9,  0),
+    E(   3,  1), E(  -3,  1), E(   1,  3), E(  -1,  3), E(   1,  4),
+    E(  -1,  4), E(  10,  0), E( -10,  0), E(  11,  0), E( -11,  0),
+    E(  12,  0), E( -12,  0), E(   4,  1), E(  -4,  1), E(   2,  2),
+    E(  -2,  2), E(   1,  5), E(  -1,  5), E(   1,  6), E(  -1,  6),
+    E(  13,  0), E( -13,  0), E(  14,  0), E( -14,  0), E(  15,  0),
+    E( -15,  0), E(  16,  0), E( -16,  0), E(  17,  0), E( -17,  0),
+    E(   5,  1), E(  -5,  1), E(   2,  3), E(  -2,  3), E(   1,  7),
+    E(  -1,  7), E(   1,  8), E(  -1,  8), E(   1,  9), E(  -1,  9),
+    E(   1, 10), E(  -1, 10), E(   0,  0), E(  18,  0), E( -18,  0),
+    E(  19,  0), E( -19,  0), E(  20,  0), E( -20,  0), E(  21,  0),
+    E( -21,  0), E(  22,  0), E( -22,  0), E(   6,  1), E(  -6,  1),
+    E(   7,  1), E(  -7,  1), E(   3,  2), E(  -3,  2), E(   2,  4),
+    E(  -2,  4), E(   2,  5), E(  -2,  5), E(   1, 11), E(  -1, 11),
+    E(   1, 12), E(  -1, 12), E(   1, 13), E(  -1, 13), E(   0,  0),
+    E(   0,  1), E(   0,  2), E(   0,  3), E(   0,  4), E(   0,  5),
+    E(   0,  6), E(   0,  7), E(   0,  8), E(   0,  9), E(   0, 10),
+    E(   0, 11), E(   0, 12), E(   0, 13), E(   0, 14), E(   0, 15),
+    E(   0, 16), E(   0, 17), E(   0, 18), E(   0, 19), E(   0, 20),
+    E(   0, 21), E(   0, 22), E(   0, 23), E(   0, 24), E(   0, 25),
+    E(   0, 26), E(   0, 27), E(   0, 28), E(   0, 29), E(   0, 30),
+    E(   0, 31), E(   0, 32), E(   0, 33), E(   0, 34), E(   0, 35),
+    E(   0, 36), E(   0, 37), E(   0, 38), E(   0, 39), E(   0, 40),
+    E(   0, 41), E(   0, 42), E(   0, 43), E(   0, 44), E(   0, 45),
+    E(   0, 46), E(   0, 47), E(   0, 48), E(   0, 49), E(   0, 50),
+    E(   0, 51), E(   0, 52), E(   0, 53), E(   0, 54), E(   0, 55),
+    E(   0, 56), E(   0, 57), E(   0, 58), E(   0, 59), E(   0, 60),
+    E(   0, 61), E(   0, 62), E(   0, 63), E(   0,  0), E(   1,  0),
+    E(  -1,  0), E(   2,  0), E(  -2,  0), E(   3,  0), E(  -3,  0),
+    E(   4,  0), E(  -4,  0), E(   5,  0), E(  -5,  0), E(   6,  0),
+    E(  -6,  0), E(   7,  0), E(  -7,  0), E(   8,  0), E(  -8,  0),
+    E(   9,  0), E(  -9,  0), E(  10,  0), E( -10,  0), E(  11,  0),
+    E( -11,  0), E(  12,  0), E( -12,  0), E(  13,  0), E( -13,  0),
+    E(  14,  0), E( -14,  0), E(  15,  0), E( -15,  0), E(  16,  0),
+    E( -16,  0), E(  17,  0), E( -17,  0), E(  18,  0), E( -18,  0),
+    E(  19,  0), E( -19,  0), E(  20,  0), E( -20,  0), E(  21,  0),
+    E( -21,  0), E(  22,  0), E( -22,  0), E(  23,  0), E( -23,  0),
+    E(  24,  0), E( -24,  0), E(  25,  0), E( -25,  0), E(  26,  0),
+    E( -26,  0), E(  27,  0), E( -27,  0), E(  28,  0), E( -28,  0),
+    E(  29,  0), E( -29,  0), E(  30,  0), E( -30,  0), E(  31,  0),
+    E( -31,  0), E(  32,  0), E( -32,  0), E(  33,  0), E( -33,  0),
+    E(  34,  0), E( -34,  0), E(  35,  0), E( -35,  0), E(  36,  0),
+    E( -36,  0), E(  37,  0), E( -37,  0), E(  38,  0), E( -38,  0),
+    E(  39,  0), E( -39,  0), E(  40,  0), E( -40,  0), E(  41,  0),
+    E( -41,  0), E(  42,  0), E( -42,  0), E(  43,  0), E( -43,  0),
+    E(  44,  0), E( -44,  0), E(  45,  0), E( -45,  0), E(  46,  0),
+    E( -46,  0), E(  47,  0), E( -47,  0), E(  48,  0), E( -48,  0),
+    E(  49,  0), E( -49,  0), E(  50,  0), E( -50,  0), E(  51,  0),
+    E( -51,  0), E(  52,  0), E( -52,  0), E(  53,  0), E( -53,  0),
+    E(  54,  0), E( -54,  0), E(  55,  0), E( -55,  0), E(  56,  0),
+    E( -56,  0), E(  57,  0), E( -57,  0), E(  58,  0), E( -58,  0),
+    E(  59,  0), E( -59,  0), E(  60,  0), E( -60,  0), E(  61,  0),
+    E( -61,  0), E(  62,  0), E( -62,  0), E(  63,  0), E( -63,  0),
+    E(  64,  0), E( -64,  0), E(  65,  0), E( -65,  0), E(  66,  0),
+    E( -66,  0), E(  67,  0), E( -67,  0), E(  68,  0), E( -68,  0),
+    E(  69,  0), E( -69,  0), E(  70,  0), E( -70,  0), E(  71,  0),
+    E( -71,  0), E(  72,  0), E( -72,  0), E(  73,  0), E( -73,  0),
+    E(  74,  0), E( -74,  0), E(  75,  0), E( -75,  0), E(  76,  0),
+    E( -76,  0), E(  77,  0), E( -77,  0), E(  78,  0), E( -78,  0),
+    E(  79,  0), E( -79,  0), E(  80,  0), E( -80,  0), E(  81,  0),
+    E( -81,  0), E(  82,  0), E( -82,  0), E(  83,  0), E( -83,  0),
+    E(  84,  0), E( -84,  0), E(  85,  0), E( -85,  0), E(  86,  0),
+    E( -86,  0), E(  87,  0), E( -87,  0), E(  88,  0), E( -88,  0),
+    E(  89,  0), E( -89,  0), E(  90,  0), E( -90,  0), E(  91,  0),
+    E( -91,  0), E(  92,  0), E( -92,  0), E(  93,  0), E( -93,  0),
+    E(  94,  0), E( -94,  0), E(  95,  0), E( -95,  0), E(  96,  0),
+    E( -96,  0), E(  97,  0), E( -97,  0), E(  98,  0), E( -98,  0),
+    E(  99,  0), E( -99,  0), E( 100,  0), E(-100,  0), E( 101,  0),
+    E(-101,  0), E( 102,  0), E(-102,  0), E( 103,  0), E(-103,  0),
+    E( 104,  0), E(-104,  0), E( 105,  0), E(-105,  0), E( 106,  0),
+    E(-106,  0), E( 107,  0), E(-107,  0), E( 108,  0), E(-108,  0),
+    E( 109,  0), E(-109,  0), E( 110,  0), E(-110,  0), E( 111,  0),
+    E(-111,  0), E( 112,  0), E(-112,  0), E( 113,  0), E(-113,  0),
+    E( 114,  0), E(-114,  0), E( 115,  0), E(-115,  0), E( 116,  0),
+    E(-116,  0), E( 117,  0), E(-117,  0), E( 118,  0), E(-118,  0),
+    E( 119,  0), E(-119,  0), E( 120,  0), E(-120,  0), E( 121,  0),
+    E(-121,  0), E( 122,  0), E(-122,  0), E( 123,  0), E(-123,  0),
+    E( 124,  0), E(-124,  0), E( 125,  0), E(-125,  0), E( 126,  0),
+    E(-126,  0), E( 127,  0), E(-127,  0), E(  23,  0), E( -23,  0),
+    E(  24,  0), E( -24,  0), E(  25,  0), E( -25,  0), E(  26,  0),
+    E( -26,  0), E(  27,  0), E( -27,  0), E(  28,  0), E( -28,  0),
+    E(   8,  1), E(  -8,  1), E(   9,  1), E(  -9,  1), E(   4,  2),
+    E(  -4,  2), E(   3,  3), E(  -3,  3), E(   3,  4), E(  -3,  4),
+    E(   2,  6), E(  -2,  6), E(   2,  7), E(  -2,  7), E(  29,  0),
+    E( -29,  0), E(  30,  0), E( -30,  0), E(  31,  0), E( -31,  0),
+    E(  32,  0), E( -32,  0), E(  33,  0), E( -33,  0), E(  34,  0),
+    E( -34,  0), E(  35,  0), E( -35,  0), E(   0,  1), E(  10,  1),
+    E( -10,  1), E(  11,  1), E( -11,  1), E(  12,  1), E( -12,  1),
+    E(   0,  2), E(   5,  2), E(  -5,  2), E(   0,  3), E(   4,  3),
+    E(  -4,  3), E(   3,  5), E(  -3,  5), E(   2,  8), E(  -2,  8),
+    E(   2,  9), E(  -2,  9), E(   1, 14), E(  -1, 14), E(   1, 15),
+    E(  -1, 15), E(  36,  0), E( -36,  0), E(  37,  0), E( -37,  0),
+    E(  38,  0), E( -38,  0), E(  39,  0), E( -39,  0), E(  40,  0),
+    E( -40,  0), E(  13,  1), E( -13,  1), E(  14,  1), E( -14,  1),
+    E(  15,  1), E( -15,  1), E(   6,  2), E(  -6,  2), E(   7,  2),
+    E(  -7,  2), E(   5,  3), E(  -5,  3), E(   0,  4), E(   4,  4),
+    E(  -4,  4), E(   0,  5), E(   0,  6), E(   3,  6), E(  -3,  6),
+    E(   0,  7), E(   3,  7), E(  -3,  7), E(   2, 10), E(  -2, 10),
+    E(   1, 16), E(  -1, 16),
+    // AC table Q32 - 354 elements
+    E(  1,  0), E( -1,  0), E(  2,  0), E( -2,  0), E(  0, 64), E(  3,  0),
+    E( -3,  0), E(  1,  1), E( -1,  1), E(  4,  0), E( -4,  0), E(  5,  0),
+    E( -5,  0), E(  2,  1), E( -2,  1), E(  1,  2), E( -1,  2), E(  1,  3),
+    E( -1,  3), E(  6,  0), E( -6,  0), E(  7,  0), E( -7,  0), E(  3,  1),
+    E( -3,  1), E(  1,  4), E( -1,  4), E(  1,  5), E( -1,  5), E(  8,  0),
+    E( -8,  0), E(  9,  0), E( -9,  0), E( 10,  0), E(-10,  0), E(  4,  1),
+    E( -4,  1), E(  2,  2), E( -2,  2), E(  1,  6), E( -1,  6), E(  1,  7),
+    E( -1,  7), E(  1,  8), E( -1,  8), E( 11,  0), E(-11,  0), E( 12,  0),
+    E(-12,  0), E( 13,  0), E(-13,  0), E(  5,  1), E( -5,  1), E(  2,  3),
+    E( -2,  3), E(  1,  9), E( -1,  9), E(  1, 10), E( -1, 10), E( 14,  0),
+    E(-14,  0), E( 15,  0), E(-15,  0), E( 16,  0), E(-16,  0), E(  6,  1),
+    E( -6,  1), E(  7,  1), E( -7,  1), E(  3,  2), E( -3,  2), E(  3,  3),
+    E( -3,  3), E(  2,  4), E( -2,  4), E(  2,  5), E( -2,  5), E(  1, 11),
+    E( -1, 11), E(  1, 12), E( -1, 12), E(  1, 13), E( -1, 13), E(  0,  0),
+    E(  0,  1), E(  0,  2), E(  0,  3), E(  0,  4), E(  0,  5), E(  0,  6),
+    E(  0,  7), E(  0,  8), E(  0,  9), E(  0, 10), E(  0, 11), E(  0, 12),
+    E(  0, 13), E(  0, 14), E(  0, 15), E(  0, 16), E(  0, 17), E(  0, 18),
+    E(  0, 19), E(  0, 20), E(  0, 21), E(  0, 22), E(  0, 23), E(  0, 24),
+    E(  0, 25), E(  0, 26), E(  0, 27), E(  0, 28), E(  0, 29), E(  0, 30),
+    E(  0, 31), E(  0, 32), E(  0, 33), E(  0, 34), E(  0, 35), E(  0, 36),
+    E(  0, 37), E(  0, 38), E(  0, 39), E(  0, 40), E(  0, 41), E(  0, 42),
+    E(  0, 43), E(  0, 44), E(  0, 45), E(  0, 46), E(  0, 47), E(  0, 48),
+    E(  0, 49), E(  0, 50), E(  0, 51), E(  0, 52), E(  0, 53), E(  0, 54),
+    E(  0, 55), E(  0, 56), E(  0, 57), E(  0, 58), E(  0, 59), E(  0, 60),
+    E(  0, 61), E(  0, 62), E(  0, 63), E(  0,  0), E( 17,  0), E(-17,  0),
+    E( 18,  0), E(-18,  0), E( 19,  0), E(-19,  0), E( 20,  0), E(-20,  0),
+    E(  8,  1), E( -8,  1), E(  9,  1), E( -9,  1), E(  4,  2), E( -4,  2),
+    E(  3,  4), E( -3,  4), E(  2,  6), E( -2,  6), E(  2,  7), E( -2,  7),
+    E(  2,  8), E( -2,  8), E(  1, 14), E( -1, 14), E(  0,  0), E(  1,  0),
+    E( -1,  0), E(  2,  0), E( -2,  0), E(  3,  0), E( -3,  0), E(  4,  0),
+    E( -4,  0), E(  5,  0), E( -5,  0), E(  6,  0), E( -6,  0), E(  7,  0),
+    E( -7,  0), E(  8,  0), E( -8,  0), E(  9,  0), E( -9,  0), E( 10,  0),
+    E(-10,  0), E( 11,  0), E(-11,  0), E( 12,  0), E(-12,  0), E( 13,  0),
+    E(-13,  0), E( 14,  0), E(-14,  0), E( 15,  0), E(-15,  0), E( 16,  0),
+    E(-16,  0), E( 17,  0), E(-17,  0), E( 18,  0), E(-18,  0), E( 19,  0),
+    E(-19,  0), E( 20,  0), E(-20,  0), E( 21,  0), E(-21,  0), E( 22,  0),
+    E(-22,  0), E( 23,  0), E(-23,  0), E( 24,  0), E(-24,  0), E( 25,  0),
+    E(-25,  0), E( 26,  0), E(-26,  0), E( 27,  0), E(-27,  0), E( 28,  0),
+    E(-28,  0), E( 29,  0), E(-29,  0), E( 30,  0), E(-30,  0), E( 31,  0),
+    E(-31,  0), E( 32,  0), E(-32,  0), E( 33,  0), E(-33,  0), E( 34,  0),
+    E(-34,  0), E( 35,  0), E(-35,  0), E( 36,  0), E(-36,  0), E( 37,  0),
+    E(-37,  0), E( 38,  0), E(-38,  0), E( 39,  0), E(-39,  0), E( 40,  0),
+    E(-40,  0), E( 41,  0), E(-41,  0), E( 42,  0), E(-42,  0), E( 43,  0),
+    E(-43,  0), E( 44,  0), E(-44,  0), E( 45,  0), E(-45,  0), E( 46,  0),
+    E(-46,  0), E( 47,  0), E(-47,  0), E( 48,  0), E(-48,  0), E( 49,  0),
+    E(-49,  0), E( 50,  0), E(-50,  0), E( 51,  0), E(-51,  0), E( 52,  0),
+    E(-52,  0), E( 53,  0), E(-53,  0), E( 54,  0), E(-54,  0), E( 55,  0),
+    E(-55,  0), E( 56,  0), E(-56,  0), E( 57,  0), E(-57,  0), E( 58,  0),
+    E(-58,  0), E( 59,  0), E(-59,  0), E( 60,  0), E(-60,  0), E( 61,  0),
+    E(-61,  0), E( 62,  0), E(-62,  0), E( 63,  0), E(-63,  0), E( 21,  0),
+    E(-21,  0), E( 22,  0), E(-22,  0), E( 23,  0), E(-23,  0), E(  0,  1),
+    E( 10,  1), E(-10,  1), E( 11,  1), E(-11,  1), E(  0,  2), E(  5,  2),
+    E( -5,  2), E(  6,  2), E( -6,  2), E(  0,  3), E(  4,  3), E( -4,  3),
+    E(  0,  4), E(  3,  5), E( -3,  5), E(  3,  6), E( -3,  6), E(  2,  9),
+    E( -2,  9), E(  1, 15), E( -1, 15), E( 24,  0), E(-24,  0), E( 25,  0),
+    E(-25,  0), E( 26,  0), E(-26,  0), E( 12,  1), E(-12,  1), E( 13,  1),
+    E(-13,  1), E(  5,  3), E( -5,  3), E(  4,  4), E( -4,  4), E(  0,  5),
+    E(  4,  5), E( -4,  5), E(  0,  6), E(  0,  7), E(  3,  7), E( -3,  7),
+    E(  0,  8), E(  3,  8), E( -3,  8), E(  0,  9), E(  1, 16), E( -1, 16),
+    // AC table Q64 - 257 elements
+    E(  1,  0), E( -1,  0), E(  0, 64), E(  2,  0), E( -2,  0), E(  3,  0),
+    E( -3,  0), E(  1,  1), E( -1,  1), E(  4,  0), E( -4,  0), E(  2,  1),
+    E( -2,  1), E(  1,  2), E( -1,  2), E(  5,  0), E( -5,  0), E(  1,  3),
+    E( -1,  3), E(  1,  4), E( -1,  4), E(  6,  0), E( -6,  0), E(  3,  1),
+    E( -3,  1), E(  2,  2), E( -2,  2), E(  1,  5), E( -1,  5), E(  1,  6),
+    E( -1,  6), E(  1,  7), E( -1,  7), E(  7,  0), E( -7,  0), E(  8,  0),
+    E( -8,  0), E(  4,  1), E( -4,  1), E(  2,  3), E( -2,  3), E(  1,  8),
+    E( -1,  8), E(  1,  9), E( -1,  9), E(  9,  0), E( -9,  0), E( 10,  0),
+    E(-10,  0), E(  5,  1), E( -5,  1), E(  3,  2), E( -3,  2), E(  2,  4),
+    E( -2,  4), E(  2,  5), E( -2,  5), E(  1, 10), E( -1, 10), E(  1, 11),
+    E( -1, 11), E(  0,  0), E(  0,  1), E(  0,  2), E(  0,  3), E(  0,  4),
+    E(  0,  5), E(  0,  6), E(  0,  7), E(  0,  8), E(  0,  9), E(  0, 10),
+    E(  0, 11), E(  0, 12), E(  0, 13), E(  0, 14), E(  0, 15), E(  0, 16),
+    E(  0, 17), E(  0, 18), E(  0, 19), E(  0, 20), E(  0, 21), E(  0, 22),
+    E(  0, 23), E(  0, 24), E(  0, 25), E(  0, 26), E(  0, 27), E(  0, 28),
+    E(  0, 29), E(  0, 30), E(  0, 31), E(  0, 32), E(  0, 33), E(  0, 34),
+    E(  0, 35), E(  0, 36), E(  0, 37), E(  0, 38), E(  0, 39), E(  0, 40),
+    E(  0, 41), E(  0, 42), E(  0, 43), E(  0, 44), E(  0, 45), E(  0, 46),
+    E(  0, 47), E(  0, 48), E(  0, 49), E(  0, 50), E(  0, 51), E(  0, 52),
+    E(  0, 53), E(  0, 54), E(  0, 55), E(  0, 56), E(  0, 57), E(  0, 58),
+    E(  0, 59), E(  0, 60), E(  0, 61), E(  0, 62), E(  0, 63), E(  0,  0),
+    E( 11,  0), E(-11,  0), E( 12,  0), E(-12,  0), E(  6,  1), E( -6,  1),
+    E(  7,  1), E( -7,  1), E(  3,  3), E( -3,  3), E(  3,  4), E( -3,  4),
+    E(  3,  5), E( -3,  5), E(  2,  6), E( -2,  6), E(  2,  7), E( -2,  7),
+    E(  1, 12), E( -1, 12), E(  1, 13), E( -1, 13), E(  1, 14), E( -1, 14),
+    E( 13,  0), E(-13,  0), E( 14,  0), E(-14,  0), E(  0,  1), E(  8,  1),
+    E( -8,  1), E(  4,  2), E( -4,  2), E(  4,  3), E( -4,  3), E(  2,  8),
+    E( -2,  8), E(  2,  9), E( -2,  9), E(  1, 15), E( -1, 15), E(  0,  0),
+    E(  1,  0), E( -1,  0), E(  2,  0), E( -2,  0), E(  3,  0), E( -3,  0),
+    E(  4,  0), E( -4,  0), E(  5,  0), E( -5,  0), E(  6,  0), E( -6,  0),
+    E(  7,  0), E( -7,  0), E(  8,  0), E( -8,  0), E(  9,  0), E( -9,  0),
+    E( 10,  0), E(-10,  0), E( 11,  0), E(-11,  0), E( 12,  0), E(-12,  0),
+    E( 13,  0), E(-13,  0), E( 14,  0), E(-14,  0), E( 15,  0), E(-15,  0),
+    E( 16,  0), E(-16,  0), E( 17,  0), E(-17,  0), E( 18,  0), E(-18,  0),
+    E( 19,  0), E(-19,  0), E( 20,  0), E(-20,  0), E( 21,  0), E(-21,  0),
+    E( 22,  0), E(-22,  0), E( 23,  0), E(-23,  0), E( 24,  0), E(-24,  0),
+    E( 25,  0), E(-25,  0), E( 26,  0), E(-26,  0), E( 27,  0), E(-27,  0),
+    E( 28,  0), E(-28,  0), E( 29,  0), E(-29,  0), E( 30,  0), E(-30,  0),
+    E( 31,  0), E(-31,  0), E( 15,  0), E(-15,  0), E(  9,  1), E( -9,  1),
+    E( 10,  1), E(-10,  1), E(  0,  2), E(  5,  2), E( -5,  2), E(  0,  3),
+    E(  5,  3), E( -5,  3), E(  0,  4), E(  4,  4), E( -4,  4), E(  0,  5),
+    E(  4,  5), E( -4,  5), E(  0,  6), E(  3,  6), E( -3,  6), E(  3,  7),
+    E( -3,  7), E(  1, 16), E( -1, 16), E(  1, 17), E( -1, 17),
+    // AC table Q128 - 194 elements
+    E(  1,  0), E( -1,  0), E(  0, 64), E(  1,  1), E( -1,  1), E(  2,  0),
+    E( -2,  0), E(  3,  0), E( -3,  0), E(  2,  1), E( -2,  1), E(  1,  2),
+    E( -1,  2), E(  1,  3), E( -1,  3), E(  1,  4), E( -1,  4), E(  4,  0),
+    E( -4,  0), E(  1,  5), E( -1,  5), E(  1,  6), E( -1,  6), E(  1,  7),
+    E( -1,  7), E(  5,  0), E( -5,  0), E(  3,  1), E( -3,  1), E(  2,  2),
+    E( -2,  2), E(  2,  3), E( -2,  3), E(  1,  8), E( -1,  8), E(  1,  9),
+    E( -1,  9), E(  6,  0), E( -6,  0), E(  4,  1), E( -4,  1), E(  2,  4),
+    E( -2,  4), E(  2,  5), E( -2,  5), E(  1, 10), E( -1, 10), E(  7,  0),
+    E( -7,  0), E(  5,  1), E( -5,  1), E(  3,  2), E( -3,  2), E(  3,  3),
+    E( -3,  3), E(  2,  6), E( -2,  6), E(  0,  0), E(  0,  1), E(  0,  2),
+    E(  0,  3), E(  0,  4), E(  0,  5), E(  0,  6), E(  0,  7), E(  0,  8),
+    E(  0,  9), E(  0, 10), E(  0, 11), E(  0, 12), E(  0, 13), E(  0, 14),
+    E(  0, 15), E(  0, 16), E(  0, 17), E(  0, 18), E(  0, 19), E(  0, 20),
+    E(  0, 21), E(  0, 22), E(  0, 23), E(  0, 24), E(  0, 25), E(  0, 26),
+    E(  0, 27), E(  0, 28), E(  0, 29), E(  0, 30), E(  0, 31), E(  0, 32),
+    E(  0, 33), E(  0, 34), E(  0, 35), E(  0, 36), E(  0, 37), E(  0, 38),
+    E(  0, 39), E(  0, 40), E(  0, 41), E(  0, 42), E(  0, 43), E(  0, 44),
+    E(  0, 45), E(  0, 46), E(  0, 47), E(  0, 48), E(  0, 49), E(  0, 50),
+    E(  0, 51), E(  0, 52), E(  0, 53), E(  0, 54), E(  0, 55), E(  0, 56),
+    E(  0, 57), E(  0, 58), E(  0, 59), E(  0, 60), E(  0, 61), E(  0, 62),
+    E(  0, 63), E(  6,  1), E( -6,  1), E(  7,  1), E( -7,  1), E(  3,  4),
+    E( -3,  4), E(  3,  5), E( -3,  5), E(  2,  7), E( -2,  7), E(  2,  8),
+    E( -2,  8), E(  2,  9), E( -2,  9), E(  1, 11), E( -1, 11), E(  1, 12),
+    E( -1, 12), E(  1, 13), E( -1, 13), E(  0,  0), E(  8,  0), E( -8,  0),
+    E(  9,  0), E( -9,  0), E(  8,  1), E( -8,  1), E(  4,  2), E( -4,  2),
+    E(  4,  3), E( -4,  3), E(  3,  6), E( -3,  6), E(  1, 14), E( -1, 14),
+    E(  1, 15), E( -1, 15), E(  1, 16), E( -1, 16), E(  0,  1), E(  0,  2),
+    E(  0,  3), E(  0,  0), E(  1,  0), E( -1,  0), E(  2,  0), E( -2,  0),
+    E(  3,  0), E( -3,  0), E(  4,  0), E( -4,  0), E(  5,  0), E( -5,  0),
+    E(  6,  0), E( -6,  0), E(  7,  0), E( -7,  0), E(  8,  0), E( -8,  0),
+    E(  9,  0), E( -9,  0), E( 10,  0), E(-10,  0), E( 11,  0), E(-11,  0),
+    E( 12,  0), E(-12,  0), E( 13,  0), E(-13,  0), E( 14,  0), E(-14,  0),
+    E( 15,  0), E(-15,  0),
 };
 
-static const HQXLUT ac32_lut[] = {
-    RPT_256 (   1,  0,  3 ), RPT_256 (  -1,  0,  3 ),
-    RPT_128 (   2,  0,  4 ), RPT_128 (  -2,  0,  4 ),
-    RPT_256 (   0, 64,  3 ), RPT_64  (   3,  0,  5 ),
-    RPT_64  (  -3,  0,  5 ), RPT_64  (   1,  1,  5 ),
-    RPT_64  (  -1,  1,  5 ), RPT_32  (   4,  0,  6 ),
-    RPT_32  (  -4,  0,  6 ), RPT_32  (   5,  0,  6 ),
-    RPT_32  (  -5,  0,  6 ), RPT_32  (   2,  1,  6 ),
-    RPT_32  (  -2,  1,  6 ), RPT_32  (   1,  2,  6 ),
-    RPT_32  (  -1,  2,  6 ), RPT_32  (   1,  3,  6 ),
-    RPT_32  (  -1,  3,  6 ), RPT_16  (   6,  0,  7 ),
-    RPT_16  (  -6,  0,  7 ), RPT_16  (   7,  0,  7 ),
-    RPT_16  (  -7,  0,  7 ), RPT_16  (   3,  1,  7 ),
-    RPT_16  (  -3,  1,  7 ), RPT_16  (   1,  4,  7 ),
-    RPT_16  (  -1,  4,  7 ), RPT_16  (   1,  5,  7 ),
-    RPT_16  (  -1,  5,  7 ), RPT_8   (   8,  0,  8 ),
-    RPT_8   (  -8,  0,  8 ), RPT_8   (   9,  0,  8 ),
-    RPT_8   (  -9,  0,  8 ), RPT_8   (  10,  0,  8 ),
-    RPT_8   ( -10,  0,  8 ), RPT_8   (   4,  1,  8 ),
-    RPT_8   (  -4,  1,  8 ), RPT_8   (   2,  2,  8 ),
-    RPT_8   (  -2,  2,  8 ), RPT_8   (   1,  6,  8 ),
-    RPT_8   (  -1,  6,  8 ), RPT_8   (   1,  7,  8 ),
-    RPT_8   (  -1,  7,  8 ), RPT_8   (   1,  8,  8 ),
-    RPT_8   (  -1,  8,  8 ), RPT_4   (  11,  0,  9 ),
-    RPT_4   ( -11,  0,  9 ), RPT_4   (  12,  0,  9 ),
-    RPT_4   ( -12,  0,  9 ), RPT_4   (  13,  0,  9 ),
-    RPT_4   ( -13,  0,  9 ), RPT_4   (   5,  1,  9 ),
-    RPT_4   (  -5,  1,  9 ), RPT_4   (   2,  3,  9 ),
-    RPT_4   (  -2,  3,  9 ), RPT_4   (   1,  9,  9 ),
-    RPT_4   (  -1,  9,  9 ), RPT_4   (   1, 10,  9 ),
-    RPT_4   (  -1, 10,  9 ), RPT_2   (  14,  0, 10 ),
-    RPT_2   ( -14,  0, 10 ), RPT_2   (  15,  0, 10 ),
-    RPT_2   ( -15,  0, 10 ), RPT_2   (  16,  0, 10 ),
-    RPT_2   ( -16,  0, 10 ), RPT_2   (   6,  1, 10 ),
-    RPT_2   (  -6,  1, 10 ), RPT_2   (   7,  1, 10 ),
-    RPT_2   (  -7,  1, 10 ), RPT_2   (   3,  2, 10 ),
-    RPT_2   (  -3,  2, 10 ), RPT_2   (   3,  3, 10 ),
-    RPT_2   (  -3,  3, 10 ), RPT_2   (   2,  4, 10 ),
-    RPT_2   (  -2,  4, 10 ), RPT_2   (   2,  5, 10 ),
-    RPT_2   (  -2,  5, 10 ), RPT_2   (   1, 11, 10 ),
-    RPT_2   (  -1, 11, 10 ), RPT_2   (   1, 12, 10 ),
-    RPT_2   (  -1, 12, 10 ), RPT_2   (   1, 13, 10 ),
-    RPT_2   (  -1, 13, 10 ), { 2048,  0, -1 }, { 2112,  0, -1 },
-    { 2176,  0, -1 }, { 2240,  0, -1 }, RPT_2   (   0,  0, 10 ),
-    {   17,  0, 11 }, {  -17,  0, 11 }, {   18,  0, 11 }, {  -18,  0, 11 },
-    {   19,  0, 11 }, {  -19,  0, 11 }, {   20,  0, 11 }, {  -20,  0, 11 },
-    {    8,  1, 11 }, {   -8,  1, 11 }, {    9,  1, 11 }, {   -9,  1, 11 },
-    {    4,  2, 11 }, {   -4,  2, 11 }, {    3,  4, 11 }, {   -3,  4, 11 },
-    {    2,  6, 11 }, {   -2,  6, 11 }, {    2,  7, 11 }, {   -2,  7, 11 },
-    {    2,  8, 11 }, {   -2,  8, 11 }, {    1, 14, 11 }, {   -1, 14, 11 },
-    { 2304,  0, -1 }, { 2368,  0, -1 }, { 2432,  0, -1 }, { 2496,  0, -1 },
-    { 2560,  0, -1 }, {    0,  1, 11 }, { 2624,  0, -1 }, { 2688,  0, -1 },
-    {    0,  2, 11 }, { 2752,  0, -1 }, { 2816,  0, -1 }, {    0,  3, 11 },
-    { 2880,  0, -1 }, {    0,  4, 11 }, { 2944,  0, -1 }, { 3008,  0, -1 },
-    { 3072,  0, -1 }, { 3136,  0, -1 }, { 3200,  0, -1 }, { 3264,  0, -1 },
-    { 3328,  0, -1 }, { 3392,  0, -1 }, { 3456,  0, -1 }, { 3520,  0, -1 },
-    { 3584,  0, -1 }, { 3648,  0, -1 }, RPT_4   (   0,  0, 15 ),
-    RPT_4   (   0,  1, 15 ), RPT_4   (   0,  2, 15 ),
-    RPT_4   (   0,  3, 15 ), RPT_4   (   0,  4, 15 ),
-    RPT_4   (   0,  5, 15 ), RPT_4   (   0,  6, 15 ),
-    RPT_4   (   0,  7, 15 ), RPT_4   (   0,  8, 15 ),
-    RPT_4   (   0,  9, 15 ), RPT_4   (   0, 10, 15 ),
-    RPT_4   (   0, 11, 15 ), RPT_4   (   0, 12, 15 ),
-    RPT_4   (   0, 13, 15 ), RPT_4   (   0, 14, 15 ),
-    RPT_4   (   0, 15, 15 ), RPT_4   (   0, 16, 15 ),
-    RPT_4   (   0, 17, 15 ), RPT_4   (   0, 18, 15 ),
-    RPT_4   (   0, 19, 15 ), RPT_4   (   0, 20, 15 ),
-    RPT_4   (   0, 21, 15 ), RPT_4   (   0, 22, 15 ),
-    RPT_4   (   0, 23, 15 ), RPT_4   (   0, 24, 15 ),
-    RPT_4   (   0, 25, 15 ), RPT_4   (   0, 26, 15 ),
-    RPT_4   (   0, 27, 15 ), RPT_4   (   0, 28, 15 ),
-    RPT_4   (   0, 29, 15 ), RPT_4   (   0, 30, 15 ),
-    RPT_4   (   0, 31, 15 ), RPT_4   (   0, 32, 15 ),
-    RPT_4   (   0, 33, 15 ), RPT_4   (   0, 34, 15 ),
-    RPT_4   (   0, 35, 15 ), RPT_4   (   0, 36, 15 ),
-    RPT_4   (   0, 37, 15 ), RPT_4   (   0, 38, 15 ),
-    RPT_4   (   0, 39, 15 ), RPT_4   (   0, 40, 15 ),
-    RPT_4   (   0, 41, 15 ), RPT_4   (   0, 42, 15 ),
-    RPT_4   (   0, 43, 15 ), RPT_4   (   0, 44, 15 ),
-    RPT_4   (   0, 45, 15 ), RPT_4   (   0, 46, 15 ),
-    RPT_4   (   0, 47, 15 ), RPT_4   (   0, 48, 15 ),
-    RPT_4   (   0, 49, 15 ), RPT_4   (   0, 50, 15 ),
-    RPT_4   (   0, 51, 15 ), RPT_4   (   0, 52, 15 ),
-    RPT_4   (   0, 53, 15 ), RPT_4   (   0, 54, 15 ),
-    RPT_4   (   0, 55, 15 ), RPT_4   (   0, 56, 15 ),
-    RPT_4   (   0, 57, 15 ), RPT_4   (   0, 58, 15 ),
-    RPT_4   (   0, 59, 15 ), RPT_4   (   0, 60, 15 ),
-    RPT_4   (   0, 61, 15 ), RPT_4   (   0, 62, 15 ),
-    RPT_4   (   0, 63, 15 ), RPT_2   (   0,  0, 16 ),
-    {    1,  0, 17 }, {   -1,  0, 17 }, {    2,  0, 17 }, {   -2,  0, 17 },
-    {    3,  0, 17 }, {   -3,  0, 17 }, {    4,  0, 17 }, {   -4,  0, 17 },
-    {    5,  0, 17 }, {   -5,  0, 17 }, {    6,  0, 17 }, {   -6,  0, 17 },
-    {    7,  0, 17 }, {   -7,  0, 17 }, {    8,  0, 17 }, {   -8,  0, 17 },
-    {    9,  0, 17 }, {   -9,  0, 17 }, {   10,  0, 17 }, {  -10,  0, 17 },
-    {   11,  0, 17 }, {  -11,  0, 17 }, {   12,  0, 17 }, {  -12,  0, 17 },
-    {   13,  0, 17 }, {  -13,  0, 17 }, {   14,  0, 17 }, {  -14,  0, 17 },
-    {   15,  0, 17 }, {  -15,  0, 17 }, {   16,  0, 17 }, {  -16,  0, 17 },
-    {   17,  0, 17 }, {  -17,  0, 17 }, {   18,  0, 17 }, {  -18,  0, 17 },
-    {   19,  0, 17 }, {  -19,  0, 17 }, {   20,  0, 17 }, {  -20,  0, 17 },
-    {   21,  0, 17 }, {  -21,  0, 17 }, {   22,  0, 17 }, {  -22,  0, 17 },
-    {   23,  0, 17 }, {  -23,  0, 17 }, {   24,  0, 17 }, {  -24,  0, 17 },
-    {   25,  0, 17 }, {  -25,  0, 17 }, {   26,  0, 17 }, {  -26,  0, 17 },
-    {   27,  0, 17 }, {  -27,  0, 17 }, {   28,  0, 17 }, {  -28,  0, 17 },
-    {   29,  0, 17 }, {  -29,  0, 17 }, {   30,  0, 17 }, {  -30,  0, 17 },
-    {   31,  0, 17 }, {  -31,  0, 17 }, {   32,  0, 17 }, {  -32,  0, 17 },
-    {   33,  0, 17 }, {  -33,  0, 17 }, {   34,  0, 17 }, {  -34,  0, 17 },
-    {   35,  0, 17 }, {  -35,  0, 17 }, {   36,  0, 17 }, {  -36,  0, 17 },
-    {   37,  0, 17 }, {  -37,  0, 17 }, {   38,  0, 17 }, {  -38,  0, 17 },
-    {   39,  0, 17 }, {  -39,  0, 17 }, {   40,  0, 17 }, {  -40,  0, 17 },
-    {   41,  0, 17 }, {  -41,  0, 17 }, {   42,  0, 17 }, {  -42,  0, 17 },
-    {   43,  0, 17 }, {  -43,  0, 17 }, {   44,  0, 17 }, {  -44,  0, 17 },
-    {   45,  0, 17 }, {  -45,  0, 17 }, {   46,  0, 17 }, {  -46,  0, 17 },
-    {   47,  0, 17 }, {  -47,  0, 17 }, {   48,  0, 17 }, {  -48,  0, 17 },
-    {   49,  0, 17 }, {  -49,  0, 17 }, {   50,  0, 17 }, {  -50,  0, 17 },
-    {   51,  0, 17 }, {  -51,  0, 17 }, {   52,  0, 17 }, {  -52,  0, 17 },
-    {   53,  0, 17 }, {  -53,  0, 17 }, {   54,  0, 17 }, {  -54,  0, 17 },
-    {   55,  0, 17 }, {  -55,  0, 17 }, {   56,  0, 17 }, {  -56,  0, 17 },
-    {   57,  0, 17 }, {  -57,  0, 17 }, {   58,  0, 17 }, {  -58,  0, 17 },
-    {   59,  0, 17 }, {  -59,  0, 17 }, {   60,  0, 17 }, {  -60,  0, 17 },
-    {   61,  0, 17 }, {  -61,  0, 17 }, {   62,  0, 17 }, {  -62,  0, 17 },
-    {   63,  0, 17 }, {  -63,  0, 17 }, RPT_32  (  21,  0, 12 ),
-    RPT_32  ( -21,  0, 12 ), RPT_32  (  22,  0, 12 ),
-    RPT_32  ( -22,  0, 12 ), RPT_32  (  23,  0, 12 ),
-    RPT_32  ( -23,  0, 12 ), RPT_32  (  10,  1, 12 ),
-    RPT_32  ( -10,  1, 12 ), RPT_32  (  11,  1, 12 ),
-    RPT_32  ( -11,  1, 12 ), RPT_32  (   5,  2, 12 ),
-    RPT_32  (  -5,  2, 12 ), RPT_32  (   6,  2, 12 ),
-    RPT_32  (  -6,  2, 12 ), RPT_32  (   4,  3, 12 ),
-    RPT_32  (  -4,  3, 12 ), RPT_32  (   3,  5, 12 ),
-    RPT_32  (  -3,  5, 12 ), RPT_32  (   3,  6, 12 ),
-    RPT_32  (  -3,  6, 12 ), RPT_32  (   2,  9, 12 ),
-    RPT_32  (  -2,  9, 12 ), RPT_32  (   1, 15, 12 ),
-    RPT_32  (  -1, 15, 12 ), RPT_16  (  24,  0, 13 ),
-    RPT_16  ( -24,  0, 13 ), RPT_16  (  25,  0, 13 ),
-    RPT_16  ( -25,  0, 13 ), RPT_16  (  26,  0, 13 ),
-    RPT_16  ( -26,  0, 13 ), RPT_16  (  12,  1, 13 ),
-    RPT_16  ( -12,  1, 13 ), RPT_16  (  13,  1, 13 ),
-    RPT_16  ( -13,  1, 13 ), RPT_16  (   5,  3, 13 ),
-    RPT_16  (  -5,  3, 13 ), RPT_16  (   4,  4, 13 ),
-    RPT_16  (  -4,  4, 13 ), RPT_32  (   0,  5, 12 ),
-    RPT_16  (   4,  5, 13 ), RPT_16  (  -4,  5, 13 ),
-    RPT_32  (   0,  6, 12 ), RPT_32  (   0,  7, 12 ),
-    RPT_16  (   3,  7, 13 ), RPT_16  (  -3,  7, 13 ),
-    RPT_32  (   0,  8, 12 ), RPT_16  (   3,  8, 13 ),
-    RPT_16  (  -3,  8, 13 ), RPT_32  (   0,  9, 12 ),
-    RPT_16  (   1, 16, 13 ), RPT_16  (  -1, 16, 13 ),
+static const uint8_t hqx_ac_lens[] = {
+    // AC table Q0 - 815 elements
+     4,  4,  4,  4,  5,  5,  5,  5,  5,  5,  6,  6,  6,  6,  6,  6,  6,  6,
+    13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14,  5,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+     7,  7,  7,  7,  7,  7,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
+     8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,
+     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+     9,  9,  9,  9,  9,  9,  9,  9,  9, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+    10, 10, 10, 10, 10, 10, 10,  9, 10, 10, 10, 10, 10, 10, 10, 10,  9, 10,
+    10,  9, 10, 10, 10, 10, 10, 10, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+    11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+    11, 11, 11, 11, 11, 11, 10, 11, 11, 10, 10, 11, 11, 11, 11, 12, 12, 12,
+    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13,
+    13, 13, 13, 13, 13,
+    // AC table Q8 - 907 elements
+     4,  4,  4,  4,  5,  5,  5,  5,  4,  6,  6,  6,  6,  6,  6,  6,  6,  6,
+     6,  6,  6,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7, 14,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
+     8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 10,
+    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+    10, 10, 10,  9, 10, 10, 10, 10, 10, 10, 10, 10,  9, 10, 10, 10, 10, 10,
+    10,  9, 10, 10, 10, 10,  9, 10, 10,  9, 10, 10, 10, 10, 10, 10, 11, 11,
+    11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+    11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+    11, 11, 11, 11, 11, 11, 11, 11, 10, 11, 11, 10, 10, 10, 11, 11, 11, 11,
+    11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 12, 12, 11, 11, 11,
+    12, 12, 12, 12, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 13, 13, 13, 13,
+    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+    13, 13, 13, 13, 13, 13, 12,
+    // AC table Q16 - 512 elements
+     3,  3,  4,  4,  5,  5,  5,  5,  5,  5,  4,  6,  6,  6,  6,  6,  6,  6,
+     6,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  8,  8,  8,  8,  8,
+     8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 10, 10, 10, 10,
+    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+    10, 10, 10, 10, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 11,
+    11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+    11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 11, 12, 12, 12, 12, 12, 12, 11, 12, 12, 11, 12, 12, 12, 12,
+    12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 13, 13, 12, 12, 13,
+    13, 12, 13, 13, 13, 13, 13, 13,
+    // AC table Q32 - 354 elements
+     3,  3,  4,  4,  3,  5,  5,  5,  5,  6,  6,  6,  6,  6,  6,  6,  6,  6,
+     6,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  8,  8,  8,  8,  8,  8,  8,
+     8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+     9,  9,  9,  9,  9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+    11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 16, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 12, 12, 12, 12, 12, 12, 11,
+    12, 12, 12, 12, 11, 12, 12, 12, 12, 11, 12, 12, 11, 12, 12, 12, 12, 12,
+    12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12,
+    13, 13, 12, 12, 13, 13, 12, 13, 13, 12, 13, 13,
+    // AC table Q64 - 257 elements
+     3,  3,  2,  4,  4,  5,  5,  5,  5,  6,  6,  6,  6,  6,  6,  7,  7,  7,
+     7,  7,  7,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  9,  9,
+     9,  9,  9,  9,  9,  9,  9,  9,  9, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+    10, 10, 10, 10, 10, 10, 10, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 10,
+    11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+    11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 11, 12, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 12, 12, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 13, 13, 13, 13,
+    13, 13, 12, 13, 13, 12, 13, 13, 12, 13, 13, 12, 13, 13, 12, 13, 13, 13,
+    13, 13, 13, 13, 13,
+    // AC table Q128 - 194 elements
+     3,  3,  2,  4,  4,  5,  5,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  7,
+     7,  7,  7,  7,  7,  7,  7,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
+     8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 10, 10, 10, 10, 10, 10, 10,
+    10, 10, 10, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 11, 11, 11, 11, 11,
+    11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12,
+    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+    12, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
 };
 
-static const HQXLUT ac64_lut[] = {
-    RPT_512 (   1,  0,  3 ), RPT_512 (  -1,  0,  3 ),
-    RPT_1024(   0, 64,  2 ), RPT_256 (   2,  0,  4 ),
-    RPT_256 (  -2,  0,  4 ), RPT_128 (   3,  0,  5 ),
-    RPT_128 (  -3,  0,  5 ), RPT_128 (   1,  1,  5 ),
-    RPT_128 (  -1,  1,  5 ), RPT_64  (   4,  0,  6 ),
-    RPT_64  (  -4,  0,  6 ), RPT_64  (   2,  1,  6 ),
-    RPT_64  (  -2,  1,  6 ), RPT_64  (   1,  2,  6 ),
-    RPT_64  (  -1,  2,  6 ), RPT_32  (   5,  0,  7 ),
-    RPT_32  (  -5,  0,  7 ), RPT_32  (   1,  3,  7 ),
-    RPT_32  (  -1,  3,  7 ), RPT_32  (   1,  4,  7 ),
-    RPT_32  (  -1,  4,  7 ), RPT_16  (   6,  0,  8 ),
-    RPT_16  (  -6,  0,  8 ), RPT_16  (   3,  1,  8 ),
-    RPT_16  (  -3,  1,  8 ), RPT_16  (   2,  2,  8 ),
-    RPT_16  (  -2,  2,  8 ), RPT_16  (   1,  5,  8 ),
-    RPT_16  (  -1,  5,  8 ), RPT_16  (   1,  6,  8 ),
-    RPT_16  (  -1,  6,  8 ), RPT_16  (   1,  7,  8 ),
-    RPT_16  (  -1,  7,  8 ), RPT_8   (   7,  0,  9 ),
-    RPT_8   (  -7,  0,  9 ), RPT_8   (   8,  0,  9 ),
-    RPT_8   (  -8,  0,  9 ), RPT_8   (   4,  1,  9 ),
-    RPT_8   (  -4,  1,  9 ), RPT_8   (   2,  3,  9 ),
-    RPT_8   (  -2,  3,  9 ), RPT_8   (   1,  8,  9 ),
-    RPT_8   (  -1,  8,  9 ), RPT_8   (   1,  9,  9 ),
-    RPT_8   (  -1,  9,  9 ), RPT_4   (   9,  0, 10 ),
-    RPT_4   (  -9,  0, 10 ), RPT_4   (  10,  0, 10 ),
-    RPT_4   ( -10,  0, 10 ), RPT_4   (   5,  1, 10 ),
-    RPT_4   (  -5,  1, 10 ), RPT_4   (   3,  2, 10 ),
-    RPT_4   (  -3,  2, 10 ), RPT_4   (   2,  4, 10 ),
-    RPT_4   (  -2,  4, 10 ), RPT_4   (   2,  5, 10 ),
-    RPT_4   (  -2,  5, 10 ), RPT_4   (   1, 10, 10 ),
-    RPT_4   (  -1, 10, 10 ), RPT_4   (   1, 11, 10 ),
-    RPT_4   (  -1, 11, 10 ), { 4096,  0, -1 }, { 4128,  0, -1 },
-    { 4160,  0, -1 }, { 4192,  0, -1 }, { 4224,  0, -1 }, { 4256,  0, -1 },
-    { 4288,  0, -1 }, { 4320,  0, -1 }, RPT_4   (   0,  0, 10 ),
-    RPT_2   (  11,  0, 11 ), RPT_2   ( -11,  0, 11 ),
-    RPT_2   (  12,  0, 11 ), RPT_2   ( -12,  0, 11 ),
-    RPT_2   (   6,  1, 11 ), RPT_2   (  -6,  1, 11 ),
-    RPT_2   (   7,  1, 11 ), RPT_2   (  -7,  1, 11 ),
-    RPT_2   (   3,  3, 11 ), RPT_2   (  -3,  3, 11 ),
-    RPT_2   (   3,  4, 11 ), RPT_2   (  -3,  4, 11 ),
-    RPT_2   (   3,  5, 11 ), RPT_2   (  -3,  5, 11 ),
-    RPT_2   (   2,  6, 11 ), RPT_2   (  -2,  6, 11 ),
-    RPT_2   (   2,  7, 11 ), RPT_2   (  -2,  7, 11 ),
-    RPT_2   (   1, 12, 11 ), RPT_2   (  -1, 12, 11 ),
-    RPT_2   (   1, 13, 11 ), RPT_2   (  -1, 13, 11 ),
-    RPT_2   (   1, 14, 11 ), RPT_2   (  -1, 14, 11 ),
-    {   13,  0, 12 }, {  -13,  0, 12 }, {   14,  0, 12 }, {  -14,  0, 12 },
-    RPT_2   (   0,  1, 11 ), {    8,  1, 12 }, {   -8,  1, 12 },
-    {    4,  2, 12 }, {   -4,  2, 12 }, {    4,  3, 12 }, {   -4,  3, 12 },
-    {    2,  8, 12 }, {   -2,  8, 12 }, {    2,  9, 12 }, {   -2,  9, 12 },
-    {    1, 15, 12 }, {   -1, 15, 12 }, { 4352,  0, -1 }, { 4384,  0, -1 },
-    { 4416,  0, -1 }, { 4448,  0, -1 }, { 4480,  0, -1 }, {    0,  2, 12 },
-    { 4512,  0, -1 }, {    0,  3, 12 }, { 4544,  0, -1 }, {    0,  4, 12 },
-    { 4576,  0, -1 }, {    0,  5, 12 }, { 4608,  0, -1 }, {    0,  6, 12 },
-    { 4640,  0, -1 }, { 4672,  0, -1 }, { 4704,  0, -1 }, { 4736,  0, -1 },
-    RPT_4   (   0,  0, 15 ), RPT_4   (   0,  1, 15 ),
-    RPT_4   (   0,  2, 15 ), RPT_4   (   0,  3, 15 ),
-    RPT_4   (   0,  4, 15 ), RPT_4   (   0,  5, 15 ),
-    RPT_4   (   0,  6, 15 ), RPT_4   (   0,  7, 15 ),
-    RPT_4   (   0,  8, 15 ), RPT_4   (   0,  9, 15 ),
-    RPT_4   (   0, 10, 15 ), RPT_4   (   0, 11, 15 ),
-    RPT_4   (   0, 12, 15 ), RPT_4   (   0, 13, 15 ),
-    RPT_4   (   0, 14, 15 ), RPT_4   (   0, 15, 15 ),
-    RPT_4   (   0, 16, 15 ), RPT_4   (   0, 17, 15 ),
-    RPT_4   (   0, 18, 15 ), RPT_4   (   0, 19, 15 ),
-    RPT_4   (   0, 20, 15 ), RPT_4   (   0, 21, 15 ),
-    RPT_4   (   0, 22, 15 ), RPT_4   (   0, 23, 15 ),
-    RPT_4   (   0, 24, 15 ), RPT_4   (   0, 25, 15 ),
-    RPT_4   (   0, 26, 15 ), RPT_4   (   0, 27, 15 ),
-    RPT_4   (   0, 28, 15 ), RPT_4   (   0, 29, 15 ),
-    RPT_4   (   0, 30, 15 ), RPT_4   (   0, 31, 15 ),
-    RPT_4   (   0, 32, 15 ), RPT_4   (   0, 33, 15 ),
-    RPT_4   (   0, 34, 15 ), RPT_4   (   0, 35, 15 ),
-    RPT_4   (   0, 36, 15 ), RPT_4   (   0, 37, 15 ),
-    RPT_4   (   0, 38, 15 ), RPT_4   (   0, 39, 15 ),
-    RPT_4   (   0, 40, 15 ), RPT_4   (   0, 41, 15 ),
-    RPT_4   (   0, 42, 15 ), RPT_4   (   0, 43, 15 ),
-    RPT_4   (   0, 44, 15 ), RPT_4   (   0, 45, 15 ),
-    RPT_4   (   0, 46, 15 ), RPT_4   (   0, 47, 15 ),
-    RPT_4   (   0, 48, 15 ), RPT_4   (   0, 49, 15 ),
-    RPT_4   (   0, 50, 15 ), RPT_4   (   0, 51, 15 ),
-    RPT_4   (   0, 52, 15 ), RPT_4   (   0, 53, 15 ),
-    RPT_4   (   0, 54, 15 ), RPT_4   (   0, 55, 15 ),
-    RPT_4   (   0, 56, 15 ), RPT_4   (   0, 57, 15 ),
-    RPT_4   (   0, 58, 15 ), RPT_4   (   0, 59, 15 ),
-    RPT_4   (   0, 60, 15 ), RPT_4   (   0, 61, 15 ),
-    RPT_4   (   0, 62, 15 ), RPT_4   (   0, 63, 15 ),
-    RPT_2   (   0,  0, 16 ), {    1,  0, 17 }, {   -1,  0, 17 },
-    {    2,  0, 17 }, {   -2,  0, 17 }, {    3,  0, 17 }, {   -3,  0, 17 },
-    {    4,  0, 17 }, {   -4,  0, 17 }, {    5,  0, 17 }, {   -5,  0, 17 },
-    {    6,  0, 17 }, {   -6,  0, 17 }, {    7,  0, 17 }, {   -7,  0, 17 },
-    {    8,  0, 17 }, {   -8,  0, 17 }, {    9,  0, 17 }, {   -9,  0, 17 },
-    {   10,  0, 17 }, {  -10,  0, 17 }, {   11,  0, 17 }, {  -11,  0, 17 },
-    {   12,  0, 17 }, {  -12,  0, 17 }, {   13,  0, 17 }, {  -13,  0, 17 },
-    {   14,  0, 17 }, {  -14,  0, 17 }, {   15,  0, 17 }, {  -15,  0, 17 },
-    {   16,  0, 17 }, {  -16,  0, 17 }, {   17,  0, 17 }, {  -17,  0, 17 },
-    {   18,  0, 17 }, {  -18,  0, 17 }, {   19,  0, 17 }, {  -19,  0, 17 },
-    {   20,  0, 17 }, {  -20,  0, 17 }, {   21,  0, 17 }, {  -21,  0, 17 },
-    {   22,  0, 17 }, {  -22,  0, 17 }, {   23,  0, 17 }, {  -23,  0, 17 },
-    {   24,  0, 17 }, {  -24,  0, 17 }, {   25,  0, 17 }, {  -25,  0, 17 },
-    {   26,  0, 17 }, {  -26,  0, 17 }, {   27,  0, 17 }, {  -27,  0, 17 },
-    {   28,  0, 17 }, {  -28,  0, 17 }, {   29,  0, 17 }, {  -29,  0, 17 },
-    {   30,  0, 17 }, {  -30,  0, 17 }, {   31,  0, 17 }, {  -31,  0, 17 },
-    RPT_16  (  15,  0, 13 ), RPT_16  ( -15,  0, 13 ),
-    RPT_16  (   9,  1, 13 ), RPT_16  (  -9,  1, 13 ),
-    RPT_16  (  10,  1, 13 ), RPT_16  ( -10,  1, 13 ),
-    RPT_16  (   5,  2, 13 ), RPT_16  (  -5,  2, 13 ),
-    RPT_16  (   5,  3, 13 ), RPT_16  (  -5,  3, 13 ),
-    RPT_16  (   4,  4, 13 ), RPT_16  (  -4,  4, 13 ),
-    RPT_16  (   4,  5, 13 ), RPT_16  (  -4,  5, 13 ),
-    RPT_16  (   3,  6, 13 ), RPT_16  (  -3,  6, 13 ),
-    RPT_16  (   3,  7, 13 ), RPT_16  (  -3,  7, 13 ),
-    RPT_16  (   1, 16, 13 ), RPT_16  (  -1, 16, 13 ),
-    RPT_16  (   1, 17, 13 ), RPT_16  (  -1, 17, 13 ),
-};
+static const uint16_t hqx_ac_nb_elems[] = { 815, 907, 512, 354, 257, 194 };
 
-static const HQXLUT ac128_lut[] = {
-    RPT_256 (   1,  0,  3 ), RPT_256 (  -1,  0,  3 ),
-    RPT_512 (   0, 64,  2 ), RPT_128 (   1,  1,  4 ),
-    RPT_128 (  -1,  1,  4 ), RPT_64  (   2,  0,  5 ),
-    RPT_64  (  -2,  0,  5 ), RPT_32  (   3,  0,  6 ),
-    RPT_32  (  -3,  0,  6 ), RPT_32  (   2,  1,  6 ),
-    RPT_32  (  -2,  1,  6 ), RPT_32  (   1,  2,  6 ),
-    RPT_32  (  -1,  2,  6 ), RPT_32  (   1,  3,  6 ),
-    RPT_32  (  -1,  3,  6 ), RPT_32  (   1,  4,  6 ),
-    RPT_32  (  -1,  4,  6 ), RPT_16  (   4,  0,  7 ),
-    RPT_16  (  -4,  0,  7 ), RPT_16  (   1,  5,  7 ),
-    RPT_16  (  -1,  5,  7 ), RPT_16  (   1,  6,  7 ),
-    RPT_16  (  -1,  6,  7 ), RPT_16  (   1,  7,  7 ),
-    RPT_16  (  -1,  7,  7 ), RPT_8   (   5,  0,  8 ),
-    RPT_8   (  -5,  0,  8 ), RPT_8   (   3,  1,  8 ),
-    RPT_8   (  -3,  1,  8 ), RPT_8   (   2,  2,  8 ),
-    RPT_8   (  -2,  2,  8 ), RPT_8   (   2,  3,  8 ),
-    RPT_8   (  -2,  3,  8 ), RPT_8   (   1,  8,  8 ),
-    RPT_8   (  -1,  8,  8 ), RPT_8   (   1,  9,  8 ),
-    RPT_8   (  -1,  9,  8 ), RPT_4   (   6,  0,  9 ),
-    RPT_4   (  -6,  0,  9 ), RPT_4   (   4,  1,  9 ),
-    RPT_4   (  -4,  1,  9 ), RPT_4   (   2,  4,  9 ),
-    RPT_4   (  -2,  4,  9 ), RPT_4   (   2,  5,  9 ),
-    RPT_4   (  -2,  5,  9 ), RPT_4   (   1, 10,  9 ),
-    RPT_4   (  -1, 10,  9 ), RPT_2   (   7,  0, 10 ),
-    RPT_2   (  -7,  0, 10 ), RPT_2   (   5,  1, 10 ),
-    RPT_2   (  -5,  1, 10 ), RPT_2   (   3,  2, 10 ),
-    RPT_2   (  -3,  2, 10 ), RPT_2   (   3,  3, 10 ),
-    RPT_2   (  -3,  3, 10 ), RPT_2   (   2,  6, 10 ),
-    RPT_2   (  -2,  6, 10 ), { 2048,  0, -1 }, { 2112,  0, -1 },
-    { 2176,  0, -1 }, { 2240,  0, -1 }, {    6,  1, 11 }, {   -6,  1, 11 },
-    {    7,  1, 11 }, {   -7,  1, 11 }, {    3,  4, 11 }, {   -3,  4, 11 },
-    {    3,  5, 11 }, {   -3,  5, 11 }, {    2,  7, 11 }, {   -2,  7, 11 },
-    {    2,  8, 11 }, {   -2,  8, 11 }, {    2,  9, 11 }, {   -2,  9, 11 },
-    {    1, 11, 11 }, {   -1, 11, 11 }, {    1, 12, 11 }, {   -1, 12, 11 },
-    {    1, 13, 11 }, {   -1, 13, 11 }, {    0,  0, 11 }, { 2304,  0, -1 },
-    { 2368,  0, -1 }, { 2432,  0, -1 }, { 2496,  0, -1 }, { 2560,  0, -1 },
-    { 2624,  0, -1 }, { 2688,  0, -1 }, { 2752,  0, -1 }, { 2816,  0, -1 },
-    { 2880,  0, -1 }, { 2944,  0, -1 }, RPT_4   (   0,  0, 15 ),
-    RPT_4   (   0,  1, 15 ), RPT_4   (   0,  2, 15 ),
-    RPT_4   (   0,  3, 15 ), RPT_4   (   0,  4, 15 ),
-    RPT_4   (   0,  5, 15 ), RPT_4   (   0,  6, 15 ),
-    RPT_4   (   0,  7, 15 ), RPT_4   (   0,  8, 15 ),
-    RPT_4   (   0,  9, 15 ), RPT_4   (   0, 10, 15 ),
-    RPT_4   (   0, 11, 15 ), RPT_4   (   0, 12, 15 ),
-    RPT_4   (   0, 13, 15 ), RPT_4   (   0, 14, 15 ),
-    RPT_4   (   0, 15, 15 ), RPT_4   (   0, 16, 15 ),
-    RPT_4   (   0, 17, 15 ), RPT_4   (   0, 18, 15 ),
-    RPT_4   (   0, 19, 15 ), RPT_4   (   0, 20, 15 ),
-    RPT_4   (   0, 21, 15 ), RPT_4   (   0, 22, 15 ),
-    RPT_4   (   0, 23, 15 ), RPT_4   (   0, 24, 15 ),
-    RPT_4   (   0, 25, 15 ), RPT_4   (   0, 26, 15 ),
-    RPT_4   (   0, 27, 15 ), RPT_4   (   0, 28, 15 ),
-    RPT_4   (   0, 29, 15 ), RPT_4   (   0, 30, 15 ),
-    RPT_4   (   0, 31, 15 ), RPT_4   (   0, 32, 15 ),
-    RPT_4   (   0, 33, 15 ), RPT_4   (   0, 34, 15 ),
-    RPT_4   (   0, 35, 15 ), RPT_4   (   0, 36, 15 ),
-    RPT_4   (   0, 37, 15 ), RPT_4   (   0, 38, 15 ),
-    RPT_4   (   0, 39, 15 ), RPT_4   (   0, 40, 15 ),
-    RPT_4   (   0, 41, 15 ), RPT_4   (   0, 42, 15 ),
-    RPT_4   (   0, 43, 15 ), RPT_4   (   0, 44, 15 ),
-    RPT_4   (   0, 45, 15 ), RPT_4   (   0, 46, 15 ),
-    RPT_4   (   0, 47, 15 ), RPT_4   (   0, 48, 15 ),
-    RPT_4   (   0, 49, 15 ), RPT_4   (   0, 50, 15 ),
-    RPT_4   (   0, 51, 15 ), RPT_4   (   0, 52, 15 ),
-    RPT_4   (   0, 53, 15 ), RPT_4   (   0, 54, 15 ),
-    RPT_4   (   0, 55, 15 ), RPT_4   (   0, 56, 15 ),
-    RPT_4   (   0, 57, 15 ), RPT_4   (   0, 58, 15 ),
-    RPT_4   (   0, 59, 15 ), RPT_4   (   0, 60, 15 ),
-    RPT_4   (   0, 61, 15 ), RPT_4   (   0, 62, 15 ),
-    RPT_4   (   0, 63, 15 ), RPT_32  (   8,  0, 12 ),
-    RPT_32  (  -8,  0, 12 ), RPT_32  (   9,  0, 12 ),
-    RPT_32  (  -9,  0, 12 ), RPT_32  (   8,  1, 12 ),
-    RPT_32  (  -8,  1, 12 ), RPT_32  (   4,  2, 12 ),
-    RPT_32  (  -4,  2, 12 ), RPT_32  (   4,  3, 12 ),
-    RPT_32  (  -4,  3, 12 ), RPT_32  (   3,  6, 12 ),
-    RPT_32  (  -3,  6, 12 ), RPT_32  (   1, 14, 12 ),
-    RPT_32  (  -1, 14, 12 ), RPT_32  (   1, 15, 12 ),
-    RPT_32  (  -1, 15, 12 ), RPT_32  (   1, 16, 12 ),
-    RPT_32  (  -1, 16, 12 ), RPT_32  (   0,  1, 12 ),
-    RPT_32  (   0,  2, 12 ), RPT_32  (   0,  3, 12 ),
-    RPT_2   (   0,  0, 16 ), {    1,  0, 17 }, {   -1,  0, 17 },
-    {    2,  0, 17 }, {   -2,  0, 17 }, {    3,  0, 17 }, {   -3,  0, 17 },
-    {    4,  0, 17 }, {   -4,  0, 17 }, {    5,  0, 17 }, {   -5,  0, 17 },
-    {    6,  0, 17 }, {   -6,  0, 17 }, {    7,  0, 17 }, {   -7,  0, 17 },
-    {    8,  0, 17 }, {   -8,  0, 17 }, {    9,  0, 17 }, {   -9,  0, 17 },
-    {   10,  0, 17 }, {  -10,  0, 17 }, {   11,  0, 17 }, {  -11,  0, 17 },
-    {   12,  0, 17 }, {  -12,  0, 17 }, {   13,  0, 17 }, {  -13,  0, 17 },
-    {   14,  0, 17 }, {  -14,  0, 17 }, {   15,  0, 17 }, {  -15,  0, 17 },
-};
-
-const HQXAC ff_hqx_ac[NUM_HQX_AC] = {
-    { 10, 5, ac0_lut   },
-    { 11, 6, ac8_lut   },
-    { 11, 6, ac16_lut  },
-    { 11, 6, ac32_lut  },
-    { 12, 5, ac64_lut  },
-    { 11, 6, ac128_lut },
-};
+static RL_VLC_ELEM hqx_ac_rl_vlc[15630];
 
 #define INIT_DC_TABLE(idx, name)                                              \
     do {                                                                      \
@@ -2148,8 +1515,47 @@ const HQXAC ff_hqx_ac[NUM_HQX_AC] = {
             return ret;                                                       \
     } while (0)
 
+static av_cold void hqx_init_static(void)
+{
+    VLCInitState state = VLC_INIT_STATE(hqx_ac_rl_vlc);
+    const uint8_t *lens = hqx_ac_lens;
+    const int16_t *run_level = hqx_ac_run_level;
+
+    for (int i = 0; i < NUM_HQX_AC; ++i) {
+        RL_VLC_ELEM *lut = state.table;
+        unsigned nb_codes = state.size;
+
+        ff_hqx_ac[i].lut =
+            ff_vlc_init_tables_from_lengths(&state, ff_hqx_ac[i].bits,
+                                            hqx_ac_nb_elems[i], lens, 1,
+                                            run_level, 2, 2, 0, 0);
+
+        nb_codes -= state.size;
+
+        for (unsigned j = 0; j < nb_codes; ++j) {
+            // lut[j] is in VLC (not RL_VLC) state
+            int sym = lut[j].sym;
+            int len = lut[j].len;
+            int level;
+
+            if (len < 0) {
+                level = sym;
+            } else {
+                level      = sym >> 7;
+                lut[j].run = sym & 0x7f;
+            }
+            // lut[j] is now in RL_VLC state
+            lut[j].len8  = len;
+            lut[j].level = level;
+        }
+        lens      += hqx_ac_nb_elems[i];
+        run_level += hqx_ac_nb_elems[i];
+    }
+}
+
 av_cold int ff_hqx_init_vlcs(HQXContext *ctx)
 {
+    static AVOnce init_static_once = AV_ONCE_INIT;
     int ret = vlc_init(&ctx->cbp_vlc, HQX_CBP_VLC_BITS, FF_ARRAY_ELEMS(cbp_vlc_lens),
                        cbp_vlc_lens, 1, 1, cbp_vlc_bits, 1, 1, 0);
     if (ret < 0)
@@ -2159,5 +1565,7 @@ av_cold int ff_hqx_init_vlcs(HQXContext *ctx)
     INIT_DC_TABLE(1, dc10);
     INIT_DC_TABLE(2, dc11);
 
+    ff_thread_once(&init_static_once, hqx_init_static);
+
     return 0;
 }
-- 
2.45.2


[-- Attachment #6: 0005-avcodec-hqxvlc-Include-implicit-1-run-in-RL-VLC-tabl.patch --]
[-- Type: text/x-patch, Size: 1758 bytes --]

From 41e9758640bc97d0b2078cd61b8a64ee59055cb6 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu, 13 Mar 2025 20:04:16 +0100
Subject: [PATCH 05/17] avcodec/hqxvlc: Include implicit +1 run in RL VLC
 tables

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/hqx.c    | 8 ++++----
 libavcodec/hqxvlc.c | 3 ++-
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/libavcodec/hqx.c b/libavcodec/hqx.c
index b31c35bbcc..32acca79ac 100644
--- a/libavcodec/hqx.c
+++ b/libavcodec/hqx.c
@@ -115,7 +115,7 @@ static int decode_block(GetBitContext *gb, VLC *vlc,
 {
     int q, dc;
     int ac_idx;
-    int run, lev, pos = 1;
+    int run, lev, pos = 0;
 
     memset(block, 0, 64 * sizeof(*block));
     dc = get_vlc2(gb, vlc->table, HQX_DC_VLC_BITS, 2);
@@ -140,10 +140,10 @@ static int decode_block(GetBitContext *gb, VLC *vlc,
     do {
         hqx_get_ac(gb, &ff_hqx_ac[ac_idx], &run, &lev);
         pos += run;
-        if (pos >= 64)
+        if (pos > 63)
             break;
-        block[ff_zigzag_direct[pos++]] = lev * q;
-    } while (pos < 64);
+        block[ff_zigzag_direct[pos]] = lev * q;
+    } while (pos < 63);
 
     return 0;
 }
diff --git a/libavcodec/hqxvlc.c b/libavcodec/hqxvlc.c
index 94ab21724c..63ca5cc33c 100644
--- a/libavcodec/hqxvlc.c
+++ b/libavcodec/hqxvlc.c
@@ -726,7 +726,8 @@ HQXAC ff_hqx_ac[NUM_HQX_AC] = {
 };
 
 // level is in -255..255 range, run 0..64, so it fits into 16 bits.
-#define E(level, run) ((level * 128) | run)
+// We offset run by 1 in order to include the implicit run of 1.
+#define E(level, run) ((level * 128) | (run + 1))
 
 static const int16_t hqx_ac_run_level[] = {
     // AC table Q0 - 815 elements
-- 
2.45.2


[-- Attachment #7: 0006-avcodec-hqx-Include-hqxvlc-directly.patch --]
[-- Type: text/x-patch, Size: 8582 bytes --]

From b22c57983d74453c0ea94d8214f8c4eb4273374b Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu, 13 Mar 2025 20:42:30 +0100
Subject: [PATCH 06/17] avcodec/hqx: Include hqxvlc directly

This avoids having to expose HQXContext in a header
and allows to make several symbols static.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/Makefile               |  2 +-
 libavcodec/hqx.c                  | 49 ++++++++++++++++--
 libavcodec/hqx.h                  | 82 -------------------------------
 libavcodec/{hqxvlc.c => hqxvlc.h} | 54 +++++++++++---------
 4 files changed, 79 insertions(+), 108 deletions(-)
 delete mode 100644 libavcodec/hqx.h
 rename libavcodec/{hqxvlc.c => hqxvlc.h} (99%)

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 3c7043a617..584938ac85 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -467,7 +467,7 @@ OBJS-$(CONFIG_HEVC_V4L2M2M_ENCODER)    += v4l2_m2m_enc.o
 OBJS-$(CONFIG_HEVC_VIDEOTOOLBOX_ENCODER) += videotoolboxenc.o
 OBJS-$(CONFIG_HNM4_VIDEO_DECODER)      += hnm4video.o
 OBJS-$(CONFIG_HQ_HQA_DECODER)          += hq_hqa.o hq_hqadsp.o canopus.o
-OBJS-$(CONFIG_HQX_DECODER)             += hqx.o hqxvlc.o hqxdsp.o canopus.o
+OBJS-$(CONFIG_HQX_DECODER)             += hqx.o hqxdsp.o canopus.o
 OBJS-$(CONFIG_HUFFYUV_DECODER)         += huffyuv.o huffyuvdec.o
 OBJS-$(CONFIG_HUFFYUV_ENCODER)         += huffyuv.o huffyuvenc.o
 OBJS-$(CONFIG_HYMT_DECODER)            += huffyuv.o huffyuvdec.o
diff --git a/libavcodec/hqx.c b/libavcodec/hqx.c
index 32acca79ac..7ff689407d 100644
--- a/libavcodec/hqx.c
+++ b/libavcodec/hqx.c
@@ -20,17 +20,21 @@
 
 #include <inttypes.h>
 
+#include "libavutil/frame.h"
 #include "libavutil/imgutils.h"
+#include "libavutil/mem_internal.h"
 #include "libavutil/intreadwrite.h"
+#include "libavutil/thread.h"
 
 #include "avcodec.h"
 #include "canopus.h"
 #include "codec_internal.h"
 #include "get_bits.h"
 #include "thread.h"
+#include "vlc.h"
 
-#include "hqx.h"
 #include "hqxdsp.h"
+#include "hqxvlc.h"
 
 /* HQX has four modes - 422, 444, 422alpha and 444alpha - all 12-bit */
 enum HQXFormat {
@@ -40,6 +44,34 @@ enum HQXFormat {
     HQX_444A,
 };
 
+struct HQXContext;
+
+typedef int (*mb_decode_func)(struct HQXContext *ctx,
+                              int slice_no, int x, int y);
+
+typedef struct HQXSlice {
+    GetBitContext gb;
+    DECLARE_ALIGNED(16, int16_t, block)[16][64];
+} HQXSlice;
+
+typedef struct HQXContext {
+    HQXDSPContext hqxdsp;
+    HQXSlice slice[16];
+
+    AVFrame *pic;
+    mb_decode_func decode_func;
+
+    int format, dcb, width, height;
+    int interlaced;
+
+    const uint8_t *src;
+    unsigned int data_size;
+    uint32_t slice_off[17];
+
+    VLC cbp_vlc;
+    VLC dc_vlc[3];
+} HQXContext;
+
 #define HQX_HEADER_SIZE 59
 
 /* macroblock selects a group of 4 possible quants and
@@ -138,7 +170,7 @@ static int decode_block(GetBitContext *gb, VLC *vlc,
         ac_idx = HQX_AC_Q0;
 
     do {
-        hqx_get_ac(gb, &ff_hqx_ac[ac_idx], &run, &lev);
+        hqx_get_ac(gb, &hqx_ac[ac_idx], &run, &lev);
         pos += run;
         if (pos > 63)
             break;
@@ -521,11 +553,22 @@ static av_cold int hqx_decode_close(AVCodecContext *avctx)
 
 static av_cold int hqx_decode_init(AVCodecContext *avctx)
 {
+    static AVOnce init_static_once = AV_ONCE_INIT;
     HQXContext *ctx = avctx->priv_data;
+    int ret = vlc_init(&ctx->cbp_vlc, HQX_CBP_VLC_BITS, FF_ARRAY_ELEMS(cbp_vlc_lens),
+                       cbp_vlc_lens, 1, 1, cbp_vlc_bits, 1, 1, 0);
+    if (ret < 0)
+        return ret;
+
+    INIT_DC_TABLE(0, dc9);
+    INIT_DC_TABLE(1, dc10);
+    INIT_DC_TABLE(2, dc11);
 
     ff_hqxdsp_init(&ctx->hqxdsp);
 
-    return ff_hqx_init_vlcs(ctx);
+    ff_thread_once(&init_static_once, hqx_init_static);
+
+    return 0;
 }
 
 const FFCodec ff_hqx_decoder = {
diff --git a/libavcodec/hqx.h b/libavcodec/hqx.h
deleted file mode 100644
index 4f313a1dc3..0000000000
--- a/libavcodec/hqx.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Canopus HQX decoder
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef AVCODEC_HQX_H
-#define AVCODEC_HQX_H
-
-#include <stdint.h>
-
-#include "libavutil/frame.h"
-#include "libavutil/mem_internal.h"
-
-#include "get_bits.h"
-#include "hqxdsp.h"
-
-enum HQXACMode {
-    HQX_AC_Q0 = 0,
-    HQX_AC_Q8,
-    HQX_AC_Q16,
-    HQX_AC_Q32,
-    HQX_AC_Q64,
-    HQX_AC_Q128,
-    NUM_HQX_AC
-};
-
-typedef struct HQXAC {
-    int bits;
-    const RL_VLC_ELEM *lut;
-} HQXAC;
-
-struct HQXContext;
-
-typedef int (*mb_decode_func)(struct HQXContext *ctx,
-                              int slice_no, int x, int y);
-
-typedef struct HQXSlice {
-    GetBitContext gb;
-    DECLARE_ALIGNED(16, int16_t, block)[16][64];
-} HQXSlice;
-
-typedef struct HQXContext {
-    HQXDSPContext hqxdsp;
-    HQXSlice slice[16];
-
-    AVFrame *pic;
-    mb_decode_func decode_func;
-
-    int format, dcb, width, height;
-    int interlaced;
-
-    const uint8_t *src;
-    unsigned int data_size;
-    uint32_t slice_off[17];
-
-    VLC cbp_vlc;
-    VLC dc_vlc[3];
-} HQXContext;
-
-#define HQX_CBP_VLC_BITS 5
-#define HQX_DC_VLC_BITS 9
-
-extern HQXAC ff_hqx_ac[NUM_HQX_AC];
-
-int ff_hqx_init_vlcs(HQXContext *ctx);
-
-#endif /* AVCODEC_HQX_H */
diff --git a/libavcodec/hqxvlc.c b/libavcodec/hqxvlc.h
similarity index 99%
rename from libavcodec/hqxvlc.c
rename to libavcodec/hqxvlc.h
index 63ca5cc33c..6ac2bab01e 100644
--- a/libavcodec/hqxvlc.c
+++ b/libavcodec/hqxvlc.h
@@ -18,8 +18,33 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "hqx.h"
-#include "libavutil/thread.h"
+#ifndef AVCODEC_HQXVLC_H
+#define AVCODEC_HQXVLC_H
+
+#include <stdint.h>
+
+#include "vlc.h"
+
+#include "libavutil/attributes.h"
+#include "libavutil/macros.h"
+
+#define HQX_CBP_VLC_BITS 5
+#define HQX_DC_VLC_BITS 9
+
+enum HQXACMode {
+    HQX_AC_Q0 = 0,
+    HQX_AC_Q8,
+    HQX_AC_Q16,
+    HQX_AC_Q32,
+    HQX_AC_Q64,
+    HQX_AC_Q128,
+    NUM_HQX_AC
+};
+
+typedef struct HQXAC {
+    int bits;
+    const RL_VLC_ELEM *lut;
+} HQXAC;
 
 static const uint8_t cbp_vlc_bits[16] = {
     0x04, 0x1C, 0x1D, 0x09, 0x1E, 0x0B, 0x1B, 0x08,
@@ -721,7 +746,7 @@ static const uint8_t dc11_vlc_lens[2048] = {
 };
 
 
-HQXAC ff_hqx_ac[NUM_HQX_AC] = {
+static HQXAC hqx_ac[NUM_HQX_AC] = {
     { 10 }, { 11 }, { 11 }, { 11 }, { 12 }, { 11 },
 };
 
@@ -1516,7 +1541,7 @@ static RL_VLC_ELEM hqx_ac_rl_vlc[15630];
             return ret;                                                       \
     } while (0)
 
-static av_cold void hqx_init_static(void)
+static av_cold av_unused void hqx_init_static(void)
 {
     VLCInitState state = VLC_INIT_STATE(hqx_ac_rl_vlc);
     const uint8_t *lens = hqx_ac_lens;
@@ -1526,8 +1551,8 @@ static av_cold void hqx_init_static(void)
         RL_VLC_ELEM *lut = state.table;
         unsigned nb_codes = state.size;
 
-        ff_hqx_ac[i].lut =
-            ff_vlc_init_tables_from_lengths(&state, ff_hqx_ac[i].bits,
+        hqx_ac[i].lut =
+            ff_vlc_init_tables_from_lengths(&state, hqx_ac[i].bits,
                                             hqx_ac_nb_elems[i], lens, 1,
                                             run_level, 2, 2, 0, 0);
 
@@ -1554,19 +1579,4 @@ static av_cold void hqx_init_static(void)
     }
 }
 
-av_cold int ff_hqx_init_vlcs(HQXContext *ctx)
-{
-    static AVOnce init_static_once = AV_ONCE_INIT;
-    int ret = vlc_init(&ctx->cbp_vlc, HQX_CBP_VLC_BITS, FF_ARRAY_ELEMS(cbp_vlc_lens),
-                       cbp_vlc_lens, 1, 1, cbp_vlc_bits, 1, 1, 0);
-    if (ret < 0)
-        return ret;
-
-    INIT_DC_TABLE(0, dc9);
-    INIT_DC_TABLE(1, dc10);
-    INIT_DC_TABLE(2, dc11);
-
-    ff_thread_once(&init_static_once, hqx_init_static);
-
-    return 0;
-}
+#endif /* AVCODEC_HQXVLC_H*/
-- 
2.45.2


[-- Attachment #8: 0007-avcodec-hqxvlc-Make-cbp_vlc-static.patch --]
[-- Type: text/x-patch, Size: 3695 bytes --]

From e5280f836450aa63caf33fea913bf7fcf5cba404 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu, 13 Mar 2025 21:04:39 +0100
Subject: [PATCH 07/17] avcodec/hqxvlc: Make cbp_vlc static

This is trivial as well as beneficial because frame threads
now use the same table, saving cache/memory.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/hqx.c    | 15 +++++----------
 libavcodec/hqxvlc.h |  7 +++++--
 2 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/libavcodec/hqx.c b/libavcodec/hqx.c
index 7ff689407d..e73a023c29 100644
--- a/libavcodec/hqx.c
+++ b/libavcodec/hqx.c
@@ -68,7 +68,6 @@ typedef struct HQXContext {
     unsigned int data_size;
     uint32_t slice_off[17];
 
-    VLC cbp_vlc;
     VLC dc_vlc[3];
 } HQXContext;
 
@@ -224,12 +223,12 @@ static int hqx_decode_422a(HQXContext *ctx, int slice_no, int x, int y)
     int i, ret;
     int cbp;
 
-    cbp = get_vlc2(gb, ctx->cbp_vlc.table, HQX_CBP_VLC_BITS, 1);
-
     for (i = 0; i < 12; i++)
         memset(slice->block[i], 0, sizeof(**slice->block) * 64);
     for (i = 0; i < 12; i++)
         slice->block[i][0] = -0x800;
+
+    cbp = get_vlc2(gb, cbp_vlc, HQX_CBP_VLC_BITS, 1);
     if (cbp) {
         if (ctx->interlaced)
             flag = get_bits1(gb);
@@ -310,12 +309,12 @@ static int hqx_decode_444a(HQXContext *ctx, int slice_no, int x, int y)
     int i, ret;
     int cbp;
 
-    cbp = get_vlc2(gb, ctx->cbp_vlc.table, HQX_CBP_VLC_BITS, 1);
-
     for (i = 0; i < 16; i++)
         memset(slice->block[i], 0, sizeof(**slice->block) * 64);
     for (i = 0; i < 16; i++)
         slice->block[i][0] = -0x800;
+
+    cbp = get_vlc2(gb, cbp_vlc, HQX_CBP_VLC_BITS, 1);
     if (cbp) {
         if (ctx->interlaced)
             flag = get_bits1(gb);
@@ -543,7 +542,6 @@ static av_cold int hqx_decode_close(AVCodecContext *avctx)
     int i;
     HQXContext *ctx = avctx->priv_data;
 
-    ff_vlc_free(&ctx->cbp_vlc);
     for (i = 0; i < 3; i++) {
         ff_vlc_free(&ctx->dc_vlc[i]);
     }
@@ -555,10 +553,7 @@ static av_cold int hqx_decode_init(AVCodecContext *avctx)
 {
     static AVOnce init_static_once = AV_ONCE_INIT;
     HQXContext *ctx = avctx->priv_data;
-    int ret = vlc_init(&ctx->cbp_vlc, HQX_CBP_VLC_BITS, FF_ARRAY_ELEMS(cbp_vlc_lens),
-                       cbp_vlc_lens, 1, 1, cbp_vlc_bits, 1, 1, 0);
-    if (ret < 0)
-        return ret;
+    int ret;
 
     INIT_DC_TABLE(0, dc9);
     INIT_DC_TABLE(1, dc10);
diff --git a/libavcodec/hqxvlc.h b/libavcodec/hqxvlc.h
index 6ac2bab01e..aa7fbcdc59 100644
--- a/libavcodec/hqxvlc.h
+++ b/libavcodec/hqxvlc.h
@@ -1529,7 +1529,7 @@ static const uint8_t hqx_ac_lens[] = {
 
 static const uint16_t hqx_ac_nb_elems[] = { 815, 907, 512, 354, 257, 194 };
 
-static RL_VLC_ELEM hqx_ac_rl_vlc[15630];
+static VLCElem cbp_vlc[(1 << HQX_CBP_VLC_BITS) + 15630 /* RL_VLC_ELEMS for hqx_ac */];
 
 #define INIT_DC_TABLE(idx, name)                                              \
     do {                                                                      \
@@ -1543,10 +1543,13 @@ static RL_VLC_ELEM hqx_ac_rl_vlc[15630];
 
 static av_cold av_unused void hqx_init_static(void)
 {
-    VLCInitState state = VLC_INIT_STATE(hqx_ac_rl_vlc);
+    VLCInitState state = VLC_INIT_STATE(cbp_vlc);
     const uint8_t *lens = hqx_ac_lens;
     const int16_t *run_level = hqx_ac_run_level;
 
+    ff_vlc_init_tables(&state, HQX_CBP_VLC_BITS, FF_ARRAY_ELEMS(cbp_vlc_lens),
+                       cbp_vlc_lens, 1, 1, cbp_vlc_bits, 1, 1, 0);
+
     for (int i = 0; i < NUM_HQX_AC; ++i) {
         RL_VLC_ELEM *lut = state.table;
         unsigned nb_codes = state.size;
-- 
2.45.2


[-- Attachment #9: 0008-avcodec-hqx-Cache-pointer-to-used-dc-table.patch --]
[-- Type: text/x-patch, Size: 5832 bytes --]

From 1d2322ea36ae7480c8e3e2fce3d8f9969f0691e5 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu, 13 Mar 2025 22:17:03 +0100
Subject: [PATCH 08/17] avcodec/hqx: Cache pointer to used dc table

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/hqx.c    | 32 ++++++++++++++++----------------
 libavcodec/hqxvlc.h |  2 +-
 2 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/libavcodec/hqx.c b/libavcodec/hqx.c
index e73a023c29..aab28a2156 100644
--- a/libavcodec/hqx.c
+++ b/libavcodec/hqx.c
@@ -68,7 +68,9 @@ typedef struct HQXContext {
     unsigned int data_size;
     uint32_t slice_off[17];
 
-    VLC dc_vlc[3];
+    const VLCElem *dc_vlc;
+
+    VLC dc_vlcs[3];
 } HQXContext;
 
 #define HQX_HEADER_SIZE 59
@@ -140,7 +142,7 @@ static inline void hqx_get_ac(GetBitContext *gb, const HQXAC *ac,
     *lev  = level;
 }
 
-static int decode_block(GetBitContext *gb, VLC *vlc,
+static int decode_block(GetBitContext *gb, const VLCElem vlc[],
                         const int *quants, int dcb,
                         int16_t block[64], int *last_dc)
 {
@@ -149,7 +151,7 @@ static int decode_block(GetBitContext *gb, VLC *vlc,
     int run, lev, pos = 0;
 
     memset(block, 0, 64 * sizeof(*block));
-    dc = get_vlc2(gb, vlc->table, HQX_DC_VLC_BITS, 2);
+    dc = get_vlc2(gb, vlc, HQX_DC_VLC_BITS, 2);
     *last_dc += dc;
 
     block[0] = sign_extend(*last_dc << (12 - dcb), 12);
@@ -196,10 +198,9 @@ static int hqx_decode_422(HQXContext *ctx, int slice_no, int x, int y)
     quants = hqx_quants[get_bits(gb, 4)];
 
     for (i = 0; i < 8; i++) {
-        int vlc_index = ctx->dcb - 9;
         if (i == 0 || i == 4 || i == 6)
             last_dc = 0;
-        ret = decode_block(gb, &ctx->dc_vlc[vlc_index], quants,
+        ret = decode_block(gb, ctx->dc_vlc, quants,
                            ctx->dcb, slice->block[i], &last_dc);
         if (ret < 0)
             return ret;
@@ -244,8 +245,7 @@ static int hqx_decode_422a(HQXContext *ctx, int slice_no, int x, int y)
             if (i == 0 || i == 4 || i == 8 || i == 10)
                 last_dc = 0;
             if (cbp & (1 << i)) {
-                int vlc_index = ctx->dcb - 9;
-                ret = decode_block(gb, &ctx->dc_vlc[vlc_index], quants,
+                ret = decode_block(gb, ctx->dc_vlc, quants,
                                    ctx->dcb, slice->block[i], &last_dc);
                 if (ret < 0)
                     return ret;
@@ -280,10 +280,9 @@ static int hqx_decode_444(HQXContext *ctx, int slice_no, int x, int y)
     quants = hqx_quants[get_bits(gb, 4)];
 
     for (i = 0; i < 12; i++) {
-        int vlc_index = ctx->dcb - 9;
         if (i == 0 || i == 4 || i == 8)
             last_dc = 0;
-        ret = decode_block(gb, &ctx->dc_vlc[vlc_index], quants,
+        ret = decode_block(gb, ctx->dc_vlc, quants,
                            ctx->dcb, slice->block[i], &last_dc);
         if (ret < 0)
             return ret;
@@ -327,8 +326,7 @@ static int hqx_decode_444a(HQXContext *ctx, int slice_no, int x, int y)
             if (i == 0 || i == 4 || i == 8 || i == 12)
                 last_dc = 0;
             if (cbp & (1 << i)) {
-                int vlc_index = ctx->dcb - 9;
-                ret = decode_block(gb, &ctx->dc_vlc[vlc_index], quants,
+                ret = decode_block(gb, ctx->dc_vlc, quants,
                                    ctx->dcb, slice->block[i], &last_dc);
                 if (ret < 0)
                     return ret;
@@ -434,7 +432,7 @@ static int hqx_decode_frame(AVCodecContext *avctx, AVFrame *frame,
     HQXContext *ctx = avctx->priv_data;
     const uint8_t *src = avpkt->data;
     uint32_t info_tag;
-    int data_start;
+    int data_start, dcb_code;
     int i, ret;
 
     if (avpkt->size < 4 + 4) {
@@ -473,16 +471,18 @@ static int hqx_decode_frame(AVCodecContext *avctx, AVFrame *frame,
     }
     ctx->interlaced = !(src[2] & 0x80);
     ctx->format     = src[2] & 7;
-    ctx->dcb        = (src[3] & 3) + 8;
+    dcb_code        = src[3] & 3;
     ctx->width      = AV_RB16(src + 4);
     ctx->height     = AV_RB16(src + 6);
     for (i = 0; i < 17; i++)
         ctx->slice_off[i] = AV_RB24(src + 8 + i * 3);
 
-    if (ctx->dcb == 8) {
-        av_log(avctx, AV_LOG_ERROR, "Invalid DC precision %d.\n", ctx->dcb);
+    if (dcb_code == 0) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid DC precision 8.\n");
         return AVERROR_INVALIDDATA;
     }
+    ctx->dc_vlc = ctx->dc_vlcs[dcb_code - 1].table;
+    ctx->dcb    = dcb_code + 8;
     ret = av_image_check_size(ctx->width, ctx->height, 0, avctx);
     if (ret < 0) {
         av_log(avctx, AV_LOG_ERROR, "Invalid stored dimensions %dx%d.\n",
@@ -543,7 +543,7 @@ static av_cold int hqx_decode_close(AVCodecContext *avctx)
     HQXContext *ctx = avctx->priv_data;
 
     for (i = 0; i < 3; i++) {
-        ff_vlc_free(&ctx->dc_vlc[i]);
+        ff_vlc_free(&ctx->dc_vlcs[i]);
     }
 
     return 0;
diff --git a/libavcodec/hqxvlc.h b/libavcodec/hqxvlc.h
index aa7fbcdc59..4bdc3cd191 100644
--- a/libavcodec/hqxvlc.h
+++ b/libavcodec/hqxvlc.h
@@ -1533,7 +1533,7 @@ static VLCElem cbp_vlc[(1 << HQX_CBP_VLC_BITS) + 15630 /* RL_VLC_ELEMS for hqx_a
 
 #define INIT_DC_TABLE(idx, name)                                              \
     do {                                                                      \
-        ret = vlc_init(&ctx->dc_vlc[idx], HQX_DC_VLC_BITS,                    \
+        ret = vlc_init(&ctx->dc_vlcs[idx], HQX_DC_VLC_BITS,                   \
                        FF_ARRAY_ELEMS(name ## _vlc_lens),                     \
                        name ## _vlc_lens, 1, 1,                               \
                        name ## _vlc_bits, 2, 2, 0);                           \
-- 
2.45.2


[-- Attachment #10: 0009-avcodec-hqxvlc-Make-dc9-dc10-VLC-tables-static.patch --]
[-- Type: text/x-patch, Size: 4209 bytes --]

From 77c85aaf2e80cd759cb146efb076b0bc16bb6435 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu, 13 Mar 2025 21:43:37 +0100
Subject: [PATCH 09/17] avcodec/hqxvlc: Make dc9, dc10 VLC tables static

It allows to share them between frame threads.
dc11 can unfortunately not be made static without increasing
LOCALBUF_ELEMS in vlc.c.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/hqx.c    | 17 +++++++----------
 libavcodec/hqxvlc.h | 18 +++++++++++-------
 2 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/libavcodec/hqx.c b/libavcodec/hqx.c
index aab28a2156..e5a727a609 100644
--- a/libavcodec/hqx.c
+++ b/libavcodec/hqx.c
@@ -70,7 +70,7 @@ typedef struct HQXContext {
 
     const VLCElem *dc_vlc;
 
-    VLC dc_vlcs[3];
+    VLC dc11_vlc;
 } HQXContext;
 
 #define HQX_HEADER_SIZE 59
@@ -481,7 +481,7 @@ static int hqx_decode_frame(AVCodecContext *avctx, AVFrame *frame,
         av_log(avctx, AV_LOG_ERROR, "Invalid DC precision 8.\n");
         return AVERROR_INVALIDDATA;
     }
-    ctx->dc_vlc = ctx->dc_vlcs[dcb_code - 1].table;
+    ctx->dc_vlc = dcb_code == 3 ? ctx->dc11_vlc.table : dc_vlc[dcb_code - 1];
     ctx->dcb    = dcb_code + 8;
     ret = av_image_check_size(ctx->width, ctx->height, 0, avctx);
     if (ret < 0) {
@@ -539,12 +539,9 @@ static int hqx_decode_frame(AVCodecContext *avctx, AVFrame *frame,
 
 static av_cold int hqx_decode_close(AVCodecContext *avctx)
 {
-    int i;
     HQXContext *ctx = avctx->priv_data;
 
-    for (i = 0; i < 3; i++) {
-        ff_vlc_free(&ctx->dc_vlcs[i]);
-    }
+    ff_vlc_free(&ctx->dc11_vlc);
 
     return 0;
 }
@@ -553,11 +550,11 @@ static av_cold int hqx_decode_init(AVCodecContext *avctx)
 {
     static AVOnce init_static_once = AV_ONCE_INIT;
     HQXContext *ctx = avctx->priv_data;
-    int ret;
+    int ret = vlc_init(&ctx->dc11_vlc, HQX_DC_VLC_BITS, FF_ARRAY_ELEMS(dc11_vlc_lens),
+                       dc11_vlc_lens, 1, 1, dc11_vlc_bits, 2, 2, 0);
 
-    INIT_DC_TABLE(0, dc9);
-    INIT_DC_TABLE(1, dc10);
-    INIT_DC_TABLE(2, dc11);
+    if (ret < 0)
+        return ret;
 
     ff_hqxdsp_init(&ctx->hqxdsp);
 
diff --git a/libavcodec/hqxvlc.h b/libavcodec/hqxvlc.h
index 4bdc3cd191..28c55b20e0 100644
--- a/libavcodec/hqxvlc.h
+++ b/libavcodec/hqxvlc.h
@@ -1529,16 +1529,17 @@ static const uint8_t hqx_ac_lens[] = {
 
 static const uint16_t hqx_ac_nb_elems[] = { 815, 907, 512, 354, 257, 194 };
 
-static VLCElem cbp_vlc[(1 << HQX_CBP_VLC_BITS) + 15630 /* RL_VLC_ELEMS for hqx_ac */];
+static VLCElem cbp_vlc[(1 << HQX_CBP_VLC_BITS) + 896 /* dc9 */ + 1344 /* dc10 */
+                       + 15630 /* RL_VLC_ELEMS for hqx_ac */];
+
+static const VLCElem *dc_vlc[2];
 
 #define INIT_DC_TABLE(idx, name)                                              \
     do {                                                                      \
-        ret = vlc_init(&ctx->dc_vlcs[idx], HQX_DC_VLC_BITS,                   \
-                       FF_ARRAY_ELEMS(name ## _vlc_lens),                     \
-                       name ## _vlc_lens, 1, 1,                               \
-                       name ## _vlc_bits, 2, 2, 0);                           \
-        if (ret < 0)                                                          \
-            return ret;                                                       \
+         dc_vlc[idx] = ff_vlc_init_tables(&state, HQX_DC_VLC_BITS,            \
+                                          FF_ARRAY_ELEMS(name ## _vlc_lens),  \
+                                          name ## _vlc_lens, 1, 1,            \
+                                          name ## _vlc_bits, 2, 2, 0);        \
     } while (0)
 
 static av_cold av_unused void hqx_init_static(void)
@@ -1550,6 +1551,9 @@ static av_cold av_unused void hqx_init_static(void)
     ff_vlc_init_tables(&state, HQX_CBP_VLC_BITS, FF_ARRAY_ELEMS(cbp_vlc_lens),
                        cbp_vlc_lens, 1, 1, cbp_vlc_bits, 1, 1, 0);
 
+    INIT_DC_TABLE(0, dc9);
+    INIT_DC_TABLE(1, dc10);
+
     for (int i = 0; i < NUM_HQX_AC; ++i) {
         RL_VLC_ELEM *lut = state.table;
         unsigned nb_codes = state.size;
-- 
2.45.2


[-- Attachment #11: 0010-avcodec-hqx-Combine-memsets.patch --]
[-- Type: text/x-patch, Size: 1211 bytes --]

From 64a1a74f0a6dd625e6ac05951f6615269a097559 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu, 13 Mar 2025 21:48:17 +0100
Subject: [PATCH 10/17] avcodec/hqx: Combine memsets

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/hqx.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/libavcodec/hqx.c b/libavcodec/hqx.c
index e5a727a609..c6f0989ee5 100644
--- a/libavcodec/hqx.c
+++ b/libavcodec/hqx.c
@@ -224,8 +224,7 @@ static int hqx_decode_422a(HQXContext *ctx, int slice_no, int x, int y)
     int i, ret;
     int cbp;
 
-    for (i = 0; i < 12; i++)
-        memset(slice->block[i], 0, sizeof(**slice->block) * 64);
+    memset(slice->block, 0, sizeof(*slice->block) * 12);
     for (i = 0; i < 12; i++)
         slice->block[i][0] = -0x800;
 
@@ -308,8 +307,7 @@ static int hqx_decode_444a(HQXContext *ctx, int slice_no, int x, int y)
     int i, ret;
     int cbp;
 
-    for (i = 0; i < 16; i++)
-        memset(slice->block[i], 0, sizeof(**slice->block) * 64);
+    memset(slice->block, 0, sizeof(*slice->block) * 16);
     for (i = 0; i < 16; i++)
         slice->block[i][0] = -0x800;
 
-- 
2.45.2


[-- Attachment #12: 0011-avcodec-hqx-Don-t-zero-in-small-chunks-don-t-zero-tw.patch --]
[-- Type: text/x-patch, Size: 1734 bytes --]

From b28200cd38a0a875d34b9d9359bb2d8e36f7b254 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu, 13 Mar 2025 21:56:23 +0100
Subject: [PATCH 11/17] avcodec/hqx: Don't zero in small chunks, don't zero
 twice

Up until now, decode_block() zeroed every block (of 128 bytes)
before decoding a block; yet this is suboptimal for all modes,
because all modes need to reset all the blocks they use anyway
and so it should be done in one go for all blocks.

For the alpha modes (where blocks need not be coded) all blocks
are zeroed initially anyway, because decode_block() might not
be doing it, so zeroing there again for the coded blocks is
a waste.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/hqx.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/libavcodec/hqx.c b/libavcodec/hqx.c
index c6f0989ee5..c28c274b24 100644
--- a/libavcodec/hqx.c
+++ b/libavcodec/hqx.c
@@ -150,7 +150,6 @@ static int decode_block(GetBitContext *gb, const VLCElem vlc[],
     int ac_idx;
     int run, lev, pos = 0;
 
-    memset(block, 0, 64 * sizeof(*block));
     dc = get_vlc2(gb, vlc, HQX_DC_VLC_BITS, 2);
     *last_dc += dc;
 
@@ -190,6 +189,8 @@ static int hqx_decode_422(HQXContext *ctx, int slice_no, int x, int y)
     int last_dc;
     int i, ret;
 
+    memset(slice->block, 0, sizeof(*slice->block) * 8);
+
     if (ctx->interlaced)
         flag = get_bits1(gb);
     else
@@ -271,6 +272,8 @@ static int hqx_decode_444(HQXContext *ctx, int slice_no, int x, int y)
     int last_dc;
     int i, ret;
 
+    memset(slice->block, 0, sizeof(*slice->block) * 12);
+
     if (ctx->interlaced)
         flag = get_bits1(gb);
     else
-- 
2.45.2


[-- Attachment #13: 0012-avcodec-hqx-Combine-checks.patch --]
[-- Type: text/x-patch, Size: 1303 bytes --]

From f681c443ea634e0bbadf502db714f3718cb27280 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu, 13 Mar 2025 22:23:50 +0100
Subject: [PATCH 12/17] avcodec/hqx: Combine checks

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/hqx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/hqx.c b/libavcodec/hqx.c
index c28c274b24..54a9870e11 100644
--- a/libavcodec/hqx.c
+++ b/libavcodec/hqx.c
@@ -282,7 +282,7 @@ static int hqx_decode_444(HQXContext *ctx, int slice_no, int x, int y)
     quants = hqx_quants[get_bits(gb, 4)];
 
     for (i = 0; i < 12; i++) {
-        if (i == 0 || i == 4 || i == 8)
+        if (!(i & 3))
             last_dc = 0;
         ret = decode_block(gb, ctx->dc_vlc, quants,
                            ctx->dcb, slice->block[i], &last_dc);
@@ -324,7 +324,7 @@ static int hqx_decode_444a(HQXContext *ctx, int slice_no, int x, int y)
         cbp |= cbp << 4; // alpha CBP
         cbp |= cbp << 8; // chroma CBP
         for (i = 0; i < 16; i++) {
-            if (i == 0 || i == 4 || i == 8 || i == 12)
+            if (!(i & 3))
                 last_dc = 0;
             if (cbp & (1 << i)) {
                 ret = decode_block(gb, ctx->dc_vlc, quants,
-- 
2.45.2


[-- Attachment #14: 0013-avcodec-hqx-Simplify-deriving-AC-table-index.patch --]
[-- Type: text/x-patch, Size: 5660 bytes --]

From b65df72dda7448fafdcbc756dab3d31916e2ff5b Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu, 13 Mar 2025 22:52:15 +0100
Subject: [PATCH 13/17] avcodec/hqx: Simplify deriving AC table index

It can be simply encoded in the quant coefficients itself
as they are so small.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/hqx.c | 61 ++++++++++++++++++++++++------------------------
 1 file changed, 30 insertions(+), 31 deletions(-)

diff --git a/libavcodec/hqx.c b/libavcodec/hqx.c
index 54a9870e11..2e9698ee6c 100644
--- a/libavcodec/hqx.c
+++ b/libavcodec/hqx.c
@@ -75,21 +75,27 @@ typedef struct HQXContext {
 
 #define HQX_HEADER_SIZE 59
 
+#define AC_IDX(q) ((q) >= 128 ? HQX_AC_Q128 : (q) >= 64 ? HQX_AC_Q64 : \
+                   (q) >=  32 ? HQX_AC_Q32  : (q) >= 16 ? HQX_AC_Q16 : \
+                   (q) >=   8 ? HQX_AC_Q8   : HQX_AC_Q0)
+
 /* macroblock selects a group of 4 possible quants and
  * a block can use any of those four quantisers
  * one column is powers of 2, the other one is powers of 2 * 3,
- * then there is the special one, powers of 2 * 5 */
-static const int hqx_quants[16][4] = {
-    {  0x1,   0x2,   0x4,   0x8 }, {  0x1,  0x3,   0x6,   0xC },
-    {  0x2,   0x4,   0x8,  0x10 }, {  0x3,  0x6,   0xC,  0x18 },
-    {  0x4,   0x8,  0x10,  0x20 }, {  0x6,  0xC,  0x18,  0x30 },
-    {  0x8,  0x10,  0x20,  0x40 },
-                      { 0xA, 0x14, 0x28, 0x50 },
-                                   {  0xC, 0x18,  0x30,  0x60 },
-    { 0x10,  0x20,  0x40,  0x80 }, { 0x18, 0x30,  0x60,  0xC0 },
-    { 0x20,  0x40,  0x80, 0x100 }, { 0x30, 0x60,  0xC0, 0x180 },
-    { 0x40,  0x80, 0x100, 0x200 }, { 0x60, 0xC0, 0x180, 0x300 },
-    { 0x80, 0x100, 0x200, 0x400 }
+ * then there is the special one, powers of 2 * 5.
+ * We also encode the corresponding AC index in these tables in bits 29-31. */
+static const unsigned hqx_quants[16][4] = {
+#define Q(q) ((unsigned)AC_IDX(q) << 29 | (q))
+    { Q( 0x1), Q(  0x2), Q(  0x4), Q(  0x8) }, { Q( 0x1), Q( 0x3), Q(  0x6), Q(  0xC) },
+    { Q( 0x2), Q(  0x4), Q(  0x8), Q( 0x10) }, { Q( 0x3), Q( 0x6), Q(  0xC), Q( 0x18) },
+    { Q( 0x4), Q(  0x8), Q( 0x10), Q( 0x20) }, { Q( 0x6), Q( 0xC), Q( 0x18), Q( 0x30) },
+    { Q( 0x8), Q( 0x10), Q( 0x20), Q( 0x40) },
+                            { Q(0xA), Q(0x14), Q(0x28), Q(0x50) },
+                                               { Q( 0xC), Q(0x18), Q( 0x30), Q( 0x60) },
+    { Q(0x10), Q( 0x20), Q( 0x40), Q( 0x80) }, { Q(0x18), Q(0x30), Q( 0x60), Q( 0xC0) },
+    { Q(0x20), Q( 0x40), Q( 0x80), Q(0x100) }, { Q(0x30), Q(0x60), Q( 0xC0), Q(0x180) },
+    { Q(0x40), Q( 0x80), Q(0x100), Q(0x200) }, { Q(0x60), Q(0xC0), Q(0x180), Q(0x300) },
+    { Q(0x80), Q(0x100), Q(0x200), Q(0x400) }
 };
 
 static const uint8_t hqx_quant_luma[64] = {
@@ -143,12 +149,12 @@ static inline void hqx_get_ac(GetBitContext *gb, const HQXAC *ac,
 }
 
 static int decode_block(GetBitContext *gb, const VLCElem vlc[],
-                        const int *quants, int dcb,
+                        const unsigned *quants, int dcb,
                         int16_t block[64], int *last_dc)
 {
-    int q, dc;
-    int ac_idx;
     int run, lev, pos = 0;
+    unsigned ac_idx, q;
+    int dc;
 
     dc = get_vlc2(gb, vlc, HQX_DC_VLC_BITS, 2);
     *last_dc += dc;
@@ -156,18 +162,9 @@ static int decode_block(GetBitContext *gb, const VLCElem vlc[],
     block[0] = sign_extend(*last_dc << (12 - dcb), 12);
 
     q = quants[get_bits(gb, 2)];
-    if (q >= 128)
-        ac_idx = HQX_AC_Q128;
-    else if (q >= 64)
-        ac_idx = HQX_AC_Q64;
-    else if (q >= 32)
-        ac_idx = HQX_AC_Q32;
-    else if (q >= 16)
-        ac_idx = HQX_AC_Q16;
-    else if (q >= 8)
-        ac_idx = HQX_AC_Q8;
-    else
-        ac_idx = HQX_AC_Q0;
+    // ac_idx is encoded in the high bits of quants;
+    // because block is 16 bit, we do not even need to clear said bits.
+    ac_idx = q >> 29;
 
     do {
         hqx_get_ac(gb, &hqx_ac[ac_idx], &run, &lev);
@@ -184,7 +181,7 @@ static int hqx_decode_422(HQXContext *ctx, int slice_no, int x, int y)
 {
     HQXSlice *slice = &ctx->slice[slice_no];
     GetBitContext *gb = &slice->gb;
-    const int *quants;
+    const unsigned *quants;
     int flag;
     int last_dc;
     int i, ret;
@@ -219,7 +216,6 @@ static int hqx_decode_422a(HQXContext *ctx, int slice_no, int x, int y)
 {
     HQXSlice *slice = &ctx->slice[slice_no];
     GetBitContext *gb = &slice->gb;
-    const int *quants;
     int flag = 0;
     int last_dc;
     int i, ret;
@@ -231,6 +227,8 @@ static int hqx_decode_422a(HQXContext *ctx, int slice_no, int x, int y)
 
     cbp = get_vlc2(gb, cbp_vlc, HQX_CBP_VLC_BITS, 1);
     if (cbp) {
+        const unsigned *quants;
+
         if (ctx->interlaced)
             flag = get_bits1(gb);
 
@@ -267,7 +265,7 @@ static int hqx_decode_444(HQXContext *ctx, int slice_no, int x, int y)
 {
     HQXSlice *slice = &ctx->slice[slice_no];
     GetBitContext *gb = &slice->gb;
-    const int *quants;
+    const unsigned *quants;
     int flag;
     int last_dc;
     int i, ret;
@@ -304,7 +302,6 @@ static int hqx_decode_444a(HQXContext *ctx, int slice_no, int x, int y)
 {
     HQXSlice *slice = &ctx->slice[slice_no];
     GetBitContext *gb = &slice->gb;
-    const int *quants;
     int flag = 0;
     int last_dc;
     int i, ret;
@@ -316,6 +313,8 @@ static int hqx_decode_444a(HQXContext *ctx, int slice_no, int x, int y)
 
     cbp = get_vlc2(gb, cbp_vlc, HQX_CBP_VLC_BITS, 1);
     if (cbp) {
+        const unsigned *quants;
+
         if (ctx->interlaced)
             flag = get_bits1(gb);
 
-- 
2.45.2


[-- Attachment #15: 0014-avcodec-cfhd-Move-GetBitContext-from-context-to-stac.patch --]
[-- Type: text/x-patch, Size: 3987 bytes --]

From 37e037c55320738b76ba6181ed6e5f4fd5fad852 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Fri, 14 Mar 2025 00:11:31 +0100
Subject: [PATCH 14/17] avcodec/cfhd: Move GetBitContext from context to stack

Its lifetime is extremely limited.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/cfhd.c | 17 +++++++++--------
 libavcodec/cfhd.h |  3 ---
 2 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/libavcodec/cfhd.c b/libavcodec/cfhd.c
index 6f1d960058..4ae5510448 100644
--- a/libavcodec/cfhd.c
+++ b/libavcodec/cfhd.c
@@ -772,6 +772,7 @@ static int cfhd_decode(AVCodecContext *avctx, AVFrame *pic,
         if (tag == BandHeader || tag == BandSecondPass) {
             int highpass_height, highpass_width, highpass_a_width, highpass_a_height, highpass_stride, a_expected;
             int expected;
+            GetBitContext gbit;
             int level, run, coeff;
             int count = 0, bytes;
 
@@ -802,11 +803,11 @@ static int cfhd_decode(AVCodecContext *avctx, AVFrame *pic,
 
             av_log(avctx, AV_LOG_DEBUG, "Start subband coeffs plane %i level %i codebook %i expected %i\n", s->channel_num, s->level, s->codebook, expected);
 
-            ret = init_get_bits8(&s->gb, gb.buffer, bytestream2_get_bytes_left(&gb));
+            ret = init_get_bits8(&gbit, gb.buffer, bytestream2_get_bytes_left(&gb));
             if (ret < 0)
                 goto end;
             {
-                OPEN_READER(re, &s->gb);
+                OPEN_READER(re, &gbit);
 
                 const int lossless = s->band_encoding == 5;
 
@@ -814,8 +815,8 @@ static int cfhd_decode(AVCodecContext *avctx, AVFrame *pic,
                     s->codebook = 1;
                 if (!s->codebook) {
                     while (1) {
-                        UPDATE_CACHE(re, &s->gb);
-                        GET_RL_VLC(level, run, re, &s->gb, s->table_9_rl_vlc,
+                        UPDATE_CACHE(re, &gbit);
+                        GET_RL_VLC(level, run, re, &gbit, s->table_9_rl_vlc,
                                    VLC_BITS, 3, 1);
 
                         /* escape */
@@ -845,8 +846,8 @@ static int cfhd_decode(AVCodecContext *avctx, AVFrame *pic,
                     }
                 } else {
                     while (1) {
-                        UPDATE_CACHE(re, &s->gb);
-                        GET_RL_VLC(level, run, re, &s->gb, s->table_18_rl_vlc,
+                        UPDATE_CACHE(re, &gbit);
+                        GET_RL_VLC(level, run, re, &gbit, s->table_18_rl_vlc,
                                    VLC_BITS, 3, 1);
 
                         /* escape */
@@ -875,7 +876,7 @@ static int cfhd_decode(AVCodecContext *avctx, AVFrame *pic,
                         }
                     }
                 }
-                CLOSE_READER(re, &s->gb);
+                CLOSE_READER(re, &gbit);
             }
 
             if (count > expected) {
@@ -888,7 +889,7 @@ static int cfhd_decode(AVCodecContext *avctx, AVFrame *pic,
             if (s->difference_coding)
                 difference_coding(s->plane[s->channel_num].subband[s->subband_num_actual], highpass_width, highpass_height);
 
-            bytes = FFALIGN(AV_CEIL_RSHIFT(get_bits_count(&s->gb), 3), 4);
+            bytes = FFALIGN(AV_CEIL_RSHIFT(get_bits_count(&gbit), 3), 4);
             if (bytes > bytestream2_get_bytes_left(&gb)) {
                 av_log(avctx, AV_LOG_ERROR, "Bitstream overread error\n");
                 ret = AVERROR(EINVAL);
diff --git a/libavcodec/cfhd.h b/libavcodec/cfhd.h
index 586d3360b6..2dbac80c66 100644
--- a/libavcodec/cfhd.h
+++ b/libavcodec/cfhd.h
@@ -25,7 +25,6 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
-#include "get_bits.h"
 #include "cfhddsp.h"
 
 enum CFHDParam {
@@ -144,8 +143,6 @@ typedef struct CFHDContext {
 
     int lut[2][256];
 
-    GetBitContext gb;
-
     int planes;
     int frame_type;
     int frame_index;
-- 
2.45.2


[-- Attachment #16: 0015-avcodec-cfhd-Use-smaller-scope-where-appropriate.patch --]
[-- Type: text/x-patch, Size: 17522 bytes --]

From b479232b4c46fd3da4789d9d93e5d79efecd351b Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Fri, 14 Mar 2025 00:24:26 +0100
Subject: [PATCH 15/17] avcodec/cfhd: Use smaller scope where appropriate

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/cfhd.c | 115 ++++++++++++++++++++++------------------------
 1 file changed, 54 insertions(+), 61 deletions(-)

diff --git a/libavcodec/cfhd.c b/libavcodec/cfhd.c
index 4ae5510448..2044254c84 100644
--- a/libavcodec/cfhd.c
+++ b/libavcodec/cfhd.c
@@ -117,10 +117,8 @@ static inline int dequant_and_decompand(CFHDContext *s, int level, int quantisat
 
 static inline void difference_coding(int16_t *band, int width, int height)
 {
-
-    int i,j;
-    for (i = 0; i < height; i++) {
-        for (j = 1; j < width; j++) {
+    for (int i = 0; i < height; i++) {
+        for (int j = 1; j < width; j++) {
           band[j] += band[j-1];
         }
         band += width;
@@ -129,17 +127,15 @@ static inline void difference_coding(int16_t *band, int width, int height)
 
 static inline void peak_table(int16_t *band, Peak *peak, int length)
 {
-    int i;
-    for (i = 0; i < length; i++)
+    for (int i = 0; i < length; i++)
         if (abs(band[i]) > peak->level)
             band[i] = bytestream2_get_le16(&peak->base);
 }
 
 static inline void process_alpha(int16_t *alpha, int width)
 {
-    int i, channel;
-    for (i = 0; i < width; i++) {
-        channel   = alpha[i];
+    for (int i = 0; i < width; i++) {
+        int channel   = alpha[i];
         channel  -= ALPHA_COMPAND_DC_OFFSET;
         channel <<= 3;
         channel  *= ALPHA_COMPAND_GAIN;
@@ -196,11 +192,9 @@ static inline void process_bayer(AVFrame *frame, int bpc)
 static inline void interlaced_vertical_filter(int16_t *output, int16_t *low, int16_t *high,
                          int width, int linesize, int plane)
 {
-    int i;
-    int16_t even, odd;
-    for (i = 0; i < width; i++) {
-        even = (low[i] - high[i])/2;
-        odd  = (low[i] + high[i])/2;
+    for (int i = 0; i < width; i++) {
+        int16_t even = (low[i] - high[i])/2;
+        int16_t odd  = (low[i] + high[i])/2;
         output[i]            = av_clip_uintp2(even, 10);
         output[i + linesize] = av_clip_uintp2(odd, 10);
     }
@@ -219,21 +213,19 @@ static inline void inverse_temporal_filter(int16_t *low, int16_t *high, int widt
 
 static void free_buffers(CFHDContext *s)
 {
-    int i, j;
-
-    for (i = 0; i < FF_ARRAY_ELEMS(s->plane); i++) {
+    for (size_t i = 0; i < FF_ARRAY_ELEMS(s->plane); i++) {
         Plane *p = &s->plane[i];
         av_freep(&s->plane[i].idwt_buf);
         av_freep(&s->plane[i].idwt_tmp);
         s->plane[i].idwt_size = 0;
 
-        for (j = 0; j < SUBBAND_COUNT_3D; j++)
+        for (int j = 0; j < SUBBAND_COUNT_3D; j++)
             s->plane[i].subband[j] = NULL;
 
-        for (j = 0; j < 10; j++)
+        for (int j = 0; j < 10; j++)
             s->plane[i].l_h[j] = NULL;
 
-        for (j = 0; j < DWT_LEVELS_3D; j++)
+        for (int j = 0; j < DWT_LEVELS_3D; j++)
             p->band[j][0].read_ok =
             p->band[j][1].read_ok =
             p->band[j][2].read_ok =
@@ -247,9 +239,8 @@ static void free_buffers(CFHDContext *s)
 static int alloc_buffers(AVCodecContext *avctx)
 {
     CFHDContext *s = avctx->priv_data;
-    int i, j, ret, planes, bayer = 0;
+    int ret, planes, bayer = 0;
     int chroma_x_shift, chroma_y_shift;
-    unsigned k;
 
     if ((ret = ff_set_dimensions(avctx, s->coded_width, s->coded_height)) < 0)
         return ret;
@@ -269,7 +260,7 @@ static int alloc_buffers(AVCodecContext *avctx)
         bayer = 1;
     }
 
-    for (i = 0; i < planes; i++) {
+    for (int i = 0; i < planes; i++) {
         int w8, h8, w4, h4, w2, h2;
         int width  = (i || bayer) ? s->coded_width  >> chroma_x_shift : s->coded_width;
         int height = (i || bayer) ? s->coded_height >> chroma_y_shift : s->coded_height;
@@ -331,17 +322,17 @@ static int alloc_buffers(AVCodecContext *avctx)
         }
 
         if (s->transform_type == 0) {
-            for (j = 0; j < DWT_LEVELS; j++) {
-                for (k = 0; k < FF_ARRAY_ELEMS(s->plane[i].band[j]); k++) {
+            for (int j = 0; j < DWT_LEVELS; j++) {
+                for (unsigned k = 0; k < FF_ARRAY_ELEMS(s->plane[i].band[j]); k++) {
                     s->plane[i].band[j][k].a_width  = w8 << j;
                     s->plane[i].band[j][k].a_height = h8 << j;
                 }
             }
         } else {
-            for (j = 0; j < DWT_LEVELS_3D; j++) {
+            for (int j = 0; j < DWT_LEVELS_3D; j++) {
                 int t = j < 1 ? 0 : (j < 3 ? 1 : 2);
 
-                for (k = 0; k < FF_ARRAY_ELEMS(s->plane[i].band[j]); k++) {
+                for (unsigned k = 0; k < FF_ARRAY_ELEMS(s->plane[i].band[j]); k++) {
                     s->plane[i].band[j][k].a_width  = w8 << t;
                     s->plane[i].band[j][k].a_height = h8 << t;
                 }
@@ -379,8 +370,7 @@ static int cfhd_decode(AVCodecContext *avctx, AVFrame *pic,
     CFHDContext *s = avctx->priv_data;
     CFHDDSPContext *dsp = &s->dsp;
     GetByteContext gb;
-    int ret = 0, i, j, plane, got_buffer = 0;
-    int16_t *coeff_data;
+    int ret = 0, got_buffer = 0;
 
     init_frame_defaults(s);
     s->planes = av_pix_fmt_count_planes(s->coded_format);
@@ -395,6 +385,8 @@ static int cfhd_decode(AVCodecContext *avctx, AVFrame *pic,
         uint16_t abstag = abs(tag);
         int8_t abs_tag8 = abs(tag8);
         uint16_t data   = bytestream2_get_be16(&gb);
+        int16_t *coeff_data;
+
         if (abs_tag8 >= 0x60 && abs_tag8 <= 0x6f) {
             av_log(avctx, AV_LOG_DEBUG, "large len %x\n", ((tagu & 0xff) << 16) | data);
         } else if (tag == SampleFlags) {
@@ -477,7 +469,7 @@ static int cfhd_decode(AVCodecContext *avctx, AVFrame *pic,
             s->quantisation = data;
             av_log(avctx, AV_LOG_DEBUG, "Quantisation: %"PRIu16"\n", data);
         } else if (tag == PrescaleTable) {
-            for (i = 0; i < 8; i++)
+            for (int i = 0; i < 8; i++)
                 s->prescale_table[i] = (data >> (14 - i * 2)) & 0x3;
             av_log(avctx, AV_LOG_DEBUG, "Prescale table: %x\n", data);
         } else if (tag == BandEncoding) {
@@ -529,7 +521,7 @@ static int cfhd_decode(AVCodecContext *avctx, AVFrame *pic,
                 ret = AVERROR_INVALIDDATA;
                 goto end;
             }
-            for (i = 0; i < data; i++) {
+            for (int i = 0; i < data; i++) {
                 uint32_t offset = bytestream2_get_be32(&gb);
                 av_log(avctx, AV_LOG_DEBUG, "Offset = %"PRIu32"\n", offset);
             }
@@ -746,8 +738,8 @@ static int cfhd_decode(AVCodecContext *avctx, AVFrame *pic,
             }
 
             av_log(avctx, AV_LOG_DEBUG, "Start of lowpass coeffs component %d height:%d, width:%d\n", s->channel_num, lowpass_height, lowpass_width);
-            for (i = 0; i < lowpass_height; i++) {
-                for (j = 0; j < lowpass_width; j++)
+            for (int i = 0; i < lowpass_height; i++) {
+                for (int j = 0; j < lowpass_width; j++)
                     coeff_data[j] = bytestream2_get_be16u(&gb);
 
                 coeff_data += lowpass_width;
@@ -773,7 +765,6 @@ static int cfhd_decode(AVCodecContext *avctx, AVFrame *pic,
             int highpass_height, highpass_width, highpass_a_width, highpass_a_height, highpass_stride, a_expected;
             int expected;
             GetBitContext gbit;
-            int level, run, coeff;
             int count = 0, bytes;
 
             if (!s->a_width || !s->a_height) {
@@ -815,6 +806,8 @@ static int cfhd_decode(AVCodecContext *avctx, AVFrame *pic,
                     s->codebook = 1;
                 if (!s->codebook) {
                     while (1) {
+                        int level, run, coeff;
+
                         UPDATE_CACHE(re, &gbit);
                         GET_RL_VLC(level, run, re, &gbit, s->table_9_rl_vlc,
                                    VLC_BITS, 3, 1);
@@ -835,17 +828,19 @@ static int cfhd_decode(AVCodecContext *avctx, AVFrame *pic,
                         if (tag == BandSecondPass) {
                             const uint16_t q = s->quantisation;
 
-                            for (i = 0; i < run; i++) {
+                            for (int i = 0; i < run; i++) {
                                 *coeff_data |= coeff * 256U;
                                 *coeff_data++ *= q;
                             }
                         } else {
-                            for (i = 0; i < run; i++)
+                            for (int i = 0; i < run; i++)
                                 *coeff_data++ = coeff;
                         }
                     }
                 } else {
                     while (1) {
+                        int level, run, coeff;
+
                         UPDATE_CACHE(re, &gbit);
                         GET_RL_VLC(level, run, re, &gbit, s->table_18_rl_vlc,
                                    VLC_BITS, 3, 1);
@@ -866,12 +861,12 @@ static int cfhd_decode(AVCodecContext *avctx, AVFrame *pic,
                         if (tag == BandSecondPass) {
                             const uint16_t q = s->quantisation;
 
-                            for (i = 0; i < run; i++) {
+                            for (int i = 0; i < run; i++) {
                                 *coeff_data |= coeff * 256U;
                                 *coeff_data++ *= q;
                             }
                         } else {
-                            for (i = 0; i < run; i++)
+                            for (int i = 0; i < run; i++)
                                 *coeff_data++ = coeff;
                         }
                     }
@@ -927,14 +922,12 @@ finish:
         goto end;
     }
 
-    for (plane = 0; plane < s->planes; plane++) {
-        int o, level;
-
-        for (level = 0; level < (s->transform_type == 0 ? DWT_LEVELS : DWT_LEVELS_3D) ; level++) {
+    for (int plane = 0; plane < s->planes; plane++) {
+        for (int level = 0; level < (s->transform_type == 0 ? DWT_LEVELS : DWT_LEVELS_3D) ; level++) {
             if (s->transform_type == 2)
                 if (level == 2 || level == 5)
                     continue;
-            for (o = !!level; o < 4 ; o++) {
+            for (int o = !!level; o < 4 ; o++) {
                 if (!s->plane[plane].band[level][o].read_ok) {
                     ret = AVERROR_INVALIDDATA;
                     goto end;
@@ -944,7 +937,7 @@ finish:
     }
 
     if (s->transform_type == 0 && s->sample_type != 1) {
-        for (plane = 0; plane < s->planes && !ret; plane++) {
+        for (int plane = 0; plane < s->planes && !ret; plane++) {
             /* level 1 */
             int lowpass_height  = s->plane[plane].band[0][0].height;
             int output_stride   = s->plane[plane].band[0][0].a_width;
@@ -988,8 +981,8 @@ finish:
             dsp->horiz_filter(output, output_stride, low, output_stride, high, output_stride, lowpass_width, lowpass_height * 2);
             if (s->bpc == 12) {
                 output = s->plane[plane].subband[0];
-                for (i = 0; i < lowpass_height * 2; i++) {
-                    for (j = 0; j < lowpass_width * 2; j++)
+                for (int i = 0; i < lowpass_height * 2; i++) {
+                    for (int j = 0; j < lowpass_width * 2; j++)
                         output[j] *= 4;
 
                     output += output_stride * 2;
@@ -1028,8 +1021,8 @@ finish:
             dsp->horiz_filter(output, output_stride, low, output_stride, high, output_stride, lowpass_width, lowpass_height * 2);
 
             output = s->plane[plane].subband[0];
-            for (i = 0; i < lowpass_height * 2; i++) {
-                for (j = 0; j < lowpass_width * 2; j++)
+            for (int i = 0; i < lowpass_height * 2; i++) {
+                for (int j = 0; j < lowpass_width * 2; j++)
                     output[j] *= 4;
 
                 output += output_stride * 2;
@@ -1079,7 +1072,7 @@ finish:
                     goto end;
                 }
 
-                for (i = 0; i < s->plane[act_plane].height; i++) {
+                for (int i = 0; i < s->plane[act_plane].height; i++) {
                     dsp->horiz_filter_clip(dst, low, high, lowpass_width, s->bpc);
                     if (avctx->pix_fmt == AV_PIX_FMT_GBRAP12 && act_plane == 3)
                         process_alpha(dst, lowpass_width * 2);
@@ -1103,7 +1096,7 @@ finish:
                 dst  = (int16_t *)pic->data[act_plane];
                 low  = s->plane[plane].l_h[6];
                 high = s->plane[plane].l_h[7];
-                for (i = 0; i < s->plane[act_plane].height / 2; i++) {
+                for (int i = 0; i < s->plane[act_plane].height / 2; i++) {
                     interlaced_vertical_filter(dst, low, high, lowpass_width * 2,  pic->linesize[act_plane]/2, act_plane);
                     low  += output_stride * 2;
                     high += output_stride * 2;
@@ -1112,7 +1105,7 @@ finish:
             }
         }
     } else if (s->transform_type == 2 && (avctx->internal->is_copy || s->frame_index == 1 || s->sample_type != 1)) {
-        for (plane = 0; plane < s->planes && !ret; plane++) {
+        for (int plane = 0; plane < s->planes && !ret; plane++) {
             int lowpass_height  = s->plane[plane].band[0][0].height;
             int output_stride   = s->plane[plane].band[0][0].a_width;
             int lowpass_width   = s->plane[plane].band[0][0].width;
@@ -1154,8 +1147,8 @@ finish:
             dsp->horiz_filter(output, output_stride, low, output_stride, high, output_stride, lowpass_width, lowpass_height * 2);
             if (s->bpc == 12) {
                 output = s->plane[plane].l_h[7];
-                for (i = 0; i < lowpass_height * 2; i++) {
-                    for (j = 0; j < lowpass_width * 2; j++)
+                for (int i = 0; i < lowpass_height * 2; i++) {
+                    for (int j = 0; j < lowpass_width * 2; j++)
                         output[j] *= 4;
 
                     output += output_stride * 2;
@@ -1193,8 +1186,8 @@ finish:
             dsp->horiz_filter(output, output_stride, low, output_stride, high, output_stride, lowpass_width, lowpass_height * 2);
 
             output = s->plane[plane].l_h[7];
-            for (i = 0; i < lowpass_height * 2; i++) {
-                for (j = 0; j < lowpass_width * 2; j++)
+            for (int i = 0; i < lowpass_height * 2; i++) {
+                for (int j = 0; j < lowpass_width * 2; j++)
                     output[j] *= 4;
                 output += output_stride * 2;
             }
@@ -1231,7 +1224,7 @@ finish:
             low    = s->plane[plane].l_h[7];
             high   = s->plane[plane].l_h[9];
             output = s->plane[plane].l_h[7];
-            for (i = 0; i < lowpass_height; i++) {
+            for (int i = 0; i < lowpass_height; i++) {
                 inverse_temporal_filter(low, high, lowpass_width);
                 low    += output_stride;
                 high   += output_stride;
@@ -1278,7 +1271,7 @@ finish:
 
                 low  = s->plane[plane].l_h[6];
                 high = s->plane[plane].l_h[7];
-                for (i = 0; i < s->plane[act_plane].height; i++) {
+                for (int i = 0; i < s->plane[act_plane].height; i++) {
                     dsp->horiz_filter_clip(dst, low, high, lowpass_width, s->bpc);
                     low  += output_stride;
                     high += output_stride;
@@ -1312,7 +1305,7 @@ finish:
                 dst  = (int16_t *)pic->data[act_plane];
                 low  = s->plane[plane].l_h[6];
                 high = s->plane[plane].l_h[7];
-                for (i = 0; i < s->plane[act_plane].height / 2; i++) {
+                for (int i = 0; i < s->plane[act_plane].height / 2; i++) {
                     interlaced_vertical_filter(dst, low, high, lowpass_width * 2,  pic->linesize[act_plane]/2, act_plane);
                     low  += output_stride * 2;
                     high += output_stride * 2;
@@ -1327,7 +1320,7 @@ finish:
         int output_stride, lowpass_height, lowpass_width;
         ptrdiff_t dst_linesize;
 
-        for (plane = 0; plane < s->planes; plane++) {
+        for (int plane = 0; plane < s->planes; plane++) {
             int act_plane = plane == 1 ? 2 : plane == 2 ? 1 : plane;
 
             if (avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16) {
@@ -1369,7 +1362,7 @@ finish:
                     goto end;
                 }
 
-                for (i = 0; i < s->plane[act_plane].height; i++) {
+                for (int i = 0; i < s->plane[act_plane].height; i++) {
                     dsp->horiz_filter_clip(dst, low, high, lowpass_width, s->bpc);
                     low  += output_stride;
                     high += output_stride;
@@ -1379,7 +1372,7 @@ finish:
                 dst  = (int16_t *)pic->data[act_plane];
                 low  = s->plane[plane].l_h[8];
                 high = s->plane[plane].l_h[9];
-                for (i = 0; i < s->plane[act_plane].height / 2; i++) {
+                for (int i = 0; i < s->plane[act_plane].height / 2; i++) {
                     interlaced_vertical_filter(dst, low, high, lowpass_width * 2,  pic->linesize[act_plane]/2, act_plane);
                     low  += output_stride * 2;
                     high += output_stride * 2;
-- 
2.45.2


[-- Attachment #17: 0016-avcodec-qdm2-vorbisdec-Use-compile-time-const-max_de.patch --]
[-- Type: text/x-patch, Size: 2137 bytes --]

From 998391484026434b125d4856531fe1203f87fe50 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Fri, 14 Mar 2025 02:31:51 +0100
Subject: [PATCH 16/17] avcodec/qdm2, vorbisdec: Use compile-time const
 max_depth in get_vlc2

It makes no sense to try to be exact with max depth
in get_vlc2(): It will mean that the compiler emits code
for all three stages of parsing and runtime checks for
whether max_depth is big enough to parse the next stage
when a not yet complete code has been encountered.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/qdm2.c      | 6 +++---
 libavcodec/vorbisdec.c | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c
index e629e3b42a..ffb44015ec 100644
--- a/libavcodec/qdm2.c
+++ b/libavcodec/qdm2.c
@@ -34,6 +34,7 @@
 #include <math.h>
 #include <stddef.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/mem_internal.h"
 #include "libavutil/thread.h"
@@ -199,9 +200,8 @@ static const int switchtable[23] = {
 
 static int qdm2_get_vlc(GetBitContext *gb, const VLC *vlc, int flag, int depth)
 {
-    int value;
-
-    value = get_vlc2(gb, vlc->table, vlc->bits, depth);
+    int value = get_vlc2(gb, vlc->table, vlc->bits,
+                         av_builtin_constant_p(depth) ? depth : 2);
 
     /* stage-2, 3 bits exponent escape sequence */
     if (value < 0)
diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c
index 11111e7eb3..a778dc6b58 100644
--- a/libavcodec/vorbisdec.c
+++ b/libavcodec/vorbisdec.c
@@ -1150,7 +1150,7 @@ static int vorbis_floor0_decode(vorbis_context *vc,
             ff_dlog(NULL, "floor0 dec: maximum depth: %d\n", codebook.maxdepth);
             /* read temp vector */
             vec_off = get_vlc2(&vc->gb, codebook.vlc.table,
-                               codebook.nb_bits, codebook.maxdepth);
+                               codebook.nb_bits, 3);
             if (vec_off < 0)
                 return AVERROR_INVALIDDATA;
             vec_off *= codebook.dimensions;
-- 
2.45.2


[-- Attachment #18: 0017-avcodec-qdm2-Use-explicit-overread-checks-instead-of.patch --]
[-- Type: text/x-patch, Size: 3581 bytes --]

From 4d8c0f1980673b3c3e11a79de925d5fb0b063cde Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Fri, 14 Mar 2025 02:58:33 +0100
Subject: [PATCH 17/17] avcodec/qdm2: Use explicit overread checks instead of
 implicit ones

If there were not enough data, checksum_size would be read
as zero (due to the implicit checks of the bytestream2 API)
and run into a "data block size invalid" error. Erroring out
earlier via "not enough extradata" is better.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/qdm2.c | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c
index ffb44015ec..b2136c6824 100644
--- a/libavcodec/qdm2.c
+++ b/libavcodec/qdm2.c
@@ -1661,20 +1661,20 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx)
     bytestream2_init(&gb, avctx->extradata, avctx->extradata_size);
 
     while (bytestream2_get_bytes_left(&gb) > 8) {
-        if (bytestream2_peek_be64(&gb) == (((uint64_t)MKBETAG('f','r','m','a') << 32) |
+        if (bytestream2_peek_be64u(&gb) == (((uint64_t)MKBETAG('f','r','m','a') << 32) |
                                             (uint64_t)MKBETAG('Q','D','M','2')))
             break;
-        bytestream2_skip(&gb, 1);
+        bytestream2_skipu(&gb, 1);
     }
 
-    if (bytestream2_get_bytes_left(&gb) < 12) {
+    if (bytestream2_get_bytes_left(&gb) < 44) {
         av_log(avctx, AV_LOG_ERROR, "not enough extradata (%i)\n",
                bytestream2_get_bytes_left(&gb));
         return AVERROR_INVALIDDATA;
     }
 
-    bytestream2_skip(&gb, 8);
-    size = bytestream2_get_be32(&gb);
+    bytestream2_skipu(&gb, 8);
+    size = bytestream2_get_be32u(&gb);
 
     if (size > bytestream2_get_bytes_left(&gb)) {
         av_log(avctx, AV_LOG_ERROR, "extradata size too small, %i < %i\n",
@@ -1683,14 +1683,14 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx)
     }
 
     av_log(avctx, AV_LOG_DEBUG, "size: %d\n", size);
-    if (bytestream2_get_be32(&gb) != MKBETAG('Q','D','C','A')) {
+    if (bytestream2_get_be32u(&gb) != MKBETAG('Q','D','C','A')) {
         av_log(avctx, AV_LOG_ERROR, "invalid extradata, expecting QDCA\n");
         return AVERROR_INVALIDDATA;
     }
 
-    bytestream2_skip(&gb, 4);
+    bytestream2_skipu(&gb, 4);
 
-    s->nb_channels = s->channels = bytestream2_get_be32(&gb);
+    s->nb_channels = s->channels = bytestream2_get_be32u(&gb);
     if (s->channels <= 0 || s->channels > MPA_MAX_CHANNELS) {
         av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n");
         return AVERROR_INVALIDDATA;
@@ -1698,11 +1698,11 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx)
     av_channel_layout_uninit(&avctx->ch_layout);
     av_channel_layout_default(&avctx->ch_layout, s->channels);
 
-    avctx->sample_rate = bytestream2_get_be32(&gb);
-    avctx->bit_rate = bytestream2_get_be32(&gb);
-    s->group_size = bytestream2_get_be32(&gb);
-    s->fft_size = bytestream2_get_be32(&gb);
-    s->checksum_size = bytestream2_get_be32(&gb);
+    avctx->sample_rate = bytestream2_get_be32u(&gb);
+    avctx->bit_rate    = bytestream2_get_be32u(&gb);
+    s->group_size      = bytestream2_get_be32u(&gb);
+    s->fft_size        = bytestream2_get_be32u(&gb);
+    s->checksum_size   = bytestream2_get_be32u(&gb);
     if (s->checksum_size >= 1U << 28 || s->checksum_size <= 1) {
         av_log(avctx, AV_LOG_ERROR, "data block size invalid (%u)\n", s->checksum_size);
         return AVERROR_INVALIDDATA;
-- 
2.45.2


[-- Attachment #19: Type: text/plain, Size: 251 bytes --]

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2025-03-16  3:50 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-03-14 10:53 [FFmpeg-devel] Subject: [PATCH 01/17] avcodec/vlc: Merge VLCElem and RL_VLC_ELEM Andreas Rheinhardt
2025-03-16  3:50 ` Andreas Rheinhardt

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git