diff -Nur old/kmail/headerstyle.cpp new/kmail/headerstyle.cpp
--- old/kmail/headerstyle.cpp	Wed Nov 17 00:49:06 2004
+++ new/kmail/headerstyle.cpp	Wed Nov 17 01:05:07 2004
@@ -41,6 +41,8 @@
 #include "kmkernel.h"
 
 #include <libemailfunctions/email.h>
+#include <libkdepim/kxface.h>
+using namespace KPIM;
 
 #include <mimelib/string.h>
 #include <mimelib/field.h>
@@ -55,6 +57,7 @@
 #include <kmdcodec.h>
 #include <qdatetime.h>
 #include <qbuffer.h>
+#include <qbitmap.h>
 #include <qimage.h>
 #include <qapplication.h>
 #include <qregexp.h>
@@ -392,6 +395,9 @@
     KABC::AddressBook *addressBook = KABC::StdAddressBook::self();
     KABC::AddresseeList addresses = addressBook->findByEmail( KPIM::getEmailAddr( message->from() ) );
 
+    QString photoURL;
+    int photoWidth = 60;
+    int photoHeight = 60;
     if( addresses.count() == 1 )
     {
       // kabcUid is embedded in im: URIs to indicate which IM contact to message
@@ -408,9 +414,6 @@
           }
       }
       // picture
-      QString photoURL;
-      int photoWidth = 60;
-      int photoHeight = 60;
       if ( addresses[0].photo().isIntern() )
       {
         // get photo data and convert to data: url
@@ -437,37 +440,54 @@
         if ( photoURL.startsWith("/") )
           photoURL.prepend( "file:" );
       }
-      if( !photoURL.isEmpty() )
-      {
-        //kdDebug( 5006 ) << "Got a photo: " << photoURL << endl;
-        userHTML = QString("<img src=\"%1\" width=\"%2\" height=\"%3\">")
-                           .arg( photoURL ).arg( photoWidth ).arg( photoHeight );
-        if ( presence.isEmpty() ) {
-          userHTML = QString("<div class=\"senderpic\">") + userHTML + "</div>";
-        } else {
-          userHTML = QString( "<div class=\"senderpic\">"
-              "<a href=\"im:%1\">%2<div class=\"senderstatus\">"
-              "<span name=\"presence-%3\">%4</span></div></a>"
-              "</div>" ).arg( kabcUid )
-              .arg( userHTML )
-              .arg( kabcUid )
-              .arg( presence );
-        }
-      } else {
-        // we don't have a photo, just show presence, if we have it
-        if ( !presence.isEmpty() ) {
-          userHTML = QString( "<div class=\"senderstatus\">"
-              "<span name=\"presence-%1\">%2</span></div>" )
-              .arg( kabcUid )
-              .arg( presence );
-        }
-      }
     }
     else // TODO: find a usable one
     {
       kdDebug( 5006 ) << "Multiple / No addressees matched email address; Count is " << addresses.count() << endl;
       userHTML = "&nbsp;";
     }
+
+    if( photoURL.isEmpty() )
+    {
+      // no photo, look for a X-Face header
+      QString xfaceURL;
+      QString xfhead = message->headerField( "X-Face" );
+      if ( !xfhead.isEmpty() )
+      {
+        KXFace xf;
+        photoURL = imgToDataUrl( xf.toBitmap( xfhead ).convertToImage() );
+        photoWidth = 48;
+        photoHeight = 48;
+
+      }
+
+    }
+
+    if( !photoURL.isEmpty() )
+    {
+        //kdDebug( 5006 ) << "Got a photo: " << photoURL << endl;
+      userHTML = QString("<img src=\"%1\" width=\"%2\" height=\"%3\">")
+          .arg( photoURL ).arg( photoWidth ).arg( photoHeight );
+      if ( presence.isEmpty() ) {
+        userHTML = QString("<div class=\"senderpic\">") + userHTML + "</div>";
+      } else {
+        userHTML = QString( "<div class=\"senderpic\">"
+            "<a href=\"im:%1\">%2<div class=\"senderstatus\">"
+            "<span name=\"presence-%3\">%4</span></div></a>"
+            "</div>" ).arg( kabcUid )
+            .arg( presence )
+             .arg( kabcUid )
+            .arg( userHTML );
+      }
+    } else {
+       // we don't have a photo, just show presence, if we have it
+      if ( !presence.isEmpty() )
+        userHTML = QString( "<a href=\"im:%1\"><div class=\"senderstatus\">"
+            "<span name=\"presence-%2\">%3</span></div></a>" )
+            .arg( kabcUid )
+            .arg( kabcUid )
+            .arg( presence );
+    }
 #if 0
     // Disabled 'Launch IM' link in headers - Will
     if ( imProxy->imAppsAvailable() )
@@ -547,8 +567,7 @@
                                     .arg(onlineStatus));
     */
     headerStr.append(
-          QString("</table></td><td align=\"center\">%1</td></tr></table>\n").arg(userHTML)
-                     );
+          QString( "</table></td><td align=\"center\">%1</td></tr></table>\n" ).arg(userHTML) );
 
     headerStr += "</div>\n\n";
     return headerStr;
diff -Nur old/kmail/identitydialog.cpp new/kmail/identitydialog.cpp
--- old/kmail/identitydialog.cpp	Wed Nov 17 00:49:06 2004
+++ new/kmail/identitydialog.cpp	Mon Nov 15 02:45:36 2004
@@ -37,6 +37,7 @@
 
 // other KMail headers:
 #include "signatureconfigurator.h"
+#include "xfaceconfigurator.h"
 #include "kmfoldercombobox.h"
 #include "kmfoldermgr.h"
 #include "transportmanager.h"
@@ -362,6 +363,10 @@
     mSignatureConfigurator->layout()->setMargin( KDialog::marginHint() );
     tabWidget->addTab( mSignatureConfigurator, i18n("&Signature") );
 
