]> Git repositories of Nishi - repoview.git/commitdiff
implemented avatar
authorNishi <nishi@nishi.boats>
Thu, 22 Aug 2024 02:50:46 +0000 (02:50 +0000)
committerNishi <nishi@nishi.boats>
Thu, 22 Aug 2024 02:50:46 +0000 (02:50 +0000)
git-svn-id: file:///raid/svn-personal/repoview/trunk@34 7e8b2a19-8934-dd40-8cb3-db22cdd5a80f

CGI/avatar.c
CGI/rv_avatar.h

index facfd4d386d87ba78198b157f9cf8854525535cd..09201a3ca9cb75e57494d5bb7ea6f8a4196ca8f9 100644 (file)
 
 #include "rv_avatar.h"
 
+#include "rv_md5.h"
+
 #include <stdio.h>
 #include <stdlib.h>
 
 #include <png.h>
 
-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);
 }
index 573aa4f065fe3eef2a2e8f71b6d33f2f91f391fc..1f561644d946ae6be70bed1400a7aeb7e0150994 100644 (file)
@@ -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