myy-color 0.0.1

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: f2a893a6bce235224a2b5914227bd5354334e083
4
+ data.tar.gz: 9018dfe883831727c29adbcf52e33efe2b236984
5
+ SHA512:
6
+ metadata.gz: cceba474a1c2ce1c83dd330e8e3fb8f964ea6be18932fa47e8bbf64e93b10d12a4eedc306b11ec8bf7cc79207f6859a9afbca2ef03eb61825aa44a809dbae90f
7
+ data.tar.gz: bad0309811316d4c0d038d9eddcc709bd0646c730252d61b3824a45d67fa00d1ca3b5a3980cc85653a733030db89d5e98d93e707a0723095f5111d151e32350e
data/CHANGES ADDED
@@ -0,0 +1,29 @@
1
+
2
+ Version 0.0.1
3
+ -------------
4
+
5
+ * Added a CHANGELOG
6
+
7
+ * Renamed color to myy-color
8
+
9
+ * Cleaned up myy_bmp2raw
10
+
11
+ * Added two modules to myy-color
12
+ * BMP which handles the decoding of BMP files
13
+ * GL which handles the encoding of raw textures for OpenGL
14
+
15
+ * Added a few tests that currently only test the decoding procedures.
16
+
17
+ * Added a README which documents :
18
+ * The current goals of the project
19
+ * How to use the library
20
+ * How to use myy_bmp2raw
21
+ * What currently needs to be done.
22
+ However a TODO file might be needed.
23
+
24
+ * Created the gemspec file that handles the generation of the gem.
25
+ Build the gem like this :
26
+ `$ gem build myy-color.gemspec`
27
+
28
+ * Modified the .gitignore file so that backup files, gem files and
29
+ test textures are not added in the Git tree.
data/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2016 Miouyouyou
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/bin/myy_bmp2raw ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+ require "myy-color"
3
+
4
+ if ARGV.length < 4
5
+ puts "convert bmp_file input_color_encoding raw_file output_color_encoding"
6
+ puts "Example : convert file.bmp rgba8888 text.raw rgba5551"
7
+ exit
8
+ end
9
+
10
+ bmp_file, input_color_encoding, raw_file, output_color_encoding, = ARGV
11
+
12
+ MyyColor::OpenGL.convert_bmp(bmp_filename: bmp_file,
13
+ raw_filename: raw_file,
14
+ from: input_color_encoding,
15
+ to: output_color_encoding)
16
+
17
+ puts "Raw converted."
18
+
data/lib/myy-color.rb ADDED
@@ -0,0 +1,181 @@
1
+ module MyyColor
2
+ class DecompInfo
3
+ # right-shift operand (>>), and-mask operand (&), multiplication operand
4
+ def initialize(rs, am, mult)
5
+ @rs, @am, @mult = rs, am, mult
6
+ end
7
+ def decompose_component(whole_element)
8
+ ((whole_element >> @rs) & @am) * @mult
9
+ end
10
+ def recompose_component(component)
11
+ component / @mult << @rs
12
+ end
13
+ end
14
+ @@rgba = [:r, :g, :b, :a].freeze
15
+ @@orders = {
16
+ # encoding - {r: DecompInfo(rs, am, mult), g: idem, b: idem, a: idem)}
17
+ rgba4444:
18
+ [[12, 0xf, 16], [8, 0xf, 16], [4, 0xf, 16], [0, 0xf, 16]],
19
+ rgba5551:
20
+ [[11, 0b11111, 8], [6,0b11111,8], [1, 0b11111, 8], [0, 1, 255]],
21
+ argb5551:
22
+ [[10, 0b11111, 8], [5,0b11111,8], [0, 0b11111, 8], [15, 1, 255]],
23
+ rgba8888:
24
+ [[24, 0xff, 1], [16, 0xff, 1], [8, 0xff, 1], [0, 0xff, 1]],
25
+ bgra8888:
26
+ [[8, 0xff, 1], [16, 0xff, 1], [24, 0xff, 1], [0, 0xff, 1]],
27
+ argb8888:
28
+ [[16, 0xff, 1], [8, 0xff, 1], [0, 0xff, 1], [24, 0xff, 1]]
29
+ }
30
+ @@orders.each do |encoding,decomp_infos|
31
+ # if encoding is rgba5551 :
32
+ # decomp_infos = [[11, 0b11111, 8],...]
33
+ # encoding = :rgba5551
34
+
35
+ @@orders[encoding] = {} # Example : @@orders[:rgba5551] = {}
36
+
37
+ # Continuing with the same example :
38
+ # shift remove the first value of an array and return the removed value
39
+ # rs, am, mult
40
+ # @@orders[:rgba5551][:r] = DecompInfo.new(*[11,0b11111, 8])
41
+ # @@orders[:rgba5551][:g] = DecompInfo.new(*[5,0b11111, 8])
42
+ # ...
43
+
44
+ @@rgba.each do |component|
45
+ component_decomp_infos = decomp_infos.shift
46
+ @@orders[encoding][component] =
47
+ DecompInfo.new(*component_decomp_infos)
48
+ end
49
+ end
50
+ def self.handle_format?(format)
51
+ @@orders.has_key?(format)
52
+ end
53
+ @@hf_meth = method(:handle_format?)
54
+ def self.handle_formats?(*formats)
55
+ formats.flatten.all?(&@@hf_meth)
56
+ end
57
+ def self.handled_formats
58
+ @@orders.keys
59
+ end
60
+ def self.check_infos(infos)
61
+ if infos.nil?
62
+ raise ArgumentError, "No valid informations provided about the encoding #{encoding}"
63
+ end
64
+ end
65
+ def self.decode(encoded_color, encoding: nil, infos: @@orders[encoding])
66
+
67
+ check_infos(infos)
68
+
69
+ @@rgba.map do |component|
70
+
71
+ infos[component].decompose_component(encoded_color)
72
+ end
73
+ end
74
+
75
+ ## Use : MyyColors.encode(r, g, b, a, encoding: :rgba5551) -> Fixnum
76
+ ## Note : r, g, b, a must be normalised values in the [0,255] range.
77
+ def self.encode(*rgba_colors, encoding: nil, infos: @@orders[encoding])
78
+ check_infos(infos)
79
+
80
+ color_components = rgba_colors.flatten
81
+
82
+ color = 0
83
+ @@rgba.each do |component|
84
+ color |= infos[component].recompose_component((color_components.shift))
85
+ end
86
+ color
87
+ end
88
+ def self.convert_pixels(input_pixels, from:, to:)
89
+ input_pixels.map do |pixel|
90
+ encode(decode(pixel, encoding: from), encoding: to)
91
+ end
92
+ end
93
+
94
+ module BMP
95
+
96
+ @@header_offsets = { content_start_address_info: 0xa }.freeze
97
+ @@unpack_formats = {
98
+ rgba5551: "S<*",
99
+ rgba4444: "S<*",
100
+ rgba8888: "I<*",
101
+ argb8888: "I<*"
102
+ }
103
+ def self.convert_content(filename:, from:, to:)
104
+ if MyyColor.handle_formats?(from, to)
105
+ if !File.exists?(filename)
106
+ raise ArgumentError,
107
+ "Are you sure about that file ? #{filename}"
108
+ end
109
+
110
+ infile = File.open(filename, "r")
111
+
112
+ infile.seek(@@header_offsets[:content_start_address_info])
113
+ start_address, bitmap_header_size, width, height =
114
+ infile.read(16).unpack("I<4")
115
+ $stderr.puts("[Read] width : %d (%x) -- height : %d (%02x)" %
116
+ [width, width, height, height])
117
+ $stderr.puts "[Read] Starting from : 0x%x" % start_address
118
+
119
+ infile.seek(start_address)
120
+
121
+ input_pixels = infile.read.unpack(@@unpack_formats[from])
122
+
123
+ infile.close
124
+
125
+ output = {
126
+ content:
127
+ MyyColor.convert_pixels(input_pixels, from: from, to: to),
128
+ metadata: {width: width, height: height}
129
+ }.freeze
130
+
131
+ $stderr.puts("Encoded pixels : %d - By width : %d" %
132
+ [output[:content].length,
133
+ output[:content].length/width])
134
+
135
+ output
136
+ else
137
+ raise ArgumentError, <<-error.strip.gsub(/\s+/, ' ')
138
+ One of these formats is not supported by MyyColor :
139
+ #{from} - #{to}
140
+ Supported formats :
141
+ #{MyyColor.handled_formats.join('\n')}
142
+ error
143
+ end
144
+ end
145
+ end
146
+
147
+ module OpenGL
148
+
149
+ module GL
150
+ UNSIGNED_BYTE = 0x1401
151
+ RGBA = 0x1908
152
+ UNSIGNED_SHORT_5_5_5_1 = 0x8034
153
+ UNSIGNED_SHORT_4_4_4_4 = 0x8033
154
+ end
155
+
156
+ @@formats = {
157
+ rgba5551: {headers: [GL::RGBA, GL::UNSIGNED_SHORT_5_5_5_1],
158
+ unpack: "S<*", pack: "S<*"},
159
+ rgba4444: {headers: [GL::RGBA, GL::UNSIGNED_SHORT_4_4_4_4],
160
+ unpack: "S<*", pack: "S<*"},
161
+ rgba8888: {headers: [GL::RGBA, GL::UNSIGNED_BYTE],
162
+ unpack: "I<*", pack: "I>*"},
163
+ argb8888: {headers: [GL::RGBA, GL::UNSIGNED_BYTE],
164
+ unpack: "I<*", pack: "I>*"}
165
+ }
166
+
167
+ def self.convert_bmp(bmp_filename:, raw_filename:, from:, to:)
168
+ raw = MyyColor::BMP.convert_content(filename: bmp_filename,
169
+ from: from.to_sym,
170
+ to: to.to_sym)
171
+ output_format = @@formats[to.to_sym]
172
+ metadata = [raw[:metadata][:width], raw[:metadata][:height]] +
173
+ output_format[:headers]
174
+
175
+ File.open(raw_filename, "w") do |out|
176
+ out.write(metadata.pack("I<*"))
177
+ out.write(raw[:content].flatten.pack(output_format[:pack]))
178
+ end
179
+ end
180
+ end
181
+ end
data/lib/myy-color.rb~ ADDED
@@ -0,0 +1,150 @@
1
+ module MyyColor
2
+ class DecompInfo
3
+ # right-shift operand (>>), and-mask operand (&), multiplication operand
4
+ def initialize(rs, am, mult)
5
+ @rs, @am, @mult = rs, am, mult
6
+ end
7
+ def decompose_component(whole_element)
8
+ ((whole_element >> @rs) & @am) * @mult
9
+ end
10
+ def recompose_component(component)
11
+ component / @mult << @rs
12
+ end
13
+ end
14
+ @@rgba = [:r, :g, :b, :a].freeze
15
+ @@orders = {
16
+ # encoding - {r: DecompInfo(rs, am, mult), g: idem, b: idem, a: idem)}
17
+ rgba4444: [[12, 0xf, 16], [8, 0xf, 16], [4, 0xf, 16], [0, 0xf, 16]],
18
+ rgba5551: [[11, 0b11111, 8], [6,0b11111,8], [1, 0b11111, 8], [0, 1, 255]],
19
+ argb5551: [[10, 0b11111, 8], [5,0b11111,8], [0, 0b11111, 8], [15, 1, 255]],
20
+ rgba8888: [[24, 0xff, 1], [16, 0xff, 1], [8, 0xff, 1], [0, 0xff, 1]],
21
+ bgra8888: [[8, 0xff, 1], [16, 0xff, 1], [24, 0xff, 1], [0, 0xff, 1]],
22
+ argb8888: [[16, 0xff, 1], [8, 0xff, 1], [0, 0xff, 1], [24, 0xff, 1]]
23
+ }
24
+ @@orders.each do |encoding,decomp_infos|
25
+ # if encoding is rgba5551 :
26
+ # decomp_infos = [[11, 0b11111, 8],...]
27
+ # encoding = :rgba5551
28
+
29
+ @@orders[encoding] = {} # Example : @@orders[:rgba5551] = {}
30
+
31
+ # Continuing with the same example :
32
+ # shift remove the first value of an array and return the removed value
33
+ # rs, am, mult
34
+ # @@orders[:rgba5551][:r] = DecompInfo.new(*[11,0b11111, 8])
35
+ # @@orders[:rgba5551][:g] = DecompInfo.new(*[5,0b11111, 8])
36
+ # ...
37
+
38
+ @@rgba.each do |component|
39
+ component_decomp_infos = decomp_infos.shift
40
+ @@orders[encoding][component] = DecompInfo.new(*component_decomp_infos)
41
+ end
42
+ end
43
+ def self.handle_format?(format)
44
+ @@orders.has_key?(format)
45
+ end
46
+ def self.handled_formats
47
+ @@orders.keys
48
+ end
49
+ def self.check_infos(infos)
50
+ if infos.nil?
51
+ raise ArgumentError, "No valid informations provided about the encoding #{encoding}"
52
+ end
53
+ end
54
+ def self.decode(encoded_color, encoding: nil, infos: @@orders[encoding])
55
+
56
+ check_infos(infos)
57
+
58
+ @@rgba.map do |component|
59
+
60
+ infos[component].decompose_component(encoded_color)
61
+ end
62
+ end
63
+ def self.encode(*rgba_colors, encoding: nil, infos: @@orders[encoding])
64
+ check_infos(infos)
65
+
66
+ color_components = rgba_colors.flatten
67
+
68
+ color = 0
69
+ @@rgba.each do |component|
70
+ color |= infos[component].recompose_component((color_components.shift))
71
+ end
72
+ color
73
+ end
74
+ def self.convert_pixels(input_pixels, from:, to:)
75
+ input_pixels.map do |pixel|
76
+ Color.encode(Color.decode(pixel, encoding: from), encoding: to)
77
+ end
78
+ end
79
+
80
+ module BMP
81
+
82
+ @@header_offsets = { content_start_address_info: 0xa }.freeze
83
+ def self.convert_content(filename:, from:, to:)
84
+ if MyyColor.handle_formats?(from, to)
85
+ infile = File.open(bmp_file, "r")
86
+
87
+ infile.seek(@@header_offsets[:content_start_address_info])
88
+ start_address, bitmap_header_size, width, height = infile.read(16).unpack("I<4")
89
+ puts "[Read] width : %d (%x) -- height : %d (%02x)" % [width, width, height, height]
90
+ puts "[Read] Starting from : 0x%x" % start_address
91
+
92
+ infile.seek(start_address)
93
+
94
+ input_pixels = infile.read.unpack(formats[input_color_encoding][:unpack])
95
+
96
+ infile.close
97
+
98
+ output = {
99
+ content: MyyColor.convert_pixels(input_pixels, from: from, to: to),
100
+ metadata: {width: width, height: height}
101
+ }.freeze
102
+
103
+ puts "Encoded pixels : %d - By width : %d" % [output[:content].length, output[:content].length/width]
104
+
105
+ output
106
+ else
107
+ raise ArgumentError, <<-error.strip.gsub(/\s+/, ' ')
108
+ One of these formats is not supported by MyyColor :
109
+ #{from} - #{to}
110
+ Supported formats :
111
+ #{MyyColor.handled_formats.join('\n')}
112
+ error
113
+ end
114
+ end
115
+ end
116
+
117
+ module OpenGL
118
+
119
+ module GL
120
+ UNSIGNED_BYTE = 0x1401
121
+ RGBA = 0x1908
122
+ UNSIGNED_SHORT_5_5_5_1 = 0x8034
123
+ UNSIGNED_SHORT_4_4_4_4 = 0x8033
124
+ end
125
+
126
+ @@formats = {
127
+ rgba5551: {headers: [GL::RGBA, GL::UNSIGNED_SHORT_5_5_5_1],
128
+ unpack: "S<*", pack: "S<*"},
129
+ rgba4444: {headers: [GL::RGBA, GL::UNSIGNED_SHORT_4_4_4_4],
130
+ unpack: "S<*", pack: "S<*"},
131
+ rgba8888: {headers: [GL::RGBA, GL::UNSIGNED_BYTE],
132
+ unpack: "I<*", pack: "I>*"},
133
+ argb8888: {headers: [GL::RGBA, GL::UNSIGNED_BYTE],
134
+ unpack: "I<*", pack: "I>*"}
135
+ }
136
+
137
+ def convert_bmp(bmp_filename:, raw_filename:, from:, to:)
138
+ raw = MyyColor::BMP.convert_content(filename: bmp_filename,
139
+ from: from.to_sym, to: to.to_sym)
140
+ output_format = @@formats[to.to_sym]
141
+ metadata = [raw[:metadata][:width], raw[:metadata][:height]] +
142
+ output_format[:headers]
143
+
144
+ File.open(raw_filename, "w") do |out|
145
+ out.write(metadata.pack("I<*"))
146
+ out.write(raw[:content].flatten.pack(output_format[:pack]))
147
+ end
148
+ end
149
+ end
150
+ end
data/myy-color.gemspec ADDED
@@ -0,0 +1,17 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "myy-color"
3
+ s.version = "0.0.1"
4
+ s.authors = ["Myy"]
5
+ s.email = ["color@miouyouyou.fr"]
6
+ s.homepage = "https://github.com/Miouyouyou/myy-color"
7
+ s.summary = "a basic RGBA decoder/encoder"
8
+ s.description = <<-desc.strip.gsub(/\s+/, ' ')
9
+ MyyColor provides basic color encoding and decoding facilities,
10
+ which are mainly used for converting BMP to OpenGL raw texture
11
+ format.
12
+ desc
13
+ s.rubyforge_project = "myy-color"
14
+ s.files = Dir['LICENSE', 'README', 'CHANGES', 'myy-color.gemspec', 'lib/**', 'bin/myy_bmp2raw']
15
+ s.executables = %w(myy_bmp2raw)
16
+ s.license = 'MIT'
17
+ end
metadata ADDED
@@ -0,0 +1,52 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: myy-color
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Myy
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-10-11 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: MyyColor provides basic color encoding and decoding facilities, which
14
+ are mainly used for converting BMP to OpenGL raw texture format.
15
+ email:
16
+ - color@miouyouyou.fr
17
+ executables:
18
+ - myy_bmp2raw
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - CHANGES
23
+ - LICENSE
24
+ - bin/myy_bmp2raw
25
+ - lib/myy-color.rb
26
+ - lib/myy-color.rb~
27
+ - myy-color.gemspec
28
+ homepage: https://github.com/Miouyouyou/myy-color
29
+ licenses:
30
+ - MIT
31
+ metadata: {}
32
+ post_install_message:
33
+ rdoc_options: []
34
+ require_paths:
35
+ - lib
36
+ required_ruby_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ requirements: []
47
+ rubyforge_project: myy-color
48
+ rubygems_version: 2.5.1
49
+ signing_key:
50
+ specification_version: 4
51
+ summary: a basic RGBA decoder/encoder
52
+ test_files: []