How to tell the difference between RAW and ProRAW

Published on by Geoff Taylor

If you’ve been shooting RAW photos on your iPhone for a few years, and now you’re shooting ProRAW, you probably have a mix of RAW and ProRAW images in the Photos app. How can you tell the difference? Both are DNG files, and the Photos app identifies both simply as “RAW.” Here’s a regular RAW photo in the Photos app.

And here’s a ProRAW photo.

There is a difference, however, as you can see in Halide’s photo viewer. The RAW file’s photometric interpretation is “CFA,” and the ProRAW file’s photometric interpretation is “Linear RAW.”

A RAW photo's attributes viewed in Halide.
A RAW photo's attributes viewed in Halide.
A ProRAW photo's attributes viewed in Halide.
A ProRAW photo's attributes viewed in Halide.

But if I’m in the Photos app, I don’t want to switch to Halide just to find out what kind of RAW file it is. I normally use ViewExif’s extension to inspect EXIF data in the Photos app, but it doesn’t show the photometric interpretation, so I decided to see if Shortcuts could help.

I started with a simple shortcut that gets a dictionary from an image.

The dictionary helpfully includes the photometric interpretation, but it’s a number.

Thanks to the ExifTool website, which includes a comprehensive list of EXIF tags, I learned that a photometric interpretation value of 34892 indicates a Linear RAW, and a value of 32803 indicates a CFA (Color Filter Array, or a regular RAW file).

I created a shortcut that performs these steps.

  1. Get an image via the share sheet.
  2. If the image file’s extension is not “DNG,” just display the extension in an alert.
  3. If the image file’s extension is “DNG,” get a dictionary from the image.
  4. Get the value of the dictionary’s “{TIFF}” key, which is another dictionary.
  5. From that second dictionary, get the value of the “PhotometricInterpretation” key.
  6. From that second dictionary, get the value of the “Make” key.
  7. If the photometric interpretation is 34892 and the make is “Apple,” display “ProRAW” in an alert.
  8. If the photometric interpretation is 34892 and the make is not “Apple,” display “Linear RAW” in an alert.
  9. If the photometric interpretation is 32803, display “RAW” in an alert.
  10. Otherwise display “Unknown” in an alert.

The logic is that, since all ProRAW files are Linear RAW, and ProRAW is a format used only by Apple cameras, a Linear RAW file created by an Apple camera is a ProRAW file. However, Linear RAW has been around longer than ProRAW, so your phone may hold Linear RAW files created by other devices or apps. The shortcut will simply display those as “Linear RAW.” Any CFA file is displayed as “RAW.” Since ProRAW photos and RAW photos taken with an iPhone are always DNG files, this only works for DNG files. If the file has any other extension, the shortcut will just report the extension as the image type. (You can download the shortcut here.)

This approach is admittedly a little naive. Changes to the photo metadata could break the shortcut, but at least for now, it works. This is what it looks like when you run the shortcut from the share sheet.

Running the shortcut with a ProRAW photo
Running the shortcut with a ProRAW photo
Running the shortcut with a RAW photo
Running the shortcut with a RAW photo

How do you tell the difference on a Mac? I recommend using ExifTool. After you’ve installed ExifTool, open Terminal and enter this command:

exiftool -S -PhotometricInterpretation -Make /path/to/file.dng

(Replace /path/to/file.dng with the path to a DNG file.) It will display either

PhotometricInterpretation: Color Filter Array
Make: (Camera Make)

or

PhotometricInterpretation: Linear Raw
Make: (Camera Make)

where “(Camera Make)” is the name of the camera manufacturer.

You can use this information to determine if the DNG file is a ProRAW image, another type of Linear RAW image, or a regular RAW image. For example, for a ProRAW file, the command would display this output:

PhotometricInterpretation: Linear Raw
Make: Apple

Scripting the menu bar in macOS Big Sur

Published on by Geoff Taylor

This post explores some changes in Big Sur that affect UI scripting, specifically UI scripts that interact with the menu bar. I learned much of this while updating my Keyboard Maestro macro for Sidecar to work with Big Sur, so most of the information is presented in that context.

