Skip Menu |

This queue is for tickets about the PDF-API2 CPAN distribution.

Report information
The Basics
Id: 118047
Status: open
Priority: 0/
Queue: PDF-API2

People
Owner: Nobody in particular
Requestors: ppisar [...] redhat.com
Cc: jffry [...] posteo.net
AdminCc:

Bug Information
Severity: (no value)
Broken in: 2.028
Fixed in: (no value)



Subject: Adding 8bpp TIFF results in broken image
The following code creates a one-page PDF file and adds a TIFF image into the page: #!/usr/bin/perl use strict; use warnings; use PDF::API2; my $pdf = PDF::API2->new(-file => 'out.pdf'); my $page = $pdf->page; $page->mediabox(157, 196); my $imgobj = $pdf->image_tiff('8.tiff'); my $gfx = $page->gfx; $gfx->image($imgobj, 0, 0, 157, 196); $pdf->save; $pdf->end; The problem is the resulting PDF renderes the image broken if the TIFF image has 8 bit per pixel. It works fine if the image has only 1 bit per pixel. I attached the the two TIFF images and the resulting broken PDF file.
Subject: 1.tiff
Download 1.tiff
image/tiff 844b
1.tiff
Subject: 8.tiff
Download 8.tiff
image/tiff 1.8k
8.tiff
Subject: out.pdf
Download out.pdf
application/x-download 1.3k

Message body not shown because it is not plain text.

It's another lzw problem. 8.tiff is lzw compressed. If I uncompress it, (tiffcp -c none) PDF::API2 has no problem.
The attached patch fixed this for me, albeit by adding the dependency Graphics::TIFF, which uses libtiff to do the decompression. If you were happy with this approach, RT 84665 could be fixed in the same way. I was unable to come up with a G3-encoded TIFF that the current version of PDF::API2 accepts. If you can find a way of generating one, then I can update the tests. Alternatively, I can simply implement G3 and G4 support without worrying about the old approach.
Subject: 0001-Fix-IO-Handle-warnings-from-Debian-bug-622078.patch
From 15d142b167312cf5fa52eda2dcd0a39aa58fc747 Mon Sep 17 00:00:00 2001 From: Jeffrey Ratcliffe <Jeffrey.Ratcliffe@gmail.com> Date: Tue, 4 Oct 2016 17:49:09 +0200 Subject: [PATCH] Fix IO::Handle warnings from Debian bug #622078 --- lib/PDF/API2/Resource/XObject/Image/TIFF.pm | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/PDF/API2/Resource/XObject/Image/TIFF.pm b/lib/PDF/API2/Resource/XObject/Image/TIFF.pm index 154006e..b79a3b4 100644 --- a/lib/PDF/API2/Resource/XObject/Image/TIFF.pm +++ b/lib/PDF/API2/Resource/XObject/Image/TIFF.pm @@ -372,6 +372,7 @@ sub new { $fh->seek( $self->{offset}, 0 ); # checking byte order of data + $self->{byteOrder} = undef; # suppress warning from IO::Handle $fh->read( $self->{byteOrder}, 2 ); $self->{byte}='C'; $self->{short}=(($self->{byteOrder} eq 'MM') ? 'n' : 'v' ); @@ -379,11 +380,13 @@ sub new { $self->{rational}=(($self->{byteOrder} eq 'MM') ? 'NN' : 'VV' );; # get/check version id + $self->{version} = undef; # suppress warning from IO::Handle $fh->read( $self->{version}, 2 ); $self->{version}=unpack($self->{short},$self->{version}); die "Wrong TIFF Id '$self->{version}' (should be 42)." if($self->{version} != 42); # get the offset to the first tag directory. + $self->{ifdOffset} = undef; # suppress warning from IO::Handle $fh->read( $self->{ifdOffset}, 4 ); $self->{ifdOffset}=unpack($self->{long},$self->{ifdOffset}); @@ -457,6 +460,7 @@ sub readTags { while($self->{ifd} > 0) { $fh->seek( $self->{ifd}, 0 ); + $self->{ifdNum} = undef; # suppress warning from IO::Handle $fh->read( $self->{ifdNum}, 2 ); $self->{ifdNum}=unpack($self->{short},$self->{ifdNum}); $self->{bitsPerSample}=1; @@ -531,12 +535,14 @@ sub readTags { # ImageDescription my $here=$fh->tell; $fh->seek($valOffset,0); + $self->{imageDescription} = undef; # suppress warning from IO::Handle $fh->read($self->{imageDescription},$valLen); $fh->seek($here,0); } elsif($valTag==282) { # xRes my $here=$fh->tell; $fh->seek($valOffset,0); + $self->{xRes} = undef; # suppress warning from IO::Handle $fh->read($self->{xRes},$valLen); $fh->seek($here,0); $self->{xRes}=[unpack($self->{rational},$self->{xRes})]; @@ -545,6 +551,7 @@ sub readTags { # yRes my $here=$fh->tell; $fh->seek($valOffset,0); + $self->{yRes} = undef; # suppress warning from IO::Handle $fh->read($self->{yRes},$valLen); $fh->seek($here,0); $self->{yRes}=[unpack($self->{rational},$self->{yRes})]; @@ -598,6 +605,7 @@ sub readTags { # imageID my $here=$fh->tell; $fh->seek($valOffset,0); + $self->{imageId} = undef; # suppress warning from IO::Handle $fh->read($self->{imageId},$valLen); $fh->seek($here,0); # } elsif($valTag==) { -- 2.4.4
Sorry. Attached wrong patch. Please try this.
Subject: 0001-Use-libtiff-to-decode-image-data-in-TIFF-fixing-RT-1.patch

