nuclear@0: /* nuclear@0: libimago - a multi-format image file input/output library. nuclear@0: Copyright (C) 2010-2012 John Tsiombikas nuclear@0: nuclear@0: This program is free software: you can redistribute it and/or modify nuclear@0: it under the terms of the GNU Lesser General Public License as published nuclear@0: by the Free Software Foundation, either version 3 of the License, or nuclear@0: (at your option) any later version. nuclear@0: nuclear@0: This program is distributed in the hope that it will be useful, nuclear@0: but WITHOUT ANY WARRANTY; without even the implied warranty of nuclear@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nuclear@0: GNU Lesser General Public License for more details. nuclear@0: nuclear@0: You should have received a copy of the GNU Lesser General Public License nuclear@0: along with this program. If not, see . nuclear@0: */ nuclear@0: nuclear@0: #ifndef IMAGO2_H_ nuclear@0: #define IMAGO2_H_ nuclear@0: nuclear@0: #include nuclear@0: nuclear@0: #ifdef __cplusplus nuclear@0: #define IMG_OPTARG(arg, val) arg = val nuclear@0: #else nuclear@0: #define IMG_OPTARG(arg, val) arg nuclear@0: #endif nuclear@0: nuclear@0: /* XXX if you change this make sure to also change pack/unpack arrays in conv.c */ nuclear@0: enum img_fmt { nuclear@0: IMG_FMT_GREY8, nuclear@0: IMG_FMT_RGB24, nuclear@0: IMG_FMT_RGBA32, nuclear@0: IMG_FMT_GREYF, nuclear@0: IMG_FMT_RGBF, nuclear@0: IMG_FMT_RGBAF, nuclear@0: nuclear@0: NUM_IMG_FMT nuclear@0: }; nuclear@0: nuclear@0: struct img_pixmap { nuclear@0: void *pixels; nuclear@0: int width, height; nuclear@0: enum img_fmt fmt; nuclear@0: int pixelsz; nuclear@0: char *name; nuclear@0: }; nuclear@0: nuclear@0: struct img_io { nuclear@0: void *uptr; /* user-data */ nuclear@0: nuclear@0: size_t (*read)(void *buf, size_t bytes, void *uptr); nuclear@0: size_t (*write)(void *buf, size_t bytes, void *uptr); nuclear@0: long (*seek)(long offs, int whence, void *uptr); nuclear@0: }; nuclear@0: nuclear@0: #ifdef __cplusplus nuclear@0: extern "C" { nuclear@0: #endif nuclear@0: nuclear@0: /* initialize the img_pixmap structure */ nuclear@0: void img_init(struct img_pixmap *img); nuclear@0: /* destroys the img_pixmap structure, freeing the pixel buffer (if available) nuclear@0: * and any other memory held by the pixmap. nuclear@0: */ nuclear@0: void img_destroy(struct img_pixmap *img); nuclear@0: nuclear@0: /* convenience function that allocates an img_pixmap struct and then initializes it. nuclear@0: * returns null if the malloc fails. nuclear@0: */ nuclear@0: struct img_pixmap *img_create(void); nuclear@0: /* frees a pixmap previously allocated with img_create (free followed by img_destroy) */ nuclear@0: void img_free(struct img_pixmap *img); nuclear@0: nuclear@0: int img_set_name(struct img_pixmap *img, const char *name); nuclear@0: nuclear@0: /* set the image pixel format */ nuclear@0: int img_set_format(struct img_pixmap *img, enum img_fmt fmt); nuclear@0: nuclear@0: /* copies one pixmap to another. nuclear@0: * equivalent to: img_set_pixels(dest, src->width, src->height, src->fmt, src->pixels) nuclear@0: */ nuclear@0: int img_copy(struct img_pixmap *dest, struct img_pixmap *src); nuclear@0: nuclear@0: /* allocates a pixel buffer of the specified dimensions and format, and copies the nuclear@0: * pixels given through the pix pointer into it. nuclear@0: * the pix pointer can be null, in which case there's no copy, just allocation. nuclear@0: * nuclear@0: * C++: fmt and pix have default parameters IMG_FMT_RGBA32 and null respectively. nuclear@0: */ nuclear@0: int img_set_pixels(struct img_pixmap *img, int w, int h, IMG_OPTARG(enum img_fmt fmt, IMG_FMT_RGBA32), IMG_OPTARG(void *pix, 0)); nuclear@0: nuclear@0: /* Simplified image loading nuclear@0: * Loads the specified file, and returns a pointer to an array of pixels of the nuclear@0: * requested pixel format. The width and height of the image are returned through nuclear@0: * the xsz and ysz pointers. nuclear@0: * If the image cannot be loaded, the function returns null. nuclear@0: * nuclear@0: * C++: the format argument is optional and defaults to IMG_FMT_RGBA32 nuclear@0: */ nuclear@0: void *img_load_pixels(const char *fname, int *xsz, int *ysz, IMG_OPTARG(enum img_fmt fmt, IMG_FMT_RGBA32)); nuclear@0: nuclear@0: /* Simplified image saving nuclear@0: * Reads an array of pixels supplied through the pix pointer, of dimensions xsz nuclear@0: * and ysz, and pixel-format fmt, and saves it to a file. nuclear@0: * The output filetype is guessed by the filename suffix. nuclear@0: * nuclear@0: * C++: the format argument is optional and defaults to IMG_FMT_RGBA32 nuclear@0: */ nuclear@0: int img_save_pixels(const char *fname, void *pix, int xsz, int ysz, IMG_OPTARG(enum img_fmt fmt, IMG_FMT_RGBA32)); nuclear@0: nuclear@0: /* Frees the memory allocated by img_load_pixels */ nuclear@0: void img_free_pixels(void *pix); nuclear@0: nuclear@0: /* Loads an image file into the supplied pixmap */ nuclear@0: int img_load(struct img_pixmap *img, const char *fname); nuclear@0: /* Saves the supplied pixmap to a file. The output filetype is guessed by the filename suffix */ nuclear@0: int img_save(struct img_pixmap *img, const char *fname); nuclear@0: nuclear@0: /* Reads an image from an open FILE* into the supplied pixmap */ nuclear@0: int img_read_file(struct img_pixmap *img, FILE *fp); nuclear@0: /* Writes the supplied pixmap to an open FILE* */ nuclear@0: int img_write_file(struct img_pixmap *img, FILE *fp); nuclear@0: nuclear@0: /* Reads an image using user-defined file-i/o functions (see img_io_set_*) */ nuclear@0: int img_read(struct img_pixmap *img, struct img_io *io); nuclear@0: /* Writes an image using user-defined file-i/o functions (see img_io_set_*) */ nuclear@0: int img_write(struct img_pixmap *img, struct img_io *io); nuclear@0: nuclear@0: /* Converts an image to the specified pixel format */ nuclear@0: int img_convert(struct img_pixmap *img, enum img_fmt tofmt); nuclear@0: nuclear@0: /* Converts an image from an integer pixel format to the corresponding floating point one */ nuclear@0: int img_to_float(struct img_pixmap *img); nuclear@0: /* Converts an image from a floating point pixel format to the corresponding integer one */ nuclear@0: int img_to_integer(struct img_pixmap *img); nuclear@0: nuclear@0: /* Returns non-zero (true) if the supplied image is in a floating point pixel format */ nuclear@0: int img_is_float(struct img_pixmap *img); nuclear@0: /* Returns non-zero (true) if the supplied image has an alpha channel */ nuclear@0: int img_has_alpha(struct img_pixmap *img); nuclear@0: nuclear@0: nuclear@0: /* don't use these for anything performance-critical */ nuclear@0: void img_setpixel(struct img_pixmap *img, int x, int y, void *pixel); nuclear@0: void img_getpixel(struct img_pixmap *img, int x, int y, void *pixel); nuclear@0: nuclear@0: void img_setpixel1i(struct img_pixmap *img, int x, int y, int pix); nuclear@0: void img_setpixel1f(struct img_pixmap *img, int x, int y, float pix); nuclear@0: void img_setpixel4i(struct img_pixmap *img, int x, int y, int r, int g, int b, int a); nuclear@0: void img_setpixel4f(struct img_pixmap *img, int x, int y, float r, float g, float b, float a); nuclear@0: nuclear@0: void img_getpixel1i(struct img_pixmap *img, int x, int y, int *pix); nuclear@0: void img_getpixel1f(struct img_pixmap *img, int x, int y, float *pix); nuclear@0: void img_getpixel4i(struct img_pixmap *img, int x, int y, int *r, int *g, int *b, int *a); nuclear@0: void img_getpixel4f(struct img_pixmap *img, int x, int y, float *r, float *g, float *b, float *a); nuclear@0: nuclear@0: nuclear@0: /* OpenGL helper functions */ nuclear@0: nuclear@0: /* Returns the equivalent OpenGL "format" as expected by the 7th argument of glTexImage2D */ nuclear@0: unsigned int img_fmt_glfmt(enum img_fmt fmt); nuclear@0: /* Returns the equivalent OpenGL "type" as expected by the 8th argument of glTexImage2D */ nuclear@0: unsigned int img_fmt_gltype(enum img_fmt fmt); nuclear@0: /* Returns the equivalent OpenGL "internal format" as expected by the 3rd argument of glTexImage2D */ nuclear@0: unsigned int img_fmt_glintfmt(enum img_fmt fmt); nuclear@0: nuclear@0: /* Same as above, based on the pixel format of the supplied image */ nuclear@0: unsigned int img_glfmt(struct img_pixmap *img); nuclear@0: unsigned int img_gltype(struct img_pixmap *img); nuclear@0: unsigned int img_glintfmt(struct img_pixmap *img); nuclear@0: nuclear@0: /* Creates an OpenGL texture from the image, and returns the texture id, or 0 for failure */ nuclear@0: unsigned int img_gltexture(struct img_pixmap *img); nuclear@0: nuclear@0: /* Load an image and create an OpenGL texture out of it */ nuclear@0: unsigned int img_gltexture_load(const char *fname); nuclear@0: unsigned int img_gltexture_read_file(FILE *fp); nuclear@0: unsigned int img_gltexture_read(struct img_io *io); nuclear@0: nuclear@0: /* These functions can be used to fill an img_io struct before it's passed to nuclear@0: * one of the user-defined i/o image reading/writing functions (img_read/img_write). nuclear@0: * nuclear@0: * User-defined i/o functions: nuclear@0: * nuclear@0: * - size_t read_func(void *buffer, size_t bytes, void *user_ptr) nuclear@0: * Must try to fill the buffer with the specified number of bytes, and return nuclear@0: * the number of bytes actually read. nuclear@0: * nuclear@0: * - size_t write_func(void *buffer, size_t bytes, void *user_ptr) nuclear@0: * Must write the specified number of bytes from the supplied buffer and return nuclear@0: * the number of bytes actually written. nuclear@0: * nuclear@0: * - long seek_func(long offset, int whence, void *user_ptr) nuclear@0: * Must seek offset bytes from: the beginning of the file if whence is SEEK_SET, nuclear@0: * the current position if whence is SEEK_CUR, or the end of the file if whence is nuclear@0: * SEEK_END, and return the resulting file offset from the beginning of the file. nuclear@0: * (i.e. seek_func(0, SEEK_CUR, user_ptr); must be equivalent to an ftell). nuclear@0: * nuclear@0: * All three functions get the user-data pointer set through img_io_set_user_data nuclear@0: * as their last argument. nuclear@0: * nuclear@0: * Note: obviously you don't need to set a write function if you're only going nuclear@0: * to call img_read, or the read and seek function if you're only going to call nuclear@0: * img_write. nuclear@0: * nuclear@0: * Note: if the user-supplied write function is buffered, make sure to flush nuclear@0: * (or close the file) after img_write returns. nuclear@0: */ nuclear@0: void img_io_set_user_data(struct img_io *io, void *uptr); nuclear@0: void img_io_set_read_func(struct img_io *io, size_t (*read)(void*, size_t, void*)); nuclear@0: void img_io_set_write_func(struct img_io *io, size_t (*write)(void*, size_t, void*)); nuclear@0: void img_io_set_seek_func(struct img_io *io, long (*seek)(long, int, void*)); nuclear@0: nuclear@0: nuclear@0: #ifdef __cplusplus nuclear@0: } nuclear@0: #endif nuclear@0: nuclear@0: nuclear@0: #endif /* IMAGO_H_ */