blob: 1f5cb4a9864ad728ed23686eb6b3f6b78286ca5a [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% PPPP L AAA SSSSS M M AAA %
7% P P L A A SS MM MM A A %
8% PPPP L AAAAA SSS M M M AAAAA %
9% P L A A SS M M A A %
10% P LLLLL A A SSSSS M M A A %
11% %
12% %
13% Read a Plasma Image. %
14% %
15% Software Design %
16% John Cristy %
17% July 1992 %
18% %
19% %
cristy7e41fe82010-12-04 23:12:08 +000020% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000021% dedicated to making software imaging solutions freely available. %
22% %
23% You may not use this file except in compliance with the License. You may %
24% obtain a copy of the License at %
25% %
26% http://www.imagemagick.org/script/license.php %
27% %
28% Unless required by applicable law or agreed to in writing, software %
29% distributed under the License is distributed on an "AS IS" BASIS, %
30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31% See the License for the specific language governing permissions and %
32% limitations under the License. %
33% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36%
37*/
38
39/*
40 Include declarations.
41*/
cristy4c08aed2011-07-01 19:47:50 +000042#include "MagickCore/studio.h"
43#include "MagickCore/blob.h"
44#include "MagickCore/blob-private.h"
45#include "MagickCore/cache.h"
46#include "MagickCore/constitute.h"
47#include "MagickCore/exception.h"
48#include "MagickCore/exception-private.h"
49#include "MagickCore/fx.h"
50#include "MagickCore/image.h"
51#include "MagickCore/image-private.h"
52#include "MagickCore/list.h"
53#include "MagickCore/magick.h"
54#include "MagickCore/memory_.h"
55#include "MagickCore/monitor.h"
56#include "MagickCore/monitor-private.h"
57#include "MagickCore/pixel-accessor.h"
58#include "MagickCore/random_.h"
59#include "MagickCore/random-private.h"
60#include "MagickCore/signature-private.h"
61#include "MagickCore/quantum-private.h"
62#include "MagickCore/static.h"
63#include "MagickCore/string_.h"
64#include "MagickCore/module.h"
cristy3ed852e2009-09-05 21:47:34 +000065
66/*
67%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
68% %
69% %
70% %
71% R e a d P L A S M A I m a g e %
72% %
73% %
74% %
75%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
76%
77% ReadPlasmaImage creates a plasma fractal image. The image is
78% initialized to the X server color as specified by the filename.
79%
80% The format of the ReadPlasmaImage method is:
81%
82% Image *ReadPlasmaImage(const ImageInfo *image_info,
83% ExceptionInfo *exception)
84%
85% A description of each parameter follows:
86%
87% o image_info: the image info.
88%
89% o exception: return any errors or warnings in this structure.
90%
91*/
92
93static inline size_t MagickMax(const size_t x,const size_t y)
94{
95 if (x > y)
96 return(x);
97 return(y);
98}
99
100static inline void PlasmaPixel(Image *image,RandomInfo *random_info,double x,
101 double y)
102{
103 ExceptionInfo
104 *exception;
105
106 QuantumAny
107 range;
108
cristy4c08aed2011-07-01 19:47:50 +0000109 register Quantum
cristy3ed852e2009-09-05 21:47:34 +0000110 *q;
111
112 exception=(&image->exception);
cristybb503372010-05-27 20:51:26 +0000113 q=GetAuthenticPixels(image,(ssize_t) ceil(x-0.5),(ssize_t) ceil(y-0.5),1,1,
cristy3ed852e2009-09-05 21:47:34 +0000114 exception);
cristy4c08aed2011-07-01 19:47:50 +0000115 if (q == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000116 return;
117 range=GetQuantumRange(16UL);
cristy4c08aed2011-07-01 19:47:50 +0000118 SetPixelRed(image,ScaleAnyToQuantum((size_t) (65535.0*
119 GetPseudoRandomValue(random_info)+0.5),range),q);
120 SetPixelGreen(image,ScaleAnyToQuantum((size_t) (65535.0*
121 GetPseudoRandomValue(random_info)+0.5),range),q);
122 SetPixelBlue(image,ScaleAnyToQuantum((size_t) (65535.0*
123 GetPseudoRandomValue(random_info)+0.5),range),q);
cristy3ed852e2009-09-05 21:47:34 +0000124 (void) SyncAuthenticPixels(image,exception);
125}
126
127static Image *ReadPlasmaImage(const ImageInfo *image_info,
128 ExceptionInfo *exception)
129{
130 Image
131 *image;
132
133 ImageInfo
134 *read_info;
135
cristy3ed852e2009-09-05 21:47:34 +0000136 MagickBooleanType
137 status;
138
cristybb503372010-05-27 20:51:26 +0000139 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000140 x;
141
cristy4c08aed2011-07-01 19:47:50 +0000142 register Quantum
cristy3ed852e2009-09-05 21:47:34 +0000143 *q;
144
cristybb503372010-05-27 20:51:26 +0000145 register size_t
cristy3ed852e2009-09-05 21:47:34 +0000146 i;
147
148 SegmentInfo
149 segment_info;
150
cristybb503372010-05-27 20:51:26 +0000151 size_t
cristy3ed852e2009-09-05 21:47:34 +0000152 depth,
153 max_depth;
154
cristyaff6d802011-04-26 01:46:31 +0000155 ssize_t
156 y;
157
cristy3ed852e2009-09-05 21:47:34 +0000158 /*
159 Recursively apply plasma to the image.
160 */
161 read_info=CloneImageInfo(image_info);
162 SetImageInfoBlob(read_info,(void *) NULL,0);
cristyb51dff52011-05-19 16:55:47 +0000163 (void) FormatLocaleString(read_info->filename,MaxTextExtent,
cristy3ed852e2009-09-05 21:47:34 +0000164 "gradient:%s",image_info->filename);
165 image=ReadImage(read_info,exception);
166 read_info=DestroyImageInfo(read_info);
167 if (image == (Image *) NULL)
168 return((Image *) NULL);
169 image->storage_class=DirectClass;
cristybb503372010-05-27 20:51:26 +0000170 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000171 {
172 q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +0000173 if (q == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000174 break;
cristybb503372010-05-27 20:51:26 +0000175 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +0000176 {
cristy4c08aed2011-07-01 19:47:50 +0000177 SetPixelAlpha(image,QuantumRange/2,q);
cristyed231572011-07-14 02:18:59 +0000178 q+=GetPixelChannels(image);
cristy3ed852e2009-09-05 21:47:34 +0000179 }
180 if (SyncAuthenticPixels(image,exception) == MagickFalse)
181 break;
182 }
183 segment_info.x1=0;
184 segment_info.y1=0;
185 segment_info.x2=(double) image->columns-1;
186 segment_info.y2=(double) image->rows-1;
187 if (LocaleCompare(image_info->filename,"fractal") == 0)
188 {
189 RandomInfo
190 *random_info;
191
192 /*
193 Seed pixels before recursion.
194 */
195 random_info=AcquireRandomInfo();
196 PlasmaPixel(image,random_info,segment_info.x1,segment_info.y1);
197 PlasmaPixel(image,random_info,segment_info.x1,(segment_info.y1+
198 segment_info.y2)/2);
199 PlasmaPixel(image,random_info,segment_info.x1,segment_info.y2);
200 PlasmaPixel(image,random_info,(segment_info.x1+segment_info.x2)/2,
201 segment_info.y1);
202 PlasmaPixel(image,random_info,(segment_info.x1+segment_info.x2)/2,
203 (segment_info.y1+segment_info.y2)/2);
204 PlasmaPixel(image,random_info,(segment_info.x1+segment_info.x2)/2,
205 segment_info.y2);
206 PlasmaPixel(image,random_info,segment_info.x2,segment_info.y1);
207 PlasmaPixel(image,random_info,segment_info.x2,(segment_info.y1+
208 segment_info.y2)/2);
209 PlasmaPixel(image,random_info,segment_info.x2,segment_info.y2);
210 random_info=DestroyRandomInfo(random_info);
211 }
cristybb503372010-05-27 20:51:26 +0000212 i=(size_t) MagickMax(image->columns,image->rows)/2;
cristy3ed852e2009-09-05 21:47:34 +0000213 for (max_depth=0; i != 0; max_depth++)
214 i>>=1;
215 for (depth=1; ; depth++)
216 {
217 if (PlasmaImage(image,&segment_info,0,depth) != MagickFalse)
218 break;
219 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) depth,
220 max_depth);
221 if (status == MagickFalse)
222 break;
223 }
cristy63240882011-08-05 19:05:27 +0000224 (void) SetImageAlphaChannel(image,DeactivateAlphaChannel,exception);
cristy3ed852e2009-09-05 21:47:34 +0000225 return(GetFirstImageInList(image));
226}
227
228/*
229%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
230% %
231% %
232% %
233% R e g i s t e r P L A S M A I m a g e %
234% %
235% %
236% %
237%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
238%
239% RegisterPLASMAImage() adds attributes for the Plasma image format to
240% the list of supported formats. The attributes include the image format
241% tag, a method to read and/or write the format, whether the format
242% supports the saving of more than one frame to the same file or blob,
243% whether the format supports native in-memory I/O, and a brief
244% description of the format.
245%
246% The format of the RegisterPLASMAImage method is:
247%
cristybb503372010-05-27 20:51:26 +0000248% size_t RegisterPLASMAImage(void)
cristy3ed852e2009-09-05 21:47:34 +0000249%
250*/
cristybb503372010-05-27 20:51:26 +0000251ModuleExport size_t RegisterPLASMAImage(void)
cristy3ed852e2009-09-05 21:47:34 +0000252{
253 MagickInfo
254 *entry;
255
256 entry=SetMagickInfo("PLASMA");
257 entry->decoder=(DecodeImageHandler *) ReadPlasmaImage;
258 entry->adjoin=MagickFalse;
cristy009d7392010-07-25 22:08:41 +0000259 entry->format_type=ImplicitFormatType;
cristy3ed852e2009-09-05 21:47:34 +0000260 entry->description=ConstantString("Plasma fractal image");
261 entry->module=ConstantString("PLASMA");
262 (void) RegisterMagickInfo(entry);
263 entry=SetMagickInfo("FRACTAL");
264 entry->decoder=(DecodeImageHandler *) ReadPlasmaImage;
265 entry->adjoin=MagickFalse;
cristy009d7392010-07-25 22:08:41 +0000266 entry->format_type=ImplicitFormatType;
cristy3ed852e2009-09-05 21:47:34 +0000267 entry->description=ConstantString("Plasma fractal image");
268 entry->module=ConstantString("PLASMA");
269 (void) RegisterMagickInfo(entry);
270 return(MagickImageCoderSignature);
271}
272
273/*
274%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
275% %
276% %
277% %
278% U n r e g i s t e r P L A S M A I m a g e %
279% %
280% %
281% %
282%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
283%
284% UnregisterPLASMAImage() removes format registrations made by the
285% PLASMA module from the list of supported formats.
286%
287% The format of the UnregisterPLASMAImage method is:
288%
289% UnregisterPLASMAImage(void)
290%
291*/
292ModuleExport void UnregisterPLASMAImage(void)
293{
294 (void) UnregisterMagickInfo("FRACTAL");
295 (void) UnregisterMagickInfo("PLASMA");
296}