1 /** \file
2  * \brief Image Manipulation
3  *
4  * See Copyright Notice in im_lib.d
5  */
6 
7 
8 module im.image;
9 
10 import im.file;
11 
12 extern (C) @safe nothrow:
13 
14 
15 /** \defgroup imgclass imImage
16  *
17  * \par
18  *  Base definitions and functions for image representation. \n
19  * Only the image processing operations depends on these definitions,
20  * Image Storage and Image Capture are completely independent.
21  * \par
22  * You can also initialize a structure with your own memory buffer, see \ref imImageInit.
23  * To release the structure without releasing the buffer,
24  * set "data[0]" to NULL before calling imImageDestroy.
25  * \par
26  * See \ref im_image.h
27  * \ingroup imagerep */
28 
29 
30 
31 /** \brief Image Representation Structure
32  *
33  * \par
34  * An image representation than supports all the color spaces,
35  * but planes are always unpacked and the orientation is always bottom up.
36  * \ingroup imgclass */
37 struct _imImage
38 {
39   /* main parameters */
40   int width;          /**< Number of columns. image:Width() -> width: number [in Lua 5]. */
41   int height;         /**< Number of lines. image:Height() -> height: number [in Lua 5]. */
42   int color_space;    /**< Color space descriptor. See also \ref imColorSpace. image:ColorSpace() -> color_space: number [in Lua 5]. */
43   int data_type;      /**< Data type descriptor. See also \ref imDataType. image:DataType() -> data_type: number [in Lua 5]. */
44   int has_alpha;      /**< Indicates that there is an extra channel with alpha. image:HasAlpha() -> has_alpha: boolean [in Lua 5]. \n
45                            It will not affect the secondary parameters, i.e. the number of planes will be in fact depth+1. \n
46                            It is always 0 unless imImageAddAlpha is called. Alpha is automatically added in image loading functions. */
47 
48   /* secondary parameters */
49   int depth;          /**< Number of planes                      (ColorSpaceDepth)   image:Depth() -> depth: number [in Lua 5].       */
50   int line_size;      /**< Number of bytes per line in one plane (width * DataTypeSize)    */
51   int plane_size;     /**< Number of bytes per plane.            (line_size * height)      */
52   int size;           /**< Number of bytes occupied by the image (plane_size * depth)      */
53   int count;          /**< Number of pixels per plane            (width * height)          */
54 
55   /* image data */
56   void** data;        /**< Image data organized as a 2D matrix with several planes.   \n
57                            But plane 0 is also a pointer to the full data.            \n
58                            The remaining planes are: "data[i] = data[0] + i*plane_size". \n
59                            In Lua, data indexing is possible using: "image[plane][line][column]". \n
60                            Also in Lua, is possible to set all pixels using a table calling "image:SetPixels(table)"
61                            and get all pixels using "table = image:GetPixels()" (Since 3.9). */
62 
63   /* image attributes */
64   long *palette;      /**< Color palette. image:GetPalette() -> palette: imPalette [in Lua 5]. \n
65                            Used only when depth=1. Otherwise is NULL. */
66   int palette_count;  /**< The palette is always 256 colors allocated, but can have less colors used. */
67 
68   void* attrib_table; /**< in fact is an imAttribTable, but we hide this here */
69 }
70 alias imImage = _imImage;
71 
72 
73 /** Creates a new image.
74  * See also \ref imDataType and \ref imColorSpace. Image data is cleared as \ref imImageClear. \n
75  * In Lua the IM image metatable name is "imImage".
76  * When converted to a string will return "imImage(%p) [width=%d,height=%d,color_space=%s,data_type=%s,depth=%d]" where %p is replaced by the userdata address,
77  * and other values are replaced by the respective attributes.
78  * If the image is already destroyed by im.ImageDestroy, then it will return also the suffix "-destroyed".
79  *
80  * \verbatim im.ImageCreate(width: number, height: number, color_space: number, data_type: number) -> image: imImage [in Lua 5] \endverbatim
81  * \ingroup imgclass */
82 imImage* imImageCreate(int width, int height, int color_space, int data_type);
83 
84 /** Initializes the image structure but does not allocates image data.
85  * See also \ref imDataType and \ref imColorSpace.
86  * The only addtional flag thar color_mode can has here is IM_ALPHA.
87  * To release the image structure without releasing the buffer,
88  * set "data[0]" to NULL before calling imImageDestroy.
89  * \ingroup imgclass */
90 imImage* imImageInit(int width, int height, int color_mode, int data_type, void* data_buffer, long* palette, int palette_count);
91 
92 /** Creates a new image based on an existing one. \n
93  * If the addicional parameters are -1, the given image parameters are used. \n
94  * The image atributes always are copied. HasAlpha is copied.
95  * See also \ref imDataType and \ref imColorSpace.
96  *
97  * \verbatim im.ImageCreateBased(image: imImage, [width: number], [height: number], [color_space: number], [data_type: number]) -> image: imImage [in Lua 5] \endverbatim
98  * The addicional parameters in Lua can be nil,
99  * and they can also be functions with the based image as a parameter to return the respective value.
100  * \ingroup imgclass */
101 imImage* imImageCreateBased(const(imImage) * image, int width, int height, int color_space, int data_type);
102 
103 /** Destroys the image and frees the memory used.
104  * image data is destroyed only if its data[0] is not NULL. \n
105  * In Lua if this function is not called, the image is destroyed by the garbage collector.
106  *
107  * \verbatim im.ImageDestroy(image: imImage) [in Lua 5] \endverbatim
108  * \verbatim image:Destroy() [in Lua 5] \endverbatim
109  * \ingroup imgclass */
110 void imImageDestroy(imImage* image);
111 
112 /** Adds an alpha channel plane and sets its value to 0 (transparent).
113  *
114  * \verbatim image:AddAlpha() [in Lua 5] \endverbatim
115  * \ingroup imgclass */
116 void imImageAddAlpha(imImage* image);
117 
118 /** Sets the alpha channel plane to a constant.
119  *
120  * \verbatim image:SetAlpha(alpha: number) [in Lua 5] \endverbatim
121  * \ingroup imgclass */
122 void imImageSetAlpha(imImage* image, float alpha);
123 
124 /** Removes the alpha channel plane if any.
125  *
126  * \verbatim image:RemoveAlpha() [in Lua 5] \endverbatim
127  * \ingroup imgclass */
128 void imImageRemoveAlpha(imImage* image);
129 
130 /** Changes the buffer size. Reallocate internal buffers if the new size is larger than the original.
131  *
132  * \verbatim image:Reshape(width: number, height: number) [in Lua 5] \endverbatim
133  * \ingroup imgclass */
134 void imImageReshape(imImage* image, int width, int height);
135 
136 /** Copy image data and attributes from one image to another. \n
137  * Images must have the same size and type.
138  *
139  * \verbatim image:Copy(dst_image: imImage) [in Lua 5] \endverbatim
140  * \ingroup imgclass */
141 void imImageCopy(const(imImage) * src_image, imImage* dst_image);
142 
143 /** Copy image data only fom one image to another. \n
144  * Images must have the same size and type.
145  *
146  * \verbatim image:CopyData(dst_image: imImage) [in Lua 5] \endverbatim
147  * \ingroup imgclass */
148 void imImageCopyData(const(imImage) * src_image, imImage* dst_image);
149 
150 /** Copies the image attributes from src to dst.
151  * Includes the pallete if defined in both images.
152  *
153  * \verbatim image:CopyAttributes(dst_image: imImage) [in Lua 5] \endverbatim
154  * \ingroup imgclass */
155 void imImageCopyAttributes(const(imImage) * src_image, imImage* dst_image);
156 
157 /** Merges the image attributes from src to dst. \n
158  * Attributes that exist in dst are not replaced.
159  * Doens NOT include the pallete.
160  *
161  * \verbatim image:MergeAttributes(dst_image: imImage) [in Lua 5] \endverbatim
162  * \ingroup imgclass */
163 void imImageMergeAttributes(const(imImage) * src_image, imImage* dst_image);
164 
165 /** Copy one image plane fom one image to another. \n
166  * Images must have the same size and type.
167  *
168  * \verbatim image:CopyPlane(src_plane: number, dst_image: imImage, dst_plane: number) [in Lua 5] \endverbatim
169  * \ingroup imgclass */
170 void imImageCopyPlane(const(imImage) * src_image, int src_plane, imImage* dst_image, int dst_plane);
171 
172 /** Creates a copy of the image.
173  *
174  * \verbatim image:Duplicate() -> new_image: imImage [in Lua 5] \endverbatim
175  * \ingroup imgclass */
176 imImage* imImageDuplicate(const(imImage) * image);
177 
178 /** Creates a clone of the image. i.e. same attributes but ignore contents.
179  *
180  * \verbatim image:Clone() -> new_image: imImage [in Lua 5] \endverbatim
181  * \ingroup imgclass */
182 imImage* imImageClone(const(imImage) * image);
183 
184 /** Changes an extended attribute. \n
185  * The data will be internally duplicated. \n
186  * If data is NULL and count==0 the attribute is removed. \n
187  * If count is -1 and data_type is IM_BYTE then data is zero terminated.
188  * See also \ref imDataType.
189  *
190  * \verbatim image:SetAttribute(attrib: string, data_type: number, data: table of numbers or string) [in Lua 5] \endverbatim
191  * If data_type is IM_BYTE, a string can be used as data.
192  * \ingroup imgclass */
193 void imImageSetAttribute(const(imImage) * image, const(char) * attrib, int data_type, int count, const(void) * data);
194 
195 /** Changes an extended attribute as an integer.
196 *
197 * \verbatim image:SetAttribInteger(attrib: string, data_type: number, value: number) [in Lua 5] \endverbatim
198 * \ingroup imgclass */
199 void imImageSetAttribInteger(const(imImage) * image, const(char) * attrib, int data_type, int value);
200 
201 /** Changes an extended attribute as a real.
202 *
203 * \verbatim image:SetAttribReal(attrib: string, data_type: number, value: number) [in Lua 5] \endverbatim
204 * \ingroup imgclass */
205 void imImageSetAttribReal(const(imImage) * image, const(char) * attrib, int data_type, double value);
206 
207 /** Changes an extended attribute as a string.
208 *
209 * \verbatim image:SetAttribString(attrib: string, value: string) [in Lua 5] \endverbatim
210 * \ingroup imgclass */
211 void imImageSetAttribString(const(imImage) * image, const(char) * attrib, const(char) * value);
212 
213 /** Returns an extended attribute. \n
214  * Returns NULL if not found.
215  * See also \ref imDataType.
216  *
217  * \verbatim image:GetAttribute(attrib: string, [as_string: boolean]) -> data: table of numbers or string, data_type: number [in Lua 5] \endverbatim
218  * If data_type is IM_BYTE, as_string can be used to return a string instead of a table.
219  * \ingroup imgclass */
220 const(void) * imImageGetAttribute(const(imImage) * image, const(char) * attrib, int *data_type, int *count);
221 
222 /** Returns an extended attribute as an integer.
223 *
224 * \verbatim image:GetAttribInteger(attrib: string, [index: number]) -> value: number [in Lua 5] \endverbatim
225 * \ingroup imgclass */
226 int imImageGetAttribInteger(const(imImage) * image, const(char) * attrib, int index);
227 
228 /** Returns an extended attribute as a real.
229 *
230 * \verbatim image:GetAttribReal(attrib: string, [index: number]) -> value: number [in Lua 5] \endverbatim
231 * \ingroup imgclass */
232 double imImageGetAttribReal(const(imImage) * image, const(char) * attrib, int index);
233 
234 /** Returns an extended attribute as a string.
235 *
236 * \verbatim image:GetAttribString(attrib: string) -> value: string [in Lua 5] \endverbatim
237 * \ingroup imgclass */
238 const(char) * imImageGetAttribString(const(imImage) * image, const(char) * attrib);
239 
240 /** Returns a list of the attribute names. \n
241  * "attrib" must contain room enough for "attrib_count" names. Use "attrib=NULL" to return only the count.
242  *
243  * \verbatim image:GetAttributeList() -> data: table of strings [in Lua 5] \endverbatim
244  * \ingroup imgclass */
245 void imImageGetAttributeList(const(imImage) * image, char** attrib, int *attrib_count);
246 
247 /** Sets all image data to zero. But if color space is YCBCR, LAB or LUV, and data type is BYTE or USHORT, then
248  * data is initialized with 128 or 32768 accordingly. Alpha is initialized as transparent (0).
249  *
250  * \verbatim image:Clear() [in Lua 5] \endverbatim
251  * \ingroup imgclass */
252 void imImageClear(imImage* image);
253 
254 /** Indicates that the image can be viewed in common graphic devices.
255  * Data type must be IM_BYTE. Color mode can be IM_RGB, IM_MAP, IM_GRAY or IM_BINARY.
256  *
257  * \verbatim image:IsBitmap() -> is_bitmap: boolean [in Lua 5] \endverbatim
258  * \ingroup imgclass */
259 int imImageIsBitmap(const(imImage) * image);
260 
261 /** Changes the image palette.
262  * This will destroy the existing palette and replace it with the given palette pointer.
263  * Only the pointer is stored, so the palette should be a new palette and it can not be a static array.
264  *
265  * \verbatim image:SetPalette(palette: imPalette) [in Lua 5] \endverbatim
266  * \ingroup imgclass */
267 void imImageSetPalette(imImage* image, long* palette, int palette_count);
268 
269 /** Returns 1 if the images match width and height. Returns 0 otherwise.
270  *
271  * \verbatim image:MatchSize(image2: imImage) -> match: boolean [in Lua 5] \endverbatim
272  * \ingroup imgclass */
273 int imImageMatchSize(const(imImage) * image1, const(imImage) * image2);
274 
275 /** Returns 1 if the images match color mode and data type. Returns 0 otherwise.
276  *
277  * \verbatim image:MatchColor(image2: imImage) -> match: boolean [in Lua 5] \endverbatim
278  * \ingroup imgclass */
279 int imImageMatchColor(const(imImage) * image1, const(imImage) * image2);
280 
281 /** Returns 1 if the images match width, height and data type. Returns 0 otherwise.
282  *
283  * \verbatim image:MatchDataType(image2: imImage) -> match: boolean [in Lua 5] \endverbatim
284  * \ingroup imgclass */
285 int imImageMatchDataType(const(imImage) * image1, const(imImage) * image2);
286 
287 /** Returns 1 if the images match width, height and color space. Returns 0 otherwise.
288  *
289  * \verbatim image:MatchColorSpace(image2: imImage) -> match: boolean [in Lua 5] \endverbatim
290  * \ingroup imgclass */
291 int imImageMatchColorSpace(const(imImage) * image1, const(imImage) * image2);
292 
293 /** Returns 1 if the images match in width, height, data type and color space. Returns 0 otherwise.
294  *
295  * \verbatim image:Match(image2: imImage) -> match: boolean [in Lua 5] \endverbatim
296  * \ingroup imgclass */
297 int imImageMatch(const(imImage) * image1, const(imImage) * image2);
298 
299 /** Changes the image color space to map
300  * by just changing color_space. \n
301  * Image must be BINARY or GRAY/BYTE.
302  *
303  * \verbatim image:SetMap() [in Lua 5] \endverbatim
304  * \ingroup imgclass */
305 void imImageSetMap(imImage* image);
306 
307 /** Changes the image color space to binary
308  * by just changing color_space and the palette.
309  * Image must be MAP or GRAY/BYTE.
310  *
311  * \verbatim image:SetBinary() [in Lua 5] \endverbatim
312  * \ingroup imgclass */
313 void imImageSetBinary(imImage* image);
314 
315 /** Changes the image color space to gray
316  * by just changing color_space and the palette.
317  * Image must be BINARY or MAP. Palette is changed only if image was BINARY.
318  *
319  * \verbatim image:SetGray() [in Lua 5] \endverbatim
320  * \ingroup imgclass */
321 void imImageSetGray(imImage* image);
322 
323 /** Changes a gray BYTE data (0,255) into a binary data (0,1), done in-place.
324  * Color space is not changed. Data type must be IM_BYTE.
325  *
326  * \verbatim image:MakeBinary() [in Lua 5] \endverbatim
327  * \ingroup imgclass */
328 void imImageMakeBinary(imImage *image);
329 
330 /** Changes a binary data (0,1) into a gray BYTE data (0,255), done in-place.
331  * Color space is not changed. Data type must be IM_BYTE.
332  *
333  * \verbatim image:MakeGray() [in Lua 5] \endverbatim
334  * \ingroup imgclass */
335 void imImageMakeGray(imImage *image);
336 
337 
338 
339 /** \defgroup imgfile imImage Storage
340  *
341  * \par
342  *  Functions to simplify the process of reading and writting imImage structures.
343  *  Will also load and save the alpha planes when possible.
344  * \par
345  * See \ref im_image.h
346  * \ingroup file */
347 
348 
349 /** Loads an image from an already open file. Returns NULL if failed. \n
350  * This will call \ref imFileReadImageInfo and \ref imFileReadImageData. \n
351  * index specifies the image number between 0 and image_count-1. \n
352  * The returned image will be of the same color_space and data_type of the image in the file. \n
353  * Attributes from the file will be stored at the image.
354  * See also \ref imErrorCodes.
355  *
356  * \verbatim ifile:LoadImage([index: number]) -> image: imImage, error: number [in Lua 5] \endverbatim
357  * Default index is 0.
358  * \ingroup imgfile */
359 imImage* imFileLoadImage(imFile* ifile, int index, int *error);
360 
361 /** Loads an image from an already open file. Returns NULL if failed. \n
362  * This function assumes that the image in the file has the same parameters as the given image. \n
363  * This will call \ref imFileReadImageInfo and \ref imFileReadImageData. \n
364  * index specifies the image number between 0 and image_count-1. \n
365  * The returned image will be of the same color_space and data_type of the image in the file. \n
366  * Attributes from the file will be stored at the image.
367  * See also \ref imErrorCodes.
368  *
369  * \verbatim ifile:LoadImageFrame(index: number, image: imImage) -> error: number [in Lua 5] \endverbatim
370  * Default index is 0.
371  * \ingroup imgfile */
372 void imFileLoadImageFrame(imFile* ifile, int index, imImage* image, int *error);
373 
374 /** Loads an image from an already open file, but forces the image to be a bitmap.\n
375  * The returned imagem will be always a Bitmap image, with color_space RGB, MAP, GRAY or BINARY, and data_type IM_BYTE. \n
376  * index specifies the image number between 0 and image_count-1. \n
377  * Returns NULL if failed.
378  * Attributes from the file will be stored at the image.
379  * See also \ref imErrorCodes.
380  *
381  * \verbatim ifile:LoadBitmap([index: number]) -> image: imImage, error: number [in Lua 5] \endverbatim
382  * Default index is 0.
383  * \ingroup imgfile */
384 imImage* imFileLoadBitmap(imFile* ifile, int index, int *error);
385 
386 /** Loads an image region from an already open file. Returns NULL if failed. \n
387  * This will call \ref imFileReadImageInfo and \ref imFileReadImageData. \n
388  * index specifies the image number between 0 and image_count-1. \n
389  * The returned image will be of the same color_space and data_type of the image in the file,
390  * or will be a Bitmap image. \n
391  * Attributes from the file will be stored at the image.
392  * See also \ref imErrorCodes. \n
393  * For now, it works only for the ECW file format.
394  *
395  * \verbatim ifile:LoadRegion(index, bitmap, xmin, xmax, ymin, ymax, width, height: number) -> image: imImage, error: number [in Lua 5] \endverbatim
396  * Default index is 0.
397  * \ingroup imgfile */
398 imImage* imFileLoadImageRegion(imFile* ifile, int index, int bitmap, int *error,
399                                int xmin, int xmax, int ymin, int ymax, int width, int height);
400 
401 /** Loads an image from an already open file, but forces the image to be a bitmap.\n
402  * This function assumes that the image in the file has the same parameters as the given image. \n
403  * The imagem must be a Bitmap image, with color_space RGB, MAP, GRAY or BINARY, and data_type IM_BYTE. \n
404  * index specifies the image number between 0 and image_count-1. \n
405  * Returns NULL if failed.
406  * Attributes from the file will be stored at the image.
407  * See also \ref imErrorCodes.
408  *
409  * \verbatim ifile:LoadBitmapFrame(index: number, image: imImage) -> error: number [in Lua 5] \endverbatim
410  * Default index is 0.
411  * \ingroup imgfile */
412 void imFileLoadBitmapFrame(imFile* ifile, int index, imImage* image, int *error);
413 
414 /** Saves the image to an already open file. \n
415  * This will call \ref imFileWriteImageInfo and \ref imFileWriteImageData. \n
416  * Attributes from the image will be stored at the file.
417  * Returns error code.
418  *
419  * \verbatim ifile:SaveImage(image: imImage) -> error: number [in Lua 5] \endverbatim
420  * \ingroup imgfile */
421 int imFileSaveImage(imFile* ifile, const(imImage) * image);
422 
423 /** Loads an image from file. Open, loads and closes the file. \n
424  * index specifies the image number between 0 and image_count-1. \n
425  * Returns NULL if failed.
426  * Attributes from the file will be stored at the image.
427  * See also \ref imErrorCodes.
428  *
429  * \verbatim im.FileImageLoad(file_name: string, [index: number]) -> image: imImage, error: number [in Lua 5] \endverbatim
430  * Default index is 0.
431  * \ingroup imgfile */
432 imImage* imFileImageLoad(const(char) * file_name, int index, int *error);
433 
434 /** Loads an image from file, but forces the image to be a bitmap. Open, loads and closes the file. \n
435  * index specifies the image number between 0 and image_count-1. \n
436  * Returns NULL if failed.
437  * Attributes from the file will be stored at the image.
438  * See also \ref imErrorCodes.
439  *
440  * \verbatim im.FileImageLoadBitmap(file_name: string, [index: number]) -> image: imImage, error: number [in Lua 5] \endverbatim
441  * Default index is 0.
442  * \ingroup imgfile */
443 imImage* imFileImageLoadBitmap(const(char) * file_name, int index, int *error);
444 
445 /** Loads an image region from file. Open, loads and closes the file. \n
446  * index specifies the image number between 0 and image_count-1. \n
447  * Returns NULL if failed.
448  * Attributes from the file will be stored at the image.
449  * See also \ref imErrorCodes. \n
450  * For now, it works only for the ECW file format.
451  *
452  * \verbatim im.FileImageLoadRegion(file_name: string, index, bitmap, xmin, xmax, ymin, ymax, width, height: number, ) -> image: imImage, error: number [in Lua 5] \endverbatim
453  * Default index is 0.
454  * \ingroup imgfile */
455 imImage* imFileImageLoadRegion(const(char) * file_name, int index, int bitmap, int *error,
456                                int xmin, int xmax, int ymin, int ymax, int width, int height);
457 
458 /** Saves the image to file. Open, saves and closes the file. \n
459  * Returns error code. \n
460  * Attributes from the image will be stored at the file.
461  *
462  * \verbatim im.FileImageSave(file_name: string, format: string, image: imImage) -> error: number [in Lua 5] \endverbatim
463  * \verbatim image:Save(file_name: string, format: string) -> error: number [in Lua 5] \endverbatim
464  * \ingroup imgfile */
465 int imFileImageSave(const(char) * file_name, const(char) * format, const(imImage) * image);
466 
467 
468 
469 /** Utility macro to draw the image in a CD library canvas.
470  * Works only for data_type IM_BYTE, and color spaces: IM_RGB, IM_MAP, IMGRAY and IM_BINARY.
471  * \ingroup imgclass */
472 /+ TODO
473 #define imcdCanvasPutImage(_canvas, _image, _x, _y, _w, _h, _xmin, _xmax, _ymin, _ymax)     \
474   {                                                                         \
475     if (_image->color_space == IM_RGB)                                      \
476     {                                                                       \
477       if (_image->has_alpha)                                                \
478         cdCanvasPutImageRectRGBA(_canvas, _image->width, _image->height,    \
479                           (unsigned char*)_image->data[0],                  \
480                           (unsigned char*)_image->data[1],                  \
481                           (unsigned char*)_image->data[2],                  \
482                           (unsigned char*)_image->data[3],                  \
483                           _x, _y, _w, _h, _xmin, _xmax, _ymin, _ymax);      \
484       else                                                                  \
485         cdCanvasPutImageRectRGB(_canvas, _image->width, _image->height,     \
486                           (unsigned char*)_image->data[0],                  \
487                           (unsigned char*)_image->data[1],                  \
488                           (unsigned char*)_image->data[2],                  \
489                           _x, _y, _w, _h, _xmin, _xmax, _ymin, _ymax);      \
490     }                                                                       \
491     else                                                                    \
492       cdCanvasPutImageRectMap(_canvas, _image->width, _image->height,       \
493                         (unsigned char*)_image->data[0], _image->palette,   \
494                         _x, _y, _w, _h, _xmin, _xmax, _ymin, _ymax);        \
495   }
496 
497 +/