qTox  Version: nightly | Commit: bc751c8e1cac455f9690654fcfe0f560d2d7dfdd
identicon.cpp
Go to the documentation of this file.
1 /*
2  Copyright © 2019 by The qTox Project Contributors
3 
4  This file is part of qTox, a Qt-based graphical interface for Tox.
5 
6  qTox is libre software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  qTox is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with qTox. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "identicon.h"
21 #include "src/core/toxpk.h"
22 
23 #include <cassert>
24 
25 #include <QColor>
26 #include <QCryptographicHash>
27 #include <QDebug>
28 #include <QImage>
29 
30 // The following constants change the appearance of the identicon
31 // they have been choosen by trying to make the output look nice.
63 Identicon::Identicon(const QByteArray& data)
64 {
65  static_assert(Identicon::COLORS == 2, "Only two colors are implemented");
66  // hash with sha256
67  QByteArray hash = QCryptographicHash::hash(data, QCryptographicHash::Sha256);
68  for (int colorIndex = 0; colorIndex < COLORS; ++colorIndex) {
69  const QByteArray hashPart = hash.right(IDENTICON_COLOR_BYTES);
70  hash.truncate(hash.length() - IDENTICON_COLOR_BYTES);
71 
72  const qreal hue = bytesToColor(hashPart);
73  // change offset when COLORS != 2
74  const qreal lig = static_cast<qreal>(colorIndex) / COLORS + 0.3;
75  const qreal sat = 0.5;
76  colors[colorIndex].setHslF(hue, sat, lig);
77  }
78 
79  const uint8_t* const hashBytes = reinterpret_cast<const uint8_t*>(hash.constData());
80  // compute the block colors from the hash
81  for (int row = 0; row < IDENTICON_ROWS; ++row) {
82  for (int col = 0; col < ACTIVE_COLS; ++col) {
83  const int hashIdx = row * ACTIVE_COLS + col;
84  const uint8_t colorIndex = hashBytes[hashIdx] % COLORS;
85  identiconColors[row][col] = colorIndex;
86  }
87  }
88 }
89 
95 float Identicon::bytesToColor(QByteArray bytes)
96 {
97  static_assert(IDENTICON_COLOR_BYTES <= 8, "IDENTICON_COLOR max value is 8");
98  const uint8_t* const bytesChr = reinterpret_cast<const uint8_t*>(bytes.constData());
99  assert(bytes.length() == IDENTICON_COLOR_BYTES);
100 
101  // get foreground color
102  uint64_t hue = bytesChr[0];
103 
104  // convert the last bytes to an uint
105  for (int i = 1; i < IDENTICON_COLOR_BYTES; ++i) {
106  hue = hue << 8;
107  hue += bytesChr[i];
108  }
109 
110  // normalize to 0.0 ... 1.0
111  return (static_cast<float>(hue))
112  / (static_cast<float>(((static_cast<uint64_t>(1)) << (8 * IDENTICON_COLOR_BYTES)) - 1));
113 }
114 
121 QImage Identicon::toImage(int scaleFactor)
122 {
123  if (scaleFactor < 1) {
124  qDebug() << "Can't scale with values <1, clamping to 1";
125  scaleFactor = 1;
126  }
127 
128  scaleFactor *= IDENTICON_ROWS;
129 
130  QImage pixels(IDENTICON_ROWS, IDENTICON_ROWS, QImage::Format_RGB888);
131 
132  for (int row = 0; row < IDENTICON_ROWS; ++row) {
133  for (int col = 0; col < IDENTICON_ROWS; ++col) {
134  // mirror on vertical axis
135  const int columnIdx = abs((col * 2 - (IDENTICON_ROWS - 1)) / 2);
136  const int colorIdx = identiconColors[row][columnIdx];
137  pixels.setPixel(col, row, colors[colorIdx].rgb());
138  }
139  }
140 
141  // scale up without smoothing to make it look sharp
142  return pixels.scaled(scaleFactor, scaleFactor, Qt::IgnoreAspectRatio, Qt::FastTransformation);
143 }
Identicon::colors
QColor colors[COLORS]
Definition: identicon.h:43
Identicon::bytesToColor
static float bytesToColor(QByteArray bytes)
Converts a series of IDENTICON_COLOR_BYTES bytes to a value in the range 0.0..1.0.
Definition: identicon.cpp:95
Identicon::Identicon
Identicon(const QByteArray &data)
Creates an Identicon, that visualizes a hash in graphical form.
Definition: identicon.cpp:63
toxpk.h
Identicon::IDENTICON_ROWS
static constexpr int IDENTICON_ROWS
Definition: identicon.h:33
Identicon::COLORS
static constexpr int COLORS
Definition: identicon.h:37
Identicon::toImage
QImage toImage(int scaleFactor=1)
Writes the Identicon to a QImage.
Definition: identicon.cpp:121
Identicon::identiconColors
uint8_t identiconColors[IDENTICON_ROWS][ACTIVE_COLS]
Definition: identicon.h:42
Identicon::ACTIVE_COLS
static constexpr int ACTIVE_COLS
Definition: identicon.h:38
Identicon::IDENTICON_COLOR_BYTES
static constexpr int IDENTICON_COLOR_BYTES
Definition: identicon.h:34
identicon.h