imv[-dir] bug
[This may be the same bug as #51, but that was specifically for PNG images, so...]
It appears that the image library that imv uses to display JPEG images cannot handle wide images (not sure about tall ones, yet). I will explore further, but those I have attempted that were something over 16K pixesl wide have the following behaviour:
If imv-dir is handed the image directly from a folder, it displays as completely white.
If imv-dir is handed the image before that image, and one uses the right arrow to go to it, then the previous image is displayed, but with the last row of pixels duplicated below it, until the height of the image it was supposed to display is reached, and the last column of pixels duplicated to the right, until the width of the image it was supposed to display is reached. Note that NONE of the image that was supposed to be displayed is displayed at all, although the info in the window title and overlay is that of the intended image.
If one goes beyond the image to the next one, and it also is too large, the same thing happens, but with the dimensions of the image corresponding to the second problem image, and STILL showing the image from two files before. If we now go beyond the problem images, and then go BACK to a problem image (left arrow), the problem is the same, but the image displayed is now the image AFTER the problem images.
Thus, it is clear that imv[-dir] does not clear a previously displayed image until a successful loading of a new one. If the loading is unsuccessful, then it displays the un-cleared previous image, but with the dimensions of the image that failed to load.
I will make a short video of the problem as viewed, and either attach it, or upload it to a private youtube page and include a link to it inline. https://youtu.be/NmaPES3Kz1s
scott@ASUS-Prime-B350MA:~$ hostnamectl
Static hostname: ASUS-Prime-B350MA
Icon name: computer-desktop
Chassis: desktop 🖥
Machine ID: afa17170ef654b46a53bdb748d110973
Boot ID: 4082ad23b79e40869a521f80152f3a09
Operating System: Debian GNU/Linux trixie/sid
Kernel: Linux 6.4.0-3-amd64
Architecture: x86-64
Hardware Vendor: ASUSTeK COMPUTER INC.
Hardware Model: PRIME B350M-A
Firmware Version: 4207
Firmware Date: Fri 2018-12-07
Firmware Age: 5y 1month 1d
sway 1.8.1-2
libwlroots11 0.16.2-3
imv 4.4.0-1
scott@ASUS-Prime-B350MA:~$ls -l /usr/bin/imv*
lrwxrwxrwx 1 root root 20 Nov 26 20:08 /usr/bin/imv -> /usr/bin/imv-wayland
-rwxr-xr-x 1 root root 132 Sep 5 03:31 /usr/bin/imv-dir
-rwxr-xr-x 1 root root 68928 Sep 5 03:31 /usr/bin/imv-msg
-rwxr-xr-x 1 root root 105984 Sep 5 03:31 /usr/bin/imv-wayland
-rwxr-xr-x 1 root root 97600 Sep 5 03:31 /usr/bin/imv-x11
scott@ASUS-Prime-B350MA:~$ imv -h
imv 4.4.0
See manual for usage information.
This version of imv has been compiled with the following backends:
Name: FreeImage
Description: Open source image library supporting a large number of formats
Website: http://freeimage.sourceforge.net/
License: FreeImage Public License v1.0
Name: libtiff
Description: The de-facto tiff library
Website: http://www.libtiff.org/
License: MIT
Name: libpng
Description: The official PNG reference implementation
Website: http://www.libpng.org/pub/png/libpng.html
License: The libpng license
Name: libRSVG
Description: SVG library developed by GNOME
Website: https://wiki.gnome.org/Projects/LibRsvg
License: GNU Lesser General Public License v2.1+
Name: libheif
Description: ISO/IEC 23008-12:2017 HEIF file format decoder and encoder.
Website: http://www.libheif.org
License: GNU Lesser General Public License
imv's full source code is published under the terms of the MIT
license, and can be found at https://sr.ht/~exec64/imv
imv uses the inih library to parse ini files.
See https://github.com/benhoyt/inih for details.
inih is used under the New (3-clause) BSD license.
scott@ASUS-Prime-B350MA:~$ apt list --installed "*jpeg*"
libjpeg62-turbo/testing,now 1:2.1.5-2 amd64 [installed,automatic]
libmjpegutils-2.1-0/now 1:2.1.0+debian-7 amd64 [installed,upgradable to: 1:2.1.0+debian-8]
scott@ASUS-Prime-B350MA:~$ apt list --installed "*libjxr*"
libjxr-tools/testing,now 1.2~git20170615.f752187-5 amd64 [installed,automatic]
libjxr0/testing,now 1.2~git20170615.f752187-5 amd64 [installed,automatic]
scott@ASUS-Prime-B350MA:~$ apt list --installed "*freeimage*"
libfreeimage3/testing,now 3.18.0+ds2-10 amd64 [installed,automatic]
Update: Further testing shows that it does not appear to matter which file format is used: if an image width (or presumably height) is larger than ~16,384 (2^14) all one sees is a white box. I have two panoramas, one 16379x2947 and one 16395x3903. The first displays, the second does not.
At first, I thought that FreeImage was at fault, as I work in JPEG, and the default imv package from Debian uses FreeImage for JPEG. However, I downloaded and generated imv, blacklisting FreeImage, and enabling libjpeg, and got exactly the same result. It being unlikely that both libraries would have exactly the same bug, it became clear that imv was where the bug was, at least for JPEG. I then took the two JPEG images (and several others, mostly larger, but one "normal" 4000x3000 image) and converted them to tiff, png, jxl and heic, and each image displayed fine if smaller than 16384, and displayed as a white rectangle if larger. As before, if an image that CAN be displayed is displayed first, and THEN an image that cannot, the prior image is displayed instead, filled out to the undisplayed image's width/height with what is probably the last column/row of pixels.
I was trying to find out how to get imv to log errors, or find out where it was doing so, if it already was, when I discovered that it WAS already doing so... I was invoking imv[-dir] from the terminal, and nothing ever was printed; except now, when a tif was displayed, I got (from the 4000x3000 image) "TIFFReadDirectory: Warning, Unknown field with tag 18246 (0x4746) encountered." So... apparently logging IS being done, and to stderr. What this means, is that when a white rectangle or distorted image is displayed, imv THINKS everything is OK, and that the image is being displayed correctly - since no error message of "cannot load image" or such is displayed.
I will try to investigate this further, but as I am no image-handling expert, I am not sure how much I can find (I already looked for "MAX", thinking that there might be a width-max and/or height-max, but found nothing suitable. I considered that maybe there was a buffer, whose width/height was stored in a variable too small to hold it when it exceeded 2^14 - but what type has a size greater than 8 bits, but smaller than 16? not likely... unless it was using the other 2 bits for something else? )
If anyone has anything to suggest, I (we all?) would be interested in hearing about it...
Well, after looking at a lot of code, I could not find an obvious error, so I reluctantly started looking at the OpenGL functions. It turns out that an attempt is made to nail the image to a "texture" (or the texture to the image...), and that (at least on my system) the maximum texture width/height is ... 16384. So... image smaller than 16384 --> great. Image greater than 16384-->fail. After much hair-tearing, and internet searching, the concept of tiling came up. I have fixed the problem by dividing the image up into as many smaller-than-maximum textures it takes to span the image. The only file needing change is canvas.c, and the only functions changed are imv_canvas_free() and draw_bitmap(). The struct canvas.cache is changed to add texture_count, and "textures" is GLuint * (instead of "texture" being a GLuint .
~quantenzitrone will be happy to know that his image displays correctly now.
Now, all I have to do is find out how to get the modified canvas.c into this website's source, somehow...
Now, all I have to do is find out how to get the modified canvas.c into this website's source, somehow...
If you mean how to submit a patch, follow this: https://git-send-email.io/
I just sent a patch. In the cc: that was sent me, it only says [Patch], despite the fact that I invoked the command as follows:
git send-email --compose --subject="[PATCH imv] Handle large images by using multiple OpenGL textures" --to="~exec64/imv-devel@lists.sr.ht" HEAD^
AND I don't see the body text that I added in the editor:
Without this patch, imv fails to display images with width/height larger than OpenGL's GL_MAX_TEXTURE_SIZE (usually these days: 16384), as it tries to make a texture equal to the bitmap->width x bitmap->height. This patch divides up the image into multiple adjoining textures, each of whose dimensions are smaller than GL_MAX_TEXTURE_SIZE. To avoid 'slivers', the width/height of the original image are divided into equal-sized pieces.
I don't know where I went wrong...
where do i find the patch if i want to test it out?
Can confirm this patch fixes the large images not being rendered / glitches on my system.
Thanks ~scott092707! Hopefully this will be merged.