This file is indexed.

/usr/share/psychtoolbox-3/PsychDemos/RenderDemo.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
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
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
% RenderDemo
%
% Illustrates calibration interface for simple task of producing a uniform
% color patch of desired CIE xyY coordinates.
%
% The calculation is done with respect to the current PTB demonstration
% calibration file.
%
% The demo shows multiple different ways to implement this, starting with a
% purely Matlab based method, progressing to more advanced methods. The
% final demonstration shows how to do it automatically and graphics
% hardware accelerated.
%
% Demo 1:
%
% The RGB values are gamma corrected and live in the range [0,1].  If they
% contain 0 or 1, the xyY coordinates requested may have been out of gamut.
%
% A uniform color patch is displayed in the MATLAB figure window. This is
% not a well-controlled display method, but does give a sense of the patch
% color if the calibration file is a reasonable description of the display.
%
% Immediately afterwards, the same color patch is shown in a PTB onscreen
% window, with the same gamma table loaded which was used during
% calibration measurements. This should render an accurate stimulus.
%
% Demo 2: As demo 1, but displaying in a onscreen window and performing the
% gamma correction via proper inverse gamma lookup tables loaded into the
% graphics card, thereby presenting on a linearized display, instead of
% using the SensorToSettings() routine to adapt the stimulus to a
% non-linearized display.
%
% The last two demos Demo 3 and Demo 4 require a recent graphics card and
% perform all color space conversions and calibrated display automatically
% and hardware accelerated on the graphics card. Any NVidia GeForce-8000 or
% later, AMD Radeon X-1000 or later, or Intel HD graphics card should be
% able to support these demos.
%
% Demo 3: The stimulus is defined in XYZ tristimulus color space and
% converted automatically by Screen() into RGB output format, taking the
% calibration data in 'cal' into account.
%
% Demo 4: The stimulus is directly defined in xyY chromacity + luminance
% format and all conversions and calibrations are done automatically by
% Screen().
%
% 4/26/97  dhb  Wrote it.
% 7/25/97  dhb  Better initialization.
% 3/12/98  dgp  Use Ask.
% 3/14/02  dhb  Update for OpenWindow.
% 4/03/02  awi  Merged in Windows changes.  On Windows we do not copy the result to the clipboard. 
% 4/13/02  awi	Changed "SetColorSpace" to new name "SetSensorColorSpace".
%				Changed "LinearToSettings" to new name "SensorToSettings".
% 12/21/02 dhb  Remove reliance on now obsolete OpenWindow/CloseWindow.
% 11/16/06 dhb  Start getting this to work with PTB-3.
% 11/22/06 dhb  Fixed except that Ask() needs to be fixed.
% 6/16/11  dhb  The PTB display section was out of date and didn't work.  I removed it.
% 1/26/13  mk   Add standard PTB display, but also imaging pipeline based methods.

% Clear out workspace
clear

% Load default calibration file:
cal = LoadCalFile('PTB3TestCal');
load T_xyz1931
T_xyz1931 = 683*T_xyz1931;
cal = SetSensorColorSpace(cal,T_xyz1931,S_xyz1931);
cal = SetGammaMethod(cal,0);

% Get xyY, render, and report.
xyY = input('Enter xyY (as a row vector) default [.3 .3 50]: ')';
if isempty(xyY)
    xyY = [.3 .3 50]';
end

% Pure software conversion:
XYZ = xyYToXYZ(xyY);
[RGB, outOfRangePixels] = SensorToSettings(cal, XYZ);
fprintf('Computed RGB: [%g %g %g]\n', RGB(1), RGB(2), RGB(3));

% Check for out-of-range non-displayable color values:
if any(outOfRangePixels)
    fprintf('WARNING: Out of range RGB values -- not displayable!\n');
end

% Make it an image
nX = 256; nY = 128;
theRGBCalFormat = RGB*ones(1,nX*nY);
theRGBImage = CalFormatToImage(theRGBCalFormat,nX,nY);

% Show in a Matlab figure window.  This will not be calibrated,
% but gives the general sense.  Use PTB display routines for
% more precise display.
figure; clf;
h = image(theRGBImage);
title('Here is the color');
set(gca,'XTickLabel','')
set(gca,'YTickLabel','')
set(gca,'XTick',[]);
set(gca,'YTick',[])
drawnow;

fprintf('\n\nPress any key to continue. This will do the same thing in a set of Psychtoolbox onscreen windows.\n');
KbStrokeWait(-1);
close all;
drawnow;

