blob: 9ba71e918fdcc3a4c21f50699568f028bf4073e6 [file] [log] [blame]
Cristye6c08712020-10-09 20:28:51 -04001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% K K EEEEE RRRR N N EEEEE L %
7% K K E R R NN N E L %
8% KKK EEE RRRR N N N EEE L %
9% K K E R R N NN E L %
10% K K EEEEE R R N N EEEEE LLLLL %
11% %
12% %
13% Write the Morphology Kernel Format %
14% %
15% Software Design %
16% Cristy %
17% October 2020 %
18% %
19% %
Cristyd8420112021-01-01 14:52:00 -050020% Copyright 1999-2021 ImageMagick Studio LLC, a non-profit organization %
Cristye6c08712020-10-09 20:28:51 -040021% 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/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%
Cristyfc680352020-10-09 20:52:40 -040036% Adapted from http://im.snibgo.com/customim.htm#img2knl.c.
Cristye6c08712020-10-09 20:28:51 -040037%
38*/
39
40/*
41 Include declarations.
42*/
43#include "MagickCore/studio.h"
44#include "MagickCore/blob.h"
45#include "MagickCore/blob-private.h"
46#include "MagickCore/cache.h"
47#include "MagickCore/colorspace.h"
48#include "MagickCore/colorspace-private.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/monitor.h"
57#include "MagickCore/monitor-private.h"
58#include "MagickCore/pixel-accessor.h"
59#include "MagickCore/quantum-private.h"
60#include "MagickCore/static.h"
61#include "MagickCore/string_.h"
62#include "MagickCore/module.h"
63
64/*
65 Forward declarations.
66*/
67static MagickBooleanType
68 WriteKERNELImage(const ImageInfo *,Image *,ExceptionInfo *);
69
70/*
71%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
72% %
73% %
74% %
75% R e g i s t e r K E R N E L I m a g e %
76% %
77% %
78% %
79%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
80%
81% RegisterKERNELImage() adds attributes for the KERNEL image format to the
82% list of supported formats. The attributes include the image format tag, a
83% method to read and/or write the format, whether the format supports the
84% saving of more than one frame to the same file or blob, whether the format
85% supports native in-memory I/O, and a brief description of the format.
86%
87% The format of the RegisterKERNELImage method is:
88%
89% size_t RegisterKERNELImage(void)
90%
91*/
92ModuleExport size_t RegisterKERNELImage(void)
93{
94 MagickInfo
95 *entry;
96
97 entry=AcquireMagickInfo("KERNEL","KERNEL","Morphology Kernel");
98 entry->encoder=(EncodeImageHandler *) WriteKERNELImage;
99 entry->flags^=CoderAdjoinFlag;
100 (void) RegisterMagickInfo(entry);
101 return(MagickImageCoderSignature);
102}
103
104/*
105%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
106% %
107% %
108% %
109% U n r e g i s t e r K E R N E L I m a g e %
110% %
111% %
112% %
113%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
114%
115% UnregisterKERNELImage() removes format registrations made by the
116% KERNEL module from the list of supported formats.
117%
118% The format of the UnregisterKERNELImage method is:
119%
120% UnregisterKERNELImage(void)
121%
122*/
123ModuleExport void UnregisterKERNELImage(void)
124{
125 (void) UnregisterMagickInfo("KERNEL");
126}
127
128/*
129%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
130% %
131% %
132% %
133% W r i t e K E R N E L I m a g e %
134% %
135% %
136% %
137%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
138%
139% WriteKERNELImage() writes an image to a file in KERNEL image format.
140%
141% The format of the WriteKERNELImage method is:
142%
143% MagickBooleanType WriteKERNELImage(const ImageInfo *image_info,
144% Image *image,ExceptionInfo *exception)
145%
146% A description of each parameter follows.
147%
148% o image_info: the image info.
149%
150% o image: The image.
151%
152% o exception: return any errors or warnings in this structure.
153%
154*/
155static MagickBooleanType WriteKERNELImage(const ImageInfo *image_info,
156 Image *image,ExceptionInfo *exception)
157{
158 char
159 buffer[MagickPathExtent];
160
161 MagickBooleanType
162 status;
163
164 ssize_t
165 y;
Cristyfc680352020-10-09 20:52:40 -0400166
Cristye6c08712020-10-09 20:28:51 -0400167 /*
168 Open output image file.
169 */
170 assert(image_info != (const ImageInfo *) NULL);
171 assert(image_info->signature == MagickCoreSignature);
172 assert(image != (Image *) NULL);
173 assert(image->signature == MagickCoreSignature);
174 if (image->debug != MagickFalse)
175 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
176 assert(exception != (ExceptionInfo *) NULL);
177 assert(exception->signature == MagickCoreSignature);
178 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
179 if (status == MagickFalse)
180 return(status);
181 /*
182 Write KERNEL header.
183 */
184 (void) TransformImageColorspace(image,sRGBColorspace,exception);
185 (void) FormatLocaleString(buffer,MagickPathExtent,"%gx%g:",(double)
186 image->columns,(double) image->rows);
187 (void) WriteBlobString(image,buffer);
188 /*
189 Convert MIFF to KERNEL raster pixels.
190 */
191 for (y=0; y < (ssize_t) image->rows; y++)
192 {
Cristyf2dc1dd2020-12-28 13:59:26 -0500193 const Quantum
Cristye6c08712020-10-09 20:28:51 -0400194 *magick_restrict p;
195
Cristyf2dc1dd2020-12-28 13:59:26 -0500196 ssize_t
Cristye6c08712020-10-09 20:28:51 -0400197 x;
198
199 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
200 if (p == (const Quantum *) NULL)
201 break;
202 for (x=0; x < (ssize_t) image->columns; x++)
203 {
204 if ((x != 0) || (y != 0))
205 (void) WriteBlobString(image,",");
206 if ((image->alpha_trait == BlendPixelTrait) &&
207 (GetPixelAlpha(image,p) < OpaqueAlpha/2))
208 (void) WriteBlobString(image,"-");
209 else
210 {
211 (void) FormatLocaleString(buffer,MagickPathExtent,"%.*g",
212 GetMagickPrecision(),QuantumScale*GetPixelIntensity(image,p));
213 (void) WriteBlobString(image,buffer);
214 }
215 p+=GetPixelChannels(image);
216 }
Cristye6c08712020-10-09 20:28:51 -0400217 if (image->previous == (Image *) NULL)
218 {
219 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
220 image->rows);
221 if (status == MagickFalse)
222 break;
223 }
224 }
Cristyfc680352020-10-09 20:52:40 -0400225 (void) WriteBlobString(image,"\n");
Cristye6c08712020-10-09 20:28:51 -0400226 (void) CloseBlob(image);
227 return(MagickTrue);
228}