Code with Finding: |
class PdfImageObject {
/**
* decodes the bytes currently captured in the streamBytes and replaces it with an image representation of the bytes
* (this will either be a png or a tiff, depending on the color depth of the image)
* @throws IOException
*/
private void decodeImageBytes() throws IOException{
if (streamContentType != null)
throw new IllegalStateException(MessageLocalization.getComposedMessage("Decoding.can't.happen.on.this.type.of.stream.(.1.)", streamContentType));
pngColorType = -1;
PdfArray decode = dictionary.getAsArray(PdfName.DECODE);
width = dictionary.getAsNumber(PdfName.WIDTH).intValue();
height = dictionary.getAsNumber(PdfName.HEIGHT).intValue();
bpc = dictionary.getAsNumber(PdfName.BITSPERCOMPONENT).intValue();
pngBitDepth = bpc;
PdfObject colorspace = dictionary.getDirectObject(PdfName.COLORSPACE);
if (colorspace instanceof PdfName && colorSpaceDic != null){
PdfObject csLookup = colorSpaceDic.getDirectObject((PdfName)colorspace);
if (csLookup != null)
colorspace = csLookup;
}
palette = null;
icc = null;
stride = 0;
findColorspace(colorspace, true);
ByteArrayOutputStream ms = new ByteArrayOutputStream();
if (pngColorType < 0) {
if (bpc != 8)
throw new UnsupportedPdfException(MessageLocalization.getComposedMessage("the.color.depth.1.is.not.supported", bpc));
if (PdfName.DEVICECMYK.equals(colorspace)) {
}
else if (colorspace instanceof PdfArray) {
PdfArray ca = (PdfArray)colorspace;
PdfObject tyca = ca.getDirectObject(0);
if (!PdfName.ICCBASED.equals(tyca))
throw new UnsupportedPdfException(MessageLocalization.getComposedMessage("the.color.space.1.is.not.supported", colorspace));
PRStream pr = (PRStream)ca.getDirectObject(1);
int n = pr.getAsNumber(PdfName.N).intValue();
if (n != 4) {
throw new UnsupportedPdfException(MessageLocalization.getComposedMessage("N.value.1.is.not.supported", n));
}
icc = PdfReader.getStreamBytes(pr);
}
else
throw new UnsupportedPdfException(MessageLocalization.getComposedMessage("the.color.space.1.is.not.supported", colorspace));
stride = 4 * width;
TiffWriter wr = new TiffWriter();
wr.addField(new TiffWriter.FieldShort(TIFFConstants.TIFFTAG_SAMPLESPERPIXEL, 4));
wr.addField(new TiffWriter.FieldShort(TIFFConstants.TIFFTAG_BITSPERSAMPLE, new int[]{8,8,8,8}));
wr.addField(new TiffWriter.FieldShort(TIFFConstants.TIFFTAG_PHOTOMETRIC, TIFFConstants.PHOTOMETRIC_SEPARATED));
wr.addField(new TiffWriter.FieldLong(TIFFConstants.TIFFTAG_IMAGEWIDTH, width));
wr.addField(new TiffWriter.FieldLong(TIFFConstants.TIFFTAG_IMAGELENGTH, height));
wr.addField(new TiffWriter.FieldShort(TIFFConstants.TIFFTAG_COMPRESSION, TIFFConstants.COMPRESSION_LZW));
wr.addField(new TiffWriter.FieldShort(TIFFConstants.TIFFTAG_PREDICTOR, TIFFConstants.PREDICTOR_HORIZONTAL_DIFFERENCING));
wr.addField(new TiffWriter.FieldLong(TIFFConstants.TIFFTAG_ROWSPERSTRIP, height));
wr.addField(new TiffWriter.FieldRational(TIFFConstants.TIFFTAG_XRESOLUTION, new int[]{300,1}));
wr.addField(new TiffWriter.FieldRational(TIFFConstants.TIFFTAG_YRESOLUTION, new int[]{300,1}));
wr.addField(new TiffWriter.FieldShort(TIFFConstants.TIFFTAG_RESOLUTIONUNIT, TIFFConstants.RESUNIT_INCH));
wr.addField(new TiffWriter.FieldAscii(TIFFConstants.TIFFTAG_SOFTWARE, Document.getVersion()));
ByteArrayOutputStream comp = new ByteArrayOutputStream();
TiffWriter.compressLZW(comp, 2, imageBytes, height, 4, stride);
byte[] buf = comp.toByteArray();
wr.addField(new TiffWriter.FieldImage(buf));
wr.addField(new TiffWriter.FieldLong(TIFFConstants.TIFFTAG_STRIPBYTECOUNTS, buf.length));
if (icc != null)
wr.addField(new TiffWriter.FieldUndefined(TIFFConstants.TIFFTAG_ICCPROFILE, icc));
wr.writeFile(ms);
streamContentType = ImageBytesType.CCITT;
imageBytes = ms.toByteArray();
return;
} else {
PngWriter png = new PngWriter(ms);
if (decode != null){
if (pngBitDepth == 1){
// if the decode array is 1,0, then we need to invert the image
if(decode.getAsNumber(0).intValue() == 1 && decode.getAsNumber(1).intValue() == 0){
int len = imageBytes.length;
for (int t = 0; t < len; ++t) {
imageBytes[t] ^= 0xff;
}
} else {
// if the decode array is 0,1, do nothing. It's possible that the array could be 0,0 or 1,1 - but that would be silly, so we'll just ignore that case
}
} else {
// todo: add decode transformation for other depths
}
}
png.writeHeader(width, height, pngBitDepth, pngColorType);
if (icc != null)
png.writeIccProfile(icc);
if (palette != null)
png.writePalette(palette);
png.writeData(imageBytes, stride);
png.writeEnd();
streamContentType = ImageBytesType.PNG;
imageBytes = ms.toByteArray();
}
}
}
|