📄 pdccitt.java
字号:
raf.seek(dataoffset);
byte[] buf = new byte[8192];
int amountRead = -1;
while( (amountRead = raf.read( buf,0, Math.min(8192,datalength) )) > 0 )
{
datalength -= amountRead;
os.write( buf, 0, amountRead );
}
}
finally
{
os.close();
}
}
private int readshort(char endianess, RandomAccess raf) throws IOException
{
if (endianess == 'I')
{
return raf.read() | (raf.read() << 8);
}
return (raf.read() << 8) | raf.read();
}
private int readlong(char endianess, RandomAccess raf) throws IOException
{
if (endianess == 'I')
{
return raf.read() | (raf.read() << 8) | (raf.read() << 16) | (raf.read() << 24);
}
return (raf.read() << 24) | (raf.read() << 16) | (raf.read() << 8) | raf.read();
}
/**
* Extends InputStream to wrap the data from the CCITT Fax with a suitable TIFF Header.
* For details see www.tiff.org, which contains useful information including pointers to the
* TIFF 6.0 Specification
*
*/
private class TiffWrapper extends InputStream
{
private int currentOffset; // When reading, where in the tiffheader are we.
private byte[] tiffheader; // Byte array to store tiff header data
private InputStream datastream; // Original InputStream
private TiffWrapper(InputStream rawstream, COSDictionary options)
{
buildHeader(options);
currentOffset=0;
datastream = rawstream;
}
// Implement basic methods from InputStream
/**
* {@inheritDoc}
*/
public boolean markSupported()
{
return false;
}
/**
* {@inheritDoc}
*/
public void reset() throws IOException
{
throw new IOException("reset not supported");
}
/**
* For simple read, take a byte from the tiffheader array or pass through.
*
* {@inheritDoc}
*/
public int read() throws IOException
{
if (currentOffset < tiffheader.length)
{
return tiffheader[currentOffset++];
}
return datastream.read();
}
/**
* For read methods only return as many bytes as we have left in the header
* if we've exhausted the header, pass through to the InputStream of the raw CCITT data.
*
* {@inheritDoc}
*/
public int read(byte[] data) throws IOException
{
if (currentOffset < tiffheader.length)
{
int length = java.lang.Math.min(tiffheader.length - currentOffset, data.length);
if (length > 0)
{
System.arraycopy(tiffheader, currentOffset, data, 0, length);
}
currentOffset += length;
return length;
}
else
{
return datastream.read(data);
}
}
/**
* For read methods only return as many bytes as we have left in the header
* if we've exhausted the header, pass through to the InputStream of the raw CCITT data.
*
* {@inheritDoc}
*/
public int read(byte[] data, int off, int len) throws IOException
{
if (currentOffset < tiffheader.length)
{
int length = java.lang.Math.min(tiffheader.length - currentOffset, len);
if (length > 0)
{
System.arraycopy(tiffheader, currentOffset, data, off, length);
}
currentOffset += length;
return length;
}
else
{
return datastream.read(data,off,len);
}
}
/**
* When skipping if any header data not yet read, only allow to skip what we've in the buffer
* Otherwise just pass through.
*
* {@inheritDoc}
*/
public long skip(long n) throws IOException
{
if (currentOffset < tiffheader.length)
{
long length = Math.min(tiffheader.length - currentOffset, n);
currentOffset += length;
return length;
}
else
{
return datastream.skip(n);
}
}
// Static data for the beginning of the TIFF header
private final byte[] basicHeader = {
'I','I',42,0,8,0,0,0, // File introducer and pointer to first IFD
0,0}; // Number of tags start with two
private int additionalOffset; // Offset in header to additional data
// Builds up the tiffheader based on the options passed through.
private void buildHeader(COSDictionary options)
{
final int numOfTags = 10; // The maximum tags we'll fill
final int maxAdditionalData = 24; // The maximum amount of additional data
// outside the IFDs. (bytes)
// The length of the header will be the length of the basic header (10)
// plus 12 bytes for each IFD, 4 bytes as a pointer to the next IFD (will be 0)
// plus the length of the additional data
tiffheader = new byte[10 + (12 * numOfTags ) + 4 + maxAdditionalData];
java.util.Arrays.fill(tiffheader,(byte)0);
System.arraycopy(basicHeader,0,tiffheader,0,basicHeader.length);
// Additional data outside the IFD starts after the IFD's and pointer to the next IFD (0)
additionalOffset = 10 + (12 * numOfTags ) + 4;
// Now work out the variable values from TIFF defaults,
// PDF Defaults and the Dictionary for this XObject
short cols = 1728;
short rows = 0;
short blackis1 = 0;
short comptype = 3; // T4 compression
long t4options = 0; // Will set if 1d or 2d T4
COSDictionary decodeParms = (COSDictionary) options.getDictionaryObject("DecodeParms");
if (decodeParms != null)
{
cols = (short) decodeParms.getInt("Columns", cols);
rows = (short) decodeParms.getInt("Rows", rows);
if (decodeParms.getBoolean("BlackIs1", false))
{
blackis1 = 1;
}
int k = decodeParms.getInt("K"); // Mandatory parm
if (k < 0)
{
//T6
comptype = 4;
}
if (k > 0)
{
//T4 2D
comptype = 3;
t4options = 1;
}
// else k = 0, leave as default T4 1D compression
}
// If we couldn't get the number of rows, use the main item from XObject
if (rows == 0)
{
rows = (short) options.getInt("Height", rows);
}
// Now put the tags into the tiffheader
// These musn't exceed the maximum set above, and by TIFF spec should be sorted into
// Numeric sequence.
addTag(256, cols); // Columns
addTag(257, rows); // Rows
addTag(259, comptype); // T6
addTag(262, blackis1); // Photometric Interpretation
addTag(273, tiffheader.length); // Offset to start of image data - updated below
addTag(279, options.getInt("Length")); // Length of image data
addTag(282, 300, 1); // X Resolution 300 (default unit Inches) This is arbitary
addTag(283, 300, 1); // Y Resolution 300 (default unit Inches) This is arbitary
if (comptype == 3)
{
addTag(292, t4options);
}
addTag(305, "PDFBOX"); // Software generating image
}
/* Tiff types 1 = byte, 2=ascii, 3=short, 4=ulong 5=rational */
private void addTag(int tag,long value)
{
// Adds a tag of type 4 (ulong)
int count = ++tiffheader[8];
int offset = (count-1)*12 + 10;
tiffheader[offset]=(byte)(tag & 0xff);
tiffheader[offset+1]=(byte)((tag>>8) & 0xff);
tiffheader[offset+2]=4; // Type Long
tiffheader[offset+4]=1; // One Value
tiffheader[offset+8]=(byte)(value & 0xff);
tiffheader[offset+9]=(byte)((value>>8) & 0xff);
tiffheader[offset+10]=(byte)((value>>16) & 0xff);
tiffheader[offset+11]=(byte)((value>>24) & 0xff);
}
private void addTag(int tag, short value)
{
// Adds a tag of type 3 (short)
int count = ++tiffheader[8];
int offset = (count-1)*12 + 10;
tiffheader[offset]=(byte)(tag & 0xff);
tiffheader[offset+1]=(byte)((tag>>8) & 0xff);
tiffheader[offset+2]=3; // Type Short
tiffheader[offset+4]=1; // One Value
tiffheader[offset+8]=(byte)(value & 0xff);
tiffheader[offset+9]=(byte)((value>>8) & 0xff);
}
private void addTag(int tag, String value)
{
// Adds a tag of type 2 (ascii)
int count = ++tiffheader[8];
int offset = (count-1)*12 + 10;
tiffheader[offset]=(byte)(tag & 0xff);
tiffheader[offset+1]=(byte)((tag>>8) & 0xff);
tiffheader[offset+2]=2; // Type Ascii
tiffheader[offset+4]=1; // One Value
tiffheader[offset+8]=(byte)(additionalOffset & 0xff);
tiffheader[offset+9]=(byte)((additionalOffset>>8) & 0xff);
tiffheader[offset+10]=(byte)((additionalOffset>>16) & 0xff);
tiffheader[offset+11]=(byte)((additionalOffset>>24) & 0xff);
System.arraycopy(value.getBytes(), 0, tiffheader, additionalOffset, value.length());
additionalOffset += value.length() + 1;
}
private void addTag(int tag, long numerator, long denominator)
{
// Adds a tag of type 5 (rational)
int count = ++tiffheader[8];
int offset = (count-1)*12 + 10;
tiffheader[offset]=(byte)(tag & 0xff);
tiffheader[offset+1]=(byte)((tag>>8) & 0xff);
tiffheader[offset+2]=5; // Type Rational
tiffheader[offset+4]=1; // One Value
tiffheader[offset+8]=(byte)(additionalOffset & 0xff);
tiffheader[offset+9]=(byte)((additionalOffset>>8) & 0xff);
tiffheader[offset+10]=(byte)((additionalOffset>>16) & 0xff);
tiffheader[offset+11]=(byte)((additionalOffset>>24) & 0xff);
tiffheader[additionalOffset++]=(byte) ((numerator) & 0xFF);
tiffheader[additionalOffset++]=(byte) ((numerator>>8) & 0xFF);
tiffheader[additionalOffset++]=(byte) ((numerator>>16) & 0xFF);
tiffheader[additionalOffset++]=(byte) ((numerator>>24) & 0xFF);
tiffheader[additionalOffset++]=(byte) ((denominator) & 0xFF);
tiffheader[additionalOffset++]=(byte) ((denominator>>8) & 0xFF);
tiffheader[additionalOffset++]=(byte) ((denominator>>16) & 0xFF);
tiffheader[additionalOffset++]=(byte) ((denominator>>24) & 0xFF);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -