📄 ccittfaxdecodefilter.java
字号:
/**
* Copyright (c) 2003-2005, www.pdfbox.org
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of pdfbox; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://www.pdfbox.org
*
*/
package org.pdfbox.filter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.pdfbox.cos.COSDictionary;
import org.pdfbox.cos.COSName;
/**
* This is a filter for the CCITTFax Decoder.
*
* @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
* @author Marcel Kammer
* @author Paul King
* @version $Revision: 1.12 $
*/
public class CCITTFaxDecodeFilter implements Filter
{
// Filter will write 15 TAG's
// If you add or remove TAG's you will have to modify this value
private static final int TAG_COUNT = 15;
// HEADERLENGTH(fix 8 Bytes) plus ImageLength(variable)
private int offset = 8;
// Bytecounter for Bytes that will be written after the TAG-DICTIONARY
private int tailingBytesCount = 0;
// Bytes to write after TAG-DICTIONARY
private final ByteArrayOutputStream tailer = new ByteArrayOutputStream();
/**
* Constructor.
*/
public CCITTFaxDecodeFilter()
{
}
/**
* This will decode some compressed data.
*
* @param compressedData
* The compressed byte stream.
* @param result
* The place to write the uncompressed byte stream.
* @param options
* The options to use to encode the data.
*
* @throws IOException
* If there is an error decompressing the stream.
*/
public void decode(InputStream compressedData, OutputStream result, COSDictionary options) throws IOException
{
// log.warn( "Warning: CCITTFaxDecode.decode is not implemented yet,
// skipping this stream." );
// Get ImageParams from PDF
COSDictionary dict = (COSDictionary) options.getDictionaryObject("DecodeParms");
int width = options.getInt("Width");
int height = options.getInt("Height");
int length = options.getInt(COSName.LENGTH);
int compressionType = dict.getInt("K");
boolean blackIs1 = dict.getBoolean("BlackIs1", false);
// HEADER-INFO and starting point of TAG-DICTIONARY
writeTagHeader(result, length);
// IMAGE-DATA
int i = 0;
//int sum = 0;
byte[] buffer = new byte[32768];
int lentoread = length;
while ((lentoread > 0) && ((i = compressedData.read(buffer, 0, Math.min(lentoread, 32768))) != -1))
{
//sum += i;
result.write(buffer, 0, i);
lentoread = lentoread - i;
}
// If lentoread is > 0 then we need to write out some padding to equal the header
// We'll use what we have in the buffer it's just padding after all
while (lentoread > 0)
{
result.write(buffer, 0, Math.min(lentoread, 32768));
lentoread = lentoread - Math.min(lentoread, 32738);
}
//System.out.println("Gelesen: " + sum);
// TAG-COUNT
writeTagCount(result);
// WIDTH 0x0100
writeTagWidth(result, width);
// HEIGHT 0x0101
writeTagHeight(result, height);
// BITSPERSAMPLE 0x0102
// Always 1 for CCITTFax
writeTagBitsPerSample(result, 1);
// COMPRESSION 0x0103
writeTagCompression(result, compressionType);
// PHOTOMETRIC 0x0106
writeTagPhotometric(result, blackIs1);
// STRIPOFFSET 0x0111
// HERE ALWAYS 8, because ImageData comes before TAG-DICTIONARY
writeTagStripOffset(result, 8);
// ORIENTATION 0x0112
writeTagOrientation(result, 1);
// SamplesPerPixel 0x0115
writeTagSamplesPerPixel(result, 1);
// RowsPerStrip 0x0116
writeTagRowsPerStrip(result, height);
// Stripcount 0x0117
writeTagStripByteCount(result, length);
// XRESOLUTION 0x011A
// HERE: 200 DPI
writeTagXRes(result, 200, 1);
// YRESOLITION 0x011B
// HERE: 200 DPI
writeTagYRes(result, 200, 1);
// ResolutionUnit 0x0128
// HERE: DPI
writeTagResolutionUnit(result, 2);
// SOFTWARE 0x0131
// minimum 4 chars
writeTagSoftware(result, "pdfbox".getBytes());
// DATE AND TIME 0x0132
writeTagDateTime(result, new Date());
// END OF TAG-DICT
writeTagTailer(result);
}
private void writeTagHeader(OutputStream result, int length) throws IOException
{
byte[] header = { 'M', 'M', 0, '*' };// Big-endian
result.write(header);
// Add imagelength to offset
offset += length;
// OFFSET TAG-DICTIONARY
int i1 = offset/16777216;//=value/(256*256*256)
int i2 = (offset-i1*16777216)/65536;
int i3 = (offset-i1*16777216-i2*65536)/256;
int i4 = offset % 256;
result.write(i1);
result.write(i2);
result.write(i3);
result.write(i4);
}
private void writeTagCount(OutputStream result) throws IOException
{
result.write(TAG_COUNT / 256);
result.write(TAG_COUNT % 256);// tagCount
}
private void writeTagWidth(OutputStream result, int width) throws IOException
{
// @todo width berechnen
// TAG-ID 100
result.write(1);
result.write(0);
// TAG-TYPE SHORT=3
result.write(0);
result.write(3);
// TAG-LENGTH = 1
result.write(0);
result.write(0);
result.write(0);
result.write(1);
// TAG-VALUE = width
result.write(width/256);
result.write(width%256);
result.write(0);// SHORT=0
result.write(0);// SHORT=0
}
private void writeTagHeight(OutputStream result, int height) throws IOException
{
//@todo height berechnen
// TAG-ID 101
result.write(1);
result.write(1);
// TAG-TYPE SHORT=3
result.write(0);
result.write(3);
// TAG-LENGTH = 1
result.write(0);
result.write(0);
result.write(0);
result.write(1);
// TAG-VALUE
result.write(height/256);
result.write(height%256);
result.write(0);// SHORT=0
result.write(0);// SHORT=0
}
private void writeTagBitsPerSample(OutputStream result, int value) throws IOException
{
// TAG-ID 102
result.write(1);
result.write(2);
// TAG-TYPE SHORT=3
result.write(0);
result.write(3);
// TAG-LENGTH = 1
result.write(0);
result.write(0);
result.write(0);
result.write(1);
// TAG-VALUE
result.write(value/256);
result.write(value%256);
result.write(0);//SHORT=0
result.write(0);//SHORT=0
}
/**
* Write the tag compression.
*
* @param result The stream to write to.
* @param type The type to write.
* @throws IOException If there is an error writing to the stream.
*/
public void writeTagCompression(OutputStream result, int type) throws IOException
{
// TAG-ID 103
result.write(1);
result.write(3);
// TAG-TYPE SHORT=3
result.write(0);
result.write(3);
// TAG-LEGNTH = 1
result.write(0);
result.write(0);
result.write(0);
result.write(1);
// TAG-VALUE
//@todo typ eintragen; hier immer 4
result.write(0);
if (type < 0)
{
result.write(4);// G4
}
else if (type == 0)
{
result.write(3);// G3-1D
}
else
{
result.write(2);// G3-2D
}
result.write(0);
result.write(0);
}
private void writeTagPhotometric(OutputStream result, boolean blackIs1) throws IOException
{
// TAG-ID 106
result.write(1);
result.write(6);
// TAG-TYPE SHORT
result.write(0);
result.write(3);
// TAG-LENGTH = 1
result.write(0);
result.write(0);
result.write(0);
result.write(1);
// TAG-VALUE
result.write(0);
if (blackIs1)
{
result.write(1);
}
else
{
result.write(0);
}
result.write(0);// SHORT=0
result.write(0);// SHORT=0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -