Decompose 16-bit TIF into two 8-bit PNGs

Questions and postings pertaining to the development of ImageMagick, feature enhancements, and ImageMagick internals. ImageMagick source code and algorithms are discussed here. Usage questions which are too arcane for the normal user list should also be posted here.
Post Reply
personalrobert
Posts: 11
Joined: 2012-12-20T12:49:30-07:00
Authentication code: 6789

Decompose 16-bit TIF into two 8-bit PNGs

Post by personalrobert »

Can I use convert to write only the upper (or lower) 8 bits of a 16-bit grayscale TIF? That is, will the following work?

Code: Select all

convert original.tif -evaluate and 255 -depth 8 lower.png
convert original.tif -evaluate RightShift 8 -evaluate and 255 -depth 8 upper.png
I don't want any normalization to occur. When I go from 16 to 8, how do I know which 8 bits it will use?
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Decompose 16-bit TIF into two 8-bit PNGs

Post by snibgo »

Can I use convert to write only the upper (or lower) 8 bits of a 16-bit grayscale TIF?
Yes.
That is, will the following work?
No.

The main difficulty with your approach is that when converting 16-bit=>8-bit, the important bits are the ones at the top, not the bottom. And we can't just strip the bottom bits, because 16-bit=>8-bit(#9ABC) = #99, not #9A.
snibgo's IM pages: im.snibgo.com
personalrobert
Posts: 11
Joined: 2012-12-20T12:49:30-07:00
Authentication code: 6789

Re: Decompose 16-bit TIF into two 8-bit PNGs

Post by personalrobert »

16-bit=>8-bit(#9ABC) = #99, not #9A
I give up. How do you get #99 from the top bits of #9ABC?

Is there documentation of the rules for converting from 16 to 8 bit?
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Decompose 16-bit TIF into two 8-bit PNGs

Post by snibgo »

Sorry, I meant to say 16-bit=>8-bit(#9A00) = #99, not #9A.

Yes, it's documented somewhere. I forget where; you'll have to look around. And it is in the source code, of course.

To get the correct spread of values, when converting from 8-bit to 16, the 8 bits must be replicated. To ensure symmetry, the conversion is the same in the other direction.

16-bit <=> 8-bit
#0000 <=> #00
#0101 <=> #01
#0202 <=> #02
#0303 <=> #03
#0404 <=> #04
:
#9898 <=> #98
#9999 <=> #99
#9A9A <=> #9A
#9B9B <=> #9B
;
#FFFF <=> #FF

You can see that #9A00 is closer to #9999 than to #9A9A, so it converts to #99.
snibgo's IM pages: im.snibgo.com
personalrobert
Posts: 11
Joined: 2012-12-20T12:49:30-07:00
Authentication code: 6789

Re: Decompose 16-bit TIF into two 8-bit PNGs

Post by personalrobert »

So it looks to me that if I want to force #XXYY to convert to #XX (regardless of YY), I should first modify it to #XXXX.
Do you agree?

Thanks a ton for your assistance!
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Decompose 16-bit TIF into two 8-bit PNGs

Post by snibgo »

Yes, I think that's right. This seems to be a general solution (not thoroughly tested, and there may be neater/faster solutions):

Code: Select all

convert x.tif -evaluate And 255 -evaluate Multiply 256 ( +clone -evaluate Divide 256 ) -compose Add -composite -depth 8 lower.png

convert x.tif -evaluate RightShift 8 -evaluate LeftShift 8 ( +clone -evaluate Divide 256 ) -compose Add -composite -depth 8 upper.png
snibgo's IM pages: im.snibgo.com
personalrobert
Posts: 11
Joined: 2012-12-20T12:49:30-07:00
Authentication code: 6789

Re: Decompose 16-bit TIF into two 8-bit PNGs

Post by personalrobert »

I was thinking:

Code: Select all

-fx "(u & #ff00) | (u >> 8)" -depth 8 upper.png
-fx "(u & #00ff) | (u << 8)" -depth 8 lower.png
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Decompose 16-bit TIF into two 8-bit PNGs

Post by snibgo »

Have you tried it? Does it work?
snibgo's IM pages: im.snibgo.com
personalrobert
Posts: 11
Joined: 2012-12-20T12:49:30-07:00
Authentication code: 6789

Re: Decompose 16-bit TIF into two 8-bit PNGs

Post by personalrobert »

I tried it. It doesn't seem to work.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Decompose 16-bit TIF into two 8-bit PNGs

Post by snibgo »

I'm not an FX expert, but I think the values of "u" are floating point in the range zero to one. Bit-wise manipulations, and coping with rounding errors, is messy.
snibgo's IM pages: im.snibgo.com
pipe
Posts: 28
Joined: 2013-04-09T08:32:37-07:00
Authentication code: 6789

Re: Decompose 16-bit TIF into two 8-bit PNGs

Post by pipe »

If you really must do this with imagemagick you can use this trick. It assumes that you know the image dimensions and that you are running on a platform with working pipes (that is, linux/bsd/osx/cygwin..). If you run this in windows you can create a temporary file instead. (GRAY:foo.raw instead of GRAY:-)

You must replace 2*W and H in the commands with the actual double source width and the real source height. If your source image is 320x240 you would write 640x240.
convert gray.tiff -depth 16 GRAY:- | convert -size 2*WxH -depth 8 GRAY:- -define sample:offset=25x50 -sample 50%x100%\! upper.png
convert gray.tiff -depth 16 GRAY:- | convert -size 2*WxH -depth 8 GRAY:- -define sample:offset=75x50 -sample 50%x100%\! lower.png
Upper and lower depends on the endianess of your machine.

If you're a real ImageMagick pro (Anthony), you may figure out a way to do this in one command, or at least calculate the image size in the second convert from the source image.
Post Reply