use of loci.formats.codec.JPEGCodec 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.codec.JPEGCodec 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;
}
use of loci.formats.codec.JPEGCodec in project bioformats by openmicroscopy.
the class OMEXMLReader 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 {
if (binDataOffsets.size() == 0)
return buf;
FormatTools.checkPlaneParameters(this, no, buf.length, x, y, w, h);
int index = no;
int series = getSeries();
for (int i = 0; i < series; i++) {
index += core.get(i).imageCount;
}
if (index >= binDataOffsets.size()) {
index = binDataOffsets.size() - 1;
}
long offset = binDataOffsets.get(index).longValue();
String compress = compression.get(index);
in.seek(offset);
int depth = FormatTools.getBytesPerPixel(getPixelType());
int planeSize = getSizeX() * getSizeY() * depth;
CodecOptions options = new CodecOptions();
options.width = getSizeX();
options.height = getSizeY();
options.bitsPerSample = depth * 8;
options.channels = getRGBChannelCount();
options.maxBytes = planeSize;
options.littleEndian = isLittleEndian();
options.interleaved = isInterleaved();
String encoded = in.readString("<");
encoded = encoded.trim();
if (encoded.length() == 0 || encoded.equals("<")) {
LOGGER.debug("No pixel data for plane #{}", no);
return buf;
}
encoded = encoded.substring(0, encoded.length() - 1);
byte[] pixels = BaseEncoding.base64().decode(encoded);
// return a blank plane if no pixel data was stored
if (pixels.length == 0) {
LOGGER.debug("No pixel data for plane #{}", no);
return buf;
}
// TODO: Create a method uncompress to handle all compression methods
if (compress.equals("bzip2")) {
byte[] tempPixels = pixels;
pixels = new byte[tempPixels.length - 2];
System.arraycopy(tempPixels, 2, pixels, 0, pixels.length);
ByteArrayInputStream bais = new ByteArrayInputStream(pixels);
CBZip2InputStream bzip = new CBZip2InputStream(bais);
pixels = new byte[planeSize];
bzip.read(pixels, 0, pixels.length);
tempPixels = null;
bais.close();
bzip.close();
bais = null;
bzip = null;
} else if (compress.equals("zlib")) {
pixels = new ZlibCodec().decompress(pixels, options);
} else if (compress.equals("J2K")) {
pixels = new JPEG2000Codec().decompress(pixels, options);
} else if (compress.equals("JPEG")) {
pixels = new JPEGCodec().decompress(pixels, options);
}
for (int row = 0; row < h; row++) {
int off = (row + y) * getSizeX() * depth + x * depth;
System.arraycopy(pixels, off, buf, row * w * depth, w * depth);
}
pixels = null;
return buf;
}
Aggregations