• Post Reply Bookmark Topic Watch Topic
  • New Topic

Splitting Tiff file with JAI taking more time  RSS feed

Janardhan Kotha
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

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();

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(

/* 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) {
image = decoder.decodeAsRenderedImage((pageIndex-1));

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

dbh.logMessage("adding binary data to return list...");

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";

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);

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();
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) {

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


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

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

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

Appreciate your help.

[ February 01, 2006: Message edited by: Janardhan Kotha ]
Ernest Friedman-Hill
author and iconoclast
Posts: 24217
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

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
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

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
Boost this thread!