File indexing completed on 2024-05-12 15:55:07

0001 /***************************************************************************
0002                              -------------------
0003     begin                : Fri Jun 30 2000
0004     copyright            : (C) 2000 by Klaas Freitag
0005     email                : freitag@suse.de
0006  ***************************************************************************/
0007 
0008 /***************************************************************************
0009  *                                                                         *
0010  *  This file may be distributed and/or modified under the terms of the    *
0011  *  GNU General Public License version 2 as published by the Free Software *
0012  *  Foundation and appearing in the file COPYING included in the           *
0013  *  packaging of this file.                                                *
0014  *
0015  *  As a special exception, permission is given to link this program       *
0016  *  with any version of the KADMOS ocr/icr engine of reRecognition GmbH,   *
0017  *  Kreuzlingen and distribute the resulting executable without            *
0018  *  including the source code for KADMOS in the source distribution.       *
0019  *
0020  *  As a special exception, permission is given to link this program       *
0021  *  with any edition of Qt, and distribute the resulting executable,       *
0022  *  without including the source code for Qt in the source distribution.   *
0023  *                                                                         *
0024  ***************************************************************************/
0025 
0026 #include "ocrkadmosengine.h"
0027 
0028 #include <qtemporaryfile.h>
0029 #ifdef QT_THREAD_SUPPORT
0030 #include <qtimer.h>
0031 #endif
0032 
0033 #include <klocalizedstring.h>
0034 #include <kmessagebox.h>
0035 
0036 #include "kookaimage.h"
0037 #include "ocrkadmosdialog.h"
0038 #include "ocr_logging.h"
0039 
0040 #define USE_KADMOS_FILEOP /* use a save-file for OCR instead of filling the reImage struct manually */
0041 
0042 /*
0043  * Thread support is disabled here because the kadmos lib seems not to be
0044  * thread safe, unfortunately. See slotKadmosResult-comments for more information
0045  */
0046 
0047 OcrKadmosEngine::OcrKadmosEngine(QWidget *parent)
0048     : OcrEngine(parent)
0049 {
0050     m_tmpFile = QString();
0051 }
0052 
0053 OcrKadmosEngine::~OcrKadmosEngine()
0054 {
0055 }
0056 
0057 OcrBaseDialog *OcrKadmosEngine::createOCRDialog(QWidget *parent)
0058 {
0059     //QT5 return (new KadmosDialog(parent));
0060     return 0;
0061 }
0062 
0063 OcrEngine::EngineType OcrKadmosEngine::engineType() const
0064 {
0065     return (OcrEngine::EngineKadmos);
0066 }
0067 
0068 QString OcrKadmosEngine::engineDesc()
0069 {
0070     return (xi18nc("@info %1 is one of the two following messages",
0071                    "<para><emphasis>Kadmos</emphasis> is a commercial OCR/ICR library produced by reRecognition&nbsp;AG.</para>"
0072                    "<para>%1</para>"
0073                    "<para>See <link url=\"http://www.rerecognition.com\">www.rerecognition.com</link> for more information on Kadmos.</para>",
0074 #ifdef HAVE_KADMOS
0075                    i18n("This version of Kooka is configured to use the Kadmos engine.")
0076 #else
0077                    i18n("This version of Kooka is not configured for Kadmos.  The Kadmos "
0078                         "libraries need to be installed, and Kooka needs to be rebuilt with "
0079                         "the '--with-kadmos' option.")
0080 #endif
0081                 ));
0082 }
0083 
0084 void OcrKadmosEngine::startProcess(OcrBaseDialog *dia, const ScanImage *img)
0085 {
0086     //qCDebug(OCR_LOG);
0087 #if 0 //QT5
0088     KadmosDialog *kadDia = static_cast<KadmosDialog *>(dia);
0089 
0090     QString clasPath;                   /* target where the clasPath is written in */
0091     if (! kadDia->getSelClassifier(clasPath)) {
0092         KMessageBox::error(m_parent,
0093                            i18n("The classifier file necessary for OCR cannot be loaded: %1;\n"
0094                                 "OCR with the KADMOS engine is not possible.",
0095                                 clasPath), i18n("KADMOS Installation Problem"));
0096         finishedOCRVisible(false);
0097         return;
0098     }
0099     QByteArray c = clasPath.toLatin1();
0100 
0101     //qCDebug(OCR_LOG) << "Using classifier" << c;
0102 #ifdef HAVE_KADMOS
0103     m_rep.Init(c);
0104     if (m_rep.kadmosError()) { /* check if kadmos initialised OK */
0105         KMessageBox::error(m_parent,
0106                            i18n("The KADMOS OCR system could not be started:\n"
0107                                 "%1\n"
0108                                 "Please check the configuration.",
0109                                 m_rep.getErrorText()),
0110                            i18n("KADMOS Failure"));
0111     } else {
0112         /** Since initialising succeeded, we start the ocr here **/
0113         m_rep.SetNoiseReduction(kadDia->getNoiseReduction());
0114         m_rep.SetScaling(kadDia->getAutoScale());
0115         //qCDebug(OCR_LOG) << "Image size [" << img->width() << " x " << img->height() << "]";
0116         //qCDebug(OCR_LOG) << "Image depth" << img->depth() << "colors" << img->numColors();
0117 #ifdef USE_KADMOS_FILEOP
0118         QTemporaryFile tmpFile(QDir::tempPath()+"/ocrkadmos_XXXXXX.bmp");
0119         tmpFile.setAutoRemove(false);
0120 
0121         if (!tmpFile.open()) {
0122             //qCDebug(OCR_LOG) << "error creating temporary file";
0123             return;
0124         }
0125         m_tmpFile = QFile::encodeName(tmpFile.fileName());
0126 
0127         //qCDebug(OCR_LOG) << "Saving to file" << m_tmpFile;
0128         img->save(&tmpFile, "BMP");         // save to temp file
0129         tmpFile.close();
0130         m_rep.SetImage(tmpFile);
0131 #else                           // USE_KADMOS_FILEOP
0132         m_rep.SetImage(img);
0133 #endif                          // USE_KADMOS_FILEOP
0134         m_rep.run();
0135 
0136         /* Dealing with threads or no threads (using QT_THREAD_SUPPORT to distinguish)
0137          * If threads are here, the recognition task is started in its own thread. The gui thread
0138          * needs to wait until the recognition thread is finished. Therefore, a timer is fired once
0139          * that calls slotKadmosResult and checks if the recognition task is finished. If it is not,
0140          * a new one-shot-timer is fired in slotKadmosResult. If it is, the OCR result can be
0141          * processed.
0142          * In case the system has no threads, the method start of the recognition engine does not
0143          * return until it is ready, the user has to live with a non responsive gui while
0144          * recognition is performed. The start()-method is implemented as a wrapper to the run()
0145          * method of CRep, which does the recognition job. Instead of pulling up a timer, simply
0146          * the result slot is called if start()=run() has finished. In the result slot, finished()
0147          * is only a dummy always returning true to avoid more preprocessor tags here.
0148          * Hope that works ...
0149          * It does not :( That is why it is not used here. Maybe some day...
0150          */
0151     }
0152 #endif                          // HAVE_KADMOS
0153 #ifdef QT_THREAD_SUPPORT
0154     /* start a timer and wait until it fires. */
0155     QTimer::singleShot(500, this, SLOT(slotKadmosResult()));
0156 #else                           // QT_THREAD_SUPPORT
0157     slotKadmosResult();
0158 #endif                          // QT_THREAD_SUPPORT
0159 #endif
0160     //qCDebug(OCR_LOG) << "done";
0161 }
0162 
0163 /*
0164  * This method is called to check if the kadmos process was already finished, if
0165  * thread support is enabled (check for preprocessor variable QT_THREAD_SUPPORT)
0166  * The problem is that the kadmos library seems not to be thread stable so thread
0167  * support should not be enabled by default. In case threads are enabled, this slot
0168  * checks if the KADMOS engine is finished already and if not it fires a timer.
0169  */
0170 
0171 void OcrKadmosEngine::slotKadmosResult()
0172 {
0173     //qCDebug(OCR_LOG);
0174 
0175 #ifdef HAVE_KADMOS
0176     if (m_rep.finished()) {
0177         /* The recognition thread is finished. */
0178         //qCDebug(OCR_LOG) << "Kadmos is finished";
0179 
0180         m_ocrResultText = "";
0181         if (! m_rep.kadmosError()) {
0182             int lines = m_rep.GetMaxLine();
0183             //qCDebug(OCR_LOG) << "Count lines" << lines;
0184             m_ocrPage.clear();
0185             m_ocrPage.resize(lines);
0186 
0187             for (int line = 0; line < m_rep.GetMaxLine(); line++) {
0188                 // ocrWordList wordList = m_rep.getLineWords(line);
0189                 /* call an ocr engine independent method to use the spellbook */
0190                 ocrWordList words = m_rep.getLineWords(line);
0191                 //qCDebug(OCR_LOG) << "Have" << words.count() << "entries in list";
0192                 m_ocrPage[line] = words;
0193             }
0194 
0195             /* show results of ocr */
0196             m_rep.End();
0197         }
0198         finishedOCRVisible(!m_rep.kadmosError());
0199     } else {
0200         /* recognition thread is not yet finished. Wait another half a second. */
0201         QTimer::singleShot(500, this, SLOT(slotKadmosResult()));
0202         /* Never comes here if no threads exist on the system */
0203     }
0204 #endif
0205 }
0206 
0207 QStringList OcrKadmosEngine::tempFiles(bool retain)
0208 {
0209     QStringList result;
0210 
0211 #ifdef USE_KADMOS_FILEOP
0212     if (!m_tmpFile.isNull()) {
0213         result << m_tmpFile;
0214         m_tmpFile = QString();
0215     }
0216 #endif
0217 
0218     return (result);
0219 }