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,12 +9,38 @@
9
9
  #include "pikl.h"
10
10
  #include "pikl_private.h"
11
11
 
12
- //unsharp target pixel
13
- #define RADIUS 1
12
+ struct PKL_FILTER {
13
+ int type;
14
+ int matrix[9];
15
+ };
14
16
 
15
- typedef struct {
16
- int max, min;
17
- long data[PKL_COLOR];
18
- } PKL_HISTGRAM;
17
+ struct PKL_FILTER emboss_filter[] =
18
+ {
19
+ { PKL_EMBOSS_EMBOSS, { 0, 0, -1,
20
+ 0, 0, 0,
21
+ 1, 0, 0 }},
22
+ { PKL_EMBOSS_LAPLACIAN, {-1, -1, -1,
23
+ -1, 8, -1,
24
+ -1, -1, -1 }},
25
+ { PKL_EMBOSS_HEAVY, { 2, 0, 0,
26
+ 0, -1, 0,
27
+ 0, 0, -1 }},
28
+ { PKL_EMBOSS_LIGHT, { 0, 0, 0,
29
+ 0, 1, 0,
30
+ 0, 0, -1 }},
31
+ };
32
+
33
+ struct PKL_FILTER focus_filter[] =
34
+ {
35
+ { PKL_FOCUS_DETAIL, { 0, -1, 0,
36
+ -1, 10, -1,
37
+ 0, -1, 0 }},
38
+ { PKL_FOCUS_EDGES, {-1, -1, -1,
39
+ -1, 9, -1,
40
+ -1, -1, -1 }},
41
+ { PKL_FOCUS_FOCUS, {-1, 0, -1,
42
+ 0, 7, 0,
43
+ -1, 0, -1 }},
44
+ };
19
45
 
20
46
  #endif
