def initialize(palette)
@colors = []
@names = {}
@statistics = Hash.new(0)
@lost = []
@order = []
@version = nil
class << palette
def readwords(count = 1)
@offset ||= 0
raise IndexError if @offset >= self.size
val = self[@offset, count * 2]
raise IndexError if val.nil? or val.size < (count * 2)
val = val.unpack("n" * count)
@offset += count * 2
val
end
def readutf16(count = 1)
@offset ||= 0
raise IndexError if @offset >= self.size
val = self[@offset, count * 2]
raise IndexError if val.nil? or val.size < (count * 2)
@offset += count * 2
val
end
end
@version, count = palette.readwords 2
raise "Unknown AdobeColor palette version #@version." unless @version.between?(1, 2)
count.times do
space, w, x, y, z = palette.readwords 5
name = nil
if @version == 2
raise IndexError unless palette.readwords == [ 0 ]
len = palette.readwords
name = palette.readutf16(len[0] - 1)
raise IndexError unless palette.readwords == [ 0 ]
end
color = case space
when 0 then
@statistics[:rgb] += 1
Color::RGB.new(w / 256, x / 256, y / 256)
when 1 then
@statistics[:hsb] += 1
h = w / 65535.0
s = x / 65535.0
v = y / 65535.0
if defined?(Color::HSB)
Color::HSB.from_fraction(h, s, v)
else
@statistics[:converted] += 1
if Color.near_zero_or_less?(s)
Color::RGB.from_fraction(v, v, v)
else
if Color.near_one_or_more?(h)
vh = 0
else
vh = h * 6.0
end
vi = vh.floor
v1 = v.to_f * (1 - s.to_f)
v2 = v.to_f * (1 - s.to_f * (vh - vi))
v3 = v.to_f * (1 - s.to_f * (1 - (vh - vi)))
case vi
when 0 then Color::RGB.from_fraction(v, v3, v1)
when 1 then Color::RGB.from_fraction(v2, v, v1)
when 2 then Color::RGB.from_fraction(v1, v, v3)
when 3 then Color::RGB.from_fraction(v1, v2, v)
when 4 then Color::RGB.from_fraction(v3, v1, v)
else Color::RGB.from_fraction(v, v1, v2)
end
end
end
when 2 then
@statistics[:cmyk] += 1
Color::CMYK.from_percent(100 - (w / 655.35),
100 - (x / 655.35),
100 - (y / 655.35),
100 - (z / 655.35))
when 7 then
@statistics[:lab] += 1
l = [w, 10000].min / 100.0
a = [[-12800, UwToSw[x]].max, 12700].min / 100.0
b = [[-12800, UwToSw[x]].max, 12700].min / 100.0
if defined? Color::Lab
Color::Lab.new(l, a, b)
else
[ space, w, x, y, z ]
end
when 8 then
@statistics[:gray] += 1
g = [w, 10000].min / 100.0
Color::GrayScale.new(g)
when 9 then
@statistics[:wcmyk] += 1
c = [w, 10000].min / 100.0
m = [x, 10000].min / 100.0
y = [y, 10000].min / 100.0
k = [z, 10000].min / 100.0
Color::CMYK.from_percent(c, m, y, k)
else
@statistics[space] += 1
[ space, w, x, y, z ]
end
@order << [ color, name ]
if color.kind_of? Array
@lost << color
else
@colors << color
if name
@names[name] ||= []
@names[name] << color
end
end
end
end