+    mXFaceConfigurator = new XFaceConfigurator( tabWidget );
+    mXFaceConfigurator->layout()->setMargin( KDialog::marginHint() );
+    tabWidget->addTab( mXFaceConfigurator, i18n("&Picture") );
+
     KConfigGroup geometry( KMKernel::config(), "Geometry" );
     if ( geometry.hasKey( "Identity Dialog size" ) )
       resize( geometry.readSizeEntry( "Identity Dialog size" ) );
@@ -545,6 +550,8 @@
 
     // "Signature" tab:
     mSignatureConfigurator->setSignature( ident.signature() );
+    mXFaceConfigurator->setXFace( ident.xface() );
+    mXFaceConfigurator->setXFaceEnabled( ident.isXFaceEnabled() );
   }
 
   void IdentityDialog::updateIdentity( KPIM::Identity & ident ) {
@@ -587,6 +594,8 @@
                      mDraftsCombo->getFolder()->idString() : QString::null );
     // "Signature" tab:
     ident.setSignature( mSignatureConfigurator->signature() );
+    ident.setXFace( mXFaceConfigurator->xface() );
+    ident.setXFaceEnabled( mXFaceConfigurator->isXFaceEnabled() );
   }
 
   void IdentityDialog::slotUpdateTransportCombo( const QStringList & sl ) {
diff -Nur old/kmail/identitydialog.h new/kmail/identitydialog.h
--- old/kmail/identitydialog.h	Thu Nov 11 01:02:50 2004
+++ new/kmail/identitydialog.h	Wed Sep  8 01:59:28 2004
@@ -50,6 +50,7 @@
 }
 namespace KMail {
   class SignatureConfigurator;
+  class XFaceConfigurator;
   class DictionaryComboBox;
 }
 
@@ -98,6 +99,8 @@
     QComboBox                    *mTransportCombo; // should be a KMTransportCombo...
     // "signature" tab:
     KMail::SignatureConfigurator *mSignatureConfigurator;
+    // "X-Face" tab:
+    KMail::XFaceConfigurator *mXFaceConfigurator;
   };
 
 } // namespace KMail
diff -Nur old/kmail/kmcomposewin.cpp new/kmail/kmcomposewin.cpp
--- old/kmail/kmcomposewin.cpp	Wed Nov 17 00:49:06 2004
+++ new/kmail/kmcomposewin.cpp	Sun Nov 14 22:51:26 2004
@@ -1412,6 +1412,11 @@
   // check for presence of a priority header, indicating urgent mail:
   mUrgentAction->setChecked( newMsg->isUrgent() );
 
