File indexing completed on 2024-04-28 15:39:40
0001 /************************************************************************ 0002 * * 0003 * This file is part of Kooka, a scanning/OCR application using * 0004 * Qt <http://www.qt.io> and KDE Frameworks <http://www.kde.org>. * 0005 * * 0006 * Copyright (C) 2000-2018 Klaas Freitag <freitag@suse.de> * 0007 * Jonathan Marten <jjm@keelhaul.me.uk> * 0008 * * 0009 * Kooka is free software; you can redistribute it and/or modify it * 0010 * under the terms of the GNU Library General Public License as * 0011 * published by the Free Software Foundation and appearing in the * 0012 * file COPYING included in the packaging of this file; either * 0013 * version 2 of the License, or (at your option) any later version. * 0014 * * 0015 * As a special exception, permission is given to link this program * 0016 * with any version of the KADMOS OCR/ICR engine (a product of * 0017 * reRecognition GmbH, Kreuzlingen), and distribute the resulting * 0018 * executable without including the source code for KADMOS in the * 0019 * source distribution. * 0020 * * 0021 * This program is distributed in the hope that it will be useful, * 0022 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0024 * GNU General Public License for more details. * 0025 * * 0026 * You should have received a copy of the GNU General Public * 0027 * License along with this program; see the file COPYING. If * 0028 * not, see <http://www.gnu.org/licenses/>. * 0029 * * 0030 ************************************************************************/ 0031 0032 #ifndef ABSTRACTOCRENGINE_H 0033 #define ABSTRACTOCRENGINE_H 0034 0035 #include <qobject.h> 0036 #include <qtextformat.h> 0037 #include <qprocess.h> 0038 0039 #include "scanimage.h" 0040 #include "abstractplugin.h" 0041 0042 /** 0043 *@author Klaas Freitag 0044 */ 0045 0046 class QProcess; 0047 class KConfigSkeletonItem; 0048 class ImageFormat; 0049 class ImageCanvas; 0050 class AbstractOcrDialogue; 0051 0052 #ifndef PLUGIN_EXPORT 0053 #define PLUGIN_EXPORT 0054 #endif 0055 0056 // Using a QTextDocument for the OCR results, with the source image rectangle 0057 // and other OCR information held as text properties. 0058 0059 class OcrWordData : public QTextCharFormat 0060 { 0061 public: 0062 enum DataType { 0063 Rectangle = QTextFormat::UserProperty, // QRect 0064 Alternatives, // QStringList 0065 KNode // int - not sure what this ever did 0066 }; 0067 0068 OcrWordData() : QTextCharFormat() {} 0069 }; 0070 0071 0072 class PLUGIN_EXPORT AbstractOcrEngine : public AbstractPlugin 0073 { 0074 Q_OBJECT 0075 0076 public: 0077 virtual ~AbstractOcrEngine(); 0078 0079 bool openOcrDialogue(QWidget *pnt = nullptr); 0080 0081 /** 0082 * Sets an image canvas that displays the result image of the OCR. 0083 * If this is set to @c nullptr (or never set) no result image is displayed. 0084 * The OCR fabric passes a new image to the canvas which is a copy of 0085 * the image to OCR. 0086 */ 0087 void setImageCanvas(ImageCanvas *canvas); 0088 void setTextDocument(QTextDocument *doc); 0089 0090 /** 0091 * Specify the image to be OCRed. 0092 * 0093 * @param img The image 0094 **/ 0095 void setImage(ScanImage::Ptr img); 0096 0097 /** 0098 * Check whether the image to be OCRed is black/white (just a bitmap). 0099 * 0100 * @return @c true if the image is pure black/white 0101 **/ 0102 bool isBW(); 0103 0104 QString findExecutable(QString (*settingFunc)(), KConfigSkeletonItem *settingItem); 0105 0106 void setErrorText(const QString &msg) { m_errorText.append(msg); } 0107 0108 /** 0109 * Check whether the engine has advanced settings: for example, the 0110 * pathname of an executable which performs the OCR. The actual dialogue 0111 * will be requested by @c openAdvancedSettings(). 0112 * 0113 * @return @c true if the engine has advanced settings 0114 **/ 0115 virtual bool hasAdvancedSettings() const { return (false); } 0116 0117 /** 0118 * Open a dialogue for advanced engine settings. This will only be 0119 * called if the engine has indicated that it has advanced settings, 0120 * by returning @c true from @c hasAdvancedSettings(). 0121 **/ 0122 virtual void openAdvancedSettings() {} 0123 0124 protected: 0125 explicit AbstractOcrEngine(QObject *pnt, const char *name); 0126 0127 virtual AbstractOcrDialogue *createOcrDialogue(AbstractOcrEngine *plugin, QWidget *pnt) = 0; 0128 0129 virtual QStringList tempFiles(bool retain) = 0; 0130 0131 /** 0132 * Save an image to a temporary file. 0133 * 0134 * @param img The image to save 0135 * @param format The image format to save in 0136 * @param colors The colour depth (bits per pixel) required. If specified, 0137 * this must be either 1, 8, 24 or 32. The default is for no colour 0138 * conversion. 0139 * 0140 * @return The file name as saved, or @c QString() if there was 0141 * an error. 0142 **/ 0143 QString tempSaveImage(ScanImage::Ptr img, const ImageFormat &format, int colors = -1); 0144 0145 /** 0146 * Get a name to use for a temporary file. 0147 * 0148 * @param suffix File name suffix, no leading '.' is required 0149 * @return The temporary file name, or @c QString() if the file could not be created 0150 * 0151 * @note The temporary file is created and is left in place under the returned name, 0152 * but is not opened. Its name should be saved and eventually returned in the 0153 * @c tempFiles() list so that it will be removed. 0154 **/ 0155 QString tempFileName(const QString &suffix, const QString &baseName = "ocrtemp"); 0156 0157 QTextDocument *startResultDocument(); 0158 void finishResultDocument(); 0159 0160 void startLine(); 0161 void addWord(const QString &word, const OcrWordData &data); 0162 void finishLine(); 0163 0164 bool verboseDebug() const; 0165 0166 virtual bool createOcrProcess(AbstractOcrDialogue *dia, ScanImage::Ptr img) = 0; 0167 0168 QProcess *initOcrProcess(); 0169 QProcess *ocrProcess() const { return (m_ocrProcess); } 0170 bool runOcrProcess(); 0171 virtual bool finishedOcrProcess(QProcess *proc) { Q_UNUSED(proc); return (true); } 0172 0173 void setResultImage(const QString &file) { m_ocrResultFile = file; } 0174 0175 signals: 0176 void newOCRResultText(); 0177 void openOcrPrefs(); 0178 0179 void setSpellCheckConfig(const QString &configFile); 0180 void startSpellCheck(bool interactive, bool background); 0181 0182 /** 0183 * Indicates that the text editor holding the text that came through 0184 * newOCRResultText should be set to readonly or not. Can be connected 0185 * to QTextEdit::setReadOnly directly. 0186 */ 0187 void readOnlyEditor(bool isReadOnly); 0188 0189 /** 0190 * Progress of the OCR process. The first integer is the main progress, 0191 * the second the sub progress. If there is only one progress, it is the 0192 * first parameter while the second should be -1. 0193 * Both have a range from 0..100. 0194 * 0195 * Note that this signal may not be emitted if the engine does not support 0196 * progress. 0197 */ 0198 void ocrProgress(int progress, int subprogress); 0199 0200 /** 0201 * Select a word in the editor corresponding to the position within 0202 * the result image. 0203 */ 0204 void selectWord(const QPoint &p); 0205 0206 public slots: 0207 void slotHighlightWord(const QRect &r); 0208 void slotScrollToWord(const QRect &r); 0209 0210 private slots: 0211 void slotStartOCR(); 0212 void slotStopOCR(); 0213 void slotClose(); 0214 0215 void slotProcessExited(int exitCode, QProcess::ExitStatus exitStatus); 0216 0217 /** 0218 * Handle mouse double clicks on the image viewer showing the 0219 * OCR result image. 0220 */ 0221 void slotImagePosition(const QPoint &p); 0222 0223 private: 0224 void stopOcrProcess(bool tellUser); 0225 void removeTempFiles(); 0226 void finishedOcr(bool success); 0227 0228 QString collectErrorMessages(const QString &starter, const QString &ender); 0229 0230 private: 0231 QWidget *m_parent; 0232 0233 QProcess *m_ocrProcess; 0234 bool m_ocrRunning; 0235 AbstractOcrDialogue *m_ocrDialog; 0236 QStringList m_errorText; 0237 QString m_ocrStderrLog; 0238 0239 QString m_ocrResultFile; 0240 ImageCanvas *m_imgCanvas; 0241 0242 ScanImage::Ptr m_introducedImage; 0243 bool m_resolvedBW; 0244 bool m_isBW; 0245 0246 QTextDocument *m_document; 0247 QTextCursor *m_cursor; 0248 int m_currHighlight; 0249 bool m_trackingActive; 0250 0251 int m_wordCount; 0252 }; 0253 0254 #endif // ABSTRACTOCRENGINE_H