pikl 0.2.8 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. data/History.txt +9 -0
  2. data/License.txt +0 -0
  3. data/Manifest.txt +17 -17
  4. data/README.txt +0 -0
  5. data/config/hoe.rb +9 -6
  6. data/config/requirements.rb +0 -0
  7. data/ext/pikl/extconf.rb +0 -0
  8. data/ext/pikl/pikl.h +617 -465
  9. data/ext/pikl/pikl_affine.c +38 -91
  10. data/ext/pikl/pikl_affine.h +0 -0
  11. data/ext/pikl/pikl_bitmap.c +0 -0
  12. data/ext/pikl/pikl_bitmap.h +0 -0
  13. data/ext/pikl/pikl_blur.c +4 -8
  14. data/ext/pikl/pikl_blur.h +0 -0
  15. data/ext/pikl/pikl_camera.c +218 -0
  16. data/ext/pikl/{pikl_effect3.h → pikl_camera.h} +2 -2
  17. data/ext/pikl/pikl_composite.c +175 -0
  18. data/ext/pikl/pikl_composite.h +12 -0
  19. data/ext/pikl/pikl_decrease.c +110 -45
  20. data/ext/pikl/pikl_decrease.h +0 -7
  21. data/ext/pikl/pikl_divide.c +116 -0
  22. data/ext/pikl/pikl_divide.h +11 -0
  23. data/ext/pikl/pikl_effect.c +583 -151
  24. data/ext/pikl/pikl_effect.h +32 -6
  25. data/ext/pikl/pikl_enhance.c +274 -0
  26. data/ext/pikl/pikl_enhance.h +20 -0
  27. data/ext/pikl/pikl_io.c +174 -23
  28. data/ext/pikl/pikl_io.h +0 -0
  29. data/ext/pikl/pikl_jpeg.c +0 -0
  30. data/ext/pikl/pikl_jpeg.h +0 -0
  31. data/ext/pikl/pikl_pattern.c +383 -357
  32. data/ext/pikl/pikl_pattern.h +0 -0
  33. data/ext/pikl/pikl_pixel.c +173 -0
  34. data/ext/pikl/{pikl_trim.h → pikl_pixel.h} +2 -2
  35. data/ext/pikl/pikl_png.c +0 -0
  36. data/ext/pikl/pikl_png.h +0 -0
  37. data/ext/pikl/pikl_private.h +12 -5
  38. data/ext/pikl/pikl_resize.c +0 -0
  39. data/ext/pikl/pikl_resize.h +0 -0
  40. data/ext/pikl/pikl_rotate.c +409 -51
  41. data/ext/pikl/pikl_rotate.h +8 -0
  42. data/ext/pikl/pikl_scrap.c +263 -483
  43. data/ext/pikl/pikl_scrap.h +0 -0
  44. data/ext/pikl/pikl_special.c +168 -0
  45. data/ext/pikl/{pikl_effect4.h → pikl_special.h} +2 -2
  46. data/ext/pikl/pikl_voronoi.c +320 -0
  47. data/ext/pikl/pikl_voronoi.h +37 -0
  48. data/lib/pikl.rb +4 -2
  49. data/lib/pikl/color.rb +47 -0
  50. data/lib/pikl/const.rb +106 -22
  51. data/lib/pikl/errors.rb +0 -0
  52. data/lib/pikl/ext.rb +115 -8
  53. data/lib/pikl/filter.rb +371 -0
  54. data/lib/pikl/image.rb +124 -117
  55. data/lib/pikl/version.rb +2 -2
  56. data/setup.rb +0 -0
  57. data/test/sample.jpg +0 -0
  58. data/test/test_helper.rb +0 -0
  59. data/test/test_pikl_image.rb +0 -14
  60. data/test/test_pikl_image2.rb +541 -0
  61. metadata +35 -23
  62. data/ext/pikl/decrease/fsdither.h +0 -554
  63. data/ext/pikl/decrease/median.c +0 -1179
  64. data/ext/pikl/decrease/median.h +0 -7
  65. data/ext/pikl/decrease/neuquan5.c +0 -563
  66. data/ext/pikl/decrease/neuquant.h +0 -62
  67. data/ext/pikl/decrease/wu.c +0 -447
  68. data/ext/pikl/decrease/wu.h +0 -7
  69. data/ext/pikl/pikl_effect2.c +0 -240
  70. data/ext/pikl/pikl_effect2.h +0 -55
  71. data/ext/pikl/pikl_effect3.c +0 -266
  72. data/ext/pikl/pikl_effect4.c +0 -495
  73. data/ext/pikl/pikl_rotate2.c +0 -312
  74. data/ext/pikl/pikl_rotate2.h +0 -19
  75. 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) */
@@ -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
- */