2
% Copyright (C) 2003 GraphicsMagick Group
3
% Copyright (C) 2002 ImageMagick Studio
4
% Copyright 1991-1999 E. I. du Pont de Nemours and Company
6
% This program is covered by multiple licenses, which are described in
7
% Copyright.txt. You should have received a copy of Copyright.txt with this
8
% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
10
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14
% PPPP RRRR EEEEE V V IIIII EEEEE W W %
15
% P P R R E V V I E W W %
16
% PPPP RRRR EEE V V I EEE W W %
17
% P R R E V V I E W W W %
18
% P R R EEEEE V IIIII EEEEE W W %
21
% Write A Preview Image. %
30
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38
#include "magick/studio.h"
39
#include "magick/attribute.h"
40
#include "magick/blob.h"
41
#include "magick/color.h"
42
#include "magick/constitute.h"
43
#include "magick/decorate.h"
44
#include "magick/effect.h"
45
#include "magick/enhance.h"
46
#include "magick/fx.h"
47
#include "magick/magick.h"
48
#include "magick/monitor.h"
49
#include "magick/montage.h"
50
#include "magick/quantize.h"
51
#include "magick/resize.h"
52
#include "magick/shear.h"
53
#include "magick/tempfile.h"
54
#include "magick/transform.h"
55
#include "magick/utility.h"
58
Constant declarations.
61
*DefaultPreviewGeometry = "204x204+10+10";
67
WritePreviewImage(const ImageInfo *,Image *);
70
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
74
% R e g i s t e r P R E V I E W I m a g e %
78
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
80
% Method RegisterPREVIEWImage adds attributes for the Preview image format to
81
% the list of supported formats. The attributes include the image format
82
% tag, a method to read and/or write the format, whether the format
83
% supports the saving of more than one frame to the same file or blob,
84
% whether the format supports native in-memory I/O, and a brief
85
% description of the format.
87
% The format of the RegisterPREVIEWImage method is:
89
% RegisterPREVIEWImage(void)
92
ModuleExport void RegisterPREVIEWImage(void)
97
entry=SetMagickInfo("PREVIEW");
98
entry->encoder=(EncoderHandler) WritePreviewImage;
101
AcquireString("Show a preview an image enhancement, effect, or f/x");
102
entry->module=AcquireString("PREVIEW");
103
(void) RegisterMagickInfo(entry);
107
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
111
% U n r e g i s t e r P R E V I E W I m a g e %
115
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
117
% Method UnregisterPREVIEWImage removes format registrations made by the
118
% PREVIEW module from the list of supported formats.
120
% The format of the UnregisterPREVIEWImage method is:
122
% UnregisterPREVIEWImage(void)
125
ModuleExport void UnregisterPREVIEWImage(void)
127
(void) UnregisterMagickInfo("PREVIEW");
131
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
135
% W r i t e P R E V I E W I m a g e %
139
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
141
% Method WritePreviewImage creates several tiles each with a varying
142
% stength of an image enhancement function (e.g. gamma). The image is written
143
% in the MIFF format.
145
% The format of the WritePreviewImage method is:
147
% unsigned int WritePreviewImage(const ImageInfo *image_info,Image *image)
149
% A description of each parameter follows.
151
% o status: Method WritePreviewImage return True if the image is written.
152
% False is returned is there is a memory shortage or if the image file
155
% o image_info: Specifies a pointer to a ImageInfo structure.
157
% o image: A pointer to an Image structure.
161
#define ReplaceImage(oldimage,func) \
166
temporary_image=func; \
167
if (temporary_image) \
169
DestroyImage(oldimage); \
170
oldimage=temporary_image; \
173
static unsigned int WritePreviewImage(const ImageInfo *image_info,Image *image)
175
#define NumberTiles 9
176
#define PreviewImageText " Creating image preview... "
179
factor[MaxTextExtent],
180
label[MaxTextExtent];
222
Open output image file.
224
assert(image_info != (const ImageInfo *) NULL);
225
assert(image_info->signature == MagickSignature);
226
assert(image != (Image *) NULL);
227
assert(image->signature == MagickSignature);
228
status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
230
ThrowWriterException(FileOpenError,UnableToOpenFile,image);
232
TransformColorspace(image,RGBColorspace);
233
clone_info=CloneImageInfo(image_info);
234
clone_info->quality=0;
238
SetGeometry(image,&geometry);
239
(void) GetMagickGeometry(DefaultPreviewGeometry,&geometry.x,&geometry.y,
240
&geometry.width,&geometry.height);
241
images=NewImageList();
248
master_image=ResizeImage(image,geometry.width,geometry.height,
249
TriangleFilter,1.0,&image->exception);
250
if (master_image == (Image *) NULL)
252
for (i=0; i < NumberTiles; i++)
254
preview_image=CloneImage(master_image,0,0,True,&image->exception);
255
if (preview_image == (Image *) NULL)
257
(void) SetImageAttribute(preview_image,"label",DefaultTileLabel);
258
if (i == (NumberTiles >> 1))
260
(void) QueryColorDatabase("#dfdfdf",&preview_image->matte_color,
262
AppendImageToList(&images,preview_image);
265
handler=SetMonitorHandler((MonitorHandler) NULL);
266
switch (image_info->preview_type)
270
FormatString(factor,"%.1f",degrees+=45.0);
271
FormatString(label,"rotate %.1024s",factor);
272
ReplaceImage(preview_image,RotateImage(preview_image,degrees,
279
FormatString(factor,"%.1fx%.1f",degrees,2.0*degrees);
280
FormatString(label,"shear %.1024s",factor);
281
ReplaceImage(preview_image,ShearImage(preview_image,degrees,
282
2.0*degrees,&image->exception));
287
x=(long) ((i+1)*preview_image->columns)/NumberTiles;
288
y=(long) ((i+1)*preview_image->rows)/NumberTiles;
289
FormatString(factor,"%+ld%+ld",x,y);
290
FormatString(label,"roll %.1024s",factor);
291
ReplaceImage(preview_image,RollImage(preview_image,x,y,
297
FormatString(factor,"100/100/%g",2.0*percentage);
298
FormatString(label,"modulate %.1024s",factor);
299
(void) ModulateImage(preview_image,factor);
302
case SaturationPreview:
304
FormatString(factor,"100/%g",2.0*percentage);
305
FormatString(label,"modulate %.1024s",factor);
306
(void) ModulateImage(preview_image,factor);
309
case BrightnessPreview:
311
FormatString(factor,"%g",2.0*percentage);
312
FormatString(label,"modulate %.1024s",factor);
313
(void) ModulateImage(preview_image,factor);
319
FormatString(factor,"%g",gamma+=0.4f);
320
FormatString(label,"gamma %.1024s",factor);
321
(void) GammaImage(preview_image,factor);
326
for (x=0; x < i; x++)
327
(void) ContrastImage(preview_image,True);
328
FormatString(label,"-contrast %ld",i+1);
333
for (x=0; x < i; x++)
334
(void) ContrastImage(preview_image,False);
335
FormatString(label,"+contrast %ld",i+1);
338
case GrayscalePreview:
343
GetQuantizeInfo(&quantize_info);
344
FormatString(factor,"%lu",colors);
345
FormatString(label,"colors %.1024s",factor);
346
TransformColorspace(preview_image,GRAYColorspace);
347
quantize_info.number_colors=colors;
348
quantize_info.colorspace=GRAYColorspace;
349
quantize_info.dither=image_info->dither;
350
quantize_info.tree_depth=8;
351
(void) QuantizeImage(&quantize_info,preview_image);
355
case QuantizePreview:
360
GetQuantizeInfo(&quantize_info);
361
FormatString(factor,"%lu",colors);
362
FormatString(label,"colors %.1024s",factor);
363
quantize_info.number_colors=colors;
364
quantize_info.colorspace=preview_image->colorspace;
365
quantize_info.dither=image_info->dither;
366
quantize_info.tree_depth=8;
367
(void) QuantizeImage(&quantize_info,preview_image);
371
case DespecklePreview:
373
for (x=0; x < i; x++)
375
ReplaceImage(preview_image,DespeckleImage(preview_image,
378
FormatString(label,"despeckle %ld",i+1);
381
case ReduceNoisePreview:
383
FormatString(factor,"%gx%g",radius,sigma);
384
FormatString(label,"noise %.1024s",factor);
385
ReplaceImage(preview_image,ReduceNoiseImage(preview_image,radius,
389
case AddNoisePreview:
397
(void) strcpy(factor,"uniform");
401
(void) strcpy(factor,"Gaussian");
405
(void) strcpy(factor,"multiplicative");
406
noise=MultiplicativeGaussianNoise;
409
(void) strcpy(factor,"impulse");
413
(void) strcpy(factor,"laplacian");
414
noise=LaplacianNoise;
417
(void) strcpy(factor,"Poisson");
421
(void) strcpy(preview_image->magick,"NULL");
426
FormatString(label,"+noise %.1024s",factor);
427
ReplaceImage(preview_image,AddNoiseImage(preview_image,noise,
433
FormatString(factor,"%gx%g",radius,sigma);
434
FormatString(label,"sharpen %.1024s",factor);
435
ReplaceImage(preview_image,SharpenImage(preview_image,radius,sigma,
441
FormatString(factor,"%gx%g",radius,sigma);
442
FormatString(label,"-blur %.1024s",factor);
443
ReplaceImage(preview_image,BlurImage(preview_image,radius,sigma,
447
case ThresholdPreview:
449
FormatString(factor,"%lu",(unsigned long)
450
((percentage*((double) MaxRGB+1.0))/100));
451
FormatString(label,"threshold %.1024s",factor);
452
(void ) ThresholdImage(preview_image,
453
(percentage*((double) MaxRGB+1.0))/100);
456
case EdgeDetectPreview:
458
FormatString(factor,"%gx%g",radius,sigma);
459
FormatString(label,"edge %.1024s",factor);
460
ReplaceImage(preview_image,EdgeImage(preview_image,radius,
466
FormatString(factor,"%ld",i+1);
467
FormatString(label,"spread %.1024s",factor);
468
ReplaceImage(preview_image,SpreadImage(preview_image,i+1,
472
case SolarizePreview:
474
FormatString(factor,"%g",percentage);
475
FormatString(label,"solarize %.1024s",factor);
476
SolarizeImage(preview_image,percentage);
483
FormatString(factor,"30x30");
484
FormatString(label,"+shade %.1024s",factor);
485
ReplaceImage(preview_image,ShadeImage(preview_image,False,30,30,
490
FormatString(factor,"%gx%g",degrees,degrees);
491
FormatString(label,"shade %.1024s",factor);
492
ReplaceImage(preview_image,ShadeImage(preview_image,True,degrees,
493
degrees,&image->exception));
501
raise_info.width=2*i+2;
502
raise_info.height=2*i+2;
505
FormatString(factor,"%ldx%ld",2*i+2,2*i+2);
506
FormatString(label,"raise %.1024s",factor);
507
RaiseImage(preview_image,&raise_info,True);
513
FormatString(factor,"%.1fx%.1f",threshold,threshold);
514
FormatString(label,"segment %.1024s",factor);
515
(void) SegmentImage(preview_image,preview_image->colorspace,False,
516
threshold,threshold);
521
FormatString(factor,"%.1f",degrees);
522
FormatString(label,"swirl %.1024s",factor);
523
ReplaceImage(preview_image,SwirlImage(preview_image,degrees,
530
FormatString(factor,"%.1f",percentage/100.0);
531
FormatString(label,"implode %.1024s",factor);
532
ReplaceImage(preview_image,ImplodeImage(preview_image,
533
percentage/100.0,&image->exception));
539
FormatString(factor,"%.1fx%.1f",0.5*degrees,2.0*degrees);
540
FormatString(label,"wave %.1024s",factor);
541
ReplaceImage(preview_image,WaveImage(preview_image,0.5*degrees,
542
2.0*degrees,&image->exception));
545
case OilPaintPreview:
547
FormatString(factor,"%g",0.5*(i+1));
548
FormatString(label,"paint %.1024s",factor);
549
ReplaceImage(preview_image,OilPaintImage(preview_image,0.5*(i+1),
553
case CharcoalDrawingPreview:
555
FormatString(factor,"%gx%g",radius,sigma);
556
FormatString(label,"charcoal %.1024s",factor);
557
ReplaceImage(preview_image,CharcoalImage(preview_image,radius,sigma,
564
filename[MaxTextExtent];
566
clone_info->quality=(unsigned int) (percentage+13.0);
567
FormatString(factor,"%lu",clone_info->quality);
568
if(!AcquireTemporaryFileName(filename))
570
DestroyImage(master_image);
571
DestroyImageInfo(clone_info);
572
ThrowWriterTemporaryFileException(filename);
574
FormatString(preview_image->filename,"jpeg:%.1024s",filename);
575
status=WriteImage(clone_info,preview_image);
581
(void) strncpy(clone_info->filename,preview_image->filename,
583
quality_image=ReadImage(clone_info,&image->exception);
584
if (quality_image != (Image *) NULL)
586
DestroyImage(preview_image);
587
preview_image=quality_image;
590
LiberateTemporaryFile(filename);
591
if ((GetBlobSize(preview_image)/1024) >= 1024)
592
FormatString(label,"quality %.1024s\n%gmb ",factor,
593
(double) GetBlobSize(preview_image)/1024.0/1024.0);
595
if (GetBlobSize(preview_image) >= 1024)
596
FormatString(label,"quality %.1024s\n%gkb ",factor,
597
(double) GetBlobSize(preview_image)/1024.0);
599
FormatString(label,"quality %.1024s\n%lub ",factor,
600
(unsigned long) GetBlobSize(preview_image));
607
(void) SetImageAttribute(preview_image,"label",(char *) NULL);
608
(void) SetImageAttribute(preview_image,"label",label);
609
(void) SetMonitorHandler(handler);
610
AppendImageToList(&images,preview_image);
611
if (!MagickMonitor(PreviewImageText,i,NumberTiles,&image->exception))
614
DestroyImage(master_image);
615
DestroyImageInfo(clone_info);
616
if (images == (Image *) NULL)
621
montage_info=CloneMontageInfo(image_info,(MontageInfo *) NULL);
622
(void) strncpy(montage_info->filename,image->filename,MaxTextExtent-1);
623
montage_info->shadow=True;
624
(void) CloneString(&montage_info->tile,"3x3");
625
(void) CloneString(&montage_info->geometry,DefaultPreviewGeometry);
626
(void) CloneString(&montage_info->frame,DefaultTileFrame);
627
montage_image=MontageImages(images,montage_info,&image->exception);
628
DestroyMontageInfo(montage_info);
629
DestroyImageList(images);
630
if (montage_image == (Image *) NULL)
631
ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
632
if (montage_image->montage != (char *) NULL)
635
Free image directory.
637
MagickFreeMemory(montage_image->montage);
638
montage_image->montage=(char *) NULL;
639
if (image->directory != (char *) NULL)
641
MagickFreeMemory(montage_image->directory);
642
montage_image->directory=(char *) NULL;
645
FormatString(montage_image->filename,"miff:%.1024s",image_info->filename);
646
status=WriteImage(image_info,montage_image);
647
DestroyImage(montage_image);