#ifndef UTILS_H #define UTILS_H /* * 0 0 0 0 0 0 0 0 * ^ - Starting Bit for all calculations * ^ - Starting bit for when I talk about sets of bits */ // The u in the BYTE Macros are for unsigned calls so colors are not changed to // signed and the values cut in half #define BYTE_A 0xFF000000u /**< Isolates the First Byte for alpha */ #define BYTE_R 0x00FF0000u /**< Isolates the Second Byte for red */ #define BYTE_G 0x0000FF00u /**< Isolates the Third Byte for green */ #define BYTE_B 0x000000FFu /**< Isolates the Fourth Byte for blue */ #define BYTE_RGB 0x00FFFFFFu /**< Isolates 24-Bits from end (RGB) */ #define BYTE 0xFFu /**< Pulls out 8 shifted Bits */ #define LONG_BYTE 0xFFFFu /**< Pulls out 16 shifted Bits */ #define SHIFT_8 8 /**< Constant shift of 8-Bits */ #define SHIFT_16 16 /**< Constant shift of 16-Bits */ #define SHIFT_24 24 /**< Constant shift of 24-Bits */ /** * * @brief Max value for any channel * @details For alpha channel this is the max opacity setting and 0 is fully * transparent, 255 is white for any color and 0 is black. * */ #define MAX 255 #define HALF_MAX \ ((int)(MAX / 2) + 1) /**< Half Max Color Value for any channel */ /**< Func to isolate alpha channel into variable */ #define DECODE_A(clr) (((clr) >> SHIFT_24) & BYTE) /**< Func to isolate red channel into variable */ #define DECODE_R(clr) (((clr) >> SHIFT_16) & BYTE) /**< Func to isolate green channel into variable */ #define DECODE_G(clr) (((clr) >> SHIFT_8) & BYTE) /**< Func to isolate blue channel into variable */ #define DECODE_B(clr) ((clr) & BYTE) /** * @brief Packs RGB channels into int * @details Takes R, G, B char channels and packs them into a singular integer * with the first 8 Bits reserved for alpha channel (set to MAX by default). See * diagram at top for my thinking of starting bits * @param[in] r The red channel stored as char and packed into int * @param[in] g The green channel stored as char and packed into int * @param[in] b The blue channel stored as char and packed into int * * */ #define ENCODE_RGB(r, g, b) \ (((unsigned int)(MAX) << SHIFT_24) | ((unsigned int)(r) << SHIFT_16) | \ ((unsigned int)(g) << SHIFT_8) | (unsigned int)(b)) /** * @brief Packs ARGB channels into int * @details Takes A, R, G, B char channels and packs them into a singular * integer with the first 8 Bits reserved for alpha channel. See diagram at top * for my thinking of starting bits * @param[in] a The alpha channel stored as char and packed into int * @param[in] r The red channel stored as char and packed into int * @param[in] g The green channel stored as char and packed into int * @param[in] b The blue channel stored as char and packed into int * * */ #define ENCODE_ARGB(a, r, g, b) \ (((unsigned int)(a) << SHIFT_24) | ((unsigned int)(r) << SHIFT_16) | \ ((unsigned int)(g) << SHIFT_8) | (unsigned int)(b)) /** * @brief Stops values exiting 0 - 255 range * @details Takes in a value of X and checks if it is Above the Max of 255. If * so, then set to Max. If not, then simply set back to whatever X was before. * @param[in] x Color channel: char * */ #define CLAMP_MAX(x) (((x) > MAX) ? MAX : (x)) /** * @brief Stops values exiting 0 - 255 range * @details Takes in a value of X and checks if it is Below 0. If so, then set * to 0. If not, then simply set back to whatever X was before. * @param[in] x Color channel: char * */ #define CLAMP_MIN(x) (((x) < 0) ? 0 : (x)) /** * @brief Contains values for PPM Image * @details Can be defined with just a name and filled later with ppm_load * as it stores information for header of file not the pixels of the image * */ typedef struct { int width; /**< Image width in pixels */ int height; /**< Image height in pixels */ int len; /**< Image length in pixels, width * height */ char* name; /**< File name and location, relative */ char fmt; /**< Raw or Binary values, P3 or P6 respectively*/ } PPM; /** * @brief Contains values for JPEG Image * @details Can be defined with just a name and filled later with jpeg_load as * it stores information for header of file not the pixels of the image * */ typedef struct { int width; /**< Image width in pixels */ int height; /**< Image height in pixels */ int len; /**< Image length in pixels, width * height */ char* name; /**< File name and location, relative */ } JPEG; /** * @brief Converts an int to long * @details Takes in 32-Bit packed color and separates the 4 color values into a * 64-Bit packed color. Used for bigger image calculations with one channel and * then dividing later. * @param[in] clr Takes a packed color, unsigned int * @return unsigned long Packed color in 4 ints instead of one * */ unsigned long u32to_u64(const unsigned int clr); /** * @brief Converts a long to int * @details Takes in a full packed color and compresses it to 1 Byte * @param[in] clr Takes a packed color, unsigned long * @param[in] u64_div Takes a divisor to break down to raw color * @return unsigned int Packed color in 1 int instead of 4 * */ unsigned int u64to_u32(const unsigned long clr, const unsigned long u64_div); /** * @brief Prints quick debug info of container * @details Prints metadata like Name, Format, Width, Height and Length * important for debugging errors * @param[in] src Pointer to src metadata of a PPM image * */ void __attribute__((overloadable)) print_attr(const PPM* src); /** * @brief Prints quick debug info of container * @details Prints metadata like Name, Width, Height and Length * important for debugging errors * @param[in] src Pointer to src metadata of a JPEG image * */ void __attribute__((overloadable)) print_attr(const JPEG* src); #endif