Classic Mac OS 9 Icons

Recently I have been looking for Mac OS 9 icons for a separate project, but they are getting rarer by the days. Luckily, NazoraioiSkadinaujo on DeviantArt1 had ran into the same issue and decided to extract the icons themselves back in 2008. The problem is that the files are in the rsrc format and I really need them in png. Thus, this is my journey in further extracting the icon files!

The Extracted Icons

If you are here looking just for the icons, I have uploaded them all to GitHub. You can also find the original files in the repository. Definitely feel free to download them if you want to poke around.

Macintosh Resource Files (rsrc)

The Apple icon image (icns) files that I am looking for are not within the resource files, but rather stored in the resource forks of the rsrc file. Resource forks were important in the classic Mac OS as they provided a standard way to store structured file data, metadata and application resources. This is equivalent to the concept of alternate data stream (ADS) in Windows OS. (It is commonly said that ADS was added as a feature to Windows to add support for Mac file system.2)

From the Get Info window of a rsrc file, we see that its file size is 122,235 bytes. However, if we create a hexdump of the file with xxd, we see that the file is empty. When I tried to upload the rsrc files to GitHub using the web interface, GitHub returns an empty file error.

> xxd 1.rsrc
>

The forks and their sizes can be listed with ls command with flag [email protected]. We can see that while the file 1.rsrc itself is 0 bytes, the ResourceFork is 122235 bytes.

> ls [email protected] 1.rsrc
[email protected] 1 user  staff  0 17 Aug  2008 1.rsrc
	com.apple.FinderInfo	32
	com.apple.ResourceFork	122235
	com.apple.lastuseddate#PS	16
	com.apple.macl	72
	com.apple.quarantine	57

The binary data at the resource fork can be accessed as 1.rsrc/..namedfork/rsrc, and therefore we can use cp to extract the resource fork data:

cp 1.rsrc/..namedfork/rsrc 1.icns

Apple Icon Image (icns)

The extracted binary files appear corrupted, and opening the files in xxd reveals a lot of leading zeroes in the files.

00000000: 0000 0100 0001 dd49 0001 dc49 0000 0032  .......I...I...2
00000010: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000020: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000030: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000040: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000050: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000060: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000070: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000080: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000090: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000f0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000100: 0001 dc45 6963 6e73 0001 dc45 6973 3332  ...Eicns...Eis32
...

icns files have a magic literal of icns, and we see 69 63 6e 73 at an offset of 260 bytes into the extracted icns files. We can use dd to extract the relevant segment. The entire Bash code to extract the icns files from the rsrc files is then:

for filename in *.rsrc; do
    cp $filename/..namedfork/rsrc $filename.icns
    dd if=$filename.icns of=$filename.offset.icns bs=260 skip=1
done

When this is done, we see that MacOS renders the icons correctly, even when Preview app doesn’t open it. Preview also doesn’t open a lot of other icns files that I have downloaded, so I’m not sure if the latest MacOS release has broken certain features. Apple isn’t well known for backwards compatibility after all.

From the hexdump above, we see the 8 byte header of an icns file.

OffsetSizeData
040x69, 0x63, 0x6e, 0x73 (icns)
44Length of file in bytes
Header of icns file

Next, the file contains any number of icons in the following format:

OffsetSizeData
04Icon OSType
44Length of icon data in bytes
8~Icon data
For each additional icon data in the icns file

Examining the icns file and comparing it to the full list on Wikipedia3, we recognise the following icon types:

OSTypeSize
is3216x16px 24-bit icon
s8mk16x16px 8-bit mask
il3232x32px 24-bit icon
l8mk32×32px 8-bit mask
ic08256×256px JPEG 2000 / PNG
ic09512x512px JPEG 2000 / PNG
Icon types found in the icns files

Conversion to png files

Had the icns files been valid, we would be able to convert the icns files to png straightaway with the following code in the Bash loop:

sips -s format png $filename.offset.icns --out $filename.png

Instead of drilling into the icon binary and trying to fix the file itself, I decided to take the easy way out and look for online file converters. Lots of these services similarly complain of invalid file, but eventually, I came across CoolUtils4 that does the job.

Remaking the icns

With the png files, we can use Apple’s iconutil to make valid icns files. The tool takes in an iconset, which is a folder containing png files of various dimensions, and convert it to an icns file.

The following Bash code does the trick:

for filename in *.png; do
    mkdir $filename.iconset
    mv $filename $filename.iconset/icon_512x512.png
    iconutil -c icns $filename.iconset
done

We now have valid icns files that the Preview app is happy to open!

Closing Remarks

I found a Python cross-platform library called rsrcfork5 that extracts MacOS resource forks. Its role is not important here as the same job can be done within Terminal, but it will be very useful when repeating the job on a Windows machine.

If you find these icons useful, be sure to tell me how you plan to use them!

References

  1. https://www.deviantart.com/nazoraioiskadinaujo/art/Mac-OS-9-icons-for-OSX-95225656
  2. https://www.bleepingcomputer.com/tutorials/windows-alternate-data-streams/
  3. https://en.wikipedia.org/wiki/Apple_Icon_Image_format
  4. https://www.coolutils.com/online/ICNS-to-PNG
  5. https://pypi.org/project/rsrcfork/

Leave a Reply

Your email address will not be published. Required fields are marked *