parent
80b2a59c9f
commit
024fd4eb79
|
@ -1,17 +1,12 @@
|
|||
cmake_minimum_required (VERSION 3.2)
|
||||
project(identiconpp
|
||||
VERSION 0.0.0
|
||||
VERSION 0.1.0
|
||||
LANGUAGES CXX
|
||||
)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(MAGICPP REQUIRED Magick++)
|
||||
pkg_check_modules(LIBCRYPTOPP libcryptopp)
|
||||
if(NOT LIBCRYPTOPP_FOUND)
|
||||
# Debian stretch package installs libcrypto++.pc
|
||||
pkg_check_modules(LIBCRYPTOPP REQUIRED libcrypto++)
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
@ -28,18 +23,15 @@ endif()
|
|||
include_directories(${PROJECT_SOURCE_DIR}/src)
|
||||
include_directories(${PROJECT_BINARY_DIR})
|
||||
include_directories(${MAGICPP_INCLUDE_DIRS})
|
||||
include_directories(${LIBCRYPTOPP_INCLUDE_DIRS})
|
||||
|
||||
link_directories(${MAGICPP_LIBRARY_DIRS})
|
||||
link_directories(${LIBCRYPTOPP_LIBRARY_DIRS})
|
||||
|
||||
file(GLOB sources src/*.cpp)
|
||||
add_library(${CMAKE_PROJECT_NAME} SHARED "${sources}")
|
||||
set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION ${${CMAKE_PROJECT_NAME}_VERSION_MAJOR})
|
||||
target_link_libraries(${CMAKE_PROJECT_NAME}
|
||||
"${MAGICPP_LDFLAGS} ${LIBCRYPTOPP_LDFLAGS}")
|
||||
target_link_libraries(${CMAKE_PROJECT_NAME} "${MAGICPP_LDFLAGS}")
|
||||
|
||||
add_executable(example "example.cpp")
|
||||
target_link_libraries(example ${CMAKE_PROJECT_NAME})
|
||||
|
|
52
example.cpp
52
example.cpp
|
@ -21,25 +21,49 @@ int main(int argc, char *argv[])
|
|||
if (algorithm == "simple")
|
||||
{
|
||||
cout << "You selected the \"simple\" algorithm.\n";
|
||||
Identiconpp identicon(13, 10, Identiconpp::identicon_type::simple,
|
||||
"ffffff88",
|
||||
{
|
||||
"000000ff",
|
||||
"ff0000ff",
|
||||
"ffff00ff",
|
||||
"00ff00ff",
|
||||
"00ffffff",
|
||||
"0000ffff"
|
||||
});
|
||||
|
||||
Magick::Image img;
|
||||
img = identicon.generate("55502f40dc8b7c769880b10874abc9d0");
|
||||
img.write("identicon_example_simple1.png");
|
||||
img = identicon.generate
|
||||
(
|
||||
"973dfe463ec85785f5f95af5ba3906eedb2d931c24e69824a89ea65dba4e813b",
|
||||
500
|
||||
);
|
||||
img.write("identicon_example_simple2.png");
|
||||
}
|
||||
else if (algorithm == "libravatar")
|
||||
{
|
||||
cout << "You selected the \"libravatar\" algorithm.\n";
|
||||
Identiconpp identicon(10, 10, Identiconpp::identicon_type::libravatar,
|
||||
"ffffffff",
|
||||
{
|
||||
"000000ff",
|
||||
"ff0000ff",
|
||||
"ffff00ff",
|
||||
"00ff00ff",
|
||||
"00ffffff",
|
||||
"0000ffff"
|
||||
});
|
||||
|
||||
Magick::Image img;
|
||||
img = identicon.generate("55502f40dc8b7c769880b10874abc9d0");
|
||||
img.write("identicon_example_libravatar.png");
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "The algorithm \"" << algorithm << "\" is not known.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
Identiconpp identicon(5, 5, 0xffffffff,
|
||||
{
|
||||
0x000000ff,
|
||||
0xff0000ff,
|
||||
0xffff00ff,
|
||||
0x00ff00ff,
|
||||
0x00ffffff,
|
||||
0x0000ffff
|
||||
});
|
||||
Identiconpp::Image image;
|
||||
image = identicon.generate("2b7dd5def082abfca556d9e8feb1fc29", Identiconpp::identicon_type::simple);
|
||||
cout.flush(); // We need to flush before we use /dev/stdout directly.
|
||||
image.data.write("/dev/stdout");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -23,22 +23,41 @@
|
|||
#include "debug.hpp"
|
||||
|
||||
Identiconpp::Identiconpp(const uint8_t rows, const uint8_t columns,
|
||||
const uint32_t background,
|
||||
const vector<uint32_t> &foreground)
|
||||
identicon_type type,
|
||||
const string background,
|
||||
const vector<string> &foreground)
|
||||
: _rows(rows)
|
||||
, _columns(columns)
|
||||
, _type(type)
|
||||
, _background(background)
|
||||
, _foreground(foreground)
|
||||
{
|
||||
if (background.length() != 8)
|
||||
{
|
||||
throw std::invalid_argument
|
||||
(
|
||||
"The background color must consist of exactly 8 digits."
|
||||
);
|
||||
}
|
||||
|
||||
for (const string &color : foreground)
|
||||
if (color.length() != 8)
|
||||
{
|
||||
throw std::invalid_argument
|
||||
(
|
||||
"The foreground colors must consist of exactly 8 digits."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Identiconpp::Image Identiconpp::generate(const string &digest,
|
||||
identicon_type type,
|
||||
const uint16_t width,
|
||||
const uint16_t height)
|
||||
Magick::Image Identiconpp::generate(const string &digest, const uint16_t width)
|
||||
{
|
||||
check_entropy(digest, type);
|
||||
switch (type)
|
||||
check_entropy(digest, _type);
|
||||
const uint16_t height = width / _columns * _rows;
|
||||
ttdebug << "width: " << std::to_string(width)
|
||||
<< ", height: " << std::to_string(height) << "\n";
|
||||
|
||||
switch (_type)
|
||||
{
|
||||
case identicon_type::simple:
|
||||
{
|
||||
|
@ -52,15 +71,12 @@ Identiconpp::Image Identiconpp::generate(const string &digest,
|
|||
}
|
||||
}
|
||||
|
||||
Identiconpp::Image Identiconpp::generate_simple(const string &digest,
|
||||
const uint16_t width,
|
||||
const uint16_t height)
|
||||
Magick::Image Identiconpp::generate_simple(const string &digest,
|
||||
const uint16_t width,
|
||||
const uint16_t height)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::hex << _background;
|
||||
const string bgcolor = "#" + ss.str();
|
||||
Magick::Image img(Magick::Geometry(_columns, _rows),
|
||||
Magick::Color(bgcolor));
|
||||
Magick::Color("#" + _background));
|
||||
uint8_t used_columns = _columns / 2 + _columns % 2;
|
||||
Magick::Color dotcolor = get_color(used_columns * _rows + 1, digest);
|
||||
|
||||
|
@ -70,10 +86,10 @@ Identiconpp::Image Identiconpp::generate_simple(const string &digest,
|
|||
{
|
||||
if (get_bit(row * used_columns + column, digest))
|
||||
{
|
||||
ttdebug << "col=" << std::to_string(column)
|
||||
<< ", row=" << std::to_string(row) << '\n';
|
||||
ttdebug << "col=" << std::to_string(used_columns - 1 + column)
|
||||
<< ", row=" << std::to_string(_rows - 1 - row) << '\n';
|
||||
// ttdebug << "col=" << std::to_string(column)
|
||||
// << ", row=" << std::to_string(row) << '\n';
|
||||
// ttdebug << "col=" << std::to_string(used_columns - 1 + column)
|
||||
// << ", row=" << std::to_string(_rows - 1 - row) << '\n';
|
||||
img.pixelColor(column, row, dotcolor);
|
||||
img.pixelColor(_columns - 1 - column, row, dotcolor);
|
||||
}
|
||||
|
@ -82,20 +98,22 @@ Identiconpp::Image Identiconpp::generate_simple(const string &digest,
|
|||
|
||||
img.scale(Magick::Geometry(width, height));
|
||||
img.magick("png");
|
||||
return { 0, img };
|
||||
return img;
|
||||
}
|
||||
|
||||
Identiconpp::Image Identiconpp::generate_libravatar(const string &digest,
|
||||
const uint16_t width,
|
||||
const uint16_t height)
|
||||
Magick::Image Identiconpp::generate_libravatar(const string &digest,
|
||||
const uint16_t width,
|
||||
const uint16_t height)
|
||||
{
|
||||
return { 1, Magick::Image() };
|
||||
Magick::Image img(Magick::Geometry(_columns, _rows),
|
||||
Magick::Color("#" + _background));
|
||||
return img;
|
||||
}
|
||||
|
||||
void Identiconpp::check_entropy(const string &digest, identicon_type type)
|
||||
{
|
||||
uint8_t entropy_provided;
|
||||
uint8_t entropy_required;
|
||||
uint16_t entropy_provided;
|
||||
uint16_t entropy_required;
|
||||
switch (type)
|
||||
{
|
||||
case identicon_type::simple:
|
||||
|
@ -167,10 +185,12 @@ Magick::Color Identiconpp::get_color(const uint16_t firstbit,
|
|||
// Get rid of excess bits
|
||||
bits = bits & (1 << colorbits) - 1;
|
||||
|
||||
if (bits > _foreground.size())
|
||||
{
|
||||
bits -= _foreground.size();
|
||||
}
|
||||
|
||||
// Lookup und set color
|
||||
ss.str(string());
|
||||
ss.clear();
|
||||
ss << std::hex << std::setw(8) << std::setfill('0') << _foreground[bits - 1];
|
||||
ttdebug << "Color: #" << ss.str() << '\n';
|
||||
return Magick::Color("#" + ss.str());
|
||||
ttdebug << "Color: #" << _foreground[bits - 1] << '\n';
|
||||
return Magick::Color("#" + _foreground[bits - 1]);
|
||||
}
|
||||
|
|
|
@ -29,20 +29,12 @@ using std::vector;
|
|||
/*!
|
||||
* @brief Base class for identiconpp.
|
||||
*
|
||||
* Use this class for all your identicons.
|
||||
* Use this class for all your identicons. Exceptions will be thrown on
|
||||
* error.
|
||||
*/
|
||||
class Identiconpp
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* @brief Return type for images.
|
||||
*/
|
||||
struct Image
|
||||
{
|
||||
uint8_t error;
|
||||
Magick::Image data;
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief List of identicon types
|
||||
*
|
||||
|
@ -59,35 +51,36 @@ public:
|
|||
* @brief Initialises an instance of Identiconpp.
|
||||
*
|
||||
* The instance can be used for creating identicons with differing
|
||||
* image formats and sizes.
|
||||
* image formats and sizes. The colors must consist of exactly 8
|
||||
* digits.
|
||||
*
|
||||
* @param rows Number of rows
|
||||
* @param columns Number of columns
|
||||
* @param type The type of identicon
|
||||
* @param background Background color, hexadecimal, rrggbbaa
|
||||
* @param foreground vector of foreground colors
|
||||
*/
|
||||
explicit Identiconpp(const uint8_t rows, const uint8_t columns,
|
||||
const uint32_t background = 0xffffffff,
|
||||
const vector<uint32_t> &foreground = { 0x000000ff } );
|
||||
identicon_type type,
|
||||
const string background = "ffffffff",
|
||||
const vector<string> &foreground = { "000000ff" } );
|
||||
|
||||
/*!
|
||||
* @brief Generates identicon from digest.
|
||||
*
|
||||
* @param digest The pre-computed digest
|
||||
* @param type The type of identicon
|
||||
* @param width The width of the image
|
||||
* @param height The height of the image
|
||||
*
|
||||
* @return 0 and an image on success, 1 and an empty image on error.
|
||||
* @return The image
|
||||
*/
|
||||
Image generate(const string &digest, identicon_type type,
|
||||
const uint16_t width = 100, const uint16_t height = 100);
|
||||
Magick::Image generate(const string &digest, const uint16_t width = 100);
|
||||
|
||||
private:
|
||||
const uint8_t _rows;
|
||||
const uint8_t _columns;
|
||||
const uint32_t _background;
|
||||
const vector<uint32_t> _foreground;
|
||||
const identicon_type _type;
|
||||
const string _background;
|
||||
const vector<string> _foreground;
|
||||
|
||||
/*!
|
||||
* @brief Generate simple identicon.
|
||||
|
@ -96,10 +89,11 @@ private:
|
|||
* @param width The width of the image
|
||||
* @param height The height of the image
|
||||
*
|
||||
* @return 0 and an image on success, 1 and an empty image on error.
|
||||
* @return The image
|
||||
*/
|
||||
Image generate_simple(const string &digest,
|
||||
const uint16_t width, const uint16_t height);
|
||||
Magick::Image generate_simple(const string &digest,
|
||||
const uint16_t width,
|
||||
const uint16_t height);
|
||||
|
||||
/*!
|
||||
* @brief Generate libravatar-style / sigil identicon.
|
||||
|
@ -108,10 +102,11 @@ private:
|
|||
* @param width The width of the image
|
||||
* @param height The height of the image
|
||||
*
|
||||
* @return 0 and an image on success, 1 and an empty image on error.
|
||||
* @return The image
|
||||
*/
|
||||
Image generate_libravatar(const string &digest,
|
||||
const uint16_t width, const uint16_t height);
|
||||
Magick::Image generate_libravatar(const string &digest,
|
||||
const uint16_t width,
|
||||
const uint16_t height);
|
||||
|
||||
/*!
|
||||
* @brief Check if the digest contains enough entropy.
|
||||
|
|
Loading…
Reference in New Issue
Block a user