speedpetal 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,9 @@
1
+ == 0.0.1 2009-03-05
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
5
+
6
+ == 0.0.2 2009-03-07
7
+
8
+ * 1 minor enhancement:
9
+ * bug fix
@@ -0,0 +1,7 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.rdoc
4
+ Rakefile
5
+ lib/speedpetal.rb
6
+ ext/extconf.rb
7
+ ext/speedpetal.c
@@ -0,0 +1,36 @@
1
+ = speedpetal
2
+
3
+ * http://www.kaeruspoon.net/
4
+
5
+ == DESCRIPTION:
6
+
7
+ Fast thumbnail Image generator.
8
+
9
+ == INSTALL:
10
+
11
+ * sudo gem install tsukasaoishi-speedpetal
12
+
13
+ == LICENSE:
14
+
15
+ (The MIT License)
16
+
17
+ Copyright (c) 2009 Tsukasa OISHI
18
+
19
+ Permission is hereby granted, free of charge, to any person obtaining
20
+ a copy of this software and associated documentation files (the
21
+ 'Software'), to deal in the Software without restriction, including
22
+ without limitation the rights to use, copy, modify, merge, publish,
23
+ distribute, sublicense, and/or sell copies of the Software, and to
24
+ permit persons to whom the Software is furnished to do so, subject to
25
+ the following conditions:
26
+
27
+ The above copyright notice and this permission notice shall be
28
+ included in all copies or substantial portions of the Software.
29
+
30
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
31
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
32
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
33
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
34
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
35
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
36
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,22 @@
1
+ %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
2
+ require File.dirname(__FILE__) + '/lib/speedpetal'
3
+
4
+ $hoe = Hoe.new('speedpetal', Speedpetal::VERSION) do |p|
5
+ p.developer('Tsukasa OISHI', 'tsukasa.oishi@gmail.com')
6
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
7
+ p.rubyforge_name = p.name
8
+ p.extra_dev_deps = [
9
+ ['newgem', ">= #{::Newgem::VERSION}"]
10
+ ]
11
+ p.spec_extras = {
12
+ :extensions => ['ext/extconf.rb'],
13
+ }
14
+
15
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
16
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
17
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
18
+ p.rsync_args = '-av --delete --ignore-errors'
19
+ end
20
+
21
+ require 'newgem/tasks'
22
+ Dir['tasks/**/*.rake'].each { |t| load t }
@@ -0,0 +1,3 @@
1
+ require "mkmf"
2
+ have_library("jpeg")
3
+ create_makefile("speedpetal")
@@ -0,0 +1,219 @@
1
+ //---------------------------------------------------
2
+ //
3
+ // Ruby Enhancing library
4
+ //
5
+ // Speedpetal
6
+ //
7
+ // Thumbnail image is made at high speed.
8
+ //
9
+ // 2009/03/04 Tsukasa OISHI
10
+ //
11
+ //
12
+ //
13
+ // Return Speedpetal version
14
+ // Speedpetal::version
15
+ //
16
+ // Make thumbnail image
17
+ // Speedpetal::resize(size, origin_file, output_file)
18
+ //
19
+ // Make square thumbnail image
20
+ // Speedpetal::resize_square(size, origin_file, output_file)
21
+ //
22
+ //
23
+ //---------------------------------------------------
24
+ #include <stdio.h>
25
+ #include <ruby.h>
26
+ #include <stdlib.h>
27
+ #include <math.h>
28
+ #include <string.h>
29
+ #include <jpeglib.h>
30
+
31
+ typedef struct image_size {
32
+ int width;
33
+ int height;
34
+ } IMAGESIZE;
35
+
36
+ // The ratio of resizes is requested.
37
+ double get_scale_factor(int target_size, int width, int height, int square) {
38
+ int denominator = square ? (width > height ? height : width) : (width > height ? width : height);
39
+ return (double)target_size / denominator;
40
+ }
41
+
42
+ // The size after making thumbnail image.
43
+ IMAGESIZE get_after_size(int request_size, struct jpeg_decompress_struct *in_info, int square) {
44
+ IMAGESIZE i_size;
45
+ double scale_factor = get_scale_factor(request_size, in_info->output_width, in_info->output_height, square);
46
+ i_size.width = i_size.height = request_size;
47
+
48
+ if((square && in_info->output_width > in_info->output_height) || (!square && in_info->output_width < in_info->output_height)) {
49
+ i_size.width = (int)(in_info->output_width * scale_factor);
50
+ } else {
51
+ i_size.height = (int)(in_info->output_height * scale_factor);
52
+ }
53
+ return i_size;
54
+ }
55
+
56
+ // configs.
57
+ void speed_setting(int request_size, struct jpeg_decompress_struct *in_info, int square) {
58
+ jpeg_calc_output_dimensions(in_info);
59
+ in_info->scale_denom = (unsigned int)(1 / get_scale_factor(request_size, in_info->output_width, in_info->output_height, square));
60
+ in_info->two_pass_quantize = FALSE;
61
+ in_info->dither_mode = JDITHER_ORDERED;
62
+ if (!in_info->quantize_colors) {
63
+ in_info->desired_number_of_colors = 216;
64
+ }
65
+ in_info->dct_method = JDCT_FASTEST;
66
+ in_info->do_fancy_upsampling = FALSE;
67
+ }
68
+
69
+ // memory allocate.
70
+ JSAMPARRAY sppedpetal_alloc(int width, int height, int components) {
71
+ int i;
72
+ JSAMPARRAY img = (JSAMPARRAY)malloc(sizeof(JSAMPROW) * height);
73
+ for(i = 0; i < height; i++){
74
+ img[i] = (JSAMPROW)calloc(sizeof(JSAMPLE), width * components);
75
+ }
76
+ return img;
77
+ }
78
+
79
+ // memory free.
80
+ void speedpetal_free(JSAMPARRAY buffer, int height) {
81
+ int i;
82
+ for(i = 0; i < height; i++){
83
+ free(buffer[i]);
84
+ }
85
+ free(buffer);
86
+ }
87
+
88
+ // create thumbnail image.
89
+ void create_thumbnail(JSAMPARRAY in_buffer, JSAMPARRAY out_buffer, int origin_width, int origin_height, int width, int height, int target_size, int components) {
90
+ double width_factor = (double)origin_width / width;
91
+ double height_factor = (double)origin_height / height;
92
+ int width_pos[width];
93
+ int x;
94
+ int y;
95
+ int start_x = 0;
96
+ int start_y = 0;
97
+
98
+ if(target_size) {
99
+ width > height ? (start_x = (width - target_size) / 2) : (start_y = (height - target_size) / 2);
100
+ width = height = target_size;
101
+ }
102
+
103
+ for(x = 0; x < width; x++) {
104
+ width_pos[x] = (int)((x + start_x) * width_factor) * components;
105
+ }
106
+
107
+ for(y = 0; y < height; y++) {
108
+ int height_pos = (int)((y + start_y) * height_factor);
109
+ for(x = 0; x < width; x++) {
110
+ memcpy(&out_buffer[y][x * components], &in_buffer[height_pos][width_pos[x]], components);
111
+ }
112
+ }
113
+ }
114
+
115
+ // main process
116
+ void abstract_resize(VALUE request_size, VALUE in_file_name, VALUE out_file_name, int square){
117
+ Check_Type(in_file_name, T_STRING);
118
+ Check_Type(out_file_name, T_STRING);
119
+ int target_size = NUM2INT(request_size);
120
+
121
+ FILE *infile;
122
+ if((infile = fopen(StringValuePtr(in_file_name), "rb")) == NULL){
123
+ rb_raise(rb_eRuntimeError, "Can't open in_file");
124
+ }
125
+
126
+ FILE *outfile;
127
+ if((outfile = fopen(StringValuePtr(out_file_name), "wb")) == NULL){
128
+ fclose(infile);
129
+ rb_raise(rb_eRuntimeError, "Can't open out_file");
130
+ }
131
+
132
+ // decompress
133
+ struct jpeg_decompress_struct in_info;
134
+ struct jpeg_error_mgr jpeg_error;
135
+ in_info.err = jpeg_std_error(&jpeg_error);
136
+
137
+ jpeg_create_decompress(&in_info);
138
+ jpeg_stdio_src(&in_info, infile);
139
+ jpeg_read_header(&in_info, TRUE);
140
+
141
+ speed_setting(target_size, &in_info, square);
142
+
143
+ int components = in_info.output_components;
144
+ J_COLOR_SPACE color_space = components == 3 ? JCS_RGB : JCS_GRAYSCALE;
145
+ IMAGESIZE image_size = get_after_size(target_size, &in_info, square);
146
+
147
+ jpeg_start_decompress(&in_info);
148
+
149
+ JSAMPARRAY buffer = (JSAMPARRAY)sppedpetal_alloc(in_info.output_width, in_info.output_height, components);
150
+
151
+ while(in_info.output_scanline < in_info.output_height){
152
+ jpeg_read_scanlines(&in_info, buffer + in_info.output_scanline, in_info.output_height - in_info.output_scanline);
153
+ }
154
+
155
+ JSAMPARRAY img = (JSAMPARRAY)sppedpetal_alloc(image_size.width, image_size.height, components);
156
+ create_thumbnail(buffer, img, in_info.output_width, in_info.output_height, image_size.width, image_size.height, square ? target_size : 0, components);
157
+
158
+ speedpetal_free(buffer, in_info.output_height);
159
+ jpeg_finish_decompress(&in_info);
160
+ jpeg_destroy_decompress(&in_info);
161
+ fclose(infile);
162
+
163
+ // compress
164
+ struct jpeg_compress_struct out_info;
165
+ out_info.err = jpeg_std_error(&jpeg_error);
166
+ jpeg_create_compress(&out_info);
167
+ jpeg_stdio_dest(&out_info, outfile);
168
+
169
+ if (square) {
170
+ out_info.image_width = target_size;
171
+ out_info.image_height = target_size;
172
+ } else {
173
+ out_info.image_width = image_size.width;
174
+ out_info.image_height = image_size.height;
175
+ }
176
+
177
+ out_info.input_components = components;
178
+ out_info.in_color_space = color_space;
179
+ jpeg_set_defaults(&out_info);
180
+
181
+ jpeg_start_compress(&out_info, TRUE);
182
+ jpeg_write_scanlines(&out_info, img, out_info.image_height);
183
+ jpeg_finish_compress(&out_info);
184
+ jpeg_destroy_compress(&out_info);
185
+ fclose(outfile);
186
+
187
+ speedpetal_free(img, image_size.height);
188
+ }
189
+
190
+ /* Thumbnail image create */
191
+ static VALUE t_resize(VALUE self, VALUE request_size, VALUE in_file_name, VALUE out_file_name){
192
+ abstract_resize(request_size, in_file_name, out_file_name, 0);
193
+ return self;
194
+ }
195
+
196
+ /* Square thumbnail image create */
197
+ static VALUE t_resize_square(VALUE self, VALUE request_size, VALUE in_file_name, VALUE out_file_name){
198
+ abstract_resize(request_size, in_file_name, out_file_name, 1);
199
+ return self;
200
+ }
201
+
202
+ // initial
203
+ void Init_speedpetal() {
204
+ VALUE cSpeedpetal;
205
+
206
+ cSpeedpetal = rb_define_module("Speedpetal");
207
+
208
+ /* Thumbnail image create */
209
+ // request_size: thumbnail size
210
+ // in_file_name: origin image path
211
+ // out_file_name: thumbnail image path
212
+ rb_define_module_function(cSpeedpetal, "resize", t_resize, 3);
213
+
214
+ /* Square thumbnail image create */
215
+ // request_size: thumbnail size
216
+ // in_file_name: origin image path
217
+ // out_file_name: thumbnail image path
218
+ rb_define_module_function(cSpeedpetal, "resize_square", t_resize_square, 3);
219
+ }
@@ -0,0 +1,7 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require 'speedpetal.so'
5
+ module Speedpetal
6
+ VERSION = '0.0.3'
7
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: speedpetal
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Tsukasa OISHI
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-03-07 00:00:00 +09:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: newgem
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.2.3
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: hoe
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.8.0
34
+ version:
35
+ description: Fast thumbnail Image generator.
36
+ email:
37
+ - tsukasa.oishi@gmail.com
38
+ executables: []
39
+
40
+ extensions:
41
+ - ext/extconf.rb
42
+ extra_rdoc_files:
43
+ - History.txt
44
+ - Manifest.txt
45
+ - README.rdoc
46
+ files:
47
+ - History.txt
48
+ - Manifest.txt
49
+ - README.rdoc
50
+ - Rakefile
51
+ - lib/speedpetal.rb
52
+ - ext/extconf.rb
53
+ - ext/speedpetal.c
54
+ has_rdoc: true
55
+ homepage: http://www.kaeruspoon.net/
56
+ licenses: []
57
+
58
+ post_install_message:
59
+ rdoc_options:
60
+ - --main
61
+ - README.rdoc
62
+ require_paths:
63
+ - lib
64
+ - ext
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: "0"
70
+ version:
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: "0"
76
+ version:
77
+ requirements: []
78
+
79
+ rubyforge_project: speedpetal
80
+ rubygems_version: 1.3.5
81
+ signing_key:
82
+ specification_version: 2
83
+ summary: Fast thumbnail Image generator.
84
+ test_files: []
85
+