This file is indexed.

/usr/share/octave/packages/image-2.2.2/stretchlim.m is in octave-image 2.2.2-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
## Copyright (C) 2004 Josep Mones i Teixidor <jmones@puntbarra.com>
##
## 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 3 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, see <http://www.gnu.org/licenses/>.

## -*- texinfo -*-
## @deftypefn {Function File} {@var{LOW_HIGH} = } stretchlim (@var{I},@var{TOL})
## @deftypefnx {Function File} {@var{LOW_HIGH} = } stretchlim (@var{I})
## @deftypefnx {Function File} {@var{LOW_HIGH} = } stretchlim (@var{RGB},@var{TOL})
## @deftypefnx {Function File} {@var{LOW_HIGH} = } stretchlim (@var{RGB})
## Finds limits to contrast stretch an image
##
## @code{LOW_HIGH=stretchlim(I,TOL)} returns a vector @var{LOW_HIGH}
## which contains a pair of intensities which can be used in
## @code{imadjust} to stretch the contrast of an image, first of them
## will be lower value (@code{imadjust} would assign 0 to it) and second
## is the upper bound. @var{TOL} specifies the fraction of the image to
## saturate at lower and upper limits. It can be a vector of length 2:
## @code{[LOW_FRACT, HIGH_FRACT]}, or it can be a scalar, in that case
## @code{[LOW_FRACT, HIGH_FRACT]=[TOL, 1-TOL]}.
##
## @var{TOL} can't be larger than 0.50 and for TOL=0 then
## @code{LOW_HIGH=[min(I(:)), max(I(:))]}.
##
## @code{LOW_HIGH=stretchlim(I)} behaves as described but defaults
## @var{TOL} to @code{[0.01, 0.99]}.
##
## @code{LOW_HIGH=stretchlim(RGB,TOL)} returns a 2-by-3 matrix in
## @var{LOW_HIGH} of lower and upper values to saturate for each plane
## of the RGB image in M-by-N-by-3 array @var{RGB}. @var{TOL} is a
## vector or a scalar, as described above, and the same fractions are
## applied for each plane.
##
## @code{LOW_HIGH=stretchlim(RGB)} uses @code{[0.01, 0.99]} as default
## value for @var{TOL}.
##
## @strong{Notes:}
##
## Values in @var{LOW_HIGH} are of type double and comprised between 0
## and 1 regardless class of input image.
##
## @strong{Compatibility notes:}
##
## @itemize @bullet
## @item
## int* and uint* types are still not implemented (waiting for support
## in Octave 2.1.58).
## @item
## This function tries to find limits that are nearer to saturate
## requested interval. So, for instance, if you requested a 5% and it
## has to choose between discarding a 1% and a 7%, it will choose the
## later despite being more than requested. This should be test against
## MATLAB behaviour.
## @end itemize
##
## @seealso{imadjust}
## @end deftypefn

function LOW_HIGH = stretchlim(image, TOL)
  if (nargin<1 || nargin>2)
    print_usage;
  endif
  
  if(!ismatrix(image) || ischar(image))
    error("stretchlim: image should be a matrix");
  endif
  
  ## Prepare limits
  if(nargin==1)
    low_count=0.01;
    high_count=0.01;                ## we use this definition in __stretchlim_plane__
  else
    if(isscalar(TOL))
      if(TOL<0 || TOL>=0.5)
        error("stretchlim: TOL out of bounds. Expected: 0<=TOL<0.5");
      endif
      low_count=TOL;
      high_count=TOL;               ## as before...
    elseif(isvector(TOL))
      if(length(TOL)!=2)
        error("stretchlim: TOL length must be 2.");
      endif
      low_count=TOL(1);
      high_count=1-TOL(2);          ## as before...
    else
      error("stretchlim: TOL contains an invalid value.");
    endif
  endif

  ## well use size of image several times...
  simage=size(image);

  ## Convert fractions to pixels
  psimage=prod(simage(1:2));
  low_count*=psimage;
  high_count*=psimage;

  if(length(simage)<=2)
    ## intensity
    LOW_HIGH=__stretchlim_plane__(image, low_count, high_count);
  elseif(length(simage)==3 && simage(3)==3)
    ## RGB
    LOW_HIGH=zeros(2,3);
    for i=1:3
      LOW_HIGH(:,i)=__stretchlim_plane__(image(:,:,i), low_count, ...
                                         high_count);
    endfor
  else
    error("stretchlim: invalid image.");
  endif
endfunction


## Processes a plane
## high_count is defined so that high_count=elements is the same as
## low_count=elements (and not total_elements-elements)
function LOW_HIGH = __stretchlim_plane__(plane, low_count, high_count)
  ## check exceptions
  if(low_count==0 && high_count==0)
    LOW_HIGH=[min(plane(:)); max(plane(:))];
  else

    ## we sort values
    sorted=sort(plane(:));
    
    low=sorted(round(low_count+1));
    pos=find(sorted>low);
    if(length(pos)>0)
      low2=sorted(pos(1));
      d1=low_count-sum(sorted<low);
      d2=sum(sorted<low2)-low_count;
      if(d2<d1)
        low=low2;
      endif
    endif
      
    high=sorted(end-round(high_count));
    pos=find(sorted<high);
    if(length(pos)>0)
      high2=sorted(pos(end));
      d1=high_count-sum(sorted>high);
      d2=sum(sorted>high2)-high_count;
      if(d2<d1)
        high=high2;
      endif
    endif

    ## set result variable
    LOW_HIGH=[low;high];
  endif
endfunction

%!demo
%! stretchlim([1:100])
%! # This discards 1% of data from each end, 1 and 100.
%! # So result should be [2;99]

%!# some invalid params
%!error(stretchlim());
%!error(stretchlim("bad parameter"));
%!error(stretchlim(zeros(10,10,4)));
%!error(stretchlim(zeros(10,10,3,2)));
%!error(stretchlim(zeros(10,10),"bad parameter"));
%!error(stretchlim(zeros(10,10),0.01,2));


%!# default param
%!assert(stretchlim([1:100]),[2;99]);

%!# scalar TOL
%!assert(stretchlim([1:100],0.01),[2;99]);

%!# vector TOL
%!assert(stretchlim([1:100],[0.01,0.98]),[2;98]);

%!# TOL=0
%!assert(stretchlim([1:100],0),[1;100]);

%!# non uniform histogram tests
%!assert(stretchlim([1,ones(1,90)*2,92:100],0.05),[2;95]);
%!assert(stretchlim([1,ones(1,4)*2,6:100],0.05),[6;95]);

%!# test limit rounding...
%!assert(stretchlim([1,ones(1,5)*2,7:100],0.05),[7;95]); # 6% lost 
%!assert(stretchlim([1,ones(1,6)*2,8:100],0.05),[8;95]); # 7% lost
%!assert(stretchlim([1,ones(1,7)*2,9:100],0.05),[9;95]); # 8% lost
%!assert(stretchlim([1,ones(1,8)*2,10:100],0.05),[2;95]); # now he limit at 2 => 1% lost

%!# test RGB
%!test
%! RGB=zeros(100,1,3);
%! RGB(:,:,1)=[1:100];
%! RGB(:,:,2)=[2:2:200];
%! RGB(:,:,3)=[4:4:400];
%! assert(stretchlim(RGB),[2,4,8;99,198,396]);