blob: 6dd5f0d9218f1543f7208f7b2d8e07db3883508f [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% %
cristy1454be72011-12-19 01:52:48 +000020% Copyright 1999-2012 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,
cristyc82a27b2011-10-21 01:07:16 +0000101 double y,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000102{
cristy3ed852e2009-09-05 21:47:34 +0000103 QuantumAny
104 range;
105
cristy4c08aed2011-07-01 19:47:50 +0000106 register Quantum
cristy3ed852e2009-09-05 21:47:34 +0000107 *q;
108
cristybb503372010-05-27 20:51:26 +0000109 q=GetAuthenticPixels(image,(ssize_t) ceil(x-0.5),(ssize_t) ceil(y-0.5),1,1,
cristy3ed852e2009-09-05 21:47:34 +0000110 exception);
cristyacd2ed22011-08-30 01:44:23 +0000111 if (q == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000112 return;
113 range=GetQuantumRange(16UL);
cristy4c08aed2011-07-01 19:47:50 +0000114 SetPixelRed(image,ScaleAnyToQuantum((size_t) (65535.0*
115 GetPseudoRandomValue(random_info)+0.5),range),q);
116 SetPixelGreen(image,ScaleAnyToQuantum((size_t) (65535.0*
117 GetPseudoRandomValue(random_info)+0.5),range),q);
118 SetPixelBlue(image,ScaleAnyToQuantum((size_t) (65535.0*
119 GetPseudoRandomValue(random_info)+0.5),range),q);
cristy3ed852e2009-09-05 21:47:34 +0000120 (void) SyncAuthenticPixels(image,exception);
121}
122
123static Image *ReadPlasmaImage(const ImageInfo *image_info,
124 ExceptionInfo *exception)
125{
126 Image
127 *image;
128
129 ImageInfo
130 *read_info;
131
cristy3ed852e2009-09-05 21:47:34 +0000132 MagickBooleanType
133 status;
134
cristybb503372010-05-27 20:51:26 +0000135 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000136 x;
137
cristy4c08aed2011-07-01 19:47:50 +0000138 register Quantum
cristy3ed852e2009-09-05 21:47:34 +0000139 *q;
140
cristybb503372010-05-27 20:51:26 +0000141 register size_t
cristy3ed852e2009-09-05 21:47:34 +0000142 i;
143
144 SegmentInfo
145 segment_info;
146
cristybb503372010-05-27 20:51:26 +0000147 size_t
cristy3ed852e2009-09-05 21:47:34 +0000148 depth,
149 max_depth;
150
cristyaff6d802011-04-26 01:46:31 +0000151 ssize_t
152 y;
153
cristy3ed852e2009-09-05 21:47:34 +0000154 /*
155 Recursively apply plasma to the image.
156 */
157 read_info=CloneImageInfo(image_info);
158 SetImageInfoBlob(read_info,(void *) NULL,0);
cristyb51dff52011-05-19 16:55:47 +0000159 (void) FormatLocaleString(read_info->filename,MaxTextExtent,
cristy3ed852e2009-09-05 21:47:34 +0000160 "gradient:%s",image_info->filename);
161 image=ReadImage(read_info,exception);
162 read_info=DestroyImageInfo(read_info);
163 if (image == (Image *) NULL)
164 return((Image *) NULL);
cristy9cd32fb2012-06-20 00:59:59 +0000165 (void) SetImageStorageClass(image,DirectClass,exception);
cristybb503372010-05-27 20:51:26 +0000166 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000167 {
168 q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
cristyacd2ed22011-08-30 01:44:23 +0000169 if (q == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000170 break;
cristybb503372010-05-27 20:51:26 +0000171 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +0000172 {
cristy4c08aed2011-07-01 19:47:50 +0000173 SetPixelAlpha(image,QuantumRange/2,q);
cristyed231572011-07-14 02:18:59 +0000174 q+=GetPixelChannels(image);
cristy3ed852e2009-09-05 21:47:34 +0000175 }
176 if (SyncAuthenticPixels(image,exception) == MagickFalse)
177 break;
178 }
179 segment_info.x1=0;
180 segment_info.y1=0;
181 segment_info.x2=(double) image->columns-1;
182 segment_info.y2=(double) image->rows-1;
183 if (LocaleCompare(image_info->filename,"fractal") == 0)
184 {
185 RandomInfo
186 *random_info;
187
188 /*
189 Seed pixels before recursion.
190 */
cristy9cd32fb2012-06-20 00:59:59 +0000191 (void) SetImageColorspace(image,sRGBColorspace,exception);
cristy3ed852e2009-09-05 21:47:34 +0000192 random_info=AcquireRandomInfo();
cristyc82a27b2011-10-21 01:07:16 +0000193 PlasmaPixel(image,random_info,segment_info.x1,segment_info.y1,exception);
cristy3ed852e2009-09-05 21:47:34 +0000194 PlasmaPixel(image,random_info,segment_info.x1,(segment_info.y1+
cristyc82a27b2011-10-21 01:07:16 +0000195 segment_info.y2)/2,exception);
196 PlasmaPixel(image,random_info,segment_info.x1,segment_info.y2,exception);
cristy3ed852e2009-09-05 21:47:34 +0000197 PlasmaPixel(image,random_info,(segment_info.x1+segment_info.x2)/2,
cristyc82a27b2011-10-21 01:07:16 +0000198 segment_info.y1,exception);
cristy3ed852e2009-09-05 21:47:34 +0000199 PlasmaPixel(image,random_info,(segment_info.x1+segment_info.x2)/2,
cristyc82a27b2011-10-21 01:07:16 +0000200 (segment_info.y1+segment_info.y2)/2,exception);
cristy3ed852e2009-09-05 21:47:34 +0000201 PlasmaPixel(image,random_info,(segment_info.x1+segment_info.x2)/2,
cristyc82a27b2011-10-21 01:07:16 +0000202 segment_info.y2,exception);
203 PlasmaPixel(image,random_info,segment_info.x2,segment_info.y1,exception);
cristy3ed852e2009-09-05 21:47:34 +0000204 PlasmaPixel(image,random_info,segment_info.x2,(segment_info.y1+
cristyc82a27b2011-10-21 01:07:16 +0000205 segment_info.y2)/2,exception);
206 PlasmaPixel(image,random_info,segment_info.x2,segment_info.y2,exception);
cristy3ed852e2009-09-05 21:47:34 +0000207 random_info=DestroyRandomInfo(random_info);
208 }
cristybb503372010-05-27 20:51:26 +0000209 i=(size_t) MagickMax(image->columns,image->rows)/2;
cristy3ed852e2009-09-05 21:47:34 +0000210 for (max_depth=0; i != 0; max_depth++)
211 i>>=1;
212 for (depth=1; ; depth++)
213 {
cristy5cbc0162011-08-29 00:36:28 +0000214 if (PlasmaImage(image,&segment_info,0,depth,exception) != MagickFalse)
cristy3ed852e2009-09-05 21:47:34 +0000215 break;
216 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) depth,
217 max_depth);
218 if (status == MagickFalse)
219 break;
220 }
cristy63240882011-08-05 19:05:27 +0000221 (void) SetImageAlphaChannel(image,DeactivateAlphaChannel,exception);
cristy3ed852e2009-09-05 21:47:34 +0000222 return(GetFirstImageInList(image));
223}
224
225/*
226%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
227% %
228% %
229% %
230% R e g i s t e r P L A S M A I m a g e %
231% %
232% %
233% %
234%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
235%
236% RegisterPLASMAImage() adds attributes for the Plasma image format to
237% the list of supported formats. The attributes include the image format
238% tag, a method to read and/or write the format, whether the format
239% supports the saving of more than one frame to the same file or blob,
240% whether the format supports native in-memory I/O, and a brief
241% description of the format.
242%
243% The format of the RegisterPLASMAImage method is:
244%
cristybb503372010-05-27 20:51:26 +0000245% size_t RegisterPLASMAImage(void)
cristy3ed852e2009-09-05 21:47:34 +0000246%
247*/
cristybb503372010-05-27 20:51:26 +0000248ModuleExport size_t RegisterPLASMAImage(void)
cristy3ed852e2009-09-05 21:47:34 +0000249{
250 MagickInfo
251 *entry;
252
253 entry=SetMagickInfo("PLASMA");
254 entry->decoder=(DecodeImageHandler *) ReadPlasmaImage;
255 entry->adjoin=MagickFalse;
cristy009d7392010-07-25 22:08:41 +0000256 entry->format_type=ImplicitFormatType;
cristy3ed852e2009-09-05 21:47:34 +0000257 entry->description=ConstantString("Plasma fractal image");
258 entry->module=ConstantString("PLASMA");
259 (void) RegisterMagickInfo(entry);
260 entry=SetMagickInfo("FRACTAL");
261 entry->decoder=(DecodeImageHandler *) ReadPlasmaImage;
262 entry->adjoin=MagickFalse;
cristy009d7392010-07-25 22:08:41 +0000263 entry->format_type=ImplicitFormatType;
cristy3ed852e2009-09-05 21:47:34 +0000264 entry->description=ConstantString("Plasma fractal image");
265 entry->module=ConstantString("PLASMA");
266 (void) RegisterMagickInfo(entry);
267 return(MagickImageCoderSignature);
268}
269
270/*
271%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
272% %
273% %
274% %
275% U n r e g i s t e r P L A S M A I m a g e %
276% %
277% %
278% %
279%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
280%
281% UnregisterPLASMAImage() removes format registrations made by the
282% PLASMA module from the list of supported formats.
283%
284% The format of the UnregisterPLASMAImage method is:
285%
286% UnregisterPLASMAImage(void)
287%
288*/
289ModuleExport void UnregisterPLASMAImage(void)
290{
291 (void) UnregisterMagickInfo("FRACTAL");
292 (void) UnregisterMagickInfo("PLASMA");
293}