diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj b/build/cocos2d_libs.xcodeproj/project.pbxproj index 138951d22f..e4555d5cbe 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj @@ -690,6 +690,10 @@ 464AD6E6197EBB1400E502D8 /* pvr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 464AD6E3197EBB1400E502D8 /* pvr.cpp */; }; 464AD6E7197EBB1400E502D8 /* pvr.h in Headers */ = {isa = PBXBuildFile; fileRef = 464AD6E4197EBB1400E502D8 /* pvr.h */; }; 464AD6E8197EBB1400E502D8 /* pvr.h in Headers */ = {isa = PBXBuildFile; fileRef = 464AD6E4197EBB1400E502D8 /* pvr.h */; }; + 46633BC4199DDB2F00F6E838 /* CCModuleManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46633BC2199DDB2F00F6E838 /* CCModuleManager.cpp */; }; + 46633BC5199DDB2F00F6E838 /* CCModuleManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46633BC2199DDB2F00F6E838 /* CCModuleManager.cpp */; }; + 46633BC6199DDB2F00F6E838 /* CCModuleManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46633BC3199DDB2F00F6E838 /* CCModuleManager.h */; }; + 46633BC7199DDB2F00F6E838 /* CCModuleManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46633BC3199DDB2F00F6E838 /* CCModuleManager.h */; }; 46A160421807A5D4005B8026 /* Export.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A15FE11807A56F005B8026 /* Export.h */; }; 46A160431807A5D4005B8026 /* SimpleAudioEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A15FE21807A56F005B8026 /* SimpleAudioEngine.h */; }; 46A160441807A5D4005B8026 /* CDAudioManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A15FF41807A56F005B8026 /* CDAudioManager.h */; }; @@ -2505,6 +2509,8 @@ 3EA4786F195478E00068D9D1 /* CCBundleReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCBundleReader.h; sourceTree = ""; }; 464AD6E3197EBB1400E502D8 /* pvr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pvr.cpp; path = ../base/pvr.cpp; sourceTree = ""; }; 464AD6E4197EBB1400E502D8 /* pvr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pvr.h; path = ../base/pvr.h; sourceTree = ""; }; + 46633BC2199DDB2F00F6E838 /* CCModuleManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CCModuleManager.cpp; path = ../base/CCModuleManager.cpp; sourceTree = ""; }; + 46633BC3199DDB2F00F6E838 /* CCModuleManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CCModuleManager.h; path = ../base/CCModuleManager.h; sourceTree = ""; }; 46A15FCC1807A544005B8026 /* AUTHORS */ = {isa = PBXFileReference; lastKnownFileType = text; name = AUTHORS; path = ../AUTHORS; sourceTree = ""; }; 46A15FCE1807A544005B8026 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = text; name = README.md; path = ../README.md; sourceTree = ""; }; 46A15FE11807A56F005B8026 /* Export.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Export.h; sourceTree = ""; }; @@ -3411,6 +3417,8 @@ 1A570095180BC5B00088DEC7 /* base-nodes */ = { isa = PBXGroup; children = ( + 46633BC2199DDB2F00F6E838 /* CCModuleManager.cpp */, + 46633BC3199DDB2F00F6E838 /* CCModuleManager.h */, 15EFA20F198A2BB5000C57D3 /* CCProtectedNode.cpp */, 15EFA210198A2BB5000C57D3 /* CCProtectedNode.h */, 1A57009C180BC5D20088DEC7 /* CCNode.cpp */, @@ -5280,6 +5288,7 @@ 1ABA68B01888D700007D1BB4 /* CCFontCharMap.h in Headers */, 5034CA3F191D591100CE6051 /* ccShader_Position_uColor.vert in Headers */, 50ABBD461925AB0000A911A9 /* CCVertex.h in Headers */, + 46633BC6199DDB2F00F6E838 /* CCModuleManager.h in Headers */, 46A170E71807CECA005B8026 /* CCPhysicsBody.h in Headers */, 46A170EB1807CECA005B8026 /* CCPhysicsJoint.h in Headers */, 50ABBD3E1925AB0000A911A9 /* CCGeometry.h in Headers */, @@ -5664,6 +5673,7 @@ 50ABC0041926664800A911A9 /* CCLock.h in Headers */, 5034CA40191D591100CE6051 /* ccShader_Position_uColor.vert in Headers */, 50ABBEC21925AB6F00A911A9 /* CCValue.h in Headers */, + 46633BC7199DDB2F00F6E838 /* CCModuleManager.h in Headers */, 50ABBECA1925AB6F00A911A9 /* firePngData.h in Headers */, B257B4511989D5E800D9A687 /* CCPrimitive.h in Headers */, 50ABBE401925AB6F00A911A9 /* CCDataVisitor.h in Headers */, @@ -6821,6 +6831,7 @@ 50ABBE651925AB6F00A911A9 /* CCEventListenerCustom.cpp in Sources */, B37510781823AC9F00B3BA6A /* CCPhysicsShapeInfo_chipmunk.cpp in Sources */, 50ABBE391925AB6F00A911A9 /* CCData.cpp in Sources */, + 46633BC4199DDB2F00F6E838 /* CCModuleManager.cpp in Sources */, 1A57010E180BC8EE0088DEC7 /* CCDrawingPrimitives.cpp in Sources */, 50ABBED71925AB6F00A911A9 /* ZipUtils.cpp in Sources */, 1A01C68418F57BE800EFE3A6 /* CCArray.cpp in Sources */, @@ -7228,6 +7239,7 @@ 50ABBE8C1925AB6F00A911A9 /* CCNS.cpp in Sources */, 50ABBDAE1925AB4100A911A9 /* CCRenderer.cpp in Sources */, 50ABBDBA1925AB4100A911A9 /* CCTextureAtlas.cpp in Sources */, + 46633BC5199DDB2F00F6E838 /* CCModuleManager.cpp in Sources */, 1A5702FB180BCE750088DEC7 /* CCTMXXMLParser.cpp in Sources */, 1A570301180BCE890088DEC7 /* CCParallaxNode.cpp in Sources */, 1A57030D180BCF190088DEC7 /* CCComponent.cpp in Sources */, diff --git a/cocos/Android.mk b/cocos/Android.mk index 471ef20ff7..32b0039a16 100644 --- a/cocos/Android.mk +++ b/cocos/Android.mk @@ -127,6 +127,7 @@ base/CCEventListenerTouch.cpp \ base/CCEventMouse.cpp \ base/CCEventTouch.cpp \ base/CCIMEDispatcher.cpp \ +base/CCModuleManager.cpp \ base/CCNS.cpp \ base/CCProfiling.cpp \ base/CCRef.cpp \ @@ -226,9 +227,6 @@ LOCAL_WHOLE_STATIC_LIBRARIES := cocos_freetype2_static LOCAL_WHOLE_STATIC_LIBRARIES += chipmunk_static LOCAL_WHOLE_STATIC_LIBRARIES += cocos2dxandroid_static LOCAL_WHOLE_STATIC_LIBRARIES += cocos_png_static -LOCAL_WHOLE_STATIC_LIBRARIES += cocos_jpeg_static -LOCAL_WHOLE_STATIC_LIBRARIES += cocos_tiff_static -LOCAL_WHOLE_STATIC_LIBRARIES += cocos_webp_static # define the macro to compile through support/zip_support/ioapi.c LOCAL_CFLAGS := -DUSE_FILE32API @@ -241,7 +239,4 @@ include $(BUILD_STATIC_LIBRARY) $(call import-module,freetype2/prebuilt/android) $(call import-module,chipmunk) $(call import-module,platform/android) -$(call import-module,jpeg/prebuilt/android) $(call import-module,png/prebuilt/android) -$(call import-module,tiff/prebuilt/android) -$(call import-module,webp/prebuilt/android) diff --git a/cocos/base/CCModuleManager.cpp b/cocos/base/CCModuleManager.cpp new file mode 100644 index 0000000000..d6a8d9b681 --- /dev/null +++ b/cocos/base/CCModuleManager.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** + Copyright (c) 2014 cocos2d-x.org + + http://www.cocos2d-x.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + ****************************************************************************/ + +#include "base/CCModuleManager.h" +#include +#include "base/CCConsole.h" + +using namespace std; + +//RegisterJPEG *temp = new RegisterJPEG(); + +NS_CC_BEGIN + +void ModuleManager::registerModule(const string &moduleName, void* module) +{ + auto &moduleMap = createMap(); + if (moduleMap.find(moduleName) != moduleMap.end()) + { + CCLOG("module: %s exists", moduleName.c_str()); + return; + } + + moduleMap[moduleName] = module; +} + +void ModuleManager::unRegisterModule(const string &moduleName) +{ + auto &moduleMap = createMap(); + moduleMap.erase(moduleName); +} + +void* ModuleManager::getModule(const string &moduleName) +{ + auto &moduleMap = createMap(); + auto result = moduleMap.find(moduleName); + if (result != moduleMap.end()) + { + return result->second; + } + else + return nullptr; +} + +unordered_map& ModuleManager::createMap() +{ + static unordered_map map; + return map; +} + +NS_CC_END diff --git a/cocos/base/CCModuleManager.h b/cocos/base/CCModuleManager.h new file mode 100644 index 0000000000..c6ec6f1268 --- /dev/null +++ b/cocos/base/CCModuleManager.h @@ -0,0 +1,50 @@ +/**************************************************************************** + Copyright (c) 2014 cocos2d-x.org + + http://www.cocos2d-x.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + ****************************************************************************/ + +#ifndef __BASE_CC_MODULE_MANAGER__ +#define __BASE_CC_MODULE_MANAGER__ + +#include +#include + +#include "base/CCPlatformMacros.h" + + +NS_CC_BEGIN + +class CC_DLL ModuleManager +{ +public: + static void registerModule(const std::string &moduleName, void* module); + static void unRegisterModule(const std::string &moduleName); + static void* getModule(const std::string &moduleName); + +private: + static std::unordered_map& createMap(); +}; + +NS_CC_END + +#endif + diff --git a/cocos/platform/CCImage.cpp b/cocos/platform/CCImage.cpp index 08cd3e5f10..80ba8e672b 100644 --- a/cocos/platform/CCImage.cpp +++ b/cocos/platform/CCImage.cpp @@ -31,12 +31,6 @@ THE SOFTWARE. #include "base/CCData.h" - -#ifdef EMSCRIPTEN -#include -#include -#endif // EMSCRIPTEN - extern "C" { // To resolve link error when building 32bits with Xcode 6. @@ -57,22 +51,21 @@ extern "C" { return strerror(errnum); } + // int fputs(const char * __restrict, FILE * __restrict) __DARWIN_ALIAS(fputs); + int fputs$UNIX2003(const char *str, FILE *stream) + { + return fputs(str, stream); + } #endif #endif #include "png.h" -#include "tiffio.h" #include "base/etc1.h" -#include "jpeglib.h" } #include "base/s3tc.h" #include "base/atitc.h" #include "base/pvr.h" #include "base/TGAlib.h" -#if (CC_TARGET_PLATFORM != CC_PLATFORM_WP8) && (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT) -#include "decode.h" -#endif - #include "base/ccMacros.h" #include "CCCommon.h" #include "CCStdC.h" @@ -80,6 +73,7 @@ extern "C" #include "base/CCConfiguration.h" #include "base/ccUtils.h" #include "base/ZipUtils.h" +#include "base/CCModuleManager.h" #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) #include "android/CCFileUtilsAndroid.h" #endif @@ -96,7 +90,6 @@ NS_CC_BEGIN namespace { static const int PVR_TEXTURE_FLAG_TYPE_MASK = 0xff; - static bool _PVRHaveAlphaPremultiplied = false; // Values taken from PVRTexture.h from http://www.imgtec.com @@ -759,158 +752,28 @@ bool Image::isCompressed() return Texture2D::getPixelFormatInfoMap().at(_renderFormat).compressed; } -namespace -{ -/* - * ERROR HANDLING: - * - * The JPEG library's standard error handler (jerror.c) is divided into - * several "methods" which you can override individually. This lets you - * adjust the behavior without duplicating a lot of code, which you might - * have to update with each future release. - * - * We override the "error_exit" method so that control is returned to the - * library's caller when a fatal error occurs, rather than calling exit() - * as the standard error_exit method does. - * - * We use C's setjmp/longjmp facility to return control. This means that the - * routine which calls the JPEG library must first execute a setjmp() call to - * establish the return point. We want the replacement error_exit to do a - * longjmp(). But we need to make the setjmp buffer accessible to the - * error_exit routine. To do this, we make a private extension of the - * standard JPEG error handler object. (If we were using C++, we'd say we - * were making a subclass of the regular error handler.) - * - * Here's the extended error handler struct: - */ - struct MyErrorMgr - { - struct jpeg_error_mgr pub; /* "public" fields */ - jmp_buf setjmp_buffer; /* for return to caller */ - }; - - typedef struct MyErrorMgr * MyErrorPtr; - - /* - * Here's the routine that will replace the standard error_exit method: - */ - - METHODDEF(void) - myErrorExit(j_common_ptr cinfo) - { - /* cinfo->err really points to a MyErrorMgr struct, so coerce pointer */ - MyErrorPtr myerr = (MyErrorPtr) cinfo->err; - - /* Always display the message. */ - /* We could postpone this until after returning, if we chose. */ - /* internal message function cann't show error message in some platforms, so we rewrite it here. - * edit it if has version confilict. - */ - //(*cinfo->err->output_message) (cinfo); - char buffer[JMSG_LENGTH_MAX]; - (*cinfo->err->format_message) (cinfo, buffer); - CCLOG("jpeg error: %s", buffer); - - /* Return control to the setjmp point */ - longjmp(myerr->setjmp_buffer, 1); - } -} - bool Image::initWithJpgData(const unsigned char * data, ssize_t dataLen) { - /* these are standard libjpeg structures for reading(decompression) */ - struct jpeg_decompress_struct cinfo; - /* We use our private extension JPEG error handler. - * Note that this struct must live as long as the main JPEG parameter - * struct, to avoid dangling-pointer problems. - */ - struct MyErrorMgr jerr; - /* libjpeg data structure for storing one row, that is, scanline of an image */ - JSAMPROW row_pointer[1] = {0}; - unsigned long location = 0; - unsigned int i = 0; - - bool bRet = false; - do + _hasPremultipliedAlpha = false; + + JPEGModule *jpegModule = static_cast(ModuleManager::getModule("jpeg")); + if (jpegModule) { - /* We set up the normal JPEG error routines, then override error_exit. */ - cinfo.err = jpeg_std_error(&jerr.pub); - jerr.pub.error_exit = myErrorExit; - /* Establish the setjmp return context for MyErrorExit to use. */ - if (setjmp(jerr.setjmp_buffer)) { - /* If we get here, the JPEG code has signaled an error. - * We need to clean up the JPEG object, close the input file, and return. - */ - jpeg_destroy_decompress(&cinfo); - break; - } - - /* setup decompression process and source, then read JPEG header */ - jpeg_create_decompress( &cinfo ); - -#ifndef CC_TARGET_QT5 - jpeg_mem_src( &cinfo, const_cast(data), dataLen ); -#endif /* CC_TARGET_QT5 */ - - /* reading the image header which contains image information */ -#if (JPEG_LIB_VERSION >= 90) - // libjpeg 0.9 adds stricter types. - jpeg_read_header( &cinfo, TRUE ); -#else - jpeg_read_header( &cinfo, true ); -#endif - - // we only support RGB or grayscale - if (cinfo.jpeg_color_space == JCS_GRAYSCALE) - { - _renderFormat = Texture2D::PixelFormat::I8; - }else - { - cinfo.out_color_space = JCS_RGB; - _renderFormat = Texture2D::PixelFormat::RGB888; - } - - /* Start decompression jpeg here */ - jpeg_start_decompress( &cinfo ); - - /* init image info */ - _width = cinfo.output_width; - _height = cinfo.output_height; - _hasPremultipliedAlpha = false; - row_pointer[0] = static_cast(malloc(cinfo.output_width*cinfo.output_components * sizeof(unsigned char))); - CC_BREAK_IF(! row_pointer[0]); - - _dataLen = cinfo.output_width*cinfo.output_height*cinfo.output_components; - _data = static_cast(malloc(_dataLen * sizeof(unsigned char))); - CC_BREAK_IF(! _data); - - /* now actually read the jpeg into the raw buffer */ - /* read one scan line at a time */ - while( cinfo.output_scanline < cinfo.output_height ) - { - jpeg_read_scanlines( &cinfo, row_pointer, 1 ); - for( i=0; iinitWithJPEGData(data, dataLen, dataFromJPEGInit); + _width = dataFromJPEGInit.width; + _height = dataFromJPEGInit.height; + _renderFormat = dataFromJPEGInit.renderFormat; + _dataLen = dataFromJPEGInit.dataLength; + _data = dataFromJPEGInit.data; + + return result; + } + else { - free(row_pointer[0]); - }; - return bRet; + CCLOG("jpeg module is not enabled"); + return false; + } } bool Image::initWithPngData(const unsigned char * data, ssize_t dataLen) @@ -1062,175 +925,28 @@ bool Image::initWithPngData(const unsigned char * data, ssize_t dataLen) return bRet; } -namespace -{ - static tmsize_t tiffReadProc(thandle_t fd, void* buf, tmsize_t size) - { - tImageSource* isource = (tImageSource*)fd; - uint8* ma; - uint64 mb; - unsigned long n; - unsigned long o; - tmsize_t p; - ma=(uint8*)buf; - mb=size; - p=0; - while (mb>0) - { - n=0x80000000UL; - if ((uint64)n>mb) - n=(unsigned long)mb; - - - if((int)(isource->offset + n) <= isource->size) - { - memcpy(ma, isource->data+isource->offset, n); - isource->offset += n; - o = n; - } - else - { - return 0; - } - - ma+=o; - mb-=o; - p+=o; - if (o!=n) - { - break; - } - } - return p; - } - - static tmsize_t tiffWriteProc(thandle_t fd, void* buf, tmsize_t size) - { - CC_UNUSED_PARAM(fd); - CC_UNUSED_PARAM(buf); - CC_UNUSED_PARAM(size); - return 0; - } - - - static uint64 tiffSeekProc(thandle_t fd, uint64 off, int whence) - { - tImageSource* isource = (tImageSource*)fd; - uint64 ret = -1; - do - { - if (whence == SEEK_SET) - { - CC_BREAK_IF(off >= (uint64)isource->size); - ret = isource->offset = (uint32)off; - } - else if (whence == SEEK_CUR) - { - CC_BREAK_IF(isource->offset + off >= (uint64)isource->size); - ret = isource->offset += (uint32)off; - } - else if (whence == SEEK_END) - { - CC_BREAK_IF(off >= (uint64)isource->size); - ret = isource->offset = (uint32)(isource->size-1 - off); - } - else - { - CC_BREAK_IF(off >= (uint64)isource->size); - ret = isource->offset = (uint32)off; - } - } while (0); - - return ret; - } - - static uint64 tiffSizeProc(thandle_t fd) - { - tImageSource* pImageSrc = (tImageSource*)fd; - return pImageSrc->size; - } - - static int tiffCloseProc(thandle_t fd) - { - CC_UNUSED_PARAM(fd); - return 0; - } - - static int tiffMapProc(thandle_t fd, void** pbase, toff_t* psize) - { - CC_UNUSED_PARAM(fd); - CC_UNUSED_PARAM(pbase); - CC_UNUSED_PARAM(psize); - return 0; - } - - static void tiffUnmapProc(thandle_t fd, void* base, toff_t size) - { - CC_UNUSED_PARAM(fd); - CC_UNUSED_PARAM(base); - CC_UNUSED_PARAM(size); - } -} - bool Image::initWithTiffData(const unsigned char * data, ssize_t dataLen) { - bool bRet = false; - do + _hasPremultipliedAlpha = true; + + TIFFModule *tiffModule = static_cast(ModuleManager::getModule("tiff")); + if (tiffModule) { - // set the read call back function - tImageSource imageSource; - imageSource.data = data; - imageSource.size = dataLen; - imageSource.offset = 0; - - TIFF* tif = TIFFClientOpen("file.tif", "r", (thandle_t)&imageSource, - tiffReadProc, tiffWriteProc, - tiffSeekProc, tiffCloseProc, tiffSizeProc, - tiffMapProc, - tiffUnmapProc); - - CC_BREAK_IF(nullptr == tif); - - uint32 w = 0, h = 0; - uint16 bitsPerSample = 0, samplePerPixel = 0, planarConfig = 0; - size_t npixels = 0; + DataFromModule dataFromTIFFInit; + bool result = tiffModule->initWithTIFFData(data, dataLen, dataFromTIFFInit); + _width = dataFromTIFFInit.width; + _height = dataFromTIFFInit.height; + _renderFormat = dataFromTIFFInit.renderFormat; + _dataLen = dataFromTIFFInit.dataLength; + _data = dataFromTIFFInit.data; - TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w); - TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); - TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitsPerSample); - TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplePerPixel); - TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planarConfig); - - npixels = w * h; - - _renderFormat = Texture2D::PixelFormat::RGBA8888; - _width = w; - _height = h; - - _dataLen = npixels * sizeof (uint32); - _data = static_cast(malloc(_dataLen * sizeof(unsigned char))); - - uint32* raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32)); - if (raster != nullptr) - { - if (TIFFReadRGBAImageOriented(tif, w, h, raster, ORIENTATION_TOPLEFT, 0)) - { - /* the raster data is pre-multiplied by the alpha component - after invoking TIFFReadRGBAImageOriented*/ - _hasPremultipliedAlpha = true; - - memcpy(_data, raster, npixels*sizeof (uint32)); - } - - _TIFFfree(raster); - } - - - TIFFClose(tif); - - bRet = true; - } while (0); - return bRet; + return result; + } + else + { + CCLOG("tiff module is not enabled"); + return false; + } } namespace @@ -2011,42 +1727,29 @@ bool Image::initWithPVRData(const unsigned char * data, ssize_t dataLen) bool Image::initWithWebpData(const unsigned char * data, ssize_t dataLen) { - bool bRet = false; - #if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) CCLOG("WEBP image format not supported on WinRT or WP8"); + return false; #else - do - { - WebPDecoderConfig config; - if (WebPInitDecoderConfig(&config) == 0) break; - if (WebPGetFeatures(static_cast(data), dataLen, &config.input) != VP8_STATUS_OK) break; - if (config.input.width == 0 || config.input.height == 0) break; + WEBPModule *webpModule = static_cast(ModuleManager::getModule("webp")); + if (webpModule) + { + DataFromModule dataFromWEBPInit; + bool result = webpModule->initWithWEBPData(data, dataLen, dataFromWEBPInit); + _width = dataFromWEBPInit.width; + _height = dataFromWEBPInit.height; + _renderFormat = dataFromWEBPInit.renderFormat; + _dataLen = dataFromWEBPInit.dataLength; + _data = dataFromWEBPInit.data; - config.output.colorspace = MODE_RGBA; - _renderFormat = Texture2D::PixelFormat::RGBA8888; - _width = config.input.width; - _height = config.input.height; - - _dataLen = _width * _height * 4; - _data = static_cast(malloc(_dataLen * sizeof(unsigned char))); - - config.output.u.RGBA.rgba = static_cast(_data); - config.output.u.RGBA.stride = _width * 4; - config.output.u.RGBA.size = _dataLen; - config.output.is_external_memory = 1; - - if (WebPDecode(static_cast(data), dataLen, &config) != VP8_STATUS_OK) - { - free(_data); - _data = nullptr; - break; - } - - bRet = true; - } while (0); + return result; + } + else + { + CCLOG("webp module is not enabled"); + return false; + } #endif - return bRet; } @@ -2265,82 +1968,16 @@ bool Image::saveImageToPNG(const std::string& filePath, bool isToRGB) } bool Image::saveImageToJPG(const std::string& filePath) { - bool bRet = false; - do + JPEGModule *jpegModule = static_cast(ModuleManager::getModule("jpeg")); + if (jpegModule) { - struct jpeg_compress_struct cinfo; - struct jpeg_error_mgr jerr; - FILE * outfile; /* target file */ - JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ - int row_stride; /* physical row width in image buffer */ - - cinfo.err = jpeg_std_error(&jerr); - /* Now we can initialize the JPEG compression object. */ - jpeg_create_compress(&cinfo); - - CC_BREAK_IF((outfile = fopen(filePath.c_str(), "wb")) == nullptr); - - jpeg_stdio_dest(&cinfo, outfile); - - cinfo.image_width = _width; /* image width and height, in pixels */ - cinfo.image_height = _height; - cinfo.input_components = 3; /* # of color components per pixel */ - cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ - - jpeg_set_defaults(&cinfo); - jpeg_set_quality(&cinfo, 90, TRUE); - - jpeg_start_compress(&cinfo, TRUE); - - row_stride = _width * 3; /* JSAMPLEs per row in image_buffer */ - - if (hasAlpha()) - { - unsigned char *pTempData = static_cast(malloc(_width * _height * 3 * sizeof(unsigned char))); - if (nullptr == pTempData) - { - jpeg_finish_compress(&cinfo); - jpeg_destroy_compress(&cinfo); - fclose(outfile); - break; - } - - for (int i = 0; i < _height; ++i) - { - for (int j = 0; j < _width; ++j) - - { - pTempData[(i * _width + j) * 3] = _data[(i * _width + j) * 4]; - pTempData[(i * _width + j) * 3 + 1] = _data[(i * _width + j) * 4 + 1]; - pTempData[(i * _width + j) * 3 + 2] = _data[(i * _width + j) * 4 + 2]; - } - } - - while (cinfo.next_scanline < cinfo.image_height) { - row_pointer[0] = & pTempData[cinfo.next_scanline * row_stride]; - (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); - } - - if (pTempData != nullptr) - { - free(pTempData); - } - } - else - { - while (cinfo.next_scanline < cinfo.image_height) { - row_pointer[0] = & _data[cinfo.next_scanline * row_stride]; - (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); - } - } - - jpeg_finish_compress(&cinfo); - fclose(outfile); - jpeg_destroy_compress(&cinfo); - - bRet = true; - } while (0); - return bRet; + return jpegModule->saveImage(filePath, this); + } + else + { + CCLOG("jpeg module is not enabled"); + return false; + } } void Image::premultipliedAlpha() @@ -2357,7 +1994,6 @@ void Image::premultipliedAlpha() _hasPremultipliedAlpha = true; } - void Image::setPVRImagesHavePremultipliedAlpha(bool haveAlphaPremultiplied) { _PVRHaveAlphaPremultiplied = haveAlphaPremultiplied; diff --git a/cocos/platform/CCImage.h b/cocos/platform/CCImage.h index 483ea686ff..bb9e8d0014 100644 --- a/cocos/platform/CCImage.h +++ b/cocos/platform/CCImage.h @@ -26,6 +26,8 @@ THE SOFTWARE. #ifndef __CC_IMAGE_H__ #define __CC_IMAGE_H__ +#include +#include #include "base/CCRef.h" #include "renderer/CCTexture2D.h" @@ -167,6 +169,7 @@ protected: void premultipliedAlpha(); + protected: /** @brief Determine how many mipmaps can we have. @@ -212,6 +215,35 @@ protected: bool isATITC(const unsigned char *data, ssize_t dataLen); }; +/* Data returned from jpeg/tiff/webp module initialization + */ +typedef struct DataFromModule +{ + Texture2D::PixelFormat renderFormat; + int width; + int height; + ssize_t dataLength; + unsigned char* data; + bool hasPremultiAlpha; +} DataFromModule; + +struct JPEGModule +{ + std::function saveImage; + std::function initWithJPEGData; +}; + +struct TIFFModule +{ + std::function initWithTIFFData; +}; + +struct WEBPModule +{ + std::function initWithWEBPData; +}; + + // end of platform group /// @}