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
@@ -9,4 +9,12 @@
9
9
  #include "pikl.h"
10
10
  #include "pikl_private.h"
11
11
 
12
+ typedef struct {
13
+ float rcos, rsin;
14
+ int width, height;
15
+ int sx, sy;
16
+ int ex, ey;
17
+ unsigned char back[PKL_CHANNEL];
18
+ } PIKL_ROTATE;
19
+
12
20
  #endif
@@ -1,6 +1,7 @@
1
1
  #include "pikl_scrap.h"
2
2
 
3
- static void pkl_circle(PKLImage pkl, int x, int y, int radius, unsigned char *color);
3
+ static void circle(PKLImage pkl, int x, int y, int radius, unsigned char *color);
4
+ static unsigned char lighting(unsigned char color, double dx, double dy, double dz, double mil, double env, double *light);
4
5
 
5
6
  //=============================================================================
6
7
  // �A���`�G�C���A�X�����������~��`��
@@ -8,7 +9,7 @@ static void pkl_circle(PKLImage pkl, int x, int y, int radius, unsigned char *co
8
9
  // radius: ���a
9
10
  // color: �h��F(unsigned char x[pkl->channel]�̗̈�����ƒ|�C���^)
10
11
  //=============================================================================
11
- static void pkl_circle(PKLImage pkl, int x, int y, int radius, unsigned char *color)
12
+ static void circle(PKLImage pkl, int x, int y, int radius, unsigned char *color)
12
13
  {
13
14
  unsigned char *p;
14
15
  int sx, sy, ex, ey, tx, ty;
@@ -67,7 +68,7 @@ static void pkl_circle(PKLImage pkl, int x, int y, int radius, unsigned char *co
67
68
  //=============================================================================
68
69
  // pkl_dots
69
70
  //=============================================================================
70
- PKLExport int pkl_dots(PKLImage pkl, int zone, int color)
71
+ PKLExport int pkl_dots(PKLImage pkl, int zone, PKLColor color)
71
72
  {
72
73
  unsigned char *wrk, *bp, *p, dc[PKL_CHANNEL];
73
74
  int i, j, k, t, s, gray, count, stock;
@@ -79,8 +80,12 @@ PKLExport int pkl_dots(PKLImage pkl, int zone, int color)
79
80
  if(!wrk) return(1);
80
81
  memset(wrk, 0xff, pkl->width*pkl->height*pkl->channel);
81
82
 
82
- for(i=0; i<pkl->channel; i++)
83
- dc[i] = (color>>((pkl->channel-i)*8) & 0xFF);
83
+ //for(i=0; i<pkl->channel; i++)
84
+ // dc[i] = (color>>((pkl->channel-i)*8) & 0xFF);
85
+ if(color)
86
+ memcpy(dc, color->color, pkl->channel);
87
+ else
88
+ memset(dc, 0, pkl->channel);
84
89
 
85
90
  propc = zone/32.0;
86
91
 
@@ -102,7 +107,7 @@ PKLExport int pkl_dots(PKLImage pkl, int zone, int color)
102
107
  }
103
108
  }
104
109
  if(count)
105
- pkl_circle(pkl, j+zone/2, i+zone/2, sqrt(stock/count)*propc, dc);
110
+ circle(pkl, j+zone/2, i+zone/2, sqrt(stock/count)*propc, dc);
106
111
  }
107
112
  }
108
113
 
@@ -113,7 +118,7 @@ PKLExport int pkl_dots(PKLImage pkl, int zone, int color)
113
118
  //=============================================================================
114
119
  // pkl_swirl
115
120
  //=============================================================================
