From a53dd7d7444ede6b684c4179edb6e2aceb96a765 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 15 Jul 2011 08:32:04 +0000 Subject: [PATCH] From Philip Lamp, submitted by Stephan Huber, "Modify the ReaderWriteImageIO_IOS to correctly handle relative paths when reading from a file. This means that no longer do all image files have to live at the root of the Resources folder inside the app bundle, but can now be organized inside folders. Also improved error handling and fixed a potential leak of a CGColorSpaceRef each once per image load." --- .../imageio/ReaderWriterImageIO_IOS.cpp | 130 +++++++++++------- 1 file changed, 77 insertions(+), 53 deletions(-) diff --git a/src/osgPlugins/imageio/ReaderWriterImageIO_IOS.cpp b/src/osgPlugins/imageio/ReaderWriterImageIO_IOS.cpp index a4459598d..a8c7c7ba3 100644 --- a/src/osgPlugins/imageio/ReaderWriterImageIO_IOS.cpp +++ b/src/osgPlugins/imageio/ReaderWriterImageIO_IOS.cpp @@ -1,4 +1,3 @@ -#pragma once #include #include #include @@ -163,50 +162,70 @@ osg::Image* ReadCoreGraphicsImageFromFile(std::string file) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; //chop the extension off - std::string strExt = osgDB::getFileExtension(file); - std::string strPath = osgDB::getFilePath(file); - std::string strName = osgDB::getStrippedName(file); - std::string strFile = strPath+"/"+strName; + //std::string strExt = osgDB::getFileExtension(file); + //std::string strPath = osgDB::getFilePath(file); + //std::string strName = osgDB::getStrippedName(file); + //std::string strFile = strPath + "/" + strName; - NSString* path = [NSString stringWithCString:strName.c_str() length:strlen(strName.c_str())]; - NSString* ext = [NSString stringWithCString:strExt.c_str() length:strlen(strExt.c_str())]; + //NSString* path = [NSString stringWithCString:strName.c_str() encoding:NSUTF8StringEncoding]; + //NSString* ext = [NSString stringWithCString:strExt.c_str() encoding:NSUTF8StringEncoding]; //CGImageRef textureImage = [UIImage imageNamed:path].CGImage; - CGImageRef textureImage = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:path ofType:ext]].CGImage; - - if (textureImage == nil) { + //CGImageRef textureImage = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:path ofType:ext]].CGImage; + NSString* path = [NSString stringWithCString:file.c_str() encoding:NSUTF8StringEncoding]; + //NSLog(@"imageio: About to open %@.\n", path); + UIImage *img = [UIImage imageWithContentsOfFile:path]; + if (!img) { + NSLog(@"imageio: failed to load UIImage image '%@'.\n", path); + [pool release]; + return NULL; + } + CGImageRef textureImage = img.CGImage; + if (!textureImage) { + NSLog(@"imageio: failed to create CGImageRef.\n"); + [pool release]; + return NULL; + } - NSLog(@"imageio: failed to load CGImageRef image '%@'", path ); + size_t texWidth = CGImageGetWidth(textureImage); + size_t texHeight = CGImageGetHeight(textureImage); + GLubyte *textureData = (GLubyte *)malloc(texWidth * texHeight * 4); + if (!textureData) { + NSLog(@"imageio: out of memory.\n"); + [pool release]; + return NULL; + } + + CGColorSpaceRef csref = CGColorSpaceCreateDeviceRGB(); + if (!csref) { + NSLog(@"imageio: failed to create CGColorSpaceRef.\n"); + free(textureData); + [pool release]; + return NULL; + } + + CGContextRef textureContext = CGBitmapContextCreate(textureData, + texWidth, texHeight, + 8, texWidth * 4, + csref, + kCGImageAlphaPremultipliedLast); + CGColorSpaceRelease(csref); + if (!textureContext) { + NSLog(@"imageio: failed to create CGContextRef.\n"); + free(textureData); [pool release]; return NULL; } - - NSInteger texWidth = CGImageGetWidth(textureImage); - NSInteger texHeight = CGImageGetHeight(textureImage); - - GLubyte *textureData = (GLubyte *)malloc(texWidth * texHeight * 4); - - CGContextRef textureContext = CGBitmapContextCreate(textureData, - texWidth, texHeight, - 8, texWidth * 4, - CGColorSpaceCreateDeviceRGB(), - kCGImageAlphaPremultipliedLast); - //copy into texturedata CGContextDrawImage(textureContext, - CGRectMake(0.0, 0.0, (float)texWidth, (float)texHeight), + CGRectMake(0.0f, 0.0f, (float)texWidth, (float)texHeight), textureImage); - CGContextRelease(textureContext); - //create the osg image - unsigned int dataType = GL_UNSIGNED_BYTE; int s = texWidth; int t = texHeight; - - osg::Image* image = new osg::Image(); image->setImage(s, t, 1, GL_RGBA, @@ -223,12 +242,10 @@ osg::Image* ReadCoreGraphicsImageFromFile(std::string file) // by Tatsuhiro Nishioka (based on SDL's workaround on the similar issue) // http://bugzilla.libsdl.org/show_bug.cgi?id=868 // - - int i, j; GLubyte *pixels = (GLubyte *)image->data(); for (i = image->t() * image->s(); i--; ) { - + GLubyte alpha = pixels[3]; if (alpha && (alpha < 255)) { for (j = 0; j < 3; ++j) { @@ -237,12 +254,9 @@ osg::Image* ReadCoreGraphicsImageFromFile(std::string file) } pixels += 4; } - - + [pool release]; return image; - - } osg::Image* CreateOSGImageFromCGImage(CGImageRef textureImage) @@ -253,35 +267,49 @@ osg::Image* CreateOSGImageFromCGImage(CGImageRef textureImage) NSLog(@"imageio: failed to load CGImageRef image"); return NULL; } - - - - NSInteger texWidth = CGImageGetWidth(textureImage); - NSInteger texHeight = CGImageGetHeight(textureImage); - + + size_t texWidth = CGImageGetWidth(textureImage); + size_t texHeight = CGImageGetHeight(textureImage); + GLubyte *textureData = (GLubyte *)malloc(texWidth * texHeight * 4); + if (!textureData) { + NSLog(@"imageio: out of memory.\n"); + [pool release]; + return NULL; + } + CGColorSpaceRef csref = CGColorSpaceCreateDeviceRGB(); + if (!csref) { + NSLog(@"imageio: failed to create CGColorSpaceRef.\n"); + free(textureData); + [pool release]; + return NULL; + } + CGContextRef textureContext = CGBitmapContextCreate(textureData, texWidth, texHeight, 8, texWidth * 4, - CGColorSpaceCreateDeviceRGB(), + csref, kCGImageAlphaPremultipliedLast); - + CGColorSpaceRelease(csref); + if (!textureContext) { + NSLog(@"imageio: failed to create CGContextRef.\n"); + free(textureData); + [pool release]; + return NULL; + } //copy into texturedata CGContextDrawImage(textureContext, - CGRectMake(0.0, 0.0, (float)texWidth, (float)texHeight), + CGRectMake(0.0f, 0.0f, (float)texWidth, (float)texHeight), textureImage); CGContextFlush(textureContext); CGContextRelease(textureContext); //create the osg image - unsigned int dataType = GL_UNSIGNED_BYTE; int s = texWidth; int t = texHeight; - - osg::Image* image = new osg::Image(); image->setImage(s, t, 1, GL_RGBA, @@ -312,13 +340,9 @@ osg::Image* CreateOSGImageFromCGImage(CGImageRef textureImage) } pixels += 4; } - - + [pool release]; return image; - - - } class ReaderWriterImageIO : public osgDB::ReaderWriter