Tesseract 3.02

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
tesseractmain.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 * File: tessedit.cpp (Formerly tessedit.c)
3 * Description: Main program for merge of tess and editor.
4 * Author: Ray Smith
5 * Created: Tue Jan 07 15:21:46 GMT 1992
6 *
7 * (C) Copyright 1992, Hewlett-Packard Ltd.
8 ** Licensed under the Apache License, Version 2.0 (the "License");
9 ** you may not use this file except in compliance with the License.
10 ** You may obtain a copy of the License at
11 ** http://www.apache.org/licenses/LICENSE-2.0
12 ** Unless required by applicable law or agreed to in writing, software
13 ** distributed under the License is distributed on an "AS IS" BASIS,
14 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 ** See the License for the specific language governing permissions and
16 ** limitations under the License.
17 *
18 **********************************************************************/
19
20 // #define USE_VLD //Uncomment for Visual Leak Detector.
21 #if (defined _MSC_VER && defined USE_VLD)
22 #include "mfcpch.h"
23 #include <vld.h>
24 #endif
25
26 // Include automatically generated configuration file if running autoconf
27 #ifdef HAVE_CONFIG_H
28 #include "config_auto.h"
29 #endif
30 #ifdef USING_GETTEXT
31 #include <libintl.h>
32 #include <locale.h>
33 #define _(x) gettext(x)
34 #else
35 #define _(x) (x)
36 #endif
37
38 #include "allheaders.h"
39 #include "baseapi.h"
40 #include "basedir.h"
41 #include "strngs.h"
42 #include "tesseractmain.h"
43 #include "tprintf.h"
44
45 /**********************************************************************
46 * main()
47 *
48 **********************************************************************/
49
50 int main(int argc, char **argv) {
51 #ifdef USING_GETTEXT
52 setlocale (LC_ALL, "");
53 bindtextdomain (PACKAGE, LOCALEDIR);
54 textdomain (PACKAGE);
55 #endif
56 if ((argc == 2 && strcmp(argv[1], "-v") == 0) ||
57 (argc == 2 && strcmp(argv[1], "--version") == 0)) {
58 char *versionStrP;
59
60 fprintf(stderr, "tesseract %s\n", tesseract::TessBaseAPI::Version());
61
62 versionStrP = getLeptonicaVersion();
63 fprintf(stderr, " %s\n", versionStrP);
64 lept_free(versionStrP);
65
66 versionStrP = getImagelibVersions();
67 fprintf(stderr, " %s\n", versionStrP);
68 lept_free(versionStrP);
69
70 exit(0);
71 }
72
73 tesseract::TessBaseAPI api;
74 STRING tessdata_dir;
75 truncate_path(argv[0], &tessdata_dir);
76 int rc = api.Init(tessdata_dir.string(), NULL);
77 if (rc) {
78 fprintf(stderr, _("Could not initialize tesseract.\n"));
79 exit(1);
80 }
81
82 if (argc == 2 && strcmp(argv[1], "--list-langs") == 0) {
83 GenericVector<STRING> languages;
84 api.GetAvailableLanguagesAsVector(&languages);
85 fprintf(stderr, _("List of available languages (%d):\n"), languages.size());
86 for (int index = 0; index < languages.size(); ++index) {
87 STRING& string = languages[index];
88 fprintf(stderr, "%s\n", string.string());
89 }
90 api.Clear();
91 exit(0);
92 }
93 api.End();
94
95 // Make the order of args a bit more forgiving than it used to be.
96 const char* lang = "eng";
97 const char* image = NULL;
98 const char* output = NULL;
99 tesseract::PageSegMode pagesegmode = tesseract::PSM_AUTO;
100 int arg = 1;
101 while (arg < argc && (output == NULL || argv[arg][0] == '-')) {
102 if (strcmp(argv[arg], "-l") == 0 && arg + 1 < argc) {
103 lang = argv[arg + 1];
104 ++arg;
105 } else if (strcmp(argv[arg], "-psm") == 0 && arg + 1 < argc) {
106 pagesegmode = static_cast< tesseract::PageSegMode >(atoi(argv[arg + 1]));
107 ++arg;
108 } else if (image == NULL) {
109 image = argv[arg];
110 } else if (output == NULL) {
111 output = argv[arg];
112 }
113 ++arg;
114 }
115 if (output == NULL) {
116 fprintf(stderr, _("Usage:%s imagename outputbase [-l lang] "
117 "[-psm pagesegmode] [configfile...]\n\n"), argv[0]);
118 fprintf(stderr,
119 _("pagesegmode values are:\n"
120 "0 = Orientation and script detection (OSD) only.\n"
121 "1 = Automatic page segmentation with OSD.\n"
122 "2 = Automatic page segmentation, but no OSD, or OCR\n"
123 "3 = Fully automatic page segmentation, but no OSD. (Default)\n"
124 "4 = Assume a single column of text of variable sizes.\n"
125 "5 = Assume a single uniform block of vertically aligned text.\n"
126 "6 = Assume a single uniform block of text.\n"
127 "7 = Treat the image as a single text line.\n"
128 "8 = Treat the image as a single word.\n"
129 "9 = Treat the image as a single word in a circle.\n"
130 "10 = Treat the image as a single character.\n"));
131 fprintf(stderr, _("-l lang and/or -psm pagesegmode must occur before any"
132 "configfile.\n\n"));
133 fprintf(stderr, _("Single options:\n"));
134 fprintf(stderr, _(" -v --version: version info\n"));
135 fprintf(stderr, _(" --list-langs: list available languages for tesseract "
136 "engine\n"));
137 exit(1);
138 }
139
140
141 api.SetOutputName(output);
142
143 rc = api.Init(tessdata_dir.string(), lang, tesseract::OEM_DEFAULT,
144 &(argv[arg]), argc - arg, NULL, NULL, false);
145 if (rc) {
146 fprintf(stderr, _("Could not initialize tesseract.\n"));
147 exit(1);
148 }
149
150 // We have 2 possible sources of pagesegmode: a config file and
151 // the command line. For backwards compatability reasons, the
152 // default in tesseract is tesseract::PSM_SINGLE_BLOCK, but the
153 // default for this program is tesseract::PSM_AUTO. We will let
154 // the config file take priority, so the command-line default
155 // can take priority over the tesseract default, so we use the
156 // value from the command line only if the retrieved mode
157 // is still tesseract::PSM_SINGLE_BLOCK, indicating no change
158 // in any config file. Therefore the only way to force
159 // tesseract::PSM_SINGLE_BLOCK is from the command line.
160 // It would be simpler if we could set the value before Init,
161 // but that doesn't work.
162 if (api.GetPageSegMode() == tesseract::PSM_SINGLE_BLOCK)
163 api.SetPageSegMode(pagesegmode);
164 tprintf("Tesseract Open Source OCR Engine v%s with Leptonica\n",
165 tesseract::TessBaseAPI::Version());
166
167
168 FILE* fin = fopen(image, "rb");
169 if (fin == NULL) {
170 fprintf(stderr, _("Cannot open input file: %s\n"), image);
171 exit(2);
172 }
173 fclose(fin);
174
175 PIX *pixs;
176 if ((pixs = pixRead(image)) == NULL) {
177 fprintf(stderr, _("Unsupported image type.\n"));
178 exit(3);
179 }
180 pixDestroy(&pixs);
181
182 STRING text_out;
183 if (!api.ProcessPages(image, NULL, 0, &text_out)) {
184 fprintf(stderr, _("Error during processing.\n"));
185 }
186 bool output_hocr = false;
187 api.GetBoolVariable("tessedit_create_hocr", &output_hocr);
188 bool output_box = false;
189 api.GetBoolVariable("tessedit_create_boxfile", &output_box);
190 STRING outfile = output;
191 outfile += output_hocr ? ".html" : output_box ? ".box" : ".txt";
192 FILE* fout = fopen(outfile.string(), "wb");
193 if (fout == NULL) {
194 fprintf(stderr, _("Cannot create output file %s\n"), outfile.string());
195 exit(1);
196 }
197 fwrite(text_out.string(), 1, text_out.length(), fout);
198 fclose(fout);
199
200 return 0; // Normal exit
201 }
202
203 #ifdef _WIN32
204
205 char szAppName[] = "Tesseract"; //app name
206 int initialized = 0;
207
208 /**********************************************************************
209 * WinMain
210 *
211 * Main function for a windows program.
212 **********************************************************************/
213
214 int WINAPI WinMain( //main for windows //command line
215 HINSTANCE hInstance,
216 HINSTANCE hPrevInstance,
217 LPSTR lpszCmdLine,
218 int nCmdShow) {
219 WNDCLASS wc;
220 HWND hwnd;
221 MSG msg;
222
223 char **argv;
224 char *argsin[2];
225 int argc;
226 int exit_code;
227
228 wc.style = CS_NOCLOSE | CS_OWNDC;
229 wc.lpfnWndProc = (WNDPROC) WndProc;
230 wc.cbClsExtra = 0;
231 wc.cbWndExtra = 0;
232 wc.hInstance = hInstance;
233 wc.hIcon = NULL; //LoadIcon (NULL, IDI_APPLICATION);
234 wc.hCursor = NULL; //LoadCursor (NULL, IDC_ARROW);
235 wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
236 wc.lpszMenuName = NULL;
237 wc.lpszClassName = szAppName;
238
239 RegisterClass(&wc);
240
241 hwnd = CreateWindow (szAppName, szAppName,
242 WS_OVERLAPPEDWINDOW | WS_DISABLED,
243 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
244 CW_USEDEFAULT, HWND_DESKTOP, NULL, hInstance, NULL);
245
246 argsin[0] = strdup (szAppName);
247 argsin[1] = strdup (lpszCmdLine);
248 /*allocate memory for the args. There can never be more than half*/
249 /*the total number of characters in the arguments.*/
250 argv = (char **)malloc(((strlen(argsin[0]) + strlen(argsin[1])) / 2 + 1) *
251 sizeof(char *));
252
253 /*now construct argv as it should be for C.*/
254 argc = parse_args (2, argsin, argv);
255
256 // ShowWindow (hwnd, nCmdShow);
257 // UpdateWindow (hwnd);
258
259 if (initialized) {
260 exit_code = main (argc, argv);
261 free (argsin[0]);
262 free (argsin[1]);
263 free(argv);
264 return exit_code;
265 }
266 while (GetMessage (&msg, NULL, 0, 0)) {
267 TranslateMessage(&msg);
268 DispatchMessage(&msg);
269 if (initialized) {
270 exit_code = main (argc, argv);
271 break;
272 }
273 else
274 exit_code = msg.wParam;
275 }
276 free (argsin[0]);
277 free (argsin[1]);
278 free(argv);
279 return exit_code;
280 }
281
282
283 /**********************************************************************
284 * WndProc
285 *
286 * Function to respond to messages.
287 **********************************************************************/
288
289 LONG WINAPI WndProc( //message handler
290 HWND hwnd, //window with message
291 UINT msg, //message typ
292 WPARAM wParam,
293 LPARAM lParam) {
294 HDC hdc;
295
296 if (msg == WM_CREATE) {
297 //
298 // Create a rendering context.
299 //
300 hdc = GetDC (hwnd);
301 ReleaseDC(hwnd, hdc);
302 initialized = 1;
303 return 0;
304 }
305 return DefWindowProc (hwnd, msg, wParam, lParam);
306 }
307
308
309 /**********************************************************************
310 * parse_args
311 *
312 * Turn a list of args into a new list of args with each separate
313 * whitespace spaced string being an arg.
314 **********************************************************************/
315
316 int
317 parse_args ( /*refine arg list */
318 int argc, /*no of input args */
319 char *argv[], /*input args */
320 char *arglist[] /*output args */
321 ) {
322 int argcount; /*converted argc */
323 char *testchar; /*char in option string */
324 int arg; /*current argument */
325
326 argcount = 0; /*no of options */
327 for (arg = 0; arg < argc; arg++) {
328 testchar = argv[arg]; /*start of arg */
329 do {
330 while (*testchar
331 && (*testchar == ' ' || *testchar == '\n'
332 || *testchar == '\t'))
333 testchar++; /*skip white space */
334 if (*testchar) {
335 /*new arg */
336 arglist[argcount++] = testchar;
337 /*skip to white space */
338 for (testchar++; *testchar && *testchar != ' ' && *testchar != '\n' && *testchar != '\t'; testchar++) ;
339 if (*testchar)
340 *testchar++ = '\0'; /*turn to separate args */
341 }
342 }
343 while (*testchar);
344 }
345 return argcount; /*new number of args */
346 }
347 #endif