@@ -0,0 +1,274 @@
1
+ #include "pikl_enhance.h"
2
+
3
+ //=================================================================================
4
+ // pkl_unsharp
5
+ //=================================================================================
6
+ PKLExport int pkl_unsharp(PKLImage pkl, int threshold, double edge)
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);
13
+ if(!wrk) return(1);
14
+ memset(wrk, 0, pkl->height * pkl->width * pkl->channel);
15
+
16
+ for(i=0; i<pkl->height; i++){
17
+ for(j=0; j<pkl->width; j++){
18
+ cnt = 0;
19
+ memset(stock, 0, sizeof(stock));
20
+
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++;
26
+ }
27
+ }
28
+ }
29
+ s = &wrk[(i * pkl->width + j) * pkl->channel];
30
+ for(k=0; k<pkl->channel; k++)
31
+ *s++ = stock[k] / cnt;
32
+ }
33
+ }
34
+
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);
38
+ }
39
+ free(wrk);
40
+ return(0);
41
+ }
42
+
43
+ //=================================================================================
44
+ // pkl_contrast
45
+ //=================================================================================
46
+ PKLExport int pkl_contrast(PKLImage pkl, int rate)
47
+ {
48
+ unsigned char ct[PKL_COLOR];
49
+ int value, i;
50
+
51
+ if(rate < -127 || rate > 127) return(1);
52
+
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);
58
+ }
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);
64
+ }
65
+ }
66
+
67
+ for(i=0; i<pkl->width*pkl->height*pkl->channel; i++)
68
+ pkl->image[i] = ct[pkl->image[i]];
69
+
70
+ return(0);
71
+ }
72
+
73
+ //=================================================================================
74
+ // pkl_level def=0.0050
75
+ //=================================================================================
76
+ PKLExport int pkl_level(PKLImage pkl, double low, double high, double coeff)
77
+ {
78
+ PKL_HISTGRAM hst[PKL_CHANNEL];
79
+ int i, j, cnt, value;
80
+ double lt, ht;
81
+
82
+ if((low < 0.0 && low > 100.0) ||
83
+ (high < 0.0 && high > 100.0) ||
84
+ (coeff< 0.0 && coeff> 2.0)) return(1);
85
+
86
+ memset(&hst, 0, sizeof(hst));
87
+ for(i=0; i<pkl->height*pkl->width; i++){
88
+ for(j=0; j<pkl->channel; j++){
89
+ hst[j].data[ pkl->image[i*pkl->channel+j] ]++;
90
+ }
91
+ }
92
+
93
+ lt = (low / 100.0) * pkl->height * pkl->width;
94
+ ht = (high / 100.0) * pkl->height * pkl->width;
95
+
96
+ for(i=0; i<pkl->channel; i++){
97
+ cnt=0;
98
+ for(j=0; j<PKL_COLOR; j++){
99
+ cnt += hst[i].data[j];
100
+ if(cnt > lt){
101
+ hst[i].min = j;
102
+ break;
103
+ }
104
+ }
105
+ cnt=0;
106
+ for(j=PKL_COLOR-1; j>=0; j--){
107
+ cnt += hst[i].data[j];
108
+ if(cnt > ht){
109
+ hst[i].max = j;
110
+ break;
111
+ }
112
+ }
113
+ }
114
+
115
+ //�q�X�g�O��������e�[�u���𐶐�
116
+ for(i=0; i<pkl->channel; i++){
117
+ for(j=0; j<PKL_COLOR; j++){
118
+ value = ((coeff * j)-hst[i].min) / (hst[i].max-hst[i].min+1) * 255;
119
+ hst[i].data[j] = PKL_COLOR_CLIP(value);
120
+ }
121
+ }
122
+
123
+ for(i=0; i<pkl->width*pkl->height; i++)
124
+ for(j=0; j<pkl->channel; j++)
125
+ pkl->image[i*pkl->channel+j] = hst[j].data[pkl->image[i*pkl->channel+j]];
126
+
127
+ return(0);
128
+ }
129
+
130
+ //=============================================================================
131
+ // pkl_brightness
132
+ //=============================================================================
133
+ PKLExport int pkl_brightness(PKLImage pkl, int color)
134
+ {
135
+ int i;
136
+ for(i=0; i<pkl->width*pkl->height*pkl->channel; i++)
137
+ pkl->image[i] = PKL_COLOR_CLIP(pkl->image[i] + color);
138
+ return(0);
139
+ }
140
+
141
+ //=============================================================================
142
+ // pkl_hls
143
+ //=============================================================================
144
+ PKLExport int pkl_hls(PKLImage pkl, double ym, double sm, double hd)
145
+ {
146
+ int i;
147
+ double c1, c2; //�F�M��
148
+ double y, s, h; //y=�P�x, s=�ʓx, h=�F��
149
+
150
+ if(pkl->color != PKL_RGB) return(1);
151
+
152
+ for(i=0; i<pkl->width*pkl->height; i++){
153
+ /* �P�x,�F�M��1,2 */
154
+ y = 0.299 * pkl->image[i*pkl->channel] +
155
+ 0.587 * pkl->image[i*pkl->channel+1] +
156
+ 0.114 * pkl->image[i*pkl->channel+2];
157
+ c1 = pkl->image[i*pkl->channel] - y;
158
+ c2 = pkl->image[i*pkl->channel+2] - y;
159
+
160
+ /* �ʓx */
161
+ s = sqrt(c1*c1 + c2*c2);
162
+
163
+ /* �F�� */
164
+ if(s < 0.0) h = 0.0;
165
+ else h = atan2(c1, c2) * 180.0 / M_PI;
166
+
167
+ /* ������������ */
168
+ y *= (1 + ym);
169
+ s *= (1 + sm);
170
+ h += hd;
171
+
172
+ /* �����l����RGB�ɖ߂� */
173
+ c1 = s * sin(M_PI * h / 180.0);
174
+ c2 = s * cos(M_PI * h / 180.0);
175
+
176
+ pkl->image[i*pkl->channel] = PKL_COLOR_CLIP(c1 + y);
177
+ pkl->image[i*pkl->channel+1] = PKL_COLOR_CLIP(y - (0.299*c1 + 0.114*c2)/0.587);
178
+ pkl->image[i*pkl->channel+2] = PKL_COLOR_CLIP(c2 + y);
179
+ }
180
+ return(0);
181
+ }
182
+
183
+ //=================================================================================
184
+ // pkl_gamma
185
+ //=================================================================================
186
+ PKLExport int pkl_gamma(PKLImage pkl, double gm)
187
+ {
188
+ unsigned char gt[PKL_COLOR];
189
+ int i;
190
+
191
+ if(gm < 0.0) return(1);
192
+
193
+ for(i=0; i<PKL_COLOR; i++)
194
+ gt[i] = PKL_COLOR_CLIP(255.0 * pow(i/255.0, 1.0/gm));
195
+
196
+ for(i=0; i<pkl->width*pkl->height*pkl->channel; i++)
197
+ pkl->image[i] = gt[pkl->image[i]];
198
+
199
+ return(0);
200
+ }
201
+
202
+ //=============================================================================
203
+ // pkl_noisecut(median filter)
204
+ //=============================================================================
205
+ PKLExport int pkl_noisecut(PKLImage pkl)
206
+ {
207
+ unsigned char *wrk, *p, sort[PKL_CHANNEL][9], median[PKL_CHANNEL];
208
+ int i, j, tx, ty, k, clipx, clipy, rd, s, t, n;
209
+
210
+ wrk = malloc(pkl->width*pkl->height*pkl->channel);
211
+ if(!wrk) return(1);
212
+ memset(wrk, 0, pkl->width*pkl->height*pkl->channel);
213
+
214
+ for(i=0; i<pkl->height; i++){
215
+ for(j=0; j<pkl->width; j++){
216
+ rd=0;
217
+ for(ty=-1; ty<=1; ty++){
218
+ for(tx=-1; tx<=1; tx++){
219
+ clipx = j+tx < 0 ? 0 : j+tx>=pkl->width ? pkl->width-1 : j+tx;
220
+ clipy = i+ty < 0 ? 0 : i+ty>=pkl->height ? pkl->height-1 : i+ty;
221
+ p = &pkl->image[(clipy*pkl->width+clipx)*pkl->channel];
222
+ for(k=0; k<pkl->channel; k++)
223
+ sort[k][rd] = *p++;
224
+ rd++;
225
+ }
226
+ }
227
+ //�����l�T��
228
+ for(k=0; k<pkl->channel; k++){
229
+ for(s=0; s<5; s++){
230
+ for(t=1,n=0,median[k]=sort[k][0]; t<9; t++){
231
+ if(median[k]<sort[k][t]){
232
+ median[k]=sort[k][t];
233
+ n=t;
234
+ }
235
+ }
236
+ sort[k][n]=0;
237
+ }
238
+ }
239
+ p= &wrk[(i*pkl->width+j)*pkl->channel];
240
+ for(k=0; k<pkl->channel; k++) *p++=median[k];
241
+ }
242
+ }
243
+
244
+ free(pkl->image);
245
+ pkl->image = wrk;
246
+ return(0);
247
+ }
248
+
249
+ //=================================================================================
250
+ // pkl_trim
251
+ //=================================================================================
252
+ PKLExport int pkl_trim(PKLImage pkl, int sx, int sy, int width, int height)
253
+ {
254
+ unsigned char *wrk;
255
+ int p, y;
256
+
257
+ if( sx < 0 || sy < 0 || width <= 0 || height <= 0 ) return(1);
258
+ if( sx+width > pkl->width ) return(1);
259
+ if( sy+height > pkl->height ) return(1);
260
+
261
+ wrk = malloc(height * width * pkl->channel);
262
+ if(!wrk) return(1);
263
+
264
+ for(p=0,y=sy; y<sy+height; p++,y++){
265
+ memcpy(&wrk[p*width*pkl->channel], &pkl->image[(y*pkl->width+sx)*pkl->channel], width*pkl->channel);
266
+ }
267
+
268
+ free(pkl->image);
269
+ pkl->image = wrk;
270
+ pkl->height = height;
271
+ pkl->width = width;
272
+
273
+ return(0);
274
+ }
@@ -0,0 +1,20 @@
1
+ #ifndef _LIB_PIKL_ENHANCE_
2
+ #define _LIB_PIKL_ENHANCE_
3
+
4
+ #include <stdio.h>
5
+ #include <stdlib.h>
6
+ #include <string.h>
7
+ #include <math.h>
8
+
9
+ #include "pikl.h"
10
+ #include "pikl_private.h"
11
+
12
+ //unsharp target pixel
13
+ #define RADIUS 1
14
+
15
+ typedef struct {
16
+ int max, min;
17
+ long data[PKL_COLOR];
18
+ } PKL_HISTGRAM;
19
+
20
+ #endif
@@ -1,48 +1,114 @@
1
1
  #include "pikl_io.h"
