From e723c6d63b83cf4ebc57dadb9304b6f35406e5ea Mon Sep 17 00:00:00 2001 From: Ulrich Hertlein Date: Sun, 23 Apr 2017 11:52:05 +0200 Subject: [PATCH 1/3] Fixes compiler warning regarding logic vs bitwise AND --- src/osgViewer/GraphicsWindowCocoa.mm | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/src/osgViewer/GraphicsWindowCocoa.mm b/src/osgViewer/GraphicsWindowCocoa.mm index c2ab32b80..bbca00de9 100644 --- a/src/osgViewer/GraphicsWindowCocoa.mm +++ b/src/osgViewer/GraphicsWindowCocoa.mm @@ -710,16 +710,15 @@ static NSRect convertToQuartzCoordinates(const NSRect& rect) if (!_win) return; NSString* unmodified_chars = [theEvent charactersIgnoringModifiers]; - if ([theEvent modifierFlags] && NSShiftKeyMask) { + if ([theEvent modifierFlags] & NSShiftKeyMask) { unmodified_chars = [unmodified_chars lowercaseString]; } NSString* chars = [theEvent characters]; - - if ((chars) && ([chars length] > 0)) { + if (chars && ([chars length] > 0)) { unsigned int unmodified_keyCode = remapCocoaKey([unmodified_chars characterAtIndex:0], [theEvent modifierFlags] ); unsigned int keyCode = remapCocoaKey([chars characterAtIndex:0], [theEvent modifierFlags] ); - //std::cout << std::hex << "key dn: " <<[chars characterAtIndex:0] << "=" << keyCode << " unmodified: " << unmodified_keyCode << std::endl; + //std::cout << "key dn: " << std::hex << [chars characterAtIndex:0] << "=" << keyCode << " unmodified: " << unmodified_keyCode << std::endl; _win->getEventQueue()->keyPress( keyCode, _win->getEventQueue()->getTime(), unmodified_keyCode); } } @@ -730,17 +729,15 @@ static NSRect convertToQuartzCoordinates(const NSRect& rect) if (!_win) return; NSString* unmodified_chars = [theEvent charactersIgnoringModifiers]; - if ([theEvent modifierFlags] && NSShiftKeyMask) { + if ([theEvent modifierFlags] & NSShiftKeyMask) { unmodified_chars = [unmodified_chars lowercaseString]; } NSString* chars = [theEvent characters]; - - if ((chars) && ([chars length] > 0)) { + if (chars && ([chars length] > 0)) { unsigned int unmodified_keyCode = remapCocoaKey([unmodified_chars characterAtIndex:0], [theEvent modifierFlags] ); unsigned int keyCode = remapCocoaKey([chars characterAtIndex:0], [theEvent modifierFlags] ); - //std::cout << std::hex << "key up: " <<[chars characterAtIndex:0] << "=" << keyCode << " unmodified: " << unmodified_keyCode << std::endl; - + //std::cout << "key up: " << std::hex << [chars characterAtIndex:0] << "=" << keyCode << " unmodified: " << unmodified_keyCode << std::endl; _win->getEventQueue()->keyRelease( keyCode, _win->getEventQueue()->getTime(), unmodified_keyCode); } } @@ -790,26 +787,18 @@ static NSRect convertToQuartzCoordinates(const NSRect& rect) - (osgGA::GUIEventAdapter::TouchPhase) convertTouchPhase: (NSTouchPhase) phase { switch(phase) { - case NSTouchPhaseBegan: return osgGA::GUIEventAdapter::TOUCH_BEGAN; - break; case NSTouchPhaseMoved: return osgGA::GUIEventAdapter::TOUCH_MOVED; - break; - case NSTouchPhaseStationary: return osgGA::GUIEventAdapter::TOUCH_STATIONERY; - break; - case NSTouchPhaseEnded: case NSTouchPhaseCancelled: return osgGA::GUIEventAdapter::TOUCH_ENDED; - break; } return osgGA::GUIEventAdapter::TOUCH_ENDED; - } @@ -1107,7 +1096,6 @@ void GraphicsWindowCocoa::init() void GraphicsWindowCocoa::setupNSWindow(NSWindow* win) { - [win setReleasedWhenClosed:NO]; [win setDisplaysWhenScreenProfileChanges:YES]; GraphicsWindowCocoaDelegate* delegate = [[GraphicsWindowCocoaDelegate alloc] initWith: this]; @@ -1116,7 +1104,6 @@ void GraphicsWindowCocoa::setupNSWindow(NSWindow* win) [win makeKeyAndOrderFront:nil]; [win setAcceptsMouseMovedEvents: YES]; - } From b26e350e72cd492f8ae9490eb054f607030bf7f8 Mon Sep 17 00:00:00 2001 From: Ulrich Hertlein Date: Sun, 23 Apr 2017 21:38:01 +0200 Subject: [PATCH 2/3] Updates the macOS build instructions in README.md. - Removes obsolete instructions regarding x86_64 vs i386, Cocoa vs Carbon, etc - Markdown formatting changes --- README.md | 194 +++++++++++++++--------------------------------------- 1 file changed, 53 insertions(+), 141 deletions(-) diff --git a/README.md b/README.md index 5dccc4ea2..37f0ceb1f 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,11 @@ [![Coverity Status](https://scan.coverity.com/projects/9159/badge.svg)](https://scan.coverity.com/projects/openscenegraph-openscenegraph) [![Documentation](https://codedocs.xyz/openscenegraph/OpenSceneGraph.svg)](https://codedocs.xyz/openscenegraph/OpenSceneGraph/) -### Introduction +# Introduction Welcome to the OpenSceneGraph (OSG). -For up-to-date information on the project, in-depth details on how to -compile and run libraries and examples, see the documentation on the -OpenSceneGraph website: +For up-to-date information on the project, in-depth details on how to compile and run libraries and examples, see the documentation on the OpenSceneGraph website: http://www.openscenegraph.org/index.php/documentation @@ -16,53 +14,36 @@ For support subscribe to our public mailing list or forum, details at: http://www.openscenegraph.org/index.php/support -For the impatient, we've included quick build instructions below, these -are are broken down is three parts: +For the impatient, we've included quick build instructions below, these are are broken down is three parts: 1) General notes on building the OpenSceneGraph - 2) OSX release notes + 2) macOS release notes 3) iOS release notes -If details below are not sufficient then head over to the openscenegraph.org -to the Documentation/GettingStarted and Documentation/PlatformSpecifics sections for -more indepth instructions. +If details below are not sufficient then head over to the openscenegraph.org to the Documentation/GettingStarted and Documentation/PlatformSpecifics sections for more indepth instructions. Robert Osfield. Project Lead. 28th March 2017. --- +--- -### Section 1. How to build the OpenSceneGraph +## Section 1. How to build OpenSceneGraph -The OpenSceneGraph uses the CMake build system to generate a -platform-specific build environment. CMake reads the CMakeLists.txt -files that you'll find throughout the OpenSceneGraph directories, -checks for installed dependenciesand then generates the appropriate -build system. +The OpenSceneGraph uses the CMake build system to generate a platform-specific build environment. CMake reads the `CMakeLists.txt` files that you'll find throughout the OpenSceneGraph directories, checks for installed dependencies and then generates files for the selected build system. -If you don't already have CMake installed on your system you can grab -it from http://www.cmake.org, use version 2.8.0 or later. Details on the -OpenSceneGraph's CMake build can be found at: +If you don't already have CMake installed on your system you can grab it from http://www.cmake.org, use version 2.8.0 or later. Details on the OpenSceneGraph's CMake build can be found at: http://www.openscenegraph.org/projects/osg/wiki/Build/CMake -Under unices (i.e. Linux, IRIX, Solaris, Free-BSD, HP-Ux, AIX, OSX) -use the cmake or ccmake command-line utils. Note that cmake . defaults -to building Release to ensure that you get the best performance from -your final libraries/applications. +Under Unix-like systems (i.e. Linux, IRIX, Solaris, Free-BSD, HP-UX, AIX, macOS) use the `cmake` or `ccmake` command-line utils. Note that `cmake .` defaults to building Release to ensure that you get the best performance from your final libraries/applications. cd OpenSceneGraph cmake . make sudo make install -Alternatively, you can create an out-of-source build directory and run -cmake or ccmake from there. The advantage to this approach is that the -temporary files created by CMake won't clutter the OpenSceneGraph -source directory, and also makes it possible to have multiple -independent build targets by creating multiple build directories. In a -directory alongside the OpenSceneGraph use: +Alternatively, you can create an out-of-source build directory and run cmake or ccmake from there. The advantage to this approach is that the temporary files created by CMake won't clutter the OpenSceneGraph source directory, and also makes it possible to have multiple independent build targets by creating multiple build directories. In a directory alongside the OpenSceneGraph use: mkdir build cd build @@ -70,137 +51,68 @@ directory alongside the OpenSceneGraph use: make sudo make install -Under Windows use the GUI tool CMakeSetup to build your VisualStudio -files. The following page on our wiki dedicated to the CMake build -system should help guide you through the process: +Under Windows use the GUI tool CMakeSetup to build your VisualStudio files. The following page on our wiki dedicated to the CMake build system should help guide you through the process: http://www.openscenegraph.org/index.php/documentation/platform-specifics/windows -Under OSX you can either use the CMake build system above, or use the -Xcode projects that you will find in the OpenSceneGraph/Xcode -directory. See release notes on OSX CMake build below. +Under macOS you can either use the CMake build system above, or use the Xcode projects that you will find in the OpenSceneGraph/Xcode directory. See release notes on macOS CMake build below. -For further details on compilation, installation and platform-specific -information read "Getting Started" guide: +For further details on compilation, installation and platform-specific information read "Getting Started" guide: http://www.openscenegraph.org/index.php/documentation/10-getting-started -### Section 2. Release notes on OSX build, by Eric Sokolowsky, August 5, 2008 +## Section 2. Release notes on macOS build, by Eric Sokolowski et al. -There are several ways to compile OpenSceneGraph under OSX. The -recommended way is to use CMake 2.6 to generate Xcode projects, then use -Xcode to build the library. The default project will be able to build -Debug or Release libraries, examples, and sample applications. Here are -some key settings to consider when using CMake: +There are two ways to compile OpenSceneGraph under macOS. The recommended way is to use CMake to generate Xcode project files and then use Xcode to build the library. The default project will be able to build Debug or Release libraries, examples, and sample applications. -BUILD_OSG_EXAMPLES - By default this is turned off. Turn this setting on -to compile many great example programs. +The alternative is to build OpenSceneGraph from the command line using `make` or `ninja` using the instructions for Unix-like systems above. -CMAKE_OSX_ARCHITECTURES - Xcode can create applications, executables, -libraries, and frameworks that can be run on more than one architecture. -Use this setting to indicate the architectures on which to build OSG. -Possibilities include ppc, ppc64, i386, and x86_64. Building OSG using -either of the 64-bit options (ppc64 and x86_64) has its own caveats -below. +Here are some key settings to consider when using CMake: -OSG_BUILD_APPLICATION_BUNDLES - Normally only executable binaries are -created for the examples and sample applications. Turn this option on if -you want to create real OSX .app bundles. There are caveats to creating -.app bundles, see below. - -OSG_WINDOWING_SYSTEM - You have the choice to use Carbon or X11 when -building applications on OSX. Under Leopard and later, X11 applications, -when started, will automatically launch X11 when needed. However, -full-screen X11 applications will still show the menu bar at the top of -the screen. Since many parts of the Carbon user interface are not -64-bit, X11 is the only supported option for OSX applications compiled -for ppc64 or x86_64. - -There is an Xcode directory in the base of the OSG software -distribution, but its future is limited, and will be discontinued once -the CMake project generator completely implements its functionality. +- BUILD_OSG_EXAMPLES - By default this is turned off. Turn this setting on to compile many great example programs. +- CMAKE_OSX_ARCHITECTURES - Xcode can create applications, executables, libraries, and frameworks that can be run on more than one architecture. Use this setting to indicate the architectures on which to build OSG. x86_64 is the only supported value for OS versions > 10.7. +- OSG_BUILD_APPLICATION_BUNDLES - Normally only executable binaries are created for the examples and sample applications. Turn this option on if you want to create real macOS .app bundles. There are caveats to creating `.app` bundles, see below. +- OSG_DEFAULT_IMAGE_PLUGIN_FOR_OSX - By default macOS uses the `imageio` plugin instead of the plugins for the individual file types (e.g. `jpg`, `gif`, etc.) to load image file types. The `imageio` plugin can handle all popular file formats through the ImageIO framework. +- OSG_WINDOWING_SYSTEM - You have the choice to use Cocoa, Carbon, or X11 when building applications on macOS. Cocoa is the default for OS versions >= 10.5. Carbon and X11 are no longer actively supported, either by Apple or the OSG community. -APPLICATION BUNDLES (.app bundles) +### APPLICATION BUNDLES (.app bundles) -The example programs when built as application bundles only contain the -executable file. They do not contain the dependent libraries as would a -normal bundle, so they are not generally portable to other machines. -They also do not know where to find plugins. An environmental variable -OSG_LIBRARY_PATH may be set to point to the location where the plugin -.so files are located. OSG_FILE_PATH may be set to point to the location -where data files are located. Setting OSG_FILE_PATH to the -OpenSceneGraph-Data directory is very useful when testing OSG by running -the example programs. +The example programs when built as application bundles only contain the executable file. They do not contain the dependent libraries as would a normal bundle, so they are not generally portable to other machines. +They also do not know where to find plugins. An environmental variable OSG_LIBRARY_PATH may be set to point to the location where the plugin .so files are located. OSG_FILE_PATH may be set to point to the location where data files are located. Setting OSG_FILE_PATH to the OpenSceneGraph-Data directory is very useful when testing OSG by running the example programs. -Many of the example programs use command-line arguments. When -double-clicking on an application (or using the equivalent "open" -command on the command line) only those examples and applications that -do not require command-line arguments will successfully run. The -executable file within the .app bundle can be run from the command-line -if command-line arguments are needed. +Many of the example programs use command-line arguments. When double-clicking on an application (or using the equivalent "open" command on the command line) only those examples and applications that do not require command-line arguments will successfully run. The executable file within the .app bundle can be run from the command-line if command-line arguments are needed. -64-BIT APPLICATION SUPPORT +## Section 3. Release notes on iOS build, by Thomas Hogarth -OpenSceneGraph will not compile successfully when OSG_WINDOWING_SYSTEM is -Carbon and either x86_64 or ppc64 is selected under CMAKE_OSX_ARCHITECTURES, -as Carbon is a 32bit only API. A version of the osgviewer library written in -Cocoa is needed. However, OSG may be compiled under 64-bits if the X11 -windowing system is selected. However, Two parts of the OSG default -distribution will not work with 64-bit X11: the osgviewerWX example -program and the osgdb_qt (Quicktime) plugin. These must be removed from -the Xcode project after Cmake generates it in order to compile with -64-bit architectures. The lack of the latter means that images such as -jpeg, tiff, png, and gif will not work, nor will animations dependent on -Quicktime. A new ImageIO-based plugin is being developed to handle the -still images, and a QTKit plugin will need to be developed to handle -animations. +With CMake, XCode and the iOS sdk installed you can generate an iOS XCode project using the following command line: + + export THIRDPARTY_PATH=/path/to/my/3rdParty + cmake ./ -G Xcode -DOSG_BUILD_PLATFORM_IPHONE:BOOL=ON \ + -DIPHONE_SDKVER="10.2" \ + -DIPHONE_VERSION_MIN="8.0" \ + -DOPENGL_PROFILE:STRING=GLES2 \ + -DBUILD_OSG_APPLICATIONS:BOOL=OFF \ + -DBUILD_OSG_EXAMPLES:BOOL=ON \ + -DOSG_WINDOWING_SYSTEM:STRING=IOS \ + -DOSG_DEFAULT_IMAGE_PLUGIN_FOR_OSX="imageio" \ + -DDYNAMIC_OPENSCENEGRAPH:BOOL=OFF \ + -DDYNAMIC_OPENTHREADS:BOOL=OFF \ + -DCURL_INCLUDE_DIR:PATH="$THIRDPARTY_PATH/curl-ios-device/include" \ + -DCURL_LIBRARY:PATH="$THIRDPARTY_PATH/curl-ios-device/lib/libcurl.a" \ + -DFREETYPE_INCLUDE_DIR_freetype2:PATH="$THIRDPARTY_PATH/freetype-ios-universal/include/freetype" \ + -DFREETYPE_INCLUDE_DIR_ft2build:PATH="$THIRDPARTY_PATH/freetype-ios-universal/include" \ + -DFREETYPE_LIBRARY:PATH="$THIRDPARTY_PATH/freetype-ios-universal/lib/libFreeType_iphone_universal.a" \ + -DTIFF_INCLUDE_DIR:PATH="$THIRDPARTY_PATH/tiff-ios-device/include" \ + -DTIFF_LIBRARY:PATH="$THIRDPARTY_PATH/tiff-ios-device/lib/libtiff.a" \ + -DGDAL_INCLUDE_DIR:PATH="$THIRDPARTY_PATH/gdal-ios-device/include" \ + -DGDAL_LIBRARY:PATH="$THIRDPARTY_PATH/gdal-ios-device/lib/libgdal.a" -### Section 3. Release notes on iOS build, by Thomas Hogarth +Be sure to set the THIRDPARTY_PATH to the path containing your thirdparty dependencies. Set IPHONE_SDKVER to the version of the iOS sdk you have installed, in this instance 10.2. IPHONE_VERSION_MIN controls the base sdk used by xcode, and lastly set OPENGL_PROFILE to the version of GLES you want to use. -With CMake, XCode and the iOS sdk installed you can generate an iOS XCode -project using the following command line - - -export THIRDPARTY_PATH=/path/to/my/3rdParty -cmake ./ -G Xcode -DOSG_BUILD_PLATFORM_IPHONE:BOOL=ON \ --DIPHONE_SDKVER="10.2" \ --DIPHONE_VERSION_MIN="8.0" \ --DOPENGL_PROFILE:STRING=GLES2 \ --DBUILD_OSG_APPLICATIONS:BOOL=OFF \ --DBUILD_OSG_EXAMPLES:BOOL=ON \ --DOSG_WINDOWING_SYSTEM:STRING=IOS \ --DOSG_DEFAULT_IMAGE_PLUGIN_FOR_OSX="imageio" \ --DDYNAMIC_OPENSCENEGRAPH:BOOL=OFF \ --DDYNAMIC_OPENTHREADS:BOOL=OFF \ --DCURL_INCLUDE_DIR:PATH="$THIRDPARTY_PATH/curl-ios-device/include" \ --DCURL_LIBRARY:PATH="$THIRDPARTY_PATH/curl-ios-device/lib/libcurl.a" \ --DFREETYPE_INCLUDE_DIR_freetype2:PATH="$THIRDPARTY_PATH/freetype-ios-universal/include/freetype" \ --DFREETYPE_INCLUDE_DIR_ft2build:PATH="$THIRDPARTY_PATH/freetype-ios-universal/include" \ --DFREETYPE_LIBRARY:PATH="$THIRDPARTY_PATH/freetype-ios-universal/lib/libFreeType_iphone_universal.a" \ --DTIFF_INCLUDE_DIR:PATH="$THIRDPARTY_PATH/tiff-ios-device/include" \ --DTIFF_LIBRARY:PATH="$THIRDPARTY_PATH/tiff-ios-device/lib/libtiff.a" \ --DGDAL_INCLUDE_DIR:PATH="$THIRDPARTY_PATH/gdal-ios-device/include" \ --DGDAL_LIBRARY:PATH="$THIRDPARTY_PATH/gdal-ios-device/lib/libgdal.a" - - -Be sure to set the THIRDPARTY_PATH to the path containing your thirdparty -dependancies. Set IPHONE_SDKVER to the version of the iOS sdk you have -installed, in this instance 10.2. IPHONE_VERSION_MIN controls the base sdk -used by xcode, and lastly set OPENGL_PROFILE to the version of GLES you want -to use. - -Once this completes an XCode project will have been generated in the osg root -folder. Open the generated Xcode project, select the example_osgViewerIPhone -target. In 'General' tab set a development team. In the 'Build Settings' tab -search for 'Other Linker Flags', then for each target type (debug, release etc) -that you want to use open the list of arguments and delete the 'OpenGL' line -and the '-framework' line above it. This is because cmake has tried to add the -desktop OpenGL library which we don't want. - -Once this is done you should be able to build and deploy the example_osgViewerIPhone -target on your device. +Once this completes an XCode project will have been generated in the osg root folder. Open the generated Xcode project, select the example_osgViewerIPhone target. In 'General' tab set a development team. In the 'Build Settings' tab search for 'Other Linker Flags', then for each target type (debug, release etc) that you want to use open the list of arguments and delete the 'OpenGL' line and the '-framework' line above it. This is because cmake has tried to add the desktop OpenGL library which we don't want. +Once this is done you should be able to build and deploy the `example_osgViewerIPhone` target on your device. \ No newline at end of file From c5450394b0685f0f249a1c26c05d3e63e488fe75 Mon Sep 17 00:00:00 2001 From: Ulrich Hertlein Date: Sun, 23 Apr 2017 15:36:11 +0200 Subject: [PATCH 3/3] RAII memory management for macOS image loading - use std::vector instead of manual memory management - removes dead/commented code --- .../imageio/ReaderWriterImageIO.cpp | 173 +++++++----------- 1 file changed, 67 insertions(+), 106 deletions(-) diff --git a/src/osgPlugins/imageio/ReaderWriterImageIO.cpp b/src/osgPlugins/imageio/ReaderWriterImageIO.cpp index 1ded6047b..36d737bea 100644 --- a/src/osgPlugins/imageio/ReaderWriterImageIO.cpp +++ b/src/osgPlugins/imageio/ReaderWriterImageIO.cpp @@ -1,3 +1,8 @@ +// REVIEW: +// +// virtual bool acceptsExtension(const std::string& extension) const +// Don't override acceptsExtension, the base class checks the list of supported extensions + // Copyright Eric Wing // This plugin is the bridge to OS X's ImageIO framework // which provides access to all of Apple's supported image types. @@ -269,7 +274,6 @@ osg::Image* CreateOSGImageFromCGImage(CGImageRef image_ref) size_t bits_per_pixel = CGImageGetBitsPerPixel(image_ref); size_t bytes_per_row = CGImageGetBytesPerRow(image_ref); -// size_t bits_per_component = CGImageGetBitsPerComponent(image_ref); size_t bits_per_component = 8; CGImageAlphaInfo alpha_info = CGImageGetAlphaInfo(image_ref); @@ -278,8 +282,6 @@ osg::Image* CreateOSGImageFromCGImage(CGImageRef image_ref) GLenum pixel_format; GLenum data_type; - void* image_data = calloc(the_width * 4, the_height); - CGColorSpaceRef color_space; CGBitmapInfo bitmap_info = CGImageGetBitmapInfo(image_ref); @@ -289,7 +291,6 @@ osg::Image* CreateOSGImageFromCGImage(CGImageRef image_ref) // between a 256 color GIF, a LUMINANCE map // or an ALPHA map? case 8: - { // I probably did the formats all wrong for this case, // especially the ALPHA case. if(kCGImageAlphaNone == alpha_info) @@ -303,9 +304,8 @@ osg::Image* CreateOSGImageFromCGImage(CGImageRef image_ref) data_type = GL_UNSIGNED_INT_8_8_8_8_REV; bytes_per_row = the_width*4; -// color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); color_space = CGColorSpaceCreateDeviceRGB(); -// bitmap_info = kCGImageAlphaPremultipliedFirst; + #if __BIG_ENDIAN__ bitmap_info = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Big; /* XRGB Big Endian */ #else @@ -317,29 +317,25 @@ osg::Image* CreateOSGImageFromCGImage(CGImageRef image_ref) internal_format = GL_ALPHA; pixel_format = GL_ALPHA; data_type = GL_UNSIGNED_BYTE; - // bytes_per_row = the_width; -// color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericGray); + //bytes_per_row = the_width; color_space = CGColorSpaceCreateDeviceGray(); } - break; - } + case 24: - { internal_format = GL_RGBA8; pixel_format = GL_BGRA_EXT; data_type = GL_UNSIGNED_INT_8_8_8_8_REV; bytes_per_row = the_width*4; -// color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); color_space = CGColorSpaceCreateDeviceRGB(); -// bitmap_info = kCGImageAlphaNone; + #if __BIG_ENDIAN__ bitmap_info = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Big; /* XRGB Big Endian */ #else bitmap_info = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little; /* XRGB Little Endian */ #endif break; - } + // // Tatsuhiro Nishioka // 16 bpp grayscale (8 bit white and 8 bit alpha) causes invalid argument combination @@ -351,16 +347,12 @@ osg::Image* CreateOSGImageFromCGImage(CGImageRef image_ref) case 32: case 48: case 64: - { - internal_format = GL_RGBA8; pixel_format = GL_BGRA_EXT; data_type = GL_UNSIGNED_INT_8_8_8_8_REV; bytes_per_row = the_width*4; -// color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); color_space = CGColorSpaceCreateDeviceRGB(); -// bitmap_info = kCGImageAlphaPremultipliedFirst; #if __BIG_ENDIAN__ bitmap_info = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Big; /* XRGB Big Endian */ @@ -368,16 +360,17 @@ osg::Image* CreateOSGImageFromCGImage(CGImageRef image_ref) bitmap_info = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little; /* XRGB Little Endian */ #endif break; - } - default: - { - // OSG_WARN << "Unknown file type in " << fileName.c_str() << " with " << origDepth << std::endl; - return NULL; - break; - } + default: + OSG_WARN << "Unsupported pixel depth " << bits_per_pixel << std::endl; + return NULL; } + void* image_data = calloc(the_width * 4, the_height); + if (!image_data) { + OSG_WARN << "Failed to allocate image data size " << the_width << "x" << the_height << std::endl; + return NULL; + } // Sets up a context to be drawn to with image_data as the area to be drawn to CGContextRef bitmap_context = CGBitmapContextCreate( @@ -390,18 +383,17 @@ osg::Image* CreateOSGImageFromCGImage(CGImageRef image_ref) bitmap_info ); + // Swap upside-down CGContextTranslateCTM(bitmap_context, 0, the_height); CGContextScaleCTM(bitmap_context, 1.0, -1.0); + // Draws the image into the context's image_data CGContextDrawImage(bitmap_context, the_rect, image_ref); CGContextRelease(bitmap_context); - - if (!image_data) - return NULL; + CGColorSpaceRelease(color_space); // alpha is premultiplied with rgba, undo it - vImage_Buffer vb; vb.data = image_data; vb.height = the_height; @@ -410,7 +402,6 @@ osg::Image* CreateOSGImageFromCGImage(CGImageRef image_ref) vImageUnpremultiplyData_RGBA8888(&vb, &vb, 0); // changing it to GL_UNSIGNED_BYTE seems working, but I'm not sure if this is a right way. - // data_type = GL_UNSIGNED_BYTE; osg::Image* osg_image = new osg::Image; @@ -426,10 +417,8 @@ osg::Image* CreateOSGImageFromCGImage(CGImageRef image_ref) ); return osg_image; - - - } + /************************************************************** ***** End Support functions for reading (stream and file) ***** **************************************************************/ @@ -477,7 +466,7 @@ CGImageRef CreateCGImageFromOSGData(const osg::Image& osg_image) osg_image.getRowSizeInBytes() }; - void* out_image_data; + std::vector out_image_data; vImage_Buffer vimage_buffer_out = { NULL, // will fill-in in switch @@ -491,26 +480,24 @@ CGImageRef CreateCGImageFromOSGData(const osg::Image& osg_image) switch(osg_image.getPixelFormat()) { case GL_LUMINANCE: - { bitmap_info = kCGImageAlphaNone; target_bytes_per_row = (image_width * 8 + 7)/8; - //color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericGray); color_space = CGColorSpaceCreateDeviceGray(); if(NULL == color_space) { return NULL; } - // out_image_data = calloc(target_bytes_per_row, image_height); - out_image_data = malloc(target_bytes_per_row * image_height); - if(NULL == out_image_data) - { - OSG_WARN << "In CreateCGImageFromOSGData, malloc failed" << std::endl; + try { + out_image_data.resize(target_bytes_per_row * image_height); + } + catch (std::exception&) { + OSG_WARN << "In CreateCGImageFromOSGData, resize failed" << std::endl; CGColorSpaceRelease(color_space); return NULL; } - vimage_buffer_out.data = out_image_data; + vimage_buffer_out.data = &out_image_data[0]; vimage_buffer_out.rowBytes = target_bytes_per_row; // Now invert the image @@ -522,16 +509,12 @@ CGImageRef CreateCGImageFromOSGData(const osg::Image& osg_image) if(vimage_error_flag != kvImageNoError) { OSG_WARN << "In CreateCGImageFromOSGData for GL_LUMINANCE, vImageVerticalReflect_Planar8 failed with vImage Error Code: " << vimage_error_flag << std::endl; - free(out_image_data); CGColorSpaceRelease(color_space); return NULL; } - - break; - } + case GL_ALPHA: - { bitmap_info = kCGImageAlphaOnly; target_bytes_per_row = (image_width * 8 + 7)/8; // According to: @@ -539,15 +522,15 @@ CGImageRef CreateCGImageFromOSGData(const osg::Image& osg_image) // colorSpace=NULL is for alpha only color_space = NULL; - // out_image_data = calloc(target_bytes_per_row, image_height); - out_image_data = malloc(target_bytes_per_row * image_height); - if(NULL == out_image_data) - { - OSG_WARN << "In CreateCGImageFromOSGData, malloc failed" << std::endl; + try { + out_image_data.resize(target_bytes_per_row * image_height); + } + catch (std::exception&) { + OSG_WARN << "In CreateCGImageFromOSGData, resize failed" << std::endl; return NULL; } - vimage_buffer_out.data = out_image_data; + vimage_buffer_out.data = &out_image_data[0]; vimage_buffer_out.rowBytes = target_bytes_per_row; // Now invert the image @@ -559,44 +542,31 @@ CGImageRef CreateCGImageFromOSGData(const osg::Image& osg_image) if(vimage_error_flag != kvImageNoError) { OSG_WARN << "In CreateCGImageFromOSGData for GL_ALPHA, vImageVerticalReflect_Planar8 failed with vImage Error Code: " << vimage_error_flag << std::endl; - free(out_image_data); return NULL; } - - break; - } -/* - case GL_LUMINANCE_ALPHA: - { - // I don't know if we can support this. - // The qa1037 doesn't show both gray+alpha. - break; - } -*/ + case GL_RGB: - { bitmap_info = kCGImageAlphaNoneSkipFirst; target_bytes_per_row = (image_width * 8 * 4 + 7)/8; - //color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); color_space = CGColorSpaceCreateDeviceRGB(); - if(NULL == color_space) + if(NULL == color_space) { OSG_WARN << "In CreateCGImageFromOSGData, CGColorSpaceCreateWithName failed" << std::endl; return NULL; } - // out_image_data = calloc(target_bytes_per_row, image_height); - out_image_data = malloc(target_bytes_per_row * image_height); - if(NULL == out_image_data) - { - OSG_WARN << "In CreateCGImageFromOSGData, malloc failed" << std::endl; + try { + out_image_data.resize(target_bytes_per_row * image_height); + } + catch (std::exception&) { + OSG_WARN << "In CreateCGImageFromOSGData, resize failed" << std::endl; CGColorSpaceRelease(color_space); return NULL; } // Use vImage to get an RGB buffer into ARGB. - vimage_buffer_out.data = out_image_data; + vimage_buffer_out.data = &out_image_data[0]; vimage_buffer_out.rowBytes = target_bytes_per_row; vimage_error_flag = vImageConvert_RGB888toARGB8888( &vimage_buffer_in, @@ -609,7 +579,6 @@ CGImageRef CreateCGImageFromOSGData(const osg::Image& osg_image) if(vimage_error_flag != kvImageNoError) { OSG_WARN << "In CreateCGImageFromOSGData, vImageConvert_RGB888toARGB8888 failed with vImage Error Code: " << vimage_error_flag << std::endl; - free(out_image_data); CGColorSpaceRelease(color_space); return NULL; } @@ -622,34 +591,33 @@ CGImageRef CreateCGImageFromOSGData(const osg::Image& osg_image) if(vimage_error_flag != kvImageNoError) { OSG_WARN << "In CreateCGImageFromOSGData, vImageAffineWarp_ARGB8888 failed with vImage Error Code: " << vimage_error_flag << std::endl; - free(out_image_data); CGColorSpaceRelease(color_space); return NULL; } - break; - } + case GL_RGBA: - { bitmap_info = kCGImageAlphaPremultipliedLast; target_bytes_per_row = osg_image.getRowSizeInBytes(); - //color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); color_space = CGColorSpaceCreateDeviceRGB(); if(NULL == color_space) { OSG_WARN << "In CreateCGImageFromOSGData, CGColorSpaceCreateWithName failed" << std::endl; return NULL; } - // out_image_data = calloc(target_bytes_per_row, image_height); - out_image_data = malloc(target_bytes_per_row * image_height); - if(NULL == out_image_data) - { - OSG_WARN << "In CreateCGImageFromOSGData, malloc failed" << std::endl; + + try { + out_image_data.resize(target_bytes_per_row * image_height); + } + catch (std::exception&) { + OSG_WARN << "In CreateCGImageFromOSGData, resize failed" << std::endl; CGColorSpaceRelease(color_space); return NULL; } - vimage_buffer_out.data = out_image_data; + + vimage_buffer_out.data = &out_image_data[0]; vimage_buffer_out.rowBytes = target_bytes_per_row; + // Invert the image vimage_error_flag = vImageVerticalReflect_ARGB8888( &vimage_buffer_in, // since the osg_image is const... @@ -659,14 +627,12 @@ CGImageRef CreateCGImageFromOSGData(const osg::Image& osg_image) if(vimage_error_flag != kvImageNoError) { OSG_WARN << "In CreateCGImageFromOSGData, vImageAffineWarp_ARGB8888 failed with vImage Error Code: " << vimage_error_flag << std::endl; - free(out_image_data); CGColorSpaceRelease(color_space); return NULL; } break; - } + case GL_BGRA: - { if(GL_UNSIGNED_INT_8_8_8_8_REV == osg_image.getDataType()) { #if __BIG_ENDIAN__ @@ -682,23 +648,25 @@ CGImageRef CreateCGImageFromOSGData(const osg::Image& osg_image) } target_bytes_per_row = osg_image.getRowSizeInBytes(); - //color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); color_space = CGColorSpaceCreateDeviceRGB(); if(NULL == color_space) { OSG_WARN << "In CreateCGImageFromOSGData, CGColorSpaceCreateWithName failed" << std::endl; return NULL; } - // out_image_data = calloc(target_bytes_per_row, image_height); - out_image_data = malloc(target_bytes_per_row * image_height); - if(NULL == out_image_data) - { - OSG_WARN << "In CreateCGImageFromOSGData, malloc failed" << std::endl; + + try { + out_image_data.resize(target_bytes_per_row * image_height); + } + catch (std::exception&) { + OSG_WARN << "In CreateCGImageFromOSGData, resize failed" << std::endl; CGColorSpaceRelease(color_space); return NULL; } - vimage_buffer_out.data = out_image_data; + + vimage_buffer_out.data = &out_image_data[0]; vimage_buffer_out.rowBytes = target_bytes_per_row; + // Invert the image vimage_error_flag = vImageVerticalReflect_ARGB8888( &vimage_buffer_in, // since the osg_image is const... @@ -708,20 +676,17 @@ CGImageRef CreateCGImageFromOSGData(const osg::Image& osg_image) if(vimage_error_flag != kvImageNoError) { OSG_WARN << "In CreateCGImageFromOSGData, vImageAffineWarp_ARGB8888 failed with vImage Error Code: " << vimage_error_flag << std::endl; - free(out_image_data); CGColorSpaceRelease(color_space); return NULL; } break; - } + // FIXME: Handle other cases. // Use vImagePermuteChannels_ARGB8888 to swizzle bytes + case GL_LUMINANCE_ALPHA: default: - { OSG_WARN << "In CreateCGImageFromOSGData: Sorry support for this format is not implemented." << std::endl; return NULL; - break; - } } CGContextRef bitmap_context = CGBitmapContextCreate( @@ -733,22 +698,18 @@ CGImageRef CreateCGImageFromOSGData(const osg::Image& osg_image) color_space, bitmap_info ); + /* Done with color space */ CGColorSpaceRelease(color_space); if(NULL == bitmap_context) { - free(out_image_data); return NULL; } - /* Make an image out of our bitmap; does a cheap vm_copy of the bitmap */ CGImageRef image_ref = CGBitmapContextCreateImage(bitmap_context); - /* Done with data */ - free(out_image_data); - /* Done with bitmap_context */ CGContextRelease(bitmap_context);