/src/imagemagick/coders/plasma.c
Line | Count | Source |
1 | | /* |
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 | | % Cristy % |
17 | | % July 1992 % |
18 | | % % |
19 | | % % |
20 | | % Copyright @ 1999 ImageMagick Studio LLC, a non-profit organization % |
21 | | % 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 | | % https://imagemagick.org/license/ % |
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 "MagickCore/studio.h" |
43 | | #include "MagickCore/blob.h" |
44 | | #include "MagickCore/blob-private.h" |
45 | | #include "MagickCore/cache.h" |
46 | | #include "MagickCore/channel.h" |
47 | | #include "MagickCore/colorspace-private.h" |
48 | | #include "MagickCore/constitute.h" |
49 | | #include "MagickCore/exception.h" |
50 | | #include "MagickCore/exception-private.h" |
51 | | #include "MagickCore/image.h" |
52 | | #include "MagickCore/image-private.h" |
53 | | #include "MagickCore/list.h" |
54 | | #include "MagickCore/magick.h" |
55 | | #include "MagickCore/memory_.h" |
56 | | #include "MagickCore/module.h" |
57 | | #include "MagickCore/monitor.h" |
58 | | #include "MagickCore/monitor-private.h" |
59 | | #include "MagickCore/pixel-accessor.h" |
60 | | #include "MagickCore/random_.h" |
61 | | #include "MagickCore/random-private.h" |
62 | | #include "MagickCore/signature-private.h" |
63 | | #include "MagickCore/quantum-private.h" |
64 | | #include "MagickCore/static.h" |
65 | | #include "MagickCore/string_.h" |
66 | | #include "MagickCore/visual-effects.h" |
67 | | |
68 | | /* |
69 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
70 | | % % |
71 | | % % |
72 | | % % |
73 | | % R e a d P L A S M A I m a g e % |
74 | | % % |
75 | | % % |
76 | | % % |
77 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
78 | | % |
79 | | % ReadPlasmaImage creates a plasma fractal image. The image is |
80 | | % initialized to the X server color as specified by the filename. |
81 | | % |
82 | | % The format of the ReadPlasmaImage method is: |
83 | | % |
84 | | % Image *ReadPlasmaImage(const ImageInfo *image_info, |
85 | | % ExceptionInfo *exception) |
86 | | % |
87 | | % A description of each parameter follows: |
88 | | % |
89 | | % o image_info: the image info. |
90 | | % |
91 | | % o exception: return any errors or warnings in this structure. |
92 | | % |
93 | | */ |
94 | | |
95 | | static inline MagickBooleanType PlasmaPixel(Image *image, |
96 | | RandomInfo *magick_restrict random_info,const double x,const double y, |
97 | | ExceptionInfo *exception) |
98 | 36 | { |
99 | 36 | Quantum |
100 | 36 | *q; |
101 | | |
102 | 36 | q=GetAuthenticPixels(image,(ssize_t) (x+0.5),(ssize_t) (y+0.5),1,1, |
103 | 36 | exception); |
104 | 36 | if (q == (Quantum *) NULL) |
105 | 0 | return(MagickFalse); |
106 | 36 | SetPixelRed(image,(Quantum) ((double) QuantumRange*GetPseudoRandomValue(random_info)+ |
107 | 36 | 0.5),q); |
108 | 36 | SetPixelGreen(image,(Quantum) ((double) QuantumRange*GetPseudoRandomValue(random_info)+ |
109 | 36 | 0.5),q); |
110 | 36 | SetPixelBlue(image,(Quantum) ((double) QuantumRange*GetPseudoRandomValue(random_info)+ |
111 | 36 | 0.5),q); |
112 | 36 | return(SyncAuthenticPixels(image,exception)); |
113 | 36 | } |
114 | | |
115 | | static Image *ReadPlasmaImage(const ImageInfo *image_info, |
116 | | ExceptionInfo *exception) |
117 | 5.11k | { |
118 | 5.11k | Image |
119 | 5.11k | *image; |
120 | | |
121 | 5.11k | ImageInfo |
122 | 5.11k | *read_info; |
123 | | |
124 | 5.11k | MagickStatusType |
125 | 5.11k | status; |
126 | | |
127 | 5.11k | ssize_t |
128 | 5.11k | x; |
129 | | |
130 | 5.11k | Quantum |
131 | 5.11k | *q; |
132 | | |
133 | 5.11k | size_t |
134 | 5.11k | i; |
135 | | |
136 | 5.11k | SegmentInfo |
137 | 5.11k | segment_info; |
138 | | |
139 | 5.11k | size_t |
140 | 5.11k | depth, |
141 | 5.11k | max_depth; |
142 | | |
143 | 5.11k | ssize_t |
144 | 5.11k | y; |
145 | | |
146 | | /* |
147 | | Recursively apply plasma to the image. |
148 | | */ |
149 | 5.11k | read_info=CloneImageInfo(image_info); |
150 | 5.11k | SetImageInfoBlob(read_info,(void *) NULL,0); |
151 | 5.11k | (void) FormatLocaleString(read_info->filename,MagickPathExtent, |
152 | 5.11k | "gradient:%s",image_info->filename); |
153 | 5.11k | image=ReadImage(read_info,exception); |
154 | 5.11k | read_info=DestroyImageInfo(read_info); |
155 | 5.11k | if (image == (Image *) NULL) |
156 | 2.40k | return((Image *) NULL); |
157 | 2.71k | (void) SetImageStorageClass(image,DirectClass,exception); |
158 | 2.71k | if (IsGrayColorspace(image->colorspace) != MagickFalse) |
159 | 99 | (void) SetImageColorspace(image,sRGBColorspace,exception); |
160 | 24.9k | for (y=0; y < (ssize_t) image->rows; y++) |
161 | 22.1k | { |
162 | 22.1k | q=GetAuthenticPixels(image,0,y,image->columns,1,exception); |
163 | 22.1k | if (q == (Quantum *) NULL) |
164 | 0 | break; |
165 | 1.40M | for (x=0; x < (ssize_t) image->columns; x++) |
166 | 1.38M | { |
167 | 1.38M | SetPixelAlpha(image,QuantumRange/2,q); |
168 | 1.38M | q+=(ptrdiff_t) GetPixelChannels(image); |
169 | 1.38M | } |
170 | 22.1k | if (SyncAuthenticPixels(image,exception) == MagickFalse) |
171 | 0 | break; |
172 | 22.1k | } |
173 | 2.71k | segment_info.x1=0; |
174 | 2.71k | segment_info.y1=0; |
175 | 2.71k | segment_info.x2=(double) image->columns-1; |
176 | 2.71k | segment_info.y2=(double) image->rows-1; |
177 | 2.71k | if (LocaleCompare(image_info->filename,"fractal") == 0) |
178 | 4 | { |
179 | 4 | RandomInfo |
180 | 4 | *random_info; |
181 | | |
182 | | /* |
183 | | Seed pixels before recursion. |
184 | | */ |
185 | 4 | (void) SetImageColorspace(image,sRGBColorspace,exception); |
186 | 4 | random_info=AcquireRandomInfo(); |
187 | 4 | status=PlasmaPixel(image,random_info,segment_info.x1,segment_info.y1, |
188 | 4 | exception); |
189 | 4 | status&=(MagickStatusType) PlasmaPixel(image,random_info,segment_info.x1, |
190 | 4 | (segment_info.y1+segment_info.y2)/2,exception); |
191 | 4 | status&=(MagickStatusType) PlasmaPixel(image,random_info,segment_info.x1, |
192 | 4 | segment_info.y2,exception); |
193 | 4 | status&=(MagickStatusType) PlasmaPixel(image,random_info,(segment_info.x1+ segment_info.x2)/2,segment_info.y1,exception); |
194 | 4 | status&=(MagickStatusType) PlasmaPixel(image,random_info,(segment_info.x1+ |
195 | 4 | segment_info.x2)/2,(segment_info.y1+segment_info.y2)/2,exception); |
196 | 4 | status&=(MagickStatusType) PlasmaPixel(image,random_info,(segment_info.x1+ |
197 | 4 | segment_info.x2)/2,segment_info.y2,exception); |
198 | 4 | status&=(MagickStatusType) PlasmaPixel(image,random_info,segment_info.x2, |
199 | 4 | segment_info.y1,exception); |
200 | 4 | status&=(MagickStatusType) PlasmaPixel(image,random_info,segment_info.x2, |
201 | 4 | (segment_info.y1+segment_info.y2)/2,exception); |
202 | 4 | status&=(MagickStatusType) PlasmaPixel(image,random_info,segment_info.x2, |
203 | 4 | segment_info.y2,exception); |
204 | 4 | random_info=DestroyRandomInfo(random_info); |
205 | 4 | if (status == MagickFalse) |
206 | 0 | return(image); |
207 | 4 | } |
208 | 2.71k | i=(size_t) MagickMax(image->columns,image->rows)/2; |
209 | 5.24k | for (max_depth=0; i != 0; max_depth++) |
210 | 2.52k | i>>=1; |
211 | 2.71k | for (depth=1; ; depth++) |
212 | 4.33k | { |
213 | 4.33k | if (PlasmaImage(image,&segment_info,0,depth,exception) != MagickFalse) |
214 | 2.71k | break; |
215 | 1.62k | status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) depth, |
216 | 1.62k | max_depth); |
217 | 1.62k | if (status == MagickFalse) |
218 | 0 | break; |
219 | 1.62k | } |
220 | 2.71k | return(GetFirstImageInList(image)); |
221 | 2.71k | } |
222 | | |
223 | | /* |
224 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
225 | | % % |
226 | | % % |
227 | | % % |
228 | | % R e g i s t e r P L A S M A I m a g e % |
229 | | % % |
230 | | % % |
231 | | % % |
232 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
233 | | % |
234 | | % RegisterPLASMAImage() adds attributes for the Plasma image format to |
235 | | % the list of supported formats. The attributes include the image format |
236 | | % tag, a method to read and/or write the format, whether the format |
237 | | % supports the saving of more than one frame to the same file or blob, |
238 | | % whether the format supports native in-memory I/O, and a brief |
239 | | % description of the format. |
240 | | % |
241 | | % The format of the RegisterPLASMAImage method is: |
242 | | % |
243 | | % size_t RegisterPLASMAImage(void) |
244 | | % |
245 | | */ |
246 | | ModuleExport size_t RegisterPLASMAImage(void) |
247 | 8 | { |
248 | 8 | MagickInfo |
249 | 8 | *entry; |
250 | | |
251 | 8 | entry=AcquireMagickInfo("PLASMA","PLASMA","Plasma fractal image"); |
252 | 8 | entry->decoder=(DecodeImageHandler *) ReadPlasmaImage; |
253 | 8 | entry->flags^=CoderAdjoinFlag; |
254 | 8 | entry->format_type=ImplicitFormatType; |
255 | 8 | (void) RegisterMagickInfo(entry); |
256 | 8 | entry=AcquireMagickInfo("PLASMA","FRACTAL","Plasma fractal image"); |
257 | 8 | entry->decoder=(DecodeImageHandler *) ReadPlasmaImage; |
258 | 8 | entry->flags^=CoderAdjoinFlag; |
259 | 8 | entry->format_type=ImplicitFormatType; |
260 | 8 | (void) RegisterMagickInfo(entry); |
261 | 8 | return(MagickImageCoderSignature); |
262 | 8 | } |
263 | | |
264 | | /* |
265 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
266 | | % % |
267 | | % % |
268 | | % % |
269 | | % U n r e g i s t e r P L A S M A I m a g e % |
270 | | % % |
271 | | % % |
272 | | % % |
273 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
274 | | % |
275 | | % UnregisterPLASMAImage() removes format registrations made by the |
276 | | % PLASMA module from the list of supported formats. |
277 | | % |
278 | | % The format of the UnregisterPLASMAImage method is: |
279 | | % |
280 | | % UnregisterPLASMAImage(void) |
281 | | % |
282 | | */ |
283 | | ModuleExport void UnregisterPLASMAImage(void) |
284 | 0 | { |
285 | 0 | (void) UnregisterMagickInfo("FRACTAL"); |
286 | 0 | (void) UnregisterMagickInfo("PLASMA"); |
287 | 0 | } |