Page 1 of 2

problems with Magick::Pixels

Posted: 2017-11-04T08:37:12-07:00
by Straton
Hi,

my last posting was 2013, where I successfully integrated ImageMagick for reading and writing 16-bit gray image files in my C++ software. Now I am working on a completely new version from scratch on. For some reason, I fail doing even the simplest things with ImageMagick and I don't know what happens. Any help would be much appreciated. Currently I am working with ImageMagick 7.0.7-0 Q16 x86_64 on a Mac.

Please have a look on this code (stripped down without error detection and other things, hopefully I introduced no issues doing this):

Code: Select all

Magick::Image img;
img.read("Mars_gray.tif");
Magick::Pixels view(img);
const uint16_t* pixels = view.getConst(0,0,img.columns(), img.rows());
for (int i=0; i<20; ++i)
{
  std::cout << i << ": " << (int)pixels[i] << " " << (int)pixels[i]/256 << std::endl;
}
Output is:

Code: Select all

0: 50432 197
1: 18245 71
2: 50432 197
3: 18245 71
4: 50176 196
5: 18244 71
6: 50432 197
7: 18245 71
8: 50688 198
9: 18246 71
10: 50944 199
11: 18247 71
12: 51200 200
13: 18248 71
14: 51200 200
15: 18248 71
16: 50944 199
17: 18247 71
18: 50432 197
19: 18245 71
If you have a look into the image (using for example Fitswork), the pixel values of the first image row start with

197, 197, 196, 197, 198, 199, 200, 200, 199, 197

Each of them is represented by a 2-byte-value, as expected. What the hell are the other two bytes (18245) following each pixel value?

You can download this image here: Mars_gray.tif. I created it for testing purposes and it is a special case, since I identify says

Code: Select all

Depth: 16/8-bit
Channel depth:
    Gray: 8-bit
With my true test images, identify says

Code: Select all

Depth: 16-bit
Channel depth:
    Gray: 16-bit
With those, things are even worse, i. e. then I recognize no correlation of above test prints with the pixel values I see in Fitswork at all. So let's start step by step. In all cases there is only 1 channel.

Best regards,
Stefan

Re: problems with Magick::Pixels

Posted: 2017-11-04T08:47:55-07:00
by snibgo
IM v7 has many differences to IM v6. See http://www.imagemagick.org/script/porting.php . I suggest you stick with v6 until you are ready to upgrade to v7.

Re: problems with Magick::Pixels

Posted: 2017-11-04T09:04:51-07:00
by Straton
I am rewriting from scratch. On Mac, there isn‘t even a previous version. Since v7 was normally released, I see no reason not to use it. So I avoid any need to port later to v7.

In addition I thought my question was really simple, isn‘t it? All I want to do is read an image file and access the pixel data. Basically as described in https://www.imagemagick.org/Magick++/Pixels.html - but in my case it's even simpler, since I only need to handle 1-channel-images and all have depth 16.

Re: problems with Magick::Pixels

Posted: 2017-11-04T09:52:12-07:00
by snibgo
Your code assumes the image, as read, has one channel.

Re: problems with Magick::Pixels

Posted: 2017-11-04T10:12:17-07:00
by Straton
yes? As said, I only need to handle a very restricted subset of image types. All have 1 channel, all have 16 bit depth. I use ImageMagick just because of the image format reading and writing capabilities, for no other reason. 2013 I reported bugs in the FITS format reading and writing, which have been fixed then.

So now I want to do the very same thing - read a 16 bit 1-channel gray image from TIF or FITS and access the pixel data.

Re: problems with Magick::Pixels

Posted: 2017-11-04T10:41:23-07:00
by snibgo
Straton wrote:All have 1 channel, ...
Your code assumes this, but doesn't check. Perhaps the assumption is wrong. Your test suggests the assumption is wrong.

Re: problems with Magick::Pixels

Posted: 2017-11-04T18:12:58-07:00
by Straton
My original code includes such checks, including error checking. I cannot do more than say what I know. If you don't believe me, please download the image and check the number of channels.

Re: problems with Magick::Pixels

Posted: 2017-11-04T18:56:21-07:00
by fmw42
I know nothing about coding in C++. But using EXIFTOOL to review your file's meta data, I think it is 3 channel data RGB with the same data in each channel. And it has a color profile. Perhaps I misunderstand what EXIFTOOL is saying.

