This file is indexed.

/usr/share/pyshared/tvtk/util/ctf.py is in mayavi2 4.1.0-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
"""Color transfer function related code.

"""
# Author: Prabhu Ramachandran <prabhu@aero.iitb.ac.in>
# Copyright (c) 2006-2009, Enthought, Inc.
# License: BSD Style.

# Enthought library imports.
from traits.api import List
from tvtk.api import tvtk


##########################################################################
# Color transfer function related utility code from MayaVi1.
##########################################################################
def _err_msg(obj, cls_name):
    return '%s %s does not have either a "nodes" attribute or a '\
           '"get_node_value" method'%(cls_name, str(obj))

def save_ctfs(volume_property):
    """Given a `tvtk.VolumeProperty` it saves the state of the RGB and
    opacity CTF to a dictionary and returns that.

    The 'rgb' key stores a list of (x, r, g, b) and the 'alpha' a list
    of (x, a) values.
    """
    vp = volume_property
    ctf = vp.rgb_transfer_function
    otf = vp.get_scalar_opacity()
    s1, s2 = ctf.range
    # The RGB values.
    nc = ctf.size
    rgb = []
    if hasattr(ctf, 'nodes'):
        for i in range(nc):
            x = ctf.nodes[i]
            r, g, b = ctf.get_color(x)
            rgb.append([x, r, g, b])
    elif hasattr(ctf, 'get_node_value'):
        val = [0]*6
        for i in range(nc):
            ctf.get_node_value(i, val)
            rgb.append(val[:4])
    else:
        raise TypeError, _err_msg(ctf, 'ColorTransferFunction')

    # The Alpha values.
    na = otf.size
    a = []
    if hasattr(otf, 'nodes'):
        for i in range(na):
            x = otf.nodes[i]
            val = otf.get_value(x)
            a.append([x, val])
    elif hasattr(otf, 'get_node_value'):
        val = [0]*4
        for i in range(na):
            otf.get_node_value(i, val)
            a.append(val[:2])
    else:
        raise TypeError, _err_msg(otf, 'PiecewiseFunction')

    return {'range': (s1, s2), 'rgb':rgb, 'alpha':a}

def load_ctfs(saved_data, volume_property):
    """ Given the saved data produced via `save_ctfs`, this sets the
    state of the passed volume_property appropriately.

    It returns the new color transfer function and piecewise function.
    """
    rgb = saved_data['rgb']
    a = saved_data['alpha']

    # The new_ctf/otf shenanigans are necessary because if the ctf/otf
    # go out of scope we loose the node information.  This is because
    # the tvtk object is really a dynamically generated wrapper.

    # First do the RGB values ...
    new_ctf = True
    ctf = volume_property.rgb_transfer_function
    if isinstance(ctf, ColorTransferFunction):
        new_ctf = False
        ctf.remove_all_points()
    else:
        ctf = ColorTransferFunction()
    nc = len(rgb)
    for i in range(nc):
        ctf.add_rgb_point(rgb[i][0], *(rgb[i][1:]))
    if new_ctf:
        volume_property.set_color(ctf)
    try:
        ctf.range = saved_data['range']
    except Exception:
        # VTK versions < 5.2 don't seem to need this.
        pass
    # and then the alpha values.
    na = len(a)
    new_otf = True
    otf = volume_property.get_scalar_opacity()
    if isinstance(otf, PiecewiseFunction):
        new_otf = False
        otf.remove_all_points()
    else:
        otf = PiecewiseFunction()
    for i in range(na):
        otf.add_point(a[i][0], a[i][1])
    if new_otf:
        volume_property.set_scalar_opacity(otf)
    return ctf, otf

def rescale_ctfs(volume_property, new_range):
    """ Given the volume_property with a new_range for the data while
    using the same transfer functions, this function rescales the
    CTF's so that everything works OK.

    It returns the CTF and OTF.
    """
    ctf = volume_property.rgb_transfer_function
    otf = volume_property.get_scalar_opacity()
    old_range = ctf.range
    def _rescale_value(x, old, new):
        nx = (x - old[0])/(old[1] - old[0])
        return new[0] + nx*(new[1] - new[0])
    if new_range[0] != old_range[0] and new_range[1] != old_range[1]:
        s_d = save_ctfs(volume_property)
        # Set the new range making sure that they are in the right order.
        s1, s2 = new_range
        if s1 > s2:
            s_d['range'] = (s2, s1)
        else:
            s_d['range'] = (s1, s2)
        # Rescale the RGB values.
        rgb = s_d['rgb']
        for v in rgb:
            v[0] = _rescale_value(v[0], old_range, new_range)
        # Rescale the alpha values.
        alpha = s_d['alpha']
        for v in alpha:
            v[0] = _rescale_value(v[0], old_range, new_range)
        # Now load the rescaled values.
        ctf, otf = load_ctfs(s_d, volume_property)
    return ctf, otf

