void
fgLoadImgAnyFormat(
    const FgString &    fname,
    FgImgRgbaUb &       img)
{
    if (!fgFileReadable(fname))
        fgThrow("Unable to read file",fname);
    fgEnsureMagick();
    FgScopePtr<ExceptionInfo>   exception(AcquireExceptionInfo(),DestroyExceptionInfo);
    FgScopePtr<ImageInfo>       image_info(CloneImageInfo(0),DestroyImageInfo);
    (void) strcpy(image_info->filename,fname.as_utf8_string().c_str());
    // TODO: Do we need to convert into a specific colourspace?
    Image *imgPtr = ReadImage(image_info.get(),exception.get());
    if (imgPtr == 0)
        // exception.description is NULL
        fgThrow("Unable to read image file",fname + ": " + exception->reason);
    FgScopeGuard                sg0(boost::bind(DestroyImage,imgPtr));
    FgScopePtr<CacheView>       view(AcquireCacheView(imgPtr),DestroyCacheView);
    img.resize(uint(imgPtr->columns),uint(imgPtr->rows));
    for(uint row = 0; row < imgPtr->rows; ++row) {
        for(uint column = 0; column < imgPtr->columns; ++column) {
            PixelPacket pixel;
            FGASSERT(MagickTrue == 
                    GetOneCacheViewAuthenticPixel(view.get(),column,row,&pixel,exception.get()));
            img.elem(column,row).red() = uchar(pixel.red);
            img.elem(column,row).green() = uchar(pixel.green);
            img.elem(column,row).blue() = uchar(pixel.blue);
            img.elem(column,row).alpha() =  255 - uchar(pixel.opacity);
        }
    }
}
FgImgRgbaUb
fgOglGetRender()
{
    glReadBuffer(GL_FRONT);
    FgImgRgbaUb     ret;
    GLint           x[4];
    glGetIntegerv(GL_VIEWPORT,x);
    FgVect2UI       dims(x[2],x[3]);
    if (dims.volume() > 0) {
        ret.resize(dims);
        FgRgbaUB *          ptr = ret.dataPtr();
        for (uint yy=0; yy<dims[1]; ++yy) {     // Invert line ordering from OGL:
            glReadPixels(0,dims[1]-1-yy,dims[0],1,GL_RGBA,GL_UNSIGNED_BYTE,ptr);
            ptr += dims[0];
        }
    }
    glReadBuffer(GL_BACK);          // Restore to default
    return ret;
}