Message body is not shown because it is too large.

Grrr. My previous patch didn't apply cleanly to v2.033. This one does.
Subject: 0001-Use-libtiff-to-decode-image-data-in-TIFF-fixing-RT-1.patch

Message body is not shown because it is too large.

Because of the nature of libTIFF, it is not possible to pass an open filehandle.
Subject: Re: [rt.cpan.org #118047] Adding 8bpp TIFF results in broken image
Date: Fri, 28 Jul 2017 14:14:58 +0200
To: Jeffrey Ratcliffe via RT <bug-PDF-API2 [...] rt.cpan.org>
From: Petr Pisar <ppisar [...] redhat.com>
On Thu, Jul 27, 2017 at 04:10:14AM -0400, Jeffrey Ratcliffe via RT wrote: Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=118047 > > > Grrr. My previous patch didn't apply cleanly to v2.033. This one does.
Thank you for the patch. I tested it successfully. All PDF-API2 tests pass for me as well as the reproducer I attached to original bug report. I obtained the TIFF image when debugging gscan2pdf tool. It was produced by ImageMagic >= 6.9.3-0. The procedure is at <https://github.com/ImageMagick/ImageMagick/issues/277>. -- Petr
Download signature.asc
application/pgp-signature 213b

Message body not shown because it is not plain text.

On Fri Jul 14 11:44:50 2017, RATCLIFFE wrote: Show quoted text
> The attached patch fixed this for me, albeit by adding the dependency > Graphics::TIFF, which uses libtiff to do the decompression.
Thanks for working on this! Would it be possible to check whether Graphics::TIFF is installed at runtime, then use it if it's present? I'm hesitant to add a dependency that isn't pure-Perl. Then, if Graphics::TIFF isn't present and there's an attempt to work with a TIFF file that isn't supported by the existing code in PDF::API2, we could give an error recommending that Graphics::TIFF get installed for broader TIFF support.
Show quoted text
> Would it be possible to check whether Graphics::TIFF is installed at > runtime, then use it if it's present? I'm hesitant to add a > dependency that isn't pure-Perl. Then, if Graphics::TIFF isn't > present and there's an attempt to work with a TIFF file that isn't > supported by the existing code in PDF::API2, we could give an error > recommending that Graphics::TIFF get installed for broader TIFF > support.
Of course, it is possible to check for Graphics::TIFF. My suggestion, however, would be that if it isn't present, then to completely disable the TIFF support, as the current code is hopelessly buggy. Just out of interest, is your problem with non-pure-Perl code Windows support or something else?
Show quoted text
> Just out of interest, is your problem with non-pure-Perl code Windows > support or something else?
Three things: 1) Windows support. 2) Ease of installation on any platform. Right now, it installs cleanly from CPAN with no additional steps. I'd prefer not to give that up. 3) Backwards compatibility. The existing TIFF code is in use and working for some people's needs (based on bug reports, in any case, which are of the "it doesn't work in this case" variety vs. "it doesn't work at all"). If those people aren't in a position to install libtiff, I don't want the next version to break their code. Since most TIFF-using people can probably benefit from using Graphics::TIFF, a simpler implementation might be to print a deprecation warning if Graphics::TIFF isn't installed and then fall back to the current code, and let it error or not as it currently does.
I can see that I'm on my own here (apart from the OP), so I'll stop arguing about non-pure-Perl stuff. How about this? If Graphics::TIFF is installed, it uses it, otherwise it prints a warning and uses the legacy code.
Subject: optionally-use-libtiff-for-handling-TIFFs-fixing-RT-1.patch
diff --git a/Makefile.PL b/Makefile.PL index 62e446b..c2bc047 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -18,7 +18,8 @@ my %WriteMakefileArgs = ( "NAME" => "PDF::API2", "PREREQ_PM" => { "Compress::Zlib" => "1.0", - "Font::TTF" => 0 + "Font::TTF" => 0, + "Try::Tiny" => 0, }, "TEST_REQUIRES" => { "Test::Exception" => 0, diff --git a/lib/PDF/API2/Resource/XObject/Image/TIFF.pm b/lib/PDF/API2/Resource/XObject/Image/TIFF.pm index fd283a5..da8a10e 100644 --- a/lib/PDF/API2/Resource/XObject/Image/TIFF.pm +++ b/lib/PDF/API2/Resource/XObject/Image/TIFF.pm @@ -15,6 +15,7 @@ use PDF::API2::Basic::PDF::Utils; use PDF::API2::Resource::XObject::Image::TIFF::File; use PDF::API2::Util; use Scalar::Util qw(weaken); +use Try::Tiny; =head1 NAME @@ -32,6 +33,19 @@ Returns a tiff-image object. sub new { my ($class, $pdf, $file, $name) = @_; + try { + require Graphics::TIFF; + require PDF::API2::Resource::XObject::Image::TIFF_XS; + return PDF::API2::Resource::XObject::Image::TIFF_XS->new($pdf, $file, $name); + } + catch { + if (/Graphics\/TIFF[.]pm/xsm) { + warn "Install Graphics::TIFF for better TIFF support in PDF::API2\n"; + } + else { + die $_; + } + }; my $self; my $tif = PDF::API2::Resource::XObject::Image::TIFF::File->new($file); diff --git a/t/tiff.t b/t/tiff.t index b39501c..1cb5fd8 100644 --- a/t/tiff.t +++ b/t/tiff.t @@ -1,4 +1,4 @@ -use Test::More tests => 8; +use Test::More tests => 9; use warnings; use strict; @@ -22,19 +22,6 @@ $gfx->image($tiff, 72, 144, 216, 288); like($pdf->stringify(), qr/q 216 0 0 288 72 144 cm \S+ Do Q/, q{Add TIFF to PDF}); -# Filehandle - -$pdf = PDF::API2->new(); -open my $fh, '<', 't/resources/1x1.tif'; -$tiff = $pdf->image_tiff($fh); -isa_ok($tiff, 'PDF::API2::Resource::XObject::Image::TIFF', - q{$pdf->image_tiff(filehandle)}); - -is($tiff->width(), 1, - q{Image from filehandle has a width}); - -close $fh; - # LZW Compression $pdf = PDF::API2->new(); @@ -55,3 +42,72 @@ like($pdf->stringify(), qr/q 216 0 0 432 72 360 cm \S+ Do Q/, $pdf = PDF::API2->new(); eval { $pdf->image_tiff('t/resources/this.file.does.not.exist') }; ok($@, q{Fail fast if the requested file doesn't exist}); + +############################################################## + +my $width = 568; +my $height = 1000; +$tiff = 'test.tif'; +my $pdfout = 'test.pdf'; + +SKIP: { + skip "tiff2pdf doesn't deal with the alpha layer properly either in this case", 1; +system(sprintf"convert -depth 1 -gravity center -pointsize 78 -size %dx%d caption:'Lorem ipsum etc etc' %s", $width, $height, $tiff); +$pdf = PDF::API2->new(-file => $pdfout); +my $page = $pdf->page; +$page->mediabox( $width, $height ); +$gfx = $page->gfx; +my $img = $pdf->image_tiff($tiff); +$gfx->image( $img, 0, 0, $width, $height ); +$pdf->save; +$pdf->end; + +my $example = `convert $pdfout -depth 1 -resize 1x1 txt:-`; +my $expected = `convert $tiff -depth 1 -resize 1x1 txt:-`; + +is($example, $expected, 'alpha'); +} + +############################################################## + +SKIP: { + skip "files created with tiffcp -c g3 previously produced the 'message chunked ccitt g4 tif not supported'", 1; +system(sprintf"convert -depth 1 -gravity center -pointsize 78 -size %dx%d caption:'Lorem ipsum etc etc' -background white -alpha off %s", $width, $height, $tiff); +system("tiffcp -c g3 $tiff tmp.tif && mv tmp.tif $tiff"); +$pdf = PDF::API2->new(-file => $pdfout); +my $page = $pdf->page; +$page->mediabox( $width, $height ); +$gfx = $page->gfx; +my $img = $pdf->image_tiff($tiff); +$gfx->image( $img, 0, 0, $width, $height ); +$pdf->save; +$pdf->end; + +my $example = `convert $pdfout -depth 1 -resize 1x1 txt:-`; +my $expected = `convert $tiff -depth 1 -resize 1x1 txt:-`; + +is($example, $expected, 'g3 (not converted to flate)'); +} +############################################################## + +system(sprintf"convert -depth 1 -gravity center -pointsize 78 -size %dx%d caption:'Lorem ipsum etc etc' -background white -alpha off %s", $width, $height, $tiff); +system("tiffcp -c lzw $tiff tmp.tif && mv tmp.tif $tiff"); +$pdf = PDF::API2->new(-file => $pdfout); +my $page = $pdf->page; +$page->mediabox( $width, $height ); +$gfx = $page->gfx; +my $img = $pdf->image_tiff($tiff); +$gfx->image( $img, 0, 0, $width, $height ); +$pdf->save; +$pdf->end; + +my $example = `convert $pdfout -depth 1 -colorspace gray -alpha off -resize 1x1 txt:-`; +my $expected = `convert $tiff -depth 1 -resize 1x1 txt:-`; + +is($example, $expected, 'lzw (converted to flate)'); + +############################################################## + +unlink $pdfout, $tiff; + +##############################################################
Grr. git diff does include newly added files, so it's missed half the patch. Please try this.
Subject: 0001-Optionally-use-libtiff-for-handling-TIFFs.patch

Message body is not shown because it is too large.

On Fri Nov 17 04:10:37 2017, RATCLIFFE wrote: Show quoted text
> Grr. git diff does include newly added files, so it's missed half the > patch.
I’ve run into that problem myself many times. What I now do is something like: $ touch foo/bar $ git add foo/bar .... make changes .... $ git diff
FYI, this is fixed in PDF::Builder (requires use of optional Graphics::TIFF library)