void DrawImage( void ) { OSErr err = noErr; Handle hOpenTypeList = NewHandle(0); long numTypes = 0; FSSpec theFSSpec; Rect bounds; GraphicsImportComponent importer = 0; BuildGraphicsImporterValidFileTypes( hOpenTypeList, &numTypes ); HLock( hOpenTypeList ); err = GetOneFileWithPreview(numTypes, (OSTypePtr)*hOpenTypeList, &theFSSpec, NULL); DisposeHandle( hOpenTypeList ); if ( err ) return; // locate and open a graphics importer component which can be used to draw the // selected file. If a suitable importer is not found the ComponentInstance // is set to NULL. err = GetGraphicsImporterForFile( &theFSSpec, // specifies the file to be drawn &importer ); // pointer to the returned GraphicsImporterComponent // get the native size of the image associated with the importer err = GraphicsImportGetNaturalBounds( importer, // importer instance &bounds ); // returned bounds OffsetRect( &bounds, 10, 45 ); window = NewCWindow( NULL, &bounds, "\pDraw Image", true, documentProc, (WindowPtr)-1, true, 0); // set the graphics port for drawing err = GraphicsImportSetGWorld( importer, // importer instance GetWindowPort( window ), // destination graphics port or GWorld NULL ); // destination GDevice, set to NULL uses GWorlds device // draw the image err = GraphicsImportDraw( importer ); // close the importer instance CloseComponent( importer ); }
GLuint texture_load(const char *filename) { FSSpec fss; ComponentInstance gi; Rect rect; GWorldPtr world; int width; int height; int pitch; unsigned char *buffer; GLuint id; NativePathNameToFSSpec(filename, &fss); GetGraphicsImporterForFile(&fss, &gi); GraphicsImportGetNaturalBounds(gi, &rect); width = rect.right; height = rect.bottom; pitch = width * 4; buffer = malloc(pitch * height); QTNewGWorldFromPtr(&world, k32ARGBPixelFormat, &rect, NULL, NULL, 0, buffer, pitch); GraphicsImportSetGWorld(gi, world, NULL); GraphicsImportDraw(gi); DisposeGWorld(world); CloseComponent(gi); id = texture_load_data(buffer, width, height, 4, -pitch, GL_RGBA, ARGB_FORMAT, ARGB_TYPE); free(buffer); return id; }
// I let Quicktime handle image import since it supports most popular // image formats such as: // *.psd, *.bmp, *.tif, *.png, *.jpg, *.gif, *.pct, *.pcx //------------------------------------------------------------------------ bool pixel_map::load_from_qt(const char *filename) { FSSpec fss; OSErr err; // get file specification to application directory err = HGetVol(nil, &fss.vRefNum, &fss.parID); if (err == noErr) { CopyCStringToPascal(filename, fss.name); GraphicsImportComponent gi; err = GetGraphicsImporterForFile (&fss, &gi); if (err == noErr) { ImageDescriptionHandle desc; GraphicsImportGetImageDescription(gi, &desc); // For simplicity, all images are currently converted to 32 bit. // create an empty pixelmap short depth = 32; create ((**desc).width, (**desc).height, (org_e)depth, 0xff); DisposeHandle ((Handle)desc); // let Quicktime draw to pixelmap GraphicsImportSetGWorld(gi, m_pmap, nil); GraphicsImportDraw(gi); // Well, this is a hack. The graphics importer sets the alpha channel of the pixelmap to 0x00 // for imported images without alpha channel but this would cause agg to draw an invisible image. // set alpha channel to 0xff unsigned char * buf = m_buf; for (unsigned int size = 0; size < m_img_size; size += 4) { *buf = 0xff; buf += 4; } } } return err == noErr; }
/* DoFileOpen */ BOOL DoFileOpen(char* fullPathName) { HANDLE hInfo; PINFO pInfo; MDICREATESTRUCT mdicreate; CGrafPtr port; GDHandle gd; // Allocate memory for INFO to be associated with the hInfo = LocalAlloc(LHND, (WORD) sizeof(INFO)); if (hInfo) { if ((pInfo = (PINFO)LocalLock(hInfo)) == NULL) MessageBox(ghwndMain, "Failed in LocalLock", "Error", MB_OK); // if we do not have a fullPathName, display an open dialog if(fullPathName == NULL) { // Display an open dialog if( !DoOpen(pInfo)){ LocalFree(hInfo); return FALSE; } } else { // Else we open the file pInfo->ofn.lpstrFile = fullPathName; strcpy(pInfo->spec.name, fullPathName); pInfo->ofn.nMaxFile = 256; } // Can we import this file? if(!DoGraphicsImport(pInfo)){ LocalFree(hInfo); return FALSE; } else gMDICount++; pInfo->hParent = ghwndClient; mdicreate.szClass = "MDIClass"; mdicreate.szTitle = (LPTSTR)((*pInfo).ofn).lpstrFile; mdicreate.hOwner = ghModule; mdicreate.x = CW_USEDEFAULT; mdicreate.y = CW_USEDEFAULT; mdicreate.cx = pInfo->imageRect.right - pInfo->imageRect.left; mdicreate.cy = pInfo->imageRect.bottom - pInfo->imageRect.top + GetSystemMetrics(SM_CYCAPTION); mdicreate.style = 0L; // pass the handle of the per MDI child INFO to the child MDI window for storage mdicreate.lParam = (LONG) hInfo; // Create Child Window pInfo->hwndChildWindow = (HANDLE) SendMessage(ghwndClient, WM_MDICREATE, 0L, (LONG)(LPMDICREATESTRUCT)&mdicreate); if (pInfo->hwndChildWindow == NULL) { MessageBox(ghwndMain, "Failed in Creating Child Window", "Error", MB_OK); return FALSE; } // Create our port association && set the port MacSetPort(CreatePortAssociation(pInfo->hwndChildWindow, NULL, 0)); // These lines required to get the image to draw within the window GetGWorld(&port, &gd); GraphicsImportSetGWorld(pInfo->gi, port, gd); // Store our private data SetWindowLong(pInfo->hwndChildWindow, GWL_USERDATA, (LONG)hInfo); return TRUE; } else MessageBox(ghwndMain, "Failed to Allocate INFO data!", "Error", MB_OK); return FALSE; }
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; }
GLuint platformLoadTextureFile(string theFilename, bool generateMipmaps, int *width, int *height) { #ifdef QuickTimeInstalled GLuint textureName; // the "name" by which OpenGL knows the texture unsigned char *pImageBuffer; // the buffer that contains the image data GWorldPtr pGWorld; // a gworld to load the image into int imageDepth; FSSpec fsspecImage; // FSSpec of the image to load #ifdef __APPLE__ CFURLRef imageURL; FSRef imagefsRef; #endif OSStatus err = noErr; // err return value long rowStride; // length, in bytes, of a pixel row in the image GraphicsImportComponent giComp; // component for importing image MatrixRecord matrix; Rect rectImage; // rectangle of source image PixMapHandle hPixMap; // handle to image pix map ImageDescriptionHandle hImageDesc; // handle to image description used to get image depth long imageWidth; long imageHeight; float imageAspect; long textureWidth; long textureHeight; // get the full path to the texture file string fileLocation; fileLocation = pathToResourceDirectory() + theFilename; #ifdef __APPLE__ // create a URL to the file from the C string imageURL = CFURLCreateWithBytes (kCFAllocatorDefault, (UInt8 *)fileLocation.c_str(), fileLocation.length(), kCFStringEncodingASCII, NULL); if (imageURL == NULL) { cout << "error getting URL for image file (image file may not exist): " << theFilename << endl; return 0; } // get a FSRef from the URL if (!CFURLGetFSRef(imageURL, &imagefsRef)) { cout << "error getting FSRef for image file:: " << theFilename << endl; CFRelease(imageURL); return 0; } // get the FSSpec from the FSRef if (FSGetCatalogInfo (&imagefsRef, kFSCatInfoNone, NULL, NULL, &fsspecImage, NULL)) { cout << "error getting FSSpec for image file: " << theFilename << endl; CFRelease(imageURL); return 0; } // release the URL (not needed any more) CFRelease(imageURL); #endif #ifdef _WIN32 // get an FSSpec from the pathname if (NativePathNameToFSSpec ((char *)fileLocation.c_str(), &fsspecImage, kErrorIfFileNotFound)) { cout << "error getting FSSpec for image file: " << fileLocation << endl; return 0; } #endif // save the onscreen graphics port GDHandle origDevice; CGrafPtr origPort; GetGWorld (&origPort, &origDevice); // get an importer for the file err = GetGraphicsImporterForFileWithFlags (&fsspecImage, &giComp, kDontUseValidateToFindGraphicsImporter); if (err != noErr) return 0; // get the image bounds err = GraphicsImportGetNaturalBounds (giComp, &rectImage); if (err != noErr) return 0; // create a handle for the image description and lock it hImageDesc = (ImageDescriptionHandle) NewHandle (sizeof (ImageDescriptionHandle)); HLock ((Handle) hImageDesc); // retrieve the image description err = GraphicsImportGetImageDescription (giComp, &hImageDesc); if (err != noErr) return 0; // find width and height imageWidth = (int) (rectImage.right - rectImage.left); imageHeight = (int) (rectImage.bottom - rectImage.top); // now calculate the aspect ratio (width/height), used to restore image correctly imageAspect = ((float) imageWidth) / ((float) imageHeight); // get the image's pixel depth imageDepth = (**hImageDesc).depth; // find nearest acceptable texture size (width and height) for the image textureWidth = GetTextureDimFromImageDim (imageWidth); textureHeight = GetTextureDimFromImageDim (imageHeight); // pass the optimised (and scaled) size back out to the caller *width = textureWidth; *height = textureHeight; // set texture rectangle for creation of GWorld #ifdef __APPLE__ SetRect (&rectImage, 0, 0, (int) textureWidth, (int) textureHeight); #endif #ifdef _WIN32 MacSetRect (&rectImage, 0, 0, (int) textureWidth, (int) textureHeight); #endif // set stride in bytes width of image * 4 bytes per pixel rowStride = textureWidth * 4; // build new buffer exact size of image (stride * height) pImageBuffer = (unsigned char *) NewPtr (rowStride * textureHeight); // check we got the buffer we wanted if (pImageBuffer == NULL) { // failed - release the component and return an error CloseComponent(giComp); return 0; } // create a new gworld using our unpadded buffer, setting the pixel type correctly for the expected image depth #ifdef __BIG_ENDIAN__ QTNewGWorldFromPtr (&(pGWorld), k32ARGBPixelFormat, &rectImage, NULL, NULL, 0, pImageBuffer, rowStride); #else QTNewGWorldFromPtr (&(pGWorld), k32RGBAPixelFormat, &rectImage, NULL, NULL, 0, pImageBuffer, rowStride); #endif // could we allocate the GWorld? if (pGWorld == NULL) { // failed - release the buffer, component and return an error DisposePtr ((Ptr) pImageBuffer); CloseComponent(giComp); return 0; } // build a transformation matrix to scale the image to the texture size // this also flips the image horizontally, so that texture coordinates map correctly float horizontalScale = (float) textureWidth / (float) imageWidth; float verticalScale = (float) textureHeight / (float) imageHeight; SetIdentityMatrix (&matrix); ScaleMatrix (&matrix, X2Fix(horizontalScale), X2Fix(-verticalScale), 0, 0); TranslateMatrix (&matrix, 0, X2Fix((float)textureHeight)); // set the matrix as the importer matrix err = GraphicsImportSetMatrix(giComp, &matrix); // set the destination of the importer component if (err == noErr) err = GraphicsImportSetGWorld (giComp, pGWorld, NULL); // ensure lossless decompression (if the CODEC supports this) if (err == noErr) err = GraphicsImportSetQuality(giComp, codecLosslessQuality); if (err != noErr) { // failed - release the GWorld, buffer, component and return an error DisposeGWorld (pGWorld); DisposePtr ((Ptr) pImageBuffer); CloseComponent(giComp); return 0; } // get the address of the GWorld's pixmap hPixMap = GetGWorldPixMap (pGWorld); // if everything looks good draw the image to the locked pixmap if ((hPixMap) && (LockPixels (hPixMap))) GraphicsImportDraw (giComp); else { // the pixmap doesn't exist, or we couldn't lock it // release the GWorld, buffer, component and return an error DisposeGWorld (pGWorld); DisposePtr ((Ptr) pImageBuffer); CloseComponent(giComp); return 0; } // for images without an alpha channel, initialise the alpha bytes since QuickTime won't if (imageDepth < 32) { #ifdef __BIG_ENDIAN__ for( unsigned char *p = pImageBuffer; p < pImageBuffer + (rowStride * textureHeight); p+=4) *p = 0xFF; #else for( unsigned char *p = pImageBuffer+3; p < pImageBuffer + (rowStride * textureHeight) +3; p+=4) *p = 0xFF; #endif } // unlock the pixmap UnlockPixels (hPixMap); // dump the component CloseComponent(giComp); // set image width in groups (pixels), accounts for border this ensures proper image alignment row to row glPixelStorei (GL_UNPACK_ROW_LENGTH, textureWidth); // generate a "name" for the texture glGenTextures (1, &textureName); // create the texture in OpenGL glBindTexture(GL_TEXTURE_2D, textureName); // tell OpenGL about the texture and have GLU build mipmaps #ifdef __BIG_ENDIAN__ glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, textureWidth, textureHeight, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pImageBuffer); #else glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pImageBuffer); #endif if (generateMipmaps) #ifdef __BIG_ENDIAN__ if (gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, textureWidth, textureHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pImageBuffer) != 0) #else if (gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, textureWidth, textureHeight, GL_RGBA, GL_UNSIGNED_BYTE, pImageBuffer) != 0) #endif // good time to check for errors? openGLCheckError(); // finished with the GWorld but not the image buffer (it's used by OpenGL as the "live" image buffer) DisposeGWorld (pGWorld); // restore the current graphics port we saved earlier SetGWorld(origPort, origDevice); // all done - return the texture name return textureName; #endif // QuickTimeInstalled }
//============================================================================= // QutTexture_CreateGWorldFromFile : Create a GWorld from a file. //----------------------------------------------------------------------------- GWorldPtr QutTexture_CreateGWorldFromFile(const FSSpec *theFSSpec, TQ3PixelType pixelType) { CTabHandle colourTableHnd; ImageDescriptionHandle imageDescHnd; ComponentInstance theImporter; GWorldPtr theGWorld; TQ3Uns32 theDepth; Rect theRect; OSErr theErr; // Initialise ourselves theImporter = NULL; theGWorld = NULL; imageDescHnd = NULL; colourTableHnd = NULL; theDepth = (pixelType == kQ3PixelTypeARGB16 || pixelType == kQ3PixelTypeRGB16) ? 16 : 32; // Create the importer theErr = GetGraphicsImporterForFile(theFSSpec, &theImporter); // Query the importer for the information we need if (theErr == noErr) { GraphicsImportGetBoundsRect(theImporter, &theRect); theErr = GraphicsImportGetImageDescription(theImporter, &imageDescHnd); if (theErr == noErr) theErr = GetImageDescriptionCTable(imageDescHnd, &colourTableHnd); } // Create the GWorld if (theErr == noErr) theErr = NewGWorld(&theGWorld, theDepth, &theRect, colourTableHnd, NULL, useTempMem | kQ3NativeEndianPixMap ); // Draw the image into the GWorld if (theErr == noErr) { GraphicsImportSetGWorld(theImporter, theGWorld, NULL); GraphicsImportDraw(theImporter); } // Clean up if (theImporter != NULL) CloseComponent(theImporter); if (imageDescHnd != NULL) DisposeHandle((Handle) imageDescHnd); if (colourTableHnd != NULL) DisposeCTable(colourTableHnd); return(theGWorld); }
static void QTDR_DrawFrame (short theTrackWidth, short theTrackHeight, long theNumSample, GWorldPtr theGWorld) { Handle myHandle = NULL; char myData[kPICTFileHeaderSize]; static PicHandle myPicture = NULL; static GWorldPtr myGWorld = NULL; static GraphicsImportComponent myImporter = NULL; Rect myRect; RGBColor myColor; ComponentResult myErr = noErr; MacSetRect(&myRect, 0, 0, theTrackWidth, theTrackHeight); if (myPicture == NULL) { myErr = NewGWorld(&myGWorld, kPixelDepth, &myRect, NULL, NULL, (GWorldFlags)0); if (myErr != noErr) goto bail; // read a picture from our resource file myPicture = GetPicture(kPictureID); if (myPicture == NULL) goto bail; // use Munger to prepend a 512-byte header onto the picture data; this converts the PICT // resource data into in-memory PICT file data (see Ice Floe 14 for an explanation of this) myHandle = (Handle)myPicture; Munger(myHandle, 0, NULL, 0, myData, kPICTFileHeaderSize); // get a graphics importer for the picture myErr = OpenADefaultComponent(GraphicsImporterComponentType, kQTFileTypePicture, &myImporter); if (myErr != noErr) goto bail; // configure the graphics importer myErr = GraphicsImportSetGWorld(myImporter, myGWorld, NULL); if (myErr != noErr) goto bail; myErr = GraphicsImportSetDataHandle(myImporter, myHandle); if (myErr != noErr) goto bail; myErr = GraphicsImportSetBoundsRect(myImporter, &myRect); if (myErr != noErr) goto bail; // draw the picture into the source GWorld myErr = GraphicsImportDraw(myImporter); if (myErr != noErr) goto bail; } // set the blend amount (0 = fully transparent; 0xffff = fully opaque) myColor.red = (theNumSample - 1) * (0xffff / kNumVideoFrames - 1); myColor.green = (theNumSample - 1) * (0xffff / kNumVideoFrames - 1); myColor.blue = (theNumSample - 1) * (0xffff / kNumVideoFrames - 1); OpColor(&myColor); // blend the picture (in the source GWorld) into the empty rectangle (in the destination GWorld) CopyBits((BitMapPtr)*GetGWorldPixMap(myGWorld), (BitMapPtr)*GetGWorldPixMap(theGWorld), &myRect, &myRect, blend, NULL); if (theNumSample == kNumVideoFrames) goto bail; return; bail: if (myHandle != NULL) DisposeHandle(myHandle); if (myPicture != NULL) ReleaseResource((Handle)myPicture); if (myImporter != NULL) CloseComponent(myImporter); }
/********************> LoadTGA() <*****/ bool upload_image(const unsigned char* filePath, bool hasalpha) { if(visibleloading){ loadscreencolor=1; pgame->LoadingScreen(); } #if 1 // for Windows, just use TGA loader for now char fileName[ 256]; CopyPascalStringToC( filePath, fileName); /* // change extension to .TGA int len = strlen( fileName); if (len > 3) { fileName[ len - 3] = 't'; fileName[ len - 2] = 'g'; fileName[ len - 1] = 'a'; } */ // return (LoadTGA( fileName) != NULL); return (LoadImage(fileName, texture)); #else OSStatus err; ComponentResult cr; /*FSRef fsref; Boolean isdir; err = FSPathMakeRef((const UInt8*)filePath, &fsref, &isdir); if(err)return; FSSpec fsspec; err = FSGetCatalogInfo(&fsref, kFSCatInfoNone, NULL, NULL, &fsspec, NULL); if(err)return; */ //Boolean isdir; FSSpec fsspec; //err = FSMakeFSSpec (0, 0, (const unsigned char*)filePath, &fsspec); err = FSMakeFSSpec (0, 0, filePath, &fsspec); //err=FSPathMakeFSSpec((const UInt8*)filePath,&fsspec,&isdir);*/ if(err)return; GraphicsImportComponent gi; err = GetGraphicsImporterForFile(&fsspec, &gi); if(err)return; Rect natbounds; cr = GraphicsImportGetNaturalBounds(gi, &natbounds); size_t buffersize = 4 * natbounds.bottom * natbounds.right; //void* buf = malloc(buffersize); texture.sizeX=natbounds.right; texture.sizeY=natbounds.bottom; /*if(hasalpha)*/texture.bpp = 32; //if(!hasalpha)texture.bpp = 24; GWorldPtr gw; err = QTNewGWorldFromPtr(&gw, k32ARGBPixelFormat, &natbounds, NULL, NULL, 0, texture.data, 4 * natbounds.right); if(err)return; cr = GraphicsImportSetGWorld(gi, gw, NULL); natbounds.top = natbounds.bottom; natbounds.bottom = 0; cr = GraphicsImportSetBoundsRect(gi, &natbounds); cr = GraphicsImportDraw(gi); err = CloseComponent(gi); if(err)return; /*glTexImage2D(textureTarget, 0, GL_RGBA, natbounds.right, natbounds.top, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, buf); */ //free(buf); DisposeGWorld(gw); // Loop Through The Image Data GLuint imageSize; // Used To Store The Image Size When Setting Aside Ram GLuint temp; // Temporary Variable GLuint bytesPerPixel; // Temporary Variable bytesPerPixel=texture.bpp/8; imageSize = texture.sizeX * texture.sizeY * bytesPerPixel; int alltrans=10; for( GLuint i = 0; i < int( imageSize ); i += 4 ) { // Swaps The 1st And 3rd Bytes ('R'ed and 'B'lue) temp = texture.data[i]; // Temporarily Store The Value At Image Data 'i' texture.data[i] = texture.data[i + 1]; // Set The 1st Byte To The Value Of The 3rd Byte texture.data[i + 1] = texture.data[i + 2]; // Set The 3rd Byte To The Value In 'temp' (1st Byte Value) texture.data[i + 2] = texture.data[i + 3]; texture.data[i + 3] = temp; } int tempplace; tempplace=0; if(!hasalpha){ for( GLuint i = 0; i < int( imageSize ); i += 4 ) { texture.data[i + 3] = 255; /*texture.data[tempplace] = texture.data[i]; // Set The 1st Byte To The Value Of The 3rd Byte texture.data[tempplace + 1] = texture.data[i + 1]; // Set The 3rd Byte To The Value In 'temp' (1st Byte Value) texture.data[tempplace + 2] = texture.data[i + 2]; tempplace+=3;*/ } } if(texdetail>1){ int which=0; float temp; float howmany; for( GLuint k = 0; k < int( imageSize); k += bytesPerPixel*texture.sizeX*texdetail ) { for( GLuint i = 0; i < int( imageSize/texture.sizeY ); i += bytesPerPixel*texdetail ) { for( GLuint b = 0; b < bytesPerPixel ; b ++ ){ temp=0; howmany=0; for( GLuint l = 0; l < texdetail*texture.sizeX ; l +=texture.sizeX ){ for( GLuint j = 0; j < texdetail ; j ++ ) { temp += (int)texture.data[k+i+j*bytesPerPixel+l*bytesPerPixel+b]; // Set The 1st Byte To The Value Of The 3rd Byte howmany++; } } texture.data[which+b]=GLubyte(temp/howmany); } which+=bytesPerPixel; } } texture.sizeX/=texdetail; texture.sizeY/=texdetail; } return true; #endif }
GWorldPtr OpenImage (void) { unsigned long rowStride; GraphicsImportComponent giComp; NavReplyRecord replyNav; NavTypeListHandle hTypeList = (NavTypeListHandle) NewHandleClear (sizeof (NavTypeList) + sizeof (OSType) * 13); FSSpec fsspecImage; AEKeyword theKeyword; DescType actualType; Size actualSize; OSStatus err = noErr; Rect rectImage; GDHandle origDevice; CGrafPtr origPort; PixMapHandle hPixMap; ImageDescriptionHandle hImageDesc; MatrixRecord matrix; GWorldPtr pGWorld; unsigned char * pImageBuffer; long imageWidth; long imageHeight; float imageAspect; long imageDepth; long textureWidth; long textureHeight; GetGWorld (&origPort, &origDevice); // save onscreen graphics port HLock ((Handle) hTypeList); (**hTypeList).osTypeCount = 14; (**hTypeList).osType[0] = 'qtif'; (**hTypeList).osType[1] = 'SGI '; (**hTypeList).osType[2] = '8BPS'; (**hTypeList).osType[3] = 'GIF '; (**hTypeList).osType[4] = 'GIFf'; (**hTypeList).osType[5] = 'JPEG'; (**hTypeList).osType[6] = 'JPG '; (**hTypeList).osType[7] = 'PICT'; (**hTypeList).osType[8] = 'PNTG'; (**hTypeList).osType[9] = 'grip'; (**hTypeList).osType[10] = 'BMPp'; (**hTypeList).osType[11] = 'TIFF'; (**hTypeList).osType[12] = 'TEXT'; (**hTypeList).osType[13] = '????'; err = NavChooseFile (NULL, &replyNav, NULL, NULL, NULL, NULL, hTypeList, NULL); if ((err == noErr) && (replyNav.validRecord)) err = AEGetNthPtr (&(replyNav.selection), 1, typeFSS, &theKeyword, &actualType, &fsspecImage, sizeof (fsspecImage), &actualSize); NavDisposeReply (&replyNav); if (err != noErr) return NULL; GetGraphicsImporterForFile (&fsspecImage, &giComp); if (err != noErr) return NULL; // create GWorld err = GraphicsImportGetNaturalBounds (giComp, &rectImage); if (err != noErr) return NULL; hImageDesc = (ImageDescriptionHandle) NewHandle (sizeof (ImageDescriptionHandle)); HLock ((Handle) hImageDesc); err = GraphicsImportGetImageDescription (giComp, &hImageDesc); if (err != noErr) return NULL; imageWidth = rectImage.right - rectImage.left; imageHeight = rectImage.bottom - rectImage.top; imageAspect = ((float) imageWidth) / ((float) imageHeight); imageDepth = (**hImageDesc).depth; // bits if (imageDepth <= 16) imageDepth = 16; else imageDepth = 32; #if 1 textureWidth = imageWidth;//40;//imageWidth;//256; textureHeight = imageHeight;//40 * imageHeight / imageWidth;//imageHeight;//256; #else textureWidth = imageWidth;//256; textureHeight = imageHeight;//256; #endif SetRect (&rectImage, 0, 0, textureWidth, textureHeight); // l, t, r. b reset to texture rectangle rowStride = textureWidth * imageDepth / 8; pImageBuffer = (unsigned char *) NewPtrClear (rowStride * (textureHeight)); if (imageDepth == 32) QTNewGWorldFromPtr (&(pGWorld), k32ARGBPixelFormat, &rectImage, NULL, NULL, 0, pImageBuffer, rowStride); else QTNewGWorldFromPtr (&(pGWorld), k16BE555PixelFormat, &rectImage, NULL, NULL, 0, pImageBuffer, rowStride); if (NULL == pGWorld) return NULL; // decompress to gworld SetIdentityMatrix (&matrix); ScaleMatrix (&matrix, X2Fix ((float) textureWidth / (float) imageWidth), X2Fix ((float) textureHeight / (float) imageHeight), X2Fix (0.0), X2Fix (0.0)); err = GraphicsImportSetMatrix(giComp, &matrix); if (err != noErr) return NULL; err = GraphicsImportSetGWorld (giComp, pGWorld, NULL); if (err != noErr) return NULL; err = GraphicsImportSetQuality(giComp, codecLosslessQuality); if (err != noErr) return NULL; hPixMap = GetGWorldPixMap (pGWorld); if ((hPixMap) && (LockPixels (hPixMap))) // lock offscreen pixel map GraphicsImportDraw (giComp); else return NULL; // modify alpha if ( imageDepth == 32 ) { unsigned long i; unsigned long * pixel = (unsigned long *)GetPixBaseAddr( hPixMap ); for (i = 0; i < textureWidth * textureHeight; i++) { if ((*pixel & 0x00FFFFFF) == 0x00FF00) // mask only color bits and look for green *pixel = 0x00000000;//0x00303040; // replace green with dark gray transparent (to help filtering) else *pixel |= 0xFF000000; // ensure alpha is set for opaque pixels pixel++; } } else { unsigned short i; unsigned short * pixel = (unsigned short *)GetPixBaseAddr( hPixMap ); for (i = 0; i < textureWidth * textureHeight; i++) { if ((*pixel & 0x7FFF) == 0x03E0) // mask only color bits and look for green *pixel = 0x0000;//0x0363; // replace green with dark gray transparent (to help filtering) else *pixel |= 0x8000; // ensure alpha is set for opaque pixels pixel++; } } return pGWorld; }
// ----------------------------------------------------------------------------- // CreateCGImageWithQTFromFile // ----------------------------------------------------------------------------- // OSStatus CreateCGImageWithQTFromFile( FSRef* inFSRef, CGImageRef* outImage ) { OSStatus err; GraphicsImportComponent importer; FSSpec fileSpec; GWorldPtr gWorld = NULL; Rect bounds; CGDataProviderRef provider; CGColorSpaceRef colorspace; long width; long height; long rowbytes; Ptr dataPtr; // Make an FSRef into an FSSpec err = FSGetCatalogInfo( inFSRef, kFSCatInfoNone, NULL, NULL, &fileSpec, NULL ); require_noerr( err, CantMakeFSSpec ); err = GetGraphicsImporterForFile( &fileSpec, &importer ); require_noerr( err, CantGetImporter ); err = GraphicsImportGetNaturalBounds( importer, &bounds ); require_noerr( err, CantGetBounds ); // Allocate the buffer width = RECT_WIDTH( bounds ); height = RECT_HEIGHT( bounds ); rowbytes = width * 4; dataPtr = NewPtr( height * rowbytes ); require_action( dataPtr != NULL, CantAllocBuffer, err = memFullErr ); err = NewGWorldFromPtr( &gWorld, 32, &bounds, NULL, NULL, NULL, dataPtr, rowbytes ); require_noerr( err, CantCreateGWorld ); err = GraphicsImportSetGWorld( importer, gWorld, GetGWorldDevice( gWorld) ); require_noerr( err, CantSetGWorld ); err = GraphicsImportDraw( importer ); require_noerr( err, CantDraw ); provider = CGDataProviderCreateWithData( NULL, dataPtr, height * rowbytes, GWorldImageBufferRelease ); require_action( provider != NULL, CantCreateProvider, err = memFullErr ); colorspace = CGColorSpaceCreateDeviceRGB(); require_action( colorspace != NULL, CantCreateColorSpace, err = memFullErr ); *outImage = CGImageCreate( width, height, 8, 32, rowbytes, colorspace, kCGImageAlphaPremultipliedFirst, provider, NULL, false, kCGRenderingIntentDefault ); require_action( *outImage != NULL, CantCreateImage, err = memFullErr ); CantCreateImage: CGColorSpaceRelease( colorspace ); CantCreateColorSpace: CGDataProviderRelease( provider ); CantCreateProvider: CantDraw: CantSetGWorld: if ( gWorld != NULL ) DisposeGWorld( gWorld ); CantCreateGWorld: CantAllocBuffer: CantGetBounds: CantGetImporter: CantMakeFSSpec: return err; }
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; }
void QTCmpr_CompressImage (WindowObject theWindowObject) { Rect myRect; GraphicsImportComponent myImporter = NULL; ComponentInstance myComponent = NULL; GWorldPtr myImageWorld = NULL; // the graphics world we draw the image in PixMapHandle myPixMap = NULL; ImageDescriptionHandle myDesc = NULL; Handle myHandle = NULL; OSErr myErr = noErr; if (theWindowObject == NULL) return; ////////// // // get a graphics importer for the image file and determine the natural size of the image; // note that the image file *already* has a graphics importer associated with it (namely // (**theWindowObject).fGraphicsImporter), but we create a new one so that the existing one // can be used to redraw the image in the callback procedure QTCmpr_FilterProc // ////////// myErr = GetGraphicsImporterForFile(&(**theWindowObject).fFileFSSpec, &myImporter); if (myErr != noErr) goto bail; myErr = GraphicsImportGetNaturalBounds(myImporter, &myRect); if (myErr != noErr) goto bail; ////////// // // create an offscreen graphics world and draw the image into it // ////////// myErr = QTNewGWorld(&myImageWorld, 0, &myRect, NULL, NULL, kICMTempThenAppMemory); if (myErr != noErr) goto bail; // get the pixmap of the GWorld; we'll lock the pixmap, just to be safe myPixMap = GetGWorldPixMap(myImageWorld); if (!LockPixels(myPixMap)) goto bail; // set the current port and draw the image GraphicsImportSetGWorld(myImporter, (CGrafPtr)myImageWorld, NULL); GraphicsImportDraw(myImporter); ////////// // // configure and display the standard image compression dialog box // ////////// // open the standard compression dialog component myComponent = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType); if (myComponent == NULL) goto bail; // set the picture to be displayed in the dialog box; passing NULL for the rect // means use the entire image; passing 0 for the flags means to use the default // system method of displaying the test image, which is currently a combination // of cropping and scaling; personally, I prefer scaling (your mileage may vary) SCSetTestImagePixMap(myComponent, myPixMap, NULL, scPreferScaling); // install the custom procs, if requested // we can install two kinds of custom procedures for use in connection with // the standard dialog box: (1) a modal-dialog filter function, and (2) a hook // function to handle the custom button in the dialog box if (gUseExtendedProcs) QTCmpr_InstallExtendedProcs(myComponent, (long)myPixMap); // request image compression settings from the user; in other words, put up the dialog box myErr = SCRequestImageSettings(myComponent); if (myErr == scUserCancelled) goto bail; ////////// // // compress the image // ////////// myErr = SCCompressImage(myComponent, myPixMap, NULL, &myDesc, &myHandle); if (myErr != noErr) goto bail; ////////// // // save the compressed image in a new file // ////////// QTCmpr_PromptUserForDiskFileAndSaveCompressed(myHandle, myDesc); bail: if (gUseExtendedProcs) QTCmpr_RemoveExtendedProcs(); if (myPixMap != NULL) if (GetPixelsState(myPixMap) & pixelsLocked) UnlockPixels(myPixMap); if (myImporter != NULL) CloseComponent(myImporter); if (myComponent != NULL) CloseComponent(myComponent); if (myDesc != NULL) DisposeHandle((Handle)myDesc); if (myHandle != NULL) DisposeHandle(myHandle); if (myImageWorld != NULL) DisposeGWorld(myImageWorld); }