2
2
 
3
3
  static int format_type(PKLImage pkl, FILE *image);
4
+
4
5
  //=============================================================================
5
- // pkl_open
6
+ // pkl_canvas
6
7
  //=============================================================================
7
- PKLExport PKLImage pkl_open(const char *in)
8
+ PKLExport PKLImage pkl_canvas(int width, int height, PKL_COLOR_SPACE color, PKLColor backcolor)
8
9
  {
9
10
  PKLImage pkl;
10
- FILE *image;
11
- int result=0;
11
+ PKL_COLOR_SPACE colorspace;
12
+ int channel, i;
13
+ unsigned char back[PKL_CHANNEL];
14
+
15
+ switch(color){
16
+ case PKL_GRAYSCALE:
17
+ colorspace = PKL_GRAYSCALE;
18
+ channel = 1;
19
+ break;
20
+ case PKL_RGB:
21
+ colorspace = PKL_RGB;
22
+ channel = 3;
23
+ break;
24
+ case PKL_CMYK:
25
+ colorspace = PKL_CMYK;
26
+ channel = 4;
27
+ break;
28
+ default:
29
+ return(NULL);
30
+ }
12
31
 
13
32
  pkl = malloc( sizeof(struct _PKLImage) );
14
33
  if(!pkl) return(NULL);
15
34
  memset(pkl, 0, sizeof(struct _PKLImage));
16
35
 
36
+ pkl->image = malloc(width*height*channel);
37
+ if(!pkl->image){
38
+ free(pkl);
39
+ return(NULL);
40
+ }
41
+
42
+ pkl->width = width;
43
+ pkl->height = height;
44
+ pkl->color = colorspace;
45
+ pkl->channel = channel;
46
+ pkl->format = PKL_FORMAT_ERROR;
17
47
  pkl->compress = -1;
18
- pkl->x_scale=1.0;
19
- pkl->y_scale=1.0;
48
+
49
+ //for(i=0; i<pkl->channel; i++)
50
+ // back[i] = (backcolor>>((pkl->channel-i)*8) & 0xFF);
51
+ if(backcolor)
52
+ memcpy(back, backcolor->color, PKL_CHANNEL);
53
+ else
54
+ memset(back, 0xff, PKL_CHANNEL);
55
+
56
+ for(i=0; i<pkl->width*pkl->height*pkl->channel; i+=pkl->channel)
57
+ memcpy(&pkl->image[i], back, pkl->channel);
58
+ return(pkl);
59
+ }
60
+
61
+ //=============================================================================
62
+ // pkl_open
63
+ //=============================================================================
64
+ PKLExport PKLImage pkl_open(const char *in)
65
+ {
66
+ FILE *image;
67
+ PKLImage pkl;
20
68
 
21
69
  image = fopen(in, "rb");
22
70
  if(!image) return(NULL);
23
71
 
24
- format_type(pkl, image);
72
+ pkl = pkl_fdopen(image);
73
+
74
+ fclose(image);
75
+ return(pkl);
76
+ }
77
+
78
+ //=================================================================================
79
+ // pkl_fdopen
80
+ //=================================================================================
81
+ PKLExport PKLImage pkl_fdopen(FILE *in)
82
+ {
83
+ PKLImage pkl;
84
+ int result;
85
+
86
+ pkl = malloc( sizeof(struct _PKLImage) );
87
+ if(!pkl) return(NULL);
88
+ memset(pkl, 0, sizeof(struct _PKLImage));
89
+
90
+ pkl->compress = -1;
91
+
92
+ format_type(pkl, in);
25
93
 
26
94
  switch(pkl->format){
27
95
  case PKL_FORMAT_JPEG:
28
- result = load_jpeg(pkl, image);
96
+ result = load_jpeg(pkl, in);
29
97
  break;
30
98
  case PKL_FORMAT_PNG:
31
- result = load_png(pkl, image);
99
+ result = load_png(pkl, in);
32
100
  break;
33
101
  case PKL_FORMAT_BITMAP:
34
- result = load_bitmap(pkl, image);
102
+ result = load_bitmap(pkl, in);
35
103
  break;
36
104
  default:
37
105
  result = 1;
38
106
  }
39
- fclose(image);
40
107
 
41
108
  if(result){
42
109
  free(pkl);
43
- pkl = NULL;
110
+ pkl=NULL;
44
111
  }
45
-
46
112
  return(pkl);
47
113
  }
