]> git.imager.perl.org - imager.git/commitdiff
various JPEG fixes
authorTony Cook <tony@develop=help.com>
Wed, 22 Aug 2001 00:49:25 +0000 (00:49 +0000)
committerTony Cook <tony@develop=help.com>
Wed, 22 Aug 2001 00:49:25 +0000 (00:49 +0000)
Changes
Imager.pm
jpeg.c
t/t101jpeg.t

diff --git a/Changes b/Changes
index 2d5f0285ddc6870b476e914801879b9310b9c555..caa23e7b2f8723468d006c3983984716790ed28c 100644 (file)
--- a/Changes
+++ b/Changes
@@ -477,6 +477,9 @@ Revision history for Perl extension Imager.
         - added OO interfaces for the mosaic, bumpmap, postlevels and
           watermark filters
         - added t/t61filters.t to test the filters
+       - fixed some problems in jpeg handling from the exp_represent merge
+        - fixed buffer flushing for wiol jpeg code
+       - added some tests that will hopefully catch it in the future
 
 =================================================================
 
index 6eed0e0bc384673c86ca8d1eaee0a4bebd4f574d..a091901bde97bc991828ff7bda0f2b604518dcf3 100644 (file)
--- a/Imager.pm
+++ b/Imager.pm
@@ -52,7 +52,6 @@ use Imager::Font;
                i_haar
                i_count_colors
 
-
                i_gaussian
                i_conv
 
@@ -365,7 +364,6 @@ sub new {
   return $self;
 }
 
-
 # Copy an entire image with no changes 
 # - if an image has magic the copy of it will not be magical
 
@@ -736,7 +734,7 @@ sub read {
   # yes the code isn't here yet - next week maybe?
   # Next week?  Are you high or something?  That comment
   # has been there for half a year dude.
-
+  # Look, i just work here, ok?
 
   if (!$input{type} and $input{file}) {
     $input{type}=$FORMATGUESS->($input{file});
@@ -821,7 +819,6 @@ sub read {
 
     # Old code for reference while changing the new stuff
 
-
     if (!$input{type} and $input{file}) {
       $input{type}=$FORMATGUESS->($input{file});
     }
@@ -879,29 +876,18 @@ sub read {
       }
       $self->{DEBUG} && print "loading a gif file\n";
     }
-
-    if ( $input{type} eq 'jpeg' ) {
-      if ( !i_writejpeg_wiol($self->{IMG}, $IO, $input{jpegquality})) {
-       $self->{ERRSTR}='unable to write jpeg image'; 
-       return undef;
-      }
-      $self->{DEBUG} && print "writing a jpeg file\n";
-    }
-
   }
   return $self;
 }
 
-
 # Write an image to file
