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