Page 1 of 1

converting a 16-bit PPM file to two 8-bit PPM files

Posted: 2018-02-28T08:20:01-07:00
by Hiro
Hi,

I'd like to convert a 16-bit PPM file to two 8-bit PPM files, one is from MSB 8bits and the other from LSB 8bits.

In the following example I use a bash function, tohex(), which convert decimal numbers into hexadecimal numbers.

Code: Select all

bash$ type tohex
tohex is a function
tohex () 
{ 
    perl -nae 'print join(" ", map {sprintf "%x", $_ } @F), "\n"' "$@"
}
bash$ tohex
65535 64192 65280            
ffff fac0 ff00
To get MSB 8bit, I did follows;

Code: Select all

bash$ echo "P3 1 1 65535 64192 64192 64192" | convert - -evaluate And 65280 -depth 16 -compress None PPM:-|tohex
0
1 1
ffff
fa00 fa00 fa00
This is what I expected.

Code: Select all

bash$ echo "P3 1 1 65535 64192 64192 64192" | convert - -evaluate And 65280 -depth 8 -compress None PPM:-|tohex
0
1 1
ff
f9 f9 f9
I don't understand why I get 0xf9 instead of 0xfa.

To get LSB 8bit, similary

Code: Select all

bash$ echo "P3 1 1 65535 64192 64192 64192" | convert - -evaluate And 255 -depth 16 -compress None PPM:-|tohex
0
1 1
ffff
c0 c0 c0
bash$ echo "P3 1 1 65535 64192 64192 64192" | convert - -evaluate And 255 -evaluate LeftShift 8 -depth 16 -compress None PPM:-|tohex
0
1 1
ffff
c000 c000 c000
This is what I expected, but...

Code: Select all

bash$ echo "P3 1 1 65535 64192 64192 64192" | convert - -evaluate And 255 -evaluate LeftShift 8 -depth 8 -compress None PPM:-|tohex
0
1 1
ff
bf bf bf
Why I get 0xbf instead of 0xc0?

What is wrong? Is there a good way to get 8bit PPM from 16bit PPM?

Same results on both my Linux and Cygwin environments.

On Linux

Code: Select all

bash$ convert -version
Version: ImageMagick 6.2.5 03/04/15 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2005 ImageMagick Studio LLC
On Cygwin

Code: Select all

$ convert -version
Version: ImageMagick 6.9.9-11 Q16 i686 2017-09-30 http://www.imagemagick.org
Copyright: c 1999-2017 ImageMagick Studio LLC
License: http://www.imagemagick.org/script/license.php
Features: Cipher DPC OpenMP
Delegates (built-in): autotrace bzlib cairo fftw fontconfig fpx freetype gslib jbig jng jp2 jpeg lcms lzma pangocairo png ps rsvg tiff webp x xml zlib
Thanks in advance.

Re: converting a 16-bit PPM file to two 8-bit PPM files

Posted: 2018-02-28T08:37:27-07:00
by snibgo
Conversion from 8 to 16 bits works by replicating the byte, not by appending a zero byte. So 0xff becomes 0xffff, 0xab becomes 0xabab, etc. Similarly in the opposite direction.

Arithmetically, this is done by multiplying (or dividing) by 0x0101, which is decimal 257.

Re: converting a 16-bit PPM file to two 8-bit PPM files

Posted: 2018-02-28T08:56:08-07:00
by Hiro
Thank you for your quick reply.

Code: Select all

bash$ echo "P3 1 1 65535 64192 64192 64192" | convert - -evaluate And 255 -evaluate Multiply 257 -depth 8 -compress None PPM:-|tohex
0
1 1
ff
c0 c0 c0
bash$ echo "P3 1 1 65535 64192 64192 64192" | convert - -evaluate RightShift 8 -evaluate And 255 -evaluate Multiply 257 -depth 8 -compress None PPM:-|tohex
0
1 1
ff
fa fa fa
Works great!

Thanks a lot!

Re: converting a 16-bit PPM file to two 8-bit PPM files

Posted: 2018-03-01T08:17:46-07:00
by Hiro
0xffff/0xff = 257
0x10000/0x100=256

Re: converting a 16-bit PPM file to two 8-bit PPM files

Posted: 2018-03-01T08:47:30-07:00
by snibgo
Yes, that is correct.