pikl 0.2.8-x86-mswin32 → 0.3.0-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/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/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/pikl.dll +0 -0
- 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
|
-
*/
|