41 #define GEN(g) F[h] ^= G.g[k]; break
44 #define DIGITS (PIXELS / BITSPERDIG)
46 #define WORDSPERLINE (WIDTH / DIGSPERWORD / BITSPERDIG)
51 #define FIRSTPRINT '!'
53 #define NUMPRINTS (LASTPRINT - FIRSTPRINT + 1)
61 #define COMP unsigned long
62 #define WORDCARRY (1 << BITSPERWORD)
63 #define WORDMASK (WORDCARRY - 1)
68 #define ERR_INTERNAL -2
76 using namespace MessageViewer;
92 QImage scaledImg = image.scaled( 48, 48, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
94 QBuffer buffer( &ba,
this );
95 buffer.open( QIODevice::WriteOnly );
96 scaledImg.save( &buffer,
"XBM" );
97 QString xbm( QString::fromLatin1(ba) );
98 xbm.remove( 0, xbm.indexOf( QLatin1String(
"{") ) + 1 );
99 xbm.truncate( xbm.indexOf( QLatin1String(
"}") ) );
100 xbm.remove( QLatin1Char(
' ') );
101 xbm.remove( QLatin1Char(
',') );
102 xbm.remove( QLatin1String(
"0x") );
103 xbm.remove( QLatin1Char(
'\n') );
105 QString tmp = QLatin1String(xbm.toLatin1());
106 int len = tmp.length();
107 for(
int i=0; i<len; ++i )
109 switch( tmp[i].toLatin1() )
111 case '1': tmp[i] =
'8';
break;
112 case '2': tmp[i] =
'4';
break;
113 case '3': tmp[i] =
'c';
break;
114 case '4': tmp[i] =
'2';
break;
115 case '5': tmp[i] =
'a';
break;
116 case '7': tmp[i] =
'e';
break;
117 case '8': tmp[i] =
'1';
break;
119 case 'a': tmp[i] =
'5';
break;
121 case 'b': tmp[i] =
'd';
break;
123 case 'c': tmp[i] =
'3';
break;
125 case 'd': tmp[i] =
'b';
break;
127 case 'e': tmp[i] =
'7';
break;
136 tmp.replace( QRegExp( QLatin1String(
"(\\w{12})") ), QLatin1String(
"\\1\n") );
137 tmp.replace( QRegExp( QLatin1String(
"(\\w{4})") ), QLatin1String(
"0x\\1,") );
139 char *fbuf = (
char *)malloc( len + 1 );
140 strncpy( fbuf, (
const char *)tmp.toLatin1(), len );
142 if ( !( status = setjmp( comp_env ) ) )
148 QString ret( QString::fromLatin1(fbuf) );
161 strncpy( fbuf, xface.toLatin1(), xface.length() );
163 if ( !( status = setjmp( comp_env ) ) )
171 p.loadFromData( img,
"XBM" );
179 void KXFace::RevPush(
const Prob *p)
181 if (NumProbs >= PIXELS * 2 - 1)
183 ProbBuf[NumProbs++] = (
Prob *) p;
186 void KXFace::BigPush(
Prob *p)
188 static unsigned char tmp;
195 int KXFace::BigPop(
register const Prob *p)
197 static unsigned char tmp;
216 void KXFace::BigDiv(
register unsigned char a,
register unsigned char *r)
219 register unsigned char *w;
223 if ((a == 1) || (B.b_words == 0))
241 w = B.b_word + (i = B.b_words);
252 if (B.b_word[B.b_words - 1] == 0)
258 void KXFace::BigMul(
register unsigned char a)
261 register unsigned char *w;
265 if ((a == 1) || (B.b_words == 0))
269 if ((i = B.b_words++) >= MAXWORDS - 1)
286 *(w++) = (
unsigned char)(c &
WORDMASK);
291 if (B.b_words++ >= MAXWORDS)
299 void KXFace::BigAdd(
unsigned char a)
302 register unsigned char *w;
311 while ((i < B.b_words) && c)
314 *w++ = (
unsigned char)(c &
WORDMASK);
318 if ((i == B.b_words) && c)
320 if (B.b_words++ >= MAXWORDS)
326 void KXFace::BigClear()
331 QByteArray KXFace::WriteFace()
334 register int i, j, bits, digits, words;
337 QByteArray t(
"#define noname_width 48\n#define noname_height 48\nstatic char noname_bits[] = {\n " );
341 bits = digits = words = i = 0;
344 int wordsperline = 15;
345 while ( s < F + PIXELS )
347 if ( ( bits == 0 ) && ( digits == 0 ) )
353 i = ( i >> 1 ) | 0x8;
359 t[j-( ( digits & 1 ) * 2 )] = *(i +
HexDigits);
361 if ( ++digits == digsperword )
363 if ( s >= F + PIXELS )
367 if ( ++words == wordsperline )
381 void KXFace::UnCompAll(
char *fbuf)
388 while (p < F + PIXELS)
390 UnCompress(F, 16, 16, 0);
391 UnCompress(F + 16, 16, 16, 0);
392 UnCompress(F + 32, 16, 16, 0);
393 UnCompress(F + WIDTH * 16, 16, 16, 0);
394 UnCompress(F + WIDTH * 16 + 16, 16, 16, 0);
395 UnCompress(F + WIDTH * 16 + 32, 16, 16, 0);
396 UnCompress(F + WIDTH * 32, 16, 16, 0);
397 UnCompress(F + WIDTH * 32 + 16, 16, 16, 0);
398 UnCompress(F + WIDTH * 32 + 32, 16, 16, 0);
401 void KXFace::UnCompress(
char *f,
int wid,
int hei,
int lev)
403 switch (BigPop(&
levels[lev][0]))
408 PopGreys(f, wid, hei);
414 UnCompress(f, wid, hei, lev);
415 UnCompress(f + wid, wid, hei, lev);
416 UnCompress(f + hei * WIDTH, wid, hei, lev);
417 UnCompress(f + wid + hei * WIDTH, wid, hei, lev);
422 void KXFace::BigWrite(
register char *fbuf)
424 static unsigned char tmp;
430 while (B.b_words > 0)
453 void KXFace::BigRead(
register char *fbuf)
457 while (*fbuf !=
'\0')
467 void KXFace::ReadFace(
char *fbuf)
470 register char *s, *t;
473 for(i = strlen(s); i > 0; --i)
476 if ((c >=
'0') && (c <=
'9'))
485 else if ((c >=
'A') && (c <=
'F'))
492 *(t++) = c -
'A' + 10;
494 else if ((c >=
'a') && (c <=
'f'))
501 *(t++) = c -
'a' + 10;
503 else if (((c ==
'x') || (c ==
'X')) && (t > fbuf) && (*(t-1) == 0))
511 while (t < F + PIXELS)
513 *(t++) = (*s & c) ? 1 : 0;
522 void KXFace::GenFace()
524 static char newp[PIXELS];
537 void KXFace::UnGenFace()
543 void KXFace::Gen(
register char *f)
545 register int m, l, k, j, i, h;
547 for (j = 0; j < HEIGHT; ++j)
549 for (i = 0; i < WIDTH; ++i)
553 for (l = i - 2; l <= i + 2; ++l)
554 for (m = j - 2; m <= j; ++m)
556 if ((l >= i) && (m == j))
558 if ((l > 0) && (l <= WIDTH) && (m > 0))
559 k = *(f + l + m * WIDTH) ? k * 2 + 1 : k * 2;
611 void KXFace::PopGreys(
char *f,
int wid,
int hei)
617 PopGreys(f, wid, hei);
618 PopGreys(f + wid, wid, hei);
619 PopGreys(f + WIDTH * hei, wid, hei);
620 PopGreys(f + WIDTH * hei + wid, wid, hei);
632 *(f + WIDTH + 1) = 1;
636 void KXFace::CompAll(
char *fbuf)
638 Compress(F, 16, 16, 0);
639 Compress(F + 16, 16, 16, 0);
640 Compress(F + 32, 16, 16, 0);
641 Compress(F + WIDTH * 16, 16, 16, 0);
642 Compress(F + WIDTH * 16 + 16, 16, 16, 0);
643 Compress(F + WIDTH * 16 + 32, 16, 16, 0);
644 Compress(F + WIDTH * 32, 16, 16, 0);
645 Compress(F + WIDTH * 32 + 16, 16, 16, 0);
646 Compress(F + WIDTH * 32 + 32, 16, 16, 0);
649 BigPush(ProbBuf[--NumProbs]);
653 void KXFace::Compress(
register char *f,
register int wid,
register int hei,
register int lev)
655 if (AllWhite(f, wid, hei))
660 if (AllBlack(f, wid, hei))
663 PushGreys(f, wid, hei);
670 Compress(f, wid, hei, lev);
671 Compress(f + wid, wid, hei, lev);
672 Compress(f + hei * WIDTH, wid, hei, lev);
673 Compress(f + wid + hei * WIDTH, wid, hei, lev);
676 int KXFace::AllWhite(
char *f,
int wid,
int hei)
678 return ((*f == 0) && Same(f, wid, hei));
681 int KXFace::AllBlack(
char *f,
int wid,
int hei)
687 return (AllBlack(f, wid, hei) && AllBlack(f + wid, wid, hei) &&
688 AllBlack(f + WIDTH * hei, wid, hei) &&
689 AllBlack(f + WIDTH * hei + wid, wid, hei));
692 return (*f || *(f + 1) || *(f + WIDTH) || *(f + WIDTH + 1));
695 int KXFace::Same(
register char *f,
register int wid,
register int hei)
697 register char val, *row;
713 void KXFace::PushGreys(
char *f,
int wid,
int hei)
719 PushGreys(f, wid, hei);
720 PushGreys(f + wid, wid, hei);
721 PushGreys(f + WIDTH * hei, wid, hei);
722 PushGreys(f + WIDTH * hei + wid, wid, hei);
725 RevPush(
freqs + *f + 2 * *(f + 1) + 4 * *(f + WIDTH) +
726 8 * *(f + WIDTH + 1));
730 #include "kxface.moc"
static const int MAXLINELEN
static const Prob freqs[16]
QImage toImage(const QString &xface)
creates a pixmap from xface
static const int MAX_XFACE_LENGTH
QString fromImage(const QImage &image)
generates the xface string from image
static const Prob levels[4][3]
static const char HexDigits[]