mirror of
https://github.com/zebrajr/opencv.git
synced 2025-12-06 00:19:46 +01:00
Merge branch 4.x
This commit is contained in:
commit
d1a5723864
201
3rdparty/dlpack/LICENSE
vendored
Normal file
201
3rdparty/dlpack/LICENSE
vendored
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2017 by Contributors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
366
3rdparty/dlpack/include/dlpack/dlpack.h
vendored
Normal file
366
3rdparty/dlpack/include/dlpack/dlpack.h
vendored
Normal file
|
|
@ -0,0 +1,366 @@
|
|||
/*!
|
||||
* Copyright (c) 2017 by Contributors
|
||||
* \file dlpack.h
|
||||
* \brief The common header of DLPack.
|
||||
*/
|
||||
#ifndef DLPACK_DLPACK_H_
|
||||
#define DLPACK_DLPACK_H_
|
||||
|
||||
/**
|
||||
* \brief Compatibility with C++
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
#define DLPACK_EXTERN_C extern "C"
|
||||
#else
|
||||
#define DLPACK_EXTERN_C
|
||||
#endif
|
||||
|
||||
/*! \brief The current major version of dlpack */
|
||||
#define DLPACK_MAJOR_VERSION 1
|
||||
|
||||
/*! \brief The current minor version of dlpack */
|
||||
#define DLPACK_MINOR_VERSION 1
|
||||
|
||||
/*! \brief DLPACK_DLL prefix for windows */
|
||||
#ifdef _WIN32
|
||||
#ifdef DLPACK_EXPORTS
|
||||
#define DLPACK_DLL __declspec(dllexport)
|
||||
#else
|
||||
#define DLPACK_DLL __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define DLPACK_DLL
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* \brief The DLPack version.
|
||||
*
|
||||
* A change in major version indicates that we have changed the
|
||||
* data layout of the ABI - DLManagedTensorVersioned.
|
||||
*
|
||||
* A change in minor version indicates that we have added new
|
||||
* code, such as a new device type, but the ABI is kept the same.
|
||||
*
|
||||
* If an obtained DLPack tensor has a major version that disagrees
|
||||
* with the version number specified in this header file
|
||||
* (i.e. major != DLPACK_MAJOR_VERSION), the consumer must call the deleter
|
||||
* (and it is safe to do so). It is not safe to access any other fields
|
||||
* as the memory layout will have changed.
|
||||
*
|
||||
* In the case of a minor version mismatch, the tensor can be safely used as
|
||||
* long as the consumer knows how to interpret all fields. Minor version
|
||||
* updates indicate the addition of enumeration values.
|
||||
*/
|
||||
typedef struct {
|
||||
/*! \brief DLPack major version. */
|
||||
uint32_t major;
|
||||
/*! \brief DLPack minor version. */
|
||||
uint32_t minor;
|
||||
} DLPackVersion;
|
||||
|
||||
/*!
|
||||
* \brief The device type in DLDevice.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
typedef enum : int32_t {
|
||||
#else
|
||||
typedef enum {
|
||||
#endif
|
||||
/*! \brief CPU device */
|
||||
kDLCPU = 1,
|
||||
/*! \brief CUDA GPU device */
|
||||
kDLCUDA = 2,
|
||||
/*!
|
||||
* \brief Pinned CUDA CPU memory by cudaMallocHost
|
||||
*/
|
||||
kDLCUDAHost = 3,
|
||||
/*! \brief OpenCL devices. */
|
||||
kDLOpenCL = 4,
|
||||
/*! \brief Vulkan buffer for next generation graphics. */
|
||||
kDLVulkan = 7,
|
||||
/*! \brief Metal for Apple GPU. */
|
||||
kDLMetal = 8,
|
||||
/*! \brief Verilog simulator buffer */
|
||||
kDLVPI = 9,
|
||||
/*! \brief ROCm GPUs for AMD GPUs */
|
||||
kDLROCM = 10,
|
||||
/*!
|
||||
* \brief Pinned ROCm CPU memory allocated by hipMallocHost
|
||||
*/
|
||||
kDLROCMHost = 11,
|
||||
/*!
|
||||
* \brief Reserved extension device type,
|
||||
* used for quickly test extension device
|
||||
* The semantics can differ depending on the implementation.
|
||||
*/
|
||||
kDLExtDev = 12,
|
||||
/*!
|
||||
* \brief CUDA managed/unified memory allocated by cudaMallocManaged
|
||||
*/
|
||||
kDLCUDAManaged = 13,
|
||||
/*!
|
||||
* \brief Unified shared memory allocated on a oneAPI non-partititioned
|
||||
* device. Call to oneAPI runtime is required to determine the device
|
||||
* type, the USM allocation type and the sycl context it is bound to.
|
||||
*
|
||||
*/
|
||||
kDLOneAPI = 14,
|
||||
/*! \brief GPU support for next generation WebGPU standard. */
|
||||
kDLWebGPU = 15,
|
||||
/*! \brief Qualcomm Hexagon DSP */
|
||||
kDLHexagon = 16,
|
||||
/*! \brief Microsoft MAIA devices */
|
||||
kDLMAIA = 17,
|
||||
} DLDeviceType;
|
||||
|
||||
/*!
|
||||
* \brief A Device for Tensor and operator.
|
||||
*/
|
||||
typedef struct {
|
||||
/*! \brief The device type used in the device. */
|
||||
DLDeviceType device_type;
|
||||
/*!
|
||||
* \brief The device index.
|
||||
* For vanilla CPU memory, pinned memory, or managed memory, this is set to 0.
|
||||
*/
|
||||
int32_t device_id;
|
||||
} DLDevice;
|
||||
|
||||
/*!
|
||||
* \brief The type code options DLDataType.
|
||||
*/
|
||||
typedef enum {
|
||||
/*! \brief signed integer */
|
||||
kDLInt = 0U,
|
||||
/*! \brief unsigned integer */
|
||||
kDLUInt = 1U,
|
||||
/*! \brief IEEE floating point */
|
||||
kDLFloat = 2U,
|
||||
/*!
|
||||
* \brief Opaque handle type, reserved for testing purposes.
|
||||
* Frameworks need to agree on the handle data type for the exchange to be well-defined.
|
||||
*/
|
||||
kDLOpaqueHandle = 3U,
|
||||
/*! \brief bfloat16 */
|
||||
kDLBfloat = 4U,
|
||||
/*!
|
||||
* \brief complex number
|
||||
* (C/C++/Python layout: compact struct per complex number)
|
||||
*/
|
||||
kDLComplex = 5U,
|
||||
/*! \brief boolean */
|
||||
kDLBool = 6U,
|
||||
/*! \brief FP8 data types */
|
||||
kDLFloat8_e3m4 = 7U,
|
||||
kDLFloat8_e4m3 = 8U,
|
||||
kDLFloat8_e4m3b11fnuz = 9U,
|
||||
kDLFloat8_e4m3fn = 10U,
|
||||
kDLFloat8_e4m3fnuz = 11U,
|
||||
kDLFloat8_e5m2 = 12U,
|
||||
kDLFloat8_e5m2fnuz = 13U,
|
||||
kDLFloat8_e8m0fnu = 14U,
|
||||
/*! \brief FP6 data types
|
||||
* Setting bits != 6 is currently unspecified, and the producer must ensure it is set
|
||||
* while the consumer must stop importing if the value is unexpected.
|
||||
*/
|
||||
kDLFloat6_e2m3fn = 15U,
|
||||
kDLFloat6_e3m2fn = 16U,
|
||||
/*! \brief FP4 data types
|
||||
* Setting bits != 4 is currently unspecified, and the producer must ensure it is set
|
||||
* while the consumer must stop importing if the value is unexpected.
|
||||
*/
|
||||
kDLFloat4_e2m1fn = 17U,
|
||||
} DLDataTypeCode;
|
||||
|
||||
/*!
|
||||
* \brief The data type the tensor can hold. The data type is assumed to follow the
|
||||
* native endian-ness. An explicit error message should be raised when attempting to
|
||||
* export an array with non-native endianness
|
||||
*
|
||||
* Examples
|
||||
* - float: type_code = 2, bits = 32, lanes = 1
|
||||
* - float4(vectorized 4 float): type_code = 2, bits = 32, lanes = 4
|
||||
* - int8: type_code = 0, bits = 8, lanes = 1
|
||||
* - std::complex<float>: type_code = 5, bits = 64, lanes = 1
|
||||
* - bool: type_code = 6, bits = 8, lanes = 1 (as per common array library convention, the underlying storage size of bool is 8 bits)
|
||||
* - float8_e4m3: type_code = 8, bits = 8, lanes = 1 (packed in memory)
|
||||
* - float6_e3m2fn: type_code = 16, bits = 6, lanes = 1 (packed in memory)
|
||||
* - float4_e2m1fn: type_code = 17, bits = 4, lanes = 1 (packed in memory)
|
||||
*
|
||||
* When a sub-byte type is packed, DLPack requires the data to be in little bit-endian, i.e.,
|
||||
* for a packed data set D ((D >> (i * bits)) && bit_mask) stores the i-th element.
|
||||
*/
|
||||
typedef struct {
|
||||
/*!
|
||||
* \brief Type code of base types.
|
||||
* We keep it uint8_t instead of DLDataTypeCode for minimal memory
|
||||
* footprint, but the value should be one of DLDataTypeCode enum values.
|
||||
* */
|
||||
uint8_t code;
|
||||
/*!
|
||||
* \brief Number of bits, common choices are 8, 16, 32.
|
||||
*/
|
||||
uint8_t bits;
|
||||
/*! \brief Number of lanes in the type, used for vector types. */
|
||||
uint16_t lanes;
|
||||
} DLDataType;
|
||||
|
||||
/*!
|
||||
* \brief Plain C Tensor object, does not manage memory.
|
||||
*/
|
||||
typedef struct {
|
||||
/*!
|
||||
* \brief The data pointer points to the allocated data. This will be CUDA
|
||||
* device pointer or cl_mem handle in OpenCL. It may be opaque on some device
|
||||
* types. This pointer is always aligned to 256 bytes as in CUDA. The
|
||||
* `byte_offset` field should be used to point to the beginning of the data.
|
||||
*
|
||||
* Note that as of Nov 2021, multiply libraries (CuPy, PyTorch, TensorFlow,
|
||||
* TVM, perhaps others) do not adhere to this 256 byte aligment requirement
|
||||
* on CPU/CUDA/ROCm, and always use `byte_offset=0`. This must be fixed
|
||||
* (after which this note will be updated); at the moment it is recommended
|
||||
* to not rely on the data pointer being correctly aligned.
|
||||
*
|
||||
* For given DLTensor, the size of memory required to store the contents of
|
||||
* data is calculated as follows:
|
||||
*
|
||||
* \code{.c}
|
||||
* static inline size_t GetDataSize(const DLTensor* t) {
|
||||
* size_t size = 1;
|
||||
* for (tvm_index_t i = 0; i < t->ndim; ++i) {
|
||||
* size *= t->shape[i];
|
||||
* }
|
||||
* size *= (t->dtype.bits * t->dtype.lanes + 7) / 8;
|
||||
* return size;
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* Note that if the tensor is of size zero, then the data pointer should be
|
||||
* set to `NULL`.
|
||||
*/
|
||||
void* data;
|
||||
/*! \brief The device of the tensor */
|
||||
DLDevice device;
|
||||
/*! \brief Number of dimensions */
|
||||
int32_t ndim;
|
||||
/*! \brief The data type of the pointer*/
|
||||
DLDataType dtype;
|
||||
/*! \brief The shape of the tensor */
|
||||
int64_t* shape;
|
||||
/*!
|
||||
* \brief strides of the tensor (in number of elements, not bytes)
|
||||
* can be NULL, indicating tensor is compact and row-majored.
|
||||
*/
|
||||
int64_t* strides;
|
||||
/*! \brief The offset in bytes to the beginning pointer to data */
|
||||
uint64_t byte_offset;
|
||||
} DLTensor;
|
||||
|
||||
/*!
|
||||
* \brief C Tensor object, manage memory of DLTensor. This data structure is
|
||||
* intended to facilitate the borrowing of DLTensor by another framework. It is
|
||||
* not meant to transfer the tensor. When the borrowing framework doesn't need
|
||||
* the tensor, it should call the deleter to notify the host that the resource
|
||||
* is no longer needed.
|
||||
*
|
||||
* \note This data structure is used as Legacy DLManagedTensor
|
||||
* in DLPack exchange and is deprecated after DLPack v0.8
|
||||
* Use DLManagedTensorVersioned instead.
|
||||
* This data structure may get renamed or deleted in future versions.
|
||||
*
|
||||
* \sa DLManagedTensorVersioned
|
||||
*/
|
||||
typedef struct DLManagedTensor {
|
||||
/*! \brief DLTensor which is being memory managed */
|
||||
DLTensor dl_tensor;
|
||||
/*! \brief the context of the original host framework of DLManagedTensor in
|
||||
* which DLManagedTensor is used in the framework. It can also be NULL.
|
||||
*/
|
||||
void * manager_ctx;
|
||||
/*!
|
||||
* \brief Destructor - this should be called
|
||||
* to destruct the manager_ctx which backs the DLManagedTensor. It can be
|
||||
* NULL if there is no way for the caller to provide a reasonable destructor.
|
||||
* The destructor deletes the argument self as well.
|
||||
*/
|
||||
void (*deleter)(struct DLManagedTensor * self);
|
||||
} DLManagedTensor;
|
||||
|
||||
// bit masks used in in the DLManagedTensorVersioned
|
||||
|
||||
/*! \brief bit mask to indicate that the tensor is read only. */
|
||||
#define DLPACK_FLAG_BITMASK_READ_ONLY (1UL << 0UL)
|
||||
|
||||
/*!
|
||||
* \brief bit mask to indicate that the tensor is a copy made by the producer.
|
||||
*
|
||||
* If set, the tensor is considered solely owned throughout its lifetime by the
|
||||
* consumer, until the producer-provided deleter is invoked.
|
||||
*/
|
||||
#define DLPACK_FLAG_BITMASK_IS_COPIED (1UL << 1UL)
|
||||
|
||||
/*
|
||||
* \brief bit mask to indicate that whether a sub-byte type is packed or padded.
|
||||
*
|
||||
* The default for sub-byte types (ex: fp4/fp6) is assumed packed. This flag can
|
||||
* be set by the producer to signal that a tensor of sub-byte type is padded.
|
||||
*/
|
||||
#define DLPACK_FLAG_BITMASK_IS_SUBBYTE_TYPE_PADDED (1UL << 2UL)
|
||||
|
||||
/*!
|
||||
* \brief A versioned and managed C Tensor object, manage memory of DLTensor.
|
||||
*
|
||||
* This data structure is intended to facilitate the borrowing of DLTensor by
|
||||
* another framework. It is not meant to transfer the tensor. When the borrowing
|
||||
* framework doesn't need the tensor, it should call the deleter to notify the
|
||||
* host that the resource is no longer needed.
|
||||
*
|
||||
* \note This is the current standard DLPack exchange data structure.
|
||||
*/
|
||||
struct DLManagedTensorVersioned {
|
||||
/*!
|
||||
* \brief The API and ABI version of the current managed Tensor
|
||||
*/
|
||||
DLPackVersion version;
|
||||
/*!
|
||||
* \brief the context of the original host framework.
|
||||
*
|
||||
* Stores DLManagedTensorVersioned is used in the
|
||||
* framework. It can also be NULL.
|
||||
*/
|
||||
void *manager_ctx;
|
||||
/*!
|
||||
* \brief Destructor.
|
||||
*
|
||||
* This should be called to destruct manager_ctx which holds the DLManagedTensorVersioned.
|
||||
* It can be NULL if there is no way for the caller to provide a reasonable
|
||||
* destructor. The destructor deletes the argument self as well.
|
||||
*/
|
||||
void (*deleter)(struct DLManagedTensorVersioned *self);
|
||||
/*!
|
||||
* \brief Additional bitmask flags information about the tensor.
|
||||
*
|
||||
* By default the flags should be set to 0.
|
||||
*
|
||||
* \note Future ABI changes should keep everything until this field
|
||||
* stable, to ensure that deleter can be correctly called.
|
||||
*
|
||||
* \sa DLPACK_FLAG_BITMASK_READ_ONLY
|
||||
* \sa DLPACK_FLAG_BITMASK_IS_COPIED
|
||||
*/
|
||||
uint64_t flags;
|
||||
/*! \brief DLTensor which is being memory managed */
|
||||
DLTensor dl_tensor;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // DLPACK_EXTERN_C
|
||||
#endif
|
||||
#endif // DLPACK_DLPACK_H_
|
||||
10
3rdparty/ippicv/ippicv.cmake
vendored
10
3rdparty/ippicv/ippicv.cmake
vendored
|
|
@ -2,7 +2,7 @@ function(download_ippicv root_var)
|
|||
set(${root_var} "" PARENT_SCOPE)
|
||||
|
||||
# Commit SHA in the opencv_3rdparty repo
|
||||
set(IPPICV_COMMIT "767426b2a40a011eb2fa7f44c677c13e60e205ad")
|
||||
set(IPPICV_COMMIT "c934a2a15a6df020446ac3dfa07e3acf72b63a8f")
|
||||
# Define actual ICV versions
|
||||
if(APPLE)
|
||||
set(IPPICV_COMMIT "0cc4aa06bf2bef4b05d237c69a5a96b9cd0cb85a")
|
||||
|
|
@ -14,8 +14,8 @@ function(download_ippicv root_var)
|
|||
set(OPENCV_ICV_PLATFORM "linux")
|
||||
set(OPENCV_ICV_PACKAGE_SUBDIR "ippicv_lnx")
|
||||
if(X86_64)
|
||||
set(OPENCV_ICV_NAME "ippicv_2022.1.0_lnx_intel64_20250130_general.tgz")
|
||||
set(OPENCV_ICV_HASH "98ff71fc242d52db9cc538388e502f57")
|
||||
set(OPENCV_ICV_NAME "ippicv_2022.2.0_lnx_intel64_20250730_general.tgz")
|
||||
set(OPENCV_ICV_HASH "55d18247d8ef707f009b94f69d77b948")
|
||||
else()
|
||||
if(ANDROID)
|
||||
set(IPPICV_COMMIT "c7c6d527dde5fee7cb914ee9e4e20f7436aab3a1")
|
||||
|
|
@ -31,8 +31,8 @@ function(download_ippicv root_var)
|
|||
set(OPENCV_ICV_PLATFORM "windows")
|
||||
set(OPENCV_ICV_PACKAGE_SUBDIR "ippicv_win")
|
||||
if(X86_64)
|
||||
set(OPENCV_ICV_NAME "ippicv_2022.1.0_win_intel64_20250130_general.zip")
|
||||
set(OPENCV_ICV_HASH "67a611ab22410f392239bddff6f91df7")
|
||||
set(OPENCV_ICV_NAME "ippicv_2022.2.0_win_intel64_20250730_general.zip")
|
||||
set(OPENCV_ICV_HASH "7c0973976ab0716bc33f03a76a50017f")
|
||||
else()
|
||||
set(IPPICV_COMMIT "7f55c0c26be418d494615afca15218566775c725")
|
||||
set(OPENCV_ICV_NAME "ippicv_2021.12.0_win_ia32_20240425_general.zip")
|
||||
|
|
|
|||
2
3rdparty/libtiff/CMakeLists.txt
vendored
2
3rdparty/libtiff/CMakeLists.txt
vendored
|
|
@ -358,7 +358,7 @@ if(LIBLZMA_LIBRARIES)
|
|||
endif()
|
||||
|
||||
set(LIBTIFF_MAJOR_VERSION "4")
|
||||
set(LIBTIFF_MINOR_VERSION "6")
|
||||
set(LIBTIFF_MINOR_VERSION "7")
|
||||
set(LIBTIFF_MICRO_VERSION "0")
|
||||
set(LIBTIFF_VERSION "${LIBTIFF_MAJOR_VERSION}.${LIBTIFF_MINOR_VERSION}.${LIBTIFF_MICRO_VERSION}")
|
||||
file(READ "RELEASE-DATE" LIBTIFF_RELEASE_DATE content)
|
||||
|
|
|
|||
1627
3rdparty/libtiff/ChangeLog
vendored
1627
3rdparty/libtiff/ChangeLog
vendored
File diff suppressed because it is too large
Load Diff
2
3rdparty/libtiff/RELEASE-DATE
vendored
2
3rdparty/libtiff/RELEASE-DATE
vendored
|
|
@ -1 +1 @@
|
|||
20230908
|
||||
20240911
|
||||
|
|
|
|||
47
3rdparty/libtiff/tif_aux.c
vendored
47
3rdparty/libtiff/tif_aux.c
vendored
|
|
@ -385,53 +385,6 @@ int TIFFGetFieldDefaulted(TIFF *tif, uint32_t tag, ...)
|
|||
return (ok);
|
||||
}
|
||||
|
||||
struct _Int64Parts
|
||||
{
|
||||
int32_t low, high;
|
||||
};
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct _Int64Parts part;
|
||||
int64_t value;
|
||||
} _Int64;
|
||||
|
||||
float _TIFFUInt64ToFloat(uint64_t ui64)
|
||||
{
|
||||
_Int64 i;
|
||||
|
||||
i.value = ui64;
|
||||
if (i.part.high >= 0)
|
||||
{
|
||||
return (float)i.value;
|
||||
}
|
||||
else
|
||||
{
|
||||
long double df;
|
||||
df = (long double)i.value;
|
||||
df += 18446744073709551616.0; /* adding 2**64 */
|
||||
return (float)df;
|
||||
}
|
||||
}
|
||||
|
||||
double _TIFFUInt64ToDouble(uint64_t ui64)
|
||||
{
|
||||
_Int64 i;
|
||||
|
||||
i.value = ui64;
|
||||
if (i.part.high >= 0)
|
||||
{
|
||||
return (double)i.value;
|
||||
}
|
||||
else
|
||||
{
|
||||
long double df;
|
||||
df = (long double)i.value;
|
||||
df += 18446744073709551616.0; /* adding 2**64 */
|
||||
return (double)df;
|
||||
}
|
||||
}
|
||||
|
||||
float _TIFFClampDoubleToFloat(double val)
|
||||
{
|
||||
if (val > FLT_MAX)
|
||||
|
|
|
|||
8
3rdparty/libtiff/tif_close.c
vendored
8
3rdparty/libtiff/tif_close.c
vendored
|
|
@ -110,6 +110,14 @@ void TIFFCleanup(TIFF *tif)
|
|||
_TIFFfreeExt(tif, tif->tif_fieldscompat);
|
||||
}
|
||||
|
||||
if (tif->tif_cur_cumulated_mem_alloc != 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, "TIFFCleanup",
|
||||
"tif_cur_cumulated_mem_alloc = %" PRIu64 " whereas it "
|
||||
"should be 0",
|
||||
(uint64_t)tif->tif_cur_cumulated_mem_alloc);
|
||||
}
|
||||
|
||||
_TIFFfreeExt(NULL, tif);
|
||||
}
|
||||
|
||||
|
|
|
|||
22
3rdparty/libtiff/tif_color.c
vendored
22
3rdparty/libtiff/tif_color.c
vendored
|
|
@ -89,7 +89,7 @@ void TIFFCIELab16ToXYZ(TIFFCIELabToRGB *cielab, uint32_t l, int32_t a,
|
|||
void TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z,
|
||||
uint32_t *r, uint32_t *g, uint32_t *b)
|
||||
{
|
||||
int i;
|
||||
size_t i;
|
||||
float Yr, Yg, Yb;
|
||||
float *matrix = &cielab->display.d_mat[0][0];
|
||||
|
||||
|
|
@ -109,16 +109,16 @@ void TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z,
|
|||
Yb = TIFFmin(Yb, cielab->display.d_YCB);
|
||||
|
||||
/* Turn luminosity to colour value. */
|
||||
i = (int)((Yr - cielab->display.d_Y0R) / cielab->rstep);
|
||||
i = TIFFmin(cielab->range, i);
|
||||
i = (size_t)((Yr - cielab->display.d_Y0R) / cielab->rstep);
|
||||
i = TIFFmin((size_t)cielab->range, i);
|
||||
*r = RINT(cielab->Yr2r[i]);
|
||||
|
||||
i = (int)((Yg - cielab->display.d_Y0G) / cielab->gstep);
|
||||
i = TIFFmin(cielab->range, i);
|
||||
i = (size_t)((Yg - cielab->display.d_Y0G) / cielab->gstep);
|
||||
i = TIFFmin((size_t)cielab->range, i);
|
||||
*g = RINT(cielab->Yg2g[i]);
|
||||
|
||||
i = (int)((Yb - cielab->display.d_Y0B) / cielab->bstep);
|
||||
i = TIFFmin(cielab->range, i);
|
||||
i = (size_t)((Yb - cielab->display.d_Y0B) / cielab->bstep);
|
||||
i = TIFFmin((size_t)cielab->range, i);
|
||||
*b = RINT(cielab->Yb2b[i]);
|
||||
|
||||
/* Clip output. */
|
||||
|
|
@ -135,7 +135,7 @@ void TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z,
|
|||
int TIFFCIELabToRGBInit(TIFFCIELabToRGB *cielab, const TIFFDisplay *display,
|
||||
float *refWhite)
|
||||
{
|
||||
int i;
|
||||
size_t i;
|
||||
double dfGamma;
|
||||
|
||||
cielab->range = CIELABTORGB_TABLE_RANGE;
|
||||
|
|
@ -146,7 +146,7 @@ int TIFFCIELabToRGBInit(TIFFCIELabToRGB *cielab, const TIFFDisplay *display,
|
|||
dfGamma = 1.0 / cielab->display.d_gammaR;
|
||||
cielab->rstep =
|
||||
(cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
|
||||
for (i = 0; i <= cielab->range; i++)
|
||||
for (i = 0; i <= (size_t)cielab->range; i++)
|
||||
{
|
||||
cielab->Yr2r[i] = cielab->display.d_Vrwr *
|
||||
((float)pow((double)i / cielab->range, dfGamma));
|
||||
|
|
@ -156,7 +156,7 @@ int TIFFCIELabToRGBInit(TIFFCIELabToRGB *cielab, const TIFFDisplay *display,
|
|||
dfGamma = 1.0 / cielab->display.d_gammaG;
|
||||
cielab->gstep =
|
||||
(cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
|
||||
for (i = 0; i <= cielab->range; i++)
|
||||
for (i = 0; i <= (size_t)cielab->range; i++)
|
||||
{
|
||||
cielab->Yg2g[i] = cielab->display.d_Vrwg *
|
||||
((float)pow((double)i / cielab->range, dfGamma));
|
||||
|
|
@ -166,7 +166,7 @@ int TIFFCIELabToRGBInit(TIFFCIELabToRGB *cielab, const TIFFDisplay *display,
|
|||
dfGamma = 1.0 / cielab->display.d_gammaB;
|
||||
cielab->bstep =
|
||||
(cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
|
||||
for (i = 0; i <= cielab->range; i++)
|
||||
for (i = 0; i <= (size_t)cielab->range; i++)
|
||||
{
|
||||
cielab->Yb2b[i] = cielab->display.d_Vrwb *
|
||||
((float)pow((double)i / cielab->range, dfGamma));
|
||||
|
|
|
|||
18
3rdparty/libtiff/tif_config.h.cmake.in
vendored
18
3rdparty/libtiff/tif_config.h.cmake.in
vendored
|
|
@ -40,6 +40,18 @@
|
|||
/* Define to 1 if you have the `getopt' function. */
|
||||
#cmakedefine HAVE_GETOPT 1
|
||||
|
||||
/* Define to 1 if you have the <GLUT/glut.h> header file. */
|
||||
#cmakedefine HAVE_GLUT_GLUT_H 1
|
||||
|
||||
/* Define to 1 if you have the <GL/glut.h> header file. */
|
||||
#cmakedefine HAVE_GL_GLUT_H 1
|
||||
|
||||
/* Define to 1 if you have the <GL/glu.h> header file. */
|
||||
#cmakedefine HAVE_GL_GLU_H 1
|
||||
|
||||
/* Define to 1 if you have the <GL/gl.h> header file. */
|
||||
#cmakedefine HAVE_GL_GL_H 1
|
||||
|
||||
/* Define to 1 if you have the <io.h> header file. */
|
||||
#cmakedefine HAVE_IO_H 1
|
||||
|
||||
|
|
@ -49,6 +61,12 @@
|
|||
/* Define to 1 if you have the `mmap' function. */
|
||||
#cmakedefine HAVE_MMAP 1
|
||||
|
||||
/* Define to 1 if you have the <OpenGL/glu.h> header file. */
|
||||
#cmakedefine HAVE_OPENGL_GLU_H 1
|
||||
|
||||
/* Define to 1 if you have the <OpenGL/gl.h> header file. */
|
||||
#cmakedefine HAVE_OPENGL_GL_H 1
|
||||
|
||||
/* Define to 1 if you have the `setmode' function. */
|
||||
#cmakedefine HAVE_SETMODE 1
|
||||
|
||||
|
|
|
|||
115
3rdparty/libtiff/tif_dir.c
vendored
115
3rdparty/libtiff/tif_dir.c
vendored
|
|
@ -211,7 +211,7 @@ static uint16_t countInkNamesString(TIFF *tif, uint32_t slen, const char *s)
|
|||
}
|
||||
bad:
|
||||
TIFFErrorExtR(tif, "TIFFSetField",
|
||||
"%s: Invalid InkNames value; no NUL at given buffer end "
|
||||
"%s: Invalid InkNames value; no null at given buffer end "
|
||||
"location %" PRIu32 ", after %" PRIu16 " ink",
|
||||
tif->tif_name, slen, i);
|
||||
return (0);
|
||||
|
|
@ -1652,6 +1652,17 @@ void TIFFFreeDirectory(TIFF *tif)
|
|||
|
||||
_TIFFmemset(&(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
|
||||
_TIFFmemset(&(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
|
||||
|
||||
/* Reset some internal parameters for IFD data size checking. */
|
||||
tif->tif_dir.td_dirdatasize_read = 0;
|
||||
tif->tif_dir.td_dirdatasize_write = 0;
|
||||
if (tif->tif_dir.td_dirdatasize_offsets != NULL)
|
||||
{
|
||||
_TIFFfreeExt(tif, tif->tif_dir.td_dirdatasize_offsets);
|
||||
tif->tif_dir.td_dirdatasize_offsets = NULL;
|
||||
tif->tif_dir.td_dirdatasize_Noffsets = 0;
|
||||
}
|
||||
tif->tif_dir.td_iswrittentofile = FALSE;
|
||||
}
|
||||
#undef CleanupField
|
||||
|
||||
|
|
@ -1676,18 +1687,23 @@ TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc extender)
|
|||
*/
|
||||
int TIFFCreateDirectory(TIFF *tif)
|
||||
{
|
||||
/* Free previously allocated memory and setup default values. */
|
||||
TIFFFreeDirectory(tif);
|
||||
TIFFDefaultDirectory(tif);
|
||||
tif->tif_diroff = 0;
|
||||
tif->tif_nextdiroff = 0;
|
||||
tif->tif_curoff = 0;
|
||||
tif->tif_row = (uint32_t)-1;
|
||||
tif->tif_curstrip = (uint32_t)-1;
|
||||
tif->tif_dir.td_iswrittentofile = FALSE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TIFFCreateCustomDirectory(TIFF *tif, const TIFFFieldArray *infoarray)
|
||||
{
|
||||
/* Free previously allocated memory and setup default values. */
|
||||
TIFFFreeDirectory(tif);
|
||||
TIFFDefaultDirectory(tif);
|
||||
|
||||
/*
|
||||
|
|
@ -1848,7 +1864,9 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
|
|||
if (((uint64_t)poffa != poff) || (poffb < poffa) ||
|
||||
(poffb < (tmsize_t)sizeof(uint16_t)) || (poffb > tif->tif_size))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Error fetching directory count");
|
||||
TIFFErrorExtR(tif, module,
|
||||
"%s:%d: %s: Error fetching directory count",
|
||||
__FILE__, __LINE__, tif->tif_name);
|
||||
*nextdiroff = 0;
|
||||
return (0);
|
||||
}
|
||||
|
|
@ -1877,14 +1895,18 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
|
|||
uint16_t dircount16;
|
||||
if (poff > (uint64_t)TIFF_TMSIZE_T_MAX - sizeof(uint64_t))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Error fetching directory count");
|
||||
TIFFErrorExtR(tif, module,
|
||||
"%s:%d: %s: Error fetching directory count",
|
||||
__FILE__, __LINE__, tif->tif_name);
|
||||
return (0);
|
||||
}
|
||||
poffa = (tmsize_t)poff;
|
||||
poffb = poffa + sizeof(uint64_t);
|
||||
if (poffb > tif->tif_size)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Error fetching directory count");
|
||||
TIFFErrorExtR(tif, module,
|
||||
"%s:%d: %s: Error fetching directory count",
|
||||
__FILE__, __LINE__, tif->tif_name);
|
||||
return (0);
|
||||
}
|
||||
_TIFFmemcpy(&dircount64, tif->tif_base + poffa, sizeof(uint64_t));
|
||||
|
|
@ -1926,8 +1948,9 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
|
|||
if (!SeekOK(tif, *nextdiroff) ||
|
||||
!ReadOK(tif, &dircount, sizeof(uint16_t)))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "%s: Error fetching directory count",
|
||||
tif->tif_name);
|
||||
TIFFErrorExtR(tif, module,
|
||||
"%s:%d: %s: Error fetching directory count",
|
||||
__FILE__, __LINE__, tif->tif_name);
|
||||
return (0);
|
||||
}
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
|
|
@ -1953,15 +1976,18 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
|
|||
if (!SeekOK(tif, *nextdiroff) ||
|
||||
!ReadOK(tif, &dircount64, sizeof(uint64_t)))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "%s: Error fetching directory count",
|
||||
tif->tif_name);
|
||||
TIFFErrorExtR(tif, module,
|
||||
"%s:%d: %s: Error fetching directory count",
|
||||
__FILE__, __LINE__, tif->tif_name);
|
||||
return (0);
|
||||
}
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
TIFFSwabLong8(&dircount64);
|
||||
if (dircount64 > 0xFFFF)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Error fetching directory count");
|
||||
TIFFErrorExtR(tif, module,
|
||||
"%s:%d: %s: Error fetching directory count",
|
||||
__FILE__, __LINE__, tif->tif_name);
|
||||
return (0);
|
||||
}
|
||||
dircount16 = (uint16_t)dircount64;
|
||||
|
|
@ -2018,6 +2044,8 @@ tdir_t TIFFNumberOfDirectories(TIFF *tif)
|
|||
{
|
||||
++n;
|
||||
}
|
||||
/* Update number of main-IFDs in file. */
|
||||
tif->tif_curdircount = n;
|
||||
return (n);
|
||||
}
|
||||
|
||||
|
|
@ -2100,7 +2128,19 @@ int TIFFSetDirectory(TIFF *tif, tdir_t dirn)
|
|||
tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
|
||||
else
|
||||
tif->tif_curdir--;
|
||||
return (TIFFReadDirectory(tif));
|
||||
|
||||
tdir_t curdir = tif->tif_curdir;
|
||||
|
||||
int retval = TIFFReadDirectory(tif);
|
||||
|
||||
if (!retval && tif->tif_curdir == curdir)
|
||||
{
|
||||
/* If tif_curdir has not be incremented, TIFFFetchDirectory() in
|
||||
* TIFFReadDirectory() has failed and tif_curdir shall be set
|
||||
* specifically. */
|
||||
tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
|
||||
}
|
||||
return (retval);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -2125,8 +2165,11 @@ int TIFFSetSubDirectory(TIFF *tif, uint64_t diroff)
|
|||
int8_t probablySubIFD = 0;
|
||||
if (diroff == 0)
|
||||
{
|
||||
/* Special case to invalidate the tif_lastdiroff member. */
|
||||
/* Special case to set tif_diroff=0, which is done in
|
||||
* TIFFReadDirectory() below to indicate that the currently read IFD is
|
||||
* treated as a new, fresh IFD. */
|
||||
tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
|
||||
tif->tif_dir.td_iswrittentofile = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2136,32 +2179,40 @@ int TIFFSetSubDirectory(TIFF *tif, uint64_t diroff)
|
|||
probablySubIFD = 1;
|
||||
}
|
||||
/* -1 because TIFFReadDirectory() will increment tif_curdir. */
|
||||
tif->tif_curdir =
|
||||
curdir == 0 ? TIFF_NON_EXISTENT_DIR_NUMBER : curdir - 1;
|
||||
if (curdir >= 1)
|
||||
tif->tif_curdir = curdir - 1;
|
||||
else
|
||||
tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
|
||||
}
|
||||
curdir = tif->tif_curdir;
|
||||
|
||||
tif->tif_nextdiroff = diroff;
|
||||
retval = TIFFReadDirectory(tif);
|
||||
/* If failed, curdir was not incremented in TIFFReadDirectory(), so set it
|
||||
* back, but leave it for diroff==0. */
|
||||
if (!retval && diroff != 0)
|
||||
|
||||
/* tif_curdir is incremented in TIFFReadDirectory(), but if it has not been
|
||||
* incremented, TIFFFetchDirectory() has failed there and tif_curdir shall
|
||||
* be set specifically. */
|
||||
if (!retval && diroff != 0 && tif->tif_curdir == curdir)
|
||||
{
|
||||
if (tif->tif_curdir == TIFF_NON_EXISTENT_DIR_NUMBER)
|
||||
tif->tif_curdir = 0;
|
||||
else
|
||||
tif->tif_curdir++;
|
||||
tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
|
||||
}
|
||||
if (retval && probablySubIFD)
|
||||
|
||||
if (probablySubIFD)
|
||||
{
|
||||
/* Reset IFD list to start new one for SubIFD chain and also start
|
||||
* SubIFD chain with tif_curdir=0. */
|
||||
_TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */
|
||||
tif->tif_curdir = 0; /* first directory of new chain */
|
||||
/* add this offset to new IFD list */
|
||||
_TIFFCheckDirNumberAndOffset(tif, tif->tif_curdir, diroff);
|
||||
if (retval)
|
||||
{
|
||||
/* Reset IFD list to start new one for SubIFD chain and also start
|
||||
* SubIFD chain with tif_curdir=0 for IFD loop checking. */
|
||||
/* invalidate IFD loop lists */
|
||||
_TIFFCleanupIFDOffsetAndNumberMaps(tif);
|
||||
tif->tif_curdir = 0; /* first directory of new chain */
|
||||
/* add this offset to new IFD list */
|
||||
_TIFFCheckDirNumberAndOffset(tif, tif->tif_curdir, diroff);
|
||||
}
|
||||
/* To be able to return from SubIFD or custom-IFD to main-IFD */
|
||||
tif->tif_setdirectory_force_absolute = TRUE;
|
||||
}
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
|
|
@ -2257,9 +2308,11 @@ int TIFFUnlinkDirectory(TIFF *tif, tdir_t dirn)
|
|||
}
|
||||
else
|
||||
{
|
||||
/* Need local swap because nextdir has to be used unswapped below. */
|
||||
uint64_t nextdir64 = nextdir;
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
TIFFSwabLong8(&nextdir);
|
||||
if (!WriteOK(tif, &nextdir, sizeof(uint64_t)))
|
||||
TIFFSwabLong8(&nextdir64);
|
||||
if (!WriteOK(tif, &nextdir64, sizeof(uint64_t)))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Error writing directory link");
|
||||
return (0);
|
||||
|
|
@ -2303,6 +2356,10 @@ int TIFFUnlinkDirectory(TIFF *tif, tdir_t dirn)
|
|||
tif->tif_row = (uint32_t)-1;
|
||||
tif->tif_curstrip = (uint32_t)-1;
|
||||
tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
|
||||
if (tif->tif_curdircount > 0)
|
||||
tif->tif_curdircount--;
|
||||
else
|
||||
tif->tif_curdircount = TIFF_NON_EXISTENT_DIR_NUMBER;
|
||||
_TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */
|
||||
return (1);
|
||||
}
|
||||
|
|
|
|||
36
3rdparty/libtiff/tif_dir.h
vendored
36
3rdparty/libtiff/tif_dir.h
vendored
|
|
@ -65,6 +65,12 @@ typedef struct
|
|||
tif_dirread.c */
|
||||
} TIFFDirEntry;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint64_t offset;
|
||||
uint64_t length;
|
||||
} TIFFEntryOffsetAndLength; /* auxiliary for evaluating size of IFD data */
|
||||
|
||||
/*
|
||||
* Internal format of a TIFF directory entry.
|
||||
*/
|
||||
|
|
@ -115,6 +121,9 @@ typedef struct
|
|||
#ifdef STRIPBYTECOUNTSORTED_UNUSED
|
||||
int td_stripbytecountsorted; /* is the bytecount array sorted ascending? */
|
||||
#endif
|
||||
/* Be aware that the parameters of td_stripoffset_entry and
|
||||
* td_stripbytecount_entry are swapped but tdir_offset is not
|
||||
* and has to be swapped when used. */
|
||||
TIFFDirEntry td_stripoffset_entry; /* for deferred loading */
|
||||
TIFFDirEntry td_stripbytecount_entry; /* for deferred loading */
|
||||
uint16_t td_nsubifd;
|
||||
|
|
@ -135,6 +144,24 @@ typedef struct
|
|||
|
||||
unsigned char
|
||||
td_deferstrilearraywriting; /* see TIFFDeferStrileArrayWriting() */
|
||||
|
||||
unsigned char
|
||||
td_iswrittentofile; /* indicates if current IFD is present on file */
|
||||
|
||||
/* LibTIFF writes all data that does not fit into the IFD entries directly
|
||||
* after the IFD tag entry part. When reading, only the IFD data directly
|
||||
* and continuously behind the IFD tags is taken into account for the IFD
|
||||
* data size.*/
|
||||
uint64_t td_dirdatasize_write; /* auxiliary for evaluating size of IFD data
|
||||
to be written */
|
||||
uint64_t td_dirdatasize_read; /* auxiliary for evaluating size of IFD data
|
||||
read from file */
|
||||
uint32_t td_dirdatasize_Noffsets; /* auxiliary counter for
|
||||
tif_dir.td_dirdatasize_offsets array */
|
||||
TIFFEntryOffsetAndLength
|
||||
*td_dirdatasize_offsets; /* auxiliary array for all offsets of IFD tag
|
||||
entries with data outside the IFD tag
|
||||
entries. */
|
||||
} TIFFDirectory;
|
||||
|
||||
/*
|
||||
|
|
@ -308,11 +335,10 @@ extern "C"
|
|||
TIFFDataType field_type; /* type of associated data */
|
||||
uint32_t
|
||||
field_anonymous; /* if true, this is a unknown / anonymous tag */
|
||||
TIFFSetGetFieldType
|
||||
set_field_type; /* type to be passed to TIFFSetField */
|
||||
TIFFSetGetFieldType
|
||||
get_field_type; /* type to be passed to TIFFGetField */
|
||||
unsigned short field_bit; /* bit in fieldsset bit vector */
|
||||
TIFFSetGetFieldType set_field_type; /* type to be passed to TIFFSetField
|
||||
and TIFFGetField*/
|
||||
TIFFSetGetFieldType get_field_type; /* not used */
|
||||
unsigned short field_bit; /* bit in fieldsset bit vector */
|
||||
unsigned char field_oktochange; /* if true, can change while writing */
|
||||
unsigned char field_passcount; /* if true, pass dir count on set */
|
||||
char *field_name; /* ASCII name */
|
||||
|
|
|
|||
22
3rdparty/libtiff/tif_dirinfo.c
vendored
22
3rdparty/libtiff/tif_dirinfo.c
vendored
|
|
@ -213,8 +213,6 @@ static const TIFFField tiffFields[] = {
|
|||
{TIFFTAG_CURRENTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CurrentPreProfileMatrix", NULL},
|
||||
{TIFFTAG_PERSAMPLE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "PerSample", NULL},
|
||||
#if 0
|
||||
/* TODO: revert above #if 0 for TIFF 4.6.0 */
|
||||
|
||||
/* begin DNG 1.2.0.0 tags */
|
||||
{TIFFTAG_COLORIMETRICREFERENCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ColorimetricReference", NULL},
|
||||
{TIFFTAG_CAMERACALIBRATIONSIGNATURE, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CameraCalibrationSignature", NULL},
|
||||
|
|
@ -282,9 +280,11 @@ static const TIFFField tiffFields[] = {
|
|||
{TIFFTAG_ILLUMINANTDATA2, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "IlluminantData2", NULL},
|
||||
{TIFFTAG_ILLUMINANTDATA3, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "IlluminantData3", NULL},
|
||||
/* end DNG tags */
|
||||
#endif
|
||||
/* begin TIFF/EP tags */
|
||||
{TIFFTAG_EP_CFAREPEATPATTERNDIM, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP CFARepeatPatternDim", NULL},
|
||||
{TIFFTAG_EP_CFAPATTERN, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP CFAPattern", NULL},
|
||||
#if 0
|
||||
/* TIFFTAG_EP_BATTERYLEVEL can be RATIONAL or ASCII.
|
||||
* LibTiff defines it as ASCII and converts RATIONAL to an ASCII string. */
|
||||
{TIFFTAG_EP_BATTERYLEVEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP BatteryLevel", NULL},
|
||||
|
|
@ -374,7 +374,7 @@ static const TIFFField exifFields[] = {
|
|||
{EXIFTAG_BRIGHTNESSVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BrightnessValue", NULL},
|
||||
{EXIFTAG_EXPOSUREBIASVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureBiasValue", NULL},
|
||||
{EXIFTAG_MAXAPERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MaxApertureValue", NULL},
|
||||
/*--: EXIFTAG_SUBJECTDISTANCE: LibTiff returns value of "-1" if numerator equals 4294967295 (0xFFFFFFFF) to indicate infinite distance!
|
||||
/*--: EXIFTAG_SUBJECTDISTANCE: LibTiff returns value of "-1" if numerator equals 4294967295 (0xFFFFFFFF) to indicate infinite distance!
|
||||
* However, there are two other EXIF tags where numerator indicates a special value and six other cases where the denominator indicates special values,
|
||||
* which are not treated within LibTiff!! */
|
||||
{EXIFTAG_SUBJECTDISTANCE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistance", NULL},
|
||||
|
|
@ -887,7 +887,7 @@ const TIFFField *_TIFFFindOrRegisterField(TIFF *tif, uint32_t tag,
|
|||
if (fld == NULL)
|
||||
{
|
||||
fld = _TIFFCreateAnonField(tif, tag, dt);
|
||||
if (!_TIFFMergeFields(tif, fld, 1))
|
||||
if (fld == NULL || !_TIFFMergeFields(tif, fld, 1))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -1197,12 +1197,24 @@ int TIFFMergeFieldInfo(TIFF *tif, const TIFFFieldInfo info[], uint32_t n)
|
|||
for (i = 0; i < n; i++)
|
||||
{
|
||||
tp->field_tag = info[i].field_tag;
|
||||
if (info[i].field_readcount < TIFF_VARIABLE2 ||
|
||||
info[i].field_readcount == 0 ||
|
||||
info[i].field_writecount < TIFF_VARIABLE2 ||
|
||||
info[i].field_writecount == 0)
|
||||
{
|
||||
/* The fields (field_readcount) and (field_writecount) may use the
|
||||
* values TIFF_VARIABLE (-1), TIFF_SPP (-2), TIFF_VARIABLE2 (-3). */
|
||||
TIFFErrorExtR(tif, module,
|
||||
"The value of field_readcount and field_writecount "
|
||||
"must be greater than or equal to -3 and not zero.");
|
||||
return -1;
|
||||
}
|
||||
tp->field_readcount = info[i].field_readcount;
|
||||
tp->field_writecount = info[i].field_writecount;
|
||||
tp->field_type = info[i].field_type;
|
||||
tp->field_anonymous = 0;
|
||||
tp->set_field_type =
|
||||
_TIFFSetGetType(info[i].field_type, info[i].field_readcount,
|
||||
_TIFFSetGetType(info[i].field_type, info[i].field_writecount,
|
||||
info[i].field_passcount);
|
||||
tp->get_field_type =
|
||||
_TIFFSetGetType(info[i].field_type, info[i].field_readcount,
|
||||
|
|
|
|||
703
3rdparty/libtiff/tif_dirread.c
vendored
703
3rdparty/libtiff/tif_dirread.c
vendored
File diff suppressed because it is too large
Load Diff
561
3rdparty/libtiff/tif_dirwrite.c
vendored
561
3rdparty/libtiff/tif_dirwrite.c
vendored
File diff suppressed because it is too large
Load Diff
58
3rdparty/libtiff/tif_fax3.c
vendored
58
3rdparty/libtiff/tif_fax3.c
vendored
|
|
@ -41,6 +41,14 @@
|
|||
#include "t4.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef EOF_REACHED_COUNT_THRESHOLD
|
||||
/* Arbitrary threshold to avoid corrupted single-strip files with extremely
|
||||
* large imageheight to cause apparently endless looping, such as in
|
||||
* https://gitlab.com/libtiff/libtiff/-/issues/583
|
||||
*/
|
||||
#define EOF_REACHED_COUNT_THRESHOLD 8192
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Compression+decompression state blocks are
|
||||
* derived from this ``base state'' block.
|
||||
|
|
@ -77,6 +85,8 @@ typedef struct
|
|||
uint32_t data; /* current i/o byte/word */
|
||||
int bit; /* current i/o bit in byte */
|
||||
int EOLcnt; /* count of EOL codes recognized */
|
||||
int eofReachedCount; /* number of times decode has been called with
|
||||
EOF already reached */
|
||||
TIFFFaxFillFunc fill; /* fill routine */
|
||||
uint32_t *runs; /* b&w runs for current/previous row */
|
||||
uint32_t nruns; /* size of the refruns / curruns arrays */
|
||||
|
|
@ -120,6 +130,7 @@ typedef struct
|
|||
int EOLcnt; /* # EOL codes recognized */ \
|
||||
const unsigned char *bitmap = sp->bitmap; /* input data bit reverser */ \
|
||||
const TIFFFaxTabEnt *TabEnt
|
||||
|
||||
#define DECLARE_STATE_2D(tif, sp, mod) \
|
||||
DECLARE_STATE(tif, sp, mod); \
|
||||
int b1; /* next change on prev line */ \
|
||||
|
|
@ -162,6 +173,7 @@ static int Fax3PreDecode(TIFF *tif, uint16_t s)
|
|||
sp->bit = 0; /* force initial read */
|
||||
sp->data = 0;
|
||||
sp->EOLcnt = 0; /* force initial scan for EOL */
|
||||
sp->eofReachedCount = 0;
|
||||
/*
|
||||
* Decoder assumes lsb-to-msb bit order. Note that we select
|
||||
* this here rather than in Fax3SetupState so that viewers can
|
||||
|
|
@ -232,7 +244,12 @@ static void Fax3PrematureEOF(const char *module, TIFF *tif, uint32_t line,
|
|||
line, isTiled(tif) ? "tile" : "strip",
|
||||
(isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0);
|
||||
}
|
||||
#define prematureEOF(a0) Fax3PrematureEOF(module, tif, sp->line, a0)
|
||||
#define prematureEOF(a0) \
|
||||
do \
|
||||
{ \
|
||||
Fax3PrematureEOF(module, tif, sp->line, a0); \
|
||||
++sp->eofReachedCount; \
|
||||
} while (0)
|
||||
|
||||
#define Nop
|
||||
|
||||
|
|
@ -252,6 +269,14 @@ static int Fax3Decode1D(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
|
|||
TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
|
||||
return (-1);
|
||||
}
|
||||
if (sp->eofReachedCount >= EOF_REACHED_COUNT_THRESHOLD)
|
||||
{
|
||||
TIFFErrorExtR(
|
||||
tif, module,
|
||||
"End of file has already been reached %d times within that strip",
|
||||
sp->eofReachedCount);
|
||||
return (-1);
|
||||
}
|
||||
CACHE_STATE(tif, sp);
|
||||
thisrun = sp->curruns;
|
||||
while (occ > 0)
|
||||
|
|
@ -302,6 +327,14 @@ static int Fax3Decode2D(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
|
|||
TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
|
||||
return (-1);
|
||||
}
|
||||
if (sp->eofReachedCount >= EOF_REACHED_COUNT_THRESHOLD)
|
||||
{
|
||||
TIFFErrorExtR(
|
||||
tif, module,
|
||||
"End of file has already been reached %d times within that strip",
|
||||
sp->eofReachedCount);
|
||||
return (-1);
|
||||
}
|
||||
CACHE_STATE(tif, sp);
|
||||
while (occ > 0)
|
||||
{
|
||||
|
|
@ -536,7 +569,11 @@ static int Fax3SetupState(TIFF *tif)
|
|||
|
||||
TIFFroundup and TIFFSafeMultiply return zero on integer overflow
|
||||
*/
|
||||
dsp->runs = (uint32_t *)NULL;
|
||||
if (dsp->runs != NULL)
|
||||
{
|
||||
_TIFFfreeExt(tif, dsp->runs);
|
||||
dsp->runs = (uint32_t *)NULL;
|
||||
}
|
||||
dsp->nruns = TIFFroundup_32(rowpixels + 1, 32);
|
||||
if (needsRefLine)
|
||||
{
|
||||
|
|
@ -578,6 +615,10 @@ static int Fax3SetupState(TIFF *tif)
|
|||
* is referenced. The reference line must
|
||||
* be initialized to be ``white'' (done elsewhere).
|
||||
*/
|
||||
if (esp->refline != NULL)
|
||||
{
|
||||
_TIFFfreeExt(tif, esp->refline);
|
||||
}
|
||||
esp->refline = (unsigned char *)_TIFFmallocExt(tif, rowbytes);
|
||||
if (esp->refline == NULL)
|
||||
{
|
||||
|
|
@ -1514,7 +1555,16 @@ static int Fax4Decode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
|
|||
TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
|
||||
return (-1);
|
||||
}
|
||||
if (sp->eofReachedCount >= EOF_REACHED_COUNT_THRESHOLD)
|
||||
{
|
||||
TIFFErrorExtR(
|
||||
tif, module,
|
||||
"End of file has already been reached %d times within that strip",
|
||||
sp->eofReachedCount);
|
||||
return (-1);
|
||||
}
|
||||
CACHE_STATE(tif, sp);
|
||||
int start = sp->line;
|
||||
while (occ > 0)
|
||||
{
|
||||
a0 = 0;
|
||||
|
|
@ -1563,7 +1613,9 @@ static int Fax4Decode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
|
|||
}
|
||||
(*sp->fill)(buf, thisrun, pa, lastx);
|
||||
UNCACHE_STATE(tif, sp);
|
||||
return (sp->line ? 1 : -1); /* don't error on badly-terminated strips */
|
||||
return (sp->line != start
|
||||
? 1
|
||||
: -1); /* don't error on badly-terminated strips */
|
||||
}
|
||||
UNCACHE_STATE(tif, sp);
|
||||
return (1);
|
||||
|
|
|
|||
52
3rdparty/libtiff/tif_getimage.c
vendored
52
3rdparty/libtiff/tif_getimage.c
vendored
|
|
@ -760,6 +760,12 @@ static int gtTileContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
|
|||
toskew = -(int32_t)(tw - w);
|
||||
}
|
||||
|
||||
if (tw == 0 || th == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, TIFFFileName(tif), "tile width or height is zero");
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Leftmost tile is clipped on left side if col_offset > 0.
|
||||
*/
|
||||
|
|
@ -916,6 +922,12 @@ static int gtTileSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
|
|||
break;
|
||||
}
|
||||
|
||||
if (tw == 0 || th == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, TIFFFileName(tif), "tile width or height is zero");
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Leftmost tile is clipped on left side if col_offset > 0.
|
||||
*/
|
||||
|
|
@ -1092,6 +1104,11 @@ static int gtStripContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
|
|||
}
|
||||
|
||||
TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
|
||||
if (rowsperstrip == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, TIFFFileName(tif), "rowsperstrip is zero");
|
||||
return (0);
|
||||
}
|
||||
|
||||
scanline = TIFFScanlineSize(tif);
|
||||
fromskew = (w < imagewidth ? imagewidth - w : 0);
|
||||
|
|
@ -1216,6 +1233,12 @@ static int gtStripSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
|
|||
}
|
||||
|
||||
TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
|
||||
if (rowsperstrip == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, TIFFFileName(tif), "rowsperstrip is zero");
|
||||
return (0);
|
||||
}
|
||||
|
||||
scanline = TIFFScanlineSize(tif);
|
||||
fromskew = (w < imagewidth ? imagewidth - w : 0);
|
||||
for (row = 0; row < h; row += nrow)
|
||||
|
|
@ -3213,6 +3236,13 @@ int TIFFReadRGBAStripExt(TIFF *tif, uint32_t row, uint32_t *raster,
|
|||
}
|
||||
|
||||
TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
|
||||
|
||||
if (rowsperstrip == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, TIFFFileName(tif), "rowsperstrip is zero");
|
||||
return (0);
|
||||
}
|
||||
|
||||
if ((row % rowsperstrip) != 0)
|
||||
{
|
||||
TIFFErrorExtR(
|
||||
|
|
@ -3224,6 +3254,13 @@ int TIFFReadRGBAStripExt(TIFF *tif, uint32_t row, uint32_t *raster,
|
|||
if (TIFFRGBAImageOK(tif, emsg) &&
|
||||
TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg))
|
||||
{
|
||||
if (row >= img.height)
|
||||
{
|
||||
TIFFErrorExtR(tif, TIFFFileName(tif),
|
||||
"Invalid row passed to TIFFReadRGBAStrip().");
|
||||
TIFFRGBAImageEnd(&img);
|
||||
return (0);
|
||||
}
|
||||
|
||||
img.row_offset = row;
|
||||
img.col_offset = 0;
|
||||
|
|
@ -3282,6 +3319,13 @@ int TIFFReadRGBATileExt(TIFF *tif, uint32_t col, uint32_t row, uint32_t *raster,
|
|||
|
||||
TIFFGetFieldDefaulted(tif, TIFFTAG_TILEWIDTH, &tile_xsize);
|
||||
TIFFGetFieldDefaulted(tif, TIFFTAG_TILELENGTH, &tile_ysize);
|
||||
if (tile_xsize == 0 || tile_ysize == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, TIFFFileName(tif),
|
||||
"tile_xsize or tile_ysize is zero");
|
||||
return (0);
|
||||
}
|
||||
|
||||
if ((col % tile_xsize) != 0 || (row % tile_ysize) != 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, TIFFFileName(tif),
|
||||
|
|
@ -3301,6 +3345,14 @@ int TIFFReadRGBATileExt(TIFF *tif, uint32_t col, uint32_t row, uint32_t *raster,
|
|||
return (0);
|
||||
}
|
||||
|
||||
if (col >= img.width || row >= img.height)
|
||||
{
|
||||
TIFFErrorExtR(tif, TIFFFileName(tif),
|
||||
"Invalid row/col passed to TIFFReadRGBATile().");
|
||||
TIFFRGBAImageEnd(&img);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* The TIFFRGBAImageGet() function doesn't allow us to get off the
|
||||
* edge of the image, even to fill an otherwise valid tile. So we
|
||||
|
|
|
|||
2
3rdparty/libtiff/tif_jbig.c
vendored
2
3rdparty/libtiff/tif_jbig.c
vendored
|
|
@ -92,6 +92,7 @@ static int JBIGDecode(TIFF *tif, uint8_t *buffer, tmsize_t size, uint16_t s)
|
|||
jbg_strerror(decodeStatus)
|
||||
#endif
|
||||
);
|
||||
memset(buffer, 0, (size_t)size);
|
||||
jbg_dec_free(&decoder);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -99,6 +100,7 @@ static int JBIGDecode(TIFF *tif, uint8_t *buffer, tmsize_t size, uint16_t s)
|
|||
decodedSize = jbg_dec_getsize(&decoder);
|
||||
if ((tmsize_t)decodedSize < size)
|
||||
{
|
||||
memset(buffer + decodedSize, 0, (size_t)(size - decodedSize));
|
||||
TIFFWarningExtR(tif, "JBIG",
|
||||
"Only decoded %lu bytes, whereas %" TIFF_SSIZE_FORMAT
|
||||
" requested",
|
||||
|
|
|
|||
78
3rdparty/libtiff/tif_jpeg.c
vendored
78
3rdparty/libtiff/tif_jpeg.c
vendored
|
|
@ -73,43 +73,6 @@ int TIFFReInitJPEG_12(TIFF *tif, const JPEGOtherSettings *otherSettings,
|
|||
int scheme, int is_encode);
|
||||
int TIFFJPEGIsFullStripRequired_12(TIFF *tif);
|
||||
|
||||
/* We undefine FAR to avoid conflict with JPEG definition */
|
||||
|
||||
#ifdef FAR
|
||||
#undef FAR
|
||||
#endif
|
||||
|
||||
/*
|
||||
Libjpeg's jmorecfg.h defines INT16 and INT32, but only if XMD_H is
|
||||
not defined. Unfortunately, the MinGW and Borland compilers include
|
||||
a typedef for INT32, which causes a conflict. MSVC does not include
|
||||
a conflicting typedef given the headers which are included.
|
||||
*/
|
||||
#if defined(__BORLANDC__) || defined(__MINGW32__)
|
||||
#define XMD_H 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
The windows RPCNDR.H file defines boolean, but defines it with the
|
||||
unsigned char size. You should compile JPEG library using appropriate
|
||||
definitions in jconfig.h header, but many users compile library in wrong
|
||||
way. That causes errors of the following type:
|
||||
|
||||
"JPEGLib: JPEG parameter struct mismatch: library thinks size is 432,
|
||||
caller expects 464"
|
||||
|
||||
For such users we will fix the problem here. See install.doc file from
|
||||
the JPEG library distribution for details.
|
||||
*/
|
||||
|
||||
/* Define "boolean" as unsigned char, not int, per Windows custom. */
|
||||
#if defined(__WIN32__) && !defined(__MINGW32__)
|
||||
#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
|
||||
typedef unsigned char boolean;
|
||||
#endif
|
||||
#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
|
||||
#endif
|
||||
|
||||
#include "jerror.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
|
@ -125,18 +88,18 @@ typedef unsigned char boolean;
|
|||
* 16bit value?
|
||||
*/
|
||||
|
||||
/* HAVE_JPEGTURBO_DUAL_MODE_8_12 is defined for libjpeg-turbo >= 2.2 which
|
||||
/* HAVE_JPEGTURBO_DUAL_MODE_8_12 is defined for libjpeg-turbo >= 3.0 which
|
||||
* adds a dual-mode 8/12 bit API in the same library.
|
||||
*/
|
||||
|
||||
#if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12)
|
||||
#define JPEG_DUAL_MODE_8_12
|
||||
/* Start by undefining BITS_IN_JSAMPLE which is always set to 8 in libjpeg-turbo
|
||||
* >= 2.2 Cf
|
||||
* >= 3.0 Cf
|
||||
* https://github.com/libjpeg-turbo/libjpeg-turbo/commit/8b9bc4b9635a2a047fb23ebe70c9acd728d3f99b
|
||||
*/
|
||||
#undef BITS_IN_JSAMPLE
|
||||
/* libjpeg-turbo >= 2.2 adds J12xxxx datatypes for the 12-bit mode. */
|
||||
/* libjpeg-turbo >= 3.0 adds J12xxxx datatypes for the 12-bit mode. */
|
||||
#if defined(FROM_TIF_JPEG_12)
|
||||
#define BITS_IN_JSAMPLE 12
|
||||
#define TIFF_JSAMPLE J12SAMPLE
|
||||
|
|
@ -182,9 +145,20 @@ typedef unsigned char boolean;
|
|||
#define LONGJMP(jbuf, code) longjmp(jbuf, code)
|
||||
#define JMP_BUF jmp_buf
|
||||
|
||||
#ifndef TIFF_jpeg_destination_mgr_defined
|
||||
#define TIFF_jpeg_destination_mgr_defined
|
||||
typedef struct jpeg_destination_mgr jpeg_destination_mgr;
|
||||
#endif
|
||||
|
||||
#ifndef TIFF_jpeg_source_mgr_defined
|
||||
#define TIFF_jpeg_source_mgr_defined
|
||||
typedef struct jpeg_source_mgr jpeg_source_mgr;
|
||||
#endif
|
||||
|
||||
#ifndef TIFF_jpeg_error_mgr_defined
|
||||
#define TIFF_jpeg_error_mgr_defined
|
||||
typedef struct jpeg_error_mgr jpeg_error_mgr;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* State block for each open TIFF file using
|
||||
|
|
@ -1241,6 +1215,12 @@ int TIFFJPEGIsFullStripRequired(TIFF *tif)
|
|||
* For PC 2, scale down the expected strip/tile size
|
||||
* to match a downsampled component
|
||||
*/
|
||||
if (sp->h_sampling == 0 || sp->v_sampling == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"JPEG horizontal or vertical sampling is zero");
|
||||
return (0);
|
||||
}
|
||||
segment_width = TIFFhowmany_32(segment_width, sp->h_sampling);
|
||||
segment_height = TIFFhowmany_32(segment_height, sp->v_sampling);
|
||||
}
|
||||
|
|
@ -1471,7 +1451,10 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
|||
sp->src.bytes_in_buffer = (size_t)tif->tif_rawcc;
|
||||
|
||||
if (sp->bytesperline == 0)
|
||||
{
|
||||
memset(buf, 0, (size_t)cc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
nrows = cc / sp->bytesperline;
|
||||
if (cc % sp->bytesperline)
|
||||
|
|
@ -1492,7 +1475,10 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
|||
JSAMPROW bufptr = (JSAMPROW)buf;
|
||||
|
||||
if (TIFFjpeg_read_scanlines(sp, &bufptr, 1) != 1)
|
||||
{
|
||||
memset(buf, 0, (size_t)cc);
|
||||
return (0);
|
||||
}
|
||||
|
||||
++tif->tif_row;
|
||||
buf += sp->bytesperline;
|
||||
|
|
@ -1526,7 +1512,10 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
|||
sp->src.bytes_in_buffer = (size_t)tif->tif_rawcc;
|
||||
|
||||
if (sp->bytesperline == 0)
|
||||
{
|
||||
memset(buf, 0, (size_t)cc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
nrows = cc / sp->bytesperline;
|
||||
if (cc % sp->bytesperline)
|
||||
|
|
@ -1562,7 +1551,10 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
|||
* for 12bit data, which we need to repack.
|
||||
*/
|
||||
if (TIFFjpeg_read_scanlines(sp, &line_work_buf, 1) != 1)
|
||||
{
|
||||
memset(buf, 0, (size_t)cc);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (sp->cinfo.d.data_precision == 12)
|
||||
{
|
||||
|
|
@ -2190,6 +2182,12 @@ static int JPEGPreEncode(TIFF *tif, uint16_t s)
|
|||
/* for PC 2, scale down the strip/tile size
|
||||
* to match a downsampled component
|
||||
*/
|
||||
if (sp->h_sampling == 0 || sp->v_sampling == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"JPEG horizontal or vertical sampling is zero");
|
||||
return (0);
|
||||
}
|
||||
segment_width = TIFFhowmany_32(segment_width, sp->h_sampling);
|
||||
segment_height = TIFFhowmany_32(segment_height, sp->v_sampling);
|
||||
}
|
||||
|
|
|
|||
549
3rdparty/libtiff/tif_lerc.c
vendored
549
3rdparty/libtiff/tif_lerc.c
vendored
|
|
@ -71,6 +71,9 @@ typedef struct
|
|||
uint8_t *uncompressed_buffer;
|
||||
unsigned int uncompressed_offset;
|
||||
|
||||
uint8_t *uncompressed_buffer_multiband;
|
||||
unsigned int uncompressed_buffer_multiband_alloc;
|
||||
|
||||
unsigned int mask_size;
|
||||
uint8_t *mask_buffer;
|
||||
|
||||
|
|
@ -86,9 +89,9 @@ typedef struct
|
|||
TIFFVSetMethod vsetparent; /* super-class method */
|
||||
} LERCState;
|
||||
|
||||
#define LState(tif) ((LERCState *)(tif)->tif_data)
|
||||
#define DecoderState(tif) LState(tif)
|
||||
#define EncoderState(tif) LState(tif)
|
||||
#define GetLERCState(tif) ((LERCState *)(tif)->tif_data)
|
||||
#define LERCDecoderState(tif) GetLERCState(tif)
|
||||
#define LERCEncoderState(tif) GetLERCState(tif)
|
||||
|
||||
static int LERCEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s);
|
||||
static int LERCDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s);
|
||||
|
|
@ -101,7 +104,7 @@ static int LERCFixupTags(TIFF *tif)
|
|||
|
||||
static int LERCSetupDecode(TIFF *tif)
|
||||
{
|
||||
LERCState *sp = DecoderState(tif);
|
||||
LERCState *sp = LERCDecoderState(tif);
|
||||
|
||||
assert(sp != NULL);
|
||||
|
||||
|
|
@ -168,7 +171,7 @@ static int GetLercDataType(TIFF *tif)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int SetupUncompressedBuffer(TIFF *tif, LERCState *sp, const char *module)
|
||||
static int SetupBuffers(TIFF *tif, LERCState *sp, const char *module)
|
||||
{
|
||||
TIFFDirectory *td = &tif->tif_dir;
|
||||
uint64_t new_size_64;
|
||||
|
|
@ -202,8 +205,9 @@ static int SetupUncompressedBuffer(TIFF *tif, LERCState *sp, const char *module)
|
|||
sp->uncompressed_size = new_size;
|
||||
|
||||
/* add some margin as we are going to use it also to store deflate/zstd
|
||||
* compressed data */
|
||||
new_alloc_64 = 100 + new_size_64 + new_size_64 / 3;
|
||||
* compressed data. We also need extra margin when writing very small
|
||||
* rasters with one mask per band. */
|
||||
new_alloc_64 = 256 + new_size_64 + new_size_64 / 3;
|
||||
#ifdef ZSTD_SUPPORT
|
||||
{
|
||||
size_t zstd_max = ZSTD_compressBound((size_t)new_size_64);
|
||||
|
|
@ -243,11 +247,17 @@ static int SetupUncompressedBuffer(TIFF *tif, LERCState *sp, const char *module)
|
|||
td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA &&
|
||||
GetLercDataType(tif) == 1) ||
|
||||
(td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
|
||||
(td->td_planarconfig == PLANARCONFIG_SEPARATE ||
|
||||
td->td_samplesperpixel == 1) &&
|
||||
(td->td_bitspersample == 32 || td->td_bitspersample == 64)))
|
||||
{
|
||||
unsigned int mask_size = sp->segment_width * sp->segment_height;
|
||||
#if LERC_AT_LEAST_VERSION(3, 0, 0)
|
||||
if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
|
||||
td->td_planarconfig == PLANARCONFIG_CONTIG)
|
||||
{
|
||||
/* We may need one mask per band */
|
||||
mask_size *= td->td_samplesperpixel;
|
||||
}
|
||||
#endif
|
||||
if (sp->mask_size < mask_size)
|
||||
{
|
||||
void *mask_buffer =
|
||||
|
|
@ -277,9 +287,9 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
|
|||
static const char module[] = "LERCPreDecode";
|
||||
lerc_status lerc_ret;
|
||||
TIFFDirectory *td = &tif->tif_dir;
|
||||
LERCState *sp = DecoderState(tif);
|
||||
LERCState *sp = LERCDecoderState(tif);
|
||||
int lerc_data_type;
|
||||
unsigned int infoArray[8];
|
||||
unsigned int infoArray[9];
|
||||
unsigned nomask_bands = td->td_samplesperpixel;
|
||||
int ndims;
|
||||
int use_mask = 0;
|
||||
|
|
@ -295,7 +305,7 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
|
|||
if (lerc_data_type < 0)
|
||||
return 0;
|
||||
|
||||
if (!SetupUncompressedBuffer(tif, sp, module))
|
||||
if (!SetupBuffers(tif, sp, module))
|
||||
return 0;
|
||||
|
||||
if (sp->additional_compression != LERC_ADD_COMPRESSION_NONE)
|
||||
|
|
@ -400,7 +410,7 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
|
|||
}
|
||||
|
||||
lerc_ret =
|
||||
lerc_getBlobInfo(lerc_data, lerc_data_size, infoArray, NULL, 8, 0);
|
||||
lerc_getBlobInfo(lerc_data, lerc_data_size, infoArray, NULL, 9, 0);
|
||||
if (lerc_ret != 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "lerc_getBlobInfo() failed");
|
||||
|
|
@ -418,18 +428,16 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
|
|||
use_mask = 1;
|
||||
nomask_bands--;
|
||||
}
|
||||
else if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
|
||||
(td->td_planarconfig == PLANARCONFIG_SEPARATE ||
|
||||
td->td_samplesperpixel == 1) &&
|
||||
(td->td_bitspersample == 32 || td->td_bitspersample == 64))
|
||||
else if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP)
|
||||
{
|
||||
use_mask = 1;
|
||||
}
|
||||
|
||||
ndims = td->td_planarconfig == PLANARCONFIG_CONTIG ? nomask_bands : 1;
|
||||
|
||||
/* Info returned in infoArray is { version, dataType, nDim, nCols,
|
||||
nRows, nBands, nValidPixels, blobSize } */
|
||||
/* Info returned in infoArray is { version, dataType, nDim/nDepth, nCols,
|
||||
nRows, nBands, nValidPixels, blobSize,
|
||||
and starting with liblerc 3.0 nRequestedMasks } */
|
||||
if (infoArray[0] != (unsigned)sp->lerc_version)
|
||||
{
|
||||
TIFFWarningExtR(tif, module,
|
||||
|
|
@ -442,12 +450,29 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
|
|||
infoArray[1], lerc_data_type);
|
||||
return 0;
|
||||
}
|
||||
if (infoArray[2] != (unsigned)ndims)
|
||||
|
||||
const unsigned nFoundDims = infoArray[2];
|
||||
#if LERC_AT_LEAST_VERSION(3, 0, 0)
|
||||
if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
|
||||
td->td_planarconfig == PLANARCONFIG_CONTIG &&
|
||||
td->td_samplesperpixel > 1)
|
||||
{
|
||||
if (nFoundDims != 1 && nFoundDims != (unsigned)ndims)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Unexpected nDim: %d. Expected: 1 or %d",
|
||||
nFoundDims, ndims);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (nFoundDims != (unsigned)ndims)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Unexpected nDim: %d. Expected: %d",
|
||||
infoArray[2], ndims);
|
||||
nFoundDims, ndims);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (infoArray[3] != sp->segment_width)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Unexpected nCols: %d. Expected: %du",
|
||||
|
|
@ -460,12 +485,38 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
|
|||
infoArray[4], sp->segment_height);
|
||||
return 0;
|
||||
}
|
||||
if (infoArray[5] != 1)
|
||||
|
||||
const unsigned nFoundBands = infoArray[5];
|
||||
if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
|
||||
td->td_planarconfig == PLANARCONFIG_CONTIG &&
|
||||
td->td_samplesperpixel > 1 && nFoundDims == 1)
|
||||
{
|
||||
#if !LERC_AT_LEAST_VERSION(3, 0, 0)
|
||||
if (nFoundBands == td->td_samplesperpixel)
|
||||
{
|
||||
TIFFErrorExtR(
|
||||
tif, module,
|
||||
"Unexpected nBands: %d. This file may have been generated with "
|
||||
"a liblerc version >= 3.0, with one mask per band, and is not "
|
||||
"supported by this older version of liblerc",
|
||||
nFoundBands);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if (nFoundBands != td->td_samplesperpixel)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Unexpected nBands: %d. Expected: %d",
|
||||
nFoundBands, td->td_samplesperpixel);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (nFoundBands != 1)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Unexpected nBands: %d. Expected: %d",
|
||||
infoArray[5], 1);
|
||||
nFoundBands, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (infoArray[7] != lerc_data_size)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Unexpected blobSize: %d. Expected: %u",
|
||||
|
|
@ -473,13 +524,75 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
|
|||
return 0;
|
||||
}
|
||||
|
||||
lerc_ret = lerc_decode(lerc_data, lerc_data_size,
|
||||
int nRequestedMasks = use_mask ? 1 : 0;
|
||||
#if LERC_AT_LEAST_VERSION(3, 0, 0)
|
||||
use_mask ? 1 : 0,
|
||||
const int nFoundMasks = infoArray[8];
|
||||
if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
|
||||
td->td_planarconfig == PLANARCONFIG_CONTIG &&
|
||||
td->td_samplesperpixel > 1 && nFoundDims == 1)
|
||||
{
|
||||
if (nFoundMasks != 0 && nFoundMasks != td->td_samplesperpixel)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Unexpected nFoundMasks: %d. Expected: 0 or %d",
|
||||
nFoundMasks, td->td_samplesperpixel);
|
||||
return 0;
|
||||
}
|
||||
nRequestedMasks = nFoundMasks;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nFoundMasks != 0 && nFoundMasks != 1)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Unexpected nFoundMasks: %d. Expected: 0 or 1",
|
||||
nFoundMasks);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP && nFoundMasks == 0)
|
||||
{
|
||||
nRequestedMasks = 0;
|
||||
use_mask = 0;
|
||||
}
|
||||
#endif
|
||||
use_mask ? sp->mask_buffer : NULL, ndims,
|
||||
sp->segment_width, sp->segment_height, 1,
|
||||
lerc_data_type, sp->uncompressed_buffer);
|
||||
|
||||
const unsigned nb_pixels = sp->segment_width * sp->segment_height;
|
||||
|
||||
#if LERC_AT_LEAST_VERSION(3, 0, 0)
|
||||
if (nRequestedMasks > 1)
|
||||
{
|
||||
unsigned int num_bytes_needed =
|
||||
nb_pixels * td->td_samplesperpixel * (td->td_bitspersample / 8);
|
||||
if (sp->uncompressed_buffer_multiband_alloc < num_bytes_needed)
|
||||
{
|
||||
_TIFFfreeExt(tif, sp->uncompressed_buffer_multiband);
|
||||
sp->uncompressed_buffer_multiband =
|
||||
_TIFFmallocExt(tif, num_bytes_needed);
|
||||
if (!sp->uncompressed_buffer_multiband)
|
||||
{
|
||||
sp->uncompressed_buffer_multiband_alloc = 0;
|
||||
return 0;
|
||||
}
|
||||
sp->uncompressed_buffer_multiband_alloc = num_bytes_needed;
|
||||
}
|
||||
lerc_ret = lerc_decode(lerc_data, lerc_data_size, nRequestedMasks,
|
||||
sp->mask_buffer, nFoundDims, sp->segment_width,
|
||||
sp->segment_height, nFoundBands, lerc_data_type,
|
||||
sp->uncompressed_buffer_multiband);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
lerc_ret =
|
||||
lerc_decode(lerc_data, lerc_data_size,
|
||||
#if LERC_AT_LEAST_VERSION(3, 0, 0)
|
||||
nRequestedMasks,
|
||||
#endif
|
||||
use_mask ? sp->mask_buffer : NULL, nFoundDims,
|
||||
sp->segment_width, sp->segment_height, nFoundBands,
|
||||
lerc_data_type, sp->uncompressed_buffer);
|
||||
}
|
||||
if (lerc_ret != 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "lerc_decode() failed");
|
||||
|
|
@ -515,7 +628,6 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
|
|||
}
|
||||
else if (use_mask && td->td_sampleformat == SAMPLEFORMAT_IEEEFP)
|
||||
{
|
||||
const unsigned nb_pixels = sp->segment_width * sp->segment_height;
|
||||
unsigned i;
|
||||
#if WORDS_BIGENDIAN
|
||||
const unsigned char nan_bytes[] = {0x7f, 0xc0, 0, 0};
|
||||
|
|
@ -525,23 +637,104 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
|
|||
float nan_float32;
|
||||
memcpy(&nan_float32, nan_bytes, 4);
|
||||
|
||||
if (td->td_bitspersample == 32)
|
||||
if (td->td_planarconfig == PLANARCONFIG_SEPARATE ||
|
||||
td->td_samplesperpixel == 1)
|
||||
{
|
||||
for (i = 0; i < nb_pixels; i++)
|
||||
if (td->td_bitspersample == 32)
|
||||
{
|
||||
if (sp->mask_buffer[i] == 0)
|
||||
((float *)sp->uncompressed_buffer)[i] = nan_float32;
|
||||
for (i = 0; i < nb_pixels; i++)
|
||||
{
|
||||
if (sp->mask_buffer[i] == 0)
|
||||
((float *)sp->uncompressed_buffer)[i] = nan_float32;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const double nan_float64 = nan_float32;
|
||||
for (i = 0; i < nb_pixels; i++)
|
||||
{
|
||||
if (sp->mask_buffer[i] == 0)
|
||||
((double *)sp->uncompressed_buffer)[i] = nan_float64;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (nRequestedMasks == 1)
|
||||
{
|
||||
assert(nFoundDims == td->td_samplesperpixel);
|
||||
assert(nFoundBands == 1);
|
||||
|
||||
unsigned k = 0;
|
||||
if (td->td_bitspersample == 32)
|
||||
{
|
||||
for (i = 0; i < nb_pixels; i++)
|
||||
{
|
||||
for (int j = 0; j < td->td_samplesperpixel; j++)
|
||||
{
|
||||
if (sp->mask_buffer[i] == 0)
|
||||
((float *)sp->uncompressed_buffer)[k] = nan_float32;
|
||||
++k;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const double nan_float64 = nan_float32;
|
||||
for (i = 0; i < nb_pixels; i++)
|
||||
{
|
||||
for (int j = 0; j < td->td_samplesperpixel; j++)
|
||||
{
|
||||
if (sp->mask_buffer[i] == 0)
|
||||
((double *)sp->uncompressed_buffer)[k] =
|
||||
nan_float64;
|
||||
++k;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#if LERC_AT_LEAST_VERSION(3, 0, 0)
|
||||
else
|
||||
{
|
||||
const double nan_float64 = nan_float32;
|
||||
for (i = 0; i < nb_pixels; i++)
|
||||
assert(nRequestedMasks == td->td_samplesperpixel);
|
||||
assert(nFoundDims == 1);
|
||||
assert(nFoundBands == td->td_samplesperpixel);
|
||||
|
||||
unsigned k = 0;
|
||||
if (td->td_bitspersample == 32)
|
||||
{
|
||||
if (sp->mask_buffer[i] == 0)
|
||||
((double *)sp->uncompressed_buffer)[i] = nan_float64;
|
||||
for (i = 0; i < nb_pixels; i++)
|
||||
{
|
||||
for (int j = 0; j < td->td_samplesperpixel; j++)
|
||||
{
|
||||
if (sp->mask_buffer[i + j * nb_pixels] == 0)
|
||||
((float *)sp->uncompressed_buffer)[k] = nan_float32;
|
||||
else
|
||||
((float *)sp->uncompressed_buffer)[k] =
|
||||
((float *)sp->uncompressed_buffer_multiband)
|
||||
[i + j * nb_pixels];
|
||||
++k;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const double nan_float64 = nan_float32;
|
||||
for (i = 0; i < nb_pixels; i++)
|
||||
{
|
||||
for (int j = 0; j < td->td_samplesperpixel; j++)
|
||||
{
|
||||
if (sp->mask_buffer[i + j * nb_pixels] == 0)
|
||||
((double *)sp->uncompressed_buffer)[k] =
|
||||
nan_float64;
|
||||
else
|
||||
((double *)sp->uncompressed_buffer)[k] =
|
||||
((double *)sp->uncompressed_buffer_multiband)
|
||||
[i + j * nb_pixels];
|
||||
++k;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
|
@ -553,7 +746,7 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
|
|||
static int LERCDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
{
|
||||
static const char module[] = "LERCDecode";
|
||||
LERCState *sp = DecoderState(tif);
|
||||
LERCState *sp = LERCDecoderState(tif);
|
||||
|
||||
(void)s;
|
||||
assert(sp != NULL);
|
||||
|
|
@ -561,6 +754,7 @@ static int LERCDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
|
||||
if (sp->uncompressed_buffer == 0)
|
||||
{
|
||||
memset(op, 0, (size_t)occ);
|
||||
TIFFErrorExtR(tif, module, "Uncompressed buffer not allocated");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -568,6 +762,7 @@ static int LERCDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
if ((uint64_t)sp->uncompressed_offset + (uint64_t)occ >
|
||||
sp->uncompressed_size)
|
||||
{
|
||||
memset(op, 0, (size_t)occ);
|
||||
TIFFErrorExtR(tif, module, "Too many bytes read");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -580,7 +775,7 @@ static int LERCDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
|
||||
static int LERCSetupEncode(TIFF *tif)
|
||||
{
|
||||
LERCState *sp = EncoderState(tif);
|
||||
LERCState *sp = LERCEncoderState(tif);
|
||||
|
||||
assert(sp != NULL);
|
||||
if (sp->state & LSTATE_INIT_DECODE)
|
||||
|
|
@ -599,7 +794,7 @@ static int LERCSetupEncode(TIFF *tif)
|
|||
static int LERCPreEncode(TIFF *tif, uint16_t s)
|
||||
{
|
||||
static const char module[] = "LERCPreEncode";
|
||||
LERCState *sp = EncoderState(tif);
|
||||
LERCState *sp = LERCEncoderState(tif);
|
||||
int lerc_data_type;
|
||||
|
||||
(void)s;
|
||||
|
|
@ -611,7 +806,7 @@ static int LERCPreEncode(TIFF *tif, uint16_t s)
|
|||
if (lerc_data_type < 0)
|
||||
return 0;
|
||||
|
||||
if (!SetupUncompressedBuffer(tif, sp, module))
|
||||
if (!SetupBuffers(tif, sp, module))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
|
|
@ -623,7 +818,7 @@ static int LERCPreEncode(TIFF *tif, uint16_t s)
|
|||
static int LERCEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
||||
{
|
||||
static const char module[] = "LERCEncode";
|
||||
LERCState *sp = EncoderState(tif);
|
||||
LERCState *sp = LERCEncoderState(tif);
|
||||
|
||||
(void)s;
|
||||
assert(sp != NULL);
|
||||
|
|
@ -649,8 +844,7 @@ static int LERCPostEncode(TIFF *tif)
|
|||
{
|
||||
lerc_status lerc_ret;
|
||||
static const char module[] = "LERCPostEncode";
|
||||
LERCState *sp = EncoderState(tif);
|
||||
unsigned int numBytes = 0;
|
||||
LERCState *sp = LERCEncoderState(tif);
|
||||
unsigned int numBytesWritten = 0;
|
||||
TIFFDirectory *td = &tif->tif_dir;
|
||||
int use_mask = 0;
|
||||
|
|
@ -662,6 +856,9 @@ static int LERCPostEncode(TIFF *tif)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int mask_count = 1;
|
||||
const unsigned nb_pixels = sp->segment_width * sp->segment_height;
|
||||
|
||||
/* Extract alpha mask (if containing only 0 and 255 values, */
|
||||
/* and compact array of regular bands */
|
||||
if (td->td_planarconfig == PLANARCONFIG_CONTIG && td->td_extrasamples > 0 &&
|
||||
|
|
@ -673,7 +870,6 @@ static int LERCPostEncode(TIFF *tif)
|
|||
const unsigned src_stride =
|
||||
td->td_samplesperpixel * (td->td_bitspersample / 8);
|
||||
unsigned i = 0;
|
||||
const unsigned nb_pixels = sp->segment_width * sp->segment_height;
|
||||
|
||||
use_mask = 1;
|
||||
for (i = 0; i < nb_pixels; i++)
|
||||
|
|
@ -710,46 +906,78 @@ static int LERCPostEncode(TIFF *tif)
|
|||
}
|
||||
}
|
||||
else if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
|
||||
(td->td_planarconfig == PLANARCONFIG_SEPARATE ||
|
||||
dst_nbands == 1) &&
|
||||
(td->td_bitspersample == 32 || td->td_bitspersample == 64))
|
||||
{
|
||||
/* Check for NaN values */
|
||||
unsigned i;
|
||||
const unsigned nb_pixels = sp->segment_width * sp->segment_height;
|
||||
if (td->td_bitspersample == 32)
|
||||
{
|
||||
for (i = 0; i < nb_pixels; i++)
|
||||
if (td->td_planarconfig == PLANARCONFIG_CONTIG && dst_nbands > 1)
|
||||
{
|
||||
const float val = ((float *)sp->uncompressed_buffer)[i];
|
||||
if (val != val)
|
||||
unsigned k = 0;
|
||||
for (i = 0; i < nb_pixels; i++)
|
||||
{
|
||||
use_mask = 1;
|
||||
break;
|
||||
int count_nan = 0;
|
||||
for (int j = 0; j < td->td_samplesperpixel; ++j)
|
||||
{
|
||||
const float val = ((float *)sp->uncompressed_buffer)[k];
|
||||
++k;
|
||||
if (val != val)
|
||||
{
|
||||
++count_nan;
|
||||
}
|
||||
}
|
||||
if (count_nan > 0)
|
||||
{
|
||||
use_mask = 1;
|
||||
if (count_nan < td->td_samplesperpixel)
|
||||
{
|
||||
mask_count = td->td_samplesperpixel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < nb_pixels; i++)
|
||||
{
|
||||
const float val = ((float *)sp->uncompressed_buffer)[i];
|
||||
if (val != val)
|
||||
{
|
||||
use_mask = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < nb_pixels; i++)
|
||||
{
|
||||
const double val = ((double *)sp->uncompressed_buffer)[i];
|
||||
if (val != val)
|
||||
{
|
||||
use_mask = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (use_mask)
|
||||
{
|
||||
if (td->td_bitspersample == 32)
|
||||
if (td->td_planarconfig == PLANARCONFIG_CONTIG && dst_nbands > 1)
|
||||
{
|
||||
unsigned k = 0;
|
||||
for (i = 0; i < nb_pixels; i++)
|
||||
{
|
||||
const float val = ((float *)sp->uncompressed_buffer)[i];
|
||||
sp->mask_buffer[i] = (val == val) ? 255 : 0;
|
||||
int count_nan = 0;
|
||||
for (int j = 0; j < td->td_samplesperpixel; ++j)
|
||||
{
|
||||
const double val =
|
||||
((double *)sp->uncompressed_buffer)[k];
|
||||
++k;
|
||||
if (val != val)
|
||||
{
|
||||
++count_nan;
|
||||
}
|
||||
}
|
||||
if (count_nan > 0)
|
||||
{
|
||||
use_mask = 1;
|
||||
if (count_nan < td->td_samplesperpixel)
|
||||
{
|
||||
mask_count = td->td_samplesperpixel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -757,62 +985,168 @@ static int LERCPostEncode(TIFF *tif)
|
|||
for (i = 0; i < nb_pixels; i++)
|
||||
{
|
||||
const double val = ((double *)sp->uncompressed_buffer)[i];
|
||||
sp->mask_buffer[i] = (val == val) ? 255 : 0;
|
||||
if (val != val)
|
||||
{
|
||||
use_mask = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (use_mask)
|
||||
{
|
||||
if (mask_count > 1)
|
||||
{
|
||||
#if LERC_AT_LEAST_VERSION(3, 0, 0)
|
||||
unsigned int num_bytes_needed =
|
||||
nb_pixels * dst_nbands * (td->td_bitspersample / 8);
|
||||
if (sp->uncompressed_buffer_multiband_alloc < num_bytes_needed)
|
||||
{
|
||||
_TIFFfreeExt(tif, sp->uncompressed_buffer_multiband);
|
||||
sp->uncompressed_buffer_multiband =
|
||||
_TIFFmallocExt(tif, num_bytes_needed);
|
||||
if (!sp->uncompressed_buffer_multiband)
|
||||
{
|
||||
sp->uncompressed_buffer_multiband_alloc = 0;
|
||||
return 0;
|
||||
}
|
||||
sp->uncompressed_buffer_multiband_alloc = num_bytes_needed;
|
||||
}
|
||||
|
||||
unsigned k = 0;
|
||||
if (td->td_bitspersample == 32)
|
||||
{
|
||||
for (i = 0; i < nb_pixels; i++)
|
||||
{
|
||||
for (int j = 0; j < td->td_samplesperpixel; ++j)
|
||||
{
|
||||
const float val =
|
||||
((float *)sp->uncompressed_buffer)[k];
|
||||
((float *)sp->uncompressed_buffer_multiband)
|
||||
[i + j * nb_pixels] = val;
|
||||
++k;
|
||||
sp->mask_buffer[i + j * nb_pixels] =
|
||||
(val == val) ? 255 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < nb_pixels; i++)
|
||||
{
|
||||
for (int j = 0; j < td->td_samplesperpixel; ++j)
|
||||
{
|
||||
const double val =
|
||||
((double *)sp->uncompressed_buffer)[k];
|
||||
((double *)sp->uncompressed_buffer_multiband)
|
||||
[i + j * nb_pixels] = val;
|
||||
++k;
|
||||
sp->mask_buffer[i + j * nb_pixels] =
|
||||
(val == val) ? 255 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
TIFFErrorExtR(tif, module,
|
||||
"lerc_encode() would need to create one mask per "
|
||||
"sample, but this requires liblerc >= 3.0");
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
else if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
|
||||
dst_nbands > 1)
|
||||
{
|
||||
if (td->td_bitspersample == 32)
|
||||
{
|
||||
for (i = 0; i < nb_pixels; i++)
|
||||
{
|
||||
const float val =
|
||||
((float *)sp->uncompressed_buffer)[i * dst_nbands];
|
||||
sp->mask_buffer[i] = (val == val) ? 255 : 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < nb_pixels; i++)
|
||||
{
|
||||
const double val =
|
||||
((double *)sp->uncompressed_buffer)[i * dst_nbands];
|
||||
sp->mask_buffer[i] = (val == val) ? 255 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (td->td_bitspersample == 32)
|
||||
{
|
||||
for (i = 0; i < nb_pixels; i++)
|
||||
{
|
||||
const float val = ((float *)sp->uncompressed_buffer)[i];
|
||||
sp->mask_buffer[i] = (val == val) ? 255 : 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < nb_pixels; i++)
|
||||
{
|
||||
const double val =
|
||||
((double *)sp->uncompressed_buffer)[i];
|
||||
sp->mask_buffer[i] = (val == val) ? 255 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
lerc_ret = lerc_computeCompressedSize(
|
||||
sp->uncompressed_buffer,
|
||||
sp->lerc_version,
|
||||
GetLercDataType(tif),
|
||||
td->td_planarconfig == PLANARCONFIG_CONTIG ?
|
||||
dst_nbands : 1,
|
||||
sp->segment_width,
|
||||
sp->segment_height,
|
||||
1,
|
||||
use_mask ? sp->mask_buffer : NULL,
|
||||
sp->maxzerror,
|
||||
&numBytes);
|
||||
if( lerc_ret != 0 )
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"lerc_computeCompressedSize() failed");
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
numBytes = sp->uncompressed_alloc;
|
||||
unsigned int estimated_compressed_size = sp->uncompressed_alloc;
|
||||
#if LERC_AT_LEAST_VERSION(3, 0, 0)
|
||||
if (mask_count > 1)
|
||||
{
|
||||
estimated_compressed_size += nb_pixels * mask_count / 8;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (sp->compressed_size < numBytes)
|
||||
if (sp->compressed_size < estimated_compressed_size)
|
||||
{
|
||||
_TIFFfreeExt(tif, sp->compressed_buffer);
|
||||
sp->compressed_buffer = _TIFFmallocExt(tif, numBytes);
|
||||
sp->compressed_buffer = _TIFFmallocExt(tif, estimated_compressed_size);
|
||||
if (!sp->compressed_buffer)
|
||||
{
|
||||
sp->compressed_size = 0;
|
||||
return 0;
|
||||
}
|
||||
sp->compressed_size = numBytes;
|
||||
sp->compressed_size = estimated_compressed_size;
|
||||
}
|
||||
|
||||
lerc_ret = lerc_encodeForVersion(
|
||||
sp->uncompressed_buffer, sp->lerc_version, GetLercDataType(tif),
|
||||
td->td_planarconfig == PLANARCONFIG_CONTIG ? dst_nbands : 1,
|
||||
sp->segment_width, sp->segment_height, 1,
|
||||
#if LERC_AT_LEAST_VERSION(3, 0, 0)
|
||||
use_mask ? 1 : 0,
|
||||
if (mask_count > 1)
|
||||
{
|
||||
lerc_ret = lerc_encodeForVersion(
|
||||
sp->uncompressed_buffer_multiband, sp->lerc_version,
|
||||
GetLercDataType(tif), 1, sp->segment_width, sp->segment_height,
|
||||
dst_nbands, dst_nbands, sp->mask_buffer, sp->maxzerror,
|
||||
sp->compressed_buffer, sp->compressed_size, &numBytesWritten);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
use_mask ? sp->mask_buffer : NULL, sp->maxzerror, sp->compressed_buffer,
|
||||
sp->compressed_size, &numBytesWritten);
|
||||
{
|
||||
lerc_ret = lerc_encodeForVersion(
|
||||
sp->uncompressed_buffer, sp->lerc_version, GetLercDataType(tif),
|
||||
td->td_planarconfig == PLANARCONFIG_CONTIG ? dst_nbands : 1,
|
||||
sp->segment_width, sp->segment_height, 1,
|
||||
#if LERC_AT_LEAST_VERSION(3, 0, 0)
|
||||
use_mask ? 1 : 0,
|
||||
#endif
|
||||
use_mask ? sp->mask_buffer : NULL, sp->maxzerror,
|
||||
sp->compressed_buffer, sp->compressed_size, &numBytesWritten);
|
||||
}
|
||||
if (lerc_ret != 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "lerc_encode() failed");
|
||||
return 0;
|
||||
}
|
||||
assert(numBytesWritten < numBytes);
|
||||
assert(numBytesWritten < estimated_compressed_size);
|
||||
|
||||
if (sp->additional_compression == LERC_ADD_COMPRESSION_DEFLATE)
|
||||
{
|
||||
|
|
@ -950,7 +1284,7 @@ static int LERCPostEncode(TIFF *tif)
|
|||
|
||||
static void LERCCleanup(TIFF *tif)
|
||||
{
|
||||
LERCState *sp = LState(tif);
|
||||
LERCState *sp = GetLERCState(tif);
|
||||
|
||||
assert(sp != 0);
|
||||
|
||||
|
|
@ -958,6 +1292,7 @@ static void LERCCleanup(TIFF *tif)
|
|||
tif->tif_tagmethods.vsetfield = sp->vsetparent;
|
||||
|
||||
_TIFFfreeExt(tif, sp->uncompressed_buffer);
|
||||
_TIFFfreeExt(tif, sp->uncompressed_buffer_multiband);
|
||||
_TIFFfreeExt(tif, sp->compressed_buffer);
|
||||
_TIFFfreeExt(tif, sp->mask_buffer);
|
||||
|
||||
|
|
@ -995,7 +1330,7 @@ static const TIFFField LERCFields[] = {
|
|||
|
||||
static int LERCVSetFieldBase(TIFF *tif, uint32_t tag, ...)
|
||||
{
|
||||
LERCState *sp = LState(tif);
|
||||
LERCState *sp = GetLERCState(tif);
|
||||
int ret;
|
||||
va_list ap;
|
||||
va_start(ap, tag);
|
||||
|
|
@ -1007,7 +1342,7 @@ static int LERCVSetFieldBase(TIFF *tif, uint32_t tag, ...)
|
|||
static int LERCVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
{
|
||||
static const char module[] = "LERCVSetField";
|
||||
LERCState *sp = LState(tif);
|
||||
LERCState *sp = GetLERCState(tif);
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
|
|
@ -1115,7 +1450,7 @@ static int LERCVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
|||
|
||||
static int LERCVGetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
{
|
||||
LERCState *sp = LState(tif);
|
||||
LERCState *sp = GetLERCState(tif);
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
|
|
@ -1163,7 +1498,7 @@ int TIFFInitLERC(TIFF *tif, int scheme)
|
|||
tif->tif_data = (uint8_t *)_TIFFcallocExt(tif, 1, sizeof(LERCState));
|
||||
if (tif->tif_data == NULL)
|
||||
goto bad;
|
||||
sp = LState(tif);
|
||||
sp = GetLERCState(tif);
|
||||
|
||||
/*
|
||||
* Override parent get/set field methods.
|
||||
|
|
|
|||
8
3rdparty/libtiff/tif_luv.c
vendored
8
3rdparty/libtiff/tif_luv.c
vendored
|
|
@ -951,7 +951,8 @@ static
|
|||
int
|
||||
uv_encode(double u, double v, int em) /* encode (u',v') coordinates */
|
||||
{
|
||||
register int vi, ui;
|
||||
unsigned int vi;
|
||||
int ui;
|
||||
|
||||
/* check for NaN */
|
||||
if (u != u || v != v)
|
||||
|
|
@ -980,8 +981,9 @@ static
|
|||
int
|
||||
uv_decode(double *up, double *vp, int c) /* decode (u',v') index */
|
||||
{
|
||||
int upper, lower;
|
||||
register int ui, vi;
|
||||
unsigned int upper, lower;
|
||||
int ui;
|
||||
unsigned int vi;
|
||||
|
||||
if (c < 0 || c >= UV_NDIVS)
|
||||
return (-1);
|
||||
|
|
|
|||
50
3rdparty/libtiff/tif_lzma.c
vendored
50
3rdparty/libtiff/tif_lzma.c
vendored
|
|
@ -44,6 +44,8 @@
|
|||
typedef struct
|
||||
{
|
||||
TIFFPredictorState predict;
|
||||
int read_error; /* whether a read error has occurred, and which should cause
|
||||
further reads in the same strip/tile to be aborted */
|
||||
lzma_stream stream;
|
||||
lzma_filter filters[LZMA_FILTERS_MAX + 1];
|
||||
lzma_options_delta opt_delta; /* delta filter options */
|
||||
|
|
@ -58,9 +60,9 @@ typedef struct
|
|||
TIFFVSetMethod vsetparent; /* super-class method */
|
||||
} LZMAState;
|
||||
|
||||
#define LState(tif) ((LZMAState *)(tif)->tif_data)
|
||||
#define DecoderState(tif) LState(tif)
|
||||
#define EncoderState(tif) LState(tif)
|
||||
#define GetLZMAState(tif) ((LZMAState *)(tif)->tif_data)
|
||||
#define LZMADecoderState(tif) GetLZMAState(tif)
|
||||
#define LZMAEncoderState(tif) GetLZMAState(tif)
|
||||
|
||||
static int LZMAEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s);
|
||||
static int LZMADecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s);
|
||||
|
|
@ -106,7 +108,7 @@ static int LZMAFixupTags(TIFF *tif)
|
|||
|
||||
static int LZMASetupDecode(TIFF *tif)
|
||||
{
|
||||
LZMAState *sp = DecoderState(tif);
|
||||
LZMAState *sp = LZMADecoderState(tif);
|
||||
|
||||
assert(sp != NULL);
|
||||
|
||||
|
|
@ -127,7 +129,7 @@ static int LZMASetupDecode(TIFF *tif)
|
|||
static int LZMAPreDecode(TIFF *tif, uint16_t s)
|
||||
{
|
||||
static const char module[] = "LZMAPreDecode";
|
||||
LZMAState *sp = DecoderState(tif);
|
||||
LZMAState *sp = LZMADecoderState(tif);
|
||||
lzma_ret ret;
|
||||
|
||||
(void)s;
|
||||
|
|
@ -156,18 +158,31 @@ static int LZMAPreDecode(TIFF *tif, uint16_t s)
|
|||
LZMAStrerror(ret));
|
||||
return 0;
|
||||
}
|
||||
|
||||
sp->read_error = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int LZMADecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
{
|
||||
static const char module[] = "LZMADecode";
|
||||
LZMAState *sp = DecoderState(tif);
|
||||
LZMAState *sp = LZMADecoderState(tif);
|
||||
|
||||
(void)s;
|
||||
assert(sp != NULL);
|
||||
assert(sp->state == LSTATE_INIT_DECODE);
|
||||
|
||||
if (sp->read_error)
|
||||
{
|
||||
memset(op, 0, (size_t)occ);
|
||||
TIFFErrorExtR(tif, module,
|
||||
"LZMADecode: Scanline %" PRIu32 " cannot be read due to "
|
||||
"previous error",
|
||||
tif->tif_row);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sp->stream.next_in = tif->tif_rawcp;
|
||||
sp->stream.avail_in = (size_t)tif->tif_rawcc;
|
||||
|
||||
|
|
@ -175,6 +190,9 @@ static int LZMADecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
sp->stream.avail_out = (size_t)occ;
|
||||
if ((tmsize_t)sp->stream.avail_out != occ)
|
||||
{
|
||||
// read_error not set here as this is a usage issue that can be
|
||||
// recovered in a following call.
|
||||
memset(op, 0, (size_t)occ);
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Liblzma cannot deal with buffers this size");
|
||||
return 0;
|
||||
|
|
@ -198,6 +216,8 @@ static int LZMADecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
lzma_stream_decoder(&sp->stream, lzma_memusage(&sp->stream), 0);
|
||||
if (r != LZMA_OK)
|
||||
{
|
||||
sp->read_error = 1;
|
||||
memset(op, 0, (size_t)occ);
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Error initializing the stream decoder, %s",
|
||||
LZMAStrerror(r));
|
||||
|
|
@ -217,6 +237,8 @@ static int LZMADecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
} while (sp->stream.avail_out > 0);
|
||||
if (sp->stream.avail_out != 0)
|
||||
{
|
||||
sp->read_error = 1;
|
||||
memset(sp->stream.next_out, 0, sp->stream.avail_out);
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Not enough data at scanline %" PRIu32
|
||||
" (short %" TIFF_SIZE_FORMAT " bytes)",
|
||||
|
|
@ -232,7 +254,7 @@ static int LZMADecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
|
||||
static int LZMASetupEncode(TIFF *tif)
|
||||
{
|
||||
LZMAState *sp = EncoderState(tif);
|
||||
LZMAState *sp = LZMAEncoderState(tif);
|
||||
|
||||
assert(sp != NULL);
|
||||
if (sp->state & LSTATE_INIT_DECODE)
|
||||
|
|
@ -251,7 +273,7 @@ static int LZMASetupEncode(TIFF *tif)
|
|||
static int LZMAPreEncode(TIFF *tif, uint16_t s)
|
||||
{
|
||||
static const char module[] = "LZMAPreEncode";
|
||||
LZMAState *sp = EncoderState(tif);
|
||||
LZMAState *sp = LZMAEncoderState(tif);
|
||||
lzma_ret ret;
|
||||
|
||||
(void)s;
|
||||
|
|
@ -283,7 +305,7 @@ static int LZMAPreEncode(TIFF *tif, uint16_t s)
|
|||
static int LZMAEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
||||
{
|
||||
static const char module[] = "LZMAEncode";
|
||||
LZMAState *sp = EncoderState(tif);
|
||||
LZMAState *sp = LZMAEncoderState(tif);
|
||||
|
||||
assert(sp != NULL);
|
||||
assert(sp->state == LSTATE_INIT_ENCODE);
|
||||
|
|
@ -329,7 +351,7 @@ static int LZMAEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
|||
static int LZMAPostEncode(TIFF *tif)
|
||||
{
|
||||
static const char module[] = "LZMAPostEncode";
|
||||
LZMAState *sp = EncoderState(tif);
|
||||
LZMAState *sp = LZMAEncoderState(tif);
|
||||
lzma_ret ret;
|
||||
|
||||
sp->stream.avail_in = 0;
|
||||
|
|
@ -365,7 +387,7 @@ static int LZMAPostEncode(TIFF *tif)
|
|||
|
||||
static void LZMACleanup(TIFF *tif)
|
||||
{
|
||||
LZMAState *sp = LState(tif);
|
||||
LZMAState *sp = GetLZMAState(tif);
|
||||
|
||||
assert(sp != 0);
|
||||
|
||||
|
|
@ -388,7 +410,7 @@ static void LZMACleanup(TIFF *tif)
|
|||
static int LZMAVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
{
|
||||
static const char module[] = "LZMAVSetField";
|
||||
LZMAState *sp = LState(tif);
|
||||
LZMAState *sp = GetLZMAState(tif);
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
|
|
@ -414,7 +436,7 @@ static int LZMAVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
|||
|
||||
static int LZMAVGetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
{
|
||||
LZMAState *sp = LState(tif);
|
||||
LZMAState *sp = GetLZMAState(tif);
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
|
|
@ -457,7 +479,7 @@ int TIFFInitLZMA(TIFF *tif, int scheme)
|
|||
tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(LZMAState));
|
||||
if (tif->tif_data == NULL)
|
||||
goto bad;
|
||||
sp = LState(tif);
|
||||
sp = GetLZMAState(tif);
|
||||
memcpy(&sp->stream, &tmp_stream, sizeof(lzma_stream));
|
||||
|
||||
/*
|
||||
|
|
|
|||
50
3rdparty/libtiff/tif_lzw.c
vendored
50
3rdparty/libtiff/tif_lzw.c
vendored
|
|
@ -161,8 +161,8 @@ typedef struct
|
|||
} LZWCodecState;
|
||||
|
||||
#define LZWState(tif) ((LZWBaseState *)(tif)->tif_data)
|
||||
#define DecoderState(tif) ((LZWCodecState *)LZWState(tif))
|
||||
#define EncoderState(tif) ((LZWCodecState *)LZWState(tif))
|
||||
#define LZWDecoderState(tif) ((LZWCodecState *)LZWState(tif))
|
||||
#define LZWEncoderState(tif) ((LZWCodecState *)LZWState(tif))
|
||||
|
||||
static int LZWDecode(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s);
|
||||
#ifdef LZW_COMPAT
|
||||
|
|
@ -183,7 +183,7 @@ static int LZWFixupTags(TIFF *tif)
|
|||
static int LZWSetupDecode(TIFF *tif)
|
||||
{
|
||||
static const char module[] = "LZWSetupDecode";
|
||||
LZWCodecState *sp = DecoderState(tif);
|
||||
LZWCodecState *sp = LZWDecoderState(tif);
|
||||
int code;
|
||||
|
||||
if (sp == NULL)
|
||||
|
|
@ -199,7 +199,7 @@ static int LZWSetupDecode(TIFF *tif)
|
|||
return (0);
|
||||
}
|
||||
|
||||
sp = DecoderState(tif);
|
||||
sp = LZWDecoderState(tif);
|
||||
sp->dec_codetab = NULL;
|
||||
sp->dec_decode = NULL;
|
||||
|
||||
|
|
@ -245,7 +245,7 @@ static int LZWSetupDecode(TIFF *tif)
|
|||
static int LZWPreDecode(TIFF *tif, uint16_t s)
|
||||
{
|
||||
static const char module[] = "LZWPreDecode";
|
||||
LZWCodecState *sp = DecoderState(tif);
|
||||
LZWCodecState *sp = LZWDecoderState(tif);
|
||||
|
||||
(void)s;
|
||||
assert(sp != NULL);
|
||||
|
|
@ -329,10 +329,7 @@ static int LZWPreDecode(TIFF *tif, uint16_t s)
|
|||
#ifdef WORDS_BIGENDIAN
|
||||
#define GetNextData(nextdata, bp) memcpy(&nextdata, bp, sizeof(nextdata))
|
||||
#elif SIZEOF_WORDTYPE == 8
|
||||
#if defined(__GNUC__) && defined(__x86_64__)
|
||||
#define GetNextData(nextdata, bp) \
|
||||
nextdata = __builtin_bswap64(*(uint64_t *)(bp))
|
||||
#elif defined(_M_X64)
|
||||
#if defined(_M_X64)
|
||||
#define GetNextData(nextdata, bp) nextdata = _byteswap_uint64(*(uint64_t *)(bp))
|
||||
#elif defined(__GNUC__)
|
||||
#define GetNextData(nextdata, bp) \
|
||||
|
|
@ -346,10 +343,7 @@ static int LZWPreDecode(TIFF *tif, uint16_t s)
|
|||
(((uint64_t)bp[6]) << 8) | (((uint64_t)bp[7]))
|
||||
#endif
|
||||
#elif SIZEOF_WORDTYPE == 4
|
||||
#if defined(__GNUC__) && defined(__i386__)
|
||||
#define GetNextData(nextdata, bp) \
|
||||
nextdata = __builtin_bswap32(*(uint32_t *)(bp))
|
||||
#elif defined(_M_X86)
|
||||
#if defined(_M_X86)
|
||||
#define GetNextData(nextdata, bp) \
|
||||
nextdata = _byteswap_ulong(*(unsigned long *)(bp))
|
||||
#elif defined(__GNUC__)
|
||||
|
|
@ -409,7 +403,7 @@ static int LZWPreDecode(TIFF *tif, uint16_t s)
|
|||
static int LZWDecode(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s)
|
||||
{
|
||||
static const char module[] = "LZWDecode";
|
||||
LZWCodecState *sp = DecoderState(tif);
|
||||
LZWCodecState *sp = LZWDecoderState(tif);
|
||||
uint8_t *op = (uint8_t *)op0;
|
||||
tmsize_t occ = occ0;
|
||||
uint8_t *bp;
|
||||
|
|
@ -423,6 +417,7 @@ static int LZWDecode(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s)
|
|||
|
||||
if (sp->read_error)
|
||||
{
|
||||
memset(op, 0, (size_t)occ);
|
||||
TIFFErrorExtR(tif, module,
|
||||
"LZWDecode: Scanline %" PRIu32 " cannot be read due to "
|
||||
"previous error",
|
||||
|
|
@ -737,6 +732,7 @@ after_loop:
|
|||
|
||||
if (occ > 0)
|
||||
{
|
||||
memset(op, 0, (size_t)occ);
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Not enough data at scanline %" PRIu32 " (short %" PRIu64
|
||||
" bytes)",
|
||||
|
|
@ -746,12 +742,14 @@ after_loop:
|
|||
return (1);
|
||||
|
||||
no_eoi:
|
||||
memset(op, 0, (size_t)occ);
|
||||
sp->read_error = 1;
|
||||
TIFFErrorExtR(tif, module,
|
||||
"LZWDecode: Strip %" PRIu32 " not terminated with EOI code",
|
||||
tif->tif_curstrip);
|
||||
return 0;
|
||||
error_code:
|
||||
memset(op, 0, (size_t)occ);
|
||||
sp->read_error = 1;
|
||||
TIFFErrorExtR(tif, tif->tif_name, "Using code not yet in table");
|
||||
return 0;
|
||||
|
|
@ -800,7 +798,7 @@ error_code:
|
|||
static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s)
|
||||
{
|
||||
static const char module[] = "LZWDecodeCompat";
|
||||
LZWCodecState *sp = DecoderState(tif);
|
||||
LZWCodecState *sp = LZWDecoderState(tif);
|
||||
uint8_t *op = (uint8_t *)op0;
|
||||
tmsize_t occ = occ0;
|
||||
uint8_t *tp;
|
||||
|
|
@ -1026,7 +1024,7 @@ static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s)
|
|||
static int LZWSetupEncode(TIFF *tif)
|
||||
{
|
||||
static const char module[] = "LZWSetupEncode";
|
||||
LZWCodecState *sp = EncoderState(tif);
|
||||
LZWCodecState *sp = LZWEncoderState(tif);
|
||||
|
||||
assert(sp != NULL);
|
||||
sp->enc_hashtab = (hash_t *)_TIFFmallocExt(tif, HSIZE * sizeof(hash_t));
|
||||
|
|
@ -1043,7 +1041,7 @@ static int LZWSetupEncode(TIFF *tif)
|
|||
*/
|
||||
static int LZWPreEncode(TIFF *tif, uint16_t s)
|
||||
{
|
||||
LZWCodecState *sp = EncoderState(tif);
|
||||
LZWCodecState *sp = LZWEncoderState(tif);
|
||||
|
||||
(void)s;
|
||||
assert(sp != NULL);
|
||||
|
|
@ -1114,7 +1112,7 @@ static int LZWPreEncode(TIFF *tif, uint16_t s)
|
|||
*/
|
||||
static int LZWEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
||||
{
|
||||
register LZWCodecState *sp = EncoderState(tif);
|
||||
register LZWCodecState *sp = LZWEncoderState(tif);
|
||||
register long fcode;
|
||||
register hash_t *hp;
|
||||
register int h, c;
|
||||
|
|
@ -1299,7 +1297,7 @@ static int LZWEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
|||
*/
|
||||
static int LZWPostEncode(TIFF *tif)
|
||||
{
|
||||
register LZWCodecState *sp = EncoderState(tif);
|
||||
register LZWCodecState *sp = LZWEncoderState(tif);
|
||||
uint8_t *op = tif->tif_rawcp;
|
||||
long nextbits = sp->lzw_nextbits;
|
||||
WordType nextdata = sp->lzw_nextdata;
|
||||
|
|
@ -1381,11 +1379,11 @@ static void LZWCleanup(TIFF *tif)
|
|||
|
||||
assert(tif->tif_data != 0);
|
||||
|
||||
if (DecoderState(tif)->dec_codetab)
|
||||
_TIFFfreeExt(tif, DecoderState(tif)->dec_codetab);
|
||||
if (LZWDecoderState(tif)->dec_codetab)
|
||||
_TIFFfreeExt(tif, LZWDecoderState(tif)->dec_codetab);
|
||||
|
||||
if (EncoderState(tif)->enc_hashtab)
|
||||
_TIFFfreeExt(tif, EncoderState(tif)->enc_hashtab);
|
||||
if (LZWEncoderState(tif)->enc_hashtab)
|
||||
_TIFFfreeExt(tif, LZWEncoderState(tif)->enc_hashtab);
|
||||
|
||||
_TIFFfreeExt(tif, tif->tif_data);
|
||||
tif->tif_data = NULL;
|
||||
|
|
@ -1404,9 +1402,9 @@ int TIFFInitLZW(TIFF *tif, int scheme)
|
|||
tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(LZWCodecState));
|
||||
if (tif->tif_data == NULL)
|
||||
goto bad;
|
||||
DecoderState(tif)->dec_codetab = NULL;
|
||||
DecoderState(tif)->dec_decode = NULL;
|
||||
EncoderState(tif)->enc_hashtab = NULL;
|
||||
LZWDecoderState(tif)->dec_codetab = NULL;
|
||||
LZWDecoderState(tif)->dec_decode = NULL;
|
||||
LZWEncoderState(tif)->enc_hashtab = NULL;
|
||||
LZWState(tif)->rw_mode = tif->tif_mode;
|
||||
|
||||
/*
|
||||
|
|
|
|||
46
3rdparty/libtiff/tif_ojpeg.c
vendored
46
3rdparty/libtiff/tif_ojpeg.c
vendored
|
|
@ -207,37 +207,21 @@ static const TIFFField ojpegFields[] = {
|
|||
#include <setjmp.h>
|
||||
#endif
|
||||
|
||||
/* We undefine FAR to avoid conflict with JPEG definition */
|
||||
|
||||
#ifdef FAR
|
||||
#undef FAR
|
||||
#endif
|
||||
|
||||
/*
|
||||
Libjpeg's jmorecfg.h defines INT16 and INT32, but only if XMD_H is
|
||||
not defined. Unfortunately, the MinGW and Borland compilers include
|
||||
a typedef for INT32, which causes a conflict. MSVC does not include
|
||||
a conflicting typedef given the headers which are included.
|
||||
*/
|
||||
#if defined(__BORLANDC__) || defined(__MINGW32__)
|
||||
#define XMD_H 1
|
||||
#endif
|
||||
|
||||
/* Define "boolean" as unsigned char, not int, per Windows custom. */
|
||||
#if defined(__WIN32__) && !defined(__MINGW32__)
|
||||
#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
|
||||
typedef unsigned char boolean;
|
||||
#endif
|
||||
#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
|
||||
#endif
|
||||
|
||||
#include "jerror.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
#ifndef TIFF_jpeg_source_mgr_defined
|
||||
#define TIFF_jpeg_source_mgr_defined
|
||||
typedef struct jpeg_source_mgr jpeg_source_mgr;
|
||||
#endif
|
||||
|
||||
#ifndef TIFF_jpeg_error_mgr_defined
|
||||
#define TIFF_jpeg_error_mgr_defined
|
||||
typedef struct jpeg_error_mgr jpeg_error_mgr;
|
||||
#endif
|
||||
|
||||
typedef struct jpeg_common_struct jpeg_common_struct;
|
||||
typedef struct jpeg_decompress_struct jpeg_decompress_struct;
|
||||
typedef struct jpeg_source_mgr jpeg_source_mgr;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
|
@ -771,6 +755,9 @@ static int OJPEGPreDecode(TIFF *tif, uint16_t s)
|
|||
if (OJPEGWriteHeaderInfo(tif) == 0)
|
||||
return (0);
|
||||
}
|
||||
|
||||
sp->subsampling_convert_state = 0;
|
||||
|
||||
while (sp->write_curstrile < m)
|
||||
{
|
||||
if (sp->libjpeg_jpeg_query_style == 0)
|
||||
|
|
@ -856,12 +843,14 @@ static int OJPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
|||
(void)s;
|
||||
if (!sp->decoder_ok)
|
||||
{
|
||||
memset(buf, 0, (size_t)cc);
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Cannot decode: decoder not correctly initialized");
|
||||
return 0;
|
||||
}
|
||||
if (sp->libjpeg_session_active == 0)
|
||||
{
|
||||
memset(buf, 0, (size_t)cc);
|
||||
/* This should normally not happen, except that it does when */
|
||||
/* using TIFFReadScanline() which calls OJPEGPostDecode() for */
|
||||
/* each scanline, which assumes that a whole strile was read */
|
||||
|
|
@ -875,17 +864,24 @@ static int OJPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
|||
}
|
||||
if (sp->error_in_raw_data_decoding)
|
||||
{
|
||||
memset(buf, 0, (size_t)cc);
|
||||
return 0;
|
||||
}
|
||||
if (sp->libjpeg_jpeg_query_style == 0)
|
||||
{
|
||||
if (OJPEGDecodeRaw(tif, buf, cc) == 0)
|
||||
{
|
||||
memset(buf, 0, (size_t)cc);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (OJPEGDecodeScanlines(tif, buf, cc) == 0)
|
||||
{
|
||||
memset(buf, 0, (size_t)cc);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
|
|
|||
195
3rdparty/libtiff/tif_open.c
vendored
195
3rdparty/libtiff/tif_open.c
vendored
|
|
@ -25,7 +25,13 @@
|
|||
/*
|
||||
* TIFF Library.
|
||||
*/
|
||||
|
||||
#ifdef TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS
|
||||
#undef TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS
|
||||
#endif
|
||||
|
||||
#include "tiffiop.h"
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
/*
|
||||
|
|
@ -81,8 +87,9 @@ TIFFOpenOptions *TIFFOpenOptionsAlloc()
|
|||
void TIFFOpenOptionsFree(TIFFOpenOptions *opts) { _TIFFfree(opts); }
|
||||
|
||||
/** Define a limit in bytes for a single memory allocation done by libtiff.
|
||||
* If max_single_mem_alloc is set to 0, no other limit that the underlying
|
||||
* _TIFFmalloc() will be applied, which is the default.
|
||||
* If max_single_mem_alloc is set to 0, which is the default, no other limit
|
||||
* that the underlying _TIFFmalloc() or
|
||||
* TIFFOpenOptionsSetMaxCumulatedMemAlloc() will be applied.
|
||||
*/
|
||||
void TIFFOpenOptionsSetMaxSingleMemAlloc(TIFFOpenOptions *opts,
|
||||
tmsize_t max_single_mem_alloc)
|
||||
|
|
@ -90,6 +97,18 @@ void TIFFOpenOptionsSetMaxSingleMemAlloc(TIFFOpenOptions *opts,
|
|||
opts->max_single_mem_alloc = max_single_mem_alloc;
|
||||
}
|
||||
|
||||
/** Define a limit in bytes for the cumulated memory allocations done by libtiff
|
||||
* on a given TIFF handle.
|
||||
* If max_cumulated_mem_alloc is set to 0, which is the default, no other limit
|
||||
* that the underlying _TIFFmalloc() or
|
||||
* TIFFOpenOptionsSetMaxSingleMemAlloc() will be applied.
|
||||
*/
|
||||
void TIFFOpenOptionsSetMaxCumulatedMemAlloc(TIFFOpenOptions *opts,
|
||||
tmsize_t max_cumulated_mem_alloc)
|
||||
{
|
||||
opts->max_cumulated_mem_alloc = max_cumulated_mem_alloc;
|
||||
}
|
||||
|
||||
void TIFFOpenOptionsSetErrorHandlerExtR(TIFFOpenOptions *opts,
|
||||
TIFFErrorHandlerExtR handler,
|
||||
void *errorhandler_user_data)
|
||||
|
|
@ -117,6 +136,30 @@ static void _TIFFEmitErrorAboveMaxSingleMemAlloc(TIFF *tif,
|
|||
(uint64_t)s, (uint64_t)tif->tif_max_single_mem_alloc);
|
||||
}
|
||||
|
||||
static void _TIFFEmitErrorAboveMaxCumulatedMemAlloc(TIFF *tif,
|
||||
const char *pszFunction,
|
||||
tmsize_t s)
|
||||
{
|
||||
TIFFErrorExtR(tif, pszFunction,
|
||||
"Cumulated memory allocation of %" PRIu64 " + %" PRIu64
|
||||
" bytes is beyond the %" PRIu64
|
||||
" cumulated byte limit defined in open options",
|
||||
(uint64_t)tif->tif_cur_cumulated_mem_alloc, (uint64_t)s,
|
||||
(uint64_t)tif->tif_max_cumulated_mem_alloc);
|
||||
}
|
||||
|
||||
/* When allocating memory, we write at the beginning of the buffer it size.
|
||||
* This allows us to keep track of the total memory allocated when we
|
||||
* malloc/calloc/realloc and free. In theory we need just SIZEOF_SIZE_T bytes
|
||||
* for that, but on x86_64, allocations of more than 16 bytes are aligned on
|
||||
* 16 bytes. Hence using 2 * SIZEOF_SIZE_T.
|
||||
* It is critical that _TIFFmallocExt/_TIFFcallocExt/_TIFFreallocExt are
|
||||
* paired with _TIFFfreeExt.
|
||||
* CMakeLists.txt defines TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS, which in
|
||||
* turn disables the definition of the non Ext version in tiffio.h
|
||||
*/
|
||||
#define LEADING_AREA_TO_STORE_ALLOC_SIZE (2 * SIZEOF_SIZE_T)
|
||||
|
||||
/** malloc() version that takes into account memory-specific open options */
|
||||
void *_TIFFmallocExt(TIFF *tif, tmsize_t s)
|
||||
{
|
||||
|
|
@ -126,16 +169,32 @@ void *_TIFFmallocExt(TIFF *tif, tmsize_t s)
|
|||
_TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFmallocExt", s);
|
||||
return NULL;
|
||||
}
|
||||
if (tif != NULL && tif->tif_max_cumulated_mem_alloc > 0)
|
||||
{
|
||||
if (s > tif->tif_max_cumulated_mem_alloc -
|
||||
tif->tif_cur_cumulated_mem_alloc ||
|
||||
s > TIFF_TMSIZE_T_MAX - LEADING_AREA_TO_STORE_ALLOC_SIZE)
|
||||
{
|
||||
_TIFFEmitErrorAboveMaxCumulatedMemAlloc(tif, "_TIFFmallocExt", s);
|
||||
return NULL;
|
||||
}
|
||||
void *ptr = _TIFFmalloc(LEADING_AREA_TO_STORE_ALLOC_SIZE + s);
|
||||
if (!ptr)
|
||||
return NULL;
|
||||
tif->tif_cur_cumulated_mem_alloc += s;
|
||||
memcpy(ptr, &s, sizeof(s));
|
||||
return (char *)ptr + LEADING_AREA_TO_STORE_ALLOC_SIZE;
|
||||
}
|
||||
return _TIFFmalloc(s);
|
||||
}
|
||||
|
||||
/** calloc() version that takes into account memory-specific open options */
|
||||
void *_TIFFcallocExt(TIFF *tif, tmsize_t nmemb, tmsize_t siz)
|
||||
{
|
||||
if (nmemb <= 0 || siz <= 0 || nmemb > TIFF_TMSIZE_T_MAX / siz)
|
||||
return NULL;
|
||||
if (tif != NULL && tif->tif_max_single_mem_alloc > 0)
|
||||
{
|
||||
if (nmemb <= 0 || siz <= 0 || nmemb > TIFF_TMSIZE_T_MAX / siz)
|
||||
return NULL;
|
||||
if (nmemb * siz > tif->tif_max_single_mem_alloc)
|
||||
{
|
||||
_TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFcallocExt",
|
||||
|
|
@ -143,6 +202,23 @@ void *_TIFFcallocExt(TIFF *tif, tmsize_t nmemb, tmsize_t siz)
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
if (tif != NULL && tif->tif_max_cumulated_mem_alloc > 0)
|
||||
{
|
||||
const tmsize_t s = nmemb * siz;
|
||||
if (s > tif->tif_max_cumulated_mem_alloc -
|
||||
tif->tif_cur_cumulated_mem_alloc ||
|
||||
s > TIFF_TMSIZE_T_MAX - LEADING_AREA_TO_STORE_ALLOC_SIZE)
|
||||
{
|
||||
_TIFFEmitErrorAboveMaxCumulatedMemAlloc(tif, "_TIFFcallocExt", s);
|
||||
return NULL;
|
||||
}
|
||||
void *ptr = _TIFFcalloc(LEADING_AREA_TO_STORE_ALLOC_SIZE + s, 1);
|
||||
if (!ptr)
|
||||
return NULL;
|
||||
tif->tif_cur_cumulated_mem_alloc += s;
|
||||
memcpy(ptr, &s, sizeof(s));
|
||||
return (char *)ptr + LEADING_AREA_TO_STORE_ALLOC_SIZE;
|
||||
}
|
||||
return _TIFFcalloc(nmemb, siz);
|
||||
}
|
||||
|
||||
|
|
@ -155,13 +231,49 @@ void *_TIFFreallocExt(TIFF *tif, void *p, tmsize_t s)
|
|||
_TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFreallocExt", s);
|
||||
return NULL;
|
||||
}
|
||||
if (tif != NULL && tif->tif_max_cumulated_mem_alloc > 0)
|
||||
{
|
||||
void *oldPtr = p;
|
||||
tmsize_t oldSize = 0;
|
||||
if (p)
|
||||
{
|
||||
oldPtr = (char *)p - LEADING_AREA_TO_STORE_ALLOC_SIZE;
|
||||
memcpy(&oldSize, oldPtr, sizeof(oldSize));
|
||||
assert(oldSize <= tif->tif_cur_cumulated_mem_alloc);
|
||||
}
|
||||
if (s > oldSize &&
|
||||
(s > tif->tif_max_cumulated_mem_alloc -
|
||||
(tif->tif_cur_cumulated_mem_alloc - oldSize) ||
|
||||
s > TIFF_TMSIZE_T_MAX - LEADING_AREA_TO_STORE_ALLOC_SIZE))
|
||||
{
|
||||
_TIFFEmitErrorAboveMaxCumulatedMemAlloc(tif, "_TIFFreallocExt",
|
||||
s - oldSize);
|
||||
return NULL;
|
||||
}
|
||||
void *newPtr =
|
||||
_TIFFrealloc(oldPtr, LEADING_AREA_TO_STORE_ALLOC_SIZE + s);
|
||||
if (newPtr == NULL)
|
||||
return NULL;
|
||||
tif->tif_cur_cumulated_mem_alloc -= oldSize;
|
||||
tif->tif_cur_cumulated_mem_alloc += s;
|
||||
memcpy(newPtr, &s, sizeof(s));
|
||||
return (char *)newPtr + LEADING_AREA_TO_STORE_ALLOC_SIZE;
|
||||
}
|
||||
return _TIFFrealloc(p, s);
|
||||
}
|
||||
|
||||
/** free() version that takes into account memory-specific open options */
|
||||
void _TIFFfreeExt(TIFF *tif, void *p)
|
||||
{
|
||||
(void)tif;
|
||||
if (p != NULL && tif != NULL && tif->tif_max_cumulated_mem_alloc > 0)
|
||||
{
|
||||
void *oldPtr = (char *)p - LEADING_AREA_TO_STORE_ALLOC_SIZE;
|
||||
tmsize_t oldSize;
|
||||
memcpy(&oldSize, oldPtr, sizeof(oldSize));
|
||||
assert(oldSize <= tif->tif_cur_cumulated_mem_alloc);
|
||||
tif->tif_cur_cumulated_mem_alloc -= oldSize;
|
||||
p = oldPtr;
|
||||
}
|
||||
_TIFFfree(p);
|
||||
}
|
||||
|
||||
|
|
@ -231,6 +343,17 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
|
|||
(uint64_t)opts->max_single_mem_alloc);
|
||||
goto bad2;
|
||||
}
|
||||
if (opts && opts->max_cumulated_mem_alloc > 0 &&
|
||||
size_to_alloc > opts->max_cumulated_mem_alloc)
|
||||
{
|
||||
_TIFFErrorEarly(opts, clientdata, module,
|
||||
"%s: Memory allocation of %" PRIu64
|
||||
" bytes is beyond the %" PRIu64
|
||||
" cumulated byte limit defined in open options",
|
||||
name, (uint64_t)size_to_alloc,
|
||||
(uint64_t)opts->max_cumulated_mem_alloc);
|
||||
goto bad2;
|
||||
}
|
||||
tif = (TIFF *)_TIFFmallocExt(NULL, size_to_alloc);
|
||||
if (tif == NULL)
|
||||
{
|
||||
|
|
@ -243,6 +366,7 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
|
|||
strcpy(tif->tif_name, name);
|
||||
tif->tif_mode = m & ~(O_CREAT | O_TRUNC);
|
||||
tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER; /* non-existent directory */
|
||||
tif->tif_curdircount = TIFF_NON_EXISTENT_DIR_NUMBER;
|
||||
tif->tif_curoff = 0;
|
||||
tif->tif_curstrip = (uint32_t)-1; /* invalid strip */
|
||||
tif->tif_row = (uint32_t)-1; /* read/write pre-increment */
|
||||
|
|
@ -261,6 +385,7 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
|
|||
tif->tif_warnhandler = opts->warnhandler;
|
||||
tif->tif_warnhandler_user_data = opts->warnhandler_user_data;
|
||||
tif->tif_max_single_mem_alloc = opts->max_single_mem_alloc;
|
||||
tif->tif_max_cumulated_mem_alloc = opts->max_cumulated_mem_alloc;
|
||||
}
|
||||
|
||||
if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc)
|
||||
|
|
@ -423,9 +548,9 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
|
|||
TIFFErrorExtR(tif, name, "Cannot read TIFF header");
|
||||
goto bad;
|
||||
}
|
||||
/*
|
||||
* Setup header and write.
|
||||
*/
|
||||
/*
|
||||
* Setup header and write.
|
||||
*/
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
tif->tif_header.common.tiff_magic =
|
||||
(tif->tif_flags & TIFF_SWAB) ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN;
|
||||
|
|
@ -433,13 +558,17 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
|
|||
tif->tif_header.common.tiff_magic =
|
||||
(tif->tif_flags & TIFF_SWAB) ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN;
|
||||
#endif
|
||||
TIFFHeaderUnion tif_header_swapped;
|
||||
if (!(tif->tif_flags & TIFF_BIGTIFF))
|
||||
{
|
||||
tif->tif_header.common.tiff_version = TIFF_VERSION_CLASSIC;
|
||||
tif->tif_header.classic.tiff_diroff = 0;
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
TIFFSwabShort(&tif->tif_header.common.tiff_version);
|
||||
tif->tif_header_size = sizeof(TIFFHeaderClassic);
|
||||
/* Swapped copy for writing */
|
||||
_TIFFmemcpy(&tif_header_swapped, &tif->tif_header,
|
||||
sizeof(TIFFHeaderUnion));
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
TIFFSwabShort(&tif_header_swapped.common.tiff_version);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -447,12 +576,15 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
|
|||
tif->tif_header.big.tiff_offsetsize = 8;
|
||||
tif->tif_header.big.tiff_unused = 0;
|
||||
tif->tif_header.big.tiff_diroff = 0;
|
||||
tif->tif_header_size = sizeof(TIFFHeaderBig);
|
||||
/* Swapped copy for writing */
|
||||
_TIFFmemcpy(&tif_header_swapped, &tif->tif_header,
|
||||
sizeof(TIFFHeaderUnion));
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
{
|
||||
TIFFSwabShort(&tif->tif_header.common.tiff_version);
|
||||
TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize);
|
||||
TIFFSwabShort(&tif_header_swapped.common.tiff_version);
|
||||
TIFFSwabShort(&tif_header_swapped.big.tiff_offsetsize);
|
||||
}
|
||||
tif->tif_header_size = sizeof(TIFFHeaderBig);
|
||||
}
|
||||
/*
|
||||
* The doc for "fopen" for some STD_C_LIBs says that if you
|
||||
|
|
@ -462,26 +594,12 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
|
|||
* on Solaris.
|
||||
*/
|
||||
TIFFSeekFile(tif, 0, SEEK_SET);
|
||||
if (!WriteOK(tif, &tif->tif_header, (tmsize_t)(tif->tif_header_size)))
|
||||
if (!WriteOK(tif, &tif_header_swapped,
|
||||
(tmsize_t)(tif->tif_header_size)))
|
||||
{
|
||||
TIFFErrorExtR(tif, name, "Error writing TIFF header");
|
||||
goto bad;
|
||||
}
|
||||
/*
|
||||
* Setup the byte order handling.
|
||||
*/
|
||||
if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN)
|
||||
{
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
tif->tif_flags |= TIFF_SWAB;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
tif->tif_flags |= TIFF_SWAB;
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* Setup default directory.
|
||||
*/
|
||||
|
|
@ -490,10 +608,14 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
|
|||
tif->tif_diroff = 0;
|
||||
tif->tif_lastdiroff = 0;
|
||||
tif->tif_setdirectory_force_absolute = FALSE;
|
||||
/* tif_curdircount = 0 means 'empty file opened for writing, but no IFD
|
||||
* written yet' */
|
||||
tif->tif_curdircount = 0;
|
||||
return (tif);
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the byte order handling.
|
||||
* Setup the byte order handling according to the opened file for reading.
|
||||
*/
|
||||
if (tif->tif_header.common.tiff_magic != TIFF_BIGENDIAN &&
|
||||
tif->tif_header.common.tiff_magic != TIFF_LITTLEENDIAN
|
||||
|
|
@ -619,9 +741,17 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
|
|||
* example, it may be broken) and want to proceed to other
|
||||
* directories. I this case we use the TIFF_HEADERONLY flag to open
|
||||
* file and return immediately after reading TIFF header.
|
||||
* However, the pointer to TIFFSetField() and TIFFGetField()
|
||||
* (i.e. tif->tif_tagmethods.vsetfield and
|
||||
* tif->tif_tagmethods.vgetfield) need to be initialized, which is
|
||||
* done in TIFFDefaultDirectory().
|
||||
*/
|
||||
if (tif->tif_flags & TIFF_HEADERONLY)
|
||||
{
|
||||
if (!TIFFDefaultDirectory(tif))
|
||||
goto bad;
|
||||
return (tif);
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup initial directory.
|
||||
|
|
@ -764,10 +894,7 @@ int TIFFIsBigEndian(TIFF *tif)
|
|||
/*
|
||||
* Return nonzero if given file is BigTIFF style.
|
||||
*/
|
||||
int TIFFIsBigTIFF(TIFF *tif)
|
||||
{
|
||||
return (tif->tif_header.common.tiff_version == TIFF_VERSION_BIG);
|
||||
}
|
||||
int TIFFIsBigTIFF(TIFF *tif) { return ((tif->tif_flags & TIFF_BIGTIFF) != 0); }
|
||||
|
||||
/*
|
||||
* Return pointer to file read method.
|
||||
|
|
|
|||
1
3rdparty/libtiff/tif_packbits.c
vendored
1
3rdparty/libtiff/tif_packbits.c
vendored
|
|
@ -300,6 +300,7 @@ static int PackBitsDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
tif->tif_rawcc = cc;
|
||||
if (occ > 0)
|
||||
{
|
||||
memset(op, 0, (size_t)occ);
|
||||
TIFFErrorExtR(tif, module, "Not enough data for scanline %" PRIu32,
|
||||
tif->tif_row);
|
||||
return (0);
|
||||
|
|
|
|||
25
3rdparty/libtiff/tif_pixarlog.c
vendored
25
3rdparty/libtiff/tif_pixarlog.c
vendored
|
|
@ -670,8 +670,8 @@ static int PixarLogMakeTables(TIFF *tif, PixarLogState *sp)
|
|||
return 1;
|
||||
}
|
||||
|
||||
#define DecoderState(tif) ((PixarLogState *)(tif)->tif_data)
|
||||
#define EncoderState(tif) ((PixarLogState *)(tif)->tif_data)
|
||||
#define PixarLogDecoderState(tif) ((PixarLogState *)(tif)->tif_data)
|
||||
#define PixarLogEncoderState(tif) ((PixarLogState *)(tif)->tif_data)
|
||||
|
||||
static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s);
|
||||
static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s);
|
||||
|
|
@ -740,7 +740,7 @@ static int PixarLogSetupDecode(TIFF *tif)
|
|||
{
|
||||
static const char module[] = "PixarLogSetupDecode";
|
||||
TIFFDirectory *td = &tif->tif_dir;
|
||||
PixarLogState *sp = DecoderState(tif);
|
||||
PixarLogState *sp = PixarLogDecoderState(tif);
|
||||
tmsize_t tbuf_size;
|
||||
uint32_t strip_height;
|
||||
|
||||
|
|
@ -813,7 +813,7 @@ static int PixarLogSetupDecode(TIFF *tif)
|
|||
static int PixarLogPreDecode(TIFF *tif, uint16_t s)
|
||||
{
|
||||
static const char module[] = "PixarLogPreDecode";
|
||||
PixarLogState *sp = DecoderState(tif);
|
||||
PixarLogState *sp = PixarLogDecoderState(tif);
|
||||
|
||||
(void)s;
|
||||
assert(sp != NULL);
|
||||
|
|
@ -835,7 +835,7 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
{
|
||||
static const char module[] = "PixarLogDecode";
|
||||
TIFFDirectory *td = &tif->tif_dir;
|
||||
PixarLogState *sp = DecoderState(tif);
|
||||
PixarLogState *sp = PixarLogDecoderState(tif);
|
||||
tmsize_t i;
|
||||
tmsize_t nsamples;
|
||||
int llen;
|
||||
|
|
@ -859,6 +859,7 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
TIFFErrorExtR(tif, module,
|
||||
"%" PRIu16 " bit input not supported in PixarLog",
|
||||
td->td_bitspersample);
|
||||
memset(op, 0, (size_t)occ);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -879,12 +880,14 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
if (sp->stream.avail_out != nsamples * sizeof(uint16_t))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size");
|
||||
memset(op, 0, (size_t)occ);
|
||||
return (0);
|
||||
}
|
||||
/* Check that we will not fill more than what was allocated */
|
||||
if ((tmsize_t)sp->stream.avail_out > sp->tbuf_size)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "sp->stream.avail_out > sp->tbuf_size");
|
||||
memset(op, 0, (size_t)occ);
|
||||
return (0);
|
||||
}
|
||||
do
|
||||
|
|
@ -899,12 +902,14 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
TIFFErrorExtR(
|
||||
tif, module, "Decoding error at scanline %" PRIu32 ", %s",
|
||||
tif->tif_row, sp->stream.msg ? sp->stream.msg : "(null)");
|
||||
memset(op, 0, (size_t)occ);
|
||||
return (0);
|
||||
}
|
||||
if (state != Z_OK)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "ZLib error: %s",
|
||||
sp->stream.msg ? sp->stream.msg : "(null)");
|
||||
memset(op, 0, (size_t)occ);
|
||||
return (0);
|
||||
}
|
||||
} while (sp->stream.avail_out > 0);
|
||||
|
|
@ -916,6 +921,7 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
"Not enough data at scanline %" PRIu32
|
||||
" (short %u bytes)",
|
||||
tif->tif_row, sp->stream.avail_out);
|
||||
memset(op, 0, (size_t)occ);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
@ -977,6 +983,7 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
default:
|
||||
TIFFErrorExtR(tif, module, "Unsupported bits/sample: %" PRIu16,
|
||||
td->td_bitspersample);
|
||||
memset(op, 0, (size_t)occ);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
|
@ -988,7 +995,7 @@ static int PixarLogSetupEncode(TIFF *tif)
|
|||
{
|
||||
static const char module[] = "PixarLogSetupEncode";
|
||||
TIFFDirectory *td = &tif->tif_dir;
|
||||
PixarLogState *sp = EncoderState(tif);
|
||||
PixarLogState *sp = PixarLogEncoderState(tif);
|
||||
tmsize_t tbuf_size;
|
||||
|
||||
assert(sp != NULL);
|
||||
|
|
@ -1038,7 +1045,7 @@ static int PixarLogSetupEncode(TIFF *tif)
|
|||
static int PixarLogPreEncode(TIFF *tif, uint16_t s)
|
||||
{
|
||||
static const char module[] = "PixarLogPreEncode";
|
||||
PixarLogState *sp = EncoderState(tif);
|
||||
PixarLogState *sp = PixarLogEncoderState(tif);
|
||||
|
||||
(void)s;
|
||||
assert(sp != NULL);
|
||||
|
|
@ -1294,7 +1301,7 @@ static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
|||
{
|
||||
static const char module[] = "PixarLogEncode";
|
||||
TIFFDirectory *td = &tif->tif_dir;
|
||||
PixarLogState *sp = EncoderState(tif);
|
||||
PixarLogState *sp = PixarLogEncoderState(tif);
|
||||
tmsize_t i;
|
||||
tmsize_t n;
|
||||
int llen;
|
||||
|
|
@ -1401,7 +1408,7 @@ static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
|||
static int PixarLogPostEncode(TIFF *tif)
|
||||
{
|
||||
static const char module[] = "PixarLogPostEncode";
|
||||
PixarLogState *sp = EncoderState(tif);
|
||||
PixarLogState *sp = PixarLogEncoderState(tif);
|
||||
int state;
|
||||
|
||||
sp->stream.avail_in = 0;
|
||||
|
|
|
|||
65
3rdparty/libtiff/tif_read.c
vendored
65
3rdparty/libtiff/tif_read.c
vendored
|
|
@ -105,8 +105,8 @@ static int TIFFReadAndRealloc(TIFF *tif, tmsize_t size, tmsize_t rawdata_offset,
|
|||
TIFFErrorExtR(tif, module, "Invalid buffer size");
|
||||
return 0;
|
||||
}
|
||||
new_rawdata =
|
||||
(uint8_t *)_TIFFrealloc(tif->tif_rawdata, tif->tif_rawdatasize);
|
||||
new_rawdata = (uint8_t *)_TIFFreallocExt(tif, tif->tif_rawdata,
|
||||
tif->tif_rawdatasize);
|
||||
if (new_rawdata == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
|
|
@ -464,6 +464,10 @@ int TIFFReadScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
|
|||
if (e)
|
||||
(*tif->tif_postdecode)(tif, (uint8_t *)buf, tif->tif_scanlinesize);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(buf, 0, (size_t)tif->tif_scanlinesize);
|
||||
}
|
||||
return (e > 0 ? 1 : -1);
|
||||
}
|
||||
|
||||
|
|
@ -495,6 +499,11 @@ static tmsize_t TIFFReadEncodedStripGetStripSize(TIFF *tif, uint32_t strip,
|
|||
rowsperstrip = td->td_rowsperstrip;
|
||||
if (rowsperstrip > td->td_imagelength)
|
||||
rowsperstrip = td->td_imagelength;
|
||||
if (rowsperstrip == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "rowsperstrip is zero");
|
||||
return ((tmsize_t)(-1));
|
||||
}
|
||||
stripsperplane =
|
||||
TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip);
|
||||
stripinplane = (strip % stripsperplane);
|
||||
|
|
@ -544,7 +553,10 @@ tmsize_t TIFFReadEncodedStrip(TIFF *tif, uint32_t strip, void *buf,
|
|||
if ((size != (tmsize_t)(-1)) && (size < stripsize))
|
||||
stripsize = size;
|
||||
if (!TIFFFillStrip(tif, strip))
|
||||
{
|
||||
memset(buf, 0, (size_t)stripsize);
|
||||
return ((tmsize_t)(-1));
|
||||
}
|
||||
if ((*tif->tif_decodestrip)(tif, buf, stripsize, plane) <= 0)
|
||||
return ((tmsize_t)(-1));
|
||||
(*tif->tif_postdecode)(tif, buf, stripsize);
|
||||
|
|
@ -962,9 +974,13 @@ tmsize_t TIFFReadEncodedTile(TIFF *tif, uint32_t tile, void *buf, tmsize_t size)
|
|||
size = tilesize;
|
||||
else if (size > tilesize)
|
||||
size = tilesize;
|
||||
if (TIFFFillTile(tif, tile) &&
|
||||
(*tif->tif_decodetile)(tif, (uint8_t *)buf, size,
|
||||
(uint16_t)(tile / td->td_stripsperimage)))
|
||||
if (!TIFFFillTile(tif, tile))
|
||||
{
|
||||
memset(buf, 0, (size_t)size);
|
||||
return ((tmsize_t)(-1));
|
||||
}
|
||||
else if ((*tif->tif_decodetile)(tif, (uint8_t *)buf, size,
|
||||
(uint16_t)(tile / td->td_stripsperimage)))
|
||||
{
|
||||
(*tif->tif_postdecode)(tif, (uint8_t *)buf, size);
|
||||
return (size);
|
||||
|
|
@ -1449,6 +1465,11 @@ static int TIFFStartTile(TIFF *tif, uint32_t tile)
|
|||
tif->tif_flags |= TIFF_CODERSETUP;
|
||||
}
|
||||
tif->tif_curtile = tile;
|
||||
if (td->td_tilewidth == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Zero tilewidth");
|
||||
return 0;
|
||||
}
|
||||
howmany32 = TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth);
|
||||
if (howmany32 == 0)
|
||||
{
|
||||
|
|
@ -1545,9 +1566,14 @@ int TIFFReadFromUserBuffer(TIFF *tif, uint32_t strile, void *inbuf,
|
|||
|
||||
if (TIFFIsTiled(tif))
|
||||
{
|
||||
if (!TIFFStartTile(tif, strile) ||
|
||||
!(*tif->tif_decodetile)(tif, (uint8_t *)outbuf, outsize,
|
||||
(uint16_t)(strile / td->td_stripsperimage)))
|
||||
if (!TIFFStartTile(tif, strile))
|
||||
{
|
||||
ret = 0;
|
||||
memset(outbuf, 0, (size_t)outsize);
|
||||
}
|
||||
else if (!(*tif->tif_decodetile)(
|
||||
tif, (uint8_t *)outbuf, outsize,
|
||||
(uint16_t)(strile / td->td_stripsperimage)))
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
|
|
@ -1558,14 +1584,27 @@ int TIFFReadFromUserBuffer(TIFF *tif, uint32_t strile, void *inbuf,
|
|||
uint32_t stripsperplane;
|
||||
if (rowsperstrip > td->td_imagelength)
|
||||
rowsperstrip = td->td_imagelength;
|
||||
stripsperplane =
|
||||
TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip);
|
||||
if (!TIFFStartStrip(tif, strile) ||
|
||||
!(*tif->tif_decodestrip)(tif, (uint8_t *)outbuf, outsize,
|
||||
(uint16_t)(strile / stripsperplane)))
|
||||
if (rowsperstrip == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "rowsperstrip is zero");
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
stripsperplane =
|
||||
TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip);
|
||||
if (!TIFFStartStrip(tif, strile))
|
||||
{
|
||||
ret = 0;
|
||||
memset(outbuf, 0, (size_t)outsize);
|
||||
}
|
||||
else if (!(*tif->tif_decodestrip)(
|
||||
tif, (uint8_t *)outbuf, outsize,
|
||||
(uint16_t)(strile / stripsperplane)))
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ret)
|
||||
{
|
||||
|
|
|
|||
36
3rdparty/libtiff/tif_strip.c
vendored
36
3rdparty/libtiff/tif_strip.c
vendored
|
|
@ -38,6 +38,11 @@ uint32_t TIFFComputeStrip(TIFF *tif, uint32_t row, uint16_t sample)
|
|||
TIFFDirectory *td = &tif->tif_dir;
|
||||
uint32_t strip;
|
||||
|
||||
if (td->td_rowsperstrip == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Cannot compute strip: RowsPerStrip is zero");
|
||||
return 0;
|
||||
}
|
||||
strip = row / td->td_rowsperstrip;
|
||||
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
|
||||
{
|
||||
|
|
@ -61,6 +66,11 @@ uint32_t TIFFNumberOfStrips(TIFF *tif)
|
|||
TIFFDirectory *td = &tif->tif_dir;
|
||||
uint32_t nstrips;
|
||||
|
||||
if (td->td_rowsperstrip == 0)
|
||||
{
|
||||
TIFFWarningExtR(tif, "TIFFNumberOfStrips", "RowsPerStrip is zero");
|
||||
return 0;
|
||||
}
|
||||
nstrips = (td->td_rowsperstrip == (uint32_t)-1
|
||||
? 1
|
||||
: TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip));
|
||||
|
|
@ -107,7 +117,8 @@ uint64_t TIFFVStripSize64(TIFF *tif, uint32_t nrows)
|
|||
if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 &&
|
||||
ycbcrsubsampling[0] != 4) ||
|
||||
(ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 &&
|
||||
ycbcrsubsampling[1] != 4))
|
||||
ycbcrsubsampling[1] != 4) ||
|
||||
(ycbcrsubsampling[0] == 0 || ycbcrsubsampling[1] == 0))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Invalid YCbCr subsampling (%dx%d)",
|
||||
ycbcrsubsampling[0], ycbcrsubsampling[1]);
|
||||
|
|
@ -267,7 +278,8 @@ uint64_t TIFFScanlineSize64(TIFF *tif)
|
|||
if (((ycbcrsubsampling[0] != 1) && (ycbcrsubsampling[0] != 2) &&
|
||||
(ycbcrsubsampling[0] != 4)) ||
|
||||
((ycbcrsubsampling[1] != 1) && (ycbcrsubsampling[1] != 2) &&
|
||||
(ycbcrsubsampling[1] != 4)))
|
||||
(ycbcrsubsampling[1] != 4)) ||
|
||||
((ycbcrsubsampling[0] == 0) || (ycbcrsubsampling[1] == 0)))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Invalid YCbCr subsampling");
|
||||
return 0;
|
||||
|
|
@ -287,7 +299,25 @@ uint64_t TIFFScanlineSize64(TIFF *tif)
|
|||
else
|
||||
{
|
||||
uint64_t scanline_samples;
|
||||
scanline_samples = _TIFFMultiply64(tif, td->td_imagewidth,
|
||||
uint32_t scanline_width = td->td_imagewidth;
|
||||
|
||||
#if 0
|
||||
// Tries to fix https://gitlab.com/libtiff/libtiff/-/merge_requests/564
|
||||
// but causes regression when decoding legit files with tiffcp -c none
|
||||
// Cf https://gitlab.com/libtiff/libtiff/-/merge_requests/644
|
||||
if (td->td_photometric == PHOTOMETRIC_YCBCR)
|
||||
{
|
||||
uint16_t subsampling_hor;
|
||||
uint16_t ignored;
|
||||
TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING,
|
||||
&subsampling_hor, &ignored);
|
||||
if (subsampling_hor > 1) // roundup width for YCbCr
|
||||
scanline_width =
|
||||
TIFFroundup_32(scanline_width, subsampling_hor);
|
||||
}
|
||||
#endif
|
||||
|
||||
scanline_samples = _TIFFMultiply64(tif, scanline_width,
|
||||
td->td_samplesperpixel, module);
|
||||
scanline_size =
|
||||
TIFFhowmany_64(_TIFFMultiply64(tif, scanline_samples,
|
||||
|
|
|
|||
16
3rdparty/libtiff/tif_thunder.c
vendored
16
3rdparty/libtiff/tif_thunder.c
vendored
|
|
@ -82,13 +82,14 @@ static int ThunderSetupDecode(TIFF *tif)
|
|||
return (1);
|
||||
}
|
||||
|
||||
static int ThunderDecode(TIFF *tif, uint8_t *op, tmsize_t maxpixels)
|
||||
static int ThunderDecode(TIFF *tif, uint8_t *op0, tmsize_t maxpixels)
|
||||
{
|
||||
static const char module[] = "ThunderDecode";
|
||||
register unsigned char *bp;
|
||||
register tmsize_t cc;
|
||||
unsigned int lastpixel;
|
||||
tmsize_t npixels;
|
||||
uint8_t *op = op0;
|
||||
|
||||
bp = (unsigned char *)tif->tif_rawcp;
|
||||
cc = tif->tif_rawcc;
|
||||
|
|
@ -107,6 +108,8 @@ static int ThunderDecode(TIFF *tif, uint8_t *op, tmsize_t maxpixels)
|
|||
* Replicate the last pixel n times,
|
||||
* where n is the lower-order 6 bits.
|
||||
*/
|
||||
if (n == 0)
|
||||
break;
|
||||
if (npixels & 1)
|
||||
{
|
||||
op[0] |= lastpixel;
|
||||
|
|
@ -117,11 +120,10 @@ static int ThunderDecode(TIFF *tif, uint8_t *op, tmsize_t maxpixels)
|
|||
else
|
||||
lastpixel |= lastpixel << 4;
|
||||
npixels += n;
|
||||
if (npixels < maxpixels)
|
||||
{
|
||||
for (; n > 0; n -= 2)
|
||||
*op++ = (uint8_t)lastpixel;
|
||||
}
|
||||
if (npixels > maxpixels)
|
||||
break;
|
||||
for (; n > 0; n -= 2)
|
||||
*op++ = (uint8_t)lastpixel;
|
||||
if (n == -1)
|
||||
*--op &= 0xf0;
|
||||
lastpixel &= 0xf;
|
||||
|
|
@ -154,6 +156,8 @@ static int ThunderDecode(TIFF *tif, uint8_t *op, tmsize_t maxpixels)
|
|||
tif->tif_rawcc = cc;
|
||||
if (npixels != maxpixels)
|
||||
{
|
||||
uint8_t *op_end = op0 + (maxpixels + 1) / 2;
|
||||
memset(op, 0, (size_t)(op_end - op));
|
||||
TIFFErrorExtR(tif, module,
|
||||
"%s data at scanline %lu (%" PRIu64 " != %" PRIu64 ")",
|
||||
npixels < maxpixels ? "Not enough" : "Too much",
|
||||
|
|
|
|||
10
3rdparty/libtiff/tif_unix.c
vendored
10
3rdparty/libtiff/tif_unix.c
vendored
|
|
@ -27,6 +27,10 @@
|
|||
* Windows Common RunTime Library.
|
||||
*/
|
||||
|
||||
#ifdef TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS
|
||||
#undef TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS
|
||||
#endif
|
||||
|
||||
#include "tif_config.h"
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
|
|
@ -79,6 +83,8 @@ static tmsize_t _tiffReadProc(thandle_t fd, void *buf, tmsize_t size)
|
|||
size_t io_size = bytes_total - bytes_read;
|
||||
if (io_size > TIFF_IO_MAX)
|
||||
io_size = TIFF_IO_MAX;
|
||||
/* Below is an obvious false positive of Coverity Scan */
|
||||
/* coverity[overflow_sink] */
|
||||
count = read(fdh.fd, buf_offset, (TIFFIOSize_t)io_size);
|
||||
if (count <= 0)
|
||||
break;
|
||||
|
|
@ -106,6 +112,8 @@ static tmsize_t _tiffWriteProc(thandle_t fd, void *buf, tmsize_t size)
|
|||
size_t io_size = bytes_total - bytes_written;
|
||||
if (io_size > TIFF_IO_MAX)
|
||||
io_size = TIFF_IO_MAX;
|
||||
/* Below is an obvious false positive of Coverity Scan */
|
||||
/* coverity[overflow_sink] */
|
||||
count = write(fdh.fd, buf_offset, (TIFFIOSize_t)io_size);
|
||||
if (count <= 0)
|
||||
break;
|
||||
|
|
@ -258,7 +266,7 @@ TIFF *TIFFOpenExt(const char *name, const char *mode, TIFFOpenOptions *opts)
|
|||
return tif;
|
||||
}
|
||||
|
||||
#ifdef __WIN32__
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
/*
|
||||
* Open a TIFF file with a Unicode filename, for read/writing.
|
||||
|
|
|
|||
40
3rdparty/libtiff/tif_webp.c
vendored
40
3rdparty/libtiff/tif_webp.c
vendored
|
|
@ -47,7 +47,9 @@ typedef struct
|
|||
{
|
||||
uint16_t nSamples; /* number of samples per pixel */
|
||||
|
||||
int lossless; /* lossy/lossless compression */
|
||||
int read_error; /* whether a read error has occurred, and which should cause
|
||||
further reads in the same strip/tile to be aborted */
|
||||
int lossless; /* lossy/lossless compression */
|
||||
int lossless_exact; /* lossless exact mode. If TRUE, R,G,B values in areas
|
||||
with alpha = 0 will be preserved */
|
||||
int quality_level; /* compression level */
|
||||
|
|
@ -133,6 +135,16 @@ static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
assert(sp != NULL);
|
||||
assert(sp->state == LSTATE_INIT_DECODE);
|
||||
|
||||
if (sp->read_error)
|
||||
{
|
||||
memset(op, 0, (size_t)occ);
|
||||
TIFFErrorExtR(tif, module,
|
||||
"ZIPDecode: Scanline %" PRIu32 " cannot be read due to "
|
||||
"previous error",
|
||||
tif->tif_row);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sp->psDecoder == NULL)
|
||||
{
|
||||
TIFFDirectory *td = &tif->tif_dir;
|
||||
|
|
@ -158,12 +170,16 @@ static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
: (uint32_t)tif->tif_rawcc,
|
||||
&webp_width, &webp_height))
|
||||
{
|
||||
memset(op, 0, (size_t)occ);
|
||||
sp->read_error = 1;
|
||||
TIFFErrorExtR(tif, module, "WebPGetInfo() failed");
|
||||
return 0;
|
||||
}
|
||||
if ((uint32_t)webp_width != segment_width ||
|
||||
(uint32_t)webp_height != segment_height)
|
||||
{
|
||||
memset(op, 0, (size_t)occ);
|
||||
sp->read_error = 1;
|
||||
TIFFErrorExtR(
|
||||
tif, module, "WebP blob dimension is %dx%d. Expected %ux%u",
|
||||
webp_width, webp_height, segment_width, segment_height);
|
||||
|
|
@ -174,6 +190,8 @@ static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
WebPDecoderConfig config;
|
||||
if (!WebPInitDecoderConfig(&config))
|
||||
{
|
||||
memset(op, 0, (size_t)occ);
|
||||
sp->read_error = 1;
|
||||
TIFFErrorExtR(tif, module, "WebPInitDecoderConfig() failed");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -189,6 +207,8 @@ static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
|
||||
if (!bWebPGetFeaturesOK)
|
||||
{
|
||||
memset(op, 0, (size_t)occ);
|
||||
sp->read_error = 1;
|
||||
TIFFErrorExtR(tif, module, "WebPInitDecoderConfig() failed");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -202,6 +222,8 @@ static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
*/
|
||||
!(webp_bands == 3 && sp->nSamples == 4))
|
||||
{
|
||||
memset(op, 0, (size_t)occ);
|
||||
sp->read_error = 1;
|
||||
TIFFErrorExtR(tif, module,
|
||||
"WebP blob band count is %d. Expected %d", webp_bands,
|
||||
sp->nSamples);
|
||||
|
|
@ -228,6 +250,8 @@ static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
if (!sp->pBuffer)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Cannot allocate buffer");
|
||||
memset(op, 0, (size_t)occ);
|
||||
sp->read_error = 1;
|
||||
return 0;
|
||||
}
|
||||
sp->buffer_size = buffer_size;
|
||||
|
|
@ -257,6 +281,8 @@ static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
|
||||
if (sp->psDecoder == NULL)
|
||||
{
|
||||
memset(op, 0, (size_t)occ);
|
||||
sp->read_error = 1;
|
||||
TIFFErrorExtR(tif, module, "Unable to allocate WebP decoder.");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -264,6 +290,10 @@ static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
|
||||
if (occ % sp->sDecBuffer.u.RGBA.stride)
|
||||
{
|
||||
// read_error not set here as this is a usage issue that can be
|
||||
// recovered in a following call.
|
||||
memset(op, 0, (size_t)occ);
|
||||
/* Do not set read_error as could potentially be recovered */
|
||||
TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -284,6 +314,8 @@ static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
{
|
||||
TIFFErrorExtR(tif, module, "Unrecognized error.");
|
||||
}
|
||||
memset(op, 0, (size_t)occ);
|
||||
sp->read_error = 1;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
|
|
@ -303,6 +335,8 @@ static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
{
|
||||
if (current_y != numberOfExpectedLines)
|
||||
{
|
||||
memset(op, 0, (size_t)occ);
|
||||
sp->read_error = 1;
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Unable to decode WebP data: less lines than "
|
||||
"expected.");
|
||||
|
|
@ -332,6 +366,8 @@ static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
}
|
||||
else
|
||||
{
|
||||
memset(op, 0, (size_t)occ);
|
||||
sp->read_error = 1;
|
||||
TIFFErrorExtR(tif, module, "Unable to decode WebP data.");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -451,6 +487,8 @@ static int TWebPPreDecode(TIFF *tif, uint16_t s)
|
|||
sp->psDecoder = NULL;
|
||||
}
|
||||
|
||||
sp->read_error = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
4
3rdparty/libtiff/tif_win32.c
vendored
4
3rdparty/libtiff/tif_win32.c
vendored
|
|
@ -27,6 +27,10 @@
|
|||
* Scott Wagner (wagner@itek.com), Itek Graphix, Rochester, NY USA
|
||||
*/
|
||||
|
||||
#ifdef TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS
|
||||
#undef TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS
|
||||
#endif
|
||||
|
||||
#include "tiffiop.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
|
|
|
|||
55
3rdparty/libtiff/tif_zip.c
vendored
55
3rdparty/libtiff/tif_zip.c
vendored
|
|
@ -67,6 +67,8 @@ typedef struct
|
|||
{
|
||||
TIFFPredictorState predict;
|
||||
z_stream stream;
|
||||
int read_error; /* whether a read error has occurred, and which should cause
|
||||
further reads in the same strip/tile to be aborted */
|
||||
int zipquality; /* compression level */
|
||||
int state; /* state flags */
|
||||
int subcodec; /* DEFLATE_SUBCODEC_ZLIB or DEFLATE_SUBCODEC_LIBDEFLATE */
|
||||
|
|
@ -83,9 +85,9 @@ typedef struct
|
|||
TIFFVSetMethod vsetparent; /* super-class method */
|
||||
} ZIPState;
|
||||
|
||||
#define ZState(tif) ((ZIPState *)(tif)->tif_data)
|
||||
#define DecoderState(tif) ZState(tif)
|
||||
#define EncoderState(tif) ZState(tif)
|
||||
#define GetZIPState(tif) ((ZIPState *)(tif)->tif_data)
|
||||
#define ZIPDecoderState(tif) GetZIPState(tif)
|
||||
#define ZIPEncoderState(tif) GetZIPState(tif)
|
||||
|
||||
static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s);
|
||||
static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s);
|
||||
|
|
@ -99,7 +101,7 @@ static int ZIPFixupTags(TIFF *tif)
|
|||
static int ZIPSetupDecode(TIFF *tif)
|
||||
{
|
||||
static const char module[] = "ZIPSetupDecode";
|
||||
ZIPState *sp = DecoderState(tif);
|
||||
ZIPState *sp = ZIPDecoderState(tif);
|
||||
|
||||
assert(sp != NULL);
|
||||
|
||||
|
|
@ -131,7 +133,7 @@ static int ZIPSetupDecode(TIFF *tif)
|
|||
*/
|
||||
static int ZIPPreDecode(TIFF *tif, uint16_t s)
|
||||
{
|
||||
ZIPState *sp = DecoderState(tif);
|
||||
ZIPState *sp = ZIPDecoderState(tif);
|
||||
|
||||
(void)s;
|
||||
assert(sp != NULL);
|
||||
|
|
@ -150,18 +152,33 @@ static int ZIPPreDecode(TIFF *tif, uint16_t s)
|
|||
sp->stream.avail_in = (uint64_t)tif->tif_rawcc < 0xFFFFFFFFU
|
||||
? (uInt)tif->tif_rawcc
|
||||
: 0xFFFFFFFFU;
|
||||
return (inflateReset(&sp->stream) == Z_OK);
|
||||
if (inflateReset(&sp->stream) == Z_OK)
|
||||
{
|
||||
sp->read_error = 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
{
|
||||
static const char module[] = "ZIPDecode";
|
||||
ZIPState *sp = DecoderState(tif);
|
||||
ZIPState *sp = ZIPDecoderState(tif);
|
||||
|
||||
(void)s;
|
||||
assert(sp != NULL);
|
||||
assert(sp->state == ZSTATE_INIT_DECODE);
|
||||
|
||||
if (sp->read_error)
|
||||
{
|
||||
memset(op, 0, (size_t)occ);
|
||||
TIFFErrorExtR(tif, module,
|
||||
"ZIPDecode: Scanline %" PRIu32 " cannot be read due to "
|
||||
"previous error",
|
||||
tif->tif_row);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if LIBDEFLATE_SUPPORT
|
||||
if (sp->libdeflate_state == 1)
|
||||
return 0;
|
||||
|
|
@ -227,8 +244,10 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
if (res != LIBDEFLATE_SUCCESS &&
|
||||
res != LIBDEFLATE_INSUFFICIENT_SPACE)
|
||||
{
|
||||
memset(op, 0, (size_t)occ);
|
||||
TIFFErrorExtR(tif, module, "Decoding error at scanline %lu",
|
||||
(unsigned long)tif->tif_row);
|
||||
sp->read_error = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -263,13 +282,17 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
break;
|
||||
if (state == Z_DATA_ERROR)
|
||||
{
|
||||
memset(sp->stream.next_out, 0, sp->stream.avail_out);
|
||||
TIFFErrorExtR(tif, module, "Decoding error at scanline %lu, %s",
|
||||
(unsigned long)tif->tif_row, SAFE_MSG(sp));
|
||||
sp->read_error = 1;
|
||||
return (0);
|
||||
}
|
||||
if (state != Z_OK)
|
||||
{
|
||||
memset(sp->stream.next_out, 0, sp->stream.avail_out);
|
||||
TIFFErrorExtR(tif, module, "ZLib error: %s", SAFE_MSG(sp));
|
||||
sp->read_error = 1;
|
||||
return (0);
|
||||
}
|
||||
} while (occ > 0);
|
||||
|
|
@ -279,6 +302,8 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
"Not enough data at scanline %lu (short %" PRIu64
|
||||
" bytes)",
|
||||
(unsigned long)tif->tif_row, (uint64_t)occ);
|
||||
memset(sp->stream.next_out, 0, sp->stream.avail_out);
|
||||
sp->read_error = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
@ -290,7 +315,7 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
static int ZIPSetupEncode(TIFF *tif)
|
||||
{
|
||||
static const char module[] = "ZIPSetupEncode";
|
||||
ZIPState *sp = EncoderState(tif);
|
||||
ZIPState *sp = ZIPEncoderState(tif);
|
||||
int cappedQuality;
|
||||
|
||||
assert(sp != NULL);
|
||||
|
|
@ -321,7 +346,7 @@ static int ZIPSetupEncode(TIFF *tif)
|
|||
*/
|
||||
static int ZIPPreEncode(TIFF *tif, uint16_t s)
|
||||
{
|
||||
ZIPState *sp = EncoderState(tif);
|
||||
ZIPState *sp = ZIPEncoderState(tif);
|
||||
|
||||
(void)s;
|
||||
assert(sp != NULL);
|
||||
|
|
@ -348,7 +373,7 @@ static int ZIPPreEncode(TIFF *tif, uint16_t s)
|
|||
static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
||||
{
|
||||
static const char module[] = "ZIPEncode";
|
||||
ZIPState *sp = EncoderState(tif);
|
||||
ZIPState *sp = ZIPEncoderState(tif);
|
||||
|
||||
assert(sp != NULL);
|
||||
assert(sp->state == ZSTATE_INIT_ENCODE);
|
||||
|
|
@ -487,7 +512,7 @@ static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
|||
static int ZIPPostEncode(TIFF *tif)
|
||||
{
|
||||
static const char module[] = "ZIPPostEncode";
|
||||
ZIPState *sp = EncoderState(tif);
|
||||
ZIPState *sp = ZIPEncoderState(tif);
|
||||
int state;
|
||||
|
||||
#if LIBDEFLATE_SUPPORT
|
||||
|
|
@ -526,7 +551,7 @@ static int ZIPPostEncode(TIFF *tif)
|
|||
|
||||
static void ZIPCleanup(TIFF *tif)
|
||||
{
|
||||
ZIPState *sp = ZState(tif);
|
||||
ZIPState *sp = GetZIPState(tif);
|
||||
|
||||
assert(sp != 0);
|
||||
|
||||
|
|
@ -562,7 +587,7 @@ static void ZIPCleanup(TIFF *tif)
|
|||
static int ZIPVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
{
|
||||
static const char module[] = "ZIPVSetField";
|
||||
ZIPState *sp = ZState(tif);
|
||||
ZIPState *sp = GetZIPState(tif);
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
|
|
@ -628,7 +653,7 @@ static int ZIPVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
|||
|
||||
static int ZIPVGetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
{
|
||||
ZIPState *sp = ZState(tif);
|
||||
ZIPState *sp = GetZIPState(tif);
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
|
|
@ -680,7 +705,7 @@ int TIFFInitZIP(TIFF *tif, int scheme)
|
|||
tif->tif_data = (uint8_t *)_TIFFcallocExt(tif, sizeof(ZIPState), 1);
|
||||
if (tif->tif_data == NULL)
|
||||
goto bad;
|
||||
sp = ZState(tif);
|
||||
sp = GetZIPState(tif);
|
||||
sp->stream.zalloc = NULL;
|
||||
sp->stream.zfree = NULL;
|
||||
sp->stream.opaque = NULL;
|
||||
|
|
|
|||
30
3rdparty/libtiff/tif_zstd.c
vendored
30
3rdparty/libtiff/tif_zstd.c
vendored
|
|
@ -54,9 +54,9 @@ typedef struct
|
|||
TIFFVSetMethod vsetparent; /* super-class method */
|
||||
} ZSTDState;
|
||||
|
||||
#define LState(tif) ((ZSTDState *)(tif)->tif_data)
|
||||
#define DecoderState(tif) LState(tif)
|
||||
#define EncoderState(tif) LState(tif)
|
||||
#define GetZSTDState(tif) ((ZSTDState *)(tif)->tif_data)
|
||||
#define ZSTDDecoderState(tif) GetZSTDState(tif)
|
||||
#define ZSTDEncoderState(tif) GetZSTDState(tif)
|
||||
|
||||
static int ZSTDEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s);
|
||||
static int ZSTDDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s);
|
||||
|
|
@ -69,7 +69,7 @@ static int ZSTDFixupTags(TIFF *tif)
|
|||
|
||||
static int ZSTDSetupDecode(TIFF *tif)
|
||||
{
|
||||
ZSTDState *sp = DecoderState(tif);
|
||||
ZSTDState *sp = ZSTDDecoderState(tif);
|
||||
|
||||
assert(sp != NULL);
|
||||
|
||||
|
|
@ -91,7 +91,7 @@ static int ZSTDSetupDecode(TIFF *tif)
|
|||
static int ZSTDPreDecode(TIFF *tif, uint16_t s)
|
||||
{
|
||||
static const char module[] = "ZSTDPreDecode";
|
||||
ZSTDState *sp = DecoderState(tif);
|
||||
ZSTDState *sp = ZSTDDecoderState(tif);
|
||||
size_t zstd_ret;
|
||||
|
||||
(void)s;
|
||||
|
|
@ -124,7 +124,7 @@ static int ZSTDPreDecode(TIFF *tif, uint16_t s)
|
|||
static int ZSTDDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
{
|
||||
static const char module[] = "ZSTDDecode";
|
||||
ZSTDState *sp = DecoderState(tif);
|
||||
ZSTDState *sp = ZSTDDecoderState(tif);
|
||||
ZSTD_inBuffer in_buffer;
|
||||
ZSTD_outBuffer out_buffer;
|
||||
size_t zstd_ret;
|
||||
|
|
@ -146,6 +146,7 @@ static int ZSTDDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
zstd_ret = ZSTD_decompressStream(sp->dstream, &out_buffer, &in_buffer);
|
||||
if (ZSTD_isError(zstd_ret))
|
||||
{
|
||||
memset(op + out_buffer.pos, 0, out_buffer.size - out_buffer.pos);
|
||||
TIFFErrorExtR(tif, module, "Error in ZSTD_decompressStream(): %s",
|
||||
ZSTD_getErrorName(zstd_ret));
|
||||
return 0;
|
||||
|
|
@ -155,6 +156,7 @@ static int ZSTDDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
|
||||
if (out_buffer.pos < (size_t)occ)
|
||||
{
|
||||
memset(op + out_buffer.pos, 0, out_buffer.size - out_buffer.pos);
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Not enough data at scanline %lu (short %lu bytes)",
|
||||
(unsigned long)tif->tif_row,
|
||||
|
|
@ -170,7 +172,7 @@ static int ZSTDDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
|||
|
||||
static int ZSTDSetupEncode(TIFF *tif)
|
||||
{
|
||||
ZSTDState *sp = EncoderState(tif);
|
||||
ZSTDState *sp = ZSTDEncoderState(tif);
|
||||
|
||||
assert(sp != NULL);
|
||||
if (sp->state & LSTATE_INIT_DECODE)
|
||||
|
|
@ -190,7 +192,7 @@ static int ZSTDSetupEncode(TIFF *tif)
|
|||
static int ZSTDPreEncode(TIFF *tif, uint16_t s)
|
||||
{
|
||||
static const char module[] = "ZSTDPreEncode";
|
||||
ZSTDState *sp = EncoderState(tif);
|
||||
ZSTDState *sp = ZSTDEncoderState(tif);
|
||||
size_t zstd_ret;
|
||||
|
||||
(void)s;
|
||||
|
|
@ -229,7 +231,7 @@ static int ZSTDPreEncode(TIFF *tif, uint16_t s)
|
|||
static int ZSTDEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
||||
{
|
||||
static const char module[] = "ZSTDEncode";
|
||||
ZSTDState *sp = EncoderState(tif);
|
||||
ZSTDState *sp = ZSTDEncoderState(tif);
|
||||
ZSTD_inBuffer in_buffer;
|
||||
size_t zstd_ret;
|
||||
|
||||
|
|
@ -271,7 +273,7 @@ static int ZSTDEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
|||
static int ZSTDPostEncode(TIFF *tif)
|
||||
{
|
||||
static const char module[] = "ZSTDPostEncode";
|
||||
ZSTDState *sp = EncoderState(tif);
|
||||
ZSTDState *sp = ZSTDEncoderState(tif);
|
||||
size_t zstd_ret;
|
||||
|
||||
do
|
||||
|
|
@ -297,7 +299,7 @@ static int ZSTDPostEncode(TIFF *tif)
|
|||
|
||||
static void ZSTDCleanup(TIFF *tif)
|
||||
{
|
||||
ZSTDState *sp = LState(tif);
|
||||
ZSTDState *sp = GetZSTDState(tif);
|
||||
|
||||
assert(sp != 0);
|
||||
|
||||
|
|
@ -325,7 +327,7 @@ static void ZSTDCleanup(TIFF *tif)
|
|||
static int ZSTDVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
{
|
||||
static const char module[] = "ZSTDVSetField";
|
||||
ZSTDState *sp = LState(tif);
|
||||
ZSTDState *sp = GetZSTDState(tif);
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
|
|
@ -347,7 +349,7 @@ static int ZSTDVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
|||
|
||||
static int ZSTDVGetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
{
|
||||
ZSTDState *sp = LState(tif);
|
||||
ZSTDState *sp = GetZSTDState(tif);
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
|
|
@ -389,7 +391,7 @@ int TIFFInitZSTD(TIFF *tif, int scheme)
|
|||
tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(ZSTDState));
|
||||
if (tif->tif_data == NULL)
|
||||
goto bad;
|
||||
sp = LState(tif);
|
||||
sp = GetZSTDState(tif);
|
||||
|
||||
/*
|
||||
* Override parent get/set field methods.
|
||||
|
|
|
|||
22
3rdparty/libtiff/tiffio.h
vendored
22
3rdparty/libtiff/tiffio.h
vendored
|
|
@ -77,10 +77,6 @@ typedef tstrile_t ttile_t; /* tile number */
|
|||
typedef tmsize_t tsize_t; /* i/o size in bytes */
|
||||
typedef void *tdata_t; /* image data ref */
|
||||
|
||||
#if !defined(__WIN32__) && (defined(_WIN32) || defined(WIN32))
|
||||
#define __WIN32__
|
||||
#endif
|
||||
|
||||
/*
|
||||
* On windows you should define USE_WIN32_FILEIO if you are using tif_win32.c
|
||||
* or AVOID_WIN32_FILEIO if you are using something else (like tif_unix.c).
|
||||
|
|
@ -88,7 +84,7 @@ typedef void *tdata_t; /* image data ref */
|
|||
* By default tif_unix.c is assumed.
|
||||
*/
|
||||
|
||||
#if defined(_WINDOWS) || defined(__WIN32__) || defined(_Windows)
|
||||
#if defined(_WIN32)
|
||||
#if !defined(__CYGWIN) && !defined(AVOID_WIN32_FILEIO) && \
|
||||
!defined(USE_WIN32_FILEIO)
|
||||
#define AVOID_WIN32_FILEIO
|
||||
|
|
@ -98,11 +94,11 @@ typedef void *tdata_t; /* image data ref */
|
|||
#if defined(USE_WIN32_FILEIO)
|
||||
#define VC_EXTRALEAN
|
||||
#include <windows.h>
|
||||
#ifdef __WIN32__
|
||||
#ifdef _WIN32
|
||||
DECLARE_HANDLE(thandle_t); /* Win32 file handle */
|
||||
#else
|
||||
typedef HFILE thandle_t; /* client data handle */
|
||||
#endif /* __WIN32__ */
|
||||
#endif /* _WIN32 */
|
||||
#else
|
||||
typedef void *thandle_t; /* client data handle */
|
||||
#endif /* USE_WIN32_FILEIO */
|
||||
|
|
@ -311,14 +307,15 @@ extern "C"
|
|||
/*
|
||||
* Auxiliary functions.
|
||||
*/
|
||||
|
||||
#ifndef TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS
|
||||
extern void *_TIFFmalloc(tmsize_t s);
|
||||
extern void *_TIFFcalloc(tmsize_t nmemb, tmsize_t siz);
|
||||
extern void *_TIFFrealloc(void *p, tmsize_t s);
|
||||
extern void _TIFFfree(void *p);
|
||||
#endif
|
||||
extern void _TIFFmemset(void *p, int v, tmsize_t c);
|
||||
extern void _TIFFmemcpy(void *d, const void *s, tmsize_t c);
|
||||
extern int _TIFFmemcmp(const void *p1, const void *p2, tmsize_t c);
|
||||
extern void _TIFFfree(void *p);
|
||||
|
||||
/*
|
||||
** Stuff, related to tag handling and creating custom tags.
|
||||
|
|
@ -508,6 +505,9 @@ extern int TIFFReadRGBAImageOriented(TIFF *, uint32_t, uint32_t, uint32_t *,
|
|||
TIFFOpenOptionsSetMaxSingleMemAlloc(TIFFOpenOptions *opts,
|
||||
tmsize_t max_single_mem_alloc);
|
||||
extern void
|
||||
TIFFOpenOptionsSetMaxCumulatedMemAlloc(TIFFOpenOptions *opts,
|
||||
tmsize_t max_cumulated_mem_alloc);
|
||||
extern void
|
||||
TIFFOpenOptionsSetErrorHandlerExtR(TIFFOpenOptions *opts,
|
||||
TIFFErrorHandlerExtR handler,
|
||||
void *errorhandler_user_data);
|
||||
|
|
@ -518,11 +518,11 @@ extern int TIFFReadRGBAImageOriented(TIFF *, uint32_t, uint32_t, uint32_t *,
|
|||
|
||||
extern TIFF *TIFFOpen(const char *, const char *);
|
||||
extern TIFF *TIFFOpenExt(const char *, const char *, TIFFOpenOptions *opts);
|
||||
#ifdef __WIN32__
|
||||
#ifdef _WIN32
|
||||
extern TIFF *TIFFOpenW(const wchar_t *, const char *);
|
||||
extern TIFF *TIFFOpenWExt(const wchar_t *, const char *,
|
||||
TIFFOpenOptions *opts);
|
||||
#endif /* __WIN32__ */
|
||||
#endif /* _WIN32 */
|
||||
extern TIFF *TIFFFdOpen(int, const char *, const char *);
|
||||
extern TIFF *TIFFFdOpenExt(int, const char *, const char *,
|
||||
TIFFOpenOptions *opts);
|
||||
|
|
|
|||
52
3rdparty/libtiff/tiffiop.h
vendored
52
3rdparty/libtiff/tiffiop.h
vendored
|
|
@ -102,6 +102,13 @@ struct TIFFOffsetAndDirNumber
|
|||
};
|
||||
typedef struct TIFFOffsetAndDirNumber TIFFOffsetAndDirNumber;
|
||||
|
||||
typedef union
|
||||
{
|
||||
TIFFHeaderCommon common;
|
||||
TIFFHeaderClassic classic;
|
||||
TIFFHeaderBig big;
|
||||
} TIFFHeaderUnion;
|
||||
|
||||
struct tiff
|
||||
{
|
||||
char *tif_name; /* name of open file */
|
||||
|
|
@ -153,20 +160,35 @@ struct tiff
|
|||
TIFFDirectory tif_dir; /* internal rep of current directory */
|
||||
TIFFDirectory
|
||||
tif_customdir; /* custom IFDs are separated from the main ones */
|
||||
union
|
||||
{
|
||||
TIFFHeaderCommon common;
|
||||
TIFFHeaderClassic classic;
|
||||
TIFFHeaderBig big;
|
||||
} tif_header;
|
||||
uint16_t tif_header_size; /* file's header block and its length */
|
||||
uint32_t tif_row; /* current scanline */
|
||||
tdir_t tif_curdir; /* current directory (index) */
|
||||
TIFFHeaderUnion tif_header; /* file's header block Classic/BigTIFF union */
|
||||
uint16_t tif_header_size; /* file's header block and its length */
|
||||
uint32_t tif_row; /* current scanline */
|
||||
|
||||
/* There are IFDs in the file and an "active" IFD in memory,
|
||||
* from which fields are "set" and "get".
|
||||
* tif_curdir is set to:
|
||||
* a) TIFF_NON_EXISTENT_DIR_NUMBER if there is no IFD in the file
|
||||
* or the state is unknown,
|
||||
* or the last read (i.e. TIFFFetchDirectory()) failed,
|
||||
* or a custom directory was written.
|
||||
* b) IFD index of last IFD written in the file. In this case the
|
||||
* active IFD is a new (empty) one and tif_diroff is zero.
|
||||
* If writing fails, tif_curdir is not changed.
|
||||
* c) IFD index of IFD read from file into memory (=active IFD),
|
||||
* even if IFD is corrupt and TIFFReadDirectory() returns 0.
|
||||
* Then tif_diroff contains the offset of the IFD in the file.
|
||||
* d) IFD index 0, whenever a custom directory or an unchained SubIFD
|
||||
* was read. */
|
||||
tdir_t tif_curdir; /* current directory (index) */
|
||||
/* tif_curdircount: number of directories (main-IFDs) in file:
|
||||
* - TIFF_NON_EXISTENT_DIR_NUMBER means 'dont know number of IFDs'.
|
||||
* - 0 means 'empty file opened for writing, but no IFD written yet' */
|
||||
tdir_t tif_curdircount;
|
||||
uint32_t tif_curstrip; /* current strip for read/write */
|
||||
uint64_t tif_curoff; /* current offset for read/write */
|
||||
uint64_t tif_lastvalidoff; /* last valid offset allowed for rewrite in
|
||||
place. Used only by TIFFAppendToStrip() */
|
||||
uint64_t tif_dataoff; /* current offset for writing dir */
|
||||
uint64_t tif_dataoff; /* current offset for writing dir (IFD) */
|
||||
/* SubIFD support */
|
||||
uint16_t tif_nsubifd; /* remaining subifds to write */
|
||||
uint64_t tif_subifdoff; /* offset for patching SubIFD link */
|
||||
|
|
@ -233,7 +255,9 @@ struct tiff
|
|||
void *tif_errorhandler_user_data;
|
||||
TIFFErrorHandlerExtR tif_warnhandler;
|
||||
void *tif_warnhandler_user_data;
|
||||
tmsize_t tif_max_single_mem_alloc; /* in bytes. 0 for unlimited */
|
||||
tmsize_t tif_max_single_mem_alloc; /* in bytes. 0 for unlimited */
|
||||
tmsize_t tif_max_cumulated_mem_alloc; /* in bytes. 0 for unlimited */
|
||||
tmsize_t tif_cur_cumulated_mem_alloc; /* in bytes */
|
||||
};
|
||||
|
||||
struct TIFFOpenOptions
|
||||
|
|
@ -243,6 +267,7 @@ struct TIFFOpenOptions
|
|||
TIFFErrorHandlerExtR warnhandler; /* may be NULL */
|
||||
void *warnhandler_user_data; /* may be NULL */
|
||||
tmsize_t max_single_mem_alloc; /* in bytes. 0 for unlimited */
|
||||
tmsize_t max_cumulated_mem_alloc; /* in bytes. 0 for unlimited */
|
||||
};
|
||||
|
||||
#define isPseudoTag(t) (t > 0xffff) /* is tag value normal or pseudo */
|
||||
|
|
@ -331,7 +356,7 @@ struct TIFFOpenOptions
|
|||
#define ftell(stream, offset, whence) ftello(stream, offset, whence)
|
||||
#endif
|
||||
#endif
|
||||
#if defined(__WIN32__) && !(defined(_MSC_VER) && _MSC_VER < 1400) && \
|
||||
#if defined(_WIN32) && \
|
||||
!(defined(__MSVCRT_VERSION__) && __MSVCRT_VERSION__ < 0x800)
|
||||
typedef unsigned int TIFFIOSize_t;
|
||||
#define _TIFF_lseek_f(fildes, offset, whence) \
|
||||
|
|
@ -437,9 +462,6 @@ extern "C"
|
|||
extern void *_TIFFCheckRealloc(TIFF *, void *, tmsize_t, tmsize_t,
|
||||
const char *);
|
||||
|
||||
extern double _TIFFUInt64ToDouble(uint64_t);
|
||||
extern float _TIFFUInt64ToFloat(uint64_t);
|
||||
|
||||
extern float _TIFFClampDoubleToFloat(double);
|
||||
extern uint32_t _TIFFClampDoubleToUInt32(double);
|
||||
|
||||
|
|
|
|||
|
|
@ -574,6 +574,7 @@ ocv_cmake_hook(POST_CMAKE_BUILD_OPTIONS)
|
|||
# --- Python Support ---
|
||||
if(NOT IOS AND NOT XROS)
|
||||
include(cmake/OpenCVDetectPython.cmake)
|
||||
include(cmake/OpenCVDetectDLPack.cmake)
|
||||
endif()
|
||||
|
||||
include(cmake/OpenCVCompilerOptions.cmake)
|
||||
|
|
|
|||
|
|
@ -31,6 +31,9 @@ CalibPipeline::CalibPipeline(captureParameters params) :
|
|||
|
||||
PipelineExitStatus CalibPipeline::start(std::vector<cv::Ptr<FrameProcessor> > processors)
|
||||
{
|
||||
const int allowedEmptyFrames = 5;
|
||||
int emptyFrames = 0;
|
||||
|
||||
auto open_camera = [this] () {
|
||||
if(mCaptureParams.source == Camera)
|
||||
{
|
||||
|
|
@ -87,6 +90,22 @@ PipelineExitStatus CalibPipeline::start(std::vector<cv::Ptr<FrameProcessor> > pr
|
|||
CV_CheckEQ(mImageSize, newSize, "Camera image size changed after reopening.");
|
||||
}
|
||||
mCapture.retrieve(frame);
|
||||
|
||||
if (frame.empty()) {
|
||||
emptyFrames++;
|
||||
if (emptyFrames >= allowedEmptyFrames) {
|
||||
CV_LOG_ERROR(NULL, "VideoCapture error: grabbed sequence of empty frames. VideoCapture is not ready or broken.");
|
||||
return Finished;
|
||||
}
|
||||
|
||||
continue;
|
||||
} else {
|
||||
emptyFrames = 0;
|
||||
if (mImageSize.width == 0 || mImageSize.height == 0) { // looks like VideoCapture does not support required properties
|
||||
mImageSize = frame.size();
|
||||
}
|
||||
}
|
||||
|
||||
if(mCaptureParams.flipVertical)
|
||||
cv::flip(frame, frame, -1);
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ macro(ocv_initialize_nvidia_device_generations)
|
|||
set(_arch_ampere "8.0;8.6")
|
||||
set(_arch_lovelace "8.9")
|
||||
set(_arch_hopper "9.0")
|
||||
set(_arch_blackwell "10.0;12.0")
|
||||
set(_arch_blackwell "10.0;10.3;11.0;12.0;12.1")
|
||||
if(NOT CMAKE_CROSSCOMPILING)
|
||||
list(APPEND _generations "Auto")
|
||||
endif()
|
||||
|
|
@ -271,14 +271,15 @@ macro(ocv_set_cuda_arch_bin_and_ptx nvcc_executable)
|
|||
endif()
|
||||
if(NOT _nvcc_res EQUAL 0)
|
||||
message(STATUS "CUDA: Automatic detection of CUDA generation failed. Going to build for all known architectures")
|
||||
# TX1 (5.3) TX2 (6.2) Xavier (7.2) V100 (7.0) Orin (8.7) Thor (10.1)
|
||||
# TX1 (5.3) TX2 (6.2) Xavier (7.2) V100 (7.0) Orin (8.7) Thor (11.0) Spark (12.1)
|
||||
ocv_filter_available_architecture(${nvcc_executable} __cuda_arch_bin
|
||||
5.3
|
||||
6.2
|
||||
7.2
|
||||
7.0
|
||||
8.7
|
||||
10.1
|
||||
11.0
|
||||
12.1
|
||||
)
|
||||
else()
|
||||
set(__cuda_arch_bin "${_nvcc_out}")
|
||||
|
|
|
|||
5
cmake/OpenCVDetectDLPack.cmake
Normal file
5
cmake/OpenCVDetectDLPack.cmake
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
find_package(dlpack QUIET)
|
||||
if (NOT dlpack_FOUND)
|
||||
ocv_include_directories("${OpenCV_SOURCE_DIR}/3rdparty/dlpack/include")
|
||||
ocv_install_3rdparty_licenses(dlpack "${OpenCV_SOURCE_DIR}/3rdparty/dlpack/LICENSE")
|
||||
endif()
|
||||
|
|
@ -42,7 +42,7 @@ target_include_directories(ipphal PRIVATE
|
|||
|
||||
target_link_libraries(ipphal PUBLIC ${IPP_IW_LIBRARY} ${IPP_LIBRARIES})
|
||||
|
||||
set_target_properties(ipphal PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH})
|
||||
set_target_properties(ipphal PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH} DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}")
|
||||
|
||||
if(NOT BUILD_SHARED_LIBS)
|
||||
ocv_install_target(ipphal EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
|
||||
|
|
|
|||
|
|
@ -243,6 +243,29 @@ int integral(int depth, int sdepth, int sqdepth,
|
|||
//#undef cv_hal_integral
|
||||
//#define cv_hal_integral cv::rvv_hal::imgproc::integral
|
||||
|
||||
/* ############ scharr ############ */
|
||||
int scharr(const uint8_t *src_data, size_t src_step, uint8_t *dst_data, size_t dst_step, int width, int height, int src_depth, int dst_depth, int cn, int margin_left, int margin_top, int margin_right, int margin_bottom, int dx, int dy, double scale, double delta, int border_type);
|
||||
|
||||
#undef cv_hal_scharr
|
||||
#define cv_hal_scharr cv::rvv_hal::imgproc::scharr
|
||||
|
||||
/* ############ sobel ############ */
|
||||
|
||||
int sobel(const uint8_t *src_data, size_t src_step, uint8_t *dst_data, size_t dst_step, int width, int height, int src_depth, int dst_depth, int cn, int margin_left, int margin_top, int margin_right, int margin_bottom, int dx, int dy, int ksize, double scale, double delta, int border_type);
|
||||
|
||||
#undef cv_hal_sobel
|
||||
#define cv_hal_sobel cv::rvv_hal::imgproc::sobel
|
||||
|
||||
/* ############ canny ############ */
|
||||
int canny(const uint8_t *src_data, size_t src_step,
|
||||
uint8_t *dst_data, size_t dst_step,
|
||||
int width, int height, int cn,
|
||||
double low_thresh, double high_thresh,
|
||||
int ksize, bool L2gradient);
|
||||
|
||||
#undef cv_hal_canny
|
||||
#define cv_hal_canny cv::rvv_hal::imgproc::canny
|
||||
|
||||
#endif // CV_HAL_RVV_1P0_ENABLED
|
||||
|
||||
#if CV_HAL_RVV_071_ENABLED
|
||||
|
|
|
|||
426
hal/riscv-rvv/src/imgproc/canny.cpp
Normal file
426
hal/riscv-rvv/src/imgproc/canny.cpp
Normal file
|
|
@ -0,0 +1,426 @@
|
|||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
// Copyright (C) 2025, SpaceMIT Inc., all rights reserved.
|
||||
|
||||
#include "rvv_hal.hpp"
|
||||
#include "common.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace rvv_hal
|
||||
{
|
||||
namespace imgproc
|
||||
{
|
||||
#if CV_HAL_RVV_1P0_ENABLED
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int *buffer;
|
||||
int *prev;
|
||||
int *curr;
|
||||
int *next;
|
||||
size_t size;
|
||||
} LineBuffer;
|
||||
|
||||
LineBuffer *createLineBuffer(size_t width, size_t align);
|
||||
|
||||
void rotateLineBuffer(LineBuffer *buf);
|
||||
|
||||
void freeLineBuffer(LineBuffer *buf);
|
||||
|
||||
LineBuffer *createLineBuffer(size_t width, size_t align)
|
||||
{
|
||||
LineBuffer *buf = (LineBuffer *)malloc(sizeof(LineBuffer));
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
size_t aligned_width = ((width + align - 1) & ~(align - 1));
|
||||
buf->buffer = (int *)aligned_alloc(align, 3 * aligned_width * sizeof(int));
|
||||
if (!buf->buffer)
|
||||
{
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf->prev = buf->buffer;
|
||||
buf->curr = buf->prev + aligned_width;
|
||||
buf->next = buf->curr + aligned_width;
|
||||
buf->size = aligned_width;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void rotateLineBuffer(LineBuffer *buf)
|
||||
{
|
||||
int *temp = buf->prev;
|
||||
buf->prev = buf->curr;
|
||||
buf->curr = buf->next;
|
||||
buf->next = temp;
|
||||
}
|
||||
|
||||
void freeLineBuffer(LineBuffer *buf)
|
||||
{
|
||||
if (buf)
|
||||
{
|
||||
free(buf->buffer);
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t **data;
|
||||
int capacity;
|
||||
int size;
|
||||
} Stack;
|
||||
|
||||
static Stack *canny_createStack(int capacity);
|
||||
static void canny_push(Stack *stack, uint8_t *item);
|
||||
static uint8_t *canny_pop(Stack *stack);
|
||||
static void freeStack(Stack *stack);
|
||||
|
||||
static Stack *canny_createStack(int capacity)
|
||||
{
|
||||
Stack *stack = (Stack *)malloc(sizeof(Stack));
|
||||
stack->data = (uint8_t **)malloc(capacity * sizeof(uint8_t *));
|
||||
stack->capacity = capacity;
|
||||
stack->size = 0;
|
||||
return stack;
|
||||
}
|
||||
|
||||
static void canny_push(Stack *stack, uint8_t *item)
|
||||
{
|
||||
if (stack->size < stack->capacity)
|
||||
{
|
||||
stack->data[stack->size++] = item;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t *canny_pop(Stack *stack)
|
||||
{
|
||||
if (stack->size > 0)
|
||||
{
|
||||
return stack->data[--stack->size];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void freeStack(Stack *stack)
|
||||
{
|
||||
free(stack->data);
|
||||
free(stack);
|
||||
}
|
||||
|
||||
int sobel(const uint8_t *src_data, size_t src_step, uint8_t *dst_data, size_t dst_step, int width, int height, int src_depth, int dst_depth, int cn, int margin_left, int margin_top, int margin_right, int margin_bottom, int dx, int dy, int ksize, double scale, double delta, int border_type);
|
||||
|
||||
int canny(const uint8_t *src_data, size_t src_step,
|
||||
uint8_t *dst_data, size_t dst_step,
|
||||
int width, int height, int cn,
|
||||
double low_thresh, double high_thresh,
|
||||
int ksize, bool L2gradient)
|
||||
{
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (cn != 1 || (ksize != 3 && ksize != 5))
|
||||
{
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (L2gradient)
|
||||
{
|
||||
low_thresh = 32767.0 < low_thresh ? 32767.0 : low_thresh;
|
||||
high_thresh = 32767.0 < high_thresh ? 32767.0 : high_thresh;
|
||||
|
||||
if (low_thresh > 0)
|
||||
low_thresh *= low_thresh;
|
||||
if (high_thresh > 0)
|
||||
high_thresh *= high_thresh;
|
||||
}
|
||||
|
||||
int low = (int)low_thresh;
|
||||
low_thresh = low - (low > low_thresh);
|
||||
int high = (int)high_thresh;
|
||||
high_thresh = high - (high > high_thresh);
|
||||
|
||||
int16_t *dx_data = (int16_t *)malloc(height * width * sizeof(int16_t));
|
||||
int16_t *dy_data = (int16_t *)malloc(height * width * sizeof(int16_t));
|
||||
if (!dx_data || !dy_data)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
const size_t grad_step = width * sizeof(int16_t);
|
||||
|
||||
int ret = sobel(src_data, src_step, (uint8_t *)dx_data, grad_step,
|
||||
width, height, CV_8U, CV_16S, 1,
|
||||
0, 0, 0, 0, 1, 0, ksize, 1.0, 0.0, BORDER_REPLICATE);
|
||||
if (ret != CV_HAL_ERROR_OK)
|
||||
{
|
||||
free(dx_data);
|
||||
free(dy_data);
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ret = sobel(src_data, src_step, (uint8_t *)dy_data, grad_step,
|
||||
width, height, CV_8U, CV_16S, 1,
|
||||
0, 0, 0, 0, 0, 1, ksize, 1.0, 0.0, BORDER_REPLICATE);
|
||||
if (ret != CV_HAL_ERROR_OK)
|
||||
{
|
||||
free(dx_data);
|
||||
free(dy_data);
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
const int mapstep = width + 2;
|
||||
const size_t mapsize = (height + 2) * mapstep;
|
||||
uint8_t *edge_map = (uint8_t *)calloc(mapsize, sizeof(uint8_t));
|
||||
if (!edge_map)
|
||||
{
|
||||
free(dx_data);
|
||||
free(dy_data);
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
Stack *stack = canny_createStack(width * height);
|
||||
Stack *borderPeaksLocal = canny_createStack(width * height);
|
||||
if (!stack || !borderPeaksLocal)
|
||||
{
|
||||
free(dx_data);
|
||||
free(dy_data);
|
||||
free(edge_map);
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
memset(edge_map, 1, mapstep);
|
||||
memset(edge_map + (height + 1) * mapstep, 1, mapstep);
|
||||
|
||||
for (int i = 1; i <= height; i++)
|
||||
{
|
||||
edge_map[i * mapstep] = 1;
|
||||
edge_map[i * mapstep + width + 1] = 1;
|
||||
}
|
||||
|
||||
uint8_t *map = edge_map + mapstep + 1;
|
||||
|
||||
const int simd_align = 16;
|
||||
LineBuffer *lineBuf = createLineBuffer(width, simd_align);
|
||||
if (!lineBuf)
|
||||
{
|
||||
free(dx_data);
|
||||
free(dy_data);
|
||||
free(edge_map);
|
||||
freeStack(stack);
|
||||
freeStack(borderPeaksLocal);
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
const int TG22 = 13573;
|
||||
for (int i = 0; i <= height; i++)
|
||||
{
|
||||
if (i < height)
|
||||
{
|
||||
int16_t *dx = (int16_t *)(dx_data + i * width);
|
||||
int16_t *dy = (int16_t *)(dy_data + i * width);
|
||||
|
||||
if (L2gradient)
|
||||
{
|
||||
size_t vl = 0;
|
||||
for (int j = 0; j < width; j += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e32m8(width - j);
|
||||
vint32m8_t vdx = __riscv_vwcvt_x_x_v_i32m8(__riscv_vle16_v_i16m4(dx + j, vl), vl);
|
||||
vint32m8_t vdy = __riscv_vwcvt_x_x_v_i32m8(__riscv_vle16_v_i16m4(dy + j, vl), vl);
|
||||
vint32m8_t vres = __riscv_vmul_vv_i32m8(vdx, vdx, vl);
|
||||
vres = __riscv_vmacc_vv_i32m8(vres, vdy, vdy, vl);
|
||||
__riscv_vse32_v_i32m8(lineBuf->next + j, vres, vl);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t vl = 0;
|
||||
for (int j = 0; j < width; j += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e32m8(width - j);
|
||||
vint32m8_t vdx = __riscv_vwcvt_x_x_v_i32m8(__riscv_vle16_v_i16m4(dx + j, vl), vl);
|
||||
vint32m8_t vdy = __riscv_vwcvt_x_x_v_i32m8(__riscv_vle16_v_i16m4(dy + j, vl), vl);
|
||||
vbool4_t mask = __riscv_vmslt_vx_i32m8_b4(vdx, 0, vl);
|
||||
vdx = __riscv_vmul_vx_i32m8_m(mask, vdx, -1, vl);
|
||||
mask = __riscv_vmslt_vx_i32m8_b4(vdy, 0, vl);
|
||||
vdy = __riscv_vmul_vx_i32m8_m(mask, vdy, -1, vl);
|
||||
vint32m8_t vres = __riscv_vadd_vv_i32m8(vdx, vdy, vl);
|
||||
__riscv_vse32_v_i32m8(lineBuf->next + j, vres, vl);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(lineBuf->next, 0, width * sizeof(int));
|
||||
}
|
||||
|
||||
uint8_t *pmap = map + i * mapstep;
|
||||
|
||||
int16_t *dx = (int16_t *)(dx_data + i * width);
|
||||
int16_t *dy = (int16_t *)(dy_data + i * width);
|
||||
|
||||
size_t vl = 0;
|
||||
for (int j = 0; j < width; j += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e32m8(width - j);
|
||||
|
||||
vint32m8_t vm = __riscv_vle32_v_i32m8(lineBuf->curr + j, vl);
|
||||
|
||||
vint32m8_t vdx = __riscv_vwcvt_x_x_v_i32m8(__riscv_vle16_v_i16m4(dx + j, vl), vl);
|
||||
vint32m8_t vdy = __riscv_vwcvt_x_x_v_i32m8(__riscv_vle16_v_i16m4(dy + j, vl), vl);
|
||||
|
||||
vbool4_t mask_dx = __riscv_vmslt_vx_i32m8_b4(vdx, 0, vl);
|
||||
vbool4_t mask_dy = __riscv_vmslt_vx_i32m8_b4(vdy, 0, vl);
|
||||
vint32m8_t vdx_abs = __riscv_vmul_vx_i32m8_m(mask_dx, vdx, -1, vl);
|
||||
vint32m8_t vdy_abs = __riscv_vmul_vx_i32m8_m(mask_dy, vdy, -1, vl);
|
||||
|
||||
vdy_abs = __riscv_vsll_vx_i32m8(vdy_abs, 15, vl);
|
||||
|
||||
// Calculate threshold values
|
||||
vint32m8_t vtg22x = __riscv_vmul_vx_i32m8(vdx_abs, TG22, vl);
|
||||
vint32m8_t vtg67x = __riscv_vadd_vv_i32m8(vtg22x, __riscv_vsll_vx_i32m8(vdx_abs, 16, vl), vl);
|
||||
|
||||
// Create masks for different angle ranges
|
||||
vbool4_t mask1 = __riscv_vmslt_vv_i32m8_b4(vdy_abs, vtg22x, vl);
|
||||
vbool4_t mask2 = __riscv_vmsgt_vv_i32m8_b4(vdy_abs, vtg67x, vl);
|
||||
vbool4_t mask3 = __riscv_vmnot_m_b4(__riscv_vmor_mm_b4(mask1, mask2, vl), vl);
|
||||
|
||||
// Load neighbor pixels for all conditions
|
||||
vint32m8_t prev_curr = __riscv_vle32_v_i32m8(lineBuf->curr + (j > 0 ? j - 1 : j), vl);
|
||||
vint32m8_t next_curr = __riscv_vle32_v_i32m8(lineBuf->curr + j + 1, vl);
|
||||
vint32m8_t prev_line = __riscv_vle32_v_i32m8(lineBuf->prev + j, vl);
|
||||
vint32m8_t next_line = __riscv_vle32_v_i32m8(lineBuf->next + j, vl);
|
||||
|
||||
// Condition 1: Horizontal/Vertical edges (compare left/right)
|
||||
vbool4_t cond1_max = __riscv_vmand_mm_b4(
|
||||
__riscv_vmsgt_vv_i32m8_b4(vm, prev_curr, vl),
|
||||
__riscv_vmsge_vv_i32m8_b4(vm, next_curr, vl),
|
||||
vl);
|
||||
|
||||
// Condition 2: Diagonal edges (compare top/bottom)
|
||||
vbool4_t cond2_max = __riscv_vmand_mm_b4(
|
||||
__riscv_vmsgt_vv_i32m8_b4(vm, prev_line, vl),
|
||||
__riscv_vmsge_vv_i32m8_b4(vm, next_line, vl),
|
||||
vl);
|
||||
|
||||
// Condition 3: Other diagonals (calculate s)
|
||||
vint32m8_t vxor = __riscv_vxor_vv_i32m8(vdx, vdy, vl);
|
||||
vbool4_t s_mask = __riscv_vmslt_vx_i32m8_b4(vxor, 0, vl);
|
||||
|
||||
vint32m8_t prev_s1 = __riscv_vle32_v_i32m8(lineBuf->prev + (j > 0 ? j - 1 : j), vl);
|
||||
vint32m8_t prev_s2 = __riscv_vle32_v_i32m8(lineBuf->prev + j + 1, vl);
|
||||
vint32m8_t next_s1 = __riscv_vle32_v_i32m8(lineBuf->next + j + 1, vl);
|
||||
vint32m8_t next_s2 = __riscv_vle32_v_i32m8(lineBuf->next + (j > 0 ? j - 1 : j), vl);
|
||||
|
||||
vint32m8_t prev_sel = __riscv_vmerge_vvm_i32m8(prev_s1, prev_s2, s_mask, vl);
|
||||
vint32m8_t next_sel = __riscv_vmerge_vvm_i32m8(next_s1, next_s2, s_mask, vl);
|
||||
|
||||
vbool4_t cond3_max = __riscv_vmand_mm_b4(
|
||||
__riscv_vmsgt_vv_i32m8_b4(vm, prev_sel, vl),
|
||||
__riscv_vmsgt_vv_i32m8_b4(vm, next_sel, vl),
|
||||
vl);
|
||||
|
||||
// Combine results from all conditions
|
||||
vbool4_t vmax = __riscv_vmor_mm_b4(
|
||||
__riscv_vmand_mm_b4(mask1, cond1_max, vl),
|
||||
__riscv_vmand_mm_b4(mask2, cond2_max, vl),
|
||||
vl);
|
||||
vmax = __riscv_vmor_mm_b4(
|
||||
vmax,
|
||||
__riscv_vmand_mm_b4(mask3, cond3_max, vl),
|
||||
vl);
|
||||
|
||||
// Threshold checks
|
||||
vbool4_t vlow = __riscv_vmsgt_vx_i32m8_b4(vm, low_thresh, vl);
|
||||
vbool4_t vhigh = __riscv_vmsgt_vx_i32m8_b4(vm, high_thresh, vl);
|
||||
vbool4_t valid_edges = __riscv_vmand_mm_b4(vmax, vlow, vl);
|
||||
vbool4_t strong_edges = __riscv_vmand_mm_b4(valid_edges, vhigh, vl);
|
||||
|
||||
// Generate result map
|
||||
vuint8m2_t vres = __riscv_vmv_v_x_u8m2(1, vl);
|
||||
vres = __riscv_vmerge_vxm_u8m2(vres, 0, valid_edges, vl);
|
||||
vres = __riscv_vmerge_vxm_u8m2(vres, 2, strong_edges, vl);
|
||||
__riscv_vse8_v_u8m2(pmap + j, vres, vl);
|
||||
|
||||
// canny_Push strong edges to stack
|
||||
int32_t vidx = __riscv_vfirst_m_b4(strong_edges, vl);
|
||||
while (vidx >= 0)
|
||||
{
|
||||
canny_push(stack, pmap + j + vidx);
|
||||
strong_edges = __riscv_vmand_mm_b4(strong_edges,
|
||||
__riscv_vmclr_m_b4(vl), vl);
|
||||
vidx = __riscv_vfirst_m_b4(strong_edges, vl);
|
||||
}
|
||||
}
|
||||
|
||||
rotateLineBuffer(lineBuf);
|
||||
}
|
||||
|
||||
uint8_t *pmapLower = edge_map;
|
||||
uint32_t pmapDiff = (uint32_t)((edge_map + mapsize) - pmapLower);
|
||||
|
||||
while (stack->size > 0)
|
||||
{
|
||||
uint8_t *m = canny_pop(stack);
|
||||
|
||||
if ((uint64_t)m < (uint64_t)pmapLower || (uint64_t)m >= (uint64_t)(pmapLower + pmapDiff))
|
||||
continue;
|
||||
|
||||
const int offsets[8] = {
|
||||
-mapstep - 1, -mapstep, -mapstep + 1,
|
||||
-1, +1,
|
||||
+mapstep - 1, +mapstep, +mapstep + 1};
|
||||
|
||||
for (int k = 0; k < 8; k++)
|
||||
{
|
||||
uint8_t *neighbor = m + offsets[k];
|
||||
if ((uint64_t)neighbor < (uint64_t)edge_map ||
|
||||
(uint64_t)neighbor >= (uint64_t)(edge_map + mapsize))
|
||||
continue;
|
||||
|
||||
if (*neighbor == 0)
|
||||
{
|
||||
*neighbor = 2;
|
||||
canny_push(stack, neighbor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (borderPeaksLocal->size > 0)
|
||||
{
|
||||
for (int i = 0; i < borderPeaksLocal->size; i++)
|
||||
{
|
||||
canny_push(stack, borderPeaksLocal->data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < height; i++)
|
||||
{
|
||||
uint8_t *pdst = dst_data + i * dst_step;
|
||||
uint8_t *pmap = map + i * mapstep + 1;
|
||||
size_t vl = 0;
|
||||
for (int j = 0; j < width; j += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e8m8(width - j);
|
||||
vuint8m8_t vres = __riscv_vle8_v_u8m8(pmap + j, vl);
|
||||
vres = __riscv_vsrl_vx_u8m8(vres, 1, vl);
|
||||
vres = __riscv_vsub_vv_u8m8(__riscv_vmv_v_x_u8m8(0, vl), vres, vl);
|
||||
__riscv_vse8_v_u8m8(pdst + j, vres, vl);
|
||||
}
|
||||
}
|
||||
|
||||
freeLineBuffer(lineBuf);
|
||||
freeStack(borderPeaksLocal);
|
||||
freeStack(stack);
|
||||
free(dx_data);
|
||||
free(dy_data);
|
||||
free(edge_map);
|
||||
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // CV_HAL_RVV_1P0_ENABLED
|
||||
} // namespace cv::rvv_hal::imgproc
|
||||
883
hal/riscv-rvv/src/imgproc/scharr.cpp
Normal file
883
hal/riscv-rvv/src/imgproc/scharr.cpp
Normal file
|
|
@ -0,0 +1,883 @@
|
|||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html .
|
||||
|
||||
// Copyright (C) 2025, SpaceMIT Inc., all rights reserved.
|
||||
|
||||
#include "rvv_hal.hpp"
|
||||
#include "common.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace rvv_hal
|
||||
{
|
||||
namespace imgproc
|
||||
{
|
||||
|
||||
#if CV_HAL_RVV_1P0_ENABLED
|
||||
|
||||
#define borderValue 0
|
||||
|
||||
static inline int scharr_dx0(int start, int end, const uint8_t *src_data, size_t src_step,
|
||||
uint8_t *dst_data, size_t dst_step,
|
||||
int width, int height,
|
||||
int src_depth __attribute__((unused)), int dst_depth, int cn __attribute__((unused)),
|
||||
int margin_left __attribute__((unused)), int margin_top __attribute__((unused)),
|
||||
int margin_right __attribute__((unused)), int margin_bottom __attribute__((unused)),
|
||||
double scale __attribute__((unused)), double delta __attribute__((unused)),
|
||||
int border_type)
|
||||
{
|
||||
int dx0, dx1, dx2, dy0, dy1, dy2;
|
||||
|
||||
dy0 = -1;
|
||||
dx0 = 3;
|
||||
|
||||
dy1 = 0;
|
||||
dx1 = 10;
|
||||
|
||||
dy2 = 1;
|
||||
dx2 = 3;
|
||||
|
||||
int16_t trow[width];
|
||||
|
||||
static thread_local std::vector<uint8_t> zero_row;
|
||||
if (zero_row.size() < static_cast<size_t>(width))
|
||||
{
|
||||
zero_row.clear();
|
||||
zero_row.resize(width, 0);
|
||||
}
|
||||
|
||||
if (dst_depth == CV_8U)
|
||||
{
|
||||
for (int y = start; y < end; ++y)
|
||||
{
|
||||
const uint8_t *srow1 = src_data + y * src_step;
|
||||
const uint8_t *srow0;
|
||||
const uint8_t *srow2;
|
||||
|
||||
if (y != 0)
|
||||
{
|
||||
srow0 = src_data + (y - 1) * src_step;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
srow0 = srow1;
|
||||
}
|
||||
else
|
||||
{
|
||||
srow0 = zero_row.data();
|
||||
}
|
||||
}
|
||||
|
||||
if (y != height - 1)
|
||||
{
|
||||
srow2 = src_data + (y + 1) * src_step;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
srow2 = srow1;
|
||||
}
|
||||
else
|
||||
{
|
||||
srow2 = zero_row.data();
|
||||
}
|
||||
}
|
||||
|
||||
trow[0] = (dy0 * srow0[0] + dy1 * srow1[0] + dy2 * srow2[0]);
|
||||
|
||||
// Last pixel
|
||||
|
||||
trow[width - 1] = dy0 * srow0[width - 1] + dy1 * srow1[width - 1] + dy2 * srow2[width - 1];
|
||||
|
||||
size_t vl = 0;
|
||||
|
||||
// Vector processing
|
||||
|
||||
for (int x = 1; x < width - 1; x += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e8m4(width - x - 1);
|
||||
|
||||
vint16m8_t vsrow0 = __riscv_vreinterpret_v_u16m8_i16m8(__riscv_vwcvtu_x_x_v_u16m8(__riscv_vle8_v_u8m4(srow0 + x, vl), vl));
|
||||
vint16m8_t vsrow2 = __riscv_vreinterpret_v_u16m8_i16m8(__riscv_vwcvtu_x_x_v_u16m8(__riscv_vle8_v_u8m4(srow2 + x, vl), vl));
|
||||
|
||||
vint16m8_t vrowx = __riscv_vsub_vv_i16m8(vsrow2, vsrow0, vl);
|
||||
|
||||
__riscv_vse16_v_i16m8(trow + x, vrowx, vl);
|
||||
}
|
||||
|
||||
int x = 0;
|
||||
|
||||
uint8_t *drow = (uint8_t *)(dst_data + y * dst_step);
|
||||
|
||||
int16_t temp = trow[0] * dx1 + trow[1] * dx2;
|
||||
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
temp += trow[0] * dx0;
|
||||
}
|
||||
|
||||
drow[x] = (uint8_t)(temp > 0 ? (temp < 255 ? temp : 255) : 0);
|
||||
|
||||
x = 1;
|
||||
for (; x < width - 1; x += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e16m8(width - x - 1);
|
||||
vint16m8_t vleft = __riscv_vle16_v_i16m8(trow + x - 1, vl);
|
||||
vint16m8_t vcenter = __riscv_vle16_v_i16m8(trow + x, vl);
|
||||
vint16m8_t vright = __riscv_vle16_v_i16m8(trow + x + 1, vl);
|
||||
|
||||
vint16m8_t vres = __riscv_vmul_vx_i16m8(vcenter, dx1, vl);
|
||||
vcenter = __riscv_vadd_vv_i16m8(vleft, vright, vl);
|
||||
vres = __riscv_vmacc_vx_i16m8(vres, dx0, vcenter, vl);
|
||||
|
||||
vres = __riscv_vmax_vx_i16m8(vres, 0, vl);
|
||||
vres = __riscv_vmin_vx_i16m8(vres, 255, vl);
|
||||
|
||||
__riscv_vse8_v_u8m4(drow + x, __riscv_vncvt_x_x_w_u8m4(__riscv_vreinterpret_v_i16m8_u16m8(vres), vl), vl);
|
||||
}
|
||||
|
||||
x = width - 1;
|
||||
|
||||
temp = trow[width - 2] * dx0 + trow[width - 1] * dx1;
|
||||
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
temp += trow[width - 1] * dx2;
|
||||
}
|
||||
|
||||
drow[x] = (uint8_t)(temp > 0 ? (temp < 255 ? temp : 255) : 0);
|
||||
}
|
||||
}
|
||||
|
||||
else if (dst_depth == CV_16S)
|
||||
{
|
||||
|
||||
for (int y = start; y < end; ++y)
|
||||
{
|
||||
const uint8_t *srow1 = src_data + y * src_step;
|
||||
const uint8_t *srow0;
|
||||
const uint8_t *srow2;
|
||||
|
||||
if (y != 0)
|
||||
{
|
||||
srow0 = src_data + (y - 1) * src_step;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
srow0 = srow1;
|
||||
}
|
||||
else
|
||||
{
|
||||
srow0 = zero_row.data();
|
||||
}
|
||||
}
|
||||
|
||||
if (y != height - 1)
|
||||
{
|
||||
srow2 = src_data + (y + 1) * src_step;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
srow2 = srow1;
|
||||
}
|
||||
else
|
||||
{
|
||||
srow2 = zero_row.data();
|
||||
}
|
||||
}
|
||||
|
||||
if (y == 0)
|
||||
{
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
srow0 = srow1;
|
||||
}
|
||||
else
|
||||
{
|
||||
srow0 = zero_row.data();
|
||||
}
|
||||
}
|
||||
else if (y == height - 1)
|
||||
{
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
srow2 = srow1;
|
||||
}
|
||||
else
|
||||
{
|
||||
srow2 = zero_row.data();
|
||||
}
|
||||
}
|
||||
|
||||
size_t vl = 0;
|
||||
|
||||
// Vector processing
|
||||
|
||||
for (int x = 0; x < width; x += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e8m4(width - x);
|
||||
|
||||
vint16m8_t vsrow0 = __riscv_vreinterpret_v_u16m8_i16m8(__riscv_vwcvtu_x_x_v_u16m8(__riscv_vle8_v_u8m4(srow0 + x, vl), vl));
|
||||
vint16m8_t vsrow2 = __riscv_vreinterpret_v_u16m8_i16m8(__riscv_vwcvtu_x_x_v_u16m8(__riscv_vle8_v_u8m4(srow2 + x, vl), vl));
|
||||
|
||||
vint16m8_t vrowx = __riscv_vsub_vv_i16m8(vsrow2, vsrow0, vl);
|
||||
|
||||
__riscv_vse16_v_i16m8(trow + x, vrowx, vl);
|
||||
}
|
||||
|
||||
int x = 0;
|
||||
|
||||
int16_t *drow = (int16_t *)(dst_data + y * dst_step);
|
||||
|
||||
drow[0] = trow[0] * dx1 + trow[1] * dx2;
|
||||
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
drow[x] += trow[0] * dx0;
|
||||
}
|
||||
|
||||
x = 1;
|
||||
for (; x < width - 1; x += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e16m8(width - x - 1);
|
||||
vint16m8_t vleft = __riscv_vle16_v_i16m8(trow + x - 1, vl);
|
||||
vint16m8_t vcenter = __riscv_vle16_v_i16m8(trow + x, vl);
|
||||
vint16m8_t vright = __riscv_vle16_v_i16m8(trow + x + 1, vl);
|
||||
|
||||
vint16m8_t vres = __riscv_vmul_vx_i16m8(vcenter, dx1, vl);
|
||||
vcenter = __riscv_vadd_vv_i16m8(vleft, vright, vl);
|
||||
vres = __riscv_vmacc_vx_i16m8(vres, dx0, vcenter, vl);
|
||||
|
||||
__riscv_vse16_v_i16m8(drow + x, vres, vl);
|
||||
}
|
||||
|
||||
x = width - 1;
|
||||
|
||||
drow[x] = trow[width - 2] * dx0 + trow[width - 1] * dx1;
|
||||
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
drow[x] += trow[width - 1] * dx2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (dst_depth == CV_32F)
|
||||
{
|
||||
for (int y = start; y < end; ++y)
|
||||
{
|
||||
const uint8_t *srow1 = src_data + y * src_step;
|
||||
const uint8_t *srow0;
|
||||
const uint8_t *srow2;
|
||||
|
||||
if (y != 0)
|
||||
{
|
||||
srow0 = src_data + (y - 1) * src_step;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
srow0 = srow1;
|
||||
}
|
||||
else
|
||||
{
|
||||
srow0 = zero_row.data();
|
||||
}
|
||||
}
|
||||
|
||||
if (y != height - 1)
|
||||
{
|
||||
srow2 = src_data + (y + 1) * src_step;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
srow2 = srow1;
|
||||
}
|
||||
else
|
||||
{
|
||||
srow2 = zero_row.data();
|
||||
}
|
||||
}
|
||||
|
||||
if (y == 0)
|
||||
{
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
srow0 = srow1;
|
||||
}
|
||||
else
|
||||
{
|
||||
srow0 = zero_row.data();
|
||||
}
|
||||
}
|
||||
else if (y == height - 1)
|
||||
{
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
srow2 = srow1;
|
||||
}
|
||||
else
|
||||
{
|
||||
srow2 = zero_row.data();
|
||||
}
|
||||
}
|
||||
|
||||
size_t vl = 0;
|
||||
|
||||
// Vector processing
|
||||
for (int x = 0; x < width; x += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e8m4(width - x);
|
||||
|
||||
vint16m8_t vsrow0 = __riscv_vreinterpret_v_u16m8_i16m8(__riscv_vwcvtu_x_x_v_u16m8(__riscv_vle8_v_u8m4(srow0 + x, vl), vl));
|
||||
vint16m8_t vsrow2 = __riscv_vreinterpret_v_u16m8_i16m8(__riscv_vwcvtu_x_x_v_u16m8(__riscv_vle8_v_u8m4(srow2 + x, vl), vl));
|
||||
|
||||
vint16m8_t vrowx = __riscv_vsub_vv_i16m8(vsrow2, vsrow0, vl);
|
||||
|
||||
__riscv_vse16_v_i16m8(trow + x, vrowx, vl);
|
||||
}
|
||||
|
||||
int x = 0;
|
||||
|
||||
float *drow = (float *)(dst_data + y * dst_step);
|
||||
|
||||
drow[x] = trow[0] * dx1 + trow[1] * dx2;
|
||||
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
drow[x] += trow[0] * dx0;
|
||||
}
|
||||
|
||||
x = 1;
|
||||
|
||||
for (; x < width - 1; x += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e16m4(width - x - 1);
|
||||
vint16m4_t vleft = __riscv_vle16_v_i16m4(trow + x - 1, vl);
|
||||
vint16m4_t vcenter = __riscv_vle16_v_i16m4(trow + x, vl);
|
||||
vint16m4_t vright = __riscv_vle16_v_i16m4(trow + x + 1, vl);
|
||||
|
||||
vint16m4_t vres = __riscv_vmul_vx_i16m4(vcenter, dx1, vl);
|
||||
vcenter = __riscv_vadd_vv_i16m4(vleft, vright, vl);
|
||||
vres = __riscv_vmacc_vx_i16m4(vres, dx0, vcenter, vl);
|
||||
|
||||
__riscv_vse32_v_f32m8(drow + x, __riscv_vfwcvt_f_x_v_f32m8(vres, vl), vl);
|
||||
}
|
||||
|
||||
x = width - 1;
|
||||
|
||||
drow[x] = trow[width - 2] * dx0 + trow[width - 1] * dx1;
|
||||
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
drow[x] += trow[width - 1] * dx2;
|
||||
}
|
||||
}
|
||||
}
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
static inline int scharr_dx1(int start, int end, const uint8_t *src_data, size_t src_step,
|
||||
uint8_t *dst_data, size_t dst_step,
|
||||
int width, int height,
|
||||
int src_depth __attribute__((unused)), int dst_depth, int cn __attribute__((unused)),
|
||||
int margin_left __attribute__((unused)), int margin_top __attribute__((unused)),
|
||||
int margin_right __attribute__((unused)), int margin_bottom __attribute__((unused)),
|
||||
double scale __attribute__((unused)), double delta __attribute__((unused)),
|
||||
int border_type)
|
||||
{
|
||||
int dx0, dx1, dx2, dy0, dy1, dy2;
|
||||
dx0 = -1;
|
||||
dy0 = 3;
|
||||
|
||||
dx1 = 0;
|
||||
dy1 = 10;
|
||||
|
||||
dx2 = 1;
|
||||
dy2 = 3;
|
||||
|
||||
int16_t trow[width];
|
||||
|
||||
static thread_local std::vector<uint8_t> zero_row;
|
||||
if (zero_row.size() < static_cast<size_t>(width))
|
||||
{
|
||||
zero_row.clear();
|
||||
zero_row.resize(width, 0);
|
||||
}
|
||||
|
||||
if (dst_depth == CV_8U)
|
||||
{
|
||||
for (int y = start; y < end; ++y)
|
||||
{
|
||||
const uint8_t *srow1 = src_data + y * src_step;
|
||||
const uint8_t *srow0;
|
||||
const uint8_t *srow2;
|
||||
|
||||
if (y != 0)
|
||||
{
|
||||
srow0 = src_data + (y - 1) * src_step;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
srow0 = srow1;
|
||||
}
|
||||
else
|
||||
{
|
||||
srow0 = zero_row.data();
|
||||
}
|
||||
}
|
||||
|
||||
if (y != height - 1)
|
||||
{
|
||||
srow2 = src_data + (y + 1) * src_step;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
srow2 = srow1;
|
||||
}
|
||||
else
|
||||
{
|
||||
srow2 = zero_row.data();
|
||||
}
|
||||
}
|
||||
|
||||
if (y == 0)
|
||||
{
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
srow0 = srow1;
|
||||
}
|
||||
else
|
||||
{
|
||||
srow0 = zero_row.data();
|
||||
}
|
||||
}
|
||||
else if (y == height - 1)
|
||||
{
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
srow2 = srow1;
|
||||
}
|
||||
else
|
||||
{
|
||||
srow2 = zero_row.data();
|
||||
}
|
||||
}
|
||||
|
||||
trow[0] = (dy0 * srow0[0] + dy1 * srow1[0] + dy2 * srow2[0]);
|
||||
|
||||
// Last pixel
|
||||
|
||||
trow[width - 1] = dy0 * srow0[width - 1] + dy1 * srow1[width - 1] + dy2 * srow2[width - 1];
|
||||
|
||||
size_t vl = 0;
|
||||
|
||||
// Vector processing
|
||||
|
||||
for (int x = 1; x < width - 1; x += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e8m4(width - x - 1);
|
||||
|
||||
vuint8m4_t vsrow0 = __riscv_vle8_v_u8m4(srow0 + x, vl);
|
||||
vuint8m4_t vsrow1 = __riscv_vle8_v_u8m4(srow1 + x, vl);
|
||||
vuint8m4_t vsrow2 = __riscv_vle8_v_u8m4(srow2 + x, vl);
|
||||
|
||||
vuint16m8_t vrowx = __riscv_vwmulu_vx_u16m8(vsrow1, dy1, vl);
|
||||
vuint16m8_t vtemp = __riscv_vwaddu_vv_u16m8(vsrow0, vsrow2, vl);
|
||||
vrowx = __riscv_vmacc_vx_u16m8(vrowx, dy0, vtemp, vl);
|
||||
|
||||
__riscv_vse16_v_i16m8(trow + x, __riscv_vreinterpret_v_u16m8_i16m8(vrowx), vl);
|
||||
}
|
||||
|
||||
int x = 0;
|
||||
|
||||
uint8_t *drow = (uint8_t *)(dst_data + y * dst_step);
|
||||
|
||||
int16_t temp = trow[0] * dx1 + trow[1] * dx2;
|
||||
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
temp += trow[0] * dx0;
|
||||
}
|
||||
|
||||
drow[x] = (uint8_t)(temp > 0 ? (temp < 255 ? temp : 255) : 0);
|
||||
|
||||
x = 1;
|
||||
|
||||
for (; x < width - 1; x += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e16m8(width - x - 1);
|
||||
vint16m8_t vleft = __riscv_vle16_v_i16m8(trow + x - 1, vl);
|
||||
|
||||
vint16m8_t vright = __riscv_vle16_v_i16m8(trow + x + 1, vl);
|
||||
vint16m8_t vres = __riscv_vsub_vv_i16m8(vright, vleft, vl);
|
||||
|
||||
vres = __riscv_vmax_vx_i16m8(vres, 0, vl);
|
||||
vres = __riscv_vmin_vx_i16m8(vres, 255, vl);
|
||||
|
||||
__riscv_vse8_v_u8m4(drow + x, __riscv_vncvt_x_x_w_u8m4(__riscv_vreinterpret_v_i16m8_u16m8(vres), vl), vl);
|
||||
}
|
||||
|
||||
x = width - 1;
|
||||
|
||||
temp = trow[width - 2] * dx0 + trow[width - 1] * dx1;
|
||||
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
temp += trow[width - 1] * dx2;
|
||||
}
|
||||
|
||||
drow[x] = (uint8_t)(temp > 0 ? (temp < 255 ? temp : 255) : 0);
|
||||
}
|
||||
}
|
||||
|
||||
else if (dst_depth == CV_16S)
|
||||
{
|
||||
for (int y = start; y < end; ++y)
|
||||
{
|
||||
const uint8_t *srow1 = src_data + y * src_step;
|
||||
const uint8_t *srow0;
|
||||
const uint8_t *srow2;
|
||||
|
||||
if (y != 0)
|
||||
{
|
||||
srow0 = src_data + (y - 1) * src_step;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
srow0 = srow1;
|
||||
}
|
||||
else
|
||||
{
|
||||
srow0 = zero_row.data();
|
||||
}
|
||||
}
|
||||
|
||||
if (y != height - 1)
|
||||
{
|
||||
srow2 = src_data + (y + 1) * src_step;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
srow2 = srow1;
|
||||
}
|
||||
else
|
||||
{
|
||||
srow2 = zero_row.data();
|
||||
}
|
||||
}
|
||||
|
||||
if (y == 0)
|
||||
{
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
srow0 = srow1;
|
||||
}
|
||||
else
|
||||
{
|
||||
srow0 = zero_row.data();
|
||||
}
|
||||
}
|
||||
else if (y == height - 1)
|
||||
{
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
srow2 = srow1;
|
||||
}
|
||||
else
|
||||
{
|
||||
srow2 = zero_row.data();
|
||||
}
|
||||
}
|
||||
|
||||
size_t vl = 0;
|
||||
|
||||
// Vector processing
|
||||
|
||||
for (int x = 0; x < width; x += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e8m4(width - x);
|
||||
|
||||
vuint8m4_t vsrow0 = __riscv_vle8_v_u8m4(srow0 + x, vl);
|
||||
vuint8m4_t vsrow1 = __riscv_vle8_v_u8m4(srow1 + x, vl);
|
||||
vuint8m4_t vsrow2 = __riscv_vle8_v_u8m4(srow2 + x, vl);
|
||||
|
||||
vuint16m8_t vrowx = __riscv_vwmulu_vx_u16m8(vsrow1, dy1, vl);
|
||||
vuint16m8_t vtemp = __riscv_vwaddu_vv_u16m8(vsrow0, vsrow2, vl);
|
||||
vrowx = __riscv_vmacc_vx_u16m8(vrowx, dy0, vtemp, vl);
|
||||
|
||||
__riscv_vse16_v_i16m8(trow + x, __riscv_vreinterpret_v_u16m8_i16m8(vrowx), vl);
|
||||
}
|
||||
|
||||
int x = 0;
|
||||
|
||||
int16_t *drow = (int16_t *)(dst_data + y * dst_step);
|
||||
|
||||
drow[x] = trow[0] * dx1 + trow[1] * dx2;
|
||||
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
drow[x] += trow[0] * dx0;
|
||||
}
|
||||
|
||||
x = 1;
|
||||
for (; x < width - 1; x += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e16m8(width - x - 1);
|
||||
vint16m8_t vleft = __riscv_vle16_v_i16m8(trow + x - 1, vl);
|
||||
|
||||
vint16m8_t vright = __riscv_vle16_v_i16m8(trow + x + 1, vl);
|
||||
vint16m8_t vres = __riscv_vsub_vv_i16m8(vright, vleft, vl);
|
||||
|
||||
__riscv_vse16_v_i16m8(drow + x, vres, vl);
|
||||
}
|
||||
|
||||
x = width - 1;
|
||||
|
||||
drow[x] = trow[width - 2] * dx0 + trow[width - 1] * dx1;
|
||||
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
drow[x] += trow[width - 1] * dx2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (dst_depth == CV_32F)
|
||||
{
|
||||
for (int y = start; y < end; ++y)
|
||||
{
|
||||
const uint8_t *srow1 = src_data + y * src_step;
|
||||
const uint8_t *srow0;
|
||||
const uint8_t *srow2;
|
||||
|
||||
if (y != 0)
|
||||
{
|
||||
srow0 = src_data + (y - 1) * src_step;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
srow0 = srow1;
|
||||
}
|
||||
else
|
||||
{
|
||||
srow0 = zero_row.data();
|
||||
}
|
||||
}
|
||||
|
||||
if (y != height - 1)
|
||||
{
|
||||
srow2 = src_data + (y + 1) * src_step;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
srow2 = srow1;
|
||||
}
|
||||
else
|
||||
{
|
||||
srow2 = zero_row.data();
|
||||
}
|
||||
}
|
||||
|
||||
if (y == 0)
|
||||
{
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
srow0 = srow1;
|
||||
}
|
||||
else
|
||||
{
|
||||
srow0 = zero_row.data();
|
||||
}
|
||||
}
|
||||
else if (y == height - 1)
|
||||
{
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
srow2 = srow1;
|
||||
}
|
||||
else
|
||||
{
|
||||
srow2 = zero_row.data();
|
||||
}
|
||||
}
|
||||
|
||||
size_t vl = 0;
|
||||
|
||||
// Vector processing
|
||||
for (int x = 0; x < width; x += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e8m4(width - x);
|
||||
|
||||
vuint8m4_t vsrow0 = __riscv_vle8_v_u8m4(srow0 + x, vl);
|
||||
vuint8m4_t vsrow1 = __riscv_vle8_v_u8m4(srow1 + x, vl);
|
||||
vuint8m4_t vsrow2 = __riscv_vle8_v_u8m4(srow2 + x, vl);
|
||||
|
||||
vuint16m8_t vrowx = __riscv_vwmulu_vx_u16m8(vsrow1, dy1, vl);
|
||||
vuint16m8_t vtemp = __riscv_vwaddu_vv_u16m8(vsrow0, vsrow2, vl);
|
||||
vrowx = __riscv_vmacc_vx_u16m8(vrowx, dy0, vtemp, vl);
|
||||
|
||||
__riscv_vse16_v_i16m8(trow + x, __riscv_vreinterpret_v_u16m8_i16m8(vrowx), vl);
|
||||
}
|
||||
|
||||
int x = 0;
|
||||
|
||||
float *drow = (float *)(dst_data + y * dst_step);
|
||||
|
||||
drow[x] = trow[0] * dx1 + trow[1] * dx2;
|
||||
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
drow[x] += trow[0] * dx0;
|
||||
}
|
||||
|
||||
x = 1;
|
||||
|
||||
for (; x < width - 1; x += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e16m4(width - x - 1);
|
||||
vint16m4_t vleft = __riscv_vle16_v_i16m4(trow + x - 1, vl);
|
||||
|
||||
vint16m4_t vright = __riscv_vle16_v_i16m4(trow + x + 1, vl);
|
||||
vint16m4_t vres = __riscv_vsub_vv_i16m4(vright, vleft, vl);
|
||||
|
||||
__riscv_vse32_v_f32m8(drow + x, __riscv_vfwcvt_f_x_v_f32m8(vres, vl), vl);
|
||||
}
|
||||
|
||||
x = width - 1;
|
||||
|
||||
drow[x] = trow[width - 2] * dx0 + trow[width - 1] * dx1;
|
||||
|
||||
if (border_type == BORDER_REPLICATE)
|
||||
{
|
||||
drow[x] += trow[width - 1] * dx2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
class ScharrInvoker : public ParallelLoopBody
|
||||
{
|
||||
public:
|
||||
explicit ScharrInvoker(std::function<int(int, int)> _func)
|
||||
: func(std::move(_func)) {}
|
||||
|
||||
void operator()(const Range &range) const override
|
||||
{
|
||||
func(range.start, range.end);
|
||||
}
|
||||
|
||||
private:
|
||||
std::function<int(int, int)> func;
|
||||
};
|
||||
|
||||
template <typename... Args>
|
||||
inline int invoke(int height,
|
||||
int (*f)(int, int, Args...),
|
||||
Args... args)
|
||||
{
|
||||
using namespace std::placeholders;
|
||||
auto bound = std::bind(f, _1, _2, std::forward<Args>(args)...);
|
||||
cv::parallel_for_(Range(1, height), ScharrInvoker(bound), cv::getNumThreads());
|
||||
return f(0, 1, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
int scharr(const uint8_t *src_data, size_t src_step,
|
||||
uint8_t *dst_data, size_t dst_step,
|
||||
int width, int height,
|
||||
int src_depth, int dst_depth, int cn,
|
||||
int margin_left, int margin_top,
|
||||
int margin_right, int margin_bottom,
|
||||
int dx, int dy __attribute__((unused)),
|
||||
double scale, double delta,
|
||||
int border_type)
|
||||
{
|
||||
if (src_depth != CV_8U ||
|
||||
(dst_depth != CV_8U && dst_depth != CV_16S && dst_depth != CV_32F) ||
|
||||
cn != 1 || width < 3)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
if (scale != 1 || delta != 0)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
if (border_type != BORDER_REPLICATE && border_type != BORDER_CONSTANT)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
if (margin_left != 0 || margin_top != 0 || margin_right != 0 || margin_bottom != 0)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
// This is copied from opencv/modules/imgproc/src/deriv.cpp
|
||||
// if (!(dx >= 0 && dy >= 0 && dx + dy == 1))
|
||||
// {
|
||||
// return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
// }
|
||||
|
||||
int size = 1;
|
||||
if (dst_depth == CV_16S)
|
||||
{
|
||||
size = 2;
|
||||
}
|
||||
else if (dst_depth == CV_32F)
|
||||
{
|
||||
size = 4;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> temp_buffer;
|
||||
uint8_t *actual_dst_data = dst_data;
|
||||
if (src_data == dst_data)
|
||||
{
|
||||
temp_buffer.resize(height * dst_step);
|
||||
actual_dst_data = temp_buffer.data();
|
||||
}
|
||||
|
||||
int res = invoke(height,
|
||||
dx == 1 ? &scharr_dx1 : &scharr_dx0,
|
||||
src_data, src_step,
|
||||
actual_dst_data, dst_step,
|
||||
width, height,
|
||||
src_depth, dst_depth, cn,
|
||||
margin_left, margin_top,
|
||||
margin_right, margin_bottom,
|
||||
scale, delta,
|
||||
border_type);
|
||||
if (src_data == dst_data && res == CV_HAL_ERROR_OK)
|
||||
{
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
memcpy(dst_data + y * dst_step,
|
||||
actual_dst_data + y * dst_step,
|
||||
width * size);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif // CV_HAL_RVV_1P0_ENABLED
|
||||
}
|
||||
}
|
||||
} // cv::rvv_hal::imgproc
|
||||
1128
hal/riscv-rvv/src/imgproc/sobel.cpp
Normal file
1128
hal/riscv-rvv/src/imgproc/sobel.cpp
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -774,7 +774,7 @@ struct CV_EXPORTS_W_SIMPLE CirclesGridFinderParameters
|
|||
{
|
||||
SYMMETRIC_GRID, ASYMMETRIC_GRID
|
||||
};
|
||||
GridType gridType;
|
||||
CV_PROP_RW GridType gridType;
|
||||
|
||||
CV_PROP_RW float squareSize; //!< Distance between two adjacent points. Used by CALIB_CB_CLUSTERING.
|
||||
CV_PROP_RW float maxRectifiedDistance; //!< Max deviation from prediction. Used by CALIB_CB_CLUSTERING.
|
||||
|
|
|
|||
|
|
@ -648,6 +648,31 @@
|
|||
"jni_var": "Vec3d %(n)s(%(n)s_val0, %(n)s_val1, %(n)s_val2)",
|
||||
"suffix": "DDD"
|
||||
},
|
||||
"Vec4i": {
|
||||
"j_type": "int[]",
|
||||
"jn_args": [
|
||||
[
|
||||
"int",
|
||||
".val[0]"
|
||||
],
|
||||
[
|
||||
"int",
|
||||
".val[1]"
|
||||
],
|
||||
[
|
||||
"int",
|
||||
".val[2]"
|
||||
],
|
||||
[
|
||||
"int",
|
||||
".val[3]"
|
||||
]
|
||||
],
|
||||
"jn_type": "int[]",
|
||||
"jni_type": "jintArray",
|
||||
"jni_var": "Vec4i %(n)s(%(n)s_val0, %(n)s_val1, %(n)s_val2, %(n)s_val3)",
|
||||
"suffix": "IIII"
|
||||
},
|
||||
"c_string": {
|
||||
"j_type": "String",
|
||||
"jn_type": "String",
|
||||
|
|
@ -852,6 +877,15 @@
|
|||
"v_type": "Mat",
|
||||
"j_import": "org.opencv.core.MatOfByte"
|
||||
},
|
||||
"vector_vector_Mat": {
|
||||
"j_type": "List<List<Mat>>",
|
||||
"jn_type": "long",
|
||||
"jni_type": "jlong",
|
||||
"jni_var": "std::vector< std::vector<Mat> > %(n)s",
|
||||
"suffix": "J",
|
||||
"v_type": "vector_Mat",
|
||||
"j_import": "org.opencv.core.Mat"
|
||||
},
|
||||
"vector_vector_DMatch": {
|
||||
"j_type": "List<MatOfDMatch>",
|
||||
"jn_type": "long",
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#ifdef HAVE_OPENCV_CORE
|
||||
|
||||
#include "dlpack/dlpack.h"
|
||||
|
||||
static PyObject* pycvMakeType(PyObject* , PyObject* args, PyObject* kw) {
|
||||
const char *keywords[] = { "depth", "channels", NULL };
|
||||
|
||||
|
|
@ -20,6 +22,201 @@ static PyObject* pycvMakeTypeCh(PyObject*, PyObject *value) {
|
|||
return PyInt_FromLong(CV_MAKETYPE(depth, channels));
|
||||
}
|
||||
|
||||
#define CV_DLPACK_CAPSULE_NAME "dltensor"
|
||||
#define CV_DLPACK_USED_CAPSULE_NAME "used_dltensor"
|
||||
|
||||
template<typename T>
|
||||
bool fillDLPackTensor(const T& src, DLManagedTensor* tensor, const DLDevice& device);
|
||||
|
||||
template<typename T>
|
||||
bool parseDLPackTensor(DLManagedTensor* tensor, T& obj, bool copy);
|
||||
|
||||
template<typename T>
|
||||
int GetNumDims(const T& src);
|
||||
|
||||
// source: https://github.com/dmlc/dlpack/blob/7f393bbb86a0ddd71fde3e700fc2affa5cdce72d/docs/source/python_spec.rst#L110
|
||||
static void dlpack_capsule_deleter(PyObject *self){
|
||||
if (PyCapsule_IsValid(self, CV_DLPACK_USED_CAPSULE_NAME)) {
|
||||
return;
|
||||
}
|
||||
|
||||
DLManagedTensor *managed = (DLManagedTensor *)PyCapsule_GetPointer(self, CV_DLPACK_CAPSULE_NAME);
|
||||
if (managed == NULL) {
|
||||
PyErr_WriteUnraisable(self);
|
||||
return;
|
||||
}
|
||||
|
||||
if (managed->deleter) {
|
||||
managed->deleter(managed);
|
||||
}
|
||||
}
|
||||
|
||||
static void array_dlpack_deleter(DLManagedTensor *self)
|
||||
{
|
||||
if (!Py_IsInitialized()) {
|
||||
return;
|
||||
}
|
||||
|
||||
PyGILState_STATE state = PyGILState_Ensure();
|
||||
|
||||
PyObject *array = (PyObject *)self->manager_ctx;
|
||||
PyMem_Free(self);
|
||||
Py_XDECREF(array);
|
||||
|
||||
PyGILState_Release(state);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static PyObject* to_dlpack(const T& src, PyObject* self, PyObject* py_args, PyObject* kw)
|
||||
{
|
||||
int stream = 0;
|
||||
PyObject* maxVersion = nullptr;
|
||||
PyObject* dlDevice = nullptr;
|
||||
bool copy = false;
|
||||
const char* keywords[] = { "stream", "max_version", "dl_device", "copy", NULL };
|
||||
if (!PyArg_ParseTupleAndKeywords(py_args, kw, "|iOOp:__dlpack__", (char**)keywords, &stream, &maxVersion, &dlDevice, ©))
|
||||
return nullptr;
|
||||
|
||||
DLDevice device = {(DLDeviceType)-1, 0};
|
||||
if (dlDevice && dlDevice != Py_None && PyTuple_Check(dlDevice))
|
||||
{
|
||||
device.device_type = static_cast<DLDeviceType>(PyLong_AsLong(PyTuple_GetItem(dlDevice, 0)));
|
||||
device.device_id = PyLong_AsLong(PyTuple_GetItem(dlDevice, 1));
|
||||
}
|
||||
|
||||
int ndim = GetNumDims(src);
|
||||
void* ptr = PyMem_Malloc(sizeof(DLManagedTensor) + sizeof(int64_t) * ndim * 2);
|
||||
if (!ptr) {
|
||||
PyErr_NoMemory();
|
||||
return nullptr;
|
||||
}
|
||||
DLManagedTensor* tensor = reinterpret_cast<DLManagedTensor*>(ptr);
|
||||
tensor->manager_ctx = self;
|
||||
tensor->deleter = array_dlpack_deleter;
|
||||
tensor->dl_tensor.ndim = ndim;
|
||||
tensor->dl_tensor.shape = reinterpret_cast<int64_t*>(reinterpret_cast<char*>(ptr) + sizeof(DLManagedTensor));
|
||||
tensor->dl_tensor.strides = tensor->dl_tensor.shape + ndim;
|
||||
fillDLPackTensor(src, tensor, device);
|
||||
|
||||
PyObject* capsule = PyCapsule_New(ptr, CV_DLPACK_CAPSULE_NAME, dlpack_capsule_deleter);
|
||||
if (!capsule) {
|
||||
PyMem_Free(ptr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// the capsule holds a reference
|
||||
Py_INCREF(self);
|
||||
|
||||
return capsule;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static PyObject* from_dlpack(PyObject* py_args, PyObject* kw)
|
||||
{
|
||||
PyObject* arr = nullptr;
|
||||
PyObject* device = nullptr;
|
||||
bool copy = false;
|
||||
const char* keywords[] = { "device", "copy", NULL };
|
||||
if (!PyArg_ParseTupleAndKeywords(py_args, kw, "O|Op:from_dlpack", (char**)keywords, &arr, &device, ©))
|
||||
return nullptr;
|
||||
|
||||
PyObject* capsule = nullptr;
|
||||
if (PyCapsule_CheckExact(arr))
|
||||
{
|
||||
capsule = arr;
|
||||
}
|
||||
else
|
||||
{
|
||||
PyGILState_STATE gstate;
|
||||
gstate = PyGILState_Ensure();
|
||||
capsule = PyObject_CallMethodObjArgs(arr, PyString_FromString("__dlpack__"), NULL);
|
||||
PyGILState_Release(gstate);
|
||||
}
|
||||
|
||||
DLManagedTensor* tensor = reinterpret_cast<DLManagedTensor*>(PyCapsule_GetPointer(capsule, CV_DLPACK_CAPSULE_NAME));
|
||||
if (tensor == nullptr)
|
||||
{
|
||||
if (capsule != arr)
|
||||
Py_DECREF(capsule);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
T retval;
|
||||
bool success = parseDLPackTensor(tensor, retval, copy);
|
||||
if (success)
|
||||
{
|
||||
PyCapsule_SetName(capsule, CV_DLPACK_USED_CAPSULE_NAME);
|
||||
}
|
||||
if (capsule != arr)
|
||||
Py_DECREF(capsule);
|
||||
|
||||
return success ? pyopencv_from(retval) : nullptr;
|
||||
}
|
||||
|
||||
static DLDataType GetDLPackType(size_t elemSize1, int depth) {
|
||||
DLDataType dtype;
|
||||
dtype.bits = static_cast<uint8_t>(8 * elemSize1);
|
||||
dtype.lanes = 1;
|
||||
switch (depth)
|
||||
{
|
||||
case CV_8S: case CV_16S: case CV_32S: dtype.code = kDLInt; break;
|
||||
case CV_8U: case CV_16U: dtype.code = kDLUInt; break;
|
||||
case CV_16F: case CV_32F: case CV_64F: dtype.code = kDLFloat; break;
|
||||
default:
|
||||
CV_Error(Error::StsNotImplemented, "__dlpack__ data type");
|
||||
}
|
||||
return dtype;
|
||||
}
|
||||
|
||||
static int DLPackTypeToCVType(const DLDataType& dtype, int channels) {
|
||||
if (dtype.code == kDLInt)
|
||||
{
|
||||
switch (dtype.bits)
|
||||
{
|
||||
case 8: return CV_8SC(channels);
|
||||
case 16: return CV_16SC(channels);
|
||||
case 32: return CV_32SC(channels);
|
||||
default:
|
||||
{
|
||||
PyErr_SetString(PyExc_BufferError,
|
||||
format("Unsupported int dlpack depth: %d", dtype.bits).c_str());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dtype.code == kDLUInt)
|
||||
{
|
||||
switch (dtype.bits)
|
||||
{
|
||||
case 8: return CV_8UC(channels);
|
||||
case 16: return CV_16UC(channels);
|
||||
default:
|
||||
{
|
||||
PyErr_SetString(PyExc_BufferError,
|
||||
format("Unsupported uint dlpack depth: %d", dtype.bits).c_str());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dtype.code == kDLFloat)
|
||||
{
|
||||
switch (dtype.bits)
|
||||
{
|
||||
case 16: return CV_16FC(channels);
|
||||
case 32: return CV_32FC(channels);
|
||||
case 64: return CV_64FC(channels);
|
||||
default:
|
||||
{
|
||||
PyErr_SetString(PyExc_BufferError,
|
||||
format("Unsupported float dlpack depth: %d", dtype.bits).c_str());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
PyErr_SetString(PyExc_BufferError, format("Unsupported dlpack data type: %d", dtype.code).c_str());
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define PYOPENCV_EXTRA_METHODS_CV \
|
||||
{"CV_MAKETYPE", CV_PY_FN_WITH_KW(pycvMakeType), "CV_MAKETYPE(depth, channels) -> retval"}, \
|
||||
{"CV_8UC", (PyCFunction)(pycvMakeTypeCh<CV_8U>), METH_O, "CV_8UC(channels) -> retval"}, \
|
||||
|
|
|
|||
|
|
@ -21,17 +21,175 @@ template<> struct pyopencvVecConverter<cuda::GpuMat>
|
|||
};
|
||||
|
||||
CV_PY_TO_CLASS(cuda::GpuMat)
|
||||
CV_PY_TO_CLASS(cuda::GpuMatND)
|
||||
CV_PY_TO_CLASS(cuda::Stream)
|
||||
CV_PY_TO_CLASS(cuda::Event)
|
||||
CV_PY_TO_CLASS(cuda::HostMem)
|
||||
|
||||
CV_PY_TO_CLASS_PTR(cuda::GpuMat)
|
||||
CV_PY_TO_CLASS_PTR(cuda::GpuMatND)
|
||||
CV_PY_TO_CLASS_PTR(cuda::GpuMat::Allocator)
|
||||
|
||||
CV_PY_FROM_CLASS(cuda::GpuMat)
|
||||
CV_PY_FROM_CLASS(cuda::GpuMatND)
|
||||
CV_PY_FROM_CLASS(cuda::Stream)
|
||||
CV_PY_FROM_CLASS(cuda::HostMem)
|
||||
|
||||
CV_PY_FROM_CLASS_PTR(cuda::GpuMat::Allocator)
|
||||
|
||||
template<>
|
||||
bool fillDLPackTensor(const Ptr<cv::cuda::GpuMat>& src, DLManagedTensor* tensor, const DLDevice& device)
|
||||
{
|
||||
if ((device.device_type != -1 && device.device_type != kDLCUDA) || device.device_id != 0)
|
||||
{
|
||||
PyErr_SetString(PyExc_BufferError, "GpuMat can be exported only on GPU:0");
|
||||
return false;
|
||||
}
|
||||
tensor->dl_tensor.data = src->cudaPtr();
|
||||
tensor->dl_tensor.device.device_type = kDLCUDA;
|
||||
tensor->dl_tensor.device.device_id = 0;
|
||||
tensor->dl_tensor.dtype = GetDLPackType(src->elemSize1(), src->depth());
|
||||
tensor->dl_tensor.shape[0] = src->rows;
|
||||
tensor->dl_tensor.shape[1] = src->cols;
|
||||
tensor->dl_tensor.shape[2] = src->channels();
|
||||
tensor->dl_tensor.strides[0] = src->step1();
|
||||
tensor->dl_tensor.strides[1] = src->channels();
|
||||
tensor->dl_tensor.strides[2] = 1;
|
||||
tensor->dl_tensor.byte_offset = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<>
|
||||
bool fillDLPackTensor(const Ptr<cv::cuda::GpuMatND>& src, DLManagedTensor* tensor, const DLDevice& device)
|
||||
{
|
||||
if ((device.device_type != -1 && device.device_type != kDLCUDA) || device.device_id != 0)
|
||||
{
|
||||
PyErr_SetString(PyExc_BufferError, "GpuMatND can be exported only on GPU:0");
|
||||
return false;
|
||||
}
|
||||
tensor->dl_tensor.data = src->getDevicePtr();
|
||||
tensor->dl_tensor.device.device_type = kDLCUDA;
|
||||
tensor->dl_tensor.device.device_id = 0;
|
||||
tensor->dl_tensor.dtype = GetDLPackType(src->elemSize1(), CV_MAT_DEPTH(src->flags));
|
||||
for (int i = 0; i < src->dims; ++i)
|
||||
tensor->dl_tensor.shape[i] = src->size[i];
|
||||
for (int i = 0; i < src->dims; ++i)
|
||||
tensor->dl_tensor.strides[i] = src->step[i];
|
||||
tensor->dl_tensor.byte_offset = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<>
|
||||
bool parseDLPackTensor(DLManagedTensor* tensor, cv::cuda::GpuMat& obj, bool copy)
|
||||
{
|
||||
if (tensor->dl_tensor.byte_offset != 0)
|
||||
{
|
||||
PyErr_SetString(PyExc_BufferError, "Unimplemented from_dlpack for GpuMat with memory offset");
|
||||
return false;
|
||||
}
|
||||
if (tensor->dl_tensor.ndim != 3)
|
||||
{
|
||||
PyErr_SetString(PyExc_BufferError, "cuda_GpuMat.from_dlpack expects a 3D tensor. Use cuda_GpuMatND.from_dlpack instead");
|
||||
return false;
|
||||
}
|
||||
if (tensor->dl_tensor.device.device_type != kDLCUDA)
|
||||
{
|
||||
PyErr_SetString(PyExc_BufferError, "cuda_GpuMat.from_dlpack expects a tensor on CUDA device");
|
||||
return false;
|
||||
}
|
||||
if (tensor->dl_tensor.strides[1] != tensor->dl_tensor.shape[2] ||
|
||||
tensor->dl_tensor.strides[2] != 1)
|
||||
{
|
||||
PyErr_SetString(PyExc_BufferError, "Unexpected strides for image. Try use GpuMatND");
|
||||
return false;
|
||||
}
|
||||
int type = DLPackTypeToCVType(tensor->dl_tensor.dtype, (int)tensor->dl_tensor.shape[2]);
|
||||
if (type == -1)
|
||||
return false;
|
||||
|
||||
obj = cv::cuda::GpuMat(
|
||||
static_cast<int>(tensor->dl_tensor.shape[0]),
|
||||
static_cast<int>(tensor->dl_tensor.shape[1]),
|
||||
type,
|
||||
tensor->dl_tensor.data,
|
||||
tensor->dl_tensor.strides[0] * tensor->dl_tensor.dtype.bits / 8
|
||||
);
|
||||
if (copy)
|
||||
obj = obj.clone();
|
||||
return true;
|
||||
}
|
||||
|
||||
template<>
|
||||
bool parseDLPackTensor(DLManagedTensor* tensor, cv::cuda::GpuMatND& obj, bool copy)
|
||||
{
|
||||
if (tensor->dl_tensor.byte_offset != 0)
|
||||
{
|
||||
PyErr_SetString(PyExc_BufferError, "Unimplemented from_dlpack for GpuMat with memory offset");
|
||||
return false;
|
||||
}
|
||||
if (tensor->dl_tensor.device.device_type != kDLCUDA)
|
||||
{
|
||||
PyErr_SetString(PyExc_BufferError, "cuda_GpuMat.from_dlpack expects a tensor on CUDA device");
|
||||
return false;
|
||||
}
|
||||
int type = DLPackTypeToCVType(tensor->dl_tensor.dtype, (int)tensor->dl_tensor.shape[2]);
|
||||
if (type == -1)
|
||||
return false;
|
||||
|
||||
std::vector<size_t> steps(tensor->dl_tensor.ndim - 1);
|
||||
std::vector<int> sizes(tensor->dl_tensor.ndim);
|
||||
for (int i = 0; i < tensor->dl_tensor.ndim - 1; ++i)
|
||||
{
|
||||
steps[i] = tensor->dl_tensor.strides[i] * tensor->dl_tensor.dtype.bits / 8;
|
||||
sizes[i] = static_cast<int>(tensor->dl_tensor.shape[i]);
|
||||
}
|
||||
sizes.back() = static_cast<int>(tensor->dl_tensor.shape[tensor->dl_tensor.ndim - 1]);
|
||||
obj = cv::cuda::GpuMatND(sizes, type, tensor->dl_tensor.data, steps);
|
||||
if (copy)
|
||||
obj = obj.clone();
|
||||
return true;
|
||||
}
|
||||
|
||||
template<>
|
||||
int GetNumDims(const Ptr<cv::cuda::GpuMat>& src) { return 3; }
|
||||
|
||||
template<>
|
||||
int GetNumDims(const Ptr<cv::cuda::GpuMatND>& src) { return src->dims; }
|
||||
|
||||
static PyObject* pyDLPackGpuMat(PyObject* self, PyObject* py_args, PyObject* kw) {
|
||||
Ptr<cv::cuda::GpuMat> * self1 = 0;
|
||||
if (!pyopencv_cuda_GpuMat_getp(self, self1))
|
||||
return failmsgp("Incorrect type of self (must be 'cuda_GpuMat' or its derivative)");
|
||||
return to_dlpack(*(self1), self, py_args, kw);
|
||||
}
|
||||
|
||||
static PyObject* pyDLPackGpuMatND(PyObject* self, PyObject* py_args, PyObject* kw) {
|
||||
Ptr<cv::cuda::GpuMatND> * self1 = 0;
|
||||
if (!pyopencv_cuda_GpuMatND_getp(self, self1))
|
||||
return failmsgp("Incorrect type of self (must be 'cuda_GpuMatND' or its derivative)");
|
||||
return to_dlpack(*(self1), self, py_args, kw);
|
||||
}
|
||||
|
||||
static PyObject* pyDLPackDeviceCUDA(PyObject*, PyObject*, PyObject*) {
|
||||
return pyopencv_from(std::tuple<int, int>(kDLCUDA, 0));
|
||||
}
|
||||
|
||||
static PyObject* pyGpuMatFromDLPack(PyObject*, PyObject* py_args, PyObject* kw) {
|
||||
return from_dlpack<cv::cuda::GpuMat>(py_args, kw);
|
||||
}
|
||||
|
||||
static PyObject* pyGpuMatNDFromDLPack(PyObject*, PyObject* py_args, PyObject* kw) {
|
||||
return from_dlpack<cv::cuda::GpuMatND>(py_args, kw);
|
||||
}
|
||||
|
||||
#define PYOPENCV_EXTRA_METHODS_cuda_GpuMat \
|
||||
{"__dlpack__", CV_PY_FN_WITH_KW(pyDLPackGpuMat), ""}, \
|
||||
{"__dlpack_device__", CV_PY_FN_WITH_KW(pyDLPackDeviceCUDA), ""}, \
|
||||
{"from_dlpack", CV_PY_FN_WITH_KW_(pyGpuMatFromDLPack, METH_STATIC), ""}, \
|
||||
|
||||
#define PYOPENCV_EXTRA_METHODS_cuda_GpuMatND \
|
||||
{"__dlpack__", CV_PY_FN_WITH_KW(pyDLPackGpuMatND), ""}, \
|
||||
{"__dlpack_device__", CV_PY_FN_WITH_KW(pyDLPackDeviceCUDA), ""}, \
|
||||
{"from_dlpack", CV_PY_FN_WITH_KW_(pyGpuMatNDFromDLPack, METH_STATIC), ""}, \
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -60,6 +60,14 @@ namespace cv
|
|||
#undef USE_IPP_DFT
|
||||
#endif
|
||||
|
||||
#if defined USE_IPP_DFT
|
||||
#if IPP_VERSION_X100 >= 202220
|
||||
#define IPP_DISABLE_DFT32F ((depth == CV_32F) && (ippCPUID_AVX512F&cv::ipp::getIppFeatures()))
|
||||
#else
|
||||
#define IPP_DISABLE_DFT32F false
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/****************************************************************************************\
|
||||
Discrete Fourier Transform
|
||||
\****************************************************************************************/
|
||||
|
|
@ -3258,7 +3266,7 @@ public:
|
|||
opt.ipp_spec = 0;
|
||||
opt.ipp_work = 0;
|
||||
|
||||
if( CV_IPP_CHECK_COND && (opt.n*count >= 64) ) // use IPP DFT if available
|
||||
if( CV_IPP_CHECK_COND && (opt.n*count >= 64) && !IPP_DISABLE_DFT32F) // use IPP DFT if available
|
||||
{
|
||||
int ipp_norm_flag = (flags & CV_HAL_DFT_SCALE) == 0 ? 8 : opt.isInverse ? 2 : 1;
|
||||
int specsize=0, initsize=0, worksize=0;
|
||||
|
|
|
|||
67
modules/dnn/misc/java/test/DnnForwardAndRetrieve.java
Normal file
67
modules/dnn/misc/java/test/DnnForwardAndRetrieve.java
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
package org.opencv.test.dnn;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.opencv.core.Core;
|
||||
import org.opencv.core.CvType;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.MatOfByte;
|
||||
import org.opencv.core.Range;
|
||||
import org.opencv.dnn.Dnn;
|
||||
import org.opencv.dnn.Net;
|
||||
import org.opencv.test.OpenCVTestCase;
|
||||
|
||||
public class DnnForwardAndRetrieve extends OpenCVTestCase {
|
||||
|
||||
public void testForwardAndRetrieve()
|
||||
{
|
||||
// Create a simple Caffe prototxt with a Slice layer
|
||||
String prototxt =
|
||||
"input: \"data\"\n" +
|
||||
"layer {\n" +
|
||||
" name: \"testLayer\"\n" +
|
||||
" type: \"Slice\"\n" +
|
||||
" bottom: \"data\"\n" +
|
||||
" top: \"firstCopy\"\n" +
|
||||
" top: \"secondCopy\"\n" +
|
||||
" slice_param {\n" +
|
||||
" axis: 0\n" +
|
||||
" slice_point: 2\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
// Read network from prototxt
|
||||
MatOfByte bufferProto = new MatOfByte();
|
||||
bufferProto.fromArray(prototxt.getBytes());
|
||||
MatOfByte bufferModel = new MatOfByte();
|
||||
Net net = Dnn.readNetFromCaffe(bufferProto, bufferModel, Dnn.ENGINE_CLASSIC);
|
||||
net.setPreferableBackend(Dnn.DNN_BACKEND_OPENCV);
|
||||
|
||||
// Create input data
|
||||
Mat inp = new Mat(4, 5, CvType.CV_32F);
|
||||
Core.randu(inp, -1, 1);
|
||||
net.setInput(inp);
|
||||
|
||||
// Define output names
|
||||
List<String> outNames = new ArrayList<>();
|
||||
outNames.add("testLayer");
|
||||
|
||||
// Forward and retrieve multiple outputs
|
||||
List<List<Mat>> outBlobs = new ArrayList<>();
|
||||
net.forwardAndRetrieve(outBlobs, outNames);
|
||||
|
||||
// Verify results
|
||||
assertEquals(1, outBlobs.size());
|
||||
assertEquals(2, outBlobs.get(0).size());
|
||||
|
||||
// Compare results
|
||||
Mat expectedFirst = inp.rowRange(0, 2);
|
||||
Mat expectedSecond = inp.rowRange(2, 4);
|
||||
|
||||
Mat actualFirst = outBlobs.get(0).get(0);
|
||||
Mat actualSecond = outBlobs.get(0).get(1);
|
||||
|
||||
assertEquals(0, Core.norm(expectedFirst, actualFirst, Core.NORM_INF), EPS);
|
||||
assertEquals(0, Core.norm(expectedSecond, actualSecond, Core.NORM_INF), EPS);
|
||||
}
|
||||
}
|
||||
|
|
@ -1110,13 +1110,27 @@ public:
|
|||
*/
|
||||
CV_WRAP Subdiv2D(Rect rect);
|
||||
|
||||
/** @brief Creates a new empty Delaunay subdivision
|
||||
/** @overload */
|
||||
CV_WRAP Subdiv2D(Rect2f rect2f);
|
||||
|
||||
/** @overload
|
||||
|
||||
@brief Creates a new empty Delaunay subdivision
|
||||
|
||||
@param rect Rectangle that includes all of the 2D points that are to be added to the subdivision.
|
||||
|
||||
*/
|
||||
CV_WRAP void initDelaunay(Rect rect);
|
||||
|
||||
/** @overload
|
||||
|
||||
@brief Creates a new empty Delaunay subdivision
|
||||
|
||||
@param rect Rectangle that includes all of the 2d points that are to be added to the subdivision.
|
||||
|
||||
*/
|
||||
CV_WRAP_AS(initDelaunay2f) CV_WRAP void initDelaunay(Rect2f rect);
|
||||
|
||||
/** @brief Insert a single point into a Delaunay triangulation.
|
||||
|
||||
@param pt Point to insert.
|
||||
|
|
|
|||
|
|
@ -118,6 +118,16 @@ Subdiv2D::Subdiv2D(Rect rect)
|
|||
initDelaunay(rect);
|
||||
}
|
||||
|
||||
Subdiv2D::Subdiv2D(Rect2f rect)
|
||||
{
|
||||
validGeometry = false;
|
||||
freeQEdge = 0;
|
||||
freePoint = 0;
|
||||
recentEdge = 0;
|
||||
|
||||
initDelaunay(rect);
|
||||
}
|
||||
|
||||
|
||||
Subdiv2D::QuadEdge::QuadEdge()
|
||||
{
|
||||
|
|
@ -535,6 +545,52 @@ void Subdiv2D::initDelaunay( Rect rect )
|
|||
recentEdge = edge_AB;
|
||||
}
|
||||
|
||||
void Subdiv2D::initDelaunay( Rect2f rect )
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
float big_coord = 6.f * MAX( rect.width, rect.height );
|
||||
float rx = rect.x;
|
||||
float ry = rect.y;
|
||||
|
||||
vtx.clear();
|
||||
qedges.clear();
|
||||
|
||||
recentEdge = 0;
|
||||
validGeometry = false;
|
||||
|
||||
topLeft = Point2f( rx, ry );
|
||||
bottomRight = Point2f( rx + rect.width, ry + rect.height );
|
||||
|
||||
Point2f ppA( rx + big_coord, ry );
|
||||
Point2f ppB( rx, ry + big_coord );
|
||||
Point2f ppC( rx - big_coord, ry - big_coord );
|
||||
|
||||
vtx.push_back(Vertex());
|
||||
qedges.push_back(QuadEdge());
|
||||
|
||||
freeQEdge = 0;
|
||||
freePoint = 0;
|
||||
|
||||
int pA = newPoint(ppA, false);
|
||||
int pB = newPoint(ppB, false);
|
||||
int pC = newPoint(ppC, false);
|
||||
|
||||
int edge_AB = newEdge();
|
||||
int edge_BC = newEdge();
|
||||
int edge_CA = newEdge();
|
||||
|
||||
setEdgePoints( edge_AB, pA, pB );
|
||||
setEdgePoints( edge_BC, pB, pC );
|
||||
setEdgePoints( edge_CA, pC, pA );
|
||||
|
||||
splice( edge_AB, symEdge( edge_CA ));
|
||||
splice( edge_BC, symEdge( edge_AB ));
|
||||
splice( edge_CA, symEdge( edge_BC ));
|
||||
|
||||
recentEdge = edge_AB;
|
||||
}
|
||||
|
||||
|
||||
void Subdiv2D::clearVoronoi()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -11,10 +11,13 @@ namespace opencv_test { namespace {
|
|||
// return true if point lies inside ellipse
|
||||
static bool check_pt_in_ellipse(const Point2f& pt, const RotatedRect& el) {
|
||||
Point2f to_pt = pt - el.center;
|
||||
double pt_angle = atan2(to_pt.y, to_pt.x);
|
||||
double el_angle = el.angle * CV_PI / 180;
|
||||
double x_dist = 0.5 * el.size.width * cos(pt_angle + el_angle);
|
||||
double y_dist = 0.5 * el.size.height * sin(pt_angle + el_angle);
|
||||
const Point2d to_pt_el(
|
||||
to_pt.x * cos(-el_angle) - to_pt.y * sin(-el_angle),
|
||||
to_pt.x * sin(-el_angle) + to_pt.y * cos(-el_angle));
|
||||
const double pt_angle = atan2(to_pt_el.y / el.size.height, to_pt_el.x / el.size.width);
|
||||
const double x_dist = 0.5 * el.size.width * cos(pt_angle);
|
||||
const double y_dist = 0.5 * el.size.height * sin(pt_angle);
|
||||
double el_dist = sqrt(x_dist * x_dist + y_dist * y_dist);
|
||||
return cv::norm(to_pt) < el_dist;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,4 +64,57 @@ TEST(Imgproc_Subdiv2D, issue_25696) {
|
|||
|
||||
ASSERT_EQ(static_cast<size_t>(2), triangles.size());
|
||||
}
|
||||
|
||||
// Initialization test
|
||||
TEST(Imgproc_Subdiv2D, rect2f_constructor_and_init)
|
||||
{
|
||||
cv::Rect2f rect_f(0.5f, 1.5f, 100.7f, 200.3f);
|
||||
cv::Subdiv2D subdiv_f(rect_f);
|
||||
|
||||
cv::Point2f pt1(50.2f, 80.1f);
|
||||
cv::Point2f pt2(75.8f, 120.9f);
|
||||
cv::Point2f pt3(25.5f, 150.3f);
|
||||
|
||||
EXPECT_NO_THROW(subdiv_f.insert(pt1));
|
||||
EXPECT_NO_THROW(subdiv_f.insert(pt2));
|
||||
EXPECT_NO_THROW(subdiv_f.insert(pt3));
|
||||
|
||||
cv::Subdiv2D subdiv_init;
|
||||
|
||||
EXPECT_NO_THROW(subdiv_init.initDelaunay(rect_f));
|
||||
EXPECT_NO_THROW(subdiv_init.insert(pt1));
|
||||
EXPECT_NO_THROW(subdiv_init.insert(pt2));
|
||||
EXPECT_NO_THROW(subdiv_init.insert(pt3));
|
||||
|
||||
std::vector<cv::Vec6f> triangles;
|
||||
|
||||
EXPECT_NO_THROW(subdiv_f.getTriangleList(triangles));
|
||||
EXPECT_GT(triangles.size(), 0u);
|
||||
}
|
||||
|
||||
// test with small coordinates
|
||||
TEST(Imgproc_Subdiv2D, rect2f_edge_cases)
|
||||
{
|
||||
cv::Rect2f small_rect(0.0f, 0.0f, 0.1f, 0.1f);
|
||||
cv::Subdiv2D subdiv_small(small_rect);
|
||||
|
||||
cv::Point2f small_pt(0.05f, 0.05f);
|
||||
EXPECT_NO_THROW(subdiv_small.insert(small_pt));
|
||||
cv::Rect2f float_rect(10.25f, 20.75f, 50.5f, 30.25f);
|
||||
|
||||
cv::Subdiv2D subdiv_float(float_rect);
|
||||
|
||||
cv::Point2f float_pt1(35.125f, 35.875f);
|
||||
cv::Point2f float_pt2(45.375f, 25.625f);
|
||||
cv::Point2f float_pt3(55.750f, 45.125f);
|
||||
|
||||
EXPECT_NO_THROW(subdiv_float.insert(float_pt1));
|
||||
EXPECT_NO_THROW(subdiv_float.insert(float_pt2));
|
||||
EXPECT_NO_THROW(subdiv_float.insert(float_pt3));
|
||||
|
||||
std::vector<cv::Vec6f> triangles;
|
||||
|
||||
subdiv_float.getTriangleList(triangles);
|
||||
EXPECT_GT(triangles.size(), 0u);
|
||||
}
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -756,6 +756,13 @@ class JavaWrapperGenerator(object):
|
|||
"jdouble _tmp_retval_[%(cnt)i] = {%(args)s}; " +
|
||||
"env->SetDoubleArrayRegion(_da_retval_, 0, %(cnt)i, _tmp_retval_);") %
|
||||
{ "cnt" : len(fields), "args" : ", ".join(["(jdouble)_retval_" + f[1] for f in fields]) } )
|
||||
elif type_dict[fi.ctype]["jni_type"] == "jintArray":
|
||||
fields = type_dict[fi.ctype]["jn_args"]
|
||||
c_epilogue.append(
|
||||
("jintArray _ia_retval_ = env->NewIntArray(%(cnt)i); " +
|
||||
"jint _tmp_retval_[%(cnt)i] = {%(args)s}; " +
|
||||
"env->SetIntArrayRegion(_ia_retval_, 0, %(cnt)i, _tmp_retval_);") %
|
||||
{ "cnt" : len(fields), "args" : ", ".join(["(jint)_retval_" + f[1] for f in fields]) } )
|
||||
if fi.classname and fi.ctype and not fi.static: # non-static class method except c-tor
|
||||
# adding 'self'
|
||||
jn_args.append ( ArgInfo([ "__int64", "nativeObj", "", [], "" ]) )
|
||||
|
|
@ -803,7 +810,14 @@ class JavaWrapperGenerator(object):
|
|||
fields = type_dict[a.ctype].get("jn_args", ((a.ctype, ""),))
|
||||
if "I" in a.out or not a.out or self.isWrapped(a.ctype): # input arg, pass by primitive fields
|
||||
for f in fields:
|
||||
jn_args.append ( ArgInfo([ f[0], a.name + f[1], "", [], "" ]) )
|
||||
# Use array access format for Java code when jn_type is array type
|
||||
if type_dict[a.ctype].get("jn_type", "").endswith("[]"):
|
||||
# For Java code: convert .val[0] format to [0] format
|
||||
jn_args.append ( ArgInfo([ f[0], a.name + f[1].replace(".val[", "["), "", [], "" ]) )
|
||||
else:
|
||||
# For non-array types, use conventional format
|
||||
jn_args.append ( ArgInfo([ f[0], a.name + f[1], "", [], "" ]) )
|
||||
# For C++ code: use conventional format as is
|
||||
jni_args.append( ArgInfo([ f[0], a.name + normalize_field_name(f[1]), "", [], "" ]) )
|
||||
if "O" in a.out and not self.isWrapped(a.ctype): # out arg, pass as double[]
|
||||
jn_args.append ( ArgInfo([ "double[]", "%s_out" % a.name, "", [], "" ]) )
|
||||
|
|
@ -818,9 +832,16 @@ class JavaWrapperGenerator(object):
|
|||
set_vals = []
|
||||
i = 0
|
||||
for f in fields:
|
||||
set_vals.append( "%(n)s%(f)s = %(t)s%(n)s_out[%(i)i]" %
|
||||
{"n" : a.name, "t": ("("+type_dict[f[0]]["j_type"]+")", "")[f[0]=="double"], "f" : f[1], "i" : i}
|
||||
)
|
||||
# Use array access format for Java code when jn_type is array type
|
||||
if type_dict[a.ctype].get("jn_type", "").endswith("[]"):
|
||||
# For Java code: convert .val[0] format to [0] format
|
||||
set_vals.append( "%(n)s%(f)s = %(t)s%(n)s_out[%(i)i]" %
|
||||
{"n" : a.name, "t": ("("+type_dict[f[0]]["j_type"]+")", "")[f[0]=="double"], "f" : f[1].replace(".val[", "["), "i" : i}
|
||||
)
|
||||
else:
|
||||
set_vals.append( "%(n)s%(f)s = %(t)s%(n)s_out[%(i)i]" %
|
||||
{"n" : a.name, "t": ("("+type_dict[f[0]]["j_type"]+")", "")[f[0]=="double"], "f" : f[1], "i" : i}
|
||||
)
|
||||
i += 1
|
||||
j_epilogue.append( "if("+a.name+"!=null){ " + "; ".join(set_vals) + "; } ")
|
||||
|
||||
|
|
@ -1015,6 +1036,8 @@ class JavaWrapperGenerator(object):
|
|||
ret = "return (jlong) _retval_;"
|
||||
elif type_dict[fi.ctype]["jni_type"] == "jdoubleArray":
|
||||
ret = "return _da_retval_;"
|
||||
elif type_dict[fi.ctype]["jni_type"] == "jintArray":
|
||||
ret = "return _ia_retval_;"
|
||||
elif "jni_var" in type_dict[ret_type]:
|
||||
c_epilogue.append(type_dict[ret_type]["jni_var"] % {"n" : '_retval_'})
|
||||
ret = f"return {type_dict[ret_type]['jni_name'] % {'n' : '_retval_'}};"
|
||||
|
|
|
|||
|
|
@ -219,6 +219,32 @@ void vector_Mat_to_Mat(std::vector<cv::Mat>& v_mat, cv::Mat& mat)
|
|||
}
|
||||
}
|
||||
|
||||
void Mat_to_vector_vector_Mat(Mat& mat, std::vector< std::vector< Mat > >& vv_mat)
|
||||
{
|
||||
std::vector<Mat> vm;
|
||||
vm.reserve( mat.rows );
|
||||
Mat_to_vector_Mat(mat, vm);
|
||||
for(size_t i=0; i<vm.size(); i++)
|
||||
{
|
||||
std::vector<Mat> vmat;
|
||||
Mat_to_vector_Mat(vm[i], vmat);
|
||||
vv_mat.push_back(vmat);
|
||||
}
|
||||
}
|
||||
|
||||
void vector_vector_Mat_to_Mat(std::vector< std::vector< Mat > >& vv_mat, Mat& mat)
|
||||
{
|
||||
std::vector<Mat> vm;
|
||||
vm.reserve( vv_mat.size() );
|
||||
for(size_t i=0; i<vv_mat.size(); i++)
|
||||
{
|
||||
Mat m;
|
||||
vector_Mat_to_Mat(vv_mat[i], m);
|
||||
vm.push_back(m);
|
||||
}
|
||||
vector_Mat_to_Mat(vm, mat);
|
||||
}
|
||||
|
||||
void Mat_to_vector_vector_Point(Mat& mat, std::vector< std::vector< Point > >& vv_pt)
|
||||
{
|
||||
std::vector<Mat> vm;
|
||||
|
|
|
|||
|
|
@ -50,6 +50,9 @@ void vector_Vec6f_to_Mat(std::vector<cv::Vec6f>& v_vec, cv::Mat& mat);
|
|||
void Mat_to_vector_Mat(cv::Mat& mat, std::vector<cv::Mat>& v_mat);
|
||||
void vector_Mat_to_Mat(std::vector<cv::Mat>& v_mat, cv::Mat& mat);
|
||||
|
||||
void Mat_to_vector_vector_Mat(cv::Mat& mat, std::vector< std::vector< cv::Mat > >& vv_mat);
|
||||
void vector_vector_Mat_to_Mat(std::vector< std::vector< cv::Mat > >& vv_mat, cv::Mat& mat);
|
||||
|
||||
void Mat_to_vector_vector_char(cv::Mat& mat, std::vector< std::vector< char > >& vv_ch);
|
||||
void vector_vector_char_to_Mat(std::vector< std::vector< char > >& vv_ch, cv::Mat& mat);
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import org.opencv.core.CvType;
|
|||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.MatOfByte;
|
||||
import org.opencv.core.MatOfDMatch;
|
||||
import org.opencv.core.MatOfInt;
|
||||
import org.opencv.core.MatOfKeyPoint;
|
||||
import org.opencv.core.MatOfPoint;
|
||||
import org.opencv.core.MatOfPoint2f;
|
||||
|
|
@ -514,6 +515,41 @@ public class Converters {
|
|||
}
|
||||
}
|
||||
|
||||
// vector_vector_Mat
|
||||
public static Mat vector_vector_Mat_to_Mat(List<List<Mat>> vecMats, List<Mat> mats) {
|
||||
Mat res;
|
||||
int lCount = (vecMats != null) ? vecMats.size() : 0;
|
||||
if (lCount > 0) {
|
||||
for (List<Mat> matList : vecMats) {
|
||||
Mat mat = vector_Mat_to_Mat(matList);
|
||||
mats.add(mat);
|
||||
}
|
||||
res = vector_Mat_to_Mat(mats);
|
||||
} else {
|
||||
res = new Mat();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public static void Mat_to_vector_vector_Mat(Mat m, List<List<Mat>> vecMats) {
|
||||
if (vecMats == null)
|
||||
throw new IllegalArgumentException("Output List can't be null");
|
||||
|
||||
if (m == null)
|
||||
throw new IllegalArgumentException("Input Mat can't be null");
|
||||
|
||||
vecMats.clear();
|
||||
List<Mat> mats = new ArrayList<Mat>(m.rows());
|
||||
Mat_to_vector_Mat(m, mats);
|
||||
for (Mat mi : mats) {
|
||||
List<Mat> rowList = new ArrayList<Mat>(mi.rows());
|
||||
Mat_to_vector_Mat(mi, rowList);
|
||||
vecMats.add(rowList);
|
||||
mi.release();
|
||||
}
|
||||
mats.clear();
|
||||
}
|
||||
|
||||
// vector_vector_Point
|
||||
public static Mat vector_vector_Point_to_Mat(List<MatOfPoint> pts, List<Mat> mats) {
|
||||
Mat res;
|
||||
|
|
@ -803,4 +839,75 @@ public class Converters {
|
|||
rs.add(new RotatedRect(new Point(buff[5 * i], buff[5 * i + 1]), new Size(buff[5 * i + 2], buff[5 * i + 3]), buff[5 * i + 4]));
|
||||
}
|
||||
}
|
||||
|
||||
// vector_MatShape
|
||||
public static Mat vector_MatShape_to_Mat(List<MatOfInt> matOfInts) {
|
||||
Mat res;
|
||||
int count = (matOfInts != null) ? matOfInts.size() : 0;
|
||||
if (count > 0) {
|
||||
res = new Mat(count, 1, CvType.CV_32SC2);
|
||||
int[] buff = new int[count * 2];
|
||||
for (int i = 0; i < count; i++) {
|
||||
long addr = matOfInts.get(i).nativeObj;
|
||||
buff[i * 2] = (int) (addr >> 32);
|
||||
buff[i * 2 + 1] = (int) (addr & 0xffffffff);
|
||||
}
|
||||
res.put(0, 0, buff);
|
||||
} else {
|
||||
res = new Mat();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public static void Mat_to_vector_MatShape(Mat m, List<MatOfInt> matOfInts) {
|
||||
if (matOfInts == null)
|
||||
throw new IllegalArgumentException("matOfInts == null");
|
||||
int count = m.rows();
|
||||
if (CvType.CV_32SC2 != m.type() || m.cols() != 1)
|
||||
throw new IllegalArgumentException(
|
||||
"CvType.CV_32SC2 != m.type() || m.cols()!=1\n" + m);
|
||||
|
||||
matOfInts.clear();
|
||||
int[] buff = new int[count * 2];
|
||||
m.get(0, 0, buff);
|
||||
for (int i = 0; i < count; i++) {
|
||||
long addr = (((long) buff[i * 2]) << 32) | (((long) buff[i * 2 + 1]) & 0xffffffffL);
|
||||
matOfInts.add(MatOfInt.fromNativeAddr(addr));
|
||||
}
|
||||
}
|
||||
|
||||
// vector_vector_MatShape
|
||||
public static Mat vector_vector_MatShape_to_Mat(List<List<MatOfInt>> vecMatOfInts, List<Mat> mats) {
|
||||
Mat res;
|
||||
int lCount = (vecMatOfInts != null) ? vecMatOfInts.size() : 0;
|
||||
if (lCount > 0) {
|
||||
for (List<MatOfInt> matList : vecMatOfInts) {
|
||||
Mat mat = vector_MatShape_to_Mat(matList);
|
||||
mats.add(mat);
|
||||
}
|
||||
res = vector_Mat_to_Mat(mats);
|
||||
} else {
|
||||
res = new Mat();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public static void Mat_to_vector_vector_MatShape(Mat m, List<List<MatOfInt>> vecMatOfInts) {
|
||||
if (vecMatOfInts == null)
|
||||
throw new IllegalArgumentException("Output List can't be null");
|
||||
|
||||
if (m == null)
|
||||
throw new IllegalArgumentException("Input Mat can't be null");
|
||||
|
||||
vecMatOfInts.clear();
|
||||
List<Mat> mats = new ArrayList<Mat>(m.rows());
|
||||
Mat_to_vector_Mat(m, mats);
|
||||
for (Mat mi : mats) {
|
||||
List<MatOfInt> rowList = new ArrayList<MatOfInt>(mi.rows());
|
||||
Mat_to_vector_MatShape(mi, rowList);
|
||||
vecMatOfInts.add(rowList);
|
||||
mi.release();
|
||||
}
|
||||
mats.clear();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,13 +68,20 @@ if(DEFINED OPENCV_PYTHON_INSTALL_PATH)
|
|||
endif()
|
||||
set(CMAKE_PYTHON_BINARIES_PATH "${CMAKE_PYTHON_BINARIES_INSTALL_PATH}")
|
||||
if (WIN32 AND HAVE_CUDA)
|
||||
set(_cuda_bin_dir "bin")
|
||||
if (ENABLE_CUDA_FIRST_CLASS_LANGUAGE)
|
||||
if (DEFINED CUDAToolkit_LIBRARY_ROOT)
|
||||
list(APPEND CMAKE_PYTHON_BINARIES_PATH "os.path.join(os.getenv('CUDA_PATH', '${CUDAToolkit_LIBRARY_ROOT}'), 'bin')")
|
||||
if(DEFINED CUDAToolkit_VERSION_MAJOR AND CUDAToolkit_VERSION_MAJOR GREATER_EQUAL 13)
|
||||
set(_cuda_bin_dir "bin/x64")
|
||||
endif()
|
||||
list(APPEND CMAKE_PYTHON_BINARIES_PATH "os.path.join(os.getenv('CUDA_PATH', '${CUDAToolkit_LIBRARY_ROOT}'), '${_cuda_bin_dir}')")
|
||||
endif()
|
||||
else()
|
||||
if (DEFINED CUDA_TOOLKIT_ROOT_DIR)
|
||||
list(APPEND CMAKE_PYTHON_BINARIES_PATH "os.path.join(os.getenv('CUDA_PATH', '${CUDA_TOOLKIT_ROOT_DIR}'), 'bin')")
|
||||
if(DEFINED CUDA_VERSION_MAJOR AND CUDA_VERSION_MAJOR GREATER_EQUAL 13)
|
||||
set(_cuda_bin_dir "bin/x64")
|
||||
endif()
|
||||
list(APPEND CMAKE_PYTHON_BINARIES_PATH "os.path.join(os.getenv('CUDA_PATH', '${CUDA_TOOLKIT_ROOT_DIR}'), '${_cuda_bin_dir}')")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -133,6 +133,9 @@ static PyGetSetDef pyopencv_${name}_getseters[] =
|
|||
|
||||
static PyMethodDef pyopencv_${name}_methods[] =
|
||||
{
|
||||
#ifdef PYOPENCV_EXTRA_METHODS_${name}
|
||||
PYOPENCV_EXTRA_METHODS_${name}
|
||||
#endif
|
||||
${methods_inits}
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ class cuda_test(NewOpenCVTests):
|
|||
self.assertTrue(cuMat.step == 0)
|
||||
self.assertTrue(cuMat.size() == (0, 0))
|
||||
|
||||
@unittest.skip("failed test")
|
||||
def test_cuda_convertTo(self):
|
||||
# setup
|
||||
npMat_8UC4 = (np.random.random((128, 128, 4)) * 255).astype(np.uint8)
|
||||
|
|
@ -105,6 +106,7 @@ class cuda_test(NewOpenCVTests):
|
|||
stream.waitForCompletion()
|
||||
self.assertTrue(np.array_equal(npMat_32FC4, npMat_32FC4_out))
|
||||
|
||||
@unittest.skip("failed test")
|
||||
def test_cuda_copyTo(self):
|
||||
# setup
|
||||
npMat_8UC4 = (np.random.random((128, 128, 4)) * 255).astype(np.uint8)
|
||||
|
|
@ -143,5 +145,18 @@ class cuda_test(NewOpenCVTests):
|
|||
self.assertEqual(True, hasattr(cv.cuda, 'fastNlMeansDenoisingColored'))
|
||||
self.assertEqual(True, hasattr(cv.cuda, 'nonLocalMeans'))
|
||||
|
||||
def test_dlpack_GpuMat(self):
|
||||
for dtype in [np.int8, np.uint8, np.int16, np.uint16, np.float16, np.int32, np.float32, np.float64]:
|
||||
for channels in [2, 3, 5]:
|
||||
ref = (np.random.random((64, 128, channels)) * 255).astype(dtype)
|
||||
src = cv.cuda_GpuMat()
|
||||
src.upload(ref)
|
||||
dst = cv.cuda_GpuMat.from_dlpack(src)
|
||||
test = dst.download()
|
||||
equal = np.array_equal(ref, test)
|
||||
if not equal:
|
||||
print(f"Failed test with dtype {dtype} and {channels} channels")
|
||||
self.assertTrue(equal)
|
||||
|
||||
if __name__ == '__main__':
|
||||
NewOpenCVTests.bootstrap()
|
||||
|
|
|
|||
|
|
@ -711,7 +711,15 @@ enum VideoCaptureOBSensorProperties{
|
|||
CAP_PROP_OBSENSOR_DEPTH_POS_MSEC=26006,
|
||||
CAP_PROP_OBSENSOR_DEPTH_WIDTH=26007,
|
||||
CAP_PROP_OBSENSOR_DEPTH_HEIGHT=26008,
|
||||
CAP_PROP_OBSENSOR_DEPTH_FPS=26009
|
||||
CAP_PROP_OBSENSOR_DEPTH_FPS=26009,
|
||||
CAP_PROP_OBSENSOR_COLOR_DISTORTION_K1=26010,
|
||||
CAP_PROP_OBSENSOR_COLOR_DISTORTION_K2=26011,
|
||||
CAP_PROP_OBSENSOR_COLOR_DISTORTION_K3=26012,
|
||||
CAP_PROP_OBSENSOR_COLOR_DISTORTION_K4=26013,
|
||||
CAP_PROP_OBSENSOR_COLOR_DISTORTION_K5=26014,
|
||||
CAP_PROP_OBSENSOR_COLOR_DISTORTION_K6=26015,
|
||||
CAP_PROP_OBSENSOR_COLOR_DISTORTION_P1=26016,
|
||||
CAP_PROP_OBSENSOR_COLOR_DISTORTION_P2=26017
|
||||
};
|
||||
|
||||
//! @} OBSENSOR
|
||||
|
|
|
|||
|
|
@ -685,7 +685,10 @@ void CvCapture_FFMPEG::close()
|
|||
if( video_st )
|
||||
{
|
||||
#ifdef CV_FFMPEG_CODECPAR
|
||||
// avcodec_close removed in FFmpeg release 8.0
|
||||
# if (LIBAVCODEC_BUILD < CALC_FFMPEG_VERSION(62, 11, 100))
|
||||
avcodec_close( context );
|
||||
# endif
|
||||
#endif
|
||||
video_st = NULL;
|
||||
}
|
||||
|
|
@ -2005,7 +2008,18 @@ void CvCapture_FFMPEG::get_rotation_angle()
|
|||
rotation_angle = 0;
|
||||
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(57, 68, 100)
|
||||
const uint8_t *data = 0;
|
||||
// av_stream_get_side_data removed in FFmpeg release 8.0
|
||||
# if (LIBAVCODEC_BUILD < CALC_FFMPEG_VERSION(62, 11, 100))
|
||||
data = av_stream_get_side_data(video_st, AV_PKT_DATA_DISPLAYMATRIX, NULL);
|
||||
# else
|
||||
AVPacketSideData* sd = video_st->codecpar->coded_side_data;
|
||||
int nb_sd = video_st->codecpar->nb_coded_side_data;
|
||||
if (sd && nb_sd > 0)
|
||||
{
|
||||
const AVPacketSideData* mtx = av_packet_side_data_get(sd, nb_sd, AV_PKT_DATA_DISPLAYMATRIX);
|
||||
data = mtx->data;
|
||||
}
|
||||
# endif
|
||||
if (data)
|
||||
{
|
||||
rotation_angle = -cvRound(av_display_rotation_get((const int32_t*)data));
|
||||
|
|
|
|||
|
|
@ -84,10 +84,19 @@ VideoCapture_obsensor::VideoCapture_obsensor(int, const cv::VideoCaptureParamete
|
|||
});
|
||||
|
||||
auto param = pipe->getCameraParam();
|
||||
camParam.p1[0] = param.rgbIntrinsic.fx;
|
||||
camParam.p1[1] = param.rgbIntrinsic.fy;
|
||||
camParam.p1[2] = param.rgbIntrinsic.cx;
|
||||
camParam.p1[3] = param.rgbIntrinsic.cy;
|
||||
camParam.intrinsicColor[0] = param.rgbIntrinsic.fx;
|
||||
camParam.intrinsicColor[1] = param.rgbIntrinsic.fy;
|
||||
camParam.intrinsicColor[2] = param.rgbIntrinsic.cx;
|
||||
camParam.intrinsicColor[3] = param.rgbIntrinsic.cy;
|
||||
|
||||
camParam.distortionColor[0] = param.depthDistortion.k1;
|
||||
camParam.distortionColor[1] = param.depthDistortion.k2;
|
||||
camParam.distortionColor[2] = param.depthDistortion.k3;
|
||||
camParam.distortionColor[3] = param.depthDistortion.k4;
|
||||
camParam.distortionColor[4] = param.depthDistortion.k5;
|
||||
camParam.distortionColor[5] = param.depthDistortion.k6;
|
||||
camParam.distortionColor[6] = param.depthDistortion.p1;
|
||||
camParam.distortionColor[7] = param.depthDistortion.p2;
|
||||
}
|
||||
|
||||
VideoCapture_obsensor::~VideoCapture_obsensor(){
|
||||
|
|
@ -101,17 +110,42 @@ double VideoCapture_obsensor::getProperty(int propIdx) const
|
|||
switch (propIdx)
|
||||
{
|
||||
case CAP_PROP_OBSENSOR_INTRINSIC_FX:
|
||||
rst = camParam.p1[0];
|
||||
rst = camParam.intrinsicColor[0];
|
||||
break;
|
||||
case CAP_PROP_OBSENSOR_INTRINSIC_FY:
|
||||
rst = camParam.p1[1];
|
||||
rst = camParam.intrinsicColor[1];
|
||||
break;
|
||||
case CAP_PROP_OBSENSOR_INTRINSIC_CX:
|
||||
rst = camParam.p1[2];
|
||||
rst = camParam.intrinsicColor[2];
|
||||
break;
|
||||
case CAP_PROP_OBSENSOR_INTRINSIC_CY:
|
||||
rst = camParam.p1[3];
|
||||
rst = camParam.intrinsicColor[3];
|
||||
break;
|
||||
case CAP_PROP_OBSENSOR_COLOR_DISTORTION_K1:
|
||||
rst = camParam.distortionColor[0];
|
||||
break;
|
||||
case CAP_PROP_OBSENSOR_COLOR_DISTORTION_K2:
|
||||
rst = camParam.distortionColor[1];
|
||||
break;
|
||||
case CAP_PROP_OBSENSOR_COLOR_DISTORTION_K3:
|
||||
rst = camParam.distortionColor[2];
|
||||
break;
|
||||
case CAP_PROP_OBSENSOR_COLOR_DISTORTION_K4:
|
||||
rst = camParam.distortionColor[3];
|
||||
break;
|
||||
case CAP_PROP_OBSENSOR_COLOR_DISTORTION_K5:
|
||||
rst = camParam.distortionColor[4];
|
||||
break;
|
||||
case CAP_PROP_OBSENSOR_COLOR_DISTORTION_K6:
|
||||
rst = camParam.distortionColor[5];
|
||||
break;
|
||||
case CAP_PROP_OBSENSOR_COLOR_DISTORTION_P1:
|
||||
rst = camParam.distortionColor[6];
|
||||
break;
|
||||
case CAP_PROP_OBSENSOR_COLOR_DISTORTION_P2:
|
||||
rst = camParam.distortionColor[7];
|
||||
break;
|
||||
|
||||
case CAP_PROP_POS_MSEC:
|
||||
case CAP_PROP_OBSENSOR_RGB_POS_MSEC:
|
||||
if (grabbedColorFrame)
|
||||
|
|
|
|||
|
|
@ -33,14 +33,8 @@ namespace cv
|
|||
|
||||
struct CameraParam
|
||||
{
|
||||
float p0[4];
|
||||
float p1[4];
|
||||
float p2[9];
|
||||
float p3[3];
|
||||
float p4[5];
|
||||
float p5[5];
|
||||
uint32_t p6[2];
|
||||
uint32_t p7[2];
|
||||
float intrinsicColor[4];
|
||||
float distortionColor[8];
|
||||
};
|
||||
|
||||
class VideoCapture_obsensor : public IVideoCapture
|
||||
|
|
|
|||
|
|
@ -648,7 +648,7 @@ static bool runCalibration( Settings& s, Size& imageSize, Mat& cameraMatrix, Mat
|
|||
{
|
||||
objectPoints[0][s.boardSize.width - 2].x = objectPoints[0][0].x + grid_width;
|
||||
}
|
||||
else if (s.calibrationPattern != Settings::Pattern::CHESSBOARD)
|
||||
else if (s.calibrationPattern == Settings::Pattern::CHESSBOARD)
|
||||
{
|
||||
objectPoints[0][s.boardSize.width - 1].x = objectPoints[0][0].x + grid_width;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,7 +78,20 @@ int main(int argc, char** argv)
|
|||
double fy = obsensorCapture.get(CAP_PROP_OBSENSOR_INTRINSIC_FY);
|
||||
double cx = obsensorCapture.get(CAP_PROP_OBSENSOR_INTRINSIC_CX);
|
||||
double cy = obsensorCapture.get(CAP_PROP_OBSENSOR_INTRINSIC_CY);
|
||||
|
||||
double k1 = obsensorCapture.get(CAP_PROP_OBSENSOR_COLOR_DISTORTION_K1);
|
||||
double k2 = obsensorCapture.get(CAP_PROP_OBSENSOR_COLOR_DISTORTION_K2);
|
||||
double k3 = obsensorCapture.get(CAP_PROP_OBSENSOR_COLOR_DISTORTION_K3);
|
||||
double k4 = obsensorCapture.get(CAP_PROP_OBSENSOR_COLOR_DISTORTION_K4);
|
||||
double k5 = obsensorCapture.get(CAP_PROP_OBSENSOR_COLOR_DISTORTION_K5);
|
||||
double k6 = obsensorCapture.get(CAP_PROP_OBSENSOR_COLOR_DISTORTION_K6);
|
||||
double p1 = obsensorCapture.get(CAP_PROP_OBSENSOR_COLOR_DISTORTION_P1);
|
||||
double p2 = obsensorCapture.get(CAP_PROP_OBSENSOR_COLOR_DISTORTION_P1);
|
||||
|
||||
std::cout << "obsensor camera intrinsic params: fx=" << fx << ", fy=" << fy << ", cx=" << cx << ", cy=" << cy << std::endl;
|
||||
std::cout << "obsensor camera distortion params: k,p=" << k1 << ", " << k2 << ", " << k3 << ", "
|
||||
<< k4 << ", " << k5 << ", " << k6 << ", "
|
||||
<< p1 << ", " << p2 << std::endl;
|
||||
|
||||
Mat image;
|
||||
Mat depthMap;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user