diff options
Diffstat (limited to 'libkdepim/kxface.cpp')
-rw-r--r-- | libkdepim/kxface.cpp | 729 |
1 files changed, 0 insertions, 729 deletions
diff --git a/libkdepim/kxface.cpp b/libkdepim/kxface.cpp deleted file mode 100644 index 210fefb5f..000000000 --- a/libkdepim/kxface.cpp +++ /dev/null @@ -1,729 +0,0 @@ -/* - This file is part of libtdepim. - - Original compface: - Copyright (c) James Ashton - Sydney University - June 1990. - - Additions for KDE: - Copyright (c) 2004 Jakob Schröter <js@camaya.net> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "kxface.h" - -#include <kdebug.h> - -#include <tqbuffer.h> -#include <tqcstring.h> -#include <tqimage.h> -#include <tqregexp.h> -#include <tqstring.h> -#include <tqpainter.h> - -#include <stdlib.h> -#include <string.h> - -#define GEN(g) F[h] ^= G.g[k]; break - -#define BITSPERDIG 4 -#define DIGITS (PIXELS / BITSPERDIG) -#define DIGSPERWORD 4 -#define WORDSPERLINE (WIDTH / DIGSPERWORD / BITSPERDIG) - -/* compressed output uses the full range of printable characters. - * in ascii these are in a contiguous block so we just need to know - * the first and last. The total number of printables is needed too */ -#define FIRSTPRINT '!' -#define LASTPRINT '~' -#define NUMPRINTS (LASTPRINT - FIRSTPRINT + 1) - -/* output line length for compressed data */ -#define MAXLINELEN 78 - -/* Portable, very large unsigned integer arithmetic is needed. - * Implementation uses arrays of WORDs. COMPs must have at least - * twice as many bits as WORDs to handle intermediate results */ -#define COMP unsigned long -#define WORDCARRY (1 << BITSPERWORD) -#define WORDMASK (WORDCARRY - 1) - -#define ERR_OK 0 /* successful completion */ -#define ERR_EXCESS 1 /* completed OK but some input was ignored */ -#define ERR_INSUFF -1 /* insufficient input. Bad face format? */ -#define ERR_INTERNAL -2 /* Arithmetic overflow or buffer overflow */ - -#define BLACK 0 -#define GREY 1 -#define WHITE 2 - -#define MAX_XFACE_LENGTH 2048 - -using namespace KPIM; - -KXFace::KXFace() -{ - NumProbs = 0; -} - -KXFace::~KXFace() -{ -} - -TQString KXFace::fromImage( const TQImage &image ) -{ - if( image.isNull() ) - return TQString(); - - TQImage scaledImg = image.smoothScale( 48, 48 ); - TQByteArray ba; - TQBuffer buffer( ba ); - buffer.open( IO_WriteOnly ); - scaledImg.save( &buffer, "XBM" ); - TQString xbm( ba ); - xbm.remove( 0, xbm.find( "{" ) + 1 ); - xbm.truncate( xbm.find( "}" ) ); - xbm.remove( " " ); - xbm.remove( "," ); - xbm.remove( "0x" ); - xbm.remove( "\n" ); - xbm.truncate( 576 ); - TQCString tmp = TQCString( xbm.latin1() ); - uint len = tmp.length(); - for( uint i=0; i<len; ++i ) - { - switch( tmp[i] ) - { - case '1': tmp[i] = '8'; break; - case '2': tmp[i] = '4'; break; - case '3': tmp[i] = 'c'; break; - case '4': tmp[i] = '2'; break; - case '5': tmp[i] = 'a'; break; - case '7': tmp[i] = 'e'; break; - case '8': tmp[i] = '1'; break; - case 'A': - case 'a': tmp[i] = '5'; break; - case 'B': - case 'b': tmp[i] = 'd'; break; - case 'C': - case 'c': tmp[i] = '3'; break; - case 'D': - case 'd': tmp[i] = 'b'; break; - case 'E': - case 'e': tmp[i] = '7'; break; - } - if ( i % 2 ) - { - char t = tmp[i]; - tmp[i] = tmp[i-1]; - tmp[i-1] = t; - } - } - tmp.replace( TQRegExp( "(\\w{12})" ), "\\1\n" ); - tmp.replace( TQRegExp( "(\\w{4})" ), "0x\\1," ); - len = tmp.length(); - char *fbuf = (char *)malloc( len + 1 ); - strncpy( fbuf, (const char *)tmp, len ); - fbuf[len] = '\0'; - if ( !( status = setjmp( comp_env ) ) ) - { - ReadFace( fbuf ); - GenFace(); - CompAll( fbuf ); - } - TQString ret( fbuf ); - free( fbuf ); - - return ret; -} - -TQImage KXFace::toImage(const TQString &xface) -{ - if ( xface.length() > MAX_XFACE_LENGTH ) - return TQImage(); - - char *fbuf = (char *)malloc( MAX_XFACE_LENGTH ); - memset( fbuf, '\0', MAX_XFACE_LENGTH ); - strncpy( fbuf, xface.latin1(), xface.length() ); - TQCString img; - if ( !( status = setjmp( comp_env ) ) ) - { - UnCompAll( fbuf );/* compress otherwise */ - UnGenFace(); - img = WriteFace(); - } - free( fbuf ); - TQImage p; - p.loadFromData( img, "XBM" ); - - return p; -} - -//============================================================================ -// more or less original compface 1.4 source - -void KXFace::RevPush(const Prob *p) -{ - if (NumProbs >= PIXELS * 2 - 1) - longjmp(comp_env, ERR_INTERNAL); - ProbBuf[NumProbs++] = (Prob *) p; -} - -void KXFace::BigPush(Prob *p) -{ - static unsigned char tmp; - - BigDiv(p->p_range, &tmp); - BigMul(0); - BigAdd(tmp + p->p_offset); -} - -int KXFace::BigPop(register const Prob *p) -{ - static unsigned char tmp; - register int i; - - BigDiv(0, &tmp); - i = 0; - while ((tmp < p->p_offset) || (tmp >= p->p_range + p->p_offset)) - { - p++; - i++; - } - BigMul(p->p_range); - BigAdd(tmp - p->p_offset); - return i; -} - - -/* Divide B by a storing the result in B and the remainder in the word - * pointer to by r - */ -void KXFace::BigDiv(register unsigned char a, register unsigned char *r) -{ - register int i; - register unsigned char *w; - register COMP c, d; - - a &= WORDMASK; - if ((a == 1) || (B.b_words == 0)) - { - *r = 0; - return; - } - if (a == 0) /* treat this as a == WORDCARRY */ - { /* and just shift everything right a WORD (unsigned char)*/ - i = --B.b_words; - w = B.b_word; - *r = *w; - while (i--) - { - *w = *(w + 1); - w++; - } - *w = 0; - return; - } - w = B.b_word + (i = B.b_words); - c = 0; - while (i--) - { - c <<= BITSPERWORD; - c += (COMP)*--w; - d = c / (COMP)a; - c = c % (COMP)a; - *w = (unsigned char)(d & WORDMASK); - } - *r = c; - if (B.b_word[B.b_words - 1] == 0) - B.b_words--; -} - -/* Multiply a by B storing the result in B - */ -void KXFace::BigMul(register unsigned char a) -{ - register int i; - register unsigned char *w; - register COMP c; - - a &= WORDMASK; - if ((a == 1) || (B.b_words == 0)) - return; - if (a == 0) /* treat this as a == WORDCARRY */ - { /* and just shift everything left a WORD (unsigned char) */ - if ((i = B.b_words++) >= MAXWORDS - 1) - longjmp(comp_env, ERR_INTERNAL); - w = B.b_word + i; - while (i--) - { - *w = *(w - 1); - w--; - } - *w = 0; - return; - } - i = B.b_words; - w = B.b_word; - c = 0; - while (i--) - { - c += (COMP)*w * (COMP)a; - *(w++) = (unsigned char)(c & WORDMASK); - c >>= BITSPERWORD; - } - if (c) - { - if (B.b_words++ >= MAXWORDS) - longjmp(comp_env, ERR_INTERNAL); - *w = (COMP)(c & WORDMASK); - } -} - -/* Add to a to B storing the result in B - */ -void KXFace::BigAdd(unsigned char a) -{ - register int i; - register unsigned char *w; - register COMP c; - - a &= WORDMASK; - if (a == 0) - return; - i = 0; - w = B.b_word; - c = a; - while ((i < B.b_words) && c) - { - c += (COMP)*w; - *w++ = (unsigned char)(c & WORDMASK); - c >>= BITSPERWORD; - i++; - } - if ((i == B.b_words) && c) - { - if (B.b_words++ >= MAXWORDS) - longjmp(comp_env, ERR_INTERNAL); - *w = (COMP)(c & WORDMASK); - } -} - -void KXFace::BigClear() -{ - B.b_words = 0; -} - -TQCString KXFace::WriteFace() -{ - register char *s; - register int i, j, bits, digits, words; - int digsperword = DIGSPERWORD; - int wordsperline = WORDSPERLINE; - TQCString t( "#define noname_width 48\n#define noname_height 48\nstatic char noname_bits[] = {\n " ); - j = t.length() - 1; - - s = F; - bits = digits = words = i = 0; - t.resize( MAX_XFACE_LENGTH ); - digsperword = 2; - wordsperline = 15; - while ( s < F + PIXELS ) - { - if ( ( bits == 0 ) && ( digits == 0 ) ) - { - t[j++] = '0'; - t[j++] = 'x'; - } - if ( *(s++) ) - i = ( i >> 1 ) | 0x8; - else - i >>= 1; - if ( ++bits == BITSPERDIG ) - { - j++; - t[j-( ( digits & 1 ) * 2 )] = *(i + HexDigits); - bits = i = 0; - if ( ++digits == digsperword ) - { - if ( s >= F + PIXELS ) - break; - t[j++] = ','; - digits = 0; - if ( ++words == wordsperline ) - { - t[j++] = '\n'; - t[j++] = ' '; - words = 0; - } - } - } - } - t.resize( j + 1 ); - t += "};\n"; - return t; -} - -void KXFace::UnCompAll(char *fbuf) -{ - register char *p; - - BigClear(); - BigRead(fbuf); - p = F; - while (p < F + PIXELS) - *(p++) = 0; - UnCompress(F, 16, 16, 0); - UnCompress(F + 16, 16, 16, 0); - UnCompress(F + 32, 16, 16, 0); - UnCompress(F + WIDTH * 16, 16, 16, 0); - UnCompress(F + WIDTH * 16 + 16, 16, 16, 0); - UnCompress(F + WIDTH * 16 + 32, 16, 16, 0); - UnCompress(F + WIDTH * 32, 16, 16, 0); - UnCompress(F + WIDTH * 32 + 16, 16, 16, 0); - UnCompress(F + WIDTH * 32 + 32, 16, 16, 0); -} - -void KXFace::UnCompress(char *f, int wid, int hei, int lev) -{ - switch (BigPop(&levels[lev][0])) - { - case WHITE : - return; - case BLACK : - PopGreys(f, wid, hei); - return; - default : - wid /= 2; - hei /= 2; - lev++; - UnCompress(f, wid, hei, lev); - UnCompress(f + wid, wid, hei, lev); - UnCompress(f + hei * WIDTH, wid, hei, lev); - UnCompress(f + wid + hei * WIDTH, wid, hei, lev); - return; - } -} - -void KXFace::BigWrite(register char *fbuf) -{ - static unsigned char tmp; - static char buf[DIGITS]; - register char *s; - register int i; - - s = buf; - while (B.b_words > 0) - { - BigDiv(NUMPRINTS, &tmp); - *(s++) = tmp + FIRSTPRINT; - } - i = 7; // leave room for the field name on the first line - *(fbuf++) = ' '; - while (s-- > buf) - { - if (i == 0) - *(fbuf++) = ' '; - *(fbuf++) = *s; - if (++i >= MAXLINELEN) - { - *(fbuf++) = '\n'; - i = 0; - } - } - if (i > 0) - *(fbuf++) = '\n'; - *(fbuf++) = '\0'; -} - -void KXFace::BigRead(register char *fbuf) -{ - register int c; - - while (*fbuf != '\0') - { - c = *(fbuf++); - if ((c < FIRSTPRINT) || (c > LASTPRINT)) - continue; - BigMul(NUMPRINTS); - BigAdd((unsigned char)(c - FIRSTPRINT)); - } -} - -void KXFace::ReadFace(char *fbuf) -{ - register int c, i; - register char *s, *t; - - t = s = fbuf; - for(i = strlen(s); i > 0; i--) - { - c = (int)*(s++); - if ((c >= '0') && (c <= '9')) - { - if (t >= fbuf + DIGITS) - { - status = ERR_EXCESS; - break; - } - *(t++) = c - '0'; - } - else if ((c >= 'A') && (c <= 'F')) - { - if (t >= fbuf + DIGITS) - { - status = ERR_EXCESS; - break; - } - *(t++) = c - 'A' + 10; - } - else if ((c >= 'a') && (c <= 'f')) - { - if (t >= fbuf + DIGITS) - { - status = ERR_EXCESS; - break; - } - *(t++) = c - 'a' + 10; - } - else if (((c == 'x') || (c == 'X')) && (t > fbuf) && (*(t-1) == 0)) - t--; - } - if (t < fbuf + DIGITS) - longjmp(comp_env, ERR_INSUFF); - s = fbuf; - t = F; - c = 1 << (BITSPERDIG - 1); - while (t < F + PIXELS) - { - *(t++) = (*s & c) ? 1 : 0; - if ((c >>= 1) == 0) - { - s++; - c = 1 << (BITSPERDIG - 1); - } - } -} - -void KXFace::GenFace() -{ - static char newp[PIXELS]; - register char *f1; - register char *f2; - register int i; - - f1 = newp; - f2 = F; - i = PIXELS; - while (i-- > 0) - *(f1++) = *(f2++); - Gen(newp); -} - -void KXFace::UnGenFace() -{ - Gen(F); -} - -// static -void KXFace::Gen(register char *f) -{ - register int m, l, k, j, i, h; - - for (j = 0; j < HEIGHT; j++) - { - for (i = 0; i < WIDTH; i++) - { - h = i + j * WIDTH; - k = 0; - for (l = i - 2; l <= i + 2; l++) - for (m = j - 2; m <= j; m++) - { - if ((l >= i) && (m == j)) - continue; - if ((l > 0) && (l <= WIDTH) && (m > 0)) - k = *(f + l + m * WIDTH) ? k * 2 + 1 : k * 2; - } - switch (i) - { - case 1 : - switch (j) - { - case 1 : GEN(g_22); - case 2 : GEN(g_21); - default : GEN(g_20); - } - break; - case 2 : - switch (j) - { - case 1 : GEN(g_12); - case 2 : GEN(g_11); - default : GEN(g_10); - } - break; - case WIDTH - 1 : - switch (j) - { - case 1 : GEN(g_42); - case 2 : GEN(g_41); - default : GEN(g_40); - } - break; - /* i runs from 0 to WIDTH-1, so case can never occur. I leave the code in - because it appears exactly like this in the original compface code. - case WIDTH : - switch (j) - { - case 1 : GEN(g_32); - case 2 : GEN(g_31); - default : GEN(g_30); - } - break; - */ - default : - switch (j) - { - case 1 : GEN(g_02); - case 2 : GEN(g_01); - default : GEN(g_00); - } - break; - } - } - } -} - -void KXFace::PopGreys(char *f, int wid, int hei) -{ - if (wid > 3) - { - wid /= 2; - hei /= 2; - PopGreys(f, wid, hei); - PopGreys(f + wid, wid, hei); - PopGreys(f + WIDTH * hei, wid, hei); - PopGreys(f + WIDTH * hei + wid, wid, hei); - } - else - { - wid = BigPop(freqs); - if (wid & 1) - *f = 1; - if (wid & 2) - *(f + 1) = 1; - if (wid & 4) - *(f + WIDTH) = 1; - if (wid & 8) - *(f + WIDTH + 1) = 1; - } -} - -void KXFace::CompAll(char *fbuf) -{ - Compress(F, 16, 16, 0); - Compress(F + 16, 16, 16, 0); - Compress(F + 32, 16, 16, 0); - Compress(F + WIDTH * 16, 16, 16, 0); - Compress(F + WIDTH * 16 + 16, 16, 16, 0); - Compress(F + WIDTH * 16 + 32, 16, 16, 0); - Compress(F + WIDTH * 32, 16, 16, 0); - Compress(F + WIDTH * 32 + 16, 16, 16, 0); - Compress(F + WIDTH * 32 + 32, 16, 16, 0); - BigClear(); - while (NumProbs > 0) - BigPush(ProbBuf[--NumProbs]); - BigWrite(fbuf); -} - -void KXFace::Compress(register char *f, register int wid, register int hei, register int lev) -{ - if (AllWhite(f, wid, hei)) - { - RevPush(&levels[lev][WHITE]); - return; - } - if (AllBlack(f, wid, hei)) - { - RevPush(&levels[lev][BLACK]); - PushGreys(f, wid, hei); - return; - } - RevPush(&levels[lev][GREY]); - wid /= 2; - hei /= 2; - lev++; - Compress(f, wid, hei, lev); - Compress(f + wid, wid, hei, lev); - Compress(f + hei * WIDTH, wid, hei, lev); - Compress(f + wid + hei * WIDTH, wid, hei, lev); -} - -int KXFace::AllWhite(char *f, int wid, int hei) -{ - return ((*f == 0) && Same(f, wid, hei)); -} - -int KXFace::AllBlack(char *f, int wid, int hei) -{ - if (wid > 3) - { - wid /= 2; - hei /= 2; - return (AllBlack(f, wid, hei) && AllBlack(f + wid, wid, hei) && - AllBlack(f + WIDTH * hei, wid, hei) && - AllBlack(f + WIDTH * hei + wid, wid, hei)); - } - else - return (*f || *(f + 1) || *(f + WIDTH) || *(f + WIDTH + 1)); -} - -int KXFace::Same(register char *f, register int wid, register int hei) -{ - register char val, *row; - register int x; - - val = *f; - while (hei--) - { - row = f; - x = wid; - while (x--) - if (*(row++) != val) - return(0); - f += WIDTH; - } - return 1; -} - -void KXFace::PushGreys(char *f, int wid, int hei) -{ - if (wid > 3) - { - wid /= 2; - hei /= 2; - PushGreys(f, wid, hei); - PushGreys(f + wid, wid, hei); - PushGreys(f + WIDTH * hei, wid, hei); - PushGreys(f + WIDTH * hei + wid, wid, hei); - } - else - RevPush(freqs + *f + 2 * *(f + 1) + 4 * *(f + WIDTH) + - 8 * *(f + WIDTH + 1)); -} - - -#include "kxface.moc" |