PdfFlateFilter.java :  » PDF » pjx » com » etymon » pjx » stream » Java Open Source

Java Open Source » PDF » pjx 
pjx » com » etymon » pjx » stream » PdfFlateFilter.java
/*
  Copyright (C) Etymon Systems, Inc. <http://www.etymon.com/>
*/

package com.etymon.pjx.stream;

import java.io.*;
import java.nio.*;
import java.util.*;
import java.util.zip.*;
import com.etymon.pjx.*;

/**
   Implements a stream filter for Flate compression (based on
   zlib/deflate).  This class is synchronized.
   @author Nassib Nassar
*/
public class PdfFlateFilter
  implements PdfStreamFilter {

        protected static final PdfName PDFNAME_FILTER = new PdfName("Filter");
        protected static final PdfName PDFNAME_FLATEDECODE = new PdfName("FlateDecode");

  /**
     The manager associated with the PDF document.
  */
  protected PdfManager _m;

  /**
     A byte array used for buffering.
  */
  protected byte[] _ba = new byte[16384];

  /**
     Instance used for deflating.
   */
  Deflater _deflater = new Deflater(9);
  
  /**
     Instance used for inflating.
   */
  Inflater _inflater = new Inflater();
  
  /**
     Constructs an instance of this class with a specified
     manager instance.
     @param manager the manager instance.
   */
  public PdfFlateFilter(PdfManager manager) {
    _m = manager;
  }

  public PdfName getName() {
    return PDFNAME_FLATEDECODE;
  }

  public PdfStream encode(PdfStream stream) throws IOException, PdfFormatException {
    synchronized (this) {
      synchronized (_m) {
    
        PdfManager m = _m;
        
        // add /FlateDecode to the pipeline
        Map dict = new HashMap( stream.getDictionary().getMap() );
        List filters = PdfDecodeStream.getFilterList(m, dict);
        if (filters == null) {
          dict.put(PDFNAME_FILTER, PDFNAME_FLATEDECODE);
        } else {
          List newFilters = new ArrayList(filters.size() + 1);
          newFilters.add(PDFNAME_FLATEDECODE);
          newFilters.addAll(filters);
          dict.put(PDFNAME_FILTER, new PdfArray(newFilters));
        }
        
        // encode the stream
        Deflater deflater = _deflater;
        ByteBuffer bb = stream.getBuffer();
        byte[] bba = new byte[bb.capacity()];
        bb.get(bba);
        deflater.setInput(bba);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int len;
        byte[] ba = _ba;
        do {
          do {
            while ( (len = deflater.deflate(ba)) != 0) {
              baos.write(ba, 0, len);
            }
          } while (deflater.needsInput() == false);
          deflater.finish();
        } while (deflater.finished() == false);
        deflater.reset();
        baos.close();
        
        byte[] nbba = baos.toByteArray();
        ByteBuffer nbb = ByteBuffer.wrap(nbba);

        return new PdfStream( new PdfDictionary(dict),
                  nbb );
        
      }
    }
  }
  
  public PdfStream decode(PdfStream stream) throws IOException, PdfFormatException, PdfDecoderFormatException {
    synchronized (this) {
      synchronized (_m) {
    
        PdfManager m = _m;
        
        // check that /FlateDecode is first in the pipeline
        Map dict = new HashMap( stream.getDictionary().getMap() );
        List filters = PdfDecodeStream.getFilterList(m, dict);
        if ( (filters == null) ||
             ( ((PdfName)filters.get(0)).equals(PDFNAME_FLATEDECODE) == false) ) {
          throw new PdfDecoderFormatException("Incorrect decoding method for this stream.");
        }
        // now we have confirmed that /FlateDecode is first
        
        // remove /FlateDecode
        PdfDecodeStream.modifyFilterList(filters, dict);
        
        // decode the stream
        Inflater inflater = _inflater;
        ByteBuffer bb = stream.getBuffer();
        byte[] bba = new byte[bb.capacity()];
        bb.get(bba);
        inflater.setInput(bba);
        if (inflater.needsDictionary()) {
          throw new PdfDecoderFormatException("Flate compression needs dictionary.");
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream(bba.length);
        int len;
        byte[] ba = _ba;
        try {
          while ( (len = inflater.inflate(ba)) != 0) {
            baos.write(ba, 0, len);
          }
        } catch (DataFormatException e) {
          throw new PdfDecoderFormatException( e.getMessage() );
        }
        if (inflater.finished() == false) {
          throw new PdfDecoderFormatException("Flate decoder: unexpected end of stream.");
        }
        inflater.reset();
        baos.close();
        
        byte[] nbba = baos.toByteArray();
        ByteBuffer nbb = ByteBuffer.wrap(nbba);

        return new PdfStream( new PdfDictionary(dict),
                  nbb );
        
      }
    }
  }
  
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.