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

[BUG] - Copied image can't be pasted in some applications #343

Closed
EsterLoken opened this issue Dec 17, 2020 · 11 comments
Closed

[BUG] - Copied image can't be pasted in some applications #343

EsterLoken opened this issue Dec 17, 2020 · 11 comments
Labels
bug fixed (hopefully)

Comments

@EsterLoken
Copy link

EsterLoken commented Dec 17, 2020

Version information

  • PhotoDemon version 8.4 and Nightly (9.0-a)
  • Windows 10

Describe the bug

Copied image from PhotoDemon can't be pasted into some applications Chrome.

How to reproduce the bug

For example when I copy an image in PhotoDemon and go to https://imgur.com/upload I can't paste it into the site, nothing happens.

If I do the same in Photoshop, copy an image, paste it into the site, it works.

Expected behavior

Pasting a copied image from PhotoDemon into https://imgur.com/upload should actually paste that image.

@wqweto
Copy link
Contributor

wqweto commented Dec 17, 2020

FYI, https://www.nirsoft.net/utils/inside_clipboard.html can be used after PS copy/cut to inspect clipboard formats made available.

@EsterLoken
Copy link
Author

FYI, https://www.nirsoft.net/utils/inside_clipboard.html can be used after PS copy/cut to inspect clipboard formats made available.

Why am I not surprised NirSoft has a tool for that lol

I tried Photoshop and https://nomacs.org/ and both work.
Difference seems to be that PhotoDemon doesn't populate CF_DIB, only CF_DIBV5.

PhotoDemon
photodemon_not_working

Nomacs
nomacs_works

Photoshop
photoshop_works

.

@tannerhelland
Copy link
Owner

Hello @EsterLoken! Thank you for reporting this bug. This is most likely a Chrome-specific error. Chrome has historically had terrible clipboard support - for example, I can paste images from PhotoDemon into GitHub on Firefox, but I can't on Chrome without using a Chrome-specific order of clipboard formats (which in turn breaks pasting into other software). If you could try pasting from PhotoDemon into imgur using a different web browser, and let me know the results, that would help me a great deal. (I don't have an imgur account or I'd try this myself.)

I've rewritten PhotoDemon's clipboard code a number of times to "play nicely" with Chrome, and if this is their issue yet again, it wouldn't surprise me in the least.

