magro 0.5.1 → 0.6.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/ext/magro/imgrw.c DELETED
@@ -1,410 +0,0 @@
1
- #include "imgrw.h"
2
-
3
- RUBY_EXTERN VALUE mMagro;
4
-
5
- /**
6
- * @!visibility private
7
- */
8
- static VALUE magro_io_read_png(VALUE self, VALUE filename_) {
9
- char* filename = StringValuePtr(filename_);
10
- FILE* file_ptr = fopen(filename, "rb");
11
- unsigned char header[8];
12
- png_structp png_ptr;
13
- png_infop info_ptr;
14
- png_bytep* row_ptr_ptr;
15
- png_bytep row_ptr;
16
- png_uint_32 width, height;
17
- int color_type;
18
- int bit_depth;
19
- png_uint_32 y;
20
- int n_dims = 0;
21
- int n_ch;
22
- size_t shape[3] = {0};
23
- VALUE nary;
24
- uint8_t* nary_ptr;
25
-
26
- if (file_ptr == NULL) {
27
- rb_raise(rb_eIOError, "Failed to open file '%s'", filename);
28
- return Qnil;
29
- }
30
-
31
- if (fread(header, 1, 8, file_ptr) < 8) {
32
- fclose(file_ptr);
33
- rb_raise(rb_eIOError, "Failed to read header info '%s'", filename);
34
- return Qnil;
35
- }
36
-
37
- if (png_sig_cmp(header, 0, 8)) {
38
- fclose(file_ptr);
39
- rb_raise(rb_eIOError, "Failed to read header info '%s'", filename);
40
- return Qnil;
41
- }
42
-
43
- png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
44
- if (png_ptr == NULL) {
45
- fclose(file_ptr);
46
- rb_raise(rb_eNoMemError, "Failed to allocate memory.");
47
- return Qnil;
48
- }
49
- info_ptr = png_create_info_struct(png_ptr);
50
- if (info_ptr == NULL) {
51
- png_destroy_read_struct(&png_ptr, NULL, NULL);
52
- fclose(file_ptr);
53
- rb_raise(rb_eNoMemError, "Failed to allocate memory.");
54
- return Qnil;
55
- }
56
- if (setjmp(png_jmpbuf(png_ptr))) {
57
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
58
- fclose(file_ptr);
59
- rb_raise(rb_eIOError, "Error happened while reading file '%s'", filename);
60
- return Qnil;
61
- }
62
-
63
- png_init_io(png_ptr, file_ptr);
64
- png_set_sig_bytes(png_ptr, 8);
65
-
66
- png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_STRIP_16, NULL);
67
- row_ptr_ptr = png_get_rows(png_ptr, info_ptr);
68
- png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL);
69
-
70
- if (color_type == PNG_COLOR_TYPE_PALETTE) {
71
- png_set_palette_to_rgb(png_ptr);
72
- png_read_update_info(png_ptr, info_ptr);
73
- png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL);
74
- }
75
-
76
- switch (color_type) {
77
- case PNG_COLOR_TYPE_GRAY:
78
- n_ch = 1;
79
- n_dims = 2;
80
- shape[0] = height;
81
- shape[1] = width;
82
- break;
83
- case PNG_COLOR_TYPE_GRAY_ALPHA:
84
- n_ch = 2;
85
- n_dims = 3;
86
- shape[0] = height;
87
- shape[1] = width;
88
- shape[2] = 2;
89
- break;
90
- case PNG_COLOR_TYPE_RGB:
91
- n_ch = 3;
92
- n_dims = 3;
93
- shape[0] = height;
94
- shape[1] = width;
95
- shape[2] = 3;
96
- break;
97
- case PNG_COLOR_TYPE_RGB_ALPHA:
98
- n_ch = 4;
99
- n_dims = 3;
100
- shape[0] = height;
101
- shape[1] = width;
102
- shape[2] = 4;
103
- break;
104
- default:
105
- n_dims = 0;
106
- break;
107
- }
108
-
109
- if (n_dims == 0) {
110
- fclose(file_ptr);
111
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
112
- rb_raise(rb_eIOError, "Unsupported color type of input file '%s'", filename);
113
- return Qnil;
114
- }
115
-
116
- nary = rb_narray_new(numo_cUInt8, n_dims, shape);
117
- nary_ptr = (uint8_t*)na_get_pointer_for_write(nary);
118
-
119
- for (y = 0; y < height; y++) {
120
- row_ptr = row_ptr_ptr[y];
121
- memcpy(nary_ptr + y * width * n_ch, row_ptr, width * n_ch);
122
- }
123
-
124
- fclose(file_ptr);
125
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
126
-
127
- RB_GC_GUARD(filename_);
128
-
129
- return nary;
130
- }
131
-
132
- /**
133
- * @!visibility private
134
- */
135
- static VALUE magro_io_save_png(VALUE self, VALUE filename_, VALUE image) {
136
- char* filename = StringValuePtr(filename_);
137
- FILE* file_ptr = fopen(filename, "wb");
138
- png_structp png_ptr;
139
- png_infop info_ptr;
140
- png_bytep* row_ptr_ptr;
141
- png_uint_32 width, height;
142
- int color_type;
143
- int bit_depth = 8;
144
- png_uint_32 y;
145
- int n_ch;
146
- int n_dims;
147
- narray_t* image_nary;
148
- uint8_t* image_ptr;
149
-
150
- if (file_ptr == NULL) {
151
- rb_raise(rb_eIOError, "Failed to open file '%s'", filename);
152
- return Qfalse;
153
- }
154
-
155
- if (CLASS_OF(image) != numo_cUInt8) {
156
- image = rb_funcall(numo_cUInt8, rb_intern("cast"), 1, image);
157
- }
158
- if (!RTEST(nary_check_contiguous(image))) {
159
- image = nary_dup(image);
160
- }
161
-
162
- GetNArray(image, image_nary);
163
- n_dims = NA_NDIM(image_nary);
164
- height = (png_uint_32)NA_SHAPE(image_nary)[0];
165
- width = (png_uint_32)NA_SHAPE(image_nary)[1];
166
- image_ptr = (uint8_t*)na_get_pointer_for_read(image);
167
-
168
- n_ch = 1;
169
- if (n_dims == 3) {
170
- n_ch = (int)NA_SHAPE(image_nary)[2];
171
- }
172
-
173
- switch (n_ch) {
174
- case 4:
175
- color_type = PNG_COLOR_TYPE_RGBA;
176
- break;
177
- case 3:
178
- color_type = PNG_COLOR_TYPE_RGB;
179
- break;
180
- case 2:
181
- color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
182
- break;
183
- default:
184
- color_type = PNG_COLOR_TYPE_GRAY;
185
- break;
186
- }
187
-
188
- png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
189
- if (png_ptr == NULL) {
190
- fclose(file_ptr);
191
- rb_raise(rb_eNoMemError, "Failed to allocate memory.");
192
- return Qfalse;
193
- }
194
- info_ptr = png_create_info_struct(png_ptr);
195
- if (info_ptr == NULL) {
196
- png_destroy_read_struct(&png_ptr, NULL, NULL);
197
- fclose(file_ptr);
198
- rb_raise(rb_eNoMemError, "Failed to allocate memory.");
199
- return Qfalse;
200
- }
201
- if (setjmp(png_jmpbuf(png_ptr))) {
202
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
203
- fclose(file_ptr);
204
- return Qfalse;
205
- }
206
-
207
- png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
208
- PNG_FILTER_TYPE_DEFAULT);
209
-
210
- row_ptr_ptr = png_malloc(png_ptr, height * sizeof(png_bytep));
211
- for (y = 0; y < height; y++) {
212
- row_ptr_ptr[y] = png_malloc(png_ptr, width * n_ch * sizeof(png_byte));
213
- memcpy(row_ptr_ptr[y], image_ptr + y * width * n_ch, width * n_ch);
214
- }
215
-
216
- png_init_io(png_ptr, file_ptr);
217
- png_set_rows(png_ptr, info_ptr, row_ptr_ptr);
218
- png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
219
-
220
- fclose(file_ptr);
221
- for (y = 0; y < height; y++) {
222
- png_free(png_ptr, row_ptr_ptr[y]);
223
- }
224
- png_free(png_ptr, row_ptr_ptr);
225
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
226
-
227
- RB_GC_GUARD(image);
228
- RB_GC_GUARD(filename_);
229
-
230
- return Qtrue;
231
- }
232
-
233
- struct my_error_mgr {
234
- struct jpeg_error_mgr pub;
235
- jmp_buf setjmp_buffer;
236
- };
237
-
238
- static void my_error_exit(j_common_ptr cinfo) {
239
- struct my_error_mgr* my_err = (struct my_error_mgr*)cinfo->err;
240
- (*cinfo->err->output_message)(cinfo);
241
- longjmp(my_err->setjmp_buffer, 1);
242
- }
243
-
244
- /**
245
- * @!visibility private
246
- */
247
- static VALUE magro_io_read_jpg(VALUE self, VALUE filename_) {
248
- char* filename = StringValuePtr(filename_);
249
- FILE* file_ptr = fopen(filename, "rb");
250
- struct jpeg_decompress_struct jpeg;
251
- struct my_error_mgr err;
252
- unsigned int width, height;
253
- int n_colors;
254
- size_t shape[3] = {0};
255
- int n_dims;
256
- unsigned int y;
257
- VALUE nary;
258
- uint8_t* nary_ptr;
259
- JSAMPLE* tmp;
260
-
261
- if (file_ptr == NULL) {
262
- rb_raise(rb_eIOError, "Failed to open file '%s'", filename);
263
- return Qnil;
264
- }
265
-
266
- jpeg.err = jpeg_std_error(&err.pub);
267
- err.pub.error_exit = my_error_exit;
268
- if (setjmp(err.setjmp_buffer)) {
269
- rb_raise(rb_eIOError, "Error happened while reading file '%s'", filename);
270
- return Qnil;
271
- }
272
-
273
- jpeg_create_decompress(&jpeg);
274
- jpeg_stdio_src(&jpeg, file_ptr);
275
- jpeg_read_header(&jpeg, TRUE);
276
- jpeg_start_decompress(&jpeg);
277
-
278
- width = jpeg.output_width;
279
- height = jpeg.output_height;
280
- n_colors = jpeg.out_color_components;
281
-
282
- n_dims = n_colors == 1 ? 2 : 3;
283
- shape[0] = height;
284
- shape[1] = width;
285
- shape[2] = n_colors;
286
- nary = rb_narray_new(numo_cUInt8, n_dims, shape);
287
- nary_ptr = (uint8_t*)na_get_pointer_for_write(nary);
288
-
289
- for (y = 0; y < height; y++) {
290
- tmp = nary_ptr + y * width * n_colors;
291
- jpeg_read_scanlines(&jpeg, &tmp, 1);
292
- }
293
-
294
- fclose(file_ptr);
295
- jpeg_finish_decompress(&jpeg);
296
- jpeg_destroy_decompress(&jpeg);
297
-
298
- RB_GC_GUARD(filename_);
299
-
300
- return nary;
301
- }
302
-
303
- /**
304
- * @!visibility private
305
- */
306
- static VALUE magro_io_save_jpg(int argc, VALUE* argv, VALUE self) {
307
- VALUE filename_;
308
- VALUE image;
309
- VALUE quality_;
310
- char* filename;
311
- FILE* file_ptr;
312
- struct jpeg_compress_struct jpeg;
313
- struct my_error_mgr err;
314
- narray_t* image_nary;
315
- int quality;
316
- int n_dims, n_ch;
317
- unsigned int width, height, y;
318
- uint8_t* image_ptr;
319
- JSAMPLE* tmp;
320
-
321
- rb_scan_args(argc, argv, "21", &filename_, &image, &quality_);
322
-
323
- if (NIL_P(quality_)) {
324
- quality = 95;
325
- } else {
326
- quality = NUM2INT(quality_);
327
- }
328
-
329
- filename = StringValuePtr(filename_);
330
-
331
- if (CLASS_OF(image) != numo_cUInt8) {
332
- image = rb_funcall(numo_cUInt8, rb_intern("cast"), 1, image);
333
- }
334
- if (!RTEST(nary_check_contiguous(image))) {
335
- image = nary_dup(image);
336
- }
337
-
338
- jpeg.err = jpeg_std_error(&err.pub);
339
- err.pub.error_exit = my_error_exit;
340
- if (setjmp(err.setjmp_buffer)) {
341
- return Qfalse;
342
- }
343
-
344
- jpeg_create_compress(&jpeg);
345
-
346
- file_ptr = fopen(filename, "wb");
347
- if (file_ptr == NULL) {
348
- rb_raise(rb_eIOError, "Failed to open file '%s'", filename);
349
- jpeg_destroy_compress(&jpeg);
350
- return Qfalse;
351
- }
352
-
353
- GetNArray(image, image_nary);
354
- n_dims = NA_NDIM(image_nary);
355
- height = (unsigned int)NA_SHAPE(image_nary)[0];
356
- width = (unsigned int)NA_SHAPE(image_nary)[1];
357
- image_ptr = (uint8_t*)na_get_pointer_for_read(image);
358
-
359
- n_ch = 1;
360
- if (n_dims == 3) {
361
- n_ch = (int)NA_SHAPE(image_nary)[2];
362
- }
363
-
364
- jpeg_stdio_dest(&jpeg, file_ptr);
365
-
366
- jpeg.image_height = height;
367
- jpeg.image_width = width;
368
- jpeg.input_components = n_ch;
369
-
370
- switch (n_ch) {
371
- case 3:
372
- jpeg.in_color_space = JCS_RGB;
373
- break;
374
- case 1:
375
- jpeg.in_color_space = JCS_GRAYSCALE;
376
- break;
377
- default:
378
- jpeg.in_color_space = JCS_UNKNOWN;
379
- break;
380
- }
381
-
382
- jpeg_set_defaults(&jpeg);
383
-
384
- jpeg_set_quality(&jpeg, quality, TRUE);
385
-
386
- jpeg_start_compress(&jpeg, TRUE);
387
-
388
- for (y = 0; y < height; y++) {
389
- tmp = image_ptr + y * width * n_ch;
390
- jpeg_write_scanlines(&jpeg, &tmp, 1);
391
- }
392
-
393
- jpeg_finish_compress(&jpeg);
394
- jpeg_destroy_compress(&jpeg);
395
-
396
- fclose(file_ptr);
397
-
398
- RB_GC_GUARD(image);
399
- RB_GC_GUARD(filename_);
400
-
401
- return Qtrue;
402
- }
403
-
404
- void init_io_module() {
405
- VALUE mIO = rb_define_module_under(mMagro, "IO");
406
- rb_define_module_function(mIO, "read_png", magro_io_read_png, 1);
407
- rb_define_module_function(mIO, "save_png", magro_io_save_png, 2);
408
- rb_define_module_function(mIO, "read_jpg", magro_io_read_jpg, 1);
409
- rb_define_module_function(mIO, "save_jpg", magro_io_save_jpg, -1);
410
- }
data/ext/magro/imgrw.h DELETED
@@ -1,20 +0,0 @@
1
- #ifndef MAGRO_IO_H
2
- #define MAGRO_IO_H 1
3
-
4
- #include <stdio.h>
5
- #include <stdlib.h>
6
- #include <string.h>
7
-
8
- #include <setjmp.h>
9
-
10
- #include <jpeglib.h>
11
- #include <png.h>
12
-
13
- #include <ruby.h>
14
-
15
- #include <numo/narray.h>
16
- #include <numo/template.h>
17
-
18
- void init_io_module();
19
-
20
- #endif /* MAGRO_IO_H */
data/magro.gemspec DELETED
@@ -1,39 +0,0 @@
1
- lib = File.expand_path('lib', __dir__)
2
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require 'magro/version'
4
-
5
- Gem::Specification.new do |spec|
6
- spec.name = 'magro'
7
- spec.version = Magro::VERSION
8
- spec.authors = ['yoshoku']
9
- spec.email = ['yoshoku@outlook.com']
10
-
11
- spec.summary = 'Magro is a minimal image processing library for Ruby.'
12
- spec.description = <<~MSG
13
- Magro is a minimal image processing library for Ruby.
14
- Magro uses Numo::NArray arrays as image objects and provides basic image processing functions.
15
- Current supporting features are reading and writing JPEG and PNG images,
16
- image resizing with bilinear interpolation method, and image filtering.
17
- MSG
18
-
19
- spec.homepage = 'https://github.com/yoshoku/magro'
20
- spec.license = 'BSD-3-Clause'
21
-
22
- spec.metadata['homepage_uri'] = spec.homepage
23
- spec.metadata['source_code_uri'] = 'https://github.com/yoshoku/magro'
24
- spec.metadata['changelog_uri'] = 'https://github.com/yoshoku/magro/blob/main/CHANGELOG.md'
25
- spec.metadata['documentation_uri'] = 'https://yoshoku.github.io/magro/doc/'
26
-
27
- # Specify which files should be added to the gem when it is released.
28
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
29
- spec.files = Dir.chdir(File.expand_path(__dir__)) do
30
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
31
- end
32
-
33
- spec.bindir = 'exe'
34
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
35
- spec.require_paths = ['lib']
36
- spec.extensions = ['ext/magro/extconf.rb']
37
-
38
- spec.add_runtime_dependency 'numo-narray', '>= 0.9.1'
39
- end
data/sig/patch.rbs DELETED
@@ -1,90 +0,0 @@
1
- module Numo
2
- class NArray
3
- def self.cast: (untyped a) -> untyped
4
- def self.zeros: (*Integer) -> untyped
5
- def self.[]: (*untyped) -> untyped
6
- def []: () -> untyped
7
- def []=: () -> untyped
8
- def +: (untyped) -> untyped
9
- def empty?: () -> bool
10
- def flatten: () -> untyped
11
- def initialize: (*untyped) -> untyped
12
- def ndim: () -> Integer
13
- def shape: () -> [Integer, Integer]
14
- def swapaxes: (Integer, Integer) -> untyped
15
- def transpose: (*untyped) -> untyped
16
- end
17
-
18
- class Int8 < NArray
19
- def *: (untyped) -> untyped
20
- def +: (untyped) -> untyped
21
- def []: (*untyped) -> untyped
22
- def []=: (*untyped) -> untyped
23
- end
24
-
25
- class Int16 < NArray
26
- def *: (untyped) -> untyped
27
- def +: (untyped) -> untyped
28
- def []: (*untyped) -> untyped
29
- def []=: (*untyped) -> untyped
30
- end
31
-
32
- class Int32 < NArray
33
- def *: (untyped) -> untyped
34
- def +: (untyped) -> untyped
35
- def []: (*untyped) -> untyped
36
- def []=: (*untyped) -> untyped
37
- def seq: (*untyped) -> untyped
38
- end
39
-
40
- class Int64 < NArray
41
- def *: (untyped) -> untyped
42
- def +: (untyped) -> untyped
43
- def []: (*untyped) -> untyped
44
- def []=: (*untyped) -> untyped
45
- end
46
-
47
- class UInt8 < NArray
48
- def *: (untyped) -> untyped
49
- def +: (untyped) -> untyped
50
- def []: (*untyped) -> untyped
51
- def []=: (*untyped) -> untyped
52
- end
53
-
54
- class UInt16 < NArray
55
- def *: (untyped) -> untyped
56
- def +: (untyped) -> untyped
57
- def []: (*untyped) -> untyped
58
- def []=: (*untyped) -> untyped
59
- end
60
-
61
- class UInt32 < NArray
62
- def *: (untyped) -> untyped
63
- def +: (untyped) -> untyped
64
- def []: (*untyped) -> untyped
65
- def []=: (*untyped) -> untyped
66
- end
67
-
68
- class UInt64 < NArray
69
- def *: (untyped) -> untyped
70
- def +: (untyped) -> untyped
71
- def []: (*untyped) -> untyped
72
- def []=: (*untyped) -> untyped
73
- end
74
-
75
- class SFloat < NArray
76
- def sum: (*untyped) -> untyped
77
- def *: (untyped) -> untyped
78
- def +: (untyped) -> untyped
79
- def []: (*untyped) -> untyped
80
- def []=: (*untyped) -> untyped
81
- end
82
-
83
- class DFloat < NArray
84
- def sum: (*untyped) -> untyped
85
- def *: (untyped) -> untyped
86
- def +: (untyped) -> untyped
87
- def []: (*untyped) -> untyped
88
- def []=: (*untyped) -> untyped
89
- end
90
- end