gnustep-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: NSBitmapImageRep scaling/copying issue


From: Josh Freeman
Subject: Re: NSBitmapImageRep scaling/copying issue
Date: Wed, 13 Apr 2016 04:47:00 -0400

Hi Riccardo,

Ran PRICE 1.3.0 on OS X and saw some discoloration in an image's partially-transparent region after flipping it horizontally.

The issue seems to be due to mismatched bitmap-formats: Bitmaps loaded from external data can be either premultiplied- or nonpremultiplied- alpha (in -[MyDocument loadDataRepresentation:ofType:], there's some Mac-only code that checks whether the loaded bitmap is nonpremultiplied, but the result is unused), and bitmaps generated by PRICE for pixel-data operations are always in the default premultiplied-alpha format (PRICE only uses the version of the -[NSBitmap initWithBitmapDataPlanes:...] initializer that doesn't include the bitmapFormat parameter). Copying pixel data directly from a nonpremultiplied to a premultiplied bitmap without reformatting the data can cause discoloration in partially- transparent areas.

The horizontal-flip issue disappeared after switching the NSBitmapImageRep initializer call in -[PRTransforms flipImageHoriz:] to the version with the bitmapFormat: parameter (passing [srcImageRep bitmapFormat] as the value so the formats matched). Not counting flipImageHoriz:'s call, there are 20 more bitmap-initializer calls throughout the rest of the app - they'd need to be switched as well to fix format-mismatches in other operations.

Another thing that can cause discoloration on OS X are mismatched bitmap color profiles (color management is currently unimplemented on GNUstep, so it's not affected): When copying pixel data directly between bitmaps, the bitmaps should have the same color profile, otherwise they'll render on the screen in different colors (despite identical pixel data).

After generating a destination bitmap for a pixel-data operation, it should be assigned the source bitmap's color profile, if it has one:

{
    ...

destImageRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: ... ];

NSData *iccProfile = [srcImageRep valueForProperty: NSImageColorSyncProfileData];

    if (iccProfile)
    {
[destImageRep setProperty: NSImageColorSyncProfileData withValue: iccProfile];
    }
}


Cheers,

Josh



On Apr 12, 2016, at 9:26 AM, Riccardo Mottola wrote:

Hi,

while trying to debug the issue betweeen GUI and GWorkspace icons with multi-page tiffs and high-res versions of our GUI controls, I noticed something strange.

I did a test-case on Mac where due to different backgrounds it is easier to detect.

The "scale" (but actually any) code I use IN PRICE and thus in also in GWorkspace appears to be broken, it produces artefacts with images with Alpha channel.

Even verys imple code, where I copy from the source to destination all "samples per pixels" copies all colors correctly, copies but produces effect around the borders and, apparently, on certain images it totally ruins alpha, on others not, just around the borders.

e.g in simplified pseudocode.

for (height)
 for (width)
   for (i in samples per pixel)
    destData[xy +  i] = srcData[xy +i];

fails. The actual code is actually smarter and tries to use bytesPerRow.

Does a bell ring for anybody? I know that e.g. when scaling, pre- multiplied alpha should be considered, but this produces minor issues and should not affect just simple copying or flipping or such. The nested loops should essentially do a byte-copy.. and they do for images without alpha.

Riccardo

_______________________________________________
Gnustep-dev mailing list
address@hidden
https://lists.gnu.org/mailman/listinfo/gnustep-dev





reply via email to

[Prev in Thread] Current Thread [Next in Thread]