From 56d26fe72306febaa9b107ffc067997d6c2b1863 Mon Sep 17 00:00:00 2001 From: Andrew Haynes Date: Thu, 3 Sep 2026 14:14:41 -0400 Subject: [PATCH] REFACTOR: Completely remade the error handling format. Using pre-defined error codes and error messages to make it easier to debug problems. --- .clang-format | 1 + include/image/imgio.h | 2 +- include/image/utils.h | 16 ++++++ src/filters.c | 19 ++++--- src/imgio.c | 127 +++++++++++++++++++++++++++++------------- src/main.c | 41 +++++++++++--- src/transformations.c | 16 +++++- src/utils.c | 33 +++++++---- 8 files changed, 188 insertions(+), 67 deletions(-) diff --git a/.clang-format b/.clang-format index 369e701..da585e7 100644 --- a/.clang-format +++ b/.clang-format @@ -17,3 +17,4 @@ AllowShortIfStatementsOnASingleLine: AllIfsAndElse AllowShortLoopsOnASingleLine: true IndentAccessModifiers: false # Indent access specifiers by one level AccessModifierOffset: -4 # Optional: adjust offset relative to the class indentation level +# SpacesInBlockCommentsStyle: Always diff --git a/include/image/imgio.h b/include/image/imgio.h index 59916b5..965d293 100644 --- a/include/image/imgio.h +++ b/include/image/imgio.h @@ -19,7 +19,7 @@ void transcode_to_jpeg(PPM* in, JPEG* out); void -transcode_to_ppm(JPEG* input, PPM* out); +transcode_to_ppm(JPEG* in, PPM* out); PPM inherit_from_jpeg(const JPEG* in, const char fmt); diff --git a/include/image/utils.h b/include/image/utils.h index 825e661..9201e1e 100644 --- a/include/image/utils.h +++ b/include/image/utils.h @@ -21,6 +21,22 @@ #define SHIFT_16 16 /**< Constant shift of 16-Bits */ #define SHIFT_24 24 /**< Constant shift of 24-Bits */ +#define SUCCESS 0 + +#define FAILURE 1 +#define ERR_BUF_NULL 20 +#define ERR_FILE_NULL 21 +#define ERR_INVALID_SIZE 22 +#define ERR_CREATION_FAIL 23 +#define ERR_IMG_NULL 24 +#define ERR_IMG_NAME_INVALID 25 +#define ERR_JHEADER 26 + +extern const char* error_messages[]; + +#define LOG(msg) printf("LOG: %s\n", msg) +#define LOGERROR(error_code) printf("ERROR: %s\n", error_messages[error_code]) + /** * * @brief Max value for any channel diff --git a/src/filters.c b/src/filters.c index 490733c..8cb8734 100644 --- a/src/filters.c +++ b/src/filters.c @@ -3,6 +3,8 @@ #include #include +#include "image/utils.h" + unsigned int u32_put_alpha(const unsigned int clr, const unsigned char alpha) { @@ -103,10 +105,10 @@ u32_mask(const unsigned int clr, const char keep) return clr & (BYTE_A | BYTE_B); break; default: - return 0; + return FAILURE; break; } - return 0; + return FAILURE; } unsigned int @@ -114,11 +116,8 @@ u32_rotl(const unsigned int clr, const int n) { if (n > 8) { - printf( - "ERROR: %i is greater than 8 results in black " - "pixels, please use values less than 8\n", - n); - exit(10); + LOGERROR(ERR_INVALID_SIZE); + return ERR_INVALID_SIZE; } unsigned int red = DECODE_R(clr); unsigned int green = DECODE_G(clr); @@ -261,13 +260,15 @@ box_blur(const unsigned int* src_buf, const PPM* img, const int radius) unsigned int* first_pass = malloc(img->len * sizeof(unsigned int)); if (!first_pass) { - return 0; + LOGERROR(ERR_BUF_NULL); + return NULL; } unsigned int* dst_buf = malloc(img->len * sizeof(unsigned int)); if (!dst_buf) { free(first_pass); - return 0; + LOGERROR(ERR_BUF_NULL); + return NULL; } for (int y = 0; y < img->height; y++) { diff --git a/src/imgio.c b/src/imgio.c index 248fe9b..f503c89 100644 --- a/src/imgio.c +++ b/src/imgio.c @@ -4,20 +4,21 @@ #include #include +#include "image/utils.h" + unsigned int* ppm_load(const char* file, PPM* m_attr) { - printf("Starting decode...\n"); - unsigned char red; - unsigned char green; - unsigned char blue; + LOG("Decoding"); + unsigned char red, green, blue; char fmt[3]; int max_val; FILE* fptr; fptr = fopen(file, "r"); if (!fptr) { - printf("Invalid file name: %s\n", file); + LOGERROR(ERR_IMG_NAME_INVALID); + LOG(file); return NULL; } fscanf(fptr, "%s", fmt); @@ -29,12 +30,14 @@ ppm_load(const char* file, PPM* m_attr) unsigned char* img_buf = malloc(m_attr->len * 3); if (!img_buf) { + LOGERROR(ERR_BUF_NULL); return NULL; } unsigned int* clr_buf = malloc(m_attr->len * sizeof(unsigned int)); if (!clr_buf) { free(img_buf); + LOGERROR(ERR_BUF_NULL); return NULL; } if (m_attr->fmt == '3') @@ -60,7 +63,7 @@ ppm_load(const char* file, PPM* m_attr) fclose(fptr); free(img_buf); - printf("Decoding done!\n"); + LOG("Decoding Finished"); return clr_buf; } @@ -69,15 +72,16 @@ ppm_save(const unsigned int* buf, const PPM img, char* name) { if (!buf) { - return 10; + LOGERROR(ERR_BUF_NULL); + return ERR_BUF_NULL; } - unsigned char red, green, blue; unsigned char* dst_buf = malloc(img.len * 3); if (!dst_buf) { - return 10; + LOGERROR(ERR_BUF_NULL); + return ERR_BUF_NULL; } - printf("Starting encode...\n"); + LOG("Encoding"); FILE* fptr; if (img.fmt == '3') @@ -93,7 +97,8 @@ ppm_save(const unsigned int* buf, const PPM img, char* name) if (!fptr) { free(dst_buf); - return 10; + LOGERROR(ERR_FILE_NULL); + return ERR_FILE_NULL; } fprintf(fptr, "P%c\n%d %d\n255\n", img.fmt, img.width, img.height); @@ -101,10 +106,8 @@ ppm_save(const unsigned int* buf, const PPM img, char* name) { for (int i = 0; i < img.len; i++) { - red = DECODE_R(buf[i]); - green = DECODE_G(buf[i]); - blue = DECODE_B(buf[i]); - fprintf(fptr, "%d %d %d ", red, green, blue); + fprintf(fptr, "%d %d %d ", DECODE_R(buf[i]), + DECODE_G(buf[i]), DECODE_B(buf[i])); if (i % 7 == 0) { fprintf(fptr, "\n"); @@ -124,20 +127,20 @@ ppm_save(const unsigned int* buf, const PPM img, char* name) } fclose(fptr); free(dst_buf); - printf("Encode Done!\n"); - printf("Image: %s is saved.\n", name); - return 1; + LOG("Encoding Finished"); + return SUCCESS; } unsigned int* jpeg_load(JPEG* m_attr) { - printf("Starting Decode...\n"); + LOG("Decoding"); tjhandle tjdecompress = tj3Init(TJINIT_DECOMPRESS); unsigned char* jpeg_buf = NULL; FILE* infile = fopen(m_attr->name, "rb"); if (!infile) { + LOGERROR(ERR_FILE_NULL); return NULL; } fseek(infile, 0, SEEK_END); @@ -148,26 +151,33 @@ jpeg_load(JPEG* m_attr) fclose(infile); if (tj3DecompressHeader(tjdecompress, jpeg_buf, m_attr->len) < 0) { - printf("Header error: %s\n", tj3GetErrorStr(tjdecompress)); + LOGERROR(ERR_JHEADER); + LOG(tj3GetErrorStr(tjdecompress)); free(jpeg_buf); return NULL; } m_attr->width = tj3Get(tjdecompress, TJPARAM_JPEGWIDTH); m_attr->height = tj3Get(tjdecompress, TJPARAM_JPEGHEIGHT); + m_attr->len = m_attr->width * m_attr->height; unsigned int* pixels = malloc(m_attr->width * m_attr->height * sizeof(unsigned int)); + if (!pixels) + { + LOGERROR(ERR_BUF_NULL); + return NULL; + } tj3Decompress8(tjdecompress, jpeg_buf, m_attr->len, (unsigned char*)pixels, 0, TJPF_BGRA); tj3Destroy(tjdecompress); free(jpeg_buf); - printf("Decode Successful!\n"); + LOG("Decoding Finished"); return pixels; } int jpeg_save(const unsigned int* src_buf, const JPEG* attr, const char* name) { - printf("Starting Decode...\n"); + LOG("Encoding"); tjhandle tjcompress = tj3Init(TJINIT_COMPRESS); unsigned char* dst_buf = NULL; size_t dst_size = 0; @@ -176,27 +186,52 @@ jpeg_save(const unsigned int* src_buf, const JPEG* attr, const char* name) if (tj3Compress8(tjcompress, (unsigned char*)src_buf, attr->width, 0, attr->height, TJPF_BGRA, &dst_buf, &dst_size) < 0) { - printf("TurboJPEG Error: %s\n", tj3GetErrorStr(tjcompress)); + LOGERROR(ERR_JHEADER); + LOG(tj3GetErrorStr(tjcompress)); + return ERR_JHEADER; } FILE* fptr = fopen(name, "wb"); - if (!fptr || dst_buf == NULL || dst_size <= 0) + if (!fptr) { tj3Free(dst_buf); - return 25; + LOGERROR(ERR_FILE_NULL); + return ERR_FILE_NULL; + } + if (dst_buf == NULL) + { + tj3Free(dst_buf); + LOGERROR(ERR_BUF_NULL); + return ERR_BUF_NULL; + } + if (dst_size <= 0) + { + tj3Free(dst_buf); + LOGERROR(ERR_INVALID_SIZE); + return ERR_INVALID_SIZE; } fwrite(dst_buf, 1, dst_size, fptr); fclose(fptr); tj3Destroy(tjcompress); tj3Free(dst_buf); - printf("Encode Successful!\n"); - return 1; + LOG("Encoding Finished"); + return SUCCESS; } void transcode_to_jpeg(PPM* in, JPEG* out) { + if (!in || !out) + { + LOGERROR(ERR_IMG_NULL); + return; + } unsigned int* dst = ppm_load(in->name, in); + if (!dst) + { + LOGERROR(ERR_BUF_NULL); + return; + } out->width = in->width; out->height = in->height; jpeg_save(dst, out, out->name); @@ -204,11 +239,21 @@ transcode_to_jpeg(PPM* in, JPEG* out) } void -transcode_to_ppm(JPEG* input, PPM* out) +transcode_to_ppm(JPEG* in, PPM* out) { - unsigned int* dst = jpeg_load(input); - out->width = input->width; - out->height = input->height; + if (!in || !out) + { + LOGERROR(ERR_IMG_NULL); + return; + } + unsigned int* dst = jpeg_load(in); + if (!dst) + { + LOGERROR(ERR_BUF_NULL); + return; + } + out->width = in->width; + out->height = in->height; out->len = out->width * out->height; ppm_save(dst, *out, out->name); free(dst); @@ -217,6 +262,12 @@ transcode_to_ppm(JPEG* input, PPM* out) PPM inherit_from_jpeg(const JPEG* in, const char fmt) { + PPM img; + if (!in) + { + LOGERROR(ERR_IMG_NULL); + return img; + } PPM image = { .name = in->name, .width = in->width, .height = in->height, @@ -228,6 +279,12 @@ inherit_from_jpeg(const JPEG* in, const char fmt) JPEG inherit_from_ppm(const PPM* in) { + JPEG blank; + if (!in) + { + LOGERROR(ERR_IMG_NULL); + return blank; + } JPEG image = { .name = in->name, .width = in->width, @@ -236,11 +293,3 @@ inherit_from_ppm(const PPM* in) }; return image; } - -/** The Second image gets merged into the first. - * The First image obtains attributes from the second image that were not found. - */ -// PPM -// merge_ppm(const PPM* in_1, const PPM* in_2) { -// if(in) -// } diff --git a/src/main.c b/src/main.c index 8f2afaf..232d25a 100644 --- a/src/main.c +++ b/src/main.c @@ -12,7 +12,7 @@ * Keep in mind any function that creates a new buffer and returns it can * overwrite the old one, however it is lost. SO create a new variable and free * the old one after use. - * */ + */ int main() { @@ -20,19 +20,46 @@ main() // .name = "../MF8jno.jpg", // // }; + // JPEG img_j = { + // .name = "../assets/test_2.jpg", + // }; + // + + // unsigned int* buffer = jpeg_load(&img_j); + // PPM out = inherit_from_jpeg(&img_j, '3'); + // print_attr(&out); + // + // ppm_save(buffer, out, "../assets/test_2.ppm"); + // free(buffer); PPM img = { - .name = "../assets/test.ppm", + .name = "../assets/test_2.ppm", }; + // unsigned int* buf = ppm_load(img.name, &img); + // unsigned int* box = box_blur(buf, &img, 20); + // free(buf); + img.fmt = '3'; unsigned int* buf = ppm_load(img.name, &img); + if (!buf) + { + return ERR_BUF_NULL; + } + unsigned int* blur = box_blur(buf, &img, 20); + free(buf); + if (!blur) + { + return ERR_BUF_NULL; + } for (int i = 0; i < img.len; i++) { - // you need to replace the old value with the new updated value - buf[i] = u32_contrast(buf[i], 9); + blur[i] = u32_rotl(blur[i], 4); } - img.fmt = '3'; - // buf = u32_rotate(buf, &img); - ppm_save(buf, img, "../assets/test_new.ppm"); + ppm_save(blur, img, "../assets/test_2_new.ppm"); + free(blur); + + // // buf = u32_rotate(buf, &img); + // ppm_save(box, img, "../assets/test_new.ppm"); + // free(box); // PPM out_2 = inherit_from_jpeg(&out_1, '6'); // diff --git a/src/transformations.c b/src/transformations.c index d38ede2..be9275d 100644 --- a/src/transformations.c +++ b/src/transformations.c @@ -1,17 +1,22 @@ #include "image/transformations.h" +#include #include +#include "image/utils.h" + unsigned int* ppm_flip_h(const unsigned int* buf, const PPM img) { if (!buf) { + LOGERROR(ERR_BUF_NULL); return NULL; } unsigned int* flip = malloc(img.len * sizeof(unsigned int)); if (!flip) { + LOGERROR(ERR_CREATION_FAIL); return NULL; } int idx = 0; @@ -33,11 +38,13 @@ ppm_flip_v(const unsigned int* buf, const PPM img) { if (!buf) { + LOGERROR(ERR_BUF_NULL); return NULL; } unsigned int* flip = malloc(img.len * sizeof(unsigned int)); if (!flip) { + LOGERROR(ERR_FILE_NULL); return NULL; } @@ -58,13 +65,20 @@ ppm_flip_v(const unsigned int* buf, const PPM img) unsigned int* u32_rotate(const unsigned int* buf, PPM* m_img) { - if (!buf || !m_img) + if (!buf) { + LOGERROR(ERR_BUF_NULL); + return NULL; + } + if (!m_img) + { + LOGERROR(ERR_IMG_NULL); return NULL; } unsigned int* mask = malloc(m_img->len * sizeof(unsigned int)); if (!mask) { + LOGERROR(ERR_BUF_NULL); return NULL; } int old_width = m_img->width; diff --git a/src/utils.c b/src/utils.c index 0ad0d64..267cb46 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1,6 +1,19 @@ #include "image/utils.h" + #include +const char* error_messages[] = { + [ERR_BUF_NULL] = "Buffer NULL", + [ERR_FILE_NULL] = "File NULL", + [ERR_CREATION_FAIL] = "Buffer creation failed", + [ERR_INVALID_SIZE] = "Given size is invalid", + [ERR_IMG_NULL] = "Image NULL", + [ERR_IMG_NAME_INVALID] = "Invalid File Name", + [ERR_JHEADER] = "Header Error:", + +#define ERR_JHEADER 26 +}; + unsigned long u32to_u64(const unsigned int clr) { @@ -23,16 +36,16 @@ u64to_u32(const unsigned long clr, const unsigned long u64_div) (b / u64_div)); } -void -__attribute__((overloadable)) -print_attr(const PPM *src) { - printf("Name: %s\nFMT: %c\nWidth: %i, Height: %i\nLength: %i\n", - src->name, src->fmt, src->width, src->height, src->len); +void __attribute__((overloadable)) +print_attr(const PPM* src) +{ + printf("Name: %s\nFMT: %c\nWidth: %i, Height: %i\nLength: %i\n", + src->name, src->fmt, src->width, src->height, src->len); } -void -__attribute__((overloadable)) -print_attr(const JPEG *src) { - printf("Name: %s\nWidth: %i, Height: %i\nLength: %i\n", - src->name, src->width, src->height, src->len); +void __attribute__((overloadable)) +print_attr(const JPEG* src) +{ + printf("Name: %s\nWidth: %i, Height: %i\nLength: %i\n", src->name, + src->width, src->height, src->len); }