FYI - BITMAP, DIB, and DIBv5 are all interchangeable formats. If you post any one of them, Windows creates the other two "on-demand". Microsoft explicitly suggests placing DIBv5 data on the clipboard if possible (not surprising since it's the only format that guarantees compatibility for alpha-channels). Here's a direct quote from their developer docs:

If the system provides an automatic type conversion for a particular clipboard format, there is no advantage to placing the conversion format(s) on the clipboard.

When copying bitmaps, it is best to place the CF_DIB or CF_DIBV5 format on the clipboard. This is because the colors in a device-dependent bitmap (CF_BITMAP) are relative to the system palette, which may change before the bitmap is pasted. If the CF_DIB or CF_DIBV5 format is on the clipboard and a window requests the CF_BITMAP format, the system renders the device-independent bitmap (DIB) using the current palette at that time... If you place the CF_DIBV5 format with the bitmap color space information in the clipboard, the system will convert the bitmap bits from the bitmap color space to the sRGB color space when CF_DIB or CF_DIBV5 is requested.

Color-management concerns are why PhotoDemon supplies DIBv5 data, specifically. (And given that DIBv5 has been around since Windows 98, I don't know why a web-browser wouldn't support it natively... but given my experiences with Google engineering, this wouldn't be at all surprising 😉 )

Anyway, I mention this because NirSoft's reporting of "0" bytes for BITMAP and DIB formats is misleading; those formats are available from PhotoDemon, and other software can paste from PhotoDemon in any of those formats. This is easily tested using e.g. Microsoft Paint, which doesn't support DIBv5 for legacy reasons but it will happily paste from PhotoDemon because a BITMAP copy of the data is automatically converted by Windows.

Another option is to try PhotoDemon's Edit > Special > Cut/Copy Special menu, if you can. That menu allows you to explicitly copy only a given format to the clipboard. If that works (but PhotoDemon's regular Copy command doesn't), that's a useful clue. I've done this before when Chrome's clipboard support breaks for the umpteenth time.

Sorry that I don't have an easy explanation up-front. Clipboard support is very complicated (as PhotoDemon's source code will attest), because changing it to make one program work will break compatibility with a bunch of other software. If Google forces me to do this yet again... 😠 curse them lol

@EsterLoken
Copy link
Author

Thank you for the extensive reply, looks like you were right on the money, as a simple CTRL+C does work in Firefox but not in Chrome. Sorry for not testing it with different browsers in the first place.

other software can paste from PhotoDemon in any of those formats.

Yeah, I can paste the CTRL+C content from PhotoDemon into anything ... paint, photoshop, nomacs, instant messengers like telegram, firefox ... only chrome is like

EnormousSpottedCornsnake-small

I don't have an imgur account or I'd try this myself.

You don't need an account for https://imgur.com/upload that site allows anonymous uploading.
Alternatively, as you noted, you can test it right here in Github. I can paste images from nomacs/photoshop/Photo Demon's Copy Special DIB/Bitmap right here in the comment field in Chrome, but not from the regular CTRL+C from PhotoDemon.

Another option is to try PhotoDemon's Edit > Special > Cut/Copy Special menu, if you can.

Bitmap and DIB work in Chrome, but everything else including DIB v5 doesn't.
Looking at NirSoft's InsideClipboard again, I can't help but think that it does have something to do with CF_DIB being null or not existing. The only ones that do work have content in CF_DIB, maybe Chrome somehow skips the conversion by the system, sees there is nothing in CF_DIB and calls it a day?

Btw, is there a way to change/define keyboard shortcuts? I'd be fine with it if I could just override CTRL+C to one of the working Copy Special's.

image

@wqweto
Copy link
Contributor

wqweto commented Dec 18, 2020

@EsterLoken Null in Handle column means "delay rendered format".

Try normal Ctrl+C copy in PD, paste in MS Paint as intermediary, then paste in Chrome. The idea of the intermediary is to actually render the CF_DIB so it's not marked as delay rendered anymore.

You can observe if Handle column changes after paste in MS Paint -- I might be wrong in that OS does not cache the delay rendered format on first actual render.

@EsterLoken
Copy link
Author

@wqweto Just tried it, copying from PhotoDemon to Paint (or nomacs, Photoshop) doesn't change anything, CF_DIB remains null and the clipboard content remains unpasteable (is that even a word?) in Chrome.

@wqweto
Copy link
Contributor

wqweto commented Dec 18, 2020

Just traced the delay rendering in PD and IMO there is a bug/quirk in Windows for delay rendering CF_DIB meaning it's not working as expected.

On GetClipboardData for delay rendered CF_DIB the source application receives WM_RENDERFORMAT for CF_DIBV5 (and not CF_DIB) which is weird. Rendering both CF_DIB and CF_DIBV5 on this request does not fix PD's clipboard issues though -- target application has to request CF_DIB second time to succeed. Rendering only CF_DIB on this request does fix it though but makes CF_DIBV5 unavailable (because WM_RENDERFORMAT is rendering CF_DIB instead).

Don't know how this can be fixed for Win10 and keep on delay rendering both CF_DIB and CF_DIBV5.

Edit: Couple of links

tannerhelland added a commit that referenced this issue Dec 19, 2020
See #343 for details.  Thank you to @EsterLoken for catching and reporting, and @wqweto for additional follow-up.

tl;dr: this fixes Copy+Paste into Google Chrome.  By manually marking CF_DIB as available at Cut/Copy-time, PD can reliably receive notifications for copy+paste when old-style CF_DIB format is requested.  This is an ancient Windows bug going back to at least Windows 7 (possibly earlier? idk), but the bug was useful because you could "force" apps to choose between bitmaps/DDBs (which every app supports all the way back to Win 3.1) or DIBv5 (which any Win 98+ app should support, as it fixes DIB issues by e.g. making alpha-handling and color-management explicit).  I have never before encountered an app that didn't support either DDBs or DIBv5, but at some point, Chrome developers apparently decided this was the way to go.  I'm shocked that Google developers are this incompetent (/s obviously, Google's app behavior on Windows is perpetually incompetent)

Longer explanation: from a code standpoint this change is trivial, but it has many potential implications for interop with other software, including breaking 32-bpp copy+paste ops in old software.  Given Chrome's ubiquity, I think changing this is probably the least of several evils, but I'm extremely annoyed that Chrome is incapable of using modern clipboard formats, and that its clipboard interop breaks with regularity.  (I've lost track of how many times I've tweaked PD's clipboard code to make Chrome happy.  At least this time it involves broken pasting into Chrome instead of broken copying out of Chrome... so points for at least breaking in a novel way?  uuuuuugh)

Even longer explanation: Windows DIB format, like nearly everything in GDI, is inconsistent in its handling of alpha bytes.  As an easy example, PrintScreen keypresses often place a 32-bpp DIB on the clipboard with random alpha bytes.  Because you don't ever know if a clipboard DIB has useful or broken alpha, you must assume broken alpha and treat the data as 24-bpp only.  (Heuristics can be used to try and "guess" alpha state, but like any heuristics, edge-cases are complicated and impossible to handle perfectly.)

Old-school DDBs (CF_BITMAP) don't have this issue because alpha is explicitly *not* supported, and "modern" DIBv5 fixes the issue with not just explicit alpha support, but extra support for nice things like color-management.  There is no reason to forcibly use CF_DIB except for software which predates Windows 98.  (Or if you're a Google dev, apparently.)

By reenabling old-style DIB support to make Chrome work, I must manually composite 32-bpp images against a backcolor when using DIB format.  This is required to making pasting into e.g. MS Paint still viable.  (MS Paint preferentially grabs DIB data over DDB data, so when placing 32-bpp DIB data on the clipboard you *must* composite first or you'll get a broken image when pasting into MS Paint.  Paint will ignore a DDB copy completely if a DIB is present, alas.)

This change also breaks some software that would preferentially choose DIBv5 over DIB when available (e.g. Chasys Draw, which can no longer paste 32-bpp data from PD.  This is technically a problem on their end but users will only know "it worked before and now it doesn't", alas).

I'm especially frustrated with Chrome because this change doesn't even allow you to paste 32-bpp data into Chrome - that still isn't possible, because they won't take DIBv5 or PNG-format data if available, no matter what you do.  All it does is break interop with a bunch of legacy software, just so you can paste into Chrome *at all*.

Anyway, I don't maintain an exhaustive list of clipboard format support in other apps, but I'm hoping that PNG as an interop format is more ubiquitious in 2020, which may negate some of the worst issues of this change. (For example, the last time I changed PD's clipboard mechanism, this fix didn't work because pasting into Paint.NET was downgraded to 24-bpp data only.  Two years later, however, I can revert this because Paint.NET added PNG clipboard support in 2019, and it will preferentially use PNG data over the DIB data PD is now forced to place on the clipboard.)

Anyway, I've been interrupted by my toddler roughly 1000x while trying to explain this issue, so I've probably repeated myself many times over.  Sorry!  I'm just frustrated with Google for what feels like the billionth time, and being forced to enable a Win-95-era clipboard format just to appease Chrome makes me very unhappy.
@tannerhelland
Copy link
Owner

Thank you for the follow-up, @EsterLoken and @wqweto. I've just uploaded a nightly build that fixes Copy+Paste with Chrome.

The commit notes go into more technical detail, but basically Windows specifies three different clipboard formats for images: CF_Bitmap, CF_DIB, and CF_DIBv5. These roughly correlate to Windows 3.1, 95, and 98 support. Pretty much every Windows app ever written supports CF_Bitmap, and every modern app typically supports CF_DIBv5 because it's the only format that allows copy+pasting images with transparency, color-management and more.

When none of those formats are good enough (modern HDR images, for example), most modern apps also support PNG as a Copy+Paste format. PNG clipboard support isn't officially defined by Microsoft, but because the clipboard allows you to put custom formats on it, everyone just uses "PNG" as their identifier and it works great! PhotoDemon uses this to trade HDR images with e.g. GIMP, for example.

Google Chrome is the weird outlier here because it doesn't support CF_DIBv5, and it also won't take the legacy CF_Bitmap format if available. It insists on CF_DIB at any cost. Making Chrome work (well, this version of Chrome because who knows what will change next week) is as simple as explicitly making CF_DIB available, and that's what I've done in the latest nightly build.

Unfortunately, this has negative implications for PhotoDemon because PD has a big emphasis on legacy app/OS support. Many PD users interact with very old software (like pre-CS versions of Photoshop). These programs prefer CF_DIB over DIBv5 simply due to their age, so enabling CF_DIB means that those apps will always grab old CF_DIB data from the clipboard instead of the preferred DIBv5. This is technically a bug in those apps, but they will never be updated because they're 20+ years old at this point, so I can't really help but try to work around their quirks.

I'm okay making this change because it's usually preferable to make modern software interop work instead of ancient software (when I have to choose), and PhotoDemon does provides that "Special" Cut/Copy menu as an absolute last resort. But this change is purely to work around incompetence on Google's part, which is always frustrating. (I'm of course still grateful for the bug report, @EsterLoken - thank you again for your help!)

Anyway, /rant over. @EsterLoken I'm happy to add you to the contributor list for the next release as a "thank you" for your excellent follow-up help on this. Just let me know what name and/or URL to use!

(And thank you as always to @wqweto for additional technical support!)

@tannerhelland tannerhelland added fixed (hopefully) and removed unconfirmed labels Dec 23, 2020
@EsterLoken
Copy link
Author

EsterLoken commented Jan 2, 2021

First of all, happy new year Tanner and @wqweto Vladimir!

May 21 be a more happy endeavor than 20. : )

Just add me as Ester Loken if you must, I'm just happy to contribute either way.

I just tried the nightly and it works like a charm.

This will make shitposting memes contributing in-depth infographics on various forums so much easier. ; )


Btw, I really appreciate your in depth commit messages/borderline rants lol. I learned more about the clipboard during this interaction than I ever thought I would.

@tannerhelland
Copy link
Owner

This will make shitposting memes contributing in-depth infographics on various forums so much easier. ; )

🤣

Supporting the shitposting infographics community is what motivates me to keep this project alive!

Thank you for the follow-up, and best wishes for a happier 2021 to you as well, @EsterLoken. I'll get your name added to the contributor list in the next round of commits!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug fixed (hopefully)
Projects
None yet
Development

No branches or pull requests

4 participants