blob: 9153dc54f72fc79f8f89166465b4f7ad819da8f4 [file] [log] [blame]
cristy8fdeeb32013-03-31 21:15:31 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% M M AAA SSSSS K K %
7% MM MM A A SS K K %
8% M M M AAAAA SSS KKK %
9% M M A A SS K K %
10% M M A A SSSSS K K %
11% %
12% %
13% Write Mask File. %
14% %
15% Software Design %
16% John Cristy %
17% July 1992 %
18% %
19% %
20% Copyright 1999-2013 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% 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 "MagickCore/studio.h"
43#include "MagickCore/attribute.h"
44#include "MagickCore/blob.h"
45#include "MagickCore/blob-private.h"
46#include "MagickCore/constitute.h"
47#include "MagickCore/enhance.h"
48#include "MagickCore/exception.h"
49#include "MagickCore/exception-private.h"
50#include "MagickCore/list.h"
51#include "MagickCore/magick.h"
52#include "MagickCore/memory_.h"
53#include "MagickCore/monitor.h"
54#include "MagickCore/monitor-private.h"
55#include "MagickCore/pixel-accessor.h"
56#include "MagickCore/quantum-private.h"
57#include "MagickCore/static.h"
58#include "MagickCore/string_.h"
59#include "MagickCore/module.h"
60
61/*
62 Forward declarations.
63*/
64static MagickBooleanType
65 WriteMASKImage(const ImageInfo *,Image *,ExceptionInfo *);
66
67/*
68%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
69% %
70% %
71% %
72% R e a d M A S K I m a g e %
73% %
74% %
75% %
76%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
77%
78% ReadMASKImage returns the image mask associated with the image.
79%
80% The format of the ReadMASKImage method is:
81%
82% Image *ReadMASKImage(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*/
92static Image *ReadMASKImage(const ImageInfo *image_info,
93 ExceptionInfo *exception)
94{
95 Image
96 *image;
97
98 ImageInfo
99 *read_info;
100
101 /*
102 Initialize Image structure.
103 */
104 assert(image_info != (const ImageInfo *) NULL);
105 assert(image_info->signature == MagickSignature);
106 if (image_info->debug != MagickFalse)
107 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
108 image_info->filename);
109 assert(exception != (ExceptionInfo *) NULL);
110 assert(exception->signature == MagickSignature);
111 read_info=CloneImageInfo(image_info);
112 SetImageInfoBlob(read_info,(void *) NULL,0);
113 *read_info->magick='\0';
114 image=ReadImage(read_info,exception);
115 read_info=DestroyImageInfo(read_info);
116 if (image != (Image *) NULL)
117 {
118 MagickBooleanType
119 status;
120
121 status=GrayscaleImage(image,image->intensity,exception);
122 if (status == MagickFalse)
123 image=DestroyImage(image);
124 }
125 return(GetFirstImageInList(image));
126}
127
128/*
129%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
130% %
131% %
132% %
133% R e g i s t e r M A S K I m a g e %
134% %
135% %
136% %
137%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
138%
139% RegisterMASKImage() adds attributes for the MASK image format to
140% the list of supported formats. The attributes include the image format
141% tag, a method to read and/or write the format, whether the format
142% supports the saving of more than one frame to the same file or blob,
143% whether the format supports native in-memory I/O, and a brief
144% description of the format.
145%
146% The format of the RegisterMASKImage method is:
147%
148% size_t RegisterMASKImage(void)
149%
150*/
151ModuleExport size_t RegisterMASKImage(void)
152{
153 MagickInfo
154 *entry;
155
156 entry=SetMagickInfo("MASK");
157 entry->decoder=(DecodeImageHandler *) ReadMASKImage;
158 entry->encoder=(EncodeImageHandler *) WriteMASKImage;
159 entry->description=ConstantString("Image Clip Mask");
160 entry->module=ConstantString("MASK");
161 (void) RegisterMagickInfo(entry);
162 return(MagickImageCoderSignature);
163}
164
165/*
166%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
167% %
168% %
169% %
170% U n r e g i s t e r M A S K I m a g e %
171% %
172% %
173% %
174%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
175%
176% UnregisterMASKImage() removes format registrations made by the
177% MASK module from the list of supported formats.
178%
179% The format of the UnregisterMASKImage method is:
180%
181% UnregisterMASKImage(void)
182%
183*/
184ModuleExport void UnregisterMASKImage(void)
185{
186 (void) UnregisterMagickInfo("MASK");
187}
188
189/*
190%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
191% %
192% %
193% %
194% W r i t e M A S K I m a g e %
195% %
196% %
197% %
198%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
199%
200% WriteMASKImage() writes an image mask to a file.
201%
202% The format of the WriteMASKImage method is:
203%
204% MagickBooleanType WriteMASKImage(const ImageInfo *image_info,
205% Image *image,ExceptionInfo *exception)
206%
207% A description of each parameter follows.
208%
209% o image_info: the image info.
210%
211% o image: The image.
212%
213% o exception: return any errors or warnings in this structure.
214%
215*/
216
217static Image *MaskImage(const Image *image,ExceptionInfo *exception)
218{
219 CacheView
220 *image_view,
221 *mask_view;
222
223 Image
224 *mask_image;
225
226 MagickBooleanType
227 status;
228
229 ssize_t
230 y;
231
232 mask_image=CloneImage(image,image->columns,image->rows,MagickTrue,
233 exception);
234 if (mask_image == (Image *) NULL)
235 return((Image *) NULL);
236 if (SetImageStorageClass(mask_image,DirectClass,exception) == MagickFalse)
237 {
238 mask_image=DestroyImage(mask_image);
239 return((Image *) NULL);
240 }
241 mask_image->alpha_trait=UndefinedPixelTrait;
242 (void) SetImageColorspace(mask_image,GRAYColorspace,exception);
243 /*
244 Mask image.
245 */
246 status=MagickTrue;
247 image_view=AcquireVirtualCacheView(image,exception);
248 mask_view=AcquireAuthenticCacheView(mask_image,exception);
249 for (y=0; y < (ssize_t) image->rows; y++)
250 {
251 register const Quantum
252 *restrict p;
253
254 register Quantum
255 *restrict q;
256
257 register ssize_t
258 x;
259
260 if (status == MagickFalse)
261 continue;
262 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
263 q=QueueCacheViewAuthenticPixels(mask_view,0,y,mask_image->columns,1,
264 exception);
265 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
266 {
267 status=MagickFalse;
268 continue;
269 }
270 for (x=0; x < (ssize_t) image->columns; x++)
271 {
272 SetPixelChannel(mask_image,GrayPixelChannel,0,q);
cristy883fde12013-04-08 00:50:13 +0000273 SetPixelChannel(mask_image,GrayPixelChannel,GetPixelReadMask(image,p),q);
cristy8fdeeb32013-03-31 21:15:31 +0000274 p+=GetPixelChannels(image);
275 q+=GetPixelChannels(mask_image);
276 }
277 if (SyncCacheViewAuthenticPixels(mask_view,exception) == MagickFalse)
278 status=MagickFalse;
279 }
280 mask_view=DestroyCacheView(mask_view);
281 image_view=DestroyCacheView(image_view);
282 if (status == MagickFalse)
283 mask_image=DestroyImage(mask_image);
284 return(mask_image);
285}
286
287static MagickBooleanType WriteMASKImage(const ImageInfo *image_info,
288 Image *image,ExceptionInfo *exception)
289{
290 Image
291 *mask_image;
292
293 ImageInfo
294 *write_info;
295
296 MagickBooleanType
297 status;
298
299 mask_image=MaskImage(image,exception);
300 if (mask_image == (Image *) NULL)
301 return(MagickFalse);
302 (void) CopyMagickString(mask_image->filename,image->filename,MaxTextExtent);
303 write_info=CloneImageInfo(image_info);
304 (void) SetImageInfo(write_info,1,exception);
305 if (LocaleCompare(write_info->magick,"MASK") == 0)
306 (void) FormatLocaleString(mask_image->filename,MaxTextExtent,"miff:%s",
307 write_info->filename);
308 status=WriteImage(write_info,mask_image,exception);
309 mask_image=DestroyImage(mask_image);
310 write_info=DestroyImageInfo(write_info);
311 return(status);
312}