Bug 405693 - PNG Brush tips are suddenly being recognized as GBR format instead of masks
Summary: PNG Brush tips are suddenly being recognized as GBR format instead of masks
Alias: None
Product: krita
Classification: Applications
Component: Brush engines (show other bugs)
Version: nightly build (please specify the git hash!)
Platform: Manjaro Linux
: NOR normal
Target Milestone: ---
Assignee: Krita Bugs
Depends on:
Reported: 2019-03-20 15:45 UTC by M
Modified: 2019-05-04 12:09 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed In:

PNG brush tip, that is misidentified (356.45 KB, image/png)
2019-03-20 15:45 UTC, M
Converted from SVG to PNG (64.32 KB, image/png)
2019-03-20 19:10 UTC, M
Extracted from PSD layer (364.72 KB, image/png)
2019-03-20 19:11 UTC, M

Note You need to log in before you can comment on or make changes to this bug.
Description M 2019-03-20 15:45:48 UTC
Created attachment 118940 [details]
PNG brush tip, that is misidentified

A few of the PNG brush tips in my collection suddenly don't work correctly anymore, both in Version 4.1.8 and 4.2.0 Next nightly, as of a couple of days ago. Instead of counting as masks where the brightness is the transparency, they are now identified as GBR format, so when drawing I get the grayscale image with rectangular borders instead of transparency. Some of affected ones I made directly in Krita not long ago. I verified they were working and I use them frequently. I tried assigning sRGB and Gray color profiles in Krita and swapping channels in ImageMagick, but the only thing that worked was converting into Gimp brush format (.gbr).

I attached one of the affected PNG images as an example.
Comment 1 Ahab Greybeard 2019-03-20 17:36:19 UTC
I confirm that this happens with the attached example brush tip .png image in the latest (19 Mar) 4.2.0 pre-alpha appimage.

It does not happen in the 21 Feb build 4.2.0 appimage.

I've opened the attached example brush .png file and re-exported it to .png and the re-exported version also showed this problem.
If I export to .jpg then open the .jpg and export it to .png, that new .png image has no problem used as a brush tip.
(Could it be due to the combination of options that were used when first exporting the original images to .png?)
Comment 2 M 2019-03-20 19:10:58 UTC
Created attachment 118948 [details]
Converted from SVG to PNG
Comment 3 M 2019-03-20 19:11:41 UTC
Created attachment 118949 [details]
Extracted from PSD layer
Comment 4 M 2019-03-20 19:17:56 UTC
I added 2 more affected examples, that previously worked. The triangles one was converted from an SVG in Inkscape, the scale was extracted from a multi layer PSD with ImageMagick. Maybe it helps spot some pattern.
Comment 5 Halla Rempt 2019-04-30 09:12:53 UTC
snu anisotropix and and scale6-8 are both 16 bit/channel RGB images, media-militia-vector-triangles-1 is 8 bit RGB. 

Qts checks whether an image is greyscale probably changed, instead of checking the pixels, it checks the color model of the images. The documentation stills says "Returns true if all the colors in the image are shades of gray (i.e. their red, green and blue components are equal); otherwise false.": https://doc.qt.io/qt-5/qimage.html#allGray so this would seem to be a bug in Qt.

If you convert the image to 8 bit grayscale and save the PNG image with "force sRGB" unchecked, then the brushes load as brushes.
Comment 6 Halla Rempt 2019-04-30 09:19:00 UTC
Git commit f35496cf3a45a6b50ae2d9332c6f4ebc6e39ebe2 by Boudewijn Rempt.
Committed on 30/04/2019 at 09:16.
Pushed by rempt into branch 'master'.

Use allGray instead of isGrayScale to determine whether the brush tip is grayscale

This works around a bug in QImage::isGrayScale where images with
16 bits/channel are not checked with allGray, so by default are not
grayscale. These images have depth 64, which is not in the switch

bool QImage::isGrayscale() const
    if (!d)
        return false;

    if (d->format == QImage::Format_Alpha8)
        return false;

    if (d->format == QImage::Format_Grayscale8)
        return true;

    switch (depth()) {
    case 32:
    case 24:
    case 16:
        return allGray();
    case 8: {
        Q_ASSERT(d->format == QImage::Format_Indexed8);
        for (int i = 0; i < colorCount(); i++)
            if (d->colortable.at(i) != qRgb(i,i,i))
                return false;
        return true;
    return false;

M  +1    -1    libs/brush/kis_png_brush.cpp

Comment 7 Halla Rempt 2019-05-04 12:09:05 UTC
Git commit eef2caf3807a8eb3a4e0ad928e7d966e1a397cf4 by Boudewijn Rempt.
Committed on 04/05/2019 at 12:08.
Pushed by rempt into branch 'master'.

Convert the brushtip image to grayscale if it's a mask

M  +2    -1    libs/brush/kis_png_brush.cpp