Code: Select all
#include <stdio.h>
#include <stdlib.h>
#include <wand/MagickWand.h>
print_stat(MagickWand *wand, long long unsigned max_img_val, long long unsigned max_IM_val) {
double minimum, maximum, mean,stdev;
const char *fmt=" %-13s depth=%2lu min=%8.1lf(%5.3lf) max=%8.1lf(%5.3lf) mean=%8.1lf(%5.3lf) stdev=%8.1lf(%5.3lf)\n";
fprintf(stderr,"img_depth=%lu\n",MagickGetImageDepth(wand));
#define print_chan(S,c) { \
MagickGetImageChannelRange(wand,c,&minimum,&maximum); \
MagickGetImageChannelMean(wand,c,&mean,&stdev); \
fprintf(stderr,fmt,S,MagickGetImageChannelDepth(wand,c),\
max_img_val*minimum/max_IM_val,minimum/max_IM_val, max_img_val*maximum/max_IM_val,maximum/max_IM_val,\
max_img_val*mean/max_IM_val,mean/max_IM_val, max_img_val*stdev/max_IM_val,stdev/max_IM_val); \
}
print_chan("RedChannel:",RedChannel);
print_chan("GreenChannel:",GreenChannel);
print_chan("BlueChannel:",BlueChannel);
print_chan("GrayChannel:",GrayChannel);
}
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;
MagickWandGenesis();
MagickWand *wand=NewMagickWand();
status=MagickReadImage(wand,argv[1]);
if (status == MagickFalse) ThrowWandException(wand);
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);
long long unsigned max_IM_val=1ULL<<IM_quantum_depth;
long long unsigned max_img_val=(1ULL<<img_depth)-1;
fprintf(stderr,"1L<<IM_quantum_depth=%Lu max_IM_val=$Lu max_img_val=%Lu\n",
1ULL<<IM_quantum_depth,max_IM_val,max_img_val);
print_stat(wand, max_img_val, max_IM_val);
double degree=5;
MagickWand *rotated_wand = CloneMagickWand(wand);
PixelWand *background_color=NewPixelWand();
printf("\n\nbefore RotateImage: degree=%f\n",degree);
status=MagickRotateImage(rotated_wand, background_color, degree);
fprintf(stderr,"after MagickRotateImage: background_color=%s[%%s]\n",
PixelGetColorAsString(background_color));
if(status == MagickFalse) {
fprintf(stderr,"%s: MagickRotateImage failed, for degree=%f\n",
argv[0],degree);
exit(-1);
}
print_stat(rotated_wand,max_img_val,max_IM_val);
char out_f[1024];
sprintf(out_f,"OutImages/%s",argv[2]);
printf("\n\nbefore MagickWriteImages(rotated_wand,%s,):\n",out_f);
status=MagickWriteImages(rotated_wand,out_f,MagickTrue);
printf("\n\nafter MagickWriteImages(rotated_wand):\n");
if (status == MagickFalse) ThrowWandException(rotated_wand);
rotated_wand=DestroyMagickWand(rotated_wand);
wand=DestroyMagickWand(wand);
MagickWandTerminus();
return(0);
}
rose@moose:/home_moose/rose/Txt/src/Test/C/ImageMagick/Wand(406)$ rotate-image_with_getChannelRange lena.png lena_rotated.png
IM_quantum_depth_str=|Q32| IM_quantum_depth=|32| img_depth=8 quantum_format=|(null)|
1L<<IM_quantum_depth=4294967296 max_IM_val=$Lu max_img_val=4294967296
img_depth=8
RedChannel: depth= 8 min= 38.0(0.149) max= 255.0(1.000) mean= 180.0(0.706) stdev= 49.4(0.194)
GreenChannel: depth= 8 min= 0.0(0.000) max= 243.0(0.953) mean= 99.4(0.390) stdev= 52.6(0.206)
BlueChannel: depth= 8 min= 9.0(0.035) max= 234.0(0.918) mean= 105.3(0.413) stdev= 34.1(0.134)
GrayChannel: depth= 8 min= 38.0(0.149) max= 255.0(1.000) mean= 180.0(0.706) stdev= 49.4(0.194)
before RotateImage: degree=5.000000
after MagickRotateImage: background_color=rgb(0,0,0)[%s]
img_depth=8
RedChannel: depth=32 min= -16.6(-0.065) max= 271.0(1.063) mean= 152.6(0.599) stdev= 78.8(0.309)
GreenChannel: depth=32 min= -14.1(-0.055) max= 241.9(0.949) mean= 84.3(0.331) stdev= 60.0(0.235)
BlueChannel: depth=32 min= -11.9(-0.047) max= 228.5(0.896) mean= 89.3(0.350) stdev= 49.0(0.192)
GrayChannel: depth=32 min= -16.6(-0.065) max= 271.0(1.063) mean= 152.6(0.599) stdev= 78.8(0.309)
...
I.e., after rotation the minimal pixel values are negative and the maximal red value is larger than 255. The channel depths changed from 8 to 32.
If I test the result with identify, I see the following values:
rose@moose:/home_moose/rose/Txt/src/Test/C/ImageMagick/Wand(407)$ identify -verbose OutImages/lena_rotated.png
Image: OutImages/lena_rotated.png
Format: PNG (Portable Network Graphics)
Class: DirectClass
Geometry: 556x556+0+0
...
Channel depth:
red: 8-bit
green: 8-bit
blue: 8-bit
Channel statistics:
Red:
min: 0 (0)
max: 255 (1)
mean: 152.666 (0.598692)
standard deviation: 78.7507 (0.308826)
kurtosis: -0.538735
skewness: -0.857874
Green:
min: 0 (0)
max: 242 (0.94902)
mean: 84.341 (0.330749)
standard deviation: 60.0008 (0.235297)
kurtosis: -0.915871
skewness: 0.210762
Blue:
min: 0 (0)
max: 229 (0.898039)
mean: 89.3244 (0.350292)
standard deviation: 48.9691 (0.192036)
kurtosis: -0.278467
skewness: -0.307794
Image statistics:
Overall:
min: 0 (0)
max: 255 (1)
mean: 108.777 (0.426577)
standard deviation: 63.7697 (0.250077)
kurtosis: 0.151732
skewness: 0.0844437
I.e., the channel depths are again 8, the negative minima disapeared, the maxima are not larger than 255. Mean and stdev are the same I got. So the rotated output looks nice. If I try to repeate the same procedure with a 16 bit tiff, the writing of the rotated image fails:
rose@moose:/home_moose/rose/Txt/src/Test/C/ImageMagick/Wand(408)$ rotate-image_with_getChannelRange 12Anti9_HgF2_100V_21x5s_40x__p008.tiff 12Anti9_HgF2_100V_21x5s_40x__p008_rotated.tiff
IM_quantum_depth_str=|Q32| IM_quantum_depth=|32| img_depth=16 quantum_format=|(null)|
1L<<IM_quantum_depth=4294967296 max_IM_val=$Lu max_img_val=4294967296
img_depth=16
RedChannel: depth=16 min= 5.0(0.000) max= 65295.0(0.996) mean= 32804.1(0.501) stdev= 19002.5(0.290)
GreenChannel: depth=16 min= 5.0(0.000) max= 65295.0(0.996) mean= 32804.1(0.501) stdev= 19002.5(0.290)
BlueChannel: depth=16 min= 5.0(0.000) max= 65295.0(0.996) mean= 32804.1(0.501) stdev= 19002.5(0.290)
GrayChannel: depth=16 min= 5.0(0.000) max= 65295.0(0.996) mean= 32804.1(0.501) stdev= 19002.5(0.290)
before RotateImage: degree=5.000000
after MagickRotateImage: background_color=rgb(0,0,0)[%s]
img_depth=16
RedChannel: depth=32 min=-11444.1(-0.175) max= 74949.4(1.144) mean= 27685.1(0.422) stdev= 19288.0(0.294)
GreenChannel: depth=32 min=-11444.1(-0.175) max= 74949.4(1.144) mean= 27685.1(0.422) stdev= 19288.0(0.294)
BlueChannel: depth=32 min=-11444.1(-0.175) max= 74949.4(1.144) mean= 27685.1(0.422) stdev= 19288.0(0.294)
GrayChannel: depth=32 min=-11444.1(-0.175) max= 74949.4(1.144) mean= 27685.1(0.422) stdev= 19288.0(0.294)
before MagickWriteImages(rotated_wand,OutImages/12Anti9_HgF2_100V_21x5s_40x__p008_rotated.tiff,):
rotate-image_with_getChannelRange: tif_dirwrite.c:2084: TIFFWriteDirectoryTagCheckedRational: Assertion `value>=0.0' failed.
Abgebrochen
I will deeply appreciate any hint, how to handle this issue.