/* This file is part of libravatarserv. * Copyright © 2022 tastytea * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "image.hpp" #include "types.hpp" #include #include #include #include #include #include #include #include #include #include namespace libravatarserv::image { Magick::Image get(const fs::path &filepath, const size_t size) { Magick::Image img; img.read(filepath); img.resize(Magick::Geometry(size, size)); return img; } Magick::Image generate_identicon(const request_t &req) { const auto padwidth{[&req]() -> std::uint8_t { if (req.size < 60) { return 0; } return static_cast(std::max(req.size / 10, 10)); }()}; Identiconpp identicon(5, 5, Identiconpp::algorithm::sigil, "fefefeff", { // The same colors ivatar uses. "2d4fffff", // Blue "feb42cff", // Yellow "e279eaff", // Bright pink "1eb3fdff", // Cyan "E84D41ff", // Red "31CB73ff", // Green "8D45AAff" // Dark pink }, {padwidth, padwidth}); Magick::Image img{ identicon.generate(req.hash, static_cast(req.size))}; img.magick("PNG"); return img; } void write(Magick::Image &img, const std::optional magick_force) { std::string magick{magick_force.value_or(img.magick())}; std::transform(magick.begin(), magick.end(), magick.begin(), ::tolower); const auto quality{[&img, &magick]() -> size_t { if (img.quality() != 0) { return img.quality(); // same as source } if (magick == "png") { return 100; // highest compression } if (magick == "webp") { if (img.magick() == "WEBP" || img.magick() == "PNG" || img.magick() == "GIF" || img.magick() == "SVG") { return 100; // lossless } } return 0; // default }()}; img.magick(magick); img.quality(quality); Magick::Blob buffer; img.write(&buffer); std::cout << "Content-Type: image/" << magick << '\n'; std::cout << "Content-Length: " << buffer.length() << "\n\n"; std::cout.write(static_cast(buffer.data()), static_cast(buffer.length())); } } // namespace libravatarserv::image