pull/198/head
commit
268a07b950
|
@ -12,15 +12,15 @@ SET ( PROJECT_VERSION "${ASSIMP_VERSION}" )
|
||||||
set(ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used for uploading the sources")
|
set(ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used for uploading the sources")
|
||||||
|
|
||||||
option(ASSIMP_OPT_BUILD_PACKAGES "Set to ON to generate CPack configuration files and packaging targets" OFF)
|
option(ASSIMP_OPT_BUILD_PACKAGES "Set to ON to generate CPack configuration files and packaging targets" OFF)
|
||||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules")
|
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules" )
|
||||||
set(LIBASSIMP_COMPONENT libassimp${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VERSION_PATCH})
|
set(LIBASSIMP_COMPONENT "libassimp${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VERSION_PATCH}" )
|
||||||
set(LIBASSIMP-DEV_COMPONENT libassimp${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VERSION_PATCH}-dev)
|
set(LIBASSIMP-DEV_COMPONENT "libassimp${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VERSION_PATCH}-dev" )
|
||||||
set(CPACK_COMPONENTS_ALL assimp-bin ${LIBASSIMP_COMPONENT} ${LIBASSIMP-DEV_COMPONENT} assimp-dev)
|
set(CPACK_COMPONENTS_ALL assimp-bin ${LIBASSIMP_COMPONENT} ${LIBASSIMP-DEV_COMPONENT} assimp-dev)
|
||||||
set(ASSIMP_LIBRARY_SUFFIX "" CACHE STRING "Suffix to append to library names")
|
set(ASSIMP_LIBRARY_SUFFIX "" CACHE STRING "Suffix to append to library names")
|
||||||
|
|
||||||
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
|
if( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX AND NOT MINGW )
|
||||||
add_definitions(-fPIC) # this is a very important switch and some libraries seem now to have it....
|
add_definitions(-fPIC) # this is a very important switch and some libraries seem now to have it....
|
||||||
## hide all not-exported symbols
|
# hide all not-exported symbols
|
||||||
add_definitions( -fvisibility=hidden -Wall )
|
add_definitions( -fvisibility=hidden -Wall )
|
||||||
elseif(MSVC)
|
elseif(MSVC)
|
||||||
# enable multi-core compilation with MSVC
|
# enable multi-core compilation with MSVC
|
||||||
|
@ -37,9 +37,9 @@ INCLUDE (PrecompiledHeader)
|
||||||
# source tree. During an out-of-source build, however, do not litter this
|
# source tree. During an out-of-source build, however, do not litter this
|
||||||
# directory, since that is probably what the user wanted to avoid.
|
# directory, since that is probably what the user wanted to avoid.
|
||||||
IF ( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR )
|
IF ( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR )
|
||||||
SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib )
|
SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/lib" )
|
||||||
SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib )
|
SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/lib" )
|
||||||
SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/bin )
|
SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/bin" )
|
||||||
ENDIF ( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR )
|
ENDIF ( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR )
|
||||||
|
|
||||||
# Cache these to allow the user to override them manually.
|
# Cache these to allow the user to override them manually.
|
||||||
|
@ -50,7 +50,7 @@ SET( ASSIMP_INCLUDE_INSTALL_DIR "include" CACHE PATH
|
||||||
SET( ASSIMP_BIN_INSTALL_DIR "bin" CACHE PATH
|
SET( ASSIMP_BIN_INSTALL_DIR "bin" CACHE PATH
|
||||||
"Path the tool executables are installed to." )
|
"Path the tool executables are installed to." )
|
||||||
|
|
||||||
SET(ASSIMP_DEBUG_POSTFIX "D" CACHE STRING "Debug Postfitx for lib, samples and tools")
|
SET(ASSIMP_DEBUG_POSTFIX "d" CACHE STRING "Debug Postfitx for lib, samples and tools")
|
||||||
|
|
||||||
# Allow the user to build a static library
|
# Allow the user to build a static library
|
||||||
SET ( ASSIMP_BUILD_STATIC_LIB OFF CACHE BOOL
|
SET ( ASSIMP_BUILD_STATIC_LIB OFF CACHE BOOL
|
||||||
|
@ -62,9 +62,9 @@ CONFIGURE_FILE( "${PROJECT_SOURCE_DIR}/assimp.pc.in" "${PROJECT_BINARY_DIR}/assi
|
||||||
INSTALL( FILES "${PROJECT_BINARY_DIR}/assimp.pc" DESTINATION ${ASSIMP_LIB_INSTALL_DIR}/pkgconfig/ COMPONENT ${LIBASSIMP-DEV_COMPONENT})
|
INSTALL( FILES "${PROJECT_BINARY_DIR}/assimp.pc" DESTINATION ${ASSIMP_LIB_INSTALL_DIR}/pkgconfig/ COMPONENT ${LIBASSIMP-DEV_COMPONENT})
|
||||||
|
|
||||||
# cmake configuration files
|
# cmake configuration files
|
||||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake" @ONLY IMMEDIATE)
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake" @ONLY IMMEDIATE)
|
||||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config-version.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" @ONLY IMMEDIATE)
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config-version.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" @ONLY IMMEDIATE)
|
||||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" DESTINATION "${ASSIMP_LIB_INSTALL_DIR}/cmake/assimp-${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}" COMPONENT ${LIBASSIMP-DEV_COMPONENT})
|
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" DESTINATION "${ASSIMP_LIB_INSTALL_DIR}/cmake/assimp-${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}" COMPONENT ${LIBASSIMP-DEV_COMPONENT})
|
||||||
|
|
||||||
# Only generate this target if no higher-level project already has
|
# Only generate this target if no higher-level project already has
|
||||||
IF (NOT TARGET uninstall)
|
IF (NOT TARGET uninstall)
|
||||||
|
@ -75,7 +75,7 @@ ENDIF()
|
||||||
|
|
||||||
# Globally enbale Boost resp. the Boost workaround – it is also needed by the
|
# Globally enbale Boost resp. the Boost workaround – it is also needed by the
|
||||||
# tools which include the Assimp headers.
|
# tools which include the Assimp headers.
|
||||||
SET ( ASSIMP_ENABLE_BOOST_WORKAROUND OFF CACHE BOOL
|
SET ( ASSIMP_ENABLE_BOOST_WORKAROUND ON CACHE BOOL
|
||||||
"If a simple implementation of the used Boost functions is used. Slightly reduces functionality, but enables builds without Boost available."
|
"If a simple implementation of the used Boost functions is used. Slightly reduces functionality, but enables builds without Boost available."
|
||||||
)
|
)
|
||||||
IF ( ASSIMP_ENABLE_BOOST_WORKAROUND )
|
IF ( ASSIMP_ENABLE_BOOST_WORKAROUND )
|
||||||
|
@ -113,8 +113,8 @@ if( NOT ZLIB_FOUND )
|
||||||
# compile from sources
|
# compile from sources
|
||||||
add_subdirectory(contrib/zlib)
|
add_subdirectory(contrib/zlib)
|
||||||
set(ZLIB_FOUND 1)
|
set(ZLIB_FOUND 1)
|
||||||
set(ZLIB_LIBRARIES zlib)
|
set(ZLIB_LIBRARIES zlibstatic)
|
||||||
set(ZLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/zlib)
|
set(ZLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/contrib/zlib ${CMAKE_CURRENT_BINARY_DIR}/contrib/zlib)
|
||||||
else(NOT ZLIB_FOUND)
|
else(NOT ZLIB_FOUND)
|
||||||
ADD_DEFINITIONS(-DASSIMP_BUILD_NO_OWN_ZLIB)
|
ADD_DEFINITIONS(-DASSIMP_BUILD_NO_OWN_ZLIB)
|
||||||
endif(NOT ZLIB_FOUND)
|
endif(NOT ZLIB_FOUND)
|
||||||
|
@ -154,7 +154,6 @@ ENDIF ( ASSIMP_BUILD_COMPILER STREQUAL "")
|
||||||
|
|
||||||
MARK_AS_ADVANCED ( ASSIMP_BUILD_ARCHITECTURE ASSIMP_BUILD_COMPILER )
|
MARK_AS_ADVANCED ( ASSIMP_BUILD_ARCHITECTURE ASSIMP_BUILD_COMPILER )
|
||||||
|
|
||||||
|
|
||||||
ADD_SUBDIRECTORY( code/ )
|
ADD_SUBDIRECTORY( code/ )
|
||||||
SET ( ASSIMP_BUILD_ASSIMP_TOOLS ON CACHE BOOL
|
SET ( ASSIMP_BUILD_ASSIMP_TOOLS ON CACHE BOOL
|
||||||
"If the supplementary tools for Assimp are built in addition to the library."
|
"If the supplementary tools for Assimp are built in addition to the library."
|
||||||
|
@ -195,38 +194,38 @@ ENDIF(MSVC)
|
||||||
|
|
||||||
if(CMAKE_CPACK_COMMAND AND UNIX AND ASSIMP_OPT_BUILD_PACKAGES)
|
if(CMAKE_CPACK_COMMAND AND UNIX AND ASSIMP_OPT_BUILD_PACKAGES)
|
||||||
# Packing information
|
# Packing information
|
||||||
set(CPACK_PACKAGE_NAME assimp{ASSIMP_VERSION_MAJOR})
|
set(CPACK_PACKAGE_NAME "assimp{ASSIMP_VERSION_MAJOR}")
|
||||||
set(CPACK_PACKAGE_CONTACT "" CACHE STRING "Package maintainer and PGP signer.")
|
set(CPACK_PACKAGE_CONTACT "" CACHE STRING "Package maintainer and PGP signer.")
|
||||||
set(CPACK_PACKAGE_VENDOR "http://assimp.sourceforge.net/")
|
set(CPACK_PACKAGE_VENDOR "http://assimp.sourceforge.net/")
|
||||||
set(CPACK_PACKAGE_DISPLAY_NAME "Assimp ${ASSIMP_VERSION}")
|
set(CPACK_PACKAGE_DISPLAY_NAME "Assimp ${ASSIMP_VERSION}")
|
||||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY " - Open Asset Import Library ${ASSIMP_VERSION}")
|
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY " - Open Asset Import Library ${ASSIMP_VERSION}")
|
||||||
set(CPACK_PACKAGE_VERSION ${ASSIMP_VERSION}.${ASSIMP_PACKAGE_VERSION})
|
set(CPACK_PACKAGE_VERSION "${ASSIMP_VERSION}.${ASSIMP_PACKAGE_VERSION}" )
|
||||||
set(CPACK_PACKAGE_VERSION_MAJOR ${ASSIMP_VERSION_MAJOR})
|
set(CPACK_PACKAGE_VERSION_MAJOR "${ASSIMP_VERSION_MAJOR}")
|
||||||
set(CPACK_PACKAGE_VERSION_MINOR ${ASSIMP_VERSION_MINOR})
|
set(CPACK_PACKAGE_VERSION_MINOR "${ASSIMP_VERSION_MINOR}")
|
||||||
set(CPACK_PACKAGE_VERSION_PATCH ${ASSIMP_VERSION_PATCH})
|
set(CPACK_PACKAGE_VERSION_PATCH "${ASSIMP_VERSION_PATCH}")
|
||||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY "assimp${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}")
|
set(CPACK_PACKAGE_INSTALL_DIRECTORY "assimp${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}")
|
||||||
#set(CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_CURRENT_SOURCE_DIR}/description)
|
#set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/description")
|
||||||
set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE)
|
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
|
||||||
|
|
||||||
string(TOUPPER ${LIBASSIMP_COMPONENT} LIBASSIMP_COMPONENT_UPPER)
|
string(TOUPPER ${LIBASSIMP_COMPONENT} "LIBASSIMP_COMPONENT_UPPER")
|
||||||
string(TOUPPER ${LIBASSIMP-DEV_COMPONENT} LIBASSIMP-DEV_COMPONENT_UPPER)
|
string(TOUPPER ${LIBASSIMP-DEV_COMPONENT} "LIBASSIMP-DEV_COMPONENT_UPPER")
|
||||||
|
|
||||||
set(CPACK_COMPONENT_ASSIMP-BIN_DISPLAY_NAME "tools")
|
set(CPACK_COMPONENT_ASSIMP-BIN_DISPLAY_NAME "tools")
|
||||||
set(CPACK_COMPONENT_ASSIMP-BIN_DEPENDS ${LIBASSIMP_COMPONENT})
|
set(CPACK_COMPONENT_ASSIMP-BIN_DEPENDS "${LIBASSIMP_COMPONENT}" )
|
||||||
set(CPACK_COMPONENT_${LIBASSIMP_COMPONENT_UPPER}_DISPLAY_NAME "libraries")
|
set(CPACK_COMPONENT_${LIBASSIMP_COMPONENT_UPPER}_DISPLAY_NAME "libraries")
|
||||||
set(CPACK_COMPONENT_${LIBASSIMP-DEV_COMPONENT_UPPER}_DISPLAY_NAME "common headers and installs")
|
set(CPACK_COMPONENT_${LIBASSIMP-DEV_COMPONENT_UPPER}_DISPLAY_NAME "common headers and installs")
|
||||||
set(CPACK_COMPONENT_${LIBASSIMP-DEV_COMPONENT_UPPER}_DEPENDS ${LIBASSIMP_COMPONENT})
|
set(CPACK_COMPONENT_${LIBASSIMP-DEV_COMPONENT_UPPER}_DEPENDS $ "{LIBASSIMP_COMPONENT}" )
|
||||||
set(CPACK_COMPONENT_ASSIMP-DEV_DISPLAY_NAME ${CPACK_COMPONENT_${LIBASSIMP-DEV_COMPONENT}_DISPLAY_NAME})
|
set(CPACK_COMPONENT_ASSIMP-DEV_DISPLAY_NAME "${CPACK_COMPONENT_${LIBASSIMP-DEV_COMPONENT}_DISPLAY_NAME}" )
|
||||||
set(CPACK_COMPONENT_ASSIMP-DEV_DEPENDS ${LIBASSIMP-DEV_COMPONENT})
|
set(CPACK_COMPONENT_ASSIMP-DEV_DEPENDS "${LIBASSIMP-DEV_COMPONENT}" )
|
||||||
set(CPACK_DEBIAN_BUILD_DEPENDS debhelper cmake libboost-dev libboost-thread-dev libboost-math-dev zlib1g-dev pkg-config)
|
set(CPACK_DEBIAN_BUILD_DEPENDS debhelper cmake libboost-dev libboost-thread-dev libboost-math-dev zlib1g-dev pkg-config)
|
||||||
|
|
||||||
# debian
|
# debian
|
||||||
set(CPACK_DEBIAN_PACKAGE_PRIORITY optional)
|
set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
|
||||||
set(CPACK_DEBIAN_CMAKE_OPTIONS "-DBUILD_ASSIMP_SAMPLES:BOOL=${ASSIMP_BUILD_SAMPLES}")
|
set(CPACK_DEBIAN_CMAKE_OPTIONS "-DBUILD_ASSIMP_SAMPLES:BOOL=${ASSIMP_BUILD_SAMPLES}")
|
||||||
set(CPACK_DEBIAN_PACKAGE_SECTION libs)
|
set(CPACK_DEBIAN_PACKAGE_SECTION "libs" )
|
||||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS ${CPACK_COMPONENTS_ALL})
|
set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_COMPONENTS_ALL}")
|
||||||
set(CPACK_DEBIAN_PACKAGE_SUGGESTS)
|
set(CPACK_DEBIAN_PACKAGE_SUGGESTS)
|
||||||
set(CPACK_DEBIAN_PACKAGE_NAME assimp)
|
set(CPACK_DEBIAN_PACKAGE_NAME "assimp")
|
||||||
set(CPACK_DEBIAN_PACKAGE_REMOVE_SOURCE_FILES contrib/cppunit-1.12.1 contrib/cppunit_note.txt contrib/zlib workspaces test doc obj samples packaging)
|
set(CPACK_DEBIAN_PACKAGE_REMOVE_SOURCE_FILES contrib/cppunit-1.12.1 contrib/cppunit_note.txt contrib/zlib workspaces test doc obj samples packaging)
|
||||||
set(CPACK_DEBIAN_PACKAGE_SOURCE_COPY svn export --force)
|
set(CPACK_DEBIAN_PACKAGE_SOURCE_COPY svn export --force)
|
||||||
set(CPACK_DEBIAN_CHANGELOG)
|
set(CPACK_DEBIAN_CHANGELOG)
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
===============================================
|
||||||
|
The Asset-Importer-Library Coding conventions
|
||||||
|
===============================================
|
||||||
|
|
||||||
|
If you want to participate to the Asset-Importer_Library please have a look
|
||||||
|
onto these coding conventions and try to follow them. They are more or less
|
||||||
|
some kind of guide line to help others coming into the code and help all
|
||||||
|
the Asset-Importer-Library users.
|
||||||
|
|
||||||
|
Tab width
|
||||||
|
===========
|
||||||
|
The tab width shall be 4 spaces.
|
||||||
|
|
||||||
|
|
57
Readme.md
57
Readme.md
|
@ -1,20 +1,19 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
========
|
========
|
||||||
|
|
||||||
Open Asset Import Library is a Open Source library designed to load various __3d file formats and convert them into a single, in-memory format__. It supports more than 30 file formats. It also supports exporting files to a few selected file formats.
|
Open Asset Import Library is a Open Source library designed to load various __3d file formats and convert them into a single, in-memory format__. It supports more than __30 file formats__ for import and a growing selection of file formats for export. Additionally, assimp features various __post processing tools__ to refine the imported data: _normals and tangent space generation, triangulation, vertex cache locality optimization, removal of degenerate primitives and duplicate vertices, sorting by primitive type, merging of redundant materials_ and many more.
|
||||||
|
|
||||||
Its abbreviated name under which it is commonly known is __assimp__.
|
Its abbreviated name under which it is commonly known is __assimp__.
|
||||||
|
|
||||||
This is the development trunk of assimp containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [assimp.sf.net](http://assimp.sf.net) or from *nix package repositories. According to [Travis-CI] (https://travis-ci.org/), the current build status of the trunk is [![Build Status](https://travis-ci.org/assimp/assimp.png)](https://travis-ci.org/assimp/assimp)
|
This is the development trunk of assimp containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [assimp.sf.net](http://assimp.sf.net) or from *nix package repositories. According to [Travis-CI] (https://travis-ci.org/), the current build status of the trunk is [![Build Status](https://travis-ci.org/assimp/assimp.png)](https://travis-ci.org/assimp/assimp)
|
||||||
|
|
||||||
|
#### Supported file formats ####
|
||||||
#### 1.1 Supported file formats ####
|
|
||||||
|
|
||||||
The library provides importers for a lot of file formats, including:
|
The library provides importers for a lot of file formats, including:
|
||||||
|
|
||||||
- 3DS
|
- 3DS
|
||||||
- BLEND (Blender 3D)
|
- BLEND (Blender 3D)
|
||||||
- DAE (Collada)
|
- DAE/Collada
|
||||||
- FBX
|
- FBX
|
||||||
- IFC-STEP
|
- IFC-STEP
|
||||||
- ASE
|
- ASE
|
||||||
|
@ -46,6 +45,10 @@ The library provides importers for a lot of file formats, including:
|
||||||
- NDO
|
- NDO
|
||||||
- Ogre XML
|
- Ogre XML
|
||||||
- Q3D
|
- Q3D
|
||||||
|
|
||||||
|
Additionally, the following formats are also supported, but not part of the core library as they depend on proprietary libraries.
|
||||||
|
|
||||||
|
- C4D (https://github.com/acgessler/assimp-cinema4d)
|
||||||
|
|
||||||
Exporters include:
|
Exporters include:
|
||||||
|
|
||||||
|
@ -58,7 +61,7 @@ See [the full list here](http://assimp.sourceforge.net/main_features_formats.htm
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#### 1.2 Repository structure ####
|
#### Repository structure ####
|
||||||
|
|
||||||
|
|
||||||
Open Asset Import Library is implemented in C++ (but provides both a C and a
|
Open Asset Import Library is implemented in C++ (but provides both a C and a
|
||||||
|
@ -68,48 +71,50 @@ C++ish interface). The directory structure is:
|
||||||
/code Source code
|
/code Source code
|
||||||
/contrib Third-party libraries
|
/contrib Third-party libraries
|
||||||
/doc Documentation (doxysource and pre-compiled docs)
|
/doc Documentation (doxysource and pre-compiled docs)
|
||||||
/include Public header C and C++ header files.
|
/include Public header C and C++ header files
|
||||||
/lib Static library location for Windows.
|
/lib Static library location for Windows
|
||||||
/obj Object file location for Windows.
|
/obj Object file location for Windows
|
||||||
/port Ports to other languages and scripts to maintain those.
|
/scripts Scripts used to generate the loading code for some formats
|
||||||
/test Unit- and regression tests, test suite of models.
|
/port Ports to other languages and scripts to maintain those.
|
||||||
/tools Tools (viewer, command line `assimp`).
|
/test Unit- and regression tests, test suite of models
|
||||||
|
/tools Tools (viewer, command line `assimp`)
|
||||||
/samples A small number of samples to illustrate possible
|
/samples A small number of samples to illustrate possible
|
||||||
use cases for Assimp.
|
use cases for Assimp
|
||||||
/workspaces Build enviroments for vc,xcode,... (deprecated,
|
/workspaces Build enviroments for vc,xcode,... (deprecated,
|
||||||
CMake has superseeded all legacy build options!)
|
CMake has superseeded all legacy build options!)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 2. Build the library ###
|
### Building ###
|
||||||
|
|
||||||
|
|
||||||
Take a look into the `INSTALL` file. Or fire up CMake with the usual steps.
|
Take a look into the `INSTALL` file. Or fire up CMake with the usual steps.
|
||||||
|
|
||||||
|
|
||||||
|
### Where to get help ###
|
||||||
### 3. Where to get help ###
|
|
||||||
|
|
||||||
|
|
||||||
For more information, visit [our website](http://assimp.sourceforge.net/). Or check out the `./doc`- folder, which contains the official documentation in HTML format.
|
For more information, visit [our website](http://assimp.sourceforge.net/). Or check out the `./doc`- folder, which contains the official documentation in HTML format.
|
||||||
(CHMs for Windows are included in some release packages and should be located right here in the root folder).
|
(CHMs for Windows are included in some release packages and should be located right here in the root folder).
|
||||||
|
|
||||||
If the documentation doesn't solve your problems, try our forums at SF.net
|
If the documentation doesn't solve your problems,
|
||||||
|
[try our forums at SF.net](http://sourceforge.net/p/assimp/discussion/817654) or ask on
|
||||||
|
[StackOverflow](http://stackoverflow.com/questions/tagged/assimp?sort=newest).
|
||||||
|
|
||||||
|
For development discussions, there is also a mailing list, _assimp-discussions_
|
||||||
- [Open Discussion](http://sourceforge.net/projects/assimp/forums/forum/817653)
|
|
||||||
- [General Help](http://sourceforge.net/projects/assimp/forums/forum/817654)
|
|
||||||
|
|
||||||
|
|
||||||
For development stuff, there is also a mailing list, _assimp-discussions_
|
|
||||||
[(subscribe here)]( https://lists.sourceforge.net/lists/listinfo/assimp-discussions)
|
[(subscribe here)]( https://lists.sourceforge.net/lists/listinfo/assimp-discussions)
|
||||||
|
|
||||||
|
### Contributing ###
|
||||||
|
|
||||||
|
Contributions to assimp are highly appreciated. The easiest way to get involved is to submit
|
||||||
|
a pull request with your changes against the main repository's `master` branch.
|
||||||
|
|
||||||
|
|
||||||
### 4. License ###
|
### License ###
|
||||||
|
|
||||||
The license of the Asset Import Library is based on the modified, __3-clause BSD__-License, which is a very liberal license. An _informal_ summary is: do whatever you want, but include Assimp's license text with your product - and don't sue us if our code doesn't work.
|
Our license is based on the modified, __3-clause BSD__-License, which is very liberal.
|
||||||
|
|
||||||
Note that, unlike LGPLed code, you may link statically to Assimp.
|
An _informal_ summary is: do whatever you want, but include Assimp's license text with your product -
|
||||||
For the formal details, see the `LICENSE` file.
|
and don't sue us if our code doesn't work. Note that, unlike LGPLed code, you may link statically to Assimp.
|
||||||
|
For the legal details, see the `LICENSE` file.
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,8 @@ static const aiImporterDesc desc = {
|
||||||
Discreet3DS::Chunk chunk; \
|
Discreet3DS::Chunk chunk; \
|
||||||
ReadChunk(&chunk); \
|
ReadChunk(&chunk); \
|
||||||
int chunkSize = chunk.Size-sizeof(Discreet3DS::Chunk); \
|
int chunkSize = chunk.Size-sizeof(Discreet3DS::Chunk); \
|
||||||
|
if(chunkSize <= 0) \
|
||||||
|
continue; \
|
||||||
const int oldReadLimit = stream->GetReadLimit(); \
|
const int oldReadLimit = stream->GetReadLimit(); \
|
||||||
stream->SetReadLimit(stream->GetCurrentPos() + chunkSize); \
|
stream->SetReadLimit(stream->GetCurrentPos() + chunkSize); \
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,7 @@ ASSIMP_API const aiExportFormatDesc* aiGetExportFormatDescription( size_t pIndex
|
||||||
return Exporter().GetExportFormatDescription(pIndex);
|
return Exporter().GetExportFormatDescription(pIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ASSIMP_API void aiCopyScene(const aiScene* pIn, aiScene** pOut)
|
ASSIMP_API void aiCopyScene(const aiScene* pIn, aiScene** pOut)
|
||||||
{
|
{
|
||||||
|
@ -72,8 +73,19 @@ ASSIMP_API void aiCopyScene(const aiScene* pIn, aiScene** pOut)
|
||||||
}
|
}
|
||||||
|
|
||||||
SceneCombiner::CopyScene(pOut,pIn,true);
|
SceneCombiner::CopyScene(pOut,pIn,true);
|
||||||
|
ScenePriv(*pOut)->mIsCopy = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiFreeScene(const C_STRUCT aiScene* pIn)
|
||||||
|
{
|
||||||
|
// note: aiReleaseImport() is also able to delete scene copies, but in addition
|
||||||
|
// it also handles scenes with import metadata.
|
||||||
|
delete pIn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ASSIMP_API aiReturn aiExportScene( const aiScene* pScene, const char* pFormatId, const char* pFileName, unsigned int pPreprocessing )
|
ASSIMP_API aiReturn aiExportScene( const aiScene* pScene, const char* pFormatId, const char* pFileName, unsigned int pPreprocessing )
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,176 @@
|
||||||
|
/*
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2013, assimp team
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the
|
||||||
|
following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file BlenderBMesh.cpp
|
||||||
|
* @brief Conversion of Blender's new BMesh stuff
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AssimpPCH.h"
|
||||||
|
|
||||||
|
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
|
||||||
|
|
||||||
|
#include "BlenderDNA.h"
|
||||||
|
#include "BlenderScene.h"
|
||||||
|
#include "BlenderBMesh.h"
|
||||||
|
#include "BlenderTessellator.h"
|
||||||
|
|
||||||
|
namespace Assimp
|
||||||
|
{
|
||||||
|
template< > const std::string LogFunctions< BlenderBMeshConverter >::log_prefix = "BLEND_BMESH: ";
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace Assimp;
|
||||||
|
using namespace Assimp::Blender;
|
||||||
|
using namespace Assimp::Formatter;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
BlenderBMeshConverter::BlenderBMeshConverter( const Mesh* mesh ):
|
||||||
|
BMesh( mesh ),
|
||||||
|
triMesh( NULL )
|
||||||
|
{
|
||||||
|
AssertValidMesh( );
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
BlenderBMeshConverter::~BlenderBMeshConverter( )
|
||||||
|
{
|
||||||
|
DestroyTriMesh( );
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
bool BlenderBMeshConverter::ContainsBMesh( ) const
|
||||||
|
{
|
||||||
|
// TODO - Should probably do some additional verification here
|
||||||
|
return BMesh->totpoly && BMesh->totloop && BMesh->totvert;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
const Mesh* BlenderBMeshConverter::TriangulateBMesh( )
|
||||||
|
{
|
||||||
|
AssertValidMesh( );
|
||||||
|
AssertValidSizes( );
|
||||||
|
PrepareTriMesh( );
|
||||||
|
|
||||||
|
for ( int i = 0; i < BMesh->totpoly; ++i )
|
||||||
|
{
|
||||||
|
const MPoly& poly = BMesh->mpoly[ i ];
|
||||||
|
ConvertPolyToFaces( poly );
|
||||||
|
}
|
||||||
|
|
||||||
|
return triMesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BlenderBMeshConverter::AssertValidMesh( )
|
||||||
|
{
|
||||||
|
if ( !ContainsBMesh( ) )
|
||||||
|
{
|
||||||
|
ThrowException( "BlenderBMeshConverter requires a BMesh with \"polygons\" - please call BlenderBMeshConverter::ContainsBMesh to check this first" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BlenderBMeshConverter::AssertValidSizes( )
|
||||||
|
{
|
||||||
|
if ( BMesh->totpoly != BMesh->mpoly.size( ) )
|
||||||
|
{
|
||||||
|
ThrowException( "BMesh poly array has incorrect size" );
|
||||||
|
}
|
||||||
|
if ( BMesh->totloop != BMesh->mloop.size( ) )
|
||||||
|
{
|
||||||
|
ThrowException( "BMesh loop array has incorrect size" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BlenderBMeshConverter::PrepareTriMesh( )
|
||||||
|
{
|
||||||
|
if ( triMesh )
|
||||||
|
{
|
||||||
|
DestroyTriMesh( );
|
||||||
|
}
|
||||||
|
|
||||||
|
triMesh = new Mesh( *BMesh );
|
||||||
|
triMesh->totface = 0;
|
||||||
|
triMesh->mface.clear( );
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BlenderBMeshConverter::DestroyTriMesh( )
|
||||||
|
{
|
||||||
|
delete triMesh;
|
||||||
|
triMesh = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BlenderBMeshConverter::ConvertPolyToFaces( const MPoly& poly )
|
||||||
|
{
|
||||||
|
const MLoop* polyLoop = &BMesh->mloop[ poly.loopstart ];
|
||||||
|
if ( poly.totloop == 3 || poly.totloop == 4 )
|
||||||
|
{
|
||||||
|
AddFace( polyLoop[ 0 ].v, polyLoop[ 1 ].v, polyLoop[ 2 ].v, poly.totloop == 4 ? polyLoop[ 3 ].v : 0 );
|
||||||
|
}
|
||||||
|
else if ( poly.totloop > 4 )
|
||||||
|
{
|
||||||
|
#if ASSIMP_BLEND_WITH_GLU_TESSELLATE
|
||||||
|
BlenderTessellatorGL tessGL( *this );
|
||||||
|
tessGL.Tessellate( polyLoop, poly.totloop, triMesh->mvert );
|
||||||
|
#elif ASSIMP_BLEND_WITH_POLY_2_TRI
|
||||||
|
BlenderTessellatorP2T tessP2T( *this );
|
||||||
|
tessP2T.Tessellate( polyLoop, poly.totloop, triMesh->mvert );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BlenderBMeshConverter::AddFace( int v1, int v2, int v3, int v4 )
|
||||||
|
{
|
||||||
|
MFace face;
|
||||||
|
face.v1 = v1;
|
||||||
|
face.v2 = v2;
|
||||||
|
face.v3 = v3;
|
||||||
|
face.v4 = v4;
|
||||||
|
// TODO - Work out how materials work
|
||||||
|
face.mat_nr = 0;
|
||||||
|
triMesh->mface.push_back( face );
|
||||||
|
triMesh->totface = triMesh->mface.size( );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // ASSIMP_BUILD_NO_BLEND_IMPORTER
|
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2013, assimp team
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the
|
||||||
|
following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file BlenderBMesh.h
|
||||||
|
* @brief Conversion of Blender's new BMesh stuff
|
||||||
|
*/
|
||||||
|
#ifndef INCLUDED_AI_BLEND_BMESH_H
|
||||||
|
#define INCLUDED_AI_BLEND_BMESH_H
|
||||||
|
|
||||||
|
#include "LogAux.h"
|
||||||
|
|
||||||
|
namespace Assimp
|
||||||
|
{
|
||||||
|
// TinyFormatter.h
|
||||||
|
namespace Formatter
|
||||||
|
{
|
||||||
|
template < typename T,typename TR, typename A > class basic_formatter;
|
||||||
|
typedef class basic_formatter< char, std::char_traits< char >, std::allocator< char > > format;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlenderScene.h
|
||||||
|
namespace Blender
|
||||||
|
{
|
||||||
|
struct Mesh;
|
||||||
|
struct MPoly;
|
||||||
|
struct MLoop;
|
||||||
|
}
|
||||||
|
|
||||||
|
class BlenderBMeshConverter: public LogFunctions< BlenderBMeshConverter >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BlenderBMeshConverter( const Blender::Mesh* mesh );
|
||||||
|
~BlenderBMeshConverter( );
|
||||||
|
|
||||||
|
bool ContainsBMesh( ) const;
|
||||||
|
|
||||||
|
const Blender::Mesh* TriangulateBMesh( );
|
||||||
|
|
||||||
|
private:
|
||||||
|
void AssertValidMesh( );
|
||||||
|
void AssertValidSizes( );
|
||||||
|
void PrepareTriMesh( );
|
||||||
|
void DestroyTriMesh( );
|
||||||
|
void ConvertPolyToFaces( const Blender::MPoly& poly );
|
||||||
|
void AddFace( int v1, int v2, int v3, int v4 = 0 );
|
||||||
|
|
||||||
|
const Blender::Mesh* BMesh;
|
||||||
|
Blender::Mesh* triMesh;
|
||||||
|
|
||||||
|
friend class BlenderTessellatorGL;
|
||||||
|
friend class BlenderTessellatorP2T;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end of namespace Assimp
|
||||||
|
|
||||||
|
#endif // INCLUDED_AI_BLEND_BMESH_H
|
|
@ -278,19 +278,23 @@ public:
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
// field parsing for pointer or dynamic array types
|
// field parsing for pointer or dynamic array types
|
||||||
// (boost::shared_ptr or boost::shared_array)
|
// (boost::shared_ptr or boost::shared_array)
|
||||||
|
// The return value indicates whether the data was already cached.
|
||||||
template <int error_policy, template <typename> class TOUT, typename T>
|
template <int error_policy, template <typename> class TOUT, typename T>
|
||||||
void ReadFieldPtr(TOUT<T>& out, const char* name,
|
bool ReadFieldPtr(TOUT<T>& out, const char* name,
|
||||||
const FileDatabase& db) const;
|
const FileDatabase& db,
|
||||||
|
bool non_recursive = false) const;
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
// field parsing for static arrays of pointer or dynamic
|
// field parsing for static arrays of pointer or dynamic
|
||||||
// array types (boost::shared_ptr[] or boost::shared_array[])
|
// array types (boost::shared_ptr[] or boost::shared_array[])
|
||||||
|
// The return value indicates whether the data was already cached.
|
||||||
template <int error_policy, template <typename> class TOUT, typename T, size_t N>
|
template <int error_policy, template <typename> class TOUT, typename T, size_t N>
|
||||||
void ReadFieldPtr(TOUT<T> (&out)[N], const char* name,
|
bool ReadFieldPtr(TOUT<T> (&out)[N], const char* name,
|
||||||
const FileDatabase& db) const;
|
const FileDatabase& db) const;
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
// field parsing for `normal` values
|
// field parsing for `normal` values
|
||||||
|
// The return value indicates whether the data was already cached.
|
||||||
template <int error_policy, typename T>
|
template <int error_policy, typename T>
|
||||||
void ReadField(T& out, const char* name,
|
void ReadField(T& out, const char* name,
|
||||||
const FileDatabase& db) const;
|
const FileDatabase& db) const;
|
||||||
|
@ -299,17 +303,18 @@ private:
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
template <template <typename> class TOUT, typename T>
|
template <template <typename> class TOUT, typename T>
|
||||||
void ResolvePointer(TOUT<T>& out, const Pointer & ptrval,
|
bool ResolvePointer(TOUT<T>& out, const Pointer & ptrval,
|
||||||
const FileDatabase& db, const Field& f) const;
|
const FileDatabase& db, const Field& f,
|
||||||
|
bool non_recursive = false) const;
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
template <template <typename> class TOUT, typename T>
|
template <template <typename> class TOUT, typename T>
|
||||||
void ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval,
|
bool ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval,
|
||||||
const FileDatabase& db, const Field& f) const;
|
const FileDatabase& db, const Field& f, bool) const;
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
void ResolvePointer( boost::shared_ptr< FileOffset >& out, const Pointer & ptrval,
|
bool ResolvePointer( boost::shared_ptr< FileOffset >& out, const Pointer & ptrval,
|
||||||
const FileDatabase& db, const Field& f) const;
|
const FileDatabase& db, const Field& f, bool) const;
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
inline const FileBlockHead* LocateFileBlockForAddress(
|
inline const FileBlockHead* LocateFileBlockForAddress(
|
||||||
|
@ -384,10 +389,11 @@ template <> struct Structure :: _defaultInitializer<ErrorPolicy_Fail> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------
|
||||||
template <> inline void Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost::shared_ptr<ElemBase>& out,
|
template <> inline bool Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost::shared_ptr<ElemBase>& out,
|
||||||
const Pointer & ptrval,
|
const Pointer & ptrval,
|
||||||
const FileDatabase& db,
|
const FileDatabase& db,
|
||||||
const Field& f
|
const Field& f,
|
||||||
|
bool
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -180,7 +180,8 @@ void Structure :: ReadFieldArray2(T (& out)[M][N], const char* name, const FileD
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
template <int error_policy, template <typename> class TOUT, typename T>
|
template <int error_policy, template <typename> class TOUT, typename T>
|
||||||
void Structure :: ReadFieldPtr(TOUT<T>& out, const char* name, const FileDatabase& db) const
|
bool Structure :: ReadFieldPtr(TOUT<T>& out, const char* name, const FileDatabase& db,
|
||||||
|
bool non_recursive /*= false*/) const
|
||||||
{
|
{
|
||||||
const StreamReaderAny::pos old = db.reader->GetCurrentPos();
|
const StreamReaderAny::pos old = db.reader->GetCurrentPos();
|
||||||
Pointer ptrval;
|
Pointer ptrval;
|
||||||
|
@ -203,23 +204,27 @@ void Structure :: ReadFieldPtr(TOUT<T>& out, const char* name, const FileDatabas
|
||||||
_defaultInitializer<error_policy>()(out,e.what());
|
_defaultInitializer<error_policy>()(out,e.what());
|
||||||
|
|
||||||
out.reset();
|
out.reset();
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolve the pointer and load the corresponding structure
|
// resolve the pointer and load the corresponding structure
|
||||||
ResolvePointer(out,ptrval,db,*f);
|
const bool res = ResolvePointer(out,ptrval,db,*f, non_recursive);
|
||||||
|
|
||||||
// and recover the previous stream position
|
if(!non_recursive) {
|
||||||
db.reader->SetCurrentPos(old);
|
// and recover the previous stream position
|
||||||
|
db.reader->SetCurrentPos(old);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
|
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
|
||||||
++db.stats().fields_read;
|
++db.stats().fields_read;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
template <int error_policy, template <typename> class TOUT, typename T, size_t N>
|
template <int error_policy, template <typename> class TOUT, typename T, size_t N>
|
||||||
void Structure :: ReadFieldPtr(TOUT<T> (&out)[N], const char* name,
|
bool Structure :: ReadFieldPtr(TOUT<T> (&out)[N], const char* name,
|
||||||
const FileDatabase& db) const
|
const FileDatabase& db) const
|
||||||
{
|
{
|
||||||
// XXX see if we can reduce this to call to the 'normal' ReadFieldPtr
|
// XXX see if we can reduce this to call to the 'normal' ReadFieldPtr
|
||||||
|
@ -253,11 +258,13 @@ void Structure :: ReadFieldPtr(TOUT<T> (&out)[N], const char* name,
|
||||||
for(size_t i = 0; i < N; ++i) {
|
for(size_t i = 0; i < N; ++i) {
|
||||||
out[i].reset();
|
out[i].reset();
|
||||||
}
|
}
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool res = true;
|
||||||
for(size_t i = 0; i < N; ++i) {
|
for(size_t i = 0; i < N; ++i) {
|
||||||
// resolve the pointer and load the corresponding structure
|
// resolve the pointer and load the corresponding structure
|
||||||
ResolvePointer(out[i],ptrval[i],db,*f);
|
res = ResolvePointer(out[i],ptrval[i],db,*f) && res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// and recover the previous stream position
|
// and recover the previous stream position
|
||||||
|
@ -266,6 +273,7 @@ void Structure :: ReadFieldPtr(TOUT<T> (&out)[N], const char* name,
|
||||||
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
|
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
|
||||||
++db.stats().fields_read;
|
++db.stats().fields_read;
|
||||||
#endif
|
#endif
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -296,11 +304,13 @@ void Structure :: ReadField(T& out, const char* name, const FileDatabase& db) co
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
template <template <typename> class TOUT, typename T>
|
template <template <typename> class TOUT, typename T>
|
||||||
void Structure :: ResolvePointer(TOUT<T>& out, const Pointer & ptrval, const FileDatabase& db, const Field& f) const
|
bool Structure :: ResolvePointer(TOUT<T>& out, const Pointer & ptrval, const FileDatabase& db,
|
||||||
|
const Field& f,
|
||||||
|
bool non_recursive /*= false*/) const
|
||||||
{
|
{
|
||||||
out.reset();
|
out.reset(); // ensure null pointers work
|
||||||
if (!ptrval.val) {
|
if (!ptrval.val) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
const Structure& s = db.dna[f.type];
|
const Structure& s = db.dna[f.type];
|
||||||
// find the file block the pointer is pointing to
|
// find the file block the pointer is pointing to
|
||||||
|
@ -318,7 +328,7 @@ void Structure :: ResolvePointer(TOUT<T>& out, const Pointer & ptrval, const Fil
|
||||||
// try to retrieve the object from the cache
|
// try to retrieve the object from the cache
|
||||||
db.cache(out).get(s,out,ptrval);
|
db.cache(out).get(s,out,ptrval);
|
||||||
if (out) {
|
if (out) {
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// seek to this location, but save the previous stream pointer.
|
// seek to this location, but save the previous stream pointer.
|
||||||
|
@ -334,27 +344,36 @@ void Structure :: ResolvePointer(TOUT<T>& out, const Pointer & ptrval, const Fil
|
||||||
// cache the object before we convert it to avoid cyclic recursion.
|
// cache the object before we convert it to avoid cyclic recursion.
|
||||||
db.cache(out).set(s,out,ptrval);
|
db.cache(out).set(s,out,ptrval);
|
||||||
|
|
||||||
for (size_t i = 0; i < num; ++i,++o) {
|
// if the non_recursive flag is set, we don't do anything but leave
|
||||||
s.Convert(*o,db);
|
// the cursor at the correct position to resolve the object.
|
||||||
}
|
if (!non_recursive) {
|
||||||
|
for (size_t i = 0; i < num; ++i,++o) {
|
||||||
|
s.Convert(*o,db);
|
||||||
|
}
|
||||||
|
|
||||||
db.reader->SetCurrentPos(pold);
|
db.reader->SetCurrentPos(pold);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
|
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
|
||||||
if(out) {
|
if(out) {
|
||||||
++db.stats().pointers_resolved;
|
++db.stats().pointers_resolved;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
inline void Structure :: ResolvePointer( boost::shared_ptr< FileOffset >& out, const Pointer & ptrval, const FileDatabase& db, const Field& /*f*/) const
|
inline bool Structure :: ResolvePointer( boost::shared_ptr< FileOffset >& out, const Pointer & ptrval,
|
||||||
|
const FileDatabase& db,
|
||||||
|
const Field&,
|
||||||
|
bool) const
|
||||||
{
|
{
|
||||||
// Currently used exclusively by PackedFile::data to represent
|
// Currently used exclusively by PackedFile::data to represent
|
||||||
// a simple offset into the mapped BLEND file.
|
// a simple offset into the mapped BLEND file.
|
||||||
out.reset();
|
out.reset();
|
||||||
if (!ptrval.val) {
|
if (!ptrval.val) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the file block the pointer is pointing to
|
// find the file block the pointer is pointing to
|
||||||
|
@ -362,11 +381,15 @@ inline void Structure :: ResolvePointer( boost::shared_ptr< FileOffset >& out, c
|
||||||
|
|
||||||
out = boost::shared_ptr< FileOffset > (new FileOffset());
|
out = boost::shared_ptr< FileOffset > (new FileOffset());
|
||||||
out->val = block->start+ static_cast<size_t>((ptrval.val - block->address.val) );
|
out->val = block->start+ static_cast<size_t>((ptrval.val - block->address.val) );
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
template <template <typename> class TOUT, typename T>
|
template <template <typename> class TOUT, typename T>
|
||||||
void Structure :: ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval, const FileDatabase& db, const Field& f) const
|
bool Structure :: ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval,
|
||||||
|
const FileDatabase& db,
|
||||||
|
const Field& f,
|
||||||
|
bool) const
|
||||||
{
|
{
|
||||||
// This is a function overload, not a template specialization. According to
|
// This is a function overload, not a template specialization. According to
|
||||||
// the partial ordering rules, it should be selected by the compiler
|
// the partial ordering rules, it should be selected by the compiler
|
||||||
|
@ -374,7 +397,7 @@ void Structure :: ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval,
|
||||||
|
|
||||||
out.reset();
|
out.reset();
|
||||||
if (!ptrval.val) {
|
if (!ptrval.val) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the file block the pointer is pointing to
|
// find the file block the pointer is pointing to
|
||||||
|
@ -385,6 +408,7 @@ void Structure :: ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval,
|
||||||
const StreamReaderAny::pos pold = db.reader->GetCurrentPos();
|
const StreamReaderAny::pos pold = db.reader->GetCurrentPos();
|
||||||
db.reader->SetCurrentPos(block->start+ static_cast<size_t>((ptrval.val - block->address.val) ));
|
db.reader->SetCurrentPos(block->start+ static_cast<size_t>((ptrval.val - block->address.val) ));
|
||||||
|
|
||||||
|
bool res = false;
|
||||||
// allocate raw storage for the array
|
// allocate raw storage for the array
|
||||||
out.resize(num);
|
out.resize(num);
|
||||||
for (size_t i = 0; i< num; ++i) {
|
for (size_t i = 0; i< num; ++i) {
|
||||||
|
@ -392,17 +416,19 @@ void Structure :: ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval,
|
||||||
Convert(val,db);
|
Convert(val,db);
|
||||||
|
|
||||||
// and resolve the pointees
|
// and resolve the pointees
|
||||||
ResolvePointer(out[i],val,db,f);
|
res = ResolvePointer(out[i],val,db,f) && res;
|
||||||
}
|
}
|
||||||
|
|
||||||
db.reader->SetCurrentPos(pold);
|
db.reader->SetCurrentPos(pold);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
template <> void Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost::shared_ptr<ElemBase>& out,
|
template <> bool Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost::shared_ptr<ElemBase>& out,
|
||||||
const Pointer & ptrval,
|
const Pointer & ptrval,
|
||||||
const FileDatabase& db,
|
const FileDatabase& db,
|
||||||
const Field& /*f*/
|
const Field&,
|
||||||
|
bool
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
// Special case when the data type needs to be determined at runtime.
|
// Special case when the data type needs to be determined at runtime.
|
||||||
|
@ -410,7 +436,7 @@ template <> void Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost::
|
||||||
|
|
||||||
out.reset();
|
out.reset();
|
||||||
if (!ptrval.val) {
|
if (!ptrval.val) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the file block the pointer is pointing to
|
// find the file block the pointer is pointing to
|
||||||
|
@ -422,7 +448,7 @@ template <> void Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost::
|
||||||
// try to retrieve the object from the cache
|
// try to retrieve the object from the cache
|
||||||
db.cache(out).get(s,out,ptrval);
|
db.cache(out).get(s,out,ptrval);
|
||||||
if (out) {
|
if (out) {
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// seek to this location, but save the previous stream pointer.
|
// seek to this location, but save the previous stream pointer.
|
||||||
|
@ -440,7 +466,7 @@ template <> void Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost::
|
||||||
DefaultLogger::get()->warn((Formatter::format(),
|
DefaultLogger::get()->warn((Formatter::format(),
|
||||||
"Failed to find a converter for the `",s.name,"` structure"
|
"Failed to find a converter for the `",s.name,"` structure"
|
||||||
));
|
));
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate the object hull
|
// allocate the object hull
|
||||||
|
@ -459,11 +485,11 @@ template <> void Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost::
|
||||||
// to perform additional type checking.
|
// to perform additional type checking.
|
||||||
out->dna_type = s.name.c_str();
|
out->dna_type = s.name.c_str();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
|
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
|
||||||
++db.stats().pointers_resolved;
|
++db.stats().pointers_resolved;
|
||||||
#endif
|
#endif
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
|
|
@ -51,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "BlenderIntermediate.h"
|
#include "BlenderIntermediate.h"
|
||||||
#include "BlenderModifier.h"
|
#include "BlenderModifier.h"
|
||||||
|
#include "BlenderBMesh.h"
|
||||||
|
|
||||||
#include "StreamReader.h"
|
#include "StreamReader.h"
|
||||||
#include "MemoryIOWrapper.h"
|
#include "MemoryIOWrapper.h"
|
||||||
|
@ -446,9 +447,43 @@ void BlenderImporter::ResolveImage(aiMaterial* out, const Material* mat, const M
|
||||||
else {
|
else {
|
||||||
name = aiString( img->name );
|
name = aiString( img->name );
|
||||||
}
|
}
|
||||||
out->AddProperty(&name,AI_MATKEY_TEXTURE_DIFFUSE(
|
|
||||||
conv_data.next_texture[aiTextureType_DIFFUSE]++)
|
aiTextureType texture_type = aiTextureType_UNKNOWN;
|
||||||
);
|
MTex::MapType map_type = tex->mapto;
|
||||||
|
|
||||||
|
if (map_type & MTex::MapType_COL)
|
||||||
|
texture_type = aiTextureType_DIFFUSE;
|
||||||
|
else if (map_type & MTex::MapType_NORM) {
|
||||||
|
if (tex->tex->imaflag & Tex::ImageFlags_NORMALMAP) {
|
||||||
|
texture_type = aiTextureType_NORMALS;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
texture_type = aiTextureType_HEIGHT;
|
||||||
|
}
|
||||||
|
out->AddProperty(&tex->norfac,1,AI_MATKEY_BUMPSCALING);
|
||||||
|
}
|
||||||
|
else if (map_type & MTex::MapType_COLSPEC)
|
||||||
|
texture_type = aiTextureType_SPECULAR;
|
||||||
|
else if (map_type & MTex::MapType_COLMIR)
|
||||||
|
texture_type = aiTextureType_REFLECTION;
|
||||||
|
//else if (map_type & MTex::MapType_REF)
|
||||||
|
else if (map_type & MTex::MapType_SPEC)
|
||||||
|
texture_type = aiTextureType_SHININESS;
|
||||||
|
else if (map_type & MTex::MapType_EMIT)
|
||||||
|
texture_type = aiTextureType_EMISSIVE;
|
||||||
|
//else if (map_type & MTex::MapType_ALPHA)
|
||||||
|
//else if (map_type & MTex::MapType_HAR)
|
||||||
|
//else if (map_type & MTex::MapType_RAYMIRR)
|
||||||
|
//else if (map_type & MTex::MapType_TRANSLU)
|
||||||
|
else if (map_type & MTex::MapType_AMB)
|
||||||
|
texture_type = aiTextureType_AMBIENT;
|
||||||
|
else if (map_type & MTex::MapType_DISPLACE)
|
||||||
|
texture_type = aiTextureType_DISPLACEMENT;
|
||||||
|
//else if (map_type & MTex::MapType_WARP)
|
||||||
|
|
||||||
|
out->AddProperty(&name,AI_MATKEY_TEXTURE(texture_type,
|
||||||
|
conv_data.next_texture[texture_type]++));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -624,6 +659,12 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
|
||||||
ConversionData& conv_data, TempArray<std::vector,aiMesh>& temp
|
ConversionData& conv_data, TempArray<std::vector,aiMesh>& temp
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
BlenderBMeshConverter BMeshConverter( mesh );
|
||||||
|
if ( BMeshConverter.ContainsBMesh( ) )
|
||||||
|
{
|
||||||
|
mesh = BMeshConverter.TriangulateBMesh( );
|
||||||
|
}
|
||||||
|
|
||||||
typedef std::pair<const int,size_t> MyPair;
|
typedef std::pair<const int,size_t> MyPair;
|
||||||
if ((!mesh->totface && !mesh->totloop) || !mesh->totvert) {
|
if ((!mesh->totface && !mesh->totloop) || !mesh->totvert) {
|
||||||
return;
|
return;
|
||||||
|
@ -958,19 +999,41 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
aiCamera* BlenderImporter::ConvertCamera(const Scene& /*in*/, const Object* /*obj*/, const Camera* /*mesh*/, ConversionData& /*conv_data*/)
|
aiCamera* BlenderImporter::ConvertCamera(const Scene& /*in*/, const Object* obj, const Camera* camera, ConversionData& /*conv_data*/)
|
||||||
{
|
{
|
||||||
ScopeGuard<aiCamera> out(new aiCamera());
|
ScopeGuard<aiCamera> out(new aiCamera());
|
||||||
|
out->mName = obj->id.name+2;
|
||||||
return NULL ; //out.dismiss();
|
out->mPosition = aiVector3D(0.f, 0.f, 0.f);
|
||||||
|
out->mUp = aiVector3D(0.f, 1.f, 0.f);
|
||||||
|
out->mLookAt = aiVector3D(0.f, 0.f, -1.f);
|
||||||
|
return out.dismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
aiLight* BlenderImporter::ConvertLight(const Scene& /*in*/, const Object* /*obj*/, const Lamp* /*mesh*/, ConversionData& /*conv_data*/)
|
aiLight* BlenderImporter::ConvertLight(const Scene& in, const Object* obj, const Lamp* lamp, ConversionData& conv_data)
|
||||||
{
|
{
|
||||||
ScopeGuard<aiLight> out(new aiLight());
|
ScopeGuard<aiLight> out(new aiLight());
|
||||||
|
out->mName = obj->id.name+2;
|
||||||
|
|
||||||
return NULL ; //out.dismiss();
|
switch (lamp->type)
|
||||||
|
{
|
||||||
|
case Lamp::Type_Local:
|
||||||
|
out->mType = aiLightSource_POINT;
|
||||||
|
break;
|
||||||
|
case Lamp::Type_Sun:
|
||||||
|
out->mType = aiLightSource_DIRECTIONAL;
|
||||||
|
|
||||||
|
// blender orients directional lights as facing toward -z
|
||||||
|
out->mDirection = aiVector3D(0.f, 0.f, -1.f);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
out->mColorAmbient = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy;
|
||||||
|
out->mColorSpecular = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy;
|
||||||
|
out->mColorDiffuse = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy;
|
||||||
|
return out.dismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -598,6 +598,18 @@ struct Tex : ElemBase {
|
||||||
,Type_VOXELDATA = 15
|
,Type_VOXELDATA = 15
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ImageFlags {
|
||||||
|
ImageFlags_INTERPOL = 1
|
||||||
|
,ImageFlags_USEALPHA = 2
|
||||||
|
,ImageFlags_MIPMAP = 4
|
||||||
|
,ImageFlags_IMAROT = 16
|
||||||
|
,ImageFlags_CALCALPHA = 32
|
||||||
|
,ImageFlags_NORMALMAP = 2048
|
||||||
|
,ImageFlags_GAUSS_MIP = 4096
|
||||||
|
,ImageFlags_FILTER_MIN = 8192
|
||||||
|
,ImageFlags_DERIVATIVEMAP = 16384
|
||||||
|
};
|
||||||
|
|
||||||
ID id FAIL;
|
ID id FAIL;
|
||||||
// AnimData *adt;
|
// AnimData *adt;
|
||||||
|
|
||||||
|
@ -618,7 +630,8 @@ struct Tex : ElemBase {
|
||||||
//short noisedepth, noisetype;
|
//short noisedepth, noisetype;
|
||||||
//short noisebasis, noisebasis2;
|
//short noisebasis, noisebasis2;
|
||||||
|
|
||||||
//short imaflag, flag;
|
//short flag;
|
||||||
|
ImageFlags imaflag;
|
||||||
Type type FAIL;
|
Type type FAIL;
|
||||||
//short stype;
|
//short stype;
|
||||||
|
|
||||||
|
@ -685,7 +698,25 @@ struct MTex : ElemBase {
|
||||||
,BlendType_BLEND_COLOR = 13
|
,BlendType_BLEND_COLOR = 13
|
||||||
};
|
};
|
||||||
|
|
||||||
// short texco, mapto, maptoneg;
|
enum MapType {
|
||||||
|
MapType_COL = 1
|
||||||
|
,MapType_NORM = 2
|
||||||
|
,MapType_COLSPEC = 4
|
||||||
|
,MapType_COLMIR = 8
|
||||||
|
,MapType_REF = 16
|
||||||
|
,MapType_SPEC = 32
|
||||||
|
,MapType_EMIT = 64
|
||||||
|
,MapType_ALPHA = 128
|
||||||
|
,MapType_HAR = 256
|
||||||
|
,MapType_RAYMIRR = 512
|
||||||
|
,MapType_TRANSLU = 1024
|
||||||
|
,MapType_AMB = 2048
|
||||||
|
,MapType_DISPLACE = 4096
|
||||||
|
,MapType_WARP = 8192
|
||||||
|
};
|
||||||
|
|
||||||
|
// short texco, maptoneg;
|
||||||
|
MapType mapto;
|
||||||
|
|
||||||
BlendType blendtype;
|
BlendType blendtype;
|
||||||
boost::shared_ptr<Object> object;
|
boost::shared_ptr<Object> object;
|
||||||
|
@ -705,7 +736,8 @@ struct MTex : ElemBase {
|
||||||
|
|
||||||
//float colfac, varfac;
|
//float colfac, varfac;
|
||||||
|
|
||||||
//float norfac, dispfac, warpfac;
|
float norfac;
|
||||||
|
//float dispfac, warpfac;
|
||||||
float colspecfac, mirrfac, alphafac;
|
float colspecfac, mirrfac, alphafac;
|
||||||
float difffac, specfac, emitfac, hardfac;
|
float difffac, specfac, emitfac, hardfac;
|
||||||
//float raymirrfac, translfac, ambfac;
|
//float raymirrfac, translfac, ambfac;
|
||||||
|
|
|
@ -47,204 +47,204 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace Blender {
|
namespace Blender {
|
||||||
|
|
||||||
|
|
||||||
template <> void Structure :: Convert<Object> (
|
template <> void Structure :: Convert<Object> (
|
||||||
Object& dest,
|
Object& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<Group> (
|
template <> void Structure :: Convert<Group> (
|
||||||
Group& dest,
|
Group& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<MTex> (
|
template <> void Structure :: Convert<MTex> (
|
||||||
MTex& dest,
|
MTex& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<TFace> (
|
template <> void Structure :: Convert<TFace> (
|
||||||
TFace& dest,
|
TFace& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<SubsurfModifierData> (
|
template <> void Structure :: Convert<SubsurfModifierData> (
|
||||||
SubsurfModifierData& dest,
|
SubsurfModifierData& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<MFace> (
|
template <> void Structure :: Convert<MFace> (
|
||||||
MFace& dest,
|
MFace& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<Lamp> (
|
template <> void Structure :: Convert<Lamp> (
|
||||||
Lamp& dest,
|
Lamp& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<MDeformWeight> (
|
template <> void Structure :: Convert<MDeformWeight> (
|
||||||
MDeformWeight& dest,
|
MDeformWeight& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<PackedFile> (
|
template <> void Structure :: Convert<PackedFile> (
|
||||||
PackedFile& dest,
|
PackedFile& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<Base> (
|
template <> void Structure :: Convert<Base> (
|
||||||
Base& dest,
|
Base& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<MTFace> (
|
template <> void Structure :: Convert<MTFace> (
|
||||||
MTFace& dest,
|
MTFace& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<Material> (
|
template <> void Structure :: Convert<Material> (
|
||||||
Material& dest,
|
Material& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<MTexPoly> (
|
template <> void Structure :: Convert<MTexPoly> (
|
||||||
MTexPoly& dest,
|
MTexPoly& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<Mesh> (
|
template <> void Structure :: Convert<Mesh> (
|
||||||
Mesh& dest,
|
Mesh& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<MDeformVert> (
|
template <> void Structure :: Convert<MDeformVert> (
|
||||||
MDeformVert& dest,
|
MDeformVert& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<World> (
|
template <> void Structure :: Convert<World> (
|
||||||
World& dest,
|
World& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<MLoopCol> (
|
template <> void Structure :: Convert<MLoopCol> (
|
||||||
MLoopCol& dest,
|
MLoopCol& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<MVert> (
|
template <> void Structure :: Convert<MVert> (
|
||||||
MVert& dest,
|
MVert& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<MEdge> (
|
template <> void Structure :: Convert<MEdge> (
|
||||||
MEdge& dest,
|
MEdge& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<MLoopUV> (
|
template <> void Structure :: Convert<MLoopUV> (
|
||||||
MLoopUV& dest,
|
MLoopUV& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<GroupObject> (
|
template <> void Structure :: Convert<GroupObject> (
|
||||||
GroupObject& dest,
|
GroupObject& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<ListBase> (
|
template <> void Structure :: Convert<ListBase> (
|
||||||
ListBase& dest,
|
ListBase& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<MLoop> (
|
template <> void Structure :: Convert<MLoop> (
|
||||||
MLoop& dest,
|
MLoop& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<ModifierData> (
|
template <> void Structure :: Convert<ModifierData> (
|
||||||
ModifierData& dest,
|
ModifierData& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<ID> (
|
template <> void Structure :: Convert<ID> (
|
||||||
ID& dest,
|
ID& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<MCol> (
|
template <> void Structure :: Convert<MCol> (
|
||||||
MCol& dest,
|
MCol& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<MPoly> (
|
template <> void Structure :: Convert<MPoly> (
|
||||||
MPoly& dest,
|
MPoly& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<Scene> (
|
template <> void Structure :: Convert<Scene> (
|
||||||
Scene& dest,
|
Scene& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<Library> (
|
template <> void Structure :: Convert<Library> (
|
||||||
Library& dest,
|
Library& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<Tex> (
|
template <> void Structure :: Convert<Tex> (
|
||||||
Tex& dest,
|
Tex& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<Camera> (
|
template <> void Structure :: Convert<Camera> (
|
||||||
Camera& dest,
|
Camera& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<MirrorModifierData> (
|
template <> void Structure :: Convert<MirrorModifierData> (
|
||||||
MirrorModifierData& dest,
|
MirrorModifierData& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<Image> (
|
template <> void Structure :: Convert<Image> (
|
||||||
Image& dest,
|
Image& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,520 @@
|
||||||
|
/*
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2013, assimp team
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the
|
||||||
|
following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file BlenderTessellator.cpp
|
||||||
|
* @brief A simple tessellation wrapper
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AssimpPCH.h"
|
||||||
|
|
||||||
|
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
|
||||||
|
|
||||||
|
#include "BlenderDNA.h"
|
||||||
|
#include "BlenderScene.h"
|
||||||
|
#include "BlenderBMesh.h"
|
||||||
|
#include "BlenderTessellator.h"
|
||||||
|
|
||||||
|
#define BLEND_TESS_MAGIC ( 0x83ed9ac3 )
|
||||||
|
|
||||||
|
#if ASSIMP_BLEND_WITH_GLU_TESSELLATE
|
||||||
|
|
||||||
|
namespace Assimp
|
||||||
|
{
|
||||||
|
template< > const std::string LogFunctions< BlenderTessellatorGL >::log_prefix = "BLEND_TESS_GL: ";
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace Assimp;
|
||||||
|
using namespace Assimp::Blender;
|
||||||
|
|
||||||
|
#ifndef CALLBACK
|
||||||
|
#define CALLBACK
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
BlenderTessellatorGL::BlenderTessellatorGL( BlenderBMeshConverter& converter ):
|
||||||
|
converter( &converter )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
BlenderTessellatorGL::~BlenderTessellatorGL( )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BlenderTessellatorGL::Tessellate( const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices )
|
||||||
|
{
|
||||||
|
AssertVertexCount( vertexCount );
|
||||||
|
|
||||||
|
std::vector< VertexGL > polyLoopGL;
|
||||||
|
GenerateLoopVerts( polyLoopGL, polyLoop, vertexCount, vertices );
|
||||||
|
|
||||||
|
TessDataGL tessData;
|
||||||
|
Tesssellate( polyLoopGL, tessData );
|
||||||
|
|
||||||
|
TriangulateDrawCalls( tessData );
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BlenderTessellatorGL::AssertVertexCount( int vertexCount )
|
||||||
|
{
|
||||||
|
if ( vertexCount <= 4 )
|
||||||
|
{
|
||||||
|
ThrowException( "Expected more than 4 vertices for tessellation" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BlenderTessellatorGL::GenerateLoopVerts( std::vector< VertexGL >& polyLoopGL, const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices )
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < vertexCount; ++i )
|
||||||
|
{
|
||||||
|
const MLoop& loopItem = polyLoop[ i ];
|
||||||
|
const MVert& vertex = vertices[ loopItem.v ];
|
||||||
|
polyLoopGL.push_back( VertexGL( vertex.co[ 0 ], vertex.co[ 1 ], vertex.co[ 2 ], loopItem.v, BLEND_TESS_MAGIC ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BlenderTessellatorGL::Tesssellate( std::vector< VertexGL >& polyLoopGL, TessDataGL& tessData )
|
||||||
|
{
|
||||||
|
GLUtesselator* tessellator = gluNewTess( );
|
||||||
|
gluTessCallback( tessellator, GLU_TESS_BEGIN_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateBegin ) );
|
||||||
|
gluTessCallback( tessellator, GLU_TESS_END_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateEnd ) );
|
||||||
|
gluTessCallback( tessellator, GLU_TESS_VERTEX_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateVertex ) );
|
||||||
|
gluTessCallback( tessellator, GLU_TESS_COMBINE_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateCombine ) );
|
||||||
|
gluTessCallback( tessellator, GLU_TESS_EDGE_FLAG_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateEdgeFlag ) );
|
||||||
|
gluTessCallback( tessellator, GLU_TESS_ERROR_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateError ) );
|
||||||
|
gluTessProperty( tessellator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO );
|
||||||
|
|
||||||
|
gluTessBeginPolygon( tessellator, &tessData );
|
||||||
|
gluTessBeginContour( tessellator );
|
||||||
|
|
||||||
|
for ( unsigned int i = 0; i < polyLoopGL.size( ); ++i )
|
||||||
|
{
|
||||||
|
gluTessVertex( tessellator, reinterpret_cast< GLdouble* >( &polyLoopGL[ i ] ), &polyLoopGL[ i ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
gluTessEndContour( tessellator );
|
||||||
|
gluTessEndPolygon( tessellator );
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BlenderTessellatorGL::TriangulateDrawCalls( const TessDataGL& tessData )
|
||||||
|
{
|
||||||
|
// NOTE - Because we are supplying a callback to GLU_TESS_EDGE_FLAG_DATA we don't technically
|
||||||
|
// need support for GL_TRIANGLE_STRIP and GL_TRIANGLE_FAN but we'll keep it here in case
|
||||||
|
// GLU tessellate changes or tristrips and fans are wanted.
|
||||||
|
// See: http://www.opengl.org/sdk/docs/man2/xhtml/gluTessCallback.xml
|
||||||
|
for ( unsigned int i = 0; i < tessData.drawCalls.size( ); ++i )
|
||||||
|
{
|
||||||
|
const DrawCallGL& drawCallGL = tessData.drawCalls[ i ];
|
||||||
|
const VertexGL* vertices = &tessData.vertices[ drawCallGL.baseVertex ];
|
||||||
|
if ( drawCallGL.drawMode == GL_TRIANGLES )
|
||||||
|
{
|
||||||
|
MakeFacesFromTris( vertices, drawCallGL.vertexCount );
|
||||||
|
}
|
||||||
|
else if ( drawCallGL.drawMode == GL_TRIANGLE_STRIP )
|
||||||
|
{
|
||||||
|
MakeFacesFromTriStrip( vertices, drawCallGL.vertexCount );
|
||||||
|
}
|
||||||
|
else if ( drawCallGL.drawMode == GL_TRIANGLE_FAN )
|
||||||
|
{
|
||||||
|
MakeFacesFromTriFan( vertices, drawCallGL.vertexCount );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BlenderTessellatorGL::MakeFacesFromTris( const VertexGL* vertices, int vertexCount )
|
||||||
|
{
|
||||||
|
int triangleCount = vertexCount / 3;
|
||||||
|
for ( int i = 0; i < triangleCount; ++i )
|
||||||
|
{
|
||||||
|
int vertexBase = i * 3;
|
||||||
|
converter->AddFace( vertices[ vertexBase + 0 ].index, vertices[ vertexBase + 1 ].index, vertices[ vertexBase + 2 ].index );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BlenderTessellatorGL::MakeFacesFromTriStrip( const VertexGL* vertices, int vertexCount )
|
||||||
|
{
|
||||||
|
int triangleCount = vertexCount - 2;
|
||||||
|
for ( int i = 0; i < triangleCount; ++i )
|
||||||
|
{
|
||||||
|
int vertexBase = i;
|
||||||
|
converter->AddFace( vertices[ vertexBase + 0 ].index, vertices[ vertexBase + 1 ].index, vertices[ vertexBase + 2 ].index );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BlenderTessellatorGL::MakeFacesFromTriFan( const VertexGL* vertices, int vertexCount )
|
||||||
|
{
|
||||||
|
int triangleCount = vertexCount - 2;
|
||||||
|
for ( int i = 0; i < triangleCount; ++i )
|
||||||
|
{
|
||||||
|
int vertexBase = i;
|
||||||
|
converter->AddFace( vertices[ 0 ].index, vertices[ vertexBase + 1 ].index, vertices[ vertexBase + 2 ].index );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BlenderTessellatorGL::TessellateBegin( GLenum drawModeGL, void* userData )
|
||||||
|
{
|
||||||
|
TessDataGL& tessData = *reinterpret_cast< TessDataGL* >( userData );
|
||||||
|
tessData.drawCalls.push_back( DrawCallGL( drawModeGL, tessData.vertices.size( ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BlenderTessellatorGL::TessellateEnd( void* )
|
||||||
|
{
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BlenderTessellatorGL::TessellateVertex( const void* vtxData, void* userData )
|
||||||
|
{
|
||||||
|
TessDataGL& tessData = *reinterpret_cast< TessDataGL* >( userData );
|
||||||
|
|
||||||
|
const VertexGL& vertex = *reinterpret_cast< const VertexGL* >( vtxData );
|
||||||
|
if ( vertex.magic != BLEND_TESS_MAGIC )
|
||||||
|
{
|
||||||
|
ThrowException( "Point returned by GLU Tessellate was probably not one of ours. This indicates we need a new way to store vertex information" );
|
||||||
|
}
|
||||||
|
tessData.vertices.push_back( vertex );
|
||||||
|
if ( tessData.drawCalls.size( ) == 0 )
|
||||||
|
{
|
||||||
|
ThrowException( "\"Vertex\" callback received before \"Begin\"" );
|
||||||
|
}
|
||||||
|
++( tessData.drawCalls.back( ).vertexCount );
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BlenderTessellatorGL::TessellateCombine( const GLdouble intersection[ 3 ], const GLdouble* [ 4 ], const GLfloat [ 4 ], GLdouble** out, void* userData )
|
||||||
|
{
|
||||||
|
ThrowException( "Intersected polygon loops are not yet supported" );
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BlenderTessellatorGL::TessellateEdgeFlag( GLboolean, void* )
|
||||||
|
{
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BlenderTessellatorGL::TessellateError( GLenum errorCode, void* )
|
||||||
|
{
|
||||||
|
ThrowException( reinterpret_cast< const char* >( gluErrorString( errorCode ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // ASSIMP_BLEND_WITH_GLU_TESSELLATE
|
||||||
|
|
||||||
|
#if ASSIMP_BLEND_WITH_POLY_2_TRI
|
||||||
|
|
||||||
|
namespace Assimp
|
||||||
|
{
|
||||||
|
template< > const std::string LogFunctions< BlenderTessellatorP2T >::log_prefix = "BLEND_TESS_P2T: ";
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace Assimp;
|
||||||
|
using namespace Assimp::Blender;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
BlenderTessellatorP2T::BlenderTessellatorP2T( BlenderBMeshConverter& converter ):
|
||||||
|
converter( &converter )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
BlenderTessellatorP2T::~BlenderTessellatorP2T( )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BlenderTessellatorP2T::Tessellate( const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices )
|
||||||
|
{
|
||||||
|
AssertVertexCount( vertexCount );
|
||||||
|
|
||||||
|
// NOTE - We have to hope that points in a Blender polygon are roughly on the same plane.
|
||||||
|
// There may be some triangulation artifacts if they are wildly different.
|
||||||
|
|
||||||
|
std::vector< PointP2T > points;
|
||||||
|
Copy3DVertices( polyLoop, vertexCount, vertices, points );
|
||||||
|
|
||||||
|
PlaneP2T plane = FindLLSQPlane( points );
|
||||||
|
|
||||||
|
aiMatrix4x4 transform = GeneratePointTransformMatrix( plane );
|
||||||
|
|
||||||
|
TransformAndFlattenVectices( transform, points );
|
||||||
|
|
||||||
|
std::vector< p2t::Point* > pointRefs;
|
||||||
|
ReferencePoints( points, pointRefs );
|
||||||
|
|
||||||
|
p2t::CDT cdt( pointRefs );
|
||||||
|
|
||||||
|
cdt.Triangulate( );
|
||||||
|
std::vector< p2t::Triangle* > triangles = cdt.GetTriangles( );
|
||||||
|
|
||||||
|
MakeFacesFromTriangles( triangles );
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BlenderTessellatorP2T::AssertVertexCount( int vertexCount )
|
||||||
|
{
|
||||||
|
if ( vertexCount <= 4 )
|
||||||
|
{
|
||||||
|
ThrowException( "Expected more than 4 vertices for tessellation" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BlenderTessellatorP2T::Copy3DVertices( const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices, std::vector< PointP2T >& points ) const
|
||||||
|
{
|
||||||
|
points.resize( vertexCount );
|
||||||
|
for ( int i = 0; i < vertexCount; ++i )
|
||||||
|
{
|
||||||
|
const MLoop& loop = polyLoop[ i ];
|
||||||
|
const MVert& vert = vertices[ loop.v ];
|
||||||
|
|
||||||
|
PointP2T& point = points[ i ];
|
||||||
|
point.point3D.Set( vert.co[ 0 ], vert.co[ 1 ], vert.co[ 2 ] );
|
||||||
|
point.index = loop.v;
|
||||||
|
point.magic = BLEND_TESS_MAGIC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
aiMatrix4x4 BlenderTessellatorP2T::GeneratePointTransformMatrix( const Blender::PlaneP2T& plane ) const
|
||||||
|
{
|
||||||
|
aiVector3D sideA( 1.0f, 0.0f, 0.0f );
|
||||||
|
if ( fabs( plane.normal * sideA ) > 0.999f )
|
||||||
|
{
|
||||||
|
sideA = aiVector3D( 0.0f, 1.0f, 0.0f );
|
||||||
|
}
|
||||||
|
|
||||||
|
aiVector3D sideB( plane.normal ^ sideA );
|
||||||
|
sideB.Normalize( );
|
||||||
|
sideA = sideB ^ plane.normal;
|
||||||
|
|
||||||
|
aiMatrix4x4 result;
|
||||||
|
result.a1 = sideA.x;
|
||||||
|
result.a2 = sideA.y;
|
||||||
|
result.a3 = sideA.z;
|
||||||
|
result.b1 = sideB.x;
|
||||||
|
result.b2 = sideB.y;
|
||||||
|
result.b3 = sideB.z;
|
||||||
|
result.c1 = plane.normal.x;
|
||||||
|
result.c2 = plane.normal.y;
|
||||||
|
result.c3 = plane.normal.z;
|
||||||
|
result.a4 = plane.centre.x;
|
||||||
|
result.b4 = plane.centre.y;
|
||||||
|
result.c4 = plane.centre.z;
|
||||||
|
result.Inverse( );
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BlenderTessellatorP2T::TransformAndFlattenVectices( const aiMatrix4x4& transform, std::vector< Blender::PointP2T >& vertices ) const
|
||||||
|
{
|
||||||
|
for ( unsigned int i = 0; i < vertices.size( ); ++i )
|
||||||
|
{
|
||||||
|
PointP2T& point = vertices[ i ];
|
||||||
|
point.point3D = transform * point.point3D;
|
||||||
|
point.point2D.set( point.point3D.y, point.point3D.z );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BlenderTessellatorP2T::ReferencePoints( std::vector< Blender::PointP2T >& points, std::vector< p2t::Point* >& pointRefs ) const
|
||||||
|
{
|
||||||
|
pointRefs.resize( points.size( ) );
|
||||||
|
for ( unsigned int i = 0; i < points.size( ); ++i )
|
||||||
|
{
|
||||||
|
pointRefs[ i ] = &points[ i ].point2D;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Yes this is filthy... but we have no choice
|
||||||
|
#define OffsetOf( Class, Member ) ( static_cast< unsigned int >( \
|
||||||
|
reinterpret_cast<uint8_t*>(&( reinterpret_cast< Class* >( NULL )->*( &Class::Member ) )) - \
|
||||||
|
static_cast<uint8_t*>(NULL) ) )
|
||||||
|
|
||||||
|
inline PointP2T& BlenderTessellatorP2T::GetActualPointStructure( p2t::Point& point ) const
|
||||||
|
{
|
||||||
|
unsigned int pointOffset = OffsetOf( PointP2T, point2D );
|
||||||
|
PointP2T& pointStruct = *reinterpret_cast< PointP2T* >( reinterpret_cast< char* >( &point ) - pointOffset );
|
||||||
|
if ( pointStruct.magic != BLEND_TESS_MAGIC )
|
||||||
|
{
|
||||||
|
ThrowException( "Point returned by poly2tri was probably not one of ours. This indicates we need a new way to store vertex information" );
|
||||||
|
}
|
||||||
|
return pointStruct;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BlenderTessellatorP2T::MakeFacesFromTriangles( std::vector< p2t::Triangle* >& triangles ) const
|
||||||
|
{
|
||||||
|
for ( unsigned int i = 0; i < triangles.size( ); ++i )
|
||||||
|
{
|
||||||
|
p2t::Triangle& Triangle = *triangles[ i ];
|
||||||
|
|
||||||
|
PointP2T& pointA = GetActualPointStructure( *Triangle.GetPoint( 0 ) );
|
||||||
|
PointP2T& pointB = GetActualPointStructure( *Triangle.GetPoint( 1 ) );
|
||||||
|
PointP2T& pointC = GetActualPointStructure( *Triangle.GetPoint( 2 ) );
|
||||||
|
|
||||||
|
converter->AddFace( pointA.index, pointB.index, pointC.index );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
inline float p2tMax( float a, float b )
|
||||||
|
{
|
||||||
|
return a > b ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Adapted from: http://missingbytes.blogspot.co.uk/2012/06/fitting-plane-to-point-cloud.html
|
||||||
|
float BlenderTessellatorP2T::FindLargestMatrixElem( const aiMatrix3x3& mtx ) const
|
||||||
|
{
|
||||||
|
float result = 0.0f;
|
||||||
|
|
||||||
|
for ( int x = 0; x < 3; ++x )
|
||||||
|
{
|
||||||
|
for ( int y = 0; y < 3; ++y )
|
||||||
|
{
|
||||||
|
result = p2tMax( fabs( mtx[ x ][ y ] ), result );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Aparently Assimp doesn't have matrix scaling
|
||||||
|
aiMatrix3x3 BlenderTessellatorP2T::ScaleMatrix( const aiMatrix3x3& mtx, float scale ) const
|
||||||
|
{
|
||||||
|
aiMatrix3x3 result;
|
||||||
|
|
||||||
|
for ( int x = 0; x < 3; ++x )
|
||||||
|
{
|
||||||
|
for ( int y = 0; y < 3; ++y )
|
||||||
|
{
|
||||||
|
result[ x ][ y ] = mtx[ x ][ y ] * scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Adapted from: http://missingbytes.blogspot.co.uk/2012/06/fitting-plane-to-point-cloud.html
|
||||||
|
aiVector3D BlenderTessellatorP2T::GetEigenVectorFromLargestEigenValue( const aiMatrix3x3& mtx ) const
|
||||||
|
{
|
||||||
|
float scale = FindLargestMatrixElem( mtx );
|
||||||
|
aiMatrix3x3 mc = ScaleMatrix( mtx, 1.0f / scale );
|
||||||
|
mc = mc * mc * mc;
|
||||||
|
|
||||||
|
aiVector3D v( 1.0f );
|
||||||
|
aiVector3D lastV = v;
|
||||||
|
for ( int i = 0; i < 100; ++i )
|
||||||
|
{
|
||||||
|
v = mc * v;
|
||||||
|
v.Normalize( );
|
||||||
|
if ( ( v - lastV ).SquareLength( ) < 1e-16f )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lastV = v;
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Adapted from: http://missingbytes.blogspot.co.uk/2012/06/fitting-plane-to-point-cloud.html
|
||||||
|
PlaneP2T BlenderTessellatorP2T::FindLLSQPlane( const std::vector< PointP2T >& points ) const
|
||||||
|
{
|
||||||
|
PlaneP2T result;
|
||||||
|
|
||||||
|
aiVector3D sum( 0.0f );
|
||||||
|
for ( unsigned int i = 0; i < points.size( ); ++i )
|
||||||
|
{
|
||||||
|
sum += points[ i ].point3D;
|
||||||
|
}
|
||||||
|
result.centre = sum * ( 1.0f / points.size( ) );
|
||||||
|
|
||||||
|
float sumXX = 0.0f;
|
||||||
|
float sumXY = 0.0f;
|
||||||
|
float sumXZ = 0.0f;
|
||||||
|
float sumYY = 0.0f;
|
||||||
|
float sumYZ = 0.0f;
|
||||||
|
float sumZZ = 0.0f;
|
||||||
|
for ( unsigned int i = 0; i < points.size( ); ++i )
|
||||||
|
{
|
||||||
|
aiVector3D offset = points[ i ].point3D - result.centre;
|
||||||
|
sumXX += offset.x * offset.x;
|
||||||
|
sumXY += offset.x * offset.y;
|
||||||
|
sumXZ += offset.x * offset.z;
|
||||||
|
sumYY += offset.y * offset.y;
|
||||||
|
sumYZ += offset.y * offset.z;
|
||||||
|
sumZZ += offset.z * offset.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
aiMatrix3x3 mtx( sumXX, sumXY, sumXZ, sumXY, sumYY, sumYZ, sumXZ, sumYZ, sumZZ );
|
||||||
|
|
||||||
|
float det = mtx.Determinant( );
|
||||||
|
if ( det == 0.0f )
|
||||||
|
{
|
||||||
|
result.normal = aiVector3D( 0.0f );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
aiMatrix3x3 invMtx = mtx;
|
||||||
|
invMtx.Inverse( );
|
||||||
|
result.normal = GetEigenVectorFromLargestEigenValue( invMtx );
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // ASSIMP_BLEND_WITH_POLY_2_TRI
|
||||||
|
|
||||||
|
#endif // ASSIMP_BUILD_NO_BLEND_IMPORTER
|
|
@ -0,0 +1,208 @@
|
||||||
|
/*
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2013, assimp team
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the
|
||||||
|
following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file BlenderTessellator.h
|
||||||
|
* @brief A simple tessellation wrapper
|
||||||
|
*/
|
||||||
|
#ifndef INCLUDED_AI_BLEND_TESSELLATOR_H
|
||||||
|
#define INCLUDED_AI_BLEND_TESSELLATOR_H
|
||||||
|
|
||||||
|
// Use these to toggle between GLU Tessellate or poly2tri
|
||||||
|
// Note (acg) keep GLU Tesselate disabled by default - if it is turned on,
|
||||||
|
// assimp needs to be linked against GLU, which is currently not yet
|
||||||
|
// made configurable in CMake and potentially not wanted by most users
|
||||||
|
// as it requires a Gl environment.
|
||||||
|
#ifndef ASSIMP_BLEND_WITH_GLU_TESSELLATE
|
||||||
|
# define ASSIMP_BLEND_WITH_GLU_TESSELLATE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ASSIMP_BLEND_WITH_POLY_2_TRI
|
||||||
|
# define ASSIMP_BLEND_WITH_POLY_2_TRI 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "LogAux.h"
|
||||||
|
|
||||||
|
#if ASSIMP_BLEND_WITH_GLU_TESSELLATE
|
||||||
|
|
||||||
|
#if defined( WIN32 ) || defined( _WIN32 ) || defined( _MSC_VER )
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
#include <GL/glu.h>
|
||||||
|
|
||||||
|
namespace Assimp
|
||||||
|
{
|
||||||
|
class BlenderBMeshConverter;
|
||||||
|
|
||||||
|
// TinyFormatter.h
|
||||||
|
namespace Formatter
|
||||||
|
{
|
||||||
|
template < typename T,typename TR, typename A > class basic_formatter;
|
||||||
|
typedef class basic_formatter< char, std::char_traits< char >, std::allocator< char > > format;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlenderScene.h
|
||||||
|
namespace Blender
|
||||||
|
{
|
||||||
|
struct MLoop;
|
||||||
|
struct MVert;
|
||||||
|
|
||||||
|
struct VertexGL
|
||||||
|
{
|
||||||
|
GLdouble X;
|
||||||
|
GLdouble Y;
|
||||||
|
GLdouble Z;
|
||||||
|
int index;
|
||||||
|
int magic;
|
||||||
|
|
||||||
|
VertexGL( GLdouble X, GLdouble Y, GLdouble Z, int index, int magic ): X( X ), Y( Y ), Z( Z ), index( index ), magic( magic ) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DrawCallGL
|
||||||
|
{
|
||||||
|
GLenum drawMode;
|
||||||
|
int baseVertex;
|
||||||
|
int vertexCount;
|
||||||
|
|
||||||
|
DrawCallGL( GLenum drawMode, int baseVertex ): drawMode( drawMode ), baseVertex( baseVertex ), vertexCount( 0 ) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TessDataGL
|
||||||
|
{
|
||||||
|
std::vector< DrawCallGL > drawCalls;
|
||||||
|
std::vector< VertexGL > vertices;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class BlenderTessellatorGL: public LogFunctions< BlenderTessellatorGL >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BlenderTessellatorGL( BlenderBMeshConverter& converter );
|
||||||
|
~BlenderTessellatorGL( );
|
||||||
|
|
||||||
|
void Tessellate( const Blender::MLoop* polyLoop, int vertexCount, const std::vector< Blender::MVert >& vertices );
|
||||||
|
|
||||||
|
private:
|
||||||
|
void AssertVertexCount( int vertexCount );
|
||||||
|
void GenerateLoopVerts( std::vector< Blender::VertexGL >& polyLoopGL, const Blender::MLoop* polyLoop, int vertexCount, const std::vector< Blender::MVert >& vertices );
|
||||||
|
void Tesssellate( std::vector< Blender::VertexGL >& polyLoopGL, Blender::TessDataGL& tessData );
|
||||||
|
void TriangulateDrawCalls( const Blender::TessDataGL& tessData );
|
||||||
|
void MakeFacesFromTris( const Blender::VertexGL* vertices, int vertexCount );
|
||||||
|
void MakeFacesFromTriStrip( const Blender::VertexGL* vertices, int vertexCount );
|
||||||
|
void MakeFacesFromTriFan( const Blender::VertexGL* vertices, int vertexCount );
|
||||||
|
|
||||||
|
static void TessellateBegin( GLenum drawModeGL, void* userData );
|
||||||
|
static void TessellateEnd( void* userData );
|
||||||
|
static void TessellateVertex( const void* vtxData, void* userData );
|
||||||
|
static void TessellateCombine( const GLdouble intersection[ 3 ], const GLdouble* [ 4 ], const GLfloat [ 4 ], GLdouble** out, void* userData );
|
||||||
|
static void TessellateEdgeFlag( GLboolean edgeFlag, void* userData );
|
||||||
|
static void TessellateError( GLenum errorCode, void* userData );
|
||||||
|
|
||||||
|
BlenderBMeshConverter* converter;
|
||||||
|
};
|
||||||
|
} // end of namespace Assimp
|
||||||
|
|
||||||
|
#endif // ASSIMP_BLEND_WITH_GLU_TESSELLATE
|
||||||
|
|
||||||
|
#if ASSIMP_BLEND_WITH_POLY_2_TRI
|
||||||
|
|
||||||
|
#include "../contrib/poly2tri/poly2tri/poly2tri.h"
|
||||||
|
|
||||||
|
namespace Assimp
|
||||||
|
{
|
||||||
|
class BlenderBMeshConverter;
|
||||||
|
|
||||||
|
// TinyFormatter.h
|
||||||
|
namespace Formatter
|
||||||
|
{
|
||||||
|
template < typename T,typename TR, typename A > class basic_formatter;
|
||||||
|
typedef class basic_formatter< char, std::char_traits< char >, std::allocator< char > > format;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlenderScene.h
|
||||||
|
namespace Blender
|
||||||
|
{
|
||||||
|
struct MLoop;
|
||||||
|
struct MVert;
|
||||||
|
|
||||||
|
struct PointP2T
|
||||||
|
{
|
||||||
|
aiVector3D point3D;
|
||||||
|
p2t::Point point2D;
|
||||||
|
int magic;
|
||||||
|
int index;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PlaneP2T
|
||||||
|
{
|
||||||
|
aiVector3D centre;
|
||||||
|
aiVector3D normal;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class BlenderTessellatorP2T: public LogFunctions< BlenderTessellatorP2T >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BlenderTessellatorP2T( BlenderBMeshConverter& converter );
|
||||||
|
~BlenderTessellatorP2T( );
|
||||||
|
|
||||||
|
void Tessellate( const Blender::MLoop* polyLoop, int vertexCount, const std::vector< Blender::MVert >& vertices );
|
||||||
|
|
||||||
|
private:
|
||||||
|
void AssertVertexCount( int vertexCount );
|
||||||
|
void Copy3DVertices( const Blender::MLoop* polyLoop, int vertexCount, const std::vector< Blender::MVert >& vertices, std::vector< Blender::PointP2T >& targetVertices ) const;
|
||||||
|
aiMatrix4x4 GeneratePointTransformMatrix( const Blender::PlaneP2T& plane ) const;
|
||||||
|
void TransformAndFlattenVectices( const aiMatrix4x4& transform, std::vector< Blender::PointP2T >& vertices ) const;
|
||||||
|
void ReferencePoints( std::vector< Blender::PointP2T >& points, std::vector< p2t::Point* >& pointRefs ) const;
|
||||||
|
inline Blender::PointP2T& GetActualPointStructure( p2t::Point& point ) const;
|
||||||
|
void MakeFacesFromTriangles( std::vector< p2t::Triangle* >& triangles ) const;
|
||||||
|
|
||||||
|
// Adapted from: http://missingbytes.blogspot.co.uk/2012/06/fitting-plane-to-point-cloud.html
|
||||||
|
float FindLargestMatrixElem( const aiMatrix3x3& mtx ) const;
|
||||||
|
aiMatrix3x3 ScaleMatrix( const aiMatrix3x3& mtx, float scale ) const;
|
||||||
|
aiVector3D GetEigenVectorFromLargestEigenValue( const aiMatrix3x3& mtx ) const;
|
||||||
|
Blender::PlaneP2T FindLLSQPlane( const std::vector< Blender::PointP2T >& points ) const;
|
||||||
|
|
||||||
|
BlenderBMeshConverter* converter;
|
||||||
|
};
|
||||||
|
} // end of namespace Assimp
|
||||||
|
|
||||||
|
#endif // ASSIMP_BLEND_WITH_POLY_2_TRI
|
||||||
|
|
||||||
|
#endif // INCLUDED_AI_BLEND_TESSELLATOR_H
|
|
@ -88,9 +88,9 @@ public:
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
virtual size_t Read(void* pvBuffer,
|
virtual size_t Read( void *,
|
||||||
size_t pSize,
|
size_t,
|
||||||
size_t pCount)
|
size_t )
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#ifndef __AI_BOOST_WORKAROUND_LEXICAL_CAST
|
#ifndef __AI_BOOST_WORKAROUND_LEXICAL_CAST
|
||||||
#define __AI_BOOST_WORKAROUND_LEXICAL_CAST
|
#define __AI_BOOST_WORKAROUND_LEXICAL_CAST
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -362,6 +362,10 @@ SET(BLENDER_SRCS
|
||||||
BlenderIntermediate.h
|
BlenderIntermediate.h
|
||||||
BlenderModifier.h
|
BlenderModifier.h
|
||||||
BlenderModifier.cpp
|
BlenderModifier.cpp
|
||||||
|
BlenderBMesh.h
|
||||||
|
BlenderBMesh.cpp
|
||||||
|
BlenderTessellator.h
|
||||||
|
BlenderTessellator.cpp
|
||||||
)
|
)
|
||||||
SOURCE_GROUP( BLENDER FILES ${BLENDER_SRCS})
|
SOURCE_GROUP( BLENDER FILES ${BLENDER_SRCS})
|
||||||
|
|
||||||
|
|
|
@ -235,9 +235,13 @@ void ColladaExporter::WriteMaterials()
|
||||||
if( mat->Get( AI_MATKEY_NAME, name) != aiReturn_SUCCESS )
|
if( mat->Get( AI_MATKEY_NAME, name) != aiReturn_SUCCESS )
|
||||||
name = "mat";
|
name = "mat";
|
||||||
materials[a].name = std::string( "m") + boost::lexical_cast<std::string> (a) + name.C_Str();
|
materials[a].name = std::string( "m") + boost::lexical_cast<std::string> (a) + name.C_Str();
|
||||||
for( std::string::iterator it = materials[a].name.begin(); it != materials[a].name.end(); ++it )
|
for( std::string::iterator it = materials[a].name.begin(); it != materials[a].name.end(); ++it ) {
|
||||||
if( !isalnum( *it) )
|
// isalnum on MSVC asserts for code points in [0,255]. Thus prevent unwanted promotion
|
||||||
|
// of char to signed int and take the unsigned char value.
|
||||||
|
if( !isalnum( static_cast<uint8_t>(*it) ) ) {
|
||||||
*it = '_';
|
*it = '_';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ReadMaterialSurface( materials[a].ambient, mat, aiTextureType_AMBIENT, AI_MATKEY_COLOR_AMBIENT);
|
ReadMaterialSurface( materials[a].ambient, mat, aiTextureType_AMBIENT, AI_MATKEY_COLOR_AMBIENT);
|
||||||
if( !materials[a].ambient.texture.empty() ) numTextures++;
|
if( !materials[a].ambient.texture.empty() ) numTextures++;
|
||||||
|
|
|
@ -321,6 +321,8 @@ struct Mesh
|
||||||
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
|
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
|
||||||
mNumUVComponents[i] = 2;
|
mNumUVComponents[i] = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string mName;
|
||||||
|
|
||||||
// just to check if there's some sophisticated addressing involved...
|
// just to check if there's some sophisticated addressing involved...
|
||||||
// which we don't support, and therefore should warn about.
|
// which we don't support, and therefore should warn about.
|
||||||
|
|
|
@ -73,7 +73,7 @@ static const aiImporterDesc desc = {
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
ColladaLoader::ColladaLoader()
|
ColladaLoader::ColladaLoader()
|
||||||
: noSkeletonMesh()
|
: noSkeletonMesh(), ignoreUpDirection(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -108,6 +108,7 @@ bool ColladaLoader::CanRead( const std::string& pFile, IOSystem* pIOHandler, boo
|
||||||
void ColladaLoader::SetupProperties(const Importer* pImp)
|
void ColladaLoader::SetupProperties(const Importer* pImp)
|
||||||
{
|
{
|
||||||
noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0;
|
noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0;
|
||||||
|
ignoreUpDirection = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION,0) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -160,21 +161,21 @@ void ColladaLoader::InternReadFile( const std::string& pFile, aiScene* pScene, I
|
||||||
0, parser.mUnitSize, 0, 0,
|
0, parser.mUnitSize, 0, 0,
|
||||||
0, 0, parser.mUnitSize, 0,
|
0, 0, parser.mUnitSize, 0,
|
||||||
0, 0, 0, 1);
|
0, 0, 0, 1);
|
||||||
|
if( !ignoreUpDirection ) {
|
||||||
// Convert to Y_UP, if different orientation
|
// Convert to Y_UP, if different orientation
|
||||||
if( parser.mUpDirection == ColladaParser::UP_X)
|
if( parser.mUpDirection == ColladaParser::UP_X)
|
||||||
pScene->mRootNode->mTransformation *= aiMatrix4x4(
|
pScene->mRootNode->mTransformation *= aiMatrix4x4(
|
||||||
0, -1, 0, 0,
|
0, -1, 0, 0,
|
||||||
1, 0, 0, 0,
|
1, 0, 0, 0,
|
||||||
0, 0, 1, 0,
|
0, 0, 1, 0,
|
||||||
0, 0, 0, 1);
|
0, 0, 0, 1);
|
||||||
else if( parser.mUpDirection == ColladaParser::UP_Z)
|
else if( parser.mUpDirection == ColladaParser::UP_Z)
|
||||||
pScene->mRootNode->mTransformation *= aiMatrix4x4(
|
pScene->mRootNode->mTransformation *= aiMatrix4x4(
|
||||||
1, 0, 0, 0,
|
1, 0, 0, 0,
|
||||||
0, 0, 1, 0,
|
0, 0, 1, 0,
|
||||||
0, -1, 0, 0,
|
0, -1, 0, 0,
|
||||||
0, 0, 0, 1);
|
0, 0, 0, 1);
|
||||||
|
}
|
||||||
// store all meshes
|
// store all meshes
|
||||||
StoreSceneMeshes( pScene);
|
StoreSceneMeshes( pScene);
|
||||||
|
|
||||||
|
@ -520,7 +521,10 @@ void ColladaLoader::BuildMeshesForNode( const ColladaParser& pParser, const Coll
|
||||||
|
|
||||||
// assign the material index
|
// assign the material index
|
||||||
dstMesh->mMaterialIndex = matIdx;
|
dstMesh->mMaterialIndex = matIdx;
|
||||||
dstMesh->mName = mid.mMeshOrController;
|
if(dstMesh->mName.length == 0)
|
||||||
|
{
|
||||||
|
dstMesh->mName = mid.mMeshOrController;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -540,6 +544,8 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
|
||||||
const Collada::Controller* pSrcController, size_t pStartVertex, size_t pStartFace)
|
const Collada::Controller* pSrcController, size_t pStartVertex, size_t pStartFace)
|
||||||
{
|
{
|
||||||
aiMesh* dstMesh = new aiMesh;
|
aiMesh* dstMesh = new aiMesh;
|
||||||
|
|
||||||
|
dstMesh->mName = pSrcMesh->mName;
|
||||||
|
|
||||||
// count the vertices addressed by its faces
|
// count the vertices addressed by its faces
|
||||||
const size_t numVertices = std::accumulate( pSrcMesh->mFaceSize.begin() + pStartFace,
|
const size_t numVertices = std::accumulate( pSrcMesh->mFaceSize.begin() + pStartFace,
|
||||||
|
|
|
@ -234,6 +234,7 @@ protected:
|
||||||
std::vector<aiAnimation*> mAnims;
|
std::vector<aiAnimation*> mAnims;
|
||||||
|
|
||||||
bool noSkeletonMesh;
|
bool noSkeletonMesh;
|
||||||
|
bool ignoreUpDirection;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
|
@ -1492,6 +1492,13 @@ void ColladaParser::ReadGeometryLibrary()
|
||||||
// create a mesh and store it in the library under its ID
|
// create a mesh and store it in the library under its ID
|
||||||
Mesh* mesh = new Mesh;
|
Mesh* mesh = new Mesh;
|
||||||
mMeshLibrary[id] = mesh;
|
mMeshLibrary[id] = mesh;
|
||||||
|
|
||||||
|
// read the mesh name if it exists
|
||||||
|
const int nameIndex = TestAttribute("name");
|
||||||
|
if(nameIndex != -1)
|
||||||
|
{
|
||||||
|
mesh->mName = mReader->getAttributeValue(nameIndex);
|
||||||
|
}
|
||||||
|
|
||||||
// read on from there
|
// read on from there
|
||||||
ReadGeometry( mesh);
|
ReadGeometry( mesh);
|
||||||
|
|
|
@ -110,7 +110,14 @@ size_t DefaultIOStream::FileSize() const
|
||||||
|
|
||||||
if (SIZE_MAX == cachedSize) {
|
if (SIZE_MAX == cachedSize) {
|
||||||
|
|
||||||
// TODO: Is that really faster if we're already owning a handle to the file?
|
// Although fseek/ftell would allow us to reuse the exising file handle here,
|
||||||
|
// it is generally unsafe because:
|
||||||
|
// - For binary streams, it is not technically well-defined
|
||||||
|
// - For text files the results are meaningless
|
||||||
|
// That's why we use the safer variant fstat here.
|
||||||
|
//
|
||||||
|
// See here for details:
|
||||||
|
// https://www.securecoding.cert.org/confluence/display/seccode/FIO19-C.+Do+not+use+fseek()+and+ftell()+to+compute+the+size+of+a+regular+file
|
||||||
#if defined _WIN32 && !defined __GNUC__
|
#if defined _WIN32 && !defined __GNUC__
|
||||||
struct __stat64 fileStat;
|
struct __stat64 fileStat;
|
||||||
int err = _stat64( mFilename.c_str(), &fileStat );
|
int err = _stat64( mFilename.c_str(), &fileStat );
|
||||||
|
|
|
@ -60,6 +60,7 @@ Here we implement only the C++ interface (Assimp::Exporter).
|
||||||
#include "BaseProcess.h"
|
#include "BaseProcess.h"
|
||||||
#include "Importer.h" // need this for GetPostProcessingStepInstanceList()
|
#include "Importer.h" // need this for GetPostProcessingStepInstanceList()
|
||||||
|
|
||||||
|
#include "JoinVerticesProcess.h"
|
||||||
#include "MakeVerboseFormat.h"
|
#include "MakeVerboseFormat.h"
|
||||||
#include "ConvertToLHProcess.h"
|
#include "ConvertToLHProcess.h"
|
||||||
|
|
||||||
|
@ -73,6 +74,7 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out);
|
||||||
void ExportSceneCollada(const char*,IOSystem*, const aiScene*);
|
void ExportSceneCollada(const char*,IOSystem*, const aiScene*);
|
||||||
void ExportSceneObj(const char*,IOSystem*, const aiScene*);
|
void ExportSceneObj(const char*,IOSystem*, const aiScene*);
|
||||||
void ExportSceneSTL(const char*,IOSystem*, const aiScene*);
|
void ExportSceneSTL(const char*,IOSystem*, const aiScene*);
|
||||||
|
void ExportSceneSTLBinary(const char*,IOSystem*, const aiScene*);
|
||||||
void ExportScenePly(const char*,IOSystem*, const aiScene*);
|
void ExportScenePly(const char*,IOSystem*, const aiScene*);
|
||||||
void ExportScene3DS(const char*, IOSystem*, const aiScene*) {}
|
void ExportScene3DS(const char*, IOSystem*, const aiScene*) {}
|
||||||
|
|
||||||
|
@ -86,13 +88,16 @@ Exporter::ExportFormatEntry gExporters[] =
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER
|
||||||
Exporter::ExportFormatEntry( "obj", "Wavefront OBJ format", "obj", &ExportSceneObj,
|
Exporter::ExportFormatEntry( "obj", "Wavefront OBJ format", "obj", &ExportSceneObj,
|
||||||
aiProcess_GenNormals | aiProcess_PreTransformVertices),
|
aiProcess_GenSmoothNormals /*| aiProcess_PreTransformVertices */),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_STL_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_STL_EXPORTER
|
||||||
Exporter::ExportFormatEntry( "stl", "Stereolithography", "stl" , &ExportSceneSTL,
|
Exporter::ExportFormatEntry( "stl", "Stereolithography", "stl" , &ExportSceneSTL,
|
||||||
aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_PreTransformVertices
|
aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_PreTransformVertices
|
||||||
),
|
),
|
||||||
|
Exporter::ExportFormatEntry( "stlb", "Stereolithography(binary)", "stlb" , &ExportSceneSTLBinary,
|
||||||
|
aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_PreTransformVertices
|
||||||
|
),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_PLY_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_PLY_EXPORTER
|
||||||
|
@ -197,7 +202,7 @@ bool Exporter :: IsDefaultIOHandler() const
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const aiExportDataBlob* Exporter :: ExportToBlob( const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing )
|
const aiExportDataBlob* Exporter :: ExportToBlob( const aiScene* pScene, const char* pFormatId, unsigned int )
|
||||||
{
|
{
|
||||||
if (pimpl->blob) {
|
if (pimpl->blob) {
|
||||||
delete pimpl->blob;
|
delete pimpl->blob;
|
||||||
|
@ -222,11 +227,47 @@ const aiExportDataBlob* Exporter :: ExportToBlob( const aiScene* pScene, const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
bool IsVerboseFormat(const aiMesh* mesh)
|
||||||
|
{
|
||||||
|
// avoid slow vector<bool> specialization
|
||||||
|
std::vector<unsigned int> seen(mesh->mNumVertices,0);
|
||||||
|
for(unsigned int i = 0; i < mesh->mNumFaces; ++i) {
|
||||||
|
const aiFace& f = mesh->mFaces[i];
|
||||||
|
for(unsigned int j = 0; j < f.mNumIndices; ++j) {
|
||||||
|
if(++seen[f.mIndices[j]] == 2) {
|
||||||
|
// found a duplicate index
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
bool IsVerboseFormat(const aiScene* pScene)
|
||||||
|
{
|
||||||
|
for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
|
||||||
|
if(!IsVerboseFormat(pScene->mMeshes[i])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing )
|
aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing )
|
||||||
{
|
{
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
|
|
||||||
|
// when they create scenes from scratch, users will likely create them not in verbose
|
||||||
|
// format. They will likely not be aware that there is a flag in the scene to indicate
|
||||||
|
// this, however. To avoid surprises and bug reports, we check for duplicates in
|
||||||
|
// meshes upfront.
|
||||||
|
const bool is_verbose_format = !(pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) || IsVerboseFormat(pScene);
|
||||||
|
|
||||||
pimpl->mError = "";
|
pimpl->mError = "";
|
||||||
for (size_t i = 0; i < pimpl->mExporters.size(); ++i) {
|
for (size_t i = 0; i < pimpl->mExporters.size(); ++i) {
|
||||||
const Exporter::ExportFormatEntry& exp = pimpl->mExporters[i];
|
const Exporter::ExportFormatEntry& exp = pimpl->mExporters[i];
|
||||||
|
@ -248,19 +289,21 @@ aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const
|
||||||
const unsigned int nonIdempotentSteps = aiProcess_FlipWindingOrder | aiProcess_FlipUVs | aiProcess_MakeLeftHanded;
|
const unsigned int nonIdempotentSteps = aiProcess_FlipWindingOrder | aiProcess_FlipUVs | aiProcess_MakeLeftHanded;
|
||||||
|
|
||||||
// Erase all pp steps that were already applied to this scene
|
// Erase all pp steps that were already applied to this scene
|
||||||
unsigned int pp = (exp.mEnforcePP | pPreprocessing) & ~(priv
|
const unsigned int pp = (exp.mEnforcePP | pPreprocessing) & ~(priv && !priv->mIsCopy
|
||||||
? (priv->mPPStepsApplied & ~nonIdempotentSteps)
|
? (priv->mPPStepsApplied & ~nonIdempotentSteps)
|
||||||
: 0u);
|
: 0u);
|
||||||
|
|
||||||
// If no extra postprocessing was specified, and we obtained this scene from an
|
// If no extra postprocessing was specified, and we obtained this scene from an
|
||||||
// Assimp importer, apply the reverse steps automatically.
|
// Assimp importer, apply the reverse steps automatically.
|
||||||
if (!pPreprocessing && priv) {
|
// TODO: either drop this, or document it. Otherwise it is just a bad surprise.
|
||||||
pp |= (nonIdempotentSteps & priv->mPPStepsApplied);
|
//if (!pPreprocessing && priv) {
|
||||||
}
|
// pp |= (nonIdempotentSteps & priv->mPPStepsApplied);
|
||||||
|
//}
|
||||||
|
|
||||||
// If the input scene is not in verbose format, but there is at least postprocessing step that relies on it,
|
// If the input scene is not in verbose format, but there is at least postprocessing step that relies on it,
|
||||||
// we need to run the MakeVerboseFormat step first.
|
// we need to run the MakeVerboseFormat step first.
|
||||||
if (scenecopy->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) {
|
bool must_join_again = false;
|
||||||
|
if (!is_verbose_format) {
|
||||||
|
|
||||||
bool verbosify = false;
|
bool verbosify = false;
|
||||||
for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) {
|
for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) {
|
||||||
|
@ -277,6 +320,10 @@ aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const
|
||||||
|
|
||||||
MakeVerboseFormatProcess proc;
|
MakeVerboseFormatProcess proc;
|
||||||
proc.Execute(scenecopy.get());
|
proc.Execute(scenecopy.get());
|
||||||
|
|
||||||
|
if(!(exp.mEnforcePP & aiProcess_JoinIdenticalVertices)) {
|
||||||
|
must_join_again = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,6 +368,11 @@ aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const
|
||||||
privOut->mPPStepsApplied |= pp;
|
privOut->mPPStepsApplied |= pp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(must_join_again) {
|
||||||
|
JoinVerticesProcess proc;
|
||||||
|
proc.Execute(scenecopy.get());
|
||||||
|
}
|
||||||
|
|
||||||
exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get());
|
exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get());
|
||||||
}
|
}
|
||||||
catch (DeadlyExportError& err) {
|
catch (DeadlyExportError& err) {
|
||||||
|
|
|
@ -232,7 +232,7 @@ void ReadData(const char*& sbegin_out, const char*& send_out, const char* input,
|
||||||
|
|
||||||
// compute length based on type and check against the stored value
|
// compute length based on type and check against the stored value
|
||||||
if(encoding == 0) {
|
if(encoding == 0) {
|
||||||
uint32_t stride;
|
uint32_t stride = 0;
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case 'f':
|
case 'f':
|
||||||
|
@ -248,6 +248,7 @@ void ReadData(const char*& sbegin_out, const char*& send_out, const char* input,
|
||||||
default:
|
default:
|
||||||
ai_assert(false);
|
ai_assert(false);
|
||||||
};
|
};
|
||||||
|
ai_assert(stride > 0);
|
||||||
if(length * stride != comp_len) {
|
if(length * stride != comp_len) {
|
||||||
TokenizeError("cannot ReadData, calculated data stride differs from what the file claims",input, cursor);
|
TokenizeError("cannot ReadData, calculated data stride differs from what the file claims",input, cursor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -547,6 +547,10 @@ private:
|
||||||
default:
|
default:
|
||||||
ai_assert(false);
|
ai_assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ai_assert((order[0] >= 0) && (order[0] <= 2));
|
||||||
|
ai_assert((order[1] >= 0) && (order[1] <= 2));
|
||||||
|
ai_assert((order[2] >= 0) && (order[2] <= 2));
|
||||||
|
|
||||||
if(!is_id[order[0]]) {
|
if(!is_id[order[0]]) {
|
||||||
out = temp[order[0]];
|
out = temp[order[0]];
|
||||||
|
@ -1844,7 +1848,7 @@ private:
|
||||||
}}
|
}}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const AnimationCurveNode* curve_node;
|
const AnimationCurveNode* curve_node = NULL;
|
||||||
BOOST_FOREACH(const AnimationCurveNode* node, curves) {
|
BOOST_FOREACH(const AnimationCurveNode* node, curves) {
|
||||||
ai_assert(node);
|
ai_assert(node);
|
||||||
|
|
||||||
|
|
|
@ -290,14 +290,19 @@ void Document::ReadHeader()
|
||||||
const Scope& shead = *ehead->Compound();
|
const Scope& shead = *ehead->Compound();
|
||||||
fbxVersion = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(shead,"FBXVersion",ehead),0));
|
fbxVersion = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(shead,"FBXVersion",ehead),0));
|
||||||
|
|
||||||
|
// while we maye have some success with newer files, we don't support
|
||||||
if(fbxVersion < 7200 || fbxVersion > 7300) {
|
// the older 6.n fbx format
|
||||||
|
if(fbxVersion < 7100) {
|
||||||
|
DOMError("unsupported, old format version, supported are only FBX 2011, FBX 2012 and FBX 2013");
|
||||||
|
}
|
||||||
|
if(fbxVersion > 7300) {
|
||||||
if(Settings().strictMode) {
|
if(Settings().strictMode) {
|
||||||
DOMError("unsupported format version, supported are only FBX 2012 and FBX 2013"\
|
DOMError("unsupported, newer format version, supported are only FBX 2011, FBX 2012 and FBX 2013"
|
||||||
" in ASCII format (turn off strict mode to try anyhow) ");
|
" (turn off strict mode to try anyhow) ");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DOMWarning("unsupported format version, supported are only FBX 2012 and FBX 2013, trying to read it nevertheless");
|
DOMWarning("unsupported, newer format version, supported are only FBX 2011, FBX 2012 and FBX 2013,"
|
||||||
|
" trying to read it nevertheless");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,8 +50,8 @@ namespace Util {
|
||||||
|
|
||||||
|
|
||||||
/* DOM/Parse error reporting - does not return */
|
/* DOM/Parse error reporting - does not return */
|
||||||
void DOMError(const std::string& message, const Token& token);
|
AI_WONT_RETURN void DOMError(const std::string& message, const Token& token) AI_WONT_RETURN_SUFFIX;
|
||||||
void DOMError(const std::string& message, const Element* element = NULL);
|
AI_WONT_RETURN void DOMError(const std::string& message, const Element* element = NULL) AI_WONT_RETURN_SUFFIX;
|
||||||
|
|
||||||
// does return
|
// does return
|
||||||
void DOMWarning(const std::string& message, const Token& token);
|
void DOMWarning(const std::string& message, const Token& token);
|
||||||
|
|
|
@ -512,7 +512,7 @@ void ReadBinaryDataArray(char type, uint32_t count, const char*& data, const cha
|
||||||
ai_assert(data + comp_len == end);
|
ai_assert(data + comp_len == end);
|
||||||
|
|
||||||
// determine the length of the uncompressed data by looking at the type signature
|
// determine the length of the uncompressed data by looking at the type signature
|
||||||
uint32_t stride;
|
uint32_t stride = 0;
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case 'f':
|
case 'f':
|
||||||
|
|
|
@ -43,7 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "AssimpPCH.h"
|
#include "AssimpPCH.h"
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_IRR_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_IRRMESH_IMPORTER
|
||||||
|
|
||||||
#include "IRRMeshLoader.h"
|
#include "IRRMeshLoader.h"
|
||||||
#include "ParsingUtils.h"
|
#include "ParsingUtils.h"
|
||||||
|
@ -512,4 +512,4 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
|
||||||
AI_DEBUG_INVALIDATE_PTR(reader);
|
AI_DEBUG_INVALIDATE_PTR(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !! ASSIMP_BUILD_NO_IRR_IMPORTER
|
#endif // !! ASSIMP_BUILD_NO_IRRMESH_IMPORTER
|
||||||
|
|
|
@ -45,7 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "AssimpPCH.h"
|
#include "AssimpPCH.h"
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_IRR_IMPORTER
|
//This section should be excluded only if both the Irrlicht AND the Irrlicht Mesh importers were omitted.
|
||||||
|
#if !(defined(ASSIMP_BUILD_NO_IRR_IMPORTER) && defined(ASSIMP_BUILD_NO_IRRMESH_IMPORTER))
|
||||||
|
|
||||||
#include "IRRShared.h"
|
#include "IRRShared.h"
|
||||||
#include "ParsingUtils.h"
|
#include "ParsingUtils.h"
|
||||||
|
@ -497,4 +498,4 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags)
|
||||||
return mat;
|
return mat;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !! ASSIMP_BUILD_NO_IRR_IMPORTER
|
#endif // !(defined(ASSIMP_BUILD_NO_IRR_IMPORTER) && defined(ASSIMP_BUILD_NO_IRRMESH_IMPORTER))
|
||||||
|
|
|
@ -1296,6 +1296,11 @@ void LWOImporter::LoadLWO2File()
|
||||||
uint8_t* const next = mFileBuffer+head->length;
|
uint8_t* const next = mFileBuffer+head->length;
|
||||||
unsigned int iUnnamed = 0;
|
unsigned int iUnnamed = 0;
|
||||||
|
|
||||||
|
if(!head->length) {
|
||||||
|
mFileBuffer = next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
switch (head->type)
|
switch (head->type)
|
||||||
{
|
{
|
||||||
// new layer
|
// new layer
|
||||||
|
|
|
@ -167,19 +167,21 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
|
||||||
// The older LWOB format does not use indirect references to clips.
|
// The older LWOB format does not use indirect references to clips.
|
||||||
// The file name of a texture is directly specified in the tex chunk.
|
// The file name of a texture is directly specified in the tex chunk.
|
||||||
if (mIsLWO2) {
|
if (mIsLWO2) {
|
||||||
// find the corresponding clip
|
// find the corresponding clip (take the last one if multiple
|
||||||
ClipList::iterator clip = mClips.begin();
|
// share the same index)
|
||||||
|
ClipList::iterator end = mClips.end(), candidate = end;
|
||||||
temp = (*it).mClipIdx;
|
temp = (*it).mClipIdx;
|
||||||
for (ClipList::iterator end = mClips.end(); clip != end; ++clip) {
|
for (ClipList::iterator clip = mClips.begin(); clip != end; ++clip) {
|
||||||
if ((*clip).idx == temp)
|
if ((*clip).idx == temp) {
|
||||||
break;
|
candidate = clip;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (mClips.end() == clip) {
|
if (candidate == end) {
|
||||||
DefaultLogger::get()->error("LWO2: Clip index is out of bounds");
|
DefaultLogger::get()->error("LWO2: Clip index is out of bounds");
|
||||||
temp = 0;
|
temp = 0;
|
||||||
|
|
||||||
// fixme: appearently some LWO files shipping with Doom3 don't
|
// fixme: apparently some LWO files shipping with Doom3 don't
|
||||||
// have clips at all ... check whether that's true or whether
|
// have clips at all ... check whether that's true or whether
|
||||||
// it's a bug in the loader.
|
// it's a bug in the loader.
|
||||||
|
|
||||||
|
@ -188,16 +190,16 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
|
||||||
//continue;
|
//continue;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (Clip::UNSUPPORTED == (*clip).type) {
|
if (Clip::UNSUPPORTED == (*candidate).type) {
|
||||||
DefaultLogger::get()->error("LWO2: Clip type is not supported");
|
DefaultLogger::get()->error("LWO2: Clip type is not supported");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
AdjustTexturePath((*clip).path);
|
AdjustTexturePath((*candidate).path);
|
||||||
s.Set((*clip).path);
|
s.Set((*candidate).path);
|
||||||
|
|
||||||
// Additional image settings
|
// Additional image settings
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
if ((*clip).negate) {
|
if ((*candidate).negate) {
|
||||||
flags |= aiTextureFlags_Invert;
|
flags |= aiTextureFlags_Invert;
|
||||||
}
|
}
|
||||||
pcMat->AddProperty(&flags,1,AI_MATKEY_TEXFLAGS(type,cur));
|
pcMat->AddProperty(&flags,1,AI_MATKEY_TEXFLAGS(type,cur));
|
||||||
|
|
|
@ -563,7 +563,7 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... add dummy nodes under a single root, each holding a reference to one
|
// ... add dummy nodes under a single root, each holding a reference to one
|
||||||
// mesh. If we didn't do this, we'd loose the group name.
|
// mesh. If we didn't do this, we'd lose the group name.
|
||||||
aiNode* rt = pScene->mRootNode = new aiNode("<MS3DRoot>");
|
aiNode* rt = pScene->mRootNode = new aiNode("<MS3DRoot>");
|
||||||
|
|
||||||
#ifdef ASSIMP_BUILD_MS3D_ONE_NODE_PER_MESH
|
#ifdef ASSIMP_BUILD_MS3D_ONE_NODE_PER_MESH
|
||||||
|
|
|
@ -102,7 +102,7 @@ aiReturn aiGetMaterialFloatArray(const aiMaterial* pMat,
|
||||||
}
|
}
|
||||||
|
|
||||||
// data is given in floats, simply copy it
|
// data is given in floats, simply copy it
|
||||||
unsigned int iWrite;
|
unsigned int iWrite = 0;
|
||||||
if( aiPTI_Float == prop->mType || aiPTI_Buffer == prop->mType) {
|
if( aiPTI_Float == prop->mType || aiPTI_Buffer == prop->mType) {
|
||||||
iWrite = prop->mDataLength / sizeof(float);
|
iWrite = prop->mDataLength / sizeof(float);
|
||||||
if (pMax) {
|
if (pMax) {
|
||||||
|
@ -175,7 +175,7 @@ aiReturn aiGetMaterialIntegerArray(const aiMaterial* pMat,
|
||||||
}
|
}
|
||||||
|
|
||||||
// data is given in ints, simply copy it
|
// data is given in ints, simply copy it
|
||||||
unsigned int iWrite;
|
unsigned int iWrite = 0;
|
||||||
if( aiPTI_Integer == prop->mType || aiPTI_Buffer == prop->mType) {
|
if( aiPTI_Integer == prop->mType || aiPTI_Buffer == prop->mType) {
|
||||||
iWrite = prop->mDataLength / sizeof(int32_t);
|
iWrite = prop->mDataLength / sizeof(int32_t);
|
||||||
if (pMax) {
|
if (pMax) {
|
||||||
|
|
|
@ -61,14 +61,14 @@ void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
|
||||||
boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
|
boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
|
||||||
if(outfile == NULL) {
|
if(outfile == NULL) {
|
||||||
throw DeadlyExportError("could not open output .obj file: " + std::string(pFile));
|
throw DeadlyExportError("could not open output .obj file: " + std::string(pFile));
|
||||||
}
|
}
|
||||||
outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
|
outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(exporter.GetMaterialLibFileName(),"wt"));
|
boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(exporter.GetMaterialLibFileName(),"wt"));
|
||||||
if(outfile == NULL) {
|
if(outfile == NULL) {
|
||||||
throw DeadlyExportError("could not open output .mtl file: " + std::string(exporter.GetMaterialLibFileName()));
|
throw DeadlyExportError("could not open output .mtl file: " + std::string(exporter.GetMaterialLibFileName()));
|
||||||
}
|
}
|
||||||
outfile->Write( exporter.mOutputMat.str().c_str(), static_cast<size_t>(exporter.mOutputMat.tellp()),1);
|
outfile->Write( exporter.mOutputMat.str().c_str(), static_cast<size_t>(exporter.mOutputMat.tellp()),1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,6 +199,7 @@ void ObjExporter :: WriteGeometryFile()
|
||||||
AddNode(pScene->mRootNode,mBase);
|
AddNode(pScene->mRootNode,mBase);
|
||||||
|
|
||||||
// write vertex positions
|
// write vertex positions
|
||||||
|
vpMap.getVectors(vp);
|
||||||
mOutput << "# " << vp.size() << " vertex positions" << endl;
|
mOutput << "# " << vp.size() << " vertex positions" << endl;
|
||||||
BOOST_FOREACH(const aiVector3D& v, vp) {
|
BOOST_FOREACH(const aiVector3D& v, vp) {
|
||||||
mOutput << "v " << v.x << " " << v.y << " " << v.z << endl;
|
mOutput << "v " << v.x << " " << v.y << " " << v.z << endl;
|
||||||
|
@ -206,6 +207,7 @@ void ObjExporter :: WriteGeometryFile()
|
||||||
mOutput << endl;
|
mOutput << endl;
|
||||||
|
|
||||||
// write uv coordinates
|
// write uv coordinates
|
||||||
|
vtMap.getVectors(vt);
|
||||||
mOutput << "# " << vt.size() << " UV coordinates" << endl;
|
mOutput << "# " << vt.size() << " UV coordinates" << endl;
|
||||||
BOOST_FOREACH(const aiVector3D& v, vt) {
|
BOOST_FOREACH(const aiVector3D& v, vt) {
|
||||||
mOutput << "vt " << v.x << " " << v.y << " " << v.z << endl;
|
mOutput << "vt " << v.x << " " << v.y << " " << v.z << endl;
|
||||||
|
@ -213,6 +215,7 @@ void ObjExporter :: WriteGeometryFile()
|
||||||
mOutput << endl;
|
mOutput << endl;
|
||||||
|
|
||||||
// write vertex normals
|
// write vertex normals
|
||||||
|
vnMap.getVectors(vn);
|
||||||
mOutput << "# " << vn.size() << " vertex normals" << endl;
|
mOutput << "# " << vn.size() << " vertex normals" << endl;
|
||||||
BOOST_FOREACH(const aiVector3D& v, vn) {
|
BOOST_FOREACH(const aiVector3D& v, vn) {
|
||||||
mOutput << "vn " << v.x << " " << v.y << " " << v.z << endl;
|
mOutput << "vn " << v.x << " " << v.y << " " << v.z << endl;
|
||||||
|
@ -252,6 +255,31 @@ void ObjExporter :: WriteGeometryFile()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int ObjExporter::vecIndexMap::getIndex(const aiVector3D& vec)
|
||||||
|
{
|
||||||
|
vecIndexMap::dataType::iterator vertIt = vecMap.find(vec);
|
||||||
|
if(vertIt != vecMap.end()){// vertex already exists, so reference it
|
||||||
|
return vertIt->second;
|
||||||
|
}
|
||||||
|
vecMap[vec] = mNextIndex;
|
||||||
|
int ret = mNextIndex;
|
||||||
|
mNextIndex++;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjExporter::vecIndexMap::getVectors( std::vector<aiVector3D>& vecs )
|
||||||
|
{
|
||||||
|
vecs.resize(vecMap.size());
|
||||||
|
for(vecIndexMap::dataType::iterator it = vecMap.begin(); it != vecMap.end(); it++){
|
||||||
|
vecs[it->second-1] = it->first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ObjExporter :: AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat)
|
void ObjExporter :: AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat)
|
||||||
{
|
{
|
||||||
|
@ -262,6 +290,7 @@ void ObjExporter :: AddMesh(const aiString& name, const aiMesh* m, const aiMatri
|
||||||
mesh.matname = GetMaterialName(m->mMaterialIndex);
|
mesh.matname = GetMaterialName(m->mMaterialIndex);
|
||||||
|
|
||||||
mesh.faces.resize(m->mNumFaces);
|
mesh.faces.resize(m->mNumFaces);
|
||||||
|
|
||||||
for(unsigned int i = 0; i < m->mNumFaces; ++i) {
|
for(unsigned int i = 0; i < m->mNumFaces; ++i) {
|
||||||
const aiFace& f = m->mFaces[i];
|
const aiFace& f = m->mFaces[i];
|
||||||
|
|
||||||
|
@ -281,21 +310,22 @@ void ObjExporter :: AddMesh(const aiString& name, const aiMesh* m, const aiMatri
|
||||||
for(unsigned int a = 0; a < f.mNumIndices; ++a) {
|
for(unsigned int a = 0; a < f.mNumIndices; ++a) {
|
||||||
const unsigned int idx = f.mIndices[a];
|
const unsigned int idx = f.mIndices[a];
|
||||||
|
|
||||||
// XXX need a way to check if this is an unique vertex or if we had it already,
|
aiVector3D vert = mat * m->mVertices[idx];
|
||||||
// in which case we should instead reference the previous occurrence.
|
face.indices[a].vp = vpMap.getIndex(vert);
|
||||||
ai_assert(m->mVertices);
|
|
||||||
vp.push_back( mat * m->mVertices[idx] );
|
|
||||||
face.indices[a].vp = vp.size();
|
|
||||||
|
|
||||||
if (m->mNormals) {
|
if (m->mNormals) {
|
||||||
vn.push_back( m->mNormals[idx] );
|
face.indices[a].vn = vnMap.getIndex(m->mNormals[idx]);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
face.indices[a].vn = 0;
|
||||||
}
|
}
|
||||||
face.indices[a].vn = vn.size();
|
|
||||||
|
|
||||||
if (m->mTextureCoords[0]) {
|
if (m->mTextureCoords[0]) {
|
||||||
vt.push_back( m->mTextureCoords[0][idx] );
|
face.indices[a].vt = vtMap.getIndex(m->mTextureCoords[0][idx]);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
face.indices[a].vt = 0;
|
||||||
}
|
}
|
||||||
face.indices[a].vt = vt.size();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,6 +112,36 @@ private:
|
||||||
const aiScene* const pScene;
|
const aiScene* const pScene;
|
||||||
|
|
||||||
std::vector<aiVector3D> vp, vn, vt;
|
std::vector<aiVector3D> vp, vn, vt;
|
||||||
|
|
||||||
|
|
||||||
|
struct aiVectorCompare
|
||||||
|
{
|
||||||
|
bool operator() (const aiVector3D& a, const aiVector3D& b) const
|
||||||
|
{
|
||||||
|
if(a.x < b.x) return true;
|
||||||
|
if(a.x > b.x) return false;
|
||||||
|
if(a.y < b.y) return true;
|
||||||
|
if(a.y > b.y) return false;
|
||||||
|
if(a.z < b.z) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class vecIndexMap
|
||||||
|
{
|
||||||
|
int mNextIndex;
|
||||||
|
typedef std::map<aiVector3D, int, aiVectorCompare> dataType;
|
||||||
|
dataType vecMap;
|
||||||
|
public:
|
||||||
|
|
||||||
|
vecIndexMap():mNextIndex(1)
|
||||||
|
{}
|
||||||
|
|
||||||
|
int getIndex(const aiVector3D& vec);
|
||||||
|
void getVectors( std::vector<aiVector3D>& vecs );
|
||||||
|
};
|
||||||
|
|
||||||
|
vecIndexMap vpMap, vnMap, vtMap;
|
||||||
std::vector<MeshInstance> meshes;
|
std::vector<MeshInstance> meshes;
|
||||||
|
|
||||||
// this endl() doesn't flush() the stream
|
// this endl() doesn't flush() the stream
|
||||||
|
|
|
@ -277,7 +277,7 @@ struct Model
|
||||||
//! Material map
|
//! Material map
|
||||||
std::map<std::string, Material*> m_MaterialMap;
|
std::map<std::string, Material*> m_MaterialMap;
|
||||||
|
|
||||||
//! \brief Default constructor
|
//! \brief The default class constructor
|
||||||
Model() :
|
Model() :
|
||||||
m_ModelName(""),
|
m_ModelName(""),
|
||||||
m_pCurrent(NULL),
|
m_pCurrent(NULL),
|
||||||
|
@ -290,7 +290,7 @@ struct Model
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \brief Destructor
|
//! \brief The class destructor
|
||||||
~Model()
|
~Model()
|
||||||
{
|
{
|
||||||
// Clear all stored object instances
|
// Clear all stored object instances
|
||||||
|
|
|
@ -123,8 +123,9 @@ void ObjFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
|
||||||
|
|
||||||
// Get the file-size and validate it, throwing an exception when fails
|
// Get the file-size and validate it, throwing an exception when fails
|
||||||
size_t fileSize = file->FileSize();
|
size_t fileSize = file->FileSize();
|
||||||
if( fileSize < 16)
|
if( fileSize < 16) {
|
||||||
throw DeadlyImportError( "OBJ-file is too small.");
|
throw DeadlyImportError( "OBJ-file is too small.");
|
||||||
|
}
|
||||||
|
|
||||||
// Allocate buffer and read file into it
|
// Allocate buffer and read file into it
|
||||||
TextFileToBuffer(file.get(),m_Buffer);
|
TextFileToBuffer(file.get(),m_Buffer);
|
||||||
|
@ -167,15 +168,15 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// This is an error, so break down the application
|
// This is a fatal error, so break down the application
|
||||||
ai_assert(false);
|
ai_assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create nodes for the whole scene
|
// Create nodes for the whole scene
|
||||||
std::vector<aiMesh*> MeshArray;
|
std::vector<aiMesh*> MeshArray;
|
||||||
for (size_t index = 0; index < pModel->m_Objects.size(); index++)
|
for (size_t index = 0; index < pModel->m_Objects.size(); index++)
|
||||||
{
|
{
|
||||||
createNodes(pModel, pModel->m_Objects[ index ], index, pScene->mRootNode, pScene, MeshArray);
|
createNodes(pModel, pModel->m_Objects[ index ], pScene->mRootNode, pScene, MeshArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create mesh pointer buffer for this scene
|
// Create mesh pointer buffer for this scene
|
||||||
|
@ -195,7 +196,6 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Creates all nodes of the model
|
// Creates all nodes of the model
|
||||||
aiNode *ObjFileImporter::createNodes(const ObjFile::Model* pModel, const ObjFile::Object* pObject,
|
aiNode *ObjFileImporter::createNodes(const ObjFile::Model* pModel, const ObjFile::Object* pObject,
|
||||||
unsigned int /*uiMeshIndex*/,
|
|
||||||
aiNode *pParent, aiScene* pScene,
|
aiNode *pParent, aiScene* pScene,
|
||||||
std::vector<aiMesh*> &MeshArray )
|
std::vector<aiMesh*> &MeshArray )
|
||||||
{
|
{
|
||||||
|
@ -276,14 +276,23 @@ void ObjFileImporter::createTopology(const ObjFile::Model* pModel,
|
||||||
for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++)
|
for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++)
|
||||||
{
|
{
|
||||||
ObjFile::Face* const inp = pObjMesh->m_Faces[ index ];
|
ObjFile::Face* const inp = pObjMesh->m_Faces[ index ];
|
||||||
|
|
||||||
if (inp->m_PrimitiveType == aiPrimitiveType_LINE) {
|
if (inp->m_PrimitiveType == aiPrimitiveType_LINE) {
|
||||||
pMesh->mNumFaces += inp->m_pVertices->size() - 1;
|
pMesh->mNumFaces += inp->m_pVertices->size() - 1;
|
||||||
|
pMesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
|
||||||
}
|
}
|
||||||
else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) {
|
else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) {
|
||||||
pMesh->mNumFaces += inp->m_pVertices->size();
|
pMesh->mNumFaces += inp->m_pVertices->size();
|
||||||
|
pMesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
++pMesh->mNumFaces;
|
++pMesh->mNumFaces;
|
||||||
|
if (inp->m_pVertices->size() > 3) {
|
||||||
|
pMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,7 +393,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
|
||||||
pMesh->mVertices[ newIndex ] = pModel->m_Vertices[ vertex ];
|
pMesh->mVertices[ newIndex ] = pModel->m_Vertices[ vertex ];
|
||||||
|
|
||||||
// Copy all normals
|
// Copy all normals
|
||||||
if ( !pSourceFace->m_pNormals->empty() && !pModel->m_Normals.empty())
|
if ( !pModel->m_Normals.empty() && vertexIndex < pSourceFace->m_pNormals->size())
|
||||||
{
|
{
|
||||||
const unsigned int normal = pSourceFace->m_pNormals->at( vertexIndex );
|
const unsigned int normal = pSourceFace->m_pNormals->at( vertexIndex );
|
||||||
if ( normal >= pModel->m_Normals.size() )
|
if ( normal >= pModel->m_Normals.size() )
|
||||||
|
@ -394,21 +403,16 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy all texture coordinates
|
// Copy all texture coordinates
|
||||||
if ( !pModel->m_TextureCoord.empty() )
|
if ( !pModel->m_TextureCoord.empty() && vertexIndex < pSourceFace->m_pTexturCoords->size())
|
||||||
{
|
{
|
||||||
if ( !pSourceFace->m_pTexturCoords->empty() )
|
const unsigned int tex = pSourceFace->m_pTexturCoords->at( vertexIndex );
|
||||||
{
|
ai_assert( tex < pModel->m_TextureCoord.size() );
|
||||||
const unsigned int tex = pSourceFace->m_pTexturCoords->at( vertexIndex );
|
|
||||||
ai_assert( tex < pModel->m_TextureCoord.size() );
|
if ( tex >= pModel->m_TextureCoord.size() )
|
||||||
for ( size_t i=0; i < pMesh->GetNumUVChannels(); i++ )
|
throw DeadlyImportError("OBJ: texture coord index out of range");
|
||||||
{
|
|
||||||
if ( tex >= pModel->m_TextureCoord.size() )
|
|
||||||
throw DeadlyImportError("OBJ: texture coord index out of range");
|
|
||||||
|
|
||||||
aiVector2D coord2d = pModel->m_TextureCoord[ tex ];
|
aiVector2D coord2d = pModel->m_TextureCoord[ tex ];
|
||||||
pMesh->mTextureCoords[ i ][ newIndex ] = aiVector3D( coord2d.x, coord2d.y, 0.0 );
|
pMesh->mTextureCoords[ 0 ][ newIndex ] = aiVector3D( coord2d.x, coord2d.y, 0.0 );
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ai_assert( pMesh->mNumVertices > newIndex );
|
ai_assert( pMesh->mNumVertices > newIndex );
|
||||||
|
@ -587,15 +591,12 @@ void ObjFileImporter::appendChildToParentNode(aiNode *pParent, aiNode *pChild)
|
||||||
|
|
||||||
// Assign parent to child
|
// Assign parent to child
|
||||||
pChild->mParent = pParent;
|
pChild->mParent = pParent;
|
||||||
size_t sNumChildren = 0;
|
|
||||||
(void)sNumChildren; // remove warning on release build
|
|
||||||
|
|
||||||
// If already children was assigned to the parent node, store them in a
|
// If already children was assigned to the parent node, store them in a
|
||||||
std::vector<aiNode*> temp;
|
std::vector<aiNode*> temp;
|
||||||
if (pParent->mChildren != NULL)
|
if (pParent->mChildren != NULL)
|
||||||
{
|
{
|
||||||
sNumChildren = pParent->mNumChildren;
|
ai_assert( 0 != pParent->mNumChildren );
|
||||||
ai_assert( 0 != sNumChildren );
|
|
||||||
for (size_t index = 0; index < pParent->mNumChildren; index++)
|
for (size_t index = 0; index < pParent->mNumChildren; index++)
|
||||||
{
|
{
|
||||||
temp.push_back(pParent->mChildren [ index ] );
|
temp.push_back(pParent->mChildren [ index ] );
|
||||||
|
|
|
@ -77,7 +77,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
//! \brief Appends the supported extention.
|
//! \brief Appends the supported extension.
|
||||||
const aiImporterDesc* GetInfo () const;
|
const aiImporterDesc* GetInfo () const;
|
||||||
|
|
||||||
//! \brief File import implementation.
|
//! \brief File import implementation.
|
||||||
|
@ -87,7 +87,7 @@ private:
|
||||||
void CreateDataFromImport(const ObjFile::Model* pModel, aiScene* pScene);
|
void CreateDataFromImport(const ObjFile::Model* pModel, aiScene* pScene);
|
||||||
|
|
||||||
//! \brief Creates all nodes stored in imported content.
|
//! \brief Creates all nodes stored in imported content.
|
||||||
aiNode *createNodes(const ObjFile::Model* pModel, const ObjFile::Object* pData, unsigned int uiMeshIndex,
|
aiNode *createNodes(const ObjFile::Model* pModel, const ObjFile::Object* pData,
|
||||||
aiNode *pParent, aiScene* pScene, std::vector<aiMesh*> &MeshArray);
|
aiNode *pParent, aiScene* pScene, std::vector<aiMesh*> &MeshArray);
|
||||||
|
|
||||||
//! \brief Creates topology data like faces and meshes for the geometry.
|
//! \brief Creates topology data like faces and meshes for the geometry.
|
||||||
|
@ -104,18 +104,15 @@ private:
|
||||||
//! \brief Material creation.
|
//! \brief Material creation.
|
||||||
void createMaterials(const ObjFile::Model* pModel, aiScene* pScene);
|
void createMaterials(const ObjFile::Model* pModel, aiScene* pScene);
|
||||||
|
|
||||||
//! \brief Appends a child node to a parentnode and updates the datastructures.
|
//! \brief Appends a child node to a parent node and updates the data structures.
|
||||||
void appendChildToParentNode(aiNode *pParent, aiNode *pChild);
|
void appendChildToParentNode(aiNode *pParent, aiNode *pChild);
|
||||||
|
|
||||||
//! \brief TODO!
|
|
||||||
void createAnimations();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//! Data buffer
|
//! Data buffer
|
||||||
std::vector<char> m_Buffer;
|
std::vector<char> m_Buffer;
|
||||||
//! Pointer to root object instance
|
//! Pointer to root object instance
|
||||||
ObjFile::Object *m_pRootObject;
|
ObjFile::Object *m_pRootObject;
|
||||||
//! Absolute pathname of model in filesystem
|
//! Absolute pathname of model in file system
|
||||||
std::string m_strAbsPath;
|
std::string m_strAbsPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -50,10 +50,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "../include/assimp/types.h"
|
#include "../include/assimp/types.h"
|
||||||
#include "DefaultIOSystem.h"
|
#include "DefaultIOSystem.h"
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp {
|
||||||
{
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
const std::string ObjFileParser::DEFAULT_MATERIAL = AI_DEFAULT_MATERIAL_NAME;
|
const std::string ObjFileParser::DEFAULT_MATERIAL = AI_DEFAULT_MATERIAL_NAME;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
@ -71,9 +69,10 @@ ObjFileParser::ObjFileParser(std::vector<char> &Data,const std::string &strModel
|
||||||
m_pModel = new ObjFile::Model();
|
m_pModel = new ObjFile::Model();
|
||||||
m_pModel->m_ModelName = strModelName;
|
m_pModel->m_ModelName = strModelName;
|
||||||
|
|
||||||
|
// create default material and store it
|
||||||
m_pModel->m_pDefaultMaterial = new ObjFile::Material();
|
m_pModel->m_pDefaultMaterial = new ObjFile::Material();
|
||||||
m_pModel->m_pDefaultMaterial->MaterialName.Set( DEFAULT_MATERIAL );
|
m_pModel->m_pDefaultMaterial->MaterialName.Set( DEFAULT_MATERIAL );
|
||||||
m_pModel->m_MaterialLib.push_back( DEFAULT_MATERIAL );
|
m_pModel->m_MaterialLib.push_back( DEFAULT_MATERIAL );
|
||||||
m_pModel->m_MaterialMap[ DEFAULT_MATERIAL ] = m_pModel->m_pDefaultMaterial;
|
m_pModel->m_MaterialMap[ DEFAULT_MATERIAL ] = m_pModel->m_pDefaultMaterial;
|
||||||
|
|
||||||
// Start parsing the file
|
// Start parsing the file
|
||||||
|
@ -84,9 +83,6 @@ ObjFileParser::ObjFileParser(std::vector<char> &Data,const std::string &strModel
|
||||||
// Destructor
|
// Destructor
|
||||||
ObjFileParser::~ObjFileParser()
|
ObjFileParser::~ObjFileParser()
|
||||||
{
|
{
|
||||||
/*delete m_pModel->m_pDefaultMaterial;
|
|
||||||
m_pModel->m_pDefaultMaterial = NULL;*/
|
|
||||||
|
|
||||||
delete m_pModel;
|
delete m_pModel;
|
||||||
m_pModel = NULL;
|
m_pModel = NULL;
|
||||||
}
|
}
|
||||||
|
@ -112,7 +108,7 @@ void ObjFileParser::parseFile()
|
||||||
case 'v': // Parse a vertex texture coordinate
|
case 'v': // Parse a vertex texture coordinate
|
||||||
{
|
{
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
if (*m_DataIt == ' ')
|
if (*m_DataIt == ' ' || *m_DataIt == '\t')
|
||||||
{
|
{
|
||||||
// Read in vertex definition
|
// Read in vertex definition
|
||||||
getVector3(m_pModel->m_Vertices);
|
getVector3(m_pModel->m_Vertices);
|
||||||
|
@ -200,6 +196,8 @@ void ObjFileParser::copyNextWord(char *pBuffer, size_t length)
|
||||||
break;
|
break;
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ai_assert(index < length);
|
||||||
pBuffer[index] = '\0';
|
pBuffer[index] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,16 +205,30 @@ void ObjFileParser::copyNextWord(char *pBuffer, size_t length)
|
||||||
// Copy the next line into a temporary buffer
|
// Copy the next line into a temporary buffer
|
||||||
void ObjFileParser::copyNextLine(char *pBuffer, size_t length)
|
void ObjFileParser::copyNextLine(char *pBuffer, size_t length)
|
||||||
{
|
{
|
||||||
size_t index = 0;
|
size_t index = 0u;
|
||||||
while (m_DataIt != m_DataItEnd)
|
|
||||||
{
|
|
||||||
if (*m_DataIt == '\n' || *m_DataIt == '\r' || index == length-1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
pBuffer[ index ] = *m_DataIt;
|
// some OBJ files have line continuations using \ (such as in C++ et al)
|
||||||
++index;
|
bool continuation = false;
|
||||||
++m_DataIt;
|
for (;m_DataIt != m_DataItEnd && index < length-1; ++m_DataIt)
|
||||||
|
{
|
||||||
|
const char c = *m_DataIt;
|
||||||
|
if (c == '\\') {
|
||||||
|
continuation = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == '\n' || c == '\r') {
|
||||||
|
if(continuation) {
|
||||||
|
pBuffer[ index++ ] = ' ';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
continuation = false;
|
||||||
|
pBuffer[ index++ ] = c;
|
||||||
}
|
}
|
||||||
|
ai_assert(index < length);
|
||||||
pBuffer[ index ] = '\0';
|
pBuffer[ index ] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,6 +286,10 @@ void ObjFileParser::getFace(aiPrimitiveType type)
|
||||||
std::vector<unsigned int> *pNormalID = new std::vector<unsigned int>;
|
std::vector<unsigned int> *pNormalID = new std::vector<unsigned int>;
|
||||||
bool hasNormal = false;
|
bool hasNormal = false;
|
||||||
|
|
||||||
|
const int vSize = m_pModel->m_Vertices.size();
|
||||||
|
const int vtSize = m_pModel->m_TextureCoord.size();
|
||||||
|
const int vnSize = m_pModel->m_Normals.size();
|
||||||
|
|
||||||
const bool vt = (!m_pModel->m_TextureCoord.empty());
|
const bool vt = (!m_pModel->m_TextureCoord.empty());
|
||||||
const bool vn = (!m_pModel->m_Normals.empty());
|
const bool vn = (!m_pModel->m_Normals.empty());
|
||||||
int iStep = 0, iPos = 0;
|
int iStep = 0, iPos = 0;
|
||||||
|
@ -307,7 +323,11 @@ void ObjFileParser::getFace(aiPrimitiveType type)
|
||||||
{
|
{
|
||||||
//OBJ USES 1 Base ARRAYS!!!!
|
//OBJ USES 1 Base ARRAYS!!!!
|
||||||
const int iVal = atoi( pPtr );
|
const int iVal = atoi( pPtr );
|
||||||
|
|
||||||
|
// increment iStep position based off of the sign and # of digits
|
||||||
int tmp = iVal;
|
int tmp = iVal;
|
||||||
|
if (iVal < 0)
|
||||||
|
++iStep;
|
||||||
while ( ( tmp = tmp / 10 )!=0 )
|
while ( ( tmp = tmp / 10 )!=0 )
|
||||||
++iStep;
|
++iStep;
|
||||||
|
|
||||||
|
@ -332,6 +352,27 @@ void ObjFileParser::getFace(aiPrimitiveType type)
|
||||||
reportErrorTokenInFace();
|
reportErrorTokenInFace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ( iVal < 0 )
|
||||||
|
{
|
||||||
|
// Store relatively index
|
||||||
|
if ( 0 == iPos )
|
||||||
|
{
|
||||||
|
pIndices->push_back( vSize + iVal );
|
||||||
|
}
|
||||||
|
else if ( 1 == iPos )
|
||||||
|
{
|
||||||
|
pTexID->push_back( vtSize + iVal );
|
||||||
|
}
|
||||||
|
else if ( 2 == iPos )
|
||||||
|
{
|
||||||
|
pNormalID->push_back( vnSize + iVal );
|
||||||
|
hasNormal = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
reportErrorTokenInFace();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pPtr += iStep;
|
pPtr += iStep;
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,7 +103,7 @@ PlyExporter :: PlyExporter(const char* _filename, const aiScene* pScene)
|
||||||
|
|
||||||
mOutput << "ply" << endl;
|
mOutput << "ply" << endl;
|
||||||
mOutput << "format ascii 1.0" << endl;
|
mOutput << "format ascii 1.0" << endl;
|
||||||
mOutput << "Created by Open Asset Import Library - http://assimp.sf.net (v"
|
mOutput << "comment Created by Open Asset Import Library - http://assimp.sf.net (v"
|
||||||
<< aiGetVersionMajor() << '.' << aiGetVersionMinor() << '.'
|
<< aiGetVersionMajor() << '.' << aiGetVersionMinor() << '.'
|
||||||
<< aiGetVersionRevision() << ")" << endl;
|
<< aiGetVersionRevision() << ")" << endl;
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@ PlyExporter :: PlyExporter(const char* _filename, const aiScene* pScene)
|
||||||
}
|
}
|
||||||
|
|
||||||
mOutput << "element face " << faces << endl;
|
mOutput << "element face " << faces << endl;
|
||||||
mOutput << "property list uint uint vertex_indices" << endl;
|
mOutput << "property list uint uint vertex_index" << endl;
|
||||||
mOutput << "end_header" << endl;
|
mOutput << "end_header" << endl;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
|
for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
|
||||||
|
|
|
@ -47,6 +47,7 @@ corresponding preprocessor flag to selectively disable steps.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AssimpPCH.h"
|
#include "AssimpPCH.h"
|
||||||
|
#include "ProcessHelper.h"
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_CALCTANGENTS_PROCESS
|
#ifndef ASSIMP_BUILD_NO_CALCTANGENTS_PROCESS
|
||||||
# include "CalcTangentsProcess.h"
|
# include "CalcTangentsProcess.h"
|
||||||
|
@ -215,7 +216,7 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out)
|
||||||
#if (!defined ASSIMP_BUILD_NO_FLIPWINDINGORDER_PROCESS)
|
#if (!defined ASSIMP_BUILD_NO_FLIPWINDINGORDER_PROCESS)
|
||||||
out.push_back( new FlipWindingOrderProcess());
|
out.push_back( new FlipWindingOrderProcess());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_DEBONE_PROCESS)
|
#if (!defined ASSIMP_BUILD_NO_DEBONE_PROCESS)
|
||||||
out.push_back( new DeboneProcess());
|
out.push_back( new DeboneProcess());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_LIMITBONEWEIGHTS_PROCESS)
|
#if (!defined ASSIMP_BUILD_NO_LIMITBONEWEIGHTS_PROCESS)
|
||||||
|
|
|
@ -63,12 +63,25 @@ void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
|
||||||
|
|
||||||
outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
|
outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
|
||||||
}
|
}
|
||||||
|
void ExportSceneSTLBinary(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene)
|
||||||
|
{
|
||||||
|
// invoke the exporter
|
||||||
|
STLExporter exporter(pFile, pScene, true);
|
||||||
|
|
||||||
|
// we're still here - export successfully completed. Write the file.
|
||||||
|
boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
|
||||||
|
if(outfile == NULL) {
|
||||||
|
throw DeadlyExportError("could not open output .stl file: " + std::string(pFile));
|
||||||
|
}
|
||||||
|
|
||||||
|
outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
|
||||||
|
}
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
STLExporter :: STLExporter(const char* _filename, const aiScene* pScene)
|
STLExporter :: STLExporter(const char* _filename, const aiScene* pScene, bool binary)
|
||||||
: filename(_filename)
|
: filename(_filename)
|
||||||
, pScene(pScene)
|
, pScene(pScene)
|
||||||
, endl("\n")
|
, endl("\n")
|
||||||
|
@ -76,14 +89,31 @@ STLExporter :: STLExporter(const char* _filename, const aiScene* pScene)
|
||||||
// make sure that all formatting happens using the standard, C locale and not the user's current locale
|
// make sure that all formatting happens using the standard, C locale and not the user's current locale
|
||||||
const std::locale& l = std::locale("C");
|
const std::locale& l = std::locale("C");
|
||||||
mOutput.imbue(l);
|
mOutput.imbue(l);
|
||||||
|
if (binary) {
|
||||||
const std::string& name = "AssimpScene";
|
char buf[80] = {0} ;
|
||||||
|
buf[0] = 'A'; buf[1] = 's'; buf[2] = 's'; buf[3] = 'i'; buf[4] = 'm'; buf[5] = 'p';
|
||||||
|
buf[6] = 'S'; buf[7] = 'c'; buf[8] = 'e'; buf[9] = 'n'; buf[10] = 'e';
|
||||||
|
mOutput.write(buf, 80);
|
||||||
|
unsigned int meshnum = 0;
|
||||||
|
for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
|
||||||
|
for (unsigned int j = 0; j < pScene->mMeshes[i]->mNumFaces; ++j) {
|
||||||
|
meshnum++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AI_SWAP4(meshnum);
|
||||||
|
mOutput.write((char *)&meshnum, 4);
|
||||||
|
for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
|
||||||
|
WriteMeshBinary(pScene->mMeshes[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const std::string& name = "AssimpScene";
|
||||||
|
|
||||||
mOutput << "solid " << name << endl;
|
mOutput << "solid " << name << endl;
|
||||||
for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
|
for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
|
||||||
WriteMesh(pScene->mMeshes[i]);
|
WriteMesh(pScene->mMeshes[i]);
|
||||||
|
}
|
||||||
|
mOutput << "endsolid " << name << endl;
|
||||||
}
|
}
|
||||||
mOutput << "endsolid " << name << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -113,4 +143,31 @@ void STLExporter :: WriteMesh(const aiMesh* m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void STLExporter :: WriteMeshBinary(const aiMesh* m)
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < m->mNumFaces; ++i) {
|
||||||
|
const aiFace& f = m->mFaces[i];
|
||||||
|
// we need per-face normals. We specified aiProcess_GenNormals as pre-requisite for this exporter,
|
||||||
|
// but nonetheless we have to expect per-vertex normals.
|
||||||
|
aiVector3D nor;
|
||||||
|
if (m->mNormals) {
|
||||||
|
for(unsigned int a = 0; a < f.mNumIndices; ++a) {
|
||||||
|
nor += m->mNormals[f.mIndices[a]];
|
||||||
|
}
|
||||||
|
nor.Normalize();
|
||||||
|
}
|
||||||
|
float nx = nor.x, ny = nor.y, nz = nor.z;
|
||||||
|
AI_SWAP4(nx); AI_SWAP4(ny); AI_SWAP4(nz);
|
||||||
|
mOutput.write((char *)&nx, 4); mOutput.write((char *)&ny, 4); mOutput.write((char *)&nz, 4);
|
||||||
|
for(unsigned int a = 0; a < f.mNumIndices; ++a) {
|
||||||
|
const aiVector3D& v = m->mVertices[f.mIndices[a]];
|
||||||
|
float vx = v.x, vy = v.y, vz = v.z;
|
||||||
|
AI_SWAP4(vx); AI_SWAP4(vy); AI_SWAP4(vz);
|
||||||
|
mOutput.write((char *)&vx, 4); mOutput.write((char *)&vy, 4); mOutput.write((char *)&vz, 4);
|
||||||
|
}
|
||||||
|
char dummy[2] = {0};
|
||||||
|
mOutput.write(dummy, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -59,7 +59,7 @@ class STLExporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Constructor for a specific scene to export
|
/// Constructor for a specific scene to export
|
||||||
STLExporter(const char* filename, const aiScene* pScene);
|
STLExporter(const char* filename, const aiScene* pScene, bool binary = false);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -69,6 +69,7 @@ public:
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void WriteMesh(const aiMesh* m);
|
void WriteMesh(const aiMesh* m);
|
||||||
|
void WriteMeshBinary(const aiMesh* m);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
|
namespace {
|
||||||
static const aiImporterDesc desc = {
|
static const aiImporterDesc desc = {
|
||||||
"Stereolithography (STL) Importer",
|
"Stereolithography (STL) Importer",
|
||||||
"",
|
"",
|
||||||
|
@ -64,6 +65,39 @@ static const aiImporterDesc desc = {
|
||||||
"stl"
|
"stl"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// A valid binary STL buffer should consist of the following elements, in order:
|
||||||
|
// 1) 80 byte header
|
||||||
|
// 2) 4 byte face count
|
||||||
|
// 3) 50 bytes per face
|
||||||
|
bool IsBinarySTL(const char* buffer, unsigned int fileSize) {
|
||||||
|
if (fileSize < 84)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const uint32_t faceCount = *reinterpret_cast<const uint32_t*>(buffer + 80);
|
||||||
|
const uint32_t expectedBinaryFileSize = faceCount * 50 + 84;
|
||||||
|
|
||||||
|
return expectedBinaryFileSize == fileSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// An ascii STL buffer will begin with "solid NAME", where NAME is optional.
|
||||||
|
// Note: The "solid NAME" check is necessary, but not sufficient, to determine
|
||||||
|
// if the buffer is ASCII; a binary header could also begin with "solid NAME".
|
||||||
|
bool IsAsciiSTL(const char* buffer, unsigned int fileSize) {
|
||||||
|
if (IsBinarySTL(buffer, fileSize))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const char* bufferEnd = buffer + fileSize;
|
||||||
|
|
||||||
|
if (!SkipSpaces(&buffer))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (buffer + 5 >= bufferEnd)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return strncmp(buffer, "solid", 5) == 0;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
STLImporter::STLImporter()
|
STLImporter::STLImporter()
|
||||||
|
@ -136,12 +170,13 @@ void STLImporter::InternReadFile( const std::string& pFile,
|
||||||
|
|
||||||
bool bMatClr = false;
|
bool bMatClr = false;
|
||||||
|
|
||||||
// check whether the file starts with 'solid' -
|
if (IsBinarySTL(mBuffer, fileSize)) {
|
||||||
// in this case we can simply assume it IS a text file. finished.
|
bMatClr = LoadBinaryFile();
|
||||||
if (!::strncmp(mBuffer,"solid",5)) {
|
} else if (IsAsciiSTL(mBuffer, fileSize)) {
|
||||||
LoadASCIIFile();
|
LoadASCIIFile();
|
||||||
|
} else {
|
||||||
|
throw DeadlyImportError( "Failed to determine STL storage representation for " + pFile + ".");
|
||||||
}
|
}
|
||||||
else bMatClr = LoadBinaryFile();
|
|
||||||
|
|
||||||
// now copy faces
|
// now copy faces
|
||||||
pMesh->mFaces = new aiFace[pMesh->mNumFaces];
|
pMesh->mFaces = new aiFace[pMesh->mNumFaces];
|
||||||
|
@ -179,7 +214,11 @@ void STLImporter::LoadASCIIFile()
|
||||||
{
|
{
|
||||||
aiMesh* pMesh = pScene->mMeshes[0];
|
aiMesh* pMesh = pScene->mMeshes[0];
|
||||||
|
|
||||||
const char* sz = mBuffer + 5; // skip the "solid"
|
const char* sz = mBuffer;
|
||||||
|
SkipSpaces(&sz);
|
||||||
|
ai_assert(!IsLineEnd(sz));
|
||||||
|
|
||||||
|
sz += 5; // skip the "solid"
|
||||||
SkipSpaces(&sz);
|
SkipSpaces(&sz);
|
||||||
const char* szMe = sz;
|
const char* szMe = sz;
|
||||||
while (!::IsSpaceOrNewLine(*sz)) {
|
while (!::IsSpaceOrNewLine(*sz)) {
|
||||||
|
|
|
@ -53,6 +53,7 @@ struct ScenePrivateData {
|
||||||
ScenePrivateData()
|
ScenePrivateData()
|
||||||
: mOrigImporter()
|
: mOrigImporter()
|
||||||
, mPPStepsApplied()
|
, mPPStepsApplied()
|
||||||
|
, mIsCopy()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// Importer that originally loaded the scene though the C-API
|
// Importer that originally loaded the scene though the C-API
|
||||||
|
@ -61,6 +62,13 @@ struct ScenePrivateData {
|
||||||
|
|
||||||
// List of postprocessing steps already applied to the scene.
|
// List of postprocessing steps already applied to the scene.
|
||||||
unsigned int mPPStepsApplied;
|
unsigned int mPPStepsApplied;
|
||||||
|
|
||||||
|
// true if the scene is a copy made with aiCopyScene()
|
||||||
|
// or the corresponding C++ API. This means that user code
|
||||||
|
// may have made modifications to it, so mPPStepsApplied
|
||||||
|
// and mOrigImporter are no longer safe to rely on and only
|
||||||
|
// serve informative purposes.
|
||||||
|
bool mIsCopy;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Access private data stored in the scene
|
// Access private data stored in the scene
|
||||||
|
|
|
@ -151,7 +151,7 @@ void SortByPTypeProcess::Execute( aiScene* pScene)
|
||||||
std::vector<unsigned int>::iterator meshIdx = replaceMeshIndex.begin();
|
std::vector<unsigned int>::iterator meshIdx = replaceMeshIndex.begin();
|
||||||
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
|
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
|
||||||
{
|
{
|
||||||
aiMesh* mesh = pScene->mMeshes[i];
|
aiMesh* const mesh = pScene->mMeshes[i];
|
||||||
ai_assert(0 != mesh->mPrimitiveTypes);
|
ai_assert(0 != mesh->mPrimitiveTypes);
|
||||||
|
|
||||||
// if there's just one primitive type in the mesh there's nothing to do for us
|
// if there's just one primitive type in the mesh there's nothing to do for us
|
||||||
|
@ -367,6 +367,9 @@ void SortByPTypeProcess::Execute( aiScene* pScene)
|
||||||
|
|
||||||
// delete the input mesh
|
// delete the input mesh
|
||||||
delete mesh;
|
delete mesh;
|
||||||
|
|
||||||
|
// avoid invalid pointer
|
||||||
|
pScene->mMeshes[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outMeshes.empty())
|
if (outMeshes.empty())
|
||||||
|
|
|
@ -193,7 +193,7 @@ public:
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
/** Increase the file pointer (relative seeking) */
|
/** Increase the file pointer (relative seeking) */
|
||||||
void IncPtr(int plus) {
|
void IncPtr(size_t plus) {
|
||||||
current += plus;
|
current += plus;
|
||||||
if (current > limit) {
|
if (current > limit) {
|
||||||
throw DeadlyImportError("End of file or read limit was reached");
|
throw DeadlyImportError("End of file or read limit was reached");
|
||||||
|
|
|
@ -82,7 +82,7 @@ protected:
|
||||||
/** Report a validation error. This will throw an exception,
|
/** Report a validation error. This will throw an exception,
|
||||||
* control won't return.
|
* control won't return.
|
||||||
* @param msg Format string for sprintf().*/
|
* @param msg Format string for sprintf().*/
|
||||||
AI_WONT_RETURN void ReportError(const char* msg,...);
|
AI_WONT_RETURN void ReportError(const char* msg,...) AI_WONT_RETURN_SUFFIX;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#define __FAST_A_TO_F_H_INCLUDED__
|
#define __FAST_A_TO_F_H_INCLUDED__
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp
|
||||||
{
|
{
|
||||||
|
|
|
@ -164,6 +164,8 @@ int Triangle::Index(const Point* p)
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
assert(0);
|
assert(0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Triangle::EdgeIndex(const Point* p1, const Point* p2)
|
int Triangle::EdgeIndex(const Point* p1, const Point* p2)
|
||||||
|
@ -223,6 +225,8 @@ Point* Triangle::PointCW(Point& point)
|
||||||
return points_[1];
|
return points_[1];
|
||||||
}
|
}
|
||||||
assert(0);
|
assert(0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The point counter-clockwise to given point
|
// The point counter-clockwise to given point
|
||||||
|
@ -236,6 +240,8 @@ Point* Triangle::PointCCW(Point& point)
|
||||||
return points_[0];
|
return points_[0];
|
||||||
}
|
}
|
||||||
assert(0);
|
assert(0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The neighbor clockwise to given point
|
// The neighbor clockwise to given point
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace p2t {
|
namespace p2t {
|
||||||
|
|
||||||
|
@ -137,8 +138,8 @@ struct Edge {
|
||||||
p = &p2;
|
p = &p2;
|
||||||
} else if (p1.x == p2.x) {
|
} else if (p1.x == p2.x) {
|
||||||
// Repeat points
|
// Repeat points
|
||||||
// ASSIMP_CHANGE (aramis_acg)
|
// ASSIMP_CHANGE (aramis_acg)
|
||||||
throw std::runtime_error("repeat points");
|
throw std::runtime_error(std::string("repeat points"));
|
||||||
//assert(false);
|
//assert(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,25 @@
|
||||||
|
cmake_minimum_required(VERSION 2.4.4)
|
||||||
|
set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)
|
||||||
|
|
||||||
|
project(zlib C)
|
||||||
|
|
||||||
|
set(VERSION "1.2.8")
|
||||||
|
|
||||||
|
option(ASM686 "Enable building i686 assembly implementation for zlib")
|
||||||
|
option(AMD64 "Enable building amd64 assembly implementation for zlib")
|
||||||
|
|
||||||
|
#set(INSTALL_BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Installation directory for executables")
|
||||||
|
#set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation directory for libraries")
|
||||||
|
#set(INSTALL_INC_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "Installation directory for headers")
|
||||||
|
#set(INSTALL_MAN_DIR "${CMAKE_INSTALL_PREFIX}/share/man" CACHE PATH "Installation directory for manual pages")
|
||||||
|
#set(INSTALL_PKGCONFIG_DIR "${CMAKE_INSTALL_PREFIX}/share/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files")
|
||||||
|
|
||||||
|
include(CheckTypeSize)
|
||||||
|
include(CheckFunctionExists)
|
||||||
|
include(CheckIncludeFile)
|
||||||
|
include(CheckCSourceCompiles)
|
||||||
|
enable_testing()
|
||||||
|
|
||||||
check_include_file(sys/types.h HAVE_SYS_TYPES_H)
|
check_include_file(sys/types.h HAVE_SYS_TYPES_H)
|
||||||
check_include_file(stdint.h HAVE_STDINT_H)
|
check_include_file(stdint.h HAVE_STDINT_H)
|
||||||
check_include_file(stddef.h HAVE_STDDEF_H)
|
check_include_file(stddef.h HAVE_STDDEF_H)
|
||||||
|
@ -18,7 +40,6 @@ endif()
|
||||||
if(HAVE_STDDEF_H)
|
if(HAVE_STDDEF_H)
|
||||||
list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDDEF_H)
|
list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDDEF_H)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
check_type_size(off64_t OFF64_T)
|
check_type_size(off64_t OFF64_T)
|
||||||
if(HAVE_OFF64_T)
|
if(HAVE_OFF64_T)
|
||||||
add_definitions(-D_LARGEFILE64_SOURCE=1)
|
add_definitions(-D_LARGEFILE64_SOURCE=1)
|
||||||
|
@ -42,22 +63,28 @@ if(MSVC)
|
||||||
set(CMAKE_DEBUG_POSTFIX "d")
|
set(CMAKE_DEBUG_POSTFIX "d")
|
||||||
add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
|
add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
|
||||||
add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE)
|
add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE)
|
||||||
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
|
||||||
# If we're doing an out of source build and the user has a zconf.h
|
# If we're doing an out of source build and the user has a zconf.h
|
||||||
# in their source tree...
|
# in their source tree...
|
||||||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h)
|
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h)
|
||||||
message(FATAL_ERROR
|
message(STATUS "Renaming")
|
||||||
"You must remove ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h "
|
message(STATUS " ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h")
|
||||||
"from the source tree. This file is included with zlib "
|
message(STATUS "to 'zconf.h.included' because this file is included with zlib")
|
||||||
"but CMake generates this file for you automatically "
|
message(STATUS "but CMake generates it automatically in the build directory.")
|
||||||
"in the build directory.")
|
file(RENAME ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.included)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#configure_file(${CMAKE_CURRENT_SOURCE_DIR}/zconf.in.h ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h @ONLY)
|
set(ZLIB_PC ${CMAKE_CURRENT_BINARY_DIR}/zlib.pc)
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zlib.pc.cmakein
|
||||||
|
${ZLIB_PC} @ONLY)
|
||||||
|
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.cmakein
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/zconf.h @ONLY)
|
||||||
|
|
||||||
|
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR})
|
||||||
|
|
||||||
|
|
||||||
#============================================================================
|
#============================================================================
|
||||||
|
@ -65,28 +92,104 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
#============================================================================
|
#============================================================================
|
||||||
|
|
||||||
set(ZLIB_PUBLIC_HDRS
|
set(ZLIB_PUBLIC_HDRS
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/zconf.h
|
${CMAKE_CURRENT_BINARY_DIR}/zconf.h
|
||||||
zlib.h
|
zlib.h
|
||||||
)
|
)
|
||||||
set(ZLIB_PRIVATE_HDRS
|
set(ZLIB_PRIVATE_HDRS
|
||||||
crc32.h deflate.h inffast.h inffixed.h inflate.h inftrees.h trees.h zconf.h zlib.h zutil.h
|
crc32.h
|
||||||
|
deflate.h
|
||||||
|
gzguts.h
|
||||||
|
inffast.h
|
||||||
|
inffixed.h
|
||||||
|
inflate.h
|
||||||
|
inftrees.h
|
||||||
|
trees.h
|
||||||
|
zutil.h
|
||||||
)
|
)
|
||||||
set(ZLIB_SRCS
|
set(ZLIB_SRCS
|
||||||
adler32.c compress.c crc32.c deflate.c inffast.c inflate.c inftrees.c trees.c zutil.c
|
adler32.c
|
||||||
|
compress.c
|
||||||
|
crc32.c
|
||||||
|
deflate.c
|
||||||
|
gzclose.c
|
||||||
|
gzlib.c
|
||||||
|
gzread.c
|
||||||
|
gzwrite.c
|
||||||
|
inflate.c
|
||||||
|
infback.c
|
||||||
|
inftrees.c
|
||||||
|
inffast.c
|
||||||
|
trees.c
|
||||||
|
uncompr.c
|
||||||
|
zutil.c
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(NOT MINGW)
|
||||||
|
set(ZLIB_DLL_SRCS
|
||||||
|
win32/zlib1.rc # If present will override custom build rule below.
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CMAKE_COMPILER_IS_GNUCC)
|
||||||
|
if(ASM686)
|
||||||
|
set(ZLIB_ASMS contrib/asm686/match.S)
|
||||||
|
elseif (AMD64)
|
||||||
|
set(ZLIB_ASMS contrib/amd64/amd64-match.S)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if(ZLIB_ASMS)
|
||||||
|
add_definitions(-DASMV)
|
||||||
|
set_source_files_properties(${ZLIB_ASMS} PROPERTIES LANGUAGE C COMPILE_FLAGS -DNO_UNDERLINE)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(MSVC)
|
||||||
|
if(ASM686)
|
||||||
|
ENABLE_LANGUAGE(ASM_MASM)
|
||||||
|
set(ZLIB_ASMS
|
||||||
|
contrib/masmx86/inffas32.asm
|
||||||
|
contrib/masmx86/match686.asm
|
||||||
|
)
|
||||||
|
elseif (AMD64)
|
||||||
|
ENABLE_LANGUAGE(ASM_MASM)
|
||||||
|
set(ZLIB_ASMS
|
||||||
|
contrib/masmx64/gvmat64.asm
|
||||||
|
contrib/masmx64/inffasx64.asm
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ZLIB_ASMS)
|
||||||
|
add_definitions(-DASMV -DASMINF)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
# parse the full version number from zlib.h and include in ZLIB_FULL_VERSION
|
# parse the full version number from zlib.h and include in ZLIB_FULL_VERSION
|
||||||
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents)
|
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents)
|
||||||
string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([0-9A-Za-z.]+)\".*"
|
string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*"
|
||||||
"\\1" ZLIB_FULL_VERSION ${_zlib_h_contents})
|
"\\1" ZLIB_FULL_VERSION ${_zlib_h_contents})
|
||||||
|
|
||||||
add_library(zlib STATIC ${ZLIB_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})
|
if(MINGW)
|
||||||
set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS}")
|
# This gets us DLL resource information when compiling on MinGW.
|
||||||
|
if(NOT CMAKE_RC_COMPILER)
|
||||||
|
set(CMAKE_RC_COMPILER windres.exe)
|
||||||
|
endif()
|
||||||
|
|
||||||
set_target_properties(zlib PROPERTIES SOVERSION 1)
|
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj
|
||||||
|
COMMAND ${CMAKE_RC_COMPILER}
|
||||||
|
-D GCC_WINDRES
|
||||||
|
-I ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
-I ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
-o ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj
|
||||||
|
-i ${CMAKE_CURRENT_SOURCE_DIR}/win32/zlib1.rc)
|
||||||
|
set(ZLIB_DLL_SRCS ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj)
|
||||||
|
endif(MINGW)
|
||||||
|
|
||||||
if(NOT CYGWIN)
|
#add_library(zlib SHARED ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_DLL_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})
|
||||||
|
add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})
|
||||||
|
#set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL)
|
||||||
|
#set_target_properties(zlib PROPERTIES SOVERSION 1)
|
||||||
|
|
||||||
|
#if(NOT CYGWIN)
|
||||||
# This property causes shared libraries on Linux to have the full version
|
# This property causes shared libraries on Linux to have the full version
|
||||||
# encoded into their final filename. We disable this on Cygwin because
|
# encoded into their final filename. We disable this on Cygwin because
|
||||||
# it causes cygz-${ZLIB_FULL_VERSION}.dll to be created when cygz.dll
|
# it causes cygz-${ZLIB_FULL_VERSION}.dll to be created when cygz.dll
|
||||||
|
@ -94,48 +197,33 @@ if(NOT CYGWIN)
|
||||||
#
|
#
|
||||||
# This has no effect with MSVC, on that platform the version info for
|
# This has no effect with MSVC, on that platform the version info for
|
||||||
# the DLL comes from the resource file win32/zlib1.rc
|
# the DLL comes from the resource file win32/zlib1.rc
|
||||||
set_target_properties(zlib PROPERTIES VERSION ${ZLIB_FULL_VERSION})
|
#set_target_properties(zlib PROPERTIES VERSION ${ZLIB_FULL_VERSION})
|
||||||
endif()
|
#endif()
|
||||||
|
|
||||||
if(UNIX)
|
#if(UNIX)
|
||||||
# On unix-like platforms the library is almost always called libz
|
# On unix-like platforms the library is almost always called libz
|
||||||
set_target_properties(zlib PROPERTIES OUTPUT_NAME z)
|
#set_target_properties(zlib zlibstatic PROPERTIES OUTPUT_NAME z)
|
||||||
elseif(BUILD_SHARED_LIBS AND WIN32)
|
#if(NOT APPLE)
|
||||||
# Creates zlib1.dll when building shared library version
|
# set_target_properties(zlib PROPERTIES LINK_FLAGS "-Wl,--version-script,\"${CMAKE_CURRENT_SOURCE_DIR}/zlib.map\"")
|
||||||
set_target_properties(zlib PROPERTIES SUFFIX "1.dll")
|
#endif()
|
||||||
endif()
|
#elseif(BUILD_SHARED_LIBS AND WIN32)
|
||||||
|
# # Creates zlib1.dll when building shared library version
|
||||||
|
# set_target_properties(zlib PROPERTIES SUFFIX "1.dll")
|
||||||
|
#endif()
|
||||||
|
|
||||||
#if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL )
|
#if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL )
|
||||||
# install(TARGETS zlib
|
# install(TARGETS zlib zlibstatic
|
||||||
# RUNTIME DESTINATION bin
|
# RUNTIME DESTINATION "${INSTALL_BIN_DIR}"
|
||||||
# ARCHIVE DESTINATION lib
|
# ARCHIVE DESTINATION "${INSTALL_LIB_DIR}"
|
||||||
# LIBRARY DESTINATION lib )
|
# LIBRARY DESTINATION "${INSTALL_LIB_DIR}" )
|
||||||
#endif()
|
#endif()
|
||||||
#if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL )
|
#if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL )
|
||||||
# install(FILES ${ZLIB_PUBLIC_HDRS} DESTINATION include)
|
# install(FILES ${ZLIB_PUBLIC_HDRS} DESTINATION "${INSTALL_INC_DIR}")
|
||||||
#endif()
|
#endif()
|
||||||
#if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL )
|
#if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL )
|
||||||
# install(FILES zlib.3 DESTINATION share/man/man3)
|
# install(FILES zlib.3 DESTINATION "${INSTALL_MAN_DIR}/man3")
|
||||||
|
#endif()
|
||||||
|
#if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL )
|
||||||
|
# install(FILES ${ZLIB_PC} DESTINATION "${INSTALL_PKGCONFIG_DIR}")
|
||||||
#endif()
|
#endif()
|
||||||
|
|
||||||
#============================================================================
|
|
||||||
# Example binaries
|
|
||||||
#============================================================================
|
|
||||||
|
|
||||||
#add_executable(example example.c)
|
|
||||||
#target_link_libraries(example zlib)
|
|
||||||
#add_test(example example)
|
|
||||||
#
|
|
||||||
#add_executable(minigzip minigzip.c)
|
|
||||||
#target_link_libraries(minigzip zlib)
|
|
||||||
#
|
|
||||||
#if(HAVE_OFF64_T)
|
|
||||||
# add_executable(example64 example.c)
|
|
||||||
# target_link_libraries(example64 zlib)
|
|
||||||
# set_target_properties(example64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64")
|
|
||||||
# add_test(example64 example64)
|
|
||||||
#
|
|
||||||
# add_executable(minigzip64 minigzip.c)
|
|
||||||
# target_link_libraries(minigzip64 zlib)
|
|
||||||
# set_target_properties(minigzip64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64")
|
|
||||||
#endif()
|
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
ZLIB DATA COMPRESSION LIBRARY
|
ZLIB DATA COMPRESSION LIBRARY
|
||||||
|
|
||||||
zlib 1.2.5 is a general purpose data compression library. All the code is
|
zlib 1.2.8 is a general purpose data compression library. All the code is
|
||||||
thread safe. The data format used by the zlib library is described by RFCs
|
thread safe. The data format used by the zlib library is described by RFCs
|
||||||
(Request for Comments) 1950 to 1952 in the files
|
(Request for Comments) 1950 to 1952 in the files
|
||||||
http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
|
http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and
|
||||||
and rfc1952.txt (gzip format).
|
rfc1952 (gzip format).
|
||||||
|
|
||||||
All functions of the compression library are documented in the file zlib.h
|
All functions of the compression library are documented in the file zlib.h
|
||||||
(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
|
(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
|
||||||
of the library is given in the file example.c which also tests that the library
|
of the library is given in the file test/example.c which also tests that
|
||||||
is working correctly. Another example is given in the file minigzip.c. The
|
the library is working correctly. Another example is given in the file
|
||||||
compression library itself is composed of all source files except example.c and
|
test/minigzip.c. The compression library itself is composed of all source
|
||||||
minigzip.c.
|
files in the root directory.
|
||||||
|
|
||||||
To compile all files and run the test program, follow the instructions given at
|
To compile all files and run the test program, follow the instructions given at
|
||||||
the top of Makefile.in. In short "./configure; make test", and if that goes
|
the top of Makefile.in. In short "./configure; make test", and if that goes
|
||||||
well, "make install" should work for most flavors of Unix. For Windows, use one
|
well, "make install" should work for most flavors of Unix. For Windows, use
|
||||||
of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use
|
one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use
|
||||||
make_vms.com.
|
make_vms.com.
|
||||||
|
|
||||||
Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
|
Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
|
||||||
|
@ -31,7 +31,7 @@ Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
|
||||||
issue of Dr. Dobb's Journal; a copy of the article is available at
|
issue of Dr. Dobb's Journal; a copy of the article is available at
|
||||||
http://marknelson.us/1997/01/01/zlib-engine/ .
|
http://marknelson.us/1997/01/01/zlib-engine/ .
|
||||||
|
|
||||||
The changes made in version 1.2.5 are documented in the file ChangeLog.
|
The changes made in version 1.2.8 are documented in the file ChangeLog.
|
||||||
|
|
||||||
Unsupported third party contributions are provided in directory contrib/ .
|
Unsupported third party contributions are provided in directory contrib/ .
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ http://search.cpan.org/~pmqs/IO-Compress-Zlib/ .
|
||||||
|
|
||||||
A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is
|
A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is
|
||||||
available in Python 1.5 and later versions, see
|
available in Python 1.5 and later versions, see
|
||||||
http://www.python.org/doc/lib/module-zlib.html .
|
http://docs.python.org/library/zlib.html .
|
||||||
|
|
||||||
zlib is built into tcl: http://wiki.tcl.tk/4610 .
|
zlib is built into tcl: http://wiki.tcl.tk/4610 .
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ Acknowledgments:
|
||||||
|
|
||||||
Copyright notice:
|
Copyright notice:
|
||||||
|
|
||||||
(C) 1995-2010 Jean-loup Gailly and Mark Adler
|
(C) 1995-2013 Jean-loup Gailly and Mark Adler
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any damages
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* adler32.c -- compute the Adler-32 checksum of a data stream
|
/* adler32.c -- compute the Adler-32 checksum of a data stream
|
||||||
* Copyright (C) 1995-2007 Mark Adler
|
* Copyright (C) 1995-2011 Mark Adler
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -9,9 +9,9 @@
|
||||||
|
|
||||||
#define local static
|
#define local static
|
||||||
|
|
||||||
local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2);
|
local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
|
||||||
|
|
||||||
#define BASE 65521UL /* largest prime smaller than 65536 */
|
#define BASE 65521 /* largest prime smaller than 65536 */
|
||||||
#define NMAX 5552
|
#define NMAX 5552
|
||||||
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
|
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
|
||||||
|
|
||||||
|
@ -21,39 +21,44 @@ local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2);
|
||||||
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
|
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
|
||||||
#define DO16(buf) DO8(buf,0); DO8(buf,8);
|
#define DO16(buf) DO8(buf,0); DO8(buf,8);
|
||||||
|
|
||||||
/* use NO_DIVIDE if your processor does not do division in hardware */
|
/* use NO_DIVIDE if your processor does not do division in hardware --
|
||||||
|
try it both ways to see which is faster */
|
||||||
#ifdef NO_DIVIDE
|
#ifdef NO_DIVIDE
|
||||||
# define MOD(a) \
|
/* note that this assumes BASE is 65521, where 65536 % 65521 == 15
|
||||||
|
(thank you to John Reiser for pointing this out) */
|
||||||
|
# define CHOP(a) \
|
||||||
do { \
|
do { \
|
||||||
if (a >= (BASE << 16)) a -= (BASE << 16); \
|
unsigned long tmp = a >> 16; \
|
||||||
if (a >= (BASE << 15)) a -= (BASE << 15); \
|
a &= 0xffffUL; \
|
||||||
if (a >= (BASE << 14)) a -= (BASE << 14); \
|
a += (tmp << 4) - tmp; \
|
||||||
if (a >= (BASE << 13)) a -= (BASE << 13); \
|
} while (0)
|
||||||
if (a >= (BASE << 12)) a -= (BASE << 12); \
|
# define MOD28(a) \
|
||||||
if (a >= (BASE << 11)) a -= (BASE << 11); \
|
do { \
|
||||||
if (a >= (BASE << 10)) a -= (BASE << 10); \
|
CHOP(a); \
|
||||||
if (a >= (BASE << 9)) a -= (BASE << 9); \
|
|
||||||
if (a >= (BASE << 8)) a -= (BASE << 8); \
|
|
||||||
if (a >= (BASE << 7)) a -= (BASE << 7); \
|
|
||||||
if (a >= (BASE << 6)) a -= (BASE << 6); \
|
|
||||||
if (a >= (BASE << 5)) a -= (BASE << 5); \
|
|
||||||
if (a >= (BASE << 4)) a -= (BASE << 4); \
|
|
||||||
if (a >= (BASE << 3)) a -= (BASE << 3); \
|
|
||||||
if (a >= (BASE << 2)) a -= (BASE << 2); \
|
|
||||||
if (a >= (BASE << 1)) a -= (BASE << 1); \
|
|
||||||
if (a >= BASE) a -= BASE; \
|
if (a >= BASE) a -= BASE; \
|
||||||
} while (0)
|
} while (0)
|
||||||
# define MOD4(a) \
|
# define MOD(a) \
|
||||||
do { \
|
do { \
|
||||||
if (a >= (BASE << 4)) a -= (BASE << 4); \
|
CHOP(a); \
|
||||||
if (a >= (BASE << 3)) a -= (BASE << 3); \
|
MOD28(a); \
|
||||||
if (a >= (BASE << 2)) a -= (BASE << 2); \
|
} while (0)
|
||||||
if (a >= (BASE << 1)) a -= (BASE << 1); \
|
# define MOD63(a) \
|
||||||
|
do { /* this assumes a is not negative */ \
|
||||||
|
z_off64_t tmp = a >> 32; \
|
||||||
|
a &= 0xffffffffL; \
|
||||||
|
a += (tmp << 8) - (tmp << 5) + tmp; \
|
||||||
|
tmp = a >> 16; \
|
||||||
|
a &= 0xffffL; \
|
||||||
|
a += (tmp << 4) - tmp; \
|
||||||
|
tmp = a >> 16; \
|
||||||
|
a &= 0xffffL; \
|
||||||
|
a += (tmp << 4) - tmp; \
|
||||||
if (a >= BASE) a -= BASE; \
|
if (a >= BASE) a -= BASE; \
|
||||||
} while (0)
|
} while (0)
|
||||||
#else
|
#else
|
||||||
# define MOD(a) a %= BASE
|
# define MOD(a) a %= BASE
|
||||||
# define MOD4(a) a %= BASE
|
# define MOD28(a) a %= BASE
|
||||||
|
# define MOD63(a) a %= BASE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
@ -92,7 +97,7 @@ uLong ZEXPORT adler32(adler, buf, len)
|
||||||
}
|
}
|
||||||
if (adler >= BASE)
|
if (adler >= BASE)
|
||||||
adler -= BASE;
|
adler -= BASE;
|
||||||
MOD4(sum2); /* only added so many BASE's */
|
MOD28(sum2); /* only added so many BASE's */
|
||||||
return adler | (sum2 << 16);
|
return adler | (sum2 << 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,8 +142,13 @@ local uLong adler32_combine_(adler1, adler2, len2)
|
||||||
unsigned long sum2;
|
unsigned long sum2;
|
||||||
unsigned rem;
|
unsigned rem;
|
||||||
|
|
||||||
|
/* for negative len, return invalid adler32 as a clue for debugging */
|
||||||
|
if (len2 < 0)
|
||||||
|
return 0xffffffffUL;
|
||||||
|
|
||||||
/* the derivation of this formula is left as an exercise for the reader */
|
/* the derivation of this formula is left as an exercise for the reader */
|
||||||
rem = (unsigned)(len2 % BASE);
|
MOD63(len2); /* assumes len2 >= 0 */
|
||||||
|
rem = (unsigned)len2;
|
||||||
sum1 = adler1 & 0xffff;
|
sum1 = adler1 & 0xffff;
|
||||||
sum2 = rem * sum1;
|
sum2 = rem * sum1;
|
||||||
MOD(sum2);
|
MOD(sum2);
|
||||||
|
|
|
@ -29,7 +29,7 @@ int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
|
||||||
z_stream stream;
|
z_stream stream;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
stream.next_in = (Bytef*)source;
|
stream.next_in = (z_const Bytef *)source;
|
||||||
stream.avail_in = (uInt)sourceLen;
|
stream.avail_in = (uInt)sourceLen;
|
||||||
#ifdef MAXSEG_64K
|
#ifdef MAXSEG_64K
|
||||||
/* Check for source > 64K on 16-bit machine: */
|
/* Check for source > 64K on 16-bit machine: */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* crc32.c -- compute the CRC-32 of a data stream
|
/* crc32.c -- compute the CRC-32 of a data stream
|
||||||
* Copyright (C) 1995-2006, 2010 Mark Adler
|
* Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
*
|
*
|
||||||
* Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
|
* Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
|
||||||
|
@ -17,6 +17,8 @@
|
||||||
of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
|
of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
|
||||||
first call get_crc_table() to initialize the tables before allowing more than
|
first call get_crc_table() to initialize the tables before allowing more than
|
||||||
one thread to use crc32().
|
one thread to use crc32().
|
||||||
|
|
||||||
|
DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef MAKECRCH
|
#ifdef MAKECRCH
|
||||||
|
@ -30,31 +32,11 @@
|
||||||
|
|
||||||
#define local static
|
#define local static
|
||||||
|
|
||||||
/* Find a four-byte integer type for crc32_little() and crc32_big(). */
|
|
||||||
#ifndef NOBYFOUR
|
|
||||||
# ifdef STDC /* need ANSI C limits.h to determine sizes */
|
|
||||||
# include <limits.h>
|
|
||||||
# define BYFOUR
|
|
||||||
# if (UINT_MAX == 0xffffffffUL)
|
|
||||||
typedef unsigned int u4;
|
|
||||||
# else
|
|
||||||
# if (ULONG_MAX == 0xffffffffUL)
|
|
||||||
typedef unsigned long u4;
|
|
||||||
# else
|
|
||||||
# if (USHRT_MAX == 0xffffffffUL)
|
|
||||||
typedef unsigned short u4;
|
|
||||||
# else
|
|
||||||
# undef BYFOUR /* can't find a four-byte integer type! */
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
# endif /* STDC */
|
|
||||||
#endif /* !NOBYFOUR */
|
|
||||||
|
|
||||||
/* Definitions for doing the crc four data bytes at a time. */
|
/* Definitions for doing the crc four data bytes at a time. */
|
||||||
|
#if !defined(NOBYFOUR) && defined(Z_U4)
|
||||||
|
# define BYFOUR
|
||||||
|
#endif
|
||||||
#ifdef BYFOUR
|
#ifdef BYFOUR
|
||||||
# define REV(w) ((((w)>>24)&0xff)+(((w)>>8)&0xff00)+ \
|
|
||||||
(((w)&0xff00)<<8)+(((w)&0xff)<<24))
|
|
||||||
local unsigned long crc32_little OF((unsigned long,
|
local unsigned long crc32_little OF((unsigned long,
|
||||||
const unsigned char FAR *, unsigned));
|
const unsigned char FAR *, unsigned));
|
||||||
local unsigned long crc32_big OF((unsigned long,
|
local unsigned long crc32_big OF((unsigned long,
|
||||||
|
@ -68,16 +50,16 @@
|
||||||
local unsigned long gf2_matrix_times OF((unsigned long *mat,
|
local unsigned long gf2_matrix_times OF((unsigned long *mat,
|
||||||
unsigned long vec));
|
unsigned long vec));
|
||||||
local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
|
local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
|
||||||
local uLong crc32_combine_(uLong crc1, uLong crc2, z_off64_t len2);
|
local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2));
|
||||||
|
|
||||||
|
|
||||||
#ifdef DYNAMIC_CRC_TABLE
|
#ifdef DYNAMIC_CRC_TABLE
|
||||||
|
|
||||||
local volatile int crc_table_empty = 1;
|
local volatile int crc_table_empty = 1;
|
||||||
local unsigned long FAR crc_table[TBLS][256];
|
local z_crc_t FAR crc_table[TBLS][256];
|
||||||
local void make_crc_table OF((void));
|
local void make_crc_table OF((void));
|
||||||
#ifdef MAKECRCH
|
#ifdef MAKECRCH
|
||||||
local void write_table OF((FILE *, const unsigned long FAR *));
|
local void write_table OF((FILE *, const z_crc_t FAR *));
|
||||||
#endif /* MAKECRCH */
|
#endif /* MAKECRCH */
|
||||||
/*
|
/*
|
||||||
Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
|
Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
|
||||||
|
@ -107,9 +89,9 @@ local void make_crc_table OF((void));
|
||||||
*/
|
*/
|
||||||
local void make_crc_table()
|
local void make_crc_table()
|
||||||
{
|
{
|
||||||
unsigned long c;
|
z_crc_t c;
|
||||||
int n, k;
|
int n, k;
|
||||||
unsigned long poly; /* polynomial exclusive-or pattern */
|
z_crc_t poly; /* polynomial exclusive-or pattern */
|
||||||
/* terms of polynomial defining this crc (except x^32): */
|
/* terms of polynomial defining this crc (except x^32): */
|
||||||
static volatile int first = 1; /* flag to limit concurrent making */
|
static volatile int first = 1; /* flag to limit concurrent making */
|
||||||
static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
|
static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
|
||||||
|
@ -121,13 +103,13 @@ local void make_crc_table()
|
||||||
first = 0;
|
first = 0;
|
||||||
|
|
||||||
/* make exclusive-or pattern from polynomial (0xedb88320UL) */
|
/* make exclusive-or pattern from polynomial (0xedb88320UL) */
|
||||||
poly = 0UL;
|
poly = 0;
|
||||||
for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
|
for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++)
|
||||||
poly |= 1UL << (31 - p[n]);
|
poly |= (z_crc_t)1 << (31 - p[n]);
|
||||||
|
|
||||||
/* generate a crc for every 8-bit value */
|
/* generate a crc for every 8-bit value */
|
||||||
for (n = 0; n < 256; n++) {
|
for (n = 0; n < 256; n++) {
|
||||||
c = (unsigned long)n;
|
c = (z_crc_t)n;
|
||||||
for (k = 0; k < 8; k++)
|
for (k = 0; k < 8; k++)
|
||||||
c = c & 1 ? poly ^ (c >> 1) : c >> 1;
|
c = c & 1 ? poly ^ (c >> 1) : c >> 1;
|
||||||
crc_table[0][n] = c;
|
crc_table[0][n] = c;
|
||||||
|
@ -138,11 +120,11 @@ local void make_crc_table()
|
||||||
and then the byte reversal of those as well as the first table */
|
and then the byte reversal of those as well as the first table */
|
||||||
for (n = 0; n < 256; n++) {
|
for (n = 0; n < 256; n++) {
|
||||||
c = crc_table[0][n];
|
c = crc_table[0][n];
|
||||||
crc_table[4][n] = REV(c);
|
crc_table[4][n] = ZSWAP32(c);
|
||||||
for (k = 1; k < 4; k++) {
|
for (k = 1; k < 4; k++) {
|
||||||
c = crc_table[0][c & 0xff] ^ (c >> 8);
|
c = crc_table[0][c & 0xff] ^ (c >> 8);
|
||||||
crc_table[k][n] = c;
|
crc_table[k][n] = c;
|
||||||
crc_table[k + 4][n] = REV(c);
|
crc_table[k + 4][n] = ZSWAP32(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* BYFOUR */
|
#endif /* BYFOUR */
|
||||||
|
@ -164,7 +146,7 @@ local void make_crc_table()
|
||||||
if (out == NULL) return;
|
if (out == NULL) return;
|
||||||
fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
|
fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
|
||||||
fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
|
fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
|
||||||
fprintf(out, "local const unsigned long FAR ");
|
fprintf(out, "local const z_crc_t FAR ");
|
||||||
fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
|
fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
|
||||||
write_table(out, crc_table[0]);
|
write_table(out, crc_table[0]);
|
||||||
# ifdef BYFOUR
|
# ifdef BYFOUR
|
||||||
|
@ -184,12 +166,13 @@ local void make_crc_table()
|
||||||
#ifdef MAKECRCH
|
#ifdef MAKECRCH
|
||||||
local void write_table(out, table)
|
local void write_table(out, table)
|
||||||
FILE *out;
|
FILE *out;
|
||||||
const unsigned long FAR *table;
|
const z_crc_t FAR *table;
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
for (n = 0; n < 256; n++)
|
for (n = 0; n < 256; n++)
|
||||||
fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
|
fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ",
|
||||||
|
(unsigned long)(table[n]),
|
||||||
n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
|
n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
|
||||||
}
|
}
|
||||||
#endif /* MAKECRCH */
|
#endif /* MAKECRCH */
|
||||||
|
@ -204,13 +187,13 @@ local void write_table(out, table)
|
||||||
/* =========================================================================
|
/* =========================================================================
|
||||||
* This function can be used by asm versions of crc32()
|
* This function can be used by asm versions of crc32()
|
||||||
*/
|
*/
|
||||||
const unsigned long FAR * ZEXPORT get_crc_table()
|
const z_crc_t FAR * ZEXPORT get_crc_table()
|
||||||
{
|
{
|
||||||
#ifdef DYNAMIC_CRC_TABLE
|
#ifdef DYNAMIC_CRC_TABLE
|
||||||
if (crc_table_empty)
|
if (crc_table_empty)
|
||||||
make_crc_table();
|
make_crc_table();
|
||||||
#endif /* DYNAMIC_CRC_TABLE */
|
#endif /* DYNAMIC_CRC_TABLE */
|
||||||
return (const unsigned long FAR *)crc_table;
|
return (const z_crc_t FAR *)crc_table;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
@ -232,7 +215,7 @@ unsigned long ZEXPORT crc32(crc, buf, len)
|
||||||
|
|
||||||
#ifdef BYFOUR
|
#ifdef BYFOUR
|
||||||
if (sizeof(void *) == sizeof(ptrdiff_t)) {
|
if (sizeof(void *) == sizeof(ptrdiff_t)) {
|
||||||
u4 endian;
|
z_crc_t endian;
|
||||||
|
|
||||||
endian = 1;
|
endian = 1;
|
||||||
if (*((unsigned char *)(&endian)))
|
if (*((unsigned char *)(&endian)))
|
||||||
|
@ -266,17 +249,17 @@ local unsigned long crc32_little(crc, buf, len)
|
||||||
const unsigned char FAR *buf;
|
const unsigned char FAR *buf;
|
||||||
unsigned len;
|
unsigned len;
|
||||||
{
|
{
|
||||||
register u4 c;
|
register z_crc_t c;
|
||||||
register const u4 FAR *buf4;
|
register const z_crc_t FAR *buf4;
|
||||||
|
|
||||||
c = (u4)crc;
|
c = (z_crc_t)crc;
|
||||||
c = ~c;
|
c = ~c;
|
||||||
while (len && ((ptrdiff_t)buf & 3)) {
|
while (len && ((ptrdiff_t)buf & 3)) {
|
||||||
c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
|
c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
|
||||||
len--;
|
len--;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf4 = (const u4 FAR *)(const void FAR *)buf;
|
buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
|
||||||
while (len >= 32) {
|
while (len >= 32) {
|
||||||
DOLIT32;
|
DOLIT32;
|
||||||
len -= 32;
|
len -= 32;
|
||||||
|
@ -306,17 +289,17 @@ local unsigned long crc32_big(crc, buf, len)
|
||||||
const unsigned char FAR *buf;
|
const unsigned char FAR *buf;
|
||||||
unsigned len;
|
unsigned len;
|
||||||
{
|
{
|
||||||
register u4 c;
|
register z_crc_t c;
|
||||||
register const u4 FAR *buf4;
|
register const z_crc_t FAR *buf4;
|
||||||
|
|
||||||
c = REV((u4)crc);
|
c = ZSWAP32((z_crc_t)crc);
|
||||||
c = ~c;
|
c = ~c;
|
||||||
while (len && ((ptrdiff_t)buf & 3)) {
|
while (len && ((ptrdiff_t)buf & 3)) {
|
||||||
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
|
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
|
||||||
len--;
|
len--;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf4 = (const u4 FAR *)(const void FAR *)buf;
|
buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
|
||||||
buf4--;
|
buf4--;
|
||||||
while (len >= 32) {
|
while (len >= 32) {
|
||||||
DOBIG32;
|
DOBIG32;
|
||||||
|
@ -333,7 +316,7 @@ local unsigned long crc32_big(crc, buf, len)
|
||||||
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
|
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
|
||||||
} while (--len);
|
} while (--len);
|
||||||
c = ~c;
|
c = ~c;
|
||||||
return (unsigned long)(REV(c));
|
return (unsigned long)(ZSWAP32(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* BYFOUR */
|
#endif /* BYFOUR */
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* Generated automatically by crc32.c
|
* Generated automatically by crc32.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
local const unsigned long FAR crc_table[TBLS][256] =
|
local const z_crc_t FAR crc_table[TBLS][256] =
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
|
0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* deflate.c -- compress data using the deflation algorithm
|
/* deflate.c -- compress data using the deflation algorithm
|
||||||
* Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
|
* Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
* REFERENCES
|
* REFERENCES
|
||||||
*
|
*
|
||||||
* Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
|
* Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
|
||||||
* Available in http://www.ietf.org/rfc/rfc1951.txt
|
* Available in http://tools.ietf.org/html/rfc1951
|
||||||
*
|
*
|
||||||
* A description of the Rabin and Karp algorithm is given in the book
|
* A description of the Rabin and Karp algorithm is given in the book
|
||||||
* "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
|
* "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
#include "deflate.h"
|
#include "deflate.h"
|
||||||
|
|
||||||
const char deflate_copyright[] =
|
const char deflate_copyright[] =
|
||||||
" deflate 1.2.5 Copyright 1995-2010 Jean-loup Gailly and Mark Adler ";
|
" deflate 1.2.8 Copyright 1995-2013 Jean-loup Gailly and Mark Adler ";
|
||||||
/*
|
/*
|
||||||
If you use the zlib library in a product, an acknowledgment is welcome
|
If you use the zlib library in a product, an acknowledgment is welcome
|
||||||
in the documentation of your product. If for some reason you cannot
|
in the documentation of your product. If for some reason you cannot
|
||||||
|
@ -155,6 +155,9 @@ local const config configuration_table[10] = {
|
||||||
struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
|
struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */
|
||||||
|
#define RANK(f) (((f) << 1) - ((f) > 4 ? 9 : 0))
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Update a hash value with the given input byte
|
* Update a hash value with the given input byte
|
||||||
* IN assertion: all calls to to UPDATE_HASH are made with consecutive
|
* IN assertion: all calls to to UPDATE_HASH are made with consecutive
|
||||||
|
@ -235,10 +238,19 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
|
||||||
|
|
||||||
strm->msg = Z_NULL;
|
strm->msg = Z_NULL;
|
||||||
if (strm->zalloc == (alloc_func)0) {
|
if (strm->zalloc == (alloc_func)0) {
|
||||||
|
#ifdef Z_SOLO
|
||||||
|
return Z_STREAM_ERROR;
|
||||||
|
#else
|
||||||
strm->zalloc = zcalloc;
|
strm->zalloc = zcalloc;
|
||||||
strm->opaque = (voidpf)0;
|
strm->opaque = (voidpf)0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (strm->zfree == (free_func)0) strm->zfree = zcfree;
|
if (strm->zfree == (free_func)0)
|
||||||
|
#ifdef Z_SOLO
|
||||||
|
return Z_STREAM_ERROR;
|
||||||
|
#else
|
||||||
|
strm->zfree = zcfree;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef FASTEST
|
#ifdef FASTEST
|
||||||
if (level != 0) level = 1;
|
if (level != 0) level = 1;
|
||||||
|
@ -293,7 +305,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
|
||||||
if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
|
if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
|
||||||
s->pending_buf == Z_NULL) {
|
s->pending_buf == Z_NULL) {
|
||||||
s->status = FINISH_STATE;
|
s->status = FINISH_STATE;
|
||||||
strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
|
strm->msg = ERR_MSG(Z_MEM_ERROR);
|
||||||
deflateEnd (strm);
|
deflateEnd (strm);
|
||||||
return Z_MEM_ERROR;
|
return Z_MEM_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -314,43 +326,70 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
|
||||||
uInt dictLength;
|
uInt dictLength;
|
||||||
{
|
{
|
||||||
deflate_state *s;
|
deflate_state *s;
|
||||||
uInt length = dictLength;
|
uInt str, n;
|
||||||
uInt n;
|
int wrap;
|
||||||
IPos hash_head = 0;
|
unsigned avail;
|
||||||
|
z_const unsigned char *next;
|
||||||
|
|
||||||
if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
|
if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL)
|
||||||
strm->state->wrap == 2 ||
|
return Z_STREAM_ERROR;
|
||||||
(strm->state->wrap == 1 && strm->state->status != INIT_STATE))
|
s = strm->state;
|
||||||
|
wrap = s->wrap;
|
||||||
|
if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead)
|
||||||
return Z_STREAM_ERROR;
|
return Z_STREAM_ERROR;
|
||||||
|
|
||||||
s = strm->state;
|
/* when using zlib wrappers, compute Adler-32 for provided dictionary */
|
||||||
if (s->wrap)
|
if (wrap == 1)
|
||||||
strm->adler = adler32(strm->adler, dictionary, dictLength);
|
strm->adler = adler32(strm->adler, dictionary, dictLength);
|
||||||
|
s->wrap = 0; /* avoid computing Adler-32 in read_buf */
|
||||||
|
|
||||||
if (length < MIN_MATCH) return Z_OK;
|
/* if dictionary would fill window, just replace the history */
|
||||||
if (length > s->w_size) {
|
if (dictLength >= s->w_size) {
|
||||||
length = s->w_size;
|
if (wrap == 0) { /* already empty otherwise */
|
||||||
dictionary += dictLength - length; /* use the tail of the dictionary */
|
CLEAR_HASH(s);
|
||||||
|
s->strstart = 0;
|
||||||
|
s->block_start = 0L;
|
||||||
|
s->insert = 0;
|
||||||
|
}
|
||||||
|
dictionary += dictLength - s->w_size; /* use the tail */
|
||||||
|
dictLength = s->w_size;
|
||||||
}
|
}
|
||||||
zmemcpy(s->window, dictionary, length);
|
|
||||||
s->strstart = length;
|
|
||||||
s->block_start = (long)length;
|
|
||||||
|
|
||||||
/* Insert all strings in the hash table (except for the last two bytes).
|
/* insert dictionary into window and hash */
|
||||||
* s->lookahead stays null, so s->ins_h will be recomputed at the next
|
avail = strm->avail_in;
|
||||||
* call of fill_window.
|
next = strm->next_in;
|
||||||
*/
|
strm->avail_in = dictLength;
|
||||||
s->ins_h = s->window[0];
|
strm->next_in = (z_const Bytef *)dictionary;
|
||||||
UPDATE_HASH(s, s->ins_h, s->window[1]);
|
fill_window(s);
|
||||||
for (n = 0; n <= length - MIN_MATCH; n++) {
|
while (s->lookahead >= MIN_MATCH) {
|
||||||
INSERT_STRING(s, n, hash_head);
|
str = s->strstart;
|
||||||
|
n = s->lookahead - (MIN_MATCH-1);
|
||||||
|
do {
|
||||||
|
UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
|
||||||
|
#ifndef FASTEST
|
||||||
|
s->prev[str & s->w_mask] = s->head[s->ins_h];
|
||||||
|
#endif
|
||||||
|
s->head[s->ins_h] = (Pos)str;
|
||||||
|
str++;
|
||||||
|
} while (--n);
|
||||||
|
s->strstart = str;
|
||||||
|
s->lookahead = MIN_MATCH-1;
|
||||||
|
fill_window(s);
|
||||||
}
|
}
|
||||||
if (hash_head) hash_head = 0; /* to make compiler happy */
|
s->strstart += s->lookahead;
|
||||||
|
s->block_start = (long)s->strstart;
|
||||||
|
s->insert = s->lookahead;
|
||||||
|
s->lookahead = 0;
|
||||||
|
s->match_length = s->prev_length = MIN_MATCH-1;
|
||||||
|
s->match_available = 0;
|
||||||
|
strm->next_in = next;
|
||||||
|
strm->avail_in = avail;
|
||||||
|
s->wrap = wrap;
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
int ZEXPORT deflateReset (strm)
|
int ZEXPORT deflateResetKeep (strm)
|
||||||
z_streamp strm;
|
z_streamp strm;
|
||||||
{
|
{
|
||||||
deflate_state *s;
|
deflate_state *s;
|
||||||
|
@ -380,11 +419,22 @@ int ZEXPORT deflateReset (strm)
|
||||||
s->last_flush = Z_NO_FLUSH;
|
s->last_flush = Z_NO_FLUSH;
|
||||||
|
|
||||||
_tr_init(s);
|
_tr_init(s);
|
||||||
lm_init(s);
|
|
||||||
|
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ========================================================================= */
|
||||||
|
int ZEXPORT deflateReset (strm)
|
||||||
|
z_streamp strm;
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = deflateResetKeep(strm);
|
||||||
|
if (ret == Z_OK)
|
||||||
|
lm_init(strm->state);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
int ZEXPORT deflateSetHeader (strm, head)
|
int ZEXPORT deflateSetHeader (strm, head)
|
||||||
z_streamp strm;
|
z_streamp strm;
|
||||||
|
@ -396,15 +446,43 @@ int ZEXPORT deflateSetHeader (strm, head)
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ========================================================================= */
|
||||||
|
int ZEXPORT deflatePending (strm, pending, bits)
|
||||||
|
unsigned *pending;
|
||||||
|
int *bits;
|
||||||
|
z_streamp strm;
|
||||||
|
{
|
||||||
|
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
||||||
|
if (pending != Z_NULL)
|
||||||
|
*pending = strm->state->pending;
|
||||||
|
if (bits != Z_NULL)
|
||||||
|
*bits = strm->state->bi_valid;
|
||||||
|
return Z_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
int ZEXPORT deflatePrime (strm, bits, value)
|
int ZEXPORT deflatePrime (strm, bits, value)
|
||||||
z_streamp strm;
|
z_streamp strm;
|
||||||
int bits;
|
int bits;
|
||||||
int value;
|
int value;
|
||||||
{
|
{
|
||||||
|
deflate_state *s;
|
||||||
|
int put;
|
||||||
|
|
||||||
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
||||||
strm->state->bi_valid = bits;
|
s = strm->state;
|
||||||
strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
|
if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3))
|
||||||
|
return Z_BUF_ERROR;
|
||||||
|
do {
|
||||||
|
put = Buf_size - s->bi_valid;
|
||||||
|
if (put > bits)
|
||||||
|
put = bits;
|
||||||
|
s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid);
|
||||||
|
s->bi_valid += put;
|
||||||
|
_tr_flush_bits(s);
|
||||||
|
value >>= put;
|
||||||
|
bits -= put;
|
||||||
|
} while (bits);
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,6 +513,8 @@ int ZEXPORT deflateParams(strm, level, strategy)
|
||||||
strm->total_in != 0) {
|
strm->total_in != 0) {
|
||||||
/* Flush the last buffer: */
|
/* Flush the last buffer: */
|
||||||
err = deflate(strm, Z_BLOCK);
|
err = deflate(strm, Z_BLOCK);
|
||||||
|
if (err == Z_BUF_ERROR && s->pending == 0)
|
||||||
|
err = Z_OK;
|
||||||
}
|
}
|
||||||
if (s->level != level) {
|
if (s->level != level) {
|
||||||
s->level = level;
|
s->level = level;
|
||||||
|
@ -562,19 +642,22 @@ local void putShortMSB (s, b)
|
||||||
local void flush_pending(strm)
|
local void flush_pending(strm)
|
||||||
z_streamp strm;
|
z_streamp strm;
|
||||||
{
|
{
|
||||||
unsigned len = strm->state->pending;
|
unsigned len;
|
||||||
|
deflate_state *s = strm->state;
|
||||||
|
|
||||||
|
_tr_flush_bits(s);
|
||||||
|
len = s->pending;
|
||||||
if (len > strm->avail_out) len = strm->avail_out;
|
if (len > strm->avail_out) len = strm->avail_out;
|
||||||
if (len == 0) return;
|
if (len == 0) return;
|
||||||
|
|
||||||
zmemcpy(strm->next_out, strm->state->pending_out, len);
|
zmemcpy(strm->next_out, s->pending_out, len);
|
||||||
strm->next_out += len;
|
strm->next_out += len;
|
||||||
strm->state->pending_out += len;
|
s->pending_out += len;
|
||||||
strm->total_out += len;
|
strm->total_out += len;
|
||||||
strm->avail_out -= len;
|
strm->avail_out -= len;
|
||||||
strm->state->pending -= len;
|
s->pending -= len;
|
||||||
if (strm->state->pending == 0) {
|
if (s->pending == 0) {
|
||||||
strm->state->pending_out = strm->state->pending_buf;
|
s->pending_out = s->pending_buf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -801,7 +884,7 @@ int ZEXPORT deflate (strm, flush)
|
||||||
* flushes. For repeated and useless calls with Z_FINISH, we keep
|
* flushes. For repeated and useless calls with Z_FINISH, we keep
|
||||||
* returning Z_STREAM_END instead of Z_BUF_ERROR.
|
* returning Z_STREAM_END instead of Z_BUF_ERROR.
|
||||||
*/
|
*/
|
||||||
} else if (strm->avail_in == 0 && flush <= old_flush &&
|
} else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) &&
|
||||||
flush != Z_FINISH) {
|
flush != Z_FINISH) {
|
||||||
ERR_RETURN(strm, Z_BUF_ERROR);
|
ERR_RETURN(strm, Z_BUF_ERROR);
|
||||||
}
|
}
|
||||||
|
@ -850,6 +933,7 @@ int ZEXPORT deflate (strm, flush)
|
||||||
if (s->lookahead == 0) {
|
if (s->lookahead == 0) {
|
||||||
s->strstart = 0;
|
s->strstart = 0;
|
||||||
s->block_start = 0L;
|
s->block_start = 0L;
|
||||||
|
s->insert = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -945,12 +1029,12 @@ int ZEXPORT deflateCopy (dest, source)
|
||||||
|
|
||||||
ss = source->state;
|
ss = source->state;
|
||||||
|
|
||||||
zmemcpy(dest, source, sizeof(z_stream));
|
zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
|
||||||
|
|
||||||
ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
|
ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
|
||||||
if (ds == Z_NULL) return Z_MEM_ERROR;
|
if (ds == Z_NULL) return Z_MEM_ERROR;
|
||||||
dest->state = (struct internal_state FAR *) ds;
|
dest->state = (struct internal_state FAR *) ds;
|
||||||
zmemcpy(ds, ss, sizeof(deflate_state));
|
zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state));
|
||||||
ds->strm = dest;
|
ds->strm = dest;
|
||||||
|
|
||||||
ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
|
ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
|
||||||
|
@ -966,8 +1050,8 @@ int ZEXPORT deflateCopy (dest, source)
|
||||||
}
|
}
|
||||||
/* following zmemcpy do not work for 16-bit MSDOS */
|
/* following zmemcpy do not work for 16-bit MSDOS */
|
||||||
zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
|
zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
|
||||||
zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
|
zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos));
|
||||||
zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
|
zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos));
|
||||||
zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
|
zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
|
||||||
|
|
||||||
ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
|
ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
|
||||||
|
@ -1001,15 +1085,15 @@ local int read_buf(strm, buf, size)
|
||||||
|
|
||||||
strm->avail_in -= len;
|
strm->avail_in -= len;
|
||||||
|
|
||||||
|
zmemcpy(buf, strm->next_in, len);
|
||||||
if (strm->state->wrap == 1) {
|
if (strm->state->wrap == 1) {
|
||||||
strm->adler = adler32(strm->adler, strm->next_in, len);
|
strm->adler = adler32(strm->adler, buf, len);
|
||||||
}
|
}
|
||||||
#ifdef GZIP
|
#ifdef GZIP
|
||||||
else if (strm->state->wrap == 2) {
|
else if (strm->state->wrap == 2) {
|
||||||
strm->adler = crc32(strm->adler, strm->next_in, len);
|
strm->adler = crc32(strm->adler, buf, len);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
zmemcpy(buf, strm->next_in, len);
|
|
||||||
strm->next_in += len;
|
strm->next_in += len;
|
||||||
strm->total_in += len;
|
strm->total_in += len;
|
||||||
|
|
||||||
|
@ -1036,6 +1120,7 @@ local void lm_init (s)
|
||||||
s->strstart = 0;
|
s->strstart = 0;
|
||||||
s->block_start = 0L;
|
s->block_start = 0L;
|
||||||
s->lookahead = 0;
|
s->lookahead = 0;
|
||||||
|
s->insert = 0;
|
||||||
s->match_length = s->prev_length = MIN_MATCH-1;
|
s->match_length = s->prev_length = MIN_MATCH-1;
|
||||||
s->match_available = 0;
|
s->match_available = 0;
|
||||||
s->ins_h = 0;
|
s->ins_h = 0;
|
||||||
|
@ -1310,6 +1395,8 @@ local void fill_window(s)
|
||||||
unsigned more; /* Amount of free space at the end of the window. */
|
unsigned more; /* Amount of free space at the end of the window. */
|
||||||
uInt wsize = s->w_size;
|
uInt wsize = s->w_size;
|
||||||
|
|
||||||
|
Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
|
||||||
|
|
||||||
do {
|
do {
|
||||||
more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
|
more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
|
||||||
|
|
||||||
|
@ -1362,7 +1449,7 @@ local void fill_window(s)
|
||||||
#endif
|
#endif
|
||||||
more += wsize;
|
more += wsize;
|
||||||
}
|
}
|
||||||
if (s->strm->avail_in == 0) return;
|
if (s->strm->avail_in == 0) break;
|
||||||
|
|
||||||
/* If there was no sliding:
|
/* If there was no sliding:
|
||||||
* strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
|
* strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
|
||||||
|
@ -1381,12 +1468,24 @@ local void fill_window(s)
|
||||||
s->lookahead += n;
|
s->lookahead += n;
|
||||||
|
|
||||||
/* Initialize the hash value now that we have some input: */
|
/* Initialize the hash value now that we have some input: */
|
||||||
if (s->lookahead >= MIN_MATCH) {
|
if (s->lookahead + s->insert >= MIN_MATCH) {
|
||||||
s->ins_h = s->window[s->strstart];
|
uInt str = s->strstart - s->insert;
|
||||||
UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
|
s->ins_h = s->window[str];
|
||||||
|
UPDATE_HASH(s, s->ins_h, s->window[str + 1]);
|
||||||
#if MIN_MATCH != 3
|
#if MIN_MATCH != 3
|
||||||
Call UPDATE_HASH() MIN_MATCH-3 more times
|
Call UPDATE_HASH() MIN_MATCH-3 more times
|
||||||
#endif
|
#endif
|
||||||
|
while (s->insert) {
|
||||||
|
UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
|
||||||
|
#ifndef FASTEST
|
||||||
|
s->prev[str & s->w_mask] = s->head[s->ins_h];
|
||||||
|
#endif
|
||||||
|
s->head[s->ins_h] = (Pos)str;
|
||||||
|
str++;
|
||||||
|
s->insert--;
|
||||||
|
if (s->lookahead + s->insert < MIN_MATCH)
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
|
/* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
|
||||||
* but this is not important since only literal bytes will be emitted.
|
* but this is not important since only literal bytes will be emitted.
|
||||||
|
@ -1427,6 +1526,9 @@ local void fill_window(s)
|
||||||
s->high_water += init;
|
s->high_water += init;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
|
||||||
|
"not enough room for search");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
|
@ -1506,8 +1608,14 @@ local block_state deflate_stored(s, flush)
|
||||||
FLUSH_BLOCK(s, 0);
|
FLUSH_BLOCK(s, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FLUSH_BLOCK(s, flush == Z_FINISH);
|
s->insert = 0;
|
||||||
return flush == Z_FINISH ? finish_done : block_done;
|
if (flush == Z_FINISH) {
|
||||||
|
FLUSH_BLOCK(s, 1);
|
||||||
|
return finish_done;
|
||||||
|
}
|
||||||
|
if ((long)s->strstart > s->block_start)
|
||||||
|
FLUSH_BLOCK(s, 0);
|
||||||
|
return block_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
|
@ -1603,8 +1711,14 @@ local block_state deflate_fast(s, flush)
|
||||||
}
|
}
|
||||||
if (bflush) FLUSH_BLOCK(s, 0);
|
if (bflush) FLUSH_BLOCK(s, 0);
|
||||||
}
|
}
|
||||||
FLUSH_BLOCK(s, flush == Z_FINISH);
|
s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
|
||||||
return flush == Z_FINISH ? finish_done : block_done;
|
if (flush == Z_FINISH) {
|
||||||
|
FLUSH_BLOCK(s, 1);
|
||||||
|
return finish_done;
|
||||||
|
}
|
||||||
|
if (s->last_lit)
|
||||||
|
FLUSH_BLOCK(s, 0);
|
||||||
|
return block_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef FASTEST
|
#ifndef FASTEST
|
||||||
|
@ -1728,8 +1842,14 @@ local block_state deflate_slow(s, flush)
|
||||||
_tr_tally_lit(s, s->window[s->strstart-1], bflush);
|
_tr_tally_lit(s, s->window[s->strstart-1], bflush);
|
||||||
s->match_available = 0;
|
s->match_available = 0;
|
||||||
}
|
}
|
||||||
FLUSH_BLOCK(s, flush == Z_FINISH);
|
s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
|
||||||
return flush == Z_FINISH ? finish_done : block_done;
|
if (flush == Z_FINISH) {
|
||||||
|
FLUSH_BLOCK(s, 1);
|
||||||
|
return finish_done;
|
||||||
|
}
|
||||||
|
if (s->last_lit)
|
||||||
|
FLUSH_BLOCK(s, 0);
|
||||||
|
return block_done;
|
||||||
}
|
}
|
||||||
#endif /* FASTEST */
|
#endif /* FASTEST */
|
||||||
|
|
||||||
|
@ -1749,11 +1869,11 @@ local block_state deflate_rle(s, flush)
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* Make sure that we always have enough lookahead, except
|
/* Make sure that we always have enough lookahead, except
|
||||||
* at the end of the input file. We need MAX_MATCH bytes
|
* at the end of the input file. We need MAX_MATCH bytes
|
||||||
* for the longest encodable run.
|
* for the longest run, plus one for the unrolled loop.
|
||||||
*/
|
*/
|
||||||
if (s->lookahead < MAX_MATCH) {
|
if (s->lookahead <= MAX_MATCH) {
|
||||||
fill_window(s);
|
fill_window(s);
|
||||||
if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) {
|
if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) {
|
||||||
return need_more;
|
return need_more;
|
||||||
}
|
}
|
||||||
if (s->lookahead == 0) break; /* flush the current block */
|
if (s->lookahead == 0) break; /* flush the current block */
|
||||||
|
@ -1776,6 +1896,7 @@ local block_state deflate_rle(s, flush)
|
||||||
if (s->match_length > s->lookahead)
|
if (s->match_length > s->lookahead)
|
||||||
s->match_length = s->lookahead;
|
s->match_length = s->lookahead;
|
||||||
}
|
}
|
||||||
|
Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Emit match if have run of MIN_MATCH or longer, else emit literal */
|
/* Emit match if have run of MIN_MATCH or longer, else emit literal */
|
||||||
|
@ -1796,8 +1917,14 @@ local block_state deflate_rle(s, flush)
|
||||||
}
|
}
|
||||||
if (bflush) FLUSH_BLOCK(s, 0);
|
if (bflush) FLUSH_BLOCK(s, 0);
|
||||||
}
|
}
|
||||||
FLUSH_BLOCK(s, flush == Z_FINISH);
|
s->insert = 0;
|
||||||
return flush == Z_FINISH ? finish_done : block_done;
|
if (flush == Z_FINISH) {
|
||||||
|
FLUSH_BLOCK(s, 1);
|
||||||
|
return finish_done;
|
||||||
|
}
|
||||||
|
if (s->last_lit)
|
||||||
|
FLUSH_BLOCK(s, 0);
|
||||||
|
return block_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
|
@ -1829,6 +1956,12 @@ local block_state deflate_huff(s, flush)
|
||||||
s->strstart++;
|
s->strstart++;
|
||||||
if (bflush) FLUSH_BLOCK(s, 0);
|
if (bflush) FLUSH_BLOCK(s, 0);
|
||||||
}
|
}
|
||||||
FLUSH_BLOCK(s, flush == Z_FINISH);
|
s->insert = 0;
|
||||||
return flush == Z_FINISH ? finish_done : block_done;
|
if (flush == Z_FINISH) {
|
||||||
|
FLUSH_BLOCK(s, 1);
|
||||||
|
return finish_done;
|
||||||
|
}
|
||||||
|
if (s->last_lit)
|
||||||
|
FLUSH_BLOCK(s, 0);
|
||||||
|
return block_done;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* deflate.h -- internal compression state
|
/* deflate.h -- internal compression state
|
||||||
* Copyright (C) 1995-2010 Jean-loup Gailly
|
* Copyright (C) 1995-2012 Jean-loup Gailly
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -48,6 +48,9 @@
|
||||||
#define MAX_BITS 15
|
#define MAX_BITS 15
|
||||||
/* All codes must not exceed MAX_BITS bits */
|
/* All codes must not exceed MAX_BITS bits */
|
||||||
|
|
||||||
|
#define Buf_size 16
|
||||||
|
/* size of bit buffer in bi_buf */
|
||||||
|
|
||||||
#define INIT_STATE 42
|
#define INIT_STATE 42
|
||||||
#define EXTRA_STATE 69
|
#define EXTRA_STATE 69
|
||||||
#define NAME_STATE 73
|
#define NAME_STATE 73
|
||||||
|
@ -101,7 +104,7 @@ typedef struct internal_state {
|
||||||
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
|
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
|
||||||
gz_headerp gzhead; /* gzip header information to write */
|
gz_headerp gzhead; /* gzip header information to write */
|
||||||
uInt gzindex; /* where in extra, name, or comment */
|
uInt gzindex; /* where in extra, name, or comment */
|
||||||
Byte method; /* STORED (for zip only) or DEFLATED */
|
Byte method; /* can only be DEFLATED */
|
||||||
int last_flush; /* value of flush param for previous deflate call */
|
int last_flush; /* value of flush param for previous deflate call */
|
||||||
|
|
||||||
/* used by deflate.c: */
|
/* used by deflate.c: */
|
||||||
|
@ -188,7 +191,7 @@ typedef struct internal_state {
|
||||||
int nice_match; /* Stop searching when current match exceeds this */
|
int nice_match; /* Stop searching when current match exceeds this */
|
||||||
|
|
||||||
/* used by trees.c: */
|
/* used by trees.c: */
|
||||||
/* Didn't use ct_data typedef below to supress compiler warning */
|
/* Didn't use ct_data typedef below to suppress compiler warning */
|
||||||
struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
|
struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
|
||||||
struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
|
struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
|
||||||
struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
|
struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
|
||||||
|
@ -244,7 +247,7 @@ typedef struct internal_state {
|
||||||
ulg opt_len; /* bit length of current block with optimal trees */
|
ulg opt_len; /* bit length of current block with optimal trees */
|
||||||
ulg static_len; /* bit length of current block with static trees */
|
ulg static_len; /* bit length of current block with static trees */
|
||||||
uInt matches; /* number of string matches in current block */
|
uInt matches; /* number of string matches in current block */
|
||||||
int last_eob_len; /* bit length of EOB code for last block */
|
uInt insert; /* bytes at end of window left to insert */
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
ulg compressed_len; /* total bit length of compressed file mod 2^32 */
|
ulg compressed_len; /* total bit length of compressed file mod 2^32 */
|
||||||
|
@ -294,6 +297,7 @@ void ZLIB_INTERNAL _tr_init OF((deflate_state *s));
|
||||||
int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
|
int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
|
||||||
void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf,
|
void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf,
|
||||||
ulg stored_len, int last));
|
ulg stored_len, int last));
|
||||||
|
void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s));
|
||||||
void ZLIB_INTERNAL _tr_align OF((deflate_state *s));
|
void ZLIB_INTERNAL _tr_align OF((deflate_state *s));
|
||||||
void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
|
void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
|
||||||
ulg stored_len, int last));
|
ulg stored_len, int last));
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
/* gzclose.c -- zlib gzclose() function
|
||||||
|
* Copyright (C) 2004, 2010 Mark Adler
|
||||||
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gzguts.h"
|
||||||
|
|
||||||
|
/* gzclose() is in a separate file so that it is linked in only if it is used.
|
||||||
|
That way the other gzclose functions can be used instead to avoid linking in
|
||||||
|
unneeded compression or decompression routines. */
|
||||||
|
int ZEXPORT gzclose(file)
|
||||||
|
gzFile file;
|
||||||
|
{
|
||||||
|
#ifndef NO_GZCOMPRESS
|
||||||
|
gz_statep state;
|
||||||
|
|
||||||
|
if (file == NULL)
|
||||||
|
return Z_STREAM_ERROR;
|
||||||
|
state = (gz_statep)file;
|
||||||
|
|
||||||
|
return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file);
|
||||||
|
#else
|
||||||
|
return gzclose_r(file);
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,209 @@
|
||||||
|
/* gzguts.h -- zlib internal header definitions for gz* operations
|
||||||
|
* Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler
|
||||||
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef _LARGEFILE64_SOURCE
|
||||||
|
# ifndef _LARGEFILE_SOURCE
|
||||||
|
# define _LARGEFILE_SOURCE 1
|
||||||
|
# endif
|
||||||
|
# ifdef _FILE_OFFSET_BITS
|
||||||
|
# undef _FILE_OFFSET_BITS
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_HIDDEN
|
||||||
|
# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
|
||||||
|
#else
|
||||||
|
# define ZLIB_INTERNAL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "zlib.h"
|
||||||
|
#ifdef STDC
|
||||||
|
# include <string.h>
|
||||||
|
# include <stdlib.h>
|
||||||
|
# include <limits.h>
|
||||||
|
#endif
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
# include <stddef.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32)
|
||||||
|
# include <io.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WINAPI_FAMILY
|
||||||
|
# define open _open
|
||||||
|
# define read _read
|
||||||
|
# define write _write
|
||||||
|
# define close _close
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NO_DEFLATE /* for compatibility with old definition */
|
||||||
|
# define NO_GZCOMPRESS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
|
||||||
|
# ifndef HAVE_VSNPRINTF
|
||||||
|
# define HAVE_VSNPRINTF
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__CYGWIN__)
|
||||||
|
# ifndef HAVE_VSNPRINTF
|
||||||
|
# define HAVE_VSNPRINTF
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410)
|
||||||
|
# ifndef HAVE_VSNPRINTF
|
||||||
|
# define HAVE_VSNPRINTF
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_VSNPRINTF
|
||||||
|
# ifdef MSDOS
|
||||||
|
/* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
|
||||||
|
but for now we just assume it doesn't. */
|
||||||
|
# define NO_vsnprintf
|
||||||
|
# endif
|
||||||
|
# ifdef __TURBOC__
|
||||||
|
# define NO_vsnprintf
|
||||||
|
# endif
|
||||||
|
# ifdef WIN32
|
||||||
|
/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
|
||||||
|
# if !defined(vsnprintf) && !defined(NO_vsnprintf)
|
||||||
|
# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )
|
||||||
|
# define vsnprintf _vsnprintf
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# ifdef __SASC
|
||||||
|
# define NO_vsnprintf
|
||||||
|
# endif
|
||||||
|
# ifdef VMS
|
||||||
|
# define NO_vsnprintf
|
||||||
|
# endif
|
||||||
|
# ifdef __OS400__
|
||||||
|
# define NO_vsnprintf
|
||||||
|
# endif
|
||||||
|
# ifdef __MVS__
|
||||||
|
# define NO_vsnprintf
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* unlike snprintf (which is required in C99, yet still not supported by
|
||||||
|
Microsoft more than a decade later!), _snprintf does not guarantee null
|
||||||
|
termination of the result -- however this is only used in gzlib.c where
|
||||||
|
the result is assured to fit in the space provided */
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# define snprintf _snprintf
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef local
|
||||||
|
# define local static
|
||||||
|
#endif
|
||||||
|
/* compile with -Dlocal if your debugger can't find static symbols */
|
||||||
|
|
||||||
|
/* gz* functions always use library allocation functions */
|
||||||
|
#ifndef STDC
|
||||||
|
extern voidp malloc OF((uInt size));
|
||||||
|
extern void free OF((voidpf ptr));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* get errno and strerror definition */
|
||||||
|
#if defined UNDER_CE
|
||||||
|
# include <windows.h>
|
||||||
|
# define zstrerror() gz_strwinerror((DWORD)GetLastError())
|
||||||
|
#else
|
||||||
|
# ifndef NO_STRERROR
|
||||||
|
# include <errno.h>
|
||||||
|
# define zstrerror() strerror(errno)
|
||||||
|
# else
|
||||||
|
# define zstrerror() "stdio error (consult errno)"
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* provide prototypes for these when building zlib without LFS */
|
||||||
|
#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0
|
||||||
|
ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
|
||||||
|
ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
|
||||||
|
ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
|
||||||
|
ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* default memLevel */
|
||||||
|
#if MAX_MEM_LEVEL >= 8
|
||||||
|
# define DEF_MEM_LEVEL 8
|
||||||
|
#else
|
||||||
|
# define DEF_MEM_LEVEL MAX_MEM_LEVEL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* default i/o buffer size -- double this for output when reading (this and
|
||||||
|
twice this must be able to fit in an unsigned type) */
|
||||||
|
#define GZBUFSIZE 8192
|
||||||
|
|
||||||
|
/* gzip modes, also provide a little integrity check on the passed structure */
|
||||||
|
#define GZ_NONE 0
|
||||||
|
#define GZ_READ 7247
|
||||||
|
#define GZ_WRITE 31153
|
||||||
|
#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */
|
||||||
|
|
||||||
|
/* values for gz_state how */
|
||||||
|
#define LOOK 0 /* look for a gzip header */
|
||||||
|
#define COPY 1 /* copy input directly */
|
||||||
|
#define GZIP 2 /* decompress a gzip stream */
|
||||||
|
|
||||||
|
/* internal gzip file state data structure */
|
||||||
|
typedef struct {
|
||||||
|
/* exposed contents for gzgetc() macro */
|
||||||
|
struct gzFile_s x; /* "x" for exposed */
|
||||||
|
/* x.have: number of bytes available at x.next */
|
||||||
|
/* x.next: next output data to deliver or write */
|
||||||
|
/* x.pos: current position in uncompressed data */
|
||||||
|
/* used for both reading and writing */
|
||||||
|
int mode; /* see gzip modes above */
|
||||||
|
int fd; /* file descriptor */
|
||||||
|
char *path; /* path or fd for error messages */
|
||||||
|
unsigned size; /* buffer size, zero if not allocated yet */
|
||||||
|
unsigned want; /* requested buffer size, default is GZBUFSIZE */
|
||||||
|
unsigned char *in; /* input buffer */
|
||||||
|
unsigned char *out; /* output buffer (double-sized when reading) */
|
||||||
|
int direct; /* 0 if processing gzip, 1 if transparent */
|
||||||
|
/* just for reading */
|
||||||
|
int how; /* 0: get header, 1: copy, 2: decompress */
|
||||||
|
z_off64_t start; /* where the gzip data started, for rewinding */
|
||||||
|
int eof; /* true if end of input file reached */
|
||||||
|
int past; /* true if read requested past end */
|
||||||
|
/* just for writing */
|
||||||
|
int level; /* compression level */
|
||||||
|
int strategy; /* compression strategy */
|
||||||
|
/* seek request */
|
||||||
|
z_off64_t skip; /* amount to skip (already rewound if backwards) */
|
||||||
|
int seek; /* true if seek request pending */
|
||||||
|
/* error information */
|
||||||
|
int err; /* error code */
|
||||||
|
char *msg; /* error message */
|
||||||
|
/* zlib inflate or deflate stream */
|
||||||
|
z_stream strm; /* stream structure in-place (not a pointer) */
|
||||||
|
} gz_state;
|
||||||
|
typedef gz_state FAR *gz_statep;
|
||||||
|
|
||||||
|
/* shared functions */
|
||||||
|
void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *));
|
||||||
|
#if defined UNDER_CE
|
||||||
|
char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t
|
||||||
|
value -- needed when comparing unsigned to z_off64_t, which is signed
|
||||||
|
(possible z_off64_t types off_t, off64_t, and long are all signed) */
|
||||||
|
#ifdef INT_MAX
|
||||||
|
# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX)
|
||||||
|
#else
|
||||||
|
unsigned ZLIB_INTERNAL gz_intmax OF((void));
|
||||||
|
# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())
|
||||||
|
#endif
|
|
@ -0,0 +1,634 @@
|
||||||
|
/* gzlib.c -- zlib functions common to reading and writing gzip files
|
||||||
|
* Copyright (C) 2004, 2010, 2011, 2012, 2013 Mark Adler
|
||||||
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gzguts.h"
|
||||||
|
|
||||||
|
#if defined(_WIN32) && !defined(__BORLANDC__)
|
||||||
|
# define LSEEK _lseeki64
|
||||||
|
#else
|
||||||
|
#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
|
||||||
|
# define LSEEK lseek64
|
||||||
|
#else
|
||||||
|
# define LSEEK lseek
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Local functions */
|
||||||
|
local void gz_reset OF((gz_statep));
|
||||||
|
local gzFile gz_open OF((const void *, int, const char *));
|
||||||
|
|
||||||
|
#if defined UNDER_CE
|
||||||
|
|
||||||
|
/* Map the Windows error number in ERROR to a locale-dependent error message
|
||||||
|
string and return a pointer to it. Typically, the values for ERROR come
|
||||||
|
from GetLastError.
|
||||||
|
|
||||||
|
The string pointed to shall not be modified by the application, but may be
|
||||||
|
overwritten by a subsequent call to gz_strwinerror
|
||||||
|
|
||||||
|
The gz_strwinerror function does not change the current setting of
|
||||||
|
GetLastError. */
|
||||||
|
char ZLIB_INTERNAL *gz_strwinerror (error)
|
||||||
|
DWORD error;
|
||||||
|
{
|
||||||
|
static char buf[1024];
|
||||||
|
|
||||||
|
wchar_t *msgbuf;
|
||||||
|
DWORD lasterr = GetLastError();
|
||||||
|
DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
|
||||||
|
| FORMAT_MESSAGE_ALLOCATE_BUFFER,
|
||||||
|
NULL,
|
||||||
|
error,
|
||||||
|
0, /* Default language */
|
||||||
|
(LPVOID)&msgbuf,
|
||||||
|
0,
|
||||||
|
NULL);
|
||||||
|
if (chars != 0) {
|
||||||
|
/* If there is an \r\n appended, zap it. */
|
||||||
|
if (chars >= 2
|
||||||
|
&& msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
|
||||||
|
chars -= 2;
|
||||||
|
msgbuf[chars] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chars > sizeof (buf) - 1) {
|
||||||
|
chars = sizeof (buf) - 1;
|
||||||
|
msgbuf[chars] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
wcstombs(buf, msgbuf, chars + 1);
|
||||||
|
LocalFree(msgbuf);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sprintf(buf, "unknown win32 error (%ld)", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetLastError(lasterr);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* UNDER_CE */
|
||||||
|
|
||||||
|
/* Reset gzip file state */
|
||||||
|
local void gz_reset(state)
|
||||||
|
gz_statep state;
|
||||||
|
{
|
||||||
|
state->x.have = 0; /* no output data available */
|
||||||
|
if (state->mode == GZ_READ) { /* for reading ... */
|
||||||
|
state->eof = 0; /* not at end of file */
|
||||||
|
state->past = 0; /* have not read past end yet */
|
||||||
|
state->how = LOOK; /* look for gzip header */
|
||||||
|
}
|
||||||
|
state->seek = 0; /* no seek request pending */
|
||||||
|
gz_error(state, Z_OK, NULL); /* clear error */
|
||||||
|
state->x.pos = 0; /* no uncompressed data yet */
|
||||||
|
state->strm.avail_in = 0; /* no input data yet */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open a gzip file either by name or file descriptor. */
|
||||||
|
local gzFile gz_open(path, fd, mode)
|
||||||
|
const void *path;
|
||||||
|
int fd;
|
||||||
|
const char *mode;
|
||||||
|
{
|
||||||
|
gz_statep state;
|
||||||
|
size_t len;
|
||||||
|
int oflag;
|
||||||
|
#ifdef O_CLOEXEC
|
||||||
|
int cloexec = 0;
|
||||||
|
#endif
|
||||||
|
#ifdef O_EXCL
|
||||||
|
int exclusive = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* check input */
|
||||||
|
if (path == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* allocate gzFile structure to return */
|
||||||
|
state = (gz_statep)malloc(sizeof(gz_state));
|
||||||
|
if (state == NULL)
|
||||||
|
return NULL;
|
||||||
|
state->size = 0; /* no buffers allocated yet */
|
||||||
|
state->want = GZBUFSIZE; /* requested buffer size */
|
||||||
|
state->msg = NULL; /* no error message yet */
|
||||||
|
|
||||||
|
/* interpret mode */
|
||||||
|
state->mode = GZ_NONE;
|
||||||
|
state->level = Z_DEFAULT_COMPRESSION;
|
||||||
|
state->strategy = Z_DEFAULT_STRATEGY;
|
||||||
|
state->direct = 0;
|
||||||
|
while (*mode) {
|
||||||
|
if (*mode >= '0' && *mode <= '9')
|
||||||
|
state->level = *mode - '0';
|
||||||
|
else
|
||||||
|
switch (*mode) {
|
||||||
|
case 'r':
|
||||||
|
state->mode = GZ_READ;
|
||||||
|
break;
|
||||||
|
#ifndef NO_GZCOMPRESS
|
||||||
|
case 'w':
|
||||||
|
state->mode = GZ_WRITE;
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
state->mode = GZ_APPEND;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case '+': /* can't read and write at the same time */
|
||||||
|
free(state);
|
||||||
|
return NULL;
|
||||||
|
case 'b': /* ignore -- will request binary anyway */
|
||||||
|
break;
|
||||||
|
#ifdef O_CLOEXEC
|
||||||
|
case 'e':
|
||||||
|
cloexec = 1;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef O_EXCL
|
||||||
|
case 'x':
|
||||||
|
exclusive = 1;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case 'f':
|
||||||
|
state->strategy = Z_FILTERED;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
state->strategy = Z_HUFFMAN_ONLY;
|
||||||
|
break;
|
||||||
|
case 'R':
|
||||||
|
state->strategy = Z_RLE;
|
||||||
|
break;
|
||||||
|
case 'F':
|
||||||
|
state->strategy = Z_FIXED;
|
||||||
|
break;
|
||||||
|
case 'T':
|
||||||
|
state->direct = 1;
|
||||||
|
break;
|
||||||
|
default: /* could consider as an error, but just ignore */
|
||||||
|
;
|
||||||
|
}
|
||||||
|
mode++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* must provide an "r", "w", or "a" */
|
||||||
|
if (state->mode == GZ_NONE) {
|
||||||
|
free(state);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* can't force transparent read */
|
||||||
|
if (state->mode == GZ_READ) {
|
||||||
|
if (state->direct) {
|
||||||
|
free(state);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
state->direct = 1; /* for empty file */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* save the path name for error messages */
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (fd == -2) {
|
||||||
|
len = wcstombs(NULL, path, 0);
|
||||||
|
if (len == (size_t)-1)
|
||||||
|
len = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
len = strlen((const char *)path);
|
||||||
|
state->path = (char *)malloc(len + 1);
|
||||||
|
if (state->path == NULL) {
|
||||||
|
free(state);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (fd == -2)
|
||||||
|
if (len)
|
||||||
|
wcstombs(state->path, path, len + 1);
|
||||||
|
else
|
||||||
|
*(state->path) = 0;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
|
||||||
|
snprintf(state->path, len + 1, "%s", (const char *)path);
|
||||||
|
#else
|
||||||
|
strcpy(state->path, path);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* compute the flags for open() */
|
||||||
|
oflag =
|
||||||
|
#ifdef O_LARGEFILE
|
||||||
|
O_LARGEFILE |
|
||||||
|
#endif
|
||||||
|
#ifdef O_BINARY
|
||||||
|
O_BINARY |
|
||||||
|
#endif
|
||||||
|
#ifdef O_CLOEXEC
|
||||||
|
(cloexec ? O_CLOEXEC : 0) |
|
||||||
|
#endif
|
||||||
|
(state->mode == GZ_READ ?
|
||||||
|
O_RDONLY :
|
||||||
|
(O_WRONLY | O_CREAT |
|
||||||
|
#ifdef O_EXCL
|
||||||
|
(exclusive ? O_EXCL : 0) |
|
||||||
|
#endif
|
||||||
|
(state->mode == GZ_WRITE ?
|
||||||
|
O_TRUNC :
|
||||||
|
O_APPEND)));
|
||||||
|
|
||||||
|
/* open the file with the appropriate flags (or just use fd) */
|
||||||
|
state->fd = fd > -1 ? fd : (
|
||||||
|
#ifdef _WIN32
|
||||||
|
fd == -2 ? _wopen(path, oflag, 0666) :
|
||||||
|
#endif
|
||||||
|
open((const char *)path, oflag, 0666));
|
||||||
|
if (state->fd == -1) {
|
||||||
|
free(state->path);
|
||||||
|
free(state);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (state->mode == GZ_APPEND)
|
||||||
|
state->mode = GZ_WRITE; /* simplify later checks */
|
||||||
|
|
||||||
|
/* save the current position for rewinding (only if reading) */
|
||||||
|
if (state->mode == GZ_READ) {
|
||||||
|
state->start = LSEEK(state->fd, 0, SEEK_CUR);
|
||||||
|
if (state->start == -1) state->start = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initialize stream */
|
||||||
|
gz_reset(state);
|
||||||
|
|
||||||
|
/* return stream */
|
||||||
|
return (gzFile)state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
gzFile ZEXPORT gzopen(path, mode)
|
||||||
|
const char *path;
|
||||||
|
const char *mode;
|
||||||
|
{
|
||||||
|
return gz_open(path, -1, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
gzFile ZEXPORT gzopen64(path, mode)
|
||||||
|
const char *path;
|
||||||
|
const char *mode;
|
||||||
|
{
|
||||||
|
return gz_open(path, -1, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
gzFile ZEXPORT gzdopen(fd, mode)
|
||||||
|
int fd;
|
||||||
|
const char *mode;
|
||||||
|
{
|
||||||
|
char *path; /* identifier for error messages */
|
||||||
|
gzFile gz;
|
||||||
|
|
||||||
|
if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL)
|
||||||
|
return NULL;
|
||||||
|
#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
|
||||||
|
snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd); /* for debugging */
|
||||||
|
#else
|
||||||
|
sprintf(path, "<fd:%d>", fd); /* for debugging */
|
||||||
|
#endif
|
||||||
|
gz = gz_open(path, fd, mode);
|
||||||
|
free(path);
|
||||||
|
return gz;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
#ifdef _WIN32
|
||||||
|
gzFile ZEXPORT gzopen_w(path, mode)
|
||||||
|
const wchar_t *path;
|
||||||
|
const char *mode;
|
||||||
|
{
|
||||||
|
return gz_open(path, -2, mode);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
int ZEXPORT gzbuffer(file, size)
|
||||||
|
gzFile file;
|
||||||
|
unsigned size;
|
||||||
|
{
|
||||||
|
gz_statep state;
|
||||||
|
|
||||||
|
/* get internal structure and check integrity */
|
||||||
|
if (file == NULL)
|
||||||
|
return -1;
|
||||||
|
state = (gz_statep)file;
|
||||||
|
if (state->mode != GZ_READ && state->mode != GZ_WRITE)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* make sure we haven't already allocated memory */
|
||||||
|
if (state->size != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* check and set requested size */
|
||||||
|
if (size < 2)
|
||||||
|
size = 2; /* need two bytes to check magic header */
|
||||||
|
state->want = size;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
int ZEXPORT gzrewind(file)
|
||||||
|
gzFile file;
|
||||||
|
{
|
||||||
|
gz_statep state;
|
||||||
|
|
||||||
|
/* get internal structure */
|
||||||
|
if (file == NULL)
|
||||||
|
return -1;
|
||||||
|
state = (gz_statep)file;
|
||||||
|
|
||||||
|
/* check that we're reading and that there's no error */
|
||||||
|
if (state->mode != GZ_READ ||
|
||||||
|
(state->err != Z_OK && state->err != Z_BUF_ERROR))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* back up and start over */
|
||||||
|
if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
|
||||||
|
return -1;
|
||||||
|
gz_reset(state);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
z_off64_t ZEXPORT gzseek64(file, offset, whence)
|
||||||
|
gzFile file;
|
||||||
|
z_off64_t offset;
|
||||||
|
int whence;
|
||||||
|
{
|
||||||
|
unsigned n;
|
||||||
|
z_off64_t ret;
|
||||||
|
gz_statep state;
|
||||||
|
|
||||||
|
/* get internal structure and check integrity */
|
||||||
|
if (file == NULL)
|
||||||
|
return -1;
|
||||||
|
state = (gz_statep)file;
|
||||||
|
if (state->mode != GZ_READ && state->mode != GZ_WRITE)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* check that there's no error */
|
||||||
|
if (state->err != Z_OK && state->err != Z_BUF_ERROR)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* can only seek from start or relative to current position */
|
||||||
|
if (whence != SEEK_SET && whence != SEEK_CUR)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* normalize offset to a SEEK_CUR specification */
|
||||||
|
if (whence == SEEK_SET)
|
||||||
|
offset -= state->x.pos;
|
||||||
|
else if (state->seek)
|
||||||
|
offset += state->skip;
|
||||||
|
state->seek = 0;
|
||||||
|
|
||||||
|
/* if within raw area while reading, just go there */
|
||||||
|
if (state->mode == GZ_READ && state->how == COPY &&
|
||||||
|
state->x.pos + offset >= 0) {
|
||||||
|
ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR);
|
||||||
|
if (ret == -1)
|
||||||
|
return -1;
|
||||||
|
state->x.have = 0;
|
||||||
|
state->eof = 0;
|
||||||
|
state->past = 0;
|
||||||
|
state->seek = 0;
|
||||||
|
gz_error(state, Z_OK, NULL);
|
||||||
|
state->strm.avail_in = 0;
|
||||||
|
state->x.pos += offset;
|
||||||
|
return state->x.pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate skip amount, rewinding if needed for back seek when reading */
|
||||||
|
if (offset < 0) {
|
||||||
|
if (state->mode != GZ_READ) /* writing -- can't go backwards */
|
||||||
|
return -1;
|
||||||
|
offset += state->x.pos;
|
||||||
|
if (offset < 0) /* before start of file! */
|
||||||
|
return -1;
|
||||||
|
if (gzrewind(file) == -1) /* rewind, then skip to offset */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if reading, skip what's in output buffer (one less gzgetc() check) */
|
||||||
|
if (state->mode == GZ_READ) {
|
||||||
|
n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ?
|
||||||
|
(unsigned)offset : state->x.have;
|
||||||
|
state->x.have -= n;
|
||||||
|
state->x.next += n;
|
||||||
|
state->x.pos += n;
|
||||||
|
offset -= n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* request skip (if not zero) */
|
||||||
|
if (offset) {
|
||||||
|
state->seek = 1;
|
||||||
|
state->skip = offset;
|
||||||
|
}
|
||||||
|
return state->x.pos + offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
z_off_t ZEXPORT gzseek(file, offset, whence)
|
||||||
|
gzFile file;
|
||||||
|
z_off_t offset;
|
||||||
|
int whence;
|
||||||
|
{
|
||||||
|
z_off64_t ret;
|
||||||
|
|
||||||
|
ret = gzseek64(file, (z_off64_t)offset, whence);
|
||||||
|
return ret == (z_off_t)ret ? (z_off_t)ret : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
z_off64_t ZEXPORT gztell64(file)
|
||||||
|
gzFile file;
|
||||||
|
{
|
||||||
|
gz_statep state;
|
||||||
|
|
||||||
|
/* get internal structure and check integrity */
|
||||||
|
if (file == NULL)
|
||||||
|
return -1;
|
||||||
|
state = (gz_statep)file;
|
||||||
|
if (state->mode != GZ_READ && state->mode != GZ_WRITE)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* return position */
|
||||||
|
return state->x.pos + (state->seek ? state->skip : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
z_off_t ZEXPORT gztell(file)
|
||||||
|
gzFile file;
|
||||||
|
{
|
||||||
|
z_off64_t ret;
|
||||||
|
|
||||||
|
ret = gztell64(file);
|
||||||
|
return ret == (z_off_t)ret ? (z_off_t)ret : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
z_off64_t ZEXPORT gzoffset64(file)
|
||||||
|
gzFile file;
|
||||||
|
{
|
||||||
|
z_off64_t offset;
|
||||||
|
gz_statep state;
|
||||||
|
|
||||||
|
/* get internal structure and check integrity */
|
||||||
|
if (file == NULL)
|
||||||
|
return -1;
|
||||||
|
state = (gz_statep)file;
|
||||||
|
if (state->mode != GZ_READ && state->mode != GZ_WRITE)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* compute and return effective offset in file */
|
||||||
|
offset = LSEEK(state->fd, 0, SEEK_CUR);
|
||||||
|
if (offset == -1)
|
||||||
|
return -1;
|
||||||
|
if (state->mode == GZ_READ) /* reading */
|
||||||
|
offset -= state->strm.avail_in; /* don't count buffered input */
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
z_off_t ZEXPORT gzoffset(file)
|
||||||
|
gzFile file;
|
||||||
|
{
|
||||||
|
z_off64_t ret;
|
||||||
|
|
||||||
|
ret = gzoffset64(file);
|
||||||
|
return ret == (z_off_t)ret ? (z_off_t)ret : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
int ZEXPORT gzeof(file)
|
||||||
|
gzFile file;
|
||||||
|
{
|
||||||
|
gz_statep state;
|
||||||
|
|
||||||
|
/* get internal structure and check integrity */
|
||||||
|
if (file == NULL)
|
||||||
|
return 0;
|
||||||
|
state = (gz_statep)file;
|
||||||
|
if (state->mode != GZ_READ && state->mode != GZ_WRITE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* return end-of-file state */
|
||||||
|
return state->mode == GZ_READ ? state->past : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
const char * ZEXPORT gzerror(file, errnum)
|
||||||
|
gzFile file;
|
||||||
|
int *errnum;
|
||||||
|
{
|
||||||
|
gz_statep state;
|
||||||
|
|
||||||
|
/* get internal structure and check integrity */
|
||||||
|
if (file == NULL)
|
||||||
|
return NULL;
|
||||||
|
state = (gz_statep)file;
|
||||||
|
if (state->mode != GZ_READ && state->mode != GZ_WRITE)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* return error information */
|
||||||
|
if (errnum != NULL)
|
||||||
|
*errnum = state->err;
|
||||||
|
return state->err == Z_MEM_ERROR ? "out of memory" :
|
||||||
|
(state->msg == NULL ? "" : state->msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
void ZEXPORT gzclearerr(file)
|
||||||
|
gzFile file;
|
||||||
|
{
|
||||||
|
gz_statep state;
|
||||||
|
|
||||||
|
/* get internal structure and check integrity */
|
||||||
|
if (file == NULL)
|
||||||
|
return;
|
||||||
|
state = (gz_statep)file;
|
||||||
|
if (state->mode != GZ_READ && state->mode != GZ_WRITE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* clear error and end-of-file */
|
||||||
|
if (state->mode == GZ_READ) {
|
||||||
|
state->eof = 0;
|
||||||
|
state->past = 0;
|
||||||
|
}
|
||||||
|
gz_error(state, Z_OK, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create an error message in allocated memory and set state->err and
|
||||||
|
state->msg accordingly. Free any previous error message already there. Do
|
||||||
|
not try to free or allocate space if the error is Z_MEM_ERROR (out of
|
||||||
|
memory). Simply save the error message as a static string. If there is an
|
||||||
|
allocation failure constructing the error message, then convert the error to
|
||||||
|
out of memory. */
|
||||||
|
void ZLIB_INTERNAL gz_error(state, err, msg)
|
||||||
|
gz_statep state;
|
||||||
|
int err;
|
||||||
|
const char *msg;
|
||||||
|
{
|
||||||
|
/* free previously allocated message and clear */
|
||||||
|
if (state->msg != NULL) {
|
||||||
|
if (state->err != Z_MEM_ERROR)
|
||||||
|
free(state->msg);
|
||||||
|
state->msg = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */
|
||||||
|
if (err != Z_OK && err != Z_BUF_ERROR)
|
||||||
|
state->x.have = 0;
|
||||||
|
|
||||||
|
/* set error code, and if no message, then done */
|
||||||
|
state->err = err;
|
||||||
|
if (msg == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* for an out of memory error, return literal string when requested */
|
||||||
|
if (err == Z_MEM_ERROR)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* construct error message with path */
|
||||||
|
if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) ==
|
||||||
|
NULL) {
|
||||||
|
state->err = Z_MEM_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
|
||||||
|
snprintf(state->msg, strlen(state->path) + strlen(msg) + 3,
|
||||||
|
"%s%s%s", state->path, ": ", msg);
|
||||||
|
#else
|
||||||
|
strcpy(state->msg, state->path);
|
||||||
|
strcat(state->msg, ": ");
|
||||||
|
strcat(state->msg, msg);
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef INT_MAX
|
||||||
|
/* portably return maximum value for an int (when limits.h presumed not
|
||||||
|
available) -- we need to do this to cover cases where 2's complement not
|
||||||
|
used, since C standard permits 1's complement and sign-bit representations,
|
||||||
|
otherwise we could just use ((unsigned)-1) >> 1 */
|
||||||
|
unsigned ZLIB_INTERNAL gz_intmax()
|
||||||
|
{
|
||||||
|
unsigned p, q;
|
||||||
|
|
||||||
|
p = 1;
|
||||||
|
do {
|
||||||
|
q = p;
|
||||||
|
p <<= 1;
|
||||||
|
p++;
|
||||||
|
} while (p > q);
|
||||||
|
return q >> 1;
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,594 @@
|
||||||
|
/* gzread.c -- zlib functions for reading gzip files
|
||||||
|
* Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler
|
||||||
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gzguts.h"
|
||||||
|
|
||||||
|
/* Local functions */
|
||||||
|
local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
|
||||||
|
local int gz_avail OF((gz_statep));
|
||||||
|
local int gz_look OF((gz_statep));
|
||||||
|
local int gz_decomp OF((gz_statep));
|
||||||
|
local int gz_fetch OF((gz_statep));
|
||||||
|
local int gz_skip OF((gz_statep, z_off64_t));
|
||||||
|
|
||||||
|
/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from
|
||||||
|
state->fd, and update state->eof, state->err, and state->msg as appropriate.
|
||||||
|
This function needs to loop on read(), since read() is not guaranteed to
|
||||||
|
read the number of bytes requested, depending on the type of descriptor. */
|
||||||
|
local int gz_load(state, buf, len, have)
|
||||||
|
gz_statep state;
|
||||||
|
unsigned char *buf;
|
||||||
|
unsigned len;
|
||||||
|
unsigned *have;
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
*have = 0;
|
||||||
|
do {
|
||||||
|
ret = read(state->fd, buf + *have, len - *have);
|
||||||
|
if (ret <= 0)
|
||||||
|
break;
|
||||||
|
*have += ret;
|
||||||
|
} while (*have < len);
|
||||||
|
if (ret < 0) {
|
||||||
|
gz_error(state, Z_ERRNO, zstrerror());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (ret == 0)
|
||||||
|
state->eof = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load up input buffer and set eof flag if last data loaded -- return -1 on
|
||||||
|
error, 0 otherwise. Note that the eof flag is set when the end of the input
|
||||||
|
file is reached, even though there may be unused data in the buffer. Once
|
||||||
|
that data has been used, no more attempts will be made to read the file.
|
||||||
|
If strm->avail_in != 0, then the current data is moved to the beginning of
|
||||||
|
the input buffer, and then the remainder of the buffer is loaded with the
|
||||||
|
available data from the input file. */
|
||||||
|
local int gz_avail(state)
|
||||||
|
gz_statep state;
|
||||||
|
{
|
||||||
|
unsigned got;
|
||||||
|
z_streamp strm = &(state->strm);
|
||||||
|
|
||||||
|
if (state->err != Z_OK && state->err != Z_BUF_ERROR)
|
||||||
|
return -1;
|
||||||
|
if (state->eof == 0) {
|
||||||
|
if (strm->avail_in) { /* copy what's there to the start */
|
||||||
|
unsigned char *p = state->in;
|
||||||
|
unsigned const char *q = strm->next_in;
|
||||||
|
unsigned n = strm->avail_in;
|
||||||
|
do {
|
||||||
|
*p++ = *q++;
|
||||||
|
} while (--n);
|
||||||
|
}
|
||||||
|
if (gz_load(state, state->in + strm->avail_in,
|
||||||
|
state->size - strm->avail_in, &got) == -1)
|
||||||
|
return -1;
|
||||||
|
strm->avail_in += got;
|
||||||
|
strm->next_in = state->in;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Look for gzip header, set up for inflate or copy. state->x.have must be 0.
|
||||||
|
If this is the first time in, allocate required memory. state->how will be
|
||||||
|
left unchanged if there is no more input data available, will be set to COPY
|
||||||
|
if there is no gzip header and direct copying will be performed, or it will
|
||||||
|
be set to GZIP for decompression. If direct copying, then leftover input
|
||||||
|
data from the input buffer will be copied to the output buffer. In that
|
||||||
|
case, all further file reads will be directly to either the output buffer or
|
||||||
|
a user buffer. If decompressing, the inflate state will be initialized.
|
||||||
|
gz_look() will return 0 on success or -1 on failure. */
|
||||||
|
local int gz_look(state)
|
||||||
|
gz_statep state;
|
||||||
|
{
|
||||||
|
z_streamp strm = &(state->strm);
|
||||||
|
|
||||||
|
/* allocate read buffers and inflate memory */
|
||||||
|
if (state->size == 0) {
|
||||||
|
/* allocate buffers */
|
||||||
|
state->in = (unsigned char *)malloc(state->want);
|
||||||
|
state->out = (unsigned char *)malloc(state->want << 1);
|
||||||
|
if (state->in == NULL || state->out == NULL) {
|
||||||
|
if (state->out != NULL)
|
||||||
|
free(state->out);
|
||||||
|
if (state->in != NULL)
|
||||||
|
free(state->in);
|
||||||
|
gz_error(state, Z_MEM_ERROR, "out of memory");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
state->size = state->want;
|
||||||
|
|
||||||
|
/* allocate inflate memory */
|
||||||
|
state->strm.zalloc = Z_NULL;
|
||||||
|
state->strm.zfree = Z_NULL;
|
||||||
|
state->strm.opaque = Z_NULL;
|
||||||
|
state->strm.avail_in = 0;
|
||||||
|
state->strm.next_in = Z_NULL;
|
||||||
|
if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */
|
||||||
|
free(state->out);
|
||||||
|
free(state->in);
|
||||||
|
state->size = 0;
|
||||||
|
gz_error(state, Z_MEM_ERROR, "out of memory");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get at least the magic bytes in the input buffer */
|
||||||
|
if (strm->avail_in < 2) {
|
||||||
|
if (gz_avail(state) == -1)
|
||||||
|
return -1;
|
||||||
|
if (strm->avail_in == 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* look for gzip magic bytes -- if there, do gzip decoding (note: there is
|
||||||
|
a logical dilemma here when considering the case of a partially written
|
||||||
|
gzip file, to wit, if a single 31 byte is written, then we cannot tell
|
||||||
|
whether this is a single-byte file, or just a partially written gzip
|
||||||
|
file -- for here we assume that if a gzip file is being written, then
|
||||||
|
the header will be written in a single operation, so that reading a
|
||||||
|
single byte is sufficient indication that it is not a gzip file) */
|
||||||
|
if (strm->avail_in > 1 &&
|
||||||
|
strm->next_in[0] == 31 && strm->next_in[1] == 139) {
|
||||||
|
inflateReset(strm);
|
||||||
|
state->how = GZIP;
|
||||||
|
state->direct = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no gzip header -- if we were decoding gzip before, then this is trailing
|
||||||
|
garbage. Ignore the trailing garbage and finish. */
|
||||||
|
if (state->direct == 0) {
|
||||||
|
strm->avail_in = 0;
|
||||||
|
state->eof = 1;
|
||||||
|
state->x.have = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* doing raw i/o, copy any leftover input to output -- this assumes that
|
||||||
|
the output buffer is larger than the input buffer, which also assures
|
||||||
|
space for gzungetc() */
|
||||||
|
state->x.next = state->out;
|
||||||
|
if (strm->avail_in) {
|
||||||
|
memcpy(state->x.next, strm->next_in, strm->avail_in);
|
||||||
|
state->x.have = strm->avail_in;
|
||||||
|
strm->avail_in = 0;
|
||||||
|
}
|
||||||
|
state->how = COPY;
|
||||||
|
state->direct = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decompress from input to the provided next_out and avail_out in the state.
|
||||||
|
On return, state->x.have and state->x.next point to the just decompressed
|
||||||
|
data. If the gzip stream completes, state->how is reset to LOOK to look for
|
||||||
|
the next gzip stream or raw data, once state->x.have is depleted. Returns 0
|
||||||
|
on success, -1 on failure. */
|
||||||
|
local int gz_decomp(state)
|
||||||
|
gz_statep state;
|
||||||
|
{
|
||||||
|
int ret = Z_OK;
|
||||||
|
unsigned had;
|
||||||
|
z_streamp strm = &(state->strm);
|
||||||
|
|
||||||
|
/* fill output buffer up to end of deflate stream */
|
||||||
|
had = strm->avail_out;
|
||||||
|
do {
|
||||||
|
/* get more input for inflate() */
|
||||||
|
if (strm->avail_in == 0 && gz_avail(state) == -1)
|
||||||
|
return -1;
|
||||||
|
if (strm->avail_in == 0) {
|
||||||
|
gz_error(state, Z_BUF_ERROR, "unexpected end of file");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* decompress and handle errors */
|
||||||
|
ret = inflate(strm, Z_NO_FLUSH);
|
||||||
|
if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
|
||||||
|
gz_error(state, Z_STREAM_ERROR,
|
||||||
|
"internal error: inflate stream corrupt");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (ret == Z_MEM_ERROR) {
|
||||||
|
gz_error(state, Z_MEM_ERROR, "out of memory");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (ret == Z_DATA_ERROR) { /* deflate stream invalid */
|
||||||
|
gz_error(state, Z_DATA_ERROR,
|
||||||
|
strm->msg == NULL ? "compressed data error" : strm->msg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} while (strm->avail_out && ret != Z_STREAM_END);
|
||||||
|
|
||||||
|
/* update available output */
|
||||||
|
state->x.have = had - strm->avail_out;
|
||||||
|
state->x.next = strm->next_out - state->x.have;
|
||||||
|
|
||||||
|
/* if the gzip stream completed successfully, look for another */
|
||||||
|
if (ret == Z_STREAM_END)
|
||||||
|
state->how = LOOK;
|
||||||
|
|
||||||
|
/* good decompression */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fetch data and put it in the output buffer. Assumes state->x.have is 0.
|
||||||
|
Data is either copied from the input file or decompressed from the input
|
||||||
|
file depending on state->how. If state->how is LOOK, then a gzip header is
|
||||||
|
looked for to determine whether to copy or decompress. Returns -1 on error,
|
||||||
|
otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the
|
||||||
|
end of the input file has been reached and all data has been processed. */
|
||||||
|
local int gz_fetch(state)
|
||||||
|
gz_statep state;
|
||||||
|
{
|
||||||
|
z_streamp strm = &(state->strm);
|
||||||
|
|
||||||
|
do {
|
||||||
|
switch(state->how) {
|
||||||
|
case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */
|
||||||
|
if (gz_look(state) == -1)
|
||||||
|
return -1;
|
||||||
|
if (state->how == LOOK)
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case COPY: /* -> COPY */
|
||||||
|
if (gz_load(state, state->out, state->size << 1, &(state->x.have))
|
||||||
|
== -1)
|
||||||
|
return -1;
|
||||||
|
state->x.next = state->out;
|
||||||
|
return 0;
|
||||||
|
case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */
|
||||||
|
strm->avail_out = state->size << 1;
|
||||||
|
strm->next_out = state->out;
|
||||||
|
if (gz_decomp(state) == -1)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} while (state->x.have == 0 && (!state->eof || strm->avail_in));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */
|
||||||
|
local int gz_skip(state, len)
|
||||||
|
gz_statep state;
|
||||||
|
z_off64_t len;
|
||||||
|
{
|
||||||
|
unsigned n;
|
||||||
|
|
||||||
|
/* skip over len bytes or reach end-of-file, whichever comes first */
|
||||||
|
while (len)
|
||||||
|
/* skip over whatever is in output buffer */
|
||||||
|
if (state->x.have) {
|
||||||
|
n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ?
|
||||||
|
(unsigned)len : state->x.have;
|
||||||
|
state->x.have -= n;
|
||||||
|
state->x.next += n;
|
||||||
|
state->x.pos += n;
|
||||||
|
len -= n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* output buffer empty -- return if we're at the end of the input */
|
||||||
|
else if (state->eof && state->strm.avail_in == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* need more data to skip -- load up output buffer */
|
||||||
|
else {
|
||||||
|
/* get more output, looking for header if required */
|
||||||
|
if (gz_fetch(state) == -1)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
int ZEXPORT gzread(file, buf, len)
|
||||||
|
gzFile file;
|
||||||
|
voidp buf;
|
||||||
|
unsigned len;
|
||||||
|
{
|
||||||
|
unsigned got, n;
|
||||||
|
gz_statep state;
|
||||||
|
z_streamp strm;
|
||||||
|
|
||||||
|
/* get internal structure */
|
||||||
|
if (file == NULL)
|
||||||
|
return -1;
|
||||||
|
state = (gz_statep)file;
|
||||||
|
strm = &(state->strm);
|
||||||
|
|
||||||
|
/* check that we're reading and that there's no (serious) error */
|
||||||
|
if (state->mode != GZ_READ ||
|
||||||
|
(state->err != Z_OK && state->err != Z_BUF_ERROR))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* since an int is returned, make sure len fits in one, otherwise return
|
||||||
|
with an error (this avoids the flaw in the interface) */
|
||||||
|
if ((int)len < 0) {
|
||||||
|
gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if len is zero, avoid unnecessary operations */
|
||||||
|
if (len == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* process a skip request */
|
||||||
|
if (state->seek) {
|
||||||
|
state->seek = 0;
|
||||||
|
if (gz_skip(state, state->skip) == -1)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get len bytes to buf, or less than len if at the end */
|
||||||
|
got = 0;
|
||||||
|
do {
|
||||||
|
/* first just try copying data from the output buffer */
|
||||||
|
if (state->x.have) {
|
||||||
|
n = state->x.have > len ? len : state->x.have;
|
||||||
|
memcpy(buf, state->x.next, n);
|
||||||
|
state->x.next += n;
|
||||||
|
state->x.have -= n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* output buffer empty -- return if we're at the end of the input */
|
||||||
|
else if (state->eof && strm->avail_in == 0) {
|
||||||
|
state->past = 1; /* tried to read past end */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* need output data -- for small len or new stream load up our output
|
||||||
|
buffer */
|
||||||
|
else if (state->how == LOOK || len < (state->size << 1)) {
|
||||||
|
/* get more output, looking for header if required */
|
||||||
|
if (gz_fetch(state) == -1)
|
||||||
|
return -1;
|
||||||
|
continue; /* no progress yet -- go back to copy above */
|
||||||
|
/* the copy above assures that we will leave with space in the
|
||||||
|
output buffer, allowing at least one gzungetc() to succeed */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* large len -- read directly into user buffer */
|
||||||
|
else if (state->how == COPY) { /* read directly */
|
||||||
|
if (gz_load(state, (unsigned char *)buf, len, &n) == -1)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* large len -- decompress directly into user buffer */
|
||||||
|
else { /* state->how == GZIP */
|
||||||
|
strm->avail_out = len;
|
||||||
|
strm->next_out = (unsigned char *)buf;
|
||||||
|
if (gz_decomp(state) == -1)
|
||||||
|
return -1;
|
||||||
|
n = state->x.have;
|
||||||
|
state->x.have = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* update progress */
|
||||||
|
len -= n;
|
||||||
|
buf = (char *)buf + n;
|
||||||
|
got += n;
|
||||||
|
state->x.pos += n;
|
||||||
|
} while (len);
|
||||||
|
|
||||||
|
/* return number of bytes read into user buffer (will fit in int) */
|
||||||
|
return (int)got;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
#ifdef Z_PREFIX_SET
|
||||||
|
# undef z_gzgetc
|
||||||
|
#else
|
||||||
|
# undef gzgetc
|
||||||
|
#endif
|
||||||
|
int ZEXPORT gzgetc(file)
|
||||||
|
gzFile file;
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
unsigned char buf[1];
|
||||||
|
gz_statep state;
|
||||||
|
|
||||||
|
/* get internal structure */
|
||||||
|
if (file == NULL)
|
||||||
|
return -1;
|
||||||
|
state = (gz_statep)file;
|
||||||
|
|
||||||
|
/* check that we're reading and that there's no (serious) error */
|
||||||
|
if (state->mode != GZ_READ ||
|
||||||
|
(state->err != Z_OK && state->err != Z_BUF_ERROR))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* try output buffer (no need to check for skip request) */
|
||||||
|
if (state->x.have) {
|
||||||
|
state->x.have--;
|
||||||
|
state->x.pos++;
|
||||||
|
return *(state->x.next)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* nothing there -- try gzread() */
|
||||||
|
ret = gzread(file, buf, 1);
|
||||||
|
return ret < 1 ? -1 : buf[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
int ZEXPORT gzgetc_(file)
|
||||||
|
gzFile file;
|
||||||
|
{
|
||||||
|
return gzgetc(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
int ZEXPORT gzungetc(c, file)
|
||||||
|
int c;
|
||||||
|
gzFile file;
|
||||||
|
{
|
||||||
|
gz_statep state;
|
||||||
|
|
||||||
|
/* get internal structure */
|
||||||
|
if (file == NULL)
|
||||||
|
return -1;
|
||||||
|
state = (gz_statep)file;
|
||||||
|
|
||||||
|
/* check that we're reading and that there's no (serious) error */
|
||||||
|
if (state->mode != GZ_READ ||
|
||||||
|
(state->err != Z_OK && state->err != Z_BUF_ERROR))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* process a skip request */
|
||||||
|
if (state->seek) {
|
||||||
|
state->seek = 0;
|
||||||
|
if (gz_skip(state, state->skip) == -1)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* can't push EOF */
|
||||||
|
if (c < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* if output buffer empty, put byte at end (allows more pushing) */
|
||||||
|
if (state->x.have == 0) {
|
||||||
|
state->x.have = 1;
|
||||||
|
state->x.next = state->out + (state->size << 1) - 1;
|
||||||
|
state->x.next[0] = c;
|
||||||
|
state->x.pos--;
|
||||||
|
state->past = 0;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if no room, give up (must have already done a gzungetc()) */
|
||||||
|
if (state->x.have == (state->size << 1)) {
|
||||||
|
gz_error(state, Z_DATA_ERROR, "out of room to push characters");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* slide output data if needed and insert byte before existing data */
|
||||||
|
if (state->x.next == state->out) {
|
||||||
|
unsigned char *src = state->out + state->x.have;
|
||||||
|
unsigned char *dest = state->out + (state->size << 1);
|
||||||
|
while (src > state->out)
|
||||||
|
*--dest = *--src;
|
||||||
|
state->x.next = dest;
|
||||||
|
}
|
||||||
|
state->x.have++;
|
||||||
|
state->x.next--;
|
||||||
|
state->x.next[0] = c;
|
||||||
|
state->x.pos--;
|
||||||
|
state->past = 0;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
char * ZEXPORT gzgets(file, buf, len)
|
||||||
|
gzFile file;
|
||||||
|
char *buf;
|
||||||
|
int len;
|
||||||
|
{
|
||||||
|
unsigned left, n;
|
||||||
|
char *str;
|
||||||
|
unsigned char *eol;
|
||||||
|
gz_statep state;
|
||||||
|
|
||||||
|
/* check parameters and get internal structure */
|
||||||
|
if (file == NULL || buf == NULL || len < 1)
|
||||||
|
return NULL;
|
||||||
|
state = (gz_statep)file;
|
||||||
|
|
||||||
|
/* check that we're reading and that there's no (serious) error */
|
||||||
|
if (state->mode != GZ_READ ||
|
||||||
|
(state->err != Z_OK && state->err != Z_BUF_ERROR))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* process a skip request */
|
||||||
|
if (state->seek) {
|
||||||
|
state->seek = 0;
|
||||||
|
if (gz_skip(state, state->skip) == -1)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy output bytes up to new line or len - 1, whichever comes first --
|
||||||
|
append a terminating zero to the string (we don't check for a zero in
|
||||||
|
the contents, let the user worry about that) */
|
||||||
|
str = buf;
|
||||||
|
left = (unsigned)len - 1;
|
||||||
|
if (left) do {
|
||||||
|
/* assure that something is in the output buffer */
|
||||||
|
if (state->x.have == 0 && gz_fetch(state) == -1)
|
||||||
|
return NULL; /* error */
|
||||||
|
if (state->x.have == 0) { /* end of file */
|
||||||
|
state->past = 1; /* read past end */
|
||||||
|
break; /* return what we have */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* look for end-of-line in current output buffer */
|
||||||
|
n = state->x.have > left ? left : state->x.have;
|
||||||
|
eol = (unsigned char *)memchr(state->x.next, '\n', n);
|
||||||
|
if (eol != NULL)
|
||||||
|
n = (unsigned)(eol - state->x.next) + 1;
|
||||||
|
|
||||||
|
/* copy through end-of-line, or remainder if not found */
|
||||||
|
memcpy(buf, state->x.next, n);
|
||||||
|
state->x.have -= n;
|
||||||
|
state->x.next += n;
|
||||||
|
state->x.pos += n;
|
||||||
|
left -= n;
|
||||||
|
buf += n;
|
||||||
|
} while (left && eol == NULL);
|
||||||
|
|
||||||
|
/* return terminated string, or if nothing, end of file */
|
||||||
|
if (buf == str)
|
||||||
|
return NULL;
|
||||||
|
buf[0] = 0;
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
int ZEXPORT gzdirect(file)
|
||||||
|
gzFile file;
|
||||||
|
{
|
||||||
|
gz_statep state;
|
||||||
|
|
||||||
|
/* get internal structure */
|
||||||
|
if (file == NULL)
|
||||||
|
return 0;
|
||||||
|
state = (gz_statep)file;
|
||||||
|
|
||||||
|
/* if the state is not known, but we can find out, then do so (this is
|
||||||
|
mainly for right after a gzopen() or gzdopen()) */
|
||||||
|
if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0)
|
||||||
|
(void)gz_look(state);
|
||||||
|
|
||||||
|
/* return 1 if transparent, 0 if processing a gzip stream */
|
||||||
|
return state->direct;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
int ZEXPORT gzclose_r(file)
|
||||||
|
gzFile file;
|
||||||
|
{
|
||||||
|
int ret, err;
|
||||||
|
gz_statep state;
|
||||||
|
|
||||||
|
/* get internal structure */
|
||||||
|
if (file == NULL)
|
||||||
|
return Z_STREAM_ERROR;
|
||||||
|
state = (gz_statep)file;
|
||||||
|
|
||||||
|
/* check that we're reading */
|
||||||
|
if (state->mode != GZ_READ)
|
||||||
|
return Z_STREAM_ERROR;
|
||||||
|
|
||||||
|
/* free memory and close file */
|
||||||
|
if (state->size) {
|
||||||
|
inflateEnd(&(state->strm));
|
||||||
|
free(state->out);
|
||||||
|
free(state->in);
|
||||||
|
}
|
||||||
|
err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK;
|
||||||
|
gz_error(state, Z_OK, NULL);
|
||||||
|
free(state->path);
|
||||||
|
ret = close(state->fd);
|
||||||
|
free(state);
|
||||||
|
return ret ? Z_ERRNO : err;
|
||||||
|
}
|
|
@ -0,0 +1,577 @@
|
||||||
|
/* gzwrite.c -- zlib functions for writing gzip files
|
||||||
|
* Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler
|
||||||
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gzguts.h"
|
||||||
|
|
||||||
|
/* Local functions */
|
||||||
|
local int gz_init OF((gz_statep));
|
||||||
|
local int gz_comp OF((gz_statep, int));
|
||||||
|
local int gz_zero OF((gz_statep, z_off64_t));
|
||||||
|
|
||||||
|
/* Initialize state for writing a gzip file. Mark initialization by setting
|
||||||
|
state->size to non-zero. Return -1 on failure or 0 on success. */
|
||||||
|
local int gz_init(state)
|
||||||
|
gz_statep state;
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
z_streamp strm = &(state->strm);
|
||||||
|
|
||||||
|
/* allocate input buffer */
|
||||||
|
state->in = (unsigned char *)malloc(state->want);
|
||||||
|
if (state->in == NULL) {
|
||||||
|
gz_error(state, Z_MEM_ERROR, "out of memory");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* only need output buffer and deflate state if compressing */
|
||||||
|
if (!state->direct) {
|
||||||
|
/* allocate output buffer */
|
||||||
|
state->out = (unsigned char *)malloc(state->want);
|
||||||
|
if (state->out == NULL) {
|
||||||
|
free(state->in);
|
||||||
|
gz_error(state, Z_MEM_ERROR, "out of memory");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate deflate memory, set up for gzip compression */
|
||||||
|
strm->zalloc = Z_NULL;
|
||||||
|
strm->zfree = Z_NULL;
|
||||||
|
strm->opaque = Z_NULL;
|
||||||
|
ret = deflateInit2(strm, state->level, Z_DEFLATED,
|
||||||
|
MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy);
|
||||||
|
if (ret != Z_OK) {
|
||||||
|
free(state->out);
|
||||||
|
free(state->in);
|
||||||
|
gz_error(state, Z_MEM_ERROR, "out of memory");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mark state as initialized */
|
||||||
|
state->size = state->want;
|
||||||
|
|
||||||
|
/* initialize write buffer if compressing */
|
||||||
|
if (!state->direct) {
|
||||||
|
strm->avail_out = state->size;
|
||||||
|
strm->next_out = state->out;
|
||||||
|
state->x.next = strm->next_out;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compress whatever is at avail_in and next_in and write to the output file.
|
||||||
|
Return -1 if there is an error writing to the output file, otherwise 0.
|
||||||
|
flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH,
|
||||||
|
then the deflate() state is reset to start a new gzip stream. If gz->direct
|
||||||
|
is true, then simply write to the output file without compressing, and
|
||||||
|
ignore flush. */
|
||||||
|
local int gz_comp(state, flush)
|
||||||
|
gz_statep state;
|
||||||
|
int flush;
|
||||||
|
{
|
||||||
|
int ret, got;
|
||||||
|
unsigned have;
|
||||||
|
z_streamp strm = &(state->strm);
|
||||||
|
|
||||||
|
/* allocate memory if this is the first time through */
|
||||||
|
if (state->size == 0 && gz_init(state) == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* write directly if requested */
|
||||||
|
if (state->direct) {
|
||||||
|
got = write(state->fd, strm->next_in, strm->avail_in);
|
||||||
|
if (got < 0 || (unsigned)got != strm->avail_in) {
|
||||||
|
gz_error(state, Z_ERRNO, zstrerror());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
strm->avail_in = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* run deflate() on provided input until it produces no more output */
|
||||||
|
ret = Z_OK;
|
||||||
|
do {
|
||||||
|
/* write out current buffer contents if full, or if flushing, but if
|
||||||
|
doing Z_FINISH then don't write until we get to Z_STREAM_END */
|
||||||
|
if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
|
||||||
|
(flush != Z_FINISH || ret == Z_STREAM_END))) {
|
||||||
|
have = (unsigned)(strm->next_out - state->x.next);
|
||||||
|
if (have && ((got = write(state->fd, state->x.next, have)) < 0 ||
|
||||||
|
(unsigned)got != have)) {
|
||||||
|
gz_error(state, Z_ERRNO, zstrerror());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (strm->avail_out == 0) {
|
||||||
|
strm->avail_out = state->size;
|
||||||
|
strm->next_out = state->out;
|
||||||
|
}
|
||||||
|
state->x.next = strm->next_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* compress */
|
||||||
|
have = strm->avail_out;
|
||||||
|
ret = deflate(strm, flush);
|
||||||
|
if (ret == Z_STREAM_ERROR) {
|
||||||
|
gz_error(state, Z_STREAM_ERROR,
|
||||||
|
"internal error: deflate stream corrupt");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
have -= strm->avail_out;
|
||||||
|
} while (have);
|
||||||
|
|
||||||
|
/* if that completed a deflate stream, allow another to start */
|
||||||
|
if (flush == Z_FINISH)
|
||||||
|
deflateReset(strm);
|
||||||
|
|
||||||
|
/* all done, no errors */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compress len zeros to output. Return -1 on error, 0 on success. */
|
||||||
|
local int gz_zero(state, len)
|
||||||
|
gz_statep state;
|
||||||
|
z_off64_t len;
|
||||||
|
{
|
||||||
|
int first;
|
||||||
|
unsigned n;
|
||||||
|
z_streamp strm = &(state->strm);
|
||||||
|
|
||||||
|
/* consume whatever's left in the input buffer */
|
||||||
|
if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* compress len zeros (len guaranteed > 0) */
|
||||||
|
first = 1;
|
||||||
|
while (len) {
|
||||||
|
n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
|
||||||
|
(unsigned)len : state->size;
|
||||||
|
if (first) {
|
||||||
|
memset(state->in, 0, n);
|
||||||
|
first = 0;
|
||||||
|
}
|
||||||
|
strm->avail_in = n;
|
||||||
|
strm->next_in = state->in;
|
||||||
|
state->x.pos += n;
|
||||||
|
if (gz_comp(state, Z_NO_FLUSH) == -1)
|
||||||
|
return -1;
|
||||||
|
len -= n;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
int ZEXPORT gzwrite(file, buf, len)
|
||||||
|
gzFile file;
|
||||||
|
voidpc buf;
|
||||||
|
unsigned len;
|
||||||
|
{
|
||||||
|
unsigned put = len;
|
||||||
|
gz_statep state;
|
||||||
|
z_streamp strm;
|
||||||
|
|
||||||
|
/* get internal structure */
|
||||||
|
if (file == NULL)
|
||||||
|
return 0;
|
||||||
|
state = (gz_statep)file;
|
||||||
|
strm = &(state->strm);
|
||||||
|
|
||||||
|
/* check that we're writing and that there's no error */
|
||||||
|
if (state->mode != GZ_WRITE || state->err != Z_OK)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* since an int is returned, make sure len fits in one, otherwise return
|
||||||
|
with an error (this avoids the flaw in the interface) */
|
||||||
|
if ((int)len < 0) {
|
||||||
|
gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if len is zero, avoid unnecessary operations */
|
||||||
|
if (len == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* allocate memory if this is the first time through */
|
||||||
|
if (state->size == 0 && gz_init(state) == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* check for seek request */
|
||||||
|
if (state->seek) {
|
||||||
|
state->seek = 0;
|
||||||
|
if (gz_zero(state, state->skip) == -1)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for small len, copy to input buffer, otherwise compress directly */
|
||||||
|
if (len < state->size) {
|
||||||
|
/* copy to input buffer, compress when full */
|
||||||
|
do {
|
||||||
|
unsigned have, copy;
|
||||||
|
|
||||||
|
if (strm->avail_in == 0)
|
||||||
|
strm->next_in = state->in;
|
||||||
|
have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
|
||||||
|
copy = state->size - have;
|
||||||
|
if (copy > len)
|
||||||
|
copy = len;
|
||||||
|
memcpy(state->in + have, buf, copy);
|
||||||
|
strm->avail_in += copy;
|
||||||
|
state->x.pos += copy;
|
||||||
|
buf = (const char *)buf + copy;
|
||||||
|
len -= copy;
|
||||||
|
if (len && gz_comp(state, Z_NO_FLUSH) == -1)
|
||||||
|
return 0;
|
||||||
|
} while (len);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* consume whatever's left in the input buffer */
|
||||||
|
if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* directly compress user buffer to file */
|
||||||
|
strm->avail_in = len;
|
||||||
|
strm->next_in = (z_const Bytef *)buf;
|
||||||
|
state->x.pos += len;
|
||||||
|
if (gz_comp(state, Z_NO_FLUSH) == -1)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* input was all buffered or compressed (put will fit in int) */
|
||||||
|
return (int)put;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
int ZEXPORT gzputc(file, c)
|
||||||
|
gzFile file;
|
||||||
|
int c;
|
||||||
|
{
|
||||||
|
unsigned have;
|
||||||
|
unsigned char buf[1];
|
||||||
|
gz_statep state;
|
||||||
|
z_streamp strm;
|
||||||
|
|
||||||
|
/* get internal structure */
|
||||||
|
if (file == NULL)
|
||||||
|
return -1;
|
||||||
|
state = (gz_statep)file;
|
||||||
|
strm = &(state->strm);
|
||||||
|
|
||||||
|
/* check that we're writing and that there's no error */
|
||||||
|
if (state->mode != GZ_WRITE || state->err != Z_OK)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* check for seek request */
|
||||||
|
if (state->seek) {
|
||||||
|
state->seek = 0;
|
||||||
|
if (gz_zero(state, state->skip) == -1)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* try writing to input buffer for speed (state->size == 0 if buffer not
|
||||||
|
initialized) */
|
||||||
|
if (state->size) {
|
||||||
|
if (strm->avail_in == 0)
|
||||||
|
strm->next_in = state->in;
|
||||||
|
have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
|
||||||
|
if (have < state->size) {
|
||||||
|
state->in[have] = c;
|
||||||
|
strm->avail_in++;
|
||||||
|
state->x.pos++;
|
||||||
|
return c & 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no room in buffer or not initialized, use gz_write() */
|
||||||
|
buf[0] = c;
|
||||||
|
if (gzwrite(file, buf, 1) != 1)
|
||||||
|
return -1;
|
||||||
|
return c & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
int ZEXPORT gzputs(file, str)
|
||||||
|
gzFile file;
|
||||||
|
const char *str;
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
unsigned len;
|
||||||
|
|
||||||
|
/* write string */
|
||||||
|
len = (unsigned)strlen(str);
|
||||||
|
ret = gzwrite(file, str, len);
|
||||||
|
return ret == 0 && len != 0 ? -1 : ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
|
||||||
|
{
|
||||||
|
int size, len;
|
||||||
|
gz_statep state;
|
||||||
|
z_streamp strm;
|
||||||
|
|
||||||
|
/* get internal structure */
|
||||||
|
if (file == NULL)
|
||||||
|
return -1;
|
||||||
|
state = (gz_statep)file;
|
||||||
|
strm = &(state->strm);
|
||||||
|
|
||||||
|
/* check that we're writing and that there's no error */
|
||||||
|
if (state->mode != GZ_WRITE || state->err != Z_OK)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* make sure we have some buffer space */
|
||||||
|
if (state->size == 0 && gz_init(state) == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* check for seek request */
|
||||||
|
if (state->seek) {
|
||||||
|
state->seek = 0;
|
||||||
|
if (gz_zero(state, state->skip) == -1)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* consume whatever's left in the input buffer */
|
||||||
|
if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* do the printf() into the input buffer, put length in len */
|
||||||
|
size = (int)(state->size);
|
||||||
|
state->in[size - 1] = 0;
|
||||||
|
#ifdef NO_vsnprintf
|
||||||
|
# ifdef HAS_vsprintf_void
|
||||||
|
(void)vsprintf((char *)(state->in), format, va);
|
||||||
|
for (len = 0; len < size; len++)
|
||||||
|
if (state->in[len] == 0) break;
|
||||||
|
# else
|
||||||
|
len = vsprintf((char *)(state->in), format, va);
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# ifdef HAS_vsnprintf_void
|
||||||
|
(void)vsnprintf((char *)(state->in), size, format, va);
|
||||||
|
len = strlen((char *)(state->in));
|
||||||
|
# else
|
||||||
|
len = vsnprintf((char *)(state->in), size, format, va);
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* check that printf() results fit in buffer */
|
||||||
|
if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* update buffer and position, defer compression until needed */
|
||||||
|
strm->avail_in = (unsigned)len;
|
||||||
|
strm->next_in = state->in;
|
||||||
|
state->x.pos += len;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list va;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
va_start(va, format);
|
||||||
|
ret = gzvprintf(file, format, va);
|
||||||
|
va_end(va);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* !STDC && !Z_HAVE_STDARG_H */
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
|
||||||
|
a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||||
|
gzFile file;
|
||||||
|
const char *format;
|
||||||
|
int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
|
||||||
|
a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
|
||||||
|
{
|
||||||
|
int size, len;
|
||||||
|
gz_statep state;
|
||||||
|
z_streamp strm;
|
||||||
|
|
||||||
|
/* get internal structure */
|
||||||
|
if (file == NULL)
|
||||||
|
return -1;
|
||||||
|
state = (gz_statep)file;
|
||||||
|
strm = &(state->strm);
|
||||||
|
|
||||||
|
/* check that can really pass pointer in ints */
|
||||||
|
if (sizeof(int) != sizeof(void *))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* check that we're writing and that there's no error */
|
||||||
|
if (state->mode != GZ_WRITE || state->err != Z_OK)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* make sure we have some buffer space */
|
||||||
|
if (state->size == 0 && gz_init(state) == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* check for seek request */
|
||||||
|
if (state->seek) {
|
||||||
|
state->seek = 0;
|
||||||
|
if (gz_zero(state, state->skip) == -1)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* consume whatever's left in the input buffer */
|
||||||
|
if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* do the printf() into the input buffer, put length in len */
|
||||||
|
size = (int)(state->size);
|
||||||
|
state->in[size - 1] = 0;
|
||||||
|
#ifdef NO_snprintf
|
||||||
|
# ifdef HAS_sprintf_void
|
||||||
|
sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
|
||||||
|
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
|
||||||
|
for (len = 0; len < size; len++)
|
||||||
|
if (state->in[len] == 0) break;
|
||||||
|
# else
|
||||||
|
len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
|
||||||
|
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# ifdef HAS_snprintf_void
|
||||||
|
snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8,
|
||||||
|
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
|
||||||
|
len = strlen((char *)(state->in));
|
||||||
|
# else
|
||||||
|
len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6,
|
||||||
|
a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18,
|
||||||
|
a19, a20);
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* check that printf() results fit in buffer */
|
||||||
|
if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* update buffer and position, defer compression until needed */
|
||||||
|
strm->avail_in = (unsigned)len;
|
||||||
|
strm->next_in = state->in;
|
||||||
|
state->x.pos += len;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
int ZEXPORT gzflush(file, flush)
|
||||||
|
gzFile file;
|
||||||
|
int flush;
|
||||||
|
{
|
||||||
|
gz_statep state;
|
||||||
|
|
||||||
|
/* get internal structure */
|
||||||
|
if (file == NULL)
|
||||||
|
return -1;
|
||||||
|
state = (gz_statep)file;
|
||||||
|
|
||||||
|
/* check that we're writing and that there's no error */
|
||||||
|
if (state->mode != GZ_WRITE || state->err != Z_OK)
|
||||||
|
return Z_STREAM_ERROR;
|
||||||
|
|
||||||
|
/* check flush parameter */
|
||||||
|
if (flush < 0 || flush > Z_FINISH)
|
||||||
|
return Z_STREAM_ERROR;
|
||||||
|
|
||||||
|
/* check for seek request */
|
||||||
|
if (state->seek) {
|
||||||
|
state->seek = 0;
|
||||||
|
if (gz_zero(state, state->skip) == -1)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* compress remaining data with requested flush */
|
||||||
|
gz_comp(state, flush);
|
||||||
|
return state->err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
int ZEXPORT gzsetparams(file, level, strategy)
|
||||||
|
gzFile file;
|
||||||
|
int level;
|
||||||
|
int strategy;
|
||||||
|
{
|
||||||
|
gz_statep state;
|
||||||
|
z_streamp strm;
|
||||||
|
|
||||||
|
/* get internal structure */
|
||||||
|
if (file == NULL)
|
||||||
|
return Z_STREAM_ERROR;
|
||||||
|
state = (gz_statep)file;
|
||||||
|
strm = &(state->strm);
|
||||||
|
|
||||||
|
/* check that we're writing and that there's no error */
|
||||||
|
if (state->mode != GZ_WRITE || state->err != Z_OK)
|
||||||
|
return Z_STREAM_ERROR;
|
||||||
|
|
||||||
|
/* if no change is requested, then do nothing */
|
||||||
|
if (level == state->level && strategy == state->strategy)
|
||||||
|
return Z_OK;
|
||||||
|
|
||||||
|
/* check for seek request */
|
||||||
|
if (state->seek) {
|
||||||
|
state->seek = 0;
|
||||||
|
if (gz_zero(state, state->skip) == -1)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* change compression parameters for subsequent input */
|
||||||
|
if (state->size) {
|
||||||
|
/* flush previous input with previous parameters before changing */
|
||||||
|
if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1)
|
||||||
|
return state->err;
|
||||||
|
deflateParams(strm, level, strategy);
|
||||||
|
}
|
||||||
|
state->level = level;
|
||||||
|
state->strategy = strategy;
|
||||||
|
return Z_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
int ZEXPORT gzclose_w(file)
|
||||||
|
gzFile file;
|
||||||
|
{
|
||||||
|
int ret = Z_OK;
|
||||||
|
gz_statep state;
|
||||||
|
|
||||||
|
/* get internal structure */
|
||||||
|
if (file == NULL)
|
||||||
|
return Z_STREAM_ERROR;
|
||||||
|
state = (gz_statep)file;
|
||||||
|
|
||||||
|
/* check that we're writing */
|
||||||
|
if (state->mode != GZ_WRITE)
|
||||||
|
return Z_STREAM_ERROR;
|
||||||
|
|
||||||
|
/* check for seek request */
|
||||||
|
if (state->seek) {
|
||||||
|
state->seek = 0;
|
||||||
|
if (gz_zero(state, state->skip) == -1)
|
||||||
|
ret = state->err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* flush, free memory, and close file */
|
||||||
|
if (gz_comp(state, Z_FINISH) == -1)
|
||||||
|
ret = state->err;
|
||||||
|
if (state->size) {
|
||||||
|
if (!state->direct) {
|
||||||
|
(void)deflateEnd(&(state->strm));
|
||||||
|
free(state->out);
|
||||||
|
}
|
||||||
|
free(state->in);
|
||||||
|
}
|
||||||
|
gz_error(state, Z_OK, NULL);
|
||||||
|
free(state->path);
|
||||||
|
if (close(state->fd) == -1)
|
||||||
|
ret = Z_ERRNO;
|
||||||
|
free(state);
|
||||||
|
return ret;
|
||||||
|
}
|
|
@ -0,0 +1,640 @@
|
||||||
|
/* infback.c -- inflate using a call-back interface
|
||||||
|
* Copyright (C) 1995-2011 Mark Adler
|
||||||
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
This code is largely copied from inflate.c. Normally either infback.o or
|
||||||
|
inflate.o would be linked into an application--not both. The interface
|
||||||
|
with inffast.c is retained so that optimized assembler-coded versions of
|
||||||
|
inflate_fast() can be used with either inflate.c or infback.c.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "zutil.h"
|
||||||
|
#include "inftrees.h"
|
||||||
|
#include "inflate.h"
|
||||||
|
#include "inffast.h"
|
||||||
|
|
||||||
|
/* function prototypes */
|
||||||
|
local void fixedtables OF((struct inflate_state FAR *state));
|
||||||
|
|
||||||
|
/*
|
||||||
|
strm provides memory allocation functions in zalloc and zfree, or
|
||||||
|
Z_NULL to use the library memory allocation functions.
|
||||||
|
|
||||||
|
windowBits is in the range 8..15, and window is a user-supplied
|
||||||
|
window and output buffer that is 2**windowBits bytes.
|
||||||
|
*/
|
||||||
|
int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
|
||||||
|
z_streamp strm;
|
||||||
|
int windowBits;
|
||||||
|
unsigned char FAR *window;
|
||||||
|
const char *version;
|
||||||
|
int stream_size;
|
||||||
|
{
|
||||||
|
struct inflate_state FAR *state;
|
||||||
|
|
||||||
|
if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
|
||||||
|
stream_size != (int)(sizeof(z_stream)))
|
||||||
|
return Z_VERSION_ERROR;
|
||||||
|
if (strm == Z_NULL || window == Z_NULL ||
|
||||||
|
windowBits < 8 || windowBits > 15)
|
||||||
|
return Z_STREAM_ERROR;
|
||||||
|
strm->msg = Z_NULL; /* in case we return an error */
|
||||||
|
if (strm->zalloc == (alloc_func)0) {
|
||||||
|
#ifdef Z_SOLO
|
||||||
|
return Z_STREAM_ERROR;
|
||||||
|
#else
|
||||||
|
strm->zalloc = zcalloc;
|
||||||
|
strm->opaque = (voidpf)0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (strm->zfree == (free_func)0)
|
||||||
|
#ifdef Z_SOLO
|
||||||
|
return Z_STREAM_ERROR;
|
||||||
|
#else
|
||||||
|
strm->zfree = zcfree;
|
||||||
|
#endif
|
||||||
|
state = (struct inflate_state FAR *)ZALLOC(strm, 1,
|
||||||
|
sizeof(struct inflate_state));
|
||||||
|
if (state == Z_NULL) return Z_MEM_ERROR;
|
||||||
|
Tracev((stderr, "inflate: allocated\n"));
|
||||||
|
strm->state = (struct internal_state FAR *)state;
|
||||||
|
state->dmax = 32768U;
|
||||||
|
state->wbits = windowBits;
|
||||||
|
state->wsize = 1U << windowBits;
|
||||||
|
state->window = window;
|
||||||
|
state->wnext = 0;
|
||||||
|
state->whave = 0;
|
||||||
|
return Z_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Return state with length and distance decoding tables and index sizes set to
|
||||||
|
fixed code decoding. Normally this returns fixed tables from inffixed.h.
|
||||||
|
If BUILDFIXED is defined, then instead this routine builds the tables the
|
||||||
|
first time it's called, and returns those tables the first time and
|
||||||
|
thereafter. This reduces the size of the code by about 2K bytes, in
|
||||||
|
exchange for a little execution time. However, BUILDFIXED should not be
|
||||||
|
used for threaded applications, since the rewriting of the tables and virgin
|
||||||
|
may not be thread-safe.
|
||||||
|
*/
|
||||||
|
local void fixedtables(state)
|
||||||
|
struct inflate_state FAR *state;
|
||||||
|
{
|
||||||
|
#ifdef BUILDFIXED
|
||||||
|
static int virgin = 1;
|
||||||
|
static code *lenfix, *distfix;
|
||||||
|
static code fixed[544];
|
||||||
|
|
||||||
|
/* build fixed huffman tables if first call (may not be thread safe) */
|
||||||
|
if (virgin) {
|
||||||
|
unsigned sym, bits;
|
||||||
|
static code *next;
|
||||||
|
|
||||||
|
/* literal/length table */
|
||||||
|
sym = 0;
|
||||||
|
while (sym < 144) state->lens[sym++] = 8;
|
||||||
|
while (sym < 256) state->lens[sym++] = 9;
|
||||||
|
while (sym < 280) state->lens[sym++] = 7;
|
||||||
|
while (sym < 288) state->lens[sym++] = 8;
|
||||||
|
next = fixed;
|
||||||
|
lenfix = next;
|
||||||
|
bits = 9;
|
||||||
|
inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
|
||||||
|
|
||||||
|
/* distance table */
|
||||||
|
sym = 0;
|
||||||
|
while (sym < 32) state->lens[sym++] = 5;
|
||||||
|
distfix = next;
|
||||||
|
bits = 5;
|
||||||
|
inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
|
||||||
|
|
||||||
|
/* do this just once */
|
||||||
|
virgin = 0;
|
||||||
|
}
|
||||||
|
#else /* !BUILDFIXED */
|
||||||
|
# include "inffixed.h"
|
||||||
|
#endif /* BUILDFIXED */
|
||||||
|
state->lencode = lenfix;
|
||||||
|
state->lenbits = 9;
|
||||||
|
state->distcode = distfix;
|
||||||
|
state->distbits = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Macros for inflateBack(): */
|
||||||
|
|
||||||
|
/* Load returned state from inflate_fast() */
|
||||||
|
#define LOAD() \
|
||||||
|
do { \
|
||||||
|
put = strm->next_out; \
|
||||||
|
left = strm->avail_out; \
|
||||||
|
next = strm->next_in; \
|
||||||
|
have = strm->avail_in; \
|
||||||
|
hold = state->hold; \
|
||||||
|
bits = state->bits; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Set state from registers for inflate_fast() */
|
||||||
|
#define RESTORE() \
|
||||||
|
do { \
|
||||||
|
strm->next_out = put; \
|
||||||
|
strm->avail_out = left; \
|
||||||
|
strm->next_in = next; \
|
||||||
|
strm->avail_in = have; \
|
||||||
|
state->hold = hold; \
|
||||||
|
state->bits = bits; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Clear the input bit accumulator */
|
||||||
|
#define INITBITS() \
|
||||||
|
do { \
|
||||||
|
hold = 0; \
|
||||||
|
bits = 0; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Assure that some input is available. If input is requested, but denied,
|
||||||
|
then return a Z_BUF_ERROR from inflateBack(). */
|
||||||
|
#define PULL() \
|
||||||
|
do { \
|
||||||
|
if (have == 0) { \
|
||||||
|
have = in(in_desc, &next); \
|
||||||
|
if (have == 0) { \
|
||||||
|
next = Z_NULL; \
|
||||||
|
ret = Z_BUF_ERROR; \
|
||||||
|
goto inf_leave; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Get a byte of input into the bit accumulator, or return from inflateBack()
|
||||||
|
with an error if there is no input available. */
|
||||||
|
#define PULLBYTE() \
|
||||||
|
do { \
|
||||||
|
PULL(); \
|
||||||
|
have--; \
|
||||||
|
hold += (unsigned long)(*next++) << bits; \
|
||||||
|
bits += 8; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Assure that there are at least n bits in the bit accumulator. If there is
|
||||||
|
not enough available input to do that, then return from inflateBack() with
|
||||||
|
an error. */
|
||||||
|
#define NEEDBITS(n) \
|
||||||
|
do { \
|
||||||
|
while (bits < (unsigned)(n)) \
|
||||||
|
PULLBYTE(); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Return the low n bits of the bit accumulator (n < 16) */
|
||||||
|
#define BITS(n) \
|
||||||
|
((unsigned)hold & ((1U << (n)) - 1))
|
||||||
|
|
||||||
|
/* Remove n bits from the bit accumulator */
|
||||||
|
#define DROPBITS(n) \
|
||||||
|
do { \
|
||||||
|
hold >>= (n); \
|
||||||
|
bits -= (unsigned)(n); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Remove zero to seven bits as needed to go to a byte boundary */
|
||||||
|
#define BYTEBITS() \
|
||||||
|
do { \
|
||||||
|
hold >>= bits & 7; \
|
||||||
|
bits -= bits & 7; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Assure that some output space is available, by writing out the window
|
||||||
|
if it's full. If the write fails, return from inflateBack() with a
|
||||||
|
Z_BUF_ERROR. */
|
||||||
|
#define ROOM() \
|
||||||
|
do { \
|
||||||
|
if (left == 0) { \
|
||||||
|
put = state->window; \
|
||||||
|
left = state->wsize; \
|
||||||
|
state->whave = left; \
|
||||||
|
if (out(out_desc, put, left)) { \
|
||||||
|
ret = Z_BUF_ERROR; \
|
||||||
|
goto inf_leave; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
strm provides the memory allocation functions and window buffer on input,
|
||||||
|
and provides information on the unused input on return. For Z_DATA_ERROR
|
||||||
|
returns, strm will also provide an error message.
|
||||||
|
|
||||||
|
in() and out() are the call-back input and output functions. When
|
||||||
|
inflateBack() needs more input, it calls in(). When inflateBack() has
|
||||||
|
filled the window with output, or when it completes with data in the
|
||||||
|
window, it calls out() to write out the data. The application must not
|
||||||
|
change the provided input until in() is called again or inflateBack()
|
||||||
|
returns. The application must not change the window/output buffer until
|
||||||
|
inflateBack() returns.
|
||||||
|
|
||||||
|
in() and out() are called with a descriptor parameter provided in the
|
||||||
|
inflateBack() call. This parameter can be a structure that provides the
|
||||||
|
information required to do the read or write, as well as accumulated
|
||||||
|
information on the input and output such as totals and check values.
|
||||||
|
|
||||||
|
in() should return zero on failure. out() should return non-zero on
|
||||||
|
failure. If either in() or out() fails, than inflateBack() returns a
|
||||||
|
Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
|
||||||
|
was in() or out() that caused in the error. Otherwise, inflateBack()
|
||||||
|
returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
|
||||||
|
error, or Z_MEM_ERROR if it could not allocate memory for the state.
|
||||||
|
inflateBack() can also return Z_STREAM_ERROR if the input parameters
|
||||||
|
are not correct, i.e. strm is Z_NULL or the state was not initialized.
|
||||||
|
*/
|
||||||
|
int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
|
||||||
|
z_streamp strm;
|
||||||
|
in_func in;
|
||||||
|
void FAR *in_desc;
|
||||||
|
out_func out;
|
||||||
|
void FAR *out_desc;
|
||||||
|
{
|
||||||
|
struct inflate_state FAR *state;
|
||||||
|
z_const unsigned char FAR *next; /* next input */
|
||||||
|
unsigned char FAR *put; /* next output */
|
||||||
|
unsigned have, left; /* available input and output */
|
||||||
|
unsigned long hold; /* bit buffer */
|
||||||
|
unsigned bits; /* bits in bit buffer */
|
||||||
|
unsigned copy; /* number of stored or match bytes to copy */
|
||||||
|
unsigned char FAR *from; /* where to copy match bytes from */
|
||||||
|
code here; /* current decoding table entry */
|
||||||
|
code last; /* parent table entry */
|
||||||
|
unsigned len; /* length to copy for repeats, bits to drop */
|
||||||
|
int ret; /* return code */
|
||||||
|
static const unsigned short order[19] = /* permutation of code lengths */
|
||||||
|
{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
|
||||||
|
|
||||||
|
/* Check that the strm exists and that the state was initialized */
|
||||||
|
if (strm == Z_NULL || strm->state == Z_NULL)
|
||||||
|
return Z_STREAM_ERROR;
|
||||||
|
state = (struct inflate_state FAR *)strm->state;
|
||||||
|
|
||||||
|
/* Reset the state */
|
||||||
|
strm->msg = Z_NULL;
|
||||||
|
state->mode = TYPE;
|
||||||
|
state->last = 0;
|
||||||
|
state->whave = 0;
|
||||||
|
next = strm->next_in;
|
||||||
|
have = next != Z_NULL ? strm->avail_in : 0;
|
||||||
|
hold = 0;
|
||||||
|
bits = 0;
|
||||||
|
put = state->window;
|
||||||
|
left = state->wsize;
|
||||||
|
|
||||||
|
/* Inflate until end of block marked as last */
|
||||||
|
for (;;)
|
||||||
|
switch (state->mode) {
|
||||||
|
case TYPE:
|
||||||
|
/* determine and dispatch block type */
|
||||||
|
if (state->last) {
|
||||||
|
BYTEBITS();
|
||||||
|
state->mode = DONE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
NEEDBITS(3);
|
||||||
|
state->last = BITS(1);
|
||||||
|
DROPBITS(1);
|
||||||
|
switch (BITS(2)) {
|
||||||
|
case 0: /* stored block */
|
||||||
|
Tracev((stderr, "inflate: stored block%s\n",
|
||||||
|
state->last ? " (last)" : ""));
|
||||||
|
state->mode = STORED;
|
||||||
|
break;
|
||||||
|
case 1: /* fixed block */
|
||||||
|
fixedtables(state);
|
||||||
|
Tracev((stderr, "inflate: fixed codes block%s\n",
|
||||||
|
state->last ? " (last)" : ""));
|
||||||
|
state->mode = LEN; /* decode codes */
|
||||||
|
break;
|
||||||
|
case 2: /* dynamic block */
|
||||||
|
Tracev((stderr, "inflate: dynamic codes block%s\n",
|
||||||
|
state->last ? " (last)" : ""));
|
||||||
|
state->mode = TABLE;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
strm->msg = (char *)"invalid block type";
|
||||||
|
state->mode = BAD;
|
||||||
|
}
|
||||||
|
DROPBITS(2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STORED:
|
||||||
|
/* get and verify stored block length */
|
||||||
|
BYTEBITS(); /* go to byte boundary */
|
||||||
|
NEEDBITS(32);
|
||||||
|
if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
|
||||||
|
strm->msg = (char *)"invalid stored block lengths";
|
||||||
|
state->mode = BAD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
state->length = (unsigned)hold & 0xffff;
|
||||||
|
Tracev((stderr, "inflate: stored length %u\n",
|
||||||
|
state->length));
|
||||||
|
INITBITS();
|
||||||
|
|
||||||
|
/* copy stored block from input to output */
|
||||||
|
while (state->length != 0) {
|
||||||
|
copy = state->length;
|
||||||
|
PULL();
|
||||||
|
ROOM();
|
||||||
|
if (copy > have) copy = have;
|
||||||
|
if (copy > left) copy = left;
|
||||||
|
zmemcpy(put, next, copy);
|
||||||
|
have -= copy;
|
||||||
|
next += copy;
|
||||||
|
left -= copy;
|
||||||
|
put += copy;
|
||||||
|
state->length -= copy;
|
||||||
|
}
|
||||||
|
Tracev((stderr, "inflate: stored end\n"));
|
||||||
|
state->mode = TYPE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TABLE:
|
||||||
|
/* get dynamic table entries descriptor */
|
||||||
|
NEEDBITS(14);
|
||||||
|
state->nlen = BITS(5) + 257;
|
||||||
|
DROPBITS(5);
|
||||||
|
state->ndist = BITS(5) + 1;
|
||||||
|
DROPBITS(5);
|
||||||
|
state->ncode = BITS(4) + 4;
|
||||||
|
DROPBITS(4);
|
||||||
|
#ifndef PKZIP_BUG_WORKAROUND
|
||||||
|
if (state->nlen > 286 || state->ndist > 30) {
|
||||||
|
strm->msg = (char *)"too many length or distance symbols";
|
||||||
|
state->mode = BAD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
Tracev((stderr, "inflate: table sizes ok\n"));
|
||||||
|
|
||||||
|
/* get code length code lengths (not a typo) */
|
||||||
|
state->have = 0;
|
||||||
|
while (state->have < state->ncode) {
|
||||||
|
NEEDBITS(3);
|
||||||
|
state->lens[order[state->have++]] = (unsigned short)BITS(3);
|
||||||
|
DROPBITS(3);
|
||||||
|
}
|
||||||
|
while (state->have < 19)
|
||||||
|
state->lens[order[state->have++]] = 0;
|
||||||
|
state->next = state->codes;
|
||||||
|
state->lencode = (code const FAR *)(state->next);
|
||||||
|
state->lenbits = 7;
|
||||||
|
ret = inflate_table(CODES, state->lens, 19, &(state->next),
|
||||||
|
&(state->lenbits), state->work);
|
||||||
|
if (ret) {
|
||||||
|
strm->msg = (char *)"invalid code lengths set";
|
||||||
|
state->mode = BAD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Tracev((stderr, "inflate: code lengths ok\n"));
|
||||||
|
|
||||||
|
/* get length and distance code code lengths */
|
||||||
|
state->have = 0;
|
||||||
|
while (state->have < state->nlen + state->ndist) {
|
||||||
|
for (;;) {
|
||||||
|
here = state->lencode[BITS(state->lenbits)];
|
||||||
|
if ((unsigned)(here.bits) <= bits) break;
|
||||||
|
PULLBYTE();
|
||||||
|
}
|
||||||
|
if (here.val < 16) {
|
||||||
|
DROPBITS(here.bits);
|
||||||
|
state->lens[state->have++] = here.val;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (here.val == 16) {
|
||||||
|
NEEDBITS(here.bits + 2);
|
||||||
|
DROPBITS(here.bits);
|
||||||
|
if (state->have == 0) {
|
||||||
|
strm->msg = (char *)"invalid bit length repeat";
|
||||||
|
state->mode = BAD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
len = (unsigned)(state->lens[state->have - 1]);
|
||||||
|
copy = 3 + BITS(2);
|
||||||
|
DROPBITS(2);
|
||||||
|
}
|
||||||
|
else if (here.val == 17) {
|
||||||
|
NEEDBITS(here.bits + 3);
|
||||||
|
DROPBITS(here.bits);
|
||||||
|
len = 0;
|
||||||
|
copy = 3 + BITS(3);
|
||||||
|
DROPBITS(3);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
NEEDBITS(here.bits + 7);
|
||||||
|
DROPBITS(here.bits);
|
||||||
|
len = 0;
|
||||||
|
copy = 11 + BITS(7);
|
||||||
|
DROPBITS(7);
|
||||||
|
}
|
||||||
|
if (state->have + copy > state->nlen + state->ndist) {
|
||||||
|
strm->msg = (char *)"invalid bit length repeat";
|
||||||
|
state->mode = BAD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while (copy--)
|
||||||
|
state->lens[state->have++] = (unsigned short)len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* handle error breaks in while */
|
||||||
|
if (state->mode == BAD) break;
|
||||||
|
|
||||||
|
/* check for end-of-block code (better have one) */
|
||||||
|
if (state->lens[256] == 0) {
|
||||||
|
strm->msg = (char *)"invalid code -- missing end-of-block";
|
||||||
|
state->mode = BAD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* build code tables -- note: do not change the lenbits or distbits
|
||||||
|
values here (9 and 6) without reading the comments in inftrees.h
|
||||||
|
concerning the ENOUGH constants, which depend on those values */
|
||||||
|
state->next = state->codes;
|
||||||
|
state->lencode = (code const FAR *)(state->next);
|
||||||
|
state->lenbits = 9;
|
||||||
|
ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
|
||||||
|
&(state->lenbits), state->work);
|
||||||
|
if (ret) {
|
||||||
|
strm->msg = (char *)"invalid literal/lengths set";
|
||||||
|
state->mode = BAD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
state->distcode = (code const FAR *)(state->next);
|
||||||
|
state->distbits = 6;
|
||||||
|
ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
|
||||||
|
&(state->next), &(state->distbits), state->work);
|
||||||
|
if (ret) {
|
||||||
|
strm->msg = (char *)"invalid distances set";
|
||||||
|
state->mode = BAD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Tracev((stderr, "inflate: codes ok\n"));
|
||||||
|
state->mode = LEN;
|
||||||
|
|
||||||
|
case LEN:
|
||||||
|
/* use inflate_fast() if we have enough input and output */
|
||||||
|
if (have >= 6 && left >= 258) {
|
||||||
|
RESTORE();
|
||||||
|
if (state->whave < state->wsize)
|
||||||
|
state->whave = state->wsize - left;
|
||||||
|
inflate_fast(strm, state->wsize);
|
||||||
|
LOAD();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get a literal, length, or end-of-block code */
|
||||||
|
for (;;) {
|
||||||
|
here = state->lencode[BITS(state->lenbits)];
|
||||||
|
if ((unsigned)(here.bits) <= bits) break;
|
||||||
|
PULLBYTE();
|
||||||
|
}
|
||||||
|
if (here.op && (here.op & 0xf0) == 0) {
|
||||||
|
last = here;
|
||||||
|
for (;;) {
|
||||||
|
here = state->lencode[last.val +
|
||||||
|
(BITS(last.bits + last.op) >> last.bits)];
|
||||||
|
if ((unsigned)(last.bits + here.bits) <= bits) break;
|
||||||
|
PULLBYTE();
|
||||||
|
}
|
||||||
|
DROPBITS(last.bits);
|
||||||
|
}
|
||||||
|
DROPBITS(here.bits);
|
||||||
|
state->length = (unsigned)here.val;
|
||||||
|
|
||||||
|
/* process literal */
|
||||||
|
if (here.op == 0) {
|
||||||
|
Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
|
||||||
|
"inflate: literal '%c'\n" :
|
||||||
|
"inflate: literal 0x%02x\n", here.val));
|
||||||
|
ROOM();
|
||||||
|
*put++ = (unsigned char)(state->length);
|
||||||
|
left--;
|
||||||
|
state->mode = LEN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* process end of block */
|
||||||
|
if (here.op & 32) {
|
||||||
|
Tracevv((stderr, "inflate: end of block\n"));
|
||||||
|
state->mode = TYPE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* invalid code */
|
||||||
|
if (here.op & 64) {
|
||||||
|
strm->msg = (char *)"invalid literal/length code";
|
||||||
|
state->mode = BAD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* length code -- get extra bits, if any */
|
||||||
|
state->extra = (unsigned)(here.op) & 15;
|
||||||
|
if (state->extra != 0) {
|
||||||
|
NEEDBITS(state->extra);
|
||||||
|
state->length += BITS(state->extra);
|
||||||
|
DROPBITS(state->extra);
|
||||||
|
}
|
||||||
|
Tracevv((stderr, "inflate: length %u\n", state->length));
|
||||||
|
|
||||||
|
/* get distance code */
|
||||||
|
for (;;) {
|
||||||
|
here = state->distcode[BITS(state->distbits)];
|
||||||
|
if ((unsigned)(here.bits) <= bits) break;
|
||||||
|
PULLBYTE();
|
||||||
|
}
|
||||||
|
if ((here.op & 0xf0) == 0) {
|
||||||
|
last = here;
|
||||||
|
for (;;) {
|
||||||
|
here = state->distcode[last.val +
|
||||||
|
(BITS(last.bits + last.op) >> last.bits)];
|
||||||
|
if ((unsigned)(last.bits + here.bits) <= bits) break;
|
||||||
|
PULLBYTE();
|
||||||
|
}
|
||||||
|
DROPBITS(last.bits);
|
||||||
|
}
|
||||||
|
DROPBITS(here.bits);
|
||||||
|
if (here.op & 64) {
|
||||||
|
strm->msg = (char *)"invalid distance code";
|
||||||
|
state->mode = BAD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
state->offset = (unsigned)here.val;
|
||||||
|
|
||||||
|
/* get distance extra bits, if any */
|
||||||
|
state->extra = (unsigned)(here.op) & 15;
|
||||||
|
if (state->extra != 0) {
|
||||||
|
NEEDBITS(state->extra);
|
||||||
|
state->offset += BITS(state->extra);
|
||||||
|
DROPBITS(state->extra);
|
||||||
|
}
|
||||||
|
if (state->offset > state->wsize - (state->whave < state->wsize ?
|
||||||
|
left : 0)) {
|
||||||
|
strm->msg = (char *)"invalid distance too far back";
|
||||||
|
state->mode = BAD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Tracevv((stderr, "inflate: distance %u\n", state->offset));
|
||||||
|
|
||||||
|
/* copy match from window to output */
|
||||||
|
do {
|
||||||
|
ROOM();
|
||||||
|
copy = state->wsize - state->offset;
|
||||||
|
if (copy < left) {
|
||||||
|
from = put + copy;
|
||||||
|
copy = left - copy;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
from = put - state->offset;
|
||||||
|
copy = left;
|
||||||
|
}
|
||||||
|
if (copy > state->length) copy = state->length;
|
||||||
|
state->length -= copy;
|
||||||
|
left -= copy;
|
||||||
|
do {
|
||||||
|
*put++ = *from++;
|
||||||
|
} while (--copy);
|
||||||
|
} while (state->length != 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DONE:
|
||||||
|
/* inflate stream terminated properly -- write leftover output */
|
||||||
|
ret = Z_STREAM_END;
|
||||||
|
if (left < state->wsize) {
|
||||||
|
if (out(out_desc, state->window, state->wsize - left))
|
||||||
|
ret = Z_BUF_ERROR;
|
||||||
|
}
|
||||||
|
goto inf_leave;
|
||||||
|
|
||||||
|
case BAD:
|
||||||
|
ret = Z_DATA_ERROR;
|
||||||
|
goto inf_leave;
|
||||||
|
|
||||||
|
default: /* can't happen, but makes compilers happy */
|
||||||
|
ret = Z_STREAM_ERROR;
|
||||||
|
goto inf_leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return unused input */
|
||||||
|
inf_leave:
|
||||||
|
strm->next_in = next;
|
||||||
|
strm->avail_in = have;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ZEXPORT inflateBackEnd(strm)
|
||||||
|
z_streamp strm;
|
||||||
|
{
|
||||||
|
if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
|
||||||
|
return Z_STREAM_ERROR;
|
||||||
|
ZFREE(strm, strm->state);
|
||||||
|
strm->state = Z_NULL;
|
||||||
|
Tracev((stderr, "inflate: end\n"));
|
||||||
|
return Z_OK;
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/* inffast.c -- fast decoding
|
/* inffast.c -- fast decoding
|
||||||
* Copyright (C) 1995-2008, 2010 Mark Adler
|
* Copyright (C) 1995-2008, 2010, 2013 Mark Adler
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -69,8 +69,8 @@ z_streamp strm;
|
||||||
unsigned start; /* inflate()'s starting value for strm->avail_out */
|
unsigned start; /* inflate()'s starting value for strm->avail_out */
|
||||||
{
|
{
|
||||||
struct inflate_state FAR *state;
|
struct inflate_state FAR *state;
|
||||||
unsigned char FAR *in; /* local strm->next_in */
|
z_const unsigned char FAR *in; /* local strm->next_in */
|
||||||
unsigned char FAR *last; /* while in < last, enough input available */
|
z_const unsigned char FAR *last; /* have enough input while in < last */
|
||||||
unsigned char FAR *out; /* local strm->next_out */
|
unsigned char FAR *out; /* local strm->next_out */
|
||||||
unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
|
unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
|
||||||
unsigned char FAR *end; /* while out < end, enough space available */
|
unsigned char FAR *end; /* while out < end, enough space available */
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
* Generated automatically by makefixed().
|
* Generated automatically by makefixed().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* WARNING: this file should *not* be used by applications. It
|
/* WARNING: this file should *not* be used by applications.
|
||||||
is part of the implementation of the compression library and
|
It is part of the implementation of this library and is
|
||||||
is subject to change. Applications should only use zlib.h.
|
subject to change. Applications should only use zlib.h.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const code lenfix[512] = {
|
static const code lenfix[512] = {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* inflate.c -- zlib decompression
|
/* inflate.c -- zlib decompression
|
||||||
* Copyright (C) 1995-2010 Mark Adler
|
* Copyright (C) 1995-2012 Mark Adler
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -93,14 +93,15 @@
|
||||||
|
|
||||||
/* function prototypes */
|
/* function prototypes */
|
||||||
local void fixedtables OF((struct inflate_state FAR *state));
|
local void fixedtables OF((struct inflate_state FAR *state));
|
||||||
local int updatewindow OF((z_streamp strm, unsigned out));
|
local int updatewindow OF((z_streamp strm, const unsigned char FAR *end,
|
||||||
|
unsigned copy));
|
||||||
#ifdef BUILDFIXED
|
#ifdef BUILDFIXED
|
||||||
void makefixed OF((void));
|
void makefixed OF((void));
|
||||||
#endif
|
#endif
|
||||||
local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
|
local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf,
|
||||||
unsigned len));
|
unsigned len));
|
||||||
|
|
||||||
int ZEXPORT inflateReset(strm)
|
int ZEXPORT inflateResetKeep(strm)
|
||||||
z_streamp strm;
|
z_streamp strm;
|
||||||
{
|
{
|
||||||
struct inflate_state FAR *state;
|
struct inflate_state FAR *state;
|
||||||
|
@ -109,15 +110,13 @@ z_streamp strm;
|
||||||
state = (struct inflate_state FAR *)strm->state;
|
state = (struct inflate_state FAR *)strm->state;
|
||||||
strm->total_in = strm->total_out = state->total = 0;
|
strm->total_in = strm->total_out = state->total = 0;
|
||||||
strm->msg = Z_NULL;
|
strm->msg = Z_NULL;
|
||||||
strm->adler = 1; /* to support ill-conceived Java test suite */
|
if (state->wrap) /* to support ill-conceived Java test suite */
|
||||||
|
strm->adler = state->wrap & 1;
|
||||||
state->mode = HEAD;
|
state->mode = HEAD;
|
||||||
state->last = 0;
|
state->last = 0;
|
||||||
state->havedict = 0;
|
state->havedict = 0;
|
||||||
state->dmax = 32768U;
|
state->dmax = 32768U;
|
||||||
state->head = Z_NULL;
|
state->head = Z_NULL;
|
||||||
state->wsize = 0;
|
|
||||||
state->whave = 0;
|
|
||||||
state->wnext = 0;
|
|
||||||
state->hold = 0;
|
state->hold = 0;
|
||||||
state->bits = 0;
|
state->bits = 0;
|
||||||
state->lencode = state->distcode = state->next = state->codes;
|
state->lencode = state->distcode = state->next = state->codes;
|
||||||
|
@ -127,6 +126,19 @@ z_streamp strm;
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ZEXPORT inflateReset(strm)
|
||||||
|
z_streamp strm;
|
||||||
|
{
|
||||||
|
struct inflate_state FAR *state;
|
||||||
|
|
||||||
|
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
||||||
|
state = (struct inflate_state FAR *)strm->state;
|
||||||
|
state->wsize = 0;
|
||||||
|
state->whave = 0;
|
||||||
|
state->wnext = 0;
|
||||||
|
return inflateResetKeep(strm);
|
||||||
|
}
|
||||||
|
|
||||||
int ZEXPORT inflateReset2(strm, windowBits)
|
int ZEXPORT inflateReset2(strm, windowBits)
|
||||||
z_streamp strm;
|
z_streamp strm;
|
||||||
int windowBits;
|
int windowBits;
|
||||||
|
@ -180,10 +192,19 @@ int stream_size;
|
||||||
if (strm == Z_NULL) return Z_STREAM_ERROR;
|
if (strm == Z_NULL) return Z_STREAM_ERROR;
|
||||||
strm->msg = Z_NULL; /* in case we return an error */
|
strm->msg = Z_NULL; /* in case we return an error */
|
||||||
if (strm->zalloc == (alloc_func)0) {
|
if (strm->zalloc == (alloc_func)0) {
|
||||||
|
#ifdef Z_SOLO
|
||||||
|
return Z_STREAM_ERROR;
|
||||||
|
#else
|
||||||
strm->zalloc = zcalloc;
|
strm->zalloc = zcalloc;
|
||||||
strm->opaque = (voidpf)0;
|
strm->opaque = (voidpf)0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (strm->zfree == (free_func)0) strm->zfree = zcfree;
|
if (strm->zfree == (free_func)0)
|
||||||
|
#ifdef Z_SOLO
|
||||||
|
return Z_STREAM_ERROR;
|
||||||
|
#else
|
||||||
|
strm->zfree = zcfree;
|
||||||
|
#endif
|
||||||
state = (struct inflate_state FAR *)
|
state = (struct inflate_state FAR *)
|
||||||
ZALLOC(strm, 1, sizeof(struct inflate_state));
|
ZALLOC(strm, 1, sizeof(struct inflate_state));
|
||||||
if (state == Z_NULL) return Z_MEM_ERROR;
|
if (state == Z_NULL) return Z_MEM_ERROR;
|
||||||
|
@ -321,8 +342,8 @@ void makefixed()
|
||||||
low = 0;
|
low = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if ((low % 7) == 0) printf("\n ");
|
if ((low % 7) == 0) printf("\n ");
|
||||||
printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,
|
printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op,
|
||||||
state.lencode[low].val);
|
state.lencode[low].bits, state.lencode[low].val);
|
||||||
if (++low == size) break;
|
if (++low == size) break;
|
||||||
putchar(',');
|
putchar(',');
|
||||||
}
|
}
|
||||||
|
@ -355,12 +376,13 @@ void makefixed()
|
||||||
output will fall in the output data, making match copies simpler and faster.
|
output will fall in the output data, making match copies simpler and faster.
|
||||||
The advantage may be dependent on the size of the processor's data caches.
|
The advantage may be dependent on the size of the processor's data caches.
|
||||||
*/
|
*/
|
||||||
local int updatewindow(strm, out)
|
local int updatewindow(strm, end, copy)
|
||||||
z_streamp strm;
|
z_streamp strm;
|
||||||
unsigned out;
|
const Bytef *end;
|
||||||
|
unsigned copy;
|
||||||
{
|
{
|
||||||
struct inflate_state FAR *state;
|
struct inflate_state FAR *state;
|
||||||
unsigned copy, dist;
|
unsigned dist;
|
||||||
|
|
||||||
state = (struct inflate_state FAR *)strm->state;
|
state = (struct inflate_state FAR *)strm->state;
|
||||||
|
|
||||||
|
@ -380,19 +402,18 @@ unsigned out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy state->wsize or less output bytes into the circular window */
|
/* copy state->wsize or less output bytes into the circular window */
|
||||||
copy = out - strm->avail_out;
|
|
||||||
if (copy >= state->wsize) {
|
if (copy >= state->wsize) {
|
||||||
zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
|
zmemcpy(state->window, end - state->wsize, state->wsize);
|
||||||
state->wnext = 0;
|
state->wnext = 0;
|
||||||
state->whave = state->wsize;
|
state->whave = state->wsize;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dist = state->wsize - state->wnext;
|
dist = state->wsize - state->wnext;
|
||||||
if (dist > copy) dist = copy;
|
if (dist > copy) dist = copy;
|
||||||
zmemcpy(state->window + state->wnext, strm->next_out - copy, dist);
|
zmemcpy(state->window + state->wnext, end - copy, dist);
|
||||||
copy -= dist;
|
copy -= dist;
|
||||||
if (copy) {
|
if (copy) {
|
||||||
zmemcpy(state->window, strm->next_out - copy, copy);
|
zmemcpy(state->window, end - copy, copy);
|
||||||
state->wnext = copy;
|
state->wnext = copy;
|
||||||
state->whave = state->wsize;
|
state->whave = state->wsize;
|
||||||
}
|
}
|
||||||
|
@ -499,11 +520,6 @@ unsigned out;
|
||||||
bits -= bits & 7; \
|
bits -= bits & 7; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/* Reverse the bytes in a 32-bit value */
|
|
||||||
#define REVERSE(q) \
|
|
||||||
((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
|
|
||||||
(((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
inflate() uses a state machine to process as much input data and generate as
|
inflate() uses a state machine to process as much input data and generate as
|
||||||
much output data as possible before returning. The state machine is
|
much output data as possible before returning. The state machine is
|
||||||
|
@ -591,7 +607,7 @@ z_streamp strm;
|
||||||
int flush;
|
int flush;
|
||||||
{
|
{
|
||||||
struct inflate_state FAR *state;
|
struct inflate_state FAR *state;
|
||||||
unsigned char FAR *next; /* next input */
|
z_const unsigned char FAR *next; /* next input */
|
||||||
unsigned char FAR *put; /* next output */
|
unsigned char FAR *put; /* next output */
|
||||||
unsigned have, left; /* available input and output */
|
unsigned have, left; /* available input and output */
|
||||||
unsigned long hold; /* bit buffer */
|
unsigned long hold; /* bit buffer */
|
||||||
|
@ -797,7 +813,7 @@ int flush;
|
||||||
#endif
|
#endif
|
||||||
case DICTID:
|
case DICTID:
|
||||||
NEEDBITS(32);
|
NEEDBITS(32);
|
||||||
strm->adler = state->check = REVERSE(hold);
|
strm->adler = state->check = ZSWAP32(hold);
|
||||||
INITBITS();
|
INITBITS();
|
||||||
state->mode = DICT;
|
state->mode = DICT;
|
||||||
case DICT:
|
case DICT:
|
||||||
|
@ -905,7 +921,7 @@ int flush;
|
||||||
while (state->have < 19)
|
while (state->have < 19)
|
||||||
state->lens[order[state->have++]] = 0;
|
state->lens[order[state->have++]] = 0;
|
||||||
state->next = state->codes;
|
state->next = state->codes;
|
||||||
state->lencode = (code const FAR *)(state->next);
|
state->lencode = (const code FAR *)(state->next);
|
||||||
state->lenbits = 7;
|
state->lenbits = 7;
|
||||||
ret = inflate_table(CODES, state->lens, 19, &(state->next),
|
ret = inflate_table(CODES, state->lens, 19, &(state->next),
|
||||||
&(state->lenbits), state->work);
|
&(state->lenbits), state->work);
|
||||||
|
@ -925,7 +941,6 @@ int flush;
|
||||||
PULLBYTE();
|
PULLBYTE();
|
||||||
}
|
}
|
||||||
if (here.val < 16) {
|
if (here.val < 16) {
|
||||||
NEEDBITS(here.bits);
|
|
||||||
DROPBITS(here.bits);
|
DROPBITS(here.bits);
|
||||||
state->lens[state->have++] = here.val;
|
state->lens[state->have++] = here.val;
|
||||||
}
|
}
|
||||||
|
@ -980,7 +995,7 @@ int flush;
|
||||||
values here (9 and 6) without reading the comments in inftrees.h
|
values here (9 and 6) without reading the comments in inftrees.h
|
||||||
concerning the ENOUGH constants, which depend on those values */
|
concerning the ENOUGH constants, which depend on those values */
|
||||||
state->next = state->codes;
|
state->next = state->codes;
|
||||||
state->lencode = (code const FAR *)(state->next);
|
state->lencode = (const code FAR *)(state->next);
|
||||||
state->lenbits = 9;
|
state->lenbits = 9;
|
||||||
ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
|
ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
|
||||||
&(state->lenbits), state->work);
|
&(state->lenbits), state->work);
|
||||||
|
@ -989,7 +1004,7 @@ int flush;
|
||||||
state->mode = BAD;
|
state->mode = BAD;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
state->distcode = (code const FAR *)(state->next);
|
state->distcode = (const code FAR *)(state->next);
|
||||||
state->distbits = 6;
|
state->distbits = 6;
|
||||||
ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
|
ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
|
||||||
&(state->next), &(state->distbits), state->work);
|
&(state->next), &(state->distbits), state->work);
|
||||||
|
@ -1170,7 +1185,7 @@ int flush;
|
||||||
#ifdef GUNZIP
|
#ifdef GUNZIP
|
||||||
state->flags ? hold :
|
state->flags ? hold :
|
||||||
#endif
|
#endif
|
||||||
REVERSE(hold)) != state->check) {
|
ZSWAP32(hold)) != state->check) {
|
||||||
strm->msg = (char *)"incorrect data check";
|
strm->msg = (char *)"incorrect data check";
|
||||||
state->mode = BAD;
|
state->mode = BAD;
|
||||||
break;
|
break;
|
||||||
|
@ -1214,8 +1229,9 @@ int flush;
|
||||||
*/
|
*/
|
||||||
inf_leave:
|
inf_leave:
|
||||||
RESTORE();
|
RESTORE();
|
||||||
if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
|
if (state->wsize || (out != strm->avail_out && state->mode < BAD &&
|
||||||
if (updatewindow(strm, out)) {
|
(state->mode < CHECK || flush != Z_FINISH)))
|
||||||
|
if (updatewindow(strm, strm->next_out, out - strm->avail_out)) {
|
||||||
state->mode = MEM;
|
state->mode = MEM;
|
||||||
return Z_MEM_ERROR;
|
return Z_MEM_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -1249,13 +1265,37 @@ z_streamp strm;
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength)
|
||||||
|
z_streamp strm;
|
||||||
|
Bytef *dictionary;
|
||||||
|
uInt *dictLength;
|
||||||
|
{
|
||||||
|
struct inflate_state FAR *state;
|
||||||
|
|
||||||
|
/* check state */
|
||||||
|
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
||||||
|
state = (struct inflate_state FAR *)strm->state;
|
||||||
|
|
||||||
|
/* copy dictionary */
|
||||||
|
if (state->whave && dictionary != Z_NULL) {
|
||||||
|
zmemcpy(dictionary, state->window + state->wnext,
|
||||||
|
state->whave - state->wnext);
|
||||||
|
zmemcpy(dictionary + state->whave - state->wnext,
|
||||||
|
state->window, state->wnext);
|
||||||
|
}
|
||||||
|
if (dictLength != Z_NULL)
|
||||||
|
*dictLength = state->whave;
|
||||||
|
return Z_OK;
|
||||||
|
}
|
||||||
|
|
||||||
int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
|
int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
|
||||||
z_streamp strm;
|
z_streamp strm;
|
||||||
const Bytef *dictionary;
|
const Bytef *dictionary;
|
||||||
uInt dictLength;
|
uInt dictLength;
|
||||||
{
|
{
|
||||||
struct inflate_state FAR *state;
|
struct inflate_state FAR *state;
|
||||||
unsigned long id;
|
unsigned long dictid;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* check state */
|
/* check state */
|
||||||
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
||||||
|
@ -1263,29 +1303,21 @@ uInt dictLength;
|
||||||
if (state->wrap != 0 && state->mode != DICT)
|
if (state->wrap != 0 && state->mode != DICT)
|
||||||
return Z_STREAM_ERROR;
|
return Z_STREAM_ERROR;
|
||||||
|
|
||||||
/* check for correct dictionary id */
|
/* check for correct dictionary identifier */
|
||||||
if (state->mode == DICT) {
|
if (state->mode == DICT) {
|
||||||
id = adler32(0L, Z_NULL, 0);
|
dictid = adler32(0L, Z_NULL, 0);
|
||||||
id = adler32(id, dictionary, dictLength);
|
dictid = adler32(dictid, dictionary, dictLength);
|
||||||
if (id != state->check)
|
if (dictid != state->check)
|
||||||
return Z_DATA_ERROR;
|
return Z_DATA_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy dictionary to window */
|
/* copy dictionary to window using updatewindow(), which will amend the
|
||||||
if (updatewindow(strm, strm->avail_out)) {
|
existing dictionary if appropriate */
|
||||||
|
ret = updatewindow(strm, dictionary + dictLength, dictLength);
|
||||||
|
if (ret) {
|
||||||
state->mode = MEM;
|
state->mode = MEM;
|
||||||
return Z_MEM_ERROR;
|
return Z_MEM_ERROR;
|
||||||
}
|
}
|
||||||
if (dictLength > state->wsize) {
|
|
||||||
zmemcpy(state->window, dictionary + dictLength - state->wsize,
|
|
||||||
state->wsize);
|
|
||||||
state->whave = state->wsize;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
zmemcpy(state->window + state->wsize - dictLength, dictionary,
|
|
||||||
dictLength);
|
|
||||||
state->whave = dictLength;
|
|
||||||
}
|
|
||||||
state->havedict = 1;
|
state->havedict = 1;
|
||||||
Tracev((stderr, "inflate: dictionary set\n"));
|
Tracev((stderr, "inflate: dictionary set\n"));
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
|
@ -1321,7 +1353,7 @@ gz_headerp head;
|
||||||
*/
|
*/
|
||||||
local unsigned syncsearch(have, buf, len)
|
local unsigned syncsearch(have, buf, len)
|
||||||
unsigned FAR *have;
|
unsigned FAR *have;
|
||||||
unsigned char FAR *buf;
|
const unsigned char FAR *buf;
|
||||||
unsigned len;
|
unsigned len;
|
||||||
{
|
{
|
||||||
unsigned got;
|
unsigned got;
|
||||||
|
@ -1433,8 +1465,8 @@ z_streamp source;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy state */
|
/* copy state */
|
||||||
zmemcpy(dest, source, sizeof(z_stream));
|
zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
|
||||||
zmemcpy(copy, state, sizeof(struct inflate_state));
|
zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state));
|
||||||
if (state->lencode >= state->codes &&
|
if (state->lencode >= state->codes &&
|
||||||
state->lencode <= state->codes + ENOUGH - 1) {
|
state->lencode <= state->codes + ENOUGH - 1) {
|
||||||
copy->lencode = copy->codes + (state->lencode - state->codes);
|
copy->lencode = copy->codes + (state->lencode - state->codes);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* inftrees.c -- generate Huffman trees for efficient decoding
|
/* inftrees.c -- generate Huffman trees for efficient decoding
|
||||||
* Copyright (C) 1995-2010 Mark Adler
|
* Copyright (C) 1995-2013 Mark Adler
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
#define MAXBITS 15
|
#define MAXBITS 15
|
||||||
|
|
||||||
const char inflate_copyright[] =
|
const char inflate_copyright[] =
|
||||||
" inflate 1.2.5 Copyright 1995-2010 Mark Adler ";
|
" inflate 1.2.8 Copyright 1995-2013 Mark Adler ";
|
||||||
/*
|
/*
|
||||||
If you use the zlib library in a product, an acknowledgment is welcome
|
If you use the zlib library in a product, an acknowledgment is welcome
|
||||||
in the documentation of your product. If for some reason you cannot
|
in the documentation of your product. If for some reason you cannot
|
||||||
|
@ -62,7 +62,7 @@ unsigned short FAR *work;
|
||||||
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
|
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
|
||||||
static const unsigned short lext[31] = { /* Length codes 257..285 extra */
|
static const unsigned short lext[31] = { /* Length codes 257..285 extra */
|
||||||
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
|
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
|
||||||
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 73, 195};
|
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78};
|
||||||
static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
|
static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
|
||||||
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
|
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
|
||||||
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
|
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
|
||||||
|
@ -208,8 +208,8 @@ unsigned short FAR *work;
|
||||||
mask = used - 1; /* mask for comparing low */
|
mask = used - 1; /* mask for comparing low */
|
||||||
|
|
||||||
/* check available table space */
|
/* check available table space */
|
||||||
if ((type == LENS && used >= ENOUGH_LENS) ||
|
if ((type == LENS && used > ENOUGH_LENS) ||
|
||||||
(type == DISTS && used >= ENOUGH_DISTS))
|
(type == DISTS && used > ENOUGH_DISTS))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* process all codes and make table entries */
|
/* process all codes and make table entries */
|
||||||
|
@ -277,8 +277,8 @@ unsigned short FAR *work;
|
||||||
|
|
||||||
/* check for enough space */
|
/* check for enough space */
|
||||||
used += 1U << curr;
|
used += 1U << curr;
|
||||||
if ((type == LENS && used >= ENOUGH_LENS) ||
|
if ((type == LENS && used > ENOUGH_LENS) ||
|
||||||
(type == DISTS && used >= ENOUGH_DISTS))
|
(type == DISTS && used > ENOUGH_DISTS))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* point entry in root table to sub-table */
|
/* point entry in root table to sub-table */
|
||||||
|
@ -289,38 +289,14 @@ unsigned short FAR *work;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* fill in remaining table entry if code is incomplete (guaranteed to have
|
||||||
Fill in rest of table for incomplete codes. This loop is similar to the
|
at most one remaining entry, since if the code is incomplete, the
|
||||||
loop above in incrementing huff for table indices. It is assumed that
|
maximum code length that was allowed to get this far is one bit) */
|
||||||
len is equal to curr + drop, so there is no loop needed to increment
|
if (huff != 0) {
|
||||||
through high index bits. When the current sub-table is filled, the loop
|
here.op = (unsigned char)64; /* invalid code marker */
|
||||||
drops back to the root table to fill in any remaining entries there.
|
here.bits = (unsigned char)(len - drop);
|
||||||
*/
|
here.val = (unsigned short)0;
|
||||||
here.op = (unsigned char)64; /* invalid code marker */
|
next[huff] = here;
|
||||||
here.bits = (unsigned char)(len - drop);
|
|
||||||
here.val = (unsigned short)0;
|
|
||||||
while (huff != 0) {
|
|
||||||
/* when done with sub-table, drop back to root table */
|
|
||||||
if (drop != 0 && (huff & mask) != low) {
|
|
||||||
drop = 0;
|
|
||||||
len = root;
|
|
||||||
next = *table;
|
|
||||||
here.bits = (unsigned char)len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* put invalid code marker in table */
|
|
||||||
next[huff >> drop] = here;
|
|
||||||
|
|
||||||
/* backwards increment the len-bit code huff */
|
|
||||||
incr = 1U << (len - 1);
|
|
||||||
while (huff & incr)
|
|
||||||
incr >>= 1;
|
|
||||||
if (incr != 0) {
|
|
||||||
huff &= incr - 1;
|
|
||||||
huff += incr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
huff = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set return parameters */
|
/* set return parameters */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* trees.c -- output deflated data using Huffman coding
|
/* trees.c -- output deflated data using Huffman coding
|
||||||
* Copyright (C) 1995-2010 Jean-loup Gailly
|
* Copyright (C) 1995-2012 Jean-loup Gailly
|
||||||
* detect_data_type() function provided freely by Cosmin Truta, 2006
|
* detect_data_type() function provided freely by Cosmin Truta, 2006
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
*/
|
*/
|
||||||
|
@ -74,11 +74,6 @@ local const uch bl_order[BL_CODES]
|
||||||
* probability, to avoid transmitting the lengths for unused bit length codes.
|
* probability, to avoid transmitting the lengths for unused bit length codes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define Buf_size (8 * 2*sizeof(char))
|
|
||||||
/* Number of bits used within bi_buf. (bi_buf might be implemented on
|
|
||||||
* more than 16 bits on some systems.)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Local data. These are initialized only once.
|
* Local data. These are initialized only once.
|
||||||
*/
|
*/
|
||||||
|
@ -151,8 +146,8 @@ local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
|
||||||
local int build_bl_tree OF((deflate_state *s));
|
local int build_bl_tree OF((deflate_state *s));
|
||||||
local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
|
local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
|
||||||
int blcodes));
|
int blcodes));
|
||||||
local void compress_block OF((deflate_state *s, ct_data *ltree,
|
local void compress_block OF((deflate_state *s, const ct_data *ltree,
|
||||||
ct_data *dtree));
|
const ct_data *dtree));
|
||||||
local int detect_data_type OF((deflate_state *s));
|
local int detect_data_type OF((deflate_state *s));
|
||||||
local unsigned bi_reverse OF((unsigned value, int length));
|
local unsigned bi_reverse OF((unsigned value, int length));
|
||||||
local void bi_windup OF((deflate_state *s));
|
local void bi_windup OF((deflate_state *s));
|
||||||
|
@ -399,7 +394,6 @@ void ZLIB_INTERNAL _tr_init(s)
|
||||||
|
|
||||||
s->bi_buf = 0;
|
s->bi_buf = 0;
|
||||||
s->bi_valid = 0;
|
s->bi_valid = 0;
|
||||||
s->last_eob_len = 8; /* enough lookahead for inflate */
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
s->compressed_len = 0L;
|
s->compressed_len = 0L;
|
||||||
s->bits_sent = 0L;
|
s->bits_sent = 0L;
|
||||||
|
@ -882,16 +876,18 @@ void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
|
||||||
copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
|
copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ===========================================================================
|
||||||
|
* Flush the bits in the bit buffer to pending output (leaves at most 7 bits)
|
||||||
|
*/
|
||||||
|
void ZLIB_INTERNAL _tr_flush_bits(s)
|
||||||
|
deflate_state *s;
|
||||||
|
{
|
||||||
|
bi_flush(s);
|
||||||
|
}
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Send one empty static block to give enough lookahead for inflate.
|
* Send one empty static block to give enough lookahead for inflate.
|
||||||
* This takes 10 bits, of which 7 may remain in the bit buffer.
|
* This takes 10 bits, of which 7 may remain in the bit buffer.
|
||||||
* The current inflate code requires 9 bits of lookahead. If the
|
|
||||||
* last two codes for the previous block (real code plus EOB) were coded
|
|
||||||
* on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
|
|
||||||
* the last real code. In this case we send two empty static blocks instead
|
|
||||||
* of one. (There are no problems if the previous block is stored or fixed.)
|
|
||||||
* To simplify the code, we assume the worst case of last real code encoded
|
|
||||||
* on one bit only.
|
|
||||||
*/
|
*/
|
||||||
void ZLIB_INTERNAL _tr_align(s)
|
void ZLIB_INTERNAL _tr_align(s)
|
||||||
deflate_state *s;
|
deflate_state *s;
|
||||||
|
@ -902,20 +898,6 @@ void ZLIB_INTERNAL _tr_align(s)
|
||||||
s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
|
s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
|
||||||
#endif
|
#endif
|
||||||
bi_flush(s);
|
bi_flush(s);
|
||||||
/* Of the 10 bits for the empty block, we have already sent
|
|
||||||
* (10 - bi_valid) bits. The lookahead for the last real code (before
|
|
||||||
* the EOB of the previous block) was thus at least one plus the length
|
|
||||||
* of the EOB plus what we have just sent of the empty static block.
|
|
||||||
*/
|
|
||||||
if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
|
|
||||||
send_bits(s, STATIC_TREES<<1, 3);
|
|
||||||
send_code(s, END_BLOCK, static_ltree);
|
|
||||||
#ifdef DEBUG
|
|
||||||
s->compressed_len += 10L;
|
|
||||||
#endif
|
|
||||||
bi_flush(s);
|
|
||||||
}
|
|
||||||
s->last_eob_len = 7;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
|
@ -990,7 +972,8 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
|
||||||
} else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
|
} else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
|
||||||
#endif
|
#endif
|
||||||
send_bits(s, (STATIC_TREES<<1)+last, 3);
|
send_bits(s, (STATIC_TREES<<1)+last, 3);
|
||||||
compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
|
compress_block(s, (const ct_data *)static_ltree,
|
||||||
|
(const ct_data *)static_dtree);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
s->compressed_len += 3 + s->static_len;
|
s->compressed_len += 3 + s->static_len;
|
||||||
#endif
|
#endif
|
||||||
|
@ -998,7 +981,8 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
|
||||||
send_bits(s, (DYN_TREES<<1)+last, 3);
|
send_bits(s, (DYN_TREES<<1)+last, 3);
|
||||||
send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
|
send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
|
||||||
max_blindex+1);
|
max_blindex+1);
|
||||||
compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
|
compress_block(s, (const ct_data *)s->dyn_ltree,
|
||||||
|
(const ct_data *)s->dyn_dtree);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
s->compressed_len += 3 + s->opt_len;
|
s->compressed_len += 3 + s->opt_len;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1075,8 +1059,8 @@ int ZLIB_INTERNAL _tr_tally (s, dist, lc)
|
||||||
*/
|
*/
|
||||||
local void compress_block(s, ltree, dtree)
|
local void compress_block(s, ltree, dtree)
|
||||||
deflate_state *s;
|
deflate_state *s;
|
||||||
ct_data *ltree; /* literal tree */
|
const ct_data *ltree; /* literal tree */
|
||||||
ct_data *dtree; /* distance tree */
|
const ct_data *dtree; /* distance tree */
|
||||||
{
|
{
|
||||||
unsigned dist; /* distance of matched string */
|
unsigned dist; /* distance of matched string */
|
||||||
int lc; /* match length or unmatched char (if dist == 0) */
|
int lc; /* match length or unmatched char (if dist == 0) */
|
||||||
|
@ -1118,7 +1102,6 @@ local void compress_block(s, ltree, dtree)
|
||||||
} while (lx < s->last_lit);
|
} while (lx < s->last_lit);
|
||||||
|
|
||||||
send_code(s, END_BLOCK, ltree);
|
send_code(s, END_BLOCK, ltree);
|
||||||
s->last_eob_len = ltree[END_BLOCK].Len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
|
@ -1226,7 +1209,6 @@ local void copy_block(s, buf, len, header)
|
||||||
int header; /* true if block header must be written */
|
int header; /* true if block header must be written */
|
||||||
{
|
{
|
||||||
bi_windup(s); /* align on byte boundary */
|
bi_windup(s); /* align on byte boundary */
|
||||||
s->last_eob_len = 8; /* enough lookahead for inflate */
|
|
||||||
|
|
||||||
if (header) {
|
if (header) {
|
||||||
put_short(s, (ush)len);
|
put_short(s, (ush)len);
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
/* uncompr.c -- decompress a memory buffer
|
||||||
|
* Copyright (C) 1995-2003, 2010 Jean-loup Gailly.
|
||||||
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* @(#) $Id$ */
|
||||||
|
|
||||||
|
#define ZLIB_INTERNAL
|
||||||
|
#include "zlib.h"
|
||||||
|
|
||||||
|
/* ===========================================================================
|
||||||
|
Decompresses the source buffer into the destination buffer. sourceLen is
|
||||||
|
the byte length of the source buffer. Upon entry, destLen is the total
|
||||||
|
size of the destination buffer, which must be large enough to hold the
|
||||||
|
entire uncompressed data. (The size of the uncompressed data must have
|
||||||
|
been saved previously by the compressor and transmitted to the decompressor
|
||||||
|
by some mechanism outside the scope of this compression library.)
|
||||||
|
Upon exit, destLen is the actual size of the compressed buffer.
|
||||||
|
|
||||||
|
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
|
||||||
|
enough memory, Z_BUF_ERROR if there was not enough room in the output
|
||||||
|
buffer, or Z_DATA_ERROR if the input data was corrupted.
|
||||||
|
*/
|
||||||
|
int ZEXPORT uncompress (dest, destLen, source, sourceLen)
|
||||||
|
Bytef *dest;
|
||||||
|
uLongf *destLen;
|
||||||
|
const Bytef *source;
|
||||||
|
uLong sourceLen;
|
||||||
|
{
|
||||||
|
z_stream stream;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
stream.next_in = (z_const Bytef *)source;
|
||||||
|
stream.avail_in = (uInt)sourceLen;
|
||||||
|
/* Check for source > 64K on 16-bit machine: */
|
||||||
|
if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
|
||||||
|
|
||||||
|
stream.next_out = dest;
|
||||||
|
stream.avail_out = (uInt)*destLen;
|
||||||
|
if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
|
||||||
|
|
||||||
|
stream.zalloc = (alloc_func)0;
|
||||||
|
stream.zfree = (free_func)0;
|
||||||
|
|
||||||
|
err = inflateInit(&stream);
|
||||||
|
if (err != Z_OK) return err;
|
||||||
|
|
||||||
|
err = inflate(&stream, Z_FINISH);
|
||||||
|
if (err != Z_STREAM_END) {
|
||||||
|
inflateEnd(&stream);
|
||||||
|
if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
|
||||||
|
return Z_DATA_ERROR;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
*destLen = stream.total_out;
|
||||||
|
|
||||||
|
err = inflateEnd(&stream);
|
||||||
|
return err;
|
||||||
|
}
|
|
@ -0,0 +1,397 @@
|
||||||
|
|
||||||
|
Frequently Asked Questions about ZLIB1.DLL
|
||||||
|
|
||||||
|
|
||||||
|
This document describes the design, the rationale, and the usage
|
||||||
|
of the official DLL build of zlib, named ZLIB1.DLL. If you have
|
||||||
|
general questions about zlib, you should see the file "FAQ" found
|
||||||
|
in the zlib distribution, or at the following location:
|
||||||
|
http://www.gzip.org/zlib/zlib_faq.html
|
||||||
|
|
||||||
|
|
||||||
|
1. What is ZLIB1.DLL, and how can I get it?
|
||||||
|
|
||||||
|
- ZLIB1.DLL is the official build of zlib as a DLL.
|
||||||
|
(Please remark the character '1' in the name.)
|
||||||
|
|
||||||
|
Pointers to a precompiled ZLIB1.DLL can be found in the zlib
|
||||||
|
web site at:
|
||||||
|
http://www.zlib.net/
|
||||||
|
|
||||||
|
Applications that link to ZLIB1.DLL can rely on the following
|
||||||
|
specification:
|
||||||
|
|
||||||
|
* The exported symbols are exclusively defined in the source
|
||||||
|
files "zlib.h" and "zlib.def", found in an official zlib
|
||||||
|
source distribution.
|
||||||
|
* The symbols are exported by name, not by ordinal.
|
||||||
|
* The exported names are undecorated.
|
||||||
|
* The calling convention of functions is "C" (CDECL).
|
||||||
|
* The ZLIB1.DLL binary is linked to MSVCRT.DLL.
|
||||||
|
|
||||||
|
The archive in which ZLIB1.DLL is bundled contains compiled
|
||||||
|
test programs that must run with a valid build of ZLIB1.DLL.
|
||||||
|
It is recommended to download the prebuilt DLL from the zlib
|
||||||
|
web site, instead of building it yourself, to avoid potential
|
||||||
|
incompatibilities that could be introduced by your compiler
|
||||||
|
and build settings. If you do build the DLL yourself, please
|
||||||
|
make sure that it complies with all the above requirements,
|
||||||
|
and it runs with the precompiled test programs, bundled with
|
||||||
|
the original ZLIB1.DLL distribution.
|
||||||
|
|
||||||
|
If, for any reason, you need to build an incompatible DLL,
|
||||||
|
please use a different file name.
|
||||||
|
|
||||||
|
|
||||||
|
2. Why did you change the name of the DLL to ZLIB1.DLL?
|
||||||
|
What happened to the old ZLIB.DLL?
|
||||||
|
|
||||||
|
- The old ZLIB.DLL, built from zlib-1.1.4 or earlier, required
|
||||||
|
compilation settings that were incompatible to those used by
|
||||||
|
a static build. The DLL settings were supposed to be enabled
|
||||||
|
by defining the macro ZLIB_DLL, before including "zlib.h".
|
||||||
|
Incorrect handling of this macro was silently accepted at
|
||||||
|
build time, resulting in two major problems:
|
||||||
|
|
||||||
|
* ZLIB_DLL was missing from the old makefile. When building
|
||||||
|
the DLL, not all people added it to the build options. In
|
||||||
|
consequence, incompatible incarnations of ZLIB.DLL started
|
||||||
|
to circulate around the net.
|
||||||
|
|
||||||
|
* When switching from using the static library to using the
|
||||||
|
DLL, applications had to define the ZLIB_DLL macro and
|
||||||
|
to recompile all the sources that contained calls to zlib
|
||||||
|
functions. Failure to do so resulted in creating binaries
|
||||||
|
that were unable to run with the official ZLIB.DLL build.
|
||||||
|
|
||||||
|
The only possible solution that we could foresee was to make
|
||||||
|
a binary-incompatible change in the DLL interface, in order to
|
||||||
|
remove the dependency on the ZLIB_DLL macro, and to release
|
||||||
|
the new DLL under a different name.
|
||||||
|
|
||||||
|
We chose the name ZLIB1.DLL, where '1' indicates the major
|
||||||
|
zlib version number. We hope that we will not have to break
|
||||||
|
the binary compatibility again, at least not as long as the
|
||||||
|
zlib-1.x series will last.
|
||||||
|
|
||||||
|
There is still a ZLIB_DLL macro, that can trigger a more
|
||||||
|
efficient build and use of the DLL, but compatibility no
|
||||||
|
longer dependents on it.
|
||||||
|
|
||||||
|
|
||||||
|
3. Can I build ZLIB.DLL from the new zlib sources, and replace
|
||||||
|
an old ZLIB.DLL, that was built from zlib-1.1.4 or earlier?
|
||||||
|
|
||||||
|
- In principle, you can do it by assigning calling convention
|
||||||
|
keywords to the macros ZEXPORT and ZEXPORTVA. In practice,
|
||||||
|
it depends on what you mean by "an old ZLIB.DLL", because the
|
||||||
|
old DLL exists in several mutually-incompatible versions.
|
||||||
|
You have to find out first what kind of calling convention is
|
||||||
|
being used in your particular ZLIB.DLL build, and to use the
|
||||||
|
same one in the new build. If you don't know what this is all
|
||||||
|
about, you might be better off if you would just leave the old
|
||||||
|
DLL intact.
|
||||||
|
|
||||||
|
|
||||||
|
4. Can I compile my application using the new zlib interface, and
|
||||||
|
link it to an old ZLIB.DLL, that was built from zlib-1.1.4 or
|
||||||
|
earlier?
|
||||||
|
|
||||||
|
- The official answer is "no"; the real answer depends again on
|
||||||
|
what kind of ZLIB.DLL you have. Even if you are lucky, this
|
||||||
|
course of action is unreliable.
|
||||||
|
|
||||||
|
If you rebuild your application and you intend to use a newer
|
||||||
|
version of zlib (post- 1.1.4), it is strongly recommended to
|
||||||
|
link it to the new ZLIB1.DLL.
|
||||||
|
|
||||||
|
|
||||||
|
5. Why are the zlib symbols exported by name, and not by ordinal?
|
||||||
|
|
||||||
|
- Although exporting symbols by ordinal is a little faster, it
|
||||||
|
is risky. Any single glitch in the maintenance or use of the
|
||||||
|
DEF file that contains the ordinals can result in incompatible
|
||||||
|
builds and frustrating crashes. Simply put, the benefits of
|
||||||
|
exporting symbols by ordinal do not justify the risks.
|
||||||
|
|
||||||
|
Technically, it should be possible to maintain ordinals in
|
||||||
|
the DEF file, and still export the symbols by name. Ordinals
|
||||||
|
exist in every DLL, and even if the dynamic linking performed
|
||||||
|
at the DLL startup is searching for names, ordinals serve as
|
||||||
|
hints, for a faster name lookup. However, if the DEF file
|
||||||
|
contains ordinals, the Microsoft linker automatically builds
|
||||||
|
an implib that will cause the executables linked to it to use
|
||||||
|
those ordinals, and not the names. It is interesting to
|
||||||
|
notice that the GNU linker for Win32 does not suffer from this
|
||||||
|
problem.
|
||||||
|
|
||||||
|
It is possible to avoid the DEF file if the exported symbols
|
||||||
|
are accompanied by a "__declspec(dllexport)" attribute in the
|
||||||
|
source files. You can do this in zlib by predefining the
|
||||||
|
ZLIB_DLL macro.
|
||||||
|
|
||||||
|
|
||||||
|
6. I see that the ZLIB1.DLL functions use the "C" (CDECL) calling
|
||||||
|
convention. Why not use the STDCALL convention?
|
||||||
|
STDCALL is the standard convention in Win32, and I need it in
|
||||||
|
my Visual Basic project!
|
||||||
|
|
||||||
|
(For readability, we use CDECL to refer to the convention
|
||||||
|
triggered by the "__cdecl" keyword, STDCALL to refer to
|
||||||
|
the convention triggered by "__stdcall", and FASTCALL to
|
||||||
|
refer to the convention triggered by "__fastcall".)
|
||||||
|
|
||||||
|
- Most of the native Windows API functions (without varargs) use
|
||||||
|
indeed the WINAPI convention (which translates to STDCALL in
|
||||||
|
Win32), but the standard C functions use CDECL. If a user
|
||||||
|
application is intrinsically tied to the Windows API (e.g.
|
||||||
|
it calls native Windows API functions such as CreateFile()),
|
||||||
|
sometimes it makes sense to decorate its own functions with
|
||||||
|
WINAPI. But if ANSI C or POSIX portability is a goal (e.g.
|
||||||
|
it calls standard C functions such as fopen()), it is not a
|
||||||
|
sound decision to request the inclusion of <windows.h>, or to
|
||||||
|
use non-ANSI constructs, for the sole purpose to make the user
|
||||||
|
functions STDCALL-able.
|
||||||
|
|
||||||
|
The functionality offered by zlib is not in the category of
|
||||||
|
"Windows functionality", but is more like "C functionality".
|
||||||
|
|
||||||
|
Technically, STDCALL is not bad; in fact, it is slightly
|
||||||
|
faster than CDECL, and it works with variable-argument
|
||||||
|
functions, just like CDECL. It is unfortunate that, in spite
|
||||||
|
of using STDCALL in the Windows API, it is not the default
|
||||||
|
convention used by the C compilers that run under Windows.
|
||||||
|
The roots of the problem reside deep inside the unsafety of
|
||||||
|
the K&R-style function prototypes, where the argument types
|
||||||
|
are not specified; but that is another story for another day.
|
||||||
|
|
||||||
|
The remaining fact is that CDECL is the default convention.
|
||||||
|
Even if an explicit convention is hard-coded into the function
|
||||||
|
prototypes inside C headers, problems may appear. The
|
||||||
|
necessity to expose the convention in users' callbacks is one
|
||||||
|
of these problems.
|
||||||
|
|
||||||
|
The calling convention issues are also important when using
|
||||||
|
zlib in other programming languages. Some of them, like Ada
|
||||||
|
(GNAT) and Fortran (GNU G77), have C bindings implemented
|
||||||
|
initially on Unix, and relying on the C calling convention.
|
||||||
|
On the other hand, the pre- .NET versions of Microsoft Visual
|
||||||
|
Basic require STDCALL, while Borland Delphi prefers, although
|
||||||
|
it does not require, FASTCALL.
|
||||||
|
|
||||||
|
In fairness to all possible uses of zlib outside the C
|
||||||
|
programming language, we choose the default "C" convention.
|
||||||
|
Anyone interested in different bindings or conventions is
|
||||||
|
encouraged to maintain specialized projects. The "contrib/"
|
||||||
|
directory from the zlib distribution already holds a couple
|
||||||
|
of foreign bindings, such as Ada, C++, and Delphi.
|
||||||
|
|
||||||
|
|
||||||
|
7. I need a DLL for my Visual Basic project. What can I do?
|
||||||
|
|
||||||
|
- Define the ZLIB_WINAPI macro before including "zlib.h", when
|
||||||
|
building both the DLL and the user application (except that
|
||||||
|
you don't need to define anything when using the DLL in Visual
|
||||||
|
Basic). The ZLIB_WINAPI macro will switch on the WINAPI
|
||||||
|
(STDCALL) convention. The name of this DLL must be different
|
||||||
|
than the official ZLIB1.DLL.
|
||||||
|
|
||||||
|
Gilles Vollant has contributed a build named ZLIBWAPI.DLL,
|
||||||
|
with the ZLIB_WINAPI macro turned on, and with the minizip
|
||||||
|
functionality built in. For more information, please read
|
||||||
|
the notes inside "contrib/vstudio/readme.txt", found in the
|
||||||
|
zlib distribution.
|
||||||
|
|
||||||
|
|
||||||
|
8. I need to use zlib in my Microsoft .NET project. What can I
|
||||||
|
do?
|
||||||
|
|
||||||
|
- Henrik Ravn has contributed a .NET wrapper around zlib. Look
|
||||||
|
into contrib/dotzlib/, inside the zlib distribution.
|
||||||
|
|
||||||
|
|
||||||
|
9. If my application uses ZLIB1.DLL, should I link it to
|
||||||
|
MSVCRT.DLL? Why?
|
||||||
|
|
||||||
|
- It is not required, but it is recommended to link your
|
||||||
|
application to MSVCRT.DLL, if it uses ZLIB1.DLL.
|
||||||
|
|
||||||
|
The executables (.EXE, .DLL, etc.) that are involved in the
|
||||||
|
same process and are using the C run-time library (i.e. they
|
||||||
|
are calling standard C functions), must link to the same
|
||||||
|
library. There are several libraries in the Win32 system:
|
||||||
|
CRTDLL.DLL, MSVCRT.DLL, the static C libraries, etc.
|
||||||
|
Since ZLIB1.DLL is linked to MSVCRT.DLL, the executables that
|
||||||
|
depend on it should also be linked to MSVCRT.DLL.
|
||||||
|
|
||||||
|
|
||||||
|
10. Why are you saying that ZLIB1.DLL and my application should
|
||||||
|
be linked to the same C run-time (CRT) library? I linked my
|
||||||
|
application and my DLLs to different C libraries (e.g. my
|
||||||
|
application to a static library, and my DLLs to MSVCRT.DLL),
|
||||||
|
and everything works fine.
|
||||||
|
|
||||||
|
- If a user library invokes only pure Win32 API (accessible via
|
||||||
|
<windows.h> and the related headers), its DLL build will work
|
||||||
|
in any context. But if this library invokes standard C API,
|
||||||
|
things get more complicated.
|
||||||
|
|
||||||
|
There is a single Win32 library in a Win32 system. Every
|
||||||
|
function in this library resides in a single DLL module, that
|
||||||
|
is safe to call from anywhere. On the other hand, there are
|
||||||
|
multiple versions of the C library, and each of them has its
|
||||||
|
own separate internal state. Standalone executables and user
|
||||||
|
DLLs that call standard C functions must link to a C run-time
|
||||||
|
(CRT) library, be it static or shared (DLL). Intermixing
|
||||||
|
occurs when an executable (not necessarily standalone) and a
|
||||||
|
DLL are linked to different CRTs, and both are running in the
|
||||||
|
same process.
|
||||||
|
|
||||||
|
Intermixing multiple CRTs is possible, as long as their
|
||||||
|
internal states are kept intact. The Microsoft Knowledge Base
|
||||||
|
articles KB94248 "HOWTO: Use the C Run-Time" and KB140584
|
||||||
|
"HOWTO: Link with the Correct C Run-Time (CRT) Library"
|
||||||
|
mention the potential problems raised by intermixing.
|
||||||
|
|
||||||
|
If intermixing works for you, it's because your application
|
||||||
|
and DLLs are avoiding the corruption of each of the CRTs'
|
||||||
|
internal states, maybe by careful design, or maybe by fortune.
|
||||||
|
|
||||||
|
Also note that linking ZLIB1.DLL to non-Microsoft CRTs, such
|
||||||
|
as those provided by Borland, raises similar problems.
|
||||||
|
|
||||||
|
|
||||||
|
11. Why are you linking ZLIB1.DLL to MSVCRT.DLL?
|
||||||
|
|
||||||
|
- MSVCRT.DLL exists on every Windows 95 with a new service pack
|
||||||
|
installed, or with Microsoft Internet Explorer 4 or later, and
|
||||||
|
on all other Windows 4.x or later (Windows 98, Windows NT 4,
|
||||||
|
or later). It is freely distributable; if not present in the
|
||||||
|
system, it can be downloaded from Microsoft or from other
|
||||||
|
software provider for free.
|
||||||
|
|
||||||
|
The fact that MSVCRT.DLL does not exist on a virgin Windows 95
|
||||||
|
is not so problematic. Windows 95 is scarcely found nowadays,
|
||||||
|
Microsoft ended its support a long time ago, and many recent
|
||||||
|
applications from various vendors, including Microsoft, do not
|
||||||
|
even run on it. Furthermore, no serious user should run
|
||||||
|
Windows 95 without a proper update installed.
|
||||||
|
|
||||||
|
|
||||||
|
12. Why are you not linking ZLIB1.DLL to
|
||||||
|
<<my favorite C run-time library>> ?
|
||||||
|
|
||||||
|
- We considered and abandoned the following alternatives:
|
||||||
|
|
||||||
|
* Linking ZLIB1.DLL to a static C library (LIBC.LIB, or
|
||||||
|
LIBCMT.LIB) is not a good option. People are using the DLL
|
||||||
|
mainly to save disk space. If you are linking your program
|
||||||
|
to a static C library, you may as well consider linking zlib
|
||||||
|
in statically, too.
|
||||||
|
|
||||||
|
* Linking ZLIB1.DLL to CRTDLL.DLL looks appealing, because
|
||||||
|
CRTDLL.DLL is present on every Win32 installation.
|
||||||
|
Unfortunately, it has a series of problems: it does not
|
||||||
|
work properly with Microsoft's C++ libraries, it does not
|
||||||
|
provide support for 64-bit file offsets, (and so on...),
|
||||||
|
and Microsoft discontinued its support a long time ago.
|
||||||
|
|
||||||
|
* Linking ZLIB1.DLL to MSVCR70.DLL or MSVCR71.DLL, supplied
|
||||||
|
with the Microsoft .NET platform, and Visual C++ 7.0/7.1,
|
||||||
|
raises problems related to the status of ZLIB1.DLL as a
|
||||||
|
system component. According to the Microsoft Knowledge Base
|
||||||
|
article KB326922 "INFO: Redistribution of the Shared C
|
||||||
|
Runtime Component in Visual C++ .NET", MSVCR70.DLL and
|
||||||
|
MSVCR71.DLL are not supposed to function as system DLLs,
|
||||||
|
because they may clash with MSVCRT.DLL. Instead, the
|
||||||
|
application's installer is supposed to put these DLLs
|
||||||
|
(if needed) in the application's private directory.
|
||||||
|
If ZLIB1.DLL depends on a non-system runtime, it cannot
|
||||||
|
function as a redistributable system component.
|
||||||
|
|
||||||
|
* Linking ZLIB1.DLL to non-Microsoft runtimes, such as
|
||||||
|
Borland's, or Cygwin's, raises problems related to the
|
||||||
|
reliable presence of these runtimes on Win32 systems.
|
||||||
|
It's easier to let the DLL build of zlib up to the people
|
||||||
|
who distribute these runtimes, and who may proceed as
|
||||||
|
explained in the answer to Question 14.
|
||||||
|
|
||||||
|
|
||||||
|
13. If ZLIB1.DLL cannot be linked to MSVCR70.DLL or MSVCR71.DLL,
|
||||||
|
how can I build/use ZLIB1.DLL in Microsoft Visual C++ 7.0
|
||||||
|
(Visual Studio .NET) or newer?
|
||||||
|
|
||||||
|
- Due to the problems explained in the Microsoft Knowledge Base
|
||||||
|
article KB326922 (see the previous answer), the C runtime that
|
||||||
|
comes with the VC7 environment is no longer considered a
|
||||||
|
system component. That is, it should not be assumed that this
|
||||||
|
runtime exists, or may be installed in a system directory.
|
||||||
|
Since ZLIB1.DLL is supposed to be a system component, it may
|
||||||
|
not depend on a non-system component.
|
||||||
|
|
||||||
|
In order to link ZLIB1.DLL and your application to MSVCRT.DLL
|
||||||
|
in VC7, you need the library of Visual C++ 6.0 or older. If
|
||||||
|
you don't have this library at hand, it's probably best not to
|
||||||
|
use ZLIB1.DLL.
|
||||||
|
|
||||||
|
We are hoping that, in the future, Microsoft will provide a
|
||||||
|
way to build applications linked to a proper system runtime,
|
||||||
|
from the Visual C++ environment. Until then, you have a
|
||||||
|
couple of alternatives, such as linking zlib in statically.
|
||||||
|
If your application requires dynamic linking, you may proceed
|
||||||
|
as explained in the answer to Question 14.
|
||||||
|
|
||||||
|
|
||||||
|
14. I need to link my own DLL build to a CRT different than
|
||||||
|
MSVCRT.DLL. What can I do?
|
||||||
|
|
||||||
|
- Feel free to rebuild the DLL from the zlib sources, and link
|
||||||
|
it the way you want. You should, however, clearly state that
|
||||||
|
your build is unofficial. You should give it a different file
|
||||||
|
name, and/or install it in a private directory that can be
|
||||||
|
accessed by your application only, and is not visible to the
|
||||||
|
others (i.e. it's neither in the PATH, nor in the SYSTEM or
|
||||||
|
SYSTEM32 directories). Otherwise, your build may clash with
|
||||||
|
applications that link to the official build.
|
||||||
|
|
||||||
|
For example, in Cygwin, zlib is linked to the Cygwin runtime
|
||||||
|
CYGWIN1.DLL, and it is distributed under the name CYGZ.DLL.
|
||||||
|
|
||||||
|
|
||||||
|
15. May I include additional pieces of code that I find useful,
|
||||||
|
link them in ZLIB1.DLL, and export them?
|
||||||
|
|
||||||
|
- No. A legitimate build of ZLIB1.DLL must not include code
|
||||||
|
that does not originate from the official zlib source code.
|
||||||
|
But you can make your own private DLL build, under a different
|
||||||
|
file name, as suggested in the previous answer.
|
||||||
|
|
||||||
|
For example, zlib is a part of the VCL library, distributed
|
||||||
|
with Borland Delphi and C++ Builder. The DLL build of VCL
|
||||||
|
is a redistributable file, named VCLxx.DLL.
|
||||||
|
|
||||||
|
|
||||||
|
16. May I remove some functionality out of ZLIB1.DLL, by enabling
|
||||||
|
macros like NO_GZCOMPRESS or NO_GZIP at compile time?
|
||||||
|
|
||||||
|
- No. A legitimate build of ZLIB1.DLL must provide the complete
|
||||||
|
zlib functionality, as implemented in the official zlib source
|
||||||
|
code. But you can make your own private DLL build, under a
|
||||||
|
different file name, as suggested in the previous answer.
|
||||||
|
|
||||||
|
|
||||||
|
17. I made my own ZLIB1.DLL build. Can I test it for compliance?
|
||||||
|
|
||||||
|
- We prefer that you download the official DLL from the zlib
|
||||||
|
web site. If you need something peculiar from this DLL, you
|
||||||
|
can send your suggestion to the zlib mailing list.
|
||||||
|
|
||||||
|
However, in case you do rebuild the DLL yourself, you can run
|
||||||
|
it with the test programs found in the DLL distribution.
|
||||||
|
Running these test programs is not a guarantee of compliance,
|
||||||
|
but a failure can imply a detected problem.
|
||||||
|
|
||||||
|
**
|
||||||
|
|
||||||
|
This document is written and maintained by
|
||||||
|
Cosmin Truta <cosmint@cs.ubbcluj.ro>
|
|
@ -0,0 +1,110 @@
|
||||||
|
# Makefile for zlib
|
||||||
|
# Borland C++ for Win32
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# make -f win32/Makefile.bor
|
||||||
|
# make -f win32/Makefile.bor LOCAL_ZLIB=-DASMV OBJA=match.obj OBJPA=+match.obj
|
||||||
|
|
||||||
|
# ------------ Borland C++ ------------
|
||||||
|
|
||||||
|
# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7)
|
||||||
|
# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or
|
||||||
|
# added to the declaration of LOC here:
|
||||||
|
LOC = $(LOCAL_ZLIB)
|
||||||
|
|
||||||
|
CC = bcc32
|
||||||
|
AS = bcc32
|
||||||
|
LD = bcc32
|
||||||
|
AR = tlib
|
||||||
|
CFLAGS = -a -d -k- -O2 $(LOC)
|
||||||
|
ASFLAGS = $(LOC)
|
||||||
|
LDFLAGS = $(LOC)
|
||||||
|
|
||||||
|
|
||||||
|
# variables
|
||||||
|
ZLIB_LIB = zlib.lib
|
||||||
|
|
||||||
|
OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj
|
||||||
|
OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
|
||||||
|
#OBJA =
|
||||||
|
OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj
|
||||||
|
OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
|
||||||
|
#OBJPA=
|
||||||
|
|
||||||
|
|
||||||
|
# targets
|
||||||
|
all: $(ZLIB_LIB) example.exe minigzip.exe
|
||||||
|
|
||||||
|
.c.obj:
|
||||||
|
$(CC) -c $(CFLAGS) $<
|
||||||
|
|
||||||
|
.asm.obj:
|
||||||
|
$(AS) -c $(ASFLAGS) $<
|
||||||
|
|
||||||
|
adler32.obj: adler32.c zlib.h zconf.h
|
||||||
|
|
||||||
|
compress.obj: compress.c zlib.h zconf.h
|
||||||
|
|
||||||
|
crc32.obj: crc32.c zlib.h zconf.h crc32.h
|
||||||
|
|
||||||
|
deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
|
||||||
|
|
||||||
|
gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
|
||||||
|
|
||||||
|
gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
|
||||||
|
|
||||||
|
gzread.obj: gzread.c zlib.h zconf.h gzguts.h
|
||||||
|
|
||||||
|
gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
|
||||||
|
|
||||||
|
infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
|
||||||
|
inffast.h inffixed.h
|
||||||
|
|
||||||
|
inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
|
||||||
|
inffast.h
|
||||||
|
|
||||||
|
inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
|
||||||
|
inffast.h inffixed.h
|
||||||
|
|
||||||
|
inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
|
||||||
|
|
||||||
|
trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
|
||||||
|
|
||||||
|
uncompr.obj: uncompr.c zlib.h zconf.h
|
||||||
|
|
||||||
|
zutil.obj: zutil.c zutil.h zlib.h zconf.h
|
||||||
|
|
||||||
|
example.obj: test/example.c zlib.h zconf.h
|
||||||
|
|
||||||
|
minigzip.obj: test/minigzip.c zlib.h zconf.h
|
||||||
|
|
||||||
|
|
||||||
|
# For the sake of the old Borland make,
|
||||||
|
# the command line is cut to fit in the MS-DOS 128 byte limit:
|
||||||
|
$(ZLIB_LIB): $(OBJ1) $(OBJ2) $(OBJA)
|
||||||
|
-del $(ZLIB_LIB)
|
||||||
|
$(AR) $(ZLIB_LIB) $(OBJP1)
|
||||||
|
$(AR) $(ZLIB_LIB) $(OBJP2)
|
||||||
|
$(AR) $(ZLIB_LIB) $(OBJPA)
|
||||||
|
|
||||||
|
|
||||||
|
# testing
|
||||||
|
test: example.exe minigzip.exe
|
||||||
|
example
|
||||||
|
echo hello world | minigzip | minigzip -d
|
||||||
|
|
||||||
|
example.exe: example.obj $(ZLIB_LIB)
|
||||||
|
$(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
|
||||||
|
|
||||||
|
minigzip.exe: minigzip.obj $(ZLIB_LIB)
|
||||||
|
$(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
|
||||||
|
|
||||||
|
|
||||||
|
# cleanup
|
||||||
|
clean:
|
||||||
|
-del $(ZLIB_LIB)
|
||||||
|
-del *.obj
|
||||||
|
-del *.exe
|
||||||
|
-del *.tds
|
||||||
|
-del zlib.bak
|
||||||
|
-del foo.gz
|
|
@ -0,0 +1,182 @@
|
||||||
|
# Makefile for zlib, derived from Makefile.dj2.
|
||||||
|
# Modified for mingw32 by C. Spieler, 6/16/98.
|
||||||
|
# Updated for zlib 1.2.x by Christian Spieler and Cosmin Truta, Mar-2003.
|
||||||
|
# Last updated: Mar 2012.
|
||||||
|
# Tested under Cygwin and MinGW.
|
||||||
|
|
||||||
|
# Copyright (C) 1995-2003 Jean-loup Gailly.
|
||||||
|
# For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
|
|
||||||
|
# To compile, or to compile and test, type from the top level zlib directory:
|
||||||
|
#
|
||||||
|
# make -fwin32/Makefile.gcc; make test testdll -fwin32/Makefile.gcc
|
||||||
|
#
|
||||||
|
# To use the asm code, type:
|
||||||
|
# cp contrib/asm?86/match.S ./match.S
|
||||||
|
# make LOC=-DASMV OBJA=match.o -fwin32/Makefile.gcc
|
||||||
|
#
|
||||||
|
# To install libz.a, zconf.h and zlib.h in the system directories, type:
|
||||||
|
#
|
||||||
|
# make install -fwin32/Makefile.gcc
|
||||||
|
#
|
||||||
|
# BINARY_PATH, INCLUDE_PATH and LIBRARY_PATH must be set.
|
||||||
|
#
|
||||||
|
# To install the shared lib, append SHARED_MODE=1 to the make command :
|
||||||
|
#
|
||||||
|
# make install -fwin32/Makefile.gcc SHARED_MODE=1
|
||||||
|
|
||||||
|
# Note:
|
||||||
|
# If the platform is *not* MinGW (e.g. it is Cygwin or UWIN),
|
||||||
|
# the DLL name should be changed from "zlib1.dll".
|
||||||
|
|
||||||
|
STATICLIB = libz.a
|
||||||
|
SHAREDLIB = zlib1.dll
|
||||||
|
IMPLIB = libz.dll.a
|
||||||
|
|
||||||
|
#
|
||||||
|
# Set to 1 if shared object needs to be installed
|
||||||
|
#
|
||||||
|
SHARED_MODE=0
|
||||||
|
|
||||||
|
#LOC = -DASMV
|
||||||
|
#LOC = -DDEBUG -g
|
||||||
|
|
||||||
|
PREFIX =
|
||||||
|
CC = $(PREFIX)gcc
|
||||||
|
CFLAGS = $(LOC) -O3 -Wall
|
||||||
|
|
||||||
|
AS = $(CC)
|
||||||
|
ASFLAGS = $(LOC) -Wall
|
||||||
|
|
||||||
|
LD = $(CC)
|
||||||
|
LDFLAGS = $(LOC)
|
||||||
|
|
||||||
|
AR = $(PREFIX)ar
|
||||||
|
ARFLAGS = rcs
|
||||||
|
|
||||||
|
RC = $(PREFIX)windres
|
||||||
|
RCFLAGS = --define GCC_WINDRES
|
||||||
|
|
||||||
|
STRIP = $(PREFIX)strip
|
||||||
|
|
||||||
|
CP = cp -fp
|
||||||
|
# If GNU install is available, replace $(CP) with install.
|
||||||
|
INSTALL = $(CP)
|
||||||
|
RM = rm -f
|
||||||
|
|
||||||
|
prefix ?= /usr/local
|
||||||
|
exec_prefix = $(prefix)
|
||||||
|
|
||||||
|
OBJS = adler32.o compress.o crc32.o deflate.o gzclose.o gzlib.o gzread.o \
|
||||||
|
gzwrite.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o
|
||||||
|
OBJA =
|
||||||
|
|
||||||
|
all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) example.exe minigzip.exe example_d.exe minigzip_d.exe
|
||||||
|
|
||||||
|
test: example.exe minigzip.exe
|
||||||
|
./example
|
||||||
|
echo hello world | ./minigzip | ./minigzip -d
|
||||||
|
|
||||||
|
testdll: example_d.exe minigzip_d.exe
|
||||||
|
./example_d
|
||||||
|
echo hello world | ./minigzip_d | ./minigzip_d -d
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
.S.o:
|
||||||
|
$(AS) $(ASFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
$(STATICLIB): $(OBJS) $(OBJA)
|
||||||
|
$(AR) $(ARFLAGS) $@ $(OBJS) $(OBJA)
|
||||||
|
|
||||||
|
$(IMPLIB): $(SHAREDLIB)
|
||||||
|
|
||||||
|
$(SHAREDLIB): win32/zlib.def $(OBJS) $(OBJA) zlibrc.o
|
||||||
|
$(CC) -shared -Wl,--out-implib,$(IMPLIB) $(LDFLAGS) \
|
||||||
|
-o $@ win32/zlib.def $(OBJS) $(OBJA) zlibrc.o
|
||||||
|
$(STRIP) $@
|
||||||
|
|
||||||
|
example.exe: example.o $(STATICLIB)
|
||||||
|
$(LD) $(LDFLAGS) -o $@ example.o $(STATICLIB)
|
||||||
|
$(STRIP) $@
|
||||||
|
|
||||||
|
minigzip.exe: minigzip.o $(STATICLIB)
|
||||||
|
$(LD) $(LDFLAGS) -o $@ minigzip.o $(STATICLIB)
|
||||||
|
$(STRIP) $@
|
||||||
|
|
||||||
|
example_d.exe: example.o $(IMPLIB)
|
||||||
|
$(LD) $(LDFLAGS) -o $@ example.o $(IMPLIB)
|
||||||
|
$(STRIP) $@
|
||||||
|
|
||||||
|
minigzip_d.exe: minigzip.o $(IMPLIB)
|
||||||
|
$(LD) $(LDFLAGS) -o $@ minigzip.o $(IMPLIB)
|
||||||
|
$(STRIP) $@
|
||||||
|
|
||||||
|
example.o: test/example.c zlib.h zconf.h
|
||||||
|
$(CC) $(CFLAGS) -I. -c -o $@ test/example.c
|
||||||
|
|
||||||
|
minigzip.o: test/minigzip.c zlib.h zconf.h
|
||||||
|
$(CC) $(CFLAGS) -I. -c -o $@ test/minigzip.c
|
||||||
|
|
||||||
|
zlibrc.o: win32/zlib1.rc
|
||||||
|
$(RC) $(RCFLAGS) -o $@ win32/zlib1.rc
|
||||||
|
|
||||||
|
.PHONY: install uninstall clean
|
||||||
|
|
||||||
|
install: zlib.h zconf.h $(STATICLIB) $(IMPLIB)
|
||||||
|
@if test -z "$(DESTDIR)$(INCLUDE_PATH)" -o -z "$(DESTDIR)$(LIBRARY_PATH)" -o -z "$(DESTDIR)$(BINARY_PATH)"; then \
|
||||||
|
echo INCLUDE_PATH, LIBRARY_PATH, and BINARY_PATH must be specified; \
|
||||||
|
exit 1; \
|
||||||
|
fi
|
||||||
|
-@mkdir -p '$(DESTDIR)$(INCLUDE_PATH)'
|
||||||
|
-@mkdir -p '$(DESTDIR)$(LIBRARY_PATH)' '$(DESTDIR)$(LIBRARY_PATH)'/pkgconfig
|
||||||
|
-if [ "$(SHARED_MODE)" = "1" ]; then \
|
||||||
|
mkdir -p '$(DESTDIR)$(BINARY_PATH)'; \
|
||||||
|
$(INSTALL) $(SHAREDLIB) '$(DESTDIR)$(BINARY_PATH)'; \
|
||||||
|
$(INSTALL) $(IMPLIB) '$(DESTDIR)$(LIBRARY_PATH)'; \
|
||||||
|
fi
|
||||||
|
-$(INSTALL) zlib.h '$(DESTDIR)$(INCLUDE_PATH)'
|
||||||
|
-$(INSTALL) zconf.h '$(DESTDIR)$(INCLUDE_PATH)'
|
||||||
|
-$(INSTALL) $(STATICLIB) '$(DESTDIR)$(LIBRARY_PATH)'
|
||||||
|
sed \
|
||||||
|
-e 's|@prefix@|${prefix}|g' \
|
||||||
|
-e 's|@exec_prefix@|${exec_prefix}|g' \
|
||||||
|
-e 's|@libdir@|$(LIBRARY_PATH)|g' \
|
||||||
|
-e 's|@sharedlibdir@|$(LIBRARY_PATH)|g' \
|
||||||
|
-e 's|@includedir@|$(INCLUDE_PATH)|g' \
|
||||||
|
-e 's|@VERSION@|'`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' zlib.h`'|g' \
|
||||||
|
zlib.pc.in > '$(DESTDIR)$(LIBRARY_PATH)'/pkgconfig/zlib.pc
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
-if [ "$(SHARED_MODE)" = "1" ]; then \
|
||||||
|
$(RM) '$(DESTDIR)$(BINARY_PATH)'/$(SHAREDLIB); \
|
||||||
|
$(RM) '$(DESTDIR)$(LIBRARY_PATH)'/$(IMPLIB); \
|
||||||
|
fi
|
||||||
|
-$(RM) '$(DESTDIR)$(INCLUDE_PATH)'/zlib.h
|
||||||
|
-$(RM) '$(DESTDIR)$(INCLUDE_PATH)'/zconf.h
|
||||||
|
-$(RM) '$(DESTDIR)$(LIBRARY_PATH)'/$(STATICLIB)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
-$(RM) $(STATICLIB)
|
||||||
|
-$(RM) $(SHAREDLIB)
|
||||||
|
-$(RM) $(IMPLIB)
|
||||||
|
-$(RM) *.o
|
||||||
|
-$(RM) *.exe
|
||||||
|
-$(RM) foo.gz
|
||||||
|
|
||||||
|
adler32.o: zlib.h zconf.h
|
||||||
|
compress.o: zlib.h zconf.h
|
||||||
|
crc32.o: crc32.h zlib.h zconf.h
|
||||||
|
deflate.o: deflate.h zutil.h zlib.h zconf.h
|
||||||
|
gzclose.o: zlib.h zconf.h gzguts.h
|
||||||
|
gzlib.o: zlib.h zconf.h gzguts.h
|
||||||
|
gzread.o: zlib.h zconf.h gzguts.h
|
||||||
|
gzwrite.o: zlib.h zconf.h gzguts.h
|
||||||
|
inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
|
||||||
|
inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
|
||||||
|
infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
|
||||||
|
inftrees.o: zutil.h zlib.h zconf.h inftrees.h
|
||||||
|
trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
|
||||||
|
uncompr.o: zlib.h zconf.h
|
||||||
|
zutil.o: zutil.h zlib.h zconf.h
|
|
@ -0,0 +1,163 @@
|
||||||
|
# Makefile for zlib using Microsoft (Visual) C
|
||||||
|
# zlib is copyright (C) 1995-2006 Jean-loup Gailly and Mark Adler
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# nmake -f win32/Makefile.msc (standard build)
|
||||||
|
# nmake -f win32/Makefile.msc LOC=-DFOO (nonstandard build)
|
||||||
|
# nmake -f win32/Makefile.msc LOC="-DASMV -DASMINF" \
|
||||||
|
# OBJA="inffas32.obj match686.obj" (use ASM code, x86)
|
||||||
|
# nmake -f win32/Makefile.msc AS=ml64 LOC="-DASMV -DASMINF -I." \
|
||||||
|
# OBJA="inffasx64.obj gvmat64.obj inffas8664.obj" (use ASM code, x64)
|
||||||
|
|
||||||
|
# The toplevel directory of the source tree.
|
||||||
|
#
|
||||||
|
TOP = .
|
||||||
|
|
||||||
|
# optional build flags
|
||||||
|
LOC =
|
||||||
|
|
||||||
|
# variables
|
||||||
|
STATICLIB = zlib.lib
|
||||||
|
SHAREDLIB = zlib1.dll
|
||||||
|
IMPLIB = zdll.lib
|
||||||
|
|
||||||
|
CC = cl
|
||||||
|
AS = ml
|
||||||
|
LD = link
|
||||||
|
AR = lib
|
||||||
|
RC = rc
|
||||||
|
CFLAGS = -nologo -MD -W3 -O2 -Oy- -Zi -Fd"zlib" $(LOC)
|
||||||
|
WFLAGS = -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE
|
||||||
|
ASFLAGS = -coff -Zi $(LOC)
|
||||||
|
LDFLAGS = -nologo -debug -incremental:no -opt:ref
|
||||||
|
ARFLAGS = -nologo
|
||||||
|
RCFLAGS = /dWIN32 /r
|
||||||
|
|
||||||
|
OBJS = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj \
|
||||||
|
gzwrite.obj infback.obj inflate.obj inftrees.obj inffast.obj trees.obj uncompr.obj zutil.obj
|
||||||
|
OBJA =
|
||||||
|
|
||||||
|
|
||||||
|
# targets
|
||||||
|
all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) \
|
||||||
|
example.exe minigzip.exe example_d.exe minigzip_d.exe
|
||||||
|
|
||||||
|
$(STATICLIB): $(OBJS) $(OBJA)
|
||||||
|
$(AR) $(ARFLAGS) -out:$@ $(OBJS) $(OBJA)
|
||||||
|
|
||||||
|
$(IMPLIB): $(SHAREDLIB)
|
||||||
|
|
||||||
|
$(SHAREDLIB): $(TOP)/win32/zlib.def $(OBJS) $(OBJA) zlib1.res
|
||||||
|
$(LD) $(LDFLAGS) -def:$(TOP)/win32/zlib.def -dll -implib:$(IMPLIB) \
|
||||||
|
-out:$@ -base:0x5A4C0000 $(OBJS) $(OBJA) zlib1.res
|
||||||
|
if exist $@.manifest \
|
||||||
|
mt -nologo -manifest $@.manifest -outputresource:$@;2
|
||||||
|
|
||||||
|
example.exe: example.obj $(STATICLIB)
|
||||||
|
$(LD) $(LDFLAGS) example.obj $(STATICLIB)
|
||||||
|
if exist $@.manifest \
|
||||||
|
mt -nologo -manifest $@.manifest -outputresource:$@;1
|
||||||
|
|
||||||
|
minigzip.exe: minigzip.obj $(STATICLIB)
|
||||||
|
$(LD) $(LDFLAGS) minigzip.obj $(STATICLIB)
|
||||||
|
if exist $@.manifest \
|
||||||
|
mt -nologo -manifest $@.manifest -outputresource:$@;1
|
||||||
|
|
||||||
|
example_d.exe: example.obj $(IMPLIB)
|
||||||
|
$(LD) $(LDFLAGS) -out:$@ example.obj $(IMPLIB)
|
||||||
|
if exist $@.manifest \
|
||||||
|
mt -nologo -manifest $@.manifest -outputresource:$@;1
|
||||||
|
|
||||||
|
minigzip_d.exe: minigzip.obj $(IMPLIB)
|
||||||
|
$(LD) $(LDFLAGS) -out:$@ minigzip.obj $(IMPLIB)
|
||||||
|
if exist $@.manifest \
|
||||||
|
mt -nologo -manifest $@.manifest -outputresource:$@;1
|
||||||
|
|
||||||
|
{$(TOP)}.c.obj:
|
||||||
|
$(CC) -c $(WFLAGS) $(CFLAGS) $<
|
||||||
|
|
||||||
|
{$(TOP)/test}.c.obj:
|
||||||
|
$(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) $<
|
||||||
|
|
||||||
|
{$(TOP)/contrib/masmx64}.c.obj:
|
||||||
|
$(CC) -c $(WFLAGS) $(CFLAGS) $<
|
||||||
|
|
||||||
|
{$(TOP)/contrib/masmx64}.asm.obj:
|
||||||
|
$(AS) -c $(ASFLAGS) $<
|
||||||
|
|
||||||
|
{$(TOP)/contrib/masmx86}.asm.obj:
|
||||||
|
$(AS) -c $(ASFLAGS) $<
|
||||||
|
|
||||||
|
adler32.obj: $(TOP)/adler32.c $(TOP)/zlib.h $(TOP)/zconf.h
|
||||||
|
|
||||||
|
compress.obj: $(TOP)/compress.c $(TOP)/zlib.h $(TOP)/zconf.h
|
||||||
|
|
||||||
|
crc32.obj: $(TOP)/crc32.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/crc32.h
|
||||||
|
|
||||||
|
deflate.obj: $(TOP)/deflate.c $(TOP)/deflate.h $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h
|
||||||
|
|
||||||
|
gzclose.obj: $(TOP)/gzclose.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h
|
||||||
|
|
||||||
|
gzlib.obj: $(TOP)/gzlib.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h
|
||||||
|
|
||||||
|
gzread.obj: $(TOP)/gzread.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h
|
||||||
|
|
||||||
|
gzwrite.obj: $(TOP)/gzwrite.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h
|
||||||
|
|
||||||
|
infback.obj: $(TOP)/infback.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \
|
||||||
|
$(TOP)/inffast.h $(TOP)/inffixed.h
|
||||||
|
|
||||||
|
inffast.obj: $(TOP)/inffast.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \
|
||||||
|
$(TOP)/inffast.h
|
||||||
|
|
||||||
|
inflate.obj: $(TOP)/inflate.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \
|
||||||
|
$(TOP)/inffast.h $(TOP)/inffixed.h
|
||||||
|
|
||||||
|
inftrees.obj: $(TOP)/inftrees.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h
|
||||||
|
|
||||||
|
trees.obj: $(TOP)/trees.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/deflate.h $(TOP)/trees.h
|
||||||
|
|
||||||
|
uncompr.obj: $(TOP)/uncompr.c $(TOP)/zlib.h $(TOP)/zconf.h
|
||||||
|
|
||||||
|
zutil.obj: $(TOP)/zutil.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h
|
||||||
|
|
||||||
|
gvmat64.obj: $(TOP)/contrib\masmx64\gvmat64.asm
|
||||||
|
|
||||||
|
inffasx64.obj: $(TOP)/contrib\masmx64\inffasx64.asm
|
||||||
|
|
||||||
|
inffas8664.obj: $(TOP)/contrib\masmx64\inffas8664.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h \
|
||||||
|
$(TOP)/inftrees.h $(TOP)/inflate.h $(TOP)/inffast.h
|
||||||
|
|
||||||
|
inffas32.obj: $(TOP)/contrib\masmx86\inffas32.asm
|
||||||
|
|
||||||
|
match686.obj: $(TOP)/contrib\masmx86\match686.asm
|
||||||
|
|
||||||
|
example.obj: $(TOP)/test/example.c $(TOP)/zlib.h $(TOP)/zconf.h
|
||||||
|
|
||||||
|
minigzip.obj: $(TOP)/test/minigzip.c $(TOP)/zlib.h $(TOP)/zconf.h
|
||||||
|
|
||||||
|
zlib1.res: $(TOP)/win32/zlib1.rc
|
||||||
|
$(RC) $(RCFLAGS) /fo$@ $(TOP)/win32/zlib1.rc
|
||||||
|
|
||||||
|
# testing
|
||||||
|
test: example.exe minigzip.exe
|
||||||
|
example
|
||||||
|
echo hello world | minigzip | minigzip -d
|
||||||
|
|
||||||
|
testdll: example_d.exe minigzip_d.exe
|
||||||
|
example_d
|
||||||
|
echo hello world | minigzip_d | minigzip_d -d
|
||||||
|
|
||||||
|
|
||||||
|
# cleanup
|
||||||
|
clean:
|
||||||
|
-del $(STATICLIB)
|
||||||
|
-del $(SHAREDLIB)
|
||||||
|
-del $(IMPLIB)
|
||||||
|
-del *.obj
|
||||||
|
-del *.res
|
||||||
|
-del *.exp
|
||||||
|
-del *.exe
|
||||||
|
-del *.pdb
|
||||||
|
-del *.manifest
|
||||||
|
-del foo.gz
|
|
@ -0,0 +1,103 @@
|
||||||
|
ZLIB DATA COMPRESSION LIBRARY
|
||||||
|
|
||||||
|
zlib 1.2.8 is a general purpose data compression library. All the code is
|
||||||
|
thread safe. The data format used by the zlib library is described by RFCs
|
||||||
|
(Request for Comments) 1950 to 1952 in the files
|
||||||
|
http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
|
||||||
|
and rfc1952.txt (gzip format).
|
||||||
|
|
||||||
|
All functions of the compression library are documented in the file zlib.h
|
||||||
|
(volunteer to write man pages welcome, contact zlib@gzip.org). Two compiled
|
||||||
|
examples are distributed in this package, example and minigzip. The example_d
|
||||||
|
and minigzip_d flavors validate that the zlib1.dll file is working correctly.
|
||||||
|
|
||||||
|
Questions about zlib should be sent to <zlib@gzip.org>. The zlib home page
|
||||||
|
is http://zlib.net/ . Before reporting a problem, please check this site to
|
||||||
|
verify that you have the latest version of zlib; otherwise get the latest
|
||||||
|
version and check whether the problem still exists or not.
|
||||||
|
|
||||||
|
PLEASE read DLL_FAQ.txt, and the the zlib FAQ http://zlib.net/zlib_faq.html
|
||||||
|
before asking for help.
|
||||||
|
|
||||||
|
|
||||||
|
Manifest:
|
||||||
|
|
||||||
|
The package zlib-1.2.8-win32-x86.zip will contain the following files:
|
||||||
|
|
||||||
|
README-WIN32.txt This document
|
||||||
|
ChangeLog Changes since previous zlib packages
|
||||||
|
DLL_FAQ.txt Frequently asked questions about zlib1.dll
|
||||||
|
zlib.3.pdf Documentation of this library in Adobe Acrobat format
|
||||||
|
|
||||||
|
example.exe A statically-bound example (using zlib.lib, not the dll)
|
||||||
|
example.pdb Symbolic information for debugging example.exe
|
||||||
|
|
||||||
|
example_d.exe A zlib1.dll bound example (using zdll.lib)
|
||||||
|
example_d.pdb Symbolic information for debugging example_d.exe
|
||||||
|
|
||||||
|
minigzip.exe A statically-bound test program (using zlib.lib, not the dll)
|
||||||
|
minigzip.pdb Symbolic information for debugging minigzip.exe
|
||||||
|
|
||||||
|
minigzip_d.exe A zlib1.dll bound test program (using zdll.lib)
|
||||||
|
minigzip_d.pdb Symbolic information for debugging minigzip_d.exe
|
||||||
|
|
||||||
|
zlib.h Install these files into the compilers' INCLUDE path to
|
||||||
|
zconf.h compile programs which use zlib.lib or zdll.lib
|
||||||
|
|
||||||
|
zdll.lib Install these files into the compilers' LIB path if linking
|
||||||
|
zdll.exp a compiled program to the zlib1.dll binary
|
||||||
|
|
||||||
|
zlib.lib Install these files into the compilers' LIB path to link zlib
|
||||||
|
zlib.pdb into compiled programs, without zlib1.dll runtime dependency
|
||||||
|
(zlib.pdb provides debugging info to the compile time linker)
|
||||||
|
|
||||||
|
zlib1.dll Install this binary shared library into the system PATH, or
|
||||||
|
the program's runtime directory (where the .exe resides)
|
||||||
|
zlib1.pdb Install in the same directory as zlib1.dll, in order to debug
|
||||||
|
an application crash using WinDbg or similar tools.
|
||||||
|
|
||||||
|
All .pdb files above are entirely optional, but are very useful to a developer
|
||||||
|
attempting to diagnose program misbehavior or a crash. Many additional
|
||||||
|
important files for developers can be found in the zlib127.zip source package
|
||||||
|
available from http://zlib.net/ - review that package's README file for details.
|
||||||
|
|
||||||
|
|
||||||
|
Acknowledgments:
|
||||||
|
|
||||||
|
The deflate format used by zlib was defined by Phil Katz. The deflate and
|
||||||
|
zlib specifications were written by L. Peter Deutsch. Thanks to all the
|
||||||
|
people who reported problems and suggested various improvements in zlib; they
|
||||||
|
are too numerous to cite here.
|
||||||
|
|
||||||
|
|
||||||
|
Copyright notice:
|
||||||
|
|
||||||
|
(C) 1995-2012 Jean-loup Gailly and Mark Adler
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
|
Jean-loup Gailly Mark Adler
|
||||||
|
jloup@gzip.org madler@alumni.caltech.edu
|
||||||
|
|
||||||
|
If you use the zlib library in a product, we would appreciate *not* receiving
|
||||||
|
lengthy legal documents to sign. The sources are provided for free but without
|
||||||
|
warranty of any kind. The library has been entirely written by Jean-loup
|
||||||
|
Gailly and Mark Adler; it does not include third-party code.
|
||||||
|
|
||||||
|
If you redistribute modified sources, we would appreciate that you include in
|
||||||
|
the file ChangeLog history information documenting your changes. Please read
|
||||||
|
the FAQ for more information on the distribution of modified source versions.
|
|
@ -0,0 +1,3 @@
|
||||||
|
|
||||||
|
To build zlib using the Microsoft Visual C++ environment,
|
||||||
|
use the appropriate project from the projects/ directory.
|
|
@ -0,0 +1,86 @@
|
||||||
|
; zlib data compression library
|
||||||
|
EXPORTS
|
||||||
|
; basic functions
|
||||||
|
zlibVersion
|
||||||
|
deflate
|
||||||
|
deflateEnd
|
||||||
|
inflate
|
||||||
|
inflateEnd
|
||||||
|
; advanced functions
|
||||||
|
deflateSetDictionary
|
||||||
|
deflateCopy
|
||||||
|
deflateReset
|
||||||
|
deflateParams
|
||||||
|
deflateTune
|
||||||
|
deflateBound
|
||||||
|
deflatePending
|
||||||
|
deflatePrime
|
||||||
|
deflateSetHeader
|
||||||
|
inflateSetDictionary
|
||||||
|
inflateGetDictionary
|
||||||
|
inflateSync
|
||||||
|
inflateCopy
|
||||||
|
inflateReset
|
||||||
|
inflateReset2
|
||||||
|
inflatePrime
|
||||||
|
inflateMark
|
||||||
|
inflateGetHeader
|
||||||
|
inflateBack
|
||||||
|
inflateBackEnd
|
||||||
|
zlibCompileFlags
|
||||||
|
; utility functions
|
||||||
|
compress
|
||||||
|
compress2
|
||||||
|
compressBound
|
||||||
|
uncompress
|
||||||
|
gzopen
|
||||||
|
gzdopen
|
||||||
|
gzbuffer
|
||||||
|
gzsetparams
|
||||||
|
gzread
|
||||||
|
gzwrite
|
||||||
|
gzprintf
|
||||||
|
gzvprintf
|
||||||
|
gzputs
|
||||||
|
gzgets
|
||||||
|
gzputc
|
||||||
|
gzgetc
|
||||||
|
gzungetc
|
||||||
|
gzflush
|
||||||
|
gzseek
|
||||||
|
gzrewind
|
||||||
|
gztell
|
||||||
|
gzoffset
|
||||||
|
gzeof
|
||||||
|
gzdirect
|
||||||
|
gzclose
|
||||||
|
gzclose_r
|
||||||
|
gzclose_w
|
||||||
|
gzerror
|
||||||
|
gzclearerr
|
||||||
|
; large file functions
|
||||||
|
gzopen64
|
||||||
|
gzseek64
|
||||||
|
gztell64
|
||||||
|
gzoffset64
|
||||||
|
adler32_combine64
|
||||||
|
crc32_combine64
|
||||||
|
; checksum functions
|
||||||
|
adler32
|
||||||
|
crc32
|
||||||
|
adler32_combine
|
||||||
|
crc32_combine
|
||||||
|
; various hacks, don't look :)
|
||||||
|
deflateInit_
|
||||||
|
deflateInit2_
|
||||||
|
inflateInit_
|
||||||
|
inflateInit2_
|
||||||
|
inflateBackInit_
|
||||||
|
gzgetc_
|
||||||
|
zError
|
||||||
|
inflateSyncPoint
|
||||||
|
get_crc_table
|
||||||
|
inflateUndermine
|
||||||
|
inflateResetKeep
|
||||||
|
deflateResetKeep
|
||||||
|
gzopen_w
|
|
@ -0,0 +1,40 @@
|
||||||
|
#include <winver.h>
|
||||||
|
#include "../zlib.h"
|
||||||
|
|
||||||
|
#ifdef GCC_WINDRES
|
||||||
|
VS_VERSION_INFO VERSIONINFO
|
||||||
|
#else
|
||||||
|
VS_VERSION_INFO VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
|
||||||
|
#endif
|
||||||
|
FILEVERSION ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0
|
||||||
|
PRODUCTVERSION ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0
|
||||||
|
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||||
|
#ifdef _DEBUG
|
||||||
|
FILEFLAGS 1
|
||||||
|
#else
|
||||||
|
FILEFLAGS 0
|
||||||
|
#endif
|
||||||
|
FILEOS VOS__WINDOWS32
|
||||||
|
FILETYPE VFT_DLL
|
||||||
|
FILESUBTYPE 0 // not used
|
||||||
|
BEGIN
|
||||||
|
BLOCK "StringFileInfo"
|
||||||
|
BEGIN
|
||||||
|
BLOCK "040904E4"
|
||||||
|
//language ID = U.S. English, char set = Windows, Multilingual
|
||||||
|
BEGIN
|
||||||
|
VALUE "FileDescription", "zlib data compression library\0"
|
||||||
|
VALUE "FileVersion", ZLIB_VERSION "\0"
|
||||||
|
VALUE "InternalName", "zlib1.dll\0"
|
||||||
|
VALUE "LegalCopyright", "(C) 1995-2013 Jean-loup Gailly & Mark Adler\0"
|
||||||
|
VALUE "OriginalFilename", "zlib1.dll\0"
|
||||||
|
VALUE "ProductName", "zlib\0"
|
||||||
|
VALUE "ProductVersion", ZLIB_VERSION "\0"
|
||||||
|
VALUE "Comments", "For more information visit http://www.zlib.net/\0"
|
||||||
|
END
|
||||||
|
END
|
||||||
|
BLOCK "VarFileInfo"
|
||||||
|
BEGIN
|
||||||
|
VALUE "Translation", 0x0409, 1252
|
||||||
|
END
|
||||||
|
END
|
|
@ -1,5 +1,5 @@
|
||||||
/* zconf.h -- configuration of the zlib compression library
|
/* zconf.h -- configuration of the zlib compression library
|
||||||
* Copyright (C) 1995-2010 Jean-loup Gailly.
|
* Copyright (C) 1995-2013 Jean-loup Gailly.
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
#ifndef ZCONF_H
|
#ifndef ZCONF_H
|
||||||
#define ZCONF_H
|
#define ZCONF_H
|
||||||
|
#cmakedefine Z_PREFIX
|
||||||
|
#cmakedefine Z_HAVE_UNISTD_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If you *really* need a unique prefix for all types and library functions,
|
* If you *really* need a unique prefix for all types and library functions,
|
||||||
|
@ -15,11 +17,13 @@
|
||||||
* this permanently in zconf.h using "./configure --zprefix".
|
* this permanently in zconf.h using "./configure --zprefix".
|
||||||
*/
|
*/
|
||||||
#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
|
#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
|
||||||
|
# define Z_PREFIX_SET
|
||||||
|
|
||||||
/* all linked symbols */
|
/* all linked symbols */
|
||||||
# define _dist_code z__dist_code
|
# define _dist_code z__dist_code
|
||||||
# define _length_code z__length_code
|
# define _length_code z__length_code
|
||||||
# define _tr_align z__tr_align
|
# define _tr_align z__tr_align
|
||||||
|
# define _tr_flush_bits z__tr_flush_bits
|
||||||
# define _tr_flush_block z__tr_flush_block
|
# define _tr_flush_block z__tr_flush_block
|
||||||
# define _tr_init z__tr_init
|
# define _tr_init z__tr_init
|
||||||
# define _tr_stored_block z__tr_stored_block
|
# define _tr_stored_block z__tr_stored_block
|
||||||
|
@ -27,9 +31,11 @@
|
||||||
# define adler32 z_adler32
|
# define adler32 z_adler32
|
||||||
# define adler32_combine z_adler32_combine
|
# define adler32_combine z_adler32_combine
|
||||||
# define adler32_combine64 z_adler32_combine64
|
# define adler32_combine64 z_adler32_combine64
|
||||||
# define compress z_compress
|
# ifndef Z_SOLO
|
||||||
# define compress2 z_compress2
|
# define compress z_compress
|
||||||
# define compressBound z_compressBound
|
# define compress2 z_compress2
|
||||||
|
# define compressBound z_compressBound
|
||||||
|
# endif
|
||||||
# define crc32 z_crc32
|
# define crc32 z_crc32
|
||||||
# define crc32_combine z_crc32_combine
|
# define crc32_combine z_crc32_combine
|
||||||
# define crc32_combine64 z_crc32_combine64
|
# define crc32_combine64 z_crc32_combine64
|
||||||
|
@ -40,44 +46,53 @@
|
||||||
# define deflateInit2_ z_deflateInit2_
|
# define deflateInit2_ z_deflateInit2_
|
||||||
# define deflateInit_ z_deflateInit_
|
# define deflateInit_ z_deflateInit_
|
||||||
# define deflateParams z_deflateParams
|
# define deflateParams z_deflateParams
|
||||||
|
# define deflatePending z_deflatePending
|
||||||
# define deflatePrime z_deflatePrime
|
# define deflatePrime z_deflatePrime
|
||||||
# define deflateReset z_deflateReset
|
# define deflateReset z_deflateReset
|
||||||
|
# define deflateResetKeep z_deflateResetKeep
|
||||||
# define deflateSetDictionary z_deflateSetDictionary
|
# define deflateSetDictionary z_deflateSetDictionary
|
||||||
# define deflateSetHeader z_deflateSetHeader
|
# define deflateSetHeader z_deflateSetHeader
|
||||||
# define deflateTune z_deflateTune
|
# define deflateTune z_deflateTune
|
||||||
# define deflate_copyright z_deflate_copyright
|
# define deflate_copyright z_deflate_copyright
|
||||||
# define get_crc_table z_get_crc_table
|
# define get_crc_table z_get_crc_table
|
||||||
# define gz_error z_gz_error
|
# ifndef Z_SOLO
|
||||||
# define gz_intmax z_gz_intmax
|
# define gz_error z_gz_error
|
||||||
# define gz_strwinerror z_gz_strwinerror
|
# define gz_intmax z_gz_intmax
|
||||||
# define gzbuffer z_gzbuffer
|
# define gz_strwinerror z_gz_strwinerror
|
||||||
# define gzclearerr z_gzclearerr
|
# define gzbuffer z_gzbuffer
|
||||||
# define gzclose z_gzclose
|
# define gzclearerr z_gzclearerr
|
||||||
# define gzclose_r z_gzclose_r
|
# define gzclose z_gzclose
|
||||||
# define gzclose_w z_gzclose_w
|
# define gzclose_r z_gzclose_r
|
||||||
# define gzdirect z_gzdirect
|
# define gzclose_w z_gzclose_w
|
||||||
# define gzdopen z_gzdopen
|
# define gzdirect z_gzdirect
|
||||||
# define gzeof z_gzeof
|
# define gzdopen z_gzdopen
|
||||||
# define gzerror z_gzerror
|
# define gzeof z_gzeof
|
||||||
# define gzflush z_gzflush
|
# define gzerror z_gzerror
|
||||||
# define gzgetc z_gzgetc
|
# define gzflush z_gzflush
|
||||||
# define gzgets z_gzgets
|
# define gzgetc z_gzgetc
|
||||||
# define gzoffset z_gzoffset
|
# define gzgetc_ z_gzgetc_
|
||||||
# define gzoffset64 z_gzoffset64
|
# define gzgets z_gzgets
|
||||||
# define gzopen z_gzopen
|
# define gzoffset z_gzoffset
|
||||||
# define gzopen64 z_gzopen64
|
# define gzoffset64 z_gzoffset64
|
||||||
# define gzprintf z_gzprintf
|
# define gzopen z_gzopen
|
||||||
# define gzputc z_gzputc
|
# define gzopen64 z_gzopen64
|
||||||
# define gzputs z_gzputs
|
# ifdef _WIN32
|
||||||
# define gzread z_gzread
|
# define gzopen_w z_gzopen_w
|
||||||
# define gzrewind z_gzrewind
|
# endif
|
||||||
# define gzseek z_gzseek
|
# define gzprintf z_gzprintf
|
||||||
# define gzseek64 z_gzseek64
|
# define gzvprintf z_gzvprintf
|
||||||
# define gzsetparams z_gzsetparams
|
# define gzputc z_gzputc
|
||||||
# define gztell z_gztell
|
# define gzputs z_gzputs
|
||||||
# define gztell64 z_gztell64
|
# define gzread z_gzread
|
||||||
# define gzungetc z_gzungetc
|
# define gzrewind z_gzrewind
|
||||||
# define gzwrite z_gzwrite
|
# define gzseek z_gzseek
|
||||||
|
# define gzseek64 z_gzseek64
|
||||||
|
# define gzsetparams z_gzsetparams
|
||||||
|
# define gztell z_gztell
|
||||||
|
# define gztell64 z_gztell64
|
||||||
|
# define gzungetc z_gzungetc
|
||||||
|
# define gzwrite z_gzwrite
|
||||||
|
# endif
|
||||||
# define inflate z_inflate
|
# define inflate z_inflate
|
||||||
# define inflateBack z_inflateBack
|
# define inflateBack z_inflateBack
|
||||||
# define inflateBackEnd z_inflateBackEnd
|
# define inflateBackEnd z_inflateBackEnd
|
||||||
|
@ -92,16 +107,22 @@
|
||||||
# define inflateReset z_inflateReset
|
# define inflateReset z_inflateReset
|
||||||
# define inflateReset2 z_inflateReset2
|
# define inflateReset2 z_inflateReset2
|
||||||
# define inflateSetDictionary z_inflateSetDictionary
|
# define inflateSetDictionary z_inflateSetDictionary
|
||||||
|
# define inflateGetDictionary z_inflateGetDictionary
|
||||||
# define inflateSync z_inflateSync
|
# define inflateSync z_inflateSync
|
||||||
# define inflateSyncPoint z_inflateSyncPoint
|
# define inflateSyncPoint z_inflateSyncPoint
|
||||||
# define inflateUndermine z_inflateUndermine
|
# define inflateUndermine z_inflateUndermine
|
||||||
|
# define inflateResetKeep z_inflateResetKeep
|
||||||
# define inflate_copyright z_inflate_copyright
|
# define inflate_copyright z_inflate_copyright
|
||||||
# define inflate_fast z_inflate_fast
|
# define inflate_fast z_inflate_fast
|
||||||
# define inflate_table z_inflate_table
|
# define inflate_table z_inflate_table
|
||||||
# define uncompress z_uncompress
|
# ifndef Z_SOLO
|
||||||
|
# define uncompress z_uncompress
|
||||||
|
# endif
|
||||||
# define zError z_zError
|
# define zError z_zError
|
||||||
# define zcalloc z_zcalloc
|
# ifndef Z_SOLO
|
||||||
# define zcfree z_zcfree
|
# define zcalloc z_zcalloc
|
||||||
|
# define zcfree z_zcfree
|
||||||
|
# endif
|
||||||
# define zlibCompileFlags z_zlibCompileFlags
|
# define zlibCompileFlags z_zlibCompileFlags
|
||||||
# define zlibVersion z_zlibVersion
|
# define zlibVersion z_zlibVersion
|
||||||
|
|
||||||
|
@ -111,7 +132,9 @@
|
||||||
# define alloc_func z_alloc_func
|
# define alloc_func z_alloc_func
|
||||||
# define charf z_charf
|
# define charf z_charf
|
||||||
# define free_func z_free_func
|
# define free_func z_free_func
|
||||||
# define gzFile z_gzFile
|
# ifndef Z_SOLO
|
||||||
|
# define gzFile z_gzFile
|
||||||
|
# endif
|
||||||
# define gz_header z_gz_header
|
# define gz_header z_gz_header
|
||||||
# define gz_headerp z_gz_headerp
|
# define gz_headerp z_gz_headerp
|
||||||
# define in_func z_in_func
|
# define in_func z_in_func
|
||||||
|
@ -197,6 +220,12 @@
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(ZLIB_CONST) && !defined(z_const)
|
||||||
|
# define z_const const
|
||||||
|
#else
|
||||||
|
# define z_const
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Some Mac compilers merge all .h files incorrectly: */
|
/* Some Mac compilers merge all .h files incorrectly: */
|
||||||
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
|
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
|
||||||
# define NO_DUMMY_DECL
|
# define NO_DUMMY_DECL
|
||||||
|
@ -243,6 +272,14 @@
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef Z_ARG /* function prototypes for stdarg */
|
||||||
|
# if defined(STDC) || defined(Z_HAVE_STDARG_H)
|
||||||
|
# define Z_ARG(args) args
|
||||||
|
# else
|
||||||
|
# define Z_ARG(args) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* The following definitions for FAR are needed only for MSDOS mixed
|
/* The following definitions for FAR are needed only for MSDOS mixed
|
||||||
* model programming (small or medium model with some far allocations).
|
* model programming (small or medium model with some far allocations).
|
||||||
* This was tested only with MSC; for other MSDOS compilers you may have
|
* This was tested only with MSC; for other MSDOS compilers you may have
|
||||||
|
@ -356,12 +393,47 @@ typedef uLong FAR uLongf;
|
||||||
typedef Byte *voidp;
|
typedef Byte *voidp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
|
||||||
|
# include <limits.h>
|
||||||
|
# if (UINT_MAX == 0xffffffffUL)
|
||||||
|
# define Z_U4 unsigned
|
||||||
|
# elif (ULONG_MAX == 0xffffffffUL)
|
||||||
|
# define Z_U4 unsigned long
|
||||||
|
# elif (USHRT_MAX == 0xffffffffUL)
|
||||||
|
# define Z_U4 unsigned short
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef Z_U4
|
||||||
|
typedef Z_U4 z_crc_t;
|
||||||
|
#else
|
||||||
|
typedef unsigned long z_crc_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
|
#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
|
||||||
# define Z_HAVE_UNISTD_H
|
# define Z_HAVE_UNISTD_H
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */
|
||||||
|
# define Z_HAVE_STDARG_H
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef STDC
|
#ifdef STDC
|
||||||
# include <sys/types.h> /* for off_t */
|
# ifndef Z_SOLO
|
||||||
|
# include <sys/types.h> /* for off_t */
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
|
||||||
|
# ifndef Z_SOLO
|
||||||
|
# include <stdarg.h> /* for va_list */
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
# ifndef Z_SOLO
|
||||||
|
# include <stddef.h> /* for wchar_t */
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
|
/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
|
||||||
|
@ -370,21 +442,38 @@ typedef uLong FAR uLongf;
|
||||||
* both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
|
* both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
|
||||||
* equivalently requesting no 64-bit operations
|
* equivalently requesting no 64-bit operations
|
||||||
*/
|
*/
|
||||||
#if -_LARGEFILE64_SOURCE - -1 == 1
|
#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
|
||||||
# undef _LARGEFILE64_SOURCE
|
# undef _LARGEFILE64_SOURCE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
|
#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
|
||||||
# include <unistd.h> /* for SEEK_* and off_t */
|
# define Z_HAVE_UNISTD_H
|
||||||
# ifdef VMS
|
#endif
|
||||||
# include <unixio.h> /* for off_t */
|
#ifndef Z_SOLO
|
||||||
# endif
|
# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
|
||||||
# ifndef z_off_t
|
# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
|
||||||
# define z_off_t off_t
|
# ifdef VMS
|
||||||
|
# include <unixio.h> /* for off_t */
|
||||||
|
# endif
|
||||||
|
# ifndef z_off_t
|
||||||
|
# define z_off_t off_t
|
||||||
|
# endif
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef SEEK_SET
|
#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
|
||||||
|
# define Z_LFS64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
|
||||||
|
# define Z_LARGE64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
|
||||||
|
# define Z_WANT64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(SEEK_SET) && !defined(Z_SOLO)
|
||||||
# define SEEK_SET 0 /* Seek from beginning of file. */
|
# define SEEK_SET 0 /* Seek from beginning of file. */
|
||||||
# define SEEK_CUR 1 /* Seek from current position. */
|
# define SEEK_CUR 1 /* Seek from current position. */
|
||||||
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
|
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
|
||||||
|
@ -394,18 +483,14 @@ typedef uLong FAR uLongf;
|
||||||
# define z_off_t long
|
# define z_off_t long
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
|
#if !defined(_WIN32) && defined(Z_LARGE64)
|
||||||
# define z_off64_t off64_t
|
# define z_off64_t off64_t
|
||||||
#else
|
#else
|
||||||
# define z_off64_t z_off_t
|
# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
|
||||||
#endif
|
# define z_off64_t __int64
|
||||||
|
# else
|
||||||
#if defined(__OS400__)
|
# define z_off64_t z_off_t
|
||||||
# define NO_vsnprintf
|
# endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__MVS__)
|
|
||||||
# define NO_vsnprintf
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* MVS linker does not support external names larger than 8 bytes */
|
/* MVS linker does not support external names larger than 8 bytes */
|
|
@ -1,7 +1,7 @@
|
||||||
/* zlib.h -- interface of the 'zlib' general purpose compression library
|
/* zlib.h -- interface of the 'zlib' general purpose compression library
|
||||||
version 1.2.5, April 19th, 2010
|
version 1.2.8, April 28th, 2013
|
||||||
|
|
||||||
Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
|
Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any damages
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
@ -24,8 +24,8 @@
|
||||||
|
|
||||||
|
|
||||||
The data format used by the zlib library is described by RFCs (Request for
|
The data format used by the zlib library is described by RFCs (Request for
|
||||||
Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
|
Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
|
||||||
(zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
|
(zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ZLIB_H
|
#ifndef ZLIB_H
|
||||||
|
@ -37,11 +37,11 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ZLIB_VERSION "1.2.5"
|
#define ZLIB_VERSION "1.2.8"
|
||||||
#define ZLIB_VERNUM 0x1250
|
#define ZLIB_VERNUM 0x1280
|
||||||
#define ZLIB_VER_MAJOR 1
|
#define ZLIB_VER_MAJOR 1
|
||||||
#define ZLIB_VER_MINOR 2
|
#define ZLIB_VER_MINOR 2
|
||||||
#define ZLIB_VER_REVISION 5
|
#define ZLIB_VER_REVISION 8
|
||||||
#define ZLIB_VER_SUBREVISION 0
|
#define ZLIB_VER_SUBREVISION 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -83,15 +83,15 @@ typedef void (*free_func) OF((voidpf opaque, voidpf address));
|
||||||
struct internal_state;
|
struct internal_state;
|
||||||
|
|
||||||
typedef struct z_stream_s {
|
typedef struct z_stream_s {
|
||||||
Bytef *next_in; /* next input byte */
|
z_const Bytef *next_in; /* next input byte */
|
||||||
uInt avail_in; /* number of bytes available at next_in */
|
uInt avail_in; /* number of bytes available at next_in */
|
||||||
uLong total_in; /* total nb of input bytes read so far */
|
uLong total_in; /* total number of input bytes read so far */
|
||||||
|
|
||||||
Bytef *next_out; /* next output byte should be put there */
|
Bytef *next_out; /* next output byte should be put there */
|
||||||
uInt avail_out; /* remaining free space at next_out */
|
uInt avail_out; /* remaining free space at next_out */
|
||||||
uLong total_out; /* total nb of bytes output so far */
|
uLong total_out; /* total number of bytes output so far */
|
||||||
|
|
||||||
char *msg; /* last error message, NULL if no error */
|
z_const char *msg; /* last error message, NULL if no error */
|
||||||
struct internal_state FAR *state; /* not visible by applications */
|
struct internal_state FAR *state; /* not visible by applications */
|
||||||
|
|
||||||
alloc_func zalloc; /* used to allocate the internal state */
|
alloc_func zalloc; /* used to allocate the internal state */
|
||||||
|
@ -327,8 +327,9 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
|
||||||
|
|
||||||
Z_FINISH can be used immediately after deflateInit if all the compression
|
Z_FINISH can be used immediately after deflateInit if all the compression
|
||||||
is to be done in a single step. In this case, avail_out must be at least the
|
is to be done in a single step. In this case, avail_out must be at least the
|
||||||
value returned by deflateBound (see below). If deflate does not return
|
value returned by deflateBound (see below). Then deflate is guaranteed to
|
||||||
Z_STREAM_END, then it must be called again as described above.
|
return Z_STREAM_END. If not enough output space is provided, deflate will
|
||||||
|
not return Z_STREAM_END, and it must be called again as described above.
|
||||||
|
|
||||||
deflate() sets strm->adler to the adler32 checksum of all input read
|
deflate() sets strm->adler to the adler32 checksum of all input read
|
||||||
so far (that is, total_in bytes).
|
so far (that is, total_in bytes).
|
||||||
|
@ -451,23 +452,29 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
|
||||||
error. However if all decompression is to be performed in a single step (a
|
error. However if all decompression is to be performed in a single step (a
|
||||||
single call of inflate), the parameter flush should be set to Z_FINISH. In
|
single call of inflate), the parameter flush should be set to Z_FINISH. In
|
||||||
this case all pending input is processed and all pending output is flushed;
|
this case all pending input is processed and all pending output is flushed;
|
||||||
avail_out must be large enough to hold all the uncompressed data. (The size
|
avail_out must be large enough to hold all of the uncompressed data for the
|
||||||
of the uncompressed data may have been saved by the compressor for this
|
operation to complete. (The size of the uncompressed data may have been
|
||||||
purpose.) The next operation on this stream must be inflateEnd to deallocate
|
saved by the compressor for this purpose.) The use of Z_FINISH is not
|
||||||
the decompression state. The use of Z_FINISH is never required, but can be
|
required to perform an inflation in one step. However it may be used to
|
||||||
used to inform inflate that a faster approach may be used for the single
|
inform inflate that a faster approach can be used for the single inflate()
|
||||||
inflate() call.
|
call. Z_FINISH also informs inflate to not maintain a sliding window if the
|
||||||
|
stream completes, which reduces inflate's memory footprint. If the stream
|
||||||
|
does not complete, either because not all of the stream is provided or not
|
||||||
|
enough output space is provided, then a sliding window will be allocated and
|
||||||
|
inflate() can be called again to continue the operation as if Z_NO_FLUSH had
|
||||||
|
been used.
|
||||||
|
|
||||||
In this implementation, inflate() always flushes as much output as
|
In this implementation, inflate() always flushes as much output as
|
||||||
possible to the output buffer, and always uses the faster approach on the
|
possible to the output buffer, and always uses the faster approach on the
|
||||||
first call. So the only effect of the flush parameter in this implementation
|
first call. So the effects of the flush parameter in this implementation are
|
||||||
is on the return value of inflate(), as noted below, or when it returns early
|
on the return value of inflate() as noted below, when inflate() returns early
|
||||||
because Z_BLOCK or Z_TREES is used.
|
when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of
|
||||||
|
memory for a sliding window when Z_FINISH is used.
|
||||||
|
|
||||||
If a preset dictionary is needed after this call (see inflateSetDictionary
|
If a preset dictionary is needed after this call (see inflateSetDictionary
|
||||||
below), inflate sets strm->adler to the adler32 checksum of the dictionary
|
below), inflate sets strm->adler to the Adler-32 checksum of the dictionary
|
||||||
chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
|
chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
|
||||||
strm->adler to the adler32 checksum of all output produced so far (that is,
|
strm->adler to the Adler-32 checksum of all output produced so far (that is,
|
||||||
total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
|
total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
|
||||||
below. At the end of the stream, inflate() checks that its computed adler32
|
below. At the end of the stream, inflate() checks that its computed adler32
|
||||||
checksum is equal to that saved by the compressor and returns Z_STREAM_END
|
checksum is equal to that saved by the compressor and returns Z_STREAM_END
|
||||||
|
@ -478,7 +485,9 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
|
||||||
initializing with inflateInit2(). Any information contained in the gzip
|
initializing with inflateInit2(). Any information contained in the gzip
|
||||||
header is not retained, so applications that need that information should
|
header is not retained, so applications that need that information should
|
||||||
instead use raw inflate, see inflateInit2() below, or inflateBack() and
|
instead use raw inflate, see inflateInit2() below, or inflateBack() and
|
||||||
perform their own processing of the gzip header and trailer.
|
perform their own processing of the gzip header and trailer. When processing
|
||||||
|
gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output
|
||||||
|
producted so far. The CRC-32 is checked against the gzip trailer.
|
||||||
|
|
||||||
inflate() returns Z_OK if some progress has been made (more input processed
|
inflate() returns Z_OK if some progress has been made (more input processed
|
||||||
or more output produced), Z_STREAM_END if the end of the compressed data has
|
or more output produced), Z_STREAM_END if the end of the compressed data has
|
||||||
|
@ -580,10 +589,15 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
|
||||||
uInt dictLength));
|
uInt dictLength));
|
||||||
/*
|
/*
|
||||||
Initializes the compression dictionary from the given byte sequence
|
Initializes the compression dictionary from the given byte sequence
|
||||||
without producing any compressed output. This function must be called
|
without producing any compressed output. When using the zlib format, this
|
||||||
immediately after deflateInit, deflateInit2 or deflateReset, before any call
|
function must be called immediately after deflateInit, deflateInit2 or
|
||||||
of deflate. The compressor and decompressor must use exactly the same
|
deflateReset, and before any call of deflate. When doing raw deflate, this
|
||||||
dictionary (see inflateSetDictionary).
|
function must be called either before any call of deflate, or immediately
|
||||||
|
after the completion of a deflate block, i.e. after all input has been
|
||||||
|
consumed and all output has been delivered when using any of the flush
|
||||||
|
options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The
|
||||||
|
compressor and decompressor must use exactly the same dictionary (see
|
||||||
|
inflateSetDictionary).
|
||||||
|
|
||||||
The dictionary should consist of strings (byte sequences) that are likely
|
The dictionary should consist of strings (byte sequences) that are likely
|
||||||
to be encountered later in the data to be compressed, with the most commonly
|
to be encountered later in the data to be compressed, with the most commonly
|
||||||
|
@ -610,8 +624,8 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
|
||||||
deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
|
deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
|
||||||
parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
|
parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
|
||||||
inconsistent (for example if deflate has already been called for this stream
|
inconsistent (for example if deflate has already been called for this stream
|
||||||
or if the compression method is bsort). deflateSetDictionary does not
|
or if not at a block boundary for raw deflate). deflateSetDictionary does
|
||||||
perform any compression: this will be done by deflate().
|
not perform any compression: this will be done by deflate().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
|
ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
|
||||||
|
@ -688,9 +702,29 @@ ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
|
||||||
deflation of sourceLen bytes. It must be called after deflateInit() or
|
deflation of sourceLen bytes. It must be called after deflateInit() or
|
||||||
deflateInit2(), and after deflateSetHeader(), if used. This would be used
|
deflateInit2(), and after deflateSetHeader(), if used. This would be used
|
||||||
to allocate an output buffer for deflation in a single pass, and so would be
|
to allocate an output buffer for deflation in a single pass, and so would be
|
||||||
called before deflate().
|
called before deflate(). If that first deflate() call is provided the
|
||||||
|
sourceLen input bytes, an output buffer allocated to the size returned by
|
||||||
|
deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed
|
||||||
|
to return Z_STREAM_END. Note that it is possible for the compressed size to
|
||||||
|
be larger than the value returned by deflateBound() if flush options other
|
||||||
|
than Z_FINISH or Z_NO_FLUSH are used.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
|
||||||
|
unsigned *pending,
|
||||||
|
int *bits));
|
||||||
|
/*
|
||||||
|
deflatePending() returns the number of bytes and bits of output that have
|
||||||
|
been generated, but not yet provided in the available output. The bytes not
|
||||||
|
provided would be due to the available output space having being consumed.
|
||||||
|
The number of bits of output not provided are between 0 and 7, where they
|
||||||
|
await more bits to join them in order to fill out a full byte. If pending
|
||||||
|
or bits are Z_NULL, then those values are not set.
|
||||||
|
|
||||||
|
deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source
|
||||||
|
stream state was inconsistent.
|
||||||
|
*/
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
|
ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
|
||||||
int bits,
|
int bits,
|
||||||
int value));
|
int value));
|
||||||
|
@ -703,8 +737,9 @@ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
|
||||||
than or equal to 16, and that many of the least significant bits of value
|
than or equal to 16, and that many of the least significant bits of value
|
||||||
will be inserted in the output.
|
will be inserted in the output.
|
||||||
|
|
||||||
deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
|
deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough
|
||||||
stream state was inconsistent.
|
room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the
|
||||||
|
source stream state was inconsistent.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
|
ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
|
||||||
|
@ -790,10 +825,11 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
|
||||||
if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
|
if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
|
||||||
can be determined from the adler32 value returned by that call of inflate.
|
can be determined from the adler32 value returned by that call of inflate.
|
||||||
The compressor and decompressor must use exactly the same dictionary (see
|
The compressor and decompressor must use exactly the same dictionary (see
|
||||||
deflateSetDictionary). For raw inflate, this function can be called
|
deflateSetDictionary). For raw inflate, this function can be called at any
|
||||||
immediately after inflateInit2() or inflateReset() and before any call of
|
time to set the dictionary. If the provided dictionary is smaller than the
|
||||||
inflate() to set the dictionary. The application must insure that the
|
window and there is already data in the window, then the provided dictionary
|
||||||
dictionary that was used for compression is provided.
|
will amend what's there. The application must insure that the dictionary
|
||||||
|
that was used for compression is provided.
|
||||||
|
|
||||||
inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
|
inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
|
||||||
parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
|
parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
|
||||||
|
@ -803,19 +839,38 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
|
||||||
inflate().
|
inflate().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm,
|
||||||
|
Bytef *dictionary,
|
||||||
|
uInt *dictLength));
|
||||||
|
/*
|
||||||
|
Returns the sliding dictionary being maintained by inflate. dictLength is
|
||||||
|
set to the number of bytes in the dictionary, and that many bytes are copied
|
||||||
|
to dictionary. dictionary must have enough space, where 32768 bytes is
|
||||||
|
always enough. If inflateGetDictionary() is called with dictionary equal to
|
||||||
|
Z_NULL, then only the dictionary length is returned, and nothing is copied.
|
||||||
|
Similary, if dictLength is Z_NULL, then it is not set.
|
||||||
|
|
||||||
|
inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the
|
||||||
|
stream state is inconsistent.
|
||||||
|
*/
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
|
ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
|
||||||
/*
|
/*
|
||||||
Skips invalid compressed data until a full flush point (see above the
|
Skips invalid compressed data until a possible full flush point (see above
|
||||||
description of deflate with Z_FULL_FLUSH) can be found, or until all
|
for the description of deflate with Z_FULL_FLUSH) can be found, or until all
|
||||||
available input is skipped. No output is provided.
|
available input is skipped. No output is provided.
|
||||||
|
|
||||||
inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
|
inflateSync searches for a 00 00 FF FF pattern in the compressed data.
|
||||||
if no more input was provided, Z_DATA_ERROR if no flush point has been
|
All full flush points have this pattern, but not all occurrences of this
|
||||||
found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the
|
pattern are full flush points.
|
||||||
success case, the application may save the current current value of total_in
|
|
||||||
which indicates where valid compressed data was found. In the error case,
|
inflateSync returns Z_OK if a possible full flush point has been found,
|
||||||
the application may repeatedly call inflateSync, providing more input each
|
Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point
|
||||||
time, until success or end of the input data.
|
has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.
|
||||||
|
In the success case, the application may save the current current value of
|
||||||
|
total_in which indicates where valid compressed data was found. In the
|
||||||
|
error case, the application may repeatedly call inflateSync, providing more
|
||||||
|
input each time, until success or end of the input data.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
|
ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
|
||||||
|
@ -962,12 +1017,13 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
|
||||||
See inflateBack() for the usage of these routines.
|
See inflateBack() for the usage of these routines.
|
||||||
|
|
||||||
inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
|
inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
|
||||||
the paramaters are invalid, Z_MEM_ERROR if the internal state could not be
|
the parameters are invalid, Z_MEM_ERROR if the internal state could not be
|
||||||
allocated, or Z_VERSION_ERROR if the version of the library does not match
|
allocated, or Z_VERSION_ERROR if the version of the library does not match
|
||||||
the version of the header file.
|
the version of the header file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
|
typedef unsigned (*in_func) OF((void FAR *,
|
||||||
|
z_const unsigned char FAR * FAR *));
|
||||||
typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
|
typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
|
ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
|
||||||
|
@ -975,11 +1031,12 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
|
||||||
out_func out, void FAR *out_desc));
|
out_func out, void FAR *out_desc));
|
||||||
/*
|
/*
|
||||||
inflateBack() does a raw inflate with a single call using a call-back
|
inflateBack() does a raw inflate with a single call using a call-back
|
||||||
interface for input and output. This is more efficient than inflate() for
|
interface for input and output. This is potentially more efficient than
|
||||||
file i/o applications in that it avoids copying between the output and the
|
inflate() for file i/o applications, in that it avoids copying between the
|
||||||
sliding window by simply making the window itself the output buffer. This
|
output and the sliding window by simply making the window itself the output
|
||||||
function trusts the application to not change the output buffer passed by
|
buffer. inflate() can be faster on modern CPUs when used with large
|
||||||
the output function, at least until inflateBack() returns.
|
buffers. inflateBack() trusts the application to not change the output
|
||||||
|
buffer passed by the output function, at least until inflateBack() returns.
|
||||||
|
|
||||||
inflateBackInit() must be called first to allocate the internal state
|
inflateBackInit() must be called first to allocate the internal state
|
||||||
and to initialize the state with the user-provided window buffer.
|
and to initialize the state with the user-provided window buffer.
|
||||||
|
@ -1088,6 +1145,7 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
|
||||||
27-31: 0 (reserved)
|
27-31: 0 (reserved)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef Z_SOLO
|
||||||
|
|
||||||
/* utility functions */
|
/* utility functions */
|
||||||
|
|
||||||
|
@ -1149,10 +1207,11 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
|
||||||
|
|
||||||
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
|
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
|
||||||
enough memory, Z_BUF_ERROR if there was not enough room in the output
|
enough memory, Z_BUF_ERROR if there was not enough room in the output
|
||||||
buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
|
buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In
|
||||||
|
the case where there is not enough room, uncompress() will fill the output
|
||||||
|
buffer with the uncompressed data up to that point.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* gzip file access functions */
|
/* gzip file access functions */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1162,7 +1221,7 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
|
||||||
wrapper, documented in RFC 1952, wrapped around a deflate stream.
|
wrapper, documented in RFC 1952, wrapped around a deflate stream.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef voidp gzFile; /* opaque gzip file descriptor */
|
typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
|
ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
|
||||||
|
@ -1172,13 +1231,28 @@ ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
|
||||||
a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
|
a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
|
||||||
compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
|
compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
|
||||||
for fixed code compression as in "wb9F". (See the description of
|
for fixed code compression as in "wb9F". (See the description of
|
||||||
deflateInit2 for more information about the strategy parameter.) Also "a"
|
deflateInit2 for more information about the strategy parameter.) 'T' will
|
||||||
can be used instead of "w" to request that the gzip stream that will be
|
request transparent writing or appending with no compression and not using
|
||||||
written be appended to the file. "+" will result in an error, since reading
|
the gzip format.
|
||||||
and writing to the same gzip file is not supported.
|
|
||||||
|
"a" can be used instead of "w" to request that the gzip stream that will
|
||||||
|
be written be appended to the file. "+" will result in an error, since
|
||||||
|
reading and writing to the same gzip file is not supported. The addition of
|
||||||
|
"x" when writing will create the file exclusively, which fails if the file
|
||||||
|
already exists. On systems that support it, the addition of "e" when
|
||||||
|
reading or writing will set the flag to close the file on an execve() call.
|
||||||
|
|
||||||
|
These functions, as well as gzip, will read and decode a sequence of gzip
|
||||||
|
streams in a file. The append function of gzopen() can be used to create
|
||||||
|
such a file. (Also see gzflush() for another way to do this.) When
|
||||||
|
appending, gzopen does not test whether the file begins with a gzip stream,
|
||||||
|
nor does it look for the end of the gzip streams to begin appending. gzopen
|
||||||
|
will simply append a gzip stream to the existing file.
|
||||||
|
|
||||||
gzopen can be used to read a file which is not in gzip format; in this
|
gzopen can be used to read a file which is not in gzip format; in this
|
||||||
case gzread will directly read from the file without decompression.
|
case gzread will directly read from the file without decompression. When
|
||||||
|
reading, this will be detected automatically by looking for the magic two-
|
||||||
|
byte gzip header.
|
||||||
|
|
||||||
gzopen returns NULL if the file could not be opened, if there was
|
gzopen returns NULL if the file could not be opened, if there was
|
||||||
insufficient memory to allocate the gzFile state, or if an invalid mode was
|
insufficient memory to allocate the gzFile state, or if an invalid mode was
|
||||||
|
@ -1197,7 +1271,11 @@ ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
|
||||||
descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
|
descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
|
||||||
fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
|
fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
|
||||||
mode);. The duplicated descriptor should be saved to avoid a leak, since
|
mode);. The duplicated descriptor should be saved to avoid a leak, since
|
||||||
gzdopen does not close fd if it fails.
|
gzdopen does not close fd if it fails. If you are using fileno() to get the
|
||||||
|
file descriptor from a FILE *, then you will have to use dup() to avoid
|
||||||
|
double-close()ing the file descriptor. Both gzclose() and fclose() will
|
||||||
|
close the associated file descriptor, so they need to have different file
|
||||||
|
descriptors.
|
||||||
|
|
||||||
gzdopen returns NULL if there was insufficient memory to allocate the
|
gzdopen returns NULL if there was insufficient memory to allocate the
|
||||||
gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
|
gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
|
||||||
|
@ -1235,14 +1313,26 @@ ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
|
||||||
ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
|
ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
|
||||||
/*
|
/*
|
||||||
Reads the given number of uncompressed bytes from the compressed file. If
|
Reads the given number of uncompressed bytes from the compressed file. If
|
||||||
the input file was not in gzip format, gzread copies the given number of
|
the input file is not in gzip format, gzread copies the given number of
|
||||||
bytes into the buffer.
|
bytes into the buffer directly from the file.
|
||||||
|
|
||||||
After reaching the end of a gzip stream in the input, gzread will continue
|
After reaching the end of a gzip stream in the input, gzread will continue
|
||||||
to read, looking for another gzip stream, or failing that, reading the rest
|
to read, looking for another gzip stream. Any number of gzip streams may be
|
||||||
of the input file directly without decompression. The entire input file
|
concatenated in the input file, and will all be decompressed by gzread().
|
||||||
will be read if gzread is called until it returns less than the requested
|
If something other than a gzip stream is encountered after a gzip stream,
|
||||||
len.
|
that remaining trailing garbage is ignored (and no error is returned).
|
||||||
|
|
||||||
|
gzread can be used to read a gzip file that is being concurrently written.
|
||||||
|
Upon reaching the end of the input, gzread will return with the available
|
||||||
|
data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then
|
||||||
|
gzclearerr can be used to clear the end of file indicator in order to permit
|
||||||
|
gzread to be tried again. Z_OK indicates that a gzip stream was completed
|
||||||
|
on the last gzread. Z_BUF_ERROR indicates that the input file ended in the
|
||||||
|
middle of a gzip stream. Note that gzread does not return -1 in the event
|
||||||
|
of an incomplete gzip stream. This error is deferred until gzclose(), which
|
||||||
|
will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip
|
||||||
|
stream. Alternatively, gzerror can be used before gzclose to detect this
|
||||||
|
case.
|
||||||
|
|
||||||
gzread returns the number of uncompressed bytes actually read, less than
|
gzread returns the number of uncompressed bytes actually read, less than
|
||||||
len for end of file, or -1 for error.
|
len for end of file, or -1 for error.
|
||||||
|
@ -1256,7 +1346,7 @@ ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
|
||||||
error.
|
error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
|
ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
|
||||||
/*
|
/*
|
||||||
Converts, formats, and writes the arguments to the compressed file under
|
Converts, formats, and writes the arguments to the compressed file under
|
||||||
control of the format string, as in fprintf. gzprintf returns the number of
|
control of the format string, as in fprintf. gzprintf returns the number of
|
||||||
|
@ -1301,7 +1391,10 @@ ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
|
||||||
ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
|
ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
|
||||||
/*
|
/*
|
||||||
Reads one byte from the compressed file. gzgetc returns this byte or -1
|
Reads one byte from the compressed file. gzgetc returns this byte or -1
|
||||||
in case of end of file or error.
|
in case of end of file or error. This is implemented as a macro for speed.
|
||||||
|
As such, it does not do all of the checking the other functions do. I.e.
|
||||||
|
it does not check to see if file is NULL, nor whether the structure file
|
||||||
|
points to has been clobbered or not.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
|
ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
|
||||||
|
@ -1397,9 +1490,7 @@ ZEXTERN int ZEXPORT gzeof OF((gzFile file));
|
||||||
ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
|
ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
|
||||||
/*
|
/*
|
||||||
Returns true (1) if file is being copied directly while reading, or false
|
Returns true (1) if file is being copied directly while reading, or false
|
||||||
(0) if file is a gzip stream being decompressed. This state can change from
|
(0) if file is a gzip stream being decompressed.
|
||||||
false to true while reading the input file if the end of a gzip stream is
|
|
||||||
reached, but is followed by data that is not another gzip stream.
|
|
||||||
|
|
||||||
If the input file is empty, gzdirect() will return true, since the input
|
If the input file is empty, gzdirect() will return true, since the input
|
||||||
does not contain a gzip stream.
|
does not contain a gzip stream.
|
||||||
|
@ -1408,6 +1499,13 @@ ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
|
||||||
cause buffers to be allocated to allow reading the file to determine if it
|
cause buffers to be allocated to allow reading the file to determine if it
|
||||||
is a gzip file. Therefore if gzbuffer() is used, it should be called before
|
is a gzip file. Therefore if gzbuffer() is used, it should be called before
|
||||||
gzdirect().
|
gzdirect().
|
||||||
|
|
||||||
|
When writing, gzdirect() returns true (1) if transparent writing was
|
||||||
|
requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note:
|
||||||
|
gzdirect() is not needed when writing. Transparent writing must be
|
||||||
|
explicitly requested, so the application already knows the answer. When
|
||||||
|
linking statically, using gzdirect() will include all of the zlib code for
|
||||||
|
gzip file reading and decompression, which may not be desired.)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT gzclose OF((gzFile file));
|
ZEXTERN int ZEXPORT gzclose OF((gzFile file));
|
||||||
|
@ -1419,7 +1517,8 @@ ZEXTERN int ZEXPORT gzclose OF((gzFile file));
|
||||||
must not be called more than once on the same allocation.
|
must not be called more than once on the same allocation.
|
||||||
|
|
||||||
gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
|
gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
|
||||||
file operation error, or Z_OK on success.
|
file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the
|
||||||
|
last read ended in the middle of a gzip stream, or Z_OK on success.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
|
ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
|
||||||
|
@ -1457,6 +1556,7 @@ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
|
||||||
file that is being written concurrently.
|
file that is being written concurrently.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#endif /* !Z_SOLO */
|
||||||
|
|
||||||
/* checksum functions */
|
/* checksum functions */
|
||||||
|
|
||||||
|
@ -1492,16 +1592,17 @@ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
|
||||||
Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
|
Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
|
||||||
and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
|
and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
|
||||||
each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
|
each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
|
||||||
seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
|
seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note
|
||||||
|
that the z_off_t type (like off_t) is a signed integer. If len2 is
|
||||||
|
negative, the result has no meaning or utility.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
|
ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
|
||||||
/*
|
/*
|
||||||
Update a running CRC-32 with the bytes buf[0..len-1] and return the
|
Update a running CRC-32 with the bytes buf[0..len-1] and return the
|
||||||
updated CRC-32. If buf is Z_NULL, this function returns the required
|
updated CRC-32. If buf is Z_NULL, this function returns the required
|
||||||
initial value for the for the crc. Pre- and post-conditioning (one's
|
initial value for the crc. Pre- and post-conditioning (one's complement) is
|
||||||
complement) is performed within this function so it shouldn't be done by the
|
performed within this function so it shouldn't be done by the application.
|
||||||
application.
|
|
||||||
|
|
||||||
Usage example:
|
Usage example:
|
||||||
|
|
||||||
|
@ -1544,17 +1645,42 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
|
||||||
const char *version,
|
const char *version,
|
||||||
int stream_size));
|
int stream_size));
|
||||||
#define deflateInit(strm, level) \
|
#define deflateInit(strm, level) \
|
||||||
deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
|
deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
|
||||||
#define inflateInit(strm) \
|
#define inflateInit(strm) \
|
||||||
inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
|
inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
|
||||||
#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
|
#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
|
||||||
deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
|
deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
|
||||||
(strategy), ZLIB_VERSION, sizeof(z_stream))
|
(strategy), ZLIB_VERSION, (int)sizeof(z_stream))
|
||||||
#define inflateInit2(strm, windowBits) \
|
#define inflateInit2(strm, windowBits) \
|
||||||
inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
|
inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
|
||||||
|
(int)sizeof(z_stream))
|
||||||
#define inflateBackInit(strm, windowBits, window) \
|
#define inflateBackInit(strm, windowBits, window) \
|
||||||
inflateBackInit_((strm), (windowBits), (window), \
|
inflateBackInit_((strm), (windowBits), (window), \
|
||||||
ZLIB_VERSION, sizeof(z_stream))
|
ZLIB_VERSION, (int)sizeof(z_stream))
|
||||||
|
|
||||||
|
#ifndef Z_SOLO
|
||||||
|
|
||||||
|
/* gzgetc() macro and its supporting function and exposed data structure. Note
|
||||||
|
* that the real internal state is much larger than the exposed structure.
|
||||||
|
* This abbreviated structure exposes just enough for the gzgetc() macro. The
|
||||||
|
* user should not mess with these exposed elements, since their names or
|
||||||
|
* behavior could change in the future, perhaps even capriciously. They can
|
||||||
|
* only be used by the gzgetc() macro. You have been warned.
|
||||||
|
*/
|
||||||
|
struct gzFile_s {
|
||||||
|
unsigned have;
|
||||||
|
unsigned char *next;
|
||||||
|
z_off64_t pos;
|
||||||
|
};
|
||||||
|
ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
|
||||||
|
#ifdef Z_PREFIX_SET
|
||||||
|
# undef z_gzgetc
|
||||||
|
# define z_gzgetc(g) \
|
||||||
|
((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
|
||||||
|
#else
|
||||||
|
# define gzgetc(g) \
|
||||||
|
((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
|
||||||
|
#endif
|
||||||
|
|
||||||
/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
|
/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
|
||||||
* change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
|
* change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
|
||||||
|
@ -1562,7 +1688,7 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
|
||||||
* functions are changed to 64 bits) -- in case these are set on systems
|
* functions are changed to 64 bits) -- in case these are set on systems
|
||||||
* without large file support, _LFS64_LARGEFILE must also be true
|
* without large file support, _LFS64_LARGEFILE must also be true
|
||||||
*/
|
*/
|
||||||
#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
|
#ifdef Z_LARGE64
|
||||||
ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
|
ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
|
||||||
ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
|
ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
|
||||||
ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
|
ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
|
||||||
|
@ -1571,14 +1697,23 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
|
||||||
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
|
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0
|
#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)
|
||||||
# define gzopen gzopen64
|
# ifdef Z_PREFIX_SET
|
||||||
# define gzseek gzseek64
|
# define z_gzopen z_gzopen64
|
||||||
# define gztell gztell64
|
# define z_gzseek z_gzseek64
|
||||||
# define gzoffset gzoffset64
|
# define z_gztell z_gztell64
|
||||||
# define adler32_combine adler32_combine64
|
# define z_gzoffset z_gzoffset64
|
||||||
# define crc32_combine crc32_combine64
|
# define z_adler32_combine z_adler32_combine64
|
||||||
# ifdef _LARGEFILE64_SOURCE
|
# define z_crc32_combine z_crc32_combine64
|
||||||
|
# else
|
||||||
|
# define gzopen gzopen64
|
||||||
|
# define gzseek gzseek64
|
||||||
|
# define gztell gztell64
|
||||||
|
# define gzoffset gzoffset64
|
||||||
|
# define adler32_combine adler32_combine64
|
||||||
|
# define crc32_combine crc32_combine64
|
||||||
|
# endif
|
||||||
|
# ifndef Z_LARGE64
|
||||||
ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
|
ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
|
||||||
ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
|
ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
|
||||||
ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
|
ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
|
||||||
|
@ -1595,6 +1730,13 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
|
||||||
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
|
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#else /* Z_SOLO */
|
||||||
|
|
||||||
|
ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
|
||||||
|
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
|
||||||
|
|
||||||
|
#endif /* !Z_SOLO */
|
||||||
|
|
||||||
/* hack for buggy compilers */
|
/* hack for buggy compilers */
|
||||||
#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
|
#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
|
||||||
struct internal_state {int dummy;};
|
struct internal_state {int dummy;};
|
||||||
|
@ -1603,8 +1745,21 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
|
||||||
/* undocumented functions */
|
/* undocumented functions */
|
||||||
ZEXTERN const char * ZEXPORT zError OF((int));
|
ZEXTERN const char * ZEXPORT zError OF((int));
|
||||||
ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp));
|
ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp));
|
||||||
ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
|
ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void));
|
||||||
ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int));
|
ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int));
|
||||||
|
ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp));
|
||||||
|
ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp));
|
||||||
|
#if defined(_WIN32) && !defined(Z_SOLO)
|
||||||
|
ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path,
|
||||||
|
const char *mode));
|
||||||
|
#endif
|
||||||
|
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
|
||||||
|
# ifndef Z_SOLO
|
||||||
|
ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file,
|
||||||
|
const char *format,
|
||||||
|
va_list va));
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
prefix=@CMAKE_INSTALL_PREFIX@
|
||||||
|
exec_prefix=@CMAKE_INSTALL_PREFIX@
|
||||||
|
libdir=@INSTALL_LIB_DIR@
|
||||||
|
sharedlibdir=@INSTALL_LIB_DIR@
|
||||||
|
includedir=@INSTALL_INC_DIR@
|
||||||
|
|
||||||
|
Name: zlib
|
||||||
|
Description: zlib compression library
|
||||||
|
Version: @VERSION@
|
||||||
|
|
||||||
|
Requires:
|
||||||
|
Libs: -L${libdir} -L${sharedlibdir} -lz
|
||||||
|
Cflags: -I${includedir}
|
|
@ -1,17 +1,20 @@
|
||||||
/* zutil.c -- target dependent utility functions for the compression library
|
/* zutil.c -- target dependent utility functions for the compression library
|
||||||
* Copyright (C) 1995-2005, 2010 Jean-loup Gailly.
|
* Copyright (C) 1995-2005, 2010, 2011, 2012 Jean-loup Gailly.
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* @(#) $Id$ */
|
/* @(#) $Id$ */
|
||||||
|
|
||||||
#include "zutil.h"
|
#include "zutil.h"
|
||||||
|
#ifndef Z_SOLO
|
||||||
|
# include "gzguts.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef NO_DUMMY_DECL
|
#ifndef NO_DUMMY_DECL
|
||||||
struct internal_state {int dummy;}; /* for buggy compilers */
|
struct internal_state {int dummy;}; /* for buggy compilers */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char * const z_errmsg[10] = {
|
z_const char * const z_errmsg[10] = {
|
||||||
"need dictionary", /* Z_NEED_DICT 2 */
|
"need dictionary", /* Z_NEED_DICT 2 */
|
||||||
"stream end", /* Z_STREAM_END 1 */
|
"stream end", /* Z_STREAM_END 1 */
|
||||||
"", /* Z_OK 0 */
|
"", /* Z_OK 0 */
|
||||||
|
@ -85,27 +88,27 @@ uLong ZEXPORT zlibCompileFlags()
|
||||||
#ifdef FASTEST
|
#ifdef FASTEST
|
||||||
flags += 1L << 21;
|
flags += 1L << 21;
|
||||||
#endif
|
#endif
|
||||||
#ifdef STDC
|
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
|
||||||
# ifdef NO_vsnprintf
|
# ifdef NO_vsnprintf
|
||||||
flags += 1L << 25;
|
flags += 1L << 25;
|
||||||
# ifdef HAS_vsprintf_void
|
# ifdef HAS_vsprintf_void
|
||||||
flags += 1L << 26;
|
flags += 1L << 26;
|
||||||
# endif
|
# endif
|
||||||
# else
|
# else
|
||||||
# ifdef HAS_vsnprintf_void
|
# ifdef HAS_vsnprintf_void
|
||||||
flags += 1L << 26;
|
flags += 1L << 26;
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
flags += 1L << 24;
|
flags += 1L << 24;
|
||||||
# ifdef NO_snprintf
|
# ifdef NO_snprintf
|
||||||
flags += 1L << 25;
|
flags += 1L << 25;
|
||||||
# ifdef HAS_sprintf_void
|
# ifdef HAS_sprintf_void
|
||||||
flags += 1L << 26;
|
flags += 1L << 26;
|
||||||
# endif
|
# endif
|
||||||
# else
|
# else
|
||||||
# ifdef HAS_snprintf_void
|
# ifdef HAS_snprintf_void
|
||||||
flags += 1L << 26;
|
flags += 1L << 26;
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -181,6 +184,7 @@ void ZLIB_INTERNAL zmemzero(dest, len)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef Z_SOLO
|
||||||
|
|
||||||
#ifdef SYS16BIT
|
#ifdef SYS16BIT
|
||||||
|
|
||||||
|
@ -316,3 +320,5 @@ void ZLIB_INTERNAL zcfree (opaque, ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* MY_ZCALLOC */
|
#endif /* MY_ZCALLOC */
|
||||||
|
|
||||||
|
#endif /* !Z_SOLO */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* zutil.h -- internal interface and configuration of the compression library
|
/* zutil.h -- internal interface and configuration of the compression library
|
||||||
* Copyright (C) 1995-2010 Jean-loup Gailly.
|
* Copyright (C) 1995-2013 Jean-loup Gailly.
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
#ifndef ZUTIL_H
|
#ifndef ZUTIL_H
|
||||||
#define ZUTIL_H
|
#define ZUTIL_H
|
||||||
|
|
||||||
#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ)
|
#ifdef HAVE_HIDDEN
|
||||||
# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
|
# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
|
||||||
#else
|
#else
|
||||||
# define ZLIB_INTERNAL
|
# define ZLIB_INTERNAL
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
#include "zlib.h"
|
#include "zlib.h"
|
||||||
|
|
||||||
#ifdef STDC
|
#if defined(STDC) && !defined(Z_SOLO)
|
||||||
# if !(defined(_WIN32_WCE) && defined(_MSC_VER))
|
# if !(defined(_WIN32_WCE) && defined(_MSC_VER))
|
||||||
# include <stddef.h>
|
# include <stddef.h>
|
||||||
# endif
|
# endif
|
||||||
|
@ -29,6 +29,10 @@
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef Z_SOLO
|
||||||
|
typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef local
|
#ifndef local
|
||||||
# define local static
|
# define local static
|
||||||
#endif
|
#endif
|
||||||
|
@ -40,13 +44,13 @@ typedef unsigned short ush;
|
||||||
typedef ush FAR ushf;
|
typedef ush FAR ushf;
|
||||||
typedef unsigned long ulg;
|
typedef unsigned long ulg;
|
||||||
|
|
||||||
extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
||||||
/* (size given to avoid silly warnings with Visual C++) */
|
/* (size given to avoid silly warnings with Visual C++) */
|
||||||
|
|
||||||
#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
|
#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
|
||||||
|
|
||||||
#define ERR_RETURN(strm,err) \
|
#define ERR_RETURN(strm,err) \
|
||||||
return (strm->msg = (char*)ERR_MSG(err), (err))
|
return (strm->msg = ERR_MSG(err), (err))
|
||||||
/* To be used only when the state is known to be valid */
|
/* To be used only when the state is known to be valid */
|
||||||
|
|
||||||
/* common constants */
|
/* common constants */
|
||||||
|
@ -78,16 +82,18 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
||||||
|
|
||||||
#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
|
#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
|
||||||
# define OS_CODE 0x00
|
# define OS_CODE 0x00
|
||||||
# if defined(__TURBOC__) || defined(__BORLANDC__)
|
# ifndef Z_SOLO
|
||||||
# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
|
# if defined(__TURBOC__) || defined(__BORLANDC__)
|
||||||
/* Allow compilation with ANSI keywords only enabled */
|
# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
|
||||||
void _Cdecl farfree( void *block );
|
/* Allow compilation with ANSI keywords only enabled */
|
||||||
void *_Cdecl farmalloc( unsigned long nbytes );
|
void _Cdecl farfree( void *block );
|
||||||
# else
|
void *_Cdecl farmalloc( unsigned long nbytes );
|
||||||
# include <alloc.h>
|
# else
|
||||||
|
# include <alloc.h>
|
||||||
|
# endif
|
||||||
|
# else /* MSC or DJGPP */
|
||||||
|
# include <malloc.h>
|
||||||
# endif
|
# endif
|
||||||
# else /* MSC or DJGPP */
|
|
||||||
# include <malloc.h>
|
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -107,18 +113,20 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
||||||
|
|
||||||
#ifdef OS2
|
#ifdef OS2
|
||||||
# define OS_CODE 0x06
|
# define OS_CODE 0x06
|
||||||
# ifdef M_I86
|
# if defined(M_I86) && !defined(Z_SOLO)
|
||||||
# include <malloc.h>
|
# include <malloc.h>
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MACOS) || defined(TARGET_OS_MAC)
|
#if defined(MACOS) || defined(TARGET_OS_MAC)
|
||||||
# define OS_CODE 0x07
|
# define OS_CODE 0x07
|
||||||
# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
|
# ifndef Z_SOLO
|
||||||
# include <unix.h> /* for fdopen */
|
# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
|
||||||
# else
|
# include <unix.h> /* for fdopen */
|
||||||
# ifndef fdopen
|
# else
|
||||||
# define fdopen(fd,mode) NULL /* No fdopen() */
|
# ifndef fdopen
|
||||||
|
# define fdopen(fd,mode) NULL /* No fdopen() */
|
||||||
|
# endif
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -153,14 +161,15 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__BORLANDC__)
|
#if defined(__BORLANDC__) && !defined(MSDOS)
|
||||||
#pragma warn -8004
|
#pragma warn -8004
|
||||||
#pragma warn -8008
|
#pragma warn -8008
|
||||||
#pragma warn -8066
|
#pragma warn -8066
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* provide prototypes for these when building zlib without LFS */
|
/* provide prototypes for these when building zlib without LFS */
|
||||||
#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0
|
#if !defined(_WIN32) && \
|
||||||
|
(!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)
|
||||||
ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
|
ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
|
||||||
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
|
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
|
||||||
#endif
|
#endif
|
||||||
|
@ -177,42 +186,7 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
||||||
|
|
||||||
/* functions */
|
/* functions */
|
||||||
|
|
||||||
#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
|
#if defined(pyr) || defined(Z_SOLO)
|
||||||
# ifndef HAVE_VSNPRINTF
|
|
||||||
# define HAVE_VSNPRINTF
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
#if defined(__CYGWIN__)
|
|
||||||
# ifndef HAVE_VSNPRINTF
|
|
||||||
# define HAVE_VSNPRINTF
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
#ifndef HAVE_VSNPRINTF
|
|
||||||
# ifdef MSDOS
|
|
||||||
/* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
|
|
||||||
but for now we just assume it doesn't. */
|
|
||||||
# define NO_vsnprintf
|
|
||||||
# endif
|
|
||||||
# ifdef __TURBOC__
|
|
||||||
# define NO_vsnprintf
|
|
||||||
# endif
|
|
||||||
# ifdef WIN32
|
|
||||||
/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
|
|
||||||
# if !defined(vsnprintf) && !defined(NO_vsnprintf)
|
|
||||||
# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )
|
|
||||||
# define vsnprintf _vsnprintf
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
# ifdef __SASC
|
|
||||||
# define NO_vsnprintf
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
#ifdef VMS
|
|
||||||
# define NO_vsnprintf
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(pyr)
|
|
||||||
# define NO_MEMCPY
|
# define NO_MEMCPY
|
||||||
#endif
|
#endif
|
||||||
#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
|
#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
|
||||||
|
@ -261,14 +235,19 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
||||||
# define Tracecv(c,x)
|
# define Tracecv(c,x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef Z_SOLO
|
||||||
voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
|
voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
|
||||||
unsigned size));
|
unsigned size));
|
||||||
void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr));
|
void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr));
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ZALLOC(strm, items, size) \
|
#define ZALLOC(strm, items, size) \
|
||||||
(*((strm)->zalloc))((strm)->opaque, (items), (size))
|
(*((strm)->zalloc))((strm)->opaque, (items), (size))
|
||||||
#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
|
#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
|
||||||
#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
|
#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
|
||||||
|
|
||||||
|
/* Reverse the bytes in a 32-bit value */
|
||||||
|
#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
|
||||||
|
(((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
|
||||||
|
|
||||||
#endif /* ZUTIL_H */
|
#endif /* ZUTIL_H */
|
||||||
|
|
|
@ -191,7 +191,7 @@ can use a comfortable installer from <a href="http://www.boost-consulting.com/pr
|
||||||
http://www.boost-consulting.com/products/free</a>. Choose the appropriate version of boost for your runtime of choice.
|
http://www.boost-consulting.com/products/free</a>. Choose the appropriate version of boost for your runtime of choice.
|
||||||
|
|
||||||
<b>If you don't want to use boost</b>, you can build against our <i>"Boost-Workaround"</i>. It consists of very small
|
<b>If you don't want to use boost</b>, you can build against our <i>"Boost-Workaround"</i>. It consists of very small
|
||||||
implementations of the various boost utility classes used. However, you'll loose functionality (e.g. threading) by doing this.
|
implementations of the various boost utility classes used. However, you'll lose functionality (e.g. threading) by doing this.
|
||||||
So, if you can use boost, you should use boost. Otherwise, See the @link use_noboost NoBoost-Section @endlink
|
So, if you can use boost, you should use boost. Otherwise, See the @link use_noboost NoBoost-Section @endlink
|
||||||
later on this page for the details of the workaround.
|
later on this page for the details of the workaround.
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
# pragma pack(push,1)
|
# pragma pack(push,1)
|
||||||
# define PACK_STRUCT
|
# define PACK_STRUCT
|
||||||
#elif defined( __GNUC__ )
|
#elif defined( __GNUC__ )
|
||||||
# define PACK_STRUCT __attribute__((packed))
|
# define PACK_STRUCT __attribute__((gcc_struct, __packed__))
|
||||||
#else
|
#else
|
||||||
# error Compiler not supported
|
# error Compiler not supported
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -168,7 +168,9 @@ public:
|
||||||
* @return the exported data or NULL in case of error.
|
* @return the exported data or NULL in case of error.
|
||||||
* @note If the Exporter instance did already hold a blob from
|
* @note If the Exporter instance did already hold a blob from
|
||||||
* a previous call to #ExportToBlob, it will be disposed.
|
* a previous call to #ExportToBlob, it will be disposed.
|
||||||
* Any IO handlers set via #SetIOHandler are ignored here.*/
|
* Any IO handlers set via #SetIOHandler are ignored here.
|
||||||
|
* @note Use aiCopyScene() to get a modifiable copy of a previously
|
||||||
|
* imported scene. */
|
||||||
const aiExportDataBlob* ExportToBlob( const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing = 0u );
|
const aiExportDataBlob* ExportToBlob( const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing = 0u );
|
||||||
inline const aiExportDataBlob* ExportToBlob( const aiScene* pScene, const std::string& pFormatId, unsigned int pPreprocessing = 0u );
|
inline const aiExportDataBlob* ExportToBlob( const aiScene* pScene, const std::string& pFormatId, unsigned int pPreprocessing = 0u );
|
||||||
|
|
||||||
|
@ -196,8 +198,16 @@ public:
|
||||||
* redundant as exporters would apply them anyhow. A good example
|
* redundant as exporters would apply them anyhow. A good example
|
||||||
* is triangulation - whilst you can enforce it by specifying
|
* is triangulation - whilst you can enforce it by specifying
|
||||||
* the #aiProcess_Triangulate flag, most export formats support only
|
* the #aiProcess_Triangulate flag, most export formats support only
|
||||||
* triangulate data so they would run the step even if it wasn't requested.
|
* triangulate data so they would run the step even if it wasn't requested.
|
||||||
* @return AI_SUCCESS if everything was fine. */
|
*
|
||||||
|
* If assimp detects that the input scene was directly taken from the importer side of
|
||||||
|
* the library (i.e. not copied using aiCopyScene and potetially modified afterwards),
|
||||||
|
* any postprocessing steps already applied to the scene will not be applied again, unless
|
||||||
|
* they show non-idempotent behaviour (#aiProcess_MakeLeftHanded, #aiProcess_FlipUVs and
|
||||||
|
* #aiProcess_FlipWindingOrder).
|
||||||
|
* @return AI_SUCCESS if everything was fine.
|
||||||
|
* @note Use aiCopyScene() to get a modifiable copy of a previously
|
||||||
|
* imported scene.*/
|
||||||
aiReturn Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing = 0u);
|
aiReturn Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing = 0u);
|
||||||
inline aiReturn Export( const aiScene* pScene, const std::string& pFormatId, const std::string& pPath, unsigned int pPreprocessing = 0u);
|
inline aiReturn Export( const aiScene* pScene, const std::string& pFormatId, const std::string& pPath, unsigned int pPreprocessing = 0u);
|
||||||
|
|
||||||
|
|
|
@ -95,16 +95,22 @@ ASSIMP_API const C_STRUCT aiExportFormatDesc* aiGetExportFormatDescription( size
|
||||||
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------
|
||||||
/** Create a modifyable copy of a scene.
|
/** Create a modifiable copy of a scene.
|
||||||
* This is useful to import files via Assimp, change their topology and
|
* This is useful to import files via Assimp, change their topology and
|
||||||
* export them again. Since the scene returned by the various importer functions
|
* export them again. Since the scene returned by the various importer functions
|
||||||
* is const, a modifyable copy is needed.
|
* is const, a modifiable copy is needed.
|
||||||
* @param pIn Valid scene to be copied
|
* @param pIn Valid scene to be copied
|
||||||
* @param pOut Receives a modifyable copy of the scene.
|
* @param pOut Receives a modifyable copy of the scene. Use aiFreeScene() to
|
||||||
|
* delete it again.
|
||||||
*/
|
*/
|
||||||
ASSIMP_API void aiCopyScene(const C_STRUCT aiScene* pIn,
|
ASSIMP_API void aiCopyScene(const C_STRUCT aiScene* pIn,
|
||||||
C_STRUCT aiScene** pOut);
|
C_STRUCT aiScene** pOut);
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Frees a scene copy created using aiCopyScene() */
|
||||||
|
ASSIMP_API void aiFreeScene(const C_STRUCT aiScene* pIn);
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------
|
||||||
/** Exports the given scene to a chosen file format and writes the result file(s) to disk.
|
/** Exports the given scene to a chosen file format and writes the result file(s) to disk.
|
||||||
* @param pScene The scene to export. Stays in possession of the caller, is not changed by the function.
|
* @param pScene The scene to export. Stays in possession of the caller, is not changed by the function.
|
||||||
|
@ -137,7 +143,15 @@ ASSIMP_API void aiCopyScene(const C_STRUCT aiScene* pIn,
|
||||||
* is triangulation - whilst you can enforce it by specifying
|
* is triangulation - whilst you can enforce it by specifying
|
||||||
* the #aiProcess_Triangulate flag, most export formats support only
|
* the #aiProcess_Triangulate flag, most export formats support only
|
||||||
* triangulate data so they would run the step anyway.
|
* triangulate data so they would run the step anyway.
|
||||||
|
*
|
||||||
|
* If assimp detects that the input scene was directly taken from the importer side of
|
||||||
|
* the library (i.e. not copied using aiCopyScene and potetially modified afterwards),
|
||||||
|
* any postprocessing steps already applied to the scene will not be applied again, unless
|
||||||
|
* they show non-idempotent behaviour (#aiProcess_MakeLeftHanded, #aiProcess_FlipUVs and
|
||||||
|
* #aiProcess_FlipWindingOrder).
|
||||||
* @return a status code indicating the result of the export
|
* @return a status code indicating the result of the export
|
||||||
|
* @note Use aiCopyScene() to get a modifiable copy of a previously
|
||||||
|
* imported scene.
|
||||||
*/
|
*/
|
||||||
ASSIMP_API aiReturn aiExportScene( const C_STRUCT aiScene* pScene,
|
ASSIMP_API aiReturn aiExportScene( const C_STRUCT aiScene* pScene,
|
||||||
const char* pFormatId,
|
const char* pFormatId,
|
||||||
|
@ -157,6 +171,8 @@ ASSIMP_API aiReturn aiExportScene( const C_STRUCT aiScene* pScene,
|
||||||
* @param pPreprocessing Please see the documentation for #aiExportScene
|
* @param pPreprocessing Please see the documentation for #aiExportScene
|
||||||
* @return a status code indicating the result of the export
|
* @return a status code indicating the result of the export
|
||||||
* @note Include <aiFileIO.h> for the definition of #aiFileIO.
|
* @note Include <aiFileIO.h> for the definition of #aiFileIO.
|
||||||
|
* @note Use aiCopyScene() to get a modifiable copy of a previously
|
||||||
|
* imported scene.
|
||||||
*/
|
*/
|
||||||
ASSIMP_API aiReturn aiExportSceneEx( const C_STRUCT aiScene* pScene,
|
ASSIMP_API aiReturn aiExportSceneEx( const C_STRUCT aiScene* pScene,
|
||||||
const char* pFormatId,
|
const char* pFormatId,
|
||||||
|
|
|
@ -841,4 +841,6 @@ enum aiComponent
|
||||||
*/
|
*/
|
||||||
#define AI_CONFIG_IMPORT_IFC_CUSTOM_TRIANGULATION "IMPORT_IFC_CUSTOM_TRIANGULATION"
|
#define AI_CONFIG_IMPORT_IFC_CUSTOM_TRIANGULATION "IMPORT_IFC_CUSTOM_TRIANGULATION"
|
||||||
|
|
||||||
#endif // !! AI_CONFIG_H_INC
|
#define AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION "IMPORT_COLLADA_IGNORE_UP_DIRECTION"
|
||||||
|
|
||||||
|
#endif // !! AI_CONFIG_H_INC
|
||||||
|
|
|
@ -162,6 +162,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
# define AI_FORCE_INLINE inline
|
# define AI_FORCE_INLINE inline
|
||||||
#endif // (defined _MSC_VER)
|
#endif // (defined _MSC_VER)
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
# define AI_WONT_RETURN_SUFFIX __attribute__((analyzer_noreturn))
|
||||||
|
#else
|
||||||
|
# define AI_WONT_RETURN_SUFFIX
|
||||||
|
#endif // (defined __clang__)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
/* No explicit 'struct' and 'enum' tags for C++, this keeps showing up
|
/* No explicit 'struct' and 'enum' tags for C++, this keeps showing up
|
||||||
* in doxydocs.
|
* in doxydocs.
|
||||||
|
|
|
@ -691,6 +691,12 @@ public:
|
||||||
aiReturn Get(const char* pKey,unsigned int type,
|
aiReturn Get(const char* pKey,unsigned int type,
|
||||||
unsigned int idx, Type* pOut, unsigned int* pMax) const;
|
unsigned int idx, Type* pOut, unsigned int* pMax) const;
|
||||||
|
|
||||||
|
aiReturn Get(const char* pKey,unsigned int type,
|
||||||
|
unsigned int idx, int* pOut, unsigned int* pMax) const;
|
||||||
|
|
||||||
|
aiReturn Get(const char* pKey,unsigned int type,
|
||||||
|
unsigned int idx, float* pOut, unsigned int* pMax) const;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** @brief Retrieve a Type value with a specific key
|
/** @brief Retrieve a Type value with a specific key
|
||||||
* from the material
|
* from the material
|
||||||
|
@ -705,6 +711,25 @@ public:
|
||||||
aiReturn Get(const char* pKey,unsigned int type,
|
aiReturn Get(const char* pKey,unsigned int type,
|
||||||
unsigned int idx,Type& pOut) const;
|
unsigned int idx,Type& pOut) const;
|
||||||
|
|
||||||
|
|
||||||
|
aiReturn Get(const char* pKey,unsigned int type,
|
||||||
|
unsigned int idx, int& pOut) const;
|
||||||
|
|
||||||
|
aiReturn Get(const char* pKey,unsigned int type,
|
||||||
|
unsigned int idx, float& pOut) const;
|
||||||
|
|
||||||
|
aiReturn Get(const char* pKey,unsigned int type,
|
||||||
|
unsigned int idx, aiString& pOut) const;
|
||||||
|
|
||||||
|
aiReturn Get(const char* pKey,unsigned int type,
|
||||||
|
unsigned int idx, aiColor3D& pOut) const;
|
||||||
|
|
||||||
|
aiReturn Get(const char* pKey,unsigned int type,
|
||||||
|
unsigned int idx, aiColor4D& pOut) const;
|
||||||
|
|
||||||
|
aiReturn Get(const char* pKey,unsigned int type,
|
||||||
|
unsigned int idx, aiUVTransform& pOut) const;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Get the number of textures for a particular texture type.
|
/** Get the number of textures for a particular texture type.
|
||||||
* @param type Texture type to check for
|
* @param type Texture type to check for
|
||||||
|
@ -797,6 +822,42 @@ public:
|
||||||
unsigned int type = 0,
|
unsigned int type = 0,
|
||||||
unsigned int index = 0);
|
unsigned int index = 0);
|
||||||
|
|
||||||
|
aiReturn AddProperty (const aiVector3D* pInput,
|
||||||
|
unsigned int pNumValues,
|
||||||
|
const char* pKey,
|
||||||
|
unsigned int type = 0,
|
||||||
|
unsigned int index = 0);
|
||||||
|
|
||||||
|
aiReturn AddProperty (const aiColor3D* pInput,
|
||||||
|
unsigned int pNumValues,
|
||||||
|
const char* pKey,
|
||||||
|
unsigned int type = 0,
|
||||||
|
unsigned int index = 0);
|
||||||
|
|
||||||
|
aiReturn AddProperty (const aiColor4D* pInput,
|
||||||
|
unsigned int pNumValues,
|
||||||
|
const char* pKey,
|
||||||
|
unsigned int type = 0,
|
||||||
|
unsigned int index = 0);
|
||||||
|
|
||||||
|
aiReturn AddProperty (const int* pInput,
|
||||||
|
unsigned int pNumValues,
|
||||||
|
const char* pKey,
|
||||||
|
unsigned int type = 0,
|
||||||
|
unsigned int index = 0);
|
||||||
|
|
||||||
|
aiReturn AddProperty (const float* pInput,
|
||||||
|
unsigned int pNumValues,
|
||||||
|
const char* pKey,
|
||||||
|
unsigned int type = 0,
|
||||||
|
unsigned int index = 0);
|
||||||
|
|
||||||
|
aiReturn AddProperty (const aiUVTransform* pInput,
|
||||||
|
unsigned int pNumValues,
|
||||||
|
const char* pKey,
|
||||||
|
unsigned int type = 0,
|
||||||
|
unsigned int index = 0);
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
/** @brief Remove a given key from the list.
|
/** @brief Remove a given key from the list.
|
||||||
*
|
*
|
||||||
|
|
|
@ -89,7 +89,7 @@ inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
|
||||||
}
|
}
|
||||||
|
|
||||||
iNum = std::min((size_t)iNum,prop->mDataLength / sizeof(Type));
|
iNum = std::min((size_t)iNum,prop->mDataLength / sizeof(Type));
|
||||||
memcpy(pOut,prop->mData,iNum * sizeof(Type));
|
::memcpy(pOut,prop->mData,iNum * sizeof(Type));
|
||||||
if (pMax) {
|
if (pMax) {
|
||||||
*pMax = iNum;
|
*pMax = iNum;
|
||||||
}
|
}
|
||||||
|
@ -115,51 +115,45 @@ inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
|
||||||
return AI_FAILURE;
|
return AI_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&pOut,prop->mData,sizeof(Type));
|
::memcpy(&pOut,prop->mData,sizeof(Type));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
template <>
|
inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
|
||||||
inline aiReturn aiMaterial::Get<float>(const char* pKey,unsigned int type,
|
|
||||||
unsigned int idx,float* pOut,
|
unsigned int idx,float* pOut,
|
||||||
unsigned int* pMax) const
|
unsigned int* pMax) const
|
||||||
{
|
{
|
||||||
return ::aiGetMaterialFloatArray(this,pKey,type,idx,pOut,pMax);
|
return ::aiGetMaterialFloatArray(this,pKey,type,idx,pOut,pMax);
|
||||||
}
|
}
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
template <>
|
inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
|
||||||
inline aiReturn aiMaterial::Get<int>(const char* pKey,unsigned int type,
|
|
||||||
unsigned int idx,int* pOut,
|
unsigned int idx,int* pOut,
|
||||||
unsigned int* pMax) const
|
unsigned int* pMax) const
|
||||||
{
|
{
|
||||||
return ::aiGetMaterialIntegerArray(this,pKey,type,idx,pOut,pMax);
|
return ::aiGetMaterialIntegerArray(this,pKey,type,idx,pOut,pMax);
|
||||||
}
|
}
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
template <>
|
inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
|
||||||
inline aiReturn aiMaterial::Get<float>(const char* pKey,unsigned int type,
|
|
||||||
unsigned int idx,float& pOut) const
|
unsigned int idx,float& pOut) const
|
||||||
{
|
{
|
||||||
return aiGetMaterialFloat(this,pKey,type,idx,&pOut);
|
return aiGetMaterialFloat(this,pKey,type,idx,&pOut);
|
||||||
}
|
}
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
template <>
|
inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
|
||||||
inline aiReturn aiMaterial::Get<int>(const char* pKey,unsigned int type,
|
|
||||||
unsigned int idx,int& pOut) const
|
unsigned int idx,int& pOut) const
|
||||||
{
|
{
|
||||||
return aiGetMaterialInteger(this,pKey,type,idx,&pOut);
|
return aiGetMaterialInteger(this,pKey,type,idx,&pOut);
|
||||||
}
|
}
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
template <>
|
inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
|
||||||
inline aiReturn aiMaterial::Get<aiColor4D>(const char* pKey,unsigned int type,
|
|
||||||
unsigned int idx,aiColor4D& pOut) const
|
unsigned int idx,aiColor4D& pOut) const
|
||||||
{
|
{
|
||||||
return aiGetMaterialColor(this,pKey,type,idx,&pOut);
|
return aiGetMaterialColor(this,pKey,type,idx,&pOut);
|
||||||
}
|
}
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
template <>
|
inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
|
||||||
inline aiReturn aiMaterial::Get<aiColor3D>(const char* pKey,unsigned int type,
|
|
||||||
unsigned int idx,aiColor3D& pOut) const
|
unsigned int idx,aiColor3D& pOut) const
|
||||||
{
|
{
|
||||||
aiColor4D c;
|
aiColor4D c;
|
||||||
|
@ -168,8 +162,7 @@ inline aiReturn aiMaterial::Get<aiColor3D>(const char* pKey,unsigned int type,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
template <>
|
inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
|
||||||
inline aiReturn aiMaterial::Get<aiString>(const char* pKey,unsigned int type,
|
|
||||||
unsigned int idx,aiString& pOut) const
|
unsigned int idx,aiString& pOut) const
|
||||||
{
|
{
|
||||||
return aiGetMaterialString(this,pKey,type,idx,&pOut);
|
return aiGetMaterialString(this,pKey,type,idx,&pOut);
|
||||||
|
@ -189,9 +182,88 @@ aiReturn aiMaterial::AddProperty (const TYPE* pInput,
|
||||||
pKey,type,index,aiPTI_Buffer);
|
pKey,type,index,aiPTI_Buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
inline aiReturn aiMaterial::AddProperty(const float* pInput,
|
||||||
|
const unsigned int pNumValues,
|
||||||
|
const char* pKey,
|
||||||
|
unsigned int type,
|
||||||
|
unsigned int index)
|
||||||
|
{
|
||||||
|
return AddBinaryProperty((const void*)pInput,
|
||||||
|
pNumValues * sizeof(float),
|
||||||
|
pKey,type,index,aiPTI_Float);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
inline aiReturn aiMaterial::AddProperty(const aiUVTransform* pInput,
|
||||||
|
const unsigned int pNumValues,
|
||||||
|
const char* pKey,
|
||||||
|
unsigned int type,
|
||||||
|
unsigned int index)
|
||||||
|
{
|
||||||
|
return AddBinaryProperty((const void*)pInput,
|
||||||
|
pNumValues * sizeof(aiUVTransform),
|
||||||
|
pKey,type,index,aiPTI_Float);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
inline aiReturn aiMaterial::AddProperty(const aiColor4D* pInput,
|
||||||
|
const unsigned int pNumValues,
|
||||||
|
const char* pKey,
|
||||||
|
unsigned int type,
|
||||||
|
unsigned int index)
|
||||||
|
{
|
||||||
|
return AddBinaryProperty((const void*)pInput,
|
||||||
|
pNumValues * sizeof(aiColor4D),
|
||||||
|
pKey,type,index,aiPTI_Float);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
inline aiReturn aiMaterial::AddProperty(const aiColor3D* pInput,
|
||||||
|
const unsigned int pNumValues,
|
||||||
|
const char* pKey,
|
||||||
|
unsigned int type,
|
||||||
|
unsigned int index)
|
||||||
|
{
|
||||||
|
return AddBinaryProperty((const void*)pInput,
|
||||||
|
pNumValues * sizeof(aiColor3D),
|
||||||
|
pKey,type,index,aiPTI_Float);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
inline aiReturn aiMaterial::AddProperty(const aiVector3D* pInput,
|
||||||
|
const unsigned int pNumValues,
|
||||||
|
const char* pKey,
|
||||||
|
unsigned int type,
|
||||||
|
unsigned int index)
|
||||||
|
{
|
||||||
|
return AddBinaryProperty((const void*)pInput,
|
||||||
|
pNumValues * sizeof(aiVector3D),
|
||||||
|
pKey,type,index,aiPTI_Float);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
inline aiReturn aiMaterial::AddProperty(const int* pInput,
|
||||||
|
const unsigned int pNumValues,
|
||||||
|
const char* pKey,
|
||||||
|
unsigned int type,
|
||||||
|
unsigned int index)
|
||||||
|
{
|
||||||
|
return AddBinaryProperty((const void*)pInput,
|
||||||
|
pNumValues * sizeof(int),
|
||||||
|
pKey,type,index,aiPTI_Integer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// The template specializations below are for backwards compatibility.
|
||||||
|
// The recommended way to add material properties is using the non-template
|
||||||
|
// overloads.
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
template<>
|
template<>
|
||||||
inline aiReturn aiMaterial::AddProperty<float> (const float* pInput,
|
inline aiReturn aiMaterial::AddProperty<float>(const float* pInput,
|
||||||
const unsigned int pNumValues,
|
const unsigned int pNumValues,
|
||||||
const char* pKey,
|
const char* pKey,
|
||||||
unsigned int type,
|
unsigned int type,
|
||||||
|
@ -204,7 +276,7 @@ inline aiReturn aiMaterial::AddProperty<float> (const float* pInput,
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
template<>
|
template<>
|
||||||
inline aiReturn aiMaterial::AddProperty<aiUVTransform> (const aiUVTransform* pInput,
|
inline aiReturn aiMaterial::AddProperty<aiUVTransform>(const aiUVTransform* pInput,
|
||||||
const unsigned int pNumValues,
|
const unsigned int pNumValues,
|
||||||
const char* pKey,
|
const char* pKey,
|
||||||
unsigned int type,
|
unsigned int type,
|
||||||
|
@ -217,7 +289,7 @@ inline aiReturn aiMaterial::AddProperty<aiUVTransform> (const aiUVTransform* pIn
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
template<>
|
template<>
|
||||||
inline aiReturn aiMaterial::AddProperty<aiColor4D> (const aiColor4D* pInput,
|
inline aiReturn aiMaterial::AddProperty<aiColor4D>(const aiColor4D* pInput,
|
||||||
const unsigned int pNumValues,
|
const unsigned int pNumValues,
|
||||||
const char* pKey,
|
const char* pKey,
|
||||||
unsigned int type,
|
unsigned int type,
|
||||||
|
@ -230,7 +302,7 @@ inline aiReturn aiMaterial::AddProperty<aiColor4D> (const aiColor4D* pInput,
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
template<>
|
template<>
|
||||||
inline aiReturn aiMaterial::AddProperty<aiColor3D> (const aiColor3D* pInput,
|
inline aiReturn aiMaterial::AddProperty<aiColor3D>(const aiColor3D* pInput,
|
||||||
const unsigned int pNumValues,
|
const unsigned int pNumValues,
|
||||||
const char* pKey,
|
const char* pKey,
|
||||||
unsigned int type,
|
unsigned int type,
|
||||||
|
@ -243,7 +315,7 @@ inline aiReturn aiMaterial::AddProperty<aiColor3D> (const aiColor3D* pInput,
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
template<>
|
template<>
|
||||||
inline aiReturn aiMaterial::AddProperty<aiVector3D> (const aiVector3D* pInput,
|
inline aiReturn aiMaterial::AddProperty<aiVector3D>(const aiVector3D* pInput,
|
||||||
const unsigned int pNumValues,
|
const unsigned int pNumValues,
|
||||||
const char* pKey,
|
const char* pKey,
|
||||||
unsigned int type,
|
unsigned int type,
|
||||||
|
@ -256,7 +328,7 @@ inline aiReturn aiMaterial::AddProperty<aiVector3D> (const aiVector3D* pInput,
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
template<>
|
template<>
|
||||||
inline aiReturn aiMaterial::AddProperty<int> (const int* pInput,
|
inline aiReturn aiMaterial::AddProperty<int>(const int* pInput,
|
||||||
const unsigned int pNumValues,
|
const unsigned int pNumValues,
|
||||||
const char* pKey,
|
const char* pKey,
|
||||||
unsigned int type,
|
unsigned int type,
|
||||||
|
|
|
@ -50,6 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
// Our compile configuration
|
// Our compile configuration
|
||||||
|
|
|
@ -57,18 +57,33 @@ def make_tuple(ai_obj, type = None):
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
# It is faster and more correct to have an init function for each assimp class
|
||||||
|
def _init_face(aiFace):
|
||||||
|
aiFace.indices = [aiFace.mIndices[i] for i in range(aiFace.mNumIndices)]
|
||||||
|
|
||||||
|
assimp_struct_inits = \
|
||||||
|
{ structs.Face : _init_face }
|
||||||
|
|
||||||
def call_init(obj, caller = None):
|
def call_init(obj, caller = None):
|
||||||
# init children
|
if helper.hasattr_silent(obj,'contents'): #pointer
|
||||||
if helper.hasattr_silent(obj, '_init'):
|
_init(obj.contents, obj, caller)
|
||||||
obj._init(parent = caller)
|
else:
|
||||||
|
_init(obj,parent=caller)
|
||||||
# pointers
|
|
||||||
elif helper.hasattr_silent(obj, 'contents'):
|
|
||||||
if helper.hasattr_silent(obj.contents, '_init'):
|
|
||||||
obj.contents._init(target = obj, parent = caller)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def _is_init_type(obj):
|
||||||
|
if helper.hasattr_silent(obj,'contents'): #pointer
|
||||||
|
return _is_init_type(obj[0])
|
||||||
|
# null-pointer case that arises when we reach a mesh attribute
|
||||||
|
# like mBitangents which use mNumVertices rather than mNumBitangents
|
||||||
|
# so it breaks the 'is iterable' check.
|
||||||
|
# Basically:
|
||||||
|
# FIXME!
|
||||||
|
elif not bool(obj):
|
||||||
|
return False
|
||||||
|
tname = obj.__class__.__name__
|
||||||
|
return not (tname[:2] == 'c_' or tname == 'Structure' \
|
||||||
|
or tname == 'POINTER') and not isinstance(obj,int)
|
||||||
|
|
||||||
def _init(self, target = None, parent = None):
|
def _init(self, target = None, parent = None):
|
||||||
"""
|
"""
|
||||||
Custom initialize() for C structs, adds safely accessable member functionality.
|
Custom initialize() for C structs, adds safely accessable member functionality.
|
||||||
|
@ -76,29 +91,35 @@ def _init(self, target = None, parent = None):
|
||||||
:param target: set the object which receive the added methods. Useful when manipulating
|
:param target: set the object which receive the added methods. Useful when manipulating
|
||||||
pointers, to skip the intermediate 'contents' deferencing.
|
pointers, to skip the intermediate 'contents' deferencing.
|
||||||
"""
|
"""
|
||||||
if helper.hasattr_silent(self, '_is_init'):
|
|
||||||
return self
|
|
||||||
self._is_init = True
|
|
||||||
|
|
||||||
if not target:
|
if not target:
|
||||||
target = self
|
target = self
|
||||||
|
|
||||||
for m in dir(self):
|
dirself = dir(self)
|
||||||
|
for m in dirself:
|
||||||
name = m[1:].lower()
|
|
||||||
|
|
||||||
if m.startswith("_"):
|
if m.startswith("_"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
obj = getattr(self, m)
|
|
||||||
|
|
||||||
if m.startswith('mNum'):
|
if m.startswith('mNum'):
|
||||||
if 'm' + m[4:] in dir(self):
|
if 'm' + m[4:] in dirself:
|
||||||
continue # will be processed later on
|
continue # will be processed later on
|
||||||
else:
|
else:
|
||||||
|
name = m[1:].lower()
|
||||||
|
|
||||||
|
obj = getattr(self, m)
|
||||||
setattr(target, name, obj)
|
setattr(target, name, obj)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if m == 'mName':
|
||||||
|
obj = self.mName
|
||||||
|
target.name = str(obj.data.decode("utf-8"))
|
||||||
|
target.__class__.__repr__ = lambda x: str(x.__class__) + "(" + x.name + ")"
|
||||||
|
target.__class__.__str__ = lambda x: x.name
|
||||||
|
continue
|
||||||
|
|
||||||
|
name = m[1:].lower()
|
||||||
|
|
||||||
|
obj = getattr(self, m)
|
||||||
|
|
||||||
# Create tuples
|
# Create tuples
|
||||||
if isinstance(obj, assimp_structs_as_tuple):
|
if isinstance(obj, assimp_structs_as_tuple):
|
||||||
|
@ -106,14 +127,6 @@ def _init(self, target = None, parent = None):
|
||||||
logger.debug(str(self) + ": Added array " + str(getattr(target, name)) + " as self." + name.lower())
|
logger.debug(str(self) + ": Added array " + str(getattr(target, name)) + " as self." + name.lower())
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
||||||
if isinstance(obj, structs.String):
|
|
||||||
setattr(target, 'name', obj.data.decode("utf-8"))
|
|
||||||
setattr(target.__class__, '__repr__', lambda x: str(x.__class__) + "(" + x.name + ")")
|
|
||||||
setattr(target.__class__, '__str__', lambda x: x.name)
|
|
||||||
continue
|
|
||||||
|
|
||||||
|
|
||||||
if m.startswith('m'):
|
if m.startswith('m'):
|
||||||
|
|
||||||
if name == "parent":
|
if name == "parent":
|
||||||
|
@ -150,8 +163,15 @@ def _init(self, target = None, parent = None):
|
||||||
logger.debug(str(self) + ": Added list of " + str(obj) + " " + name + " as self." + name + " (type: " + str(type(obj)) + ")")
|
logger.debug(str(self) + ": Added list of " + str(obj) + " " + name + " as self." + name + " (type: " + str(type(obj)) + ")")
|
||||||
|
|
||||||
# initialize array elements
|
# initialize array elements
|
||||||
for e in getattr(target, name):
|
try:
|
||||||
call_init(e, caller = target)
|
init = assimp_struct_inits[type(obj[0])]
|
||||||
|
except KeyError:
|
||||||
|
if _is_init_type(obj[0]):
|
||||||
|
for e in getattr(target, name):
|
||||||
|
call_init(e, target)
|
||||||
|
else:
|
||||||
|
for e in getattr(target, name):
|
||||||
|
init(e)
|
||||||
|
|
||||||
|
|
||||||
except IndexError:
|
except IndexError:
|
||||||
|
@ -174,8 +194,9 @@ def _init(self, target = None, parent = None):
|
||||||
|
|
||||||
setattr(target, name, obj)
|
setattr(target, name, obj)
|
||||||
logger.debug("Added " + name + " as self." + name + " (type: " + str(type(obj)) + ")")
|
logger.debug("Added " + name + " as self." + name + " (type: " + str(type(obj)) + ")")
|
||||||
|
|
||||||
call_init(obj, caller = target)
|
if _is_init_type(obj):
|
||||||
|
call_init(obj, target)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -189,16 +210,6 @@ def _init(self, target = None, parent = None):
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
Python magic to add the _init() function to all C struct classes.
|
|
||||||
"""
|
|
||||||
for struct in dir(structs):
|
|
||||||
if not (struct.startswith('_') or struct.startswith('c_') or struct == "Structure" or struct == "POINTER") and not isinstance(getattr(structs, struct),int):
|
|
||||||
|
|
||||||
setattr(getattr(structs, struct), '_init', _init)
|
|
||||||
|
|
||||||
|
|
||||||
class AssimpLib(object):
|
class AssimpLib(object):
|
||||||
"""
|
"""
|
||||||
Assimp-Singleton
|
Assimp-Singleton
|
||||||
|
@ -281,7 +292,7 @@ def load(filename, processing=0):
|
||||||
#Uhhh, something went wrong!
|
#Uhhh, something went wrong!
|
||||||
raise AssimpError("could not import file: %s" % filename)
|
raise AssimpError("could not import file: %s" % filename)
|
||||||
|
|
||||||
scene = model.contents._init()
|
scene = _init(model.contents)
|
||||||
|
|
||||||
recur_pythonize(scene.rootnode, scene)
|
recur_pythonize(scene.rootnode, scene)
|
||||||
|
|
||||||
|
@ -313,7 +324,7 @@ def _finalize_mesh(mesh, target):
|
||||||
data = numpy.array([make_tuple(getattr(mesh, name)[i]) for i in range(nb_vertices)], dtype=numpy.float32)
|
data = numpy.array([make_tuple(getattr(mesh, name)[i]) for i in range(nb_vertices)], dtype=numpy.float32)
|
||||||
setattr(target, name[1:].lower(), data)
|
setattr(target, name[1:].lower(), data)
|
||||||
else:
|
else:
|
||||||
setattr(target, name[1:].lower(), [])
|
setattr(target, name[1:].lower(), numpy.array([], dtype="float32"))
|
||||||
|
|
||||||
def fillarray(name):
|
def fillarray(name):
|
||||||
mAttr = getattr(mesh, name)
|
mAttr = getattr(mesh, name)
|
||||||
|
@ -336,6 +347,27 @@ def _finalize_mesh(mesh, target):
|
||||||
faces = numpy.array([f.indices for f in target.faces], dtype=numpy.int32)
|
faces = numpy.array([f.indices for f in target.faces], dtype=numpy.int32)
|
||||||
setattr(target, 'faces', faces)
|
setattr(target, 'faces', faces)
|
||||||
|
|
||||||
|
|
||||||
|
class PropertyGetter(dict):
|
||||||
|
def __getitem__(self, key):
|
||||||
|
semantic = 0
|
||||||
|
if isinstance(key, tuple):
|
||||||
|
key, semantic = key
|
||||||
|
|
||||||
|
return dict.__getitem__(self, (key, semantic))
|
||||||
|
|
||||||
|
def keys(self):
|
||||||
|
for k in dict.keys(self):
|
||||||
|
yield k[0]
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return self.keys()
|
||||||
|
|
||||||
|
def items(self):
|
||||||
|
for k, v in dict.items(self):
|
||||||
|
yield k[0], v
|
||||||
|
|
||||||
|
|
||||||
def _get_properties(properties, length):
|
def _get_properties(properties, length):
|
||||||
"""
|
"""
|
||||||
Convenience Function to get the material properties as a dict
|
Convenience Function to get the material properties as a dict
|
||||||
|
@ -346,7 +378,7 @@ def _get_properties(properties, length):
|
||||||
for p in [properties[i] for i in range(length)]:
|
for p in [properties[i] for i in range(length)]:
|
||||||
#the name
|
#the name
|
||||||
p = p.contents
|
p = p.contents
|
||||||
key = str(p.mKey.data.decode("utf-8")).split('.')[1]
|
key = (str(p.mKey.data.decode("utf-8")).split('.')[1], p.mSemantic)
|
||||||
|
|
||||||
#the data
|
#the data
|
||||||
from ctypes import POINTER, cast, c_int, c_float, sizeof
|
from ctypes import POINTER, cast, c_int, c_float, sizeof
|
||||||
|
@ -366,7 +398,7 @@ def _get_properties(properties, length):
|
||||||
|
|
||||||
result[key] = value
|
result[key] = value
|
||||||
|
|
||||||
return result
|
return PropertyGetter(result)
|
||||||
|
|
||||||
def decompose_matrix(matrix):
|
def decompose_matrix(matrix):
|
||||||
if not isinstance(matrix, structs.Matrix4x4):
|
if not isinstance(matrix, structs.Matrix4x4):
|
||||||
|
|
|
@ -30,7 +30,11 @@ if os.name=='posix':
|
||||||
|
|
||||||
elif os.name=='nt':
|
elif os.name=='nt':
|
||||||
ext_whitelist.append('.dll')
|
ext_whitelist.append('.dll')
|
||||||
|
path_dirs = os.environ['PATH'].split(';')
|
||||||
|
for dir_candidate in path_dirs:
|
||||||
|
if 'assimp' in dir_candidate.lower():
|
||||||
|
additional_dirs.append(dir_candidate)
|
||||||
|
|
||||||
#print(additional_dirs)
|
#print(additional_dirs)
|
||||||
def vec2tuple(x):
|
def vec2tuple(x):
|
||||||
""" Converts a VECTOR3D to a Tuple """
|
""" Converts a VECTOR3D to a Tuple """
|
||||||
|
|
|
@ -10,6 +10,7 @@ import logging
|
||||||
logging.basicConfig(level=logging.INFO)
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
import pyassimp
|
import pyassimp
|
||||||
|
import pyassimp.postprocess
|
||||||
|
|
||||||
def recur_node(node,level = 0):
|
def recur_node(node,level = 0):
|
||||||
print(" " + "\t" * level + "- " + str(node))
|
print(" " + "\t" * level + "- " + str(node))
|
||||||
|
@ -19,7 +20,7 @@ def recur_node(node,level = 0):
|
||||||
|
|
||||||
def main(filename=None):
|
def main(filename=None):
|
||||||
|
|
||||||
scene = pyassimp.load(filename)
|
scene = pyassimp.load(filename, pyassimp.postprocess.aiProcess_Triangulate)
|
||||||
|
|
||||||
#the model we load
|
#the model we load
|
||||||
print("MODEL:" + filename)
|
print("MODEL:" + filename)
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import <OpenGL/OpenGL.h>
|
#import <OpenGL/OpenGL.h>
|
||||||
#import "aiColor4D.h"
|
#import "color4.h"
|
||||||
#import "aiVector3D.h"
|
#import "vector3.h"
|
||||||
#import "aiVector2D.h"
|
#import "vector2.h"
|
||||||
#import "aiMatrix4x4.h"
|
#import "matrix4x4.h"
|
||||||
|
|
||||||
/* workflow:
|
/* workflow:
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue