#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;
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);
}