Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

10 bit tiff support #185

Closed
wants to merge 2 commits into from
Closed

Conversation

evanspa
Copy link

@evanspa evanspa commented Nov 7, 2022

Hello - I was asked by Accelerate Diagnostics Inc. to add support to ImageJ for 10-bit TIFF images produced by their equipment. This PR contains this functionality. The meat of the code is a new "read10bitImage()" function inside of ImageReader.java, along with a new file info constant, GRAY10_UNSIGNED. I tried to keep the code consistent with how the other bit-length reader functions are implemented. This code was tested against several 10-bit TIFF files provided by Accelerate and worked well. To accomplish this, the read10bitImage() function reads in 5 bytes of data at a time, and produces 4 pixels of information. The result is that each new pixel contains no data loss, so the fidelity of the image is not reduced with this conversion. Each new 16-bit pixel contains the original 10-bits of information; the remaining unused 6-bits are set to 0 (left-padded).

Accelerate Diagnostics Inc has been a happy user of ImageJ for years, and are excited that this small contribution may make its way into the core product, to benefit other users.

Thank you for your consideration of this PR.
-Paul

@ctrueden
Copy link
Member

@evanspa That's awesome! Thanks for contributing.

@rasband What do you think? If you want to review the patch without the whitespace changes cluttering the view, you can append ?w=1 to the URL—in this case: https://github.com/imagej/ImageJ/pull/185/files?w=1

@rasband
Copy link
Member

rasband commented Feb 18, 2023

Hi @evanspa,
It would be helpful if you could provide an example 10 bit tiff file to use for testing.

@ctrueden
Copy link
Member

The LibTIFF library has a nice collection of samples, including bit depths from 2 through 32, downloadable from http://www.simplesystems.org/libtiff/images.html. In particular, these files from the archive might be helpful for testing:

  • libtiffpic/depth/flower-minisblack-10.tif
  • libtiffpic/depth/flower-rgb-planar-10.tif
  • libtiffpic/depth/flower-rgb-contig-10.tif

@rasband
Copy link
Member

rasband commented Feb 19, 2023

@evanspa, @ctrueden
10 bit tiff support is in the ImageJ 1.54c26 daily build but there seems to be a problem with the read10bitImage() method. It enters an infinite loop when you try to open the libtiffpic/depth/flower-minisblack-10.tif sample image.

The commit is at 8355378.

@rasband
Copy link
Member

rasband commented Feb 20, 2023

I made 2 small changes to the read10bitImage() method (marked with "//wsr") and it now opens the libtiffpic/depth/flower-minisblack-10.tif sample image. These changes are in the ImageJ 1.54c27 daily build.

-wayne

 	short[] read10bitImage(InputStream in) throws IOException {
 		int bytesPerLine = (int)(width*1.25); // there are 1.25 bytes of data for each pixel (5 bytes per 4 pixels)
 		if ((width&1)==1) bytesPerLine++; // add 1 if odd //wsr
 		byte[] buffer = new byte[bytesPerLine*height];
 		short[] pixels = new short[nPixels];
 		DataInputStream dis = new DataInputStream(in);
 		dis.readFully(buffer);
 		for (int y=0; y<height; y++) {
 			int index1 = y*bytesPerLine;
 			int index2 = y*width;
 			int count = 0;
			while (count<width) {
 				if (index1 + 4 < buffer.length) {
 					final short B0 = (short) (buffer[index1] & 0xFF);
 					final short B1 = (short) (buffer[index1 + 1] & 0xFF);
 					final short B2 = (short) (buffer[index1 + 2] & 0xFF);
 					final short B3 = (short) (buffer[index1 + 3] & 0xFF);
 					final short B4 = (short) (buffer[index1 + 4] & 0xFF);
 					short b0, b1, b2, b3;

 					// Set pixel 1
 					b0 = (short) (B0 << 2);
 					b1 = (short) (B1 >> 6);
 					pixels[index2 + count] = (short) (b0 | b1);
 					count++;

 					// set pixel 2
 					b1 = (short) ((B1 & (0xFF >> 2)) << 4);
 					b2 = (short) (B2 >> 4);
 					pixels[index2 + count] = (short) (b1 | b2);
 					count++;

 					// set pixel 3
 					b2 = (short) ((B2 & (0xFF >> 4)) << 6);
 					b3 = (short) (B3 >> 2);
 					pixels[index2 + count] = (short) (b2 | b3);
 					count++;

 					// set pixel 4
 					b3 = (short) ((B3 & (0xFF >> 6)) << 8);
 					pixels[index2 + count] = (short) (b3 | B4);
 					count++;
 					index1 += 5;
 				} else
 					break; //wsr
 			}
 		}
 		return pixels;
 	}

@rasband rasband closed this Feb 20, 2023
@evanspa
Copy link
Author

evanspa commented Feb 21, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants