View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0036311 | Lazarus | LCL | public | 2019-11-13 15:49 | 2020-04-01 06:56 |
Reporter | TK | Assigned To | Dmitry Boyarintsev | ||
Priority | normal | Severity | minor | Reproducibility | always |
Status | closed | Resolution | fixed | ||
Product Version | 2.1 (SVN) | ||||
Summary | 0036311: Cocoa support for BGRA or ABGR bitmaps | ||||
Description | There was problem using bitmaps with BGRA or ABGR bitmaps (Windows bitmaps) in Cocoa. There was TODO exception. Even the IDE could not read forms with these and crashed. I made a fix for this. Since I could not find how to pass those bitmaps to Cocoa API directly I just made a simple workaround - swapping B and R components. | ||||
Tags | No tags attached. | ||||
Fixed in Revision | 62351 | ||||
LazTarget | - | ||||
Widgetset | Cocoa | ||||
Attached Files |
|
related to | 0036374 | resolved | Juha Manninen | gtk3: Canvas artifacts, swapped R/B colors |
|
cocoa_bitmap_bgra_support.patch (4,983 bytes)
Index: lcl/interfaces/cocoa/cocoagdiobjects.pas =================================================================== --- lcl/interfaces/cocoa/cocoagdiobjects.pas (revision 62190) +++ lcl/interfaces/cocoa/cocoagdiobjects.pas (working copy) @@ -31,7 +31,9 @@ cbtGray, // grayscale bitmap cbtRGB, // color bitmap 8-8-8 R-G-B cbtARGB, // color bitmap with alpha channel first 8-8-8-8 A-R-G-B - cbtRGBA // color bitmap with alpha channel last 8-8-8-8 R-G-B-A + cbtRGBA, // color bitmap with alpha channel last 8-8-8-8 R-G-B-A + cbtABGR, // color bitmap with alpha channel first 8-8-8-8 A-B-G-R + cbtBGRA // color bitmap with alpha channel last 8-8-8-8 B-G-R-A ); const @@ -870,6 +872,43 @@ constructor TCocoaBitmap.Create(AWidth, AHeight, ADepth, ABitsPerPixel: Integer; AAlignment: TCocoaBitmapAlignment; AType: TCocoaBitmapType; AData: Pointer; ACopyData: Boolean); + +type + TColorEntry = packed record + C1, C2, C3, C4: Byte; + end; + PColorEntry = ^TColorEntry; + + TColorEntryArray = array[0..MaxInt div SizeOf(TColorEntry) - 1] of TColorEntry; + PColorEntryArray = ^TColorEntryArray; + + + procedure CopySwappedColorComponents(ASrcData, ADestData: PColorEntryArray; ADataSize: Integer; AType: TCocoaBitmapType); + var + I: Integer; + begin + //switch B and R components + for I := 0 to ADataSize div SizeOf(TColorEntry) - 1 do + begin + case AType of + cbtABGR: + begin + ADestData^[I].C1 := ASrcData^[I].C1; + ADestData^[I].C2 := ASrcData^[I].C4; + ADestData^[I].C3 := ASrcData^[I].C3; + ADestData^[I].C4 := ASrcData^[I].C2; + end; + cbtBGRA: + begin + ADestData^[I].C1 := ASrcData^[I].C3; + ADestData^[I].C2 := ASrcData^[I].C2; + ADestData^[I].C3 := ASrcData^[I].C1; + ADestData^[I].C4 := ASrcData^[I].C4; + end; + end; + end; + end; + begin inherited Create(False); {$ifdef VerboseBitmaps} @@ -885,7 +924,15 @@ System.GetMem(FData, FDataSize); FFreeData := True; if AData <> nil then - System.Move(AData^, FData^, FDataSize) // copy data + begin + if AType in [cbtABGR, cbtBGRA] then + begin + Assert(AWidth * AHeight * SizeOf(TColorEntry) = FDataSize); + CopySwappedColorComponents(AData, FData, FDataSize, AType); + end + else + System.Move(AData^, FData^, FDataSize) // copy data + end else FillDWord(FData^, FDataSize shr 2, 0); // clear bitmap end @@ -982,7 +1029,7 @@ HasAlpha: Boolean; BitmapFormat: NSBitmapFormat; begin - HasAlpha := FType in [cbtARGB, cbtRGBA]; + 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 @@ -989,7 +1036,7 @@ if FFreeData then PreMultiplyAlpha(); BitmapFormat := 0; - if FType in [cbtARGB, cbtRGB] then + if FType in [cbtARGB, cbtABGR, cbtRGB] then BitmapFormat := BitmapFormat or NSAlphaFirstBitmapFormat; //WriteLn('[TCocoaBitmap.Create] FSamplesPerPixel=', FSamplesPerPixel, Index: lcl/interfaces/cocoa/cocoaobject.inc =================================================================== --- lcl/interfaces/cocoa/cocoaobject.inc (revision 62190) +++ lcl/interfaces/cocoa/cocoaobject.inc (working copy) @@ -776,11 +776,23 @@ and (ADesc.BlueShift = 0 ) then bmpType := cbtARGB else - if (ADesc.AlphaShift = 0) + if (ADesc.AlphaShift = 24) + and (ADesc.RedShift = 0 ) + and (ADesc.GreenShift = 8 ) + and (ADesc.BlueShift = 16) + then bmpType := cbtABGR + else + if (ADesc.AlphaShift = 0 ) and (ADesc.RedShift = 24) - and (ADesc.GreenShift = 16 ) + and (ADesc.GreenShift = 16) and (ADesc.BlueShift = 8 ) then bmpType := cbtRGBA + else + if (ADesc.AlphaShift = 0 ) + and (ADesc.RedShift = 8 ) + and (ADesc.GreenShift = 16) + and (ADesc.BlueShift = 24) + then bmpType := cbtBGRA else Exit; end else begin @@ -790,11 +802,23 @@ and (ADesc.BlueShift = 24) then bmpType := cbtARGB else - if (ADesc.AlphaShift = 24 ) + if (ADesc.AlphaShift = 0 ) + and (ADesc.RedShift = 24) + and (ADesc.GreenShift = 16) + and (ADesc.BlueShift = 8 ) + then bmpType := cbtABGR + else + if (ADesc.AlphaShift = 24) and (ADesc.RedShift = 0 ) - and (ADesc.GreenShift = 8) + and (ADesc.GreenShift = 8 ) and (ADesc.BlueShift = 16) then bmpType := cbtRGBA + else + if (ADesc.AlphaShift = 24) + and (ADesc.RedShift = 16) + and (ADesc.GreenShift = 8 ) + and (ADesc.BlueShift = 0 ) + then bmpType := cbtBGRA else Exit; end; end |
|
IMO graphtype has platform-agnostic set of routines for rawimage manipulation |
|
I knew something like that existed but didn't remember anymore how to use it. I just needed this feature working. When looking on graphtype.pp source now (RawImage_WriteBits etc.) it seems to me that at least my solution is a lot faster because TRawImage is more generous. |
|
thanks for the patch, applied |
Date Modified | Username | Field | Change |
---|---|---|---|
2019-11-13 15:49 | TK | New Issue | |
2019-11-13 15:49 | TK | File Added: cocoa_bitmap_bgra_support.patch | |
2019-11-13 19:51 | Anton Kavalenka | Note Added: 0119274 | |
2019-11-13 23:02 | TK | Note Added: 0119282 | |
2019-12-08 05:30 | Dmitry Boyarintsev | Assigned To | => Dmitry Boyarintsev |
2019-12-08 05:30 | Dmitry Boyarintsev | Status | new => resolved |
2019-12-08 05:30 | Dmitry Boyarintsev | Resolution | open => fixed |
2019-12-08 05:30 | Dmitry Boyarintsev | Fixed in Revision | => 62351 |
2019-12-08 05:30 | Dmitry Boyarintsev | LazTarget | => - |
2019-12-08 05:30 | Dmitry Boyarintsev | Widgetset | Cocoa => Cocoa |
2019-12-08 05:30 | Dmitry Boyarintsev | Note Added: 0119688 | |
2020-01-22 21:03 | TK | Status | resolved => closed |
2020-04-01 06:56 | Juha Manninen | Relationship added | related to 0036374 |