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,62 @@
|
|
1
|
+
/* NeuQuant Neural-Net Quantization Algorithm Interface
|
2
|
+
* ----------------------------------------------------
|
3
|
+
*/
|
4
|
+
|
5
|
+
#include <stdio.h>
|
6
|
+
|
7
|
+
/* For 256 colours, fixed arrays need 8kb, plus space for the image
|
8
|
+
---------------------------------------------------------------- */
|
9
|
+
|
10
|
+
/* four primes near 500 - assume no image has a length so large */
|
11
|
+
/* that it is divisible by all four primes */
|
12
|
+
#define prime1 499
|
13
|
+
#define prime2 491
|
14
|
+
#define prime3 487
|
15
|
+
#define prime4 503
|
16
|
+
|
17
|
+
#define minpicturebytes (3*prime4) /* minimum size for input image */
|
18
|
+
|
19
|
+
|
20
|
+
/* Initialise network in range (0,0,0) to (255,255,255) and set parameters
|
21
|
+
----------------------------------------------------------------------- */
|
22
|
+
void initnet(unsigned char *thepic, int len, int sample);
|
23
|
+
|
24
|
+
/* Unbias network to give byte values 0..255 and record position i to prepare for sort
|
25
|
+
----------------------------------------------------------------------------------- */
|
26
|
+
void unbiasnet(); /* can edit this function to do output of colour map */
|
27
|
+
|
28
|
+
/* Output colour map
|
29
|
+
----------------- */
|
30
|
+
void writecolourmap(FILE *f);
|
31
|
+
|
32
|
+
/* Insertion sort of network and building of netindex[0..255] (to do after unbias)
|
33
|
+
------------------------------------------------------------------------------- */
|
34
|
+
void inxbuild();
|
35
|
+
|
36
|
+
/* Search for BGR values 0..255 (after net is unbiased) and return colour index
|
37
|
+
---------------------------------------------------------------------------- */
|
38
|
+
int inxsearch(register int b, register int g, register int r);
|
39
|
+
|
40
|
+
/* Main Learning Loop
|
41
|
+
------------------ */
|
42
|
+
void learn();
|
43
|
+
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
int neuReduce(unsigned char *RGBpic, int numcolors, long picsize, int sfactor,
|
48
|
+
unsigned char *QuantizedPicture, unsigned char *QuantizedPalette);
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
/* Program Skeleton
|
53
|
+
----------------
|
54
|
+
[select samplefac in range 1..30]
|
55
|
+
[read image from input file]
|
56
|
+
pic = (unsigned char*) malloc(3*width*height);
|
57
|
+
initnet(pic,3*width*height,samplefac);
|
58
|
+
learn();
|
59
|
+
unbiasnet();
|
60
|
+
[write output image header, using writecolourmap(f)]
|
61
|
+
inxbuild();
|
62
|
+
write output image using inxsearch(b,g,r) */
|
@@ -0,0 +1,447 @@
|
|
1
|
+
/*
|
2
|
+
C Implementation of Wu's Color Quantizer (v2.0)
|
3
|
+
-- Xiaolin Wu.
|
4
|
+
From the Graphics Gems.
|
5
|
+
|
6
|
+
Memory hungry.
|
7
|
+
|
8
|
+
Some fixes and additional code by Benny.
|
9
|
+
*/
|
10
|
+
|
11
|
+
#include<stdio.h>
|
12
|
+
#include<assert.h>
|
13
|
+
#include<malloc.h>
|
14
|
+
|
15
|
+
//#define NOINVERT // RGB or BGR
|
16
|
+
|
17
|
+
void error(char *s);
|
18
|
+
|
19
|
+
///* Externs: */
|
20
|
+
//extern unsigned char *Picture256;
|
21
|
+
//extern unsigned char QuantizedPalette[768];
|
22
|
+
|
23
|
+
#define MAXCOLOR 256
|
24
|
+
#define RED 2
|
25
|
+
#define GREEN 1
|
26
|
+
#define BLUE 0
|
27
|
+
|
28
|
+
struct box {
|
29
|
+
int r0; /* min value, exclusive */
|
30
|
+
int r1; /* max value, inclusive */
|
31
|
+
int g0;
|
32
|
+
int g1;
|
33
|
+
int b0;
|
34
|
+
int b1;
|
35
|
+
int vol;
|
36
|
+
};
|
37
|
+
|
38
|
+
/* Histogram is in elements 1..HISTSIZE along each axis,
|
39
|
+
element 0 is for base or marginal value.
|
40
|
+
NB: these must start out 0! */
|
41
|
+
#define BOX 33
|
42
|
+
long wt[BOX][BOX][BOX],
|
43
|
+
mr[BOX][BOX][BOX],
|
44
|
+
mg[BOX][BOX][BOX],
|
45
|
+
mb[BOX][BOX][BOX];
|
46
|
+
float m2[BOX][BOX][BOX];
|
47
|
+
|
48
|
+
int ImageSize; /* image size */
|
49
|
+
int PalSize; /* color look-up table size */
|
50
|
+
|
51
|
+
unsigned short *Qadd; // *must* be unsigned?
|
52
|
+
unsigned char *TrueColorPic;
|
53
|
+
|
54
|
+
/* build 3-D color histogram of counts, r/g/b, c^2 */
|
55
|
+
static void Hist3d(long *vwt, long *vmr, long *vmg, long *vmb, float *m_2)
|
56
|
+
{
|
57
|
+
int ind,
|
58
|
+
r,
|
59
|
+
g,
|
60
|
+
b;
|
61
|
+
int inr,
|
62
|
+
ing,
|
63
|
+
inb,
|
64
|
+
table[256];
|
65
|
+
long i;
|
66
|
+
|
67
|
+
for (i = 0; i < 256; ++i)
|
68
|
+
table[i] = i * i;
|
69
|
+
|
70
|
+
for (i = 0; i < ImageSize; ++i) {
|
71
|
+
r = TrueColorPic[i*3 ];
|
72
|
+
g = TrueColorPic[i*3+1];
|
73
|
+
b = TrueColorPic[i*3+2];
|
74
|
+
|
75
|
+
inr = (r >> 3) + 1;
|
76
|
+
ing = (g >> 3) + 1;
|
77
|
+
inb = (b >> 3) + 1;
|
78
|
+
Qadd[i] = ind = (inr << 10) + (inr << 6) + inr + (ing << 5) + ing + inb;
|
79
|
+
/* [inr][ing][inb] */
|
80
|
+
++vwt[ind];
|
81
|
+
vmr[ind] += r;
|
82
|
+
vmg[ind] += g;
|
83
|
+
vmb[ind] += b;
|
84
|
+
m_2[ind] += (float) (table[r] + table[g] + table[b]);
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
/* We now convert histogram into moments so that we can rapidly calculate
|
89
|
+
the sums of the above quantities over any desired box. */
|
90
|
+
static void Momt3d(long *vwt, long *vmr, long *vmg, long *vmb, float *m_2)
|
91
|
+
{
|
92
|
+
unsigned short ind1,
|
93
|
+
ind2;
|
94
|
+
unsigned char i,
|
95
|
+
r,
|
96
|
+
g,
|
97
|
+
b;
|
98
|
+
long line,
|
99
|
+
line_r,
|
100
|
+
line_g,
|
101
|
+
line_b,
|
102
|
+
area[BOX],
|
103
|
+
area_r[BOX],
|
104
|
+
area_g[BOX],
|
105
|
+
area_b[BOX];
|
106
|
+
float line2,
|
107
|
+
area2[BOX];
|
108
|
+
|
109
|
+
for (r = 1; r <= 32; ++r) {
|
110
|
+
for (i = 0; i <= 32; ++i)
|
111
|
+
area2[i] = area[i] = area_r[i] = area_g[i] = area_b[i] = 0;
|
112
|
+
for (g = 1; g <= 32; ++g) {
|
113
|
+
line2 = line = line_r = line_g = line_b = 0;
|
114
|
+
for (b = 1; b <= 32; ++b) {
|
115
|
+
ind1 = (r << 10) + (r << 6) + r + (g << 5) + g + b;
|
116
|
+
/* [r][g][b] */
|
117
|
+
line += vwt[ind1];
|
118
|
+
line_r += vmr[ind1];
|
119
|
+
line_g += vmg[ind1];
|
120
|
+
line_b += vmb[ind1];
|
121
|
+
line2 += m_2[ind1];
|
122
|
+
area[b] += line;
|
123
|
+
area_r[b] += line_r;
|
124
|
+
area_g[b] += line_g;
|
125
|
+
area_b[b] += line_b;
|
126
|
+
area2[b] += line2;
|
127
|
+
ind2 = ind1 - 1089; /* [r-1][g][b] */
|
128
|
+
vwt[ind1] = vwt[ind2] + area[b];
|
129
|
+
vmr[ind1] = vmr[ind2] + area_r[b];
|
130
|
+
vmg[ind1] = vmg[ind2] + area_g[b];
|
131
|
+
vmb[ind1] = vmb[ind2] + area_b[b];
|
132
|
+
m_2[ind1] = m_2[ind2] + area2[b];
|
133
|
+
}
|
134
|
+
}
|
135
|
+
}
|
136
|
+
}
|
137
|
+
|
138
|
+
static long Vol(struct box * cube, long mmt[BOX][BOX][BOX])
|
139
|
+
{
|
140
|
+
return (mmt[cube->r1][cube->g1][cube->b1]
|
141
|
+
- mmt[cube->r1][cube->g1][cube->b0]
|
142
|
+
- mmt[cube->r1][cube->g0][cube->b1]
|
143
|
+
+ mmt[cube->r1][cube->g0][cube->b0]
|
144
|
+
- mmt[cube->r0][cube->g1][cube->b1]
|
145
|
+
+ mmt[cube->r0][cube->g1][cube->b0]
|
146
|
+
+ mmt[cube->r0][cube->g0][cube->b1]
|
147
|
+
- mmt[cube->r0][cube->g0][cube->b0]);
|
148
|
+
}
|
149
|
+
|
150
|
+
static long
|
151
|
+
Bottom(struct box * cube, unsigned char dir, long mmt[BOX][BOX][BOX])
|
152
|
+
{
|
153
|
+
switch (dir) {
|
154
|
+
case RED:
|
155
|
+
return (-mmt[cube->r0][cube->g1][cube->b1]
|
156
|
+
+ mmt[cube->r0][cube->g1][cube->b0]
|
157
|
+
+ mmt[cube->r0][cube->g0][cube->b1]
|
158
|
+
- mmt[cube->r0][cube->g0][cube->b0]);
|
159
|
+
case GREEN:
|
160
|
+
return (-mmt[cube->r1][cube->g0][cube->b1]
|
161
|
+
+ mmt[cube->r1][cube->g0][cube->b0]
|
162
|
+
+ mmt[cube->r0][cube->g0][cube->b1]
|
163
|
+
- mmt[cube->r0][cube->g0][cube->b0]);
|
164
|
+
case BLUE:
|
165
|
+
return (-mmt[cube->r1][cube->g1][cube->b0]
|
166
|
+
+ mmt[cube->r1][cube->g0][cube->b0]
|
167
|
+
+ mmt[cube->r0][cube->g1][cube->b0]
|
168
|
+
- mmt[cube->r0][cube->g0][cube->b0]);
|
169
|
+
}
|
170
|
+
error("error in Bottom()");
|
171
|
+
return 0;
|
172
|
+
}
|
173
|
+
|
174
|
+
static long
|
175
|
+
Top(struct box * cube, unsigned char dir, int pos, long mmt[BOX][BOX][BOX])
|
176
|
+
{
|
177
|
+
switch (dir) {
|
178
|
+
case RED:
|
179
|
+
return (mmt[pos][cube->g1][cube->b1]
|
180
|
+
- mmt[pos][cube->g1][cube->b0]
|
181
|
+
- mmt[pos][cube->g0][cube->b1]
|
182
|
+
+ mmt[pos][cube->g0][cube->b0]);
|
183
|
+
case GREEN:
|
184
|
+
return (mmt[cube->r1][pos][cube->b1]
|
185
|
+
- mmt[cube->r1][pos][cube->b0]
|
186
|
+
- mmt[cube->r0][pos][cube->b1]
|
187
|
+
+ mmt[cube->r0][pos][cube->b0]);
|
188
|
+
case BLUE:
|
189
|
+
return (mmt[cube->r1][cube->g1][pos]
|
190
|
+
- mmt[cube->r1][cube->g0][pos]
|
191
|
+
- mmt[cube->r0][cube->g1][pos]
|
192
|
+
+ mmt[cube->r0][cube->g0][pos]);
|
193
|
+
}
|
194
|
+
error("error in Top()");
|
195
|
+
return 0;
|
196
|
+
}
|
197
|
+
|
198
|
+
|
199
|
+
static float Var(struct box * cube)
|
200
|
+
{
|
201
|
+
float dr,
|
202
|
+
dg,
|
203
|
+
db,
|
204
|
+
xx;
|
205
|
+
|
206
|
+
dr = Vol(cube, mr);
|
207
|
+
dg = Vol(cube, mg);
|
208
|
+
db = Vol(cube, mb);
|
209
|
+
xx = m2[cube->r1][cube->g1][cube->b1]
|
210
|
+
- m2[cube->r1][cube->g1][cube->b0]
|
211
|
+
- m2[cube->r1][cube->g0][cube->b1]
|
212
|
+
+ m2[cube->r1][cube->g0][cube->b0]
|
213
|
+
- m2[cube->r0][cube->g1][cube->b1]
|
214
|
+
+ m2[cube->r0][cube->g1][cube->b0]
|
215
|
+
+ m2[cube->r0][cube->g0][cube->b1]
|
216
|
+
- m2[cube->r0][cube->g0][cube->b0];
|
217
|
+
|
218
|
+
return (xx - (dr * dr + dg * dg + db * db) / (float) Vol(cube, wt));
|
219
|
+
}
|
220
|
+
|
221
|
+
static float Maximize(cube, dir, first, last, cut,
|
222
|
+
whole_r, whole_g, whole_b, whole_w)
|
223
|
+
struct box *cube;
|
224
|
+
unsigned char dir;
|
225
|
+
int first,
|
226
|
+
last,
|
227
|
+
*cut;
|
228
|
+
long whole_r,
|
229
|
+
whole_g,
|
230
|
+
whole_b,
|
231
|
+
whole_w;
|
232
|
+
{
|
233
|
+
long half_r,
|
234
|
+
half_g,
|
235
|
+
half_b,
|
236
|
+
half_w;
|
237
|
+
long base_r,
|
238
|
+
base_g,
|
239
|
+
base_b,
|
240
|
+
base_w;
|
241
|
+
int i;
|
242
|
+
float temp, max;
|
243
|
+
|
244
|
+
base_r = Bottom(cube, dir, mr);
|
245
|
+
base_g = Bottom(cube, dir, mg);
|
246
|
+
base_b = Bottom(cube, dir, mb);
|
247
|
+
base_w = Bottom(cube, dir, wt);
|
248
|
+
max = 0.0;
|
249
|
+
*cut = -1;
|
250
|
+
for (i = first; i < last; ++i) {
|
251
|
+
half_r = base_r + Top(cube, dir, i, mr);
|
252
|
+
half_g = base_g + Top(cube, dir, i, mg);
|
253
|
+
half_b = base_b + Top(cube, dir, i, mb);
|
254
|
+
half_w = base_w + Top(cube, dir, i, wt);
|
255
|
+
/* now half_x is sum over lower half of box, if split at i */
|
256
|
+
if (half_w == 0) { /* subbox could be empty of pixels! */
|
257
|
+
continue; /* never split into an empty box */
|
258
|
+
} else
|
259
|
+
temp = ((float) half_r * half_r + (float) half_g * half_g +
|
260
|
+
(float) half_b * half_b) / half_w;
|
261
|
+
|
262
|
+
half_r = whole_r - half_r;
|
263
|
+
half_g = whole_g - half_g;
|
264
|
+
half_b = whole_b - half_b;
|
265
|
+
half_w = whole_w - half_w;
|
266
|
+
if (half_w == 0) { /* subbox could be empty of pixels! */
|
267
|
+
continue; /* never split into an empty box */
|
268
|
+
} else
|
269
|
+
temp += ((float) half_r * half_r + (float) half_g * half_g +
|
270
|
+
(float) half_b * half_b) / half_w;
|
271
|
+
|
272
|
+
if (temp > max) {
|
273
|
+
max = temp;
|
274
|
+
*cut = i;
|
275
|
+
}
|
276
|
+
}
|
277
|
+
return (max);
|
278
|
+
}
|
279
|
+
|
280
|
+
static int Cut(struct box * set1, struct box * set2)
|
281
|
+
{
|
282
|
+
unsigned char dir;
|
283
|
+
int cutr,
|
284
|
+
cutg,
|
285
|
+
cutb;
|
286
|
+
float maxr,
|
287
|
+
maxg,
|
288
|
+
maxb;
|
289
|
+
long whole_r,
|
290
|
+
whole_g,
|
291
|
+
whole_b,
|
292
|
+
whole_w;
|
293
|
+
|
294
|
+
whole_r = Vol(set1, mr);
|
295
|
+
whole_g = Vol(set1, mg);
|
296
|
+
whole_b = Vol(set1, mb);
|
297
|
+
whole_w = Vol(set1, wt);
|
298
|
+
|
299
|
+
maxr = Maximize(set1, RED, set1->r0 + 1, set1->r1, &cutr,
|
300
|
+
whole_r, whole_g, whole_b, whole_w);
|
301
|
+
maxg = Maximize(set1, GREEN, set1->g0 + 1, set1->g1, &cutg,
|
302
|
+
whole_r, whole_g, whole_b, whole_w);
|
303
|
+
maxb = Maximize(set1, BLUE, set1->b0 + 1, set1->b1, &cutb,
|
304
|
+
whole_r, whole_g, whole_b, whole_w);
|
305
|
+
|
306
|
+
if ((maxr >= maxg) && (maxr >= maxb)) {
|
307
|
+
dir = RED;
|
308
|
+
if (cutr < 0)
|
309
|
+
return 0; /* can't split the box */
|
310
|
+
} else if ((maxg >= maxr) && (maxg >= maxb))
|
311
|
+
dir = GREEN;
|
312
|
+
else
|
313
|
+
dir = BLUE;
|
314
|
+
|
315
|
+
set2->r1 = set1->r1;
|
316
|
+
set2->g1 = set1->g1;
|
317
|
+
set2->b1 = set1->b1;
|
318
|
+
|
319
|
+
switch (dir) {
|
320
|
+
case RED:
|
321
|
+
set2->r0 = set1->r1 = cutr;
|
322
|
+
set2->g0 = set1->g0;
|
323
|
+
set2->b0 = set1->b0;
|
324
|
+
break;
|
325
|
+
case GREEN:
|
326
|
+
set2->g0 = set1->g1 = cutg;
|
327
|
+
set2->r0 = set1->r0;
|
328
|
+
set2->b0 = set1->b0;
|
329
|
+
break;
|
330
|
+
case BLUE:
|
331
|
+
set2->b0 = set1->b1 = cutb;
|
332
|
+
set2->r0 = set1->r0;
|
333
|
+
set2->g0 = set1->g0;
|
334
|
+
break;
|
335
|
+
}
|
336
|
+
set1->vol = (set1->r1 - set1->r0) * (set1->g1 - set1->g0) * (set1->b1 - set1->b0);
|
337
|
+
set2->vol = (set2->r1 - set2->r0) * (set2->g1 - set2->g0) * (set2->b1 - set2->b0);
|
338
|
+
return 1;
|
339
|
+
}
|
340
|
+
|
341
|
+
static void Mark(struct box * cube, int label, unsigned char *tag)
|
342
|
+
{
|
343
|
+
int r, g, b;
|
344
|
+
for (r = cube->r0 + 1; r <= cube->r1; ++r)
|
345
|
+
for (g = cube->g0 + 1; g <= cube->g1; ++g)
|
346
|
+
for (b = cube->b0 + 1; b <= cube->b1; ++b)
|
347
|
+
tag[(r << 10) + (r << 6) + r + (g << 5) + g + b] = label;
|
348
|
+
}
|
349
|
+
|
350
|
+
#define WEIG //>>2
|
351
|
+
//int wuReduce(unsigned char *RGBpic, int numcolors, long picsize)
|
352
|
+
int wuReduce(unsigned char *RGBpic, int numcolors, long picsize,
|
353
|
+
unsigned char *Picture256, unsigned char *QuantizedPalette)
|
354
|
+
{
|
355
|
+
struct box cube[MAXCOLOR];
|
356
|
+
unsigned char *tag = 0;
|
357
|
+
float vv[MAXCOLOR],
|
358
|
+
temp = 0.;
|
359
|
+
long i = 0,
|
360
|
+
weight = 0;
|
361
|
+
int next = 0;
|
362
|
+
int j = 0,k = 0,l = 0;
|
363
|
+
|
364
|
+
/* input R,G,B components into TrueColorPic;
|
365
|
+
set ImageSize to width*height */
|
366
|
+
TrueColorPic = RGBpic;
|
367
|
+
ImageSize = picsize;
|
368
|
+
PalSize = numcolors;
|
369
|
+
|
370
|
+
for (j=0;j<BOX;j++)
|
371
|
+
for (k=0;k<BOX;k++)
|
372
|
+
for (l=0;l<BOX;l++) {
|
373
|
+
wt[j][k][l] = 0;
|
374
|
+
mr[j][k][l] = 0;
|
375
|
+
mg[j][k][l] = 0;
|
376
|
+
mb[j][k][l] = 0;
|
377
|
+
m2[j][k][l] = 0.;
|
378
|
+
}
|
379
|
+
|
380
|
+
Qadd = malloc(ImageSize * sizeof(short));
|
381
|
+
if (!Qadd) error("Not enough mem for *Qadd");
|
382
|
+
|
383
|
+
Hist3d((long *)&wt, (long *)&mr, (long *)&mg, (long *)&mb, (float *)&m2);
|
384
|
+
Momt3d((long *)&wt, (long *)&mr, (long *)&mg, (long *)&mb, (float *)&m2);
|
385
|
+
|
386
|
+
cube[0].r0 = cube[0].g0 = cube[0].b0 = 0;
|
387
|
+
cube[0].r1 = cube[0].g1 = cube[0].b1 = 32;
|
388
|
+
next = 0;
|
389
|
+
for (i = 1; i < PalSize; ++i) {
|
390
|
+
if (Cut(&cube[next], &cube[i])) {
|
391
|
+
vv[next] = (cube[next].vol > 1) ? Var(&cube[next]) : 0.0;
|
392
|
+
vv[i] = (cube[i].vol > 1) ? Var(&cube[i]) : 0.0;
|
393
|
+
} else {
|
394
|
+
vv[next] = 0.0;
|
395
|
+
i--;
|
396
|
+
}
|
397
|
+
next = 0;
|
398
|
+
temp = vv[0];
|
399
|
+
for (k = 1; k <= i; ++k)
|
400
|
+
if (vv[k] > temp) {
|
401
|
+
temp = vv[k];
|
402
|
+
next = k;
|
403
|
+
}
|
404
|
+
if (temp <= 0.0) {
|
405
|
+
PalSize = i + 1;
|
406
|
+
break;
|
407
|
+
}
|
408
|
+
}
|
409
|
+
|
410
|
+
tag = malloc(BOX * BOX * BOX);
|
411
|
+
if (!tag) error("Not enough mem for *tag");
|
412
|
+
|
413
|
+
for (k = 0; k < PalSize; ++k) {
|
414
|
+
Mark(&cube[k], k, tag);
|
415
|
+
weight = Vol(&cube[k], wt);
|
416
|
+
if (weight) {
|
417
|
+
|
418
|
+
#ifdef NOINVERT
|
419
|
+
QuantizedPalette[k*3+2] = (Vol(&cube[k], mr) / weight) WEIG;
|
420
|
+
QuantizedPalette[k*3+0] = (Vol(&cube[k], mb) / weight) WEIG;
|
421
|
+
#else
|
422
|
+
QuantizedPalette[k*3+0] = (Vol(&cube[k], mr) / weight) WEIG;
|
423
|
+
QuantizedPalette[k*3+2] = (Vol(&cube[k], mb) / weight) WEIG;
|
424
|
+
#endif
|
425
|
+
QuantizedPalette[k*3+1] = (Vol(&cube[k], mg) / weight) WEIG;
|
426
|
+
} else {
|
427
|
+
QuantizedPalette[k*3+0] =
|
428
|
+
QuantizedPalette[k*3+1] =
|
429
|
+
QuantizedPalette[k*3+2] = 0;
|
430
|
+
}
|
431
|
+
}
|
432
|
+
|
433
|
+
#ifdef VERBOSE
|
434
|
+
printf("ImageSize = %i\n", ImageSize);
|
435
|
+
#endif
|
436
|
+
for (i = 0; i < ImageSize; i++) {
|
437
|
+
Picture256[i] = tag[Qadd[i]];
|
438
|
+
}
|
439
|
+
|
440
|
+
free(tag);
|
441
|
+
free(Qadd);
|
442
|
+
|
443
|
+
return 0;
|
444
|
+
}
|
445
|
+
/* Output: QuantizedPalette[numcolors*3];
|
446
|
+
Picture256[picsize];
|
447
|
+
*/
|