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
data/ext/pikl/pikl_effect.c
CHANGED
@@ -1,203 +1,540 @@
|
|
1
1
|
#include "pikl_effect.h"
|
2
2
|
|
3
|
-
|
4
|
-
//
|
5
|
-
|
6
|
-
PKLExport int
|
3
|
+
//=============================================================================
|
4
|
+
// pkl_invert
|
5
|
+
//=============================================================================
|
6
|
+
PKLExport int pkl_invert(PKLImage pkl)
|
7
7
|
{
|
8
|
-
int i
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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->
|
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
|
-
|
19
|
-
|
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
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
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
|
-
|
30
|
-
|
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
|
-
|
36
|
-
|
37
|
-
|
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
|
-
|
129
|
+
|
130
|
+
free(pkl->image);
|
131
|
+
pkl->image = wrk;
|
40
132
|
return(0);
|
41
133
|
}
|
42
134
|
|
43
|
-
|
44
|
-
//
|
45
|
-
|
46
|
-
PKLExport int
|
135
|
+
//=============================================================================
|
136
|
+
// pkl_vtr
|
137
|
+
//=============================================================================
|
138
|
+
PKLExport int pkl_vtr(PKLImage pkl, int colspace, int gst, int cst)
|
47
139
|
{
|
48
|
-
unsigned char
|
49
|
-
int
|
140
|
+
unsigned char *wrk;
|
141
|
+
int i, j, k, t;
|
142
|
+
int h=0, l_det=0;
|
50
143
|
|
51
|
-
|
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
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
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
|
-
|
60
|
-
|
61
|
-
for(
|
62
|
-
|
63
|
-
|
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
|
-
|
68
|
-
|
69
|
-
|
164
|
+
free(pkl->image);
|
165
|
+
pkl->image = wrk;
|
70
166
|
return(0);
|
71
167
|
}
|
72
168
|
|
73
|
-
|
74
|
-
//
|
75
|
-
|
76
|
-
PKLExport int
|
169
|
+
//=============================================================================
|
170
|
+
// pkl_edgepaint
|
171
|
+
//=============================================================================
|
172
|
+
PKLExport int pkl_edgepaint(PKLImage pkl, int edge)
|
77
173
|
{
|
78
|
-
|
79
|
-
int i, j,
|
80
|
-
|
81
|
-
|
82
|
-
|
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
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
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->
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
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
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
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
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
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
|
-
//
|
317
|
+
// pkl_edge
|
123
318
|
//=============================================================================
|
124
|
-
PKLExport int
|
319
|
+
PKLExport int pkl_edge(PKLImage pkl, int threshold)
|
125
320
|
{
|
126
|
-
|
127
|
-
|
128
|
-
|
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
|
-
//
|
373
|
+
// pkl_dither
|
135
374
|
//=============================================================================
|
136
|
-
PKLExport int
|
375
|
+
PKLExport int pkl_dither(PKLImage pkl, PKL_DITHER dither)
|
137
376
|
{
|
138
|
-
|
139
|
-
|
140
|
-
|
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
|
-
|
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
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
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
|
-
|
169
|
-
|
170
|
-
|
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
|
-
//
|
177
|
-
|
178
|
-
PKLExport int
|
469
|
+
//=============================================================================
|
470
|
+
// pkl_colordither
|
471
|
+
//=============================================================================
|
472
|
+
PKLExport int pkl_colordither(PKLImage pkl, int weight)
|
179
473
|
{
|
180
|
-
|
181
|
-
|
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
|
-
|
481
|
+
row = 3;
|
482
|
+
col = 2;
|
483
|
+
pt = &(FloydSteinberg[0][0]);
|
184
484
|
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
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
|
-
//
|
531
|
+
// pkl_contour
|
196
532
|
//=============================================================================
|
197
|
-
PKLExport int
|
533
|
+
PKLExport int pkl_contour(PKLImage pkl)
|
198
534
|
{
|
199
|
-
|
200
|
-
int i, j,
|
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
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
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
|
-
|
220
|
-
for(
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
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
|
-
|
232
|
-
for(k=0; k<pkl->channel; 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
|
+
}
|