• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#  Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization
2#  dedicated to making software imaging solutions freely available.
3#
4#  You may not use this file except in compliance with the License.  You may
5#  obtain a copy of the License at
6#
7#    https://imagemagick.org/script/license.php
8#
9#  Unless required by applicable law or agreed to in writing, software
10#  distributed under the License is distributed on an "AS IS" BASIS,
11#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12#  See the License for the specific language governing permissions and
13#  limitations under the License.
14#
15#
16# Common subroutines to support tests
17#
18# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
19#
20
21#
22# Test composite method using comparison with a reference image
23#
24# Usage: testFilterCompare( background image name, background read options,
25#                           composite image name, composite read options,
26#                           composite options,reference image
27#                           normalized_mean_error,
28#                           normalized_maximum_error );
29sub testCompositeCompare {
30  my ($background_name,
31      $background_read_options,
32      $composite_name,
33      $composite_read_options,
34      $composite_options,
35      $refimage_name,
36      $normalized_mean_error_max,
37      $normalized_maximum_error_max) = @_;
38  my ($background,
39      $composite,
40      $errorinfo,
41      $normalized_maximum_error,
42      $normalized_mean_error,
43      $refimage,
44      $status);
45
46  $errorinfo='';
47  $status='';
48
49  #print( $filter, " ...\n" );
50
51  # Create images
52  $background=Image::Magick->new;
53  $composite=Image::Magick->new;
54  $refimage=Image::Magick->new;
55
56  # Read background image
57  if ( "$background_read_options" ne "" ) {
58    print("Set($background_read_options) ...\n");
59    eval "\$status=\$background->Set($background_read_options);";
60    if ("$status")
61      {
62        $errorinfo = "Set($background_read_options): $status";
63        goto COMPARE_RUNTIME_ERROR;
64      }
65  }
66  $status=$background->ReadImage($background_name);
67  if ("$status")
68    {
69      $errorinfo = "Readimage ($background_name): $status";
70      goto COMPARE_RUNTIME_ERROR;
71    }
72
73  # Read composite image
74  if ( "$composite_read_options" ne "" ) {
75    print("Set($composite_read_options) ...\n");
76    eval "\$status=\$composite->Set($composite_read_options);";
77    if ("$status")
78      {
79        $errorinfo = "Set($composite_read_options): $status";
80        goto COMPARE_RUNTIME_ERROR;
81      }
82  }
83  $status=$composite->ReadImage($composite_name);
84  if ("$status")
85    {
86      $errorinfo = "Readimage ($composite_name): $status";
87      goto COMPARE_RUNTIME_ERROR;
88    }
89
90  # Do composition
91  print("Composite\($composite_options\) ...\n");
92  eval "\$status=\$background->Composite(image=>\$composite, $composite_options);";
93  if ("$status")
94    {
95      $errorinfo = "Composite ($composite_options): $status";
96      goto COMPARE_RUNTIME_ERROR;
97    }
98
99  $background->Clamp();
100  $background->set(depth=>8);
101#  if ("$filter" eq "Atop") {
102#    $background->write(filename=>"$refimage_name", compression=>'None');
103#  $background->Display();
104#  }
105
106  $status=$refimage->ReadImage("$refimage_name");
107  if ("$status")
108    {
109      $errorinfo = "Readimage ($refimage_name): $status";
110      goto COMPARE_RUNTIME_ERROR;
111    }
112
113  $status=$background->Difference($refimage);
114  if ("$status")
115    {
116      $errorinfo = "Difference($refimage_name): $status";
117      print("  Reference: ", $refimage->Get('columns'), "x", $refimage->Get('rows'), "\n");
118      print("  Computed:  ", $background->Get('columns'), "x", $background->Get('rows'), "\n");
119      goto COMPARE_RUNTIME_ERROR;
120    }
121
122  $normalized_mean_error=0;
123  $normalized_mean_error=$background->GetAttribute('mean-error');
124  if ( !defined($normalized_mean_error) )
125    {
126      $errorinfo = "GetAttribute('mean-error') returned undefined value!";
127      goto COMPARE_RUNTIME_ERROR;
128    }
129  $normalized_maximum_error=0;
130  $normalized_maximum_error=$background->GetAttribute('maximum-error');
131  if ( ! defined($normalized_maximum_error) )
132    {
133      $errorinfo = "GetAttribute('maximum-error') returned undefined value!";
134      goto COMPARE_RUNTIME_ERROR;
135    }
136  if ( ($normalized_mean_error > $normalized_mean_error_max) ||
137       ($normalized_maximum_error > $normalized_maximum_error_max) )
138    {
139      print("  mean-error=$normalized_mean_error, maximum-error=$normalized_maximum_error\n");
140      print "not ok $test\n";
141      $background->Display();
142      undef $background;
143      undef $composite;
144      undef $refimage;
145      return 1
146    }
147
148  undef $background;
149  undef $composite;
150  undef $refimage;
151  print "ok $test\n";
152  return 0;
153
154 COMPARE_RUNTIME_ERROR:
155  undef $background;
156  undef $composite;
157  undef $refimage;
158  print("  $errorinfo\n");
159  print "not ok $test\n";
160  return 1
161}
162
163#
164# Test reading a 16-bit file in which two signatures are possible,
165# depending on whether 16-bit pixels data has been enabled
166#
167# Usage: testRead( read filename, expected ref_8 [, expected ref_16] [, expected ref_32] );
168#
169sub testRead {
170  my( $infile, $ref_8, $ref_16, $ref_32 ) =  @_;
171
172  my($image,$magick,$success,$ref_signature);
173
174  $failure=0;
175
176  if ( !defined( $ref_16 ) )
177    {
178      $ref_16 = $ref_8;
179    }
180  if ( !defined( $ref_32 ) )
181    {
182      $ref_32 = $ref_16;
183    }
184
185  if (Image::Magick->new()->QuantumDepth == 32)
186    {
187      $ref_signature=$ref_32;
188    }
189  elsif (Image::Magick->new()->QuantumDepth == 16)
190    {
191      $ref_signature=$ref_16;
192    }
193  else
194    {
195      $ref_signature=$ref_8;
196    }
197
198  $magick='';
199
200  #
201  # Test reading from file
202  #
203  {
204    my($image, $signature, $status);
205
206    print( "  testing reading from file \"", $infile, "\" ...\n");
207    $image=Image::Magick->new;
208    $image->Set(size=>'512x512');
209    $status=$image->ReadImage("$infile");
210    if( "$status" && !($status =~ /Exception ((315)|(350))/)) {
211      print "ReadImage $infile: $status\n";
212      ++$failure;
213    } else {
214      if( "$status" ) {
215        print "ReadImage $infile: $status\n";
216      }
217      undef $status;
218      $magick=$image->Get('magick');
219      $signature=$image->Get('signature');
220
221      if ( $signature ne $ref_signature ) {
222        print "ReadImage()\n";
223       	print "Image: $infile, signatures do not match.\n";
224      	print "     Expected: $ref_signature\n";
225      	print "     Computed: $signature\n";
226        print "     Depth:    ", Image::Magick->new()->QuantumDepth, "\n";
227        ++$failure;
228        $image->Display();
229      }
230    }
231    undef $image;
232  }
233
234  #
235  # Test reading from blob
236  #
237  if (!($infile =~ /\.bz2$/) && !($infile =~ /\.gz$/) && !($infile =~ /\.Z$/))
238  {
239    my(@blob, $blob_length, $image, $signature, $status);
240
241    if( open( FILE, "< $infile"))
242      {
243        print( "  testing reading from BLOB with magick \"", $magick, "\"...\n");
244        binmode( FILE );
245        $blob_length = read( FILE, $blob, 10000000 );
246        close( FILE );
247        if( defined( $blob ) ) {
248          $image=Image::Magick->new(magick=>$magick);
249          $status=$image->BlobToImage( $blob );
250          undef $blob;
251          if( "$status" && !($status =~ /Exception ((315)|(350))/)) {
252            print "BlobToImage $infile: $status\n";
253            ++$failure;
254          } else {
255            if( "$status" ) {
256              print "ReadImage $infile: $status\n";
257            }
258            $signature=$image->Get('signature');
259            if ( $signature ne $ref_signature ) {
260              print "BlobToImage()\n";
261              print "Image: $infile, signatures do not match.\n";
262              print "     Expected: $ref_signature\n";
263              print "     Computed: $signature\n";
264              print "     Depth:    ", Image::Magick->new()->QuantumDepth, "\n";
265              #$image->Display();
266              ++$failure;
267            }
268          }
269        }
270      }
271    undef $image;
272  }
273
274  #
275  # Display test status
276  #
277  if ( $failure != 0 ) {
278    print "not ok $test\n";
279  } else {
280    print "ok $test\n";
281  }
282}
283
284
285#
286# Test reading a file, and compare with a reference file
287#
288sub testReadCompare {
289  my( $srcimage_name,$refimage_name, $read_options,
290      $normalized_mean_error_max, $normalized_maximum_error_max) = @_;
291  my($srcimage, $refimage, $normalized_mean_error, $normalized_maximum_error);
292
293  $errorinfo='';
294
295  # Create images
296  $srcimage=Image::Magick->new;
297  $refimage=Image::Magick->new;
298
299  if ( "$read_options" ne "" ) {
300    eval "\$status=\$srcimage->Set($read_options);";
301    if ("$status")
302      {
303        $errorinfo = "Set($read_options): $status";
304        warn("$errorinfo");
305        goto COMPARE_RUNTIME_ERROR;
306      }
307  }
308
309  $status=$srcimage->ReadImage("$srcimage_name");
310  if ("$status")
311    {
312      $errorinfo = "Readimage ($srcimage_name): $status";
313      warn("$errorinfo");
314      goto COMPARE_RUNTIME_ERROR;
315    }
316
317# if ("$srcimage_name" eq "input.tim") {
318#    $srcimage->write(filename=>"$refimage_name", compression=>'None');
319#  }
320
321  #print("writing file $refimage_name\n");
322  #$srcimage->Quantize(colors=>256);
323  #$status=$srcimage->write(filename=>"$refimage_name", compression=>'rle');
324  #warn "$status" if $status;
325
326  $status=$refimage->ReadImage("$refimage_name");
327  if ("$status")
328    {
329      $errorinfo = "Readimage ($refimage_name): $status";
330       warn("$errorinfo");
331      goto COMPARE_RUNTIME_ERROR;
332    }
333
334  $srcimage->Clamp();
335  $srcimage->set(depth=>8);
336
337  # FIXME: The following statement should not be needed.
338#  $status=$refimage->Set(type=>'TrueColor');
339#  if ("$status")
340#    {
341#      $errorinfo = "Set(type=>'TrueColor'): $status";
342#      goto COMPARE_RUNTIME_ERROR;
343#    }
344
345  # Verify that $srcimage and $refimage contain the same number of frames.
346  if ( $#srcimage != $#refimage )
347    {
348      $errorinfo = "Source and reference images contain different number of frames ($#srcimage != $#refimage)";
349      warn("$errorinfo");
350      goto COMPARE_RUNTIME_ERROR;
351    }
352
353  # Compare each frame in the sequence.
354  for ($index = 0; $srcimage->[$index] && $refimage->[$index]; $index++)
355    {
356      $status=$srcimage->[$index]->Difference($refimage->[$index]);
357      if ("$status")
358        {
359          $errorinfo = "Difference($refimage_name)->[$index]: $status";
360          warn("$errorinfo");
361          goto COMPARE_RUNTIME_ERROR;
362        }
363    }
364
365
366  $normalized_mean_error=0;
367  $normalized_mean_error=$srcimage->GetAttribute('mean-error');
368  if ( !defined($normalized_mean_error) )
369    {
370      $errorinfo = "GetAttribute('mean-error') returned undefined value!";
371      warn("$errorinfo");
372      goto COMPARE_RUNTIME_ERROR;
373    }
374  $normalized_maximum_error=0;
375  $normalized_maximum_error=$srcimage->GetAttribute('maximum-error');
376  if ( ! defined($normalized_maximum_error) )
377    {
378      $errorinfo = "GetAttribute('maximum-error') returned undefined value!";
379      warn("$errorinfo");
380      goto COMPARE_RUNTIME_ERROR;
381    }
382  if ( ($normalized_mean_error > $normalized_mean_error_max) ||
383       ($normalized_maximum_error > $normalized_maximum_error_max) )
384    {
385      print("mean-error=$normalized_mean_error, maximum-error=$normalized_maximum_error\n");
386      #$srcimage->Display();
387      print "not ok $test\n";
388      return 1
389    }
390
391  undef $srcimage;
392  undef $refimage;
393  print "ok $test\n";
394  return 0;
395
396 COMPARE_RUNTIME_ERROR:
397  undef $srcimage;
398  undef $refimage;
399  print "not ok $test\n";
400  return 1
401}
402
403#
404# Test reading a file which requires a file size to read (GRAY, RGB, CMYK)
405# or supports multiple resolutions (JBIG, JPEG, PCD)
406#
407# Usage: testRead( read filename, size, depth, expected ref_8 [, expected ref_16] [, expected ref_32] );
408#
409sub testReadSized {
410  my( $infile, $size, $ref_8, $ref_16, $ref_32 ) =  @_;
411
412  my($image,$ref_signature);
413
414  if ( !defined( $ref_16 ) )
415    {
416      $ref_16 = $ref_8;
417    }
418  if ( !defined( $ref_32 ) )
419    {
420      $ref_32 = $ref_16;
421    }
422
423  if (Image::Magick->new()->QuantumDepth == 32)
424    {
425      $ref_signature=$ref_32;
426    }
427  elsif (Image::Magick->new()->QuantumDepth == 16)
428    {
429      $ref_signature=$ref_16;
430    }
431  else
432    {
433      $ref_signature=$ref_8;
434    }
435
436  $image=Image::Magick->new;
437
438  # Set size attribute
439  $status=$image->SetAttribute(size=>"$size");
440  warn "$status" if "$status";
441
442  # If depth is not zero, then set it
443  if ( Image::Magick->new()->QuantumDepth != 0 ) {
444    $status=$image->SetAttribute(depth=>Image::Magick->new()->QuantumDepth);
445    warn "$status" if "$status";
446  }
447
448  $status=$image->ReadImage("$infile");
449  if( "$status" ) {
450    print "ReadImage $infile: $status";
451    print "not ok $test\n";
452  } else {
453    $signature=$image->Get('signature');
454      if ( $signature ne $ref_signature ) {
455        print "ReadImage()\n";
456      	print "Image: $infile, signatures do not match.\n";
457      	print "     Expected: $ref_signature\n";
458      	print "     Computed: $signature\n";
459        print "     Depth:    ", Image::Magick->new()->QuantumDepth, "\n";
460        print "not ok $test\n";
461        #$image->Display();
462      } else {
463        print "ok $test\n";
464    }
465  }
466}
467
468#
469# Test writing a file by first reading a source image, writing to a new image,
470# reading the written image, and comparing with expected REF_8.
471#
472# Usage: testReadWrite( read filename, write filename, write options,
473#    expected ref_8 [, expected ref_16] );
474#
475# .e.g
476#
477# testReadWrite( 'input.jpg', 'output.jpg', q/quality=>80, interlace=>'None'/,
478#                'dc0a144a0b9480cd1e93757a30f01ae3' );
479#
480# If the REF_8 of the written image is not what is expected, the written
481# image is preserved.  Otherwise, the written image is removed.
482#
483sub testReadWrite {
484  my( $infile, $outfile, $writeoptions, $ref_8, $ref_16, $ref_32 ) = @_;
485
486  my($image);
487
488  if ( !defined( $ref_16 ) )
489    {
490      $ref_16 = $ref_8;
491    }
492  if ( !defined( $ref_32 ) )
493    {
494      $ref_32 = $ref_16;
495    }
496
497  if (Image::Magick->new()->QuantumDepth == 32)
498    {
499      $ref_signature=$ref_32;
500    }
501  elsif (Image::Magick->new()->QuantumDepth == 16)
502    {
503      $ref_signature=$ref_16;
504    }
505  else
506    {
507      $ref_signature=$ref_8;
508    }
509
510  $image=Image::Magick->new;
511  $status=$image->ReadImage("$infile");
512  $signature=$image->Get('signature');
513  if( "$status" ) {
514    print "ReadImage $infile: $status\n";
515    print "not ok $test\n";
516  } else {
517    # Write image to file
518    my $options = 'filename=>"$outfile", ' . "$writeoptions";
519    #print "Using options: $options\n";
520    eval "\$status=\$image->WriteImage( $options ) ;";
521    if( $@ ) {
522      print "$@\n";
523      print "not ok $test\n";
524      exit 1;
525    }
526    if( "$status" ) {
527      print "WriteImage $outfile: $status\n";
528      print "not ok $test\n";
529    } else {
530      my($image);
531
532      # Read image just written
533      $image=Image::Magick->new;
534      $status=$image->ReadImage("$outfile");
535      if( "$status" ) {
536        print "ReadImage $outfile: $status\n";
537        print "not ok $test\n";
538      } else {
539        # Check signature
540        $signature=$image->Get('signature');
541        if ( $signature ne $ref_signature ) {
542          print "ReadImage()\n";
543          print "Image: $infile, signatures do not match.\n";
544          print "     Expected: $ref_signature\n";
545          print "     Computed: $signature\n";
546          print "     Depth:    ", Image::Magick->new()->QuantumDepth, "\n";
547          print "not ok $test\n";
548          $image->Display();
549        } else {
550          print "ok $test\n";
551          ($file = $outfile) =~ s/.*://g;
552          #unlink "$file";
553        }
554      }
555    }
556  }
557}
558
559#
560# Test reading a file, and compare with a reference file
561#
562sub testReadWriteCompare {
563  my( $srcimage_name, $outimage_name, $refimage_name,
564      $read_options, $write_options,
565      $normalized_mean_error_max, $normalized_maximum_error_max) = @_;
566  my($srcimage, $refimage, $normalized_mean_error,
567    $normalized_maximum_error);
568
569  $errorinfo='';
570
571  $image=Image::Magick->new;
572  $refimage=Image::Magick->new;
573
574  #
575  # Read the initial image
576  #
577  $status=$image->ReadImage($srcimage_name);
578  if ("$status")
579    {
580      $errorinfo = "Readimage ($srcimage_name): $status";
581      goto COMPARE_RUNTIME_ERROR;
582    }
583
584  #
585  # Write image to output file
586  #
587  if ( "$write_options" ne "" ) {
588    eval "\$status=\$image->Set($write_options);";
589    if ("$status")
590      {
591        $errorinfo = "Set($write_options): $status";
592        goto COMPARE_RUNTIME_ERROR;
593      }
594  }
595  $image->Set(filename=>"$outimage_name");
596
597  $status=$image->WriteImage( );
598  if ("$status")
599    {
600      $errorinfo = "WriteImage ($outimage_name): $status";
601      goto COMPARE_RUNTIME_ERROR;
602    }
603
604  undef $image;
605  $image=Image::Magick->new;
606
607  #
608  # Read image from output file
609  #
610  if ( "$read_options" ne "" ) {
611    eval "\$status=\$image->Set($read_options);";
612    if ("$status")
613      {
614        $errorinfo = "Set($read_options): $status";
615        goto COMPARE_RUNTIME_ERROR;
616      }
617  }
618
619  $image->ReadImage("$outimage_name");
620  if ("$status")
621    {
622      $errorinfo = "WriteImage ($outimage_name): $status";
623      goto COMPARE_RUNTIME_ERROR;
624    }
625
626# eval "\$status=\$image->Set($write_options);";
627#$status=$image->write(filename=>"$refimage_name", compression=>'None');
628# warn "$status" if $status;
629
630  #
631  # Read reference image
632  #
633  $status=$refimage->ReadImage("$refimage_name");
634  if ("$status")
635    {
636      $errorinfo = "Readimage ($refimage_name): $status";
637      goto COMPARE_RUNTIME_ERROR;
638    }
639
640  #
641  # Compare output file with reference image
642  #
643
644  $image->Clamp();
645  $image->set(depth=>8);
646
647  # FIXME: The following statement should not be needed.
648#  $status=$refimage->Set(type=>'TrueColor');
649#  if ("$status")
650#    {
651#      $errorinfo = "Set(type=>'TrueColor'): $status";
652#      goto COMPARE_RUNTIME_ERROR;
653#    }
654
655  $status=$image->Difference($refimage);
656  if ("$status")
657    {
658      $errorinfo = "Difference($refimage_name): $status";
659      goto COMPARE_RUNTIME_ERROR;
660    }
661
662  $normalized_mean_error=0;
663  $normalized_mean_error=$image->GetAttribute('mean-error');
664  if ( !defined($normalized_mean_error) )
665    {
666      $errorinfo = "GetAttribute('mean-error') returned undefined value!";
667      goto COMPARE_RUNTIME_ERROR;
668    }
669  $normalized_maximum_error=0;
670  $normalized_maximum_error=$image->GetAttribute('maximum-error');
671  if ( ! defined($normalized_maximum_error) )
672    {
673      $errorinfo = "GetAttribute('maximum-error') returned undefined value!";
674      goto COMPARE_RUNTIME_ERROR;
675    }
676
677  if ( ($normalized_mean_error > $normalized_mean_error_max) ||
678       ($normalized_maximum_error > $normalized_maximum_error_max) )
679    {
680      print("mean-error=$normalized_mean_error, maximum-error=$normalized_maximum_error\n");
681      print "not ok $test\n";
682      return 1
683    }
684
685  print "ok $test\n";
686  undef $image;
687  undef $refimage;
688  return 0;
689
690 COMPARE_RUNTIME_ERROR:
691  warn("$errorinfo");
692  print "not ok $test\n";
693  undef $image;
694  undef $refimage;
695  return 1
696}
697
698#
699# Test writing a file by first reading a source image, writing to a
700# new image, and reading the written image.  Depends on detecting
701# reported errors by ImageMagick
702#
703# Usage: testReadWrite( read filename, write filename, write options);
704#
705# .e.g
706#
707# testReadWrite( 'input.jpg', 'output.jpg', q/quality=>80, 'interlace'=>'None'/ );
708#
709# If the read of the written image is not what is expected, the
710# written image is preserved.  Otherwise, the written image is
711# removed.
712#
713sub testReadWriteNoVerify {
714  my( $infile, $outfile, $writeoptions) = @_;
715
716  my($image, $images);
717
718  $image=Image::Magick->new;
719  $status=$image->ReadImage("$infile");
720  if( "$status" ) {
721    print "$status\n";
722    print "ReadImage $infile: not ok $test\n";
723  } else {
724    # Write image to file
725    my $options = 'filename=>"$outfile", ' . $writeoptions;
726    #print "Using options: $options\n";
727    eval "\$status=\$image->WriteImage( $options ) ;";
728    if( $@ ) {
729      print "$@";
730      print "not ok $test\n";
731      exit 1;
732    }
733    if( "$status" ) {
734      print "WriteImage $outfile: $status\n";
735      print "not ok $test\n";
736    } else {
737      my($image);
738
739      # Read image just written
740      $image=Image::Magick->new;
741      $status=$image->ReadImage("$outfile");
742      if( "$status" ) {
743        print "ReadImage $outfile: $status\n";
744        print "not ok $test\n";
745      } else {
746        print "ok $test\n";
747        unlink $outfile;
748      }
749    }
750  }
751}
752
753#
754# Test writing a file by first reading a source image, writing to a new image,
755# reading the written image, and comparing with expected REF_8.
756#
757# Usage: testReadWriteSized( read filename,
758#                            write filename,
759#                            read filename size,
760#                            read filename depth,
761#                            write options,
762#                            expected ref_8 [,expected ref_16] );
763#
764# .e.g
765#
766# testReadWriteSized( 'input.jpg', 'output.jpg', '70x46', 8, q/quality=>80,
767#                     'interlace'=>'None'/, 'dc0a144a0b9480cd1e93757a30f01ae3' );
768#
769# If the REF_8 of the written image is not what is expected, the written
770# image is preserved.  Otherwise, the written image is removed.  A depth of 0 is
771# ignored.
772#
773sub testReadWriteSized {
774  my( $infile, $outfile, $size, $readdepth, $writeoptions, $ref_8, $ref_16,
775      $ref_32 ) = @_;
776
777  my($image, $ref_signature);
778
779  if ( !defined( $ref_16 ) )
780    {
781      $ref_16 = $ref_8;
782    }
783  if ( !defined( $ref_32 ) )
784    {
785      $ref_32 = $ref_16;
786    }
787
788  if (Image::Magick->new()->QuantumDepth == 32)
789    {
790      $ref_signature=$ref_32;
791    }
792  elsif (Image::Magick->new()->QuantumDepth == 16)
793    {
794      $ref_signature=$ref_16;
795    }
796  else
797    {
798      $ref_signature=$ref_8;
799    }
800
801  $image=Image::Magick->new;
802
803  #$image->SetAttribute(debug=>'transform');
804
805  # Set size attribute
806  $status=$image->SetAttribute(size=>"$size");
807  warn "$status" if "$status";
808
809  # If read depth is not zero, then set it
810  if ( $readdepth != 0 ) {
811    $status=$image->SetAttribute(depth=>$readdepth);
812    warn "$status" if "$status";
813  }
814
815  $status=$image->ReadImage("$infile");
816  if( "$status" ) {
817    print "ReadImage $infile: $status\n";
818    print "not ok $test\n";
819  } else {
820    # Write image to file
821    my $options = 'filename=>"$outfile", ' . "$writeoptions";
822    #print "Using options: $options\n";
823    eval "\$status=\$image->WriteImage( $options ) ;";
824    if( $@ ) {
825      print "$@\n";
826      print "not ok $test\n";
827      exit 1;
828    }
829    if( "$status" ) {
830      print "WriteImage $outfile: $status\n";
831      print "not ok $test\n";
832    } else {
833      my($image);
834
835      $image=Image::Magick->new;
836
837      if ( $readdepth != 0 ) {
838        $status=$image->SetAttribute(depth=>$readdepth);
839        warn "$status" if "$status";
840      }
841      # Set image size attribute
842      $status=$image->SetAttribute(size=>"$size");
843      warn "$status" if "$status";
844
845      # Read image just written
846      $status=$image->ReadImage("$outfile");
847      if( "$status" ) {
848        print "ReadImage $outfile: $status\n";
849        print "not ok $test\n";
850      } else {
851        # Check signature
852        $signature=$image->Get('signature');
853
854        if ( $signature ne $ref_signature ) {
855          print "ReadImage()\n";
856          print "Image: $infile, signatures do not match.\n";
857          print "     Expected: $ref_signature\n";
858          print "     Computed: $signature\n";
859          print "     Depth:    ", Image::Magick->new()->QuantumDepth, "\n";
860          print "not ok $test\n";
861          #$image->Display();
862        } else {
863          print "ok $test\n";
864          #$image->Display();
865          ($file = $outfile) =~ s/.*://g;
866          unlink "$file";
867        }
868      }
869    }
870  }
871}
872
873#
874# Test SetAttribute method
875#
876# Usage: testSetAttribute( name, attribute);
877#
878sub testSetAttribute {
879  my( $srcimage, $name, $attribute ) = @_;
880
881  my($image);
882
883  # Create temporary image
884  $image=Image::Magick->new;
885
886  $status=$image->ReadImage("$srcimage");
887  warn "Readimage: $status" if "$status";
888
889  # Set image option
890  print "Image Option  : $name=>$attribute\n";
891  eval "\$status = \$image->Set('$name'=>'$attribute') ;";
892  warn "SetImage: $status" if "$status";
893
894  # Convert input values to expected output values
895  $expected=$attribute;
896  if ($attribute eq 'True' || $attribute eq 'true') {
897    $expected = 1;
898  } elsif ($attribute eq 'False' || $attribute eq 'false') {
899    $expected = 0;
900  }
901
902
903  $value=$image->GetAttribute($name);
904
905  if( defined( $value ) ) {
906    if ("$expected" eq "$value") {
907      print "ok $test\n";
908    } else {
909      print "Expected ($expected), Got ($value)\n";
910      print "not ok $test\n";
911    }
912  } else {
913    print "GetAttribute returned undefined value!\n";
914    print "not ok $test\n";
915  }
916}
917
918#
919# Test GetAttribute method
920#
921# Usage: testGetAttribute( name, expected);
922#
923sub testGetAttribute {
924  my( $srcimage, $name, $expected ) = @_;
925
926  my($image);
927
928  # Create temporary image
929  $image=Image::Magick->new;
930
931  $status=$image->ReadImage("$srcimage");
932  warn "Readimage: $status" if "$status";
933
934  $value=$image->GetAttribute($name);
935
936  if( !defined( $expected ) && !defined( $value ) ) {
937    # Undefined value is expected
938    print "ok $test\n";
939  } elsif ( !defined( $value ) ) {
940    print "Expected ($expected), Got (undefined)\n";
941    print "not ok $test\n";
942  } else {
943    if ("$expected" eq "$value") {
944      print "ok $test\n";
945    } else {
946      print "Expected ($expected), Got ($value)\n";
947      print "not ok $test\n";
948    }
949  }
950}
951
952#
953# Test MontageImage method
954#
955# Usage: testMontage( input image attributes, montage options, expected REF_8
956#       [, expected REF_16] );
957#
958sub testMontage {
959  my( $imageOptions, $montageOptions, $ref_8, $ref_16, $ref_32 ) = @_;
960
961  my($image,$ref_signature);
962
963  if ( !defined( $ref_16 ) )
964    {
965      $ref_16 = $ref_8;
966    }
967  if ( !defined( $ref_32 ) )
968    {
969      $ref_32 = $ref_16;
970    }
971
972  if (Image::Magick->new()->QuantumDepth == 32)
973    {
974      $ref_signature=$ref_32;
975    }
976  elsif (Image::Magick->new()->QuantumDepth == 16)
977    {
978      $ref_signature=$ref_16;
979    }
980  else
981    {
982      $ref_signature=$ref_8;
983    }
984
985  # Create image for image list
986  $images=Image::Magick->new;
987
988  # Create temporary image
989  $image=Image::Magick->new;
990
991  my @colors = ( '#000000', '#008000', '#C0C0C0', '#00FF00',
992                 '#808080', '#808000', '#FFFFFF', '#FFFF00',
993                 '#800000', '#000080', '#FF0000', '#0000FF',
994                 '#800080', '#008080', '#FF00FF', '#00FFFF' );
995
996  my $color;
997  foreach $color ( @colors ) {
998
999    # Generate image
1000    $image->Set(size=>'50x50');
1001    #print("\$image->ReadImage(xc:$color);\n");
1002    $status=$image->ReadImage("xc:$color");
1003    if ("$status") {
1004      warn "Readimage: $status" if "$status";
1005    } else {
1006      # Add image to list
1007      push( @$images, @$image);
1008    }
1009    undef @$image;
1010  }
1011
1012  # Set image options
1013  if ("$imageOptions" ne "") {
1014    print("\$images->Set($imageOptions)\n");
1015    eval "\$status = \$images->Set($imageOptions) ;";
1016    warn "SetImage: $status" if "$status";
1017  }
1018
1019  #print "Border color : ", $images->Get('bordercolor'), "\n";
1020  #print "Matte color  : ", $images->Get('mattecolor'), "\n";
1021  #print "Pen color    : ", $images->Get('pen'), "\n";
1022
1023  # Do montage
1024  #print "Montage Options: $montageOptions\n";
1025  print("\$montage=\$images->Montage( $montageOptions )\n");
1026  eval "\$montage=\$images->Montage( $montageOptions ) ;";
1027  if( $@ ) {
1028    print "$@";
1029    print "not ok $test\n";
1030    return 1;
1031  }
1032
1033  if( ! ref($montage) ) {
1034    print "not ok $test\n";
1035  } else {
1036    # Check REF_8 signature
1037    # $montage->Display();
1038    $signature=$montage->GetAttribute('signature');
1039    if ( defined( $signature ) ) {
1040      if ( $signature ne $ref_signature ) {
1041        print "ReadImage()\n";
1042        print "Test $test, signatures do not match.\n";
1043      	print "     Expected: $ref_signature\n";
1044      	print "     Computed: $signature\n";
1045        print "     Depth:    ", Image::Magick->new()->QuantumDepth, "\n";
1046        $status = $montage->Write("test_${test}_out.miff");
1047        warn "Write: $status" if "$status";
1048
1049        print "not ok $test\n";
1050      } else {
1051        # Check montage directory
1052        my $directory = $montage->Get('directory');
1053        my $expected = join( "\xff", @colors ) . "\xff";
1054        if ( !defined($directory) ) {
1055          print "ok $test\n";
1056        } elsif ( $directory  ne $expected) {
1057          print("Invalid montage directory:\n\"$directory\"\n");
1058          print("Expected:\n\"$expected\"\n");
1059          print "not ok $test\n";
1060        } else {
1061          # Check montage geometry
1062          $montage_geom=$montage->Get('montage');
1063          if( !defined($montage_geom) ) {
1064            print("Montage geometry not defined!\n");
1065            print "not ok $test\n";
1066          } elsif ( $montage_geom !~ /^\d+x\d+\+\d+\+\d+$/ ) {
1067            print("Montage geometry not in correct format: \"$montage_geom\"\n");
1068            print "not ok $test\n";
1069          } else {
1070            print "ok $test\n";
1071          }
1072        }
1073      }
1074    } else {
1075      warn "GetAttribute returned undefined value!";
1076      print "not ok $test\n";
1077    }
1078  }
1079}
1080
1081#
1082# Test filter method using signature compare
1083#
1084# Usage: testFilterSignature( input image attributes, filter, options, expected REF_8
1085#      [, expected REF_16] );
1086#
1087sub testFilterSignature {
1088  my( $srcimage, $filter, $filter_options, $ref_8, $ref_16, $ref_32 ) = @_;
1089
1090  my($image, $ref_signature);
1091
1092#  print( $filter, " ...\n" );
1093
1094  if ( !defined( $ref_16 ) )
1095    {
1096      $ref_16 = $ref_8;
1097    }
1098  if ( !defined( $ref_32 ) )
1099    {
1100      $ref_32 = $ref_16;
1101    }
1102
1103  if (Image::Magick->new()->QuantumDepth == 32)
1104    {
1105      $ref_signature=$ref_32;
1106    }
1107  elsif (Image::Magick->new()->QuantumDepth == 16)
1108    {
1109      $ref_signature=$ref_16;
1110    }
1111  else
1112    {
1113      $ref_signature=$ref_8;
1114    }
1115
1116  # Create temporary image
1117  $image=Image::Magick->new;
1118
1119  $status=$image->ReadImage("$srcimage");
1120  warn "Readimage: $status" if "$status";
1121
1122  print("$filter\($filter_options\) ...\n");
1123  $image->$filter($filter_options);
1124#$image->write(filename=>"reference/filter/$filter.miff", compression=>'None');
1125
1126  $signature=$image->GetAttribute('signature');
1127  if ( defined( $signature ) ) {
1128    if ( $signature ne $ref_signature ) {
1129      print "Test $test, signatures do not match.\n";
1130      print "     Expected: $ref_signature\n";
1131      print "     Computed: $signature\n";
1132      print "     Depth:    ", Image::Magick->new()->QuantumDepth, "\n";
1133      #$image->Display();
1134      print "not ok $test\n";
1135    } else {
1136      print "ok $test\n";
1137    }
1138  } else {
1139    warn "GetAttribute returned undefined value!";
1140    print "not ok $test\n";
1141  }
1142}
1143
1144#
1145# Test filter method using comparison with reference image
1146#
1147# Usage: testFilterCompare( input image, input image options, reference image, filter, filter options,
1148#                           normalized_mean_error,
1149#                           normalized_maximum_error );
1150sub testFilterCompare {
1151  my ($srcimage_name, $src_read_options, $refimage_name, $filter,
1152      $filter_options, $normalized_mean_error_max,
1153      $normalized_maximum_error_max) = @_;
1154  my($srcimage, $refimage, $normalized_mean_error,
1155    $normalized_maximum_error);
1156  my($status,$errorinfo);
1157
1158  $errorinfo='';
1159  $status='';
1160
1161  #print( $filter, " ...\n" );
1162
1163  # Create images
1164  $srcimage=Image::Magick->new;
1165  $refimage=Image::Magick->new;
1166
1167  if ( "$src_read_options" ne "" ) {
1168    print("Set($src_read_options) ...\n");
1169    eval "\$status=\$srcimage->Set($src_read_options);";
1170    if ("$status")
1171      {
1172        $errorinfo = "Set($src_read_options): $status";
1173        goto COMPARE_RUNTIME_ERROR;
1174      }
1175  }
1176
1177  $status=$srcimage->ReadImage($srcimage_name);
1178  #eval "\$status=\$srcimage->ReadImage($srcimage_name);";
1179  if ("$status")
1180    {
1181      $errorinfo = "Readimage ($srcimage_name): $status";
1182      goto COMPARE_RUNTIME_ERROR;
1183    }
1184
1185  print("$filter\($filter_options\) ...\n");
1186  eval "\$status=\$srcimage->$filter($filter_options);";
1187  if ("$status")
1188    {
1189      $errorinfo = "$filter ($filter_options): $status";
1190      goto COMPARE_RUNTIME_ERROR;
1191    }
1192
1193  $srcimage->Clamp();
1194  $srcimage->set(depth=>8);
1195#  if ("$filter" eq "Shear") {
1196#    $srcimage->Display();
1197#    $srcimage->write(filename=>"$refimage_name", compression=>'None');
1198#  }
1199
1200  $status=$refimage->ReadImage("$refimage_name");
1201  if ("$status")
1202    {
1203      $errorinfo = "Readimage ($refimage_name): $status";
1204      goto COMPARE_RUNTIME_ERROR;
1205    }
1206
1207  # FIXME: The following statement should not be needed.
1208#  $status=$refimage->Set(type=>'TrueColor');
1209#  if ("$status")
1210#    {
1211#      $errorinfo = "Set(type=>'TrueColor'): $status";
1212#      goto COMPARE_RUNTIME_ERROR;
1213#    }
1214
1215  $status=$srcimage->Difference($refimage);
1216  if ("$status")
1217    {
1218      $errorinfo = "Difference($refimage_name): $status";
1219      print("  Reference: ", $refimage->Get('columns'), "x", $refimage->Get('rows'), "\n");
1220      print("  Computed:  ", $srcimage->Get('columns'), "x", $srcimage->Get('rows'), "\n");
1221      goto COMPARE_RUNTIME_ERROR;
1222    }
1223
1224  $normalized_mean_error=0;
1225  $normalized_mean_error=$srcimage->GetAttribute('mean-error');
1226  if ( !defined($normalized_mean_error) )
1227    {
1228      $errorinfo = "GetAttribute('mean-error') returned undefined value!";
1229      goto COMPARE_RUNTIME_ERROR;
1230    }
1231  $normalized_maximum_error=0;
1232  $normalized_maximum_error=$srcimage->GetAttribute('maximum-error');
1233  if ( ! defined($normalized_maximum_error) )
1234    {
1235      $errorinfo = "GetAttribute('maximum-error') returned undefined value!";
1236      goto COMPARE_RUNTIME_ERROR;
1237    }
1238  if ( ($normalized_mean_error > $normalized_mean_error_max) ||
1239       ($normalized_maximum_error > $normalized_maximum_error_max) )
1240    {
1241      print("  mean-error=$normalized_mean_error, maximum-error=$normalized_maximum_error\n");
1242      print "not ok $test\n";
1243      #$srcimage->Display();
1244      undef $srcimage;
1245      undef $refimage;
1246      return 1
1247    }
1248
1249  undef $srcimage;
1250  undef $refimage;
1251  print "ok $test\n";
1252  return 0;
1253
1254 COMPARE_RUNTIME_ERROR:
1255  undef $srcimage;
1256  undef $refimage;
1257  print("  $errorinfo\n");
1258  print "not ok $test\n";
1259  return 1
1260}
12611;
1262