116
- PKLExport int pkl_swirl(PKLImage pkl, double factor, int x, int y, int backcolor)
121
+ PKLExport int pkl_swirl(PKLImage pkl, double factor, int x, int y, PKLColor backcolor)
117
122
  {
118
123
  unsigned char *wrk, color[PKL_CHANNEL], *p, *q;
119
124
  int i, j, k, tx, ty, sx, sy;
@@ -125,9 +130,13 @@ PKLExport int pkl_swirl(PKLImage pkl, double factor, int x, int y, int backcolor
125
130
  if(!wrk) return(1);
126
131
  memset(wrk, 0, pkl->width*pkl->height*pkl->channel);
127
132
 
128
- for(i=0; i<pkl->channel; i++)
129
- color[i] = (backcolor>>((pkl->channel-i)*8) & 0xFF);
130
-
133
+ //for(i=0; i<pkl->channel; i++)
134
+ // color[i] = (backcolor>>((pkl->channel-i)*8) & 0xFF);
135
+ if(backcolor)
136
+ memcpy(color, backcolor->color, pkl->channel);
137
+ else
138
+ memset(color, 0xff, pkl->channel);
139
+
131
140
  for(i=0; i<pkl->width*pkl->height; i++)
132
141
  memcpy(&wrk[i*pkl->channel], color, pkl->channel);
133
142
 
@@ -201,531 +210,302 @@ PKLExport int pkl_wave(PKLImage pkl, PKL_WAVE mode, double factor, double freque
201
210
  }
202
211
 
203
212
  //=============================================================================
204
- // pkl_splitframe
213
+ // pkl_rgb2hsb(�F��:Hue/�ʓx:Saturation/���x:Brightness)
205
214
  //=============================================================================
206
- PKLExport int pkl_splitframe(PKLImage pkl, int backcolor, int wbs, int hbs, int margin, int frame)
215
+ static float *pkl_rgb2hsb(unsigned char *rgb, float *hsb)
207
216
  {
208
- unsigned char *wrk, color[PKL_CHANNEL];
209
- int i, j, k, s, t, u, tx, ty;
210
- int offsetx, offsety, width, height, fw, fh;
211
- int warea, harea;
212
- int shift=5;
217
+ #define _max(a,b) (a>b) ? a : b
218
+ #define _min(a,b) (a>b) ? b : a
219
+
220
+ float hue, saturation, brightness;
221
+ unsigned char color_max, color_min;
222
+ unsigned char r, g, b;
223
+ int diff;
224
+
225
+ r = rgb[0];
226
+ g = rgb[1];
227
+ b = rgb[2];
228
+
229
+ color_max= _max(_max(r, g), b);
230
+ color_min= _min(_min(r, g), b);
231
+ diff= color_max - color_min;
232
+
233
+ hue=0.0;
234
+ if(diff != 0){
235
+ if(color_max==r) hue=60*(g-b)/(float)diff;
236
+ if(color_max==g) hue=60*(b-r)/(float)diff + 120.0;
237
+ if(color_max==b) hue=60*(r-g)/(float)diff + 240.0;
238
+ }
239
+ saturation = color_max!=0 ? diff/(float)color_max : 0.0;
240
+ brightness = color_max / 255.0;
213
241
 
214
- if(wbs<=0 || hbs<=0) return(1);
215
- if(margin<0) return(1);
216
- if(frame<1) return(1);
242
+ hsb[0] = hue;
243
+ hsb[1] = saturation;
244
+ hsb[2] = brightness;
217
245
 
218
- //1�‚̕����G���A�̃C���[�W�T�C�Y
219
- warea = pkl->width / wbs;
220
- harea = pkl->height / hbs;
221
- //1�‚̃G���A�̃T�C�Y(�t���[���T�C�Y���܂�)
222
- fw = warea + frame*2;
223
- fh = harea + frame*2;
224
- //�ŏI�I�ȃL�����o�X�̑傫��
225
- width = fw * wbs + margin*2;
226
- height = fh * hbs + margin*2;
246
+ return(hsb);
247
+ }
227
248
 
228
- wrk = malloc(width*height*pkl->channel);
229
- if(!wrk) return(1);
230
-
231
- //�w�i�F�̐ݒ�
232
- for(i=0; i<pkl->channel; i++)
233
- color[i] = (backcolor>>((pkl->channel-i)*8) & 0xFF);
234
- for(i=0; i<width*height; i++)
235
- memcpy(&wrk[i*pkl->channel], color, pkl->channel);
249
+ //=============================================================================
250
+ // pkl_hsb2rgb
251
+ //=============================================================================
252
+ static unsigned char *pkl_hsb2rgb(float *hsb, unsigned char *rgb)
253
+ {
254
+ float h, s, b, f;
255
+ int br, p, q, t, hue;
256
+
257
+ h = hsb[0];
258
+ s = hsb[1];
259
+ b = hsb[2];
236
260
 
237
- srand48(1);
238
- for(i=margin,s=0; i<height-margin; i+=fh,s+=harea){
239
- for(j=margin,t=0; j<width-margin; j+=fw,t+=warea){
240
- offsetx = mrand48()%shift;
241
- offsety = mrand48()%shift;
242
-
243
- //�t�H�g�t���[��
244
- k = i+offsety<0 ? 0 : i+offsety+fh>=height ? height-fh : i+offsety;
245
- for(ty=k; ty<k+fh; ty++){
246
- tx = j+offsetx<0 ? 0 : j+offsetx+fw>=width ? width-fw : j+offsetx;
247
- //�w�i�F(��)
248
- memset(&wrk[(ty*width+tx)*pkl->channel], 0xFF, fw*pkl->channel);
249
- //�V�n�̃t���[��
250
- if(ty==k || ty==k+fh-1)
251
- memset(&wrk[(ty*width+tx)*pkl->channel], 0x00, fw*pkl->channel);
252
- //���E�̃t���[��
253
- memset(&wrk[(ty*width+tx)*pkl->channel], 0x00, pkl->channel);
254
- memset(&wrk[(ty*width+tx+fw-1)*pkl->channel], 0x00, pkl->channel);
255
- }
256
- //�C���[�W
257
- k = i+offsety<0 ? frame : i+offsety+fh>=height ? height-fh+frame : i+offsety+frame;
258
- for(ty=k,u=s; ty<k+harea; ty++,u++){
259
- tx = j+offsetx<0 ? frame : j+offsetx+fw>=width ? width-fw+frame : j+offsetx+frame;
260
- memcpy(&wrk[(ty*width+tx)*pkl->channel], &pkl->image[(u*pkl->width+t)*pkl->channel], warea*pkl->channel);
261
- }
261
+ h = (h>360.0) ? h-360.0 : (h<0.0) ? h+360.0 : h;
262
+ s = (s>1.0) ? 1.0 : (s<0.0) ? 0.0 : s;
263
+ br=(int)(255*b);
264
+ br = PKL_COLOR_CLIP(br);
265
+
266
+ if(s==0.0){
267
+ rgb[0]=br;
268
+ rgb[1]=br;
269
+ rgb[2]=br;
270
+ }else{
271
+ hue=(int)(h/60.0);
272
+ f=h/60.0-hue;
273
+
274
+ p=(int)(br*(1.0-s));
275
+ p = PKL_COLOR_CLIP(p);
276
+
277
+ q=(int)(br*(1.0-f*s));
278
+ q = PKL_COLOR_CLIP(q);
279
+
280
+ t=(int)(br*(1.0-(1.0-f)*s));
281
+ t = PKL_COLOR_CLIP(t);
282
+
283
+ switch(hue){
284
+ case 1:rgb[0]=q; rgb[1]=br; rgb[2]=p; break;
285
+ case 2:rgb[0]=p; rgb[1]=br; rgb[2]=t; break;
286
+ case 3:rgb[0]=p; rgb[1]=q; rgb[2]=br; break;
287
+ case 4:rgb[0]=t; rgb[1]=p; rgb[2]=br; break;
288
+ case 5:rgb[0]=br; rgb[1]=p; rgb[2]=q; break;
289
+ case 0:
290
+ default:
291
+ rgb[0]=br; rgb[1]=t; rgb[2]=p; break;
262
292
  }
263
293
  }
264
-
265
- free(pkl->image);
266
- pkl->image = wrk;
267
- pkl->width = width;
268
- pkl->height = height;
269
- return(0);
294
+ return(rgb);
270
295
  }
271
296
 
272
297
  //=============================================================================
273
- // pkl_colordither
298
+ // pkl_sobelpaint
274
299
  //=============================================================================
275
- PKLExport int pkl_colordither(PKLImage pkl, int weight)
300
+ PKLExport int pkl_sobelpaint(PKLImage pkl, int edgeweight, float mix, float saturation, float hue)
276
301
  {
277
- double FloydSteinberg[2][3] = {
278
- { -1, -1, 7.0/16.0},
279
- { 3.0/16.0, 5.0/16.0, 1.0/16.0} };
280
- unsigned char *wrk, pix, *graypic;
281
- double *pt, err;
282
- int i, j, k, gray, s, t, tx, ty, row, col, xrange;
283
-
284
- row = 3;
285
- col = 2;
286
- pt = &(FloydSteinberg[0][0]);
302
+ //Sobel Filter
303
+ double Fx[3][3] = { {-0.25, 0.0, 0.25},
304
+ {-0.50, 0.0, 0.50},
305
+ {-0.25, 0.0, 0.25}};
306
+ double Fy[3][3] = { {-0.25, -0.50, -0.25},
307
+ { 0.0, 0.0, 0.0},
308
+ { 0.25, 0.50, 0.25}};
309
+ double kg[3] = {0.298912, 0.586611, 0.114478};
310
+ double dx, dy, dR, dG, dB, weight;
311
+ int i, j, tx, ty, offset=1;
312
+ unsigned char *wrk;
313
+ float hsb[3], bright;
314
+
315
+ if(pkl->color != PKL_RGB) return(1);
287
316
 
288
317
  wrk = malloc(pkl->width*pkl->height*pkl->channel);
289
318
  if(!wrk) return(1);
290
319
  memset(wrk, 0xff, pkl->width*pkl->height*pkl->channel);
291
320
 
292
- graypic = malloc(pkl->width*pkl->height);
293
- if(!wrk) return(1);
294
-
295
321
  for(i=0; i<pkl->height; i++){
296
322
  for(j=0; j<pkl->width; j++){
297
- gray=0;
298
- for(k=0; k<pkl->channel; k++)
299
- gray += pkl->image[(i*pkl->width+j)*pkl->channel+k];
300
- graypic[i*pkl->width+j] = PKL_COLOR_CLIP(gray/pkl->channel);
301
- }
302
- }
303
- xrange = (row-1)/2;
304
-
305
- for(i=0; i<pkl->height; i++){
306
- for(j=0; j<pkl->width; j++){
307
- pix = graypic[i*pkl->width+j];
308
- if(pix<127){
309
- memcpy(&wrk[(i*pkl->width+j)*pkl->channel], &pkl->image[(i*pkl->width+j)*pkl->channel], pkl->channel);
310
- }else{
311
- for(k=0; k<pkl->channel; k++)
312
- wrk[(i*pkl->width+j)*pkl->channel+k] = PKL_COLOR_CLIP(pkl->image[(i*pkl->width+j)*pkl->channel+k]+weight);
323
+ if(j-offset<0 || j+offset>=pkl->width || i-offset<0 || i+offset>=pkl->height) continue;
324
+
325
+ dR=dG=dB=0.0;
326
+ for(ty=-offset; ty<=offset; ty++){
327
+ for(tx=-offset; tx<=offset; tx++){
328
+ //if(j+tx<0 || j+tx>=pkl->width || i+ty<0 || i+ty>=pkl->height) continue;
329
+ weight = Fx[ty+offset][tx+offset];
330
+ dR += (pkl->image[((i+ty)*pkl->width+j+tx)*pkl->channel+0] * weight);
331
+ dG += (pkl->image[((i+ty)*pkl->width+j+tx)*pkl->channel+1] * weight);
332
+ dB += (pkl->image[((i+ty)*pkl->width+j+tx)*pkl->channel+2] * weight);
333
+ }
313
334
  }
314
- err = pix>127 ? pix-255 : pix;
315
-
316
- for(s=0; s<col; s++){
317
- for(t=-xrange; t<=xrange; t++){
318
- tx = j+t;
319
- ty = i+s;
320
- if(tx<0 || tx>=pkl->width || ty>=pkl->height) continue;
321
- if (pt[s*row+t+xrange] < 0) continue;
322
- graypic[ty*pkl->width+tx] = PKL_COLOR_CLIP(graypic[ty*pkl->width+tx] + err * pt[s*row+t+xrange]);
335
+ dx = kg[0]*dR + kg[1]*dG + kg[2]*dB;
336
+
337
+ dR=dG=dB=0.0;
338
+ for(ty=-offset; ty<=offset; ty++){
339
+ for(tx=-offset; tx<=offset; tx++){
340
+ //if(j+tx<0 || j+tx>=pkl->width || i+ty<0 || i+ty>=pkl->height) continue;
341
+ weight = Fy[ty+offset][tx+offset];
342
+ dR += (pkl->image[((i+ty)*pkl->width+j+tx)*pkl->channel+0] * weight);
343
+ dG += (pkl->image[((i+ty)*pkl->width+j+tx)*pkl->channel+1] * weight);
344
+ dB += (pkl->image[((i+ty)*pkl->width+j+tx)*pkl->channel+2] * weight);
323
345
  }
324
346
  }
347
+ dy = kg[0]*dR + kg[1]*dG + kg[2]*dB;
348
+
349
+ //RGB->HSB
350
+ pkl_rgb2hsb(&pkl->image[(i*pkl->width+j)*pkl->channel], hsb);
351
+
352
+ //���x�ɂ̂�sobel��K�p���Č����x�ƍ�������
353
+ bright = hsb[2];
354
+ hsb[2] = sqrt(dx*dx+dy*dy) * edgeweight * 0.01;
355
+ hsb[2] = (hsb[2]>1.0) ? 0.0 : 1.0-hsb[2];
356
+ hsb[2] = hsb[2]*(1.0-mix) + bright*mix;
357
+
358
+ //�ʓx����
359
+ hsb[1] *= saturation;
360
+
361
+ //�F������
362
+ hsb[0] += hue;
363
+
364
+ //HSB->RGB
365
+ pkl_hsb2rgb(hsb, &wrk[(i*pkl->width+j)*pkl->channel]);
325
366
  }
326
367
  }
327
- free(graypic);
328
368
  free(pkl->image);
329
- pkl->image = wrk;
369
+ pkl->image=wrk;
330
370
  return(0);
331
371
  }
332
372
 
333
-
334
373
  //=============================================================================
335
- // pkl_ttt
374
+ // pkl_illust
336
375
  //=============================================================================
337
- PKLExport int pkl_ttt(PKLImage pkl)
376
+ PKLExport int pkl_illust(PKLImage pkl, int gap, int edge, int gammaint)
338
377
  {
378
+ int sobel1[9] = { 1, 0, -1, 2, 0, -2, 1, 0, -1 }; //sobel filter
379
+ int sobel2[9] = { 1, 2, 1, 0, 0, 0, -1, -2, -1 }; //sobel filter
380
+ int i, j, k, s, t, px, py, rp, r1, r2, gt;
381
+ int wx[PKL_CHANNEL], wy[PKL_CHANNEL], rate[PKL_CHANNEL];
339
382
  unsigned char *wrk;
340
- int i, j, s, t, k, clipx, clipy;
341
- int color[PKL_CHANNEL];
342
-
343
- int matrix[9] = { 0, 0, -1,
344
- 0, 0, 0,
345
- 1, 0, 0 };
346
-
347
- // { PKL_EMBOSS_EMBOSS, { 0, 0, -1,
348
- // 0, 0, 0,
349
- // 1, 0, 0 }},
350
- //
351
- // { PKL_EMBOSS_LAPLACIAN, {-1, -1, -1,
352
- // -1, 8, -1,
353
- // -1, -1, -1 }},
354
- //
355
- // { PKL_EMBOSS_HEAVY, { 2, 0, 0,
356
- // 0, -1, 0,
357
- // 0, 0, -1 }},
358
- //
359
- // { PKL_EMBOSS_LIGHT, { 0, 0, 0,
360
- // 0, 1, 0,
361
- // 0, 0, -1 }},
383
+ double gamma;
384
+ int th1, th2, th3;
362
385
 
363
-
364
-
365
- wrk = malloc(pkl->width*pkl->height);
386
+ wrk = malloc(pkl->width*pkl->height*pkl->channel);
366
387
  if(!wrk) return(1);
367
- memset(wrk, 0, pkl->width*pkl->height);
368
-
388
+
389
+ gamma = 1.0/((double)gammaint/100.0);
390
+ th1 = (int)(pow(128.0/255.0, gamma)*255.0);
391
+ th2 = (int)(pow( 96.0/255.0, gamma)*255.0);
392
+ th3 = (int)(pow( 64.0/255.0, gamma)*255.0);
393
+
369
394
  for(i=0; i<pkl->height; i++){
370
395
  for(j=0; j<pkl->width; j++){
371
- memset(color, 0, sizeof(color));
396
+
397
+ memset(wx, 0, sizeof(wx));
398
+ memset(wy, 0, sizeof(wy));
399
+
372
400
  for(s=0; s<3; s++){
373
401
  for(t=0; t<3; t++){
374
- clipx = (j+t)>=pkl->width ? pkl->width-1 : j+t;
375
- clipy = (i+s)>=pkl->height ? pkl->height-1 : i+s;
376
- //for(k=0; k<pkl->channel; k++)
377
- color[0] += pkl->image[(clipy*pkl->width+clipx) * pkl->channel + 0] * matrix[t+s*3];
402
+ px = (j+t-1)<0 ? 0 : (j+t-1)>=pkl->width ? pkl->width-1 : (j+t-1);
403
+ py = (i+s-1)<0 ? 0 : (i+s-1)>=pkl->height ? pkl->height-1 : (i+s-1);
404
+ for(k=0; k<pkl->channel; k++){
405
+ wx[k] += pkl->image[(py*pkl->width+px)*pkl->channel+k] * sobel1[s*3+t];
406
+ wy[k] += pkl->image[(py*pkl->width+px)*pkl->channel+k] * sobel2[s*3+t];
407
+ }
378
408
  }
379
409
  }
380
410
 
381
- //for(k=0; k<pkl->channel; k++)
382
- wrk[i*pkl->width+j] = PKL_COLOR_CLIP(color[0]-127);
411
+ for(k=0; k<pkl->channel; k++)
412
+ rate[k] = (int)(sqrt((double)(wx[k]*wx[k]+wy[k]*wy[k]))/8.0);
413
+ rp = 0;
414
+ for(k=0; k<pkl->channel; k++)
415
+ if(rate[k]>rp) rp=rate[k];
416
+ r1 = (rp<edge) ? 255 : (rp<edge+gap) ? 255-255*(rp-edge)/gap : 0;
417
+
418
+ gt = 0;
419
+ for(k=0; k<pkl->channel; k++)
420
+ gt += pkl->image[(i*pkl->width+j)*pkl->channel+k];
421
+ gt /= pkl->channel;
422
+ r2 = (gt>th1) ? 255 : (gt>th2) ? 128 : (gt>th3) ? 64 : 0;
423
+
424
+ for(k=0; k<pkl->channel; k++)
425
+ wrk[(i*pkl->width+j)*pkl->channel+k] = PKL_COLOR_CLIP(pkl->image[(i*pkl->width+j)*pkl->channel+k] * r1/256*r2/256);
383
426
  }
384
427
  }
428
+
429
+ free(pkl->image);
430
+ pkl->image = wrk;
431
+ return(0);
432
+ }
433
+
434
+ //=============================================================================
435
+ // pkl_color_emboss
436
+ //=============================================================================
437
+ PKLExport int pkl_color_emboss(PKLImage pkl, double mil, double env)
438
+ {
439
+ int sobel1[9] = { 1, 0, -1, 2, 0, -2, 1, 0, -1 }; //sobel filter
440
+ int sobel2[9] = { 1, 2, 1, 0, 0, 0, -1, -2, -1 }; //sobel filter
441
+ int i, j, k, s, t, wx, wy, gt, px, py;
442
+ unsigned char *wrk, color[PKL_CHANNEL];
443
+ double dx, dy, dz, light[3], abl;
444
+
445
+ wrk = malloc(pkl->width*pkl->height*pkl->channel);
446
+ if(!wrk) return(1);
447
+ memset(wrk, 0, pkl->width*pkl->height*pkl->channel);
448
+
449
+ //�����x�N�g����P�ʃx�N�g���ɕ␳����
450
+ abl = sqrt(-1.0*-1.0 + -1.0*-1.0 + 1.0*1.0);
451
+ light[0] = -1.0/abl;
452
+ light[1] = -1.0/abl;
453
+ light[2] = 1.0/abl;
385
454
 
386
455
  for(i=0; i<pkl->height; i++){
387
456
  for(j=0; j<pkl->width; j++){
457
+ wx=wy=0;
458
+ for(s=0; s<3; s++){
459
+ for(t=0; t<3; t++){
460
+ px = (j+t-1)<0 ? 0 : (j+t-1)>=pkl->width ? pkl->width-1 : (j+t-1);
461
+ py = (i+s-1)<0 ? 0 : (i+s-1)>=pkl->height ? pkl->height-1 : (i+s-1);
462
+
463
+ gt=0;
464
+ for(k=0; k<pkl->channel; k++)
465
+ gt += pkl->image[(py*pkl->width+px)*pkl->channel+k];
466
+ gt /= pkl->channel;
467
+ wx += gt*sobel1[s*3+t];
468
+ wy += gt*sobel2[s*3+t];
469
+ }
470
+ }
471
+ dx = (double)wx;
472
+ dy = (double)wy;
473
+ dz = 16.0;
388
474
  for(k=0; k<pkl->channel; k++)
389
- pkl->image[(i*pkl->width+j)*pkl->channel+k] =
390
- PKL_COLOR_CLIP((pkl->image[(i*pkl->width+j)*pkl->channel+k] - wrk[i*pkl->width+j]));
475
+ color[k] = lighting(pkl->image[(py*pkl->width+px)*pkl->channel+k], dx, dy, dz, mil, env, light);
476
+ memcpy(&wrk[(i*pkl->width+j)*pkl->channel], color, pkl->channel);
391
477
  }
392
478
  }
393
-
394
479
 
395
- free(wrk);
480
+ free(pkl->image);
481
+ pkl->image = wrk;
482
+
396
483
  return(0);
397
484
  }
398
485
 
486
+ //=============================================================================
487
+ // �A�e�t��
488
+ // (dx,dy,dz)��@���x�N�g���Ƃ���i�P�ʃx�N�g���łȂ��Ă��悢�j
489
+ //=============================================================================
490
+ static unsigned char lighting(unsigned char color, double dx, double dy, double dz,
491
+ double mil, double env, double *light)
492
+ {
493
+ double abl, rz, env2, cosT, cosT2;
494
+ int res;
495
+
496
+ //�@���x�N�g����P�ʃx�N�g���ɕ␳
497
+ abl = sqrt(dx*dx + dy*dy + dz*dz);
498
+ cosT = (dx/abl)*light[0] + (dy/abl)*light[1] + (dz/abl)*light[2];
499
+ rz = 2.0*cosT*(dz/abl) - light[2];
500
+ cosT2 = (rz>0.0) ? pow(rz, 12.0) : 0.0;
501
+ cosT = (cosT<0.0) ? 0.0 : cosT;
502
+
503
+ env2=env*255.0/100.0;
504
+ res=(int)((cosT*255.0+env2)*(double)color/255.0);
505
+
506
+ if(res>color) res=color;
507
+ res+=(mil*cosT2);
508
+
509
+ return(PKL_COLOR_CLIP(res));
510
+ }
399
511
 
400
-
401
- ////=============================================================================
402
- //// pkl_sketch
403
- ////=============================================================================
404
- //PKLExport int pkl_sketch(PKLImage pkl)
405
- //{
406
- // unsigned char *wrk, ave[PKL_CHANNEL];
407
- // int color[PKL_CHANNEL];
408
- // int i, j, k, s;
409
- // int weight=10;
410
- // int sx, sy, dx, dy, x1, x2, y1, y2, xadder;
411
- // double t, adder;
412
- //
413
- // wrk = malloc(pkl->width*pkl->height*pkl->channel);
414
- // if(!wrk) return(1);
415
- // memset(wrk, 0xff, pkl->width*pkl->height*pkl->channel);
416
- //
417
- // srand48(1);
418
- // for(i=0; i<pkl->height; i+=weight){
419
- // for(j=0; j<pkl->width; j+=weight){
420
- //
421
- // for(k=0; k<weight*2; k++){
422
- // //�����_���ȂQ�_�𐶐�
423
- // x1 = j + mrand48()%weight;
424
- // y1 = i + mrand48()%weight;
425
- // x2 = j + mrand48()%weight;
426
- // y2 = i + mrand48()%weight;
427
- //
428
- // sx = x1;
429
- // dx = x2;
430
- // sy = y1<y2 ? y1 : y2;
431
- // dy = y1<y2 ? y2 : y1;
432
- //
433
- // sx = sx<0 ? 0 : sx>=pkl->width ? pkl->width-1 : sx;
434
- // dx = dx<0 ? 0 : dx>=pkl->width ? pkl->width-1 : dx;
435
- // sy = sy<0 ? 0 : sy>=pkl->height ? pkl->height-1 : sy;
436
- // dy = dy<0 ? 0 : dy>=pkl->height ? pkl->height-1 : dy;
437
- //
438
- // if(dx-sx != 0)
439
- // adder = (double)(dy-sy)/(double)(dx-sx);
440
- // else
441
- // adder=1.0;
442
- //
443
- // if(sx<dx){
444
- // for(s=sx,t=sy; s<dx; s++,t+=adder){
445
- // if(t<pkl->height)
446
- // memcpy(&wrk[((int)t*pkl->width+s)*pkl->channel], &pkl->image[((int)t*pkl->width+s)*pkl->channel], pkl->channel);
447
- // }
448
- // }else{
449
- // for(s=sx,t=sy; s>=dx; s--,t-=adder){
450
- // if(t>0.0)
451
- // memcpy(&wrk[((int)t*pkl->width+s)*pkl->channel], &pkl->image[((int)t*pkl->width+s)*pkl->channel], pkl->channel);
452
- // }
453
- // }
454
- // }
455
- // }
456
- // }
457
- //
458
- // free(pkl->image);
459
- // pkl->image = wrk;
460
- // return(0);
461
- //}
462
-
463
-
464
-
465
-
466
-
467
-
468
-
469
- // /** �X�g���[�N�̒��� */
470
- // int LENGTH = 10; //1..50
471
- // /** �u���V�̑傫�� */
472
- // int BRUSHSIZE = 8; //1..50
473
- // /** �Z�W����**/
474
- // int Gray = 124; //50..200
475
- // /** ���l */
476
- // float ALPHA = .8f; //0.01 .. 1.0
477
- //
478
- // /** �C���[�W�̃\�[�X */
479
- // protected AnimatedImage AI;
480
- // protected int width;
481
- // protected int height;
482
- //
483
- // /** (r, g, b)����P�x���Z�o���� */
484
- // public int getLuminance(int r, int g, int b){
485
- // return (int)(0.3f*r + 0.59f*g + 0.11f*b);
486
- // }
487
- //
488
- // /** �摜�̃t�B���^�����O���s�� */
489
- // public void filter(AnimatedImage AI){
490
- // this.AI = AI;
491
- // width = AI.getWidth();
492
- // height = AI.getHeight();
493
- //
494
- // Random rand = new Random(System.currentTimeMillis());
495
- //
496
- // //�o�b�t�@�̏�����
497
- // setUpBuffer();
498
- //
499
- // //�z���C�g�m�C�Y
500
- // for (int y=0; y<height; y++) {
501
- // for (int x=0; x<width; x++) {
502
- // int r = AI.getR(x, y);
503
- // int g = AI.getG(x, y);
504
- // int b = AI.getB(x, y);
505
- // int G=getLuminance(r,g,b);
506
- // double T = 0.2*(1-G/40);
507
- // double P = rand.nextInt()%1.0;
508
- // if(P>=T)AI.setRGB(x, y, 255, 255, 255);
509
- // else AI.setRGB(x, y, 0, 0, 0);
510
- // }
511
- // }
512
- //
513
- // //�����_���ɃX�g���[�N��z�u
514
- // for (int i = 0; i < height; i++) {
515
- // for(int j = 0; j < width/5; j++){
516
- // int x = Math.abs(rand.nextInt()) % width;
517
- // int y = i + Math.abs(rand.nextInt()) % (LENGTH+BRUSHSIZE);
518
- // if ( y<0 || y>=height ) continue;
519
- //
520
- // int r = AI.getR(x, y);
521
- // int g = AI.getG(x, y);
522
- // int b = AI.getB(x, y);
523
- //
524
- // //�u���V�X�g���[�N��`��
525
- // drawPenStroke(x, y, r, g, b);
526
- // }
527
- // }
528
- // return;
529
- // }
530
- //
531
- // //* �y���X�g���[�N���P�•`�悷��
532
- // protected void drawPenStroke(int x, int y, int r, int g, int b){
533
- // // �摜�̋P�x�̌��z�������擾
534
- // Point dir = getDirection(x, y);
535
- // float vx, vy, l;
536
- // vx = -dir.y/255.0f;
537
- // vy = dir.x/255.0f;
538
- // l = (float)Math.sqrt(vx*vx+vy*vy);
539
- // vx /= l;
540
- // vy /= l;
541
- //
542
- // //�`��̈���w�肷��
543
- // int vxl = (int)(vx * LENGTH);
544
- // int vyl = (int)(vy * LENGTH);
545
- // int vxb = (int)(vx * BRUSHSIZE / 2);
546
- // int vyb = (int)(vy * BRUSHSIZE / 2);
547
- // int sx = x - vxl, sy = y - vyl ; //�n�_
548
- // int ex = x + vxl, ey = y + vyl; //�I�_
549
- //
550
- // writeLine(sx - vyb, sy + vxb, ex - vyb, ey + vxb);
551
- // //�`��̈���w��F�œh��‚Ԃ��B
552
- // paintBuffer(r, g, b, ALPHA);
553
- // }
554
- //
555
- // //* �P�x�̌��z�������擾����
556
- // protected Point getDirection(int x, int y){
557
- // int vx, vy;
558
- // int[][] pixel = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
559
- //
560
- // for(int i = 0; i < pixel.length; i++){
561
- // int yy = y + i - 1;
562
- //
563
- // if(yy < 0) continue;
564
- // else if(yy >= height) break;
565
- //
566
- // for(int j = 0; j < pixel[i].length; j++){
567
- // int xx = x + j - 1;
568
- //
569
- // if(xx < 0) continue;
570
- // else if(xx >= width) break;
571
- //
572
- // int r = AI.getR(xx, yy);
573
- // int g = AI.getG(xx, yy);
574
- // int b = AI.getB(xx, yy);
575
- //
576
- // pixel[i][j] = getLuminance(r, g, b);
577
- // }
578
- // }
579
- //
580
- // vx = - pixel[0][0] + pixel[0][2] - 2 * pixel[1][0] + 2 * pixel[1][2] - pixel[2][0] + pixel[2][2];
581
- // vy = - pixel[0][0] + pixel[2][0] - 2 * pixel[0][1] + 2 * pixel[2][1] - pixel[0][2] + pixel[2][2];
582
- //
583
- // return new Point(vx, vy);
584
- // }
585
- //
586
- // //**************************************************************************
587
- // // �ȍ~�A�O���t�B�b�N�X�֘A�̃����o���L�q����
588
- // //**************************************************************************
589
- //
590
- // /* �`��̈�𒲂ׂ邽�߂̃o�b�t�@�B
591
- // * �`��̈�͓ʂł���Ɖ��肵�Ă���B
592
- // * ��{(x, y) | y �� {0, ... height - 1}, buf[y][0] <= x <= buf[y][1]}
593
- // * �ŕ\�����̈悪�`��̈�ƂȂ�B
594
- // */
595
- // protected int[][] buf;
596
- //
597
- // /** �`��̈��y���W�̍ŏ��l */
598
- // protected int yMin;
599
- //
600
- // /** �`��̈��y���W�̍ő�l */
601
- // protected int yMax;
602
- //
603
- //
604
- // /**
605
- // * buf�̏��������s���B
606
- // * �n�߂ɂP�x�����Ăяo�����ƁB
607
- // */
608
- // protected void setUpBuffer(){
609
- // buf = new int[height][2];
610
- // yMin = 0;
611
- // yMax = height - 1;
612
- // clearBuffer();
613
- // }
614
- //
615
- // //* buf�̓��e���N���A����B
616
- // protected void clearBuffer(){
617
- // if(yMin < 0) yMin = 0;
618
- // if(yMax >= height) yMax = height - 1;
619
- //
620
- // for(int i = yMin; i <= yMax; i++){
621
- // buf[i][0] = width - 1; //�ŏ��l�̏����l�͍ő�l
622
- // buf[i][1] = 0; //�ő�l�̏����l�͍ŏ��l
623
- // }
624
- // yMin = height - 1; //�ŏ��l�̏����l�͍ő�l
625
- // yMax = 0; //�ő�l�̏����l�͍ŏ��l
626
- // }
627
- //
628
- // // * buf�ŕ\�����`��̈��F(r, g, b, a)�œh��‚Ԃ��B
629
- // protected void paintBuffer(int r, int g, int b, float a){
630
- // if(yMin < 0) yMin = 0;
631
- // if(yMax >= height) yMax = height - 1;
632
- //
633
- // for(int y = yMin; y <= yMax; y++){
634
- // if(buf[y][0] < 0) buf[y][0] = 0;
635
- // if(buf[y][1] >= width) buf[y][1] = width - 1;
636
- //
637
- // for(int x = buf[y][0]; x <= buf[y][1]; x++){
638
- // int G=(int)(0.299*r+0.587*g+0.114*b);
639
- // if(G>=3*Gray/2)
640
- // AI.setRGBA(x, y,255, 255, 255, a);
641
- // else if(G>=Gray&&G<3*Gray/2)
642
- // AI.setRGBA(x, y,170, 170, 170, a);
643
- // else if(G<Gray&&G>Gray/2)
644
- // AI.setRGBA(x, y,80, 80, 80, a);
645
- // else
646
- // AI.setRGBA(x, y,0, 0, 0, a);
647
- // }
648
- // }
649
- // clearBuffer();
650
- // }
651
- //
652
- //// * �_�f�[�^��buf�ɏ������ށB
653
- //// * yMin, yMax�͍X�V����Ȃ����Ƃɒ��ӁB
654
- // protected void writePoint(int x, int y){
655
- // if(y < 0 || y >= height) return;
656
- // if(x < buf[y][0]) buf[y][0] = x;
657
- // if(x > buf[y][1]) buf[y][1] = x;
658
- // }
659
- //
660
- //
661
- // /**
662
- // * �����f�[�^��buf�ɏ������ށB
663
- // * �u���[���n���̃A���S���Y����p���Ă���B
664
- // */
665
- // protected void writeLine(int x1, int y1, int x2, int y2){
666
- // //yMin, yMax�̍X�V
667
- // if(y1 < yMin) yMin = y1;
668
- // if(y1 > yMax) yMax = y1;
669
- // if(y2 < yMin) yMin = y2;
670
- // if(y2 > yMax) yMax = y2;
671
- //
672
- // //dx, dy: X, Y�������̋���
673
- // int dx = x2 - x1, dy = y2 - y1;
674
- // int sx, sy; //dx, dy�̕�������
675
- //
676
- // if(dx >= 0)
677
- // sx = 1;
678
- // else{
679
- // sx = -1; dx = -dx;
680
- // }
681
- // if(dy >= 0)
682
- // sy = 1;
683
- // else{
684
- // sy = -1; dy = -dy;
685
- // }
686
- //
687
- // int x = x1, y = y1;
688
- // int d, tmp;
689
- //
690
- // if(dx >= dy){
691
- // dy += dy; //dy *= 2
692
- // d = dy - dx;
693
- // tmp = dy - 2 * dx;
694
- //
695
- // //(x, y)��check
696
- // writePoint(x, y);
697
- //
698
- // for(int i = 0; i < dx; i++){
699
- // if(d > 0){
700
- // y += sy; d += tmp;
701
- // }else
702
- // d += dy;
703
- //
704
- // x += sx;
705
- //
706
- // //(x, y)��check
707
- // writePoint(x, y);
708
- // }
709
- // }else{
710
- // dx += dx; //dx *= 2
711
- // d = dx - dy;
712
- // tmp = dx - 2 * dy;
713
- //
714
- // //(x, y)��check
715
- // writePoint(x, y);
716
- //
717
- // for(int i = 0; i < dy; i++){
718
- // if(d > 0){
719
- // x += sx; d += tmp;
720
- // }else
721
- // d += dx;
722
- //
723
- // y += sy;
724
- //
725
- // //(x, y)��check
726
- // writePoint(x, y);
727
- // }
728
- // }
729
- // }
730
- //
731
- //}