17#include <QRegularExpression>
28#define DIGITS (PIXELS / BITSPERDIG)
30#define WORDSPERLINE (WIDTH / DIGSPERWORD / BITSPERDIG)
37#define NUMPRINTS (LASTPRINT - FIRSTPRINT + 1)
40static const int MAXLINELEN = 78;
45#define COMP unsigned long
46#define WORDCARRY (1 << BITSPERWORD)
47#define WORDMASK (WORDCARRY - 1)
52#define ERR_INTERNAL -2
58static const int MAX_XFACE_LENGTH = 2048;
60using namespace MessageViewer;
67KXFace::~KXFace() =
default;
85 xbm.remove(QStringLiteral(
"0x"));
90 for (
int i = 0;
i <
len; ++
i) {
91 switch (
tmp[
i].toLatin1()) {
146 if (!(status =
setjmp(comp_env))) {
159 if (xface.
length() > MAX_XFACE_LENGTH) {
163 char *
fbuf = (
char *)
malloc(MAX_XFACE_LENGTH);
167 if (!(status =
setjmp(comp_env))) {
182void KXFace::RevPush(
const Prob *p)
184 if (NumProbs >= PIXELS * 2 - 1) {
185 longjmp(comp_env, ERR_INTERNAL);
187 ProbBuf[NumProbs++] = (Prob *)p;
190void KXFace::BigPush(Prob *p)
192 static unsigned char tmp;
194 BigDiv(p->p_range, &
tmp);
196 BigAdd(
tmp + p->p_offset);
199int KXFace::BigPop(
const Prob *p)
201 static unsigned char tmp;
211 BigAdd(
tmp - p->p_offset);
218void KXFace::BigDiv(
unsigned char a,
unsigned char *r)
225 if ((a == 1) || (B.b_words == 0)) {
241 w = B.b_word + (
i = B.b_words);
248 *w = (
unsigned char)(d & WORDMASK);
251 if (B.b_word[B.b_words - 1] == 0) {
258void KXFace::BigMul(
unsigned char a)
265 if ((a == 1) || (B.b_words == 0)) {
270 if ((
i = B.b_words++) >= MAXWORDS - 1) {
271 longjmp(comp_env, ERR_INTERNAL);
285 c += (COMP)*w * (COMP)a;
286 *(w++) = (
unsigned char)(c & WORDMASK);
290 if (B.b_words++ >= MAXWORDS) {
291 longjmp(comp_env, ERR_INTERNAL);
293 *w = (COMP)(c & WORDMASK);
299void KXFace::BigAdd(
unsigned char a)
312 while ((
i < B.b_words) && c) {
314 *w++ = (
unsigned char)(c & WORDMASK);
318 if ((
i == B.b_words) && c) {
319 if (B.b_words++ >= MAXWORDS) {
320 longjmp(comp_env, ERR_INTERNAL);
322 *w = (COMP)(c & WORDMASK);
326void KXFace::BigClear()
341 QByteArray t(
"#define noname_width 48\n#define noname_height 48\nstatic char noname_bits[] = {\n ");
346 t.resize(MAX_XFACE_LENGTH);
349 while (
s < F + PIXELS) {
350 if ((bits == 0) && (
digits == 0)) {
359 if (++bits == BITSPERDIG) {
361 t[
j - ((
digits & 1) * 2)] = *(
i + HexDigits);
364 if (
s >= F + PIXELS) {
382void KXFace::UnCompAll(
char *fbuf)
389 while (p < F + PIXELS) {
392 UnCompress(F, 16, 16, 0);
393 UnCompress(F + 16, 16, 16, 0);
394 UnCompress(F + 32, 16, 16, 0);
395 UnCompress(F + WIDTH * 16, 16, 16, 0);
396 UnCompress(F + WIDTH * 16 + 16, 16, 16, 0);
397 UnCompress(F + WIDTH * 16 + 32, 16, 16, 0);
398 UnCompress(F + WIDTH * 32, 16, 16, 0);
399 UnCompress(F + WIDTH * 32 + 16, 16, 16, 0);
400 UnCompress(F + WIDTH * 32 + 32, 16, 16, 0);
403void KXFace::UnCompress(
char *f,
int wid,
int hei,
int lev)
405 switch (BigPop(&levels[
lev][0])) {
423void KXFace::BigWrite(
char *fbuf)
425 static unsigned char tmp;
426 static char buf[DIGITS];
431 while (B.b_words > 0) {
432 BigDiv(NUMPRINTS, &
tmp);
433 *(
s++) =
tmp + FIRSTPRINT;
442 if (++
i >= MAXLINELEN) {
453void KXFace::BigRead(
char *fbuf)
457 while (*
fbuf !=
'\0') {
459 if ((c < FIRSTPRINT) || (c > LASTPRINT)) {
463 BigAdd((
unsigned char)(c - FIRSTPRINT));
467void KXFace::ReadFace(
char *fbuf)
477 if ((c >=
'0') && (c <=
'9')) {
478 if (
t >=
fbuf + DIGITS) {
483 }
else if ((c >=
'A') && (c <=
'F')) {
484 if (
t >=
fbuf + DIGITS) {
488 *(
t++) = c -
'A' + 10;
489 }
else if ((c >=
'a') && (c <=
'f')) {
490 if (
t >=
fbuf + DIGITS) {
494 *(
t++) = c -
'a' + 10;
495 }
else if (((c ==
'x') || (c ==
'X')) && (
t >
fbuf) && (*(
t - 1) == 0)) {
499 if (
t <
fbuf + DIGITS) {
504 c = 1 << (BITSPERDIG - 1);
505 while (
t < F + PIXELS) {
506 *(
t++) = (*
s & c) ? 1 : 0;
507 if ((c >>= 1) == 0) {
509 c = 1 << (BITSPERDIG - 1);
514void KXFace::GenFace()
516 static char newp[PIXELS];
530void KXFace::UnGenFace()
536void KXFace::Gen(
char *f)
545 for (
j = 0;
j < HEIGHT; ++
j) {
546 for (
i = 0;
i < WIDTH; ++
i) {
549 for (l =
i - 2; l <=
i + 2; ++l) {
550 for (
m =
j - 2;
m <=
j; ++
m) {
551 if ((l >=
i) && (
m ==
j)) {
554 if ((l > 0) && (l <= WIDTH) && (
m > 0)) {
555 k = *(
f + l +
m * WIDTH) ?
k * 2 + 1 :
k * 2;
616void KXFace::PopGreys(
char *f,
int wid,
int hei)
637 *(
f + WIDTH + 1) = 1;
642void KXFace::CompAll(
char *fbuf)
644 Compress(F, 16, 16, 0);
645 Compress(F + 16, 16, 16, 0);
646 Compress(F + 32, 16, 16, 0);
647 Compress(F + WIDTH * 16, 16, 16, 0);
648 Compress(F + WIDTH * 16 + 16, 16, 16, 0);
649 Compress(F + WIDTH * 16 + 32, 16, 16, 0);
650 Compress(F + WIDTH * 32, 16, 16, 0);
651 Compress(F + WIDTH * 32 + 16, 16, 16, 0);
652 Compress(F + WIDTH * 32 + 32, 16, 16, 0);
654 while (NumProbs > 0) {
655 BigPush(ProbBuf[--NumProbs]);
660void KXFace::Compress(
char *f,
int wid,
int hei,
int lev)
663 RevPush(&levels[
lev][WHITE]);
667 RevPush(&levels[
lev][BLACK]);
671 RevPush(&levels[
lev][GREY]);
681int KXFace::AllWhite(
char *f,
int wid,
int hei)
683 return (*
f == 0) && Same(
f,
wid,
hei);
686int KXFace::AllBlack(
char *f,
int wid,
int hei)
693 return *
f || *(
f + 1) || *(
f + WIDTH) || *(
f + WIDTH + 1);
697int KXFace::Same(
char *f,
int wid,
int hei)
708 if (*(row++) !=
val) {
717void KXFace::PushGreys(
char *f,
int wid,
int hei)
727 RevPush(freqs + *
f + 2 * *(
f + 1) + 4 * *(
f + WIDTH) + 8 * *(
f + WIDTH + 1));
731#include "moc_kxface.cpp"
QString fromImage(const QImage &image)
generates the xface string from image
QImage toImage(const QString &xface)
creates a pixmap from xface
virtual bool open(OpenMode flags) override
const char * constData() const const
bool isNull() const const
bool loadFromData(QByteArrayView data, const char *format)
QImage scaled(const QSize &size, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformMode) const const
T qobject_cast(QObject *object)
QString fromLatin1(QByteArrayView str)
qsizetype length() const const
QByteArray toLatin1() const const