#    Copyright (C) 2011 Jeremy S. Sanders
#    Email: Jeremy Sanders <jeremy@jeremysanders.net>
#
#    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 2 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 re

import numpy as N

from .. import qtall as qt
from ..helpers.qtloops import numpyToQImage, applyImageTransparancy

# Default colormaps used by widgets.
# Each item in this dict is a colormap entry, with the key the name.

# The values in the dict are tuples of (B, G, R, alpha).  B, G, R and
# alpha go from 0 to 255

# Colors are linearly interpolated in this space, unless they start
# with (-1,0,0,0) which enables a step mode (this first value is
# ignored)

_defaultmaps = {
    'blank': (
        (0,   0,   0,   0),
        (0,   0,   0,   0),
    ),
    'heat': (
        (0,   0,   0,   255),
        (0,   0,   186, 255),
        (50,  139, 255, 255),
        (19,  239, 248, 255),
        (255, 255, 255, 255),
    ),
    'spectrum2': (
        (0,   0,   255, 255),
        (0,   255, 255, 255),
        (0,   255, 0,   255),
        (255, 255, 0,   255),
        (255, 0,   0,   255),
    ),
    'spectrum2-step': (
        (-1,  0,   0,   0),
        (0,   0,   255, 255),
        (0,   255, 255, 255),
        (0,   255, 0,   255),
        (255, 255, 0,   255),
        (255, 0,   0,   255),
    ),
    'spectrum': (
        (0,   0,   0,   255),
        (0,   0,   255, 255),
        (0,   255, 255, 255),
        (0,   255, 0,   255),
        (255, 255, 0,   255),
        (255, 0,   0,   255),
        (255, 255, 255, 255),
    ),
    'grey': (
        (0,   0,   0,   255),
        (255, 255, 255, 255),
    ),
    'blue': (
        (0,   0,   0,   255),
        (255, 0,   0,   255),
        (255, 255, 255, 255),
    ),
    'red': (
        (0,   0,   0,   255),
        (0,   0,   255, 255),
        (255, 255, 255, 255),
    ),
    'green': (
        (0,   0,   0,   255),
        (0,   255, 0,   255),
        (255, 255, 255, 255),
    ),
    'bluegreen': (
        (0,   0,   0,   255),
        (255, 123, 0,   255),
        (255, 226, 72,  255),
        (161, 255, 0,   255),
        (255, 255, 255, 255),
    ),
    'transblack': (
        (0,   0,   0,   255),
        (0,   0,   0,   0),
    ),
    'royal': (
        (0,   0,   0,   255),
        (128, 0,   0,   255),
        (255, 0,   128, 255),
        (0,   255, 255, 255),
        (255, 255, 255, 255),
    ),
    'complement': (
        (0,   0,   0,   255),
        (0,   255, 0,   255),
        (255, 0,   255, 255),
        (0,   0,   255, 255),
        (0,   255, 255, 255),
        (255, 255, 255, 255),
    ),

    # from http://www.kennethmoreland.com/color-maps/
    'cool-warm': (
        (59, 76, 192, 255),
        (68, 90, 204, 255),
        (77, 104, 215, 255),
        (87, 117, 225, 255),
        (98, 130, 234, 255),
        (108, 142, 241, 255),
        (119, 154, 247, 255),
        (130, 165, 251, 255),
        (141, 176, 254, 255),
        (152, 185, 255, 255),
        (163, 194, 255, 255),
        (174, 201, 253, 255),
        (184, 208, 249, 255),
        (194, 213, 244, 255),
        (204, 217, 238, 255),
        (213, 219, 230, 255),
        (221, 221, 221, 255),
        (229, 216, 209, 255),
        (236, 211, 197, 255),
        (241, 204, 185, 255),
        (245, 196, 173, 255),
        (247, 187, 160, 255),
        (247, 177, 148, 255),
        (247, 166, 135, 255),
        (244, 154, 123, 255),
        (241, 141, 111, 255),
        (236, 127, 99, 255),
        (229, 112, 88, 255),
        (222, 96, 77, 255),
        (213, 80, 66, 255),
        (203, 62, 56, 255),
        (192, 40, 47, 255),
        (180, 4, 38, 255),
    ),

    # from http://geog.uoregon.edu/datagraphics/color_scales.htm
    'green-magenta': (
        (0, 80, 0, 255),
        (0, 134, 0, 255),
        (0, 187, 0, 255),
        (0, 241, 0, 255),
        (80, 255, 80, 255),
        (134, 255, 134, 255),
        (187, 255, 187, 255),
        (255, 255, 255, 255),
        (255, 241, 255, 255),
        (255, 187, 255, 255),
        (255, 134, 255, 255),
        (255, 80, 255, 255),
        (241, 0, 241, 255),
        (187, 0, 187, 255),
        (134, 0, 134, 255),
        (80, 0, 80, 255)
    ),

    'blue-darkred': (
        (216, 0, 36, 255),
        (247, 28, 24, 255),
        (255, 87, 40, 255),
        (255, 135, 61, 255),
        (255, 176, 86, 255),
        (255, 211, 117, 255),
        (255, 234, 153, 255),
        (255, 249, 188, 255),
        (255, 255, 234, 255),
        (234, 255, 255, 255),
        (188, 241, 255, 255),
        (153, 214, 255, 255),
        (117, 172, 255, 255),
        (86, 120, 255, 255),
        (61, 61, 255, 255),
        (53, 39, 247, 255),
        (47, 21, 216, 255),
        (33, 0, 165, 255)
    ),

    'blue-darkorange': (
        (102, 102, 0, 255),
        (153, 153, 0, 255),
        (204, 204, 0, 255),
        (255, 255, 0, 255),
        (255, 255, 51, 255),
        (255, 255, 101, 255),
        (255, 255, 153, 255),
        (255, 255, 178, 255),
        (255, 255, 203, 255),
        (255, 255, 229, 255),
        (203, 229, 255, 255),
        (153, 202, 255, 255),
        (101, 173, 255, 255),
        (51, 142, 255, 255),
        (0, 110, 255, 255),
        (0, 85, 204, 255),
        (0, 61, 153, 255),
        (0, 39, 102, 255)
    ),

    'brown-blue': (
        (0, 25, 51, 255),
        (0, 47, 102, 255),
        (53, 96, 153, 255),
        (122, 155, 204, 255),
        (151, 175, 216, 255),
        (205, 218, 242, 255),
        (255, 253, 204, 255),
        (255, 248, 153, 255),
        (255, 239, 101, 255),
        (255, 227, 50, 255),
        (204, 169, 0, 255),
        (153, 122, 0, 255)
    ),

    'blue-orange': (
        (255, 42, 0, 255),
        (255, 101, 25, 255),
        (255, 153, 50, 255),
        (255, 204, 101, 255),
        (255, 237, 153, 255),
        (255, 255, 204, 255),
        (204, 255, 255, 255),
        (153, 238, 255, 255),
        (101, 204, 255, 255),
        (50, 153, 255, 255),
        (25, 102, 255, 255),
        (0, 42, 255, 255)
    ),

    'seq': (
        (15, 15, 153, 255),
        (44, 44, 178, 255),
        (81, 81, 204, 255),
        (126, 126, 229, 255),
        (178, 178, 255, 255),
        (15, 84, 153, 255),
        (44, 111, 178, 255),
        (81, 142, 204, 255),
        (126, 177, 229, 255),
        (178, 216, 255, 255),
        (15, 153, 107, 255),
        (44, 178, 133, 255),
        (81, 204, 163, 255),
        (126, 229, 195, 255),
        (178, 255, 229, 255),
        (153, 107, 15, 255),
        (178, 133, 44, 255),
        (204, 163, 81, 255),
        (229, 195, 126, 255),
        (255, 229, 178, 255),
        (153, 15, 38, 255),
        (178, 44, 66, 255),
        (204, 81, 101, 255),
        (229, 126, 143, 255),
        (255, 178, 191, 255),
    ),

    # from https://github.com/visit-vis/VisIt/blob/master/avt/Pipeline/Data/avtColorTables.C
    'hot_desaturated': (
        (219, 71,  71,  255),
        (91,  0,   0,   255),
        (255, 255, 0,   255),
        (0,   127, 0,   255),
        (0,   255, 255, 255),
        (0,   96,  255, 255),
        (0,   0,   107, 255),
        (76,  76,  224, 255),
    ),

    # exported from VisIt color table (http://www.visitusers.org)
    'yellow-green': (
        (229, 255, 255, 255),
        (185, 252, 247, 255),
        (163, 240, 217, 255),
        (142, 221, 173, 255),
        (121, 198, 120, 255),
        (93,  171, 65,  255),
        (67,  132, 35,  255),
        (55,  104, 0,   255),
        (41,  69,  0,   255),
    ),
    'yellow-green-blue': (
        (217, 255, 255, 255),
        (177, 248, 237, 255),
        (180, 233, 199, 255),
        (187, 205, 127, 255),
        (196, 182, 65,  255),
        (192, 145, 29,  255),
        (168, 94,  34,  255),
        (148, 52,  37,  255),
        (88,  29,  8,   255),
    ),
    'yellow-orange-brown': (
        (229, 255, 255, 255),
        (188, 247, 255, 255),
        (145, 227, 254, 255),
        (79,  196, 254, 255),
        (41,  153, 254, 255),
        (20,  112, 236, 255),
        (2,   76,  204, 255),
        (4,   52,  153, 255),
        (6,   37,  102, 255),
    ),
    'yellow-orange-red': (
        (204, 255, 255, 255),
        (160, 237, 255, 255),
        (118, 217, 254, 255),
        (76,  178, 254, 255),
        (60,  141, 253, 255),
        (42,  78,  252, 255),
        (28,  26,  227, 255),
        (38,  0,   189, 255),
        (38,  0,   128, 255),
    ),

    # https://iamkate.com/data/12-bit-rainbow/
    'rainbow-12bit': (
        (0x77, 0x11, 0x88, 0xff),
        (0x55, 0x33, 0xaa, 0xff),
        (0x66, 0x66, 0xcc, 0xff),
        (0x44, 0x99, 0xee, 0xff),
        (0x00, 0xdd, 0xee, 0xff),
        (0x55, 0xdd, 0x99, 0xff),
        (0x88, 0xdd, 0x44, 0xff),
        (0xbb, 0xcc, 0x22, 0xff),
        (0xcc, 0xbb, 0x00, 0xff),
        (0xcc, 0x99, 0x00, 0xff),
        (0xbb, 0x66, 0x33, 0xff),
        (0x99, 0x33, 0x66, 0xff),
    ),

    'none': (
        (255, 255, 255, 255),
    ),
}

