blob: 9157574ed3c5c225c63a674676840de903309b74 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.imaging.formats.tiff.datareaders;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import org.apache.commons.imaging.ImageReadException;
import org.apache.commons.imaging.common.BitInputStream;
import org.apache.commons.imaging.common.ImageBuilder;
import org.apache.commons.imaging.formats.tiff.TiffDirectory;
import org.apache.commons.imaging.formats.tiff.TiffImageData;
import org.apache.commons.imaging.formats.tiff.photometricinterpreters.PhotometricInterpreter;
public final class DataReaderTiled extends DataReader
{
private final int tileWidth;
private final int tileLength;
private final int bitsPerPixel;
private final int compression;
private final int byteOrder;
private final TiffImageData.Tiles imageData;
public DataReaderTiled(TiffDirectory directory,
PhotometricInterpreter photometricInterpreter,
int tileWidth, int tileLength, int bitsPerPixel,
int bitsPerSample[], int predictor, int samplesPerPixel, int width,
int height, int compression, int byteOrder, TiffImageData.Tiles imageData)
{
super(directory, photometricInterpreter, bitsPerSample, predictor, samplesPerPixel, width, height);
this.tileWidth = tileWidth;
this.tileLength = tileLength;
this.bitsPerPixel = bitsPerPixel;
this.compression = compression;
this.imageData = imageData;
this.byteOrder = byteOrder;
}
private void interpretTile(ImageBuilder imageBuilder, byte bytes[], int startX,
int startY) throws ImageReadException, IOException
{
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
BitInputStream bis = new BitInputStream(bais, byteOrder);
int pixelsPerTile = tileWidth * tileLength;
int tileX = 0, tileY = 0;
int[] samples = new int[bitsPerSample.length];
for (int i = 0; i < pixelsPerTile; i++)
{
int x = tileX + startX;
int y = tileY + startY;
getSamplesAsBytes(bis, samples);
if ((x < width) && (y < height))
{
samples = applyPredictor(samples, x);
photometricInterpreter.interpretPixel(imageBuilder, samples, x, y);
}
tileX++;
if (tileX >= tileWidth)
{
tileX = 0;
tileY++;
bis.flushCache();
if (tileY >= tileLength)
break;
}
}
}
@Override
public void readImageData(ImageBuilder imageBuilder) throws ImageReadException,
IOException
{
int bitsPerRow = tileWidth * bitsPerPixel;
int bytesPerRow = (bitsPerRow + 7) / 8;
int bytesPerTile = bytesPerRow * tileLength;
int x = 0, y = 0;
for (int tile = 0; tile < imageData.tiles.length; tile++)
{
byte compressed[] = imageData.tiles[tile].data;
byte decompressed[] = decompress(compressed, compression,
bytesPerTile, tileWidth, tileLength);
interpretTile(imageBuilder, decompressed, x, y);
x += tileWidth;
if (x >= width)
{
x = 0;
y += tileLength;
if (y >= height)
break;
}
}
}
}