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

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
largactyl
Posts: 3
Joined: 2019-06-18T00:58:35-07:00
Authentication code: 1152

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

Post by largactyl » 2019-06-18T01:51:12-07:00

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.

snibgo
Posts: 11809
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

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

Post by snibgo » 2019-06-18T04:18:04-07:00

I think the "GRAY:" format does what you want, eg:

Code: Select all

magick in.png -depth 1 GRAY:out.bin
snibgo's IM pages: im.snibgo.com

largactyl
Posts: 3
Joined: 2019-06-18T00:58:35-07:00
Authentication code: 1152

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

Post by largactyl » 2019-06-18T14:28:44-07:00

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? ;)

snibgo
Posts: 11809
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

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

Post by snibgo » 2019-06-18T14:38:13-07:00

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.
snibgo's IM pages: im.snibgo.com

largactyl
Posts: 3
Joined: 2019-06-18T00:58:35-07:00
Authentication code: 1152

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

Post by largactyl » 2019-06-18T22:06:01-07:00

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. :)

snibgo
Posts: 11809
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

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

Post by snibgo » 2019-06-19T04:26:08-07:00

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.
snibgo's IM pages: im.snibgo.com

Post Reply