rfreeimage 0.1.0 → 0.1.1
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.
- checksums.yaml +4 -4
- data/ext/rfreeimage/rfi_main.c +206 -48
- data/lib/rfreeimage/image.rb +24 -1
- data/lib/rfreeimage/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d8d7e7bca8f13f158da2617a15667627c8a0c31a
|
4
|
+
data.tar.gz: 638dacb99a69891c7cbd5112e31a4c9b13e28680
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af82826b1c9556159e616dca72a0e639dd7897b8aa9e00934cd2ffb62e24710b9f2956afae22ecb862f63548bb2b48754e760dda623b07e7fe4b4079cb0884e5
|
7
|
+
data.tar.gz: cdab92f66f9dcb575d3d429e63e3eaef0b8c5770ae703ddab435a244a4972d19bd496662de6a7483beaaf9efcff0948baaaf695018df1c5dfd5c41f611cc5d70
|
data/ext/rfreeimage/rfi_main.c
CHANGED
@@ -6,6 +6,16 @@ static VALUE rb_mFI;
|
|
6
6
|
static VALUE Class_Image;
|
7
7
|
static VALUE Class_RFIError;
|
8
8
|
|
9
|
+
__attribute__((constructor))
|
10
|
+
static void __rfi_module_init() {
|
11
|
+
FreeImage_Initialise(FALSE);
|
12
|
+
}
|
13
|
+
|
14
|
+
__attribute__((destructor))
|
15
|
+
static void __rfi_module_uninit() {
|
16
|
+
FreeImage_DeInitialise();
|
17
|
+
}
|
18
|
+
|
9
19
|
static VALUE rb_rfi_version(VALUE self)
|
10
20
|
{
|
11
21
|
return rb_ary_new3(3, INT2NUM(FREEIMAGE_MAJOR_VERSION),
|
@@ -20,14 +30,6 @@ static VALUE rb_rfi_string_version(VALUE self)
|
|
20
30
|
return result;
|
21
31
|
}
|
22
32
|
|
23
|
-
static VALUE
|
24
|
-
file_arg_rescue(VALUE arg)
|
25
|
-
{
|
26
|
-
rb_raise(rb_eTypeError, "argument must be path name or open file (%s given)",
|
27
|
-
rb_class2name(CLASS_OF(arg)));
|
28
|
-
return(VALUE)0;
|
29
|
-
}
|
30
|
-
|
31
33
|
struct native_image {
|
32
34
|
int w;
|
33
35
|
int h;
|
@@ -60,6 +62,7 @@ static inline char *rfi_value_to_str(VALUE v)
|
|
60
62
|
{
|
61
63
|
char *filename;
|
62
64
|
long f_len;
|
65
|
+
Check_Type(v, T_STRING);
|
63
66
|
f_len = RSTRING_LEN(v);
|
64
67
|
filename = malloc(f_len + 1);
|
65
68
|
memcpy(filename, RSTRING_PTR(v), f_len);
|
@@ -67,14 +70,28 @@ static inline char *rfi_value_to_str(VALUE v)
|
|
67
70
|
return filename;
|
68
71
|
}
|
69
72
|
|
73
|
+
static FIBITMAP *
|
74
|
+
convert_bpp(FIBITMAP *orig, unsigned int bpp) {
|
75
|
+
FIBITMAP *h = NULL;
|
76
|
+
switch(bpp) {
|
77
|
+
case 8:
|
78
|
+
h = FreeImage_ConvertToGreyscale(orig);
|
79
|
+
break;
|
80
|
+
case 32:
|
81
|
+
h = FreeImage_ConvertTo32Bits(orig);
|
82
|
+
break;
|
83
|
+
}
|
84
|
+
return h;
|
85
|
+
}
|
86
|
+
|
70
87
|
static void
|
71
88
|
rd_image(VALUE clazz, VALUE file, struct native_image *img, unsigned int bpp, BOOL ping)
|
72
89
|
{
|
73
90
|
char *filename;
|
91
|
+
int flags = 0;
|
74
92
|
FIBITMAP *h = NULL, *orig = NULL;
|
75
93
|
FREE_IMAGE_FORMAT in_fif;
|
76
94
|
|
77
|
-
file = rb_rescue(rb_String, file, file_arg_rescue, file);
|
78
95
|
filename = rfi_value_to_str(file);
|
79
96
|
|
80
97
|
in_fif = FreeImage_GetFileType(filename, 0);
|
@@ -83,33 +100,62 @@ rd_image(VALUE clazz, VALUE file, struct native_image *img, unsigned int bpp, BO
|
|
83
100
|
rb_raise(rb_eIOError, "Invalid image file");
|
84
101
|
}
|
85
102
|
|
86
|
-
|
103
|
+
if (ping) flags |= FIF_LOAD_NOPIXELS;
|
104
|
+
if (in_fif == FIF_JPEG) flags |= JPEG_EXIFROTATE;
|
105
|
+
orig = FreeImage_Load(in_fif, filename, flags);
|
87
106
|
free(filename);
|
88
107
|
if (!orig)
|
89
108
|
rb_raise(rb_eIOError, "Fail to load image file");
|
90
|
-
if (
|
109
|
+
if (ping) {
|
91
110
|
h = orig;
|
92
111
|
} else {
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
112
|
+
if (bpp <= 0) bpp = 32;
|
113
|
+
h = convert_bpp(orig, bpp);
|
114
|
+
FreeImage_Unload(orig);
|
115
|
+
if (!h) rb_raise(rb_eArgError, "Invalid bpp");
|
116
|
+
}
|
117
|
+
img->handle = h;
|
118
|
+
img->w = FreeImage_GetWidth(h);
|
119
|
+
img->h = FreeImage_GetHeight(h);
|
120
|
+
img->bpp = FreeImage_GetBPP(h);
|
121
|
+
img->stride = FreeImage_GetPitch(h);
|
122
|
+
img->fif = in_fif;
|
123
|
+
}
|
124
|
+
|
125
|
+
static void
|
126
|
+
rd_image_blob(VALUE clazz, VALUE blob, struct native_image *img, unsigned int bpp, BOOL ping)
|
127
|
+
{
|
128
|
+
FIBITMAP *h = NULL, *orig = NULL;
|
129
|
+
FIMEMORY *fmh;
|
130
|
+
FREE_IMAGE_FORMAT in_fif;
|
131
|
+
|
132
|
+
Check_Type(blob, T_STRING);
|
133
|
+
fmh = FreeImage_OpenMemory((BYTE*)RSTRING_PTR(blob), RSTRING_LEN(blob));
|
134
|
+
|
135
|
+
in_fif = FreeImage_GetFileTypeFromMemory(fmh, 0);
|
136
|
+
if (in_fif == FIF_UNKNOWN) {
|
137
|
+
FreeImage_CloseMemory(fmh);
|
138
|
+
rb_raise(rb_eIOError, "Invalid image blob");
|
139
|
+
}
|
140
|
+
|
141
|
+
orig = FreeImage_LoadFromMemory(in_fif, fmh, ping ? FIF_LOAD_NOPIXELS : 0 );
|
142
|
+
FreeImage_CloseMemory(fmh);
|
143
|
+
if (!orig)
|
144
|
+
rb_raise(rb_eIOError, "Fail to load image from memory");
|
145
|
+
|
146
|
+
if (ping) {
|
147
|
+
h = orig;
|
148
|
+
} else {
|
149
|
+
if (bpp <= 0) bpp = 32;
|
150
|
+
h = convert_bpp(orig, bpp);
|
106
151
|
FreeImage_Unload(orig);
|
152
|
+
if (!h) rb_raise(rb_eArgError, "Invalid bpp");
|
107
153
|
}
|
108
154
|
img->handle = h;
|
109
155
|
img->w = FreeImage_GetWidth(h);
|
110
156
|
img->h = FreeImage_GetHeight(h);
|
111
157
|
img->bpp = FreeImage_GetBPP(h);
|
112
|
-
img->stride =
|
158
|
+
img->stride = FreeImage_GetPitch(h);
|
113
159
|
img->fif = in_fif;
|
114
160
|
}
|
115
161
|
|
@@ -119,7 +165,6 @@ VALUE Image_initialize(int argc, VALUE *argv, VALUE self)
|
|
119
165
|
/* unwrap */
|
120
166
|
Data_Get_Struct(self, struct native_image, img);
|
121
167
|
|
122
|
-
memset(img, 0, sizeof(struct native_image));
|
123
168
|
switch (argc)
|
124
169
|
{
|
125
170
|
case 1:
|
@@ -149,7 +194,7 @@ VALUE Image_save(VALUE self, VALUE file)
|
|
149
194
|
Data_Get_Struct(self, struct native_image, img);
|
150
195
|
RFI_CHECK_IMG(img);
|
151
196
|
|
152
|
-
|
197
|
+
Check_Type(file, T_STRING);
|
153
198
|
filename = rfi_value_to_str(file);
|
154
199
|
|
155
200
|
out_fif = FreeImage_GetFIFFromFilename(filename);
|
@@ -158,7 +203,14 @@ VALUE Image_save(VALUE self, VALUE file)
|
|
158
203
|
rb_raise(Class_RFIError, "Invalid format");
|
159
204
|
}
|
160
205
|
|
161
|
-
|
206
|
+
if (out_fif == FIF_JPEG && img->bpp != 8 && img->bpp != 24) {
|
207
|
+
FIBITMAP *to_save = FreeImage_ConvertTo24Bits(img->handle);
|
208
|
+
result = FreeImage_Save(out_fif, to_save, filename, JPEG_BASELINE);
|
209
|
+
FreeImage_Unload(to_save);
|
210
|
+
} else {
|
211
|
+
result = FreeImage_Save(out_fif, img->handle, filename, 0);
|
212
|
+
}
|
213
|
+
|
162
214
|
free(filename);
|
163
215
|
|
164
216
|
if(!result)
|
@@ -219,11 +271,25 @@ VALUE Image_read_bytes(VALUE self)
|
|
219
271
|
{
|
220
272
|
struct native_image* img;
|
221
273
|
const char *p;
|
274
|
+
char *ptr;
|
275
|
+
unsigned stride_dst;
|
276
|
+
int i;
|
277
|
+
VALUE v;
|
222
278
|
|
223
279
|
Data_Get_Struct(self, struct native_image, img);
|
224
280
|
RFI_CHECK_IMG(img);
|
225
281
|
p = (const char*)FreeImage_GetBits(img->handle);
|
226
|
-
|
282
|
+
stride_dst = img->w * (img->bpp / 8);
|
283
|
+
v = rb_str_new(NULL, stride_dst * img->h);
|
284
|
+
|
285
|
+
/* up-side-down */
|
286
|
+
ptr = RSTRING_PTR(v) + img->h * stride_dst;
|
287
|
+
for(i = 0; i < img->h; i++) {
|
288
|
+
ptr -= stride_dst;
|
289
|
+
memcpy(ptr, p, stride_dst);
|
290
|
+
p += img->stride;
|
291
|
+
}
|
292
|
+
return v;
|
227
293
|
}
|
228
294
|
|
229
295
|
VALUE Image_buffer_addr(VALUE self)
|
@@ -251,7 +317,7 @@ static inline VALUE rfi_get_image(FIBITMAP *nh)
|
|
251
317
|
new_img = malloc(sizeof(struct native_image));
|
252
318
|
memset(new_img, 0, sizeof(struct native_image));
|
253
319
|
new_img->handle = nh;
|
254
|
-
new_img->stride =
|
320
|
+
new_img->stride = FreeImage_GetPitch(nh);
|
255
321
|
new_img->bpp = FreeImage_GetBPP(nh);
|
256
322
|
new_img->w = FreeImage_GetWidth(nh);
|
257
323
|
new_img->h = FreeImage_GetHeight(nh);
|
@@ -266,20 +332,12 @@ VALUE Image_to_bpp(VALUE self, VALUE _bpp)
|
|
266
332
|
int bpp = NUM2INT(_bpp);
|
267
333
|
Data_Get_Struct(self, struct native_image, img);
|
268
334
|
RFI_CHECK_IMG(img);
|
335
|
+
if (bpp == img->bpp)
|
336
|
+
return self;
|
337
|
+
|
338
|
+
nh = convert_bpp(img->handle, bpp);
|
339
|
+
if (!nh) rb_raise(rb_eArgError, "Invalid bpp");
|
269
340
|
|
270
|
-
switch(bpp) {
|
271
|
-
case 8:
|
272
|
-
nh = FreeImage_ConvertTo8Bits(img->handle);
|
273
|
-
break;
|
274
|
-
case 24:
|
275
|
-
nh = FreeImage_ConvertTo24Bits(img->handle);
|
276
|
-
break;
|
277
|
-
case 32:
|
278
|
-
nh = FreeImage_ConvertTo32Bits(img->handle);
|
279
|
-
break;
|
280
|
-
default:
|
281
|
-
rb_raise(rb_eArgError, "Invalid bpp");
|
282
|
-
}
|
283
341
|
return rfi_get_image(nh);
|
284
342
|
}
|
285
343
|
|
@@ -342,18 +400,115 @@ VALUE Image_crop(VALUE self, VALUE _left, VALUE _top, VALUE _right, VALUE _botto
|
|
342
400
|
return rfi_get_image(nh);
|
343
401
|
}
|
344
402
|
|
403
|
+
#define ALLOC_NEW_IMAGE(__v, img) \
|
404
|
+
VALUE __v = Image_alloc(Class_Image); \
|
405
|
+
struct native_image* img; \
|
406
|
+
Data_Get_Struct(__v, struct native_image, img) \
|
407
|
+
|
345
408
|
VALUE Image_ping(VALUE self, VALUE file)
|
346
409
|
{
|
347
|
-
|
410
|
+
ALLOC_NEW_IMAGE(v, img);
|
411
|
+
|
348
412
|
rd_image(self, file, img, 0, 1);
|
413
|
+
if (img->handle)
|
414
|
+
FreeImage_Unload(img->handle);
|
415
|
+
img->handle = NULL;
|
416
|
+
|
417
|
+
return v;
|
418
|
+
}
|
419
|
+
|
420
|
+
VALUE Image_from_blob(int argc, VALUE *argv, VALUE self)
|
421
|
+
{
|
422
|
+
ALLOC_NEW_IMAGE(v, img);
|
349
423
|
|
424
|
+
switch (argc)
|
425
|
+
{
|
426
|
+
case 1:
|
427
|
+
rd_image_blob(self, argv[0], img, 0, 0);
|
428
|
+
break;
|
429
|
+
case 2:
|
430
|
+
rd_image_blob(self, argv[0], img, NUM2INT(argv[1]), 0);
|
431
|
+
break;
|
432
|
+
default:
|
433
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
|
434
|
+
break;
|
435
|
+
}
|
436
|
+
|
437
|
+
return v;
|
438
|
+
}
|
439
|
+
|
440
|
+
VALUE Image_ping_blob(VALUE self, VALUE blob)
|
441
|
+
{
|
442
|
+
ALLOC_NEW_IMAGE(v, img);
|
443
|
+
|
444
|
+
rd_image_blob(self, blob, img, 0, 1);
|
350
445
|
if (img->handle)
|
351
446
|
FreeImage_Unload(img->handle);
|
352
447
|
img->handle = NULL;
|
353
448
|
|
354
|
-
return
|
449
|
+
return v;
|
450
|
+
}
|
451
|
+
|
452
|
+
/* draw */
|
453
|
+
VALUE Image_draw_point(VALUE self, VALUE _x, VALUE _y, VALUE color, VALUE _size)
|
454
|
+
{
|
455
|
+
struct native_image* img;
|
456
|
+
int x = NUM2INT(_x);
|
457
|
+
int y = NUM2INT(_y);
|
458
|
+
int size = NUM2INT(_size);
|
459
|
+
int hs = size / 2, i, j;
|
460
|
+
unsigned int bgra = NUM2UINT(color);
|
461
|
+
if (size < 0)
|
462
|
+
rb_raise(rb_eArgError, "Invalid point size: %d", size);
|
463
|
+
Data_Get_Struct(self, struct native_image, img);
|
464
|
+
RFI_CHECK_IMG(img);
|
465
|
+
|
466
|
+
for(i = -hs; i <= hs; i++) {
|
467
|
+
for(j = -hs; j <= hs; j++) {
|
468
|
+
if (i*i + j*j <= hs*hs)
|
469
|
+
FreeImage_SetPixelColor(img->handle, x + i, img->h - (y + j) - 1, (RGBQUAD*)&bgra);
|
470
|
+
}
|
471
|
+
}
|
472
|
+
|
473
|
+
return self;
|
355
474
|
}
|
356
475
|
|
476
|
+
VALUE Image_draw_rectangle(VALUE self, VALUE _x1, VALUE _y1,
|
477
|
+
VALUE _x2, VALUE _y2,
|
478
|
+
VALUE color, VALUE _width)
|
479
|
+
{
|
480
|
+
struct native_image* img;
|
481
|
+
int x1 = NUM2INT(_x1);
|
482
|
+
int y1 = NUM2INT(_y1);
|
483
|
+
int x2 = NUM2INT(_x2);
|
484
|
+
int y2 = NUM2INT(_y2);
|
485
|
+
int size = NUM2INT(_width);
|
486
|
+
int hs = size / 2, i, j;
|
487
|
+
unsigned int bgra = NUM2UINT(color);
|
488
|
+
if (size < 0)
|
489
|
+
rb_raise(rb_eArgError, "Invalid line width: %d", size);
|
490
|
+
Data_Get_Struct(self, struct native_image, img);
|
491
|
+
RFI_CHECK_IMG(img);
|
492
|
+
|
493
|
+
for(i = -hs; i <= hs; i++) {
|
494
|
+
for(j = x1; j <= x2; j++) {
|
495
|
+
FreeImage_SetPixelColor(img->handle, j, img->h - (y1 + i) - 1, (RGBQUAD*)&bgra);
|
496
|
+
FreeImage_SetPixelColor(img->handle, j, img->h - (y2 + i) - 1, (RGBQUAD*)&bgra);
|
497
|
+
}
|
498
|
+
}
|
499
|
+
|
500
|
+
for(i = -hs; i <= hs; i++) {
|
501
|
+
for(j = y1; j <= y2; j++) {
|
502
|
+
FreeImage_SetPixelColor(img->handle, x1 + i, img->h - j - 1, (RGBQUAD*)&bgra);
|
503
|
+
FreeImage_SetPixelColor(img->handle, x2 + i, img->h - j - 1, (RGBQUAD*)&bgra);
|
504
|
+
}
|
505
|
+
}
|
506
|
+
|
507
|
+
return self;
|
508
|
+
}
|
509
|
+
|
510
|
+
|
511
|
+
|
357
512
|
void Init_rfreeimage(void)
|
358
513
|
{
|
359
514
|
rb_mFI = rb_define_module("RFreeImage");
|
@@ -382,8 +537,11 @@ void Init_rfreeimage(void)
|
|
382
537
|
rb_define_method(Class_Image, "resize", Image_resize, 2);
|
383
538
|
rb_define_method(Class_Image, "crop", Image_crop, 4);
|
384
539
|
|
385
|
-
|
540
|
+
/* draw */
|
541
|
+
rb_define_method(Class_Image, "draw_point", Image_draw_point, 4);
|
542
|
+
rb_define_method(Class_Image, "draw_rectangle", Image_draw_rectangle, 4 + 2);
|
386
543
|
|
544
|
+
rb_define_singleton_method(Class_Image, "ping", Image_ping, 1);
|
545
|
+
rb_define_singleton_method(Class_Image, "from_blob", Image_from_blob, -1);
|
546
|
+
rb_define_singleton_method(Class_Image, "ping_blob", Image_ping_blob, 1);
|
387
547
|
}
|
388
|
-
|
389
|
-
|
data/lib/rfreeimage/image.rb
CHANGED
@@ -4,6 +4,16 @@ module RFreeImage
|
|
4
4
|
BGR = 24
|
5
5
|
BGRA = 32
|
6
6
|
end
|
7
|
+
module Color
|
8
|
+
BLUE = 0xff0000ff
|
9
|
+
GREEN = 0xff00ff00
|
10
|
+
RED = 0xffff0000
|
11
|
+
YELLOW = 0xffffff00
|
12
|
+
CYAN = 0xff00ffff
|
13
|
+
WHITE = 0xffffffff
|
14
|
+
BLACK = 0xff000000
|
15
|
+
GRAY = 0xffa9a9a9
|
16
|
+
end
|
7
17
|
class Image
|
8
18
|
def bytes
|
9
19
|
@bytes ||= read_bytes
|
@@ -15,12 +25,25 @@ module RFreeImage
|
|
15
25
|
end
|
16
26
|
|
17
27
|
def gray?
|
18
|
-
bpp == GRAY
|
28
|
+
bpp == ImageBPP::GRAY
|
19
29
|
end
|
20
30
|
|
21
31
|
def to_gray
|
22
32
|
return self if gray?
|
23
33
|
to_bpp 8
|
24
34
|
end
|
35
|
+
|
36
|
+
def bgra?
|
37
|
+
bpp == ImageBPP::BGRA
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_bgra
|
41
|
+
return self if bgra?
|
42
|
+
to_bpp 32
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
alias_method :write, :save
|
47
|
+
alias_method :columns, :cols
|
25
48
|
end
|
26
49
|
end
|
data/lib/rfreeimage/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rfreeimage
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yuheng Chen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-04-
|
11
|
+
date: 2015-04-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|