You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by je...@apache.org on 2011/07/27 10:46:21 UTC
svn commit: r1151382 [1/2] - in /pdfbox/trunk/pdfbox/src:
main/java/org/apache/pdfbox/ main/java/org/apache/pdfbox/filter/
main/java/org/apache/pdfbox/pdfparser/ main/java/org/apache/pdfbox/pdmodel/
main/java/org/apache/pdfbox/pdmodel/font/ main/java/o...
Author: jeremias
Date: Wed Jul 27 08:46:12 2011
New Revision: 1151382
URL: http://svn.apache.org/viewvc?rev=1151382&view=rev
Log:
Code cleanup:
Removed all tab characters.
Fixed some Checkstyle violations.
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/PDFToImage.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/TextToPDF.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/filter/FlateFilter.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/filter/JBIG2Filter.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/filter/JPXFilter.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/BaseParser.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/PDFParser.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/PDFStreamParser.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/PDFXrefStreamParser.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/XrefTrailerResolver.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDPage.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFont.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontDescriptorDictionary.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/CompositeImage.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDJpeg.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDPixelMap.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDXObjectImage.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/DateConverter.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/Matrix.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/PDFText2HTML.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/PositionWrapper.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/TextPosition.java
pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/TestTextToPdf.java
pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/util/TestMatrix.java
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/PDFToImage.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/PDFToImage.java?rev=1151382&r1=1151381&r2=1151382&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/PDFToImage.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/PDFToImage.java Wed Jul 27 08:46:12 2011
@@ -19,11 +19,10 @@ package org.apache.pdfbox;
import java.awt.HeadlessException;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
+import java.util.List;
import javax.imageio.ImageIO;
-import java.util.List;
-
import org.apache.pdfbox.exceptions.InvalidPasswordException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
@@ -76,7 +75,7 @@ public class PDFToImage
float cropBoxLowerLeftX = 0;
float cropBoxLowerLeftY = 0;
float cropBoxUpperRightX = 0;
- float cropBoxUpperRightY = 0;
+ float cropBoxUpperRightY = 0;
try
{
resolution = Toolkit.getDefaultToolkit().getScreenResolution();
@@ -137,13 +136,13 @@ public class PDFToImage
else if( args[i].equals( CROPBOX ) )
{
i++;
- cropBoxLowerLeftX = Float.valueOf(args[i]).floatValue();
+ cropBoxLowerLeftX = Float.valueOf(args[i]).floatValue();
i++;
- cropBoxLowerLeftY = Float.valueOf(args[i]).floatValue();
+ cropBoxLowerLeftY = Float.valueOf(args[i]).floatValue();
i++;
- cropBoxUpperRightX = Float.valueOf(args[i]).floatValue();
+ cropBoxUpperRightX = Float.valueOf(args[i]).floatValue();
i++;
- cropBoxUpperRightY = Float.valueOf(args[i]).floatValue();
+ cropBoxUpperRightY = Float.valueOf(args[i]).floatValue();
}
else
{
@@ -219,12 +218,15 @@ public class PDFToImage
System.exit( 2 );
}
- //si une cropBox a ete specifier, appeler la methode de modification de cropbox
- //changeCropBoxes(PDDocument document,float a, float b, float c,float d)
- if ( cropBoxLowerLeftX!=0 || cropBoxLowerLeftY!=0 || cropBoxUpperRightX!=0 || cropBoxUpperRightY!=0 )
- {
- changeCropBoxes(document,cropBoxLowerLeftX, cropBoxLowerLeftY, cropBoxUpperRightX, cropBoxUpperRightY);
- }
+ //if a CropBox has been specified, update the CropBox:
+ //changeCropBoxes(PDDocument document,float a, float b, float c,float d)
+ if ( cropBoxLowerLeftX!=0 || cropBoxLowerLeftY!=0
+ || cropBoxUpperRightX!=0 || cropBoxUpperRightY!=0 )
+ {
+ changeCropBoxes(document,
+ cropBoxLowerLeftX, cropBoxLowerLeftY,
+ cropBoxUpperRightX, cropBoxUpperRightY);
+ }
//Make the call
PDFImageWriter imageWriter = new PDFImageWriter();
@@ -287,21 +289,20 @@ public class PDFToImage
private static void changeCropBoxes(PDDocument document,float a, float b, float c,float d)
{
- List pages = document.getDocumentCatalog().getAllPages();
- for( int i = 0; i < pages.size(); i++ )
- {
+ List pages = document.getDocumentCatalog().getAllPages();
+ for( int i = 0; i < pages.size(); i++ )
+ {
System.out.println("resizing page");
- PDPage page = (PDPage)pages.get( i );
- PDRectangle rectangle = new PDRectangle();
+ PDPage page = (PDPage)pages.get( i );
+ PDRectangle rectangle = new PDRectangle();
rectangle.setLowerLeftX(a);
rectangle.setLowerLeftY(b);
rectangle.setUpperRightX(c);
rectangle.setUpperRightY(d);
- page.setMediaBox(rectangle);
- page.setCropBox(rectangle);
-
- }
+ page.setMediaBox(rectangle);
+ page.setCropBox(rectangle);
+ }
}
}
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/TextToPDF.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/TextToPDF.java?rev=1151382&r1=1151381&r2=1151382&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/TextToPDF.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/TextToPDF.java Wed Jul 27 08:46:12 2011
@@ -56,7 +56,7 @@ public class TextToPDF
PDDocument doc = null;
try
{
-
+
final int margin = 40;
float height = font.getFontDescriptor().getFontBoundingBox().getHeight()/1000;
@@ -69,17 +69,17 @@ public class TextToPDF
PDPageContentStream contentStream = null;
float y = -1;
float maxStringLength = page.getMediaBox().getWidth() - 2*margin;
-
+
// There is a special case of creating a PDF document from an empty string.
boolean textIsEmpty = true;
-
+
while( (nextLine = data.readLine()) != null )
{
-
- // The input text is nonEmpty. New pages will be created and added
- // to the PDF document as they are needed, depending on the length of
- // the text.
- textIsEmpty = false;
+
+ // The input text is nonEmpty. New pages will be created and added
+ // to the PDF document as they are needed, depending on the length of
+ // the text.
+ textIsEmpty = false;
String[] lineWords = nextLine.trim().split( " " );
int lineIndex = 0;
@@ -103,8 +103,8 @@ public class TextToPDF
lengthIfUsingNextWord < maxStringLength );
if( y < margin )
{
- // We have crossed the end-of-page boundary and need to extend the
- // document by another page.
+ // We have crossed the end-of-page boundary and need to extend the
+ // document by another page.
page = new PDPage();
doc.addPage( page );
if( contentStream != null )
@@ -133,15 +133,15 @@ public class TextToPDF
}
-
+
// If the input text was the empty string, then the above while loop will have short-circuited
// and we will not have added any PDPages to the document.
// So in order to make the resultant PDF document readable by Adobe Reader etc, we'll add an empty page.
if (textIsEmpty)
{
- doc.addPage(page);
+ doc.addPage(page);
}
-
+
if( contentStream != null )
{
contentStream.endText();
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/filter/FlateFilter.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/filter/FlateFilter.java?rev=1151382&r1=1151381&r2=1151382&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/filter/FlateFilter.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/filter/FlateFilter.java Wed Jul 27 08:46:12 2011
@@ -40,7 +40,7 @@ import org.apache.pdfbox.cos.COSName;
* @author Marcel Kammer
* @version $Revision: 1.12 $
*/
-public class FlateFilter implements Filter
+public class FlateFilter implements Filter
{
/**
@@ -53,7 +53,7 @@ public class FlateFilter implements Filt
/**
* {@inheritDoc}
*/
- public void decode(InputStream compressedData, OutputStream result, COSDictionary options, int filterIndex )
+ public void decode(InputStream compressedData, OutputStream result, COSDictionary options, int filterIndex )
throws IOException
{
COSBase baseObj = options.getDictionaryObject(COSName.DECODE_PARMS, COSName.DP);
@@ -76,7 +76,7 @@ public class FlateFilter implements Filt
}
else
{
- throw new IOException( "Error: Expected COSArray or COSDictionary and not "
+ throw new IOException( "Error: Expected COSArray or COSDictionary and not "
+ baseObj.getClass().getName() );
}
@@ -106,14 +106,14 @@ public class FlateFilter implements Filt
int amountRead;
int mayRead = compressedData.available();
- if (mayRead > 0)
+ if (mayRead > 0)
{
byte[] buffer = new byte[Math.min(mayRead,BUFFER_SIZE)];
// Decode data using given predictor
if (predictor==-1 || predictor == 1 )
{
- try
+ try
{
// decoding not needed
while ((amountRead = decompressor.read(buffer, 0, Math.min(mayRead,BUFFER_SIZE))) != -1)
@@ -121,17 +121,17 @@ public class FlateFilter implements Filt
result.write(buffer, 0, amountRead);
}
}
- catch (OutOfMemoryError exception)
+ catch (OutOfMemoryError exception)
{
// if the stream is corrupt an OutOfMemoryError may occur
log.error("Stop reading corrupt stream");
}
- catch (ZipException exception)
+ catch (ZipException exception)
{
// if the stream is corrupt an OutOfMemoryError may occur
log.error("Stop reading corrupt stream");
}
- catch (EOFException exception)
+ catch (EOFException exception)
{
// if the stream is corrupt an OutOfMemoryError may occur
log.error("Stop reading corrupt stream");
@@ -222,10 +222,10 @@ public class FlateFilter implements Filt
while (!done && data.available() > 0)
{
- // test for PNG predictor; each value >= 10 (not only 15) indicates usage of PNG predictor
- if (predictor >= 10)
+ // test for PNG predictor; each value >= 10 (not only 15) indicates usage of PNG predictor
+ if (predictor >= 10)
{
- // PNG predictor; each row starts with predictor type (0, 1, 2, 3, 4)
+ // PNG predictor; each row starts with predictor type (0, 1, 2, 3, 4)
linepredictor = data.read();// read per line predictor
if (linepredictor == -1)
{
@@ -251,23 +251,25 @@ public class FlateFilter implements Filt
{
case 2:// PRED TIFF SUB
/**
- * @TODO decode tiff with bitsPerComponent != 8; e.g. for 4 bpc each nibble must be subtracted separately
+ * @TODO decode tiff with bitsPerComponent != 8;
+ * e.g. for 4 bpc each nibble must be subtracted separately
*/
if ( bitsPerComponent != 8 )
{
- throw new IOException("TIFF-Predictor with " + bitsPerComponent + " bits per component not supported");
+ throw new IOException("TIFF-Predictor with " + bitsPerComponent
+ + " bits per component not supported");
}
// for 8 bits per component it is the same algorithm as PRED SUB of PNG format
- for (int p = 0; p < rowlength; p++)
- {
- int sub = actline[p] & 0xff;
- int left = p - bpp >= 0 ? actline[p - bpp] & 0xff : 0;
- actline[p] = (byte) (sub + left);
- }
- break;
+ for (int p = 0; p < rowlength; p++)
+ {
+ int sub = actline[p] & 0xff;
+ int left = p - bpp >= 0 ? actline[p - bpp] & 0xff : 0;
+ actline[p] = (byte) (sub + left);
+ }
+ break;
case 10:// PRED NONE
- // do nothing
- break;
+ // do nothing
+ break;
case 11:// PRED SUB
for (int p = 0; p < rowlength; p++)
{
@@ -322,7 +324,7 @@ public class FlateFilter implements Filt
default:
break;
}
- lastline = (byte[])actline.clone();
+ lastline = actline.clone();
baos.write(actline, 0, actline.length);
}
}
@@ -332,13 +334,13 @@ public class FlateFilter implements Filt
/**
* {@inheritDoc}
*/
- public void encode(InputStream rawData, OutputStream result, COSDictionary options, int filterIndex )
+ public void encode(InputStream rawData, OutputStream result, COSDictionary options, int filterIndex )
throws IOException
{
DeflaterOutputStream out = new DeflaterOutputStream(result);
int amountRead = 0;
int mayRead = rawData.available();
- if (mayRead > 0)
+ if (mayRead > 0)
{
byte[] buffer = new byte[Math.min(mayRead,BUFFER_SIZE)];
while ((amountRead = rawData.read(buffer, 0, Math.min(mayRead,BUFFER_SIZE))) != -1)
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/filter/JBIG2Filter.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/filter/JBIG2Filter.java?rev=1151382&r1=1151381&r2=1151382&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/filter/JBIG2Filter.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/filter/JBIG2Filter.java Wed Jul 27 08:46:12 2011
@@ -40,20 +40,20 @@ import org.apache.pdfbox.cos.COSDictiona
public class JBIG2Filter implements Filter
{
- /** Log instance */
+ /** Log instance. */
private static final Log log = LogFactory.getLog(JBIG2Filter.class);
-
+
/**
* Decode JBIG2 data using Java ImageIO library.
- *
+ *
* {@inheritDoc}
- *
+ *
*/
- public void decode( InputStream compressedData, OutputStream result, COSDictionary options, int filterIndex )
+ public void decode( InputStream compressedData, OutputStream result, COSDictionary options, int filterIndex )
throws IOException
{
- BufferedImage bi = ImageIO.read(compressedData);
- if ( bi != null )
+ BufferedImage bi = ImageIO.read(compressedData);
+ if ( bi != null )
{
DataBuffer dBuf = bi.getData().getDataBuffer();
if ( dBuf.getDataType() == DataBuffer.TYPE_BYTE )
@@ -67,22 +67,22 @@ public class JBIG2Filter implements Filt
}
else
{
- Iterator<ImageReader> reader = ImageIO.getImageReadersByFormatName("JBIG2");
- if (!reader.hasNext())
- {
- log.error( "Can't find an ImageIO plugin to decode the JBIG2 encoded datastream.");
- }
- else
- {
- log.error( "Something went wrong when decoding the JBIG2 encoded datastream.");
- }
+ Iterator<ImageReader> reader = ImageIO.getImageReadersByFormatName("JBIG2");
+ if (!reader.hasNext())
+ {
+ log.error( "Can't find an ImageIO plugin to decode the JBIG2 encoded datastream.");
+ }
+ else
+ {
+ log.error( "Something went wrong when decoding the JBIG2 encoded datastream.");
+ }
}
}
/**
* {@inheritDoc}
*/
- public void encode( InputStream rawData, OutputStream result, COSDictionary options, int filterIndex )
+ public void encode( InputStream rawData, OutputStream result, COSDictionary options, int filterIndex )
throws IOException
{
System.err.println( "Warning: JBIG2.encode is not implemented yet, skipping this stream." );
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/filter/JPXFilter.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/filter/JPXFilter.java?rev=1151382&r1=1151381&r2=1151382&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/filter/JPXFilter.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/filter/JPXFilter.java Wed Jul 27 08:46:12 2011
@@ -33,21 +33,21 @@ import org.apache.pdfbox.cos.COSDictiona
* This is used for the JPXDecode filter.
*
* @author <a href="mailto:timo.boehme@ontochem.com">Timo Böhme</a>
- *
+ *
*/
public class JPXFilter implements Filter
{
- /** Log instance */
+ /** Log instance. */
private static final Log log = LogFactory.getLog(JPXFilter.class);
-
+
/**
* Decode JPEG2000 data using Java ImageIO library.
- *
+ *
* {@inheritDoc}
- *
+ *
*/
- public void decode( InputStream compressedData, OutputStream result, COSDictionary options, int filterIndex )
+ public void decode( InputStream compressedData, OutputStream result, COSDictionary options, int filterIndex )
throws IOException
{
BufferedImage bi = ImageIO.read( compressedData );
@@ -57,10 +57,10 @@ public class JPXFilter implements Filter
if ( dBuf.getDataType() == DataBuffer.TYPE_BYTE )
{
result.write( ( ( DataBufferByte ) dBuf ).getData() );
- }
+ }
else
{
- log.error( "Image data buffer not of type byte but type " + dBuf.getDataType() );
+ log.error( "Image data buffer not of type byte but type " + dBuf.getDataType() );
}
}
}
@@ -68,7 +68,7 @@ public class JPXFilter implements Filter
/**
* {@inheritDoc}
*/
- public void encode( InputStream rawData, OutputStream result, COSDictionary options, int filterIndex )
+ public void encode( InputStream rawData, OutputStream result, COSDictionary options, int filterIndex )
throws IOException
{
System.err.println( "Warning: JPXFilter.encode is not implemented yet, skipping this stream." );
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/BaseParser.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/BaseParser.java?rev=1151382&r1=1151381&r2=1151382&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/BaseParser.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/BaseParser.java Wed Jul 27 08:46:12 2011
@@ -110,7 +110,8 @@ public abstract class BaseParser
*/
protected final boolean forceParsing;
- public BaseParser() {
+ public BaseParser()
+ {
this.forceParsing = FORCE_PARSING;
}
@@ -124,7 +125,8 @@ public abstract class BaseParser
* @throws IOException If there is an error reading the input stream.
*/
public BaseParser(InputStream input, boolean forceParsing)
- throws IOException {
+ throws IOException
+ {
this.pdfSource = new PushBackInputStream(
new BufferedInputStream(input, 16384), 4096);
this.forceParsing = forceParsing;
@@ -232,17 +234,17 @@ public abstract class BaseParser
if( c == '>')
{
done = true;
- }
- else
- if(c != '/')
+ }
+ else
+ if(c != '/')
{
//an invalid dictionary, we are expecting
//the key, read until we can recover
- log.warn("Invalid dictionary, found: '" + (char)c + "' but expected: '/'");
+ log.warn("Invalid dictionary, found: '" + c + "' but expected: '/'");
int read = pdfSource.read();
while(read != -1 && read != '/' && read != '>')
{
- // in addition to stopping when we find / or >, we also want
+ // in addition to stopping when we find / or >, we also want
// to stop when we find endstream or endobj.
if(read==E) {
read = pdfSource.read();
@@ -281,7 +283,7 @@ public abstract class BaseParser
}
read = pdfSource.read();
}
- if(read != -1)
+ if(read != -1)
{
pdfSource.unread(read);
}
@@ -403,14 +405,14 @@ public abstract class BaseParser
String endStream = null;
readUntilEndStream(out);
skipSpaces();
- endStream = readString();
+ endStream = readString();
if (!endStream.equals("endstream"))
{
/*
* Sometimes stream objects don't have an endstream tag so readUntilEndStream(out)
* also can stop on endobj tags. If that's the case we need to make sure to unread
- * the endobj so parseObject() can handle that case normally.
+ * the endobj so parseObject() can handle that case normally.
*/
if (endStream.startsWith("endobj"))
{
@@ -418,7 +420,7 @@ public abstract class BaseParser
pdfSource.unread(endobjarray);
}
/*
- * Some PDF files don't contain a new line after endstream so we
+ * Some PDF files don't contain a new line after endstream so we
* need to make sure that the next object number is getting read separately
* and not part of the endstream keyword. Ex. Some files would have "endstream8"
* instead of "endstream"
@@ -461,9 +463,9 @@ public abstract class BaseParser
* object. Some pdf files, however, forget to write some endstream tags
* and just close off objects with an "endobj" tag so we have to handle
* this case as well.
- * @param out The stream we write out to.
+ * @param out The stream we write out to.
* @throws IOException
- */
+ */
private void readUntilEndStream( OutputStream out ) throws IOException{
int byteRead;
do{ //use a fail fast test for end of stream markers
@@ -530,7 +532,10 @@ public abstract class BaseParser
out.write(E);
}
}
- if(byteRead!=-1)out.write(byteRead);
+ if(byteRead!=-1)
+ {
+ out.write(byteRead);
+ }
}while(byteRead!=-1);
}
@@ -541,59 +546,60 @@ public abstract class BaseParser
* /Title ( (5)
* /Creator which was patched in 1 place.
* However it missed the case where the Close Paren was escaped
- *
- * The second bug was in this format
+ *
+ * The second bug was in this format
* /Title (c:\)
- * /Producer
- *
+ * /Producer
+ *
* This patch moves this code out of the parseCOSString method, so it can be used twice.
- *
- *
+ *
+ *
* @param bracesParameter the number of braces currently open.
- *
+ *
* @return the corrected value of the brace counter
* @throws IOException
*/
- private int checkForMissingCloseParen(final int bracesParameter) throws IOException {
- int braces=bracesParameter;
- byte[] nextThreeBytes = new byte[3];
- int amountRead = pdfSource.read(nextThreeBytes);
-
- //lets handle the special case seen in Bull River Rules and Regulations.pdf
- //The dictionary looks like this
- // 2 0 obj
- // <<
- // /Type /Info
- // /Creator (PaperPort http://www.scansoft.com)
- // /Producer (sspdflib 1.0 http://www.scansoft.com)
- // /Title ( (5)
- // /Author ()
- // /Subject ()
- //
- // Notice the /Title, the braces are not even but they should
- // be. So lets assume that if we encounter an this scenario
- // <end_brace><new_line><opening_slash> then that
- // means that there is an error in the pdf and assume that
- // was the end of the document.
- //
- if( amountRead == 3 )
- {
- if(( nextThreeBytes[0] == 0x0d && // Look for a carriage return
- nextThreeBytes[1] == 0x0a && // Look for a new line
- nextThreeBytes[2] == 0x2f ) || // Look for a slash /
- // Add a second case without a new line
- (nextThreeBytes[0] == 0x0d && // Look for a carriage return
- nextThreeBytes[1] == 0x2f )) // Look for a slash /
- {
- braces = 0;
- }
- }
- if (amountRead > 0)
+ private int checkForMissingCloseParen(final int bracesParameter) throws IOException
+ {
+ int braces = bracesParameter;
+ byte[] nextThreeBytes = new byte[3];
+ int amountRead = pdfSource.read(nextThreeBytes);
+
+ //lets handle the special case seen in Bull River Rules and Regulations.pdf
+ //The dictionary looks like this
+ // 2 0 obj
+ // <<
+ // /Type /Info
+ // /Creator (PaperPort http://www.scansoft.com)
+ // /Producer (sspdflib 1.0 http://www.scansoft.com)
+ // /Title ( (5)
+ // /Author ()
+ // /Subject ()
+ //
+ // Notice the /Title, the braces are not even but they should
+ // be. So lets assume that if we encounter an this scenario
+ // <end_brace><new_line><opening_slash> then that
+ // means that there is an error in the pdf and assume that
+ // was the end of the document.
+ //
+ if (amountRead == 3)
+ {
+ if (( nextThreeBytes[0] == 0x0d // Look for a carriage return
+ && nextThreeBytes[1] == 0x0a // Look for a new line
+ && nextThreeBytes[2] == 0x2f ) // Look for a slash /
+ // Add a second case without a new line
+ || (nextThreeBytes[0] == 0x0d // Look for a carriage return
+ && nextThreeBytes[1] == 0x2f )) // Look for a slash /
+ {
+ braces = 0;
+ }
+ }
+ if (amountRead > 0)
{
pdfSource.unread( nextThreeBytes, 0, amountRead );
}
- return braces;
- }
+ return braces;
+ }
/**
* This will parse a PDF string.
*
@@ -634,9 +640,9 @@ public abstract class BaseParser
if(ch == closeBrace)
{
-
- braces--;
- braces=checkForMissingCloseParen(braces);
+
+ braces--;
+ braces = checkForMissingCloseParen(braces);
if( braces != 0 )
{
retval.append( ch );
@@ -669,14 +675,15 @@ public abstract class BaseParser
retval.append( '\f' );
break;
case ')':
- // PDFBox 276 /Title (c:\)
- braces=checkForMissingCloseParen(braces);
+ // PDFBox 276 /Title (c:\)
+ braces = checkForMissingCloseParen(braces);
if( braces != 0 )
{
retval.append( next );
}
- else {
- retval.append('\\');
+ else
+ {
+ retval.append('\\');
}
break;
case '(':
@@ -806,23 +813,23 @@ public abstract class BaseParser
pbo = parseDirObject();
if( pbo instanceof COSObject )
{
- // We have to check if the expected values are there or not PDFBOX-385
- if (po.get(po.size()-1) instanceof COSInteger)
+ // We have to check if the expected values are there or not PDFBOX-385
+ if (po.get(po.size()-1) instanceof COSInteger)
{
COSInteger genNumber = (COSInteger)po.remove( po.size() -1 );
- if (po.get(po.size()-1) instanceof COSInteger)
+ if (po.get(po.size()-1) instanceof COSInteger)
{
COSInteger number = (COSInteger)po.remove( po.size() -1 );
COSObjectKey key = new COSObjectKey(number.intValue(), genNumber.intValue());
pbo = document.getObjectFromPool(key);
}
- else
+ else
{
// the object reference is somehow wrong
pbo = null;
}
}
- else
+ else
{
pbo = null;
}
@@ -835,13 +842,15 @@ public abstract class BaseParser
{
//it could be a bad object in the array which is just skipped
log.warn("Corrupt object reference" );
-
+
// This could also be an "endobj" or "endstream" which means we can assume that
// the array has ended.
String isThisTheEnd = readString();
pdfSource.unread(isThisTheEnd.getBytes("ISO-8859-1"));
if("endobj".equals(isThisTheEnd) || "endstream".equals(isThisTheEnd))
+ {
return po;
+ }
}
skipSpaces();
}
@@ -1102,10 +1111,12 @@ public abstract class BaseParser
throw new IOException( "Unknown dir object c='" + c +
"' cInt=" + (int)c + " peek='" + (char)peek + "' peekInt=" + peek + " " + pdfSource );
}
-
+
// if it's an endstream/endobj, we want to put it back so the caller will see it
if("endobj".equals(badString) || "endstream".equals(badString))
+ {
pdfSource.unread(badString.getBytes("ISO-8859-1"));
+ }
}
}
}
@@ -1247,7 +1258,7 @@ public abstract class BaseParser
*
* @throws IOException If there is an error reading from the stream.
*/
- protected String readLine() throws IOException
+ protected String readLine() throws IOException
{
if (pdfSource.isEOF())
{
@@ -1255,11 +1266,11 @@ public abstract class BaseParser
}
StringBuilder buffer = new StringBuilder( 11 );
-
+
int c;
- while ((c = pdfSource.read()) != -1)
+ while ((c = pdfSource.read()) != -1)
{
- if (isEOL(c))
+ if (isEOL(c))
{
break;
}
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/PDFParser.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/PDFParser.java?rev=1151382&r1=1151381&r2=1151382&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/PDFParser.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/PDFParser.java Wed Jul 27 08:46:12 2011
@@ -59,14 +59,14 @@ public class PDFParser extends BaseParse
private static final String FDF_HEADER = "%FDF-";
/**
* A list of duplicate objects found when Parsing the PDF
- * File.
+ * File.
*/
private List<ConflictObj> conflictList = new ArrayList<ConflictObj>();
-
+
/** Collects all Xref/trailer objects and resolves them into single
* object using startxref reference */
private XrefTrailerResolver xrefTrailerResolver = new XrefTrailerResolver();
-
+
/**
* Temp file directory.
*/
@@ -96,13 +96,13 @@ public class PDFParser extends BaseParse
throws IOException {
this(input, rafi, FORCE_PARSING);
}
-
+
/**
* Constructor to allow control over RandomAccessFile.
* Also enables parser to skip corrupt objects to try and force parsing
* @param input The input stream that contains the PDF document.
* @param rafi The RandomAccessFile to be used in internal COSDocument
- * @param force When true, the parser will skip corrupt pdf objects and
+ * @param force When true, the parser will skip corrupt pdf objects and
* will continue parsing at the next object in the file
*
* @throws IOException If there is an error initializing the stream.
@@ -127,17 +127,17 @@ public class PDFParser extends BaseParse
}
/**
- * Returns true if parsing should be continued. By default, forceParsing is returned.
- * This can be overridden to add application specific handling (for example to stop
+ * Returns true if parsing should be continued. By default, forceParsing is returned.
+ * This can be overridden to add application specific handling (for example to stop
* parsing when the number of exceptions thrown exceed a certain number).
- *
+ *
* @param e The exception if vailable. Can be null if there is no exception available
*/
protected boolean isContinueOnError(Exception e)
{
return forceParsing;
}
-
+
/**
* This will parse the stream and populate the COSDocument object. This will close
* the stream when it is done parsing.
@@ -167,7 +167,7 @@ public class PDFParser extends BaseParse
setDocument( document );
parseHeader();
-
+
//Some PDF files have garbage between the header and the
//first object
skipToNextObj();
@@ -187,9 +187,9 @@ public class PDFParser extends BaseParse
{
/*
* PDF files may have random data after the EOF marker. Ignore errors if
- * last object processed is EOF.
+ * last object processed is EOF.
*/
- if( wasLastParsedObjectEOF )
+ if( wasLastParsedObjectEOF )
{
break;
}
@@ -203,25 +203,25 @@ public class PDFParser extends BaseParse
skipToNextObj();
}
else
- {
+ {
throw e;
}
}
skipSpaces();
}
-
- // set xref to start with
+
+ // set xref to start with
xrefTrailerResolver.setStartxref( document.getStartXref() );
-
+
// get resolved xref table + trailer
document.setTrailer( xrefTrailerResolver.getTrailer() );
document.addXRefTable( xrefTrailerResolver.getXrefTable() );
-
+
if( !document.isEncrypted() )
{
document.dereferenceObjectStreams();
}
- ConflictObj.resolveConflicts(document, conflictList);
+ ConflictObj.resolveConflicts(document, conflictList);
}
catch( Throwable t )
{
@@ -245,22 +245,22 @@ public class PDFParser extends BaseParse
pdfSource.close();
}
}
-
+
/**
* Skip to the start of the next object. This is used to recover
* from a corrupt object. This should handle all cases that parseObject
* supports. This assumes that the next object will
* start on its own line.
- *
- * @throws IOException
+ *
+ * @throws IOException
*/
- private void skipToNextObj() throws IOException
+ private void skipToNextObj() throws IOException
{
byte[] b = new byte[16];
Pattern p = Pattern.compile("\\d+\\s+\\d+\\s+obj.*", Pattern.DOTALL);
/* Read a buffer of data each time to see if it starts with a
* known keyword. This is not the most efficient design, but we should
- * rarely be needing this function. We could update this to use the
+ * rarely be needing this function. We could update this to use the
* circular buffer, like in readUntilEndStream().
*/
while(!pdfSource.isEOF())
@@ -270,9 +270,9 @@ public class PDFParser extends BaseParse
{
break;
}
- String s = new String(b, "US-ASCII");
+ String s = new String(b, "US-ASCII");
if(s.startsWith("trailer") ||
- s.startsWith("xref") ||
+ s.startsWith("xref") ||
s.startsWith("startxref") ||
s.startsWith("stream") ||
p.matcher(s).matches())
@@ -284,7 +284,7 @@ public class PDFParser extends BaseParse
{
pdfSource.unread(b, 1, l-1);
}
- }
+ }
}
private void parseHeader() throws IOException
@@ -311,7 +311,7 @@ public class PDFParser extends BaseParse
{
throw new IOException( "Error: Header doesn't contain versioninfo" );
}
-
+
//sometimes there are some garbage bytes in the header before the header
//actually starts, so lets try to find the header first.
int headerStart = header.indexOf( PDF_HEADER );
@@ -331,18 +331,18 @@ public class PDFParser extends BaseParse
/*
* This is used if there is garbage after the header on the same line
*/
- if (header.startsWith(PDF_HEADER))
+ if (header.startsWith(PDF_HEADER))
{
- if(!header.matches(PDF_HEADER + "\\d.\\d"))
+ if(!header.matches(PDF_HEADER + "\\d.\\d"))
{
String headerGarbage = header.substring(PDF_HEADER.length()+3, header.length()) + "\n";
header = header.substring(0, PDF_HEADER.length()+3);
pdfSource.unread(headerGarbage.getBytes("ISO-8859-1"));
}
}
- else
+ else
{
- if(!header.matches(FDF_HEADER + "\\d.\\d"))
+ if(!header.matches(FDF_HEADER + "\\d.\\d"))
{
String headerGarbage = header.substring(FDF_HEADER.length()+3, header.length()) + "\n";
header = header.substring(0, FDF_HEADER.length()+3);
@@ -350,16 +350,16 @@ public class PDFParser extends BaseParse
}
}
document.setHeaderString(header);
-
+
try
{
- if (header.startsWith( PDF_HEADER ))
+ if (header.startsWith( PDF_HEADER ))
{
float pdfVersion = Float. parseFloat(
header.substring( PDF_HEADER.length(), Math.min( header.length(), PDF_HEADER .length()+3) ) );
document.setVersion( pdfVersion );
}
- else
+ else
{
float pdfVersion = Float. parseFloat(
header.substring( FDF_HEADER.length(), Math.min( header.length(), FDF_HEADER.length()+3) ) );
@@ -369,8 +369,8 @@ public class PDFParser extends BaseParse
catch ( NumberFormatException e )
{
throw new IOException( "Error getting pdf version:" + e );
- }
- }
+ }
+ }
/**
* This will get the document that was parsed. parse() must be called before this is called.
@@ -417,8 +417,8 @@ public class PDFParser extends BaseParse
}
/**
- * This will parse the next object from the stream and add it to
- * the local state.
+ * This will parse the next object from the stream and add it to
+ * the local state.
*
* @return Returns true if the processed object had an endOfFile marker
*
@@ -427,11 +427,11 @@ public class PDFParser extends BaseParse
private boolean parseObject() throws IOException
{
int currentObjByteOffset = pdfSource.getOffset();
- boolean isEndOfFile = false;
+ boolean isEndOfFile = false;
skipSpaces();
//peek at the next character to determine the type of object we are parsing
char peekedChar = (char)pdfSource.peek();
-
+
//ignore endobj and endstream sections.
while( peekedChar == 'e' )
{
@@ -447,46 +447,50 @@ public class PDFParser extends BaseParse
//end of file we will return a false and call it a day.
}
//xref table. Note: The contents of the Xref table are currently ignored
- else if( peekedChar == 'x')
+ else if( peekedChar == 'x')
{
parseXrefTable( currentObjByteOffset );
}
- // Note: startxref can occur in either a trailer section or by itself
- else if (peekedChar == 't' || peekedChar == 's')
+ // Note: startxref can occur in either a trailer section or by itself
+ else if (peekedChar == 't' || peekedChar == 's')
{
if(peekedChar == 't')
{
parseTrailer();
- peekedChar = (char)pdfSource.peek();
+ peekedChar = (char)pdfSource.peek();
}
if (peekedChar == 's')
- {
+ {
parseStartXref();
- // readString() calls skipSpaces() will skip comments... that's
+ // readString() calls skipSpaces() will skip comments... that's
// bad for us b/c the %%EOF flag is a comment
while(isWhitespace(pdfSource.peek()) && !pdfSource.isEOF())
+ {
pdfSource.read(); // read (get rid of) all the whitespace
+ }
String eof = "";
if(!pdfSource.isEOF())
+ {
eof = readLine(); // if there's more data to read, get the EOF flag
-
+ }
+
// verify that EOF exists (see PDFBOX-979 for documentation on special cases)
if(!"%%EOF".equals(eof)) {
if(eof.startsWith("%%EOF")) {
// content after marker -> unread with first space byte for read newline
- pdfSource.unread(SPACE_BYTE); // we read a whole line; add space as newline replacement
+ pdfSource.unread(SPACE_BYTE); // we read a whole line; add space as newline replacement
pdfSource.unread(eof.substring(5).getBytes("ISO-8859-1"));
} else {
- // PDF does not conform to spec, we should warn someone
- log.warn("expected='%%EOF' actual='" + eof + "'");
- // if we're not at the end of a file, just put it back and move on
- if(!pdfSource.isEOF()) {
- pdfSource.unread( SPACE_BYTE ); // we read a whole line; add space as newline replacement
- pdfSource.unread(eof.getBytes("ISO-8859-1"));
+ // PDF does not conform to spec, we should warn someone
+ log.warn("expected='%%EOF' actual='" + eof + "'");
+ // if we're not at the end of a file, just put it back and move on
+ if(!pdfSource.isEOF()) {
+ pdfSource.unread( SPACE_BYTE ); // we read a whole line; add space as newline replacement
+ pdfSource.unread(eof.getBytes("ISO-8859-1"));
}
}
}
- isEndOfFile = true;
+ isEndOfFile = true;
}
}
//we are going to parse an normal object
@@ -529,8 +533,8 @@ public class PDFParser extends BaseParse
if (!isContinueOnError(null) || !objectKey.equals("o")) {
throw new IOException("expected='obj' actual='" + objectKey + "' " + pdfSource);
}
- //assume that "o" was meant to be "obj" (this is a workaround for
- // PDFBOX-773 attached PDF Andersens_Fairy_Tales.pdf).
+ //assume that "o" was meant to be "obj" (this is a workaround for
+ // PDFBOX-773 attached PDF Andersens_Fairy_Tales.pdf).
}
}
else
@@ -542,7 +546,7 @@ public class PDFParser extends BaseParse
skipSpaces();
COSBase pb = parseDirObject();
String endObjectKey = readString();
-
+
if( endObjectKey.equals( "stream" ) )
{
pdfSource.unread( endObjectKey.getBytes("ISO-8859-1") );
@@ -550,14 +554,14 @@ public class PDFParser extends BaseParse
if( pb instanceof COSDictionary )
{
pb = parseCOSStream( (COSDictionary)pb, getDocument().getScratchFile() );
-
+
// test for XRef type
final COSStream strmObj = (COSStream) pb;
final COSName objectType = (COSName)strmObj.getItem( COSName.TYPE );
if( objectType != null && objectType.equals( COSName.XREF ) )
{
// XRef stream
- parseXrefStream( strmObj, currentObjByteOffset );
+ parseXrefStream( strmObj, currentObjByteOffset );
}
}
else
@@ -569,7 +573,7 @@ public class PDFParser extends BaseParse
skipSpaces();
endObjectKey = readLine();
}
-
+
COSObjectKey key = new COSObjectKey( number, genNum );
COSObject pdfObject = document.getObjectFromPool( key );
if(pdfObject.getObject() == null)
@@ -582,22 +586,22 @@ public class PDFParser extends BaseParse
*/
else
{
- addObjectToConflicts(currentObjByteOffset, key, pb);
+ addObjectToConflicts(currentObjByteOffset, key, pb);
}
-
+
if( !endObjectKey.equals( "endobj" ) )
{
- if (endObjectKey.startsWith( "endobj" ) )
+ if (endObjectKey.startsWith( "endobj" ) )
{
/*
- * Some PDF files don't contain a new line after endobj so we
+ * Some PDF files don't contain a new line after endobj so we
* need to make sure that the next object number is getting read separately
* and not part of the endobj keyword. Ex. Some files would have "endobj28"
* instead of "endobj"
*/
pdfSource.unread( SPACE_BYTE ); // add a space first in place of the newline consumed by readline()
pdfSource.unread( endObjectKey.substring( 6 ).getBytes("ISO-8859-1") );
- }
+ }
else if(endObjectKey.trim().endsWith("endobj"))
{
/*
@@ -620,7 +624,7 @@ public class PDFParser extends BaseParse
}
return isEndOfFile;
}
-
+
/**
* Adds a new ConflictObj to the conflictList.
* @param offset the offset of the ConflictObj
@@ -635,21 +639,21 @@ public class PDFParser extends BaseParse
obj.setGenerationNumber( COSInteger.get( key.getGeneration() ) );
obj.setObject(pb);
ConflictObj conflictObj = new ConflictObj(offset, key, obj);
- conflictList.add(conflictObj);
+ conflictList.add(conflictObj);
}
/**
* This will parse the startxref section from the stream.
* The startxref value is ignored.
- *
- * @return false on parsing error
+ *
+ * @return false on parsing error
* @throws IOException If an IO error occurs.
*/
private boolean parseStartXref() throws IOException
{
if(pdfSource.peek() != 's')
{
- return false;
+ return false;
}
String startXRef = readString();
if( !startXRef.trim().equals( "startxref" ) )
@@ -668,8 +672,8 @@ public class PDFParser extends BaseParse
/**
* This will parse the xref table from the stream and add it to the state
* The XrefTable contents are ignored.
- * @param startByteOffset the offset to start at
- * @return false on parsing error
+ * @param startByteOffset the offset to start at
+ * @return false on parsing error
* @throws IOException If an IO error occurs.
*/
private boolean parseXrefTable( int startByteOffset ) throws IOException
@@ -679,16 +683,16 @@ public class PDFParser extends BaseParse
return false;
}
String xref = readString();
- if( !xref.trim().equals( "xref" ) )
+ if( !xref.trim().equals( "xref" ) )
{
return false;
}
-
+
// signal start of new XRef
xrefTrailerResolver.nextXrefObj( startByteOffset );
-
+
/*
- * Xref tables can have multiple sections.
+ * Xref tables can have multiple sections.
* Each starts with a starting object id and a count.
*/
while(true)
@@ -714,7 +718,7 @@ public class PDFParser extends BaseParse
log.warn("invalid xref line: " + currentLine);
break;
}
- /* This supports the corrupt table as reported in
+ /* This supports the corrupt table as reported in
* PDFBOX-474 (XXXX XXX XX n) */
if(splitString[splitString.length-1].equals("n"))
{
@@ -749,7 +753,7 @@ public class PDFParser extends BaseParse
/**
* This will parse the trailer from the stream and add it to the state.
- *
+ *
* @return false on parsing error
* @throws IOException If an IO error occurs.
*/
@@ -761,20 +765,20 @@ public class PDFParser extends BaseParse
}
//read "trailer"
String nextLine = readLine();
- if( !nextLine.trim().equals( "trailer" ) )
+ if( !nextLine.trim().equals( "trailer" ) )
{
- // in some cases the EOL is missing and the trailer immediately
+ // in some cases the EOL is missing and the trailer immediately
// continues with "<<" or with a blank character
// even if this does not comply with PDF reference we want to support as many PDFs as possible
// Acrobat reader can also deal with this.
- if (nextLine.startsWith("trailer"))
+ if (nextLine.startsWith("trailer"))
{
byte[] b = nextLine.getBytes("ISO-8859-1");
int len = "trailer".length();
pdfSource.unread('\n');
pdfSource.unread(b, len, b.length-len);
}
- else
+ else
{
return false;
}
@@ -794,23 +798,23 @@ public class PDFParser extends BaseParse
skipSpaces();
return true;
}
-
+
/**
* The document catalog can also have a /Version parameter which overrides the version specified
* in the header if, and only if it is greater.
- *
+ *
* @param parsedTrailer the parsed catalog in the trailer
*/
- private void readVersionInTrailer(COSDictionary parsedTrailer)
+ private void readVersionInTrailer(COSDictionary parsedTrailer)
{
COSObject root = (COSObject) parsedTrailer.getItem(COSName.ROOT);
if (root != null)
{
COSName version = (COSName) root.getItem(COSName.VERSION);
- if (version != null)
+ if (version != null)
{
float trailerVersion = Float.valueOf(version.getName());
- if (trailerVersion > document.getVersion())
+ if (trailerVersion > document.getVersion())
{
document.setVersion(trailerVersion);
}
@@ -828,20 +832,20 @@ public class PDFParser extends BaseParse
public void parseXrefStream( COSStream stream, int objByteOffset ) throws IOException
{
xrefTrailerResolver.nextXrefObj( objByteOffset );
- xrefTrailerResolver.setTrailer( stream );
- PDFXrefStreamParser parser =
+ xrefTrailerResolver.setTrailer( stream );
+ PDFXrefStreamParser parser =
new PDFXrefStreamParser( stream, document, forceParsing, xrefTrailerResolver );
parser.parse();
}
-
+
/**
* Used to resolve conflicts when a PDF Document has multiple objects with
* the same id number. Ideally, we could use the Xref table when parsing
* the document to be able to determine which of the objects with the same ID
* is correct, but we do not have access to the Xref Table during parsing.
* Instead, we queue up the conflicts and resolve them after the Xref has
- * been parsed. The Objects listed in the Xref Table are kept and the
- * others are ignored.
+ * been parsed. The Objects listed in the Xref Table are kept and the
+ * others are ignored.
*/
private static class ConflictObj
{
@@ -849,8 +853,8 @@ public class PDFParser extends BaseParse
private int offset;
private COSObjectKey objectKey;
private COSObject object;
-
- public ConflictObj(int offsetValue, COSObjectKey key, COSObject pdfObject)
+
+ public ConflictObj(int offsetValue, COSObjectKey key, COSObject pdfObject)
{
this.offset = offsetValue;
this.objectKey = key;
@@ -861,13 +865,13 @@ public class PDFParser extends BaseParse
{
return "Object(" + offset + ", " + objectKey + ")";
}
-
+
/**
* Sometimes pdf files have objects with the same ID number yet are
- * not referenced by the Xref table and therefore should be excluded.
+ * not referenced by the Xref table and therefore should be excluded.
* This method goes through the conflicts list and replaces the object stored
* in the objects array with this one if it is referenced by the xref
- * table.
+ * table.
* @throws IOException
*/
private static void resolveConflicts(COSDocument document, List<ConflictObj> conflictList) throws IOException
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/PDFStreamParser.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/PDFStreamParser.java?rev=1151382&r1=1151381&r2=1151382&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/PDFStreamParser.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/PDFStreamParser.java Wed Jul 27 08:46:12 2011
@@ -149,66 +149,63 @@ public class PDFStreamParser extends Bas
{
return streamObjects;
}
-
+
public void close() throws IOException
{
- pdfSource.close();
+ pdfSource.close();
}
/**
* This will get an iterator which can be used to parse the stream
* one token after the other.
- *
+ *
* @return an iterator to get one token after the other
*/
public Iterator<Object> getTokenIterator()
{
return new Iterator<Object>()
{
- private Object token;
-
- private void tryNext()
- {
- try {
- if(token == null)
- {
- token = parseNextToken();
- }
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean hasNext()
- {
- tryNext();
- return token != null;
- }
-
- /**
- * {@inheritDoc}
- */
- public Object next() {
- tryNext();
- Object tmp = token;
- if(tmp == null)
- {
- throw new NoSuchElementException();
- }
- token = null;
- return tmp;
- }
-
- /**
- * {@inheritDoc}
- */
- public void remove()
- {
- throw new UnsupportedOperationException();
- }
+ private Object token;
+
+ private void tryNext()
+ {
+ try
+ {
+ if (token == null)
+ {
+ token = parseNextToken();
+ }
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public boolean hasNext()
+ {
+ tryNext();
+ return token != null;
+ }
+
+ /** {@inheritDoc} */
+ public Object next() {
+ tryNext();
+ Object tmp = token;
+ if (tmp == null)
+ {
+ throw new NoSuchElementException();
+ }
+ token = null;
+ return tmp;
+ }
+
+ /** {@inheritDoc} */
+ public void remove()
+ {
+ throw new UnsupportedOperationException();
+ }
};
}
@@ -461,25 +458,25 @@ public class PDFStreamParser extends Bas
//average string size is around 2 and the normal string buffer size is
//about 16 so lets save some space.
StringBuffer buffer = new StringBuffer(4);
- int nextChar = (int)pdfSource.peek();
+ int nextChar = pdfSource.peek();
while(
nextChar != -1 && // EOF
!isWhitespace(nextChar) &&
!isClosing(nextChar) &&
- nextChar != (int)'[' &&
- nextChar != (int)'<' &&
- nextChar != (int)'(' &&
- nextChar != (int)'/' &&
- (nextChar < (int)'0' ||
- nextChar > (int)'9' ) )
+ nextChar != '[' &&
+ nextChar != '<' &&
+ nextChar != '(' &&
+ nextChar != '/' &&
+ (nextChar < '0' ||
+ nextChar > '9' ) )
{
char currentChar = (char)pdfSource.read();
- nextChar = (int)pdfSource.peek();
+ nextChar = pdfSource.peek();
buffer.append( currentChar );
- // Type3 Glyph description has operators with a number in the name
+ // Type3 Glyph description has operators with a number in the name
if (currentChar == 'd' && (nextChar == '0' || nextChar == '1') ) {
buffer.append( (char)pdfSource.read() );
- nextChar = (int)pdfSource.peek();
+ nextChar = pdfSource.peek();
}
}
return buffer.toString();
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/PDFXrefStreamParser.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/PDFXrefStreamParser.java?rev=1151382&r1=1151381&r2=1151382&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/PDFXrefStreamParser.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/PDFXrefStreamParser.java Wed Jul 27 08:46:12 2011
@@ -30,13 +30,13 @@ import org.apache.pdfbox.cos.COSStream;
import org.apache.pdfbox.persistence.util.COSObjectKey;
/**
- * This will parse a PDF 1.5 (or better) Xref stream and
+ * This will parse a PDF 1.5 (or better) Xref stream and
* extract the xref information from the stream.
- *
+ *
* @author <a href="mailto:justinl@basistech.com">Justin LeFebvre</a>
* @version $Revision: 1.0 $
*/
-public class PDFXrefStreamParser extends BaseParser
+public class PDFXrefStreamParser extends BaseParser
{
private COSStream stream;
private XrefTrailerResolver xrefTrailerResolver;
@@ -47,16 +47,17 @@ public class PDFXrefStreamParser extends
* @since 1.3.0
* @param strm The stream to parse.
* @param doc The document for the current parsing.
- * @param forceParcing flag to skip malformed or otherwise unparseable
+ * @param forceParsing flag to skip malformed or otherwise unparseable
* input where possible
- * @param xrefTrailerResolver resolver to read the xref/trailer information
- *
+ * @param xrefTrailerResolver resolver to read the xref/trailer information
+ *
* @throws IOException If there is an error initializing the stream.
*/
public PDFXrefStreamParser(
COSStream strm, COSDocument doc, boolean forceParsing,
XrefTrailerResolver xrefTrailerResolver )
- throws IOException {
+ throws IOException
+ {
super(strm.getUnfilteredStream(), forceParsing);
setDocument(doc);
stream = strm;
@@ -74,7 +75,7 @@ public class PDFXrefStreamParser extends
COSArray xrefFormat = (COSArray)stream.getDictionaryObject(COSName.W);
COSArray indexArray = (COSArray)stream.getDictionaryObject(COSName.INDEX);
/*
- * If Index doesn't exist, we will use the default values.
+ * If Index doesn't exist, we will use the default values.
*/
if(indexArray == null)
{
@@ -82,9 +83,9 @@ public class PDFXrefStreamParser extends
indexArray.add(COSInteger.ZERO);
indexArray.add(stream.getDictionaryObject(COSName.SIZE));
}
-
+
ArrayList<Integer> objNums = new ArrayList<Integer>();
-
+
/*
* Populates objNums with all object numbers available
*/
@@ -106,7 +107,7 @@ public class PDFXrefStreamParser extends
int w1 = xrefFormat.getInt(1);
int w2 = xrefFormat.getInt(2);
int lineSize = w0 + w1 + w2;
-
+
while(pdfSource.available() > 0 && objIter.hasNext())
{
byte[] currLine = new byte[lineSize];
@@ -114,7 +115,7 @@ public class PDFXrefStreamParser extends
int type = 0;
/*
- * Grabs the number of bytes specified for the first column in
+ * Grabs the number of bytes specified for the first column in
* the W array and stores it.
*/
for(int i = 0; i < w0; i++)
@@ -122,9 +123,9 @@ public class PDFXrefStreamParser extends
type += (currLine[i] & 0x00ff) << ((w0 - i - 1)* 8);
}
//Need to remember the current objID
- Integer objID = (Integer)objIter.next();
+ Integer objID = objIter.next();
/*
- * 3 different types of entries.
+ * 3 different types of entries.
*/
switch(type)
{
@@ -133,7 +134,7 @@ public class PDFXrefStreamParser extends
* Skipping free objects
*/
break;
- case 1:
+ case 1:
int offset = 0;
for(int i = 0; i < w1; i++)
{
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/XrefTrailerResolver.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/XrefTrailerResolver.java?rev=1151382&r1=1151381&r2=1151382&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/XrefTrailerResolver.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/XrefTrailerResolver.java Wed Jul 27 08:46:12 2011
@@ -28,7 +28,7 @@ import org.apache.pdfbox.cos.COSDictiona
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.persistence.util.COSObjectKey;
-/**
+/**
* This class will collect all XRef/trailer objects and creates correct
* xref/trailer information after all objects are read using startxref
* and 'Prev' information (unused XRef/trailer objects are discarded).
@@ -36,48 +36,47 @@ import org.apache.pdfbox.persistence.uti
* In case of missing startxref or wrong startxref pointer all
* XRef/trailer objects are used to create xref table / trailer dictionary
* in order they occur.
- *
+ *
* For each new xref object/XRef stream method {@link #nextXrefObj(int)}
* must be called with start byte position. All following calls to
* {@link #setXRef(COSObjectKey, int)} or {@link #setTrailer(COSDictionary)}
* will add the data for this byte position.
- *
+ *
* After all objects are parsed the startxref position must be provided
* using {@link #setStartxref(int)}. This is used to build the chain of
* active xref/trailer objects used for creating document trailer and xref table.
- *
+ *
* @author Timo Böhme (timo.boehme at ontochem.com)
*/
public class XrefTrailerResolver
{
/**
- * A class which represents a xref/trailer object
- *
+ * A class which represents a xref/trailer object.
*/
- class XrefTrailerObj
- {
- private COSDictionary trailer = null;
- private final Map<COSObjectKey, Integer> xrefTable = new HashMap<COSObjectKey, Integer>();
- }
-
- private final Map<Integer, XrefTrailerObj> bytePosToXrefMap = new HashMap<Integer, XrefTrailerObj>();
- private XrefTrailerObj curXrefTrailerObj = null;
- private XrefTrailerObj resolvedXrefTrailer = null;
-
+ class XrefTrailerObj
+ {
+ private COSDictionary trailer = null;
+ private final Map<COSObjectKey, Integer> xrefTable = new HashMap<COSObjectKey, Integer>();
+ }
+
+ private final Map<Integer, XrefTrailerObj> bytePosToXrefMap = new HashMap<Integer, XrefTrailerObj>();
+ private XrefTrailerObj curXrefTrailerObj = null;
+ private XrefTrailerObj resolvedXrefTrailer = null;
+
/** Log instance. */
private static final Log log = LogFactory.getLog( XrefTrailerResolver.class );
-
- /**
- * Signals that a new XRef object (table or stream) starts.
- * @param startBytePos the offset to start at
- *
- */
- public void nextXrefObj( final int startBytePos )
- {
- bytePosToXrefMap.put( startBytePos, curXrefTrailerObj = new XrefTrailerObj() );
- }
-
+
+ /**
+ * Signals that a new XRef object (table or stream) starts.
+ * @param startBytePos the offset to start at
+ *
+ */
+ public void nextXrefObj( final int startBytePos )
+ {
+ bytePosToXrefMap.put( startBytePos, curXrefTrailerObj = new XrefTrailerObj() );
+ }
+
/**
* Populate XRef HashMap of current XRef object.
* Will add an Xreftable entry that maps ObjectKeys to byte offsets in the file.
@@ -86,15 +85,15 @@ public class XrefTrailerResolver
*/
public void setXRef( COSObjectKey objKey, int offset )
{
- if ( curXrefTrailerObj == null )
- {
+ if ( curXrefTrailerObj == null )
+ {
// should not happen...
- log.warn( "Cannot add XRef entry for '" + objKey.getNumber() + "' because XRef start was not signalled." );
- return;
- }
+ log.warn( "Cannot add XRef entry for '" + objKey.getNumber() + "' because XRef start was not signalled." );
+ return;
+ }
curXrefTrailerObj.xrefTable.put( objKey, offset );
}
-
+
/**
* Adds trailer information for current XRef object.
*
@@ -102,20 +101,20 @@ public class XrefTrailerResolver
*/
public void setTrailer( COSDictionary trailer )
{
- if ( curXrefTrailerObj == null )
+ if ( curXrefTrailerObj == null )
{
// should not happen...
- log.warn( "Cannot add trailer because XRef start was not signalled." );
- return;
+ log.warn( "Cannot add trailer because XRef start was not signalled." );
+ return;
}
curXrefTrailerObj.trailer = trailer;
}
-
- /**
+
+ /**
* Sets the byte position of the first XRef
* (has to be called after very last startxref was read).
* This is used to resolve chain of active XRef/trailer.
- *
+ *
* In case startxref position is not found we output a
* warning and use all XRef/trailer objects combined
* in byte position order.
@@ -124,84 +123,84 @@ public class XrefTrailerResolver
*/
public void setStartxref( int startxrefBytePos )
{
- if ( resolvedXrefTrailer != null )
- {
+ if ( resolvedXrefTrailer != null )
+ {
log.warn( "Method must be called only ones with last startxref value." );
- return;
- }
-
- resolvedXrefTrailer = new XrefTrailerObj();
- resolvedXrefTrailer.trailer = new COSDictionary();
-
- XrefTrailerObj curObj = bytePosToXrefMap.get( startxrefBytePos );
- List<Integer> xrefSeqBytePos = new ArrayList<Integer>();
-
- if ( curObj == null )
- {
- // no XRef at given position
- log.warn( "Did not found XRef object at specified startxref position " + startxrefBytePos );
-
- // use all objects in byte position order (last entries overwrite previous ones)
- xrefSeqBytePos.addAll( bytePosToXrefMap.keySet() );
- Collections.sort( xrefSeqBytePos );
- }
- else
- {
- // found starting Xref object
- // add this and follow chain defined by 'Prev' keys
- xrefSeqBytePos.add( startxrefBytePos );
- while ( curObj.trailer != null )
- {
- int prevBytePos = curObj.trailer.getInt( COSName.PREV, -1 );
- if ( prevBytePos == -1 )
- {
- break;
- }
-
- curObj = bytePosToXrefMap.get( prevBytePos );
- if ( curObj == null )
- {
- log.warn( "Did not found XRef object pointed to by 'Prev' key at position " + prevBytePos );
- break;
- }
- xrefSeqBytePos.add( prevBytePos );
-
- // sanity check to prevent infinite loops
- if ( xrefSeqBytePos.size() >= bytePosToXrefMap.size() )
- {
- break;
- }
- }
- // have to reverse order so that later XRefs will overwrite previous ones
- Collections.reverse( xrefSeqBytePos );
- }
-
- // merge used and sorted XRef/trailer
- for ( Integer bPos : xrefSeqBytePos )
- {
- curObj = bytePosToXrefMap.get( bPos );
- if ( curObj.trailer != null )
- {
- resolvedXrefTrailer.trailer.addAll( curObj.trailer );
- }
- resolvedXrefTrailer.xrefTable.putAll( curObj.xrefTable );
- }
-
+ return;
+ }
+
+ resolvedXrefTrailer = new XrefTrailerObj();
+ resolvedXrefTrailer.trailer = new COSDictionary();
+
+ XrefTrailerObj curObj = bytePosToXrefMap.get( startxrefBytePos );
+ List<Integer> xrefSeqBytePos = new ArrayList<Integer>();
+
+ if ( curObj == null )
+ {
+ // no XRef at given position
+ log.warn( "Did not found XRef object at specified startxref position " + startxrefBytePos );
+
+ // use all objects in byte position order (last entries overwrite previous ones)
+ xrefSeqBytePos.addAll( bytePosToXrefMap.keySet() );
+ Collections.sort( xrefSeqBytePos );
+ }
+ else
+ {
+ // found starting Xref object
+ // add this and follow chain defined by 'Prev' keys
+ xrefSeqBytePos.add( startxrefBytePos );
+ while ( curObj.trailer != null )
+ {
+ int prevBytePos = curObj.trailer.getInt( COSName.PREV, -1 );
+ if ( prevBytePos == -1 )
+ {
+ break;
+ }
+
+ curObj = bytePosToXrefMap.get( prevBytePos );
+ if ( curObj == null )
+ {
+ log.warn( "Did not found XRef object pointed to by 'Prev' key at position " + prevBytePos );
+ break;
+ }
+ xrefSeqBytePos.add( prevBytePos );
+
+ // sanity check to prevent infinite loops
+ if ( xrefSeqBytePos.size() >= bytePosToXrefMap.size() )
+ {
+ break;
+ }
+ }
+ // have to reverse order so that later XRefs will overwrite previous ones
+ Collections.reverse( xrefSeqBytePos );
+ }
+
+ // merge used and sorted XRef/trailer
+ for ( Integer bPos : xrefSeqBytePos )
+ {
+ curObj = bytePosToXrefMap.get( bPos );
+ if ( curObj.trailer != null )
+ {
+ resolvedXrefTrailer.trailer.addAll( curObj.trailer );
+ }
+ resolvedXrefTrailer.xrefTable.putAll( curObj.xrefTable );
+ }
+
}
-
- /**
+
+ /**
* Gets the resolved trailer. Might return <code>null</code> in case
- * {@link #setStartxref(int)} was not called before.
- *
+ * {@link #setStartxref(int)} was not called before.
+ *
*/
public COSDictionary getTrailer()
{
return ( resolvedXrefTrailer == null ) ? null : resolvedXrefTrailer.trailer;
}
-
- /**
+
+ /**
* Gets the resolved xref table. Might return <code>null</code> in case
- * {@link #setStartxref(int)} was not called before.
+ * {@link #setStartxref(int)} was not called before.
*
*/
public Map<COSObjectKey, Integer> getXrefTable()
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDPage.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDPage.java?rev=1151382&r1=1151381&r2=1151382&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDPage.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDPage.java Wed Jul 27 08:46:12 2011
@@ -71,14 +71,14 @@ public class PDPage implements COSObject
private static final Log log = LogFactory.getLog(PDPage.class);
private static final int DEFAULT_USER_SPACE_UNIT_DPI = 72;
-
+
private static final float MM_TO_UNITS = 1/(10*2.54f)*DEFAULT_USER_SPACE_UNIT_DPI;
-
+
/**
* Fully transparent that can fall back to white when image type has no alpha.
*/
- private static final Color TRANSPARENT_WHITE = new Color( 255, 255, 255, 0 );
-
+ private static final Color TRANSPARENT_WHITE = new Color( 255, 255, 255, 0 );
+
private COSDictionary page;
/**
@@ -126,7 +126,7 @@ public class PDPage implements COSObject
/**
* Creates a new instance of PDPage.
- *
+ *
* @param size The MediaBox or the page.
*/
public PDPage(PDRectangle size)
@@ -136,8 +136,8 @@ public class PDPage implements COSObject
setMediaBox( size );
}
-
-
+
+
/**
* Creates a new instance of PDPage.
*
@@ -177,7 +177,8 @@ public class PDPage implements COSObject
*/
public PDPageNode getParent()
{
- if( parent == null){
+ if( parent == null)
+ {
COSDictionary parentDic = (COSDictionary)page.getDictionaryObject( "Parent", "P" );
if( parentDic != null )
{
@@ -188,7 +189,7 @@ public class PDPage implements COSObject
}
private PDPageNode parent = null;
-
+
/**
* This will set the parent of this page.
*
@@ -279,18 +280,19 @@ public class PDPage implements COSObject
*/
public PDRectangle getMediaBox()
{
- if( mediaBox == null){
+ if( mediaBox == null)
+ {
COSArray array = (COSArray)page.getDictionaryObject( COSName.MEDIA_BOX );
if( array != null )
{
- mediaBox = new PDRectangle( array );
+ mediaBox = new PDRectangle( array );
}
}
return mediaBox;
}
private PDRectangle mediaBox = null;
-
+
/**
* This will find the MediaBox for this page by looking up the hierarchy until
* it finds them.
@@ -306,7 +308,7 @@ public class PDPage implements COSObject
}
return retval;
}
-
+
/**
* This will set the mediaBox for this page.
*
@@ -315,7 +317,7 @@ public class PDPage implements COSObject
public void setMediaBox( PDRectangle mediaBox )
{
this.mediaBox = mediaBox;
- if( mediaBox == null )
+ if( mediaBox == null )
{
page.removeItem( COSName.MEDIA_BOX );
}
@@ -692,7 +694,7 @@ public class PDPage implements COSObject
//and let the client scale it down.
return convertToImage(8, 2 * DEFAULT_USER_SPACE_UNIT_DPI);
}
-
+
/**
* Convert this page to an output image.
*
@@ -712,7 +714,7 @@ public class PDPage implements COSObject
int heightPx = Math.round(heightPt * scaling);
//TODO The following reduces accuracy. It should really be a Dimension2D.Float.
Dimension pageDimension = new Dimension( (int)widthPt, (int)heightPt );
-
+
BufferedImage retval = new BufferedImage( widthPx, heightPx, imageType );
Graphics2D graphics = (Graphics2D)retval.getGraphics();
graphics.setBackground( TRANSPARENT_WHITE );
@@ -723,19 +725,19 @@ public class PDPage implements COSObject
//TODO This could be done directly by manipulating the transformation matrix before painting.
//That could result in a better image quality.
- try
+ try
{
int rotation = findRotation();
- if (rotation == 90 || rotation == 270)
+ if (rotation == 90 || rotation == 270)
{
- int w = retval.getWidth();
- int h = retval.getHeight();
- BufferedImage rotatedImg = new BufferedImage(w, h, retval.getType());
- Graphics2D g = rotatedImg.createGraphics();
- g.rotate(Math.toRadians(rotation), w/2, h/2);
- g.drawImage(retval, null, 0, 0);
+ int w = retval.getWidth();
+ int h = retval.getHeight();
+ BufferedImage rotatedImg = new BufferedImage(w, h, retval.getType());
+ Graphics2D g = rotatedImg.createGraphics();
+ g.rotate(Math.toRadians(rotation), w/2, h/2);
+ g.drawImage(retval, null, 0, 0);
}
- }
+ }
catch (ImagingOpException e)
{
log.warn("Unable to rotate page image", e);