summaryrefslogtreecommitdiff
path: root/include/im_image.h
blob: 28c5369d40d8055078487b770aed18ddee082829 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
/** \file
 * \brief Image Manipulation
 *
 * See Copyright Notice in im_lib.h
 */

#ifndef __IM_IMAGE_H
#define __IM_IMAGE_H

#if	defined(__cplusplus)
extern "C" {
#endif


/** \defgroup imgclass imImage 
 *
 * \par
 *  Base definitions and functions for image representation. \n
 * Only the image processing operations depends on these definitions, 
 * Image Storage and Image Capture are completely independent.
 * \par
 * You can also initialize a structure with your own memory buffer, see \ref imImageInit.
 * To release the structure without releasing the buffer, 
 * set "data[0]" to NULL before calling imImageDestroy.
 * \par
 * See \ref im_image.h
 * \ingroup imagerep */



/** \brief imImage Structure Definition.  
 *
 * \par
 * An image representation than supports all the color spaces, 
 * but planes are always unpacked and the orientation is always bottom up.
 * \ingroup imgclass */
typedef struct _imImage
{
  /* main parameters */
  int width;          /**< Number of columns. image:Width() -> width: number [in Lua 5]. */
  int height;         /**< Number of lines. image:Height() -> height: number [in Lua 5]. */
  int color_space;    /**< Color space descriptor. See also \ref imColorSpace. image:ColorSpace() -> color_space: number [in Lua 5]. */
  int data_type;      /**< Data type descriptor. See also \ref imDataType. image:DataType() -> data_type: number [in Lua 5]. */
  int has_alpha;      /**< Indicates that there is an extra channel with alpha. image:HasAlpha() -> has_alpha: number [in Lua 5]. \n
                           It will not affect the secondary parameters, i.e. the number of planes will be in fact depth+1. \n
                           It is always 0 unless imImageAddAlpha is called, this is done in image load functions. */

  /* secondary parameters */
  int depth;          /**< Number of planes                      (ColorSpaceDepth)         */
  int line_size;      /**< Number of bytes per line in one plane (width * DataTypeSize)    */
  int plane_size;     /**< Number of bytes per plane.            (line_size * height)      */
  int size;           /**< Number of bytes occupied by the image (plane_size * depth)      */
  int count;          /**< Number of pixels                      (width * height)          */

  /* image data */
  void** data;        /**< Image data organized as a 2D matrix with several planes.   \n
                           But plane 0 is also a pointer to the full data.            \n
                           The remaining planes are: data[i] = data[0] + i*plane_size \n
                           In Lua, data indexing is possible using: image[plane][row][column] */

  /* image attributes */
  long *palette;      /**< Color palette. image:GetPalette() -> palette: imPalette [in Lua 5]. \n
                           Used when depth=1. Otherwise is NULL. */
  int palette_count;  /**< The palette is always 256 colors allocated, but can have less colors used. */

  void* attrib_table; /**< in fact is an imAttribTable, but we hide this here */
} imImage;


/** Creates a new image.
 * See also \ref imDataType and \ref imColorSpace. Image data is cleared as \ref imImageClear. \n
 * In Lua the IM image metatable name is "imImage".
 * 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,
 * and other values are replaced by the respective attributes.
 * If the image is already destroyed by im.ImageDestroy, then it will return also the suffix "-destroyed".
 *
 * \verbatim im.ImageCreate(width: number, height: number, color_space: number, data_type: number) -> image: imImage [in Lua 5] \endverbatim
 * \ingroup imgclass */
imImage* imImageCreate(int width, int height, int color_space, int data_type);

/** Initializes the image structure but does not allocates image data.
 * See also \ref imDataType and \ref imColorSpace.
 * \ingroup imgclass */
imImage* imImageInit(int width, int height, int color_space, int data_type, void* data_buffer, long* palette, int palette_count);

/** Creates a new image based on an existing one. \n
 * If the addicional parameters are -1, the given image parameters are used. \n
 * The image atributes always are copied. HasAlpha is copied.
 * See also \ref imDataType and \ref imColorSpace.
 *
 * \verbatim im.ImageCreateBased(image: imImage, [width: number], [height: number], [color_space: number], [data_type: number]) -> image: imImage [in Lua 5] \endverbatim
 * The addicional parameters in Lua can be nil, 
 * and they can also be functions with the based image as a parameter to return the respective value.
 * \ingroup imgclass */
imImage* imImageCreateBased(const imImage* image, int width, int height, int color_space, int data_type);

/** Destroys the image and frees the memory used.
 * image data is destroyed only if its data[0] is not NULL. \n
 * In Lua if this function is not called, the image is destroyed by the garbage collector.
 *
 * \verbatim im.ImageDestroy(image: imImage) [in Lua 5] \endverbatim
 * \verbatim image:Destroy() [in Lua 5] \endverbatim
 * \ingroup imgclass */
void imImageDestroy(imImage* image);

/** Adds an alpha channel plane.
 *
 * \verbatim image:AddAlpha() [in Lua 5] \endverbatim
 * \ingroup imgclass */
void imImageAddAlpha(imImage* image);

/** Changes the buffer size. Reallocate internal buffers if the new size is larger than the original.
 *
 * \verbatim image:Reshape(width: number, height: number) [in Lua 5] \endverbatim
 * \ingroup imgclass */
void imImageReshape(imImage* image, int width, int height);

/** Copy image data and attributes from one image to another. \n
 * Images must have the same size and type.
 *
 * \verbatim image:Copy(dst_image: imImage) [in Lua 5] \endverbatim
 * \ingroup imgclass */
void imImageCopy(const imImage* src_image, imImage* dst_image);

/** Copy image data only fom one image to another. \n
 * Images must have the same size and type.
 *
 * \verbatim image:CopyData(dst_image: imImage) [in Lua 5] \endverbatim
 * \ingroup imgclass */
void imImageCopyData(const imImage* src_image, imImage* dst_image);

/** Copies the image attributes from src to dst.
 * Includes the pallete when a MAP or GRAY image.
 *
 * \verbatim image:CopyAttributes(dst_image: imImage) [in Lua 5] \endverbatim
 * \ingroup imgclass */
void imImageCopyAttributes(const imImage* src_image, imImage* dst_image);

/** Copy one image plane fom one image to another. \n
 * Images must have the same size and type.
 *
 * \verbatim image:CopyPlane(src_plane: number, dst_image: imImage, dst_plane: number) [in Lua 5] \endverbatim
 * \ingroup imgclass */
void imImageCopyPlane(const imImage* src_image, int src_plane, imImage* dst_image, int dst_plane);

/** Creates a copy of the image.
 *
 * \verbatim image:Duplicate() -> new_image: imImage [in Lua 5] \endverbatim
 * \ingroup imgclass */
imImage* imImageDuplicate(const imImage* image);

/** Creates a clone of the image. i.e. same attributes but ignore contents.
 *
 * \verbatim image:Clone() -> new_image: imImage [in Lua 5] \endverbatim
 * \ingroup imgclass */
imImage* imImageClone(const imImage* image);

/** Changes an extended attribute. \n
 * The data will be internally duplicated. \n
 * If data is NULL and count==0 the attribute is removed. \n
 * If count is -1 and data_type is IM_BYTE then data is zero terminated.
 * See also \ref imDataType.
 *
 * \verbatim image:SetAttribute(attrib: string, data_type: number, data: table of numbers or string) [in Lua 5] \endverbatim
 * If data_type is IM_BYTE, as_string can be used as data.
 * \ingroup imgclass */
void imImageSetAttribute(const imImage* image, const char* attrib, int data_type, int count, const void* data);

/** Returns an extended attribute. \n
 * Returns NULL if not found.
 * See also \ref imDataType.
 *
 * \verbatim image:GetAttribute(attrib: string, [as_string: boolean]) -> data: table of numbers or string, data_type: number [in Lua 5] \endverbatim
 * If data_type is IM_BYTE, as_string can be used to return a string instead of a table.
 * \ingroup imgclass */
const void* imImageGetAttribute(const imImage* image, const char* attrib, int *data_type, int *count);

/** Returns a list of the attribute names. \n
 * "attrib" must contain room enough for "attrib_count" names. Use "attrib=NULL" to return only the count.
 *
 * \verbatim image:GetAttributeList() -> data: table of strings [in Lua 5] \endverbatim
 * \ingroup imgclass */
void imImageGetAttributeList(const imImage* image, char** attrib, int *attrib_count);

/** Sets all image data to zero. But if color space is YCBCR, LAB or LUV, and data type is BYTE or USHORT, then
 * data is initialized with 128 or 32768 accordingly. Alpha is initialized as transparent (0).
 *
 * \verbatim image:Clear() [in Lua 5] \endverbatim
 * \ingroup imgclass */
void imImageClear(imImage* image);

/** Indicates that the image can be viewed in common graphic devices.     
 * Data type must be IM_BYTE. Color mode can be IM_RGB, IM_MAP, IM_GRAY or IM_BINARY.
 *
 * \verbatim image:IsBitmap() -> is_bitmap: boolean [in Lua 5] \endverbatim
 * \ingroup imgclass */
int imImageIsBitmap(const imImage* image);

/** Changes the image palette.
 * This will destroy the existing palette and replace it with the given palette pointer.
 * Only the pointer is stored, so the palette should be a new palette and it can not be a static array.
 *
 * \verbatim image:SetPalette(palette: imPalette) [in Lua 5] \endverbatim
 * \ingroup imgclass */
void imImageSetPalette(imImage* image, long* palette, int palette_count);

/** Returns 1 if the images match width and height. Returns 0 otherwise.
 *
 * \verbatim image:MatchSize(image2: imImage) -> match: boolean [in Lua 5] \endverbatim
 * \ingroup imgclass */
int imImageMatchSize(const imImage* image1, const imImage* image2);

/** Returns 1 if the images match color mode and data type. Returns 0 otherwise.
 *
 * \verbatim image:MatchColor(image2: imImage) -> match: boolean [in Lua 5] \endverbatim
 * \ingroup imgclass */
int imImageMatchColor(const imImage* image1, const imImage* image2);

/** Returns 1 if the images match width, height and data type. Returns 0 otherwise.
 *
 * \verbatim image:MatchDataType(image2: imImage) -> match: boolean [in Lua 5] \endverbatim
 * \ingroup imgclass */
int imImageMatchDataType(const imImage* image1, const imImage* image2);

/** Returns 1 if the images match width, height and color space. Returns 0 otherwise.
 *
 * \verbatim image:MatchColorSpace(image2: imImage) -> match: boolean [in Lua 5] \endverbatim
 * \ingroup imgclass */
int imImageMatchColorSpace(const imImage* image1, const imImage* image2);

/** Returns 1 if the images match in width, height, data type and color space. Returns 0 otherwise.
 *
 * \verbatim image:Match(image2: imImage) -> match: boolean [in Lua 5] \endverbatim
 * \ingroup imgclass */
int imImageMatch(const imImage* image1, const imImage* image2);

/** Changes the image color space from gray to binary by just changing color_space and the palette.
 *
 * \verbatim image:SetBinary() [in Lua 5] \endverbatim
 * \ingroup imgclass */
void imImageSetBinary(imImage* image);

/** Changes a gray BYTE data (0,255) into a binary data (0,1), done in-place. Color space is not changed.
 *
 * \verbatim image:MakeBinary() [in Lua 5] \endverbatim
 * \ingroup imgclass */
void imImageMakeBinary(imImage *image);

/** Changes a binary data (0,1) into a gray BYTE data (0,255), done in-place. Color space is not changed.
 *
 * \verbatim image:MakeGray() [in Lua 5] \endverbatim
 * \ingroup imgclass */
void imImageMakeGray(imImage *image);



/** \defgroup imgfile imImage Storage
 *
 * \par
 *  Functions to simplify the process of reading and writting imImage structures. 
 *  Will also load and save the alpha planes when possible.
 * \par
 * See \ref im_image.h
 * \ingroup file */


/** Loads an image from an already open file. Returns NULL if failed. \n
 * This will call \ref imFileReadImageInfo and \ref imFileReadImageData. \n
 * index specifies the image number between 0 and image_count-1. \n
 * The returned image will be of the same color_space and data_type of the image in the file. \n
 * Attributes from the file will be stored at the image.
 * See also \ref imErrorCodes.
 *
 * \verbatim ifile:LoadImage([index: number]) -> image: imImage, error: number [in Lua 5] \endverbatim
 * Default index is 0.
 * \ingroup imgfile */
imImage* imFileLoadImage(imFile* ifile, int index, int *error);

/** Loads an image from an already open file. Returns NULL if failed. \n
 * This function assumes that the image in the file has the same parameters as the given image. \n
 * This will call \ref imFileReadImageInfo and \ref imFileReadImageData. \n
 * index specifies the image number between 0 and image_count-1. \n
 * The returned image will be of the same color_space and data_type of the image in the file. \n
 * Attributes from the file will be stored at the image.
 * See also \ref imErrorCodes.
 *
 * \verbatim ifile:LoadImageFrame(index: number, image: imImage) -> error: number [in Lua 5] \endverbatim
 * Default index is 0.
 * \ingroup imgfile */
void imFileLoadImageFrame(imFile* ifile, int index, imImage* image, int *error);

/** Loads an image from an already open file, but forces the image to be a bitmap.\n
 * The returned imagem will be always a Bitmap image, with color_space RGB, MAP, GRAY or BINARY, and data_type IM_BYTE. \n
 * index specifies the image number between 0 and image_count-1. \n
 * Returns NULL if failed.
 * Attributes from the file will be stored at the image.
 * See also \ref imErrorCodes.
 *
 * \verbatim ifile:LoadBitmap([index: number]) -> image: imImage, error: number [in Lua 5] \endverbatim
 * Default index is 0.
 * \ingroup imgfile */
imImage* imFileLoadBitmap(imFile* ifile, int index, int *error);

/** Loads an image region from an already open file. Returns NULL if failed. \n
 * This will call \ref imFileReadImageInfo and \ref imFileReadImageData. \n
 * index specifies the image number between 0 and image_count-1. \n
 * The returned image will be of the same color_space and data_type of the image in the file, 
 * or will be a Bitmap image. \n
 * Attributes from the file will be stored at the image.
 * See also \ref imErrorCodes. \n
 * For now, it works only for the ECW file format.
 *
 * \verbatim ifile:LoadRegion(index, bitmap, xmin, xmax, ymin, ymax, width, height: number) -> image: imImage, error: number [in Lua 5] \endverbatim
 * Default index is 0.
 * \ingroup imgfile */
imImage* imFileLoadImageRegion(imFile* ifile, int index, int bitmap, int *error, 
                               int xmin, int xmax, int ymin, int ymax, int width, int height);

/** Loads an image from an already open file, but forces the image to be a bitmap.\n
 * This function assumes that the image in the file has the same parameters as the given image. \n
 * The imagem must be a Bitmap image, with color_space RGB, MAP, GRAY or BINARY, and data_type IM_BYTE. \n
 * index specifies the image number between 0 and image_count-1. \n
 * Returns NULL if failed.
 * Attributes from the file will be stored at the image.
 * See also \ref imErrorCodes.
 *
 * \verbatim ifile:LoadBitmapFrame(index: number, image: imImage) -> error: number [in Lua 5] \endverbatim
 * Default index is 0.
 * \ingroup imgfile */
void imFileLoadBitmapFrame(imFile* ifile, int index, imImage* image, int *error);

/** Saves the image to an already open file. \n
 * This will call \ref imFileWriteImageInfo and \ref imFileWriteImageData. \n
 * Attributes from the image will be stored at the file.
 * Returns error code.
 *
 * \verbatim ifile:SaveImage(image: imImage) -> error: number [in Lua 5] \endverbatim
 * \ingroup imgfile */
int imFileSaveImage(imFile* ifile, const imImage* image);

/** Loads an image from file. Open, loads and closes the file. \n
 * index specifies the image number between 0 and image_count-1. \n
 * Returns NULL if failed.
 * Attributes from the file will be stored at the image.
 * See also \ref imErrorCodes.
 *
 * \verbatim im.FileImageLoad(file_name: string, [index: number]) -> image: imImage, error: number [in Lua 5] \endverbatim
 * Default index is 0.
 * \ingroup imgfile */
imImage* imFileImageLoad(const char* file_name, int index, int *error);

/** Loads an image from file, but forces the image to be a bitmap. Open, loads and closes the file. \n
 * index specifies the image number between 0 and image_count-1. \n
 * Returns NULL if failed.
 * Attributes from the file will be stored at the image.
 * See also \ref imErrorCodes.
 *
 * \verbatim im.FileImageLoadBitmap(file_name: string, [index: number]) -> image: imImage, error: number [in Lua 5] \endverbatim
 * Default index is 0.
 * \ingroup imgfile */
imImage* imFileImageLoadBitmap(const char* file_name, int index, int *error);

/** Loads an image region from file. Open, loads and closes the file. \n
 * index specifies the image number between 0 and image_count-1. \n
 * Returns NULL if failed.
 * Attributes from the file will be stored at the image.
 * See also \ref imErrorCodes. \n
 * For now, it works only for the ECW file format.
 *
 * \verbatim im.FileImageLoadRegion(file_name: string, index, bitmap, xmin, xmax, ymin, ymax, width, height: number, ) -> image: imImage, error: number [in Lua 5] \endverbatim
 * Default index is 0.
 * \ingroup imgfile */
imImage* imFileImageLoadRegion(const char* file_name, int index, int bitmap, int *error, 
                               int xmin, int xmax, int ymin, int ymax, int width, int height);

/** Saves the image to file. Open, saves and closes the file. \n
 * Returns error code. \n
 * Attributes from the image will be stored at the file.
 *
 * \verbatim im.FileImageSave(file_name: string, format: string, image: imImage) -> error: number [in Lua 5] \endverbatim
 * \verbatim image:Save(file_name: string, format: string) -> error: number [in Lua 5] \endverbatim
 * \ingroup imgfile */
int imFileImageSave(const char* file_name, const char* format, const imImage* image);



/** Utility macro to draw the image in a CD library canvas.
 * Works only for data_type IM_BYTE, and color spaces: IM_RGB, IM_MAP, IMGRAY and IM_BINARY.
 * \ingroup imgclass */
#define imcdCanvasPutImage(_canvas, _image, _x, _y, _w, _h, _xmin, _xmax, _ymin, _ymax)     \
  {                                                                         \
    if (_image->color_space == IM_RGB)                                      \
    {                                                                       \
      if (_image->has_alpha)                                                \
        cdCanvasPutImageRectRGBA(_canvas, _image->width, _image->height,    \
                          (unsigned char*)_image->data[0],                  \
                          (unsigned char*)_image->data[1],                  \
                          (unsigned char*)_image->data[2],                  \
                          (unsigned char*)_image->data[3],                  \
                          _x, _y, _w, _h, _xmin, _xmax, _ymin, _ymax);      \
      else                                                                  \
        cdCanvasPutImageRectRGB(_canvas, _image->width, _image->height,     \
                          (unsigned char*)_image->data[0],                  \
                          (unsigned char*)_image->data[1],                  \
                          (unsigned char*)_image->data[2],                  \
                          _x, _y, _w, _h, _xmin, _xmax, _ymin, _ymax);      \
    }                                                                       \
    else                                                                    \
      cdCanvasPutImageRectMap(_canvas, _image->width, _image->height,       \
                        (unsigned char*)_image->data[0], _image->palette,   \
                        _x, _y, _w, _h, _xmin, _xmax, _ymin, _ymax);        \
  }                                                                               


#if	defined(__cplusplus)
}
#endif

#endif