コード例 #1
0
ファイル: operation.py プロジェクト: mozillazg/pypy
def chr(space, w_ascii):
    "Return a string of one character with the given ascii code."
    try:
        char = __builtin__.chr(space.int_w(w_ascii))
    except ValueError:  # chr(out-of-range)
        raise oefmt(space.w_ValueError, "character code not in range(256)")
    return space.wrap(char)
コード例 #2
0
def chr(space, w_ascii):
    "Return a string of one character with the given ascii code."
    try:
        char = __builtin__.chr(space.int_w(w_ascii))
    except ValueError:  # chr(out-of-range)
        raise oefmt(space.w_ValueError, "character code not in range(256)")
    return space.newtext(char)
コード例 #3
0
ファイル: test.py プロジェクト: redforks/spork-compiler
 def test_cover_global_var(self):
     global chr
     self.assertEqual(' ', chr(32))
     chr = 'b'
     self.assertEqual('b', chr)
     import __builtin__ as builtin
     self.assertEqual(' ', builtin.chr(32))
コード例 #4
0
ファイル: operation.py プロジェクト: njues/Sypy
def chr(space, w_ascii):
    "Return a string of one character with the given ascii code."
    try:
        char = __builtin__.chr(space.int_w(w_ascii))
    except ValueError:  # chr(out-of-range)
        raise OperationError(space.w_ValueError,
                             space.wrap("character code not in range(256)"))
    return space.wrap(char)
