Requesting quantum format from MagickCore and MagickWand API
Requesting quantum format from MagickCore and MagickWand API
I have some pictures, where 'identify -verbose' says "quantum:format: floating-point". I want to save the pixels of these and other images with GetOneAuthenticPixel in MagickCore and with MagickExportImagePixels in MagickWand to a long or a double array. To do this, I want to decide from the MagickCore and MagickWand API, what is the quantum:format of my input images. I am looking for something like a function GetQuantumFormat(), I found only SetQuantumFormat() for MagickCore. I tried also:
QuantumInfo *quantum_info=AcquireQuantumInfo(image_info,img);
if (quantum_info->format == FloatingPointQuantumFormat) {
fprintf(stderr,"FloatingPointQuantumFormat found!\n");
}
But the compiler says:
print_tiff_asc_Core.c:119:38: error: dereferencing pointer to incomplete type
I have imagemagick-6.7.3.0 compiled under gentoo with the hdri q32 USE flags.
Any hint is deeply appreciated.
QuantumInfo *quantum_info=AcquireQuantumInfo(image_info,img);
if (quantum_info->format == FloatingPointQuantumFormat) {
fprintf(stderr,"FloatingPointQuantumFormat found!\n");
}
But the compiler says:
print_tiff_asc_Core.c:119:38: error: dereferencing pointer to incomplete type
I have imagemagick-6.7.3.0 compiled under gentoo with the hdri q32 USE flags.
Any hint is deeply appreciated.
Re: Requesting quantum format from MagickCore and MagickWand
Every setter should have a getter. We added GetQuantumFormat() to ImageMagick 6.7.4-0 available as beta by sometime tomorrow. Look for a release within the next week or two.
Re: Requesting quantum format from MagickCore and MagickWand
Thanks magick,
I will wait for GetQuantumFormat(). But in the meantime is there any other solution to get information from the Core or Wand API whether a image has long or float pixel?
Regards Juergeen
I will wait for GetQuantumFormat(). But in the meantime is there any other solution to get information from the Core or Wand API whether a image has long or float pixel?
Regards Juergeen
Re: Requesting quantum format from MagickCore and MagickWand
Use
- const char *option=GetImageOption(image_info,"quantum:format");
Re: Requesting quantum format from MagickCore and MagickWand
It seems that
const char *option=GetImageOption(image_info,"quantum:format");
does not work for me. I use the following source:
with MagickCore and
With MagickWand. I tested the programs resulting from both sources with three small files:
rose@moose:/home_moose/rose/Txt/projects/MicroElectrodes/Test/GetOneAuthenticPixel_versus_MagickExportImagePixels(471)$ ll input__*.tif*
-rw-r----- 1 rose rose 4183 6. Dez 14:34 input__16BitsGray-16Bits_quantum_format_long.tiff (http://141.89.194.24/~rose/input__16Bit ... _long.tiff)
-rw-r----- 1 rose rose 4629 8. Dez 17:48 input__29BitsGray-32Bits_quantum_format_float.tiff (http://141.89.194.24/~rose/input__29Bit ... float.tiff)
-rw-r----- 1 rose rose 14817 5. Dez 16:48 input__32BitsGray-32Bits_quantum_format_float.tiff (http://141.89.194.24/~rose/input__32Bit ... float.tiff)
using the script get_quantuminfo.sh:
rose@moose:/home_moose/rose/Txt/projects/MicroElectrodes/Test/GetOneAuthenticPixel_versus_MagickExportImagePixels(475)$ cat get_quantuminfo.sh
The result is:
rose@moose:/home_moose/rose/Txt/projects/MicroElectrodes/Test/GetOneAuthenticPixel_versus_MagickExportImagePixels(477)$ ./get_quantuminfo.sh
================= f=input__16BitsGray-16Bits_quantum_format_long.tiff =================
-------- before 'identify -verbose $f | grep quantum:format' ------------
-------- before './get_quantuminfo_Core $f' ------------
after ReadImage() magick_precision=6 imgs=0x1d0ccf0 imgs->next=(nil)
depth=16 gray_channel_depth=16 quantum_depth=16
quantum_format=|'is not defined'|
-------- before './get_quantuminfo_Wand $f' ------------
depth=16 gray_channel_depth=16
quantum_format=||
================= f=input__29BitsGray-32Bits_quantum_format_float.tiff =================
-------- before 'identify -verbose $f | grep quantum:format' ------------
quantum:format: floating-point
-------- before './get_quantuminfo_Core $f' ------------
after ReadImage() magick_precision=6 imgs=0x6ebcf0 imgs->next=(nil)
depth=29 gray_channel_depth=29 quantum_depth=32
quantum_format=|'is not defined'|
-------- before './get_quantuminfo_Wand $f' ------------
depth=32 gray_channel_depth=29
quantum_format=||
================= f=input__32BitsGray-32Bits_quantum_format_float.tiff =================
-------- before 'identify -verbose $f | grep quantum:format' ------------
quantum:format: floating-point
-------- before './get_quantuminfo_Core $f' ------------
after ReadImage() magick_precision=6 imgs=0x1da0cf0 imgs->next=(nil)
depth=32 gray_channel_depth=32 quantum_depth=32
quantum_format=|'is not defined'|
-------- before './get_quantuminfo_Wand $f' ------------
depth=32 gray_channel_depth=32
quantum_format=||
I.e., "identify -verbose" finds that two files have the quantum:format: floating-point, while GetImageOption(image_info,"quantum:format") gives a Null-pointer and MagickGetOption(wand,"quantum:format") gives a
pointer to an empty string. What I am doing wrong?
Btw. in the case of the input file input__29BitsGray-32Bits_quantum_format_float.tiff using MagickCore, GetImageDepth() and GetImageChannelDepth() return 29Bits and GetImageQuantumDepth() returns 32Bits,
while using MagickWand MagickGetImageDepth() returns 32Bits and MagickGetImageChannelDepth() returns 29Bits. I.e., MagickWand MagickGetImageDepth() corresponds to GetImageQuantumDepth() and not to GetImageDepth(). Is this intentionally?
const char *option=GetImageOption(image_info,"quantum:format");
does not work for me. I use the following source:
Code: Select all
#include <stdio.h>
#include <string.h>
#include <magick/MagickCore.h>
int main (int argc, char *argv[]) {
MagickCoreGenesis(*argv,MagickTrue);
ExceptionInfo *exception=AcquireExceptionInfo();
ImageInfo *image_info=CloneImageInfo((ImageInfo *) NULL);
int magick_precision=GetMagickPrecision();
(void) strcpy(image_info->filename,argv[1]);
Image *imgs = ReadImages(image_info,exception);
if (exception->severity != UndefinedException) CatchException(exception);
size_t depth=GetImageDepth(imgs,&imgs->exception);
ChannelType channel=GrayChannel;
size_t gray_channel_depth=GetImageChannelDepth(imgs,channel,
&imgs->exception);
MagickBooleanType constrain=MagickFalse;
size_t quantum_depth=GetImageQuantumDepth(imgs,constrain);
printf("depth=%lu gray_channel_depth=%lu quantum_depth=%lu\n",
depth,gray_channel_depth,quantum_depth);
const char *quantum_format=GetImageOption(image_info,"quantum:format");
printf("quantum_format=|%s|\n",
quantum_format?quantum_format:"'is not defined'");
image_info=DestroyImageInfo(image_info);
exception=DestroyExceptionInfo(exception);
MagickCoreTerminus();
return 0;
}
Code: Select all
#include <stdio.h>
#include <string.h>
#include <wand/magick_wand.h>
#define ThrowWandException(wand) { \
ExceptionType severity; \
char *description=MagickGetException(wand,&severity); \
(void) fprintf(stderr,"%s %s %ld %s\n",GetMagickModule(),description); \
description=(char *) MagickRelinquishMemory(description); \
exit(-1); \
}
int main (int argc, char *argv[]) {
MagickWandGenesis();
MagickWand *wand=NewMagickWand();
int status=MagickReadImage(wand,argv[1]);
if (status == MagickFalse) ThrowWandException(wand);
size_t depth=MagickGetImageDepth(wand);
ChannelType channel=GrayChannel;
size_t gray_channel_depth=MagickGetImageChannelDepth(wand,channel);
printf("depth=%lu gray_channel_depth=%lu\n",
depth,gray_channel_depth);
const char *quantum_format=MagickGetOption(wand,"quantum:format");
printf("quantum_format=|%s|\n",
quantum_format?quantum_format:"'is not defined'");
if(wand != NULL) wand=DestroyMagickWand(wand);
MagickWandTerminus();
return 0;
}
rose@moose:/home_moose/rose/Txt/projects/MicroElectrodes/Test/GetOneAuthenticPixel_versus_MagickExportImagePixels(471)$ ll input__*.tif*
-rw-r----- 1 rose rose 4183 6. Dez 14:34 input__16BitsGray-16Bits_quantum_format_long.tiff (http://141.89.194.24/~rose/input__16Bit ... _long.tiff)
-rw-r----- 1 rose rose 4629 8. Dez 17:48 input__29BitsGray-32Bits_quantum_format_float.tiff (http://141.89.194.24/~rose/input__29Bit ... float.tiff)
-rw-r----- 1 rose rose 14817 5. Dez 16:48 input__32BitsGray-32Bits_quantum_format_float.tiff (http://141.89.194.24/~rose/input__32Bit ... float.tiff)
using the script get_quantuminfo.sh:
rose@moose:/home_moose/rose/Txt/projects/MicroElectrodes/Test/GetOneAuthenticPixel_versus_MagickExportImagePixels(475)$ cat get_quantuminfo.sh
Code: Select all
#!/bin/bash
for f in input__*.tif* ; do
echo "================= f=$f =================";
cmd='identify -verbose $f | grep quantum:format'
echo "-------- before '$cmd' ------------"; eval $cmd 2>/dev/null
cmd='./get_quantuminfo_Core $f'
echo "-------- before '$cmd' ------------"; eval $cmd 2>/dev/null
cmd='./get_quantuminfo_Wand $f'
echo "-------- before '$cmd' ------------"; eval $cmd 2>/dev/null
done
rose@moose:/home_moose/rose/Txt/projects/MicroElectrodes/Test/GetOneAuthenticPixel_versus_MagickExportImagePixels(477)$ ./get_quantuminfo.sh
================= f=input__16BitsGray-16Bits_quantum_format_long.tiff =================
-------- before 'identify -verbose $f | grep quantum:format' ------------
-------- before './get_quantuminfo_Core $f' ------------
after ReadImage() magick_precision=6 imgs=0x1d0ccf0 imgs->next=(nil)
depth=16 gray_channel_depth=16 quantum_depth=16
quantum_format=|'is not defined'|
-------- before './get_quantuminfo_Wand $f' ------------
depth=16 gray_channel_depth=16
quantum_format=||
================= f=input__29BitsGray-32Bits_quantum_format_float.tiff =================
-------- before 'identify -verbose $f | grep quantum:format' ------------
quantum:format: floating-point
-------- before './get_quantuminfo_Core $f' ------------
after ReadImage() magick_precision=6 imgs=0x6ebcf0 imgs->next=(nil)
depth=29 gray_channel_depth=29 quantum_depth=32
quantum_format=|'is not defined'|
-------- before './get_quantuminfo_Wand $f' ------------
depth=32 gray_channel_depth=29
quantum_format=||
================= f=input__32BitsGray-32Bits_quantum_format_float.tiff =================
-------- before 'identify -verbose $f | grep quantum:format' ------------
quantum:format: floating-point
-------- before './get_quantuminfo_Core $f' ------------
after ReadImage() magick_precision=6 imgs=0x1da0cf0 imgs->next=(nil)
depth=32 gray_channel_depth=32 quantum_depth=32
quantum_format=|'is not defined'|
-------- before './get_quantuminfo_Wand $f' ------------
depth=32 gray_channel_depth=32
quantum_format=||
I.e., "identify -verbose" finds that two files have the quantum:format: floating-point, while GetImageOption(image_info,"quantum:format") gives a Null-pointer and MagickGetOption(wand,"quantum:format") gives a
pointer to an empty string. What I am doing wrong?
Btw. in the case of the input file input__29BitsGray-32Bits_quantum_format_float.tiff using MagickCore, GetImageDepth() and GetImageChannelDepth() return 29Bits and GetImageQuantumDepth() returns 32Bits,
while using MagickWand MagickGetImageDepth() returns 32Bits and MagickGetImageChannelDepth() returns 29Bits. I.e., MagickWand MagickGetImageDepth() corresponds to GetImageQuantumDepth() and not to GetImageDepth(). Is this intentionally?
Re: Requesting quantum format from MagickCore and MagickWand
We patched ImageMagick 6.7.0-0 Beta so that MagickGetImageDepth() computes the depth as it already does for ImageMagick 7.0.0-0 alpha. Thanks.
Re: Requesting quantum format from MagickCore and MagickWand
But what about the main problem the identification of quantum:format?
Re: Requesting quantum format from MagickCore and MagickWand
That's in ImageMagick 6.7.4-0 Beta as well. We should have a release with the next week.
Re: Requesting quantum format from MagickCore and MagickWand
I repeated the test with ImageMagick 6.7.4-0:
rose@moose:/home_moose/rose/Txt/projects/MicroElectrodes/Test/GetOneAuthenticPixel_versus_MagickExportImagePixels(741)$ identify -version
Version: ImageMagick 6.7.4-0 2011-12-12 Q32 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2011 ImageMagick Studio LLC
Features: OpenMP HDRI
But the behaviour of GetImageOption(image_info,"quantum:format") did not changed, the only way to determine the quantum format I found is to parse the output of IdentifyImage(img,T_FILE,MagickTrue) or MagickIdentifyImage(wand), which works but it is not very elegant.
Now with ImageMagick 6.7.4-0 GetImageDepth() and MagickGetImageDepth() return both 29 Bit for my file input__29BitsGray-32Bits_quantum_format_float.tiff. But I did not found any way to identify from the MagickWand-API, that there is 32 Bit information in the file. MagickGetImageDepth() and MagickGetImageChannelDepth(wand,channel) return 29 Bit. I am missing a function MagickGetImageQuantumDepth() (in MagickCore I have GetImageQuantumDepth()). So I have to parse again the output of MagickIdentifyImage().
Is there any shorter way to get these information (quantum_format for MagickCore, quantum_depth and quantum_format for MagickWand) without using the Identity functions and in particular in case of MagickCore without writing and reading of files to and from disk?
rose@moose:/home_moose/rose/Txt/projects/MicroElectrodes/Test/GetOneAuthenticPixel_versus_MagickExportImagePixels(741)$ identify -version
Version: ImageMagick 6.7.4-0 2011-12-12 Q32 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2011 ImageMagick Studio LLC
Features: OpenMP HDRI
But the behaviour of GetImageOption(image_info,"quantum:format") did not changed, the only way to determine the quantum format I found is to parse the output of IdentifyImage(img,T_FILE,MagickTrue) or MagickIdentifyImage(wand), which works but it is not very elegant.
Code: Select all
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <pcre.h>
#include <magick/MagickCore.h>
typedef struct {
ClassType storage_class;
const char *Class_str; // directly from identify
const char *image_type_str;
size_t height, width;
const char *Depth_str;
size_t depth_from_depth_str;
size_t quantum_depth_from_depth_str;
size_t depth;
//const char *quantum_depth_str;
size_t quantum_depth;
const char *color_space_string;
const char *compression_type_str;
size_t gray_channel_depth;
MagickBooleanType is_gray_image;
const char *quantum_format_str; // directly from identify
const char *quantum_format;
size_t n_imgs;
double x_resolution,y_resolution;
double gamma;
const char *gravity_type_str;
QuantumType quantum_type;
size_t quantum_extent;
MagickBooleanType is_high_dynamic_range;
const char *min_str, *max_str; // directly from identify
double minimum, maximum;
const char *mean_str, *stdev_str; // directly from identify
double mean, stdev;
ChannelFeatures *channel_features;
} Image_Info;
#define OVECCOUNT 30 /* should be a multiple of 3 */
//#define DEBUG 1
int main (int argc, char *argv[]) {
int rc,erroffset;
char *pat;
pcre *re;
const char *error;
int ovector[OVECCOUNT];
const char *Level1_Attribut, *Level2_Attribut;
MagickCoreGenesis(*argv,MagickTrue);
ExceptionInfo *exception=AcquireExceptionInfo();
ImageInfo *image_info=CloneImageInfo((ImageInfo *) NULL);
int magick_precision=GetMagickPrecision();
(void) strcpy(image_info->filename,argv[1]);
Image *imgs = ReadImages(image_info,exception);
if (exception->severity != UndefinedException) CatchException(exception);
if (imgs == (Image *) NULL) {
fprintf(stderr,"imgs is not defined\n"); exit(1);
}
printf("after ReadImage() magick_precision=%d imgs=%p imgs->next=%p\n",
magick_precision,imgs,imgs->next);
Image_Info *image_Info=(Image_Info *)malloc(sizeof(Image_Info));
MagickBooleanType constrain=MagickFalse;
image_Info->quantum_depth=GetImageQuantumDepth(imgs,constrain);
image_Info->quantum_format=GetImageOption(image_info,"quantum:format");
image_Info->depth=GetImageDepth(imgs,&imgs->exception);
ChannelType channel=GrayChannel;
image_Info->gray_channel_depth=GetImageChannelDepth(imgs,channel,
&imgs->exception);
image_Info->Class_str=0; char Class_str_aux[1024];
image_Info->Depth_str=0; char Depth_str_aux[1024];
image_Info->quantum_format_str=0; char quantum_format_str_aux[1024];
image_Info->min_str=0; char min_str_aux[1024];
image_Info->max_str=0; char max_str_aux[1024];
image_Info->mean_str=0; char mean_str_aux[1024];
image_Info->stdev_str=0; char stdev_str_aux[1024];
pid_t pid=getpid(); //Ermitteln des aktuellen Prozesses
fprintf(stderr,"pid=%d\n",pid);
char tmp_file[1024];
sprintf(tmp_file,"/tmp/image_identify_%d\n",pid);
FILE *T_FILE=fopen(tmp_file,"w");
if (T_FILE == NULL) {
fprintf(stderr,"ERROR opening %s for writing\n",tmp_file);
exit(EXIT_FAILURE);
}
const MagickBooleanType verbose=MagickTrue;
MagickBooleanType status=IdentifyImage(imgs,T_FILE,verbose);
fclose(T_FILE);
T_FILE=fopen(tmp_file,"r");
if (T_FILE == NULL) {
fprintf(stderr,"ERROR opening %s for reading\n",tmp_file);
exit(EXIT_FAILURE);
}
#define BUFLEN 1024
char *line = NULL;
char s0[BUFLEN+1],s1[BUFLEN+1],s2[BUFLEN+1];
size_t len=BUFLEN;
size_t read;
int Channel_stat=0, Gray_Channel=0;
while ((read = getline(&line, &len, T_FILE)) != -1) {
//printf("Retrieved line of length %zu : len=%lu\n", read,len);
if ( line[strlen(line)-1] == '\n' ) line[strlen(line)-1]=0;
#ifdef DEBUG
fprintf(stderr,"line=|%s|\n",line);
#endif
if(!(re=pcre_compile("^[\\s]*$",0,&error,&erroffset,NULL))) {
printf("PCRE compilation failed at offset %d: %s\n", erroffset, error);
exit(1);
}
if(pcre_exec(re,NULL,line,(int)strlen(line),0,0,ovector,OVECCOUNT)>=0) {
#ifdef DEBUG
fprintf(stderr,"Empty line found\n");
#endif
} else {
pat="([\\s]*)(.*)[\\s]*:[\\s]*(.*)[\\s]*$";
//pat="[\\s]*quantum:format[\\s]*:[\\s]*(.*)[\\s]*$";
//fprintf(stderr,"before testing pat=|%s| line=|%s|\n",pat,line);
if(!(re=pcre_compile(pat,0,&error,&erroffset,NULL))) {
fprintf(stderr,"PCRE compilation failed at offset %d: %s\n",erroffset,error);
exit(1);
}
rc = pcre_exec(re,NULL,line,(int)strlen(line),0,0,ovector,OVECCOUNT);
/* Matching failed: handle error cases */
if (rc < 0) {
switch(rc) {
case PCRE_ERROR_NOMATCH:
//fprintf(stderr,"No match in tmp_file=|%s| line=|%s|\n",tmp_file,line);
//exit(2);
break;
/*
Handle other special cases if you like
*/
default:
fprintf(stderr,"Matching error %d in tmp_file=|%s| line=|%s|\n",
rc,tmp_file,line);
exit(2);
break;
}
} else {
/* Match succeded */
#ifdef DEBUG
fprintf(stderr," Match succeeded\n");
#endif
/* The output vector wasn't big enough */
if (rc == 0) {
rc = OVECCOUNT/3;
fprintf(stderr,"ovector only has room for %d captured substrings\n",
rc-1);
}
#ifdef DEBUG
/* Show substrings stored in the output vector */
int i;
for(i=0; i<rc; i++) {
char *substring_start = line+ovector[2*i];
int substring_length = ovector[2*i+1]-ovector[2*i];
fprintf(stderr," %2d: |%.*s|\n",i,substring_length,substring_start);
}
#endif
strncpy(s0,line+ovector[2],ovector[2+1]-ovector[2]);
strncpy(s1,line+ovector[4],ovector[4+1]-ovector[4]);
strncpy(s2,line+ovector[6],ovector[6+1]-ovector[6]);
s0[ovector[2+1]-ovector[2]]=0;
s1[ovector[4+1]-ovector[4]]=0;
s2[ovector[6+1]-ovector[6]]=0;
#ifdef DEBUG
fprintf(stderr,"strlen(s0)=%4lu s1=|%s| s2=|%s|\n",strlen(s0),s1,s2);
#endif
if (strlen(s0)==2) {
Level1_Attribut=s1;
Channel_stat=0;
if (!strcmp(s1,"Channel statistics")) {
Channel_stat=1;
}
}
if (strlen(s0)==4) {
Level2_Attribut=s1;
if (Channel_stat==1) {
if (!strcmp(s1,"Gray")) {
Gray_Channel=1;
}
}
}
if (!strcmp(s1,"Class")) {
strcpy(Class_str_aux,s2);
image_Info->Class_str=Class_str_aux;
}
if (!strcmp(s1,"Depth")) {
char *pc=index(s2,'-');
if ( pc ) {
*pc=0;
char *endptr;
strcpy(Depth_str_aux,s2);
image_Info->Depth_str=Depth_str_aux;
if ((pc = index(s2,'/')) != NULL) {
*pc=0;
image_Info->depth_from_depth_str= strtol(pc+1,&endptr,10);
image_Info->quantum_depth_from_depth_str=strtol(s2,&endptr,10);
} else {
image_Info->quantum_depth_from_depth_str=strtol(s2,&endptr,10);
image_Info->depth_from_depth_str=
image_Info->quantum_depth_from_depth_str;
}
} else {
fprintf(stderr,"ERROR: unexpected 'Depth:' line\n");
exit(-1);
}
}
if (!strcmp(s1,"quantum:format")) {
strcpy(quantum_format_str_aux,s2);
image_Info->quantum_format_str=quantum_format_str_aux;
}
if (Channel_stat!=0 && !strcmp(s1,"min")) {
strcpy(min_str_aux,s2);
image_Info->min_str=min_str_aux;
}
if (Channel_stat!=0 && !strcmp(s1,"max")) {
strcpy(max_str_aux,s2);
image_Info->max_str=max_str_aux;
}
if (Channel_stat!=0 && !strcmp(s1,"mean")) {
strcpy(mean_str_aux,s2);
image_Info->mean_str=mean_str_aux;
}
if (Channel_stat!=0 && !strcmp(s1,"standard deviation")) {
strcpy(stdev_str_aux,s2);
image_Info->stdev_str=stdev_str_aux;
}
}
}
}
printf("option=%p (quantum:format)\n",image_Info->quantum_format);
printf("------ depth =%lu quantum_depth =%ld\n",
image_Info->depth,image_Info->quantum_depth);
printf(" depth_from_depth_str=%lu quantum_depth_from_depth_str=%lu\n",
image_Info->depth_from_depth_str,
image_Info->quantum_depth_from_depth_str);
printf(" gray channel_depth=%ld width=%ld height=%ld n_imgs=%lu\n",
image_Info->gray_channel_depth,
image_Info->width,image_Info->height,image_Info->n_imgs);
printf("quantum:format=|%s| quantum:format_str=|%s|\n",
image_Info->quantum_format?
image_Info->quantum_format:" is not defined",
image_Info->quantum_format_str?
image_Info->quantum_format_str:" is not defined");
printf("storage_class=%d Class_str=|%s| \n",image_Info->storage_class,
image_Info->Class_str?
image_Info->Class_str:" is not defined");
double max_value=(double)(2L<<(image_Info->quantum_depth_from_depth_str-1));
printf("image_Info->depth=%lu image_Info->quantum_depth_from_depth_str=%lu max_value=%f\n",
image_Info->depth,image_Info->quantum_depth_from_depth_str,max_value);
printf("min_str=|%s| mean_str=|%s| max_str=|%s| stdev=|%s|\n",
image_Info->min_str,image_Info->mean_str,
image_Info->max_str,image_Info->stdev_str);
image_info=DestroyImageInfo(image_info);
exception=DestroyExceptionInfo(exception);
MagickCoreTerminus();
return 0;
}
Code: Select all
#include <stdio.h>
#include <string.h>
#include <pcre.h>
#include <wand/magick_wand.h>
typedef struct {
ClassType storage_class;
const char *Class_str; // directly from identify
const char *image_type_str;
size_t height, width;
const char *Depth_str;
size_t depth_from_depth_str;
size_t quantum_depth_from_depth_str;
size_t depth;
//const char *quantum_depth_str;
size_t quantum_depth;
const char *color_space_string;
const char *compression_type_str;
size_t gray_channel_depth;
MagickBooleanType is_gray_image;
const char *quantum_format_str; // directly from identify
const char *quantum_format;
size_t n_imgs;
double x_resolution,y_resolution;
double gamma;
const char *gravity_type_str;
QuantumType quantum_type;
size_t quantum_extent;
MagickBooleanType is_high_dynamic_range;
const char *min_str, *max_str; // directly from identify
double minimum, maximum;
const char *mean_str, *stdev_str; // directly from identify
double mean, stdev;
ChannelFeatures *channel_features;
} Image_Info;
#define OVECCOUNT 30 /* should be a multiple of 3 */
//#define DEBUG 1
#define ThrowWandException(wand) { \
ExceptionType severity; \
char *description=MagickGetException(wand,&severity); \
(void) fprintf(stderr,"%s %s %ld %s\n",GetMagickModule(),description); \
description=(char *) MagickRelinquishMemory(description); \
exit(-1); \
}
int main (int argc, char *argv[]) {
int rc,erroffset;
char *pat;
pcre *re;
const char *error;
int ovector[OVECCOUNT];
const char *Level1_Attribut, *Level2_Attribut;
MagickWandGenesis();
MagickWand *wand=NewMagickWand();
int status=MagickReadImage(wand,argv[1]);
if (status == MagickFalse) ThrowWandException(wand);
Image_Info *image_Info=(Image_Info *)malloc(sizeof(Image_Info));
image_Info->storage_class= -1;
image_Info->height=MagickGetImageHeight(wand);
image_Info->width=MagickGetImageWidth(wand);
image_Info->depth=MagickGetImageDepth(wand);
image_Info->quantum_depth=-1;
ChannelType channel=GrayChannel;
image_Info->gray_channel_depth=MagickGetImageChannelDepth(wand,channel);
image_Info->quantum_format=MagickGetOption(wand,"quantum:format");
image_Info->Class_str=0; char Class_str_aux[1024];
image_Info->Depth_str=0; char Depth_str_aux[1024];
image_Info->quantum_format_str=0; char quantum_format_str_aux[1024];
image_Info->min_str=0; char min_str_aux[1024];
image_Info->max_str=0; char max_str_aux[1024];
image_Info->mean_str=0; char mean_str_aux[1024];
image_Info->stdev_str=0; char stdev_str_aux[1024];
char *identify_image=MagickIdentifyImage(wand);
#define BUFLEN 1024
char *line = (char *)malloc(BUFLEN+1);
char *pc, *old_pc=identify_image;
char s0[BUFLEN+1],s1[BUFLEN+1],s2[BUFLEN+1];
int Channel_stat, Gray_Channel;
while ((pc=index(old_pc,'\n'))!=NULL) {
//fprintf(stderr,"pc-old_pc=%ld\n",pc-old_pc);
strncpy(line,old_pc,pc-old_pc);
line[pc-old_pc]=0;
#ifdef DEBUG
fprintf(stderr,"line=|%s|\n",line);
#endif
if(!(re=pcre_compile("^[\\s]*$",0,&error,&erroffset,NULL))) {
printf("PCRE compilation failed at offset %d: %s\n", erroffset, error);
exit(1);
}
if(pcre_exec(re,NULL,line,(int)strlen(line),0,0,ovector,OVECCOUNT)>=0) {
#ifdef DEBUG
fprintf(stderr,"Empty line found\n");
#endif
} else {
pat="([\\s]*)(.*)[\\s]*:[\\s]*(.*)[\\s]*$";
//pat="[\\s]*quantum:format[\\s]*:[\\s]*(.*)[\\s]*$";
//fprintf(stderr,"before testing pat=|%s| line=|%s|\n",pat,line);
if(!(re=pcre_compile(pat,0,&error,&erroffset,NULL))) {
fprintf(stderr,"PCRE compilation failed at offset %d: %s\n",erroffset,error);
exit(1);
}
rc = pcre_exec(re,NULL,line,(int)strlen(line),0,0,ovector,OVECCOUNT);
/* Matching failed: handle error cases */
if (rc < 0) {
switch(rc) {
case PCRE_ERROR_NOMATCH:
//fprintf(stderr,"No match in tmp_file=|%s| line=|%s|\n",tmp_file,line);
//exit(2);
break;
/*
Handle other special cases if you like
*/
default:
fprintf(stderr,"Matching error %d using identify line=|%s|\n",
rc,line);
exit(2);
break;
}
} else {
/* Match succeded */
#ifdef DEBUG
fprintf(stderr," Match succeeded\n");
#endif
/* The output vector wasn't big enough */
if (rc == 0) {
rc = OVECCOUNT/3;
fprintf(stderr,"ovector only has room for %d captured substrings\n",
rc-1);
}
#ifdef DEBUG
/* Show substrings stored in the output vector */
int i;
for(i=0; i<rc; i++) {
char *substring_start = line+ovector[2*i];
int substring_length = ovector[2*i+1]-ovector[2*i];
fprintf(stderr," %2d: |%.*s|\n",i,substring_length,substring_start);
}
#endif
strncpy(s0,line+ovector[2],ovector[2+1]-ovector[2]);
strncpy(s1,line+ovector[4],ovector[4+1]-ovector[4]);
strncpy(s2,line+ovector[6],ovector[6+1]-ovector[6]);
s0[ovector[2+1]-ovector[2]]=0;
s1[ovector[4+1]-ovector[4]]=0;
s2[ovector[6+1]-ovector[6]]=0;
#ifdef DEBUG
fprintf(stderr,"strlen(s0)=%4lu s1=|%s| s2=|%s|\n",strlen(s0),s1,s2);
#endif
if (strlen(s0)==2) {
Level1_Attribut=s1;
Channel_stat=0;
if (!strcmp(s1,"Channel statistics")) {
Channel_stat=1;
}
}
if (strlen(s0)==4) {
Level2_Attribut=s1;
if (Channel_stat==1) {
if (!strcmp(s1,"Gray")) {
Gray_Channel=1;
}
}
}
if (!strcmp(s1,"Class")) {
strcpy(Class_str_aux,s2);
image_Info->Class_str=Class_str_aux;
}
if (!strcmp(s1,"Depth")) {
char *pc=index(s2,'-');
if ( pc ) {
*pc=0;
char *endptr;
strcpy(Depth_str_aux,s2);
image_Info->Depth_str=Depth_str_aux;
if ((pc = index(s2,'/')) != NULL) {
*pc=0;
image_Info->depth_from_depth_str= strtol(pc+1,&endptr,10);
image_Info->quantum_depth_from_depth_str=strtol(s2,&endptr,10);
} else {
image_Info->quantum_depth_from_depth_str=strtol(s2,&endptr,10);
image_Info->depth_from_depth_str=
image_Info->quantum_depth_from_depth_str;
}
} else {
fprintf(stderr,"ERROR: unexpected 'Depth:' line\n");
exit(-1);
}
}
if (!strcmp(s1,"quantum:format")) {
strcpy(quantum_format_str_aux,s2);
image_Info->quantum_format_str=quantum_format_str_aux;
}
if (Channel_stat!=0 && !strcmp(s1,"min")) {
strcpy(min_str_aux,s2);
image_Info->min_str=min_str_aux;
}
if (Channel_stat!=0 && !strcmp(s1,"max")) {
strcpy(max_str_aux,s2);
image_Info->max_str=max_str_aux;
}
if (Channel_stat!=0 && !strcmp(s1,"mean")) {
strcpy(mean_str_aux,s2);
image_Info->mean_str=mean_str_aux;
}
if (Channel_stat!=0 && !strcmp(s1,"standard deviation")) {
strcpy(stdev_str_aux,s2);
image_Info->stdev_str=stdev_str_aux;
}
}
}
old_pc=pc+1;
}
printf("option=%p (quantum:format)\n",image_Info->quantum_format);
printf("------ depth =%lu quantum_depth =%ld\n",
image_Info->depth,image_Info->quantum_depth);
printf(" depth_from_depth_str=%lu quantum_depth_from_depth_str=%lu\n",
image_Info->depth_from_depth_str,
image_Info->quantum_depth_from_depth_str);
printf(" gray channel_depth=%ld width=%ld height=%ld n_imgs=%lu\n",
image_Info->gray_channel_depth,
image_Info->width,image_Info->height,image_Info->n_imgs);
printf("quantum:format=|%s| quantum:format_str=|%s|\n",
image_Info->quantum_format?
image_Info->quantum_format:" is not defined",
image_Info->quantum_format_str?
image_Info->quantum_format_str:" is not defined");
printf("storage_class=%d Class_str=|%s| \n",image_Info->storage_class,
image_Info->Class_str?
image_Info->Class_str:" is not defined");
double max_value=(double)(2L<<(image_Info->quantum_depth_from_depth_str-1));
printf("image_Info->depth=%lu image_Info->quantum_depth_from_depth_str=%lu max_value=%f\n",
image_Info->depth,image_Info->quantum_depth_from_depth_str,max_value);
printf("min_str=|%s| mean_str=|%s| max_str=|%s| stdev=|%s|\n",
image_Info->min_str,image_Info->mean_str,
image_Info->max_str,image_Info->stdev_str);
if(wand != NULL) wand=DestroyMagickWand(wand);
MagickWandTerminus();
return 0;
}
Re: Requesting quantum format from MagickCore and MagickWand
This returns floating-point for us:
- MagickGetImageProperty(wand,"quantum:format")