blob: 4fd75d6c31c5ca378ec1d21dd1fff3623ca7d02e [file] [log] [blame]
cristyd04e7bf2012-03-03 19:19:12 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% CCCC H H AAA N N N N EEEEE L %
7% C H H A A NN N NN N E L %
8% C HHHHH AAAAA N N N N N N RRR L %
9% C H H A A N NN N NN E L %
10% CCCC H H A A N N N N EEEEE LLLLL %
11% %
12% %
13% MagickCore Image Channel Methods %
14% %
15% Software Design %
16% John Cristy %
17% December 2003 %
18% %
19% %
20% Copyright 1999-2012 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/*
41 Include declarations.
42*/
43#include "MagickCore/studio.h"
cristya15140f2012-03-04 01:21:15 +000044#include "MagickCore/image.h"
45#include "MagickCore/list.h"
46#include "MagickCore/log.h"
47#include "MagickCore/option.h"
48#include "MagickCore/token.h"
cristyd04e7bf2012-03-03 19:19:12 +000049#include "MagickCore/utility.h"
50#include "MagickCore/version.h"
51
52/*
53%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
54% %
55% %
56% %
57% C h a n n e l O p e r a t i o n I m a g e %
58% %
59% %
60% %
61%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
62%
63% ChannelOperationImage() applies a channel expression to the specified image.
64%
65% The format of the ChannelOperationImage method is:
66%
cristya15140f2012-03-04 01:21:15 +000067% Image *ChannelOperationImage(const Image *images,
cristyd04e7bf2012-03-03 19:19:12 +000068% const char *expression,ExceptionInfo *exception)
69%
70% A description of each parameter follows:
71%
cristya15140f2012-03-04 01:21:15 +000072% o images: the images.
cristyd04e7bf2012-03-03 19:19:12 +000073%
74% o expression: A channel expression.
75%
76% o exception: return any errors or warnings in this structure.
77%
78*/
cristya15140f2012-03-04 01:21:15 +000079
80typedef enum
81{
82 ExtractChannelOp,
83 ExchangeChannelOp,
84 TransferChannelOp
85} ChannelOperation;
86
87static MagickBooleanType ChannelImage(Image *channel_image,const Image *image,
88 const ChannelOperation channel_op,const PixelChannel p_channel,
89 const PixelChannel q_channel,ExceptionInfo *exception)
90{
91 return(MagickTrue);
92}
93
94MagickExport Image *ChannelOperationImage(const Image *images,
cristyd04e7bf2012-03-03 19:19:12 +000095 const char *expression,ExceptionInfo *exception)
96{
cristya15140f2012-03-04 01:21:15 +000097 char
98 token[MaxTextExtent];
99
100 ChannelOperation
101 channel_op;
102
103 const char
104 *p;
105
106 Image
107 *channel_images;
108
109 PixelChannel
110 p_channel,
111 q_channel;
112
113 assert(images != (Image *) NULL);
114 assert(images->signature == MagickSignature);
115 if (images->debug != MagickFalse)
116 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
117 channel_images=CloneImage(images,images->columns,images->columns,MagickTrue,
118 exception);
119 p=(char *) expression;
120 GetMagickToken(p,&p,token);
121 for (q_channel=RedPixelChannel; *p != '\0'; )
122 {
123 MagickBooleanType
124 status;
125
126 ssize_t
127 i;
128
129 /*
130 Interpret channel expression.
131 */
132 if (*token == ',')
133 {
134 q_channel=(PixelChannel) ((ssize_t) q_channel+1);
135 GetMagickToken(p,&p,token);
136 }
137 if (*token == '|')
138 {
139 if (GetNextImageInList(images) != (Image *) NULL)
140 images=GetNextImageInList(images);
141 else
142 images=GetFirstImageInList(images);
143 GetMagickToken(p,&p,token);
144 }
145 if (*token == ';')
146 {
147 AppendImageToList(&channel_images,CloneImage(images,
148 channel_images->columns,channel_images->rows,MagickTrue,exception));
149 channel_images=GetLastImageInList(channel_images);
150 GetMagickToken(p,&p,token);
151 }
152 i=ParsePixelChannelOption(token);
153 if (i < 0)
154 {
155 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
156 "UnableToParseExpression","`%s'",p);
157 channel_images=DestroyImageList(channel_images);
158 break;
159 }
160 p_channel=(PixelChannel) i;
161 channel_op=ExtractChannelOp;
162 GetMagickToken(p,&p,token);
163 if (*token == '<')
164 {
165 channel_op=ExchangeChannelOp;
166 GetMagickToken(p,&p,token);
167 }
168 if (*token == '=')
169 GetMagickToken(p,&p,token);
170 if (*token == '>')
171 {
172 if (channel_op != ExchangeChannelOp)
173 channel_op=TransferChannelOp;
174 GetMagickToken(p,&p,token);
175 }
176 if (channel_op != ExtractChannelOp)
177 {
178 i=ParsePixelChannelOption(token);
179 if (i < 0)
180 {
181 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
182 "UnableToParseExpression","`%s'",p);
183 channel_images=DestroyImageList(channel_images);
184 break;
185 }
186 q_channel=(PixelChannel) i;
187 }
188 status=ChannelImage(channel_images,images,channel_op,p_channel,q_channel,
189 exception);
190 if (status == MagickFalse)
191 {
192 channel_images=DestroyImageList(channel_images);
193 break;
194 }
195 }
196 return(channel_images);
cristyd04e7bf2012-03-03 19:19:12 +0000197}