From: Tony Cook Date: Wed, 8 Jun 2011 12:25:45 +0000 (+1000) Subject: progressive JPEG support X-Git-Tag: v0.84~14 X-Git-Url: http://git.imager.perl.org/imager.git/commitdiff_plain/92e9df65d56e52f8db74e352cb02f2407ce55655 progressive JPEG support --- diff --git a/Changes b/Changes index 0d1d5222..1511f272 100644 --- a/Changes +++ b/Changes @@ -6,6 +6,9 @@ Imager 0.84 (** update GIF, TIFF, W32, PNG, JPEG, FT2 versions!) - Imager no longer inherits from Exporter (unless you're running an old, old perl. + - Imager can now write progressive JPEGs (it could always read them). + https://rt.cpan.org/Ticket/Display.html?id=68691 + Bug fixes: - re-work, document and test Imager's logging facility. diff --git a/JPEG/Changes b/JPEG/Changes index 5274b6a0..f8bfd45e 100644 --- a/JPEG/Changes +++ b/JPEG/Changes @@ -1,3 +1,8 @@ +Imager-File-JPEG 0.79 +===================== + + - add progressive support + Imager-File-JPEG 0.78 ===================== diff --git a/JPEG/imjpeg.c b/JPEG/imjpeg.c index 318965be..6854cb58 100644 --- a/JPEG/imjpeg.c +++ b/JPEG/imjpeg.c @@ -543,6 +543,14 @@ i_readjpeg_wiol(io_glue *data, int length, char** iptc_itext, int *itlength) { i_tags_set_float2(&im->tags, "i_yres", 0, yres, 6); } + /* I originally used jpeg_has_multiple_scans() here, but that can + * return true for non-progressive files too. The progressive_mode + * member is available at least as far back as 6b and does the right + * thing. + */ + i_tags_setn(&im->tags, "jpeg_progressive", + cinfo.progressive_mode ? 1 : 0); + (void) jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); *itlength=tlength; @@ -567,6 +575,7 @@ i_writejpeg_wiol(i_img *im, io_glue *ig, int qfactor) { double xres, yres; int comment_entry; int want_channels = im->channels; + int progressive = 0; struct jpeg_compress_struct cinfo; struct my_error_mgr jerr; @@ -618,6 +627,12 @@ i_writejpeg_wiol(i_img *im, io_glue *ig, int qfactor) { jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, quality, TRUE); /* limit to baseline-JPEG values */ + if (!i_tags_get_int(&im->tags, "jpeg_progressive", 0, &progressive)) + progressive = 0; + if (progressive) { + jpeg_simple_progression(&cinfo); + } + got_xres = i_tags_get_float(&im->tags, "i_xres", 0, &xres); got_yres = i_tags_get_float(&im->tags, "i_yres", 0, &yres); if (!i_tags_get_int(&im->tags, "i_aspect_only", 0,&aspect_only)) diff --git a/JPEG/t/t10jpeg.t b/JPEG/t/t10jpeg.t index 1512666f..2ca080cc 100644 --- a/JPEG/t/t10jpeg.t +++ b/JPEG/t/t10jpeg.t @@ -2,7 +2,7 @@ use strict; use Imager qw(:all); use Test::More; -use Imager::Test qw(is_color_close3 test_image_raw); +use Imager::Test qw(is_color_close3 test_image_raw test_image is_image); -d "testout" or mkdir "testout"; @@ -11,7 +11,7 @@ init_log("testout/t101jpeg.log",1); $Imager::formats{"jpeg"} or plan skip_all => "no jpeg support"; -plan tests => 94; +plan tests => 101; my $green=i_color_new(0,255,0,255); my $blue=i_color_new(0,0,255,255); @@ -408,4 +408,27 @@ SKIP: ok(grep($_ eq 'jpeg', Imager->write_types), "check jpeg in write types"); } +{ # progressive JPEG + # https://rt.cpan.org/Ticket/Display.html?id=68691 + my $im = test_image(); + my $progim = $im->copy; + ok($progim->write(file => "testout/t10prog.jpg", type => "jpeg", + jpeg_progressive => 1), + "write progressive jpeg"); + + my $rdprog = Imager->new(file => "testout/t10prog.jpg"); + ok($rdprog, "read progressive jpeg"); + my @prog = $rdprog->tags(name => "jpeg_progressive"); + is($prog[0], 1, "check progressive flag set on read"); + + my $data; + ok($im->write(data => \$data, type => "jpeg"), + "save as non-progressive to compare"); + my $norm = Imager->new(data => $data); + ok($norm, "read non-progressive file"); + my @nonprog = $norm->tags(name => "jpeg_progressive"); + is($nonprog[0], 0, "check progressive flag 0 for non prog file"); + + is_image($rdprog, $norm, "prog vs norm should be the same image"); +} diff --git a/lib/Imager/Files.pod b/lib/Imager/Files.pod index dcb1be5e..45faceb9 100644 --- a/lib/Imager/Files.pod +++ b/lib/Imager/Files.pod @@ -496,26 +496,32 @@ to control output: =over -=item C +=item * -The value of the density unit field in the C header. This is -ignored on writing if the C tag is non-zero. +C - The value of the density unit field in the +C header. This is ignored on writing if the C +tag is non-zero. The C and C tags are expressed in pixels per inch no matter the value of this tag, they will be converted to/from the value stored in the JPEG file. -=item C +=item * -This is set when reading a JPEG file to the name of the unit given by -C. Possible results include C, -C, C (the C tag is also set reading -these files). If the value of C is unknown then -this tag isn't set. +C - This is set when reading a JPEG file to +the name of the unit given by C. Possible results +include C, C, C (the C tag is +also set reading these files). If the value of C +is unknown then this tag isn't set. -=item C +=item * + +C - Text comment. + +=item * -Text comment. +C - Whether the JPEG file is a progressive +file. (Imager 0.84) =back