Listing the current loaded colorsync (icc) profiles

Does anyone knows how to get a list of the current loaded ICC profiles.
In the past this could be done using the colorsyncScripting application which was included in the OS.
This application has now been removed.
Is there an alternative within the objective-c frameworks/ASOC to get information about icc profiles in general.

Thanks

NSColorSpace’s availableColorSpacesWithModel: looks like what you’re after.

Thanks Shane.
I indeed was using : current application’s NSColorSpace’s availableColorSpacesWithModel_(-1)

This works but the only problem is that I do not get all the profile types as colorsyncscripting did.
I compared the output of the two methods and there is a difference.
I think the ASOC way does not see profiles of type input and some other types too.
This is a beginning but it should be nice to have a good replacement for the colorsyncscripting app.

Have you tried listing the directories they’re stored in?

I did, the drawbacks are performance and the way the system loads the profiles (folder depths within the /Profiles/ directory, and the use of aliases (links) to other locations.
Listing is fast enough but the further handling to get the internal names of the profiles and excluding duplicates (from the internal names) makes the processing time take longer.
On my system ( a recent MacBook Pro) it takes about 8 seconds.

Here I have the code, maybe you have other suggestions about getting more performance. or using other methods.
Thanks


--  KDGetprofiles.applescript
script KDGetprofiles
	property parent : class "NSObject"
	
	on getLoadedProfiles()
		try
			set starttime to time of (current date)
			-- Get all profile locations
			set paths to NSSearchPathForDirectoriesInDomains(current application's NSLibraryDirectory, current application's NSAllDomainsMask, true) as list
			set profilesPath to current application's NSString's stringWithString_("/Colorsync/Profiles/")
			repeat with i from 1 to (count paths)
				set cur_path to (item i of paths) as string
				set fullpath to (cur_path & profilesPath) as string
				set item i of paths to fullpath
			end repeat
			
			-- list all profiles
			set laptime1 to time of (current date)
			set all_profiles to {}
			repeat with i from 1 to (count paths)
				set profile_location to item i of paths
				set {cur_profiles, cur_folders} to getProfilesFromLocation_(profile_location)
				set all_profiles to all_profiles & cur_profiles
				repeat with j from 1 to (count cur_folders)
					set cur_folder to (item j of cur_folders) as string
					set {cur_profile_list, cur_folder_list} to getProfilesFromLocation_(cur_folder)
					if cur_profile_list is false then error cur_folder_list
					if cur_profile_list is not {} then set all_profiles to all_profiles & cur_profile_list
				end repeat
			end repeat
			
			-- get internal profile names
			set laptime2 to time of (current date)
			set {internal_names, color_spaces, not_duplicate_indexes} to getInternalProfileNameFromList_(all_profiles)
			
			-- get unique names
			set laptime3 to time of (current date)
			set {profileNames, profileSpaces, profilePaths} to {{}, {}, {}}
			repeat with i from 1 to (count not_duplicate_indexes)
				set cur_index to (item i of not_duplicate_indexes)
				set end of profileNames to item cur_index of internal_names
				set end of profilePaths to item cur_index of all_profiles
				set end of profileSpaces to item cur_index of color_spaces
			end repeat
			
			set laptime4 to time of (current date)
			
			set stoptime to time of (current date)
			log "get locations " & laptime1 - starttime
			log "list all profiles  " & laptime2 - laptime1
			log "get internal names " & laptime3 - laptime2
			log "remove duplicates " & laptime4 - laptime3
			log "Total time is " & stoptime - starttime
			log (count all_profiles)
			log (count profileNames)
			log (count profilePaths)
			log profileNames
			log profilePaths
			log profileSpaces
			
			return {stoptime - starttime, profileNames, profilePaths, profileSpaces}
		on error errmsg
			log "main   " & errmsg
			return false
		end try
	end getLoadedProfiles
	
	
	on getProfilesFromLocation_(cur_path)
		try
			set cur_path to cur_path as string
			set folderlist to {}
			set profileList to {}
			set localFileManager to current application's NSFileManager's alloc()'s init()
			set localWorkspace to current application's NSWorkspace's alloc()'s init()
			set cur_list to localFileManager's contentsOfDirectoryAtPath_error_(cur_path, missing value)
			if cur_list is missing value then
				set cur_list to {}
			else
				
				set cur_list to cur_list as list
				repeat with j from 1 to (count cur_list)
					if (item j of cur_list) is not in {missing value, ".DS_Store"} then
						set cur_item to (cur_path & (item j of cur_list) as string) as string
						set {itemExists, isFolder} to localFileManager's fileExistsAtPath_isDirectory_(cur_item, reference)
						if (isFolder as boolean) and (itemExists as boolean) then
							set end of folderlist to (cur_item & "/") as string
						else
							-- is file
							set {didFindIt, appPath, theExtension} to localWorkspace's getInfoForFile_application_type_(cur_item, reference, reference)
							set isProfile to ((appPath as string) contains "Colorsync") or ((theExtension as string) is in {"icc", "icm", "pf"}) as boolean
							if isProfile then set end of profileList to cur_item as string
						end if
					end if
				end repeat
			end if
			localFileManager's release()
			localWorkspace's release()
			return {profileList, folderlist}
		on error errmsg
			log "getProfilesFromLocation_   " & errmsg
			try
				localFileManager's release()
				localWorkspace's release()
			end try
			return {false, errmsg}
		end try
	end getProfilesFromLocation_
	
	on getInternalProfileNameFromList_(all_profiles)
		set all_description_names to {}
		set color_spaces to {}
		set notDuplicates to {}
		
		repeat with i from 1 to (count all_profiles)
			set cur_item to (item i of all_profiles) as string
			set theResult to paragraph 2 of (do shell script "sips -g description " & quoted form of cur_item)
			set theString to current application's NSString's stringWithString_(theResult as string)
			set parsedItems to theString's componentsSeparatedByString_(("  " & "description" & ": "))
			set cur_description_name to (item 2 of parsedItems) as string
			if cur_description_name is not in all_description_names then
				set end of notDuplicates to i
			end if
			set end of all_description_names to cur_description_name
			try
				set theResult to paragraph 2 of (do shell script "sips -g space " & quoted form of cur_item)
				set theString to current application's NSString's stringWithString_(theResult as string)
				set parsedItems to theString's componentsSeparatedByString_(("  " & "space" & ": "))
				set cur_color_space to (item 2 of parsedItems) as string
				set end of color_spaces to cur_color_space
			on error errmsg
				log "getInternalProfileNameFromList_    " & errmsg
				set end of color_spaces to "missing value"
			end try
		end repeat
		return {all_description_names, color_spaces, notDuplicates}
	end getInternalProfileNameFromList_
	
end script





Well your logs show where the time is being taken, and thus where to focus. As a general comment, things like this:

           set theString to current application's NSString's stringWithString_(theResult as string)
           set parsedItems to theString's componentsSeparatedByString_((" " & "description" & ": "))
           set cur_description_name to (item 2 of parsedItems) as string

are pretty inefficient. Going from text to NSString and back to text for something text item delimiters can do may well be costing you time. But if you do go to NSString, you might want to stay in Cocoa classes, and use an NSMutableArray and addObject_ rather than “set end of list…”.

Can you avoid the call to sips?

Hi Shane,
Thanks again for your reaction. It’s a good feeling when learning new things all the time.

I suddenly remembered that the “Image Events.app” from /System/Library/CoreServices/ is still there while ColorSyncScripting.app has been removed.
With the Image Events.app I can do things from the ColorSync and from the sips applications.
After some tests I have now the result I wanted with performance. With the image events I can get all the properties of the profiles from the internal names (description) whenever needed.
Here is the strongly reduced code need.

Again thanks for your support.


script KDGetprofiles
	property parent : class "NSObject"
	
	on getLoadedProfiles()
		try
                   set starttime to time of (current date)
		   set stoptime to time of (current date)
                   set {unique_profile_names, unique_profile_locations} to getProfiles()
                   set stoptime to  time of (current date)
                   log "done in "&stoptime-starttime
		   return {stoptime - starttime, unique_profile_names, unique_profile_locations, {}}
		on error errmsg
			log "main   " & errmsg
			return false
		end try
	end getLoadedProfiles
	    
    on getProfiles()
        set unique_profile_names to {}
        set unique_profile_locations to {}
        tell application "Image Events"
            set all_profile_names to name of profiles
            set all_profile_locations to POSIX path of location of profiles
            repeat with i from 1 to (count all_profile_names)
                set cur_profile_name to item i of all_profile_names
                if cur_profile_name is not in unique_profile_names then
                    set end of unique_profile_names to cur_profile_name
                    set end of unique_profile_locations to item i of all_profile_locations
                end if
            end repeat
        end tell
        return {unique_profile_names, unique_profile_locations}
    end getProfiles

end script