Well, the situation generally is pretty awful.
As it turns out, the PNG file format specification dictates that color should not be premultiplied (also known as "unassociated alpha"), and the OpenEXR specification is pretty clear that color should always be premultipled (also known as "associated alpha"). Some other file formats allow either choice, for example TIFF has a metadata field that's supposed to say if the "extra" channel (beyond RGB) is supposed to be associated alpha, unassociated alpha, or neither/don't know.
Short answer:
By default, OIIO's texture system will automatically premultiply upon input, for image files that appear to be unassociated, so from OSL's point of view, you should treat all texture inputs as premultiplied.
There is an option (as discussed earlier in this thread) when the renderer to initialize the texture system that will turn off this behavior, i.e., to leave unpremultiplied colors as they were in the file. If you do that, then, the shader itself needs to do the premultiplication to use it as ordinary texture (though. You can probably *mostly* tell by looking for file metadata "oiio:UnassociatedAlpha" is present and nonzero. So you could imagine shader code that looks like this ugly mess:
color Ctex;
float Atex;
Ctex = texture (filename, s, t, "alpha", Atex, "fill", 1.0);
int unassociated = 0;
gettextureinfo (filename, "oiio:UnassociatedAlpha", unassociated);
if (unassociated)
Ctex *= Atex;
The good news is that the gettextureinfo will probably constant-fold away, and so will the multiply if it's not an unassociated file, that is, if the runtime optimizer can determine the name of the file used by the shader when it's being JITed, so this is not nearly as expensive at runtime as it appears. The bad news, though, is that it's not 100% clear to me that the results of texture-filtering-then-premultiplying are correct compared to premultply-then-filter. Other bad news is that you are relying on OIIO input reader for that file, which is probably fine for exr or png (where it's supposed to always be one way), but like I said for TIFF also requires trust that it was correct in the metadata in the first place. If the metadata is wrong, you're probably hosed either way.
Long answer, including background info and rant:
At this point, I'm going to go on a bit of a religious rant and just say that associated alpha (premultiplied color) is the only choice that makes sense. It's the only thing that renderers are likely to produce naturally, it's the only way that compositing and any other image processing math works, and in my opinion it's the only sensible form to store any image. It is also worth noting that associated alpha can express RGBA values that unassociated alpha (un-premultipled color) CANNOT. It's just a fact of life; for example, an RGBA pixel that means "glow bright yellow but don't block the view of the things behind it" can only be expressed in premultiplied colors (associated alpha).
Except... except that unassociated alpha (which is equivalent to a solid color and a mask) was a familiar analogy to painters and graphic designers, and saved you some precision problems if you were stuck with 8 bits per channel in the old days (and assuming you didn't need any of those transparent but glowy pixels), and the math didn't seem too bad if you were developing your application prior to publication of Porter & Duff's seminal 1984 paper "Compositing Digital Images" (or indeed after that, if you were somehow unaware of the paper or didn't understand it). So we have a lot of apps (Photoshop, I'm looking at you) and file formats (PNG, etc.) whose architectures are geared toward the inferior way to represent pixels. So the use of unassociated/unpremultiplied files continues in some circles.
OK, rant over. Thanks for sticking with me. Back to the main topic...
So the way that OpenImageIO (which supplies the texture system used by most renderers using OSL, and they heavily influence each other) deals with this is to attempt to determine (through metadata or file type) its best guess on whether an image being read is associated or unassociated alpha, and for the latter will automatically premultiply in order to present the pixels on the app side of the API as if they were premultiplied.
Which means that, I think, in OSL you ought to be able to just carry on as if all colors were premultiplied.
* Best practice, IMHO: Write OSL as if all texture inputs are premultiplied, and let OIIO's texture system do that for you automatically.
But every once in a while, somebody wants the original pixels, in order to ensure that you don't lose color precision in the premultiplication (this is really only important for 8 bit per channel images). There is a way for the renderer to tell the texture system, as described earlier. But as I said, this leaves you with having to deal with both cases in the shader.
I'm open to better suggestions for how to deal with this mess.