コード例 #5
0
class Renderer(object):
    '''Object that is responsible for generating the highlighted string.

	:param dict theme_config:
		Main theme configuration.
	:param local_themes:
		Local themes. Is to be used by subclasses from ``.get_theme()`` method, 
		base class only records this parameter to a ``.local_themes`` attribute.
	:param dict theme_kwargs:
		Keyword arguments for ``Theme`` class constructor.
	:param Colorscheme colorscheme:
		Colorscheme object that holds colors configuration.
	:param PowerlineLogger pl:
		Object used for logging.
	:param int ambiwidth:
		Width of the characters with east asian width unicode attribute equal to 
		``A`` (Ambigious).
	:param dict options:
		Various options. Are normally not used by base renderer, but all options 
		are recorded as attributes.
	'''

    segment_info = {
        'environ': os.environ,
        'getcwd': getattr(os, 'getcwdu', os.getcwd),
        'home': os.environ.get('HOME'),
    }
    '''Basic segment info. Is merged with local segment information by 
	``.get_segment_info()`` method. Keys:

	``environ``
		Object containing environment variables. Must define at least the 
		following methods: ``.__getitem__(var)`` that raises ``KeyError`` in 
		case requested environment variable is not present, ``.get(var, 
		default=None)`` that works like ``dict.get`` and be able to be passed to 
		``Popen``.

	``getcwd``
		Function that returns current working directory. Will be called without 
		any arguments, should return ``unicode`` or (in python-2) regular 
		string.

	``home``
		String containing path to home directory. Should be ``unicode`` or (in 
		python-2) regular string or ``None``.
	'''

    character_translations = {ord(' '): NBSP}
    '''Character translations for use in escape() function.
	
	See documentation of ``unicode.translate`` for details.
	'''

    np_character_translations = dict(
        ((i, '^' + chr(i + 0x40)) for i in range(0x20)))
    '''Non-printable character translations

	These are used to transform characters in range 0x00—0x1F into ``^@``, 
	``^A`` and so on. Unilke with ``.escape()`` method (and 
	``character_translations``) result is passed to ``.strwidth()`` method.

	Note: transforms tab into ``^I``.
	'''
    def __init__(self,
                 theme_config,
                 local_themes,
                 theme_kwargs,
                 colorscheme,
                 pl,
                 ambiwidth=1,
                 **options):
        self.__dict__.update(options)
        self.theme_config = theme_config
        theme_kwargs['pl'] = pl
        self.pl = pl
        self.theme = Theme(theme_config=theme_config, **theme_kwargs)
        self.local_themes = local_themes
        self.theme_kwargs = theme_kwargs
        self.colorscheme = colorscheme
        self.width_data = {
            'N': 1,  # Neutral
            'Na': 1,  # Narrow
            'A': ambiwidth,  # Ambigious
            'H': 1,  # Half-width
            'W': 2,  # Wide
            'F': 2,  # Fullwidth
        }

    def strwidth(self, string):
        '''Function that returns string width.
		
		Is used to calculate the place given string occupies when handling 
		``width`` argument to ``.render()`` method. Must take east asian width 
		into account.

		:param unicode string:
			String whose width will be calculated.

		:return: unsigned integer.
		'''
        return sum((0 if combining(symbol) else
                    self.width_data[east_asian_width(symbol)]
                    for symbol in string))

    def get_theme(self, matcher_info):
        '''Get Theme object.
		
		Is to be overridden by subclasses to support local themes, this variant 
		only returns ``.theme`` attribute.

		:param matcher_info:
			Parameter ``matcher_info`` that ``.render()`` method received. 
			Unused.
		'''
        return self.theme

    def shutdown(self):
        '''Prepare for interpreter shutdown. The only job it is supposed to do 
		is calling ``.shutdown()`` method for all theme objects. Should be 
		overridden by subclasses in case they support local themes.
		'''
        self.theme.shutdown()

    def _get_highlighting(self, segment, mode):
        segment['highlight'] = self.colorscheme.get_highlighting(
            segment['highlight_group'], mode, segment.get('gradient_level'))
        if segment['divider_highlight_group']:
            segment['divider_highlight'] = self.colorscheme.get_highlighting(
                segment['divider_highlight_group'], mode)
        else:
            segment['divider_highlight'] = None
        return segment

    def get_segment_info(self, segment_info, mode):
        '''Get segment information.
		
		Must return a dictionary containing at least ``home``, ``environ`` and 
		``getcwd`` keys (see documentation for ``segment_info`` attribute). This 
		implementation merges ``segment_info`` dictionary passed to 
		``.render()`` method with ``.segment_info`` attribute, preferring keys 
		from the former. It also replaces ``getcwd`` key with function returning 
		``segment_info['environ']['PWD']`` in case ``PWD`` variable is 
		available.

		:param dict segment_info:
			Segment information that was passed to ``.render()`` method.

		:return: dict with segment information.
		'''
        r = self.segment_info.copy()
        r['mode'] = mode
        if segment_info:
            r.update(segment_info)
        if 'PWD' in r['environ']:
            r['getcwd'] = lambda: r['environ']['PWD']
        return r

    def render(self,
               mode=None,
               width=None,
               side=None,
               output_raw=False,
               segment_info=None,
               matcher_info=None):
        '''Render all segments.

		When a width is provided, low-priority segments are dropped one at
		a time until the line is shorter than the width, or only segments
		with a negative priority are left. If one or more filler segments are
		provided they will fill the remaining space until the desired width is
		reached.

		:param str mode:
			Mode string. Affects contents (colors and the set of segments) of 
			rendered string.
		:param int width:
			Maximum width text can occupy. May be exceeded if there are too much 
			non-removable segments.
		:param str side:
			One of ``left``, ``right``. Determines which side will be rendered. 
			If not present all sides are rendered.
		:param bool output_raw:
			Changes the output: if this parameter is ``True`` then in place of 
			one string this method outputs a pair ``(colored_string, 
			colorless_string)``.
		:param dict segment_info:
			Segment information. See also ``.get_segment_info()`` method.
		:param matcher_info:
			Matcher information. Is processed in ``.get_theme()`` method.
		'''
        theme = self.get_theme(matcher_info)
        segments = theme.get_segments(
            side, self.get_segment_info(segment_info, mode))

        # Handle excluded/included segments for the current mode
        segments = [
            self._get_highlighting(segment, mode) for segment in segments
            if mode not in segment['exclude_modes'] and
            (not segment['include_modes'] or mode in segment['include_modes'])
        ]

        segments = [
            segment for segment in self._render_segments(theme, segments)
        ]

        if not width:
            # No width specified, so we don't need to crop or pad anything
            return construct_returned_value(
                ''.join([segment['_rendered_hl']
                         for segment in segments]) + self.hlstyle(), segments,
                output_raw)

        # Create an ordered list of segments that can be dropped
        segments_priority = sorted(
            (segment
             for segment in segments if segment['priority'] is not None),
            key=lambda segment: segment['priority'],
            reverse=True)
        while sum([segment['_len'] for segment in segments
                   ]) > width and len(segments_priority):
            segments.remove(segments_priority[0])
            segments_priority.pop(0)

        # Distribute the remaining space on spacer segments
        segments_spacers = [
            segment for segment in segments if segment['width'] == 'auto'
        ]
        if segments_spacers:
            distribute_len, distribute_len_remainder = divmod(
                width - sum([segment['_len'] for segment in segments]),
                len(segments_spacers))
            for segment in segments_spacers:
                if segment['align'] == 'l':
                    segment['_space_right'] += distribute_len
                elif segment['align'] == 'r':
                    segment['_space_left'] += distribute_len
                elif segment['align'] == 'c':
                    space_side, space_side_remainder = divmod(
                        distribute_len, 2)
                    segment['_space_left'] += space_side + space_side_remainder
                    segment['_space_right'] += space_side
            segments_spacers[0]['_space_right'] += distribute_len_remainder

        rendered_highlighted = ''.join([
            segment['_rendered_hl']
            for segment in self._render_segments(theme, segments)
        ]) + self.hlstyle()

        return construct_returned_value(rendered_highlighted, segments,
                                        output_raw)

    def _render_segments(self, theme, segments, render_highlighted=True):
        '''Internal segment rendering method.

		This method loops through the segment array and compares the
		foreground/background colors and divider properties and returns the
		rendered statusline as a string.

		The method always renders the raw segment contents (i.e. without
		highlighting strings added), and only renders the highlighted
		statusline if render_highlighted is True.
		'''
        segments_len = len(segments)

        for index, segment in enumerate(segments):
            segment['_rendered_raw'] = ''
            segment['_rendered_hl'] = ''

            prev_segment = segments[index -
                                    1] if index > 0 else theme.EMPTY_SEGMENT
            next_segment = segments[
                index + 1] if index < segments_len - 1 else theme.EMPTY_SEGMENT
            compare_segment = next_segment if segment[
                'side'] == 'left' else prev_segment
            outer_padding = ' ' if (index == 0 and segment['side'] == 'left'
                                    ) or (index == segments_len - 1 and
                                          segment['side'] == 'right') else ''
            divider_type = 'soft' if compare_segment['highlight'][
                'bg'] == segment['highlight']['bg'] else 'hard'

            divider_raw = theme.get_divider(segment['side'], divider_type)
            divider_spaces = theme.get_spaces()
            divider_highlighted = ''
            contents_raw = segment['contents']
            contents_highlighted = ''
            draw_divider = segment['draw_' + divider_type + '_divider']

            # Pad segments first
            if draw_divider:
                if segment['side'] == 'left':
                    contents_raw = outer_padding + (
                        segment['_space_left'] * ' ') + contents_raw + (
                            (divider_spaces + segment['_space_right']) * ' ')
                else:
                    contents_raw = (
                        (divider_spaces + segment['_space_left']) *
                        ' ') + contents_raw + (segment['_space_right'] *
                                               ' ') + outer_padding
            else:
                if segment['side'] == 'left':
                    contents_raw = outer_padding + (
                        segment['_space_left'] *
                        ' ') + contents_raw + (segment['_space_right'] * ' ')
                else:
                    contents_raw = (
                        segment['_space_left'] * ' ') + contents_raw + (
                            segment['_space_right'] * ' ') + outer_padding

            # Replace spaces with no-break spaces
            divider_raw = divider_raw.replace(' ', NBSP)
            contents_raw = contents_raw.translate(
                self.np_character_translations)

            # Apply highlighting to padded dividers and contents
            if render_highlighted:
                if divider_type == 'soft':
                    divider_highlight_group_key = 'highlight' if segment[
                        'divider_highlight_group'] is None else 'divider_highlight'
                    divider_fg = segment[divider_highlight_group_key]['fg']
                    divider_bg = segment[divider_highlight_group_key]['bg']
                else:
                    divider_fg = segment['highlight']['bg']
                    divider_bg = compare_segment['highlight']['bg']
                divider_highlighted = self.hl(divider_raw, divider_fg,
                                              divider_bg, False)
                contents_highlighted = self.hl(self.escape(contents_raw),
                                               **segment['highlight'])

            # Append padded raw and highlighted segments to the rendered segment variables
            if draw_divider:
                if segment['side'] == 'left':
                    segment['_rendered_raw'] += contents_raw + divider_raw
                    segment[
                        '_rendered_hl'] += contents_highlighted + divider_highlighted
                else:
                    segment['_rendered_raw'] += divider_raw + contents_raw
                    segment[
                        '_rendered_hl'] += divider_highlighted + contents_highlighted
            else:
                if segment['side'] == 'left':
                    segment['_rendered_raw'] += contents_raw
                    segment['_rendered_hl'] += contents_highlighted
                else:
                    segment['_rendered_raw'] += contents_raw
                    segment['_rendered_hl'] += contents_highlighted
            segment['_len'] = self.strwidth(segment['_rendered_raw'])
            yield segment

    @classmethod
    def escape(cls, string):
        '''Method that escapes segment contents.
		'''
        return string.translate(cls.character_translations)

    def hlstyle(fg=None, bg=None, attr=None):
        '''Output highlight style string.

		Assuming highlighted string looks like ``{style}{contents}`` this method 
		should output ``{style}``. If it is called without arguments this method 
		is supposed to reset style to its default.
		'''
        raise NotImplementedError

    def hl(self, contents, fg=None, bg=None, attr=None):
        '''Output highlighted chunk.

		This implementation just outputs ``.hlstyle()`` joined with 
		``contents``.
		'''
        return self.hlstyle(fg, bg, attr) + (contents or '')
