From 7be070744ba361e61d273b3eefef441b765c7ca3 Mon Sep 17 00:00:00 2001 From: Gres Date: Fri, 29 Jul 2022 23:09:56 +0300 Subject: [PATCH] Use single tesseract library Link with it during compilation. Bump to 5.2.0. --- screen-translator.pro | 2 +- share/ci/appimage.py | 3 +- share/ci/get_tesseract.py | 116 +++++------------ share/ci/release.py | 7 -- share/translations/screentranslator_ru.ts | 98 +++++++-------- src/ocr/recognizer.cpp | 6 +- src/ocr/recognizer.h | 2 +- src/ocr/recognizerworker.cpp | 10 +- src/ocr/recognizerworker.h | 3 +- src/ocr/tesseract.cpp | 146 ++++------------------ src/ocr/tesseract.h | 11 +- src/settings.cpp | 41 ------ src/settings.h | 3 - src/settingseditor.cpp | 18 +-- src/settingseditor.ui | 54 ++++---- 15 files changed, 145 insertions(+), 375 deletions(-) diff --git a/screen-translator.pro b/screen-translator.pro index 6452ef9..7713b76 100644 --- a/screen-translator.pro +++ b/screen-translator.pro @@ -8,7 +8,7 @@ DEPS_DIR=$$(ST_DEPS_DIR) isEmpty(DEPS_DIR):DEPS_DIR=$$PWD/../deps INCLUDEPATH += $$DEPS_DIR/include LIBS += -L$$DEPS_DIR/lib -LIBS += -lhunspell -lleptonica +LIBS += -lhunspell -lleptonica -ltesseract win32{ LIBS += -lUser32 diff --git a/share/ci/appimage.py b/share/ci/appimage.py index 1e6b26f..331d40f 100644 --- a/share/ci/appimage.py +++ b/share/ci/appimage.py @@ -47,8 +47,7 @@ flags = '' if os.getenv("DEBUG") is None else '-unsupported-allow-new-glibc' additional_files = glob(ssl_dir + '/lib/lib*.so.*') + \ - glob('/usr/lib/x86_64-linux-gnu/nss/*') + \ - glob(dependencies_dir + '/lib/libtesseract-*.so') + glob('/usr/lib/x86_64-linux-gnu/nss/*') out_lib_dir = install_dir + '/usr/lib' os.makedirs(out_lib_dir, exist_ok=True) for f in additional_files: diff --git a/share/ci/get_tesseract.py b/share/ci/get_tesseract.py index 301e763..5fa8cc0 100644 --- a/share/ci/get_tesseract.py +++ b/share/ci/get_tesseract.py @@ -6,27 +6,12 @@ c.print('>> Installing tesseract') install_dir = dependencies_dir -url = 'https://github.com/tesseract-ocr/tesseract/archive/5.1.0.tar.gz' -required_version = '5.1.0' +required_version = '5.2.0' +url = 'https://github.com/tesseract-ocr/tesseract/archive/{}.tar.gz'.format(required_version) build_type_flag = 'Debug' if build_type == 'debug' else 'Release' -# compatibility flags -compat_flags = '' -compat_flags += ' -D DISABLE_LEGACY_ENGINE=ON ' -compat_flags += ' -D DISABLE_ARCHIVE=ON ' -compat_flags += ' -D DISABLE_CURL=ON ' - -version_tag = os.environ.get('TAG', '') -if version_tag == 'compatible': - compat_flags += ' -D HAVE_AVX2=0 ' - compat_flags += ' -D HAVE_FMA=0 ' - -lib_suffix = version_tag -if len(lib_suffix) > 0: - lib_suffix = '-' + lib_suffix - -cache_file = install_dir + '/tesseract{}.cache'.format(lib_suffix) +cache_file = install_dir + '/tesseract.cache' cache_file_data = required_version + build_type_flag def check_existing(): @@ -42,22 +27,25 @@ def check_existing(): return False if platform.system() == "Windows": - lib = install_dir + '/bin/tesseract{}.dll'.format(lib_suffix) - orig_lib = install_dir + '/bin/tesseract51.dll' + file_name_ver = required_version[0] + required_version[2] + dll = install_dir + '/bin/tesseract{}.dll'.format(file_name_ver) + lib = install_dir + '/lib/tesseract{}.lib'.format(file_name_ver) + if not os.path.exists(dll) or not os.path.exists(lib): + return False + c.symlink(dll, install_dir + '/bin/tesseract.dll') + c.symlink(lib, install_dir + '/lib/tesseract.lib') elif platform.system() == "Darwin": - lib = install_dir + '/lib/libtesseract{}.dylib'.format(lib_suffix) - orig_lib = install_dir + '/lib/libtesseract.{}.dylib'.format(required_version) + lib = install_dir + '/lib/libtesseract.{}.dylib'.format(required_version) + if not os.path.exists(lib): + return False + c.symlink(lib, install_dir + '/lib/libtesseract.dylib') else: - lib = install_dir + '/lib/libtesseract{}.so'.format(lib_suffix) - orig_lib = install_dir + '/lib/libtesseract.so.{}'.format(required_version) - - if os.path.exists(lib): - return True - if os.path.exists(orig_lib): - os.rename(orig_lib, lib) - return True + lib = install_dir + '/lib/libtesseract.so.{}'.format(required_version) + if not os.path.exists(lib): + return False + c.symlink(lib, install_dir + '/lib/libtesseract.so') - return False + return True if check_existing() and not 'FORCE' in os.environ: @@ -71,60 +59,24 @@ def check_existing(): c.extract(archive, '.') c.symlink(c.get_archive_top_dir(archive), src_dir) -if platform.system() == "Windows": - # workaround for not found 'max' - modify_data = '' - modify_file = '{}/src/ccmain/thresholder.cpp'.format(src_dir) - with open(modify_file, 'r') as f: - modify_data = f.read() - - if modify_data.find('') == -1: - modify_data = modify_data.replace( - '''''', - '''\n#include ''') - - with open(modify_file, 'w') as f: - f.write(modify_data) - - # ignore libtiff - modify_data = '' - modify_file = '{}/CMakeLists.txt'.format(src_dir) - with open(modify_file, 'r') as f: - modify_data = f.read() - - if modify_data.find('#pkg_check_modules(TIFF libtiff-4)') == -1: - modify_data = modify_data.replace( - '''pkg_check_modules(TIFF libtiff-4)''', - '''#pkg_check_modules(TIFF libtiff-4)''') - - with open(modify_file, 'w') as f: - f.write(modify_data) - -if platform.system() == "Linux": - # FIXME fix crash on ubuntu - modify_data = '' - modify_file = '{}/src/ccmain/tessedit.cpp'.format(src_dir) - with open(modify_file, 'r') as f: - modify_data = f.read() - - lines = modify_data.split('\n') - for line in [250,253,255,256]: - if not lines[line].startswith('//'): - lines[line] = '// ' + lines[line] - modify_data = '\n'.join(lines) - - with open(modify_file, 'w') as f: - f.write(modify_data) - - - c.ensure_got_path(install_dir) c.recreate_dir(build_dir) os.chdir(build_dir) -cmake_args = '"{0}" -DCMAKE_INSTALL_PREFIX="{1}" -DLeptonica_DIR="{1}/cmake" \ --DBUILD_TRAINING_TOOLS=OFF -DBUILD_TESTS=OFF -DBUILD_SHARED_LIBS=ON -DSW_BUILD=OFF \ +cmake_args = '"{0}" \ +-DCMAKE_INSTALL_PREFIX="{1}" \ +-DLeptonica_DIR="{1}/cmake" \ +-DSW_BUILD=OFF \ +-DBUILD_TRAINING_TOOLS=OFF \ +-DBUILD_TESTS=OFF \ +-DBUILD_SHARED_LIBS=ON \ +-DDISABLE_CURL=ON \ +-DDISABLE_ARCHIVE=ON \ +-DUSE_SYSTEM_ICU=ON \ +-DENABLE_LTO=ON \ +-DGRAPHICS_DISABLED=ON \ +-DDISABLED_LEGACY_ENGINE=ON \ '.format(src_dir, install_dir) if platform.system() == "Windows": @@ -135,10 +87,6 @@ def check_existing(): c.set_make_threaded() c.run('cmake {}'.format(cmake_args)) -if len(compat_flags) > 0: - c.run('cmake {} .'.format(compat_flags)) - c.run('cmake {} .'.format(compat_flags)) # for sure :) - c.run('cmake --build . --config {}'.format(build_type_flag)) c.run('cmake --build . --target install --config {}'.format(build_type_flag)) diff --git a/share/ci/release.py b/share/ci/release.py index 7b0416c..aa80fee 100644 --- a/share/ci/release.py +++ b/share/ci/release.py @@ -29,15 +29,8 @@ def r(script): r('get_qt.py') r('get_qt_ssl.py') r('get_leptonica.py') - -os.environ['TAG'] = 'optimized' -r('get_tesseract.py') - -os.environ['TAG'] = 'compatible' r('get_tesseract.py') -del os.environ['TAG'] - r('get_hunspell.py') r('test.py') r('build.py') diff --git a/share/translations/screentranslator_ru.ts b/share/translations/screentranslator_ru.ts index 1bf9b90..0b6b860 100644 --- a/share/translations/screentranslator_ru.ts +++ b/share/translations/screentranslator_ru.ts @@ -673,12 +673,12 @@ Check for updates to silence this warning неизвестные языки для перевода: %1 или %2 - + init failed ошибка инициалиизации - + Failed to recognize text or no text selected Ошибка распознавания текста или нет текста в выделенной зоне @@ -697,12 +697,12 @@ in %1 в %1 - + No source language set Не задан исходный язык - + No target language set Не задан язык результата @@ -712,37 +712,37 @@ in %1 Не восстанавливать интерфейс пользователя (размер и положения окна и т.д.) - + <p>Optical character recognition (OCR) and translation tool</p> <p>Инструмент оптического распознавания текста (OCR) и перевода</p> - + <p>Version: %1</p> <p>Версия: %1</p> - + <p>Setup instructions: <a href="%1">%1</a></p> <p>Инструкции по установке: <a href="%1">%1</a></p> - + <p>Changelog: <a href="%1">%2</a></p> <p>Список изменений: <a href="%1">%2</a></p> - + <p>License: <a href="%3">MIT</a></p> <p>Лицензия: <a href="%3">MIT</a></p> - + <p>Author: Gres (<a href="mailto:%1">%1</a>)</p> <p>Автор: Gres (<a href="mailto:%1">%1</a>)</p> - + <p>Issues: <a href="%1">%1</a></p> <p>Поддержка: <a href="%1">%1</a></p> @@ -844,7 +844,7 @@ in %1 Повторить захват - + Without correction: Без коррекции: @@ -919,42 +919,41 @@ in %1 сохранять пароль (небезопасно) - Library version - Версия + Версия - + User substitutions Пользовательская коррекция - + Use auto corrections (hunspell) Использовать автокоррекцию (hunspell) - + Use user substitutions Использовать пользовательскую коррекцию - + Hunspell dictionaries path: Путь к словарям Hunspell: - + Language: Язык: - + secs сек - + Ignore SSL errors Игнорировать ошибки SSL @@ -984,102 +983,102 @@ in %1 Писать логи в файл (отладка) - + Default language: Язык по умолчанию: - + Tessdata path: Путь к языкам (tessdata): - + \\ for \ symbol, \n for newline \\ для символа \ , \n для символа новой строки - + Translators path: Путь к переводчикам: - + Translators Переводчики - + Result window Окно результата - + Font: Шрифт: - + Font size: Размер шрифта: - + Font color: Цвет шрифта: - + Background: Фон: - + Show image Показывать изображение - + Show recognized Показывать распознанное - + Update check interval (days): Интервал проверки обновления (дней): - + 0 - disabled - отключено - + Translate text Переводить текст - + Single translator timeout: Переходить к следующему переводчику после: - + Result type Тип результата - + Tray Трей - + Window Окно - + Check now Проверить сейчас @@ -1175,32 +1174,29 @@ Hunspell ищет в своем словаре слова, похожие на HTTP - Optimized - Оптимизированная + Оптимизированная - Compatible - Совместимая + Совместимая - Use compatible version if you are experiencing crashes during recognition - Используйте совместимую версию если программа неожиданно завершается во время распознавания + Используйте совместимую версию если программа неожиданно завершается во время распознавания - + <b>NOTE! Some translators might require the translation window to be visible. You can make it using the "Show translator" entry in the tray icon's context menu</b> <b>ПРИМЕЧАНИЕ! Для работы некоторых переводчиков может потребоваться активное окно перевода. Его можно отобразить при помощи пункта "Показать окно перевода" контекстного меню иконки в трее</b> - + Sample text Текст для проверки - + The program workflow consists of the following steps: 1. Selection on the screen area 2. Recognition of the selected area @@ -1223,7 +1219,7 @@ Then set default recognition and translation languages, enable some (or all) tra Далее установите языки распознавания и перевода по умолчанию, активируйте некоторые (или все) переводчики и настройку "переводить текст", если нужно. - + Portable changed. Apply settings first Portable режим изменен. Сначала примените настройки diff --git a/src/ocr/recognizer.cpp b/src/ocr/recognizer.cpp index c9b422c..99866b4 100644 --- a/src/ocr/recognizer.cpp +++ b/src/ocr/recognizer.cpp @@ -79,9 +79,5 @@ void Recognizer::updateSettings() SOFT_ASSERT(!settings_.tessdataPath.isEmpty(), return ); queue_.clear(); - const auto libName = - (settings_.tesseractVersion == TesseractVersion::Optimized - ? "tesseract-optimized" - : "tesseract-compatible"); - emit reset(settings_.tessdataPath, libName); + emit reset(settings_.tessdataPath); } diff --git a/src/ocr/recognizer.h b/src/ocr/recognizer.h index eb227df..8bc0216 100644 --- a/src/ocr/recognizer.h +++ b/src/ocr/recognizer.h @@ -18,7 +18,7 @@ class Recognizer : public QObject signals: void recognizeImpl(const TaskPtr &task); - void reset(const QString &tessdataPath, const QString &tesseractLibrary); + void reset(const QString &tessdataPath); private: void recognized(const TaskPtr &task); diff --git a/src/ocr/recognizerworker.cpp b/src/ocr/recognizerworker.cpp index b7a6080..40d354f 100644 --- a/src/ocr/recognizerworker.cpp +++ b/src/ocr/recognizerworker.cpp @@ -17,8 +17,8 @@ void RecognizeWorker::handle(const TaskPtr &task) if (!engines_.count(task->sourceLanguage)) { LTRACE() << "Create OCR engine" << task->sourceLanguage; - auto engine = std::make_unique(task->sourceLanguage, - tessdataPath_, tesseractLibrary_); + auto engine = + std::make_unique(task->sourceLanguage, tessdataPath_); if (!engine->isValid()) { result->error = tr("Failed to init OCR engine: %1").arg(engine->error()); @@ -43,14 +43,12 @@ void RecognizeWorker::handle(const TaskPtr &task) emit finished(result); } -void RecognizeWorker::reset(const QString &tessdataPath, - const QString &tesseractLibrary) +void RecognizeWorker::reset(const QString &tessdataPath) { - if (tessdataPath_ == tessdataPath && tesseractLibrary_ == tesseractLibrary) + if (tessdataPath_ == tessdataPath) return; tessdataPath_ = tessdataPath; - tesseractLibrary_ = tesseractLibrary; engines_.clear(); LTRACE() << "Cleared OCR engines"; } diff --git a/src/ocr/recognizerworker.h b/src/ocr/recognizerworker.h index db44057..74350b3 100644 --- a/src/ocr/recognizerworker.h +++ b/src/ocr/recognizerworker.h @@ -13,7 +13,7 @@ class RecognizeWorker : public QObject ~RecognizeWorker(); void handle(const TaskPtr &task); - void reset(const QString &tessdataPath, const QString &tesseractLibrary); + void reset(const QString &tessdataPath); signals: void finished(const TaskPtr &task); @@ -24,5 +24,4 @@ class RecognizeWorker : public QObject std::map> engines_; std::map lastGenerations_; QString tessdataPath_; - QString tesseractLibrary_; }; diff --git a/src/ocr/tesseract.cpp b/src/ocr/tesseract.cpp index 41458ff..0b8adb2 100644 --- a/src/ocr/tesseract.cpp +++ b/src/ocr/tesseract.cpp @@ -4,6 +4,7 @@ #include "task.h" #include +#include #include #include @@ -204,115 +205,7 @@ static Pix *prepareImage(const QImage &image) return pix.take(); } -static void cleanupImage(Pix **image) -{ - pixDestroy(image); -} - -// do not include capi.h from tesseract because it defined BOOL that breaks msvc -struct TessBaseAPI; - -class Tesseract::Wrapper -{ - using CreateApi = TessBaseAPI *(*)(); - using DeleteApi = void (*)(TessBaseAPI *); - using InitApi = int (*)(TessBaseAPI *, const char *, const char *, int); - using SetImage = void (*)(TessBaseAPI *, struct Pix *); - using GetUtf8 = char *(*)(TessBaseAPI *); - using ClearApi = void (*)(TessBaseAPI *); - using DeleteUtf8 = void (*)(const char *); - using SetPageMode = void (*)(TessBaseAPI *, int); - -public: - explicit Wrapper(const QString &libraryName) - : lib(libraryName) - { - if (!lib.load()) { - LERROR() << "Failed to load tesseract library" << libraryName; - return; - } - - LTRACE() << "Loaded tesseract library" << lib.fileName(); - auto ok = true; - ok &= bool(createApi_ = (CreateApi)lib.resolve("TessBaseAPICreate")); - ok &= bool(deleteApi_ = (DeleteApi)lib.resolve("TessBaseAPIDelete")); - ok &= bool(initApi_ = (InitApi)lib.resolve("TessBaseAPIInit2")); - ok &= bool(setImage_ = (SetImage)lib.resolve("TessBaseAPISetImage2")); - ok &= bool(getUtf8_ = (GetUtf8)lib.resolve("TessBaseAPIGetUTF8Text")); - ok &= bool(clearApi_ = (ClearApi)lib.resolve("TessBaseAPIClear")); - ok &= bool(deleteUtf8_ = (DeleteUtf8)lib.resolve("TessDeleteText")); - ok &= bool(setPageMode_ = - (SetPageMode)lib.resolve("TessBaseAPISetPageSegMode")); - if (!ok) { - LERROR() << "Failed to resolve tesseract functions from" << libraryName; - return; - } - handle_ = createApi_(); - } - - ~Wrapper() - { - if (handle_ && deleteApi_) { - deleteApi_(handle_); - } - lib.unload(); - } - - int Init(const char *datapath, const char *language) - { - SOFT_ASSERT(handle_, return -1); - SOFT_ASSERT(initApi_, return -1); - - const auto mode = 3; // TessOcrEngineMode::OEM_DEFAULT - return initApi_(handle_, datapath, language, mode); - } - - QString GetText(Pix *pix) - { - SOFT_ASSERT(handle_, return {}); - - SOFT_ASSERT(setPageMode_, return {}); - setPageMode_(handle_, 3); // PSM_AUTO - - SOFT_ASSERT(setImage_, return {}); - setImage_(handle_, pix); - LTRACE() << "Set Pix to engine"; - - char *outText = nullptr; - - SOFT_ASSERT(getUtf8_, return {}); - outText = getUtf8_(handle_); - LTRACE() << "Received recognized text"; - - SOFT_ASSERT(clearApi_, return {}); - clearApi_(handle_); - LTRACE() << "Cleared engine"; - - const auto result = QString(outText).trimmed(); - - SOFT_ASSERT(deleteUtf8_, return {}); - deleteUtf8_(outText); - LTRACE() << "Cleared recognized text buffer"; - - return result; - } - -private: - QLibrary lib; - CreateApi createApi_{nullptr}; - DeleteApi deleteApi_{nullptr}; - InitApi initApi_{nullptr}; - SetImage setImage_{nullptr}; - GetUtf8 getUtf8_{nullptr}; - ClearApi clearApi_{nullptr}; - DeleteUtf8 deleteUtf8_{nullptr}; - SetPageMode setPageMode_{nullptr}; - TessBaseAPI *handle_{nullptr}; -}; - -Tesseract::Tesseract(const LanguageId &language, const QString &tessdataPath, - const QString &tesseractLibrary) - : tesseractLibrary_(tesseractLibrary) +Tesseract::Tesseract(const LanguageId &language, const QString &tessdataPath) { SOFT_ASSERT(!tessdataPath.isEmpty(), return ); SOFT_ASSERT(!language.isEmpty(), return ); @@ -324,20 +217,22 @@ Tesseract::~Tesseract() = default; void Tesseract::init(const LanguageId &language, const QString &tessdataPath) { - SOFT_ASSERT(!engine_, return ); + SOFT_ASSERT(!api_, return ); - engine_ = std::make_unique(tesseractLibrary_); - LTRACE() << "Created Tesseract api" << engine_.get(); + api_ = std::make_unique(); + LTRACE() << "Created Tesseract api" << api_.get(); const auto tesseractName = LanguageCodes::tesseract(language); - auto result = - engine_->Init(qPrintable(tessdataPath), qPrintable(tesseractName)); + auto result = api_->Init(qPrintable(tessdataPath), qPrintable(tesseractName), + tesseract::OcrEngineMode::OEM_DEFAULT); LTRACE() << "Inited Tesseract api" << result; if (result == 0) return; + api_->SetPageSegMode(tesseract::PageSegMode::PSM_AUTO); + error_ = QObject::tr("init failed"); - engine_.reset(); + api_.reset(); LTRACE() << "Cleared Tesseract api"; } @@ -372,19 +267,28 @@ QStringList Tesseract::availableLanguageNames(const QString &path) QString Tesseract::recognize(const QPixmap &source) { - SOFT_ASSERT(engine_, return {}); + SOFT_ASSERT(api_, return {}); SOFT_ASSERT(!source.isNull(), return {}); error_.clear(); - Pix *image = prepareImage(source.toImage()); + PixGuard image(prepareImage(source.toImage())); SOFT_ASSERT(image, return {}); LTRACE() << "Preprocessed Pix for OCR" << image; - auto result = engine_->GetText(image); + api_->SetImage(image); + LTRACE() << "Set Pix to engine"; + + const auto outText = api_->GetUTF8Text(); + LTRACE() << "Received recognized text"; + + api_->Clear(); + LTRACE() << "Cleared engine"; + + const auto result = QString(outText).trimmed(); - cleanupImage(&image); - LTRACE() << "Cleared preprocessed Pix"; + delete[] outText; + LTRACE() << "Cleared recognized text buffer"; if (result.isEmpty()) error_ = QObject::tr("Failed to recognize text or no text selected"); @@ -393,5 +297,5 @@ QString Tesseract::recognize(const QPixmap &source) bool Tesseract::isValid() const { - return engine_.get(); + return api_.get(); } diff --git a/src/ocr/tesseract.h b/src/ocr/tesseract.h index 36d7911..0ddf088 100644 --- a/src/ocr/tesseract.h +++ b/src/ocr/tesseract.h @@ -8,12 +8,15 @@ class QPixmap; class Task; +namespace tesseract +{ +class TessBaseAPI; +} class Tesseract { public: - Tesseract(const LanguageId& language, const QString& tessdataPath, - const QString& tesseractLibrary); + Tesseract(const LanguageId& language, const QString& tessdataPath); ~Tesseract(); QString recognize(const QPixmap& source); @@ -23,10 +26,8 @@ class Tesseract static QStringList availableLanguageNames(const QString& path); private: - class Wrapper; void init(const LanguageId& language, const QString& tessdataPath); - const QString tesseractLibrary_; - std::unique_ptr engine_; + std::unique_ptr api_; QString error_; }; diff --git a/src/settings.cpp b/src/settings.cpp index 8f8d833..8b073af 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -35,7 +35,6 @@ const QString qs_showMessageOnStart = "showMessageOnStart"; const QString qs_recogntionGroup = "Recognition"; const QString qs_ocrLanguage = "language"; -const QString qs_tesseractVersion = "tesseractVersion"; const QString qs_correctionGroup = "Correction"; const QString qs_userSubstitutions = "userSubstitutions"; @@ -133,36 +132,6 @@ void cleanupOutdated(QSettings& settings) settings.endGroup(); } -#ifdef _MSC_VER -#include -void cpuid(int leaf, int subleaf, std::array& cpuinfo) -{ - __cpuidex(reinterpret_cast(cpuinfo.data()), leaf, subleaf); -} -#else -#include -void cpuid(int leaf, int subleaf, std::array& cpuinfo) -{ - __get_cpuid_count(leaf, subleaf, &cpuinfo[0], &cpuinfo[1], &cpuinfo[2], - &cpuinfo[3]); -} -#endif - -bool checkOptimizedTesseractSupport() -{ - std::array cpuinfo{0}; - - cpuid(1, 0, cpuinfo); - const bool sse4_1 = cpuinfo[2] & (1 << 19); - const bool sse4_2 = cpuinfo[2] & (1 << 20); - const bool avx = cpuinfo[2] & (1 << 28); - - cpuid(7, 0, cpuinfo); - const bool avx2 = cpuinfo[1] & (1 << 5); - - return sse4_1 && sse4_2 && avx && avx2; -} - } // namespace void Settings::save() const @@ -207,7 +176,6 @@ void Settings::save() const settings.beginGroup(qs_recogntionGroup); settings.setValue(qs_ocrLanguage, sourceLanguage); - settings.setValue(qs_tesseractVersion, int(tesseractVersion)); settings.endGroup(); settings.beginGroup(qs_correctionGroup); @@ -295,15 +263,6 @@ void Settings::load() settings.beginGroup(qs_recogntionGroup); sourceLanguage = settings.value(qs_ocrLanguage, sourceLanguage).toString(); - if (!settings.contains(qs_tesseractVersion)) { - tesseractVersion = checkOptimizedTesseractSupport() - ? TesseractVersion::Optimized - : TesseractVersion::Compatible; - } else { - tesseractVersion = TesseractVersion(std::clamp( - settings.value(qs_tesseractVersion, int(tesseractVersion)).toInt(), - int(TesseractVersion::Optimized), int(TesseractVersion::Compatible))); - } settings.endGroup(); settings.beginGroup(qs_correctionGroup); diff --git a/src/settings.h b/src/settings.h index 703a89c..fef273e 100644 --- a/src/settings.h +++ b/src/settings.h @@ -19,8 +19,6 @@ using Substitutions = std::multimap; enum class ProxyType { Disabled, System, Socks5, Http }; -enum class TesseractVersion { Optimized, Compatible }; - class Settings { public: @@ -60,7 +58,6 @@ class Settings QString tessdataPath; QString sourceLanguage{"eng"}; - TesseractVersion tesseractVersion{TesseractVersion::Optimized}; bool doTranslation{true}; bool ignoreSslErrors{false}; diff --git a/src/settingseditor.cpp b/src/settingseditor.cpp index 4bf4f17..6b4b1d1 100644 --- a/src/settingseditor.cpp +++ b/src/settingseditor.cpp @@ -122,14 +122,6 @@ SettingsEditor::SettingsEditor(Manager &manager, update::Updater &updater) // recognition ui->tesseractLangCombo->setModel(models_.sourceLanguageModel()); - const QMap tesseractVersions{ - {TesseractVersion::Optimized, tr("Optimized")}, - {TesseractVersion::Compatible, tr("Compatible")}, - }; - ui->tesseractVersion->addItems(tesseractVersions.values()); - ui->tesseractVersion->setToolTip( - tr("Use compatible version if you are experiencing crashes during " - "recognition")); // correction ui->userSubstitutionsTable->setEnabled(ui->useUserSubstitutions->isChecked()); @@ -191,14 +183,15 @@ SettingsEditor::SettingsEditor(Manager &manager, update::Updater &updater) (locale.language() == QLocale::Russian ? "ru" : "en") + ".md"; const auto license = baseUrl + "/blob/master/LICENSE.md"; const auto help = locale.language() == QLocale::Russian - ? "https://translator.gres.biz/page/download/" - : baseUrl + "/blob/master/README.md"; + ? "https://translator.gres.biz/page/download/" + : baseUrl + "/blob/master/README.md"; const auto aboutLines = QStringList{ QObject::tr( R"(

Optical character recognition (OCR) and translation tool

)"), QObject::tr(R"(

Version: %1

)") .arg(QApplication::applicationVersion()), - QObject::tr(R"(

Setup instructions: %1

)").arg(help), + QObject::tr(R"(

Setup instructions: %1

)") + .arg(help), QObject::tr(R"(

Changelog: %2

)") .arg(changelog, QUrl(changelog).fileName()), QObject::tr(R"(

License: MIT

)").arg(license), @@ -267,8 +260,6 @@ Settings SettingsEditor::settings() const settings.sourceLanguage = LanguageCodes::idForName(ui->tesseractLangCombo->currentText()); - settings.tesseractVersion = - TesseractVersion(ui->tesseractVersion->currentIndex()); settings.useHunspell = ui->useHunspell->isChecked(); settings.useUserSubstitutions = ui->useUserSubstitutions->isChecked(); @@ -328,7 +319,6 @@ void SettingsEditor::setSettings(const Settings &settings) ui->tesseractLangCombo->setCurrentText( LanguageCodes::name(settings.sourceLanguage)); - ui->tesseractVersion->setCurrentIndex(int(settings.tesseractVersion)); ui->useHunspell->setChecked(settings.useHunspell); ui->hunspellDir->setText(settings.hunspellPath); diff --git a/src/settingseditor.ui b/src/settingseditor.ui index 2c3dc7b..ab41a1d 100644 --- a/src/settingseditor.ui +++ b/src/settingseditor.ui @@ -221,7 +221,7 @@ - + @@ -231,7 +231,7 @@ - + @@ -241,7 +241,7 @@ - + @@ -251,7 +251,7 @@ - + @@ -268,7 +268,7 @@ - + @@ -291,7 +291,23 @@ - + + + + + 0 + 0 + + + + Tessdata path: + + + + + + + Qt::Vertical @@ -317,19 +333,6 @@ - - - - - 0 - 0 - - - - Tessdata path: - - - @@ -346,19 +349,6 @@ - - - - - - - Library version - - - - - -