+  if (!ident.isXFaceEnabled() || ident.xface().isEmpty())
+    mMsg->removeHeaderField("X-Face");
+  else
+    mMsg->setHeaderField("X-Face", ident.xface());
+
   // enable/disable encryption if the message was/wasn't encrypted
   switch ( mMsg->encryptionState() ) {
     case KMMsgFullyEncrypted: // fall through
@@ -3476,6 +3481,11 @@
     mMsg->removeHeaderField("Organization");
   else
     mMsg->setHeaderField("Organization", ident.organization());
+
+  if (!ident.isXFaceEnabled() || ident.xface().isEmpty())
+    mMsg->removeHeaderField("X-Face");
+  else
+    mMsg->setHeaderField("X-Face", ident.xface());
 
   if ( !mBtnTransport->isChecked() ) {
     QString transp = ident.transport();
diff -Nur old/kmail/xfaceconfigurator.cpp new/kmail/xfaceconfigurator.cpp
--- old/kmail/xfaceconfigurator.cpp	Thu Jan  1 01:00:00 1970
+++ new/kmail/xfaceconfigurator.cpp	Wed Nov 17 03:49:09 2004
@@ -0,0 +1,282 @@
+/*
+    This file is part of KMail.
+
+    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., 59 Temple Place - Suite 330,
+    Boston, MA 02111-1307, USA.
+
+    In addition, as a special exception, the copyright holders give
+    permission to link the code of this program with any edition of
+    the Qt library by Trolltech AS, Norway (or with modified versions
+    of Qt that use the same license as Qt), and distribute linked
+    combinations including the two.  You must obey the GNU General
+    Public License in all respects for all of the code used other than
+    Qt.  If you modify this file, you may extend this exception to
+    your version of the file, but you are not obligated to do so.  If
+    you do not wish to do so, delete this exception statement from
+    your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "xfaceconfigurator.h"
+
+#include <kactivelabel.h>
+#include <kdialog.h>
+#include <kfiledialog.h>
+#include <kglobalsettings.h>
+#include <kimageio.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kurl.h>
+#include <kio/netaccess.h>
+using namespace KIO;
+#include <kxface.h>
+using namespace KPIM;
+#include <kabc/stdaddressbook.h>
+#include <kabc/addressee.h>
+using namespace KABC;
+
+#include <qbitmap.h>
+#include <qcheckbox.h>
+#include <qcombobox.h>
+#include <qimage.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qwhatsthis.h>
+#include <qwidgetstack.h>
+
+
+// #include <assert.h>
+
+using namespace KMail;
+using namespace KPIM;
+
+namespace KMail {
+
+  XFaceConfigurator::XFaceConfigurator( QWidget * parent, const char * name )
+    : QWidget( parent, name )
+  {
+    // tmp. vars:
+    QLabel * label;
+    QLabel * label1;
+    KActiveLabel * label2;
+    QWidget * page;
+    QVBoxLayout * vlay;
+    QHBoxLayout * hlay;
+    QVBoxLayout * page_vlay;
+    QPushButton * mFromFileBtn;
+    QPushButton * mFromAddrbkBtn;
+
+    vlay = new QVBoxLayout( this, 0, KDialog::spacingHint(), "main layout" );
+    hlay = new QHBoxLayout( vlay );
+
+    // "enable X-Face" checkbox:
+    mEnableCheck = new QCheckBox( i18n("&Send picture with every Email"), this );
+    QWhatsThis::add( mEnableCheck,
+        i18n( "Check this box if you want KMail to add a so-called X-Face header to mails "
+            "written with this identity. A X-Face is a small (48x48 pixels) black and "
+            "white image that some mail clients are able to display." ) );
+    hlay->addWidget( mEnableCheck, Qt::AlignLeft | Qt::AlignVCenter );
+
+    mXFaceLabel = new QLabel( this );
+    QWhatsThis::add(mXFaceLabel,
+                    i18n( "This is a preview of the picture selected/entered below." ) );
+    mXFaceLabel->setFixedSize(48, 48);
+    mXFaceLabel->setFrameShape( QFrame::Box );
+    hlay->addWidget( mXFaceLabel );
+
+//     label1 = new QLabel( "X-Face:", this );
+//     vlay->addWidget( label1 );
+
+    // "obtain X-Facet from" combo and label:
+    hlay = new QHBoxLayout( vlay ); // inherits spacing
+    mSourceCombo = new QComboBox( false, this );
+    QWhatsThis::add(mSourceCombo,
+                    i18n("Click on the widgets below to obtain help on the input methods."));
+    mSourceCombo->setEnabled( false ); // since !mEnableCheck->isChecked()
+    mSourceCombo->insertStringList( QStringList()
+        << i18n( "continuation of \"obtain picture from\"",
+                "Input Field Below" )
+        << i18n( "continuation of \"obtain picture from\"",
+                "External Source" ) );
+    label = new QLabel( mSourceCombo,
+                        i18n("Obtain pic&ture from:"), this );
+    label->setEnabled( false ); // since !mEnableCheck->isChecked()
+    hlay->addWidget( label );
+    hlay->addWidget( mSourceCombo, 1 );
+
+    // widget stack that is controlled by the source combo:
+    QWidgetStack * widgetStack = new QWidgetStack( this );
+    widgetStack->setEnabled( false ); // since !mEnableCheck->isChecked()
+    vlay->addWidget( widgetStack, 1 );
+    connect( mSourceCombo, SIGNAL(highlighted(int)),
+             widgetStack, SLOT(raiseWidget(int)) );
+    connect( mEnableCheck, SIGNAL(toggled(bool)),
+             mSourceCombo, SLOT(setEnabled(bool)) );
+    connect( mEnableCheck, SIGNAL(toggled(bool)),
+             widgetStack, SLOT(setEnabled(bool)) );
+    connect( mEnableCheck, SIGNAL(toggled(bool)),
+             label, SLOT(setEnabled(bool)) );
+    // The focus might be still in the widget that is disabled
+    connect( mEnableCheck, SIGNAL(clicked()),
+             mEnableCheck, SLOT(setFocus()) );
+
+    int pageno = 0;
+    // page 0: create X-Face from image file or addressbook entry
+    page = new QWidget( widgetStack );
+    widgetStack->addWidget( page, pageno ); // force sequential numbers (play safe)
+    page_vlay = new QVBoxLayout( page, 0, KDialog::spacingHint() );
+    hlay = new QHBoxLayout( page_vlay ); // inherits spacing
+    mFromFileBtn = new QPushButton( "Select File", page );
+    QWhatsThis::add( mFromFileBtn,
+                     i18n("Use this to select an image file to create the picture from. "
+                         "The image should be of high contrast and nearly quadratic shape. "
+                         "A light background helps improve the result." ) );
+    mFromFileBtn->setAutoDefault( false );
+    page_vlay->addWidget( mFromFileBtn, 1 );
+    connect( mFromFileBtn, SIGNAL(released()),
+             this, SLOT(slotSelectFile()) );
+    mFromAddrbkBtn = new QPushButton( "Set from Addressbook", page );
+    QWhatsThis::add( mFromAddrbkBtn,
+                     i18n( "You can use a scaled-down version of the picture "
+                         "you have set in your addressbook entry." ) );
+    mFromAddrbkBtn->setAutoDefault( false );
+    page_vlay->addWidget( mFromAddrbkBtn, 1 );
+    connect( mFromAddrbkBtn, SIGNAL(released()),
+             this, SLOT(slotSelectFromAddressbook()) );
+    label1 = new QLabel( i18n("KMail can send a small (48x48 pixels), low-quality,\n"
+        "monochrome picture with every mail.\n"
+        "For example, this could be a picture of you or a glyph.\n"
+        "It is shown in the recipient's mail client (if supported)." ), page );
+    page_vlay->addWidget( label1 );
+
+    widgetStack->raiseWidget( 0 ); // since mSourceCombo->currentItem() == 0
+
+    // page 1: input field for direct entering
+    ++pageno;
+    page = new QWidget( widgetStack );
+    widgetStack->addWidget( page, pageno );
+    page_vlay = new QVBoxLayout( page, 0, KDialog::spacingHint() );
+    mTextEdit = new QTextEdit( page );
+    page_vlay->addWidget( mTextEdit );
+    QWhatsThis::add( mTextEdit, i18n( "Use this field to enter an arbitrary X-Face string." ) );
+    mTextEdit->setFont( KGlobalSettings::fixedFont() );
+    mTextEdit->setWordWrap( QTextEdit::NoWrap );
+    mTextEdit->setTextFormat( Qt::PlainText );
+    label2 = new KActiveLabel( i18n("Get example X-Faces at <a href=\"http://www.xs4all.nl/~ace/X-Faces/\">http://www.xs4all.nl/~ace/X-Faces/</a><br>or create your own at <a href=\"http://www.dairiki.org/xface/\">http://www.dairiki.org/xface/</a>"), page );
+    page_vlay->addWidget( label2 );
+
+
+    connect(mTextEdit, SIGNAL(textChanged()), this, SLOT(slotUpdateXFace()));
+  }
+
+  XFaceConfigurator::~XFaceConfigurator() {
+
+  }
+
+  bool XFaceConfigurator::isXFaceEnabled() const {
+    return mEnableCheck->isChecked();
+  }
+
+  void XFaceConfigurator::setXFaceEnabled( bool enable ) {
+    mEnableCheck->setChecked( enable );
+  }
+
+  QString XFaceConfigurator::xface() const {
+    return mTextEdit->text();
+  }
+
+  void XFaceConfigurator::setXFace( const QString & text ) {
+    mTextEdit->setText( text );
+  }
+
+  void XFaceConfigurator::setXfaceFromFile( const KURL &url )
+  {
+    QString tmpFile;
+    if( KIO::NetAccess::download( url, tmpFile, this ) )
+    {
+      KXFace xf;
+      mTextEdit->setText( xf.fromImage( QImage( tmpFile ) ) );
+      KIO::NetAccess::removeTempFile( tmpFile );
+    } else {
+      KMessageBox::error(this, KIO::NetAccess::lastErrorString() );
+    }
+  }
+
+  void XFaceConfigurator::slotSelectFile()
+  {
+    QStringList mimeTypes = KImageIO::mimeTypes (KImageIO::Reading);
+    QString filter = mimeTypes.join (" ");
+    KURL url = KFileDialog::getOpenURL( QString::null, filter, this, QString::null );
+    if ( !url.isEmpty() )
+      setXfaceFromFile( url );
+  }
+
+  void XFaceConfigurator::slotSelectFromAddressbook()
+  {
+    StdAddressBook *ab = StdAddressBook::self();
+    Addressee me = ab->whoAmI();
+    if ( !me.isEmpty() )
+    {
+      if ( me.photo().isIntern() )
+      {
+        QImage photo = me.photo().data();
+        if ( !photo.isNull() )
+        {
+          KXFace xf;
+          mTextEdit->setText( xf.fromImage( photo ) );
+        }
+        else
+          KMessageBox::information( this, "No picture set for your Adressbook entry.", "No picture" );
+
+      }
+      else
+      {
+        KURL url = me.photo().url();
+        if( !url.isEmpty() )
+          setXfaceFromFile( url );
+        else
+          KMessageBox::information( this, "No picture set for your Adressbook entry.", "No picture" );
+      }
+    }
+    else
+      KMessageBox::information( this, "You don't have your own contact defined in the Addressbook.", "No picture" );
+  }
+
+  void XFaceConfigurator::slotUpdateXFace()
+  {
+    QString str = mTextEdit->text();
+    if ( !str.isEmpty() )
+    {
+      if ( str.startsWith("x-face:", false) )
+      {
+        str = str.remove("x-face:", false);
+        mTextEdit->setText(str);
+      }
+      KXFace xf;
+      mXFaceLabel->setPixmap( xf.toBitmap(str) );
+    }
+    else
+      mXFaceLabel->setPixmap( 0L );
+  }
+
+} // namespace KMail
+
+#include "xfaceconfigurator.moc"
diff -Nur old/kmail/xfaceconfigurator.h new/kmail/xfaceconfigurator.h
--- old/kmail/xfaceconfigurator.h	Thu Jan  1 01:00:00 1970
+++ new/kmail/xfaceconfigurator.h	Mon Nov 15 22:43:41 2004
@@ -0,0 +1,64 @@
+/*  -*- c++ -*-
+    xfaceconfigurator.cpp
+
+    KMail, the KDE mail client.
+    Copyright (c) 2004 Jakob Schröter <js@camaya.net>
+    Copyright (c) 2002 the KMail authors.
+    See file AUTHORS for details
+
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License,
+    version 2.0, as published by the Free Software Foundation.
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software Foundation,
+    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, US
+*/
+
+#ifndef __KMAIL_XFACECONFIGURATOR_H__
+#define __KMAIL_XFACECONFIGURATOR_H__
+
+#include <qwidget.h>
+#include <qtextedit.h>
+
+class KURL;
+
+class QCheckBox;
+class QString;
+class QLabel;
+class QComboBox;
+
+namespace KMail {
+
+  class XFaceConfigurator : public QWidget {
+    Q_OBJECT
+  public:
+    XFaceConfigurator( QWidget * parent=0, const char * name=0 );
+    virtual ~XFaceConfigurator();
+
+    bool isXFaceEnabled() const;
+    void setXFaceEnabled( bool enable );
+
+
+    QString xface() const;
+    void setXFace( const QString & text );
+
+  protected:
+    QCheckBox     * mEnableCheck;
+    QTextEdit     * mTextEdit;
+    QLabel        * mXFaceLabel;
+    QComboBox     * mSourceCombo;
+
+
+  private:
+    void setXfaceFromFile( const KURL &url );
+
+  private slots:
+    void slotSelectFile();
+    void slotSelectFromAddressbook();
+    void slotUpdateXFace();
+  };
+} // namespace KMail
+
+#endif // __KMAIL_XFACECONFIGURATOR_H__
+
+
diff -Nur old/knode/knarticlewidget.cpp new/knode/knarticlewidget.cpp
--- old/knode/knarticlewidget.cpp	Fri Nov 12 21:52:04 2004
+++ new/knode/knarticlewidget.cpp	Mon Nov 15 19:47:42 2004
@@ -25,6 +25,8 @@
 #include <qpainter.h>
 #include <qtimer.h>
 #include <qurl.h>
+#include <qbuffer.h>
+#include <qbitmap.h>
 
 #include <kprinter.h>
 #include <kiconloader.h>
@@ -40,6 +42,8 @@
 #include <kpgpblock.h>
 #include <kstringhandler.h>
 
+#include <libkdepim/kxface.h>
+
 #include "resource.h"
 #include "knarticlewidget.h"
 #include "knglobals.h"
@@ -58,6 +62,7 @@
 #include <kstandarddirs.h>
 #include <kbookmarkmanager.h>
 #include <kaddrbook.h>
+#include <ktempfile.h>
 
 #define PUP_OPEN    1000
 #define PUP_SAVE    2000
@@ -222,6 +227,10 @@
   r_ot13=false;
   a_ctToggleRot13->setChecked(false);
   applyConfig();
+
+  t_mpFile = new KTempFile(locateLocal("tmp", "knode"), ".png");
+  t_mpFile->close();
+  t_mpFile->setAutoDelete(true);
 }
 
 
@@ -242,6 +251,7 @@
   delete t_imer;
   delete f_inddialog;
   delete u_mailtoPopup;
+  delete t_mpFile;
 }
 
 void KNArticleWidget::setText( const QString& text, const QString& context )
