All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jpedal.parser.PdfObjectCache Maven / Gradle / Ivy

The newest version!
/*
 * ===========================================
 * Java Pdf Extraction Decoding Access Library
 * ===========================================
 *
 * Project Info:  http://www.idrsolutions.com
 * Help section for developers at http://www.idrsolutions.com/java-pdf-library-support/
 *
 * (C) Copyright 1997-2013, IDRsolutions and Contributors.
 *
 * 	This file is part of JPedal
 *
     This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


 *
 * ---------------
 * PdfObjectCache.java
 * ---------------
 */
package org.jpedal.parser;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.jpedal.exception.PdfException;
import org.jpedal.io.PdfObjectReader;
import org.jpedal.objects.raw.ObjectFactory;
import org.jpedal.objects.raw.PdfDictionary;
import org.jpedal.objects.raw.PdfKeyPairsIterator;
import org.jpedal.objects.raw.PdfObject;
import org.jpedal.objects.raw.XObject;
import org.jpedal.utils.StringUtils;

/**
 * caches for data
 */
public class PdfObjectCache {

	public static final int ColorspacesUsed = 1;
	public static final int Colorspaces = 2;

	// init size of maps
	private static final int initSize = 50;

	// int values for all colorspaces
	private final Map colorspacesUsed = new HashMap(initSize);

	public Map colorspacesObjects = new HashMap(initSize);

	/**
	 * avoid resaving the same image multiple times
	 */
	HashMap imageAlreadySaved = new HashMap();

	/** colors */
	private Map colorspaces = new HashMap(initSize);

	private Map globalXObjects = new HashMap(initSize), localXObjects = new HashMap(initSize);

	public final Map XObjectColorspaces = new HashMap(initSize);

	public Map patterns = new HashMap(initSize), globalShadings = new HashMap(initSize), localShadings = new HashMap(initSize);

	Map imposedImages = new HashMap(initSize);

	PdfObject groupObj = null;

	PdfObject pageGroupingObj = null;

	/** fonts */
	public Map unresolvedFonts = new HashMap(initSize);
	public Map directFonts = new HashMap(initSize);
	public Map resolvedFonts = new HashMap(initSize);

	/** GS */
	Map GraphicsStates = new HashMap(initSize);

	public PdfObjectCache copy() {

		PdfObjectCache copy = new PdfObjectCache();

		copy.localShadings = this.localShadings;
		copy.unresolvedFonts = this.unresolvedFonts;
		copy.GraphicsStates = this.GraphicsStates;
		copy.directFonts = this.directFonts;
		copy.resolvedFonts = this.resolvedFonts;
		copy.colorspaces = this.colorspaces;

		copy.localXObjects = this.localXObjects;
		copy.globalXObjects = this.globalXObjects;

		copy.groupObj = this.groupObj;

		return copy;
	}

	public PdfObjectCache() {}

	public void put(int type, int key, Object value) {
		switch (type) {
			case ColorspacesUsed:
				this.colorspacesUsed.put(key, value);
				break;
		}
	}

	public Iterator iterator(int type) {

		Iterator returnValue = null;

		switch (type) {
			case ColorspacesUsed:
				returnValue = this.colorspacesUsed.keySet().iterator();
				break;
		}

		return returnValue;
	}

	public Object get(int key, Object value) {

		Object returnValue = null;

		switch (key) {
			case ColorspacesUsed:
				returnValue = this.colorspacesUsed.get(value);
				break;

			case Colorspaces:
				returnValue = this.colorspaces.get(value);
				break;
		}

		return returnValue;
	}

	public void resetFonts() {
		this.resolvedFonts.clear();
		this.unresolvedFonts.clear();
		this.directFonts.clear();
	}

	public PdfObject getXObjects(String localName) {

		PdfObject XObject = (PdfObject) this.localXObjects.get(localName);
		if (XObject == null) XObject = (PdfObject) this.globalXObjects.get(localName);

		return XObject;
	}

	public void readResources(PdfObject Resources, boolean resetList, PdfObjectReader currentPdfFile) throws PdfException {

		currentPdfFile.checkResolved(Resources);

		// decode
		String[] names = { "ColorSpace", "ExtGState", "Font", "Pattern", "Shading", "XObject" };
		int[] keys = { PdfDictionary.ColorSpace, PdfDictionary.ExtGState, PdfDictionary.Font, PdfDictionary.Pattern, PdfDictionary.Shading,
				PdfDictionary.XObject };

		for (int ii = 0; ii < names.length; ii++) {

			if (keys[ii] == PdfDictionary.Font || keys[ii] == PdfDictionary.XObject) readArrayPairs(Resources, resetList, keys[ii], currentPdfFile);
			else readArrayPairs(Resources, false, keys[ii], currentPdfFile);
		}
	}

