All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.pdfview.decode.DCTDecode Maven / Gradle / Ivy

/*
 * $Id: DCTDecode.java,v 1.2 2007/12/20 18:33:33 rbair Exp $
 *
 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
 * Santa Clara, California 95054, U.S.A. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) 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
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

package com.sun.pdfview.decode;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.DataBufferInt;
import java.awt.image.ImageObserver;
import java.io.IOException;
import java.nio.ByteBuffer;

import com.sun.pdfview.PDFObject;
import com.sun.pdfview.PDFParseException;
import com.sun.pdfview.colorspace.PDFColorSpace;

/**
 * decode a DCT encoded array into a byte array.  This class uses Java's
 * built-in JPEG image class to do the decoding.
 *
 * @author Mike Wessler
 */
public class DCTDecode {

    /**
     * decode an array of bytes in DCT format.
     * 

* DCT is the format used by JPEG images, so this class simply * loads the DCT-format bytes as an image, then reads the bytes out * of the image to create the array. Unfortunately, their most * likely use is to get turned BACK into an image, so this isn't * terribly efficient... but is is general... don't hit, please. *

* The DCT-encoded stream may have 1, 3 or 4 samples per pixel, depending * on the colorspace of the image. In decoding, we look for the colorspace * in the stream object's dictionary to decide how to decode this image. * If no colorspace is present, we guess 3 samples per pixel. * * @param dict the stream dictionary * @param buf the DCT-encoded buffer * @param params the parameters to the decoder (ignored) * @return the decoded buffer */ protected static ByteBuffer decode(PDFObject dict, ByteBuffer buf, PDFObject params) throws PDFParseException { // System.out.println("DCTDecode image info: "+params); buf.rewind(); // copy the data into a byte array required by createimage byte[] ary = new byte[buf.remaining()]; buf.get(ary); // wait for the image to get drawn Image img= Toolkit.getDefaultToolkit().createImage(ary); MyTracker mt= new MyTracker(img); mt.waitForAll(); // the default components per pixel is 3 int numComponents = 3; // see if we have a colorspace try { PDFObject csObj = dict.getDictRef("ColorSpace"); if (csObj != null) { // we do, so get the number of components PDFColorSpace cs = PDFColorSpace.getColorSpace(csObj, null); numComponents = cs.getNumComponents(); } } catch (IOException ioe) { // oh well } // figure out the type int type = BufferedImage.TYPE_INT_RGB; if (numComponents == 1) { type = BufferedImage.TYPE_BYTE_GRAY; } else if (numComponents == 4) { type = BufferedImage.TYPE_INT_ARGB; } // create a buffered image BufferedImage bimg = new BufferedImage(img.getWidth(null), img.getHeight(null), type); Graphics bg= bimg.getGraphics(); // draw the image onto it bg.drawImage(img, 0, 0, null); byte[] output = null; if (type == BufferedImage.TYPE_INT_RGB) { // read back the data DataBufferInt db = (DataBufferInt) bimg.getData().getDataBuffer(); int[] data = db.getData(); output = new byte[data.length*3]; for (int i=0; i>16); output[i*3+1]= (byte)(data[i]>>8); output[i*3+2]= (byte)(data[i]); } } else if (type == BufferedImage.TYPE_BYTE_GRAY) { DataBufferByte db = (DataBufferByte) bimg.getData().getDataBuffer(); output = db.getData(); } else if (type == BufferedImage.TYPE_INT_ARGB) { // read back the data DataBufferInt db = (DataBufferInt) bimg.getData().getDataBuffer(); int[] data = db.getData(); output = new byte[data.length*4]; for (int i=0; i>24); output[i*4+1]= (byte)(data[i]>>16); output[i*4+2]= (byte)(data[i]>>8); output[i*4+3]= (byte)(data[i]); } } // System.out.println("Translated data"); return ByteBuffer.wrap(output); } } /** * Image tracker. I'm not sure why I'm not using the default Java * image tracker for this one. */ class MyTracker implements ImageObserver { boolean done= false; /** * create a new MyTracker that watches this image. The image * will start loading immediately. */ public MyTracker(Image img) { img.getWidth(this); } /** * More information has come in about the image. */ public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) { if ((infoflags & (ALLBITS | ERROR | ABORT))!=0) { synchronized(this) { done= true; notifyAll(); } return false; } return true; } /** * Wait until the image is done, then return. */ public synchronized void waitForAll() { if (!done) { try { wait(); } catch (InterruptedException ie) {} } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy