ruby-epeg 0.1.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.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.travis.yml +14 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +56 -0
- data/Rakefile +11 -0
- data/epeg.gemspec +26 -0
- data/ext/epeg/EPEG_LICENSE +7 -0
- data/ext/epeg/Epeg.h +76 -0
- data/ext/epeg/epeg_image.c +414 -0
- data/ext/epeg/epeg_image.h +24 -0
- data/ext/epeg/epeg_main.c +1418 -0
- data/ext/epeg/epeg_private.h +86 -0
- data/ext/epeg/extconf.rb +12 -0
- data/lib/epeg/epeg.rb +7 -0
- data/lib/epeg/version.rb +3 -0
- data/spec/epeg_image_spec.rb +126 -0
- data/spec/fixtures/test.jpg +0 -0
- data/spec/spec_helper.rb +6 -0
- metadata +113 -0
@@ -0,0 +1,86 @@
|
|
1
|
+
#ifndef _EPEG_PRIVATE_H
|
2
|
+
#define _EPEG_PRIVATE_H
|
3
|
+
|
4
|
+
#include <stdio.h>
|
5
|
+
#include <unistd.h>
|
6
|
+
#include <stdlib.h>
|
7
|
+
#include <string.h>
|
8
|
+
#include <limits.h>
|
9
|
+
#include <time.h>
|
10
|
+
#include <fcntl.h>
|
11
|
+
#include <sys/types.h>
|
12
|
+
#include <sys/stat.h>
|
13
|
+
#include <setjmp.h>
|
14
|
+
#include <jpeglib.h>
|
15
|
+
#include <libexif/exif-data.h>
|
16
|
+
|
17
|
+
typedef struct _epeg_error_mgr *emptr;
|
18
|
+
|
19
|
+
struct _epeg_error_mgr
|
20
|
+
{
|
21
|
+
struct jpeg_error_mgr pub;
|
22
|
+
jmp_buf setjmp_buffer;
|
23
|
+
};
|
24
|
+
|
25
|
+
struct _Epeg_Image
|
26
|
+
{
|
27
|
+
struct _epeg_error_mgr jerr;
|
28
|
+
struct stat stat_info;
|
29
|
+
unsigned char *pixels;
|
30
|
+
unsigned char **lines;
|
31
|
+
|
32
|
+
char scaled : 1;
|
33
|
+
|
34
|
+
int error;
|
35
|
+
|
36
|
+
Epeg_Colorspace color_space;
|
37
|
+
|
38
|
+
struct {
|
39
|
+
char *file;
|
40
|
+
struct {
|
41
|
+
unsigned char **data;
|
42
|
+
int size;
|
43
|
+
} mem;
|
44
|
+
int w, h;
|
45
|
+
char *comment;
|
46
|
+
FILE *f;
|
47
|
+
J_COLOR_SPACE color_space;
|
48
|
+
int orientation; /* Exif orientation values 0-8 */
|
49
|
+
struct jpeg_decompress_struct jinfo;
|
50
|
+
struct {
|
51
|
+
char *uri;
|
52
|
+
unsigned long long int mtime;
|
53
|
+
int w, h;
|
54
|
+
char *mime;
|
55
|
+
} thumb_info;
|
56
|
+
} in;
|
57
|
+
struct {
|
58
|
+
char *file;
|
59
|
+
struct {
|
60
|
+
unsigned char **data;
|
61
|
+
int *size;
|
62
|
+
} mem;
|
63
|
+
int x, y;
|
64
|
+
int w, h;
|
65
|
+
char *comment;
|
66
|
+
FILE *f;
|
67
|
+
struct jpeg_compress_struct jinfo;
|
68
|
+
int quality;
|
69
|
+
char thumbnail_info : 1;
|
70
|
+
} out;
|
71
|
+
};
|
72
|
+
|
73
|
+
METHODDEF(void) _jpeg_decompress_error_exit(j_common_ptr cinfo);
|
74
|
+
METHODDEF(void) _jpeg_init_source(j_decompress_ptr cinfo);
|
75
|
+
METHODDEF(boolean) _jpeg_fill_input_buffer(j_decompress_ptr cinfo);
|
76
|
+
METHODDEF(void) _jpeg_skip_input_data(j_decompress_ptr cinfo, long num_bytes);
|
77
|
+
METHODDEF(void) _jpeg_term_source(j_decompress_ptr cinfo);
|
78
|
+
|
79
|
+
METHODDEF(void) _jpeg_init_destination(j_compress_ptr cinfo);
|
80
|
+
METHODDEF(boolean) _jpeg_empty_output_buffer (j_compress_ptr cinfo);
|
81
|
+
METHODDEF(void) _jpeg_term_destination (j_compress_ptr cinfo);
|
82
|
+
|
83
|
+
METHODDEF(void) _emit_message (j_common_ptr cinfo, int msg_level);
|
84
|
+
METHODDEF(void) _output_message (j_common_ptr cinfo);
|
85
|
+
METHODDEF(void) _format_message (j_common_ptr cinfo, char * buffer);
|
86
|
+
#endif
|
data/ext/epeg/extconf.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require "mkmf"
|
2
|
+
|
3
|
+
INCLUDE_DIRS = [ RbConfig::CONFIG["includedir"] ]
|
4
|
+
LIB_DIRS = [ RbConfig::CONFIG["libdir"] ]
|
5
|
+
|
6
|
+
dir_config("jpeg", INCLUDE_DIRS, LIB_DIRS)
|
7
|
+
dir_config("exif", INCLUDE_DIRS, LIB_DIRS)
|
8
|
+
|
9
|
+
raise "Please install libjpeg." unless have_library("jpeg")
|
10
|
+
raise "Please install libexif." unless have_library("exif")
|
11
|
+
|
12
|
+
create_makefile("epeg")
|
data/lib/epeg/epeg.rb
ADDED
data/lib/epeg/version.rb
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "tempfile"
|
3
|
+
|
4
|
+
describe Epeg::Image do
|
5
|
+
context "when loading an invalid jpeg file" do
|
6
|
+
it "should raise an error" do
|
7
|
+
invalid_jpeg = Tempfile.new(%w{invalid .jpg})
|
8
|
+
expect(lambda { Epeg::Image.open(invalid_jpeg.path) }).to raise_error
|
9
|
+
expect(lambda { Epeg::Image.from_blob(invalid_jpeg.read) }).to raise_error
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context "when loading a valid jpeg file" do
|
14
|
+
around(:each) do |example|
|
15
|
+
Epeg::Image.quality = 75
|
16
|
+
@image = Epeg::Image.open(TEST_JPEG)
|
17
|
+
@output_image = Tempfile.new(%w{out .jpg})
|
18
|
+
|
19
|
+
example.run
|
20
|
+
|
21
|
+
@output_image.unlink
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should have well-defined width and height" do
|
25
|
+
expect(@image.width ).to eq(20)
|
26
|
+
expect(@image.height).to eq(10)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should create new image from blob" do
|
30
|
+
data = File.open(TEST_JPEG, "rb"){ |f| f.read }
|
31
|
+
expect{ Epeg::Image.from_blob(data) }.not_to raise_error
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should return blob" do
|
35
|
+
blob = @image.to_blob
|
36
|
+
|
37
|
+
File.open(@output_image.path, "wb"){ |f| f.write(blob) }
|
38
|
+
@image_from_blob = Epeg::Image.open(@output_image.path)
|
39
|
+
|
40
|
+
expect(@image_from_blob.width ).to eq(20)
|
41
|
+
expect(@image_from_blob.height).to eq(10)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should resize an image" do
|
45
|
+
@image.resize(2, 2)
|
46
|
+
@image.write(@output_image.path)
|
47
|
+
|
48
|
+
@resized_image = Epeg::Image.open(@output_image.path)
|
49
|
+
|
50
|
+
expect(@resized_image.width ).to eq(2)
|
51
|
+
expect(@resized_image.height).to eq(2)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should resize an image to fit specific dimensions" do
|
55
|
+
@image.resize_to_fit(8,4)
|
56
|
+
@image.write(@output_image.path)
|
57
|
+
|
58
|
+
@resized_image = Epeg::Image.open(@output_image.path)
|
59
|
+
|
60
|
+
expect(@resized_image.width ).to eq(8)
|
61
|
+
expect(@resized_image.height).to eq(4)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should resize an image to fill specific dimensions" do
|
65
|
+
@image.resize_to_fill(8,8)
|
66
|
+
@image.write(@output_image.path)
|
67
|
+
|
68
|
+
@resized_image = Epeg::Image.open(@output_image.path)
|
69
|
+
|
70
|
+
expect(@resized_image.width ).to eq(16)
|
71
|
+
expect(@resized_image.height).to eq(8)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should crop an image" do
|
75
|
+
@image.crop(8, 8, 0, 0)
|
76
|
+
@image.write(@output_image.path)
|
77
|
+
|
78
|
+
@another_image = Epeg::Image.open(TEST_JPEG)
|
79
|
+
@another_image.crop(8, 8)
|
80
|
+
@another_output_image = Tempfile.new(%w{out2 .jpg})
|
81
|
+
@another_image.write(@another_output_image.path)
|
82
|
+
|
83
|
+
@cropped_image = Epeg::Image.open(@output_image.path)
|
84
|
+
@another_cropped_image = Epeg::Image.open(@another_output_image.path)
|
85
|
+
|
86
|
+
expect(@cropped_image.width ).to eq(8)
|
87
|
+
expect(@cropped_image.height).to eq(8)
|
88
|
+
|
89
|
+
expect(@another_cropped_image.width ).to eq(8)
|
90
|
+
expect(@another_cropped_image.height).to eq(8)
|
91
|
+
|
92
|
+
expect(@cropped_image.to_blob).not_to eq(@another_cropped_image.to_blob)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should not write image after closing" do
|
96
|
+
@image.close
|
97
|
+
|
98
|
+
expect(@image).to be_closed
|
99
|
+
expect{@image.write(@output_image.path)}.to raise_error
|
100
|
+
expect{@image.to_blob}.to raise_error
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should use default quality" do
|
104
|
+
expect(@image.quality).to eq(75)
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should set valid quality" do
|
108
|
+
@image.quality = 100
|
109
|
+
@image.write(@output_image.path)
|
110
|
+
high_qu_file_size = File.size(@output_image)
|
111
|
+
|
112
|
+
@image = Epeg::Image.open(TEST_JPEG)
|
113
|
+
@image.quality = 1
|
114
|
+
@image.write(@output_image.path)
|
115
|
+
low_qu_file_size = File.size(@output_image)
|
116
|
+
|
117
|
+
expect(@image.quality).to eq(1)
|
118
|
+
expect(high_qu_file_size).to be > low_qu_file_size
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should not set invalid quality" do
|
122
|
+
expect{ @image.quality = -1 }.to raise_error
|
123
|
+
expect{ @image.quality = 101 }.to raise_error
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
Binary file
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby-epeg
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nelson Darkwah Oppong
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2014-10-13 00:00:00 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake-compiler
|
16
|
+
prerelease: false
|
17
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: "0.9"
|
22
|
+
type: :runtime
|
23
|
+
version_requirements: *id001
|
24
|
+
- !ruby/object:Gem::Dependency
|
25
|
+
name: bundler
|
26
|
+
prerelease: false
|
27
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
28
|
+
requirements:
|
29
|
+
- - ~>
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: "1.7"
|
32
|
+
type: :development
|
33
|
+
version_requirements: *id002
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: rake
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ~>
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: "10.0"
|
42
|
+
type: :development
|
43
|
+
version_requirements: *id003
|
44
|
+
- !ruby/object:Gem::Dependency
|
45
|
+
name: rspec
|
46
|
+
prerelease: false
|
47
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ~>
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: "3.0"
|
52
|
+
type: :development
|
53
|
+
version_requirements: *id004
|
54
|
+
description:
|
55
|
+
email:
|
56
|
+
- ndo@felixnelson.de
|
57
|
+
executables: []
|
58
|
+
|
59
|
+
extensions:
|
60
|
+
- ext/epeg/extconf.rb
|
61
|
+
extra_rdoc_files: []
|
62
|
+
|
63
|
+
files:
|
64
|
+
- .gitignore
|
65
|
+
- .travis.yml
|
66
|
+
- Gemfile
|
67
|
+
- LICENSE.txt
|
68
|
+
- README.md
|
69
|
+
- Rakefile
|
70
|
+
- epeg.gemspec
|
71
|
+
- ext/epeg/EPEG_LICENSE
|
72
|
+
- ext/epeg/Epeg.h
|
73
|
+
- ext/epeg/epeg_image.c
|
74
|
+
- ext/epeg/epeg_image.h
|
75
|
+
- ext/epeg/epeg_main.c
|
76
|
+
- ext/epeg/epeg_private.h
|
77
|
+
- ext/epeg/extconf.rb
|
78
|
+
- lib/epeg/epeg.rb
|
79
|
+
- lib/epeg/version.rb
|
80
|
+
- spec/epeg_image_spec.rb
|
81
|
+
- spec/fixtures/test.jpg
|
82
|
+
- spec/spec_helper.rb
|
83
|
+
homepage: http://github.com/nelsond/ruby-epeg
|
84
|
+
licenses:
|
85
|
+
- MIT
|
86
|
+
metadata: {}
|
87
|
+
|
88
|
+
post_install_message:
|
89
|
+
rdoc_options: []
|
90
|
+
|
91
|
+
require_paths:
|
92
|
+
- lib
|
93
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- &id005
|
96
|
+
- ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: "0"
|
99
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- *id005
|
102
|
+
requirements: []
|
103
|
+
|
104
|
+
rubyforge_project:
|
105
|
+
rubygems_version: 2.4.2
|
106
|
+
signing_key:
|
107
|
+
specification_version: 4
|
108
|
+
summary: Ruby extension for the epeg library which provides facilities for scaling JPEG images very quickly.
|
109
|
+
test_files:
|
110
|
+
- spec/epeg_image_spec.rb
|
111
|
+
- spec/fixtures/test.jpg
|
112
|
+
- spec/spec_helper.rb
|
113
|
+
has_rdoc:
|