Monthly Archives: August 2005

Report-an-Apple-Bug Friday for August 26, 2005

It’s the favorite day of the week for Apple developers worldwide!

We have reports from Brent Simmons and renowned drunkenbatman (and he’s got a pretty good one too). More bugs from Chris Woods, Mike Zornek. I’ll try to add more links to this entry as bugs are posted, but it’s a bit hard to track them at the moment (someone should make a website to track those).

In any case, I was supposed to write about a QTKit bug or limitation having to do with opening movies embedded inside files at a particular known offset. After several hours of work, I can say with relative confidence that QuickTime is one awesomely weird piece of technology. For reasons that are beyond my understanding, trying to open a perfectly valid movie file using a data fork reference number and NewMovieFromProperties fails with a movie not found error (-2048). Creating a movie for the same file using a POSIX path or a CFURL works perfectly fine. Of course, since QTKit doesn’t expose functionality equivalent to kQTDataLocationPropertyID_DataFork, there is no such equivalent problem in QTKit.

Which brings me to the code I posted in On Report-an-Apple-Bug Fridays and to my current state of confusion. The snippet I posted is part of MHKKit, a Foundation-based framework I am currently developing as part of the Riven X project, a Mac OS X native re-implementation of the popular game by Cyan Worlds. Riven data files contain several embedded QuickTime movies, and the only API that properly opens them is NewMovieFromProperties with kQTDataLocationPropertyID_DataFork and kQTMovieResourceLocatorPropertyID_FileOffset (which, incidentally, only works with kQTDataLocationPropertyID_DataFork). Pretty cute, isn’t it? But I get the message Apple, I won’t try to see logic in QuickTime anymore. I promise.

I still have a bug to post

But I still have a bug to post, although I’m almost certain it will finish as a duplicate because it’s such an obvious one. It involves the Dock and Uniform Type Identifiers. The theory is that UTIs are as of Tiger the primary way to determine the type of a items on the system, be them files, filesystem objects or more abstract entities like contacts or calendar events. Everything else (OSTypes, extensions and MIME types) maps back to a UTI. Therefore, if one is write a Tiger-only application, one should normally use UTIs for purposes of file type identification. If you’re not familiar with UTIs, I encourage you to read the link above which explains in good details what they are about. The executive summary is that they are a most worthy successor to every other type identification mechanism we’ve had so far.

One area in particular where UTIs should be used is in the Info.plist file that can be found in every bundle when it’s time to declare the types of documents or entities a particular application supports. This is the well-known CFBundleDocumentTypes key in plists. Instead of using CFBundleTypeExtensions or CFBundleTypeOSTypes, one should use LSItemContentTypes, which is specified as an array of UTIs corresponding to the document type entry it belongs to(CFBundleDocumentTypes is an array itself). Unfortunately, this isn’t quite usable yet because the Dock doesn’t perform conformance tests properly.

If you read the documentation about UTIs, you know they are organized in hierarchies. This implies some form of relationships between UTIs, which is called conformance. A UTI conforms to another UTI if it expresses a refinement of the conformed to type. A very simple example of conformance is with JPEG images. It’s readily apparent that a JPEG image is generally speaking an image, and thus the public.jpeg UTI conforms to the public.image UTI.

Conformance is really important and amazing because for example an image editing application doesn’t need to declare a document type for every known image format – all it needs to do is declare one document type with the UTI public.image and suddenly the system knows that particular application can open any image file.

We call a conformance test the process of computing whether a particular UTI conforms to another given UTI. For instance, a conformance test of public.jpeg and public.image would indicate public.jpegconforms to public.image. Similarly, a conformance test of public.mp3 and public.image would fail.

You can now most likely understand the bug when I say that the Dock doesn’t perform conformance tests properly. What happens is that if your application declares a document type with a UTI, say public.jpeg, the Dock will accept a file drop on that application’s icon only if the UTI of the file being dropped is exactly public.jpeg. If your document type uses public.image, the Dock will refuse the file drop. On the other hand, this works perfectly fine in the Finder.

Radar bug #4234661.

Of MPQs and Kits

The MPQKit project page is now online. This is my Foundation-based framework for editing Blizzard MoPaQ archives and is quite possibly one of my oldest projects that has survived the tides of time. There isn’t much content on it yet in a similar fashion to that of DropMPQ, but at least the generated documentation and the framework itself are available at last.