	private void readArrayPairs(PdfObject Resources, boolean resetFontList, int type, PdfObjectReader currentPdfFile) throws PdfException {

		final boolean debugPairs = false;

		if (debugPairs) {
			System.out.println("-------------readArrayPairs-----------" + type);
			System.out.println("new=" + Resources + ' ' + Resources.getObjectRefAsString());
		}
		String id, value;

		/**
		 * new code
		 */
		if (Resources != null) {

			PdfObject resObj = Resources.getDictionary(type);

			if (debugPairs) System.out.println("new res object=" + resObj);

			if (resObj != null) {

				/**
				 * read all the key pairs for Glyphs
				 */
				PdfKeyPairsIterator keyPairs = resObj.getKeyPairsIterator();

				PdfObject obj;

				if (debugPairs) {
					System.out.println("New values");
					System.out.println("----------");
				}

				while (keyPairs.hasMorePairs()) {

					id = keyPairs.getNextKeyAsString();
					value = keyPairs.getNextValueAsString();
					obj = keyPairs.getNextValueAsDictionary();

					if (debugPairs) System.out.println(id + ' ' + obj + ' ' + value + ' ' + Resources.isDataExternal());

					if (Resources.isDataExternal()) { // check and flag if missing

						// ObjectDecoder objectDecoder=new ObjectDecoder(currentPdfFile.getObjectReader());

						if (obj == null && value == null) {
							Resources.setFullyResolved(false);
							return;
						}
						else
							if (obj == null) {

								PdfObject childObj = ObjectFactory.createObject(type, value, type, -1);

								childObj.setStatus(PdfObject.UNDECODED_DIRECT);
								childObj.setUnresolvedData(StringUtils.toBytes(value), type);

								// if(!objectDecoder.resolveFully(childObj)){
								// Resources.setFullyResolved(false);
								// return;
								// }

								// cache if setup
								if (type == PdfDictionary.Font) {
									this.directFonts.put(id, childObj);
								}
								// }else if(!objectDecoder.resolveFully(obj)){
								// Resources.setFullyResolved(false);
								// return;
							}
					}

					switch (type) {

						case PdfDictionary.ColorSpace:
							this.colorspaces.put(id, obj);
							break;

						case PdfDictionary.ExtGState:
							this.GraphicsStates.put(id, obj);
							break;

						case PdfDictionary.Font:

							this.unresolvedFonts.put(id, obj);

							break;

						case PdfDictionary.Pattern:
							this.patterns.put(id, obj);

							break;

						case PdfDictionary.Shading:
							if (resetFontList) this.globalShadings.put(id, obj);
							else this.localShadings.put(id, obj);

							break;

						case PdfDictionary.XObject:
							if (resetFontList) this.globalXObjects.put(id, obj);
							else this.localXObjects.put(id, obj);

							break;

					}

					keyPairs.nextPair();
				}
			}
		}
	}

	public void reset(PdfObjectCache newCache) {

		// reset copies
		this.localShadings = new HashMap(initSize);
		this.resolvedFonts = new HashMap(initSize);
		this.unresolvedFonts = new HashMap(initSize);
		this.directFonts = new HashMap(initSize);
		this.colorspaces = new HashMap(initSize);
		this.GraphicsStates = new HashMap(initSize);
		this.localXObjects = new HashMap(initSize);

		Iterator keys = newCache.GraphicsStates.keySet().iterator();
		while (keys.hasNext()) {
			Object key = keys.next();
			this.GraphicsStates.put(key, newCache.GraphicsStates.get(key));
		}

		keys = newCache.colorspaces.keySet().iterator();
		while (keys.hasNext()) {
			Object key = keys.next();
			this.colorspaces.put(key, newCache.colorspaces.get(key));
		}

		keys = newCache.localXObjects.keySet().iterator();
		while (keys.hasNext()) {
			Object key = keys.next();
			this.localXObjects.put(key, newCache.localXObjects.get(key));
		}

		keys = newCache.globalXObjects.keySet().iterator();
		while (keys.hasNext()) {
			Object key = keys.next();
			this.globalXObjects.put(key, newCache.globalXObjects.get(key));
		}

		// allow for no fonts in FormObject when we use any global
		if (this.unresolvedFonts.isEmpty()) {
			// unresolvedFonts=rawFonts;
			keys = newCache.unresolvedFonts.keySet().iterator();
			while (keys.hasNext()) {
				Object key = keys.next();
				this.unresolvedFonts.put(key, newCache.unresolvedFonts.get(key));
			}
		}
	}

	public void restore(PdfObjectCache mainCache) {

		this.directFonts = mainCache.directFonts;
		this.unresolvedFonts = mainCache.unresolvedFonts;
		this.resolvedFonts = mainCache.resolvedFonts;
		this.GraphicsStates = mainCache.GraphicsStates;
		this.colorspaces = mainCache.colorspaces;
		this.localShadings = mainCache.localShadings;
		this.localXObjects = mainCache.localXObjects;
		this.globalXObjects = mainCache.globalXObjects;

		this.groupObj = mainCache.groupObj;
	}

	public int getXObjectCount() {
		return this.localXObjects.keySet().size() + this.globalXObjects.keySet().size();
	}

	public Object getImposedKey(String key) {
		return this.imposedImages.get(key);
	}

	public void setImposedKey(String key, int id) {
		if (this.imposedImages != null) this.imposedImages.put(key, id);
	}

	/**
	 * see if image saved (and flag as true in future)
	 * 
	 * @param XObject objectRefAsString
	 */
	public boolean testIfImageAlreadySaved(PdfObject XObject) {

		boolean flag = false;

		if (XObject.getGeneralType(-1) != PdfDictionary.ID) { // never cache these

			String objectRefAsString = XObject.getObjectRefAsString();

			flag = this.imageAlreadySaved.containsKey(objectRefAsString);

			if (flag == false) {
				this.imageAlreadySaved.put(objectRefAsString, "x");
			}
		}
		return flag;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy