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.
@@ -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
@@ -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
+ }
@@ -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
+