rszr 0.4.0 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: f6ab5d9447d5919f0bed35e0562f7645bb5a23db
4
- data.tar.gz: 88988dc45c31575db6a1cf11618298be6641fca8
2
+ SHA256:
3
+ metadata.gz: c4fc21afb848256445e310a0feebab86b2b10ee6baf464bd7e67a44b282b4d07
4
+ data.tar.gz: bfe92bbc780dbf03135b4b3d7296df141bee74279412b6bd3b6d2ba70362a140
5
5
  SHA512:
6
- metadata.gz: 4a5d7d5ba83088cce7de9af7a0d68c92d2e2c0f58029617dfa1c270a83aa58af96168b11b2bebdd0c3ad1a930598726acd0809b5b3a7dea901567402bf23ed1b
7
- data.tar.gz: 1a53df4fcbd02f524d42cfadcd9dbacdba3945423f5a244af8da190e4cc59de2b87b267de78b0481c4c8d106d27dc16a2ec30f4f728310eced9e9da8a0191f0f
6
+ metadata.gz: 26d46f7b4d594da5e871d75975d99cd54358bb6585d8b18fbddcba1b4383970099891f7af6d16b51b8dcf19f5ed179b275d001b15f546c3baa58a3b6573613f9
7
+ data.tar.gz: 0f5866b917277c7afb518fb15ba83451fc7b448681fec26dad4321d17cfa464854e9182cff88008f7ee25b1c6df135f6a14f3980b64a145db9ef93e035de1d9e
data/README.md CHANGED
@@ -45,6 +45,9 @@ image.resize(400, 300)
45
45
  # save it
46
46
  image.save('resized.jpg')
47
47
 
48
+ # save it as PNG
49
+ image.save('resized.png')
50
+
48
51
  # auto height
49
52
  image.resize(400, :auto)
50
53
 
@@ -57,18 +60,28 @@ image.resize(0.5)
57
60
  # crop
58
61
  image.crop(200, 200, 100, 100)
59
62
 
63
+ # rotate three times 90 deg clockwise
64
+ image.turn!(3)
65
+
66
+ # rotate one time 90 deg counterclockwise
67
+ image.turn!(-1)
68
+
69
+ # initialize copy
70
+ image.dup
71
+
60
72
  # save memory, do not duplicate instance
61
73
  image.resize!(400, :auto)
62
74
 
63
- # image dimensions
75
+ # image info
64
76
  image.width => 400
65
77
  image.height => 300
66
78
  image.dimensions => [400, 300]
79
+ image.format => "jpeg"
67
80
  ```
68
81
 
69
82
  ## Thread safety
70
83
 
71
- As of version 0.4.0, Rszr provides thread safety by synchronizing access to imlib2 function calls.
84
+ As of version 0.4.0, Rszr is thread safe through the Ruby GIL.
72
85
  Use of any previous versions in a threaded environment is discouraged.
73
86
 
74
87
  ## Speed
data/Rakefile CHANGED
@@ -9,3 +9,9 @@ begin
9
9
  rescue LoadError
10
10
  # no rspec available
11
11
  end
12
+
13
+ require 'rake/extensiontask'
14
+
15
+ Rake::ExtensionTask.new('rszr') do |ext|
16
+ ext.lib_dir = 'lib/rszr'
17
+ end
@@ -0,0 +1,63 @@
1
+ #ifndef RUBY_RSZR_ERRORS
2
+ #define RUBY_RSZR_ERRORS
3
+
4
+ #include "rszr.h"
5
+ #include "errors.h"
6
+
7
+ VALUE eRszrError = Qnil;
8
+ VALUE eRszrFileNotFound = Qnil;
9
+ VALUE eRszrTransformationError = Qnil;
10
+ VALUE eRszrErrorWithMessage = Qnil;
11
+ VALUE eRszrLoadError = Qnil;
12
+ VALUE eRszrSaveError = Qnil;
13
+
14
+ static const char * const sRszrErrorMessages[] =
15
+ {
16
+ "File does not exist",
17
+ "File is a directory",
18
+ "Read permission denied",
19
+ "Unsupported format",
20
+ "Path too long",
21
+ "Non-existant path component",
22
+ "Path component is not a directory",
23
+ "Path outside address space",
24
+ "Too many symbolic links",
25
+ "Out of memory",
26
+ "Out of file descriptors",
27
+ "Write permission denied",
28
+ "Out of disk space",
29
+ "Unknown error"
30
+ };
31
+ const int RSZR_MAX_ERROR_INDEX = 13;
32
+
33
+ void Init_rszr_errors()
34
+ {
35
+ eRszrError = rb_define_class_under(mRszr, "Error", rb_eStandardError);
36
+ eRszrFileNotFound = rb_define_class_under(mRszr, "FileNotFound", eRszrError);
37
+ eRszrTransformationError = rb_define_class_under(mRszr, "TransformationError", eRszrError);
38
+ eRszrErrorWithMessage = rb_define_class_under(mRszr, "ErrorWithMessage", eRszrError);
39
+ eRszrLoadError = rb_define_class_under(mRszr, "LoadError", eRszrErrorWithMessage);
40
+ eRszrSaveError = rb_define_class_under(mRszr, "SaveError", eRszrErrorWithMessage);
41
+ }
42
+
43
+ static void rszr_raise_error_with_message(VALUE rb_error_class, Imlib_Load_Error error)
44
+ {
45
+ int error_index = (int) error - 1;
46
+ if (error_index < 1 || error_index > RSZR_MAX_ERROR_INDEX)
47
+ error_index = 13;
48
+ VALUE rb_error = rb_exc_new2(rb_error_class, sRszrErrorMessages[error_index]);
49
+ rb_exc_raise(rb_error);
50
+ }
51
+
52
+ void rszr_raise_load_error(Imlib_Load_Error error)
53
+ {
54
+ rszr_raise_error_with_message(eRszrLoadError, error);
55
+ }
56
+
57
+ void rszr_raise_save_error(Imlib_Load_Error error)
58
+ {
59
+ rszr_raise_error_with_message(eRszrSaveError, error);
60
+ }
61
+
62
+
63
+ #endif
@@ -0,0 +1,15 @@
1
+ #ifndef RUBY_RSZR_ERRORS_H
2
+ #define RUBY_RSZR_ERRORS_H
3
+
4
+ void Init_rszr_errors();
5
+ void rszr_raise_load_error(Imlib_Load_Error error);
6
+ void rszr_raise_save_error(Imlib_Load_Error error);
7
+
8
+ extern VALUE eRszrError;
9
+ extern VALUE eRszrFileNotFound;
10
+ extern VALUE eRszrTransformationError;
11
+ extern VALUE eRszrErrorWithMessage;
12
+ extern VALUE eRszrLoadError;
13
+ extern VALUE eRszrSaveError;
14
+
15
+ #endif
@@ -0,0 +1,18 @@
1
+ require 'mkmf'
2
+ require 'rbconfig'
3
+
4
+ imlib2_config = with_config('imlib2-config', 'imlib2-config')
5
+
6
+ $CFLAGS << ' -DX_DISPLAY_MISSING ' << `#{imlib2_config} --cflags`.chomp
7
+ $LDFLAGS << ' ' << `#{imlib2_config} --libs`.chomp
8
+ $LDFLAGS.gsub!(/\ -lX11\ -lXext/, '') if RUBY_PLATFORM =~ /darwin/
9
+
10
+ unless find_header('Imlib2.h')
11
+ abort 'imlib2 development headers are missing'
12
+ end
13
+
14
+ unless find_library('Imlib2', 'imlib_set_cache_size')
15
+ abort 'Imlib2 is missing'
16
+ end
17
+
18
+ create_makefile 'rszr/rszr'
@@ -0,0 +1,309 @@
1
+ #ifndef RUBY_RSZR_IMAGE
2
+ #define RUBY_RSZR_IMAGE
3
+
4
+ #include "rszr.h"
5
+ #include "image.h"
6
+ #include "errors.h"
7
+
8
+ VALUE cImage = Qnil;
9
+
10
+
11
+ static void rszr_free_image(Imlib_Image image)
12
+ {
13
+ imlib_context_set_image(image);
14
+ imlib_free_image();
15
+ }
16
+
17
+
18
+ static void rszr_image_deallocate(rszr_image_handle * handle)
19
+ {
20
+ // fprintf(stderr, "rszr_image_deallocate");
21
+ if (handle->image) {
22
+ // fprintf(stderr, ": freeing");
23
+ rszr_free_image(handle->image);
24
+ handle->image = NULL;
25
+ }
26
+ free(handle);
27
+ // fprintf(stderr, "\n");
28
+ }
29
+
30
+
31
+ static VALUE rszr_image_s_allocate(VALUE klass)
32
+ {
33
+ rszr_image_handle * handle = calloc(1, sizeof(rszr_image_handle));
34
+ return Data_Wrap_Struct(klass, NULL, rszr_image_deallocate, handle);
35
+ }
36
+
37
+
38
+ static VALUE rszr_image_initialize(VALUE self, VALUE rb_width, VALUE rb_height)
39
+ {
40
+ rszr_image_handle * handle;
41
+
42
+ Check_Type(rb_width, T_FIXNUM);
43
+ Check_Type(rb_height, T_FIXNUM);
44
+
45
+ Data_Get_Struct(self, rszr_image_handle, handle);
46
+
47
+ handle->image = imlib_create_image(FIX2INT(rb_width), FIX2INT(rb_height));
48
+
49
+ return self;
50
+ }
51
+
52
+
53
+ static VALUE rszr_image_s__load(VALUE klass, VALUE rb_path)
54
+ {
55
+ rszr_image_handle * handle;
56
+ Imlib_Image image;
57
+ char * path;
58
+ Imlib_Load_Error error;
59
+ VALUE oImage;
60
+
61
+ path = StringValueCStr(rb_path);
62
+
63
+ imlib_set_cache_size(0);
64
+ image = imlib_load_image_with_error_return(path, &error);
65
+
66
+ if (!image) {
67
+ rszr_raise_load_error(error);
68
+ return Qnil;
69
+ }
70
+
71
+ oImage = rszr_image_s_allocate(cImage);
72
+ Data_Get_Struct(oImage, rszr_image_handle, handle);
73
+ handle->image = image;
74
+ return oImage;
75
+ }
76
+
77
+
78
+ static VALUE rszr_image_format(VALUE self)
79
+ {
80
+ rszr_image_handle * handle;
81
+ char * format;
82
+
83
+ Data_Get_Struct(self, rszr_image_handle, handle);
84
+
85
+ imlib_context_set_image(handle->image);
86
+ format = imlib_image_format();
87
+
88
+ if (format) {
89
+ return rb_str_new2(format);
90
+ } else {
91
+ return Qnil;
92
+ }
93
+ }
94
+
95
+
96
+ static VALUE rszr_image_width(VALUE self)
97
+ {
98
+ rszr_image_handle * handle;
99
+ int width;
100
+
101
+ Data_Get_Struct(self, rszr_image_handle, handle);
102
+
103
+ imlib_context_set_image(handle->image);
104
+ width = imlib_image_get_width();
105
+
106
+ return INT2NUM(width);
107
+ }
108
+
109
+
110
+ static VALUE rszr_image_height(VALUE self)
111
+ {
112
+ rszr_image_handle * handle;
113
+ int height;
114
+
115
+ Data_Get_Struct(self, rszr_image_handle, handle);
116
+
117
+ imlib_context_set_image(handle->image);
118
+ height = imlib_image_get_height();
119
+
120
+ return INT2NUM(height);
121
+ }
122
+
123
+
124
+ static VALUE rszr_image_dup(VALUE self)
125
+ {
126
+ rszr_image_handle * handle;
127
+ rszr_image_handle * cloned_handle;
128
+ Imlib_Image cloned_image;
129
+ VALUE oClonedImage;
130
+
131
+ Data_Get_Struct(self, rszr_image_handle, handle);
132
+
133
+ imlib_context_set_image(handle->image);
134
+ cloned_image = imlib_clone_image();
135
+
136
+ if (!cloned_image) {
137
+ rb_raise(eRszrTransformationError, "error cloning image");
138
+ return Qnil;
139
+ }
140
+
141
+ oClonedImage = rszr_image_s_allocate(cImage);
142
+ Data_Get_Struct(oClonedImage, rszr_image_handle, cloned_handle);
143
+ cloned_handle->image = cloned_image;
144
+
145
+ return oClonedImage;
146
+ }
147
+
148
+
149
+ static VALUE rszr_image__turn_bang(VALUE self, VALUE orientation)
150
+ {
151
+ rszr_image_handle * handle;
152
+
153
+ Data_Get_Struct(self, rszr_image_handle, handle);
154
+
155
+ imlib_context_set_image(handle->image);
156
+ imlib_image_orientate(NUM2INT(orientation));
157
+
158
+ return self;
159
+ }
160
+
161
+
162
+ static Imlib_Image rszr_create_cropped_scaled_image(const Imlib_Image image, VALUE rb_src_x, VALUE rb_src_y, VALUE rb_src_w, VALUE rb_src_h, VALUE rb_dst_w, VALUE rb_dst_h)
163
+ {
164
+ Imlib_Image resized_image;
165
+
166
+ int src_x = NUM2INT(rb_src_x);
167
+ int src_y = NUM2INT(rb_src_y);
168
+ int src_w = NUM2INT(rb_src_w);
169
+ int src_h = NUM2INT(rb_src_h);
170
+ int dst_w = NUM2INT(rb_dst_w);
171
+ int dst_h = NUM2INT(rb_dst_h);
172
+
173
+ // TODO: raise if <= 0
174
+
175
+ imlib_context_set_image(image);
176
+ imlib_context_set_anti_alias(1);
177
+ resized_image = imlib_create_cropped_scaled_image(src_x, src_y, src_w, src_h, dst_w, dst_h);
178
+
179
+ if (!resized_image) {
180
+ rb_raise(eRszrTransformationError, "error resizing image");
181
+ return NULL;
182
+ }
183
+
184
+ return resized_image;
185
+ }
186
+
187
+
188
+ static VALUE rszr_image__resize(VALUE self, VALUE bang, VALUE rb_src_x, VALUE rb_src_y, VALUE rb_src_w, VALUE rb_src_h, VALUE rb_dst_w, VALUE rb_dst_h)
189
+ {
190
+ rszr_image_handle * handle;
191
+ Imlib_Image resized_image;
192
+ rszr_image_handle * resized_handle;
193
+ VALUE oResizedImage;
194
+
195
+ Data_Get_Struct(self, rszr_image_handle, handle);
196
+
197
+ resized_image = rszr_create_cropped_scaled_image(handle->image, rb_src_x, rb_src_y, rb_src_w, rb_src_h, rb_dst_w, rb_dst_h);
198
+ if (!resized_image) return Qfalse;
199
+
200
+ if (RTEST(bang)) {
201
+ rszr_free_image(handle->image);
202
+ handle->image = resized_image;
203
+
204
+ return self;
205
+ }
206
+ else {
207
+ oResizedImage = rszr_image_s_allocate(cImage);
208
+ Data_Get_Struct(oResizedImage, rszr_image_handle, resized_handle);
209
+ resized_handle->image = resized_image;
210
+
211
+ return oResizedImage;
212
+ }
213
+ }
214
+
215
+
216
+ static Imlib_Image rszr_create_cropped_image(const Imlib_Image image, VALUE rb_x, VALUE rb_y, VALUE rb_w, VALUE rb_h)
217
+ {
218
+ Imlib_Image cropped_image;
219
+
220
+ int x = NUM2INT(rb_x);
221
+ int y = NUM2INT(rb_y);
222
+ int w = NUM2INT(rb_w);
223
+ int h = NUM2INT(rb_h);
224
+
225
+ imlib_context_set_image(image);
226
+ cropped_image = imlib_create_cropped_image(x, y, w, h);
227
+
228
+ if (!cropped_image) {
229
+ rb_raise(eRszrTransformationError, "error cropping image");
230
+ return NULL;
231
+ }
232
+
233
+ return cropped_image;
234
+ }
235
+
236
+
237
+ static VALUE rszr_image__crop(VALUE self, VALUE bang, VALUE rb_x, VALUE rb_y, VALUE rb_w, VALUE rb_h)
238
+ {
239
+ rszr_image_handle * handle;
240
+ Imlib_Image cropped_image;
241
+ rszr_image_handle * cropped_handle;
242
+ VALUE oCroppedImage;
243
+
244
+ Data_Get_Struct(self, rszr_image_handle, handle);
245
+
246
+ cropped_image = rszr_create_cropped_image(handle->image, rb_x, rb_y, rb_w, rb_h);
247
+ if (!cropped_image) return Qfalse;
248
+
249
+ if (RTEST(bang)) {
250
+ rszr_free_image(handle->image);
251
+ handle->image = cropped_image;
252
+
253
+ return self;
254
+ }
255
+ else {
256
+ oCroppedImage = rszr_image_s_allocate(cImage);
257
+ Data_Get_Struct(oCroppedImage, rszr_image_handle, cropped_handle);
258
+ cropped_handle->image = cropped_image;
259
+
260
+ return oCroppedImage;
261
+ }
262
+ }
263
+
264
+
265
+ static VALUE rszr_image__save(VALUE self, VALUE rb_path, VALUE rb_format)
266
+ {
267
+ rszr_image_handle * handle;
268
+ char * path;
269
+ char * format;
270
+ Imlib_Load_Error save_error;
271
+
272
+ path = StringValueCStr(rb_path);
273
+ format = StringValueCStr(rb_format);
274
+
275
+ Data_Get_Struct(self, rszr_image_handle, handle);
276
+
277
+ imlib_context_set_image(handle->image);
278
+ imlib_image_set_format(format);
279
+ imlib_save_image_with_error_return(path, &save_error);
280
+
281
+ if (save_error) {
282
+ rszr_raise_save_error(save_error);
283
+ return Qfalse;
284
+ }
285
+
286
+ return Qtrue;
287
+ }
288
+
289
+ void Init_rszr_image()
290
+ {
291
+ cImage = rb_define_class_under(mRszr, "Image", rb_cObject);
292
+ rb_define_alloc_func(cImage, rszr_image_s_allocate);
293
+
294
+ // Class methods
295
+ rb_define_private_method(rb_singleton_class(cImage), "_load", rszr_image_s__load, 1);
296
+
297
+ // Instance methods
298
+ rb_define_method(cImage, "initialize", rszr_image_initialize, 2);
299
+ rb_define_method(cImage, "width", rszr_image_width, 0);
300
+ rb_define_method(cImage, "height", rszr_image_height, 0);
301
+ rb_define_method(cImage, "format", rszr_image_format, 0);
302
+ rb_define_method(cImage, "dup", rszr_image_dup, 0);
303
+ rb_define_private_method(cImage, "_resize", rszr_image__resize, 7);
304
+ rb_define_private_method(cImage, "_crop", rszr_image__crop, 5);
305
+ rb_define_private_method(cImage, "_turn!", rszr_image__turn_bang, 1);
306
+ rb_define_private_method(cImage, "_save", rszr_image__save, 2);
307
+ }
308
+
309
+ #endif
@@ -0,0 +1,12 @@
1
+ #ifndef RUBY_RSZR_IMAGE_H
2
+ #define RUBY_RSZR_IMAGE_H
3
+
4
+ typedef struct {
5
+ Imlib_Image image;
6
+ } rszr_image_handle;
7
+
8
+ extern VALUE cImage;
9
+
10
+ void Init_rszr_image();
11
+
12
+ #endif
@@ -0,0 +1,17 @@
1
+ #ifndef RUBY_RSZR
2
+ #define RUBY_RSZR
3
+
4
+ #include "rszr.h"
5
+ #include "image.h"
6
+ #include "errors.h"
7
+
8
+ VALUE mRszr = Qnil;
9
+
10
+ void Init_rszr()
11
+ {
12
+ mRszr = rb_define_module("Rszr");
13
+ Init_rszr_errors();
14
+ Init_rszr_image();
15
+ }
16
+
17
+ #endif
@@ -0,0 +1,10 @@
1
+ #ifndef RUBY_RSZR_H
2
+ #define RUBY_RSZR_H
3
+
4
+ #include "ruby.h"
5
+ #include <Imlib2.h>
6
+
7
+ extern VALUE mRszr;
8
+ void Init_rszr();
9
+
10
+ #endif
@@ -1,12 +1,6 @@
1
- require 'fiddle'
2
- require 'fiddle/import'
3
1
  require 'rbconfig'
4
2
  require 'pathname'
5
3
 
4
+ require 'rszr/rszr'
6
5
  require 'rszr/version'
7
- require 'rszr/errors'
8
- require 'rszr/lib'
9
- require 'rszr/lock'
10
- require 'rszr/handle'
11
- require 'rszr/base'
12
6
  require 'rszr/image'
@@ -1,97 +1,53 @@
1
1
  module Rszr
2
2
  class Image
3
- include Base
4
3
 
5
4
  class << self
6
5
 
7
- alias_method :instantiate, :new
8
- protected :instantiate
9
-
10
- def new(width, height)
11
- ptr = with_lock { imlib_create_image(width, height) }
12
- raise Error, 'Could not instantiate image' if ptr.null?
13
- instantiate(ptr)
14
- end
15
-
16
6
  def load(path, options = {})
17
7
  path = path.to_s
18
8
  raise FileNotFound unless File.exist?(path)
19
- load_error = LoadError.new
20
- ptr = with_lock do
21
- imlib_set_cache_size(0)
22
- imlib_load_image_with_error_return(path, load_error.ptr)
23
- end
24
- raise load_error, load_error.message if ptr.null?
25
- return instantiate(ptr)
9
+ _load(path)
26
10
  end
27
11
  alias :open :load
28
12
 
29
- protected
30
-
31
- def finalize(ptr)
32
- with_lock do
33
- imlib_context_set_image(ptr)
34
- imlib_free_image
35
- end
36
- end
37
-
38
- end
39
-
40
- def initialize(ptr)
41
- @handle = Handle.new(self, ptr)
42
13
  end
43
-
44
- def width
45
- with_image { imlib_image_get_width }
46
- end
47
-
48
- def height
49
- with_image { imlib_image_get_height }
50
- end
51
-
14
+
52
15
  def dimensions
53
16
  [width, height]
54
17
  end
55
-
56
- def format
57
- str_ptr = with_image { imlib_image_format }
58
- return if str_ptr.null?
59
- str_ptr.to_s
18
+
19
+ def inspect
20
+ fmt = format
21
+ fmt = " #{fmt.upcase}" if fmt
22
+ "#<#{self.class.name}:0x#{object_id.to_s(16)} #{width}x#{height}#{fmt}>"
60
23
  end
61
-
24
+
62
25
  def resize(*args)
63
- instantiate(create_resized_image(*args))
26
+ _resize(false, *calculate_size(*args))
64
27
  end
65
-
28
+
66
29
  def resize!(*args)
67
- handle.replace!(create_resized_image(*args))
68
- self
30
+ _resize(true, *calculate_size(*args))
69
31
  end
70
-
71
- def crop(*args)
72
- instantiate(create_cropped_image(*args))
32
+
33
+ def crop(x, y, width, height)
34
+ _crop(false, x, y, width, height)
73
35
  end
74
-
75
- def crop!(*args)
76
- handle.replace!(create_cropped_image(*args))
77
- self
36
+
37
+ def crop!(x, y, width, height)
38
+ _crop(true, x, y, width, height)
78
39
  end
79
-
80
- def save(path, format = nil)
81
- with_image do
82
- format ||= format_from_filename(path) || 'jpg'
83
- imlib_image_set_format(format)
84
- save_error = SaveError.new
85
- imlib_save_image_with_error_return(path, save_error.ptr)
86
- raise save_error, save_error.message if save_error.error?
87
- true
88
- end
40
+
41
+ def turn!(orientation)
42
+ orientation = orientation.abs + 2 if orientation.negative?
43
+ _turn!(orientation % 4)
89
44
  end
90
-
91
- def inspect
92
- "#<#{self.class.name}:0x#{object_id.to_s(16)} width=#{width} height=#{height} format=#{format.inspect}>"
45
+
46
+ def save(path, format = nil)
47
+ format ||= format_from_filename(path) || 'jpg'
48
+ _save(path.to_s, format.to_s)
93
49
  end
94
-
50
+
95
51
  private
96
52
 
97
53
  # 0.5 0 < scale < 1
@@ -102,7 +58,7 @@ module Rszr
102
58
  # 400, 300, background: rgba
103
59
  # 400, 300, aspect: false
104
60
 
105
- def create_resized_image(*args)
61
+ def calculate_size(*args)
106
62
  options = args.last.is_a?(Hash) ? args.pop : {}
107
63
  assert_valid_keys options, :crop, :background, :skew #:extend, :width, :height, :max_width, :max_height, :box
108
64
  original_width, original_height = width, height
@@ -142,38 +98,18 @@ module Rszr
142
98
  else
143
99
  raise ArgumentError, "wrong number of arguments (#{args.size} for 1..2)"
144
100
  end
145
- resized_ptr = with_image do
146
- imlib_context_set_anti_alias(1)
147
- imlib_create_cropped_scaled_image(x, y, imlib_image_get_width, imlib_image_get_height, new_width.round, new_height.round)
148
- end
149
- raise TransformationError, "error resizing image" if resized_ptr.null?
150
- resized_ptr
151
- end
152
-
153
- def create_cropped_image(x, y, width, height)
154
- cropped_ptr = with_image { imlib_create_cropped_image(x, y, width, height) }
155
- raise TransformationError, 'error cropping image' if cropped_ptr.null?
156
- cropped_ptr
101
+ [x, y, original_width, original_height, new_width.round, new_height.round]
157
102
  end
158
103
 
159
104
  def format_from_filename(path)
160
105
  File.extname(path)[1..-1]
161
106
  end
162
-
163
- def context_set_image
164
- imlib_context_set_image(ptr)
165
- end
166
-
167
- def with_image
168
- with_lock do
169
- context_set_image
170
- yield
107
+
108
+ def assert_valid_keys(hsh, *valid_keys)
109
+ if unknown_key = (hsh.keys - valid_keys).first
110
+ raise ArgumentError.new("Unknown key: #{unknown_key.inspect}. Valid keys are: #{valid_keys.map(&:inspect).join(', ')}")
171
111
  end
172
112
  end
173
113
 
174
- def instantiate(ptr)
175
- self.class.send(:instantiate, ptr)
176
- end
177
-
178
114
  end
179
115
  end
@@ -1,3 +1,3 @@
1
1
  module Rszr
2
- VERSION = "0.4.0"
2
+ VERSION = "0.5.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rszr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthias Grosser
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-05 00:00:00.000000000 Z
11
+ date: 2019-03-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake-compiler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: byebug
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -108,23 +122,40 @@ dependencies:
108
122
  - - ">="
109
123
  - !ruby/object:Gem::Version
110
124
  version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: memory_profiler
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
111
139
  description: Fast image resizer - do one thing and do it fast.
112
140
  email:
113
141
  - mtgrosser@gmx.net
114
142
  executables: []
115
- extensions: []
143
+ extensions:
144
+ - ext/rszr/extconf.rb
116
145
  extra_rdoc_files: []
117
146
  files:
118
147
  - LICENSE
119
148
  - README.md
120
149
  - Rakefile
150
+ - ext/rszr/errors.c
151
+ - ext/rszr/errors.h
152
+ - ext/rszr/extconf.rb
153
+ - ext/rszr/image.c
154
+ - ext/rszr/image.h
155
+ - ext/rszr/rszr.c
156
+ - ext/rszr/rszr.h
121
157
  - lib/rszr.rb
122
- - lib/rszr/base.rb
123
- - lib/rszr/errors.rb
124
- - lib/rszr/handle.rb
125
158
  - lib/rszr/image.rb
126
- - lib/rszr/lib.rb
127
- - lib/rszr/lock.rb
128
159
  - lib/rszr/version.rb
129
160
  homepage: https://github.com/mtgrosser/rszr
130
161
  licenses:
@@ -134,6 +165,7 @@ post_install_message:
134
165
  rdoc_options: []
135
166
  require_paths:
136
167
  - lib
168
+ - ext
137
169
  required_ruby_version: !ruby/object:Gem::Requirement
138
170
  requirements:
139
171
  - - ">="
@@ -145,8 +177,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
145
177
  - !ruby/object:Gem::Version
146
178
  version: '0'
147
179
  requirements: []
148
- rubyforge_project:
149
- rubygems_version: 2.5.2.3
180
+ rubygems_version: 3.0.1
150
181
  signing_key:
151
182
  specification_version: 4
152
183
  summary: Fast image resizer
