use of com.tom_roush.pdfbox.cos.COSDictionary in project PdfBox-Android by TomRoush.
the class PDInlineImageTest method testInlineImage.
/**
* Tests PDInlineImage#PDInlineImage(COSDictionary parameters, byte[] data,
* Map<String, PDColorSpace> colorSpaces)
*/
@Test
public void testInlineImage() throws IOException {
COSDictionary dict = new COSDictionary();
dict.setBoolean(COSName.IM, true);
int width = 31;
int height = 27;
dict.setInt(COSName.W, width);
dict.setInt(COSName.H, height);
dict.setInt(COSName.BPC, 1);
int rowbytes = width / 8;
if (rowbytes * 8 < width) {
// PDF spec:
// If the number of data bits per row is not a multiple of 8,
// the end of the row is padded with extra bits to fill out the last byte.
++rowbytes;
}
// draw a grid
int datalen = rowbytes * height;
byte[] data = new byte[datalen];
for (int i = 0; i < datalen; ++i) {
data[i] = (i / 4 % 2 == 0) ? (byte) Integer.parseInt("10101010", 2) : 0;
}
PDInlineImage inlineImage1 = new PDInlineImage(dict, data, null);
assertTrue(inlineImage1.isStencil());
assertEquals(width, inlineImage1.getWidth());
assertEquals(height, inlineImage1.getHeight());
assertEquals(1, inlineImage1.getBitsPerComponent());
COSDictionary dict2 = new COSDictionary();
dict2.addAll(dict);
// use decode array to revert in image2
COSArray decodeArray = new COSArray();
decodeArray.add(COSInteger.ONE);
decodeArray.add(COSInteger.ZERO);
dict2.setItem(COSName.DECODE, decodeArray);
PDInlineImage inlineImage2 = new PDInlineImage(dict2, data, null);
Paint paint = new Paint();
paint.setColor(Color.BLACK);
Bitmap stencilImage = inlineImage1.getStencilImage(paint);
assertEquals(width, stencilImage.getWidth());
assertEquals(height, stencilImage.getHeight());
Bitmap stencilImage2 = inlineImage2.getStencilImage(paint);
assertEquals(width, stencilImage2.getWidth());
assertEquals(height, stencilImage2.getHeight());
Bitmap image1 = inlineImage1.getImage();
assertEquals(width, image1.getWidth());
assertEquals(height, image1.getHeight());
Bitmap image2 = inlineImage2.getImage();
assertEquals(width, image2.getWidth());
assertEquals(height, image2.getHeight());
// write and read
boolean writeOk = image1.compress(Bitmap.CompressFormat.PNG, 100, new FileOutputStream(testResultsDir.getPath() + "/inline-grid1.png"));
assertTrue(writeOk);
Bitmap bim1 = BitmapFactory.decodeFile(new File(testResultsDir + "/inline-grid1.png").getPath());
assertNotNull(bim1);
assertEquals(width, bim1.getWidth());
assertEquals(height, bim1.getHeight());
writeOk = image2.compress(Bitmap.CompressFormat.PNG, 100, new FileOutputStream(testResultsDir.getPath() + "/inline-grid2.png"));
assertTrue(writeOk);
Bitmap bim2 = BitmapFactory.decodeFile(new File(testResultsDir + "/inline-grid2.png").getPath());
assertNotNull(bim2);
assertEquals(width, bim2.getWidth());
assertEquals(height, bim2.getHeight());
// compare: pixels with even coordinates are white (FF), all others are black (0)
int[] bimPixels = new int[width * height];
bim1.getPixels(bimPixels, 0, width, 0, 0, width, height);
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
if (x % 2 == 0 && y % 2 == 0) {
assertEquals(0xFFFFFF, bimPixels[x + width * y] & 0xFFFFFF);
} else {
assertEquals(0, bimPixels[x + width * y] & 0xFFFFFF);
}
}
}
// compare: pixels with odd coordinates are white (FF), all others are black (0)
bim2.getPixels(bimPixels, 0, width, 0, 0, width, height);
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
if (x % 2 == 0 && y % 2 == 0) {
assertEquals(0, bimPixels[x + width * y] & 0xFFFFFF);
} else {
assertEquals(0xFFFFFF, bimPixels[x + width * y] & 0xFFFFFF);
}
}
}
PDDocument document = new PDDocument();
PDPage page = new PDPage();
document.addPage(page);
PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, false);
contentStream.drawImage(inlineImage1, 150, 400);
contentStream.drawImage(inlineImage1, 150, 500, inlineImage1.getWidth() * 2, inlineImage1.getHeight() * 2);
contentStream.drawImage(inlineImage1, 150, 600, inlineImage1.getWidth() * 4, inlineImage1.getHeight() * 4);
contentStream.drawImage(inlineImage2, 350, 400);
contentStream.drawImage(inlineImage2, 350, 500, inlineImage2.getWidth() * 2, inlineImage2.getHeight() * 2);
contentStream.drawImage(inlineImage2, 350, 600, inlineImage2.getWidth() * 4, inlineImage2.getHeight() * 4);
contentStream.close();
File pdfFile = new File(testResultsDir, "inline.pdf");
document.save(pdfFile);
document.close();
document = PDDocument.load(pdfFile, (String) null);
new PDFRenderer(document).renderImage(0);
document.close();
}
use of com.tom_roush.pdfbox.cos.COSDictionary in project PdfBox-Android by TomRoush.
the class Filter method getDecodeParams.
// gets the decode params for a specific filter index, this is used to
// normalise the DecodeParams entry so that it is always a dictionary
protected COSDictionary getDecodeParams(COSDictionary dictionary, int index) {
COSBase filter = dictionary.getDictionaryObject(COSName.FILTER, COSName.F);
COSBase obj = dictionary.getDictionaryObject(COSName.DECODE_PARMS, COSName.DP);
if (filter instanceof COSName && obj instanceof COSDictionary) {
// but tests show that Adobe means "one filter name object".
return (COSDictionary) obj;
} else if (filter instanceof COSArray && obj instanceof COSArray) {
COSArray array = (COSArray) obj;
if (index < array.size()) {
COSBase objAtIndex = array.getObject(index);
if (objAtIndex instanceof COSDictionary) {
return (COSDictionary) array.getObject(index);
}
}
} else if (obj != null && !(filter instanceof COSArray || obj instanceof COSArray)) {
Log.e("PdfBox-Android", "Expected DecodeParams to be an Array or Dictionary but found " + obj.getClass().getName());
}
return new COSDictionary();
}
use of com.tom_roush.pdfbox.cos.COSDictionary in project PdfBox-Android by TomRoush.
the class LZWFilter method decode.
// BEWARE: codeTable must be local to each method, because there is only
// one instance of each filter
/**
* {@inheritDoc}
*/
@Override
public DecodeResult decode(InputStream encoded, OutputStream decoded, COSDictionary parameters, int index) throws IOException {
COSDictionary decodeParams = getDecodeParams(parameters, index);
int earlyChange = decodeParams.getInt(COSName.EARLY_CHANGE, 1);
if (earlyChange != 0 && earlyChange != 1) {
earlyChange = 1;
}
doLZWDecode(encoded, Predictor.wrapPredictor(decoded, decodeParams), earlyChange);
return new DecodeResult(parameters);
}
use of com.tom_roush.pdfbox.cos.COSDictionary in project PdfBox-Android by TomRoush.
the class CCITTFaxFilter method decode.
@Override
public DecodeResult decode(InputStream encoded, OutputStream decoded, COSDictionary parameters, int index) throws IOException {
// get decode parameters
COSDictionary decodeParms = getDecodeParams(parameters, index);
// parse dimensions
int cols = decodeParms.getInt(COSName.COLUMNS, 1728);
int rows = decodeParms.getInt(COSName.ROWS, 0);
int height = parameters.getInt(COSName.HEIGHT, COSName.H, 0);
if (rows > 0 && height > 0) {
// PDFBOX-771, PDFBOX-3727: rows in DecodeParms sometimes contains an incorrect value
rows = height;
} else {
// at least one of the values has to have a valid value
rows = Math.max(rows, height);
}
// decompress data
int k = decodeParms.getInt(COSName.K, 0);
boolean encodedByteAlign = decodeParms.getBoolean(COSName.ENCODED_BYTE_ALIGN, false);
int arraySize = (cols + 7) / 8 * rows;
// TODO possible options??
byte[] decompressed = new byte[arraySize];
CCITTFaxDecoderStream s;
int type;
long tiffOptions;
if (k == 0) {
tiffOptions = encodedByteAlign ? TIFFExtension.GROUP3OPT_BYTEALIGNED : 0;
type = TIFFExtension.COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE;
} else {
if (k > 0) {
tiffOptions = encodedByteAlign ? TIFFExtension.GROUP3OPT_BYTEALIGNED : 0;
tiffOptions |= TIFFExtension.GROUP3OPT_2DENCODING;
type = TIFFExtension.COMPRESSION_CCITT_T4;
} else {
// k < 0
tiffOptions = encodedByteAlign ? TIFFExtension.GROUP4OPT_BYTEALIGNED : 0;
type = TIFFExtension.COMPRESSION_CCITT_T6;
}
}
s = new CCITTFaxDecoderStream(encoded, cols, type, TIFFExtension.FILL_LEFT_TO_RIGHT, tiffOptions);
readFromDecoderStream(s, decompressed);
// invert bitmap
boolean blackIsOne = decodeParms.getBoolean(COSName.BLACK_IS_1, false);
if (!blackIsOne) {
// Inverting the bitmap
// Note the previous approach with starting from an IndexColorModel didn't work
// reliably. In some cases the image wouldn't be painted for some reason.
// So a safe but slower approach was taken.
invertBitmap(decompressed);
}
decoded.write(decompressed);
return new DecodeResult(parameters);
}
use of com.tom_roush.pdfbox.cos.COSDictionary in project PdfBox-Android by TomRoush.
the class PDStream method getFileDecodeParams.
/**
* Get the list of decode parameters. Each entry in the list will refer to
* an entry in the filters list.
*
* @return The list of decode parameters.
* @throws IOException if there is an error retrieving the parameters.
*/
public List<Object> getFileDecodeParams() throws IOException {
List<Object> retval = null;
COSBase dp = stream.getDictionaryObject(COSName.F_DECODE_PARMS);
if (dp instanceof COSDictionary) {
Map<?, ?> map = COSDictionaryMap.convertBasicTypesToMap((COSDictionary) dp);
retval = new COSArrayList<Object>(map, dp, stream, COSName.F_DECODE_PARMS);
} else if (dp instanceof COSArray) {
COSArray array = (COSArray) dp;
List<Object> actuals = new ArrayList<Object>();
for (int i = 0; i < array.size(); i++) {
actuals.add(COSDictionaryMap.convertBasicTypesToMap((COSDictionary) array.getObject(i)));
}
retval = new COSArrayList<Object>(actuals, array);
}
return retval;
}
Aggregations