Hello!
I'm trying to add support for NSColorSpace to TCocoaBitmap as it's the only way of displaying image colors correctly on OSX.
Some pieces of my code:
FN:='System/Library/ColorSync/Profiles/AdobeRGB1998.icc';
LoadBinFile(FN, data, size);
iccData := NSData.dataWithBytes_length(data, size);
Next, i added to CocoaGDIObjects to TCocoaBitmap class these lines
FICCAssigned : Boolean;
FNSColorSpace : NSColorSpace;
FNSColorSpaceData : NSData;
procedure SetColorspace(iccdata: NSData);
procedure TCocoaBitmap.SetColorspace(iccdata: NSData);
begin
FNSColorSpaceData:=iccdata;
if FNSColorSpaceData<>nil then
Begin
if FNSColorSpace <>nil then
Begin
FNSColorSpace.release;
end;
FNSColorSpace:=NSColorSpace.alloc.initWithICCProfileData(FNSColorSpaceData);
GFNSColorSpace:=NSColorSpace.alloc.initWithICCProfileData(GFNSColorSpaceData);
FICCAssigned:=True;
End;
SetModified;
End;
I modified CreateHandle so it would change bitmap profile after creating:
procedure TCocoaBitmap.CreateHandle();
var
HasAlpha: Boolean;
BitmapFormat: NSBitmapFormat;
AImageRep: NSBitmapImageRep;
begin
HasAlpha := FType in [cbtARGB, cbtRGBA, cbtABGR, cbtBGRA];
// Non premultiplied bitmaps can't be used for bitmap context
// So we need to pre-multiply ourselves, but only if we were allowed
// to copy the data, otherwise we might corrupt the original
if FFreeData then
PreMultiplyAlpha();
BitmapFormat := 0;
if FType in [cbtARGB, cbtABGR, cbtRGB] then
BitmapFormat := BitmapFormat or NSAlphaFirstBitmapFormat;
//WriteLn('[TCocoaBitmap.Create] FSamplesPerPixel=', FSamplesPerPixel,
// ' FData=', DebugShowData());
// Create the associated NSImageRep
Assert(FImagerep = nil);
AImageRep := NSBitmapImageRep.alloc.initWithBitmapDataPlanes_pixelsWide_pixelsHigh__colorSpaceName_bitmapFormat_bytesPerRow_bitsPerPixel(
@FData, // planes, BitmapDataPlanes
FWidth, // width, pixelsWide
FHeight,// height, PixelsHigh
FBitsPerSample,// bitsPerSample, bps
FSamplesPerPixel, // samplesPerPixel, spp
HasAlpha, // hasAlpha
False, // isPlanar
GetColorSpace, // colorSpaceName
BitmapFormat, // bitmapFormat
FBytesPerRow, // bytesPerRow
FBitsPerPixel //bitsPerPixel
);
If FICCAssigned then
begin
FImageRep := AImageRep.bitmapImageRepByRetaggingWithColorSpace(FNSColorSpace);
AImageRep.release;
end
else
FImageRep := AImageRep;
// Create the associated NSImage
Assert(FImage = nil);
FImage := NSImage.alloc.initWithSize(NSMakeSize(FWidth, FHeight));
//pool := NSAutoreleasePool.alloc.init;
Image.addRepresentation(FImagerep);
//pool.release;
end;
This works if I first create bitmap and assign icc:
TCocoaBitmap(Bmp.Handle).SetColorspace(iccData)
But if this bitmap was ever shown, setting it's color space causes an exception in procedure TCocoaBitmap.FreeHandle();
during FImageRep.release;
I'm using latest lazarus from SVN.
I'd like to have this method added to SVN, but I don't know how to do that. I'd be happy to donate to anyone who can help me solving this problem.
Oleg