コード例 #6
0
ファイル: vim.py プロジェクト: liston/Myvimrc
from powerline.colorscheme import ATTR_BOLD, ATTR_ITALIC, ATTR_UNDERLINE
from powerline.theme import Theme

import vim
import sys


try:
	from __builtin__ import unichr as chr
except ImportError:
	pass


vim_mode = vim_get_func('mode', rettype=str)
mode_translations = {
	chr(ord('V') - 0x40): '^V',
	chr(ord('S') - 0x40): '^S',
}


class VimRenderer(Renderer):
	'''Powerline vim segment renderer.'''

	character_translations = Renderer.character_translations.copy()
	character_translations[ord('%')] = '%%'

	segment_info = Renderer.segment_info.copy()
	segment_info.update(environ=environ)

	def __init__(self, *args, **kwargs):
		if not hasattr(vim, 'strwidth'):
コード例 #7
0
from powerline.colorscheme import ATTR_BOLD, ATTR_ITALIC, ATTR_UNDERLINE
from powerline.theme import Theme

import vim
import sys


try:
	from __builtin__ import unichr as chr
except ImportError:
	pass


vim_mode = vim_get_func('mode', rettype=str)
mode_translations = {
	chr(ord('V') - 0x40): '^V',
	chr(ord('S') - 0x40): '^S',
}


