diff --git a/src/osgPlugins/quicktime/QTtexture.cpp b/src/osgPlugins/quicktime/QTtexture.cpp index a14e808e1..09b132ea0 100644 --- a/src/osgPlugins/quicktime/QTtexture.cpp +++ b/src/osgPlugins/quicktime/QTtexture.cpp @@ -11,48 +11,48 @@ /* PORTIONS OF THIS CODE ARE COPYRIGHT APPLE COMPUTER - - Copyright: Copyright © 2001 Apple Computer, Inc., All Rights Reserved + Copyright: Copyright © 2001 Apple Computer, Inc., All Rights Reserved - Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. - ("Apple") in consideration of your agreement to the following terms, and your - use, installation, modification or redistribution of this Apple software - constitutes acceptance of these terms. If you do not agree with these terms, - please do not use, install, modify or redistribute this Apple software. + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. - In consideration of your agreement to abide by the following terms, and subject - to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs - copyrights in this original Apple software (the "Apple Software"), to use, - reproduce, modify and redistribute the Apple Software, with or without - modifications, in source and/or binary forms; provided that if you redistribute - the Apple Software in its entirety and without modifications, you must retain - this notice and the following text and disclaimers in all such redistributions of - the Apple Software. Neither the name, trademarks, service marks or logos of - Apple Computer, Inc. may be used to endorse or promote products derived from the - Apple Software without specific prior written permission from Apple. Except as - expressly stated in this notice, no other rights or licenses, express or implied, - are granted by Apple herein, including but not limited to any patent rights that - may be infringed by your derivative works or by other works in which the Apple - Software may be incorporated. + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs + copyrights in this original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks or logos of + Apple Computer, Inc. may be used to endorse or promote products derived from the + Apple Software without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any patent rights that + may be infringed by your derivative works or by other works in which the Apple + Software may be incorporated. - The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO - WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED - WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN - COMBINATION WITH YOUR PRODUCTS. + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. - IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION - OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT - (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include - + #include // for image loading and decompression #include // for file type support @@ -109,11 +109,11 @@ static unsigned char * LoadBufferFromImageFile (FSSpec fsspecImage, short imageS static long GetScaledTextureDimFromImageDim (long imageDimension, short scaling) { switch (scaling) - { - case kNone: // no scaling + { + case kNone: // no scaling return imageDimension; break; - case kNearest: // scale to nearest power of two + case kNearest: // scale to nearest power of two { // find power of 2 greater long i = 0, texDim = 1, imageTemp = imageDimension; @@ -130,7 +130,7 @@ static long GetScaledTextureDimFromImageDim (long imageDimension, short scaling) return texDim; // otherwise orginal guess is closer so return this } break; - case kNearestLess: + case kNearestLess: { // find power of 2 lower long i = 0, texDim = 1; @@ -140,9 +140,9 @@ static long GetScaledTextureDimFromImageDim (long imageDimension, short scaling) return texDim; // returns the maxium power of two that is less than or equal the texture dimension } break; - case KNearestGreater: + case KNearestGreater: { - // find power of 2 greater + // find power of 2 greater long i = 0, texDim = 1; while (imageDimension >>= 1) // while the dimension still has bits of data shift right (losing a bit at a time) i++; // count shifts (i.e., powers of two) @@ -150,35 +150,35 @@ static long GetScaledTextureDimFromImageDim (long imageDimension, short scaling) return texDim; // returns the minimum power of two that is greater than or equal the texture dimension } break; - case k32: // return hard values for texture dimension + case k32: // return hard values for texture dimension return 32; break; - case k64: - return 64; - break; - case k128: - return 128; - break; - case k256: - return 256; - break; - case k512: - return 512; - break; - case k1024: - return 1024; - break; - case k2048: - return 2048; - break; - case k4096: - return 8192; - break; - case k8192: - return 8192; - break; - } - return 0; + case k64: + return 64; + break; + case k128: + return 128; + break; + case k256: + return 256; + break; + case k512: + return 512; + break; + case k1024: + return 1024; + break; + case k2048: + return 2048; + break; + case k4096: + return 8192; + break; + case k8192: + return 8192; + break; + } + return 0; } static char errMess[256]; @@ -188,62 +188,69 @@ char *QTfailureMessage(void) { return errMess; } static unsigned char * LoadBufferFromImageFile ( FSSpec fsspecImage, short imageScale, long *pOrigImageWidth, long *pOrigImageHeight, long *pOrigImageDepth, - long *pBufferWidth, long *pBufferHeight, long *pBufferDepth) + long *pBufferWidth, long *pBufferHeight, long *pBufferDepth) { - unsigned char * pImageBuffer = NULL; + unsigned char * pImageBuffer = NULL; int scalefac; - GWorldPtr pGWorld = NULL; - OSType pixelFormat; - long rowStride; // length, in bytes, of a pixel row in the image - GraphicsImportComponent giComp; // componenet for importing image - Rect rectImage; // rectangle of source image + GWorldPtr pGWorld = NULL; + OSType pixelFormat; + long rowStride; // length, in bytes, of a pixel row in the image + GraphicsImportComponent giComp; // componenet for importing image + Rect rectImage; // rectangle of source image ImageDescriptionHandle hImageDesc; // handle to image description used to get image depth MatrixRecord matrix; - GDHandle origDevice; // save field for current graphics device - CGrafPtr origPort; // save field for current graphics port - OSStatus err = noErr; // err return value - - // zero output params - *pOrigImageWidth = 0; - *pOrigImageHeight = 0; - *pOrigImageDepth = 0; - *pBufferWidth = 0; - *pBufferHeight = 0; - *pBufferDepth = 0; - - // get imorter for the image tyoe in file - GetGraphicsImporterForFile (&fsspecImage, &giComp); - if (err != noErr) { // if we have an error - sprintf ( errMess, "couldnt find importer\n"); - return NULL; // go away - } + GDHandle origDevice; // save field for current graphics device + CGrafPtr origPort; // save field for current graphics port + OSStatus err = noErr; // err return value - // Create GWorld + // zero output params + *pOrigImageWidth = 0; + *pOrigImageHeight = 0; + *pOrigImageDepth = 0; + *pBufferWidth = 0; + *pBufferHeight = 0; + *pBufferDepth = 0; + + // get imorter for the image tyoe in file + GetGraphicsImporterForFile (&fsspecImage, &giComp); + if (err != noErr) { // if we have an error + sprintf ( errMess, "couldnt find importer\n"); + return NULL; // go away + } + + // Create GWorld err = GraphicsImportGetNaturalBounds (giComp, &rectImage); // get the image bounds if (err != noErr) { - sprintf ( errMess, "failed to GraphicsImportGetNaturalBounds"); + sprintf ( errMess, "failed to GraphicsImportGetNaturalBounds"); return NULL; // go away if error - } - // create a handle for the image description + } + // create a handle for the image description hImageDesc = (ImageDescriptionHandle) NewHandle (sizeof (ImageDescriptionHandle)); HLock ((Handle) hImageDesc); // lock said handle err = GraphicsImportGetImageDescription (giComp, &hImageDesc); // retrieve the image description if (err != noErr) { - sprintf ( errMess, "failed to GraphicsImportGetImageDescription"); + sprintf ( errMess, "failed to GraphicsImportGetImageDescription"); return NULL; // go away if error - } + } *pOrigImageWidth = (long) (rectImage.right - rectImage.left); // find width from right side - left side bounds *pOrigImageHeight = (long) (rectImage.bottom - rectImage.top); // same for height - - // we will use a 24-bit rgb texture or a 32-bit rgba - if ((**hImageDesc).depth == 32) *pOrigImageDepth=4; - else *pOrigImageDepth=3; - + + // we will use a 24-bit rgb texture or a 32-bit rgba + if ((**hImageDesc).depth == 32) *pOrigImageDepth=4; + else *pOrigImageDepth=3; + *pBufferDepth = 32; // we will use a 32 bbit texture (this includes 24 bit images) pixelFormat = k32ARGBPixelFormat; - + +#define NO_SCALING +#ifdef NO_SCALING + // NOTE: scaling of the image removed, this is already done inside osg::Image + + *pBufferWidth = *pOrigImageWidth; + *pBufferHeight= *pOrigImageHeight; +#else // note - we want texels to stay square, so if ((*pOrigImageWidth) > (*pOrigImageHeight)) { *pBufferWidth = GetScaledTextureDimFromImageDim ( *pOrigImageWidth, imageScale ) ; @@ -255,71 +262,83 @@ static unsigned char * LoadBufferFromImageFile ( FSSpec fsspecImage, *pBufferWidth = *pBufferHeight; scalefac = X2Fix ((float) (*pBufferHeight) / (float) *pOrigImageHeight); } - SetRect (&rectImage, 0, 0, (short) *pBufferWidth, (short) *pBufferHeight); // l, t, r. b set image rectangle for creation of GWorld - rowStride = *pBufferWidth * *pBufferDepth >> 3; // set stride in bytes width of image * pixel depth in bytes +#endif + SetRect (&rectImage, 0, 0, (short) *pBufferWidth, (short) *pBufferHeight); // l, t, r. b set image rectangle for creation of GWorld + rowStride = *pBufferWidth * *pBufferDepth >> 3; // set stride in bytes width of image * pixel depth in bytes - const long len = rowStride * *pBufferHeight; + const long len = rowStride * *pBufferHeight; - pImageBuffer = new unsigned char [ len ]; // build new buffer exact size of image (stride * height) + pImageBuffer = new unsigned char [ len ]; // build new buffer exact size of image (stride * height) - // pImageBuffer = (unsigned char *) NewPtrClear (rowStride * *pBufferHeight); // build new buffer exact size of image (stride * height) + // pImageBuffer = (unsigned char *) NewPtrClear (rowStride * *pBufferHeight); // build new buffer exact size of image (stride * height) - if (NULL == pImageBuffer) - { - sprintf ( errMess, "failed to allocate image buffer"); - CloseComponent(giComp); // dump component - return NULL; // if we failed to allocate buffer + if (NULL == pImageBuffer) + { + sprintf ( errMess, "failed to allocate image buffer"); + CloseComponent(giComp); // dump component + return NULL; // if we failed to allocate buffer } - // create a new gworld using our unpadded buffer, ensure we set the pixel type correctly for the expected image bpp - QTNewGWorldFromPtr (&pGWorld, pixelFormat, &rectImage, NULL, NULL, 0, pImageBuffer, rowStride); - if (NULL == pGWorld) - { - sprintf ( errMess, "failed to create GWorld"); - // DisposePtr ((Ptr) pImageBuffer); // dump image buffer - delete [] pImageBuffer; - pImageBuffer = NULL; - CloseComponent(giComp); - return NULL; // if we failed to create gworld - } + // create a new gworld using our unpadded buffer, ensure we set the pixel type correctly for the expected image bpp + QTNewGWorldFromPtr (&pGWorld, pixelFormat, &rectImage, NULL, NULL, 0, pImageBuffer, rowStride); + if (NULL == pGWorld) + { + sprintf ( errMess, "failed to create GWorld"); + // DisposePtr ((Ptr) pImageBuffer); // dump image buffer + delete [] pImageBuffer; + pImageBuffer = NULL; + CloseComponent(giComp); + return NULL; // if we failed to create gworld + } - GetGWorld (&origPort, &origDevice); // save onscreen graphics port - // decompress (draw) to gworld and thus fill buffer - SetIdentityMatrix (&matrix); // set transform matrix to identity (basically pass thorugh) + GetGWorld (&origPort, &origDevice); // save onscreen graphics port - - TranslateMatrix ( &matrix, -X2Fix(0.5f * *pOrigImageWidth), -X2Fix(0.5f * *pOrigImageHeight)); - ScaleMatrix (&matrix, X2Fix(1.0), X2Fix(-1.0), X2Fix (0.0), X2Fix (0.0)); - TranslateMatrix ( &matrix, X2Fix(0.5f * *pOrigImageWidth), X2Fix(0.5f * *pOrigImageHeight)); - - err = GraphicsImportSetMatrix(giComp, &matrix); // set our matrix as the importer matrix - if (err == noErr) - err = GraphicsImportSetGWorld (giComp, pGWorld, NULL); // set the destination of the importer component - if (err == noErr) - err = GraphicsImportSetQuality (giComp, codecLosslessQuality); // we want lossless decompression - if ((err == noErr) && GetGWorldPixMap (pGWorld) && LockPixels (GetGWorldPixMap (pGWorld))) - GraphicsImportDraw (giComp); // if everything looks good draw image to locked pixmap - else - { - sprintf ( errMess, "failed to Set Matrix or GWorld or Quality or GetPixMap"); + // decompress (draw) to gworld and thus fill buffer +#ifdef NO_SCALING + SetIdentityMatrix (&matrix); // set transform matrix to identity (basically pass through) + + TranslateMatrix ( &matrix, -X2Fix(0.5f * *pOrigImageWidth), -X2Fix(0.5f * *pOrigImageHeight)); + ScaleMatrix (&matrix, X2Fix(1.0), X2Fix(-1.0), X2Fix (0.0), X2Fix (0.0)); + TranslateMatrix ( &matrix, X2Fix(0.5f * *pOrigImageWidth), X2Fix(0.5f * *pOrigImageHeight)); + + err = GraphicsImportSetMatrix(giComp, &matrix); // set our matrix as the importer matrix +#else + SetIdentityMatrix (&matrix); // set transform matrix to identity (basically pass thorugh) - DisposeGWorld (pGWorld); // dump gworld - pGWorld = NULL; - // DisposePtr ((Ptr) pImageBuffer); // dump image buffer - delete [] pImageBuffer; - pImageBuffer = NULL; - CloseComponent(giComp); // dump component - return NULL; - } - - UnlockPixels (GetGWorldPixMap (pGWorld)); // unlock pixels - CloseComponent(giComp); // dump component - SetGWorld(origPort, origDevice); // set current graphics port to offscreen - // done with gworld and image since they are loaded to a texture - // DisposeGWorld (pGWorld); // do not need gworld - // pGWorld = NULL; - - return pImageBuffer; + + TranslateMatrix ( &matrix, -X2Fix(0.5f * *pOrigImageWidth), -X2Fix(0.5f * *pOrigImageHeight)); + ScaleMatrix (&matrix, X2Fix(1.0), X2Fix(-1.0), X2Fix (0.0), X2Fix (0.0)); + TranslateMatrix ( &matrix, X2Fix(0.5f * *pOrigImageWidth), X2Fix(0.5f * *pOrigImageHeight)); + + err = GraphicsImportSetMatrix(giComp, &matrix); // set our matrix as the importer matrix +#endif + if (err == noErr) + err = GraphicsImportSetGWorld (giComp, pGWorld, NULL); // set the destination of the importer component + if (err == noErr) + err = GraphicsImportSetQuality (giComp, codecLosslessQuality); // we want lossless decompression + if ((err == noErr) && GetGWorldPixMap (pGWorld) && LockPixels (GetGWorldPixMap (pGWorld))) + GraphicsImportDraw (giComp); // if everything looks good draw image to locked pixmap + else + { + sprintf ( errMess, "failed to Set Matrix or GWorld or Quality or GetPixMap"); + + DisposeGWorld (pGWorld); // dump gworld + pGWorld = NULL; + // DisposePtr ((Ptr) pImageBuffer); // dump image buffer + delete [] pImageBuffer; + pImageBuffer = NULL; + CloseComponent(giComp); // dump component + return NULL; + } + + UnlockPixels (GetGWorldPixMap (pGWorld)); // unlock pixels + CloseComponent(giComp); // dump component + SetGWorld(origPort, origDevice); // set current graphics port to offscreen + // done with gworld and image since they are loaded to a texture + // DisposeGWorld (pGWorld); // do not need gworld + // pGWorld = NULL; + + return pImageBuffer; } // new implementation of darwinPathToFSSpec @@ -330,39 +349,39 @@ static unsigned char * LoadBufferFromImageFile ( FSSpec fsspecImage, FSSpec *darwinPathToFSSpec (char *fname ) { - FSSpec *fs; - OSStatus result; - FSRef ref; - - /* convert the POSIX path to an FSRef */ - result = FSPathMakeRef(fname, &ref, false); // fname is not a directory + FSSpec *fs; + OSStatus result; + FSRef ref; + + /* convert the POSIX path to an FSRef */ + result = FSPathMakeRef(fname, &ref, false); // fname is not a directory - if (result!=0) return NULL; - - /* and then convert the FSRef to an FSSpec */ + if (result!=0) return NULL; + + /* and then convert the FSRef to an FSSpec */ fs = (FSSpec *) malloc(sizeof(FSSpec)); - result = FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL, fs, NULL); - if (result==0) return fs; // success + result = FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL, fs, NULL); + if (result==0) return fs; // success - // failed: - free(fs); - return NULL; + // failed: + free(fs); + return NULL; } unsigned char* LoadBufferFromDarwinPath ( const char *fname, long *origWidth, long *origHeight, long *origDepth, - long *buffWidth, long *buffHeight, - long *buffDepth) + long *buffWidth, long *buffHeight, + long *buffDepth) { - FSSpec *fs; - sprintf ( errMess, "" ); - - fs=darwinPathToFSSpec ( const_cast( fname ) ); - - if (fs == NULL) { - return NULL; - } - else - return LoadBufferFromImageFile ( *fs, kNone, origWidth,origHeight,origDepth,buffWidth,buffHeight,buffDepth); + FSSpec *fs; + sprintf ( errMess, "" ); + + fs=darwinPathToFSSpec ( const_cast( fname ) ); + + if (fs == NULL) { + return NULL; + } + else + return LoadBufferFromImageFile ( *fs, kNone, origWidth,origHeight,origDepth,buffWidth,buffHeight,buffDepth); }