1 module dmagick.c.layer;
2 
3 import dmagick.c.composite;
4 import dmagick.c.exception;
5 import dmagick.c.image;
6 
7 alias ptrdiff_t ssize_t;
8 
9 extern(C)
10 {
11 	/**
12 	 * The dispose method used for GIF animations.
13 	 * 
14 	 * See_Also: $(LINK2 http://www.imagemagick.org/Usage/anim_basics/#dispose,
15 	 *     Frame Disposal Methods) in the Examples of ImageMagick Usage.
16 	 */
17 	enum DisposeType
18 	{
19 		/** */
20 		UnrecognizedDispose,
21 
22 		/**
23 		 * No disposal specified.
24 		 */
25 		UndefinedDispose = 0,
26 		
27 		/**
28 		 * Do not dispose between frames.
29 		 */
30 		NoneDispose = 1,
31 		
32 		/**
33 		 * Overwrite the image area with the background color.
34 		 */
35 		BackgroundDispose = 2,
36 		
37 		/**
38 		 * Overwrite the image area with what was there prior
39 		 * to rendering the image.
40 		 */
41 		PreviousDispose = 3
42 	}
43 
44 	/**
45 	 * Determines image operation to apply to ordered sequence of images.
46 	 */
47 	enum ImageLayerMethod
48 	{
49 		/** */
50 		UndefinedLayer,
51 
52 		/**
53 		 * Apply the GIF disposal methods set in the current image sequence
54 		 * to form a fully defined animation sequence without, as it should
55 		 * be displayed. Effectively converting a GIF animation into
56 		 * a 'film strip' like animation.
57 		 */
58 		CoalesceLayer,
59 
60 		/**
61 		 * Crop the second and later frames to the smallest rectangle that
62 		 * contains all the differences between the two images. No GIF
63 		 * disposal methods are taken into account.
64 		 * 
65 		 * This does not preserve a animation's normal working, especially
66 		 * when a animation used GIF disposal methods
67 		 * such as 'Previous' or 'Background'.
68 		 */
69 		CompareAnyLayer,
70 
71 		/**
72 		 * As CompareAnyLayer but crop to the bounds of any opaque pixels
73 		 * which become transparent in the second frame. That is the
74 		 * smallest image needed to mask or erase pixels for the next frame.
75 		 */
76 		CompareClearLayer,
77 
78 		/**
79 		 * As CompareAnyLayer but crop to pixels that add extra color to
80 		 * the next image, as a result of overlaying color pixels. That is
81 		 * the smallest single overlaid image to add or change colors.
82 		 * 
83 		 * This can, be used with the -compose alpha composition method
84 		 * 'change-mask', to reduce the image to just the pixels that need
85 		 * to be overlaid.
86 		 */
87 		CompareOverlayLayer,
88 
89 		/**
90 		 * This is like CoalesceLayer but shows the look of the animation
91 		 * after the GIF disposal method has been applied, before the next
92 		 * sub-frame image is overlaid. That is the 'dispose' image that
93 		 * results from the application of the GIF disposal method. This
94 		 * allows you to check what is going wrong with a particular
95 		 * animation you may be developing.
96 		 */
97 		DisposeLayer,
98 
99 		/**
100 		 * Optimize a coalesced animation into GIF animation using a number
101 		 * of general techniques. This is currently a short cut to apply
102 		 * both the OptimizeImageLayer and OptimizeTransLayer methods
103 		 * but will expand to include other methods.
104 		 */
105 		OptimizeLayer,
106 
107 		/**
108 		 * Optimize a coalesced animation into GIF animation by reducing
109 		 * the number of pixels per frame as much as possible by attempting
110 		 * to pick the best GIF disposal method to use, while ensuring the
111 		 * result will continue to animate properly. 
112 		 * 
113 		 * There is no guarantee that the best optimization will be found.
114 		 * But then no reasonably fast GIF optimization algorithm can do
115 		 * this. However this does seem to do better than most other GIF
116 		 * frame optimizers seen.
117 		 */
118 		OptimizeImageLayer,
119 
120 		/**
121 		 * As OptimizeImageLayer but attempt to improve the overall
122 		 * optimization by adding extra frames to the animation, without
123 		 * changing the final look or timing of the animation. The frames
124 		 * are added to attempt to separate the clearing of pixels from the
125 		 * overlaying of new additional pixels from one animation frame to
126 		 * the next. If this does not improve the optimization (for the next
127 		 * frame only), it will fall back to the results of the previous
128 		 * normal OptimizeImageLayer technique.
129 		 * 
130 		 * There is the possibility that the change in the disposal style
131 		 * will result in a worsening in the optimization of later frames,
132 		 * though this is unlikely. In other words there no guarantee that
133 		 * it is better than the normal 'optimize-frame' technique.
134 		 */
135 		OptimizePlusLayer,
136 
137 		/**
138 		 * Given a GIF animation, replace any pixel in the sub-frame overlay
139 		 * images with transparency, if it does not change the resulting
140 		 * animation by more than the current fuzz factor.
141 		 * 
142 		 * This should allow a existing frame optimized GIF animation to
143 		 * compress into a smaller file size due to larger areas of one
144 		 * (transparent) color rather than a pattern of multiple colors
145 		 * repeating the current disposed image of the last frame.
146 		 */
147 		OptimizeTransLayer,
148 
149 		/**
150 		 * Remove (and merge time delays) of duplicate consecutive images,
151 		 * so as to simplify layer overlays of coalesced animations. Usually
152 		 * this is a result of using a constant time delay across the whole
153 		 * animation, or after a larger animation was split into smaller
154 		 * sub-animations. The duplicate frames could also have been used as
155 		 * part of some frame optimization methods.
156 		 */
157 		RemoveDupsLayer,
158 
159 		/**
160 		 * Remove any image with a zero time delay, unless ALL the images
161 		 * have a zero time delay (and is not a proper timed animation, a
162 		 * warning is then issued). In a GIF animation, such images are
163 		 * usually frames which provide partial intermediary updates between
164 		 * the frames that are actually displayed to users. These frames are
165 		 * usually added for improved frame optimization in GIF animations.
166 		 */
167 		RemoveZeroLayer,
168 
169 		/**
170 		 * Alpha Composition of two image lists, separated by a "null:"
171 		 * image, with the destination image list first, and the source
172 		 * images last. An image from each list are composited together
173 		 * until one list is finished. The separator image and source image
174 		 * lists are removed.
175 		 * 
176 		 * The geometry offset is adjusted according to gravity in
177 		 * accordance of the virtual canvas size of the first image in each
178 		 * list. Unlike a normal composite operation, the canvas offset is
179 		 * also added to the final composite positioning of each image.
180 		 * 
181 		 * If one of the image lists only contains one image, that image is
182 		 * applied to all the images in the other image list, regardless of
183 		 * which list it is. In this case it is the image meta-data of the
184 		 * list which preserved.
185 		 */
186 		CompositeLayer,
187 
188 		/**
189 		 * As FlattenLayer but merging all the given image layers into a
190 		 * new layer image just large enough to hold all the image without
191 		 * clipping or extra space. The new image's virtual offset will
192 		 * prevere the position of the new layer, even if this offset is
193 		 * negative. the virtual canvas size of the first image is preserved.
194 		 * 
195 		 * Caution is advised when handling image layers with negative
196 		 * offsets as few image file formats handle them correctly.
197 		 */
198 		MergeLayer,
199 
200 		/**
201 		 * Create a canvas the size of the first images virtual canvas using
202 		 * the current background color, and compose each image in turn onto
203 		 * that canvas. Images falling outside that canvas will be clipped.
204 		 * Final image will have a zero virtual canvas offset.
205 		 * 
206 		 * This is usually used as one of the final 'image layering'
207 		 * operations overlaying all the prepared image layers into a
208 		 * final image.
209 		 * 
210 		 * For a single image this method can also be used to fillout a
211 		 * virtual canvas with real pixels, or to underlay a opaque color
212 		 * to remove transparency from an image.
213 		 */
214 		FlattenLayer,
215 
216 		/**
217 		 * As FlattenLayer but expanding the initial canvas size of the
218 		 * first image so as to hold all the image layers. However as a
219 		 * virtual canvas is 'locked' to the origin, by definition, image
220 		 * layers with a negative offsets will still be clipped by the top
221 		 * and left edges.
222 		 * 
223 		 * This method is commonly used to layout individual image using
224 		 * various offset but without knowing the final canvas size. The
225 		 * resulting image will, like FlattenLayer not have any virtual
226 		 * offset, so can be saved to any image file format. This method
227 		 * corresponds to mosaic, above.
228 		 */
229 		MosaicLayer,
230 
231 		/**
232 		 * Find the minimal bounds of all the images in the current image
233 		 * sequence, then adjust the offsets so all images are contained
234 		 * on a minimal positive canvas. None of the image data is modified,
235 		 * only the virtual canvas size and offset. Then all the images will
236 		 * have the same canvas size, and all will have a positive offset,
237 		 * at least one image will touch every edge of that canvas with
238 		 * actual pixel data, though that data may be transparent.
239 		 */
240 		TrimBoundsLayer
241 	}
242 
243 	Image* CoalesceImages(const(Image)*, ExceptionInfo*);
244 	Image* DisposeImages(const(Image)*, ExceptionInfo*);
245 	Image* CompareImageLayers(const(Image)*, const ImageLayerMethod, ExceptionInfo*);
246 	Image* DeconstructImages(const(Image)*, ExceptionInfo*);
247 	Image* MergeImageLayers(Image*, const ImageLayerMethod, ExceptionInfo*);
248 	Image* OptimizeImageLayers(const(Image)*, ExceptionInfo*);
249 	Image* OptimizePlusImageLayers(const(Image)*, ExceptionInfo*);
250 
251 	void CompositeLayers(Image*, const CompositeOperator, Image*, const ssize_t, const ssize_t, ExceptionInfo*);
252 	void OptimizeImageTransparency(const(Image)*, ExceptionInfo*);
253 	void RemoveDuplicateLayers(Image**, ExceptionInfo*);
254 	void RemoveZeroDelayLayers(Image**, ExceptionInfo*);
255 }