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

📄 ccittg4encoder.java

📁 iText是一个能够快速产生PDF文件的java类库。iText的java类对于那些要产生包含文本
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * Copyright 2005 by Paulo Soares.
 *
 * The contents of this file are subject to the Mozilla Public License Version 1.1
 * (the "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the License.
 *
 * The Original Code is 'iText, a free JAVA-PDF library'.
 *
 * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
 * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
 * All Rights Reserved.
 * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
 * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
 *
 * Contributor(s): all the names of the contributors are added in the source code
 * where applicable.
 *
 * Alternatively, the contents of this file may be used under the terms of the
 * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
 * provisions of LGPL are applicable instead of those above.  If you wish to
 * allow use of your version of this file only under the terms of the LGPL
 * License and not to allow others to use your version of this file under
 * the MPL, indicate your decision by deleting the provisions above and
 * replace them with the notice and other provisions required by the LGPL.
 * If you do not delete the provisions above, a recipient may use your version
 * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the MPL as stated above or under the terms of the GNU
 * Library General Public License as published by the Free Software Foundation;
 * either version 2 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
 * details.
 *
 * If you didn't download this code from the following link, you should check if
 * you aren't using an obsolete version:
 * http://www.lowagie.com/iText/
 *
 * This code is base in the libtiff encoder
 */
package com.lowagie.text.pdf.codec;

import com.lowagie.text.pdf.ByteBuffer;

/**
 * Encodes data in the CCITT G4 FAX format.
 */
public class CCITTG4Encoder {
    private int rowbytes;
    private int rowpixels;
    private int bit = 8;
    private int data;
    private byte[] refline;
    private ByteBuffer outBuf = new ByteBuffer(1024);
    private byte[] dataBp;
    private int offsetData;
    private int sizeData;
    
    /**
     * Creates a new encoder.
     * @param width the line width
     */    
    public CCITTG4Encoder(int width) {
        rowpixels = width;
        rowbytes = (rowpixels + 7) / 8;
        refline = new byte[rowbytes];
    }
    
    /**
     * Encodes a number of lines.
     * @param data the data to be encoded
     * @param offset the offset into the data
     * @param size the size of the data to be encoded
     */    
    public void fax4Encode(byte[] data, int offset, int size) {
        dataBp = data;
        offsetData = offset;
        sizeData = size;
        while (sizeData > 0) {
            Fax3Encode2DRow();
            System.arraycopy(dataBp, offsetData, refline, 0, rowbytes);
            offsetData += rowbytes;
            sizeData -= rowbytes;
        }
    }
    

    /**
     * Encodes a full image.
     * @param data the data to encode
     * @param width the image width
     * @param height the image height
     * @return the encoded image
     */    
    public static byte[] compress(byte[] data, int width, int height) {
        CCITTG4Encoder g4 = new CCITTG4Encoder(width);
        g4.fax4Encode(data, 0, g4.rowbytes * height);
        return g4.close();
    }
    
    /**
     * Encodes a number of lines.
     * @param data the data to be encoded
     * @param height the number of lines to encode
     */    
    public void fax4Encode(byte[] data, int height) {
        fax4Encode(data, 0, rowbytes * height);
    }

    private void putcode(int[] table) {
        putBits(table[CODE], table[LENGTH]);
    }
    
    private void putspan(int span, int[][] tab) {
        int code, length;
        
        while (span >= 2624) {
            int[] te = tab[63 + (2560>>6)];
            code = te[CODE];
            length = te[LENGTH];
            putBits(code, length);
            span -= te[RUNLEN];
        }
        if (span >= 64) {
            int[] te = tab[63 + (span>>6)];
            code = te[CODE];
            length = te[LENGTH];
            putBits(code, length);
            span -= te[RUNLEN];
        }
        code = tab[span][CODE];
        length = tab[span][LENGTH];
        putBits(code, length);
    }
    
    private void putBits(int bits, int length) {
        while (length > bit) {
            data |= bits >> (length - bit);
            length -= bit;
            outBuf.append((byte)data);
            data = 0;
            bit = 8;
        }
        data |= (bits & msbmask[length]) << (bit - length);
        bit -= length;
        if (bit == 0) {
            outBuf.append((byte)data);
            data = 0;
            bit = 8;
        }
    }
    
    private void Fax3Encode2DRow() {
        int a0 = 0;
        int a1 = (pixel(dataBp, offsetData, 0) != 0 ? 0 : finddiff(dataBp, offsetData, 0, rowpixels, 0));
        int b1 = (pixel(refline, 0, 0) != 0 ? 0 : finddiff(refline, 0, 0, rowpixels, 0));
        int a2, b2;
        
        for (;;) {
            b2 = finddiff2(refline, 0, b1, rowpixels, pixel(refline, 0,b1));
            if (b2 >= a1) {
                int d = b1 - a1;
                if (!(-3 <= d && d <= 3)) {	/* horizontal mode */
                    a2 = finddiff2(dataBp, offsetData, a1, rowpixels, pixel(dataBp, offsetData,a1));
                    putcode(horizcode);
                    if (a0+a1 == 0 || pixel(dataBp, offsetData, a0) == 0) {
                        putspan(a1-a0, TIFFFaxWhiteCodes);
                        putspan(a2-a1, TIFFFaxBlackCodes);
                    } else {
                        putspan(a1-a0, TIFFFaxBlackCodes);
                        putspan(a2-a1, TIFFFaxWhiteCodes);
                    }
                    a0 = a2;
                } else {			/* vertical mode */
                    putcode(vcodes[d+3]);
                    a0 = a1;
                }
            } else {				/* pass mode */
                putcode(passcode);
                a0 = b2;
            }
            if (a0 >= rowpixels)
                break;
            a1 = finddiff(dataBp, offsetData, a0, rowpixels, pixel(dataBp, offsetData,a0));
            b1 = finddiff(refline, 0, a0, rowpixels, pixel(dataBp, offsetData,a0) ^ 1);
            b1 = finddiff(refline, 0, b1, rowpixels, pixel(dataBp, offsetData,a0));
        }
    }
    
    private void Fax4PostEncode() {
        putBits(EOL, 12);
        putBits(EOL, 12);
        if (bit != 8) {
            outBuf.append((byte)data);
            data = 0;
            bit = 8;
        }
    }
    
    /**
     * Closes the encoder and returns the encoded data.
     * @return the encoded data
     */    
    public byte[] close() {
        Fax4PostEncode();
        return outBuf.toByteArray();
    }
    
    private int pixel(byte[] data, int offset, int bit) {
        if (bit >= rowpixels)
            return 0;
        return ((data[offset + (bit >> 3)] & 0xff) >> (7-((bit)&7))) & 1;
    }
    
    private static int find1span(byte[] bp, int offset, int bs, int be) {
        int bits = be - bs;
        int n, span;
        
        int pos = offset + (bs >> 3);
        /*
         * Check partial byte on lhs.
         */
        if (bits > 0 && (n = (bs & 7)) != 0) {
            span = oneruns[((int)bp[pos] << n) & 0xff];
            if (span > 8-n)		/* table value too generous */
                span = 8-n;
            if (span > bits)	/* constrain span to bit range */
                span = bits;
            if (n+span < 8)		/* doesn't extend to edge of byte */
                return span;
            bits -= span;
            pos++;
        } else
            span = 0;
        /*
         * Scan full bytes for all 1's.
         */
        while (bits >= 8) {
            if (bp[pos] != -1)	/* end of run */
                return (span + oneruns[bp[pos] & 0xff]);
            span += 8;
            bits -= 8;
            pos++;
        }
        /*
         * Check partial byte on rhs.
         */
        if (bits > 0) {
            n = oneruns[bp[pos] & 0xff];
            span += (n > bits ? bits : n);
        }
        return span;
    }
    
    private static int find0span(byte[] bp, int offset, int bs, int be) {
        int bits = be - bs;
        int n, span;
        
        int pos = offset + (bs >> 3);
        /*
         * Check partial byte on lhs.
         */
        if (bits > 0 && (n = (bs & 7)) != 0) {
            span = zeroruns[((int)bp[pos] << n) & 0xff];
            if (span > 8-n)		/* table value too generous */
                span = 8-n;
            if (span > bits)	/* constrain span to bit range */
                span = bits;
            if (n+span < 8)		/* doesn't extend to edge of byte */
                return span;
            bits -= span;
            pos++;
        } else
            span = 0;
        /*
         * Scan full bytes for all 1's.
         */
        while (bits >= 8) {
            if (bp[pos] != 0)	/* end of run */
                return (span + zeroruns[bp[pos] & 0xff]);
            span += 8;
            bits -= 8;
            pos++;
        }
        /*
         * Check partial byte on rhs.
         */
        if (bits > 0) {
            n = zeroruns[bp[pos] & 0xff];
            span += (n > bits ? bits : n);
        }
        return span;
    }

⌨️ 快捷键说明

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