class VimRenderer(Renderer):
	'''Powerline vim segment renderer.'''

	character_translations = Renderer.character_translations.copy()
	character_translations[ord('%')] = '%%'

	def __init__(self, *args, **kwargs):
		if not hasattr(vim, 'strwidth'):
			# Hope nobody want to change this at runtime
			if vim.eval('&ambiwidth') == 'double':
				kwargs = dict(**kwargs)
コード例 #8
0
ファイル: userdecompress.py プロジェクト: KevinSJ/KindleEar
def _decompress(length, resetValue, getNextValue):
    dictionary = {}
    enlargeIn = 4
    dictSize = 4
    numBits = 3
    entry = ""
    result = []

    data = Object(
        val=getNextValue(0),
        position=resetValue,
        index=1
    )

    for i in range(3):
        dictionary[i] = i

    bits = 0
    maxpower = math.pow(2, 2)
    power = 1

    while power != maxpower:
        resb = data.val & data.position
        data.position >>= 1
        if data.position == 0:
            data.position = resetValue
            data.val = getNextValue(data.index)
            data.index += 1

        bits |= power if resb > 0 else 0
        power <<= 1;

    next = bits
    if next == 0:
        bits = 0
        maxpower = math.pow(2, 8)
        power = 1
        while power != maxpower:
            resb = data.val & data.position
            data.position >>= 1
            if data.position == 0:
                data.position = resetValue
                data.val = getNextValue(data.index)
                data.index += 1
            bits |= power if resb > 0 else 0
            power <<= 1
        c = chr(bits)
    elif next == 1:
        bits = 0
        maxpower = math.pow(2, 16)
        power = 1
        while power != maxpower:
            resb = data.val & data.position
            data.position >>= 1
            if data.position == 0:
                data.position = resetValue;
                data.val = getNextValue(data.index)
                data.index += 1
            bits |= power if resb > 0 else 0
            power <<= 1
        c = chr(bits)
    elif next == 2:
        return ""

    dictionary[3] = c
    w = c
    result.append(c)
    counter = 0
    while True:
        counter += 1
        if data.index > length:
            return ""

        bits = 0
        maxpower = math.pow(2, numBits)
        power = 1
        while power != maxpower:
            resb = data.val & data.position
            data.position >>= 1
            if data.position == 0:
                data.position = resetValue;
                data.val = getNextValue(data.index)
                data.index += 1
            bits |= power if resb > 0 else 0
            power <<= 1

        c = bits
        if c == 0:
            bits = 0
            maxpower = math.pow(2, 8)
            power = 1
            while power != maxpower:
                resb = data.val & data.position
                data.position >>= 1
                if data.position == 0:
                    data.position = resetValue
                    data.val = getNextValue(data.index)
                    data.index += 1
                bits |= power if resb > 0 else 0
                power <<= 1

            dictionary[dictSize] = chr(bits)
            dictSize += 1
            c = dictSize - 1
            enlargeIn -= 1
        elif c == 1:
            bits = 0
            maxpower = math.pow(2, 16)
            power = 1
            while power != maxpower:
                resb = data.val & data.position
                data.position >>= 1
                if data.position == 0:
                    data.position = resetValue;
                    data.val = getNextValue(data.index)
                    data.index += 1
                bits |= power if resb > 0 else 0
                power <<= 1
            dictionary[dictSize] = chr(bits)
            dictSize += 1
            c = dictSize - 1
            enlargeIn -= 1
        elif c == 2:
            return "".join(result)

        if enlargeIn == 0:
            enlargeIn = math.pow(2, numBits)
            numBits += 1

        if c in dictionary:
            entry = dictionary[c]
        else:
            if c == dictSize:
                entry = w + w[0]
            else:
                return None
        result.append(entry)

        # Add w+entry[0] to the dictionary.
        dictionary[dictSize] = w + entry[0]
        dictSize += 1
        enlargeIn -= 1

        w = entry
        if enlargeIn == 0:
            enlargeIn = math.pow(2, numBits)
            numBits += 1
