We help IT Professionals succeed at work.

Perl Iteration issue

See attached code.  This is the main part of my Perl program.  Here is my data.txt file:

TYPE:
C:\Users\ddecker\Desktop\Dad\tiffs\filename.tif:
TIFF Directory at offset 0x10eb4
  Image Width: 1728 Image Length: 2376
  Resolution: 200, 200 pixels/inch
  Bits/Sample: 1
  Compression Scheme: CCITT Group 4
  Photometric Interpretation: min-is-white
  FillOrder: lsb-to-msb
  Document Name: "Standard Input"
  Image Description: "converted PBM file"
  Orientation: row 0 top, col 0 lhs
  Samples/Pixel: 1
  Rows/Strip: 2376
  Planar Configuration: single image plane
TYPE:
C:\Users\ddecker\Desktop\Dad\tiffs\filename2.tif:
TIFF Directory at offset 0x4aac
  Image Width: 1728 Image Length: 2376
  Resolution: 200, 200 pixels/inch
  Bits/Sample: 1
  Compression Scheme: CCITT Group 4
  Photometric Interpretation: min-is-white
  FillOrder: lsb-to-msb
  Document Name: "Standard Input"
  Image Description: "converted PBM file"
  Orientation: row 0 top, col 0 lhs
  Samples/Pixel: 1
  Rows/Strip: 2376
  Planar Configuration: single image plane
TYPE:
C:\Users\ddecker\Desktop\Dad\tiffs\filename3.tif:
TIFF Directory at offset 0x8
  Subfile Type: (0 = 0x0)
  Image Width: 124 Image Length: 124
  Resolution: 31, 31 pixels/inch
  Bits/Sample: 8
  Compression Scheme: None
  Photometric Interpretation: RGB color
  Software: "¼"
  Samples/Pixel: 3
  Rows/Strip: 55
  Planar Configuration: single image plane

Basically the program goes through and treats each section or "block" between each "TYPE:" sections.  So, everytime the program sees "TYPE:", it treats it as a new "set", and performs the code seen in the perl code.

If you look at the comments, there is some information for error checking.  My problem is the fact that when the program starts out with all needed information, but then the second block has missing information, then it doesn't work.  For example, take this data.txt sample (different from above; filename2.tif is missing Sample/Pixel.):

TYPE:
C:\Users\ddecker\Desktop\Dad\tiffs\filename.tif:
TIFF Directory at offset 0x10eb4
  Image Width: 1728 Image Length: 2376
  Resolution: 200, 200 pixels/inch
  Bits/Sample: 1
  Compression Scheme: CCITT Group 4
  Photometric Interpretation: min-is-white
  FillOrder: lsb-to-msb
  Document Name: "Standard Input"
  Image Description: "converted PBM file"
  Orientation: row 0 top, col 0 lhs
  Samples/Pixel: 1
  Rows/Strip: 2376
  Planar Configuration: single image plane
TYPE:
C:\Users\ddecker\Desktop\Dad\tiffs\filename2.tif:
TIFF Directory at offset 0x4aac
  Image Width: 1728 Image Length: 2376
  Resolution: 200, 200 pixels/inch
  Bits/Sample: 1
  Compression Scheme: CCITT Group 4
  Photometric Interpretation: min-is-white
  FillOrder: lsb-to-msb
  Document Name: "Standard Input"
  Image Description: "converted PBM file"
  Orientation: row 0 top, col 0 lhs
  Rows/Strip: 2376
  Planar Configuration: single image plane
TYPE:
C:\Users\ddecker\Desktop\Dad\tiffs\filename3.tif:
TIFF Directory at offset 0x8
  Subfile Type: (0 = 0x0)
  Image Width: 124 Image Length: 124
  Resolution: 31, 31 pixels/inch
  Bits/Sample: 8
  Compression Scheme: None
  Photometric Interpretation: RGB color
  Software: "¼"
  Samples/Pixel: 3
  Rows/Strip: 55
  Planar Configuration: single image plane

Normal output for the program is the following:

Processing filename.tif
Processing filename2.tif
Processing filename3.tif

However, when missing the data from above it should be:

Processing filename.tif
: Sample/Pixels data for filename2.tif not found.
[INFO]: filename.tif was not processed, too many errors.
Processing filename3.tif
Error log saved.

HOWEVER, it isn't doing this, the output is:

Processing filename.tif
Processing filename2.tif
Processing filename3.tif

Which means, that when it starts out with a good record, and then hits a "bad" or "missing data" record, it thinks it's good data for some reasons, and treats it as good and processes the data.  If I remove EVERYTHING from "TYPE: ... FILENAME ... and TIFF Directory at offset 0x4aac", from a record, THEN it sees the errors.  Makes no sense.  See this example:

TYPE:
C:\Users\ddecker\Desktop\Dad\tiffs\filename.tif:
TIFF Directory at offset 0x10eb4
  Image Width: 1728 Image Length: 2376
  Resolution: 200, 200 pixels/inch
  Bits/Sample: 1
  Compression Scheme: CCITT Group 4
  Photometric Interpretation: min-is-white
  FillOrder: lsb-to-msb
  Document Name: "Standard Input"
  Image Description: "converted PBM file"
  Orientation: row 0 top, col 0 lhs
  Samples/Pixel: 1
  Rows/Strip: 2376
  Planar Configuration: single image plane
TYPE:
C:\Users\ddecker\Desktop\Dad\tiffs\filename2.tif:
TIFF Directory at offset 0x4aac
TYPE:
C:\Users\ddecker\Desktop\Dad\tiffs\filename3.tif:
TIFF Directory at offset 0x8
  Subfile Type: (0 = 0x0)
  Image Width: 124 Image Length: 124
  Resolution: 31, 31 pixels/inch
  Bits/Sample: 8
  Compression Scheme: None
  Photometric Interpretation: RGB color
  Software: "¼"
  Samples/Pixel: 3
  Rows/Strip: 55
  Planar Configuration: single image plane

The output is as follows:

Processing filename.tif
: Width for filename2.tif not found.
: Length for filename2.tif not found.
: Resolution for filename2.tif not found.
[INFO]: filename2.tif was not processed, too many errors.
Processing filename3.tif
Error log saved.

So, basically, when NO data is present for a record, it works, but when 1 or more values (but not ALL) are missing for a record that is needed for output, it treats it as no errors.

Can anyone shed some light on this.
$infile = 'data.txt';
#$infile = $batOutput;

## Output File Handles (open)
open(OUT1,"> \!".$state.$status."INFO.txt") or die "Can't open \!".$state.$status."INFO.txt: $!"; 
open(OUT2,"> \!".$state.$status."INFOspdsht.txt") or die "Can't open \!".$state.$status."INFO.txt $!";
open(ERRLOG,"> \!errors.log") or die "Can't open !errors.log $!";

## Print Headers To spdsht file
print OUT2 ";;;;Whitespace;;DPI ReSize;;;\n";
print OUT2 "Filename;Comp;AlphCnl;Foto;Wid;Len;Res 0;x0;;;MB\n";

## Configuration Data for masking data output
my %config = (
    'LZW'                               => 'colors',
    'Lempel-Ziv & Welch encoding'       => 'colors',
    'CCITT Group 4'                     => 'bkwhts',
    'CCITT Group 4 facsimile encoding'  => 'bkwhts',
    'None'                              => 'none',
    'none'								=> 'none',
    'RGB color'                         => 'colors',
    'min-is-white'                      => 'bkwhts',
    'min-is-black'                      => 'bkwhts',
    'palette color (RGB from colormap)' => 'colors',
    'Resolution'                        => sub {
                                            my @r = split(/, /, shift);
                                            $r[0] =~ s/\D//g;
                                            $r[1] =~ s/\D//g;
                                            return @r[0,1];
    },
);

my @config = keys %config;

my $file = $infile; # set this as needed.

open my $fh, '<', $file or die "can't open <$file> for reading $!";

