use of nitf.NITFException in project imageio-ext by geosolutions-it.
the class NITFReader method getImageReader.
private synchronized nitf.ImageReader getImageReader(int imageIndex) throws IOException {
checkIndex(imageIndex);
Integer key = new Integer(imageIndex);
try {
if (!imageReaderMap.containsKey(key))
imageReaderMap.put(key, reader.getNewImageReader(imageIndex));
return imageReaderMap.get(key);
} catch (NITFException e) {
LOGGER.severe(e.getLocalizedMessage());
throw new IIOException("NITF Exception", e);
}
}
use of nitf.NITFException in project imageio-ext by geosolutions-it.
the class NITFReader method readRaster.
/*
* Returns the ACTUAL data from the image. Note: for anything other than byte or int, this is NOT viewable. This is used for getting the actual
* data. (non-Javadoc)
*
* @see javax.imageio.ImageReader#readRaster(int, javax.imageio.ImageReadParam)
*/
@Override
public Raster readRaster(int imageIndex, ImageReadParam param) throws IOException {
checkIndex(imageIndex);
Rectangle sourceRegion = new Rectangle();
Rectangle destRegion = new Rectangle();
computeRegions(param, getWidth(imageIndex), getHeight(imageIndex), null, sourceRegion, destRegion);
// Set everything to default values
int sourceXSubsampling = param != null ? param.getSourceXSubsampling() : 1;
int sourceYSubsampling = param != null ? param.getSourceYSubsampling() : 1;
Point destinationOffset = param != null ? param.getDestinationOffset() : new Point(0, 0);
ImageSubheader subheader;
try {
subheader = record.getImages()[imageIndex].getSubheader();
} catch (NITFException e) {
throw new IOException(e);
}
String irep = subheader.getImageRepresentation().getStringData().trim();
String pvType = subheader.getPixelValueType().getStringData().trim();
int nbpp = subheader.getNumBitsPerPixel().getIntData();
int bandCount = subheader.getBandCount();
// make the band offsets array, for the output
int[] bandOffsets = null;
int[] sourceBands = param != null ? param.getSourceBands() : null;
if (param != null && param.getDestinationBands() != null) {
bandOffsets = param.getDestinationBands();
} else if (param != null && sourceBands != null) {
bandOffsets = new int[sourceBands.length];
for (int i = 0; i < bandOffsets.length; i++) {
bandOffsets[i] = sourceBands[i];
}
} else {
// Setup band offsets -- TODO should we really read ALL bands by
// default?
bandOffsets = new int[bandCount];
for (int i = 0; i < bandOffsets.length; i++) bandOffsets[i] = i;
}
int nBytes = ((nbpp - 1) / 8) + 1;
int bufType = -1;
// byte
if (nBytes == 1) {
bufType = DataBuffer.TYPE_BYTE;
} else // short
if (nBytes == 2) {
bufType = DataBuffer.TYPE_USHORT;
} else // float
if (nBytes == 4 && pvType.equals("R")) {
bufType = DataBuffer.TYPE_FLOAT;
} else // double
if (nBytes == 8 && pvType.equals("R")) {
bufType = DataBuffer.TYPE_DOUBLE;
} else {
throw new UnsupportedOperationException("not yet implemented");
}
WritableRaster ras = ImageIOUtils.makeGenericPixelInterleavedWritableRaster(destRegion.width, destRegion.height, bandOffsets.length, bufType);
checkReadParamBandSettings(param, bandCount, ras.getSampleModel().getNumBands());
readRaster(imageIndex, sourceRegion, destRegion, sourceXSubsampling, sourceYSubsampling, bandOffsets, nBytes, destinationOffset, ras);
return ras;
}
use of nitf.NITFException in project imageio-ext by geosolutions-it.
the class NITFReader method readFullImage.
/**
* Optimization to read the entire image in one fell swoop... This is most likely the common use case for this codec, so we hope this optimization
* will be helpful.
*
* @param imageIndex
* @param sourceXSubsampling
* @param sourceYSubsampling
* @param bandOffsets
* @param pixelSize
* @param imRas
* @throws IOException
*/
protected void readFullImage(int imageIndex, Rectangle destRegion, int sourceXSubsampling, int sourceYSubsampling, int[] bandOffsets, int pixelSize, WritableRaster imRas) throws IOException {
try {
ImageSubheader subheader = record.getImages()[imageIndex].getSubheader();
int numCols = destRegion.width;
int numRows = destRegion.height;
int nBands = subheader.getBandCount();
/*
* NOTE: This is a "fix" that will be removed once the underlying NITRO library gets patched. Currently, if you make a request of a single
* band, it doesn't matter which band you request - the data from the first band will be returned regardless. This is obviously wrong. To
* thwart this, we will read all bands, then scale down what we return to the user based on their actual request.
*/
int[] requestBands = bandOffsets;
/*
* if (nBands != bandOffsets.length && bandOffsets.length == 1 && bandOffsets[0] != 0) { requestBands = new int[nBands]; for (int i = 0; i
* < nBands; ++i) requestBands[i] = i; }
*/
int bufSize = numCols * numRows * pixelSize;
byte[][] imageBuf = new byte[requestBands.length][bufSize];
// make a SubWindow from the params
// TODO may want to read by blocks or rows to make faster and more
// memory efficient
SubWindow window;
window = new SubWindow();
window.setNumBands(requestBands.length);
window.setBandList(requestBands);
window.setNumCols(numCols);
window.setNumRows(numRows);
window.setStartCol(0);
window.setStartRow(0);
// the NITRO library can do the subsampling for us
if (sourceYSubsampling != 1 || sourceXSubsampling != 1) {
DownSampler downSampler = new PixelSkipDownSampler(sourceYSubsampling, sourceXSubsampling);
window.setDownSampler(downSampler);
}
// String pixelJustification = subheader.getPixelJustification()
// .getStringData().trim();
// boolean shouldSwap = pixelJustification.equals("R");
// since this is Java, we need the data in big-endian format
// boolean shouldSwap = ByteOrder.nativeOrder() !=
// ByteOrder.BIG_ENDIAN;
nitf.ImageReader imageReader = getImageReader(imageIndex);
imageReader.read(window, imageBuf);
List<ByteBuffer> bandBufs = new ArrayList<ByteBuffer>();
for (int i = 0; i < bandOffsets.length; ++i) {
ByteBuffer bandBuf = null;
// the special "fix" we added needs to do this
if (bandOffsets.length != requestBands.length) {
bandBuf = ByteBuffer.wrap(imageBuf[bandOffsets[i]]);
} else {
bandBuf = ByteBuffer.wrap(imageBuf[i]);
}
// ban dBuf.order(ByteOrder.nativeOrder());
// shouldSwap ? ByteOrder.LITTLE_ENDIAN
// : ByteOrder.BIG_ENDIAN);
bandBufs.add(bandBuf);
}
// optimization for 1 band case... just dump the whole thing
if (bandOffsets.length == 1) {
ByteBuffer bandBuf = bandBufs.get(0);
switch(pixelSize) {
case 1:
ByteBuffer rasterByteBuf = ByteBuffer.wrap(((DataBufferByte) imRas.getDataBuffer()).getData());
rasterByteBuf.put(bandBuf);
break;
case 2:
ShortBuffer rasterShortBuf = ShortBuffer.wrap(((DataBufferUShort) imRas.getDataBuffer()).getData());
rasterShortBuf.put(bandBuf.asShortBuffer());
break;
case 4:
FloatBuffer rasterFloatBuf = FloatBuffer.wrap(((DataBufferFloat) imRas.getDataBuffer()).getData());
rasterFloatBuf.put(bandBuf.asFloatBuffer());
break;
case 8:
DoubleBuffer rasterDoubleBuf = DoubleBuffer.wrap(((DataBufferDouble) imRas.getDataBuffer()).getData());
rasterDoubleBuf.put(bandBuf.asDoubleBuffer());
break;
}
} else {
for (int srcY = 0, srcX = 0; srcY < numRows; srcY++) {
// Copy each (subsampled) source pixel into imRas
for (int dstX = 0; dstX < numCols; srcX += pixelSize, dstX++) {
for (int i = 0; i < bandOffsets.length; ++i) {
ByteBuffer bandBuf = bandBufs.get(i);
switch(pixelSize) {
case 1:
imRas.setSample(dstX, srcY, i, bandBuf.get(srcX));
break;
case 2:
imRas.setSample(dstX, srcY, i, bandBuf.getShort(srcX));
break;
case 4:
imRas.setSample(dstX, srcY, i, bandBuf.getFloat(srcX));
break;
case 8:
imRas.setSample(dstX, srcY, i, bandBuf.getDouble(srcX));
break;
}
}
}
}
}
} catch (NITFException e1) {
throw new IOException(e1);
}
}
use of nitf.NITFException in project imageio-ext by geosolutions-it.
the class NITFReader method readRaster.
/**
* Reads image data as bytes for the given region, and writes it to the given writable raster
*
* @param sourceRegion
* @param sourceXSubsampling
* @param sourceYSubsampling
* @param bandOffsets
* @param destinationOffset
* @param imRas
* @return Raster
* @throws IOException
*/
protected void readRaster(int imageIndex, Rectangle sourceRegion, Rectangle destRegion, int sourceXSubsampling, int sourceYSubsampling, int[] bandOffsets, int pixelSize, Point destinationOffset, WritableRaster imRas) throws IOException {
checkIndex(imageIndex);
try {
ImageSubheader subheader = record.getImages()[imageIndex].getSubheader();
int numCols = subheader.getNumCols().getIntData();
int numRows = subheader.getNumRows().getIntData();
// image at once
if ((destRegion.height * sourceYSubsampling) == numRows && (destRegion.width * sourceXSubsampling) == numCols) {
readFullImage(imageIndex, destRegion, sourceXSubsampling, sourceYSubsampling, bandOffsets, pixelSize, imRas);
return;
} else // the general purpose case
{
int colBytes = destRegion.width * pixelSize;
int dstMinX = imRas.getMinX();
int dstMaxX = dstMinX + imRas.getWidth() - 1;
int dstMinY = imRas.getMinY();
int dstMaxY = dstMinY + imRas.getHeight() - 1;
// int swap = 0;
int nBands = subheader.getBandCount();
/*
* NOTE: This is a "fix" that will be removed once the underlying NITRO library gets patched. Currently, if you make a request of a
* single band, it doesn't matter which band you request - the data from the first band will be returned regardless. This is obviously
* wrong. To thwart this, we will read all bands, then scale down what we return to the user based on their actual request.
*/
int[] requestBands = new int[nBands];
for (int i = 0; i < nBands; ++i) requestBands[i] = i;
byte[][] rowBuf = new byte[requestBands.length][colBytes];
// make a SubWindow from the params
// TODO may want to read by blocks or rows to make faster and
// more
// memory efficient
SubWindow window;
window = new SubWindow();
window.setNumBands(requestBands.length);
window.setBandList(requestBands);
window.setNumCols(destRegion.width);
window.setNumRows(1);
window.setStartCol(sourceRegion.x);
window.setStartRow(sourceRegion.y);
// the NITRO library can do the subsampling for us
if (sourceYSubsampling != 1 || sourceXSubsampling != 1) {
DownSampler downSampler = new PixelSkipDownSampler(sourceYSubsampling, sourceXSubsampling);
window.setDownSampler(downSampler);
}
// String pixelJustification = record.getImages()[imageIndex]
// .getSubheader().getPixelJustification().getStringData()
// .trim();
// swap = pixelJustification.equals("R") ? 1 : 0;
List<ByteBuffer> bandBufs = new ArrayList<ByteBuffer>();
for (int i = 0; i < requestBands.length; ++i) {
ByteBuffer bandBuf = null;
bandBuf = ByteBuffer.wrap(rowBuf[i]);
// bandBuf.order(ByteOrder.nativeOrder());
// bandBuf.order(swap == 0 ? ByteOrder.BIG_ENDIAN
// : ByteOrder.LITTLE_ENDIAN);
bandBufs.add(bandBuf);
}
nitf.ImageReader imageReader = getImageReader(imageIndex);
for (int srcY = 0; srcY < sourceRegion.height; srcY++) {
if (sourceYSubsampling != 1 && (srcY % sourceYSubsampling) != 0)
continue;
window.setStartRow(sourceRegion.y + srcY);
// Read the row
try {
imageReader.read(window, rowBuf);
} catch (NITFException e) {
throw new IIOException("Error reading line " + srcY, e);
}
// Determine where the row will go in the destination
int dstY = destinationOffset.y + srcY / sourceYSubsampling;
if (dstY < dstMinY) {
// The row is above imRas
continue;
}
if (dstY > dstMaxY) {
// We're done with the image
break;
}
// Copy each (subsampled) source pixel into imRas
for (int srcX = 0, dstX = destinationOffset.x; srcX < colBytes; srcX += pixelSize, dstX++) {
if (dstX < dstMinX) {
continue;
}
if (dstX > dstMaxX) {
break;
}
for (int i = 0; i < bandOffsets.length; ++i) {
ByteBuffer bandBuf = bandBufs.get(bandOffsets[i]);
switch(pixelSize) {
case 1:
imRas.setSample(dstX, dstY, i, bandBuf.get(srcX));
break;
case 2:
imRas.setSample(dstX, dstY, i, bandBuf.getShort(srcX));
break;
case 4:
imRas.setSample(dstX, dstY, i, bandBuf.getFloat(srcX));
break;
case 8:
imRas.setSample(dstX, dstY, i, bandBuf.getDouble(srcX));
break;
}
}
}
}
}
} catch (NITFException e1) {
throw new IOException(e1);
}
}
use of nitf.NITFException in project imageio-ext by geosolutions-it.
the class NITFImageWriter method getShapeData.
/**
* @param record
* @param shape
* @return
* @throws NITFException
* @throws IOException
*/
private byte[] getShapeData(Record record, ShapeFileWrapper shape) throws NITFException, IOException {
final DESegment des = record.newDESegment();
byte[] fullData = null;
TRE csshpa = new TRE("CSSHPA");
TRE tre = des.getSubheader().setSubheaderFields(csshpa);
final byte[] bshp = shape.getShp();
final byte[] bshx = shape.getShx();
final byte[] bdbf = shape.getDbf();
final int shp = shape.getShpLength();
final int shx = shape.getShxLength();
final int dbf = shape.getDbfLength();
if (bshp == null || bshx == null || bdbf == null) {
throw new NITFException("Unable to write CSSHPA ShapeFile");
}
fullData = new byte[shp + shx + dbf];
System.arraycopy(bshp, 0, fullData, 0, shp);
System.arraycopy(bshx, 0, fullData, shp, shx);
System.arraycopy(bdbf, 0, fullData, shp + shx, dbf);
tre.setField("SHAPE_USE", "IMAGE_SHAPE ");
NITFUtilities.setTREField(tre, "SHAPE_CLASS", "POLYGON ", false);
NITFUtilities.setTREField(tre, "SHAPE1_NAME", "SHP", false);
NITFUtilities.setTREField(tre, "SHAPE1_START", NITFUtilities.Consts.ZERO, false);
NITFUtilities.setTREField(tre, "SHAPE2_NAME", "SHX", false);
NITFUtilities.setTREField(tre, "SHAPE2_START", String.valueOf(shp), false);
NITFUtilities.setTREField(tre, "SHAPE3_NAME", "DBF", false);
NITFUtilities.setTREField(tre, "SHAPE3_START", String.valueOf(shx + shp), false);
NITFUtilities.setField("DE", des.getSubheader().getFilePartType(), "DE");
NITFUtilities.setField("DESID", des.getSubheader().getTypeID(), "CSSHPA DES");
NITFUtilities.setField("DESVER", des.getSubheader().getVersion(), "01");
NITFUtilities.setField("DECLAS", des.getSubheader().getSecurityClass(), "U");
NITFUtilities.setField("DESCLSY", des.getSubheader().getSecurityGroup().getClassificationSystem(), "US");
return fullData;
}
Aggregations