This file is indexed.

/usr/share/octave/packages/image-2.6.1/impyramid.m is in octave-image 2.6.1-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
## Copyright (C) 2015 Avinoam Kalma <a.kalma@gmail.com>
## Copyright (C) 2015 Carnë Draug <carandraug@octave.org>
##
## 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} {} impyramid (@var{im}, @var{direction})
## Compute gaussian pyramid expansion or reduction.
##
## Create image which is one level up or down in the Gaussian
## pyramid.  @var{direction} must be @qcode{"reduce"} or
## @qcode{"expand"}.  These operations are only done in the first
## two dimensions, so that even if @var{im} is a N dimensional
## array, only the number of rows and columns will change.
##
## The @qcode{"reduce"} stage is done by low-pass filtering and
## subsampling of 1:2 in each axis.  If the size of the original
## image is [M N], the size of the reduced image is
## @qcode{[ceil((M+1)/2) ceil((N+1)/2)]}.
##
## The @qcode{"expand"} stage is done by upsampling the image
## (2:1 in each axis), and then low-pass filtering.  If the size
## of the original image is [M N], the size of the expanded image
## is @code{[2M-1 2N-1]}.
##
## Note that image processing pyramids are upside down, so
## @qcode{"reduce"} is going one level @emph{down} in the pyramid,
## while @qcode{"expand"} is going one level @emph{up} in the pyramid.
##
## @example
## @group
## impyramid (im, "reduce");   # return reduced image (one level down)
## impyramid (im, "expand");   # return expanded image (one level up)
## @end group
## @end example
##
## The low-pass filter is defined according to Burt & Adelson [1]
## @code{W(i,j) = w(i)w(j)} where
## @code{w = [0.25-alpha/2 0.25 alpha 0.25 0.25-alpha/2]} with
## @code{alpha = 0.375}
##
## [1] Peter J. Burt and Edward H. Adelson (1983).  The Laplacian Pyramid
## as a Compact Image Code.  IEEE Transactions on Communications,
## vol. COM-31(4), 532-540.
##
## @seealso{imresize, imfilter}
## @end deftypefn

## Author: Avinoam Kalma <a.kalma@gmail.com>

function imp = impyramid (im, direction)

  if (nargin != 2)
    print_usage ();
  elseif (! isnumeric (im) && ! isbool (im))
    error ("impyramid: IM must be numeric or logical")
  endif

  ## low pass filters to be used
  alpha = 0.375;
  filt_horz = [(0.25-alpha/2)  0.25  alpha  0.25  (0.25-alpha/2)];
  filt_vert = filt_horz.';

  nd = ndims (im);
  sz = size (im);
  cl = class (im);
  switch (tolower (direction))
    case "reduce"
      ## vertical low pass filtering
      im = padarray (im, floor (size (filt_vert) /2), "replicate");
      im = convn (im, filt_vert, "valid");

      ## horizontal low pass filtering
      im = padarray (im, floor (size (filt_horz) /2), "replicate");
      im = convn (im, filt_horz, "valid");

      im = cast (im, cl);

      ## subsampling
      idx = repmat ({":"}, 1, nd);
      idx([1 2]) = {1:2:sz(1), 1:2:sz(2)};
      imp = im(idx{:});

    case "expand"
      ## Create image, twice the size (rows and columns only),
      ## with the original image on the odd pixels.
      imp_sz = sz .* postpad ([2 2], nd, 1);
      imp_sz([1 2]) -= 1;
      imp = zeros (imp_sz, cl);
      idx = repmat ({":"}, 1, nd);
      idx([1 2]) = {1:2:imp_sz(1), 1:2:imp_sz(2)};
      imp(idx{:}) = im;

      ## horizontal low pass filtering
      imp = padarray (imp, floor (size (filt_horz) /2));
      imp = convn (imp, filt_horz, "valid");
      imp *= 2;

      ## vertical low pass filtering
      imp = padarray (imp, floor (size (filt_vert) /2));
      imp = convn (imp, filt_vert, "valid");
      imp *= 2;

      imp = cast (imp, cl);

    otherwise
      error ("impyramid: DIRECTION must be 'reduce' or 'expand'")
  endswitch
endfunction

## Note that there are small differences, 1 and 2 gray levels, between
## the results here (the ones we get in Octave), and the ones we should
## have for Matlab compatibility.  This is specially true for elements
## in the border, and worse when expanding.

%!test
%! in = [116  227  153   69  146  194   59  130  139  106
%!         2   47  137  249   90   75   16   24  158   44
%!       155   68   46   84  166  156   69  204   32  152
%!        71  221  137  230  210  153  192  115   30  118
%!       107  143  108   52   51   73  101   21  175   90
%!        54  158  143   77   26  168  113  229  165  225
%!         9   47  133  135  130  207  236   43   19   73];
%!
%! reduced = [
%!     114  139  131  103  111
%!      97  122  141  110   99
%!     103  123  112  123  121
%!      47  107  134  153   94];
%!
%! ## this is what we should return if we were Matlab compatible
%! reduced_matlab = [
%!     114  139  131  103  111
%!      97  122  141  111  100
%!     103  123  112  123  122
%!      47  107  134  153   94];
%!
%! expanded = [
%!    88  132  160  154  132  108   94  102  120  138  138  100   66   74   96  112  116  104   78
%!    62   98  128  142  146  154  154  140  126  126  122   86   54   58   82  114  132  112   74
%!    36   54   74  100  130  168  184  156  118  104   92   64   40   44   66  100  122  104   66
%!    66   68   64   76   98  130  154  148  132  122  108   80   60   78  104  106   98   98   86
%!   104  106   88   78   78   96  122  144  154  154  140  112   98  124  144  110   74   92  106
%!   102  130  134  120  108  126  154  174  180  172  156  142  138  146  140   96   60   84  106
%!    88  140  170  158  140  156  180  188  180  164  152  154  156  140  112   82   66   84   96
%!    90  136  164  154  134  132  138  136  130  122  120  130  134  108   82   86  100  104   92
%!    92  126  142  136  116   96   80   74   72   82   94  106  106   88   78  108  138  132  102
%!    80  116  140  138  122   96   68   52   52   80  110  114  112  118  128  148  164  164  140
%!    58   98  132  140  130  110   82   62   62  102  142  144  138  154  168  164  156  170  162
%!    36   68  100  120  130  122  106   92   96  134  174  182  172  156  136  116  104  122  124
%!    16   34   58   86  108  114  110  106  112  138  170  184  172  126   74   48   44   60   68];
%!
%! ## this is what we should return if we were Matlab compatible
%! expanded_matlab = [
%!   115  154  185  178  150  122  105  116  138  159  158  117   78   86  112  129  133  120  103
%!    69   98  128  141  146  152  152  139  125  127  121   87   55   58   81  113  131  112   84
%!    40   54   74  100  131  167  184  157  119  104   92   64   41   44   66  100  121  103   74
%!    76   69   65   75   97  130  153  148  131  122  108   80   61   79  103  105   98   97   98
%!   120  105   88   77   78   96  121  143  155  154  140  112   98  124  143  109   74   91  123
%!   117  129  134  119  107  125  153  173  180  172  156  143  138  146  140   96   60   83  122
%!    99  139  170  157  139  156  181  188  180  164  151  154  156  140  112   81   65   84  110
%!   101  136  163  153  133  132  138  136  130  122  120  130  133  108   82   86   99  104  104
%!   103  126  143  136  116   97   81   73   73   82   94  105  105   87   78  108  138  133  116
%!    90  116  139  139  122   96   69   52   53   80  109  114  111  116  128  148  163  164  160
%!    66   99  131  140  131  109   83   62   62  102  142  144  138  154  169  164  157  169  184
%!    41   68   99  121  130  122  107   92   95  133  173  182  172  156  135  114  105  121  142
%!    21   38   64   98  124  131  127  123  129  160  194  212  199  144   82   52   48   65   85];
%!
%! assert (impyramid (uint8 (in), "reduce"), uint8 (reduced))
%! assert (impyramid (uint8 (in), "expand"), uint8 (expanded))

## Test that that reduction and expansion are done in the
## first 2 dimensions only.
%!test
%! in = randi ([0 255], [40 39 3 5], "uint8");
%! red = impyramid (in, "reduce");
%! for p = 1:3
%!   for n = 1:5
%!     assert (red(:,:,p,n), impyramid (in(:,:,p,n), "reduce"))
%!   endfor
%! endfor
%!
%! exp = impyramid (in, "expand");
%! for p = 1:3
%!   for n = 1:5
%!     assert (exp(:,:,p,n), impyramid (in(:,:,p,n), "expand"))
%!   endfor
%! endfor

%!test
%! in = repmat (uint8 (255), [10 10]);
%! assert (impyramid (in, "reduce"), repmat (uint8 (255), [5 5]))
%! assert (impyramid (in, "expand"), repmat (uint8 (255), [19 19]))

## This test is failing because it uses the expected Matlab results
%!test
%! in = logical ([
%!   1  0  1  1  0  0  1  1  0  0
%!   1  1  0  0  0  1  0  0  1  0
%!   0  1  1  0  1  1  1  1  1  1
%!   1  0  1  0  1  0  1  0  1  1
%!   1  1  1  0  0  0  1  1  1  1
%!   0  0  1  1  0  0  1  0  0  0
%!   0  0  1  1  0  1  1  0  1  1
%!   1  1  0  0  1  0  0  0  1  0
%!   1  1  1  1  1  1  0  1  0  0
%!   1  1  0  0  1  0  0  0  1  0]);
%!
%! reduced = logical ([
%!   1  1  0  1  0
%!   1  1  0  1  1
%!   1  1  0  1  1
%!   0  1  0  0  0
%!   1  1  1  0  0]);
%!
%! expanded = logical ([
%!   1  1  0  0  1  1  1  0  0  0  0  0  1  1  1  0  0  0  0
%!   1  1  1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
%!   1  1  1  1  0  0  0  0  0  0  1  1  0  0  0  1  1  0  0
%!   1  1  1  1  0  0  0  0  0  1  1  1  1  0  1  1  1  1  1
%!   0  1  1  1  1  0  0  0  1  1  1  1  1  1  1  1  1  1  1
%!   0  0  1  1  1  0  0  0  1  1  1  1  1  1  1  1  1  1  1
%!   1  1  0  1  1  0  0  0  1  0  0  1  1  1  0  1  1  1  1
%!   1  1  1  1  1  0  0  0  0  0  0  0  1  1  1  1  1  1  1
%!   1  1  1  1  1  1  0  0  0  0  0  0  1  1  1  1  1  1  1
%!   0  0  1  1  1  1  0  0  0  0  0  0  1  1  1  0  0  0  0
%!   0  0  0  1  1  1  1  0  0  0  0  1  1  1  0  0  0  0  0
%!   0  0  0  0  1  1  1  0  0  0  0  1  1  0  0  0  0  0  0
%!   0  0  0  0  1  1  1  0  0  0  1  1  1  0  0  0  1  1  1
%!   0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  1  1  1
%!   1  1  1  1  0  0  0  1  1  1  0  0  0  0  0  0  1  0  0
%!   1  1  1  1  1  0  1  1  1  1  0  0  0  0  0  0  0  0  0
%!   1  1  1  1  1  1  1  1  1  1  1  0  0  0  1  0  0  0  0
%!   1  1  1  1  1  0  1  1  1  1  0  0  0  0  0  0  0  0  0
%!   1  1  1  1  0  0  0  1  1  1  0  0  0  0  0  0  1  0  0]);
%!
%! assert (impyramid (in, "reduce"), reduced)
%! assert (impyramid (in, "expand"), expanded)