Page 1 of 1

Converting to raw MONO: images - wrong bit order within byte

Posted: 2019-06-18T01:51:12-07:00
by largactyl
Hi,

I am trying to convert a batch of monochrome PNGs to raw 1-bit data, i.e. 8 ON/OFF pixels represented by each byte. My issue is that the output's bit order within each byte (not the byte order) is the opposite of what I need. As a result, each successive group of 8 pixels is flipped on the X axis.

For my purposes the most significant bit should be the leftmost pixel. For example, if my input has one pixel 'ON' followed by seven pixels OFF (left to right), I'd expect a byte value of 10000000 binary, but IM outputs 00000001.

Can this be fixed? I've tried various permutations of options like:

Code: Select all

magick convert input.png -monochrome -depth 1 MONO:test1.raw

magick convert input.png -type bilevel MONO:test2.raw
Seems like this can be fixed for TIFF files (-define tiff:fill-order=msb|lsb), but I couldn't find such an option for MONO:, or for any format other than TIFF. Any tips or workarounds would be appreciated.

Re: Converting to raw MONO: images - wrong bit order within byte

Posted: 2019-06-18T04:18:04-07:00
by snibgo
I think the "GRAY:" format does what you want, eg:

Code: Select all

magick in.png -depth 1 GRAY:out.bin

Re: Converting to raw MONO: images - wrong bit order within byte

Posted: 2019-06-18T14:28:44-07:00
by largactyl
Yep, that did it - thank you.

Doesn't seem intuitive to me, though... and the documentation doesn't mention anything about the bit-ordering in GRAY: vs. MONO: (unless I missed it, of course). I don't really see the reasoning behind the difference; perhaps this should be a configurable setting, as it is with TIFF? Or, failing that, at least document the issue? ;)

Re: Converting to raw MONO: images - wrong bit order within byte

Posted: 2019-06-18T14:38:13-07:00
by snibgo
The documentation http://www.imagemagick.org/script/formats.php says about MONO:
Bi-level bitmap in least-significant-byte first order
On GRAY, It says nothing about the order, I think because it is as expected: the left-most pixels are represented by the most significant bits.

Re: Converting to raw MONO: images - wrong bit order within byte

Posted: 2019-06-18T22:06:01-07:00
by largactyl
Ah, then I suppose the MONO description should simply be corrected: "Bi-level bitmap in least-significant-bit first order". That one did have me scratching my head a bit. :)

Re: Converting to raw MONO: images - wrong bit order within byte

Posted: 2019-06-19T04:26:08-07:00
by snibgo
largactyl wrote:... the MONO description should simply be corrected "Bi-level bitmap in least-significant-bit first order".
Yes, I agree. Bit, not byte. @Fred: can you change that wording to "Bi-level bitmap in least-significant-bit first order".

But the code in mono.c has me scratching my head. It reads pixels in the usual row,column order, and always sets the first pixel in a group of 8 to the least-significant bit. However, it uses the endian setting. If this is LSBEndian (the default), it inverts each bit. I don't think this is documented. We can confirm at the command line with an 8x1 image that is black except for white at the left-most pixel.

Code: Select all

magick xc:White -background Black -extent 8x1 MONO:- |dumpbin /p0 /i- /o-
{fe}

magick xc:White -background Black -extent 8x1 -endian LSB MONO:- |dumpbin /p0 /i- /o-
{fe}

magick xc:White -background Black -extent 8x1 -endian MSB MONO:- |dumpbin /p0 /i- /o-
{01}
dumpbin is my own utility that here dumps the single byte as hex.