try
    % Open window in GUI mode, top-left, 300 x 300 pixels:
    AssertOpenGL;
    
    % Define our desired background color in RGB primary space:
    % RGB = [0.01, 0.01, 0.01] for almost black.
    bgcolor = [0.01; 0.01; 0.01];

    % Declutter our output for this demo:
    Screen('Preference', 'SuppressAllWarnings', 1);
    
    % Skip display sync tests:
    oldsync = Screen('Preference', 'SkipSyncTests', 2);

    % Select display screen to show windows:
    screenId = max(Screen('Screens'));
    
    [win0, winRect0] = Screen('OpenWindow', screenId, bgcolor * 255, [0 0 300 300], [], [], [], [], [], kPsychGUIWindow);
    
    % Load the gamma table which was used during calibration measurements:
    % If this is a 1024 slot table we downsample to 256 slots, so it works
    % with MS-Windows, otherwise we hope it is a compatible table.
    % We could do better here, but this is just a demo...
    if length(cal.gammaInput) == 1024
        gammaInput = cal.gammaInput(1:4:end);
    else
        gammaInput = cal.gammaInput;
    end
    
    % Replicate to 3 columns for the three primary colors:
    gammaInput = repmat(gammaInput, 1, 3);
    
    % Before table upload, we store a backup copy of the original table, so
    % it can get restored at end of session:
    BackupCluts(screenId);
    Screen('LoadNormalizedGammaTable', screenId, gammaInput);
    
    % Convert new theRGBImage to texture and draw it into win1:
    tex = Screen('MakeTexture', win0, round(theRGBImage * 255));
    Screen('DrawTexture', win0, tex);
    Screen('Close', tex);
    
    % Show it:
    Screen('Flip', win0);
    dstRect0 = CenterRect([0 0 nX nY], winRect0);
    readBack0 = Screen('GetImage', win0, dstRect0);
    
    fprintf('\n\nPress any key to continue. This will demonstrate another way, using SensorToPrimary() + \n');
    fprintf('a proper inverse gamma table, to linearize your display, instead of SensorToSettings().\n\n');
    KbStrokeWait(-1);
    
    % Close old window, as its content is not compatible with the gamma
    % table we're gonna set now:
    sca;
    
    % Show same thing in a GUI window of 300 x 300 pixels.
    fprintf('Now we do exactly the same thing, just displaying in a onscreen window.\n');
    fprintf('However, we use gamma correction via the graphics hardware, so we have a linearized\n');
    fprintf('display. This allows to use the simpler SensorToPrimary() instead of SensorToSettings().\n\n');
    
    % Open a standard window:
    [win1, winRect1] = Screen('OpenWindow', screenId, bgcolor * 255, [0 0 300 300], [], [], [], [], [], kPsychGUIWindow);
    
    % Load a gamma correction table into the graphics card, as defined as
    % the inverse gamma table for given measured display gamma table
    % 'cal.gammaTable'. However, we sub-sample the table to 256 slots to
    % make sure it works on MS-Windows, not only on OSX or Linux:
    iGammaTable = InvertGammaTable(cal.gammaInput, cal.gammaTable, 256);
    
    % Load inverse gamma table into GPU:
    Screen('LoadNormalizedGammaTable', screenId, iGammaTable);
    
    % Ok, now we have a linearized display due to gamma correction. This means
    % we can define our stimulus in tristimulus XYZ space. This allows us to
    % use the simpler SensorToPrimary() function instead of the more complex
    % SensorToSettings() function:
    XYZ = xyYToXYZ(xyY);
    RGB = SensorToPrimary(cal, XYZ);
    fprintf('Recomputed linear RGB: [%g %g %g]\n', RGB(1), RGB(2), RGB(3));

    % Check for out-of-range non-displayable color values:
    if any(RGB < 0 | RGB > 1)
        fprintf('WARNING: Out of range RGB values -- not displayable!\n');
    end
    
    % Make it an image. Now need to scale by 255, as onscreen windows want
    % color values in range 0 - 255 instead of 0 - 1 by default:
    nX = 256; nY = 128;
    theRGBCalFormat = RGB * 255 * ones(1,nX*nY);
    theRGBImage = CalFormatToImage(theRGBCalFormat,nX,nY);
    
    % Convert new theRGBImage to texture and draw it into win1:
    tex = Screen('MakeTexture', win1, round(theRGBImage));
    Screen('DrawTexture', win1, tex);
    Screen('Close', tex);
    
    % Show it:
    Screen('Flip', win1);
    dstRect1 = CenterRect([0 0 nX nY], winRect1);
    readBack1 = Screen('GetImage', win1, dstRect1);
    
    fprintf('\n\nPress any key to continue. This will demonstrate a simpler way to do it via the imaging pipeline.\n');
    fprintf('Screen() will automatically convert XYZ tristimulus color values to calibrated RGB values before display.\n\n');
    KbStrokeWait(-1);
    
    % Make sure this will actually work:
    AssertGLSL;
    
    % Open a 2nd window, now using the imaging pipeline:
    PsychImaging('PrepareConfiguration');
    
    % Enable 32 bpc floating point framebuffer, so fractional color values
    % can be represented accurately. We will store XYZ tristimulus color
    % values in the frambuffer, not RGB values:
    PsychImaging('AddTask', 'General', 'FloatingPoint32Bit');
    
    % Also use unrestricted color range for writing arbitrary color values
    % to the framebuffer:
    PsychImaging('AddTask', 'General', 'NormalizedHighresColorRange');
    
    % It shall use builtin fast SensorToPrimary() plugin:
    PsychImaging('AddTask', 'AllViews', 'DisplayColorCorrection', 'SensorToPrimary');
    
    % Check for valid (displayable) final color values in 0.0 - 1.0 range.
    % Mark out-of-range pixels visually:
    PsychImaging('AddTask', 'AllViews', 'DisplayColorCorrection', 'CheckOnly');
    
    % Open it: Our window operates in XYZ color space, so we need to define
    % a XYZ background input color that leads to our desired background
    % color 'bgcolor':
    background = PrimaryToSensor(cal, bgcolor);
    [win2, winRect2] = PsychImaging('OpenWindow', screenId, background, [310 0 610 300], [], [], [], [], [], kPsychGUIWindow);
    
    % Assign 'cal' struct for XYZ -> RGB conversion:
    PsychColorCorrection('SetSensorToPrimary', win2, cal);
    
    % Compared to above, we can skip the SensorToPrimary step:
    XYZ = xyYToXYZ(xyY);
    
    % Simply draw to the framebuffer, directly in XYZ format instead of RGB:
    % We can use fillrect to draw the patch, without intermediate need for
    % textures:
    dstRect2 = CenterRect([0 0 nX nY], winRect2);
    Screen('FillRect', win2, XYZ, dstRect2);
    
    % Readback image in XYZ format from framebuffer:    
    readBack2In = Screen('GetImage', win2, [], 'drawBuffer', 1);
    
    % Show it:
    Screen('Flip', win2);
    
    % Read back final image from framebuffer, for correctness check:    
    readBack2 = Screen('GetImage', win2, dstRect2);
    
    % Plot manual and automatic result for comparison:
    close all;
    imshow(readBack1);
    figure;
    imshow(readBack2);
    
    fprintf('\n\nPress any key to continue. This will demonstrate the most simple way to do it via the imaging pipeline.\n');
    fprintf('This method allows to draw and define your stimulus completely in the xyY chromacity+luminance color space.\n');
    fprintf('Screen() will automatically convert your xyY color values to proper RGB framebuffer values before display.\n\n');
    KbStrokeWait(-1);
    
    % Now the same thing, but we draw colors directly in (x,y) chromacity and Y
    % luminance format [x,y,Y] into the framebuffer. The imaging pipeline
    % will do the complete conversion from xyY space to XYZ space and then
    % XYZ space to RGB space, followed by gamma correction by the graphics
    % card for display linearization:
    % Open a 2nd window, now using the imaging pipeline:
    PsychImaging('PrepareConfiguration');
    
    % Enable 32 bpc floating point framebuffer, so fractional color values
    % can be represented accurately. We will store xyY chromacity +
    % luminance color values in the frambuffer, not RGB values:
    PsychImaging('AddTask', 'General', 'FloatingPoint32Bit');
    
    % Also use unrestricted color range for writing arbitrary color values
    % to the framebuffer:
    PsychImaging('AddTask', 'General', 'NormalizedHighresColorRange');

    % It shall use builtin fast xyYToXYZ() plugin for xyY -> XYZ conversion:
    PsychImaging('AddTask', 'AllViews', 'DisplayColorCorrection', 'xyYToXYZ');
    
    % It shall use builtin fast SensorToPrimary() plugin:
    PsychImaging('AddTask', 'AllViews', 'DisplayColorCorrection', 'SensorToPrimary');

    % Check for valid (displayable) final color values in 0.0 - 1.0 range.
    % Mark out-of-range pixels visually:
    PsychImaging('AddTask', 'AllViews', 'DisplayColorCorrection', 'CheckOnly');
    
    % Open it: Our window operates in xyY color space, so we need to define
    % a xyY background input color that leads to our desired background
    % color 'bgcolor':
    background = XYZToxyY(PrimaryToSensor(cal, bgcolor));
    [win3, winRect3] = PsychImaging('OpenWindow', screenId, background, [0 330 300 630], [], [], [], [], [], kPsychGUIWindow);
    
    % Assign 'cal' struct for XYZ -> RGB conversion:
    PsychColorCorrection('SetSensorToPrimary', win3, cal);
    
    % Simply draw to the framebuffer, directly in xyY format:
    dstRect3 = CenterRect([0 0 nX nY], winRect3);
    Screen('FillRect', win3, xyY, dstRect3);
    
    % Readback image in xyY format from framebuffer:
    readBack3In = Screen('GetImage', win3, dstRect3, 'drawBuffer', 1);
    
    % Show it:
    Screen('Flip', win3);
    
    % Read back final image from framebuffer, for correctness check:
    readBack3 = Screen('GetImage', win3, dstRect3);

    % Plot manual and automatic result for comparison:    
    close all;
    imshow(readBack1);
    figure;
    imshow(readBack3);

    fprintf('Press any key to end the demo.\n');
    KbStrokeWait(-1);
    
    % sca closes all onscreen windows and restores the original gamma tables:
    sca;
    
    Screen('Preference', 'SuppressAllWarnings', 0);
    Screen('Preference', 'SkipSyncTests', oldsync);

catch %#ok<CTCH>
    sca;
    Screen('Preference', 'SuppressAllWarnings', 0);
    Screen('Preference', 'SkipSyncTests', oldsync);
    psychrethrow(psychlasterror);
end