Tk Source Code

View Ticket
Login
Ticket UUID: 32f2e19de82946d0277b72dcb840b4753d6e643e
Title: Windows: photo -gamma and -palette are ignored since RGBA rendering
Type: Bug Version: 9.1b1
Submitter: serhiy.storchaka Created on: 2026-09-24 13:53:02
Subsystem: 41. Photo Images Assigned To: aku
Priority: 5 Medium Severity: Minor
Status: Closed Last Modified: 2026-10-20 03:10:58
Resolution: Fixed Closed By: chrstphrchvz
    Closed on: 2026-10-20 03:10:58
Description:

Since [3bbe54bc74] (merge of [7caf9e9e]) win/tkWinPort.h defines TK_CAN_RENDER_RGBA. With it, TkImgPhotoDisplay draws the model's RGBA pixels directly with TkpPutRGBAImage, and the photo instance, where -gamma correction and -palette reduction are applied, is not used for drawing. So on Windows these options no longer have any visible effect.

-gamma:

foreach {img opts} {plain {} gamma {-gamma 2}} {
    image create photo $img -width 60 -height 60 {*}$opts
    $img put #ffa500 -to 0 0 60 60
    pack [label .$img -image $img] -side left
}

In 8.6 and 9.0 the right image is lighter than the left one, (255,205,0) instead of (255,165,0); in 9.1b1 both are the same orange.

-palette:

foreach {img opts} {plain {} gray2 {-palette 2} rgb3 {-palette 3/3/3}} {
    image create photo $img -width 120 -height 120 {*}$opts
    for {set x 0} {$x < 120} {incr x} {
        $img put [format #%02x%02x00 [expr {$x * 255 / 119}] [expr {$x * 165 / 119}]] \
                -to $x 0 [expr {$x + 1}] 120
    }
    pack [label .$img -image $img] -side left
}

In 8.6 and 9.0 the second and third images are dithered with 2 shades of gray and 3 levels per color; in 9.1b1 all three show the same smooth gradient. (The black and white dither of -palette 2 is inverted on Windows, which is [481255ffff].)

On X11 both options work as expected in 8.6, 9.0 and 9.1. macOS has always ignored them ([de6ef8276c]).

User Comments: chrstphrchvz added on 2026-10-20 03:10:58:

Glad to hear that fix worked. Could it please be backported to 9.0, even though 9.0 does not have the tests added for this ticket? Thanks


marc_culler (claiming to be Marc Culler) added on 2026-10-20 01:35:23:
That worked for me.  I pushed the fix to main and will close this ticket
again.

chrstphrchvz added on 2026-10-19 04:18:40:

Marc, I have reproduced that test failure, and for me it is fixed by the following change:

--- macosx/tkMacOSXWindowEvent.c
+++ macosx/tkMacOSXWindowEvent.c
@@ -1376,6 +1376,7 @@
     );
     // CGDisplayCopyColorSpace retains the colorspace.
     CGColorSpaceRelease(colorspace);
+    CGContextSetInterpolationQuality(newCtx, kCGInterpolationNone);
     CGContextScaleCTM(newCtx, self.layer.contentsScale,
 		      self.layer.contentsScale);
 #if 0

I think your explanation is mostly correct that the cause is unwanted interpolation. However, Tk is currently only requesting no interpolation for the CGBitmapContext being created in CreateCGImageFromDrawableRect(), and not the one created in resetTkLayerBitmapContext. My understanding is that CGContextSetInterpolationQuality() only applies to subsequent drawing done into a specified context, and not for when a CGImage created from that context is then drawn into a different context. So if Tk wants no interpolation e.g. when XCopyArea() is used to draw a pixmap into a widget on a Retina display, then it should have a similar call to CGContextSetInterpolationQuality() in resetTkLayerBitmapContext. This change probably helps performance, but I have not checked.


marc_culler (claiming to be Marc Culler) added on 2026-10-19 03:11:32:
The checkerboard pattern is visible with "Digital Color Meter".app.
See the image attachment.

marc_culler added on 2026-10-19 02:57:40:
I am reopening the ticket because I am seeing a test failure when running
the new imgPhInstance tests on macOS with a Retina display:

==== imgPhInstance-7.2 -palette is applied FAILED
==== Contents of test case:

    .c create image 10 10 -anchor nw -image photo.palette
    update
    set colors {}
    for {set y 14} {$y < 18} {incr y} {
        for {set x 14} {$x < 18} {incr x} {
            lappend colors [testpixel .c $x $y]
        }
    }
    join [lsort -unique $colors]

---- Result was:
#383838 #c7c7c7
---- Result should have been (exact matching):
#000000 #ffffff
==== imgPhInstance-7.2 FAILED


Here is my explanation.  The palette consists of black and white only.
The test draws a square containing #808080.  Tk dithers that square,
producing a square where the pixels alternate between black and white
in a checkerboard pattern.  When that image gets drawn on a Retina display,
it must be resampled at twice the size. We are only allowed to provide
hints about how to interpolate when resampling - Apple makes the final
decision.  The Tk code says it prefers no interpolation.  But that hint
is rejected by Apple, and they decide to do bilinear interpolation.
Bilinear interpolation when resampling that checkerboard produces
an image where the 2x2 Retina logical pixels contain 4 display pixels
with colors #383838 and #c7c7c7 in a checkerboard pattern.  So when
the test samples the pixels on the screen it sees only those two colors
and does not see any black or white pixels.

The test passes on a non-retina screen.

chrstphrchvz added on 2026-10-17 10:14:11:

Also, for similar reasons as this ticket, -gamma and -palette are now ignored in some cases on X11: see [ff3965a5].


chrstphrchvz added on 2026-10-14 02:33:04:

It is not true that -gamma and -palette have always been ignored on macOS. In [de6ef8276c], both the reporter's description and my comments indicate that -gamma (and also -palette, it turns out) used to work before 8.6.9.


oehhar added on 2026-09-29 19:32:13:

Thanks ! Fix is effective.

Merged to main by [05a0704a].

Mason, could you comment on this fix?

Bug closed.

Thanks for all, Harald


serhiy.storchaka added on 2026-09-24 19:20:11:

Correction: this can be tested. tktest has testpixel, which reads back rendered pixels. Tests imgPhInstance-7.1 and 7.2 were added in win-photo-gamma-palette; they fail on Windows without the fix.


serhiy.storchaka added on 2026-09-24 13:55:27:

Fixed in branch win-photo-gamma-palette ([c892f77266]). When the instance has a non-default -gamma or -palette, Windows again draws the instance pixmap, as in 9.0. With the examples above it now looks the same as in 8.6 and 9.0.

Images with partially transparent pixels are still drawn from the model's RGBA data, so these options still have no effect on them, as on macOS.

There is no automatic test: Tk cannot read pixels back from the screen, so the examples above have to be checked visually.


Attachments: