Skip Menu |

This queue is for tickets about the Imager CPAN distribution.

Report information
The Basics
Id: 197
Status: resolved
Priority: 0/
Queue: Imager

People
Owner: Nobody in particular
Requestors: addi [...] umich.edu
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.39
Fixed in: (no value)



Subject: Imager leaks memory somehow
Imager runs out of memory over time. Might be a GC problem or related to freetype.
#!perl -w # Requires: # - perl module Imager version 0.39 # http://www.eecs.umich.edu/~addi/perl/Imager/ # - the C library FreeType 2.0.5 # http://www.freetype.org # - Perl version 5 or superior # David Cerezo Sánchez (2002) use Imager qw(:all); use DBI; # Dictionary file $wordfile = 'words.spanish'; # Minimun length of a word $min_length = 5; # Maximun length of a word $max_length = 10; # Maximun number of generated graphic files $max_graphics = 500; # Array of randomly selected words from $file @words = (); # List of the chars that will be used to generate random strings @chars = ("A" .. "Z", "a" .. "z", 0 .. 9); @chars2 = ("a" .. "f"); # Maximun width $maxWidth = 240; # Maximun height $maxHeight = 60; # Font type file $fontType = "\.ttf"; # Dir file where fonts are to be found $fontDir = "./fonts/"; # Background color $bgColor = Imager::Color->new("#CCCCCC"); # Filters my %filters = ( a=>{type => 'mosaic', size => 3}, b=>{type => 'gaussian', stddev => 1.5}, c=>{type => 'noise', amount => 30, subtype => 1}, d=>{type => 'noise', amount => 30}, e=>{type => 'unsharpmask'}, f=>{}, ); if (!(i_has_format("ft2"))) { print("No FreeType2 library\n"); exit(0); } if (!(i_has_format("jpeg"))) { printf("No JPEG support\n"); exit(0); } # Preloading Fonts i_init_fonts(); @fonts = (); $i = 0; opendir (DIRHNDL, $fontDir) or die "Please, install fonts in the fonts/ directory: $!"; @flist = readdir(DIRHNDL); closedir(DIRHNDL); foreach(@flist) { next if ($_ eq "." || $_ eq ".."); if (/$fontType/io) { $fontnames[$i] = "$fontDir$_"; $i++; } } # Initialize the font kernel i_init_fonts(); # Preloading Fonts @fonts = (); $i = 0; foreach (@fontnames) { $fonts[$i] = Imager::Font->new (file => $_, aa => 1); $fonts[$i] or errorLoadingFont(); $i++; } $i = 0; # Loading colors @colors = (); $colors[0] = Imager::Color->new("#FF0000"); $colors[1] = Imager::Color->new("#00FF00"); $colors[2] = Imager::Color->new("#0000FF"); flush STDOUT; print "Selecting words\n"; %hashInserted = (); open (FILE, "< $wordfile") or die "Cannot open $wordfile: $!"; $numLines += tr/\n/\n/ while sysread(FILE, $_, 2 ** 16); close (FILE); open (FILE, "< $wordfile") or die "Cannot open $wordfile: $!"; open (INDEX, "+> $wordfile.idx") or die "Can't open $wordfile.idx: $!"; buildIndex(*FILE, *INDEX) if -z "$wordfile.idx"; while ($i < $max_graphics) { srand; $random = int(rand($numLines)) + 1; $line = lineIndex(*FILE, *INDEX, $random); if ( (length($line)) > $min_length && (length($line)-1) <= $max_length && ! $hashInserted{$line}) { $hashInserted{$line} = 1; push(@words, trim($line)); $i++; } } close (FILE); close (INDEX); $i = 0; while ($i < $max_graphics) { generate(); } sub generate { while ($i < $max_graphics) { $img = Imager->new(xsize => $maxWidth, ysize => $maxHeight, channels => 3); $filename = join("", @chars[ map { rand @chars } (1..32) ]); srand; $currentSize = 70; $currentFont = $fonts[ rand @fonts ]; $currentColor = $colors[ rand @colors ]; $currentX = 0; @bbox = $currentFont->bounding_box(string => $words[$i], size => $currentSize, canon => 1); while ($bbox[2] > $maxWidth || $bbox[3] > $maxHeight) { $currentSize -= 1; @bbox = $currentFont->bounding_box(string => $words[$i], size => $currentSize, canon => 1); } if ($bbox[2] < ($maxWidth-10)) { $currentX = int (($maxWidth-$bbox[2])/2); } print "$i: $words[$i] => size: $currentSize \n"; $img->box(color=>$bgColor, xmin=>0, ymin=>0, xmax=>$maxWidth, ymax=>$maxHeight, filled=>1); $img->string(font => $currentFont, text => $words[$i], x => $currentX, y => 50, size => $currentSize, color => $currentColor, aa => 1); $img->filter(%{$filters{join("", @chars2[map {rand @chars2 } (1) ])}}); $img->write(file => "imagout/$filename.gif", type => 'gif') || print "failed: ",$img->{ERRSTR},"\n"; $img = ""; $i++; if (($i % 10) eq 0) { print "$i\n"; return; } } } sub buildIndex { my $dataFile = shift; my $indexFile = shift; my $offset = 0; while (<$dataFile>) { print $indexFile pack("N", $offset); $offset = tell($dataFile); } } sub lineIndex { my $dataFile = shift; my $indexFile = shift; my $lineNumber = shift; my $size; my $iOffset; my $entry; my $dOffset; $size = length(pack("N", 0)); $iOffset = $size * ($lineNumber - 1); seek($indexFile, $iOffset, 0) or return; read($indexFile, $entry, $size); $dOffset = unpack("N", $entry); seek($dataFile, $dOffset, 0); return scalar(<$dataFile>); } sub trim($) { $_ = shift; s/^\s*//; s/\s*$//; return $_; } sub errorLoadingFont() { print Imager::_error_as_msg(),"\n"; $i--; }
This bug was fixed in 0.40. The font cache was not properly freeing all resources.