48
114
 
@@ -51,10 +117,42 @@ PKLExport PKLImage pkl_open(const char *in)
51
117
  //=============================================================================
52
118
  PKLExport void pkl_close(PKLImage pkl)
53
119
  {
120
+ if(!pkl) return;
54
121
  if(pkl->image) free(pkl->image);
55
122
  free(pkl);
56
123
  }
57
124
 
125
+ //=============================================================================
126
+ // pkl_dup
127
+ //=============================================================================
128
+ PKLExport PKLImage pkl_dup(PKLImage pkl)
129
+ {
130
+ PKLImage dst;
131
+
132
+ if(!pkl) return(NULL);
133
+
134
+ dst = malloc(sizeof(struct _PKLImage));
135
+ if(!dst) return(NULL);
136
+ memset(dst, 0, sizeof(struct _PKLImage));
137
+
138
+ dst->width = pkl->width;
139
+ dst->height = pkl->height;
140
+ dst->color = pkl->color;
141
+ dst->channel = pkl->channel;
142
+ dst->format = pkl->format;
143
+ dst->compress = pkl->compress;
144
+
145
+ if(pkl->image){
146
+ dst->image = malloc(pkl->width*pkl->height*pkl->channel);
147
+ if(!dst->image){
148
+ free(dst);
149
+ return(NULL);
150
+ }
151
+ memcpy(dst->image, pkl->image, pkl->width*pkl->height*pkl->channel);
152
+ }
153
+ return(dst);
154
+ }
155
+
58
156
  //=============================================================================