exiftool -s -ee -g1 -u -n -D Mars_gray_preview.jpeg
---- ExifTool ----
- ExifToolVersion : 10.51
---- System ----
- FileName : Mars_gray_preview.jpeg
- Directory : .
- FileSize : 215498
- FileModifyDate : 2017:11:04 18:46:54-07:00
- FileAccessDate : 2017:11:04 18:47:13-07:00
- FileInodeChangeDate : 2017:11:04 18:46:54-07:00
- FilePermissions : 644
---- File ----
- FileType : JPEG
- FileTypeExtension : JPG
- MIMEType : image/jpeg
- ImageWidth : 960
- ImageHeight : 970
- EncodingProcess : 0
- BitsPerSample : 8
- ColorComponents : 3
- YCbCrSubSampling : 2 2
---- JFIF ----
0 JFIFVersion : 1 1
2 ResolutionUnit : 0
3 XResolution : 1
5 YResolution : 1
---- ICC-header ----
4 ProfileCMMType :
8 ProfileVersion : 0
12 ProfileClass : mntr
16 ColorSpaceData : RGB
20 ProfileConnectionSpace : XYZ
24 ProfileDateTime : 2014:06:04 17:43:56
36 ProfileFileSignature : acsp
40 PrimaryPlatform :
44 CMMFlags : 0
48 DeviceManufacturer :
52 DeviceModel :
56 DeviceAttributes : 1 0
64 RenderingIntent : 0
68 ConnectionSpaceIlluminant : 0.9642 1 0.82491
80 ProfileCreator :
84 ProfileID : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
---- ICC_Profile ----
- ProfileDescription : sRGB IEC61966-2-1 black scaled
- MediaBlackPoint : 0.01205 0.0125 0.01031
- MediaWhitePoint : 0.9642 1 0.82491
- ProfileCopyright : Dropbox, Inc.
- RedMatrixColumn : 0.43607 0.22249 0.01392
- GreenMatrixColumn : 0.38515 0.71687 0.09708
- BlueMatrixColumn : 0.14307 0.06061 0.7141
- RedTRC : (Binary data 64 bytes, use -b option to extract)
- GreenTRC : (Binary data 64 bytes, use -b option to extract)
- BlueTRC : (Binary data 64 bytes, use -b option to extract)
---- Composite ----
- ImageSize : 960x970
- Megapixels : 0.9312


Using IM 7 to strip the profile and convert to grayscale with:

Code: Select all

magick Mars_gray_preview.jpeg -strip -colorspace gray  Mars_gray_preview2.jpg
Then I get 1 channel:

exiftool -s -ee -g1 -u -n -D Mars_gray_preview2.jpg
---- ExifTool ----
- ExifToolVersion : 10.51
---- System ----
- FileName : Mars_gray_preview2.jpg
- Directory : .
- FileSize : 208398
- FileModifyDate : 2017:11:04 18:53:51-07:00
- FileAccessDate : 2017:11:04 18:54:07-07:00
- FileInodeChangeDate : 2017:11:04 18:53:51-07:00
- FilePermissions : 644
---- File ----
- FileType : JPEG
- FileTypeExtension : JPG
- MIMEType : image/jpeg
- ImageWidth : 960
- ImageHeight : 970
- EncodingProcess : 0
- BitsPerSample : 8
- ColorComponents : 1
---- JFIF ----
0 JFIFVersion : 1 1
2 ResolutionUnit : 0
3 XResolution : 1
5 YResolution : 1
---- Composite ----
- ImageSize : 960x970
- Megapixels : 0.9312

Re: problems with Magick::Pixels

Posted: 2017-11-04T19:13:50-07:00
by snibgo
@Fred: you are looking at the preview JPEG, not the downloaded larger image.

@Straton: The contents of the file don't matter. You are looking at values after they have been read.

I suppose you are not using HDRI? Because then the "Quantum" data type isn't "uint16_t". What does "magick -version" say?

Re: problems with Magick::Pixels

Posted: 2017-11-04T19:48:01-07:00
by fmw42
@snibgo: It was the only image that had a link. So I thought that was what he asked us to review. But you know more about all this. So I will leave it to you to continue.

Re: problems with Magick::Pixels

Posted: 2017-11-05T03:45:13-07:00
by Straton
C++ doesn't allow implicit conversion of pointer types. If Quantum wasn't 2-byte, above code wouldn't compile. No warning, just an error. Nevertheless:

Code: Select all

/opt/bin> ./magick  -version
Version: ImageMagick 7.0.7-0 Q16 x86_64 2017-08-29 http://www.imagemagick.org
Copyright: © 1999-2017 ImageMagick Studio LLC
License: http://www.imagemagick.org/script/license.php
Features: Cipher DPC HDRI 
Delegates (built-in): bzlib fontconfig freetype jng jp2 jpeg lcms pangocairo png tiff xml zlib

Re: problems with Magick::Pixels

Posted: 2017-11-05T05:03:59-07:00
by snibgo
Straton wrote:HDRI
That's a problem. Probably the problem. Your pixels are stored as floating point, not integer.

getConst returns a pointer to Quantum. This datatype is floating-point for HDRI. It isn't advised to make any assumptions about this; explicitly convert values as required.

Re: problems with Magick::Pixels

Posted: 2017-11-05T05:50:40-07:00
by Straton
If Quantum was different from uint16_t (like with float), the C++ compiler would issue an error. This is the reason that I use uint16_t instead of Quantum. It avoids any problems with configurations my code does not support anyway. So it is impossible that Quantum is float in my configuration. If you don't believe me, please try to compile that code:

Code: Select all

float* p;
uint16_t* a = p;
In addition my IDE's code completion confirms that Quantum is uint16_t in my configuration: https://www.dropbox.com/s/52ynw48tyhatk ... e.png?dl=0

Re: problems with Magick::Pixels

Posted: 2017-11-05T06:01:08-07:00
by snibgo
In that case, you are running more than one version of IM.

Running multiple versions isn't a problem, with care. But if you accidentally run multiple versions, you can expect problems.

I suggest you remove all versions of IM. Then install just one. Before you install, decide if you want HDRI or not.

Re: problems with Magick::Pixels

Posted: 2017-11-05T06:02:54-07:00
by dlemstra
It looks like you are using header files that have HDRI disabled. And linking with a library that has HDRI enabled.