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:
M | photomosaics.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;
}