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

📄 pdccitt.java

📁 非常有用的操作pdf文件的java源码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/**
 * Copyright (c) 2005-2006, 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.pdmodel.graphics.xobject;

import java.awt.image.BufferedImage;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;

import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;

import org.pdfbox.cos.COSDictionary;
import org.pdfbox.cos.COSName;
import org.pdfbox.io.RandomAccess;

import org.pdfbox.pdmodel.PDDocument;
import org.pdfbox.pdmodel.common.PDStream;
import org.pdfbox.pdmodel.graphics.color.PDDeviceGray;

/**
 * An image class for CCITT Fax. 
 * 
 * @author <a href="ben@benlitchfield.com">Ben Litchfield</a>
 * @author paul king
 * @version $Revision: 1.4 $
 */
public class PDCcitt extends PDXObjectImage 
{
    private static final List FAX_FILTERS = new ArrayList();
    
    static
    {
        FAX_FILTERS.add( COSName.CCITTFAX_DECODE.getName() );
        FAX_FILTERS.add( COSName.CCITTFAX_DECODE_ABBREVIATION.getName() );
    }
    
    /**
     * Standard constructor.
     * 
     * @param ccitt The PDStream that already contains all ccitt information.
     */
    public PDCcitt(PDStream ccitt) 
    {
        super(ccitt, "tiff");
        
    }
    
    /**
     * Construct from a tiff file.
     * 
     * @param doc The document to create the image as part of.
     * @param raf The random access TIFF file which contains a suitable CCITT compressed image
     * @throws IOException If there is an error reading the tiff data.
     */
    
    public PDCcitt( PDDocument doc, RandomAccess raf ) throws IOException
    {
        super( new PDStream(doc),"tiff");
        // super( new PDStream( doc, null, true ), "tiff" );
        
        COSDictionary decodeParms = new COSDictionary(); 
        
        COSDictionary dic = getCOSStream();
      
        extractFromTiff(raf, getCOSStream().createFilteredStream(),decodeParms);
        
        dic.setItem( COSName.FILTER, COSName.CCITTFAX_DECODE);
        dic.setItem( COSName.SUBTYPE, COSName.IMAGE);
        dic.setItem( COSName.TYPE, COSName.getPDFName( "XObject" ) );
        dic.setItem( "DecodeParms", decodeParms);
        
        setBitsPerComponent( 1 );
        setColorSpace( new PDDeviceGray() );
        setWidth( decodeParms.getInt("Columns") );
        setHeight( decodeParms.getInt("Rows") );
        
    }
    
    /**
     * Returns an image of the CCITT Fax, or null if TIFFs are not supported. (Requires additional JAI Image filters )
     * 
     * {@inheritDoc}
     */
    public BufferedImage getRGBImage() throws IOException
    {
        // ImageIO.scanForPlugins();
        return ImageIO.read(new TiffWrapper(getPDStream().getPartiallyFilteredStream( FAX_FILTERS ),getCOSStream()));
    }
    
    /**
     * This writes a tiff to out. 
     * 
     * {@inheritDoc}
     */
    public void write2OutputStream(OutputStream out) throws IOException
    {
        InputStream data = new TiffWrapper(getPDStream().getPartiallyFilteredStream( FAX_FILTERS ),getCOSStream());
        byte[] buf = new byte[1024];
        int amountRead = -1;
        while( (amountRead = data.read( buf )) != -1 )
        {
            out.write( buf, 0, amountRead );
        }
    }
    
    /**
     * Extract the ccitt stream from the tiff file.
     * 
     * @param raf  - TIFF File
     * @param os   - Stream to write raw ccitt data two
     * @param parms - COSDictionary which the encoding parameters are added to
     * @throws IOException If there is an error reading/writing to/from the stream
     */
    private void extractFromTiff(RandomAccess raf, OutputStream os, COSDictionary parms) throws IOException 
    {
        try 
        {
            
            // First check the basic tiff header
            raf.seek(0);  
            char endianess = (char) raf.read();
            if ((char) raf.read() != endianess) 
            {
                throw new IOException("Not a valid tiff file");
            }
            //ensure that endianess is either M or I
            if (endianess != 'M' && endianess != 'I')
            {
                throw new IOException("Not a valid tiff file");
            }
            int magicNumber = readshort(endianess, raf); 
            if( magicNumber != 42)
            {
                throw new  IOException("Not a valid tiff file");
            }
            
            // Relocate to the first set of tags
            raf.seek(readlong(endianess, raf));
            
            int numtags = readshort(endianess, raf);
            
            //    The number 50 is somewhat arbitary, it just stops us load up junk from somewhere and tramping on
            if (numtags > 50)
            {
                throw new IOException("Not a valid tiff file"); 
            }
            
            // Loop through the tags, some will convert to items in the parms dictionary
            // Other point us to where to find the data stream
            // The only parm which might change as a result of other options is K, so
            // We'll deal with that as a special;
            
            int k=-1000; // Default Non CCITT compression
            int dataoffset=0;
            int datalength=0;
            
            for (int i=0; i < numtags; i++) 
            {
                int tag = readshort(endianess, raf);
                int type = readshort(endianess, raf);
                int count = readlong(endianess, raf);
                int val = readlong(endianess, raf); // See note
                
                // Note, we treated that value as a long. The value always occupies 4 bytes
                // But it might only use the first byte or two. Depending on endianess we might need to correct
                // Note we ignore all other types, they are of little interest for PDFs/CCITT Fax
                if (endianess == 'M') 
                {
                    switch (type) 
                    {
                        case 1: 
                        {
                            val = val >> 24; 
                            break; // byte value
                        }
                        case 3: 
                        {
                            val = val >> 16; 
                            break; // short value
                        }
                        case 4:
                        {
                            break; // long value
                        }
                        default:
                        {
                            //do nothing
                        }
                    }
                }
                switch (tag) 
                {
                    case 256:
                    {
                        parms.setInt("Columns",val); 
                        break;
                    }
                    case 257:
                    {
                        parms.setInt("Rows",val);
                        break;
                    }
                    case 259: 
                    {
                        if (val == 4)
                        {
                            k=-1; 
                        }
                        if (val == 3)
                        {
                            k=0;
                        }
                        break;  // T6/T4 Compression
                    }
                    case 262:
                    {
                        if (val == 1)
                        {
                            parms.setBoolean("BlackIs1", true); 
                        }
                        break;
                    }
                    case 273:
                    {
                        if (count == 1)
                        {
                            dataoffset=val; 
                        }
                        break;
                    }
                    case 279:
                    {
                        if (count == 1)
                        {
                            datalength=val; 
                        }
                        break;
                    }
                    case 292: 
                    {
                        if (val == 1)
                        {
                            k=50;  // T4 2D - arbitary K value
                        }
                        break;
                    }
                    case 324:
                    {
                        if (count == 1)
                        {
                            dataoffset=val;
                        }
                        break;
                    }
                    case 325:
                    {
                        if (count == 1)
                        {
                            datalength=val; 
                        }
                        break;
                    }
                    default:
                    {
                        //do nothing
                    }
                }
            }
            
            if (k == -1000)
            {
                throw new IOException("First image in tiff is not CCITT T4 or T6 compressed");
            }
            if (dataoffset == 0)
            {
                throw new IOException("First image in tiff is not a single tile/strip");
            }
            
            parms.setInt("K",k);
            

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -