• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Splitting Tiff file with JAI taking more time

 
Janardhan Kotha
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Pie
Posts: 24211
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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?
 
Janardhan Kotha
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic