pikl 0.2.8 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +9 -0
- data/License.txt +0 -0
- data/Manifest.txt +17 -17
- data/README.txt +0 -0
- data/config/hoe.rb +9 -6
- data/config/requirements.rb +0 -0
- data/ext/pikl/extconf.rb +0 -0
- data/ext/pikl/pikl.h +617 -465
- data/ext/pikl/pikl_affine.c +38 -91
- data/ext/pikl/pikl_affine.h +0 -0
- data/ext/pikl/pikl_bitmap.c +0 -0
- data/ext/pikl/pikl_bitmap.h +0 -0
- data/ext/pikl/pikl_blur.c +4 -8
- data/ext/pikl/pikl_blur.h +0 -0
- data/ext/pikl/pikl_camera.c +218 -0
- data/ext/pikl/{pikl_effect3.h → pikl_camera.h} +2 -2
- data/ext/pikl/pikl_composite.c +175 -0
- data/ext/pikl/pikl_composite.h +12 -0
- data/ext/pikl/pikl_decrease.c +110 -45
- data/ext/pikl/pikl_decrease.h +0 -7
- data/ext/pikl/pikl_divide.c +116 -0
- data/ext/pikl/pikl_divide.h +11 -0
- data/ext/pikl/pikl_effect.c +583 -151
- data/ext/pikl/pikl_effect.h +32 -6
- data/ext/pikl/pikl_enhance.c +274 -0
- data/ext/pikl/pikl_enhance.h +20 -0
- data/ext/pikl/pikl_io.c +174 -23
- data/ext/pikl/pikl_io.h +0 -0
- data/ext/pikl/pikl_jpeg.c +0 -0
- data/ext/pikl/pikl_jpeg.h +0 -0
- data/ext/pikl/pikl_pattern.c +383 -357
- data/ext/pikl/pikl_pattern.h +0 -0
- data/ext/pikl/pikl_pixel.c +173 -0
- data/ext/pikl/{pikl_trim.h → pikl_pixel.h} +2 -2
- data/ext/pikl/pikl_png.c +0 -0
- data/ext/pikl/pikl_png.h +0 -0
- data/ext/pikl/pikl_private.h +12 -5
- data/ext/pikl/pikl_resize.c +0 -0
- data/ext/pikl/pikl_resize.h +0 -0
- data/ext/pikl/pikl_rotate.c +409 -51
- data/ext/pikl/pikl_rotate.h +8 -0
- data/ext/pikl/pikl_scrap.c +263 -483
- data/ext/pikl/pikl_scrap.h +0 -0
- data/ext/pikl/pikl_special.c +168 -0
- data/ext/pikl/{pikl_effect4.h → pikl_special.h} +2 -2
- data/ext/pikl/pikl_voronoi.c +320 -0
- data/ext/pikl/pikl_voronoi.h +37 -0
- data/lib/pikl.rb +4 -2
- data/lib/pikl/color.rb +47 -0
- data/lib/pikl/const.rb +106 -22
- data/lib/pikl/errors.rb +0 -0
- data/lib/pikl/ext.rb +115 -8
- data/lib/pikl/filter.rb +371 -0
- data/lib/pikl/image.rb +124 -117
- data/lib/pikl/version.rb +2 -2
- data/setup.rb +0 -0
- data/test/sample.jpg +0 -0
- data/test/test_helper.rb +0 -0
- data/test/test_pikl_image.rb +0 -14
- data/test/test_pikl_image2.rb +541 -0
- metadata +35 -23
- data/ext/pikl/decrease/fsdither.h +0 -554
- data/ext/pikl/decrease/median.c +0 -1179
- data/ext/pikl/decrease/median.h +0 -7
- data/ext/pikl/decrease/neuquan5.c +0 -563
- data/ext/pikl/decrease/neuquant.h +0 -62
- data/ext/pikl/decrease/wu.c +0 -447
- data/ext/pikl/decrease/wu.h +0 -7
- data/ext/pikl/pikl_effect2.c +0 -240
- data/ext/pikl/pikl_effect2.h +0 -55
- data/ext/pikl/pikl_effect3.c +0 -266
- data/ext/pikl/pikl_effect4.c +0 -495
- data/ext/pikl/pikl_rotate2.c +0 -312
- data/ext/pikl/pikl_rotate2.h +0 -19
- data/ext/pikl/pikl_trim.c +0 -28
@@ -1,62 +0,0 @@
|
|
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) */
|
data/ext/pikl/decrease/wu.c
DELETED
@@ -1,447 +0,0 @@
|
|
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
|
-
*/
|