@@ -1073,6 +1083,22 @@
 
   QString headerHtml;
   int headerLines=0;
+  int headerCols=3;
+
+  QString xfhead;
+  KMime::Headers::Base *temp = a_rticle->getHeaderByType("X-Face");
+  if (temp)
+    xfhead = temp->asUnicodeString();
+  QString xface = "";
+  if ( !xfhead.isEmpty() )
+  {
+    KPIM::KXFace xf;
+    xf.toBitmap(xfhead).convertToImage().save(t_mpFile->name(), "PNG");
+    xface = QString::fromLatin1(
+        "<td rowspan=\"4\" width=\"48\" height=\"48\"><img border=\"1\" src=\"%1\"></td>")
+        .arg(t_mpFile->name());
+    ++headerCols;
+  }
 
   if(a_ctToggleFullHdrs->isChecked()) {
     QCString head = a_rticle->head();
@@ -1083,9 +1109,11 @@
       if (header) {
         if (headerLines > 0)
           headerHtml += "<tr>";
-        headerHtml+=QString("<td align=right><articlefont><b>%1</b></articlefont></td><td width=\"100%\"><articlefont>%2</articlefont></td></tr>")
+        headerHtml+=QString("<td align=right><articlefont><b>%1</b></articlefont></td><td width=\"100%\"><articlefont>%2</articlefont></td>%3</tr>")
                       .arg(toHtmlString(header->type())+":")
-                      .arg(toHtmlString(header->asUnicodeString(),true, false, false, true));
+                      .arg(toHtmlString(header->asUnicodeString(),true, false, false, true))
+                      .arg(xface);
+        xface = "";
         delete header;
         headerLines++;
       }
@@ -1122,7 +1150,8 @@
       } else
         headerHtml+=toHtmlString(hb->asUnicodeString(),true, false, false, true);
 
