Changeset 132

Show
Ignore:
Timestamp:
03.07.2007 15:13:17 (1 year ago)
Author:
decoder
Message:

Added capabilities to scan PDF files (highly experimental and disabled by default)

  • config params: focr_scan_pdfs focr_pdf_maxpages
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/devel/FuzzyOcr.cf

    r129 r132  
    9999focr_bin_helper pnmnorm, pnminvert, pamthreshold, ppmtopgm, pamtopnm 
    100100focr_bin_helper tesseract 
     101 
     102# These helpers must be defined before enabling PDF scanning 
     103#focr_bin_helper pdfinfo, pdftops, pstopnm 
    101104 
    102105### 
     
    131134#focr_bin_pnminvert /usr/bin/pnminvert 
    132135 
     136#focr_bin_pdfinfo /usr/bin/pdfinfo 
     137#focr_bin_pdftops /usr/bin/pdftops 
     138#focr_bin_pstopnm /usr/bin/pstopnm 
     139 
    133140### 
    134141### Scansets  
     
    177184# Minimum image size to scan. Images with dimensions smaller than the 
    178185# ones specified here will be skipped: 
     186# (This parameter does not apply to PDF files) 
    179187# Default: Height:4 Width:4 
    180188# 
     
    184192# Maximum image size to scan. Images with dimensions bigger than the 
    185193# ones specified here will be skipped: 
     194# (This parameter does not apply to PDF files) 
    186195# Default: Height:800 Width:800 
    187196# 
     
    206215#focr_skip_bmp 1 
    207216#focr_skip_tiff 1 
     217# 
     218 
     219# PDF specific options 
     220# WARNING: Enable this at your own risk, this might lead to false positives and classify 
     221#          important documents as spam. YOU HAVE BEEN WARNED. 
     222#focr_scan_pdfs 0 
     223# PDFs having more pages than this value will be skipped 
     224#focr_pdf_maxpages 1 
    208225 
    209226# Default detection treshold (see manual)  
  • trunk/devel/FuzzyOcr.pm

    r131 r132  
    138138    foreach my $p ( 
    139139        $pms->{msg}->find_parts(qr(^image\b)i), 
    140         $pms->{msg}->find_parts(qr(Application/Octet-Stream)i) 
     140        $pms->{msg}->find_parts(qr(Application/Octet-Stream)i), 
     141        $pms->{msg}->find_parts(qr(application/pdf)i) 
    141142    ) { 
    142143        my $ctype = $p->{'type'}; 
     
    226227            $imgfiles{$filename}{width}  = $w ? $w : 1; 
    227228            $imgfiles{$filename}{height} = $h ? $h : 1; 
    228         } 
     229        } elsif (substr($pdata,0,5) eq "\x25\x50\x44\x46\x2d") { 
     230            my $version = substr($pdata,5,3); 
     231            infolog("PDF: [version $version] $filename ($pdatalen)"); 
     232            $imgfiles{$filename}{ftype} = 6; 
     233            $imgfiles{$filename}{version} = $version; 
     234            $imgfiles{$filename}{width}  = 0; 
     235            $imgfiles{$filename}{height} = 0; 
     236        } 
    229237 
    230238        #Skip unless we found the right header 
     
    234242            next; 
    235243        } 
    236  
    237         #Skip images that cannot contain text 
    238         if ($imgfiles{$filename}{height} < $conf->{focr_min_height}) { 
    239             infolog("Skipping image: height < $conf->{focr_min_height}"); 
    240             delete $imgfiles{$filename}; 
    241             next; 
    242         } 
    243  
    244         #Skip images that cannot contain text 
    245         if ($imgfiles{$filename}{width} < $conf->{focr_min_width}) { 
    246             infolog("Skipping image: width < $conf->{focr_min_width}"); 
    247             delete $imgfiles{$filename}; 
    248             next; 
    249         } 
    250  
    251         #Skip too big images, screenshots etc 
    252         if ($imgfiles{$filename}{height} > $conf->{focr_max_height}) { 
    253             infolog("Skipping image: height > $conf->{focr_max_height}"); 
    254             delete $imgfiles{$filename}; 
    255             next; 
    256         } 
    257  
    258         #Skip too big images, screenshots etc 
    259         if ($imgfiles{$filename}{width} > $conf->{focr_max_width}) { 
    260             infolog("Skipping image: width > $conf->{focr_max_width}"); 
    261             delete $imgfiles{$filename}; 
    262             next; 
    263         } 
    264  
     244        if ($imgfiles{$filename}{ftype} == 6) { 
     245                unless ($conf->{focr_scan_pdfs}) { 
     246                        infolog("Skipping PDF file: PDF Scanning was disabled in config"); 
     247                        next; 
     248                } 
     249        } else { 
     250                #Skip images that cannot contain text 
     251                if ($imgfiles{$filename}{height} < $conf->{focr_min_height}) { 
     252                    infolog("Skipping image: height < $conf->{focr_min_height}"); 
     253                    delete $imgfiles{$filename}; 
     254                    next; 
     255                } 
     256 
     257                #Skip images that cannot contain text 
     258                if ($imgfiles{$filename}{width} < $conf->{focr_min_width}) { 
     259                    infolog("Skipping image: width < $conf->{focr_min_width}"); 
     260                    delete $imgfiles{$filename}; 
     261                    next; 
     262                } 
     263 
     264                #Skip too big images, screenshots etc 
     265                if ($imgfiles{$filename}{height} > $conf->{focr_max_height}) { 
     266                    infolog("Skipping image: height > $conf->{focr_max_height}"); 
     267                    delete $imgfiles{$filename}; 
     268                    next; 
     269                } 
     270 
     271                #Skip too big images, screenshots etc 
     272                if ($imgfiles{$filename}{width} > $conf->{focr_max_width}) { 
     273                    infolog("Skipping image: width > $conf->{focr_max_width}"); 
     274                    delete $imgfiles{$filename}; 
     275                    next; 
     276                } 
     277        } 
    265278        #Found Image!! Get a temporary dir to save image 
    266279        $imgdir = Mail::SpamAssassin::Util::secure_tmpdir(); 
     
    689702                ++$imgerr if $conf->{focr_keep_bad_images}>0; next; 
    690703            } 
    691         } 
     704        } elsif ($$pic{ftype} == 6) { 
     705            infolog("Found PDF header name=\"$$pic{fname}\""); 
     706 
     707            my $missing_bin = 0; 
     708            foreach my $a (qw/pdftops pstopnm pdfinfo/) { 
     709                unless (defined $conf->{"focr_bin_$a"}) { 
     710                    $missing_bin = 1; 
     711                    errorlog("Cannot exec $a, skipping image"); 
     712                    next; 
     713                } 
     714            } 
     715 
     716            if ($missing_bin) { 
     717                next; 
     718            } 
     719 
     720            my @stderr_data; 
     721            my ($retcode, @stdout_data) = save_execute( 
     722                "$conf->{focr_bin_pdfinfo} $file", 
     723                undef, 
     724                ">$imgdir/pdfinfo.info", 
     725                ">>$imgdir/pdfinfo.err", 1); 
     726             
     727            foreach (@stdout_data) { 
     728                if ($_ =~ /^Pages:\s*([0-9]+)/) { 
     729                        $$pic{pages} = $1; 
     730                } 
     731            } 
     732             
     733            unless ($$pic{pages}) { 
     734                infolog("Can't determine page count of PDF Document\n"); 
     735            } 
     736 
     737            if ($$pic{pages} > $conf->{focr_pdf_maxpages}) { 
     738                infolog("PDF has too many pages, skipping this file...\n"); 
     739                next; 
     740            } 
     741             
     742            if ( ($$pic{ctype} !~ /pdf/i) and not $generic_ctype) { 
     743                wrong_ctype( "Application/PDF", $$pic{ctype} ); 
     744                $internal_score += $conf->{'focr_wrongctype_score'}; 
     745            } 
     746 
     747            $retcode = save_execute("$conf->{focr_bin_pdftops} $file -", undef, ">$file.ps", ">>$efile"); 
     748 
     749            if ($retcode<0) { 
     750                chomp $retcode; 
     751                printf RAWERR "?? Timed out > $retcode\n" if ($haserr>0); 
     752                errorlog("$conf->{focr_bin_pdftops}: Timed out [$retcode], skipping..."); 
     753                ++$imgerr if $conf->{focr_keep_bad_images}>0; next; 
     754            } elsif ($retcode>0) { 
     755                chomp $retcode; 
     756                printf RAWERR "?? [$retcode] returned from $conf->{focr_bin_pdftops}\n" if ($haserr>0); 
     757                errorlog("$conf->{focr_bin_pdftops}: Returned [$retcode], skipping..."); 
     758                ++$imgerr if $conf->{focr_keep_bad_images}>0; next; 
     759            } 
     760 
     761            $retcode = save_execute("$conf->{focr_bin_pstopnm} -stdout -xsize=1000 $file.ps", undef, ">$pfile", ">>$efile"); 
     762 
     763            if ($retcode<0) { 
     764                chomp $retcode; 
     765                printf RAWERR "?? Timed out > $retcode\n" if ($haserr>0); 
     766                errorlog("$conf->{focr_bin_pstopnm}: Timed out [$retcode], skipping..."); 
     767                ++$imgerr if $conf->{focr_keep_bad_images}>0; next; 
     768            } elsif ($retcode>0) { 
     769                chomp $retcode; 
     770                printf RAWERR "?? [$retcode] returned from $conf->{focr_bin_pstopnm}\n" if ($haserr>0); 
     771                errorlog("$conf->{focr_bin_pstopnm}: Returned [$retcode], skipping..."); 
     772                ++$imgerr if $conf->{focr_keep_bad_images}>0; next; 
     773            } 
     774        } 
    692775        else { 
    693776            errorlog("Image type not recognized, unknown format. Skipping this image..."); 
     
    751834        my $wref = get_wordlist(); 
    752835        my %words = %$wref; 
     836         
    753837        foreach my $scanset (@$scansets) { 
    754838            my $scanlabel = $scanset->{label}; 
     
    758842                next; 
    759843            } 
    760             if (($scancmd =~ m/ocrad/) and  
     844            if (($$pic{ftype} != 6) and ($scancmd =~ m/ocrad/) and  
    761845                ($$pic{width} < 16 or $$pic{height} < 16)) { 
    762846                warnlog("Skipping $scanlabel, image too small"); 
  • trunk/devel/FuzzyOcr.preps

    r100 r132  
    3333    args = -color -truecolor 
    3434} 
     35 
  • trunk/devel/FuzzyOcr.scansets

    r101 r132  
    6161#    args = -i $input 
    6262#} 
     63 
  • trunk/devel/FuzzyOcr/Config.pm

    r127 r132  
    445445        }); 
    446446    } 
     447 
     448    push (@cmds, { 
     449        setting => 'focr_scan_pdfs', 
     450        default => 0, 
     451        type => $Mail::SpamAssassin::Conf::CONF_TYPE_BOOL 
     452    }); 
     453    push (@cmds, { 
     454        setting => 'focr_pdf_maxpages', 
     455        default => 1, 
     456        type => $Mail::SpamAssassin::Conf::CONF_TYPE_NUMERIC 
     457    }); 
    447458 
    448459    push (@cmds, {