-
 sub write {
   my $self = shift;
   my %input=(jpegquality=>75, gifquant=>'mc', lmdither=>6.0, lmfixed=>[], 
             fax_fine=>1, @_);
   my ($fh, $rc, $fd, $IO);
 
-  my %iolready=( tiff=>1, raw=>1, png=>1, pnm=>1, bmp=>1, ); # this will be SO MUCH BETTER once they are all in there
+  my %iolready=( tiff=>1, raw=>1, png=>1, pnm=>1, bmp=>1, jpeg=>1 ); # this will be SO MUCH BETTER once they are all in there
 
   unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
 
@@ -957,6 +943,12 @@ sub write {
        return undef;
       }
       $self->{DEBUG} && print "writing a png file\n";
+    } elsif ( $input{type} eq 'jpeg' ) {
+      if ( !i_writejpeg_wiol($self->{IMG}, $IO, $input{jpegquality})) {
+       $self->{ERRSTR}='unable to write jpeg image'; 
+       return undef;
+      }
+      $self->{DEBUG} && print "writing a jpeg file\n";
     } elsif ( $input{type} eq 'bmp' ) {
       if ( !i_writebmp_wiol($self->{IMG}, $IO) ) {
        $self->{ERRSTR}='unable to write bmp image';
@@ -975,7 +967,6 @@ sub write {
     }
     return $self;
   } else {
-
     if ( $input{type} eq 'gif' ) {
       if (not $input{gifplanes}) {
        my $gp;
diff --git a/jpeg.c b/jpeg.c
index 6aba12524aa6f2febc568623a4716c1437423906..5796f0034fb0d328a4b83f2b25a62ee5a64ceb9e 100644 (file)
--- a/jpeg.c
+++ b/jpeg.c
@@ -177,14 +177,23 @@ wiol_init_destination (j_compress_ptr cinfo) {
 static boolean
 wiol_empty_output_buffer(j_compress_ptr cinfo) {
   wiol_dest_ptr dest = (wiol_dest_ptr) cinfo->dest;
-  ssize_t nbytes     = JPGS - dest->pub.free_in_buffer;
   ssize_t rc;
+  /*
+    Previously this code was checking free_in_buffer to see how much 
+    needed to be written.  This does not follow the documentation:
+
+                       "In typical applications, it should write out the
+        *entire* buffer (use the saved start address and buffer length;
+        ignore the current state of next_output_byte and free_in_buffer)."
+
+  ssize_t nbytes     = JPGS - dest->pub.free_in_buffer;
+  */
 
   mm_log((1,"wiol_emtpy_output_buffer(cinfo 0x%p)\n"));
-  rc = dest->data->writecb(dest->data, dest->buffer, nbytes);
+  rc = dest->data->writecb(dest->data, dest->buffer, JPGS);
   
-  if (rc != nbytes) { /* XXX: Should raise some jpeg error */
-    mm_log((1, "wiol_empty_output_buffer: Error: nbytes = %d != rc = %d\n", nbytes, rc));
+  if (rc != JPGS) { /* XXX: Should raise some jpeg error */
+    mm_log((1, "wiol_empty_output_buffer: Error: nbytes = %d != rc = %d\n", JPGS, rc));
   }
   dest->pub.free_in_buffer = JPGS;
   dest->pub.next_output_byte = dest->buffer;
@@ -194,6 +203,12 @@ wiol_empty_output_buffer(j_compress_ptr cinfo) {
 static void
 wiol_term_destination (j_compress_ptr cinfo) {
   wiol_dest_ptr dest = (wiol_dest_ptr) cinfo->dest;
+
+  /* yes, this needs to flush the buffer */
+  /* needs error handling */
+  dest->data->writecb(dest->data, dest->buffer, 
+                     JPGS - dest->pub.free_in_buffer);
+
   mm_log((1, "wiol_term_destination(cinfo %p)\n", cinfo));
   mm_log((1, "wiol_term_destination: dest %p\n", cinfo->dest));
   if (dest != NULL) myfree(dest->buffer);
index 8043c8cb09c07d9a7fdfcf1e1c2a8ae5f0250086..00c09e6a5bd0a1ad97f0127c048c22cde6774c44 100644 (file)
@@ -1,6 +1,6 @@
 use Imager qw(:all);
 
-print "1..2\n";
+print "1..7\n";
 
 init_log("testout/t101jpeg.log",1);
 
@@ -18,8 +18,9 @@ i_conv($img,[0.1, 0.2, 0.4, 0.2, 0.1]);
 
 i_has_format("jpeg") && print "# has jpeg\n";
 if (!i_has_format("jpeg")) {
-  print "ok 1 # skip no jpeg support\n";
-  print "ok 2 # skip no jpeg support\n";
+  for (1..7) {
+    print "ok $_ # skip no jpeg support\n";
+  }
 } else {
   open(FH,">testout/t101.jpg") || die "cannot open testout/t101.jpg for writing\n";
   binmode(FH);
@@ -36,7 +37,24 @@ if (!i_has_format("jpeg")) {
   close(FH);
 
   print "$cmpimg\n";
-
-  print "# jpeg average mean square pixel difference: ",sqrt(i_img_diff($img,$cmpimg))/150*150,"\n";
+  my $diff = sqrt(i_img_diff($img,$cmpimg))/150*150;
+  print "# jpeg average mean square pixel difference: ",$diff,"\n";
   print "ok 2\n";
+
+  $diff < 10000 or print "not ";
+  print "ok 3\n";
+
+  my $imoo = Imager->new;
+  $imoo->read(file=>'testout/t101.jpg') or print "not ";
+  print "ok 4\n";
+  $imoo->write(file=>'testout/t101_oo.jpg') or print "not ";
+  print "ok 5\n";
+  my $oocmp = Imager->new;
+  $oocmp->read(file=>'testout/t101_oo.jpg') or print "not ";
+  print "ok 6\n";
+
+  $diff = sqrt(i_img_diff($imoo->{IMG},$oocmp->{IMG}))/150*150;
+  print "# OO image difference $diff\n";
+  $diff < 10000 or print "not ";
+  print "ok 7\n";
 }