blob: ac2eb6e5aa01b9ffae350762f1c7d6f22ee09f0b [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*/
42#include "magick/studio.h"
43#include "magick/blob.h"
44#include "magick/blob-private.h"
45#include "magick/cache.h"
46#include "magick/constitute.h"
47#include "magick/exception.h"
48#include "magick/exception-private.h"
49#include "magick/fx.h"
50#include "magick/image.h"
51#include "magick/image-private.h"
52#include "magick/list.h"
53#include "magick/magick.h"
54#include "magick/memory_.h"
55#include "magick/monitor.h"
56#include "magick/monitor-private.h"
57#include "magick/random_.h"
58#include "magick/random-private.h"
59#include "magick/signature-private.h"
60#include "magick/quantum-private.h"
61#include "magick/static.h"
62#include "magick/string_.h"
63#include "magick/module.h"
64
65/*
66%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
67% %
68% %
69% %
70% R e a d P L A S M A I m a g e %
71% %
72% %
73% %
74%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75%
76% ReadPlasmaImage creates a plasma fractal image. The image is
77% initialized to the X server color as specified by the filename.
78%
79% The format of the ReadPlasmaImage method is:
80%
81% Image *ReadPlasmaImage(const ImageInfo *image_info,
82% ExceptionInfo *exception)
83%
84% A description of each parameter follows:
85%
86% o image_info: the image info.
87%
88% o exception: return any errors or warnings in this structure.
89%
90*/
91
92static inline size_t MagickMax(const size_t x,const size_t y)
93{
94 if (x > y)
95 return(x);
96 return(y);
97}
98
99static inline void PlasmaPixel(Image *image,RandomInfo *random_info,double x,
100 double y)
101{
102 ExceptionInfo
103 *exception;
104
105 QuantumAny
106 range;
107
108 register PixelPacket
109 *q;
110
111 exception=(&image->exception);
cristybb503372010-05-27 20:51:26 +0000112 q=GetAuthenticPixels(image,(ssize_t) ceil(x-0.5),(ssize_t) ceil(y-0.5),1,1,
cristy3ed852e2009-09-05 21:47:34 +0000113 exception);
114 if (q == (PixelPacket *) NULL)
115 return;
116 range=GetQuantumRange(16UL);
cristybb503372010-05-27 20:51:26 +0000117 q->red=ScaleAnyToQuantum((size_t) (65535.0*
cristy3ed852e2009-09-05 21:47:34 +0000118 GetPseudoRandomValue(random_info)+0.5),range);
cristybb503372010-05-27 20:51:26 +0000119 q->green=ScaleAnyToQuantum((size_t) (65535.0*
cristy3ed852e2009-09-05 21:47:34 +0000120 GetPseudoRandomValue(random_info)+0.5),range);
cristybb503372010-05-27 20:51:26 +0000121 q->blue=ScaleAnyToQuantum((size_t) (65535.0*
cristy3ed852e2009-09-05 21:47:34 +0000122 GetPseudoRandomValue(random_info)+0.5),range);
123 (void) SyncAuthenticPixels(image,exception);
124}
125
126static Image *ReadPlasmaImage(const ImageInfo *image_info,
127 ExceptionInfo *exception)
128{
129 Image
130 *image;
131
132 ImageInfo
133 *read_info;
134
cristybb503372010-05-27 20:51:26 +0000135 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000136 y;
137
138 MagickBooleanType
139 status;
140
cristybb503372010-05-27 20:51:26 +0000141 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000142 x;
143
144 register PixelPacket
145 *q;
146
cristybb503372010-05-27 20:51:26 +0000147 register size_t
cristy3ed852e2009-09-05 21:47:34 +0000148 i;
149
150 SegmentInfo
151 segment_info;
152
cristybb503372010-05-27 20:51:26 +0000153 size_t
cristy3ed852e2009-09-05 21:47:34 +0000154 depth,
155 max_depth;
156
157 /*
158 Recursively apply plasma to the image.
159 */
160 read_info=CloneImageInfo(image_info);
161 SetImageInfoBlob(read_info,(void *) NULL,0);
162 (void) FormatMagickString(read_info->filename,MaxTextExtent,
163 "gradient:%s",image_info->filename);
164 image=ReadImage(read_info,exception);
165 read_info=DestroyImageInfo(read_info);
166 if (image == (Image *) NULL)
167 return((Image *) NULL);
168 image->storage_class=DirectClass;
cristybb503372010-05-27 20:51:26 +0000169 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000170 {
171 q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
172 if (q == (PixelPacket *) NULL)
173 break;
cristybb503372010-05-27 20:51:26 +0000174 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +0000175 {
176 q->opacity=(Quantum) (QuantumRange/2);
177 q++;
178 }
179 if (SyncAuthenticPixels(image,exception) == MagickFalse)
180 break;
181 }
182 segment_info.x1=0;
183 segment_info.y1=0;
184 segment_info.x2=(double) image->columns-1;
185 segment_info.y2=(double) image->rows-1;
186 if (LocaleCompare(image_info->filename,"fractal") == 0)
187 {
188 RandomInfo
189 *random_info;
190
191 /*
192 Seed pixels before recursion.
193 */
194 random_info=AcquireRandomInfo();
195 PlasmaPixel(image,random_info,segment_info.x1,segment_info.y1);
196 PlasmaPixel(image,random_info,segment_info.x1,(segment_info.y1+
197 segment_info.y2)/2);
198 PlasmaPixel(image,random_info,segment_info.x1,segment_info.y2);
199 PlasmaPixel(image,random_info,(segment_info.x1+segment_info.x2)/2,
200 segment_info.y1);
201 PlasmaPixel(image,random_info,(segment_info.x1+segment_info.x2)/2,
202 (segment_info.y1+segment_info.y2)/2);
203 PlasmaPixel(image,random_info,(segment_info.x1+segment_info.x2)/2,
204 segment_info.y2);
205 PlasmaPixel(image,random_info,segment_info.x2,segment_info.y1);
206 PlasmaPixel(image,random_info,segment_info.x2,(segment_info.y1+
207 segment_info.y2)/2);
208 PlasmaPixel(image,random_info,segment_info.x2,segment_info.y2);
209 random_info=DestroyRandomInfo(random_info);
210 }
cristybb503372010-05-27 20:51:26 +0000211 i=(size_t) MagickMax(image->columns,image->rows)/2;
cristy3ed852e2009-09-05 21:47:34 +0000212 for (max_depth=0; i != 0; max_depth++)
213 i>>=1;
214 for (depth=1; ; depth++)
215 {
216 if (PlasmaImage(image,&segment_info,0,depth) != MagickFalse)
217 break;
218 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) depth,
219 max_depth);
220 if (status == MagickFalse)
221 break;
222 }
223 (void) SetImageAlphaChannel(image,DeactivateAlphaChannel);
224 return(GetFirstImageInList(image));
225}
226
227/*
228%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
229% %
230% %
231% %
232% R e g i s t e r P L A S M A I m a g e %
233% %
234% %
235% %
236%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
237%
238% RegisterPLASMAImage() adds attributes for the Plasma image format to
239% the list of supported formats. The attributes include the image format
240% tag, a method to read and/or write the format, whether the format
241% supports the saving of more than one frame to the same file or blob,
242% whether the format supports native in-memory I/O, and a brief
243% description of the format.
244%
245% The format of the RegisterPLASMAImage method is:
246%
cristybb503372010-05-27 20:51:26 +0000247% size_t RegisterPLASMAImage(void)
cristy3ed852e2009-09-05 21:47:34 +0000248%
249*/
cristybb503372010-05-27 20:51:26 +0000250ModuleExport size_t RegisterPLASMAImage(void)
cristy3ed852e2009-09-05 21:47:34 +0000251{
252 MagickInfo
253 *entry;
254
255 entry=SetMagickInfo("PLASMA");
256 entry->decoder=(DecodeImageHandler *) ReadPlasmaImage;
257 entry->adjoin=MagickFalse;
cristy009d7392010-07-25 22:08:41 +0000258 entry->format_type=ImplicitFormatType;
cristy3ed852e2009-09-05 21:47:34 +0000259 entry->description=ConstantString("Plasma fractal image");
260 entry->module=ConstantString("PLASMA");
261 (void) RegisterMagickInfo(entry);
262 entry=SetMagickInfo("FRACTAL");
263 entry->decoder=(DecodeImageHandler *) ReadPlasmaImage;
264 entry->adjoin=MagickFalse;
cristy009d7392010-07-25 22:08:41 +0000265 entry->format_type=ImplicitFormatType;
cristy3ed852e2009-09-05 21:47:34 +0000266 entry->description=ConstantString("Plasma fractal image");
267 entry->module=ConstantString("PLASMA");
268 (void) RegisterMagickInfo(entry);
269 return(MagickImageCoderSignature);
270}
271
272/*
273%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
274% %
275% %
276% %
277% U n r e g i s t e r P L A S M A I m a g e %
278% %
279% %
280% %
281%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
282%
283% UnregisterPLASMAImage() removes format registrations made by the
284% PLASMA module from the list of supported formats.
285%
286% The format of the UnregisterPLASMAImage method is:
287%
288% UnregisterPLASMAImage(void)
289%
290*/
291ModuleExport void UnregisterPLASMAImage(void)
292{
293 (void) UnregisterMagickInfo("FRACTAL");
294 (void) UnregisterMagickInfo("PLASMA");
295}