Skip to content

Commit cf1c796

Browse files
committed
add webp write support
see libvips#65 I've updated the bundle and broken rspec, this needs fixing we should probably have webp read as well I guess
1 parent c627404 commit cf1c796

File tree

8 files changed

+152
-28
lines changed

8 files changed

+152
-28
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ tags
88
*.o
99
/Makefile
1010
/mkmf.log
11+
rdoc

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# master
22

3+
# Version 0.3.10
4+
5+
* added webp write [John Cupitt]
6+
37
# Version 0.3.9
48

59
* removed a stray file from gemspec [Alessandro Tagliapietra]

Gemfile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ source "http://rubygems.org"
33
group :development do
44
gem "rdoc", "~> 4.1"
55
gem "rdoc-data", "~> 4.0"
6-
gem "bundler"
7-
gem "jeweler", "~> 1.8.3"
8-
gem 'rspec'
6+
gem "bundler", "~> 1.7"
7+
gem "jeweler", "~> 1.8"
8+
gem 'rspec', "~> 3.3"
99
end

Gemfile.lock

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
GEM
22
remote: http://rubygems.org/
33
specs:
4-
addressable (2.3.6)
4+
addressable (2.3.8)
55
builder (3.2.2)
66
diff-lcs (1.2.5)
77
faraday (0.8.9)
88
multipart-post (~> 1.2.0)
9-
git (1.2.7)
9+
git (1.2.9.1)
1010
github_api (0.10.1)
1111
addressable
1212
faraday (~> 0.8.1)
1313
hashie (>= 1.2)
1414
multi_json (~> 1.4)
1515
nokogiri (~> 1.5.2)
1616
oauth2
17-
hashie (3.2.0)
18-
highline (1.6.21)
17+
hashie (3.4.2)
18+
highline (1.7.2)
1919
jeweler (1.8.8)
2020
builder
2121
bundler (~> 1.0)
@@ -25,9 +25,9 @@ GEM
2525
nokogiri (= 1.5.10)
2626
rake
2727
rdoc
28-
json (1.8.1)
29-
jwt (1.0.0)
30-
multi_json (1.10.1)
28+
json (1.8.3)
29+
jwt (1.5.1)
30+
multi_json (1.11.1)
3131
multi_xml (0.5.5)
3232
multipart-post (1.2.0)
3333
nokogiri (1.5.10)
@@ -37,31 +37,32 @@ GEM
3737
multi_json (~> 1.3)
3838
multi_xml (~> 0.5)
3939
rack (~> 1.2)
40-
rack (1.5.2)
41-
rake (10.2.2)
42-
rdoc (4.1.1)
40+
rack (1.6.4)
41+
rake (10.4.2)
42+
rdoc (4.2.0)
4343
json (~> 1.4)
4444
rdoc-data (4.0.1)
4545
rdoc (~> 4.0)
46-
rspec (3.0.0)
47-
rspec-core (~> 3.0.0)
48-
rspec-expectations (~> 3.0.0)
49-
rspec-mocks (~> 3.0.0)
50-
rspec-core (3.0.2)
51-
rspec-support (~> 3.0.0)
52-
rspec-expectations (3.0.2)
46+
rspec (3.3.0)
47+
rspec-core (~> 3.3.0)
48+
rspec-expectations (~> 3.3.0)
49+
rspec-mocks (~> 3.3.0)
50+
rspec-core (3.3.1)
51+
rspec-support (~> 3.3.0)
52+
rspec-expectations (3.3.0)
5353
diff-lcs (>= 1.2.0, < 2.0)
54-
rspec-support (~> 3.0.0)
55-
rspec-mocks (3.0.2)
56-
rspec-support (~> 3.0.0)
57-
rspec-support (3.0.2)
54+
rspec-support (~> 3.3.0)
55+
rspec-mocks (3.3.1)
56+
diff-lcs (>= 1.2.0, < 2.0)
57+
rspec-support (~> 3.3.0)
58+
rspec-support (3.3.0)
5859

5960
PLATFORMS
6061
ruby
6162

6263
DEPENDENCIES
63-
bundler
64-
jeweler (~> 1.8.3)
64+
bundler (~> 1.7)
65+
jeweler (~> 1.8)
6566
rdoc (~> 4.1)
6667
rdoc-data (~> 4.0)
67-
rspec
68+
rspec (~> 3.3)

ext/writer.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,23 @@ png_write_internal(VALUE obj, VALUE path)
248248

249249
/* :nodoc: */
250250

251+
static VALUE
252+
webp_write_internal(VALUE obj, VALUE path)
253+
{
254+
#if ATLEAST_VIPS( 7, 42 )
255+
GetImg(obj, data, im);
256+
257+
if (im_vips2webp(im, RSTRING_PTR(path)))
258+
vips_lib_error();
259+
#else
260+
rb_raise(eVIPSError, "This method is not implemented in your version of VIPS");
261+
#endif
262+
263+
return obj;
264+
}
265+
266+
/* :nodoc: */
267+
251268
static VALUE
252269
csv_write_internal(VALUE obj, VALUE path)
253270
{
@@ -327,6 +344,13 @@ init_Writer(void)
327344
rb_define_private_method(png_writer, "write_internal", png_write_internal, 1);
328345
rb_define_private_method(png_writer, "buf_internal", png_buf_internal, 2);
329346

347+
/*
348+
* Write WebP images.
349+
*/
350+
351+
VALUE webp_writer = rb_define_class_under(mVIPS, "WEBPWriter", writer);
352+
rb_define_private_method(webp_writer, "write_internal", webp_write_internal, 1);
353+
330354
/*
331355
* Write CSV images.
332356
*/

lib/vips/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module VIPS
2-
VERSION = "0.3.9"
2+
VERSION = "0.3.10"
33
end

lib/vips/writer.rb

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,40 @@ def compression=(compression_v)
102102
end
103103
end
104104

105+
class WEBPWriter < Writer
106+
attr_accessor :quality, :lossless
107+
108+
def initialize(image, options={})
109+
super image
110+
111+
@quality = 75
112+
@lossless = false
113+
114+
self.quality = options[:quality] if options.has_key?(:quality)
115+
self.lossless = options[:lossless] if options.has_key?(:lossless)
116+
end
117+
118+
def write(path)
119+
write_gc "#{path}:#{@quality},#{@lossless ? 1 : 0}"
120+
end
121+
122+
def quality=(quality_v)
123+
unless (0..100).include?(quality_v)
124+
raise ArgumentError, 'quality must be a numeric value between 0 and 100'
125+
end
126+
127+
@quality = quality_v
128+
end
129+
130+
def lossless=(lossless_v)
131+
unless [True, False].include?(lossless_v)
132+
raise ArgumentError, 'lossless must be a boolean value'
133+
end
134+
135+
@lossless = lossless_v
136+
end
137+
end
138+
105139
class PPMWriter < Writer
106140
attr_reader :format
107141

spec/vips/webp_writer_spec.rb

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
require "spec_helper"
2+
3+
describe VIPS::WEBPWriter do
4+
before :all do
5+
@image = simg 'wagon.v'
6+
@writer = VIPS::WEBPWriter.new @image
7+
@path = tmp('wagon.webp').to_s
8+
end
9+
10+
it "should write to a webp file" do
11+
@writer.write(@path)
12+
13+
# no webp reader
14+
#im = VIPS::Image.webp @path
15+
#im.x_size.should == @image.x_size
16+
#im.y_size.should == @image.y_size
17+
end
18+
19+
it "should set a default quality of 75" do
20+
@writer.quality.should == 75
21+
end
22+
23+
it "should allow setting of the jpeg quality" do
24+
@writer.quality = 33
25+
@writer.quality.should == 33
26+
end
27+
28+
it "should raise an exception when trying to set an invalid quality" do
29+
lambda{ @writer.quality = -2 }.should raise_error(ArgumentError)
30+
lambda{ @writer.quality = "abc" }.should raise_error(ArgumentError)
31+
lambda{ @writer.quality = 3333 }.should raise_error(ArgumentError)
32+
end
33+
34+
it "should write smaller images with lower quality settings" do
35+
@writer.quality = 10
36+
@writer.write(@path)
37+
size1 = File.size @path
38+
39+
@writer.quality = 90
40+
@writer.write(@path)
41+
size2 = File.size @path
42+
43+
size1.should < size2 / 2
44+
end
45+
46+
it "should create a webp writer from an image" do
47+
@writer.class.should == VIPS::WEBPWriter
48+
@writer.image.should == @image
49+
end
50+
51+
it "should accept options on creation from an image" do
52+
writer = @image.webp(nil, :quality => 22)
53+
writer.quality.should == 22
54+
end
55+
56+
it "should allow access to header fields" do
57+
@writer.x_size.should == @image.x_size
58+
@writer.y_size.should == @image.y_size
59+
end
60+
end

0 commit comments

Comments
 (0)