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_io.h
CHANGED
File without changes
|
data/ext/pikl/pikl_jpeg.c
CHANGED
File without changes
|
data/ext/pikl/pikl_jpeg.h
CHANGED
File without changes
|
data/ext/pikl/pikl_pattern.c
CHANGED
@@ -1,15 +1,27 @@
|
|
1
1
|
#include "pikl_pattern.h"
|
2
2
|
|
3
|
+
static int tile_rectangle(PKLImage pkl, int msx, int msy, unsigned char level);
|
4
|
+
static int tile_pattern(PKLImage pkl, PKL_TILE_TYPE type, int pw, int ph, unsigned char level);
|
5
|
+
static int tile_pattern_draw(PKLImage pkl, double *wd, int pw, int ph, unsigned char level);
|
6
|
+
static int tile_brick(PKLImage pkl, int msx, int msy, unsigned char level);
|
7
|
+
|
8
|
+
static void pattern_hexagon(int ph, double *wd, double ww, double hh);
|
9
|
+
static void pattern_diamond(int ph, double *wd, double ww, double hh);
|
10
|
+
static void pattern_circle(int ph, double *wd, double ww, double hh);
|
11
|
+
static void pattern_brick(int ph, double *wd, double ww, double hh);
|
12
|
+
|
3
13
|
static int pkl_pattern_draw_line(PKLImage pkl, double *wd, int pw, int ph);
|
4
14
|
static int pkl_pattern_draw_average(PKLImage pkl, double *wd, int pw, int ph);
|
5
15
|
|
6
16
|
//=============================================================================
|
7
|
-
//
|
17
|
+
// pkl_pattern
|
8
18
|
//=============================================================================
|
9
|
-
PKLExport int
|
19
|
+
PKLExport int pkl_pattern(PKLImage pkl, int pw, int ph, PKL_PATTERN_TYPE mode, PKL_PAINT_TYPE type)
|
10
20
|
{
|
11
21
|
double ww, hh, *wd;
|
12
|
-
int
|
22
|
+
int result;
|
23
|
+
|
24
|
+
if(pw<1 || ph<1) return(1);
|
13
25
|
|
14
26
|
wd = malloc(sizeof(double)*ph);
|
15
27
|
if(!wd) return(1);
|
@@ -17,21 +29,22 @@ PKLExport int pkl_pattern_hexagon(PKLImage pkl, int pw, int ph, PKL_PAINT_TYPE t
|
|
17
29
|
ww = (double)pw;
|
18
30
|
hh = (double)ph;
|
19
31
|
|
20
|
-
/*
|
21
|
-
|
22
|
-
|
23
|
-
wd
|
24
|
-
|
25
|
-
|
26
|
-
wd
|
27
|
-
|
28
|
-
|
29
|
-
wd
|
30
|
-
|
31
|
-
|
32
|
-
|
32
|
+
/* パターン座標の構築 */
|
33
|
+
switch(mode){
|
34
|
+
case PKL_PATTERN_DIAMOND:
|
35
|
+
pattern_diamond(ph, wd, ww, hh);
|
36
|
+
break;
|
37
|
+
case PKL_PATTERN_CIRCLE:
|
38
|
+
pattern_circle(ph, wd, ww, hh);
|
39
|
+
break;
|
40
|
+
case PKL_PATTERN_BRICK:
|
41
|
+
pattern_brick(ph, wd, ww, hh);
|
42
|
+
break;
|
43
|
+
case PKL_PATTERN_HEXAGON:
|
44
|
+
default:
|
45
|
+
pattern_hexagon(ph, wd, ww, hh);
|
33
46
|
}
|
34
|
-
|
47
|
+
|
35
48
|
/* 塗りタイプ別の処理 */
|
36
49
|
switch(type){
|
37
50
|
case PKL_PAINT_AVE:
|
@@ -47,20 +60,32 @@ PKLExport int pkl_pattern_hexagon(PKLImage pkl, int pw, int ph, PKL_PAINT_TYPE t
|
|
47
60
|
}
|
48
61
|
|
49
62
|
//=============================================================================
|
50
|
-
//
|
63
|
+
// pattern_hexagon
|
51
64
|
//=============================================================================
|
52
|
-
|
65
|
+
void pattern_hexagon(int ph, double *wd, double ww, double hh)
|
53
66
|
{
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
67
|
+
int i;
|
68
|
+
for(i=0; i<ph; i++){
|
69
|
+
if((double)i < hh/6.0){
|
70
|
+
wd[i] = ww * (double)i*6.0/hh;
|
71
|
+
}else
|
72
|
+
if((double)i < hh/2.0){
|
73
|
+
wd[i] = ww;
|
74
|
+
}else
|
75
|
+
if((double)i < hh*2.0/3.0){
|
76
|
+
wd[i] = ww*4.0 - ww*(double)i*6.0/hh;
|
77
|
+
}else{
|
78
|
+
wd[i] = 0.0;
|
79
|
+
}
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
//=============================================================================
|
84
|
+
// pattern_diamond
|
85
|
+
//=============================================================================
|
86
|
+
void pattern_diamond(int ph, double *wd, double ww, double hh)
|
87
|
+
{
|
88
|
+
int i;
|
64
89
|
for(i=0; i<ph; i++){
|
65
90
|
if((double)i < hh/2.0){
|
66
91
|
wd[i] = ww*(double)i*2.0/hh;
|
@@ -68,36 +93,14 @@ PKLExport int pkl_pattern_diamond(PKLImage pkl, int pw, int ph, PKL_PAINT_TYPE t
|
|
68
93
|
wd[i] = ww*2.0 - ww*(double)i*2.0/hh;
|
69
94
|
}
|
70
95
|
}
|
71
|
-
|
72
|
-
/* 塗りタイプ別の処理 */
|
73
|
-
switch(type){
|
74
|
-
case PKL_PAINT_AVE:
|
75
|
-
result = pkl_pattern_draw_average(pkl, wd, pw, ph);
|
76
|
-
break;
|
77
|
-
case PKL_PAINT_LINE:
|
78
|
-
default:
|
79
|
-
result = pkl_pattern_draw_line(pkl, wd, pw, ph);
|
80
|
-
}
|
81
|
-
|
82
|
-
free(wd);
|
83
|
-
return(result);
|
84
96
|
}
|
85
97
|
|
86
98
|
//=============================================================================
|
87
|
-
//
|
99
|
+
// pattern_circle
|
88
100
|
//=============================================================================
|
89
|
-
|
101
|
+
void pattern_circle(int ph, double *wd, double ww, double hh)
|
90
102
|
{
|
91
|
-
|
92
|
-
int i, result;
|
93
|
-
|
94
|
-
wd = malloc(sizeof(double)*ph);
|
95
|
-
if(!wd) return(1);
|
96
|
-
|
97
|
-
ww = (double)pw;
|
98
|
-
hh = (double)ph;
|
99
|
-
|
100
|
-
/* パターン座標を構築する */
|
103
|
+
int i;
|
101
104
|
for(i=0; i<ph; i++){
|
102
105
|
if((double)i < hh/2.0){
|
103
106
|
wd[i] = ww*(double)i*2.0/hh - (ww/8.0)*sin((double)i*4.0/hh*M_PI);
|
@@ -105,36 +108,14 @@ PKLExport int pkl_pattern_circle(PKLImage pkl, int pw, int ph, PKL_PAINT_TYPE ty
|
|
105
108
|
wd[i] = ww*2.0 - ww*(double)i*2.0/hh + (ww/8.0)*sin((double)(i-hh/2.0)*4.0/hh*M_PI);
|
106
109
|
}
|
107
110
|
}
|
108
|
-
|
109
|
-
/* 塗りタイプ別の処理 */
|
110
|
-
switch(type){
|
111
|
-
case PKL_PAINT_AVE:
|
112
|
-
result = pkl_pattern_draw_average(pkl, wd, pw, ph);
|
113
|
-
break;
|
114
|
-
case PKL_PAINT_LINE:
|
115
|
-
default:
|
116
|
-
result = pkl_pattern_draw_line(pkl, wd, pw, ph);
|
117
|
-
}
|
118
|
-
|
119
|
-
free(wd);
|
120
|
-
return(result);
|
121
111
|
}
|
122
112
|
|
123
113
|
//=============================================================================
|
124
|
-
//
|
114
|
+
// pattern_brick
|
125
115
|
//=============================================================================
|
126
|
-
|
116
|
+
void pattern_brick(int ph, double *wd, double ww, double hh)
|
127
117
|
{
|
128
|
-
|
129
|
-
int i, result;
|
130
|
-
|
131
|
-
wd = malloc(sizeof(double)*ph);
|
132
|
-
if(!wd) return(1);
|
133
|
-
|
134
|
-
ww = (double)pw;
|
135
|
-
hh = (double)ph;
|
136
|
-
|
137
|
-
/* パターン座標を構築する */
|
118
|
+
int i;
|
138
119
|
for(i=0; i<ph; i++){
|
139
120
|
if((double)i < hh/2.0){
|
140
121
|
wd[i] = ww;
|
@@ -142,25 +123,12 @@ PKLExport int pkl_pattern_brick(PKLImage pkl, int pw, int ph, PKL_PAINT_TYPE typ
|
|
142
123
|
wd[i] = 0.0;
|
143
124
|
}
|
144
125
|
}
|
145
|
-
|
146
|
-
/* 塗りタイプ別の処理 */
|
147
|
-
switch(type){
|
148
|
-
case PKL_PAINT_AVE:
|
149
|
-
result = pkl_pattern_draw_average(pkl, wd, pw, ph);
|
150
|
-
break;
|
151
|
-
case PKL_PAINT_LINE:
|
152
|
-
default:
|
153
|
-
result = pkl_pattern_draw_line(pkl, wd, pw, ph);
|
154
|
-
}
|
155
|
-
|
156
|
-
free(wd);
|
157
|
-
return(result);
|
158
126
|
}
|
159
127
|
|
160
128
|
//=============================================================================
|
161
129
|
// pkl_pattern_draw_line
|
162
130
|
//=============================================================================
|
163
|
-
|
131
|
+
int pkl_pattern_draw_line(PKLImage pkl, double *wd, int pw, int ph)
|
164
132
|
{
|
165
133
|
unsigned char clipcolor[PKL_CHANNEL], *p;
|
166
134
|
int i, j, s, idx, k, color[PKL_CHANNEL];
|
@@ -215,7 +183,7 @@ static int pkl_pattern_draw_line(PKLImage pkl, double *wd, int pw, int ph)
|
|
215
183
|
//=============================================================================
|
216
184
|
// pkl_pattern_draw_average
|
217
185
|
//=============================================================================
|
218
|
-
|
186
|
+
int pkl_pattern_draw_average(PKLImage pkl, double *wd, int pw, int ph)
|
219
187
|
{
|
220
188
|
unsigned char clipcolor[PKL_CHANNEL], *p;
|
221
189
|
int i, j, s, t, k, color[PKL_CHANNEL];
|
@@ -282,330 +250,388 @@ static int pkl_pattern_draw_average(PKLImage pkl, double *wd, int pw, int ph)
|
|
282
250
|
}
|
283
251
|
|
284
252
|
//=============================================================================
|
285
|
-
//
|
253
|
+
// pkl_tile
|
286
254
|
//=============================================================================
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
255
|
+
PKLExport int pkl_tile(PKLImage pkl, PKL_TILE_TYPE type, int msx, int msy, unsigned char level)
|
256
|
+
{
|
257
|
+
if(msx<=0 || msx>pkl->width || msy<=0 || msy>pkl->height)
|
258
|
+
return(1);
|
259
|
+
|
260
|
+
switch(type){
|
261
|
+
case PKL_TILE_RECT:
|
262
|
+
return tile_rectangle(pkl, msx, msy, level);
|
263
|
+
case PKL_TILE_HEXAGON:
|
264
|
+
case PKL_TILE_DIAMOND:
|
265
|
+
case PKL_TILE_CIRCLE:
|
266
|
+
return tile_pattern(pkl, type, msx, msy, level);
|
267
|
+
case PKL_TILE_BRICK:
|
268
|
+
return tile_brick(pkl, msx, msy, level);
|
269
|
+
}
|
270
|
+
return(1);
|
271
|
+
}
|
293
272
|
|
294
273
|
//=============================================================================
|
295
|
-
//
|
274
|
+
// tile_brick
|
296
275
|
//=============================================================================
|
297
|
-
static
|
276
|
+
static int tile_brick(PKLImage pkl, int msx, int msy, unsigned char level)
|
298
277
|
{
|
299
|
-
|
300
|
-
int
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
278
|
+
unsigned char *wrk, *p;
|
279
|
+
int mpx, mpy; //モザイクの大きさ
|
280
|
+
int mlx, mly; //画像の分割数
|
281
|
+
int i, j, k, sx, sy, ex, ey, px, py, count, offset;
|
282
|
+
long color[PKL_CHANNEL];
|
283
|
+
|
284
|
+
wrk = malloc(pkl->width*pkl->height*pkl->channel);
|
285
|
+
if(!wrk) return(1);
|
286
|
+
memset(wrk, 0, pkl->width*pkl->height*pkl->channel);
|
287
|
+
|
288
|
+
mpx = (msx<1) ? 1 : (msx>=pkl->width) ? pkl->width-1 : msx;
|
289
|
+
mpy = (msy<1) ? 1 : (msy>=pkl->height) ? pkl->height-1 : msy;
|
290
|
+
mlx = (pkl->width+mpx-1)/mpx;
|
291
|
+
mly = (pkl->height+mpy-1)/mpy;
|
292
|
+
|
293
|
+
for(i=0; i<=mly; i++){
|
294
|
+
offset = (i%2) ? 0 : mpx/2;
|
295
|
+
for(j=0; j<=mlx; j++){
|
296
|
+
sx = j*mpx - offset;
|
297
|
+
sx = sx<0 ? 0 : sx;
|
298
|
+
sy = i*mpy;
|
299
|
+
ex = sx+mpx>pkl->width ? pkl->width : sx+mpx;
|
300
|
+
ey = sy+mpy>pkl->height ? pkl->height : sy+mpy;
|
322
301
|
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
mind = d;
|
332
|
-
minIx = tx;
|
333
|
-
minIy = ty;
|
334
|
-
}
|
302
|
+
//1セルの総和算出
|
303
|
+
count=0;
|
304
|
+
memset(color, 0, sizeof(color));
|
305
|
+
for(py=sy; py<ey; py++){
|
306
|
+
for(px=sx; px<ex; px++){
|
307
|
+
count++;
|
308
|
+
for(k=0; k<pkl->channel; k++)
|
309
|
+
color[k] += pkl->image[(py*pkl->width+px)*pkl->channel+k];
|
335
310
|
}
|
336
311
|
}
|
312
|
+
if(!count) continue;
|
337
313
|
|
314
|
+
//セルの平均色を算出して、セル内のピクセルに適用
|
338
315
|
for(k=0; k<pkl->channel; k++)
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
316
|
+
color[k] = PKL_COLOR_CLIP(color[k]/count);
|
317
|
+
for(py=sy; py<ey; py++){
|
318
|
+
for(px=sx; px<ex; px++){
|
319
|
+
for(k=0; k<pkl->channel; k++)
|
320
|
+
wrk[(py*pkl->width+px)*pkl->channel+k] = color[k];
|
321
|
+
}
|
322
|
+
}
|
323
|
+
|
324
|
+
//平均色で塗り終わったら枠線を描く
|
325
|
+
//横方向
|
326
|
+
for(px=sx; px<ex; px++){
|
327
|
+
p = &wrk[(sy*pkl->width+px)*pkl->channel];
|
328
|
+
for(k=0; k<pkl->channel; k++,p++)
|
329
|
+
*p = PKL_MIN(0xff, *p+level);
|
330
|
+
|
331
|
+
p = &wrk[((ey-1)*pkl->width+px)*pkl->channel];
|
332
|
+
for(k=0; k<pkl->channel; k++,p++)
|
333
|
+
*p = PKL_MAX(0, *p-level);
|
334
|
+
}
|
335
|
+
//縦方向
|
336
|
+
for(py=sy; py<ey; py++){
|
337
|
+
p = &wrk[(py*pkl->width+sx)*pkl->channel];
|
338
|
+
for(k=0; k<pkl->channel; k++,p++)
|
339
|
+
*p = PKL_MIN(0xff, *p+level);
|
340
|
+
|
341
|
+
p = &wrk[(py*pkl->width+ex-1)*pkl->channel];
|
342
|
+
for(k=0; k<pkl->channel; k++,p++)
|
343
|
+
*p = PKL_MAX(0, *p-level);
|
344
|
+
}
|
345
|
+
|
344
346
|
}
|
345
347
|
}
|
348
|
+
|
349
|
+
free(pkl->image);
|
350
|
+
pkl->image = wrk;
|
351
|
+
return(0);
|
346
352
|
}
|
347
353
|
|
348
354
|
//=============================================================================
|
349
|
-
//
|
355
|
+
// tile_rectangle
|
350
356
|
//=============================================================================
|
351
|
-
|
357
|
+
static int tile_rectangle(PKLImage pkl, int msx, int msy, unsigned char level)
|
352
358
|
{
|
353
|
-
|
354
|
-
int
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
for(i=0; i<pkl->channel; i++)
|
367
|
-
border[i] = (bordercolor>>((pkl->channel-i)*8) & 0xFF);
|
368
|
-
|
369
|
-
//ボロノイ管理データ
|
370
|
-
vptr = malloc(sizeof(struct VoronoiPoint) * xzone*yzone);
|
371
|
-
memset(vptr, 0, sizeof(struct VoronoiPoint) * xzone*yzone);
|
372
|
-
|
373
|
-
//各座標のボロノイIDを格納するデータ
|
374
|
-
id = malloc(sizeof(int) * pkl->width*pkl->height);
|
375
|
-
|
376
|
-
//ボロノイ管理データを作る
|
377
|
-
voronoi_type1_query(pkl, vptr, id, zone, xzone, yzone);
|
378
|
-
|
379
|
-
if(test){
|
380
|
-
//分割シュミレーション(母点を置く)
|
381
|
-
memset(pkl->image, 0xff, pkl->width*pkl->height*pkl->channel);
|
382
|
-
for(i=0; i<xzone*yzone; i++)
|
383
|
-
memcpy(&pkl->image[(vptr[i].y*pkl->width+vptr[i].x)*pkl->channel], border, pkl->channel);
|
384
|
-
}else{
|
385
|
-
//各ボロノイポイントの平均色算出
|
386
|
-
for(ty=0; ty<yzone; ty++){
|
387
|
-
for(tx=0; tx<xzone; tx++){
|
388
|
-
if(vptr[ty*xzone+tx].count == 0) continue;
|
389
|
-
p = &vptr[ty*xzone+tx];
|
390
|
-
for(k=0; k<pkl->channel; k++)
|
391
|
-
p->ave[k] = PKL_COLOR_CLIP(p->color[k]/p->count);
|
392
|
-
}
|
359
|
+
unsigned char *p;
|
360
|
+
int i, j, k;
|
361
|
+
|
362
|
+
//モザイク化
|
363
|
+
if(pkl_mosaic(pkl, msx, msy)) return(1);
|
364
|
+
|
365
|
+
//横方向(light)
|
366
|
+
for(i=0; i<pkl->height; i+=msy){
|
367
|
+
for(j=0; j<pkl->width; j++){
|
368
|
+
p = &pkl->image[(i*pkl->width+j)*pkl->channel];
|
369
|
+
for(k=0; k<pkl->channel; k++,p++)
|
370
|
+
*p = PKL_MIN(0xff, *p+level);
|
393
371
|
}
|
394
|
-
//色を設定
|
395
|
-
for(i=0; i<pkl->height; i++)
|
396
|
-
for(j=0; j<pkl->width; j++)
|
397
|
-
memcpy(&pkl->image[(i*pkl->width+j)*pkl->channel], vptr[id[i*pkl->width+j]].ave, pkl->channel);
|
398
372
|
}
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
for(
|
405
|
-
|
406
|
-
currentId = id[j*pkl->width+i];
|
407
|
-
if(i-1>=0 && currentId!=id[j*pkl->width+i-1]) hit++;
|
408
|
-
if(i+1<pkl->width && currentId!=id[j*pkl->width+i+1]) hit++;
|
409
|
-
if(j-1>=0 && currentId!=id[(j-1)*pkl->width+i+1]) hit++;
|
410
|
-
if(j+1<pkl->height && currentId!=id[(j+1)*pkl->width+i+1]) hit++;
|
411
|
-
if(hit)
|
412
|
-
memcpy(&pkl->image[(j*pkl->width+i)*pkl->channel], border, pkl->channel);
|
413
|
-
}
|
373
|
+
|
374
|
+
//横方向(dark)
|
375
|
+
for(i=msy-1; i<pkl->height; i+=msy){
|
376
|
+
for(j=0; j<pkl->width; j++){
|
377
|
+
p = &pkl->image[(i*pkl->width+j)*pkl->channel];
|
378
|
+
for(k=0; k<pkl->channel; k++,p++)
|
379
|
+
*p = PKL_MAX(0, *p-level);
|
414
380
|
}
|
415
381
|
}
|
416
|
-
free(id);
|
417
|
-
free(vptr);
|
418
|
-
return(0);
|
419
|
-
}
|
420
382
|
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
383
|
+
//縦方向(light)
|
384
|
+
for(i=0; i<pkl->height; i++){
|
385
|
+
for(j=0; j<pkl->width; j+=msx){
|
386
|
+
p = &pkl->image[(i*pkl->width+j)*pkl->channel];
|
387
|
+
for(k=0; k<pkl->channel; k++,p++)
|
388
|
+
*p = PKL_MIN(0xff, *p+level);
|
389
|
+
}
|
390
|
+
}
|
391
|
+
|
392
|
+
//縦方向(dark)
|
393
|
+
for(i=0; i<pkl->height; i++){
|
394
|
+
for(j=msx-1; j<pkl->width; j+=msx){
|
395
|
+
p = &pkl->image[(i*pkl->width+j)*pkl->channel];
|
396
|
+
for(k=0; k<pkl->channel; k++,p++)
|
397
|
+
*p = PKL_MAX(0, *p-level);
|
398
|
+
}
|
399
|
+
}
|
426
400
|
|
427
|
-
|
428
|
-
|
429
|
-
int id; //管理用ID
|
430
|
-
long color[PKL_CHANNEL]; //ターゲット領域の色累積領域
|
431
|
-
int count; //累積ピクセル数
|
432
|
-
int next[VORONOI_CNT]; //隣接する母点のID
|
433
|
-
};
|
401
|
+
return(0);
|
402
|
+
}
|
434
403
|
|
435
404
|
//=============================================================================
|
436
|
-
//
|
405
|
+
// tile_pattern
|
437
406
|
//=============================================================================
|
438
|
-
static int
|
407
|
+
static int tile_pattern(PKLImage pkl, PKL_TILE_TYPE type, int pw, int ph, unsigned char level)
|
439
408
|
{
|
440
|
-
|
441
|
-
|
409
|
+
double ww, hh, *wd;
|
410
|
+
int result=1;
|
411
|
+
|
412
|
+
wd = malloc(sizeof(double)*ph);
|
413
|
+
if(!wd) return(1);
|
414
|
+
|
415
|
+
ww = (double)pw;
|
416
|
+
hh = (double)ph;
|
442
417
|
|
443
|
-
|
444
|
-
|
445
|
-
|
418
|
+
/* パターン座標の構築 */
|
419
|
+
switch(type){
|
420
|
+
case PKL_TILE_HEXAGON:
|
421
|
+
pattern_hexagon(ph, wd, ww, hh); break;
|
422
|
+
case PKL_TILE_DIAMOND:
|
423
|
+
pattern_diamond(ph, wd, ww, hh); break;
|
424
|
+
case PKL_TILE_CIRCLE:
|
425
|
+
pattern_circle(ph, wd, ww, hh); break;
|
426
|
+
default:
|
427
|
+
;;
|
428
|
+
}
|
429
|
+
|
430
|
+
//パターンで塗りつぶしてから枠を描く
|
431
|
+
if(!pkl_pattern_draw_average(pkl, wd, pw, ph))
|
432
|
+
result = tile_pattern_draw(pkl, wd, pw, ph, level);
|
433
|
+
free(wd);
|
434
|
+
return(result);
|
446
435
|
}
|
447
436
|
|
448
437
|
//=============================================================================
|
449
|
-
//
|
438
|
+
// tile_pattern_draw
|
450
439
|
//=============================================================================
|
451
|
-
static
|
440
|
+
static int tile_pattern_draw(PKLImage pkl, double *wd, int pw, int ph, unsigned char level)
|
452
441
|
{
|
453
|
-
|
442
|
+
unsigned char *p;
|
443
|
+
int i, j, t, k, pos;
|
444
|
+
int ys, idx, ptn=0;
|
445
|
+
double ww, hh, rm;
|
454
446
|
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
447
|
+
ww = (double)pw;
|
448
|
+
hh = (double)ph;
|
449
|
+
|
450
|
+
for(j=0; j<pkl->width+pw; j+=pw){
|
451
|
+
ptn = !ptn;
|
452
|
+
ys = (ptn) ? 0 : (-ph/2);
|
453
|
+
for(i=ys; i<pkl->height; i+=ph){
|
454
|
+
rm=wd[0];
|
455
|
+
|
456
|
+
for(t=i; t<i+ph; t++){
|
457
|
+
if(t<0 || t>=pkl->height) continue;
|
458
|
+
idx = t % ph;
|
459
|
+
rm = ptn ? wd[idx] : ww-wd[idx];
|
460
|
+
|
461
|
+
//first=light
|
462
|
+
pos = j - rm;
|
463
|
+
if(pos>=0 && pos<pkl->width){
|
464
|
+
p = &pkl->image[(t*pkl->width+pos)*pkl->channel];
|
465
|
+
for(k=0; k<pkl->channel; k++,p++)
|
466
|
+
*p = PKL_MIN(0xff, *p+level);
|
467
|
+
}
|
468
|
+
|
469
|
+
//last=dark
|
470
|
+
pos = j + rm - 1;
|
471
|
+
if(pos>=0 && pos<pkl->width){
|
472
|
+
p = &pkl->image[(t*pkl->width+pos)*pkl->channel];
|
473
|
+
for(k=0; k<pkl->channel; k++,p++)
|
474
|
+
*p = PKL_MAX(0, *p-level);
|
475
|
+
}
|
476
|
+
}
|
459
477
|
}
|
460
478
|
}
|
479
|
+
return(0);
|
461
480
|
}
|
462
481
|
|
482
|
+
|
463
483
|
//=============================================================================
|
464
|
-
//
|
484
|
+
// pkl_mosaic
|
465
485
|
//=============================================================================
|
466
|
-
|
486
|
+
PKLExport int pkl_mosaic(PKLImage pkl, int msx, int msy)
|
467
487
|
{
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
dx = kp[pre_id].x-i;
|
490
|
-
dy = kp[pre_id].y-j;
|
491
|
-
min_d = sqrt(dx*dx+dy*dy);
|
488
|
+
unsigned char *wrk;
|
489
|
+
int mpx, mpy; //モザイクの大きさ
|
490
|
+
int mlx, mly; //画像の分割数
|
491
|
+
int i, j, k, sx, sy, ex, ey, px, py, mm;
|
492
|
+
long color[PKL_CHANNEL];
|
493
|
+
|
494
|
+
wrk = malloc(pkl->width*pkl->height*pkl->channel);
|
495
|
+
if(!wrk) return(1);
|
496
|
+
memset(wrk, 0, pkl->width*pkl->height*pkl->channel);
|
497
|
+
|
498
|
+
mpx = (msx<1) ? 1 : (msx>=pkl->width) ? pkl->width-1 : msx;
|
499
|
+
mpy = (msy<1) ? 1 : (msy>=pkl->height) ? pkl->height-1 : msy;
|
500
|
+
mlx = (pkl->width+mpx-1)/mpx;
|
501
|
+
mly = (pkl->height+mpy-1)/mpy;
|
502
|
+
|
503
|
+
for(i=0; i<=mly; i++){
|
504
|
+
for(j=0; j<=mlx; j++){
|
505
|
+
sx = j*mpx;
|
506
|
+
sy = i*mpy;
|
507
|
+
ex = sx+mpx>pkl->width ? pkl->width : sx+mpx;
|
508
|
+
ey = sy+mpy>pkl->height ? pkl->height : sy+mpy;
|
492
509
|
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
min_d=d;
|
502
|
-
}
|
510
|
+
//1セルの総和算出
|
511
|
+
mm=0;
|
512
|
+
memset(color, 0, sizeof(color));
|
513
|
+
for(py=sy; py<ey; py++){
|
514
|
+
for(px=sx; px<ex; px++){
|
515
|
+
mm++;
|
516
|
+
for(k=0; k<pkl->channel; k++)
|
517
|
+
color[k] += pkl->image[(py*pkl->width+px)*pkl->channel+k];
|
503
518
|
}
|
504
519
|
}
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
}
|
520
|
+
if(!mm) continue;
|
521
|
+
|
522
|
+
//セルの平均色を算出して、セル内のピクセルに適用
|
523
|
+
for(k=0; k<pkl->channel; k++)
|
524
|
+
color[k] = PKL_COLOR_CLIP(color[k]/mm);
|
525
|
+
for(py=sy; py<ey; py++){
|
526
|
+
for(px=sx; px<ex; px++){
|
527
|
+
for(k=0; k<pkl->channel; k++)
|
528
|
+
wrk[(py*pkl->width+px)*pkl->channel+k] = color[k];
|
515
529
|
}
|
516
530
|
}
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
531
|
+
}
|
532
|
+
}
|
533
|
+
|
534
|
+
free(pkl->image);
|
535
|
+
pkl->image = wrk;
|
536
|
+
return(0);
|
537
|
+
}
|
538
|
+
|
539
|
+
//=============================================================================
|
540
|
+
// pkl_pixelate
|
541
|
+
//=============================================================================
|
542
|
+
PKLExport int pkl_pixelate(PKLImage pkl, int ms)
|
543
|
+
{
|
544
|
+
unsigned char *wrk;
|
545
|
+
int mpx, mpy; //モザイクの大きさ
|
546
|
+
int mlx, mly; //画像の分割数
|
547
|
+
int i, j, k, sx, sy, ex, ey, px, py, mm;
|
548
|
+
long color[PKL_CHANNEL];
|
549
|
+
int total;
|
550
|
+
unsigned char p;
|
551
|
+
|
552
|
+
wrk = malloc(pkl->width*pkl->height*pkl->channel);
|
553
|
+
if(!wrk) return(1);
|
554
|
+
|
555
|
+
mpx = (ms<1) ? 1 : (ms>=pkl->width) ? pkl->width-1 : ms;
|
556
|
+
mpy = (ms<1) ? 1 : (ms>=pkl->height) ? pkl->height-1 : ms;
|
557
|
+
mlx = (pkl->width+mpx-1)/mpx;
|
558
|
+
mly = (pkl->height+mpy-1)/mpy;
|
559
|
+
|
560
|
+
for(i=0; i<=mly; i++){
|
561
|
+
for(j=0; j<=mlx; j++){
|
562
|
+
sx = j*mpx;
|
563
|
+
sy = i*mpy;
|
564
|
+
ex = sx+mpx>pkl->width ? pkl->width : sx+mpx;
|
565
|
+
ey = sy+mpy>pkl->height ? pkl->height : sy+mpy;
|
566
|
+
|
567
|
+
//1セルの総和算出
|
568
|
+
mm=0;
|
569
|
+
memset(color, 0, sizeof(color));
|
570
|
+
for(py=sy; py<ey; py++){
|
571
|
+
for(px=sx; px<ex; px++){
|
572
|
+
mm++;
|
573
|
+
for(k=0; k<pkl->channel; k++)
|
574
|
+
color[k] += pkl->image[(py*pkl->width+px)*pkl->channel+k];
|
575
|
+
}
|
521
576
|
}
|
577
|
+
if(!mm) continue;
|
522
578
|
|
523
|
-
|
524
|
-
|
525
|
-
|
579
|
+
//セルの平均色を算出
|
580
|
+
for(k=0; k<pkl->channel; k++)
|
581
|
+
color[k] = PKL_COLOR_CLIP(color[k]/mm);
|
582
|
+
|
583
|
+
total=0;
|
584
|
+
for(k=0; k<pkl->channel; k++)
|
585
|
+
total += color[k];
|
586
|
+
total /=pkl->channel;
|
587
|
+
p = total<128 ? 0 : 255;
|
588
|
+
|
589
|
+
for(py=sy; py<ey; py++){
|
590
|
+
for(px=sx; px<ex; px++){
|
591
|
+
for(k=0; k<pkl->channel; k++)
|
592
|
+
wrk[(py*pkl->width+px)*pkl->channel+k] = p;
|
593
|
+
}
|
594
|
+
}
|
526
595
|
}
|
527
596
|
}
|
597
|
+
|
598
|
+
free(pkl->image);
|
599
|
+
pkl->image = wrk;
|
600
|
+
return(0);
|
528
601
|
}
|
529
602
|
|
530
603
|
//=============================================================================
|
531
|
-
//
|
604
|
+
// pkl_grid
|
532
605
|
//=============================================================================
|
533
|
-
PKLExport int
|
606
|
+
PKLExport int pkl_grid(PKLImage pkl, int msx, int msy, int color)
|
534
607
|
{
|
535
|
-
|
536
|
-
int i, j, k,
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
for(i=0; i<count; i++)
|
553
|
-
memset(kp[i].next, -1, sizeof(int)*VORONOI_CNT);
|
554
|
-
|
555
|
-
//ボロノイ管理データを作る
|
556
|
-
voronoi_type2_query(pkl, kp, ip, count);
|
557
|
-
|
558
|
-
if(test){
|
559
|
-
//分割シュミレーション(母点を置く)
|
560
|
-
memset(pkl->image, 0xff, pkl->width*pkl->height*pkl->channel);
|
561
|
-
for(i=0; i<count; i++)
|
562
|
-
memcpy(&pkl->image[(kp[i].y*pkl->width+kp[i].x)*pkl->channel], border, pkl->channel);
|
563
|
-
}else{
|
564
|
-
//ボロノイ分割されたので、各セルの平均色を算出するためにセルの色を累積する
|
565
|
-
for(j=0; j<pkl->height; j++) {
|
566
|
-
for(i=0; i<pkl->width; i++) {
|
567
|
-
//ipを参照することで、現在の座標がどのIDに所属するかわかる
|
568
|
-
if(ip[j*pkl->width+i] == -1) continue;
|
569
|
-
//IDごとに色を累積する
|
570
|
-
kp[ ip[j*pkl->width+i] ].count++;
|
571
|
-
for(k=0; k<pkl->channel; k++)
|
572
|
-
kp[ ip[j*pkl->width+i] ].color[k] += pkl->image[(j*pkl->width+i)*pkl->channel+k];
|
608
|
+
unsigned char *p;
|
609
|
+
int i, j, k, mpx, mpy;
|
610
|
+
|
611
|
+
//一旦モザイク化
|
612
|
+
if(pkl_mosaic(pkl, msx, msy)) return(1);
|
613
|
+
|
614
|
+
mpx = (msx<1) ? 1 : (msx>=pkl->width) ? pkl->width-1 : msx;
|
615
|
+
mpy = (msy<1) ? 1 : (msy>=pkl->height) ? pkl->height-1 : msy;
|
616
|
+
|
617
|
+
for(i=0; i<pkl->height-1; i++){
|
618
|
+
if(i%mpy==0){
|
619
|
+
for(j=0; j<pkl->width; j++){
|
620
|
+
p = &pkl->image[(i*pkl->width+j)*pkl->channel];
|
621
|
+
for(k=0; k<pkl->channel; k++){
|
622
|
+
*p = PKL_COLOR_CLIP(*p+color);
|
623
|
+
p++;
|
624
|
+
}
|
573
625
|
}
|
574
626
|
}
|
575
|
-
|
576
|
-
|
577
|
-
for(i=0; i<count; i++){
|
627
|
+
for(j=mpx; j<pkl->width; j+=mpx){
|
628
|
+
p = &pkl->image[(i*pkl->width+j)*pkl->channel];
|
578
629
|
for(k=0; k<pkl->channel; k++){
|
579
|
-
|
580
|
-
|
630
|
+
*p = PKL_COLOR_CLIP(*p+color);
|
631
|
+
p++;
|
581
632
|
}
|
582
633
|
}
|
583
|
-
|
584
|
-
//色を置く
|
585
|
-
for(j=0; j<pkl->height; j++)
|
586
|
-
for(i=0; i<pkl->width; i++)
|
587
|
-
for(k=0; k<pkl->channel; k++)
|
588
|
-
pkl->image[(j*pkl->width+i)*pkl->channel+k] = kp[ ip[j*pkl->width+i] ].color[k];
|
589
634
|
}
|
590
635
|
|
591
|
-
//境界線を引く
|
592
|
-
if(bordercolor!=-1){
|
593
|
-
int currentId, hit=0;
|
594
|
-
for(j=0; j<pkl->height; j++){
|
595
|
-
for(i=0; i<pkl->width; i++){
|
596
|
-
hit=0;
|
597
|
-
currentId = ip[j*pkl->width+i];
|
598
|
-
if(i-1>=0 && currentId!=ip[j*pkl->width+i-1]) hit++;
|
599
|
-
if(i+1<pkl->width && currentId!=ip[j*pkl->width+i+1]) hit++;
|
600
|
-
if(j-1>=0 && currentId!=ip[(j-1)*pkl->width+i+1]) hit++;
|
601
|
-
if(j+1<pkl->height && currentId!=ip[(j+1)*pkl->width+i+1]) hit++;
|
602
|
-
if(hit)
|
603
|
-
memcpy(&pkl->image[(j*pkl->width+i)*pkl->channel], border, pkl->channel);
|
604
|
-
}
|
605
|
-
}
|
606
|
-
}
|
607
|
-
|
608
|
-
free(kp);
|
609
|
-
free(ip);
|
610
636
|
return(0);
|
611
637
|
}
|