Tuesday, January 10, 2012

Compress Files

package com.nmmc.dms.utils.compression;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.HashMap;

import multivalent.std.adaptor.pdf.Dict;
import multivalent.std.adaptor.pdf.PDFReader;
import multivalent.std.adaptor.pdf.PDFWriter;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.math.RandomUtils;

public class CompressFiles {

    public final static int BUFFER = 1024;

    public static InputStream compressAsStream(String strFilePath, boolean isPDF) throws IOException {
        System.out.println("Compression Started" + new Date());
        CompressFiles compressFiles = new CompressFiles();
        InputStream inputStream = null;
        if (isPDF) {
            File tempfile = File.createTempFile("CC" + RandomStringUtils.randomAlphanumeric(6).toString() + "" + RandomUtils.nextInt(), ".pdf");
            compressFiles.compressPDFFiles(strFilePath, tempfile.getPath());
            // TODO Compress Only the PDF Files
            // ByteArrayOutputStream arrayOutputStream =
            // compressFiles.compressData(new FileInputStream(tempfile));
            // inputStream = new
            // ByteArrayInputStream(arrayOutputStream.toByteArray());
            // arrayOutputStream.close();
            inputStream = new FileInputStream(tempfile);
            System.out.println(tempfile.getPath());
            tempfile.delete();
        }
        System.out.println("Compression Completed" + new Date());
        return inputStream;
    }

    public static InputStream compressAsStream(InputStream inputStream, boolean isPDF) throws IOException {
        CompressFiles compressFiles = new CompressFiles();
        System.out.println("Compression Started" + new Date());
        InputStream inputStreamData = null;
        if (isPDF) {
            // Create Temporary Main File
            File fileMainFile = File.createTempFile(RandomStringUtils.randomAlphanumeric(6).toString() + "" + RandomUtils.nextInt(), ".pdf");
            FileOutputStream fileOutputStream = new FileOutputStream(fileMainFile);
            IOUtils.write(IOUtils.toByteArray(inputStream), fileOutputStream);
            fileOutputStream.close();

            // Create Temporary compressedFile
            File tempFile = File.createTempFile(RandomStringUtils.randomAlphanumeric(6).toString() + "" + RandomUtils.nextInt(), ".pdf");
            compressFiles.compressPDFFiles(fileMainFile.getPath(), tempFile.getPath());
            inputStreamData = new FileInputStream(tempFile);
           
            //TODO only if the we require gZip Compression
            // ByteArrayOutputStream arrayOutputStream =
            // compressFiles.compressData(new FileInputStream(tempfile));
            // inputStreamData = new
            // ByteArrayInputStream(arrayOutputStream.toByteArray());
            // arrayOutputStream.close();

            fileMainFile.delete();
            tempFile.delete();
        }
        System.out.println("Compression Completed" + new Date());
        return inputStreamData;
    }

    public static InputStream uncompressAsStream(InputStream inputStreamData) throws IOException {
        System.out.println("UnCompression Started" + new Date());
        CompressFiles compressFiles = new CompressFiles();
        InputStream inputStream = null;
        inputStream = compressFiles.uncompressData(inputStreamData);
        inputStreamData.close();
        System.out.println("UnCompression Completed" + new Date());
        return inputStream;
    }

    public static File uncompressAsFile(InputStream inputStream, String strPath) throws IOException {
        System.out.println("UnCompression Started" + new Date());
        CompressFiles compressFiles = new CompressFiles();
        InputStream inputStreamUnCompressed = compressFiles.uncompressData(inputStream);
        File file = new File(strPath);
        FileOutputStream fos2 = new FileOutputStream(file);
        compressFiles.doCopy(inputStreamUnCompressed, fos2);
        inputStreamUnCompressed.close();
        fos2.close();
        inputStream.close();
        System.out.println("UnCompression Completed" + new Date());
        return file;
    }

    public static void main(String[] args) throws Exception {
        // for (int i = 0; i < 25; i++)
        {
            InputStream inputStream = compressAsStream("C:/Documents and Settings/Balaji/Desktop/Fedora/scan0009.pdf", true);
            uncompressAsFile(inputStream, "C:/Documents and Settings/Balaji/Desktop/Fedora/uncompressed/" + 0 + "scan0009.pdf");
        }
    }

    private ByteArrayOutputStream compressData(InputStream fis) throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        CompressingOutputStream deflaterOutputStream = new CompressingOutputStream(outputStream);
        doCopy(fis, deflaterOutputStream);
        deflaterOutputStream.close();
        outputStream.close();
        return outputStream;
    }

    private InputStream uncompressData(InputStream inputStream) throws IOException {
        DecompressingInputStream iis = new DecompressingInputStream(inputStream);
        return iis;
    }

    private void doCopy(InputStream is, OutputStream os) throws IOException {
        byte data[] = new byte[BUFFER];
        BufferedOutputStream dest = new BufferedOutputStream(os, BUFFER);
        int count;
        try {
            while ((count = is.read(data, 0, BUFFER)) != -1) {
                dest.write(data, 0, count);
            }
        } catch (IOException exception) {

        }
        dest.flush();
        dest.close();
    }

    private void compressPDFFiles(String strPDFFilePath, String strCompressPDFPath) {
        try {
            PDFReader reader = new PDFReader(new File(strPDFFilePath));
            PDFWriter writer = new PDFWriter(new File(strCompressPDFPath), reader, false);
            for (int i = 0; i < reader.getObjCnt(); i++) {
                Object object = reader.getObject(i);
                if (object instanceof Dict) {
                    Dict dict = (Dict) object;
                    if (dict.containsKey("Subtype")) {
                        String subtype = reader.getObject(dict.get("Subtype")).toString();
                        if (subtype.equalsIgnoreCase("Image")) {
                            try {
                                InputStream inputStream = reader.getInputStream(dict);
                                HashMap hstKeys = ImageResizer.createResizedCopy(inputStream, false);
                                dict.putAll(hstKeys);
                            } catch (Exception ex) {

                            }
                        }
                    }
                }
            }
            writer.setExact(false);
            writer.setCompress(true);
            writer.writePDF();
            writer.close();
            reader.close();
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }
}