Bug 344287 - Open floating point tiffs
Summary: Open floating point tiffs
Status: REPORTED
Alias: None
Product: okular
Classification: Applications
Component: TIFF backend (show other bugs)
Version: unspecified
Platform: Other Linux
: NOR wishlist
Target Milestone: ---
Assignee: Okular developers
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-02-17 17:31 UTC by Mikhail Kandel
Modified: 2015-02-17 21:47 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments
floating point tiff in [0 to 1.0] range (59.58 KB, image/jpeg)
2015-02-17 19:42 UTC, Mikhail Kandel
Details
floating point tiff (low resolution blood cells, taken with a holographic microscope) (1.00 MB, image/tiff)
2015-02-17 19:43 UTC, Mikhail Kandel
Details
that file open with okular (482.45 KB, image/png)
2015-02-17 20:38 UTC, Albert Astals Cid
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Mikhail Kandel 2015-02-17 17:31:57 UTC
I work with floating point textures in the form of textures for 3D models and holography images.

LibTiff has support for reading and writting this format, as does ImageJ or Matlab.

On a Windows system (and Adobe PS) float point tiffs appear as an image scaled to the [0,1] range.  Can we have this?

Reproducible: Always
Comment 1 Albert Astals Cid 2015-02-17 19:23:01 UTC
Attach a file and how is supposed to look.

That way if someone wants to implement it, he'll have something to work over.
Comment 2 Mikhail Kandel 2015-02-17 19:42:39 UTC
Created attachment 91138 [details]
floating point tiff in [0 to 1.0] range
Comment 3 Mikhail Kandel 2015-02-17 19:43:23 UTC
Created attachment 91139 [details]
floating point tiff (low resolution blood cells, taken with a holographic microscope)
Comment 4 Mikhail Kandel 2015-02-17 19:45:36 UTC
I read them where T=float:

static
		TIFFImage<T> readBuffer(const char* fname)//deallocate with 
	{
		TIFF* tif = TIFFOpen(fname, "r");//tiff open catch error?
		assert(tif);
		int imgH, imgW;
		TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imgH);
		TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imgW);
		int rowsize = imgW*sizeof(T);
		auto mydata = (unsigned char*)malloc(rowsize*imgH);
		for (int row = 0; row < imgH; row++)
		{
			auto toMe = (void*)&mydata[rowsize*row];
			TIFFReadScanline(tif, toMe, row);
		}
		TIFFClose(tif);
		TIFFImage<T> s;
		s.c = imgW;
		s.r = imgH;
		s.img = (T*)mydata;
		return s;
	}


write them like

	static void writeTiffFast(const char* name, const void* buffer, unsigned int w, unsigned int h, bool isfloat, bool fast=false, const TiffExtraMetaData* meta = nullptr)
	{
		assert((w>0) && (h > 0));
		TIFF* tif = TIFFOpen(name, "w");//quality error correcting code
		TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, w);  // set the width of the image
		TIFFSetField(tif, TIFFTAG_IMAGELENGTH, h);    // set the height of the image
		TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);   // set number of channels per pixel
		TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
		TIFFSetField(tif, TIFFTAG_SOFTWARE, "QLI SLIM5");
		TIFFSetField(tif, TIFFTAG_MAKE, "Mikhail Kandel");
		if (meta!=nullptr)
		{
			TIFFSetField(tif, TIFFTAG_DATETIME, meta->datetime);
		}
		else
		{
			//get default meta data;
			TiffExtraMetaData defaulto;
			TIFFSetField(tif, TIFFTAG_DATETIME, defaulto.datetime);
		}
		TIFFSetField(tif, TIFFTAG_MODEL, __DATE__);
		int rowsize = 0;
		if (isfloat)
		{
			//todo write a LUT
			//TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE);
			TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
			TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8 * sizeof(float));    // set the size of the channels
			TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);   // set number of channels per pixel
			rowsize = w*sizeof(float);
		}
		else
		{
			TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
			TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8 * sizeof(unsigned short));    // set the size of the channels
			TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);   // set number of channels per pixel
			rowsize = w*sizeof(unsigned short);
		}
		if (fast)
			//if (0) //todo make this work ?
		{
			TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, h);
			int bytesize = rowsize*h;
			TIFFWriteRawStrip(tif, 1, (void*)buffer, bytesize);
		}
		else
		{
			TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
			for (unsigned int r = 0; r < h; r++)//'r' for row
			{
				auto aschar = (unsigned char*)buffer;
				auto data = &aschar[rowsize*r];
				TIFFWriteScanline(tif, data, r);
			}
		}
		TIFFClose(tif);
	}
Comment 5 Albert Astals Cid 2015-02-17 20:38:23 UTC
Errr, this already works?
Comment 6 Albert Astals Cid 2015-02-17 20:38:57 UTC
Created attachment 91140 [details]
that file open with okular
Comment 7 Mikhail Kandel 2015-02-17 21:37:46 UTC
Comment on attachment 91140 [details]
that file open with okular

That would be nice. This is what I see when I open the tif file.

fruitcake@gentoo ~/Desktop $ okular file.tif
okular(10268)/kdecore (KConfigSkeleton) KCoreConfigSkeleton::writeConfig:
okular(10268)/kdecore (KConfigSkeleton) KCoreConfigSkeleton::writeConfig:
okular(10268)/kdecore (KConfigSkeleton) KCoreConfigSkeleton::writeConfig:
okular(10268)/kdecore (KConfigSkeleton) KCoreConfigSkeleton::writeConfig:
okular(10268)/kdecore (KConfigSkeleton) KCoreConfigSkeleton::writeConfig:
47949_BEST.tif: Sorry, can not handle images with 32-bit samples.
47949_BEST.tif: Sorry, can not handle images with 32-bit samples.
47949_BEST.tif: Sorry, can not handle images with 32-bit samples.
daniel@cortana ~/Desktop $ okular -v
Qt: 4.8.5
KDE Development Platform: 4.14.3
Okular: 0.20.3
Comment 8 Albert Astals Cid 2015-02-17 21:40:36 UTC
Well since it works for me with the stock Ubuntu packages, it's seems to me its something that the gentoo packagers are doing different/wrong.

I suggest bringing the issue to their attention in their bug tracker.
Comment 9 Albert Astals Cid 2015-02-17 21:46:24 UTC
Ignore me, i messed up and was opening the jpeg you attached.
Comment 10 Albert Astals Cid 2015-02-17 21:47:00 UTC
You seem to have some code and ideas how to do it, why not download okular's source code and play with it?