#!/usr/bin/perl -w use strict; use OpenGL(':all'); # Images used for testing my $src_image = 'test.png'; my $dst_image = 'test.jpg'; my $tga_image = 'test.tga'; my $width = 128; my $height = 128; my $deviation = 0.15; # Init tests my $t = new MyTests(26,'Testing OpenGL::Image'); # Get OpenGL version my $pogl_ver = $OpenGL::VERSION; my $has_pogl5503 = $pogl_ver ge '0.5503'; $t->status("Using OpenGL v$pogl_ver"); $t->status("Recommend OpenGL 0.55_03 or newer to use") if (!$has_pogl5503); #1 Get module version my $ogi_ver; my $exec = qq { use OpenGL\::Image; \$ogi_ver = \$OpenGL::Image::VERSION; }; eval($exec); $t->bail("OpenGL::Image failed to load: $@") if ($@ || !$ogi_ver); $t->ok("OpenGL::Image module loaded: v$ogi_ver"); #2 Get ImageMagick version my $im_ver = 0; $exec = qq { use Image\::Magick; \$im_ver = \$Image::Magick::VERSION; }; eval($exec); if ($@ || !$im_ver) { $t->skip("Image::Magick module not installed: $@") } elsif ($im_ver lt '6.3.5' ) { $t->skip("Image::Magick module installed: v$im_ver - recommend 6.3.5 or newer"); } else { $t->ok("Image::Magick module installed: v$im_ver"); } #3 Enumerate installed engines $t->status("Testing OpenGL::Image::GetEngines():"); my $engines = OpenGL::Image::GetEngines(); my @engines = keys(%$engines); $t->bail("No imaging engines installed!") if (!@engines); my $has_TGA = 0; my $has_IM = 0; my $has_IM635 = 0; foreach my $engine (sort @engines) { $t->status(" $engine: ".$engines->{$engine}->{version}); if ($engine eq 'Targa') { $has_TGA = 1; } elsif ($engine eq 'Magick') { $has_IM = 1; $has_IM635 = $engines->{'Magick'}->{version} ge '6.3.5'; } } $t->status('Targa is ' . ($has_TGA ? '' : 'NOT ') . "installed"); $t->status('Magick is ' . ($has_IM ? '' : 'NOT ') . "installed"); $t->ok("At least one imaging engine is installed"); #4 Test HasEngine() my $engine_ver = OpenGL::Image::HasEngine($engines[0])->{version}; $t->bail("HasEngine('$engines[0]') failed to return a version") if (!$engine_ver); $t->ok("HasEngine('$engines[0]') returned '$engine_ver'"); #5 Test OpenGL::Array my $oga = OpenGL::Array->new_list(OpenGL::GL_UNSIGNED_BYTE,1,2,3,4); $t->bail("Unable to instantiate OpenGL::Array") if (!$oga); $t->bail("OpenGL::Array returned invalid element count") if (4 != $oga->elements()); $t->ok("Instantiated OpenGL::Array"); #6 Test image object instantiation my $tga = new OpenGL::Image(width=>$width,height=>$height); $t->bail("Unable to instantiate OpenGL::Image") if (!$tga); $t->ok("Instantiated OpenGL::Image(width\=>$width,height\=>$height)"); #7 Test Get/Set Pixel $tga->SetPixel(0,0, 0.1, 0.2, 0.3, 0.4); my($v0,$v1,$v2,$v3) = $tga->GetPixel(0,0); # Normalized values introduce rounding errors my $dev = (abs($v0 - 0.1) + abs($v1 - 0.2) + abs($v2 - 0.3) + abs($v3 - 0.4)) / 4; #$t->status("Get/SetPixel deviation: $dev"); if ($dev > $deviation) { $t->bail("GetPixel failed to return values used with SetPixel"); } $t->ok("GetPixel returns valid values used with SetPixel"); # set up test pixels my @pixels = (); my $x0 = 1.0 / $width; my $y0 = 1.0 / $height; my $r = 1.0; my $g = 0.0; for (my $y=0; $y<$height; $y++) { $b = 1.0; $a = 0.0; for (my $x=0; $x<$width; $x++) { push(@pixels,[$x,$y, $r,$g,$b,$a]); $b -= $x0; $a += $x0; } $r -= $y0; $g += $y0; } foreach my $pixel (@pixels) { $tga->SetPixel(@$pixel); } #8 Test image saving $tga->Save($tga_image); $t->bail("Save('$tga_image') failed to create $tga_image") if (!-e $tga_image); $t->ok("Save('$tga_image') created image"); #9 Test image loading my $sav = new OpenGL::Image(source=>$tga_image); $t->bail("Unable to instantiate OpenGL::Image") if (!$sav); $t->ok("Instantiated OpenGL::Image(source=>'$tga_image')"); unlink($tga_image); #10 Test image parameters my $params = $sav->Get(); $t->fail("Get() failed to return a parameter hashref") if (!$params); my @params = keys(%$params); $t->fail("Get() failed to return parameters") if (!scalar(@params)); $t->status("Testing object parameters:"); foreach my $key (sort @params) { $t->status(" $key: ".$params->{$key}); } $t->ok("Get() returned parameters"); #11 Test image size my($w,$h,$p,$c,$s) = $sav->Get('width','height','pixels','components','size'); if ($w != $width || $h != $height) { $t->fail("Get('width','height') returned invalid dimensions: $w x $h"); } elsif($p != $w * $h) { $t->fail("Get('pixels') failed to return $w x $h: $p"); } else { $t->ok("Get('width','height','pixels') returned: $w x $h = $p"); } #12 Test pixel deviation my $d = 0; my $i = 0; for (my $y=0; $y<$height; $y++) { for (my $x=0; $x<$width; $x++) { my($r,$g,$b,$a) = $sav->GetPixel($x,$y); my $pixel = $pixels[$i++]; $d += abs($r - (@$pixel)[2]); $d += abs($g - (@$pixel)[3]); $d += abs($b - (@$pixel)[4]); $d += abs($a - (@$pixel)[5]); } } $d /= ($i * 4); if ($d > $deviation) { $t->fail("Set/Get Pixels deviation out of range: $d") } elsif ($d) { $t->ok("Set/Get Pixels within acceptable deviation: $d"); } else { $t->ok("Set/Get Pixels resulted in no deviation"); } #13 Test IsPowerOf2() if (!$sav->IsPowerOf2(256)) { $t->fail("IsPowerOf2(256) returned false"); } elsif ($sav->IsPowerOf2(13)) { $t->fail("IsPowerOf2(13) returned true"); } elsif (!$sav->IsPowerOf2()) { $t->fail("IsPowerOf2() returned false"); } else { $t->ok("IsPowerOf2() returned true"); } #14 Test GetArray() $oga = $sav->GetArray(); $t->bail("GetArray() failed to return an OpenGL::Array object") if (!$oga); my $elements = $oga->elements(); if ($elements != $p * $c) { $t->bail("GetArray() contains invalid number of elements: $elements"); } $t->ok("GetArray() contains $elements elements"); #15 Test Ptr() if ($oga->ptr() && $oga->ptr() != $sav->Ptr()) { $t->bail("Ptr() returned invalid pointer: ".$oga->ptr().', '.$sav->Ptr()."\n"); } $t->ok("Ptr() returned a valid pointer"); #16 Test GetBlob() my $blob = $sav->GetBlob(); $t->bail("GetBlob() failed to return blob\n") if (!$blob); my $blob_len = length($blob); if ('Targa' eq $sav->Get('engine')) { if ($blob_len != $p * $c * $s) { $t->bail("GetBlob() returned invalid blob length: $blob_len\n"); } } $t->ok("GetBlob() returned a blob of length: $blob_len"); # Skip the rest if no Magick engine or test image my $has_image = -e $src_image; if (!$has_IM || !$has_image) { my $msg = $has_IM ? "Test image '$src_image' not found" : 'No ImageMagick'; $t->done($msg); exit 0; } #17 Test Loading source image my $src = new OpenGL::Image(engine=>'Magick',source=>$src_image); $t->bail("Unable to instantiate OpenGL::Image(engine=>'Magick',source=>'$src_image')") if (!$src); $t->ok("Instantiated OpenGL::Image(engine=>'Magick',source=>'$src_image')"); #18 Test source image size my($ws,$hs,$ps,$cs,$ss) = $src->Get('width','height','pixels','components','size'); if ($ws != $width || $hs != $height) { $t->fail("Get('width','height') returned invalid dimensions: $ws x $hs"); } elsif($ps != $ws * $hs) { $t->fail("Get('pixels') failed to return $ws x $hs: $ps"); } else { $t->ok("Get('width','height','pixels') returned: $ws x $hs = $ps"); } #19 Test Save() $src->Save($dst_image); $t->bail("Save('$dst_image') failed to create file") if (!-e $dst_image); $t->ok("Save('$dst_image') created image"); #20 Test Loading destination image my $dst = new OpenGL::Image(engine=>'Magick',source=>$dst_image); $t->bail("Unable to instantiate OpenGL::Image(engine=>'Magick',source=>'$dst_image')") if (!$dst); $t->ok("Instantiated OpenGL::Image(engine=>'Magick',source=>'$dst_image')"); unlink($dst_image); #21 Test destination image size my($wd,$hd,$pd,$cd,$sd) = $dst->Get('width','height','pixels','components','size'); if ($wd != $ws || $hd != $hs) { $t->fail("Get('width','height') returned invalid dimensions: $wd x $hd"); } elsif($pd != $wd * $hd) { $t->fail("Get('pixels') failed to return $wd x $hd: $pd"); } else { $t->ok("Get('width','height','pixels') returned: $wd x $hd = $pd"); } #22 Test RGB deviation $d = 0; for (my $y=0; $y<$height; $y++) { for (my $x=0; $x<$width; $x++) { my($rs,$gs,$bs,$as) = $src->GetPixel($x,$y); my($rd,$gd,$bd,$ad) = $dst->GetPixel($x,$y); $d += abs($rs-$rd) + abs($gs-$gd) + abs($bs-$bd); } } $d /= ($ps * 3); if ($d > $deviation) { $t->fail("Set/Get Pixels deviation out of range: $d") } elsif ($d) { $t->ok("Set/Get Pixels within acceptable deviation: $d"); } else { $t->ok("Set/Get Pixels resulted in no deviation"); } #23 Test Native() $t->bail("Native() returned invalid PerlMagick object") if (!$src->Native()); my($x,$y) = $src->Native->Get('width','height'); if ($x != $w || $y != $h) { $t->bail("Native->Get('width','height') returned invalid dimensions"); } $t->ok("Native->Get('width','height') returned: $x x $y"); #24 Test GetBlob() $blob = $src->GetBlob(magick=>'jpg'); $t->bail("GetBlob(type=>'jpg') failed to return a blob") if (!$blob); my $im = Image::Magick->new(magick=>'jpg'); $im->BlobToImage($blob); my($w0,$h0) = $im->Get('width','height'); if (!$w0 || !$h0) { $t->bail("GetBlob(type=>'jpg') failed"); } elsif ($w != $w0 || $h != $h0) { $t->bail("GetBlob(type=>'jpg') returns invalid dimensions: $w0 x $h0"); } $t->ok("GetBlob(type=>'jpg') returned a blob of length: ".length($blob)); #25 Test GetArray() $oga = $src->GetArray(); $t->bail("GetArray() failed to return an OpenGL::Array object") if (!$oga); $elements = $oga->elements(); if ($elements != $p * $c) { $t->bail("GetArray() contains invalid number of elements: $elements"); } $t->ok("GetArray() contains $elements elements"); #26 Test Ptr() if ($oga->ptr() && $oga->ptr() != $src->Ptr()) { $t->bail("Ptr() returned invalid pointer: ".$oga->ptr().', '.$src->Ptr()."\n"); } $t->ok("Ptr() returned a valid pointer"); $t->done(); exit 0; package MyTests; sub new { my $this = shift; my $class = ref($this) || $this; my $self = {count=>0}; bless($self,$class); my($tests,$title) = @_; $self->{tests} = $tests; print "1..$tests\n"; $self->status("\n________________________________________"); $self->status($title); $self->status("----------------------------------------"); return $self; } sub status { my($self,$msg) = @_; print STDERR "$msg\n"; } sub ok { my($self,$msg) = @_; $self->status("* ok: $msg"); print 'ok '.++$self->{count}."\n"; } sub skip { my($self,$msg) = @_; $self->status("* skip: $msg"); print 'ok '.++$self->{count}." \# skip $msg\n"; } sub fail { my($self,$msg) = @_; $self->status("* fail: $msg"); print 'not ok '.++$self->{count}."\n"; } sub bail { my($self,$msg) = @_; $self->status("* bail: $msg\n"); print "Bail out!\n"; exit 0; } sub done { my($self,$msg) = @_; for (my $c=$self->{count}; $self->{count} < $self->{tests}; $c++) { $self->skip('#'.($c+1)." - $msg"); } $self->status("________________________________________"); } __END__