This will be my modus operandi for the rest of the project pages I suspect. As I wrote previously, my first priority is to get those online as quickly as possible with enough information to tell readers what the project is and where they can grab it.

So check it out at http://www.devklog.net/mpqkit.

And the first project page was

I have finally published my first project page. DropMPQ is a small application whose sole purpose is to pack folders into MoPaQ archives, the data storage brainchild of famous Blizzard Entertainment Inc. I’m not entirely sure why I picked that particular program to serve as my guinea pig for layout experimentation, but there you have it.

Barring some overwhelming negative feedback, this layout will pretty much be my template for all my project pages. This is an important step in my world domination plan going public plan, because I now have a stable foundation upon which I can build a public presence for all my programs which have remained mostly in the dark up until now.

I will be focussing on the most important ones next, with means MPQKit, MHKKit and MPQDraft.

On Report-an-Apple-Bug Fridays

Brent Simmons writes on inessential about Report-an-Apple-Bug Friday:

If you reported a bug to Apple today—it being Report-an-Apple-Bug Friday—please leave a comment and say what your bug id is. (Oh, and why not say what the bug is too. But we gotta have an id—a bug id is a badge of honor.)

I think weekly bug reports are a pretty good idea and so I will try to follow this new tradition among Mac developers as dutifully as I can. My first one will probably be about either a limitation or a bug in QTKit related to movie creation.

The problem has to do with opening embedded QuickTime movies – that is, opening movies that are somewhere inside another file. This is supported by QuickTime through various means:

  • You can either open the movie using an existing fork, or
  • you can open the movie using a file reference of some sort

In both cases, you specify the offset of the QuickTime movie when the movie is created, which in our case we assume is a known correct value. The best way to open a movie in such a way with QuickTime 7 is by using the new NewMovieFromProperties function. The following code demonstrate how this can be done. It’s an excerpt from MHKKit, a framework project I will soon introduce in more details.

// setup the movie properties
Boolean active = TRUE;
QTVisualContextRef visualContext = NULL;
QTNewMoviePropertyElement newMovieProperties[] = {
{kQTPropertyClass_DataLocation, kQTDataLocationPropertyID_DataFork, sizeof(forkRef), &forkRef, 0},
{kQTPropertyClass_MovieResourceLocator, kQTMovieResourceLocatorPropertyID_FileOffset, sizeof(qt_offset), &qt_offset, 0},
{kQTPropertyClass_Context, kQTContextPropertyID_VisualContext, sizeof(visualContext), &visualContext, 0},
{kQTPropertyClass_NewMovieProperty, kQTNewMoviePropertyID_Active, sizeof(active), &active, 0}
};

// make the movie
Movie aMovie = NULL;
err = NewMovieFromProperties(sizeof(newMovieProperties) / sizeof(newMovieProperties[0]), newMovieProperties, 0, NULL, &aMovie);

In this particular case, I use an existing fork to open the movie, but using a URL or FSRef to the file from which that fork was opened shouldn’t make any difference in theory. That is unfortunately where QTMovie seems to be broken. Attempting to create an instance of that class with - initWithAttributes:error: and the QTMovieFileOffsetAttribute attribute fails, even if the specified file and offset are the same.

I haven’t done any digging in order to figure out exactly what is broken, but I intent to before posting my bug report. Remember kids: detailed bug reports make QA people happy and bug squishing a joy.

The grand opening

Hello and welcome to /dev/klog. It’s been a long road to this moment, but I finally made it. As Brent Dillingham puts it, “CSS is an acquired taste”. Indeed, I’ve lost count of the hours spent carefully crafting the theme and PHP code that underlay this blog, which is rather depressing considering it is, for the most part, the default WordPress 1.5 theme. But like in all things, it’s not worth doing it unless it’s done right.

In any case, having a place to talk about my software projects and other things I find interesting is quite exciting, and I’ll make it a priority to write on a regular basis. The teaser that was online prior to this launch reflects that commitment, as anyone who has read the MYST novels will understand.

For now, I would cordially invite you, dear reader, to read this page about blogging and what /dev/klog will be about, in the hope that you may gain a better understanding of what this will be about and decide whether or not you should subscribe to my feeds.

/dev/klog – You better pipe that through your mind.