def set_lut(lut, volume_property):
    """Given a `tvtk.LookupTable` and a `tvtk.VolumeProperty` it saves
    the state of the RGB and opacity CTF from the volume property to
    the LUT.  The number of colors to use is obtained from the LUT and
    not the CTF.
    """
    vp = volume_property
    ctf = vp.rgb_transfer_function
    otf = vp.get_scalar_opacity()
    s1, s2 = ctf.range
    nc = lut.number_of_colors
    ds = float(s2-s1)/(nc - 1)
    for i in range(nc):
        r, g, b = ctf.get_color(s1 + i*ds)
        a = otf.get_value(s1 + i*ds)
        lut.set_table_value(i, r, g, b, a)

def set_ctf_from_lut(lut, volume_property):
    """Given a `tvtk.LookupTable` and a `tvtk.VolumeProperty` it loads
    the state of the RGB and opacity CTF from the lookup table to the
    CTF.  The CTF range is obtained from the volume property and the
    number of colors to use is obtained from the LUT.
    """
    vp = volume_property
    ctf = vp.rgb_transfer_function
    s1, s2 = ctf.range
    nc = lut.number_of_colors
    ds = float(s2-s1)/(nc - 1)
    ctf = ColorTransferFunction()
    otf = PiecewiseFunction()
    for i in range(nc):
        v = s1 + i*ds
        r, g, b, a = lut.get_table_value(i)
        ctf.add_rgb_point(v, r, g, b)
        otf.add_point(v, a)
    volume_property.set_color(ctf)
    volume_property.set_scalar_opacity(otf)


##########################################################################
# `ColorTransferFunction` class.
##########################################################################
class ColorTransferFunction(tvtk.ColorTransferFunction):
    """Overrides a few important methods that allow us to glean node
    information.  This is useful in cases where the super class does
    not have methods to get the nodes.
    """

    # Stores the nodes used by the CTF.  Note that this is not a
    # proper trait and modifying this will not change the underlying
    # VTK object.
    nodes = List

    def add_rgb_point(self, *args):
        """V.add_rgb_point(float, float, float, float) -> int
        V.add_rgb_point(float, float, float, float, float, float) -> int

        Add/Remove a point to/from the function defined in RGB or HSV
        Return the index of the point (0 based), or -1 on error.

        Wrapper around parent class functionality to store node
        information.

        """
        ret = super(ColorTransferFunction, self).add_rgb_point(*args)
        self.nodes.append(args[0])
        self.nodes.sort()
        return ret

    def add_hsv_point(self, *args):
        """V.add_hsv_point(float, float, float, float) -> int
        V.add_hsv_point(float, float, float, float, float, float) -> int

        Add/Remove a point to/from the function defined in RGB or HSV
        Return the index of the point (0 based), or -1 on error.

        Wrapper around parent class functionality to store node
        information.

        """
        ret = super(ColorTransferFunction, self).add_hsv_point(*args)
        self.nodes.append(args[0])
        self.nodes.sort()
        return ret

    def remove_all_points(self):
        """Remove all the points.
        """
        super(ColorTransferFunction, self).remove_all_points()
        self.nodes = []


##########################################################################
# `PiecewiseFunction` class.
##########################################################################
class PiecewiseFunction(tvtk.PiecewiseFunction):
    """Overrides a few important methods that allow us to glean node
    information.  This is useful in cases where the super class does
    not have methods to get the nodes.
    """

    # Stores the nodes used by the function.  Note that this is not a
    # proper trait and modifying this will not change the underlying
    # VTK object.
    nodes = List

    def initialize(self):
        """V.initialize()

        Clears out the current function. A newly created
        PiecewiseFunction is alreay initialized, so there is no need
        to call this method which in turn simply calls
        remove_all_points()
        """
        super(PiecewiseFunction, self).initialize()
        self.nodes = []

    def add_point(self, x, val):
        """V.add_point(float, float) -> int
        V.add_point(float, float, float, float) -> int

        Add/Remove points to/from the function. If a duplicate point
        is added then the function value is changed at that location.
        Return the index of the point (0 based), or -1 on error.
        """
        ret = super(PiecewiseFunction, self).add_point(x, val)
        self.nodes.append(x)
        self.nodes.sort()
        return ret

    def remove_point(self, x):
        """V.remove_point(float) -> int

        Add/Remove points to/from the function. If a duplicate point
        is added then the function value is changed at that location.
        Return the index of the point (0 based), or -1 on error.
        """
        ret = super(PiecewiseFunction, self).remove_point(x)
        self.nodes.remove(x)
        self.nodes.sort()
        return ret

    def remove_all_points(self):
        """Remove all the points.
        """
        super(PiecewiseFunction, self).remove_all_points()
        self.nodes = []