Refactored
All checks were successful
the build was successful

This commit is contained in:
tastytea 2018-12-26 04:36:58 +01:00
parent 80b2a59c9f
commit 024fd4eb79
Signed by: tastytea
GPG Key ID: CFC39497F1B26E07
4 changed files with 112 additions and 81 deletions

View File

@ -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})

View File

@ -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;
}

View File

@ -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]);
}

View File

@ -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.