diff --git a/sys/CMakeLists.txt b/sys/CMakeLists.txt index d0ea511..29a7215 100644 --- a/sys/CMakeLists.txt +++ b/sys/CMakeLists.txt @@ -14,6 +14,10 @@ if (EURESYS_FOUND) add_subdirectory (euresys) endif (EURESYS_FOUND) +#if (GENICAM_FOUND) + add_subdirectory (genicam) +#endif (GENICAM_FOUND) + if (IDSUEYE_FOUND) add_subdirectory (idsueye) endif (IDSUEYE_FOUND) diff --git a/sys/genicam/CMakeLists.txt b/sys/genicam/CMakeLists.txt new file mode 100644 index 0000000..5c7a683 --- /dev/null +++ b/sys/genicam/CMakeLists.txt @@ -0,0 +1,33 @@ +set (SOURCES + gstgenicamsrc.c + ioapi.c + unzip.c) + +set (HEADERS + gstgenicamsrc.h) + +include_directories (AFTER + ${GSTREAMER_INCLUDE_DIR}/.. + ${GENICAM_INCLUDE_DIR} + C:/devel/aravis/src) + +set (libname libgstgenicam) + +add_library (${libname} MODULE + ${SOURCES} + ${HEADERS}) + +target_link_libraries (${libname} + ${GLIB2_LIBRARIES} + ${GOBJECT_LIBRARIES} + ${GSTREAMER_LIBRARY} + ${GSTREAMER_BASE_LIBRARY} + ${GSTREAMER_VIDEO_LIBRARY} + ${GENICAM_LIBRARIES} + ${GSTREAMER_INCLUDE_DIR}/../../lib/z.lib + C:/devel/aravis/vs2012x64/src/Debug/libaravis.lib) + +set (pdbfile "${CMAKE_CURRENT_BINARY_DIR}/\${CMAKE_INSTALL_CONFIG_NAME}/${libname}.pdb") +install (FILES ${pdbfile} DESTINATION lib/gstreamer-1.0) +install(TARGETS ${libname} + LIBRARY DESTINATION lib/gstreamer-1.0) diff --git a/sys/genicam/GenTL_v1_5.h b/sys/genicam/GenTL_v1_5.h new file mode 100644 index 0000000..41cfc40 --- /dev/null +++ b/sys/genicam/GenTL_v1_5.h @@ -0,0 +1,791 @@ +/**************************************************************************** +(c) 2004-2015 by GenICam GenTL Subcommittee + +License: This file is published under the license of the EMVA GenICam Standard Group. +A text file describing the legal terms is included in your installation as 'license.txt'. +If for some reason you are missing this file please contact the EMVA or visit the website +(http://www.genicam.org) for a full copy. + +THIS SOFTWARE IS PROVIDED BY THE EMVA GENICAM STANDARD GROUP "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 EMVA GENICAM STANDARD GROUP +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 GenTL.h + * \brief GenICam Transport Layer Client Interface + * \version 1.5 + * \author GenTL Subcommittee + * \date 2015 + * + * \par Version history + * \li Version 0.1.0 First official version from the meeting in Pilsen + * \li Version 0.1.1 rst (SI) 0.4.160 + * - added _E_INTERFACE_INFO_CMD_LIST_T_ enum name + * - added _E_DEVICE_ACCCESS_STATUS_TYPE_T_ to be used + * with the /a IFGetDeviceInfo and DevGetInfo + * - rename of the enum value DEVICE_INFO_ACCESSMODE to + * DEVICE_INFO_ACCESS_STATUS which now refers to + * _E_DEVICE_ACCCESS_STATUS_TYPE_T_ + * - added Timeout parameter to update interface list and + * device list. + * \li Version 0.1.2 - change datatype of timeout parameter of + * TLUpdateInterfaceList and IFUpdateDeviceList to + * uint64_t to match with the timeout in the event object. + * - changed all enums to have a typedef to uint32_t + * with them to allow custom ids + * - changed type of string constants to be char * instead + * of gcstring + * \li Version 0.1.3 rst (SI), cbi (IDS) 0.4.163 + * - adjusted parameter names to be closer aligned with + * the standard text + * - changed typedefs for enums from uint32_t to int32_t + * - removed default parameter + * - added parameter name to DevGetPort function + * \li Version 0.1.4 jb (LV) + * - fixes to align the file with standard text + * - make the file self-contained, independent on GenApi + * \li Version 0.1.5 rst (SI) cbi (IDS) jb (LV) tho (MVTec) + * - Adjust it for Linux + * - Cosmetics + * \li Version 1.0 rst (SI) cbi (IDS) jb (LV) tho (MVTec) + * - Adjust for Standard 1.0 + * - Make it plain C compliant + * - Cosmetics + * \li Version 1.2 rst (SI) jb (LV) tho (MVTec) + * - Adjust for Standard 1.2 + * - adjust packing + * - Cosmetics + * \li Version 1.3 (Stemmer, Leutron, Matrix Vision, MVTec, MathWorks) + * - Adjust for Standard 1.3 + * - added chunk handling + * - added Mac OS X + * - Cosmetics + * \li Version 1.3.1 (MathWorks) + * - Spelling corrections in comments + * \li Version 1.4 GenTL Subcommittee + * \li Version 1.5 GenTL Subcommittee + * - Changed namespace to GenTL + * - Changes for GenTL 1.5, Please refer to the GenTL spec + * for a list of changes. + */ + + +#ifndef GC_TLI_CLIENT_H_ +#define GC_TLI_CLIENT_H_ 1 + +#ifndef GC_USER_DEFINED_TYPES +/* The types should be the same as defined in GCTypes.h from GenApi. But in + * case you do not have this header the necessary types are defined here. */ +# if defined(_WIN32) +# if defined(_MSC_VER) && _MSC_VER >= 1600 /* VS2010 provides stdint.h */ +# include +# elif !defined _STDINT_H && !defined _STDINT + /* stdint.h is usually not available under Windows */ + typedef unsigned char uint8_t; + typedef __int32 int32_t; + typedef unsigned __int32 uint32_t; + typedef unsigned __int64 uint64_t; +# endif +# else +# include +# endif + +# ifdef __cplusplus + typedef bool bool8_t; +# else + typedef uint8_t bool8_t; +# endif +#endif /* GC_DEFINE_TYPES */ + +#include + + +/* Function declaration modifiers */ +#if defined (_WIN32) +# ifndef GCTLI_NO_DECLSPEC_STATEMENTS +# ifdef GCTLIDLL +# define GC_IMPORT_EXPORT __declspec(dllexport) +# else +# define GC_IMPORT_EXPORT __declspec(dllimport) +# endif +# else +# define GC_IMPORT_EXPORT +# endif /* # ifndef GCTLI_NO_DECLSPEC_STATEMENTS */ +# if defined (_M_IX86) || defined (__i386__) +# define GC_CALLTYPE __stdcall +# else +# define GC_CALLTYPE /* default */ +# endif +# ifndef EXTERN_C +# define EXTERN_C extern "C" +# endif + +#elif defined (__GNUC__) && (__GNUC__ >= 4) && (defined (__linux__) || defined (__APPLE__)) +# define GC_IMPORT_EXPORT __attribute__((visibility("default"))) +# if defined (__i386__) +# define GC_CALLTYPE __attribute__((stdcall)) +# else +# define GC_CALLTYPE /* default */ +# endif +# ifndef EXTERN_C +# define EXTERN_C extern "C" +# endif + +#else +# error Unknown platform, file needs adaption +#endif + +#ifdef __cplusplus +extern "C" { + namespace GenTL { +#endif + + /* Errors */ + enum GC_ERROR_LIST + { + GC_ERR_SUCCESS = 0, + GC_ERR_ERROR = -1001, + GC_ERR_NOT_INITIALIZED = -1002, + GC_ERR_NOT_IMPLEMENTED = -1003, + GC_ERR_RESOURCE_IN_USE = -1004, + GC_ERR_ACCESS_DENIED = -1005, + GC_ERR_INVALID_HANDLE = -1006, + GC_ERR_INVALID_ID = -1007, + GC_ERR_NO_DATA = -1008, + GC_ERR_INVALID_PARAMETER = -1009, + GC_ERR_IO = -1010, + GC_ERR_TIMEOUT = -1011, + GC_ERR_ABORT = -1012, /* GenTL v1.1 */ + GC_ERR_INVALID_BUFFER = -1013, /* GenTL v1.1 */ + GC_ERR_NOT_AVAILABLE = -1014, /* GenTL v1.2 */ + GC_ERR_INVALID_ADDRESS = -1015, /* GenTL v1.3 */ + GC_ERR_BUFFER_TOO_SMALL = -1016, /* GenTL v1.4 */ + GC_ERR_INVALID_INDEX = -1017, /* GenTL v1.4 */ + GC_ERR_PARSING_CHUNK_DATA = -1018, /* GenTL v1.4 */ + GC_ERR_INVALID_VALUE = -1019, /* GenTL v1.4 */ + GC_ERR_RESOURCE_EXHAUSTED = -1020, /* GenTL v1.4 */ + GC_ERR_OUT_OF_MEMORY = -1021, /* GenTL v1.4 */ + GC_ERR_BUSY = -1022, /* GenTL v1.5 */ + + GC_ERR_CUSTOM_ID = -10000 + }; + typedef int32_t GC_ERROR; + +# ifndef GC_GENTL_HEADER_VERSION + +# define GenTLMajorVersion 1 /* defines the major version of the GenICam GenTL standard version this header is based on */ +# define GenTLMinorVersion 5 /* defines the minor version of the GenICam GenTL standard version this header is based on */ +# define GenTLSubMinorVersion 0 /* defines the sub minor version of the GenICam GenTL standard version this header is based on */ + +# define GC_GENTL_HEADER_VERSION_CODE(major,minor,subminor) (((major)<<24)+((minor)<<16)+(subminor)) +# define GC_GENTL_HEADER_VERSION GC_GENTL_HEADER_VERSION_CODE(GenTLMajorVersion,GenTLMinorVersion,GenTLSubMinorVersion) + +# endif /* GC_GENTL_HEADER_VERSION */ + +# ifndef GC_GENTL_DONT_USE_TYPE_DEFINITIONS +# define TLTypeMixedName "Mixed" /* Type to use for several supported technologies */ +# define TLTypeCustomName "Custom" /* Type to use for custom technologies */ +# define TLTypeGEVName "GEV" /* Type to use for GigE Vision technology */ +# define TLTypeCLName "CL" /* Type to use for Camera Link technology */ +# define TLTypeIIDCName "IIDC" /* Type to use for IIDC 1394 technology */ +# define TLTypeUVCName "UVC" /* Type to use for USB video class devices */ +# define TLTypeCXPName "CXP" /* Type to use for CoaXPress, V1.3 */ +# define TLTypeCLHSName "CLHS" /* Type to use for Camera Link HS, V1.3 */ +# define TLTypeU3VName "U3V" /* Type to use for USB3 Vision Standard, V1.4 */ +# define TLTypeETHERNETName "Ethernet" /* Type to use for Ethernet devices, V1.3 */ +# define TLTypePCIName "PCI" /* Type to use for PCI/PCIe devices, V1.3 */ +# endif /* GC_GENTL_DONT_USE_TYPE_DEFINITIONS */ + +# ifndef GC_GENTL_DONT_USE_MODULE_NAMES +# define TLSystemModuleName "TLSystem" /* Name to identify a system module */ +# define TLInterfaceModuleName "TLInterface" /* Name to identify a interface module */ +# define TLDeviceModuleName "TLDevice" /* Name to identify a device module */ +# define TLDataStreamModuleName "TLDataStream" /* Name to identify a data stream module */ +# define TLBufferModuleName "TLBuffer" /* Name to identify a buffer module */ +# define TLRemoteDeviceModuleName "Device" /* Name to identify a remote device module */ +# endif /* GC_GENTL_DONT_USE_MODULE_NAMES */ + + /* Handles */ + typedef void * TL_HANDLE; /* Transport Layer handle, obtained through the TLOpen */ + typedef void * IF_HANDLE; /* Interface handle, obtained through ::TLOpenInterface */ + typedef void * DEV_HANDLE; /* Device Handle, obtained through the ::IFOpenDevice */ + typedef void * DS_HANDLE; /* Handle to an image stream object, obtained through DevOpenDataStream */ + typedef void * PORT_HANDLE; /* A Port handle is used to access the register space of a port */ + /* a PORT_HANDLE can be one of the following TL_HANDLE, IF_HANDLE, */ + /* DEV_HANDLE, handle to a device port, obtained through ::DevGetPort, */ + /* DS_HANDLE, BUFFER_HANDLE */ + + typedef void * BUFFER_HANDLE; /* BufferHandle, obtained through the ::DSAnnounceBuffer function */ + typedef void * EVENTSRC_HANDLE; /* A Event source handle is used to register a OS Event and to retrieve a GenTL event handle */ + /* a EVENTSRC_HANDLE can be on of the following TL_HANDLE, */ + /* IF_HANDLE, DEV_HANDLE, A handle to a device port, obtained through ::DevGetPort */ + /* DS_HANDLE, BUFFER_HANDLE */ + typedef void * EVENT_HANDLE; /* Event Handle */ + +# define GENTL_INVALID_HANDLE NULL /* Invalid handle value, V1.4 */ +# define GENTL_INFINITE 0xFFFFFFFFFFFFFFFFULL /* Infinite value to be used in various function calls, V1.4 */ + + /* Defines the data type possible for the various Info functions. */ + enum INFO_DATATYPE_LIST + { + INFO_DATATYPE_UNKNOWN = 0, /* Unknown data type */ + INFO_DATATYPE_STRING = 1, /* NULL-terminated C string (ASCII encoded). */ + INFO_DATATYPE_STRINGLIST = 2, /* Concatenated INFO_DATATYPE_STRING list. End of list is signaled with an additional NULL. */ + INFO_DATATYPE_INT16 = 3, /* Signed 16 bit integer. */ + INFO_DATATYPE_UINT16 = 4, /* Unsigned 16 bit integer */ + INFO_DATATYPE_INT32 = 5, /* Signed 32 bit integer */ + INFO_DATATYPE_UINT32 = 6, /* Unsigned 32 bit integer */ + INFO_DATATYPE_INT64 = 7, /* Signed 64 bit integer */ + INFO_DATATYPE_UINT64 = 8, /* Unsigned 64 bit integer */ + INFO_DATATYPE_FLOAT64 = 9, /* Signed 64 bit floating point number. */ + INFO_DATATYPE_PTR = 10, /* Pointer type (void*). Size is platform dependent (32 bit on 32 bit platforms). */ + INFO_DATATYPE_BOOL8 = 11, /* Boolean value occupying 8 bit. 0 for false and anything for true. */ + INFO_DATATYPE_SIZET = 12, /* Platform dependent unsigned integer (32 bit on 32 bit platforms). */ + INFO_DATATYPE_BUFFER = 13, /* Like a INFO_DATATYPE_STRING but with arbitrary data and no NULL termination. */ + INFO_DATATYPE_PTRDIFF = 14, /* Platform dependent signed integer (32 bit on 32 bit platforms). GenTL v1.3 */ + + INFO_DATATYPE_CUSTOM_ID = 1000 /* Starting value for custom IDs. */ + }; + typedef int32_t INFO_DATATYPE; + + /* Defines char encoding schemes used by the producer, GenTL v1.4 */ + enum TL_CHAR_ENCODING_LIST + { + TL_CHAR_ENCODING_ASCII = 0, + TL_CHAR_ENCODING_UTF8 = 1 + }; + typedef int32_t TL_CHAR_ENCODING; /* GenTL v1.4 */ + + /* System module information commands for the GenICam::TL::Client::TLGetInfo and GenICam::TL::Client::GCGetInfo functions. */ + enum TL_INFO_CMD_LIST + { + TL_INFO_ID = 0, /* STRING Transport layer ID. */ + TL_INFO_VENDOR = 1, /* STRING Transport layer vendor name. */ + TL_INFO_MODEL = 2, /* STRING Transport layer model name. */ + TL_INFO_VERSION = 3, /* STRING Transport layer version. */ + TL_INFO_TLTYPE = 4, /* STRING Transport layer technology that is supported. */ + TL_INFO_NAME = 5, /* STRING File name including extension of the library. */ + TL_INFO_PATHNAME = 6, /* STRING Full path including file name and extension of the library. */ + TL_INFO_DISPLAYNAME = 7, /* STRING User readable name of the device. If this is not defined in the device this should be VENDOR MODEL (ID). */ + TL_INFO_CHAR_ENCODING = 8, /* INT32 Reporting the char encoding used by this Producer, GenTL v1.4 */ + TL_INFO_GENTL_VER_MAJOR = 9, /* UINT32 Major number of the GenTL spec this producer complies with, GenTL v1.5 */ + TL_INFO_GENTL_VER_MINOR = 10, /* UINT32 Minor number of the GenTL spec this producer complies with, GenTL v1.5 */ + TL_INFO_CUSTOM_ID = 1000 /* Starting value for custom IDs. */ + }; + typedef int32_t TL_INFO_CMD; + + /* This enumeration defines commands to retrieve information with the GenICam::TL::Client::IFGetInfo function from the Interface module. */ + enum INTERFACE_INFO_CMD_LIST + { + INTERFACE_INFO_ID = 0, /* STRING Unique ID of the interface. */ + INTERFACE_INFO_DISPLAYNAME = 1, /* STRING User readable name of the interface. */ + INTERFACE_INFO_TLTYPE = 2, /* STRING Transport layer technology that is supported. */ + + INTERFACE_INFO_CUSTOM_ID = 1000 /* Starting value for GenTL Producer custom IDs. */ + }; + typedef int32_t INTERFACE_INFO_CMD; + + /* This enumeration defines flags of how a device is to be opened with the GenICam::TL::Client::IFOpenDevice function. */ + enum DEVICE_ACCESS_FLAGS_LIST + { + DEVICE_ACCESS_UNKNOWN = 0, /* Not used in a command. Can be used to initialize a variable to query that information. */ + DEVICE_ACCESS_NONE = 1, /* This either means that the device is not open because it was not opened before or the access to it was denied. */ + DEVICE_ACCESS_READONLY = 2, /* Open the device read only. All Port functions can only read from the device. */ + DEVICE_ACCESS_CONTROL = 3, /* Open the device in a way that other hosts/processes can have read only access to the device. Device access level is read/write for this process. */ + DEVICE_ACCESS_EXCLUSIVE = 4, /* Open the device in a way that only this host/process can have access to the device. Device access level is read/write for this process. */ + + DEVICE_ACCESS_CUSTOM_ID = 1000 /* Starting value for GenTL Producer custom IDs. */ + }; + typedef int32_t DEVICE_ACCESS_FLAGS; + + /* This enumeration defines values for the accessibility of the device to be returned in the GenICam::TL::Client::DevGetInfo function on a device handle. */ + enum DEVICE_ACCESS_STATUS_LIST + { + DEVICE_ACCESS_STATUS_UNKNOWN = 0, /* The device accessibility is not known. */ + DEVICE_ACCESS_STATUS_READWRITE = 1, /* The device is available for read/write access. */ + DEVICE_ACCESS_STATUS_READONLY = 2, /* The device is available for read only access. */ + DEVICE_ACCESS_STATUS_NOACCESS = 3, /* The device is not accessible. */ + DEVICE_ACCESS_STATUS_BUSY = 4, /* The device has already been opened by another process/host. GenTL v1.5 */ + DEVICE_ACCESS_STATUS_OPEN_READWRITE = 5, /* The device has already been opened by this process. GenTL v1.5 */ + DEVICE_ACCESS_STATUS_OPEN_READONLY = 6, /* The device has already been opened by this process. GenTL v1.5 */ + + DEVICE_ACCESS_STATUS_CUSTOM_ID = 1000 /* Starting value for custom IDs. */ + }; + typedef int32_t DEVICE_ACCESS_STATUS; + + /* This enumeration defines commands to retrieve information with the GenICam::TL::Client::DevGetInfo function on a device handle. */ + enum DEVICE_INFO_CMD_LIST + { + DEVICE_INFO_ID = 0, /* STRING Unique ID of the device. */ + DEVICE_INFO_VENDOR = 1, /* STRING Device vendor name. */ + DEVICE_INFO_MODEL = 2, /* STRING Device model name. */ + DEVICE_INFO_TLTYPE = 3, /* STRING Transport layer technology that is supported. */ + DEVICE_INFO_DISPLAYNAME = 4, /* STRING String containing a display name for the device ( including a unique id ) */ + DEVICE_INFO_ACCESS_STATUS = 5, /* INT32 Gets the access mode the GenTL Producer has on the opened device. (DEVICE_ACCESS_STATUS enumeration value). */ + DEVICE_INFO_USER_DEFINED_NAME = 6, /* STRING String containing the user defined name, GenTL v1.4 */ + DEVICE_INFO_SERIAL_NUMBER = 7, /* STRING String containing the device's serial number, GenTL v1.4 */ + DEVICE_INFO_VERSION = 8, /* STRING String containing the device version, GenTL v1.4 */ + DEVICE_INFO_TIMESTAMP_FREQUENCY = 9, /* UINT64 Tick-frequency of the time stamp clock, GenTL v1.4 */ + + DEVICE_INFO_CUSTOM_ID = 1000 /* Starting value for GenTL Producer custom IDs. */ + }; + typedef int32_t DEVICE_INFO_CMD; + + /* This enumeration defines special stop flags for the acquisition engine. The function used is GenICam::TL::Client::DSStopAcquisition. */ + enum ACQ_STOP_FLAGS_LIST + { + ACQ_STOP_FLAGS_DEFAULT = 0, /* Stop the acquisition engine when the currently running tasks like filling a buffer are completed (default behavior). */ + ACQ_STOP_FLAGS_KILL = 1, /* Stop the acquisition engine immediately and leave buffers currently being filled in the Input Buffer Pool. */ + + ACQ_STOP_FLAGS_CUSTOM_ID = 1000 /* Starting value for GenTL Producer custom IDs. */ + }; + typedef int32_t ACQ_STOP_FLAGS; + + /* This enumeration defines special start flags for the acquisition engine. The function used is GenICam::TL::Client::DSStartAcquisition. */ + enum ACQ_START_FLAGS_LIST + { + ACQ_START_FLAGS_DEFAULT = 0, /* Default behavior. */ + + ACQ_START_FLAGS_CUSTOM_ID = 1000 /* Starting value for GenTL Producer custom IDs. */ + }; + typedef int32_t ACQ_START_FLAGS; + + /* This enumeration commands from which to which queue/pool buffers are flushed with the GenICam::TL::Client::DSFlushQueue function. */ + enum ACQ_QUEUE_TYPE_LIST + { + ACQ_QUEUE_INPUT_TO_OUTPUT = 0, /* Flushes the input pool to the output queue and if necessary adds entries in the New Buffer event data queue. */ + ACQ_QUEUE_OUTPUT_DISCARD = 1, /* Discards all buffers in the output queue and if necessary remove the entries from the event data queue. */ + ACQ_QUEUE_ALL_TO_INPUT = 2, /* Puts all buffers in the input pool. Even those in the output queue and discard entries in the event data queue. */ + ACQ_QUEUE_UNQUEUED_TO_INPUT = 3, /* Puts all buffers that are not in the input pool or the output queue in the input pool. */ + ACQ_QUEUE_ALL_DISCARD = 4, /* Discards all buffers in the input pool and output queue. */ + + ACQ_QUEUE_CUSTOM_ID = 1000 /* Starting value for GenTL Producer custom IDs. */ + }; + typedef int32_t ACQ_QUEUE_TYPE; + + /* This enumeration defines commands to retrieve information with the GenICam::TL::Client::DSGetInfo function on a data stream handle */ + enum STREAM_INFO_CMD_LIST + { + STREAM_INFO_ID = 0, /* STRING Unique ID of the data stream. */ + STREAM_INFO_NUM_DELIVERED = 1, /* UINT64 Number of delivered buffers since last acquisition start. */ + STREAM_INFO_NUM_UNDERRUN = 2, /* UINT64 Number of lost buffers due to queue underrun. */ + STREAM_INFO_NUM_ANNOUNCED = 3, /* SIZET Number of announced buffers. */ + STREAM_INFO_NUM_QUEUED = 4, /* SIZET Number of buffers in the input pool. */ + STREAM_INFO_NUM_AWAIT_DELIVERY = 5, /* SIZET Number of buffers in the output queue. */ + STREAM_INFO_NUM_STARTED = 6, /* UINT64 Number of buffers started in the acquisition engine. */ + STREAM_INFO_PAYLOAD_SIZE = 7, /* SIZET Size of the expected data in bytes. */ + STREAM_INFO_IS_GRABBING = 8, /* BOOL8 Flag indicating whether the acquisition engine is started or not. */ + STREAM_INFO_DEFINES_PAYLOADSIZE = 9, /* BOOL8 Flag that indicated that this data stream defines a payload size independent from the remote device. */ + STREAM_INFO_TLTYPE = 10, /* STRING Transport layer technology that is supported. */ + STREAM_INFO_NUM_CHUNKS_MAX = 11, /* SIZET Max number of chunks in a buffer, if known. GenTL v1.3 */ + STREAM_INFO_BUF_ANNOUNCE_MIN = 12, /* SIZET Min number of buffers to announce before acq can start, if known. GenTL v1.3 */ + STREAM_INFO_BUF_ALIGNMENT = 13, /* SIZET Buffer alignment in bytes. GenTL v1.3 */ + + STREAM_INFO_CUSTOM_ID = 1000 /* Starting value for GenTL Producer custom IDs. */ + }; + typedef int32_t STREAM_INFO_CMD; + + /* This enumeration defines commands to retrieve information with the GenICam::TL::Client::DSGetBufferInfo function on a buffer handle. */ + enum BUFFER_INFO_CMD_LIST + { + BUFFER_INFO_BASE = 0, /* PTR Base address of the buffer memory. */ + BUFFER_INFO_SIZE = 1, /* SIZET Size of the buffer in bytes. */ + BUFFER_INFO_USER_PTR = 2, /* PTR Private data pointer of the GenTL Consumer. */ + BUFFER_INFO_TIMESTAMP = 3, /* UINT64 Timestamp the buffer was acquired. */ + BUFFER_INFO_NEW_DATA = 4, /* BOOL8 Flag to indicate that the buffer contains new data since the last call. */ + BUFFER_INFO_IS_QUEUED = 5, /* BOOL8 Flag to indicate if the buffer is in the input pool or output queue. */ + BUFFER_INFO_IS_ACQUIRING = 6, /* BOOL8 Flag to indicate that the buffer is currently being filled with data. */ + BUFFER_INFO_IS_INCOMPLETE = 7, /* BOOL8 Flag to indicate that a buffer was filled but an error occurred during that process. */ + BUFFER_INFO_TLTYPE = 8, /* STRING Transport layer technology that is supported. */ + BUFFER_INFO_SIZE_FILLED = 9, /* SIZET Number of bytes written into the buffer last time it has been filled. This value is reset to 0 when the buffer is placed into the Input Buffer Pool. */ + BUFFER_INFO_WIDTH = 10, /* SIZET GenTL v1.2 */ + BUFFER_INFO_HEIGHT = 11, /* SIZET GenTL v1.2 */ + BUFFER_INFO_XOFFSET = 12, /* SIZET GenTL v1.2 */ + BUFFER_INFO_YOFFSET = 13, /* SIZET GenTL v1.2 */ + BUFFER_INFO_XPADDING = 14, /* SIZET GenTL v1.2 */ + BUFFER_INFO_YPADDING = 15, /* SIZET GenTL v1.2 */ + BUFFER_INFO_FRAMEID = 16, /* UINT64 GenTL v1.2 */ + BUFFER_INFO_IMAGEPRESENT = 17, /* BOOL8 GenTL v1.2 */ + BUFFER_INFO_IMAGEOFFSET = 18, /* SIZET GenTL v1.2 */ + BUFFER_INFO_PAYLOADTYPE = 19, /* SIZET GenTL v1.2 */ + BUFFER_INFO_PIXELFORMAT = 20, /* UINT64 GenTL v1.2 */ + BUFFER_INFO_PIXELFORMAT_NAMESPACE = 21, /* UINT64 GenTL v1.2 */ + BUFFER_INFO_DELIVERED_IMAGEHEIGHT = 22, /* SIZET GenTL v1.2 */ + BUFFER_INFO_DELIVERED_CHUNKPAYLOADSIZE = 23, /* SIZET GenTL v1.2 */ + BUFFER_INFO_CHUNKLAYOUTID = 24, /* UINT64 GenTL v1.2 */ + BUFFER_INFO_FILENAME = 25, /* STRING GenTL v1.2 */ + BUFFER_INFO_PIXEL_ENDIANNESS = 26, /* INT32 GenTL v1.4 */ + BUFFER_INFO_DATA_SIZE = 27, /* SIZET GenTL v1.4 */ + BUFFER_INFO_TIMESTAMP_NS = 28, /* UINT64 GenTL v1.4 */ + BUFFER_INFO_DATA_LARGER_THAN_BUFFER = 29, /* BOOL8 GenTL v1.4 */ + BUFFER_INFO_CONTAINS_CHUNKDATA = 30, /* BOOL8 GenTL v1.4 */ + + BUFFER_INFO_CUSTOM_ID = 1000 /* Starting value for GenTL Producer custom IDs. */ + }; + typedef int32_t BUFFER_INFO_CMD; + + /* This enumeration defines commands to retrieve information about individual data parts in a multi-part buffer + using the GenICam::TL::Client::DSGetBufferPartInfo function. Introduced in GenTL v1.5. */ + enum BUFFER_PART_INFO_CMD_LIST + { + BUFFER_PART_INFO_BASE = 0, /* PTR Base address of the buffer part memory. */ + BUFFER_PART_INFO_DATA_SIZE = 1, /* SIZET Size of the buffer part in bytes. */ + BUFFER_PART_INFO_DATA_TYPE = 2, /* SIZET Type of the data in given part (PARTDATATYPE_ID enumeration value). */ + BUFFER_PART_INFO_DATA_FORMAT = 3, /* UINT64 Format of individual items (such as pixels) in the buffer part. */ + BUFFER_PART_INFO_DATA_FORMAT_NAMESPACE = 4, /* UINT64 Allows interpretation of BUFFER_PART_INFO_DATA_FORMAT (PIXELFORMAT_NAMESPACE_ID enumeration value). */ + BUFFER_PART_INFO_WIDTH = 5, /* SIZET Width of data in the buffer part in pixels. */ + BUFFER_PART_INFO_HEIGHT = 6, /* SIZET Expected height of data in the buffer part in pixels . */ + BUFFER_PART_INFO_XOFFSET = 7, /* SIZET Horizontal offset of data in the buffer part in pixels. */ + BUFFER_PART_INFO_YOFFSET = 8, /* SIZET Vertical offset of data in the buffer part in pixels. */ + BUFFER_PART_INFO_XPADDING = 9, /* SIZET Horizontal padding of data in the buffer part in pixels. */ + BUFFER_PART_INFO_SOURCE_ID = 10, /* UINT64 Identifier allowing to group data parts belonging to the same source. */ + BUFFER_PART_INFO_DELIVERED_IMAGEHEIGHT = 11, /* SIZET Height of the data currently in the buffer part in pixels*/ + BUFFER_PART_INFO_CUSTOM_ID = 1000 /* Starting value for GenTL Producer custom IDs. */ + }; + typedef int32_t BUFFER_PART_INFO_CMD; /* GenTL v1.5 */ + + /* Enumeration of TLType dependent payload types. Introduced in GenTL v1.2 */ + enum PAYLOADTYPE_INFO_IDS + { + PAYLOAD_TYPE_UNKNOWN = 0, /* GenTL v1.2 */ + PAYLOAD_TYPE_IMAGE = 1, /* GenTL v1.2 */ + PAYLOAD_TYPE_RAW_DATA = 2, /* GenTL v1.2 */ + PAYLOAD_TYPE_FILE = 3, /* GenTL v1.2 */ + PAYLOAD_TYPE_CHUNK_DATA = 4, /* GenTL v1.2, Deprecated in GenTL 1.5*/ + PAYLOAD_TYPE_JPEG = 5, /* GenTL v1.4 */ + PAYLOAD_TYPE_JPEG2000 = 6, /* GenTL v1.4 */ + PAYLOAD_TYPE_H264 = 7, /* GenTL v1.4 */ + PAYLOAD_TYPE_CHUNK_ONLY = 8, /* GenTL v1.4 */ + PAYLOAD_TYPE_DEVICE_SPECIFIC = 9, /* GenTL v1.4 */ + PAYLOAD_TYPE_MULTI_PART = 10, /* GenTL v1.5 */ + + PAYLOAD_TYPE_CUSTOM_ID = 1000 /* Starting value for GenTL Producer custom IDs. */ + }; + typedef int32_t PAYLOADTYPE_INFO_ID; + + /* Enumeration of TLType dependent pixel format namespaces introduced GenTL v1.2 */ + enum PIXELFORMAT_NAMESPACE_IDS + { + PIXELFORMAT_NAMESPACE_UNKNOWN = 0, /* GenTL v1.2 */ + PIXELFORMAT_NAMESPACE_GEV = 1, /* GenTL v1.2 */ + PIXELFORMAT_NAMESPACE_IIDC = 2, /* GenTL v1.2 */ + PIXELFORMAT_NAMESPACE_PFNC_16BIT = 3, /* GenTL v1.4 */ + PIXELFORMAT_NAMESPACE_PFNC_32BIT = 4, /* GenTL v1.4 */ + + PIXELFORMAT_NAMESPACE_CUSTOM_ID = 1000 /* Starting value for GenTL Producer custom IDs. */ + }; + typedef int32_t PIXELFORMAT_NAMESPACE_ID; /* GenTL v1.2 */ + + /* Enumeration of pixel endianness values. Introduced in GenTL v1.4 */ + enum PIXELENDIANNESS_IDS + { + PIXELENDIANNESS_UNKNOWN = 0, /* Unknown pixel endianness. GenTL v1.4 */ + PIXELENDIANNESS_LITTLE = 1, /* Little endian pixel data. GenTL v1.4 */ + PIXELENDIANNESS_BIG = 2 /* Big endian pixel data. GenTL v1.4 */ + }; + typedef int32_t PIXELENDIANNESS_ID; /* GenTL v1.4*/ + + /* Enumeration describing which data type is present in given buffer part. Introduced in GenTL v1.5 */ + enum PARTDATATYPE_IDS + { + PART_DATATYPE_UNKNOWN = 0, /* Unknown data type */ + PART_DATATYPE_2D_IMAGE = 1, /* Color or monochrome 2D image. */ + PART_DATATYPE_2D_PLANE_BIPLANAR = 2, /* Single color plane of a planar 2D image consisting of 2 planes. */ + PART_DATATYPE_2D_PLANE_TRIPLANAR = 3, /* Single color plane of a planar 2D image consisting of 3 planes. */ + PART_DATATYPE_2D_PLANE_QUADPLANAR = 4, /* Single color plane of a planar 2D image consisting of 4 planes. */ + PART_DATATYPE_3D_IMAGE = 5, /* 3D image (pixel coordinates). */ + PART_DATATYPE_3D_PLANE_BIPLANAR = 6, /* Single plane of a planar 3D image consisting of 2 planes. */ + PART_DATATYPE_3D_PLANE_TRIPLANAR = 7, /* Single plane of a planar 3D image consisting of 3 planes. */ + PART_DATATYPE_3D_PLANE_QUADPLANAR = 8, /* Single plane of a planar 3D image consisting of 4 planes. */ + PART_DATATYPE_CONFIDENCE_MAP = 9, /* Confidence of the individual pixel values. */ + + PART_DATATYPE_CUSTOM_ID = 1000 /* Starting value for GenTL Producer custom IDs. */ + }; + typedef int32_t PARTDATATYPE_ID; /* GenTL v1.5*/ + + /* This enumeration defines commands to retrieve information with the GenICam::TL::Client::GCGetPortInfo function on a module or remote device handle. */ + enum PORT_INFO_CMD_LIST + { + PORT_INFO_ID = 0, /* STRING Unique ID of the port. */ + PORT_INFO_VENDOR = 1, /* STRING Port vendor name. */ + PORT_INFO_MODEL = 2, /* STRING Port model name. */ + PORT_INFO_TLTYPE = 3, /* STRING Transport layer technology that is supported. */ + PORT_INFO_MODULE = 4, /* STRING GenTL Module the port refers to. */ + PORT_INFO_LITTLE_ENDIAN = 5, /* BOOL8 Flag indicating that the port data is little endian. */ + PORT_INFO_BIG_ENDIAN = 6, /* BOOL8 Flag indicating that the port data is big endian. */ + PORT_INFO_ACCESS_READ = 7, /* BOOL8 Port has read access. */ + PORT_INFO_ACCESS_WRITE = 8, /* BOOL8 Port has write access. */ + PORT_INFO_ACCESS_NA = 9, /* BOOL8 Port is not accessible. */ + PORT_INFO_ACCESS_NI = 10, /* BOOL8 Port is not implemented. */ + PORT_INFO_VERSION = 11, /* STRING Version of the port. */ + PORT_INFO_PORTNAME = 12, /* STRING Name of the port as referenced in the XML description. */ + + PORT_INFO_CUSTOM_ID = 1000 /* Starting value for GenTL Producer custom IDs. */ + }; + typedef int32_t PORT_INFO_CMD; + + /* This enumeration defines enum values returned by the URL_INFO_SCHEME command. + introduced in GenTL v1.5 */ + enum URL_SCHEME_IDS + { + URL_SCHEME_LOCAL = 0, /* The XML can be read from the local register map */ + URL_SCHEME_HTTP = 1, /* The XML can be downloaded from a http server */ + URL_SCHEME_FILE = 2, /* The XML can be read from the local hard drive */ + + URL_SCHEME_CUSTOM_ID = 1000 /* Starting value for custom scheme locations */ + }; + typedef int32_t URL_SCHEME_ID; + + /* This enumeration defines commands to retrieve information with the GenICam::TL::Client::GCGetPortURLInfo + function on a module or remote device handle. Introduced in GenTL v1.1 */ + enum URL_INFO_CMD_LIST + { + URL_INFO_URL = 0, /* STRING URL as defined in chapter 4.1.2 GenTL v1.1 */ + URL_INFO_SCHEMA_VER_MAJOR = 1, /* INT32 Major version of the schema this URL refers to. GenTL v1.1 */ + URL_INFO_SCHEMA_VER_MINOR = 2, /* INT32 Minor version of the schema this URL refers to. GenTL v1.1 */ + URL_INFO_FILE_VER_MAJOR = 3, /* INT32 Major version of the XML-file this URL refers to. GenTL v1.1 */ + URL_INFO_FILE_VER_MINOR = 4, /* INT32 Minor version of the XML-file this URL refers to. GenTL v1.1 */ + URL_INFO_FILE_VER_SUBMINOR = 5, /* INT32 Subminor version of the XML-file this URL refers to. GenTL v1.1 */ + URL_INFO_FILE_SHA1_HASH = 6, /* BUFFER 160-bit SHA1 Hash code of XML-file. GenTL v1.4 */ + URL_INFO_FILE_REGISTER_ADDRESS = 7, /* UINT64 Register address in the device's register map. GenTL v1.5 */ + URL_INFO_FILE_SIZE = 8, /* UINT64 File size in bytes. GenTL v1.5 */ + URL_INFO_SCHEME = 9, /* INT32 Scheme of the URL as defined in URL_SCHEME_IDS. GenTL v1.5 */ + URL_INFO_FILENAME = 10, /* STRING File name if the scheme of the URL is file. GenTL v1.5 */ + + URL_INFO_CUSTOM_ID = 1000 /* Starting value for GenTL Producer custom IDs. */ + }; + typedef int32_t URL_INFO_CMD; /* GenTL v1.1 */ + + /* Known event types that can be registered on certain modules with the GenICam::TL::Client::GCRegisterEvent function. */ + enum EVENT_TYPE_LIST + { + EVENT_ERROR = 0, /* Notification on module errors. */ + EVENT_NEW_BUFFER = 1, /* Notification on newly filled buffers. */ + EVENT_FEATURE_INVALIDATE = 2, /* Notification if a feature was changed by the GenTL Producer library and thus needs to be invalidated in the GenICam GenApi instance using the module. */ + EVENT_FEATURE_CHANGE = 3, /* Notification if the GenTL Producer library wants to manually set a feature in the GenICam GenApi instance using the module. */ + EVENT_REMOTE_DEVICE = 4, /* Notification if the GenTL Producer wants to inform the GenICam GenApi instance of the remote device that a GenApi compatible event was fired. */ + EVENT_MODULE = 5, /* Notification if the GenTL Producer wants to inform the GenICam GenApi instance of the module that a GenApi compatible event was fired. GenTL v1.4 */ + + EVENT_CUSTOM_ID = 1000 /* Starting value for GenTL Producer custom IDs. */ + }; + typedef int32_t EVENT_TYPE; + + /* Event info command */ + enum EVENT_INFO_CMD_LIST + { + EVENT_EVENT_TYPE = 0, /* INT32 The event type of the event handle (EVENT_TYPE enum value). */ + EVENT_NUM_IN_QUEUE = 1, /* SIZET Number of events in the event data queue. */ + EVENT_NUM_FIRED = 2, /* UINT64 Number of events that were fired since the creation of the module. */ + EVENT_SIZE_MAX = 3, /* SIZET Max size of data carried with an event in bytes. GenTL v1.2 */ + EVENT_INFO_DATA_SIZE_MAX = 4, /* SIZET Max size of data provided through EventGetDataInfo in bytes. GenTL v1.2 */ + + EVENT_INFO_CUSTOM_ID = 1000 /* Starting value for GenTL Producer custom IDs. */ + }; + typedef int32_t EVENT_INFO_CMD; + + /* Event data info command */ + enum EVENT_DATA_INFO_CMD_LIST + { + EVENT_DATA_ID = 0, /* Event specific Unique Event ID (String or Number)*/ + EVENT_DATA_VALUE = 1, /* Event specific Data */ + EVENT_DATA_NUMID = 2, /* UINT64 Numeric representation of the unique Event ID, GenTL v1.3. */ + + EVENT_DATA_CUSTOM_ID = 1000 /* Starting value for GenTL Producer custom IDs. */ + }; + typedef int32_t EVENT_DATA_INFO_CMD; + + /* Structure of the data returned from a signaled "New Buffer" event. */ +# pragma pack (push, 1) + typedef struct S_EVENT_NEW_BUFFER + { + BUFFER_HANDLE BufferHandle; /* Buffer handle which contains new data. */ + void* pUserPointer; /* User pointer provided at announcement of the buffer. */ + } EVENT_NEW_BUFFER_DATA; +# pragma pack (pop) + + /* Structure to be use with GCWritePortStacked and GCReadPortStacked. */ +# pragma pack (push, 1) + typedef struct S_PORT_REGISTER_STACK_ENTRY + { + uint64_t Address; /* Address of the register. */ + void* pBuffer; /* Pointer to the buffer containing the data. */ + size_t Size; /* Number of bytes to read write. */ + } PORT_REGISTER_STACK_ENTRY; +# pragma pack (pop) + +# pragma pack (push, 1) + /* Structure carrying information about a single chunk in the buffer, V1.3 */ + typedef struct S_SINGLE_CHUNK_DATA + { + uint64_t ChunkID; /* Numeric representation of ChunkID */ + ptrdiff_t ChunkOffset; /* Chunk offset in the buffer */ + size_t ChunkLength; /* Size of the chunk data */ + } SINGLE_CHUNK_DATA; +# pragma pack (pop) + + + /* C API Interface Functions */ +# define GC_API GC_IMPORT_EXPORT GC_ERROR GC_CALLTYPE + GC_API GCGetInfo ( TL_INFO_CMD iInfoCmd, INFO_DATATYPE *piType, void *pBuffer, size_t *piSize ); + + GC_API GCGetLastError ( GC_ERROR *piErrorCode, char *sErrText, size_t *piSize ); + + GC_API GCInitLib ( void ); + GC_API GCCloseLib ( void ); + + GC_API GCReadPort ( PORT_HANDLE hPort, uint64_t iAddress, void *pBuffer, size_t *piSize ); + GC_API GCWritePort ( PORT_HANDLE hPort, uint64_t iAddress, const void *pBuffer, size_t *piSize ); + GC_API GCGetPortURL ( PORT_HANDLE hPort, char *sURL, size_t *piSize ); + + GC_API GCGetPortInfo ( PORT_HANDLE hPort, PORT_INFO_CMD iInfoCmd, INFO_DATATYPE *piType, void *pBuffer, size_t *piSize ); + + GC_API GCRegisterEvent ( EVENTSRC_HANDLE hEventSrc, EVENT_TYPE iEventID, EVENT_HANDLE *phEvent ); + GC_API GCUnregisterEvent ( EVENTSRC_HANDLE hEventSrc, EVENT_TYPE iEventID ); + + GC_API EventGetData ( EVENT_HANDLE hEvent, void *pBuffer, size_t *piSize, uint64_t iTimeout ); + GC_API EventGetDataInfo ( EVENT_HANDLE hEvent, const void *pInBuffer, size_t iInSize, EVENT_DATA_INFO_CMD iInfoCmd, INFO_DATATYPE *piType, void *pOutBuffer, size_t *piOutSize ); + GC_API EventGetInfo ( EVENT_HANDLE hEvent, EVENT_INFO_CMD iInfoCmd, INFO_DATATYPE *piType, void *pBuffer, size_t *piSize ); + GC_API EventFlush ( EVENT_HANDLE hEvent ); + GC_API EventKill ( EVENT_HANDLE hEvent ); + + GC_API TLOpen ( TL_HANDLE *phTL ); + GC_API TLClose ( TL_HANDLE hTL ); + GC_API TLGetInfo ( TL_HANDLE hTL, TL_INFO_CMD iInfoCmd, INFO_DATATYPE *piType, void *pBuffer, size_t *piSize ); + + GC_API TLGetNumInterfaces ( TL_HANDLE hTL, uint32_t *piNumIfaces ); + GC_API TLGetInterfaceID ( TL_HANDLE hTL, uint32_t iIndex, char *sID, size_t *piSize ); + GC_API TLGetInterfaceInfo ( TL_HANDLE hTL, const char *sIfaceID, INTERFACE_INFO_CMD iInfoCmd, INFO_DATATYPE *piType, void *pBuffer, size_t *piSize ); + GC_API TLOpenInterface ( TL_HANDLE hTL, const char *sIfaceID, IF_HANDLE *phIface ); + GC_API TLUpdateInterfaceList ( TL_HANDLE hTL, bool8_t *pbChanged, uint64_t iTimeout ); + + GC_API IFClose ( IF_HANDLE hIface ); + GC_API IFGetInfo ( IF_HANDLE hIface, INTERFACE_INFO_CMD iInfoCmd, INFO_DATATYPE *piType, void *pBuffer, size_t *piSize ); + + GC_API IFGetNumDevices ( IF_HANDLE hIface, uint32_t *piNumDevices ); + GC_API IFGetDeviceID ( IF_HANDLE hIface, uint32_t iIndex, char *sIDeviceID, size_t *piSize ); + GC_API IFUpdateDeviceList ( IF_HANDLE hIface, bool8_t *pbChanged, uint64_t iTimeout ); + GC_API IFGetDeviceInfo ( IF_HANDLE hIface, const char *sDeviceID, DEVICE_INFO_CMD iInfoCmd, INFO_DATATYPE *piType, void *pBuffer, size_t *piSize ); + GC_API IFOpenDevice ( IF_HANDLE hIface, const char *sDeviceID, DEVICE_ACCESS_FLAGS iOpenFlags, DEV_HANDLE *phDevice ); + + GC_API DevGetPort ( DEV_HANDLE hDevice, PORT_HANDLE *phRemoteDevice ); + GC_API DevGetNumDataStreams ( DEV_HANDLE hDevice, uint32_t *piNumDataStreams ); + GC_API DevGetDataStreamID ( DEV_HANDLE hDevice, uint32_t iIndex, char *sDataStreamID, size_t *piSize ); + GC_API DevOpenDataStream ( DEV_HANDLE hDevice, const char *sDataStreamID, DS_HANDLE *phDataStream ); + GC_API DevGetInfo ( DEV_HANDLE hDevice, DEVICE_INFO_CMD iInfoCmd, INFO_DATATYPE *piType, void *pBuffer, size_t *piSize ); + GC_API DevClose ( DEV_HANDLE hDevice ); + + GC_API DSAnnounceBuffer ( DS_HANDLE hDataStream, void *pBuffer, size_t iSize, void *pPrivate, BUFFER_HANDLE *phBuffer ); + GC_API DSAllocAndAnnounceBuffer( DS_HANDLE hDataStream, size_t iSize, void *pPrivate, BUFFER_HANDLE *phBuffer ); + GC_API DSFlushQueue ( DS_HANDLE hDataStream, ACQ_QUEUE_TYPE iOperation ); + GC_API DSStartAcquisition ( DS_HANDLE hDataStream, ACQ_START_FLAGS iStartFlags, uint64_t iNumToAcquire ); + GC_API DSStopAcquisition ( DS_HANDLE hDataStream, ACQ_STOP_FLAGS iStopFlags ); + GC_API DSGetInfo ( DS_HANDLE hDataStream, STREAM_INFO_CMD iInfoCmd, INFO_DATATYPE *piType, void *pBuffer, size_t *piSize ); + GC_API DSGetBufferID ( DS_HANDLE hDataStream, uint32_t iIndex, BUFFER_HANDLE *phBuffer ); + GC_API DSClose ( DS_HANDLE hDataStream ); + + GC_API DSRevokeBuffer ( DS_HANDLE hDataStream, BUFFER_HANDLE hBuffer, void **pBuffer, void **pPrivate ); + GC_API DSQueueBuffer ( DS_HANDLE hDataStream, BUFFER_HANDLE hBuffer ); + GC_API DSGetBufferInfo ( DS_HANDLE hDataStream, BUFFER_HANDLE hBuffer, BUFFER_INFO_CMD iInfoCmd, INFO_DATATYPE *piType, void *pBuffer, size_t *piSize ); + + /* GenTL v1.1 */ + GC_API GCGetNumPortURLs ( PORT_HANDLE hPort, uint32_t *piNumURLs ); + GC_API GCGetPortURLInfo ( PORT_HANDLE hPort, uint32_t iURLIndex, URL_INFO_CMD iInfoCmd, INFO_DATATYPE *piType, void *pBuffer, size_t *piSize ); + GC_API GCReadPortStacked ( PORT_HANDLE hPort, PORT_REGISTER_STACK_ENTRY *pEntries, size_t *piNumEntries ); + GC_API GCWritePortStacked ( PORT_HANDLE hPort, PORT_REGISTER_STACK_ENTRY *pEntries, size_t *piNumEntries ); + + /* GenTL v1.3 */ + GC_API DSGetBufferChunkData ( DS_HANDLE hDataStream, BUFFER_HANDLE hBuffer, SINGLE_CHUNK_DATA *pChunkData, size_t *piNumChunks ); + + /* GenTL v1.4 */ + GC_API IFGetParentTL ( IF_HANDLE hIface, TL_HANDLE *phSystem ); + GC_API DevGetParentIF ( DEV_HANDLE hDevice, IF_HANDLE *phIface ); + GC_API DSGetParentDev ( DS_HANDLE hDataStream, DEV_HANDLE *phDevice ); + + /* GenTL v1.5 */ + GC_API DSGetNumBufferParts ( DS_HANDLE hDataStream, BUFFER_HANDLE hBuffer, uint32_t *piNumParts ); + GC_API DSGetBufferPartInfo ( DS_HANDLE hDataStream, BUFFER_HANDLE hBuffer, uint32_t iPartIndex, BUFFER_PART_INFO_CMD iInfoCmd, INFO_DATATYPE *piType, void *pBuffer, size_t *piSize ); + + /* typedefs for dynamic loading */ +# define GC_API_P(function) typedef GC_ERROR( GC_CALLTYPE *function ) + GC_API_P(PGCGetInfo )( TL_INFO_CMD iInfoCmd, INFO_DATATYPE *piType, void *pBuffer, size_t *piSize ); + GC_API_P(PGCGetLastError )( GC_ERROR *piErrorCode, char *sErrText, size_t *piSize ); + GC_API_P(PGCInitLib )( void ); + GC_API_P(PGCCloseLib )( void ); + GC_API_P(PGCReadPort )( PORT_HANDLE hPort, uint64_t iAddress, void *pBuffer, size_t *piSize ); + GC_API_P(PGCWritePort )( PORT_HANDLE hPort, uint64_t iAddress, const void *pBuffer, size_t *piSize ); + GC_API_P(PGCGetPortURL )( PORT_HANDLE hPort, char *sURL, size_t *piSize ); + GC_API_P(PGCGetPortInfo )( PORT_HANDLE hPort, PORT_INFO_CMD iInfoCmd, INFO_DATATYPE *piType, void *pBuffer, size_t *piSize ); + + GC_API_P(PGCRegisterEvent )( EVENTSRC_HANDLE hEventSrc, EVENT_TYPE iEventID, EVENT_HANDLE *phEvent ); + GC_API_P(PGCUnregisterEvent )( EVENTSRC_HANDLE hEventSrc, EVENT_TYPE iEventID ); + GC_API_P(PEventGetData )( EVENT_HANDLE hEvent, void *pBuffer, size_t *piSize, uint64_t iTimeout ); + GC_API_P(PEventGetDataInfo )( EVENT_HANDLE hEvent, const void *pInBuffer, size_t iInSize, EVENT_DATA_INFO_CMD iInfoCmd, INFO_DATATYPE *piType, void *pOutBuffer, size_t *piOutSize ); + GC_API_P(PEventGetInfo )( EVENT_HANDLE hEvent, EVENT_INFO_CMD iInfoCmd, INFO_DATATYPE *piType, void *pBuffer, size_t *piSize ); + GC_API_P(PEventFlush )( EVENT_HANDLE hEvent ); + GC_API_P(PEventKill )( EVENT_HANDLE hEvent ); + GC_API_P(PTLOpen )( TL_HANDLE *phTL ); + GC_API_P(PTLClose )( TL_HANDLE hTL ); + GC_API_P(PTLGetInfo )( TL_HANDLE hTL, TL_INFO_CMD iInfoCmd, INFO_DATATYPE *piType, void *pBuffer, size_t *piSize ); + GC_API_P(PTLGetNumInterfaces )( TL_HANDLE hTL, uint32_t *piNumIfaces ); + GC_API_P(PTLGetInterfaceID )( TL_HANDLE hTL, uint32_t iIndex, char *sID, size_t *piSize ); + GC_API_P(PTLGetInterfaceInfo )( TL_HANDLE hTL, const char *sIfaceID, INTERFACE_INFO_CMD iInfoCmd, INFO_DATATYPE *piType, void *pBuffer, size_t *piSize ); + GC_API_P(PTLOpenInterface )( TL_HANDLE hTL, const char *sIfaceID, IF_HANDLE *phIface ); + GC_API_P(PTLUpdateInterfaceList )( TL_HANDLE hTL, bool8_t *pbChanged, uint64_t iTimeout ); + GC_API_P(PIFClose )( IF_HANDLE hIface ); + GC_API_P(PIFGetInfo )( IF_HANDLE hIface, INTERFACE_INFO_CMD iInfoCmd, INFO_DATATYPE *piType, void *pBuffer, size_t *piSize ); + GC_API_P(PIFGetNumDevices )( IF_HANDLE hIface, uint32_t *piNumDevices ); + GC_API_P(PIFGetDeviceID )( IF_HANDLE hIface, uint32_t iIndex, char *sIDeviceID, size_t *piSize ); + GC_API_P(PIFUpdateDeviceList )( IF_HANDLE hIface, bool8_t *pbChanged, uint64_t iTimeout ); + GC_API_P(PIFGetDeviceInfo )( IF_HANDLE hIface, const char *sDeviceID, DEVICE_INFO_CMD iInfoCmd, INFO_DATATYPE *piType, void *pBuffer, size_t *piSize ); + GC_API_P(PIFOpenDevice )( IF_HANDLE hIface, const char *sDeviceID, DEVICE_ACCESS_FLAGS iOpenFlags, DEV_HANDLE *phDevice ); + + GC_API_P(PDevGetPort )( DEV_HANDLE hDevice, PORT_HANDLE *phRemoteDevice ); + GC_API_P(PDevGetNumDataStreams )( DEV_HANDLE hDevice, uint32_t *piNumDataStreams ); + GC_API_P(PDevGetDataStreamID )( DEV_HANDLE hDevice, uint32_t iIndex, char *sDataStreamID, size_t *piSize ); + GC_API_P(PDevOpenDataStream )( DEV_HANDLE hDevice, const char *sDataStreamID, DS_HANDLE *phDataStream ); + GC_API_P(PDevGetInfo )( DEV_HANDLE hDevice, DEVICE_INFO_CMD iInfoCmd, INFO_DATATYPE *piType, void *pBuffer, size_t *piSize ); + GC_API_P(PDevClose )( DEV_HANDLE hDevice ); + + GC_API_P(PDSAnnounceBuffer )( DS_HANDLE hDataStream, void *pBuffer, size_t iSize, void *pPrivate, BUFFER_HANDLE *phBuffer ); + GC_API_P(PDSAllocAndAnnounceBuffer)( DS_HANDLE hDataStream, size_t iSize, void *pPrivate, BUFFER_HANDLE *phBuffer ); + GC_API_P(PDSFlushQueue )( DS_HANDLE hDataStream, ACQ_QUEUE_TYPE iOperation ); + GC_API_P(PDSStartAcquisition )( DS_HANDLE hDataStream, ACQ_START_FLAGS iStartFlags, uint64_t iNumToAcquire ); + GC_API_P(PDSStopAcquisition )( DS_HANDLE hDataStream, ACQ_STOP_FLAGS iStopFlags ); + GC_API_P(PDSGetInfo )( DS_HANDLE hDataStream, STREAM_INFO_CMD iInfoCmd, INFO_DATATYPE *piType, void *pBuffer, size_t *piSize ); + GC_API_P(PDSGetBufferID )( DS_HANDLE hDataStream, uint32_t iIndex, BUFFER_HANDLE *phBuffer ); + GC_API_P(PDSClose )( DS_HANDLE hDataStream ); + GC_API_P(PDSRevokeBuffer )( DS_HANDLE hDataStream, BUFFER_HANDLE hBuffer, void **pBuffer, void **pPrivate ); + GC_API_P(PDSQueueBuffer )( DS_HANDLE hDataStream, BUFFER_HANDLE hBuffer ); + GC_API_P(PDSGetBufferInfo )( DS_HANDLE hDataStream, BUFFER_HANDLE hBuffer, BUFFER_INFO_CMD iInfoCmd, INFO_DATATYPE *piType, void *pBuffer, size_t *piSize ); + + /* GenTL v1.1 */ + GC_API_P(PGCGetNumPortURLs )( PORT_HANDLE hPort, uint32_t *iNumURLs ); + GC_API_P(PGCGetPortURLInfo )( PORT_HANDLE hPort, uint32_t iURLIndex, URL_INFO_CMD iInfoCmd, INFO_DATATYPE *piType, void *pBuffer, size_t *piSize ); + GC_API_P(PGCReadPortStacked )( PORT_HANDLE hPort, PORT_REGISTER_STACK_ENTRY *pEntries, size_t *piNumEntries ); + GC_API_P(PGCWritePortStacked )( PORT_HANDLE hPort, PORT_REGISTER_STACK_ENTRY *pEntries, size_t *piNumEntries ); + + /* GenTL v1.3 */ + GC_API_P(PDSGetBufferChunkData )( DS_HANDLE hDataStream, BUFFER_HANDLE hBuffer, SINGLE_CHUNK_DATA *pChunkData, size_t *piNumChunks ); + + /* GenTL v1.4 */ + GC_API_P(PIFGetParentTL )( IF_HANDLE hIface, TL_HANDLE *phSystem ); + GC_API_P(PDevGetParentIF )( DEV_HANDLE hDevice, IF_HANDLE *phIface ); + GC_API_P(PDSGetParentDev )( DS_HANDLE hDataStream, DEV_HANDLE *phDevice ); + + /* GenTL v1.5 */ + GC_API_P(PDSGetNumBufferParts )( DS_HANDLE hDataStream, BUFFER_HANDLE hBuffer, uint32_t *piNumParts ); + GC_API_P(PDSGetBufferPartInfo )( DS_HANDLE hDataStream, BUFFER_HANDLE hBuffer, uint32_t iPartIndex, BUFFER_PART_INFO_CMD iInfoCmd, INFO_DATATYPE *piType, void *pBuffer, size_t *piSize ); +#ifdef __cplusplus + } /* end of namespace GenTL */ +} /* end of extern "C" */ +#endif +#endif /* GC_TLI_CLIENT_H_ */ diff --git a/sys/genicam/gstgenicamsrc.c b/sys/genicam/gstgenicamsrc.c new file mode 100644 index 0000000..5062754 --- /dev/null +++ b/sys/genicam/gstgenicamsrc.c @@ -0,0 +1,1414 @@ +/* GStreamer + * Copyright (C) 2011 FIXME + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Suite 500, + * Boston, MA 02110-1335, USA. + */ +/** + * SECTION:element-gstgenicamsrc + * + * The genicamsrc element is a source for GenICam framegrabbers. + * + * + * Example launch line + * |[ + * gst-launch -v genicamsrc ! videoconvert ! autovideosink + * ]| + * Shows video from the default GenICam framegrabber + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include +#include + +#include "unzip.h" + +#include "gstgenicamsrc.h" + +#ifdef HAVE_ORC +#include +#else +#define orc_memcpy memcpy +#endif + +GST_DEBUG_CATEGORY_STATIC (gst_genicamsrc_debug); +#define GST_CAT_DEFAULT gst_genicamsrc_debug + +/* prototypes */ +static void gst_genicamsrc_set_property (GObject * object, + guint property_id, const GValue * value, GParamSpec * pspec); +static void gst_genicamsrc_get_property (GObject * object, + guint property_id, GValue * value, GParamSpec * pspec); +static void gst_genicamsrc_dispose (GObject * object); +static void gst_genicamsrc_finalize (GObject * object); + +static gboolean gst_genicamsrc_start (GstBaseSrc * src); +static gboolean gst_genicamsrc_stop (GstBaseSrc * src); +static GstCaps *gst_genicamsrc_get_caps (GstBaseSrc * src, GstCaps * filter); +static gboolean gst_genicamsrc_set_caps (GstBaseSrc * src, GstCaps * caps); +static gboolean gst_genicamsrc_unlock (GstBaseSrc * src); +static gboolean gst_genicamsrc_unlock_stop (GstBaseSrc * src); + +static GstFlowReturn gst_genicamsrc_create (GstPushSrc * src, GstBuffer ** buf); + +static gchar *gst_genicamsrc_get_error_string (GstGenicamSrc * src); + +enum +{ + PROP_0, + PROP_INTERFACE_INDEX, + PROP_INTERFACE_ID, + PROP_DEVICE_INDEX, + PROP_DEVICE_ID, + PROP_STREAM_INDEX, + PROP_STREAM_ID, + PROP_NUM_CAPTURE_BUFFERS, + PROP_TIMEOUT +}; + +#define DEFAULT_PROP_INTERFACE_INDEX 0 +#define DEFAULT_PROP_INTERFACE_ID "" +#define DEFAULT_PROP_DEVICE_INDEX 0 +#define DEFAULT_PROP_DEVICE_ID "" +#define DEFAULT_PROP_STREAM_INDEX 0 +#define DEFAULT_PROP_STREAM_ID "" +#define DEFAULT_PROP_NUM_CAPTURE_BUFFERS 3 +#define DEFAULT_PROP_TIMEOUT 1000 + +/* pad templates */ + +static GstStaticPadTemplate gst_genicamsrc_src_template = +GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE + ("{ GRAY8, GRAY16_LE, GRAY16_BE, BGRA }")) + ); + +#define HANDLE_GTL_ERROR(arg) \ + if (ret != GC_ERR_SUCCESS) { \ + GST_ELEMENT_ERROR (src, LIBRARY, FAILED, \ + (arg ": %s", gst_genicamsrc_get_error_string (src)), (NULL)); \ + goto error; \ + } + +PGCGetInfo GTL_GCGetInfo; +PGCGetLastError GTL_GCGetLastError; +PGCInitLib GTL_GCInitLib; +PGCCloseLib GTL_GCCloseLib; +PGCReadPort GTL_GCReadPort; +PGCWritePort GTL_GCWritePort; +PGCGetPortURL GTL_GCGetPortURL; +PGCGetPortInfo GTL_GCGetPortInfo; +PGCRegisterEvent GTL_GCRegisterEvent; +PGCUnregisterEvent GTL_GCUnregisterEvent; +PEventGetData GTL_EventGetData; +PEventGetDataInfo GTL_EventGetDataInfo; +PEventGetInfo GTL_EventGetInfo; +PEventFlush GTL_EventFlush; +PEventKill GTL_EventKill; +PTLOpen GTL_TLOpen; +PTLClose GTL_TLClose; +PTLGetInfo GTL_TLGetInfo; +PTLGetNumInterfaces GTL_TLGetNumInterfaces; +PTLGetInterfaceID GTL_TLGetInterfaceID; +PTLGetInterfaceInfo GTL_TLGetInterfaceInfo; +PTLOpenInterface GTL_TLOpenInterface; +PTLUpdateInterfaceList GTL_TLUpdateInterfaceList; +PIFClose GTL_IFClose; +PIFGetInfo GTL_IFGetInfo; +PIFGetNumDevices GTL_IFGetNumDevices; +PIFGetDeviceID GTL_IFGetDeviceID; +PIFUpdateDeviceList GTL_IFUpdateDeviceList; +PIFGetDeviceInfo GTL_IFGetDeviceInfo; +PIFOpenDevice GTL_IFOpenDevice; +PDevGetPort GTL_DevGetPort; +PDevGetNumDataStreams GTL_DevGetNumDataStreams; +PDevGetDataStreamID GTL_DevGetDataStreamID; +PDevOpenDataStream GTL_DevOpenDataStream; +PDevGetInfo GTL_DevGetInfo; +PDevClose GTL_DevClose; +PDSAnnounceBuffer GTL_DSAnnounceBuffer; +PDSAllocAndAnnounceBuffer GTL_DSAllocAndAnnounceBuffer; +PDSFlushQueue GTL_DSFlushQueue; +PDSStartAcquisition GTL_DSStartAcquisition; +PDSStopAcquisition GTL_DSStopAcquisition; +PDSGetInfo GTL_DSGetInfo; +PDSGetBufferID GTL_DSGetBufferID; +PDSClose GTL_DSClose; +PDSRevokeBuffer GTL_DSRevokeBuffer; +PDSQueueBuffer GTL_DSQueueBuffer; +PDSGetBufferInfo GTL_DSGetBufferInfo; +PGCGetNumPortURLs GTL_GCGetNumPortURLs; +PGCGetPortURLInfo GTL_GCGetPortURLInfo; + +#define GTL_BIND(fcn) if (!g_module_symbol (module, G_STRINGIFY(fcn), (gpointer *) & GTL_##fcn)) { \ + GST_DEBUG_OBJECT(src, "Failed to bind function " G_STRINGIFY(fcn)); goto error; } + +gboolean +gst_genicamsrc_bind_functions (GstGenicamSrc * src) +{ + GModule *module; + //const char cti_path[] = "C:\\BitFlow SDK 6.20\\Bin64\\BFGTL.cti"; + const char cti_path[] = + "C:\\Program Files\\Basler\\pylon 5\\Runtime\\x64\\ProducerGEV.cti"; + gboolean ret = TRUE; + + GST_DEBUG_OBJECT (src, "Trying to bind functions from '%s'", cti_path); + + module = g_module_open (cti_path, G_MODULE_BIND_LAZY); + if (!module) { + GST_ELEMENT_ERROR (src, LIBRARY, INIT, + ("GenTL CTI %s could not be opened: %s", cti_path, g_module_error ()), + (NULL)); + return FALSE; + } + + GTL_BIND (GCGetInfo); + GTL_BIND (GCGetLastError); + GTL_BIND (GCInitLib); + GTL_BIND (GCCloseLib); + GTL_BIND (GCReadPort); + GTL_BIND (GCWritePort); + GTL_BIND (GCGetPortURL); + GTL_BIND (GCGetPortInfo); + GTL_BIND (GCRegisterEvent); + GTL_BIND (GCUnregisterEvent); + GTL_BIND (EventGetData); + GTL_BIND (EventGetDataInfo); + GTL_BIND (EventGetInfo); + GTL_BIND (EventFlush); + GTL_BIND (EventKill); + GTL_BIND (TLOpen); + GTL_BIND (TLClose); + GTL_BIND (TLGetInfo); + GTL_BIND (TLGetNumInterfaces); + GTL_BIND (TLGetInterfaceID); + GTL_BIND (TLGetInterfaceInfo); + GTL_BIND (TLOpenInterface); + GTL_BIND (TLUpdateInterfaceList); + GTL_BIND (IFClose); + GTL_BIND (IFGetInfo); + GTL_BIND (IFGetNumDevices); + GTL_BIND (IFGetDeviceID); + GTL_BIND (IFUpdateDeviceList); + GTL_BIND (IFGetDeviceInfo); + GTL_BIND (IFOpenDevice); + GTL_BIND (DevGetPort); + GTL_BIND (DevGetNumDataStreams); + GTL_BIND (DevGetDataStreamID); + GTL_BIND (DevOpenDataStream); + GTL_BIND (DevGetInfo); + GTL_BIND (DevClose); + GTL_BIND (DSAnnounceBuffer); + GTL_BIND (DSAllocAndAnnounceBuffer); + GTL_BIND (DSFlushQueue); + GTL_BIND (DSStartAcquisition); + GTL_BIND (DSStopAcquisition); + GTL_BIND (DSGetInfo); + GTL_BIND (DSGetBufferID); + GTL_BIND (DSClose); + GTL_BIND (DSRevokeBuffer); + GTL_BIND (DSQueueBuffer); + GTL_BIND (DSGetBufferInfo); + GTL_BIND (GCGetNumPortURLs); + GTL_BIND (GCGetPortURLInfo); + + return TRUE; + +error: + GST_ERROR_OBJECT (src, "One or more functions doesn't exist in %s", cti_path); + return FALSE; +} + + +/* class initialization */ + +G_DEFINE_TYPE (GstGenicamSrc, gst_genicamsrc, GST_TYPE_PUSH_SRC); + +static void +gst_genicamsrc_class_init (GstGenicamSrcClass * klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); + GstBaseSrcClass *gstbasesrc_class = GST_BASE_SRC_CLASS (klass); + GstPushSrcClass *gstpushsrc_class = GST_PUSH_SRC_CLASS (klass); + + gobject_class->set_property = gst_genicamsrc_set_property; + gobject_class->get_property = gst_genicamsrc_get_property; + gobject_class->dispose = gst_genicamsrc_dispose; + gobject_class->finalize = gst_genicamsrc_finalize; + + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&gst_genicamsrc_src_template)); + + gst_element_class_set_static_metadata (gstelement_class, + "GenICam Video Source", "Source/Video", + "GenICam framegrabber video source", "Joshua M. Doe "); + + gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_genicamsrc_start); + gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_genicamsrc_stop); + gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_genicamsrc_get_caps); + gstbasesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_genicamsrc_set_caps); + gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_genicamsrc_unlock); + gstbasesrc_class->unlock_stop = + GST_DEBUG_FUNCPTR (gst_genicamsrc_unlock_stop); + + gstpushsrc_class->create = GST_DEBUG_FUNCPTR (gst_genicamsrc_create); + + /* Install GObject properties */ + g_object_class_install_property (gobject_class, PROP_INTERFACE_INDEX, + g_param_spec_uint ("interface-index", "Interface index", + "Interface index number, zero-based, overridden by interface-id", + 0, G_MAXUINT, DEFAULT_PROP_INTERFACE_INDEX, + (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | + GST_PARAM_MUTABLE_READY))); + g_object_class_install_property (gobject_class, PROP_INTERFACE_ID, + g_param_spec_string ("interface-id", "Interface ID", + "Interface ID, overrides interface-index if not empty string", + DEFAULT_PROP_INTERFACE_ID, + (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | + GST_PARAM_MUTABLE_READY))); + g_object_class_install_property (gobject_class, PROP_INTERFACE_INDEX, + g_param_spec_uint ("device-index", "Device index", + "Device index number, zero-based, overridden by device-id", + 0, G_MAXUINT, DEFAULT_PROP_DEVICE_INDEX, + (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | + GST_PARAM_MUTABLE_READY))); + g_object_class_install_property (gobject_class, PROP_DEVICE_ID, + g_param_spec_string ("device-id", "Device ID", + "Device ID, overrides device-index if not empty string", + DEFAULT_PROP_DEVICE_ID, + (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | + GST_PARAM_MUTABLE_READY))); + g_object_class_install_property (gobject_class, PROP_STREAM_INDEX, + g_param_spec_uint ("stream-index", "Stream index", + "Stream index number, zero-based, overridden by stream-id", + 0, G_MAXUINT, DEFAULT_PROP_STREAM_INDEX, + (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | + GST_PARAM_MUTABLE_READY))); + g_object_class_install_property (gobject_class, PROP_STREAM_ID, + g_param_spec_string ("stream-id", "Stream ID", + "Stream ID, overrides stream-index if not empty string", + DEFAULT_PROP_STREAM_ID, + (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | + GST_PARAM_MUTABLE_READY))); + g_object_class_install_property (gobject_class, PROP_NUM_CAPTURE_BUFFERS, + g_param_spec_uint ("num-capture-buffers", "Number of capture buffers", + "Number of capture buffers", 1, G_MAXUINT, + DEFAULT_PROP_NUM_CAPTURE_BUFFERS, + (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); + g_object_class_install_property (G_OBJECT_CLASS (klass), + PROP_TIMEOUT, g_param_spec_int ("timeout", + "Timeout (ms)", + "Timeout in ms (0 to use default)", 0, G_MAXINT, + DEFAULT_PROP_TIMEOUT, G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE)); + +} + +static void +gst_genicamsrc_reset (GstGenicamSrc * src) +{ + src->error_string[0] = 0; + src->last_frame_count = 0; + src->total_dropped_frames = 0; + + if (src->caps) { + gst_caps_unref (src->caps); + src->caps = NULL; + } +} + +static void +gst_genicamsrc_init (GstGenicamSrc * src) +{ + /* set source as live (no preroll) */ + gst_base_src_set_live (GST_BASE_SRC (src), TRUE); + + /* override default of BYTES to operate in time mode */ + gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_TIME); + + /* initialize member variables */ + src->interface_index = DEFAULT_PROP_INTERFACE_INDEX; + src->interface_id = g_strdup (DEFAULT_PROP_INTERFACE_ID); + src->num_capture_buffers = DEFAULT_PROP_NUM_CAPTURE_BUFFERS; + src->timeout = DEFAULT_PROP_TIMEOUT; + + src->stop_requested = FALSE; + src->caps = NULL; + + src->hTL = NULL; + src->hIF = NULL; + src->hDEV = NULL; + src->hDS = NULL; + + gst_genicamsrc_reset (src); +} + +void +gst_genicamsrc_set_property (GObject * object, guint property_id, + const GValue * value, GParamSpec * pspec) +{ + GstGenicamSrc *src; + + src = GST_GENICAM_SRC (object); + + switch (property_id) { + case PROP_INTERFACE_INDEX: + src->interface_index = g_value_get_uint (value); + break; + case PROP_INTERFACE_ID: + g_free (src->interface_id); + src->interface_id = g_strdup (g_value_get_string (value)); + break; + case PROP_DEVICE_INDEX: + src->device_index = g_value_get_uint (value); + break; + case PROP_DEVICE_ID: + g_free (src->device_id); + src->device_id = g_strdup (g_value_get_string (value)); + break; + case PROP_STREAM_INDEX: + src->stream_index = g_value_get_uint (value); + break; + case PROP_STREAM_ID: + g_free (src->stream_id); + src->stream_id = g_strdup (g_value_get_string (value)); + break; + case PROP_NUM_CAPTURE_BUFFERS: + src->num_capture_buffers = g_value_get_uint (value); + break; + case PROP_TIMEOUT: + src->timeout = g_value_get_int (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +void +gst_genicamsrc_get_property (GObject * object, guint property_id, + GValue * value, GParamSpec * pspec) +{ + GstGenicamSrc *src; + + g_return_if_fail (GST_IS_GENICAM_SRC (object)); + src = GST_GENICAM_SRC (object); + + switch (property_id) { + case PROP_INTERFACE_INDEX: + g_value_set_uint (value, src->interface_index); + break; + case PROP_INTERFACE_ID: + g_value_set_string (value, src->interface_id); + break; + case PROP_DEVICE_INDEX: + g_value_set_uint (value, src->device_index); + break; + case PROP_DEVICE_ID: + g_value_set_string (value, src->device_id); + break; + case PROP_STREAM_INDEX: + g_value_set_uint (value, src->stream_index); + break; + case PROP_STREAM_ID: + g_value_set_string (value, src->stream_id); + break; + case PROP_NUM_CAPTURE_BUFFERS: + g_value_set_uint (value, src->num_capture_buffers); + break; + case PROP_TIMEOUT: + g_value_set_int (value, src->timeout); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +void +gst_genicamsrc_dispose (GObject * object) +{ + GstGenicamSrc *src; + + g_return_if_fail (GST_IS_GENICAM_SRC (object)); + src = GST_GENICAM_SRC (object); + + /* clean up as possible. may be called multiple times */ + + G_OBJECT_CLASS (gst_genicamsrc_parent_class)->dispose (object); +} + +void +gst_genicamsrc_finalize (GObject * object) +{ + GstGenicamSrc *src; + + g_return_if_fail (GST_IS_GENICAM_SRC (object)); + src = GST_GENICAM_SRC (object); + + /* clean up object here */ + + if (src->caps) { + gst_caps_unref (src->caps); + src->caps = NULL; + } + + G_OBJECT_CLASS (gst_genicamsrc_parent_class)->finalize (object); +} + +#define GTL_MAX_STR_SIZE 256 + +void +gst_genicam_print_gentl_impl_info (GstGenicamSrc * src) +{ + size_t str_size; + char id[GTL_MAX_STR_SIZE]; + char vendor[GTL_MAX_STR_SIZE]; + char model[GTL_MAX_STR_SIZE]; + char version[GTL_MAX_STR_SIZE]; + char tl_type[GTL_MAX_STR_SIZE]; + char name[GTL_MAX_STR_SIZE]; + char path_name[GTL_MAX_STR_SIZE]; + char display_name[GTL_MAX_STR_SIZE]; + INFO_DATATYPE datatype; + + str_size = GTL_MAX_STR_SIZE; + GTL_GCGetInfo (TL_INFO_ID, &datatype, id, &str_size); + str_size = GTL_MAX_STR_SIZE; + GTL_GCGetInfo (TL_INFO_VENDOR, &datatype, vendor, &str_size); + str_size = GTL_MAX_STR_SIZE; + GTL_GCGetInfo (TL_INFO_MODEL, &datatype, model, &str_size); + str_size = GTL_MAX_STR_SIZE; + GTL_GCGetInfo (TL_INFO_VERSION, &datatype, version, &str_size); + str_size = GTL_MAX_STR_SIZE; + GTL_GCGetInfo (TL_INFO_TLTYPE, &datatype, tl_type, &str_size); + str_size = GTL_MAX_STR_SIZE; + GTL_GCGetInfo (TL_INFO_NAME, &datatype, name, &str_size); + str_size = GTL_MAX_STR_SIZE; + GTL_GCGetInfo (TL_INFO_PATHNAME, &datatype, path_name, &str_size); + str_size = GTL_MAX_STR_SIZE; + GTL_GCGetInfo (TL_INFO_DISPLAYNAME, &datatype, display_name, &str_size); + + GST_DEBUG_OBJECT (src, + "ID=%s, Vendor=%s, Model=%s, Version=%s, TL_Type=%s, Name=%s, Path_Name=%s, Display_Name=%s", + id, vendor, model, version, tl_type, name, path_name, display_name); +} + +void +gst_genicam_print_system_info (GstGenicamSrc * src) +{ + size_t str_size; + char id[GTL_MAX_STR_SIZE]; + char vendor[GTL_MAX_STR_SIZE]; + char model[GTL_MAX_STR_SIZE]; + char version[GTL_MAX_STR_SIZE]; + char tl_type[GTL_MAX_STR_SIZE]; + char name[GTL_MAX_STR_SIZE]; + char path_name[GTL_MAX_STR_SIZE]; + char display_name[GTL_MAX_STR_SIZE]; + INFO_DATATYPE datatype; + + str_size = GTL_MAX_STR_SIZE; + GTL_TLGetInfo (src->hTL, TL_INFO_ID, &datatype, id, &str_size); + str_size = GTL_MAX_STR_SIZE; + GTL_TLGetInfo (src->hTL, TL_INFO_VENDOR, &datatype, vendor, &str_size); + str_size = GTL_MAX_STR_SIZE; + GTL_TLGetInfo (src->hTL, TL_INFO_MODEL, &datatype, model, &str_size); + str_size = GTL_MAX_STR_SIZE; + GTL_TLGetInfo (src->hTL, TL_INFO_VERSION, &datatype, version, &str_size); + str_size = GTL_MAX_STR_SIZE; + GTL_TLGetInfo (src->hTL, TL_INFO_TLTYPE, &datatype, tl_type, &str_size); + str_size = GTL_MAX_STR_SIZE; + GTL_TLGetInfo (src->hTL, TL_INFO_NAME, &datatype, name, &str_size); + str_size = GTL_MAX_STR_SIZE; + GTL_TLGetInfo (src->hTL, TL_INFO_PATHNAME, &datatype, path_name, &str_size); + str_size = GTL_MAX_STR_SIZE; + GTL_TLGetInfo (src->hTL, TL_INFO_DISPLAYNAME, &datatype, display_name, + &str_size); + + GST_DEBUG_OBJECT (src, + "System: ID=%s, Vendor=%s, Model=%s, Version=%s, TL_Type=%s, Name=%s, Path_Name=%s, Display_Name=%s", + id, vendor, model, version, tl_type, name, path_name, display_name); +} + +void +gst_genicam_print_interface_info (GstGenicamSrc * src, uint32_t index) +{ + GC_ERROR ret; + size_t str_size; + char iface_id[GTL_MAX_STR_SIZE]; + char id[GTL_MAX_STR_SIZE]; + char tl_type[GTL_MAX_STR_SIZE]; + char display_name[GTL_MAX_STR_SIZE]; + INFO_DATATYPE datatype; + + ret = GTL_TLGetInterfaceID (src->hTL, index, iface_id, &str_size); + if (ret != GC_ERR_SUCCESS) { + GST_WARNING_OBJECT (src, "Failed to get interface id: %s", + gst_genicamsrc_get_error_string (src)); + return; + } + + str_size = GTL_MAX_STR_SIZE; + GTL_TLGetInterfaceInfo (src->hTL, iface_id, INTERFACE_INFO_ID, &datatype, id, + &str_size); + str_size = GTL_MAX_STR_SIZE; + GTL_TLGetInterfaceInfo (src->hTL, iface_id, INTERFACE_INFO_DISPLAYNAME, + &datatype, display_name, &str_size); + str_size = GTL_MAX_STR_SIZE; + GTL_TLGetInterfaceInfo (src->hTL, iface_id, INTERFACE_INFO_TLTYPE, &datatype, + tl_type, &str_size); + + GST_DEBUG_OBJECT (src, "Interface %d: ID=%s, TL_Type=%s, Display_Name=%s", + index, id, tl_type, display_name); +} + +void +gst_genicam_print_device_info (GstGenicamSrc * src, uint32_t index) +{ + GC_ERROR ret; + size_t str_size; + char dev_id[GTL_MAX_STR_SIZE]; + char id[GTL_MAX_STR_SIZE]; + char vendor[GTL_MAX_STR_SIZE]; + char model[GTL_MAX_STR_SIZE]; + char tl_type[GTL_MAX_STR_SIZE]; + char display_name[GTL_MAX_STR_SIZE]; + gint32 access_status; + INFO_DATATYPE datatype; + + ret = GTL_IFGetDeviceID (src->hIF, index, dev_id, &str_size); + if (ret != GC_ERR_SUCCESS) { + GST_WARNING_OBJECT (src, "Failed to get device id: %s", + gst_genicamsrc_get_error_string (src)); + return; + } + + str_size = GTL_MAX_STR_SIZE; + GTL_IFGetDeviceInfo (src->hIF, dev_id, DEVICE_INFO_ID, &datatype, id, + &str_size); + str_size = GTL_MAX_STR_SIZE; + GTL_IFGetDeviceInfo (src->hIF, dev_id, DEVICE_INFO_VENDOR, &datatype, vendor, + &str_size); + str_size = GTL_MAX_STR_SIZE; + GTL_IFGetDeviceInfo (src->hIF, dev_id, DEVICE_INFO_MODEL, &datatype, model, + &str_size); + str_size = GTL_MAX_STR_SIZE; + GTL_IFGetDeviceInfo (src->hIF, dev_id, DEVICE_INFO_TLTYPE, &datatype, tl_type, + &str_size); + str_size = GTL_MAX_STR_SIZE; + GTL_IFGetDeviceInfo (src->hIF, dev_id, DEVICE_INFO_DISPLAYNAME, &datatype, + display_name, &str_size); + str_size = sizeof (access_status); + GTL_IFGetDeviceInfo (src->hIF, dev_id, DEVICE_INFO_ACCESS_STATUS, &datatype, + &access_status, &str_size); + + GST_DEBUG_OBJECT (src, + "Device %d: ID=%s, Vendor=%s, Model=%s, TL_Type=%s, Display_Name=%s, Access_Status=%d", + index, id, vendor, model, tl_type, display_name, access_status); +} + +//void gst_genicam_print_stream_info (GstGenicamSrc * src) +//{ +// GC_ERROR ret; +// size_t str_size; +// char dev_id[GTL_MAX_STR_SIZE]; +// char id[GTL_MAX_STR_SIZE]; +// char vendor[GTL_MAX_STR_SIZE]; +// char model[GTL_MAX_STR_SIZE]; +// char tl_type[GTL_MAX_STR_SIZE]; +// char display_name[GTL_MAX_STR_SIZE]; +// gint32 access_status; +// INFO_DATATYPE datatype; +// +// //ret = GTL_DevGetDataStreamID(src->hIF, index, dev_id, &str_size); +// //if (ret != GC_ERR_SUCCESS) { +// // GST_WARNING_OBJECT (src, "Failed to get stream id: %s", gst_genicamsrc_get_error_string(src)); +// // return; +// //} +// +// str_size = GTL_MAX_STR_SIZE; +// GTL_DSGetInfo(src->hDEV, DEVICE_INFO_ID, &datatype, id, &str_size); +// str_size = GTL_MAX_STR_SIZE; +// GTL_DSGetInfo(src->hDEV, DEVICE_INFO_VENDOR, &datatype, vendor, &str_size); +// str_size = GTL_MAX_STR_SIZE; +// GTL_DSGetInfo(src->hDEV, DEVICE_INFO_MODEL, &datatype, model, &str_size); +// str_size = GTL_MAX_STR_SIZE; +// GTL_DSGetInfo(src->hDEV, DEVICE_INFO_TLTYPE, &datatype, tl_type, &str_size); +// str_size = GTL_MAX_STR_SIZE; +// GTL_DSGetInfo(src->hDEV, DEVICE_INFO_DISPLAYNAME, &datatype, display_name, &str_size); +// str_size = sizeof(access_status); +// GTL_DSGetInfo(src->hDEV, DEVICE_INFO_ACCESS_STATUS, &datatype, &access_status, &str_size); +// +// GST_DEBUG_OBJECT (src, "Device %d: ID=%s, Vendor=%s, Model=%s, TL_Type=%s, Display_Name=%s, Access_Status=%d", +// index, id, vendor, model, tl_type, display_name, access_status); +//} + + +static size_t +gst_genicamsrc_get_payload_size (GstGenicamSrc * src) +{ + GC_ERROR ret; + INFO_DATATYPE info_datatype; + size_t info_size; + bool8_t size_defined; + size_t payload_size = 0; + + info_size = sizeof (size_defined); + ret = + GTL_DSGetInfo (src->hDS, STREAM_INFO_DEFINES_PAYLOADSIZE, &info_datatype, + &size_defined, &info_size); + + if (size_defined) { + info_size = sizeof (payload_size); + ret = + GTL_DSGetInfo (src->hDS, STREAM_INFO_PAYLOAD_SIZE, &info_datatype, + &payload_size, &info_size); + } else { + guint32 val = 0; + size_t datasize = 4; + // TODO: use node map + ret = GTL_GCReadPort (src->hDevPort, 0x10088, &val, &datasize); + HANDLE_GTL_ERROR ("Failed to get payload size"); + payload_size = GUINT32_FROM_BE (val); + + //PORT_HANDLE port_handle; + //ret = GTL_DevGetPort(src->hDEV, &port_handle); + + //GTL_GCGetNum + + //GTL_GCReadPort(port_handle, ) + ////GTL_GCGetPortInfo(port_handle, ) + } + + return payload_size; + +error: + return 0; +} + +static gboolean +gst_genicamsrc_prepare_buffers (GstGenicamSrc * src) +{ + size_t payload_size; + guint i; + BUFFER_HANDLE hBuffer; + GC_ERROR ret; + + /* TODO: query Data Stream features to find min/max num_buffers */ + payload_size = gst_genicamsrc_get_payload_size (src); + if (payload_size == 0) { + return FALSE; + } + + for (i = 0; i < src->num_capture_buffers; ++i) { + ret = GTL_DSAllocAndAnnounceBuffer (src->hDS, payload_size, NULL, &hBuffer); + HANDLE_GTL_ERROR ("Failed to alloc and announce buffer"); + + ret = GTL_DSQueueBuffer (src->hDS, hBuffer); + HANDLE_GTL_ERROR ("Failed to queue buffer"); + } + + return TRUE; + +error: + return FALSE; +} + + + +static gboolean +gst_genicamsrc_start (GstBaseSrc * bsrc) +{ + GstGenicamSrc *src = GST_GENICAM_SRC (bsrc); + GC_ERROR ret; + uint32_t i, num_ifaces, num_devs; + guint32 width, height, bpp, stride; + GstVideoInfo vinfo; + + GST_DEBUG_OBJECT (src, "start"); + + /* bind functions from CTI */ + if (!gst_genicamsrc_bind_functions (src)) { + GST_ELEMENT_ERROR (src, LIBRARY, INIT, + ("GenTL CTI could not be opened: %s", g_module_error ()), (NULL)); + return FALSE; + } + + /* initialize library and print info */ + ret = GTL_GCInitLib (); + HANDLE_GTL_ERROR ("GenTL Producer library could not be initialized"); + + gst_genicam_print_gentl_impl_info (src); + + /* open GenTL, print info, and update interface list */ + ret = GTL_TLOpen (&src->hTL); + HANDLE_GTL_ERROR ("System module failed to open"); + + gst_genicam_print_system_info (src); + + ret = GTL_TLUpdateInterfaceList (src->hTL, NULL, src->timeout); + HANDLE_GTL_ERROR ("Failed to update interface list within timeout"); + + /* print info for all interfaces and open specified interface */ + ret = GTL_TLGetNumInterfaces (src->hTL, &num_ifaces); + HANDLE_GTL_ERROR ("Failed to get number of interfaces"); + if (num_ifaces > 0) { + GST_DEBUG_OBJECT (src, "Found %dGenTL interfaces", num_ifaces); + for (i = 0; i < num_ifaces; ++i) { + gst_genicam_print_interface_info (src, i); + } + } else { + GST_ELEMENT_ERROR (src, LIBRARY, FAILED, ("No interfaces found"), (NULL)); + goto error; + } + + if (!src->interface_id || src->interface_id[0] == 0) { + size_t id_size; + GST_DEBUG_OBJECT (src, "Trying to find interface ID at index %d", + src->interface_index); + + ret = GTL_TLGetInterfaceID (src->hTL, src->interface_index, NULL, &id_size); + HANDLE_GTL_ERROR ("Failed to get interface ID at specified index"); + if (src->interface_id) { + g_free (src->interface_id); + } + src->interface_id = (gchar *) g_malloc (id_size); + ret = + GTL_TLGetInterfaceID (src->hTL, src->interface_index, src->interface_id, + &id_size); + HANDLE_GTL_ERROR ("Failed to get interface ID at specified index"); + } + + GST_DEBUG_OBJECT (src, "Trying to open interface '%s'", src->interface_id); + ret = GTL_TLOpenInterface (src->hTL, src->interface_id, &src->hIF); + HANDLE_GTL_ERROR ("Interface module failed to open"); + + ret = GTL_IFUpdateDeviceList (src->hIF, NULL, src->timeout); + HANDLE_GTL_ERROR ("Failed to update device list within timeout"); + + /* print info for all devices and open specified device */ + ret = GTL_IFGetNumDevices (src->hIF, &num_devs); + HANDLE_GTL_ERROR ("Failed to get number of devices"); + if (num_devs > 0) { + for (i = 0; i < num_devs; ++i) { + gst_genicam_print_device_info (src, i); + } + } else { + GST_ELEMENT_ERROR (src, LIBRARY, FAILED, + ("No devices found on interface"), (NULL)); + goto error; + } + + if (!src->device_id || src->device_id[0] == 0) { + size_t id_size; + GST_DEBUG_OBJECT (src, "Trying to find device ID at index %d", + src->device_index); + + GTL_IFGetDeviceID (src->hIF, src->device_index, NULL, &id_size); + HANDLE_GTL_ERROR ("Failed to get device ID at specified index"); + if (src->device_id) { + g_free (src->device_id); + } + src->device_id = (gchar *) g_malloc (id_size); + GTL_IFGetDeviceID (src->hIF, src->device_index, src->device_id, &id_size); + HANDLE_GTL_ERROR ("Failed to get device ID at specified index"); + } + + GST_DEBUG_OBJECT (src, "Trying to open device '%s'", src->device_id); + ret = + GTL_IFOpenDevice (src->hIF, src->device_id, DEVICE_ACCESS_CONTROL, + &src->hDEV); + HANDLE_GTL_ERROR ("Failed to open device"); + + /* find and open specified data stream id */ + if (!src->stream_id || src->stream_id[0] == 0) { + size_t id_size; + GST_DEBUG_OBJECT (src, "Trying to find stream ID at index %d", + src->stream_index); + + GTL_DevGetDataStreamID (src->hDEV, src->stream_index, NULL, &id_size); + HANDLE_GTL_ERROR ("Failed to get stream ID at specified index"); + if (src->stream_id) { + g_free (src->stream_id); + } + src->stream_id = (gchar *) g_malloc (id_size); + GTL_DevGetDataStreamID (src->hDEV, src->stream_index, src->stream_id, + &id_size); + HANDLE_GTL_ERROR ("Failed to get stream ID at specified index"); + } + + GST_DEBUG_OBJECT (src, "Trying to open data stream '%s'", src->stream_id); + ret = GTL_DevOpenDataStream (src->hDEV, src->stream_id, &src->hDS); + HANDLE_GTL_ERROR ("Failed to open data stream"); + + { + uint32_t num_urls = 0; + char url[2048]; + size_t url_len = sizeof (url); + INFO_DATATYPE datatype; + const uint32_t url_index = 0; + + ret = GTL_DevGetPort (src->hDEV, &src->hDevPort); + HANDLE_GTL_ERROR ("Failed to get port on device"); + ret = GTL_GCGetNumPortURLs (src->hDevPort, &num_urls); + HANDLE_GTL_ERROR ("Failed to get number of port URLs"); + + GST_DEBUG_OBJECT (src, "Found %d port URLs", num_urls); + + GST_DEBUG_OBJECT (src, "Trying to get URL index %d", url_index); + GTL_GCGetPortURLInfo (src->hDevPort, url_index, URL_INFO_URL, &datatype, + url, &url_len); + HANDLE_GTL_ERROR ("Failed to get URL"); + GST_DEBUG_OBJECT (src, "Found URL '%s'", url); + + g_assert (url_len > 6); + if (g_str_has_prefix (url, "file")) { + GST_ELEMENT_ERROR (src, RESOURCE, TOO_LAZY, + ("file url not supported yet"), (NULL)); + goto error; + } else if (g_str_has_prefix (url, "local")) { + GError *err = NULL; + GMatchInfo *matchInfo; + GRegex *regex; + gchar *filename, *addr_str, *len_str; + uint64_t addr; + size_t len; + gchar *buf; + + regex = + g_regex_new + ("local:(?:///)?(?[^;]+);(?
[^;]+);(?[^?]+)(?:[?]SchemaVersion=([^&]+))?", + (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, &err); + if (!regex) { + goto error; + } + g_regex_match (regex, url, (GRegexMatchFlags) 0, &matchInfo); + filename = g_match_info_fetch_named (matchInfo, "filename"); + addr_str = g_match_info_fetch_named (matchInfo, "address"); + len_str = g_match_info_fetch_named (matchInfo, "length"); + if (!filename || !addr_str || !len_str) { + GST_ELEMENT_ERROR (src, RESOURCE, TOO_LAZY, + ("Failed to parse local URL"), (NULL)); + goto error; + } + + addr = g_ascii_strtoull (addr_str, NULL, 16); + len = g_ascii_strtoull (len_str, NULL, 16); + buf = (gchar *) g_malloc (len); + GTL_GCReadPort (src->hDevPort, addr, buf, &len); + HANDLE_GTL_ERROR ("Failed to read XML from port"); + + if (g_str_has_suffix (filename, "zip")) { + gchar *zipfilepath; + unzFile uf; + unz_file_info64 fileinfo; + gchar xmlfilename[2048]; + gchar *xml; + + zipfilepath = g_build_filename (g_get_tmp_dir (), filename, NULL); + if (!g_file_set_contents (zipfilepath, buf, len, &err)) { + GST_ELEMENT_ERROR (src, RESOURCE, TOO_LAZY, + ("Failed to write zipped XML to %s", zipfilepath), (NULL)); + goto error; + } + uf = unzOpen64 (zipfilepath); + if (!uf) { + GST_ELEMENT_ERROR (src, RESOURCE, TOO_LAZY, + ("Failed to open zipped XML %s", zipfilepath), (NULL)); + goto error; + } + //ret = unzGetGlobalInfo64(uf, &gi); + ret = + unzGetCurrentFileInfo64 (uf, &fileinfo, xmlfilename, + sizeof (xmlfilename), NULL, 0, NULL, 0); + if (ret != UNZ_OK) { + GST_ELEMENT_ERROR (src, RESOURCE, TOO_LAZY, + ("Failed to query zip file %s", zipfilepath), (NULL)); + goto error; + } + + ret = unzOpenCurrentFile (uf); + if (ret != UNZ_OK) { + GST_ELEMENT_ERROR (src, RESOURCE, TOO_LAZY, + ("Failed to extract file %s", xmlfilename), (NULL)); + goto error; + } + + xml = (gchar *) g_malloc (fileinfo.uncompressed_size); + if (!xml) { + GST_ELEMENT_ERROR (src, RESOURCE, TOO_LAZY, + ("Failed to allocate memory to extract XML file"), (NULL)); + goto error; + } + + ret = unzReadCurrentFile (uf, xml, fileinfo.uncompressed_size); + if (ret != fileinfo.uncompressed_size) { + GST_ELEMENT_ERROR (src, RESOURCE, TOO_LAZY, + ("Failed to extract XML file %s", xmlfilename), (NULL)); + goto error; + } + unzClose (uf); + g_free (zipfilepath); + + zipfilepath = g_build_filename (g_get_tmp_dir (), xmlfilename, NULL); + g_file_set_contents (zipfilepath, xml, fileinfo.uncompressed_size, + &err); + g_free (zipfilepath); + + g_free (xml); + //GZlibDecompressor *decompress; + //char *unzipped; + //gsize outbuf_size, bytes_read, bytes_written; + //GInputStream *zippedstream, *unzippedstream; + //decompress = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_ZLIB); + + ////zippedstream = g_memory_input_stream_new_from_data(buf, len, g_free); + ////unzippedstream = g_converter_input_stream_new (zippedstream, G_CONVERTER(decompress)); + ////g_input_stream_read_all (G_INPUT_STREAM(unzippedstream), + //// g_converter_output_stream + //outbuf_size = 10000000; + //unzipped = (gchar*) g_malloc(outbuf_size); + //g_converter_convert (G_CONVERTER (decompress), buf, len, unzipped, outbuf_size, G_CONVERTER_NO_FLAGS, &bytes_read, &bytes_written, &err); + //GST_DEBUG_OBJECT (src, unzipped); + } + + g_free (filename); + g_free (addr_str); + g_free (len_str); + g_free (buf); + } else if (g_str_has_prefix (url, "http")) { + GST_ELEMENT_ERROR (src, RESOURCE, TOO_LAZY, + ("file url not supported yet"), (NULL)); + goto error; + } + } + + { + // TODO: use Genicam node map for this + guint32 val = 0; + size_t datasize = 4; + ret = GTL_GCReadPort (src->hDevPort, 0x30204, &val, &datasize); + HANDLE_GTL_ERROR ("Failed to get width"); + width = GUINT32_FROM_BE (val); + ret = GTL_GCReadPort (src->hDevPort, 0x30224, &val, &datasize); + HANDLE_GTL_ERROR ("Failed to get height"); + height = GUINT32_FROM_BE (val); + + bpp = 8; + } + + if (!gst_genicamsrc_prepare_buffers (src)) { + GST_ELEMENT_ERROR (src, RESOURCE, TOO_LAZY, ("Failed to prepare buffers"), + (NULL)); + goto error; + } + + { + ret = + GTL_GCRegisterEvent (src->hDS, EVENT_NEW_BUFFER, &src->hNewBufferEvent); + HANDLE_GTL_ERROR ("Failed to register New Buffer event"); + } + + ret = + GTL_DSStartAcquisition (src->hDS, ACQ_START_FLAGS_DEFAULT, + GENTL_INFINITE); + HANDLE_GTL_ERROR ("Failed to start stream acquisition"); + + { + // TODO: use Genicam node map for this + guint32 val; + size_t datasize; + + /* set AcquisitionMode to Continuous */ + val = GUINT32_TO_BE (2); + datasize = sizeof (val); + ret = GTL_GCWritePort (src->hDevPort, 0x40004, &val, &datasize); + HANDLE_GTL_ERROR ("Failed to start device acquisition"); + + /* send AcquisitionStart command */ + val = GUINT32_TO_BE (1); + datasize = sizeof (val); + ret = GTL_GCWritePort (src->hDevPort, 0x40024, &val, &datasize); + HANDLE_GTL_ERROR ("Failed to start device acquisition"); + } + + /* create caps */ + if (src->caps) { + gst_caps_unref (src->caps); + src->caps = NULL; + } + + gst_video_info_init (&vinfo); + + if (bpp <= 8) { + gst_video_info_set_format (&vinfo, GST_VIDEO_FORMAT_GRAY8, width, height); + src->caps = gst_video_info_to_caps (&vinfo); + } else if (bpp > 8 && bpp <= 16) { + GValue val = G_VALUE_INIT; + GstStructure *s; + + if (G_BYTE_ORDER == G_LITTLE_ENDIAN) { + gst_video_info_set_format (&vinfo, GST_VIDEO_FORMAT_GRAY16_LE, width, + height); + } else if (G_BYTE_ORDER == G_BIG_ENDIAN) { + gst_video_info_set_format (&vinfo, GST_VIDEO_FORMAT_GRAY16_BE, width, + height); + } + src->caps = gst_video_info_to_caps (&vinfo); + + /* set bpp, extra info for GRAY16 so elements can scale properly */ + s = gst_caps_get_structure (src->caps, 0); + g_value_init (&val, G_TYPE_INT); + g_value_set_int (&val, bpp); + gst_structure_set_value (s, "bpp", &val); + g_value_unset (&val); + } else { + GST_ELEMENT_ERROR (src, STREAM, WRONG_TYPE, + ("Unknown or unsupported bit depth (%d).", bpp), (NULL)); + return FALSE; + } + + src->height = vinfo.height; + src->gst_stride = GST_VIDEO_INFO_COMP_STRIDE (&vinfo, 0); + + GST_DEBUG_OBJECT (src, "starting acquisition"); +//TODO: start acquisition engine + + /* TODO: check timestamps on buffers vs start time */ + src->acq_start_time = + gst_clock_get_time (gst_element_get_clock (GST_ELEMENT (src))); + + return TRUE; + +error: + if (src->hDS) { + GTL_DSClose (src->hDS); + src->hDS = NULL; + } + + if (src->hDEV) { + GTL_DevClose (src->hDEV); + src->hDEV = NULL; + } + + if (src->hIF) { + GTL_IFClose (src->hIF); + src->hIF = NULL; + } + + if (src->hTL) { + GTL_TLClose (src->hTL); + src->hTL = NULL; + } + + GTL_GCCloseLib (); + + return FALSE; +} + +static gboolean +gst_genicamsrc_stop (GstBaseSrc * bsrc) +{ + GstGenicamSrc *src = GST_GENICAM_SRC (bsrc); + + GST_DEBUG_OBJECT (src, "stop"); + + if (src->hDS) { + GTL_DSStopAcquisition (src->hDS, ACQ_STOP_FLAGS_DEFAULT); + // TODO: also command device AcquisitionStop + GTL_DSFlushQueue (src->hDS, ACQ_QUEUE_INPUT_TO_OUTPUT); + GTL_DSFlushQueue (src->hDS, ACQ_QUEUE_OUTPUT_DISCARD); + GTL_DSClose (src->hDS); + src->hDS = NULL; + } + + if (src->hDEV) { + GTL_DevClose (src->hDEV); + src->hDEV = NULL; + } + + if (src->hIF) { + GTL_IFClose (src->hIF); + src->hIF = NULL; + } + + if (src->hTL) { + GTL_TLClose (src->hTL); + src->hTL = NULL; + } + + GTL_GCCloseLib (); + + gst_genicamsrc_reset (src); + + return TRUE; +} + +static GstCaps * +gst_genicamsrc_get_caps (GstBaseSrc * bsrc, GstCaps * filter) +{ + GstGenicamSrc *src = GST_GENICAM_SRC (bsrc); + GstCaps *caps; + + if (src->hDS == NULL) { + caps = gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD (src)); + } else { + caps = gst_caps_copy (src->caps); + } + + GST_DEBUG_OBJECT (src, "The caps before filtering are %" GST_PTR_FORMAT, + caps); + + if (filter && caps) { + GstCaps *tmp = gst_caps_intersect (caps, filter); + gst_caps_unref (caps); + caps = tmp; + } + + GST_DEBUG_OBJECT (src, "The caps after filtering are %" GST_PTR_FORMAT, caps); + + return caps; +} + +static gboolean +gst_genicamsrc_set_caps (GstBaseSrc * bsrc, GstCaps * caps) +{ + GstGenicamSrc *src = GST_GENICAM_SRC (bsrc); + GstVideoInfo vinfo; + GstStructure *s = gst_caps_get_structure (caps, 0); + + GST_DEBUG_OBJECT (src, "The caps being set are %" GST_PTR_FORMAT, caps); + + gst_video_info_from_caps (&vinfo, caps); + + if (GST_VIDEO_INFO_FORMAT (&vinfo) != GST_VIDEO_FORMAT_UNKNOWN) { + src->gst_stride = GST_VIDEO_INFO_COMP_STRIDE (&vinfo, 0); + } else { + goto unsupported_caps; + } + + return TRUE; + +unsupported_caps: + GST_ERROR_OBJECT (src, "Unsupported caps: %" GST_PTR_FORMAT, caps); + return FALSE; +} + +static gboolean +gst_genicamsrc_unlock (GstBaseSrc * bsrc) +{ + GstGenicamSrc *src = GST_GENICAM_SRC (bsrc); + + GST_LOG_OBJECT (src, "unlock"); + + src->stop_requested = TRUE; + + return TRUE; +} + +static gboolean +gst_genicamsrc_unlock_stop (GstBaseSrc * bsrc) +{ + GstGenicamSrc *src = GST_GENICAM_SRC (bsrc); + + GST_LOG_OBJECT (src, "unlock_stop"); + + src->stop_requested = FALSE; + + return TRUE; +} + +static GstBuffer * +gst_genicamsrc_get_buffer (GstGenicamSrc * src) +{ + GC_ERROR ret; + EVENT_NEW_BUFFER_DATA new_buffer_data; + INFO_DATATYPE datatype; + size_t datasize; + GstBuffer *buf = NULL; + size_t payload_type, buffer_size; + uint64_t frame_id; + bool8_t buffer_is_incomplete, is_acquiring; + guint8 *data_ptr; + GstMapInfo minfo; + + datasize = sizeof (new_buffer_data); + ret = + GTL_EventGetData (src->hNewBufferEvent, &new_buffer_data, &datasize, + src->timeout); + HANDLE_GTL_ERROR ("Failed to get New Buffer event within timeout period"); + + datasize = sizeof (payload_type); + ret = + GTL_DSGetBufferInfo (src->hDS, new_buffer_data.BufferHandle, + BUFFER_INFO_PAYLOADTYPE, &datatype, &payload_type, &datasize); + HANDLE_GTL_ERROR ("Failed to get payload type"); + + datasize = sizeof (frame_id); + ret = + GTL_DSGetBufferInfo (src->hDS, new_buffer_data.BufferHandle, + BUFFER_INFO_FRAMEID, &datatype, &frame_id, &datasize); + HANDLE_GTL_ERROR ("Failed to get frame id"); + + datasize = sizeof (buffer_is_incomplete); + ret = + GTL_DSGetBufferInfo (src->hDS, new_buffer_data.BufferHandle, + BUFFER_INFO_IS_INCOMPLETE, &datatype, &buffer_is_incomplete, &datasize); + HANDLE_GTL_ERROR ("Failed to get complete flag"); + + datasize = sizeof (buffer_size); + ret = + GTL_DSGetBufferInfo (src->hDS, new_buffer_data.BufferHandle, + BUFFER_INFO_SIZE, &datatype, &buffer_size, &datasize); + HANDLE_GTL_ERROR ("Failed to get buffer size"); + + datasize = sizeof (data_ptr); + ret = + GTL_DSGetBufferInfo (src->hDS, new_buffer_data.BufferHandle, + BUFFER_INFO_BASE, &datatype, &data_ptr, &datasize); + HANDLE_GTL_ERROR ("Failed to get buffer pointer"); + + if (payload_type != PAYLOAD_TYPE_IMAGE) { + GST_ELEMENT_ERROR (src, STREAM, TOO_LAZY, + ("Unsupported payload type: %d", payload_type), (NULL)); + goto error; + } + // TODO: what if strides aren't same? + + buf = gst_buffer_new_allocate (NULL, buffer_size, NULL); + if (!buf) { + GST_ELEMENT_ERROR (src, STREAM, TOO_LAZY, + ("Failed to allocate buffer"), (NULL)); + goto error; + } + + gst_buffer_map (buf, &minfo, GST_MAP_WRITE); + orc_memcpy (minfo.data, (void *) data_ptr, minfo.size); + gst_buffer_unmap (buf, &minfo); + + GTL_DSQueueBuffer (src->hDS, new_buffer_data.BufferHandle); + HANDLE_GTL_ERROR ("Failed to queue buffer"); + + return buf; + +error: + if (buf) { + gst_buffer_unref (buf); + } + return NULL; +} + +static GstFlowReturn +gst_genicamsrc_create (GstPushSrc * psrc, GstBuffer ** buf) +{ + GstGenicamSrc *src = GST_GENICAM_SRC (psrc); + guint32 dropped_frames = 0; + GstClock *clock; + GstClockTime clock_time; + + GST_LOG_OBJECT (src, "create"); + + *buf = gst_genicamsrc_get_buffer (src); + if (!*buf) { + return GST_FLOW_ERROR; + } + + clock = gst_element_get_clock (GST_ELEMENT (src)); + clock_time = gst_clock_get_time (clock); + gst_object_unref (clock); + + /* check for dropped frames and disrupted signal */ + //dropped_frames = (circ_handle.FrameCount - src->last_frame_count) - 1; + if (dropped_frames > 0) { + src->total_dropped_frames += dropped_frames; + GST_WARNING_OBJECT (src, "Dropped %d frames (%d total)", dropped_frames, + src->total_dropped_frames); + } else if (dropped_frames < 0) { + GST_WARNING_OBJECT (src, "Frame count non-monotonic, signal disrupted?"); + } + //src->last_frame_count = circ_handle.FrameCount; + + /* create GstBuffer then release circ buffer back to acquisition */ + //*buf = gst_genicamsrc_create_buffer_from_circ_handle (src, &circ_handle); + //ret = + // BiCirStatusSet (src->board, &src->buffer_array, circ_handle, BIAVAILABLE); + //if (ret != BI_OK) { + // GST_ELEMENT_ERROR (src, RESOURCE, FAILED, + // ("Failed to release buffer: %s", gst_genicamsrc_get_error_string (src, + // ret)), (NULL)); + // return GST_FLOW_ERROR; + //} + + /* TODO: understand why timestamps for circ_handle are sometimes 0 */ + //GST_BUFFER_TIMESTAMP (*buf) = + // GST_CLOCK_DIFF (gst_element_get_base_time (GST_ELEMENT (src)), + // src->acq_start_time + circ_handle.HiResTimeStamp.totalSec * GST_SECOND); + GST_BUFFER_TIMESTAMP (*buf) = + GST_CLOCK_DIFF (gst_element_get_base_time (GST_ELEMENT (src)), + clock_time); + //GST_BUFFER_OFFSET (*buf) = circ_handle.FrameCount - 1; + + if (src->stop_requested) { + if (*buf != NULL) { + gst_buffer_unref (*buf); + *buf = NULL; + } + return GST_FLOW_FLUSHING; + } + + return GST_FLOW_OK; + +error: + return GST_FLOW_ERROR; +} + +gchar * +gst_genicamsrc_get_error_string (GstGenicamSrc * src) +{ + size_t error_string_size = MAX_ERROR_STRING_LEN; + GC_ERROR error_code; + GTL_GCGetLastError (&error_code, src->error_string, &error_string_size); + return src->error_string; +} + + +static gboolean +plugin_init (GstPlugin * plugin) +{ + GST_DEBUG_CATEGORY_INIT (gst_genicamsrc_debug, "genicamsrc", 0, + "debug category for genicamsrc element"); + gst_element_register (plugin, "genicamsrc", GST_RANK_NONE, + gst_genicamsrc_get_type ()); + + return TRUE; +} + +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + genicam, + "GenICam frame grabber source", + plugin_init, GST_PACKAGE_VERSION, GST_PACKAGE_LICENSE, GST_PACKAGE_NAME, + GST_PACKAGE_ORIGIN); diff --git a/sys/genicam/gstgenicamsrc.h b/sys/genicam/gstgenicamsrc.h new file mode 100644 index 0000000..a14c7dd --- /dev/null +++ b/sys/genicam/gstgenicamsrc.h @@ -0,0 +1,84 @@ +/* GStreamer + * Copyright (C) 2011 FIXME + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GST_GENICAM_SRC_H_ +#define _GST_GENICAM_SRC_H_ + +#include + +#undef __cplusplus +#include "GenTL_v1_5.h" + +#define MAX_ERROR_STRING_LEN 256 + +G_BEGIN_DECLS + +#define GST_TYPE_GENICAM_SRC (gst_genicamsrc_get_type()) +#define GST_GENICAM_SRC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GENICAM_SRC,GstGenicamSrc)) +#define GST_GENICAM_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GENICAM_SRC,GstGenicamSrcClass)) +#define GST_IS_GENICAM_SRC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GENICAM_SRC)) +#define GST_IS_GENICAM_SRC_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GENICAM_SRC)) + +typedef struct _GstGenicamSrc GstGenicamSrc; +typedef struct _GstGenicamSrcClass GstGenicamSrcClass; + +struct _GstGenicamSrc +{ + GstPushSrc base_genicamsrc; + + /* camera handle */ + TL_HANDLE hTL; + IF_HANDLE hIF; + DEV_HANDLE hDEV; + DS_HANDLE hDS; + PORT_HANDLE hDevPort; + EVENT_HANDLE hNewBufferEvent; + char error_string[MAX_ERROR_STRING_LEN]; + + /* properties */ + guint interface_index; + gchar *interface_id; + guint device_index; + gchar *device_id; + guint stream_index; + gchar *stream_id; + guint num_capture_buffers; + gint timeout; + + GstClockTime acq_start_time; + guint32 last_frame_count; + guint32 total_dropped_frames; + + GstCaps *caps; + gint height; + gint gst_stride; + + gboolean stop_requested; +}; + +struct _GstGenicamSrcClass +{ + GstPushSrcClass base_genicamsrc_class; +}; + +GType gst_genicamsrc_get_type (void); + +G_END_DECLS + +#endif diff --git a/sys/genicam/ioapi.c b/sys/genicam/ioapi.c new file mode 100644 index 0000000..7f5c191 --- /dev/null +++ b/sys/genicam/ioapi.c @@ -0,0 +1,247 @@ +/* ioapi.h -- IO base function header for compress/uncompress .zip + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + +*/ + +#if defined(_WIN32) && (!(defined(_CRT_SECURE_NO_WARNINGS))) + #define _CRT_SECURE_NO_WARNINGS +#endif + +#if defined(__APPLE__) || defined(IOAPI_NO_64) +// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions +#define FOPEN_FUNC(filename, mode) fopen(filename, mode) +#define FTELLO_FUNC(stream) ftello(stream) +#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin) +#else +#define FOPEN_FUNC(filename, mode) fopen64(filename, mode) +#define FTELLO_FUNC(stream) ftello64(stream) +#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin) +#endif + + +#include "ioapi.h" + +voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode) +{ + if (pfilefunc->zfile_func64.zopen64_file != NULL) + return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode); + else + { + return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode); + } +} + +long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin) +{ + if (pfilefunc->zfile_func64.zseek64_file != NULL) + return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin); + else + { + uLong offsetTruncated = (uLong)offset; + if (offsetTruncated != offset) + return -1; + else + return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin); + } +} + +ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream) +{ + if (pfilefunc->zfile_func64.zseek64_file != NULL) + return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream); + else + { + uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream); + if ((tell_uLong) == MAXU32) + return (ZPOS64_T)-1; + else + return tell_uLong; + } +} + +void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32) +{ + p_filefunc64_32->zfile_func64.zopen64_file = NULL; + p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file; + p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; + p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file; + p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file; + p_filefunc64_32->zfile_func64.ztell64_file = NULL; + p_filefunc64_32->zfile_func64.zseek64_file = NULL; + p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file; + p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; + p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque; + p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file; + p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file; +} + + + +static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode)); +static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size)); +static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream)); +static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); +static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream)); +static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream)); + +static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode) +{ + FILE* file = NULL; + const char* mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename!=NULL) && (mode_fopen != NULL)) + file = fopen(filename, mode_fopen); + return file; +} + +static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode) +{ + FILE* file = NULL; + const char* mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename!=NULL) && (mode_fopen != NULL)) + file = FOPEN_FUNC((const char*)filename, mode_fopen); + return file; +} + + +static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size) +{ + uLong ret; + ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size) +{ + uLong ret; + ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream) +{ + long ret; + ret = ftell((FILE *)stream); + return ret; +} + + +static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream) +{ + ZPOS64_T ret; + ret = FTELLO_FUNC((FILE *)stream); + return ret; +} + +static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin) +{ + int fseek_origin=0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END : + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + fseek_origin = SEEK_SET; + break; + default: return -1; + } + ret = 0; + if (fseek((FILE *)stream, offset, fseek_origin) != 0) + ret = -1; + return ret; +} + +static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) +{ + int fseek_origin=0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END : + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + fseek_origin = SEEK_SET; + break; + default: return -1; + } + ret = 0; + + if(FSEEKO_FUNC((FILE *)stream, offset, fseek_origin) != 0) + ret = -1; + + return ret; +} + + +static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream) +{ + int ret; + ret = fclose((FILE *)stream); + return ret; +} + +static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream) +{ + int ret; + ret = ferror((FILE *)stream); + return ret; +} + +void fill_fopen_filefunc (pzlib_filefunc_def) + zlib_filefunc_def* pzlib_filefunc_def; +{ + pzlib_filefunc_def->zopen_file = fopen_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell_file = ftell_file_func; + pzlib_filefunc_def->zseek_file = fseek_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} + +void fill_fopen64_filefunc (zlib_filefunc64_def* pzlib_filefunc_def) +{ + pzlib_filefunc_def->zopen64_file = fopen64_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell64_file = ftell64_file_func; + pzlib_filefunc_def->zseek64_file = fseek64_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} diff --git a/sys/genicam/ioapi.h b/sys/genicam/ioapi.h new file mode 100644 index 0000000..8dcbdb0 --- /dev/null +++ b/sys/genicam/ioapi.h @@ -0,0 +1,208 @@ +/* ioapi.h -- IO base function header for compress/uncompress .zip + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + Changes + + Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this) + Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux. + More if/def section may be needed to support other platforms + Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows. + (but you should use iowin32.c for windows instead) + +*/ + +#ifndef _ZLIBIOAPI64_H +#define _ZLIBIOAPI64_H + +#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__)) + + // Linux needs this to support file operation on files larger then 4+GB + // But might need better if/def to select just the platforms that needs them. + + #ifndef __USE_FILE_OFFSET64 + #define __USE_FILE_OFFSET64 + #endif + #ifndef __USE_LARGEFILE64 + #define __USE_LARGEFILE64 + #endif + #ifndef _LARGEFILE64_SOURCE + #define _LARGEFILE64_SOURCE + #endif + #ifndef _FILE_OFFSET_BIT + #define _FILE_OFFSET_BIT 64 + #endif + +#endif + +#include +#include +#include "zlib.h" + +#if defined(USE_FILE32API) +#define fopen64 fopen +#define ftello64 ftell +#define fseeko64 fseek +#else +#ifdef __FreeBSD__ +#define fopen64 fopen +#define ftello64 ftello +#define fseeko64 fseeko +#endif +#ifdef _MSC_VER + #define fopen64 fopen + #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC))) + #define ftello64 _ftelli64 + #define fseeko64 _fseeki64 + #else // old MSC + #define ftello64 ftell + #define fseeko64 fseek + #endif +#endif +#endif + +/* +#ifndef ZPOS64_T + #ifdef _WIN32 + #define ZPOS64_T fpos_t + #else + #include + #define ZPOS64_T uint64_t + #endif +#endif +*/ + +#ifdef HAVE_MINIZIP64_CONF_H +#include "mz64conf.h" +#endif + +/* a type choosen by DEFINE */ +#ifdef HAVE_64BIT_INT_CUSTOM +typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T; +#else +#ifdef HAS_STDINT_H +#include "stdint.h" +typedef uint64_t ZPOS64_T; +#else + +/* Maximum unsigned 32-bit value used as placeholder for zip64 */ +#define MAXU32 0xffffffff + +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef unsigned __int64 ZPOS64_T; +#else +typedef unsigned long long int ZPOS64_T; +#endif +#endif +#endif + + + +#ifdef __cplusplus +extern "C" { +#endif + + +#define ZLIB_FILEFUNC_SEEK_CUR (1) +#define ZLIB_FILEFUNC_SEEK_END (2) +#define ZLIB_FILEFUNC_SEEK_SET (0) + +#define ZLIB_FILEFUNC_MODE_READ (1) +#define ZLIB_FILEFUNC_MODE_WRITE (2) +#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) + +#define ZLIB_FILEFUNC_MODE_EXISTING (4) +#define ZLIB_FILEFUNC_MODE_CREATE (8) + + +#ifndef ZCALLBACK + #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) + #define ZCALLBACK CALLBACK + #else + #define ZCALLBACK + #endif +#endif + + + + +typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); +typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); +typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); +typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); + +typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); +typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); + + +/* here is the "old" 32 bits structure structure */ +typedef struct zlib_filefunc_def_s +{ + open_file_func zopen_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell_file_func ztell_file; + seek_file_func zseek_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc_def; + +typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream)); +typedef long (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); +typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, const void* filename, int mode)); + +typedef struct zlib_filefunc64_def_s +{ + open64_file_func zopen64_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell64_file_func ztell64_file; + seek64_file_func zseek64_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc64_def; + +void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def)); +void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); + +/* now internal definition, only for zip.c and unzip.h */ +typedef struct zlib_filefunc64_32_def_s +{ + zlib_filefunc64_def zfile_func64; + open_file_func zopen32_file; + tell_file_func ztell32_file; + seek_file_func zseek32_file; +} zlib_filefunc64_32_def; + + +#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) +#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) +//#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream)) +//#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode)) +#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream)) +#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream)) + +voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)); +long call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)); +ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)); + +void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32); + +#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode))) +#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream))) +#define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode))) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sys/genicam/unzip.c b/sys/genicam/unzip.c new file mode 100644 index 0000000..affad4b --- /dev/null +++ b/sys/genicam/unzip.c @@ -0,0 +1,2125 @@ +/* unzip.c -- IO for uncompress .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications of Unzip for Zip64 + Copyright (C) 2007-2008 Even Rouault + + Modifications for Zip64 support on both zip and unzip + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + + ------------------------------------------------------------------------------------ + Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of + compatibility with older software. The following is from the original crypt.c. + Code woven in by Terry Thorsen 1/2003. + + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html + + crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] + + The encryption/decryption parts of this source code (as opposed to the + non-echoing password parts) were originally written in Europe. The + whole source package can be freely distributed, including from the USA. + (Prior to January 2000, re-export from the US was a violation of US law.) + + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + + ------------------------------------------------------------------------------------ + + Changes in unzip.c + + 2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos + 2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz* + 2007-2008 - Even Rouault - Remove old C style function prototypes + 2007-2008 - Even Rouault - Add unzip support for ZIP64 + + Copyright (C) 2007-2008 Even Rouault + + + Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again). + Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G + should only read the compressed/uncompressed size from the Zip64 format if + the size from normal header was 0xFFFFFFFF + Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant + Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required) + Patch created by Daniel Borca + + Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer + + Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson + +*/ + + +#include +#include +#include + +#ifndef NOUNCRYPT + #define NOUNCRYPT +#endif + +#include "zlib.h" +#include "unzip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + + +#ifndef CASESENSITIVITYDEFAULT_NO +# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) +# define CASESENSITIVITYDEFAULT_NO +# endif +#endif + + +#ifndef UNZ_BUFSIZE +#define UNZ_BUFSIZE (16384) +#endif + +#ifndef UNZ_MAXFILENAMEINZIP +#define UNZ_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) + + +const char unz_copyright[] = + " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; + +/* unz_file_info_interntal contain internal info about a file in zipfile*/ +typedef struct unz_file_info64_internal_s +{ + ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */ +} unz_file_info64_internal; + + +/* file_in_zip_read_info_s contain internal information about a file in zipfile, + when reading and decompress it */ +typedef struct +{ + char *read_buffer; /* internal buffer for compressed data */ + z_stream stream; /* zLib stream structure for inflate */ + +#ifdef HAVE_BZIP2 + bz_stream bstream; /* bzLib stream structure for bziped */ +#endif + + ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ + uLong stream_initialised; /* flag set if stream structure is initialised*/ + + ZPOS64_T offset_local_extrafield;/* offset of the local extra field */ + uInt size_local_extrafield;/* size of the local extra field */ + ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/ + ZPOS64_T total_out_64; + + uLong crc32; /* crc32 of all data uncompressed */ + uLong crc32_wait; /* crc32 we must obtain after decompress all */ + ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */ + ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/ + zlib_filefunc64_32_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + uLong compression_method; /* compression method (0==store) */ + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + int raw; +} file_in_zip64_read_info_s; + + +/* unz64_s contain internal information about the zipfile +*/ +typedef struct +{ + zlib_filefunc64_32_def z_filefunc; + int is64bitOpenFunction; + voidpf filestream; /* io structore of the zipfile */ + unz_global_info64 gi; /* public global information */ + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + ZPOS64_T num_file; /* number of the current file in the zipfile*/ + ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/ + ZPOS64_T current_file_ok; /* flag about the usability of the current file*/ + ZPOS64_T central_pos; /* position of the beginning of the central dir*/ + + ZPOS64_T size_central_dir; /* size of the central directory */ + ZPOS64_T offset_central_dir; /* offset of start of central directory with + respect to the starting disk number */ + + unz_file_info64 cur_file_info; /* public info about the current file in zip*/ + unz_file_info64_internal cur_file_info_internal; /* private info about it*/ + file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current + file if we are decompressing it */ + int encrypted; + + int isZip64; + +# ifndef NOUNCRYPT + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + const unsigned long* pcrc_32_tab; +# endif +} unz64_s; + + +#ifndef NOUNCRYPT +#include "crypt.h" +#endif + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ + + +local int unz64local_getByte OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + int *pi)); + +local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi) +{ + unsigned char c; + int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); + if (err==1) + { + *pi = (int)c; + return UNZ_OK; + } + else + { + if (ZERROR64(*pzlib_filefunc_def,filestream)) + return UNZ_ERRNO; + else + return UNZ_EOF; + } +} + + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +local int unz64local_getShort OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX) +{ + uLong x ; + int i = 0; + int err; + + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((uLong)i)<<8; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int unz64local_getLong OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX) +{ + uLong x ; + int i = 0; + int err; + + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((uLong)i)<<8; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((uLong)i)<<16; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<24; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int unz64local_getLong64 OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + ZPOS64_T *pX)); + + +local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + ZPOS64_T *pX) +{ + ZPOS64_T x ; + int i = 0; + int err; + + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (ZPOS64_T)i; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<8; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<16; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<24; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<32; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<40; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<48; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<56; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +/* My own strcmpi / strcasecmp */ +local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2) +{ + for (;;) + { + char c1=*(fileName1++); + char c2=*(fileName2++); + if ((c1>='a') && (c1<='z')) + c1 -= 0x20; + if ((c2>='a') && (c2<='z')) + c2 -= 0x20; + if (c1=='\0') + return ((c2=='\0') ? 0 : -1); + if (c2=='\0') + return 1; + if (c1c2) + return 1; + } +} + + +#ifdef CASESENSITIVITYDEFAULT_NO +#define CASESENSITIVITYDEFAULTVALUE 2 +#else +#define CASESENSITIVITYDEFAULTVALUE 1 +#endif + +#ifndef STRCMPCASENOSENTIVEFUNCTION +#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal +#endif + +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) + +*/ +extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, + const char* fileName2, + int iCaseSensitivity) + +{ + if (iCaseSensitivity==0) + iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; + + if (iCaseSensitivity==1) + return strcmp(fileName1,fileName2); + + return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); +} + +#ifndef BUFREADCOMMENT +#define BUFREADCOMMENT (0x400) +#endif + +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +*/ +local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); +local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + return uPosFound; +} + + +/* + Locate the Central directory 64 of a zipfile (at the end, just before + the global comment) +*/ +local ZPOS64_T unz64local_SearchCentralDir64 OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream)); + +local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + uLong uL; + ZPOS64_T relativeOffset; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + if (uPosFound == 0) + return 0; + + /* Zip64 end of central directory locator */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature, already checked */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + + /* number of the disk with the start of the zip64 end of central directory */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + if (uL != 0) + return 0; + + /* relative offset of the zip64 end of central directory record */ + if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK) + return 0; + + /* total number of disks */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + if (uL != 1) + return 0; + + /* Goto end of central directory record */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + + if (uL != 0x06064b50) + return 0; + + return relativeOffset; +} + +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer + "zlib/zlib114.zip". + If the zipfile cannot be opened (file doesn't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ +local unzFile unzOpenInternal (const void *path, + zlib_filefunc64_32_def* pzlib_filefunc64_32_def, + int is64bitOpenFunction) +{ + unz64_s us; + unz64_s *s; + ZPOS64_T central_pos; + uLong uL; + + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + ZPOS64_T number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + + int err=UNZ_OK; + + if (unz_copyright[0]!=' ') + return NULL; + + us.z_filefunc.zseek32_file = NULL; + us.z_filefunc.ztell32_file = NULL; + if (pzlib_filefunc64_32_def==NULL) + fill_fopen64_filefunc(&us.z_filefunc.zfile_func64); + else + us.z_filefunc = *pzlib_filefunc64_32_def; + us.is64bitOpenFunction = is64bitOpenFunction; + + + + us.filestream = ZOPEN64(us.z_filefunc, + path, + ZLIB_FILEFUNC_MODE_READ | + ZLIB_FILEFUNC_MODE_EXISTING); + if (us.filestream==NULL) + return NULL; + + central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream); + if (central_pos) + { + uLong uS; + ZPOS64_T uL64; + + us.isZip64 = 1; + + if (ZSEEK64(us.z_filefunc, us.filestream, + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* size of zip64 end of central directory record */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK) + err=UNZ_ERRNO; + + /* version made by */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) + err=UNZ_ERRNO; + + /* version needed to extract */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central directory on this disk */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central directory */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + us.gi.size_comment = 0; + } + else + { + central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream); + if (central_pos==0) + err=UNZ_ERRNO; + + us.isZip64 = 0; + + if (ZSEEK64(us.z_filefunc, us.filestream, + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir on this disk */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.gi.number_entry = uL; + + /* total number of entries in the central dir */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + number_entry_CD = uL; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.size_central_dir = uL; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.offset_central_dir = uL; + + /* zipfile comment length */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) + err=UNZ_ERRNO; + } + + if ((central_pospfile_in_zip_read!=NULL) + unzCloseCurrentFile(file); + + ZCLOSE64(s->z_filefunc, s->filestream); + TRYFREE(s); + return UNZ_OK; +} + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ +extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info) +{ + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + *pglobal_info=s->gi; + return UNZ_OK; +} + +extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32) +{ + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + /* to do : check if number_entry is not truncated */ + pglobal_info32->number_entry = (uLong)s->gi.number_entry; + pglobal_info32->size_comment = s->gi.size_comment; + return UNZ_OK; +} +/* + Translate date/time from Dos format to tm_unz (readable more easilty) +*/ +local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm) +{ + ZPOS64_T uDate; + uDate = (ZPOS64_T)(ulDosDate>>16); + ptm->tm_mday = (uInt)(uDate&0x1f) ; + ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; + ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; + + ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); + ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; + ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; +} + +/* + Get Info about the current file in the zipfile, with internal only info +*/ +local int unz64local_GetCurrentFileInfoInternal OF((unzFile file, + unz_file_info64 *pfile_info, + unz_file_info64_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); + +local int unz64local_GetCurrentFileInfoInternal (unzFile file, + unz_file_info64 *pfile_info, + unz_file_info64_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize) +{ + unz64_s* s; + unz_file_info64 file_info; + unz_file_info64_internal file_info_internal; + int err=UNZ_OK; + uLong uMagic; + long lSeek=0; + uLong uL; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (ZSEEK64(s->z_filefunc, s->filestream, + s->pos_in_central_dir+s->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + + /* we check the magic */ + if (err==UNZ_OK) + { + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x02014b50) + err=UNZ_BADZIPFILE; + } + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) + err=UNZ_ERRNO; + + unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info.compressed_size = uL; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info.uncompressed_size = uL; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) + err=UNZ_ERRNO; + + // relative offset of local header + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info_internal.offset_curfile = uL; + + lSeek+=file_info.size_filename; + if ((err==UNZ_OK) && (szFileName!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_filename0) && (fileNameBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek -= uSizeRead; + } + + // Read extrafield + if ((err==UNZ_OK) && (extraField!=NULL)) + { + ZPOS64_T uSizeRead ; + if (file_info.size_file_extraz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + + lSeek += file_info.size_file_extra - (uLong)uSizeRead; + } + else + lSeek += file_info.size_file_extra; + + + if ((err==UNZ_OK) && (file_info.size_file_extra != 0)) + { + uLong acc = 0; + + // since lSeek now points to after the extra field we need to move back + lSeek -= file_info.size_file_extra; + + if (lSeek!=0) + { + if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + while(acc < file_info.size_file_extra) + { + uLong headerId; + uLong dataSize; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK) + err=UNZ_ERRNO; + + /* ZIP64 extra fields */ + if (headerId == 0x0001) + { + uLong uL; + + if(file_info.uncompressed_size == MAXU32) + { + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info.compressed_size == MAXU32) + { + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info_internal.offset_curfile == MAXU32) + { + /* Relative Header offset */ + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info.disk_num_start == MAXU32) + { + /* Disk Start Number */ + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + } + + } + else + { + if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0) + err=UNZ_ERRNO; + } + + acc += 2 + 2 + dataSize; + } + } + + if ((err==UNZ_OK) && (szComment!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_commentz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + if ((file_info.size_file_comment>0) && (commentBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek+=file_info.size_file_comment - uSizeRead; + } + else + lSeek+=file_info.size_file_comment; + + + if ((err==UNZ_OK) && (pfile_info!=NULL)) + *pfile_info=file_info; + + if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) + *pfile_info_internal=file_info_internal; + + return err; +} + + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. +*/ +extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file, + unz_file_info64 * pfile_info, + char * szFileName, uLong fileNameBufferSize, + void *extraField, uLong extraFieldBufferSize, + char* szComment, uLong commentBufferSize) +{ + return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); +} + +extern int ZEXPORT unzGetCurrentFileInfo (unzFile file, + unz_file_info * pfile_info, + char * szFileName, uLong fileNameBufferSize, + void *extraField, uLong extraFieldBufferSize, + char* szComment, uLong commentBufferSize) +{ + int err; + unz_file_info64 file_info64; + err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); + if ((err==UNZ_OK) && (pfile_info != NULL)) + { + pfile_info->version = file_info64.version; + pfile_info->version_needed = file_info64.version_needed; + pfile_info->flag = file_info64.flag; + pfile_info->compression_method = file_info64.compression_method; + pfile_info->dosDate = file_info64.dosDate; + pfile_info->crc = file_info64.crc; + + pfile_info->size_filename = file_info64.size_filename; + pfile_info->size_file_extra = file_info64.size_file_extra; + pfile_info->size_file_comment = file_info64.size_file_comment; + + pfile_info->disk_num_start = file_info64.disk_num_start; + pfile_info->internal_fa = file_info64.internal_fa; + pfile_info->external_fa = file_info64.external_fa; + + pfile_info->tmu_date = file_info64.tmu_date, + + + pfile_info->compressed_size = (uLong)file_info64.compressed_size; + pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size; + + } + return err; +} +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ +extern int ZEXPORT unzGoToFirstFile (unzFile file) +{ + int err=UNZ_OK; + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + s->pos_in_central_dir=s->offset_central_dir; + s->num_file=0; + err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ +extern int ZEXPORT unzGoToNextFile (unzFile file) +{ + unz64_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ + if (s->num_file+1==s->gi.number_entry) + return UNZ_END_OF_LIST_OF_FILE; + + s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; + s->num_file++; + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzipStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ +extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity) +{ + unz64_s* s; + int err; + + /* We remember the 'current' position in the file so that we can jump + * back there if we fail. + */ + unz_file_info64 cur_file_infoSaved; + unz_file_info64_internal cur_file_info_internalSaved; + ZPOS64_T num_fileSaved; + ZPOS64_T pos_in_central_dirSaved; + + + if (file==NULL) + return UNZ_PARAMERROR; + + if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) + return UNZ_PARAMERROR; + + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + /* Save the current state */ + num_fileSaved = s->num_file; + pos_in_central_dirSaved = s->pos_in_central_dir; + cur_file_infoSaved = s->cur_file_info; + cur_file_info_internalSaved = s->cur_file_info_internal; + + err = unzGoToFirstFile(file); + + while (err == UNZ_OK) + { + char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; + err = unzGetCurrentFileInfo64(file,NULL, + szCurrentFileName,sizeof(szCurrentFileName)-1, + NULL,0,NULL,0); + if (err == UNZ_OK) + { + if (unzStringFileNameCompare(szCurrentFileName, + szFileName,iCaseSensitivity)==0) + return UNZ_OK; + err = unzGoToNextFile(file); + } + } + + /* We failed, so restore the state of the 'current file' to where we + * were. + */ + s->num_file = num_fileSaved ; + s->pos_in_central_dir = pos_in_central_dirSaved ; + s->cur_file_info = cur_file_infoSaved; + s->cur_file_info_internal = cur_file_info_internalSaved; + return err; +} + + +/* +/////////////////////////////////////////// +// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) +// I need random access +// +// Further optimization could be realized by adding an ability +// to cache the directory in memory. The goal being a single +// comprehensive file read to put the file I need in a memory. +*/ + +/* +typedef struct unz_file_pos_s +{ + ZPOS64_T pos_in_zip_directory; // offset in file + ZPOS64_T num_of_file; // # of file +} unz_file_pos; +*/ + +extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) +{ + unz64_s* s; + + if (file==NULL || file_pos==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + file_pos->pos_in_zip_directory = s->pos_in_central_dir; + file_pos->num_of_file = s->num_file; + + return UNZ_OK; +} + +extern int ZEXPORT unzGetFilePos( + unzFile file, + unz_file_pos* file_pos) +{ + unz64_file_pos file_pos64; + int err = unzGetFilePos64(file,&file_pos64); + if (err==UNZ_OK) + { + file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory; + file_pos->num_of_file = (uLong)file_pos64.num_of_file; + } + return err; +} + +extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos) +{ + unz64_s* s; + int err; + + if (file==NULL || file_pos==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + + /* jump to the right spot */ + s->pos_in_central_dir = file_pos->pos_in_zip_directory; + s->num_file = file_pos->num_of_file; + + /* set the current file */ + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + /* return results */ + s->current_file_ok = (err == UNZ_OK); + return err; +} + +extern int ZEXPORT unzGoToFilePos( + unzFile file, + unz_file_pos* file_pos) +{ + unz64_file_pos file_pos64; + if (file_pos == NULL) + return UNZ_PARAMERROR; + + file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory; + file_pos64.num_of_file = file_pos->num_of_file; + return unzGoToFilePos64(file,&file_pos64); +} + +/* +// Unzip Helper Functions - should be here? +/////////////////////////////////////////// +*/ + +/* + Read the local header of the current zipfile + Check the coherency of the local header and info in the end of central + directory about this file + store in *piSizeVar the size of extra info in local header + (filename and size of extra field data) +*/ +local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar, + ZPOS64_T * poffset_local_extrafield, + uInt * psize_local_extrafield) +{ + uLong uMagic,uData,uFlags; + uLong size_filename; + uLong size_extra_field; + int err=UNZ_OK; + + *piSizeVar = 0; + *poffset_local_extrafield = 0; + *psize_local_extrafield = 0; + + if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + + s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + + if (err==UNZ_OK) + { + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x04034b50) + err=UNZ_BADZIPFILE; + } + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; +/* + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) + err=UNZ_BADZIPFILE; +*/ + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) + err=UNZ_BADZIPFILE; + + if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && +/* #ifdef HAVE_BZIP2 */ + (s->cur_file_info.compression_method!=Z_BZIP2ED) && +/* #endif */ + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ + err=UNZ_ERRNO; + else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ + err=UNZ_ERRNO; + else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) + err=UNZ_BADZIPFILE; + + *piSizeVar += (uInt)size_filename; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) + err=UNZ_ERRNO; + *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + + SIZEZIPLOCALHEADER + size_filename; + *psize_local_extrafield = (uInt)size_extra_field; + + *piSizeVar += (uInt)size_extra_field; + + return err; +} + +/* + Open for reading data the current file in the zipfile. + If there is no error and the file is opened, the return value is UNZ_OK. +*/ +extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, + int* level, int raw, const char* password) +{ + int err=UNZ_OK; + uInt iSizeVar; + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + ZPOS64_T offset_local_extrafield; /* offset of the local extra field */ + uInt size_local_extrafield; /* size of the local extra field */ +# ifndef NOUNCRYPT + char source[12]; +# else + if (password != NULL) + return UNZ_PARAMERROR; +# endif + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_PARAMERROR; + + if (s->pfile_in_zip_read != NULL) + unzCloseCurrentFile(file); + + if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) + return UNZ_BADZIPFILE; + + pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s)); + if (pfile_in_zip_read_info==NULL) + return UNZ_INTERNALERROR; + + pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); + pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; + pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; + pfile_in_zip_read_info->pos_local_extrafield=0; + pfile_in_zip_read_info->raw=raw; + + if (pfile_in_zip_read_info->read_buffer==NULL) + { + TRYFREE(pfile_in_zip_read_info); + return UNZ_INTERNALERROR; + } + + pfile_in_zip_read_info->stream_initialised=0; + + if (method!=NULL) + *method = (int)s->cur_file_info.compression_method; + + if (level!=NULL) + { + *level = 6; + switch (s->cur_file_info.flag & 0x06) + { + case 6 : *level = 1; break; + case 4 : *level = 2; break; + case 2 : *level = 9; break; + } + } + + if ((s->cur_file_info.compression_method!=0) && +/* #ifdef HAVE_BZIP2 */ + (s->cur_file_info.compression_method!=Z_BZIP2ED) && +/* #endif */ + (s->cur_file_info.compression_method!=Z_DEFLATED)) + + err=UNZ_BADZIPFILE; + + pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; + pfile_in_zip_read_info->crc32=0; + pfile_in_zip_read_info->total_out_64=0; + pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method; + pfile_in_zip_read_info->filestream=s->filestream; + pfile_in_zip_read_info->z_filefunc=s->z_filefunc; + pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; + + pfile_in_zip_read_info->stream.total_out = 0; + + if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw)) + { +#ifdef HAVE_BZIP2 + pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0; + pfile_in_zip_read_info->bstream.bzfree = (free_func)0; + pfile_in_zip_read_info->bstream.opaque = (voidpf)0; + pfile_in_zip_read_info->bstream.state = (voidpf)0; + + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + pfile_in_zip_read_info->stream.next_in = (voidpf)0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED; + else + { + TRYFREE(pfile_in_zip_read_info); + return err; + } +#else + pfile_in_zip_read_info->raw=1; +#endif + } + else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw)) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + pfile_in_zip_read_info->stream.next_in = 0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=Z_DEFLATED; + else + { + TRYFREE(pfile_in_zip_read_info); + return err; + } + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + * In unzip, i don't wait absolutely Z_STREAM_END because I known the + * size of both compressed and uncompressed data + */ + } + pfile_in_zip_read_info->rest_read_compressed = + s->cur_file_info.compressed_size ; + pfile_in_zip_read_info->rest_read_uncompressed = + s->cur_file_info.uncompressed_size ; + + + pfile_in_zip_read_info->pos_in_zipfile = + s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + + iSizeVar; + + pfile_in_zip_read_info->stream.avail_in = (uInt)0; + + s->pfile_in_zip_read = pfile_in_zip_read_info; + s->encrypted = 0; + +# ifndef NOUNCRYPT + if (password != NULL) + { + int i; + s->pcrc_32_tab = get_crc_table(); + init_keys(password,s->keys,s->pcrc_32_tab); + if (ZSEEK64(s->z_filefunc, s->filestream, + s->pfile_in_zip_read->pos_in_zipfile + + s->pfile_in_zip_read->byte_before_the_zipfile, + SEEK_SET)!=0) + return UNZ_INTERNALERROR; + if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12) + return UNZ_INTERNALERROR; + + for (i = 0; i<12; i++) + zdecode(s->keys,s->pcrc_32_tab,source[i]); + + s->pfile_in_zip_read->pos_in_zipfile+=12; + s->encrypted=1; + } +# endif + + + return UNZ_OK; +} + +extern int ZEXPORT unzOpenCurrentFile (unzFile file) +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); +} + +extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password) +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, password); +} + +extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw) +{ + return unzOpenCurrentFile3(file, method, level, raw, NULL); +} + +/** Addition for GDAL : START */ + +extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + s=(unz64_s*)file; + if (file==NULL) + return 0; //UNZ_PARAMERROR; + pfile_in_zip_read_info=s->pfile_in_zip_read; + if (pfile_in_zip_read_info==NULL) + return 0; //UNZ_PARAMERROR; + return pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile; +} + +/** Addition for GDAL : END */ + +/* + Read bytes from the current file. + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ +extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) +{ + int err=UNZ_OK; + uInt iRead = 0; + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if (pfile_in_zip_read_info->read_buffer == NULL) + return UNZ_END_OF_LIST_OF_FILE; + if (len==0) + return 0; + + pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; + + pfile_in_zip_read_info->stream.avail_out = (uInt)len; + + if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && + (!(pfile_in_zip_read_info->raw))) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_uncompressed; + + if ((len>pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in) && + (pfile_in_zip_read_info->raw)) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in; + + while (pfile_in_zip_read_info->stream.avail_out>0) + { + if ((pfile_in_zip_read_info->stream.avail_in==0) && + (pfile_in_zip_read_info->rest_read_compressed>0)) + { + uInt uReadThis = UNZ_BUFSIZE; + if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; + if (uReadThis == 0) + return UNZ_EOF; + if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + if (ZREAD64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->read_buffer, + uReadThis)!=uReadThis) + return UNZ_ERRNO; + + +# ifndef NOUNCRYPT + if(s->encrypted) + { + uInt i; + for(i=0;iread_buffer[i] = + zdecode(s->keys,s->pcrc_32_tab, + pfile_in_zip_read_info->read_buffer[i]); + } +# endif + + + pfile_in_zip_read_info->pos_in_zipfile += uReadThis; + + pfile_in_zip_read_info->rest_read_compressed-=uReadThis; + + pfile_in_zip_read_info->stream.next_in = + (Bytef*)pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; + } + + if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) + { + uInt uDoCopy,i ; + + if ((pfile_in_zip_read_info->stream.avail_in == 0) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + return (iRead==0) ? UNZ_EOF : iRead; + + if (pfile_in_zip_read_info->stream.avail_out < + pfile_in_zip_read_info->stream.avail_in) + uDoCopy = pfile_in_zip_read_info->stream.avail_out ; + else + uDoCopy = pfile_in_zip_read_info->stream.avail_in ; + + for (i=0;istream.next_out+i) = + *(pfile_in_zip_read_info->stream.next_in+i); + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy; + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, + pfile_in_zip_read_info->stream.next_out, + uDoCopy); + pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; + pfile_in_zip_read_info->stream.avail_in -= uDoCopy; + pfile_in_zip_read_info->stream.avail_out -= uDoCopy; + pfile_in_zip_read_info->stream.next_out += uDoCopy; + pfile_in_zip_read_info->stream.next_in += uDoCopy; + pfile_in_zip_read_info->stream.total_out += uDoCopy; + iRead += uDoCopy; + } + else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED) + { +#ifdef HAVE_BZIP2 + uLong uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + uLong uOutThis; + + pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in; + pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in; + pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in; + pfile_in_zip_read_info->bstream.total_in_hi32 = 0; + pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out; + pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out; + pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out; + pfile_in_zip_read_info->bstream.total_out_hi32 = 0; + + uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32; + bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out; + + err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream); + + uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis)); + pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in; + pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in; + pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32; + pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out; + pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out; + pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32; + + if (err==BZ_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=BZ_OK) + break; +#endif + } // end Z_BZIP2ED + else + { + ZPOS64_T uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + ZPOS64_T uOutThis; + int flush=Z_SYNC_FLUSH; + + uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; + bufBefore = pfile_in_zip_read_info->stream.next_out; + + /* + if ((pfile_in_zip_read_info->rest_read_uncompressed == + pfile_in_zip_read_info->stream.avail_out) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + flush = Z_FINISH; + */ + err=inflate(&pfile_in_zip_read_info->stream,flush); + + if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) + err = Z_DATA_ERROR; + + uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; + + pfile_in_zip_read_info->crc32 = + crc32(pfile_in_zip_read_info->crc32,bufBefore, + (uInt)(uOutThis)); + + pfile_in_zip_read_info->rest_read_uncompressed -= + uOutThis; + + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + if (err==Z_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=Z_OK) + break; + } + } + + if (err==Z_OK) + return iRead; + return err; +} + + +/* + Give the current position in uncompressed data +*/ +extern z_off_t ZEXPORT unztell (unzFile file) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + return (z_off_t)pfile_in_zip_read_info->stream.total_out; +} + +extern ZPOS64_T ZEXPORT unztell64 (unzFile file) +{ + + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return (ZPOS64_T)-1; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return (ZPOS64_T)-1; + + return pfile_in_zip_read_info->total_out_64; +} + + +/* + return 1 if the end of file was reached, 0 elsewhere +*/ +extern int ZEXPORT unzeof (unzFile file) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + return 1; + else + return 0; +} + + + +/* +Read extra field from the current file (opened by unzOpenCurrentFile) +This is the local-header version of the extra field (sometimes, there is +more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field that can be read + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ +extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + uInt read_now; + ZPOS64_T size_to_read; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + size_to_read = (pfile_in_zip_read_info->size_local_extrafield - + pfile_in_zip_read_info->pos_local_extrafield); + + if (buf==NULL) + return (int)size_to_read; + + if (len>size_to_read) + read_now = (uInt)size_to_read; + else + read_now = (uInt)len ; + + if (read_now==0) + return 0; + + if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->offset_local_extrafield + + pfile_in_zip_read_info->pos_local_extrafield, + ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + if (ZREAD64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + buf,read_now)!=read_now) + return UNZ_ERRNO; + + return (int)read_now; +} + +/* + Close the file in zip opened with unzipOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ +extern int ZEXPORT unzCloseCurrentFile (unzFile file) +{ + int err=UNZ_OK; + + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && + (!pfile_in_zip_read_info->raw)) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + err=UNZ_CRCERROR; + } + + + TRYFREE(pfile_in_zip_read_info->read_buffer); + pfile_in_zip_read_info->read_buffer = NULL; + if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED) + inflateEnd(&pfile_in_zip_read_info->stream); +#ifdef HAVE_BZIP2 + else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED) + BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream); +#endif + + + pfile_in_zip_read_info->stream_initialised = 0; + TRYFREE(pfile_in_zip_read_info); + + s->pfile_in_zip_read=NULL; + + return err; +} + + +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ +extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf) +{ + unz64_s* s; + uLong uReadThis ; + if (file==NULL) + return (int)UNZ_PARAMERROR; + s=(unz64_s*)file; + + uReadThis = uSizeBuf; + if (uReadThis>s->gi.size_comment) + uReadThis = s->gi.size_comment; + + if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + if (uReadThis>0) + { + *szComment='\0'; + if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) + return UNZ_ERRNO; + } + + if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) + *(szComment+s->gi.size_comment)='\0'; + return (int)uReadThis; +} + +/* Additions by RX '2004 */ +extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) +{ + unz64_s* s; + + if (file==NULL) + return 0; //UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return 0; + if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) + if (s->num_file==s->gi.number_entry) + return 0; + return s->pos_in_central_dir; +} + +extern uLong ZEXPORT unzGetOffset (unzFile file) +{ + ZPOS64_T offset64; + + if (file==NULL) + return 0; //UNZ_PARAMERROR; + offset64 = unzGetOffset64(file); + return (uLong)offset64; +} + +extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos) +{ + unz64_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + + s->pos_in_central_dir = pos; + s->num_file = s->gi.number_entry; /* hack */ + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +extern int ZEXPORT unzSetOffset (unzFile file, uLong pos) +{ + return unzSetOffset64(file,pos); +} diff --git a/sys/genicam/unzip.h b/sys/genicam/unzip.h new file mode 100644 index 0000000..3183968 --- /dev/null +++ b/sys/genicam/unzip.h @@ -0,0 +1,437 @@ +/* unzip.h -- IO for uncompress .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications of Unzip for Zip64 + Copyright (C) 2007-2008 Even Rouault + + Modifications for Zip64 support on both zip and unzip + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + --------------------------------------------------------------------------------- + + Condition of use and distribution are the same than zlib : + + 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. + + --------------------------------------------------------------------------------- + + Changes + + See header of unzip64.c + +*/ + +#ifndef _unz64_H +#define _unz64_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#ifndef _ZLIBIOAPI_H +#include "ioapi.h" +#endif + +#ifdef HAVE_BZIP2 +#include "bzlib.h" +#endif + +#define Z_BZIP2ED 12 + +#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagunzFile__ { int unused; } unzFile__; +typedef unzFile__ *unzFile; +#else +typedef voidp unzFile; +#endif + + +#define UNZ_OK (0) +#define UNZ_END_OF_LIST_OF_FILE (-100) +#define UNZ_ERRNO (Z_ERRNO) +#define UNZ_EOF (0) +#define UNZ_PARAMERROR (-102) +#define UNZ_BADZIPFILE (-103) +#define UNZ_INTERNALERROR (-104) +#define UNZ_CRCERROR (-105) + +/* tm_unz contain date/time info */ +typedef struct tm_unz_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_unz; + +/* unz_global_info structure contain global data about the ZIPfile + These data comes from the end of central dir */ +typedef struct unz_global_info64_s +{ + ZPOS64_T number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info64; + +typedef struct unz_global_info_s +{ + uLong number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info; + +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_info64_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + ZPOS64_T compressed_size; /* compressed size 8 bytes */ + ZPOS64_T uncompressed_size; /* uncompressed size 8 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info64; + +typedef struct unz_file_info_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + uLong compressed_size; /* compressed size 4 bytes */ + uLong uncompressed_size; /* uncompressed size 4 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info; + +extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, + const char* fileName2, + int iCaseSensitivity)); +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) +*/ + + +extern unzFile ZEXPORT unzOpen OF((const char *path)); +extern unzFile ZEXPORT unzOpen64 OF((const void *path)); +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer + "zlib/zlib113.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. + the "64" function take a const void* pointer, because the path is just the + value passed to the open64_file_func callback. + Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path + is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char* + does not describe the reality +*/ + + +extern unzFile ZEXPORT unzOpen2 OF((const char *path, + zlib_filefunc_def* pzlib_filefunc_def)); +/* + Open a Zip file, like unzOpen, but provide a set of file low level API + for read/write the zip file (see ioapi.h) +*/ + +extern unzFile ZEXPORT unzOpen2_64 OF((const void *path, + zlib_filefunc64_def* pzlib_filefunc_def)); +/* + Open a Zip file, like unz64Open, but provide a set of file low level API + for read/write the zip file (see ioapi.h) +*/ + +extern int ZEXPORT unzClose OF((unzFile file)); +/* + Close a ZipFile opened with unzipOpen. + If there is files inside the .Zip opened with unzOpenCurrentFile (see later), + these files MUST be closed with unzipCloseCurrentFile before call unzipClose. + return UNZ_OK if there is no problem. */ + +extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, + unz_global_info *pglobal_info)); + +extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file, + unz_global_info64 *pglobal_info)); +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ + + +extern int ZEXPORT unzGetGlobalComment OF((unzFile file, + char *szComment, + uLong uSizeBuf)); +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ + + +/***************************************************************************/ +/* Unzip package allow you browse the directory of the zipfile */ + +extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ + +extern int ZEXPORT unzGoToNextFile OF((unzFile file)); +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ + +extern int ZEXPORT unzLocateFile OF((unzFile file, + const char *szFileName, + int iCaseSensitivity)); +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ + + +/* ****************************************** */ +/* Ryan supplied functions */ +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_pos_s +{ + uLong pos_in_zip_directory; /* offset in zip file directory */ + uLong num_of_file; /* # of file */ +} unz_file_pos; + +extern int ZEXPORT unzGetFilePos( + unzFile file, + unz_file_pos* file_pos); + +extern int ZEXPORT unzGoToFilePos( + unzFile file, + unz_file_pos* file_pos); + +typedef struct unz64_file_pos_s +{ + ZPOS64_T pos_in_zip_directory; /* offset in zip file directory */ + ZPOS64_T num_of_file; /* # of file */ +} unz64_file_pos; + +extern int ZEXPORT unzGetFilePos64( + unzFile file, + unz64_file_pos* file_pos); + +extern int ZEXPORT unzGoToFilePos64( + unzFile file, + const unz64_file_pos* file_pos); + +/* ****************************************** */ + +extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file, + unz_file_info64 *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); + +extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, + unz_file_info *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); +/* + Get Info about the current file + if pfile_info!=NULL, the *pfile_info structure will contain somes info about + the current file + if szFileName!=NULL, the filemane string will be copied in szFileName + (fileNameBufferSize is the size of the buffer) + if extraField!=NULL, the extra field information will be copied in extraField + (extraFieldBufferSize is the size of the buffer). + This is the Central-header version of the extra field + if szComment!=NULL, the comment string of the file will be copied in szComment + (commentBufferSize is the size of the buffer) +*/ + + +/** Addition for GDAL : START */ + +extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file)); + +/** Addition for GDAL : END */ + + +/***************************************************************************/ +/* for reading the content of the current zipfile, you can open it, read data + from it, and close it (you can close it before reading all the file) + */ + +extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); +/* + Open for reading data the current file in the zipfile. + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, + const char* password)); +/* + Open for reading data the current file in the zipfile. + password is a crypting password + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, + int* method, + int* level, + int raw)); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + +extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, + int* method, + int* level, + int raw, + const char* password)); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + + +extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); +/* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ + +extern int ZEXPORT unzReadCurrentFile OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read bytes from the current file (opened by unzOpenCurrentFile) + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ + +extern z_off_t ZEXPORT unztell OF((unzFile file)); + +extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file)); +/* + Give the current position in uncompressed data +*/ + +extern int ZEXPORT unzeof OF((unzFile file)); +/* + return 1 if the end of file was reached, 0 elsewhere +*/ + +extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ + +/***************************************************************************/ + +/* Get the current file offset */ +extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file); +extern uLong ZEXPORT unzGetOffset (unzFile file); + +/* Set the current file offset */ +extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos); +extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); + + + +#ifdef __cplusplus +} +#endif + +#endif /* _unz64_H */