photomosaics

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit 21af64dcf85e772297f9860af8efe16de166f38d
parent 94c9cf42466549865991c7b5560e3081241357a5
Author: Wilson Gheen <wilson@wilsonrgheen.com>
Date:   Mon,  2 Jan 2023 08:53:55 -0600

WIP: Add the beginning of some caching

Diffstat:
Mphotomosaics.c | 73+++++++++++++++++++++++++++++++++++++++++++------------------------------
1 file changed, 43 insertions(+), 30 deletions(-)

diff --git a/photomosaics.c b/photomosaics.c @@ -14,7 +14,9 @@ typedef struct { unsigned int r, g, b; } Pixel; +static const char *CACHE_FILENAME = "/home/wilson/.cache/photomosaics/avgs"; static FILE *cache = NULL; +static long cache_size = 0; static bool parse_float(char *str, float *out) { char *endptr; @@ -49,17 +51,42 @@ static bool parse_ulong(char *str, unsigned long *out) { return strncmp(str, endptr, strlen(str)); } -static bool cache_put(int nargs, ...) { - if(!cache) cache = fopen("~/.cache/photomosaics/avgs"); - if(!cache) return false; - char *buf; - int ind = 0, chars_written; - va_list vl; - va_start(vl, nargs); - for(int i=0; i < nargs-1; i++, ind += chars_written) - chars_written = sprintf(buf[ind], "%s\t", va_arg(vl, char *)); - sprintf(buf[ind], "%s\n", va_arg(vl, char *)); - va_end(vl); +static bool cache_put_pixel(char *key, Pixel value) { + if(cache_size < 0) + return false; + if(!cache) { + cache = fopen(CACHE_FILENAME, "a+"); + if(!cache) { + fprintf(stderr, "WARN: Couldn't open cache file %s. Please ensure the directory exists. Will stop attempting to cache for the remainder of execution.", CACHE_FILENAME); + cache_size = -1; + return false; + } + fseek(cache, 0, SEEK_END); + cache_size = ftell(cache); + } + rewind(cache); + char filename[150]; + for(int i=0, fn_ind=0; i < cache_size;) { + // TODO handle this better in case EOF is an error + if((filename[fn_ind]=fgetc(cache)) == EOF) break; + i++; + if(filename[fn_ind] == '\t') { + filename[fn_ind] = 0; + if(!strncmp(filename, key, fn_ind)) { + //Already exists in cache + //TODO check timestamp + return true; + } + fn_ind = 0; + for(char tmp=fgetc(cache); i < cache_size && tmp != '\n'; i++) { + if(tmp == EOF) break; + tmp = fgetc(cache); + } + } + else fn_ind++; + } + fseek(cache, 0, SEEK_END); + fprintf(cache, "%s\t%02x%02x%02x\n", key, value.r, value.g, value.b); return true; } @@ -167,8 +194,7 @@ static bool get_closest_pixel(Pixel p, const size_t width, const size_t height, if(!avgs_list) return false; #define MY_AVGS_SIZE 5931 char buf[MY_AVGS_SIZE]; - size_t z = fread(buf, 1, MY_AVGS_SIZE, avgs_list); -/* printf("Read %zu bytes from my_avgs.\n", z);*/ + fread(buf, 1, MY_AVGS_SIZE, avgs_list); fclose(avgs_list); char *filename = strtok(buf, " "); char *closest_file = malloc(150); @@ -189,7 +215,7 @@ static bool get_closest_pixel(Pixel p, const size_t width, const size_t height, if(new_distance < distance_of_closest) { distance_of_closest = new_distance; closest_file[0] = 0; - strncat(closest_file, filename, 150); + strncat(closest_file, filename, 149); } } while((filename=strtok(NULL, " ")) && filename < buf + MY_AVGS_SIZE); @@ -210,7 +236,7 @@ static bool get_closest_pixel(Pixel p, const size_t width, const size_t height, return true; } -static unsigned char *get_img_with_closest_avg(Pixel p, const size_t width, const size_t height, ExceptionInfo *exception) { +static unsigned char *get_img_with_closest_avg(const size_t width, const size_t height, ExceptionInfo *exception) { Pixel img_avgs[105]; FILE *f = popen("find $(find ~/pics -type d | grep -vE 'redacted|not_real') -maxdepth 1 -type f -print0", "r"); #define IMG_LIST_SIZE 5091 @@ -220,31 +246,18 @@ static unsigned char *get_img_with_closest_avg(Pixel p, const size_t width, cons for(int c=0, k=0; c < IMG_LIST_SIZE; k++) { ImageInfo *image_info = CloneImageInfo((ImageInfo *)NULL); image_info->filename[0] = 0; - strncat(image_info->filename, &buf[c], IMG_LIST_SIZE - c); + strncat(image_info->filename, &buf[c], IMG_LIST_SIZE - c - 1); Image *src_img = ReadImage(image_info, exception); Image *src_img_r = resize_image_to(src_img, width, height, exception); unsigned char *pixels = malloc(width * height * 3); ExportImagePixels(src_img_r, 0, 0, width, height, "RGB", CharPixel, pixels, exception); img_avgs[k] = get_avg_color(pixels, width, 0, 0, width, height); + cache_put_pixel(&buf[c], img_avgs[k]); c += strnlen(&buf[c], IMG_LIST_SIZE - c) + 1; DestroyImage(src_img); DestroyImage(src_img_r); DestroyImageInfo(image_info); } -/* FILE *avgs_list = fopen("al", "wb");*/ -/* if(!avgs_list) exit(1);*/ -/* for(int i=0; i < 105; i++) {*/ -/* char str[4] = {img_avgs[i].r, img_avgs[i].g, img_avgs[i].b,};*/ -/* fwrite(str, 1, 3, avgs_list);*/ -/* }*/ -/* fclose(avgs_list);*/ - FILE *my_avgs = fopen("my_avgs", "w"); - if(!my_avgs) exit(1); - for(int i=0, c=0; i < 105 && c < IMG_LIST_SIZE; i++) { - fprintf(my_avgs, "%s: %02x%02x%02x\n", &buf[c], img_avgs[i].r, img_avgs[i].g, img_avgs[i].b); - c += strnlen(&buf[c], IMG_LIST_SIZE - c) + 1; - } - fclose(my_avgs); return NULL; }