pikl 0.2.2-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 +8 -0
- data/License.txt +21 -0
- data/Manifest.txt +37 -0
- data/README.txt +66 -0
- data/Rakefile +4 -0
- data/config/hoe.rb +89 -0
- data/config/requirements.rb +15 -0
- data/ext/pikl/pikl.h +264 -0
- data/ext/pikl/pikl_bitmap.c +152 -0
- data/ext/pikl/pikl_bitmap.h +18 -0
- data/ext/pikl/pikl_effect.c +191 -0
- data/ext/pikl/pikl_effect.h +20 -0
- data/ext/pikl/pikl_io.c +137 -0
- data/ext/pikl/pikl_io.h +27 -0
- data/ext/pikl/pikl_jpeg.c +161 -0
- data/ext/pikl/pikl_jpeg.h +22 -0
- data/ext/pikl/pikl_png.c +188 -0
- data/ext/pikl/pikl_png.h +17 -0
- data/ext/pikl/pikl_private.h +24 -0
- data/ext/pikl/pikl_resize.c +338 -0
- data/ext/pikl/pikl_resize.h +12 -0
- data/ext/pikl/pikl_rotate.c +70 -0
- data/ext/pikl/pikl_rotate.h +12 -0
- data/ext/pikl/pikl_trim.c +28 -0
- data/ext/pikl/pikl_trim.h +11 -0
- data/lib/pikl/const.rb +54 -0
- data/lib/pikl/errors.rb +7 -0
- data/lib/pikl/ext.rb +35 -0
- data/lib/pikl/image.rb +230 -0
- data/lib/pikl/pikl.dll +0 -0
- data/lib/pikl/version.rb +9 -0
- data/lib/pikl.rb +14 -0
- data/setup.rb +1585 -0
- data/test/sample.jpg +0 -0
- data/test/test_helper.rb +2 -0
- data/test/test_pikl_image.rb +268 -0
- metadata +95 -0
data/ext/pikl/pikl_png.c
ADDED
@@ -0,0 +1,188 @@
|
|
1
|
+
#include "pikl_png.h"
|
2
|
+
|
3
|
+
static int color_pn2pk(int color);
|
4
|
+
static int color_pk2pn(int color);
|
5
|
+
static int pkl_png_channels(int color);
|
6
|
+
static int pkl_png_depth(int color);
|
7
|
+
static int compress_pk2pn(int level);
|
8
|
+
|
9
|
+
//=============================================================================
|
10
|
+
// load_png
|
11
|
+
//=============================================================================
|
12
|
+
int load_png(PKLImage pkl, FILE *image)
|
13
|
+
{
|
14
|
+
png_structp png_ptr;
|
15
|
+
png_infop info_ptr;
|
16
|
+
int i;
|
17
|
+
|
18
|
+
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
19
|
+
if(!png_ptr) return(1);
|
20
|
+
|
21
|
+
info_ptr = png_create_info_struct(png_ptr);
|
22
|
+
if(!info_ptr){
|
23
|
+
png_destroy_read_struct(&png_ptr, NULL, NULL);
|
24
|
+
return(1);
|
25
|
+
}
|
26
|
+
|
27
|
+
if( setjmp(png_jmpbuf(png_ptr)) ){
|
28
|
+
png_destroy_info_struct(png_ptr, &info_ptr);
|
29
|
+
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
|
30
|
+
return(1);
|
31
|
+
}
|
32
|
+
|
33
|
+
png_init_io(png_ptr, image);
|
34
|
+
png_read_info(png_ptr, info_ptr);
|
35
|
+
pkl->width = info_ptr->width;
|
36
|
+
pkl->height = info_ptr->height;
|
37
|
+
pkl->color = color_pn2pk(info_ptr->color_type);
|
38
|
+
pkl->channel = pkl_png_channels(pkl->color);
|
39
|
+
if(pkl->color == PKL_UNKNOWN) return(1);
|
40
|
+
|
41
|
+
pkl->image = malloc(pkl->width * pkl->height * pkl->channel);
|
42
|
+
if(!pkl->image) return(1);
|
43
|
+
|
44
|
+
if(info_ptr->color_type==PNG_COLOR_TYPE_RGB_ALPHA ||
|
45
|
+
info_ptr->color_type==PNG_COLOR_TYPE_GRAY_ALPHA || info_ptr->num_trans) png_set_strip_alpha(png_ptr);
|
46
|
+
if(info_ptr->bit_depth<8 &&
|
47
|
+
info_ptr->color_type==PNG_COLOR_TYPE_GRAY) png_set_gray_1_2_4_to_8(png_ptr);
|
48
|
+
if(info_ptr->bit_depth==16) png_set_strip_16(png_ptr);
|
49
|
+
if(info_ptr->color_type==PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr);
|
50
|
+
|
51
|
+
for(i=0; i<pkl->height; i++)
|
52
|
+
png_read_row(png_ptr, &pkl->image[i*pkl->width*pkl->channel], NULL);
|
53
|
+
|
54
|
+
png_destroy_info_struct(png_ptr, &info_ptr);
|
55
|
+
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
|
56
|
+
|
57
|
+
return(0);
|
58
|
+
}
|
59
|
+
|
60
|
+
//===================================================================
|
61
|
+
// save_png
|
62
|
+
//===================================================================
|
63
|
+
int save_png(PKLImage pkl, FILE *image)
|
64
|
+
{
|
65
|
+
png_structp png_ptr;
|
66
|
+
png_infop info_ptr;
|
67
|
+
int i;
|
68
|
+
|
69
|
+
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
70
|
+
if(!png_ptr) return(1);
|
71
|
+
|
72
|
+
info_ptr = png_create_info_struct(png_ptr);
|
73
|
+
if(!info_ptr){
|
74
|
+
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
|
75
|
+
return(1);
|
76
|
+
}
|
77
|
+
|
78
|
+
if( setjmp(png_jmpbuf(png_ptr)) ){
|
79
|
+
png_destroy_info_struct(png_ptr, &info_ptr);
|
80
|
+
png_destroy_write_struct(&png_ptr, &info_ptr);
|
81
|
+
return(1);
|
82
|
+
}
|
83
|
+
|
84
|
+
png_init_io(png_ptr, image);
|
85
|
+
info_ptr->width = pkl->width;
|
86
|
+
info_ptr->height = pkl->height;
|
87
|
+
info_ptr->bit_depth = pkl_png_depth(pkl->color);
|
88
|
+
info_ptr->color_type = color_pk2pn(pkl->color);
|
89
|
+
png_set_compression_level(png_ptr, compress_pk2pn(pkl->compress));
|
90
|
+
png_write_info(png_ptr, info_ptr);
|
91
|
+
|
92
|
+
for(i=0; i<pkl->height; i++)
|
93
|
+
png_write_row(png_ptr, &pkl->image[i*pkl->width*pkl->channel]);
|
94
|
+
png_write_end(png_ptr, info_ptr);
|
95
|
+
png_destroy_info_struct(png_ptr, &info_ptr);
|
96
|
+
png_destroy_write_struct(&png_ptr, &info_ptr);
|
97
|
+
|
98
|
+
return(0);
|
99
|
+
}
|
100
|
+
|
101
|
+
//=============================================================================
|
102
|
+
// color_pn2pk
|
103
|
+
//=============================================================================
|
104
|
+
static int color_pn2pk(int color)
|
105
|
+
{
|
106
|
+
switch(color){
|
107
|
+
case PNG_COLOR_TYPE_GRAY:
|
108
|
+
case PNG_COLOR_TYPE_GRAY_ALPHA:
|
109
|
+
return(PKL_GRAYSCALE);
|
110
|
+
case PNG_COLOR_TYPE_PALETTE:
|
111
|
+
case PNG_COLOR_TYPE_RGB:
|
112
|
+
case PNG_COLOR_TYPE_RGB_ALPHA:
|
113
|
+
return(PKL_RGB);
|
114
|
+
default:
|
115
|
+
return(PKL_UNKNOWN);
|
116
|
+
}
|
117
|
+
return(PKL_UNKNOWN);
|
118
|
+
}
|
119
|
+
|
120
|
+
//=============================================================================
|
121
|
+
// pkl_png_channels
|
122
|
+
//=============================================================================
|
123
|
+
static int pkl_png_channels(int color)
|
124
|
+
{
|
125
|
+
switch(color){
|
126
|
+
//case PKL_BLACKWHITE:
|
127
|
+
// return ;
|
128
|
+
case PKL_GRAYSCALE:
|
129
|
+
return 1;
|
130
|
+
case PKL_RGB:
|
131
|
+
return 3;
|
132
|
+
//case PKL_RGBA:
|
133
|
+
//case PKL_CMYK:
|
134
|
+
// return 4;
|
135
|
+
default:
|
136
|
+
return 0;
|
137
|
+
}
|
138
|
+
return 0;
|
139
|
+
}
|
140
|
+
|
141
|
+
//=============================================================================
|
142
|
+
// pkl_png_depth
|
143
|
+
//=============================================================================
|
144
|
+
static int pkl_png_depth(int color)
|
145
|
+
{
|
146
|
+
switch(color){
|
147
|
+
//case PKL_BLACKWHITE:
|
148
|
+
// return 1;
|
149
|
+
case PKL_GRAYSCALE:
|
150
|
+
case PKL_RGB:
|
151
|
+
//case PKL_CMYK:
|
152
|
+
//case PKL_RGBA:
|
153
|
+
return 8;
|
154
|
+
default:
|
155
|
+
return 0;
|
156
|
+
}
|
157
|
+
return 0;
|
158
|
+
}
|
159
|
+
|
160
|
+
//=============================================================================
|
161
|
+
// color_pk2pn
|
162
|
+
//=============================================================================
|
163
|
+
static int color_pk2pn(int color)
|
164
|
+
{
|
165
|
+
switch(color){
|
166
|
+
//case PKL_BLACKWHITE:
|
167
|
+
// return PNG_COLOR_TYPE_GRAY;
|
168
|
+
case PKL_GRAYSCALE:
|
169
|
+
return PNG_COLOR_TYPE_GRAY;
|
170
|
+
case PKL_RGB:
|
171
|
+
return PNG_COLOR_TYPE_RGB;
|
172
|
+
//case PKL_CMYK:
|
173
|
+
//case PKL_RGBA:
|
174
|
+
default:
|
175
|
+
return -1;
|
176
|
+
}
|
177
|
+
return -1;
|
178
|
+
}
|
179
|
+
|
180
|
+
//=============================================================================
|
181
|
+
// compress_pk2pn
|
182
|
+
//=============================================================================
|
183
|
+
static int compress_pk2pn(int level)
|
184
|
+
{
|
185
|
+
if(level < 0) return(Z_BEST_COMPRESSION);
|
186
|
+
if(level > 9) return(9);
|
187
|
+
return(level);
|
188
|
+
}
|
data/ext/pikl/pikl_png.h
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#ifndef _LIB_PIKL_PNG_
|
2
|
+
#define _LIB_PIKL_PNG_
|
3
|
+
|
4
|
+
#include <stdio.h>
|
5
|
+
#include <stdlib.h>
|
6
|
+
#include <string.h>
|
7
|
+
#include <setjmp.h>
|
8
|
+
#include <png.h>
|
9
|
+
|
10
|
+
#include "pikl.h"
|
11
|
+
#include "pikl_private.h"
|
12
|
+
|
13
|
+
int load_png(PKLImage pkl, FILE *image);
|
14
|
+
int save_png(PKLImage pkl, FILE *image);
|
15
|
+
|
16
|
+
#endif
|
17
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
#ifndef _LIB_PIKL_PRIVATE_
|
2
|
+
#define _LIB_PIKL_PRIVATE_
|
3
|
+
|
4
|
+
#define PKL_MINMAX(a,b,i) (((a>=i)?a:((b<=i)?b:i)))
|
5
|
+
#define PKL_RGB(v) v<0?0:v>255?255:v
|
6
|
+
#define PKL_CHANNEL 4
|
7
|
+
#define PKL_COLOR 256
|
8
|
+
#ifndef M_PI
|
9
|
+
#define M_PI 3.14159265358979323846
|
10
|
+
#endif
|
11
|
+
//=============================================================================
|
12
|
+
// PKLImage
|
13
|
+
//=============================================================================
|
14
|
+
struct _PKLImage {
|
15
|
+
int width;
|
16
|
+
int height;
|
17
|
+
PKL_COLOR_SPACE color;
|
18
|
+
int channel;
|
19
|
+
unsigned char *image;
|
20
|
+
PKL_FORMAT format;
|
21
|
+
int compress;
|
22
|
+
};
|
23
|
+
|
24
|
+
#endif
|
@@ -0,0 +1,338 @@
|
|
1
|
+
#include "pikl_resize.h"
|
2
|
+
|
3
|
+
static int resize_pa(PKLImage pkl, int width, int height);
|
4
|
+
static int resize_nn(PKLImage pkl, int width, int height);
|
5
|
+
static int resize_lz(PKLImage pkl, int width, int height);
|
6
|
+
static int resize_bc(PKLImage pkl, int width, int height);
|
7
|
+
static int resize_bl(PKLImage pkl, int width, int height);
|
8
|
+
static int resize_lz_cr(PKLImage pkl, double scale, int ax);
|
9
|
+
static double lz_weight(double x);
|
10
|
+
static int get_pixel(PKLImage pkl, int x, int y, unsigned char *pix);
|
11
|
+
|
12
|
+
//=================================================================================
|
13
|
+
// pkl_resize
|
14
|
+
//=================================================================================
|
15
|
+
PKLExport int pkl_resize(PKLImage pkl, int width, int height, PKL_SAMPLE sample)
|
16
|
+
{
|
17
|
+
// color mode check
|
18
|
+
|
19
|
+
if(width < 1 || height < 1) return(1);
|
20
|
+
if(width==pkl->width && height==pkl->height) return(0);
|
21
|
+
|
22
|
+
switch(sample){
|
23
|
+
case PKL_SAMPLE_NN:
|
24
|
+
return resize_nn(pkl, width, height);
|
25
|
+
case PKL_SAMPLE_BL:
|
26
|
+
return resize_bl(pkl, width, height);
|
27
|
+
case PKL_SAMPLE_BC:
|
28
|
+
return resize_bc(pkl, width, height);
|
29
|
+
case PKL_SAMPLE_PA:
|
30
|
+
if(width<pkl->width && height<pkl->height) return resize_pa(pkl, width, height);
|
31
|
+
case PKL_SAMPLE_LZ:
|
32
|
+
return resize_lz(pkl, width, height);
|
33
|
+
default:
|
34
|
+
return(1);
|
35
|
+
}
|
36
|
+
return(1);
|
37
|
+
}
|
38
|
+
|
39
|
+
//=============================================================================
|
40
|
+
// resize_nn
|
41
|
+
//=============================================================================
|
42
|
+
static int resize_nn(PKLImage pkl, int width, int height)
|
43
|
+
{
|
44
|
+
unsigned char *wrk;
|
45
|
+
double zx, zy;
|
46
|
+
int i, j, px, py;
|
47
|
+
|
48
|
+
wrk = malloc(width*height*pkl->channel);
|
49
|
+
if(!wrk) return(1);
|
50
|
+
memset(wrk, 0, width*height*pkl->channel);
|
51
|
+
|
52
|
+
zx = (double)width /pkl->width;
|
53
|
+
zy = (double)height/pkl->height;
|
54
|
+
|
55
|
+
for(i=0; i<height; i++){
|
56
|
+
for(j=0; j<width; j++){
|
57
|
+
px = (int)((double)j)/zx;
|
58
|
+
py = (int)((double)i)/zy;
|
59
|
+
if(px>=0 && px<pkl->width && py>=0 && py<pkl->height){
|
60
|
+
memcpy(&wrk[(i*width+j)*pkl->channel], &pkl->image[(py*pkl->width+px)*pkl->channel], pkl->channel);
|
61
|
+
}
|
62
|
+
}
|
63
|
+
}
|
64
|
+
free(pkl->image);
|
65
|
+
pkl->image = wrk;
|
66
|
+
pkl->width = width;
|
67
|
+
pkl->height = height;
|
68
|
+
return(0);
|
69
|
+
}
|
70
|
+
|
71
|
+
//=============================================================================
|
72
|
+
// resize_bl
|
73
|
+
//=============================================================================
|
74
|
+
static int resize_bl(PKLImage pkl, int width, int height)
|
75
|
+
{
|
76
|
+
unsigned char *wrk;
|
77
|
+
double zx, zy, dx, dy, px, py, f[4];
|
78
|
+
int i, j, k, wx, wy, sx, sy;
|
79
|
+
|
80
|
+
wrk = malloc(width*height*pkl->channel);
|
81
|
+
if(!wrk) return(1);
|
82
|
+
memset(wrk, 0, width*height*pkl->channel);
|
83
|
+
|
84
|
+
zx = (double)pkl->width / (double)width;
|
85
|
+
zy = (double)pkl->height/ (double)height;
|
86
|
+
|
87
|
+
for(i=0; i<height; i++){
|
88
|
+
for(j=0; j<width; j++){
|
89
|
+
dx = modf(zx*j, &px);
|
90
|
+
dy = modf(zy*i, &py);
|
91
|
+
f[0] = (1.0-dx)*(1.0-dy);
|
92
|
+
f[1] = dx*(1.0-dy);
|
93
|
+
f[2] = (1.0-dx)*dy;
|
94
|
+
f[3] = dx*dy;
|
95
|
+
|
96
|
+
for(wy=0; wy<2; wy++){
|
97
|
+
for(wx=0; wx<2; wx++){
|
98
|
+
sx = ((int)px+wx<0) ? pkl->width +((int)px+wx)%pkl->width -1 : ((int)px+wx)%pkl->width;
|
99
|
+
sy = ((int)py+wy<0) ? pkl->height+((int)py+wy)%pkl->height-1 : ((int)py+wy)%pkl->height;
|
100
|
+
for(k=0; k<pkl->channel; k++){
|
101
|
+
wrk[(i*width+j)*pkl->channel+k] =
|
102
|
+
PKL_RGB(wrk[(i*width+j)*pkl->channel+k] + pkl->image[(sy*pkl->width+sx)*pkl->channel+k] * f[wy*2+wx]);
|
103
|
+
}
|
104
|
+
}
|
105
|
+
}
|
106
|
+
}
|
107
|
+
}
|
108
|
+
|
109
|
+
free(pkl->image);
|
110
|
+
pkl->image = wrk;
|
111
|
+
pkl->width = width;
|
112
|
+
pkl->height = height;
|
113
|
+
return(0);
|
114
|
+
}
|
115
|
+
|
116
|
+
//=============================================================================
|
117
|
+
// resize_bc
|
118
|
+
//=============================================================================
|
119
|
+
static int resize_bc(PKLImage pkl, int width, int height)
|
120
|
+
{
|
121
|
+
int i, j, k, px, py, x0, y0;
|
122
|
+
double wx, wy, dx, dy, zx, zy, sx, sy;
|
123
|
+
double data[PKL_CHANNEL];
|
124
|
+
unsigned char *wrk;
|
125
|
+
|
126
|
+
wrk = malloc(width*height*pkl->channel);
|
127
|
+
if(!wrk) return(1);
|
128
|
+
memset(wrk, 0, width*height*pkl->channel);
|
129
|
+
|
130
|
+
zx = (double)pkl->width / (double)width;
|
131
|
+
zy = (double)pkl->height/ (double)height;
|
132
|
+
|
133
|
+
for(i=0; i<height; i++){
|
134
|
+
for(j=0; j<width; j++){
|
135
|
+
memset(&data, 0, sizeof(data));
|
136
|
+
sx = zx * j;
|
137
|
+
sy = zy * i;
|
138
|
+
for(py=(int)sy-1; py<=(int)sy+2; py++){
|
139
|
+
for(px=(int)sx-1; px<=(int)sx+2; px++){
|
140
|
+
dx = fabs(sx-px);
|
141
|
+
dy = fabs(sy-py);
|
142
|
+
wx = (dx<1) ? (dx-1)*(dx*dx-dx-1) : -(dx-1)*(dx-2)*(dx-2);
|
143
|
+
wy = (dy<1) ? (dy-1)*(dy*dy-dy-1) : -(dy-1)*(dy-2)*(dy-2);
|
144
|
+
x0 = (px<0 || px>pkl->width -1) ? sx : px;
|
145
|
+
y0 = (py<0 || py>pkl->height-1) ? sy : py;
|
146
|
+
for(k=0; k<pkl->channel; k++) data[k]+=pkl->image[(y0*pkl->width+x0)*pkl->channel+k]*wx*wy;
|
147
|
+
}
|
148
|
+
}
|
149
|
+
for(k=0; k<pkl->channel; k++) wrk[(i*width+j)*pkl->channel+k]=PKL_RGB(data[k]);
|
150
|
+
}
|
151
|
+
}
|
152
|
+
free(pkl->image);
|
153
|
+
pkl->image = wrk;
|
154
|
+
pkl->width = width;
|
155
|
+
pkl->height = height;
|
156
|
+
return(0);
|
157
|
+
}
|
158
|
+
|
159
|
+
//=============================================================================
|
160
|
+
// resize_pa
|
161
|
+
//=============================================================================
|
162
|
+
static int resize_pa(PKLImage pkl, int width, int height)
|
163
|
+
{
|
164
|
+
unsigned char *wrk;
|
165
|
+
int i, j;
|
166
|
+
double zx, zy;
|
167
|
+
|
168
|
+
wrk = malloc(width * height * pkl->channel);
|
169
|
+
if(!wrk) return(1);
|
170
|
+
memset(wrk, 0, width*height*pkl->channel);
|
171
|
+
|
172
|
+
zx = (double)pkl->width / (double)width;
|
173
|
+
zy = (double)pkl->height / (double)height;
|
174
|
+
|
175
|
+
for(i=0; i<height; i++){
|
176
|
+
for(j=0; j<width; j++){
|
177
|
+
double w1, w2, h1, h2;
|
178
|
+
double w1b, w2b, h1b, h2b;
|
179
|
+
double bi, ixg[PKL_CHANNEL] = {0.0, 0.0, 0.0, 0.0};
|
180
|
+
int fsx ,fsy, s, t, k;
|
181
|
+
|
182
|
+
w1b = modf(zx * j, &w1);
|
183
|
+
w2b = modf(zx * (j+1), &w2);
|
184
|
+
h1b = modf(zy * i, &h1);
|
185
|
+
h2b = modf(zy * (i+1), &h2);
|
186
|
+
|
187
|
+
for(s=(int)w1; s<=(int)w2; s++){
|
188
|
+
for(t=(int)h1; t<=(int)h2; t++){
|
189
|
+
bi = 1.0;
|
190
|
+
if(s == (int)w1) bi*=(1-w1b);
|
191
|
+
if(s == (int)w2) bi*=(w2b);
|
192
|
+
if(t == (int)h1) bi*=(1-h1b);
|
193
|
+
if(t == (int)h2) bi*=(h2b);
|
194
|
+
fsx = (s < 0) ? 0 : (s > pkl->width -1) ? pkl->width -1 : s;
|
195
|
+
fsy = (t < 0) ? 0 : (t > pkl->height-1) ? pkl->height-1 : t;
|
196
|
+
for(k=0; k<pkl->channel; k++)
|
197
|
+
ixg[k] += pkl->image[(fsy*pkl->width+fsx)*pkl->channel+k] * bi;
|
198
|
+
}
|
199
|
+
}
|
200
|
+
for(k=0; k<pkl->channel; k++)
|
201
|
+
wrk[(i*width+j)*pkl->channel+k] = PKL_RGB(ixg[k]/(zx*zy));
|
202
|
+
}
|
203
|
+
}
|
204
|
+
free(pkl->image);
|
205
|
+
pkl->image = wrk;
|
206
|
+
pkl->width = width;
|
207
|
+
pkl->height = height;
|
208
|
+
return(0);
|
209
|
+
}
|
210
|
+
|
211
|
+
//=============================================================================
|
212
|
+
// resize_lz
|
213
|
+
//=============================================================================
|
214
|
+
static int resize_lz(PKLImage pkl, int width, int height)
|
215
|
+
{
|
216
|
+
double scale;
|
217
|
+
|
218
|
+
scale = (double)width / (double)pkl->width;
|
219
|
+
if( resize_lz_cr(pkl, scale, 1) ) return(1);
|
220
|
+
|
221
|
+
scale = (double)height / (double)pkl->height;
|
222
|
+
if( resize_lz_cr(pkl, scale, 0) ) return(1);
|
223
|
+
|
224
|
+
return(0);
|
225
|
+
}
|
226
|
+
|
227
|
+
//=============================================================================
|
228
|
+
// resize_lz_cr
|
229
|
+
//=============================================================================
|
230
|
+
static int resize_lz_cr(PKLImage pkl, double scale, int ax)
|
231
|
+
{
|
232
|
+
int hsize, vsize, i, j, k, l, lMax, zx, zy, factor;
|
233
|
+
double *w0, *w1, T, t, F, data[PKL_CHANNEL];
|
234
|
+
unsigned char *wrk, v[PKL_CHANNEL], v1[PKL_CHANNEL], v2[PKL_CHANNEL];
|
235
|
+
int mx, Mx;
|
236
|
+
|
237
|
+
if(ax){
|
238
|
+
zy = hsize = (int)(0.5 + pkl->width * scale);
|
239
|
+
zx = vsize = pkl->height;
|
240
|
+
}else{
|
241
|
+
zx = hsize = pkl->width;
|
242
|
+
zy = vsize = (int)(0.5 + pkl->height * scale);
|
243
|
+
}
|
244
|
+
|
245
|
+
wrk = malloc(hsize*vsize*pkl->channel);
|
246
|
+
if(!wrk) return(1);
|
247
|
+
memset(wrk, 0, hsize*vsize*pkl->channel);
|
248
|
+
|
249
|
+
factor = (scale>=1) ? 1 : (int)(1.4/scale);
|
250
|
+
lMax = factor << 1;
|
251
|
+
w0 = malloc(lMax * sizeof(double));
|
252
|
+
w1 = malloc(lMax * sizeof(double));
|
253
|
+
|
254
|
+
for(j=0; j<zy; j++){
|
255
|
+
F = modf((double)j/scale, &T);
|
256
|
+
for(l=0; l<lMax; l++){
|
257
|
+
w0[lMax-l-1] = lz_weight( ((lMax-l-1) + F)/factor );
|
258
|
+
w1[l] = lz_weight( ((l+1) - F)/factor );
|
259
|
+
}
|
260
|
+
t = 0.0;
|
261
|
+
for(l=0; l<lMax; l++){
|
262
|
+
t+=w0[l];
|
263
|
+
t+=w1[l];
|
264
|
+
}
|
265
|
+
t /= (double)factor;
|
266
|
+
for(l=0; l<lMax; l++){
|
267
|
+
w0[l] /= t;
|
268
|
+
w1[l] /= t;
|
269
|
+
}
|
270
|
+
|
271
|
+
if(ax){
|
272
|
+
for(i=0; i<zx; i++){
|
273
|
+
memset(data, 0, sizeof(data));
|
274
|
+
for(l=0; l<lMax; l++){
|
275
|
+
mx = (T-lMax+l+1 < 0) ? 0 : T-lMax+l+1;
|
276
|
+
Mx = (T+l+1 >= pkl->width) ? pkl->width-1 : T+l+1;
|
277
|
+
get_pixel(pkl, Mx, i, v1);
|
278
|
+
get_pixel(pkl, mx, i, v2);
|
279
|
+
for(k=0; k<pkl->channel; k++) data[k]+=(w1[l]*v1[k]+w0[lMax-l-1]*v2[k]);
|
280
|
+
}
|
281
|
+
for(k=0; k<pkl->channel; k++) v[k]=PKL_MINMAX(0, 255, 0.5+(data[k]/factor));
|
282
|
+
if(i>=0 && i<vsize && j>=0 && j<hsize) memcpy(&wrk[(i*hsize+j)*pkl->channel], &v, pkl->channel);
|
283
|
+
}
|
284
|
+
}else{
|
285
|
+
for(i=0; i<zx; i++){
|
286
|
+
memset(data, 0, sizeof(data));
|
287
|
+
for(l=0; l<lMax; l++){
|
288
|
+
mx = (T-lMax+l+1 < 0) ? 0 : T-lMax+l+1;
|
289
|
+
Mx = (T+l+1 >= pkl->height) ? pkl->height-1 : T+l+1;
|
290
|
+
get_pixel(pkl, i, Mx, v1);
|
291
|
+
get_pixel(pkl, i, mx, v2);
|
292
|
+
for(k=0; k<pkl->channel; k++) data[k]+=(w1[l]*v1[k]+w0[lMax-l-1]*v2[k]);
|
293
|
+
}
|
294
|
+
for(k=0; k<pkl->channel; k++) v[k]=PKL_MINMAX(0, 255, 0.5+(data[k]/factor));
|
295
|
+
if(j>=0 && j<vsize && i>=0 && i<hsize) memcpy(&wrk[(j*hsize+i)*pkl->channel], &v, pkl->channel);
|
296
|
+
}
|
297
|
+
}
|
298
|
+
}
|
299
|
+
free(w0);
|
300
|
+
free(w1);
|
301
|
+
free(pkl->image);
|
302
|
+
pkl->image = wrk;
|
303
|
+
pkl->width = hsize;
|
304
|
+
pkl->height = vsize;
|
305
|
+
return(0);
|
306
|
+
}
|
307
|
+
|
308
|
+
//=============================================================================
|
309
|
+
// get_pixel
|
310
|
+
//=============================================================================
|
311
|
+
static int get_pixel(PKLImage pkl, int x, int y, unsigned char *pix)
|
312
|
+
{
|
313
|
+
if(x<0 || x>=pkl->width || y<0 || y>=pkl->height) return(1);
|
314
|
+
memset(pix, 0, pkl->channel);
|
315
|
+
memcpy(pix, &pkl->image[(y*pkl->width+x)*pkl->channel], pkl->channel);
|
316
|
+
return(0);
|
317
|
+
}
|
318
|
+
|
319
|
+
//=============================================================================
|
320
|
+
// lz_weight
|
321
|
+
//=============================================================================
|
322
|
+
static double lz_weight(double x)
|
323
|
+
{
|
324
|
+
double PIx, PIx2;
|
325
|
+
|
326
|
+
PIx = M_PI * x;
|
327
|
+
PIx2 = PIx / 2.0;
|
328
|
+
|
329
|
+
if(x>=2.0 || x<=-2.0){
|
330
|
+
return (0.0);
|
331
|
+
}else
|
332
|
+
if(x == 0.0){
|
333
|
+
return (1.0);
|
334
|
+
}else{
|
335
|
+
return(sin(PIx) / PIx * sin(PIx2) / PIx2);
|
336
|
+
}
|
337
|
+
}
|
338
|
+
|
@@ -0,0 +1,70 @@
|
|
1
|
+
#include "pikl_rotate.h"
|
2
|
+
|
3
|
+
//=================================================================================
|
4
|
+
// pkl_rotate
|
5
|
+
//=================================================================================
|
6
|
+
PKLExport int pkl_rotate(PKLImage pkl, PKL_ANGLE angle)
|
7
|
+
{
|
8
|
+
unsigned char *wrk;
|
9
|
+
int rsin, rcos;
|
10
|
+
int width, height;
|
11
|
+
int sx, sy, ex, ey;
|
12
|
+
int i, j, x, y;
|
13
|
+
|
14
|
+
switch(angle){
|
15
|
+
case PKL_ANGLE_000:
|
16
|
+
return(0);
|
17
|
+
case PKL_ANGLE_090:
|
18
|
+
rcos = 0;
|
19
|
+
rsin = 1;
|
20
|
+
width = pkl->height;
|
21
|
+
height = pkl->width;
|
22
|
+
sx = 0;
|
23
|
+
sy = -(pkl->width-1);
|
24
|
+
ex = pkl->height-1;
|
25
|
+
ey = 0;
|
26
|
+
break;
|
27
|
+
case PKL_ANGLE_180:
|
28
|
+
rcos = -1;
|
29
|
+
rsin = 0;
|
30
|
+
width = pkl->width;
|
31
|
+
height = pkl->height;
|
32
|
+
sx = -(pkl->width-1);
|
33
|
+
sy = -(pkl->height-1);
|
34
|
+
ex = 0;
|
35
|
+
ey = 0;
|
36
|
+
break;
|
37
|
+
case PKL_ANGLE_270:
|
38
|
+
rcos = 0;
|
39
|
+
rsin = -1;
|
40
|
+
width = pkl->height;
|
41
|
+
height = pkl->width;
|
42
|
+
sx = -(pkl->height-1);
|
43
|
+
sy = 0;
|
44
|
+
ex = 0;
|
45
|
+
ey = pkl->width-1;
|
46
|
+
break;
|
47
|
+
default:
|
48
|
+
return(1);
|
49
|
+
}
|
50
|
+
|
51
|
+
wrk = malloc(width * height * pkl->channel);
|
52
|
+
if(!wrk) return(1);
|
53
|
+
|
54
|
+
for(i=sy; i<=ey; i++){
|
55
|
+
for(j=sx; j<=ex; j++){
|
56
|
+
x = rcos * j - rsin * i;
|
57
|
+
y = rsin * j + rcos * i;
|
58
|
+
memcpy(&wrk[((i-sy)*width+j-sx)*pkl->channel], &pkl->image[(y*pkl->width+x)*pkl->channel], pkl->channel);
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
free(pkl->image);
|
63
|
+
pkl->image = wrk;
|
64
|
+
pkl->width = width;
|
65
|
+
pkl->height = height;
|
66
|
+
|
67
|
+
return(0);
|
68
|
+
}
|
69
|
+
|
70
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#include "pikl_trim.h"
|
2
|
+
|
3
|
+
//=================================================================================
|
4
|
+
// pkl_trim
|
5
|
+
//=================================================================================
|
6
|
+
PKLExport int pkl_trim(PKLImage pkl, int sx, int sy, int width, int height)
|
7
|
+
{
|
8
|
+
unsigned char *wrk;
|
9
|
+
int p, y;
|
10
|
+
|
11
|
+
if( sx < 0 || sy < 0 || width <= 0 || height <= 0 ) return(1);
|
12
|
+
if( sx+width > pkl->width ) return(1);
|
13
|
+
if( sy+height > pkl->height ) return(1);
|
14
|
+
|
15
|
+
wrk = malloc(height * width * pkl->channel);
|
16
|
+
if(!wrk) return(1);
|
17
|
+
|
18
|
+
for(p=0,y=sy; y<sy+height; p++,y++){
|
19
|
+
memcpy(&wrk[p*width*pkl->channel], &pkl->image[(y*pkl->width+sx)*pkl->channel], width*pkl->channel);
|
20
|
+
}
|
21
|
+
|
22
|
+
free(pkl->image);
|
23
|
+
pkl->image = wrk;
|
24
|
+
pkl->height = height;
|
25
|
+
pkl->width = width;
|
26
|
+
|
27
|
+
return(0);
|
28
|
+
}
|