Hello!
It's been a while now that I've been analyzing color swatches in
different software. Here is the result of my work:
http://www.selapa.net/couleurs/fileformats.php (it's an update of
http://wiki.scribus.net/index.php/Talk:New_Colours_Format with another
presentation). If someone has informations about other formats or
precisions about these ones, I'd be happy to add it to the list...
I also started writing a conversion script (attached). For now, it can
only read pal (riff), aco, act, acb (adobe and autocad unencrypted
only), ase, acf, bcf, clr (colors only), cpl, qcl, bcs, cs. No write
function is there yet. It returns a dictionary with the content of the
swatch. All values are kept as in the original file, that's why there's
a 'orig' field in the dictionary. I'm pretty new to python programming
so my code is probably not optimal...
Now some thoughts about color swatches in general and about the CREATE
draft:
Registration color
IMHO, this shouldn't come in a color swatch file. It's a "system" color,
just the opposite of 'None'. It depends of the colors used in the
document. If you're using only cyan in your document, registration will
be 100% cyan. If your document contains only magenta and yellow,
registration will be red. And if you have spot colors, registration
won't be C=100% M=100% Y=100% K=100%. In other words, registration can't
be defined out of the document's context. Registration should just be
added in the software's color list for any press work.
Color swatch draft
<http://create.freedesktop.org/wiki/index.php/Swatches_-_colour_file_format/Draft>
The name and space attributes shouldn't be mandatory. A color doesn't
need a name to come into a palette and many palettes are just a
arbitrary "geometrical" division of the possibilities of color model.
When you have #003399 in a palette, it's not because it looks like
anything in real life, it's just because its neighbors are #003366 and
#0033CC. It just shows different possibilities of RGB, whether you're
using sRGB or AdobeRGB doesn't matter. The same applies to "Black 20%"
(or C=10% M=20% Y=30% K%). There are a lot of such palettes where
neither the name or the color space have any importance. By the way, Lab
and XYZ don't need any color space since these are device-independant
models.
That model also lacks swatch informations (name, copyright, license,
...) and swatch-wide settings ("all rgb values are in Adobe1998 color
space", "all color names start with 'PANTONE' and end with 'C'", ...).
Olivier
#!/usr/bin/python
# coding: utf-8
#
# swatch_convertor.py â version 2008-04-06
#
# Copyright 2008 Olivier Berten <[EMAIL PROTECTED]>
#
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
#
import sys
import struct
from collections import defaultdict
import os.path
from xml.etree import ElementTree as etree
def test_format(file):
ext = os.path.splitext(os.path.basename(file))[1].lower()
# Adobe
if ext == '.acb':
data = open(file).read(4)
if struct.unpack('4s', data)[0] == '8BCB':
format = 'adobe_acb'
elif struct.unpack('4s', data)[0] == '<?xm':
if etree.parse(file).getroot().tag == 'colorBook':
format = 'autocad_acb'
elif ext == '.aco':
data = open(file).read(2)
if struct.unpack('>h', data)[0] in (1,2):
format = 'adobe_aco'
elif ext == '.act':
if os.path.getsize(file) == 772 or os.path.getsize(file)%3 == 0:
format = 'adobe_act'
elif ext == '.ase':
data = open(file).read(4)
if struct.unpack('4s', data)[0] == 'ASEF':
format = 'adobe_ase'
elif ext == '.acf':
data = open(file).read(7)
if struct.unpack('7s', data)[0] in ('ACF 1.0','ACF 2.1'):
format = 'adobe_acf'
elif ext == '.bcf':
data = open(file).read(7)
if struct.unpack('7s', data)[0] in ('ACF 1.0','ACF 2.1','BCF 2.0'):
format = 'adobe_bcf'
elif ext == '.clr':
data = open(file).read(4)
if data == '\xff\xff\x00\x00':
format = 'adobe_clr'
# RAL
elif ext == '.bcs':
data = open(file).read(4)
if struct.unpack('b3s', data)[1] in ('clf','rgb','atl'):
format = 'ral_bcs'
# Corel
elif ext == '.cpl':
data = open(file).read(2)
if data in ('\xcc\xbc','\xcc\xdc','\xcd\xbc','\xcd\xdc','\xdd\xdc','\xdc\xdc','\xcd\xdd'):
format = 'corel_cpl'
# Quark
elif ext == '.qcl':
if etree.parse(file).getroot().tag == 'cgats17':
format = 'quark_qcl'
# ColorSchemer
elif ext == '.cs':
data = open(file).read(2)
if struct.unpack('<H', data)[0] == 3:
format = 'colorschemer'
# RIFF
elif ext == '.pal':
data = open(file).read(12)
RIFF, size, PAL = struct.unpack('<4s L 4s', data)
if RIFF == 'RIFF' and PAL == 'PAL ':
format = 'riff_pal'
if 'format' in vars():
return format
def ords2str(ords):
string = u''
for ord in ords:
string += unichr(ord)
return string.split('\x00', 1)[0]
def acb_decode_str(str):
if str[0:4] == '$$$/':
str = str.partition('=')[2]
return str.replace('^C',u'©').replace('^R',u'®')
adobe_model = {0: 'RGB', 1: 'HSV', 2: 'CMYK', 7: 'Lab', 8: 'Gray', 9: 'CMYK_100'}
bcf_model = {1: 'RGB', 2: 'CMYK',8: 'hifi', 16: 'Mixed'}
def read(file):
filesize = os.path.getsize(file)
if test_format(file):
format = test_format(file)
else:
print 'unknown swatch format'
sys.exit(-1)
swatch = defaultdict(dict)
swatch['orig'] = format
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Adobe Color Book #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
if format == 'adobe_acb':
file = open(file)
file.seek(8, 1)
length = struct.unpack('>L',file.read(4))[0]
if length > 0:
name = acb_decode_str(ords2str(struct.unpack('>'+str(length)+'H',file.read(length*2))))
if name > u'':
swatch['swatch']['name'] = name
length = struct.unpack('>L',file.read(4))[0]
if length > 0:
prefix = acb_decode_str(ords2str(struct.unpack('>'+str(length)+'H',file.read(length*2))))
if 'prefix' in vars() and prefix > u'':
swatch['swatch']['name_format'] = {}
swatch['swatch']['name_format'][0] = prefix+'%n'
length = struct.unpack('>L',file.read(4))[0]
if length > 0:
postfix = acb_decode_str(ords2str(struct.unpack('>'+str(length)+'H',file.read(length*2))))
if 'postfix' in vars() and postfix > u'':
if swatch['swatch']['name_format']:
swatch['swatch']['name_format'][0] = swatch['swatch']['name_format'][0]+postfix
else:
swatch['swatch']['name_format'] = {}
swatch['swatch']['name_format'][0] = '%n'+postfix
length = struct.unpack('>L',file.read(4))[0]
if length > 0:
description = acb_decode_str(ords2str(struct.unpack('>'+str(length)+'H',file.read(length*2))))
if 'description' in vars() and description > u'':
swatch['swatch']['description'] = description
nbcolors = struct.unpack('>H',file.read(2))[0]
swatch['swatch']['columns'] = struct.unpack('>H',file.read(2))[0]
file.seek(2, 1)
model = adobe_model[struct.unpack('>H',file.read(2))[0]]
for i in range(nbcolors):
swatch['colors'][i] = {}
length = struct.unpack('>L',file.read(4))[0]
if length > 0:
swatch['colors'][i]['name'] = acb_decode_str(ords2str(struct.unpack('>'+str(length)+'H',file.read(length*2))))
file.seek(6, 1)
if model in ('RGB','Lab'):
swatch['colors'][i][model] = struct.unpack('>3B',file.read(3))
elif model == 'CMYK':
swatch['colors'][i][model] = struct.unpack('>4B',file.read(4))
else:
print 'unknown color model'
if file.read(4):
if struct.unpack('>4s',file.read(4))[0] == 'spot':
swatch['swatch']['spot'] = 1
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Adobe Color Swatch #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
elif format == 'adobe_aco':
file = open(file)
version, nbcolors = struct.unpack('>2H',file.read(4))
if version == 1 and filesize > 4+nbcolors*10:
file.seek(4+nbcolors*10)
version, nbcolors = struct.unpack('>2H',file.read(4))
for i in range(nbcolors):
swatch['colors'][i] = {}
model = adobe_model[struct.unpack('>H',file.read(2))[0]]
if model in ('CMYK','CMYK_100'):
swatch['colors'][i][model] = struct.unpack('>4H',file.read(8))
elif model in ('RGB','HSV','Lab'):
swatch['colors'][i][model] = struct.unpack('>3H',file.read(6))
file.seek(2, 1)
elif model == 'Gray':
swatch['colors'][i][model] = struct.unpack('>H',file.read(2))
file.seek(6, 1)
else:
print 'unknown color model'
if version == 2:
length = struct.unpack('>L',file.read(4))[0]
if length > 0:
swatch['colors'][i]['name'] = ords2str(struct.unpack('>'+str(length)+'H',file.read(length*2)))
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Adobe Swatch Exchange #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
elif format == 'adobe_ase':
file = open(file)
file.seek(4)
version = struct.unpack('>2H',file.read(4))
nbblocks = struct.unpack('>L',file.read(4))[0]
for i in range(nbblocks):
swatch['colors'][i] = {}
block_type,block_size = struct.unpack('>HL',file.read(6))
if block_type == 0xc001:
swatch['colors'][i]['group'] = 'start'
elif block_type == 0xc002:
swatch['colors'][i]['group'] = 'end'
if block_size > 0:
length = struct.unpack('>H',file.read(2))[0]
if length > 0:
name = ords2str(struct.unpack('>'+str(length)+'H',file.read(length*2)))
if name > u'':
swatch['colors'][i]['name'] = name
if block_type == 0x0001:
model = struct.unpack('4s',file.read(4))[0]
if model == "CMYK":
swatch['colors'][i]['CMYK'] = struct.unpack('>4f',file.read(16))
elif model == "RGB ":
swatch['colors'][i]['RGB'] = struct.unpack('>3f',file.read(12))
elif model == "LAB ":
swatch['colors'][i]['Lab'] = struct.unpack('>3f',file.read(12))
elif model == "Gray":
swatch['colors'][i]['Gray'] = struct.unpack('>f',file.read(4))
type = struct.unpack('>H',file.read(2))[0]
if type == 0:
swatch['colors'][i]['global'] = 1
elif type == 1:
swatch['colors'][i]['spot'] = 1
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Adobe Color Table #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
elif format == 'adobe_act':
if os.path.getsize(file) == 772: # CS2
file = open(file)
file.seek(768, 0)
nbcolors = struct.unpack('>H',file.read(2))[0]
file.seek(0, 0)
else:
nbcolors = os.path.getsize(file)/3
file = open(file)
for i in range (nbcolors):
swatch['colors'][i] = {}
swatch['colors'][i]['RGB'] = struct.unpack('3B',file.read(3))
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# ASCII Color Format #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
elif format == 'adobe_acf':
file = open(file, 'U').readlines()
version = file[0].strip()
swatch['swatch']['name'] = file[1].strip()
swatch['swatch']['version'] = file[2].partition('LibraryVersion: ')[2].strip()
copyright = file[3].partition('Copyright: ')[2].strip()
if copyright > '':
swatch['swatch']['copyright'] = copyright
description = file[4].partition('AboutMessage: ')[2].strip()
if description > '':
swatch['swatch']['description'] = description
name_format = file[5].partition('Names: ')[2].strip().lower() # Full Partial
swatch['swatch']['columns'] = file[6].partition('Rows: ')[2].strip()
swatch['swatch']['rows'] = file[7].partition('Columns: ')[2].strip()
nbcolors = eval(file[8].partition('Entries: ')[2].strip())
prefix = file[9].partition('Prefix: ')[2].strip()
if prefix > '':
swatch['swatch']['name_format'] = {}
swatch['swatch']['name_format'][0] = prefix+'%n'
suffix = file[10].partition('Suffix: ')[2].strip()
if suffix > '':
if swatch['swatch']['name_format']:
swatch['swatch']['name_format'][0] = swatch['swatch']['name_format'][0]+suffix
else:
swatch['swatch']['name_format'] = {}
swatch['swatch']['name_format'][0] = '%n'+suffix
type = file[11].partition('Type: ')[2].strip() # hifi Process Spot Mixed
if type == 'Spot':
swatch['swatch']['spot'] = 1
models = file[12].partition('Models: ')[2].strip().split() # hifi Lab RGB CMYK
swatch['swatch']['preferredmodel'] = file[13].partition('PreferredModel: ')[2].strip()
pos = 14
if version == 'ACF 2.1':
nbinks = int(file[pos].partition('Inks: ')[2].strip())
pos = pos+1
swatch['swatch']['inks'] = []
for i in range(nbinks):
swatch['swatch']['inks'].append(file[pos].strip())
pos = pos+1
pos = pos+1
for i in range(nbcolors):
swatch['colors'][i] = {}
for j in models:
colors = file[pos].strip().split()
for k in range(len(colors)):
colors[k] = eval(colors[k])
swatch['colors'][i][j] = tuple(colors)
pos = pos+1
if type == 'Mixed':
col_type = file[pos].strip()
if col_type == 'Spot':
swatch['colors'][i]['spot'] = 1
pos = pos+1
swatch['colors'][i]['name'] = file[pos].strip()
pos = pos+1
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Binary Color Format #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
elif format == 'adobe_bcf':
file = open(file)
version = struct.unpack('8s',file.read(8))[0].split('\x00', 1)[0]
swatch['swatch']['name'] = struct.unpack('32s',file.read(32))[0].split('\x00', 1)[0]
swatch['swatch']['version'] = struct.unpack('8s',file.read(8))[0].split('\x00', 1)[0]
copyright = struct.unpack('32s',file.read(32))[0].split('\x00', 1)[0]
if copyright > '':
swatch['swatch']['copyright'] = copyright
description = struct.unpack('512s',file.read(512))[0].split('\x00', 1)[0]
if description > '':
swatch['swatch']['description'] = description
names, swatch['display']['columns'], swatch['display']['rows'], nbcolors = struct.unpack('>4H',file.read(8))
prefix = struct.unpack('12s',file.read(12))[0].split('\x00', 1)[0]
if prefix > '':
swatch['swatch']['name_format'] = {}
swatch['swatch']['name_format'][0] = prefix+'%n'
suffix = struct.unpack('4s',file.read(4))[0].split('\x00', 1)[0]
if suffix > '':
if swatch['swatch']['name_format']:
swatch['swatch']['name_format'][0] = swatch['swatch']['name_format'][0]+suffix
else:
swatch['swatch']['name_format'] = {}
swatch['swatch']['name_format'][0] = '%n'+suffix
type, XYZ, CMYK, RGB, preferredmodel = struct.unpack('>5h',file.read(10))
swatch['swatch']['preferredmodel'] = bcf_model[preferredmodel]
if version in ('ACF 2.1','BCF 2.0'):
extender = struct.unpack('>H',file.read(2))[0]
if extender == 1:
description2 = struct.unpack('100s',file.read(100))[0].split('\x00', 1)[0]
swatch['swatch']['description'] = swatch['swatch']['description']+description2
inks,nbinks,Lab = struct.unpack('>3H',file.read(6))
file.seek(24, 1)
if inks == 1:
swatch['swatch']['inks'] = []
for i in range(nbinks):
swatch['swatch']['inks'] .append(struct.unpack('>10s 10s H 32s',file.read(54)))
for i in range(nbcolors):
swatch['colors'][i] = {}
if XYZ == 1:
swatch['colors'][i]['XYZ'] = struct.unpack('>3H',file.read(6))
elif 'Lab' in vars() and Lab == 1:
swatch['colors'][i]['Lab'] = struct.unpack('>3h',file.read(6))
else:
file.seek(6, 1)
if CMYK == 1:
swatch['colors'][i]['CMYK'] = struct.unpack('>4H',file.read(8))
else:
file.seek(8, 1)
if RGB == 1:
swatch['colors'][i]['RGB'] = struct.unpack('>3H',file.read(6))
else:
file.seek(6, 1)
if version in ('ACF 2.1','BCF 2.0') and type in (8,16):
col_nbinks = struct.unpack('>H',file.read(2))[0]
hifi = []
for j in range(col_nbinks):
hifi.append( struct.unpack('>2H',file.read(4)))
swatch['colors'][i]['hifi'] = tuple(hifi)
file.seek((8-col_nbinks)*4, 1)
col_type = struct.unpack('>H',file.read(2))[0]
if col_type == 1:
swatch['colors'][i]['spot'] = 1
if version in ('ACF 2.1','BCF 2.0') and type in (8,16):
col_preferredmodel = struct.unpack('>H',file.read(2))[0]
swatch['colors'][i]['preferredmodel'] = bcf_model[col_preferredmodel]
swatch['colors'][i]['name'] = struct.unpack('32s',file.read(32))[0].split('\x00', 1)[0]
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Flash Color Set #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
elif format == 'adobe_clr':
file = open(file)
file.seek(16, 1)
nbcolors = struct.unpack('<H',file.read(2))[0]
file.seek(15, 1)
for i in range(nbcolors):
swatch['colors'][i] = {}
file.seek(1, 1)
swatch['colors'][i]['RGBa'] = struct.unpack('4B',file.read(4))
file.seek(2, 1)
swatch['colors'][i]['HSL'] = struct.unpack('<3H',file.read(6))
file.seek(2, 1)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# AutoCAD Color Book #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
elif format == 'autocad_acb':
xml = etree.parse(file).getroot()
swatch['swatch']['name'] = xml.getiterator('bookName')[0].text
if len(xml.getiterator('majorVersion')) > 0:
swatch['swatch']['version'] = xml.getiterator('majorVersion')[0].text+'.'+xml.getiterator('minorVersion')[0].text
nbcolors = len(xml.getiterator('colorEntry'))
swatch['display']['columns'] = 0
i = 0
for colorPage in xml.getiterator('colorPage'):
swatch['display']['columns'] = max(swatch['display']['columns'],len(colorPage.getiterator('colorEntry')))
breaks = []
encrypted = 0
for colorPage in xml.getiterator('colorPage'):
for colorEntry in colorPage.getiterator('colorEntry'):
swatch['colors'][i] = {}
swatch['colors'][i]['name'] = colorEntry.find('colorName').text
if colorEntry.find('RGB8Encrypt'):
encrypted = 1
elif colorEntry.find('RGB8'):
swatch['colors'][i]['RGB'] = (eval(colorEntry.find('RGB8').find('red').text),eval(colorEntry.find('RGB8').find('green').text),eval(colorEntry.find('RGB8').find('blue').text))
i = i+1
if len(colorPage.getiterator('colorEntry')) < swatch['display']['columns'] and i<nbcolors:
breaks.append(i)
if len(breaks)>0:
swatch['display']['breaks'] = breaks
if encrypted == 1:
print "this script can't decode encrypted RGB values"
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# QuarkXPress Color Library #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
elif format == 'quark_qcl':
xml = etree.parse(file).getroot()
swatch['swatch']['name'] = xml.getiterator('file_descriptor')[0].text
swatch['swatch']['copyright'] = xml.getiterator('originator')[0].text
swatch['swatch']['preferredmodel'] = xml.getiterator('default_color_space')[0].text.strip()
name_field_info = xml.getiterator('name_field_info')
swatch['swatch']['name_format'] = {}
for name in name_field_info:
swatch['swatch']['name_format'][eval(name.attrib['format_id'])-1] = name.attrib['long_form']
ui_spec = os.path.dirname(file)+'/'+xml.getiterator('ui_spec')[0].text
if os.path.isfile(ui_spec):
ui = etree.parse(ui_spec).getroot()
swatch['display']['columns'] = eval(ui.getiterator('rows_per_page')[0].text)
breaks = ui.getiterator('column_break')
if len(breaks)>0:
for i in range(len(breaks)):
breaks[i] = eval(breaks[i].text)
swatch['display']['breaks'] = breaks
else:
print 'ui file '+ui_spec+' doesn\'t exist'
fields = xml.getiterator('field_info')
data_format = {}
for field in fields:
data_format[field.attrib['name']] = field.attrib['pos']
colors = xml.getiterator('tr')
i = 0
for color in colors:
swatch['colors'][i] = {}
swatch['colors'][i]['name'] = color.getchildren()[eval(data_format['SAMPLE_ID'])-1].text
if data_format.has_key('NAME_FORMAT_ID') and len(swatch['swatch']['name_format'])> 1:
swatch['colors'][i]['name_format'] = eval(color.getchildren()[eval(data_format['NAME_FORMAT_ID'])-1].text)-1
if data_format.has_key('LAB_L'):
swatch['colors'][i]['Lab'] = (eval(color.getchildren()[eval(data_format['LAB_L'])-1].text),\
eval(color.getchildren()[eval(data_format['LAB_A'])-1].text),\
eval(color.getchildren()[eval(data_format['LAB_B'])-1].text))
if data_format.has_key('RGB_R'):
swatch['colors'][i]['RGB'] = (eval(color.getchildren()[eval(data_format['RGB_R'])-1].text),\
eval(color.getchildren()[eval(data_format['RGB_G'])-1].text),\
eval(color.getchildren()[eval(data_format['RGB_B'])-1].text))
if data_format.has_key('CMYK_C'):
swatch['colors'][i]['CMYK'] = (eval(color.getchildren()[eval(data_format['CMYK_C'])-1].text),\
eval(color.getchildren()[eval(data_format['CMYK_M'])-1].text),\
eval(color.getchildren()[eval(data_format['CMYK_Y'])-1].text),\
eval(color.getchildren()[eval(data_format['CMYK_K'])-1].text))
if data_format.has_key('PC6_1'):
swatch['colors'][i]['PC6'] = (eval(color.getchildren()[eval(data_format['PC6_1'])-1].text),\
eval(color.getchildren()[eval(data_format['PC6_2'])-1].text),\
eval(color.getchildren()[eval(data_format['PC6_3'])-1].text),\
eval(color.getchildren()[eval(data_format['PC6_4'])-1].text),\
eval(color.getchildren()[eval(data_format['PC6_5'])-1].text),\
eval(color.getchildren()[eval(data_format['PC6_6'])-1].text))
i = i+1
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# RAL #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
elif format == 'ral_bcs':
file = open(file)
offset, sig = struct.unpack('B 3s',file.read(4))
if sig == 'clf':
swatch['swatch']['spot'] = 1
file.seek(offset+1, 0)
nbcolors = struct.unpack('<H',file.read(2))[0]
length = struct.unpack('B',file.read(1))[0]
name_tmp = struct.unpack(str(length)+'s',file.read(length))[0].split(':')
swatch['swatch']['name'] = name_tmp[0].split('English_')[1]
if name_tmp[1].split('German_')[1] != swatch['swatch']['name']:
swatch['swatch']['name_de'] = name_tmp[1].split('German_')[1]
file.seek(1, 1)
for i in range(nbcolors):
swatch['colors'][i] = {}
length = struct.unpack('B',file.read(1))[0]
if length > 0:
swatch['colors'][i]['name'] = struct.unpack(str(length)+'s',file.read(length))[0]
swatch['colors'][i]['Lab'] = struct.unpack('<3f',file.read(12))
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# RIFF Palette #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
elif format == 'riff_pal':
file = open(file)
file.seek(12, 0)
chunk = struct.unpack('<4s L', file.read(8))
while chunk[0] != 'data':
file.seek(chunk[1], 1)
chunk = struct.unpack('<4s L', file.read(8))
version, nbcolors = struct.unpack('<2H',file.read(4))
for i in range(nbcolors):
swatch['colors'][i] = {}
swatch['colors'][i]['RGB'] = struct.unpack('3B',file.read(3))
file.seek(1, 1)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# ColorSchemer #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
elif format == 'colorschemer':
file = open(file)
version, nbcolors = struct.unpack('<2H',file.read(4))
file.seek(4, 1)
for i in range(nbcolors):
swatch['colors'][i] = {}
swatch['colors'][i]['RGB'] = struct.unpack('3B',file.read(3))
file.seek(1, 1)
length = struct.unpack('<L',file.read(4))[0]
if length > 0:
swatch['colors'][i]['name'] = struct.unpack(str(length)+'s',file.read(length))[0]
file.seek(11, 1)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# CorelDRAW Palette #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
elif format == 'corel_cpl':
file = open(file)
version = file.read(2)
if version == '\xdc\xdc': #custom palettes
length = struct.unpack('B',file.read(1))[0]
if length > 0:
swatch['swatch']['name'] = struct.unpack(str(length)+'s',file.read(length))[0]
nbcolors = struct.unpack('<H',file.read(2))[0]
elif version in ('\xcc\xbc','\xcc\xdc'):
nbcolors = struct.unpack('<H',file.read(2))[0]
else:
nbheaders = struct.unpack('<L',file.read(4))[0]
headers = {}
for i in range(nbheaders):
id,offset = struct.unpack('<2L',file.read(8))
headers[id] = offset
# Header 0: Name
file.seek(headers[0], 0)
length = struct.unpack('B',file.read(1))[0]
if length > 0:
if version == '\xcd\xdc':
swatch['swatch']['name'] = struct.unpack(str(length)+'s',file.read(length))[0]
else:
swatch['swatch']['name'] = ords2str(struct.unpack('<'+str(length)+'H',file.read(length*2)))
# Header 1: Palette Type
file.seek(headers[1], 0)
type = struct.unpack('<H',file.read(2))[0]
# Header 2: Number of colors
file.seek(headers[2], 0)
nbcolors = struct.unpack('<H',file.read(2))[0]
# Header 3: Custom inks
if 3 in headers:
file.seek(headers[3], 0)
nbinks = struct.unpack('<H',file.read(2))[0]
swatch['swatch']['inks'] = struct.unpack('<'+str(nbinks)+'H',file.read(nbinks*2))
# Header 5: UI informations
if 5 in headers:
file.seek(headers[5], 0)
swatch['display']['columns'],swatch['display']['rows'] = struct.unpack('<2H',file.read(4))
file.seek(headers[2]+2, 0)
if version in ('\xcd\xbc','\xcd\xdc','\xcd\xdd') and type < 38 and type not in(5,16):
long = True
else:
long = False
row = {}
col = {}
breaks = []
for i in range(nbcolors):
swatch['colors'][i] = {}
if long:
file.seek(4, 1)
model = struct.unpack('<H',file.read(2))[0]
file.seek(2, 1)
if model == 2:
file.seek(4, 1)
swatch['colors'][i]['CMYK100'] = struct.unpack('4B',file.read(4))
elif model in (3,12,17):
file.seek(4, 1)
swatch['colors'][i]['CMYK'] = struct.unpack('4B',file.read(4))
elif model == 4:
file.seek(4, 1)
swatch['colors'][i]['CMY'] = struct.unpack('3B',file.read(3))
file.seek(1, 1)
elif model in (5,21):
file.seek(4, 1)
swatch['colors'][i]['RGB'] = struct.unpack('3B',file.read(3))
file.seek(1, 1)
elif model == 6:
file.seek(4, 1)
swatch['colors'][i]['HSB'] = struct.unpack('<H2B',file.read(4))
elif model == 7:
file.seek(4, 1)
swatch['colors'][i]['HLS'] = struct.unpack('<H2B',file.read(4))
elif model == 9:
file.seek(4, 1)
swatch['colors'][i]['Gray'] = struct.unpack('B',file.read(1))
file.seek(3, 1)
elif model == 11:
file.seek(4, 1)
swatch['colors'][i]['YIQ'] = struct.unpack('3B',file.read(3))
file.seek(1, 1)
elif model == 15:
file.seek(2, 1)
swatch['colors'][i]['YOMCGK'] = struct.unpack('6B',file.read(3))
elif model == 5:
file.seek(4, 1)
swatch['colors'][i]['RGB'] = struct.unpack('3B',file.read(3))
file.seek(1, 1)
elif model == 18:
file.seek(4, 1)
swatch['colors'][i]['Lab'] = struct.unpack('3B',file.read(3))
file.seek(1, 1)
else:
file.seek(8, 1)
if long:
model2 = struct.unpack('<H',file.read(2))[0]
file.seek(2, 1)
if model2 == model:
file.seek(8, 1)
else:
if model2 == 2:
file.seek(4, 1)
swatch['colors'][i]['CMYK100'] = struct.unpack('4B',file.read(4))
elif model2 in (3,12,17):
file.seek(4, 1)
swatch['colors'][i]['CMYK'] = struct.unpack('4B',file.read(4))
elif model2 == 4:
file.seek(4, 1)
swatch['colors'][i]['CMY'] = struct.unpack('3B',file.read(3))
file.seek(1, 1)
elif model2 in (5,21):
file.seek(4, 1)
swatch['colors'][i]['RGB'] = struct.unpack('3B',file.read(3))
file.seek(1, 1)
elif model2 == 6:
file.seek(4, 1)
swatch['colors'][i]['HSB'] = struct.unpack('<H2B',file.read(4))
elif model2 == 7:
file.seek(4, 1)
swatch['colors'][i]['HLS'] = struct.unpack('<H2B',file.read(4))
elif model2 == 9:
file.seek(4, 1)
swatch['colors'][i]['Gray'] = struct.unpack('B',file.read(1))
file.seek(3, 1)
elif model2 == 11:
file.seek(4, 1)
swatch['colors'][i]['YIQ'] = struct.unpack('3B',file.read(3))
file.seek(1, 1)
elif model2 == 15:
file.seek(2, 1)
swatch['colors'][i]['YOMCGK'] = struct.unpack('6B',file.read(3))
elif model2 == 5:
file.seek(4, 1)
swatch['colors'][i]['RGB'] = struct.unpack('3B',file.read(3))
file.seek(1, 1)
elif model2 == 18:
file.seek(4, 1)
swatch['colors'][i]['Lab'] = struct.unpack('3B',file.read(3))
file.seek(1, 1)
else:
file.seek(8, 1)
length = struct.unpack('B',file.read(1))[0]
if length > 0:
if version in ('\xdc\xdc','\xcc\xdc') or (version == '\xcd\xdc' and type not in (16)):
swatch['colors'][i]['name'] = struct.unpack(str(length)+'s',file.read(length))[0]
else:
swatch['colors'][i]['name'] = ords2str(struct.unpack('<'+str(length)+'H',file.read(length*2)))
if version == '\xcd\xdd':
row[i], col[i] = struct.unpack('<2L',file.read(8))
if row[i] > 0 and col[i] == 0 and col[i-1] < swatch['display']['columns']-1:
breaks.append(i)
file.seek(4, 1)
if len(breaks)>0:
swatch['display']['breaks'] = breaks
return swatch
def write(content, format, version):
return
def main():
args = sys.argv[1:]
if len(args) != 1:
print 'usage: python test.py inputfile outputformat version'
sys.exit(-1)
file = args[0]
filename = os.path.basename(file)
basename = os.path.splitext(filename)[0]
if not os.path.isfile(file):
print 'file '+file+' doesn\'t exist'
sys.exit(-1)
if os.path.getsize(file) == 0:
print 'empty file'
sys.exit(-1)
print read(file)
if __name__ == '__main__':
main()
_______________________________________________
CREATE mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/create