It's not a secret anymore!*
The moose likes Java in General and the fly likes Splitting Tiff file with JAI taking more time Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "Splitting Tiff file with JAI taking more time" Watch "Splitting Tiff file with JAI taking more time" New topic
Author

Splitting Tiff file with JAI taking more time

Janardhan Kotha
Greenhorn

Joined: Feb 01, 2006
Posts: 14
Hi,

I am using Java Advanced Imaging (JAI) API to split a tiff file into mutliple files. Our tiff file is in COMPRESSION_GROUP4.

To split the file in memory, we are using ImageDecoder & ImageEncoder. Here if the original doc is 10 pages and we may want to split it as let us say 1-3, 4-5, 6-9, 10-10 pages, the decoder reads them as render image and encode as tiff using COMPRESSION_GROUP4. Decompression and compression is taking more time. Is there any way to get the compressed images as it is?

Please have a look at the source code below.

/* This is a helper class that takes a tiff byte stream path and
page ranges and returns a byte array for every page range */
public static List splitTiff(byte[] bytes, List pageRanges) throws AppException, Exception {
long startTime = System.currentTimeMillis();

final String methodName = "splitTiff";
DbHelper dbh = new DbHelper(logger, CLASS_NAME, methodName);

List splittedDocBytes = new ArrayList();

dbh.logMessage("Instantiating tiff decoder");
RenderedImage image;
TIFFDecodeParam param = new TIFFDecodeParam();
ImageDecoder decoder = ImageCodec.createImageDecoder("TIFF", new ByteArrayInputStream(bytes), param);
int pageCount = decoder.getNumPages();
dbh.logMessage("PageCount="+pageCount);

if ( pageRanges != null && pageCount > 0 ) {
List docPageRange;
int startPage = -1;
int endPage = -1;
int docCount = 0;

for (Iterator iter = pageRanges.iterator(); iter.hasNext(); ++docCount) {
docPageRange = (List)iter.next();
startPage = ((Integer)docPageRange.get(0)).intValue();
endPage = ((Integer)docPageRange.get(1)).intValue();

dbh.logMessage("Document "+docCount +" - startpage=" + startPage + " - endpage=" + endPage);

if ( startPage < 0 || startPage > pageCount
|| endPage < 0 || endPage > pageCount ){
throw new AppException(
2201,
AppException.ERROR,
CLASS_NAME,
methodName);
}

/* swap start & end pages if they are swapped */
if ( startPage > endPage ){
dbh.logMessage("swapping the start & end pages");
int temp = startPage;
startPage = endPage;
endPage = temp;
}

dbh.logMessage("extracting the page as rendered images from main document");
List pages = new ArrayList((endPage-startPage+1));
for (int pageIndex = startPage; pageIndex <= endPage; ++pageIndex) {
dbh.logMessage("pageIndex="+pageIndex);
image = decoder.decodeAsRenderedImage((pageIndex-1));
pages.add(image);
}

dbh.logMessage("getting the binary data of rendered images...");
byte[] pageBytes = getBytesForMultiPageTIFF(pages, dbh);

dbh.logMessage("adding binary data to return list...");
splittedDocBytes.add(pageBytes);
}
}

long endTime = System.currentTimeMillis();
dbh.logMessage("Time taken (ms):" + (endTime-startTime));

return splittedDocBytes;
}

/* It converts vector of buffered images to multi Page Tiff image and
* returns the byte array out of it. */
private static byte[] getBytesForMultiPageTIFF(List images, DbHelper dbh) throws IOException {
long startTime = System.currentTimeMillis();

final String methodName = "getBytesForMultiPageTIFF";
dbh.setMethodName(methodName);

byte[] bytes = new byte[0];

/* check if there are any images?? */
if (images.size() < 1)
return bytes;

/*Get the first page and remove it from list*/
dbh.logMessage("Getting the first rendered page/image");
RenderedImage firstImage = (RenderedImage) images.get(0);
images.remove(0);

ByteArrayOutputStream out = null;

try {
/* We need to capture the data in byte array */
dbh.logMessage("instantiating byte-array-outputstream to write binary data of images");
out = new ByteArrayOutputStream();

/*Use tiffencoder and write the data to byte array output stream. */
dbh.logMessage("instantiating tiff encoder to encode binary data");
TIFFEncodeParam param = new TIFFEncodeParam();
param.setCompression(TIFFEncodeParam.COMPRESSION_GROUP4);
ImageEncoder encoder = ImageCodec.createImageEncoder("TIFF", out, param);

/*Set the pages other than first page*/
dbh.logMessage("setting all the pages to be written other than first-page");
if (images.size() > 0) {
param.setExtraImages(images.iterator());
}

/*Encode the first image.*/
dbh.logMessage("encode first page");

/*THIS IS THE CULPRIT & TAKING MORE TIME.*/
encoder.encode(firstImage);

/* Get the data in bytes */
dbh.logMessage("get the data in bytes");
bytes = out.toByteArray();

} catch (IOException ex) {
throw ex;
}
finally{
if ( null != out ){
out.close();
}
}

long endTime = System.currentTimeMillis();
dbh.logMessage("Time taken (ms):" + (endTime-startTime));
return bytes;
}

Appreciate your help.

Thanks,
Janardhan.
[ February 01, 2006: Message edited by: Janardhan Kotha ]
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24183
    
  34

Hi,

Welcome to JavaRanch!

Please don't post the same question to multiple forums; I've deleted your other copy. See here for an explanation.

Have you done any profiling? Do you know where the time is going?


[Jess in Action][AskingGoodQuestions]
Janardhan Kotha
Greenhorn

Joined: Feb 01, 2006
Posts: 14
Hi,

My apologies for posting in different forums. I haven't done the profiling, but as per the timings(in millis) from my log file, it is taking more time in encoder.encode().

Thanks in advance.
Rao Kotha.
 
wood burning stoves
 
subject: Splitting Tiff file with JAI taking more time
 
Similar Threads
Setting ScrollPane size
Image Dimensions
Error Diplaying TIFF in Applet through JSP
Grid size limit
problems while converting