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 +/