59
157
  // format_type
60
158
  //=============================================================================
@@ -100,6 +198,14 @@ PKLExport int pkl_height(PKLImage pkl)
100
198
  return(pkl->height);
101
199
  }
102
200
 
201
+ //=============================================================================
202
+ // pkl_colorspace
203
+ //=============================================================================
204
+ PKLExport PKL_COLOR_SPACE pkl_colorspace(PKLImage pkl)
205
+ {
206
+ return(pkl->color);
207
+ }
208
+
103
209
  //=============================================================================
104
210
  // pkl_compress
105
211
  //=============================================================================
@@ -116,24 +222,69 @@ PKLExport int pkl_compress(PKLImage pkl, int level)
116
222
  PKLExport int pkl_save(PKLImage pkl, const char *out, PKL_FORMAT format)
117
223
  {
118
224
  FILE *image;
119
- int result=0;
225
+ int result;
120
226
 
121
227
  image = fopen(out, "wb");
122
228
  if(!image) return(1);
123
229
 
230
+ result = pkl_output(pkl, image, format);
231
+
232
+ fclose(image);
233
+ return(result);
234
+ }
235
+
236
+ //=================================================================================
237
+ // pkl_output
238
+ //=================================================================================
239
+ PKLExport int pkl_output(PKLImage pkl, FILE *out, PKL_FORMAT format)
240
+ {
124
241
  switch(format){
125
242
  case PKL_FORMAT_JPEG:
126
- result = save_jpeg(pkl, image);
127
- break;
243
+ return save_jpeg(pkl, out);
128
244
  case PKL_FORMAT_PNG:
129
- result = save_png(pkl, image);
130
- break;
245
+ return save_png(pkl, out);
131
246
  case PKL_FORMAT_BITMAP:
132
- result = save_bitmap(pkl, image);
133
- break;
247
+ return save_bitmap(pkl, out);
134
248
  default:
135
- result=1;
249
+ return(1);
136
250
  }
137
- fclose(image);
138
- return(result);
251
+ return(1);
252
+ }
253
+
254
+ //=============================================================================
255
+ // pkl_count
256
+ //=============================================================================
257
+ PKLExport int pkl_count(PKLImage pkl)
258
+ {
259
+ unsigned char *colors;
260
+ int i, j, byte, bit, count=0, channel;
261
+ union {
262
+ int color;
263
+ unsigned char row[PKL_CHANNEL];
264
+ } pixel;
265
+
266
+ switch(pkl->channel){
267
+ case 1: channel=1; break;
268
+ case 3:
269
+ case 4: channel=3; break;
270
+ default: return(0);
271
+ }
272
+
273
+ colors = malloc(256 * 256 * 32);
274
+ memset(colors, 0, 256 * 256 * 32);
275
+
276
+ for(i=0; i<pkl->height; i++){
277
+ for(j=0; j<pkl->width; j++){
278
+ pixel.color=0;
279
+ memcpy(pixel.row, &pkl->image[(i*pkl->width+j)*pkl->channel], channel);
280
+ byte = pixel.color / 8;
281
+ bit = pixel.color % 8;
282
+
283
+ if((colors[byte]&(1<<bit))) continue;
284
+ colors[byte] = colors[byte]|(1<<bit);
285
+ count++;
286
+ }
287
+ }
288
+ free(colors);
289
+ return(count);
139
290
  }