pikl 0.1.0
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 +4 -0
- data/License.txt +21 -0
- data/Manifest.txt +37 -0
- data/README.txt +52 -0
- data/Rakefile +4 -0
- data/config/hoe.rb +72 -0
- data/config/requirements.rb +15 -0
- data/ext/pikl/extconf.rb +16 -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 +24 -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 +22 -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.rb +14 -0
- data/lib/pikl/const.rb +49 -0
- data/lib/pikl/errors.rb +7 -0
- data/lib/pikl/ext.rb +32 -0
- data/lib/pikl/image.rb +219 -0
- data/lib/pikl/version.rb +9 -0
- data/setup.rb +1585 -0
- data/test/sample.jpg +0 -0
- data/test/test_helper.rb +2 -0
- data/test/test_pikl.rb +13 -0
- data/test/test_pikl_image.rb +262 -0
- metadata +90 -0
data/ext/pikl/pikl_io.h
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#ifndef _LIB_PIKL_IO_
|
2
|
+
#define _LIB_PIKL_IO_
|
3
|
+
|
4
|
+
#include <stdio.h>
|
5
|
+
#include <stdlib.h>
|
6
|
+
#include <string.h>
|
7
|
+
|
8
|
+
#include "pikl.h"
|
9
|
+
#include "pikl_private.h"
|
10
|
+
#include "pikl_jpeg.h"
|
11
|
+
#include "pikl_bitmap.h"
|
12
|
+
#include "pikl_png.h"
|
13
|
+
|
14
|
+
#define PKL_HEADER_SIZE 8
|
15
|
+
struct PKL_HEADER {
|
16
|
+
PKL_FORMAT format;
|
17
|
+
int size;
|
18
|
+
unsigned char mark[PKL_HEADER_SIZE];
|
19
|
+
};
|
20
|
+
|
21
|
+
static struct PKL_HEADER pklheader[] = {
|
22
|
+
{ PKL_FORMAT_JPEG, 2, {0xFF, 0xD8} },
|
23
|
+
{ PKL_FORMAT_PNG, 8, {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A} },
|
24
|
+
{ PKL_FORMAT_BITMAP, 2, {0x42, 0x4D} },
|
25
|
+
};
|
26
|
+
|
27
|
+
#endif
|
@@ -0,0 +1,161 @@
|
|
1
|
+
#include "pikl_jpeg.h"
|
2
|
+
|
3
|
+
static void pkljpeg_error_exit(j_common_ptr cinfo);
|
4
|
+
static int color_p2j(int color);
|
5
|
+
static int color_j2p(int color);
|
6
|
+
static int compress_p2j(int level);
|
7
|
+
|
8
|
+
//=============================================================================
|
9
|
+
// pkljpeg_error_exit
|
10
|
+
//=============================================================================
|
11
|
+
static void pkljpeg_error_exit(j_common_ptr cinfo)
|
12
|
+
{
|
13
|
+
struct err_mgr *jp_err = (struct err_mgr *)cinfo->err;
|
14
|
+
longjmp(jp_err->setjmp_buffer, 1);
|
15
|
+
}
|
16
|
+
|
17
|
+
//=============================================================================
|
18
|
+
// load_jpeg
|
19
|
+
//=============================================================================
|
20
|
+
int load_jpeg(PKLImage pkl, FILE *image)
|
21
|
+
{
|
22
|
+
struct jpeg_decompress_struct cinfo;
|
23
|
+
struct err_mgr jerr;
|
24
|
+
unsigned char *p;
|
25
|
+
|
26
|
+
cinfo.err = jpeg_std_error(&jerr.pub);
|
27
|
+
jerr.pub.error_exit = pkljpeg_error_exit;
|
28
|
+
|
29
|
+
if( setjmp(jerr.setjmp_buffer) ){
|
30
|
+
jpeg_destroy_decompress(&cinfo);
|
31
|
+
return(1);
|
32
|
+
}
|
33
|
+
|
34
|
+
jpeg_create_decompress(&cinfo);
|
35
|
+
jpeg_stdio_src(&cinfo, image);
|
36
|
+
jpeg_read_header(&cinfo, TRUE);
|
37
|
+
jpeg_start_decompress(&cinfo);
|
38
|
+
|
39
|
+
pkl->width = cinfo.output_width;
|
40
|
+
pkl->height = cinfo.output_height;
|
41
|
+
pkl->color = color_j2p(cinfo.out_color_space);
|
42
|
+
pkl->channel = cinfo.output_components;
|
43
|
+
if(pkl->color == PKL_UNKNOWN) return(1);
|
44
|
+
|
45
|
+
pkl->image = malloc(cinfo.output_height * cinfo.output_width * cinfo.output_components);
|
46
|
+
if(!pkl->image) return(1);
|
47
|
+
|
48
|
+
p = pkl->image;
|
49
|
+
while(cinfo.output_scanline < cinfo.output_height){
|
50
|
+
jpeg_read_scanlines(&cinfo, &p, 1);
|
51
|
+
p += (cinfo.output_width * cinfo.output_components);
|
52
|
+
}
|
53
|
+
jpeg_finish_decompress(&cinfo);
|
54
|
+
jpeg_destroy_decompress(&cinfo);
|
55
|
+
|
56
|
+
return(0);
|
57
|
+
}
|
58
|
+
|
59
|
+
//=============================================================================
|
60
|
+
// save_jpg
|
61
|
+
//=============================================================================
|
62
|
+
int save_jpeg(PKLImage pkl, FILE *image)
|
63
|
+
{
|
64
|
+
struct jpeg_compress_struct oinfo;
|
65
|
+
struct err_mgr jerr;
|
66
|
+
JSAMPROW row_pointer[1];
|
67
|
+
int i;
|
68
|
+
|
69
|
+
if(pkl->color == PKL_UNKNOWN) return(1);
|
70
|
+
|
71
|
+
oinfo.err = jpeg_std_error(&jerr.pub);
|
72
|
+
jerr.pub.error_exit = pkljpeg_error_exit;
|
73
|
+
|
74
|
+
if( setjmp(jerr.setjmp_buffer) ){
|
75
|
+
jpeg_destroy_compress(&oinfo);
|
76
|
+
return(1);
|
77
|
+
}
|
78
|
+
|
79
|
+
jpeg_create_compress(&oinfo);
|
80
|
+
jpeg_stdio_dest(&oinfo, image);
|
81
|
+
|
82
|
+
oinfo.image_width = pkl->width;
|
83
|
+
oinfo.image_height = pkl->height;
|
84
|
+
oinfo.in_color_space = color_p2j(pkl->color);
|
85
|
+
oinfo.input_components = pkl->channel;
|
86
|
+
jpeg_set_defaults(&oinfo);
|
87
|
+
jpeg_set_quality(&oinfo, compress_p2j(pkl->compress), TRUE);
|
88
|
+
oinfo.write_JFIF_header= TRUE;
|
89
|
+
oinfo.density_unit = 1; //(1)dots/inch, (2)dots/cm
|
90
|
+
|
91
|
+
jpeg_start_compress(&oinfo, TRUE);
|
92
|
+
|
93
|
+
for(i=0; i<pkl->height ; i++){
|
94
|
+
row_pointer[0] = &pkl->image[i*pkl->width*pkl->channel];
|
95
|
+
jpeg_write_scanlines(&oinfo, row_pointer, 1);
|
96
|
+
}
|
97
|
+
|
98
|
+
jpeg_finish_compress(&oinfo);
|
99
|
+
jpeg_destroy_compress(&oinfo);
|
100
|
+
|
101
|
+
|
102
|
+
return(0);
|
103
|
+
}
|
104
|
+
|
105
|
+
//=============================================================================
|
106
|
+
// color_p2j
|
107
|
+
//=============================================================================
|
108
|
+
static int color_p2j(int color)
|
109
|
+
{
|
110
|
+
switch(color){
|
111
|
+
case PKL_GRAYSCALE:
|
112
|
+
return JCS_GRAYSCALE;
|
113
|
+
case PKL_RGB:
|
114
|
+
return JCS_RGB;
|
115
|
+
//case PKL_YCbCr:
|
116
|
+
// return JCS_YCbCr;
|
117
|
+
case PKL_CMYK:
|
118
|
+
return JCS_CMYK;
|
119
|
+
//case PKL_YCCK:
|
120
|
+
// return JCS_YCCK;
|
121
|
+
//case PKL_RGBA:
|
122
|
+
default:
|
123
|
+
return JCS_UNKNOWN;
|
124
|
+
}
|
125
|
+
return JCS_UNKNOWN;
|
126
|
+
}
|
127
|
+
|
128
|
+
//=============================================================================
|
129
|
+
// color_j2p
|
130
|
+
//=============================================================================
|
131
|
+
static int color_j2p(int color)
|
132
|
+
{
|
133
|
+
switch(color){
|
134
|
+
case JCS_GRAYSCALE:
|
135
|
+
return PKL_GRAYSCALE;
|
136
|
+
case JCS_RGB:
|
137
|
+
return PKL_RGB;
|
138
|
+
//case JCS_YCbCr:
|
139
|
+
// return PKL_CMYK;
|
140
|
+
case JCS_CMYK:
|
141
|
+
return PKL_CMYK;
|
142
|
+
//case JCS_YCCK:
|
143
|
+
// return PKL_YCCK;
|
144
|
+
default:
|
145
|
+
return PKL_UNKNOWN;
|
146
|
+
}
|
147
|
+
return PKL_UNKNOWN;
|
148
|
+
}
|
149
|
+
|
150
|
+
//=============================================================================
|
151
|
+
// compress_p2j
|
152
|
+
//=============================================================================
|
153
|
+
static int compress_p2j(int level)
|
154
|
+
{
|
155
|
+
int comp;
|
156
|
+
|
157
|
+
if(level < 0) return(90);
|
158
|
+
comp = 100 - (level*10);
|
159
|
+
if(comp <= 0) return(1);
|
160
|
+
return(comp);
|
161
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#ifndef _LIB_PIKL_JPEG_
|
2
|
+
#define _LIB_PIKL_JPEG_
|
3
|
+
|
4
|
+
#include <stdio.h>
|
5
|
+
#include <stdlib.h>
|
6
|
+
#include <string.h>
|
7
|
+
#include <setjmp.h>
|
8
|
+
#include <jpeglib.h>
|
9
|
+
|
10
|
+
#include "pikl.h"
|
11
|
+
#include "pikl_private.h"
|
12
|
+
|
13
|
+
/* libjpeg error handler */
|
14
|
+
struct err_mgr {
|
15
|
+
struct jpeg_error_mgr pub;
|
16
|
+
jmp_buf setjmp_buffer;
|
17
|
+
};
|
18
|
+
|
19
|
+
int load_jpeg(PKLImage pkl, FILE *image);
|
20
|
+
int save_jpeg(PKLImage pkl, FILE *image);
|
21
|
+
|
22
|
+
#endif
|
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,22 @@
|
|
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
|
+
|
9
|
+
//=============================================================================
|
10
|
+
// PKLImage
|
11
|
+
//=============================================================================
|
12
|
+
struct _PKLImage {
|
13
|
+
int width;
|
14
|
+
int height;
|
15
|
+
PKL_COLOR_SPACE color;
|
16
|
+
int channel;
|
17
|
+
unsigned char *image;
|
18
|
+
PKL_FORMAT format;
|
19
|
+
int compress;
|
20
|
+
};
|
21
|
+
|
22
|
+
#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
|
+
|