コード例 #9
0
def _decompress(length, resetValue, getNextValue):
    dictionary = {}
    enlargeIn = 4
    dictSize = 4
    numBits = 3
    entry = ""
    result = []

    data = Object(val=getNextValue(0), position=resetValue, index=1)

    for i in range(3):
        dictionary[i] = i

    bits = 0
    maxpower = math.pow(2, 2)
    power = 1

    while power != maxpower:
        resb = data.val & data.position
        data.position >>= 1
        if data.position == 0:
            data.position = resetValue
            data.val = getNextValue(data.index)
            data.index += 1

        bits |= power if resb > 0 else 0
        power <<= 1

    next = bits
    if next == 0:
        bits = 0
        maxpower = math.pow(2, 8)
        power = 1
        while power != maxpower:
            resb = data.val & data.position
            data.position >>= 1
            if data.position == 0:
                data.position = resetValue
                data.val = getNextValue(data.index)
                data.index += 1
            bits |= power if resb > 0 else 0
            power <<= 1
        c = chr(bits)
    elif next == 1:
        bits = 0
        maxpower = math.pow(2, 16)
        power = 1
        while power != maxpower:
            resb = data.val & data.position
            data.position >>= 1
            if data.position == 0:
                data.position = resetValue
                data.val = getNextValue(data.index)
                data.index += 1
            bits |= power if resb > 0 else 0
            power <<= 1
        c = chr(bits)
    elif next == 2:
        return ""

    dictionary[3] = c
    w = c
    result.append(c)
    counter = 0
    while True:
        counter += 1
        if data.index > length:
            return ""

        bits = 0
        maxpower = math.pow(2, numBits)
        power = 1
        while power != maxpower:
            resb = data.val & data.position
            data.position >>= 1
            if data.position == 0:
                data.position = resetValue
                data.val = getNextValue(data.index)
                data.index += 1
            bits |= power if resb > 0 else 0
            power <<= 1

        c = bits
        if c == 0:
            bits = 0
            maxpower = math.pow(2, 8)
            power = 1
            while power != maxpower:
                resb = data.val & data.position
                data.position >>= 1
                if data.position == 0:
                    data.position = resetValue
                    data.val = getNextValue(data.index)
                    data.index += 1
                bits |= power if resb > 0 else 0
                power <<= 1

            dictionary[dictSize] = chr(bits)
            dictSize += 1
            c = dictSize - 1
            enlargeIn -= 1
        elif c == 1:
            bits = 0
            maxpower = math.pow(2, 16)
            power = 1
            while power != maxpower:
                resb = data.val & data.position
                data.position >>= 1
                if data.position == 0:
                    data.position = resetValue
                    data.val = getNextValue(data.index)
                    data.index += 1
                bits |= power if resb > 0 else 0
                power <<= 1
            dictionary[dictSize] = chr(bits)
            dictSize += 1
            c = dictSize - 1
            enlargeIn -= 1
        elif c == 2:
            return "".join(result)

        if enlargeIn == 0:
            enlargeIn = math.pow(2, numBits)
            numBits += 1

        if c in dictionary:
            entry = dictionary[c]
        else:
            if c == dictSize:
                entry = w + w[0]
            else:
                return None
        result.append(entry)

        # Add w+entry[0] to the dictionary.
        dictionary[dictSize] = w + entry[0]
        dictSize += 1
        enlargeIn -= 1

        w = entry
        if enlargeIn == 0:
            enlargeIn = math.pow(2, numBits)
            numBits += 1
