Mercurial > hg > octave-lyh
changeset 17342:f8ee0ed7f1b8
Fix reading of binary images.
* __magick_read__.cc (__magick_read__): since depth() seems to not always
give 1 for binary images, check the depth of multiple channels to confirm.
author | Carnë Draug <carandraug@octave.org> |
---|---|
date | Wed, 28 Aug 2013 08:24:21 +0100 |
parents | 51c011825bcc |
children | 583306fe7e4f |
files | libinterp/dldfcn/__magick_read__.cc |
diffstat | 1 files changed, 39 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/dldfcn/__magick_read__.cc +++ b/libinterp/dldfcn/__magick_read__.cc @@ -668,8 +668,28 @@ } } - const Magick::ClassType klass = imvec[frameidx(0)].classType (); - const octave_idx_type depth = imvec[frameidx(0)].depth (); + // FIXME: the depth here is not always correct for us but seems to be the best + // value we can get. For example, a grayscale png image with 1 bit + // per channel should return a depth of 1 but instead we get 8. + // We could check channelDepth() but then, which channel has the data + // is not straightforward. So we'd have to check all + // the channels and select the highest value. But then, I also + // have a 16bit TIFF whose depth returns 16 (correct), but all of the + // channels gives 8 (wrong). No idea why, maybe a bug in GM? + // Anyway, using depth() seems that only causes problems for binary + // images, and the problem with channelDepth() is not making set them + // all to 1. So we will guess that if all channels have depth of 1, + // then we must have a binary image. + // Note that we can't use AllChannels it doesn't work for this. + // Instead of checking all of the individual channels, we check one + // from RGB, CMYK, grayscale, and transparency. + octave_idx_type depth = imvec[frameidx(0)].depth (); + if (depth != 1 + && imvec[frameidx(0)].channelDepth (Magick::RedChannel) == 1 + && imvec[frameidx(0)].channelDepth (Magick::CyanChannel) == 1 + && imvec[frameidx(0)].channelDepth (Magick::OpacityChannel) == 1 + && imvec[frameidx(0)].channelDepth (Magick::GrayChannel) == 1) + depth = 1; // Magick::ClassType // PseudoClass: @@ -677,6 +697,7 @@ // DirectClass: // Image is composed of pixels which represent literal color values. + Magick::ClassType klass = imvec[frameidx(0)].classType (); // FIXME: GraphicsMagick does not really distinguishes between indexed and // normal images. After reading a file, it decides itself the optimal // way to store the image in memory, independently of the how the @@ -684,11 +705,23 @@ // it seems to match the original file most of the times, this is // not necessarily true all the times. See // https://sourceforge.net/mailarchive/message.php?msg_id=31180507 - // A grayscale jpeg image reports being indexed even though the JPEG - // format has no support for indexed images. So we can skip at least - // for that. + // In addition to the ClassType, there is also ImageType which has a + // type for indexed images (PaletteType and PaletteMatteType). However, + // they also don't represent the original image. Interestingly, one + // would at least guess that PseudoClass would include only the Palette + // types but that does not happen. + // + // We can't do better without having format specific code which is + // what we are trying to avoid by using a library such as GM. We at + // least create workarounds for the most common problems. - if (klass == Magick::PseudoClass && imvec[0].magick () != "JPEG") + // 1) A grayscale jpeg image can report being indexed even though the + // JPEG format has no support for indexed images. We can at least + // fix this one. + if (klass == Magick::PseudoClass && imvec[0].magick () == "JPEG") + klass = Magick::DirectClass; + + if (klass == Magick::PseudoClass) { if (depth <= 1) output = read_indexed_images<boolNDArray> (imvec, frameidx,