-      headerHtml += dh->headerCloseTag()+"</articlefont></td></tr>";
+      headerHtml += dh->headerCloseTag()+"</articlefont></td>"+xface+"</tr>";
+      xface = "";
       headerLines++;
     }
   }
@@ -1135,8 +1164,8 @@
     if (headerLines > 0) {
       html+=QString("<tr><td width=\"40\" bgcolor=\"%1\" rowspan=\"%2\"></td>"+headerHtml)
            .arg(app->headerDecoHexcode()).arg(headerLines);
-      html+=QString("<tr><td colspan=\"3\" bgcolor=\"%1\"><articlefont>")
-            .arg(app->headerDecoHexcode());
+      html+=QString("<tr><td colspan=\"%1\" bgcolor=\"%2\"><articlefont>")
+          .arg(headerCols).arg(app->headerDecoHexcode());
     } else {
       html+=QString("<tr><td bgcolor=\"%1\"><articlefont>")
           .arg(app->headerDecoHexcode());
diff -Nur old/knode/knarticlewidget.h new/knode/knarticlewidget.h
--- old/knode/knarticlewidget.h	Thu Nov 11 01:07:09 2004
+++ new/knode/knarticlewidget.h	Fri Nov 12 23:21:40 2004
@@ -30,6 +30,7 @@
 class KToggleAction;
 class KSelectAction;
 class KPopupMenu;
+class KTempFile;
 
 class KNArticle;
 class KNArticleCollection;
@@ -208,6 +209,9 @@
   protected:
     static QPtrList<KNArticleWidget> *i_nstances;
     static QPtrList<KNArticleWidget> *instances();
+
+  private:
+    KTempFile *t_mpFile;
 
 };
 
diff -Nur old/libkdepim/Makefile.am new/libkdepim/Makefile.am
--- old/libkdepim/Makefile.am	Thu Nov 11 01:07:43 2004
+++ new/libkdepim/Makefile.am	Sun Nov 14 23:57:30 2004
@@ -25,7 +25,7 @@
   resourceabc.cpp diffalgo.cpp addresseediffalgo.cpp calendardiffalgo.cpp \
   htmldiffalgodisplay.cpp broadcaststatus.cpp kresourceprefs.cpp \
   kpixmapregionselectorwidget.cpp kpixmapregionselectordialog.cpp \
-  kabcresourcecached.cpp \
+  kabcresourcecached.cpp kxface.cpp \
   kaccount.cpp kaddrbook.cpp kfoldertree.cpp kregexp3.cpp \
   kscoring.cpp kscoringeditor.cpp ksubscription.cpp kwidgetlister.cpp \
   linklocator.cpp qutf7codec.cpp \
