pikl 0.2.8 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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/extconf.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/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.h
CHANGED
@@ -9,12 +9,38 @@
|
|
9
9
|
#include "pikl.h"
|
10
10
|
#include "pikl_private.h"
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
struct PKL_FILTER {
|
13
|
+
int type;
|
14
|
+
int matrix[9];
|
15
|
+
};
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
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
|
data/ext/pikl/pikl_io.c
CHANGED
@@ -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
|
-
//
|
6
|
+
// pkl_canvas
|
6
7
|
//=============================================================================
|
7
|
-
PKLExport PKLImage
|
8
|
+
PKLExport PKLImage pkl_canvas(int width, int height, PKL_COLOR_SPACE color, PKLColor backcolor)
|
8
9
|
{
|
9
10
|
PKLImage pkl;
|
10
|
-
|
11
|
-
int
|
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
|
-
|
19
|
-
|
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
|
-
|
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,
|
96
|
+
result = load_jpeg(pkl, in);
|
29
97
|
break;
|
30
98
|
case PKL_FORMAT_PNG:
|
31
|
-
result = load_png(pkl,
|
99
|
+
result = load_png(pkl, in);
|
32
100
|
break;
|
33
101
|
case PKL_FORMAT_BITMAP:
|
34
|
-
result = load_bitmap(pkl,
|
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
|
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
|
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
|
-
|
127
|
-
break;
|
243
|
+
return save_jpeg(pkl, out);
|
128
244
|
case PKL_FORMAT_PNG:
|
129
|
-
|
130
|
-
break;
|
245
|
+
return save_png(pkl, out);
|
131
246
|
case PKL_FORMAT_BITMAP:
|
132
|
-
|
133
|
-
break;
|
247
|
+
return save_bitmap(pkl, out);
|
134
248
|
default:
|
135
|
-
|
249
|
+
return(1);
|
136
250
|
}
|
137
|
-
|
138
|
-
|
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
|
}
|