io.github.h5jan.io.Grey12bitTIFFReader Maven / Gradle / Ivy
/*
* Copyright (c) 2012 Diamond Light Source Ltd.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package io.github.h5jan.io;
import it.tidalwave.imageio.io.RAWImageInputStream;
import it.tidalwave.imageio.raw.Packed12RasterReader;
import it.tidalwave.imageio.raw.RAWImageReaderSupport;
import it.tidalwave.imageio.raw.RasterReader;
import it.tidalwave.imageio.tiff.IFD;
import it.tidalwave.imageio.tiff.TIFFImageReaderSupport;
import it.tidalwave.imageio.tiff.TIFFMetadataSupport;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferUShort;
import java.awt.image.WritableRaster;
import java.io.IOException;
import javax.imageio.spi.ImageReaderSpi;
public class Grey12bitTIFFReader extends TIFFImageReaderSupport {
class Grey12RasterReader extends Packed12RasterReader {
@Override
protected void loadUncompressedRaster(final RAWImageInputStream iis, final WritableRaster raster,
final RAWImageReaderSupport ir) throws IOException {
final DataBufferUShort dataBuffer = (DataBufferUShort) raster.getDataBuffer();
final short[] data = dataBuffer.getData();
final int width = raster.getWidth();
final int height = raster.getHeight();
final int pixelStride = 1;
final int scanStride = width * pixelStride;
setBitsPerSample(12);
selectBitReader(iis, raster, 12);
//
// We can rely on the fact that the array has been zeroed by the JVM, so we just set nonzero samples.
//
for (int y = 0; y < height; y++) {
final int row = getRow(y, height);
int i = row * scanStride;
for (int x = 0; x < width; x++) {
int sample = (int) iis.readBits(12);
data[i] = (short) sample;
endOfColumn(x, iis);
i += pixelStride;
}
ir.processImageProgress((100.0f * y) / height);
endOfRow(y, iis);
}
}
@Override
protected int[] getBandOffsets() {
return new int[] {R_OFFSET};
}
}
public Grey12bitTIFFReader(final ImageReaderSpi originatingProvider) {
super(originatingProvider, IFD.class, TIFFMetadataSupport.class);
}
@Override
protected WritableRaster loadRAWRaster() throws IOException {
final IFD rasterIFD = ((TIFFMetadataSupport) metadata).getPrimaryIFD();
final RasterReader rasterReader = new Grey12RasterReader();
final int width = rasterIFD.getImageWidth();
final int height = rasterIFD.getImageLength();
final int bitsPerSample = rasterIFD.getBitsPerSample()[0];
initializeRasterReader(width, height, bitsPerSample, rasterReader);
if (!rasterIFD.isTileWidthAvailable()) {
iis.seek(rasterIFD.getStripOffsets()); // FIXME: move, it's responsibility of the rreader to seek
}
final WritableRaster raster = rasterReader.loadRaster(iis, this);
return raster;
}
@Override
protected BufferedImage loadImage(int imageIndex) throws IOException {
checkImageIndex(imageIndex);
ensureMetadataIsLoaded(imageIndex);
final WritableRaster raster = loadRAWRaster();
final int width = raster.getWidth();
final int height = raster.getHeight();
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_USHORT_GRAY);
bufferedImage.setData(raster);
return bufferedImage;
}
@Override
protected void initializeRasterReader(int width, int height, int bitsPerSample, RasterReader rasterReader) {
IFD rasterIFD = ((TIFFMetadataSupport) metadata).getRasterIFD();
rasterReader.setWidth(width);
rasterReader.setHeight(height);
rasterReader.setBitsPerSample(bitsPerSample);
// if (rasterReader instanceof Gray12RasterReader) {
// IFD primaryIFD = ((TIFFMetadataSupport) metadata).getPrimaryIFD();
// ((Gray12RasterReader) rasterReader).setStripsOffset(primaryIFD.getStripOffsets());
// }
if ((rasterIFD != null) && rasterIFD.isCompressionAvailable()) {
rasterReader.setCompression(rasterIFD.getCompression().intValue());
}
if ((rasterIFD != null) && rasterIFD.isStripByteCountsAvailable()) {
rasterReader.setStripByteCount(rasterIFD.getStripByteCounts());
}
if ((rasterIFD != null) && rasterIFD.isTileWidthAvailable()) {
int imageWidth = rasterIFD.getImageWidth();
int imageLength = rasterIFD.getImageLength();
int tileWidth = rasterIFD.getTileWidth();
int tileLength = rasterIFD.getTileLength();
rasterReader.setTileWidth(tileWidth);
rasterReader.setTileHeight(tileLength);
rasterReader.setTilesAcross((imageWidth + tileWidth - 1) / tileWidth);
rasterReader.setTilesDown((imageLength + tileLength - 1) / tileLength);
rasterReader.setTileOffsets(rasterIFD.getTileOffsets());
// int[] tileByteCounts = imageIFD.getTileByteCounts();
}
}
}