diff -Nur old/libkdepim/kxface.cpp new/libkdepim/kxface.cpp
--- old/libkdepim/kxface.cpp	Thu Jan  1 01:00:00 1970
+++ new/libkdepim/kxface.cpp	Wed Nov 17 03:13:59 2004
@@ -0,0 +1,866 @@
+/*
+  This file is part of libkdepim.
+
+  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., 59 Temple Place - Suite 330,
+  Boston, MA 02111-1307, USA.
+*/
+
+#include "kxface.h"
+
+#include <kdebug.h>
+
+#include <qbitmap.h>
+#include <qbuffer.h>
+#include <qcstring.h>
+#include <qimage.h>
+#include <qpixmap.h>
+#include <qregexp.h>
+#include <qstring.h>
+#include <qpainter.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;
+  compface_xbitmap = 0;
+}
+
+KXFace::~KXFace()
+{
+}
+
+QString KXFace::fromImage( const QImage &image )
+{
+  if( image.isNull() )
+    return QString();
+
+  QImage scaledImg = image.smoothScale( 48, 48 );
+  QByteArray ba;
+  QBuffer buffer( ba );
+  buffer.open( IO_WriteOnly );
+  scaledImg.save( &buffer, "XBM" );
+  QString 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 );
+  char *tmp = (char *)malloc( sizeof(char)*577 );
+  strcpy( tmp, xbm.latin1() );
+  char *c = tmp;
+  uint len = strlen( tmp );
+  for( uint i=0; i<len; ++i )
+  {
+    switch( c[i] )
+    {
+      case '1': c[i] = '8'; break;
+      case '2': c[i] = '4'; break;
+      case '3': c[i] = 'c'; break;
+      case '4': c[i] = '2'; break;
+      case '5': c[i] = 'a'; break;
+      case '7': c[i] = 'e'; break;
+      case '8': c[i] = '1'; break;
+      case 'A':
+      case 'a': c[i] = '5'; break;
+      case 'B':
+      case 'b': c[i] = 'd'; break;
+      case 'C':
+      case 'c': c[i] = '3'; break;
+      case 'D':
+      case 'd': c[i] = 'b'; break;
+      case 'E':
+      case 'e': c[i] = '7'; break;
+    }
+    if ( i % 2 )
+    {
+      char t = c[i];
+      c[i] = c[i-1];
+      c[i-1] = t;
+    }
+  }
+  xbm = QString( tmp );
+  free( tmp );
+  xbm.replace( QRegExp( "(\\w{12})" ), "\\1\n" );
+  xbm.replace( QRegExp( "(\\w{4})" ), "0x\\1," );
+  len = xbm.length();
+  char *fbuf = (char *)malloc( len + 1 );
+  strncpy( fbuf, xbm.latin1(), len );
+  fbuf[len] = '\0';
+  if ( !( status = setjmp( comp_env ) ) )
+  {
+    ReadFace( fbuf );
+    GenFace();
+    CompAll( fbuf );
+  }
+  QString ret( fbuf );
+  free( fbuf );
+
+  return ret;
+}
+
+QBitmap KXFace::toBitmap(const QString &xface)
+{
+  if ( xface.length() > MAX_XFACE_LENGTH )
+    return QBitmap();
+
+  char *fbuf = (char *)malloc( MAX_XFACE_LENGTH );
+  memset( fbuf, '\0', MAX_XFACE_LENGTH );
+  strncpy( fbuf, xface.latin1(), xface.length() );
+  if ( !( status = setjmp( comp_env ) ) )
+  {
+    UnCompAll( fbuf );/* compress otherwise */
+    UnGenFace();
+    WriteFace( fbuf );
+  }
+  QString ikon( fbuf );
+  free( fbuf );
+
+  QBitmap b( 48, 48, true );
+  QPainter p( &b );
+  p.setPen( Qt::color1 );
+
+  ikon.remove( "0x", true );
+  ikon.remove( ",", true );
+  ikon.remove( "\n", true );
+  ikon.remove( " ", true );
+
+  uint i = 0;
+  int pos = 0;
+  for( i=0; i<ikon.length(); i++ )
+  {
+    switch( ikon.at( i ).latin1() )
+    {
+      case '0':
+        pos += 4;
+        break;
+      case '1':
+        pos += 3;
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        break;
+      case '2':
+        pos += 2;
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        ++pos;
+        break;
+      case '3':
+        pos += 2;
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        break;
+      case '4':
+        ++pos;
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        pos += 2;
+        break;
+      case '5':
+        ++pos;
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        ++pos;
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        break;
+      case '6':
+        ++pos;
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        ++pos;
+        break;
+      case '7':
+        ++pos;
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        break;
+      case '8':
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        pos += 3;
+        break;
+      case '9':
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        pos += 2;
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        break;
+      case 'A':
+      case 'a':
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        ++pos;
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        ++pos;
+        break;
+      case 'B':
+      case 'b':
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        ++pos;
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        break;
+      case 'c':
+      case 'C':
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        pos += 2;
+        break;
+      case 'd':
+      case 'D':
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        ++pos;
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        break;
+      case 'e':
+      case 'E':
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        ++pos;
+        break;
+      case 'f':
+      case 'F':
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        p.drawPoint(x(pos), y(pos)); ++pos;
+        break;
+    }
+  }
+  p.end();
+  b.setMask( b );
+
+  return b;
+}
+
+int KXFace::x(const int pos)
+{
+  return pos%48;
+}
+
+int KXFace::y(const int pos)
+{
+  return pos/48;
+}
+
+//============================================================================
+// 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;
+}
+
+void KXFace::WriteFace(char *fbuf)
+{
+  register char *s, *t;
+  register int i, bits, digits, words;
+  int digsperword = DIGSPERWORD;
+  int wordsperline = WORDSPERLINE;
+
+  s = F;
+  t = fbuf;
+  bits = digits = words = i = 0;
+  if (compface_xbitmap) {
+    sprintf(t,"#define noname_width 48\n#define noname_height 48\nstatic char noname_bits[] = {\n ");
+    while (*t) t++;
+    digsperword = 2;
+    wordsperline = 15;
+  }
+  while (s < F + PIXELS)
+  {
+    if ((bits == 0) && (digits == 0))
+    {
+      *(t++) = '0';
+      *(t++) = 'x';
+    }
+    if (compface_xbitmap) {
+      if (*(s++))
+        i = (i >> 1) | 0x8;
+      else
+        i >>= 1;
+    }
+    else {
+      if (*(s++))
+        i = i * 2 + 1;
+      else
+        i *= 2;
+    }
+    if (++bits == BITSPERDIG)
+    {
+      if (compface_xbitmap) {
+        t++;
+        t[-(digits & 1) * 2] = *(i + HexDigits);
+      }
+      else *(t++) = *(i + HexDigits);
+      bits = i = 0;
+      if (++digits == digsperword)
+      {
+        if (compface_xbitmap && (s >= F + PIXELS))
+          break;
+        *(t++) = ',';
+        digits = 0;
+        if (++words == wordsperline)
+        {
+          *(t++) = '\n';
+          if (compface_xbitmap) *(t++) = ' ';
+          words = 0;
+        }
+      }
+    }
+  }
+  if (compface_xbitmap) {
+    sprintf(t, "};\n");
+    while (*t) t++;
+  }
+  *(t++) = '\0';
+}
+
+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;
+        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"
diff -Nur old/libkdepim/kxface.h new/libkdepim/kxface.h
--- old/libkdepim/kxface.h	Thu Jan  1 01:00:00 1970
+++ new/libkdepim/kxface.h	Wed Nov 17 01:01:29 2004
@@ -0,0 +1,597 @@
+/*
+  This file is part of libkdepim.
+
+  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., 59 Temple Place - Suite 330,
+  Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef __KXFACE_H
+#define __KXFACE_H
+
+
+#include <qobject.h>
+#include <setjmp.h>
+
+// #define WIDTH 48
+// #define HEIGHT WIDTH
+
+/* total number of pixels and digits */
+// #define PIXELS (WIDTH * HEIGHT)
+// #define WORD unsigned char
+// #define MAXWORDS ((PIXELS * 2 + BITSPERWORD - 1) / BITSPERWORD)
+// #define BITSPERWORD 8
+
+
+typedef struct guesses
+{
+  char g_00[1<<12];
+  char g_01[1<<7];
+  char g_02[1<<2];
+  char g_10[1<<9];
+  char g_20[1<<6];
+  char g_30[1<<8];
+  char g_40[1<<10];
+  char g_11[1<<5];
+  char g_21[1<<3];
+  char g_31[1<<5];
+  char g_41[1<<6];
+  char g_12[1<<1];
+  char g_22[1<<0];
+  char g_32[1<<2];
+  char g_42[1<<2];
+} Guesses;
+
+static const Guesses G =
+{
+  {
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1,
+    0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1,
+    0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1,
+    0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1,
+    0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1,
+    1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+    1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1,
+    0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0,
+    0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1,
+    0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1,
+    1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1,
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
+    0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1,
+    1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1,
+    0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1,
+    0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1,
+    1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1,
+    0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+    0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1,
+    0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
+    1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1,
+    0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1,
+    0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0,
+    0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1,
+    0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1,
+    1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1,
+    0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1,
+    0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
+    0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
+    0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1,
+    1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1,
+    0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
+    0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1,
+    0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+    0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0,
+    0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+    0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1,
+    0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0,
+    0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+    1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1,
+    1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1,
+    0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1,
+    1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
+    0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
+    0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
+    0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1,
+    0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0,
+    0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
+    0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
+    0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+    0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+    1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1,
+    0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1,
+    1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+    0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0,
+    0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
+    0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1,
+    1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0,
+    0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
+    1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1,
+    0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
+    0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1,
+    1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
+    0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0,
+    0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1,
+    0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
+    1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
+    0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0,
+    0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1,
+    0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1,
+    0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1,
+    0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1,
+    1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
+    1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1,
+    0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+    0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1,
+    0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
+    0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0,
+    0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+    0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+    1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1,
+    0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0,
+    0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
+    0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0,
+    1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1,
+    1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1,
+    0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1,
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1,
+    1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0,
+    1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0,
+    1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
+    0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0,
+    1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0,
+    1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1,
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1,
+    1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0,
+    1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  },
+  {
+    0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1,
+    0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1,
+    0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1,
+    1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1,
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  },
+  {
+    0, 1, 0, 1, 
+  },
+  {
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 
+    1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 
+    0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 
+    0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 
+    0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 
+    0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 
+    0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 
+    0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 
+    0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 
+    0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 
+    0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 
+    0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 
+    0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 
+    0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 
+    1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 
+    0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 
+    1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 
+    0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 
+    0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+  },
+  {
+    0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 
+    0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 
+    1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 
+  },
+  {
+    0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 
+    0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 
+    0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 
+    0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 
+    0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 
+    0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 
+    0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 
+    0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 
+    0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 
+    0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 
+    0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 
+    0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 
+    0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 
+    0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 
+    0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 
+    0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 
+  },
+  {
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 
+    1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 
+    0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 
+    0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 
+    0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 
+    1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 
+    0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 
+    0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 
+    0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 
+    0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 
+    0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 
+    0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 
+    0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 
+    0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 
+    0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 
+    0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 
+    0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 
+    0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 
+    0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 
+    0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 
+    0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 
+    0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 
+    0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 
+    0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 
+    0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 
+    0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 
+    0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 
+    0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 
+    0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 
+    0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 
+    0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+  },
+  {
+    0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 
+    0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 
+  },
+  {
+    0, 0, 0, 1, 0, 1, 1, 1, 
+  },
+  {
+    0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 
+    0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 
+  },
+  {
+    0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 
+    0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 
+    0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 
+    0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+  },
+  {
+    0, 1, 
+  },
+  {
+    0, 
+  },
+  {
+    0, 0, 0, 1, 
+  },
+  {
+    0, 0, 0, 1, 
+  }
+};
+
+typedef struct prob
+{
+  int p_range;
+  int p_offset;
+} Prob;
+
+
+
+static const Prob levels[4][3] = {
+  {{1, 255},  {251, 0}, {4, 251}},	/* Top of tree almost always grey */
+  {{1, 255},  {200, 0}, {55, 200}},
+  {{33, 223}, {159, 0}, {64, 159}},
+  {{131, 0},  {0, 0},   {125, 131}}	/* Grey disallowed at bottom */
+};
+
+static const Prob freqs[16] = {
+  {0, 0},    {38, 0},   {38, 38},  {13, 152},
+  {38, 76},  {13, 165}, {13, 178}, {6, 230},
+  {38, 114}, {13, 191}, {13, 204}, {6, 236},
+  {13, 217}, {6, 242},  {5, 248},  {3, 253}
+};
+
+static const char HexDigits[] = "0123456789ABCDEF";
+
+
+
+class QBitmap;
+class QImage;
+class QString;
+
+namespace KPIM {
+
+  class KXFace : public QObject
+  {
+    Q_OBJECT
+
+    public:
+      KXFace();
+      virtual ~KXFace();
+
+      /**
+       * @p generates the xface string from @p image
+       */
+      QString fromImage(const QImage &image);
+
+      /**
+       * creates a pixmap from @p xface
+       */
+      QBitmap toBitmap(const QString &xface);
+
+
+    private:
+      static const int WIDTH = 48;
+      static const int HEIGHT = WIDTH;
+      static const int PIXELS = (WIDTH * HEIGHT);
+      static const int BITSPERWORD = 8;
+      static const int MAXWORDS = ((PIXELS * 2 + BITSPERWORD - 1) / BITSPERWORD);
+
+      int NumProbs;
+      int status;
+      int compface_xbitmap;
+
+      char F[PIXELS];
+      Prob *ProbBuf[PIXELS * 2];
+
+      jmp_buf comp_env;
+
+      typedef struct bigint
+      {
+        int b_words;
+        unsigned char b_word[MAXWORDS];
+      } BigInt;
+
+      BigInt B;
+
+      static int x(const int pos);
+      static int y(const int pos);
+
+      void RevPush(const Prob *p);
+      void BigPush(Prob *p);
+      int  BigPop(register const Prob *p);
+      void BigDiv(register unsigned char a, register unsigned char *r);
+      void BigMul(register unsigned char a);
+      void BigAdd(unsigned char a);
+      void BigClear();
+
+      void WriteFace(char *fbuf);
+      void UnCompAll(char *fbuf);
+      void UnCompress(register char *f, register int wid, register int hei, register int lev);
+      void BigWrite(register char *fbuf);
+      void BigRead(register char *fbuf);
+      void ReadFace(char *fbuf);
+      void GenFace();
+      void UnGenFace();
+      void Gen(register char *f);
+      void PopGreys(char *f, int wid, int hei);
+      void CompAll(char *fbuf);
+      void Compress(register char *f, register int wid, register int hei, register int lev);
+      int  AllWhite(char *f, int wid, int hei);
+      int  AllBlack(char *f, int wid, int hei);
+      int  Same(register char *f, register int wid, register int hei);
+      void PushGreys(char *f, int wid, int hei);
+
+
+  };
+} // namespace KPIM
+#endif // __KXFACE_H
diff -Nur old/libkpimidentities/identity.cpp new/libkpimidentities/identity.cpp
--- old/libkpimidentities/identity.cpp	Thu Nov 11 01:07:23 2004
+++ new/libkpimidentities/identity.cpp	Fri Nov 12 21:56:26 2004
@@ -237,7 +237,8 @@
     mSMIMEEncryptionKey.isEmpty() && mSMIMESigningKey.isEmpty() &&
     mTransport.isEmpty() && mDictionary.isEmpty() &&
     mPreferredCryptoMessageFormat == Kleo::AutoFormat &&
