-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Adding ruby gem * Add Instance getter and test * Typo * Update comments * Update README * Add resize method * Update comments * Add header method to patch python lib capability * Add 4 bytes to account for removing header
- Loading branch information
Showing
14 changed files
with
256 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/.bundle/ | ||
/.yardoc | ||
/_yardoc/ | ||
/coverage/ | ||
/doc/ | ||
/pkg/ | ||
/spec/reports/ | ||
/tmp/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
AllCops: | ||
TargetRubyVersion: 2.7 | ||
|
||
Style/StringLiterals: | ||
Enabled: true | ||
EnforcedStyle: double_quotes | ||
|
||
Style/StringLiteralsInInterpolation: | ||
Enabled: true | ||
EnforcedStyle: double_quotes | ||
|
||
Layout/LineLength: | ||
Max: 120 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# frozen_string_literal: true | ||
|
||
source "https://rubygems.org" | ||
|
||
# Specify your gem's dependencies in wasm-thumbnail-rb.gemspec | ||
gemspec | ||
|
||
gem "rake", "~> 13.0" | ||
|
||
gem "minitest", "~> 5.0" | ||
|
||
gem "rubocop", "~> 1.7" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Wasm::Thumbnail::Rb | ||
|
||
## Installation | ||
|
||
Note this gem has not been released to rubygems. It may in the future but for now it is intended to be referenced via git. | ||
|
||
Add this line to your application's Gemfile: | ||
|
||
```ruby | ||
gem 'wasm-thumbnail-rb', git: 'gitlocationofgem' | ||
``` | ||
|
||
And then execute: | ||
|
||
$ bundle install | ||
|
||
## Usage | ||
|
||
See `rb_test.rb` for an example of usage. | ||
|
||
## Development | ||
|
||
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. | ||
|
||
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org). | ||
|
||
## Contributing | ||
|
||
Bug reports and pull requests are welcome on GitHub at https://github.com/brave-intl/wasm-thumbnail-rb. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# frozen_string_literal: true | ||
|
||
require "bundler/gem_tasks" | ||
require "rake/testtask" | ||
|
||
Rake::TestTask.new(:test) do |t| | ||
t.libs << "test" | ||
t.libs << "lib" | ||
t.test_files = FileList["test/**/*_test.rb"] | ||
end | ||
|
||
require "rubocop/rake_task" | ||
|
||
RuboCop::RakeTask.new | ||
|
||
task default: %i[test rubocop] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#!/usr/bin/env ruby | ||
# frozen_string_literal: true | ||
|
||
require "bundler/setup" | ||
require "wasm/thumbnail/rb" | ||
|
||
# You can add fixtures and/or initialization code here to make experimenting | ||
# with your gem easier. You can also use a different console, if you like. | ||
|
||
# (If you use this, don't forget to add pry to your Gemfile!) | ||
# require "pry" | ||
# Pry.start | ||
|
||
require "irb" | ||
IRB.start(__FILE__) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#!/usr/bin/env bash | ||
set -euo pipefail | ||
IFS=$'\n\t' | ||
set -vx | ||
|
||
bundle install | ||
|
||
# Do any other automated setup that you need to do here |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
# frozen_string_literal: true | ||
|
||
require_relative "rb/version" | ||
require "wasmer" | ||
module Wasm | ||
module Thumbnail | ||
# As opposed to the PY implementation | ||
module Rb | ||
class Error < StandardError; end | ||
|
||
# Now the module is compiled, we can instantiate it. Doing so outside the method where used results in errors. | ||
def self.register_panic(_msg_ptr = nil, _msg_len = nil, _file_ptr = nil, _file_len = nil, _line = nil, _column = nil) | ||
puts("WASM panicked") | ||
end | ||
|
||
WASMStore = Wasmer::Store.new | ||
WASMImportObject = Wasmer::ImportObject.new | ||
WASMImportObject.register( | ||
"env", | ||
register_panic: Wasmer::Function.new( | ||
WASMStore, | ||
:register_panic, | ||
Wasmer::FunctionType.new([Wasmer::Type::I32, | ||
Wasmer::Type::I32, | ||
Wasmer::Type::I32, | ||
Wasmer::Type::I32, | ||
Wasmer::Type::I32, | ||
Wasmer::Type::I32], []) | ||
) | ||
) | ||
|
||
def self.resize_and_pad_with_header(file_bytes:, width:, height:, size:) | ||
# Let's compile the module to be able to execute it! | ||
wasm_instance = Wasm::Thumbnail::Rb::GetWasmInstance.call | ||
|
||
# This tells us how much space we'll need to put our image in the WASM env | ||
image_length = file_bytes.length | ||
input_pointer = wasm_instance.exports.allocate.call(image_length) | ||
# Get a pointer on the allocated memory so we can write to it | ||
memory = wasm_instance.exports.memory.uint8_view input_pointer | ||
|
||
# Put the image to resize in the allocated space | ||
(0..image_length - 1).each do |nth| | ||
memory[nth] = file_bytes[nth] | ||
end | ||
|
||
# Do the actual resize and pad | ||
# Note that this writes to a portion of memory the new JPEG file, but right pads the rest of the space | ||
# we gave it with 0. | ||
begin | ||
output_pointer = wasm_instance.exports.resize_and_pad.call(input_pointer, | ||
image_length, | ||
width, | ||
height, | ||
size) | ||
rescue RuntimeError | ||
raise "Error processing the image." | ||
end | ||
# Get a pointer to the result | ||
memory = wasm_instance.exports.memory.uint8_view output_pointer | ||
|
||
# Only take the buffer that we told the rust function we needed. The resize function | ||
# makes a smaller image than the buffer we said, and then pads out the rest. | ||
bytes = memory.to_a.take(size) | ||
|
||
# Deallocate | ||
wasm_instance.exports.deallocate.call(input_pointer, image_length) | ||
wasm_instance.exports.deallocate.call(output_pointer, bytes.length) | ||
|
||
bytes | ||
end | ||
|
||
def self.resize_and_pad(file_bytes:, width:, height:, size:) | ||
bytes = resize_and_pad_with_header(file_bytes: file_bytes, width: width, height: height, size: size + 4) | ||
|
||
# The first 4 bytes are a header until the image. The actual image probably ends well before | ||
# the whole buffer, but we keep the junk data on the end to make all the images the same size | ||
# for privacy concerns. | ||
bytes[4..].pack("C*") | ||
end | ||
|
||
# Return an instance so you don't have to constantly compile | ||
class GetWasmInstance | ||
def self.call | ||
# Let's compile the module to be able to execute it! | ||
Wasmer::Instance.new( | ||
Wasmer::Module.new(WASMStore, IO.read("#{__dir__}/rb/data/wasm_thumbnail.wasm", mode: "rb")), | ||
WASMImportObject | ||
) | ||
end | ||
end | ||
end | ||
end | ||
end |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# frozen_string_literal: true | ||
|
||
module Wasm | ||
module Thumbnail | ||
module Rb | ||
VERSION = "0.1.0" | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# frozen_string_literal: true | ||
|
||
$LOAD_PATH.unshift File.expand_path("../lib", __dir__) | ||
require "wasm/thumbnail/rb" | ||
|
||
require "minitest/autorun" |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# frozen_string_literal: true | ||
|
||
require "test_helper" | ||
|
||
class Wasm::Thumbnail::RbTest < Minitest::Test | ||
def test_that_it_has_a_version_number | ||
refute_nil ::Wasm::Thumbnail::Rb::VERSION | ||
end | ||
|
||
def test_it_does_something_useful | ||
file_bytes = File.binread("#{__dir__}/brave.png").unpack("C*") | ||
image = Wasm::Thumbnail::Rb.resize_and_pad(file_bytes: file_bytes, | ||
width: 100, | ||
height: 200, | ||
size: 250_000) | ||
puts "Image resized and padded to size #{image.length}" | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# frozen_string_literal: true | ||
|
||
require_relative "lib/wasm/thumbnail/rb/version" | ||
|
||
Gem::Specification.new do |spec| | ||
spec.name = "wasm-thumbnail-rb" | ||
spec.version = Wasm::Thumbnail::Rb::VERSION | ||
spec.authors = ["Tyler Smart"] | ||
spec.email = ["[email protected]"] | ||
spec.licenses = ["MPL-2.0"] | ||
spec.summary = "WASM based thumbnail library" | ||
spec.homepage = "https://github.com/brave-intl/wasm-thumbnail" | ||
spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0") | ||
|
||
spec.metadata["homepage_uri"] = spec.homepage | ||
spec.metadata["source_code_uri"] = "https://github.com/brave-intl/wasm-thumbnail" | ||
|
||
# Specify which files should be added to the gem when it is released. | ||
# The `git ls-files -z` loads the files in the RubyGem that have been added into git. | ||
spec.files = Dir.chdir(File.expand_path(__dir__)) do | ||
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) } | ||
end | ||
spec.bindir = "exe" | ||
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) } | ||
spec.require_paths = ["lib"] | ||
|
||
spec.add_dependency "wasmer", "~> 1.0" | ||
end |