<commit_before>#!/usr/bin/python3

from mrcrowbar import models as mrc
from mrcrowbar import utils

from PIL import Image

import array
import itertools


class Colour( mrc.Block ):
    _block_size = 0
    r_8 = 0
    g_8 = 0
    b_8 = 0
    a_8 = 255

    @property
    def r( self ):
        return self.r_8/255

    @property
    def g( self ):
        return self.g_8/255

    @property
    def b( self ):
        return self.b_8/255

    @property
    def a( self ):
        return self.a_8/255

    def __str__( self ):
        return '#{:02X}{:02X}{:02X}{:02X}'.format( self.r_8, self.g_8, self.b_8, self.a_8 )

    def __eq__( self, other ):
        return (self.r_8 == other.r_8) and (self.g_8 == other.g_8) and (self.b_8 == other.b_8) and (self.a_8 == other.a_8)

class Transparent( Colour ):
    a_8 = 0


class RGBColour( Colour ):
    _block_size = 3

    r_8 = mrc.UInt8( 0x00 )
    g_8 = mrc.UInt8( 0x01 )
    b_8 = mrc.UInt8( 0x02 )


class RawIndexedImage( mrc.Block ):
    _width =            0
    _height =           0
    _palette =          []

    data = mrc.Bytes( 0x0000 )

    def __init__( self, buffer, width=0, height=0, palette=None, **kwargs ):
        self._width = width
        self._height = height
        if palette is not None:
            self._palette = palette
        #assert len( buffer ) == width*height
        super( RawIndexedImage, self ).__init__( buffer, **kwargs )

    def get_image( self ):
        im = Image.new( 'P', (self._width, self._height) )
        im.putdata( self.data[:self._width*self._height] )
        im.putpalette( itertools.chain( *[(c.r_8, c.g_8, c.b_8) for c in self._palette] ) )
        return im

    def ansi_format( self ):
        result = []
        for y in range( 0, self._height, 2 ):
            for x in range( 0, self._width ):
                p1 = self._palette[self.data[self._width*y + x]]
                p2 = self._palette[self.data[self._width*(y+1) + x]] if (self._width*(y+1) + x) < len( self.data ) else Transparent()
                if p1.a_8 == 0 and p2.a_8 == 0:
                    result.append( u'\x1b[0m ' )
                elif p1 == p2:
                    result.append( u'\x1b[38;2;{};{};{}m█'.format( p1.r_8, p1.g_8, p1.b_8 ) )
                elif p1.a_8 == 0 and p2.a_8 != 0:
                    result.append( u'\x1b[38;2;{};{};{}m▄'.format( p2.r_8, p2.g_8, p2.b_8 ) )
                elif p1.a_8 != 0 and p2.a_8 == 0:
                    result.append( u'\x1b[38;2;{};{};{}m▀'.format( p1.r_8, p1.g_8, p1.b_8 ) )
                else:
                    result.append( u'\x1b[38;2;{};{};{};48;2;{};{};{}m▀\x1b[0m'.format( p1.r_8, p1.g_8, p1.b_8, p2.r_8, p2.g_8, p2.b_8 ) )

            result.append( u'\x1b[0m\n' )
        return u''.join( result )
    
    def print( self ):
        print( self.ansi_format() )

    def __str__( self ):
        return self.ansi_format()<commit_msg>lib.images.base: add range options to ansi_format()<commit_after>#!/usr/bin/python3

from mrcrowbar import models as mrc
from mrcrowbar import utils

from PIL import Image

import array
import itertools


class Colour( mrc.Block ):
    _block_size = 0
    r_8 = 0
    g_8 = 0
    b_8 = 0
    a_8 = 255

    @property
    def r( self ):
        return self.r_8/255

    @property
    def g( self ):
        return self.g_8/255

    @property
    def b( self ):
        return self.b_8/255

    @property
    def a( self ):
        return self.a_8/255

    def __str__( self ):
        return '#{:02X}{:02X}{:02X}{:02X}'.format( self.r_8, self.g_8, self.b_8, self.a_8 )

    def __eq__( self, other ):
        return (self.r_8 == other.r_8) and (self.g_8 == other.g_8) and (self.b_8 == other.b_8) and (self.a_8 == other.a_8)

class Transparent( Colour ):
    a_8 = 0


class RGBColour( Colour ):
    _block_size = 3

    r_8 = mrc.UInt8( 0x00 )
    g_8 = mrc.UInt8( 0x01 )
    b_8 = mrc.UInt8( 0x02 )


class RawIndexedImage( mrc.Block ):
    _width =            0
    _height =           0
    _palette =          []

    data = mrc.Bytes( 0x0000 )

    def __init__( self, buffer, width=0, height=0, palette=None, **kwargs ):
        self._width = width
        self._height = height
        if palette is not None:
            self._palette = palette
        #assert len( buffer ) == width*height
        super( RawIndexedImage, self ).__init__( buffer, **kwargs )

    def get_image( self ):
        im = Image.new( 'P', (self._width, self._height) )
        im.putdata( self.data[:self._width*self._height] )
        im.putpalette( itertools.chain( *[(c.r_8, c.g_8, c.b_8) for c in self._palette] ) )
        return im

    def ansi_format( self, x_start=0, y_start=0, width=None, height=None ):
        assert x_start in range( 0, self._width )
        assert y_start in range( 0, self._height )
        if not width:
            width = self._width-x_start
        if not height:
            height = self._height-y_start
        result = []
        for y in range( 0, height, 2 ):
            for x in range( 0, width ):
                p1 = self._palette[self.data[self._width*(y_start+y) + (x_start+x)]]
                p2 = self._palette[self.data[self._width*(y_start+y+1) + (x_start+x)]] if (self._width*(y_start+y+1) + (x_start+x)) < len( self.data ) else Transparent()
                if p1.a_8 == 0 and p2.a_8 == 0:
                    result.append( u'\x1b[0m ' )
                elif p1 == p2:
                    result.append( u'\x1b[38;2;{};{};{}m█'.format( p1.r_8, p1.g_8, p1.b_8 ) )
                elif p1.a_8 == 0 and p2.a_8 != 0:
                    result.append( u'\x1b[38;2;{};{};{}m▄'.format( p2.r_8, p2.g_8, p2.b_8 ) )
                elif p1.a_8 != 0 and p2.a_8 == 0:
                    result.append( u'\x1b[38;2;{};{};{}m▀'.format( p1.r_8, p1.g_8, p1.b_8 ) )
                else:
                    result.append( u'\x1b[38;2;{};{};{};48;2;{};{};{}m▀\x1b[0m'.format( p1.r_8, p1.g_8, p1.b_8, p2.r_8, p2.g_8, p2.b_8 ) )

            result.append( u'\x1b[0m\n' )
        return u''.join( result )
    
    def print( self, *args, **kwargs ):
        print( self.ansi_format( *args, **kwargs ) )

    def __str__( self ):
        return self.ansi_format()
{'fraction_non_alphanumeric': 0.15138282387190685, 'fraction_numerical': 0.05240174672489083, 'mean_word_length': 1.9019239793524167, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1853429', 'n_tokens_mistral': 2539, 'n_tokens_neox': 2370, 'n_words': 540}