⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ccittfaxdecodefilter.java

📁 非常有用的操作pdf文件的java源码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/**
 * 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 + -