public ColorMapping(PdfObjectReader currentPdfFile, PdfObject functionObj) { // needed for this class functionType = functionObj.getInt(PdfDictionary.FunctionType); /** setup the translation function */ function = FunctionFactory.getFunction(functionObj, currentPdfFile); }
public void checkParentForResources(final PdfObject pdfObject) { /** if no resource, check parent for one (in theory should recurse up whole tree) */ if (pdfObject.getDictionary(PdfDictionary.Resources) == null) { final String parent = pdfObject.getStringKey(PdfDictionary.Parent); if (parent != null) { final PdfObject parentObj = new PageObject(parent); readObject(parentObj); final PdfObject resObj = parentObj.getDictionary(PdfDictionary.Resources); if (resObj != null) { pdfObject.setDictionary(PdfDictionary.Resources, resObj); } } } }
public CCITT(PdfObject decodeParms, int width, int height) { super(decodeParms); this.width = width; this.height = height; // check JAI loaded on first call JAIHelper.confirmJAIOnClasspath(); // get EncodedByteAligned if (decodeParms != null) EncodedByteAligned = decodeParms.getBoolean(PdfDictionary.EncodedByteAlign); }
public static int setNameTreeValue( final PdfObject pdfObject, int i, final byte[] raw, final int length, final boolean ignoreRecursion, final int PDFkeyInt, final PdfFileReader objectReader) { boolean isRef = false; // move to start while (raw[i] != '[') { // can be number as well if (raw[i] == '(') { // allow for W (7) isRef = false; break; } // allow for number as in refer 9 0 R if (raw[i] >= '0' && raw[i] <= '9') { isRef = true; break; } i++; } // allow for direct or indirect byte[] data = raw; int start = i, j = i; int count = 0; // read ref data and slot in if (isRef) { // number final int[] values = StreamReaderUtils.readRefFromStream(raw, i); i = values[2]; final int generation = values[1]; final int number = values[0]; if (raw[i] != 82) // we are expecting R to end ref { throw new RuntimeException( "3. Unexpected value in file " + raw[i] + " - please send to IDRsolutions for analysis"); } if (!ignoreRecursion) { // read the Dictionary data data = objectReader.readObjectAsByteArray( pdfObject, objectReader.isCompressed(number, generation), number, generation); // allow for data in Linear object not yet loaded if (data == null) { pdfObject.setFullyResolved(false); if (debugFastCode) { System.out.println(padding + "Data not yet loaded"); } i = length; return i; } // lose obj at start j = 3; while (data[j - 1] != 106 && data[j - 2] != 98 && data[j - 3] != 111 && data[j - 3] != '<') { j++; } j = StreamReaderUtils.skipSpaces(data, j); // reset pointer start = j; } } // move to end while (j < data.length) { if (data[j] == '[' || data[j] == '(') { count++; } else if (data[j] == ']' || data[j] == ')') { count--; } if (count == 0) { break; } j++; } if (!ignoreRecursion) { final int stringLength = j - start + 1; byte[] newString = new byte[stringLength]; System.arraycopy(data, start, newString, 0, stringLength); if (pdfObject.getObjectType() != PdfDictionary.Encrypt) { final DecryptionFactory decryption = objectReader.getDecryptionObject(); if (decryption != null) { try { newString = decryption.decrypt( newString, pdfObject.getObjectRefAsString(), false, null, false, false); } catch (final PdfSecurityException e) { LogWriter.writeLog("Exception: " + e.getMessage()); } } } pdfObject.setTextStreamValue(PDFkeyInt, newString); if (debugFastCode) { System.out.println(padding + "name=" + new String(newString) + " set in " + pdfObject); } } // roll on if (!isRef) { i = j; } return i; }
public static int setNameStringValue( final PdfObject pdfObject, int i, final byte[] raw, final boolean isMap, final Object PDFkey, final int PDFkeyInt, final PdfFileReader objectReader) { byte[] stringBytes; // move cursor to end of last command if needed while (raw[i] != 10 && raw[i] != 13 && raw[i] != 32 && raw[i] != 47 && raw[i] != '(' && raw[i] != '<') { i++; } i = StreamReaderUtils.skipSpaces(raw, i); // work out if direct (ie /String or read ref 27 0 R int j2 = i; byte[] arrayData = raw; boolean isIndirect = raw[i] != 47 && raw[i] != 40 && raw[i] != 60; // Some /NAME values start ( final boolean startsWithBrace = raw[i] == 40; // delete // @speed - lose this code once Filters done properly /* * just check its not /Filter [/FlateDecode ] or [] or [ /ASCII85Decode /FlateDecode ] * by checking next valid char not / */ boolean isInsideArray = false; if (isIndirect) { int aa = i + 1; aa = StreamReaderUtils.skipSpaces(raw, aa); if (raw[aa] == 47 || raw[aa] == ']') { isIndirect = false; i = aa + 1; isInsideArray = true; } } if (isIndirect) { // its in another object so we need to fetch final int[] values = StreamReaderUtils.readRefFromStream(raw, i); final int ref = values[0]; final int generation = values[1]; i = values[2]; if (raw[i] != 82) { // we are expecting R to end ref throw new RuntimeException( padding + "2. Unexpected value in file - please send to IDRsolutions for analysis"); } // read the Dictionary data arrayData = objectReader.readObjectAsByteArray( pdfObject, objectReader.isCompressed(ref, generation), ref, generation); // allow for data in Linear object not yet loaded if (arrayData == null) { pdfObject.setFullyResolved(false); if (debugFastCode) { System.out.println(padding + "Data not yet loaded"); } return raw.length; } // lose obj at start and roll onto / if (arrayData[0] == 47) { j2 = 0; } else { j2 = 3; while (arrayData[j2] != 47) { j2++; } } } // lose / j2++; // allow for no value with /Intent//Filter if (arrayData[j2] == 47) { return j2 - 1; } int end = j2 + 1; if (isInsideArray) { // values inside [] // move cursor to start of text j2 = StreamReaderUtils.skipSpacesOrOtherCharacter(arrayData, j2, 47); int slashes = 0; // count chars byte lastChar = 0; while (true) { if (arrayData[end] == ']') { break; } if (arrayData[end] == 47 && (lastChar == 32 || lastChar == 10 || lastChar == 13)) // count the / if gap before { slashes++; } lastChar = arrayData[end]; end++; if (end == arrayData.length) { break; } } // set value and ensure space gap final int charCount = end - slashes; int ptr = 0; stringBytes = new byte[charCount - j2]; byte nextChar, previous = 0; for (int ii = j2; ii < charCount; ii++) { nextChar = arrayData[ii]; if (nextChar == 47) { if (previous != 32 && previous != 10 && previous != 13) { stringBytes[ptr] = 32; ptr++; } } else { stringBytes[ptr] = nextChar; ptr++; } previous = nextChar; } } else { // its in data stream directly or (string) // count chars while (true) { if (startsWithBrace) { if (arrayData[end] == ')' && !ObjectUtils.isEscaped(arrayData, end)) { break; } } else if (arrayData[end] == 32 || arrayData[end] == 10 || arrayData[end] == 13 || arrayData[end] == 47 || arrayData[end] == 62) { break; } end++; if (end == arrayData.length) { break; } } // set value final int charCount = end - j2; stringBytes = new byte[charCount]; System.arraycopy(arrayData, j2, stringBytes, 0, charCount); } if (isMap) { pdfObject.setName(PDFkey, StringUtils.getTextString(stringBytes, false)); } else { pdfObject.setName(PDFkeyInt, stringBytes); } if (debugFastCode) { System.out.println( padding + "String set as =" + new String(stringBytes) + "< written to " + pdfObject); } // put cursor in correct place (already there if ref) if (!isIndirect) { i = end - 1; } return i; }
/** * read 1.5 compression stream ref table * * @throws PdfException */ private PdfObject readCompressedStream( PdfObject rootObj, int pointer, final PdfFileReader currentPdfFile, final ObjectReader objectReader, final PdfObject linearObj) throws PdfException { while (pointer != -1) { /** get values to read stream ref */ movePointer(pointer); final byte[] raw = objectReader.readObjectData(-1, null); /** read the object name from the start */ final StringBuilder objectName = new StringBuilder(); char current1, last = ' '; int matched = 0, i1 = 0; while (i1 < raw.length) { current1 = (char) raw[i1]; // treat returns same as spaces if (current1 == 10 || current1 == 13) { current1 = ' '; } if (current1 == ' ' && last == ' ') { // lose duplicate or spaces matched = 0; } else if (current1 == pattern.charAt(matched)) { // looking for obj at end matched++; } else { matched = 0; objectName.append(current1); } if (matched == 3) { break; } last = current1; i1++; } // add end and put into Map objectName.append('R'); final PdfObject pdfObject = new CompressedObject(objectName.toString()); pdfObject.setCompressedStream(true); final ObjectDecoder objectDecoder = new ObjectDecoder(currentPdfFile); objectDecoder.readDictionaryAsObject(pdfObject, 0, raw); // read the field sizes final int[] fieldSizes = pdfObject.getIntArray(PdfDictionary.W); // read the xrefs stream byte[] xrefs = pdfObject.getDecodedStream(); // if encr if (xrefs == null) { xrefs = currentPdfFile.readStream(pdfObject, true, true, false, false, true, null); } final int[] Index = pdfObject.getIntArray(PdfDictionary.Index); if (Index == null) { // single set of values // System.out.println("-------------1.Offsets-------------"+current+" "+numbEntries); CompressedObjects.readCompressedOffsets( 0, 0, pdfObject.getInt(PdfDictionary.Size), fieldSizes, xrefs, offset, pdf_datafile); } else { // pairs of values in Index[] array final int count = Index.length; int pntr = 0; for (int aa = 0; aa < count; aa += 2) { // System.out.println("-------------2.Offsets-------------"+Index[aa]+" "+Index[aa+1]); pntr = CompressedObjects.readCompressedOffsets( pntr, Index[aa], Index[aa + 1], fieldSizes, xrefs, offset, pdf_datafile); } } /** * now process trailer values - only first set of table values for root, encryption and info */ if (rootObj == null) { rootObj = pdfObject.getDictionary(PdfDictionary.Root); /** handle encryption */ encryptObj = pdfObject.getDictionary(PdfDictionary.Encrypt); if (encryptObj != null) { final byte[][] IDs = pdfObject.getStringArray(PdfDictionary.ID); if (IDs != null && this.ID == null) { // only the first encountered ID should be used as a fileID for decryption this.ID = IDs[0]; } } infoObject = pdfObject.getDictionary(PdfDictionary.Info); } // make sure first values used if several tables and code for prev so long as not linearized // may need adjusting as more examples turn up if (linearObj != null) { pointer = -1; } else { pointer = pdfObject.getInt(PdfDictionary.Prev); // a non-compressed object table can follow a compressed one so we need to allow for this if (!isCompressedStream(pointer, (int) eof)) { return readLegacyReferenceTable(rootObj, pointer, (int) eof, currentPdfFile); } } } return rootObj; }
/** read reference table from file so we can locate objects in pdf file and read the trailers */ private PdfObject readLegacyReferenceTable( PdfObject rootObj, int pointer, final int eof, final PdfFileReader currentPdfFile) throws PdfException { int endTable, current = 0; // current object number byte[] Bytes; int bufSize = 1024; /** read and decode 1 or more trailers */ while (true) { try { // allow for pointer outside file Bytes = Trailer.readTrailer(bufSize, pointer, eof, pdf_datafile); } catch (final Exception e) { try { closeFile(); } catch (final IOException e1) { if (LogWriter.isOutput()) { LogWriter.writeLog("Exception " + e + " closing file " + e1); } } throw new PdfException("Exception " + e + " reading trailer"); } if (Bytes == null) // safety catch { break; } /** get trailer */ int i = 0; final int maxLen = Bytes.length; // for(int a=0;a<100;a++) // System.out.println((char)Bytes[i+a]); while (i < maxLen) { // look for trailer keyword if (Bytes[i] == 116 && Bytes[i + 1] == 114 && Bytes[i + 2] == 97 && Bytes[i + 3] == 105 && Bytes[i + 4] == 108 && Bytes[i + 5] == 101 && Bytes[i + 6] == 114) { break; } i++; } // save endtable position for later endTable = i; if (i == Bytes.length) { break; } // move to beyond << while (Bytes[i] != 60 && Bytes[i - 1] != 60) { i++; } i++; final PdfObject pdfObject = new CompressedObject("1 0 R"); Dictionary.readDictionary(pdfObject, i, Bytes, -1, true, currentPdfFile, false); // move to beyond >> int level = 0; while (true) { if (Bytes[i] == 60 && Bytes[i - 1] == 60) { level++; i++; } else if (Bytes[i] == '[') { i++; while (Bytes[i] != ']') { i++; if (i == Bytes.length) { break; } } } else if (Bytes[i] == 62 && Bytes[i - 1] == 62) { level--; i++; } if (level == 0) { break; } i++; } // handle optional XRefStm final int XRefStm = pdfObject.getInt(PdfDictionary.XRefStm); if (XRefStm != -1) { pointer = XRefStm; } else { // usual way boolean hasRef = true; /** handle spaces and comments */ while (Bytes[i] == 10 || Bytes[i] == 13) { i++; } while (Bytes[i] == '%') { while (Bytes[i] != 10) { i++; } i++; } /* fix for /Users/markee/Downloads/oneiderapartnerbrochure_web_1371798737.pdf /**/ // look for xref as end of startref while (Bytes[i] != 116 && Bytes[i + 1] != 120 && Bytes[i + 2] != 114 && Bytes[i + 3] != 101 && Bytes[i + 4] != 102) { if (Bytes[i] == 'o' && Bytes[i + 1] == 'b' && Bytes[i + 2] == 'j') { hasRef = false; break; } i++; } if (hasRef) { i += 8; // move to start of value ignoring spaces or returns while ((i < maxLen) && (Bytes[i] == 10 || Bytes[i] == 32 || Bytes[i] == 13)) { i++; } final int s = i; // allow for characters between xref and startref while (i < maxLen && Bytes[i] != 10 && Bytes[i] != 32 && Bytes[i] != 13) { i++; } /** convert xref to string to get pointer */ if (s != i) { pointer = NumberUtils.parseInt(s, i, Bytes); } } } i = 0; // allow for bum data at start while (Bytes[i] == 13 || Bytes[i] == 10 || Bytes[i] == 9) { i++; } if (pointer == -1) { if (LogWriter.isOutput()) { LogWriter.writeLog("No startRef"); } /** now read the objects for the trailers */ } else if (Bytes[i] == 120 && Bytes[i + 1] == 114 && Bytes[i + 2] == 101 && Bytes[i + 3] == 102) { // make sure starts xref i = 5; // move to start of value ignoring spaces or returns while (Bytes[i] == 10 || Bytes[i] == 32 || Bytes[i] == 13) { i++; } current = offset.readXRefs(current, Bytes, endTable, i, eof, pdf_datafile); /** * now process trailer values - only first set of table values for root, encryption and info */ if (rootObj == null) { rootObj = pdfObject.getDictionary(PdfDictionary.Root); encryptObj = pdfObject.getDictionary(PdfDictionary.Encrypt); if (encryptObj != null) { final byte[][] IDs = pdfObject.getStringArray(PdfDictionary.ID); if (IDs != null && this.ID == null) { // only the first encountered ID should be used as a fileID for decryption this.ID = IDs[0]; } } infoObject = pdfObject.getDictionary(PdfDictionary.Info); } // make sure first values used if several tables and code for prev pointer = pdfObject.getInt(PdfDictionary.Prev); // see if other trailers if (pointer != -1 && pointer < this.eof) { // reset values for loop bufSize = 1024; // track ref table so we can work out object length offset.addXref(pointer); } else // reset if fails second test above { pointer = -1; } } else { pointer = -1; // needs to be read to pick up potential /Pages value //noinspection ObjectAllocationInLoop rootObj = new PageObject(BrokenRefTable.findOffsets(pdf_datafile, offset)); currentPdfFile.readObject(rootObj); offset.setRefTableInvalid(true); } if (pointer == -1) { break; } } if (encryptObj == null && rootObj != null) { // manual check for broken file (ignore if Encrypted) int type = -1; int status = rootObj.getStatus(); byte[] data = rootObj.getUnresolvedData(); try { final ObjectDecoder objectDecoder = new ObjectDecoder(currentPdfFile); objectDecoder.checkResolved(rootObj); type = rootObj.getParameterConstant(PdfDictionary.Type); } catch (Exception e) { // we need to ignore so just catch, put back as was and log rootObj.setStatus(status); rootObj.setUnresolvedData(data, status); if (LogWriter.isOutput()) { LogWriter.writeLog("[PDF] Exception reading type on root object " + e); } } // something gone wrong so manually index if (type == PdfDictionary.Font) { // see 21153 - ref table in wrong order rootObj = null; // /will reset in code at end } } // something gone wrong so manually index if (rootObj == null) { // see 21382 offset.clear(); offset.reuse(); // needs to be read to pick up potential /Pages value //noinspection ObjectAllocationInLoop rootObj = new PageObject(BrokenRefTable.findOffsets(pdf_datafile, offset)); currentPdfFile.readObject(rootObj); offset.setRefTableInvalid(true); } return rootObj; }
public void setJavascriptForObject( final FormObject formObject, final int parentType, final int actionType) { final String JSscript; final PdfObject actionObj; final PdfObject JSobj; final PdfObject additionalObject = formObject.getDictionary(parentType); final ObjectDecoder objectDecoder = new ObjectDecoder(this.objectReader); objectDecoder.checkResolved(additionalObject); if (additionalObject == null) { return; } if (actionType == parentType) { actionObj = additionalObject; } else { if (actionType == PdfDictionary.C2) // special case { actionObj = additionalObject.getDictionary(PdfDictionary.C); } else { actionObj = additionalObject.getDictionary(actionType); } } if (actionObj == null) { // throw new RuntimeException("Failed on actionType="+actionType+" // "+formObject.getPDFRef()+ // "\nformObject="+formObject+" parentObject="+additionalObject+ // "\nadditionalObject="+additionalObject.getTextStreamValue(PdfDictionary.T) // +"\nadditionalObject="+formObject.getTextStreamValue(PdfDictionary.T)); } else { objectDecoder.checkResolved(actionObj); JSobj = actionObj.getDictionary(PdfDictionary.JS); if (JSobj != null) { final byte[] data = JSobj.getDecodedStream(); JSscript = StringUtils.getTextString(data, true); } else { JSscript = actionObj.getTextStreamValue(PdfDictionary.JS); } // store if (JSscript != null) { // use name to reference Js if name is null use ref. seems to be slower, but better on // abacus/L295KantoonVaadt.pdf String name = formObject.getTextStreamValue(PdfDictionary.T); if (name == null) { name = formObject.getObjectRefAsString(); } javascript.storeJavascript(name, JSscript, actionType); // old version // // javascript.storeJavascript(formObject.getObjectRefAsString(),JSscript,actionType); } } }
public BufferedImage convert( final DecoderResults resultsFromDecode, final int displayRotation, final PdfResources res, final ExternalHandlers externalHandlers, final int renderMode, final PdfPageData pageData, final AcroRenderer formRenderer, final float scaling, final PdfObjectReader currentPdfFile, final int pageIndex, final boolean imageIsTransparent, final String currentPageOffset) throws PdfException { final ObjectStore localStore = new ObjectStore(); /** read page or next pages */ final PdfObject pdfObject = new PageObject(currentPageOffset); currentPdfFile.readObject(pdfObject); currentPdfFile.checkParentForResources(pdfObject); // ensure set (needed for XFA) pdfObject.setPageNumber(pageIndex); final PdfObject Resources = pdfObject.getDictionary(PdfDictionary.Resources); imageDisplay = getDisplay(pageIndex, localStore, imageIsTransparent); if (!imageDisplay.isHTMLorSVG()) { if (options.getPageColor() != null) { imageDisplay.setValue( DynamicVectorRenderer.ALT_BACKGROUND_COLOR, options.getPageColor().getRGB()); } if (options.getTextColor() != null) { imageDisplay.setValue( DynamicVectorRenderer.ALT_FOREGROUND_COLOR, options.getTextColor().getRGB()); if (options.getChangeTextAndLine()) { imageDisplay.setValue(DynamicVectorRenderer.FOREGROUND_INCLUDE_LINEART, 1); } else { imageDisplay.setValue(DynamicVectorRenderer.FOREGROUND_INCLUDE_LINEART, 0); } imageDisplay.setValue( DynamicVectorRenderer.COLOR_REPLACEMENT_THRESHOLD, options.getReplacementColorThreshold()); } } final PdfStreamDecoder currentImageDecoder = formRenderer.getStreamDecoder(currentPdfFile, true, null, true); currentImageDecoder.setParameters( true, true, renderMode, PdfDecoderInt.TEXT, false, externalHandlers.getMode().equals(GUIModes.JAVAFX)); externalHandlers.addHandlers(currentImageDecoder); // currentImageDecoder.setObjectValue(ValueTypes.Name, filename); currentImageDecoder.setObjectValue(ValueTypes.ObjectStore, localStore); currentImageDecoder.setMultiplyer(multiplyer); currentImageDecoder.setObjectValue(ValueTypes.PDFPageData, pageData); currentImageDecoder.setIntValue(ValueTypes.PageNum, pageIndex); currentImageDecoder.setRenderer(imageDisplay); externalHandlers.addHandlers(currentImageDecoder); res.setupResources(currentImageDecoder, true, Resources, pageIndex, currentPdfFile); // can for max if (multiplyer == -2) { multiplyer = -1; currentImageDecoder.setMultiplyer(multiplyer); final PdfStreamDecoderForSampling currentImageDecoder2 = new PdfStreamDecoderForSampling(currentPdfFile); currentImageDecoder2.setParameters( true, true, renderMode, 0, false, externalHandlers.getMode().equals(GUIModes.JAVAFX)); // currentImageDecoder2.setObjectValue(ValueTypes.Name, filename); currentImageDecoder2.setObjectValue(ValueTypes.ObjectStore, localStore); currentImageDecoder2.setMultiplyer(multiplyer); currentImageDecoder2.setObjectValue(ValueTypes.PDFPageData, pageData); currentImageDecoder2.setIntValue(ValueTypes.PageNum, pageIndex); currentImageDecoder2.setRenderer(imageDisplay); res.setupResources(currentImageDecoder2, true, Resources, pageIndex, currentPdfFile); externalHandlers.addHandlers(currentImageDecoder2); /** bare minimum to get value */ multiplyer = currentImageDecoder2.decodePageContentForImageSampling(pdfObject); int bestQualityMaxScalingToUse = 0; if (instance_bestQualityMaxScaling != null) { bestQualityMaxScalingToUse = instance_bestQualityMaxScaling; } else if (bestQualityMaxScaling != null) { bestQualityMaxScalingToUse = bestQualityMaxScaling; } if (bestQualityMaxScalingToUse > 0 && multiplyer > bestQualityMaxScalingToUse) { multiplyer = bestQualityMaxScalingToUse; } currentImageDecoder2.setMultiplyer(multiplyer); currentImageDecoder.setMultiplyer(multiplyer); } if (!allowPagesSmallerThanPageSize && !instance_allowPagesSmallerThanPageSize && multiplyer < 1 && multiplyer > 0) { multiplyer = 1; } // allow for value not set if (multiplyer == -1) { multiplyer = 1; } /** setup positions,transformations and image */ imageScaling = PDFtoImageConvertorSwing.setPageParametersForImage( scaling * multiplyer, pageIndex, pageData); setParams(scaling, pageData, pageIndex); final BufferedImage image = pageToImage(imageIsTransparent, currentImageDecoder, scaling, pdfObject, formRenderer); resultsFromDecode.update(currentImageDecoder, false); /** draw acroform data onto Panel */ if (formRenderer != null && formRenderer.hasFormsOnPage(pageIndex) && !formRenderer.ignoreForms()) { resultsFromDecode.resetColorSpaces(); if (!formRenderer.getCompData().hasformsOnPageDecoded(pageIndex)) { formRenderer.createDisplayComponentsForPage(pageIndex, currentImageDecoder); } if (isFX) { // done in fx image code } else if (!formRenderer.getCompData().formsRasterizedForDisplay()) { if (!formRenderer.useXFA()) { java.util.List[] formsOrdered = formRenderer.getCompData().getFormList(true); // get unsorted components and iterate over forms for (Object nextVal : formsOrdered[pageIndex]) { if (nextVal != null) { formRenderer .getFormFlattener() .drawFlattenedForm( currentImageDecoder, (org.jpedal.objects.raw.FormObject) nextVal, false, (PdfObject) formRenderer.getFormResources()[0]); } } } else { formRenderer .getCompData() .renderFormsOntoG2( image.getGraphics(), pageIndex, 0, displayRotation, null, null, pageData.getMediaBoxHeight(pageIndex)); } } else { final java.util.List[] formsOrdered = formRenderer.getCompData().getFormList(true); // get unsorted components and iterate over forms for (final Object nextVal : formsOrdered[pageIndex]) { if (nextVal != null) { formRenderer .getFormFlattener() .drawFlattenedForm( currentImageDecoder, (org.jpedal.objects.raw.FormObject) nextVal, false, (PdfObject) formRenderer.getFormResources()[0]); } } } } if (currentImageDecoder != null) { currentImageDecoder.dispose(); } localStore.flush(); return image; }
public static boolean convert( byte[] objectData, ImageData imageData, GenericColorSpace decodeColorData, PdfObject newSMask, PdfObjectReader currentPdfFile) throws PdfException { newSMask.setFloatArray(PdfDictionary.Decode, new float[] {1, 0}); final PdfArrayIterator Filters = newSMask.getMixedArray(PdfDictionary.Filter); boolean isMaskJPX = false; // check not handled elsewhere int firstValue; if (Filters != null && Filters.hasMoreTokens()) { while (Filters.hasMoreTokens()) { firstValue = Filters.getNextValueAsConstant(true); // isDCT=firstValue==PdfFilteredReader.DCTDecode; isMaskJPX = firstValue == PdfFilteredReader.JPXDecode; } } byte[] objData = currentPdfFile.readStream(newSMask, true, true, false, false, false, null); imageData.setObjectData(objData); imageData.setDepth(1); imageData.setWidth(newSMask.getInt(PdfDictionary.Width)); imageData.setHeight(newSMask.getInt(PdfDictionary.Height)); int newDepth = newSMask.getInt(PdfDictionary.BitsPerComponent); // JPEG2000 causes us special difficulties as we not actually decoding objectData because // it is JPEG2000 and we decode as part of image handling because Java does byte[] to image // directly // // This code fixes specific example by getting the actual data and ignoring empty mask but will // probably need developing further if we find other examples if (isMaskJPX) { // see case 17665 for example BufferedImage img = decodeColorData.JPEG2000ToRGBImage( imageData.getObjectData(), imageData.getWidth(), imageData.getHeight(), null, -1, -1, 8); img = ColorSpaceConvertor.convertColorspace(img, 10); objData = ((DataBufferByte) img.getRaster().getDataBuffer()).getData(); imageData.setObjectData(objData); boolean isEmptyMask = true; for (final byte b : objectData) { if (b != 0) { isEmptyMask = false; break; } } if (isEmptyMask) { imageData.setObjectData(null); } // we need to unset this as e have handled the JPX filter newSMask.setMixedArray(PdfDictionary.Filter, null); } if (newDepth != PdfDictionary.Unknown) { imageData.setDepth(newDepth); } return objData == null; }