From 2a168f894746f753889a4ee110371a774887e287 Mon Sep 17 00:00:00 2001 From: Andrew Haynes Date: Wed, 9 Sep 2026 16:44:37 -0400 Subject: [PATCH] DOCS: Added docs to imgio and refactored some of the names and code of imgio --- include/image/imgio.h | 53 +++++++++++++++++++++++++---- include/image/utils.h | 12 +++++-- src/imgio.c | 79 ++++++++++++++++++++++++++++++++----------- src/main.c | 49 +++------------------------ src/utils.c | 18 ++++++++-- 5 files changed, 136 insertions(+), 75 deletions(-) diff --git a/include/image/imgio.h b/include/image/imgio.h index 965d293..732def5 100644 --- a/include/image/imgio.h +++ b/include/image/imgio.h @@ -3,27 +3,68 @@ #include "utils.h" +/** + * @brief Open and Fill buffer from .ppm file + * @param [in] file Char pointer use to locate the image to be modified lays. + * @param [in,out] m_attr PPM pointer to store image information + */ unsigned int* -ppm_load(const char* file, PPM* m_attr); +read_ppm(const char* file, PPM* m_attr); +/** + * @brief Open and write buffer to file + * @param [in] buf Information of pixels + * @param [in] img PPM pointer to store image information + * @param [in] char Name/Location for file + */ int -ppm_save(const unsigned int* buf, const PPM img, char* name); +write_ppm(const unsigned int* buf, const PPM img, const char* name); +/** + * @brief Open and Fill buffer from .jpg file + * @details Opens a .jpg file, creates a new buffer and extracts the pixels into + * said buffer as integers. + * @param [in] file Char pointer use to locate the image to be modified lays. + * @param [in,out] m_attr JPEG pointer to store image information + */ unsigned int* -jpeg_load(JPEG* m_attr); +read_jpeg(JPEG* m_attr); +/** + * @brief Open and write buffer to file + * @param [in] buf Information of pixels + * @param [in] attr JPEG pointer to store image information + * @param [in] char Name/Location for file + */ int -jpeg_save(const unsigned int* src_buf, const JPEG* attr, const char* name); +write_jpeg(const unsigned int* src_buf, const JPEG* attr, const char* name); +/** + * @brief Converts PPM to JPEG + * @param [in] in Pointer to PPM container + */ void -transcode_to_jpeg(PPM* in, JPEG* out); +transcode_to_jpeg(PPM* in); +/** + * @brief Converts JPEG to PPM + * @param [in] in Pointer to JPEG container + */ void -transcode_to_ppm(JPEG* in, PPM* out); +transcode_to_ppm(JPEG* in); +/** + * @brief Inherits the attributes from JPEG container + * @param [in] in Pointer to JPEG container + * @param [in] fmt Character for type of PPM image, binary or raw + */ PPM inherit_from_jpeg(const JPEG* in, const char fmt); +/** + * @brief Inherits the attributes from PPM container + * @param [in] in Pointer to PPM container + */ JPEG inherit_from_ppm(const PPM* in); diff --git a/include/image/utils.h b/include/image/utils.h index 9201e1e..e9af703 100644 --- a/include/image/utils.h +++ b/include/image/utils.h @@ -9,6 +9,7 @@ // The u in the BYTE Macros are for unsigned calls so colors are not changed to // signed and the values cut in half +#include #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 */ @@ -21,6 +22,7 @@ #define SHIFT_16 16 /**< Constant shift of 16-Bits */ #define SHIFT_24 24 /**< Constant shift of 24-Bits */ +// These are success and error codes #define SUCCESS 0 #define FAILURE 1 @@ -31,11 +33,14 @@ #define ERR_IMG_NULL 24 #define ERR_IMG_NAME_INVALID 25 #define ERR_JHEADER 26 +#define ERR_MALLOC_NULL 27 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]) +#define LOG(msg) printf("LOG: %s\n", msg) /**< Print log message*/ +#define LOGERROR(error_code) \ + printf("ERROR: %s\n", \ + error_messages[error_code]) /**< Print log error message*/ /** * @@ -167,4 +172,7 @@ print_attr(const PPM* src); void __attribute__((overloadable)) print_attr(const JPEG* src); +size_t +find_extension(const char* n); + #endif diff --git a/src/imgio.c b/src/imgio.c index f503c89..82c2d50 100644 --- a/src/imgio.c +++ b/src/imgio.c @@ -2,12 +2,13 @@ #include #include +#include #include #include "image/utils.h" unsigned int* -ppm_load(const char* file, PPM* m_attr) +read_ppm(const char* file, PPM* m_attr) { LOG("Decoding"); unsigned char red, green, blue; @@ -68,7 +69,7 @@ ppm_load(const char* file, PPM* m_attr) } int -ppm_save(const unsigned int* buf, const PPM img, char* name) +write_ppm(const unsigned int* buf, const PPM img, const char* name) { if (!buf) { @@ -132,7 +133,7 @@ ppm_save(const unsigned int* buf, const PPM img, char* name) } unsigned int* -jpeg_load(JPEG* m_attr) +read_jpeg(JPEG* m_attr) { LOG("Decoding"); tjhandle tjdecompress = tj3Init(TJINIT_DECOMPRESS); @@ -175,7 +176,7 @@ jpeg_load(JPEG* m_attr) } int -jpeg_save(const unsigned int* src_buf, const JPEG* attr, const char* name) +write_jpeg(const unsigned int* src_buf, const JPEG* attr, const char* name) { LOG("Encoding"); tjhandle tjcompress = tj3Init(TJINIT_COMPRESS); @@ -219,44 +220,84 @@ jpeg_save(const unsigned int* src_buf, const JPEG* attr, const char* name) } void -transcode_to_jpeg(PPM* in, JPEG* out) +transcode_to_jpeg(PPM* in) { - if (!in || !out) + size_t length = find_extension(in->name); + char str2[length]; + for (int i = 0; i < length; i++) + { + str2[i] = in->name[i]; + } + char* str3 = ".jpg"; + char* result = malloc(strlen(str2) + strlen(str3) + 1); + if (result != NULL) + { + strcat(result, str2); + strcat(result, str3); + } + else + { + LOGERROR(ERR_MALLOC_NULL); + return; + } + JPEG img; + if (!in) { LOGERROR(ERR_IMG_NULL); return; } - unsigned int* dst = ppm_load(in->name, in); + unsigned int* dst = read_ppm(in->name, in); if (!dst) { LOGERROR(ERR_BUF_NULL); return; } - out->width = in->width; - out->height = in->height; - jpeg_save(dst, out, out->name); + img.width = in->width; + img.height = in->height; + write_jpeg(dst, &img, result); free(dst); + free(result); } void -transcode_to_ppm(JPEG* in, PPM* out) +transcode_to_ppm(JPEG* in) { - if (!in || !out) + size_t length = find_extension(in->name); + char str2[length]; + for (int i = 0; i < length; i++) + { + str2[i] = in->name[i]; + } + char* str3 = ".ppm"; + char* result = malloc(strlen(str2) + strlen(str3) + 1); + if (result != NULL) + { + strcat(result, str2); + strcat(result, str3); + } + else + { + LOGERROR(ERR_MALLOC_NULL); + return; + } + PPM img; + if (!in) { LOGERROR(ERR_IMG_NULL); return; } - unsigned int* dst = jpeg_load(in); + unsigned int* dst = read_jpeg(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); + img.width = in->width; + img.height = in->height; + img.len = img.width * img.height; + write_ppm(dst, img, result); free(dst); + free(result); } PPM @@ -268,8 +309,7 @@ inherit_from_jpeg(const JPEG* in, const char fmt) LOGERROR(ERR_IMG_NULL); return img; } - PPM image = { .name = in->name, - .width = in->width, + PPM image = { .width = in->width, .height = in->height, .len = in->len, .fmt = fmt }; @@ -286,7 +326,6 @@ inherit_from_ppm(const PPM* in) return blank; } JPEG image = { - .name = in->name, .width = in->width, .height = in->height, .len = in->len, diff --git a/src/main.c b/src/main.c index fe741fa..7ce3aa8 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,7 @@ +#include #include #include +#include #include "image/filters.h" #include "image/transformations.h" @@ -16,52 +18,9 @@ int main() { - // Init base image containers PPM img; - JPEG jimg; - - // Add a file location of image to modify - img.name = "../assets/test_2.ppm"; - - // Load the PPM image - unsigned int* buf = ppm_load(img.name, &img); - - // Check for null image load. In case image doesnt exist or fails to - // load - if (!buf) - { - LOGERROR(ERR_BUF_NULL); - return ERR_BUF_NULL; - } - // Blur image and save to new pointer - unsigned int* blur = box_blur(buf, &img, 20); - - // Free old buffer. MUST DO THIS. Maybe not immediately but before - // ending or possibly leaking. Also it stays in heap and a large image - // can take a lot of memory so better to clear anyways. - free(buf); - // Check for null image load. In case image doesnt exist or fails to - // load - if (!blur) - { - LOGERROR(ERR_BUF_NULL); - return ERR_BUF_NULL; - } - - // Loop image and apply filter to each pixel. - for (int i = 0; i < img.len; i++) - { - blur[i] = u32_rotl(blur[i], 4); - } - - // Take the attributes from ppm image so jpeg file can be saved - jimg = inherit_from_ppm(&img); - - // Saves jpeg to location specified - jpeg_save(blur, &jimg, "../assets/test_2_new.jpg"); - - // Make sure to free any buffer still active - free(blur); + img.name = "../assets/IMG_1649_new.ppm"; + transcode_to_jpeg(&img); return 0; } diff --git a/src/utils.c b/src/utils.c index 267cb46..5d4c227 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1,6 +1,7 @@ #include "image/utils.h" #include +#include const char* error_messages[] = { [ERR_BUF_NULL] = "Buffer NULL", @@ -10,8 +11,7 @@ const char* error_messages[] = { [ERR_IMG_NULL] = "Image NULL", [ERR_IMG_NAME_INVALID] = "Invalid File Name", [ERR_JHEADER] = "Header Error:", - -#define ERR_JHEADER 26 + [ERR_MALLOC_NULL] = "Malloc Failed to allocate", }; unsigned long @@ -49,3 +49,17 @@ print_attr(const JPEG* src) printf("Name: %s\nWidth: %i, Height: %i\nLength: %i\n", src->name, src->width, src->height, src->len); } + +size_t +find_extension(const char* n) +{ + size_t length = strlen(n); + for (int i = length; i >= 0; i--) + { + if (n[i] == '.') + { + return i; + } + } + return FAILURE; +}