Re: Fix for: ImageJ cannot open 48-bit LZW compressed TIFFs

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Re: Fix for: ImageJ cannot open 48-bit LZW compressed TIFFs

Wayne Rasband
This patch, which adds support for 48-bit LZW compressed TIFFs, is in
the v1.43c daily build.

-wayne

On Jul 1, 2009, at 6:27 PM, aaron wrote:

> Hi,
>
> having encountered the dreaded "ImageJ cannot open 48-bit LZW
> compressed
> TIFFs" more than once
> and using Bio-Formats Importer plugin being out of scope (due to it
> being published under GPL),
> I decided to give it a try and add support for 48-bit LZW compressed
> TIFFs to ImageJ myself.
>
> Looks like it wasn't as tricky as I initially feared it would be... I'd
> be happy to see this included in a future release.
> (Included patch is against content of ij143b-src.zip.)
>
> Kind Regards
>   Olaf Freyer
> Nur in source_fixed: build.
> diff -r -uwb source/ij/io/ImageReader.java
> source_fixed/ij/io/ImageReader.java
> --- source/ij/io/ImageReader.java 2009-06-18 11:34:58.000000000 +0200
> +++ source_fixed/ij/io/ImageReader.java 2009-07-02 00:09:59.000000000
> +0200
> @@ -495,6 +495,8 @@
>   }
>  
>   Object readRGB48(InputStream in) throws IOException {
> + if (fi.compression==FileInfo.LZW ||
> fi.compression==FileInfo.LZW_WITH_DIFFERENCING ||
> fi.compression==FileInfo.PACK_BITS)
> + return readCompressedRGB48(in);
>   int channels = 3;
>   short[][] stack = new short[channels][nPixels];
>   DataInputStream dis = new DataInputStream(in);
> @@ -533,6 +535,49 @@
>   return stack;
>   }
>
> +        Object readCompressedRGB48(InputStream in) throws IOException
> {
> + if (fi.compression==FileInfo.LZW_WITH_DIFFERENCING)
> + throw new IOException("ImageJ cannot open 48-bit LZW compressed
> TIFFs with predictor");
> + int channels = 3;
> + short[][] stack = new short[channels][nPixels];
> + DataInputStream dis = new DataInputStream(in);
> + int pixel = 0;
> + int min=65535, max=0;
> + for (int i=0; i<fi.stripOffsets.length; i++) {
> + if (i>0) {
> + int skip = fi.stripOffsets[i] - fi.stripOffsets[i-1] -
> fi.stripLengths[i-1];
> + if (skip>0) dis.skip(skip);
> + }
> + int len = fi.stripLengths[i];
> + byte[] buffer = new byte[len];
> + dis.readFully(buffer);
> + buffer = uncompress(buffer);
> + len = buffer.length;
> + if (len % 2 != 0)
> + len--;
> + int value;
> + int channel=0;
> + boolean intel = fi.intelByteOrder;
> + for (int base=0; base<len; base+=2) {
> + if (intel)
> + value = ((buffer[base+1]&0xff)<<8) | (buffer[base]&0xff);
> + else
> + value = ((buffer[base]&0xff)<<8) | (buffer[base+1]&0xff);
> + if (value<min) min = value;
> + if (value>max) max = value;
> + stack[channel][pixel] = (short)(value);
> + channel++;
> + if (channel==channels) {
> + channel = 0;
> + pixel++;
> + }
> + }
> + showProgress(i+1, fi.stripOffsets.length);
> + }
> + this.min=min; this.max=max;
> + return stack;
> +        }
> +
>   Object readRGB48Planar(InputStream in) throws IOException {
>   short[] red = read16bitImage(in);
>   short[] green = read16bitImage(in);
> diff -r -uwb source/ij/io/TiffDecoder.java
> source_fixed/ij/io/TiffDecoder.java
> --- source/ij/io/TiffDecoder.java 2009-06-18 11:24:54.000000000 +0200
> +++ source_fixed/ij/io/TiffDecoder.java 2009-07-01 22:09:03.000000000
> +0200
> @@ -447,8 +447,6 @@
>   case COMPRESSION:
>   if (value==5) { // LZW compression
>   int bpp = fi.getBytesPerPixel();
> - if (bpp==6)
> - error("ImageJ cannot open 48-bit LZW compressed TIFFs");
>   fi.compression = FileInfo.LZW;
>   } else if (value==32773) { // PackBits compression
>   fi.compression = FileInfo.PACK_BITS;
> Nur in source_fixed: ij.jar.