Strange result of MagickGetImageChannelRange

The MagickWand interface is a new high-level C API interface to ImageMagick core methods. We discourage the use of the core methods and encourage the use of this API instead. Post MagickWand questions, bug reports, and suggestions to this forum.
Post Reply
jrrose
Posts: 11
Joined: 2011-12-05T08:19:02-07:00
Authentication code: 8675308

Strange result of MagickGetImageChannelRange

Post by jrrose » 2012-02-01T09:15:20-07:00

With 'identify -verbose file' I can show minmal and maximal pixel values, e.g.

rose@moose:/home_moose/rose/Txt/src/Test/C/ImageMagick/Wand(203)$ identify -verbose lena.png
...
Colorspace: RGB
Depth: 8-bit
Channel depth:
red: 8-bit
green: 8-bit
blue: 8-bit
Channel statistics:
Red:
min: 38 (0.14902)
max: 255 (1)
mean: 179.987 (0.705832)
standard deviation: 49.3533 (0.193542)
kurtosis: -0.777526
skewness: -0.690397
Green:
min: 0 (0)
max: 243 (0.952941)
mean: 99.4344 (0.389939)
standard deviation: 52.5844 (0.206213)
kurtosis: -0.740379
skewness: 0.219766
Blue:
min: 9 (0.0352941)
max: 234 (0.917647)
mean: 105.311 (0.412985)
standard deviation: 34.1127 (0.133775)
kurtosis: -0.15
skewness: 0.622583
Image statistics:
Overall:
min: 0 (0)
max: 255 (1)
mean: 128.244 (0.502919)
standard deviation: 46.0599 (0.180627)
kurtosis: 2.6211
skewness: 0.461482
...

I try to get the same information with a small MagickWand program (getChannelRange.c):

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <wand/MagickWand.h>

int main(int argc,char **argv) {

#define ThrowWandException(wand) { \
		description=MagickGetException(wand,&severity);											\
		(void) fprintf(stderr,"%s %s %lu %s\n",GetMagickModule(),description); \
		description=(char *) MagickRelinquishMemory(description);						\
		exit(-1);																														\
	}

  char *description;
  ExceptionType severity;
  MagickBooleanType status;

  /*
    Read an image.
  */
  MagickWandGenesis();
	MagickWand *wand=NewMagickWand();
  status=MagickReadImage(wand,argv[1]);
  if (status == MagickFalse) ThrowWandException(wand);

	double minimum, maximum;

	fprintf(stderr,"RedChannel=%d\n",RedChannel);
	fprintf(stderr,"GreenChannel=%d\n",GreenChannel);
	fprintf(stderr,"BlueChannel=%d\n",BlueChannel);

	MagickGetImageChannelRange(wand,RedChannel,&minimum,&maximum);
	fprintf(stderr,"	  after 'GetImageChannelRange(,RedChannel,)  '   minimum=%13.1f  maximum=%13.1f\n",minimum,maximum);

	MagickGetImageChannelRange(wand,GreenChannel,&minimum,&maximum);
	fprintf(stderr,"	  after 'GetImageChannelRange(,GreenChannel,)'   minimum=%13.1f  maximum=%13.1f\n",minimum,maximum);

	MagickGetImageChannelRange(wand,BlueChannel,&minimum,&maximum);
	fprintf(stderr,"	  after 'GetImageChannelRange(,BlueChannel,) '   minimum=%13.1f  maximum=%13.1f\n",minimum,maximum);

	MagickGetImageChannelRange(wand,GrayChannel,&minimum,&maximum);
	fprintf(stderr,"	  after 'GetImageChannelRange(,GrayChannel,) '   minimum=%13.1f  maximum=%13.1f\n",minimum,maximum);
  wand=DestroyMagickWand(wand);
  MagickWandTerminus();
  return(0);
}
The result of this program is:

rose@moose:/home_moose/rose/Txt/src/Test/C/ImageMagick/Wand(204)$ ./getChannelRange lena.png
RedChannel=1
GreenChannel=2
BlueChannel=4
after 'GetImageChannelRange(,RedChannel,) ' minimum= 640034368.0 maximum= 4294967296.0
after 'GetImageChannelRange(,GreenChannel,)' minimum= 0.0 maximum= 4092851200.0
after 'GetImageChannelRange(,BlueChannel,) ' minimum= 151587088.0 maximum= 3941264128.0
after 'GetImageChannelRange(,GrayChannel,) ' minimum= 640034368.0 maximum= 4294967296.0

I.e. the resulting values are about a factor of 16843009.5... too large. What I am doing wrong. Any hint is deeply appreciated.

jrrose
Posts: 11
Joined: 2011-12-05T08:19:02-07:00
Authentication code: 8675308

Re: Strange result of MagickGetImageChannelRange

