our
$VERSION
=
'3.026'
;
our
$LAST_UPDATE
=
'3.026'
;
sub
new {
my
(
$class
,
$pdf
,
$file
,
%opts
) =
@_
;
if
(
defined
$opts
{
'-nouseGT'
} && !
defined
$opts
{
'nouseGT'
}) {
$opts
{
'nouseGT'
} =
delete
(
$opts
{
'-nouseGT'
}); }
if
(
defined
$opts
{
'-name'
} && !
defined
$opts
{
'name'
}) {
$opts
{
'name'
} =
delete
(
$opts
{
'-name'
}); }
if
(
defined
$opts
{
'-compress'
} && !
defined
$opts
{
'compress'
}) {
$opts
{
'compress'
} =
delete
(
$opts
{
'-compress'
}); }
my
(
$name
,
$compress
);
if
(
exists
$opts
{
'name'
}) {
$name
=
$opts
{
'name'
}; }
my
$self
;
my
$tif
= PDF::Builder::Resource::XObject::Image::TIFF::File->new(
$file
,
%opts
);
$class
=
ref
(
$class
)
if
ref
(
$class
);
$self
=
$class
->SUPER::new(
$pdf
,
$name
||
'Ix'
.pdfkey());
$pdf
->new_obj(
$self
)
unless
$self
->is_obj(
$pdf
);
$self
->{
' apipdf'
} =
$pdf
;
weaken
$self
->{
' apipdf'
};
$self
->read_tiff(
$pdf
,
$tif
);
$tif
->
close
();
return
$self
;
}
sub
usesLib {
my
(
$self
) =
shift
;
return
$self
->{
'usesGT'
}->val();
}
sub
handle_generic {
my
(
$self
,
$pdf
,
$tif
) =
@_
;
if
(
$tif
->{
'filter'
}) {
$self
->filters(
$tif
->{
'filter'
});
$self
->{
' nofilt'
} = 1;
}
else
{
$self
->filters(
'FlateDecode'
);
}
if
(
ref
(
$tif
->{
'imageOffset'
})) {
$self
->{
' stream'
} =
''
;
my
$d
=
scalar
@{
$tif
->{
'imageOffset'
}};
foreach
(1 ..
$d
) {
my
$buf
;
$tif
->{
'fh'
}->
seek
(
shift
(@{
$tif
->{
'imageOffset'
}}), 0);
$tif
->{
'fh'
}->
read
(
$buf
,
shift
(@{
$tif
->{
'imageLength'
}}));
$self
->{
' stream'
} .=
$buf
;
}
}
else
{
$tif
->{
'fh'
}->
seek
(
$tif
->{
'imageOffset'
}, 0);
$tif
->{
'fh'
}->
read
(
$self
->{
' stream'
},
$tif
->{
'imageLength'
});
}
return
$self
;
}
sub
handle_flate {
my
(
$self
,
$pdf
,
$tif
) =
@_
;
$self
->filters(
'FlateDecode'
);
if
(
ref
(
$tif
->{
'imageOffset'
})) {
$self
->{
' stream'
} =
''
;
my
$d
=
scalar
@{
$tif
->{
'imageOffset'
}};
foreach
(1 ..
$d
) {
my
$buf
;
$tif
->{
'fh'
}->
seek
(
shift
(@{
$tif
->{
'imageOffset'
}}), 0);
$tif
->{
'fh'
}->
read
(
$buf
,
shift
(@{
$tif
->{
'imageLength'
}}));
$buf
= uncompress(
$buf
);
$self
->{
' stream'
} .=
$buf
;
}
}
else
{
$tif
->{
'fh'
}->
seek
(
$tif
->{
'imageOffset'
}, 0);
$tif
->{
'fh'
}->
read
(
$self
->{
' stream'
},
$tif
->{
'imageLength'
});
$self
->{
' stream'
} = uncompress(
$self
->{
' stream'
});
}
return
$self
;
}
sub
handle_lzw {
my
(
$self
,
$pdf
,
$tif
) =
@_
;
$self
->{
' nofilt'
} = 1;
$self
->{
'Filter'
} = PDFArray(PDFName(
'LZWDecode'
));
my
$decode
= PDFDict();
$self
->{
'DecodeParms'
} = PDFArray(
$decode
);
$decode
->{
'Columns'
} = PDFNum(
$tif
->{
'imageWidth'
});
$decode
->{
'Rows'
} = PDFNum(
$tif
->{
'imageHeight'
});
$decode
->{
'DamagedRowsBeforeError'
} = PDFNum(100);
$decode
->{
'EndOfLine'
} = PDFBool(1);
$decode
->{
'EncodedByteAlign'
} = PDFBool(1);
if
(
defined
$tif
->{
'Predictor'
} and
$tif
->{
'Predictor'
} > 1) {
$decode
->{
'Predictor'
} = PDFNum(
$tif
->{
'Predictor'
});
}
if
(
ref
(
$tif
->{
'imageOffset'
})) {
$self
->{
' stream'
} =
''
;
my
$d
=
scalar
@{
$tif
->{
'imageOffset'
}};
foreach
(1 ..
$d
) {
$tif
->{
'fh'
}->
seek
(
shift
(@{
$tif
->{
'imageOffset'
}}), 0);
my
$buf
;
$tif
->{
'fh'
}->
read
(
$buf
,
shift
(@{
$tif
->{
'imageLength'
}}));
my
$filter
= PDF::Builder::Basic::PDF::Filter::LZWDecode->new();
$self
->{
' stream'
} .=
$filter
->infilt(
$buf
);
}
my
$filter
= PDF::Builder::Basic::PDF::Filter::LZWDecode->new();
$self
->{
' stream'
} =
$filter
->outfilt(
$self
->{
' stream'
});
}
else
{
$tif
->{
'fh'
}->
seek
(
$tif
->{
'imageOffset'
}, 0);
$tif
->{
'fh'
}->
read
(
$self
->{
' stream'
},
$tif
->{
'imageLength'
});
}
return
$self
;
}
sub
handle_ccitt {
my
(
$self
,
$pdf
,
$tif
) =
@_
;
$self
->{
' nofilt'
} = 1;
$self
->{
'Filter'
} = PDFName(
'CCITTFaxDecode'
);
$self
->{
'DecodeParms'
} = PDFDict();
$self
->{
'DecodeParms'
}->{
'K'
} = (
$tif
->{
'ccitt'
} == 4 ||
((
$tif
->{
'g3Options'
}||0) & 0x1))? PDFNum(-1): PDFNum(0);
$self
->{
'DecodeParms'
}->{
'Columns'
} = PDFNum(
$tif
->{
'imageWidth'
});
$self
->{
'DecodeParms'
}->{
'Rows'
} = PDFNum(
$tif
->{
'imageHeight'
});
$self
->{
'DecodeParms'
}->{
'BlackIs1'
} =
PDFBool((
$tif
->{
'whiteIsZero'
}||0) == 0? 1: 0);
if
(
defined
(
$tif
->{
'g3Options'
}) && (
$tif
->{
'g3Options'
} & 0x4)) {
$self
->{
'DecodeParms'
}->{
'EndOfLine'
} = PDFBool(1);
$self
->{
'DecodeParms'
}->{
'EncodedByteAlign'
} = PDFBool(1);
}
$self
->{
'DecodeParms'
}->{
'DamagedRowsBeforeError'
} = PDFNum(100);
if
(
ref
(
$tif
->{
'imageOffset'
})) {
die
"Chunked CCITT G4 TIFF not supported."
;
}
else
{
$tif
->{
'fh'
}->
seek
(
$tif
->{
'imageOffset'
}, 0);
$tif
->{
'fh'
}->
read
(
$self
->{
' stream'
},
$tif
->{
'imageLength'
});
}
return
$self
;
}
sub
read_tiff {
my
(
$self
,
$pdf
,
$tif
) =
@_
;
$self
->width(
$tif
->{
'imageWidth'
});
$self
->height(
$tif
->{
'imageHeight'
});
if
(
$tif
->{
'colorSpace'
} eq
'Indexed'
) {
my
$dict
= PDFDict();
$pdf
->new_obj(
$dict
);
$self
->colorspace(PDFArray(PDFName(
$tif
->{
'colorSpace'
}),
PDFName(
'DeviceRGB'
), PDFNum(2*
*$tif
->{
'bitsPerSample'
}-1),
$dict
));
$dict
->{
'Filter'
} = PDFArray(PDFName(
'FlateDecode'
));
$tif
->{
'fh'
}->
seek
(
$tif
->{
'colorMapOffset'
}, 0);
my
$colormap
;
my
$straight
;
$tif
->{
'fh'
}->
read
(
$colormap
,
$tif
->{
'colorMapLength'
});
$dict
->{
' stream'
} =
''
;
$straight
.=
pack
(
'C'
, (
$_
/256))
for
unpack
(
$tif
->{
'short'
} .
'*'
,
$colormap
);
foreach
my
$c
(0 .. ((
$tif
->{
'colorMapSamples'
}/3)-1)) {
$dict
->{
' stream'
} .=
substr
(
$straight
,
$c
, 1);
$dict
->{
' stream'
} .=
substr
(
$straight
,
$c
+ (
$tif
->{
'colorMapSamples'
}/3), 1);
$dict
->{
' stream'
} .=
substr
(
$straight
,
$c
+ (
$tif
->{
'colorMapSamples'
}/3)*2, 1);
}
}
else
{
$self
->colorspace(
$tif
->{
'colorSpace'
});
}
$self
->{
'Interpolate'
} = PDFBool(1);
$self
->bits_per_component(
$tif
->{
'bitsPerSample'
});
if
((
$tif
->{
'whiteIsZero'
}||0) == 1 &&
(
$tif
->{
'filter'
}||
''
) ne
'CCITTFaxDecode'
) {
$self
->{
'Decode'
} = PDFArray(PDFNum(1), PDFNum(0));
}
if
(
defined
$tif
->{
'filter'
} and
$tif
->{
'filter'
} eq
'CCITTFaxDecode'
) {
$self
->handle_ccitt(
$pdf
,
$tif
);
}
elsif
(
defined
$tif
->{
'filter'
} and
$tif
->{
'filter'
} eq
'LZWDecode'
) {
$self
->handle_lzw(
$pdf
,
$tif
);
}
elsif
(
defined
$tif
->{
'filter'
} and
$tif
->{
'filter'
} eq
'FlateDecode'
) {
$self
->handle_flate(
$pdf
,
$tif
);
}
else
{
$self
->handle_generic(
$pdf
,
$tif
);
}
if
(
$tif
->{
'fillOrder'
} == 2) {
my
@bl
= ();
foreach
my
$n
(0 .. 255) {
my
$b
=
$n
;
my
$f
= 0;
foreach
(0 .. 7) {
my
$bit
= 0;
if
(
$b
& 0x1) {
$bit
= 1;
}
$b
>>= 1;
$f
<<= 1;
$f
|=
$bit
;
}
$bl
[
$n
] =
$f
;
}
my
$l
=
length
(
$self
->{
' stream'
}) - 1;
foreach
my
$n
(0 ..
$l
) {
vec
(
$self
->{
' stream'
},
$n
, 8) =
$bl
[
vec
(
$self
->{
' stream'
},
$n
, 8)];
}
}
$self
->{
' tiff'
} =
$tif
;
return
$self
;
}
sub
tiffTag {
my
(
$self
,
$tag
) =
@_
;
return
$self
->{
' tiff'
}->{
$tag
};
}
1;