Mercurial > octave
changeset 25980:221c039aa415
Fix rendering of images with permuted x/ydata (bug #49756).
* gl-render.cc (opengl_renderer::draw_image): Sort xdata and ydata before
computing pixel dimensions and flip dimensions if necessary.
* genpropdoc.m: Use "[x/yfirst x/ylast]" instead of "[x/ymin x/ymax]" in
documentation for clarity.
* imshow.m: Ditto.
author | Pantxo Diribarne <pantxo.diribarne@gmail.com> |
---|---|
date | Sun, 28 Oct 2018 21:56:40 +0100 |
parents | 69a160d7ab68 |
children | 63b3d5e4e5c3 |
files | doc/interpreter/genpropdoc.m libinterp/corefcn/gl-render.cc scripts/image/imagesc.m scripts/image/imshow.m |
diffstat | 4 files changed, 80 insertions(+), 27 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/interpreter/genpropdoc.m Mon Oct 29 21:56:08 2018 -0700 +++ b/doc/interpreter/genpropdoc.m Sun Oct 28 21:56:40 2018 +0100 @@ -1150,7 +1150,7 @@ s.valid = valid_cellstring; case "xdata" - s.doc = "Two-element vector @code{[xmin xmax]} specifying the x \ + s.doc = "Two-element vector @code{[xfirst xlast]} specifying the x \ coordinates of the centers of the first and last columns of the image.\n\ \n\ Setting @code{xdata} to the empty matrix ([]) will restore the default value \ @@ -1158,7 +1158,7 @@ s.valid = valid_2elvec; case "ydata" - s.doc = "Two-element vector @code{[ymin ymax]} specifying the y \ + s.doc = "Two-element vector @code{[yfirst ylast]} specifying the y \ coordinates of the centers of the first and last rows of the image.\n\ \n\ Setting @code{ydata} to the empty matrix ([]) will restore the default value \
--- a/libinterp/corefcn/gl-render.cc Mon Oct 29 21:56:08 2018 -0700 +++ b/libinterp/corefcn/gl-render.cc Sun Oct 28 21:56:40 2018 +0100 @@ -3776,10 +3776,23 @@ if (x.isempty () || y.isempty ()) return; - if (w > 1 && x(1) == x(0)) + // Sort x/ydata and mark flipped dimensions + bool xflip = false; + if (x(0) > x(1)) + { + std::swap (x(0), x(1)); + xflip = true; + } + else if (w > 1 && x(1) == x(0)) x(1) = x(1) + (w-1); - - if (h > 1 && y(1) == y(0)) + + bool yflip = false; + if (y(0) > y(1)) + { + std::swap (y(0), y(1)); + yflip = true; + } + else if (h > 1 && y(1) == y(0)) y(1) = y(1) + (h-1); const ColumnVector p0 = xform.transform (x(0), y(0), 0); @@ -3824,7 +3837,7 @@ // OpenGL won't draw any of the image if its origin is outside the // viewport/clipping plane so we must do the clipping ourselves. - int j0, j1, i0, i1; + int j0, j1, jj, i0, i1, ii; j0 = 0, j1 = w; i0 = 0, i1 = h; @@ -3872,9 +3885,19 @@ { for (int j = j0, idx = (i-i0)*(j1-j0)*3; j < j1; j++, idx += 3) { - a[idx] = xcdata(i,j,0); - a[idx+1] = xcdata(i,j,1); - a[idx+2] = xcdata(i,j,2); + if (! yflip) + ii = i; + else + ii = h - i - 1; + + if (! xflip) + jj = j; + else + jj = w - j - 1; + + a[idx] = xcdata(ii,jj,0); + a[idx+1] = xcdata(ii,jj,1); + a[idx+2] = xcdata(ii,jj,2); } } @@ -3891,9 +3914,19 @@ { for (int j = j0, idx = (i-i0)*(j1-j0)*3; j < j1; j++, idx += 3) { - a[idx] = xcdata(i,j,0); - a[idx+1] = xcdata(i,j,1); - a[idx+2] = xcdata(i,j,2); + if (! yflip) + ii = i; + else + ii = h - i - 1; + + if (! xflip) + jj = j; + else + jj = w - j - 1; + + a[idx] = xcdata(ii,jj,0); + a[idx+1] = xcdata(ii,jj,1); + a[idx+2] = xcdata(ii,jj,2); } } @@ -3910,9 +3943,19 @@ { for (int j = j0, idx = (i-i0)*(j1-j0)*3; j < j1; j++, idx += 3) { - a[idx] = xcdata(i,j,0); - a[idx+1] = xcdata(i,j,1); - a[idx+2] = xcdata(i,j,2); + if (! yflip) + ii = i; + else + ii = h - i - 1; + + if (! xflip) + jj = j; + else + jj = w - j - 1; + + a[idx] = xcdata(ii,jj,0); + a[idx+1] = xcdata(ii,jj,1); + a[idx+2] = xcdata(ii,jj,2); } } @@ -3929,9 +3972,19 @@ { for (int j = j0, idx = (i-i0)*(j1-j0)*3; j < j1; j++, idx += 3) { - a[idx] = xcdata(i,j,0); - a[idx+1] = xcdata(i,j,1); - a[idx+2] = xcdata(i,j,2); + if (! yflip) + ii = i; + else + ii = h - i - 1; + + if (! xflip) + jj = j; + else + jj = w - j - 1; + + a[idx] = xcdata(ii,jj,0); + a[idx+1] = xcdata(ii,jj,1); + a[idx+2] = xcdata(ii,jj,2); } }
--- a/scripts/image/imagesc.m Mon Oct 29 21:56:08 2018 -0700 +++ b/scripts/image/imagesc.m Sun Oct 28 21:56:40 2018 +0100 @@ -35,8 +35,8 @@ ## If a range is specified as @w{@code{[max, min]}} then the image will be ## reversed along that axis. For convenience, @var{x} and @var{y} may be ## specified as N-element vectors matching the length of the data in @var{img}. -## However, only the first and last elements will be used to determine the axis -## limits. +## However, only the first and last elements will be used to determine +## the image limits. ## ## The optional return value @var{h} is a graphics handle to the image. ##
--- a/scripts/image/imshow.m Mon Oct 29 21:56:08 2018 -0700 +++ b/scripts/image/imshow.m Sun Oct 28 21:56:40 2018 +0100 @@ -49,16 +49,16 @@ ## ## @item @qcode{"xdata"} ## If @var{value1} is a 2-element vector, it must contain horizontal image -## limits in the form [xmin, xmax], where xmin and xmax are the abscissa of -## the centers of the corner pixels. Otherwise @var{value1} must be a vector -## and only the first and last elements will be used for xmin and xmax -## respectively. +## limits in the form [xfirst, xlast], where xfirst and xlast are the +## abscissa of the centers of the corner pixels. Otherwise @var{value1} +## must be a vector and only the first and last elements will be used +## for xfirst and xlast respectively. ## ## @item @qcode{"ydata"} ## If @var{value1} is a 2-element vector, it must contain vertical image -## limits in the form [ymin, ymax], where ymin and ymax are the ordinates of -## the center of the corner pixels. Otherwise @var{value1} must be a vector -## and only the first and last elements will be used for ymin and ymax +## limits in the form [yfirst, ylast], where yfirst and ylast are the ordinates +## of the center of the corner pixels. Otherwise @var{value1} must be a vector +## and only the first and last elements will be used for yfirst and ylast ## respectively. ## ## @end table