#LyX 1.1 created this file. For more info see http://www.lyx.org/ \lyxformat 218 \textclass book \begin_preamble \pagestyle{fancy} \renewcommand{\chaptermark}[1]{\markboth{#1}{}} \renewcommand{\sectionmark}[1]{\markright{\thesection\ #1}} \fancyhead{} \fancyfoot{} \fancyhead[LE,RO]{\bfseries\thepage} \fancyhead[LO]{\bfseries GOCR\ API\ Documentation} \fancyhead[RE]{\bfseries \leftmark} \renewcommand{\headrulewidth}{0.5pt} \addtolength{\headheight}{0.5pt} \fancypagestyle{plain}{% \fancyhead{} \renewcommand{\headrulewidth}{0pt} % } \end_preamble \language english \inputencoding latin1 \fontscheme default \graphics default \float_placement htb \paperfontsize default \spacing single \papersize a4paper \paperpackage a4 \use_geometry 0 \use_amsmath 0 \paperorientation portrait \secnumdepth 2 \tocdepth 2 \paragraph_separation indent \defskip medskip \quotes_language english \quotes_times 2 \papercolumns 1 \papersides 2 \paperpagestyle fancy \layout Standard \latex latex \backslash pagenumbering{roman} \latex default \layout Title \size giant \bar under libGOCR API \layout Author \added_space_top bigskip Bruno Barberi Gnecco \emph on brunobg \emph default @ \emph on sourceforge.net \layout Standard GOCR is \latex latex \backslash copyright \latex default 2000 Jörg Schulenburg. All rights reserved. \layout Standard libGOCR API and this manual are \latex latex \backslash copyright \latex default 2001 Bruno Barberi Gnecco. All rights reserved. \layout Standard \begin_inset LatexCommand \tableofcontents{} \end_inset \layout Chapter Introduction \layout Standard \latex latex \backslash pagenumbering{arabic} \backslash setcounter{page}{1} \latex default GOCR is an attempt to fulfill a large gap in the Linux world: the lack of an OCR program. At the time the project started, there were some available, but their quality was very deceptive. Licensed using the LGPL license, it can be used by anyone. \layout Standard As of the 0.3.x versions, it was decided that gocr, until then a stand-alone program, should become a library. I (Bruno) decided then to be responsible for it, and this is the result. I hope I did a good job, or at least something that's quite usable. \layout Standard This documentation covers three different views on the API, which are the layers it's subdivided. First, there's the GOCR frontend API itself, which allows you to write a program that uses the library to do some OCRing. It's a small set of functions that allow you to decide what operations should be done, and in what order, and to tune some of the attributes of the library. Second, there's the module interface. The GOCR library lets you write new pieces of code or to complement the existing ones without recompiling; we call these pieces \emph on modules \emph default , but many other programs call them plugins. It's just nomenclature. This API is fully independent of the first one, and has a completely different functionality. Last, but not least, is the internal GOCR API. You don't need to know what it is, or even that it exists, but it's what joins the two first API's, all the modules you're using, the program you wrote, and makes it all work together, or not. It's GOCR itself, and you only want to know about it if you want to develop GOCR. \layout Standard With the API, there is the possibility of writing wrappers, or bindings, to other languages. C++ and Python are on the list, and soon will be available. \layout Standard This document was written not only as a reference, but as a tutorial as well; the language is light, a handful of jokes are spread around, etc. The code is well documented, and automatic documentation, man pages, etc, can be generated using Doxygen. \layout Section About this document \layout Standard This file documents libgocr. Unless you are interested in developing frontends or modules, you shouldn't be reading it. It's filled with technical information and documentation of functions, and just the last phrase probably made 50% of whomever read it immediately close the window . In case this file is not what you are looking for, you can take a look at the \begin_inset Quotes eld \end_inset Brief introduction \begin_inset Quotes erd \end_inset documentation (which is not written yet, so you may read section \begin_inset LatexCommand \ref{introduction to modules} \end_inset ). \layout Standard Please realize that, while we try to keep this file up-to-date, it's inevitable that we'll forget something and impossible to keep the latest improvements in the code in sync with this file. Since the file is intended to be a user's guide and not a reference guide, that's not so bad. Always keep in mind that the automatically generated documentation (with Doxygen) is more accurate (but less complete). \layout Section Authors and contact information \layout Standard GOCR project was created by Jörg Schulenburg \newline < \family typewriter Joerg.Schulenburg@physik.uni-magdeburg.de \family default >. \layout Standard It's currently hosted at Sourceforge: \family typewriter http://jocr.sourceforge.net \family default (yes, with a 'j'). \layout Standard Other developers have joined the effort, and many people send inpatches, bug reports and ideas. \layout Standard The API was designed and this manual has been written by Bruno Barberi Gnecco < \family typewriter brunobg@geocities.com \family default > \layout Section Version information/development plan \layout Standard This manual contains the 0.7.1 API standard. 0.7.x versions are development versions, which will be used until a stable, usable and complete version is reached. By that time, version number will be upgraded to 0.9. The 0.9.x versions will be for debugging and testing, because minor corrections are to be expected. Once it's good enough to be widely, publicly used, it will be 1.0. \layout Standard So, in other words, while it's not 1.0, you can't blame us that it sucks and doesn't work. After that, it's OK. :-) \layout Subsection Current status \layout Standard The frontend API is pratically stable, but new additions will come. A new image loading system was designed and implemented (0.7.1). A wrapper to a GUI system is being designed, so modules can interact with the user. \layout Standard The internal API is being done solidly, to avoid future problems. I'm taking special care to make sure that it's a good system, and will support the rest well. There's a real bunch of fprintf's to the inevitable debugging. ;-) \layout Standard The module API is not stable. It's being developed. The general idea, however, is here. \layout Chapter Frontend API \layout Standard GOCR API is a simple set of functions that let you easily write a frontend. You are responsible for what modules you are calling. A module is simply a piece of code that performs a certain kind of function; it will be explained more detailedly below. \layout Section Initializing and finalizing \layout Standard The header that contains the prototypes, etc is \family typewriter gocr.h \family default . \layout Standard It's mandatory that you call two functions when using GOCR. They are: \layout LyX-Code int gocr_init \begin_inset LatexCommand \index{gocr\_init} \end_inset ( int argc, char **argv ); \layout LyX-Code void gocr_finalize \begin_inset LatexCommand \index{gocr\_finalize} \end_inset ( void ); \layout Standard The first function parses the arguments your program got, setups all the internal structures of GOCR, initializes all that it's needed to run. It must be called before any other GOCR function. It returns 0 if GOCR could be correctly initialized, -1 otherwise. This is a constant in the API: if a function returns -1, it failed. You should always test the return values. GOCR also outputs to stderr what was the problem. \layout Standard At the end of your program, or when you don't intend to use GOCR anymore, you must call the second function. \layout Standard Currently, GOCR accept the following arguments: none yet. \layout Section Attributes \begin_inset LatexCommand \index{Attributes} \end_inset \begin_inset LatexCommand \label{attributes} \end_inset \layout Standard After calling \family typewriter gocr_init() \family default , the next thing to do is to set the attributes of the library. These are parameters that let you tune several aspects of the API. They can be set and read using these two functions: \layout LyX-Code int gocr_setAttribute \begin_inset LatexCommand \index{gocr\_setAttribute} \end_inset ( gocr_AttributeType t, void *value ); \layout LyX-Code void *gocr_getAttribute \begin_inset LatexCommand \index{gocr\_getAttribute} \end_inset ( gocr_AttributeType t ); \layout Standard The first function sets the attribute \family typewriter t \family default with a value \family typewriter value \family default . The second returns the current value of attribute \family typewriter t \family default . The list of attributes currently supported and the values you can pass to them is: \layout Standard \added_space_top 0.3cm \added_space_bottom 0.3cm \align center \begin_inset Tabular \begin_inset Text \layout Standard \size small Attribute type \end_inset \begin_inset Text \layout Standard \size small Value \end_inset \begin_inset Text \layout Standard \size small Function \end_inset \begin_inset Text \layout Standard \size small Default \end_inset \begin_inset Text \layout Standard \size small LIBVERSION \size default \end_inset \begin_inset Text \layout Standard \size small string \end_inset \begin_inset Text \layout Standard \size small Returns a string containing the library version. This is a read-only attribute. \end_inset \begin_inset Text \layout Standard \size small none \end_inset \begin_inset Text \layout Standard \size small VERBOSE \size default \end_inset \begin_inset Text \layout Standard \size small an integer from 0 to 3 \end_inset \begin_inset Text \layout Standard \size small Sets the level of output: \newline 0 nothing; \newline 1 error messages; \newline 2 warnings and errors; \newline 3: everything. Used mostly for debugging. \end_inset \begin_inset Text \layout Standard \size small 1 \end_inset \begin_inset Text \layout Standard \size small BLOCK_OVERLAP \end_inset \begin_inset Text \layout Standard \size small boolean \end_inset \begin_inset Text \layout Standard \size small If true, allows two blocks to overlap \end_inset \begin_inset Text \layout Standard \size small FALSE \end_inset \begin_inset Text \layout Standard \size small NO_BLOCK \size default \end_inset \begin_inset Text \layout Standard \size small boolean \end_inset \begin_inset Text \layout Standard \size small If true, and no block was found, creates a block covering whole image. \end_inset \begin_inset Text \layout Standard \size small TRUE \end_inset \begin_inset Text \layout Standard CHAR_OVERLAP \end_inset \begin_inset Text \layout Standard \size small boolean \end_inset \begin_inset Text \layout Standard \size small If true, allows characters to overlap \end_inset \begin_inset Text \layout Standard \size small TRUE \end_inset \begin_inset Text \layout Standard CHAR_RECTANGLES \end_inset \begin_inset Text \layout Standard \size small boolean \end_inset \begin_inset Text \layout Standard \size small If true, all characters are selected as rectangles \end_inset \begin_inset Text \layout Standard \size small TRUE \end_inset \begin_inset Text \layout Standard FIND_ALL \end_inset \begin_inset Text \layout Standard \size small boolean \end_inset \begin_inset Text \layout Standard \size small If true, first find all characters, saving in memory, and then process. \end_inset \begin_inset Text \layout Standard \size small FALSE \end_inset \begin_inset Text \layout Standard \size small ERROR_FILE \end_inset \begin_inset Text \layout Standard \size small (FILE *) variable \end_inset \begin_inset Text \layout Standard \size small Sets the error messages output file. \end_inset \begin_inset Text \layout Standard \size small stderr \end_inset \begin_inset Text \layout Standard \size small PRINT \size default \end_inset \begin_inset Text \layout Standard \size small an integer from 0 to 6 \end_inset \begin_inset Text \layout Standard What is printed: \size small \newline 0: only data bit (. = white, * = black) \newline 1: marked bits (mark1 + 2*mark2 + 4*mark3) \newline 2: data and marked bits: if white, a\SpecialChar \ldots{} h;if black, marked bits->A\SpecialChar \ldots{} H \newline 3: only isblock bit (. = is not block, * = is block) \newline 4: only ischar bit (. = is not char, * = is char) \newline 5: complete byte, in hexadecimal \newline 6: complete byte, in ASCII \end_inset \begin_inset Text \layout Standard \size small 0 \end_inset \begin_inset Text \layout Standard \size small PRINT_IMAGE \size default \end_inset \begin_inset Text \layout Standard \size small boolean \end_inset \begin_inset Text \layout Standard \size small If true, gocr_print* functions will print the image associated with the structure. \end_inset \begin_inset Text \layout Standard \size small 1 \end_inset \end_inset \layout Standard Boolean values are either GOCR_TRUE or GOCR_FALSE. \emph on Do not use TRUE or FALSE, since they are defined with different values by Unicode. \layout Standard Some module packages may require certain attributes; take a look at their documentation. They may automatically set these attributes, so don't be stubborn and override. Certain functions of libgocr may lock some attributes, to avoid chaos. \layout Section Images \begin_inset LatexCommand \index{Images} \end_inset \layout Standard If the purpose of your program isn't opening an image and processing it to turn into some kind of text, you are reading the wrong document ;-). GOCR currently works this way: you open an image, let the modules process it, and close it. This can be done any number of times you want. Image loading and closing is done using: \layout LyX-Code int gocr_imageLoad \begin_inset LatexCommand \index{gocr\_imageLoad} \end_inset ( const char *filename, void *data ); \layout LyX-Code void gocr_imageClose \begin_inset LatexCommand \index{gocr\_imageClose} \end_inset ( void ); \layout Standard well, they are pretty clear. \family typewriter gocr_imageLoad() \family default returns 0 in case of success, -1 otherwise. If you try to open an image while there's one already open, \family typewriter gocr_imageLoad() \family default will return -1. \layout Standard Image loading is part of a module, and \family typewriter gocr_imageLoad() \family default may be overriden. Libgocr provides a default one, which is capable of opening the most common image types. It accepts, as the second argument, one of these: \layout List \labelwidthstring 00.00.0000 GOCR_BW Convert to black and white. \layout List \labelwidthstring 00.00.0000 GOCR_GRAY Convert to grayscale. \layout List \labelwidthstring 00.00.0000 GOCR_COLOR Convert to RGB (24 bit) color. \layout List \labelwidthstring 00.00.0000 GOCR_NONE Do not convert. \layout Section Modules \begin_inset LatexCommand \label{api-modules} \end_inset \layout Subsection Introduction to modules \latex latex \begin_inset LatexCommand \index{modules!introduction} \end_inset \begin_inset LatexCommand \label{introduction to modules} \end_inset \layout Standard There are three things that could be called a \emph on module \emph default in GOCR, so here's a thorough specification: \layout Itemize the module \latex latex \begin_inset LatexCommand \index{modules!type} \end_inset \latex default type. There are many different types of modules, as explained below. For example, there's a imageFilter type, that may be used to do clean the image dust, for example, and a charRecognizer, that is intended to get a small image of a single character and find out which one it is. When I refer to \emph on module \emph default , I usually mean an instance of a module type. \layout Itemize the function \latex latex \begin_inset LatexCommand \index{modules!function} \end_inset \latex default . Each module type may have several different functions. For example, imageFilter module may have a function to increase contrast, another to clean dust, and a third to remove coffee mug stains. These are called \emph on module functions \emph default , or simply \emph on functions \emph default . \layout Itemize the file, which ends with .so, and is a shared object. In our terminology, this is a \emph on shared object file \emph default \latex latex \begin_inset LatexCommand \index{shared object file} \end_inset \latex default , or (same thing different name) a \emph on module package \emph default \begin_inset LatexCommand \index{modules!package} \end_inset . This file contains the module functions, which may be of different module types. \layout Standard There are several module types \begin_inset LatexCommand \index{modules!types} \end_inset : \layout Standard \added_space_top 0.3cm \added_space_bottom 0.3cm \align center \begin_inset Tabular \begin_inset Text \layout Standard Module type \end_inset \begin_inset Text \layout Standard Function \end_inset \begin_inset Text \layout Standard Examples \end_inset \begin_inset Text \layout Standard imageLoader \end_inset \begin_inset Text \layout Standard Loads an image. \end_inset \begin_inset Text \layout Standard Load images. There can be only oneimage loader. \end_inset \begin_inset Text \layout Standard imageFilter \end_inset \begin_inset Text \layout Standard Filter the image. \end_inset \begin_inset Text \layout Standard Dust removal, etc. \end_inset \begin_inset Text \layout Standard blockFinder \end_inset \begin_inset Text \layout Standard Find blocks, i.e., groups of similar dataand add information of its content. \end_inset \begin_inset Text \layout Standard Find pictures, find columns of text,find mathematical expressions. \end_inset \begin_inset Text \layout Standard charFinder \end_inset \begin_inset Text \layout Standard Frame characters, and add informationof its content. \end_inset \begin_inset Text \layout Standard Frame characters, font recognition. \end_inset \begin_inset Text \layout Standard charRecognizer \end_inset \begin_inset Text \layout Standard Recognize the framed characters. \end_inset \begin_inset Text \layout Standard Italic, bold, greek specialiazed OCR. \end_inset \begin_inset Text \layout Standard contextCorrection \end_inset \begin_inset Text \layout Standard Try to recognize the still unrecognized characters. \end_inset \begin_inset Text \layout Standard Spell checker, ligature checker. \end_inset \begin_inset Text \layout Standard outputFormatter \end_inset \begin_inset Text \layout Standard Output data to some format and file. \end_inset \begin_inset Text \layout Standard HTML output, \latex latex \backslash LaTeX \backslash \latex default output. \end_inset \end_inset \layout Standard All of the modules (except imageLoader) may be composed of several different functions, which may be in different module packages. The following sections explain how to load modules, set their order, and run them. \layout Subsection Loading shared object files \latex latex \begin_inset LatexCommand \index{shared object files!loading} \end_inset \begin_inset LatexCommand \index{modules!loading!files} \end_inset \latex default \layout Standard The first thing to do, when you want to add some function to a module, is to open its file. All the work is done internally by the library, and you just need to call: \layout LyX-Code int gocr_moduleLoad \begin_inset LatexCommand \index{gocr\_moduleLoad} \end_inset ( char *filename ); \layout Standard If \family typewriter filename \family default is just the filename, libgocr will search for the file in the following directories: \layout Itemize A colon-separated list of directories in the user's LD_LIBRARY path environment variable. \layout Itemize The list of libraries specified in /etc/ld.so.cache. \layout Itemize /usr/lib, followed by /lib. \layout Itemize The directory libgocr was installed in. \layout Standard This function returns a module id (that can be used to set attributes, see below) if the operation was successful, -1 otherwise. \layout Subsection Setting module attributes \begin_inset LatexCommand \label{module attributes} \end_inset \begin_inset LatexCommand \index{modules!attributes} \end_inset \layout Standard Some module packages allow you to set their attributes. You can do this using this function: \layout LyX-Code int gocr_moduleSetAttribute \begin_inset LatexCommand \index{gocr\_moduleSetAttribute} \end_inset ( int id, void *a, void *b ); \layout Description id \family typewriter \family default is the module package id \layout Description a,\SpecialChar ~ b fields are passed directly to the module package, refer to its documentation to know how to use them. \layout Standard The function returns -1 in case of some internal error, or the value returned by the module package. \layout Subsection Loading module functions \latex latex \begin_inset LatexCommand \index{modules!loading!functions} \end_inset \latex default \layout Standard Since a shared object file may have several different module functions, and you may be interested only in one of them, GOCR enables you to decide exactly which module function should be run, and the order they do that. The functions that load module functions are: \layout LyX-Code int gocr_functionAppend \begin_inset LatexCommand \index{gocr\_functionAppend} \end_inset ( gocr_moduleType t, \begin_deeper \layout LyX-Code char *functionname, void *data ); \end_deeper \layout LyX-Code int gocr_functionInsertBefore \begin_inset LatexCommand \index{gocr\_functionInsertBefore} \end_inset ( gocr_moduleType t, \begin_deeper \layout LyX-Code char *functionname, void *data, int id ); \end_deeper \layout LyX-Code int gocr_functionDeleteById \begin_inset LatexCommand \index{gocr\_deleteModule} \end_inset ( int id ); \layout Standard Module functions are internally saved in a linked list, but you don't have to know that (so, I shouldn't haven written\SpecialChar \ldots{} well, knowledge is never too much). Let's first see \family typewriter gocr_functionAppend \family default . The arguments are: \layout Description t \family typewriter \family default the module type, as in the first column of the table above. \layout Description functionname this is the name of the module function you want to load. Refer to the documentation that should come with the shared file object. \layout Description data this is a parameter that will be passed to the function when it's called. It's a pointer, that you are responsible for allocation. Do not free it until you call \family typewriter gocr_functionDelete \family default or \family typewriter gocr_finalize \family default . Being a void pointer, you can pass anything to it. If you need more than one argument, use a structure. Read the module function docs to know what you can do with this. \layout Standard \family typewriter gocr_functionAppend \family default returns -1 in case of error, or a non-negative number if successful. This number is the function's ID. It can be used if you want to do access this function. \layout Standard \family typewriter gocr_functionDeleteById \family default is straight forward. Its sole argument is the id of the module function you want to delete. As usual, returns -1 if error, 0 on success. \layout Standard Last, but not least, there's \family typewriter gocr_functionInsertBefore \family default . It works like its counterpart \family typewriter gocr_functionAppend \family default , but there's a difference: it allows you to insert a function in the middle of the list. Good for the absent minded ones. The first three arguments are the same of \family typewriter gocr_functionAppend \family default , and the fourth argument is the id of the function that is be just after the position you want to insert the new function. So, if you want to insert a function in the first position, you should pass the id of the current first position function. Hm. Read it again, and it should become clearer. ;-) \layout Standard The order of the inclusion is very important, since it will determine the order of running. So, if you add a module function to recognize cyrilic text before latin text and try to decode a latin text, it'll be much slower than if you did vice-versa. Always sort the functions by the probability of their usefullness. \layout Standard Note that you don't need to specify in which shared object file the function is; GOCR does it automatically for you. \layout Subsection Running modules \latex latex \begin_inset LatexCommand \index{modules!running} \end_inset \latex default \layout Standard Now that you did everything, there remains only to run the modules. GOCR allows you to run them all at once, module by module, or module function by module function: \layout LyX-Code int gocr_runModuleFunction \begin_inset LatexCommand \index{gocr\_runModuleFunction} \end_inset ( int id ); \layout LyX-Code int gocr_runModuleType \begin_inset LatexCommand \index{gocr\_runModuleType} \end_inset ( gocr_moduleType t ); \layout LyX-Code int gocr_runAllModules \begin_inset LatexCommand \index{gocr\_runAllModules} \end_inset ( void ); \layout Standard The functions are simple to use. \family typewriter gocr_runAllModules \family default runs all the modules, taking care of how it's done. For example, charFinder module functions must be called one for each block. It's not a trivial for(), and this is the recommended way to do it. It follows the order that you provided when you appended and inserted the module functions, as described in the last section. \layout Standard \color magenta run_moduleType is not working, due to design issues. runMF will work for imageFilter, blockFinder will probably work, outForm, contCorr, charRecog(?) will work if correctly fed \layout Standard \family typewriter gocr_runModuleType \family default runs a specific module. There's no care taken of the internal data, which must be manually updated. It may be useful if you want just to apply some filters to the image, for example, or if you want to do a different implementation of the existing \family typewriter gocr_runAllModules \family default . \layout Standard Last there's \family typewriter gocr_runModuleFunction \family default . It runs just one module function, and also doesn't take care of internal data. If you want to use it, you probably know what you are doing. \layout Standard All functions return 0 on success, -1 on error. \layout Subsection Closing modules \begin_inset LatexCommand \index{modules!closing} \end_inset \layout Standard It's possible to close a module. \family typewriter gocr_finalize \family default automatically takes care of closing all modules, but if you have some special reason to close a module, you can do it. Libgocr automatically deletes all the module functions of this module. Just call: \layout LyX-Code void gocr_moduleClose \begin_inset LatexCommand \index{gocr\_moduleClose} \end_inset ( int id ); \layout Standard And that's it. \layout Section A simple example \layout Standard Ok, time to do something concrete. \layout Standard Usually examples are neat little programs, heavily commented, that do something completely useless. Since this is a tradition, I was unable to refrain using it. Unfortunadly GOCR can't do \begin_inset Quotes eld \end_inset Hello World \begin_inset Quotes erd \end_inset , and so I had to imagine something equally uninteresting, and I used the filter example I just told you. \layout LyX-Code \size small /* filter.c \layout LyX-Code \size small * A simple program, that applies a filter to a \layout LyX-Code \size small * image, and outputs the image. \layout LyX-Code \size small */ \layout LyX-Code \size small \layout LyX-Code \size small #include \layout LyX-Code \size small int main(int argc, char **argv) { \begin_deeper \layout LyX-Code \size small /* Initialize the library */ \layout LyX-Code \size small if ( gocr_init(argc, argv) == -1 ) \begin_deeper \layout LyX-Code \size small exit(1); \end_deeper \layout LyX-Code \size small /* Set output to zero */ \layout LyX-Code \size small if ( gocr_setAttribute(VERBOSE, 0) == -1 ) \begin_deeper \layout LyX-Code \size small exit(1); \end_deeper \layout LyX-Code \size small /* Load a shared object file */ \layout LyX-Code \size small if ( gocr_moduleLoad( \begin_inset Quotes erd \end_inset modulename.so \begin_inset Quotes erd \end_inset ) == -1 ) \begin_deeper \layout LyX-Code \size small exit(1); \end_deeper \layout LyX-Code \size small /* Load a module function that cleans dust */ \layout LyX-Code \size small if ( gocr_functionAppend(imageFilter, \begin_inset Quotes erd \end_inset cleanDust \begin_inset Quotes erd \end_inset , NULL) != -1 ) \begin_deeper \layout LyX-Code \size small exit(1); \end_deeper \layout LyX-Code \size small /* Load a module function that outputs an image */ \layout LyX-Code \size small if ( gocr_functionAppend(outputFormatter, \begin_inset Quotes erd \end_inset imageOutput \begin_inset Quotes erd \end_inset , \newline \begin_inset Quotes erd \end_inset output.jpg \begin_inset Quotes erd \end_inset ) != -1 ) \begin_deeper \layout LyX-Code \size small exit(1); \end_deeper \layout LyX-Code \size small /* Load the image */ \layout LyX-Code \size small if ( gocr_imageLoad( \begin_inset Quotes erd \end_inset image.jpg \begin_inset Quotes erd \end_inset , (void *)GOCR_NONE) ) \begin_deeper \layout LyX-Code \size small exit(1); \end_deeper \layout LyX-Code \size small /* Run all modules. */ \layout LyX-Code \size small gocr_runAllModules(); \layout LyX-Code \size small /* Ok, say good bye */ \layout LyX-Code \size small gocr_finalize(); \end_deeper \layout LyX-Code \size small } \layout Standard The usual comments, now. Notice that two module functions were loaded. The first cleans `dust' of the image, i.e., those nasty pixels that are black in what should be a perfectly white background. The second module outputs the image after the cleaning. Notice how this hypothetical module function takes as argument the name of the output file. \layout Standard When you call \family typewriter gocr_finalize() \family default , it takes care of unloading shared objects, deleting module functions, closing the image, etc. Don't worry with hundreds or close()s, free()s, etc. \layout Section Serious tweaking \layout Standard \color magenta This is under serious review \layout Standard Although libgocr has several module types, you don't have to use them all, and is free to abuse of the architecture. In fact, only doing so you'll be able to take full advantage of libgocr's power. \layout Standard Let's say, for example, that you are writing an algorithm that skips the segmentation process, finding characters directly. At first, it seems that such algorithm would be completely incompatible with libgocr's structure; but it's not. Here are some possible solutions: \layout Itemize use the algorithm as a blockFinder module, and do not use any charFinder or charRecognizer modules. This way you work with the entire image. \layout Itemize use the algorithm as a charFinder module. It allows the separation of the image in blocks, and you can treat it block as a whole image. It's also 100% compatible with other charFinder modules. \layout Standard \latex latex \backslash indent \latex default You may think that this is an ugly hack, but it's not. I'll explain why: since the architecture of libgocr is modular, and the modules can be used independently (with certain exceptions), it's not only OK to do it, it's designed to be used this way. The module types had to be given names, but it's as wrong to think that a charFinder module should only frame characters as to think that charRecognize r can only recognize usual characters, and not musical notes. \layout Standard Something else: do not get stuck with \family typewriter gocr_runAllModules() \family default . Since you may change interpretation of module types, it may be interesting to run them in a different way, skip some, run some twice, allow feedback, etc. \layout Standard The question that arises now is: why not make the modules objetcs, similarly to what is done with block types (see \begin_inset LatexCommand \ref{block types} \end_inset )? \layout Itemize To do so, the module type objects (MTO) would need to have their own \family typewriter run() \family default methods. Since some modules use information of their predecessors (charFinder uses blockFinder, charRecognizer uses charFinder), MTOs would have to be attached to each other, making a mess. \layout Itemize There could be an unnecessary multiplication of MTOs. It would be very easy to decide that \begin_inset Quotes eld \end_inset I don't like that MTO, because the method names are too big \begin_inset Quotes erd \end_inset , and write a new MTO with the same functionality. \layout Itemize Compatibility. Current module types are 100% compatible with each other, sharing common structures and variables. Since they are part of libgocr, you are assured that your module will be compatible with any other module, something that would not happen with MTOs. \layout Itemize Current architecture was carefully designed to work well and in a broad range of situations, and abusing of it is legal. \layout Standard If you need to create a new module type, it's likely to be a very specific situation, where you do not care about compatibility. \layout Section GUI wrapper - message system \layout Standard Note: this is being designed currently, so changes may happen at any time. \layout Standard In order to let modules communicate with users, libgocr implemens a simple GUI wrapper: the module can open a window with some of the most used widgets (text fields, buttons, etc), and get the result directly. The GUI is \emph on very \emph default high level, so the implementation can be done in any API you are using to code your frontend. In short, the GUI wrapper is just a message system, allowing the modules to communicate with users, ask questions, etc. The GUI should take care of how widgets are arranged in the window. \layout Standard Most functions are documented only in the source code while the architecture is not stable yet. Check the automatic documentation. \layout Subsection Registering your callbacks \layout Standard The first thing to do is to register your own callbacks, so whenever a module calls a function it's passed to you. The following function does it: \layout LyX-Code int gocr_guiSetFunction ( gocrGUIFunction type, void *func ); \layout Standard Where \family typewriter func \family default is a pointer to the callback function (converted to \family typewriter void * \family default ), and \family typewriter type \family default is one of the following: \layout Standard \begin_inset Tabular \begin_inset Text \layout Standard Type \end_inset \begin_inset Text \layout Standard Arguments \end_inset \begin_inset Text \layout Standard gocrBeginWindow \end_inset \begin_inset Text \layout Standard ( wchar_t *title, wchar_t **buttons ) \end_inset \begin_inset Text \layout Standard gocrEndWindow \end_inset \begin_inset Text \layout Standard \end_inset \begin_inset Text \layout Standard gocrDisplayCheckButton \end_inset \begin_inset Text \layout Standard \end_inset \begin_inset Text \layout Standard gocrDisplayImage \end_inset \begin_inset Text \layout Standard \end_inset \begin_inset Text \layout Standard gocrDisplayRadioButtons \end_inset \begin_inset Text \layout Standard \end_inset \begin_inset Text \layout Standard gocrDisplaySpinButton \end_inset \begin_inset Text \layout Standard \end_inset \begin_inset Text \layout Standard gocrDisplayText \end_inset \begin_inset Text \layout Standard \end_inset \begin_inset Text \layout Standard gocrDisplayTextField \end_inset \begin_inset Text \layout Standard \end_inset \end_inset \layout Subsection Problems to solve \layout Standard Previews would be nice, but would need interaction, so pointers to functions. it would add complexity, and I am not sure how portable it would be. \layout Standard Add some way to let the gui know what attributes can be set. \layout Chapter Modules API \layout Standard This chapter is intended to those that want to write a module. If you are just using existing modules, the information here is irrelevant. Otherwise, please take a look at section \begin_inset LatexCommand \ref{api-modules} \end_inset first. \layout Standard It's necessary to include the file \family typewriter gocr_module.h \family default , which defines all the necessary stuff. Unless you need some function declared there, there's no need to include \family typewriter gocr.h \family default . \layout Section Modules in brief \begin_inset LatexCommand \index{modules!predefined functions} \end_inset \layout Standard There are some things to say about modules that apply to all types. \layout Standard Upon loading a shared object file, GOCR tries to call a function with the following prototype: \layout LyX-Code int gocr_initModule ( void ); \layout Standard so, if you need to initialize some data, just declare this function. If the function returns something different than 0, it's assumed that some error occured, and the module package is imediately closed. \layout Standard Similarly, when a module package is closed, GOCR tries to call \layout LyX-Code void gocr_closeModule ( void ); \layout Standard which you can use to free memory, etc. \begin_float footnote \layout Standard You may be wondering about the _init and _fini symbols, used by libdl. GOCR doesn't use libdl directly, since libdl is not portable. To avoid conflicts and undefined behavior, do not define _init or _fini. The same is valid for any other library similar to libdl, such as shl_load, LoadLibrary, load_add_on, etc. \end_float \layout Standard Besides these two functions, there's a third function, also optional, that may be used to set attributes in real time: \layout LyX-Code int gocr_setAttribute ( char *field, char *data ); \layout Standard The first argument, \family typewriter field \family default , is the attribute name. The second, \family typewriter data \family default , is the value that the attribute should be set to. \layout Standard Note that all the three functions are optional, and do not need to be declared. You may use whichever you need (e.g., you may declare \family typewriter gocr_closeModule \family default without \family typewriter gocr_initModule \family default ). \layout Standard Besides these functions, there are variable that your code \emph on must \emph default export, containing information about your module: \layout LyX-Code gocrModuleInfo gocr_externalModuleData; \layout Standard which is a structure of the following format: \layout LyX-Code \layout Subsection Module Development Kit \begin_inset LatexCommand \index{modules!module development kit} \end_inset \layout Standard To load shared object files, GOCR uses libltdl, which is included in libtool. It's a bit less straight forward than working with libdl directly, but in return it's much more portable. \layout Standard If you never worked with libraries, libdl, or just don't have a clue of what I'm talking about, and \begin_inset Quotes eld \end_inset just want to write this module to recognize handwriting, man, that's all \begin_inset Quotes erd \end_inset , don't worry. The developers of GOCR have spent countless hours to make your life easier \begin_float footnote \layout Standard That is, I spent some time I had nothing to do developing methods to let you spend some time you have nothing to do developing. \end_float . You don't even have to know anything of the confusing world of libraries, shared, static, cryptic gcc arguments, weird makefiles and confusing configures. \layout Standard All you have to do is write your code, and get the module development kit (MDK) from http://jocr.sourceforge.net/download.html. This package is a whole bunch of files that take care of the libtool, automake, autoconf, and every other little pesty thing that would add hours of work, while you tried to figure out what the hell did you forget in Makefile.am. Or configure.in. See, that's what I'm talking about. \layout Standard The MDK comes with it's own documentation, which you should read before you start coding. All you have to do, however, is to edit the \family typewriter module-setup \family default script, fill some of its fields properly, and run it. It will create all necessary files, and all you have to do is run \family typewriter ./configure \family default to create the Makefiles. \layout Standard That's it. If you think it's too much work, do all the rest yourself ;). Note that to use the MDK you need the automake/autoconf packages installed in your computer. They are available at your closest GNU repository. Anyway, as I said, MDK is properly documented, so read it. \layout Subsection Packaging \begin_inset LatexCommand \index{modules!packaging} \end_inset and releasing \begin_inset LatexCommand \index{modules!releasing} \end_inset \layout Standard Here are some guidelines to help you release your module: \layout Itemize \series bold Write documentation \series default . This is a complete must, because if you don't write it, people won't know what module functions are available in the package, and won't be able to use your module, and then I think you'd missing the point. Be sure to explain what each module function does, and what arguments it may receive. \layout Itemize It's a good idea to add a prefix to the module functions of a module package. For example: foo_clean(), foo_recognize(). \layout Itemize Do not duplicate code. If someone already did what you want, don't replicate it in your code. By the other hand, don't ask to the user to have several libraries of module packages; if you need only a function, have it in your own code (respect the software license). \layout Itemize There's already a easy way to package: type \family typewriter make dist \family default . It will generate the appropriate tar file. \layout Itemize Read the Software Release Practice HOWTO. \layout Itemize Take a look at existing modules. If you are having some problem, chances are that by peeking at other's work you can find a solution. This is one of the most important laws of software coding. Be nice and add a thanks note to your documentation. \layout Section imageLoader \begin_inset LatexCommand \index{module!image} \end_inset \layout Standard This module is a special one; every good rule must have a exception. The differences between imageLoader and the other modules are: \layout Itemize There may be only one function in the image loader module at a time, which makes sense, since there may be only one open image at a time. \layout Itemize The imageLoader function may be accessed directly by calling \family typewriter gocr_imageLoad() \family default . \layout Itemize This module is not called by the \family typewriter gocr_run*Modules() \family default functions. \layout Standard libGOCR has a default image loader module, which currently opens the following images types \begin_float footnote \layout Standard Subject to availability of certain libraries. See the README file. \end_float : \layout Itemize .pnm \layout Itemize .pbm \layout Itemize .pgm \layout Itemize .ppm \layout Itemize .jpg/.jpeg \layout Itemize .gif \layout Itemize .bmp \layout Itemize .tiff \layout Itemize .png \layout Subsection Image \begin_inset LatexCommand \index{image} \end_inset and pixels \begin_inset LatexCommand \index{pixels} \end_inset \layout Standard When implementing libGOCR, the question arised: should we use grayscale? Is black and white enough? What about colors? We decided to use black and white only, since it seemed more than enough, and saved memory. Later, it was realized that color would be essential to some recognition systems --- specially if you want to use libGOCR to recognize something other than plain text. The design was changed, and now libGOCR support these image types \begin_float footnote \layout Standard Pixel size is in bytes, and is valid only for the x86 architecture (although if you have a decent compiler and sizeof(char)==1 then the results are likely to be the same o others). \end_float : \layout Standard \added_space_top 0.3cm \added_space_bottom 0.3cm \align center \begin_inset Tabular \begin_inset Text \layout Standard Type \end_inset \begin_inset Text \layout Standard Symbol \end_inset \begin_inset Text \layout Standard Pixel size \end_inset \begin_inset Text \layout Standard Black & white \end_inset \begin_inset Text \layout Standard GOCR_BW \end_inset \begin_inset Text \layout Standard 1 \end_inset \begin_inset Text \layout Standard Grayscale \end_inset \begin_inset Text \layout Standard GOCR_GRAY \end_inset \begin_inset Text \layout Standard 2 \end_inset \begin_inset Text \layout Standard Color \end_inset \begin_inset Text \layout Standard GOCR_COLOR \end_inset \begin_inset Text \layout Standard 4 \end_inset \begin_inset Text \layout Standard User-defined \end_inset \begin_inset Text \layout Standard GOCR_OTHER \end_inset \begin_inset Text \layout Standard - \end_inset \end_inset \layout Standard You may only access the image indirectly. \layout Standard The whole point of using an image is that you can access pixels individually, so, after several conferences and hundreds of emails, we decided that yes, we would have pixels in our images. Ok, the joke was not funny. \layout Standard To support the different image types, a slight hack was done in the gocrImageDat a structure, which contains the individual pixel data (section \begin_inset LatexCommand \ref{create image type} \end_inset has info about it, but you definitely don't need to know). In fact, you only won: you can access any image type just as if it's the type you want; that is, suppose the image loaded is in color, but you want to work in black and white: you can. The functions are: \layout LyX-Code void gocr_imagePixelSetBW \begin_inset LatexCommand \index{gocr\_imagePixelSetBW} \end_inset ( gocrImage *image \begin_deeper \layout LyX-Code int x, int y, unsigned char data ); \end_deeper \layout LyX-Code unsigned char gocr_imagePixelGetBW \begin_inset LatexCommand \index{gocr\_imagePixelGetBW} \end_inset ( gocrImage *image, \begin_deeper \layout LyX-Code int x, int y ); \end_deeper \layout LyX-Code void gocr_imagePixelSetGray \begin_inset LatexCommand \index{gocr\_imagePixelSetGray} \end_inset ( gocrImage *image, \begin_deeper \layout LyX-Code int x, int y, unsigned char data ); \end_deeper \layout LyX-Code unsigned char gocr_imagePixelGetGray \begin_inset LatexCommand \index{gocr\_imagePixelGetGray} \end_inset ( gocrImage *image, \begin_deeper \layout LyX-Code int x, int y ); \end_deeper \layout LyX-Code void gocr_imagePixelSetColor \begin_inset LatexCommand \index{gocr\_imagePixelSetColor} \end_inset ( gocrImage *image, \begin_deeper \layout LyX-Code int x, int y, unsigned char data[3] ); \end_deeper \layout LyX-Code unsigned char *gocr_imagePixelGetColor \begin_inset LatexCommand \index{gocr\_imagePixelGetColor} \end_inset ( gocrImage *image, \begin_deeper \layout LyX-Code int x, int y ); \end_deeper \layout Standard Examples \begin_inset LatexCommand \index{pixel!examples} \end_inset : \layout LyX-Code if ( gocr_imagePixelGetBW(img,0,0) == GOCR_WHITE ) \begin_deeper \layout LyX-Code gocr_pixelPixelSetBW(img,0,0,GOCR_BLACK); \end_deeper \layout LyX-Code \layout LyX-Code for ( i = 0; i < img->width; i++ ) \begin_deeper \layout LyX-Code for ( j = 0; j < img->height; j++ ) \begin_deeper \layout LyX-Code if ( gocr_imagePixelGetGray(img,i,j) > threshold ) \begin_deeper \layout LyX-Code gocr_imagePixelSetBW(img,i,j, GOCR_WHITE); \end_deeper \layout LyX-Code else \begin_deeper \layout LyX-Code gocr_imagePixelSetBW(img,i,j, GOCR_BLACK); \end_deeper \end_deeper \end_deeper \layout Standard The only thing to note is that, if you provide (x,y) coordinates out of bounds, the functions will return 0, which is also a valid value for a pixel. \layout Standard Each pixel has three fields that may be used as flags. They are boolean variables, and to access them use: \layout LyX-Code int gocr_pixelGetMark1 \begin_inset LatexCommand \index{gocr\_pixelGetMark} \end_inset ( gocrImage *image, int x, int y ); \layout LyX-Code int gocr_pixelSetMark1 \begin_inset LatexCommand \index{gocr\_pixelSetMark} \end_inset ( gocrImage *image, int x, int y, \begin_deeper \layout LyX-Code char value ); \end_deeper \layout LyX-Code int gocr_pixelGetMark2 \begin_inset LatexCommand \index{gocr\_pixelGetMark} \end_inset ( gocrImage *image, int x, int y ); \layout LyX-Code int gocr_pixelSetMark2 \begin_inset LatexCommand \index{gocr\_pixelSetMark} \end_inset ( gocrImage *image, int x, int y, \begin_deeper \layout LyX-Code char value ); \end_deeper \layout LyX-Code int gocr_pixelGetMark3 \begin_inset LatexCommand \index{gocr\_pixelGetMark} \end_inset ( gocrImage *image, int x, int y ); \layout LyX-Code int gocr_pixelSetMark3 \begin_inset LatexCommand \index{gocr\_pixelSetMark} \end_inset ( gocrImage *image, int x, int y, \begin_deeper \layout LyX-Code char value ); \end_deeper \layout Standard They are pretty clear, and return -1 in case of error. \layout Subsection The module \layout Standard The \family typewriter imageLoader \family default module has the following prototype: \layout LyX-Code int gocr_imageLoaderFunction ( const char *filename, \begin_deeper \layout LyX-Code void *data ); \end_deeper \layout Standard which, of course, may be named whatever you want. It's directly accessible by the user (by calling \family typewriter gocr_imageLoad \begin_inset LatexCommand \index{gocr\_imageLoad} \end_inset \family default ), and you can use the \family typewriter data \family default field to pass arguments. \layout Standard GOCRlib provides a default image loader, which handles the most common formats, and can convert images to any of the GOCRlib supported types (GOCR_BW, GOCR_GRAY, GOCR_COLOR) by using one of these symbols as argument. You should use GOCR_BW whenever you don't need extra information, since it's likely to take much less memory than the others. \layout Standard \color magenta It can be accessed with gocr_moduleAppend/etc by using \begin_inset Quotes eld \end_inset default \begin_inset Quotes erd \end_inset as argument. etc \layout Subsection Creating your own image type \begin_inset LatexCommand \index{image type} \end_inset \begin_inset LatexCommand \label{create image type} \end_inset \layout Standard This is not currently supported. It may be taken out, since C is unlikely to let us do it easily. \layout Standard If you need to create a special type, here's how to do it. It's not recommended that you do it, for the following reasons: \layout Itemize it's likely to be incompatible with current modules. \layout Itemize blabla \layout Standard What you need to do is quite simple. Declare your pixel like this: \layout LyX-Code struct mypixel { \begin_inset LatexCommand \index{gocrPixel} \end_inset \begin_deeper \layout LyX-Code unsigned char pad : 1; /* pad pixel */ \layout LyX-Code unsigned char mark1 : 1; /* user defined marker 1 */ \layout LyX-Code unsigned char mark2 : 1; /* user defined marker 1 */ \layout LyX-Code unsigned char mark3 : 1; /* user defined marker 1 */ \layout LyX-Code unsigned char isblock : 1; /* is part of a block? */ \layout LyX-Code unsigned char ischar : 1; /* is part of a character? */ \layout LyX-Code unsigned char private1: 1; /* internal field. */ \layout LyX-Code unsigned char private2: 1; /* internal field. */ \newline \layout LyX-Code /* your data goes here */ \end_deeper \layout LyX-Code }; \layout LyX-Code typedef struct mypixel MyPixel; \layout Standard You should name your data field \family typewriter value \family default . \layout Standard More: struct size, etc. \layout Section imageFilter \layout Standard It my be interesting to apply some filters to the image, to remove dust, etc. The functions of this module will get the image and apply the filter to it. \layout Standard Prototype is \layout LyX-Code int gocr_imageFilterFunction ( gocr_Image *src, gocr_Image *target, void *v ); \layout Standard You can work freely with the image, and apply any filters you desire; remember that modules that were not written by you may be used too, so do not apply a filter that changes the image data (gradient, laplacian, Fourier transform, etc). As a special note, do not create (complete) copies of the data, since it's likely to be big (expect a few megabytes for the image size). \layout Standard \color magenta todo: document application of filters to blocks of data, which may be transforma tions, etc. \layout Section blockFinder \begin_inset LatexCommand \index{blockFinder} \end_inset \layout Standard The objective of this module type is to divide the image in a number of blocks. A \emph on block \emph default \begin_inset LatexCommand \index{blocks} \end_inset is a set of pixels that are part of the original image, whose contents are all of the same type. Examples: a picture, a text column, a mathematical expression, a title. \layout Standard You must take care to avoid recognizing what should be only one block into more than one. Sometimes that's perfectly fine: for example, if a picture is recognized as two blocks, as long as they don't intersect each other, the only price to pay is to have two image files saved instead of only one; or if a text column is divided in half, along the horizontal, the output is likely to not take notice. But if the column is divided along the vertical, you may have a bad output. It's easier to say than to do, but a warning never hurts. \layout Standard The prototype of a blockFinder function is: \layout LyX-Code void gocr_blockFinder ( gocrImage *img, void *v ); \layout Subsection Block types \latex latex \begin_inset LatexCommand \index{blocks!types} \end_inset \begin_inset LatexCommand \label{block types} \end_inset \layout Standard Besides finding each block, you should try to recognize what kind of information that block carries. This will make the work of subsequent modules much easier, and will improve the speed of the processing. \layout Standard GOCR automatically defines three types of blocks: \layout Standard \added_space_top 0.3cm \added_space_bottom 0.3cm \align center \begin_inset Tabular \begin_inset Text \layout Standard Block type \end_inset \begin_inset Text \layout Standard TEXT \end_inset \begin_inset Text \layout Standard PICTURE \end_inset \begin_inset Text \layout Standard MATH_EXPRESSION \end_inset \end_inset \layout Standard \latex latex \backslash noindent \latex default but you can define new types, as explained below. The default is TEXT. \layout Standard The block types are objects, which all derive from a common parent, \family typewriter gocrBlock \family default . This allows any module to access the block, regardless of its type. This is what allows you to create new block types on the fly. To do that, you must first define the \family typewriter struct \family default of your new block type, which must be in the following format: \layout LyX-Code struct newblocktype { \begin_deeper \layout LyX-Code gocrBlock b; \layout LyX-Code /* other fields */ \end_deeper \layout LyX-Code }; \layout Standard It's absolutely necessary that the first field of your structure be \family typewriter gocrBlock b \family default . This is what allows to cast your structure to a simple \family typewriter gocrBlock \family default (If you are wondering why the hell I didn't use C++ instead of C, these are the reasons: it's easier to use C from C++ than the opposite; I have much more experience with C than C++; there are several people that program in C but not in C++; the use of C as an OO language, although slightly obfuscated, has proven to be possible and used in successful projects, such as GTK; C++ name mangling makes it more difficult to write modules, and is not supported yet by libtool). \layout Standard You must register your block type \begin_inset LatexCommand \index{blocks!type!registering} \end_inset , to make GOCR aware of its existance. To do that, use the following function: \layout LyX-Code blockType gocr_blockTypeRegister \begin_inset LatexCommand \index{gocr\_blockTypeRegister} \end_inset ( char *name ); \layout Standard This function takes the \family typewriter name \family default of your new block type, registers it, and returns a non negative number, which is the block type id \begin_inset LatexCommand \index{blocks!type!id} \end_inset , or -1 if some error occurred. This id should be saved, to provide a quick way to check what is the block type. Alternatively, you can use: \layout LyX-Code blockType gocr_blockTypeGetByName \begin_inset LatexCommand \index{gocr\_blockTypeGetByName} \end_inset ( char *name ); \layout Standard which returns the id of a already registered block type, or -1 if none was found. Since this function is kind of slow, as it must compare the string given to every other block type name registered, it's a good idea to save the id in a variable. Last, a convenience: \layout LyX-Code const char *gocr_blockTypeGetNameByType ( gocrblockType t ); \layout Standard given the block type, returns its name. Do not free this string. \layout Subsection Finding blocks \layout Standard Once you find a block, you have to notify GOCR: \layout LyX-Code int gocr_blockAdd \begin_inset LatexCommand \index{gocr\_blockAdd} \end_inset ( gocrBlock *b ); \layout Standard You are responsible for filling the \family typewriter x0 \family default , \family typewriter x1 \family default , \family typewriter y0 \family default , \family typewriter y1 \family default and \family typewriter t \family default fields of the block structure, and \emph on only \emph default those (well, if you fill anything else nothing will happen, you'll just be wasting processor time). You can pass the address of a derived block type to it. The function returns 0 if OK, -1 if error (if the block type isn't registered, it's considered an error). If two blocks overlap, and the BLOCK_OVERLAP flag is set to 0, the function returns -2. \begin_float footnote \layout Standard In the future, it will be possible to have blocks of any format, using a system similar to the used in characters currently. The problems are two: outputFormatter, and how to save the data without memory waste. \end_float \layout Subsection Blocks are more than frames \begin_inset LatexCommand \index{blocks!paradigm} \end_inset \layout Standard The blockFinder module is really half of the core of GOCR. It's responsible to setup everything to make the recognition itself a simple (ahn, simpler) task. It should, therefore, do all that it can in order to make the next two modules perform a simple, linear operation. \layout Standard Here's a description of what the module function should do for the three basic block types: \layout Subsubsection Text block \begin_inset LatexCommand \index{blocks!text!description} \end_inset \layout Standard \color magenta This structure will probably be severely changed. \layout Standard The text block structure is: \layout LyX-Code struct gocrtextblock { \begin_inset LatexCommand \index{gocrTextBlock} \end_inset \begin_deeper \layout LyX-Code gocrBlock b; /* parent; must be first field */ \layout LyX-Code List linelist; \end_deeper \layout LyX-Code }; \layout LyX-Code typedef struct gocrtextblock gocrTextBlock; \layout Standard The \family typewriter gocrBlock b \family default , as described above, is used to perform OO, and must be the first field. The only other field is a linked list (see section \begin_inset LatexCommand \ref{linked list} \end_inset ) of text lines: \layout LyX-Code struct line { \begin_inset LatexCommand \index{gocrLine} \end_inset \begin_deeper \layout LyX-Code int x0, x1; /* x-boundaries */ \layout LyX-Code int m0, m1, m2, m3; /* y-boundaries */ \layout LyX-Code List boxlist; \end_deeper \layout LyX-Code }; typedef struct line gocrLine; \layout Standard the \family typewriter x0 \family default and \family typewriter x1 \family default fields are the vertical boundaries, and the \family typewriter m? \family default fields are y boundaries: \layout Standard \added_space_top 0.3cm \added_space_bottom 0.3cm \align center \begin_inset Tabular \begin_inset Text \layout Standard Field \end_inset \begin_inset Text \layout Standard Description \end_inset \begin_inset Text \layout Standard m0 \end_inset \begin_inset Text \layout Standard Top boundary \end_inset \begin_inset Text \layout Standard m1 \end_inset \begin_inset Text \layout Standard Middle \end_inset \begin_inset Text \layout Standard m2 \end_inset \begin_inset Text \layout Standard Baseline \end_inset \begin_inset Text \layout Standard m3 \end_inset \begin_inset Text \layout Standard Bottom \end_inset \end_inset \layout Standard PICTURE describing them \layout Standard These fields are of utmost importance to the charRecognizer and charFinder modules, and their correct determination is crucial. Last is \family typewriter boxlist \family default , which is a list of \family typewriter Boxes \family default , a structure described in the next section. \layout Subsubsection Picture block \begin_inset LatexCommand \index{blocks!picture!description} \end_inset \layout Standard This is a very simple structure: \layout LyX-Code \family typewriter struct gocrpictureblock { \begin_deeper \layout LyX-Code \family typewriter gocrBlock b; /* parent; must be first field */ \layout LyX-Code \family typewriter char *name; \layout Standard \family typewriter }; \layout Standard \family typewriter typedef struct gocrpictureblock gocrPictureBlock; \end_deeper \layout Standard The structure contains only one field, \family typewriter name \family default , which is the name of the file to which the picture will be saved. \layout Subsubsection Math block \begin_inset LatexCommand \index{blocks!math!description} \end_inset \layout Standard Will use trees. To do. \layout Subsection Final considerations \layout Standard If no block was found, NO_BLOCK is set to 1 and \family typewriter gocr_runAllModules() \family default was called, GOCR creates a block covering the entire image, and continues to process the image, calling the charFinder module. If NO_BLOCK is set to 0, then \family typewriter gocr_runAllModules \family default returns -1. \layout Section charFinder \begin_inset LatexCommand \index{charFinder} \end_inset \layout Standard This module should parse each block and frame every character found. It should also provide information about the character, such as if it's bold or italic, the font, etc. This information is used by the charRecognizer module functions to quickly check if they will be able to recognize the character or will just waste processing time. Prototype: \layout LyX-Code int gocr_charFinder ( gocrBlock *b, void *v ); \layout Standard In more detail, what should happen in this module is in this pseudo code: \layout LyX-Code sweep the block \layout LyX-Code for each character { \begin_deeper \layout LyX-Code find pertinent pixels \layout LyX-Code find pertinent attributes \end_deeper \layout LyX-Code } \layout LyX-Code return 0 \layout Standard The function should return 0 if it took care of the block, -1 otherwise (for example, you don't recognize the block type). \layout Standard The way you sweep the block is completely on yourself, and but it must be done in a way that the outputFormatter module will understand. It makes sense. at least when parsing text, to sweep as one would read it (which means that you are not stuck to left to right, top to bottom languages). GOCR saves the characters in the order you add them. \color red Talk about how charRecognizer will receive the data and add to a linked list, etc. Add some way to override this default behaviour of adding characters to the list \layout Subsection Getting block information \begin_inset LatexCommand \index{blocks!in charFinder} \end_inset \layout Standard The charFinder module functions are specialized in certain block types, and thus get extra information from the blockFinder module. They must be so, otherwise they won't be able to read properly the block structure, which must be cast to the appropriate type. Your module function is likely to be something like this: \layout LyX-Code gocrBlockType your_block_type; \newline \layout LyX-Code int charFinderFunction ( gocrBlock *b, void *v ) { \begin_deeper \layout LyX-Code switch ( b->type ) { \begin_deeper \layout LyX-Code case TEXT: \begin_deeper \layout LyX-Code gocrTextBlock *tb = (gocrTextBlock *)b; \layout LyX-Code /* your code */ \layout LyX-Code return 0; \end_deeper \layout LyX-Code case YOUR_BLOCK_TYPE: \begin_deeper \layout LyX-Code your_block_struct *mb = (your_block_struct *)b; \layout LyX-Code /* your code */ \layout LyX-Code return 0; \end_deeper \layout LyX-Code case PICTURE: \layout LyX-Code default: \begin_deeper \layout LyX-Code return -1; \end_deeper \end_deeper \layout LyX-Code } \end_deeper \layout LyX-Code } \layout Standard This hypothetical function can deal with text blocks and a special block type that was previously registered, but not pictures or anything else; if you can't process a block, return -1; if you could, return 0. Currently, once a function process a block, GOCR supposes that it could do all the job there was to be done, and no other function is called (this is to avoid processing the same block twice and ending with duplicated information). Future versions may allow partial processing. \layout Subsection Delimiting characters \begin_inset LatexCommand \index{characters!creating} \end_inset \layout Standard To delimit a character, GOCR API provides a set of functions that let you select only the pixels that are part of the character. \layout Standard First thing to do is to declare that you are starting a new character: \layout LyX-Code int gocr_charBegin \begin_inset LatexCommand \index{gocr\_charBegin} \end_inset ( void ); \layout Standard This function returns -1 in case something is wrong; starting a character without ending the last one is considered an error. To end a character: \layout LyX-Code int gocr_charEnd \begin_inset LatexCommand \index{gocr\_charEnd} \end_inset ( void ); \layout Standard This function creates an image that is initially filled with the background color, with all bits unset. This image is big enough to contain all the pixels selected; these pixels are copied to the new image (only the data, the info bits are still unset), and will be passed to the charRecognizer module. \color red gocr_charEnd automatically calls the charRecognizer module? Explain FIND_ALL \layout Standard Between these two functions, you can set the pixels of the character, using the functions explained below. The \family typewriter action \family default field is common to all of them; if GOCR_SET, then the function will select; if GOCR_UNSET, the function will unselect. \layout LyX-Code int gocr_charSetPixel \begin_inset LatexCommand \index{gocr\_charSetPixel} \end_inset ( int action, int x, int y ); \layout Standard Selects the pixel at (x, y). \layout LyX-Code int gocr_charSetAllNearPixels \begin_inset LatexCommand \index{gocr\_charSetAllNearPixels} \end_inset ( int action, int x, int y, \begin_deeper \layout LyX-Code int connect ); \end_deeper \layout Standard If \family typewriter connect \family default is 4, selects all the pixels of the same color that are 4-connected with the pixel at (x, y); if connect is 8, selects all the pixels of the same color that are 8-connected with the pixel at (x, y). If \family typewriter connect \family default is neither 4 nor 8, the function assumes 4-connection. \layout LyX-Code int gocr_charSetRect \begin_inset LatexCommand \index{gocr\_charSetRect} \end_inset ( int action, int x0, int y0, int x1, \begin_deeper \layout LyX-Code int y1 ); \end_deeper \layout Standard Selects all pixels contained at the rectangle defined by (x0, y0) and (x1, y1). These points don't need to be top left and right bottom; they can be any diagonally opposite vertices. Internally, however, GOCR always convert (x0, y0) to be top left and (x1, y1) to be bottom right. This is valid for any function that takes two points defining a rectangle as arguments. \layout Standard If you change your mind after a call to \family typewriter gocr_charBegin \family default , you can still save the nation: \layout LyX-Code void gocr_charAbort \begin_inset LatexCommand \index{gocr\_charAbort} \end_inset ( void ); \layout Standard This function aborts a character begun using gocr_charBegin. All changes done by the gocr_charSet* functions since the last call to gocr_charBegin are undone. \layout Standard When you can \family typewriter gocr_charEnd \family default , the character can be saved as a simple rectangle that covers all the pixels you selected, or saving each individual pixel. While the later gives a lot more freedom, letting you select awkward regions, it consumes about 12.5% more memory, and is slower. \color magenta This is controlled by the CHAR_RECTANGLES flag. Done as argument to gocr_charEnd? \layout Subsection Setting attributes \begin_inset LatexCommand \index{characters!attributes} \end_inset \layout Standard Setting attributes of the text can get quite complicated if you want to be fancy. It was decided to design a very simple, yet powerful system, that should be able to handle most of the stuff you ever need. First, a reminding note: these attributes should only be those that are applied directly to the text, such as bold, italic, font type, etc. \layout Standard As usual in GOCR, the first thing to do is to create the attribute: \layout LyX-Code int gocr_charAttributeRegister \begin_inset LatexCommand \index{gocr\_charAttributeCreate} \end_inset ( char *name, \begin_deeper \layout LyX-Code gocrCharAttributeType t, char *format ); \end_deeper \layout Description name attribute name; must be unique. We recommend to use capital letters, but it's up to you. \layout Description type there are two possible values: \begin_deeper \layout Description SETTABLE the attribute works like a flag: either it's set, or not set. Example: boldness. \layout Description UNTIL_OVERRIDEN the attribute is valid for ever; you can only change it's values. Example: font. There must always be a font type and size, but they may change during the text. \end_deeper \layout Description format this field is used to store any attributes of the attribute (wow). It will be explained below, with a example. \layout Standard As usual, the function returns 0 if OK, -1 if error (inserting an existant attribute is considered an error). Now that you created your attributes, you are processing the text and find that you need to set an attribute. Do it with the following function: \color magenta This function name may be changed. \layout LyX-Code int gocr_charAttributeInsert \begin_inset LatexCommand \index{gocr\_charAttributeInsert} \end_inset ( char *name, ... ); \layout Description name attribute name. \layout Standard I bet you are probably wondering how the hell this stuff works. Me too. Uh, I mean, it's easier to understand using an example. The first one is simple: \layout LyX-Code gocr_charAttributeRegister("BOLD", SETTABLE, NULL); \layout LyX-Code \layout LyX-Code gocr_charAttributeInsert("BOLD"); \layout LyX-Code /* insert some text */ \layout LyX-Code gocr_charAttributeInsert("BOLD"); \layout Standard Quite easy: first you register the bold style. It's a settable attribute, and since you don't need any extra information, the \family typewriter format \family default field is NULL. Then, when processing the text, you find a word in bold. What you do is simple: insert a bold, insert the text, insert another bold. Since it's a settable attribute, the second one cancels the effect. \layout Standard Let's do something fancier now: \layout LyX-Code gocr_charAttributeRegister("FONT", UNTIL_OVERRIDEN, "%s %d"); \layout LyX-Code \layout LyX-Code gocr_charAttributeInsert("FONT", "Arial", 18); \layout LyX-Code /* insert some text */ \layout LyX-Code gocr_charAttributeInsert("FONT", "TimesNewRoman", 12); \layout LyX-Code /* insert some more text */ \layout Standard Now the explanation of the \family typewriter format \family default field: it's just a printf-like format field! So, you can save whatever you want in a format that will be easily read by anybody, even if they do not know what it means --- this is specially good when you are writing a outputFormatter module. When you insert the attribute, you pass the arguments to the format string. So, what happens in the example: we create an attribute \begin_inset Quotes eld \end_inset FONT \begin_inset Quotes erd \end_inset , which is valid for ever. Note that, although it's valid for ever, it only starts to have effect when you first call \family typewriter gocr_charAttributeInsert \family default , because you need to set its internal attributes (even if it doesn't have any). In the example, you are parsing a page, and finds that the title is typeset in Arial, size 18. The text in in Times New Roman, size 12. \layout Standard Always remember that this system is subject to all the limitations of printf and scanf. For example: in scanf, %s reads a string up to the first white space, so you can't use spaces in a %s string, even though printf accepts it. And, since GOCR does not check the format string, if you screw it up you are screwing everything. \layout Section charRecognizer \begin_inset LatexCommand \index{charRecognizer} \end_inset \layout Standard This is the core of the OCRing. This module, using some ingenious algorithm, must be able to find that the bitmap it processed is a certain character. Prototype: \layout LyX-Code \size small void gocr_charRecognizer ( gocrImage *pix, gocrBox *b, void *v ); \layout Standard \family typewriter pix \family default is an image of the framed character, whose structure \family typewriter gocrImage \family default is described in section \begin_inset LatexCommand \ref{image structure} \end_inset . There are two reasons to prefer to access \family typewriter pix \family default than the \family typewriter get/setData \family default : first, the former is much smaller, and will be entirely in the processor's cache, therefore being accessed much more quickly; second, the former starts on 0, while you'll have to add b->x0 and b->y0 to the latter. Of course, you may still use the \family typewriter set/getData \family default functions. \layout Subsection Using UNICODE \latex latex \backslash copyright \begin_inset LatexCommand \index{UNICODE} \end_inset \layout Standard Quoting from a document by Markus Kuhn that can be found at: http://www.cl.cam.ac.uk/~mgk25/unicode.html. It's a very good document, and you should read it. \layout Quotation What is UNICODE? \layout Quotation Historically, there have been two independent attempts to create a single unified character set. One was the ISO 10646 project of the International Organization for Standardiza tion (ISO), the other was the Unicode Project organized by a consortium of (initially mostly US) manufacturers of multi-lingual software. Fortunately, the participants of both projects realized around 1991 that two different unified character sets is not what the world needs. They joined their efforts and worked together on creating a single code table. Both projects still exist and publish their respective standards independently, however the Unicode Consortium and ISO/IEC JTC1/SC2 have agreed to keep the code tables of the Unicode and ISO 10646 standards compatible and they closely coordinate any further extensions. Unicode 1.1 corresponds to ISO 10646-1:1993 and Unicode 3.0 corresponds to ISO 10646-1:2000. \layout Standard In GOCR, we adopted the Unicode Standard version 3.0. To the programmer using GOCR, this is a very simple way to deal with characters that are not in the ASCII or the ISO-8859-1 table, and let one to support any language. \layout Standard Support in GOCR is very simple, as it should be. There's a list #defining some of the characters in \family typewriter unicode.h \family default . Note that only a small portion of the Unicode set is present there, which reflect what we hope to be able to recognize in the near future, and what we already do. If you need to support other characters not found there, please feel free to. Be sure to use their correct codes; you can get a full list of them in: \layout LyX-Code http://www.unicode.org \layout Standard and if you notify us, we add them to the header. As GOCR treats the codes as simple numbers, it doesn't matter if it's in the header or not. The only problem you may find is with the outputFormatter plugin, which may not support some characters. \layout Standard In short, GOCR uses UCS-4 encoding \emph on internally \emph default . This is much easier to handle by the programmer than UTF-8 encoding, and should not pose problems provided that you use \family typewriter wcs* \family default functions instead of the usual \family typewriter str* \family default functions. The OutputFormatter module can be used to export UTF-8 text or whatever you need. \layout Standard The \family typewriter wchar_t \family default type is used to handle wide characters. If needed, we assume that \family typewriter wchar_t \family default is 32 bits long, which is the default these days, but a 16-bit \family typewriter wchar_t \family default may work if you don't use characters whose code is larger than 0xFFFF (65535). \layout Standard GOCR provides a simple function that helps to compose characters and accents: \layout LyX-Code wchar_t gocr_compose \begin_inset LatexCommand \index{gocr\_compose} \end_inset ( wchar_t main, wchar_t modifier ); \layout Standard Now the arguments: \family typewriter main \family default is the character, and \family typewriter modifier \family default is the accent; the function returns the code of the accented character. Example: \layout LyX-Code character = gocr_compose( a, ACUTE_ACCENT ); \layout Standard returns the code of the character á. Currently this function supports the following: \layout Standard \added_space_top 0.3cm \added_space_bottom 0.3cm \align center \begin_inset Tabular \begin_inset Text \layout Standard Modifier \end_inset \begin_inset Text \layout Standard Characters \end_inset \begin_inset Text \layout Standard ACUTE_ACCENT \end_inset \begin_inset Text \layout Standard aeiouy AEIOUY \end_inset \begin_inset Text \layout Standard CEDILLA \end_inset \begin_inset Text \layout Standard c C \end_inset \begin_inset Text \layout Standard TILDE \end_inset \begin_inset Text \layout Standard ano ANO \end_inset \begin_inset Text \layout Standard GRAVE_ACCENT \end_inset \begin_inset Text \layout Standard aeiou AEIOU \end_inset \begin_inset Text \layout Standard DIAERESIS \end_inset \begin_inset Text \layout Standard aeiouy AEIOUY \end_inset \begin_inset Text \layout Standard CIRCUMFLEX_ACCENT \end_inset \begin_inset Text \layout Standard aeiou AEIOU \end_inset \begin_inset Text \layout Standard RING_ABOVE \end_inset \begin_inset Text \layout Standard a A \end_inset \begin_inset Text \layout Standard e or E ( \latex latex \backslash ae \latex default , \latex latex \backslash oe \latex default ) \end_inset \begin_inset Text \layout Standard ao AO \end_inset \end_inset \layout Standard Besides that, it also supports a latin \begin_inset Formula \( \rightarrow \) \end_inset greek character translation, if you pass 'g' as \family typewriter modifier \family default . See the table for reference. \begin_float tab \layout Standard \added_space_top 0.3cm \align center \begin_inset Tabular \begin_inset Text \layout Standard Latin \end_inset \begin_inset Text \layout Standard Greek \end_inset \begin_inset Text \layout Standard a \end_inset \begin_inset Text \layout Standard \begin_inset Formula \( \alpha \) \end_inset \end_inset \begin_inset Text \layout Standard b \end_inset \begin_inset Text \layout Standard \begin_inset Formula \( \beta \) \end_inset \end_inset \begin_inset Text \layout Standard g \end_inset \begin_inset Text \layout Standard \begin_inset Formula \( \gamma \) \end_inset \end_inset \begin_inset Text \layout Standard d \end_inset \begin_inset Text \layout Standard \begin_inset Formula \( \delta \) \end_inset \end_inset \begin_inset Text \layout Standard e \end_inset \begin_inset Text \layout Standard \begin_inset Formula \( \epsilon \) \end_inset \end_inset \begin_inset Text \layout Standard z \end_inset \begin_inset Text \layout Standard \begin_inset Formula \( \zeta \) \end_inset \end_inset \begin_inset Text \layout Standard h \end_inset \begin_inset Text \layout Standard \begin_inset Formula \( \eta \) \end_inset \end_inset \begin_inset Text \layout Standard q \end_inset \begin_inset Text \layout Standard \begin_inset Formula \( \theta \) \end_inset \end_inset \begin_inset Text \layout Standard i \end_inset \begin_inset Text \layout Standard \begin_inset Formula \( \iota \) \end_inset \end_inset \begin_inset Text \layout Standard k \end_inset \begin_inset Text \layout Standard \begin_inset Formula \( \kappa \) \end_inset \end_inset \begin_inset Text \layout Standard l \end_inset \begin_inset Text \layout Standard \begin_inset Formula \( \lambda \) \end_inset \end_inset \begin_inset Text \layout Standard m \end_inset \begin_inset Text \layout Standard \begin_inset Formula \( \mu \) \end_inset \end_inset \begin_inset Text \layout Standard n \end_inset \begin_inset Text \layout Standard \begin_inset Formula \( \nu \) \end_inset \end_inset \begin_inset Text \layout Standard x \end_inset \begin_inset Text \layout Standard \begin_inset Formula \( \xi \) \end_inset \end_inset \begin_inset Text \layout Standard o \end_inset \begin_inset Text \layout Standard o \end_inset \begin_inset Text \layout Standard p \end_inset \begin_inset Text \layout Standard \begin_inset Formula \( \pi \) \end_inset \end_inset \begin_inset Text \layout Standard r \end_inset \begin_inset Text \layout Standard \begin_inset Formula \( \rho \) \end_inset \end_inset \begin_inset Text \layout Standard & \end_inset \begin_inset Text \layout Standard \begin_inset Formula \( \varsigma \) \end_inset \end_inset \begin_inset Text \layout Standard s \end_inset \begin_inset Text \layout Standard \begin_inset Formula \( \sigma \) \end_inset \end_inset \begin_inset Text \layout Standard t \end_inset \begin_inset Text \layout Standard \begin_inset Formula \( \tau \) \end_inset \end_inset \begin_inset Text \layout Standard y \end_inset \begin_inset Text \layout Standard \begin_inset Formula \( \upsilon \) \end_inset \end_inset \begin_inset Text \layout Standard f \end_inset \begin_inset Text \layout Standard \begin_inset Formula \( \phi \) \end_inset \end_inset \begin_inset Text \layout Standard c \end_inset \begin_inset Text \layout Standard \begin_inset Formula \( \chi \) \end_inset \end_inset \begin_inset Text \layout Standard v \end_inset \begin_inset Text \layout Standard \begin_inset Formula \( \psi \) \end_inset \end_inset \begin_inset Text \layout Standard w \end_inset \begin_inset Text \layout Standard \begin_inset Formula \( \omega \) \end_inset \end_inset \end_inset \layout Caption Latin \begin_inset Formula \( \rightarrow \) \end_inset greek reference for gocr_compose. \end_float \layout Standard If \family typewriter main \family default is a capital letter, the returning characters will also be capital letters. Support of greek accents (tonos, dialytika, etc) is under way. \layout Subsection Setting characters \layout Standard When you are ready to add a character, use: \layout LyX-Code int gocr_boxCharSet \begin_inset LatexCommand \index{gocr\_boxCharSet} \end_inset ( gocrBox *b, wchar_t w, float prob ); \layout Standard The arguments are: \layout List \labelwidthstring 00.00.0000 \series bold b \series default the box you are processing. \layout List \labelwidthstring 00.00.0000 \series bold w \series default the character code. \layout List \labelwidthstring 00.00.0000 \series bold prob \series default the probability that the recognition is correct: 0.0 is none (which will take the character out of the list) and 1.0 is 100% sure. \layout Standard The most probable character will be returned later, etc \layout Subsection Attributes again \begin_inset LatexCommand \index{boxes!attributes} \end_inset \layout Standard The charFinder may not have found all the attributes of a character. Don't worry: this module may access the \family typewriter \color magenta gocr_charAttributeSet \family default \color default too. \layout Standard talk about using charAttribute funcitons here too, and how is gocrBox importnat here \layout Section contextCorrection \begin_inset LatexCommand \index{contextCorrection} \end_inset \layout Standard After everything, there will remain some characters that weren't recognized, and it's the task of this module to recognize them. These characters can be divided in three groups \begin_float footnote \layout Standard It's widely known that there are two types of people, those who separate people in two groups and those who don't. You might argue that there are three groups: those who separate people in three groups, those who don't separate people in groups, and those who can't decide. But then there are four groups: you must include those who separate people in two groups. And, since we are separating people in four groups, there is a fifth group. The problem is those idiots that can't make up their minds. \end_float : \layout Itemize merged characters. Due to imperfections of the original text, two or more characters ended touching it other, and should be separated. Ligatures may fall in this group too. \layout Itemize unsupported characters. There's not much to do with these; they just are not supported by any of the modules. \layout Itemize unrecognizable characters. Bad printing, bad scanning or some accident with the original document could have rendered some of the characters unrecognizable. They can be recognized by using some filter and reprocessing, or to use the context. \layout Standard So, these are the issues you must consider. \layout Subsection Accessing text \layout Standard TODO. \layout Subsection Splitting characters \begin_inset LatexCommand \index{characters!splitting} \end_inset \layout Standard GOCR provides a set of functions similar, or better, (almost) identical to those used to create characters to split them. \layout Standard Let's take a look of the situation: you have added a character that you later find out is in fact composed of two (or more, but let's assume two for simplicity; you can take care of more applying this procedure several times) characters. How to split them? Although you could delete the box, taking care of saving its attributes, create two new characters, etc, there's an easier way to do it: \layout LyX-Code int gocr_charSplitBegin \begin_inset LatexCommand \index{gocr\_charSplitBegin} \end_inset ( gocrBox *box ); \layout Description box the box to be splited. \layout Standard Now you can work just as if you were adding a character. All the \family typewriter gocr_charSet \family default functions can be used as usual. When you are done, call \layout LyX-Code int gocr_charSplitEnd \begin_inset LatexCommand \index{gocr\_charSplitEnd} \end_inset ( void ); \layout Standard It's time for the fine print. First, what happens: all the pixels you select will be part of the a new box. This box is inserted in the list \emph on before \emph default the original one, which is updated to hold the rest of the pixels only. All attributes that were part of the original box are now transferred to the new one (so, the original one doesn't have any attributes anymore; but since they are applied to the box before it, they are applied to it too). You can call \family typewriter gocr_Abort \family default just as if you were adding a character. \layout Standard \color magenta Future: there may be a flag to set which of the boxes goes before which. \layout Subsection Joining characters \layout Standard Still not planned. \layout Section outputFormatter \begin_inset LatexCommand \index{outputFormatter} \end_inset \layout Standard Once it's all done, the user usually wants the output sent to a file in some way that he/she can read it, instead of the beautiful, complex structures that are spread all over the computer memory. This module should satisfy this caprice. The prototype is: \layout LyX-Code void (*outputFormatter) (List *bl, void *v); \layout Standard where the list contains all the blocks, in the order you added them. \color magenta This module may be changed in the near future. \layout Standard Each block has a field called \family typewriter text \family default which contains all the characters of the block and the attributes. If you just want to dump them, lousily converted to ascii, here's an example of what you may do: \layout LyX-Code for_each_data(bl) { \begin_deeper \layout LyX-Code wchar_t *w = ((gocrBlock *)list_get_current(bl))->text; \layout LyX-Code while (*w) \begin_deeper \layout LyX-Code putc(*w++); \end_deeper \end_deeper \layout LyX-Code } end_for_each(bl); \layout Standard You can read more about lists in section \begin_inset LatexCommand \ref{linked list} \end_inset . \layout Subsection Dealing with unknown characters \layout Standard Since the user may be using any modules available, it's possible that they recognize some characters that are not supported by the outputFormatter function. Some may be not even in the UNICODE standard. \layout Standard We suggest three ways to deal with this situation. The first is to print the code in a readable format: U39A0, for example. The user probably can find what character is this, and using and editor easily replace the code by whatever he wants. \layout Standard The second suggestion is to let the user provide some mappings of his own, either by a configuration file or by using the gocr_setModuleAttribute (see \begin_inset LatexCommand \ref{module attributes} \end_inset ). This is our preferred solution, since it allows user customization with minimum effort. \layout Standard The third suggestion is to ask the user on the fly. \layout Subsection Dealing with unknown attributes \layout Standard TODO \layout Chapter Modules in deep \layout Standard While last chapter focused in an overview of what you have to do, this chapter presents utilities that are part of the GOCR module API, written to make your life a bit easier. \layout Section Printing image, blocks and boxes \begin_inset LatexCommand \index{boxes!printing} \end_inset \layout Standard GOCR provides a number of functions that print images, blocks or boxes, which are very helpful for debugging. How the image is printed depends of the PRINT attribute and the output file is controlled by the ERROR_FILE attribute (see section \begin_inset LatexCommand \ref{attributes} \end_inset ). \layout LyX-Code int gocr_printBlock \begin_inset LatexCommand \index{gocr\_printBlock} \end_inset ( gocrBlock *b ); \layout Standard Prints all information in \family typewriter gocrBlock *b \family default , if PRINT_IMAGE is GOCR_TRUE, prints framed image too. Here's an example of what is printed (PRINT = 0): \layout LyX-Code Block: x0:1, y0:1, x1:117, y1:16; type TEXT \layout LyX-Code ..**........******......*******..........**.....********.. \layout LyX-Code ****.......*....***....*.....**..........**.....*******... \layout LyX-Code ..**......**.....***...**....***........***.....*......... \layout LyX-Code ..**......***....***...**....***.......****.....*......... \layout LyX-Code ..**......***.....**.........**........*.**.....*......... \layout LyX-Code ..**.......**....***........***.......**.**.....*..***.... \layout LyX-Code ..**.............***.......***.......**..**.....****.**... \layout LyX-Code ..**............***......*****.......*...**.....**....**.. \layout LyX-Code ..**............***.........***.....**...**...........***. \layout LyX-Code ..**...........***...........***....*....**............**. \layout LyX-Code ..**..........***............***...*.....**............**. \layout LyX-Code ..**.........**.......***.....**...***********.***.....**. \layout LyX-Code ..**.........*.....*..***.....**.........**....***....***. \layout LyX-Code ..**........*......*..***....***.........**....**.....***. \layout LyX-Code ..**.......*********..**.....***.........**.....*.....**.. \layout LyX-Code *******...**********...***..***........*******..***.***... \layout Standard Same for boxes: \layout LyX-Code int gocr_printBox \begin_inset LatexCommand \index{gocr\_printBox} \end_inset ( gocrBox *b ); \layout Standard prints all information in \family typewriter gocrBox *b \family default ; if PRINT_IMAGE is GOCR_TRUE, prints framed image too. \layout LyX-Code int gocr_printBox2 \begin_inset LatexCommand \index{gocr\_printBox} \end_inset ( gocrBox *b1, gocrBox *b2 ); \layout Standard Prints two boxes, side by side. Neat for that quick check of what the heck is going wrong. \layout LyX-Code int gocr_printArea \begin_inset LatexCommand \index{gocr\_printArea} \end_inset ( gocrImage *image, int x0, \layout LyX-Code int y0, int x1, int y1 ); \layout Standard Prints the part of the \family typewriter image \family default framed by the (x0, y0) and (x1, y1) coordinates. \layout Section Linked lists \begin_inset LatexCommand \index{linked lists} \end_inset \begin_inset LatexCommand \label{linked list} \end_inset \layout Standard Internally, GOCR abuses of linked lists to store information. They are very useful for this kind of program, and you may need them. Include \family typewriter list.h \family default , and take advantage of our linked list functions, which were thoroughly tested! FREE! \layout LyX-Code void list_init ( List *l ); \layout Standard Must be called before you do any operations with the list, otherwise strange behaviors may occur. It doesn't not allocate memory, and so must received a non-NULL pointer. \layout LyX-Code int list_app ( List *l, void *data ); \layout Standard Appends an element \family typewriter data \family default to the end of the list. Returns 0 if OK, 1 otherwise. \layout LyX-Code int list_del ( List *l, void *data ); \layout Standard Deletes the node containing data. Use carefully. See \family typewriter for_each_data \family default , below. \layout LyX-Code int list_empty ( List *l ); \layout Standard Returns 1 if the list is empty, 0 otherwise. \layout LyX-Code void list_free ( List *l ); \layout Standard Frees the list structure and nodes. Does not free the data stored in it. \layout LyX-Code void *list_get_current(l) ( List *l ); \layout Standard Returns the data in the current node. See \family typewriter for_each_data \family default , below. \layout LyX-Code void *list_get_cur_prev(l) ( List *l ); \layout Standard Returns the data stored before the current node. See \family typewriter for_each_data \family default , below. \layout LyX-Code void *list_get_cur_next(l) ( List *l ); \layout Standard Returns the data stored after the current node. See \family typewriter for_each_data \family default , below. \layout LyX-Code void *list_get_header ( List *l ); \layout Standard Returns the data in the first node. \layout LyX-Code void *list_get_tail(l) ( List *l ); \layout Standard Returns the data in the last node. \layout LyX-Code int list_ins ( List *l, void *data_after, void *data ); \layout Standard Inserts \family typewriter data \family default before \family typewriter data_after \family default . \layout LyX-Code void * list_next ( List *l, void *data ); \layout Standard Returns the data stored after \family typewriter data \family default . \layout LyX-Code void * list_prev ( List *l, void *data ); \layout Standard Returns the data stored before \family typewriter data \family default . \layout LyX-Code \size small void list_sort(List *l, int (*compare)(const void *, const void *)); \layout Standard Similar to qsort: sorts the list. \family typewriter compare \family default function must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second. If two members compare as equal, their order in the sorted array is undefined. Uses a bubble sort to do the task. \layout LyX-Code int list_total ( List *l ); \layout Standard Returns the total number of nodes in the linked list. \layout LyX-Code for_each_data ( List *l ) { \begin_deeper \layout LyX-Code code \end_deeper \layout LyX-Code } end_for_each ( List *l ); \layout Standard This piece of code implements a for that sweeps the entire list, node by node. You can get the current node data using \family typewriter list_get_current \family default , the data before it using \family typewriter list_get_cur_prev \family default , and the data after it using \family typewriter list_get_cur_next \family default . Use these functions if possible instead of \family typewriter list_next \family default and \family typewriter list_prev \family default , since they are much faster. \layout Standard You can nest \family typewriter for_each_data \family default , but take care when you call \family typewriter list_del \family default , since you may be deleting one of the nodes that is the current one in a lower level. The internal code takes care of access to previous/next elements of the now defunct node. Here's an example: \layout LyX-Code for_each_data(l) { \begin_deeper \layout LyX-Code for_each_data(l) { \begin_deeper \layout LyX-Code list_del(l, header_data); \layout LyX-Code free(header_data); \end_deeper \layout LyX-Code } end_for_each(l); \layout LyX-Code \emph on tempnode = list_cur_next(l); \end_deeper \layout LyX-Code } end_for_each(l); \layout Standard Although you have deleted the current node of the outer loop, the line in italic will work as if nothing happened. But if it's replaced with: \layout LyX-Code tempnode = list_next(l, list_get_current(l)); \layout Standard the code will break, since \family typewriter list_get_current \family default will return either NULL or some garbage. The best way to avoid this problem is not using \family typewriter list_del \family default in a big stack of loops, or test the return value of \family typewriter list_get_current() \family default . You can use \family typewriter break \family default and \family typewriter continue \family default , just as if you were in a normal for loop, but \emph on never \emph default use a goto to somewhere outside the loop (theoretically you can do it, using the \family typewriter list_lower \family default function explained below, but if you do \series bold take care \series default ). \layout Standard Note: if you have two elements with the same data, the functions will assume that the first one is the wanted one. Not a bug, a feature. \layout Standard Another note: avoid calling \family typewriter list_prev \family default and \family typewriter list_next \family default . They are intensive and slow functions. Keep the result in a variable or, if you need something more, use \family typewriter list_get_element_from_data \family default , described below. \layout Subsection Internal list functions \layout Standard There are some functions that are used internally, but may be used by you to do some clever optimizations. Note that, if not used correctly, you may break the code. \layout LyX-Code Element *list_element_from_data ( List *l, void *data ); \layout Standard Given a data, returns the Element it's stored in. Element is a structure: \layout LyX-Code struct element { \begin_deeper \layout LyX-Code struct element *next, *previous; \layout LyX-Code void *data; \end_deeper \layout LyX-Code }; \layout LyX-Code typedef struct element Element; \layout Standard This may be interesting if you need to access the next and previous nodes several times and you are not using a \family typewriter for_each_data \family default , i.e., you need to use \family typewriter list_next \family default and \family typewriter list_prev \family default heavily. \layout LyX-Code int list_higher_level ( List *l ); \layout LyX-Code void list_lower_level ( List *l ); \layout Standard These functions are used internally by \family typewriter for_each_data \family default and should not be directly called by the user. \layout Section Hash tables \layout Standard Hash tables are used internally to access string arrays (which are used to save attributes that are created in real time, for example), and may be useful to you. The functions provided are not as flexible as the linked list ones, but should suffice for most uses. Remember to include \family typewriter hash.h \family default . \layout LyX-Code int hash_init ( HashTable *t, int size, int (*hash_func)(char *)); \layout Standard Initialize a hash table, with \family typewriter size \family default entries, using \family typewriter hash_func \family default as the hash generator func. If \family typewriter t \family default is NULL, the function automatically mallocs memory for it. If \family typewriter hash_func \family default is NULL, the default internal hash generator is used. Returns -1 on error, 0 if OK. \layout LyX-Code int hash_insert ( HashTable *t, char *key, void *data ); \layout Standard Inserts a new entry in table \family typewriter t \family default , with key \family typewriter key \family default , which will contain \family typewriter data \family default . Returns -1 on error, -2 if the data already exists, or the hash if everything was OK (although theoretically the hash should be hidden from the user, etc, it's used internally by GOCR to store character attributes. You can safely ignore the hash, and use if (hash_insert()) < 0 { error}). \layout LyX-Code void *hash_del ( HashTable *t, char *key ); \layout Standard Deletes the entry associated with the \family typewriter key \family default . Returns a pointer to the data structure, which is not freed. \layout LyX-Code void *hash_data ( HashTable *t, char *key ); \layout Standard Returns the a pointer to the data associated associated with \family typewriter key. \layout LyX-Code int hash_free ( HashTable *t, void (*free_func)(void *)); \layout Standard Frees the hash table contents. If \family typewriter free_func \family default is not NULL, it's called for every data stored in the table. Does not free the hash table structure itself. \layout LyX-Code char *hash_key ( HashTable *t, void *data ); \layout Standard Searches the hash table for the first ocurrence of data, and returns the corresponding key. \layout Chapter FAQ & Troubleshooting \layout Standard No matter how hard we developers work, writing perfect code, computers stubbornl y do not adapt to our code and insist in showing bugs and problems. \layout Section Install/running problems \layout Subsection I'm having NetPBM problems. \newline The compiler issues several warning about enum pm_check. \newline Image input or output is not working correctly. \layout Standard A: These are very likely to be result of a bad NetPBM install. \layout Standard For some reason, many Linux distributions still come with old NetPBM libraries. They lack functionality that GOCR could use, and probably have bugs that were already fixed. That would not be so bad if it were not for another problem: if you download the latest NetPBM package (http://netpbm.sourceforge.net), and do a \family typewriter make install \family default , (at least in my computer) the install is not complete. Besides the usual problem of things going to /usr, /usr/local/, /usr/local/shar e, etc, possibly resulting in keeping the old libraries and executables, the Makefile doesn't install the headers. This will lead to the \family typewriter enum pm_check \family default warnings, which seem kind of harmless, but end up messing everything. Solution: manually install the new headers (which are: pnm.h, pam.h, pbm.h, pgm.h, ppm.h, pbmplus.h and shhopt.h), and make sure that the old libraries are deleted (or at least that symbolic links point to the new ones). \layout Standard \SpecialChar ~ \layout Subsection libtool problems \layout Subsection configure problems \layout Subsection libltdl \layout Section Development \layout Subsection Why TRUE is defined as 0x22A8 (8872 in decimal)? \layout Standard Because UNICODE defines the symbol \begin_inset Formula \( \models \) \end_inset as TRUE, as code 0x22A8. If you need to use boolean values, use GOCR_TRUE and GOCR_FALSE, which are what you want. \layout Standard \SpecialChar ~ \layout Subsection How can I apply filters only to a block, instead of the entire image? \layout Standard Use gocr_runModuleFunction. For example, let's say that you want to apply function with id \emph on filter \emph default , extra data \emph on data \emph default to a block \emph on block \emph default : \layout LyX-Code gocr_runModuleFunction(filter, &block->image, data); \layout Standard Could it be any easier? You can do this for characters too, or any other image you have. \layout Chapter Notes \layout Standard These chapter contains internal notes to remind myself. Disregard them. \layout Section image \layout Standard finish the IO functions (support non-pam lib) \layout Standard finish the conversion functions \layout Section Blocks \layout Standard New architecture: instead of gocr_addBlock, use the gocr_beginBlock( geometry type) paradigm. Probably only after stable version, if ever. \layout Section charFinder \layout Standard gocr_endCharacter() may or may not automatically call charRecognizer. Set a flag to do it. \layout Standard How to save boxes? In a linked list in the gocrBlock structure? Otherwise, it's reponsability of the user? \layout Section Characters recognizer \layout Standard images Passed as copies, to improve speed with use of processor's cache. They are called/stored by gocr_endCharacter() (on flag, see above) ??? \layout Standard Finish charSplit[Begin/End] \layout Standard how to store the characters? A wchar_t *data is very inconvenient. Perhaps a linked list, paging the text. Probably wrapper functions. \layout Standard Take care of the char attributes in unicode.c \layout Section contextcorrection \layout Standard Let it access the characters without seeing internal codes (E0XX-EXXX). Should it never see the attributes? I think that knowledge such as \begin_inset Quotes eld \end_inset this is in italic \begin_inset Quotes erd \end_inset may be helpful. But using ispell will require conversion to text, which is not straight forward and should be done by outputFormatter. \layout Section outputformatter \layout Standard It should get the text preferably in one big chunk. \layout Standard \begin_inset LatexCommand \index{recursive|see{recursive}} \end_inset \layout Standard \begin_inset LatexCommand \printindex{} \end_inset \the_end