bugGNU Octave - Bugs: bug #41584, .bmp / .png display error for...


bug #41584: .bmp / .png display error for saturated RGB image.

Submitted by:  None
Submitted on:  Thu 13 Feb 2014 10:36:44 PM UTC  
Category: Octave FunctionSeverity: 3 - Normal
Priority: 5 - NormalItem Group: Inaccurate Result
Status: ConfirmedAssigned to: None
Originator Name: Greg JefferyOriginator Email: -unavailable-
Open/Closed: OpenRelease: dev
Operating System: Any

Add a New Comment(Rich Markup)

You are not logged in

Please log in, so followups can be emailed to you.


(Jump to the original submission Jump to the original submission)

Fri 08 Dec 2017 11:37:37 PM UTC, comment #12:

I've posted a bug report here:


Dan Sebald <sebald>
Fri 08 Dec 2017 05:10:10 AM UTC, comment #11:

I've looked at this one a bit, experimenting with various parts of the GraphicsMagick library. As Carnë postulated, there may be a bug in the GraphicsMagick or underlying library code. I'm leaning that way, and I will explain why a bit later.

However, the main issue is whether this approach should be used:

My thought is to not do this because the ramification is something like described in bug report https://savannah.gnu.org/bugs/?49140 . As described in earlier posts, GraphicsMagick can compress it's internal representation if the extremes are 0.0 and 1.0, e.g., 0x00 and 0xFF in 8-bit land thus suggesting the channel depth is 1-bit when the original file was not 1-bit per channel.

It's one of two bad-outcomes, but I lean toward treating 8-bit data as 1-bit (the above code) is a worse outcome than treating 1-bit data as 8-bit--unless there is some bad scaling effect I'm unaware of such that 0.0 and 1.0 aren't mapped to 0 and 255. The thing is, it's really easy to convert from (0,255) back to (0,1) after the fact with logical(img) at Octave's command line--not as easy to go the other direction. Furthermore, if down the line there are bug fixes in the GM Magick++ library, the issue will disappear on its own.

It could be a bug in the way Octave is accessing the Magick++ library (e.g., overlooked initialization, incomplete processing), but I've tried enough things to start thinking it isn't Octave's problem.

Let's get some footing by observing Octave/Magick++ (with GraphicsMagick as the library code) is /writing/ an image in 1-bit channel depth:

Notice in the above that I've used two different utilities to "identify" the image that was created. The first "gm identify" is the GraphicsMagick utility. The second "identify" is the ImageMagick utility. Right away we see that GraphicsMagick can't properly identify a 1-bit image file (although it can create one) while ImageMagick can.

I've experimented with a few code variations, most similar to the "readImages()" of the STL.h Magick++ interface. Yet, I just get a depth of 8, rather than 1, when reading testbinary.bmp. I even made use of the function

which will effectively run "gm identify" from within Octave:

which is the same result as gotten from the command line above.

The list of GM bug fixes appears to be here:


I don't see much mention of 1-bit depth fixes. I have version

I suppose someone should get the latest version of GM and compile it. Then test if the testbinary.bmp file is identified as 1-bit. If not, then file a bug report at the GM SourceForge development site. Maybe it wouldn't be that difficult to fix either...could be that no one ever noticed because 1-bit images aren't used too much.

FWIW, my version of ImageMagick utilities is:

Dan Sebald <sebald>
Tue 14 Jul 2015 10:35:40 AM UTC, comment #10:

Vallery said on Comment #9:

> if all channels are saturated or zero then imread couldn't be blamed for returning damaging data because of the logical matrix.

Of course it can. It is part of the file information if the data is 8 bit, 16 bit, signed or unsigned, boolean, floating point, or something else. The actual pixel values of the image are irrelevant. Unfortunately, this information is not available (at least not in a reliable way) to us when using GraphicsMagick (but would be if we used the format specific libraries).

Carnë Draug <carandraug>
Project Member
Mon 13 Jul 2015 11:58:27 PM UTC, comment #9:

Carnё, thank you.

BTW, if all channels are saturated or zero then imread couldn't be blamed for returning damaging data because of the logical matrix. In my case imread was simply destroying a huge part of the data.

So, imshow still probably needs to be patched to show the logical matrix right...

Valery <vak>
Mon 13 Jul 2015 12:05:50 PM UTC, comment #8:

Thank you. I confirm that your patch fixes for your image. However it does not fix the original bug report.

You fix works when only the red channels was saturated. The original bug report is when all channels are either saturated or zero. In those cases, we are still reading as binary images.

Interestingly, the issue you have would not occur if your image was in bmp so this really is a GM coder specific issue.

Anyway, I pushed your fix and a test which will part of the next minor release (Octave 4.2)


but will keep the bug report open since the original bug is not fixed yet.

Carnë Draug <carandraug>
Project Member
Mon 13 Jul 2015 07:27:37 AM UTC, comment #7:

Carnё, please, find the attached image (works fine with patched version)

Valery <vak>
Fri 10 Jul 2015 04:37:37 PM UTC, comment #6:


Can you please submit a test image that displays the problem. I just tested with the artifical image generated on comment #1, and your fix does not fix it.

Carnë Draug <carandraug>
Project Member
Fri 10 Jul 2015 11:41:23 AM UTC, comment #5:


the problem shows up to me when using the following images:

PNG 1250x1250 1250x1250+0+0 8-bit sRGB 250KB 0.000u 0:00.000

in which:

Colorspace: sRGB
Depth: 8-bit
Channel depth:
red: 1-bit
green: 8-bit
blue: 8-bit

So the "unlucky" red channel causes get_depth currently to override the correct default result value "8" with the incorrect "1", what then leads to the false matrix type "logical".

As quick-n-dirty fix I added these two lines with conditions for the green and blue channels:


static octave_idx_type
get_depth (Magick::Image& img)
octave_idx_type depth = img.depth ();
if (depth == 8
&& img.channelDepth (Magick::RedChannel) == 1
&& img.channelDepth (Magick::GreenChannel) == 1 // <<--- added
&& img.channelDepth (Magick::BlueChannel) == 1 // <<--- added
&& img.channelDepth (Magick::CyanChannel) == 1
&& img.channelDepth (Magick::OpacityChannel) == 1
&& img.channelDepth (Magick::GrayChannel) == 1)
depth = 1;

return depth;

and am getting uint8 for the image matrix in result.
Now I am bound to this my fixed Octave version and would be cool if this or other patch could be incorporated in next public releases.

P.S. Disclaimer: I don't have an answer though, why Cyan, Opacity and Gray channels all return depth of 1 for such images .

Valery <vak>
Sat 15 Feb 2014 08:04:33 PM UTC, comment #4:

I can confirm that I also get a an image of class logical rather than of uint8. My GraphicsMagick is built with a quantum-depth of 8 so I think this is a general problem.

Rik <rik5>
Project Administrator
Fri 14 Feb 2014 03:21:01 AM UTC, comment #3:

I messed up the syntax on the last message sos here it goes again:

Mike, I can replicate the problem on my system.

imread() returns a 128x128x3 logical matrix on my system which imshow() fails
to display.

I don't know if the quantum depth used with GraphicsMagick (GM) could make a
difference (I have it built with quantum-depth 32).

The gm application identifies the image correctly has 8bit

I believe the problem may be with get_depth() in _magick_read_.cc which
tries to workaround some wrong results of GM (there's a big block of comments
there trying to explain the issue).

The issue is that GM is not in fault here. What they return as depth,
channelDepth, classType, etc is not meant to be interpreted as the way the
image was represented in the file, but the way GM is keeping it in memory. If
an image has few colors, GM may decide to interpret it as indexed, if all
channels are equal, it may decide to keep it grayscale, etc. They don't have
methods that will reliable tell us what was in the file.

Carnë Draug <carandraug>
Project Member
Thu 13 Feb 2014 11:39:33 PM UTC, comment #2:

Mike, I can replicate the problem on my system.

imread() returns a 128x128x3 logical matrix on my system which imshow() fails to display.

I don't know if the quantum depth used with GraphicsMagick (GM) could make a difference (I have it built with quantum-depth 32).

The gm application identifies the image correctly has 8bit

Carnë Draug <carandraug>
Project Member
Thu 13 Feb 2014 11:23:26 PM UTC, comment #1:

Can you provide a script or example of how to demonstrate the error you are describing?

Here's what I did:

No errors or problems that I can see.

Mike Miller <mtmiller>
Project Administrator
Thu 13 Feb 2014 10:36:44 PM UTC, original submission:

iminfo/imread for any fully saturated RGB image will return logical type instead of uint8 if the pixel values are saturated. Same problem in 3.6.4, probably 3.4.3 as well. To test this, create a solid red image, with all pixels = 0xff, green=blue=0. Save as a .bmp or a .png. Try to display it; Octave throws errors. It doesn't matter if .bmp, .png.

If the same image is saved as .jpg, though, Octave is happy, and it displays properly.

Drop the value to 0xfe, image reports and displays properly.



(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach File(s):

Attached Files
file #34429:  example.png added by vak (11KiB - image/png)


Depends on the following items: None found

   bug dependencies.


Carbon-Copy List
  • -unavailable- added by pot
  • -unavailable- added by sebald (Posted a comment)
  • -unavailable- added by vak (Posted a comment)
  • -unavailable- added by mtmiller (Posted a comment)
  • -unavailable- added by None (Submitted the item)

    Do you think this task is very important?
    If so, you can click here to add your encouragement to it.
    This task has 0 encouragements so far.

    Only project members can vote.


    Please enter the title of George Orwell's famous dystopian book (it's a date):



    Follow 10 latest changes.

    Date Changed By Updated Field Previous Value => Replaced By
    Fri 08 Dec 2017 03:28:11 PM UTCpotCarbon-Copy-=>Added pot
    Tue 20 Sep 2016 04:09:14 PM UTCmtmillerDependencies-=>bugs #49140 is dependent
    Sat 04 Jun 2016 05:54:25 PM UTCmtmillerDependencies-=>bugs #48129 is dependent
    Fri 06 Nov 2015 11:50:53 AM UTCcarandraugDependencies-=>bugs #46382 is dependent
    Mon 13 Jul 2015 12:05:50 PM UTCcarandraugRelease3.8.0=>dev
      Operating SystemMicrosoft Windows=>Any
    Mon 13 Jul 2015 07:21:18 AM UTCvakAttached File-=>Added example.png, #34429
    Fri 10 Jul 2015 06:41:19 PM UTCrik5Carbon-CopyRemoved 72865=>-
    Sat 15 Feb 2014 08:04:33 PM UTCrik5StatusNeed Info=>Confirmed
    Thu 13 Feb 2014 11:23:26 PM UTCmtmillerStatusNone=>Need Info

    Back to the top

    Powered by Savane 3.1-cleanup1