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