use of javax.imageio.ImageTypeSpecifier in project imageio-ext by geosolutions-it.
the class EmptyImage method replacePixels.
public void replacePixels(RenderedImage image, ImageWriteParam param) throws IOException {
synchronized (replacePixelsLock) {
// Check state and parameters vis-a-vis ImageWriter specification.
if (stream == null) {
throw new IllegalStateException("stream == null!");
}
if (image == null) {
throw new IllegalArgumentException("image == null!");
}
if (!inReplacePixelsNest) {
throw new IllegalStateException("No previous call to prepareReplacePixels!");
}
// Subsampling values.
int stepX = 1, stepY = 1, gridX = 0, gridY = 0;
// Initialize the ImageWriteParam.
if (param == null) {
// Use the default.
param = getDefaultWriteParam();
} else {
// Make a copy of the ImageWriteParam.
ImageWriteParam paramCopy = getDefaultWriteParam();
// Force uncompressed.
paramCopy.setCompressionMode(ImageWriteParam.MODE_DISABLED);
// Force tiling to remain as in the already written image.
paramCopy.setTilingMode(ImageWriteParam.MODE_COPY_FROM_METADATA);
// Retain source and destination region and band settings.
paramCopy.setDestinationOffset(param.getDestinationOffset());
paramCopy.setSourceBands(param.getSourceBands());
paramCopy.setSourceRegion(param.getSourceRegion());
// Save original subsampling values for subsampling the
// replacement data - not the data re-read from the image.
stepX = param.getSourceXSubsampling();
stepY = param.getSourceYSubsampling();
gridX = param.getSubsamplingXOffset();
gridY = param.getSubsamplingYOffset();
// Replace the param.
param = paramCopy;
}
// Check band count and bit depth compatibility.
TIFFField f = replacePixelsMetadata.getTIFFField(BaselineTIFFTagSet.TAG_BITS_PER_SAMPLE);
if (f == null) {
throw new IIOException("Cannot read destination BitsPerSample");
}
int[] dstBitsPerSample = f.getAsInts();
int[] srcBitsPerSample = image.getSampleModel().getSampleSize();
int[] sourceBands = param.getSourceBands();
if (sourceBands != null) {
if (sourceBands.length != dstBitsPerSample.length) {
throw new IIOException("Source and destination have different SamplesPerPixel");
}
for (int i = 0; i < sourceBands.length; i++) {
if (dstBitsPerSample[i] != srcBitsPerSample[sourceBands[i]]) {
throw new IIOException("Source and destination have different BitsPerSample");
}
}
} else {
int srcNumBands = image.getSampleModel().getNumBands();
if (srcNumBands != dstBitsPerSample.length) {
throw new IIOException("Source and destination have different SamplesPerPixel");
}
for (int i = 0; i < srcNumBands; i++) {
if (dstBitsPerSample[i] != srcBitsPerSample[i]) {
throw new IIOException("Source and destination have different BitsPerSample");
}
}
}
// Get the source image bounds.
Rectangle srcImageBounds = new Rectangle(image.getMinX(), image.getMinY(), image.getWidth(), image.getHeight());
// Initialize the source rect.
Rectangle srcRect = param.getSourceRegion();
if (srcRect == null) {
srcRect = srcImageBounds;
}
// Set subsampling grid parameters.
int subPeriodX = stepX;
int subPeriodY = stepY;
int subOriginX = gridX + srcRect.x;
int subOriginY = gridY + srcRect.y;
// Intersect with the source bounds.
if (!srcRect.equals(srcImageBounds)) {
srcRect = srcRect.intersection(srcImageBounds);
if (srcRect.isEmpty()) {
throw new IllegalArgumentException("Source region does not intersect source image!");
}
}
// Get the destination offset.
Point dstOffset = param.getDestinationOffset();
// Forward map source rectangle to determine destination width.
int dMinX = XToTileX(srcRect.x, subOriginX, subPeriodX) + dstOffset.x;
int dMinY = YToTileY(srcRect.y, subOriginY, subPeriodY) + dstOffset.y;
int dMaxX = XToTileX(srcRect.x + srcRect.width, subOriginX, subPeriodX) + dstOffset.x;
int dMaxY = YToTileY(srcRect.y + srcRect.height, subOriginY, subPeriodY) + dstOffset.y;
// Initialize the destination rectangle.
Rectangle dstRect = new Rectangle(dstOffset.x, dstOffset.y, dMaxX - dMinX, dMaxY - dMinY);
// Intersect with the replacement region.
dstRect = dstRect.intersection(replacePixelsRegion);
if (dstRect.isEmpty()) {
throw new IllegalArgumentException("Forward mapped source region does not intersect destination region!");
}
// Backward map to the active source region.
int activeSrcMinX = (dstRect.x - dstOffset.x) * subPeriodX + subOriginX;
int sxmax = (dstRect.x + dstRect.width - 1 - dstOffset.x) * subPeriodX + subOriginX;
int activeSrcWidth = sxmax - activeSrcMinX + 1;
int activeSrcMinY = (dstRect.y - dstOffset.y) * subPeriodY + subOriginY;
int symax = (dstRect.y + dstRect.height - 1 - dstOffset.y) * subPeriodY + subOriginY;
int activeSrcHeight = symax - activeSrcMinY + 1;
Rectangle activeSrcRect = new Rectangle(activeSrcMinX, activeSrcMinY, activeSrcWidth, activeSrcHeight);
if (activeSrcRect.intersection(srcImageBounds).isEmpty()) {
throw new IllegalArgumentException("Backward mapped destination region does not intersect source image!");
}
if (reader == null) {
reader = new TIFFImageReader(new TIFFImageReaderSpi());
} else {
reader.reset();
}
stream.mark();
try {
stream.seek(headerPosition);
reader.setInput(stream);
this.imageMetadata = replacePixelsMetadata;
this.param = param;
SampleModel sm = image.getSampleModel();
ColorModel cm = image.getColorModel();
this.numBands = sm.getNumBands();
this.imageType = new ImageTypeSpecifier(image);
this.periodX = param.getSourceXSubsampling();
this.periodY = param.getSourceYSubsampling();
this.sourceBands = null;
int[] sBands = param.getSourceBands();
if (sBands != null) {
this.sourceBands = sBands;
this.numBands = sourceBands.length;
}
setupMetadata(cm, sm, reader.getWidth(replacePixelsIndex), reader.getHeight(replacePixelsIndex));
int[] scaleSampleSize = sm.getSampleSize();
initializeScaleTables(scaleSampleSize);
// Determine whether bilevel.
this.isBilevel = ImageUtil.isBinary(image.getSampleModel());
// Check for photometric inversion.
this.isInverted = (nativePhotometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO && photometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO) || (nativePhotometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO && photometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO);
// Analyze image data suitability for direct copy.
this.isImageSimple = (isBilevel || (!isInverted && ImageUtil.imageIsContiguous(image))) && // no value rescaling
!isRescaling && // no subbanding
sourceBands == null && periodX == 1 && // no subsampling
periodY == 1 && colorConverter == null;
int minTileX = XToTileX(dstRect.x, 0, tileWidth);
int minTileY = YToTileY(dstRect.y, 0, tileLength);
int maxTileX = XToTileX(dstRect.x + dstRect.width - 1, 0, tileWidth);
int maxTileY = YToTileY(dstRect.y + dstRect.height - 1, 0, tileLength);
TIFFCompressor encoder = new TIFFNullCompressor();
encoder.setWriter(this);
encoder.setStream(stream);
encoder.setMetadata(this.imageMetadata);
Rectangle tileRect = new Rectangle();
for (int ty = minTileY; ty <= maxTileY; ty++) {
for (int tx = minTileX; tx <= maxTileX; tx++) {
int tileIndex = ty * tilesAcross + tx;
boolean isEmpty = replacePixelsByteCounts[tileIndex] == 0L;
WritableRaster raster;
if (isEmpty) {
SampleModel tileSM = sm.createCompatibleSampleModel(tileWidth, tileLength);
raster = Raster.createWritableRaster(tileSM, null);
} else {
BufferedImage tileImage = reader.readTile(replacePixelsIndex, tx, ty);
raster = tileImage.getRaster();
}
tileRect.setLocation(tx * tileWidth, ty * tileLength);
tileRect.setSize(raster.getWidth(), raster.getHeight());
raster = raster.createWritableTranslatedChild(tileRect.x, tileRect.y);
Rectangle replacementRect = tileRect.intersection(dstRect);
int srcMinX = (replacementRect.x - dstOffset.x) * subPeriodX + subOriginX;
int srcXmax = (replacementRect.x + replacementRect.width - 1 - dstOffset.x) * subPeriodX + subOriginX;
int srcWidth = srcXmax - srcMinX + 1;
int srcMinY = (replacementRect.y - dstOffset.y) * subPeriodY + subOriginY;
int srcYMax = (replacementRect.y + replacementRect.height - 1 - dstOffset.y) * subPeriodY + subOriginY;
int srcHeight = srcYMax - srcMinY + 1;
Rectangle srcTileRect = new Rectangle(srcMinX, srcMinY, srcWidth, srcHeight);
Raster replacementData = image.getData(srcTileRect);
if (subPeriodX == 1 && subPeriodY == 1 && subOriginX == 0 && subOriginY == 0) {
replacementData = replacementData.createChild(srcTileRect.x, srcTileRect.y, srcTileRect.width, srcTileRect.height, replacementRect.x, replacementRect.y, sourceBands);
} else {
replacementData = subsample(replacementData, sourceBands, subOriginX, subOriginY, subPeriodX, subPeriodY, dstOffset.x, dstOffset.y, replacementRect);
if (replacementData == null) {
continue;
}
}
raster.setRect(replacementData);
if (isEmpty) {
stream.seek(nextSpace);
} else {
stream.seek(replacePixelsTileOffsets[tileIndex]);
}
this.image = new SingleTileRenderedImage(raster, cm);
int numBytes = writeTile(tileRect, encoder);
if (isEmpty) {
// Update Strip/TileOffsets and
// Strip/TileByteCounts fields.
stream.mark();
stream.seek(replacePixelsOffsetsPosition + 4 * tileIndex);
stream.writeInt((int) nextSpace);
stream.seek(replacePixelsByteCountsPosition + 4 * tileIndex);
stream.writeInt(numBytes);
stream.reset();
// Increment location of next available space.
nextSpace += numBytes;
}
}
}
} catch (IOException e) {
throw e;
} finally {
stream.reset();
}
}
}
use of javax.imageio.ImageTypeSpecifier in project imageio-ext by geosolutions-it.
the class PNMImageWriter method write.
public void write(IIOMetadata streamMetadata, IIOImage image, ImageWriteParam param) throws IOException {
clearAbortRequest();
processImageStarted(0);
if (param == null)
param = getDefaultWriteParam();
RenderedImage input = null;
Raster inputRaster = null;
boolean writeRaster = image.hasRaster();
Rectangle sourceRegion = param.getSourceRegion();
SampleModel sampleModel = null;
ColorModel colorModel = null;
if (writeRaster) {
inputRaster = image.getRaster();
sampleModel = inputRaster.getSampleModel();
if (sourceRegion == null)
sourceRegion = inputRaster.getBounds();
else
sourceRegion = sourceRegion.intersection(inputRaster.getBounds());
} else {
input = image.getRenderedImage();
sampleModel = input.getSampleModel();
colorModel = input.getColorModel();
Rectangle rect = new Rectangle(input.getMinX(), input.getMinY(), input.getWidth(), input.getHeight());
if (sourceRegion == null)
sourceRegion = rect;
else
sourceRegion = sourceRegion.intersection(rect);
}
if (sourceRegion.isEmpty())
throw new RuntimeException(I18N.getString("PNMImageWrite1"));
ImageUtil.canEncodeImage(this, colorModel, sampleModel);
int scaleX = param.getSourceXSubsampling();
int scaleY = param.getSourceYSubsampling();
int xOffset = param.getSubsamplingXOffset();
int yOffset = param.getSubsamplingYOffset();
sourceRegion.translate(xOffset, yOffset);
sourceRegion.width -= xOffset;
sourceRegion.height -= yOffset;
int w = (sourceRegion.width + scaleX - 1) / scaleX;
int h = (sourceRegion.height + scaleY - 1) / scaleY;
int tileWidth = sampleModel.getWidth();
// Raw data can only handle bytes, everything greater must be ASCII.
int[] sampleSize = sampleModel.getSampleSize();
int[] sourceBands = param.getSourceBands();
int numBands = sampleModel.getNumBands();
if (sourceBands != null) {
sampleModel = sampleModel.createSubsetSampleModel(sourceBands);
colorModel = null;
numBands = sampleModel.getNumBands();
} else {
sourceBands = new int[numBands];
for (int i = 0; i < numBands; i++) sourceBands[i] = i;
}
// Colormap populated for non-bilevel IndexColorModel only.
byte[] reds = null;
byte[] greens = null;
byte[] blues = null;
// Flag indicating that PB data should be inverted before writing.
boolean isPBMInverted = false;
if (numBands == 1) {
if (colorModel instanceof IndexColorModel) {
IndexColorModel icm = (IndexColorModel) colorModel;
int mapSize = icm.getMapSize();
if (mapSize < (1 << sampleSize[0]))
throw new RuntimeException(I18N.getString("PNMImageWrite2"));
if (sampleSize[0] == 1) {
variant = PBM_RAW;
// Set PBM inversion flag if 1 maps to a higher color
// value than 0: PBM expects white-is-zero so if this
// does not obtain then inversion needs to occur.
isPBMInverted = icm.getRed(1) > icm.getRed(0);
} else {
variant = PPM_RAW;
reds = new byte[mapSize];
greens = new byte[mapSize];
blues = new byte[mapSize];
icm.getReds(reds);
icm.getGreens(greens);
icm.getBlues(blues);
}
} else if (sampleSize[0] == 1) {
variant = PBM_RAW;
} else if (sampleSize[0] <= 8) {
variant = PGM_RAW;
} else {
variant = PGM_ASCII;
}
} else if (numBands == 3) {
if (sampleSize[0] <= 8 && sampleSize[1] <= 8 && sampleSize[2] <= 8) {
// all 3 bands must be <= 8
variant = PPM_RAW;
} else {
variant = PPM_ASCII;
}
} else {
throw new RuntimeException(I18N.getString("PNMImageWrite3"));
}
IIOMetadata inputMetadata = image.getMetadata();
ImageTypeSpecifier imageType;
if (colorModel != null) {
imageType = new ImageTypeSpecifier(colorModel, sampleModel);
} else {
int dataType = sampleModel.getDataType();
switch(numBands) {
case 1:
imageType = ImageTypeSpecifier.createGrayscale(sampleSize[0], dataType, false);
break;
case 3:
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
imageType = ImageTypeSpecifier.createInterleaved(cs, new int[] { 0, 1, 2 }, dataType, false, false);
break;
default:
throw new IIOException("Cannot encode image with " + numBands + " bands!");
}
}
PNMMetadata metadata;
if (inputMetadata != null) {
// Convert metadata.
metadata = (PNMMetadata) convertImageMetadata(inputMetadata, imageType, param);
} else {
// Use default.
metadata = (PNMMetadata) getDefaultImageMetadata(imageType, param);
}
// Read parameters
boolean isRawPNM;
if (param instanceof PNMImageWriteParam) {
isRawPNM = ((PNMImageWriteParam) param).getRaw();
} else {
isRawPNM = metadata.isRaw();
}
maxValue = metadata.getMaxValue();
for (int i = 0; i < sampleSize.length; i++) {
int v = (1 << sampleSize[i]) - 1;
if (v > maxValue) {
maxValue = v;
}
}
if (isRawPNM) {
// Raw output is desired.
int maxBitDepth = metadata.getMaxBitDepth();
if (!isRaw(variant) && maxBitDepth <= 8) {
// Current variant is ASCII and the bit depth is acceptable
// so convert to RAW variant by adding '3' to variant.
variant += 0x3;
} else if (isRaw(variant) && maxBitDepth > 8) {
// Current variant is RAW and the bit depth it too large for
// RAW so convert to ASCII.
variant -= 0x3;
}
// Omitted cases are (variant == RAW && max <= 8) and
// (variant == ASCII && max > 8) neither of which requires action.
} else if (isRaw(variant)) {
// Raw output is NOT desired so convert to ASCII
variant -= 0x3;
}
// Write PNM file.
// magic value: 'P'
stream.writeByte('P');
stream.writeByte(variant);
stream.write(lineSeparator);
// comment line
stream.write(COMMENT.getBytes());
// Write the comments provided in the metadata
Iterator comments = metadata.getComments();
if (comments != null) {
while (comments.hasNext()) {
stream.write(lineSeparator);
String comment = "# " + (String) comments.next();
stream.write(comment.getBytes());
}
}
stream.write(lineSeparator);
// width
writeInteger(stream, w);
stream.write(SPACE);
// height
writeInteger(stream, h);
// Write sample max value for non-binary images
if ((variant != PBM_RAW) && (variant != PBM_ASCII)) {
stream.write(lineSeparator);
writeInteger(stream, maxValue);
}
// last header value and the start of the raw data.
if (variant == PBM_RAW || variant == PGM_RAW || variant == PPM_RAW) {
stream.write('\n');
}
// Set flag for optimal image writing case: row-packed data with
// correct band order if applicable.
boolean writeOptimal = false;
if (variant == PBM_RAW && sampleModel.getTransferType() == DataBuffer.TYPE_BYTE && sampleModel instanceof MultiPixelPackedSampleModel) {
MultiPixelPackedSampleModel mppsm = (MultiPixelPackedSampleModel) sampleModel;
int originX = 0;
if (writeRaster)
originX = inputRaster.getMinX();
else
originX = input.getMinX();
// Must have left-aligned bytes with unity bit stride.
if (mppsm.getBitOffset((sourceRegion.x - originX) % tileWidth) == 0 && mppsm.getPixelBitStride() == 1 && scaleX == 1)
writeOptimal = true;
} else if ((variant == PGM_RAW || variant == PPM_RAW) && sampleModel instanceof ComponentSampleModel && !(colorModel instanceof IndexColorModel)) {
ComponentSampleModel csm = (ComponentSampleModel) sampleModel;
// Pixel stride must equal band count.
if (csm.getPixelStride() == numBands && scaleX == 1) {
writeOptimal = true;
// Band offsets must equal band indices.
if (variant == PPM_RAW) {
int[] bandOffsets = csm.getBandOffsets();
for (int b = 0; b < numBands; b++) {
if (bandOffsets[b] != b) {
writeOptimal = false;
break;
}
}
}
}
}
// Write using an optimal approach if possible.
if (writeOptimal) {
int bytesPerRow = variant == PBM_RAW ? (w + 7) / 8 : w * sampleModel.getNumBands();
byte[] bdata = null;
byte[] invertedData = new byte[bytesPerRow];
// Loop over tiles to minimize cobbling.
for (int j = 0; j < sourceRegion.height; j++) {
if (abortRequested())
break;
Raster lineRaster = null;
if (writeRaster) {
lineRaster = inputRaster.createChild(sourceRegion.x, j, sourceRegion.width, 1, 0, 0, null);
} else {
lineRaster = input.getData(new Rectangle(sourceRegion.x, sourceRegion.y + j, w, 1));
lineRaster = lineRaster.createTranslatedChild(0, 0);
}
bdata = ((DataBufferByte) lineRaster.getDataBuffer()).getData();
sampleModel = lineRaster.getSampleModel();
int offset = 0;
if (sampleModel instanceof ComponentSampleModel) {
offset = ((ComponentSampleModel) sampleModel).getOffset(lineRaster.getMinX() - lineRaster.getSampleModelTranslateX(), lineRaster.getMinY() - lineRaster.getSampleModelTranslateY());
} else if (sampleModel instanceof MultiPixelPackedSampleModel) {
offset = ((MultiPixelPackedSampleModel) sampleModel).getOffset(lineRaster.getMinX() - lineRaster.getSampleModelTranslateX(), lineRaster.getMinX() - lineRaster.getSampleModelTranslateY());
}
if (isPBMInverted) {
for (int k = offset, m = 0; m < bytesPerRow; k++, m++) invertedData[m] = (byte) ~bdata[k];
bdata = invertedData;
offset = 0;
}
stream.write(bdata, offset, bytesPerRow);
processImageProgress(100.0F * j / sourceRegion.height);
}
// Write all buffered bytes and return.
stream.flush();
if (abortRequested())
processWriteAborted();
else
processImageComplete();
return;
}
// Buffer for 1 rows of original pixels
int size = sourceRegion.width * numBands;
int[] pixels = new int[size];
// Also allocate a buffer to hold the data to be written to the file,
// so we can use array writes.
byte[] bpixels = reds == null ? new byte[w * numBands] : new byte[w * 3];
// The index of the sample being written, used to
// place a line separator after every 16th sample in
// ASCII mode. Not used in raw mode.
int count = 0;
// Process line by line
int lastRow = sourceRegion.y + sourceRegion.height;
for (int row = sourceRegion.y; row < lastRow; row += scaleY) {
if (abortRequested())
break;
// Grab the pixels
Raster src = null;
if (writeRaster)
src = inputRaster.createChild(sourceRegion.x, row, sourceRegion.width, 1, sourceRegion.x, row, sourceBands);
else
src = input.getData(new Rectangle(sourceRegion.x, row, sourceRegion.width, 1));
src.getPixels(sourceRegion.x, row, sourceRegion.width, 1, pixels);
if (isPBMInverted)
for (int i = 0; i < size; i += scaleX) bpixels[i] ^= 1;
switch(variant) {
case PBM_ASCII:
for (int i = 0; i < size; i += scaleX) {
if ((count++ % 16) == 0)
stream.write(lineSeparator);
else
stream.write(SPACE);
writeInteger(stream, isPBMInverted ? (byte) ~pixels[i] : pixels[i]);
}
stream.write(lineSeparator);
break;
case PGM_ASCII:
for (int i = 0; i < size; i += scaleX) {
if ((count++ % 16) == 0)
stream.write(lineSeparator);
else
stream.write(SPACE);
writeInteger(stream, pixels[i]);
}
stream.write(lineSeparator);
break;
case PPM_ASCII:
if (reds == null) {
for (int i = 0; i < size; i += scaleX * numBands) {
for (int j = 0; j < numBands; j++) {
if ((count++ % 16) == 0)
stream.write(lineSeparator);
else
stream.write(SPACE);
writeInteger(stream, pixels[i + j]);
}
}
} else {
for (int i = 0; i < size; i += scaleX) {
if ((count++ % 5) == 0)
stream.write(lineSeparator);
else
stream.write(SPACE);
writeInteger(stream, (reds[pixels[i]] & 0xFF));
stream.write(SPACE);
writeInteger(stream, (greens[pixels[i]] & 0xFF));
stream.write(SPACE);
writeInteger(stream, (blues[pixels[i]] & 0xFF));
}
}
stream.write(lineSeparator);
break;
case PBM_RAW:
// 8 pixels packed into 1 byte, the leftovers are padded.
int kdst = 0;
int b = 0;
int pos = 7;
for (int i = 0; i < size; i += scaleX) {
b |= pixels[i] << pos;
pos--;
if (pos == -1) {
bpixels[kdst++] = (byte) b;
b = 0;
pos = 7;
}
}
if (pos != 7)
bpixels[kdst++] = (byte) b;
stream.write(bpixels, 0, kdst);
break;
case PGM_RAW:
for (int i = 0, j = 0; i < size; i += scaleX) {
bpixels[j++] = (byte) (pixels[i]);
}
stream.write(bpixels, 0, w);
break;
case PPM_RAW:
if (reds == null) {
// no need to expand
for (int i = 0, k = 0; i < size; i += scaleX * numBands) {
for (int j = 0; j < numBands; j++) bpixels[k++] = (byte) (pixels[i + j] & 0xFF);
}
} else {
for (int i = 0, j = 0; i < size; i += scaleX) {
bpixels[j++] = reds[pixels[i]];
bpixels[j++] = greens[pixels[i]];
bpixels[j++] = blues[pixels[i]];
}
}
stream.write(bpixels, 0, bpixels.length);
break;
}
processImageProgress(100.0F * (row - sourceRegion.y) / sourceRegion.height);
}
// Force all buffered bytes to be written out.
stream.flush();
if (abortRequested())
processWriteAborted();
else
processImageComplete();
}
use of javax.imageio.ImageTypeSpecifier in project imageio-ext by geosolutions-it.
the class PNMMetadata method initialize.
void initialize(ImageTypeSpecifier imageType, ImageWriteParam param) {
ImageTypeSpecifier destType = null;
if (param != null) {
destType = param.getDestinationType();
if (destType == null) {
destType = imageType;
}
} else {
destType = imageType;
}
if (destType != null) {
SampleModel sm = destType.getSampleModel();
int[] sampleSize = sm.getSampleSize();
this.width = sm.getWidth();
this.height = sm.getHeight();
for (int i = 0; i < sampleSize.length; i++) {
if (sampleSize[i] > maxSampleSize) {
maxSampleSize = sampleSize[i];
}
}
this.maxSample = (1 << maxSampleSize) - 1;
// default value
boolean isRaw = true;
if (param instanceof PNMImageWriteParam) {
isRaw = ((PNMImageWriteParam) param).getRaw();
}
if (maxSampleSize == 1)
variant = '1';
else if (sm.getNumBands() == 1) {
variant = '2';
} else if (sm.getNumBands() == 3) {
variant = '3';
}
// Force to Raw if the sample size is small enough.
if (variant <= '3' && isRaw && maxSampleSize <= 8) {
variant += 0x3;
}
}
}
use of javax.imageio.ImageTypeSpecifier in project imageio-ext by geosolutions-it.
the class NITFReader method read.
@Override
public BufferedImage read(int imageIndex, ImageReadParam param) throws IOException {
readHeader();
Raster raster = readRaster(imageIndex, param);
// get the requested number of destination bands (or 0 for all)
int numDestBands = param != null ? (param.getDestinationBands() != null ? param.getDestinationBands().length : param.getSourceBands() != null ? param.getSourceBands().length : 0) : 0;
// try to find a good match for the specifier
ImageTypeSpecifier imageType = null, firstType = null;
Iterator<ImageTypeSpecifier> imageTypes = getImageTypes(imageIndex);
while (imageTypes.hasNext() && imageType == null) {
ImageTypeSpecifier currentImageType = imageTypes.next();
if (firstType == null)
firstType = currentImageType;
if (currentImageType.getNumBands() == numDestBands)
imageType = currentImageType;
}
if (imageType == null) {
if (firstType == null)
throw new IOException("Unable to determine the ImageTypeSpecifier");
else
imageType = firstType;
}
try {
ImageSubheader subheader = record.getImages()[imageIndex].getSubheader();
String pvType = subheader.getPixelValueType().getStringData().trim();
int nbpp = subheader.getNumBitsPerPixel().getIntData();
int nBytes = ((nbpp - 1) / 8) + 1;
if (nBytes == 1 || nBytes == 2 || (nBytes == 4 && pvType.equals("R")) || (nBytes == 8 && pvType.equals("R"))) {
return ImageIOUtils.rasterToBufferedImage(raster, imageType);
}
} catch (NITFException e) {
throw new IOException(e);
}
throw new UnsupportedOperationException("Image pixel type or bits per pixel not yet supported");
}
use of javax.imageio.ImageTypeSpecifier in project imageio-ext by geosolutions-it.
the class NITFReader method getImageTypes.
@Override
public Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex) throws IOException {
checkIndex(imageIndex);
List<ImageTypeSpecifier> l = new ArrayList<ImageTypeSpecifier>();
try {
ImageSubheader subheader = record.getImages()[imageIndex].getSubheader();
String irep = subheader.getImageRepresentation().getStringData().trim();
String pvType = subheader.getPixelValueType().getStringData().trim();
int bandCount = subheader.getBandCount();
int nbpp = subheader.getNumBitsPerPixel().getIntData();
// if (NITFUtils.isCompressed(record, imageIndex))
// {
// throw new NotImplementedException(
// "Only uncompressed imagery is currently supported");
// }
int nBytes = ((nbpp - 1) / 8) + 1;
if (nBytes == 1 || nBytes == 2 || (nBytes == 4 && pvType.equals("R")) || (nBytes == 8 && pvType.equals("R"))) {
if (nBytes == 1 && bandCount == 3 && irep.equals("RGB")) {
ColorSpace rgb = ColorSpace.getInstance(ColorSpace.CS_sRGB);
int[] bandOffsets = new int[3];
for (int i = 0; i < bandOffsets.length; ++i) bandOffsets[i] = i;
l.add(ImageTypeSpecifier.createInterleaved(rgb, bandOffsets, DataBuffer.TYPE_BYTE, false, false));
}
l.add(ImageTypeSpecifier.createGrayscale(8, DataBuffer.TYPE_BYTE, false));
} else {
throw new UnsupportedOperationException("Support for pixels of size " + nbpp + " bytes has not been implemented yet");
}
} catch (NITFException e) {
LOGGER.severe(e.getLocalizedMessage());
}
return l.iterator();
}
Aggregations