@@ -1,29 +0,0 @@
1
- module Rszr
2
- module Base
3
-
4
- def self.included(base)
5
- Rszr::Lib.delegate(base)
6
- Rszr::Lib.delegate(base.singleton_class)
7
- base.include(Lock)
8
- base.extend(Lock)
9
- end
10
-
11
- protected
12
-
13
- def handle
14
- @handle
15
- end
16
-
17
- def ptr
18
- @handle.ptr
19
- end
20
-
21
- private
22
-
23
- def assert_valid_keys(hsh, *valid_keys)
24
- if unknown_key = (hsh.keys - valid_keys).first
25
- raise ArgumentError.new("Unknown key: #{unknown_key.inspect}. Valid keys are: #{valid_keys.map(&:inspect).join(', ')}")
26
- end
27
- end
28
- end
29
- end
@@ -1,42 +0,0 @@
1
- module Rszr
2
- class Error < StandardError; end
3
-
4
- class ErrorWithMessage < Error
5
- MESSAGES = [nil,
6
- 'File does not exist',
7
- 'File is a directory',
8
- 'Read permission denied',
9
- 'Unsupported format',
10
- 'Path too long',
11
- 'Non-existant path component',
12
- 'Path component is not a directory',
13
- 'Path outside address space',
14
- 'Too many symbolic links',
15
- 'Out of memory',
16
- 'Out of file descriptors',
17
- 'Write permission denied',
18
- 'Out of disk space',
19
- 'Unknown error']
20
-
21
- attr_reader :ptr
22
-
23
- def initialize
24
- @ptr = Fiddle::Pointer.malloc(Rszr::Lib.sizeof('Imlib_Load_Error'))
25
- end
26
-
27
- def error?
28
- return if ptr.null?
29
- 0 != ptr[0]
30
- end
31
-
32
- def message
33
- MESSAGES[ptr[0]] unless ptr.null?
34
- end
35
- end
36
-
37
-
38
- class FileNotFound < Error; end
39
- class LoadError < ErrorWithMessage; end
40
- class TransformationError < Error; end
41
- class SaveError < ErrorWithMessage; end
42
- end
@@ -1,37 +0,0 @@
1
- module Rszr
2
- class Handle
3
- attr_reader :ptr, :klass
4
-
5
- def initialize(obj, ptr)
6
- @ptr = ptr
7
- raise ArgumentError, "#{obj.class.inspect} does not define the finalize class method" unless obj.class.respond_to?(:finalize, true)
8
- @klass = obj.class
9
- ObjectSpace.define_finalizer(obj, self)
10
- end
11
-
12
- def replace!(other_ptr)
13
- raise ArgumentError, "Cannot replace pointer with itself" if ptr == other_ptr
14
- finalize!
15
- @ptr = other_ptr
16
- end
17
-
18
- def finalize!(*args)
19
- #puts "Finalizing #{args.inspect} #{ptr.inspect}"
20
- if !ptr.null? && klass
21
- #puts " calling #{args.inspect}"
22
- klass.send(:finalize, ptr)
23
- @ptr = Fiddle::Pointer.new(0)
24
- #else
25
- #puts " skipping #{args.inspect}"
26
- end
27
- end
28
-
29
- def release!
30
- replace! Fiddle::Pointer.new(0)
31
- end
32
-
33
- def call(object_id)
34
- finalize!(object_id)
35
- end
36
- end
37
- end
@@ -1,73 +0,0 @@
1
- module Rszr
2
-
3
- module Lib
4
- extend Fiddle::Importer
5
-
6
- library, message = case RbConfig::CONFIG['arch']
7
- when /darwin/ then ['libImlib2.dylib', 'brew install imlib2']
8
- when /mswin/, /cygwin/ then ['imlib2.dll', nil]
9
- else
10
- ['libImlib2.so', "yum install imlib2 imlib2-devel\napt-get install libimlib2 libimlib2-dev"]
11
- end
12
-
13
- begin
14
- dlload library
15
- rescue Fiddle::DLError => e
16
- print "\n The Imlib2 library could not be loaded. "
17
- puts "You can install it using\n\n #{message}\n" if message
18
- puts ''
19
- raise e
20
- end
21
-
22
- typealias 'Imlib_Image', 'void *'
23
- typealias 'Imlib_Context', 'void *'
24
- typealias 'enum', 'int'
25
- typealias 'Imlib_Load_Error', 'enum'
26
-
27
- #typedef void *Imlib_Color_Modifier;
28
- #typedef void *Imlib_Updates;
29
- #typedef void *Imlib_Font;
30
- #typedef void *Imlib_Color_Range;
31
- #typedef void *Imlib_Filter;
32
- #typedef struct _imlib_border Imlib_Border;
33
- #typedef struct _imlib_color Imlib_Color;
34
- #typedef void *ImlibPolygon;
35
-
36
- extern 'int imlib_get_cache_size()'
37
- extern 'void imlib_set_cache_size(int)'
38
-
39
- extern 'Imlib_Image imlib_load_image(const char *)'
40
- extern 'Imlib_Image imlib_load_image_without_cache(const char *)'
41
- extern 'Imlib_Image imlib_load_image_with_error_return(const char *, Imlib_Load_Error *)'
42
- extern 'Imlib_Image imlib_create_image(int, int)'
43
- extern 'void imlib_context_set_image(Imlib_Image)'
44
- extern 'int imlib_image_get_width()'
45
- extern 'int imlib_image_get_height()'
46
- extern 'void imlib_context_set_anti_alias(char)'
47
-
48
- # source_x, source_y, source_width, source_height, destination_width, destination_height
49
- extern 'Imlib_Image imlib_create_cropped_scaled_image(int, int, int, int, int, int)'
50
- # x, y, width, height
51
- extern 'Imlib_Image imlib_create_cropped_image(int, int, int, int)'
52
-
53
- extern 'char * imlib_image_format()'
54
- extern 'void imlib_image_set_format(const char *)'
55
- extern 'void imlib_save_image(const char *)'
56
- extern 'void imlib_save_image_with_error_return(const char *, Imlib_Load_Error *)'
57
-
58
- extern 'void imlib_free_image()'
59
- extern 'void imlib_free_image_and_decache()'
60
-
61
- def self.delegate(base)
62
- Lib.methods.grep(/\Aimlib_/).each do |method|
63
- line_no = __LINE__; str = %Q{
64
- def #{method}(*args, &block)
65
- Lib.#{method}(*args, &block)
66
- end
67
- }
68
- base.class_eval(str, __FILE__, line_no)
69
- end
70
- end
71
-
72
- end
73
- end
@@ -1,23 +0,0 @@
1
- module Rszr
2
- @mutex = Mutex.new
3
-
4
- class << self
5
-
6
- def with_lock(&block) # :nodoc:
7
- mutex.synchronize(&block)
8
- end
9
-
10
- private
11
-
12
- def mutex
13
- @mutex
14
- end
15
- end
16
-
17
- module Lock # :nodoc:
18
- def with_lock(&block)
19
- Rszr.with_lock(&block)
20
- end
21
- end
22
-
23
- end