You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1258 lines
33 KiB
1258 lines
33 KiB
# Copyright 1999-2021 ImageMagick Studio LLC, a non-profit organization
|
|
# dedicated to making software imaging solutions freely available.
|
|
#
|
|
# You may not use this file except in compliance with the License. You may
|
|
# obtain a copy of the License at
|
|
#
|
|
# https://imagemagick.org/script/license.php
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
#
|
|
#
|
|
# Common subroutines to support tests
|
|
#
|
|
# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
|
|
#
|
|
|
|
#
|
|
# Test composite method using comparison with a reference image
|
|
#
|
|
# Usage: testFilterCompare( background image name, background read options,
|
|
# composite image name, composite read options,
|
|
# composite options,reference image
|
|
# normalized_mean_error,
|
|
# normalized_maximum_error );
|
|
sub testCompositeCompare {
|
|
my ($background_name,
|
|
$background_read_options,
|
|
$composite_name,
|
|
$composite_read_options,
|
|
$composite_options,
|
|
$refimage_name,
|
|
$normalized_mean_error_max,
|
|
$normalized_maximum_error_max) = @_;
|
|
my ($background,
|
|
$composite,
|
|
$errorinfo,
|
|
$normalized_maximum_error,
|
|
$normalized_mean_error,
|
|
$refimage,
|
|
$status);
|
|
|
|
$errorinfo='';
|
|
$status='';
|
|
$normalized_mean_error_max+=1.0e-12;
|
|
$normalized_maximum_error_max+=1.0e-12;
|
|
|
|
#print( $filter, " ...\n" );
|
|
|
|
# Create images
|
|
$background=Image::Magick->new;
|
|
$composite=Image::Magick->new;
|
|
$refimage=Image::Magick->new;
|
|
|
|
# Read background image
|
|
if ( "$background_read_options" ne "" ) {
|
|
print("Set($background_read_options) ...\n");
|
|
eval "\$status=\$background->Set($background_read_options);";
|
|
if ("$status")
|
|
{
|
|
$errorinfo = "Set($background_read_options): $status";
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
}
|
|
$status=$background->ReadImage($background_name);
|
|
if ("$status")
|
|
{
|
|
$errorinfo = "Readimage ($background_name): $status";
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
|
|
# Read composite image
|
|
if ( "$composite_read_options" ne "" ) {
|
|
print("Set($composite_read_options) ...\n");
|
|
eval "\$status=\$composite->Set($composite_read_options);";
|
|
if ("$status")
|
|
{
|
|
$errorinfo = "Set($composite_read_options): $status";
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
}
|
|
$status=$composite->ReadImage($composite_name);
|
|
if ("$status")
|
|
{
|
|
$errorinfo = "Readimage ($composite_name): $status";
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
|
|
# Do composition
|
|
print("Composite\($composite_options\) ...\n");
|
|
eval "\$status=\$background->Composite(image=>\$composite, $composite_options);";
|
|
if ("$status")
|
|
{
|
|
$errorinfo = "Composite ($composite_options): $status";
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
|
|
$background->Clamp();
|
|
$background->set(depth=>8);
|
|
# if ("$filter" eq "Atop") {
|
|
# $background->write(filename=>"$refimage_name", compression=>'None');
|
|
# $background->Display();
|
|
# }
|
|
|
|
$status=$refimage->ReadImage("$refimage_name");
|
|
if ("$status")
|
|
{
|
|
$errorinfo = "Readimage ($refimage_name): $status";
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
|
|
$status=$background->Difference($refimage);
|
|
if ("$status")
|
|
{
|
|
$errorinfo = "Difference($refimage_name): $status";
|
|
print(" Reference: ", $refimage->Get('columns'), "x", $refimage->Get('rows'), "\n");
|
|
print(" Computed: ", $background->Get('columns'), "x", $background->Get('rows'), "\n");
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
|
|
$normalized_mean_error=0;
|
|
$normalized_mean_error=$background->GetAttribute('mean-error');
|
|
if ( !defined($normalized_mean_error) )
|
|
{
|
|
$errorinfo = "GetAttribute('mean-error') returned undefined value!";
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
$normalized_maximum_error=0;
|
|
$normalized_maximum_error=$background->GetAttribute('maximum-error');
|
|
if ( ! defined($normalized_maximum_error) )
|
|
{
|
|
$errorinfo = "GetAttribute('maximum-error') returned undefined value!";
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
if ( ($normalized_mean_error > $normalized_mean_error_max) ||
|
|
($normalized_maximum_error > $normalized_maximum_error_max) )
|
|
{
|
|
print(" mean-error=$normalized_mean_error, maximum-error=$normalized_maximum_error\n");
|
|
print "not ok $test\n";
|
|
$background->Display();
|
|
undef $background;
|
|
undef $composite;
|
|
undef $refimage;
|
|
return 1
|
|
}
|
|
|
|
undef $background;
|
|
undef $composite;
|
|
undef $refimage;
|
|
print "ok $test\n";
|
|
return 0;
|
|
|
|
COMPARE_RUNTIME_ERROR:
|
|
undef $background;
|
|
undef $composite;
|
|
undef $refimage;
|
|
print(" $errorinfo\n");
|
|
print "not ok $test\n";
|
|
return 1
|
|
}
|
|
|
|
#
|
|
# Test reading a 16-bit file in which two signatures are possible,
|
|
# depending on whether 16-bit pixels data has been enabled
|
|
#
|
|
# Usage: testRead( read filename, expected ref_8 [, expected ref_16] [, expected ref_32] );
|
|
#
|
|
sub testRead {
|
|
my( $infile, $ref_8, $ref_16, $ref_32 ) = @_;
|
|
|
|
my($image,$magick,$success,$ref_signature);
|
|
|
|
$failure=0;
|
|
|
|
if ( !defined( $ref_16 ) )
|
|
{
|
|
$ref_16 = $ref_8;
|
|
}
|
|
if ( !defined( $ref_32 ) )
|
|
{
|
|
$ref_32 = $ref_16;
|
|
}
|
|
|
|
if (Image::Magick->new()->QuantumDepth == 32)
|
|
{
|
|
$ref_signature=$ref_32;
|
|
}
|
|
elsif (Image::Magick->new()->QuantumDepth == 16)
|
|
{
|
|
$ref_signature=$ref_16;
|
|
}
|
|
else
|
|
{
|
|
$ref_signature=$ref_8;
|
|
}
|
|
|
|
$magick='';
|
|
|
|
#
|
|
# Test reading from file
|
|
#
|
|
{
|
|
my($image, $signature, $status);
|
|
|
|
print( " testing reading from file \"", $infile, "\" ...\n");
|
|
$image=Image::Magick->new;
|
|
$image->Set(size=>'512x512');
|
|
$status=$image->ReadImage("$infile");
|
|
if( "$status" && !($status =~ /Exception ((315)|(350))/)) {
|
|
print "ReadImage $infile: $status\n";
|
|
++$failure;
|
|
} else {
|
|
if( "$status" ) {
|
|
print "ReadImage $infile: $status\n";
|
|
}
|
|
undef $status;
|
|
$magick=$image->Get('magick');
|
|
$signature=$image->Get('signature');
|
|
|
|
if ( $signature ne $ref_signature ) {
|
|
print "ReadImage()\n";
|
|
print "Image: $infile, signatures do not match.\n";
|
|
print " Expected: $ref_signature\n";
|
|
print " Computed: $signature\n";
|
|
print " Depth: ", Image::Magick->new()->QuantumDepth, "\n";
|
|
++$failure;
|
|
$image->Display();
|
|
}
|
|
}
|
|
undef $image;
|
|
}
|
|
|
|
#
|
|
# Test reading from blob
|
|
#
|
|
if (!($infile =~ /\.bz2$/) && !($infile =~ /\.gz$/) && !($infile =~ /\.Z$/))
|
|
{
|
|
my(@blob, $blob_length, $image, $signature, $status);
|
|
|
|
if( open( FILE, "< $infile"))
|
|
{
|
|
print( " testing reading from BLOB with magick \"", $magick, "\"...\n");
|
|
binmode( FILE );
|
|
$blob_length = read( FILE, $blob, 10000000 );
|
|
close( FILE );
|
|
if( defined( $blob ) ) {
|
|
$image=Image::Magick->new(magick=>$magick);
|
|
$status=$image->BlobToImage( $blob );
|
|
undef $blob;
|
|
if( "$status" && !($status =~ /Exception ((315)|(350))/)) {
|
|
print "BlobToImage $infile: $status\n";
|
|
++$failure;
|
|
} else {
|
|
if( "$status" ) {
|
|
print "ReadImage $infile: $status\n";
|
|
}
|
|
$signature=$image->Get('signature');
|
|
if ( $signature ne $ref_signature ) {
|
|
print "BlobToImage()\n";
|
|
print "Image: $infile, signatures do not match.\n";
|
|
print " Expected: $ref_signature\n";
|
|
print " Computed: $signature\n";
|
|
print " Depth: ", Image::Magick->new()->QuantumDepth, "\n";
|
|
#$image->Display();
|
|
++$failure;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
undef $image;
|
|
}
|
|
|
|
#
|
|
# Display test status
|
|
#
|
|
if ( $failure != 0 ) {
|
|
print "not ok $test\n";
|
|
} else {
|
|
print "ok $test\n";
|
|
}
|
|
}
|
|
|
|
|
|
#
|
|
# Test reading a file, and compare with a reference file
|
|
#
|
|
sub testReadCompare {
|
|
my( $srcimage_name,$refimage_name, $read_options,
|
|
$normalized_mean_error_max, $normalized_maximum_error_max) = @_;
|
|
my($srcimage, $refimage, $normalized_mean_error, $normalized_maximum_error);
|
|
|
|
$errorinfo='';
|
|
$normalized_mean_error_max+=1.0e-12;
|
|
$normalized_maximum_error_max+=1.0e-12;
|
|
|
|
# Create images
|
|
$srcimage=Image::Magick->new;
|
|
$refimage=Image::Magick->new;
|
|
|
|
if ( "$read_options" ne "" ) {
|
|
eval "\$status=\$srcimage->Set($read_options);";
|
|
if ("$status")
|
|
{
|
|
$errorinfo = "Set($read_options): $status";
|
|
warn("$errorinfo");
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
}
|
|
|
|
$status=$srcimage->ReadImage("$srcimage_name");
|
|
if ("$status")
|
|
{
|
|
$errorinfo = "Readimage ($srcimage_name): $status";
|
|
warn("$errorinfo");
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
|
|
# if ("$srcimage_name" eq "input.tim") {
|
|
# $srcimage->write(filename=>"$refimage_name", compression=>'None');
|
|
# }
|
|
|
|
#print("writing file $refimage_name\n");
|
|
#$srcimage->Quantize(colors=>256);
|
|
#$status=$srcimage->write(filename=>"$refimage_name", compression=>'rle');
|
|
#warn "$status" if $status;
|
|
|
|
$status=$refimage->ReadImage("$refimage_name");
|
|
if ("$status")
|
|
{
|
|
$errorinfo = "Readimage ($refimage_name): $status";
|
|
warn("$errorinfo");
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
|
|
$srcimage->Clamp();
|
|
$srcimage->set(depth=>8);
|
|
|
|
# FIXME: The following statement should not be needed.
|
|
# $status=$refimage->Set(type=>'TrueColor');
|
|
# if ("$status")
|
|
# {
|
|
# $errorinfo = "Set(type=>'TrueColor'): $status";
|
|
# goto COMPARE_RUNTIME_ERROR;
|
|
# }
|
|
|
|
# Verify that $srcimage and $refimage contain the same number of frames.
|
|
if ( $#srcimage != $#refimage )
|
|
{
|
|
$errorinfo = "Source and reference images contain different number of frames ($#srcimage != $#refimage)";
|
|
warn("$errorinfo");
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
|
|
# Compare each frame in the sequence.
|
|
for ($index = 0; $srcimage->[$index] && $refimage->[$index]; $index++)
|
|
{
|
|
$status=$srcimage->[$index]->Difference($refimage->[$index]);
|
|
if ("$status")
|
|
{
|
|
$errorinfo = "Difference($refimage_name)->[$index]: $status";
|
|
warn("$errorinfo");
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
}
|
|
|
|
|
|
$normalized_mean_error=0;
|
|
$normalized_mean_error=$srcimage->GetAttribute('mean-error');
|
|
if ( !defined($normalized_mean_error) )
|
|
{
|
|
$errorinfo = "GetAttribute('mean-error') returned undefined value!";
|
|
warn("$errorinfo");
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
$normalized_maximum_error=0;
|
|
$normalized_maximum_error=$srcimage->GetAttribute('maximum-error');
|
|
if ( ! defined($normalized_maximum_error) )
|
|
{
|
|
$errorinfo = "GetAttribute('maximum-error') returned undefined value!";
|
|
warn("$errorinfo");
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
if ( ($normalized_mean_error > $normalized_mean_error_max) ||
|
|
($normalized_maximum_error > $normalized_maximum_error_max) )
|
|
{
|
|
print("mean-error=$normalized_mean_error, maximum-error=$normalized_maximum_error\n");
|
|
#$srcimage->Display();
|
|
print "not ok $test\n";
|
|
return 1
|
|
}
|
|
|
|
undef $srcimage;
|
|
undef $refimage;
|
|
print "ok $test\n";
|
|
return 0;
|
|
|
|
COMPARE_RUNTIME_ERROR:
|
|
undef $srcimage;
|
|
undef $refimage;
|
|
print "not ok $test\n";
|
|
return 1
|
|
}
|
|
|
|
#
|
|
# Test reading a file which requires a file size to read (GRAY, RGB, CMYK)
|
|
# or supports multiple resolutions (JBIG, JPEG, PCD)
|
|
#
|
|
# Usage: testRead( read filename, size, depth, expected ref_8 [, expected ref_16] [, expected ref_32] );
|
|
#
|
|
sub testReadSized {
|
|
my( $infile, $size, $ref_8, $ref_16, $ref_32 ) = @_;
|
|
|
|
my($image,$ref_signature);
|
|
|
|
if ( !defined( $ref_16 ) )
|
|
{
|
|
$ref_16 = $ref_8;
|
|
}
|
|
if ( !defined( $ref_32 ) )
|
|
{
|
|
$ref_32 = $ref_16;
|
|
}
|
|
|
|
if (Image::Magick->new()->QuantumDepth == 32)
|
|
{
|
|
$ref_signature=$ref_32;
|
|
}
|
|
elsif (Image::Magick->new()->QuantumDepth == 16)
|
|
{
|
|
$ref_signature=$ref_16;
|
|
}
|
|
else
|
|
{
|
|
$ref_signature=$ref_8;
|
|
}
|
|
|
|
$image=Image::Magick->new;
|
|
|
|
# Set size attribute
|
|
$status=$image->SetAttribute(size=>"$size");
|
|
warn "$status" if "$status";
|
|
|
|
# If depth is not zero, then set it
|
|
if ( Image::Magick->new()->QuantumDepth != 0 ) {
|
|
$status=$image->SetAttribute(depth=>Image::Magick->new()->QuantumDepth);
|
|
warn "$status" if "$status";
|
|
}
|
|
|
|
$status=$image->ReadImage("$infile");
|
|
if( "$status" ) {
|
|
print "ReadImage $infile: $status";
|
|
print "not ok $test\n";
|
|
} else {
|
|
$signature=$image->Get('signature');
|
|
if ( $signature ne $ref_signature ) {
|
|
print "ReadImage()\n";
|
|
print "Image: $infile, signatures do not match.\n";
|
|
print " Expected: $ref_signature\n";
|
|
print " Computed: $signature\n";
|
|
print " Depth: ", Image::Magick->new()->QuantumDepth, "\n";
|
|
print "not ok $test\n";
|
|
#$image->Display();
|
|
} else {
|
|
print "ok $test\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
#
|
|
# Test writing a file by first reading a source image, writing to a new image,
|
|
# reading the written image, and comparing with expected REF_8.
|
|
#
|
|
# Usage: testReadWrite( read filename, write filename, write options,
|
|
# expected ref_8 [, expected ref_16] );
|
|
#
|
|
# .e.g
|
|
#
|
|
# testReadWrite( 'input.jpg', 'output.jpg', q/quality=>80, interlace=>'None'/,
|
|
# 'dc0a144a0b9480cd1e93757a30f01ae3' );
|
|
#
|
|
# If the REF_8 of the written image is not what is expected, the written
|
|
# image is preserved. Otherwise, the written image is removed.
|
|
#
|
|
sub testReadWrite {
|
|
my( $infile, $outfile, $writeoptions, $ref_8, $ref_16, $ref_32 ) = @_;
|
|
|
|
my($image);
|
|
|
|
if ( !defined( $ref_16 ) )
|
|
{
|
|
$ref_16 = $ref_8;
|
|
}
|
|
if ( !defined( $ref_32 ) )
|
|
{
|
|
$ref_32 = $ref_16;
|
|
}
|
|
|
|
if (Image::Magick->new()->QuantumDepth == 32)
|
|
{
|
|
$ref_signature=$ref_32;
|
|
}
|
|
elsif (Image::Magick->new()->QuantumDepth == 16)
|
|
{
|
|
$ref_signature=$ref_16;
|
|
}
|
|
else
|
|
{
|
|
$ref_signature=$ref_8;
|
|
}
|
|
|
|
$image=Image::Magick->new;
|
|
$status=$image->ReadImage("$infile");
|
|
$signature=$image->Get('signature');
|
|
if( "$status" ) {
|
|
print "ReadImage $infile: $status\n";
|
|
print "not ok $test\n";
|
|
} else {
|
|
# Write image to file
|
|
my $options = 'filename=>"$outfile", ' . "$writeoptions";
|
|
#print "Using options: $options\n";
|
|
eval "\$status=\$image->WriteImage( $options ) ;";
|
|
if( $@ ) {
|
|
print "$@\n";
|
|
print "not ok $test\n";
|
|
exit 1;
|
|
}
|
|
if( "$status" ) {
|
|
print "WriteImage $outfile: $status\n";
|
|
print "not ok $test\n";
|
|
} else {
|
|
my($image);
|
|
|
|
# Read image just written
|
|
$image=Image::Magick->new;
|
|
$status=$image->ReadImage("$outfile");
|
|
if( "$status" ) {
|
|
print "ReadImage $outfile: $status\n";
|
|
print "not ok $test\n";
|
|
} else {
|
|
# Check signature
|
|
$signature=$image->Get('signature');
|
|
if ( $signature ne $ref_signature ) {
|
|
print "ReadImage()\n";
|
|
print "Image: $infile, signatures do not match.\n";
|
|
print " Expected: $ref_signature\n";
|
|
print " Computed: $signature\n";
|
|
print " Depth: ", Image::Magick->new()->QuantumDepth, "\n";
|
|
print "not ok $test\n";
|
|
$image->Display();
|
|
} else {
|
|
print "ok $test\n";
|
|
($file = $outfile) =~ s/.*://g;
|
|
#unlink "$file";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#
|
|
# Test reading a file, and compare with a reference file
|
|
#
|
|
sub testReadWriteCompare {
|
|
my( $srcimage_name, $outimage_name, $refimage_name,
|
|
$read_options, $write_options,
|
|
$normalized_mean_error_max, $normalized_maximum_error_max) = @_;
|
|
my($srcimage, $refimage, $normalized_mean_error,
|
|
$normalized_maximum_error);
|
|
|
|
$errorinfo='';
|
|
$normalized_mean_error_max+=1.0e-12;
|
|
$normalized_maximum_error_max+=1.0e-12;
|
|
|
|
$image=Image::Magick->new;
|
|
$refimage=Image::Magick->new;
|
|
|
|
#
|
|
# Read the initial image
|
|
#
|
|
$status=$image->ReadImage($srcimage_name);
|
|
if ("$status")
|
|
{
|
|
$errorinfo = "Readimage ($srcimage_name): $status";
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
|
|
#
|
|
# Write image to output file
|
|
#
|
|
if ( "$write_options" ne "" ) {
|
|
eval "\$status=\$image->Set($write_options);";
|
|
if ("$status")
|
|
{
|
|
$errorinfo = "Set($write_options): $status";
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
}
|
|
$image->Set(filename=>"$outimage_name");
|
|
|
|
$status=$image->WriteImage( );
|
|
if ("$status")
|
|
{
|
|
$errorinfo = "WriteImage ($outimage_name): $status";
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
|
|
undef $image;
|
|
$image=Image::Magick->new;
|
|
|
|
#
|
|
# Read image from output file
|
|
#
|
|
if ( "$read_options" ne "" ) {
|
|
eval "\$status=\$image->Set($read_options);";
|
|
if ("$status")
|
|
{
|
|
$errorinfo = "Set($read_options): $status";
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
}
|
|
|
|
$image->ReadImage("$outimage_name");
|
|
if ("$status")
|
|
{
|
|
$errorinfo = "WriteImage ($outimage_name): $status";
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
|
|
# eval "\$status=\$image->Set($write_options);";
|
|
#$status=$image->write(filename=>"$refimage_name", compression=>'None');
|
|
# warn "$status" if $status;
|
|
|
|
#
|
|
# Read reference image
|
|
#
|
|
$status=$refimage->ReadImage("$refimage_name");
|
|
if ("$status")
|
|
{
|
|
$errorinfo = "Readimage ($refimage_name): $status";
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
|
|
#
|
|
# Compare output file with reference image
|
|
#
|
|
|
|
$image->Clamp();
|
|
$image->set(depth=>8);
|
|
|
|
# FIXME: The following statement should not be needed.
|
|
# $status=$refimage->Set(type=>'TrueColor');
|
|
# if ("$status")
|
|
# {
|
|
# $errorinfo = "Set(type=>'TrueColor'): $status";
|
|
# goto COMPARE_RUNTIME_ERROR;
|
|
# }
|
|
|
|
$status=$image->Difference($refimage);
|
|
if ("$status")
|
|
{
|
|
$errorinfo = "Difference($refimage_name): $status";
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
|
|
$normalized_mean_error=0;
|
|
$normalized_mean_error=$image->GetAttribute('mean-error');
|
|
if ( !defined($normalized_mean_error) )
|
|
{
|
|
$errorinfo = "GetAttribute('mean-error') returned undefined value!";
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
$normalized_maximum_error=0;
|
|
$normalized_maximum_error=$image->GetAttribute('maximum-error');
|
|
if ( ! defined($normalized_maximum_error) )
|
|
{
|
|
$errorinfo = "GetAttribute('maximum-error') returned undefined value!";
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
|
|
if ( ($normalized_mean_error > $normalized_mean_error_max) ||
|
|
($normalized_maximum_error > $normalized_maximum_error_max) )
|
|
{
|
|
print("mean-error=$normalized_mean_error, maximum-error=$normalized_maximum_error\n");
|
|
print "not ok $test\n";
|
|
return 1
|
|
}
|
|
|
|
print "ok $test\n";
|
|
undef $image;
|
|
undef $refimage;
|
|
return 0;
|
|
|
|
COMPARE_RUNTIME_ERROR:
|
|
warn("$errorinfo");
|
|
print "not ok $test\n";
|
|
undef $image;
|
|
undef $refimage;
|
|
return 1
|
|
}
|
|
|
|
#
|
|
# Test writing a file by first reading a source image, writing to a
|
|
# new image, and reading the written image. Depends on detecting
|
|
# reported errors by ImageMagick
|
|
#
|
|
# Usage: testReadWrite( read filename, write filename, write options);
|
|
#
|
|
# .e.g
|
|
#
|
|
# testReadWrite( 'input.jpg', 'output.jpg', q/quality=>80, 'interlace'=>'None'/ );
|
|
#
|
|
# If the read of the written image is not what is expected, the
|
|
# written image is preserved. Otherwise, the written image is
|
|
# removed.
|
|
#
|
|
sub testReadWriteNoVerify {
|
|
my( $infile, $outfile, $writeoptions) = @_;
|
|
|
|
my($image, $images);
|
|
|
|
$image=Image::Magick->new;
|
|
$status=$image->ReadImage("$infile");
|
|
if( "$status" ) {
|
|
print "$status\n";
|
|
print "ReadImage $infile: not ok $test\n";
|
|
} else {
|
|
# Write image to file
|
|
my $options = 'filename=>"$outfile", ' . $writeoptions;
|
|
#print "Using options: $options\n";
|
|
eval "\$status=\$image->WriteImage( $options ) ;";
|
|
if( $@ ) {
|
|
print "$@";
|
|
print "not ok $test\n";
|
|
exit 1;
|
|
}
|
|
if( "$status" ) {
|
|
print "WriteImage $outfile: $status\n";
|
|
print "not ok $test\n";
|
|
} else {
|
|
my($image);
|
|
|
|
# Read image just written
|
|
$image=Image::Magick->new;
|
|
$status=$image->ReadImage("$outfile");
|
|
if( "$status" ) {
|
|
print "ReadImage $outfile: $status\n";
|
|
print "not ok $test\n";
|
|
} else {
|
|
print "ok $test\n";
|
|
unlink $outfile;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#
|
|
# Test writing a file by first reading a source image, writing to a new image,
|
|
# reading the written image, and comparing with expected REF_8.
|
|
#
|
|
# Usage: testReadWriteSized( read filename,
|
|
# write filename,
|
|
# read filename size,
|
|
# read filename depth,
|
|
# write options,
|
|
# expected ref_8 [,expected ref_16] );
|
|
#
|
|
# .e.g
|
|
#
|
|
# testReadWriteSized( 'input.jpg', 'output.jpg', '70x46', 8, q/quality=>80,
|
|
# 'interlace'=>'None'/, 'dc0a144a0b9480cd1e93757a30f01ae3' );
|
|
#
|
|
# If the REF_8 of the written image is not what is expected, the written
|
|
# image is preserved. Otherwise, the written image is removed. A depth of 0 is
|
|
# ignored.
|
|
#
|
|
sub testReadWriteSized {
|
|
my( $infile, $outfile, $size, $readdepth, $writeoptions, $ref_8, $ref_16,
|
|
$ref_32 ) = @_;
|
|
|
|
my($image, $ref_signature);
|
|
|
|
if ( !defined( $ref_16 ) )
|
|
{
|
|
$ref_16 = $ref_8;
|
|
}
|
|
if ( !defined( $ref_32 ) )
|
|
{
|
|
$ref_32 = $ref_16;
|
|
}
|
|
|
|
if (Image::Magick->new()->QuantumDepth == 32)
|
|
{
|
|
$ref_signature=$ref_32;
|
|
}
|
|
elsif (Image::Magick->new()->QuantumDepth == 16)
|
|
{
|
|
$ref_signature=$ref_16;
|
|
}
|
|
else
|
|
{
|
|
$ref_signature=$ref_8;
|
|
}
|
|
|
|
$image=Image::Magick->new;
|
|
|
|
#$image->SetAttribute(debug=>'transform');
|
|
|
|
# Set size attribute
|
|
$status=$image->SetAttribute(size=>"$size");
|
|
warn "$status" if "$status";
|
|
|
|
# If read depth is not zero, then set it
|
|
if ( $readdepth != 0 ) {
|
|
$status=$image->SetAttribute(depth=>$readdepth);
|
|
warn "$status" if "$status";
|
|
}
|
|
|
|
$status=$image->ReadImage("$infile");
|
|
if( "$status" ) {
|
|
print "ReadImage $infile: $status\n";
|
|
print "not ok $test\n";
|
|
} else {
|
|
# Write image to file
|
|
my $options = 'filename=>"$outfile", ' . "$writeoptions";
|
|
#print "Using options: $options\n";
|
|
eval "\$status=\$image->WriteImage( $options ) ;";
|
|
if( $@ ) {
|
|
print "$@\n";
|
|
print "not ok $test\n";
|
|
exit 1;
|
|
}
|
|
if( "$status" ) {
|
|
print "WriteImage $outfile: $status\n";
|
|
print "not ok $test\n";
|
|
} else {
|
|
my($image);
|
|
|
|
$image=Image::Magick->new;
|
|
|
|
if ( $readdepth != 0 ) {
|
|
$status=$image->SetAttribute(depth=>$readdepth);
|
|
warn "$status" if "$status";
|
|
}
|
|
# Set image size attribute
|
|
$status=$image->SetAttribute(size=>"$size");
|
|
warn "$status" if "$status";
|
|
|
|
# Read image just written
|
|
$status=$image->ReadImage("$outfile");
|
|
if( "$status" ) {
|
|
print "ReadImage $outfile: $status\n";
|
|
print "not ok $test\n";
|
|
} else {
|
|
# Check signature
|
|
$signature=$image->Get('signature');
|
|
|
|
if ( $signature ne $ref_signature ) {
|
|
print "ReadImage()\n";
|
|
print "Image: $infile, signatures do not match.\n";
|
|
print " Expected: $ref_signature\n";
|
|
print " Computed: $signature\n";
|
|
print " Depth: ", Image::Magick->new()->QuantumDepth, "\n";
|
|
print "not ok $test\n";
|
|
#$image->Display();
|
|
} else {
|
|
print "ok $test\n";
|
|
#$image->Display();
|
|
($file = $outfile) =~ s/.*://g;
|
|
unlink "$file";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#
|
|
# Test SetAttribute method
|
|
#
|
|
# Usage: testSetAttribute( name, attribute);
|
|
#
|
|
sub testSetAttribute {
|
|
my( $srcimage, $name, $attribute ) = @_;
|
|
|
|
my($image);
|
|
|
|
# Create temporary image
|
|
$image=Image::Magick->new;
|
|
|
|
$status=$image->ReadImage("$srcimage");
|
|
warn "Readimage: $status" if "$status";
|
|
|
|
# Set image option
|
|
print "Image Option : $name=>$attribute\n";
|
|
eval "\$status = \$image->Set('$name'=>'$attribute') ;";
|
|
warn "SetImage: $status" if "$status";
|
|
|
|
# Convert input values to expected output values
|
|
$expected=$attribute;
|
|
if ($attribute eq 'True' || $attribute eq 'true') {
|
|
$expected = 1;
|
|
} elsif ($attribute eq 'False' || $attribute eq 'false') {
|
|
$expected = 0;
|
|
}
|
|
|
|
|
|
$value=$image->GetAttribute($name);
|
|
|
|
if( defined( $value ) ) {
|
|
if ("$expected" eq "$value") {
|
|
print "ok $test\n";
|
|
} else {
|
|
print "Expected ($expected), Got ($value)\n";
|
|
print "not ok $test\n";
|
|
}
|
|
} else {
|
|
print "GetAttribute returned undefined value!\n";
|
|
print "not ok $test\n";
|
|
}
|
|
}
|
|
|
|
#
|
|
# Test GetAttribute method
|
|
#
|
|
# Usage: testGetAttribute( name, expected);
|
|
#
|
|
sub testGetAttribute {
|
|
my( $srcimage, $name, $expected ) = @_;
|
|
|
|
my($image);
|
|
|
|
# Create temporary image
|
|
$image=Image::Magick->new;
|
|
|
|
$status=$image->ReadImage("$srcimage");
|
|
warn "Readimage: $status" if "$status";
|
|
|
|
$value=$image->GetAttribute($name);
|
|
|
|
if( !defined( $expected ) && !defined( $value ) ) {
|
|
# Undefined value is expected
|
|
print "ok $test\n";
|
|
} elsif ( !defined( $value ) ) {
|
|
print "Expected ($expected), Got (undefined)\n";
|
|
print "not ok $test\n";
|
|
} else {
|
|
if ("$expected" eq "$value") {
|
|
print "ok $test\n";
|
|
} else {
|
|
print "Expected ($expected), Got ($value)\n";
|
|
print "not ok $test\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
#
|
|
# Test MontageImage method
|
|
#
|
|
# Usage: testMontage( input image attributes, montage options, expected REF_8
|
|
# [, expected REF_16] );
|
|
#
|
|
sub testMontage {
|
|
my( $imageOptions, $montageOptions, $ref_8, $ref_16, $ref_32, $ref_32_hdri ) = @_;
|
|
|
|
my($image,$ref_signature);
|
|
|
|
if ( !defined( $ref_16 ) )
|
|
{
|
|
$ref_16 = $ref_8;
|
|
}
|
|
if ( !defined( $ref_32 ) )
|
|
{
|
|
$ref_32 = $ref_16;
|
|
}
|
|
|
|
# Create image for image list
|
|
$images=Image::Magick->new;
|
|
|
|
# Create temporary image
|
|
$image=Image::Magick->new;
|
|
|
|
my @colors = ( '#000000', '#008000', '#C0C0C0', '#00FF00',
|
|
'#808080', '#808000', '#FFFFFF', '#FFFF00',
|
|
'#800000', '#000080', '#FF0000', '#0000FF',
|
|
'#800080', '#008080', '#FF00FF', '#00FFFF' );
|
|
|
|
my $color;
|
|
foreach $color ( @colors ) {
|
|
|
|
# Generate image
|
|
$image->Set(size=>'50x50');
|
|
#print("\$image->ReadImage(xc:$color);\n");
|
|
$status=$image->ReadImage("xc:$color");
|
|
if ("$status") {
|
|
warn "Readimage: $status" if "$status";
|
|
} else {
|
|
# Add image to list
|
|
push( @$images, @$image);
|
|
}
|
|
undef @$image;
|
|
}
|
|
|
|
# Set image options
|
|
if ("$imageOptions" ne "") {
|
|
print("\$images->Set($imageOptions)\n");
|
|
eval "\$status = \$images->Set($imageOptions) ;";
|
|
warn "SetImage: $status" if "$status";
|
|
}
|
|
|
|
#print "Border color : ", $images->Get('bordercolor'), "\n";
|
|
#print "Matte color : ", $images->Get('mattecolor'), "\n";
|
|
#print "Pen color : ", $images->Get('pen'), "\n";
|
|
|
|
# Do montage
|
|
#print "Montage Options: $montageOptions\n";
|
|
print("\$montage=\$images->Montage( $montageOptions )\n");
|
|
eval "\$montage=\$images->Montage( $montageOptions ) ;";
|
|
#$montage->Clamp();
|
|
if( $@ ) {
|
|
print "$@";
|
|
print "not ok $test\n";
|
|
return 1;
|
|
}
|
|
|
|
if( ! ref($montage) ) {
|
|
print "not ok $test\n";
|
|
} else {
|
|
# Check REF_8 signature
|
|
# $montage->Display();
|
|
$signature=$montage->GetAttribute('signature');
|
|
if ( defined( $signature ) ) {
|
|
if ( $signature ne $ref_8 && $signature ne $ref_16 && $signature ne $ref_32 && $signature ne $ref_32_hdri) {
|
|
print "ReadImage()\n";
|
|
print "Test $test, signatures do not match.\n";
|
|
print " Expected: $ref_8\n";
|
|
print " Computed: $signature\n";
|
|
print " Depth: ", Image::Magick->new()->QuantumDepth, "\n";
|
|
$status = $montage->Write("test_${test}_out.miff");
|
|
warn "Write: $status" if "$status";
|
|
|
|
print "not ok $test\n";
|
|
} else {
|
|
# Check montage directory
|
|
my $directory = $montage->Get('directory');
|
|
my $expected = join( "\xff", @colors ) . "\xff";
|
|
if ( !defined($directory) ) {
|
|
print "ok $test\n";
|
|
} elsif ( $directory ne $expected) {
|
|
print("Invalid montage directory:\n\"$directory\"\n");
|
|
print("Expected:\n\"$expected\"\n");
|
|
print "not ok $test\n";
|
|
} else {
|
|
# Check montage geometry
|
|
$montage_geom=$montage->Get('montage');
|
|
if( !defined($montage_geom) ) {
|
|
print("Montage geometry not defined!\n");
|
|
print "not ok $test\n";
|
|
} elsif ( $montage_geom !~ /^\d+x\d+\+\d+\+\d+$/ ) {
|
|
print("Montage geometry not in correct format: \"$montage_geom\"\n");
|
|
print "not ok $test\n";
|
|
} else {
|
|
print "ok $test\n";
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
warn "GetAttribute returned undefined value!";
|
|
print "not ok $test\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
#
|
|
# Test filter method using signature compare
|
|
#
|
|
# Usage: testFilterSignature( input image attributes, filter, options, expected REF_8
|
|
# [, expected REF_16] );
|
|
#
|
|
sub testFilterSignature {
|
|
my( $srcimage, $filter, $filter_options, $ref_8, $ref_16, $ref_32 ) = @_;
|
|
|
|
my($image, $ref_signature);
|
|
|
|
# print( $filter, " ...\n" );
|
|
|
|
if ( !defined( $ref_16 ) )
|
|
{
|
|
$ref_16 = $ref_8;
|
|
}
|
|
if ( !defined( $ref_32 ) )
|
|
{
|
|
$ref_32 = $ref_16;
|
|
}
|
|
|
|
if (Image::Magick->new()->QuantumDepth == 32)
|
|
{
|
|
$ref_signature=$ref_32;
|
|
}
|
|
elsif (Image::Magick->new()->QuantumDepth == 16)
|
|
{
|
|
$ref_signature=$ref_16;
|
|
}
|
|
else
|
|
{
|
|
$ref_signature=$ref_8;
|
|
}
|
|
|
|
# Create temporary image
|
|
$image=Image::Magick->new;
|
|
|
|
$status=$image->ReadImage("$srcimage");
|
|
warn "Readimage: $status" if "$status";
|
|
|
|
print("$filter\($filter_options\) ...\n");
|
|
$image->$filter($filter_options);
|
|
#$image->write(filename=>"reference/filter/$filter.miff", compression=>'None');
|
|
|
|
$signature=$image->GetAttribute('signature');
|
|
if ( defined( $signature ) ) {
|
|
if ( $signature ne $ref_signature ) {
|
|
print "Test $test, signatures do not match.\n";
|
|
print " Expected: $ref_signature\n";
|
|
print " Computed: $signature\n";
|
|
print " Depth: ", Image::Magick->new()->QuantumDepth, "\n";
|
|
#$image->Display();
|
|
print "not ok $test\n";
|
|
} else {
|
|
print "ok $test\n";
|
|
}
|
|
} else {
|
|
warn "GetAttribute returned undefined value!";
|
|
print "not ok $test\n";
|
|
}
|
|
}
|
|
|
|
#
|
|
# Test filter method using comparison with reference image
|
|
#
|
|
# Usage: testFilterCompare( input image, input image options, reference image, filter, filter options,
|
|
# normalized_mean_error,
|
|
# normalized_maximum_error );
|
|
sub testFilterCompare {
|
|
my ($srcimage_name, $src_read_options, $refimage_name, $filter,
|
|
$filter_options, $normalized_mean_error_max,
|
|
$normalized_maximum_error_max) = @_;
|
|
my($srcimage, $refimage, $normalized_mean_error,
|
|
$normalized_maximum_error);
|
|
my($status,$errorinfo);
|
|
|
|
$errorinfo='';
|
|
$status='';
|
|
$normalized_mean_error_max+=1.0e-12;
|
|
$normalized_maximum_error_max+=1.0e-12;
|
|
|
|
#print( $filter, " ...\n" );
|
|
|
|
# Create images
|
|
$srcimage=Image::Magick->new;
|
|
$refimage=Image::Magick->new;
|
|
|
|
if ( "$src_read_options" ne "" ) {
|
|
print("Set($src_read_options) ...\n");
|
|
eval "\$status=\$srcimage->Set($src_read_options);";
|
|
if ("$status")
|
|
{
|
|
$errorinfo = "Set($src_read_options): $status";
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
}
|
|
|
|
$status=$srcimage->ReadImage($srcimage_name);
|
|
#eval "\$status=\$srcimage->ReadImage($srcimage_name);";
|
|
if ("$status")
|
|
{
|
|
$errorinfo = "Readimage ($srcimage_name): $status";
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
|
|
print("$filter\($filter_options\) ...\n");
|
|
eval "\$status=\$srcimage->$filter($filter_options);";
|
|
if ("$status")
|
|
{
|
|
$errorinfo = "$filter ($filter_options): $status";
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
|
|
$srcimage->Clamp();
|
|
$srcimage->set(depth=>8);
|
|
# if ("$filter" eq "Shear") {
|
|
# $srcimage->Display();
|
|
# $srcimage->write(filename=>"$refimage_name", compression=>'None');
|
|
# }
|
|
|
|
$status=$refimage->ReadImage("$refimage_name");
|
|
if ("$status")
|
|
{
|
|
$errorinfo = "Readimage ($refimage_name): $status";
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
|
|
# FIXME: The following statement should not be needed.
|
|
# $status=$refimage->Set(type=>'TrueColor');
|
|
# if ("$status")
|
|
# {
|
|
# $errorinfo = "Set(type=>'TrueColor'): $status";
|
|
# goto COMPARE_RUNTIME_ERROR;
|
|
# }
|
|
|
|
$status=$srcimage->Difference($refimage);
|
|
if ("$status")
|
|
{
|
|
$errorinfo = "Difference($refimage_name): $status";
|
|
print(" Reference: ", $refimage->Get('columns'), "x", $refimage->Get('rows'), "\n");
|
|
print(" Computed: ", $srcimage->Get('columns'), "x", $srcimage->Get('rows'), "\n");
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
|
|
$normalized_mean_error=0;
|
|
$normalized_mean_error=$srcimage->GetAttribute('mean-error');
|
|
if ( !defined($normalized_mean_error) )
|
|
{
|
|
$errorinfo = "GetAttribute('mean-error') returned undefined value!";
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
$normalized_maximum_error=0;
|
|
$normalized_maximum_error=$srcimage->GetAttribute('maximum-error');
|
|
if ( ! defined($normalized_maximum_error) )
|
|
{
|
|
$errorinfo = "GetAttribute('maximum-error') returned undefined value!";
|
|
goto COMPARE_RUNTIME_ERROR;
|
|
}
|
|
if ( ($normalized_mean_error > $normalized_mean_error_max) ||
|
|
($normalized_maximum_error > $normalized_maximum_error_max) )
|
|
{
|
|
print(" mean-error=$normalized_mean_error, maximum-error=$normalized_maximum_error\n");
|
|
print "not ok $test\n";
|
|
#$srcimage->Display();
|
|
undef $srcimage;
|
|
undef $refimage;
|
|
return 1
|
|
}
|
|
|
|
undef $srcimage;
|
|
undef $refimage;
|
|
print "ok $test\n";
|
|
return 0;
|
|
|
|
COMPARE_RUNTIME_ERROR:
|
|
undef $srcimage;
|
|
undef $refimage;
|
|
print(" $errorinfo\n");
|
|
print "not ok $test\n";
|
|
return 1
|
|
}
|
|
1;
|