# BBGGRRAA values encoded as string for convenience
# def fmtb(x):
#   return '\\x%02x\\x%02x\\x%02x\\xff' % (x[2],x[1],x[0])
# for i in range(256//4):
#   print("b'%s'" % ''.join((fmtb(a[i*4+j]) for j in range(4))))
_defaultmaps_enc = {
    'inferno': (
        b'\x03\x00\x00\xff\x04\x00\x00\xff\x06\x00\x00\xff\x07\x00\x01\xff'
        b'\x09\x01\x01\xff\x0b\x01\x01\xff\x0e\x01\x02\xff\x10\x02\x02\xff'
        b'\x12\x02\x03\xff\x14\x03\x04\xff\x16\x03\x04\xff\x18\x04\x05\xff'
        b'\x1b\x04\x06\xff\x1d\x05\x07\xff\x1f\x06\x08\xff\x21\x06\x09\xff'
        b'\x23\x07\x0a\xff\x26\x07\x0b\xff\x28\x08\x0d\xff\x2a\x08\x0e\xff'
        b'\x2d\x09\x0f\xff\x2f\x09\x10\xff\x32\x0a\x12\xff\x34\x0a\x13\xff'
        b'\x36\x0b\x14\xff\x39\x0b\x16\xff\x3b\x0b\x17\xff\x3e\x0b\x19\xff'
        b'\x40\x0b\x1a\xff\x43\x0c\x1c\xff\x45\x0c\x1d\xff\x47\x0c\x1f\xff'
        b'\x4a\x0c\x20\xff\x4c\x0b\x22\xff\x4e\x0b\x24\xff\x50\x0b\x26\xff'
        b'\x52\x0b\x27\xff\x54\x0b\x29\xff\x56\x0a\x2b\xff\x58\x0a\x2d\xff'
        b'\x5a\x0a\x2e\xff\x5c\x0a\x30\xff\x5d\x09\x32\xff\x5f\x09\x34\xff'
        b'\x60\x09\x35\xff\x61\x09\x37\xff\x62\x09\x39\xff\x64\x09\x3b\xff'
        b'\x65\x09\x3c\xff\x66\x09\x3e\xff\x66\x09\x40\xff\x67\x09\x41\xff'
        b'\x68\x0a\x43\xff\x69\x0a\x45\xff\x69\x0a\x46\xff\x6a\x0b\x48\xff'
        b'\x6a\x0b\x4a\xff\x6b\x0c\x4b\xff\x6b\x0c\x4d\xff\x6c\x0d\x4f\xff'
        b'\x6c\x0d\x50\xff\x6c\x0e\x52\xff\x6d\x0e\x53\xff\x6d\x0f\x55\xff'
        b'\x6d\x0f\x57\xff\x6d\x10\x58\xff\x6d\x11\x5a\xff\x6e\x11\x5b\xff'
        b'\x6e\x12\x5d\xff\x6e\x12\x5f\xff\x6e\x13\x60\xff\x6e\x14\x62\xff'
        b'\x6e\x14\x63\xff\x6e\x15\x65\xff\x6e\x15\x66\xff\x6e\x16\x68\xff'
        b'\x6e\x17\x6a\xff\x6e\x17\x6b\xff\x6e\x18\x6d\xff\x6e\x18\x6e\xff'
        b'\x6e\x19\x70\xff\x6d\x19\x72\xff\x6d\x1a\x73\xff\x6d\x1b\x75\xff'
        b'\x6d\x1b\x76\xff\x6d\x1c\x78\xff\x6d\x1c\x7a\xff\x6c\x1d\x7b\xff'
        b'\x6c\x1d\x7d\xff\x6c\x1e\x7e\xff\x6b\x1f\x80\xff\x6b\x1f\x81\xff'
        b'\x6b\x20\x83\xff\x6a\x20\x85\xff\x6a\x21\x86\xff\x6a\x21\x88\xff'
        b'\x69\x22\x89\xff\x69\x22\x8b\xff\x69\x23\x8d\xff\x68\x24\x8e\xff'
        b'\x68\x24\x90\xff\x67\x25\x91\xff\x67\x25\x93\xff\x66\x26\x95\xff'
        b'\x66\x26\x96\xff\x65\x27\x98\xff\x64\x28\x99\xff\x64\x28\x9b\xff'
        b'\x63\x29\x9c\xff\x63\x29\x9e\xff\x62\x2a\xa0\xff\x61\x2b\xa1\xff'
        b'\x61\x2b\xa3\xff\x60\x2c\xa4\xff\x5f\x2c\xa6\xff\x5f\x2d\xa7\xff'
        b'\x5e\x2e\xa9\xff\x5d\x2e\xab\xff\x5c\x2f\xac\xff\x5b\x30\xae\xff'
        b'\x5b\x31\xaf\xff\x5a\x31\xb1\xff\x59\x32\xb2\xff\x58\x33\xb4\xff'
        b'\x57\x33\xb5\xff\x56\x34\xb7\xff\x56\x35\xb8\xff\x55\x36\xba\xff'
        b'\x54\x37\xbb\xff\x53\x37\xbd\xff\x52\x38\xbe\xff\x51\x39\xbf\xff'
        b'\x50\x3a\xc1\xff\x4f\x3b\xc2\xff\x4e\x3c\xc4\xff\x4d\x3d\xc5\xff'
        b'\x4c\x3e\xc7\xff\x4b\x3e\xc8\xff\x4a\x3f\xc9\xff\x49\x40\xcb\xff'
        b'\x48\x41\xcc\xff\x47\x42\xcd\xff\x46\x44\xcf\xff\x44\x45\xd0\xff'
        b'\x43\x46\xd1\xff\x42\x47\xd2\xff\x41\x48\xd4\xff\x40\x49\xd5\xff'
        b'\x3f\x4a\xd6\xff\x3e\x4b\xd7\xff\x3d\x4d\xd9\xff\x3b\x4e\xda\xff'
        b'\x3a\x4f\xdb\xff\x39\x50\xdc\xff\x38\x52\xdd\xff\x37\x53\xde\xff'
        b'\x36\x54\xdf\xff\x34\x56\xe0\xff\x33\x57\xe2\xff\x32\x58\xe3\xff'
        b'\x31\x5a\xe4\xff\x30\x5b\xe5\xff\x2e\x5c\xe6\xff\x2d\x5e\xe6\xff'
        b'\x2c\x5f\xe7\xff\x2b\x61\xe8\xff\x2a\x62\xe9\xff\x28\x64\xea\xff'
        b'\x27\x65\xeb\xff\x26\x67\xec\xff\x25\x68\xed\xff\x23\x6a\xed\xff'
        b'\x22\x6c\xee\xff\x21\x6d\xef\xff\x1f\x6f\xf0\xff\x1e\x70\xf0\xff'
        b'\x1d\x72\xf1\xff\x1c\x74\xf2\xff\x1a\x75\xf2\xff\x19\x77\xf3\xff'
        b'\x18\x79\xf3\xff\x16\x7a\xf4\xff\x15\x7c\xf5\xff\x14\x7e\xf5\xff'
        b'\x12\x80\xf6\xff\x11\x81\xf6\xff\x10\x83\xf7\xff\x0e\x85\xf7\xff'
        b'\x0d\x87\xf8\xff\x0c\x88\xf8\xff\x0b\x8a\xf8\xff\x09\x8c\xf9\xff'
        b'\x08\x8e\xf9\xff\x08\x90\xf9\xff\x07\x91\xfa\xff\x06\x93\xfa\xff'
        b'\x06\x95\xfa\xff\x06\x97\xfa\xff\x06\x99\xfb\xff\x06\x9b\xfb\xff'
        b'\x06\x9d\xfb\xff\x07\x9e\xfb\xff\x07\xa0\xfb\xff\x08\xa2\xfb\xff'
        b'\x0a\xa4\xfb\xff\x0b\xa6\xfb\xff\x0d\xa8\xfb\xff\x0e\xaa\xfb\xff'
        b'\x10\xac\xfb\xff\x12\xae\xfb\xff\x14\xb0\xfb\xff\x16\xb1\xfb\xff'
        b'\x18\xb3\xfb\xff\x1a\xb5\xfb\xff\x1c\xb7\xfb\xff\x1e\xb9\xfb\xff'
        b'\x21\xbb\xfa\xff\x23\xbd\xfa\xff\x25\xbf\xfa\xff\x28\xc1\xfa\xff'
        b'\x2a\xc3\xf9\xff\x2c\xc5\xf9\xff\x2f\xc7\xf9\xff\x31\xc9\xf8\xff'
        b'\x34\xcb\xf8\xff\x37\xcd\xf8\xff\x3a\xcf\xf7\xff\x3c\xd1\xf7\xff'
        b'\x3f\xd3\xf6\xff\x42\xd5\xf6\xff\x45\xd7\xf5\xff\x48\xd9\xf5\xff'
        b'\x4b\xdb\xf4\xff\x4f\xdc\xf4\xff\x52\xde\xf3\xff\x56\xe0\xf3\xff'
        b'\x59\xe2\xf3\xff\x5d\xe4\xf2\xff\x60\xe6\xf2\xff\x64\xe8\xf1\xff'
        b'\x68\xe9\xf1\xff\x6c\xeb\xf1\xff\x70\xed\xf1\xff\x74\xee\xf1\xff'
        b'\x79\xf0\xf1\xff\x7d\xf2\xf1\xff\x81\xf3\xf2\xff\x85\xf4\xf2\xff'
        b'\x89\xf6\xf3\xff\x8d\xf7\xf4\xff\x91\xf8\xf5\xff\x95\xfa\xf6\xff'
        b'\x99\xfb\xf7\xff\x9d\xfc\xf9\xff\xa0\xfd\xfa\xff\xa4\xfe\xfc\xff'
    ),

    'magma': (
        b'\x03\x00\x00\xff\x04\x00\x00\xff\x06\x00\x00\xff\x07\x00\x01\xff'
        b'\x09\x01\x01\xff\x0b\x01\x01\xff\x0d\x02\x02\xff\x0f\x02\x02\xff'
        b'\x11\x03\x03\xff\x13\x03\x04\xff\x15\x04\x04\xff\x17\x04\x05\xff'
        b'\x19\x05\x06\xff\x1b\x05\x07\xff\x1d\x06\x08\xff\x1f\x07\x09\xff'
        b'\x22\x07\x0a\xff\x24\x08\x0b\xff\x26\x09\x0c\xff\x28\x0a\x0d\xff'
        b'\x2a\x0a\x0e\xff\x2c\x0b\x0f\xff\x2f\x0c\x10\xff\x31\x0c\x11\xff'
        b'\x33\x0d\x12\xff\x35\x0d\x14\xff\x38\x0e\x15\xff\x3a\x0e\x16\xff'
        b'\x3c\x0f\x17\xff\x3f\x0f\x18\xff\x41\x10\x1a\xff\x44\x10\x1b\xff'
        b'\x46\x10\x1c\xff\x49\x10\x1e\xff\x4b\x11\x1f\xff\x4d\x11\x20\xff'
        b'\x50\x11\x22\xff\x52\x11\x23\xff\x55\x11\x25\xff\x57\x11\x26\xff'
        b'\x59\x11\x28\xff\x5c\x11\x2a\xff\x5e\x11\x2b\xff\x60\x10\x2d\xff'
        b'\x62\x10\x2f\xff\x65\x10\x30\xff\x67\x10\x32\xff\x68\x10\x34\xff'
        b'\x6a\x0f\x35\xff\x6c\x0f\x37\xff\x6e\x0f\x39\xff\x6f\x0f\x3b\xff'
        b'\x71\x0f\x3c\xff\x72\x0f\x3e\xff\x73\x0f\x40\xff\x74\x0f\x42\xff'
        b'\x75\x0f\x43\xff\x76\x0f\x45\xff\x77\x0f\x47\xff\x78\x10\x48\xff'
        b'\x79\x10\x4a\xff\x79\x10\x4b\xff\x7a\x11\x4d\xff\x7b\x11\x4f\xff'
        b'\x7b\x12\x50\xff\x7c\x12\x52\xff\x7c\x13\x53\xff\x7d\x13\x55\xff'
        b'\x7d\x14\x57\xff\x7e\x15\x58\xff\x7e\x15\x5a\xff\x7e\x16\x5b\xff'
        b'\x7e\x17\x5d\xff\x7f\x17\x5e\xff\x7f\x18\x60\xff\x7f\x18\x61\xff'
        b'\x7f\x19\x63\xff\x80\x1a\x65\xff\x80\x1a\x66\xff\x80\x1b\x68\xff'
        b'\x80\x1c\x69\xff\x80\x1c\x6b\xff\x80\x1d\x6c\xff\x81\x1e\x6e\xff'
        b'\x81\x1e\x6f\xff\x81\x1f\x71\xff\x81\x1f\x73\xff\x81\x20\x74\xff'
        b'\x81\x21\x76\xff\x81\x21\x77\xff\x81\x22\x79\xff\x81\x22\x7a\xff'
        b'\x81\x23\x7c\xff\x81\x24\x7e\xff\x81\x24\x7f\xff\x81\x25\x81\xff'
        b'\x81\x25\x82\xff\x81\x26\x84\xff\x81\x26\x85\xff\x81\x27\x87\xff'
        b'\x81\x28\x89\xff\x81\x28\x8a\xff\x80\x29\x8c\xff\x80\x29\x8d\xff'
        b'\x80\x2a\x8f\xff\x80\x2a\x91\xff\x80\x2b\x92\xff\x80\x2b\x94\xff'
        b'\x80\x2c\x95\xff\x7f\x2c\x97\xff\x7f\x2d\x99\xff\x7f\x2d\x9a\xff'
        b'\x7f\x2e\x9c\xff\x7e\x2e\x9e\xff\x7e\x2f\x9f\xff\x7e\x2f\xa1\xff'
        b'\x7e\x30\xa3\xff\x7d\x30\xa4\xff\x7d\x31\xa6\xff\x7d\x31\xa7\xff'
        b'\x7c\x32\xa9\xff\x7c\x33\xab\xff\x7b\x33\xac\xff\x7b\x34\xae\xff'
        b'\x7b\x34\xb0\xff\x7a\x35\xb1\xff\x7a\x35\xb3\xff\x79\x36\xb5\xff'
        b'\x79\x36\xb6\xff\x78\x37\xb8\xff\x78\x37\xb9\xff\x77\x38\xbb\xff'
        b'\x77\x39\xbd\xff\x76\x39\xbe\xff\x75\x3a\xc0\xff\x75\x3a\xc2\xff'
        b'\x74\x3b\xc3\xff\x74\x3c\xc5\xff\x73\x3c\xc6\xff\x72\x3d\xc8\xff'
        b'\x72\x3e\xca\xff\x71\x3e\xcb\xff\x70\x3f\xcd\xff\x70\x40\xce\xff'
        b'\x6f\x41\xd0\xff\x6e\x42\xd1\xff\x6d\x42\xd3\xff\x6d\x43\xd4\xff'
        b'\x6c\x44\xd6\xff\x6b\x45\xd7\xff\x6a\x46\xd9\xff\x69\x47\xda\xff'
        b'\x69\x48\xdc\xff\x68\x49\xdd\xff\x67\x4a\xde\xff\x66\x4b\xe0\xff'
        b'\x66\x4c\xe1\xff\x65\x4d\xe2\xff\x64\x4e\xe4\xff\x63\x50\xe5\xff'
        b'\x62\x51\xe6\xff\x62\x52\xe7\xff\x61\x54\xe8\xff\x60\x55\xea\xff'
        b'\x60\x56\xeb\xff\x5f\x58\xec\xff\x5f\x59\xed\xff\x5e\x5b\xee\xff'
        b'\x5d\x5d\xee\xff\x5d\x5e\xef\xff\x5d\x60\xf0\xff\x5c\x61\xf1\xff'
        b'\x5c\x63\xf2\xff\x5c\x65\xf3\xff\x5b\x67\xf3\xff\x5b\x68\xf4\xff'
        b'\x5b\x6a\xf5\xff\x5b\x6c\xf5\xff\x5b\x6e\xf6\xff\x5b\x70\xf6\xff'
        b'\x5b\x71\xf7\xff\x5c\x73\xf7\xff\x5c\x75\xf8\xff\x5c\x77\xf8\xff'
        b'\x5c\x79\xf9\xff\x5d\x7b\xf9\xff\x5d\x7d\xf9\xff\x5e\x7f\xfa\xff'
        b'\x5e\x80\xfa\xff\x5f\x82\xfa\xff\x60\x84\xfb\xff\x60\x86\xfb\xff'
        b'\x61\x88\xfb\xff\x62\x8a\xfb\xff\x63\x8c\xfc\xff\x63\x8e\xfc\xff'
        b'\x64\x90\xfc\xff\x65\x92\xfc\xff\x66\x93\xfc\xff\x67\x95\xfd\xff'
        b'\x68\x97\xfd\xff\x69\x99\xfd\xff\x6a\x9b\xfd\xff\x6b\x9d\xfd\xff'
        b'\x6c\x9f\xfd\xff\x6e\xa1\xfd\xff\x6f\xa2\xfd\xff\x70\xa4\xfd\xff'
        b'\x71\xa6\xfe\xff\x73\xa8\xfe\xff\x74\xaa\xfe\xff\x75\xac\xfe\xff'
        b'\x76\xae\xfe\xff\x78\xaf\xfe\xff\x79\xb1\xfe\xff\x7b\xb3\xfe\xff'
        b'\x7c\xb5\xfe\xff\x7d\xb7\xfe\xff\x7f\xb9\xfe\xff\x80\xbb\xfe\xff'
        b'\x82\xbc\xfe\xff\x83\xbe\xfe\xff\x85\xc0\xfe\xff\x86\xc2\xfe\xff'
        b'\x88\xc4\xfe\xff\x89\xc6\xfe\xff\x8b\xc7\xfe\xff\x8d\xc9\xfe\xff'
        b'\x8e\xcb\xfe\xff\x90\xcd\xfd\xff\x92\xcf\xfd\xff\x93\xd1\xfd\xff'
        b'\x95\xd2\xfd\xff\x97\xd4\xfd\xff\x98\xd6\xfd\xff\x9a\xd8\xfd\xff'
        b'\x9c\xda\xfd\xff\x9d\xdc\xfd\xff\x9f\xdd\xfd\xff\xa1\xdf\xfd\xff'
        b'\xa3\xe1\xfd\xff\xa5\xe3\xfc\xff\xa6\xe5\xfc\xff\xa8\xe6\xfc\xff'
        b'\xaa\xe8\xfc\xff\xac\xea\xfc\xff\xae\xec\xfc\xff\xb0\xee\xfc\xff'
        b'\xb1\xf0\xfc\xff\xb3\xf1\xfc\xff\xb5\xf3\xfc\xff\xb7\xf5\xfc\xff'
        b'\xb9\xf7\xfb\xff\xbb\xf9\xfb\xff\xbd\xfa\xfb\xff\xbf\xfc\xfb\xff'
    ),

    'moreland': (
        b'\xc0\x4c\x3a\xff\xc1\x4d\x3b\xff\xc3\x4f\x3c\xff\xc4\x51\x3e\xff'
        b'\xc6\x53\x3f\xff\xc7\x54\x40\xff\xc9\x56\x41\xff\xca\x58\x42\xff'
        b'\xcc\x5a\x43\xff\xcd\x5b\x45\xff\xcf\x5d\x46\xff\xd0\x5f\x47\xff'
        b'\xd2\x60\x48\xff\xd3\x62\x49\xff\xd4\x64\x4b\xff\xd6\x66\x4c\xff'
        b'\xd7\x67\x4d\xff\xd8\x69\x4e\xff\xda\x6b\x50\xff\xdb\x6c\x51\xff'
        b'\xdc\x6e\x52\xff\xdd\x70\x53\xff\xdf\x71\x55\xff\xe0\x73\x56\xff'
        b'\xe1\x75\x57\xff\xe2\x76\x58\xff\xe3\x78\x5a\xff\xe4\x7a\x5b\xff'
        b'\xe5\x7b\x5c\xff\xe6\x7d\x5d\xff\xe8\x7e\x5f\xff\xe9\x80\x60\xff'
        b'\xea\x82\x61\xff\xeb\x83\x63\xff\xeb\x85\x64\xff\xec\x86\x65\xff'
        b'\xed\x88\x67\xff\xee\x89\x68\xff\xef\x8b\x69\xff\xf0\x8d\x6b\xff'
        b'\xf1\x8e\x6c\xff\xf2\x90\x6d\xff\xf2\x91\x6f\xff\xf3\x93\x70\xff'
        b'\xf4\x94\x71\xff\xf5\x96\x73\xff\xf5\x97\x74\xff\xf6\x98\x75\xff'
        b'\xf6\x9a\x77\xff\xf7\x9b\x78\xff\xf8\x9d\x79\xff\xf8\x9e\x7b\xff'
        b'\xf9\xa0\x7c\xff\xf9\xa1\x7e\xff\xfa\xa2\x7f\xff\xfa\xa4\x80\xff'
        b'\xfb\xa5\x82\xff\xfb\xa6\x83\xff\xfc\xa8\x85\xff\xfc\xa9\x86\xff'
        b'\xfc\xaa\x87\xff\xfd\xac\x89\xff\xfd\xad\x8a\xff\xfd\xae\x8b\xff'
        b'\xfd\xaf\x8d\xff\xfe\xb1\x8e\xff\xfe\xb2\x90\xff\xfe\xb3\x91\xff'
        b'\xfe\xb4\x92\xff\xfe\xb6\x94\xff\xfe\xb7\x95\xff\xfe\xb8\x97\xff'
        b'\xfe\xb9\x98\xff\xfe\xba\x99\xff\xfe\xbb\x9b\xff\xfe\xbc\x9c\xff'
        b'\xfe\xbd\x9d\xff\xfe\xbe\x9f\xff\xfe\xbf\xa0\xff\xfe\xc1\xa2\xff'
        b'\xfe\xc2\xa3\xff\xfe\xc3\xa4\xff\xfe\xc3\xa6\xff\xfd\xc4\xa7\xff'
        b'\xfd\xc5\xa8\xff\xfd\xc6\xaa\xff\xfd\xc7\xab\xff\xfc\xc8\xac\xff'
        b'\xfc\xc9\xae\xff\xfc\xca\xaf\xff\xfb\xcb\xb0\xff\xfb\xcb\xb2\xff'
        b'\xfa\xcc\xb3\xff\xfa\xcd\xb4\xff\xf9\xce\xb6\xff\xf9\xcf\xb7\xff'
        b'\xf8\xcf\xb8\xff\xf8\xd0\xb9\xff\xf7\xd1\xbb\xff\xf7\xd1\xbc\xff'
        b'\xf6\xd2\xbd\xff\xf5\xd3\xbe\xff\xf5\xd3\xc0\xff\xf4\xd4\xc1\xff'
        b'\xf3\xd4\xc2\xff\xf2\xd5\xc3\xff\xf2\xd6\xc5\xff\xf1\xd6\xc6\xff'
        b'\xf0\xd7\xc7\xff\xef\xd7\xc8\xff\xee\xd8\xc9\xff\xee\xd8\xcb\xff'
        b'\xed\xd8\xcc\xff\xec\xd9\xcd\xff\xeb\xd9\xce\xff\xea\xda\xcf\xff'
        b'\xe9\xda\xd0\xff\xe8\xda\xd1\xff\xe7\xda\xd2\xff\xe6\xdb\xd3\xff'
        b'\xe5\xdb\xd5\xff\xe4\xdb\xd6\xff\xe3\xdb\xd7\xff\xe1\xdc\xd8\xff'
        b'\xe0\xdc\xd9\xff\xdf\xdc\xda\xff\xde\xdc\xdb\xff\xdd\xdc\xdc\xff'
        b'\xdb\xdc\xdd\xff\xda\xdb\xde\xff\xd9\xdb\xdf\xff\xd7\xda\xe0\xff'
        b'\xd6\xda\xe1\xff\xd4\xd9\xe2\xff\xd3\xd9\xe3\xff\xd2\xd8\xe4\xff'
        b'\xd0\xd8\xe5\xff\xcf\xd7\xe6\xff\xcd\xd6\xe7\xff\xcc\xd6\xe8\xff'
        b'\xca\xd5\xe8\xff\xc9\xd4\xe9\xff\xc7\xd4\xea\xff\xc6\xd3\xeb\xff'
        b'\xc4\xd2\xec\xff\xc3\xd1\xec\xff\xc1\xd0\xed\xff\xc0\xd0\xee\xff'
        b'\xbe\xcf\xee\xff\xbd\xce\xef\xff\xbb\xcd\xf0\xff\xb9\xcc\xf0\xff'
        b'\xb8\xcb\xf1\xff\xb6\xca\xf1\xff\xb5\xc9\xf2\xff\xb3\xc8\xf2\xff'
        b'\xb2\xc7\xf3\xff\xb0\xc6\xf3\xff\xaf\xc5\xf3\xff\xad\xc4\xf4\xff'
        b'\xab\xc3\xf4\xff\xaa\xc2\xf5\xff\xa8\xc1\xf5\xff\xa7\xc0\xf5\xff'
        b'\xa5\xbf\xf5\xff\xa4\xbd\xf6\xff\xa2\xbc\xf6\xff\xa0\xbb\xf6\xff'
        b'\x9f\xba\xf6\xff\x9d\xb9\xf6\xff\x9c\xb7\xf7\xff\x9a\xb6\xf7\xff'
        b'\x98\xb5\xf7\xff\x97\xb4\xf7\xff\x95\xb2\xf7\xff\x94\xb1\xf7\xff'
        b'\x92\xb0\xf7\xff\x91\xae\xf7\xff\x8f\xad\xf7\xff\x8d\xab\xf7\xff'
        b'\x8c\xaa\xf7\xff\x8a\xa9\xf6\xff\x89\xa7\xf6\xff\x87\xa6\xf6\xff'
        b'\x86\xa4\xf6\xff\x84\xa3\xf6\xff\x82\xa1\xf5\xff\x81\xa0\xf5\xff'
        b'\x7f\x9e\xf5\xff\x7e\x9d\xf5\xff\x7c\x9b\xf4\xff\x7b\x9a\xf4\xff'
        b'\x79\x98\xf4\xff\x78\x96\xf3\xff\x76\x95\xf3\xff\x75\x93\xf2\xff'
        b'\x73\x92\xf2\xff\x72\x90\xf1\xff\x70\x8e\xf1\xff\x6f\x8d\xf0\xff'
        b'\x6d\x8b\xf0\xff\x6c\x89\xef\xff\x6a\x87\xef\xff\x69\x86\xee\xff'
        b'\x67\x84\xed\xff\x66\x82\xed\xff\x64\x80\xec\xff\x63\x7f\xeb\xff'
        b'\x61\x7d\xeb\xff\x60\x7b\xea\xff\x5e\x79\xe9\xff\x5d\x77\xe8\xff'
        b'\x5b\x76\xe7\xff\x5a\x74\xe7\xff\x59\x72\xe6\xff\x57\x70\xe5\xff'
        b'\x56\x6e\xe4\xff\x54\x6c\xe3\xff\x53\x6a\xe2\xff\x52\x68\xe1\xff'
        b'\x50\x66\xe0\xff\x4f\x64\xdf\xff\x4e\x62\xde\xff\x4c\x60\xdd\xff'
        b'\x4b\x5e\xdc\xff\x4a\x5c\xdb\xff\x48\x5a\xda\xff\x47\x58\xd9\xff'
        b'\x46\x56\xd8\xff\x44\x54\xd7\xff\x43\x52\xd6\xff\x42\x4f\xd4\xff'
        b'\x40\x4d\xd3\xff\x3f\x4b\xd2\xff\x3e\x49\xd1\xff\x3d\x47\xd0\xff'
        b'\x3b\x44\xce\xff\x3a\x42\xcd\xff\x39\x40\xcc\xff\x38\x3d\xca\xff'
        b'\x37\x3b\xc9\xff\x35\x38\xc8\xff\x34\x36\xc6\xff\x33\x33\xc5\xff'
        b'\x32\x30\xc4\xff\x31\x2e\xc2\xff\x30\x2b\xc1\xff\x2e\x28\xbf\xff'
        b'\x2d\x25\xbe\xff\x2c\x21\xbd\xff\x2b\x1e\xbb\xff\x2a\x1a\xba\xff'
        b'\x29\x16\xb8\xff\x28\x11\xb7\xff\x27\x0b\xb5\xff\x26\x03\xb3\xff'
    ),

    'parula': (
        b'\x86\x2a\x35\xff\x89\x2b\x35\xff\x8d\x2d\x35\xff\x90\x2e\x35\xff'
        b'\x93\x30\x35\xff\x96\x31\x36\xff\x99\x33\x36\xff\x9c\x34\x36\xff'
        b'\x9f\x36\x36\xff\xa2\x37\x36\xff\xa5\x39\x35\xff\xa9\x3b\x35\xff'
        b'\xac\x3c\x35\xff\xaf\x3e\x34\xff\xb2\x3f\x33\xff\xb5\x41\x33\xff'
        b'\xb9\x43\x32\xff\xbc\x44\x30\xff\xbf\x46\x2f\xff\xc2\x48\x2d\xff'
        b'\xc5\x49\x2c\xff\xc9\x4b\x29\xff\xcc\x4d\x27\xff\xcf\x4f\x24\xff'
        b'\xd2\x52\x20\xff\xd5\x54\x1d\xff\xd8\x56\x18\xff\xda\x58\x14\xff'
        b'\xdc\x5b\x10\xff\xde\x5d\x0c\xff\xdf\x5e\x08\xff\xe0\x60\x05\xff'
        b'\xe0\x62\x03\xff\xe1\x63\x02\xff\xe1\x65\x01\xff\xe1\x66\x01\xff'
        b'\xe1\x67\x01\xff\xe1\x68\x01\xff\xe0\x6a\x02\xff\xe0\x6b\x03\xff'
        b'\xe0\x6c\x03\xff\xdf\x6d\x04\xff\xdf\x6e\x05\xff\xdf\x6f\x06\xff'
        b'\xde\x70\x07\xff\xde\x71\x08\xff\xdd\x72\x0a\xff\xdd\x73\x0b\xff'
        b'\xdc\x74\x0c\xff\xdc\x75\x0d\xff\xdb\x76\x0e\xff\xdb\x77\x0e\xff'
        b'\xda\x78\x0f\xff\xd9\x79\x10\xff\xd9\x7a\x10\xff\xd8\x7b\x11\xff'
        b'\xd8\x7b\x12\xff\xd7\x7c\x12\xff\xd7\x7d\x13\xff\xd6\x7e\x13\xff'
        b'\xd6\x7f\x13\xff\xd5\x80\x13\xff\xd5\x81\x14\xff\xd4\x82\x14\xff'
        b'\xd4\x83\x14\xff\xd3\x84\x14\xff\xd3\x85\x14\xff\xd3\x87\x13\xff'
        b'\xd2\x88\x13\xff\xd2\x89\x13\xff\xd2\x8a\x12\xff\xd2\x8b\x11\xff'
        b'\xd2\x8c\x11\xff\xd2\x8e\x10\xff\xd2\x8f\x0f\xff\xd1\x90\x0e\xff'
        b'\xd1\x92\x0d\xff\xd1\x93\x0c\xff\xd1\x94\x0b\xff\xd1\x95\x0a\xff'
        b'\xd1\x97\x09\xff\xd1\x98\x08\xff\xd0\x99\x08\xff\xd0\x9a\x07\xff'
        b'\xcf\x9b\x07\xff\xcf\x9c\x06\xff\xce\x9d\x06\xff\xce\x9e\x06\xff'
        b'\xcd\x9f\x06\xff\xcd\xa0\x06\xff\xcc\xa1\x06\xff\xcb\xa1\x05\xff'
        b'\xca\xa2\x05\xff\xc9\xa3\x05\xff\xc8\xa4\x05\xff\xc8\xa5\x05\xff'
        b'\xc7\xa5\x05\xff\xc6\xa6\x05\xff\xc5\xa7\x05\xff\xc4\xa7\x06\xff'
        b'\xc3\xa8\x06\xff\xc2\xa9\x06\xff\xc1\xa9\x07\xff\xc0\xaa\x07\xff'
        b'\xbe\xab\x08\xff\xbd\xab\x09\xff\xbc\xac\x0a\xff\xbb\xad\x0b\xff'
        b'\xba\xad\x0d\xff\xb9\xae\x0e\xff\xb8\xae\x10\xff\xb6\xaf\x11\xff'
        b'\xb5\xaf\x13\xff\xb4\xb0\x14\xff\xb3\xb1\x16\xff\xb1\xb1\x18\xff'
        b'\xb0\xb2\x1a\xff\xaf\xb2\x1c\xff\xae\xb3\x1e\xff\xac\xb3\x20\xff'
        b'\xab\xb4\x22\xff\xaa\xb4\x24\xff\xa8\xb5\x26\xff\xa7\xb5\x28\xff'
        b'\xa5\xb6\x2a\xff\xa4\xb6\x2c\xff\xa3\xb7\x2f\xff\xa1\xb7\x31\xff'
        b'\xa0\xb8\x33\xff\x9e\xb8\x36\xff\x9d\xb9\x38\xff\x9b\xb9\x3b\xff'
        b'\x9a\xb9\x3d\xff\x98\xba\x40\xff\x97\xba\x43\xff\x95\xbb\x45\xff'
        b'\x94\xbb\x48\xff\x92\xbb\x4b\xff\x91\xbc\x4e\xff\x8f\xbc\x51\xff'
        b'\x8e\xbc\x53\xff\x8c\xbd\x56\xff\x8b\xbd\x59\xff\x89\xbd\x5c\xff'
        b'\x88\xbd\x5f\xff\x86\xbe\x62\xff\x85\xbe\x65\xff\x83\xbe\x68\xff'
        b'\x82\xbe\x6b\xff\x81\xbe\x6e\xff\x80\xbe\x71\xff\x7e\xbe\x74\xff'
        b'\x7d\xbe\x77\xff\x7c\xbe\x79\xff\x7b\xbf\x7c\xff\x7a\xbf\x7f\xff'
        b'\x78\xbf\x82\xff\x77\xbf\x84\xff\x76\xbf\x87\xff\x75\xbe\x8a\xff'
        b'\x74\xbe\x8c\xff\x73\xbe\x8f\xff\x72\xbe\x91\xff\x71\xbe\x94\xff'
        b'\x70\xbe\x96\xff\x6f\xbe\x99\xff\x6e\xbe\x9b\xff\x6d\xbe\x9e\xff'
        b'\x6c\xbe\xa0\xff\x6b\xbe\xa2\xff\x6a\xbe\xa5\xff\x69\xbe\xa7\xff'
        b'\x68\xbd\xa9\xff\x68\xbd\xab\xff\x67\xbd\xae\xff\x66\xbd\xb0\xff'
        b'\x65\xbd\xb2\xff\x64\xbd\xb4\xff\x63\xbc\xb6\xff\x62\xbc\xb9\xff'
        b'\x61\xbc\xbb\xff\x61\xbc\xbd\xff\x60\xbc\xbf\xff\x5f\xbc\xc1\xff'
        b'\x5e\xbb\xc3\xff\x5d\xbb\xc5\xff\x5c\xbb\xc7\xff\x5b\xbb\xca\xff'
        b'\x5b\xbb\xcc\xff\x5a\xbb\xce\xff\x59\xba\xd0\xff\x58\xba\xd2\xff'
        b'\x57\xba\xd4\xff\x56\xba\xd6\xff\x55\xba\xd8\xff\x55\xba\xda\xff'
        b'\x54\xb9\xdc\xff\x53\xb9\xde\xff\x52\xb9\xe0\xff\x51\xb9\xe2\xff'
        b'\x50\xb9\xe4\xff\x4f\xb9\xe6\xff\x4e\xb9\xe8\xff\x4d\xb9\xea\xff'
        b'\x4c\xb9\xec\xff\x4b\xb9\xee\xff\x4a\xb9\xf0\xff\x48\xb9\xf2\xff'
        b'\x47\xb9\xf3\xff\x46\xb9\xf5\xff\x44\xba\xf7\xff\x43\xba\xf9\xff'
        b'\x41\xbb\xfa\xff\x3f\xbc\xfb\xff\x3e\xbd\xfc\xff\x3c\xbe\xfd\xff'
        b'\x3a\xbf\xfe\xff\x39\xc1\xfe\xff\x37\xc2\xfe\xff\x36\xc3\xfe\xff'
        b'\x35\xc5\xfe\xff\x34\xc6\xfe\xff\x32\xc7\xfe\xff\x31\xc8\xfd\xff'
        b'\x30\xca\xfd\xff\x2f\xcb\xfc\xff\x2e\xcc\xfc\xff\x2d\xce\xfb\xff'
        b'\x2c\xcf\xfb\xff\x2b\xd0\xfa\xff\x2a\xd1\xfa\xff\x29\xd3\xf9\xff'
        b'\x28\xd4\xf8\xff\x27\xd5\xf8\xff\x26\xd7\xf7\xff\x25\xd8\xf7\xff'
        b'\x24\xd9\xf6\xff\x23\xdb\xf6\xff\x22\xdc\xf5\xff\x21\xde\xf5\xff'
        b'\x20\xdf\xf5\xff\x1e\xe1\xf4\xff\x1d\xe2\xf4\xff\x1c\xe4\xf4\xff'
        b'\x1b\xe6\xf4\xff\x1a\xe7\xf4\xff\x19\xe9\xf4\xff\x18\xeb\xf4\xff'
        b'\x16\xed\xf5\xff\x15\xee\xf5\xff\x14\xf0\xf5\xff\x13\xf2\xf6\xff'
        b'\x11\xf4\xf6\xff\x10\xf6\xf7\xff\x0f\xf8\xf8\xff\x0d\xfa\xf8\xff'
    ),

    'plasma': (
        b'\x86\x07\x0c\xff\x87\x07\x10\xff\x89\x06\x13\xff\x8a\x06\x15\xff'
        b'\x8b\x06\x18\xff\x8c\x06\x1b\xff\x8d\x06\x1d\xff\x8e\x05\x1f\xff'
        b'\x8f\x05\x21\xff\x90\x05\x23\xff\x91\x05\x25\xff\x92\x05\x27\xff'
        b'\x93\x05\x29\xff\x94\x05\x2b\xff\x94\x04\x2d\xff\x95\x04\x2f\xff'
        b'\x96\x04\x31\xff\x97\x04\x33\xff\x98\x04\x34\xff\x98\x04\x36\xff'
        b'\x99\x04\x38\xff\x9a\x04\x3a\xff\x9a\x03\x3b\xff\x9b\x03\x3d\xff'
        b'\x9c\x03\x3f\xff\x9c\x03\x40\xff\x9d\x03\x42\xff\x9e\x03\x44\xff'
        b'\x9e\x03\x45\xff\x9f\x02\x47\xff\x9f\x02\x49\xff\xa0\x02\x4a\xff'
        b'\xa1\x02\x4c\xff\xa1\x02\x4e\xff\xa2\x02\x4f\xff\xa2\x01\x51\xff'
        b'\xa3\x01\x52\xff\xa3\x01\x54\xff\xa3\x01\x56\xff\xa4\x01\x57\xff'
        b'\xa4\x01\x59\xff\xa5\x00\x5a\xff\xa5\x00\x5c\xff\xa5\x00\x5e\xff'
        b'\xa6\x00\x5f\xff\xa6\x00\x61\xff\xa6\x00\x62\xff\xa7\x00\x64\xff'
        b'\xa7\x00\x65\xff\xa7\x00\x67\xff\xa7\x00\x68\xff\xa7\x00\x6a\xff'
        b'\xa8\x00\x6c\xff\xa8\x00\x6d\xff\xa8\x00\x6f\xff\xa8\x00\x70\xff'
        b'\xa8\x00\x72\xff\xa8\x00\x73\xff\xa8\x00\x75\xff\xa8\x01\x76\xff'
        b'\xa8\x01\x78\xff\xa8\x01\x79\xff\xa8\x02\x7b\xff\xa7\x02\x7c\xff'
        b'\xa7\x03\x7e\xff\xa7\x03\x7f\xff\xa7\x04\x81\xff\xa7\x04\x82\xff'
        b'\xa6\x05\x84\xff\xa6\x06\x85\xff\xa6\x07\x86\xff\xa5\x07\x88\xff'
        b'\xa5\x08\x89\xff\xa4\x09\x8b\xff\xa4\x0a\x8c\xff\xa4\x0c\x8e\xff'
        b'\xa3\x0d\x8f\xff\xa3\x0e\x90\xff\xa2\x0f\x92\xff\xa1\x10\x93\xff'
        b'\xa1\x11\x95\xff\xa0\x12\x96\xff\xa0\x13\x97\xff\x9f\x14\x99\xff'
        b'\x9e\x15\x9a\xff\x9e\x17\x9b\xff\x9d\x18\x9d\xff\x9c\x19\x9e\xff'
        b'\x9b\x1a\x9f\xff\x9b\x1b\xa0\xff\x9a\x1c\xa2\xff\x99\x1d\xa3\xff'
        b'\x98\x1e\xa4\xff\x97\x1f\xa5\xff\x97\x21\xa7\xff\x96\x22\xa8\xff'
        b'\x95\x23\xa9\xff\x94\x24\xaa\xff\x93\x25\xac\xff\x92\x26\xad\xff'
        b'\x91\x27\xae\xff\x90\x28\xaf\xff\x8f\x2a\xb0\xff\x8f\x2b\xb1\xff'
        b'\x8e\x2c\xb2\xff\x8d\x2d\xb4\xff\x8c\x2e\xb5\xff\x8b\x2f\xb6\xff'
        b'\x8a\x30\xb7\xff\x89\x32\xb8\xff\x88\x33\xb9\xff\x87\x34\xba\xff'
        b'\x86\x35\xbb\xff\x85\x36\xbc\xff\x84\x37\xbd\xff\x83\x38\xbe\xff'
        b'\x82\x39\xbf\xff\x81\x3b\xc0\xff\x80\x3c\xc1\xff\x80\x3d\xc2\xff'
        b'\x7f\x3e\xc3\xff\x7e\x3f\xc4\xff\x7d\x40\xc5\xff\x7c\x41\xc6\xff'
        b'\x7b\x42\xc7\xff\x7a\x44\xc8\xff\x79\x45\xc9\xff\x78\x46\xca\xff'
        b'\x77\x47\xcb\xff\x76\x48\xcc\xff\x75\x49\xcd\xff\x75\x4a\xce\xff'
        b'\x74\x4b\xcf\xff\x73\x4d\xd0\xff\x72\x4e\xd1\xff\x71\x4f\xd1\xff'
        b'\x70\x50\xd2\xff\x6f\x51\xd3\xff\x6e\x52\xd4\xff\x6d\x53\xd5\xff'
        b'\x6d\x55\xd6\xff\x6c\x56\xd7\xff\x6b\x57\xd7\xff\x6a\x58\xd8\xff'
        b'\x69\x59\xd9\xff\x68\x5a\xda\xff\x67\x5b\xdb\xff\x66\x5d\xdc\xff'
        b'\x66\x5e\xdc\xff\x65\x5f\xdd\xff\x64\x60\xde\xff\x63\x61\xdf\xff'
        b'\x62\x62\xdf\xff\x61\x64\xe0\xff\x60\x65\xe1\xff\x60\x66\xe2\xff'
        b'\x5f\x67\xe3\xff\x5e\x68\xe3\xff\x5d\x6a\xe4\xff\x5c\x6b\xe5\xff'
        b'\x5b\x6c\xe5\xff\x5a\x6d\xe6\xff\x5a\x6e\xe7\xff\x59\x70\xe8\xff'
        b'\x58\x71\xe8\xff\x57\x72\xe9\xff\x56\x73\xea\xff\x55\x74\xea\xff'
        b'\x54\x76\xeb\xff\x54\x77\xec\xff\x53\x78\xec\xff\x52\x79\xed\xff'
        b'\x51\x7b\xed\xff\x50\x7c\xee\xff\x4f\x7d\xef\xff\x4e\x7e\xef\xff'
        b'\x4d\x80\xf0\xff\x4d\x81\xf0\xff\x4c\x82\xf1\xff\x4b\x84\xf2\xff'
        b'\x4a\x85\xf2\xff\x49\x86\xf3\xff\x48\x87\xf3\xff\x47\x89\xf4\xff'
        b'\x47\x8a\xf4\xff\x46\x8b\xf5\xff\x45\x8d\xf5\xff\x44\x8e\xf6\xff'
        b'\x43\x8f\xf6\xff\x42\x91\xf6\xff\x41\x92\xf7\xff\x41\x93\xf7\xff'
        b'\x40\x95\xf8\xff\x3f\x96\xf8\xff\x3e\x98\xf8\xff\x3d\x99\xf9\xff'
        b'\x3c\x9a\xf9\xff\x3b\x9c\xfa\xff\x3a\x9d\xfa\xff\x3a\x9f\xfa\xff'
        b'\x39\xa0\xfa\xff\x38\xa2\xfb\xff\x37\xa3\xfb\xff\x36\xa4\xfb\xff'
        b'\x35\xa6\xfc\xff\x35\xa7\xfc\xff\x34\xa9\xfc\xff\x33\xaa\xfc\xff'
        b'\x32\xac\xfc\xff\x31\xad\xfc\xff\x31\xaf\xfd\xff\x30\xb0\xfd\xff'
        b'\x2f\xb2\xfd\xff\x2e\xb3\xfd\xff\x2d\xb5\xfd\xff\x2d\xb6\xfd\xff'
        b'\x2c\xb8\xfd\xff\x2b\xb9\xfd\xff\x2b\xbb\xfd\xff\x2a\xbc\xfd\xff'
        b'\x29\xbe\xfd\xff\x29\xc0\xfd\xff\x28\xc1\xfd\xff\x28\xc3\xfd\xff'
        b'\x27\xc4\xfd\xff\x26\xc6\xfd\xff\x26\xc7\xfc\xff\x26\xc9\xfc\xff'
        b'\x25\xcb\xfc\xff\x25\xcc\xfc\xff\x25\xce\xfc\xff\x24\xd0\xfb\xff'
        b'\x24\xd1\xfb\xff\x24\xd3\xfb\xff\x24\xd5\xfa\xff\x24\xd6\xfa\xff'
        b'\x24\xd8\xfa\xff\x24\xd9\xf9\xff\x24\xdb\xf9\xff\x24\xdd\xf8\xff'
        b'\x24\xdf\xf8\xff\x24\xe0\xf7\xff\x25\xe2\xf7\xff\x25\xe4\xf6\xff'
        b'\x25\xe5\xf6\xff\x26\xe7\xf5\xff\x26\xe9\xf5\xff\x26\xea\xf4\xff'
        b'\x26\xec\xf3\xff\x26\xee\xf3\xff\x26\xf0\xf2\xff\x26\xf1\xf2\xff'
        b'\x26\xf3\xf1\xff\x25\xf5\xf0\xff\x23\xf6\xf0\xff\x21\xf8\xef\xff'
    ),

    'viridis': (
        b'\x54\x01\x44\xff\x55\x02\x44\xff\x57\x03\x44\xff\x58\x05\x45\xff'
        b'\x5a\x06\x45\xff\x5b\x08\x45\xff\x5c\x09\x46\xff\x5e\x0b\x46\xff'
        b'\x5f\x0c\x46\xff\x61\x0e\x46\xff\x62\x0f\x47\xff\x63\x11\x47\xff'
        b'\x65\x12\x47\xff\x66\x14\x47\xff\x67\x15\x47\xff\x69\x16\x47\xff'
        b'\x6a\x18\x47\xff\x6b\x19\x48\xff\x6c\x1a\x48\xff\x6e\x1c\x48\xff'
        b'\x6f\x1d\x48\xff\x70\x1e\x48\xff\x71\x20\x48\xff\x72\x21\x48\xff'
        b'\x73\x22\x48\xff\x74\x23\x48\xff\x75\x25\x47\xff\x76\x26\x47\xff'
        b'\x77\x27\x47\xff\x78\x28\x47\xff\x79\x2a\x47\xff\x7a\x2b\x47\xff'
        b'\x7b\x2c\x47\xff\x7c\x2d\x46\xff\x7c\x2f\x46\xff\x7d\x30\x46\xff'
        b'\x7e\x31\x46\xff\x7f\x32\x45\xff\x7f\x34\x45\xff\x80\x35\x45\xff'
        b'\x81\x36\x45\xff\x81\x37\x44\xff\x82\x39\x44\xff\x83\x3a\x43\xff'
        b'\x83\x3b\x43\xff\x84\x3c\x43\xff\x84\x3d\x42\xff\x85\x3e\x42\xff'
        b'\x85\x40\x42\xff\x86\x41\x41\xff\x86\x42\x41\xff\x87\x43\x40\xff'
        b'\x87\x44\x40\xff\x87\x45\x3f\xff\x88\x47\x3f\xff\x88\x48\x3e\xff'
        b'\x89\x49\x3e\xff\x89\x4a\x3d\xff\x89\x4b\x3d\xff\x89\x4c\x3d\xff'
        b'\x8a\x4d\x3c\xff\x8a\x4e\x3c\xff\x8a\x50\x3b\xff\x8a\x51\x3b\xff'
        b'\x8b\x52\x3a\xff\x8b\x53\x3a\xff\x8b\x54\x39\xff\x8b\x55\x39\xff'
        b'\x8b\x56\x38\xff\x8c\x57\x38\xff\x8c\x58\x37\xff\x8c\x59\x37\xff'
        b'\x8c\x5a\x36\xff\x8c\x5b\x36\xff\x8c\x5c\x35\xff\x8c\x5d\x35\xff'
        b'\x8d\x5e\x34\xff\x8d\x5f\x34\xff\x8d\x60\x33\xff\x8d\x61\x33\xff'
        b'\x8d\x62\x32\xff\x8d\x63\x32\xff\x8d\x64\x31\xff\x8d\x65\x31\xff'
        b'\x8d\x66\x31\xff\x8d\x67\x30\xff\x8d\x68\x30\xff\x8d\x69\x2f\xff'
        b'\x8d\x6a\x2f\xff\x8e\x6b\x2e\xff\x8e\x6c\x2e\xff\x8e\x6d\x2e\xff'
        b'\x8e\x6e\x2d\xff\x8e\x6f\x2d\xff\x8e\x70\x2c\xff\x8e\x71\x2c\xff'
        b'\x8e\x72\x2c\xff\x8e\x73\x2b\xff\x8e\x74\x2b\xff\x8e\x75\x2a\xff'
        b'\x8e\x76\x2a\xff\x8e\x77\x2a\xff\x8e\x78\x29\xff\x8e\x79\x29\xff'
        b'\x8e\x7a\x28\xff\x8e\x7a\x28\xff\x8e\x7b\x28\xff\x8e\x7c\x27\xff'
        b'\x8e\x7d\x27\xff\x8e\x7e\x27\xff\x8e\x7f\x26\xff\x8e\x80\x26\xff'
        b'\x8e\x81\x26\xff\x8e\x82\x25\xff\x8d\x83\x25\xff\x8d\x84\x24\xff'
        b'\x8d\x85\x24\xff\x8d\x86\x24\xff\x8d\x87\x23\xff\x8d\x88\x23\xff'
        b'\x8d\x89\x23\xff\x8d\x89\x22\xff\x8d\x8a\x22\xff\x8d\x8b\x22\xff'
        b'\x8d\x8c\x21\xff\x8c\x8d\x21\xff\x8c\x8e\x21\xff\x8c\x8f\x20\xff'
        b'\x8c\x90\x20\xff\x8c\x91\x20\xff\x8c\x92\x1f\xff\x8b\x93\x1f\xff'
        b'\x8b\x94\x1f\xff\x8b\x95\x1f\xff\x8b\x96\x1f\xff\x8a\x97\x1e\xff'
        b'\x8a\x98\x1e\xff\x8a\x99\x1e\xff\x8a\x99\x1e\xff\x89\x9a\x1e\xff'
        b'\x89\x9b\x1e\xff\x89\x9c\x1e\xff\x88\x9d\x1e\xff\x88\x9e\x1e\xff'
        b'\x88\x9f\x1e\xff\x87\xa0\x1e\xff\x87\xa1\x1f\xff\x86\xa2\x1f\xff'
        b'\x86\xa3\x1f\xff\x85\xa4\x20\xff\x85\xa5\x20\xff\x85\xa6\x21\xff'
        b'\x84\xa7\x21\xff\x84\xa7\x22\xff\x83\xa8\x23\xff\x82\xa9\x23\xff'
        b'\x82\xaa\x24\xff\x81\xab\x25\xff\x81\xac\x26\xff\x80\xad\x27\xff'
        b'\x7f\xae\x28\xff\x7f\xaf\x29\xff\x7e\xb0\x2a\xff\x7d\xb1\x2b\xff'
        b'\x7d\xb1\x2c\xff\x7c\xb2\x2e\xff\x7b\xb3\x2f\xff\x7a\xb4\x30\xff'
        b'\x7a\xb5\x32\xff\x79\xb6\x33\xff\x78\xb7\x35\xff\x77\xb8\x36\xff'
        b'\x76\xb9\x38\xff\x76\xb9\x39\xff\x75\xba\x3b\xff\x74\xbb\x3d\xff'
        b'\x73\xbc\x3e\xff\x72\xbd\x40\xff\x71\xbe\x42\xff\x70\xbe\x44\xff'
        b'\x6f\xbf\x45\xff\x6e\xc0\x47\xff\x6d\xc1\x49\xff\x6c\xc2\x4b\xff'
        b'\x6b\xc2\x4d\xff\x69\xc3\x4f\xff\x68\xc4\x51\xff\x67\xc5\x53\xff'
        b'\x66\xc6\x55\xff\x65\xc6\x57\xff\x64\xc7\x59\xff\x62\xc8\x5b\xff'
        b'\x61\xc9\x5e\xff\x60\xc9\x60\xff\x5f\xca\x62\xff\x5d\xcb\x64\xff'
        b'\x5c\xcc\x67\xff\x5b\xcc\x69\xff\x59\xcd\x6b\xff\x58\xce\x6d\xff'
        b'\x56\xce\x70\xff\x55\xcf\x72\xff\x54\xd0\x74\xff\x52\xd0\x77\xff'
        b'\x51\xd1\x79\xff\x4f\xd2\x7c\xff\x4e\xd2\x7e\xff\x4c\xd3\x81\xff'
        b'\x4b\xd3\x83\xff\x49\xd4\x86\xff\x47\xd5\x88\xff\x46\xd5\x8b\xff'
        b'\x44\xd6\x8d\xff\x43\xd6\x90\xff\x41\xd7\x92\xff\x3f\xd7\x95\xff'
        b'\x3e\xd8\x97\xff\x3c\xd8\x9a\xff\x3a\xd9\x9d\xff\x38\xd9\x9f\xff'
        b'\x37\xda\xa2\xff\x35\xda\xa5\xff\x33\xdb\xa7\xff\x32\xdb\xaa\xff'
        b'\x30\xdc\xad\xff\x2e\xdc\xaf\xff\x2c\xdd\xb2\xff\x2b\xdd\xb5\xff'
        b'\x29\xdd\xb7\xff\x27\xde\xba\xff\x26\xde\xbd\xff\x24\xdf\xbf\xff'
        b'\x22\xdf\xc2\xff\x21\xdf\xc5\xff\x1f\xe0\xc7\xff\x1e\xe0\xca\xff'
        b'\x1d\xe0\xcd\xff\x1c\xe1\xcf\xff\x1b\xe1\xd2\xff\x1a\xe1\xd4\xff'
        b'\x19\xe2\xd7\xff\x18\xe2\xda\xff\x18\xe2\xdc\xff\x18\xe3\xdf\xff'
        b'\x18\xe3\xe1\xff\x18\xe3\xe4\xff\x19\xe4\xe7\xff\x19\xe4\xe9\xff'
        b'\x1a\xe4\xec\xff\x1b\xe5\xee\xff\x1c\xe5\xf1\xff\x1e\xe5\xf3\xff'
        b'\x1f\xe6\xf6\xff\x21\xe6\xf8\xff\x22\xe6\xfa\xff\x24\xe7\xfd\xff'
    ),
}

def cubehelix(start, rots, hue, gamma, nlev=64):
    """Return a cube helix color scheme.
    See https://www.mrao.cam.ac.uk/~dag/CUBEHELIX/
    Green, D. A., 2011, `A colour scheme for the display of astronomical
    intensity images', Bulletin of the Astronomical Society of India, 39, 28
    """

    fract = N.linspace(0, 1, nlev)
    angle = 2*N.pi*(start/3.+1.+rots*fract)
    fract = fract**gamma
    amp = 0.5*hue*fract*(1-fract)
    c, s = N.cos(angle), N.sin(angle)
    red   = fract+amp*(-0.14861*c+1.78277*s)
    green = fract+amp*(-0.29227*c-0.90649*s)
    blue  = fract+amp*( 1.97294*c)

    r = N.clip(red*255, 0, 255)
    g = N.clip(green*255, 0, 255)
    b = N.clip(blue*255, 0, 255)
    a = N.zeros(nlev)+255

    return N.column_stack( (b,g,r,a) ).astype(N.intc)

def stepCMap(cmap, n):
    """Give color map, interpolate to produce n steps and return stepped
    colormap."""

    if n == 0:
        return N.vstack( ([-1,0,0,0], cmap) ).astype(N.intc)

    cmap = N.array(cmap, dtype=N.float64)
    x = N.linspace(0, 1, n)
    xp = N.linspace(0, 1, len(cmap))

    b = N.interp(x, xp, cmap[:,0])
    g = N.interp(x, xp, cmap[:,1])
    r = N.interp(x, xp, cmap[:,2])
    a = N.interp(x, xp, cmap[:,3])

    return N.vstack( ([-1,0,0,0], N.column_stack((b,g,r,a))) ).astype(N.intc)

class ColorMaps:
    """Class representing defined color maps.

    This is initialised from the default list.

    Also supported are functional color maps,
    e.g. cubehelix(start[,rotations[,hue[,gamma]]])

    Colormaps with steps -stepN where N is an integer or missing are
    also automatically generated.
    """

    def __init__(self):
        self.wipe()

    def wipe(self):
        """Reset colormaps to default state."""
        self.maps = dict(_defaultmaps)

        # these are maps encoded as byte strings
        for name, val in _defaultmaps_enc.items():
            self.maps[name] = N.frombuffer(val, dtype=N.uint8).reshape(-1,4)

    def get(self, idx, default=None):
        try:
            return self[idx]
        except KeyError:
            return default

    def __getitem__(self, key):
        """Lookup and return colormap."""

        origkey = key = key.strip()

        if key in self.maps:
            return self.maps[key]

        # does the name end in stepXXX ?
        step = None
        sm = re.match(r'^(.+)-step([0-9]*)$', key)
        if sm is not None:
            if sm.group(2):
                step = int(sm.group(2))
            else:
                step = 0
            key = sm.group(1)

        cmap = None
        if key in self.maps:
            cmap = self.maps[key]
        else:
            # match cubehelix(a,b,c,d), where b, c and d are optional numerics
            # giving start, rotations, hue and gamma
            cm = re.match(
                r'^cubehelix\s*\('
                r'(?:\s*(-?[0-9.]+))?'
                r'(?:\s*,\s*(-?[0-9.]+))?'
                r'(?:\s*,\s*(-?[0-9.]+))?'
                r'(?:\s*,\s*(-?[0-9.]+))?'
                r'\s*\)$',
                key)

            if cm is not None:
                vals = []
                for i, v in enumerate(cm.groups()):
                    try:
                        vals.append(float(v))
                    except (ValueError, TypeError):
                        vals.append((0,1,1,1)[i])
                cmap = cubehelix(*vals)

        if cmap is None:
            raise KeyError('Invalid colormap name')

        # apply steps to colormap
        if step is not None:
            cmap = stepCMap(cmap, step)

        # cache result and return
        self.maps[origkey] = cmap
        return cmap

    def __setitem__(self, key, val):
        self.maps[key] = val

    def __contains__(self, key):
        return self.get(key) is not None

    def __iter__(self):
        items = set(self.maps)
        items.update([
            'cubehelix(0.5,-1.5,1,1)',
            'bluegreen-step',
            'complement-step',
            'grey-step5',
            'grey-step6',
            'royal-step',
            'spectrum-step',
            'transblack-step5',
            'green-magenta-step16',
            'blue-darkred-step12',
            'blue-darkorange-step12',
            'brown-blue-step12',
            'blue-orange-step12',
            'seq-step25',
        ])
        return iter(items)

def applyScaling(data, mode, minval, maxval):
    """Apply a scaling transformation on the data.
    data is a numpy array
    mode is one of 'linear', 'sqrt', 'log', or 'squared'
    minval is the minimum value of the scale
    maxval is the maximum value of the scale

    returns transformed data, valid between 0 and 1
    """

    # catch naughty people by hardcoding a range
    if minval == maxval:
        minval, maxval = 0., 1.

    if mode == 'linear':
        # linear scaling
        data = (data - minval) * (1./(maxval - minval))

    elif mode == 'sqrt':
        # sqrt scaling
        # translate into fractions of range
        data = (data - minval) * (1./(maxval - minval))
        # clip off any bad sqrts
        data[data < 0.] = 0.
        # actually do the sqrt transform
        data = N.sqrt(data)

    elif mode == 'log':
        # log scaling of image
        with N.errstate(invalid='ignore', divide='ignore'):
            invrange = 1./(N.log(maxval)-N.log(minval))
            data = (N.log(data)-N.log(minval)) * invrange
        data[~N.isfinite(data)] = N.nan

    elif mode == 'squared':
        # squared scaling
        # clip any negative values
        lowermin = data < minval
        data = (data-minval)**2 / (maxval-minval)**2
        data[lowermin] = 0.

    else:
        raise RuntimeError('Invalid scaling mode "%s"' % mode)

    return data

def applyColorMap(cmap, scaling, datain, minval, maxval,
                  trans, transimg=None):
    """Apply a colour map to the 2d data given.

    cmap is the color map (numpy of BGRalpha quads)
    scaling is scaling mode => 'linear', 'sqrt', 'log' or 'squared'
    data are the imaging data
    minval and maxval are the extremes of the data for the colormap
    trans is a number from 0 to 100
    transimg is an optional image to apply transparency from
    Returns a QImage
    """

    cmap = N.array(cmap, dtype=N.intc)

    # invert colour map if min and max are swapped
    if minval > maxval:
        minval, maxval = maxval, minval
        if cmap[0,0] >= 0:
            # reverse standard colormap
            cmap = cmap[::-1]
        else:
            # uses flag signal at start of array for stepped maps
            # ignore this in reverse
            cmap[1:] = cmap[-1:0:-1]

    # apply transparency
    if trans != 0:
        cmap = cmap.copy()
        cmap[:,3] = (
            cmap[:,3].astype(N.float32) * (100-trans) /
            100.).astype(N.intc)

    # apply scaling of data
    fracs = applyScaling(datain, scaling, minval, maxval)

    img = numpyToQImage(fracs, cmap, transimg is not None)
    if transimg is not None:
        applyImageTransparancy(img, transimg)
    return img