$/ = "TYPE:\n";
while ( my $record = <$fh> ) {
    chomp $record;
    next if $record eq '';
    $record =~ s/(TIFF Directory at offset .+)\n//;
	
	## Future use, for incrementing errors
	$errorCount = 0;

    my ($fullpath, $data) = split(/\n/, $record, 2);
    $fullpath =~ s/:$//;

    my ($drv, $path, $file) = File::Spec->splitpath($fullpath);

	## Get Compression Scheme data
	$cs = $config{$1} if ($data =~ s/\s{2}Compression Scheme:\s+(.*?)\n//);
	if (!defined $cs) {
		print "[ERROR]: Compression Scheme for $file not found.\n";
		print ERRLOG "[ERROR]: Compression Scheme for $file not found.\n";
		$errorCount++;
		#next;
	}	
 	
 	## Get Photometric Interpretation data
 	$pi = $config{$1} if ($data =~ s/\s{2}Photometric Interpretation:\s+(.*?)\n//);
    if (!defined $pi) {
    	print "[ERROR]: Photometric Interpretation for $file not found.\n";
    	print ERRLOG "[ERROR]: Photometric Interpretation for $file not found.\n";
    	$errorCount++;
    	#next;
    }
    
    ## Get Bits/Sample data
    $bits = $1 if ($data =~ s/\s{2}Bits\/Sample:\s+(.*?)\n//);
    if (!defined $bits) {
    	print "[ERROR]: Bits/Sample data for $file not found.\n";
    	print ERRLOG "[ERROR]: Bits/Sample data for $file not found.\n";
    	$errorCount++;
    	#next;
    }
    
    ## Get Samples/Pixel data
    $pixels = $1 if ($data =~ s/\s{2}Samples\/Pixel:\s+(.*?)\n//);
    if (!defined $pixels) {
    	print "[ERROR]: Samples/Pixel data for $file not found.\n";
    	print ERRLOG "[ERROR]: Samples/Pixel data for $file not found.\n";
    	$errorCount++;
    	#next;
    }
    
    ## Get AlphaChnl Value (bits * pixels)
    $alphachnl = $bits * $pixels;
    if ($alphachnl == 1) {
    	$alphachnl = "bkwhts";
    }
    elsif ($alphachnl == 8) {
    	$alphachnl = "colors";
    }
    elsif ($alphachnl == 24) {
    	$alphachnl = "doLOGO";
    }
    else {
    	$alphachnl = "unknwn";
    }
    
    ## Get Resolution data
    my @r = $config{'Resolution'}->($1) if ($data =~ s/\s{2}Resolution:\s+(.*?)\n//);
    
    ## Get Width/Length data
    my ($w, $l) = ($1, $2) if ($data =~ s/\s{2}Image Width: (\d+) Image Length: (\d+)\n//);
    
    ## Width
	if (!defined $w) {
		print "[ERROR]: Width for $file not found.\n";
		print ERRLOG "[ERROR]: Width for $file not found.\n";
		$errorCount++;
		#next;
	}

    ## Length
	if (!defined $l) {
		print "[ERROR]: Length for $file not found.\n";
		print ERRLOG "[ERROR]: Length for $file not found.\n";
		$errorCount++;
		#next;
	}
	
	## Resolution
	if (!defined $r[0] || !defined $r[1]) {
		print "[ERROR]: Resolution for $file not found.\n";
		print ERRLOG "[ERROR]: Resolution for $file not found.\n";
		$errorCount++;
		#next;
	}	
		
	## Get Size of TIF(F) file(s)
	my $filesize = (-s $fullpath) / (1024 * 1024);
    my $size_in_mb = sprintf "%.2f", $filesize;
    
    ## Error Check
    if ($errorCount > 0) {
    	print "[INFO]: $file was not processed, too many errors.\n";
    	next;
    }
    
    $data =~ s/\n$//;

	## ** For Debugging - Prints To Screen **
    ## print $/, join(':', $file, $cs, $bits, $pi, $w, $l, @r, $size_in_mb, "\n"), $data, "\n";
    print "Processing $file\n";

    print OUT1 $/, join(';', $file, $cs, $bits, $pixels, $pi, $w, $l, @r, $size_in_mb, "\n"), $data, "\n";
    
    ## LA Output
    if ($state eq "LA") {
    	print OUT2 "$file;", "$cs;", "$alphachnl;", "$pi;", "$w;", "$l;", "$r[0];$r[1];;;", "$size_in_mb;;","\'$batch;;;;","start;","$file;;;;;;;;;;","$size_in_mb;","move;","$file;","$dir_root\\done;", "\n";	
    }
    ## NM Output
    elsif ($state eq "NM") {
    	print OUT2 "$file;", "$cs;", "$alphachnl;", "$pi;", "$w;", "$l;", "$r[0];$r[1];;;", "$size_in_mb;;","\'$batch;;;;","start;","$file;","$size_in_mb;","move;","$file;","$dir_root\\done;", "\n";
    	next;
    }
    ## OK/UT Output
    elsif ($state eq "OK" || $state eq "UT") {
    	print OUT2 "$file;", "$cs;", "$alphachnl;", "$pi;", "$w;", "$l;", "$r[0];$r[1];;;", "$size_in_mb;;","\'$batch;;;;","start;","$file;","$size_in_mb;","move;","$file;","$dir_root\\done;","start;",$file."f;","move;",$file."f;","$dir_root\\done\\TEMPdone;", "\n";
    	next;
    }
    ## TX/WY Output
    elsif ($state eq "TX" || $state eq "WY") {
    	print OUT2 "$file;", "$cs;", "$alphachnl;", "$pi;", "$w;", "$l;", "$r[0];$r[1];", "move $dir_root\\$file $dir_root\\$cs\\$file;;", "$size_in_mb;;", "\'$batch;;;","start;", "$dir_root\\$cs\\$file;", "$file;","$size_in_mb;","move;", "$dir_root\\$cs\\$file;", "$dir_root\\done;","start;", $file."f;", "move;", $file."f;", "$dir_root\\done\\TEMPdone;", "\n";
    	next;
    }
    elsif ($state eq "NONE" || $state eq "--" || $state eq "OTHER") {
    	print OUT2 "$file;", "$cs;", "$alphachnl;", "$pi;", "$w;", "$l;", "$r[0];$r[1];", "$size_in_mb\n";
    	next;
    }
}

close (OUT1) or die "Can't close out1: $!"; 
close (OUT2) or die "Can't close out2: $!"; 
close (ERRLOG) or die "Can't close error log: $!";
close ($fh) or die "Can't close $fh: $!";

Open in new window

Comment
Watch Question

The problem is that your item variables ($cs, $pi, $bits, etc) are global (because they are not defined as my or local within the loop).  This means that they all still have the value from the previous run(s) after the first one.

I would strongly suggest adding "use strict" and "use warnings" and then fixing any issues that come up.  Everything should work properly after that.
ozo
Most Valuable Expert 2014
Top Expert 2015

Commented:
do you want to undef $cs, $pi, $bits, etc. at the beginning of every record?