LIBEUNOMIA
読み取り中…
検索中…
一致する文字列を見つけられません
pict_indexing.h
[詳解]
1/*
2 * Copyright 2003-2021 oZ/acy (名賀月晃嗣)
3 * Redistribution and use in source and binary forms,
4 * with or without modification,
5 * are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 */
27/*
28 * @author oZ/acy (名賀月晃嗣)
29 * @brief 畫像のインデックス化に用ゐる函數の實裝
30 *
31 * @date 2021.4.25 LIBPOLYMNIAからLIBEUNOMIAへの移植に伴ひヘッダファイルに摘出
32 */
33#ifndef INCLUDE_GUARD_EUNOMIA_PICTURE_INDEXING_IMPLEMENT_H
34#define INCLUDE_GUARD_EUNOMIA_PICTURE_INDEXING_IMPLEMENT_H
35
36#include <algorithm>
37#include <memory>
38#include <vector>
39#include <climits>
40#include "picture_indexed.h"
41
42
43namespace eunomia::implement_
44{
46
50{
51public:
52 std::uint8_t min;
53 std::uint8_t max;
54
56 // x が [min, max] に存在するなら、bits[x >> 5] の x & 0x1f bit が 1
57 std::uint32_t bits[8];
58
59 std::uint32_t sum;
60
61public:
63 : min(0), max(255), bits{0, 0, 0, 0, 0, 0, 0, 0}, sum(0)
64 {}
65
67 bool isWithin(std::uint8_t v) const noexcept
68 { return v >= min && v <= max; }
69
71 void clear()
72 {
73 std::fill_n(bits, 8, 0);
74 sum = 0;
75 }
76
78 void add(std::uint8_t v) noexcept
79 {
80 sum += v;
81 bits[v >> 5] |= (std::uint32_t)1 << (v & 0x1f);
82 }
83
87 int cutoff()
88 {
89 // bits[]の内容に從つて最小値minを切り上げる
90 for (int j = min >> 5; j < 8; j++)
91 if (bits[j]) {
92 int i, f;
93 // 1であるビットまで讀み飛ばす
94 for (i = 0, f = 1; i < 32 && !(bits[j] & f); ++i, f <<= 1)
95 ;
96
97 i += j << 5;
98 if (i <= max)
99 min = i;
100
101 break;
102 }
103
104 // bits[]の内容に從つて最大値maxを切り下げる
105 for (int j = max >> 5; j >= 0; j--)
106 if (bits[j]) {
107 int i, f;
108 // 1であるビットまで讀み飛ばす
109 for (i = 31, f = 1 << 31; i >= 0 && !(bits[j] & f); --i, f >>= 1)
110 ;
111
112 i += j << 5;
113 if (i >= min)
114 max = i;
115
116 break;
117 }
118
119 // 區間の幅を返す
120 return max - min + 1;
121 }
122};
123
124
129{
130public:
131 unsigned count;
135
136public:
138
145 bool isWithin(std::uint8_t r, std::uint8_t g, std::uint8_t b) const noexcept
146 {
147 return
148 r >= red.min && r <= red.max
149 && g >= green.min && g <= green.max
150 && b >= blue.min && b <= blue.max;
151 }
152
154 void clear()
155 {
156 red.clear();
157 green.clear();
158 blue.clear();
159 count = 0;
160 }
161
165 void add(std::uint8_t r, std::uint8_t g, std::uint8_t b) noexcept
166 {
167 red.add(r);
168 green.add(g);
169 blue.add(b);
170 ++count;
171 }
172
173
179 {
180 int rw = red.cutoff();
181 int gw = green.cutoff();
182 int bw = blue.cutoff();
183
184 if (count == 0)
185 count = 1;
186
187 neu = *this;
188
189 if (gw >= bw && gw >= rw) {
190 green.max = green.sum / count;
191 neu.green.min = green.sum / count + 1;
192 }
193 else if(rw >= bw && rw >= gw) {
194 red.max = red.sum / count;
195 neu.red.min = red.sum / count + 1;
196 }
197 else {
198 blue.max = blue.sum / count;
199 neu.blue.min = blue.sum / count + 1;
200 }
201 }
202};
203
204
213template<class C_>
214inline
216{
217 PixelRange_ range[256];
218
219 int current_range = 1;
220
221 for (int bits = 0; bits <= 8; ++bits) {
222 for (int i = 0; i < current_range; i++)
223 range[i].clear();
224
225 for (int y = 0; y < image.height(); y++) {
226 for (int x = 0; x < image.width(); x++) {
227 std::uint8_t r = image.pixel(x, y).red;
228 std::uint8_t g = image.pixel(x, y).green;
229 std::uint8_t b = image.pixel(x, y).blue;
230
231 // r, g, bが屬するrangeを求めて、その分布情報を更新する。
232 for (int i = 0; i < current_range; i++) {
233 if (range[i].isWithin(r, g, b)) {
234 range[i].add(r, g, b);
235 break;
236 }
237 }
238 }
239 }
240
241 if (bits == 8)
242 break;
243
244 int stop = current_range;
245 for (int i = 0; i < stop; i++)
246 range[i].divide(range[current_range++]);
247 }
248
249 for (int i = 0; i < 256; i++) {
250 unsigned c = range[i].count == 0 ? 1u : range[i].count;
251 palette[i].red = range[i].red.sum / c;
252 palette[i].green = range[i].green.sum / c;
253 palette[i].blue = range[i].blue.sum / c;
254 }
255}
256
257
258
259
264{
265private:
266 static constexpr int NPALETTE_ = 256;
267 static constexpr int SAMPLE_MAX_ = NPALETTE_ - 1;
268 static constexpr int NCLASS_ = SAMPLE_MAX_ * 3 + 1;
269
270 // POW2_[n] = n * n
271 static constexpr unsigned long POW2_[NPALETTE_]
272 =
273 {
274 0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225,
275 256, 289, 324, 361, 400, 441, 484, 529, 576, 625, 676, 729,
276 784, 841, 900, 961, 1024, 1089, 1156, 1225, 1296, 1369, 1444, 1521,
277 1600, 1681, 1764, 1849, 1936, 2025, 2116, 2209, 2304, 2401, 2500, 2601,
278 2704, 2809, 2916, 3025, 3136, 3249, 3364, 3481, 3600, 3721, 3844, 3969,
279 4096, 4225, 4356, 4489, 4624, 4761, 4900, 5041, 5184, 5329, 5476, 5625,
280 5776, 5929, 6084, 6241, 6400, 6561, 6724, 6889, 7056, 7225, 7396, 7569,
281 7744, 7921, 8100, 8281, 8464, 8649, 8836, 9025, 9216, 9409, 9604, 9801,
282 10000, 10201, 10404, 10609, 10816, 11025, 11236, 11449, 11664, 11881,
283 12100, 12321, 12544, 12769, 12996, 13225, 13456, 13689, 13924, 14161,
284 14400, 14641, 14884, 15129, 15376, 15625, 15876, 16129, 16384, 16641,
285 16900, 17161, 17424, 17689, 17956, 18225, 18496, 18769, 19044, 19321,
286 19600, 19881, 20164, 20449, 20736, 21025, 21316, 21609, 21904, 22201,
287 22500, 22801, 23104, 23409, 23716, 24025, 24336, 24649, 24964, 25281,
288 25600, 25921, 26244, 26569, 26896, 27225, 27556, 27889, 28224, 28561,
289 28900, 29241, 29584, 29929, 30276, 30625, 30976, 31329, 31684, 32041,
290 32400, 32761, 33124, 33489, 33856, 34225, 34596, 34969, 35344, 35721,
291 36100, 36481, 36864, 37249, 37636, 38025, 38416, 38809, 39204, 39601,
292 40000, 40401, 40804, 41209, 41616, 42025, 42436, 42849, 43264, 43681,
293 44100, 44521, 44944, 45369, 45796, 46225, 46656, 47089, 47524, 47961,
294 48400, 48841, 49284, 49729, 50176, 50625, 51076, 51529, 51984, 52441,
295 52900, 53361, 53824, 54289, 54756, 55225, 55696, 56169, 56644, 57121,
296 57600, 58081, 58564, 59049, 59536, 60025, 60516, 61009, 61504, 62001,
297 62500, 63001, 63504, 64009, 64516, 65025,
298 };
299
300
302 template<class C1_, class C2_>
303 static unsigned long distance_(const C1_& c1, const C2_& c2) noexcept
304 {
305 return
306 POW2_[std::abs(c1.red - c2.red)]
307 + POW2_[std::abs(c1.green - c2.green)]
308 + POW2_[std::abs(c1.blue - c2.blue)];
309 }
310
311
312 // SUMDIFF_[i]: RGBの總和の差がiである2つのRGB値の最小距離
313 static constexpr unsigned long SUMDIFF_[NCLASS_]
314 =
315 {
316 0, 0, 1, 3, 5, 8, 12, 16, 21, 27, 33, 40, 48, 56, 65, 75, 85, 96, 108, 120,
317 133, 147, 161, 176, 192, 208, 225, 243, 261, 280, 300, 320, 341, 363, 385,
318 408, 432, 456, 481, 507, 533, 560, 588, 616, 645, 675, 705, 736, 768, 800,
319 833, 867, 901, 936, 972, 1008, 1045, 1083, 1121, 1160, 1200, 1240, 1281,
320 1323, 1365, 1408, 1452, 1496, 1541, 1587, 1633, 1680, 1728, 1776, 1825,
321 1875, 1925, 1976, 2028, 2080, 2133, 2187, 2241, 2296, 2352, 2408, 2465,
322 2523, 2581, 2640, 2700, 2760, 2821, 2883, 2945, 3008, 3072, 3136, 3201,
323 3267, 3333, 3400, 3468, 3536, 3605, 3675, 3745, 3816, 3888, 3960, 4033,
324 4107, 4181, 4256, 4332, 4408, 4485, 4563, 4641, 4720, 4800, 4880, 4961,
325 5043, 5125, 5208, 5292, 5376, 5461, 5547, 5633, 5720, 5808, 5896, 5985,
326 6075, 6165, 6256, 6348, 6440, 6533, 6627, 6721, 6816, 6912, 7008, 7105,
327 7203, 7301, 7400, 7500, 7600, 7701, 7803, 7905, 8008, 8112, 8216, 8321,
328 8427, 8533, 8640, 8748, 8856, 8965, 9075, 9185, 9296, 9408, 9520, 9633,
329 9747, 9861, 9976, 10092, 10208, 10325, 10443, 10561, 10680, 10800, 10920,
330 11041, 11163, 11285, 11408, 11532, 11656, 11781, 11907, 12033, 12160, 12288,
331 12416, 12545, 12675, 12805, 12936, 13068, 13200, 13333, 13467, 13601, 13736,
332 13872, 14008, 14145, 14283, 14421, 14560, 14700, 14840, 14981, 15123, 15265,
333 15408, 15552, 15696, 15841, 15987, 16133, 16280, 16428, 16576, 16725, 16875,
334 17025, 17176, 17328, 17480, 17633, 17787, 17941, 18096, 18252, 18408, 18565,
335 18723, 18881, 19040, 19200, 19360, 19521, 19683, 19845, 20008, 20172, 20336,
336 20501, 20667, 20833, 21000, 21168, 21336, 21505, 21675, 21845, 22016, 22188,
337 22360, 22533, 22707, 22881, 23056, 23232, 23408, 23585, 23763, 23941, 24120,
338 24300, 24480, 24661, 24843, 25025, 25208, 25392, 25576, 25761, 25947, 26133,
339 26320, 26508, 26696, 26885, 27075, 27265, 27456, 27648, 27840, 28033, 28227,
340 28421, 28616, 28812, 29008, 29205, 29403, 29601, 29800, 30000, 30200, 30401,
341 30603, 30805, 31008, 31212, 31416, 31621, 31827, 32033, 32240, 32448, 32656,
342 32865, 33075, 33285, 33496, 33708, 33920, 34133, 34347, 34561, 34776, 34992,
343 35208, 35425, 35643, 35861, 36080, 36300, 36520, 36741, 36963, 37185, 37408,
344 37632, 37856, 38081, 38307, 38533, 38760, 38988, 39216, 39445, 39675, 39905,
345 40136, 40368, 40600, 40833, 41067, 41301, 41536, 41772, 42008, 42245, 42483,
346 42721, 42960, 43200, 43440, 43681, 43923, 44165, 44408, 44652, 44896, 45141,
347 45387, 45633, 45880, 46128, 46376, 46625, 46875, 47125, 47376, 47628, 47880,
348 48133, 48387, 48641, 48896, 49152, 49408, 49665, 49923, 50181, 50440, 50700,
349 50960, 51221, 51483, 51745, 52008, 52272, 52536, 52801, 53067, 53333, 53600,
350 53868, 54136, 54405, 54675, 54945, 55216, 55488, 55760, 56033, 56307, 56581,
351 56856, 57132, 57408, 57685, 57963, 58241, 58520, 58800, 59080, 59361, 59643,
352 59925, 60208, 60492, 60776, 61061, 61347, 61633, 61920, 62208, 62496, 62785,
353 63075, 63365, 63656, 63948, 64240, 64533, 64827, 65121, 65416, 65712, 66008,
354 66305, 66603, 66901, 67200, 67500, 67800, 68101, 68403, 68705, 69008, 69312,
355 69616, 69921, 70227, 70533, 70840, 71148, 71456, 71765, 72075, 72385, 72696,
356 73008, 73320, 73633, 73947, 74261, 74576, 74892, 75208, 75525, 75843, 76161,
357 76480, 76800, 77120, 77441, 77763, 78085, 78408, 78732, 79056, 79381, 79707,
358 80033, 80360, 80688, 81016, 81345, 81675, 82005, 82336, 82668, 83000, 83333,
359 83667, 84001, 84336, 84672, 85008, 85345, 85683, 86021, 86360, 86700, 87040,
360 87381, 87723, 88065, 88408, 88752, 89096, 89441, 89787, 90133, 90480, 90828,
361 91176, 91525, 91875, 92225, 92576, 92928, 93280, 93633, 93987, 94341, 94696,
362 95052, 95408, 95765, 96123, 96481, 96840, 97200, 97560, 97921, 98283, 98645,
363 99008, 99372, 99736, 100101, 100467, 100833, 101200, 101568, 101936, 102305,
364 102675, 103045, 103416, 103788, 104160, 104533, 104907, 105281, 105656,
365 106032, 106408, 106785, 107163, 107541, 107920, 108300, 108680, 109061,
366 109443, 109825, 110208, 110592, 110976, 111361, 111747, 112133, 112520,
367 112908, 113296, 113685, 114075, 114465, 114856, 115248, 115640, 116033,
368 116427, 116821, 117216, 117612, 118008, 118405, 118803, 119201, 119600,
369 120000, 120400, 120801, 121203, 121605, 122008, 122412, 122816, 123221,
370 123627, 124033, 124440, 124848, 125256, 125665, 126075, 126485, 126896,
371 127308, 127720, 128133, 128547, 128961, 129376, 129792, 130208, 130625,
372 131043, 131461, 131880, 132300, 132720, 133141, 133563, 133985, 134408,
373 134832, 135256, 135681, 136107, 136533, 136960, 137388, 137816, 138245,
374 138675, 139105, 139536, 139968, 140400, 140833, 141267, 141701, 142136,
375 142572, 143008, 143445, 143883, 144321, 144760, 145200, 145640, 146081,
376 146523, 146965, 147408, 147852, 148296, 148741, 149187, 149633, 150080,
377 150528, 150976, 151425, 151875, 152325, 152776, 153228, 153680, 154133,
378 154587, 155041, 155496, 155952, 156408, 156865, 157323, 157781, 158240,
379 158700, 159160, 159621, 160083, 160545, 161008, 161472, 161936, 162401,
380 162867, 163333, 163800, 164268, 164736, 165205, 165675, 166145, 166616,
381 167088, 167560, 168033, 168507, 168981, 169456, 169932, 170408, 170885,
382 171363, 171841, 172320, 172800, 173280, 173761, 174243, 174725, 175208,
383 175692, 176176, 176661, 177147, 177633, 178120, 178608, 179096, 179585,
384 180075, 180565, 181056, 181548, 182040, 182533, 183027, 183521, 184016,
385 184512, 185008, 185505, 186003, 186501, 187000, 187500, 188000, 188501,
386 189003, 189505, 190008, 190512, 191016, 191521, 192027, 192533, 193040,
387 193548, 194056, 194565, 195075
388 };
389
390
391 // RGB成分の和を同じくするパレットにすいて片方リンクを張る。
392 // index_[k]
393 // RGBの和がkであるリンクの先頭のパレット番號
394 // -1なら成分の和がkであるパレットは存在しない
395 // next_[i]
396 // パレットiとリンクを同じくする次のパレットの番號
397 // -1ならパレットiはリンク終點
398 int next_[NPALETTE_];
399 int index_[NCLASS_];
400
401public:
402 // パレット探索リンクを構築する
403 explicit PaletteFinder_(const RgbColour palette[]) noexcept
404 {
405 std::fill_n(index_, NCLASS_, -1);
406 for (int i = 0; i < NPALETTE_; ++i) {
407 int k = palette[i].red + palette[i].green + palette[i].blue;
408 next_[i] = index_[k];
409 index_[k] = i;
410 }
411 }
412
413 // colorに最も近いパレットを求める
414 template<class C_>
415 std::uint8_t
416 findNearest(const RgbColour palette[], const C_& color) const noexcept
417 {
418 // nearest: 今までに見附かつてゐる最小距離のパレットの番號 0で初期化
419 // mindiff: palette[min]とcolorの距離の二乘 最大値で初期化
420 std::uint8_t nearest = 0;
421 unsigned long mindiff = ULONG_MAX;
422
423 // colorのRGB成分の和
424 int base = color.red + color.green + color.blue;
425
426 // 探索對象を
427 // colorとRGBの總和の差が小さいところから大きいところに擴げながら調べる
428 for (int absval = 0; absval < NCLASS_; absval++) {
429
430 // 今のところの最近パレット(nearest)との距離(mindiff)よりも
431 // これから調べる對象の距離(の最小値: SUMDIFF_として與へられてゐる)の方が
432 // 大きい場合は打ち切る
433 if (mindiff < SUMDIFF_[absval])
434 break;
435
436 // RGBの總和が color より absval だけ大きいパレットを調べて廻る
437 int p = (base + absval < NCLASS_) ? index_[base + absval] : -1;
438 while (p >= 0 && p < NPALETTE_) {
439
440 // diffはcolorとpalette[p]の距離の二乘
441 unsigned long diff = distance_(color, palette[p]);
442
443 if (diff == 0)
444 return p; // 距離0なら文句なしに終了
445 else if (diff < mindiff) {
446 // 最近パレットと距離の二乘を更新
447 nearest = p;
448 mindiff = diff;
449 }
450 p = next_[p]; // リンクの次に遷る
451 }
452
453 // RGBの總和が col より absval だけ小さいパレットを調べて廻る
454 p = (base - absval >= 0) ? index_[base - absval] : -1;
455 while (p >= 0 && p < NPALETTE_) {
456
457 // diffはcolorとpalette[p]の距離の二乘
458 unsigned long diff = distance_(color, palette[p]);
459
460 if (diff == 0)
461 return p; // 距離0なら文句なしに終了
462 else if (diff < mindiff) {
463 // 最近パレットと距離の二乘を更新
464 nearest = p;
465 mindiff = diff;
466 }
467 p = next_[p]; // リンクの次に遷る
468 }
469 }
470 return nearest; // 最終的な最近パレット番號を返す
471 }
472};
473
474
475
476
486template<class C_>
487inline
488void
490 const ImageBuffer<C_>& src,
492 const PaletteFinder_& pf)
493{
494 constexpr int PTNW = 5; // パターン配列の幅
495 constexpr int PTNH = 3; // パターン配列の高さ
496 constexpr int DAREA = 2; // 分散する畫素の範圍
497
498 constexpr int ERRPTN[PTNW * PTNH] // 分散パターン
499 = {0, 0, 0, 7, 5, 3, 5, 7, 5, 3, 1, 3, 5, 3, 1};
500
501 int sumPtn = 0;
502 for (int i = 0; i < PTNW * PTNH; i++)
503 sumPtn += ERRPTN[i];
504
505 // バッファの確保と初期化
506 int mx = src.width() + DAREA * 2;
507 int sum = mx * PTNH;
508
509 auto rerr = std::make_unique<int[]>(sum);
510 auto gerr = std::make_unique<int[]>(sum);
511 auto berr = std::make_unique<int[]>(sum);
512 std::fill_n(rerr.get(), sum, 0);
513 std::fill_n(gerr.get(), sum, 0);
514 std::fill_n(berr.get(), sum, 0);
515
516 for (int y = 0; y < src.height(); y++) {
517 for (int x = 0; x < src.width(); x++) {
518
519 const C_& color = src.pixel(x, y);
520
521 int adr = x + DAREA;
522 int rr = color.red + rerr[adr] / sumPtn;
523 int gg = color.green + gerr[adr] / sumPtn;
524 int bb = color.blue + berr[adr] / sumPtn;
525
526 int r2 = std::clamp(rr, 0, 255);
527 int g2 = std::clamp(gg, 0, 255);
528 int b2 = std::clamp(bb, 0, 255);
529
530 std::uint8_t best
531 = pf.findNearest(dst.paletteBuffer(), RgbColour(r2, g2, b2));
532
533 int re = rr - dst.palette(best).red;
534 int ge = gg - dst.palette(best).green;
535 int be = bb - dst.palette(best).blue;
536
537
538 // 誤差分散
539 adr -= DAREA;
540 for (int iy = 0; iy < PTNH; ++iy, adr += mx) {
541 for (int ix = 0; ix < PTNW; ++ix) {
542 rerr[adr + ix] += re * ERRPTN[ix + iy * PTNW];
543 gerr[adr + ix] += ge * ERRPTN[ix + iy * PTNW];
544 berr[adr + ix] += be * ERRPTN[ix + iy * PTNW];
545 }
546 }
547
548 dst.pixel(x, y) = best;
549 }
550
551 // バッファのずらし處理
552 for (int i = 0; i < mx; ++i) {
553 for (int j = 0; j < PTNH - 1; ++j) {
554 rerr[i + j * mx] = rerr[i + (j + 1) * mx];
555 gerr[i + j * mx] = gerr[i + (j + 1) * mx];
556 berr[i + j * mx] = berr[i + (j + 1) * mx];
557 }
558 rerr[i + (PTNH - 1) * mx] = 0;
559 gerr[i + (PTNH - 1) * mx] = 0;
560 berr[i + (PTNH - 1) * mx] = 0;
561 }
562 }
563}
564
565
569template<class C_>
570inline
571void
573 const ImageBuffer<C_>& src,
575 const PaletteFinder_& pf)
576{
577 for (int y = 0; y < src.height(); ++y) {
578 for (int x = 0; x < src.width(); ++x) {
579 std::uint8_t best
580 = pf.findNearest(dst.paletteBuffer(), src.pixel(x, y));
581 dst.pixel(x, y) = best;
582 }
583 }
584}
585
586
587}// end of namespace eunomia::implement_
588
589
590
591
592#endif // INCLUDE_GUARD_EUNOMIA_PICTURE_INDEXING_IMPLEMENT_H
畫像バッファ基底クラステンプレート
Definition imagebuffer.h:84
int width() const noexcept
Definition imagebuffer.h:114
C_ & pixel(int x, int y) noexcept
畫素(x, y)の參照
Definition imagebuffer.h:140
int height() const noexcept
高さ
Definition imagebuffer.h:116
RGB24bit256インデックスの畫像バッファ
Definition picture_indexed.h:58
RGB24bit色情報クラス
Definition colour.h:54
std::uint8_t green
緑要素
Definition colour.h:57
std::uint8_t red
赤要素
Definition colour.h:56
std::uint8_t blue
青要素
Definition colour.h:58
色要素の範圍情報
Definition pict_indexing.h:50
std::uint32_t sum
範圍内の色要素値の總計
Definition pict_indexing.h:59
std::uint8_t max
Definition pict_indexing.h:53
std::uint8_t min
Definition pict_indexing.h:52
void clear()
分布情報の削除
Definition pict_indexing.h:71
ColourChannelRange_() noexcept
Definition pict_indexing.h:62
int cutoff()
範圍情報の切り詰め
Definition pict_indexing.h:87
void add(std::uint8_t v) noexcept
色要素値の加算
Definition pict_indexing.h:78
bool isWithin(std::uint8_t v) const noexcept
範圍内か否かの確認
Definition pict_indexing.h:67
std::uint32_t bits[8]
色要素値の分布を表すビットフィールド
Definition pict_indexing.h:57
パレット選擇用クラス
Definition pict_indexing.h:264
std::uint8_t findNearest(const RgbColour palette[], const C_ &color) const noexcept
Definition pict_indexing.h:416
PaletteFinder_(const RgbColour palette[]) noexcept
Definition pict_indexing.h:403
メディアンカットで用ゐるヒストグラムの範圍情報
Definition pict_indexing.h:129
ColourChannelRange_ blue
青要素の範圍
Definition pict_indexing.h:134
void clear()
分布情報の削除
Definition pict_indexing.h:154
ColourChannelRange_ red
赤要素の範圍
Definition pict_indexing.h:132
ColourChannelRange_ green
緑要素の範圍
Definition pict_indexing.h:133
unsigned count
範圍内の畫素數
Definition pict_indexing.h:131
void add(std::uint8_t r, std::uint8_t g, std::uint8_t b) noexcept
分布情報の追加
Definition pict_indexing.h:165
void divide(PixelRange_ &neu)
クラスタ分割
Definition pict_indexing.h:178
PixelRange_() noexcept
Definition pict_indexing.h:137
bool isWithin(std::uint8_t r, std::uint8_t g, std::uint8_t b) const noexcept
範圍内か否かの確認
Definition pict_indexing.h:145
Definition ibuf_blt.h:39
void generatePalette_(const ImageBuffer< C_ > &image, RgbColour palette[])
パレット生成
Definition pict_indexing.h:215
void decreaseColourSimply_(const ImageBuffer< C_ > &src, PictureIndexed &dst, const PaletteFinder_ &pf)
單純近似による減色處理
Definition pict_indexing.h:572
void decreaseColourUsingErrorDiffusion_(const ImageBuffer< C_ > &src, PictureIndexed &dst, const PaletteFinder_ &pf)
誤差分散法による減色處理
Definition pict_indexing.h:489
RGB24bit256インデックスの畫像バッファクラス