コード例 #10
0
ファイル: dxtc.py プロジェクト: shuge/pilgrim
def decodeDXT3(data):
    """
    input: one "row" of data (i.e. will produce 4*width pixels)
    """

    blocks = len(data) // 16  # number of blocks in row
    finalColor = [b"", b"", b"", b""]  # row accumulators

    for block in xrange(blocks):
        block = data[block*16:block*16+16]
        # Decode next 16-byte block.
        bits = unpack(b"<8B", block[:8])
        color0, color1 = unpack(b"<HH", block[8:12])

        code, = unpack(b"<I", block[12:])

        # color 0, packed 5-6-5
        r0 = ((color0 >> 11) & 0x1f) << 3
        g0 = ((color0 >> 5) & 0x3f) << 2
        b0 = (color0 & 0x1f) << 3

        # color 1, packed 5-6-5
        r1 = ((color1 >> 11) & 0x1f) << 3
        g1 = ((color1 >> 5) & 0x3f) << 2
        b1 = (color1 & 0x1f) << 3
        for j in xrange(4):
            high = False # Do we want the higher bits?
            for i in xrange(4):
                if high:
                    high = False
                else:
                    high = True
                alphaCodeIndex = (4*j+i) / 2
                finalAlpha = bits[alphaCodeIndex]
                if high:
                    finalAlpha &= 0xf
                else:
                    finalAlpha >>= 4
                finalAlpha *= 17 # We get a value between 0 and 15

                colorCode = (code >> 2*(4*j+i)) & 0x03

                if colorCode == 0:
                    finalColor[j] += chr(r0) + chr(g0) + chr(b0) + chr(finalAlpha)
                elif colorCode == 1:
                    finalColor[j] += chr(r1) + chr(g1) +  chr(b1) + chr(finalAlpha)
                elif colorCode == 2:
                    finalColor[j] += chr((2*r0+r1)//3) + chr((2*g0+g1)//3) + chr((2*b0+b1)//3) + chr(finalAlpha)
                elif colorCode == 3:
                    finalColor[j] += chr((r0+2*r1)//3) + chr((g0+2*g1)//3) + chr((b0+2*b1)//3) + chr(finalAlpha)
    return tuple(finalColor)
コード例 #11
0
ファイル: dxtc.py プロジェクト: shuge/pilgrim
def decodeDXT1(data, alpha=False):
    """
    input: one "row" of data (i.e. will produce 4*width pixels)
    """

    blocks = len(data) // 8  # number of blocks in row
    finalColor = [b"", b"", b"", b""]  # row accumulators

    for block in xrange(blocks):
        # Decode next 8-byte block.
        color0, color1, bits = unpack(b"<HHI", data[block * 8 : block * 8 + 8])

        # color 0, packed 5-6-5
        r0 = ((color0 >> 11) & 0x1f) << 3
        g0 = ((color0 >> 5) & 0x3f) << 2
        b0 = (color0 & 0x1f) << 3

        # color 1, packed 5-6-5
        r1 = ((color1 >> 11) & 0x1f) << 3
        g1 = ((color1 >> 5) & 0x3f) << 2
        b1 = (color1 & 0x1f) << 3

        # Decode this block into 4x4 pixels
        # Accumulate the results onto our 4 row accumulators
        for j in xrange(4):
            for i in xrange(4):
                # get next control op and generate a pixel

                control = bits & 3
                bits = bits >> 2
                if control == 0:
                    finalColor[j] += chr(r0) + chr(g0) + chr(b0)
                elif control == 1:
                    finalColor[j] += chr(r1) + chr(g1) + chr(b1)
                elif control == 2:
                    if color0 > color1:
                        finalColor[j] += chr((2 * r0 + r1) // 3) + chr((2 * g0 + g1) // 3) + chr((2 * b0 + b1) // 3)
                    else:
                        finalColor[j] += chr((r0 + r1) // 2) + chr((g0 + g1) // 2) + chr((b0 + b1) // 2)
                elif control == 3:
                    if color0 > color1:
                        finalColor[j] += chr((2 * r1 + r0) // 3) + chr((2 * g1 + g0) // 3) + chr((2 * b1 + b0) // 3)
                    else:
                        if alpha:
                            finalColor[j] += b"\0\0\0\0"
                            continue
                        else:
                            finalColor[j] += b"\0\0\0"
                if alpha:
                    finalColor[j] += chr(0xFF)

    return tuple(finalColor)
コード例 #12
0
ファイル: dxtc.py プロジェクト: shuge/pilgrim
def decodeDXT5(data):
    """
    input: one "row" of data (i.e. will produce 4*width pixels)
    """

    blocks = len(data) // 16  # number of blocks in row
    finalColor = [b"", b"", b"", b""]  # row accumulators

    for block in xrange(blocks):
        block = data[block * 16 : block * 16 + 16]
        # Decode next 16-byte block.
        alpha0, alpha1 = unpack(b"<BB", block[:2])

        bits = unpack(b"<6B", block[2:8])
        alphaCode1 = bits[2] | (bits[3] << 8) | (bits[4] << 16) | (bits[5] << 24)
        alphaCode2 = bits[0] | (bits[1] << 8)

        color0, color1 = unpack(b"<HH", block[8:12])

        code, = unpack(b"<I", block[12:])

        # color 0, packed 5-6-5
        r0 = ((color0 >> 11) & 0x1f) << 3
        g0 = ((color0 >> 5) & 0x3f) << 2
        b0 = (color0 & 0x1f) << 3

        # color 1, packed 5-6-5
        r1 = ((color1 >> 11) & 0x1f) << 3
        g1 = ((color1 >> 5) & 0x3f) << 2
        b1 = (color1 & 0x1f) << 3

        for j in xrange(4):
            for i in xrange(4):
                # get next control op and generate a pixel
                alphaCodeIndex = 3*(4*j+i)

                if alphaCodeIndex <= 12:
                    alphaCode = (alphaCode2 >> alphaCodeIndex) & 0x07
                elif alphaCodeIndex == 15:
                    alphaCode = (alphaCode2 >> 15) | ((alphaCode1 << 1) & 0x06)
                else: # alphaCodeIndex >= 18 and alphaCodeIndex <= 45
                    alphaCode = (alphaCode1 >> (alphaCodeIndex - 16)) & 0x07

                if alphaCode == 0:
                    finalAlpha = alpha0
                elif alphaCode == 1:
                    finalAlpha = alpha1
                else:
                    if alpha0 > alpha1:
                        finalAlpha = ((8-alphaCode)*alpha0 + (alphaCode-1)*alpha1)/7
                    else:
                        if alphaCode == 6:
                            finalAlpha = 0
                        elif alphaCode == 7:
                            finalAlpha = 255
                        else:
                            finalAlpha = ((6-alphaCode)*alpha0 + (alphaCode-1)*alpha1)/5

                colorCode = (code >> 2*(4*j+i)) & 0x03

                if colorCode == 0:
                    finalColor[j] += chr(r0) + chr(g0) + chr(b0) + chr(finalAlpha)
                elif colorCode == 1:
                    finalColor[j] += chr(r1) + chr(g1) +  chr(b1) + chr(finalAlpha)
                elif colorCode == 2:
                    finalColor[j] += chr((2 * r0 + r1) // 3) + chr((2 * g0+g1) // 3) + chr((2 * b0 + b1) // 3 ) + chr(finalAlpha)
                elif colorCode == 3:
                    finalColor[j] += chr((r0 + 2 * r1) // 3) + chr((g0 + 2*g1) // 3) + chr((b0 + 2 * b1) // 3 ) + chr(finalAlpha)

    return tuple(finalColor)