Post

Replies

Boosts

Views

Activity

Reply to CIColorCube sometimes producing no or broken output in macOS 13
It turns out the problem was caused by how we loaded the cube data. Previously, we did it like this: let cubeImage: CGImage = ... // render cube image into a 32-bit float context, since that's the data format needed by CIColorCube let pixelData = UnsafeMutablePointer<simd_float4>.allocate(capacity: cubeImage.width * cubeImage.height) let bitmapInfo = CGImageAlphaInfo.premultipliedLast.rawValue | CGBitmapInfo.floatComponents.rawValue | CGBitmapInfo.byteOrder32Little.rawValue let colorSpace = cubeImage.colorSpace ?? CGColorSpace.sRGBColorSpace guard let bitmapContext = CGContext(data: pixelData, width: cubeImage.width, height: cubeImage.height, bitsPerComponent: MemoryLayout<simd_float4.Scalar>.size * 8, bytesPerRow: MemoryLayout<simd_float4>.size * cubeImage.width, space: colorSpace, bitmapInfo: bitmapInfo) else { assertionFailure("Failed to create bitmap context for conversion") } bitmapContext.draw(cubeImage, in: CGRect(x: 0, y: 0, width: cubeImage.width, height: cubeImage.height)) let data = Data(bytesNoCopy: pixelData, count: bitmapContext.bytesPerRow * bitmapContext.height, deallocator: .free) // pass data to filter Note that we pre-allocated the pixelData buffer and gave it to the CGContext to render the cube image into it. It seems that data was corrupted or released too early in some cases, causing the erroneous behavior described above, even though we assumed that Data(bytesNoCopy:...) would take ownership of the data. To fix this, we let CGContext create its own buffer and copy the cube data after the draw: let cubeImage: CGImage = ... // render cube image into a 32-bit float context, since that's the data format needed by CIColorCube let bitmapInfo = CGImageAlphaInfo.premultipliedLast.rawValue | CGBitmapInfo.floatComponents.rawValue | CGBitmapInfo.byteOrder32Little.rawValue let colorSpace = cubeImage.colorSpace ?? CGColorSpace.sRGBColorSpace guard let bitmapContext = CGContext(data: nil, width: cubeImage.width, height: cubeImage.height, bitsPerComponent: MemoryLayout<simd_float4.Scalar>.size * 8, bytesPerRow: MemoryLayout<simd_float4>.size * cubeImage.width, space: colorSpace, bitmapInfo: bitmapInfo) else { assertionFailure("Failed to create bitmap context for conversion") } bitmapContext.draw(cubeImage, in: CGRect(x: 0, y: 0, width: cubeImage.width, height: cubeImage.height)) guard let pixelData = bitmapContext.data else { assertionFailure("Failed to get cube data") } let data = Data(bytes: pixelData, count: bitmapContext.bytesPerRow * bitmapContext.height) // pass data to filter
Oct ’22
Reply to Adding HDR Gain Map to HEIF/JPEG manually
I think I found the reason why the gain map isn't showing any effect: There seem to be two private {MakerApple} EXIF tags controlling the HDR effect. The one @anteo83 mentioned (0x21) seems to control the global boost to brightness. I guess via some kind of gamma curve tone mapping. But there is also the 0x30 which controls how much the embedded gain map adds to the effect. It seems to range between 0.0 and 8.0, with 0.0 having the biggest effect. When 0x30 is present, 0x21 doesn't need to be present to show the effects of the gain map. They also seem to work in tandem, with 0x21 adding to the global value and 0x30 controlling local values via gain map. There is some great fun to be had with this. Check out the attached image on your XDR or OLED device in Photos. 😁 Edit: I was trying to attach an example image here, but Forums seem to convert the image, losing the gain map in the process. You can find it here.
Sep ’22
Reply to Validation failed error code when attempting to activate a Core Media I/O extension
I encountered the same. When I re-watched the session, I heard Brad say the following: And I need to ensure here that my extension's app group is prefixed by the MachServiceName in order for it to pass validation. I changed the CMIOExtensionMachServiceName in the extension's Info.plist to the same value as my app's and extension's app group name and suddenly it passed validation. I'm not sure if this is the intended configuration. Maybe Apple's Extensions team can clarify what the "prefixed" means here and what the values should look like.
Jun ’22
Reply to CISourceOverComposition unexpected behavior
I guess this is happening because CIPhotoEffectTonal also has an effect on the transparent parts of the image. If you want to limit the effect to the visible part, you can simply crop the image after the effect is applied and before you blend it over the background: video1FilteredImage = [video1FilteredImage imageByCroppingToRect:video1FilteredImage.extent]; By the way: instead of using CIConstantColorGenerator you can simply get a colored image like this: CIImage *colorBackgroundImage = [CIImage imageWithColor:inputColor];
May ’22