rfreeimage 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|