Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sanely deal with bitmaps larger than the screen #1539

Open
dankamongmen opened this issue Apr 16, 2021 · 6 comments
Open

sanely deal with bitmaps larger than the screen #1539

dankamongmen opened this issue Apr 16, 2021 · 6 comments
Assignees
Labels
enhancement New feature or request question/research Further information is requested

Comments

@dankamongmen
Copy link
Owner

With cell blitting, we can blit images far larger than the screen just fine. This is useful for e.g. parallax backgrounds as used in debwarrior. Whatever part of the plane is visible gets rendered, and the rest doesn't. This doesn't work for bitmap graphics, which we want to paint as an all-or-nothing deal. If we emit too large of one, especially when using Send Attributes to specify the image size, it simply isn't displayed. I'd like us to be able to display partial bitmap graphics, ideally still as a single graphic emission (i.e. not as a bunch of tiles). I'm not sure the best way to go about doing this -- consider it a wishlist item for now.

@dankamongmen dankamongmen added enhancement New feature or request question/research Further information is requested labels Apr 16, 2021
@dankamongmen dankamongmen self-assigned this Apr 16, 2021
@dankamongmen
Copy link
Owner Author

as part of this, ncplayer -bpixel -snone with an image larger than the visible area ought work (with or without -k). currently this is broken in sixel with or without -k, and in kitty without -k.

@dankamongmen
Copy link
Owner Author

see also the comments in #1547

@dankamongmen
Copy link
Owner Author

so the fundamental (implementation-driven) question here seems to be: if we draw a partial bitmap, is the content not drawn forever lost to us? i'd like to say "no" (it's certainly not that way when blitting cells, see comments re Debwarrior above), but that effectively means we need carry around the entire bitmap all the time, to regenerate those parts which were lost.

here again is a place where mosaics would solve the problem neatly, or at least assist us.

note that with at least sixel, we can't just lop off a portion. let's say rows are 8 pixels tall. if we wanted to cut off the top row's worth of data (this is particularly relevant to #1883), we can't just purge one or two bands of sixel -- we need drop one, then reconstruct all that follow, using the data from 8 pixels into the original bitmap. we can (with difficulty) do that using just the sixel payload available to us, but it's much easier if we start from the original RGBA data.

so let's say we bit the bullet and kept the original data. we could just keep the parts that we're not using, which would at maximum be four distinct parts (one on each side). we're already doing this, in effect, for kitty -- wipe all cells, and we keep the entire RGBA image in auxiliary vectors. so we can. can we just use auxvecs as we already do and wipe these areas out? well, we definitely can't for areas logically above the top of the screen -- there's no way to get the cursor there. we'd have to cut those down, and that's one of the most important cases.

right now we prevent such an oversized graphic from going out ourselves. what happens if we actually emit such a graphic? if we use ncplayer -k -snone -bpixel ../data/samoa.avi in Kitty, it looks like...either we or kitty scales it heightwise, and the material to the right is simply not shown (without -k, we don't display anything, and exit with an error). this surely crosses into the land of undefined behavior, though, and probably can't be relied on.

@dankamongmen
Copy link
Owner Author

so this kinda suggests only keeping the (entirety of) the RGBA around usually, and encoding on-the-fly that portion which we want to display at any given time. we would encode it directly into the outgoing memstream (eliminating the need for #1870)....except no, that's no good if we need emit the graphic more than once (for instance, imagine we draw a glyph atop a Sixel, and then clear the glyph. we need redraw the original Sixel, and under this setup would need reencode it).

if we assume that sprixel planes are resized such that only the visible portion exists at any given time (meaning they'd be destroyed if moved entirely out of the visual area, i suppose--i don't love that idea, ick), we could just keep the non-shown portions as RGBA (perhaps in an auxvec-like structure) -- remembering that this is complicated for sixel -- and reencode when the plane is resized (what do we currently do when a sprixel plane is resized? do we refuse to do so? no, it appears we destroy the associated sprixel, hrmmm). i think that's the correct thing to do. it's gonna be a gigantic pain in the ass, though, and runs the risk of consuming quite a bit of memory.

@dankamongmen
Copy link
Owner Author

for fbcon, where we absolutely can't blit beyond the screen lest we crash everywhere, i've put in hard limits. it seems happy to prep a render well beyond them, though.

@dankamongmen
Copy link
Owner Author

so having pondered this, especially in light of the new CLI mode, here's what i'm thinking:

  • when not scrolling, we simply prohibit placing new output on e.g. past the end of a row. we should do the same here. if we're not scrolling, and the output exceeds the size, refuse to plot it.
  • when we are scrolling, emission ought lead to scrolling such that the image is visible

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request question/research Further information is requested
Projects
None yet
Development

No branches or pull requests

1 participant