short[] readCompressed16bitImage(InputStream in) throws IOException { if (IJ.debugMode) IJ.log("ImageReader.read16bit, offset=" + fi.stripOffsets[0]); short[] pixels = new short[nPixels]; int base = 0; short last = 0; for (int k = 0; k < fi.stripOffsets.length; k++) { // IJ.log("seek: "+fi.stripOffsets[k]+" "+fi.stripLengths[k]+" "+(in instanceof // RandomAccessStream)); if (in instanceof RandomAccessStream) ((RandomAccessStream) in).seek(fi.stripOffsets[k]); else if (k > 0) { long skip = (fi.stripOffsets[k] & 0xffffffffL) - (fi.stripOffsets[k - 1] & 0xffffffffL) - fi.stripLengths[k - 1]; if (skip > 0L) in.skip(skip); } byte[] byteArray = new byte[fi.stripLengths[k]]; int read = 0, left = byteArray.length; while (left > 0) { int r = in.read(byteArray, read, left); if (r == -1) { eofError(); break; } read += r; left -= r; } byteArray = uncompress(byteArray); int pixelsRead = byteArray.length / bytesPerPixel; pixelsRead = pixelsRead - (pixelsRead % fi.width); int pmax = base + pixelsRead; if (pmax > nPixels) pmax = nPixels; if (fi.intelByteOrder) { for (int i = base, j = 0; i < pmax; i++, j += 2) pixels[i] = (short) (((byteArray[j + 1] & 0xff) << 8) | (byteArray[j] & 0xff)); } else { for (int i = base, j = 0; i < pmax; i++, j += 2) pixels[i] = (short) (((byteArray[j] & 0xff) << 8) | (byteArray[j + 1] & 0xff)); } if (fi.compression == FileInfo.LZW_WITH_DIFFERENCING) { for (int b = base; b < pmax; b++) { pixels[b] += last; last = b % fi.width == fi.width - 1 ? 0 : pixels[b]; } } base += pixelsRead; showProgress(k + 1, fi.stripOffsets.length); } if (fi.fileType == FileInfo.GRAY16_SIGNED) { // convert to unsigned for (int i = 0; i < nPixels; i++) pixels[i] = (short) (pixels[i] + 32768); } return pixels; }
byte[] readCompressed8bitImage(InputStream in) throws IOException { byte[] pixels = new byte[nPixels]; int current = 0; byte last = 0; for (int i = 0; i < fi.stripOffsets.length; i++) { if (in instanceof RandomAccessStream) ((RandomAccessStream) in).seek(fi.stripOffsets[i]); else if (i > 0) { long skip = (fi.stripOffsets[i] & 0xffffffffL) - (fi.stripOffsets[i - 1] & 0xffffffffL) - fi.stripLengths[i - 1]; if (skip > 0L) in.skip(skip); } byte[] byteArray = new byte[fi.stripLengths[i]]; int read = 0, left = byteArray.length; while (left > 0) { int r = in.read(byteArray, read, left); if (r == -1) { eofError(); break; } read += r; left -= r; } byteArray = uncompress(byteArray); int length = byteArray.length; length = length - (length % fi.width); if (fi.compression == FileInfo.LZW_WITH_DIFFERENCING) { for (int b = 0; b < length; b++) { byteArray[b] += last; last = b % fi.width == fi.width - 1 ? 0 : byteArray[b]; } } if (current + length > pixels.length) length = pixels.length - current; System.arraycopy(byteArray, 0, pixels, current, length); current += length; showProgress(i + 1, fi.stripOffsets.length); } return pixels; }
int[] readCompressedChunkyRGB(InputStream in) throws IOException { int[] pixels = new int[nPixels]; int base = 0; int lastRed = 0, lastGreen = 0, lastBlue = 0; int nextByte; int red = 0, green = 0, blue = 0, alpha = 0; boolean bgr = fi.fileType == FileInfo.BGR; boolean cmyk = fi.fileType == FileInfo.CMYK; boolean differencing = fi.compression == FileInfo.LZW_WITH_DIFFERENCING; for (int i = 0; i < fi.stripOffsets.length; i++) { if (in instanceof RandomAccessStream) ((RandomAccessStream) in).seek(fi.stripOffsets[i]); else if (i > 0) { long skip = (fi.stripOffsets[i] & 0xffffffffL) - (fi.stripOffsets[i - 1] & 0xffffffffL) - fi.stripLengths[i - 1]; if (skip > 0L) in.skip(skip); } byte[] byteArray = new byte[fi.stripLengths[i]]; int read = 0, left = byteArray.length; while (left > 0) { int r = in.read(byteArray, read, left); if (r == -1) { eofError(); break; } read += r; left -= r; } byteArray = uncompress(byteArray); if (differencing) { for (int b = 0; b < byteArray.length; b++) { if (b / bytesPerPixel % fi.width == 0) continue; byteArray[b] += byteArray[b - bytesPerPixel]; } } int k = 0; int pixelsRead = byteArray.length / bytesPerPixel; pixelsRead = pixelsRead - (pixelsRead % fi.width); int pmax = base + pixelsRead; if (pmax > nPixels) pmax = nPixels; for (int j = base; j < pmax; j++) { if (bytesPerPixel == 4) { red = byteArray[k++] & 0xff; green = byteArray[k++] & 0xff; blue = byteArray[k++] & 0xff; alpha = byteArray[k++] & 0xff; if (cmyk && alpha > 0) { red = ((red * (256 - alpha)) >> 8) + alpha; green = ((green * (256 - alpha)) >> 8) + alpha; blue = ((blue * (256 - alpha)) >> 8) + alpha; } } else { red = byteArray[k++] & 0xff; green = byteArray[k++] & 0xff; blue = byteArray[k++] & 0xff; } if (bgr) pixels[j] = 0xff000000 | (blue << 16) | (green << 8) | red; else pixels[j] = 0xff000000 | (red << 16) | (green << 8) | blue; } base += pixelsRead; showProgress(i + 1, fi.stripOffsets.length); } return pixels; }
float[] readCompressed32bitImage(InputStream in) throws IOException { float[] pixels = new float[nPixels]; int base = 0; float last = 0; for (int k = 0; k < fi.stripOffsets.length; k++) { // IJ.log("seek: "+fi.stripOffsets[k]+" "+(in instanceof RandomAccessStream)); if (in instanceof RandomAccessStream) ((RandomAccessStream) in).seek(fi.stripOffsets[k]); else if (k > 0) { long skip = (fi.stripOffsets[k] & 0xffffffffL) - (fi.stripOffsets[k - 1] & 0xffffffffL) - fi.stripLengths[k - 1]; if (skip > 0L) in.skip(skip); } byte[] byteArray = new byte[fi.stripLengths[k]]; int read = 0, left = byteArray.length; while (left > 0) { int r = in.read(byteArray, read, left); if (r == -1) { eofError(); break; } read += r; left -= r; } byteArray = uncompress(byteArray); int pixelsRead = byteArray.length / bytesPerPixel; pixelsRead = pixelsRead - (pixelsRead % fi.width); int pmax = base + pixelsRead; if (pmax > nPixels) pmax = nPixels; int tmp; if (fi.intelByteOrder) { for (int i = base, j = 0; i < pmax; i++, j += 4) { tmp = (int) (((byteArray[j + 3] & 0xff) << 24) | ((byteArray[j + 2] & 0xff) << 16) | ((byteArray[j + 1] & 0xff) << 8) | (byteArray[j] & 0xff)); if (fi.fileType == FileInfo.GRAY32_FLOAT) pixels[i] = Float.intBitsToFloat(tmp); else if (fi.fileType == FileInfo.GRAY32_UNSIGNED) pixels[i] = (float) (tmp & 0xffffffffL); else pixels[i] = tmp; } } else { for (int i = base, j = 0; i < pmax; i++, j += 4) { tmp = (int) (((byteArray[j] & 0xff) << 24) | ((byteArray[j + 1] & 0xff) << 16) | ((byteArray[j + 2] & 0xff) << 8) | (byteArray[j + 3] & 0xff)); if (fi.fileType == FileInfo.GRAY32_FLOAT) pixels[i] = Float.intBitsToFloat(tmp); else if (fi.fileType == FileInfo.GRAY32_UNSIGNED) pixels[i] = (float) (tmp & 0xffffffffL); else pixels[i] = tmp; } } if (fi.compression == FileInfo.LZW_WITH_DIFFERENCING) { for (int b = base; b < pmax; b++) { pixels[b] += last; last = b % fi.width == fi.width - 1 ? 0 : pixels[b]; } } base += pixelsRead; showProgress(k + 1, fi.stripOffsets.length); } return pixels; }