pikl 0.2.7 → 0.2.8
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest.txt +23 -0
- data/ext/pikl/decrease/fsdither.h +554 -0
- data/ext/pikl/decrease/median.c +1179 -0
- data/ext/pikl/decrease/median.h +7 -0
- data/ext/pikl/decrease/neuquan5.c +563 -0
- data/ext/pikl/decrease/neuquant.h +62 -0
- data/ext/pikl/decrease/wu.c +447 -0
- data/ext/pikl/decrease/wu.h +7 -0
- data/ext/pikl/pikl_affine.c +250 -0
- data/ext/pikl/pikl_affine.h +20 -0
- data/ext/pikl/pikl_blur.c +244 -0
- data/ext/pikl/pikl_blur.h +12 -0
- data/ext/pikl/pikl_decrease.c +126 -0
- data/ext/pikl/pikl_decrease.h +19 -0
- data/ext/pikl/pikl_effect2.c +240 -0
- data/ext/pikl/pikl_effect2.h +55 -0
- data/ext/pikl/pikl_effect3.c +266 -0
- data/ext/pikl/pikl_effect3.h +12 -0
- data/ext/pikl/pikl_effect4.c +495 -0
- data/ext/pikl/pikl_effect4.h +12 -0
- data/ext/pikl/pikl_pattern.c +611 -0
- data/ext/pikl/pikl_pattern.h +12 -0
- data/ext/pikl/pikl_scrap.c +731 -0
- data/ext/pikl/pikl_scrap.h +12 -0
- data/lib/pikl/version.rb +1 -1
- metadata +26 -3
@@ -0,0 +1,563 @@
|
|
1
|
+
/* NeuQuant Neural-Net Quantization Algorithm
|
2
|
+
* ------------------------------------------
|
3
|
+
*
|
4
|
+
* Copyright (c) 1994 Anthony Dekker
|
5
|
+
*
|
6
|
+
* NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994.
|
7
|
+
* See "Kohonen neural networks for optimal colour quantization"
|
8
|
+
* in "Network: Computation in Neural Systems" Vol. 5 (1994) pp 351-367.
|
9
|
+
* for a discussion of the algorithm.
|
10
|
+
* See also http://members.ozemail.com.au/~dekker/NEUQUANT.HTML
|
11
|
+
*
|
12
|
+
* Any party obtaining a copy of these files from the author, directly or
|
13
|
+
* indirectly, is granted, free of charge, a full and unrestricted irrevocable,
|
14
|
+
* world-wide, paid up, royalty-free, nonexclusive right and license to deal
|
15
|
+
* in this software and documentation files (the "Software"), including without
|
16
|
+
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
17
|
+
* and/or sell copies of the Software, and to permit persons who receive
|
18
|
+
* copies from any such party to do so, with the only requirement being
|
19
|
+
* that this copyright notice remain intact.
|
20
|
+
*/
|
21
|
+
|
22
|
+
/* ------------------------------------------
|
23
|
+
Code found on the Neuquant web page: http://acm.org/~dekker/NEUQUANT.HTML
|
24
|
+
*/
|
25
|
+
|
26
|
+
//
|
27
|
+
// Benny's additional stuff: v5
|
28
|
+
// Weber fix: 9 Mar 00
|
29
|
+
//
|
30
|
+
// soezimaster additional
|
31
|
+
// 2008.8.15
|
32
|
+
//
|
33
|
+
|
34
|
+
int colorsreq = 256;
|
35
|
+
|
36
|
+
//-- soezimaster delete(function's call)
|
37
|
+
//void error(char *s);
|
38
|
+
//extern unsigned char *QuantizedPicture;
|
39
|
+
//extern unsigned char *QuantizedPalette;
|
40
|
+
//----------------------------------------
|
41
|
+
|
42
|
+
// number of colours used
|
43
|
+
#define NETSIZE 256
|
44
|
+
|
45
|
+
// 1 slower, 30 faster [1..30]
|
46
|
+
//#define SFACTOR 15 // 1 15 30
|
47
|
+
|
48
|
+
#include "neuquant.h"
|
49
|
+
|
50
|
+
int netsize = NETSIZE;
|
51
|
+
|
52
|
+
/* Network Definitions
|
53
|
+
------------------- */
|
54
|
+
|
55
|
+
#define maxnetpos (netsize-1)
|
56
|
+
#define netbiasshift 4 /* bias for colour values */
|
57
|
+
#define ncycles 100 /* no. of learning cycles */
|
58
|
+
|
59
|
+
/* defs for freq and bias */
|
60
|
+
#define intbiasshift 16 /* bias for fractions */
|
61
|
+
#define intbias (((int) 1)<<intbiasshift)
|
62
|
+
#define gammashift 10 /* gamma = 1024 */
|
63
|
+
#define gamma (((int) 1)<<gammashift)
|
64
|
+
#define betashift 10
|
65
|
+
#define beta (intbias>>betashift) /* beta = 1/1024 */
|
66
|
+
#define betagamma (intbias<<(gammashift-betashift))
|
67
|
+
|
68
|
+
/* defs for decreasing radius factor */
|
69
|
+
#define INITRAD (NETSIZE>>3) /* for 256 cols, radius starts */
|
70
|
+
#define initrad (netsize>>3) /* for 256 cols, radius starts */
|
71
|
+
#define radiusbiasshift 6 /* at 32.0 biased by 6 bits */
|
72
|
+
#define radiusbias (((int) 1)<<radiusbiasshift)
|
73
|
+
#define initradius (initrad*radiusbias) /* and decreases by a */
|
74
|
+
#define radiusdec 30 /* factor of 1/30 each cycle */
|
75
|
+
|
76
|
+
/* defs for decreasing alpha factor */
|
77
|
+
#define alphabiasshift 10 /* alpha starts at 1.0 */
|
78
|
+
#define initalpha (((int) 1)<<alphabiasshift)
|
79
|
+
int alphadec; /* biased by 10 bits */
|
80
|
+
|
81
|
+
/* radbias and alpharadbias used for radpower calculation */
|
82
|
+
#define radbiasshift 8
|
83
|
+
#define radbias (((int) 1)<<radbiasshift)
|
84
|
+
#define alpharadbshift (alphabiasshift+radbiasshift)
|
85
|
+
#define alpharadbias (((int) 1)<<alpharadbshift)
|
86
|
+
|
87
|
+
|
88
|
+
/* Types and Global Variables
|
89
|
+
-------------------------- */
|
90
|
+
|
91
|
+
static unsigned char *thepicture; /* the input image itself */
|
92
|
+
static int lengthcount; /* lengthcount = H*W*3 */
|
93
|
+
static int samplefac; /* sampling factor 1..30 */
|
94
|
+
|
95
|
+
typedef int pixel[4]; /* BGRc */
|
96
|
+
static pixel network[NETSIZE]; /* the network itself */
|
97
|
+
|
98
|
+
static int netindex[256]; /* for network lookup - really 256 */
|
99
|
+
|
100
|
+
static int bias[NETSIZE]; /* bias and freq arrays for learning */
|
101
|
+
static int freq[NETSIZE];
|
102
|
+
static int radpower[INITRAD]; /* radpower for precomputation */
|
103
|
+
|
104
|
+
|
105
|
+
/* Initialise network in range (0,0,0) to (255,255,255) and set parameters
|
106
|
+
----------------------------------------------------------------------- */
|
107
|
+
|
108
|
+
/*
|
109
|
+
void initnet(thepic,len,sample,output_size)
|
110
|
+
unsigned char *thepic;
|
111
|
+
int len;
|
112
|
+
int sample;
|
113
|
+
int output_size;
|
114
|
+
{ */
|
115
|
+
//static void initnet(unsigned char *thepic, int len,int sample)
|
116
|
+
void initnet(unsigned char *thepic, int len,int sample)
|
117
|
+
{
|
118
|
+
int i, *p;
|
119
|
+
|
120
|
+
/*
|
121
|
+
netsize = output_size;
|
122
|
+
|
123
|
+
network = (pixel *)malloc(netsize*sizeof(pixel));
|
124
|
+
bias = (int *)malloc(netsize*sizeof(int));
|
125
|
+
freq = (int *)malloc(netsize*sizeof(int));
|
126
|
+
radpower = (int *)malloc(initrad*sizeof(int));
|
127
|
+
|
128
|
+
if(!network || !bias || !freq || !radpower)exit(1);
|
129
|
+
*/
|
130
|
+
|
131
|
+
thepicture = thepic;
|
132
|
+
lengthcount = len;
|
133
|
+
samplefac = sample;
|
134
|
+
|
135
|
+
for (i = 0; i < netsize; i++) {
|
136
|
+
p = network[i];
|
137
|
+
p[0] = p[1] = p[2] = (i << (netbiasshift + 8)) / netsize;
|
138
|
+
freq[i] = intbias / netsize; /* 1/netsize */
|
139
|
+
bias[i] = 0;
|
140
|
+
}
|
141
|
+
}
|
142
|
+
|
143
|
+
|
144
|
+
/* Unbias network to give byte values 0..255 and record position i to prepare for sort
|
145
|
+
----------------------------------------------------------------------------------- */
|
146
|
+
|
147
|
+
//static void unbiasnet()
|
148
|
+
void unbiasnet()
|
149
|
+
{
|
150
|
+
int i, j;
|
151
|
+
|
152
|
+
for (i = 0; i < netsize; i++) {
|
153
|
+
for (j = 0; j < 3; j++)
|
154
|
+
network[i][j] >>= netbiasshift;
|
155
|
+
network[i][3] = i; /* record colour no */
|
156
|
+
}
|
157
|
+
}
|
158
|
+
|
159
|
+
|
160
|
+
/* Output colour map
|
161
|
+
-----------------
|
162
|
+
static void writecolourmap(FILE *f)
|
163
|
+
{
|
164
|
+
int i, j;
|
165
|
+
|
166
|
+
for (i = 2; i >= 0; i--)
|
167
|
+
for (j = 0; j < netsize; j++)
|
168
|
+
putc(network[j][i], f);
|
169
|
+
}
|
170
|
+
*/
|
171
|
+
|
172
|
+
|
173
|
+
/* Insertion sort of network and building of netindex[0..255]
|
174
|
+
(to do after unbias)
|
175
|
+
----------------------------------------------------------
|
176
|
+
--------------------- */
|
177
|
+
|
178
|
+
//static void inxbuild()
|
179
|
+
void inxbuild()
|
180
|
+
{
|
181
|
+
int i, j, smallpos, smallval;
|
182
|
+
int *p, *q;
|
183
|
+
int previouscol, startpos;
|
184
|
+
|
185
|
+
previouscol = 0;
|
186
|
+
startpos = 0;
|
187
|
+
for (i = 0; i < netsize; i++) {
|
188
|
+
p = network[i];
|
189
|
+
smallpos = i;
|
190
|
+
smallval = p[1]; /* index on g */
|
191
|
+
/* find smallest in i..netsize-1 */
|
192
|
+
for (j = i + 1; j < netsize; j++) {
|
193
|
+
q = network[j];
|
194
|
+
if (q[1] < smallval) { /* index on g */
|
195
|
+
smallpos = j;
|
196
|
+
smallval = q[1]; /* index on g */
|
197
|
+
}
|
198
|
+
}
|
199
|
+
q = network[smallpos];
|
200
|
+
/* swap p (i) and q (smallpos) entries */
|
201
|
+
if (i != smallpos) {
|
202
|
+
j = q[0];
|
203
|
+
q[0] = p[0];
|
204
|
+
p[0] = j;
|
205
|
+
j = q[1];
|
206
|
+
q[1] = p[1];
|
207
|
+
p[1] = j;
|
208
|
+
j = q[2];
|
209
|
+
q[2] = p[2];
|
210
|
+
p[2] = j;
|
211
|
+
j = q[3];
|
212
|
+
q[3] = p[3];
|
213
|
+
p[3] = j;
|
214
|
+
}
|
215
|
+
/* smallval entry is now in position i */
|
216
|
+
if (smallval != previouscol) {
|
217
|
+
netindex[previouscol] = (startpos + i) >> 1;
|
218
|
+
for (j = previouscol + 1; j < smallval; j++)
|
219
|
+
netindex[j] = i;
|
220
|
+
previouscol = smallval;
|
221
|
+
startpos = i;
|
222
|
+
}
|
223
|
+
}
|
224
|
+
netindex[previouscol] = (startpos + maxnetpos) >> 1;
|
225
|
+
for (j = previouscol + 1; j < 256; j++)
|
226
|
+
netindex[j] = maxnetpos; /* really 256 */
|
227
|
+
}
|
228
|
+
|
229
|
+
|
230
|
+
/* Search for BGR values 0..255 (after net is unbiased) and
|
231
|
+
return colour index
|
232
|
+
--------------------------------------------------------
|
233
|
+
-------------------- */
|
234
|
+
//static int inxsearch(int b, int g, int r)
|
235
|
+
int inxsearch(int b, int g, int r)
|
236
|
+
{
|
237
|
+
int i, j, dist, a, bestd;
|
238
|
+
int *p;
|
239
|
+
int best;
|
240
|
+
|
241
|
+
bestd = 1000; /* biggest possible dist is 256*3 */
|
242
|
+
best = -1;
|
243
|
+
i = netindex[g]; /* index on g */
|
244
|
+
j = i - 1; /* start at netindex[g] and work outwards */
|
245
|
+
|
246
|
+
while ((i < netsize) || (j >= 0)) {
|
247
|
+
if (i < netsize) {
|
248
|
+
p = network[i];
|
249
|
+
dist = p[1] - g; /* inx key */
|
250
|
+
if (dist >= bestd)
|
251
|
+
i = netsize; /* stop iter */
|
252
|
+
else {
|
253
|
+
i++;
|
254
|
+
if (dist < 0)
|
255
|
+
dist = -dist;
|
256
|
+
a = p[0] - b;
|
257
|
+
if (a < 0)
|
258
|
+
a = -a;
|
259
|
+
dist += a;
|
260
|
+
if (dist < bestd) {
|
261
|
+
a = p[2] - r;
|
262
|
+
if (a < 0)
|
263
|
+
a = -a;
|
264
|
+
dist += a;
|
265
|
+
if (dist < bestd) {
|
266
|
+
bestd = dist;
|
267
|
+
best = p[3];
|
268
|
+
}
|
269
|
+
}
|
270
|
+
}
|
271
|
+
}
|
272
|
+
/* if (j >= 0) */ // not needed (Weber)
|
273
|
+
if (j >= 0){ //retreave(soezimaster)
|
274
|
+
p = network[j];
|
275
|
+
dist = g - p[1]; /* inx key - reverse dif */
|
276
|
+
if (dist >= bestd)
|
277
|
+
j = -1; /* stop iter */
|
278
|
+
else {
|
279
|
+
j--;
|
280
|
+
if (dist < 0)
|
281
|
+
dist = -dist;
|
282
|
+
a = p[0] - b;
|
283
|
+
if (a < 0)
|
284
|
+
a = -a;
|
285
|
+
dist += a;
|
286
|
+
if (dist < bestd) {
|
287
|
+
a = p[2] - r;
|
288
|
+
if (a < 0)
|
289
|
+
a = -a;
|
290
|
+
dist += a;
|
291
|
+
if (dist < bestd) {
|
292
|
+
bestd = dist;
|
293
|
+
best = p[3];
|
294
|
+
}
|
295
|
+
}
|
296
|
+
}
|
297
|
+
}
|
298
|
+
}
|
299
|
+
return (best);
|
300
|
+
}
|
301
|
+
|
302
|
+
|
303
|
+
/* Search for biased BGR values
|
304
|
+
---------------------------- */
|
305
|
+
|
306
|
+
static int contest(b, g, r)
|
307
|
+
int b, g, r;
|
308
|
+
{
|
309
|
+
/* finds closest neuron (min dist) and updates freq */
|
310
|
+
/* finds best neuron (min dist-bias) and returns position */
|
311
|
+
/* for frequently chosen neurons, freq[i] is high and bias[i] is negative */
|
312
|
+
/* bias[i] = gamma*((1/netsize)-freq[i]) */
|
313
|
+
|
314
|
+
int i, dist, a, biasdist, betafreq;
|
315
|
+
int bestpos, bestbiaspos, bestd, bestbiasd;
|
316
|
+
int *p, *f, *n;
|
317
|
+
|
318
|
+
bestd = ~(((int) 1) << 31);
|
319
|
+
bestbiasd = bestd;
|
320
|
+
bestpos = -1;
|
321
|
+
bestbiaspos = bestpos;
|
322
|
+
p = bias;
|
323
|
+
f = freq;
|
324
|
+
|
325
|
+
for (i = 0; i < netsize; i++) {
|
326
|
+
n = network[i];
|
327
|
+
dist = n[0] - b;
|
328
|
+
if (dist < 0)
|
329
|
+
dist = -dist;
|
330
|
+
a = n[1] - g;
|
331
|
+
if (a < 0)
|
332
|
+
a = -a;
|
333
|
+
dist += a;
|
334
|
+
a = n[2] - r;
|
335
|
+
if (a < 0)
|
336
|
+
a = -a;
|
337
|
+
dist += a;
|
338
|
+
if (dist < bestd) {
|
339
|
+
bestd = dist;
|
340
|
+
bestpos = i;
|
341
|
+
}
|
342
|
+
biasdist = dist - ((*p) >> (intbiasshift - netbiasshift));
|
343
|
+
if (biasdist < bestbiasd) {
|
344
|
+
bestbiasd = biasdist;
|
345
|
+
bestbiaspos = i;
|
346
|
+
}
|
347
|
+
betafreq = (*f >> betashift);
|
348
|
+
*f++ -= betafreq;
|
349
|
+
*p++ += (betafreq << gammashift);
|
350
|
+
}
|
351
|
+
freq[bestpos] += beta;
|
352
|
+
bias[bestpos] -= betagamma;
|
353
|
+
return (bestbiaspos);
|
354
|
+
}
|
355
|
+
|
356
|
+
|
357
|
+
/* Move neuron i towards biased (b,g,r) by factor alpha
|
358
|
+
---------------------------------------------------- */
|
359
|
+
|
360
|
+
static void altersingle(alpha, i, b, g, r)
|
361
|
+
int alpha, i, b, g, r;
|
362
|
+
{
|
363
|
+
int *n;
|
364
|
+
|
365
|
+
n = network[i]; /* alter hit neuron */
|
366
|
+
*n -= (alpha * (*n - b)) / initalpha;
|
367
|
+
n++;
|
368
|
+
*n -= (alpha * (*n - g)) / initalpha;
|
369
|
+
n++;
|
370
|
+
*n -= (alpha * (*n - r)) / initalpha;
|
371
|
+
}
|
372
|
+
|
373
|
+
|
374
|
+
/* Move adjacent neurons by precomputed alpha*(1-((i-j)^2/[r]^2))
|
375
|
+
in radpower[|i-j|]
|
376
|
+
--------------------------------------------------------------
|
377
|
+
------------------- */
|
378
|
+
|
379
|
+
static void alterneigh(rad, i, b, g, r)
|
380
|
+
int rad, i;
|
381
|
+
int b, g, r;
|
382
|
+
{
|
383
|
+
int j, k, lo, hi, a;
|
384
|
+
int *p, *q;
|
385
|
+
|
386
|
+
lo = i - rad;
|
387
|
+
if (lo < -1)
|
388
|
+
lo = -1;
|
389
|
+
hi = i + rad;
|
390
|
+
if (hi > netsize)
|
391
|
+
hi = netsize;
|
392
|
+
|
393
|
+
j = i + 1;
|
394
|
+
k = i - 1;
|
395
|
+
q = radpower;
|
396
|
+
while ((j < hi) || (k > lo)) {
|
397
|
+
a = (*(++q));
|
398
|
+
if (j < hi) {
|
399
|
+
p = network[j];
|
400
|
+
*p -= (a * (*p - b)) / alpharadbias;
|
401
|
+
p++;
|
402
|
+
*p -= (a * (*p - g)) / alpharadbias;
|
403
|
+
p++;
|
404
|
+
*p -= (a * (*p - r)) / alpharadbias;
|
405
|
+
j++;
|
406
|
+
}
|
407
|
+
if (k > lo) {
|
408
|
+
p = network[k];
|
409
|
+
*p -= (a * (*p - b)) / alpharadbias;
|
410
|
+
p++;
|
411
|
+
*p -= (a * (*p - g)) / alpharadbias;
|
412
|
+
p++;
|
413
|
+
*p -= (a * (*p - r)) / alpharadbias;
|
414
|
+
k--;
|
415
|
+
}
|
416
|
+
}
|
417
|
+
}
|
418
|
+
|
419
|
+
|
420
|
+
/* Main Learning Loop
|
421
|
+
------------------ */
|
422
|
+
//static void learn()
|
423
|
+
void learn()
|
424
|
+
{
|
425
|
+
int i, j, b, g, r;
|
426
|
+
int radius, rad, alpha, step, delta, samplepixels;
|
427
|
+
unsigned char *p;
|
428
|
+
unsigned char *lim;
|
429
|
+
|
430
|
+
alphadec = 30 + ((samplefac - 1) / 3);
|
431
|
+
p = thepicture;
|
432
|
+
lim = thepicture + lengthcount;
|
433
|
+
samplepixels = lengthcount / (3 * samplefac);
|
434
|
+
delta = samplepixels / ncycles;
|
435
|
+
alpha = initalpha;
|
436
|
+
radius = initradius;
|
437
|
+
|
438
|
+
rad = radius >> radiusbiasshift;
|
439
|
+
if (rad <= 1)
|
440
|
+
rad = 0;
|
441
|
+
for (i = 0; i < rad; i++)
|
442
|
+
radpower[i] = alpha * (((rad * rad - i * i) * radbias) / (rad * rad));
|
443
|
+
|
444
|
+
// printf("beginning 1D learning: initial radius=%d\n", rad);
|
445
|
+
|
446
|
+
if ((lengthcount % prime1) != 0)
|
447
|
+
step = 3 * prime1;
|
448
|
+
else {
|
449
|
+
if ((lengthcount % prime2) != 0)
|
450
|
+
step = 3 * prime2;
|
451
|
+
else {
|
452
|
+
if ((lengthcount % prime3) != 0)
|
453
|
+
step = 3 * prime3;
|
454
|
+
else
|
455
|
+
step = 3 * prime4;
|
456
|
+
}
|
457
|
+
}
|
458
|
+
|
459
|
+
i = 0;
|
460
|
+
while (i < samplepixels) {
|
461
|
+
b = p[0] << netbiasshift;
|
462
|
+
g = p[1] << netbiasshift;
|
463
|
+
r = p[2] << netbiasshift;
|
464
|
+
j = contest(b, g, r);
|
465
|
+
|
466
|
+
altersingle(alpha, j, b, g, r);
|
467
|
+
if (rad)
|
468
|
+
alterneigh(rad, j, b, g, r); /* alter neighbours */
|
469
|
+
|
470
|
+
p += step;
|
471
|
+
if (p >= lim)
|
472
|
+
p -= lengthcount;
|
473
|
+
|
474
|
+
i++;
|
475
|
+
if (i % delta == 0) {
|
476
|
+
alpha -= alpha / alphadec;
|
477
|
+
radius -= radius / radiusdec;
|
478
|
+
rad = radius >> radiusbiasshift;
|
479
|
+
if (rad <= 1)
|
480
|
+
rad = 0;
|
481
|
+
for (j = 0; j < rad; j++)
|
482
|
+
radpower[j] = alpha * (((rad * rad - j * j) * radbias) / (rad * rad));
|
483
|
+
}
|
484
|
+
}
|
485
|
+
// printf("finished 1D learning: final alpha=%f !\n",((float)alpha)/initalpha);
|
486
|
+
}
|
487
|
+
|
488
|
+
|
489
|
+
|
490
|
+
static void writemap(unsigned char *f)
|
491
|
+
{
|
492
|
+
int j, k = 0;
|
493
|
+
|
494
|
+
//// BGR
|
495
|
+
//for (j = 0; j < /*netsize*/ colorsreq; j++) {
|
496
|
+
// f[k] = network[j][2];
|
497
|
+
// k++;
|
498
|
+
// f[k] = network[j][1];
|
499
|
+
// k++;
|
500
|
+
// f[k] = network[j][0];
|
501
|
+
// k++;
|
502
|
+
//}
|
503
|
+
//--changed.(soezimaster)
|
504
|
+
//RGB
|
505
|
+
//for (j = 0; j < /*netsize*/ colorsreq; j++) {
|
506
|
+
for (j = 0; j <netsize; j++) {
|
507
|
+
f[k++] = network[j][0];
|
508
|
+
f[k++] = network[j][1];
|
509
|
+
f[k++] = network[j][2];
|
510
|
+
}
|
511
|
+
}
|
512
|
+
|
513
|
+
|
514
|
+
|
515
|
+
static void Quantize24Bit(unsigned char *pic_in,
|
516
|
+
unsigned char *pic_out, unsigned char *pal_out,
|
517
|
+
int length, int reduce_to, int sample_factor)
|
518
|
+
{
|
519
|
+
int i;
|
520
|
+
|
521
|
+
netsize = reduce_to;
|
522
|
+
initnet(pic_in, length, sample_factor);
|
523
|
+
|
524
|
+
learn();
|
525
|
+
unbiasnet();
|
526
|
+
|
527
|
+
writemap(pal_out);
|
528
|
+
inxbuild();
|
529
|
+
|
530
|
+
for (i = 0; i < length; i += 3)
|
531
|
+
pic_out[i / 3] = inxsearch(pic_in[i+0], pic_in[i+1], pic_in[i+2]);
|
532
|
+
}
|
533
|
+
|
534
|
+
//int neuReduce(unsigned char *RGBpic, int numcolors, long picsize, int sfactor)
|
535
|
+
int neuReduce(unsigned char *RGBpic, int numcolors, long picsize, int sfactor,
|
536
|
+
unsigned char *QuantizedPicture, unsigned char *QuantizedPalette)
|
537
|
+
{
|
538
|
+
colorsreq = numcolors;
|
539
|
+
Quantize24Bit(RGBpic,
|
540
|
+
QuantizedPicture,
|
541
|
+
QuantizedPalette,
|
542
|
+
picsize*3L,
|
543
|
+
numcolors,
|
544
|
+
sfactor);
|
545
|
+
return 0;
|
546
|
+
}
|
547
|
+
|
548
|
+
/* Program Skeleton
|
549
|
+
----------------
|
550
|
+
[select samplefac in range 1..30]
|
551
|
+
[read image from input file]
|
552
|
+
pic_in = (unsigned char*) malloc(3*width*height);
|
553
|
+
initnet(pic_in,3*width*height,samplefac);
|
554
|
+
learn();
|
555
|
+
unbiasnet();
|
556
|
+
[write output image header, using writecolourmap(f)]
|
557
|
+
inxbuild();
|
558
|
+
write output image using inxsearch(b,g,r)
|
559
|
+
*/
|
560
|
+
/* Output:
|
561
|
+
QuantizedPicture[picsize];
|
562
|
+
QuantizedPalette[numcolors*3];
|
563
|
+
*/
|