From bf79feedcedc755be3364e59be5720bd4cd108cf Mon Sep 17 00:00:00 2001 From: Nishi Date: Thu, 22 Aug 2024 02:50:46 +0000 Subject: [PATCH] implemented avatar git-svn-id: file:///raid/svn-personal/repoview/trunk@34 7e8b2a19-8934-dd40-8cb3-db22cdd5a80f --- CGI/avatar.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++- CGI/rv_avatar.h | 2 +- 2 files changed, 141 insertions(+), 2 deletions(-) diff --git a/CGI/avatar.c b/CGI/avatar.c index facfd4d..09201a3 100644 --- a/CGI/avatar.c +++ b/CGI/avatar.c @@ -2,14 +2,115 @@ #include "rv_avatar.h" +#include "rv_md5.h" + #include #include #include -void rv_avatar_generate(const char* name) { +int hex_to_num(const char* hex, int len) { + int i; + int num = 0; + for(i = 0; i < len; i++) { + num = num << 4; + if(hex[i] >= '0' && hex[i] <= '9') { + num |= hex[i] - '0'; + } else if(hex[i] >= 'a' && hex[i] <= 'f') { + num |= hex[i] - 'a' + 10; + } else if(hex[i] >= 'A' && hex[i] <= 'F') { + num |= hex[i] - 'A' + 10; + } + } + return num; +} + +char* generate_ident(const char* username, int* r, int* g, int* b) { + char* ident = malloc(25); + char* hash = rv_md5(username); + + double h = hex_to_num(hash + 32 - 2 - 2 - 3, 3); + double s = hex_to_num(hash + 32 - 2 - 2, 2); + double v = hex_to_num(hash + 32 - 2, 2); + + h = h * 360 / 4095; + s = 65 - s * 20 / 255; + v = 75 - v * 20 / 255; + + double max; + double min; + + if(v < 50) { + max = 2.55 * (v + v * (s / 100)); + min = 2.55 * (v - v * (s / 100)); + } else if(v >= 50) { + max = 2.55 * (v + (100 - v) * (s / 100)); + min = 2.55 * (v - (100 - v) * (s / 100)); + } + + if(0 <= h && h < 60) { + *r = max; + *g = (h / 60) * (max - min) + min; + *b = min; + } else if(60 <= h && h < 120) { + *r = ((120 - h) / 60) * (max - min) + min; + *g = max; + *b = min; + } else if(120 <= h && h < 128) { + *r = min; + *g = max; + *b = ((h - 120) / 60) * (max - min) + min; + } else if(180 <= h && h < 240) { + *r = min; + *g = ((240 - h) / 60) * (max - min) + min; + *b = max; + } else if(240 <= h && h < 300) { + *r = ((h - 240) / 60) * (max - min) + min; + *g = min; + *b = max; + } else if(300 <= h && h < 360) { + *r = max; + *g = min; + *b = ((360 - h) / 60) * (max - min) + min; + } + + int y, x; + for(x = 0; x < 3; x++) { + for(y = 0; y < 5; y++) { + int i; + char c = hash[y + x * 5]; + int px = 0; + if(c >= '0' && c <= '9') { + px = c - '0'; + } else if(c >= 'a' && c <= 'f') { + px = c - 'a' + 10; + } + if((px % 2) == 0) { + px = 1; + } else { + px = 0; + } + for(i = 0; i < 2; i++) { + int incr = -1; + if(i == 1) incr = 1; + ident[y * 5 + x * incr + 2] = px; + } + } + } + + free(hash); + return ident; +} + +void rv_avatar_generate(const char* name, const char* username) { FILE* f = fopen(name, "wb"); + int pxr; + int pxg; + int pxb; + + char* ident = generate_ident(username, &pxr, &pxg, &pxb); + if(f == NULL) return; png_structp pngp = NULL; @@ -23,9 +124,47 @@ void rv_avatar_generate(const char* name) { goto closeall; } + png_init_io(pngp, f); + + png_set_IHDR(pngp, infop, 255, 255, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + + png_text title; + title.compression = PNG_TEXT_COMPRESSION_NONE; + title.key = "Title"; + title.text = "Generated by RepoView"; + png_set_text(pngp, infop, &title, 1); + + png_write_info(pngp, infop); + + row = (png_bytep)malloc(3 * 255 * sizeof(png_byte)); + int x, y; + for(y = 0; y < 255; y++) { + for(x = 0; x < 255; x++) { + int px = x / 51; + int py = y / 51; + int colr = 0; + int colg = 0; + int colb = 0; + if(ident[px + py * 5]) { + colr = pxr; + colg = pxg; + colb = pxb; + } else { + colr = colg = colb = 240; + } + row[x * 3 + 0] = colr; + row[x * 3 + 1] = colg; + row[x * 3 + 2] = colb; + } + png_write_row(pngp, row); + } + + png_write_end(pngp, NULL); + closeall: fclose(f); if(infop != NULL) png_free_data(pngp, infop, PNG_FREE_ALL, -1); if(pngp != NULL) png_destroy_write_struct(&pngp, (png_infopp)NULL); if(row != NULL) free(row); + free(ident); } diff --git a/CGI/rv_avatar.h b/CGI/rv_avatar.h index 573aa4f..1f56164 100644 --- a/CGI/rv_avatar.h +++ b/CGI/rv_avatar.h @@ -3,6 +3,6 @@ #ifndef __RV_AVATAR_H__ #define __RV_AVATAR_H__ -void rv_avatar_generate(const char* name); +void rv_avatar_generate(const char* name, const char* username); #endif -- 2.45.2