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
@@ -0,0 +1,11 @@
1
+ #ifndef _LIB_PIKL_DIVIDE_
2
+ #define _LIB_PIKL_DIVIDE_
3
+
4
+ #include <stdio.h>
5
+ #include <stdlib.h>
6
+ #include <string.h>
7
+
8
+ #include "pikl.h"
9
+ #include "pikl_private.h"
10
+
11
+ #endif
@@ -1,203 +1,540 @@
1
1
  #include "pikl_effect.h"
2
2
 
3
- //=================================================================================
4
- // pkl_unsharp
5
- //=================================================================================
6
- PKLExport int pkl_unsharp(PKLImage pkl, int threshold, double edge)
3
+ //=============================================================================
4
+ // pkl_invert
5
+ //=============================================================================
6
+ PKLExport int pkl_invert(PKLImage pkl)
7
7
  {
8
- int i, j, p, q, k;
9
- int cnt, value, stock[PKL_CHANNEL];
10
- unsigned char *wrk, *s;
11
-
12
- wrk = malloc(pkl->height * pkl->width * pkl->channel);
8
+ int i;
9
+ for(i=0; i<pkl->height*pkl->width*pkl->channel; i++)
10
+ pkl->image[i] ^= 0xff;
11
+ return(0);
12
+ }
13
+
14
+ //=============================================================================
15
+ // pkl_sepia
16
+ //=============================================================================
17
+ PKLExport int pkl_sepia(PKLImage pkl, double red_weight, double green_weight, double blue_weight)
18
+ {
19
+ unsigned char *wrk;
20
+ int i, j, color;
21
+
22
+ if(pkl->color!=PKL_RGB) return(1);
23
+
24
+ wrk = malloc(pkl->width*pkl->height*pkl->channel);
13
25
  if(!wrk) return(1);
14
- memset(wrk, 0, pkl->height * pkl->width * pkl->channel);
26
+ memset(wrk, 0, pkl->width*pkl->height*pkl->channel);
15
27
 
16
28
  for(i=0; i<pkl->height; i++){
17
29
  for(j=0; j<pkl->width; j++){
18
- cnt = 0;
19
- memset(stock, 0, sizeof(stock));
30
+ color = ((pkl->image[(i*pkl->width+j)*pkl->channel+0]+
31
+ pkl->image[(i*pkl->width+j)*pkl->channel+1]+
32
+ pkl->image[(i*pkl->width+j)*pkl->channel+2]) / 3);
20
33
 
21
- for(p=-RADIUS; p<=RADIUS; p++){
22
- for(q=-RADIUS; q<=RADIUS; q++){
23
- if(j+q>=0 && j+q<pkl->width && i+p>=0 && i+p<pkl->height){
24
- for(k=0; k<pkl->channel; k++) stock[k] += pkl->image[((i+p)*pkl->width+(j+q))*pkl->channel+k];
25
- cnt++;
34
+ wrk[(i*pkl->width+j)*pkl->channel+0] = PKL_COLOR_CLIP(color*red_weight);
35
+ wrk[(i*pkl->width+j)*pkl->channel+1] = PKL_COLOR_CLIP(color*green_weight);
36
+ wrk[(i*pkl->width+j)*pkl->channel+2] = PKL_COLOR_CLIP(color*blue_weight);
37
+ }
38
+ }
39
+
40
+ free(pkl->image);
41
+ pkl->image = wrk;
42
+ return(0);
43
+ }
44
+
45
+ //=============================================================================
46
+ // pkl_oilpaint
47
+ //=============================================================================
48
+ PKLExport int pkl_oilpaint(PKLImage pkl, int weight)
49
+ {
50
+ int color[PKL_COLOR], gray;
51
+ int i, j, k, max, s, t, sx, sy, tx, ty;
52
+ unsigned char *wrk;
53
+
54
+ wrk = malloc(pkl->width*pkl->height*pkl->channel);
55
+ if(!wrk) return(1);
56
+ memset(wrk, 0, pkl->width*pkl->height*pkl->channel);
57
+
58
+ for(i=0; i<pkl->width*pkl->height*pkl->channel; i+=pkl->channel){
59
+ gray=0;
60
+ for(k=0; k<pkl->channel; k++)
61
+ gray += pkl->image[i+k];
62
+ wrk[i] = PKL_COLOR_CLIP(gray/pkl->channel);
63
+ }
64
+
65
+ //get histgram
66
+ memset(color, 0, sizeof(int)*PKL_COLOR);
67
+ for(i=0; i<pkl->height*pkl->width; i+=pkl->channel) color[wrk[i]]++;
68
+
69
+ //���Ӄs�N�Z������ŕp�F��I��
70
+ for(i=0; i<pkl->height; i++){
71
+ for(j=0; j<pkl->width; j++){
72
+ max = 0;
73
+ tx=j;
74
+ ty=i;
75
+ for(s=0; s<weight; s++){
76
+ for(t=0; t<weight; t++){
77
+ sx = (t+j >= pkl->width) ? pkl->width-1 : t+j;
78
+ sy = (s+i >= pkl->height) ? pkl->height-1 : s+i;
79
+ if(max<color[wrk[(sy*pkl->width+sx)*pkl->channel]]){
80
+ max = color[wrk[(sy*pkl->width+sx)*pkl->channel]];
81
+ tx = sx;
82
+ ty = sy;
26
83
  }
27
84
  }
28
85
  }
29
- s = &wrk[(i * pkl->width + j) * pkl->channel];
30
- for(k=0; k<pkl->channel; k++)
31
- *s++ = stock[k] / cnt;
86
+ //�I���W�i���̐F��K�p
87
+ memcpy(&wrk[(i*pkl->width+j)*pkl->channel], &pkl->image[(ty*pkl->width+tx)*pkl->channel], pkl->channel);
32
88
  }
33
89
  }
34
90
 
35
- for(i=0; i<pkl->height*pkl->width*pkl->channel; i++){
36
- value = abs(pkl->image[i]-wrk[i])<threshold ? pkl->image[i] : pkl->image[i]+(pkl->image[i]-wrk[i])*edge;
37
- pkl->image[i] = PKL_COLOR_CLIP(value);
91
+ free(pkl->image);
92
+ pkl->image = wrk;
93
+ return(0);
94
+ }
95
+
96
+ //=============================================================================
97
+ // pkl_noise
98
+ //=============================================================================
99
+ PKLExport int pkl_noise(PKLImage pkl, int noise)
100
+ {
101
+ unsigned char *wrk;
102
+ int i, j, k, sx, sy, nw, nh;
103
+
104
+ wrk = malloc(pkl->width*pkl->height*pkl->channel);
105
+ if(!wrk) return(1);
106
+ memset(wrk, 0, pkl->width*pkl->height*pkl->channel);
107
+
108
+ #ifdef WIN32
109
+ srand(1);
110
+ #else
111
+ srand48(1);
112
+ #endif
113
+ for(i=0; i<pkl->height; i++){
114
+ for(j=0; j<pkl->width; j++){
115
+ //nw = rand()%(noise*2+1)-noise;
116
+ #ifdef WIN32
117
+ nw = rand()%(noise*2+1)-noise;
118
+ nh = rand()%(noise*2+1)-noise;
119
+ #else
120
+ nw = lrand48()%(noise*2+1)-noise;
121
+ nh = lrand48()%(noise*2+1)-noise;
122
+ #endif
123
+ sx = j+nw<0 ? 0 : j+nw>=pkl->width ? pkl->width-1 : j+nw;
124
+ sy = i+nh<0 ? 0 : i+nh>=pkl->height ? pkl->height-1 : i+nh;
125
+ for(k=0; k<pkl->channel; k++)
126
+ wrk[(i*pkl->width+j)*pkl->channel+k] = pkl->image[(sy*pkl->width+sx)*pkl->channel+k];
127
+ }
38
128
  }
39
- free(wrk);
129
+
130
+ free(pkl->image);
131
+ pkl->image = wrk;
40
132
  return(0);
41
133
  }
42
134
 
43
- //=================================================================================
44
- // pkl_contrast
45
- //=================================================================================
46
- PKLExport int pkl_contrast(PKLImage pkl, int rate)
135
+ //=============================================================================
136
+ // pkl_vtr
137
+ //=============================================================================
138
+ PKLExport int pkl_vtr(PKLImage pkl, int colspace, int gst, int cst)
47
139
  {
48
- unsigned char ct[PKL_COLOR];
49
- int value, i;
140
+ unsigned char *wrk;
141
+ int i, j, k, t;
142
+ int h=0, l_det=0;
50
143
 
51
- if(rate < -127 || rate > 127) return(1);
144
+ wrk = malloc(pkl->width*pkl->height*pkl->channel);
145
+ if(!wrk) return(1);
146
+ memset(wrk, 0, pkl->width*pkl->height*pkl->channel);
52
147
 
53
- if(rate < 0.0){
54
- //�d�݂������̎��͒����I�ɕ��R��
55
- for(i=0; i<PKL_COLOR; i++){
56
- value = i + (i-127) * rate/127;
57
- ct[i] = PKL_COLOR_CLIP(value);
148
+ for(i=0; i<pkl->height; i++){
149
+ if(l_det >= colspace){
150
+ h = !h;
151
+ l_det=0;
58
152
  }
59
- }else{
60
- //�d�݂������̎��͎��g��
61
- for(i=0; i<PKL_COLOR; i++){
62
- value = i - rate*rate/127 * sin(M_PI/2+M_PI*i/255);
63
- ct[i] = PKL_COLOR_CLIP(value);
153
+ l_det++;
154
+
155
+ for(j=0; j<pkl->width; j++){
156
+ t = j+gst<0 ? 0 : j+gst>=pkl->width ? pkl->width-1 : j+gst;
157
+ for(k=0; k<pkl->channel; k++)
158
+ wrk[(i*pkl->width+j)*pkl->channel+k] =
159
+ PKL_COLOR_CLIP((pkl->image[(i*pkl->width+j)*pkl->channel+k] +
160
+ pkl->image[(i*pkl->width+t)*pkl->channel+k])/2 + (cst-127)*h);
64
161
  }
65
162
  }
66
163
 
67
- for(i=0; i<pkl->width*pkl->height*pkl->channel; i++)
68
- pkl->image[i] = ct[pkl->image[i]];
69
-
164
+ free(pkl->image);
165
+ pkl->image = wrk;
70
166
  return(0);
71
167
  }
72
168
 
73
- //=================================================================================
74
- // pkl_level def=0.0050
75
- //=================================================================================
76
- PKLExport int pkl_level(PKLImage pkl, double low, double high, double coeff)
169
+ //=============================================================================
170
+ // pkl_edgepaint
171
+ //=============================================================================
172
+ PKLExport int pkl_edgepaint(PKLImage pkl, int edge)
77
173
  {
78
- PKL_HISTGRAM hst[PKL_CHANNEL];
79
- int i, j, cnt, value;
80
-
81
- if((low < 0.0 && low > 100.0) ||
82
- (high < 0.0 && high > 100.0) ||
83
- (coeff< 0.0 && coeff> 2.0)) return(1);
174
+ unsigned char *wrk;
175
+ int i, j, s, t, k, color, clipx, clipy, gray;
176
+ const int filter[9] = { -1, -1, -1,
177
+ -1, 8, -1,
178
+ -1, -1, -1};
84
179
 
85
- memset(&hst, 0, sizeof(hst));
86
- for(i=0; i<pkl->height*pkl->width; i++){
87
- for(j=0; j<pkl->channel; j++){
88
- hst[j].data[ pkl->image[i*pkl->channel+j] ]++;
89
- }
180
+ wrk = malloc(pkl->width*pkl->height);
181
+ if(!wrk) return(1);
182
+
183
+ /* convert grayscale */
184
+ for(i=0; i<pkl->width*pkl->height; i++){
185
+ gray=0;
186
+ for(k=0; k<pkl->channel; k++)
187
+ gray += pkl->image[i*pkl->channel+k];
188
+ wrk[i] = PKL_COLOR_CLIP(gray/pkl->channel);
90
189
  }
91
190
 
92
- for(i=0; i<pkl->channel; i++){
93
- cnt=0;
94
- for(j=0; j<PKL_COLOR; j++){
95
- cnt += hst[i].data[j];
96
- if(cnt > low/100*pkl->height*pkl->width){
97
- hst[i].min = j;
98
- break;
191
+ for(i=0; i<pkl->height; i++){
192
+ for(j=0; j<pkl->width; j++){
193
+ color=0;
194
+ for(s=0; s<3; s++){
195
+ for(t=0; t<3; t++){
196
+ clipx = (j+t)>=pkl->width ? pkl->width-1 : j+t;
197
+ clipy = (i+s)>=pkl->height ? pkl->height-1 : i+s;
198
+ color += wrk[clipy*pkl->width+clipx] * filter[t+s*3];
199
+ }
99
200
  }
100
- }
101
- cnt=0;
102
- for(j=PKL_COLOR-1; j>=0; j--){
103
- cnt += hst[i].data[j];
104
- if(cnt > high/100*pkl->height*pkl->width){
105
- hst[i].max = j;
106
- break;
201
+ if(color>0){
202
+ //memset(&pkl->image[(i*pkl->width+j)*pkl->channel], 0, pkl->channel);
203
+ for(s=0; s<edge; s++){
204
+ for(t=0; t<edge; t++){
205
+ clipx = (j+t)>=pkl->width ? pkl->width-1 : j+t;
206
+ clipy = (i+s)>=pkl->height ? pkl->height-1 : i+s;
207
+ memset(&pkl->image[(clipy*pkl->width+clipx)*pkl->channel], 0, pkl->channel);
208
+ }
209
+ }
107
210
  }
108
211
  }
109
212
  }
213
+ free(wrk);
214
+ return(0);
215
+ }
110
216
 
111
- for(i=0; i<pkl->width*pkl->height; i++){
112
- for(j=0; j<pkl->channel; j++){
113
- value = ((coeff * pkl->image[i*pkl->channel+j])-hst[j].min)/(hst[j].max-hst[j].min) * 255;
114
- pkl->image[i*pkl->channel+j] = PKL_COLOR_CLIP(value);
217
+ //=============================================================================
218
+ // pkl_kuwahara
219
+ //=============================================================================
220
+ PKLExport int pkl_kuwahara(PKLImage pkl, int range)
221
+ {
222
+ unsigned char *wrk, *p;
223
+ int i, j, k, count, tr, t, tx, ty, clipx, clipy;
224
+ int value[4], mincolor, idx, total[PKL_CHANNEL];
225
+ struct { int sx, sy, ex, ey; } r[4]; //rect
226
+ unsigned char max_color[PKL_CHANNEL], min_color[PKL_CHANNEL], c;
227
+
228
+ if(range<=1) return(0);
229
+
230
+ wrk = malloc(pkl->width*pkl->height*pkl->channel);
231
+ if(!wrk) return(1);
232
+ memset(wrk, 0, pkl->width*pkl->height*pkl->channel);
233
+
234
+ //�̈�̃s�N�Z����
235
+ count = range*range;
236
+ tr = range-1;
237
+
238
+ for(i=0; i<pkl->height; i++){
239
+ for(j=0; j<pkl->width; j++){
240
+ /* �J�����g�s�N�Z���𒆐S��4�‚̗̈�ɕ����� */
241
+ //����(0)
242
+ r[0].sx = j-tr;
243
+ r[0].sy = i-tr;
244
+ r[0].ex = j;
245
+ r[0].ey = i;
246
+ //�E��(1)
247
+ r[1].sx = j;
248
+ r[1].sy = i-tr;
249
+ r[1].ex = j+tr;
250
+ r[1].ey = i;
251
+ //�E��(2)
252
+ r[2].sx = j;
253
+ r[2].sy = i;
254
+ r[2].ex = j+tr;
255
+ r[2].ey = i+tr;
256
+ //����(3)
257
+ r[3].sx = j-tr;
258
+ r[3].sy = i;
259
+ r[3].ex = j;
260
+ r[3].ey = i+tr;
261
+
262
+ /* �e�̈�Ŋe�F�̍ő�l�ƍŏ��l�̍���ݐς��� */
263
+ memset(value, 0, sizeof(value));
264
+ for(t=0; t<4; t++){
265
+ memset(max_color, 0x00, PKL_CHANNEL);
266
+ memset(min_color, 0xff, PKL_CHANNEL);
267
+ for(ty=r[t].sy; ty<=r[t].ey; ty++){
268
+ for(tx=r[t].sx; tx<=r[t].ex; tx++){
269
+ clipx = tx<0 ? 0 : tx>=pkl->width ? pkl->width-1 : tx;
270
+ clipy = ty<0 ? 0 : ty>=pkl->height ? pkl->height-1 : ty;
271
+ p = &pkl->image[(clipy*pkl->width+clipx)*pkl->channel];
272
+ for(k=0; k<pkl->channel; k++){
273
+ c = *p++;
274
+ max_color[k] = (c > max_color[k]) ? c : max_color[k];
275
+ min_color[k] = (c < min_color[k]) ? c : min_color[k];
276
+ }
277
+ }
278
+ }
279
+
280
+ for(k=0; k<pkl->channel; k++)
281
+ value[t] += (max_color[k] - min_color[k]);
282
+ }
283
+
284
+ /* �e�̈�ōł��F�̍������������̈��I������ */
285
+ mincolor = value[0];
286
+ idx = 0;
287
+ for(t=1; t<4; t++){
288
+ if(value[t]<mincolor){
289
+ mincolor = value[t];
290
+ idx = t;
291
+ }
292
+ }
293
+
294
+ /* �I�����ꂽ�̈�̐F�̕��ς��s�N�Z���ɓK�p���� */
295
+ memset(total, 0, sizeof(total));
296
+ for(ty=r[idx].sy; ty<=r[idx].ey; ty++){
297
+ for(tx=r[idx].sx; tx<=r[idx].ex; tx++){
298
+ clipx = tx<0 ? 0 : tx>=pkl->width ? pkl->width-1 : tx;
299
+ clipy = ty<0 ? 0 : ty>=pkl->height ? pkl->height-1 : ty;
300
+ p = &pkl->image[(clipy*pkl->width+clipx)*pkl->channel];
301
+ for(k=0; k<pkl->channel; k++)
302
+ total[k] += *p++;
303
+ }
304
+ }
305
+ p =&wrk[(i*pkl->width+j)*pkl->channel];
306
+ for(k=0; k<pkl->channel; k++)
307
+ *p++ = PKL_COLOR_CLIP(total[k]/count);
115
308
  }
116
309
  }
117
310
 
311
+ free(pkl->image);
312
+ pkl->image = wrk;
118
313
  return(0);
119
314
  }
120
315
 
121
316
  //=============================================================================
122
- // pkl_brightness
317
+ // pkl_edge
123
318
  //=============================================================================
124
- PKLExport int pkl_brightness(PKLImage pkl, int color)
319
+ PKLExport int pkl_edge(PKLImage pkl, int threshold)
125
320
  {
126
- int i;
127
- for(i=0; i<pkl->width*pkl->height*pkl->channel; i++){
128
- pkl->image[i] = PKL_COLOR_CLIP(pkl->image[i] + color);
321
+ unsigned char *wrk, *p;
322
+ int i, j, k, color[PKL_CHANNEL], total;
323
+ int r1, r2, r3;
324
+
325
+ wrk = malloc(pkl->width*pkl->height*pkl->channel);
326
+ if(!wrk) return(1);
327
+ memset(wrk, 0xff, pkl->width*pkl->height*pkl->channel);
328
+
329
+ r3 = sqrt((double)pkl->channel);
330
+
331
+ for(i=0; i<pkl->height; i++){
332
+ r1=r2=0;
333
+ for(j=0; j<pkl->width; j++){
334
+ //x����
335
+ if(j+1 < pkl->width){
336
+ p = &pkl->image[(i*pkl->width+j)*pkl->channel];
337
+ for(k=0; k<pkl->channel; k++){
338
+ color[k] = *p - *(p+pkl->channel);
339
+ color[k] *= color[k];
340
+ p++;
341
+ }
342
+ total=0;
343
+ for(k=0; k<pkl->channel; k++)
344
+ total += color[k];
345
+ r1 = sqrt(total)/r3;
346
+ }
347
+
348
+ //y����
349
+ if(i+1 < pkl->height){
350
+ p = &pkl->image[(i*pkl->width+j)*pkl->channel];
351
+ for(k=0; k<pkl->channel; k++){
352
+ color[k] = *p - *(p+pkl->width*pkl->channel);
353
+ color[k] *= color[k];
354
+ p++;
355
+ }
356
+ total=0;
357
+ for(k=0; k<pkl->channel; k++)
358
+ total += color[k];
359
+ r2 = sqrt(total)/r3;
360
+ }
361
+
362
+ p = &wrk[(i*pkl->width+j)*pkl->channel];
363
+ if(r1>=threshold || r2>=threshold)
364
+ for(k=0; k<pkl->channel; k++) *p++=0;
365
+ }
129
366
  }
367
+ free(pkl->image);
368
+ pkl->image = wrk;
130
369
  return(0);
131
370
  }
132
371
 
133
372
  //=============================================================================
134
- // pkl_hls
373
+ // pkl_dither
135
374
  //=============================================================================
136
- PKLExport int pkl_hls(PKLImage pkl, double ym, double sm, double hd)
375
+ PKLExport int pkl_dither(PKLImage pkl, PKL_DITHER dither)
137
376
  {
138
- int i;
139
- double c1, c2; //�F�M��
140
- double y, s, h; //y=�P�x, s=�ʓx, h=�F��
377
+ double FloydSteinberg[2][3] = {
378
+ { -1, -1, 7.0/16.0},
379
+ { 3.0/16.0, 5.0/16.0, 1.0/16.0} };
141
380
 
142
- if(pkl->color != PKL_RGB) return(1);
381
+ double Stucci[3][5] = {
382
+ { -1, -1, -1, 8.0/42.0, 4.0/42.0},
383
+ {2.0/42.0, 4.0/42.0, 8.0/42.0, 4.0/42.0, 2.0/42.0},
384
+ {1.0/42.0, 2.0/42.0, 4.0/42.0, 2.0/42.0, 1.0/42.0} };
385
+
386
+ double Sierra[3][5] = {
387
+ { -1, -1, -1, 5.0/32.0, 3.0/32.0},
388
+ {2.0/32.0, 4.0/32.0, 5.0/32.0, 4.0/32.0, 2.0/32.0},
389
+ { -1, 2.0/32.0, 3.0/32.0, 2.0/32.0, -1} };
390
+
391
+ double JaJuNi[3][5] = {
392
+ { -1, -1, -1, 7.0/48.0, 5.0/48.0},
393
+ {3.0/48.0, 5.0/48.0, 7.0/48.0, 5.0/48.0, 3.0/48.0},
394
+ {1.0/48.0, 3.0/48.0, 5.0/48.0, 3.0/48.0, 1.0/48.0} };
395
+
396
+ unsigned char *wrk, pix;
397
+ double *pt, err;
398
+ int i, j, k, gray, s, t, tx, ty, row, col, xrange;
143
399
 
144
- for(i=0; i<pkl->width*pkl->height; i++){
145
- /* �P�x,�F�M��1,2 */
146
- y = 0.299 * pkl->image[i*pkl->channel] +
147
- 0.587 * pkl->image[i*pkl->channel+1] +
148
- 0.114 * pkl->image[i*pkl->channel+2];
149
- c1 = pkl->image[i*pkl->channel] - y;
150
- c2 = pkl->image[i*pkl->channel+2] - y;
151
-
152
- /* �ʓx */
153
- s = sqrt(c1*c1 + c2*c2);
154
-
155
- /* �F�� */
156
- if(s < 0.0) h = 0.0;
157
- else h = atan2(c1, c2) * 180.0 / M_PI;
158
-
159
- /* ������������ */
160
- y *= (1 + ym);
161
- s *= (1 + sm);
162
- h += hd;
163
-
164
- /* �����l����RGB�ɖ߂� */
165
- c1 = s * sin(M_PI * h / 180.0);
166
- c2 = s * cos(M_PI * h / 180.0);
400
+ wrk = malloc(pkl->width*pkl->height*pkl->channel);
401
+ if(!wrk) return(1);
402
+
403
+ //�f�B�U�p�^����I��
404
+ switch(dither){
405
+ case PKL_DITHER_STUCCI:
406
+ row = 5;
407
+ col = 3;
408
+ pt = &(Stucci[0][0]);
409
+ break;
410
+
411
+ case PKL_DITHER_SIERRA:
412
+ row = 5;
413
+ col = 3;
414
+ pt = &(Sierra[0][0]);
415
+ break;
416
+
417
+ case PKL_DITHER_JAJUNI:
418
+ row = 5;
419
+ col = 3;
420
+ pt = &(JaJuNi[0][0]);
421
+ break;
422
+
423
+ case PKL_DITHER_FLOYDSTEINBERG:
424
+ default:
425
+ row = 3;
426
+ col = 2;
427
+ pt = &(FloydSteinberg[0][0]);
428
+ }
429
+
430
+ for(i=0; i<pkl->height; i++){
431
+ for(j=0; j<pkl->width; j++){
432
+ gray=0;
433
+ for(k=0; k<pkl->channel; k++)
434
+ gray += pkl->image[(i*pkl->width+j)*pkl->channel+k];
435
+ pkl->image[(i*pkl->width+j)*pkl->channel] = PKL_COLOR_CLIP(gray/pkl->channel);
436
+ }
437
+ }
438
+
439
+ xrange = (row-1)/2;
440
+
441
+ for(i=0; i<pkl->height; i++){
442
+ for(j=0; j<pkl->width; j++){
443
+ pix = pkl->image[(i*pkl->width+j)*pkl->channel];
444
+ if(pix>127)
445
+ memset(&wrk[(i*pkl->width+j)*pkl->channel], 0xff, pkl->channel);
446
+ else
447
+ memset(&wrk[(i*pkl->width+j)*pkl->channel], 0x00, pkl->channel);
448
+ err = pix>127 ? pix-255 : pix;
167
449
 
168
- pkl->image[i*pkl->channel] = PKL_COLOR_CLIP(c1 + y);
169
- pkl->image[i*pkl->channel+1] = PKL_COLOR_CLIP(y - (0.299*c1 + 0.114*c2)/0.587);
170
- pkl->image[i*pkl->channel+2] = PKL_COLOR_CLIP(c2 + y);
450
+ for(s=0; s<col; s++){
451
+ for(t=-xrange; t<=xrange; t++){
452
+ tx = j+t;
453
+ ty = i+s;
454
+ if(tx<0 || tx>=pkl->width || ty>=pkl->height) continue;
455
+ if (pt[s*row+t+xrange] < 0) continue;
456
+
457
+ pkl->image[(ty*pkl->width+tx)*pkl->channel] =
458
+ PKL_COLOR_CLIP(pkl->image[(ty*pkl->width+tx)*pkl->channel] + err * pt[s*row+t+xrange]);
459
+ }
460
+ }
461
+ }
171
462
  }
463
+
464
+ free(pkl->image);
465
+ pkl->image = wrk;
172
466
  return(0);
173
467
  }
174
468
 
175
- //=================================================================================
176
- // pkl_gamma
177
- //=================================================================================
178
- PKLExport int pkl_gamma(PKLImage pkl, double gm)
469
+ //=============================================================================
470
+ // pkl_colordither
471
+ //=============================================================================
472
+ PKLExport int pkl_colordither(PKLImage pkl, int weight)
179
473
  {
180
- unsigned char gt[PKL_COLOR];
181
- int i;
474
+ double FloydSteinberg[2][3] = {
475
+ { -1, -1, 7.0/16.0},
476
+ { 3.0/16.0, 5.0/16.0, 1.0/16.0} };
477
+ unsigned char *wrk, pix, *graypic;
478
+ double *pt, err;
479
+ int i, j, k, gray, s, t, tx, ty, row, col, xrange;
182
480
 
183
- if(gm < 0.0) return(1);
481
+ row = 3;
482
+ col = 2;
483
+ pt = &(FloydSteinberg[0][0]);
184
484
 
185
- for(i=0; i<PKL_COLOR; i++)
186
- gt[i] = PKL_COLOR_CLIP(255.0 * pow(i/255.0, 1.0/gm));
187
-
188
- for(i=0; i<pkl->width*pkl->height*pkl->channel; i++)
189
- pkl->image[i] = gt[pkl->image[i]];
485
+ wrk = malloc(pkl->width*pkl->height*pkl->channel);
486
+ if(!wrk) return(1);
487
+ memset(wrk, 0xff, pkl->width*pkl->height*pkl->channel);
488
+
489
+ graypic = malloc(pkl->width*pkl->height);
490
+ if(!graypic) return(1);
190
491
 
492
+ for(i=0; i<pkl->height; i++){
493
+ for(j=0; j<pkl->width; j++){
494
+ gray=0;
495
+ for(k=0; k<pkl->channel; k++)
496
+ gray += pkl->image[(i*pkl->width+j)*pkl->channel+k];
497
+ graypic[i*pkl->width+j] = PKL_COLOR_CLIP(gray/pkl->channel);
498
+ }
499
+ }
500
+ xrange = (row-1)/2;
501
+
502
+ for(i=0; i<pkl->height; i++){
503
+ for(j=0; j<pkl->width; j++){
504
+ pix = graypic[i*pkl->width+j];
505
+ if(pix<127){
506
+ memcpy(&wrk[(i*pkl->width+j)*pkl->channel], &pkl->image[(i*pkl->width+j)*pkl->channel], pkl->channel);
507
+ }else{
508
+ for(k=0; k<pkl->channel; k++)
509
+ wrk[(i*pkl->width+j)*pkl->channel+k] = PKL_COLOR_CLIP(pkl->image[(i*pkl->width+j)*pkl->channel+k]+weight);
510
+ }
511
+ err = pix>127 ? pix-255 : pix;
512
+
513
+ for(s=0; s<col; s++){
514
+ for(t=-xrange; t<=xrange; t++){
515
+ tx = j+t;
516
+ ty = i+s;
517
+ if(tx<0 || tx>=pkl->width || ty>=pkl->height) continue;
518
+ if (pt[s*row+t+xrange] < 0) continue;
519
+ graypic[ty*pkl->width+tx] = PKL_COLOR_CLIP(graypic[ty*pkl->width+tx] + err * pt[s*row+t+xrange]);
520
+ }
521
+ }
522
+ }
523
+ }
524
+ free(graypic);
525
+ free(pkl->image);
526
+ pkl->image = wrk;
191
527
  return(0);
192
528
  }
193
529
 
194
530
  //=============================================================================
195
- // pkl_noisecut(median filter)
531
+ // pkl_contour
196
532
  //=============================================================================
197
- PKLExport int pkl_noisecut(PKLImage pkl)
533
+ PKLExport int pkl_contour(PKLImage pkl)
198
534
  {
199
- unsigned char *wrk, *p, sort[PKL_CHANNEL][9], median[PKL_CHANNEL];
200
- int i, j, tx, ty, k, clipx, clipy, rd, s, t, n;
535
+ double dd=1.732;
536
+ int i, j, k, s, ix[4], iy[4], dis[4], max;
537
+ unsigned char *wrk, p, q;
201
538
 
202
539
  wrk = malloc(pkl->width*pkl->height*pkl->channel);
203
540
  if(!wrk) return(1);
@@ -205,31 +542,74 @@ PKLExport int pkl_noisecut(PKLImage pkl)
205
542
 
206
543
  for(i=0; i<pkl->height; i++){
207
544
  for(j=0; j<pkl->width; j++){
208
- rd=0;
209
- for(ty=-1; ty<=1; ty++){
210
- for(tx=-1; tx<=1; tx++){
211
- clipx = j+tx < 0 ? 0 : j+tx>=pkl->width ? pkl->width-1 : j+tx;
212
- clipy = i+ty < 0 ? 0 : i+ty>=pkl->height ? pkl->height-1 : i+ty;
213
- p = &pkl->image[(clipy*pkl->width+clipx)*pkl->channel];
214
- for(k=0; k<pkl->channel; k++)
215
- sort[k][rd] = *p++;
216
- rd++;
545
+ ix[0]=j+1; iy[0]=i-1; //�E��
546
+ ix[1]=j+1; iy[1]=i; //�E
547
+ ix[2]=j+1; iy[2]=i+1; //�E��
548
+ ix[3]=j; iy[3]=i+1; //��
549
+
550
+ for(s=0; s<4; s++){
551
+ dis[s]=0;
552
+ if(ix[s]>=0 && ix[s]<pkl->width && iy[s]>=0 && iy[s]<pkl->height){
553
+ for(k=0; k<pkl->channel; k++){
554
+ p = pkl->image[(i*pkl->width+j)*pkl->channel+k];
555
+ q = pkl->image[(iy[s]*pkl->width+ix[s])*pkl->channel+k];
556
+ dis[s] += ((q-p) * (q-p));
557
+ }
217
558
  }
218
559
  }
219
- //�����l�T��
220
- for(k=0; k<pkl->channel; k++){
221
- for(s=0; s<5; s++){
222
- for(t=1,n=0,median[k]=sort[k][0]; t<9; t++){
223
- if(median[k]<sort[k][t]){
224
- median[k]=sort[k][t];
225
- n=t;
226
- }
227
- }
228
- sort[k][n]=0;
560
+ max=0;
561
+ for(s=0; s<4; s++)
562
+ if(dis[s]>max) max=dis[s];
563
+
564
+ for(k=0; k<pkl->channel; k++)
565
+ wrk[(i*pkl->width+j)*pkl->channel+k] = PKL_COLOR_CLIP(255-sqrt((double)max)/dd);
566
+ }
567
+ }
568
+
569
+ free(pkl->image);
570
+ pkl->image = wrk;
571
+ return(0);
572
+ }
573
+
574
+ //=============================================================================
575
+ // pkl_focus
576
+ //=============================================================================
577
+ PKLExport int pkl_focus(PKLImage pkl, PKL_FOCUS type)
578
+ {
579
+ unsigned char *wrk;
580
+ int i, j, s, t, k, clipx, clipy, weight=1;
581
+ int *matrix, color[PKL_CHANNEL];
582
+
583
+ //select filter
584
+ matrix=focus_filter[0].matrix;
585
+ for(i=0; i<sizeof(focus_filter)/sizeof(struct PKL_FILTER); i++){
586
+ if(type==focus_filter[i].type){
587
+ matrix=focus_filter[i].matrix;
588
+ break;
589
+ }
590
+ }
591
+
592
+ for(i=0; i<9; i++)
593
+ weight += matrix[i];
594
+
595
+ wrk = malloc(pkl->width*pkl->height*pkl->channel);
596
+ if(!wrk) return(1);
597
+ memset(wrk, 0, pkl->width*pkl->height*pkl->channel);
598
+
599
+ for(i=0; i<pkl->height; i++){
600
+ for(j=0; j<pkl->width; j++){
601
+ memset(color, 0, sizeof(color));
602
+ for(s=0; s<3; s++){
603
+ for(t=0; t<3; t++){
604
+ clipx = (j+t)>=pkl->width ? pkl->width-1 : j+t;
605
+ clipy = (i+s)>=pkl->height ? pkl->height-1 : i+s;
606
+ for(k=0; k<pkl->channel; k++)
607
+ color[k] += pkl->image[(clipy*pkl->width+clipx) * pkl->channel + k] * matrix[t+s*3];
229
608
  }
230
609
  }
231
- p= &wrk[(i*pkl->width+j)*pkl->channel];
232
- for(k=0; k<pkl->channel; k++) *p++=median[k];
610
+
611
+ for(k=0; k<pkl->channel; k++)
612
+ wrk[(i*pkl->width+j)*pkl->channel+k] = PKL_COLOR_CLIP(color[k]/weight);
233
613
  }
234
614
  }
235
615
 
@@ -238,3 +618,55 @@ PKLExport int pkl_noisecut(PKLImage pkl)
238
618
  return(0);
239
619
  }
240
620
 
621
+ //=============================================================================
622
+ // pkl_emboss
623
+ //=============================================================================
624
+ PKLExport int pkl_emboss(PKLImage pkl, PKL_EMBOSS type)
625
+ {
626
+ int i, *mask;
627
+
628
+ //select filter
629
+ mask=focus_filter[0].matrix;
630
+ for(i=0; i<sizeof(emboss_filter)/sizeof(struct PKL_FILTER); i++){
631
+ if(type==emboss_filter[i].type){
632
+ mask = emboss_filter[i].matrix;
633
+ break;
634
+ }
635
+ }
636
+ return pkl_emboss2(pkl, mask, 3, 3, 1.0, 127);
637
+ }
638
+
639
+ //=============================================================================
640
+ // pkl_emboss2
641
+ //=============================================================================
642
+ PKLExport int pkl_emboss2(PKLImage pkl, int *mask, int row, int col, double factor, int offset)
643
+ {
644
+ unsigned char *wrk;
645
+ int i, j, s, t, k, clipx, clipy;
646
+ int color[PKL_CHANNEL];
647
+
648
+ wrk = malloc(pkl->width*pkl->height*pkl->channel);
649
+ if(!wrk) return(1);
650
+ memset(wrk, 0, pkl->width*pkl->height*pkl->channel);
651
+
652
+ for(i=0; i<pkl->height; i++){
653
+ for(j=0; j<pkl->width; j++){
654
+ memset(color, 0, sizeof(color));
655
+ for(s=0; s<col; s++){
656
+ for(t=0; t<row; t++){
657
+ clipx = (j+t)>=pkl->width ? pkl->width-1 : j+t;
658
+ clipy = (i+s)>=pkl->height ? pkl->height-1 : i+s;
659
+ for(k=0; k<pkl->channel; k++)
660
+ color[k] += pkl->image[(clipy*pkl->width+clipx) * pkl->channel + k] * mask[t+s*row];
661
+ }
662
+ }
663
+
664
+ for(k=0; k<pkl->channel; k++)
665
+ wrk[(i*pkl->width+j)*pkl->channel+k] = PKL_COLOR_CLIP(color[k]/factor + offset);
666
+ }
667
+ }
668
+
669
+ free(pkl->image);
670
+ pkl->image = wrk;
671
+ return(0);
672
+ }