"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "main.cc" between
ocrad-0.24.tar.gz and ocrad-0.25.tar.gz

About: GNU Ocrad is an OCR (Optical Character Recognition) program.

main.cc  (ocrad-0.24):main.cc  (ocrad-0.25)
/* GNU Ocrad - Optical Character Recognition program /* GNU Ocrad - Optical Character Recognition program
Copyright (C) 2003-2014 Antonio Diaz Diaz. Copyright (C) 2003-2015 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or the Free Software Foundation, either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
skipping to change at line 42 skipping to change at line 42
#if defined(__MSVCRT__) || defined(__OS2__) || defined(_MSC_VER) #if defined(__MSVCRT__) || defined(__OS2__) || defined(_MSC_VER)
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <io.h> #include <io.h>
#endif #endif
#include "arg_parser.h" #include "arg_parser.h"
#include "common.h" #include "common.h"
#include "rational.h" #include "rational.h"
#include "rectangle.h" #include "rectangle.h"
#include "user_filter.h"
#include "page_image.h" #include "page_image.h"
#include "textpage.h" #include "textpage.h"
namespace { namespace {
const char * const Program_name = "GNU Ocrad"; const char * const Program_name = "GNU Ocrad";
const char * const program_name = "ocrad"; const char * const program_name = "ocrad";
const char * const program_year = "2014"; const char * const program_year = "2015";
const char * invocation_name = 0; const char * invocation_name = 0;
struct Input_control struct Input_control
{ {
Transformation transformation; Transformation transformation;
int scale; int scale;
Rational threshold, ltwh[4]; Rational threshold, ltwh[4];
bool copy, cut, invert, layout; bool copy, cut, invert, layout;
Input_control() Input_control()
skipping to change at line 123 skipping to change at line 124
} }
void show_help() void show_help()
{ {
std::printf( "GNU Ocrad is an OCR (Optical Character Recognition) program base d on a\n" std::printf( "GNU Ocrad is an OCR (Optical Character Recognition) program base d on a\n"
"feature extraction method. It reads images in pbm (bitmap), pgm\ n" "feature extraction method. It reads images in pbm (bitmap), pgm\ n"
"(greyscale) or ppm (color) formats and produces text in byte (8- bit) or\n" "(greyscale) or ppm (color) formats and produces text in byte (8- bit) or\n"
"UTF-8 formats. The pbm, pgm and ppm formats are collectively kno wn as pnm.\n" "UTF-8 formats. The pbm, pgm and ppm formats are collectively kno wn as pnm.\n"
"\nOcrad includes a layout analyser able to separate the columns or blocks\n" "\nOcrad includes a layout analyser able to separate the columns or blocks\n"
"of text normally found on printed pages.\n" "of text normally found on printed pages.\n"
"\nFor best results the characters should be at least 20 pixels h
igh. If\n"
"they are smaller, try the --scale option. Scanning the image at
300 dpi\n"
"usually produces a character size good enough for ocrad.\n"
"Merged, very bold or very light (broken) characters are normally
not\n"
"recognized correctly. Try to avoid them.\n"
"\nUsage: %s [options] [files]\n", invocation_name ); "\nUsage: %s [options] [files]\n", invocation_name );
std::printf( "\nOptions:\n" std::printf( "\nOptions:\n"
" -h, --help display this help and exit\n" " -h, --help display this help and exit\n"
" -V, --version output version information and exit\n " -V, --version output version information and exit\
" n"
" -a, --append append text to output file\n" " -a, --append append text to output file\n"
" -c, --charset=<name> try '--charset=help' for a list of na " -c, --charset=<name> try '--charset=help' for a list of n
mes\n" ames\n"
" -e, --filter=<name> try '--filter=help' for a list of nam " -e, --filter=<name> try '--filter=help' for a list of na
es\n" mes\n"
" -f, --force force overwrite of output file\n" " -E, --user-filter=<file> user-defined filter, see manual for
" -F, --format=<fmt> output format (byte, utf8)\n" format\n"
" -i, --invert invert image levels (white on black)\ " -f, --force force overwrite of output file\n"
n" " -F, --format=<fmt> output format (byte, utf8)\n"
" -l, --layout perform layout analysis\n" " -i, --invert invert image levels (white on black)
" -o, --output=<file> place the output into <file>\n" \n"
" -q, --quiet suppress all messages\n" " -l, --layout perform layout analysis\n"
" -s, --scale=[-]<n> scale input image by [1/]<n>\n" " -o, --output=<file> place the output into <file>\n"
" -t, --transform=<name> try '--transform=help' for a list of " -q, --quiet suppress all messages\n"
names\n" " -s, --scale=[-]<n> scale input image by [1/]<n>\n"
" -T, --threshold=<n%%> threshold for binarization (0-100%%) " -t, --transform=<name> try '--transform=help' for a list of
\n" names\n"
" -u, --cut=<l,t,w,h> cut input image by given rectangle\n" " -T, --threshold=<n%%> threshold for binarization (0-100%%
" -v, --verbose be verbose\n" )\n"
" -x, --export=<file> export results in ORF format to <file " -u, --cut=<l,t,w,h> cut input image by given rectangle\n
>\n" ); "
" -v, --verbose be verbose\n"
" -x, --export=<file> export results in ORF format to <fil
e>\n" );
if( verbosity >= 1 ) if( verbosity >= 1 )
{ {
std::printf( " -1..6 pnm output file type (debug)\n" std::printf( " -1..6 pnm output file type (debug)\n"
" -C, --copy 'copy' input to output (debug)\n" " -C, --copy 'copy' input to output (debug)\n"
" -D, --debug=<level> (0-100) output intermediate data (d ebug)\n" ); " -D, --debug=<level> (0-100) output intermediate data (d ebug)\n" );
} }
std::printf( "If no files are specified, ocrad reads the image from standard i nput.\n" std::printf( "\nIf no files are specified, ocrad reads the image from standard input.\n"
"If the -o option is not specified, ocrad sends text to standard output.\n" "If the -o option is not specified, ocrad sends text to standard output.\n"
"\nExit status: 0 for a normal exit, 1 for environmental problems (file\n" "\nExit status: 0 for a normal exit, 1 for environmental problems (file\n"
"not found, invalid flags, I/O errors, etc), 2 to indicate a corr upt or\n" "not found, invalid flags, I/O errors, etc), 2 to indicate a corr upt or\n"
"invalid input file, 3 for an internal consistency error (eg, bug ) which\n" "invalid input file, 3 for an internal consistency error (eg, bug ) which\n"
"caused ocrad to panic.\n" "caused ocrad to panic.\n"
"\nReport bugs to bug-ocrad@gnu.org\n" "\nReport bugs to bug-ocrad@gnu.org\n"
"Ocrad home page: http://www.gnu.org/software/ocrad/ocrad.html\n" "Ocrad home page: http://www.gnu.org/software/ocrad/ocrad.html\n"
"General help using GNU software: http://www.gnu.org/gethelp\n" ) ; "General help using GNU software: http://www.gnu.org/gethelp\n" ) ;
} }
skipping to change at line 249 skipping to change at line 256
int main( const int argc, const char * const argv[] ) int main( const int argc, const char * const argv[] )
{ {
Input_control input_control; Input_control input_control;
Control control; Control control;
const char * outfile_name = 0, * exportfile_name = 0; const char * outfile_name = 0, * exportfile_name = 0;
bool append = false, force = false; bool append = false, force = false;
invocation_name = argv[0]; invocation_name = argv[0];
const Arg_parser::Option options[] = const Arg_parser::Option options[] =
{ {
{ '1', 0, Arg_parser::no }, { '1', 0, Arg_parser::no },
{ '2', 0, Arg_parser::no }, { '2', 0, Arg_parser::no },
{ '3', 0, Arg_parser::no }, { '3', 0, Arg_parser::no },
{ '4', 0, Arg_parser::no }, { '4', 0, Arg_parser::no },
{ '5', 0, Arg_parser::no }, { '5', 0, Arg_parser::no },
{ '6', 0, Arg_parser::no }, { '6', 0, Arg_parser::no },
{ 'a', "append", Arg_parser::no }, { 'a', "append", Arg_parser::no },
{ 'c', "charset", Arg_parser::yes }, { 'c', "charset", Arg_parser::yes },
{ 'C', "copy", Arg_parser::no }, { 'C', "copy", Arg_parser::no },
{ 'D', "debug", Arg_parser::yes }, { 'D', "debug", Arg_parser::yes },
{ 'e', "filter", Arg_parser::yes }, { 'e', "filter", Arg_parser::yes },
{ 'f', "force", Arg_parser::no }, { 'E', "user-filter", Arg_parser::yes },
{ 'F', "format", Arg_parser::yes }, { 'f', "force", Arg_parser::no },
{ 'h', "help", Arg_parser::no }, { 'F', "format", Arg_parser::yes },
{ 'i', "invert", Arg_parser::no }, { 'h', "help", Arg_parser::no },
{ 'l', "layout", Arg_parser::no }, { 'i', "invert", Arg_parser::no },
{ 'o', "output", Arg_parser::yes }, { 'l', "layout", Arg_parser::no },
{ 'q', "quiet", Arg_parser::no }, { 'o', "output", Arg_parser::yes },
{ 's', "scale", Arg_parser::yes }, { 'q', "quiet", Arg_parser::no },
{ 't', "transform", Arg_parser::yes }, { 's', "scale", Arg_parser::yes },
{ 'T', "threshold", Arg_parser::yes }, { 't', "transform", Arg_parser::yes },
{ 'u', "cut", Arg_parser::yes }, { 'T', "threshold", Arg_parser::yes },
{ 'v', "verbose", Arg_parser::no }, { 'u', "cut", Arg_parser::yes },
{ 'V', "version", Arg_parser::no }, { 'v', "verbose", Arg_parser::no },
{ 'x', "export", Arg_parser::yes }, { 'V', "version", Arg_parser::no },
{ 0 , 0, Arg_parser::no } }; { 'x', "export", Arg_parser::yes },
{ 0 , 0, Arg_parser::no } };
const Arg_parser parser( argc, argv, options ); const Arg_parser parser( argc, argv, options );
if( parser.error().size() ) // bad option if( parser.error().size() ) // bad option
{ show_error( parser.error().c_str(), 0, true ); return 1; } { show_error( parser.error().c_str(), 0, true ); return 1; }
int retval = 0;
int argind = 0; int argind = 0;
for( ; argind < parser.arguments(); ++argind ) for( ; argind < parser.arguments(); ++argind )
{ {
const int code = parser.code( argind ); const int code = parser.code( argind );
if( !code ) break; // no more options if( !code ) break; // no more options
const char * const arg = parser.argument( argind ).c_str(); const char * const arg = parser.argument( argind ).c_str();
switch( code ) switch( code )
{ {
case '1': case '1':
case '2': case '2':
skipping to change at line 302 skipping to change at line 311
case '5': case '5':
case '6': control.filetype = code; break; case '6': control.filetype = code; break;
case 'a': append = true; break; case 'a': append = true; break;
case 'c': if( !control.charset.enable( arg ) ) case 'c': if( !control.charset.enable( arg ) )
{ control.charset.show_error( program_name, arg ); return 1; } { control.charset.show_error( program_name, arg ); return 1; }
break; break;
case 'C': input_control.copy = true; break; case 'C': input_control.copy = true; break;
case 'D': control.debug_level = std::strtol( arg, 0, 0 ); break; case 'D': control.debug_level = std::strtol( arg, 0, 0 ); break;
case 'e': if( !control.add_filter( program_name, arg ) ) return 1; case 'e': if( !control.add_filter( program_name, arg ) ) return 1;
break; break;
case 'E': retval = control.add_user_filter( program_name, arg );
if( retval != 0 ) return retval;
break;
case 'f': force = true; break; case 'f': force = true; break;
case 'F': if( !control.set_format( arg ) ) case 'F': if( !control.set_format( arg ) )
{ show_error( "bad output format.", 0, true ); return 1; } { show_error( "bad output format.", 0, true ); return 1; }
break; break;
case 'h': show_help(); return 0; case 'h': show_help(); return 0;
case 'i': input_control.invert = true; break; case 'i': input_control.invert = true; break;
case 'l': input_control.layout = true; break; case 'l': input_control.layout = true; break;
case 'o': outfile_name = arg; break; case 'o': outfile_name = arg; break;
case 'q': verbosity = -1; break; case 'q': verbosity = -1; break;
case 's': input_control.scale = std::strtol( arg, 0, 0 ); break; case 's': input_control.scale = std::strtol( arg, 0, 0 ); break;
skipping to change at line 343 skipping to change at line 355
else if( force ) control.outfile = std::fopen( outfile_name, "w" ); else if( force ) control.outfile = std::fopen( outfile_name, "w" );
else if( ( control.outfile = std::fopen( outfile_name, "wx" ) ) == 0 ) else if( ( control.outfile = std::fopen( outfile_name, "wx" ) ) == 0 )
{ {
if( verbosity >= 0 ) if( verbosity >= 0 )
std::fprintf( stderr, "Output file %s already exists.\n", outfile_name ) ; std::fprintf( stderr, "Output file %s already exists.\n", outfile_name ) ;
return 1; return 1;
} }
if( !control.outfile ) if( !control.outfile )
{ {
if( verbosity >= 0 ) if( verbosity >= 0 )
std::fprintf( stderr, "Cannot open %s\n", outfile_name ); std::fprintf( stderr, "Can't open '%s'\n", outfile_name );
return 1; return 1;
} }
} }
if( exportfile_name && control.debug_level == 0 && !input_control.copy ) if( exportfile_name && control.debug_level == 0 && !input_control.copy )
{ {
if( std::strcmp( exportfile_name, "-" ) == 0 ) if( std::strcmp( exportfile_name, "-" ) == 0 )
{ control.exportfile = stdout; if( !outfile_name ) control.outfile = 0; } { control.exportfile = stdout; if( !outfile_name ) control.outfile = 0; }
else else
{ {
control.exportfile = std::fopen( exportfile_name, "w" ); control.exportfile = std::fopen( exportfile_name, "w" );
if( !control.exportfile ) if( !control.exportfile )
{ {
if( verbosity >= 0 ) if( verbosity >= 0 )
std::fprintf( stderr, "Cannot open %s\n", exportfile_name ); std::fprintf( stderr, "Can't open '%s'\n", exportfile_name );
return 1; return 1;
} }
} }
std::fprintf( control.exportfile, std::fprintf( control.exportfile,
"# Ocr Results File. Created by %s version %s\n", "# Ocr Results File. Created by %s version %s\n",
Program_name, PROGVERSION ); Program_name, PROGVERSION );
} }
// process any remaining command line arguments (input files) // process any remaining command line arguments (input files)
FILE * infile = (argind < parser.arguments()) ? 0 : stdin; FILE * infile = (argind < parser.arguments()) ? 0 : stdin;
const char *infile_name = "-"; const char *infile_name = "-";
int retval = 0;
while( true ) while( true )
{ {
while( infile != stdin ) while( infile != stdin )
{ {
if( infile ) std::fclose( infile ); if( infile ) std::fclose( infile );
if( argind >= parser.arguments() ) { infile = 0; break; } if( argind >= parser.arguments() ) { infile = 0; break; }
infile_name = parser.argument( argind++ ).c_str(); infile_name = parser.argument( argind++ ).c_str();
if( std::strcmp( infile_name, "-" ) == 0 ) infile = stdin; if( std::strcmp( infile_name, "-" ) == 0 ) infile = stdin;
else infile = std::fopen( infile_name, "rb" ); else infile = std::fopen( infile_name, "rb" );
if( infile ) break; if( infile ) break;
if( verbosity >= 0 ) if( verbosity >= 0 )
std::fprintf( stderr, "Cannot open %s\n", infile_name ); std::fprintf( stderr, "Can't open '%s'\n", infile_name );
if( retval == 0 ) retval = 1; if( retval == 0 ) retval = 1;
} }
if( !infile ) break; if( !infile ) break;
int tmp = process_file( infile, infile_name, input_control, control ); const int tmp = process_file( infile, infile_name, input_control, control );
if( infile == stdin ) if( infile == stdin )
{ {
if( tmp <= 1 ) if( tmp <= 1 ) // detect EOF
{ {
int ch; int ch;
do ch = std::fgetc( infile ); while( std::isspace( ch ) ); do ch = std::fgetc( infile ); while( ch == 0 || std::isspace( ch ) );
std::ungetc( ch, infile ); std::ungetc( ch, infile );
} }
if( tmp > 1 || std::feof( infile ) || std::ferror( infile ) ) infile = 0; if( tmp > 1 || std::feof( infile ) || std::ferror( infile ) ) infile = 0;
} }
if( tmp > retval ) retval = tmp; if( tmp > retval ) retval = tmp;
if( control.outfile ) std::fflush( control.outfile ); if( control.outfile ) std::fflush( control.outfile );
if( control.exportfile ) std::fflush( control.exportfile ); if( control.exportfile ) std::fflush( control.exportfile );
} }
if( control.outfile ) std::fclose( control.outfile ); if( control.outfile ) std::fclose( control.outfile );
if( control.exportfile ) std::fclose( control.exportfile ); if( control.exportfile ) std::fclose( control.exportfile );
 End of changes. 16 change blocks. 
60 lines changed or deleted 76 lines changed or added

Home  |  About  |  All  |  Newest  |  Fossies Dox  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTPS