From 27781b18ae400421700a31d6b1ed37d836c47f22 Mon Sep 17 00:00:00 2001 From: Tomas Gavenciak Date: Mon, 1 Aug 2011 21:39:01 +0200 Subject: [PATCH] First batch of gen config changes --- gfxprim_config.py | 93 ++++++++++++++ pylib/gfxprim/generators/__init__.py | 31 +++++ pylib/gfxprim/generators/gfxprimconfig.py | 57 +++++++++ pylib/gfxprim/generators/pixeltype.py | 197 ++++++++++++------------------ pylib/pixeltypes.py | 88 ------------- 5 files changed, 258 insertions(+), 208 deletions(-) create mode 100644 gfxprim_config.py create mode 100644 pylib/gfxprim/generators/gfxprimconfig.py rewrite pylib/gfxprim/generators/pixeltype.py (65%) delete mode 100644 pylib/pixeltypes.py diff --git a/gfxprim_config.py b/gfxprim_config.py new file mode 100644 index 00000000..157f93c8 --- /dev/null +++ b/gfxprim_config.py @@ -0,0 +1,93 @@ +# +# gfxprim_config.py - module configuring GfxPrim code generation and +# known PixelTypes +# + +# +# 2011 - Tomas Gavenciak +# 2011 - Cyril Hrubis +# +# This file is sourced by all the generating scripts. +# Moreover, the generated files are sourced by almost all Gfxprim sources, +# so a complete recompilation is required after any change. +# + +config = GfxPrimConfig( + + # C name and bit-size of the GP_pixel type + pixel_type = "uint32_t", + pixel_size = 32, + + # List of pixel sizes (bpp), explicit on purpose + sizes = [1, 2, 4, 8, 16, 32] + + # bit endians to generate, keep this fixed to LE, BE for now + bit_endians = ['LE', 'BE'] + + # List of PixelTypes, order defines the numbering. + # The "Undefined" type is added automatically. + types = [ + + # + # Standard RGB types + # + + PixelType(name='RGBx8888', size=32, chanslist=[ + ('R', 16, 8), + ('G', 8, 8), + ('B', 0, 8)]), + + PixelType(name='RGBA8888', size=32, chanslist=[ + ('R', 24, 8), + ('G', 16, 8), + ('B', 8, 8), + ('A', 0, 8)]), + + PixelType(name='RGB888', size=24, chanslist=[ + ('R', 16, 8), + ('G', 8, 8), + ('B', 0, 8)]), + + PixelType(name='RGB565', size=16, chanslist=[ + ('R', 11, 5), + ('G', 5, 6), + ('B', 0, 5)]), + + # + # Palette types + # + + PixelType(name='P2', size=2, bit_endian='LE', chanslist=[ + ('P', 0, 2)]), + + PixelType(name='P4', size=4, bit_endian='LE', chanslist=[ + ('P', 0, 4)]), + + PixelType(name='P8', size=8, bit_endian='LE', chanslist=[ + ('P', 0, 8)]), + + # + # Gray-only pixel types + # + + PixelType(name='V1', size=1, bit_endian='LE', chanslist=[ + ('V', 0, 1)]), + + PixelType(name='V2', size=2, bit_endian='LE', chanslist=[ + ('V', 0, 2)]), + + PixelType(name='V4', size=4, bit_endian='LE', chanslist=[ + ('V', 0, 4)]), + + PixelType(name='V8', size=8, bit_endian='LE', chanslist=[ + ('V', 0, 8)]), + + # + # Experiments + # + + PixelType(name='VA12', size=4, bit_endian='BE', chanslist=[ + ('A', 1, 2), + ('V', 3, 1)]), + ] + ) diff --git a/pylib/gfxprim/generators/__init__.py b/pylib/gfxprim/generators/__init__.py index e69de29b..bffe6ea9 100644 --- a/pylib/gfxprim/generators/__init__.py +++ b/pylib/gfxprim/generators/__init__.py @@ -0,0 +1,31 @@ +# +# gfxprim.generate +# + + +# Global config instance + +config = None + + +def load_gfxprim_config(config_file = None): + """Initialize GfxPrimConfig from a given or guessed config file. + Looks for the file by parameter, in env['PIXELTYPE_DEFS'] and + in dir(__file__)/../../../gfxprim_config.py, in that order. + """ + if not defs_file: + defs_file = os.environ.get("PIXELTYPE_DEFS", None) + if not defs_file: + path = os.path.dirname(os.path.abspath(__file__)) + defs_file = os.path.abspath( + os.path.join(path, "..", "..", "..", "gfxprim_config.py")) + if not os.path.exists(defs_file): + sys.stderr.write("WARNING: GfxPrimConfig file %s not found!\n" % defs_file) + + from gfxprim.generate.pixeltype import PixelType + from gfxprim.generate.gfxprimconfig import GfxPrimConfig + l = {"PixelType": PixelType, "GfxPrimConfig": GfxPrimConfig} + execfile(defs_file, globals(), l) + + config = l["config"] + assert config diff --git a/pylib/gfxprim/generators/gfxprimconfig.py b/pylib/gfxprim/generators/gfxprimconfig.py new file mode 100644 index 00000000..60546d08 --- /dev/null +++ b/pylib/gfxprim/generators/gfxprimconfig.py @@ -0,0 +1,57 @@ +# +# gfxprimconfig.py - Class for (global) GfxPrim configuration +# +# 2011 - Tomas Gavenciak + +import re, os, sys + +class GfxPrimConfig(object): + def __init__(self, pixel_type = None, pixel_size=None, sizes=None, + bit_endians=None, types=[]): + + self.pixel_type = pixel_type + assert self.pixel_type + assert isinstance(self.pixel_type, str) + + self.pixel_size = pixel_size + assert isinstance(self.pixel_size, int) + assert self.pixel_size % 8 == 0 + assert self.pixel_size > 0 + + # Allowed bit-sizes of pixel types + self.sizes = sizes + assert isinstance(self.sizes, list) + assert self.pixel_size in self.sizes + assert all(( isinstance(i, int) and i > 0 and i <= self.pixel_size + for i in self.sizes)) + + # bit_endian values + self.bit_endians = bit_endians + assert isinstance(self.bit_endians, list) + assert all(( i in ["LE", "BE"] for i in self.bit_endians)) + + # Set of all encountered channel names + self.channels = set() + + # Dictionary of all pixeltypes { name : PixelType } + self.types_dict = {} + # List of all PixelTypes in order. "Unknown" must be first. + self.types = [] + + self.add_pixeltype(PixelType("UNKNOWN", 0, [], bit_endian=bit_endians[0])) + for t in types: + self.add_pixeltype(t) + + def add_pixeltype(self, pixeltype): + "Add a PixelType and check its against the config" + + assert pixeltype not in self.types + self.types.append(pixeltype) + assert pixeltype.name not in self.types_dict + self.types_dict[pixeltype.name] = pixeltype + self.channels.update(set(pixeltype.chans.keys())) + try: + pixeltype.check_config(self) + except AssertionError: + sys.stderr.write("Error checking PixelType %s\n" % pixeltype.name) + diff --git a/pylib/gfxprim/generators/pixeltype.py b/pylib/gfxprim/generators/pixeltype.py dissimilarity index 65% index 92586ab2..18531fab 100644 --- a/pylib/gfxprim/generators/pixeltype.py +++ b/pylib/gfxprim/generators/pixeltype.py @@ -1,120 +1,77 @@ -# Module with PixelType descrition class -# 2011 - Tomas Gavenciak - -# pixel format: -# type -# - PAL -# - HSVRGBA -# per chan -# name, pos, size -# bitwidth -# name - -import re, os, sys -import gfxprim -from gfxprim import die - -## *Global* dictionary of all pixeltypes { name : PixelType } -pixeltypes = {} - -## *Global* set of all encountered channel names -channels = set() - -## Allowed bit-sizes of pixels -bitsizes = [1,2,4,8,16,24,32] - -## bit_endian values -bit_endians = ['LE', 'BE'] - -## Create pixel-size suffix (16BPP or 4BPP_LE) -def get_size_suffix(bpp, bit_endian): - assert bpp in bitsizes - assert bit_endian in bit_endians - size_suffix = '%dBPP' % (bpp) - if bpp < 8: - size_suffix += '_' + bit_endian - return size_suffix - - -class PixelType(object): - """Representation of one GP_PixelType""" - def __init__(self, name, size, chanslist, number=None, bit_endian=None): - """`name` must be a valid C identifier - `size` is in bits, allowed are 1, 2, 4, 8, 16, 24, 32 - `bit_endian` is order of 1,2,4BPP pixels in a byte, either 'BE' or 'LE' - `chanslist` is a list of triplets describing individual channels as - [ (`chan_name`, `bit_offset`, `bit_size`) ] - `chan_name` is usually one of: R, G, B, V (value, used for grayscale), A (opacity) - `number` is auto-assigned (internal use only) - """ - assert re.match('\A[A-Za-z][A-Za-z0-9_]*\Z', name) - self.name = name - self.chanslist = chanslist - self.chans = dict() # { chan_name: (offset, size) } - # all types except UNKNOWN=0 must have one of these sizes - if number is not 0: - assert(size in bitsizes) - self.size = size - - # bit_endian matters only for 1,2,4bpp - if size>=8 and bit_endian is None: - bit_endian = bit_endians[0] - assert bit_endian in bit_endians - self.bit_endian = bit_endian - - if self.size == 0: - self.size_suffix = "INVALID" - else: - self.size_suffix = get_size_suffix(self.size, self.bit_endian) - - # Numbering from 1 - if number is not None: - self.number = number - else: - self.number = max([ptype.number for ptype in pixeltypes.values()] + [0]) + 1 - - # Verify channel bits for overlaps - # also builds a bit-map of the PixelType - self.bits = ['x']*size - for c in chanslist: - assert c[0] not in self.chans.keys() - self.chans[c[0]] = c - for i in range(c[1],c[1]+c[2]): - assert(i" - - def is_palette(self): - return ('P' in self.chans) - -def load_pixeltypes(defs_file = None): - "Initialize pixeltypes by loading the defs file.\n" - "Looks for the file by parameter, env['PIXELTYPE_DEFS'] and " - "in dir(__file__)/../../pixeltypes.py, in that order.\n" - "PixelType UNKNOWN is not defined here." - if not defs_file: - defs_file = os.environ.get('PIXELTYPE_DEFS', None) - if not defs_file: - path = os.path.dirname(os.path.abspath(__file__)) - defs_file = os.path.join(path, '..', '..', 'pixeltypes.py') - execfile(defs_file) - -def __init__(): - "Initialize PixelType UNKNOWN.\n" - "Currently also reads PIXELTYPE_DEFS, but that may change!" - if 0 not in pixeltypes: - PixelType("UNKNOWN", 0, [], bit_endian=bit_endians[0], number=0) - load_pixeltypes() - # check if some types were loaded - if len(pixeltypes) <= 1: - sys.stderr.write("WARNING: no PixelTypes were loaded.") - -__init__() - +# +# gfxprim.pixeltype - Module with PixelType descrition class +# +# 2011 - Tomas Gavenciak +# + +import re +import os +import sys +import gfxprim +from gfxprim import die + + +def get_size_suffix(self.bpp, bit_endian): + "Create pixel-size suffix (like 16BPP or 4BPP_LE)" + + assert bpp in self.sizes + assert bit_endian in self.bit_endians + size_suffix = '%dBPP' % (bpp) + if bpp < 8: + size_suffix += '_' + bit_endian + return size_suffix + + +class PixelType(object): + """Representation of one GP_PixelType""" + + def __init__(self, name, size, chanslist, bit_endian=None): + """`name` must be a valid C identifier + `size` is type bit-width + `bit_endian` is required in 1,2,4 BPP types to determine the order of + pixels in a byte, either 'BE' or 'LE' + `chanslist` is a list of triplets describing individual channels as + [ (`chan_name`, `bit_offset`, `bit_size`) ] + where `chan_name` is usually one of: R, G, B, + V (value, used for grayscale), A (opacity) + """ + assert re.match('\A[A-Za-z][A-Za-z0-9_]*\Z', name) + self.name = name + self.chanslist = chanslist + self.chans = dict() # { chan_name: (offset, size) } + self.size = size + self.bit_endian = bit_endian + + if self.size == 0: + self.size_suffix = "INVALID" + else: + self.size_suffix = get_size_suffix(self.size, self.bit_endian) + + # Verify channel bits for overlaps + # also builds a bit-map of the PixelType + self.bits = ['x']*size + for c in chanslist: + assert c[0] not in self.chans.keys() + self.chans[c[0]] = c + for i in range(c[1],c[1]+c[2]): + assert(i" + + def is_palette(self): + return ('P' in self.chans) + diff --git a/pylib/pixeltypes.py b/pylib/pixeltypes.py deleted file mode 100644 index b035b6a6..00000000 --- a/pylib/pixeltypes.py +++ /dev/null @@ -1,88 +0,0 @@ -# -# pixeltypes.py - module defining known PixelTypes -# - -# -# 2011 - Tomas Gavenciak -# 2011 - Cyril Hrubis -# -# Every call to PixelType defines one new GP_PixelType, order defines -# the numbering. Undefined type is defined automatically. -# No other functionality than PixelType() should be defined here. -# -# This file is sourced by all the generating scripts. -# Moreover, the generated files are sourced by almost all Gfxprim sources, -# a complete recompilation is required after any change. -# - -# -# Standard RGB types -# - -PixelType(name='RGBx8888', size=32, chanslist=[ - ('R', 16, 8), - ('G', 8, 8), - ('B', 0, 8)]) - - -PixelType(name='RGBA8888', size=32, chanslist=[ - ('R', 24, 8), - ('G', 16, 8), - ('B', 8, 8), - ('A', 0, 8)]) - - -PixelType(name='RGB888', size=24, chanslist=[ - ('R', 16, 8), - ('G', 8, 8), - ('B', 0, 8)]) - - -PixelType(name='RGB565', size=16, chanslist=[ - ('R', 11, 5), - ('G', 5, 6), - ('B', 0, 5)]) - -# -# Palette types -# - -PixelType(name='P2', size=2, bit_endian='LE', chanslist=[ - ('P', 0, 2)]) - - -PixelType(name='P4', size=4, bit_endian='LE', chanslist=[ - ('P', 0, 4)]) - - -PixelType(name='P8', size=8, bit_endian='LE', chanslist=[ - ('P', 0, 8)]) - -# -# Gray-only pixel types -# - -PixelType(name='V1', size=1, bit_endian='LE', chanslist=[ - ('V', 0, 1)]) - - -PixelType(name='V2', size=2, bit_endian='LE', chanslist=[ - ('V', 0, 2)]) - - -PixelType(name='V4', size=4, bit_endian='LE', chanslist=[ - ('V', 0, 4)]) - - -PixelType(name='V8', size=8, bit_endian='LE', chanslist=[ - ('V', 0, 8)]) - - -# -# Experiments -# - -PixelType(name='VA12', size=4, bit_endian='BE', chanslist=[ - ('A', 1, 2), - ('V', 3, 1)]) - -- 2.11.4.GIT