提交 1461ab41 编写于 作者: A Alexander Alekhin

ipp: added support for updated ICV package

上级 ced81b91
...@@ -127,8 +127,7 @@ OCV_OPTION(WITH_FFMPEG "Include FFMPEG support" ON ...@@ -127,8 +127,7 @@ OCV_OPTION(WITH_FFMPEG "Include FFMPEG support" ON
OCV_OPTION(WITH_GSTREAMER "Include Gstreamer support" ON IF (UNIX AND NOT APPLE AND NOT ANDROID) ) OCV_OPTION(WITH_GSTREAMER "Include Gstreamer support" ON IF (UNIX AND NOT APPLE AND NOT ANDROID) )
OCV_OPTION(WITH_GSTREAMER_0_10 "Enable Gstreamer 0.10 support (instead of 1.x)" OFF ) OCV_OPTION(WITH_GSTREAMER_0_10 "Enable Gstreamer 0.10 support (instead of 1.x)" OFF )
OCV_OPTION(WITH_GTK "Include GTK support" ON IF (UNIX AND NOT APPLE AND NOT ANDROID) ) OCV_OPTION(WITH_GTK "Include GTK support" ON IF (UNIX AND NOT APPLE AND NOT ANDROID) )
OCV_OPTION(WITH_ICV "Include Intel IPP ICV support" ON IF (NOT IOS) ) OCV_OPTION(WITH_IPP "Include Intel IPP support" ON IF (NOT IOS) )
OCV_OPTION(WITH_IPP "Include Intel IPP support" OFF IF (NOT IOS) )
OCV_OPTION(WITH_JASPER "Include JPEG2K support" ON IF (NOT IOS) ) OCV_OPTION(WITH_JASPER "Include JPEG2K support" ON IF (NOT IOS) )
OCV_OPTION(WITH_JPEG "Include JPEG support" ON) OCV_OPTION(WITH_JPEG "Include JPEG support" ON)
OCV_OPTION(WITH_WEBP "Include WebP support" ON IF (NOT IOS) ) OCV_OPTION(WITH_WEBP "Include WebP support" ON IF (NOT IOS) )
...@@ -917,11 +916,11 @@ endif(DEFINED WITH_INTELPERC) ...@@ -917,11 +916,11 @@ endif(DEFINED WITH_INTELPERC)
status("") status("")
status(" Other third-party libraries:") status(" Other third-party libraries:")
if((WITH_IPP OR WITH_ICV) AND HAVE_IPP) if(WITH_IPP AND HAVE_IPP)
status(" Use IPP:" "${IPP_VERSION_STR} [${IPP_VERSION_MAJOR}.${IPP_VERSION_MINOR}.${IPP_VERSION_BUILD}]") status(" Use IPP:" "${IPP_VERSION_STR} [${IPP_VERSION_MAJOR}.${IPP_VERSION_MINOR}.${IPP_VERSION_BUILD}]")
status(" at:" "${IPP_ROOT_DIR}") status(" at:" "${IPP_ROOT_DIR}")
else() else()
status(" Use IPP:" (WITH_IPP OR WITH_ICV) AND NOT HAVE_IPP THEN "IPP not found" ELSE NO) status(" Use IPP:" WITH_IPP AND NOT HAVE_IPP THEN "IPP not found" ELSE NO)
endif() endif()
if(DEFINED WITH_IPP_A) if(DEFINED WITH_IPP_A)
......
...@@ -2,15 +2,12 @@ ...@@ -2,15 +2,12 @@
# The script to detect Intel(R) Integrated Performance Primitives (IPP) # The script to detect Intel(R) Integrated Performance Primitives (IPP)
# installation/package # installation/package
# #
# Windows host: # By default, ICV version will be used.
# Run script like this before cmake: # To use standalone IPP update cmake command line:
# call "<IPP_INSTALL_DIR>\bin\ippvars.bat" intel64 # cmake ... -DIPPROOT=<path> ...
# for example: #
# call "C:\Program Files (x86)\Intel\Composer XE\ipp\bin\ippvars.bat" intel64 # Note: Backward compatibility is broken, IPPROOT environment path is ignored
# #
# Linux host:
# Run script like this before cmake:
# source /opt/intel/ipp/bin/ippvars.sh [ia32|intel64]
# #
# On return this will define: # On return this will define:
# #
...@@ -39,14 +36,6 @@ unset(IPP_VERSION_BUILD) ...@@ -39,14 +36,6 @@ unset(IPP_VERSION_BUILD)
set(IPP_LIB_PREFIX ${CMAKE_STATIC_LIBRARY_PREFIX}) set(IPP_LIB_PREFIX ${CMAKE_STATIC_LIBRARY_PREFIX})
set(IPP_LIB_SUFFIX ${CMAKE_STATIC_LIBRARY_SUFFIX}) set(IPP_LIB_SUFFIX ${CMAKE_STATIC_LIBRARY_SUFFIX})
set(IPP_PREFIX "ipp")
set(IPP_SUFFIX "_l")
set(IPPCORE "core") # core functionality
set(IPPS "s") # signal processing
set(IPPI "i") # image processing
set(IPPCC "cc") # color conversion
set(IPPCV "cv") # computer vision
set(IPPVM "vm") # vector math
set(IPP_X64 0) set(IPP_X64 0)
if(CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 8) if(CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 8)
...@@ -56,21 +45,21 @@ if(CMAKE_CL_64) ...@@ -56,21 +45,21 @@ if(CMAKE_CL_64)
set(IPP_X64 1) set(IPP_X64 1)
endif() endif()
# This function detects IPP version by analyzing ippversion.h file # This function detects IPP version by analyzing .h file
macro(ipp_get_version _ROOT_DIR) macro(ipp_get_version VERSION_FILE)
unset(_VERSION_STR) unset(_VERSION_STR)
unset(_MAJOR) unset(_MAJOR)
unset(_MINOR) unset(_MINOR)
unset(_BUILD) unset(_BUILD)
# read IPP version info from file # read IPP version info from file
file(STRINGS ${_ROOT_DIR}/include/ippversion.h STR1 REGEX "IPP_VERSION_MAJOR") file(STRINGS ${VERSION_FILE} STR1 REGEX "IPP_VERSION_MAJOR")
file(STRINGS ${_ROOT_DIR}/include/ippversion.h STR2 REGEX "IPP_VERSION_MINOR") file(STRINGS ${VERSION_FILE} STR2 REGEX "IPP_VERSION_MINOR")
file(STRINGS ${_ROOT_DIR}/include/ippversion.h STR3 REGEX "IPP_VERSION_BUILD") file(STRINGS ${VERSION_FILE} STR3 REGEX "IPP_VERSION_BUILD")
if("${STR3}" STREQUAL "") if("${STR3}" STREQUAL "")
file(STRINGS ${_ROOT_DIR}/include/ippversion.h STR3 REGEX "IPP_VERSION_UPDATE") file(STRINGS ${VERSION_FILE} STR3 REGEX "IPP_VERSION_UPDATE")
endif() endif()
file(STRINGS ${_ROOT_DIR}/include/ippversion.h STR4 REGEX "IPP_VERSION_STR") file(STRINGS ${VERSION_FILE} STR4 REGEX "IPP_VERSION_STR")
# extract info and assign to variables # extract info and assign to variables
string(REGEX MATCHALL "[0-9]+" _MAJOR ${STR1}) string(REGEX MATCHALL "[0-9]+" _MAJOR ${STR1})
...@@ -83,66 +72,92 @@ macro(ipp_get_version _ROOT_DIR) ...@@ -83,66 +72,92 @@ macro(ipp_get_version _ROOT_DIR)
set(IPP_VERSION_MAJOR ${_MAJOR}) set(IPP_VERSION_MAJOR ${_MAJOR})
set(IPP_VERSION_MINOR ${_MINOR}) set(IPP_VERSION_MINOR ${_MINOR})
set(IPP_VERSION_BUILD ${_BUILD}) set(IPP_VERSION_BUILD ${_BUILD})
endmacro()
macro(_ipp_not_supported)
message(STATUS ${ARGN})
unset(HAVE_IPP)
unset(HAVE_IPP_ICV_ONLY)
unset(IPP_VERSION_STR)
return()
endmacro()
# This macro uses IPP_ROOT_DIR variable
# TODO Cleanup code after ICV package stabilization
macro(ipp_detect_version)
set(IPP_INCLUDE_DIRS ${IPP_ROOT_DIR}/include)
set(__msg) set(__msg)
if(EXISTS ${_ROOT_DIR}/include/ippicv.h) if(EXISTS ${IPP_ROOT_DIR}/ippicv.h)
ocv_assert(WITH_ICV AND NOT WITH_IPP) set(__msg " (ICV version)")
set(__msg " ICV version")
set(HAVE_IPP_ICV_ONLY 1) set(HAVE_IPP_ICV_ONLY 1)
if(EXISTS ${IPP_ROOT_DIR}/ippversion.h)
_ipp_not_supported("Can't resolve IPP directory: ${IPP_ROOT_DIR}")
else()
ipp_get_version(${IPP_ROOT_DIR}/ippicv.h)
endif()
ocv_assert(IPP_VERSION_STR VERSION_GREATER "8.0")
set(IPP_INCLUDE_DIRS ${IPP_ROOT_DIR}/)
elseif(EXISTS ${IPP_ROOT_DIR}/include/ipp.h)
ipp_get_version(${IPP_ROOT_DIR}/include/ippversion.h)
ocv_assert(IPP_VERSION_STR VERSION_GREATER "1.0")
else()
_ipp_not_supported("Can't resolve IPP directory: ${IPP_ROOT_DIR}")
endif() endif()
message(STATUS "found IPP: ${_MAJOR}.${_MINOR}.${_BUILD} [${_VERSION_STR}]${__msg}") message(STATUS "found IPP${__msg}: ${_MAJOR}.${_MINOR}.${_BUILD} [${IPP_VERSION_STR}]")
message(STATUS "at: ${_ROOT_DIR}") message(STATUS "at: ${IPP_ROOT_DIR}")
endmacro()
if(${IPP_VERSION_STR} VERSION_LESS "7.0")
_ipp_not_supported("IPP ${IPP_VERSION_STR} is not supported")
endif()
# This function sets IPP_INCLUDE_DIRS and IPP_LIBRARIES variables set(HAVE_IPP 1)
macro(ipp_set_variables _LATEST_VERSION) if(EXISTS ${IPP_INCLUDE_DIRS}/ipp_redefine.h)
if(${_LATEST_VERSION} VERSION_LESS "7.0") set(HAVE_IPP_REDEFINE 1)
message(SEND_ERROR "IPP ${_LATEST_VERSION} is not supported") else()
unset(HAVE_IPP) unset(HAVE_IPP_REDEFINE)
return()
endif() endif()
# set INCLUDE and LIB folders macro(_ipp_set_library_dir DIR)
set(IPP_INCLUDE_DIRS ${IPP_ROOT_DIR}/include) if(NOT EXISTS ${DIR})
_ipp_not_supported("IPP library directory not found")
endif()
set(IPP_LIBRARY_DIR ${DIR})
endmacro()
if(NOT HAVE_IPP_ICV_ONLY) if(NOT HAVE_IPP_ICV_ONLY)
if(APPLE) if(APPLE)
set(IPP_LIBRARY_DIR ${IPP_ROOT_DIR}/lib) _ipp_set_library_dir(${IPP_ROOT_DIR}/lib)
elseif(IPP_X64) elseif(IPP_X64)
if(NOT EXISTS ${IPP_ROOT_DIR}/lib/intel64) _ipp_set_library_dir(${IPP_ROOT_DIR}/lib/intel64)
message(SEND_ERROR "IPP EM64T libraries not found")
endif()
set(IPP_LIBRARY_DIR ${IPP_ROOT_DIR}/lib/intel64)
else() else()
if(NOT EXISTS ${IPP_ROOT_DIR}/lib/ia32) _ipp_set_library_dir(${IPP_ROOT_DIR}/lib/ia32)
message(SEND_ERROR "IPP IA32 libraries not found")
endif()
set(IPP_LIBRARY_DIR ${IPP_ROOT_DIR}/lib/ia32)
endif() endif()
else() else()
if(APPLE) if(EXISTS ${IPP_ROOT_DIR}/lib)
set(IPP_LIBRARY_DIR ${IPP_ROOT_DIR}/libs/macosx) set(IPP_LIBRARY_DIR ${IPP_ROOT_DIR}/lib)
elseif(WIN32 AND NOT ARM)
set(IPP_LIBRARY_DIR ${IPP_ROOT_DIR}/libs/windows)
elseif(UNIX)
set(IPP_LIBRARY_DIR ${IPP_ROOT_DIR}/libs/linux)
else() else()
message(MESSAGE "IPP ${_LATEST_VERSION} at ${IPP_ROOT_DIR} is not supported") _ipp_not_supported("IPP ${IPP_VERSION_STR} at ${IPP_ROOT_DIR} is not supported")
unset(HAVE_IPP)
return()
endif() endif()
if(X86_64) if(X86_64)
set(IPP_LIBRARY_DIR ${IPP_LIBRARY_DIR}/intel64) _ipp_set_library_dir(${IPP_LIBRARY_DIR}/intel64)
else() else()
set(IPP_LIBRARY_DIR ${IPP_LIBRARY_DIR}/ia32) _ipp_set_library_dir(${IPP_LIBRARY_DIR}/ia32)
endif() endif()
endif() endif()
macro(_ipp_add_library name)
if (EXISTS ${IPP_LIBRARY_DIR}/${IPP_LIB_PREFIX}${IPP_PREFIX}${name}${IPP_SUFFIX}${IPP_LIB_SUFFIX})
list(APPEND IPP_LIBRARIES ${IPP_LIBRARY_DIR}/${IPP_LIB_PREFIX}${IPP_PREFIX}${name}${IPP_SUFFIX}${IPP_LIB_SUFFIX})
else()
message(STATUS "Can't find IPP library: ${name}")
endif()
endmacro()
set(IPP_PREFIX "ipp") set(IPP_PREFIX "ipp")
if(${_LATEST_VERSION} VERSION_LESS "8.0") if(${IPP_VERSION_STR} VERSION_LESS "8.0")
set(IPP_SUFFIX "_l") # static not threaded libs suffix IPP 7.x set(IPP_SUFFIX "_l") # static not threaded libs suffix IPP 7.x
else() else()
if(WIN32) if(WIN32)
set(IPP_SUFFIX "mt") # static not threaded libs suffix IPP 8.x for Windows set(IPP_SUFFIX "mt") # static not threaded libs suffix IPP 8.x for Windows
...@@ -150,86 +165,92 @@ macro(ipp_set_variables _LATEST_VERSION) ...@@ -150,86 +165,92 @@ macro(ipp_set_variables _LATEST_VERSION)
set(IPP_SUFFIX "") # static not threaded libs suffix IPP 8.x for Linux/OS X set(IPP_SUFFIX "") # static not threaded libs suffix IPP 8.x for Linux/OS X
endif() endif()
endif() endif()
set(IPPCORE "core") # core functionality
set(IPPSP "s") # signal processing
set(IPPIP "i") # image processing
set(IPPCC "cc") # color conversion
set(IPPCV "cv") # computer vision
set(IPPVM "vm") # vector math
set(IPPM "m") # matrix math
list(APPEND IPP_LIBRARIES ${IPP_LIBRARY_DIR}/${IPP_LIB_PREFIX}${IPP_PREFIX}${IPPVM}${IPP_SUFFIX}${IPP_LIB_SUFFIX})
list(APPEND IPP_LIBRARIES ${IPP_LIBRARY_DIR}/${IPP_LIB_PREFIX}${IPP_PREFIX}${IPPCC}${IPP_SUFFIX}${IPP_LIB_SUFFIX})
list(APPEND IPP_LIBRARIES ${IPP_LIBRARY_DIR}/${IPP_LIB_PREFIX}${IPP_PREFIX}${IPPCV}${IPP_SUFFIX}${IPP_LIB_SUFFIX})
list(APPEND IPP_LIBRARIES ${IPP_LIBRARY_DIR}/${IPP_LIB_PREFIX}${IPP_PREFIX}${IPPI}${IPP_SUFFIX}${IPP_LIB_SUFFIX})
list(APPEND IPP_LIBRARIES ${IPP_LIBRARY_DIR}/${IPP_LIB_PREFIX}${IPP_PREFIX}${IPPS}${IPP_SUFFIX}${IPP_LIB_SUFFIX})
list(APPEND IPP_LIBRARIES ${IPP_LIBRARY_DIR}/${IPP_LIB_PREFIX}${IPP_PREFIX}${IPPCORE}${IPP_SUFFIX}${IPP_LIB_SUFFIX})
if(NOT HAVE_IPP_ICV_ONLY)
list(APPEND IPP_LIBRARIES ${IPP_LIBRARY_DIR}/${IPP_LIB_PREFIX}${IPP_PREFIX}${IPPM}${IPP_SUFFIX}${IPP_LIB_SUFFIX})
endif()
# FIXIT if(HAVE_IPP_ICV_ONLY)
# if(UNIX AND NOT HAVE_IPP_ICV_ONLY) _ipp_add_library(icv)
# get_filename_component(INTEL_COMPILER_LIBRARY_DIR ${IPP_ROOT_DIR}/../lib REALPATH) else()
if(UNIX) _ipp_add_library(core)
if(NOT HAVE_IPP_ICV_ONLY) _ipp_add_library(s)
_ipp_add_library(i)
_ipp_add_library(cc)
_ipp_add_library(cv)
_ipp_add_library(vm)
_ipp_add_library(m)
if(UNIX)
get_filename_component(INTEL_COMPILER_LIBRARY_DIR ${IPP_ROOT_DIR}/../lib REALPATH) get_filename_component(INTEL_COMPILER_LIBRARY_DIR ${IPP_ROOT_DIR}/../lib REALPATH)
else() if(NOT EXISTS ${INTEL_COMPILER_LIBRARY_DIR})
set(INTEL_COMPILER_LIBRARY_DIR "/opt/intel/lib") get_filename_component(INTEL_COMPILER_LIBRARY_DIR ${IPP_ROOT_DIR}/../compiler/lib REALPATH)
endif()
if(IPP_X64)
if(NOT EXISTS ${INTEL_COMPILER_LIBRARY_DIR}/intel64)
message(SEND_ERROR "Intel compiler EM64T libraries not found")
endif() endif()
if(NOT APPLE) if(NOT EXISTS ${INTEL_COMPILER_LIBRARY_DIR})
set(INTEL_COMPILER_LIBRARY_DIR ${INTEL_COMPILER_LIBRARY_DIR}/intel64) _ipp_not_supported("IPP configuration error: can't find Intel compiler library dir ${INTEL_COMPILER_LIBRARY_DIR}")
endif()
else()
if(NOT EXISTS ${INTEL_COMPILER_LIBRARY_DIR}/ia32)
message(SEND_ERROR "Intel compiler IA32 libraries not found")
endif() endif()
if (NOT APPLE) if(NOT APPLE)
set(INTEL_COMPILER_LIBRARY_DIR ${INTEL_COMPILER_LIBRARY_DIR}/ia32) if(IPP_X64)
if(NOT EXISTS ${INTEL_COMPILER_LIBRARY_DIR}/intel64)
message(SEND_ERROR "Intel compiler EM64T libraries not found")
endif()
set(INTEL_COMPILER_LIBRARY_DIR ${INTEL_COMPILER_LIBRARY_DIR}/intel64)
else()
if(NOT EXISTS ${INTEL_COMPILER_LIBRARY_DIR}/ia32)
message(SEND_ERROR "Intel compiler IA32 libraries not found")
endif()
set(INTEL_COMPILER_LIBRARY_DIR ${INTEL_COMPILER_LIBRARY_DIR}/ia32)
endif()
endif() endif()
endif()
list(APPEND IPP_LIBRARIES ${INTEL_COMPILER_LIBRARY_DIR}/${IPP_LIB_PREFIX}irc${CMAKE_SHARED_LIBRARY_SUFFIX}) macro(_ipp_add_compiler_library name)
list(APPEND IPP_LIBRARIES ${INTEL_COMPILER_LIBRARY_DIR}/${IPP_LIB_PREFIX}imf${CMAKE_SHARED_LIBRARY_SUFFIX}) if (EXISTS ${INTEL_COMPILER_LIBRARY_DIR}/${IPP_LIB_PREFIX}${name}${CMAKE_SHARED_LIBRARY_SUFFIX})
list(APPEND IPP_LIBRARIES ${INTEL_COMPILER_LIBRARY_DIR}/${IPP_LIB_PREFIX}svml${CMAKE_SHARED_LIBRARY_SUFFIX}) list(APPEND IPP_LIBRARIES ${INTEL_COMPILER_LIBRARY_DIR}/${IPP_LIB_PREFIX}${name}${CMAKE_SHARED_LIBRARY_SUFFIX})
else()
message(STATUS "Can't find compiler library: ${name}")
endif()
endmacro()
_ipp_add_compiler_library(irc)
_ipp_add_compiler_library(imf)
_ipp_add_compiler_library(svml)
endif(UNIX)
endif() endif()
#message(STATUS "IPP libs: ${IPP_LIBRARIES}") #message(STATUS "IPP libs: ${IPP_LIBRARIES}")
endmacro() endmacro()
if(WITH_IPP) # OPENCV_IPP_PATH is an environment variable for internal usage only, do not use it
set(IPPPATH $ENV{IPPROOT}) if(DEFINED ENV{OPENCV_IPP_PATH} AND NOT DEFINED IPPROOT)
if(UNIX) set(IPPROOT "$ENV{OPENCV_IPP_PATH}")
list(APPEND IPPPATH /opt/intel/ipp) endif()
endif() if(NOT DEFINED IPPROOT)
elseif(WITH_ICV) set(IPPROOT "${OpenCV_SOURCE_DIR}/3rdparty/ippicv")
if(DEFINED ENV{IPPICVROOT})
set(IPPPATH $ENV{IPPICVROOT})
else()
set(IPPPATH ${OpenCV_SOURCE_DIR}/3rdparty/ippicv)
endif()
endif() endif()
# Try ICV
find_path( find_path(
IPP_H_PATH IPP_ICV_H_PATH
NAMES ippversion.h NAMES ippicv.h
PATHS ${IPPPATH} PATHS ${IPPROOT}
PATH_SUFFIXES include DOC "The path to Intel(R) IPP ICV header files"
DOC "The path to Intel(R) IPP header files"
NO_DEFAULT_PATH NO_DEFAULT_PATH
NO_CMAKE_PATH) NO_CMAKE_PATH)
set(IPP_ROOT_DIR ${IPP_ICV_H_PATH})
if(IPP_H_PATH) if(NOT IPP_ICV_H_PATH)
set(HAVE_IPP 1) # Try standalone IPP
find_path(
IPP_H_PATH
NAMES ippversion.h
PATHS ${IPPROOT}
PATH_SUFFIXES include
DOC "The path to Intel(R) IPP header files"
NO_DEFAULT_PATH
NO_CMAKE_PATH)
if(IPP_H_PATH)
get_filename_component(IPP_ROOT_DIR ${IPP_H_PATH} PATH) get_filename_component(IPP_ROOT_DIR ${IPP_H_PATH} PATH)
endif()
endif()
ipp_get_version(${IPP_ROOT_DIR}) if(IPP_ROOT_DIR)
ipp_set_variables(${IPP_VERSION_STR}) ipp_detect_version()
endif() endif()
......
...@@ -8,7 +8,7 @@ if(WITH_TBB) ...@@ -8,7 +8,7 @@ if(WITH_TBB)
endif(WITH_TBB) endif(WITH_TBB)
# --- IPP --- # --- IPP ---
if(WITH_IPP OR WITH_ICV) if(WITH_IPP)
include("${OpenCV_SOURCE_DIR}/cmake/OpenCVFindIPP.cmake") include("${OpenCV_SOURCE_DIR}/cmake/OpenCVFindIPP.cmake")
if(HAVE_IPP) if(HAVE_IPP)
ocv_include_directories(${IPP_INCLUDE_DIRS}) ocv_include_directories(${IPP_INCLUDE_DIRS})
......
...@@ -211,8 +211,8 @@ CV_EXPORTS void scalarToRawData(const cv::Scalar& s, void* buf, int type, int un ...@@ -211,8 +211,8 @@ CV_EXPORTS void scalarToRawData(const cv::Scalar& s, void* buf, int type, int un
#ifdef HAVE_IPP #ifdef HAVE_IPP
# ifdef HAVE_IPP_ICV_ONLY # ifdef HAVE_IPP_ICV_ONLY
# include "ipp_redefine.h"
# include "ippicv.h" # include "ippicv.h"
# include "ippicv_fn_map.h"
# else # else
# include "ipp.h" # include "ipp.h"
# endif # endif
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册