Post by jrrose » 2012-02-01T12:13:07-07:00

I assume, that I found the solution:

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <wand/MagickWand.h>

int main(int argc,char **argv) {

#define ThrowWandException(wand) { \
		description=MagickGetException(wand,&severity);\
		(void) fprintf(stderr,"%s %s %lu %s\n",GetMagickModule(),description); \
		description=(char *) MagickRelinquishMemory(description);	\
		exit(-1);	\
	}

  char *description;
  ExceptionType severity;
  MagickBooleanType status;

  /*
    Read an image.
  */
  MagickWandGenesis();
	MagickWand *wand=NewMagickWand();
  status=MagickReadImage(wand,argv[1]);
  if (status == MagickFalse) ThrowWandException(wand);

  double minimum, maximum;
  size_t IM_quantum_depth;
  const char *IM_quantum_depth_str=GetMagickQuantumDepth(&IM_quantum_depth);
  size_t img_depth=MagickGetImageDepth(wand);
  const char *quantum_format=MagickGetImageProperty(wand,"quantum:format");
  fprintf(stderr,"IM_quantum_depth_str=|%s|  IM_quantum_depth=|%lu|  img_depth=%lu  quantum_format=|%s|\n",
             IM_quantum_depth_str,IM_quantum_depth,img_depth,quantum_format);

  fprintf(stderr,"RedChannel=%d\n",RedChannel);
  printf(stderr,"GreenChannel=%d\n",GreenChannel);
  fprintf(stderr,"BlueChannel=%d\n",BlueChannel);

  long long unsigned max_IM_val=1ULL<<IM_quantum_depth;
  long long unsigned max_img_val=(1ULL<<img_depth)-1;

  MagickGetImageChannelRange(wand,RedChannel,&minimum,&maximum);
  fprintf(stderr,"	  after 'GetImageChannelRange(,RedChannel,)  '   minimum=%13.1lf(%5.3lf)  maximum=%13.1lf(%5.3lf)\n",
             max_img_val*minimum/max_IM_val,minimum/max_IM_val,max_img_val*maximum/max_IM_val,maximum/max_IM_val);

  MagickGetImageChannelRange(wand,GreenChannel,&minimum,&maximum);
  fprintf(stderr,"	  after 'GetImageChannelRange(,GreenChannel,)'   minimum=%13.1lf(%5.3lf)  maximum=%13.1lf(%5.3lf)\n",
             max_img_val*minimum/max_IM_val,minimum/max_IM_val,max_img_val*maximum/max_IM_val,maximum/max_IM_val);

  MagickGetImageChannelRange(wand,BlueChannel,&minimum,&maximum);
  fprintf(stderr,"	  after 'GetImageChannelRange(,BlueChannel,) '   minimum=%13.1lf(%5.3lf)  maximum=%13.1lf(%5.3lf)\n",
            max_img_val*minimum/max_IM_val,minimum/max_IM_val,max_img_val*maximum/max_IM_val,maximum/max_IM_val);

  MagickGetImageChannelRange(wand,GrayChannel,&minimum,&maximum);
  fprintf(stderr,"	  after 'GetImageChannelRange(,GrayChannel,) '   minimum=%13.1lf(%5.3lf)  maximum=%13.1lf(%5.3lf)\n",
             max_img_val*minimum/max_IM_val,minimum/max_IM_val,max_img_val*maximum/max_IM_val,maximum/max_IM_val);

  wand=DestroyMagickWand(wand);
  MagickWandTerminus();
  return(0);
}

jrrose
Posts: 11
Joined: 2011-12-05T08:19:02-07:00
Authentication code: 8675308

Re: Strange result of MagickGetImageChannelRange

Post by jrrose » 2012-02-01T12:16:33-07:00

The result is now:

rose@moose:/home_moose/rose/Txt/src/Test/C/ImageMagick/Wand(268)$ ./getChannelRange lena.png
IM_quantum_depth_str=|Q32| IM_quantum_depth=|32| img_depth=8 quantum_format=|(null)|
RedChannel=1
GreenChannel=2
BlueChannel=4
after 'GetImageChannelRange(,RedChannel,) ' minimum= 38.0(0.149) maximum= 255.0(1.000)
after 'GetImageChannelRange(,GreenChannel,)' minimum= 0.0(0.000) maximum= 243.0(0.953)
after 'GetImageChannelRange(,BlueChannel,) ' minimum= 9.0(0.035) maximum= 234.0(0.918)
after 'GetImageChannelRange(,GrayChannel,) ' minimum= 38.0(0.149) maximum= 255.0(1.000)


So the values are as expected. But I am not yet completely convinced, that this procedure will work for all all kind of images, i.e. for all kind of image formats, image depth and quantum formats.

Post Reply