pikl 0.2.7-x86-mswin32 → 0.2.8-x86-mswin32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
*/
|