• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
  • Campbell Ritchie
  • Liutauras Vilda
  • Tim Cooke
  • Jeanne Boyarsky
  • Paul Clapham
  • Devaka Cooray
  • Ron McLeod
  • paul wheaton
Saloon Keepers:
  • Tim Moores
  • Piet Souris
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Al Hobbs
  • Frits Walraven
  • Scott Selikoff

Splitting Tiff file with JAI taking more time

Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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 ]
author and iconoclast
Posts: 24204
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
    Number of slices to send:
    Optional 'thank-you' note:
  • 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.
Water proof donuts! Eat them while reading this tiny ad:
the value of filler advertising in 2021
    Bookmark Topic Watch Topic
  • New Topic