-    mSignature.type() == Signature::Disabled;
+    mSignature.type() == Signature::Disabled &&
+    mXFace.isNull();
 }
 
 bool Identity::operator==( const Identity & other ) const {
@@ -253,7 +254,8 @@
       mSMIMESigningKey == other.mSMIMESigningKey &&
       mPreferredCryptoMessageFormat == other.mPreferredCryptoMessageFormat &&
       mDrafts == other.mDrafts && mTransport == other.mTransport &&
-      mDictionary == other.mDictionary && mSignature == other.mSignature;
+      mDictionary == other.mDictionary && mSignature == other.mSignature &&
+      mXFace == other.mXFace && mXFaceEnabled == other.mXFaceEnabled;
 
 #if 0
   if ( same )
@@ -325,6 +327,8 @@
     mDrafts = "drafts";
   mTransport = config->readEntry("Transport");
   mDictionary = config->readEntry( "Dictionary" );
+  mXFace = config->readEntry( "X-Face" );
+  mXFaceEnabled = config->readBoolEntry( "X-FaceEnabled", false );
 
   mSignature.readConfig( config );
   kdDebug(5006) << "Identity::readConfig(): UOID = " << mUoid
@@ -352,6 +356,8 @@
   config->writeEntry("Fcc", mFcc);
   config->writeEntry("Drafts", mDrafts);
   config->writeEntry( "Dictionary", mDictionary );
+  config->writeEntry( "X-Face", mXFace );
+  config->writeEntry( "X-FaceEnabled", mXFaceEnabled );
 
   mSignature.writeConfig( config );
 }