A brief introduction to UI scripting

UI (user interface) scripting is a really neat macOS feature that allows you to automate almost anything using AppleScript. Even if the app doesn’t expose a scripting interface, UI scripting works because it simulates button presses, keystrokes and other actions that you would perform if you were doing the task manually.

UI scripts use an application called System Events. You manipulate user interface elements by telling System Events to tell another process (application) to do something. For example, this code will click the Export Playlist… item in the Music app’s File menu:

tell application "System Events"
  tell its process "Music"
      click menu item "Export Playlist…" of menu "Library" of menu item "Library" of menu "File" of menu bar 1
  end tell
end tell

Often, the hardest part of writing a UI script is figuring out how to tell the process what to click. If you want the script to click a menu item, you usually can’t tell it to click the menu item directly; as in the example above, you have to give it the path from the menu bar down to the item you want it to click: click menu item "Export Playlist..." of menu "Library" of menu item "Library" of menu "File" of menu bar 1. (This example is actually written from the bottom up, but you can see that it includes the path from the menu bar — menu bar 1 — to the menu item Export Playlist...)

In addition to application menus, System Events can click system menus such as the volume menu and the Bluetooth menu. My Keyboard Maestro macro for Sidecar for Catalina and Big Sur uses a UI script to activate Sidecar via the Display menu. The original version of the macro broke under Big Sur, which is what led me down this rabbit hole.

Scripting the menu bar in Catalina

In Catalina, the system menus (Bluetooth, volume and so forth) in the menu bar are controlled by the process SystemUIServer. (SystemUIServer also controls the system menus in High Sierra and Mojave. I don’t have an OS older than High Sierra, so I don’t know if it was the same in older versions.)

You can see in this screenshot of Script Debugger running under Catalina that the element hierarchy for the Displays Menu is System Events > SystemUIServer > menu bar 1 > menu bar item 17. Using the description property shown in the screenshot, we can make that a little more intuitive, and not have to worry about finding the menu bar item number, by calling it menu bar item 1 of menu bar 1 whose description contains "Displays". There’s only one menu bar, so menu bar 1 always refers to the menu bar. There’s only one system menu called “Displays Menu,” so menu bar item 1 whose description contains "Displays" refers to the Displays Menu.

Script Debugger showing the Displays Menu in Catalina
Script Debugger showing the Displays Menu in Catalina

Because the Displays Menu hasn’t been clicked, its menu items aren’t visible, so Script Debugger can’t show you is the items in the Displays Menu. For that you need an app like UI Browser.

Using UI Browser, you can find the scriptable menu elements as you click the menu. In this case, I want to find “Geoff’s iPad” in the Displays Menu.

UI Browser showing menu path to iPad in Catalina
UI Browser showing menu path to iPad in Catalina

Once we know how to refer to the menu items, we can write the AppleScript code:

set deviceName to "Geoff's iPad"

tell application "System Events"
  tell process "SystemUIServer"
    click (menu bar item 1 of menu bar 1 whose description contains "Displays")
    set displayMenu to menu 1 of result
    if ((menu item 1 where its name starts with deviceName) of displayMenu) exists then
      -- Not connected, so click the name of the device to connect
      click ((menu item 1 where its name starts with deviceName) of displayMenu)
    else
      -- Connected, so click "Disconnect" to disconnect
      click ((menu item 1 where its name starts with "Disconnect") of displayMenu)
    end if
  end tell
end tell

(You can use Script Editor, which is installed by default on every Mac, instead of Script Debugger, but it’s not as full-featured. Likewise, Accessibility Inspector is a less capable but free alternative to UI Browser. It’s included with Xcode, which is a free download from the Mac App Store.)

Changes in Big Sur

Big Sur introduced breaking changes to the system menus. The first change you can see in the screenshot below is that most of the system menus aren’t controlled by SystemUIServer. In Big Sur, they’re controlled by the ControlCenter process.

The SystemUIServer process in Big Sur
The SystemUIServer process in Big Sur
The ControlCenter process in Big Sur
The ControlCenter process in Big Sur

Second, there’s no Displays Menu. Like many system menu items, it’s part of the Control Center menu and not displayed in the menu bar by default. And it’s now called “Display” instead of “Displays Menu.”

Big Sur Control Center menu
Big Sur Control Center menu

You can move the Display menu to the menu bar by going to System Preferences > Dock & Menu Bar and setting the Display menu to always display in the menu bar.

System Preferences > Dock & Menu Bar > Display
System Preferences > Dock & Menu Bar > Display

And now the menu bar contains a Display menu that shows my iPad as a Sidecar device.

Big Sur Display menu
Big Sur Display menu

You would think that at this point, we should be able to script the Big Sur menu bar in roughly the same way we did in Catalina. But there’s yet another big change: The system menus aren’t menu elements, and menu items aren’t menu item elements. In Big Sur, system menus are application windows, and menu items are buttons or checkboxes that are nested in groups and scroll areas.

Sidecar Preferences is a button...
Sidecar Preferences is a button...
... and my iPad is a checkbox
... and my iPad is a checkbox

Much like you have to specify the full menu hierarchy to make the script click a menu item, you must give the script the full path to the desired button. A note here on the different ways certain elements are identified: “Control Center” is identified as a system dialog and a window. My iPad is identified as a toggle button and a checkbox. The names in parentheses after the element (window and checkbox in this case) are the names you use in the script.

Putting it all together

Now that we know how the menus work in Big Sur, how do we put it all together to control the menu with a script? Step one is to determine if the Display menu is present in the menu bar. (I couldn’t get it to work unless the Display menu was always shown in the menu bar.) To accomplish this part, I took the inelegant approach of initializing the variable displayMenu to an empty string (""). Then the script checks all the menu bar items for one whose name contains ‘Display’. If it finds the Display menu, displayMenu becomes a reference to the menu.

set deviceName to "Geoff's iPad" -- Change this to the name of your iPad

set displayMenu to "" -- Do not change this

tell application "System Events"
  tell its application process "ControlCenter"
    -- Get all menu bar items.
    set menuBarItems to menu bar items of menu bar 1
    
    -- Determine if the Display menu is in the menu bar.
    repeat with mbi in menuBarItems
      if name of mbi contains "Display" then
        set displayMenu to mbi
      end if
    end repeat

The script clicks the Display menu, which allows the script to “view” the hierarchy of elements and find the checkbox with the same name as the deviceName variable. Then it clicks the checkbox, which activates Sidecar. (Admittedly, this section needs some error handling because the script will crash if the device isn’t in range of the Mac. But as long as the device is in range, it does the job.)

-- If the Display menu is in the menu bar, get the Sidecar device.
    -- In Big Sur, it's a toggle button (checkbox) instead of a menu item.
    if displayMenu is not equal to "" then
      click displayMenu
      set deviceToggle to checkbox 1 of scroll area 1 of group 1 of window "Control Center" whose title contains deviceName
      
      -- Click the device.
      click deviceToggle

There’s one more accommodation we need to make for Big Sur. In Catalina, activating Sidecar closes the Displays Menu. In Big Sur, the Display menu stays open after activating Sidecar. We can close the menu by simply clicking it again, except that the menu name changes to “Display, Sidecar on” when Sidecar is active.

Script Debugger showing Display menu when Sidecar is active
Script Debugger showing Display menu when Sidecar is active

The script doesn’t know about the menu called “Display, Sidecar on,” so we use this code to correctly identify the menu and click to close it:

-- The menu name changes when Sidecar is active, so we need to get the Display menu again, then click to close it.
    set displayMenu to (first menu bar item whose name contains "Display") of menu bar 1
    click displayMenu

Here’s the full script:

set deviceName to "Geoff's iPad" -- Change this to the name of your iPad

set displayMenu to "" -- Do not change this

