use of loci.formats.UnsupportedCompressionException in project bioformats by openmicroscopy.
the class APNGReader method decode.
private byte[] decode(PNGInputStream bytes, int width, int height) throws FormatException, IOException {
int bpp = FormatTools.getBytesPerPixel(getPixelType());
int rowLen = width * getRGBChannelCount() * bpp;
if (getBitsPerPixel() < bpp * 8) {
int div = (bpp * 8) / getBitsPerPixel();
if (div < rowLen) {
int originalRowLen = rowLen;
rowLen /= div;
if (rowLen * div < originalRowLen) {
rowLen++;
}
} else {
rowLen = 1;
}
}
byte[] image = null;
if (compression == 0 && interlace == 0) {
// decompress the image
byte[] filters = new byte[height];
image = new byte[rowLen * height];
InflaterInputStream decompressor = new InflaterInputStream(bytes);
try {
int n = 0;
for (int row = 0; row < height; row++) {
n = 0;
while (n < 1) {
n = decompressor.read(filters, row, 1);
}
n = 0;
while (n < rowLen) {
n += decompressor.read(image, row * rowLen + n, rowLen - n);
}
}
} finally {
decompressor.close();
decompressor = null;
}
// perform any necessary unfiltering
unfilter(filters, image, width, height);
} else if (compression == 0) {
// see: http://www.w3.org/TR/PNG/#8Interlace
int byteCount = 0;
byte[][] passImages = new byte[7][];
int nRowBlocks = getSizeY() / 8;
int nColBlocks = getSizeX() / 8;
if (8 * nRowBlocks != getSizeY()) {
nRowBlocks++;
}
if (8 * nColBlocks != getSizeX()) {
nColBlocks++;
}
if (nRowBlocks <= 0) {
nRowBlocks = 1;
}
if (nColBlocks <= 0) {
nColBlocks = 1;
}
image = new byte[FormatTools.getPlaneSize(this)];
InflaterInputStream decompressor = new InflaterInputStream(bytes);
try {
for (int i = 0; i < passImages.length; i++) {
int passWidth = PASS_WIDTHS[i] * nColBlocks;
int passHeight = PASS_HEIGHTS[i] * nRowBlocks;
if (nColBlocks * 8 != width) {
int extraCols = getSizeX() - (nColBlocks - 1) * 8;
switch(extraCols) {
case 1:
if (i == 1 || i == 3 || i == 5) {
passWidth -= PASS_WIDTHS[i];
}
if (i == 2 || i == 4 || i == 6) {
passWidth -= (PASS_WIDTHS[i] - 1);
}
break;
case 2:
if (i == 1 || i == 3) {
passWidth -= PASS_WIDTHS[i];
}
if (i == 2 || i == 4 || i == 5) {
passWidth -= (PASS_WIDTHS[i] - 1);
}
if (i == 6) {
passWidth -= (PASS_WIDTHS[i] - 2);
}
break;
case 3:
if (i == 1) {
passWidth -= PASS_WIDTHS[i];
}
if (i == 2 || i == 3 || i == 5) {
passWidth -= (PASS_WIDTHS[i] - 1);
}
if (i == 4) {
passWidth -= (PASS_WIDTHS[i] - 2);
}
if (i == 6) {
passWidth -= (PASS_WIDTHS[i] - 3);
}
break;
case 4:
if (i == 1) {
passWidth -= PASS_WIDTHS[i];
}
if (i == 2 || i == 3) {
passWidth -= (PASS_WIDTHS[i] - 1);
}
if (i == 4 || i == 5) {
passWidth -= (PASS_WIDTHS[i] - 2);
}
if (i == 6) {
passWidth -= (PASS_WIDTHS[i] - 4);
}
break;
case 5:
if (i == 3) {
passWidth -= (PASS_WIDTHS[i] - 1);
}
if (i == 5) {
passWidth -= (PASS_WIDTHS[i] - 2);
}
if (i == 4) {
passWidth -= (PASS_WIDTHS[i] - 3);
}
if (i == 6) {
passWidth -= (PASS_WIDTHS[i] - 5);
}
break;
case 6:
if (i == 3) {
passWidth -= (PASS_WIDTHS[i] - 1);
}
if (i == 4 || i == 5) {
passWidth -= (PASS_WIDTHS[i] - 3);
}
if (i == 6) {
passWidth -= (PASS_WIDTHS[i] - 6);
}
break;
case 7:
if (i == 5 || i == 6) {
passWidth--;
}
break;
}
}
int rowSize = passWidth * bpp * getRGBChannelCount();
byte[] filters = new byte[passHeight];
passImages[i] = new byte[rowSize * passHeight];
for (int row = 0; row < passHeight; row++) {
if (passWidth == 0) {
continue;
}
if (nRowBlocks * 8 != getSizeY() && row >= PASS_HEIGHTS[i] * (nRowBlocks - 1)) {
int extraRows = getSizeY() - (nRowBlocks - 1) * 8;
switch(extraRows) {
case 1:
if (i == 2 || i == 4 || i == 6) {
continue;
}
if ((i == 3 || i == 5) && (row % PASS_HEIGHTS[i]) > 0) {
continue;
}
break;
case 2:
if (i == 4 || i == 2) {
continue;
}
if ((i == 3 || i == 5 || i == 6) && (row % PASS_HEIGHTS[i]) > 0) {
continue;
}
break;
case 3:
if (i == 2) {
continue;
}
if ((i == 3 || i == 4 || i == 6) && (row % PASS_HEIGHTS[i]) > 0) {
continue;
}
if (i == 5 && (row % PASS_HEIGHTS[i] > 1)) {
continue;
}
break;
case 4:
if (i == 2) {
continue;
}
if ((i == 3 || i == 4) && (row % PASS_HEIGHTS[i]) > 0) {
continue;
}
if ((i == 5 || i == 6) && (row % PASS_HEIGHTS[i]) > 1) {
continue;
}
break;
case 5:
if ((i == 4) && (row % PASS_HEIGHTS[i]) > 0) {
continue;
}
if ((i == 6) && (row % PASS_HEIGHTS[i]) > 1) {
continue;
}
if ((i == 5) && (row % PASS_HEIGHTS[i]) > 2) {
continue;
}
break;
case 6:
if ((i == 4) && (row % PASS_HEIGHTS[i]) > 0) {
continue;
}
if ((i == 5 || i == 6) && (row % PASS_HEIGHTS[i]) > 2) {
continue;
}
break;
case 7:
if (i == 6 && (row % PASS_HEIGHTS[i]) > 2) {
continue;
}
break;
}
}
int n = 0;
while (n < 1) {
n = decompressor.read(filters, row, 1);
}
n = 0;
while (n < rowSize) {
n += decompressor.read(passImages[i], row * rowSize + n, rowSize - n);
}
}
unfilter(filters, passImages[i], passWidth, passHeight);
}
} finally {
decompressor.close();
decompressor = null;
}
int chunk = bpp * getRGBChannelCount();
int[] passOffset = new int[7];
for (int row = 0; row < 8 * (height / 8); row++) {
int rowOffset = row * width * chunk;
for (int col = 0; col < width; col++) {
int blockRow = row % 8;
int blockCol = col % 8;
int pass = -1;
if ((blockRow % 2) == 1) {
pass = 6;
} else if (blockRow == 0 || blockRow == 4) {
if ((blockCol % 2) == 1) {
pass = 5;
} else if (blockCol == 0) {
pass = blockRow == 0 ? 0 : 2;
} else if (blockCol == 4) {
pass = blockRow == 0 ? 1 : 2;
} else {
pass = 3;
}
} else {
pass = 4 + (blockCol % 2);
}
int colOffset = col * chunk;
for (int c = 0; c < chunk; c++) {
if (passOffset[pass] < passImages[pass].length) {
image[rowOffset + colOffset + c] = passImages[pass][passOffset[pass]++];
}
}
}
}
} else {
throw new UnsupportedCompressionException("Compression type " + compression + " not supported");
}
if (getBitsPerPixel() < 8) {
byte[] expandedImage = new byte[FormatTools.getPlaneSize(this)];
RandomAccessInputStream bits = new RandomAccessInputStream(image);
int skipBits = rowLen * 8 - getSizeX() * getBitsPerPixel();
for (int row = 0; row < getSizeY(); row++) {
for (int col = 0; col < getSizeX(); col++) {
int index = row * getSizeX() + col;
expandedImage[index] = (byte) (bits.readBits(getBitsPerPixel()) & 0xff);
}
bits.skipBits(skipBits);
}
bits.close();
bits = null;
image = expandedImage;
}
return image;
}
use of loci.formats.UnsupportedCompressionException in project bioformats by openmicroscopy.
the class CellomicsReader method initFile.
// -- Internal FormatReader API methods --
/* @see loci.formats.FormatReader#initFile(String) */
@Override
protected void initFile(String id) throws FormatException, IOException {
super.initFile(id);
// look for files with similar names
Location baseFile = new Location(id).getAbsoluteFile();
Location parent = baseFile.getParentFile();
ArrayList<String> pixelFiles = new ArrayList<String>();
String plateName = getPlateName(baseFile.getName());
if (plateName != null && isGroupFiles()) {
String[] list = parent.list();
for (String f : list) {
if (plateName.equals(getPlateName(f)) && (checkSuffix(f, "c01") || checkSuffix(f, "dib"))) {
Location loc = new Location(parent, f);
if ((!f.startsWith(".") || !loc.isHidden()) && getChannel(f) >= 0) {
pixelFiles.add(loc.getAbsolutePath());
}
}
}
} else
pixelFiles.add(id);
files = pixelFiles.toArray(new String[pixelFiles.size()]);
int wellRows = 0;
int wellColumns = 0;
int fields = 0;
ArrayList<Integer> uniqueRows = new ArrayList<Integer>();
ArrayList<Integer> uniqueCols = new ArrayList<Integer>();
ArrayList<Integer> uniqueFields = new ArrayList<Integer>();
ArrayList<Integer> uniqueChannels = new ArrayList<Integer>();
for (String f : files) {
int wellRow = getWellRow(f);
int wellCol = getWellColumn(f);
int field = getField(f);
int channel = getChannel(f);
if (!uniqueRows.contains(wellRow))
uniqueRows.add(wellRow);
if (!uniqueCols.contains(wellCol))
uniqueCols.add(wellCol);
if (!uniqueFields.contains(field))
uniqueFields.add(field);
if (!uniqueChannels.contains(channel))
uniqueChannels.add(channel);
}
fields = uniqueFields.size();
wellRows = uniqueRows.size();
wellColumns = uniqueCols.size();
if (fields * wellRows * wellColumns > files.length) {
files = new String[] { id };
}
Arrays.sort(files, new Comparator<String>() {
@Override
public int compare(String f1, String f2) {
int wellRow1 = getWellRow(f1);
int wellCol1 = getWellColumn(f1);
int field1 = getField(f1);
int channel1 = getChannel(f1);
int wellRow2 = getWellRow(f2);
int wellCol2 = getWellColumn(f2);
int field2 = getField(f2);
int channel2 = getChannel(f2);
if (wellRow1 < wellRow2) {
return -1;
} else if (wellRow1 > wellRow2) {
return 1;
}
if (wellCol1 < wellCol2) {
return -1;
} else if (wellCol1 > wellCol2) {
return 1;
}
if (field1 < field2) {
return -1;
} else if (field1 > field2) {
return 1;
}
return channel1 - channel2;
}
});
core.clear();
int seriesCount = files.length;
if (uniqueChannels.size() > 0) {
seriesCount /= uniqueChannels.size();
}
for (int i = 0; i < seriesCount; i++) {
core.add(new CoreMetadata());
}
in = getDecompressedStream(id);
LOGGER.info("Reading header data");
in.order(true);
in.skipBytes(4);
int x = in.readInt();
int y = in.readInt();
int nPlanes = in.readShort();
int nBits = in.readShort();
int compression = in.readInt();
if (x * y * nPlanes * (nBits / 8) + 52 > in.length()) {
throw new UnsupportedCompressionException("Compressed pixel data is not yet supported.");
}
in.skipBytes(4);
int pixelWidth = 0, pixelHeight = 0;
if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
pixelWidth = in.readInt();
pixelHeight = in.readInt();
int colorUsed = in.readInt();
int colorImportant = in.readInt();
LOGGER.info("Populating metadata hashtable");
addGlobalMeta("Image width", x);
addGlobalMeta("Image height", y);
addGlobalMeta("Number of planes", nPlanes);
addGlobalMeta("Bits per pixel", nBits);
addGlobalMeta("Compression", compression);
addGlobalMeta("Pixels per meter (X)", pixelWidth);
addGlobalMeta("Pixels per meter (Y)", pixelHeight);
addGlobalMeta("Color used", colorUsed);
addGlobalMeta("Color important", colorImportant);
}
LOGGER.info("Populating core metadata");
for (int i = 0; i < getSeriesCount(); i++) {
CoreMetadata ms = core.get(i);
ms.sizeX = x;
ms.sizeY = y;
ms.sizeZ = nPlanes;
ms.sizeT = 1;
ms.sizeC = uniqueChannels.size();
ms.imageCount = getSizeZ() * getSizeT() * getSizeC();
ms.littleEndian = true;
ms.dimensionOrder = "XYCZT";
ms.pixelType = FormatTools.pixelTypeFromBytes(nBits / 8, false, false);
}
LOGGER.info("Populating metadata store");
MetadataStore store = makeFilterMetadata();
MetadataTools.populatePixels(store, this);
store.setPlateID(MetadataTools.createLSID("Plate", 0), 0);
store.setPlateName(plateName, 0);
store.setPlateRowNamingConvention(NamingConvention.LETTER, 0);
store.setPlateColumnNamingConvention(NamingConvention.NUMBER, 0);
int realRows = wellRows;
int realCols = wellColumns;
if (files.length == 1) {
realRows = 1;
realCols = 1;
} else if (realRows <= 8 && realCols <= 12) {
realRows = 8;
realCols = 12;
} else {
realRows = 16;
realCols = 24;
}
int fieldCntr = 0;
int wellCntr = 0;
int wellIndexPrev = 0;
int wellIndex = 0;
for (int i = 0; i < getSeriesCount(); i++) {
String file = files[i * getSizeC()];
int fieldIndex = getField(file);
int row = getWellRow(file);
int col = getWellColumn(file);
store.setImageName(String.format("Well %s%02d, Field #%02d", new String(Character.toChars(row + 'A')), col, fieldIndex), i);
if (files.length == 1) {
row = 0;
col = 0;
}
if (i > 0 && files.length != 1) {
String prevFile = files[(i - 1) * getSizeC()];
int prevRow = getWellRow(prevFile);
int prevCol = getWellColumn(prevFile);
if (prevRow < realRows && prevCol < realCols) {
wellIndexPrev = prevRow * realCols + prevCol;
}
}
String imageID = MetadataTools.createLSID("Image", i);
store.setImageID(imageID, i);
if (row < realRows && col < realCols) {
wellIndex = row * realCols + col;
if ((wellIndexPrev != wellIndex) || i == 0) {
if (i > 0) {
wellCntr++;
fieldCntr = 0;
} else {
wellIndexPrev = wellIndex;
}
store.setWellID(MetadataTools.createLSID("Well", 0, wellIndex), 0, wellCntr);
store.setWellRow(new NonNegativeInteger(row), 0, wellCntr);
store.setWellColumn(new NonNegativeInteger(col), 0, wellCntr);
}
if (files.length == 1) {
fieldIndex = 0;
}
if (fieldIndex == 0) {
fieldCntr = 0;
}
String wellSampleID = MetadataTools.createLSID("WellSample", 0, wellIndex, fieldIndex);
store.setWellSampleID(wellSampleID, 0, wellCntr, fieldCntr);
store.setWellSampleIndex(new NonNegativeInteger(i), 0, wellCntr, fieldCntr);
store.setWellSampleImageRef(imageID, 0, wellCntr, fieldCntr);
fieldCntr++;
}
}
if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
// physical dimensions are stored as pixels per meter - we want them
// in microns per pixel
double width = pixelWidth == 0 ? 0.0 : 1000000.0 / pixelWidth;
double height = pixelHeight == 0 ? 0.0 : 1000000.0 / pixelHeight;
Length sizeX = FormatTools.getPhysicalSizeX(width);
Length sizeY = FormatTools.getPhysicalSizeY(height);
for (int i = 0; i < getSeriesCount(); i++) {
if (sizeX != null) {
store.setPixelsPhysicalSizeX(sizeX, 0);
}
if (sizeY != null) {
store.setPixelsPhysicalSizeY(sizeY, 0);
}
}
}
}
use of loci.formats.UnsupportedCompressionException in project bioformats by openmicroscopy.
the class AVIReader method uncompress.
// -- Helper methods --
private byte[] uncompress(int no, byte[] buf) throws FormatException, IOException {
if (lastImageNo == no) {
buf = lastImage;
return buf;
}
CodecOptions options = new CodecOptions();
options.width = getSizeX();
options.height = getSizeY();
options.previousImage = (lastImageNo == no - 1) ? lastImage : null;
if (options.previousImage == null && bmpCompression != JPEG) {
while (lastImageNo < no - 1) {
openBytes(lastImageNo + 1, buf);
}
options.previousImage = lastImage;
}
long fileOff = offsets.get(no).longValue();
in.seek(fileOff);
options.bitsPerSample = bmpBitsPerPixel;
options.interleaved = isInterleaved();
options.littleEndian = isLittleEndian();
if (bmpCompression == MSRLE) {
byte[] b = new byte[(int) lengths.get(no).longValue()];
in.read(b);
MSRLECodec codec = new MSRLECodec();
buf = codec.decompress(b, options);
} else if (bmpCompression == MS_VIDEO) {
MSVideoCodec codec = new MSVideoCodec();
buf = codec.decompress(in, options);
} else if (bmpCompression == JPEG) {
JPEGCodec codec = new JPEGCodec();
byte[] plane = new byte[(int) lengths.get(no).longValue()];
in.read(plane);
boolean motionJPEG = plane.length >= 10 && new String(plane, 6, 4, Constants.ENCODING).equals("AVI1");
if (motionJPEG) {
// this is Motion JPEG data
// we must manually insert the Huffman table, as Motion JPEG
// uses a fixed (but not stored) Huffman table for all planes
byte[] fixedPlane = new byte[plane.length + MJPEG_HUFFMAN_TABLE.length];
System.arraycopy(plane, 0, fixedPlane, 0, 20);
System.arraycopy(MJPEG_HUFFMAN_TABLE, 0, fixedPlane, 20, MJPEG_HUFFMAN_TABLE.length);
System.arraycopy(plane, 20, fixedPlane, 20 + MJPEG_HUFFMAN_TABLE.length, plane.length - 20);
plane = fixedPlane;
}
if (plane.length > 0) {
buf = codec.decompress(plane, options);
} else {
buf = lastImage;
}
if (!lengths.contains(0L)) {
motionJPEG = false;
}
if (motionJPEG) {
for (int i = 0; i < buf.length; i += 3) {
int y = buf[i] & 0xff;
int cb = (buf[i + 1] & 0xff) - 128;
int cr = (buf[i + 2] & 0xff) - 128;
int red = (int) (y + 1.402 * cr);
int green = (int) (y - 0.34414 * cb - 0.71414 * cr);
int blue = (int) (y + 1.772 * cb);
if (red < 0) {
red = 0;
} else if (red > 255) {
red = 255;
}
if (green < 0) {
green = 0;
} else if (green > 255) {
green = 255;
}
if (blue < 0) {
blue = 0;
} else if (blue > 255) {
blue = 255;
}
buf[i] = (byte) (red & 0xff);
buf[i + 1] = (byte) (green & 0xff);
buf[i + 2] = (byte) (blue & 0xff);
}
}
} else /*
else if (bmpCompression == CINEPAK) {
Object[] options = new Object[2];
options[0] = new Integer(bmpBitsPerPixel);
options[1] = lastImage;
CinepakCodec codec = new CinepakCodec();
buf = codec.decompress(b, options);
lastImage = buf;
if (no == m.imageCount - 1) lastImage = null;
return buf;
}
*/
{
throw new UnsupportedCompressionException(bmpCompression + " not supported");
}
lastImage = buf;
lastImageNo = no;
return buf;
}
use of loci.formats.UnsupportedCompressionException in project bioformats by openmicroscopy.
the class BMPReader method openBytes.
/**
* @see loci.formats.IFormatReader#openBytes(int, byte[], int, int, int, int)
*/
@Override
public byte[] openBytes(int no, byte[] buf, int x, int y, int w, int h) throws FormatException, IOException {
FormatTools.checkPlaneParameters(this, no, buf.length, x, y, w, h);
if (compression != RAW && in.length() < FormatTools.getPlaneSize(this)) {
throw new UnsupportedCompressionException(compression + " not supported");
}
int rowsToSkip = invertY ? y : getSizeY() - (h + y);
int rowLength = (getSizeX() * (isIndexed() ? 1 : getSizeC()) * bpp) / 8;
in.seek(global + rowsToSkip * rowLength);
int pad = ((rowLength * bpp) / 8) % 2;
if (pad == 0)
pad = ((rowLength * bpp) / 8) % 4;
else
pad *= getSizeC();
int planeSize = getSizeX() * getSizeC() * h;
if (bpp >= 8)
planeSize *= (bpp / 8);
else
planeSize /= (8 / bpp);
planeSize += pad * h;
if (planeSize + in.getFilePointer() + rowsToSkip * pad > in.length()) {
planeSize -= (pad * h);
// sometimes we have RGB images with a single padding byte
if (planeSize + getSizeY() + in.getFilePointer() <= in.length()) {
pad = 1;
planeSize += h;
} else {
pad = 0;
}
}
in.skipBytes(rowsToSkip * pad);
int effectiveC = palette != null && palette[0].length > 0 ? 1 : getSizeC();
if (compression == RAW) {
for (int row = h - 1; row >= 0; row--) {
int rowIndex = invertY ? h - 1 - row : row;
in.skipBits(x * bpp * effectiveC);
for (int i = 0; i < w * effectiveC; i++) {
if (bpp <= 8) {
buf[rowIndex * w * effectiveC + i] = (byte) (in.readBits(bpp) & 0xff);
} else {
for (int b = 0; b < bpp / 8; b++) {
buf[(bpp / 8) * (rowIndex * w * effectiveC + i) + b] = (byte) (in.readBits(8) & 0xff);
}
}
}
if (row > 0) {
int nBits = (getSizeX() - w - x) * bpp * effectiveC + pad * 8;
if (in.getFilePointer() + (nBits / 8) < in.length()) {
in.skipBits(nBits);
} else {
break;
}
}
}
} else if (compression == RLE_8 || compression == RLE_4) {
boolean endOfFile = false;
int index = 0;
byte[] plane = new byte[getSizeX() * getSizeY() * getRGBChannelCount()];
while (!endOfFile) {
byte firstByte = (byte) (in.readBits(bpp) & 0xff);
byte secondByte = (byte) (in.readBits(bpp) & 0xff);
if (firstByte == 0) {
if (secondByte == 1) {
endOfFile = true;
} else if (secondByte == 2) {
byte xDelta = (byte) (in.readBits(bpp) & 0xff);
byte yDelta = (byte) (in.readBits(bpp) & 0xff);
index += (yDelta * rowLength) + xDelta;
} else if (secondByte > 2) {
// Absolute mode
if (compression == RLE_8) {
for (int i = 0; i < secondByte; i++) {
byte absoluteByte = (byte) (in.readBits(bpp) & 0xff);
plane[index] = absoluteByte;
index++;
}
// In absolute mode, each run must be aligned on a word boundary
if (secondByte % 2 == 1)
in.skipBytes(1);
} else if (compression == RLE_4) {
for (int i = 0; i < secondByte; i += 2) {
byte absoluteByte = (byte) (in.readBits(bpp) & 0xff);
byte firstNibble = (byte) (absoluteByte & 0xf);
byte secondNibble = (byte) ((byte) (absoluteByte >> 4) & 0xf);
plane[index] = firstNibble;
index++;
if (i + 1 < secondByte) {
plane[index] = secondNibble;
index++;
}
}
// In absolute mode, each run must be aligned on a word boundary
if (secondByte % 4 == 2)
in.skipBytes(1);
}
}
} else {
if (compression == RLE_8) {
for (int i = 0; i < firstByte; i++) {
plane[index] = secondByte;
index++;
}
} else if (compression == RLE_4) {
byte firstNibble = (byte) (secondByte & 0xf);
byte secondNibble = (byte) ((byte) (secondByte >> 4) & 0xf);
for (int i = 0; i < firstByte; i++) {
if (i % 2 == 0) {
plane[index] = firstNibble;
} else {
plane[index] = secondNibble;
}
index++;
}
}
}
}
RandomAccessInputStream s = new RandomAccessInputStream(plane);
readPlane(s, x, y, w, h, buf);
s.close();
}
if (getRGBChannelCount() > 1) {
ImageTools.bgrToRgb(buf, isInterleaved(), 1, getRGBChannelCount());
}
return buf;
}
use of loci.formats.UnsupportedCompressionException in project bioformats by openmicroscopy.
the class DicomReader method openBytes.
/**
* @see loci.formats.IFormatReader#openBytes(int, byte[], int, int, int, int)
*/
@Override
public byte[] openBytes(int no, byte[] buf, int x, int y, int w, int h) throws FormatException, IOException {
FormatTools.checkPlaneParameters(this, no, buf.length, x, y, w, h);
Integer[] keys = fileList.keySet().toArray(new Integer[0]);
Arrays.sort(keys);
if (fileList.size() > 1) {
int fileNumber = 0;
if (fileList.get(keys[getSeries()]).size() > 1) {
fileNumber = no / imagesPerFile;
no = no % imagesPerFile;
}
String file = fileList.get(keys[getSeries()]).get(fileNumber);
helper.setId(file);
return helper.openBytes(no, buf, x, y, w, h);
}
int ec = isIndexed() ? 1 : getSizeC();
int bpp = FormatTools.getBytesPerPixel(getPixelType());
int bytes = getSizeX() * getSizeY() * bpp * ec;
in.seek(offsets[no]);
if (isRLE) {
// plane is compressed using run-length encoding
CodecOptions options = new CodecOptions();
options.maxBytes = getSizeX() * getSizeY();
for (int c = 0; c < ec; c++) {
PackbitsCodec codec = new PackbitsCodec();
byte[] t = null;
if (bpp > 1) {
int plane = bytes / (bpp * ec);
byte[][] tmp = new byte[bpp][];
long start = in.getFilePointer();
for (int i = 0; i < bpp; i++) {
// one or more extra 0 bytes can be inserted between
// the planes, but there isn't a good way to know in advance
// only way to know is to see if decompressing produces the
// correct number of bytes
tmp[i] = codec.decompress(in, options);
if (i > 0 && tmp[i].length > options.maxBytes) {
in.seek(start);
tmp[i] = codec.decompress(in, options);
}
if (no < imagesPerFile - 1 || i < bpp - 1) {
start = in.getFilePointer();
while (in.read() == 0) ;
long end = in.getFilePointer();
in.seek(end - 1);
}
}
t = new byte[bytes / ec];
for (int i = 0; i < plane; i++) {
for (int j = 0; j < bpp; j++) {
int byteIndex = isLittleEndian() ? bpp - j - 1 : j;
if (i < tmp[byteIndex].length) {
t[i * bpp + j] = tmp[byteIndex][i];
}
}
}
} else {
t = codec.decompress(in, options);
if (t.length < (bytes / ec)) {
byte[] tmp = t;
t = new byte[bytes / ec];
System.arraycopy(tmp, 0, t, 0, tmp.length);
}
if (no < imagesPerFile - 1 || c < ec - 1) {
while (in.read() == 0) ;
in.seek(in.getFilePointer() - 1);
}
}
int rowLen = w * bpp;
int srcRowLen = getSizeX() * bpp;
for (int row = 0; row < h; row++) {
int src = (row + y) * srcRowLen + x * bpp;
int dest = (h * c + row) * rowLen;
int len = (int) Math.min(rowLen, t.length - src - 1);
if (len < 0)
break;
System.arraycopy(t, src, buf, dest, len);
}
}
} else if (isJPEG || isJP2K) {
// plane is compressed using JPEG or JPEG-2000
long end = no < offsets.length - 1 ? offsets[no + 1] : in.length();
byte[] b = new byte[(int) (end - in.getFilePointer())];
in.read(b);
if (b[2] != (byte) 0xff) {
byte[] tmp = new byte[b.length + 1];
tmp[0] = b[0];
tmp[1] = b[1];
tmp[2] = (byte) 0xff;
System.arraycopy(b, 2, tmp, 3, b.length - 2);
b = tmp;
}
if ((b[3] & 0xff) >= 0xf0) {
b[3] -= (byte) 0x30;
}
int pt = b.length - 2;
while (pt >= 0 && b[pt] != (byte) 0xff || b[pt + 1] != (byte) 0xd9) {
pt--;
}
if (pt < b.length - 2) {
byte[] tmp = b;
b = new byte[pt + 2];
System.arraycopy(tmp, 0, b, 0, b.length);
}
Codec codec = null;
CodecOptions options = new CodecOptions();
options.littleEndian = isLittleEndian();
options.interleaved = isInterleaved();
if (isJPEG)
codec = new JPEGCodec();
else
codec = new JPEG2000Codec();
b = codec.decompress(b, options);
int rowLen = w * bpp;
int srcRowLen = getSizeX() * bpp;
int srcPlane = getSizeY() * srcRowLen;
for (int c = 0; c < ec; c++) {
for (int row = 0; row < h; row++) {
System.arraycopy(b, c * srcPlane + (row + y) * srcRowLen + x * bpp, buf, h * rowLen * c + row * rowLen, rowLen);
}
}
} else if (isDeflate) {
// TODO
throw new UnsupportedCompressionException("Deflate data is not supported.");
} else {
// plane is not compressed
readPlane(in, x, y, w, h, buf);
}
if (inverted) {
// white -> 255 (or 65535)
if (bpp == 1) {
for (int i = 0; i < buf.length; i++) {
buf[i] = (byte) (255 - buf[i]);
}
} else if (bpp == 2) {
long maxPixelValue = maxPixelRange + (centerPixelValue / 2);
if (maxPixelRange == -1 || centerPixelValue < (maxPixelRange / 2)) {
maxPixelValue = FormatTools.defaultMinMax(getPixelType())[1];
}
boolean little = isLittleEndian();
for (int i = 0; i < buf.length; i += 2) {
short s = DataTools.bytesToShort(buf, i, 2, little);
DataTools.unpackBytes(maxPixelValue - s, buf, i, 2, little);
}
}
}
return buf;
}
Aggregations