636 {
637#if defined(__USE_GNU) && defined(HAVE_FEENABLEEXCEPT)
638
639# if defined(__clang__)
640
641 feenableexcept(FE_DIVBYZERO);
642# else
643 feenableexcept(FE_DIVBYZERO | FE_OVERFLOW | FE_INVALID);
644# endif
645#endif
646 const char *lang = nullptr;
647 const char *image = nullptr;
648 const char *outputbase = nullptr;
649 const char *datapath = nullptr;
650 bool list_langs = false;
651 bool print_parameters = false;
652 bool print_fonts_table = false;
653 l_int32 dpi = 0;
654 int arg_i = 1;
656#ifdef DISABLED_LEGACY_ENGINE
658#else
660#endif
661 std::vector<std::string> vars_vec;
662 std::vector<std::string> vars_values;
663
664 if (std::getenv("LEPT_MSG_SEVERITY")) {
665
666 setMsgSeverity(L_SEVERITY_EXTERNAL);
667 } else {
668
669 setMsgSeverity(L_SEVERITY_ERROR);
670 }
671
672#if defined(HAVE_TIFFIO_H) && defined(_WIN32)
673
674 TIFFSetErrorHandler(Win32ErrorHandler);
675 TIFFSetWarningHandler(Win32WarningHandler);
676#endif
677
678 if (!ParseArgs(argc, argv, &lang, &image, &outputbase, &datapath, &dpi, &list_langs,
679 &print_parameters, &print_fonts_table, &vars_vec, &vars_values, &arg_i,
680 &pagesegmode, &enginemode)) {
681 return EXIT_FAILURE;
682 }
683
684 bool in_recognition_mode = !list_langs && !print_parameters && !print_fonts_table;
685
686 if (lang == nullptr && in_recognition_mode) {
687
688 lang = "eng";
689 }
690
691 if (image == nullptr && in_recognition_mode) {
692 return EXIT_SUCCESS;
693 }
694
695
696
697
699
701
703
704 const int init_failed = api.
Init(datapath, lang, enginemode, &(argv[arg_i]), argc - arg_i,
705 &vars_vec, &vars_values, false);
706
707 if (!SetVariablesFromCLArgs(api, argc, argv)) {
708 return EXIT_FAILURE;
709 }
710
711
713
714 if (list_langs) {
715 PrintLangsList(api);
716 return EXIT_SUCCESS;
717 }
718
719 if (init_failed) {
720 fprintf(stderr, "Could not initialize tesseract.\n");
721 return EXIT_FAILURE;
722 }
723
724 if (print_parameters) {
725 FILE *fout = stdout;
726 fprintf(stdout, "Tesseract parameters:\n");
729 return EXIT_SUCCESS;
730 }
731
732#ifndef DISABLED_LEGACY_ENGINE
733 if (print_fonts_table) {
734 FILE *fout = stdout;
735 fprintf(stdout, "Tesseract fonts table:\n");
738 return EXIT_SUCCESS;
739 }
740#endif
741
742 FixPageSegMode(api, pagesegmode);
743
744 if (dpi) {
745 auto dpi_string = std::to_string(dpi);
746 api.
SetVariable(
"user_defined_dpi", dpi_string.c_str());
747 }
748
749 int ret_val = EXIT_SUCCESS;
750
752 Pix *pixs = pixRead(image);
753 if (!pixs) {
754 fprintf(stderr, "Leptonica can't process input file: %s\n", image);
755 return 2;
756 }
757
759
763 float deskew_angle;
764
765 const std::unique_ptr<const tesseract::PageIterator> it(api.
AnalyseLayout());
766 if (it) {
767
768
769 it->Orientation(&orientation, &direction, &order, &deskew_angle);
771 "Orientation: %d\nWritingDirection: %d\nTextlineOrder: %d\n"
772 "Deskew angle: %.4f\n",
773 orientation, direction, order, deskew_angle);
774 } else {
775 ret_val = EXIT_FAILURE;
776 }
777
778 pixDestroy(&pixs);
779 return ret_val;
780 }
781
782
783
784
785 bool b = false;
786 bool in_training_mode = (api.
GetBoolVariable(
"tessedit_ambigs_training", &b) && b) ||
790
793 fprintf(stderr, "Error, OSD requires a model for the legacy engine\n");
794 return EXIT_FAILURE;
795 }
796 }
797#ifdef DISABLED_LEGACY_ENGINE
799 auto osd_warning = std::string("");
801 const char *disabled_osd_msg =
802 "\nERROR: The page segmentation mode 0 (OSD Only) is currently "
803 "disabled.\n\n";
804 fprintf(stderr, "%s", disabled_osd_msg);
805 return EXIT_FAILURE;
808 osd_warning +=
809 "\nWarning: The page segmentation mode 1 (Auto+OSD) is currently "
810 "disabled. "
811 "Using PSM 3 (Auto) instead.\n\n";
814 osd_warning +=
815 "\nWarning: The page segmentation mode 12 (Sparse text + OSD) is "
816 "currently disabled. "
817 "Using PSM 11 (Sparse text) instead.\n\n";
818 }
819#endif
820
821 std::vector<std::unique_ptr<TessResultRenderer>> renderers;
822
823 if (in_training_mode) {
824 renderers.push_back(nullptr);
825 } else if (outputbase != nullptr) {
826 PreloadRenderers(api, renderers, pagesegmode, outputbase);
827 }
828
829 if (!renderers.empty()) {
830#ifdef DISABLED_LEGACY_ENGINE
831 if (!osd_warning.empty()) {
832 fprintf(stderr, "%s", osd_warning.c_str());
833 }
834#endif
835 bool succeed = api.
ProcessPages(image,
nullptr, 0, renderers[0].get());
836 if (!succeed) {
837 fprintf(stderr, "Error during processing.\n");
838 ret_val = EXIT_FAILURE;
839 }
840 }
841
842 return ret_val;
843}
@ PSM_OSD_ONLY
Orientation and script detection only.
@ PSM_SPARSE_TEXT
Find as much text as possible in no particular order.
@ PSM_AUTO_ONLY
Automatic page segmentation, but no OSD, or OCR.
@ PSM_AUTO
Fully automatic page segmentation, but no OSD.
@ PSM_SPARSE_TEXT_OSD
Sparse text with orientation and script det.
void tprintf(const char *format,...)
void SetPageSegMode(PageSegMode mode)
bool SetVariable(const char *name, const char *value)
bool ProcessPages(const char *filename, const char *retry_config, int timeout_millisec, TessResultRenderer *renderer)
PageSegMode GetPageSegMode() const
int Init(const char *datapath, const char *language, OcrEngineMode mode, char **configs, int configs_size, const std::vector< std::string > *vars_vec, const std::vector< std::string > *vars_values, bool set_only_non_debug_params)
void PrintVariables(FILE *fp) const
void SetImage(const unsigned char *imagedata, int width, int height, int bytes_per_pixel, int bytes_per_line)
Tesseract * tesseract() const
PageIterator * AnalyseLayout()
void PrintFontsTable(FILE *fp) const
bool GetBoolVariable(const char *name, bool *value) const
void SetOutputName(const char *name)
static TESS_API void Update()
static DawgCache * GlobalDawgCache()