tell application "System Events"
  tell its application process "ControlCenter"
    -- Get all menu bar items.
    set menuBarItems to menu bar items of menu bar 1
    
    -- Determine if the Display menu is in the menu bar.
    repeat with mbi in menuBarItems
      if name of mbi contains "Display" then
        set displayMenu to mbi
      end if
    end repeat
    
    -- If the Display menu is in the menu bar, get the Sidecar device.
    -- In Big Sur, it's a toggle button (checkbox) instead of a menu item.
    if displayMenu is not equal to "" then
      click displayMenu
      set deviceToggle to checkbox 1 of scroll area 1 of group 1 of window "Control Center" whose title contains deviceName
      
      -- Click the device.
      click deviceToggle
      
      -- The menu name changes when Sidecar is active, so we need to get the Display menu again, then click to close it.
      set displayMenu to (first menu bar item whose name contains "Display") of menu bar 1
      click displayMenu
    else
      -- If the Display menu isn't in the menu bar, display an error message.
      set errorMessage to "Display menu not found in menu bar. Open System Preferences > Dock & Menu Bar. Set Display to \"Show in Menu Bar > Always.\""
      display dialog errorMessage with icon caution
    end if
  end tell
end tell

The changes in Big Sur make it harder to properly identify the menu items for scripting, and Apple’s UI Scripting documentation — which is outdated and cursory — doesn’t help. Hopefully this post proves helpful in understanding the changes and adapting old scripts for Big Sur.

Keyboard Maestro, Sidecar and Big Sur

Published on by Geoff Taylor

It was recently brought to my attention that my Keyboard Maestro macro for Sidecar doesn’t work under Big Sur. I have Big Sur installed, but my main OS is still Catalina, so I hadn’t yet thought to try the macro under Big Sur.

After a couple of hours of debugging with Script Debugger and Accessibility Inspector – not to mention a good deal of trial and error – I discovered that Big Sur significantly changed the way the menu bar is exposed to AppleScript. (I’ll try to cover that in a separate post; it’s a bit too much to go into in this post.) I finally figured out how to access the right menu bar items with AppleScript and updated the macro’s script to work under Big Sur.

You can download the updated macro here or just create a macro with an Execute AppleScript action. Copy and paste this code into the action:

set deviceName to "The name of your iPad" -- Change this to the name of your iPad

set displayMenu to "" -- Do not change this

tell application "System Events"
	tell its application process "ControlCenter"
		-- Get all menu bar items.
		set menuBarItems to menu bar items of menu bar 1
		
		-- Determine if the Display menu is in the menu bar.
		repeat with mbi in menuBarItems
			if name of mbi contains "Display" then
				set displayMenu to mbi
			end if
		end repeat
		
		-- If the Display menu is in the menu bar, get the Sidecar device.
		-- In Big Sur, it's a toggle button (checkbox) instead of a menu item.
		if displayMenu is not equal to "" then
			click displayMenu
			set deviceToggle to checkbox 1 of scroll area 1 of group 1 of window "Control Center" whose title contains deviceName
			
			-- Click the device.
			click deviceToggle
			
			-- The menu name changes when Sidecar is toggled, so we need to get the Display menu again, then click to close it.
			set displayMenu to (first menu bar item whose name contains "Display") of menu bar 1
			click displayMenu
		else
			-- If the Display menu isn't in the menu bar, display an error message.
			set errorMessage to "Display menu not found in menu bar. Open System Preferences > Dock & Menu Bar. Set Display to \"Show in Menu Bar > Always.\""
			display dialog errorMessage with icon caution
		end if
	end tell
end tell

You need to change two things before you can use this code. First, change “The name of your iPad” (in the first line of the script) to the real name of your iPad (leave the quotation marks around the name). Second, open System Preferences > Dock & Menu Bar, and set the Display menu to always show in the menu bar.

Dock & Menu Bar Preferences
Dock & Menu Bar Preferences

PopClip extension: Backticks

Published on by Geoff Taylor

I made a new PopClip extension. It’s similar to the official Quotes or Brackets extension, except for programmers. It encloses the selected text within ` ` , ' ', " ", ( ), [ ], { } or < >. Download it here. View the source on GitHub.

PopClip extension for Choosy

Published on by Geoff Taylor

I made a PopClip extension for Choosy. Download it here. View the source on GitHub.