Exemplo n.º 1
0
osg::Image* QuicktimeImportExport::doImport(unsigned char* data, unsigned int sizeData, const std::string& fileTypeHint)
{
    GWorldPtr gworld = 0;
    OSType pixelFormat;
    int rowStride;
    GraphicsImportComponent gicomp = 0;
    Rect rectImage;
    GDHandle origDevice = 0;
    CGrafPtr origPort = 0;
    ImageDescriptionHandle desc = 0;
    int depth = 32;
    unsigned int xsize, ysize;
    unsigned char* imageData = 0;
    
    // Data Handle for file data ( & load data from file )
    Handle dataRef = getPtrDataRef(data, sizeData, fileTypeHint);
    
    try {
        OSErr err = noErr;
        
        // GraphicsImporter - Get Importer for our filetype
        GetGraphicsImporterForDataRef(dataRef, 'ptr ', &gicomp);

        // GWorld - Get Texture Info
        err = GraphicsImportGetNaturalBounds(gicomp, &rectImage);
        if (err != noErr) {
            throw QTImportExportException(err, "GraphicsImportGetNaturalBounds failed");
            
        }
        xsize = (unsigned int)(rectImage.right - rectImage.left);
        ysize = (unsigned int)(rectImage.bottom - rectImage.top);

        // ImageDescription - Get Image Description
        err = GraphicsImportGetImageDescription(gicomp, &desc);
        if (err != noErr) {
            throw QTImportExportException(err, "GraphicsImportGetImageDescription failed");
        }

        // ImageDescription - Get Bit Depth
        HLock(reinterpret_cast<char **>(desc));
        

        // GWorld - Pixel Format stuff
        pixelFormat = k32ARGBPixelFormat; // Make sure its forced...NOTE: i'm pretty sure this cannot be RGBA!

        // GWorld - Row stride
        rowStride = xsize * 4; // (width * depth_bpp / 8)

        // GWorld - Allocate output buffer
        imageData = new unsigned char[rowStride * ysize];

        // GWorld - Actually Create IT!
        QTNewGWorldFromPtr(&gworld, pixelFormat, &rectImage, 0, 0, 0, imageData, rowStride);
        if (!gworld) {
            throw QTImportExportException(-1, "QTNewGWorldFromPtr failed");
        }

        // Save old Graphics Device and Graphics Port to reset to later
        GetGWorld (&origPort, &origDevice);

        // GraphicsImporter - Set Destination GWorld (our buffer)
        err = GraphicsImportSetGWorld(gicomp, gworld, 0);
        if (err != noErr) {
            throw QTImportExportException(err, "GraphicsImportSetGWorld failed");
        }

        // GraphicsImporter - Set Quality Level
        err = GraphicsImportSetQuality(gicomp, codecLosslessQuality);
        if (err != noErr) {
            throw QTImportExportException(err, "GraphicsImportSetQuality failed");
        }

        // Lock pixels so that we can draw to our memory texture
        if (!GetGWorldPixMap(gworld) || !LockPixels(GetGWorldPixMap(gworld))) {
            throw QTImportExportException(0, "GetGWorldPixMap failed");
        }
        
           
        //*** Draw GWorld into our Memory Texture!
        GraphicsImportDraw(gicomp);
 
        // Clean up
        UnlockPixels(GetGWorldPixMap(gworld));
        SetGWorld(origPort, origDevice); // set graphics port to offscreen (we don't need it now)
        DisposeGWorld(gworld);
        CloseComponent(gicomp);
        DisposeHandle(reinterpret_cast<char **>(desc));
        DisposeHandle(dataRef);
    } 
    catch (QTImportExportException& e) 
    {
        setError(e.what());
        
        if (gworld) {
            UnlockPixels(GetGWorldPixMap(gworld));
            SetGWorld(origPort, origDevice); // set graphics port to offscreen (we don't need it now)
            DisposeGWorld(gworld);
        }
        if (gicomp)
            CloseComponent(gicomp);
        if (desc) 
            DisposeHandle(reinterpret_cast<char **>(desc));
        
        if (imageData) 
            delete[] imageData;
        if (dataRef)
            DisposeHandle(dataRef);
            
        return NULL;
    }
    

    
    unsigned int bytesPerPixel = depth / 8;
    unsigned int glpixelFormat;
    switch(bytesPerPixel) {
        case 3 :
            glpixelFormat = GL_RGB;
            break;
        case 4 :
            glpixelFormat = GL_RGBA;
            break;
        default :
            delete[] imageData;
            setError("unknown pixelformat");
            return NULL;
            break;
    }
    
    unsigned char* swizzled = pepareBufferForOSG(imageData, bytesPerPixel, xsize, ysize);
    
    delete[] imageData;
 
    osg::Image* image = new osg::Image();
    image->setFileName(fileTypeHint.c_str());
    image->setImage(xsize,ysize,1,
        bytesPerPixel,
        glpixelFormat,
        GL_UNSIGNED_BYTE,
        swizzled,
        osg::Image::USE_NEW_DELETE );
    
 
    return image;
}
Exemplo n.º 2
0
bool LoadTexture(IplTexture *tex, const char *filename, const char *subdir)
{
    ComponentInstance fileImporter;
    OSErr error;
    ImageDescriptionHandle imageInfo;
    ComponentResult err;


    CFStringRef name = CFStringCreateWithCStringNoCopy(NULL, filename, kCFStringEncodingASCII, NULL);
    CFStringRef _subdir = CFStringCreateWithCStringNoCopy(NULL, subdir, kCFStringEncodingASCII, NULL);

    CFURLRef texture_url = CFBundleCopyResourceURL(
                               CFBundleGetMainBundle(),
                               name,
                               NULL,
                               _subdir);

    // Create the data reference so we can get the file's graphics importer.
    Handle dataRef;
    OSType dataRefType;

    dataRef = NewHandle(sizeof(AliasHandle));

    // The second parameter to QTNewDataReferenceFromCFURL is flags.
    // It should be set to 0.
    error = QTNewDataReferenceFromCFURL(texture_url, 0, &dataRef, &dataRefType);
    if(error != noErr) {
        //DisposeHandle(dataRef);
        //CFRelease(texture_url);
        return false;
    }

    // Get the importer for the file so we can read the information.
    error = GetGraphicsImporterForDataRef(dataRef, dataRefType, &fileImporter);

    // Retrieve information about the image
    imageInfo = (ImageDescriptionHandle)NewHandle(sizeof(ImageDescription));
    err = GraphicsImportGetImageDescription(fileImporter, &imageInfo);
    unsigned width = ((**imageInfo).width);
    unsigned height = ((**imageInfo).height);

    IplImage *im = tex->getIm();
    if (im && (im->width != width || im->height!=height))
        cvReleaseImage(&im);
    if (im==0) {
        im = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U, 4);
        //memset(im->imageData, 0x8f, 30*im->widthStep );
        //memset(im->imageData+ 50*im->widthStep, 0xff, 30*im->widthStep);
        tex->setImage(im);
        //return true;
    }
    tex->update();

    void *imageData = im->imageData;

    // Get the boundary rectangle of the image
    Rect imageRect;
    err = GraphicsImportGetNaturalBounds(fileImporter, &imageRect);

    // Create an offscreen buffer to hold the image.
    // Apparently QuickTime requires a GWorld to
    // decompress a texture file.
    long bytesPerRow = im->widthStep;
    //static
    GWorldPtr offscreenBuffer=0;

    if (offscreenBuffer==0) {
        error = QTNewGWorldFromPtr(&offscreenBuffer, k32RGBAPixelFormat, &imageRect,
                                   NULL, NULL, kNativeEndianPixMap, imageData, bytesPerRow);
        assert(error == noErr);
    }

    // Draw the image into the offscreen buffer
    err = GraphicsImportSetGWorld(fileImporter, offscreenBuffer, NULL);
    assert(err == noErr);
    err = GraphicsImportDraw(fileImporter);
    assert(err == noErr);

    // Cleanup
    error = CloseComponent(fileImporter);
    DisposeHandle((Handle)imageInfo);
    DisposeHandle(dataRef);
    DisposeGWorld(offscreenBuffer);
    return true;
}