def makeColorbarImage(minval, maxval, scaling, cmap, transparency,
                      direction='horizontal', barsize=128):
    """Make a colorbar for the scaling given."""

    if scaling in ('linear', 'sqrt', 'squared'):
        # do a linear color scaling
        vals = N.arange(barsize)/(barsize-1.0)*(maxval-minval) + minval
        colorscaling = scaling
    elif scaling == 'log':
        # a logarithmic color scaling
        # we cheat here by actually plotting a linear colorbar
        # and telling veusz to put a log axis along it
        # (as we only care about the endpoints)
        # maybe should do this better...

        vals = N.arange(barsize)/(barsize-1.0)*(maxval-minval) + minval
        colorscaling = 'linear'
    else:
        raise RuntimeError('Invalid scaling')

    # convert 1d array to 2d image
    if direction == 'horizontal':
        vals = vals.reshape(1, barsize)
    else:
        assert direction == 'vertical'
        vals = vals.reshape(barsize, 1)

    img = applyColorMap(
        cmap, colorscaling, vals, minval, maxval, transparency)

    return img

def getColormapArray(cmap, nvals):
    """Get [R,G,B,alpha] array of nvals for colormap array given.

    number of values to return is given by nvals
    """

    img = makeColorbarImage(0, 1, 'linear', cmap, 0, barsize=nvals)

    # ensure data are stored in the correct order
    fmt = qt.QImage.Format.Format_ARGB32
    if img.format() != fmt:
        img = img.convertToFormat(fmt)

    # convert image pointer to numpy array (assumes nvals*4 bytes)
    cv = N.array(img.constScanLine(0).asarray(nvals*4)).reshape((nvals,4))

    # swap into RGBA
    cv = N.column_stack(( cv[:,2], cv[:,1], cv[:,0], cv[:,3] ))

    return cv
