00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include "magick/studio.h"
00046 #include "magick/annotate.h"
00047 #include "magick/artifact.h"
00048 #include "magick/attribute.h"
00049 #include "magick/blob.h"
00050 #include "magick/cache.h"
00051 #include "magick/client.h"
00052 #include "magick/coder.h"
00053 #include "magick/color.h"
00054 #include "magick/configure.h"
00055 #include "magick/constitute.h"
00056 #include "magick/decorate.h"
00057 #include "magick/delegate.h"
00058 #include "magick/draw.h"
00059 #include "magick/effect.h"
00060 #include "magick/exception.h"
00061 #include "magick/exception-private.h"
00062 #include "magick/feature.h"
00063 #include "magick/gem.h"
00064 #include "magick/geometry.h"
00065 #include "magick/histogram.h"
00066 #include "magick/identify.h"
00067 #include "magick/image.h"
00068 #include "magick/image-private.h"
00069 #include "magick/list.h"
00070 #include "magick/locale_.h"
00071 #include "magick/log.h"
00072 #include "magick/magic.h"
00073 #include "magick/magick.h"
00074 #include "magick/memory_.h"
00075 #include "magick/module.h"
00076 #include "magick/monitor.h"
00077 #include "magick/montage.h"
00078 #include "magick/option.h"
00079 #include "magick/pixel-private.h"
00080 #include "magick/prepress.h"
00081 #include "magick/profile.h"
00082 #include "magick/property.h"
00083 #include "magick/quantize.h"
00084 #include "magick/quantum.h"
00085 #include "magick/random_.h"
00086 #include "magick/registry.h"
00087 #include "magick/resize.h"
00088 #include "magick/resource_.h"
00089 #include "magick/signature.h"
00090 #include "magick/statistic.h"
00091 #include "magick/string_.h"
00092 #include "magick/string-private.h"
00093 #include "magick/timer.h"
00094 #include "magick/utility.h"
00095 #include "magick/version.h"
00096 #if defined(MAGICKCORE_LCMS_DELEGATE)
00097 #if defined(MAGICKCORE_HAVE_LCMS_LCMS_H)
00098 #include <lcms/lcms.h>
00099 #else
00100 #include "lcms.h"
00101 #endif
00102 #endif
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 static int PrintChannelFeatures(FILE *file,const ChannelType channel,
00135 const char *name,const ChannelFeatures *channel_features)
00136 {
00137 #define PrintFeature(feature) \
00138 GetMagickPrecision(),(feature)[0], \
00139 GetMagickPrecision(),(feature)[1], \
00140 GetMagickPrecision(),(feature)[2], \
00141 GetMagickPrecision(),(feature)[3], \
00142 GetMagickPrecision(),((feature)[0]+(feature)[1]+(feature)[2]+(feature)[3])/4.0 \
00143
00144 #define FeaturesFormat " %s:\n" \
00145 " Angular Second Moment:\n" \
00146 " %.*g, %.*g, %.*g, %.*g, %.*g\n" \
00147 " Contrast:\n" \
00148 " %.*g, %.*g, %.*g, %.*g, %.*g\n" \
00149 " Correlation:\n" \
00150 " %.*g, %.*g, %.*g, %.*g, %.*g\n" \
00151 " Sum of Squares: Variance:\n" \
00152 " %.*g, %.*g, %.*g, %.*g, %.*g\n" \
00153 " Inverse Difference Moment:\n" \
00154 " %.*g, %.*g, %.*g, %.*g, %.*g\n" \
00155 " Sum Average:\n" \
00156 " %.*g, %.*g, %.*g, %.*g, %.*g\n" \
00157 " Sum Variance:\n" \
00158 " %.*g, %.*g, %.*g, %.*g, %.*g\n" \
00159 " Sum Entropy:\n" \
00160 " %.*g, %.*g, %.*g, %.*g, %.*g\n" \
00161 " Entropy:\n" \
00162 " %.*g, %.*g, %.*g, %.*g, %.*g\n" \
00163 " Difference Variance:\n" \
00164 " %.*g, %.*g, %.*g, %.*g, %.*g\n" \
00165 " Difference Entropy:\n" \
00166 " %.*g, %.*g, %.*g, %.*g, %.*g\n" \
00167 " Information Measure of Correlation 1:\n" \
00168 " %.*g, %.*g, %.*g, %.*g, %.*g\n" \
00169 " Information Measure of Correlation 2:\n" \
00170 " %.*g, %.*g, %.*g, %.*g, %.*g\n" \
00171 " Maximum Correlation Coefficient:\n" \
00172 " %.*g, %.*g, %.*g, %.*g, %.*g\n"
00173
00174 int
00175 status;
00176
00177 status=fprintf(file,FeaturesFormat,name,
00178 PrintFeature(channel_features[channel].angular_second_moment),
00179 PrintFeature(channel_features[channel].contrast),
00180 PrintFeature(channel_features[channel].correlation),
00181 PrintFeature(channel_features[channel].variance_sum_of_squares),
00182 PrintFeature(channel_features[channel].inverse_difference_moment),
00183 PrintFeature(channel_features[channel].sum_average),
00184 PrintFeature(channel_features[channel].sum_variance),
00185 PrintFeature(channel_features[channel].sum_entropy),
00186 PrintFeature(channel_features[channel].entropy),
00187 PrintFeature(channel_features[channel].difference_variance),
00188 PrintFeature(channel_features[channel].difference_entropy),
00189 PrintFeature(channel_features[channel].measure_of_correlation_1),
00190 PrintFeature(channel_features[channel].measure_of_correlation_2),
00191 PrintFeature(channel_features[channel].maximum_correlation_coefficient));
00192 return(status);
00193 }
00194
00195 static int PrintChannelStatistics(FILE *file,const ChannelType channel,
00196 const char *name,const double scale,
00197 const ChannelStatistics *channel_statistics)
00198 {
00199 #define StatisticsFormat " %s:\n min: " QuantumFormat \
00200 " (%g)\n max: " QuantumFormat " (%g)\n" \
00201 " mean: %g (%g)\n standard deviation: %g (%g)\n" \
00202 " kurtosis: %g\n skewness: %g\n"
00203
00204 int
00205 status;
00206
00207 status=fprintf(file,StatisticsFormat,name,(Quantum) (scale*
00208 channel_statistics[channel].minima+0.5),channel_statistics[channel].minima/
00209 (double) QuantumRange,(Quantum) (scale*channel_statistics[channel].maxima+
00210 0.5),channel_statistics[channel].maxima/(double) QuantumRange,scale*
00211 channel_statistics[channel].mean,channel_statistics[channel].mean/
00212 (double) QuantumRange,scale*channel_statistics[channel].standard_deviation,
00213 channel_statistics[channel].standard_deviation/(double) QuantumRange,
00214 channel_statistics[channel].kurtosis,channel_statistics[channel].skewness);
00215 return(status);
00216 }
00217
00218 MagickExport MagickBooleanType IdentifyImage(Image *image,FILE *file,
00219 const MagickBooleanType verbose)
00220 {
00221 char
00222 color[MaxTextExtent],
00223 format[MaxTextExtent],
00224 key[MaxTextExtent];
00225
00226 ChannelFeatures
00227 *channel_features;
00228
00229 ChannelStatistics
00230 *channel_statistics;
00231
00232 ColorspaceType
00233 colorspace;
00234
00235 const char
00236 *artifact,
00237 *name,
00238 *property,
00239 *registry,
00240 *value;
00241
00242 const MagickInfo
00243 *magick_info;
00244
00245 const PixelPacket
00246 *pixels;
00247
00248 double
00249 elapsed_time,
00250 user_time;
00251
00252 ExceptionInfo
00253 *exception;
00254
00255 ImageType
00256 type;
00257
00258 long
00259 y;
00260
00261 MagickBooleanType
00262 ping;
00263
00264 register long
00265 i,
00266 x;
00267
00268 unsigned long
00269 distance,
00270 scale;
00271
00272 assert(image != (Image *) NULL);
00273 assert(image->signature == MagickSignature);
00274 if (image->debug != MagickFalse)
00275 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00276 if (file == (FILE *) NULL)
00277 file=stdout;
00278 *format='\0';
00279 elapsed_time=GetElapsedTime(&image->timer);
00280 user_time=GetUserTime(&image->timer);
00281 GetTimerInfo(&image->timer);
00282 if (verbose == MagickFalse)
00283 {
00284
00285
00286
00287 if (*image->magick_filename != '\0')
00288 if (LocaleCompare(image->magick_filename,image->filename) != 0)
00289 (void) fprintf(file,"%s=>",image->magick_filename);
00290 if ((GetPreviousImageInList(image) == (Image *) NULL) &&
00291 (GetNextImageInList(image) == (Image *) NULL) &&
00292 (image->scene == 0))
00293 (void) fprintf(file,"%s ",image->filename);
00294 else
00295 (void) fprintf(file,"%s[%lu] ",image->filename,image->scene);
00296 (void) fprintf(file,"%s ",image->magick);
00297 if ((image->magick_columns != 0) || (image->magick_rows != 0))
00298 if ((image->magick_columns != image->columns) ||
00299 (image->magick_rows != image->rows))
00300 (void) fprintf(file,"%lux%lu=>",image->magick_columns,
00301 image->magick_rows);
00302 (void) fprintf(file,"%lux%lu ",image->columns,image->rows);
00303 if ((image->page.width != 0) || (image->page.height != 0) ||
00304 (image->page.x != 0) || (image->page.y != 0))
00305 (void) fprintf(file,"%lux%lu%+ld%+ld ",image->page.width,
00306 image->page.height,image->page.x,image->page.y);
00307 (void) fprintf(file,"%lu-bit ",image->depth);
00308 if (image->type != UndefinedType)
00309 (void) fprintf(file,"%s ",MagickOptionToMnemonic(MagickTypeOptions,
00310 (long) image->type));
00311 if (image->storage_class == DirectClass)
00312 {
00313 (void) fprintf(file,"DirectClass ");
00314 if (image->total_colors != 0)
00315 {
00316 (void) FormatMagickSize(image->total_colors,MagickFalse,format);
00317 (void) fprintf(file,"%s ",format);
00318 }
00319 }
00320 else
00321 if (image->total_colors <= image->colors)
00322 (void) fprintf(file,"PseudoClass %luc ",image->colors);
00323 else
00324 (void) fprintf(file,"PseudoClass %lu=>%luc ",image->total_colors,
00325 image->colors);
00326 if (image->error.mean_error_per_pixel != 0.0)
00327 (void) fprintf(file,"%ld/%f/%fdb ",(long)
00328 (image->error.mean_error_per_pixel+0.5),
00329 image->error.normalized_mean_error,
00330 image->error.normalized_maximum_error);
00331 if (GetBlobSize(image) != 0)
00332 {
00333 (void) FormatMagickSize(GetBlobSize(image),MagickFalse,format);
00334 (void) fprintf(file,"%sB ",format);
00335 }
00336 (void) fprintf(file,"%0.3fu %ld:%02ld.%03ld",user_time,(long)
00337 (elapsed_time/60.0),(long) floor(fmod(elapsed_time,60.0)),
00338 (long) (1000.0*(elapsed_time-floor(elapsed_time))));
00339 (void) fprintf(file,"\n");
00340 (void) fflush(file);
00341 return(ferror(file) != 0 ? MagickFalse : MagickTrue);
00342 }
00343
00344
00345
00346 exception=AcquireExceptionInfo();
00347 pixels=GetVirtualPixels(image,0,0,1,1,exception);
00348 exception=DestroyExceptionInfo(exception);
00349 ping=pixels == (const PixelPacket *) NULL ? MagickTrue : MagickFalse;
00350 type=GetImageType(image,&image->exception);
00351 (void) SignatureImage(image);
00352 (void) fprintf(file,"Image: %s\n",image->filename);
00353 if (*image->magick_filename != '\0')
00354 if (LocaleCompare(image->magick_filename,image->filename) != 0)
00355 {
00356 char
00357 filename[MaxTextExtent];
00358
00359 GetPathComponent(image->magick_filename,TailPath,filename);
00360 (void) fprintf(file," Base filename: %s\n",filename);
00361 }
00362 magick_info=GetMagickInfo(image->magick,&image->exception);
00363 if ((magick_info == (const MagickInfo *) NULL) ||
00364 (*GetMagickDescription(magick_info) == '\0'))
00365 (void) fprintf(file," Format: %s\n",image->magick);
00366 else
00367 (void) fprintf(file," Format: %s (%s)\n",image->magick,
00368 GetMagickDescription(magick_info));
00369 (void) fprintf(file," Class: %s\n",MagickOptionToMnemonic(MagickClassOptions,
00370 (long) image->storage_class));
00371 (void) fprintf(file," Geometry: %lux%lu%+ld%+ld\n",image->columns,
00372 image->rows,image->tile_offset.x,image->tile_offset.y);
00373 if ((image->magick_columns != 0) || (image->magick_rows != 0))
00374 if ((image->magick_columns != image->columns) ||
00375 (image->magick_rows != image->rows))
00376 (void) fprintf(file," Base geometry: %lux%lu\n",image->magick_columns,
00377 image->magick_rows);
00378 if ((image->x_resolution != 0.0) && (image->y_resolution != 0.0))
00379 {
00380 (void) fprintf(file," Resolution: %gx%g\n",image->x_resolution,
00381 image->y_resolution);
00382 (void) fprintf(file," Print size: %gx%g\n",(double) image->columns/
00383 image->x_resolution,(double) image->rows/image->y_resolution);
00384 }
00385 (void) fprintf(file," Units: %s\n",MagickOptionToMnemonic(
00386 MagickResolutionOptions,(long) image->units));
00387 (void) fprintf(file," Type: %s\n",MagickOptionToMnemonic(MagickTypeOptions,
00388 (long) type));
00389 if (image->type != UndefinedType)
00390 (void) fprintf(file," Base type: %s\n",MagickOptionToMnemonic(
00391 MagickTypeOptions,(long) image->type));
00392 (void) fprintf(file," Endianess: %s\n",MagickOptionToMnemonic(
00393 MagickEndianOptions,(long) image->endian));
00394
00395
00396
00397 (void) fprintf(file," Colorspace: %s\n",MagickOptionToMnemonic(
00398 MagickColorspaceOptions,(long) image->colorspace));
00399 channel_statistics=(ChannelStatistics *) NULL;
00400 channel_features=(ChannelFeatures *) NULL;
00401 colorspace=image->colorspace;
00402 if (ping == MagickFalse)
00403 {
00404 unsigned long
00405 depth;
00406
00407 channel_statistics=GetImageChannelStatistics(image,&image->exception);
00408 artifact=GetImageArtifact(image,"identify:features");
00409 if (artifact != (const char *) NULL)
00410 {
00411 distance=StringToUnsignedLong(artifact);
00412 channel_features=GetImageChannelFeatures(image,distance,
00413 &image->exception);
00414 }
00415 depth=GetImageDepth(image,&image->exception);
00416 if (image->depth == depth)
00417 (void) fprintf(file," Depth: %lu-bit\n",image->depth);
00418 else
00419 (void) fprintf(file," Depth: %lu/%lu-bit\n",image->depth,depth);
00420 (void) fprintf(file," Channel depth:\n");
00421 if (IsGrayImage(image,&image->exception) != MagickFalse)
00422 colorspace=GRAYColorspace;
00423 switch (colorspace)
00424 {
00425 case RGBColorspace:
00426 default:
00427 {
00428 (void) fprintf(file," red: %lu-bit\n",
00429 channel_statistics[RedChannel].depth);
00430 (void) fprintf(file," green: %lu-bit\n",
00431 channel_statistics[GreenChannel].depth);
00432 (void) fprintf(file," blue: %lu-bit\n",
00433 channel_statistics[BlueChannel].depth);
00434 if (image->matte != MagickFalse)
00435 (void) fprintf(file," alpha: %lu-bit\n",
00436 channel_statistics[OpacityChannel].depth);
00437 break;
00438 }
00439 case CMYKColorspace:
00440 {
00441 (void) fprintf(file," cyan: %lu-bit\n",
00442 channel_statistics[CyanChannel].depth);
00443 (void) fprintf(file," magenta: %lu-bit\n",
00444 channel_statistics[MagentaChannel].depth);
00445 (void) fprintf(file," yellow: %lu-bit\n",
00446 channel_statistics[YellowChannel].depth);
00447 (void) fprintf(file," black: %lu-bit\n",
00448 channel_statistics[BlackChannel].depth);
00449 if (image->matte != MagickFalse)
00450 (void) fprintf(file," alpha: %lu-bit\n",
00451 channel_statistics[OpacityChannel].depth);
00452 break;
00453 }
00454 case GRAYColorspace:
00455 {
00456 (void) fprintf(file," gray: %lu-bit\n",
00457 channel_statistics[GrayChannel].depth);
00458 if (image->matte != MagickFalse)
00459 (void) fprintf(file," alpha: %lu-bit\n",
00460 channel_statistics[OpacityChannel].depth);
00461 break;
00462 }
00463 }
00464 scale=1;
00465 if (image->depth <= MAGICKCORE_QUANTUM_DEPTH)
00466 scale=QuantumRange/((unsigned long) QuantumRange >> ((unsigned long)
00467 MAGICKCORE_QUANTUM_DEPTH-image->depth));
00468 }
00469 if (channel_statistics != (ChannelStatistics *) NULL)
00470 {
00471 (void) fprintf(file," Channel statistics:\n");
00472 switch (colorspace)
00473 {
00474 case RGBColorspace:
00475 default:
00476 {
00477 (void) PrintChannelStatistics(file,RedChannel,"Red",1.0/scale,
00478 channel_statistics);
00479 (void) PrintChannelStatistics(file,GreenChannel,"Green",1.0/scale,
00480 channel_statistics);
00481 (void) PrintChannelStatistics(file,BlueChannel,"Blue",1.0/scale,
00482 channel_statistics);
00483 break;
00484 }
00485 case CMYKColorspace:
00486 {
00487 (void) PrintChannelStatistics(file,CyanChannel,"Cyan",1.0/scale,
00488 channel_statistics);
00489 (void) PrintChannelStatistics(file,MagentaChannel,"Magenta",1.0/scale,
00490 channel_statistics);
00491 (void) PrintChannelStatistics(file,YellowChannel,"Yellow",1.0/scale,
00492 channel_statistics);
00493 (void) PrintChannelStatistics(file,BlackChannel,"Black",1.0/scale,
00494 channel_statistics);
00495 break;
00496 }
00497 case GRAYColorspace:
00498 {
00499 (void) PrintChannelStatistics(file,GrayChannel,"Gray",1.0/scale,
00500 channel_statistics);
00501 break;
00502 }
00503 }
00504 if (image->matte != MagickFalse)
00505 (void) PrintChannelStatistics(file,AlphaChannel,"Alpha",1.0/scale,
00506 channel_statistics);
00507 if (colorspace != GRAYColorspace)
00508 {
00509 (void) fprintf(file," Image statistics:\n");
00510 (void) PrintChannelStatistics(file,AllChannels,"Overall",1.0/scale,
00511 channel_statistics);
00512 }
00513 channel_statistics=(ChannelStatistics *) RelinquishMagickMemory(
00514 channel_statistics);
00515 }
00516 if (channel_features != (ChannelFeatures *) NULL)
00517 {
00518 (void) fprintf(file," Channel features (horizontal, vertical, left and right diagonals, average):\n");
00519 switch (colorspace)
00520 {
00521 case RGBColorspace:
00522 default:
00523 {
00524 (void) PrintChannelFeatures(file,RedChannel,"Red",channel_features);
00525 (void) PrintChannelFeatures(file,GreenChannel,"Green",
00526 channel_features);
00527 (void) PrintChannelFeatures(file,BlueChannel,"Blue",channel_features);
00528 break;
00529 }
00530 case CMYKColorspace:
00531 {
00532 (void) PrintChannelFeatures(file,CyanChannel,"Cyan",channel_features);
00533 (void) PrintChannelFeatures(file,MagentaChannel,"Magenta",
00534 channel_features);
00535 (void) PrintChannelFeatures(file,YellowChannel,"Yellow",
00536 channel_features);
00537 (void) PrintChannelFeatures(file,BlackChannel,"Black",
00538 channel_features);
00539 break;
00540 }
00541 case GRAYColorspace:
00542 {
00543 (void) PrintChannelFeatures(file,GrayChannel,"Gray",channel_features);
00544 break;
00545 }
00546 }
00547 if (image->matte != MagickFalse)
00548 (void) PrintChannelFeatures(file,AlphaChannel,"Alpha",channel_features);
00549 channel_features=(ChannelFeatures *) RelinquishMagickMemory(
00550 channel_features);
00551 }
00552 if (ping == MagickFalse)
00553 {
00554 if (image->colorspace == CMYKColorspace)
00555 (void) fprintf(file," Total ink density: %.0f%%\n",100.0*
00556 GetImageTotalInkDensity(image)/(double) QuantumRange);
00557 x=0;
00558 if (image->matte != MagickFalse)
00559 {
00560 register const IndexPacket
00561 *indexes;
00562
00563 register const PixelPacket
00564 *p;
00565
00566 p=(PixelPacket *) NULL;
00567 indexes=(IndexPacket *) NULL;
00568 for (y=0; y < (long) image->rows; y++)
00569 {
00570 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
00571 if (p == (const PixelPacket *) NULL)
00572 break;
00573 indexes=GetVirtualIndexQueue(image);
00574 for (x=0; x < (long) image->columns; x++)
00575 {
00576 if (p->opacity == (Quantum) TransparentOpacity)
00577 break;
00578 p++;
00579 }
00580 if (x < (long) image->columns)
00581 break;
00582 }
00583 if ((x < (long) image->columns) || (y < (long) image->rows))
00584 {
00585 char
00586 tuple[MaxTextExtent];
00587
00588 MagickPixelPacket
00589 pixel;
00590
00591 GetMagickPixelPacket(image,&pixel);
00592 SetMagickPixelPacket(image,p,indexes+x,&pixel);
00593 (void) QueryMagickColorname(image,&pixel,SVGCompliance,tuple,
00594 &image->exception);
00595 (void) fprintf(file," Alpha: %s ",tuple);
00596 GetColorTuple(&pixel,MagickTrue,tuple);
00597 (void) fprintf(file," %s\n",tuple);
00598 }
00599 }
00600 artifact=GetImageArtifact(image,"identify:unique");
00601 if ((artifact != (const char *) NULL) &&
00602 (IsMagickTrue(artifact) != MagickFalse))
00603 (void) fprintf(file," Colors: %lu\n",GetNumberColors(image,
00604 (FILE *) NULL,&image->exception));
00605 if (IsHistogramImage(image,&image->exception) != MagickFalse)
00606 {
00607 (void) fprintf(file," Histogram:\n");
00608 (void) GetNumberColors(image,file,&image->exception);
00609 }
00610 }
00611 if (image->storage_class == PseudoClass)
00612 {
00613 (void) fprintf(file," Colormap: %lu\n",image->colors);
00614 if (image->colors <= 1024)
00615 {
00616 char
00617 color[MaxTextExtent],
00618 hex[MaxTextExtent],
00619 tuple[MaxTextExtent];
00620
00621 MagickPixelPacket
00622 pixel;
00623
00624 register PixelPacket
00625 *restrict p;
00626
00627 GetMagickPixelPacket(image,&pixel);
00628 p=image->colormap;
00629 for (i=0; i < (long) image->colors; i++)
00630 {
00631 SetMagickPixelPacket(image,p,(IndexPacket *) NULL,&pixel);
00632 (void) CopyMagickString(tuple,"(",MaxTextExtent);
00633 ConcatenateColorComponent(&pixel,RedChannel,X11Compliance,tuple);
00634 (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
00635 ConcatenateColorComponent(&pixel,GreenChannel,X11Compliance,tuple);
00636 (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
00637 ConcatenateColorComponent(&pixel,BlueChannel,X11Compliance,tuple);
00638 if (pixel.colorspace == CMYKColorspace)
00639 {
00640 (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
00641 ConcatenateColorComponent(&pixel,IndexChannel,X11Compliance,
00642 tuple);
00643 }
00644 if (pixel.matte != MagickFalse)
00645 {
00646 (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
00647 ConcatenateColorComponent(&pixel,OpacityChannel,X11Compliance,
00648 tuple);
00649 }
00650 (void) ConcatenateMagickString(tuple,")",MaxTextExtent);
00651 (void) QueryMagickColorname(image,&pixel,SVGCompliance,color,
00652 &image->exception);
00653 GetColorTuple(&pixel,MagickTrue,hex);
00654 (void) fprintf(file," %8ld: %s %s %s\n",i,tuple,hex,color);
00655 p++;
00656 }
00657 }
00658 }
00659 if (image->error.mean_error_per_pixel != 0.0)
00660 (void) fprintf(file," Mean error per pixel: %g\n",
00661 image->error.mean_error_per_pixel);
00662 if (image->error.normalized_mean_error != 0.0)
00663 (void) fprintf(file," Normalized mean error: %g\n",
00664 image->error.normalized_mean_error);
00665 if (image->error.normalized_maximum_error != 0.0)
00666 (void) fprintf(file," Normalized maximum error: %g\n",
00667 image->error.normalized_maximum_error);
00668 (void) fprintf(file," Rendering intent: %s\n",MagickOptionToMnemonic(
00669 MagickIntentOptions,(long) image->rendering_intent));
00670 if (image->gamma != 0.0)
00671 (void) fprintf(file," Gamma: %g\n",image->gamma);
00672 if ((image->chromaticity.red_primary.x != 0.0) ||
00673 (image->chromaticity.green_primary.x != 0.0) ||
00674 (image->chromaticity.blue_primary.x != 0.0) ||
00675 (image->chromaticity.white_point.x != 0.0))
00676 {
00677
00678
00679
00680 (void) fprintf(file," Chromaticity:\n");
00681 (void) fprintf(file," red primary: (%g,%g)\n",
00682 image->chromaticity.red_primary.x,image->chromaticity.red_primary.y);
00683 (void) fprintf(file," green primary: (%g,%g)\n",
00684 image->chromaticity.green_primary.x,
00685 image->chromaticity.green_primary.y);
00686 (void) fprintf(file," blue primary: (%g,%g)\n",
00687 image->chromaticity.blue_primary.x,image->chromaticity.blue_primary.y);
00688 (void) fprintf(file," white point: (%g,%g)\n",
00689 image->chromaticity.white_point.x,image->chromaticity.white_point.y);
00690 }
00691 if ((image->extract_info.width*image->extract_info.height) != 0)
00692 (void) fprintf(file," Tile geometry: %lux%lu%+ld%+ld\n",
00693 image->extract_info.width,image->extract_info.height,
00694 image->extract_info.x,image->extract_info.y);
00695 (void) fprintf(file," Interlace: %s\n",MagickOptionToMnemonic(
00696 MagickInterlaceOptions,(long) image->interlace));
00697 (void) QueryColorname(image,&image->background_color,SVGCompliance,color,
00698 &image->exception);
00699 (void) fprintf(file," Background color: %s\n",color);
00700 (void) QueryColorname(image,&image->border_color,SVGCompliance,color,
00701 &image->exception);
00702 (void) fprintf(file," Border color: %s\n",color);
00703 (void) QueryColorname(image,&image->matte_color,SVGCompliance,color,
00704 &image->exception);
00705 (void) fprintf(file," Matte color: %s\n",color);
00706 (void) QueryColorname(image,&image->transparent_color,SVGCompliance,color,
00707 &image->exception);
00708 (void) fprintf(file," Transparent color: %s\n",color);
00709 (void) fprintf(file," Compose: %s\n",MagickOptionToMnemonic(
00710 MagickComposeOptions,(long) image->compose));
00711 if ((image->page.width != 0) || (image->page.height != 0) ||
00712 (image->page.x != 0) || (image->page.y != 0))
00713 (void) fprintf(file," Page geometry: %lux%lu%+ld%+ld\n",image->page.width,
00714 image->page.height,image->page.x,image->page.y);
00715 if ((image->page.x != 0) || (image->page.y != 0))
00716 (void) fprintf(file," Origin geometry: %+ld%+ld\n",image->page.x,
00717 image->page.y);
00718 (void) fprintf(file," Dispose: %s\n",MagickOptionToMnemonic(
00719 MagickDisposeOptions,(long) image->dispose));
00720 if (image->delay != 0)
00721 (void) fprintf(file," Delay: %lux%ld\n",image->delay,
00722 image->ticks_per_second);
00723 if (image->iterations != 1)
00724 (void) fprintf(file," Iterations: %lu\n",image->iterations);
00725 if ((image->next != (Image *) NULL) || (image->previous != (Image *) NULL))
00726 (void) fprintf(file," Scene: %lu of %lu\n",image->scene,
00727 GetImageListLength(image));
00728 else
00729 if (image->scene != 0)
00730 (void) fprintf(file," Scene: %lu\n",image->scene);
00731 (void) fprintf(file," Compression: %s\n",MagickOptionToMnemonic(
00732 MagickCompressOptions,(long) image->compression));
00733 if (image->quality != UndefinedCompressionQuality)
00734 (void) fprintf(file," Quality: %lu\n",image->quality);
00735 (void) fprintf(file," Orientation: %s\n",MagickOptionToMnemonic(
00736 MagickOrientationOptions,(long) image->orientation));
00737 if (image->montage != (char *) NULL)
00738 (void) fprintf(file," Montage: %s\n",image->montage);
00739 if (image->directory != (char *) NULL)
00740 {
00741 Image
00742 *tile;
00743
00744 ImageInfo
00745 *image_info;
00746
00747 register char
00748 *p,
00749 *q;
00750
00751 WarningHandler
00752 handler;
00753
00754
00755
00756
00757 image_info=AcquireImageInfo();
00758 (void) CloneString(&image_info->size,"64x64");
00759 (void) fprintf(file," Directory:\n");
00760 for (p=image->directory; *p != '\0'; p++)
00761 {
00762 q=p;
00763 while ((*q != '\n') && (*q != '\0'))
00764 q++;
00765 (void) CopyMagickString(image_info->filename,p,(size_t) (q-p+1));
00766 p=q;
00767 (void) fprintf(file," %s",image_info->filename);
00768 handler=SetWarningHandler((WarningHandler) NULL);
00769 tile=ReadImage(image_info,&image->exception);
00770 (void) SetWarningHandler(handler);
00771 if (tile == (Image *) NULL)
00772 {
00773 (void) fprintf(file,"\n");
00774 continue;
00775 }
00776 (void) fprintf(file," %lux%lu %s\n",tile->magick_columns,
00777 tile->magick_rows,tile->magick);
00778 (void) SignatureImage(tile);
00779 ResetImagePropertyIterator(tile);
00780 property=GetNextImageProperty(tile);
00781 while (property != (const char *) NULL)
00782 {
00783 (void) fprintf(file," %s:\n",property);
00784 value=GetImageProperty(tile,property);
00785 if (value != (const char *) NULL)
00786 (void) fprintf(file,"%s\n",value);
00787 property=GetNextImageProperty(tile);
00788 }
00789 tile=DestroyImage(tile);
00790 }
00791 image_info=DestroyImageInfo(image_info);
00792 }
00793 (void) GetImageProperty(image,"exif:*");
00794 ResetImagePropertyIterator(image);
00795 property=GetNextImageProperty(image);
00796 if (property != (const char *) NULL)
00797 {
00798
00799
00800
00801 (void) fprintf(file," Properties:\n");
00802 while (property != (const char *) NULL)
00803 {
00804 (void) fprintf(file," %c",*property);
00805 if (strlen(property) > 1)
00806 (void) fprintf(file,"%s: ",property+1);
00807 if (strlen(property) > 80)
00808 (void) fputc('\n',file);
00809 value=GetImageProperty(image,property);
00810 if (value != (const char *) NULL)
00811 (void) fprintf(file,"%s\n",value);
00812 property=GetNextImageProperty(image);
00813 }
00814 }
00815 (void) FormatMagickString(key,MaxTextExtent,"8BIM:1999,2998:#1");
00816 value=GetImageProperty(image,key);
00817 if (value != (const char *) NULL)
00818 {
00819
00820
00821
00822 (void) fprintf(file," Clipping path: ");
00823 if (strlen(value) > 80)
00824 (void) fputc('\n',file);
00825 (void) fprintf(file,"%s\n",value);
00826 }
00827 ResetImageProfileIterator(image);
00828 name=GetNextImageProfile(image);
00829 if (name != (char *) NULL)
00830 {
00831 const StringInfo
00832 *profile;
00833
00834
00835
00836
00837 (void) fprintf(file," Profiles:\n");
00838 while (name != (char *) NULL)
00839 {
00840 profile=GetImageProfile(image,name);
00841 if (profile == (StringInfo *) NULL)
00842 continue;
00843 (void) fprintf(file," Profile-%s: %lu bytes\n",name,(unsigned long)
00844 GetStringInfoLength(profile));
00845 #if defined(MAGICKCORE_LCMS_DELEGATE)
00846 if ((LocaleCompare(name,"icc") == 0) ||
00847 (LocaleCompare(name,"icm") == 0))
00848 {
00849 cmsHPROFILE
00850 icc_profile;
00851
00852 icc_profile=cmsOpenProfileFromMem(GetStringInfoDatum(profile),
00853 (DWORD) GetStringInfoLength(profile));
00854 if (icc_profile != (cmsHPROFILE *) NULL)
00855 {
00856 const char
00857 *name;
00858
00859 name=cmsTakeProductName(icc_profile);
00860 if (name != (const char *) NULL)
00861 (void) fprintf(file," %s\n",name);
00862 (void) cmsCloseProfile(icc_profile);
00863 }
00864 }
00865 #endif
00866 if (LocaleCompare(name,"iptc") == 0)
00867 {
00868 char
00869 *attribute,
00870 **attribute_list;
00871
00872 const char
00873 *tag;
00874
00875 long
00876 dataset,
00877 record,
00878 sentinel;
00879
00880 register long
00881 j;
00882
00883 size_t
00884 length,
00885 profile_length;
00886
00887 profile_length=GetStringInfoLength(profile);
00888 for (i=0; i < (long) profile_length; i+=(long) length)
00889 {
00890 length=1;
00891 sentinel=GetStringInfoDatum(profile)[i++];
00892 if (sentinel != 0x1c)
00893 continue;
00894 dataset=GetStringInfoDatum(profile)[i++];
00895 record=GetStringInfoDatum(profile)[i++];
00896 switch (record)
00897 {
00898 case 5: tag="Image Name"; break;
00899 case 7: tag="Edit Status"; break;
00900 case 10: tag="Priority"; break;
00901 case 15: tag="Category"; break;
00902 case 20: tag="Supplemental Category"; break;
00903 case 22: tag="Fixture Identifier"; break;
00904 case 25: tag="Keyword"; break;
00905 case 30: tag="Release Date"; break;
00906 case 35: tag="Release Time"; break;
00907 case 40: tag="Special Instructions"; break;
00908 case 45: tag="Reference Service"; break;
00909 case 47: tag="Reference Date"; break;
00910 case 50: tag="Reference Number"; break;
00911 case 55: tag="Created Date"; break;
00912 case 60: tag="Created Time"; break;
00913 case 65: tag="Originating Program"; break;
00914 case 70: tag="Program Version"; break;
00915 case 75: tag="Object Cycle"; break;
00916 case 80: tag="Byline"; break;
00917 case 85: tag="Byline Title"; break;
00918 case 90: tag="City"; break;
00919 case 95: tag="Province State"; break;
00920 case 100: tag="Country Code"; break;
00921 case 101: tag="Country"; break;
00922 case 103: tag="Original Transmission Reference"; break;
00923 case 105: tag="Headline"; break;
00924 case 110: tag="Credit"; break;
00925 case 115: tag="Src"; break;
00926 case 116: tag="Copyright String"; break;
00927 case 120: tag="Caption"; break;
00928 case 121: tag="Local Caption"; break;
00929 case 122: tag="Caption Writer"; break;
00930 case 200: tag="Custom Field 1"; break;
00931 case 201: tag="Custom Field 2"; break;
00932 case 202: tag="Custom Field 3"; break;
00933 case 203: tag="Custom Field 4"; break;
00934 case 204: tag="Custom Field 5"; break;
00935 case 205: tag="Custom Field 6"; break;
00936 case 206: tag="Custom Field 7"; break;
00937 case 207: tag="Custom Field 8"; break;
00938 case 208: tag="Custom Field 9"; break;
00939 case 209: tag="Custom Field 10"; break;
00940 case 210: tag="Custom Field 11"; break;
00941 case 211: tag="Custom Field 12"; break;
00942 case 212: tag="Custom Field 13"; break;
00943 case 213: tag="Custom Field 14"; break;
00944 case 214: tag="Custom Field 15"; break;
00945 case 215: tag="Custom Field 16"; break;
00946 case 216: tag="Custom Field 17"; break;
00947 case 217: tag="Custom Field 18"; break;
00948 case 218: tag="Custom Field 19"; break;
00949 case 219: tag="Custom Field 20"; break;
00950 default: tag="unknown"; break;
00951 }
00952 (void) fprintf(file," %s[%ld,%ld]: ",tag,dataset,record);
00953 length=(size_t) (GetStringInfoDatum(profile)[i++] << 8);
00954 length|=GetStringInfoDatum(profile)[i++];
00955 attribute=(char *) NULL;
00956 if (~length >= MaxTextExtent)
00957 attribute=(char *) AcquireQuantumMemory(length+
00958 MaxTextExtent,sizeof(*attribute));
00959 if (attribute != (char *) NULL)
00960 {
00961 (void) CopyMagickString(attribute,(char *)
00962 GetStringInfoDatum(profile)+i,length+1);
00963 attribute_list=StringToList(attribute);
00964 if (attribute_list != (char **) NULL)
00965 {
00966 for (j=0; attribute_list[j] != (char *) NULL; j++)
00967 {
00968 (void) fputs(attribute_list[j],file);
00969 (void) fputs("\n",file);
00970 attribute_list[j]=(char *) RelinquishMagickMemory(
00971 attribute_list[j]);
00972 }
00973 attribute_list=(char **) RelinquishMagickMemory(
00974 attribute_list);
00975 }
00976 attribute=DestroyString(attribute);
00977 }
00978 }
00979 }
00980 if (image->debug != MagickFalse)
00981 PrintStringInfo(file,name,profile);
00982 name=GetNextImageProfile(image);
00983 }
00984 }
00985 ResetImageArtifactIterator(image);
00986 artifact=GetNextImageArtifact(image);
00987 if (artifact != (const char *) NULL)
00988 {
00989
00990
00991
00992 (void) fprintf(file," Artifacts:\n");
00993 while (artifact != (const char *) NULL)
00994 {
00995 (void) fprintf(file," %c",*artifact);
00996 if (strlen(artifact) > 1)
00997 (void) fprintf(file,"%s: ",artifact+1);
00998 if (strlen(artifact) > 80)
00999 (void) fputc('\n',file);
01000 value=GetImageArtifact(image,artifact);
01001 if (value != (const char *) NULL)
01002 (void) fprintf(file,"%s\n",value);
01003 artifact=GetNextImageArtifact(image);
01004 }
01005 }
01006 ResetImageRegistryIterator();
01007 registry=GetNextImageRegistry();
01008 if (registry != (const char *) NULL)
01009 {
01010
01011
01012
01013 (void) fprintf(file," Registry:\n");
01014 while (registry != (const char *) NULL)
01015 {
01016 (void) fprintf(file," %c",*registry);
01017 if (strlen(registry) > 1)
01018 (void) fprintf(file,"%s: ",registry+1);
01019 if (strlen(registry) > 80)
01020 (void) fputc('\n',file);
01021 value=(const char *) GetImageRegistry(StringRegistryType,registry,
01022 &image->exception);
01023 if (value != (const char *) NULL)
01024 (void) fprintf(file,"%s\n",value);
01025 registry=GetNextImageRegistry();
01026 }
01027 }
01028 (void) fprintf(file," Tainted: %s\n",MagickOptionToMnemonic(
01029 MagickBooleanOptions,(long) image->taint));
01030 (void) FormatMagickSize(GetBlobSize(image),MagickFalse,format);
01031 (void) fprintf(file," Filesize: %sB\n",format);
01032 (void) FormatMagickSize((MagickSizeType) image->columns*image->rows,
01033 MagickFalse,format);
01034 (void) fprintf(file," Number pixels: %s\n",format);
01035 (void) FormatMagickSize((MagickSizeType) ((double) image->columns*image->rows/
01036 elapsed_time+0.5),MagickFalse,format);
01037 (void) fprintf(file," Pixels per second: %s\n",format);
01038 (void) fprintf(file," User time: %0.3fu\n",user_time);
01039 (void) fprintf(file," Elapsed time: %ld:%02ld.%03ld\n",(long)
01040 (elapsed_time/60.0),(long) ceil(fmod(elapsed_time,60.0)),(long)
01041 (1000.0*(elapsed_time-floor(elapsed_time))));
01042 (void) fprintf(file," Version: %s\n",GetMagickVersion((unsigned long *)
01043 NULL));
01044 (void) fflush(file);
01045 return(ferror(file) != 0 ? MagickFalse : MagickTrue);
01046 }