@@ -374,6 +380,7 @@
 		<< i.drafts()
 		<< i.mSignature
                 << i.dictionary()
+                << i.xface()
 		<< QString( Kleo::cryptoMessageFormatToString( i.mPreferredCryptoMessageFormat ) );
 }
 
@@ -397,6 +404,7 @@
 		>> i.mDrafts
 		>> i.mSignature
                 >> i.mDictionary
+                >> i.mXFace
 		>> format;
   i.mUoid = uoid;
   i.mPreferredCryptoMessageFormat = Kleo::stringToCryptoMessageFormat( format.latin1() );
@@ -556,6 +564,20 @@
   mDictionary = str;
   if ( mDictionary.isNull() )
     mDictionary = "";
+}
+
+
+//-----------------------------------------------------------------------------
+void Identity::setXFace( const QString &str )
+{
+  mXFace = str;
+}
+
+
+//-----------------------------------------------------------------------------
+void Identity::setXFaceEnabled( const bool on )
+{
+  mXFaceEnabled = on;
 }
 
 
diff -Nur old/libkpimidentities/identity.h new/libkpimidentities/identity.h
--- old/libkpimidentities/identity.h	Thu Nov 11 01:07:26 2004
+++ new/libkpimidentities/identity.h	Fri Nov 12 21:57:01 2004
@@ -273,6 +273,12 @@
   QString dictionary() const { return mDictionary; }
   void setDictionary( const QString& );
 
+  /** a X-Face header for this identity */
+  QString xface() const { return mXFace; }
+  void setXFace( const QString& );
+  bool isXFaceEnabled() const { return mXFaceEnabled; }
+  void setXFaceEnabled( const bool );
+
   static Identity null;
   bool isNull() const;
 protected:
@@ -288,6 +294,8 @@
   QCString mPGPEncryptionKey, mPGPSigningKey, mSMIMEEncryptionKey, mSMIMESigningKey;
   QString mFcc, mDrafts, mTransport;
   QString mDictionary;
+  QString mXFace;
+  bool mXFaceEnabled;
   Signature mSignature;
   bool      mIsDefault;
   Kleo::CryptoMessageFormat mPreferredCryptoMessageFormat;
