This file is indexed.

/usr/share/psychtoolbox-3/PsychDemos/SimpleImageMixingDemo.m is in psychtoolbox-3-common 3.0.14.20170103+git6-g605ff5c.dfsg1-1build1.

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
function SimpleImageMixingDemo(morphType, showMaskOnly)
% SimpleImageMixingDemo([morphType=gaussian][, showMaskOnly=0])
%
% This is a simple demonstration of shader use to morph two images/textures 
% back and forth using a non-uniform transparency pattern (here illustrated 
% with gaussian and left-to-right ramp, but you can use virtually any
% transparency mask).
% 
% INPUTS:
% morphType - string, either 'gaussian' or 'ramp'
% showMaskOnly - 0/1 to either see the mask or the resulting morphing
%
% Made after ImageMixingTutorial.m by Mario Kleiner
% Written by Natalia Zaretskaya 25 Nov 2014

% Basepath to our own demo images:
basepath = [ PsychtoolboxRoot 'PsychDemos' filesep ];
imageFile = [basepath 'konijntjes1024x768blur.jpg'];

% Use normalized color range, ranging from 0 to 1
PsychDefaultSetup(2);

if nargin < 1 || isempty(morphType)
    % decide whether you want a ramp or a gaussian
    morphType = 'gaussian'; % 'ramp' or 'gaussian'
end

if nargin < 2 || isempty(showMaskOnly)
    showMaskOnly = 0;
end

% open window
[w, wrect] = PsychImaging('OpenWindow',  max(Screen('Screens')), [0.5 0.5 0.5], []);
[cx, xy] = RectCenter(wrect);
Screen('TextSize', w, 20)


% Open an offscreen window the same size as the onscreen window. We use
% this to define the alpha/mixing weight channel used to later mix
% two images together:
masktex = Screen('OpenOffscreenWindow', w, [0 0 0 0]);


% -- make textures -- %
mat1 = imread(imageFile); % nice bunnies
mat2 = rand(size(mat1)); % random noise

tex1 = Screen('MakeTexture', w, mat1);
tex2 = Screen('MakeTexture', w, mat2); % upside-down


% Create a shader that allows to combine the up to four input channels
% of a texture into a weighted linear combination, using 'DrawTexture's
% modulateColor parameter to specify the weights. This is used for
% morphing between up to four alpha-masks, stored in the morphedAlphaTexture.
minimorphshader = CreateSinglePassImageProcessingShader(w, 'WeightedColorComponentSum');

% Create a texture with alpha pattern we want to morph between.
if strcmp(morphType, 'ramp')
    morphPattern = meshgrid(0:RectWidth(wrect./2), 0:RectHeight(wrect./2));
    morphPattern = morphPattern./max(morphPattern(:));
    disp('using ramp!')
elseif strcmp(morphType, 'gaussian')
    xsd = 130; % standard deviation
    ysd = 130;
    x = -RectHeight(wrect./2)/2:RectHeight(wrect./2)/2;
    y = -RectHeight(wrect./2)/2:RectHeight(wrect./2)/2;
    [x,y] = meshgrid(x,y);
    morphPattern = exp( -((x / xsd).^2) - ((y / ysd).^2) ); % gauss
    disp('using gaussian!')
else
    sca
    error('Undefined morph pattern');
end
morphTex = Screen('MakeTexture', w, morphPattern, [], [], [], [], minimorphshader);



c = 1;
while 1
    
    % check keyboard:
    keyIsDown = KbCheck;
    if keyIsDown
        break
    end
    
    % for simplicity: sine modulation
    % morph values range from 0 (image A) to 2 (image B)
    % 1 corresponds to intermediate stage
    morphValue = (sin(0.01*c)+1);
    
    % A mask morphing from all-zero to a gauss blob to all-one and back:
    if morphValue < 1
        weights = [morphValue, 0, 0, 0];
    else
        eweight = morphValue - 1;
        weights = [1 - eweight, 0, 0, eweight];
    end
    Screen('DrawTexture', masktex, morphTex, [], CenterRectOnPoint(wrect./1.5, cx, xy), [], [], [], weights);
    
    % First clear framebuffer to backgroundcolor, not using
    % alpha blending (== GL_ONE, GL_ZERO). Enable all channels
    % for writing [1 1 1 1], so everything gets cleared to good
    % starting values:
    Screen('BlendFunction', w, GL_ONE, GL_ZERO, [0 0 0 1]);
    Screen('FillRect', w, [0.5 0.5 0.5]);
    
    % Then keep alpha blending disabled and draw the mask
    % texture, but *only* into the alpha channel. Don't touch
    % the RGB color channels but use the channel mask via
    % [R G B A] = [0 0 0 1] to only enable the alpha-channel
    % for drawing into it. Use of modulateColor = [1 0 0 0] and
    % the minimorphshader causes the red channel to be copied into
    % the alpha channel. As red == luminance this means the grayscale
    % luminance value of masktext directly defines the final mask weights.
    
    if showMaskOnly
        Screen('BlendFunction', w, GL_ONE, GL_ZERO, [1 1 1 1]); % => use [1 1 1 1] without drawing the images to visualize the mask        
        Screen('DrawTexture', w, masktex, [], [], [], [], [], [1 0 0 0], minimorphshader);
    else
        Screen('BlendFunction', w, GL_ONE, GL_ZERO, [0 0 0 1]); % => use [1 1 1 1] without drawing the images to visualize the mask
        Screen('DrawTexture', w, masktex, [], [], [], [], [], [1 0 0 0], minimorphshader);
        
        % draw first image
        Screen('BlendFunction', w, GL_DST_ALPHA, GL_ZERO, [1 1 1 0]);
        Screen('DrawTexture', w, tex1, [], CenterRectOnPoint(wrect./1.5, cx, xy));
        
        % draw second image
        Screen('BlendFunction', w, GL_ONE_MINUS_DST_ALPHA, GL_ONE, [1 1 1 0]);
        Screen('DrawTexture', w, tex2, [], CenterRectOnPoint(wrect./1.5, cx, xy));
    end
    
    % show morphing stage as value:
    myString = sprintf('morph stage 0 to 2: %1.1f ', morphValue);
    DrawFormattedText(w, myString, 0, 0, [1 0 0 ]);
    
    Screen('Flip', w);
    
    c = c+1; % update the count
end

sca
end