// Copyright 2023 alexevier // licensed under the zlib license #ifndef lexlib_image_h #define lexlib_image_h #include"common.h" #include #include #include"color.h" // TODO refactor error handeling, returns are inconsistent. // TODO check binary data for image format instead of file extension. // TODO bmp file writes should be checked. /* supported file formats ● bmp ● png | libpng and zlib are optionally required. */ // it's raw data is layed in rgba order in the machine native endianness. // |rgba|rgba|rgba|rgba|rgba|...| // reading the members of the struct is supported but modifing it is not. // 8 and 16 bits per color are supported. // RGBA, RGB, GrayScale w/o alpha is supported. struct LexlibImage { void *data; uint32_t width; uint32_t height; uint8_t channels; uint8_t bpc; /* bits per color */ uint8_t bpp; /* bits per pixel */ uint8_t profile; uint8_t flags; }; #define LEXLIB_FLIP_X 0x01u #define LEXLIB_FLIP_Y 0x02u #define LEXLIB_ALPHA 0x80u #define LEXLIB_BMP_CORE 0x0Cu #define LEXLIB_BMP_INFO 0x28u #define LEXLIB_BMP_INFO_V3 0x38u #define LEXLIB_IMAGE_ZERO ((struct LexlibImage){NULL, 0, 0, 0, 0, 0, 0, 0x00}) // creates a new LexlibImage and allocates its memory. // bpc and colorProfile can be 0, default is used (RGB,8). // width/height can't be 0. // colorProfile can be any value from the LexlibColorProfile enum. (RGB555/565 are interpreted as RGB). // bpc can be 0,8,16. // returns: // LEXLIB_OK (0): everthing ok. // LEXLIB_OUT_OF_MEMORY: failed to allocate memory. // LEXLIB_INVALID_VALUE: width or height are invalid. // LEXLIB_INVALID_ARG: colorProfile or bpc are invalid. LEXLIB_EXTERN uint8_t lexlibImageNew(struct LexlibImage *image, uint32_t width, uint32_t height, uint8_t colorProfile, uint8_t bpc); // destroys a LexlibImage and its data. LEXLIB_EXTERN void lexlibImageDelete(struct LexlibImage *image); // creates a copy of a LexlibImage. // returns: // LEXLIB_OK (0): the copy was succesfull. // LEXLIB_OUT_OF_MEMORY: failed to allocate memory for the copy. // LEXLIB_INVALID_VALUE: the original image is not valid. LEXLIB_EXTERN uint8_t lexlibImageCopy(struct LexlibImage *copy, const struct LexlibImage *original); // validates a LexlibImage. // returns 0 if everthing is ok, nonzero otherwise. LEXLIB_EXTERN uint8_t lexlibImageValidate(const struct LexlibImage *image); // flips a image in the x and/or y axis depending of the flags. // the flags can be LEXLIB_FLIP_X, LEXLIB_FLIP_Y, they can be or'd together. // returns 0 on success, on error LEXLIB_INVALID_VALUE or LEXLIB_OUT_OF_MEMORY. // returns: // LEXLIB_OK (0): flipped the image successfully. // LEXLIB_OUT_OF_MEMORY: failed to allocate tmp buffer. // LEXLIB_INVALID_VALUE: the flags are invalid. LEXLIB_EXTERN uint8_t lexlibImageFlip(struct LexlibImage *image, uint8_t flags); // changes the color profile of a image. // performs color convertions. // returns: // LEXLIB_OK (0): color profile successfully changed. // LEXLIB_INVALID_VALUE: image has a invalid bpc or profile. // LEXLIB_INVALID_ARG: the new profile is invalid. // LEXLIB_OUT_OF_MEMORY: failed to make space for the image data. LEXLIB_EXTERN uint8_t lexlibImageProfileChange(struct LexlibImage *image, uint8_t profile); // fills an area in a LexlibImage // the x, y, w, h are counted from the origin. // on success returns LEXLIB_OK (0), on error LEXLIB_INVALID_OPERATION. LEXLIB_EXTERN uint8_t lexlibImageFillArea(struct LexlibImage *image, uint32_t x, uint32_t y, uint32_t w, uint32_t h, struct LexlibColor color, uint8_t blendmode); // gets a pixel from a image. // according transformations to the returned color are performed depending of the image profile. // alpha is at max if the image does not have a alpha channel. // on error color is set to LEXLIB_COLOR_MAGENTA. // returns: // LEXLIB_OK (0): pixel was successfully retrieved. // LEXLIB_INVALID_OPERATION: out of bounds. // LEXLIB_INVALID_VALUE: the image has a invalid color profile. LEXLIB_EXTERN uint8_t lexlibImagePixel(const struct LexlibImage *image, uint32_t x, uint32_t y, struct LexlibColor* color); LEXLIB_EXTERN uint8_t lexlibImagePixel16(const struct LexlibImage *image, uint32_t x, uint32_t y, struct LexlibColor16* color); // sets a pixel in a image. // according transformations to the passed color are performed depending of the image profile. // alpha is premultiplied if the image does not have a alpha channel. // returns 0 on success, LEXLIB_INVALID_OPERATION on error. // returns: // LEXLIB_OK (0): pixel successfully set. // LEXLIB_INVALID_OPERATION: out of bounds. // LEXLIB_INVALID_VALUE: image containts a invalid color profile. LEXLIB_EXTERN uint8_t lexlibImagePixelSet(struct LexlibImage *image, uint32_t x, uint32_t y, struct LexlibColor color, uint8_t blendmode); LEXLIB_EXTERN uint8_t lexlibImagePixel16Set(struct LexlibImage *image, uint32_t x, uint32_t y, struct LexlibColor16 color, uint8_t blendmode); // loads a image. // supported formats: bmp, png. // returns: // LEXLIB_OK (0): image successfully loaded. // LEXLIB_CANT_OPEN: the file doesn't exist or user might not have permissions. // LEXLIB_CANT_READ: can't read the file, might be corrupted/broken. // LEXLIB_INVALID_TYPE: the file is not a image or a unknown format to lexlib. // LEXLIB_INVALID_DATA: the image contains invalid data, might be corrupted. // LEXLIB_UNSUPORTED: the image format/type is unsuported. // LEXLIB_OUT_OF_MEMORY: failed to allocate space for the image or temporal buffers. // LEXLIB_ERROR: an unknown fatal error occured, this should never happend. LEXLIB_EXTERN uint8_t lexlibImageLoad(struct LexlibImage *image, const char *filename); // saves image as a file. // supported formats: bmp, png. // uses the format from the file extension in the filename. // returns: // LEXLIB_OK (0): image successfully saved. // LEXLIB_INVALID_NAME: the filename did not have a extension. // LEXLIB_CANT_WRITE: can't create/write the file. // LEXLIB_PARTIAL_WRITE: wrote only part of the file. // LEXLIB_OUT_OF_MEMORY: failed to allocate space for temporal buffers. // LEXLIB_UNSUPORTED: image has a combination of attributes that the format doesn't support. LEXLIB_EXTERN uint8_t lexlibImageSave(const struct LexlibImage *image, const char *filename); // loads a bmp file. // returns: // LEXLIB_OK (0): image successfully loaded. // LEXLIB_CANT_OPEN: couldn't open the file. // LEXLIB_CANT_READ: failed reading the file. // LEXLIB_PARTIAL_READ: couldn't read the entire image, (what was read is stored). // LEXLIB_INVALID_TYPE: its not a bmp. // LEXLIB_INVALID_DATA: contains invalid data. // LEXLIB_INVALID_LEN: file/buffer is shorter than expected. // LEXLIB_UNSUPORTED: the bmp is not supported. // LEXLIB_OUT_OF_MEMORY: failed to allocate memory for the image. LEXLIB_EXTERN uint8_t lexlibImageLoadBmp(struct LexlibImage *image, const char *filename); LEXLIB_EXTERN uint8_t lexlibImageLoadBmpMem(struct LexlibImage *image, const void *mem, size_t size); // saves a image as a bmp file. // returns: // LEXLIB_OK (0): image successfully saved. // LEXLIB_INVALID_VALUE: image contains invalid values. // LEXLIB_CANT_WRITE: can't create the file. // LEXLIB_PARTIAL_WRITE: couldn't write the entire image. LEXLIB_EXTERN uint8_t lexlibImageSaveBmp(const struct LexlibImage *image, const char *filename); // saves a image to a bmp file with extra options // for defaults profile and header can be left 0. // if the image/profile contains alpha its recommended to use LEXLIB_BMP_INFO_V3 for header. // returns: // LEXLIB_OK (0): image successfully saved. // LEXLIB_INVALID_ARG: profile or header is invalid. // LEXLIB_UNSUPORTED: saving with a unsuported header. // LEXLIB_CANT_WRITE: can't create the file. // LEXLIB_PARTIAL_WRITE: couldn't write the entire image. LEXLIB_EXTERN uint8_t lexlibImageSaveBmpEx(const struct LexlibImage *image, const char *filename, uint8_t profile, uint8_t header); // load a png file. // returns: // LEXLIB_OK (0): image successfully loaded. // LEXLIB_CANT_OPEN: couldn't open the file. // LEXLIB_CANT_READ: failed reading the file. // LEXLIB_INVALID_TYPE: its not a png. // LEXLIB_UNSUPORTED: the png is not supported. // LEXLIB_OUT_OF_MEMORY: failed to allocate memory for the image. // LEXLIB_ERROR: unknown error, this should never happen. LEXLIB_EXTERN uint8_t lexlibImageLoadPng(struct LexlibImage *image, const char *filename); // saves a image as png. // saving 16bpc png is supported only with libpng. // returns: // LEXLIB_OK (0): image successfully saved. // LEXLIB_CANT_WRITE: can't create the file. // LEXLIB_UNSUPORTED: format is not supported. // LEXLIB_OUT_OF_MEMORY: failed to allocate tmp buffers. LEXLIB_EXTERN uint8_t lexlibImageSavePng(const struct LexlibImage *image, const char *filename); #ifdef LEXLIB_EXPERIMENTAL // tries to fix a lexlib image. LEXLIB_EXTERN uint8_t lexlibImageRepairStruct(struct LexlibImage *image); #endif #endif