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 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 }