Search code examples
swiftparametersint32pixelformat

What to type in for int32 pixelFormat in Swift?


I'd like to use the function CGDisplayStreamCreateWithDispatchQueue.

The documentation tells me to use the following possible values for "pixelFormat": (The parameter needs to be an Int32)

The desired Core Media pixel format of the output frame data. The value must be one of the following:
'BGRA': Packed Little Endian ARGB8888
'l10r': Packed Little Endian ARGB2101010
'420v': 2-plane "video" range YCbCr 4:2:0
'420f': 2-plane "full" range YCbCr 4:2:0

If I type in for example 'BGRA', then Xcode tells me that this is an invalid argument. What shall do?


Solution

  • In the C language you can specify a multi-character constant which results in an int32 value. Swift doesn't provide this natively. You can just pass the equivalent constant.

    For 'BGRA' you need to pass 0x42475241. 0x42 is the ASCII value for B, 0x47 is the ASCII value for G, etc.

    I verified this by creating this function in C:

    int32_t convertBGRA() {
        int32_t i = 'BGRA';
    
        return i;
    }
    

    and calling it from Swift:

    print(String(format: "%x", convertBGRA()))  // output: "42475241"
    

    Here are all of the values:

    let pixelFormat_BGRA = 0x42475241
    let pixelFormat_l10r = 0x6c313072
    let pixelFormat_420v = 0x34323076
    let pixelFormat_420f = 0x34323066
    

    Here is an extension to Int32 that initializes the value from a string of 4 characters.

    extension Int32 {
        init?(char4: String) {
            var result: UInt32 = 0
    
            let scalars = char4.unicodeScalars
    
            if scalars.count != 4 {
                return nil
            } else {
                for s in scalars {
                    let value = s.value
                    if value > 255 {
                        return nil
                    }
                    result = result << 8 + value
                }
                self = Int32(bitPattern: result)
            }
        }
    }
    

    For an input of 'BGRA' you'd use:

    Int32(char4: "BGRA")!