psd_native 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3455db8f83d189130541ead18b691098dd5c63b9
4
+ data.tar.gz: 0a606b3f924bfa86ccfd5dc0a0f81a66868339e8
5
+ SHA512:
6
+ metadata.gz: e9d211703ff9633bb3d74f4fe9e54dfd802d7a183308e23369363d1de83183ec88d8d4de4565fae75e8c13ab9328c48522145a4bbd4a3926ef11ed963b8f4a60
7
+ data.tar.gz: f10ac6b1d616c6745a9d99bbb65fd7808747b8a7bc8e80a784344e4dc4a4b698ac2233a49ae32389982053260a840a6ccf01dd5217abc6917dc153c86203a8db
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ Makefile
19
+ *.o
20
+ conftest.dSYM
21
+ .DS_Store
22
+ *.bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in psd_native.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Ryan LeFevre
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # PSDNative
2
+
3
+ A gem that includes multiple mixins that speed up [PSD.rb](https://github.com/layervault/psd.rb) by delegating certain parts of the library to native C code. This library allows for PSD.rb to function as a pure Ruby library, while allowing for optional native code speed improvements. It overwrites specific methods within PSD.rb transparently, so you can use PSD.rb as you normally would.
4
+
5
+ Currently, PSDNative replaces these sections of PSD.rb with native code:
6
+
7
+ * RGB processing
8
+ * RLE decoding (disabled; needs optimization)
9
+
10
+ ## Installation
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ gem 'psd_native'
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install psd_native
23
+
24
+ ## Usage
25
+
26
+ ``` ruby
27
+ require 'psd_native'
28
+
29
+ psd = PSD.new("path/to/file.psd")
30
+ psd.parse!
31
+ ```
32
+
33
+ ## Contributing
34
+
35
+ 1. Fork it
36
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
37
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
38
+ 4. Push to the branch (`git push origin my-new-feature`)
39
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/extensiontask"
3
+
4
+ Rake::ExtensionTask.new('psd_native') do |ext|
5
+ ext.lib_dir = File.join('lib', 'psd_native')
6
+ ext.config_options = '--with-cflags="-std=c99"'
7
+ end
@@ -0,0 +1,3 @@
1
+ require 'mkmf'
2
+ $CFLAGS << ' -Wall'
3
+ create_makefile('psd_native/psd_native')
@@ -0,0 +1,39 @@
1
+ #include "psd_native_ext.h"
2
+
3
+ VALUE psd_native_combine_rgb_channel(VALUE self) {
4
+ psd_logger("debug", "Beginning RGB processing");
5
+
6
+ uint32_t num_pixels = FIX2UINT(rb_iv_get(self, "@num_pixels"));
7
+ uint32_t pixel_step = FIX2UINT(rb_funcall(self, rb_intern("pixel_step"), 0));
8
+
9
+ VALUE channels_info = rb_iv_get(self, "@channels_info");
10
+ VALUE channel_data = rb_iv_get(self, "@channel_data");
11
+ uint32_t channel_length = FIX2UINT(rb_iv_get(self, "@channel_length"));
12
+ uint32_t channel_count = FIX2UINT(rb_funcall(channels_info, rb_intern("length"), 0));
13
+
14
+ int i, j;
15
+ uint32_t val, r, g, b, a;
16
+
17
+ // Loop through every pixel in the image
18
+ for (i = 0; i < num_pixels; i += pixel_step) {
19
+ r = g = b = 0;
20
+ a = 255;
21
+
22
+ // And every channel for every pixel
23
+ for (j = 0; j < channel_count; j++) {
24
+ val = FIX2UINT(rb_ary_entry(channel_data, i + (channel_length * j)));
25
+
26
+ // Get the hash containing channel info
27
+ switch (FIX2INT(rb_hash_aref(rb_ary_entry(channels_info, j), ID2SYM(rb_intern("id"))))) {
28
+ case -1: a = val; break;
29
+ case 0: r = val; break;
30
+ case 1: g = val; break;
31
+ case 2: b = val; break;
32
+ }
33
+ }
34
+
35
+ rb_ary_push(rb_iv_get(self, "@pixel_data"), INT2FIX(BUILD_PIXEL(r, g, b, a)));
36
+ }
37
+
38
+ return Qnil;
39
+ }
@@ -0,0 +1,8 @@
1
+ #ifndef PSD_NATIVE_RGB
2
+ #define PSD_NATIVE_RGB
3
+
4
+ #define BUILD_PIXEL(r, g, b, a) (((PIXEL) (r) << 24) + ((PIXEL) (g) << 16) + ((PIXEL) (b) << 8) + (PIXEL) (a))
5
+
6
+ VALUE psd_native_combine_rgb_channel(VALUE self);
7
+
8
+ #endif
@@ -0,0 +1,33 @@
1
+ #include "psd_native_ext.h"
2
+
3
+ void Init_psd_native() {
4
+ VALUE PSDNative = rb_define_module("PSDNative");
5
+ VALUE ImageMode = rb_define_module_under(PSDNative, "ImageMode");
6
+
7
+ // RGB Processing
8
+ VALUE ImageMode_RGB = rb_define_module_under(ImageMode, "RGB");
9
+ rb_define_private_method(ImageMode_RGB, "combine_rgb_channel", psd_native_combine_rgb_channel, 0);
10
+
11
+ // RLE decoding
12
+ VALUE ImageFormat = rb_define_module_under(PSDNative, "ImageFormat");
13
+ VALUE RLE = rb_define_module_under(ImageFormat, "RLE");
14
+ rb_define_private_method(RLE, "decode_rle_channel", psd_native_decode_rle_channel, 0);
15
+
16
+ psd_logger("info", "PSD native mixins enabled!");
17
+ }
18
+
19
+ VALUE psd_class() {
20
+ return rb_const_get(rb_cObject, rb_intern("PSD"));
21
+ }
22
+
23
+ void psd_logger(char* level, char* message) {
24
+ rb_funcall(rb_funcall(psd_class(), rb_intern("logger"), 0), rb_intern(level), 1, rb_str_new2(message));
25
+ }
26
+
27
+ VALUE psd_file(VALUE self) {
28
+ return rb_iv_get(self, "@file");
29
+ }
30
+
31
+ int psd_file_tell(VALUE self) {
32
+ return FIX2INT(rb_funcall(psd_file(self), rb_intern("tell"), 0));
33
+ }
@@ -0,0 +1,22 @@
1
+ #ifndef PSD_NATIVE_EXT
2
+ #define PSD_NATIVE_EXT
3
+
4
+ #include "ruby.h"
5
+
6
+ #define RSTRING_NOT_MODIFIED
7
+
8
+ // Pixels use 32 bits unsigned integers
9
+ // We borrow this from OilyPNG
10
+ typedef uint32_t PIXEL;
11
+
12
+ // Our native mixins
13
+ #include "image_mode_rgb.h"
14
+ #include "rle_decoding.h"
15
+
16
+ void Init_psd_native();
17
+ VALUE psd_class();
18
+ void psd_logger(char* level, char* message);
19
+ VALUE psd_file(VALUE self);
20
+ int psd_file_tell(VALUE self);
21
+
22
+ #endif
@@ -0,0 +1,56 @@
1
+ #include "psd_native_ext.h"
2
+
3
+ VALUE psd_native_decode_rle_channel(VALUE self) {
4
+ int height = FIX2INT(rb_funcall(self, rb_intern("height"), 0));
5
+ VALUE channel_data = rb_iv_get(self, "@channel_data");
6
+ int bytes, finish, len, val;
7
+
8
+ for (int i = 0; i < height; i++) {
9
+ bytes = psd_byte_count(self, i);
10
+ finish = psd_file_tell(self) + bytes;
11
+
12
+ while (psd_file_tell(self) < finish) {
13
+ len = FIX2INT(psd_file_read_byte(self));
14
+
15
+ if (len < 128) {
16
+ len++;
17
+ for (int j = psd_chan_pos(self); j < psd_chan_pos(self) + len; j++) {
18
+ rb_ary_store(channel_data, j, psd_file_read_byte(self));
19
+ }
20
+
21
+ rb_iv_set(self, "@chan_pos", INT2FIX(psd_chan_pos(self) + len));
22
+ } else if (len > 128) {
23
+ len ^= 0xff;
24
+ len += 2;
25
+
26
+ val = psd_file_read_byte(self);
27
+ for (int j = psd_chan_pos(self); j < psd_chan_pos(self) + len; j++) {
28
+ rb_ary_store(channel_data, j, val);
29
+ }
30
+
31
+ rb_iv_set(self, "@chan_pos", INT2FIX(psd_chan_pos(self) + len));
32
+ }
33
+ }
34
+ }
35
+
36
+ return Qnil;
37
+ }
38
+
39
+ int psd_byte_count(VALUE self, int line) {
40
+ return FIX2INT(
41
+ rb_ary_entry(
42
+ rb_iv_get(self, "@byte_counts"),
43
+ FIX2INT(rb_iv_get(self, "@line_index")) + line
44
+ )
45
+ );
46
+ }
47
+
48
+ VALUE psd_file_read_byte(VALUE self) {
49
+ VALUE data = rb_funcall(psd_file(self), rb_intern("read"), 1, INT2FIX(1));
50
+ VALUE bytes = rb_funcall(data, rb_intern("bytes"), 0);
51
+ return rb_ary_entry(rb_funcall(bytes, rb_intern("to_a"), 0), 0);
52
+ }
53
+
54
+ int psd_chan_pos(VALUE self) {
55
+ return FIX2INT(rb_iv_get(self, "@chan_pos"));
56
+ }
@@ -0,0 +1,9 @@
1
+ #ifndef PSD_NATIVE_RLE_DECODING
2
+ #define PSD_NATIVE_RLE_DECODING
3
+
4
+ VALUE psd_native_decode_rle_channel(VALUE self);
5
+ int psd_byte_count(VALUE self, int line);
6
+ VALUE psd_file_read_byte(VALUE self);
7
+ int psd_chan_pos(VALUE self);
8
+
9
+ #endif
@@ -0,0 +1,3 @@
1
+ module PSDNative
2
+ VERSION = "0.1.0"
3
+ end
data/lib/psd_native.rb ADDED
@@ -0,0 +1,14 @@
1
+ require "psd"
2
+ require "psd_native/version"
3
+ require "psd_native/psd_native"
4
+
5
+ module PSDNative
6
+ def self.included(base)
7
+ base::Image.send(:include, PSDNative::ImageMode::RGB)
8
+
9
+ # Disabled until optimized
10
+ # base::Image.send(:include, PSDNative::ImageFormat::RLE)
11
+ end
12
+ end
13
+
14
+ PSD.send :include, PSDNative
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'psd_native/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "psd_native"
8
+ spec.version = PSDNative::VERSION
9
+ spec.authors = ["Ryan LeFevre"]
10
+ spec.email = ["ryan@layervault.com"]
11
+ spec.description = %q{Native mixins to speed up PSD.rb}
12
+ spec.summary = %q{Native C mixins to speed up the slowest parts of PSD.rb}
13
+ spec.homepage = "http://cosmos.layervault.com/psdrb.html"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+
20
+ spec.extensions = ["ext/psd_native/extconf.rb"]
21
+ spec.require_paths = ["lib", "ext"]
22
+
23
+ spec.add_runtime_dependency "psd", "~> 1.2"
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.3"
26
+ spec.add_development_dependency "rake"
27
+ spec.add_development_dependency "rake-compiler"
28
+ end
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: psd_native
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ryan LeFevre
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-09-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: psd
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake-compiler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Native mixins to speed up PSD.rb
70
+ email:
71
+ - ryan@layervault.com
72
+ executables: []
73
+ extensions:
74
+ - ext/psd_native/extconf.rb
75
+ extra_rdoc_files: []
76
+ files:
77
+ - .gitignore
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - ext/psd_native/extconf.rb
83
+ - ext/psd_native/image_mode_rgb.c
84
+ - ext/psd_native/image_mode_rgb.h
85
+ - ext/psd_native/psd_native_ext.c
86
+ - ext/psd_native/psd_native_ext.h
87
+ - ext/psd_native/rle_decoding.c
88
+ - ext/psd_native/rle_decoding.h
89
+ - lib/psd_native.rb
90
+ - lib/psd_native/version.rb
91
+ - psd_native.gemspec
92
+ homepage: http://cosmos.layervault.com/psdrb.html
93
+ licenses:
94
+ - MIT
95
+ metadata: {}
96
+ post_install_message:
97
+ rdoc_options: []
98
+ require_paths:
99
+ - lib
100
+ - ext
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ requirements: []
112
+ rubyforge_project:
113
+ rubygems_version: 2.0.8
114
+ signing_key:
115
+ specification_version: 4
116
+ summary: Native C mixins to speed up the slowest parts of PSD.rb
117
+ test_files: []