#include "image/imgio.h" #include #include #include unsigned int* ppm_load(const char* file, PPM* m_attr) { printf("Starting decode...\n"); unsigned char red; unsigned char green; unsigned char blue; char fmt[3]; int max_val; FILE* fptr; fptr = fopen(file, "r"); if (!fptr) { printf("Invalid file name: %s\n", file); return NULL; } fscanf(fptr, "%s", fmt); m_attr->fmt = fmt[1]; fscanf(fptr, "%d %d", &m_attr->width, &m_attr->height); m_attr->len = m_attr->width * m_attr->height; fscanf(fptr, "%d", &max_val); fgetc(fptr); unsigned char* img_buf = malloc(m_attr->len * 3); if (!img_buf) { return NULL; } unsigned int* clr_buf = malloc(m_attr->len * sizeof(unsigned int)); if (!clr_buf) { free(img_buf); return NULL; } if (m_attr->fmt == '3') { for (int i = 0; i < m_attr->len; i++) { fscanf(fptr, "%hhu %hhu %hhu", &red, &green, &blue); clr_buf[i] = ENCODE_RGB(red, green, blue); } } else if (m_attr->fmt == '6') { fread(img_buf, 3, m_attr->len, fptr); for (int i = 0; i < m_attr->len; i++) { red = img_buf[i * 3]; green = img_buf[i * 3 + 1]; blue = img_buf[i * 3 + 2]; clr_buf[i] = ENCODE_RGB(red, green, blue); } } fclose(fptr); free(img_buf); printf("Decoding done!\n"); return clr_buf; } int ppm_save(const unsigned int* buf, const PPM img, char* name) { if (!buf) { return 10; } unsigned char red, green, blue; unsigned char* dst_buf = malloc(img.len * 3); if (!dst_buf) { return 10; } printf("Starting encode...\n"); FILE* fptr; if (img.fmt == '3') { fptr = fopen(name, "w"); } if (img.fmt == '6') { fptr = fopen(name, "wb"); } if (!fptr) { free(dst_buf); return 10; } fprintf(fptr, "P%c\n%d %d\n255\n", img.fmt, img.width, img.height); if (img.fmt == '3') { 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); if (i % 7 == 0) { fprintf(fptr, "\n"); } } } if (img.fmt == '6') { for (int i = 0; i < img.len; i++) { dst_buf[i * 3] = DECODE_R(buf[i]); dst_buf[i * 3 + 1] = DECODE_G(buf[i]); dst_buf[i * 3 + 2] = DECODE_B(buf[i]); } fwrite(dst_buf, 1, img.len * 3, fptr); } fclose(fptr); free(dst_buf); printf("Encode Done!\n"); printf("Image: %s is saved.\n", name); return 1; } unsigned int* jpeg_load(JPEG* m_attr) { printf("Starting Decode...\n"); tjhandle tjdecompress = tj3Init(TJINIT_DECOMPRESS); unsigned char* jpeg_buf = NULL; FILE* infile = fopen(m_attr->name, "rb"); if (!infile) { return NULL; } fseek(infile, 0, SEEK_END); m_attr->len = ftell(infile); fseek(infile, 0, SEEK_SET); jpeg_buf = (unsigned char*)malloc(m_attr->len); fread(jpeg_buf, 1, m_attr->len, infile); fclose(infile); if (tj3DecompressHeader(tjdecompress, jpeg_buf, m_attr->len) < 0) { printf("Header error: %s\n", tj3GetErrorStr(tjdecompress)); free(jpeg_buf); return NULL; } m_attr->width = tj3Get(tjdecompress, TJPARAM_JPEGWIDTH); m_attr->height = tj3Get(tjdecompress, TJPARAM_JPEGHEIGHT); unsigned int* pixels = malloc(m_attr->width * m_attr->height * sizeof(unsigned int)); tj3Decompress8(tjdecompress, jpeg_buf, m_attr->len, (unsigned char*)pixels, 0, TJPF_BGRA); tj3Destroy(tjdecompress); free(jpeg_buf); printf("Decode Successful!\n"); return pixels; } int jpeg_save(const unsigned int* src_buf, const JPEG* attr, const char* name) { printf("Starting Decode...\n"); tjhandle tjcompress = tj3Init(TJINIT_COMPRESS); unsigned char* dst_buf = NULL; size_t dst_size = 0; tj3Set(tjcompress, TJPARAM_QUALITY, 80); tj3Set(tjcompress, TJPARAM_SUBSAMP, TJSAMP_420); 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)); } FILE* fptr = fopen(name, "wb"); if (!fptr || dst_buf == NULL || dst_size <= 0) { tj3Free(dst_buf); return 25; } fwrite(dst_buf, 1, dst_size, fptr); fclose(fptr); tj3Destroy(tjcompress); tj3Free(dst_buf); printf("Encode Successful!\n"); return 1; } void transcode_to_jpeg(PPM* in, JPEG* out) { unsigned int* dst = ppm_load(in->name, in); out->width = in->width; out->height = in->height; jpeg_save(dst, out, out->name); free(dst); } void transcode_to_ppm(JPEG* input, PPM* out) { unsigned int* dst = jpeg_load(input); out->width = input->width; out->height = input->height; out->len = out->width * out->height; ppm_save(dst, *out, out->name); free(dst); } PPM inherit_from_jpeg(const JPEG* in, const char fmt) { PPM image = { .name = in->name, .width = in->width, .height = in->height, .len = in->len, .fmt = fmt }; return image; } JPEG inherit_from_ppm(const PPM* in) { JPEG image = { .name = in->name, .width = in->width, .height = in->height, .len = in->len, }; 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) // }