1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * Copyright (c) 1990 James Ashton - Sydney University
3cabdff1aSopenharmony_ci * Copyright (c) 2012 Stefano Sabatini
4cabdff1aSopenharmony_ci *
5cabdff1aSopenharmony_ci * This file is part of FFmpeg.
6cabdff1aSopenharmony_ci *
7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
11cabdff1aSopenharmony_ci *
12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15cabdff1aSopenharmony_ci * Lesser General Public License for more details.
16cabdff1aSopenharmony_ci *
17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20cabdff1aSopenharmony_ci */
21cabdff1aSopenharmony_ci
22cabdff1aSopenharmony_ci/**
23cabdff1aSopenharmony_ci * @file
24cabdff1aSopenharmony_ci * X-Face common data and utilities definition.
25cabdff1aSopenharmony_ci */
26cabdff1aSopenharmony_ci
27cabdff1aSopenharmony_ci#include "libavutil/avassert.h"
28cabdff1aSopenharmony_ci
29cabdff1aSopenharmony_ci#include "xface.h"
30cabdff1aSopenharmony_ci
31cabdff1aSopenharmony_civoid ff_big_add(BigInt *b, uint8_t a)
32cabdff1aSopenharmony_ci{
33cabdff1aSopenharmony_ci    int i;
34cabdff1aSopenharmony_ci    uint8_t *w;
35cabdff1aSopenharmony_ci    uint16_t c;
36cabdff1aSopenharmony_ci
37cabdff1aSopenharmony_ci    a &= XFACE_WORDMASK;
38cabdff1aSopenharmony_ci    if (a == 0)
39cabdff1aSopenharmony_ci        return;
40cabdff1aSopenharmony_ci    w = b->words;
41cabdff1aSopenharmony_ci    c = a;
42cabdff1aSopenharmony_ci    for (i = 0; i < b->nb_words && c; i++) {
43cabdff1aSopenharmony_ci        c += *w;
44cabdff1aSopenharmony_ci        *w++ = c & XFACE_WORDMASK;
45cabdff1aSopenharmony_ci        c >>= XFACE_BITSPERWORD;
46cabdff1aSopenharmony_ci    }
47cabdff1aSopenharmony_ci    if (i == b->nb_words && c) {
48cabdff1aSopenharmony_ci        av_assert0(b->nb_words < XFACE_MAX_WORDS);
49cabdff1aSopenharmony_ci        b->nb_words++;
50cabdff1aSopenharmony_ci        *w = c & XFACE_WORDMASK;
51cabdff1aSopenharmony_ci    }
52cabdff1aSopenharmony_ci}
53cabdff1aSopenharmony_ci
54cabdff1aSopenharmony_civoid ff_big_div(BigInt *b, uint8_t a, uint8_t *r)
55cabdff1aSopenharmony_ci{
56cabdff1aSopenharmony_ci    int i;
57cabdff1aSopenharmony_ci    uint8_t *w;
58cabdff1aSopenharmony_ci    uint16_t c, d;
59cabdff1aSopenharmony_ci
60cabdff1aSopenharmony_ci    a &= XFACE_WORDMASK;
61cabdff1aSopenharmony_ci    if (a == 1 || b->nb_words == 0) {
62cabdff1aSopenharmony_ci        *r = 0;
63cabdff1aSopenharmony_ci        return;
64cabdff1aSopenharmony_ci    }
65cabdff1aSopenharmony_ci
66cabdff1aSopenharmony_ci    /* treat this as a == WORDCARRY and just shift everything right a WORD */
67cabdff1aSopenharmony_ci    if (a == 0) {
68cabdff1aSopenharmony_ci        i = --b->nb_words;
69cabdff1aSopenharmony_ci        w = b->words;
70cabdff1aSopenharmony_ci        *r = *w;
71cabdff1aSopenharmony_ci        while (i--) {
72cabdff1aSopenharmony_ci            *w = *(w + 1);
73cabdff1aSopenharmony_ci            w++;
74cabdff1aSopenharmony_ci        }
75cabdff1aSopenharmony_ci        *w = 0;
76cabdff1aSopenharmony_ci        return;
77cabdff1aSopenharmony_ci    }
78cabdff1aSopenharmony_ci    i = b->nb_words;
79cabdff1aSopenharmony_ci    w = b->words + i;
80cabdff1aSopenharmony_ci    c = 0;
81cabdff1aSopenharmony_ci    while (i--) {
82cabdff1aSopenharmony_ci        c <<= XFACE_BITSPERWORD;
83cabdff1aSopenharmony_ci        c += *--w;
84cabdff1aSopenharmony_ci        d = c / (uint16_t)a;
85cabdff1aSopenharmony_ci        c = c % (uint16_t)a;
86cabdff1aSopenharmony_ci        *w = d & XFACE_WORDMASK;
87cabdff1aSopenharmony_ci    }
88cabdff1aSopenharmony_ci    *r = c;
89cabdff1aSopenharmony_ci    if (b->words[b->nb_words - 1] == 0)
90cabdff1aSopenharmony_ci        b->nb_words--;
91cabdff1aSopenharmony_ci}
92cabdff1aSopenharmony_ci
93cabdff1aSopenharmony_civoid ff_big_mul(BigInt *b, uint8_t a)
94cabdff1aSopenharmony_ci{
95cabdff1aSopenharmony_ci    int i;
96cabdff1aSopenharmony_ci    uint8_t *w;
97cabdff1aSopenharmony_ci    uint16_t c;
98cabdff1aSopenharmony_ci
99cabdff1aSopenharmony_ci    a &= XFACE_WORDMASK;
100cabdff1aSopenharmony_ci    if (a == 1 || b->nb_words == 0)
101cabdff1aSopenharmony_ci        return;
102cabdff1aSopenharmony_ci    if (a == 0) {
103cabdff1aSopenharmony_ci        /* treat this as a == WORDCARRY and just shift everything left a WORD */
104cabdff1aSopenharmony_ci        av_assert0(b->nb_words < XFACE_MAX_WORDS);
105cabdff1aSopenharmony_ci        i = b->nb_words++;
106cabdff1aSopenharmony_ci        w = b->words + i;
107cabdff1aSopenharmony_ci        while (i--) {
108cabdff1aSopenharmony_ci            *w = *(w - 1);
109cabdff1aSopenharmony_ci            w--;
110cabdff1aSopenharmony_ci        }
111cabdff1aSopenharmony_ci        *w = 0;
112cabdff1aSopenharmony_ci        return;
113cabdff1aSopenharmony_ci    }
114cabdff1aSopenharmony_ci    i = b->nb_words;
115cabdff1aSopenharmony_ci    w = b->words;
116cabdff1aSopenharmony_ci    c = 0;
117cabdff1aSopenharmony_ci    while (i--) {
118cabdff1aSopenharmony_ci        c += (uint16_t)*w * (uint16_t)a;
119cabdff1aSopenharmony_ci        *(w++) = c & XFACE_WORDMASK;
120cabdff1aSopenharmony_ci        c >>= XFACE_BITSPERWORD;
121cabdff1aSopenharmony_ci    }
122cabdff1aSopenharmony_ci    if (c) {
123cabdff1aSopenharmony_ci        av_assert0(b->nb_words < XFACE_MAX_WORDS);
124cabdff1aSopenharmony_ci        b->nb_words++;
125cabdff1aSopenharmony_ci        *w = c & XFACE_WORDMASK;
126cabdff1aSopenharmony_ci    }
127cabdff1aSopenharmony_ci}
128cabdff1aSopenharmony_ci
129cabdff1aSopenharmony_ciconst ProbRange ff_xface_probranges_per_level[4][3] = {
130cabdff1aSopenharmony_ci    //  black      grey       white
131cabdff1aSopenharmony_ci    { {  1, 255}, {251, 0}, {  4, 251} }, /* Top of tree almost always grey */
132cabdff1aSopenharmony_ci    { {  1, 255}, {200, 0}, { 55, 200} },
133cabdff1aSopenharmony_ci    { { 33, 223}, {159, 0}, { 64, 159} },
134cabdff1aSopenharmony_ci    { {131,   0}, {  0, 0}, {125, 131} }, /* Grey disallowed at bottom */
135cabdff1aSopenharmony_ci};
136cabdff1aSopenharmony_ci
137cabdff1aSopenharmony_ciconst ProbRange ff_xface_probranges_2x2[16] = {
138cabdff1aSopenharmony_ci    { 0,   0},  {38,   0}, {38,  38},  {13, 152},
139cabdff1aSopenharmony_ci    {38,  76},  {13, 165}, {13, 178},  { 6, 230},
140cabdff1aSopenharmony_ci    {38, 114},  {13, 191}, {13, 204},  { 6, 236},
141cabdff1aSopenharmony_ci    {13, 217},  { 6, 242}, { 5, 248},  { 3, 253},
142cabdff1aSopenharmony_ci};
143cabdff1aSopenharmony_ci
144cabdff1aSopenharmony_ci/*
145cabdff1aSopenharmony_ci * The "guess the next pixel" tables follow. Normally there are 12
146cabdff1aSopenharmony_ci * neighbour pixels used to give 1<<12 cases as we get closer to the
147cabdff1aSopenharmony_ci * upper left corner lesser numbers of neighbours are available.
148cabdff1aSopenharmony_ci *
149cabdff1aSopenharmony_ci * Each byte in the tables represents 8 boolean values starting from
150cabdff1aSopenharmony_ci * the most significant bit.
151cabdff1aSopenharmony_ci */
152cabdff1aSopenharmony_ci
153cabdff1aSopenharmony_cistatic const uint8_t g_00[] = {
154cabdff1aSopenharmony_ci    0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xe3, 0xdf, 0x05, 0x17,
155cabdff1aSopenharmony_ci    0x05, 0x0f, 0x00, 0x1b, 0x0f, 0xdf, 0x00, 0x04, 0x00, 0x00,
156cabdff1aSopenharmony_ci    0x0d, 0x0f, 0x03, 0x7f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1d,
157cabdff1aSopenharmony_ci    0x45, 0x2f, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x0a, 0xff, 0xff,
158cabdff1aSopenharmony_ci    0x00, 0x04, 0x00, 0x05, 0x01, 0x3f, 0xcf, 0xff, 0x10, 0x01,
159cabdff1aSopenharmony_ci    0x80, 0xc9, 0x0f, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
160cabdff1aSopenharmony_ci    0x1b, 0x1f, 0xff, 0xff, 0x4f, 0x54, 0x07, 0x1f, 0x57, 0x47,
161cabdff1aSopenharmony_ci    0xd7, 0x3d, 0xff, 0xff, 0x5f, 0x1f, 0x7f, 0xff, 0x7f, 0x7f,
162cabdff1aSopenharmony_ci    0x05, 0x0f, 0x01, 0x0f, 0x0f, 0x5f, 0x9b, 0xdf, 0x7f, 0xff,
163cabdff1aSopenharmony_ci    0x5f, 0x1d, 0x5f, 0xff, 0x0f, 0x1f, 0x0f, 0x5f, 0x03, 0x1f,
164cabdff1aSopenharmony_ci    0x4f, 0x5f, 0xf7, 0x7f, 0x7f, 0xff, 0x0d, 0x0f, 0xfb, 0xff,
165cabdff1aSopenharmony_ci    0xf7, 0xbf, 0x0f, 0x4f, 0xd7, 0x3f, 0x4f, 0x7f, 0xff, 0xff,
166cabdff1aSopenharmony_ci    0x67, 0xbf, 0x56, 0x25, 0x1f, 0x7f, 0x9f, 0xff, 0x00, 0x00,
167cabdff1aSopenharmony_ci    0x00, 0x05, 0x5f, 0x7f, 0x01, 0xdf, 0x14, 0x00, 0x05, 0x0f,
168cabdff1aSopenharmony_ci    0x07, 0xa2, 0x09, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x5f,
169cabdff1aSopenharmony_ci    0x18, 0xd7, 0x94, 0x71, 0x00, 0x05, 0x1f, 0xb7, 0x0c, 0x07,
170cabdff1aSopenharmony_ci    0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0x1f, 0x84, 0x8f, 0x05, 0x15,
171cabdff1aSopenharmony_ci    0x05, 0x0f, 0x4f, 0xff, 0x87, 0xdf, 0x05, 0x01, 0x10, 0x00,
172cabdff1aSopenharmony_ci    0x0f, 0x0f, 0x00, 0x08, 0x05, 0x04, 0x04, 0x01, 0x4f, 0xff,
173cabdff1aSopenharmony_ci    0x9f, 0x8f, 0x4a, 0x40, 0x5f, 0x5f, 0xff, 0xfe, 0xdf, 0xff,
174cabdff1aSopenharmony_ci    0x7f, 0xf7, 0xff, 0x7f, 0xff, 0xff, 0x7b, 0xff, 0x0f, 0xfd,
175cabdff1aSopenharmony_ci    0xd7, 0x5f, 0x4f, 0x7f, 0x7f, 0xdf, 0xff, 0xff, 0xff, 0xff,
176cabdff1aSopenharmony_ci    0xff, 0x77, 0xdf, 0x7f, 0x4f, 0xef, 0xff, 0xff, 0x77, 0xff,
177cabdff1aSopenharmony_ci    0xff, 0xff, 0x6f, 0xff, 0x0f, 0x4f, 0xff, 0xff, 0x9d, 0xff,
178cabdff1aSopenharmony_ci    0x0f, 0xef, 0xff, 0xdf, 0x6f, 0xff, 0xff, 0xff, 0x4f, 0xff,
179cabdff1aSopenharmony_ci    0xcd, 0x0f, 0x4f, 0xff, 0xff, 0xdf, 0x00, 0x00, 0x00, 0x0b,
180cabdff1aSopenharmony_ci    0x05, 0x02, 0x02, 0x0f, 0x04, 0x00, 0x00, 0x0c, 0x01, 0x06,
181cabdff1aSopenharmony_ci    0x00, 0x0f, 0x20, 0x03, 0x00, 0x00, 0x05, 0x0f, 0x40, 0x08,
182cabdff1aSopenharmony_ci    0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x0c, 0x0f, 0x01, 0x00,
183cabdff1aSopenharmony_ci    0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x14, 0x01, 0x05,
184cabdff1aSopenharmony_ci    0x01, 0x15, 0xaf, 0x0f, 0x00, 0x01, 0x10, 0x00, 0x08, 0x00,
185cabdff1aSopenharmony_ci    0x46, 0x0c, 0x20, 0x00, 0x88, 0x00, 0x0f, 0x15, 0xff, 0xdf,
186cabdff1aSopenharmony_ci    0x02, 0x00, 0x00, 0x0f, 0x7f, 0x5f, 0xdb, 0xff, 0x4f, 0x3e,
187cabdff1aSopenharmony_ci    0x05, 0x0f, 0x7f, 0xf7, 0x95, 0x4f, 0x0d, 0x0f, 0x01, 0x0f,
188cabdff1aSopenharmony_ci    0x4f, 0x5f, 0x9f, 0xdf, 0x25, 0x0e, 0x0d, 0x0d, 0x4f, 0x7f,
189cabdff1aSopenharmony_ci    0x8f, 0x0f, 0x0f, 0xfa, 0x04, 0x4f, 0x4f, 0xff, 0xf7, 0x77,
190cabdff1aSopenharmony_ci    0x47, 0xed, 0x05, 0x0f, 0xff, 0xff, 0xdf, 0xff, 0x4f, 0x6f,
191cabdff1aSopenharmony_ci    0xd8, 0x5f, 0x0f, 0x7f, 0xdf, 0x5f, 0x07, 0x0f, 0x94, 0x0d,
192cabdff1aSopenharmony_ci    0x1f, 0xff, 0xff, 0xff, 0x00, 0x02, 0x00, 0x03, 0x46, 0x57,
193cabdff1aSopenharmony_ci    0x01, 0x0d, 0x01, 0x08, 0x01, 0x0f, 0x47, 0x6c, 0x0d, 0x0f,
194cabdff1aSopenharmony_ci    0x02, 0x00, 0x00, 0x00, 0x0b, 0x4f, 0x00, 0x08, 0x05, 0x00,
195cabdff1aSopenharmony_ci    0x95, 0x01, 0x0f, 0x7f, 0x0c, 0x0f, 0x01, 0x0e, 0x00, 0x00,
196cabdff1aSopenharmony_ci    0x0f, 0x41, 0x00, 0x00, 0x04, 0x24, 0x0d, 0x0f, 0x0f, 0x7f,
197cabdff1aSopenharmony_ci    0xcf, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00,
198cabdff1aSopenharmony_ci    0x06, 0x26, 0xcf, 0x05, 0xcf, 0x7f, 0xdf, 0xdf, 0x00, 0x00,
199cabdff1aSopenharmony_ci    0x17, 0x5f, 0xff, 0xfd, 0xff, 0xff, 0x46, 0x09, 0x4f, 0x5f,
200cabdff1aSopenharmony_ci    0x7f, 0xfd, 0xdf, 0xff, 0x0a, 0x88, 0xa7, 0x7f, 0x7f, 0xff,
201cabdff1aSopenharmony_ci    0xff, 0xff, 0x0f, 0x04, 0xdf, 0x7f, 0x4f, 0xff, 0x9f, 0xff,
202cabdff1aSopenharmony_ci    0x0e, 0xe6, 0xdf, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x0f, 0xec,
203cabdff1aSopenharmony_ci    0x8f, 0x4f, 0x7f, 0xff, 0xdf, 0xff, 0x0f, 0xcf, 0xdf, 0xff,
204cabdff1aSopenharmony_ci    0x6f, 0x7f, 0xff, 0xff, 0x03, 0x0c, 0x9d, 0x0f, 0x7f, 0xff,
205cabdff1aSopenharmony_ci    0xff, 0xff,
206cabdff1aSopenharmony_ci};
207cabdff1aSopenharmony_ci
208cabdff1aSopenharmony_cistatic const uint8_t g_01[] = {
209cabdff1aSopenharmony_ci    0x37, 0x73, 0x00, 0x19, 0x57, 0x7f, 0xf5, 0xfb, 0x70, 0x33,
210cabdff1aSopenharmony_ci    0xf0, 0xf9, 0x7f, 0xff, 0xff, 0xff,
211cabdff1aSopenharmony_ci};
212cabdff1aSopenharmony_ci
213cabdff1aSopenharmony_cistatic const uint8_t g_02[] = {
214cabdff1aSopenharmony_ci    0x50,
215cabdff1aSopenharmony_ci};
216cabdff1aSopenharmony_ci
217cabdff1aSopenharmony_cistatic const uint8_t g_10[] = {
218cabdff1aSopenharmony_ci    0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0xf3, 0x5f, 0x84, 0x04,
219cabdff1aSopenharmony_ci    0x17, 0x9f, 0x04, 0x23, 0x05, 0xff, 0x00, 0x00, 0x00, 0x02,
220cabdff1aSopenharmony_ci    0x03, 0x03, 0x33, 0xd7, 0x05, 0x03, 0x5f, 0x3f, 0x17, 0x33,
221cabdff1aSopenharmony_ci    0xff, 0xff, 0x00, 0x80, 0x02, 0x04, 0x12, 0x00, 0x11, 0x57,
222cabdff1aSopenharmony_ci    0x05, 0x25, 0x05, 0x03, 0x35, 0xbf, 0x9f, 0xff, 0x07, 0x6f,
223cabdff1aSopenharmony_ci    0x20, 0x40, 0x17, 0x06, 0xfa, 0xe8, 0x01, 0x07, 0x1f, 0x9f,
224cabdff1aSopenharmony_ci    0x1f, 0xff, 0xff, 0xff,
225cabdff1aSopenharmony_ci};
226cabdff1aSopenharmony_ci
227cabdff1aSopenharmony_cistatic const uint8_t g_20[] = {
228cabdff1aSopenharmony_ci    0x04, 0x00, 0x01, 0x01, 0x43, 0x2e, 0xff, 0x3f,
229cabdff1aSopenharmony_ci};
230cabdff1aSopenharmony_ci
231cabdff1aSopenharmony_cistatic const uint8_t g_30[] = {
232cabdff1aSopenharmony_ci    0x11, 0x11, 0x11, 0x11, 0x51, 0x11, 0x13, 0x11, 0x11, 0x11,
233cabdff1aSopenharmony_ci    0x13, 0x11, 0x11, 0x11, 0x33, 0x11, 0x13, 0x11, 0x13, 0x13,
234cabdff1aSopenharmony_ci    0x13, 0x13, 0x31, 0x31, 0x11, 0x01, 0x11, 0x11, 0x71, 0x11,
235cabdff1aSopenharmony_ci    0x11, 0x75,
236cabdff1aSopenharmony_ci};
237cabdff1aSopenharmony_ci
238cabdff1aSopenharmony_cistatic const uint8_t g_40[] = {
239cabdff1aSopenharmony_ci    0x00, 0x0f, 0x00, 0x09, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0f,
240cabdff1aSopenharmony_ci    0x00, 0x4e, 0xe4, 0x0d, 0x10, 0x0f, 0x00, 0x0f, 0x44, 0x4f,
241cabdff1aSopenharmony_ci    0x00, 0x1e, 0x0f, 0x0f, 0xae, 0xaf, 0x45, 0x7f, 0xef, 0xff,
242cabdff1aSopenharmony_ci    0x0f, 0xff, 0x00, 0x09, 0x01, 0x11, 0x00, 0x01, 0x1c, 0xdd,
243cabdff1aSopenharmony_ci    0x00, 0x15, 0x00, 0xff, 0x00, 0x10, 0x00, 0xfd, 0x00, 0x0f,
244cabdff1aSopenharmony_ci    0x4f, 0x5f, 0x3d, 0xff, 0xff, 0xff, 0x4f, 0xff, 0x1c, 0xff,
245cabdff1aSopenharmony_ci    0xdf, 0xff, 0x8f, 0xff, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x15,
246cabdff1aSopenharmony_ci    0x01, 0x07, 0x00, 0x01, 0x02, 0x1f, 0x01, 0x11, 0x05, 0x7f,
247cabdff1aSopenharmony_ci    0x00, 0x1f, 0x41, 0x57, 0x1f, 0xff, 0x05, 0x77, 0x0d, 0x5f,
248cabdff1aSopenharmony_ci    0x4d, 0xff, 0x4f, 0xff, 0x0f, 0xff, 0x00, 0x00, 0x02, 0x05,
249cabdff1aSopenharmony_ci    0x00, 0x11, 0x05, 0x7d, 0x10, 0x15, 0x2f, 0xff, 0x40, 0x50,
250cabdff1aSopenharmony_ci    0x0d, 0xfd, 0x04, 0x0f, 0x07, 0x1f, 0x07, 0x7f, 0x0f, 0xbf,
251cabdff1aSopenharmony_ci    0x0d, 0x7f, 0x0f, 0xff, 0x4d, 0x7d, 0x0f, 0xff,
252cabdff1aSopenharmony_ci};
253cabdff1aSopenharmony_ci
254cabdff1aSopenharmony_cistatic const uint8_t g_11[] = {
255cabdff1aSopenharmony_ci    0x01, 0x13, 0x03, 0x7f,
256cabdff1aSopenharmony_ci};
257cabdff1aSopenharmony_ci
258cabdff1aSopenharmony_cistatic const uint8_t g_21[] = {
259cabdff1aSopenharmony_ci    0x17,
260cabdff1aSopenharmony_ci};
261cabdff1aSopenharmony_ci
262cabdff1aSopenharmony_cistatic const uint8_t g_31[] = {
263cabdff1aSopenharmony_ci    0x55, 0x57, 0x57, 0x7f,
264cabdff1aSopenharmony_ci};
265cabdff1aSopenharmony_ci
266cabdff1aSopenharmony_cistatic const uint8_t g_41[] = {
267cabdff1aSopenharmony_ci    0x01, 0x01, 0x01, 0x1f, 0x03, 0x1f, 0x3f, 0xff,
268cabdff1aSopenharmony_ci};
269cabdff1aSopenharmony_ci
270cabdff1aSopenharmony_cistatic const uint8_t g_12[] = {
271cabdff1aSopenharmony_ci    0x40,
272cabdff1aSopenharmony_ci};
273cabdff1aSopenharmony_ci
274cabdff1aSopenharmony_cistatic const uint8_t g_22[] = {
275cabdff1aSopenharmony_ci    0x00,
276cabdff1aSopenharmony_ci};
277cabdff1aSopenharmony_ci
278cabdff1aSopenharmony_cistatic const uint8_t g_32[] = {
279cabdff1aSopenharmony_ci    0x10,
280cabdff1aSopenharmony_ci};
281cabdff1aSopenharmony_ci
282cabdff1aSopenharmony_cistatic const uint8_t g_42[] = {
283cabdff1aSopenharmony_ci    0x10,
284cabdff1aSopenharmony_ci};
285cabdff1aSopenharmony_ci
286cabdff1aSopenharmony_civoid ff_xface_generate_face(uint8_t *dst, uint8_t * const src)
287cabdff1aSopenharmony_ci{
288cabdff1aSopenharmony_ci    int h, i, j, k, l, m;
289cabdff1aSopenharmony_ci
290cabdff1aSopenharmony_ci    for (j = 0; j < XFACE_HEIGHT; j++) {
291cabdff1aSopenharmony_ci        for (i = 0; i < XFACE_WIDTH; i++) {
292cabdff1aSopenharmony_ci            h = i + j * XFACE_WIDTH;
293cabdff1aSopenharmony_ci            k = 0;
294cabdff1aSopenharmony_ci
295cabdff1aSopenharmony_ci            /*
296cabdff1aSopenharmony_ci               Compute k, encoding the bits *before* the current one, contained in the
297cabdff1aSopenharmony_ci               image buffer. That is, given the grid:
298cabdff1aSopenharmony_ci
299cabdff1aSopenharmony_ci                l      i
300cabdff1aSopenharmony_ci                |      |
301cabdff1aSopenharmony_ci                v      v
302cabdff1aSopenharmony_ci               +--+--+--+--+--+
303cabdff1aSopenharmony_ci          m -> | 1| 2| 3| 4| 5|
304cabdff1aSopenharmony_ci               +--+--+--+--+--+
305cabdff1aSopenharmony_ci               | 6| 7| 8| 9|10|
306cabdff1aSopenharmony_ci               +--+--+--+--+--+
307cabdff1aSopenharmony_ci          j -> |11|12| *|  |  |
308cabdff1aSopenharmony_ci               +--+--+--+--+--+
309cabdff1aSopenharmony_ci
310cabdff1aSopenharmony_ci               the value k for the pixel marked as "*" will contain the bit encoding of
311cabdff1aSopenharmony_ci               the values in the matrix marked from "1" to "12". In case the pixel is
312cabdff1aSopenharmony_ci               near the border of the grid, the number of values contained within the
313cabdff1aSopenharmony_ci               grid will be lesser than 12.
314cabdff1aSopenharmony_ci             */
315cabdff1aSopenharmony_ci
316cabdff1aSopenharmony_ci            for (l = i - 2; l <= i + 2; l++) {
317cabdff1aSopenharmony_ci                for (m = j - 2; m <= j; m++) {
318cabdff1aSopenharmony_ci                    if (l <= 0 || l >= i && m == j)
319cabdff1aSopenharmony_ci                        continue;
320cabdff1aSopenharmony_ci                    if (l <= XFACE_WIDTH && m > 0)
321cabdff1aSopenharmony_ci                        k = 2*k + src[l + m * XFACE_WIDTH];
322cabdff1aSopenharmony_ci                }
323cabdff1aSopenharmony_ci            }
324cabdff1aSopenharmony_ci
325cabdff1aSopenharmony_ci            /*
326cabdff1aSopenharmony_ci              Use the guess for the given position and the computed value of k.
327cabdff1aSopenharmony_ci
328cabdff1aSopenharmony_ci              The following table shows the number of digits in k, depending on
329cabdff1aSopenharmony_ci              the position of the pixel, and shows the corresponding guess table
330cabdff1aSopenharmony_ci              to use:
331cabdff1aSopenharmony_ci
332cabdff1aSopenharmony_ci                 i=1  i=2  i=3       i=w-1 i=w
333cabdff1aSopenharmony_ci               +----+----+----+ ... +----+----+
334cabdff1aSopenharmony_ci           j=1 |  0 |  1 |  2 |     |  2 |  2 |
335cabdff1aSopenharmony_ci               |g22 |g12 |g02 |     |g42 |g32 |
336cabdff1aSopenharmony_ci               +----+----+----+ ... +----+----+
337cabdff1aSopenharmony_ci           j=2 |  3 |  5 |  7 |     |  6 |  5 |
338cabdff1aSopenharmony_ci               |g21 |g11 |g01 |     |g41 |g31 |
339cabdff1aSopenharmony_ci               +----+----+----+ ... +----+----+
340cabdff1aSopenharmony_ci           j=3 |  5 |  9 | 12 |     | 10 |  8 |
341cabdff1aSopenharmony_ci               |g20 |g10 |g00 |     |g40 |g30 |
342cabdff1aSopenharmony_ci               +----+----+----+ ... +----+----+
343cabdff1aSopenharmony_ci            */
344cabdff1aSopenharmony_ci
345cabdff1aSopenharmony_ci#define GEN(table) dst[h] ^= (table[k>>3]>>(7-(k&7)))&1
346cabdff1aSopenharmony_ci
347cabdff1aSopenharmony_ci            switch (i) {
348cabdff1aSopenharmony_ci            case 1:
349cabdff1aSopenharmony_ci                switch (j) {
350cabdff1aSopenharmony_ci                case 1:  GEN(g_22); break;
351cabdff1aSopenharmony_ci                case 2:  GEN(g_21); break;
352cabdff1aSopenharmony_ci                default: GEN(g_20); break;
353cabdff1aSopenharmony_ci                }
354cabdff1aSopenharmony_ci                break;
355cabdff1aSopenharmony_ci            case 2:
356cabdff1aSopenharmony_ci                switch (j) {
357cabdff1aSopenharmony_ci                case 1:  GEN(g_12); break;
358cabdff1aSopenharmony_ci                case 2:  GEN(g_11); break;
359cabdff1aSopenharmony_ci                default: GEN(g_10); break;
360cabdff1aSopenharmony_ci                }
361cabdff1aSopenharmony_ci                break;
362cabdff1aSopenharmony_ci            case XFACE_WIDTH - 1:
363cabdff1aSopenharmony_ci                switch (j) {
364cabdff1aSopenharmony_ci                case 1:  GEN(g_42); break;
365cabdff1aSopenharmony_ci                case 2:  GEN(g_41); break;
366cabdff1aSopenharmony_ci                default: GEN(g_40); break;
367cabdff1aSopenharmony_ci                }
368cabdff1aSopenharmony_ci                break;
369cabdff1aSopenharmony_ci            case XFACE_WIDTH:
370cabdff1aSopenharmony_ci                switch (j) {
371cabdff1aSopenharmony_ci                case 1:  GEN(g_32); break;
372cabdff1aSopenharmony_ci                case 2:  GEN(g_31); break;
373cabdff1aSopenharmony_ci                default: GEN(g_30); break;
374cabdff1aSopenharmony_ci                }
375cabdff1aSopenharmony_ci                break;
376cabdff1aSopenharmony_ci            default:
377cabdff1aSopenharmony_ci                switch (j) {
378cabdff1aSopenharmony_ci                case 1:  GEN(g_02); break;
379cabdff1aSopenharmony_ci                case 2:  GEN(g_01); break;
380cabdff1aSopenharmony_ci                default: GEN(g_00); break;
381cabdff1aSopenharmony_ci                }
382cabdff1aSopenharmony_ci                break;
383cabdff1aSopenharmony_ci            }
384cabdff1aSopenharmony_ci        }
385cabdff1aSopenharmony_ci    }
386cabdff1aSopenharmony_ci}
387