Added identicon support (closes #2)
the build failed Details

This commit is contained in:
tastytea 2018-11-27 09:59:02 +01:00
parent 3db99fbd03
commit 645554e226
Signed by: tastytea
GPG Key ID: CFC39497F1B26E07
5 changed files with 80 additions and 5 deletions

View File

@ -1,6 +1,6 @@
cmake_minimum_required (VERSION 3.2)
project(libravatarserv
VERSION 0.4.3
VERSION 0.5.0
LANGUAGES CXX
)

View File

@ -12,7 +12,7 @@ images tied to email or OpenID addresses.
* MD5 hashes
* SHA256 hashes
* Variable image size (`s` or `size`)
* Default actions (`d` or `default`): 404, URL, mp/mm
* Default actions (`d` or `default`): 404, URL, mp/mm, identicon
The default behaviour for unknown users is to return a 404 error. If a default
image is put in the avatar directory, that is returned instead. The default

View File

@ -15,6 +15,8 @@
*/
#include <iostream>
#include <sstream>
#include <array>
#include "libravatarserv.hpp"
using std::cout;
@ -69,3 +71,61 @@ void image::write(Image &image)
cout.flush(); // We need to flush before we use /dev/stdout directly.
image.image.write("/dev/stdout");
}
Image image::identicon(const string &digest)
{
const string sha256 = hash::sha256(digest);
Magick::Image img(Magick::Geometry(4, 4), Magick::Color("white"));
// The 16 named colors specified in HTML 14.01 minus white, silver and gray.
const std::array<Magick::Color, 13> colors =
{
Magick::Color("black"),
Magick::Color("red"),
Magick::Color("maroon"),
Magick::Color("yellow"),
Magick::Color("olive"),
Magick::Color("lime"),
Magick::Color("green"),
Magick::Color("aqua"),
Magick::Color("teal"),
Magick::Color("blue"),
Magick::Color("navy"),
Magick::Color("fuchsia"),
Magick::Color("purple")
};
try
{
std::uint64_t random = 0xffff;
for (uint64_t chunk = 0; chunk < 4; ++chunk)
{
std::stringstream ss;
ss << std::hex << sha256.substr(chunk * 16, 16);
random = (random / 2) + (static_cast<std::uint64_t>(ss.get()) / 2);
}
Magick::Color dotcolor = colors[random % 13];
for (uint8_t row = 0; row < 4; ++row)
{
for (uint8_t column = 0; column < 4; ++column)
{
std::stringstream ss;
uint16_t px;
ss << std::hex << sha256.substr(row * 4 + column, 4);
ss >> px;
if (px > 0x8000)
{
img.pixelColor(column, row, dotcolor);
}
}
}
}
catch (const std::exception &e)
{
cerr << "Error: " << e.what() << endl;
return { 5, img };
}
img.magick("png");
return { 0, img };
}

View File

@ -71,8 +71,8 @@ int main()
avatar.fallback.substr(0, 2) == "mm")
{
// MD5 hash of 'mp'
image = image::get("1f2dfa567dcf95833eddf7aec167fec7",
avatar.size);
image = image::get("1f2dfa567dcf95833eddf7aec167fec7",
avatar.size);
if (image.error == 0)
{
image::write(image);
@ -80,7 +80,21 @@ int main()
else
{
cout << "Status: 404 Not Found\n\n";
cerr << "Mystery person not found.\n";
cerr << "Error: Mystery person not found.\n";
}
}
else if (avatar.fallback.substr(0, 9) == "identicon")
{
image = image::identicon(avatar.digest);
if (image.error == 0)
{
image.image.scale(Magick::Geometry(avatar.size, avatar.size));
image::write(image);
}
else
{
cout << "Status: 404 Not Found\n\n";
cerr << "Error: Couldn't generate identicon.\n";
}
}
else

View File

@ -75,6 +75,7 @@ namespace image // image.cpp
const Image get(const string &digest, const uint16_t size);
void write(Image &image);
Image identicon(const string &digest);
}
#endif // LIBRAVATARSERV_HPP