1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-22 03:43:03 +04:00

Compare commits

..

3 Commits

Author SHA1 Message Date
Alexander Alekhin 4d34934d25 gapi(simd): initialize accumulator values
original commit: 99502e99cc
2020-03-30 19:36:30 +03:00
Alexander Alekhin 1b5c2bb363 OpenCV version '-openvino' 2020-03-24 16:17:01 +03:00
Alexander Alekhin 45263d7642 dnn: use OpenVINO 2020.2 defines 2020-03-24 16:17:01 +03:00
5026 changed files with 276181 additions and 894247 deletions
-3
View File
@@ -1,3 +0,0 @@
# These are supported funding model platforms
github: opencv
+9 -16
View File
@@ -1,10 +1,3 @@
<!--
If you have a question rather than reporting a bug please go to https://forum.opencv.org where you get much faster responses.
If you need further assistance please read [How To Contribute](https://github.com/opencv/opencv/wiki/How_to_contribute).
This is a template helping you to create an issue which can be processed as quickly as possible. This is the bug reporting section for the OpenCV library.
-->
##### System information (version)
<!-- Example
- OpenCV => 4.2
@@ -33,25 +26,25 @@ This is a template helping you to create an issue which can be processed as quic
- [ ] I report the issue, it's not a question
<!--
OpenCV team works with forum.opencv.org, Stack Overflow and other communities
to discuss problems. Tickets with questions without a real issue statement will be
OpenCV team works with answers.opencv.org, Stack Overflow and other communities
to discuss problems. Tickets with question without real issue statement will be
closed.
-->
- [ ] I checked the problem with documentation, FAQ, open issues,
forum.opencv.org, Stack Overflow, etc and have not found any solution
answers.opencv.org, Stack Overflow, etc and have not found solution
<!--
Places to check:
* OpenCV documentation: https://docs.opencv.org
* FAQ page: https://github.com/opencv/opencv/wiki/FAQ
* OpenCV forum: https://forum.opencv.org
* OpenCV forum: https://answers.opencv.org
* OpenCV issue tracker: https://github.com/opencv/opencv/issues?q=is%3Aissue
* Stack Overflow branch: https://stackoverflow.com/questions/tagged/opencv
-->
- [ ] I updated to the latest OpenCV version and the issue is still there
- [ ] I updated to latest OpenCV version and the issue is still there
<!--
master branch for OpenCV 4.x and 3.4 branch for OpenCV 3.x releases.
OpenCV team supports only the latest release for each branch.
The ticket is closed if the problem is not reproduced with the modern version.
OpenCV team supports only latest release for each branch.
The ticket is closed, if the problem is not reproduced with modern version.
-->
- [ ] There is reproducer code and related data files: videos, images, onnx, etc
<!--
@@ -61,9 +54,9 @@ This is a template helping you to create an issue which can be processed as quic
to reduce attachment size
* Use PNG for images, if you report some CV related bug, but not image reader
issue
* Attach the image as an archive to the ticket, if you report some reader issue.
* Attach the image as archite to the ticket, if you report some reader issue.
Image hosting services compress images and it breaks the repro code.
* Provide ONNX file for some public model or ONNX file with random weights,
* Provide ONNX file for some public model or ONNX file with with random weights,
if you report ONNX parsing or handling issue. Architecture details diagram
from netron tool can be very useful too. See https://lutzroeder.github.io/netron/
-->
-64
View File
@@ -1,64 +0,0 @@
name: Bug Report
description: Create a report to help us reproduce and fix the bug
labels: ["bug"]
body:
- type: markdown
attributes:
value: >
#### Thank you for contributing! Before reporting a bug, please have a look at the [FAQ](https://github.com/opencv/opencv/wiki/FAQ), make sure the issue has no duplicate and hasn't been already addressed by searching through [the existing and past issues](https://github.com/opencv/opencv/issues?page=1&q=is%3Aissue+sort%3Acreated-desc).
- type: textarea
attributes:
label: System Information
description: |
Please provide the following system information to help us diagnose the bug. For example:
// example for c++ user
OpenCV version: 4.8.0
Operating System / Platform: Ubuntu 20.04
Compiler & compiler version: GCC 9.3.0
// example for python user
OpenCV python version: 4.8.0.74
Operating System / Platform: Ubuntu 20.04
Python version: 3.9.6
validations:
required: true
- type: textarea
attributes:
label: Detailed description
description: |
Please provide a clear and concise description of what the bug is and paste the error log below. It helps improving readability if the error log is wrapped in ```` ```triple quotes blocks``` ````.
placeholder: |
A clear and concise description of what the bug is.
```
# error log
```
validations:
required: true
- type: textarea
attributes:
label: Steps to reproduce
description: |
Please provide a minimal example to help us reproduce the bug. Code should be wrapped with ```` ```triple quotes blocks``` ```` to improve readability. If the code is too long, please attach as a file or create and link a public gist: https://gist.github.com.
Related data files (images, onnx, etc) should be attached below as well. If the data files are too big, feel free to upload them to a online drive, share them and put the link below.
placeholder: |
```cpp (replace cpp with python if python code)
# sample code to reproduce the bug
```
Test data: [image](https://link/to/the/image), [model.onnx](htts://link/to/the/onnx/model)
validations:
required: true
- type: checkboxes
attributes:
label: Issue submission checklist
options:
- label: I report the issue, it's not a question
required: true
- label: I checked the problem with documentation, FAQ, open issues, forum.opencv.org, Stack Overflow, etc and have not found any solution
- label: I updated to the latest OpenCV version and the issue is still there
- label: There is reproducer code and related data files (videos, images, onnx, etc)
-5
View File
@@ -1,5 +0,0 @@
blank_issues_enabled: true
contact_links:
- name: Questions
url: https://forum.opencv.org/
about: Ask questions and discuss with OpenCV community members
-26
View File
@@ -1,26 +0,0 @@
name: Documentation
description: Report an issue related to https://docs.opencv.org/
labels: ["category: documentation"]
body:
- type: markdown
attributes:
value: >
#### Thank you for contributing! Before submitting a doc issue, please make sure it has no duplicate by searching through [the existing and past issues](https://github.com/opencv/opencv/issues?page=1&q=is%3Aissue+sort%3Acreated-desc)
- type: textarea
attributes:
label: Describe the doc issue
description: >
Please provide a clear and concise description of what content in https://docs.opencv.org/ is an issue. Note that there are multiple active branches, such as 4.x and 5.x, so please specify the branch with the problem.
placeholder: |
A clear and concise description of what content in https://docs.opencv.org/ is an issue.
Link to the doc: https://docs.opencv.org/4.x/d3/d63/classcv_1_1Mat.html
validations:
required: true
- type: textarea
attributes:
label: Fix suggestion
description: >
Tell us how we could improve the documentation in this regard.
@@ -1,22 +0,0 @@
name: Feature request
description: Submit a request for a new OpenCV feature
labels: ["feature"]
body:
- type: markdown
attributes:
value: >
#### Thank you for contributing! Before submitting a feature request, please make sure the request has no duplicate by searching through [the existing and past issues](https://github.com/opencv/opencv/issues?page=1&q=is%3Aissue+sort%3Acreated-desc)
- type: textarea
attributes:
label: Describe the feature and motivation
description: |
Please provide a clear and concise proposal of the feature and outline the motivation.
validations:
required: true
- type: textarea
attributes:
label: Additional context
description: |
Add any other context, such as pseudo code, links, diagram, screenshots, to help the community better understand the feature request.
+4 -4
View File
@@ -2,10 +2,10 @@
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [ ] I agree to contribute to the project under Apache 2 License.
- [ ] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [ ] The PR is proposed to the proper branch
- [ ] There is a reference to the original bug report and related work
- [ ] I agree to contribute to the project under OpenCV (BSD) License.
- [ ] To the best of my knowledge, the proposed patch is not based on a code under GPL or other license that is incompatible with OpenCV
- [ ] The PR is proposed to proper branch
- [ ] There is reference to original bug report and related work
- [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake
-65
View File
@@ -1,65 +0,0 @@
name: PR:4.x
on:
pull_request:
branches:
- 4.x
jobs:
Ubuntu2004-ARM64:
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-ARM64.yaml@main
Ubuntu2004-ARM64-Debug:
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-ARM64-Debug.yaml@main
Ubuntu2004-x64:
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-U20.yaml@main
Ubuntu2004-x64-OpenVINO:
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-U20-OpenVINO.yaml@main
Ubuntu2204-x64:
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-U22.yaml@main
Ubuntu2404-x64:
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-U24.yaml@main
Ubuntu2004-x64-CUDA:
if: "${{ contains(github.event.pull_request.labels.*.name, 'category: dnn') }} || ${{ contains(github.event.pull_request.labels.*.name, 'category: dnn (onnx)') }}"
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-U20-Cuda.yaml@main
Windows10-x64:
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-W10.yaml@main
Windows10-ARM64:
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-W10-ARM64.yaml@main
Windows10-x64-Vulkan:
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-W10-Vulkan.yaml@main
macOS-ARM64:
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-macOS-ARM64.yaml@main
macOS-x64:
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-macOS-x86_64.yaml@main
macOS-ARM64-Vulkan:
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-macOS-ARM64-Vulkan.yaml@main
iOS:
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-iOS.yaml@main
Android-SDK:
uses: opencv/ci-gha-workflow/.github/workflows/OCV-4.x-Android-SDK.yaml@main
Android-Test:
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-Android-Test.yaml@main
TIM-VX:
uses: opencv/ci-gha-workflow/.github/workflows/OCV-timvx-backend-tests-4.x.yml@main
docs:
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-docs.yaml@main
Linux-RISC-V-Clang:
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-RISCV.yaml@main
-50
View File
@@ -1,50 +0,0 @@
name: arm64 build checks
on: workflow_dispatch
permissions:
contents: read # to fetch code (actions/checkout)
jobs:
build:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Install dependency packages
run: |
sudo sed -i -E 's|^deb ([^ ]+) (.*)$|deb [arch=amd64] \1 \2\ndeb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ \2|' /etc/apt/sources.list
sudo dpkg --add-architecture arm64
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
crossbuild-essential-arm64 \
git \
cmake \
libpython-dev:arm64 \
libpython3-dev:arm64 \
python-numpy \
python3-numpy
- name: Fetch opencv_contrib
run: |
git clone --depth 1 https://github.com/opencv/opencv_contrib.git ../opencv_contrib
- name: Configure
run: |
mkdir build
cd build
cmake -DPYTHON2_INCLUDE_PATH=/usr/include/python2.7/ \
-DPYTHON2_LIBRARIES=/usr/lib/aarch64-linux-gnu/libpython2.7.so \
-DPYTHON2_NUMPY_INCLUDE_DIRS=/usr/lib/python2.7/dist-packages/numpy/core/include \
-DPYTHON3_INCLUDE_PATH=/usr/include/python3.6m/ \
-DPYTHON3_LIBRARIES=/usr/lib/aarch64-linux-gnu/libpython3.6m.so \
-DPYTHON3_NUMPY_INCLUDE_DIRS=/usr/lib/python3/dist-packages/numpy/core/include \
-DCMAKE_TOOLCHAIN_FILE=../platforms/linux/aarch64-gnu.toolchain.cmake \
-DOPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules \
../
- name: Build
run: |
cd build
make -j$(nproc --all)
-27
View File
@@ -1,27 +0,0 @@
name: lint_python
on: workflow_dispatch
permissions:
contents: read # to fetch code (actions/checkout)
jobs:
lint_python:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- run: pip install --upgrade pip wheel
- run: pip install bandit black codespell flake8 flake8-2020 flake8-bugbear
flake8-comprehensions isort mypy pytest pyupgrade safety
- run: bandit --recursive --skip B101 . || true # B101 is assert statements
- run: black --check . || true
- run: codespell || true # --ignore-words-list="" --skip="*.css,*.js,*.lock"
- run: flake8 . --count --select=E9,F63,F7 --show-source --statistics
- run: flake8 . --count --exit-zero --max-complexity=10 --max-line-length=88
--show-source --statistics
- run: isort --check-only --profile black . || true
- run: pip install -r requirements.txt || pip install --editable . || true
- run: mkdir --parents --verbose .mypy_cache
- run: mypy --ignore-missing-imports --install-types --non-interactive . || true
- run: pytest . || true
- run: pytest --doctest-modules . || true
- run: shopt -s globstar && pyupgrade --py36-plus **/*.py || true
- run: safety check
-1
View File
@@ -24,4 +24,3 @@ bin/
build
node_modules
CMakeSettings.json
xcuserdata/
+3 -16
View File
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION ${MIN_VER_CMAKE} FATAL_ERROR)
cmake_minimum_required(VERSION 2.8.11 FATAL_ERROR)
project(Carotene)
@@ -27,11 +27,7 @@ if(CMAKE_COMPILER_IS_GNUCC)
endif()
endif()
if(APPLE AND CV_CLANG AND WITH_NEON)
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wno-unused-function)
endif()
add_library(carotene_objs OBJECT EXCLUDE_FROM_ALL
add_library(carotene_objs OBJECT
${carotene_headers}
${carotene_sources}
)
@@ -42,15 +38,6 @@ endif()
if(WITH_NEON)
target_compile_definitions(carotene_objs PRIVATE "-DWITH_NEON")
if(NOT DEFINED CAROTENE_NEON_ARCH )
elseif(CAROTENE_NEON_ARCH EQUAL 8)
target_compile_definitions(carotene_objs PRIVATE "-DCAROTENE_NEON_ARCH=8")
elseif(CAROTENE_NEON_ARCH EQUAL 7)
target_compile_definitions(carotene_objs PRIVATE "-DCAROTENE_NEON_ARCH=7")
else()
target_compile_definitions(carotene_objs PRIVATE "-DCAROTENE_NEON_ARCH=0")
endif()
endif()
# we add dummy file to fix XCode build
add_library(carotene STATIC ${OPENCV_3RDPARTY_EXCLUDE_FROM_ALL} "$<TARGET_OBJECTS:carotene_objs>" "${CAROTENE_SOURCE_DIR}/dummy.cpp")
add_library(carotene STATIC EXCLUDE_FROM_ALL "$<TARGET_OBJECTS:carotene_objs>")
+2 -3
View File
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION ${MIN_VER_CMAKE} FATAL_ERROR)
cmake_minimum_required(VERSION 2.8.8 FATAL_ERROR)
include(CheckCCompilerFlag)
include(CheckCXXCompilerFlag)
@@ -82,8 +82,7 @@ set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS ${carotene_defs})
# set_source_files_properties(impl.cpp $<TARGET_OBJECTS:carotene_objs> COMPILE_FLAGS "--param ipcp-unit-growth=100000 --param inline-unit-growth=100000 --param large-stack-frame-growth=5000")
endif()
# we add dummy file to fix XCode build
add_library(tegra_hal STATIC $<TARGET_OBJECTS:carotene_objs> "dummy.cpp")
add_library(tegra_hal STATIC $<TARGET_OBJECTS:carotene_objs>)
set_target_properties(tegra_hal PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH})
set(OPENCV_SRC_DIR "${CMAKE_SOURCE_DIR}")
if(NOT BUILD_SHARED_LIBS)
-2
View File
@@ -1,2 +0,0 @@
// This file is needed for compilation on some platforms e.g. with XCode generator
// Related issue: https://gitlab.kitware.com/cmake/cmake/-/issues/17457
+19 -28
View File
@@ -1296,13 +1296,13 @@ struct MorphCtx
CAROTENE_NS::BORDER_MODE border;
uchar borderValues[4];
};
inline int TEGRA_MORPHINIT(cvhalFilter2D **context, int operation, int src_type, int dst_type, int width, int height,
inline int TEGRA_MORPHINIT(cvhalFilter2D **context, int operation, int src_type, int dst_type, int, int,
int kernel_type, uchar *kernel_data, size_t kernel_step, int kernel_width, int kernel_height, int anchor_x, int anchor_y,
int borderType, const double borderValue[4], int iterations, bool allowSubmatrix, bool allowInplace)
{
if(!context || !kernel_data || src_type != dst_type ||
CV_MAT_DEPTH(src_type) != CV_8U || src_type < 0 || (src_type >> CV_CN_SHIFT) > 3 ||
width < kernel_width || height < kernel_height ||
allowSubmatrix || allowInplace || iterations != 1 ||
!CAROTENE_NS::isSupportedConfiguration())
return CV_HAL_ERROR_NOT_IMPLEMENTED;
@@ -1778,30 +1778,30 @@ TegraCvtColor_Invoker(bgrx2hsvf, bgrx2hsv, src_data + static_cast<size_t>(range.
: CV_HAL_ERROR_NOT_IMPLEMENTED \
)
#define TEGRA_CVT2PYUVTOBGR_EX(y_data, y_step, uv_data, uv_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx) \
#define TEGRA_CVT2PYUVTOBGR(src_data, src_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx) \
( \
CAROTENE_NS::isSupportedConfiguration() ? \
dcn == 3 ? \
uIdx == 0 ? \
(swapBlue ? \
CAROTENE_NS::yuv420i2rgb(CAROTENE_NS::Size2D(dst_width, dst_height), \
y_data, y_step, \
uv_data, uv_step, \
src_data, src_step, \
src_data + src_step * dst_height, src_step, \
dst_data, dst_step) : \
CAROTENE_NS::yuv420i2bgr(CAROTENE_NS::Size2D(dst_width, dst_height), \
y_data, y_step, \
uv_data, uv_step, \
src_data, src_step, \
src_data + src_step * dst_height, src_step, \
dst_data, dst_step)), \
CV_HAL_ERROR_OK : \
uIdx == 1 ? \
(swapBlue ? \
CAROTENE_NS::yuv420sp2rgb(CAROTENE_NS::Size2D(dst_width, dst_height), \
y_data, y_step, \
uv_data, uv_step, \
src_data, src_step, \
src_data + src_step * dst_height, src_step, \
dst_data, dst_step) : \
CAROTENE_NS::yuv420sp2bgr(CAROTENE_NS::Size2D(dst_width, dst_height), \
y_data, y_step, \
uv_data, uv_step, \
src_data, src_step, \
src_data + src_step * dst_height, src_step, \
dst_data, dst_step)), \
CV_HAL_ERROR_OK : \
CV_HAL_ERROR_NOT_IMPLEMENTED : \
@@ -1809,32 +1809,29 @@ TegraCvtColor_Invoker(bgrx2hsvf, bgrx2hsv, src_data + static_cast<size_t>(range.
uIdx == 0 ? \
(swapBlue ? \
CAROTENE_NS::yuv420i2rgbx(CAROTENE_NS::Size2D(dst_width, dst_height), \
y_data, y_step, \
uv_data, uv_step, \
src_data, src_step, \
src_data + src_step * dst_height, src_step, \
dst_data, dst_step) : \
CAROTENE_NS::yuv420i2bgrx(CAROTENE_NS::Size2D(dst_width, dst_height), \
y_data, y_step, \
uv_data, uv_step, \
src_data, src_step, \
src_data + src_step * dst_height, src_step, \
dst_data, dst_step)), \
CV_HAL_ERROR_OK : \
uIdx == 1 ? \
(swapBlue ? \
CAROTENE_NS::yuv420sp2rgbx(CAROTENE_NS::Size2D(dst_width, dst_height), \
y_data, y_step, \
uv_data, uv_step, \
src_data, src_step, \
src_data + src_step * dst_height, src_step, \
dst_data, dst_step) : \
CAROTENE_NS::yuv420sp2bgrx(CAROTENE_NS::Size2D(dst_width, dst_height), \
y_data, y_step, \
uv_data, uv_step, \
src_data, src_step, \
src_data + src_step * dst_height, src_step, \
dst_data, dst_step)), \
CV_HAL_ERROR_OK : \
CV_HAL_ERROR_NOT_IMPLEMENTED : \
CV_HAL_ERROR_NOT_IMPLEMENTED \
: CV_HAL_ERROR_NOT_IMPLEMENTED \
)
#define TEGRA_CVT2PYUVTOBGR(src_data, src_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx) \
TEGRA_CVT2PYUVTOBGR_EX(src_data, src_step, src_data + src_step * dst_height, src_step, dst_data, dst_step, \
dst_width, dst_height, dcn, swapBlue, uIdx);
#undef cv_hal_cvtBGRtoBGR
#define cv_hal_cvtBGRtoBGR TEGRA_CVTBGRTOBGR
@@ -1844,18 +1841,12 @@ TegraCvtColor_Invoker(bgrx2hsvf, bgrx2hsv, src_data + static_cast<size_t>(range.
#define cv_hal_cvtBGRtoGray TEGRA_CVTBGRTOGRAY
#undef cv_hal_cvtGraytoBGR
#define cv_hal_cvtGraytoBGR TEGRA_CVTGRAYTOBGR
#if 0 // bit-exact tests are failed
#undef cv_hal_cvtBGRtoYUV
#define cv_hal_cvtBGRtoYUV TEGRA_CVTBGRTOYUV
#endif
#undef cv_hal_cvtBGRtoHSV
#define cv_hal_cvtBGRtoHSV TEGRA_CVTBGRTOHSV
#if 0 // bit-exact tests are failed
#undef cv_hal_cvtTwoPlaneYUVtoBGR
#define cv_hal_cvtTwoPlaneYUVtoBGR TEGRA_CVT2PYUVTOBGR
#undef cv_hal_cvtTwoPlaneYUVtoBGREx
#define cv_hal_cvtTwoPlaneYUVtoBGREx TEGRA_CVT2PYUVTOBGR_EX
#endif
#endif // OPENCV_IMGPROC_HAL_INTERFACE_H
+24 -25
View File
@@ -39,7 +39,6 @@
#include "common.hpp"
#include "vtransform.hpp"
#include "vround_helper.hpp"
namespace CAROTENE_NS {
@@ -107,31 +106,31 @@ template <> struct wAdd<s32>
{
valpha = vdupq_n_f32(_alpha);
vbeta = vdupq_n_f32(_beta);
vgamma = vdupq_n_f32(_gamma);
vgamma = vdupq_n_f32(_gamma + 0.5);
}
void operator() (const VecTraits<s32>::vec128 & v_src0,
const VecTraits<s32>::vec128 & v_src1,
VecTraits<s32>::vec128 & v_dst) const
void operator() (const typename VecTraits<s32>::vec128 & v_src0,
const typename VecTraits<s32>::vec128 & v_src1,
typename VecTraits<s32>::vec128 & v_dst) const
{
float32x4_t vs1 = vcvtq_f32_s32(v_src0);
float32x4_t vs2 = vcvtq_f32_s32(v_src1);
vs1 = vmlaq_f32(vgamma, vs1, valpha);
vs1 = vmlaq_f32(vs1, vs2, vbeta);
v_dst = vroundq_s32_f32(vs1);
v_dst = vcvtq_s32_f32(vs1);
}
void operator() (const VecTraits<s32>::vec64 & v_src0,
const VecTraits<s32>::vec64 & v_src1,
VecTraits<s32>::vec64 & v_dst) const
void operator() (const typename VecTraits<s32>::vec64 & v_src0,
const typename VecTraits<s32>::vec64 & v_src1,
typename VecTraits<s32>::vec64 & v_dst) const
{
float32x2_t vs1 = vcvt_f32_s32(v_src0);
float32x2_t vs2 = vcvt_f32_s32(v_src1);
vs1 = vmla_f32(vget_low(vgamma), vs1, vget_low(valpha));
vs1 = vmla_f32(vs1, vs2, vget_low(vbeta));
v_dst = vround_s32_f32(vs1);
v_dst = vcvt_s32_f32(vs1);
}
void operator() (const s32 * src0, const s32 * src1, s32 * dst) const
@@ -151,31 +150,31 @@ template <> struct wAdd<u32>
{
valpha = vdupq_n_f32(_alpha);
vbeta = vdupq_n_f32(_beta);
vgamma = vdupq_n_f32(_gamma);
vgamma = vdupq_n_f32(_gamma + 0.5);
}
void operator() (const VecTraits<u32>::vec128 & v_src0,
const VecTraits<u32>::vec128 & v_src1,
VecTraits<u32>::vec128 & v_dst) const
void operator() (const typename VecTraits<u32>::vec128 & v_src0,
const typename VecTraits<u32>::vec128 & v_src1,
typename VecTraits<u32>::vec128 & v_dst) const
{
float32x4_t vs1 = vcvtq_f32_u32(v_src0);
float32x4_t vs2 = vcvtq_f32_u32(v_src1);
vs1 = vmlaq_f32(vgamma, vs1, valpha);
vs1 = vmlaq_f32(vs1, vs2, vbeta);
v_dst = vroundq_u32_f32(vs1);
v_dst = vcvtq_u32_f32(vs1);
}
void operator() (const VecTraits<u32>::vec64 & v_src0,
const VecTraits<u32>::vec64 & v_src1,
VecTraits<u32>::vec64 & v_dst) const
void operator() (const typename VecTraits<u32>::vec64 & v_src0,
const typename VecTraits<u32>::vec64 & v_src1,
typename VecTraits<u32>::vec64 & v_dst) const
{
float32x2_t vs1 = vcvt_f32_u32(v_src0);
float32x2_t vs2 = vcvt_f32_u32(v_src1);
vs1 = vmla_f32(vget_low(vgamma), vs1, vget_low(valpha));
vs1 = vmla_f32(vs1, vs2, vget_low(vbeta));
v_dst = vround_u32_f32(vs1);
v_dst = vcvt_u32_f32(vs1);
}
void operator() (const u32 * src0, const u32 * src1, u32 * dst) const
@@ -198,17 +197,17 @@ template <> struct wAdd<f32>
vgamma = vdupq_n_f32(_gamma + 0.5);
}
void operator() (const VecTraits<f32>::vec128 & v_src0,
const VecTraits<f32>::vec128 & v_src1,
VecTraits<f32>::vec128 & v_dst) const
void operator() (const typename VecTraits<f32>::vec128 & v_src0,
const typename VecTraits<f32>::vec128 & v_src1,
typename VecTraits<f32>::vec128 & v_dst) const
{
float32x4_t vs1 = vmlaq_f32(vgamma, v_src0, valpha);
v_dst = vmlaq_f32(vs1, v_src1, vbeta);
}
void operator() (const VecTraits<f32>::vec64 & v_src0,
const VecTraits<f32>::vec64 & v_src1,
VecTraits<f32>::vec64 & v_dst) const
void operator() (const typename VecTraits<f32>::vec64 & v_src0,
const typename VecTraits<f32>::vec64 & v_src1,
typename VecTraits<f32>::vec64 & v_dst) const
{
float32x2_t vs1 = vmla_f32(vget_low(vgamma), v_src0, vget_low(valpha));
v_dst = vmla_f32(vs1, v_src1, vget_low(vbeta));
+9 -8
View File
@@ -41,7 +41,6 @@
#include "common.hpp"
#include "saturate_cast.hpp"
#include "vround_helper.hpp"
namespace CAROTENE_NS {
@@ -199,6 +198,7 @@ void blur3x3(const Size2D &size, s32 cn,
//#define FLOAT_VARIANT_1_9
#ifdef FLOAT_VARIANT_1_9
float32x4_t v1_9 = vdupq_n_f32 (1.0/9.0);
float32x4_t v0_5 = vdupq_n_f32 (.5);
#else
const int16x8_t vScale = vmovq_n_s16(3640);
#endif
@@ -283,8 +283,8 @@ void blur3x3(const Size2D &size, s32 cn,
uint32x4_t tres2 = vmovl_u16(vget_high_u16(t0));
float32x4_t vf1 = vmulq_f32(v1_9, vcvtq_f32_u32(tres1));
float32x4_t vf2 = vmulq_f32(v1_9, vcvtq_f32_u32(tres2));
tres1 = internal::vroundq_u32_f32(vf1);
tres2 = internal::vroundq_u32_f32(vf2);
tres1 = vcvtq_u32_f32(vaddq_f32(vf1, v0_5));
tres2 = vcvtq_u32_f32(vaddq_f32(vf2, v0_5));
t0 = vcombine_u16(vmovn_u32(tres1),vmovn_u32(tres2));
vst1_u8(drow + x - 8, vmovn_u16(t0));
#else
@@ -391,9 +391,9 @@ void blur3x3(const Size2D &size, s32 cn,
}
else if (borderType == BORDER_MODE_REFLECT101)
{
tcurr = vsetq_lane_u16(vgetq_lane_u16(tcurr, 3),tcurr, 5);
tcurr = vsetq_lane_u16(vgetq_lane_u16(tcurr, 4),tcurr, 6);
tcurr = vsetq_lane_u16(vgetq_lane_u16(tcurr, 5),tcurr, 7);
tcurr = vsetq_lane_u16(vgetq_lane_u16(tcurr, 3),tcurr, 5);
}
else
{
@@ -445,8 +445,8 @@ void blur3x3(const Size2D &size, s32 cn,
uint32x4_t tres2 = vmovl_u16(vget_high_u16(t0));
float32x4_t vf1 = vmulq_f32(v1_9, vcvtq_f32_u32(tres1));
float32x4_t vf2 = vmulq_f32(v1_9, vcvtq_f32_u32(tres2));
tres1 = internal::vroundq_u32_f32(vf1);
tres2 = internal::vroundq_u32_f32(vf2);
tres1 = vcvtq_u32_f32(vaddq_f32(vf1, v0_5));
tres2 = vcvtq_u32_f32(vaddq_f32(vf2, v0_5));
t0 = vcombine_u16(vmovn_u32(tres1),vmovn_u32(tres2));
vst1_u8(drow + x - 8, vmovn_u16(t0));
#else
@@ -508,6 +508,7 @@ void blur5x5(const Size2D &size, s32 cn,
#define FLOAT_VARIANT_1_25
#ifdef FLOAT_VARIANT_1_25
float32x4_t v1_25 = vdupq_n_f32 (1.0f/25.0f);
float32x4_t v0_5 = vdupq_n_f32 (.5f);
#else
const int16x8_t vScale = vmovq_n_s16(1310);
#endif
@@ -751,8 +752,8 @@ void blur5x5(const Size2D &size, s32 cn,
uint32x4_t tres2 = vmovl_u16(vget_high_u16(t0));
float32x4_t vf1 = vmulq_f32(v1_25, vcvtq_f32_u32(tres1));
float32x4_t vf2 = vmulq_f32(v1_25, vcvtq_f32_u32(tres2));
tres1 = internal::vroundq_u32_f32(vf1);
tres2 = internal::vroundq_u32_f32(vf2);
tres1 = vcvtq_u32_f32(vaddq_f32(vf1, v0_5));
tres2 = vcvtq_u32_f32(vaddq_f32(vf2, v0_5));
t0 = vcombine_u16(vmovn_u32(tres1),vmovn_u32(tres2));
vst1_u8(drow + x - 8, vmovn_u16(t0));
#else
+11 -5
View File
@@ -40,7 +40,6 @@
#include "common.hpp"
#include "saturate_cast.hpp"
#include "vround_helper.hpp"
namespace CAROTENE_NS {
@@ -1167,10 +1166,17 @@ inline uint8x8x3_t convertToHSV(const uint8x8_t vR, const uint8x8_t vG, const ui
vSt3 = vmulq_f32(vHF1, vDivTab);
vSt4 = vmulq_f32(vHF2, vDivTab);
uint32x4_t vRes1 = internal::vroundq_u32_f32(vSt1);
uint32x4_t vRes2 = internal::vroundq_u32_f32(vSt2);
uint32x4_t vRes3 = internal::vroundq_u32_f32(vSt3);
uint32x4_t vRes4 = internal::vroundq_u32_f32(vSt4);
float32x4_t bias = vdupq_n_f32(0.5f);
vSt1 = vaddq_f32(vSt1, bias);
vSt2 = vaddq_f32(vSt2, bias);
vSt3 = vaddq_f32(vSt3, bias);
vSt4 = vaddq_f32(vSt4, bias);
uint32x4_t vRes1 = vcvtq_u32_f32(vSt1);
uint32x4_t vRes2 = vcvtq_u32_f32(vSt2);
uint32x4_t vRes3 = vcvtq_u32_f32(vSt3);
uint32x4_t vRes4 = vcvtq_u32_f32(vSt4);
int32x4_t vH_L = vmovl_s16(vget_low_s16(vDiff4));
int32x4_t vH_H = vmovl_s16(vget_high_s16(vDiff4));
-11
View File
@@ -58,17 +58,6 @@
namespace CAROTENE_NS { namespace internal {
#ifndef CAROTENE_NEON_ARCH
# if defined(__aarch64__) || defined(__aarch32__)
# define CAROTENE_NEON_ARCH 8
# else
# define CAROTENE_NEON_ARCH 7
# endif
#endif
#if ( !defined(__aarch64__) && !defined(__aarch32__) ) && (CAROTENE_NEON_ARCH == 8 )
# error("ARMv7 doen't support A32/A64 Neon instructions")
#endif
inline void prefetch(const void *ptr, size_t offset = 32*10)
{
#if defined __GNUC__
+107 -108
View File
@@ -38,7 +38,6 @@
*/
#include "common.hpp"
#include "vround_helper.hpp"
namespace CAROTENE_NS {
@@ -186,7 +185,7 @@ CVTS_FUNC1(u8, 16,
#else
CVTS_FUNC1(u8, 16,
float32x4_t vscale = vdupq_n_f32((f32)alpha);
float32x4_t vshift = vdupq_n_f32((f32)beta);,
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
{
for (size_t i = 0; i < w; i += 16)
{
@@ -210,10 +209,10 @@ CVTS_FUNC1(u8, 16,
vline2_f32 = vaddq_f32(vline2_f32, vshift);
vline3_f32 = vaddq_f32(vline3_f32, vshift);
vline4_f32 = vaddq_f32(vline4_f32, vshift);
int32x4_t vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
int32x4_t vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
int32x4_t vline3_s32 = internal::vroundq_s32_f32(vline3_f32);
int32x4_t vline4_s32 = internal::vroundq_s32_f32(vline4_f32);
int32x4_t vline1_s32 = vcvtq_s32_f32(vline1_f32);
int32x4_t vline2_s32 = vcvtq_s32_f32(vline2_f32);
int32x4_t vline3_s32 = vcvtq_s32_f32(vline3_f32);
int32x4_t vline4_s32 = vcvtq_s32_f32(vline4_f32);
uint16x8_t vRes1_u16 = vcombine_u16(vqmovun_s32(vline1_s32), vqmovun_s32(vline2_s32));
uint16x8_t vRes2_u16 = vcombine_u16(vqmovun_s32(vline3_s32), vqmovun_s32(vline4_s32));
vst1q_u8(_dst + i, vcombine_u8(vqmovn_u16(vRes1_u16), vqmovn_u16(vRes2_u16)));
@@ -271,7 +270,7 @@ CVTS_FUNC(u8, s8, 16,
#else
CVTS_FUNC(u8, s8, 16,
float32x4_t vscale = vdupq_n_f32((f32)alpha);
float32x4_t vshift = vdupq_n_f32((f32)beta);,
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
{
for (size_t i = 0; i < w; i += 16)
{
@@ -295,10 +294,10 @@ CVTS_FUNC(u8, s8, 16,
vline2_f32 = vaddq_f32(vline2_f32, vshift);
vline3_f32 = vaddq_f32(vline3_f32, vshift);
vline4_f32 = vaddq_f32(vline4_f32, vshift);
int32x4_t vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
int32x4_t vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
int32x4_t vline3_s32 = internal::vroundq_s32_f32(vline3_f32);
int32x4_t vline4_s32 = internal::vroundq_s32_f32(vline4_f32);
int32x4_t vline1_s32 = vcvtq_s32_f32(vline1_f32);
int32x4_t vline2_s32 = vcvtq_s32_f32(vline2_f32);
int32x4_t vline3_s32 = vcvtq_s32_f32(vline3_f32);
int32x4_t vline4_s32 = vcvtq_s32_f32(vline4_f32);
int16x8_t vRes1_u16 = vcombine_s16(vqmovn_s32(vline1_s32), vqmovn_s32(vline2_s32));
int16x8_t vRes2_u16 = vcombine_s16(vqmovn_s32(vline3_s32), vqmovn_s32(vline4_s32));
vst1q_s8(_dst + i, vcombine_s8(vqmovn_s16(vRes1_u16), vqmovn_s16(vRes2_u16)));
@@ -356,7 +355,7 @@ CVTS_FUNC(u8, u16, 16,
#else
CVTS_FUNC(u8, u16, 16,
float32x4_t vscale = vdupq_n_f32((f32)alpha);
float32x4_t vshift = vdupq_n_f32((f32)beta);,
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
{
for (size_t i = 0; i < w; i += 16)
{
@@ -380,10 +379,10 @@ CVTS_FUNC(u8, u16, 16,
vline2_f32 = vaddq_f32(vline2_f32, vshift);
vline3_f32 = vaddq_f32(vline3_f32, vshift);
vline4_f32 = vaddq_f32(vline4_f32, vshift);
int32x4_t vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
int32x4_t vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
int32x4_t vline3_s32 = internal::vroundq_s32_f32(vline3_f32);
int32x4_t vline4_s32 = internal::vroundq_s32_f32(vline4_f32);
int32x4_t vline1_s32 = vcvtq_s32_f32(vline1_f32);
int32x4_t vline2_s32 = vcvtq_s32_f32(vline2_f32);
int32x4_t vline3_s32 = vcvtq_s32_f32(vline3_f32);
int32x4_t vline4_s32 = vcvtq_s32_f32(vline4_f32);
vst1q_u16(_dst + i + 0, vcombine_u16(vqmovun_s32(vline1_s32), vqmovun_s32(vline2_s32)));
vst1q_u16(_dst + i + 8, vcombine_u16(vqmovun_s32(vline3_s32), vqmovun_s32(vline4_s32)));
}
@@ -440,7 +439,7 @@ CVTS_FUNC(u8, s16, 16,
#else
CVTS_FUNC(u8, s16, 16,
float32x4_t vscale = vdupq_n_f32((f32)alpha);
float32x4_t vshift = vdupq_n_f32((f32)beta);,
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
{
for (size_t i = 0; i < w; i += 16)
{
@@ -464,10 +463,10 @@ CVTS_FUNC(u8, s16, 16,
vline2_f32 = vaddq_f32(vline2_f32, vshift);
vline3_f32 = vaddq_f32(vline3_f32, vshift);
vline4_f32 = vaddq_f32(vline4_f32, vshift);
int32x4_t vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
int32x4_t vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
int32x4_t vline3_s32 = internal::vroundq_s32_f32(vline3_f32);
int32x4_t vline4_s32 = internal::vroundq_s32_f32(vline4_f32);
int32x4_t vline1_s32 = vcvtq_s32_f32(vline1_f32);
int32x4_t vline2_s32 = vcvtq_s32_f32(vline2_f32);
int32x4_t vline3_s32 = vcvtq_s32_f32(vline3_f32);
int32x4_t vline4_s32 = vcvtq_s32_f32(vline4_f32);
vst1q_s16(_dst + i + 0, vcombine_s16(vqmovn_s32(vline1_s32), vqmovn_s32(vline2_s32)));
vst1q_s16(_dst + i + 8, vcombine_s16(vqmovn_s32(vline3_s32), vqmovn_s32(vline4_s32)));
}
@@ -527,7 +526,7 @@ CVTS_FUNC(u8, s32, 16,
#else
CVTS_FUNC(u8, s32, 16,
float32x4_t vscale = vdupq_n_f32((f32)alpha);
float32x4_t vshift = vdupq_n_f32((f32)beta);,
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
{
for (size_t i = 0; i < w; i += 16)
{
@@ -551,10 +550,10 @@ CVTS_FUNC(u8, s32, 16,
vline2_f32 = vaddq_f32(vline2_f32, vshift);
vline3_f32 = vaddq_f32(vline3_f32, vshift);
vline4_f32 = vaddq_f32(vline4_f32, vshift);
int32x4_t vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
int32x4_t vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
int32x4_t vline3_s32 = internal::vroundq_s32_f32(vline3_f32);
int32x4_t vline4_s32 = internal::vroundq_s32_f32(vline4_f32);
int32x4_t vline1_s32 = vcvtq_s32_f32(vline1_f32);
int32x4_t vline2_s32 = vcvtq_s32_f32(vline2_f32);
int32x4_t vline3_s32 = vcvtq_s32_f32(vline3_f32);
int32x4_t vline4_s32 = vcvtq_s32_f32(vline4_f32);
vst1q_s32(_dst + i + 0, vline1_s32);
vst1q_s32(_dst + i + 4, vline2_s32);
vst1q_s32(_dst + i + 8, vline3_s32);
@@ -694,7 +693,7 @@ CVTS_FUNC(s8, u8, 16,
#else
CVTS_FUNC(s8, u8, 16,
float32x4_t vscale = vdupq_n_f32((f32)alpha);
float32x4_t vshift = vdupq_n_f32((f32)beta);,
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
{
for (size_t i = 0; i < w; i += 16)
{
@@ -718,10 +717,10 @@ CVTS_FUNC(s8, u8, 16,
vline2_f32 = vaddq_f32(vline2_f32, vshift);
vline3_f32 = vaddq_f32(vline3_f32, vshift);
vline4_f32 = vaddq_f32(vline4_f32, vshift);
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
vline3_s32 = internal::vroundq_s32_f32(vline3_f32);
vline4_s32 = internal::vroundq_s32_f32(vline4_f32);
vline1_s32 = vcvtq_s32_f32(vline1_f32);
vline2_s32 = vcvtq_s32_f32(vline2_f32);
vline3_s32 = vcvtq_s32_f32(vline3_f32);
vline4_s32 = vcvtq_s32_f32(vline4_f32);
uint16x8_t vRes1_u16 = vcombine_u16(vqmovun_s32(vline1_s32), vqmovun_s32(vline2_s32));
uint16x8_t vRes2_u16 = vcombine_u16(vqmovun_s32(vline3_s32), vqmovun_s32(vline4_s32));
vst1q_u8(_dst + i, vcombine_u8(vqmovn_u16(vRes1_u16), vqmovn_u16(vRes2_u16)));
@@ -779,7 +778,7 @@ CVTS_FUNC1(s8, 16,
#else
CVTS_FUNC1(s8, 16,
float32x4_t vscale = vdupq_n_f32((f32)alpha);
float32x4_t vshift = vdupq_n_f32((f32)beta);,
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
{
for (size_t i = 0; i < w; i += 16)
{
@@ -803,10 +802,10 @@ CVTS_FUNC1(s8, 16,
vline2_f32 = vaddq_f32(vline2_f32, vshift);
vline3_f32 = vaddq_f32(vline3_f32, vshift);
vline4_f32 = vaddq_f32(vline4_f32, vshift);
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
vline3_s32 = internal::vroundq_s32_f32(vline3_f32);
vline4_s32 = internal::vroundq_s32_f32(vline4_f32);
vline1_s32 = vcvtq_s32_f32(vline1_f32);
vline2_s32 = vcvtq_s32_f32(vline2_f32);
vline3_s32 = vcvtq_s32_f32(vline3_f32);
vline4_s32 = vcvtq_s32_f32(vline4_f32);
int16x8_t vRes1_s16 = vcombine_s16(vqmovn_s32(vline1_s32), vqmovn_s32(vline2_s32));
int16x8_t vRes2_s16 = vcombine_s16(vqmovn_s32(vline3_s32), vqmovn_s32(vline4_s32));
vst1q_s8(_dst + i, vcombine_s8(vqmovn_s16(vRes1_s16), vqmovn_s16(vRes2_s16)));
@@ -864,7 +863,7 @@ CVTS_FUNC(s8, u16, 16,
#else
CVTS_FUNC(s8, u16, 16,
float32x4_t vscale = vdupq_n_f32((f32)alpha);
float32x4_t vshift = vdupq_n_f32((f32)beta);,
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
{
for (size_t i = 0; i < w; i += 16)
{
@@ -888,10 +887,10 @@ CVTS_FUNC(s8, u16, 16,
vline2_f32 = vaddq_f32(vline2_f32, vshift);
vline3_f32 = vaddq_f32(vline3_f32, vshift);
vline4_f32 = vaddq_f32(vline4_f32, vshift);
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
vline3_s32 = internal::vroundq_s32_f32(vline3_f32);
vline4_s32 = internal::vroundq_s32_f32(vline4_f32);
vline1_s32 = vcvtq_s32_f32(vline1_f32);
vline2_s32 = vcvtq_s32_f32(vline2_f32);
vline3_s32 = vcvtq_s32_f32(vline3_f32);
vline4_s32 = vcvtq_s32_f32(vline4_f32);
uint16x8_t vRes1_u16 = vcombine_u16(vqmovun_s32(vline1_s32), vqmovun_s32(vline2_s32));
uint16x8_t vRes2_u16 = vcombine_u16(vqmovun_s32(vline3_s32), vqmovun_s32(vline4_s32));
vst1q_u16(_dst + i + 0, vRes1_u16);
@@ -950,7 +949,7 @@ CVTS_FUNC(s8, s16, 16,
#else
CVTS_FUNC(s8, s16, 16,
float32x4_t vscale = vdupq_n_f32((f32)alpha);
float32x4_t vshift = vdupq_n_f32((f32)beta);,
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
{
for (size_t i = 0; i < w; i += 16)
{
@@ -974,10 +973,10 @@ CVTS_FUNC(s8, s16, 16,
vline2_f32 = vaddq_f32(vline2_f32, vshift);
vline3_f32 = vaddq_f32(vline3_f32, vshift);
vline4_f32 = vaddq_f32(vline4_f32, vshift);
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
vline3_s32 = internal::vroundq_s32_f32(vline3_f32);
vline4_s32 = internal::vroundq_s32_f32(vline4_f32);
vline1_s32 = vcvtq_s32_f32(vline1_f32);
vline2_s32 = vcvtq_s32_f32(vline2_f32);
vline3_s32 = vcvtq_s32_f32(vline3_f32);
vline4_s32 = vcvtq_s32_f32(vline4_f32);
int16x8_t vRes1_s16 = vcombine_s16(vqmovn_s32(vline1_s32), vqmovn_s32(vline2_s32));
int16x8_t vRes2_s16 = vcombine_s16(vqmovn_s32(vline3_s32), vqmovn_s32(vline4_s32));
vst1q_s16(_dst + i + 0, vRes1_s16);
@@ -1039,7 +1038,7 @@ CVTS_FUNC(s8, s32, 16,
#else
CVTS_FUNC(s8, s32, 16,
float32x4_t vscale = vdupq_n_f32((f32)alpha);
float32x4_t vshift = vdupq_n_f32((f32)beta);,
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
{
for (size_t i = 0; i < w; i += 16)
{
@@ -1063,10 +1062,10 @@ CVTS_FUNC(s8, s32, 16,
vline2_f32 = vaddq_f32(vline2_f32, vshift);
vline3_f32 = vaddq_f32(vline3_f32, vshift);
vline4_f32 = vaddq_f32(vline4_f32, vshift);
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
vline3_s32 = internal::vroundq_s32_f32(vline3_f32);
vline4_s32 = internal::vroundq_s32_f32(vline4_f32);
vline1_s32 = vcvtq_s32_f32(vline1_f32);
vline2_s32 = vcvtq_s32_f32(vline2_f32);
vline3_s32 = vcvtq_s32_f32(vline3_f32);
vline4_s32 = vcvtq_s32_f32(vline4_f32);
vst1q_s32(_dst + i + 0, vline1_s32);
vst1q_s32(_dst + i + 4, vline2_s32);
vst1q_s32(_dst + i + 8, vline3_s32);
@@ -1191,7 +1190,7 @@ CVTS_FUNC(u16, u8, 16,
#else
CVTS_FUNC(u16, u8, 16,
float32x4_t vscale = vdupq_n_f32((f32)alpha);
float32x4_t vshift = vdupq_n_f32((f32)beta);,
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
{
for (size_t i = 0; i < w; i += 8)
{
@@ -1205,8 +1204,8 @@ CVTS_FUNC(u16, u8, 16,
vline2_f32 = vmulq_f32(vline2_f32, vscale);
vline1_f32 = vaddq_f32(vline1_f32, vshift);
vline2_f32 = vaddq_f32(vline2_f32, vshift);
int32x4_t vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
int32x4_t vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
int32x4_t vline1_s32 = vcvtq_s32_f32(vline1_f32);
int32x4_t vline2_s32 = vcvtq_s32_f32(vline2_f32);
int16x4_t vRes1 = vqmovn_s32(vline1_s32);
int16x4_t vRes2 = vqmovn_s32(vline2_s32);
uint8x8_t vRes = vqmovun_s16(vcombine_s16(vRes1, vRes2));
@@ -1250,7 +1249,7 @@ CVTS_FUNC(u16, s8, 16,
#else
CVTS_FUNC(u16, s8, 16,
float32x4_t vscale = vdupq_n_f32((f32)alpha);
float32x4_t vshift = vdupq_n_f32((f32)beta);,
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
{
for (size_t i = 0; i < w; i += 8)
{
@@ -1264,8 +1263,8 @@ CVTS_FUNC(u16, s8, 16,
vline2_f32 = vmulq_f32(vline2_f32, vscale);
vline1_f32 = vaddq_f32(vline1_f32, vshift);
vline2_f32 = vaddq_f32(vline2_f32, vshift);
int32x4_t vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
int32x4_t vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
int32x4_t vline1_s32 = vcvtq_s32_f32(vline1_f32);
int32x4_t vline2_s32 = vcvtq_s32_f32(vline2_f32);
int16x4_t vRes1 = vqmovn_s32(vline1_s32);
int16x4_t vRes2 = vqmovn_s32(vline2_s32);
int8x8_t vRes = vqmovn_s16(vcombine_s16(vRes1, vRes2));
@@ -1308,7 +1307,7 @@ CVTS_FUNC1(u16, 16,
#else
CVTS_FUNC1(u16, 16,
float32x4_t vscale = vdupq_n_f32((f32)alpha);
float32x4_t vshift = vdupq_n_f32((f32)beta);,
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
{
for (size_t i = 0; i < w; i += 8)
{
@@ -1322,8 +1321,8 @@ CVTS_FUNC1(u16, 16,
vline2_f32 = vmulq_f32(vline2_f32, vscale);
vline1_f32 = vaddq_f32(vline1_f32, vshift);
vline2_f32 = vaddq_f32(vline2_f32, vshift);
int32x4_t vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
int32x4_t vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
int32x4_t vline1_s32 = vcvtq_s32_f32(vline1_f32);
int32x4_t vline2_s32 = vcvtq_s32_f32(vline2_f32);
uint16x4_t vRes1 = vqmovun_s32(vline1_s32);
uint16x4_t vRes2 = vqmovun_s32(vline2_s32);
vst1q_u16(_dst + i, vcombine_u16(vRes1, vRes2));
@@ -1365,7 +1364,7 @@ CVTS_FUNC(u16, s16, 8,
#else
CVTS_FUNC(u16, s16, 8,
float32x4_t vscale = vdupq_n_f32((f32)alpha);
float32x4_t vshift = vdupq_n_f32((f32)beta);,
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
{
for (size_t i = 0; i < w; i += 8)
{
@@ -1379,8 +1378,8 @@ CVTS_FUNC(u16, s16, 8,
vline2_f32 = vmulq_f32(vline2_f32, vscale);
vline1_f32 = vaddq_f32(vline1_f32, vshift);
vline2_f32 = vaddq_f32(vline2_f32, vshift);
int32x4_t vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
int32x4_t vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
int32x4_t vline1_s32 = vcvtq_s32_f32(vline1_f32);
int32x4_t vline2_s32 = vcvtq_s32_f32(vline2_f32);
int16x4_t vRes1 = vqmovn_s32(vline1_s32);
int16x4_t vRes2 = vqmovn_s32(vline2_s32);
vst1q_s16(_dst + i, vcombine_s16(vRes1, vRes2));
@@ -1422,7 +1421,7 @@ CVTS_FUNC(u16, s32, 8,
#else
CVTS_FUNC(u16, s32, 8,
float32x4_t vscale = vdupq_n_f32((f32)alpha);
float32x4_t vshift = vdupq_n_f32((f32)beta);,
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
{
for (size_t i = 0; i < w; i += 8)
{
@@ -1436,8 +1435,8 @@ CVTS_FUNC(u16, s32, 8,
vline2_f32 = vmulq_f32(vline2_f32, vscale);
vline1_f32 = vaddq_f32(vline1_f32, vshift);
vline2_f32 = vaddq_f32(vline2_f32, vshift);
int32x4_t vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
int32x4_t vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
int32x4_t vline1_s32 = vcvtq_s32_f32(vline1_f32);
int32x4_t vline2_s32 = vcvtq_s32_f32(vline2_f32);
vst1q_s32(_dst + i + 0, vline1_s32);
vst1q_s32(_dst + i + 4, vline2_s32);
}
@@ -1531,7 +1530,7 @@ CVTS_FUNC(s16, u8, 16,
#else
CVTS_FUNC(s16, u8, 16,
float32x4_t vscale = vdupq_n_f32((f32)alpha);
float32x4_t vshift = vdupq_n_f32((f32)beta);,
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
{
for (size_t i = 0; i < w; i += 8)
{
@@ -1545,8 +1544,8 @@ CVTS_FUNC(s16, u8, 16,
vline2_f32 = vmulq_f32(vline2_f32, vscale);
vline1_f32 = vaddq_f32(vline1_f32, vshift);
vline2_f32 = vaddq_f32(vline2_f32, vshift);
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
vline1_s32 = vcvtq_s32_f32(vline1_f32);
vline2_s32 = vcvtq_s32_f32(vline2_f32);
int16x4_t vRes1 = vqmovn_s32(vline1_s32);
int16x4_t vRes2 = vqmovn_s32(vline2_s32);
uint8x8_t vRes = vqmovun_s16(vcombine_s16(vRes1, vRes2));
@@ -1590,7 +1589,7 @@ CVTS_FUNC(s16, s8, 16,
#else
CVTS_FUNC(s16, s8, 16,
float32x4_t vscale = vdupq_n_f32((f32)alpha);
float32x4_t vshift = vdupq_n_f32((f32)beta);,
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
{
for (size_t i = 0; i < w; i += 8)
{
@@ -1604,8 +1603,8 @@ CVTS_FUNC(s16, s8, 16,
vline2_f32 = vmulq_f32(vline2_f32, vscale);
vline1_f32 = vaddq_f32(vline1_f32, vshift);
vline2_f32 = vaddq_f32(vline2_f32, vshift);
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
vline1_s32 = vcvtq_s32_f32(vline1_f32);
vline2_s32 = vcvtq_s32_f32(vline2_f32);
int16x4_t vRes1 = vqmovn_s32(vline1_s32);
int16x4_t vRes2 = vqmovn_s32(vline2_s32);
int8x8_t vRes = vqmovn_s16(vcombine_s16(vRes1, vRes2));
@@ -1648,7 +1647,7 @@ CVTS_FUNC(s16, u16, 8,
#else
CVTS_FUNC(s16, u16, 8,
float32x4_t vscale = vdupq_n_f32((f32)alpha);
float32x4_t vshift = vdupq_n_f32((f32)beta);,
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
{
for (size_t i = 0; i < w; i += 8)
{
@@ -1662,8 +1661,8 @@ CVTS_FUNC(s16, u16, 8,
vline2_f32 = vmulq_f32(vline2_f32, vscale);
vline1_f32 = vaddq_f32(vline1_f32, vshift);
vline2_f32 = vaddq_f32(vline2_f32, vshift);
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
vline1_s32 = vcvtq_s32_f32(vline1_f32);
vline2_s32 = vcvtq_s32_f32(vline2_f32);
uint16x4_t vRes1 = vqmovun_s32(vline1_s32);
uint16x4_t vRes2 = vqmovun_s32(vline2_s32);
vst1q_u16(_dst + i, vcombine_u16(vRes1, vRes2));
@@ -1705,7 +1704,7 @@ CVTS_FUNC1(s16, 16,
#else
CVTS_FUNC1(s16, 16,
float32x4_t vscale = vdupq_n_f32((f32)alpha);
float32x4_t vshift = vdupq_n_f32((f32)beta);,
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
{
for (size_t i = 0; i < w; i += 8)
{
@@ -1719,8 +1718,8 @@ CVTS_FUNC1(s16, 16,
vline2_f32 = vmulq_f32(vline2_f32, vscale);
vline1_f32 = vaddq_f32(vline1_f32, vshift);
vline2_f32 = vaddq_f32(vline2_f32, vshift);
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
vline1_s32 = vcvtq_s32_f32(vline1_f32);
vline2_s32 = vcvtq_s32_f32(vline2_f32);
int16x4_t vRes1 = vqmovn_s32(vline1_s32);
int16x4_t vRes2 = vqmovn_s32(vline2_s32);
vst1q_s16(_dst + i, vcombine_s16(vRes1, vRes2));
@@ -1762,7 +1761,7 @@ CVTS_FUNC(s16, s32, 8,
#else
CVTS_FUNC(s16, s32, 8,
float32x4_t vscale = vdupq_n_f32((f32)alpha);
float32x4_t vshift = vdupq_n_f32((f32)beta);,
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
{
for (size_t i = 0; i < w; i += 8)
{
@@ -1776,8 +1775,8 @@ CVTS_FUNC(s16, s32, 8,
vline2_f32 = vmulq_f32(vline2_f32, vscale);
vline1_f32 = vaddq_f32(vline1_f32, vshift);
vline2_f32 = vaddq_f32(vline2_f32, vshift);
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
vline1_s32 = vcvtq_s32_f32(vline1_f32);
vline2_s32 = vcvtq_s32_f32(vline2_f32);
vst1q_s32(_dst + i + 0, vline1_s32);
vst1q_s32(_dst + i + 4, vline2_s32);
}
@@ -1871,7 +1870,7 @@ CVTS_FUNC(s32, u8, 8,
#else
CVTS_FUNC(s32, u8, 8,
float32x4_t vscale = vdupq_n_f32((f32)alpha);
float32x4_t vshift = vdupq_n_f32((f32)beta);,
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
{
for (size_t i = 0; i < w; i += 8)
{
@@ -1884,8 +1883,8 @@ CVTS_FUNC(s32, u8, 8,
vline2_f32 = vmulq_f32(vline2_f32, vscale);
vline1_f32 = vaddq_f32(vline1_f32, vshift);
vline2_f32 = vaddq_f32(vline2_f32, vshift);
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
vline1_s32 = vcvtq_s32_f32(vline1_f32);
vline2_s32 = vcvtq_s32_f32(vline2_f32);
uint16x4_t vRes1 = vqmovun_s32(vline1_s32);
uint16x4_t vRes2 = vqmovun_s32(vline2_s32);
uint8x8_t vRes = vqmovn_u16(vcombine_u16(vRes1, vRes2));
@@ -1929,7 +1928,7 @@ CVTS_FUNC(s32, s8, 8,
#else
CVTS_FUNC(s32, s8, 8,
float32x4_t vscale = vdupq_n_f32((f32)alpha);
float32x4_t vshift = vdupq_n_f32((f32)beta);,
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
{
for (size_t i = 0; i < w; i += 8)
{
@@ -1942,8 +1941,8 @@ CVTS_FUNC(s32, s8, 8,
vline2_f32 = vmulq_f32(vline2_f32, vscale);
vline1_f32 = vaddq_f32(vline1_f32, vshift);
vline2_f32 = vaddq_f32(vline2_f32, vshift);
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
vline1_s32 = vcvtq_s32_f32(vline1_f32);
vline2_s32 = vcvtq_s32_f32(vline2_f32);
int16x4_t vRes1 = vqmovn_s32(vline1_s32);
int16x4_t vRes2 = vqmovn_s32(vline2_s32);
int8x8_t vRes = vqmovn_s16(vcombine_s16(vRes1, vRes2));
@@ -1986,7 +1985,7 @@ CVTS_FUNC(s32, u16, 8,
#else
CVTS_FUNC(s32, u16, 8,
float32x4_t vscale = vdupq_n_f32((f32)alpha);
float32x4_t vshift = vdupq_n_f32((f32)beta);,
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
{
for (size_t i = 0; i < w; i += 8)
{
@@ -1999,8 +1998,8 @@ CVTS_FUNC(s32, u16, 8,
vline2_f32 = vmulq_f32(vline2_f32, vscale);
vline1_f32 = vaddq_f32(vline1_f32, vshift);
vline2_f32 = vaddq_f32(vline2_f32, vshift);
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
vline1_s32 = vcvtq_s32_f32(vline1_f32);
vline2_s32 = vcvtq_s32_f32(vline2_f32);
uint16x4_t vRes1 = vqmovun_s32(vline1_s32);
uint16x4_t vRes2 = vqmovun_s32(vline2_s32);
vst1q_u16(_dst + i, vcombine_u16(vRes1, vRes2));
@@ -2042,7 +2041,7 @@ CVTS_FUNC(s32, s16, 8,
#else
CVTS_FUNC(s32, s16, 8,
float32x4_t vscale = vdupq_n_f32((f32)alpha);
float32x4_t vshift = vdupq_n_f32((f32)beta);,
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
{
for (size_t i = 0; i < w; i += 8)
{
@@ -2055,8 +2054,8 @@ CVTS_FUNC(s32, s16, 8,
vline2_f32 = vmulq_f32(vline2_f32, vscale);
vline1_f32 = vaddq_f32(vline1_f32, vshift);
vline2_f32 = vaddq_f32(vline2_f32, vshift);
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
vline1_s32 = vcvtq_s32_f32(vline1_f32);
vline2_s32 = vcvtq_s32_f32(vline2_f32);
int16x4_t vRes1 = vqmovn_s32(vline1_s32);
int16x4_t vRes2 = vqmovn_s32(vline2_s32);
vst1q_s16(_dst + i, vcombine_s16(vRes1, vRes2));
@@ -2098,7 +2097,7 @@ CVTS_FUNC1(s32, 8,
#else
CVTS_FUNC1(s32, 8,
float32x4_t vscale = vdupq_n_f32((f32)alpha);
float32x4_t vshift = vdupq_n_f32((f32)beta);,
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
{
for (size_t i = 0; i < w; i += 8)
{
@@ -2111,8 +2110,8 @@ CVTS_FUNC1(s32, 8,
vline2_f32 = vmulq_f32(vline2_f32, vscale);
vline1_f32 = vaddq_f32(vline1_f32, vshift);
vline2_f32 = vaddq_f32(vline2_f32, vshift);
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
vline1_s32 = vcvtq_s32_f32(vline1_f32);
vline2_s32 = vcvtq_s32_f32(vline2_f32);
vst1q_s32(_dst + i + 0, vline1_s32);
vst1q_s32(_dst + i + 4, vline2_s32);
}
@@ -2273,7 +2272,7 @@ CVTS_FUNC(f32, s8, 8,
#else
CVTS_FUNC(f32, s8, 8,
float32x4_t vscale = vdupq_n_f32((f32)alpha);
float32x4_t vshift = vdupq_n_f32((f32)beta);,
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
{
for (size_t i = 0; i < w; i += 8)
{
@@ -2284,8 +2283,8 @@ CVTS_FUNC(f32, s8, 8,
vline2_f32 = vmulq_f32(vline2_f32, vscale);
vline1_f32 = vaddq_f32(vline1_f32, vshift);
vline2_f32 = vaddq_f32(vline2_f32, vshift);
int32x4_t vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
int32x4_t vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
int32x4_t vline1_s32 = vcvtq_s32_f32(vline1_f32);
int32x4_t vline2_s32 = vcvtq_s32_f32(vline2_f32);
int16x4_t vRes1 = vqmovn_s32(vline1_s32);
int16x4_t vRes2 = vqmovn_s32(vline2_s32);
int8x8_t vRes = vqmovn_s16(vcombine_s16(vRes1, vRes2));
@@ -2326,7 +2325,7 @@ CVTS_FUNC(f32, u16, 8,
#else
CVTS_FUNC(f32, u16, 8,
float32x4_t vscale = vdupq_n_f32((f32)alpha);
float32x4_t vshift = vdupq_n_f32((f32)beta);,
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
{
for (size_t i = 0; i < w; i += 8)
{
@@ -2337,8 +2336,8 @@ CVTS_FUNC(f32, u16, 8,
vline2_f32 = vmulq_f32(vline2_f32, vscale);
vline1_f32 = vaddq_f32(vline1_f32, vshift);
vline2_f32 = vaddq_f32(vline2_f32, vshift);
uint32x4_t vline1_u32 = internal::vroundq_u32_f32(vline1_f32);
uint32x4_t vline2_u32 = internal::vroundq_u32_f32(vline2_f32);
uint32x4_t vline1_u32 = vcvtq_u32_f32(vline1_f32);
uint32x4_t vline2_u32 = vcvtq_u32_f32(vline2_f32);
uint16x4_t vRes1 = vqmovn_u32(vline1_u32);
uint16x4_t vRes2 = vqmovn_u32(vline2_u32);
vst1q_u16(_dst + i, vcombine_u16(vRes1, vRes2));
@@ -2378,7 +2377,7 @@ CVTS_FUNC(f32, s16, 8,
#else
CVTS_FUNC(f32, s16, 8,
float32x4_t vscale = vdupq_n_f32((f32)alpha);
float32x4_t vshift = vdupq_n_f32((f32)beta);,
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
{
for (size_t i = 0; i < w; i += 8)
{
@@ -2389,8 +2388,8 @@ CVTS_FUNC(f32, s16, 8,
vline2_f32 = vmulq_f32(vline2_f32, vscale);
vline1_f32 = vaddq_f32(vline1_f32, vshift);
vline2_f32 = vaddq_f32(vline2_f32, vshift);
int32x4_t vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
int32x4_t vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
int32x4_t vline1_s32 = vcvtq_s32_f32(vline1_f32);
int32x4_t vline2_s32 = vcvtq_s32_f32(vline2_f32);
int16x4_t vRes1 = vqmovn_s32(vline1_s32);
int16x4_t vRes2 = vqmovn_s32(vline2_s32);
vst1q_s16(_dst + i, vcombine_s16(vRes1, vRes2));
@@ -2430,7 +2429,7 @@ CVTS_FUNC(f32, s32, 8,
#else
CVTS_FUNC(f32, s32, 8,
float32x4_t vscale = vdupq_n_f32((f32)alpha);
float32x4_t vshift = vdupq_n_f32((f32)beta);,
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
{
for (size_t i = 0; i < w; i += 8)
{
@@ -2441,8 +2440,8 @@ CVTS_FUNC(f32, s32, 8,
vline2_f32 = vmulq_f32(vline2_f32, vscale);
vline1_f32 = vaddq_f32(vline1_f32, vshift);
vline2_f32 = vaddq_f32(vline2_f32, vshift);
int32x4_t vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
int32x4_t vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
int32x4_t vline1_s32 = vcvtq_s32_f32(vline1_f32);
int32x4_t vline2_s32 = vcvtq_s32_f32(vline2_f32);
vst1q_s32(_dst + i + 0, vline1_s32);
vst1q_s32(_dst + i + 4, vline2_s32);
}
+20 -7
View File
@@ -39,7 +39,6 @@
#include "common.hpp"
#include "vtransform.hpp"
#include "vround_helper.hpp"
#include <cstring>
#include <cfloat>
@@ -52,6 +51,13 @@ namespace {
#ifdef CAROTENE_NEON
inline float32x4_t vroundq(const float32x4_t& v)
{
const int32x4_t signMask = vdupq_n_s32(1 << 31), half = vreinterpretq_s32_f32(vdupq_n_f32(0.5f));
float32x4_t v_addition = vreinterpretq_f32_s32(vorrq_s32(half, vandq_s32(signMask, vreinterpretq_s32_f32(v))));
return vaddq_f32(v, v_addition);
}
template <typename T>
inline T divSaturateQ(const T &v1, const T &v2, const float scale)
{
@@ -63,10 +69,17 @@ inline T divSaturateQ(const T &v1, const T &v2, const float scale)
}
template <>
inline int32x4_t divSaturateQ<int32x4_t>(const int32x4_t &v1, const int32x4_t &v2, const float scale)
{ return internal::vroundq_s32_f32(vmulq_f32(vmulq_n_f32(vcvtq_f32_s32(v1), scale), internal::vrecpq_f32(vcvtq_f32_s32(v2)))); }
{ return vcvtq_s32_f32(vroundq(vmulq_f32(vmulq_n_f32(vcvtq_f32_s32(v1), scale), internal::vrecpq_f32(vcvtq_f32_s32(v2))))); }
template <>
inline uint32x4_t divSaturateQ<uint32x4_t>(const uint32x4_t &v1, const uint32x4_t &v2, const float scale)
{ return internal::vroundq_u32_f32(vmulq_f32(vmulq_n_f32(vcvtq_f32_u32(v1), scale), internal::vrecpq_f32(vcvtq_f32_u32(v2)))); }
{ return vcvtq_u32_f32(vroundq(vmulq_f32(vmulq_n_f32(vcvtq_f32_u32(v1), scale), internal::vrecpq_f32(vcvtq_f32_u32(v2))))); }
inline float32x2_t vround(const float32x2_t& v)
{
const int32x2_t signMask = vdup_n_s32(1 << 31), half = vreinterpret_s32_f32(vdup_n_f32(0.5f));
float32x2_t v_addition = vreinterpret_f32_s32(vorr_s32(half, vand_s32(signMask, vreinterpret_s32_f32(v))));
return vadd_f32(v, v_addition);
}
template <typename T>
inline T divSaturate(const T &v1, const T &v2, const float scale)
@@ -75,10 +88,10 @@ inline T divSaturate(const T &v1, const T &v2, const float scale)
}
template <>
inline int32x2_t divSaturate<int32x2_t>(const int32x2_t &v1, const int32x2_t &v2, const float scale)
{ return internal::vround_s32_f32(vmul_f32(vmul_n_f32(vcvt_f32_s32(v1), scale), internal::vrecp_f32(vcvt_f32_s32(v2)))); }
{ return vcvt_s32_f32(vround(vmul_f32(vmul_n_f32(vcvt_f32_s32(v1), scale), internal::vrecp_f32(vcvt_f32_s32(v2))))); }
template <>
inline uint32x2_t divSaturate<uint32x2_t>(const uint32x2_t &v1, const uint32x2_t &v2, const float scale)
{ return internal::vround_u32_f32(vmul_f32(vmul_n_f32(vcvt_f32_u32(v1), scale), internal::vrecp_f32(vcvt_f32_u32(v2)))); }
{ return vcvt_u32_f32(vround(vmul_f32(vmul_n_f32(vcvt_f32_u32(v1), scale), internal::vrecp_f32(vcvt_f32_u32(v2))))); }
template <typename T>
@@ -144,8 +157,8 @@ void div(const Size2D &size,
if (scale == 0.0f ||
(std::numeric_limits<T>::is_integer &&
(scale * static_cast<float>(std::numeric_limits<T>::max())) < 1.0f &&
(scale * static_cast<float>(std::numeric_limits<T>::max())) > -1.0f))
(scale * std::numeric_limits<T>::max()) < 1.0f &&
(scale * std::numeric_limits<T>::max()) > -1.0f))
{
for (size_t y = 0; y < size.height; ++y)
{
-2
View File
@@ -1,2 +0,0 @@
// This file is needed for compilation on some platforms e.g. with XCode generator
// Related issue: https://gitlab.kitware.com/cmake/cmake/-/issues/17457
+8 -7
View File
@@ -41,7 +41,6 @@
#include <cmath>
#include "common.hpp"
#include "vround_helper.hpp"
namespace CAROTENE_NS {
@@ -122,6 +121,8 @@ void phase(const Size2D &size,
size_t roiw16 = size.width >= 15 ? size.width - 15 : 0;
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
float32x4_t v_05 = vdupq_n_f32(0.5f);
for (size_t i = 0; i < size.height; ++i)
{
const s16 * src0 = internal::getRowPtr(src0Base, src0Stride, i);
@@ -148,8 +149,8 @@ void phase(const Size2D &size,
float32x4_t v_dst32f1;
FASTATAN2VECTOR(v_src1_p, v_src0_p, v_dst32f1)
uint16x8_t v_dst16s0 = vcombine_u16(vmovn_u32(internal::vroundq_u32_f32(v_dst32f0)),
vmovn_u32(internal::vroundq_u32_f32(v_dst32f1)));
uint16x8_t v_dst16s0 = vcombine_u16(vmovn_u32(vcvtq_u32_f32(vaddq_f32(v_dst32f0, v_05))),
vmovn_u32(vcvtq_u32_f32(vaddq_f32(v_dst32f1, v_05))));
// 1
v_src0_p = vcvtq_f32_s32(vmovl_s16(vget_low_s16(v_src01)));
@@ -160,8 +161,8 @@ void phase(const Size2D &size,
v_src1_p = vcvtq_f32_s32(vmovl_s16(vget_high_s16(v_src11)));
FASTATAN2VECTOR(v_src1_p, v_src0_p, v_dst32f1)
uint16x8_t v_dst16s1 = vcombine_u16(vmovn_u32(internal::vroundq_u32_f32(v_dst32f0)),
vmovn_u32(internal::vroundq_u32_f32(v_dst32f1)));
uint16x8_t v_dst16s1 = vcombine_u16(vmovn_u32(vcvtq_u32_f32(vaddq_f32(v_dst32f0, v_05))),
vmovn_u32(vcvtq_u32_f32(vaddq_f32(v_dst32f1, v_05))));
vst1q_u8(dst + j, vcombine_u8(vmovn_u16(v_dst16s0),
vmovn_u16(v_dst16s1)));
@@ -181,8 +182,8 @@ void phase(const Size2D &size,
float32x4_t v_dst32f1;
FASTATAN2VECTOR(v_src1_p, v_src0_p, v_dst32f1)
uint16x8_t v_dst = vcombine_u16(vmovn_u32(internal::vroundq_u32_f32(v_dst32f0)),
vmovn_u32(internal::vroundq_u32_f32(v_dst32f1)));
uint16x8_t v_dst = vcombine_u16(vmovn_u32(vcvtq_u32_f32(vaddq_f32(v_dst32f0, v_05))),
vmovn_u32(vcvtq_u32_f32(vaddq_f32(v_dst32f1, v_05))));
vst1_u8(dst + j, vmovn_u16(v_dst));
}
+1 -1
View File
@@ -758,7 +758,7 @@ inline void resizeAreaRounding(const Size2D &ssize, const Size2D &dsize,
}
else if (channels == 3)
{
if ((wr == 2.0f) && (hr == 2.0f))
if ((wr == 2.0f) && (wr == 2.0f))
{
#ifndef __ANDROID__
size_t roiw16 = dsize.width >= 15 ? (dsize.width - 15) * 3 : 0;
-102
View File
@@ -1,102 +0,0 @@
/*
* By downloading, copying, installing or using the software you agree to this license.
* If you do not agree to this license, do not download, install,
* copy or use the software.
*
*
* License Agreement
* For Open Source Computer Vision Library
* (3-clause BSD License)
*
* Copyright (C) 2014-2015, NVIDIA Corporation, all rights reserved.
* Third party copyrights are property of their respective owners.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the names of the copyright holders nor the names of the contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* This software is provided by the copyright holders and contributors "as is" and
* any express or implied warranties, including, but not limited to, the implied
* warranties of merchantability and fitness for a particular purpose are disclaimed.
* In no event shall copyright holders or contributors be liable for any direct,
* indirect, incidental, special, exemplary, or consequential damages
* (including, but not limited to, procurement of substitute goods or services;
* loss of use, data, or profits; or business interruption) however caused
* and on any theory of liability, whether in contract, strict liability,
* or tort (including negligence or otherwise) arising in any way out of
* the use of this software, even if advised of the possibility of such damage.
*/
#ifndef CAROTENE_SRC_VROUND_HELPER_HPP
#define CAROTENE_SRC_VROUND_HELPER_HPP
#include "common.hpp"
#include "vtransform.hpp"
#ifdef CAROTENE_NEON
/**
* This helper header is for rounding from float32xN to uin32xN or int32xN to nearest, ties to even.
* See https://en.wikipedia.org/wiki/Rounding#Rounding_half_to_even
*/
// See https://github.com/opencv/opencv/pull/24271#issuecomment-1867318007
#define CAROTENE_ROUND_DELTA (12582912.0f)
namespace CAROTENE_NS { namespace internal {
inline uint32x4_t vroundq_u32_f32(const float32x4_t val)
{
#if CAROTENE_NEON_ARCH >= 8 /* get ready for ARMv9 */
return vcvtnq_u32_f32(val);
#else
const float32x4_t delta = vdupq_n_f32(CAROTENE_ROUND_DELTA);
return vcvtq_u32_f32(vsubq_f32(vaddq_f32(val, delta), delta));
#endif
}
inline uint32x2_t vround_u32_f32(const float32x2_t val)
{
#if CAROTENE_NEON_ARCH >= 8 /* get ready for ARMv9 */
return vcvtn_u32_f32(val);
#else
const float32x2_t delta = vdup_n_f32(CAROTENE_ROUND_DELTA);
return vcvt_u32_f32(vsub_f32(vadd_f32(val, delta), delta));
#endif
}
inline int32x4_t vroundq_s32_f32(const float32x4_t val)
{
#if CAROTENE_NEON_ARCH >= 8 /* get ready for ARMv9 */
return vcvtnq_s32_f32(val);
#else
const float32x4_t delta = vdupq_n_f32(CAROTENE_ROUND_DELTA);
return vcvtq_s32_f32(vsubq_f32(vaddq_f32(val, delta), delta));
#endif
}
inline int32x2_t vround_s32_f32(const float32x2_t val)
{
#if CAROTENE_NEON_ARCH >= 8 /* get ready for ARMv9 */
return vcvtn_s32_f32(val);
#else
const float32x2_t delta = vdup_n_f32(CAROTENE_ROUND_DELTA);
return vcvt_s32_f32(vsub_f32(vadd_f32(val, delta), delta));
#endif
}
} }
#endif // CAROTENE_NEON
#endif
+2 -2
View File
@@ -14,7 +14,7 @@ if(NOT DEFINED CPUFEATURES_SOURCES)
endif()
include_directories(${CPUFEATURES_INCLUDE_DIRS})
add_library(${OPENCV_CPUFEATURES_TARGET_NAME} STATIC ${OPENCV_3RDPARTY_EXCLUDE_FROM_ALL} ${CPUFEATURES_SOURCES})
add_library(${OPENCV_CPUFEATURES_TARGET_NAME} STATIC ${CPUFEATURES_SOURCES})
set_target_properties(${OPENCV_CPUFEATURES_TARGET_NAME}
PROPERTIES OUTPUT_NAME cpufeatures
@@ -29,7 +29,7 @@ if(ENABLE_SOLUTION_FOLDERS)
endif()
if(NOT BUILD_SHARED_LIBS)
ocv_install_target(${OPENCV_CPUFEATURES_TARGET_NAME} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev OPTIONAL)
ocv_install_target(${OPENCV_CPUFEATURES_TARGET_NAME} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
endif()
ocv_install_3rdparty_licenses(cpufeatures LICENSE README.md)
+6 -6
View File
@@ -1,9 +1,9 @@
# Binaries branch name: ffmpeg/4.x_20240522
# Binaries were created for OpenCV: 8393885a39dac1e650bf5d0aaff84c04ad8bcdd3
ocv_update(FFMPEG_BINARIES_COMMIT "394dca6ceb3085c979415e6385996b6570e94153")
ocv_update(FFMPEG_FILE_HASH_BIN32 "bdfbd1efb295f3e54c07d2cb7a843bf9")
ocv_update(FFMPEG_FILE_HASH_BIN64 "bfef029900f788480a363d6dc05c4f0e")
ocv_update(FFMPEG_FILE_HASH_CMAKE "8862c87496e2e8c375965e1277dee1c7")
# Binaries branch name: ffmpeg/master_20200311
# Binaries were created for OpenCV: 850414a501d5e6dba111c92d73fdd05794c7061d
ocv_update(FFMPEG_BINARIES_COMMIT "3d2e97081683265950316c65a52c2e8858ffba1b")
ocv_update(FFMPEG_FILE_HASH_BIN32 "3b094c37d270a30f0b20a0bc8d3ecafb")
ocv_update(FFMPEG_FILE_HASH_BIN64 "388ee23a7ca44eef2344e265fafd5940")
ocv_update(FFMPEG_FILE_HASH_CMAKE "ad57c038ba34b868277ccbe6dd0f9602")
function(download_win_ffmpeg script_var)
set(${script_var} "" PARENT_SCOPE)
-202
View File
@@ -1,202 +0,0 @@
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 [yyyy] [name of copyright owner]
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.
-1
View File
@@ -1 +0,0 @@
Origin: https://github.com/google/flatbuffers/tree/v23.5.9
-68
View File
@@ -1,68 +0,0 @@
/*
* Copyright 2021 Google Inc. All rights reserved.
*
* 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.
*/
#ifndef FLATBUFFERS_ALLOCATOR_H_
#define FLATBUFFERS_ALLOCATOR_H_
#include "flatbuffers/base.h"
namespace flatbuffers {
// Allocator interface. This is flatbuffers-specific and meant only for
// `vector_downward` usage.
class Allocator {
public:
virtual ~Allocator() {}
// Allocate `size` bytes of memory.
virtual uint8_t *allocate(size_t size) = 0;
// Deallocate `size` bytes of memory at `p` allocated by this allocator.
virtual void deallocate(uint8_t *p, size_t size) = 0;
// Reallocate `new_size` bytes of memory, replacing the old region of size
// `old_size` at `p`. In contrast to a normal realloc, this grows downwards,
// and is intended specifcally for `vector_downward` use.
// `in_use_back` and `in_use_front` indicate how much of `old_size` is
// actually in use at each end, and needs to be copied.
virtual uint8_t *reallocate_downward(uint8_t *old_p, size_t old_size,
size_t new_size, size_t in_use_back,
size_t in_use_front) {
FLATBUFFERS_ASSERT(new_size > old_size); // vector_downward only grows
uint8_t *new_p = allocate(new_size);
memcpy_downward(old_p, old_size, new_p, new_size, in_use_back,
in_use_front);
deallocate(old_p, old_size);
return new_p;
}
protected:
// Called by `reallocate_downward` to copy memory from `old_p` of `old_size`
// to `new_p` of `new_size`. Only memory of size `in_use_front` and
// `in_use_back` will be copied from the front and back of the old memory
// allocation.
void memcpy_downward(uint8_t *old_p, size_t old_size, uint8_t *new_p,
size_t new_size, size_t in_use_back,
size_t in_use_front) {
memcpy(new_p + new_size - in_use_back, old_p + old_size - in_use_back,
in_use_back);
memcpy(new_p, old_p, in_use_front);
}
};
} // namespace flatbuffers
#endif // FLATBUFFERS_ALLOCATOR_H_
-256
View File
@@ -1,256 +0,0 @@
/*
* Copyright 2021 Google Inc. All rights reserved.
*
* 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.
*/
#ifndef FLATBUFFERS_ARRAY_H_
#define FLATBUFFERS_ARRAY_H_
#include <cstdint>
#include <memory>
#include "flatbuffers/base.h"
#include "flatbuffers/stl_emulation.h"
#include "flatbuffers/vector.h"
namespace flatbuffers {
// This is used as a helper type for accessing arrays.
template<typename T, uint16_t length> class Array {
// Array<T> can carry only POD data types (scalars or structs).
typedef typename flatbuffers::bool_constant<flatbuffers::is_scalar<T>::value>
scalar_tag;
typedef
typename flatbuffers::conditional<scalar_tag::value, T, const T *>::type
IndirectHelperType;
public:
typedef uint16_t size_type;
typedef typename IndirectHelper<IndirectHelperType>::return_type return_type;
typedef VectorConstIterator<T, return_type, uoffset_t> const_iterator;
typedef VectorReverseIterator<const_iterator> const_reverse_iterator;
// If T is a LE-scalar or a struct (!scalar_tag::value).
static FLATBUFFERS_CONSTEXPR bool is_span_observable =
(scalar_tag::value && (FLATBUFFERS_LITTLEENDIAN || sizeof(T) == 1)) ||
!scalar_tag::value;
FLATBUFFERS_CONSTEXPR uint16_t size() const { return length; }
return_type Get(uoffset_t i) const {
FLATBUFFERS_ASSERT(i < size());
return IndirectHelper<IndirectHelperType>::Read(Data(), i);
}
return_type operator[](uoffset_t i) const { return Get(i); }
// If this is a Vector of enums, T will be its storage type, not the enum
// type. This function makes it convenient to retrieve value with enum
// type E.
template<typename E> E GetEnum(uoffset_t i) const {
return static_cast<E>(Get(i));
}
const_iterator begin() const { return const_iterator(Data(), 0); }
const_iterator end() const { return const_iterator(Data(), size()); }
const_reverse_iterator rbegin() const {
return const_reverse_iterator(end());
}
const_reverse_iterator rend() const {
return const_reverse_iterator(begin());
}
const_iterator cbegin() const { return begin(); }
const_iterator cend() const { return end(); }
const_reverse_iterator crbegin() const { return rbegin(); }
const_reverse_iterator crend() const { return rend(); }
// Get a mutable pointer to elements inside this array.
// This method used to mutate arrays of structs followed by a @p Mutate
// operation. For primitive types use @p Mutate directly.
// @warning Assignments and reads to/from the dereferenced pointer are not
// automatically converted to the correct endianness.
typename flatbuffers::conditional<scalar_tag::value, void, T *>::type
GetMutablePointer(uoffset_t i) const {
FLATBUFFERS_ASSERT(i < size());
return const_cast<T *>(&data()[i]);
}
// Change elements if you have a non-const pointer to this object.
void Mutate(uoffset_t i, const T &val) { MutateImpl(scalar_tag(), i, val); }
// The raw data in little endian format. Use with care.
const uint8_t *Data() const { return data_; }
uint8_t *Data() { return data_; }
// Similarly, but typed, much like std::vector::data
const T *data() const { return reinterpret_cast<const T *>(Data()); }
T *data() { return reinterpret_cast<T *>(Data()); }
// Copy data from a span with endian conversion.
// If this Array and the span overlap, the behavior is undefined.
void CopyFromSpan(flatbuffers::span<const T, length> src) {
const auto p1 = reinterpret_cast<const uint8_t *>(src.data());
const auto p2 = Data();
FLATBUFFERS_ASSERT(!(p1 >= p2 && p1 < (p2 + length)) &&
!(p2 >= p1 && p2 < (p1 + length)));
(void)p1;
(void)p2;
CopyFromSpanImpl(flatbuffers::bool_constant<is_span_observable>(), src);
}
protected:
void MutateImpl(flatbuffers::true_type, uoffset_t i, const T &val) {
FLATBUFFERS_ASSERT(i < size());
WriteScalar(data() + i, val);
}
void MutateImpl(flatbuffers::false_type, uoffset_t i, const T &val) {
*(GetMutablePointer(i)) = val;
}
void CopyFromSpanImpl(flatbuffers::true_type,
flatbuffers::span<const T, length> src) {
// Use std::memcpy() instead of std::copy() to avoid performance degradation
// due to aliasing if T is char or unsigned char.
// The size is known at compile time, so memcpy would be inlined.
std::memcpy(data(), src.data(), length * sizeof(T));
}
// Copy data from flatbuffers::span with endian conversion.
void CopyFromSpanImpl(flatbuffers::false_type,
flatbuffers::span<const T, length> src) {
for (size_type k = 0; k < length; k++) { Mutate(k, src[k]); }
}
// This class is only used to access pre-existing data. Don't ever
// try to construct these manually.
// 'constexpr' allows us to use 'size()' at compile time.
// @note Must not use 'FLATBUFFERS_CONSTEXPR' here, as const is not allowed on
// a constructor.
#if defined(__cpp_constexpr)
constexpr Array();
#else
Array();
#endif
uint8_t data_[length * sizeof(T)];
private:
// This class is a pointer. Copying will therefore create an invalid object.
// Private and unimplemented copy constructor.
Array(const Array &);
Array &operator=(const Array &);
};
// Specialization for Array[struct] with access using Offset<void> pointer.
// This specialization used by idl_gen_text.cpp.
template<typename T, uint16_t length, template<typename> class OffsetT>
class Array<OffsetT<T>, length> {
static_assert(flatbuffers::is_same<T, void>::value, "unexpected type T");
public:
typedef const void *return_type;
typedef uint16_t size_type;
const uint8_t *Data() const { return data_; }
// Make idl_gen_text.cpp::PrintContainer happy.
return_type operator[](uoffset_t) const {
FLATBUFFERS_ASSERT(false);
return nullptr;
}
private:
// This class is only used to access pre-existing data.
Array();
Array(const Array &);
Array &operator=(const Array &);
uint8_t data_[1];
};
template<class U, uint16_t N>
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<U, N> make_span(Array<U, N> &arr)
FLATBUFFERS_NOEXCEPT {
static_assert(
Array<U, N>::is_span_observable,
"wrong type U, only plain struct, LE-scalar, or byte types are allowed");
return span<U, N>(arr.data(), N);
}
template<class U, uint16_t N>
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const U, N> make_span(
const Array<U, N> &arr) FLATBUFFERS_NOEXCEPT {
static_assert(
Array<U, N>::is_span_observable,
"wrong type U, only plain struct, LE-scalar, or byte types are allowed");
return span<const U, N>(arr.data(), N);
}
template<class U, uint16_t N>
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<uint8_t, sizeof(U) * N>
make_bytes_span(Array<U, N> &arr) FLATBUFFERS_NOEXCEPT {
static_assert(Array<U, N>::is_span_observable,
"internal error, Array<T> might hold only scalars or structs");
return span<uint8_t, sizeof(U) * N>(arr.Data(), sizeof(U) * N);
}
template<class U, uint16_t N>
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const uint8_t, sizeof(U) * N>
make_bytes_span(const Array<U, N> &arr) FLATBUFFERS_NOEXCEPT {
static_assert(Array<U, N>::is_span_observable,
"internal error, Array<T> might hold only scalars or structs");
return span<const uint8_t, sizeof(U) * N>(arr.Data(), sizeof(U) * N);
}
// Cast a raw T[length] to a raw flatbuffers::Array<T, length>
// without endian conversion. Use with care.
// TODO: move these Cast-methods to `internal` namespace.
template<typename T, uint16_t length>
Array<T, length> &CastToArray(T (&arr)[length]) {
return *reinterpret_cast<Array<T, length> *>(arr);
}
template<typename T, uint16_t length>
const Array<T, length> &CastToArray(const T (&arr)[length]) {
return *reinterpret_cast<const Array<T, length> *>(arr);
}
template<typename E, typename T, uint16_t length>
Array<E, length> &CastToArrayOfEnum(T (&arr)[length]) {
static_assert(sizeof(E) == sizeof(T), "invalid enum type E");
return *reinterpret_cast<Array<E, length> *>(arr);
}
template<typename E, typename T, uint16_t length>
const Array<E, length> &CastToArrayOfEnum(const T (&arr)[length]) {
static_assert(sizeof(E) == sizeof(T), "invalid enum type E");
return *reinterpret_cast<const Array<E, length> *>(arr);
}
template<typename T, uint16_t length>
bool operator==(const Array<T, length> &lhs,
const Array<T, length> &rhs) noexcept {
return std::addressof(lhs) == std::addressof(rhs) ||
(lhs.size() == rhs.size() &&
std::memcmp(lhs.Data(), rhs.Data(), rhs.size() * sizeof(T)) == 0);
}
} // namespace flatbuffers
#endif // FLATBUFFERS_ARRAY_H_
-495
View File
@@ -1,495 +0,0 @@
#ifndef FLATBUFFERS_BASE_H_
#define FLATBUFFERS_BASE_H_
// clang-format off
// If activate should be declared and included first.
#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && \
defined(_MSC_VER) && defined(_DEBUG)
// The _CRTDBG_MAP_ALLOC inside <crtdbg.h> will replace
// calloc/free (etc) to its debug version using #define directives.
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
// Replace operator new by trace-enabled version.
#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define new DEBUG_NEW
#endif
#if !defined(FLATBUFFERS_ASSERT)
#include <assert.h>
#define FLATBUFFERS_ASSERT assert
#elif defined(FLATBUFFERS_ASSERT_INCLUDE)
// Include file with forward declaration
#include FLATBUFFERS_ASSERT_INCLUDE
#endif
#ifndef ARDUINO
#include <cstdint>
#endif
#include <cstddef>
#include <cstdlib>
#include <cstring>
#if defined(ARDUINO) && !defined(ARDUINOSTL_M_H) && defined(__AVR__)
#include <utility.h>
#else
#include <utility>
#endif
#include <string>
#include <type_traits>
#include <vector>
#include <set>
#include <algorithm>
#include <limits>
#include <iterator>
#include <memory>
#if defined(__unix__) && !defined(FLATBUFFERS_LOCALE_INDEPENDENT)
#include <unistd.h>
#endif
#ifdef __ANDROID__
#include <android/api-level.h>
#endif
#if defined(__ICCARM__)
#include <intrinsics.h>
#endif
// Note the __clang__ check is needed, because clang presents itself
// as an older GNUC compiler (4.2).
// Clang 3.3 and later implement all of the ISO C++ 2011 standard.
// Clang 3.4 and later implement all of the ISO C++ 2014 standard.
// http://clang.llvm.org/cxx_status.html
// Note the MSVC value '__cplusplus' may be incorrect:
// The '__cplusplus' predefined macro in the MSVC stuck at the value 199711L,
// indicating (erroneously!) that the compiler conformed to the C++98 Standard.
// This value should be correct starting from MSVC2017-15.7-Preview-3.
// The '__cplusplus' will be valid only if MSVC2017-15.7-P3 and the `/Zc:__cplusplus` switch is set.
// Workaround (for details see MSDN):
// Use the _MSC_VER and _MSVC_LANG definition instead of the __cplusplus for compatibility.
// The _MSVC_LANG macro reports the Standard version regardless of the '/Zc:__cplusplus' switch.
#if defined(__GNUC__) && !defined(__clang__)
#define FLATBUFFERS_GCC (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#else
#define FLATBUFFERS_GCC 0
#endif
#if defined(__clang__)
#define FLATBUFFERS_CLANG (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
#else
#define FLATBUFFERS_CLANG 0
#endif
/// @cond FLATBUFFERS_INTERNAL
#if __cplusplus <= 199711L && \
(!defined(_MSC_VER) || _MSC_VER < 1600) && \
(!defined(__GNUC__) || \
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40400))
#error A C++11 compatible compiler with support for the auto typing is \
required for FlatBuffers.
#error __cplusplus _MSC_VER __GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__
#endif
#if !defined(__clang__) && \
defined(__GNUC__) && \
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40600)
// Backwards compatibility for g++ 4.4, and 4.5 which don't have the nullptr
// and constexpr keywords. Note the __clang__ check is needed, because clang
// presents itself as an older GNUC compiler.
#ifndef nullptr_t
const class nullptr_t {
public:
template<class T> inline operator T*() const { return 0; }
private:
void operator&() const;
} nullptr = {};
#endif
#ifndef constexpr
#define constexpr const
#endif
#endif
// The wire format uses a little endian encoding (since that's efficient for
// the common platforms).
#if defined(__s390x__)
#define FLATBUFFERS_LITTLEENDIAN 0
#endif // __s390x__
#if !defined(FLATBUFFERS_LITTLEENDIAN)
#if defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__)
#if (defined(__BIG_ENDIAN__) || \
(defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
#define FLATBUFFERS_LITTLEENDIAN 0
#else
#define FLATBUFFERS_LITTLEENDIAN 1
#endif // __BIG_ENDIAN__
#elif defined(_MSC_VER)
#if defined(_M_PPC)
#define FLATBUFFERS_LITTLEENDIAN 0
#else
#define FLATBUFFERS_LITTLEENDIAN 1
#endif
#else
#error Unable to determine endianness, define FLATBUFFERS_LITTLEENDIAN.
#endif
#endif // !defined(FLATBUFFERS_LITTLEENDIAN)
#define FLATBUFFERS_VERSION_MAJOR 23
#define FLATBUFFERS_VERSION_MINOR 5
#define FLATBUFFERS_VERSION_REVISION 9
#define FLATBUFFERS_STRING_EXPAND(X) #X
#define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X)
namespace flatbuffers {
// Returns version as string "MAJOR.MINOR.REVISION".
const char* FLATBUFFERS_VERSION();
}
#if (!defined(_MSC_VER) || _MSC_VER > 1600) && \
(!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 407)) || \
defined(__clang__)
#define FLATBUFFERS_FINAL_CLASS final
#define FLATBUFFERS_OVERRIDE override
#define FLATBUFFERS_EXPLICIT_CPP11 explicit
#define FLATBUFFERS_VTABLE_UNDERLYING_TYPE : flatbuffers::voffset_t
#else
#define FLATBUFFERS_FINAL_CLASS
#define FLATBUFFERS_OVERRIDE
#define FLATBUFFERS_EXPLICIT_CPP11
#define FLATBUFFERS_VTABLE_UNDERLYING_TYPE
#endif
#if (!defined(_MSC_VER) || _MSC_VER >= 1900) && \
(!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)) || \
(defined(__cpp_constexpr) && __cpp_constexpr >= 200704)
#define FLATBUFFERS_CONSTEXPR constexpr
#define FLATBUFFERS_CONSTEXPR_CPP11 constexpr
#define FLATBUFFERS_CONSTEXPR_DEFINED
#else
#define FLATBUFFERS_CONSTEXPR const
#define FLATBUFFERS_CONSTEXPR_CPP11
#endif
#if (defined(__cplusplus) && __cplusplus >= 201402L) || \
(defined(__cpp_constexpr) && __cpp_constexpr >= 201304)
#define FLATBUFFERS_CONSTEXPR_CPP14 FLATBUFFERS_CONSTEXPR_CPP11
#else
#define FLATBUFFERS_CONSTEXPR_CPP14
#endif
#if (defined(__GXX_EXPERIMENTAL_CXX0X__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)) || \
(defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 190023026)) || \
defined(__clang__)
#define FLATBUFFERS_NOEXCEPT noexcept
#else
#define FLATBUFFERS_NOEXCEPT
#endif
// NOTE: the FLATBUFFERS_DELETE_FUNC macro may change the access mode to
// private, so be sure to put it at the end or reset access mode explicitly.
#if (!defined(_MSC_VER) || _MSC_FULL_VER >= 180020827) && \
(!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 404)) || \
defined(__clang__)
#define FLATBUFFERS_DELETE_FUNC(func) func = delete
#else
#define FLATBUFFERS_DELETE_FUNC(func) private: func
#endif
#if (!defined(_MSC_VER) || _MSC_VER >= 1900) && \
(!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 409)) || \
defined(__clang__)
#define FLATBUFFERS_DEFAULT_DECLARATION
#endif
// Check if we can use template aliases
// Not possible if Microsoft Compiler before 2012
// Possible is the language feature __cpp_alias_templates is defined well
// Or possible if the C++ std is C+11 or newer
#if (defined(_MSC_VER) && _MSC_VER > 1700 /* MSVC2012 */) \
|| (defined(__cpp_alias_templates) && __cpp_alias_templates >= 200704) \
|| (defined(__cplusplus) && __cplusplus >= 201103L)
#define FLATBUFFERS_TEMPLATES_ALIASES
#endif
#ifndef FLATBUFFERS_HAS_STRING_VIEW
// Only provide flatbuffers::string_view if __has_include can be used
// to detect a header that provides an implementation
#if defined(__has_include)
// Check for std::string_view (in c++17)
#if __has_include(<string_view>) && (__cplusplus >= 201606 || (defined(_HAS_CXX17) && _HAS_CXX17))
#include <string_view>
namespace flatbuffers {
typedef std::string_view string_view;
}
#define FLATBUFFERS_HAS_STRING_VIEW 1
// Check for std::experimental::string_view (in c++14, compiler-dependent)
#elif __has_include(<experimental/string_view>) && (__cplusplus >= 201411)
#include <experimental/string_view>
namespace flatbuffers {
typedef std::experimental::string_view string_view;
}
#define FLATBUFFERS_HAS_STRING_VIEW 1
// Check for absl::string_view
#elif __has_include("absl/strings/string_view.h") && \
__has_include("absl/base/config.h") && \
(__cplusplus >= 201411)
#include "absl/base/config.h"
#if !defined(ABSL_USES_STD_STRING_VIEW)
#include "absl/strings/string_view.h"
namespace flatbuffers {
typedef absl::string_view string_view;
}
#define FLATBUFFERS_HAS_STRING_VIEW 1
#endif
#endif
#endif // __has_include
#endif // !FLATBUFFERS_HAS_STRING_VIEW
#ifndef FLATBUFFERS_GENERAL_HEAP_ALLOC_OK
// Allow heap allocations to be used
#define FLATBUFFERS_GENERAL_HEAP_ALLOC_OK 1
#endif // !FLATBUFFERS_GENERAL_HEAP_ALLOC_OK
#ifndef FLATBUFFERS_HAS_NEW_STRTOD
// Modern (C++11) strtod and strtof functions are available for use.
// 1) nan/inf strings as argument of strtod;
// 2) hex-float as argument of strtod/strtof.
#if (defined(_MSC_VER) && _MSC_VER >= 1900) || \
(defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409)) || \
(defined(__clang__))
#define FLATBUFFERS_HAS_NEW_STRTOD 1
#endif
#endif // !FLATBUFFERS_HAS_NEW_STRTOD
#ifndef FLATBUFFERS_LOCALE_INDEPENDENT
// Enable locale independent functions {strtof_l, strtod_l,strtoll_l,
// strtoull_l}.
#if (defined(_MSC_VER) && _MSC_VER >= 1800) || \
(defined(__ANDROID_API__) && __ANDROID_API__>= 21) || \
(defined(_XOPEN_VERSION) && (_XOPEN_VERSION >= 700)) && \
(!defined(__Fuchsia__) && !defined(__ANDROID_API__))
#define FLATBUFFERS_LOCALE_INDEPENDENT 1
#else
#define FLATBUFFERS_LOCALE_INDEPENDENT 0
#endif
#endif // !FLATBUFFERS_LOCALE_INDEPENDENT
// Suppress Undefined Behavior Sanitizer (recoverable only). Usage:
// - __suppress_ubsan__("undefined")
// - __suppress_ubsan__("signed-integer-overflow")
#if defined(__clang__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >=7))
#define __suppress_ubsan__(type) __attribute__((no_sanitize(type)))
#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409)
#define __suppress_ubsan__(type) __attribute__((no_sanitize_undefined))
#else
#define __suppress_ubsan__(type)
#endif
// This is constexpr function used for checking compile-time constants.
// Avoid `#pragma warning(disable: 4127) // C4127: expression is constant`.
template<typename T> FLATBUFFERS_CONSTEXPR inline bool IsConstTrue(T t) {
return !!t;
}
// Enable C++ attribute [[]] if std:c++17 or higher.
#if ((__cplusplus >= 201703L) \
|| (defined(_MSVC_LANG) && (_MSVC_LANG >= 201703L)))
// All attributes unknown to an implementation are ignored without causing an error.
#define FLATBUFFERS_ATTRIBUTE(attr) attr
#define FLATBUFFERS_FALLTHROUGH() [[fallthrough]]
#else
#define FLATBUFFERS_ATTRIBUTE(attr)
#if FLATBUFFERS_CLANG >= 30800
#define FLATBUFFERS_FALLTHROUGH() [[clang::fallthrough]]
#elif FLATBUFFERS_GCC >= 70300
#define FLATBUFFERS_FALLTHROUGH() [[gnu::fallthrough]]
#else
#define FLATBUFFERS_FALLTHROUGH()
#endif
#endif
/// @endcond
/// @file
namespace flatbuffers {
/// @cond FLATBUFFERS_INTERNAL
// Our default offset / size type, 32bit on purpose on 64bit systems.
// Also, using a consistent offset type maintains compatibility of serialized
// offset values between 32bit and 64bit systems.
typedef uint32_t uoffset_t;
typedef uint64_t uoffset64_t;
// Signed offsets for references that can go in both directions.
typedef int32_t soffset_t;
typedef int64_t soffset64_t;
// Offset/index used in v-tables, can be changed to uint8_t in
// format forks to save a bit of space if desired.
typedef uint16_t voffset_t;
typedef uintmax_t largest_scalar_t;
// In 32bits, this evaluates to 2GB - 1
#define FLATBUFFERS_MAX_BUFFER_SIZE std::numeric_limits<::flatbuffers::soffset_t>::max()
#define FLATBUFFERS_MAX_64_BUFFER_SIZE std::numeric_limits<::flatbuffers::soffset64_t>::max()
// The minimum size buffer that can be a valid flatbuffer.
// Includes the offset to the root table (uoffset_t), the offset to the vtable
// of the root table (soffset_t), the size of the vtable (uint16_t), and the
// size of the referring table (uint16_t).
#define FLATBUFFERS_MIN_BUFFER_SIZE sizeof(uoffset_t) + sizeof(soffset_t) + \
sizeof(uint16_t) + sizeof(uint16_t)
// We support aligning the contents of buffers up to this size.
#ifndef FLATBUFFERS_MAX_ALIGNMENT
#define FLATBUFFERS_MAX_ALIGNMENT 32
#endif
/// @brief The length of a FlatBuffer file header.
static const size_t kFileIdentifierLength = 4;
inline bool VerifyAlignmentRequirements(size_t align, size_t min_align = 1) {
return (min_align <= align) && (align <= (FLATBUFFERS_MAX_ALIGNMENT)) &&
(align & (align - 1)) == 0; // must be power of 2
}
#if defined(_MSC_VER)
#pragma warning(disable: 4351) // C4351: new behavior: elements of array ... will be default initialized
#pragma warning(push)
#pragma warning(disable: 4127) // C4127: conditional expression is constant
#endif
template<typename T> T EndianSwap(T t) {
#if defined(_MSC_VER)
#define FLATBUFFERS_BYTESWAP16 _byteswap_ushort
#define FLATBUFFERS_BYTESWAP32 _byteswap_ulong
#define FLATBUFFERS_BYTESWAP64 _byteswap_uint64
#elif defined(__ICCARM__)
#define FLATBUFFERS_BYTESWAP16 __REV16
#define FLATBUFFERS_BYTESWAP32 __REV
#define FLATBUFFERS_BYTESWAP64(x) \
((__REV(static_cast<uint32_t>(x >> 32U))) | (static_cast<uint64_t>(__REV(static_cast<uint32_t>(x)))) << 32U)
#else
#if defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ < 408 && !defined(__clang__)
// __builtin_bswap16 was missing prior to GCC 4.8.
#define FLATBUFFERS_BYTESWAP16(x) \
static_cast<uint16_t>(__builtin_bswap32(static_cast<uint32_t>(x) << 16))
#else
#define FLATBUFFERS_BYTESWAP16 __builtin_bswap16
#endif
#define FLATBUFFERS_BYTESWAP32 __builtin_bswap32
#define FLATBUFFERS_BYTESWAP64 __builtin_bswap64
#endif
if (sizeof(T) == 1) { // Compile-time if-then's.
return t;
} else if (sizeof(T) == 2) {
union { T t; uint16_t i; } u = { t };
u.i = FLATBUFFERS_BYTESWAP16(u.i);
return u.t;
} else if (sizeof(T) == 4) {
union { T t; uint32_t i; } u = { t };
u.i = FLATBUFFERS_BYTESWAP32(u.i);
return u.t;
} else if (sizeof(T) == 8) {
union { T t; uint64_t i; } u = { t };
u.i = FLATBUFFERS_BYTESWAP64(u.i);
return u.t;
} else {
FLATBUFFERS_ASSERT(0);
return t;
}
}
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
template<typename T> T EndianScalar(T t) {
#if FLATBUFFERS_LITTLEENDIAN
return t;
#else
return EndianSwap(t);
#endif
}
template<typename T>
// UBSAN: C++ aliasing type rules, see std::bit_cast<> for details.
__suppress_ubsan__("alignment")
T ReadScalar(const void *p) {
return EndianScalar(*reinterpret_cast<const T *>(p));
}
// See https://github.com/google/flatbuffers/issues/5950
#if (FLATBUFFERS_GCC >= 100000) && (FLATBUFFERS_GCC < 110000)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstringop-overflow"
#endif
template<typename T>
// UBSAN: C++ aliasing type rules, see std::bit_cast<> for details.
__suppress_ubsan__("alignment")
void WriteScalar(void *p, T t) {
*reinterpret_cast<T *>(p) = EndianScalar(t);
}
template<typename T> struct Offset;
template<typename T> __suppress_ubsan__("alignment") void WriteScalar(void *p, Offset<T> t) {
*reinterpret_cast<uoffset_t *>(p) = EndianScalar(t.o);
}
#if (FLATBUFFERS_GCC >= 100000) && (FLATBUFFERS_GCC < 110000)
#pragma GCC diagnostic pop
#endif
// Computes how many bytes you'd have to pad to be able to write an
// "scalar_size" scalar if the buffer had grown to "buf_size" (downwards in
// memory).
__suppress_ubsan__("unsigned-integer-overflow")
inline size_t PaddingBytes(size_t buf_size, size_t scalar_size) {
return ((~buf_size) + 1) & (scalar_size - 1);
}
// Generic 'operator==' with conditional specialisations.
// T e - new value of a scalar field.
// T def - default of scalar (is known at compile-time).
template<typename T> inline bool IsTheSameAs(T e, T def) { return e == def; }
#if defined(FLATBUFFERS_NAN_DEFAULTS) && \
defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
// Like `operator==(e, def)` with weak NaN if T=(float|double).
template<typename T> inline bool IsFloatTheSameAs(T e, T def) {
return (e == def) || ((def != def) && (e != e));
}
template<> inline bool IsTheSameAs<float>(float e, float def) {
return IsFloatTheSameAs(e, def);
}
template<> inline bool IsTheSameAs<double>(double e, double def) {
return IsFloatTheSameAs(e, def);
}
#endif
// Check 'v' is out of closed range [low; high].
// Workaround for GCC warning [-Werror=type-limits]:
// comparison is always true due to limited range of data type.
template<typename T>
inline bool IsOutRange(const T &v, const T &low, const T &high) {
return (v < low) || (high < v);
}
// Check 'v' is in closed range [low; high].
template<typename T>
inline bool IsInRange(const T &v, const T &low, const T &high) {
return !IsOutRange(v, low, high);
}
} // namespace flatbuffers
#endif // FLATBUFFERS_BASE_H_
-199
View File
@@ -1,199 +0,0 @@
/*
* Copyright 2021 Google Inc. All rights reserved.
*
* 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.
*/
#ifndef FLATBUFFERS_BUFFER_H_
#define FLATBUFFERS_BUFFER_H_
#include <algorithm>
#include "flatbuffers/base.h"
namespace flatbuffers {
// Wrapper for uoffset_t to allow safe template specialization.
// Value is allowed to be 0 to indicate a null object (see e.g. AddOffset).
template<typename T = void> struct Offset {
// The type of offset to use.
typedef uoffset_t offset_type;
offset_type o;
Offset() : o(0) {}
Offset(const offset_type _o) : o(_o) {}
Offset<> Union() const { return o; }
bool IsNull() const { return !o; }
};
// Wrapper for uoffset64_t Offsets.
template<typename T = void> struct Offset64 {
// The type of offset to use.
typedef uoffset64_t offset_type;
offset_type o;
Offset64() : o(0) {}
Offset64(const offset_type offset) : o(offset) {}
Offset64<> Union() const { return o; }
bool IsNull() const { return !o; }
};
// Litmus check for ensuring the Offsets are the expected size.
static_assert(sizeof(Offset<>) == 4, "Offset has wrong size");
static_assert(sizeof(Offset64<>) == 8, "Offset64 has wrong size");
inline void EndianCheck() {
int endiantest = 1;
// If this fails, see FLATBUFFERS_LITTLEENDIAN above.
FLATBUFFERS_ASSERT(*reinterpret_cast<char *>(&endiantest) ==
FLATBUFFERS_LITTLEENDIAN);
(void)endiantest;
}
template<typename T> FLATBUFFERS_CONSTEXPR size_t AlignOf() {
// clang-format off
#ifdef _MSC_VER
return __alignof(T);
#else
#ifndef alignof
return __alignof__(T);
#else
return alignof(T);
#endif
#endif
// clang-format on
}
// Lexicographically compare two strings (possibly containing nulls), and
// return true if the first is less than the second.
static inline bool StringLessThan(const char *a_data, uoffset_t a_size,
const char *b_data, uoffset_t b_size) {
const auto cmp = memcmp(a_data, b_data, (std::min)(a_size, b_size));
return cmp == 0 ? a_size < b_size : cmp < 0;
}
// When we read serialized data from memory, in the case of most scalars,
// we want to just read T, but in the case of Offset, we want to actually
// perform the indirection and return a pointer.
// The template specialization below does just that.
// It is wrapped in a struct since function templates can't overload on the
// return type like this.
// The typedef is for the convenience of callers of this function
// (avoiding the need for a trailing return decltype)
template<typename T> struct IndirectHelper {
typedef T return_type;
typedef T mutable_return_type;
static const size_t element_stride = sizeof(T);
static return_type Read(const uint8_t *p, const size_t i) {
return EndianScalar((reinterpret_cast<const T *>(p))[i]);
}
static mutable_return_type Read(uint8_t *p, const size_t i) {
return reinterpret_cast<mutable_return_type>(
Read(const_cast<const uint8_t *>(p), i));
}
};
// For vector of Offsets.
template<typename T, template<typename> class OffsetT>
struct IndirectHelper<OffsetT<T>> {
typedef const T *return_type;
typedef T *mutable_return_type;
typedef typename OffsetT<T>::offset_type offset_type;
static const offset_type element_stride = sizeof(offset_type);
static return_type Read(const uint8_t *const p, const offset_type i) {
// Offsets are relative to themselves, so first update the pointer to
// point to the offset location.
const uint8_t *const offset_location = p + i * element_stride;
// Then read the scalar value of the offset (which may be 32 or 64-bits) and
// then determine the relative location from the offset location.
return reinterpret_cast<return_type>(
offset_location + ReadScalar<offset_type>(offset_location));
}
static mutable_return_type Read(uint8_t *const p, const offset_type i) {
// Offsets are relative to themselves, so first update the pointer to
// point to the offset location.
uint8_t *const offset_location = p + i * element_stride;
// Then read the scalar value of the offset (which may be 32 or 64-bits) and
// then determine the relative location from the offset location.
return reinterpret_cast<mutable_return_type>(
offset_location + ReadScalar<offset_type>(offset_location));
}
};
// For vector of structs.
template<typename T> struct IndirectHelper<const T *> {
typedef const T *return_type;
typedef T *mutable_return_type;
static const size_t element_stride = sizeof(T);
static return_type Read(const uint8_t *const p, const size_t i) {
// Structs are stored inline, relative to the first struct pointer.
return reinterpret_cast<return_type>(p + i * element_stride);
}
static mutable_return_type Read(uint8_t *const p, const size_t i) {
// Structs are stored inline, relative to the first struct pointer.
return reinterpret_cast<mutable_return_type>(p + i * element_stride);
}
};
/// @brief Get a pointer to the file_identifier section of the buffer.
/// @return Returns a const char pointer to the start of the file_identifier
/// characters in the buffer. The returned char * has length
/// 'flatbuffers::FlatBufferBuilder::kFileIdentifierLength'.
/// This function is UNDEFINED for FlatBuffers whose schema does not include
/// a file_identifier (likely points at padding or the start of a the root
/// vtable).
inline const char *GetBufferIdentifier(const void *buf,
bool size_prefixed = false) {
return reinterpret_cast<const char *>(buf) +
((size_prefixed) ? 2 * sizeof(uoffset_t) : sizeof(uoffset_t));
}
// Helper to see if the identifier in a buffer has the expected value.
inline bool BufferHasIdentifier(const void *buf, const char *identifier,
bool size_prefixed = false) {
return strncmp(GetBufferIdentifier(buf, size_prefixed), identifier,
flatbuffers::kFileIdentifierLength) == 0;
}
/// @cond FLATBUFFERS_INTERNAL
// Helpers to get a typed pointer to the root object contained in the buffer.
template<typename T> T *GetMutableRoot(void *buf) {
if (!buf) return nullptr;
EndianCheck();
return reinterpret_cast<T *>(
reinterpret_cast<uint8_t *>(buf) +
EndianScalar(*reinterpret_cast<uoffset_t *>(buf)));
}
template<typename T, typename SizeT = uoffset_t>
T *GetMutableSizePrefixedRoot(void *buf) {
return GetMutableRoot<T>(reinterpret_cast<uint8_t *>(buf) + sizeof(SizeT));
}
template<typename T> const T *GetRoot(const void *buf) {
return GetMutableRoot<T>(const_cast<void *>(buf));
}
template<typename T, typename SizeT = uoffset_t>
const T *GetSizePrefixedRoot(const void *buf) {
return GetRoot<T>(reinterpret_cast<const uint8_t *>(buf) + sizeof(SizeT));
}
} // namespace flatbuffers
#endif // FLATBUFFERS_BUFFER_H_
-53
View File
@@ -1,53 +0,0 @@
/*
* Copyright 2021 Google Inc. All rights reserved.
*
* 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.
*/
#ifndef FLATBUFFERS_BUFFER_REF_H_
#define FLATBUFFERS_BUFFER_REF_H_
#include "flatbuffers/base.h"
#include "flatbuffers/verifier.h"
namespace flatbuffers {
// Convenient way to bundle a buffer and its length, to pass it around
// typed by its root.
// A BufferRef does not own its buffer.
struct BufferRefBase {}; // for std::is_base_of
template<typename T> struct BufferRef : BufferRefBase {
BufferRef() : buf(nullptr), len(0), must_free(false) {}
BufferRef(uint8_t *_buf, uoffset_t _len)
: buf(_buf), len(_len), must_free(false) {}
~BufferRef() {
if (must_free) free(buf);
}
const T *GetRoot() const { return flatbuffers::GetRoot<T>(buf); }
bool Verify() {
Verifier verifier(buf, len);
return verifier.VerifyBuffer<T>(nullptr);
}
uint8_t *buf;
uoffset_t len;
bool must_free;
};
} // namespace flatbuffers
#endif // FLATBUFFERS_BUFFER_REF_H_
@@ -1,64 +0,0 @@
/*
* Copyright 2021 Google Inc. All rights reserved.
*
* 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.
*/
#ifndef FLATBUFFERS_DEFAULT_ALLOCATOR_H_
#define FLATBUFFERS_DEFAULT_ALLOCATOR_H_
#include "flatbuffers/allocator.h"
#include "flatbuffers/base.h"
namespace flatbuffers {
// DefaultAllocator uses new/delete to allocate memory regions
class DefaultAllocator : public Allocator {
public:
uint8_t *allocate(size_t size) FLATBUFFERS_OVERRIDE {
return new uint8_t[size];
}
void deallocate(uint8_t *p, size_t) FLATBUFFERS_OVERRIDE { delete[] p; }
static void dealloc(void *p, size_t) { delete[] static_cast<uint8_t *>(p); }
};
// These functions allow for a null allocator to mean use the default allocator,
// as used by DetachedBuffer and vector_downward below.
// This is to avoid having a statically or dynamically allocated default
// allocator, or having to move it between the classes that may own it.
inline uint8_t *Allocate(Allocator *allocator, size_t size) {
return allocator ? allocator->allocate(size)
: DefaultAllocator().allocate(size);
}
inline void Deallocate(Allocator *allocator, uint8_t *p, size_t size) {
if (allocator)
allocator->deallocate(p, size);
else
DefaultAllocator().deallocate(p, size);
}
inline uint8_t *ReallocateDownward(Allocator *allocator, uint8_t *old_p,
size_t old_size, size_t new_size,
size_t in_use_back, size_t in_use_front) {
return allocator ? allocator->reallocate_downward(old_p, old_size, new_size,
in_use_back, in_use_front)
: DefaultAllocator().reallocate_downward(
old_p, old_size, new_size, in_use_back, in_use_front);
}
} // namespace flatbuffers
#endif // FLATBUFFERS_DEFAULT_ALLOCATOR_H_
@@ -1,114 +0,0 @@
/*
* Copyright 2021 Google Inc. All rights reserved.
*
* 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.
*/
#ifndef FLATBUFFERS_DETACHED_BUFFER_H_
#define FLATBUFFERS_DETACHED_BUFFER_H_
#include "flatbuffers/allocator.h"
#include "flatbuffers/base.h"
#include "flatbuffers/default_allocator.h"
namespace flatbuffers {
// DetachedBuffer is a finished flatbuffer memory region, detached from its
// builder. The original memory region and allocator are also stored so that
// the DetachedBuffer can manage the memory lifetime.
class DetachedBuffer {
public:
DetachedBuffer()
: allocator_(nullptr),
own_allocator_(false),
buf_(nullptr),
reserved_(0),
cur_(nullptr),
size_(0) {}
DetachedBuffer(Allocator *allocator, bool own_allocator, uint8_t *buf,
size_t reserved, uint8_t *cur, size_t sz)
: allocator_(allocator),
own_allocator_(own_allocator),
buf_(buf),
reserved_(reserved),
cur_(cur),
size_(sz) {}
DetachedBuffer(DetachedBuffer &&other) noexcept
: allocator_(other.allocator_),
own_allocator_(other.own_allocator_),
buf_(other.buf_),
reserved_(other.reserved_),
cur_(other.cur_),
size_(other.size_) {
other.reset();
}
DetachedBuffer &operator=(DetachedBuffer &&other) noexcept {
if (this == &other) return *this;
destroy();
allocator_ = other.allocator_;
own_allocator_ = other.own_allocator_;
buf_ = other.buf_;
reserved_ = other.reserved_;
cur_ = other.cur_;
size_ = other.size_;
other.reset();
return *this;
}
~DetachedBuffer() { destroy(); }
const uint8_t *data() const { return cur_; }
uint8_t *data() { return cur_; }
size_t size() const { return size_; }
// These may change access mode, leave these at end of public section
FLATBUFFERS_DELETE_FUNC(DetachedBuffer(const DetachedBuffer &other));
FLATBUFFERS_DELETE_FUNC(
DetachedBuffer &operator=(const DetachedBuffer &other));
protected:
Allocator *allocator_;
bool own_allocator_;
uint8_t *buf_;
size_t reserved_;
uint8_t *cur_;
size_t size_;
inline void destroy() {
if (buf_) Deallocate(allocator_, buf_, reserved_);
if (own_allocator_ && allocator_) { delete allocator_; }
reset();
}
inline void reset() {
allocator_ = nullptr;
own_allocator_ = false;
buf_ = nullptr;
reserved_ = 0;
cur_ = nullptr;
size_ = 0;
}
};
} // namespace flatbuffers
#endif // FLATBUFFERS_DETACHED_BUFFER_H_
File diff suppressed because it is too large Load Diff
-273
View File
@@ -1,273 +0,0 @@
/*
* Copyright 2014 Google Inc. All rights reserved.
*
* 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.
*/
#ifndef FLATBUFFERS_H_
#define FLATBUFFERS_H_
#include <algorithm>
// TODO: These includes are for mitigating the pains of users editing their
// source because they relied on flatbuffers.h to include everything for them.
#include "flatbuffers/array.h"
#include "flatbuffers/base.h"
#include "flatbuffers/buffer.h"
#include "flatbuffers/buffer_ref.h"
#include "flatbuffers/detached_buffer.h"
#include "flatbuffers/flatbuffer_builder.h"
#include "flatbuffers/stl_emulation.h"
#include "flatbuffers/string.h"
#include "flatbuffers/struct.h"
#include "flatbuffers/table.h"
#include "flatbuffers/vector.h"
#include "flatbuffers/vector_downward.h"
#include "flatbuffers/verifier.h"
namespace flatbuffers {
/// @brief This can compute the start of a FlatBuffer from a root pointer, i.e.
/// it is the opposite transformation of GetRoot().
/// This may be useful if you want to pass on a root and have the recipient
/// delete the buffer afterwards.
inline const uint8_t *GetBufferStartFromRootPointer(const void *root) {
auto table = reinterpret_cast<const Table *>(root);
auto vtable = table->GetVTable();
// Either the vtable is before the root or after the root.
auto start = (std::min)(vtable, reinterpret_cast<const uint8_t *>(root));
// Align to at least sizeof(uoffset_t).
start = reinterpret_cast<const uint8_t *>(reinterpret_cast<uintptr_t>(start) &
~(sizeof(uoffset_t) - 1));
// Additionally, there may be a file_identifier in the buffer, and the root
// offset. The buffer may have been aligned to any size between
// sizeof(uoffset_t) and FLATBUFFERS_MAX_ALIGNMENT (see "force_align").
// Sadly, the exact alignment is only known when constructing the buffer,
// since it depends on the presence of values with said alignment properties.
// So instead, we simply look at the next uoffset_t values (root,
// file_identifier, and alignment padding) to see which points to the root.
// None of the other values can "impersonate" the root since they will either
// be 0 or four ASCII characters.
static_assert(flatbuffers::kFileIdentifierLength == sizeof(uoffset_t),
"file_identifier is assumed to be the same size as uoffset_t");
for (auto possible_roots = FLATBUFFERS_MAX_ALIGNMENT / sizeof(uoffset_t) + 1;
possible_roots; possible_roots--) {
start -= sizeof(uoffset_t);
if (ReadScalar<uoffset_t>(start) + start ==
reinterpret_cast<const uint8_t *>(root))
return start;
}
// We didn't find the root, either the "root" passed isn't really a root,
// or the buffer is corrupt.
// Assert, because calling this function with bad data may cause reads
// outside of buffer boundaries.
FLATBUFFERS_ASSERT(false);
return nullptr;
}
/// @brief This return the prefixed size of a FlatBuffer.
template<typename SizeT = uoffset_t>
inline SizeT GetPrefixedSize(const uint8_t *buf) {
return ReadScalar<SizeT>(buf);
}
// Base class for native objects (FlatBuffer data de-serialized into native
// C++ data structures).
// Contains no functionality, purely documentative.
struct NativeTable {};
/// @brief Function types to be used with resolving hashes into objects and
/// back again. The resolver gets a pointer to a field inside an object API
/// object that is of the type specified in the schema using the attribute
/// `cpp_type` (it is thus important whatever you write to this address
/// matches that type). The value of this field is initially null, so you
/// may choose to implement a delayed binding lookup using this function
/// if you wish. The resolver does the opposite lookup, for when the object
/// is being serialized again.
typedef uint64_t hash_value_t;
typedef std::function<void(void **pointer_adr, hash_value_t hash)>
resolver_function_t;
typedef std::function<hash_value_t(void *pointer)> rehasher_function_t;
// Helper function to test if a field is present, using any of the field
// enums in the generated code.
// `table` must be a generated table type. Since this is a template parameter,
// this is not typechecked to be a subclass of Table, so beware!
// Note: this function will return false for fields equal to the default
// value, since they're not stored in the buffer (unless force_defaults was
// used).
template<typename T>
bool IsFieldPresent(const T *table, typename T::FlatBuffersVTableOffset field) {
// Cast, since Table is a private baseclass of any table types.
return reinterpret_cast<const Table *>(table)->CheckField(
static_cast<voffset_t>(field));
}
// Utility function for reverse lookups on the EnumNames*() functions
// (in the generated C++ code)
// names must be NULL terminated.
inline int LookupEnum(const char **names, const char *name) {
for (const char **p = names; *p; p++)
if (!strcmp(*p, name)) return static_cast<int>(p - names);
return -1;
}
// These macros allow us to layout a struct with a guarantee that they'll end
// up looking the same on different compilers and platforms.
// It does this by disallowing the compiler to do any padding, and then
// does padding itself by inserting extra padding fields that make every
// element aligned to its own size.
// Additionally, it manually sets the alignment of the struct as a whole,
// which is typically its largest element, or a custom size set in the schema
// by the force_align attribute.
// These are used in the generated code only.
// clang-format off
#if defined(_MSC_VER)
#define FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(alignment) \
__pragma(pack(1)) \
struct __declspec(align(alignment))
#define FLATBUFFERS_STRUCT_END(name, size) \
__pragma(pack()) \
static_assert(sizeof(name) == size, "compiler breaks packing rules")
#elif defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__)
#define FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(alignment) \
_Pragma("pack(1)") \
struct __attribute__((aligned(alignment)))
#define FLATBUFFERS_STRUCT_END(name, size) \
_Pragma("pack()") \
static_assert(sizeof(name) == size, "compiler breaks packing rules")
#else
#error Unknown compiler, please define structure alignment macros
#endif
// clang-format on
// Minimal reflection via code generation.
// Besides full-fat reflection (see reflection.h) and parsing/printing by
// loading schemas (see idl.h), we can also have code generation for minimal
// reflection data which allows pretty-printing and other uses without needing
// a schema or a parser.
// Generate code with --reflect-types (types only) or --reflect-names (names
// also) to enable.
// See minireflect.h for utilities using this functionality.
// These types are organized slightly differently as the ones in idl.h.
enum SequenceType { ST_TABLE, ST_STRUCT, ST_UNION, ST_ENUM };
// Scalars have the same order as in idl.h
// clang-format off
#define FLATBUFFERS_GEN_ELEMENTARY_TYPES(ET) \
ET(ET_UTYPE) \
ET(ET_BOOL) \
ET(ET_CHAR) \
ET(ET_UCHAR) \
ET(ET_SHORT) \
ET(ET_USHORT) \
ET(ET_INT) \
ET(ET_UINT) \
ET(ET_LONG) \
ET(ET_ULONG) \
ET(ET_FLOAT) \
ET(ET_DOUBLE) \
ET(ET_STRING) \
ET(ET_SEQUENCE) // See SequenceType.
enum ElementaryType {
#define FLATBUFFERS_ET(E) E,
FLATBUFFERS_GEN_ELEMENTARY_TYPES(FLATBUFFERS_ET)
#undef FLATBUFFERS_ET
};
inline const char * const *ElementaryTypeNames() {
static const char * const names[] = {
#define FLATBUFFERS_ET(E) #E,
FLATBUFFERS_GEN_ELEMENTARY_TYPES(FLATBUFFERS_ET)
#undef FLATBUFFERS_ET
};
return names;
}
// clang-format on
// Basic type info cost just 16bits per field!
// We're explicitly defining the signedness since the signedness of integer
// bitfields is otherwise implementation-defined and causes warnings on older
// GCC compilers.
struct TypeCode {
// ElementaryType
unsigned short base_type : 4;
// Either vector (in table) or array (in struct)
unsigned short is_repeating : 1;
// Index into type_refs below, or -1 for none.
signed short sequence_ref : 11;
};
static_assert(sizeof(TypeCode) == 2, "TypeCode");
struct TypeTable;
// Signature of the static method present in each type.
typedef const TypeTable *(*TypeFunction)();
struct TypeTable {
SequenceType st;
size_t num_elems; // of type_codes, values, names (but not type_refs).
const TypeCode *type_codes; // num_elems count
const TypeFunction *type_refs; // less than num_elems entries (see TypeCode).
const int16_t *array_sizes; // less than num_elems entries (see TypeCode).
const int64_t *values; // Only set for non-consecutive enum/union or structs.
const char *const *names; // Only set if compiled with --reflect-names.
};
// String which identifies the current version of FlatBuffers.
inline const char *flatbuffers_version_string() {
return "FlatBuffers " FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MAJOR) "."
FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MINOR) "."
FLATBUFFERS_STRING(FLATBUFFERS_VERSION_REVISION);
}
// clang-format off
#define FLATBUFFERS_DEFINE_BITMASK_OPERATORS(E, T)\
inline E operator | (E lhs, E rhs){\
return E(T(lhs) | T(rhs));\
}\
inline E operator & (E lhs, E rhs){\
return E(T(lhs) & T(rhs));\
}\
inline E operator ^ (E lhs, E rhs){\
return E(T(lhs) ^ T(rhs));\
}\
inline E operator ~ (E lhs){\
return E(~T(lhs));\
}\
inline E operator |= (E &lhs, E rhs){\
lhs = lhs | rhs;\
return lhs;\
}\
inline E operator &= (E &lhs, E rhs){\
lhs = lhs & rhs;\
return lhs;\
}\
inline E operator ^= (E &lhs, E rhs){\
lhs = lhs ^ rhs;\
return lhs;\
}\
inline bool operator !(E rhs) \
{\
return !bool(T(rhs)); \
}
/// @endcond
} // namespace flatbuffers
// clang-format on
#endif // FLATBUFFERS_H_
-513
View File
@@ -1,513 +0,0 @@
/*
* Copyright 2017 Google Inc. All rights reserved.
*
* 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.
*/
#ifndef FLATBUFFERS_STL_EMULATION_H_
#define FLATBUFFERS_STL_EMULATION_H_
// clang-format off
#include "flatbuffers/base.h"
#include <string>
#include <type_traits>
#include <vector>
#include <memory>
#include <limits>
#ifndef FLATBUFFERS_USE_STD_OPTIONAL
// Detect C++17 compatible compiler.
// __cplusplus >= 201703L - a compiler has support of 'static inline' variables.
#if (defined(__cplusplus) && __cplusplus >= 201703L) \
|| (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
#define FLATBUFFERS_USE_STD_OPTIONAL 1
#else
#define FLATBUFFERS_USE_STD_OPTIONAL 0
#endif // (defined(__cplusplus) && __cplusplus >= 201703L) ...
#endif // FLATBUFFERS_USE_STD_OPTIONAL
#if FLATBUFFERS_USE_STD_OPTIONAL
#include <optional>
#endif
#ifndef FLATBUFFERS_USE_STD_SPAN
// Testing __cpp_lib_span requires including either <version> or <span>,
// both of which were added in C++20.
// See: https://en.cppreference.com/w/cpp/utility/feature_test
#if defined(__cplusplus) && __cplusplus >= 202002L
#define FLATBUFFERS_USE_STD_SPAN 1
#endif
#endif // FLATBUFFERS_USE_STD_SPAN
#if defined(FLATBUFFERS_USE_STD_SPAN)
#include <array>
#include <span>
#else
// Disable non-trivial ctors if FLATBUFFERS_SPAN_MINIMAL defined.
#if !defined(FLATBUFFERS_TEMPLATES_ALIASES)
#define FLATBUFFERS_SPAN_MINIMAL
#else
// Enable implicit construction of a span<T,N> from a std::array<T,N>.
#include <array>
#endif
#endif // defined(FLATBUFFERS_USE_STD_SPAN)
// This header provides backwards compatibility for older versions of the STL.
namespace flatbuffers {
#if defined(FLATBUFFERS_TEMPLATES_ALIASES)
template <typename T>
using numeric_limits = std::numeric_limits<T>;
#else
template <typename T> class numeric_limits :
public std::numeric_limits<T> {};
#endif // defined(FLATBUFFERS_TEMPLATES_ALIASES)
#if defined(FLATBUFFERS_TEMPLATES_ALIASES)
template <typename T> using is_scalar = std::is_scalar<T>;
template <typename T, typename U> using is_same = std::is_same<T,U>;
template <typename T> using is_floating_point = std::is_floating_point<T>;
template <typename T> using is_unsigned = std::is_unsigned<T>;
template <typename T> using is_enum = std::is_enum<T>;
template <typename T> using make_unsigned = std::make_unsigned<T>;
template<bool B, class T, class F>
using conditional = std::conditional<B, T, F>;
template<class T, T v>
using integral_constant = std::integral_constant<T, v>;
template <bool B>
using bool_constant = integral_constant<bool, B>;
using true_type = std::true_type;
using false_type = std::false_type;
#else
// MSVC 2010 doesn't support C++11 aliases.
template <typename T> struct is_scalar : public std::is_scalar<T> {};
template <typename T, typename U> struct is_same : public std::is_same<T,U> {};
template <typename T> struct is_floating_point :
public std::is_floating_point<T> {};
template <typename T> struct is_unsigned : public std::is_unsigned<T> {};
template <typename T> struct is_enum : public std::is_enum<T> {};
template <typename T> struct make_unsigned : public std::make_unsigned<T> {};
template<bool B, class T, class F>
struct conditional : public std::conditional<B, T, F> {};
template<class T, T v>
struct integral_constant : public std::integral_constant<T, v> {};
template <bool B>
struct bool_constant : public integral_constant<bool, B> {};
typedef bool_constant<true> true_type;
typedef bool_constant<false> false_type;
#endif // defined(FLATBUFFERS_TEMPLATES_ALIASES)
#if defined(FLATBUFFERS_TEMPLATES_ALIASES)
template <class T> using unique_ptr = std::unique_ptr<T>;
#else
// MSVC 2010 doesn't support C++11 aliases.
// We're manually "aliasing" the class here as we want to bring unique_ptr
// into the flatbuffers namespace. We have unique_ptr in the flatbuffers
// namespace we have a completely independent implementation (see below)
// for C++98 STL implementations.
template <class T> class unique_ptr : public std::unique_ptr<T> {
public:
unique_ptr() {}
explicit unique_ptr(T* p) : std::unique_ptr<T>(p) {}
unique_ptr(std::unique_ptr<T>&& u) { *this = std::move(u); }
unique_ptr(unique_ptr&& u) { *this = std::move(u); }
unique_ptr& operator=(std::unique_ptr<T>&& u) {
std::unique_ptr<T>::reset(u.release());
return *this;
}
unique_ptr& operator=(unique_ptr&& u) {
std::unique_ptr<T>::reset(u.release());
return *this;
}
unique_ptr& operator=(T* p) {
return std::unique_ptr<T>::operator=(p);
}
};
#endif // defined(FLATBUFFERS_TEMPLATES_ALIASES)
#if FLATBUFFERS_USE_STD_OPTIONAL
template<class T>
using Optional = std::optional<T>;
using nullopt_t = std::nullopt_t;
inline constexpr nullopt_t nullopt = std::nullopt;
#else
// Limited implementation of Optional<T> type for a scalar T.
// This implementation limited by trivial types compatible with
// std::is_arithmetic<T> or std::is_enum<T> type traits.
// A tag to indicate an empty flatbuffers::optional<T>.
struct nullopt_t {
explicit FLATBUFFERS_CONSTEXPR_CPP11 nullopt_t(int) {}
};
#if defined(FLATBUFFERS_CONSTEXPR_DEFINED)
namespace internal {
template <class> struct nullopt_holder {
static constexpr nullopt_t instance_ = nullopt_t(0);
};
template<class Dummy>
constexpr nullopt_t nullopt_holder<Dummy>::instance_;
}
static constexpr const nullopt_t &nullopt = internal::nullopt_holder<void>::instance_;
#else
namespace internal {
template <class> struct nullopt_holder {
static const nullopt_t instance_;
};
template<class Dummy>
const nullopt_t nullopt_holder<Dummy>::instance_ = nullopt_t(0);
}
static const nullopt_t &nullopt = internal::nullopt_holder<void>::instance_;
#endif
template<class T>
class Optional FLATBUFFERS_FINAL_CLASS {
// Non-scalar 'T' would extremely complicated Optional<T>.
// Use is_scalar<T> checking because flatbuffers flatbuffers::is_arithmetic<T>
// isn't implemented.
static_assert(flatbuffers::is_scalar<T>::value, "unexpected type T");
public:
~Optional() {}
FLATBUFFERS_CONSTEXPR_CPP11 Optional() FLATBUFFERS_NOEXCEPT
: value_(), has_value_(false) {}
FLATBUFFERS_CONSTEXPR_CPP11 Optional(nullopt_t) FLATBUFFERS_NOEXCEPT
: value_(), has_value_(false) {}
FLATBUFFERS_CONSTEXPR_CPP11 Optional(T val) FLATBUFFERS_NOEXCEPT
: value_(val), has_value_(true) {}
FLATBUFFERS_CONSTEXPR_CPP11 Optional(const Optional &other) FLATBUFFERS_NOEXCEPT
: value_(other.value_), has_value_(other.has_value_) {}
FLATBUFFERS_CONSTEXPR_CPP14 Optional &operator=(const Optional &other) FLATBUFFERS_NOEXCEPT {
value_ = other.value_;
has_value_ = other.has_value_;
return *this;
}
FLATBUFFERS_CONSTEXPR_CPP14 Optional &operator=(nullopt_t) FLATBUFFERS_NOEXCEPT {
value_ = T();
has_value_ = false;
return *this;
}
FLATBUFFERS_CONSTEXPR_CPP14 Optional &operator=(T val) FLATBUFFERS_NOEXCEPT {
value_ = val;
has_value_ = true;
return *this;
}
void reset() FLATBUFFERS_NOEXCEPT {
*this = nullopt;
}
void swap(Optional &other) FLATBUFFERS_NOEXCEPT {
std::swap(value_, other.value_);
std::swap(has_value_, other.has_value_);
}
FLATBUFFERS_CONSTEXPR_CPP11 FLATBUFFERS_EXPLICIT_CPP11 operator bool() const FLATBUFFERS_NOEXCEPT {
return has_value_;
}
FLATBUFFERS_CONSTEXPR_CPP11 bool has_value() const FLATBUFFERS_NOEXCEPT {
return has_value_;
}
FLATBUFFERS_CONSTEXPR_CPP11 const T& operator*() const FLATBUFFERS_NOEXCEPT {
return value_;
}
const T& value() const {
FLATBUFFERS_ASSERT(has_value());
return value_;
}
T value_or(T default_value) const FLATBUFFERS_NOEXCEPT {
return has_value() ? value_ : default_value;
}
private:
T value_;
bool has_value_;
};
template<class T>
FLATBUFFERS_CONSTEXPR_CPP11 bool operator==(const Optional<T>& opt, nullopt_t) FLATBUFFERS_NOEXCEPT {
return !opt;
}
template<class T>
FLATBUFFERS_CONSTEXPR_CPP11 bool operator==(nullopt_t, const Optional<T>& opt) FLATBUFFERS_NOEXCEPT {
return !opt;
}
template<class T, class U>
FLATBUFFERS_CONSTEXPR_CPP11 bool operator==(const Optional<T>& lhs, const U& rhs) FLATBUFFERS_NOEXCEPT {
return static_cast<bool>(lhs) && (*lhs == rhs);
}
template<class T, class U>
FLATBUFFERS_CONSTEXPR_CPP11 bool operator==(const T& lhs, const Optional<U>& rhs) FLATBUFFERS_NOEXCEPT {
return static_cast<bool>(rhs) && (lhs == *rhs);
}
template<class T, class U>
FLATBUFFERS_CONSTEXPR_CPP11 bool operator==(const Optional<T>& lhs, const Optional<U>& rhs) FLATBUFFERS_NOEXCEPT {
return static_cast<bool>(lhs) != static_cast<bool>(rhs)
? false
: !static_cast<bool>(lhs) ? false : (*lhs == *rhs);
}
#endif // FLATBUFFERS_USE_STD_OPTIONAL
// Very limited and naive partial implementation of C++20 std::span<T,Extent>.
#if defined(FLATBUFFERS_USE_STD_SPAN)
inline constexpr std::size_t dynamic_extent = std::dynamic_extent;
template<class T, std::size_t Extent = std::dynamic_extent>
using span = std::span<T, Extent>;
#else // !defined(FLATBUFFERS_USE_STD_SPAN)
FLATBUFFERS_CONSTEXPR std::size_t dynamic_extent = static_cast<std::size_t>(-1);
// Exclude this code if MSVC2010 or non-STL Android is active.
// The non-STL Android doesn't have `std::is_convertible` required for SFINAE.
#if !defined(FLATBUFFERS_SPAN_MINIMAL)
namespace internal {
// This is SFINAE helper class for checking of a common condition:
// > This overload only participates in overload resolution
// > Check whether a pointer to an array of From can be converted
// > to a pointer to an array of To.
// This helper is used for checking of 'From -> const From'.
template<class To, std::size_t Extent, class From, std::size_t N>
struct is_span_convertible {
using type =
typename std::conditional<std::is_convertible<From (*)[], To (*)[]>::value
&& (Extent == dynamic_extent || N == Extent),
int, void>::type;
};
template<typename T>
struct SpanIterator {
// TODO: upgrade to std::random_access_iterator_tag.
using iterator_category = std::forward_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = typename std::remove_cv<T>::type;
using reference = T&;
using pointer = T*;
// Convince MSVC compiler that this iterator is trusted (it is verified).
#ifdef _MSC_VER
using _Unchecked_type = pointer;
#endif // _MSC_VER
SpanIterator(pointer ptr) : ptr_(ptr) {}
reference operator*() const { return *ptr_; }
pointer operator->() { return ptr_; }
SpanIterator& operator++() { ptr_++; return *this; }
SpanIterator operator++(int) { auto tmp = *this; ++(*this); return tmp; }
friend bool operator== (const SpanIterator& lhs, const SpanIterator& rhs) { return lhs.ptr_ == rhs.ptr_; }
friend bool operator!= (const SpanIterator& lhs, const SpanIterator& rhs) { return lhs.ptr_ != rhs.ptr_; }
private:
pointer ptr_;
};
} // namespace internal
#endif // !defined(FLATBUFFERS_SPAN_MINIMAL)
// T - element type; must be a complete type that is not an abstract
// class type.
// Extent - the number of elements in the sequence, or dynamic.
template<class T, std::size_t Extent = dynamic_extent>
class span FLATBUFFERS_FINAL_CLASS {
public:
typedef T element_type;
typedef T& reference;
typedef const T& const_reference;
typedef T* pointer;
typedef const T* const_pointer;
typedef std::size_t size_type;
static FLATBUFFERS_CONSTEXPR size_type extent = Extent;
// Returns the number of elements in the span.
FLATBUFFERS_CONSTEXPR_CPP11 size_type size() const FLATBUFFERS_NOEXCEPT {
return count_;
}
// Returns the size of the sequence in bytes.
FLATBUFFERS_CONSTEXPR_CPP11
size_type size_bytes() const FLATBUFFERS_NOEXCEPT {
return size() * sizeof(element_type);
}
// Checks if the span is empty.
FLATBUFFERS_CONSTEXPR_CPP11 bool empty() const FLATBUFFERS_NOEXCEPT {
return size() == 0;
}
// Returns a pointer to the beginning of the sequence.
FLATBUFFERS_CONSTEXPR_CPP11 pointer data() const FLATBUFFERS_NOEXCEPT {
return data_;
}
#if !defined(FLATBUFFERS_SPAN_MINIMAL)
using Iterator = internal::SpanIterator<T>;
Iterator begin() const { return Iterator(data()); }
Iterator end() const { return Iterator(data() + size()); }
#endif
// Returns a reference to the idx-th element of the sequence.
// The behavior is undefined if the idx is greater than or equal to size().
FLATBUFFERS_CONSTEXPR_CPP11 reference operator[](size_type idx) const {
return data()[idx];
}
FLATBUFFERS_CONSTEXPR_CPP11 span(const span &other) FLATBUFFERS_NOEXCEPT
: data_(other.data_), count_(other.count_) {}
FLATBUFFERS_CONSTEXPR_CPP14 span &operator=(const span &other)
FLATBUFFERS_NOEXCEPT {
data_ = other.data_;
count_ = other.count_;
}
// Limited implementation of
// `template <class It> constexpr std::span(It first, size_type count);`.
//
// Constructs a span that is a view over the range [first, first + count);
// the resulting span has: data() == first and size() == count.
// The behavior is undefined if [first, first + count) is not a valid range,
// or if (extent != flatbuffers::dynamic_extent && count != extent).
FLATBUFFERS_CONSTEXPR_CPP11
explicit span(pointer first, size_type count) FLATBUFFERS_NOEXCEPT
: data_ (Extent == dynamic_extent ? first : (Extent == count ? first : nullptr)),
count_(Extent == dynamic_extent ? count : (Extent == count ? Extent : 0)) {
// Make span empty if the count argument is incompatible with span<T,N>.
}
// Exclude this code if MSVC2010 is active. The MSVC2010 isn't C++11
// compliant, it doesn't support default template arguments for functions.
#if defined(FLATBUFFERS_SPAN_MINIMAL)
FLATBUFFERS_CONSTEXPR_CPP11 span() FLATBUFFERS_NOEXCEPT : data_(nullptr),
count_(0) {
static_assert(extent == 0 || extent == dynamic_extent, "invalid span");
}
#else
// Constructs an empty span whose data() == nullptr and size() == 0.
// This overload only participates in overload resolution if
// extent == 0 || extent == flatbuffers::dynamic_extent.
// A dummy template argument N is need dependency for SFINAE.
template<std::size_t N = 0,
typename internal::is_span_convertible<element_type, Extent, element_type, (N - N)>::type = 0>
FLATBUFFERS_CONSTEXPR_CPP11 span() FLATBUFFERS_NOEXCEPT : data_(nullptr),
count_(0) {
static_assert(extent == 0 || extent == dynamic_extent, "invalid span");
}
// Constructs a span that is a view over the array arr; the resulting span
// has size() == N and data() == std::data(arr). These overloads only
// participate in overload resolution if
// extent == std::dynamic_extent || N == extent is true and
// std::remove_pointer_t<decltype(std::data(arr))>(*)[]
// is convertible to element_type (*)[].
template<std::size_t N,
typename internal::is_span_convertible<element_type, Extent, element_type, N>::type = 0>
FLATBUFFERS_CONSTEXPR_CPP11 span(element_type (&arr)[N]) FLATBUFFERS_NOEXCEPT
: data_(arr), count_(N) {}
template<class U, std::size_t N,
typename internal::is_span_convertible<element_type, Extent, U, N>::type = 0>
FLATBUFFERS_CONSTEXPR_CPP11 span(std::array<U, N> &arr) FLATBUFFERS_NOEXCEPT
: data_(arr.data()), count_(N) {}
//template<class U, std::size_t N,
// int = 0>
//FLATBUFFERS_CONSTEXPR_CPP11 span(std::array<U, N> &arr) FLATBUFFERS_NOEXCEPT
// : data_(arr.data()), count_(N) {}
template<class U, std::size_t N,
typename internal::is_span_convertible<element_type, Extent, U, N>::type = 0>
FLATBUFFERS_CONSTEXPR_CPP11 span(const std::array<U, N> &arr) FLATBUFFERS_NOEXCEPT
: data_(arr.data()), count_(N) {}
// Converting constructor from another span s;
// the resulting span has size() == s.size() and data() == s.data().
// This overload only participates in overload resolution
// if extent == std::dynamic_extent || N == extent is true and U (*)[]
// is convertible to element_type (*)[].
template<class U, std::size_t N,
typename internal::is_span_convertible<element_type, Extent, U, N>::type = 0>
FLATBUFFERS_CONSTEXPR_CPP11 span(const flatbuffers::span<U, N> &s) FLATBUFFERS_NOEXCEPT
: span(s.data(), s.size()) {
}
#endif // !defined(FLATBUFFERS_SPAN_MINIMAL)
private:
// This is a naive implementation with 'count_' member even if (Extent != dynamic_extent).
pointer const data_;
size_type count_;
};
#endif // defined(FLATBUFFERS_USE_STD_SPAN)
#if !defined(FLATBUFFERS_SPAN_MINIMAL)
template<class ElementType, std::size_t Extent>
FLATBUFFERS_CONSTEXPR_CPP11
flatbuffers::span<ElementType, Extent> make_span(ElementType(&arr)[Extent]) FLATBUFFERS_NOEXCEPT {
return span<ElementType, Extent>(arr);
}
template<class ElementType, std::size_t Extent>
FLATBUFFERS_CONSTEXPR_CPP11
flatbuffers::span<const ElementType, Extent> make_span(const ElementType(&arr)[Extent]) FLATBUFFERS_NOEXCEPT {
return span<const ElementType, Extent>(arr);
}
template<class ElementType, std::size_t Extent>
FLATBUFFERS_CONSTEXPR_CPP11
flatbuffers::span<ElementType, Extent> make_span(std::array<ElementType, Extent> &arr) FLATBUFFERS_NOEXCEPT {
return span<ElementType, Extent>(arr);
}
template<class ElementType, std::size_t Extent>
FLATBUFFERS_CONSTEXPR_CPP11
flatbuffers::span<const ElementType, Extent> make_span(const std::array<ElementType, Extent> &arr) FLATBUFFERS_NOEXCEPT {
return span<const ElementType, Extent>(arr);
}
template<class ElementType, std::size_t Extent>
FLATBUFFERS_CONSTEXPR_CPP11
flatbuffers::span<ElementType, dynamic_extent> make_span(ElementType *first, std::size_t count) FLATBUFFERS_NOEXCEPT {
return span<ElementType, dynamic_extent>(first, count);
}
template<class ElementType, std::size_t Extent>
FLATBUFFERS_CONSTEXPR_CPP11
flatbuffers::span<const ElementType, dynamic_extent> make_span(const ElementType *first, std::size_t count) FLATBUFFERS_NOEXCEPT {
return span<const ElementType, dynamic_extent>(first, count);
}
#endif // !defined(FLATBUFFERS_SPAN_MINIMAL)
} // namespace flatbuffers
#endif // FLATBUFFERS_STL_EMULATION_H_
-64
View File
@@ -1,64 +0,0 @@
/*
* Copyright 2021 Google Inc. All rights reserved.
*
* 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.
*/
#ifndef FLATBUFFERS_STRING_H_
#define FLATBUFFERS_STRING_H_
#include "flatbuffers/base.h"
#include "flatbuffers/vector.h"
namespace flatbuffers {
struct String : public Vector<char> {
const char *c_str() const { return reinterpret_cast<const char *>(Data()); }
std::string str() const { return std::string(c_str(), size()); }
// clang-format off
#ifdef FLATBUFFERS_HAS_STRING_VIEW
flatbuffers::string_view string_view() const {
return flatbuffers::string_view(c_str(), size());
}
#endif // FLATBUFFERS_HAS_STRING_VIEW
// clang-format on
bool operator<(const String &o) const {
return StringLessThan(this->data(), this->size(), o.data(), o.size());
}
};
// Convenience function to get std::string from a String returning an empty
// string on null pointer.
static inline std::string GetString(const String *str) {
return str ? str->str() : "";
}
// Convenience function to get char* from a String returning an empty string on
// null pointer.
static inline const char *GetCstring(const String *str) {
return str ? str->c_str() : "";
}
#ifdef FLATBUFFERS_HAS_STRING_VIEW
// Convenience function to get string_view from a String returning an empty
// string_view on null pointer.
static inline flatbuffers::string_view GetStringView(const String *str) {
return str ? str->string_view() : flatbuffers::string_view();
}
#endif // FLATBUFFERS_HAS_STRING_VIEW
} // namespace flatbuffers
#endif // FLATBUFFERS_STRING_H_
-53
View File
@@ -1,53 +0,0 @@
/*
* Copyright 2021 Google Inc. All rights reserved.
*
* 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.
*/
#ifndef FLATBUFFERS_STRUCT_H_
#define FLATBUFFERS_STRUCT_H_
#include "flatbuffers/base.h"
namespace flatbuffers {
// "structs" are flat structures that do not have an offset table, thus
// always have all members present and do not support forwards/backwards
// compatible extensions.
class Struct FLATBUFFERS_FINAL_CLASS {
public:
template<typename T> T GetField(uoffset_t o) const {
return ReadScalar<T>(&data_[o]);
}
template<typename T> T GetStruct(uoffset_t o) const {
return reinterpret_cast<T>(&data_[o]);
}
const uint8_t *GetAddressOf(uoffset_t o) const { return &data_[o]; }
uint8_t *GetAddressOf(uoffset_t o) { return &data_[o]; }
private:
// private constructor & copy constructor: you obtain instances of this
// class by pointing to existing data only
Struct();
Struct(const Struct &);
Struct &operator=(const Struct &);
uint8_t data_[1];
};
} // namespace flatbuffers
#endif // FLATBUFFERS_STRUCT_H_
-188
View File
@@ -1,188 +0,0 @@
/*
* Copyright 2021 Google Inc. All rights reserved.
*
* 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.
*/
#ifndef FLATBUFFERS_TABLE_H_
#define FLATBUFFERS_TABLE_H_
#include "flatbuffers/base.h"
#include "flatbuffers/verifier.h"
namespace flatbuffers {
// "tables" use an offset table (possibly shared) that allows fields to be
// omitted and added at will, but uses an extra indirection to read.
class Table {
public:
const uint8_t *GetVTable() const {
return data_ - ReadScalar<soffset_t>(data_);
}
// This gets the field offset for any of the functions below it, or 0
// if the field was not present.
voffset_t GetOptionalFieldOffset(voffset_t field) const {
// The vtable offset is always at the start.
auto vtable = GetVTable();
// The first element is the size of the vtable (fields + type id + itself).
auto vtsize = ReadScalar<voffset_t>(vtable);
// If the field we're accessing is outside the vtable, we're reading older
// data, so it's the same as if the offset was 0 (not present).
return field < vtsize ? ReadScalar<voffset_t>(vtable + field) : 0;
}
template<typename T> T GetField(voffset_t field, T defaultval) const {
auto field_offset = GetOptionalFieldOffset(field);
return field_offset ? ReadScalar<T>(data_ + field_offset) : defaultval;
}
template<typename P, typename OffsetSize = uoffset_t>
P GetPointer(voffset_t field) {
auto field_offset = GetOptionalFieldOffset(field);
auto p = data_ + field_offset;
return field_offset ? reinterpret_cast<P>(p + ReadScalar<OffsetSize>(p))
: nullptr;
}
template<typename P, typename OffsetSize = uoffset_t>
P GetPointer(voffset_t field) const {
return const_cast<Table *>(this)->GetPointer<P, OffsetSize>(field);
}
template<typename P> P GetPointer64(voffset_t field) {
return GetPointer<P, uoffset64_t>(field);
}
template<typename P> P GetPointer64(voffset_t field) const {
return GetPointer<P, uoffset64_t>(field);
}
template<typename P> P GetStruct(voffset_t field) const {
auto field_offset = GetOptionalFieldOffset(field);
auto p = const_cast<uint8_t *>(data_ + field_offset);
return field_offset ? reinterpret_cast<P>(p) : nullptr;
}
template<typename Raw, typename Face>
flatbuffers::Optional<Face> GetOptional(voffset_t field) const {
auto field_offset = GetOptionalFieldOffset(field);
auto p = data_ + field_offset;
return field_offset ? Optional<Face>(static_cast<Face>(ReadScalar<Raw>(p)))
: Optional<Face>();
}
template<typename T> bool SetField(voffset_t field, T val, T def) {
auto field_offset = GetOptionalFieldOffset(field);
if (!field_offset) return IsTheSameAs(val, def);
WriteScalar(data_ + field_offset, val);
return true;
}
template<typename T> bool SetField(voffset_t field, T val) {
auto field_offset = GetOptionalFieldOffset(field);
if (!field_offset) return false;
WriteScalar(data_ + field_offset, val);
return true;
}
bool SetPointer(voffset_t field, const uint8_t *val) {
auto field_offset = GetOptionalFieldOffset(field);
if (!field_offset) return false;
WriteScalar(data_ + field_offset,
static_cast<uoffset_t>(val - (data_ + field_offset)));
return true;
}
uint8_t *GetAddressOf(voffset_t field) {
auto field_offset = GetOptionalFieldOffset(field);
return field_offset ? data_ + field_offset : nullptr;
}
const uint8_t *GetAddressOf(voffset_t field) const {
return const_cast<Table *>(this)->GetAddressOf(field);
}
bool CheckField(voffset_t field) const {
return GetOptionalFieldOffset(field) != 0;
}
// Verify the vtable of this table.
// Call this once per table, followed by VerifyField once per field.
bool VerifyTableStart(Verifier &verifier) const {
return verifier.VerifyTableStart(data_);
}
// Verify a particular field.
template<typename T>
bool VerifyField(const Verifier &verifier, voffset_t field,
size_t align) const {
// Calling GetOptionalFieldOffset should be safe now thanks to
// VerifyTable().
auto field_offset = GetOptionalFieldOffset(field);
// Check the actual field.
return !field_offset || verifier.VerifyField<T>(data_, field_offset, align);
}
// VerifyField for required fields.
template<typename T>
bool VerifyFieldRequired(const Verifier &verifier, voffset_t field,
size_t align) const {
auto field_offset = GetOptionalFieldOffset(field);
return verifier.Check(field_offset != 0) &&
verifier.VerifyField<T>(data_, field_offset, align);
}
// Versions for offsets.
template<typename OffsetT = uoffset_t>
bool VerifyOffset(const Verifier &verifier, voffset_t field) const {
auto field_offset = GetOptionalFieldOffset(field);
return !field_offset || verifier.VerifyOffset<OffsetT>(data_, field_offset);
}
template<typename OffsetT = uoffset_t>
bool VerifyOffsetRequired(const Verifier &verifier, voffset_t field) const {
auto field_offset = GetOptionalFieldOffset(field);
return verifier.Check(field_offset != 0) &&
verifier.VerifyOffset<OffsetT>(data_, field_offset);
}
bool VerifyOffset64(const Verifier &verifier, voffset_t field) const {
return VerifyOffset<uoffset64_t>(verifier, field);
}
bool VerifyOffset64Required(const Verifier &verifier, voffset_t field) const {
return VerifyOffsetRequired<uoffset64_t>(verifier, field);
}
private:
// private constructor & copy constructor: you obtain instances of this
// class by pointing to existing data only
Table();
Table(const Table &other);
Table &operator=(const Table &);
uint8_t data_[1];
};
// This specialization allows avoiding warnings like:
// MSVC C4800: type: forcing value to bool 'true' or 'false'.
template<>
inline flatbuffers::Optional<bool> Table::GetOptional<uint8_t, bool>(
voffset_t field) const {
auto field_offset = GetOptionalFieldOffset(field);
auto p = data_ + field_offset;
return field_offset ? Optional<bool>(ReadScalar<uint8_t>(p) != 0)
: Optional<bool>();
}
} // namespace flatbuffers
#endif // FLATBUFFERS_TABLE_H_
-400
View File
@@ -1,400 +0,0 @@
/*
* Copyright 2021 Google Inc. All rights reserved.
*
* 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.
*/
#ifndef FLATBUFFERS_VECTOR_H_
#define FLATBUFFERS_VECTOR_H_
#include "flatbuffers/base.h"
#include "flatbuffers/buffer.h"
#include "flatbuffers/stl_emulation.h"
namespace flatbuffers {
struct String;
// An STL compatible iterator implementation for Vector below, effectively
// calling Get() for every element.
template<typename T, typename IT, typename Data = uint8_t *,
typename SizeT = uoffset_t>
struct VectorIterator {
typedef std::random_access_iterator_tag iterator_category;
typedef IT value_type;
typedef ptrdiff_t difference_type;
typedef IT *pointer;
typedef IT &reference;
static const SizeT element_stride = IndirectHelper<T>::element_stride;
VectorIterator(Data data, SizeT i) : data_(data + element_stride * i) {}
VectorIterator(const VectorIterator &other) : data_(other.data_) {}
VectorIterator() : data_(nullptr) {}
VectorIterator &operator=(const VectorIterator &other) {
data_ = other.data_;
return *this;
}
VectorIterator &operator=(VectorIterator &&other) {
data_ = other.data_;
return *this;
}
bool operator==(const VectorIterator &other) const {
return data_ == other.data_;
}
bool operator<(const VectorIterator &other) const {
return data_ < other.data_;
}
bool operator!=(const VectorIterator &other) const {
return data_ != other.data_;
}
difference_type operator-(const VectorIterator &other) const {
return (data_ - other.data_) / element_stride;
}
// Note: return type is incompatible with the standard
// `reference operator*()`.
IT operator*() const { return IndirectHelper<T>::Read(data_, 0); }
// Note: return type is incompatible with the standard
// `pointer operator->()`.
IT operator->() const { return IndirectHelper<T>::Read(data_, 0); }
VectorIterator &operator++() {
data_ += element_stride;
return *this;
}
VectorIterator operator++(int) {
VectorIterator temp(data_, 0);
data_ += element_stride;
return temp;
}
VectorIterator operator+(const SizeT &offset) const {
return VectorIterator(data_ + offset * element_stride, 0);
}
VectorIterator &operator+=(const SizeT &offset) {
data_ += offset * element_stride;
return *this;
}
VectorIterator &operator--() {
data_ -= element_stride;
return *this;
}
VectorIterator operator--(int) {
VectorIterator temp(data_, 0);
data_ -= element_stride;
return temp;
}
VectorIterator operator-(const SizeT &offset) const {
return VectorIterator(data_ - offset * element_stride, 0);
}
VectorIterator &operator-=(const SizeT &offset) {
data_ -= offset * element_stride;
return *this;
}
private:
Data data_;
};
template<typename T, typename IT, typename SizeT = uoffset_t>
using VectorConstIterator = VectorIterator<T, IT, const uint8_t *, SizeT>;
template<typename Iterator>
struct VectorReverseIterator : public std::reverse_iterator<Iterator> {
explicit VectorReverseIterator(Iterator iter)
: std::reverse_iterator<Iterator>(iter) {}
// Note: return type is incompatible with the standard
// `reference operator*()`.
typename Iterator::value_type operator*() const {
auto tmp = std::reverse_iterator<Iterator>::current;
return *--tmp;
}
// Note: return type is incompatible with the standard
// `pointer operator->()`.
typename Iterator::value_type operator->() const {
auto tmp = std::reverse_iterator<Iterator>::current;
return *--tmp;
}
};
// This is used as a helper type for accessing vectors.
// Vector::data() assumes the vector elements start after the length field.
template<typename T, typename SizeT = uoffset_t> class Vector {
public:
typedef VectorIterator<T,
typename IndirectHelper<T>::mutable_return_type,
uint8_t *, SizeT>
iterator;
typedef VectorConstIterator<T, typename IndirectHelper<T>::return_type,
SizeT>
const_iterator;
typedef VectorReverseIterator<iterator> reverse_iterator;
typedef VectorReverseIterator<const_iterator> const_reverse_iterator;
typedef typename flatbuffers::bool_constant<flatbuffers::is_scalar<T>::value>
scalar_tag;
static FLATBUFFERS_CONSTEXPR bool is_span_observable =
scalar_tag::value && (FLATBUFFERS_LITTLEENDIAN || sizeof(T) == 1);
SizeT size() const { return EndianScalar(length_); }
// Deprecated: use size(). Here for backwards compatibility.
FLATBUFFERS_ATTRIBUTE([[deprecated("use size() instead")]])
SizeT Length() const { return size(); }
typedef SizeT size_type;
typedef typename IndirectHelper<T>::return_type return_type;
typedef typename IndirectHelper<T>::mutable_return_type
mutable_return_type;
typedef return_type value_type;
return_type Get(SizeT i) const {
FLATBUFFERS_ASSERT(i < size());
return IndirectHelper<T>::Read(Data(), i);
}
return_type operator[](SizeT i) const { return Get(i); }
// If this is a Vector of enums, T will be its storage type, not the enum
// type. This function makes it convenient to retrieve value with enum
// type E.
template<typename E> E GetEnum(SizeT i) const {
return static_cast<E>(Get(i));
}
// If this a vector of unions, this does the cast for you. There's no check
// to make sure this is the right type!
template<typename U> const U *GetAs(SizeT i) const {
return reinterpret_cast<const U *>(Get(i));
}
// If this a vector of unions, this does the cast for you. There's no check
// to make sure this is actually a string!
const String *GetAsString(SizeT i) const {
return reinterpret_cast<const String *>(Get(i));
}
const void *GetStructFromOffset(size_t o) const {
return reinterpret_cast<const void *>(Data() + o);
}
iterator begin() { return iterator(Data(), 0); }
const_iterator begin() const { return const_iterator(Data(), 0); }
iterator end() { return iterator(Data(), size()); }
const_iterator end() const { return const_iterator(Data(), size()); }
reverse_iterator rbegin() { return reverse_iterator(end()); }
const_reverse_iterator rbegin() const {
return const_reverse_iterator(end());
}
reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator rend() const {
return const_reverse_iterator(begin());
}
const_iterator cbegin() const { return begin(); }
const_iterator cend() const { return end(); }
const_reverse_iterator crbegin() const { return rbegin(); }
const_reverse_iterator crend() const { return rend(); }
// Change elements if you have a non-const pointer to this object.
// Scalars only. See reflection.h, and the documentation.
void Mutate(SizeT i, const T &val) {
FLATBUFFERS_ASSERT(i < size());
WriteScalar(data() + i, val);
}
// Change an element of a vector of tables (or strings).
// "val" points to the new table/string, as you can obtain from
// e.g. reflection::AddFlatBuffer().
void MutateOffset(SizeT i, const uint8_t *val) {
FLATBUFFERS_ASSERT(i < size());
static_assert(sizeof(T) == sizeof(SizeT), "Unrelated types");
WriteScalar(data() + i,
static_cast<SizeT>(val - (Data() + i * sizeof(SizeT))));
}
// Get a mutable pointer to tables/strings inside this vector.
mutable_return_type GetMutableObject(SizeT i) const {
FLATBUFFERS_ASSERT(i < size());
return const_cast<mutable_return_type>(IndirectHelper<T>::Read(Data(), i));
}
// The raw data in little endian format. Use with care.
const uint8_t *Data() const {
return reinterpret_cast<const uint8_t *>(&length_ + 1);
}
uint8_t *Data() { return reinterpret_cast<uint8_t *>(&length_ + 1); }
// Similarly, but typed, much like std::vector::data
const T *data() const { return reinterpret_cast<const T *>(Data()); }
T *data() { return reinterpret_cast<T *>(Data()); }
template<typename K> return_type LookupByKey(K key) const {
void *search_result = std::bsearch(
&key, Data(), size(), IndirectHelper<T>::element_stride, KeyCompare<K>);
if (!search_result) {
return nullptr; // Key not found.
}
const uint8_t *element = reinterpret_cast<const uint8_t *>(search_result);
return IndirectHelper<T>::Read(element, 0);
}
template<typename K> mutable_return_type MutableLookupByKey(K key) {
return const_cast<mutable_return_type>(LookupByKey(key));
}
protected:
// This class is only used to access pre-existing data. Don't ever
// try to construct these manually.
Vector();
SizeT length_;
private:
// This class is a pointer. Copying will therefore create an invalid object.
// Private and unimplemented copy constructor.
Vector(const Vector &);
Vector &operator=(const Vector &);
template<typename K> static int KeyCompare(const void *ap, const void *bp) {
const K *key = reinterpret_cast<const K *>(ap);
const uint8_t *data = reinterpret_cast<const uint8_t *>(bp);
auto table = IndirectHelper<T>::Read(data, 0);
// std::bsearch compares with the operands transposed, so we negate the
// result here.
return -table->KeyCompareWithValue(*key);
}
};
template<typename T> using Vector64 = Vector<T, uoffset64_t>;
template<class U>
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<U> make_span(Vector<U> &vec)
FLATBUFFERS_NOEXCEPT {
static_assert(Vector<U>::is_span_observable,
"wrong type U, only LE-scalar, or byte types are allowed");
return span<U>(vec.data(), vec.size());
}
template<class U>
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const U> make_span(
const Vector<U> &vec) FLATBUFFERS_NOEXCEPT {
static_assert(Vector<U>::is_span_observable,
"wrong type U, only LE-scalar, or byte types are allowed");
return span<const U>(vec.data(), vec.size());
}
template<class U>
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<uint8_t> make_bytes_span(
Vector<U> &vec) FLATBUFFERS_NOEXCEPT {
static_assert(Vector<U>::scalar_tag::value,
"wrong type U, only LE-scalar, or byte types are allowed");
return span<uint8_t>(vec.Data(), vec.size() * sizeof(U));
}
template<class U>
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const uint8_t> make_bytes_span(
const Vector<U> &vec) FLATBUFFERS_NOEXCEPT {
static_assert(Vector<U>::scalar_tag::value,
"wrong type U, only LE-scalar, or byte types are allowed");
return span<const uint8_t>(vec.Data(), vec.size() * sizeof(U));
}
// Convenient helper functions to get a span of any vector, regardless
// of whether it is null or not (the field is not set).
template<class U>
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<U> make_span(Vector<U> *ptr)
FLATBUFFERS_NOEXCEPT {
static_assert(Vector<U>::is_span_observable,
"wrong type U, only LE-scalar, or byte types are allowed");
return ptr ? make_span(*ptr) : span<U>();
}
template<class U>
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const U> make_span(
const Vector<U> *ptr) FLATBUFFERS_NOEXCEPT {
static_assert(Vector<U>::is_span_observable,
"wrong type U, only LE-scalar, or byte types are allowed");
return ptr ? make_span(*ptr) : span<const U>();
}
// Represent a vector much like the template above, but in this case we
// don't know what the element types are (used with reflection.h).
class VectorOfAny {
public:
uoffset_t size() const { return EndianScalar(length_); }
const uint8_t *Data() const {
return reinterpret_cast<const uint8_t *>(&length_ + 1);
}
uint8_t *Data() { return reinterpret_cast<uint8_t *>(&length_ + 1); }
protected:
VectorOfAny();
uoffset_t length_;
private:
VectorOfAny(const VectorOfAny &);
VectorOfAny &operator=(const VectorOfAny &);
};
template<typename T, typename U>
Vector<Offset<T>> *VectorCast(Vector<Offset<U>> *ptr) {
static_assert(std::is_base_of<T, U>::value, "Unrelated types");
return reinterpret_cast<Vector<Offset<T>> *>(ptr);
}
template<typename T, typename U>
const Vector<Offset<T>> *VectorCast(const Vector<Offset<U>> *ptr) {
static_assert(std::is_base_of<T, U>::value, "Unrelated types");
return reinterpret_cast<const Vector<Offset<T>> *>(ptr);
}
// Convenient helper function to get the length of any vector, regardless
// of whether it is null or not (the field is not set).
template<typename T> static inline size_t VectorLength(const Vector<T> *v) {
return v ? v->size() : 0;
}
} // namespace flatbuffers
#endif // FLATBUFFERS_VERIFIER_H_
@@ -1,288 +0,0 @@
/*
* Copyright 2021 Google Inc. All rights reserved.
*
* 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.
*/
#ifndef FLATBUFFERS_VECTOR_DOWNWARD_H_
#define FLATBUFFERS_VECTOR_DOWNWARD_H_
#include <cstdint>
#include <algorithm>
#include "flatbuffers/base.h"
#include "flatbuffers/default_allocator.h"
#include "flatbuffers/detached_buffer.h"
namespace flatbuffers {
// This is a minimal replication of std::vector<uint8_t> functionality,
// except growing from higher to lower addresses. i.e. push_back() inserts data
// in the lowest address in the vector.
// Since this vector leaves the lower part unused, we support a "scratch-pad"
// that can be stored there for temporary data, to share the allocated space.
// Essentially, this supports 2 std::vectors in a single buffer.
template<typename SizeT = uoffset_t> class vector_downward {
public:
explicit vector_downward(size_t initial_size, Allocator *allocator,
bool own_allocator, size_t buffer_minalign,
const SizeT max_size = FLATBUFFERS_MAX_BUFFER_SIZE)
: allocator_(allocator),
own_allocator_(own_allocator),
initial_size_(initial_size),
max_size_(max_size),
buffer_minalign_(buffer_minalign),
reserved_(0),
size_(0),
buf_(nullptr),
cur_(nullptr),
scratch_(nullptr) {}
vector_downward(vector_downward &&other) noexcept
// clang-format on
: allocator_(other.allocator_),
own_allocator_(other.own_allocator_),
initial_size_(other.initial_size_),
max_size_(other.max_size_),
buffer_minalign_(other.buffer_minalign_),
reserved_(other.reserved_),
size_(other.size_),
buf_(other.buf_),
cur_(other.cur_),
scratch_(other.scratch_) {
// No change in other.allocator_
// No change in other.initial_size_
// No change in other.buffer_minalign_
other.own_allocator_ = false;
other.reserved_ = 0;
other.buf_ = nullptr;
other.cur_ = nullptr;
other.scratch_ = nullptr;
}
vector_downward &operator=(vector_downward &&other) noexcept {
// Move construct a temporary and swap idiom
vector_downward temp(std::move(other));
swap(temp);
return *this;
}
~vector_downward() {
clear_buffer();
clear_allocator();
}
void reset() {
clear_buffer();
clear();
}
void clear() {
if (buf_) {
cur_ = buf_ + reserved_;
} else {
reserved_ = 0;
cur_ = nullptr;
}
size_ = 0;
clear_scratch();
}
void clear_scratch() { scratch_ = buf_; }
void clear_allocator() {
if (own_allocator_ && allocator_) { delete allocator_; }
allocator_ = nullptr;
own_allocator_ = false;
}
void clear_buffer() {
if (buf_) Deallocate(allocator_, buf_, reserved_);
buf_ = nullptr;
}
// Relinquish the pointer to the caller.
uint8_t *release_raw(size_t &allocated_bytes, size_t &offset) {
auto *buf = buf_;
allocated_bytes = reserved_;
offset = vector_downward::offset();
// release_raw only relinquishes the buffer ownership.
// Does not deallocate or reset the allocator. Destructor will do that.
buf_ = nullptr;
clear();
return buf;
}
// Relinquish the pointer to the caller.
DetachedBuffer release() {
// allocator ownership (if any) is transferred to DetachedBuffer.
DetachedBuffer fb(allocator_, own_allocator_, buf_, reserved_, cur_,
size());
if (own_allocator_) {
allocator_ = nullptr;
own_allocator_ = false;
}
buf_ = nullptr;
clear();
return fb;
}
size_t ensure_space(size_t len) {
FLATBUFFERS_ASSERT(cur_ >= scratch_ && scratch_ >= buf_);
// If the length is larger than the unused part of the buffer, we need to
// grow.
if (len > unused_buffer_size()) { reallocate(len); }
FLATBUFFERS_ASSERT(size() < max_size_);
return len;
}
inline uint8_t *make_space(size_t len) {
if (len) {
ensure_space(len);
cur_ -= len;
size_ += static_cast<SizeT>(len);
}
return cur_;
}
// Returns nullptr if using the DefaultAllocator.
Allocator *get_custom_allocator() { return allocator_; }
// The current offset into the buffer.
size_t offset() const { return cur_ - buf_; }
// The total size of the vector (both the buffer and scratch parts).
inline SizeT size() const { return size_; }
// The size of the buffer part of the vector that is currently unused.
SizeT unused_buffer_size() const { return static_cast<SizeT>(cur_ - scratch_); }
// The size of the scratch part of the vector.
SizeT scratch_size() const { return static_cast<SizeT>(scratch_ - buf_); }
size_t capacity() const { return reserved_; }
uint8_t *data() const {
FLATBUFFERS_ASSERT(cur_);
return cur_;
}
uint8_t *scratch_data() const {
FLATBUFFERS_ASSERT(buf_);
return buf_;
}
uint8_t *scratch_end() const {
FLATBUFFERS_ASSERT(scratch_);
return scratch_;
}
uint8_t *data_at(size_t offset) const { return buf_ + reserved_ - offset; }
void push(const uint8_t *bytes, size_t num) {
if (num > 0) { memcpy(make_space(num), bytes, num); }
}
// Specialized version of push() that avoids memcpy call for small data.
template<typename T> void push_small(const T &little_endian_t) {
make_space(sizeof(T));
*reinterpret_cast<T *>(cur_) = little_endian_t;
}
template<typename T> void scratch_push_small(const T &t) {
ensure_space(sizeof(T));
*reinterpret_cast<T *>(scratch_) = t;
scratch_ += sizeof(T);
}
// fill() is most frequently called with small byte counts (<= 4),
// which is why we're using loops rather than calling memset.
void fill(size_t zero_pad_bytes) {
make_space(zero_pad_bytes);
for (size_t i = 0; i < zero_pad_bytes; i++) cur_[i] = 0;
}
// Version for when we know the size is larger.
// Precondition: zero_pad_bytes > 0
void fill_big(size_t zero_pad_bytes) {
memset(make_space(zero_pad_bytes), 0, zero_pad_bytes);
}
void pop(size_t bytes_to_remove) {
cur_ += bytes_to_remove;
size_ -= static_cast<SizeT>(bytes_to_remove);
}
void scratch_pop(size_t bytes_to_remove) { scratch_ -= bytes_to_remove; }
void swap(vector_downward &other) {
using std::swap;
swap(allocator_, other.allocator_);
swap(own_allocator_, other.own_allocator_);
swap(initial_size_, other.initial_size_);
swap(buffer_minalign_, other.buffer_minalign_);
swap(reserved_, other.reserved_);
swap(size_, other.size_);
swap(max_size_, other.max_size_);
swap(buf_, other.buf_);
swap(cur_, other.cur_);
swap(scratch_, other.scratch_);
}
void swap_allocator(vector_downward &other) {
using std::swap;
swap(allocator_, other.allocator_);
swap(own_allocator_, other.own_allocator_);
}
private:
// You shouldn't really be copying instances of this class.
FLATBUFFERS_DELETE_FUNC(vector_downward(const vector_downward &));
FLATBUFFERS_DELETE_FUNC(vector_downward &operator=(const vector_downward &));
Allocator *allocator_;
bool own_allocator_;
size_t initial_size_;
// The maximum size the vector can be.
SizeT max_size_;
size_t buffer_minalign_;
size_t reserved_;
SizeT size_;
uint8_t *buf_;
uint8_t *cur_; // Points at location between empty (below) and used (above).
uint8_t *scratch_; // Points to the end of the scratchpad in use.
void reallocate(size_t len) {
auto old_reserved = reserved_;
auto old_size = size();
auto old_scratch_size = scratch_size();
reserved_ +=
(std::max)(len, old_reserved ? old_reserved / 2 : initial_size_);
reserved_ = (reserved_ + buffer_minalign_ - 1) & ~(buffer_minalign_ - 1);
if (buf_) {
buf_ = ReallocateDownward(allocator_, buf_, old_reserved, reserved_,
old_size, old_scratch_size);
} else {
buf_ = Allocate(allocator_, reserved_);
}
cur_ = buf_ + reserved_ - old_size;
scratch_ = buf_ + old_scratch_size;
}
};
} // namespace flatbuffers
#endif // FLATBUFFERS_VECTOR_DOWNWARD_H_
-330
View File
@@ -1,330 +0,0 @@
/*
* Copyright 2021 Google Inc. All rights reserved.
*
* 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.
*/
#ifndef FLATBUFFERS_VERIFIER_H_
#define FLATBUFFERS_VERIFIER_H_
#include "flatbuffers/base.h"
#include "flatbuffers/vector.h"
namespace flatbuffers {
// Helper class to verify the integrity of a FlatBuffer
class Verifier FLATBUFFERS_FINAL_CLASS {
public:
struct Options {
// The maximum nesting of tables and vectors before we call it invalid.
uoffset_t max_depth = 64;
// The maximum number of tables we will verify before we call it invalid.
uoffset_t max_tables = 1000000;
// If true, verify all data is aligned.
bool check_alignment = true;
// If true, run verifier on nested flatbuffers
bool check_nested_flatbuffers = true;
// The maximum size of a buffer.
size_t max_size = FLATBUFFERS_MAX_BUFFER_SIZE;
// Use assertions to check for errors.
bool assert = false;
};
explicit Verifier(const uint8_t *const buf, const size_t buf_len,
const Options &opts)
: buf_(buf), size_(buf_len), opts_(opts) {
FLATBUFFERS_ASSERT(size_ < opts.max_size);
}
// Deprecated API, please construct with Verifier::Options.
Verifier(const uint8_t *const buf, const size_t buf_len,
const uoffset_t max_depth = 64, const uoffset_t max_tables = 1000000,
const bool check_alignment = true)
: Verifier(buf, buf_len, [&] {
Options opts;
opts.max_depth = max_depth;
opts.max_tables = max_tables;
opts.check_alignment = check_alignment;
return opts;
}()) {}
// Central location where any verification failures register.
bool Check(const bool ok) const {
// clang-format off
#ifdef FLATBUFFERS_DEBUG_VERIFICATION_FAILURE
if (opts_.assert) { FLATBUFFERS_ASSERT(ok); }
#endif
#ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
if (!ok)
upper_bound_ = 0;
#endif
// clang-format on
return ok;
}
// Verify any range within the buffer.
bool Verify(const size_t elem, const size_t elem_len) const {
// clang-format off
#ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
auto upper_bound = elem + elem_len;
if (upper_bound_ < upper_bound)
upper_bound_ = upper_bound;
#endif
// clang-format on
return Check(elem_len < size_ && elem <= size_ - elem_len);
}
bool VerifyAlignment(const size_t elem, const size_t align) const {
return Check((elem & (align - 1)) == 0 || !opts_.check_alignment);
}
// Verify a range indicated by sizeof(T).
template<typename T> bool Verify(const size_t elem) const {
return VerifyAlignment(elem, sizeof(T)) && Verify(elem, sizeof(T));
}
bool VerifyFromPointer(const uint8_t *const p, const size_t len) {
return Verify(static_cast<size_t>(p - buf_), len);
}
// Verify relative to a known-good base pointer.
bool VerifyFieldStruct(const uint8_t *const base, const voffset_t elem_off,
const size_t elem_len, const size_t align) const {
const auto f = static_cast<size_t>(base - buf_) + elem_off;
return VerifyAlignment(f, align) && Verify(f, elem_len);
}
template<typename T>
bool VerifyField(const uint8_t *const base, const voffset_t elem_off,
const size_t align) const {
const auto f = static_cast<size_t>(base - buf_) + elem_off;
return VerifyAlignment(f, align) && Verify(f, sizeof(T));
}
// Verify a pointer (may be NULL) of a table type.
template<typename T> bool VerifyTable(const T *const table) {
return !table || table->Verify(*this);
}
// Verify a pointer (may be NULL) of any vector type.
template<int &..., typename T, typename LenT>
bool VerifyVector(const Vector<T, LenT> *const vec) const {
return !vec || VerifyVectorOrString<LenT>(
reinterpret_cast<const uint8_t *>(vec), sizeof(T));
}
// Verify a pointer (may be NULL) of a vector to struct.
template<int &..., typename T, typename LenT>
bool VerifyVector(const Vector<const T *, LenT> *const vec) const {
return VerifyVector(reinterpret_cast<const Vector<T, LenT> *>(vec));
}
// Verify a pointer (may be NULL) to string.
bool VerifyString(const String *const str) const {
size_t end;
return !str || (VerifyVectorOrString<uoffset_t>(
reinterpret_cast<const uint8_t *>(str), 1, &end) &&
Verify(end, 1) && // Must have terminator
Check(buf_[end] == '\0')); // Terminating byte must be 0.
}
// Common code between vectors and strings.
template<typename LenT = uoffset_t>
bool VerifyVectorOrString(const uint8_t *const vec, const size_t elem_size,
size_t *const end = nullptr) const {
const auto vec_offset = static_cast<size_t>(vec - buf_);
// Check we can read the size field.
if (!Verify<LenT>(vec_offset)) return false;
// Check the whole array. If this is a string, the byte past the array must
// be 0.
const LenT size = ReadScalar<LenT>(vec);
const auto max_elems = opts_.max_size / elem_size;
if (!Check(size < max_elems))
return false; // Protect against byte_size overflowing.
const auto byte_size = sizeof(LenT) + elem_size * size;
if (end) *end = vec_offset + byte_size;
return Verify(vec_offset, byte_size);
}
// Special case for string contents, after the above has been called.
bool VerifyVectorOfStrings(const Vector<Offset<String>> *const vec) const {
if (vec) {
for (uoffset_t i = 0; i < vec->size(); i++) {
if (!VerifyString(vec->Get(i))) return false;
}
}
return true;
}
// Special case for table contents, after the above has been called.
template<typename T>
bool VerifyVectorOfTables(const Vector<Offset<T>> *const vec) {
if (vec) {
for (uoffset_t i = 0; i < vec->size(); i++) {
if (!vec->Get(i)->Verify(*this)) return false;
}
}
return true;
}
__suppress_ubsan__("unsigned-integer-overflow") bool VerifyTableStart(
const uint8_t *const table) {
// Check the vtable offset.
const auto tableo = static_cast<size_t>(table - buf_);
if (!Verify<soffset_t>(tableo)) return false;
// This offset may be signed, but doing the subtraction unsigned always
// gives the result we want.
const auto vtableo =
tableo - static_cast<size_t>(ReadScalar<soffset_t>(table));
// Check the vtable size field, then check vtable fits in its entirety.
if (!(VerifyComplexity() && Verify<voffset_t>(vtableo) &&
VerifyAlignment(ReadScalar<voffset_t>(buf_ + vtableo),
sizeof(voffset_t))))
return false;
const auto vsize = ReadScalar<voffset_t>(buf_ + vtableo);
return Check((vsize & 1) == 0) && Verify(vtableo, vsize);
}
template<typename T>
bool VerifyBufferFromStart(const char *const identifier, const size_t start) {
// Buffers have to be of some size to be valid. The reason it is a runtime
// check instead of static_assert, is that nested flatbuffers go through
// this call and their size is determined at runtime.
if (!Check(size_ >= FLATBUFFERS_MIN_BUFFER_SIZE)) return false;
// If an identifier is provided, check that we have a buffer
if (identifier && !Check((size_ >= 2 * sizeof(flatbuffers::uoffset_t) &&
BufferHasIdentifier(buf_ + start, identifier)))) {
return false;
}
// Call T::Verify, which must be in the generated code for this type.
const auto o = VerifyOffset<uoffset_t>(start);
return Check(o != 0) &&
reinterpret_cast<const T *>(buf_ + start + o)->Verify(*this)
// clang-format off
#ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
&& GetComputedSize()
#endif
;
// clang-format on
}
template<typename T, int &..., typename SizeT>
bool VerifyNestedFlatBuffer(const Vector<uint8_t, SizeT> *const buf,
const char *const identifier) {
// Caller opted out of this.
if (!opts_.check_nested_flatbuffers) return true;
// An empty buffer is OK as it indicates not present.
if (!buf) return true;
// If there is a nested buffer, it must be greater than the min size.
if (!Check(buf->size() >= FLATBUFFERS_MIN_BUFFER_SIZE)) return false;
Verifier nested_verifier(buf->data(), buf->size(), opts_);
return nested_verifier.VerifyBuffer<T>(identifier);
}
// Verify this whole buffer, starting with root type T.
template<typename T> bool VerifyBuffer() { return VerifyBuffer<T>(nullptr); }
template<typename T> bool VerifyBuffer(const char *const identifier) {
return VerifyBufferFromStart<T>(identifier, 0);
}
template<typename T, typename SizeT = uoffset_t>
bool VerifySizePrefixedBuffer(const char *const identifier) {
return Verify<SizeT>(0U) &&
Check(ReadScalar<SizeT>(buf_) == size_ - sizeof(SizeT)) &&
VerifyBufferFromStart<T>(identifier, sizeof(SizeT));
}
template<typename OffsetT = uoffset_t, typename SOffsetT = soffset_t>
size_t VerifyOffset(const size_t start) const {
if (!Verify<OffsetT>(start)) return 0;
const auto o = ReadScalar<OffsetT>(buf_ + start);
// May not point to itself.
if (!Check(o != 0)) return 0;
// Can't wrap around larger than the max size.
if (!Check(static_cast<SOffsetT>(o) >= 0)) return 0;
// Must be inside the buffer to create a pointer from it (pointer outside
// buffer is UB).
if (!Verify(start + o, 1)) return 0;
return o;
}
template<typename OffsetT = uoffset_t>
size_t VerifyOffset(const uint8_t *const base, const voffset_t start) const {
return VerifyOffset<OffsetT>(static_cast<size_t>(base - buf_) + start);
}
// Called at the start of a table to increase counters measuring data
// structure depth and amount, and possibly bails out with false if limits set
// by the constructor have been hit. Needs to be balanced with EndTable().
bool VerifyComplexity() {
depth_++;
num_tables_++;
return Check(depth_ <= opts_.max_depth && num_tables_ <= opts_.max_tables);
}
// Called at the end of a table to pop the depth count.
bool EndTable() {
depth_--;
return true;
}
// Returns the message size in bytes
size_t GetComputedSize() const {
// clang-format off
#ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
uintptr_t size = upper_bound_;
// Align the size to uoffset_t
size = (size - 1 + sizeof(uoffset_t)) & ~(sizeof(uoffset_t) - 1);
return (size > size_) ? 0 : size;
#else
// Must turn on FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE for this to work.
(void)upper_bound_;
FLATBUFFERS_ASSERT(false);
return 0;
#endif
// clang-format on
}
std::vector<uint8_t> *GetFlexReuseTracker() { return flex_reuse_tracker_; }
void SetFlexReuseTracker(std::vector<uint8_t> *const rt) {
flex_reuse_tracker_ = rt;
}
private:
const uint8_t *buf_;
const size_t size_;
const Options opts_;
mutable size_t upper_bound_ = 0;
uoffset_t depth_ = 0;
uoffset_t num_tables_ = 0;
std::vector<uint8_t> *flex_reuse_tracker_ = nullptr;
};
// Specialization for 64-bit offsets.
template<>
inline size_t Verifier::VerifyOffset<uoffset64_t>(const size_t start) const {
return VerifyOffset<uoffset64_t, soffset64_t>(start);
}
} // namespace flatbuffers
#endif // FLATBUFFERS_VERIFIER_H_
@@ -1,160 +0,0 @@
/*******************************************************************************
* Copyright (c) 2008-2020 The Khronos Group Inc.
*
* 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.
******************************************************************************/
/*****************************************************************************\
Copyright (c) 2013-2019 Intel Corporation All Rights Reserved.
THESE MATERIALS ARE PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THESE
MATERIALS, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
File Name: cl_va_api_media_sharing_intel.h
Abstract:
Notes:
\*****************************************************************************/
#ifndef __OPENCL_CL_VA_API_MEDIA_SHARING_INTEL_H
#define __OPENCL_CL_VA_API_MEDIA_SHARING_INTEL_H
#include <CL/cl.h>
#include <CL/cl_platform.h>
#include <va/va.h>
#ifdef __cplusplus
extern "C" {
#endif
/******************************************
* cl_intel_va_api_media_sharing extension *
*******************************************/
#define cl_intel_va_api_media_sharing 1
/* error codes */
#define CL_INVALID_VA_API_MEDIA_ADAPTER_INTEL -1098
#define CL_INVALID_VA_API_MEDIA_SURFACE_INTEL -1099
#define CL_VA_API_MEDIA_SURFACE_ALREADY_ACQUIRED_INTEL -1100
#define CL_VA_API_MEDIA_SURFACE_NOT_ACQUIRED_INTEL -1101
/* cl_va_api_device_source_intel */
#define CL_VA_API_DISPLAY_INTEL 0x4094
/* cl_va_api_device_set_intel */
#define CL_PREFERRED_DEVICES_FOR_VA_API_INTEL 0x4095
#define CL_ALL_DEVICES_FOR_VA_API_INTEL 0x4096
/* cl_context_info */
#define CL_CONTEXT_VA_API_DISPLAY_INTEL 0x4097
/* cl_mem_info */
#define CL_MEM_VA_API_MEDIA_SURFACE_INTEL 0x4098
/* cl_image_info */
#define CL_IMAGE_VA_API_PLANE_INTEL 0x4099
/* cl_command_type */
#define CL_COMMAND_ACQUIRE_VA_API_MEDIA_SURFACES_INTEL 0x409A
#define CL_COMMAND_RELEASE_VA_API_MEDIA_SURFACES_INTEL 0x409B
typedef cl_uint cl_va_api_device_source_intel;
typedef cl_uint cl_va_api_device_set_intel;
extern CL_API_ENTRY cl_int CL_API_CALL
clGetDeviceIDsFromVA_APIMediaAdapterINTEL(
cl_platform_id platform,
cl_va_api_device_source_intel media_adapter_type,
void* media_adapter,
cl_va_api_device_set_intel media_adapter_set,
cl_uint num_entries,
cl_device_id* devices,
cl_uint* num_devices) CL_EXT_SUFFIX__VERSION_1_2;
typedef CL_API_ENTRY cl_int (CL_API_CALL * clGetDeviceIDsFromVA_APIMediaAdapterINTEL_fn)(
cl_platform_id platform,
cl_va_api_device_source_intel media_adapter_type,
void* media_adapter,
cl_va_api_device_set_intel media_adapter_set,
cl_uint num_entries,
cl_device_id* devices,
cl_uint* num_devices) CL_EXT_SUFFIX__VERSION_1_2;
extern CL_API_ENTRY cl_mem CL_API_CALL
clCreateFromVA_APIMediaSurfaceINTEL(
cl_context context,
cl_mem_flags flags,
VASurfaceID* surface,
cl_uint plane,
cl_int* errcode_ret) CL_EXT_SUFFIX__VERSION_1_2;
typedef CL_API_ENTRY cl_mem (CL_API_CALL * clCreateFromVA_APIMediaSurfaceINTEL_fn)(
cl_context context,
cl_mem_flags flags,
VASurfaceID* surface,
cl_uint plane,
cl_int* errcode_ret) CL_EXT_SUFFIX__VERSION_1_2;
extern CL_API_ENTRY cl_int CL_API_CALL
clEnqueueAcquireVA_APIMediaSurfacesINTEL(
cl_command_queue command_queue,
cl_uint num_objects,
const cl_mem* mem_objects,
cl_uint num_events_in_wait_list,
const cl_event* event_wait_list,
cl_event* event) CL_EXT_SUFFIX__VERSION_1_2;
typedef CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueAcquireVA_APIMediaSurfacesINTEL_fn)(
cl_command_queue command_queue,
cl_uint num_objects,
const cl_mem* mem_objects,
cl_uint num_events_in_wait_list,
const cl_event* event_wait_list,
cl_event* event) CL_EXT_SUFFIX__VERSION_1_2;
extern CL_API_ENTRY cl_int CL_API_CALL
clEnqueueReleaseVA_APIMediaSurfacesINTEL(
cl_command_queue command_queue,
cl_uint num_objects,
const cl_mem* mem_objects,
cl_uint num_events_in_wait_list,
const cl_event* event_wait_list,
cl_event* event) CL_EXT_SUFFIX__VERSION_1_2;
typedef CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueReleaseVA_APIMediaSurfacesINTEL_fn)(
cl_command_queue command_queue,
cl_uint num_objects,
const cl_mem* mem_objects,
cl_uint num_events_in_wait_list,
const cl_event* event_wait_list,
cl_event* event) CL_EXT_SUFFIX__VERSION_1_2;
#ifdef __cplusplus
}
#endif
#endif /* __OPENCL_CL_VA_API_MEDIA_SHARING_INTEL_H */
+14 -6
View File
@@ -2,9 +2,19 @@
// File: vk_platform.h
//
/*
** Copyright 2014-2023 The Khronos Group Inc.
** Copyright (c) 2014-2017 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
** 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.
*/
@@ -42,7 +52,7 @@ extern "C"
#define VKAPI_CALL __stdcall
#define VKAPI_PTR VKAPI_CALL
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7
#error "Vulkan is not supported for the 'armeabi' NDK ABI"
#error "Vulkan isn't supported for the 'armeabi' NDK ABI"
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE)
// On Android 32-bit ARM targets, Vulkan functions use the "hardfloat"
// calling convention, i.e. float parameters are passed in registers. This
@@ -58,9 +68,7 @@ extern "C"
#define VKAPI_PTR
#endif
#if !defined(VK_NO_STDDEF_H)
#include <stddef.h>
#endif // !defined(VK_NO_STDDEF_H)
#include <stddef.h>
#if !defined(VK_NO_STDINT_H)
#if defined(_MSC_VER) && (_MSC_VER < 1600)
+18 -34
View File
@@ -2,9 +2,19 @@
#define VULKAN_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright (c) 2015-2018 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
** 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.
*/
#include "vk_platform.h"
@@ -28,16 +38,20 @@
#include "vulkan_macos.h"
#endif
#ifdef VK_USE_PLATFORM_METAL_EXT
#include "vulkan_metal.h"
#ifdef VK_USE_PLATFORM_MIR_KHR
#include <mir_toolkit/client_types.h>
#include "vulkan_mir.h"
#endif
#ifdef VK_USE_PLATFORM_VI_NN
#include "vulkan_vi.h"
#endif
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
#include <wayland-client.h>
#include "vulkan_wayland.h"
#endif
@@ -60,40 +74,10 @@
#endif
#ifdef VK_USE_PLATFORM_DIRECTFB_EXT
#include <directfb.h>
#include "vulkan_directfb.h"
#endif
#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
#include "vulkan_xlib_xrandr.h"
#endif
#ifdef VK_USE_PLATFORM_GGP
#include <ggp_c/vulkan_types.h>
#include "vulkan_ggp.h"
#endif
#ifdef VK_USE_PLATFORM_SCREEN_QNX
#include <screen/screen.h>
#include "vulkan_screen.h"
#endif
#ifdef VK_USE_PLATFORM_SCI
#include <nvscisync.h>
#include <nvscibuf.h>
#include "vulkan_sci.h"
#endif
#ifdef VK_ENABLE_BETA_EXTENSIONS
#include "vulkan_beta.h"
#endif
#endif // VULKAN_H_
+23 -22
View File
@@ -1,10 +1,24 @@
#ifndef VULKAN_ANDROID_H_
#define VULKAN_ANDROID_H_ 1
#ifdef __cplusplus
extern "C" {
#endif
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright (c) 2015-2018 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
** 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.
*/
/*
@@ -13,17 +27,14 @@
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_KHR_android_surface 1
struct ANativeWindow;
#define VK_KHR_ANDROID_SURFACE_SPEC_VERSION 6
#define VK_KHR_ANDROID_SURFACE_EXTENSION_NAME "VK_KHR_android_surface"
typedef VkFlags VkAndroidSurfaceCreateFlagsKHR;
typedef struct VkAndroidSurfaceCreateInfoKHR {
VkStructureType sType;
const void* pNext;
@@ -31,6 +42,7 @@ typedef struct VkAndroidSurfaceCreateInfoKHR {
struct ANativeWindow* window;
} VkAndroidSurfaceCreateInfoKHR;
typedef VkResult (VKAPI_PTR *PFN_vkCreateAndroidSurfaceKHR)(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
#ifndef VK_NO_PROTOTYPES
@@ -41,11 +53,12 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateAndroidSurfaceKHR(
VkSurfaceKHR* pSurface);
#endif
#define VK_ANDROID_external_memory_android_hardware_buffer 1
struct AHardwareBuffer;
#define VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_SPEC_VERSION 5
#define VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_SPEC_VERSION 3
#define VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME "VK_ANDROID_external_memory_android_hardware_buffer"
typedef struct VkAndroidHardwareBufferUsageANDROID {
VkStructureType sType;
void* pNext;
@@ -90,18 +103,6 @@ typedef struct VkExternalFormatANDROID {
uint64_t externalFormat;
} VkExternalFormatANDROID;
typedef struct VkAndroidHardwareBufferFormatProperties2ANDROID {
VkStructureType sType;
void* pNext;
VkFormat format;
uint64_t externalFormat;
VkFormatFeatureFlags2 formatFeatures;
VkComponentMapping samplerYcbcrConversionComponents;
VkSamplerYcbcrModelConversion suggestedYcbcrModel;
VkSamplerYcbcrRange suggestedYcbcrRange;
VkChromaLocation suggestedXChromaOffset;
VkChromaLocation suggestedYChromaOffset;
} VkAndroidHardwareBufferFormatProperties2ANDROID;
typedef VkResult (VKAPI_PTR *PFN_vkGetAndroidHardwareBufferPropertiesANDROID)(VkDevice device, const struct AHardwareBuffer* buffer, VkAndroidHardwareBufferPropertiesANDROID* pProperties);
typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryAndroidHardwareBufferANDROID)(VkDevice device, const VkMemoryGetAndroidHardwareBufferInfoANDROID* pInfo, struct AHardwareBuffer** pBuffer);
-492
View File
@@ -1,492 +0,0 @@
#ifndef VULKAN_BETA_H_
#define VULKAN_BETA_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
/*
** This header is generated from the Khronos Vulkan XML API Registry.
**
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_KHR_portability_subset 1
#define VK_KHR_PORTABILITY_SUBSET_SPEC_VERSION 1
#define VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME "VK_KHR_portability_subset"
typedef struct VkPhysicalDevicePortabilitySubsetFeaturesKHR {
VkStructureType sType;
void* pNext;
VkBool32 constantAlphaColorBlendFactors;
VkBool32 events;
VkBool32 imageViewFormatReinterpretation;
VkBool32 imageViewFormatSwizzle;
VkBool32 imageView2DOn3DImage;
VkBool32 multisampleArrayImage;
VkBool32 mutableComparisonSamplers;
VkBool32 pointPolygons;
VkBool32 samplerMipLodBias;
VkBool32 separateStencilMaskRef;
VkBool32 shaderSampleRateInterpolationFunctions;
VkBool32 tessellationIsolines;
VkBool32 tessellationPointMode;
VkBool32 triangleFans;
VkBool32 vertexAttributeAccessBeyondStride;
} VkPhysicalDevicePortabilitySubsetFeaturesKHR;
typedef struct VkPhysicalDevicePortabilitySubsetPropertiesKHR {
VkStructureType sType;
void* pNext;
uint32_t minVertexInputBindingStrideAlignment;
} VkPhysicalDevicePortabilitySubsetPropertiesKHR;
#define VK_KHR_video_encode_queue 1
#define VK_KHR_VIDEO_ENCODE_QUEUE_SPEC_VERSION 8
#define VK_KHR_VIDEO_ENCODE_QUEUE_EXTENSION_NAME "VK_KHR_video_encode_queue"
typedef enum VkVideoEncodeTuningModeKHR {
VK_VIDEO_ENCODE_TUNING_MODE_DEFAULT_KHR = 0,
VK_VIDEO_ENCODE_TUNING_MODE_HIGH_QUALITY_KHR = 1,
VK_VIDEO_ENCODE_TUNING_MODE_LOW_LATENCY_KHR = 2,
VK_VIDEO_ENCODE_TUNING_MODE_ULTRA_LOW_LATENCY_KHR = 3,
VK_VIDEO_ENCODE_TUNING_MODE_LOSSLESS_KHR = 4,
VK_VIDEO_ENCODE_TUNING_MODE_MAX_ENUM_KHR = 0x7FFFFFFF
} VkVideoEncodeTuningModeKHR;
typedef VkFlags VkVideoEncodeFlagsKHR;
typedef enum VkVideoEncodeCapabilityFlagBitsKHR {
VK_VIDEO_ENCODE_CAPABILITY_PRECEDING_EXTERNALLY_ENCODED_BYTES_BIT_KHR = 0x00000001,
VK_VIDEO_ENCODE_CAPABILITY_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
} VkVideoEncodeCapabilityFlagBitsKHR;
typedef VkFlags VkVideoEncodeCapabilityFlagsKHR;
typedef enum VkVideoEncodeRateControlModeFlagBitsKHR {
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DEFAULT_KHR = 0,
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR = 0x00000001,
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR = 0x00000002,
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR = 0x00000004,
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
} VkVideoEncodeRateControlModeFlagBitsKHR;
typedef VkFlags VkVideoEncodeRateControlModeFlagsKHR;
typedef enum VkVideoEncodeFeedbackFlagBitsKHR {
VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR = 0x00000001,
VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BYTES_WRITTEN_BIT_KHR = 0x00000002,
VK_VIDEO_ENCODE_FEEDBACK_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
} VkVideoEncodeFeedbackFlagBitsKHR;
typedef VkFlags VkVideoEncodeFeedbackFlagsKHR;
typedef enum VkVideoEncodeUsageFlagBitsKHR {
VK_VIDEO_ENCODE_USAGE_DEFAULT_KHR = 0,
VK_VIDEO_ENCODE_USAGE_TRANSCODING_BIT_KHR = 0x00000001,
VK_VIDEO_ENCODE_USAGE_STREAMING_BIT_KHR = 0x00000002,
VK_VIDEO_ENCODE_USAGE_RECORDING_BIT_KHR = 0x00000004,
VK_VIDEO_ENCODE_USAGE_CONFERENCING_BIT_KHR = 0x00000008,
VK_VIDEO_ENCODE_USAGE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
} VkVideoEncodeUsageFlagBitsKHR;
typedef VkFlags VkVideoEncodeUsageFlagsKHR;
typedef enum VkVideoEncodeContentFlagBitsKHR {
VK_VIDEO_ENCODE_CONTENT_DEFAULT_KHR = 0,
VK_VIDEO_ENCODE_CONTENT_CAMERA_BIT_KHR = 0x00000001,
VK_VIDEO_ENCODE_CONTENT_DESKTOP_BIT_KHR = 0x00000002,
VK_VIDEO_ENCODE_CONTENT_RENDERED_BIT_KHR = 0x00000004,
VK_VIDEO_ENCODE_CONTENT_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
} VkVideoEncodeContentFlagBitsKHR;
typedef VkFlags VkVideoEncodeContentFlagsKHR;
typedef VkFlags VkVideoEncodeRateControlFlagsKHR;
typedef struct VkVideoEncodeInfoKHR {
VkStructureType sType;
const void* pNext;
VkVideoEncodeFlagsKHR flags;
uint32_t qualityLevel;
VkBuffer dstBuffer;
VkDeviceSize dstBufferOffset;
VkDeviceSize dstBufferRange;
VkVideoPictureResourceInfoKHR srcPictureResource;
const VkVideoReferenceSlotInfoKHR* pSetupReferenceSlot;
uint32_t referenceSlotCount;
const VkVideoReferenceSlotInfoKHR* pReferenceSlots;
uint32_t precedingExternallyEncodedBytes;
} VkVideoEncodeInfoKHR;
typedef struct VkVideoEncodeCapabilitiesKHR {
VkStructureType sType;
void* pNext;
VkVideoEncodeCapabilityFlagsKHR flags;
VkVideoEncodeRateControlModeFlagsKHR rateControlModes;
uint32_t maxRateControlLayers;
uint32_t maxQualityLevels;
VkExtent2D inputImageDataFillAlignment;
VkVideoEncodeFeedbackFlagsKHR supportedEncodeFeedbackFlags;
} VkVideoEncodeCapabilitiesKHR;
typedef struct VkQueryPoolVideoEncodeFeedbackCreateInfoKHR {
VkStructureType sType;
const void* pNext;
VkVideoEncodeFeedbackFlagsKHR encodeFeedbackFlags;
} VkQueryPoolVideoEncodeFeedbackCreateInfoKHR;
typedef struct VkVideoEncodeUsageInfoKHR {
VkStructureType sType;
const void* pNext;
VkVideoEncodeUsageFlagsKHR videoUsageHints;
VkVideoEncodeContentFlagsKHR videoContentHints;
VkVideoEncodeTuningModeKHR tuningMode;
} VkVideoEncodeUsageInfoKHR;
typedef struct VkVideoEncodeRateControlLayerInfoKHR {
VkStructureType sType;
const void* pNext;
uint64_t averageBitrate;
uint64_t maxBitrate;
uint32_t frameRateNumerator;
uint32_t frameRateDenominator;
uint32_t virtualBufferSizeInMs;
uint32_t initialVirtualBufferSizeInMs;
} VkVideoEncodeRateControlLayerInfoKHR;
typedef struct VkVideoEncodeRateControlInfoKHR {
VkStructureType sType;
const void* pNext;
VkVideoEncodeRateControlFlagsKHR flags;
VkVideoEncodeRateControlModeFlagBitsKHR rateControlMode;
uint32_t layerCount;
const VkVideoEncodeRateControlLayerInfoKHR* pLayers;
} VkVideoEncodeRateControlInfoKHR;
typedef void (VKAPI_PTR *PFN_vkCmdEncodeVideoKHR)(VkCommandBuffer commandBuffer, const VkVideoEncodeInfoKHR* pEncodeInfo);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR void VKAPI_CALL vkCmdEncodeVideoKHR(
VkCommandBuffer commandBuffer,
const VkVideoEncodeInfoKHR* pEncodeInfo);
#endif
#define VK_EXT_video_encode_h264 1
#include "vk_video/vulkan_video_codec_h264std.h"
#include "vk_video/vulkan_video_codec_h264std_encode.h"
#define VK_EXT_VIDEO_ENCODE_H264_SPEC_VERSION 10
#define VK_EXT_VIDEO_ENCODE_H264_EXTENSION_NAME "VK_EXT_video_encode_h264"
typedef enum VkVideoEncodeH264RateControlStructureEXT {
VK_VIDEO_ENCODE_H264_RATE_CONTROL_STRUCTURE_UNKNOWN_EXT = 0,
VK_VIDEO_ENCODE_H264_RATE_CONTROL_STRUCTURE_FLAT_EXT = 1,
VK_VIDEO_ENCODE_H264_RATE_CONTROL_STRUCTURE_DYADIC_EXT = 2,
VK_VIDEO_ENCODE_H264_RATE_CONTROL_STRUCTURE_MAX_ENUM_EXT = 0x7FFFFFFF
} VkVideoEncodeH264RateControlStructureEXT;
typedef enum VkVideoEncodeH264CapabilityFlagBitsEXT {
VK_VIDEO_ENCODE_H264_CAPABILITY_DIRECT_8X8_INFERENCE_ENABLED_BIT_EXT = 0x00000001,
VK_VIDEO_ENCODE_H264_CAPABILITY_DIRECT_8X8_INFERENCE_DISABLED_BIT_EXT = 0x00000002,
VK_VIDEO_ENCODE_H264_CAPABILITY_SEPARATE_COLOUR_PLANE_BIT_EXT = 0x00000004,
VK_VIDEO_ENCODE_H264_CAPABILITY_QPPRIME_Y_ZERO_TRANSFORM_BYPASS_BIT_EXT = 0x00000008,
VK_VIDEO_ENCODE_H264_CAPABILITY_SCALING_LISTS_BIT_EXT = 0x00000010,
VK_VIDEO_ENCODE_H264_CAPABILITY_HRD_COMPLIANCE_BIT_EXT = 0x00000020,
VK_VIDEO_ENCODE_H264_CAPABILITY_CHROMA_QP_OFFSET_BIT_EXT = 0x00000040,
VK_VIDEO_ENCODE_H264_CAPABILITY_SECOND_CHROMA_QP_OFFSET_BIT_EXT = 0x00000080,
VK_VIDEO_ENCODE_H264_CAPABILITY_PIC_INIT_QP_MINUS26_BIT_EXT = 0x00000100,
VK_VIDEO_ENCODE_H264_CAPABILITY_WEIGHTED_PRED_BIT_EXT = 0x00000200,
VK_VIDEO_ENCODE_H264_CAPABILITY_WEIGHTED_BIPRED_EXPLICIT_BIT_EXT = 0x00000400,
VK_VIDEO_ENCODE_H264_CAPABILITY_WEIGHTED_BIPRED_IMPLICIT_BIT_EXT = 0x00000800,
VK_VIDEO_ENCODE_H264_CAPABILITY_WEIGHTED_PRED_NO_TABLE_BIT_EXT = 0x00001000,
VK_VIDEO_ENCODE_H264_CAPABILITY_TRANSFORM_8X8_BIT_EXT = 0x00002000,
VK_VIDEO_ENCODE_H264_CAPABILITY_CABAC_BIT_EXT = 0x00004000,
VK_VIDEO_ENCODE_H264_CAPABILITY_CAVLC_BIT_EXT = 0x00008000,
VK_VIDEO_ENCODE_H264_CAPABILITY_DEBLOCKING_FILTER_DISABLED_BIT_EXT = 0x00010000,
VK_VIDEO_ENCODE_H264_CAPABILITY_DEBLOCKING_FILTER_ENABLED_BIT_EXT = 0x00020000,
VK_VIDEO_ENCODE_H264_CAPABILITY_DEBLOCKING_FILTER_PARTIAL_BIT_EXT = 0x00040000,
VK_VIDEO_ENCODE_H264_CAPABILITY_DISABLE_DIRECT_SPATIAL_MV_PRED_BIT_EXT = 0x00080000,
VK_VIDEO_ENCODE_H264_CAPABILITY_MULTIPLE_SLICE_PER_FRAME_BIT_EXT = 0x00100000,
VK_VIDEO_ENCODE_H264_CAPABILITY_SLICE_MB_COUNT_BIT_EXT = 0x00200000,
VK_VIDEO_ENCODE_H264_CAPABILITY_ROW_UNALIGNED_SLICE_BIT_EXT = 0x00400000,
VK_VIDEO_ENCODE_H264_CAPABILITY_DIFFERENT_SLICE_TYPE_BIT_EXT = 0x00800000,
VK_VIDEO_ENCODE_H264_CAPABILITY_B_FRAME_IN_L1_LIST_BIT_EXT = 0x01000000,
VK_VIDEO_ENCODE_H264_CAPABILITY_DIFFERENT_REFERENCE_FINAL_LISTS_BIT_EXT = 0x02000000,
VK_VIDEO_ENCODE_H264_CAPABILITY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
} VkVideoEncodeH264CapabilityFlagBitsEXT;
typedef VkFlags VkVideoEncodeH264CapabilityFlagsEXT;
typedef struct VkVideoEncodeH264CapabilitiesEXT {
VkStructureType sType;
void* pNext;
VkVideoEncodeH264CapabilityFlagsEXT flags;
uint32_t maxPPictureL0ReferenceCount;
uint32_t maxBPictureL0ReferenceCount;
uint32_t maxL1ReferenceCount;
VkBool32 motionVectorsOverPicBoundariesFlag;
uint32_t maxBytesPerPicDenom;
uint32_t maxBitsPerMbDenom;
uint32_t log2MaxMvLengthHorizontal;
uint32_t log2MaxMvLengthVertical;
} VkVideoEncodeH264CapabilitiesEXT;
typedef struct VkVideoEncodeH264SessionParametersAddInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t stdSPSCount;
const StdVideoH264SequenceParameterSet* pStdSPSs;
uint32_t stdPPSCount;
const StdVideoH264PictureParameterSet* pStdPPSs;
} VkVideoEncodeH264SessionParametersAddInfoEXT;
typedef struct VkVideoEncodeH264SessionParametersCreateInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t maxStdSPSCount;
uint32_t maxStdPPSCount;
const VkVideoEncodeH264SessionParametersAddInfoEXT* pParametersAddInfo;
} VkVideoEncodeH264SessionParametersCreateInfoEXT;
typedef struct VkVideoEncodeH264NaluSliceInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t mbCount;
const StdVideoEncodeH264ReferenceListsInfo* pStdReferenceFinalLists;
const StdVideoEncodeH264SliceHeader* pStdSliceHeader;
} VkVideoEncodeH264NaluSliceInfoEXT;
typedef struct VkVideoEncodeH264VclFrameInfoEXT {
VkStructureType sType;
const void* pNext;
const StdVideoEncodeH264ReferenceListsInfo* pStdReferenceFinalLists;
uint32_t naluSliceEntryCount;
const VkVideoEncodeH264NaluSliceInfoEXT* pNaluSliceEntries;
const StdVideoEncodeH264PictureInfo* pStdPictureInfo;
} VkVideoEncodeH264VclFrameInfoEXT;
typedef struct VkVideoEncodeH264DpbSlotInfoEXT {
VkStructureType sType;
const void* pNext;
const StdVideoEncodeH264ReferenceInfo* pStdReferenceInfo;
} VkVideoEncodeH264DpbSlotInfoEXT;
typedef struct VkVideoEncodeH264ProfileInfoEXT {
VkStructureType sType;
const void* pNext;
StdVideoH264ProfileIdc stdProfileIdc;
} VkVideoEncodeH264ProfileInfoEXT;
typedef struct VkVideoEncodeH264RateControlInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t gopFrameCount;
uint32_t idrPeriod;
uint32_t consecutiveBFrameCount;
VkVideoEncodeH264RateControlStructureEXT rateControlStructure;
uint32_t temporalLayerCount;
} VkVideoEncodeH264RateControlInfoEXT;
typedef struct VkVideoEncodeH264QpEXT {
int32_t qpI;
int32_t qpP;
int32_t qpB;
} VkVideoEncodeH264QpEXT;
typedef struct VkVideoEncodeH264FrameSizeEXT {
uint32_t frameISize;
uint32_t framePSize;
uint32_t frameBSize;
} VkVideoEncodeH264FrameSizeEXT;
typedef struct VkVideoEncodeH264RateControlLayerInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t temporalLayerId;
VkBool32 useInitialRcQp;
VkVideoEncodeH264QpEXT initialRcQp;
VkBool32 useMinQp;
VkVideoEncodeH264QpEXT minQp;
VkBool32 useMaxQp;
VkVideoEncodeH264QpEXT maxQp;
VkBool32 useMaxFrameSize;
VkVideoEncodeH264FrameSizeEXT maxFrameSize;
} VkVideoEncodeH264RateControlLayerInfoEXT;
#define VK_EXT_video_encode_h265 1
#include "vk_video/vulkan_video_codec_h265std.h"
#include "vk_video/vulkan_video_codec_h265std_encode.h"
#define VK_EXT_VIDEO_ENCODE_H265_SPEC_VERSION 10
#define VK_EXT_VIDEO_ENCODE_H265_EXTENSION_NAME "VK_EXT_video_encode_h265"
typedef enum VkVideoEncodeH265RateControlStructureEXT {
VK_VIDEO_ENCODE_H265_RATE_CONTROL_STRUCTURE_UNKNOWN_EXT = 0,
VK_VIDEO_ENCODE_H265_RATE_CONTROL_STRUCTURE_FLAT_EXT = 1,
VK_VIDEO_ENCODE_H265_RATE_CONTROL_STRUCTURE_DYADIC_EXT = 2,
VK_VIDEO_ENCODE_H265_RATE_CONTROL_STRUCTURE_MAX_ENUM_EXT = 0x7FFFFFFF
} VkVideoEncodeH265RateControlStructureEXT;
typedef enum VkVideoEncodeH265CapabilityFlagBitsEXT {
VK_VIDEO_ENCODE_H265_CAPABILITY_SEPARATE_COLOUR_PLANE_BIT_EXT = 0x00000001,
VK_VIDEO_ENCODE_H265_CAPABILITY_SCALING_LISTS_BIT_EXT = 0x00000002,
VK_VIDEO_ENCODE_H265_CAPABILITY_SAMPLE_ADAPTIVE_OFFSET_ENABLED_BIT_EXT = 0x00000004,
VK_VIDEO_ENCODE_H265_CAPABILITY_PCM_ENABLE_BIT_EXT = 0x00000008,
VK_VIDEO_ENCODE_H265_CAPABILITY_SPS_TEMPORAL_MVP_ENABLED_BIT_EXT = 0x00000010,
VK_VIDEO_ENCODE_H265_CAPABILITY_HRD_COMPLIANCE_BIT_EXT = 0x00000020,
VK_VIDEO_ENCODE_H265_CAPABILITY_INIT_QP_MINUS26_BIT_EXT = 0x00000040,
VK_VIDEO_ENCODE_H265_CAPABILITY_LOG2_PARALLEL_MERGE_LEVEL_MINUS2_BIT_EXT = 0x00000080,
VK_VIDEO_ENCODE_H265_CAPABILITY_SIGN_DATA_HIDING_ENABLED_BIT_EXT = 0x00000100,
VK_VIDEO_ENCODE_H265_CAPABILITY_TRANSFORM_SKIP_ENABLED_BIT_EXT = 0x00000200,
VK_VIDEO_ENCODE_H265_CAPABILITY_TRANSFORM_SKIP_DISABLED_BIT_EXT = 0x00000400,
VK_VIDEO_ENCODE_H265_CAPABILITY_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT_BIT_EXT = 0x00000800,
VK_VIDEO_ENCODE_H265_CAPABILITY_WEIGHTED_PRED_BIT_EXT = 0x00001000,
VK_VIDEO_ENCODE_H265_CAPABILITY_WEIGHTED_BIPRED_BIT_EXT = 0x00002000,
VK_VIDEO_ENCODE_H265_CAPABILITY_WEIGHTED_PRED_NO_TABLE_BIT_EXT = 0x00004000,
VK_VIDEO_ENCODE_H265_CAPABILITY_TRANSQUANT_BYPASS_ENABLED_BIT_EXT = 0x00008000,
VK_VIDEO_ENCODE_H265_CAPABILITY_ENTROPY_CODING_SYNC_ENABLED_BIT_EXT = 0x00010000,
VK_VIDEO_ENCODE_H265_CAPABILITY_DEBLOCKING_FILTER_OVERRIDE_ENABLED_BIT_EXT = 0x00020000,
VK_VIDEO_ENCODE_H265_CAPABILITY_MULTIPLE_TILE_PER_FRAME_BIT_EXT = 0x00040000,
VK_VIDEO_ENCODE_H265_CAPABILITY_MULTIPLE_SLICE_PER_TILE_BIT_EXT = 0x00080000,
VK_VIDEO_ENCODE_H265_CAPABILITY_MULTIPLE_TILE_PER_SLICE_BIT_EXT = 0x00100000,
VK_VIDEO_ENCODE_H265_CAPABILITY_SLICE_SEGMENT_CTB_COUNT_BIT_EXT = 0x00200000,
VK_VIDEO_ENCODE_H265_CAPABILITY_ROW_UNALIGNED_SLICE_SEGMENT_BIT_EXT = 0x00400000,
VK_VIDEO_ENCODE_H265_CAPABILITY_DEPENDENT_SLICE_SEGMENT_BIT_EXT = 0x00800000,
VK_VIDEO_ENCODE_H265_CAPABILITY_DIFFERENT_SLICE_TYPE_BIT_EXT = 0x01000000,
VK_VIDEO_ENCODE_H265_CAPABILITY_B_FRAME_IN_L1_LIST_BIT_EXT = 0x02000000,
VK_VIDEO_ENCODE_H265_CAPABILITY_DIFFERENT_REFERENCE_FINAL_LISTS_BIT_EXT = 0x04000000,
VK_VIDEO_ENCODE_H265_CAPABILITY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
} VkVideoEncodeH265CapabilityFlagBitsEXT;
typedef VkFlags VkVideoEncodeH265CapabilityFlagsEXT;
typedef enum VkVideoEncodeH265CtbSizeFlagBitsEXT {
VK_VIDEO_ENCODE_H265_CTB_SIZE_16_BIT_EXT = 0x00000001,
VK_VIDEO_ENCODE_H265_CTB_SIZE_32_BIT_EXT = 0x00000002,
VK_VIDEO_ENCODE_H265_CTB_SIZE_64_BIT_EXT = 0x00000004,
VK_VIDEO_ENCODE_H265_CTB_SIZE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
} VkVideoEncodeH265CtbSizeFlagBitsEXT;
typedef VkFlags VkVideoEncodeH265CtbSizeFlagsEXT;
typedef enum VkVideoEncodeH265TransformBlockSizeFlagBitsEXT {
VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_4_BIT_EXT = 0x00000001,
VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_8_BIT_EXT = 0x00000002,
VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_16_BIT_EXT = 0x00000004,
VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_32_BIT_EXT = 0x00000008,
VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
} VkVideoEncodeH265TransformBlockSizeFlagBitsEXT;
typedef VkFlags VkVideoEncodeH265TransformBlockSizeFlagsEXT;
typedef struct VkVideoEncodeH265CapabilitiesEXT {
VkStructureType sType;
void* pNext;
VkVideoEncodeH265CapabilityFlagsEXT flags;
VkVideoEncodeH265CtbSizeFlagsEXT ctbSizes;
VkVideoEncodeH265TransformBlockSizeFlagsEXT transformBlockSizes;
uint32_t maxPPictureL0ReferenceCount;
uint32_t maxBPictureL0ReferenceCount;
uint32_t maxL1ReferenceCount;
uint32_t maxSubLayersCount;
uint32_t minLog2MinLumaCodingBlockSizeMinus3;
uint32_t maxLog2MinLumaCodingBlockSizeMinus3;
uint32_t minLog2MinLumaTransformBlockSizeMinus2;
uint32_t maxLog2MinLumaTransformBlockSizeMinus2;
uint32_t minMaxTransformHierarchyDepthInter;
uint32_t maxMaxTransformHierarchyDepthInter;
uint32_t minMaxTransformHierarchyDepthIntra;
uint32_t maxMaxTransformHierarchyDepthIntra;
uint32_t maxDiffCuQpDeltaDepth;
uint32_t minMaxNumMergeCand;
uint32_t maxMaxNumMergeCand;
} VkVideoEncodeH265CapabilitiesEXT;
typedef struct VkVideoEncodeH265SessionParametersAddInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t stdVPSCount;
const StdVideoH265VideoParameterSet* pStdVPSs;
uint32_t stdSPSCount;
const StdVideoH265SequenceParameterSet* pStdSPSs;
uint32_t stdPPSCount;
const StdVideoH265PictureParameterSet* pStdPPSs;
} VkVideoEncodeH265SessionParametersAddInfoEXT;
typedef struct VkVideoEncodeH265SessionParametersCreateInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t maxStdVPSCount;
uint32_t maxStdSPSCount;
uint32_t maxStdPPSCount;
const VkVideoEncodeH265SessionParametersAddInfoEXT* pParametersAddInfo;
} VkVideoEncodeH265SessionParametersCreateInfoEXT;
typedef struct VkVideoEncodeH265NaluSliceSegmentInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t ctbCount;
const StdVideoEncodeH265ReferenceListsInfo* pStdReferenceFinalLists;
const StdVideoEncodeH265SliceSegmentHeader* pStdSliceSegmentHeader;
} VkVideoEncodeH265NaluSliceSegmentInfoEXT;
typedef struct VkVideoEncodeH265VclFrameInfoEXT {
VkStructureType sType;
const void* pNext;
const StdVideoEncodeH265ReferenceListsInfo* pStdReferenceFinalLists;
uint32_t naluSliceSegmentEntryCount;
const VkVideoEncodeH265NaluSliceSegmentInfoEXT* pNaluSliceSegmentEntries;
const StdVideoEncodeH265PictureInfo* pStdPictureInfo;
} VkVideoEncodeH265VclFrameInfoEXT;
typedef struct VkVideoEncodeH265DpbSlotInfoEXT {
VkStructureType sType;
const void* pNext;
const StdVideoEncodeH265ReferenceInfo* pStdReferenceInfo;
} VkVideoEncodeH265DpbSlotInfoEXT;
typedef struct VkVideoEncodeH265ProfileInfoEXT {
VkStructureType sType;
const void* pNext;
StdVideoH265ProfileIdc stdProfileIdc;
} VkVideoEncodeH265ProfileInfoEXT;
typedef struct VkVideoEncodeH265RateControlInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t gopFrameCount;
uint32_t idrPeriod;
uint32_t consecutiveBFrameCount;
VkVideoEncodeH265RateControlStructureEXT rateControlStructure;
uint32_t subLayerCount;
} VkVideoEncodeH265RateControlInfoEXT;
typedef struct VkVideoEncodeH265QpEXT {
int32_t qpI;
int32_t qpP;
int32_t qpB;
} VkVideoEncodeH265QpEXT;
typedef struct VkVideoEncodeH265FrameSizeEXT {
uint32_t frameISize;
uint32_t framePSize;
uint32_t frameBSize;
} VkVideoEncodeH265FrameSizeEXT;
typedef struct VkVideoEncodeH265RateControlLayerInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t temporalId;
VkBool32 useInitialRcQp;
VkVideoEncodeH265QpEXT initialRcQp;
VkBool32 useMinQp;
VkVideoEncodeH265QpEXT minQp;
VkBool32 useMaxQp;
VkVideoEncodeH265QpEXT maxQp;
VkBool32 useMaxFrameSize;
VkVideoEncodeH265FrameSizeEXT maxFrameSize;
} VkVideoEncodeH265RateControlLayerInfoEXT;
#ifdef __cplusplus
}
#endif
#endif
+1796 -10278
View File
File diff suppressed because it is too large Load Diff
-54
View File
@@ -1,54 +0,0 @@
#ifndef VULKAN_DIRECTFB_H_
#define VULKAN_DIRECTFB_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
/*
** This header is generated from the Khronos Vulkan XML API Registry.
**
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_EXT_directfb_surface 1
#define VK_EXT_DIRECTFB_SURFACE_SPEC_VERSION 1
#define VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME "VK_EXT_directfb_surface"
typedef VkFlags VkDirectFBSurfaceCreateFlagsEXT;
typedef struct VkDirectFBSurfaceCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkDirectFBSurfaceCreateFlagsEXT flags;
IDirectFB* dfb;
IDirectFBSurface* surface;
} VkDirectFBSurfaceCreateInfoEXT;
typedef VkResult (VKAPI_PTR *PFN_vkCreateDirectFBSurfaceEXT)(VkInstance instance, const VkDirectFBSurfaceCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceDirectFBPresentationSupportEXT)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, IDirectFB* dfb);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkCreateDirectFBSurfaceEXT(
VkInstance instance,
const VkDirectFBSurfaceCreateInfoEXT* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceDirectFBPresentationSupportEXT(
VkPhysicalDevice physicalDevice,
uint32_t queueFamilyIndex,
IDirectFB* dfb);
#endif
#ifdef __cplusplus
}
#endif
#endif
+19 -219
View File
@@ -1,10 +1,24 @@
#ifndef VULKAN_FUCHSIA_H_
#define VULKAN_FUCHSIA_H_ 1
#ifdef __cplusplus
extern "C" {
#endif
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright (c) 2015-2018 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
** 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.
*/
/*
@@ -13,16 +27,12 @@
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_FUCHSIA_imagepipe_surface 1
#define VK_FUCHSIA_IMAGEPIPE_SURFACE_SPEC_VERSION 1
#define VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME "VK_FUCHSIA_imagepipe_surface"
typedef VkFlags VkImagePipeSurfaceCreateFlagsFUCHSIA;
typedef struct VkImagePipeSurfaceCreateInfoFUCHSIA {
VkStructureType sType;
const void* pNext;
@@ -30,6 +40,7 @@ typedef struct VkImagePipeSurfaceCreateInfoFUCHSIA {
zx_handle_t imagePipeHandle;
} VkImagePipeSurfaceCreateInfoFUCHSIA;
typedef VkResult (VKAPI_PTR *PFN_vkCreateImagePipeSurfaceFUCHSIA)(VkInstance instance, const VkImagePipeSurfaceCreateInfoFUCHSIA* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
#ifndef VK_NO_PROTOTYPES
@@ -40,217 +51,6 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateImagePipeSurfaceFUCHSIA(
VkSurfaceKHR* pSurface);
#endif
#define VK_FUCHSIA_external_memory 1
#define VK_FUCHSIA_EXTERNAL_MEMORY_SPEC_VERSION 1
#define VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME "VK_FUCHSIA_external_memory"
typedef struct VkImportMemoryZirconHandleInfoFUCHSIA {
VkStructureType sType;
const void* pNext;
VkExternalMemoryHandleTypeFlagBits handleType;
zx_handle_t handle;
} VkImportMemoryZirconHandleInfoFUCHSIA;
typedef struct VkMemoryZirconHandlePropertiesFUCHSIA {
VkStructureType sType;
void* pNext;
uint32_t memoryTypeBits;
} VkMemoryZirconHandlePropertiesFUCHSIA;
typedef struct VkMemoryGetZirconHandleInfoFUCHSIA {
VkStructureType sType;
const void* pNext;
VkDeviceMemory memory;
VkExternalMemoryHandleTypeFlagBits handleType;
} VkMemoryGetZirconHandleInfoFUCHSIA;
typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryZirconHandleFUCHSIA)(VkDevice device, const VkMemoryGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo, zx_handle_t* pZirconHandle);
typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryZirconHandlePropertiesFUCHSIA)(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, zx_handle_t zirconHandle, VkMemoryZirconHandlePropertiesFUCHSIA* pMemoryZirconHandleProperties);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryZirconHandleFUCHSIA(
VkDevice device,
const VkMemoryGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo,
zx_handle_t* pZirconHandle);
VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryZirconHandlePropertiesFUCHSIA(
VkDevice device,
VkExternalMemoryHandleTypeFlagBits handleType,
zx_handle_t zirconHandle,
VkMemoryZirconHandlePropertiesFUCHSIA* pMemoryZirconHandleProperties);
#endif
#define VK_FUCHSIA_external_semaphore 1
#define VK_FUCHSIA_EXTERNAL_SEMAPHORE_SPEC_VERSION 1
#define VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME "VK_FUCHSIA_external_semaphore"
typedef struct VkImportSemaphoreZirconHandleInfoFUCHSIA {
VkStructureType sType;
const void* pNext;
VkSemaphore semaphore;
VkSemaphoreImportFlags flags;
VkExternalSemaphoreHandleTypeFlagBits handleType;
zx_handle_t zirconHandle;
} VkImportSemaphoreZirconHandleInfoFUCHSIA;
typedef struct VkSemaphoreGetZirconHandleInfoFUCHSIA {
VkStructureType sType;
const void* pNext;
VkSemaphore semaphore;
VkExternalSemaphoreHandleTypeFlagBits handleType;
} VkSemaphoreGetZirconHandleInfoFUCHSIA;
typedef VkResult (VKAPI_PTR *PFN_vkImportSemaphoreZirconHandleFUCHSIA)(VkDevice device, const VkImportSemaphoreZirconHandleInfoFUCHSIA* pImportSemaphoreZirconHandleInfo);
typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreZirconHandleFUCHSIA)(VkDevice device, const VkSemaphoreGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo, zx_handle_t* pZirconHandle);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkImportSemaphoreZirconHandleFUCHSIA(
VkDevice device,
const VkImportSemaphoreZirconHandleInfoFUCHSIA* pImportSemaphoreZirconHandleInfo);
VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreZirconHandleFUCHSIA(
VkDevice device,
const VkSemaphoreGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo,
zx_handle_t* pZirconHandle);
#endif
#define VK_FUCHSIA_buffer_collection 1
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBufferCollectionFUCHSIA)
#define VK_FUCHSIA_BUFFER_COLLECTION_SPEC_VERSION 2
#define VK_FUCHSIA_BUFFER_COLLECTION_EXTENSION_NAME "VK_FUCHSIA_buffer_collection"
typedef VkFlags VkImageFormatConstraintsFlagsFUCHSIA;
typedef enum VkImageConstraintsInfoFlagBitsFUCHSIA {
VK_IMAGE_CONSTRAINTS_INFO_CPU_READ_RARELY_FUCHSIA = 0x00000001,
VK_IMAGE_CONSTRAINTS_INFO_CPU_READ_OFTEN_FUCHSIA = 0x00000002,
VK_IMAGE_CONSTRAINTS_INFO_CPU_WRITE_RARELY_FUCHSIA = 0x00000004,
VK_IMAGE_CONSTRAINTS_INFO_CPU_WRITE_OFTEN_FUCHSIA = 0x00000008,
VK_IMAGE_CONSTRAINTS_INFO_PROTECTED_OPTIONAL_FUCHSIA = 0x00000010,
VK_IMAGE_CONSTRAINTS_INFO_FLAG_BITS_MAX_ENUM_FUCHSIA = 0x7FFFFFFF
} VkImageConstraintsInfoFlagBitsFUCHSIA;
typedef VkFlags VkImageConstraintsInfoFlagsFUCHSIA;
typedef struct VkBufferCollectionCreateInfoFUCHSIA {
VkStructureType sType;
const void* pNext;
zx_handle_t collectionToken;
} VkBufferCollectionCreateInfoFUCHSIA;
typedef struct VkImportMemoryBufferCollectionFUCHSIA {
VkStructureType sType;
const void* pNext;
VkBufferCollectionFUCHSIA collection;
uint32_t index;
} VkImportMemoryBufferCollectionFUCHSIA;
typedef struct VkBufferCollectionImageCreateInfoFUCHSIA {
VkStructureType sType;
const void* pNext;
VkBufferCollectionFUCHSIA collection;
uint32_t index;
} VkBufferCollectionImageCreateInfoFUCHSIA;
typedef struct VkBufferCollectionConstraintsInfoFUCHSIA {
VkStructureType sType;
const void* pNext;
uint32_t minBufferCount;
uint32_t maxBufferCount;
uint32_t minBufferCountForCamping;
uint32_t minBufferCountForDedicatedSlack;
uint32_t minBufferCountForSharedSlack;
} VkBufferCollectionConstraintsInfoFUCHSIA;
typedef struct VkBufferConstraintsInfoFUCHSIA {
VkStructureType sType;
const void* pNext;
VkBufferCreateInfo createInfo;
VkFormatFeatureFlags requiredFormatFeatures;
VkBufferCollectionConstraintsInfoFUCHSIA bufferCollectionConstraints;
} VkBufferConstraintsInfoFUCHSIA;
typedef struct VkBufferCollectionBufferCreateInfoFUCHSIA {
VkStructureType sType;
const void* pNext;
VkBufferCollectionFUCHSIA collection;
uint32_t index;
} VkBufferCollectionBufferCreateInfoFUCHSIA;
typedef struct VkSysmemColorSpaceFUCHSIA {
VkStructureType sType;
const void* pNext;
uint32_t colorSpace;
} VkSysmemColorSpaceFUCHSIA;
typedef struct VkBufferCollectionPropertiesFUCHSIA {
VkStructureType sType;
void* pNext;
uint32_t memoryTypeBits;
uint32_t bufferCount;
uint32_t createInfoIndex;
uint64_t sysmemPixelFormat;
VkFormatFeatureFlags formatFeatures;
VkSysmemColorSpaceFUCHSIA sysmemColorSpaceIndex;
VkComponentMapping samplerYcbcrConversionComponents;
VkSamplerYcbcrModelConversion suggestedYcbcrModel;
VkSamplerYcbcrRange suggestedYcbcrRange;
VkChromaLocation suggestedXChromaOffset;
VkChromaLocation suggestedYChromaOffset;
} VkBufferCollectionPropertiesFUCHSIA;
typedef struct VkImageFormatConstraintsInfoFUCHSIA {
VkStructureType sType;
const void* pNext;
VkImageCreateInfo imageCreateInfo;
VkFormatFeatureFlags requiredFormatFeatures;
VkImageFormatConstraintsFlagsFUCHSIA flags;
uint64_t sysmemPixelFormat;
uint32_t colorSpaceCount;
const VkSysmemColorSpaceFUCHSIA* pColorSpaces;
} VkImageFormatConstraintsInfoFUCHSIA;
typedef struct VkImageConstraintsInfoFUCHSIA {
VkStructureType sType;
const void* pNext;
uint32_t formatConstraintsCount;
const VkImageFormatConstraintsInfoFUCHSIA* pFormatConstraints;
VkBufferCollectionConstraintsInfoFUCHSIA bufferCollectionConstraints;
VkImageConstraintsInfoFlagsFUCHSIA flags;
} VkImageConstraintsInfoFUCHSIA;
typedef VkResult (VKAPI_PTR *PFN_vkCreateBufferCollectionFUCHSIA)(VkDevice device, const VkBufferCollectionCreateInfoFUCHSIA* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBufferCollectionFUCHSIA* pCollection);
typedef VkResult (VKAPI_PTR *PFN_vkSetBufferCollectionImageConstraintsFUCHSIA)(VkDevice device, VkBufferCollectionFUCHSIA collection, const VkImageConstraintsInfoFUCHSIA* pImageConstraintsInfo);
typedef VkResult (VKAPI_PTR *PFN_vkSetBufferCollectionBufferConstraintsFUCHSIA)(VkDevice device, VkBufferCollectionFUCHSIA collection, const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo);
typedef void (VKAPI_PTR *PFN_vkDestroyBufferCollectionFUCHSIA)(VkDevice device, VkBufferCollectionFUCHSIA collection, const VkAllocationCallbacks* pAllocator);
typedef VkResult (VKAPI_PTR *PFN_vkGetBufferCollectionPropertiesFUCHSIA)(VkDevice device, VkBufferCollectionFUCHSIA collection, VkBufferCollectionPropertiesFUCHSIA* pProperties);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkCreateBufferCollectionFUCHSIA(
VkDevice device,
const VkBufferCollectionCreateInfoFUCHSIA* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkBufferCollectionFUCHSIA* pCollection);
VKAPI_ATTR VkResult VKAPI_CALL vkSetBufferCollectionImageConstraintsFUCHSIA(
VkDevice device,
VkBufferCollectionFUCHSIA collection,
const VkImageConstraintsInfoFUCHSIA* pImageConstraintsInfo);
VKAPI_ATTR VkResult VKAPI_CALL vkSetBufferCollectionBufferConstraintsFUCHSIA(
VkDevice device,
VkBufferCollectionFUCHSIA collection,
const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo);
VKAPI_ATTR void VKAPI_CALL vkDestroyBufferCollectionFUCHSIA(
VkDevice device,
VkBufferCollectionFUCHSIA collection,
const VkAllocationCallbacks* pAllocator);
VKAPI_ATTR VkResult VKAPI_CALL vkGetBufferCollectionPropertiesFUCHSIA(
VkDevice device,
VkBufferCollectionFUCHSIA collection,
VkBufferCollectionPropertiesFUCHSIA* pProperties);
#endif
#ifdef __cplusplus
}
#endif
-58
View File
@@ -1,58 +0,0 @@
#ifndef VULKAN_GGP_H_
#define VULKAN_GGP_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
/*
** This header is generated from the Khronos Vulkan XML API Registry.
**
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_GGP_stream_descriptor_surface 1
#define VK_GGP_STREAM_DESCRIPTOR_SURFACE_SPEC_VERSION 1
#define VK_GGP_STREAM_DESCRIPTOR_SURFACE_EXTENSION_NAME "VK_GGP_stream_descriptor_surface"
typedef VkFlags VkStreamDescriptorSurfaceCreateFlagsGGP;
typedef struct VkStreamDescriptorSurfaceCreateInfoGGP {
VkStructureType sType;
const void* pNext;
VkStreamDescriptorSurfaceCreateFlagsGGP flags;
GgpStreamDescriptor streamDescriptor;
} VkStreamDescriptorSurfaceCreateInfoGGP;
typedef VkResult (VKAPI_PTR *PFN_vkCreateStreamDescriptorSurfaceGGP)(VkInstance instance, const VkStreamDescriptorSurfaceCreateInfoGGP* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkCreateStreamDescriptorSurfaceGGP(
VkInstance instance,
const VkStreamDescriptorSurfaceCreateInfoGGP* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
#endif
#define VK_GGP_frame_token 1
#define VK_GGP_FRAME_TOKEN_SPEC_VERSION 1
#define VK_GGP_FRAME_TOKEN_EXTENSION_NAME "VK_GGP_frame_token"
typedef struct VkPresentFrameTokenGGP {
VkStructureType sType;
const void* pNext;
GgpFrameToken frameToken;
} VkPresentFrameTokenGGP;
#ifdef __cplusplus
}
#endif
#endif
+20 -9
View File
@@ -1,10 +1,24 @@
#ifndef VULKAN_IOS_H_
#define VULKAN_IOS_H_ 1
#ifdef __cplusplus
extern "C" {
#endif
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright (c) 2015-2018 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
** 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.
*/
/*
@@ -13,16 +27,12 @@
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_MVK_ios_surface 1
#define VK_MVK_IOS_SURFACE_SPEC_VERSION 3
#define VK_MVK_IOS_SURFACE_SPEC_VERSION 2
#define VK_MVK_IOS_SURFACE_EXTENSION_NAME "VK_MVK_ios_surface"
typedef VkFlags VkIOSSurfaceCreateFlagsMVK;
typedef struct VkIOSSurfaceCreateInfoMVK {
VkStructureType sType;
const void* pNext;
@@ -30,6 +40,7 @@ typedef struct VkIOSSurfaceCreateInfoMVK {
const void* pView;
} VkIOSSurfaceCreateInfoMVK;
typedef VkResult (VKAPI_PTR *PFN_vkCreateIOSSurfaceMVK)(VkInstance instance, const VkIOSSurfaceCreateInfoMVK* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
#ifndef VK_NO_PROTOTYPES
+20 -9
View File
@@ -1,10 +1,24 @@
#ifndef VULKAN_MACOS_H_
#define VULKAN_MACOS_H_ 1
#ifdef __cplusplus
extern "C" {
#endif
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright (c) 2015-2018 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
** 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.
*/
/*
@@ -13,16 +27,12 @@
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_MVK_macos_surface 1
#define VK_MVK_MACOS_SURFACE_SPEC_VERSION 3
#define VK_MVK_MACOS_SURFACE_SPEC_VERSION 2
#define VK_MVK_MACOS_SURFACE_EXTENSION_NAME "VK_MVK_macos_surface"
typedef VkFlags VkMacOSSurfaceCreateFlagsMVK;
typedef struct VkMacOSSurfaceCreateInfoMVK {
VkStructureType sType;
const void* pNext;
@@ -30,6 +40,7 @@ typedef struct VkMacOSSurfaceCreateInfoMVK {
const void* pView;
} VkMacOSSurfaceCreateInfoMVK;
typedef VkResult (VKAPI_PTR *PFN_vkCreateMacOSSurfaceMVK)(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
#ifndef VK_NO_PROTOTYPES
-193
View File
@@ -1,193 +0,0 @@
#ifndef VULKAN_METAL_H_
#define VULKAN_METAL_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
/*
** This header is generated from the Khronos Vulkan XML API Registry.
**
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_EXT_metal_surface 1
#ifdef __OBJC__
@class CAMetalLayer;
#else
typedef void CAMetalLayer;
#endif
#define VK_EXT_METAL_SURFACE_SPEC_VERSION 1
#define VK_EXT_METAL_SURFACE_EXTENSION_NAME "VK_EXT_metal_surface"
typedef VkFlags VkMetalSurfaceCreateFlagsEXT;
typedef struct VkMetalSurfaceCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkMetalSurfaceCreateFlagsEXT flags;
const CAMetalLayer* pLayer;
} VkMetalSurfaceCreateInfoEXT;
typedef VkResult (VKAPI_PTR *PFN_vkCreateMetalSurfaceEXT)(VkInstance instance, const VkMetalSurfaceCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkCreateMetalSurfaceEXT(
VkInstance instance,
const VkMetalSurfaceCreateInfoEXT* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
#endif
#define VK_EXT_metal_objects 1
#ifdef __OBJC__
@protocol MTLDevice;
typedef id<MTLDevice> MTLDevice_id;
#else
typedef void* MTLDevice_id;
#endif
#ifdef __OBJC__
@protocol MTLCommandQueue;
typedef id<MTLCommandQueue> MTLCommandQueue_id;
#else
typedef void* MTLCommandQueue_id;
#endif
#ifdef __OBJC__
@protocol MTLBuffer;
typedef id<MTLBuffer> MTLBuffer_id;
#else
typedef void* MTLBuffer_id;
#endif
#ifdef __OBJC__
@protocol MTLTexture;
typedef id<MTLTexture> MTLTexture_id;
#else
typedef void* MTLTexture_id;
#endif
typedef struct __IOSurface* IOSurfaceRef;
#ifdef __OBJC__
@protocol MTLSharedEvent;
typedef id<MTLSharedEvent> MTLSharedEvent_id;
#else
typedef void* MTLSharedEvent_id;
#endif
#define VK_EXT_METAL_OBJECTS_SPEC_VERSION 1
#define VK_EXT_METAL_OBJECTS_EXTENSION_NAME "VK_EXT_metal_objects"
typedef enum VkExportMetalObjectTypeFlagBitsEXT {
VK_EXPORT_METAL_OBJECT_TYPE_METAL_DEVICE_BIT_EXT = 0x00000001,
VK_EXPORT_METAL_OBJECT_TYPE_METAL_COMMAND_QUEUE_BIT_EXT = 0x00000002,
VK_EXPORT_METAL_OBJECT_TYPE_METAL_BUFFER_BIT_EXT = 0x00000004,
VK_EXPORT_METAL_OBJECT_TYPE_METAL_TEXTURE_BIT_EXT = 0x00000008,
VK_EXPORT_METAL_OBJECT_TYPE_METAL_IOSURFACE_BIT_EXT = 0x00000010,
VK_EXPORT_METAL_OBJECT_TYPE_METAL_SHARED_EVENT_BIT_EXT = 0x00000020,
VK_EXPORT_METAL_OBJECT_TYPE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
} VkExportMetalObjectTypeFlagBitsEXT;
typedef VkFlags VkExportMetalObjectTypeFlagsEXT;
typedef struct VkExportMetalObjectCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkExportMetalObjectTypeFlagBitsEXT exportObjectType;
} VkExportMetalObjectCreateInfoEXT;
typedef struct VkExportMetalObjectsInfoEXT {
VkStructureType sType;
const void* pNext;
} VkExportMetalObjectsInfoEXT;
typedef struct VkExportMetalDeviceInfoEXT {
VkStructureType sType;
const void* pNext;
MTLDevice_id mtlDevice;
} VkExportMetalDeviceInfoEXT;
typedef struct VkExportMetalCommandQueueInfoEXT {
VkStructureType sType;
const void* pNext;
VkQueue queue;
MTLCommandQueue_id mtlCommandQueue;
} VkExportMetalCommandQueueInfoEXT;
typedef struct VkExportMetalBufferInfoEXT {
VkStructureType sType;
const void* pNext;
VkDeviceMemory memory;
MTLBuffer_id mtlBuffer;
} VkExportMetalBufferInfoEXT;
typedef struct VkImportMetalBufferInfoEXT {
VkStructureType sType;
const void* pNext;
MTLBuffer_id mtlBuffer;
} VkImportMetalBufferInfoEXT;
typedef struct VkExportMetalTextureInfoEXT {
VkStructureType sType;
const void* pNext;
VkImage image;
VkImageView imageView;
VkBufferView bufferView;
VkImageAspectFlagBits plane;
MTLTexture_id mtlTexture;
} VkExportMetalTextureInfoEXT;
typedef struct VkImportMetalTextureInfoEXT {
VkStructureType sType;
const void* pNext;
VkImageAspectFlagBits plane;
MTLTexture_id mtlTexture;
} VkImportMetalTextureInfoEXT;
typedef struct VkExportMetalIOSurfaceInfoEXT {
VkStructureType sType;
const void* pNext;
VkImage image;
IOSurfaceRef ioSurface;
} VkExportMetalIOSurfaceInfoEXT;
typedef struct VkImportMetalIOSurfaceInfoEXT {
VkStructureType sType;
const void* pNext;
IOSurfaceRef ioSurface;
} VkImportMetalIOSurfaceInfoEXT;
typedef struct VkExportMetalSharedEventInfoEXT {
VkStructureType sType;
const void* pNext;
VkSemaphore semaphore;
VkEvent event;
MTLSharedEvent_id mtlSharedEvent;
} VkExportMetalSharedEventInfoEXT;
typedef struct VkImportMetalSharedEventInfoEXT {
VkStructureType sType;
const void* pNext;
MTLSharedEvent_id mtlSharedEvent;
} VkImportMetalSharedEventInfoEXT;
typedef void (VKAPI_PTR *PFN_vkExportMetalObjectsEXT)(VkDevice device, VkExportMetalObjectsInfoEXT* pMetalObjectsInfo);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR void VKAPI_CALL vkExportMetalObjectsEXT(
VkDevice device,
VkExportMetalObjectsInfoEXT* pMetalObjectsInfo);
#endif
#ifdef __cplusplus
}
#endif
#endif
+65
View File
@@ -0,0 +1,65 @@
#ifndef VULKAN_MIR_H_
#define VULKAN_MIR_H_ 1
#ifdef __cplusplus
extern "C" {
#endif
/*
** Copyright (c) 2015-2018 The Khronos Group Inc.
**
** 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.
*/
/*
** This header is generated from the Khronos Vulkan XML API Registry.
**
*/
#define VK_KHR_mir_surface 1
#define VK_KHR_MIR_SURFACE_SPEC_VERSION 4
#define VK_KHR_MIR_SURFACE_EXTENSION_NAME "VK_KHR_mir_surface"
typedef VkFlags VkMirSurfaceCreateFlagsKHR;
typedef struct VkMirSurfaceCreateInfoKHR {
VkStructureType sType;
const void* pNext;
VkMirSurfaceCreateFlagsKHR flags;
MirConnection* connection;
MirSurface* mirSurface;
} VkMirSurfaceCreateInfoKHR;
typedef VkResult (VKAPI_PTR *PFN_vkCreateMirSurfaceKHR)(VkInstance instance, const VkMirSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, MirConnection* connection);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkCreateMirSurfaceKHR(
VkInstance instance,
const VkMirSurfaceCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceMirPresentationSupportKHR(
VkPhysicalDevice physicalDevice,
uint32_t queueFamilyIndex,
MirConnection* connection);
#endif
#ifdef __cplusplus
}
#endif
#endif
-54
View File
@@ -1,54 +0,0 @@
#ifndef VULKAN_SCREEN_H_
#define VULKAN_SCREEN_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
/*
** This header is generated from the Khronos Vulkan XML API Registry.
**
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_QNX_screen_surface 1
#define VK_QNX_SCREEN_SURFACE_SPEC_VERSION 1
#define VK_QNX_SCREEN_SURFACE_EXTENSION_NAME "VK_QNX_screen_surface"
typedef VkFlags VkScreenSurfaceCreateFlagsQNX;
typedef struct VkScreenSurfaceCreateInfoQNX {
VkStructureType sType;
const void* pNext;
VkScreenSurfaceCreateFlagsQNX flags;
struct _screen_context* context;
struct _screen_window* window;
} VkScreenSurfaceCreateInfoQNX;
typedef VkResult (VKAPI_PTR *PFN_vkCreateScreenSurfaceQNX)(VkInstance instance, const VkScreenSurfaceCreateInfoQNX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceScreenPresentationSupportQNX)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct _screen_window* window);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkCreateScreenSurfaceQNX(
VkInstance instance,
const VkScreenSurfaceCreateInfoQNX* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceScreenPresentationSupportQNX(
VkPhysicalDevice physicalDevice,
uint32_t queueFamilyIndex,
struct _screen_window* window);
#endif
#ifdef __cplusplus
}
#endif
#endif
+19 -8
View File
@@ -1,10 +1,24 @@
#ifndef VULKAN_VI_H_
#define VULKAN_VI_H_ 1
#ifdef __cplusplus
extern "C" {
#endif
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright (c) 2015-2018 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
** 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.
*/
/*
@@ -13,16 +27,12 @@
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_NN_vi_surface 1
#define VK_NN_VI_SURFACE_SPEC_VERSION 1
#define VK_NN_VI_SURFACE_EXTENSION_NAME "VK_NN_vi_surface"
typedef VkFlags VkViSurfaceCreateFlagsNN;
typedef struct VkViSurfaceCreateInfoNN {
VkStructureType sType;
const void* pNext;
@@ -30,6 +40,7 @@ typedef struct VkViSurfaceCreateInfoNN {
void* window;
} VkViSurfaceCreateInfoNN;
typedef VkResult (VKAPI_PTR *PFN_vkCreateViSurfaceNN)(VkInstance instance, const VkViSurfaceCreateInfoNN* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
#ifndef VK_NO_PROTOTYPES
+19 -8
View File
@@ -1,10 +1,24 @@
#ifndef VULKAN_WAYLAND_H_
#define VULKAN_WAYLAND_H_ 1
#ifdef __cplusplus
extern "C" {
#endif
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright (c) 2015-2018 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
** 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.
*/
/*
@@ -13,16 +27,12 @@
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_KHR_wayland_surface 1
#define VK_KHR_WAYLAND_SURFACE_SPEC_VERSION 6
#define VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME "VK_KHR_wayland_surface"
typedef VkFlags VkWaylandSurfaceCreateFlagsKHR;
typedef struct VkWaylandSurfaceCreateInfoKHR {
VkStructureType sType;
const void* pNext;
@@ -31,6 +41,7 @@ typedef struct VkWaylandSurfaceCreateInfoKHR {
struct wl_surface* surface;
} VkWaylandSurfaceCreateInfoKHR;
typedef VkResult (VKAPI_PTR *PFN_vkCreateWaylandSurfaceKHR)(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct wl_display* display);
+30 -87
View File
@@ -1,10 +1,24 @@
#ifndef VULKAN_WIN32_H_
#define VULKAN_WIN32_H_ 1
#ifdef __cplusplus
extern "C" {
#endif
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright (c) 2015-2018 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
** 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.
*/
/*
@@ -13,16 +27,12 @@
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_KHR_win32_surface 1
#define VK_KHR_WIN32_SURFACE_SPEC_VERSION 6
#define VK_KHR_WIN32_SURFACE_EXTENSION_NAME "VK_KHR_win32_surface"
typedef VkFlags VkWin32SurfaceCreateFlagsKHR;
typedef struct VkWin32SurfaceCreateInfoKHR {
VkStructureType sType;
const void* pNext;
@@ -31,6 +41,7 @@ typedef struct VkWin32SurfaceCreateInfoKHR {
HWND hwnd;
} VkWin32SurfaceCreateInfoKHR;
typedef VkResult (VKAPI_PTR *PFN_vkCreateWin32SurfaceKHR)(VkInstance instance, const VkWin32SurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex);
@@ -46,10 +57,10 @@ VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32PresentationSupportKHR(
uint32_t queueFamilyIndex);
#endif
#define VK_KHR_external_memory_win32 1
#define VK_KHR_EXTERNAL_MEMORY_WIN32_SPEC_VERSION 1
#define VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME "VK_KHR_external_memory_win32"
typedef struct VkImportMemoryWin32HandleInfoKHR {
VkStructureType sType;
const void* pNext;
@@ -79,6 +90,7 @@ typedef struct VkMemoryGetWin32HandleInfoKHR {
VkExternalMemoryHandleTypeFlagBits handleType;
} VkMemoryGetWin32HandleInfoKHR;
typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandleKHR)(VkDevice device, const VkMemoryGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle);
typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandlePropertiesKHR)(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, HANDLE handle, VkMemoryWin32HandlePropertiesKHR* pMemoryWin32HandleProperties);
@@ -95,10 +107,10 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandlePropertiesKHR(
VkMemoryWin32HandlePropertiesKHR* pMemoryWin32HandleProperties);
#endif
#define VK_KHR_win32_keyed_mutex 1
#define VK_KHR_WIN32_KEYED_MUTEX_SPEC_VERSION 1
#define VK_KHR_WIN32_KEYED_MUTEX_EXTENSION_NAME "VK_KHR_win32_keyed_mutex"
typedef struct VkWin32KeyedMutexAcquireReleaseInfoKHR {
VkStructureType sType;
const void* pNext;
@@ -116,6 +128,7 @@ typedef struct VkWin32KeyedMutexAcquireReleaseInfoKHR {
#define VK_KHR_external_semaphore_win32 1
#define VK_KHR_EXTERNAL_SEMAPHORE_WIN32_SPEC_VERSION 1
#define VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME "VK_KHR_external_semaphore_win32"
typedef struct VkImportSemaphoreWin32HandleInfoKHR {
VkStructureType sType;
const void* pNext;
@@ -150,6 +163,7 @@ typedef struct VkSemaphoreGetWin32HandleInfoKHR {
VkExternalSemaphoreHandleTypeFlagBits handleType;
} VkSemaphoreGetWin32HandleInfoKHR;
typedef VkResult (VKAPI_PTR *PFN_vkImportSemaphoreWin32HandleKHR)(VkDevice device, const VkImportSemaphoreWin32HandleInfoKHR* pImportSemaphoreWin32HandleInfo);
typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreWin32HandleKHR)(VkDevice device, const VkSemaphoreGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle);
@@ -164,10 +178,10 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreWin32HandleKHR(
HANDLE* pHandle);
#endif
#define VK_KHR_external_fence_win32 1
#define VK_KHR_EXTERNAL_FENCE_WIN32_SPEC_VERSION 1
#define VK_KHR_EXTERNAL_FENCE_WIN32_EXTENSION_NAME "VK_KHR_external_fence_win32"
typedef struct VkImportFenceWin32HandleInfoKHR {
VkStructureType sType;
const void* pNext;
@@ -193,6 +207,7 @@ typedef struct VkFenceGetWin32HandleInfoKHR {
VkExternalFenceHandleTypeFlagBits handleType;
} VkFenceGetWin32HandleInfoKHR;
typedef VkResult (VKAPI_PTR *PFN_vkImportFenceWin32HandleKHR)(VkDevice device, const VkImportFenceWin32HandleInfoKHR* pImportFenceWin32HandleInfo);
typedef VkResult (VKAPI_PTR *PFN_vkGetFenceWin32HandleKHR)(VkDevice device, const VkFenceGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle);
@@ -207,10 +222,10 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceWin32HandleKHR(
HANDLE* pHandle);
#endif
#define VK_NV_external_memory_win32 1
#define VK_NV_EXTERNAL_MEMORY_WIN32_SPEC_VERSION 1
#define VK_NV_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME "VK_NV_external_memory_win32"
typedef struct VkImportMemoryWin32HandleInfoNV {
VkStructureType sType;
const void* pNext;
@@ -225,6 +240,7 @@ typedef struct VkExportMemoryWin32HandleInfoNV {
DWORD dwAccess;
} VkExportMemoryWin32HandleInfoNV;
typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandleNV)(VkDevice device, VkDeviceMemory memory, VkExternalMemoryHandleTypeFlagsNV handleType, HANDLE* pHandle);
#ifndef VK_NO_PROTOTYPES
@@ -235,10 +251,10 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandleNV(
HANDLE* pHandle);
#endif
#define VK_NV_win32_keyed_mutex 1
#define VK_NV_WIN32_KEYED_MUTEX_SPEC_VERSION 2
#define VK_NV_WIN32_KEYED_MUTEX_SPEC_VERSION 1
#define VK_NV_WIN32_KEYED_MUTEX_EXTENSION_NAME "VK_NV_win32_keyed_mutex"
typedef struct VkWin32KeyedMutexAcquireReleaseInfoNV {
VkStructureType sType;
const void* pNext;
@@ -253,79 +269,6 @@ typedef struct VkWin32KeyedMutexAcquireReleaseInfoNV {
#define VK_EXT_full_screen_exclusive 1
#define VK_EXT_FULL_SCREEN_EXCLUSIVE_SPEC_VERSION 4
#define VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME "VK_EXT_full_screen_exclusive"
typedef enum VkFullScreenExclusiveEXT {
VK_FULL_SCREEN_EXCLUSIVE_DEFAULT_EXT = 0,
VK_FULL_SCREEN_EXCLUSIVE_ALLOWED_EXT = 1,
VK_FULL_SCREEN_EXCLUSIVE_DISALLOWED_EXT = 2,
VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT = 3,
VK_FULL_SCREEN_EXCLUSIVE_MAX_ENUM_EXT = 0x7FFFFFFF
} VkFullScreenExclusiveEXT;
typedef struct VkSurfaceFullScreenExclusiveInfoEXT {
VkStructureType sType;
void* pNext;
VkFullScreenExclusiveEXT fullScreenExclusive;
} VkSurfaceFullScreenExclusiveInfoEXT;
typedef struct VkSurfaceCapabilitiesFullScreenExclusiveEXT {
VkStructureType sType;
void* pNext;
VkBool32 fullScreenExclusiveSupported;
} VkSurfaceCapabilitiesFullScreenExclusiveEXT;
typedef struct VkSurfaceFullScreenExclusiveWin32InfoEXT {
VkStructureType sType;
const void* pNext;
HMONITOR hmonitor;
} VkSurfaceFullScreenExclusiveWin32InfoEXT;
typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfacePresentModes2EXT)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes);
typedef VkResult (VKAPI_PTR *PFN_vkAcquireFullScreenExclusiveModeEXT)(VkDevice device, VkSwapchainKHR swapchain);
typedef VkResult (VKAPI_PTR *PFN_vkReleaseFullScreenExclusiveModeEXT)(VkDevice device, VkSwapchainKHR swapchain);
typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceGroupSurfacePresentModes2EXT)(VkDevice device, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, VkDeviceGroupPresentModeFlagsKHR* pModes);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModes2EXT(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
uint32_t* pPresentModeCount,
VkPresentModeKHR* pPresentModes);
VKAPI_ATTR VkResult VKAPI_CALL vkAcquireFullScreenExclusiveModeEXT(
VkDevice device,
VkSwapchainKHR swapchain);
VKAPI_ATTR VkResult VKAPI_CALL vkReleaseFullScreenExclusiveModeEXT(
VkDevice device,
VkSwapchainKHR swapchain);
VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupSurfacePresentModes2EXT(
VkDevice device,
const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
VkDeviceGroupPresentModeFlagsKHR* pModes);
#endif
#define VK_NV_acquire_winrt_display 1
#define VK_NV_ACQUIRE_WINRT_DISPLAY_SPEC_VERSION 1
#define VK_NV_ACQUIRE_WINRT_DISPLAY_EXTENSION_NAME "VK_NV_acquire_winrt_display"
typedef VkResult (VKAPI_PTR *PFN_vkAcquireWinrtDisplayNV)(VkPhysicalDevice physicalDevice, VkDisplayKHR display);
typedef VkResult (VKAPI_PTR *PFN_vkGetWinrtDisplayNV)(VkPhysicalDevice physicalDevice, uint32_t deviceRelativeId, VkDisplayKHR* pDisplay);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkAcquireWinrtDisplayNV(
VkPhysicalDevice physicalDevice,
VkDisplayKHR display);
VKAPI_ATTR VkResult VKAPI_CALL vkGetWinrtDisplayNV(
VkPhysicalDevice physicalDevice,
uint32_t deviceRelativeId,
VkDisplayKHR* pDisplay);
#endif
#ifdef __cplusplus
}
#endif
+19 -8
View File
@@ -1,10 +1,24 @@
#ifndef VULKAN_XCB_H_
#define VULKAN_XCB_H_ 1
#ifdef __cplusplus
extern "C" {
#endif
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright (c) 2015-2018 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
** 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.
*/
/*
@@ -13,16 +27,12 @@
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_KHR_xcb_surface 1
#define VK_KHR_XCB_SURFACE_SPEC_VERSION 6
#define VK_KHR_XCB_SURFACE_EXTENSION_NAME "VK_KHR_xcb_surface"
typedef VkFlags VkXcbSurfaceCreateFlagsKHR;
typedef struct VkXcbSurfaceCreateInfoKHR {
VkStructureType sType;
const void* pNext;
@@ -31,6 +41,7 @@ typedef struct VkXcbSurfaceCreateInfoKHR {
xcb_window_t window;
} VkXcbSurfaceCreateInfoKHR;
typedef VkResult (VKAPI_PTR *PFN_vkCreateXcbSurfaceKHR)(VkInstance instance, const VkXcbSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, xcb_connection_t* connection, xcb_visualid_t visual_id);
+19 -8
View File
@@ -1,10 +1,24 @@
#ifndef VULKAN_XLIB_H_
#define VULKAN_XLIB_H_ 1
#ifdef __cplusplus
extern "C" {
#endif
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright (c) 2015-2018 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
** 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.
*/
/*
@@ -13,16 +27,12 @@
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_KHR_xlib_surface 1
#define VK_KHR_XLIB_SURFACE_SPEC_VERSION 6
#define VK_KHR_XLIB_SURFACE_EXTENSION_NAME "VK_KHR_xlib_surface"
typedef VkFlags VkXlibSurfaceCreateFlagsKHR;
typedef struct VkXlibSurfaceCreateInfoKHR {
VkStructureType sType;
const void* pNext;
@@ -31,6 +41,7 @@ typedef struct VkXlibSurfaceCreateInfoKHR {
Window window;
} VkXlibSurfaceCreateInfoKHR;
typedef VkResult (VKAPI_PTR *PFN_vkCreateXlibSurfaceKHR)(VkInstance instance, const VkXlibSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, Display* dpy, VisualID visualID);
+17 -8
View File
@@ -1,10 +1,24 @@
#ifndef VULKAN_XLIB_XRANDR_H_
#define VULKAN_XLIB_XRANDR_H_ 1
#ifdef __cplusplus
extern "C" {
#endif
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright (c) 2015-2018 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
** 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.
*/
/*
@@ -13,15 +27,10 @@
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_EXT_acquire_xlib_display 1
#define VK_EXT_ACQUIRE_XLIB_DISPLAY_SPEC_VERSION 1
#define VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME "VK_EXT_acquire_xlib_display"
typedef VkResult (VKAPI_PTR *PFN_vkAcquireXlibDisplayEXT)(VkPhysicalDevice physicalDevice, Display* dpy, VkDisplayKHR display);
typedef VkResult (VKAPI_PTR *PFN_vkGetRandROutputDisplayEXT)(VkPhysicalDevice physicalDevice, Display* dpy, RROutput rrOutput, VkDisplayKHR* pDisplay);
+3 -3
View File
@@ -17,14 +17,14 @@ file(GLOB lib_hdrs ${IPP_IW_PATH}/include/*.h ${IPP_IW_PATH}/include/iw/*.h ${IP
# Define the library target:
# ----------------------------------------------------------------------------------
add_library(${IPP_IW_LIBRARY} STATIC ${OPENCV_3RDPARTY_EXCLUDE_FROM_ALL} ${lib_srcs} ${lib_hdrs})
add_library(${IPP_IW_LIBRARY} STATIC ${lib_srcs} ${lib_hdrs})
if(UNIX)
if(CV_GCC OR CV_CLANG OR CV_ICC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function -Wno-missing-braces -Wno-missing-field-initializers")
endif()
if(CV_CLANG)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-self-assign -Wno-strict-prototypes")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-self-assign")
endif()
endif()
@@ -41,5 +41,5 @@ if(ENABLE_SOLUTION_FOLDERS)
endif()
if(NOT BUILD_SHARED_LIBS)
ocv_install_target(${IPP_IW_LIBRARY} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev OPTIONAL)
ocv_install_target(${IPP_IW_LIBRARY} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
endif()
+11 -12
View File
@@ -2,33 +2,32 @@ function(download_ippicv root_var)
set(${root_var} "" PARENT_SCOPE)
# Commit SHA in the opencv_3rdparty repo
set(IPPICV_COMMIT "fd27188235d85e552de31425e7ea0f53ba73ba53")
set(IPPICV_COMMIT "a56b6ac6f030c312b2dce17430eef13aed9af274")
# Define actual ICV versions
if(APPLE)
set(IPPICV_COMMIT "0cc4aa06bf2bef4b05d237c69a5a96b9cd0cb85a")
set(OPENCV_ICV_PLATFORM "macosx")
set(OPENCV_ICV_PACKAGE_SUBDIR "ippicv_mac")
set(OPENCV_ICV_NAME "ippicv_2021.9.1_mac_intel64_20230919_general.tgz")
set(OPENCV_ICV_HASH "14f01c5a4780bfae9dde9b0aaf5e56fc")
set(OPENCV_ICV_NAME "ippicv_2020_mac_intel64_20191018_general.tgz")
set(OPENCV_ICV_HASH "1c3d675c2a2395d094d523024896e01b")
elseif((UNIX AND NOT ANDROID) OR (UNIX AND ANDROID_ABI MATCHES "x86"))
set(OPENCV_ICV_PLATFORM "linux")
set(OPENCV_ICV_PACKAGE_SUBDIR "ippicv_lnx")
if(X86_64)
set(OPENCV_ICV_NAME "ippicv_2021.11.0_lnx_intel64_20240201_general.tgz")
set(OPENCV_ICV_HASH "0f2745ff705ecae31176dad437608f6f")
set(OPENCV_ICV_NAME "ippicv_2020_lnx_intel64_20191018_general.tgz")
set(OPENCV_ICV_HASH "7421de0095c7a39162ae13a6098782f9")
else()
set(OPENCV_ICV_NAME "ippicv_2021.11.0_lnx_ia32_20240201_general.tgz")
set(OPENCV_ICV_HASH "63e381bf08076ca34fd5264203043a45")
set(OPENCV_ICV_NAME "ippicv_2020_lnx_ia32_20191018_general.tgz")
set(OPENCV_ICV_HASH "ad189a940fb60eb71f291321322fe3e8")
endif()
elseif(WIN32 AND NOT ARM)
set(OPENCV_ICV_PLATFORM "windows")
set(OPENCV_ICV_PACKAGE_SUBDIR "ippicv_win")
if(X86_64)
set(OPENCV_ICV_NAME "ippicv_2021.11.0_win_intel64_20240201_general.zip")
set(OPENCV_ICV_HASH "59d154bf54a1e3eea20d7248f81a2a8e")
set(OPENCV_ICV_NAME "ippicv_2020_win_intel64_20191018_general.zip")
set(OPENCV_ICV_HASH "879741a7946b814455eee6c6ffde2984")
else()
set(OPENCV_ICV_NAME "ippicv_2021.11.0_win_ia32_20240201_general.zip")
set(OPENCV_ICV_HASH "7a6d8ac5825c02fea6cbfc1201b521b5")
set(OPENCV_ICV_NAME "ippicv_2020_win_ia32_20191018_general.zip")
set(OPENCV_ICV_HASH "cd39bdf0c2e1cac9a61101dad7a2413e")
endif()
else()
return()
+2 -3
View File
@@ -37,7 +37,7 @@ set(ITT_SRCS
src/ittnotify/jitprofiling.c
)
add_library(${ITT_LIBRARY} STATIC ${OPENCV_3RDPARTY_EXCLUDE_FROM_ALL} ${ITT_SRCS} ${ITT_PUBLIC_HDRS} ${ITT_PRIVATE_HDRS})
add_library(${ITT_LIBRARY} STATIC ${ITT_SRCS} ${ITT_PUBLIC_HDRS} ${ITT_PRIVATE_HDRS})
if(NOT WIN32)
if(HAVE_DL_LIBRARY)
@@ -54,14 +54,13 @@ set_target_properties(${ITT_LIBRARY} PROPERTIES
)
ocv_warnings_disable(CMAKE_C_FLAGS -Wundef -Wsign-compare)
ocv_warnings_disable(CMAKE_C_FLAGS -Wstrict-prototypes) # clang15
if(ENABLE_SOLUTION_FOLDERS)
set_target_properties(${ITT_LIBRARY} PROPERTIES FOLDER "3rdparty")
endif()
if(NOT BUILD_SHARED_LIBS)
ocv_install_target(${ITT_LIBRARY} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev OPTIONAL)
ocv_install_target(${ITT_LIBRARY} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
endif()
ocv_install_3rdparty_licenses(ittnotify src/ittnotify/LICENSE.BSD src/ittnotify/LICENSE.GPL)
-23
View File
@@ -1,23 +0,0 @@
project(kleidicv_hal)
set(KLEIDICV_SOURCE_PATH "" CACHE PATH "Directory containing KleidiCV sources")
ocv_update(KLEIDICV_SRC_COMMIT "0.1.0")
ocv_update(KLEIDICV_SRC_HASH "9388f28cf2fbe3338197b2b57d491468")
if(KLEIDICV_SOURCE_PATH)
set(THE_ROOT "${KLEIDICV_SOURCE_PATH}")
else()
ocv_download(FILENAME "kleidicv-${KLEIDICV_SRC_COMMIT}.tar.gz"
HASH ${KLEIDICV_SRC_HASH}
URL
"${OPENCV_KLEIDICV_URL}"
"$ENV{OPENCV_KLEIDICV_URL}"
"https://gitlab.arm.com/kleidi/kleidicv/-/archive/${KLEIDICV_SRC_COMMIT}/"
DESTINATION_DIR "${OpenCV_BINARY_DIR}/3rdparty/kleidicv/"
ID KLEIDICV
STATUS res
UNPACK RELATIVE_URL)
set(THE_ROOT "${OpenCV_BINARY_DIR}/3rdparty/kleidicv/kleidicv-${KLEIDICV_SRC_COMMIT}")
endif()
include("${THE_ROOT}/adapters/opencv/CMakeLists.txt")
+2 -2
View File
@@ -17,7 +17,7 @@ file(GLOB lib_ext_hdrs jasper/*.h)
# Define the library target:
# ----------------------------------------------------------------------------------
add_library(${JASPER_LIBRARY} STATIC ${OPENCV_3RDPARTY_EXCLUDE_FROM_ALL} ${lib_srcs} ${lib_hdrs} ${lib_ext_hdrs})
add_library(${JASPER_LIBRARY} STATIC ${lib_srcs} ${lib_hdrs} ${lib_ext_hdrs})
if(WIN32 AND NOT MINGW)
add_definitions(-DJAS_WIN_MSVC_BUILD)
@@ -46,7 +46,7 @@ if(ENABLE_SOLUTION_FOLDERS)
endif()
if(NOT BUILD_SHARED_LIBS)
ocv_install_target(${JASPER_LIBRARY} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev OPTIONAL)
ocv_install_target(${JASPER_LIBRARY} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
endif()
ocv_install_3rdparty_licenses(jasper LICENSE README copyright)
+1 -1
View File
@@ -889,7 +889,7 @@ int jas_stream_copy(jas_stream_t *out, jas_stream_t *in, int n)
while (all || m > 0) {
if ((c = jas_stream_getc_macro(in)) == EOF) {
/* The next character of input could not be read. */
/* Return with an error if an I/O error occurred
/* Return with an error if an I/O error occured
(not including EOF) or if an explicit copy count
was specified. */
return (!all || jas_stream_error(in)) ? (-1) : 0;
+1 -1
View File
@@ -100,7 +100,7 @@
#define JPC_BITSTREAM_NOCLOSE 0x01
/* End of file has been reached while reading. */
#define JPC_BITSTREAM_EOF 0x02
/* An I/O error has occurerd. */
/* An I/O error has occured. */
#define JPC_BITSTREAM_ERR 0x04
/******************************************************************************\
+29 -165
View File
@@ -1,43 +1,12 @@
project(${JPEG_LIBRARY} C)
macro(boolean_number var)
if(${var})
set(${var} 1 ${ARGN})
else()
set(${var} 0 ${ARGN})
endif()
endmacro()
ocv_warnings_disable(CMAKE_C_FLAGS -Wunused-parameter -Wsign-compare -Wshorten-64-to-32 -Wimplicit-fallthrough)
if(APPLE)
ocv_warnings_disable(CMAKE_C_FLAGS -Wunused-variable) # NEON flags are not used on Mac
endif()
if(CV_GCC AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13)
# src/jchuff.c:1042:22: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
ocv_warnings_disable(CMAKE_C_FLAGS -Wstringop-overflow)
endif()
set(VERSION 3.0.3)
set(COPYRIGHT_YEAR "1991-2024")
string(REPLACE "." ";" VERSION_TRIPLET ${VERSION})
list(GET VERSION_TRIPLET 0 VERSION_MAJOR)
list(GET VERSION_TRIPLET 1 VERSION_MINOR)
list(GET VERSION_TRIPLET 2 VERSION_REVISION)
function(pad_number NUMBER OUTPUT_LEN)
string(LENGTH "${${NUMBER}}" INPUT_LEN)
if(INPUT_LEN LESS OUTPUT_LEN)
math(EXPR ZEROES "${OUTPUT_LEN} - ${INPUT_LEN} - 1")
set(NUM ${${NUMBER}})
foreach(C RANGE ${ZEROES})
set(NUM "0${NUM}")
endforeach()
set(${NUMBER} ${NUM} PARENT_SCOPE)
endif()
endfunction()
pad_number(VERSION_MINOR 3)
pad_number(VERSION_REVISION 3)
set(LIBJPEG_TURBO_VERSION_NUMBER ${VERSION_MAJOR}${VERSION_MINOR}${VERSION_REVISION})
set(VERSION_MAJOR 2)
set(VERSION_MINOR 0)
set(VERSION_REVISION 4)
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION})
set(LIBJPEG_TURBO_VERSION_NUMBER 2000004)
string(TIMESTAMP BUILD "opencv-${OPENCV_VERSION}-libjpeg-turbo")
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
@@ -46,59 +15,15 @@ endif()
message(STATUS "libjpeg-turbo: VERSION = ${VERSION}, BUILD = ${BUILD}")
math(EXPR BITS "${CMAKE_SIZEOF_VOID_P} * 8")
string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" CMAKE_SYSTEM_PROCESSOR_LC)
if(CMAKE_SYSTEM_PROCESSOR_LC MATCHES "x86_64" OR
CMAKE_SYSTEM_PROCESSOR_LC MATCHES "amd64" OR
CMAKE_SYSTEM_PROCESSOR_LC MATCHES "i[0-9]86" OR
CMAKE_SYSTEM_PROCESSOR_LC MATCHES "x86" OR
CMAKE_SYSTEM_PROCESSOR_LC MATCHES "ia32")
if(BITS EQUAL 64 OR CMAKE_C_COMPILER_ABI MATCHES "ELF X32")
set(CPU_TYPE x86_64)
else()
set(CPU_TYPE i386)
endif()
if(NOT CMAKE_SYSTEM_PROCESSOR STREQUAL ${CPU_TYPE})
set(CMAKE_SYSTEM_PROCESSOR ${CPU_TYPE})
endif()
elseif(CMAKE_SYSTEM_PROCESSOR_LC STREQUAL "aarch64" OR
CMAKE_SYSTEM_PROCESSOR_LC MATCHES "^arm")
if(BITS EQUAL 64)
set(CPU_TYPE arm64)
else()
set(CPU_TYPE arm)
endif()
elseif(CMAKE_SYSTEM_PROCESSOR_LC MATCHES "^ppc" OR
CMAKE_SYSTEM_PROCESSOR_LC MATCHES "^powerpc")
set(CPU_TYPE powerpc)
else()
set(CPU_TYPE ${CMAKE_SYSTEM_PROCESSOR_LC})
endif()
if(CMAKE_OSX_ARCHITECTURES MATCHES "x86_64" OR
CMAKE_OSX_ARCHITECTURES MATCHES "arm64" OR
CMAKE_OSX_ARCHITECTURES MATCHES "i386")
set(CPU_TYPE ${CMAKE_OSX_ARCHITECTURES})
endif()
if(CMAKE_OSX_ARCHITECTURES MATCHES "ppc")
set(CPU_TYPE powerpc)
endif()
if(MSVC_IDE AND CMAKE_GENERATOR_PLATFORM MATCHES "arm64")
set(CPU_TYPE arm64)
endif()
OCV_OPTION(ENABLE_LIBJPEG_TURBO_SIMD "Include SIMD extensions for libjpeg-turbo, if available for this platform" (NOT CV_DISABLE_OPTIMIZATION))
option(WITH_ARITH_ENC "Include arithmetic encoding support when emulating the libjpeg v6b API/ABI" TRUE)
option(WITH_ARITH_DEC "Include arithmetic decoding support when emulating the libjpeg v6b API/ABI" TRUE)
set(WITH_SIMD 1)
set(HAVE_LIBJPEG_TURBO_SIMD 0 PARENT_SCOPE)
include(CheckCSourceCompiles)
include(CheckIncludeFiles)
include(CheckTypeSize)
check_type_size("size_t" SIZE_T)
check_type_size("unsigned long" UNSIGNED_LONG)
check_type_size("size_t" SIZEOF_SIZE_T)
check_type_size("unsigned long" SIZEOF_UNSIGNED_LONG)
if(SIZEOF_SIZE_T EQUAL SIZEOF_UNSIGNED_LONG)
check_c_source_compiles("int main(int argc, char **argv) { unsigned long a = argc; return __builtin_ctzl(a); }"
@@ -121,6 +46,7 @@ if(UNIX)
ocv_update(HAVE_UNSIGNED_SHORT 1)
# undef INCOMPLETE_TYPES_BROKEN
ocv_update(RIGHT_SHIFT_IS_UNSIGNED 0)
ocv_update(__CHAR_UNSIGNED__ 0)
endif()
@@ -134,34 +60,32 @@ if(WITH_ARITH_DEC)
set(D_ARITH_CODING_SUPPORTED 1)
endif()
set(JPEG_LIB_VERSION 70)
set(JPEG_LIB_VERSION 62)
# OpenCV
set(JPEG_LIB_VERSION "${VERSION}-${JPEG_LIB_VERSION}" PARENT_SCOPE)
set(THREAD_LOCAL "") # WITH_TURBOJPEG is not used
add_definitions(-DNO_GETENV -DNO_PUTENV)
if(MSVC)
add_definitions(-W3 -wd4996 -wd4018)
endif()
if(WIN32)
configure_file(jconfig.h.win.in jconfig.h)
else()
configure_file(jconfig.h.in jconfig.h)
endif()
configure_file(jconfigint.h.in jconfigint.h)
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src)
set(JPEG16_SOURCES jcapistd.c jccolor.c jcdiffct.c jclossls.c jcmainct.c
jcprepct.c jcsample.c jdapistd.c jdcolor.c jddiffct.c jdlossls.c jdmainct.c
jdpostct.c jdsample.c jutils.c)
set(JPEG12_SOURCES ${JPEG16_SOURCES} jccoefct.c jcdctmgr.c jdcoefct.c
jddctmgr.c jdmerge.c jfdctfst.c jfdctint.c jidctflt.c jidctfst.c jidctint.c
jidctred.c jquant1.c jquant2.c)
set(JPEG_SOURCES ${JPEG12_SOURCES} jcapimin.c jchuff.c jcicc.c jcinit.c
jclhuff.c jcmarker.c jcmaster.c jcomapi.c jcparam.c jcphuff.c jctrans.c
jdapimin.c jdatadst.c jdatasrc.c jdhuff.c jdicc.c jdinput.c jdlhuff.c
jdmarker.c jdmaster.c jdphuff.c jdtrans.c jerror.c jfdctflt.c jmemmgr.c
jmemnobs.c jpeg_nbits.c)
set(JPEG_SOURCES
jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c jcicc.c
jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c jcphuff.c
jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c jdatadst.c jdatasrc.c
jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c jdicc.c jdinput.c jdmainct.c jdmarker.c
jdmaster.c jdmerge.c jdphuff.c jdpostct.c jdsample.c jdtrans.c jerror.c
jfdctflt.c jfdctfst.c jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c
jquant1.c jquant2.c jutils.c jmemmgr.c jmemnobs.c)
if(WITH_ARITH_ENC OR WITH_ARITH_DEC)
set(JPEG_SOURCES ${JPEG_SOURCES} jaricom.c)
@@ -175,70 +99,12 @@ if(WITH_ARITH_DEC)
set(JPEG_SOURCES ${JPEG_SOURCES} jdarith.c)
endif()
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
# Use the maximum optimization level for release builds
foreach(var CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO)
if(${var} MATCHES "-O2")
string(REGEX REPLACE "-O2" "-O3" ${var} "${${var}}")
endif()
endforeach()
endif()
# No SIMD
set(JPEG_SOURCES ${JPEG_SOURCES} jsimd_none.c)
if(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
if(CMAKE_C_COMPILER_ID MATCHES "SunPro")
# Use the maximum optimization level for release builds
foreach(var CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO)
if(${var} MATCHES "-xO3")
string(REGEX REPLACE "-xO3" "-xO5" ${var} "${${var}}")
endif()
if(${var} MATCHES "-xO2")
string(REGEX REPLACE "-xO2" "-xO5" ${var} "${${var}}")
endif()
endforeach()
endif()
endif()
include(CheckTypeSize)
check_type_size("size_t" SIZE_T)
check_type_size("unsigned long" UNSIGNED_LONG)
if(ENABLE_LIBJPEG_TURBO_SIMD)
add_subdirectory(src/simd)
if(NEON_INTRINSICS)
add_definitions(-DNEON_INTRINSICS)
endif()
else()
set(WITH_SIMD 0)
endif()
if(WITH_SIMD)
message(STATUS "SIMD extensions: ${CPU_TYPE} (WITH_SIMD = ${WITH_SIMD})")
set(HAVE_LIBJPEG_TURBO_SIMD 1 PARENT_SCOPE)
if(MSVC_IDE OR XCODE)
set_source_files_properties(${SIMD_OBJS} PROPERTIES GENERATED 1)
endif()
set(SIMD_TARGET_OBJECTS $<TARGET_OBJECTS:simd>)
endif()
configure_file(jversion.h.in jversion.h)
configure_file(jconfig.h.in jconfig.h)
configure_file(jconfigint.h.in jconfigint.h)
ocv_list_add_prefix(JPEG16_SOURCES src/)
ocv_list_add_prefix(JPEG12_SOURCES src/)
ocv_list_add_prefix(JPEG_SOURCES src/)
set(JPEG_SOURCES ${JPEG_SOURCES} ${SIMD_OBJS})
add_library(jpeg12-static OBJECT ${JPEG12_SOURCES})
set_property(TARGET jpeg12-static PROPERTY COMPILE_FLAGS
"-DBITS_IN_JSAMPLE=12")
add_library(jpeg16-static OBJECT ${JPEG16_SOURCES})
set_property(TARGET jpeg16-static PROPERTY COMPILE_FLAGS
"-DBITS_IN_JSAMPLE=16")
add_library(${JPEG_LIBRARY} STATIC ${JPEG_SOURCES} ${SIMD_TARGET_OBJECTS}
${SIMD_OBJS} $<TARGET_OBJECTS:jpeg12-static>
$<TARGET_OBJECTS:jpeg16-static>)
add_library(${JPEG_LIBRARY} STATIC ${JPEG_SOURCES} ${SIMD_OBJS})
set_target_properties(${JPEG_LIBRARY}
PROPERTIES OUTPUT_NAME ${JPEG_LIBRARY}
@@ -249,13 +115,11 @@ set_target_properties(${JPEG_LIBRARY}
)
if(ENABLE_SOLUTION_FOLDERS)
set_target_properties(${JPEG_LIBRARY} PROPERTIES FOLDER "3rdparty/jpeg")
set_target_properties(jpeg12-static PROPERTIES FOLDER "3rdparty/jpeg")
set_target_properties(jpeg16-static PROPERTIES FOLDER "3rdparty/jpeg")
set_target_properties(${JPEG_LIBRARY} PROPERTIES FOLDER "3rdparty")
endif()
if(NOT BUILD_SHARED_LIBS)
ocv_install_target(${JPEG_LIBRARY} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev OPTIONAL)
ocv_install_target(${JPEG_LIBRARY} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
endif()
ocv_install_3rdparty_licenses(libjpeg-turbo README.md LICENSE.md README.ijg)
+15 -18
View File
@@ -1,33 +1,30 @@
libjpeg-turbo Licenses
======================
libjpeg-turbo is covered by two compatible BSD-style open source licenses:
libjpeg-turbo is covered by three compatible BSD-style open source licenses:
- The IJG (Independent JPEG Group) License, which is listed in
[README.ijg](README.ijg)
This license applies to the libjpeg API library and associated programs,
including any code inherited from libjpeg and any modifications to that
code. Note that the libjpeg-turbo SIMD source code bears the
[zlib License](https://opensource.org/licenses/Zlib), but in the context of
the overall libjpeg API library, the terms of the zlib License are subsumed
by the terms of the IJG License.
This license applies to the libjpeg API library and associated programs
(any code inherited from libjpeg, and any modifications to that code.)
- The Modified (3-clause) BSD License, which is listed below
This license applies to the TurboJPEG API library and associated programs, as
well as the build system. Note that the TurboJPEG API library wraps the
libjpeg API library, so in the context of the overall TurboJPEG API library,
both the terms of the IJG License and the terms of the Modified (3-clause)
BSD License apply.
This license covers the TurboJPEG API library and associated programs, as
well as the build system.
- The [zlib License](https://opensource.org/licenses/Zlib)
This license is a subset of the other two, and it covers the libjpeg-turbo
SIMD extensions.
Complying with the libjpeg-turbo Licenses
=========================================
This section provides a roll-up of the libjpeg-turbo licensing terms, to the
best of our understanding. This is not a license in and of itself. It is
intended solely for clarification.
best of our understanding.
1. If you are distributing a modified version of the libjpeg-turbo source,
then:
@@ -41,7 +38,7 @@ intended solely for clarification.
- Clauses 1 and 3 of the zlib License
2. You must add your own copyright notice to the header of each source
file you modified, so others can tell that you modified that file. (If
file you modified, so others can tell that you modified that file (if
there is not an existing copyright header in that file, then you can
simply add a notice stating that you modified the file.)
@@ -94,7 +91,7 @@ intended solely for clarification.
The Modified (3-clause) BSD License
===================================
Copyright (C)2009-2023 D. R. Commander. All Rights Reserved.<br>
Copyright (C)2009-2019 D. R. Commander. All Rights Reserved.
Copyright (C)2015 Viktor Szathmáry. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
@@ -122,8 +119,8 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
Why Two Licenses?
=================
Why Three Licenses?
===================
The zlib License could have been used instead of the Modified (3-clause) BSD
License, and since the IJG License effectively subsumes the distribution
+40 -21
View File
@@ -43,7 +43,7 @@ User documentation:
change.log Version-to-version change highlights.
Programmer and internal documentation:
libjpeg.txt How to use the JPEG library in your own programs.
example.c Sample code for calling the JPEG library.
example.txt Sample code for calling the JPEG library.
structure.txt Overview of the JPEG library's internal structure.
coderules.txt Coding style rules --- please read if you contribute code.
@@ -68,17 +68,17 @@ other abrupt features may not compress well with JPEG, and a higher JPEG
quality may have to be used to avoid visible compression artifacts with such
images.
JPEG is normally lossy, meaning that the output pixels are not necessarily
identical to the input pixels. However, on photographic content and other
"smooth" images, very good compression ratios can be obtained with no visible
compression artifacts, and extremely high compression ratios are possible if
you are willing to sacrifice image quality (by reducing the "quality" setting
in the compressor.)
JPEG is lossy, meaning that the output pixels are not necessarily identical to
the input pixels. However, on photographic content and other "smooth" images,
very good compression ratios can be obtained with no visible compression
artifacts, and extremely high compression ratios are possible if you are
willing to sacrifice image quality (by reducing the "quality" setting in the
compressor.)
This software implements JPEG baseline, extended-sequential, progressive, and
lossless compression processes. Provision is made for supporting all variants
of these processes, although some uncommon parameter settings aren't
implemented yet. We have made no provision for supporting the hierarchical
This software implements JPEG baseline, extended-sequential, and progressive
compression processes. Provision is made for supporting all variants of these
processes, although some uncommon parameter settings aren't implemented yet.
We have made no provision for supporting the hierarchical or lossless
processes defined in the standard.
We provide a set of library routines for reading and writing JPEG image files,
@@ -128,7 +128,7 @@ with respect to this software, its quality, accuracy, merchantability, or
fitness for a particular purpose. This software is provided "AS IS", and you,
its user, assume the entire risk as to its quality and accuracy.
This software is copyright (C) 1991-2020, Thomas G. Lane, Guido Vollbeding.
This software is copyright (C) 1991-2016, Thomas G. Lane, Guido Vollbeding.
All Rights Reserved except as specified below.
Permission is hereby granted to use, copy, modify, and distribute this
@@ -159,6 +159,19 @@ commercial products, provided that all warranty or liability claims are
assumed by the product vendor.
The IJG distribution formerly included code to read and write GIF files.
To avoid entanglement with the Unisys LZW patent (now expired), GIF reading
support has been removed altogether, and the GIF writer has been simplified
to produce "uncompressed GIFs". This technique does not use the LZW
algorithm; the resulting GIF files are larger than usual, but are readable
by all standard GIF decoders.
We are required to state that
"The Graphics Interchange Format(c) is the Copyright property of
CompuServe Incorporated. GIF(sm) is a Service Mark property of
CompuServe Incorporated."
REFERENCES
==========
@@ -210,12 +223,12 @@ https://www.iso.org/standard/54989.html and http://www.itu.int/rec/T-REC-T.871.
A PDF file of the older JFIF 1.02 specification is available at
http://www.w3.org/Graphics/JPEG/jfif3.pdf.
The TIFF 6.0 file format specification can be obtained from
http://mirrors.ctan.org/graphics/tiff/TIFF6.ps.gz. The JPEG incorporation
scheme found in the TIFF 6.0 spec of 3-June-92 has a number of serious
problems. IJG does not recommend use of the TIFF 6.0 design (TIFF Compression
tag 6). Instead, we recommend the JPEG design proposed by TIFF Technical Note
#2 (Compression tag 7). Copies of this Note can be obtained from
The TIFF 6.0 file format specification can be obtained by FTP from
ftp://ftp.sgi.com/graphics/tiff/TIFF6.ps.gz. The JPEG incorporation scheme
found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems.
IJG does not recommend use of the TIFF 6.0 design (TIFF Compression tag 6).
Instead, we recommend the JPEG design proposed by TIFF Technical Note #2
(Compression tag 7). Copies of this Note can be obtained from
http://www.ijg.org/files/. It is expected that the next revision
of the TIFF spec will replace the 6.0 JPEG design with the Note's design.
Although IJG's own code does not support TIFF/JPEG, the free libtiff library
@@ -230,8 +243,14 @@ The most recent released version can always be found there in
directory "files".
The JPEG FAQ (Frequently Asked Questions) article is a source of some
general information about JPEG. It is available at
http://www.faqs.org/faqs/jpeg-faq.
general information about JPEG.
It is available on the World Wide Web at http://www.faqs.org/faqs/jpeg-faq/
and other news.answers archive sites, including the official news.answers
archive at rtfm.mit.edu: ftp://rtfm.mit.edu/pub/usenet/news.answers/jpeg-faq/.
If you don't have Web or FTP access, send e-mail to mail-server@rtfm.mit.edu
with body
send usenet/news.answers/jpeg-faq/part1
send usenet/news.answers/jpeg-faq/part2
FILE FORMAT COMPATIBILITY
@@ -241,7 +260,7 @@ This software implements ITU T.81 | ISO/IEC 10918 with some extensions from
ITU T.871 | ISO/IEC 10918-5 (JPEG File Interchange Format-- see REFERENCES).
Informally, the term "JPEG image" or "JPEG file" most often refers to JFIF or
a subset thereof, but there are other formats containing the name "JPEG" that
are incompatible with the original JPEG standard or with JFIF (for instance,
are incompatible with the DCT-based JPEG standard or with JFIF (for instance,
JPEG 2000 and JPEG XR). This software therefore does not support these
formats. Indeed, one of the original reasons for developing this free software
was to help force convergence on a common, interoperable format standard for
+36 -51
View File
@@ -2,8 +2,8 @@ Background
==========
libjpeg-turbo is a JPEG image codec that uses SIMD instructions to accelerate
baseline JPEG compression and decompression on x86, x86-64, Arm, PowerPC, and
MIPS systems, as well as progressive JPEG compression on x86, x86-64, and Arm
baseline JPEG compression and decompression on x86, x86-64, ARM, PowerPC, and
MIPS systems, as well as progressive JPEG compression on x86 and x86-64
systems. On such systems, libjpeg-turbo is generally 2-6x as fast as libjpeg,
all else being equal. On other types of systems, libjpeg-turbo can still
outperform libjpeg by a significant amount, by virtue of its highly-optimized
@@ -21,26 +21,7 @@ derivative of libjpeg v6b developed by Miyasaka Masaru. The TigerVNC and
VirtualGL projects made numerous enhancements to the codec in 2009, and in
early 2010, libjpeg-turbo spun off into an independent project, with the goal
of making high-speed JPEG compression/decompression technology available to a
broader range of users and developers. libjpeg-turbo is an ISO/IEC and ITU-T
reference implementation of the JPEG standard.
More information about libjpeg-turbo can be found at
<https://libjpeg-turbo.org>.
Funding
=======
libjpeg-turbo is an independent open source project, but we rely on patronage
and funded development in order to maintain that independence. The easiest way
to ensure that libjpeg-turbo remains community-focused and free of any one
organization's agenda is to
[sponsor our project through GitHub](https://github.com/sponsors/libjpeg-turbo).
All sponsorship money goes directly toward funding the labor necessary to
maintain libjpeg-turbo, support the user community, and implement bug fixes and
strategically important features.
[![Sponsor libjpeg-turbo](https://img.shields.io/github/sponsors/libjpeg-turbo?label=Sponsor&logo=GitHub)](https://github.com/sponsors/libjpeg-turbo)
broader range of users and developers.
License
@@ -198,8 +179,8 @@ supported and which aren't.
NOTE: As of this writing, extensive research has been conducted into the
usefulness of DCT scaling as a means of data reduction and SmartScale as a
means of quality improvement. Readers are invited to peruse the research at
<http://www.libjpeg-turbo.org/About/SmartScale> and draw their own conclusions,
means of quality improvement. The reader is invited to peruse the research at
<http://www.libjpeg-turbo.org/About/SmartScale> and draw his/her own conclusions,
but it is the general belief of our project that these features have not
demonstrated sufficient usefulness to justify inclusion in libjpeg-turbo.
@@ -264,6 +245,16 @@ programs that need them, without breaking ABI compatibility for programs that
don't, and it allows those functions to be provided in the "official"
libjpeg-turbo binaries.
Those who are concerned about maintaining strict conformance with the libjpeg
v6b or v7 API can pass an argument of `-DWITH_MEM_SRCDST=0` to `cmake` prior to
building libjpeg-turbo. This will restore the pre-1.3 behavior, in which
`jpeg_mem_src()` and `jpeg_mem_dest()` are only included when emulating the
libjpeg v8 API/ABI.
On Un*x systems, including the in-memory source/destination managers changes
the dynamic library version from 62.2.0 to 62.3.0 if using libjpeg v6b API/ABI
emulation and from 7.2.0 to 7.3.0 if using libjpeg v7 API/ABI emulation.
Note that, on most Un*x systems, the dynamic linker will not look for a
function in a library until that function is actually used. Thus, if a program
is built against libjpeg-turbo 1.3+ and uses `jpeg_mem_src()` or
@@ -283,35 +274,29 @@ Mathematical Compatibility
==========================
For the most part, libjpeg-turbo should produce identical output to libjpeg
v6b. There are two exceptions:
v6b. The one exception to this is when using the floating point DCT/IDCT, in
which case the outputs of libjpeg v6b and libjpeg-turbo can differ for the
following reasons:
1. When decompressing a JPEG image that uses 4:4:0 chrominance subsampling, the
outputs of libjpeg v6b and libjpeg-turbo can differ because libjpeg-turbo
implements a "fancy" (smooth) 4:4:0 upsampling algorithm and libjpeg did not.
- The SSE/SSE2 floating point DCT implementation in libjpeg-turbo is ever so
slightly more accurate than the implementation in libjpeg v6b, but not by
any amount perceptible to human vision (generally in the range of 0.01 to
0.08 dB gain in PNSR.)
2. When using the floating point DCT/IDCT, the outputs of libjpeg v6b and
libjpeg-turbo can differ for the following reasons:
- When not using the SIMD extensions, libjpeg-turbo uses the more accurate
(and slightly faster) floating point IDCT algorithm introduced in libjpeg
v8a as opposed to the algorithm used in libjpeg v6b. It should be noted,
however, that this algorithm basically brings the accuracy of the floating
point IDCT in line with the accuracy of the slow integer IDCT. The floating
point DCT/IDCT algorithms are mainly a legacy feature, and they do not
produce significantly more accuracy than the slow integer algorithms (to put
numbers on this, the typical difference in PNSR between the two algorithms
is less than 0.10 dB, whereas changing the quality level by 1 in the upper
range of the quality scale is typically more like a 1.0 dB difference.)
- The SSE/SSE2 floating point DCT implementation in libjpeg-turbo is ever
so slightly more accurate than the implementation in libjpeg v6b, but not
by any amount perceptible to human vision (generally in the range of 0.01
to 0.08 dB gain in PNSR.)
- When not using the SIMD extensions, libjpeg-turbo uses the more accurate
(and slightly faster) floating point IDCT algorithm introduced in libjpeg
v8a as opposed to the algorithm used in libjpeg v6b. It should be noted,
however, that this algorithm basically brings the accuracy of the
floating point IDCT in line with the accuracy of the accurate integer
IDCT. The floating point DCT/IDCT algorithms are mainly a legacy
feature, and they do not produce significantly more accuracy than the
accurate integer algorithms. (To put numbers on this, the typical
difference in PNSR between the two algorithms is less than 0.10 dB,
whereas changing the quality level by 1 in the upper range of the quality
scale is typically more like a 1.0 dB difference.)
- If the floating point algorithms in libjpeg-turbo are not implemented
using SIMD instructions on a particular platform, then the accuracy of
the floating point DCT/IDCT can depend on the compiler settings.
- If the floating point algorithms in libjpeg-turbo are not implemented using
SIMD instructions on a particular platform, then the accuracy of the
floating point DCT/IDCT can depend on the compiler settings.
While libjpeg-turbo does emulate the libjpeg v8 API/ABI, under the hood it is
still using the same algorithms as libjpeg v6b, so there are several specific
@@ -355,7 +340,7 @@ The algorithm used by the SIMD-accelerated quantization function cannot produce
correct results whenever the fast integer forward DCT is used along with a JPEG
quality of 98-100. Thus, libjpeg-turbo must use the non-SIMD quantization
function in those cases. This causes performance to drop by as much as 40%.
It is therefore strongly advised that you use the accurate integer forward DCT
It is therefore strongly advised that you use the slow integer forward DCT
whenever encoding images with a JPEG quality of 98 or higher.
+42 -29
View File
@@ -9,52 +9,65 @@
/* libjpeg-turbo version in integer form */
#define LIBJPEG_TURBO_VERSION_NUMBER @LIBJPEG_TURBO_VERSION_NUMBER@
/* Support arithmetic encoding when using 8-bit samples */
/* Support arithmetic encoding */
#cmakedefine C_ARITH_CODING_SUPPORTED 1
/* Support arithmetic decoding when using 8-bit samples */
/* Support arithmetic decoding */
#cmakedefine D_ARITH_CODING_SUPPORTED 1
/* Support in-memory source/destination managers */
#define MEM_SRCDST_SUPPORTED 1
#cmakedefine MEM_SRCDST_SUPPORTED 1
/* Use accelerated SIMD routines when using 8-bit samples */
/* Use accelerated SIMD routines. */
#cmakedefine WITH_SIMD 1
/* This version of libjpeg-turbo supports run-time selection of data precision,
* so BITS_IN_JSAMPLE is no longer used to specify the data precision at build
* time. However, some downstream software expects the macro to be defined.
* Since 12-bit data precision is an opt-in feature that requires explicitly
* calling 12-bit-specific libjpeg API functions and using 12-bit-specific data
* types, the unmodified portion of the libjpeg API still behaves as if it were
* built for 8-bit precision, and JSAMPLE is still literally an 8-bit data
* type. Thus, it is correct to define BITS_IN_JSAMPLE to 8 here.
/*
* Define BITS_IN_JSAMPLE as either
* 8 for 8-bit sample values (the usual setting)
* 12 for 12-bit sample values
* Only 8 and 12 are legal data precisions for lossy JPEG according to the
* JPEG standard, and the IJG code does not support anything else!
* We do not support run-time selection of data precision, sorry.
*/
#ifndef BITS_IN_JSAMPLE
#define BITS_IN_JSAMPLE 8
#endif
#ifdef _WIN32
#define BITS_IN_JSAMPLE @BITS_IN_JSAMPLE@ /* use 8 or 12 */
#undef RIGHT_SHIFT_IS_UNSIGNED
/* Define to 1 if you have the <locale.h> header file. */
#cmakedefine HAVE_LOCALE_H 1
/* Define "boolean" as unsigned char, not int, per Windows custom */
#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 */
/* Define to 1 if you have the <stddef.h> header file. */
#cmakedefine HAVE_STDDEF_H 1
/* Define "INT32" as int, not long, per Windows custom */
#if !(defined(_BASETSD_H_) || defined(_BASETSD_H)) /* don't conflict if basetsd.h already read */
typedef short INT16;
typedef signed int INT32;
#endif
#define XMD_H /* prevent jmorecfg.h from redefining it */
/* Define to 1 if you have the <stdlib.h> header file. */
#cmakedefine HAVE_STDLIB_H 1
#else
/* Define if you need to include <sys/types.h> to get size_t. */
#cmakedefine NEED_SYS_TYPES_H 1
/* Define if you have BSD-like bzero and bcopy in <strings.h> rather than
memset/memcpy in <string.h>. */
#cmakedefine NEED_BSD_STRINGS 1
/* Define to 1 if the system has the type `unsigned char'. */
#cmakedefine HAVE_UNSIGNED_CHAR 1
/* Define to 1 if the system has the type `unsigned short'. */
#cmakedefine HAVE_UNSIGNED_SHORT 1
/* Compiler does not support pointers to undefined structures. */
#cmakedefine INCOMPLETE_TYPES_BROKEN 1
/* Define if your (broken) compiler shifts signed values as if they were
unsigned. */
#cmakedefine RIGHT_SHIFT_IS_UNSIGNED 1
/* Define to 1 if type `char' is unsigned and you are not using gcc. */
#ifndef __CHAR_UNSIGNED__
#cmakedefine __CHAR_UNSIGNED__ 1
#endif
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
+34
View File
@@ -0,0 +1,34 @@
#define JPEG_LIB_VERSION @JPEG_LIB_VERSION@
#define LIBJPEG_TURBO_VERSION @VERSION@
#define LIBJPEG_TURBO_VERSION_NUMBER @LIBJPEG_TURBO_VERSION_NUMBER@
#cmakedefine C_ARITH_CODING_SUPPORTED
#cmakedefine D_ARITH_CODING_SUPPORTED
#cmakedefine MEM_SRCDST_SUPPORTED
#cmakedefine WITH_SIMD
#define BITS_IN_JSAMPLE @BITS_IN_JSAMPLE@ /* use 8 or 12 */
#define HAVE_STDDEF_H
#define HAVE_STDLIB_H
#undef NEED_SYS_TYPES_H
#undef NEED_BSD_STRINGS
#define HAVE_UNSIGNED_CHAR
#define HAVE_UNSIGNED_SHORT
#undef INCOMPLETE_TYPES_BROKEN
#undef RIGHT_SHIFT_IS_UNSIGNED
#undef __CHAR_UNSIGNED__
/* Define "boolean" as unsigned char, not int, per Windows custom */
#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 */
/* Define "INT32" as int, not long, per Windows custom */
#if !(defined(_BASETSD_H_) || defined(_BASETSD_H)) /* don't conflict if basetsd.h already read */
typedef short INT16;
typedef signed int INT32;
#endif
#define XMD_H /* prevent jmorecfg.h from redefining it */
+10 -47
View File
@@ -1,17 +1,19 @@
/* libjpeg-turbo build number */
#define BUILD "@BUILD@"
/* How to hide global symbols. */
#define HIDDEN @HIDDEN@
/* Compiler's inline keyword */
#undef inline
/* How to obtain function inlining. */
#define INLINE @INLINE@
/* How to obtain thread-local storage */
#define THREAD_LOCAL @THREAD_LOCAL@
#ifndef INLINE
#if defined(__GNUC__)
#define INLINE inline __attribute__((always_inline))
#elif defined(_MSC_VER)
#define INLINE __forceinline
#else
#define INLINE
#endif
#endif
/* Define to the full name of this package. */
#define PACKAGE_NAME "@CMAKE_PROJECT_NAME@"
@@ -20,7 +22,7 @@
#define VERSION "@VERSION@"
/* The size of `size_t', as computed by sizeof. */
#define SIZEOF_SIZE_T @SIZE_T@
#define SIZEOF_SIZE_T @SIZEOF_SIZE_T@
/* Define if your compiler has __builtin_ctzl() and sizeof(unsigned long) == sizeof(size_t). */
#cmakedefine HAVE_BUILTIN_CTZL
@@ -35,42 +37,3 @@
#define HAVE_BITSCANFORWARD
#endif
#endif
#if defined(__has_attribute)
#if __has_attribute(fallthrough)
#define FALLTHROUGH __attribute__((fallthrough));
#else
#define FALLTHROUGH
#endif
#else
#define FALLTHROUGH
#endif
/*
* Define BITS_IN_JSAMPLE as either
* 8 for 8-bit sample values (the usual setting)
* 12 for 12-bit sample values
* Only 8 and 12 are legal data precisions for lossy JPEG according to the
* JPEG standard, and the IJG code does not support anything else!
*/
#ifndef BITS_IN_JSAMPLE
#define BITS_IN_JSAMPLE 8 /* use 8 or 12 */
#endif
#undef C_ARITH_CODING_SUPPORTED
#undef D_ARITH_CODING_SUPPORTED
#undef WITH_SIMD
#if BITS_IN_JSAMPLE == 8
/* Support arithmetic encoding */
#cmakedefine C_ARITH_CODING_SUPPORTED 1
/* Support arithmetic decoding */
#cmakedefine D_ARITH_CODING_SUPPORTED 1
/* Use accelerated SIMD routines. */
#cmakedefine WITH_SIMD 1
#endif
-56
View File
@@ -1,56 +0,0 @@
/*
* jversion.h
*
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-2020, Thomas G. Lane, Guido Vollbeding.
* libjpeg-turbo Modifications:
* Copyright (C) 2010, 2012-2024, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
* This file contains software version identification.
*/
#if JPEG_LIB_VERSION >= 80
#define JVERSION "8d 15-Jan-2012"
#elif JPEG_LIB_VERSION >= 70
#define JVERSION "7 27-Jun-2009"
#else
#define JVERSION "6b 27-Mar-1998"
#endif
/*
* NOTE: It is our convention to place the authors in the following order:
* - libjpeg-turbo authors (2009-) in descending order of the date of their
* most recent contribution to the project, then in ascending order of the
* date of their first contribution to the project, then in alphabetical
* order
* - Upstream authors in descending order of the date of the first inclusion of
* their code
*/
#define JCOPYRIGHT1 \
"Copyright (C) 2009-2024 D. R. Commander\n" \
"Copyright (C) 2015, 2020 Google, Inc.\n" \
"Copyright (C) 2019-2020 Arm Limited\n" \
"Copyright (C) 2015-2016, 2018 Matthieu Darbois\n" \
"Copyright (C) 2011-2016 Siarhei Siamashka\n" \
"Copyright (C) 2015 Intel Corporation\n"
#define JCOPYRIGHT2 \
"Copyright (C) 2013-2014 Linaro Limited\n" \
"Copyright (C) 2013-2014 MIPS Technologies, Inc.\n" \
"Copyright (C) 2009, 2012 Pierre Ossman for Cendio AB\n" \
"Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies)\n" \
"Copyright (C) 1999-2006 MIYASAKA Masaru\n" \
"Copyright (C) 1999 Ken Murchison\n" \
"Copyright (C) 1991-2020 Thomas G. Lane, Guido Vollbeding\n"
#define JCOPYRIGHT_SHORT \
"Copyright (C) @COPYRIGHT_YEAR@ The libjpeg-turbo Project and many others"
-841
View File
@@ -1,841 +0,0 @@
/*
* cjpeg.c
*
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2003-2011 by Guido Vollbeding.
* Lossless JPEG Modifications:
* Copyright (C) 1999, Ken Murchison.
* libjpeg-turbo Modifications:
* Copyright (C) 2010, 2013-2014, 2017, 2019-2022, 2024, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
* This file contains a command-line user interface for the JPEG compressor.
* It should work on any system with Unix- or MS-DOS-style command lines.
*
* Two different command line styles are permitted, depending on the
* compile-time switch TWO_FILE_COMMANDLINE:
* cjpeg [options] inputfile outputfile
* cjpeg [options] [inputfile]
* In the second style, output is always to standard output, which you'd
* normally redirect to a file or pipe to some other program. Input is
* either from a named file or from standard input (typically redirected).
* The second style is convenient on Unix but is unhelpful on systems that
* don't support pipes. Also, you MUST use the first style if your system
* doesn't do binary I/O to stdin/stdout.
* To simplify script writing, the "-outfile" switch is provided. The syntax
* cjpeg [options] -outfile outputfile inputfile
* works regardless of which command line style is used.
*/
#ifdef _MSC_VER
#define _CRT_SECURE_NO_DEPRECATE
#endif
#ifdef CJPEG_FUZZER
#define JPEG_INTERNALS
#endif
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
#include "jversion.h" /* for version message */
#include "jconfigint.h"
/* Create the add-on message string table. */
#define JMESSAGE(code, string) string,
static const char * const cdjpeg_message_table[] = {
#include "cderror.h"
NULL
};
/*
* This routine determines what format the input file is,
* and selects the appropriate input-reading module.
*
* To determine which family of input formats the file belongs to,
* we may look only at the first byte of the file, since C does not
* guarantee that more than one character can be pushed back with ungetc.
* Looking at additional bytes would require one of these approaches:
* 1) assume we can fseek() the input file (fails for piped input);
* 2) assume we can push back more than one character (works in
* some C implementations, but unportable);
* 3) provide our own buffering (breaks input readers that want to use
* stdio directly);
* or 4) don't put back the data, and modify the input_init methods to assume
* they start reading after the start of file.
* #1 is attractive for MS-DOS but is untenable on Unix.
*
* The most portable solution for file types that can't be identified by their
* first byte is to make the user tell us what they are. This is also the
* only approach for "raw" file types that contain only arbitrary values.
* We presently apply this method for Targa files. Most of the time Targa
* files start with 0x00, so we recognize that case. Potentially, however,
* a Targa file could start with any byte value (byte 0 is the length of the
* seldom-used ID field), so we provide a switch to force Targa input mode.
*/
static boolean is_targa; /* records user -targa switch */
LOCAL(cjpeg_source_ptr)
select_file_type(j_compress_ptr cinfo, FILE *infile)
{
int c;
if (is_targa) {
#ifdef TARGA_SUPPORTED
return jinit_read_targa(cinfo);
#else
ERREXIT(cinfo, JERR_TGA_NOTCOMP);
#endif
}
if ((c = getc(infile)) == EOF)
ERREXIT(cinfo, JERR_INPUT_EMPTY);
if (ungetc(c, infile) == EOF)
ERREXIT(cinfo, JERR_UNGETC_FAILED);
switch (c) {
#ifdef BMP_SUPPORTED
case 'B':
return jinit_read_bmp(cinfo, TRUE);
#endif
#ifdef GIF_SUPPORTED
case 'G':
if (cinfo->data_precision == 16) {
#ifdef C_LOSSLESS_SUPPORTED
return j16init_read_gif(cinfo);
#else
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
break;
#endif
} else if (cinfo->data_precision == 12)
return j12init_read_gif(cinfo);
else
return jinit_read_gif(cinfo);
#endif
#ifdef PPM_SUPPORTED
case 'P':
if (cinfo->data_precision == 16) {
#ifdef C_LOSSLESS_SUPPORTED
return j16init_read_ppm(cinfo);
#else
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
break;
#endif
} else if (cinfo->data_precision == 12)
return j12init_read_ppm(cinfo);
else
return jinit_read_ppm(cinfo);
#endif
#ifdef TARGA_SUPPORTED
case 0x00:
return jinit_read_targa(cinfo);
#endif
default:
ERREXIT(cinfo, JERR_UNKNOWN_FORMAT);
break;
}
return NULL; /* suppress compiler warnings */
}
/*
* Argument-parsing code.
* The switch parser is designed to be useful with DOS-style command line
* syntax, ie, intermixed switches and file names, where only the switches
* to the left of a given file name affect processing of that file.
* The main program in this file doesn't actually use this capability...
*/
static const char *progname; /* program name for error messages */
static char *icc_filename; /* for -icc switch */
static char *outfilename; /* for -outfile switch */
static boolean memdst; /* for -memdst switch */
static boolean report; /* for -report switch */
static boolean strict; /* for -strict switch */
#ifdef CJPEG_FUZZER
#include <setjmp.h>
struct my_error_mgr {
struct jpeg_error_mgr pub;
jmp_buf setjmp_buffer;
};
void my_error_exit(j_common_ptr cinfo)
{
struct my_error_mgr *myerr = (struct my_error_mgr *)cinfo->err;
longjmp(myerr->setjmp_buffer, 1);
}
static void my_emit_message_fuzzer(j_common_ptr cinfo, int msg_level)
{
if (msg_level < 0)
cinfo->err->num_warnings++;
}
#define HANDLE_ERROR() { \
if (cinfo.global_state > CSTATE_START) { \
if (memdst && outbuffer) \
(*cinfo.dest->term_destination) (&cinfo); \
jpeg_abort_compress(&cinfo); \
} \
jpeg_destroy_compress(&cinfo); \
if (input_file != stdin && input_file != NULL) \
fclose(input_file); \
if (memdst) \
free(outbuffer); \
return EXIT_FAILURE; \
}
#endif
LOCAL(void)
usage(void)
/* complain about bad command line */
{
fprintf(stderr, "usage: %s [switches] ", progname);
#ifdef TWO_FILE_COMMANDLINE
fprintf(stderr, "inputfile outputfile\n");
#else
fprintf(stderr, "[inputfile]\n");
#endif
fprintf(stderr, "Switches (names may be abbreviated):\n");
fprintf(stderr, " -quality N[,...] Compression quality (0..100; 5-95 is most useful range,\n");
fprintf(stderr, " default is 75)\n");
fprintf(stderr, " -grayscale Create monochrome JPEG file\n");
fprintf(stderr, " -rgb Create RGB JPEG file\n");
#ifdef ENTROPY_OPT_SUPPORTED
fprintf(stderr, " -optimize Optimize Huffman table (smaller file, but slow compression)\n");
#endif
#ifdef C_PROGRESSIVE_SUPPORTED
fprintf(stderr, " -progressive Create progressive JPEG file\n");
#endif
#ifdef TARGA_SUPPORTED
fprintf(stderr, " -targa Input file is Targa format (usually not needed)\n");
#endif
fprintf(stderr, "Switches for advanced users:\n");
fprintf(stderr, " -precision N Create JPEG file with N-bit data precision\n");
#ifdef C_LOSSLESS_SUPPORTED
fprintf(stderr, " (N is 8, 12, or 16; default is 8; if N is 16, then -lossless\n");
fprintf(stderr, " must also be specified)\n");
#else
fprintf(stderr, " (N is 8 or 12; default is 8)\n");
#endif
#ifdef C_LOSSLESS_SUPPORTED
fprintf(stderr, " -lossless psv[,Pt] Create lossless JPEG file\n");
#endif
#ifdef C_ARITH_CODING_SUPPORTED
fprintf(stderr, " -arithmetic Use arithmetic coding\n");
#endif
#ifdef DCT_ISLOW_SUPPORTED
fprintf(stderr, " -dct int Use accurate integer DCT method%s\n",
(JDCT_DEFAULT == JDCT_ISLOW ? " (default)" : ""));
#endif
#ifdef DCT_IFAST_SUPPORTED
fprintf(stderr, " -dct fast Use less accurate integer DCT method [legacy feature]%s\n",
(JDCT_DEFAULT == JDCT_IFAST ? " (default)" : ""));
#endif
#ifdef DCT_FLOAT_SUPPORTED
fprintf(stderr, " -dct float Use floating-point DCT method [legacy feature]%s\n",
(JDCT_DEFAULT == JDCT_FLOAT ? " (default)" : ""));
#endif
fprintf(stderr, " -icc FILE Embed ICC profile contained in FILE\n");
fprintf(stderr, " -restart N Set restart interval in rows, or in blocks with B\n");
#ifdef INPUT_SMOOTHING_SUPPORTED
fprintf(stderr, " -smooth N Smooth dithered input (N=1..100 is strength)\n");
#endif
fprintf(stderr, " -maxmemory N Maximum memory to use (in kbytes)\n");
fprintf(stderr, " -outfile name Specify name for output file\n");
fprintf(stderr, " -memdst Compress to memory instead of file (useful for benchmarking)\n");
fprintf(stderr, " -report Report compression progress\n");
fprintf(stderr, " -strict Treat all warnings as fatal\n");
fprintf(stderr, " -verbose or -debug Emit debug output\n");
fprintf(stderr, " -version Print version information and exit\n");
fprintf(stderr, "Switches for wizards:\n");
fprintf(stderr, " -baseline Force baseline quantization tables\n");
fprintf(stderr, " -qtables FILE Use quantization tables given in FILE\n");
fprintf(stderr, " -qslots N[,...] Set component quantization tables\n");
fprintf(stderr, " -sample HxV[,...] Set component sampling factors\n");
#ifdef C_MULTISCAN_FILES_SUPPORTED
fprintf(stderr, " -scans FILE Create multi-scan JPEG per script FILE\n");
#endif
exit(EXIT_FAILURE);
}
LOCAL(int)
parse_switches(j_compress_ptr cinfo, int argc, char **argv,
int last_file_arg_seen, boolean for_real)
/* Parse optional switches.
* Returns argv[] index of first file-name argument (== argc if none).
* Any file names with indexes <= last_file_arg_seen are ignored;
* they have presumably been processed in a previous iteration.
* (Pass 0 for last_file_arg_seen on the first or only iteration.)
* for_real is FALSE on the first (dummy) pass; we may skip any expensive
* processing.
*/
{
int argn;
char *arg;
#ifdef C_LOSSLESS_SUPPORTED
int psv, pt = 0;
#endif
boolean force_baseline;
boolean simple_progressive;
char *qualityarg = NULL; /* saves -quality parm if any */
char *qtablefile = NULL; /* saves -qtables filename if any */
char *qslotsarg = NULL; /* saves -qslots parm if any */
char *samplearg = NULL; /* saves -sample parm if any */
char *scansarg = NULL; /* saves -scans parm if any */
/* Set up default JPEG parameters. */
force_baseline = FALSE; /* by default, allow 16-bit quantizers */
simple_progressive = FALSE;
is_targa = FALSE;
icc_filename = NULL;
outfilename = NULL;
memdst = FALSE;
report = FALSE;
strict = FALSE;
cinfo->err->trace_level = 0;
/* Scan command line options, adjust parameters */
for (argn = 1; argn < argc; argn++) {
arg = argv[argn];
if (*arg != '-') {
/* Not a switch, must be a file name argument */
if (argn <= last_file_arg_seen) {
outfilename = NULL; /* -outfile applies to just one input file */
continue; /* ignore this name if previously processed */
}
break; /* else done parsing switches */
}
arg++; /* advance past switch marker character */
if (keymatch(arg, "arithmetic", 1)) {
/* Use arithmetic coding. */
#ifdef C_ARITH_CODING_SUPPORTED
cinfo->arith_code = TRUE;
#else
fprintf(stderr, "%s: sorry, arithmetic coding not supported\n",
progname);
exit(EXIT_FAILURE);
#endif
} else if (keymatch(arg, "baseline", 1)) {
/* Force baseline-compatible output (8-bit quantizer values). */
force_baseline = TRUE;
} else if (keymatch(arg, "dct", 2)) {
/* Select DCT algorithm. */
if (++argn >= argc) /* advance to next argument */
usage();
if (keymatch(argv[argn], "int", 1)) {
cinfo->dct_method = JDCT_ISLOW;
} else if (keymatch(argv[argn], "fast", 2)) {
cinfo->dct_method = JDCT_IFAST;
} else if (keymatch(argv[argn], "float", 2)) {
cinfo->dct_method = JDCT_FLOAT;
} else
usage();
} else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) {
/* Enable debug printouts. */
/* On first -d, print version identification */
static boolean printed_version = FALSE;
if (!printed_version) {
fprintf(stderr, "%s version %s (build %s)\n",
PACKAGE_NAME, VERSION, BUILD);
fprintf(stderr, JCOPYRIGHT1);
fprintf(stderr, JCOPYRIGHT2 "\n");
fprintf(stderr, "Emulating The Independent JPEG Group's software, version %s\n\n",
JVERSION);
printed_version = TRUE;
}
cinfo->err->trace_level++;
} else if (keymatch(arg, "version", 4)) {
fprintf(stderr, "%s version %s (build %s)\n",
PACKAGE_NAME, VERSION, BUILD);
exit(EXIT_SUCCESS);
} else if (keymatch(arg, "grayscale", 2) ||
keymatch(arg, "greyscale", 2)) {
/* Force a monochrome JPEG file to be generated. */
jpeg_set_colorspace(cinfo, JCS_GRAYSCALE);
} else if (keymatch(arg, "rgb", 3)) {
/* Force an RGB JPEG file to be generated. */
jpeg_set_colorspace(cinfo, JCS_RGB);
} else if (keymatch(arg, "icc", 1)) {
/* Set ICC filename. */
if (++argn >= argc) /* advance to next argument */
usage();
icc_filename = argv[argn];
} else if (keymatch(arg, "lossless", 1)) {
/* Enable lossless mode. */
#ifdef C_LOSSLESS_SUPPORTED
char ch = ',', *ptr;
if (++argn >= argc) /* advance to next argument */
usage();
if (sscanf(argv[argn], "%d%c", &psv, &ch) < 1 || ch != ',')
usage();
ptr = argv[argn];
while (*ptr && *ptr++ != ','); /* advance to next segment of arg
string */
if (*ptr)
sscanf(ptr, "%d", &pt);
jpeg_enable_lossless(cinfo, psv, pt);
#else
fprintf(stderr, "%s: sorry, lossless output was not compiled\n",
progname);
exit(EXIT_FAILURE);
#endif
} else if (keymatch(arg, "maxmemory", 3)) {
/* Maximum memory in Kb (or Mb with 'm'). */
long lval;
char ch = 'x';
if (++argn >= argc) /* advance to next argument */
usage();
if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1)
usage();
if (ch == 'm' || ch == 'M')
lval *= 1000L;
cinfo->mem->max_memory_to_use = lval * 1000L;
} else if (keymatch(arg, "optimize", 1) || keymatch(arg, "optimise", 1)) {
/* Enable entropy parm optimization. */
#ifdef ENTROPY_OPT_SUPPORTED
cinfo->optimize_coding = TRUE;
#else
fprintf(stderr, "%s: sorry, entropy optimization was not compiled in\n",
progname);
exit(EXIT_FAILURE);
#endif
} else if (keymatch(arg, "outfile", 4)) {
/* Set output file name. */
if (++argn >= argc) /* advance to next argument */
usage();
outfilename = argv[argn]; /* save it away for later use */
} else if (keymatch(arg, "precision", 3)) {
/* Set data precision. */
int val;
if (++argn >= argc) /* advance to next argument */
usage();
if (sscanf(argv[argn], "%d", &val) != 1)
usage();
#ifdef C_LOSSLESS_SUPPORTED
if (val != 8 && val != 12 && val != 16)
#else
if (val != 8 && val != 12)
#endif
usage();
cinfo->data_precision = val;
} else if (keymatch(arg, "progressive", 3)) {
/* Select simple progressive mode. */
#ifdef C_PROGRESSIVE_SUPPORTED
simple_progressive = TRUE;
/* We must postpone execution until num_components is known. */
#else
fprintf(stderr, "%s: sorry, progressive output was not compiled in\n",
progname);
exit(EXIT_FAILURE);
#endif
} else if (keymatch(arg, "memdst", 2)) {
/* Use in-memory destination manager */
memdst = TRUE;
} else if (keymatch(arg, "quality", 1)) {
/* Quality ratings (quantization table scaling factors). */
if (++argn >= argc) /* advance to next argument */
usage();
qualityarg = argv[argn];
} else if (keymatch(arg, "qslots", 2)) {
/* Quantization table slot numbers. */
if (++argn >= argc) /* advance to next argument */
usage();
qslotsarg = argv[argn];
/* Must delay setting qslots until after we have processed any
* colorspace-determining switches, since jpeg_set_colorspace sets
* default quant table numbers.
*/
} else if (keymatch(arg, "qtables", 2)) {
/* Quantization tables fetched from file. */
if (++argn >= argc) /* advance to next argument */
usage();
qtablefile = argv[argn];
/* We postpone actually reading the file in case -quality comes later. */
} else if (keymatch(arg, "report", 3)) {
report = TRUE;
} else if (keymatch(arg, "restart", 1)) {
/* Restart interval in MCU rows (or in MCUs with 'b'). */
long lval;
char ch = 'x';
if (++argn >= argc) /* advance to next argument */
usage();
if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1)
usage();
if (lval < 0 || lval > 65535L)
usage();
if (ch == 'b' || ch == 'B') {
cinfo->restart_interval = (unsigned int)lval;
cinfo->restart_in_rows = 0; /* else prior '-restart n' overrides me */
} else {
cinfo->restart_in_rows = (int)lval;
/* restart_interval will be computed during startup */
}
} else if (keymatch(arg, "sample", 2)) {
/* Set sampling factors. */
if (++argn >= argc) /* advance to next argument */
usage();
samplearg = argv[argn];
/* Must delay setting sample factors until after we have processed any
* colorspace-determining switches, since jpeg_set_colorspace sets
* default sampling factors.
*/
} else if (keymatch(arg, "scans", 4)) {
/* Set scan script. */
#ifdef C_MULTISCAN_FILES_SUPPORTED
if (++argn >= argc) /* advance to next argument */
usage();
scansarg = argv[argn];
/* We must postpone reading the file in case -progressive appears. */
#else
fprintf(stderr, "%s: sorry, multi-scan output was not compiled in\n",
progname);
exit(EXIT_FAILURE);
#endif
} else if (keymatch(arg, "smooth", 2)) {
/* Set input smoothing factor. */
int val;
if (++argn >= argc) /* advance to next argument */
usage();
if (sscanf(argv[argn], "%d", &val) != 1)
usage();
if (val < 0 || val > 100)
usage();
cinfo->smoothing_factor = val;
} else if (keymatch(arg, "strict", 2)) {
strict = TRUE;
} else if (keymatch(arg, "targa", 1)) {
/* Input file is Targa format. */
is_targa = TRUE;
} else {
usage(); /* bogus switch */
}
}
/* Post-switch-scanning cleanup */
if (for_real) {
/* Set quantization tables for selected quality. */
/* Some or all may be overridden if -qtables is present. */
if (qualityarg != NULL) /* process -quality if it was present */
if (!set_quality_ratings(cinfo, qualityarg, force_baseline))
usage();
if (qtablefile != NULL) /* process -qtables if it was present */
if (!read_quant_tables(cinfo, qtablefile, force_baseline))
usage();
if (qslotsarg != NULL) /* process -qslots if it was present */
if (!set_quant_slots(cinfo, qslotsarg))
usage();
if (samplearg != NULL) /* process -sample if it was present */
if (!set_sample_factors(cinfo, samplearg))
usage();
#ifdef C_PROGRESSIVE_SUPPORTED
if (simple_progressive) /* process -progressive; -scans can override */
jpeg_simple_progression(cinfo);
#endif
#ifdef C_MULTISCAN_FILES_SUPPORTED
if (scansarg != NULL) /* process -scans if it was present */
if (!read_scan_script(cinfo, scansarg))
usage();
#endif
}
return argn; /* return index of next arg (file name) */
}
METHODDEF(void)
my_emit_message(j_common_ptr cinfo, int msg_level)
{
if (msg_level < 0) {
/* Treat warning as fatal */
cinfo->err->error_exit(cinfo);
} else {
if (cinfo->err->trace_level >= msg_level)
cinfo->err->output_message(cinfo);
}
}
/*
* The main program.
*/
int
main(int argc, char **argv)
{
struct jpeg_compress_struct cinfo;
#ifdef CJPEG_FUZZER
struct my_error_mgr myerr;
struct jpeg_error_mgr &jerr = myerr.pub;
#else
struct jpeg_error_mgr jerr;
#endif
struct cdjpeg_progress_mgr progress;
int file_index;
cjpeg_source_ptr src_mgr;
FILE *input_file = NULL;
FILE *icc_file;
JOCTET *icc_profile = NULL;
long icc_len = 0;
FILE *output_file = NULL;
unsigned char *outbuffer = NULL;
unsigned long outsize = 0;
JDIMENSION num_scanlines;
progname = argv[0];
if (progname == NULL || progname[0] == 0)
progname = "cjpeg"; /* in case C library doesn't provide it */
/* Initialize the JPEG compression object with default error handling. */
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
/* Add some application-specific error messages (from cderror.h) */
jerr.addon_message_table = cdjpeg_message_table;
jerr.first_addon_message = JMSG_FIRSTADDONCODE;
jerr.last_addon_message = JMSG_LASTADDONCODE;
/* Initialize JPEG parameters.
* Much of this may be overridden later.
* In particular, we don't yet know the input file's color space,
* but we need to provide some value for jpeg_set_defaults() to work.
*/
cinfo.in_color_space = JCS_RGB; /* arbitrary guess */
jpeg_set_defaults(&cinfo);
/* Scan command line to find file names.
* It is convenient to use just one switch-parsing routine, but the switch
* values read here are ignored; we will rescan the switches after opening
* the input file.
*/
file_index = parse_switches(&cinfo, argc, argv, 0, FALSE);
if (strict)
jerr.emit_message = my_emit_message;
#ifdef TWO_FILE_COMMANDLINE
if (!memdst) {
/* Must have either -outfile switch or explicit output file name */
if (outfilename == NULL) {
if (file_index != argc - 2) {
fprintf(stderr, "%s: must name one input and one output file\n",
progname);
usage();
}
outfilename = argv[file_index + 1];
} else {
if (file_index != argc - 1) {
fprintf(stderr, "%s: must name one input and one output file\n",
progname);
usage();
}
}
}
#else
/* Unix style: expect zero or one file name */
if (file_index < argc - 1) {
fprintf(stderr, "%s: only one input file\n", progname);
usage();
}
#endif /* TWO_FILE_COMMANDLINE */
/* Open the input file. */
if (file_index < argc) {
if ((input_file = fopen(argv[file_index], READ_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open %s\n", progname, argv[file_index]);
exit(EXIT_FAILURE);
}
} else {
/* default input file is stdin */
input_file = read_stdin();
}
/* Open the output file. */
if (outfilename != NULL) {
if ((output_file = fopen(outfilename, WRITE_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open %s\n", progname, outfilename);
exit(EXIT_FAILURE);
}
} else if (!memdst) {
/* default output file is stdout */
output_file = write_stdout();
}
if (icc_filename != NULL) {
if ((icc_file = fopen(icc_filename, READ_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open %s\n", progname, icc_filename);
exit(EXIT_FAILURE);
}
if (fseek(icc_file, 0, SEEK_END) < 0 ||
(icc_len = ftell(icc_file)) < 1 ||
fseek(icc_file, 0, SEEK_SET) < 0) {
fprintf(stderr, "%s: can't determine size of %s\n", progname,
icc_filename);
exit(EXIT_FAILURE);
}
if ((icc_profile = (JOCTET *)malloc(icc_len)) == NULL) {
fprintf(stderr, "%s: can't allocate memory for ICC profile\n", progname);
fclose(icc_file);
exit(EXIT_FAILURE);
}
if (fread(icc_profile, icc_len, 1, icc_file) < 1) {
fprintf(stderr, "%s: can't read ICC profile from %s\n", progname,
icc_filename);
free(icc_profile);
fclose(icc_file);
exit(EXIT_FAILURE);
}
fclose(icc_file);
}
#ifdef CJPEG_FUZZER
jerr.error_exit = my_error_exit;
jerr.emit_message = my_emit_message_fuzzer;
if (setjmp(myerr.setjmp_buffer))
HANDLE_ERROR()
#endif
if (report) {
start_progress_monitor((j_common_ptr)&cinfo, &progress);
progress.report = report;
}
/* Figure out the input file format, and set up to read it. */
src_mgr = select_file_type(&cinfo, input_file);
src_mgr->input_file = input_file;
#ifdef CJPEG_FUZZER
src_mgr->max_pixels = 1048576;
#endif
/* Read the input file header to obtain file size & colorspace. */
(*src_mgr->start_input) (&cinfo, src_mgr);
/* Now that we know input colorspace, fix colorspace-dependent defaults */
jpeg_default_colorspace(&cinfo);
/* Adjust default compression parameters by re-parsing the options */
file_index = parse_switches(&cinfo, argc, argv, 0, TRUE);
/* Specify data destination for compression */
if (memdst)
jpeg_mem_dest(&cinfo, &outbuffer, &outsize);
else
jpeg_stdio_dest(&cinfo, output_file);
#ifdef CJPEG_FUZZER
if (setjmp(myerr.setjmp_buffer))
HANDLE_ERROR()
#endif
/* Start compressor */
jpeg_start_compress(&cinfo, TRUE);
if (icc_profile != NULL)
jpeg_write_icc_profile(&cinfo, icc_profile, (unsigned int)icc_len);
/* Process data */
if (cinfo.data_precision == 16) {
#ifdef C_LOSSLESS_SUPPORTED
while (cinfo.next_scanline < cinfo.image_height) {
num_scanlines = (*src_mgr->get_pixel_rows) (&cinfo, src_mgr);
(void)jpeg16_write_scanlines(&cinfo, src_mgr->buffer16, num_scanlines);
}
#else
ERREXIT1(&cinfo, JERR_BAD_PRECISION, cinfo.data_precision);
#endif
} else if (cinfo.data_precision == 12) {
while (cinfo.next_scanline < cinfo.image_height) {
num_scanlines = (*src_mgr->get_pixel_rows) (&cinfo, src_mgr);
(void)jpeg12_write_scanlines(&cinfo, src_mgr->buffer12, num_scanlines);
}
} else {
while (cinfo.next_scanline < cinfo.image_height) {
num_scanlines = (*src_mgr->get_pixel_rows) (&cinfo, src_mgr);
(void)jpeg_write_scanlines(&cinfo, src_mgr->buffer, num_scanlines);
}
}
/* Finish compression and release memory */
(*src_mgr->finish_input) (&cinfo, src_mgr);
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);
/* Close files, if we opened them */
if (input_file != stdin)
fclose(input_file);
if (output_file != stdout && output_file != NULL)
fclose(output_file);
if (report)
end_progress_monitor((j_common_ptr)&cinfo);
if (memdst) {
#ifndef CJPEG_FUZZER
fprintf(stderr, "Compressed size: %lu bytes\n", outsize);
#endif
free(outbuffer);
}
free(icc_profile);
/* All done. */
return (jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS);
}
-61
View File
@@ -1,61 +0,0 @@
/*
* cmyk.h
*
* Copyright (C) 2017-2018, 2022, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
* This file contains convenience functions for performing quick & dirty
* CMYK<->RGB conversion. This algorithm is suitable for testing purposes
* only. Properly converting between CMYK and RGB requires a color management
* system.
*/
#ifndef CMYK_H
#define CMYK_H
#include <jinclude.h>
#define JPEG_INTERNALS
#include <jpeglib.h>
#include "jsamplecomp.h"
/* Fully reversible */
INLINE
LOCAL(void)
rgb_to_cmyk(_JSAMPLE r, _JSAMPLE g, _JSAMPLE b,
_JSAMPLE *c, _JSAMPLE *m, _JSAMPLE *y, _JSAMPLE *k)
{
double ctmp = 1.0 - ((double)r / (double)_MAXJSAMPLE);
double mtmp = 1.0 - ((double)g / (double)_MAXJSAMPLE);
double ytmp = 1.0 - ((double)b / (double)_MAXJSAMPLE);
double ktmp = MIN(MIN(ctmp, mtmp), ytmp);
if (ktmp == 1.0) ctmp = mtmp = ytmp = 0.0;
else {
ctmp = (ctmp - ktmp) / (1.0 - ktmp);
mtmp = (mtmp - ktmp) / (1.0 - ktmp);
ytmp = (ytmp - ktmp) / (1.0 - ktmp);
}
*c = (_JSAMPLE)((double)_MAXJSAMPLE - ctmp * (double)_MAXJSAMPLE + 0.5);
*m = (_JSAMPLE)((double)_MAXJSAMPLE - mtmp * (double)_MAXJSAMPLE + 0.5);
*y = (_JSAMPLE)((double)_MAXJSAMPLE - ytmp * (double)_MAXJSAMPLE + 0.5);
*k = (_JSAMPLE)((double)_MAXJSAMPLE - ktmp * (double)_MAXJSAMPLE + 0.5);
}
/* Fully reversible only for C/M/Y/K values generated with rgb_to_cmyk() */
INLINE
LOCAL(void)
cmyk_to_rgb(_JSAMPLE c, _JSAMPLE m, _JSAMPLE y, _JSAMPLE k,
_JSAMPLE *r, _JSAMPLE *g, _JSAMPLE *b)
{
*r = (_JSAMPLE)((double)c * (double)k / (double)_MAXJSAMPLE + 0.5);
*g = (_JSAMPLE)((double)m * (double)k / (double)_MAXJSAMPLE + 0.5);
*b = (_JSAMPLE)((double)y * (double)k / (double)_MAXJSAMPLE + 0.5);
}
#endif /* CMYK_H */
-932
View File
@@ -1,932 +0,0 @@
/*
* djpeg.c
*
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2013-2019 by Guido Vollbeding.
* libjpeg-turbo Modifications:
* Copyright (C) 2010-2011, 2013-2017, 2019-2020, 2022-2024, D. R. Commander.
* Copyright (C) 2015, Google, Inc.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
* This file contains a command-line user interface for the JPEG decompressor.
* It should work on any system with Unix- or MS-DOS-style command lines.
*
* Two different command line styles are permitted, depending on the
* compile-time switch TWO_FILE_COMMANDLINE:
* djpeg [options] inputfile outputfile
* djpeg [options] [inputfile]
* In the second style, output is always to standard output, which you'd
* normally redirect to a file or pipe to some other program. Input is
* either from a named file or from standard input (typically redirected).
* The second style is convenient on Unix but is unhelpful on systems that
* don't support pipes. Also, you MUST use the first style if your system
* doesn't do binary I/O to stdin/stdout.
* To simplify script writing, the "-outfile" switch is provided. The syntax
* djpeg [options] -outfile outputfile inputfile
* works regardless of which command line style is used.
*/
#ifdef _MSC_VER
#define _CRT_SECURE_NO_DEPRECATE
#endif
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
#include "jversion.h" /* for version message */
#include "jconfigint.h"
#include <ctype.h> /* to declare isprint() */
/* Create the add-on message string table. */
#define JMESSAGE(code, string) string,
static const char * const cdjpeg_message_table[] = {
#include "cderror.h"
NULL
};
/*
* This list defines the known output image formats
* (not all of which need be supported by a given version).
* You can change the default output format by defining DEFAULT_FMT;
* indeed, you had better do so if you undefine PPM_SUPPORTED.
*/
typedef enum {
FMT_BMP, /* BMP format (Windows flavor) */
FMT_GIF, /* GIF format (LZW-compressed) */
FMT_GIF0, /* GIF format (uncompressed) */
FMT_OS2, /* BMP format (OS/2 flavor) */
FMT_PPM, /* PPM/PGM (PBMPLUS formats) */
FMT_TARGA, /* Targa format */
FMT_TIFF /* TIFF format */
} IMAGE_FORMATS;
#ifndef DEFAULT_FMT /* so can override from CFLAGS in Makefile */
#define DEFAULT_FMT FMT_PPM
#endif
static IMAGE_FORMATS requested_fmt;
/*
* Argument-parsing code.
* The switch parser is designed to be useful with DOS-style command line
* syntax, ie, intermixed switches and file names, where only the switches
* to the left of a given file name affect processing of that file.
* The main program in this file doesn't actually use this capability...
*/
static const char *progname; /* program name for error messages */
static char *icc_filename; /* for -icc switch */
static JDIMENSION max_scans; /* for -maxscans switch */
static char *outfilename; /* for -outfile switch */
static boolean memsrc; /* for -memsrc switch */
static boolean report; /* for -report switch */
static boolean skip, crop;
static JDIMENSION skip_start, skip_end;
static JDIMENSION crop_x, crop_y, crop_width, crop_height;
static boolean strict; /* for -strict switch */
#define INPUT_BUF_SIZE 4096
LOCAL(void)
usage(void)
/* complain about bad command line */
{
fprintf(stderr, "usage: %s [switches] ", progname);
#ifdef TWO_FILE_COMMANDLINE
fprintf(stderr, "inputfile outputfile\n");
#else
fprintf(stderr, "[inputfile]\n");
#endif
fprintf(stderr, "Switches (names may be abbreviated):\n");
fprintf(stderr, " -colors N Reduce image to no more than N colors\n");
fprintf(stderr, " -fast Fast, low-quality processing\n");
fprintf(stderr, " -grayscale Force grayscale output\n");
fprintf(stderr, " -rgb Force RGB output\n");
fprintf(stderr, " -rgb565 Force RGB565 output\n");
#ifdef IDCT_SCALING_SUPPORTED
fprintf(stderr, " -scale M/N Scale output image by fraction M/N, eg, 1/8\n");
#endif
#ifdef BMP_SUPPORTED
fprintf(stderr, " -bmp Select BMP output format (Windows style)%s\n",
(DEFAULT_FMT == FMT_BMP ? " (default)" : ""));
#endif
#ifdef GIF_SUPPORTED
fprintf(stderr, " -gif Select GIF output format (LZW-compressed)%s\n",
(DEFAULT_FMT == FMT_GIF ? " (default)" : ""));
fprintf(stderr, " -gif0 Select GIF output format (uncompressed)%s\n",
(DEFAULT_FMT == FMT_GIF0 ? " (default)" : ""));
#endif
#ifdef BMP_SUPPORTED
fprintf(stderr, " -os2 Select BMP output format (OS/2 style)%s\n",
(DEFAULT_FMT == FMT_OS2 ? " (default)" : ""));
#endif
#ifdef PPM_SUPPORTED
fprintf(stderr, " -pnm Select PBMPLUS (PPM/PGM) output format%s\n",
(DEFAULT_FMT == FMT_PPM ? " (default)" : ""));
#endif
#ifdef TARGA_SUPPORTED
fprintf(stderr, " -targa Select Targa output format%s\n",
(DEFAULT_FMT == FMT_TARGA ? " (default)" : ""));
#endif
fprintf(stderr, "Switches for advanced users:\n");
#ifdef DCT_ISLOW_SUPPORTED
fprintf(stderr, " -dct int Use accurate integer DCT method%s\n",
(JDCT_DEFAULT == JDCT_ISLOW ? " (default)" : ""));
#endif
#ifdef DCT_IFAST_SUPPORTED
fprintf(stderr, " -dct fast Use less accurate integer DCT method [legacy feature]%s\n",
(JDCT_DEFAULT == JDCT_IFAST ? " (default)" : ""));
#endif
#ifdef DCT_FLOAT_SUPPORTED
fprintf(stderr, " -dct float Use floating-point DCT method [legacy feature]%s\n",
(JDCT_DEFAULT == JDCT_FLOAT ? " (default)" : ""));
#endif
fprintf(stderr, " -dither fs Use F-S dithering (default)\n");
fprintf(stderr, " -dither none Don't use dithering in quantization\n");
fprintf(stderr, " -dither ordered Use ordered dither (medium speed, quality)\n");
fprintf(stderr, " -icc FILE Extract ICC profile to FILE\n");
#ifdef QUANT_2PASS_SUPPORTED
fprintf(stderr, " -map FILE Map to colors used in named image file\n");
#endif
fprintf(stderr, " -nosmooth Don't use high-quality upsampling\n");
#ifdef QUANT_1PASS_SUPPORTED
fprintf(stderr, " -onepass Use 1-pass quantization (fast, low quality)\n");
#endif
fprintf(stderr, " -maxmemory N Maximum memory to use (in kbytes)\n");
fprintf(stderr, " -maxscans N Maximum number of scans to allow in input file\n");
fprintf(stderr, " -outfile name Specify name for output file\n");
fprintf(stderr, " -memsrc Load input file into memory before decompressing\n");
fprintf(stderr, " -report Report decompression progress\n");
fprintf(stderr, " -skip Y0,Y1 Decompress all rows except those between Y0 and Y1 (inclusive)\n");
fprintf(stderr, " -crop WxH+X+Y Decompress only a rectangular subregion of the image\n");
fprintf(stderr, " [requires PBMPLUS (PPM/PGM), GIF, or Targa output format]\n");
fprintf(stderr, " -strict Treat all warnings as fatal\n");
fprintf(stderr, " -verbose or -debug Emit debug output\n");
fprintf(stderr, " -version Print version information and exit\n");
exit(EXIT_FAILURE);
}
LOCAL(int)
parse_switches(j_decompress_ptr cinfo, int argc, char **argv,
int last_file_arg_seen, boolean for_real)
/* Parse optional switches.
* Returns argv[] index of first file-name argument (== argc if none).
* Any file names with indexes <= last_file_arg_seen are ignored;
* they have presumably been processed in a previous iteration.
* (Pass 0 for last_file_arg_seen on the first or only iteration.)
* for_real is FALSE on the first (dummy) pass; we may skip any expensive
* processing.
*/
{
int argn;
char *arg;
/* Set up default JPEG parameters. */
requested_fmt = DEFAULT_FMT; /* set default output file format */
icc_filename = NULL;
max_scans = 0;
outfilename = NULL;
memsrc = FALSE;
report = FALSE;
skip = FALSE;
crop = FALSE;
strict = FALSE;
cinfo->err->trace_level = 0;
/* Scan command line options, adjust parameters */
for (argn = 1; argn < argc; argn++) {
arg = argv[argn];
if (*arg != '-') {
/* Not a switch, must be a file name argument */
if (argn <= last_file_arg_seen) {
outfilename = NULL; /* -outfile applies to just one input file */
continue; /* ignore this name if previously processed */
}
break; /* else done parsing switches */
}
arg++; /* advance past switch marker character */
if (keymatch(arg, "bmp", 1)) {
/* BMP output format (Windows flavor). */
requested_fmt = FMT_BMP;
} else if (keymatch(arg, "colors", 1) || keymatch(arg, "colours", 1) ||
keymatch(arg, "quantize", 1) || keymatch(arg, "quantise", 1)) {
/* Do color quantization. */
int val;
if (++argn >= argc) /* advance to next argument */
usage();
if (sscanf(argv[argn], "%d", &val) != 1)
usage();
cinfo->desired_number_of_colors = val;
cinfo->quantize_colors = TRUE;
} else if (keymatch(arg, "dct", 2)) {
/* Select IDCT algorithm. */
if (++argn >= argc) /* advance to next argument */
usage();
if (keymatch(argv[argn], "int", 1)) {
cinfo->dct_method = JDCT_ISLOW;
} else if (keymatch(argv[argn], "fast", 2)) {
cinfo->dct_method = JDCT_IFAST;
} else if (keymatch(argv[argn], "float", 2)) {
cinfo->dct_method = JDCT_FLOAT;
} else
usage();
} else if (keymatch(arg, "dither", 2)) {
/* Select dithering algorithm. */
if (++argn >= argc) /* advance to next argument */
usage();
if (keymatch(argv[argn], "fs", 2)) {
cinfo->dither_mode = JDITHER_FS;
} else if (keymatch(argv[argn], "none", 2)) {
cinfo->dither_mode = JDITHER_NONE;
} else if (keymatch(argv[argn], "ordered", 2)) {
cinfo->dither_mode = JDITHER_ORDERED;
} else
usage();
} else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) {
/* Enable debug printouts. */
/* On first -d, print version identification */
static boolean printed_version = FALSE;
if (!printed_version) {
fprintf(stderr, "%s version %s (build %s)\n",
PACKAGE_NAME, VERSION, BUILD);
fprintf(stderr, JCOPYRIGHT1);
fprintf(stderr, JCOPYRIGHT2 "\n");
fprintf(stderr, "Emulating The Independent JPEG Group's software, version %s\n\n",
JVERSION);
printed_version = TRUE;
}
cinfo->err->trace_level++;
} else if (keymatch(arg, "version", 4)) {
fprintf(stderr, "%s version %s (build %s)\n",
PACKAGE_NAME, VERSION, BUILD);
exit(EXIT_SUCCESS);
} else if (keymatch(arg, "fast", 1)) {
/* Select recommended processing options for quick-and-dirty output. */
cinfo->two_pass_quantize = FALSE;
cinfo->dither_mode = JDITHER_ORDERED;
if (!cinfo->quantize_colors) /* don't override an earlier -colors */
cinfo->desired_number_of_colors = 216;
cinfo->dct_method = JDCT_FASTEST;
cinfo->do_fancy_upsampling = FALSE;
} else if (keymatch(arg, "gif", 1)) {
/* GIF output format (LZW-compressed). */
requested_fmt = FMT_GIF;
} else if (keymatch(arg, "gif0", 4)) {
/* GIF output format (uncompressed). */
requested_fmt = FMT_GIF0;
} else if (keymatch(arg, "grayscale", 2) ||
keymatch(arg, "greyscale", 2)) {
/* Force monochrome output. */
cinfo->out_color_space = JCS_GRAYSCALE;
} else if (keymatch(arg, "rgb", 2)) {
/* Force RGB output. */
cinfo->out_color_space = JCS_RGB;
} else if (keymatch(arg, "rgb565", 2)) {
/* Force RGB565 output. */
cinfo->out_color_space = JCS_RGB565;
} else if (keymatch(arg, "icc", 1)) {
/* Set ICC filename. */
if (++argn >= argc) /* advance to next argument */
usage();
icc_filename = argv[argn];
#ifdef SAVE_MARKERS_SUPPORTED
jpeg_save_markers(cinfo, JPEG_APP0 + 2, 0xFFFF);
#endif
} else if (keymatch(arg, "map", 3)) {
/* Quantize to a color map taken from an input file. */
if (++argn >= argc) /* advance to next argument */
usage();
if (for_real) { /* too expensive to do twice! */
#ifdef QUANT_2PASS_SUPPORTED /* otherwise can't quantize to supplied map */
FILE *mapfile;
if ((mapfile = fopen(argv[argn], READ_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open %s\n", progname, argv[argn]);
exit(EXIT_FAILURE);
}
if (cinfo->data_precision == 12)
read_color_map_12(cinfo, mapfile);
else
read_color_map(cinfo, mapfile);
fclose(mapfile);
cinfo->quantize_colors = TRUE;
#else
ERREXIT(cinfo, JERR_NOT_COMPILED);
#endif
}
} else if (keymatch(arg, "maxmemory", 3)) {
/* Maximum memory in Kb (or Mb with 'm'). */
long lval;
char ch = 'x';
if (++argn >= argc) /* advance to next argument */
usage();
if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1)
usage();
if (ch == 'm' || ch == 'M')
lval *= 1000L;
cinfo->mem->max_memory_to_use = lval * 1000L;
} else if (keymatch(arg, "maxscans", 4)) {
if (++argn >= argc) /* advance to next argument */
usage();
if (sscanf(argv[argn], "%u", &max_scans) != 1)
usage();
} else if (keymatch(arg, "nosmooth", 3)) {
/* Suppress fancy upsampling */
cinfo->do_fancy_upsampling = FALSE;
} else if (keymatch(arg, "onepass", 3)) {
/* Use fast one-pass quantization. */
cinfo->two_pass_quantize = FALSE;
} else if (keymatch(arg, "os2", 3)) {
/* BMP output format (OS/2 flavor). */
requested_fmt = FMT_OS2;
} else if (keymatch(arg, "outfile", 4)) {
/* Set output file name. */
if (++argn >= argc) /* advance to next argument */
usage();
outfilename = argv[argn]; /* save it away for later use */
} else if (keymatch(arg, "memsrc", 2)) {
/* Use in-memory source manager */
memsrc = TRUE;
} else if (keymatch(arg, "pnm", 1) || keymatch(arg, "ppm", 1)) {
/* PPM/PGM output format. */
requested_fmt = FMT_PPM;
} else if (keymatch(arg, "report", 2)) {
report = TRUE;
} else if (keymatch(arg, "scale", 2)) {
/* Scale the output image by a fraction M/N. */
if (++argn >= argc) /* advance to next argument */
usage();
if (sscanf(argv[argn], "%u/%u",
&cinfo->scale_num, &cinfo->scale_denom) != 2)
usage();
} else if (keymatch(arg, "skip", 2)) {
if (++argn >= argc)
usage();
if (sscanf(argv[argn], "%u,%u", &skip_start, &skip_end) != 2 ||
skip_start > skip_end)
usage();
skip = TRUE;
} else if (keymatch(arg, "crop", 2)) {
char c;
if (++argn >= argc)
usage();
if (sscanf(argv[argn], "%u%c%u+%u+%u", &crop_width, &c, &crop_height,
&crop_x, &crop_y) != 5 ||
(c != 'X' && c != 'x') || crop_width < 1 || crop_height < 1)
usage();
crop = TRUE;
} else if (keymatch(arg, "strict", 2)) {
strict = TRUE;
} else if (keymatch(arg, "targa", 1)) {
/* Targa output format. */
requested_fmt = FMT_TARGA;
} else {
usage(); /* bogus switch */
}
}
return argn; /* return index of next arg (file name) */
}
/*
* Marker processor for COM and interesting APPn markers.
* This replaces the library's built-in processor, which just skips the marker.
* We want to print out the marker as text, to the extent possible.
* Note this code relies on a non-suspending data source.
*/
LOCAL(unsigned int)
jpeg_getc(j_decompress_ptr cinfo)
/* Read next byte */
{
struct jpeg_source_mgr *datasrc = cinfo->src;
if (datasrc->bytes_in_buffer == 0) {
if (!(*datasrc->fill_input_buffer) (cinfo))
ERREXIT(cinfo, JERR_CANT_SUSPEND);
}
datasrc->bytes_in_buffer--;
return *datasrc->next_input_byte++;
}
METHODDEF(boolean)
print_text_marker(j_decompress_ptr cinfo)
{
boolean traceit = (cinfo->err->trace_level >= 1);
long length;
unsigned int ch;
unsigned int lastch = 0;
length = jpeg_getc(cinfo) << 8;
length += jpeg_getc(cinfo);
length -= 2; /* discount the length word itself */
if (traceit) {
if (cinfo->unread_marker == JPEG_COM)
fprintf(stderr, "Comment, length %ld:\n", (long)length);
else /* assume it is an APPn otherwise */
fprintf(stderr, "APP%d, length %ld:\n",
cinfo->unread_marker - JPEG_APP0, (long)length);
}
while (--length >= 0) {
ch = jpeg_getc(cinfo);
if (traceit) {
/* Emit the character in a readable form.
* Nonprintables are converted to \nnn form,
* while \ is converted to \\.
* Newlines in CR, CR/LF, or LF form will be printed as one newline.
*/
if (ch == '\r') {
fprintf(stderr, "\n");
} else if (ch == '\n') {
if (lastch != '\r')
fprintf(stderr, "\n");
} else if (ch == '\\') {
fprintf(stderr, "\\\\");
} else if (isprint(ch)) {
putc(ch, stderr);
} else {
fprintf(stderr, "\\%03o", ch);
}
lastch = ch;
}
}
if (traceit)
fprintf(stderr, "\n");
return TRUE;
}
METHODDEF(void)
my_emit_message(j_common_ptr cinfo, int msg_level)
{
if (msg_level < 0) {
/* Treat warning as fatal */
cinfo->err->error_exit(cinfo);
} else {
if (cinfo->err->trace_level >= msg_level)
cinfo->err->output_message(cinfo);
}
}
/*
* The main program.
*/
int
main(int argc, char **argv)
{
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
struct cdjpeg_progress_mgr progress;
int file_index;
djpeg_dest_ptr dest_mgr = NULL;
FILE *input_file;
FILE *output_file;
unsigned char *inbuffer = NULL;
unsigned long insize = 0;
JDIMENSION num_scanlines;
progname = argv[0];
if (progname == NULL || progname[0] == 0)
progname = "djpeg"; /* in case C library doesn't provide it */
/* Initialize the JPEG decompression object with default error handling. */
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
/* Add some application-specific error messages (from cderror.h) */
jerr.addon_message_table = cdjpeg_message_table;
jerr.first_addon_message = JMSG_FIRSTADDONCODE;
jerr.last_addon_message = JMSG_LASTADDONCODE;
/* Insert custom marker processor for COM and APP12.
* APP12 is used by some digital camera makers for textual info,
* so we provide the ability to display it as text.
* If you like, additional APPn marker types can be selected for display,
* but don't try to override APP0 or APP14 this way (see libjpeg.txt).
*/
jpeg_set_marker_processor(&cinfo, JPEG_COM, print_text_marker);
jpeg_set_marker_processor(&cinfo, JPEG_APP0 + 12, print_text_marker);
/* Scan command line to find file names. */
/* It is convenient to use just one switch-parsing routine, but the switch
* values read here are ignored; we will rescan the switches after opening
* the input file.
* (Exception: tracing level set here controls verbosity for COM markers
* found during jpeg_read_header...)
*/
file_index = parse_switches(&cinfo, argc, argv, 0, FALSE);
if (strict)
jerr.emit_message = my_emit_message;
#ifdef TWO_FILE_COMMANDLINE
/* Must have either -outfile switch or explicit output file name */
if (outfilename == NULL) {
if (file_index != argc - 2) {
fprintf(stderr, "%s: must name one input and one output file\n",
progname);
usage();
}
outfilename = argv[file_index + 1];
} else {
if (file_index != argc - 1) {
fprintf(stderr, "%s: must name one input and one output file\n",
progname);
usage();
}
}
#else
/* Unix style: expect zero or one file name */
if (file_index < argc - 1) {
fprintf(stderr, "%s: only one input file\n", progname);
usage();
}
#endif /* TWO_FILE_COMMANDLINE */
/* Open the input file. */
if (file_index < argc) {
if ((input_file = fopen(argv[file_index], READ_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open %s\n", progname, argv[file_index]);
exit(EXIT_FAILURE);
}
} else {
/* default input file is stdin */
input_file = read_stdin();
}
/* Open the output file. */
if (outfilename != NULL) {
if ((output_file = fopen(outfilename, WRITE_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open %s\n", progname, outfilename);
exit(EXIT_FAILURE);
}
} else {
/* default output file is stdout */
output_file = write_stdout();
}
if (report || max_scans != 0) {
start_progress_monitor((j_common_ptr)&cinfo, &progress);
progress.report = report;
progress.max_scans = max_scans;
}
/* Specify data source for decompression */
if (memsrc) {
size_t nbytes;
do {
inbuffer = (unsigned char *)realloc(inbuffer, insize + INPUT_BUF_SIZE);
if (inbuffer == NULL) {
fprintf(stderr, "%s: memory allocation failure\n", progname);
exit(EXIT_FAILURE);
}
nbytes = fread(&inbuffer[insize], 1, INPUT_BUF_SIZE, input_file);
if (nbytes < INPUT_BUF_SIZE && ferror(input_file)) {
if (file_index < argc)
fprintf(stderr, "%s: can't read from %s\n", progname,
argv[file_index]);
else
fprintf(stderr, "%s: can't read from stdin\n", progname);
}
insize += (unsigned long)nbytes;
} while (nbytes == INPUT_BUF_SIZE);
fprintf(stderr, "Compressed size: %lu bytes\n", insize);
jpeg_mem_src(&cinfo, inbuffer, insize);
} else
jpeg_stdio_src(&cinfo, input_file);
/* Read file header, set default decompression parameters */
(void)jpeg_read_header(&cinfo, TRUE);
/* Adjust default decompression parameters by re-parsing the options */
file_index = parse_switches(&cinfo, argc, argv, 0, TRUE);
/* Initialize the output module now to let it override any crucial
* option settings (for instance, GIF wants to force color quantization).
*/
switch (requested_fmt) {
#ifdef BMP_SUPPORTED
case FMT_BMP:
dest_mgr = jinit_write_bmp(&cinfo, FALSE, TRUE);
break;
case FMT_OS2:
dest_mgr = jinit_write_bmp(&cinfo, TRUE, TRUE);
break;
#endif
#ifdef GIF_SUPPORTED
case FMT_GIF:
if (cinfo.data_precision == 16)
ERREXIT1(&cinfo, JERR_BAD_PRECISION, cinfo.data_precision);
else if (cinfo.data_precision == 12)
dest_mgr = j12init_write_gif(&cinfo, TRUE);
else
dest_mgr = jinit_write_gif(&cinfo, TRUE);
break;
case FMT_GIF0:
dest_mgr = jinit_write_gif(&cinfo, FALSE);
break;
#endif
#ifdef PPM_SUPPORTED
case FMT_PPM:
if (cinfo.data_precision == 16)
#ifdef D_LOSSLESS_SUPPORTED
dest_mgr = j16init_write_ppm(&cinfo);
#else
ERREXIT1(&cinfo, JERR_BAD_PRECISION, cinfo.data_precision);
#endif
else if (cinfo.data_precision == 12)
dest_mgr = j12init_write_ppm(&cinfo);
else
dest_mgr = jinit_write_ppm(&cinfo);
break;
#endif
#ifdef TARGA_SUPPORTED
case FMT_TARGA:
dest_mgr = jinit_write_targa(&cinfo);
break;
#endif
default:
ERREXIT(&cinfo, JERR_UNSUPPORTED_FORMAT);
break;
}
dest_mgr->output_file = output_file;
/* Start decompressor */
(void)jpeg_start_decompress(&cinfo);
/* Skip rows */
if (skip) {
JDIMENSION tmp;
/* Check for valid skip_end. We cannot check this value until after
* jpeg_start_decompress() is called. Note that we have already verified
* that skip_start <= skip_end.
*/
if (skip_end > cinfo.output_height - 1) {
fprintf(stderr, "%s: skip region exceeds image height %u\n", progname,
cinfo.output_height);
exit(EXIT_FAILURE);
}
/* Write output file header. This is a hack to ensure that the destination
* manager creates an output image of the proper size.
*/
tmp = cinfo.output_height;
cinfo.output_height -= (skip_end - skip_start + 1);
(*dest_mgr->start_output) (&cinfo, dest_mgr);
cinfo.output_height = tmp;
if (cinfo.data_precision == 16)
ERREXIT(&cinfo, JERR_NOTIMPL);
else if (cinfo.data_precision == 12) {
/* Process data */
while (cinfo.output_scanline < skip_start) {
num_scanlines = jpeg12_read_scanlines(&cinfo, dest_mgr->buffer12,
dest_mgr->buffer_height);
(*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
}
if ((tmp = jpeg12_skip_scanlines(&cinfo, skip_end - skip_start + 1)) !=
skip_end - skip_start + 1) {
fprintf(stderr, "%s: jpeg12_skip_scanlines() returned %u rather than %u\n",
progname, tmp, skip_end - skip_start + 1);
exit(EXIT_FAILURE);
}
while (cinfo.output_scanline < cinfo.output_height) {
num_scanlines = jpeg12_read_scanlines(&cinfo, dest_mgr->buffer12,
dest_mgr->buffer_height);
(*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
}
} else {
/* Process data */
while (cinfo.output_scanline < skip_start) {
num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer,
dest_mgr->buffer_height);
(*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
}
if ((tmp = jpeg_skip_scanlines(&cinfo, skip_end - skip_start + 1)) !=
skip_end - skip_start + 1) {
fprintf(stderr, "%s: jpeg_skip_scanlines() returned %u rather than %u\n",
progname, tmp, skip_end - skip_start + 1);
exit(EXIT_FAILURE);
}
while (cinfo.output_scanline < cinfo.output_height) {
num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer,
dest_mgr->buffer_height);
(*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
}
}
/* Decompress a subregion */
} else if (crop) {
JDIMENSION tmp;
/* Check for valid crop dimensions. We cannot check these values until
* after jpeg_start_decompress() is called.
*/
if (crop_x + crop_width > cinfo.output_width ||
crop_y + crop_height > cinfo.output_height) {
fprintf(stderr, "%s: crop dimensions exceed image dimensions %u x %u\n",
progname, cinfo.output_width, cinfo.output_height);
exit(EXIT_FAILURE);
}
if (cinfo.data_precision == 16)
ERREXIT(&cinfo, JERR_NOTIMPL);
else if (cinfo.data_precision == 12)
jpeg12_crop_scanline(&cinfo, &crop_x, &crop_width);
else
jpeg_crop_scanline(&cinfo, &crop_x, &crop_width);
if (dest_mgr->calc_buffer_dimensions)
(*dest_mgr->calc_buffer_dimensions) (&cinfo, dest_mgr);
else
ERREXIT(&cinfo, JERR_UNSUPPORTED_FORMAT);
/* Write output file header. This is a hack to ensure that the destination
* manager creates an output image of the proper size.
*/
tmp = cinfo.output_height;
cinfo.output_height = crop_height;
(*dest_mgr->start_output) (&cinfo, dest_mgr);
cinfo.output_height = tmp;
if (cinfo.data_precision == 16)
ERREXIT(&cinfo, JERR_NOTIMPL);
else if (cinfo.data_precision == 12) {
/* Process data */
if ((tmp = jpeg12_skip_scanlines(&cinfo, crop_y)) != crop_y) {
fprintf(stderr, "%s: jpeg12_skip_scanlines() returned %u rather than %u\n",
progname, tmp, crop_y);
exit(EXIT_FAILURE);
}
while (cinfo.output_scanline < crop_y + crop_height) {
num_scanlines = jpeg12_read_scanlines(&cinfo, dest_mgr->buffer12,
dest_mgr->buffer_height);
(*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
}
if ((tmp =
jpeg12_skip_scanlines(&cinfo, cinfo.output_height - crop_y -
crop_height)) !=
cinfo.output_height - crop_y - crop_height) {
fprintf(stderr, "%s: jpeg12_skip_scanlines() returned %u rather than %u\n",
progname, tmp, cinfo.output_height - crop_y - crop_height);
exit(EXIT_FAILURE);
}
} else {
/* Process data */
if ((tmp = jpeg_skip_scanlines(&cinfo, crop_y)) != crop_y) {
fprintf(stderr, "%s: jpeg_skip_scanlines() returned %u rather than %u\n",
progname, tmp, crop_y);
exit(EXIT_FAILURE);
}
while (cinfo.output_scanline < crop_y + crop_height) {
num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer,
dest_mgr->buffer_height);
(*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
}
if ((tmp =
jpeg_skip_scanlines(&cinfo,
cinfo.output_height - crop_y - crop_height)) !=
cinfo.output_height - crop_y - crop_height) {
fprintf(stderr, "%s: jpeg_skip_scanlines() returned %u rather than %u\n",
progname, tmp, cinfo.output_height - crop_y - crop_height);
exit(EXIT_FAILURE);
}
}
/* Normal full-image decompress */
} else {
/* Write output file header */
(*dest_mgr->start_output) (&cinfo, dest_mgr);
if (cinfo.data_precision == 16) {
#ifdef D_LOSSLESS_SUPPORTED
/* Process data */
while (cinfo.output_scanline < cinfo.output_height) {
num_scanlines = jpeg16_read_scanlines(&cinfo, dest_mgr->buffer16,
dest_mgr->buffer_height);
(*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
}
#else
ERREXIT1(&cinfo, JERR_BAD_PRECISION, cinfo.data_precision);
#endif
} else if (cinfo.data_precision == 12) {
/* Process data */
while (cinfo.output_scanline < cinfo.output_height) {
num_scanlines = jpeg12_read_scanlines(&cinfo, dest_mgr->buffer12,
dest_mgr->buffer_height);
(*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
}
} else {
/* Process data */
while (cinfo.output_scanline < cinfo.output_height) {
num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer,
dest_mgr->buffer_height);
(*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
}
}
}
/* Hack: count final pass as done in case finish_output does an extra pass.
* The library won't have updated completed_passes.
*/
if (report || max_scans != 0)
progress.pub.completed_passes = progress.pub.total_passes;
if (icc_filename != NULL) {
FILE *icc_file;
JOCTET *icc_profile;
unsigned int icc_len;
if ((icc_file = fopen(icc_filename, WRITE_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open %s\n", progname, icc_filename);
exit(EXIT_FAILURE);
}
if (jpeg_read_icc_profile(&cinfo, &icc_profile, &icc_len)) {
if (fwrite(icc_profile, icc_len, 1, icc_file) < 1) {
fprintf(stderr, "%s: can't read ICC profile from %s\n", progname,
icc_filename);
free(icc_profile);
fclose(icc_file);
exit(EXIT_FAILURE);
}
free(icc_profile);
fclose(icc_file);
} else if (cinfo.err->msg_code != JWRN_BOGUS_ICC)
fprintf(stderr, "%s: no ICC profile data in JPEG file\n", progname);
}
/* Finish decompression and release memory.
* I must do it in this order because output module has allocated memory
* of lifespan JPOOL_IMAGE; it needs to finish before releasing memory.
*/
(*dest_mgr->finish_output) (&cinfo, dest_mgr);
(void)jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
/* Close files, if we opened them */
if (input_file != stdin)
fclose(input_file);
if (output_file != stdout)
fclose(output_file);
if (report || max_scans != 0)
end_progress_monitor((j_common_ptr)&cinfo);
if (memsrc)
free(inbuffer);
/* All done. */
exit(jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS);
return 0; /* suppress no-return-value warnings */
}
-643
View File
@@ -1,643 +0,0 @@
/*
* example.c
*
* This file was part of the Independent JPEG Group's software.
* Copyright (C) 1992-1996, Thomas G. Lane.
* libjpeg-turbo Modifications:
* Copyright (C) 2017, 2019, 2022-2023, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
* This file illustrates how to use the IJG code as a subroutine library
* to read or write JPEG image files with 8-bit or 12-bit data precision. You
* should look at this code in conjunction with the documentation file
* libjpeg.txt.
*
* We present these routines in the same coding style used in the JPEG code
* (ANSI function definitions, etc); but you are of course free to code your
* routines in a different style if you prefer.
*/
/* First-time users of libjpeg-turbo might be better served by looking at
* tjexample.c, which uses the more straightforward TurboJPEG API. Note that
* this example, like cjpeg and djpeg, interleaves disk I/O with JPEG
* compression/decompression, so it is not suitable for benchmarking purposes.
*/
#ifdef _MSC_VER
#define _CRT_SECURE_NO_DEPRECATE
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#define strcasecmp stricmp
#define strncasecmp strnicmp
#endif
/*
* Include file for users of JPEG library.
* You will need to have included system headers that define at least
* the typedefs FILE and size_t before you can include jpeglib.h.
* (stdio.h is sufficient on ANSI-conforming systems.)
* You may also wish to include "jerror.h".
*/
#include "jpeglib.h"
#include "jerror.h"
/*
* <setjmp.h> is used for the optional error recovery mechanism shown in
* the second part of the example.
*/
#include <setjmp.h>
/******************** JPEG COMPRESSION SAMPLE INTERFACE *******************/
/* This half of the example shows how to feed data into the JPEG compressor.
* We present a minimal version that does not worry about refinements such
* as error recovery (the JPEG code will just exit() if it gets an error).
*/
/*
* IMAGE DATA FORMATS:
*
* The standard input image format is a rectangular array of pixels, with
* each pixel having the same number of "component" values (color channels).
* Each pixel row is an array of JSAMPLEs (which typically are unsigned chars)
* or J12SAMPLEs (which typically are shorts). If you are working with color
* data, then the color values for each pixel must be adjacent in the row; for
* example, R,G,B,R,G,B,R,G,B,... for 24-bit RGB color.
*
* For this example, we'll assume that this data structure matches the way
* our application has stored the image in memory, so we can just pass a
* pointer to our image buffer. In particular, let's say that the image is
* RGB color and is described by:
*/
#define WIDTH 640 /* Number of columns in image */
#define HEIGHT 480 /* Number of rows in image */
/*
* Sample routine for JPEG compression. We assume that the target file name,
* a compression quality factor, and a data precision are passed in.
*/
METHODDEF(void)
write_JPEG_file(char *filename, int quality, int data_precision)
{
/* This struct contains the JPEG compression parameters and pointers to
* working space (which is allocated as needed by the JPEG library).
* It is possible to have several such structures, representing multiple
* compression/decompression processes, in existence at once. We refer
* to any one struct (and its associated working data) as a "JPEG object".
*/
struct jpeg_compress_struct cinfo;
/* This struct represents a JPEG error handler. It is declared separately
* because applications often want to supply a specialized error handler
* (see the second half of this file for an example). But here we just
* take the easy way out and use the standard error handler, which will
* print a message on stderr and call exit() if compression fails.
* Note that this struct must live as long as the main JPEG parameter
* struct, to avoid dangling-pointer problems.
*/
struct jpeg_error_mgr jerr;
/* More stuff */
FILE *outfile; /* target file */
JSAMPARRAY image_buffer = NULL;
/* Points to large array of R,G,B-order data */
JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
J12SAMPARRAY image_buffer12 = NULL;
/* Points to large array of R,G,B-order 12-bit
data */
J12SAMPROW row_pointer12[1]; /* pointer to J12SAMPLE row[s] */
int row_stride; /* physical row width in image buffer */
int row, col;
/* Step 1: allocate and initialize JPEG compression object */
/* We have to set up the error handler first, in case the initialization
* step fails. (Unlikely, but it could happen if you are out of memory.)
* This routine fills in the contents of struct jerr, and returns jerr's
* address which we place into the link field in cinfo.
*/
cinfo.err = jpeg_std_error(&jerr);
/* Now we can initialize the JPEG compression object. */
jpeg_create_compress(&cinfo);
/* Step 2: specify data destination (eg, a file) */
/* Note: steps 2 and 3 can be done in either order. */
/* Here we use the library-supplied code to send compressed data to a
* stdio stream. You can also write your own code to do something else.
* VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
* requires it in order to write binary files.
*/
if ((outfile = fopen(filename, "wb")) == NULL)
ERREXIT(&cinfo, JERR_FILE_WRITE);
jpeg_stdio_dest(&cinfo, outfile);
/* Step 3: set parameters for compression */
/* First we supply a description of the input image.
* Four fields of the cinfo struct must be filled in:
*/
cinfo.image_width = WIDTH; /* image width and height, in pixels */
cinfo.image_height = HEIGHT;
cinfo.input_components = 3; /* # of color components per pixel */
cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
cinfo.data_precision = data_precision; /* data precision of input image */
/* Now use the library's routine to set default compression parameters.
* (You must set at least cinfo.in_color_space before calling this,
* since the defaults depend on the source color space.)
*/
jpeg_set_defaults(&cinfo);
/* Now you can set any non-default parameters you wish to.
* Here we just illustrate the use of quality (quantization table) scaling:
*/
jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
/* Use 4:4:4 subsampling (default is 4:2:0) */
cinfo.comp_info[0].h_samp_factor = cinfo.comp_info[0].v_samp_factor = 1;
/* Step 4: Start compressor */
/* TRUE ensures that we will write a complete interchange-JPEG file.
* Pass TRUE unless you are very sure of what you're doing.
*/
jpeg_start_compress(&cinfo, TRUE);
/* Step 5: allocate and initialize image buffer */
row_stride = WIDTH * 3; /* J[12]SAMPLEs per row in image_buffer */
/* Make a sample array that will go away when done with image. Note that,
* for the purposes of this example, we could also create a one-row-high
* sample array and initialize it for each successive scanline written in the
* scanline loop below.
*/
if (cinfo.data_precision == 12) {
image_buffer12 = (J12SAMPARRAY)(*cinfo.mem->alloc_sarray)
((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, HEIGHT);
/* Initialize image buffer with a repeating pattern */
for (row = 0; row < HEIGHT; row++) {
for (col = 0; col < WIDTH; col++) {
image_buffer12[row][col * 3] =
(col * (MAXJ12SAMPLE + 1) / WIDTH) % (MAXJ12SAMPLE + 1);
image_buffer12[row][col * 3 + 1] =
(row * (MAXJ12SAMPLE + 1) / HEIGHT) % (MAXJ12SAMPLE + 1);
image_buffer12[row][col * 3 + 2] =
(row * (MAXJ12SAMPLE + 1) / HEIGHT +
col * (MAXJ12SAMPLE + 1) / WIDTH) % (MAXJ12SAMPLE + 1);
}
}
} else {
image_buffer = (*cinfo.mem->alloc_sarray)
((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, HEIGHT);
for (row = 0; row < HEIGHT; row++) {
for (col = 0; col < WIDTH; col++) {
image_buffer[row][col * 3] =
(col * (MAXJSAMPLE + 1) / WIDTH) % (MAXJSAMPLE + 1);
image_buffer[row][col * 3 + 1] =
(row * (MAXJSAMPLE + 1) / HEIGHT) % (MAXJSAMPLE + 1);
image_buffer[row][col * 3 + 2] =
(row * (MAXJSAMPLE + 1) / HEIGHT + col * (MAXJSAMPLE + 1) / WIDTH) %
(MAXJSAMPLE + 1);
}
}
}
/* Step 6: while (scan lines remain to be written) */
/* jpeg_write_scanlines(...); */
/* Here we use the library's state variable cinfo.next_scanline as the
* loop counter, so that we don't have to keep track ourselves.
* To keep things simple, we pass one scanline per call; you can pass
* more if you wish, though.
*/
if (cinfo.data_precision == 12) {
while (cinfo.next_scanline < cinfo.image_height) {
/* jpeg12_write_scanlines expects an array of pointers to scanlines.
* Here the array is only one element long, but you could pass
* more than one scanline at a time if that's more convenient.
*/
row_pointer12[0] = image_buffer12[cinfo.next_scanline];
(void)jpeg12_write_scanlines(&cinfo, row_pointer12, 1);
}
} else {
while (cinfo.next_scanline < cinfo.image_height) {
/* jpeg_write_scanlines expects an array of pointers to scanlines.
* Here the array is only one element long, but you could pass
* more than one scanline at a time if that's more convenient.
*/
row_pointer[0] = image_buffer[cinfo.next_scanline];
(void)jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
}
/* Step 7: Finish compression */
jpeg_finish_compress(&cinfo);
/* After finish_compress, we can close the output file. */
fclose(outfile);
/* Step 8: release JPEG compression object */
/* This is an important step since it will release a good deal of memory. */
jpeg_destroy_compress(&cinfo);
/* And we're done! */
}
/*
* SOME FINE POINTS:
*
* In the above loop, we ignored the return value of jpeg_write_scanlines,
* which is the number of scanlines actually written. We could get away
* with this because we were only relying on the value of cinfo.next_scanline,
* which will be incremented correctly. If you maintain additional loop
* variables then you should be careful to increment them properly.
* Actually, for output to a stdio stream you needn't worry, because
* then jpeg_write_scanlines will write all the lines passed (or else exit
* with a fatal error). Partial writes can only occur if you use a data
* destination module that can demand suspension of the compressor.
* (If you don't know what that's for, you don't need it.)
*
* Scanlines MUST be supplied in top-to-bottom order if you want your JPEG
* files to be compatible with everyone else's. If you cannot readily read
* your data in that order, you'll need an intermediate array to hold the
* image. See rdtarga.c or rdbmp.c for examples of handling bottom-to-top
* source data using the JPEG code's internal virtual-array mechanisms.
*/
/******************** JPEG DECOMPRESSION SAMPLE INTERFACE *******************/
/* This half of the example shows how to read data from the JPEG decompressor.
* It's a bit more refined than the above, in that we show:
* (a) how to modify the JPEG library's standard error-reporting behavior;
* (b) how to allocate workspace using the library's memory manager.
*
* Just to make this example a little different from the first one, we'll
* assume that we do not intend to put the whole image into an in-memory
* buffer, but to send it line-by-line someplace else. We need a one-
* scanline-high JSAMPLE or J12SAMPLE array as a work buffer, and we will let
* the JPEG memory manager allocate it for us. This approach is actually quite
* useful because we don't need to remember to deallocate the buffer
* separately: it will go away automatically when the JPEG object is cleaned
* up.
*/
/*
* ERROR HANDLING:
*
* The JPEG library's standard error handler (jerror.c) is divided into
* several "methods" which you can override individually. This lets you
* adjust the behavior without duplicating a lot of code, which you might
* have to update with each future release.
*
* Our example here shows how to override the "error_exit" method so that
* control is returned to the library's caller when a fatal error occurs,
* rather than calling exit() as the standard error_exit method does.
*
* We use C's setjmp/longjmp facility to return control. This means that the
* routine which calls the JPEG library must first execute a setjmp() call to
* establish the return point. We want the replacement error_exit to do a
* longjmp(). But we need to make the setjmp buffer accessible to the
* error_exit routine. To do this, we make a private extension of the
* standard JPEG error handler object. (If we were using C++, we'd say we
* were making a subclass of the regular error handler.)
*
* Here's the extended error handler struct:
*/
struct my_error_mgr {
struct jpeg_error_mgr pub; /* "public" fields */
jmp_buf setjmp_buffer; /* for return to caller */
};
typedef struct my_error_mgr *my_error_ptr;
/*
* Here's the routine that will replace the standard error_exit method:
*/
METHODDEF(void)
my_error_exit(j_common_ptr cinfo)
{
/* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
my_error_ptr myerr = (my_error_ptr)cinfo->err;
/* Always display the message. */
/* We could postpone this until after returning, if we chose. */
(*cinfo->err->output_message) (cinfo);
/* Return control to the setjmp point */
longjmp(myerr->setjmp_buffer, 1);
}
METHODDEF(int) do_read_JPEG_file(struct jpeg_decompress_struct *cinfo,
char *infilename, char *outfilename);
/*
* Sample routine for JPEG decompression. We assume that the source file name
* is passed in. We want to return 1 on success, 0 on error.
*/
METHODDEF(int)
read_JPEG_file(char *infilename, char *outfilename)
{
/* This struct contains the JPEG decompression parameters and pointers to
* working space (which is allocated as needed by the JPEG library).
*/
struct jpeg_decompress_struct cinfo;
return do_read_JPEG_file(&cinfo, infilename, outfilename);
}
/*
* We call the libjpeg API from within a separate function, because modifying
* the local non-volatile jpeg_decompress_struct instance below the setjmp()
* return point and then accessing the instance after setjmp() returns would
* result in undefined behavior that may potentially overwrite all or part of
* the structure.
*/
METHODDEF(int)
do_read_JPEG_file(struct jpeg_decompress_struct *cinfo, char *infilename,
char *outfilename)
{
/* We use our private extension JPEG error handler.
* Note that this struct must live as long as the main JPEG parameter
* struct, to avoid dangling-pointer problems.
*/
struct my_error_mgr jerr;
/* More stuff */
FILE *infile; /* source file */
FILE *outfile; /* output file */
JSAMPARRAY buffer = NULL; /* Output row buffer */
J12SAMPARRAY buffer12 = NULL; /* 12-bit output row buffer */
int col;
int row_stride; /* physical row width in output buffer */
int little_endian = 1;
/* In this example we want to open the input and output files before doing
* anything else, so that the setjmp() error recovery below can assume the
* files are open.
*
* VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
* requires it in order to read/write binary files.
*/
if ((infile = fopen(infilename, "rb")) == NULL) {
fprintf(stderr, "can't open %s\n", infilename);
return 0;
}
if ((outfile = fopen(outfilename, "wb")) == NULL) {
fprintf(stderr, "can't open %s\n", outfilename);
fclose(infile);
return 0;
}
/* Step 1: allocate and initialize JPEG decompression object */
/* We set up the normal JPEG error routines, then override error_exit. */
cinfo->err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit;
/* Establish the setjmp return context for my_error_exit to use. */
if (setjmp(jerr.setjmp_buffer)) {
/* If we get here, the JPEG code has signaled an error.
* We need to clean up the JPEG object, close the input file, and return.
*/
jpeg_destroy_decompress(cinfo);
fclose(infile);
fclose(outfile);
return 0;
}
/* Now we can initialize the JPEG decompression object. */
jpeg_create_decompress(cinfo);
/* Step 2: specify data source (eg, a file) */
jpeg_stdio_src(cinfo, infile);
/* Step 3: read file parameters with jpeg_read_header() */
(void)jpeg_read_header(cinfo, TRUE);
/* We can ignore the return value from jpeg_read_header since
* (a) suspension is not possible with the stdio data source, and
* (b) we passed TRUE to reject a tables-only JPEG file as an error.
* See libjpeg.txt for more info.
*/
/* emit header for raw PPM format */
fprintf(outfile, "P6\n%d %d\n%d\n", WIDTH, HEIGHT,
cinfo->data_precision == 12 ? MAXJ12SAMPLE : MAXJSAMPLE);
/* Step 4: set parameters for decompression */
/* In this example, we don't need to change any of the defaults set by
* jpeg_read_header(), so we do nothing here.
*/
/* Step 5: Start decompressor */
(void)jpeg_start_decompress(cinfo);
/* We can ignore the return value since suspension is not possible
* with the stdio data source.
*/
/* We may need to do some setup of our own at this point before reading
* the data. After jpeg_start_decompress() we have the correct scaled
* output image dimensions available, as well as the output colormap
* if we asked for color quantization.
* In this example, we need to make an output work buffer of the right size.
*/
/* Samples per row in output buffer */
row_stride = cinfo->output_width * cinfo->output_components;
/* Make a one-row-high sample array that will go away when done with image */
if (cinfo->data_precision == 12)
buffer12 = (J12SAMPARRAY)(*cinfo->mem->alloc_sarray)
((j_common_ptr)cinfo, JPOOL_IMAGE, row_stride, 1);
else
buffer = (*cinfo->mem->alloc_sarray)
((j_common_ptr)cinfo, JPOOL_IMAGE, row_stride, 1);
/* Step 6: while (scan lines remain to be read) */
/* jpeg_read_scanlines(...); */
/* Here we use the library's state variable cinfo->output_scanline as the
* loop counter, so that we don't have to keep track ourselves.
*/
if (cinfo->data_precision == 12) {
while (cinfo->output_scanline < cinfo->output_height) {
/* jpeg12_read_scanlines expects an array of pointers to scanlines.
* Here the array is only one element long, but you could ask for
* more than one scanline at a time if that's more convenient.
*/
(void)jpeg12_read_scanlines(cinfo, buffer12, 1);
if (*(char *)&little_endian == 1) {
/* Swap MSB and LSB in each sample */
for (col = 0; col < row_stride; col++)
buffer12[0][col] = ((buffer12[0][col] & 0xFF) << 8) |
((buffer12[0][col] >> 8) & 0xFF);
}
fwrite(buffer12[0], 1, row_stride * sizeof(J12SAMPLE), outfile);
}
} else {
while (cinfo->output_scanline < cinfo->output_height) {
/* jpeg_read_scanlines expects an array of pointers to scanlines.
* Here the array is only one element long, but you could ask for
* more than one scanline at a time if that's more convenient.
*/
(void)jpeg_read_scanlines(cinfo, buffer, 1);
fwrite(buffer[0], 1, row_stride, outfile);
}
}
/* Step 7: Finish decompression */
(void)jpeg_finish_decompress(cinfo);
/* We can ignore the return value since suspension is not possible
* with the stdio data source.
*/
/* Step 8: Release JPEG decompression object */
/* This is an important step since it will release a good deal of memory. */
jpeg_destroy_decompress(cinfo);
/* After finish_decompress, we can close the input and output files.
* Here we postpone it until after no more JPEG errors are possible,
* so as to simplify the setjmp error logic above. (Actually, I don't
* think that jpeg_destroy can do an error exit, but why assume anything...)
*/
fclose(infile);
fclose(outfile);
/* At this point you may want to check to see whether any corrupt-data
* warnings occurred (test whether jerr.pub.num_warnings is nonzero).
*/
/* And we're done! */
return 1;
}
/*
* SOME FINE POINTS:
*
* In the above code, we ignored the return value of jpeg_read_scanlines,
* which is the number of scanlines actually read. We could get away with
* this because we asked for only one line at a time and we weren't using
* a suspending data source. See libjpeg.txt for more info.
*
* We cheated a bit by calling alloc_sarray() after jpeg_start_decompress();
* we should have done it beforehand to ensure that the space would be
* counted against the JPEG max_memory setting. In some systems the above
* code would risk an out-of-memory error. However, in general we don't
* know the output image dimensions before jpeg_start_decompress(), unless we
* call jpeg_calc_output_dimensions(). See libjpeg.txt for more about this.
*
* Scanlines are returned in the same order as they appear in the JPEG file,
* which is standardly top-to-bottom. If you must emit data bottom-to-top,
* you can use one of the virtual arrays provided by the JPEG memory manager
* to invert the data. See wrbmp.c for an example.
*/
LOCAL(void)
usage(const char *progname)
{
fprintf(stderr, "usage: %s compress [switches] outputfile[.jpg]\n",
progname);
fprintf(stderr, " %s decompress inputfile[.jpg] outputfile[.ppm]\n",
progname);
fprintf(stderr, "Switches (names may be abbreviated):\n");
fprintf(stderr, " -precision N Create JPEG file with N-bit data precision\n");
fprintf(stderr, " (N is 8 or 12; default is 8)\n");
fprintf(stderr, " -quality N Compression quality (0..100; 5-95 is most useful range,\n");
fprintf(stderr, " default is 75)\n");
exit(EXIT_FAILURE);
}
typedef enum {
COMPRESS,
DECOMPRESS
} EXAMPLE_MODE;
int
main(int argc, char **argv)
{
int argn, quality = 75;
int data_precision = 8;
EXAMPLE_MODE mode = -1;
char *arg, *filename = NULL;
if (argc < 3)
usage(argv[0]);
if (!strcasecmp(argv[1], "compress"))
mode = COMPRESS;
else if (!strcasecmp(argv[1], "decompress"))
mode = DECOMPRESS;
else
usage(argv[0]);
for (argn = 2; argn < argc; argn++) {
arg = argv[argn];
if (*arg != '-') {
filename = arg;
/* Not a switch, must be a file name argument */
break; /* done parsing switches */
}
arg++; /* advance past switch marker character */
if (!strncasecmp(arg, "p", 1)) {
/* Set data precision. */
if (++argn >= argc) /* advance to next argument */
usage(argv[0]);
if (sscanf(argv[argn], "%d", &data_precision) < 1 ||
(data_precision != 8 && data_precision != 12))
usage(argv[0]);
} else if (!strncasecmp(arg, "q", 1)) {
/* Quality rating (quantization table scaling factor). */
if (++argn >= argc) /* advance to next argument */
usage(argv[0]);
if (sscanf(argv[argn], "%d", &quality) < 1 || quality < 0 ||
quality > 100)
usage(argv[0]);
if (quality < 1)
quality = 1;
}
}
if (!filename)
usage(argv[0]);
if (mode == COMPRESS)
write_JPEG_file(filename, quality, data_precision);
else if (mode == DECOMPRESS) {
if (argc - argn < 2)
usage(argv[0]);
read_JPEG_file(argv[argn], argv[argn + 1]);
}
return 0;
}
+5 -28
View File
@@ -4,8 +4,8 @@
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1994-1998, Thomas G. Lane.
* Modified 2003-2010 by Guido Vollbeding.
* libjpeg-turbo Modifications:
* Copyright (C) 2022, D. R. Commander.
* It was modified by The libjpeg-turbo Project to include only code relevant
* to libjpeg-turbo.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -23,7 +23,6 @@
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jcmaster.h"
/*
@@ -53,7 +52,7 @@ jpeg_CreateCompress(j_compress_ptr cinfo, int version, size_t structsize)
{
struct jpeg_error_mgr *err = cinfo->err;
void *client_data = cinfo->client_data; /* ignore Purify complaint here */
memset(cinfo, 0, sizeof(struct jpeg_compress_struct));
MEMZERO(cinfo, sizeof(struct jpeg_compress_struct));
cinfo->err = err;
cinfo->client_data = client_data;
}
@@ -91,18 +90,8 @@ jpeg_CreateCompress(j_compress_ptr cinfo, int version, size_t structsize)
cinfo->input_gamma = 1.0; /* in case application forgets */
cinfo->data_precision = BITS_IN_JSAMPLE;
/* OK, I'm ready */
cinfo->global_state = CSTATE_START;
/* The master struct is used to store extension parameters, so we allocate it
* here.
*/
cinfo->master = (struct jpeg_comp_master *)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_PERMANENT,
sizeof(my_comp_master));
memset(cinfo->master, 0, sizeof(my_comp_master));
}
@@ -194,20 +183,8 @@ jpeg_finish_compress(j_compress_ptr cinfo)
/* We bypass the main controller and invoke coef controller directly;
* all work is being done from the coefficient buffer.
*/
if (cinfo->data_precision == 16) {
#ifdef C_LOSSLESS_SUPPORTED
if (!(*cinfo->coef->compress_data_16) (cinfo, (J16SAMPIMAGE)NULL))
ERREXIT(cinfo, JERR_CANT_SUSPEND);
#else
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
#endif
} else if (cinfo->data_precision == 12) {
if (!(*cinfo->coef->compress_data_12) (cinfo, (J12SAMPIMAGE)NULL))
ERREXIT(cinfo, JERR_CANT_SUSPEND);
} else {
if (!(*cinfo->coef->compress_data) (cinfo, (JSAMPIMAGE)NULL))
ERREXIT(cinfo, JERR_CANT_SUSPEND);
}
if (!(*cinfo->coef->compress_data) (cinfo, (JSAMPIMAGE)NULL))
ERREXIT(cinfo, JERR_CANT_SUSPEND);
}
(*cinfo->master->finish_pass) (cinfo);
}
+14 -39
View File
@@ -1,10 +1,8 @@
/*
* jcapistd.c
*
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1994-1996, Thomas G. Lane.
* libjpeg-turbo Modifications:
* Copyright (C) 2022, D. R. Commander.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -20,11 +18,8 @@
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jsamplecomp.h"
#if BITS_IN_JSAMPLE == 8
/*
* Compression initialization.
* Before calling this, all parameters and a data destination must be set up.
@@ -56,15 +51,13 @@ jpeg_start_compress(j_compress_ptr cinfo, boolean write_all_tables)
jinit_compress_master(cinfo);
/* Set up for the first pass */
(*cinfo->master->prepare_for_pass) (cinfo);
/* Ready for application to drive first pass through _jpeg_write_scanlines
* or _jpeg_write_raw_data.
/* Ready for application to drive first pass through jpeg_write_scanlines
* or jpeg_write_raw_data.
*/
cinfo->next_scanline = 0;
cinfo->global_state = (cinfo->raw_data_in ? CSTATE_RAW_OK : CSTATE_SCANNING);
}
#endif
/*
* Write some scanlines of data to the JPEG compressor.
@@ -74,7 +67,7 @@ jpeg_start_compress(j_compress_ptr cinfo, boolean write_all_tables)
* the data destination module has requested suspension of the compressor,
* or if more than image_height scanlines are passed in.
*
* Note: we warn about excess calls to _jpeg_write_scanlines() since
* Note: we warn about excess calls to jpeg_write_scanlines() since
* this likely signals an application programmer error. However,
* excess scanlines passed in the last valid call are *silently* ignored,
* so that the application need not adjust num_lines for end-of-image
@@ -82,15 +75,11 @@ jpeg_start_compress(j_compress_ptr cinfo, boolean write_all_tables)
*/
GLOBAL(JDIMENSION)
_jpeg_write_scanlines(j_compress_ptr cinfo, _JSAMPARRAY scanlines,
JDIMENSION num_lines)
jpeg_write_scanlines(j_compress_ptr cinfo, JSAMPARRAY scanlines,
JDIMENSION num_lines)
{
#if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED)
JDIMENSION row_ctr, rows_left;
if (cinfo->data_precision != BITS_IN_JSAMPLE)
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
if (cinfo->global_state != CSTATE_SCANNING)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
if (cinfo->next_scanline >= cinfo->image_height)
@@ -104,9 +93,9 @@ _jpeg_write_scanlines(j_compress_ptr cinfo, _JSAMPARRAY scanlines,
}
/* Give master control module another chance if this is first call to
* _jpeg_write_scanlines. This lets output of the frame/scan headers be
* jpeg_write_scanlines. This lets output of the frame/scan headers be
* delayed so that application can write COM, etc, markers between
* jpeg_start_compress and _jpeg_write_scanlines.
* jpeg_start_compress and jpeg_write_scanlines.
*/
if (cinfo->master->call_pass_startup)
(*cinfo->master->pass_startup) (cinfo);
@@ -117,35 +106,23 @@ _jpeg_write_scanlines(j_compress_ptr cinfo, _JSAMPARRAY scanlines,
num_lines = rows_left;
row_ctr = 0;
(*cinfo->main->_process_data) (cinfo, scanlines, &row_ctr, num_lines);
(*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, num_lines);
cinfo->next_scanline += row_ctr;
return row_ctr;
#else
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
return 0;
#endif
}
#if BITS_IN_JSAMPLE != 16
/*
* Alternate entry point to write raw data.
* Processes exactly one iMCU row per call, unless suspended.
*/
GLOBAL(JDIMENSION)
_jpeg_write_raw_data(j_compress_ptr cinfo, _JSAMPIMAGE data,
JDIMENSION num_lines)
jpeg_write_raw_data(j_compress_ptr cinfo, JSAMPIMAGE data,
JDIMENSION num_lines)
{
JDIMENSION lines_per_iMCU_row;
if (cinfo->data_precision != BITS_IN_JSAMPLE)
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
if (cinfo->master->lossless)
ERREXIT(cinfo, JERR_NOTIMPL);
if (cinfo->global_state != CSTATE_RAW_OK)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
if (cinfo->next_scanline >= cinfo->image_height) {
@@ -161,9 +138,9 @@ _jpeg_write_raw_data(j_compress_ptr cinfo, _JSAMPIMAGE data,
}
/* Give master control module another chance if this is first call to
* _jpeg_write_raw_data. This lets output of the frame/scan headers be
* jpeg_write_raw_data. This lets output of the frame/scan headers be
* delayed so that application can write COM, etc, markers between
* jpeg_start_compress and _jpeg_write_raw_data.
* jpeg_start_compress and jpeg_write_raw_data.
*/
if (cinfo->master->call_pass_startup)
(*cinfo->master->pass_startup) (cinfo);
@@ -174,7 +151,7 @@ _jpeg_write_raw_data(j_compress_ptr cinfo, _JSAMPIMAGE data,
ERREXIT(cinfo, JERR_BUFFER_SIZE);
/* Directly compress the row. */
if (!(*cinfo->coef->_compress_data) (cinfo, data)) {
if (!(*cinfo->coef->compress_data) (cinfo, data)) {
/* If compressor did not consume the whole row, suspend processing. */
return 0;
}
@@ -183,5 +160,3 @@ _jpeg_write_raw_data(j_compress_ptr cinfo, _JSAMPIMAGE data,
cinfo->next_scanline += lines_per_iMCU_row;
return lines_per_iMCU_row;
}
#endif /* BITS_IN_JSAMPLE != 16 */
+6 -6
View File
@@ -4,7 +4,7 @@
* This file was part of the Independent JPEG Group's software:
* Developed 1997-2009 by Guido Vollbeding.
* libjpeg-turbo Modifications:
* Copyright (C) 2015, 2018, 2021-2022, D. R. Commander.
* Copyright (C) 2015, 2018, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -338,14 +338,14 @@ emit_restart(j_compress_ptr cinfo, int restart_num)
compptr = cinfo->cur_comp_info[ci];
/* DC needs no table for refinement scan */
if (cinfo->progressive_mode == 0 || (cinfo->Ss == 0 && cinfo->Ah == 0)) {
memset(entropy->dc_stats[compptr->dc_tbl_no], 0, DC_STAT_BINS);
MEMZERO(entropy->dc_stats[compptr->dc_tbl_no], DC_STAT_BINS);
/* Reset DC predictions to 0 */
entropy->last_dc_val[ci] = 0;
entropy->dc_context[ci] = 0;
}
/* AC needs no table when not present */
if (cinfo->progressive_mode == 0 || cinfo->Se) {
memset(entropy->ac_stats[compptr->ac_tbl_no], 0, AC_STAT_BINS);
MEMZERO(entropy->ac_stats[compptr->ac_tbl_no], AC_STAT_BINS);
}
}
@@ -836,7 +836,7 @@ start_pass(j_compress_ptr cinfo, boolean gather_statistics)
* We are fully adaptive here and need no extra
* statistics gathering pass!
*/
ERREXIT(cinfo, JERR_NOTIMPL);
ERREXIT(cinfo, JERR_NOT_COMPILED);
/* We assume jcmaster.c already validated the progressive scan parameters. */
@@ -867,7 +867,7 @@ start_pass(j_compress_ptr cinfo, boolean gather_statistics)
if (entropy->dc_stats[tbl] == NULL)
entropy->dc_stats[tbl] = (unsigned char *)(*cinfo->mem->alloc_small)
((j_common_ptr)cinfo, JPOOL_IMAGE, DC_STAT_BINS);
memset(entropy->dc_stats[tbl], 0, DC_STAT_BINS);
MEMZERO(entropy->dc_stats[tbl], DC_STAT_BINS);
/* Initialize DC predictions to 0 */
entropy->last_dc_val[ci] = 0;
entropy->dc_context[ci] = 0;
@@ -880,7 +880,7 @@ start_pass(j_compress_ptr cinfo, boolean gather_statistics)
if (entropy->ac_stats[tbl] == NULL)
entropy->ac_stats[tbl] = (unsigned char *)(*cinfo->mem->alloc_small)
((j_common_ptr)cinfo, JPOOL_IMAGE, AC_STAT_BINS);
memset(entropy->ac_stats[tbl], 0, AC_STAT_BINS);
MEMZERO(entropy->ac_stats[tbl], AC_STAT_BINS);
#ifdef CALCULATE_SPECTRAL_CONDITIONING
if (cinfo->progressive_mode)
/* Section G.1.3.2: Set appropriate arithmetic conditioning value Kx */
+21 -26
View File
@@ -3,20 +3,19 @@
*
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1994-1997, Thomas G. Lane.
* libjpeg-turbo Modifications:
* Copyright (C) 2022, D. R. Commander.
* It was modified by The libjpeg-turbo Project to include only code and
* information relevant to libjpeg-turbo.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
* This file contains the coefficient buffer controller for compression.
* This controller is the top level of the lossy JPEG compressor proper.
* This controller is the top level of the JPEG compressor proper.
* The coefficient buffer lies between forward-DCT and entropy encoding steps.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jsamplecomp.h"
/* We use a full-image coefficient buffer when doing Huffman optimization,
@@ -59,12 +58,11 @@ typedef my_coef_controller *my_coef_ptr;
/* Forward declarations */
METHODDEF(boolean) compress_data(j_compress_ptr cinfo, _JSAMPIMAGE input_buf);
METHODDEF(boolean) compress_data(j_compress_ptr cinfo, JSAMPIMAGE input_buf);
#ifdef FULL_COEF_BUFFER_SUPPORTED
METHODDEF(boolean) compress_first_pass(j_compress_ptr cinfo,
_JSAMPIMAGE input_buf);
METHODDEF(boolean) compress_output(j_compress_ptr cinfo,
_JSAMPIMAGE input_buf);
JSAMPIMAGE input_buf);
METHODDEF(boolean) compress_output(j_compress_ptr cinfo, JSAMPIMAGE input_buf);
#endif
@@ -108,18 +106,18 @@ start_pass_coef(j_compress_ptr cinfo, J_BUF_MODE pass_mode)
case JBUF_PASS_THRU:
if (coef->whole_image[0] != NULL)
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
coef->pub._compress_data = compress_data;
coef->pub.compress_data = compress_data;
break;
#ifdef FULL_COEF_BUFFER_SUPPORTED
case JBUF_SAVE_AND_PASS:
if (coef->whole_image[0] == NULL)
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
coef->pub._compress_data = compress_first_pass;
coef->pub.compress_data = compress_first_pass;
break;
case JBUF_CRANK_DEST:
if (coef->whole_image[0] == NULL)
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
coef->pub._compress_data = compress_output;
coef->pub.compress_data = compress_output;
break;
#endif
default:
@@ -140,7 +138,7 @@ start_pass_coef(j_compress_ptr cinfo, J_BUF_MODE pass_mode)
*/
METHODDEF(boolean)
compress_data(j_compress_ptr cinfo, _JSAMPIMAGE input_buf)
compress_data(j_compress_ptr cinfo, JSAMPIMAGE input_buf)
{
my_coef_ptr coef = (my_coef_ptr)cinfo->coef;
JDIMENSION MCU_col_num; /* index of current MCU within row */
@@ -174,10 +172,10 @@ compress_data(j_compress_ptr cinfo, _JSAMPIMAGE input_buf)
for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
if (coef->iMCU_row_num < last_iMCU_row ||
yoffset + yindex < compptr->last_row_height) {
(*cinfo->fdct->_forward_DCT) (cinfo, compptr,
input_buf[compptr->component_index],
coef->MCU_buffer[blkn],
ypos, xpos, (JDIMENSION)blockcnt);
(*cinfo->fdct->forward_DCT) (cinfo, compptr,
input_buf[compptr->component_index],
coef->MCU_buffer[blkn],
ypos, xpos, (JDIMENSION)blockcnt);
if (blockcnt < compptr->MCU_width) {
/* Create some dummy blocks at the right edge of the image. */
jzero_far((void *)coef->MCU_buffer[blkn + blockcnt],
@@ -244,7 +242,7 @@ compress_data(j_compress_ptr cinfo, _JSAMPIMAGE input_buf)
*/
METHODDEF(boolean)
compress_first_pass(j_compress_ptr cinfo, _JSAMPIMAGE input_buf)
compress_first_pass(j_compress_ptr cinfo, JSAMPIMAGE input_buf)
{
my_coef_ptr coef = (my_coef_ptr)cinfo->coef;
JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
@@ -281,10 +279,10 @@ compress_first_pass(j_compress_ptr cinfo, _JSAMPIMAGE input_buf)
*/
for (block_row = 0; block_row < block_rows; block_row++) {
thisblockrow = buffer[block_row];
(*cinfo->fdct->_forward_DCT) (cinfo, compptr,
input_buf[ci], thisblockrow,
(JDIMENSION)(block_row * DCTSIZE),
(JDIMENSION)0, blocks_across);
(*cinfo->fdct->forward_DCT) (cinfo, compptr,
input_buf[ci], thisblockrow,
(JDIMENSION)(block_row * DCTSIZE),
(JDIMENSION)0, blocks_across);
if (ndummy > 0) {
/* Create dummy blocks at the right edge of the image. */
thisblockrow += blocks_across; /* => first dummy block */
@@ -340,7 +338,7 @@ compress_first_pass(j_compress_ptr cinfo, _JSAMPIMAGE input_buf)
*/
METHODDEF(boolean)
compress_output(j_compress_ptr cinfo, _JSAMPIMAGE input_buf)
compress_output(j_compress_ptr cinfo, JSAMPIMAGE input_buf)
{
my_coef_ptr coef = (my_coef_ptr)cinfo->coef;
JDIMENSION MCU_col_num; /* index of current MCU within row */
@@ -404,13 +402,10 @@ compress_output(j_compress_ptr cinfo, _JSAMPIMAGE input_buf)
*/
GLOBAL(void)
_jinit_c_coef_controller(j_compress_ptr cinfo, boolean need_full_buffer)
jinit_c_coef_controller(j_compress_ptr cinfo, boolean need_full_buffer)
{
my_coef_ptr coef;
if (cinfo->data_precision != BITS_IN_JSAMPLE)
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
coef = (my_coef_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
sizeof(my_coef_controller));
+31 -39
View File
@@ -4,7 +4,7 @@
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-1996, Thomas G. Lane.
* libjpeg-turbo Modifications:
* Copyright (C) 2009-2012, 2015, 2022, D. R. Commander.
* Copyright (C) 2009-2012, 2015, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -29,16 +29,15 @@
INLINE
LOCAL(void)
rgb_ycc_convert_internal(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
_JSAMPIMAGE output_buf, JDIMENSION output_row,
rgb_ycc_convert_internal(j_compress_ptr cinfo, JSAMPARRAY input_buf,
JSAMPIMAGE output_buf, JDIMENSION output_row,
int num_rows)
{
#if BITS_IN_JSAMPLE != 16
my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
register int r, g, b;
register JLONG *ctab = cconvert->rgb_ycc_tab;
register _JSAMPROW inptr;
register _JSAMPROW outptr0, outptr1, outptr2;
register JSAMPROW inptr;
register JSAMPROW outptr0, outptr1, outptr2;
register JDIMENSION col;
JDIMENSION num_cols = cinfo->image_width;
@@ -49,29 +48,26 @@ rgb_ycc_convert_internal(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
outptr2 = output_buf[2][output_row];
output_row++;
for (col = 0; col < num_cols; col++) {
r = RANGE_LIMIT(inptr[RGB_RED]);
g = RANGE_LIMIT(inptr[RGB_GREEN]);
b = RANGE_LIMIT(inptr[RGB_BLUE]);
r = GETJSAMPLE(inptr[RGB_RED]);
g = GETJSAMPLE(inptr[RGB_GREEN]);
b = GETJSAMPLE(inptr[RGB_BLUE]);
inptr += RGB_PIXELSIZE;
/* If the inputs are 0.._MAXJSAMPLE, the outputs of these equations
/* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
* must be too; we do not need an explicit range-limiting operation.
* Hence the value being shifted is never negative, and we don't
* need the general RIGHT_SHIFT macro.
*/
/* Y */
outptr0[col] = (_JSAMPLE)((ctab[r + R_Y_OFF] + ctab[g + G_Y_OFF] +
ctab[b + B_Y_OFF]) >> SCALEBITS);
outptr0[col] = (JSAMPLE)((ctab[r + R_Y_OFF] + ctab[g + G_Y_OFF] +
ctab[b + B_Y_OFF]) >> SCALEBITS);
/* Cb */
outptr1[col] = (_JSAMPLE)((ctab[r + R_CB_OFF] + ctab[g + G_CB_OFF] +
ctab[b + B_CB_OFF]) >> SCALEBITS);
outptr1[col] = (JSAMPLE)((ctab[r + R_CB_OFF] + ctab[g + G_CB_OFF] +
ctab[b + B_CB_OFF]) >> SCALEBITS);
/* Cr */
outptr2[col] = (_JSAMPLE)((ctab[r + R_CR_OFF] + ctab[g + G_CR_OFF] +
ctab[b + B_CR_OFF]) >> SCALEBITS);
outptr2[col] = (JSAMPLE)((ctab[r + R_CR_OFF] + ctab[g + G_CR_OFF] +
ctab[b + B_CR_OFF]) >> SCALEBITS);
}
}
#else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
#endif
}
@@ -87,16 +83,15 @@ rgb_ycc_convert_internal(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
INLINE
LOCAL(void)
rgb_gray_convert_internal(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
_JSAMPIMAGE output_buf, JDIMENSION output_row,
rgb_gray_convert_internal(j_compress_ptr cinfo, JSAMPARRAY input_buf,
JSAMPIMAGE output_buf, JDIMENSION output_row,
int num_rows)
{
#if BITS_IN_JSAMPLE != 16
my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
register int r, g, b;
register JLONG *ctab = cconvert->rgb_ycc_tab;
register _JSAMPROW inptr;
register _JSAMPROW outptr;
register JSAMPROW inptr;
register JSAMPROW outptr;
register JDIMENSION col;
JDIMENSION num_cols = cinfo->image_width;
@@ -105,18 +100,15 @@ rgb_gray_convert_internal(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
outptr = output_buf[0][output_row];
output_row++;
for (col = 0; col < num_cols; col++) {
r = RANGE_LIMIT(inptr[RGB_RED]);
g = RANGE_LIMIT(inptr[RGB_GREEN]);
b = RANGE_LIMIT(inptr[RGB_BLUE]);
r = GETJSAMPLE(inptr[RGB_RED]);
g = GETJSAMPLE(inptr[RGB_GREEN]);
b = GETJSAMPLE(inptr[RGB_BLUE]);
inptr += RGB_PIXELSIZE;
/* Y */
outptr[col] = (_JSAMPLE)((ctab[r + R_Y_OFF] + ctab[g + G_Y_OFF] +
ctab[b + B_Y_OFF]) >> SCALEBITS);
outptr[col] = (JSAMPLE)((ctab[r + R_Y_OFF] + ctab[g + G_Y_OFF] +
ctab[b + B_Y_OFF]) >> SCALEBITS);
}
}
#else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
#endif
}
@@ -127,12 +119,12 @@ rgb_gray_convert_internal(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
INLINE
LOCAL(void)
rgb_rgb_convert_internal(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
_JSAMPIMAGE output_buf, JDIMENSION output_row,
rgb_rgb_convert_internal(j_compress_ptr cinfo, JSAMPARRAY input_buf,
JSAMPIMAGE output_buf, JDIMENSION output_row,
int num_rows)
{
register _JSAMPROW inptr;
register _JSAMPROW outptr0, outptr1, outptr2;
register JSAMPROW inptr;
register JSAMPROW outptr0, outptr1, outptr2;
register JDIMENSION col;
JDIMENSION num_cols = cinfo->image_width;
@@ -143,9 +135,9 @@ rgb_rgb_convert_internal(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
outptr2 = output_buf[2][output_row];
output_row++;
for (col = 0; col < num_cols; col++) {
outptr0[col] = inptr[RGB_RED];
outptr1[col] = inptr[RGB_GREEN];
outptr2[col] = inptr[RGB_BLUE];
outptr0[col] = GETJSAMPLE(inptr[RGB_RED]);
outptr1[col] = GETJSAMPLE(inptr[RGB_GREEN]);
outptr2[col] = GETJSAMPLE(inptr[RGB_BLUE]);
inptr += RGB_PIXELSIZE;
}
}
+112 -134
View File
@@ -5,7 +5,7 @@
* Copyright (C) 1991-1996, Thomas G. Lane.
* libjpeg-turbo Modifications:
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
* Copyright (C) 2009-2012, 2015, 2022, D. R. Commander.
* Copyright (C) 2009-2012, 2015, D. R. Commander.
* Copyright (C) 2014, MIPS Technologies, Inc., California.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
@@ -17,20 +17,16 @@
#include "jinclude.h"
#include "jpeglib.h"
#include "jsimd.h"
#include "jsamplecomp.h"
#include "jconfigint.h"
#if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED)
/* Private subobject */
typedef struct {
struct jpeg_color_converter pub; /* public fields */
#if BITS_IN_JSAMPLE != 16
/* Private state for RGB->YCC conversion */
JLONG *rgb_ycc_tab; /* => table for RGB to YCbCr conversion */
#endif
} my_color_converter;
typedef my_color_converter *my_cconvert_ptr;
@@ -40,14 +36,14 @@ typedef my_color_converter *my_cconvert_ptr;
/*
* YCbCr is defined per CCIR 601-1, except that Cb and Cr are
* normalized to the range 0.._MAXJSAMPLE rather than -0.5 .. 0.5.
* normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
* The conversion equations to be implemented are therefore
* Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
* Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + _CENTERJSAMPLE
* Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + _CENTERJSAMPLE
* Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE
* Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE
* (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
* Note: older versions of the IJG code used a zero offset of _MAXJSAMPLE/2,
* rather than _CENTERJSAMPLE, for Cb and Cr. This gave equal positive and
* Note: older versions of the IJG code used a zero offset of MAXJSAMPLE/2,
* rather than CENTERJSAMPLE, for Cb and Cr. This gave equal positive and
* negative swings for Cb/Cr, but meant that grayscale values (Cb=Cr=0)
* were not represented exactly. Now we sacrifice exact representation of
* maximum red and maximum blue in order to get exact grayscales.
@@ -58,16 +54,16 @@ typedef my_color_converter *my_cconvert_ptr;
*
* For even more speed, we avoid doing any multiplications in the inner loop
* by precalculating the constants times R,G,B for all possible values.
* For 8-bit samples this is very reasonable (only 256 entries per table);
* For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
* for 12-bit samples it is still acceptable. It's not very reasonable for
* 16-bit samples, but if you want lossless storage you shouldn't be changing
* colorspace anyway.
* The _CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included
* The CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included
* in the tables to save adding them separately in the inner loop.
*/
#define SCALEBITS 16 /* speediest right-shift on some machines */
#define CBCR_OFFSET ((JLONG)_CENTERJSAMPLE << SCALEBITS)
#define CBCR_OFFSET ((JLONG)CENTERJSAMPLE << SCALEBITS)
#define ONE_HALF ((JLONG)1 << (SCALEBITS - 1))
#define FIX(x) ((JLONG)((x) * (1L << SCALEBITS) + 0.5))
@@ -78,27 +74,15 @@ typedef my_color_converter *my_cconvert_ptr;
*/
#define R_Y_OFF 0 /* offset to R => Y section */
#define G_Y_OFF (1 * (_MAXJSAMPLE + 1)) /* offset to G => Y section */
#define B_Y_OFF (2 * (_MAXJSAMPLE + 1)) /* etc. */
#define R_CB_OFF (3 * (_MAXJSAMPLE + 1))
#define G_CB_OFF (4 * (_MAXJSAMPLE + 1))
#define B_CB_OFF (5 * (_MAXJSAMPLE + 1))
#define G_Y_OFF (1 * (MAXJSAMPLE + 1)) /* offset to G => Y section */
#define B_Y_OFF (2 * (MAXJSAMPLE + 1)) /* etc. */
#define R_CB_OFF (3 * (MAXJSAMPLE + 1))
#define G_CB_OFF (4 * (MAXJSAMPLE + 1))
#define B_CB_OFF (5 * (MAXJSAMPLE + 1))
#define R_CR_OFF B_CB_OFF /* B=>Cb, R=>Cr are the same */
#define G_CR_OFF (6 * (_MAXJSAMPLE + 1))
#define B_CR_OFF (7 * (_MAXJSAMPLE + 1))
#define TABLE_SIZE (8 * (_MAXJSAMPLE + 1))
/* 12-bit samples use a 16-bit data type, so it is possible to pass
* out-of-range sample values (< 0 or > 4095) to jpeg_write_scanlines().
* Thus, we mask the incoming 12-bit samples to guard against overrunning
* or underrunning the conversion tables.
*/
#if BITS_IN_JSAMPLE == 12
#define RANGE_LIMIT(value) ((value) & 0xFFF)
#else
#define RANGE_LIMIT(value) (value)
#endif
#define G_CR_OFF (6 * (MAXJSAMPLE + 1))
#define B_CR_OFF (7 * (MAXJSAMPLE + 1))
#define TABLE_SIZE (8 * (MAXJSAMPLE + 1))
/* Include inline routines for colorspace extensions */
@@ -213,7 +197,6 @@ typedef my_color_converter *my_cconvert_ptr;
METHODDEF(void)
rgb_ycc_start(j_compress_ptr cinfo)
{
#if BITS_IN_JSAMPLE != 16
my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
JLONG *rgb_ycc_tab;
JLONG i;
@@ -223,15 +206,15 @@ rgb_ycc_start(j_compress_ptr cinfo)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
(TABLE_SIZE * sizeof(JLONG)));
for (i = 0; i <= _MAXJSAMPLE; i++) {
for (i = 0; i <= MAXJSAMPLE; i++) {
rgb_ycc_tab[i + R_Y_OFF] = FIX(0.29900) * i;
rgb_ycc_tab[i + G_Y_OFF] = FIX(0.58700) * i;
rgb_ycc_tab[i + B_Y_OFF] = FIX(0.11400) * i + ONE_HALF;
rgb_ycc_tab[i + R_CB_OFF] = (-FIX(0.16874)) * i;
rgb_ycc_tab[i + G_CB_OFF] = (-FIX(0.33126)) * i;
/* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr.
* This ensures that the maximum output will round to _MAXJSAMPLE
* not _MAXJSAMPLE+1, and thus that we don't have to range-limit.
* This ensures that the maximum output will round to MAXJSAMPLE
* not MAXJSAMPLE+1, and thus that we don't have to range-limit.
*/
rgb_ycc_tab[i + B_CB_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF - 1;
/* B=>Cb and R=>Cr tables are the same
@@ -240,9 +223,6 @@ rgb_ycc_start(j_compress_ptr cinfo)
rgb_ycc_tab[i + G_CR_OFF] = (-FIX(0.41869)) * i;
rgb_ycc_tab[i + B_CR_OFF] = (-FIX(0.08131)) * i;
}
#else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
#endif
}
@@ -251,8 +231,8 @@ rgb_ycc_start(j_compress_ptr cinfo)
*/
METHODDEF(void)
rgb_ycc_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
_JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)
rgb_ycc_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)
{
switch (cinfo->in_color_space) {
case JCS_EXT_RGB:
@@ -299,8 +279,8 @@ rgb_ycc_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
*/
METHODDEF(void)
rgb_gray_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
_JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)
rgb_gray_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)
{
switch (cinfo->in_color_space) {
case JCS_EXT_RGB:
@@ -344,8 +324,8 @@ rgb_gray_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
*/
METHODDEF(void)
rgb_rgb_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
_JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)
rgb_rgb_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)
{
switch (cinfo->in_color_space) {
case JCS_EXT_RGB:
@@ -393,15 +373,14 @@ rgb_rgb_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
*/
METHODDEF(void)
cmyk_ycck_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
_JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)
cmyk_ycck_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)
{
#if BITS_IN_JSAMPLE != 16
my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
register int r, g, b;
register JLONG *ctab = cconvert->rgb_ycc_tab;
register _JSAMPROW inptr;
register _JSAMPROW outptr0, outptr1, outptr2, outptr3;
register JSAMPROW inptr;
register JSAMPROW outptr0, outptr1, outptr2, outptr3;
register JDIMENSION col;
JDIMENSION num_cols = cinfo->image_width;
@@ -413,31 +392,28 @@ cmyk_ycck_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
outptr3 = output_buf[3][output_row];
output_row++;
for (col = 0; col < num_cols; col++) {
r = _MAXJSAMPLE - RANGE_LIMIT(inptr[0]);
g = _MAXJSAMPLE - RANGE_LIMIT(inptr[1]);
b = _MAXJSAMPLE - RANGE_LIMIT(inptr[2]);
r = MAXJSAMPLE - GETJSAMPLE(inptr[0]);
g = MAXJSAMPLE - GETJSAMPLE(inptr[1]);
b = MAXJSAMPLE - GETJSAMPLE(inptr[2]);
/* K passes through as-is */
outptr3[col] = inptr[3];
outptr3[col] = inptr[3]; /* don't need GETJSAMPLE here */
inptr += 4;
/* If the inputs are 0.._MAXJSAMPLE, the outputs of these equations
/* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
* must be too; we do not need an explicit range-limiting operation.
* Hence the value being shifted is never negative, and we don't
* need the general RIGHT_SHIFT macro.
*/
/* Y */
outptr0[col] = (_JSAMPLE)((ctab[r + R_Y_OFF] + ctab[g + G_Y_OFF] +
ctab[b + B_Y_OFF]) >> SCALEBITS);
outptr0[col] = (JSAMPLE)((ctab[r + R_Y_OFF] + ctab[g + G_Y_OFF] +
ctab[b + B_Y_OFF]) >> SCALEBITS);
/* Cb */
outptr1[col] = (_JSAMPLE)((ctab[r + R_CB_OFF] + ctab[g + G_CB_OFF] +
ctab[b + B_CB_OFF]) >> SCALEBITS);
outptr1[col] = (JSAMPLE)((ctab[r + R_CB_OFF] + ctab[g + G_CB_OFF] +
ctab[b + B_CB_OFF]) >> SCALEBITS);
/* Cr */
outptr2[col] = (_JSAMPLE)((ctab[r + R_CR_OFF] + ctab[g + G_CR_OFF] +
ctab[b + B_CR_OFF]) >> SCALEBITS);
outptr2[col] = (JSAMPLE)((ctab[r + R_CR_OFF] + ctab[g + G_CR_OFF] +
ctab[b + B_CR_OFF]) >> SCALEBITS);
}
}
#else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
#endif
}
@@ -448,11 +424,11 @@ cmyk_ycck_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
*/
METHODDEF(void)
grayscale_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
_JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)
grayscale_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)
{
register _JSAMPROW inptr;
register _JSAMPROW outptr;
register JSAMPROW inptr;
register JSAMPROW outptr;
register JDIMENSION col;
JDIMENSION num_cols = cinfo->image_width;
int instride = cinfo->input_components;
@@ -462,7 +438,7 @@ grayscale_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
outptr = output_buf[0][output_row];
output_row++;
for (col = 0; col < num_cols; col++) {
outptr[col] = inptr[0];
outptr[col] = inptr[0]; /* don't need GETJSAMPLE() here */
inptr += instride;
}
}
@@ -476,11 +452,11 @@ grayscale_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
*/
METHODDEF(void)
null_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
_JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)
null_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
JDIMENSION output_row, int num_rows)
{
register _JSAMPROW inptr;
register _JSAMPROW outptr, outptr0, outptr1, outptr2, outptr3;
register JSAMPROW inptr;
register JSAMPROW outptr, outptr0, outptr1, outptr2, outptr3;
register JDIMENSION col;
register int ci;
int nc = cinfo->num_components;
@@ -521,7 +497,7 @@ null_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
inptr = *input_buf;
outptr = output_buf[ci][output_row];
for (col = 0; col < num_cols; col++) {
outptr[col] = inptr[ci];
outptr[col] = inptr[ci]; /* don't need GETJSAMPLE() here */
inptr += nc;
}
}
@@ -548,13 +524,10 @@ null_method(j_compress_ptr cinfo)
*/
GLOBAL(void)
_jinit_color_converter(j_compress_ptr cinfo)
jinit_color_converter(j_compress_ptr cinfo)
{
my_cconvert_ptr cconvert;
if (cinfo->data_precision != BITS_IN_JSAMPLE)
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
cconvert = (my_cconvert_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
sizeof(my_color_converter));
@@ -601,116 +574,123 @@ _jinit_color_converter(j_compress_ptr cinfo)
break;
}
/* Check num_components, set conversion method based on requested space.
* NOTE: We do not allow any lossy color conversion algorithms in lossless
* mode.
*/
/* Check num_components, set conversion method based on requested space */
switch (cinfo->jpeg_color_space) {
case JCS_GRAYSCALE:
if (cinfo->master->lossless &&
cinfo->in_color_space != cinfo->jpeg_color_space)
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
if (cinfo->num_components != 1)
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
if (cinfo->in_color_space == JCS_GRAYSCALE)
cconvert->pub._color_convert = grayscale_convert;
else if (IsExtRGB(cinfo->in_color_space)) {
#ifdef WITH_SIMD
cconvert->pub.color_convert = grayscale_convert;
else if (cinfo->in_color_space == JCS_RGB ||
cinfo->in_color_space == JCS_EXT_RGB ||
cinfo->in_color_space == JCS_EXT_RGBX ||
cinfo->in_color_space == JCS_EXT_BGR ||
cinfo->in_color_space == JCS_EXT_BGRX ||
cinfo->in_color_space == JCS_EXT_XBGR ||
cinfo->in_color_space == JCS_EXT_XRGB ||
cinfo->in_color_space == JCS_EXT_RGBA ||
cinfo->in_color_space == JCS_EXT_BGRA ||
cinfo->in_color_space == JCS_EXT_ABGR ||
cinfo->in_color_space == JCS_EXT_ARGB) {
if (jsimd_can_rgb_gray())
cconvert->pub._color_convert = jsimd_rgb_gray_convert;
else
#endif
{
cconvert->pub.color_convert = jsimd_rgb_gray_convert;
else {
cconvert->pub.start_pass = rgb_ycc_start;
cconvert->pub._color_convert = rgb_gray_convert;
cconvert->pub.color_convert = rgb_gray_convert;
}
} else if (cinfo->in_color_space == JCS_YCbCr)
cconvert->pub._color_convert = grayscale_convert;
cconvert->pub.color_convert = grayscale_convert;
else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
break;
case JCS_RGB:
if (cinfo->master->lossless && !IsExtRGB(cinfo->in_color_space))
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
if (cinfo->num_components != 3)
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
if (rgb_red[cinfo->in_color_space] == 0 &&
rgb_green[cinfo->in_color_space] == 1 &&
rgb_blue[cinfo->in_color_space] == 2 &&
rgb_pixelsize[cinfo->in_color_space] == 3) {
#if defined(WITH_SIMD) && defined(__mips__)
#if defined(__mips__)
if (jsimd_c_can_null_convert())
cconvert->pub._color_convert = jsimd_c_null_convert;
cconvert->pub.color_convert = jsimd_c_null_convert;
else
#endif
cconvert->pub._color_convert = null_convert;
} else if (IsExtRGB(cinfo->in_color_space))
cconvert->pub._color_convert = rgb_rgb_convert;
cconvert->pub.color_convert = null_convert;
} else if (cinfo->in_color_space == JCS_RGB ||
cinfo->in_color_space == JCS_EXT_RGB ||
cinfo->in_color_space == JCS_EXT_RGBX ||
cinfo->in_color_space == JCS_EXT_BGR ||
cinfo->in_color_space == JCS_EXT_BGRX ||
cinfo->in_color_space == JCS_EXT_XBGR ||
cinfo->in_color_space == JCS_EXT_XRGB ||
cinfo->in_color_space == JCS_EXT_RGBA ||
cinfo->in_color_space == JCS_EXT_BGRA ||
cinfo->in_color_space == JCS_EXT_ABGR ||
cinfo->in_color_space == JCS_EXT_ARGB)
cconvert->pub.color_convert = rgb_rgb_convert;
else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
break;
case JCS_YCbCr:
if (cinfo->master->lossless &&
cinfo->in_color_space != cinfo->jpeg_color_space)
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
if (cinfo->num_components != 3)
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
if (IsExtRGB(cinfo->in_color_space)) {
#ifdef WITH_SIMD
if (cinfo->in_color_space == JCS_RGB ||
cinfo->in_color_space == JCS_EXT_RGB ||
cinfo->in_color_space == JCS_EXT_RGBX ||
cinfo->in_color_space == JCS_EXT_BGR ||
cinfo->in_color_space == JCS_EXT_BGRX ||
cinfo->in_color_space == JCS_EXT_XBGR ||
cinfo->in_color_space == JCS_EXT_XRGB ||
cinfo->in_color_space == JCS_EXT_RGBA ||
cinfo->in_color_space == JCS_EXT_BGRA ||
cinfo->in_color_space == JCS_EXT_ABGR ||
cinfo->in_color_space == JCS_EXT_ARGB) {
if (jsimd_can_rgb_ycc())
cconvert->pub._color_convert = jsimd_rgb_ycc_convert;
else
#endif
{
cconvert->pub.color_convert = jsimd_rgb_ycc_convert;
else {
cconvert->pub.start_pass = rgb_ycc_start;
cconvert->pub._color_convert = rgb_ycc_convert;
cconvert->pub.color_convert = rgb_ycc_convert;
}
} else if (cinfo->in_color_space == JCS_YCbCr) {
#if defined(WITH_SIMD) && defined(__mips__)
#if defined(__mips__)
if (jsimd_c_can_null_convert())
cconvert->pub._color_convert = jsimd_c_null_convert;
cconvert->pub.color_convert = jsimd_c_null_convert;
else
#endif
cconvert->pub._color_convert = null_convert;
cconvert->pub.color_convert = null_convert;
} else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
break;
case JCS_CMYK:
if (cinfo->master->lossless &&
cinfo->in_color_space != cinfo->jpeg_color_space)
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
if (cinfo->num_components != 4)
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
if (cinfo->in_color_space == JCS_CMYK) {
#if defined(WITH_SIMD) && defined(__mips__)
#if defined(__mips__)
if (jsimd_c_can_null_convert())
cconvert->pub._color_convert = jsimd_c_null_convert;
cconvert->pub.color_convert = jsimd_c_null_convert;
else
#endif
cconvert->pub._color_convert = null_convert;
cconvert->pub.color_convert = null_convert;
} else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
break;
case JCS_YCCK:
if (cinfo->master->lossless &&
cinfo->in_color_space != cinfo->jpeg_color_space)
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
if (cinfo->num_components != 4)
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
if (cinfo->in_color_space == JCS_CMYK) {
cconvert->pub.start_pass = rgb_ycc_start;
cconvert->pub._color_convert = cmyk_ycck_convert;
cconvert->pub.color_convert = cmyk_ycck_convert;
} else if (cinfo->in_color_space == JCS_YCCK) {
#if defined(WITH_SIMD) && defined(__mips__)
#if defined(__mips__)
if (jsimd_c_can_null_convert())
cconvert->pub._color_convert = jsimd_c_null_convert;
cconvert->pub.color_convert = jsimd_c_null_convert;
else
#endif
cconvert->pub._color_convert = null_convert;
cconvert->pub.color_convert = null_convert;
} else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
break;
@@ -719,14 +699,12 @@ _jinit_color_converter(j_compress_ptr cinfo)
if (cinfo->jpeg_color_space != cinfo->in_color_space ||
cinfo->num_components != cinfo->input_components)
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
#if defined(WITH_SIMD) && defined(__mips__)
#if defined(__mips__)
if (jsimd_c_can_null_convert())
cconvert->pub._color_convert = jsimd_c_null_convert;
cconvert->pub.color_convert = jsimd_c_null_convert;
else
#endif
cconvert->pub._color_convert = null_convert;
cconvert->pub.color_convert = null_convert;
break;
}
}
#endif /* BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) */
+34 -61
View File
@@ -6,7 +6,7 @@
* libjpeg-turbo Modifications:
* Copyright (C) 1999-2006, MIYASAKA Masaru.
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
* Copyright (C) 2011, 2014-2015, 2022, D. R. Commander.
* Copyright (C) 2011, 2014-2015, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -28,10 +28,10 @@
typedef void (*forward_DCT_method_ptr) (DCTELEM *data);
typedef void (*float_DCT_method_ptr) (FAST_FLOAT *data);
typedef void (*convsamp_method_ptr) (_JSAMPARRAY sample_data,
typedef void (*convsamp_method_ptr) (JSAMPARRAY sample_data,
JDIMENSION start_col,
DCTELEM *workspace);
typedef void (*float_convsamp_method_ptr) (_JSAMPARRAY sample_data,
typedef void (*float_convsamp_method_ptr) (JSAMPARRAY sample_data,
JDIMENSION start_col,
FAST_FLOAT *workspace);
@@ -265,13 +265,9 @@ start_pass_fdctmgr(j_compress_ptr cinfo)
dtbl = fdct->divisors[qtblno];
for (i = 0; i < DCTSIZE2; i++) {
#if BITS_IN_JSAMPLE == 8
#ifdef WITH_SIMD
if (!compute_reciprocal(qtbl->quantval[i] << 3, &dtbl[i]) &&
fdct->quantize == jsimd_quantize)
fdct->quantize = quantize;
#else
compute_reciprocal(qtbl->quantval[i] << 3, &dtbl[i]);
#endif
#else
dtbl[i] = ((DCTELEM)qtbl->quantval[i]) << 3;
#endif
@@ -309,19 +305,12 @@ start_pass_fdctmgr(j_compress_ptr cinfo)
dtbl = fdct->divisors[qtblno];
for (i = 0; i < DCTSIZE2; i++) {
#if BITS_IN_JSAMPLE == 8
#ifdef WITH_SIMD
if (!compute_reciprocal(
DESCALE(MULTIPLY16V16((JLONG)qtbl->quantval[i],
(JLONG)aanscales[i]),
CONST_BITS - 3), &dtbl[i]) &&
fdct->quantize == jsimd_quantize)
fdct->quantize = quantize;
#else
compute_reciprocal(
DESCALE(MULTIPLY16V16((JLONG)qtbl->quantval[i],
(JLONG)aanscales[i]),
CONST_BITS-3), &dtbl[i]);
#endif
#else
dtbl[i] = (DCTELEM)
DESCALE(MULTIPLY16V16((JLONG)qtbl->quantval[i],
@@ -381,10 +370,10 @@ start_pass_fdctmgr(j_compress_ptr cinfo)
*/
METHODDEF(void)
convsamp(_JSAMPARRAY sample_data, JDIMENSION start_col, DCTELEM *workspace)
convsamp(JSAMPARRAY sample_data, JDIMENSION start_col, DCTELEM *workspace)
{
register DCTELEM *workspaceptr;
register _JSAMPROW elemptr;
register JSAMPROW elemptr;
register int elemr;
workspaceptr = workspace;
@@ -392,19 +381,19 @@ convsamp(_JSAMPARRAY sample_data, JDIMENSION start_col, DCTELEM *workspace)
elemptr = sample_data[elemr] + start_col;
#if DCTSIZE == 8 /* unroll the inner loop */
*workspaceptr++ = (*elemptr++) - _CENTERJSAMPLE;
*workspaceptr++ = (*elemptr++) - _CENTERJSAMPLE;
*workspaceptr++ = (*elemptr++) - _CENTERJSAMPLE;
*workspaceptr++ = (*elemptr++) - _CENTERJSAMPLE;
*workspaceptr++ = (*elemptr++) - _CENTERJSAMPLE;
*workspaceptr++ = (*elemptr++) - _CENTERJSAMPLE;
*workspaceptr++ = (*elemptr++) - _CENTERJSAMPLE;
*workspaceptr++ = (*elemptr++) - _CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
#else
{
register int elemc;
for (elemc = DCTSIZE; elemc > 0; elemc--)
*workspaceptr++ = (*elemptr++) - _CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
}
#endif
}
@@ -499,7 +488,7 @@ quantize(JCOEFPTR coef_block, DCTELEM *divisors, DCTELEM *workspace)
METHODDEF(void)
forward_DCT(j_compress_ptr cinfo, jpeg_component_info *compptr,
_JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
JDIMENSION start_row, JDIMENSION start_col, JDIMENSION num_blocks)
/* This version is used for integer DCT implementations. */
{
@@ -533,30 +522,31 @@ forward_DCT(j_compress_ptr cinfo, jpeg_component_info *compptr,
#ifdef DCT_FLOAT_SUPPORTED
METHODDEF(void)
convsamp_float(_JSAMPARRAY sample_data, JDIMENSION start_col,
convsamp_float(JSAMPARRAY sample_data, JDIMENSION start_col,
FAST_FLOAT *workspace)
{
register FAST_FLOAT *workspaceptr;
register _JSAMPROW elemptr;
register JSAMPROW elemptr;
register int elemr;
workspaceptr = workspace;
for (elemr = 0; elemr < DCTSIZE; elemr++) {
elemptr = sample_data[elemr] + start_col;
#if DCTSIZE == 8 /* unroll the inner loop */
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - _CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - _CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - _CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - _CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - _CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - _CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - _CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - _CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
#else
{
register int elemc;
for (elemc = DCTSIZE; elemc > 0; elemc--)
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - _CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)
(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
}
#endif
}
@@ -588,7 +578,7 @@ quantize_float(JCOEFPTR coef_block, FAST_FLOAT *divisors,
METHODDEF(void)
forward_DCT_float(j_compress_ptr cinfo, jpeg_component_info *compptr,
_JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
JDIMENSION start_row, JDIMENSION start_col,
JDIMENSION num_blocks)
/* This version is used for floating-point DCT implementations. */
@@ -628,14 +618,11 @@ forward_DCT_float(j_compress_ptr cinfo, jpeg_component_info *compptr,
*/
GLOBAL(void)
_jinit_forward_dct(j_compress_ptr cinfo)
jinit_forward_dct(j_compress_ptr cinfo)
{
my_fdct_ptr fdct;
int i;
if (cinfo->data_precision != BITS_IN_JSAMPLE)
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
fdct = (my_fdct_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
sizeof(my_fdct_controller));
@@ -646,34 +633,28 @@ _jinit_forward_dct(j_compress_ptr cinfo)
switch (cinfo->dct_method) {
#ifdef DCT_ISLOW_SUPPORTED
case JDCT_ISLOW:
fdct->pub._forward_DCT = forward_DCT;
#ifdef WITH_SIMD
fdct->pub.forward_DCT = forward_DCT;
if (jsimd_can_fdct_islow())
fdct->dct = jsimd_fdct_islow;
else
#endif
fdct->dct = _jpeg_fdct_islow;
fdct->dct = jpeg_fdct_islow;
break;
#endif
#ifdef DCT_IFAST_SUPPORTED
case JDCT_IFAST:
fdct->pub._forward_DCT = forward_DCT;
#ifdef WITH_SIMD
fdct->pub.forward_DCT = forward_DCT;
if (jsimd_can_fdct_ifast())
fdct->dct = jsimd_fdct_ifast;
else
#endif
fdct->dct = _jpeg_fdct_ifast;
fdct->dct = jpeg_fdct_ifast;
break;
#endif
#ifdef DCT_FLOAT_SUPPORTED
case JDCT_FLOAT:
fdct->pub._forward_DCT = forward_DCT_float;
#ifdef WITH_SIMD
fdct->pub.forward_DCT = forward_DCT_float;
if (jsimd_can_fdct_float())
fdct->float_dct = jsimd_fdct_float;
else
#endif
fdct->float_dct = jpeg_fdct_float;
break;
#endif
@@ -691,33 +672,25 @@ _jinit_forward_dct(j_compress_ptr cinfo)
case JDCT_IFAST:
#endif
#if defined(DCT_ISLOW_SUPPORTED) || defined(DCT_IFAST_SUPPORTED)
#ifdef WITH_SIMD
if (jsimd_can_convsamp())
fdct->convsamp = jsimd_convsamp;
else
#endif
fdct->convsamp = convsamp;
#ifdef WITH_SIMD
if (jsimd_can_quantize())
fdct->quantize = jsimd_quantize;
else
#endif
fdct->quantize = quantize;
break;
#endif
#ifdef DCT_FLOAT_SUPPORTED
case JDCT_FLOAT:
#ifdef WITH_SIMD
if (jsimd_can_convsamp_float())
fdct->float_convsamp = jsimd_convsamp_float;
else
#endif
fdct->float_convsamp = convsamp_float;
#ifdef WITH_SIMD
if (jsimd_can_quantize_float())
fdct->float_quantize = jsimd_quantize_float;
else
#endif
fdct->float_quantize = quantize_float;
break;
#endif
-411
View File
@@ -1,411 +0,0 @@
/*
* jcdiffct.c
*
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1994-1997, Thomas G. Lane.
* Lossless JPEG Modifications:
* Copyright (C) 1999, Ken Murchison.
* libjpeg-turbo Modifications:
* Copyright (C) 2022, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
* This file contains the difference buffer controller for compression.
* This controller is the top level of the lossless JPEG compressor proper.
* The difference buffer lies between the prediction/differencing and entropy
* encoding steps.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jlossls.h" /* Private declarations for lossless codec */
#ifdef C_LOSSLESS_SUPPORTED
/* We use a full-image sample buffer when doing Huffman optimization,
* and also for writing multiple-scan JPEG files. In all cases, the
* full-image buffer is filled during the first pass, and the scaling,
* prediction and differencing steps are run during subsequent passes.
*/
#ifdef ENTROPY_OPT_SUPPORTED
#define FULL_SAMP_BUFFER_SUPPORTED
#else
#ifdef C_MULTISCAN_FILES_SUPPORTED
#define FULL_SAMP_BUFFER_SUPPORTED
#endif
#endif
/* Private buffer controller object */
typedef struct {
struct jpeg_c_coef_controller pub; /* public fields */
JDIMENSION iMCU_row_num; /* iMCU row # within image */
JDIMENSION mcu_ctr; /* counts MCUs processed in current row */
int MCU_vert_offset; /* counts MCU rows within iMCU row */
int MCU_rows_per_iMCU_row; /* number of such rows needed */
_JSAMPROW cur_row[MAX_COMPONENTS]; /* row of point-transformed samples */
_JSAMPROW prev_row[MAX_COMPONENTS]; /* previous row of Pt'd samples */
JDIFFARRAY diff_buf[MAX_COMPONENTS]; /* iMCU row of differences */
/* In multi-pass modes, we need a virtual sample array for each component. */
jvirt_sarray_ptr whole_image[MAX_COMPONENTS];
} my_diff_controller;
typedef my_diff_controller *my_diff_ptr;
/* Forward declarations */
METHODDEF(boolean) compress_data(j_compress_ptr cinfo, _JSAMPIMAGE input_buf);
#ifdef FULL_SAMP_BUFFER_SUPPORTED
METHODDEF(boolean) compress_first_pass(j_compress_ptr cinfo,
_JSAMPIMAGE input_buf);
METHODDEF(boolean) compress_output(j_compress_ptr cinfo,
_JSAMPIMAGE input_buf);
#endif
LOCAL(void)
start_iMCU_row(j_compress_ptr cinfo)
/* Reset within-iMCU-row counters for a new row */
{
my_diff_ptr diff = (my_diff_ptr)cinfo->coef;
/* In an interleaved scan, an MCU row is the same as an iMCU row.
* In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
* But at the bottom of the image, process only what's left.
*/
if (cinfo->comps_in_scan > 1) {
diff->MCU_rows_per_iMCU_row = 1;
} else {
if (diff->iMCU_row_num < (cinfo->total_iMCU_rows-1))
diff->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
else
diff->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
}
diff->mcu_ctr = 0;
diff->MCU_vert_offset = 0;
}
/*
* Initialize for a processing pass.
*/
METHODDEF(void)
start_pass_diff(j_compress_ptr cinfo, J_BUF_MODE pass_mode)
{
my_diff_ptr diff = (my_diff_ptr)cinfo->coef;
/* Because it is hitching a ride on the jpeg_forward_dct struct,
* start_pass_lossless() will be called at the start of the initial pass.
* This ensures that it will be called at the start of the Huffman
* optimization and output passes as well.
*/
if (pass_mode == JBUF_CRANK_DEST)
(*cinfo->fdct->start_pass) (cinfo);
diff->iMCU_row_num = 0;
start_iMCU_row(cinfo);
switch (pass_mode) {
case JBUF_PASS_THRU:
if (diff->whole_image[0] != NULL)
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
diff->pub._compress_data = compress_data;
break;
#ifdef FULL_SAMP_BUFFER_SUPPORTED
case JBUF_SAVE_AND_PASS:
if (diff->whole_image[0] == NULL)
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
diff->pub._compress_data = compress_first_pass;
break;
case JBUF_CRANK_DEST:
if (diff->whole_image[0] == NULL)
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
diff->pub._compress_data = compress_output;
break;
#endif
default:
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
break;
}
}
#define SWAP_ROWS(rowa, rowb) { \
_JSAMPROW temp = rowa; \
rowa = rowb; rowb = temp; \
}
/*
* Process some data in the single-pass case.
* We process the equivalent of one fully interleaved MCU row ("iMCU" row)
* per call, ie, v_samp_factor rows for each component in the image.
* Returns TRUE if the iMCU row is completed, FALSE if suspended.
*
* NB: input_buf contains a plane for each component in image,
* which we index according to the component's SOF position.
*/
METHODDEF(boolean)
compress_data(j_compress_ptr cinfo, _JSAMPIMAGE input_buf)
{
my_diff_ptr diff = (my_diff_ptr)cinfo->coef;
lossless_comp_ptr losslessc = (lossless_comp_ptr)cinfo->fdct;
JDIMENSION MCU_col_num; /* index of current MCU within row */
JDIMENSION MCU_count; /* number of MCUs encoded */
JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
int ci, compi, yoffset, samp_row, samp_rows, samps_across;
jpeg_component_info *compptr;
/* Loop to write as much as one whole iMCU row */
for (yoffset = diff->MCU_vert_offset; yoffset < diff->MCU_rows_per_iMCU_row;
yoffset++) {
MCU_col_num = diff->mcu_ctr;
/* Scale and predict each scanline of the MCU row separately.
*
* Note: We only do this if we are at the start of an MCU row, ie,
* we don't want to reprocess a row suspended by the output.
*/
if (MCU_col_num == 0) {
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
compi = compptr->component_index;
if (diff->iMCU_row_num < last_iMCU_row)
samp_rows = compptr->v_samp_factor;
else {
/* NB: can't use last_row_height here, since may not be set! */
samp_rows =
(int)(compptr->height_in_blocks % compptr->v_samp_factor);
if (samp_rows == 0) samp_rows = compptr->v_samp_factor;
else {
/* Fill dummy difference rows at the bottom edge with zeros, which
* will encode to the smallest amount of data.
*/
for (samp_row = samp_rows; samp_row < compptr->v_samp_factor;
samp_row++)
memset(diff->diff_buf[compi][samp_row], 0,
jround_up((long)compptr->width_in_blocks,
(long)compptr->h_samp_factor) * sizeof(JDIFF));
}
}
samps_across = compptr->width_in_blocks;
for (samp_row = 0; samp_row < samp_rows; samp_row++) {
(*losslessc->scaler_scale) (cinfo,
input_buf[compi][samp_row],
diff->cur_row[compi],
samps_across);
(*losslessc->predict_difference[compi])
(cinfo, compi, diff->cur_row[compi], diff->prev_row[compi],
diff->diff_buf[compi][samp_row], samps_across);
SWAP_ROWS(diff->cur_row[compi], diff->prev_row[compi]);
}
}
}
/* Try to write the MCU row (or remaining portion of suspended MCU row). */
MCU_count =
(*cinfo->entropy->encode_mcus) (cinfo,
diff->diff_buf, yoffset, MCU_col_num,
cinfo->MCUs_per_row - MCU_col_num);
if (MCU_count != cinfo->MCUs_per_row - MCU_col_num) {
/* Suspension forced; update state counters and exit */
diff->MCU_vert_offset = yoffset;
diff->mcu_ctr += MCU_col_num;
return FALSE;
}
/* Completed an MCU row, but perhaps not an iMCU row */
diff->mcu_ctr = 0;
}
/* Completed the iMCU row, advance counters for next one */
diff->iMCU_row_num++;
start_iMCU_row(cinfo);
return TRUE;
}
#ifdef FULL_SAMP_BUFFER_SUPPORTED
/*
* Process some data in the first pass of a multi-pass case.
* We process the equivalent of one fully interleaved MCU row ("iMCU" row)
* per call, ie, v_samp_factor rows for each component in the image.
* This amount of data is read from the source buffer and saved into the
* virtual arrays.
*
* We must also emit the data to the compressor. This is conveniently
* done by calling compress_output() after we've loaded the current strip
* of the virtual arrays.
*
* NB: input_buf contains a plane for each component in image. All components
* are loaded into the virtual arrays in this pass. However, it may be that
* only a subset of the components are emitted to the compressor during
* this first pass; be careful about looking at the scan-dependent variables
* (MCU dimensions, etc).
*/
METHODDEF(boolean)
compress_first_pass(j_compress_ptr cinfo, _JSAMPIMAGE input_buf)
{
my_diff_ptr diff = (my_diff_ptr)cinfo->coef;
JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
JDIMENSION samps_across;
int ci, samp_row, samp_rows;
_JSAMPARRAY buffer;
jpeg_component_info *compptr;
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
/* Align the virtual buffer for this component. */
buffer = (_JSAMPARRAY)(*cinfo->mem->access_virt_sarray)
((j_common_ptr)cinfo, diff->whole_image[ci],
diff->iMCU_row_num * compptr->v_samp_factor,
(JDIMENSION)compptr->v_samp_factor, TRUE);
/* Count non-dummy sample rows in this iMCU row. */
if (diff->iMCU_row_num < last_iMCU_row)
samp_rows = compptr->v_samp_factor;
else {
/* NB: can't use last_row_height here, since may not be set! */
samp_rows = (int)(compptr->height_in_blocks % compptr->v_samp_factor);
if (samp_rows == 0) samp_rows = compptr->v_samp_factor;
}
samps_across = compptr->width_in_blocks;
/* Perform point transform scaling and prediction/differencing for all
* non-dummy rows in this iMCU row. Each call on these functions
* processes a complete row of samples.
*/
for (samp_row = 0; samp_row < samp_rows; samp_row++) {
memcpy(buffer[samp_row], input_buf[ci][samp_row],
samps_across * sizeof(_JSAMPLE));
}
}
/* NB: compress_output will increment iMCU_row_num if successful.
* A suspension return will result in redoing all the work above next time.
*/
/* Emit data to the compressor, sharing code with subsequent passes */
return compress_output(cinfo, input_buf);
}
/*
* Process some data in subsequent passes of a multi-pass case.
* We process the equivalent of one fully interleaved MCU row ("iMCU" row)
* per call, ie, v_samp_factor rows for each component in the scan.
* The data is obtained from the virtual arrays and fed to the compressor.
* Returns TRUE if the iMCU row is completed, FALSE if suspended.
*
* NB: input_buf is ignored; it is likely to be a NULL pointer.
*/
METHODDEF(boolean)
compress_output(j_compress_ptr cinfo, _JSAMPIMAGE input_buf)
{
my_diff_ptr diff = (my_diff_ptr)cinfo->coef;
int ci, compi;
_JSAMPARRAY buffer[MAX_COMPS_IN_SCAN];
jpeg_component_info *compptr;
/* Align the virtual buffers for the components used in this scan.
* NB: during first pass, this is safe only because the buffers will
* already be aligned properly, so jmemmgr.c won't need to do any I/O.
*/
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
compi = compptr->component_index;
buffer[compi] = (_JSAMPARRAY)(*cinfo->mem->access_virt_sarray)
((j_common_ptr)cinfo, diff->whole_image[compi],
diff->iMCU_row_num * compptr->v_samp_factor,
(JDIMENSION)compptr->v_samp_factor, FALSE);
}
return compress_data(cinfo, buffer);
}
#endif /* FULL_SAMP_BUFFER_SUPPORTED */
/*
* Initialize difference buffer controller.
*/
GLOBAL(void)
_jinit_c_diff_controller(j_compress_ptr cinfo, boolean need_full_buffer)
{
my_diff_ptr diff;
int ci, row;
jpeg_component_info *compptr;
diff = (my_diff_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
sizeof(my_diff_controller));
cinfo->coef = (struct jpeg_c_coef_controller *)diff;
diff->pub.start_pass = start_pass_diff;
/* Create the prediction row buffers. */
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
diff->cur_row[ci] = *(_JSAMPARRAY)(*cinfo->mem->alloc_sarray)
((j_common_ptr)cinfo, JPOOL_IMAGE,
(JDIMENSION)jround_up((long)compptr->width_in_blocks,
(long)compptr->h_samp_factor),
(JDIMENSION)1);
diff->prev_row[ci] = *(_JSAMPARRAY)(*cinfo->mem->alloc_sarray)
((j_common_ptr)cinfo, JPOOL_IMAGE,
(JDIMENSION)jround_up((long)compptr->width_in_blocks,
(long)compptr->h_samp_factor),
(JDIMENSION)1);
}
/* Create the difference buffer. */
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
diff->diff_buf[ci] =
ALLOC_DARRAY(JPOOL_IMAGE,
(JDIMENSION)jround_up((long)compptr->width_in_blocks,
(long)compptr->h_samp_factor),
(JDIMENSION)compptr->v_samp_factor);
/* Prefill difference rows with zeros. We do this because only actual
* data is placed in the buffers during prediction/differencing, leaving
* any dummy differences at the right edge as zeros, which will encode
* to the smallest amount of data.
*/
for (row = 0; row < compptr->v_samp_factor; row++)
memset(diff->diff_buf[ci][row], 0,
jround_up((long)compptr->width_in_blocks,
(long)compptr->h_samp_factor) * sizeof(JDIFF));
}
/* Create the sample buffer. */
if (need_full_buffer) {
#ifdef FULL_SAMP_BUFFER_SUPPORTED
/* Allocate a full-image virtual array for each component, */
/* padded to a multiple of samp_factor differences in each direction. */
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
diff->whole_image[ci] = (*cinfo->mem->request_virt_sarray)
((j_common_ptr)cinfo, JPOOL_IMAGE, FALSE,
(JDIMENSION)jround_up((long)compptr->width_in_blocks,
(long)compptr->h_samp_factor),
(JDIMENSION)jround_up((long)compptr->height_in_blocks,
(long)compptr->v_samp_factor),
(JDIMENSION)compptr->v_samp_factor);
}
#else
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
#endif
} else
diff->whole_image[0] = NULL; /* flag for no virtual arrays */
}
#endif /* C_LOSSLESS_SUPPORTED */
+258 -333
View File
@@ -3,14 +3,9 @@
*
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-1997, Thomas G. Lane.
* Lossless JPEG Modifications:
* Copyright (C) 1999, Ken Murchison.
* libjpeg-turbo Modifications:
* Copyright (C) 2009-2011, 2014-2016, 2018-2024, D. R. Commander.
* Copyright (C) 2009-2011, 2014-2016, 2018-2019, D. R. Commander.
* Copyright (C) 2015, Matthieu Darbois.
* Copyright (C) 2018, Matthias Räncker.
* Copyright (C) 2020, Arm Limited.
* Copyright (C) 2022, Felix Hanau.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -29,13 +24,39 @@
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#ifdef WITH_SIMD
#include "jsimd.h"
#else
#include "jchuff.h" /* Declarations shared with jc*huff.c */
#endif
#include "jconfigint.h"
#include <limits.h>
#include "jpeg_nbits.h"
/*
* NOTE: If USE_CLZ_INTRINSIC is defined, then clz/bsr instructions will be
* used for bit counting rather than the lookup table. This will reduce the
* memory footprint by 64k, which is important for some mobile applications
* that create many isolated instances of libjpeg-turbo (web browsers, for
* instance.) This may improve performance on some mobile platforms as well.
* This feature is enabled by default only on ARM processors, because some x86
* chips have a slow implementation of bsr, and the use of clz/bsr cannot be
* shown to have a significant performance impact even on the x86 chips that
* have a fast implementation of it. When building for ARMv6, you can
* explicitly disable the use of clz/bsr by adding -mthumb to the compiler
* flags (this defines __thumb__).
*/
/* NOTE: Both GCC and Clang define __GNUC__ */
#if defined(__GNUC__) && (defined(__arm__) || defined(__aarch64__))
#if !defined(__thumb__) || defined(__thumb2__)
#define USE_CLZ_INTRINSIC
#endif
#endif
#ifdef USE_CLZ_INTRINSIC
#define JPEG_NBITS_NONZERO(x) (32 - __builtin_clz(x))
#define JPEG_NBITS(x) (x ? JPEG_NBITS_NONZERO(x) : 0)
#else
#include "jpeg_nbits_table.h"
#define JPEG_NBITS(x) (jpeg_nbits_table[x])
#define JPEG_NBITS_NONZERO(x) JPEG_NBITS(x)
#endif
/* Expanded entropy encoder object for Huffman encoding.
@@ -44,45 +65,32 @@
* but must not be updated permanently until we complete the MCU.
*/
#if defined(__x86_64__) && defined(__ILP32__)
typedef unsigned long long bit_buf_type;
#else
typedef size_t bit_buf_type;
#endif
/* NOTE: The more optimal Huffman encoding algorithm is only used by the
* intrinsics implementation of the Arm Neon SIMD extensions, which is why we
* retain the old Huffman encoder behavior when using the GAS implementation.
*/
#if defined(WITH_SIMD) && !(defined(__arm__) || defined(__aarch64__) || \
defined(_M_ARM) || defined(_M_ARM64))
typedef unsigned long long simd_bit_buf_type;
#else
typedef bit_buf_type simd_bit_buf_type;
#endif
#if (defined(SIZEOF_SIZE_T) && SIZEOF_SIZE_T == 8) || defined(_WIN64) || \
(defined(__x86_64__) && defined(__ILP32__))
#define BIT_BUF_SIZE 64
#elif (defined(SIZEOF_SIZE_T) && SIZEOF_SIZE_T == 4) || defined(_WIN32)
#define BIT_BUF_SIZE 32
#else
#error Cannot determine word size
#endif
#define SIMD_BIT_BUF_SIZE (sizeof(simd_bit_buf_type) * 8)
typedef struct {
union {
bit_buf_type c;
#ifdef WITH_SIMD
simd_bit_buf_type simd;
#endif
} put_buffer; /* current bit accumulation buffer */
int free_bits; /* # of bits available in it */
/* (Neon GAS: # of bits now in it) */
size_t put_buffer; /* current bit-accumulation buffer */
int put_bits; /* # of bits now in it */
int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
} savable_state;
/* This macro is to work around compilers with missing or broken
* structure assignment. You'll need to fix this code if you have
* such a compiler and you change MAX_COMPS_IN_SCAN.
*/
#ifndef NO_STRUCT_ASSIGN
#define ASSIGN_STATE(dest, src) ((dest) = (src))
#else
#if MAX_COMPS_IN_SCAN == 4
#define ASSIGN_STATE(dest, src) \
((dest).put_buffer = (src).put_buffer, \
(dest).put_bits = (src).put_bits, \
(dest).last_dc_val[0] = (src).last_dc_val[0], \
(dest).last_dc_val[1] = (src).last_dc_val[1], \
(dest).last_dc_val[2] = (src).last_dc_val[2], \
(dest).last_dc_val[3] = (src).last_dc_val[3])
#endif
#endif
typedef struct {
struct jpeg_entropy_encoder pub; /* public fields */
@@ -101,9 +109,7 @@ typedef struct {
long *ac_count_ptrs[NUM_HUFF_TBLS];
#endif
#ifdef WITH_SIMD
int simd;
#endif
} huff_entropy_encoder;
typedef huff_entropy_encoder *huff_entropy_ptr;
@@ -117,9 +123,6 @@ typedef struct {
size_t free_in_buffer; /* # of byte spaces remaining in buffer */
savable_state cur; /* Current bit buffer & DC state */
j_compress_ptr cinfo; /* dump_buffer needs access to this */
#ifdef WITH_SIMD
int simd;
#endif
} working_state;
@@ -158,9 +161,7 @@ start_pass_huff(j_compress_ptr cinfo, boolean gather_statistics)
entropy->pub.finish_pass = finish_pass_huff;
}
#ifdef WITH_SIMD
entropy->simd = jsimd_can_huff_encode_one_block();
#endif
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
@@ -180,12 +181,12 @@ start_pass_huff(j_compress_ptr cinfo, boolean gather_statistics)
entropy->dc_count_ptrs[dctbl] = (long *)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
257 * sizeof(long));
memset(entropy->dc_count_ptrs[dctbl], 0, 257 * sizeof(long));
MEMZERO(entropy->dc_count_ptrs[dctbl], 257 * sizeof(long));
if (entropy->ac_count_ptrs[actbl] == NULL)
entropy->ac_count_ptrs[actbl] = (long *)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
257 * sizeof(long));
memset(entropy->ac_count_ptrs[actbl], 0, 257 * sizeof(long));
MEMZERO(entropy->ac_count_ptrs[actbl], 257 * sizeof(long));
#endif
} else {
/* Compute derived values for Huffman tables */
@@ -200,20 +201,8 @@ start_pass_huff(j_compress_ptr cinfo, boolean gather_statistics)
}
/* Initialize bit buffer to empty */
#ifdef WITH_SIMD
if (entropy->simd) {
entropy->saved.put_buffer.simd = 0;
#if defined(__aarch64__) && !defined(NEON_INTRINSICS)
entropy->saved.free_bits = 0;
#else
entropy->saved.free_bits = SIMD_BIT_BUF_SIZE;
#endif
} else
#endif
{
entropy->saved.put_buffer.c = 0;
entropy->saved.free_bits = BIT_BUF_SIZE;
}
entropy->saved.put_buffer = 0;
entropy->saved.put_bits = 0;
/* Initialize restart stuff */
entropy->restarts_to_go = cinfo->restart_interval;
@@ -225,7 +214,7 @@ start_pass_huff(j_compress_ptr cinfo, boolean gather_statistics)
* Compute the derived values for a Huffman table.
* This routine also performs some validation checks on the table.
*
* Note this is also used by jcphuff.c and jclhuff.c.
* Note this is also used by jcphuff.c.
*/
GLOBAL(void)
@@ -298,15 +287,14 @@ jpeg_make_c_derived_tbl(j_compress_ptr cinfo, boolean isDC, int tblno,
* this lets us detect duplicate VAL entries here, and later
* allows emit_bits to detect any attempt to emit such symbols.
*/
memset(dtbl->ehufco, 0, sizeof(dtbl->ehufco));
memset(dtbl->ehufsi, 0, sizeof(dtbl->ehufsi));
MEMZERO(dtbl->ehufsi, sizeof(dtbl->ehufsi));
/* This is also a convenient place to check for out-of-range and duplicated
* VAL entries. We allow 0..255 for AC symbols but only 0..15 for DC in
* lossy mode and 0..16 for DC in lossless mode. (We could constrain them
* further based on data depth and mode, but this seems enough.)
/* This is also a convenient place to check for out-of-range
* and duplicated VAL entries. We allow 0..255 for AC symbols
* but only 0..15 for DC. (We could constrain them further
* based on data depth and mode, but this seems enough.)
*/
maxsymbol = isDC ? (cinfo->master->lossless ? 16 : 15) : 255;
maxsymbol = isDC ? 15 : 255;
for (p = 0; p < lastp; p++) {
i = htbl->huffval[p];
@@ -346,94 +334,94 @@ dump_buffer(working_state *state)
/* Outputting bits to the file */
/* Output byte b and, speculatively, an additional 0 byte. 0xFF must be
* encoded as 0xFF 0x00, so the output buffer pointer is advanced by 2 if the
* byte is 0xFF. Otherwise, the output buffer pointer is advanced by 1, and
* the speculative 0 byte will be overwritten by the next byte.
/* These macros perform the same task as the emit_bits() function in the
* original libjpeg code. In addition to reducing overhead by explicitly
* inlining the code, additional performance is achieved by taking into
* account the size of the bit buffer and waiting until it is almost full
* before emptying it. This mostly benefits 64-bit platforms, since 6
* bytes can be stored in a 64-bit bit buffer before it has to be emptied.
*/
#define EMIT_BYTE(b) { \
buffer[0] = (JOCTET)(b); \
buffer[1] = 0; \
buffer -= -2 + ((JOCTET)(b) < 0xFF); \
#define EMIT_BYTE() { \
JOCTET c; \
put_bits -= 8; \
c = (JOCTET)GETJOCTET(put_buffer >> put_bits); \
*buffer++ = c; \
if (c == 0xFF) /* need to stuff a zero byte? */ \
*buffer++ = 0; \
}
/* Output the entire bit buffer. If there are no 0xFF bytes in it, then write
* directly to the output buffer. Otherwise, use the EMIT_BYTE() macro to
* encode 0xFF as 0xFF 0x00.
*/
#if BIT_BUF_SIZE == 64
#define FLUSH() { \
if (put_buffer & 0x8080808080808080 & ~(put_buffer + 0x0101010101010101)) { \
EMIT_BYTE(put_buffer >> 56) \
EMIT_BYTE(put_buffer >> 48) \
EMIT_BYTE(put_buffer >> 40) \
EMIT_BYTE(put_buffer >> 32) \
EMIT_BYTE(put_buffer >> 24) \
EMIT_BYTE(put_buffer >> 16) \
EMIT_BYTE(put_buffer >> 8) \
EMIT_BYTE(put_buffer ) \
} else { \
buffer[0] = (JOCTET)(put_buffer >> 56); \
buffer[1] = (JOCTET)(put_buffer >> 48); \
buffer[2] = (JOCTET)(put_buffer >> 40); \
buffer[3] = (JOCTET)(put_buffer >> 32); \
buffer[4] = (JOCTET)(put_buffer >> 24); \
buffer[5] = (JOCTET)(put_buffer >> 16); \
buffer[6] = (JOCTET)(put_buffer >> 8); \
buffer[7] = (JOCTET)(put_buffer); \
buffer += 8; \
} \
#define PUT_BITS(code, size) { \
put_bits += size; \
put_buffer = (put_buffer << size) | code; \
}
#else
#if SIZEOF_SIZE_T != 8 && !defined(_WIN64)
#define FLUSH() { \
if (put_buffer & 0x80808080 & ~(put_buffer + 0x01010101)) { \
EMIT_BYTE(put_buffer >> 24) \
EMIT_BYTE(put_buffer >> 16) \
EMIT_BYTE(put_buffer >> 8) \
EMIT_BYTE(put_buffer ) \
} else { \
buffer[0] = (JOCTET)(put_buffer >> 24); \
buffer[1] = (JOCTET)(put_buffer >> 16); \
buffer[2] = (JOCTET)(put_buffer >> 8); \
buffer[3] = (JOCTET)(put_buffer); \
buffer += 4; \
#define CHECKBUF15() { \
if (put_bits > 15) { \
EMIT_BYTE() \
EMIT_BYTE() \
} \
}
#endif
/* Fill the bit buffer to capacity with the leading bits from code, then output
* the bit buffer and put the remaining bits from code into the bit buffer.
*/
#define PUT_AND_FLUSH(code, size) { \
put_buffer = (put_buffer << (size + free_bits)) | (code >> -free_bits); \
FLUSH() \
free_bits += BIT_BUF_SIZE; \
put_buffer = code; \
#define CHECKBUF31() { \
if (put_bits > 31) { \
EMIT_BYTE() \
EMIT_BYTE() \
EMIT_BYTE() \
EMIT_BYTE() \
} \
}
/* Insert code into the bit buffer and output the bit buffer if needed.
* NOTE: We can't flush with free_bits == 0, since the left shift in
* PUT_AND_FLUSH() would have undefined behavior.
*/
#define PUT_BITS(code, size) { \
free_bits -= size; \
if (free_bits < 0) \
PUT_AND_FLUSH(code, size) \
else \
put_buffer = (put_buffer << size) | code; \
#define CHECKBUF47() { \
if (put_bits > 47) { \
EMIT_BYTE() \
EMIT_BYTE() \
EMIT_BYTE() \
EMIT_BYTE() \
EMIT_BYTE() \
EMIT_BYTE() \
} \
}
#define PUT_CODE(code, size) { \
temp &= (((JLONG)1) << nbits) - 1; \
temp |= code << nbits; \
nbits += size; \
PUT_BITS(temp, nbits) \
#if !defined(_WIN32) && !defined(SIZEOF_SIZE_T)
#error Cannot determine word size
#endif
#if SIZEOF_SIZE_T == 8 || defined(_WIN64)
#define EMIT_BITS(code, size) { \
CHECKBUF47() \
PUT_BITS(code, size) \
}
#define EMIT_CODE(code, size) { \
temp2 &= (((JLONG)1) << nbits) - 1; \
CHECKBUF31() \
PUT_BITS(code, size) \
PUT_BITS(temp2, nbits) \
}
#else
#define EMIT_BITS(code, size) { \
PUT_BITS(code, size) \
CHECKBUF15() \
}
#define EMIT_CODE(code, size) { \
temp2 &= (((JLONG)1) << nbits) - 1; \
PUT_BITS(code, size) \
CHECKBUF15() \
PUT_BITS(temp2, nbits) \
CHECKBUF15() \
}
#endif
/* Although it is exceedingly rare, it is possible for a Huffman-encoded
* coefficient block to be larger than the 128-byte unencoded block. For each
@@ -456,12 +444,11 @@ dump_buffer(working_state *state)
#define STORE_BUFFER() { \
if (localbuf) { \
size_t bytes, bytestocopy; \
bytes = buffer - _buffer; \
buffer = _buffer; \
while (bytes > 0) { \
bytestocopy = MIN(bytes, state->free_in_buffer); \
memcpy(state->next_output_byte, buffer, bytestocopy); \
MEMCOPY(state->next_output_byte, buffer, bytestocopy); \
state->next_output_byte += bytestocopy; \
buffer += bytestocopy; \
state->free_in_buffer -= bytestocopy; \
@@ -479,60 +466,26 @@ dump_buffer(working_state *state)
LOCAL(boolean)
flush_bits(working_state *state)
{
JOCTET _buffer[BUFSIZE], *buffer, temp;
simd_bit_buf_type put_buffer; int put_bits;
int localbuf = 0;
#ifdef WITH_SIMD
if (state->simd) {
#if defined(__aarch64__) && !defined(NEON_INTRINSICS)
put_bits = state->cur.free_bits;
#else
put_bits = SIMD_BIT_BUF_SIZE - state->cur.free_bits;
#endif
put_buffer = state->cur.put_buffer.simd;
} else
#endif
{
put_bits = BIT_BUF_SIZE - state->cur.free_bits;
put_buffer = state->cur.put_buffer.c;
}
JOCTET _buffer[BUFSIZE], *buffer;
size_t put_buffer; int put_bits;
size_t bytes, bytestocopy; int localbuf = 0;
put_buffer = state->cur.put_buffer;
put_bits = state->cur.put_bits;
LOAD_BUFFER()
while (put_bits >= 8) {
put_bits -= 8;
temp = (JOCTET)(put_buffer >> put_bits);
EMIT_BYTE(temp)
}
if (put_bits) {
/* fill partial byte with ones */
temp = (JOCTET)((put_buffer << (8 - put_bits)) | (0xFF >> put_bits));
EMIT_BYTE(temp)
}
/* fill any partial byte with ones */
PUT_BITS(0x7F, 7)
while (put_bits >= 8) EMIT_BYTE()
#ifdef WITH_SIMD
if (state->simd) { /* and reset bit buffer to empty */
state->cur.put_buffer.simd = 0;
#if defined(__aarch64__) && !defined(NEON_INTRINSICS)
state->cur.free_bits = 0;
#else
state->cur.free_bits = SIMD_BIT_BUF_SIZE;
#endif
} else
#endif
{
state->cur.put_buffer.c = 0;
state->cur.free_bits = BIT_BUF_SIZE;
}
state->cur.put_buffer = 0; /* and reset bit-buffer to empty */
state->cur.put_bits = 0;
STORE_BUFFER()
return TRUE;
}
#ifdef WITH_SIMD
/* Encode a single block's worth of coefficients */
LOCAL(boolean)
@@ -540,7 +493,7 @@ encode_one_block_simd(working_state *state, JCOEFPTR block, int last_dc_val,
c_derived_tbl *dctbl, c_derived_tbl *actbl)
{
JOCTET _buffer[BUFSIZE], *buffer;
int localbuf = 0;
size_t bytes, bytestocopy; int localbuf = 0;
LOAD_BUFFER()
@@ -552,53 +505,57 @@ encode_one_block_simd(working_state *state, JCOEFPTR block, int last_dc_val,
return TRUE;
}
#endif
LOCAL(boolean)
encode_one_block(working_state *state, JCOEFPTR block, int last_dc_val,
c_derived_tbl *dctbl, c_derived_tbl *actbl)
{
int temp, nbits, free_bits;
bit_buf_type put_buffer;
int temp, temp2, temp3;
int nbits;
int r, code, size;
JOCTET _buffer[BUFSIZE], *buffer;
int localbuf = 0;
int max_coef_bits = state->cinfo->data_precision + 2;
size_t put_buffer; int put_bits;
int code_0xf0 = actbl->ehufco[0xf0], size_0xf0 = actbl->ehufsi[0xf0];
size_t bytes, bytestocopy; int localbuf = 0;
free_bits = state->cur.free_bits;
put_buffer = state->cur.put_buffer.c;
put_buffer = state->cur.put_buffer;
put_bits = state->cur.put_bits;
LOAD_BUFFER()
/* Encode the DC coefficient difference per section F.1.2.1 */
temp = block[0] - last_dc_val;
temp = temp2 = block[0] - last_dc_val;
/* This is a well-known technique for obtaining the absolute value without a
* branch. It is derived from an assembly language technique presented in
* "How to Optimize for the Pentium Processors", Copyright (c) 1996, 1997 by
* Agner Fog. This code assumes we are on a two's complement machine.
* Agner Fog.
*/
nbits = temp >> (CHAR_BIT * sizeof(int) - 1);
temp += nbits;
nbits ^= temp;
temp3 = temp >> (CHAR_BIT * sizeof(int) - 1);
temp ^= temp3;
temp -= temp3;
/* For a negative input, want temp2 = bitwise complement of abs(input) */
/* This code assumes we are on a two's complement machine */
temp2 += temp3;
/* Find the number of bits needed for the magnitude of the coefficient */
nbits = JPEG_NBITS(nbits);
/* Check for out-of-range coefficient values.
* Since we're encoding a difference, the range limit is twice as much.
*/
if (nbits > max_coef_bits + 1)
ERREXIT(state->cinfo, JERR_BAD_DCT_COEF);
nbits = JPEG_NBITS(temp);
/* Emit the Huffman-coded symbol for the number of bits.
* Emit that number of bits of the value, if positive,
* or the complement of its magnitude, if negative.
*/
PUT_CODE(dctbl->ehufco[nbits], dctbl->ehufsi[nbits])
/* Emit the Huffman-coded symbol for the number of bits */
code = dctbl->ehufco[nbits];
size = dctbl->ehufsi[nbits];
EMIT_BITS(code, size)
/* Mask off any extra bits in code */
temp2 &= (((JLONG)1) << nbits) - 1;
/* Emit that number of bits of the value, if positive, */
/* or the complement of its magnitude, if negative. */
EMIT_BITS(temp2, nbits)
/* Encode the AC coefficients per section F.1.2.2 */
{
int r = 0; /* r = run length of zeros */
r = 0; /* r = run length of zeros */
/* Manually unroll the k loop to eliminate the counter variable. This
* improves performance greatly on systems with a limited number of
@@ -606,49 +563,51 @@ encode_one_block(working_state *state, JCOEFPTR block, int last_dc_val,
*/
#define kloop(jpeg_natural_order_of_k) { \
if ((temp = block[jpeg_natural_order_of_k]) == 0) { \
r += 16; \
r++; \
} else { \
temp2 = temp; \
/* Branch-less absolute value, bitwise complement, etc., same as above */ \
nbits = temp >> (CHAR_BIT * sizeof(int) - 1); \
temp += nbits; \
nbits ^= temp; \
nbits = JPEG_NBITS_NONZERO(nbits); \
/* Check for out-of-range coefficient values */ \
if (nbits > max_coef_bits) \
ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); \
temp3 = temp >> (CHAR_BIT * sizeof(int) - 1); \
temp ^= temp3; \
temp -= temp3; \
temp2 += temp3; \
nbits = JPEG_NBITS_NONZERO(temp); \
/* if run length > 15, must emit special run-length-16 codes (0xF0) */ \
while (r >= 16 * 16) { \
r -= 16 * 16; \
PUT_BITS(actbl->ehufco[0xf0], actbl->ehufsi[0xf0]) \
while (r > 15) { \
EMIT_BITS(code_0xf0, size_0xf0) \
r -= 16; \
} \
/* Emit Huffman symbol for run length / number of bits */ \
r += nbits; \
PUT_CODE(actbl->ehufco[r], actbl->ehufsi[r]) \
temp3 = (r << 4) + nbits; \
code = actbl->ehufco[temp3]; \
size = actbl->ehufsi[temp3]; \
EMIT_CODE(code, size) \
r = 0; \
} \
}
/* One iteration for each value in jpeg_natural_order[] */
kloop(1); kloop(8); kloop(16); kloop(9); kloop(2); kloop(3);
kloop(10); kloop(17); kloop(24); kloop(32); kloop(25); kloop(18);
kloop(11); kloop(4); kloop(5); kloop(12); kloop(19); kloop(26);
kloop(33); kloop(40); kloop(48); kloop(41); kloop(34); kloop(27);
kloop(20); kloop(13); kloop(6); kloop(7); kloop(14); kloop(21);
kloop(28); kloop(35); kloop(42); kloop(49); kloop(56); kloop(57);
kloop(50); kloop(43); kloop(36); kloop(29); kloop(22); kloop(15);
kloop(23); kloop(30); kloop(37); kloop(44); kloop(51); kloop(58);
kloop(59); kloop(52); kloop(45); kloop(38); kloop(31); kloop(39);
kloop(46); kloop(53); kloop(60); kloop(61); kloop(54); kloop(47);
kloop(55); kloop(62); kloop(63);
/* One iteration for each value in jpeg_natural_order[] */
kloop(1); kloop(8); kloop(16); kloop(9); kloop(2); kloop(3);
kloop(10); kloop(17); kloop(24); kloop(32); kloop(25); kloop(18);
kloop(11); kloop(4); kloop(5); kloop(12); kloop(19); kloop(26);
kloop(33); kloop(40); kloop(48); kloop(41); kloop(34); kloop(27);
kloop(20); kloop(13); kloop(6); kloop(7); kloop(14); kloop(21);
kloop(28); kloop(35); kloop(42); kloop(49); kloop(56); kloop(57);
kloop(50); kloop(43); kloop(36); kloop(29); kloop(22); kloop(15);
kloop(23); kloop(30); kloop(37); kloop(44); kloop(51); kloop(58);
kloop(59); kloop(52); kloop(45); kloop(38); kloop(31); kloop(39);
kloop(46); kloop(53); kloop(60); kloop(61); kloop(54); kloop(47);
kloop(55); kloop(62); kloop(63);
/* If the last coef(s) were zero, emit an end-of-block code */
if (r > 0) {
PUT_BITS(actbl->ehufco[0], actbl->ehufsi[0])
}
/* If the last coef(s) were zero, emit an end-of-block code */
if (r > 0) {
code = actbl->ehufco[0];
size = actbl->ehufsi[0];
EMIT_BITS(code, size)
}
state->cur.put_buffer.c = put_buffer;
state->cur.free_bits = free_bits;
state->cur.put_buffer = put_buffer;
state->cur.put_bits = put_bits;
STORE_BUFFER()
return TRUE;
@@ -695,11 +654,8 @@ encode_mcu_huff(j_compress_ptr cinfo, JBLOCKROW *MCU_data)
/* Load up working state */
state.next_output_byte = cinfo->dest->next_output_byte;
state.free_in_buffer = cinfo->dest->free_in_buffer;
state.cur = entropy->saved;
ASSIGN_STATE(state.cur, entropy->saved);
state.cinfo = cinfo;
#ifdef WITH_SIMD
state.simd = entropy->simd;
#endif
/* Emit restart marker if needed */
if (cinfo->restart_interval) {
@@ -709,7 +665,6 @@ encode_mcu_huff(j_compress_ptr cinfo, JBLOCKROW *MCU_data)
}
/* Encode the MCU data blocks */
#ifdef WITH_SIMD
if (entropy->simd) {
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
ci = cinfo->MCU_membership[blkn];
@@ -722,9 +677,7 @@ encode_mcu_huff(j_compress_ptr cinfo, JBLOCKROW *MCU_data)
/* Update last_dc_val */
state.cur.last_dc_val[ci] = MCU_data[blkn][0][0];
}
} else
#endif
{
} else {
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
ci = cinfo->MCU_membership[blkn];
compptr = cinfo->cur_comp_info[ci];
@@ -741,7 +694,7 @@ encode_mcu_huff(j_compress_ptr cinfo, JBLOCKROW *MCU_data)
/* Completed MCU, so update state */
cinfo->dest->next_output_byte = state.next_output_byte;
cinfo->dest->free_in_buffer = state.free_in_buffer;
entropy->saved = state.cur;
ASSIGN_STATE(entropy->saved, state.cur);
/* Update restart-interval state too */
if (cinfo->restart_interval) {
@@ -770,11 +723,8 @@ finish_pass_huff(j_compress_ptr cinfo)
/* Load up working state ... flush_bits needs it */
state.next_output_byte = cinfo->dest->next_output_byte;
state.free_in_buffer = cinfo->dest->free_in_buffer;
state.cur = entropy->saved;
ASSIGN_STATE(state.cur, entropy->saved);
state.cinfo = cinfo;
#ifdef WITH_SIMD
state.simd = entropy->simd;
#endif
/* Flush out the last data */
if (!flush_bits(&state))
@@ -783,7 +733,7 @@ finish_pass_huff(j_compress_ptr cinfo)
/* Update state */
cinfo->dest->next_output_byte = state.next_output_byte;
cinfo->dest->free_in_buffer = state.free_in_buffer;
entropy->saved = state.cur;
ASSIGN_STATE(entropy->saved, state.cur);
}
@@ -810,7 +760,6 @@ htest_one_block(j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val,
register int temp;
register int nbits;
register int k, r;
int max_coef_bits = cinfo->data_precision + 2;
/* Encode the DC coefficient difference per section F.1.2.1 */
@@ -827,7 +776,7 @@ htest_one_block(j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val,
/* Check for out-of-range coefficient values.
* Since we're encoding a difference, the range limit is twice as much.
*/
if (nbits > max_coef_bits + 1)
if (nbits > MAX_COEF_BITS + 1)
ERREXIT(cinfo, JERR_BAD_DCT_COEF);
/* Count the Huffman symbol for the number of bits */
@@ -856,7 +805,7 @@ htest_one_block(j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val,
while ((temp >>= 1))
nbits++;
/* Check for out-of-range coefficient values */
if (nbits > max_coef_bits)
if (nbits > MAX_COEF_BITS)
ERREXIT(cinfo, JERR_BAD_DCT_COEF);
/* Count Huffman symbol for run length / number of bits */
@@ -911,7 +860,7 @@ encode_mcu_gather(j_compress_ptr cinfo, JBLOCKROW *MCU_data)
/*
* Generate the best Huffman code table for the given counts, fill htbl.
* Note this is also used by jcphuff.c and jclhuff.c.
* Note this is also used by jcphuff.c.
*
* The JPEG standard requires that no symbol be assigned a codeword of all
* one bits (so that padding bits added at the end of a compressed segment
@@ -943,20 +892,16 @@ jpeg_gen_optimal_table(j_compress_ptr cinfo, JHUFF_TBL *htbl, long freq[])
{
#define MAX_CLEN 32 /* assumed maximum initial code length */
UINT8 bits[MAX_CLEN + 1]; /* bits[k] = # of symbols with code length k */
int bit_pos[MAX_CLEN + 1]; /* # of symbols with smaller code length */
int codesize[257]; /* codesize[k] = code length of symbol k */
int nz_index[257]; /* index of nonzero symbol in the original freq
array */
int others[257]; /* next symbol in current branch of tree */
int c1, c2;
int p, i, j;
int num_nz_symbols;
long v, v2;
long v;
/* This algorithm is explained in section K.2 of the JPEG standard */
memset(bits, 0, sizeof(bits));
memset(codesize, 0, sizeof(codesize));
MEMZERO(bits, sizeof(bits));
MEMZERO(codesize, sizeof(codesize));
for (i = 0; i < 257; i++)
others[i] = -1; /* init links to empty */
@@ -966,41 +911,28 @@ jpeg_gen_optimal_table(j_compress_ptr cinfo, JHUFF_TBL *htbl, long freq[])
* will be placed last in the largest codeword category.
*/
/* Group nonzero frequencies together so we can more easily find the
* smallest.
*/
num_nz_symbols = 0;
for (i = 0; i < 257; i++) {
if (freq[i]) {
nz_index[num_nz_symbols] = i;
freq[num_nz_symbols] = freq[i];
num_nz_symbols++;
}
}
/* Huffman's basic algorithm to assign optimal code lengths to symbols */
for (;;) {
/* Find the two smallest nonzero frequencies; set c1, c2 = their symbols */
/* In case of ties, take the larger symbol number. Since we have grouped
* the nonzero symbols together, checking for zero symbols is not
* necessary.
*/
/* Find the smallest nonzero frequency, set c1 = its symbol */
/* In case of ties, take the larger symbol number */
c1 = -1;
v = 1000000000L;
for (i = 0; i <= 256; i++) {
if (freq[i] && freq[i] <= v) {
v = freq[i];
c1 = i;
}
}
/* Find the next smallest nonzero frequency, set c2 = its symbol */
/* In case of ties, take the larger symbol number */
c2 = -1;
v = 1000000000L;
v2 = 1000000000L;
for (i = 0; i < num_nz_symbols; i++) {
if (freq[i] <= v2) {
if (freq[i] <= v) {
c2 = c1;
v2 = v;
v = freq[i];
c1 = i;
} else {
v2 = freq[i];
c2 = i;
}
for (i = 0; i <= 256; i++) {
if (freq[i] && freq[i] <= v && i != c1) {
v = freq[i];
c2 = i;
}
}
@@ -1010,10 +942,7 @@ jpeg_gen_optimal_table(j_compress_ptr cinfo, JHUFF_TBL *htbl, long freq[])
/* Else merge the two counts/trees */
freq[c1] += freq[c2];
/* Set the frequency to a very high value instead of zero, so we don't have
* to check for zero values.
*/
freq[c2] = 1000000001L;
freq[c2] = 0;
/* Increment the codesize of everything in c1's tree branch */
codesize[c1]++;
@@ -1033,24 +962,15 @@ jpeg_gen_optimal_table(j_compress_ptr cinfo, JHUFF_TBL *htbl, long freq[])
}
/* Now count the number of symbols of each code length */
for (i = 0; i < num_nz_symbols; i++) {
/* The JPEG standard seems to think that this can't happen, */
/* but I'm paranoid... */
if (codesize[i] > MAX_CLEN)
ERREXIT(cinfo, JERR_HUFF_CLEN_OVERFLOW);
for (i = 0; i <= 256; i++) {
if (codesize[i]) {
/* The JPEG standard seems to think that this can't happen, */
/* but I'm paranoid... */
if (codesize[i] > MAX_CLEN)
ERREXIT(cinfo, JERR_HUFF_CLEN_OVERFLOW);
bits[codesize[i]]++;
}
/* Count the number of symbols with a length smaller than i bits, so we can
* construct the symbol table more efficiently. Note that this includes the
* pseudo-symbol 256, but since it is the last symbol, it will not affect the
* table.
*/
p = 0;
for (i = 1; i <= MAX_CLEN; i++) {
bit_pos[i] = p;
p += bits[i];
bits[codesize[i]]++;
}
}
/* JPEG doesn't allow symbols with code lengths over 16 bits, so if the pure
@@ -1083,16 +1003,21 @@ jpeg_gen_optimal_table(j_compress_ptr cinfo, JHUFF_TBL *htbl, long freq[])
bits[i]--;
/* Return final symbol counts (only for lengths 0..16) */
memcpy(htbl->bits, bits, sizeof(htbl->bits));
MEMCOPY(htbl->bits, bits, sizeof(htbl->bits));
/* Return a list of the symbols sorted by code length */
/* It's not real clear to me why we don't need to consider the codelength
* changes made above, but Rec. ITU-T T.81 | ISO/IEC 10918-1 seems to think
* this works.
*/
for (i = 0; i < num_nz_symbols - 1; i++) {
htbl->huffval[bit_pos[codesize[i]]] = (UINT8)nz_index[i];
bit_pos[codesize[i]]++;
p = 0;
for (i = 1; i <= MAX_CLEN; i++) {
for (j = 0; j <= 255; j++) {
if (codesize[j] == i) {
htbl->huffval[p] = (UINT8)j;
p++;
}
}
}
/* Set sent_table FALSE so updated table will be written to JPEG file. */
@@ -1117,8 +1042,8 @@ finish_pass_gather(j_compress_ptr cinfo)
/* It's important not to apply jpeg_gen_optimal_table more than once
* per table, because it clobbers the input frequency counts!
*/
memset(did_dc, 0, sizeof(did_dc));
memset(did_ac, 0, sizeof(did_ac));
MEMZERO(did_dc, sizeof(did_dc));
MEMZERO(did_ac, sizeof(did_ac));
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
+7 -9
View File
@@ -3,8 +3,8 @@
*
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-1997, Thomas G. Lane.
* libjpeg-turbo Modifications:
* Copyright (C) 2022, D. R. Commander.
* It was modified by The libjpeg-turbo Project to include only code relevant
* to libjpeg-turbo.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -19,13 +19,11 @@
* Hence the magnitude should always fit in 10 or 14 bits respectively.
*/
/* The progressive Huffman encoder uses an unsigned 16-bit data type to store
* absolute values of coefficients, because it is possible to inject a
* coefficient value of -32768 into the encoder by attempting to transform a
* malformed 12-bit JPEG image, and the absolute value of -32768 would overflow
* a signed 16-bit integer.
*/
typedef unsigned short UJCOEF;
#if BITS_IN_JSAMPLE == 8
#define MAX_COEF_BITS 10
#else
#define MAX_COEF_BITS 14
#endif
/* Derived data constructed for each Huffman table */
+20 -92
View File
@@ -1,12 +1,8 @@
/*
* jcinit.c
*
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-1997, Thomas G. Lane.
* Lossless JPEG Modifications:
* Copyright (C) 1999, Ken Murchison.
* libjpeg-turbo Modifications:
* Copyright (C) 2020, 2022, D. R. Commander.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -23,7 +19,6 @@
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jpegapicomp.h"
/*
@@ -40,101 +35,34 @@ jinit_compress_master(j_compress_ptr cinfo)
/* Preprocessing */
if (!cinfo->raw_data_in) {
if (cinfo->data_precision == 16) {
#ifdef C_LOSSLESS_SUPPORTED
j16init_color_converter(cinfo);
j16init_downsampler(cinfo);
j16init_c_prep_controller(cinfo,
FALSE /* never need full buffer here */);
#else
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
#endif
} else if (cinfo->data_precision == 12) {
j12init_color_converter(cinfo);
j12init_downsampler(cinfo);
j12init_c_prep_controller(cinfo,
FALSE /* never need full buffer here */);
} else {
jinit_color_converter(cinfo);
jinit_downsampler(cinfo);
jinit_c_prep_controller(cinfo, FALSE /* never need full buffer here */);
}
jinit_color_converter(cinfo);
jinit_downsampler(cinfo);
jinit_c_prep_controller(cinfo, FALSE /* never need full buffer here */);
}
if (cinfo->master->lossless) {
#ifdef C_LOSSLESS_SUPPORTED
/* Prediction, sample differencing, and point transform */
if (cinfo->data_precision == 16)
j16init_lossless_compressor(cinfo);
else if (cinfo->data_precision == 12)
j12init_lossless_compressor(cinfo);
else
jinit_lossless_compressor(cinfo);
/* Entropy encoding: either Huffman or arithmetic coding. */
if (cinfo->arith_code) {
ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
} else {
jinit_lhuff_encoder(cinfo);
}
/* Need a full-image difference buffer in any multi-pass mode. */
if (cinfo->data_precision == 16)
j16init_c_diff_controller(cinfo, (boolean)(cinfo->num_scans > 1 ||
cinfo->optimize_coding));
else if (cinfo->data_precision == 12)
j12init_c_diff_controller(cinfo, (boolean)(cinfo->num_scans > 1 ||
cinfo->optimize_coding));
else
jinit_c_diff_controller(cinfo, (boolean)(cinfo->num_scans > 1 ||
cinfo->optimize_coding));
/* Forward DCT */
jinit_forward_dct(cinfo);
/* Entropy encoding: either Huffman or arithmetic coding. */
if (cinfo->arith_code) {
#ifdef C_ARITH_CODING_SUPPORTED
jinit_arith_encoder(cinfo);
#else
ERREXIT(cinfo, JERR_NOT_COMPILED);
ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
#endif
} else {
if (cinfo->data_precision == 16)
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
/* Forward DCT */
if (cinfo->data_precision == 12)
j12init_forward_dct(cinfo);
else
jinit_forward_dct(cinfo);
/* Entropy encoding: either Huffman or arithmetic coding. */
if (cinfo->arith_code) {
#ifdef C_ARITH_CODING_SUPPORTED
jinit_arith_encoder(cinfo);
#else
ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
#endif
} else {
if (cinfo->progressive_mode) {
if (cinfo->progressive_mode) {
#ifdef C_PROGRESSIVE_SUPPORTED
jinit_phuff_encoder(cinfo);
jinit_phuff_encoder(cinfo);
#else
ERREXIT(cinfo, JERR_NOT_COMPILED);
ERREXIT(cinfo, JERR_NOT_COMPILED);
#endif
} else
jinit_huff_encoder(cinfo);
}
/* Need a full-image coefficient buffer in any multi-pass mode. */
if (cinfo->data_precision == 12)
j12init_c_coef_controller(cinfo, (boolean)(cinfo->num_scans > 1 ||
cinfo->optimize_coding));
else
jinit_c_coef_controller(cinfo, (boolean)(cinfo->num_scans > 1 ||
cinfo->optimize_coding));
} else
jinit_huff_encoder(cinfo);
}
if (cinfo->data_precision == 16)
#ifdef C_LOSSLESS_SUPPORTED
j16init_c_main_controller(cinfo, FALSE /* never need full buffer here */);
#else
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
#endif
else if (cinfo->data_precision == 12)
j12init_c_main_controller(cinfo, FALSE /* never need full buffer here */);
else
jinit_c_main_controller(cinfo, FALSE /* never need full buffer here */);
/* Need a full-image coefficient buffer in any multi-pass mode. */
jinit_c_coef_controller(cinfo, (boolean)(cinfo->num_scans > 1 ||
cinfo->optimize_coding));
jinit_c_main_controller(cinfo, FALSE /* never need full buffer here */);
jinit_marker_writer(cinfo);
-587
View File
@@ -1,587 +0,0 @@
/*
* jclhuff.c
*
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-1997, Thomas G. Lane.
* Lossless JPEG Modifications:
* Copyright (C) 1999, Ken Murchison.
* libjpeg-turbo Modifications:
* Copyright (C) 2022, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
* This file contains Huffman entropy encoding routines for lossless JPEG.
*
* Much of the complexity here has to do with supporting output suspension.
* If the data destination module demands suspension, we want to be able to
* back up to the start of the current MCU. To do this, we copy state
* variables into local working storage, and update them back to the
* permanent JPEG objects only upon successful completion of an MCU.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jlossls.h" /* Private declarations for lossless codec */
#include "jchuff.h" /* Declarations shared with jc*huff.c */
#ifdef C_LOSSLESS_SUPPORTED
/* The legal range of a spatial difference is
* -32767 .. +32768.
* Hence the magnitude should always fit in 16 bits.
*/
#define MAX_DIFF_BITS 16
/* Expanded entropy encoder object for Huffman encoding in lossless mode.
*
* The savable_state subrecord contains fields that change within an MCU,
* but must not be updated permanently until we complete the MCU.
*/
typedef struct {
size_t put_buffer; /* current bit-accumulation buffer */
int put_bits; /* # of bits now in it */
} savable_state;
typedef struct {
int ci, yoffset, MCU_width;
} lhe_input_ptr_info;
typedef struct {
struct jpeg_entropy_encoder pub; /* public fields */
savable_state saved; /* Bit buffer at start of MCU */
/* These fields are NOT loaded into local working state. */
unsigned int restarts_to_go; /* MCUs left in this restart interval */
int next_restart_num; /* next restart number to write (0-7) */
/* Pointers to derived tables (these workspaces have image lifespan) */
c_derived_tbl *derived_tbls[NUM_HUFF_TBLS];
/* Pointers to derived tables to be used for each data unit within an MCU */
c_derived_tbl *cur_tbls[C_MAX_BLOCKS_IN_MCU];
#ifdef ENTROPY_OPT_SUPPORTED /* Statistics tables for optimization */
long *count_ptrs[NUM_HUFF_TBLS];
/* Pointers to stats tables to be used for each data unit within an MCU */
long *cur_counts[C_MAX_BLOCKS_IN_MCU];
#endif
/* Pointers to the proper input difference row for each group of data units
* within an MCU. For each component, there are Vi groups of Hi data units.
*/
JDIFFROW input_ptr[C_MAX_BLOCKS_IN_MCU];
/* Number of input pointers in use for the current MCU. This is the sum
* of all Vi in the MCU.
*/
int num_input_ptrs;
/* Information used for positioning the input pointers within the input
* difference rows.
*/
lhe_input_ptr_info input_ptr_info[C_MAX_BLOCKS_IN_MCU];
/* Index of the proper input pointer for each data unit within an MCU */
int input_ptr_index[C_MAX_BLOCKS_IN_MCU];
} lhuff_entropy_encoder;
typedef lhuff_entropy_encoder *lhuff_entropy_ptr;
/* Working state while writing an MCU.
* This struct contains all the fields that are needed by subroutines.
*/
typedef struct {
JOCTET *next_output_byte; /* => next byte to write in buffer */
size_t free_in_buffer; /* # of byte spaces remaining in buffer */
savable_state cur; /* Current bit buffer & DC state */
j_compress_ptr cinfo; /* dump_buffer needs access to this */
} working_state;
/* Forward declarations */
METHODDEF(JDIMENSION) encode_mcus_huff(j_compress_ptr cinfo,
JDIFFIMAGE diff_buf,
JDIMENSION MCU_row_num,
JDIMENSION MCU_col_num,
JDIMENSION nMCU);
METHODDEF(void) finish_pass_huff(j_compress_ptr cinfo);
#ifdef ENTROPY_OPT_SUPPORTED
METHODDEF(JDIMENSION) encode_mcus_gather(j_compress_ptr cinfo,
JDIFFIMAGE diff_buf,
JDIMENSION MCU_row_num,
JDIMENSION MCU_col_num,
JDIMENSION nMCU);
METHODDEF(void) finish_pass_gather(j_compress_ptr cinfo);
#endif
/*
* Initialize for a Huffman-compressed scan.
* If gather_statistics is TRUE, we do not output anything during the scan,
* just count the Huffman symbols used and generate Huffman code tables.
*/
METHODDEF(void)
start_pass_lhuff(j_compress_ptr cinfo, boolean gather_statistics)
{
lhuff_entropy_ptr entropy = (lhuff_entropy_ptr)cinfo->entropy;
int ci, dctbl, sampn, ptrn, yoffset, xoffset;
jpeg_component_info *compptr;
if (gather_statistics) {
#ifdef ENTROPY_OPT_SUPPORTED
entropy->pub.encode_mcus = encode_mcus_gather;
entropy->pub.finish_pass = finish_pass_gather;
#else
ERREXIT(cinfo, JERR_NOT_COMPILED);
#endif
} else {
entropy->pub.encode_mcus = encode_mcus_huff;
entropy->pub.finish_pass = finish_pass_huff;
}
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
dctbl = compptr->dc_tbl_no;
if (gather_statistics) {
#ifdef ENTROPY_OPT_SUPPORTED
/* Check for invalid table indexes */
/* (make_c_derived_tbl does this in the other path) */
if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS)
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl);
/* Allocate and zero the statistics tables */
/* Note that jpeg_gen_optimal_table expects 257 entries in each table! */
if (entropy->count_ptrs[dctbl] == NULL)
entropy->count_ptrs[dctbl] = (long *)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
257 * sizeof(long));
memset(entropy->count_ptrs[dctbl], 0, 257 * sizeof(long));
#endif
} else {
/* Compute derived values for Huffman tables */
/* We may do this more than once for a table, but it's not expensive */
jpeg_make_c_derived_tbl(cinfo, TRUE, dctbl,
&entropy->derived_tbls[dctbl]);
}
}
/* Precalculate encoding info for each sample in an MCU of this scan */
for (sampn = 0, ptrn = 0; sampn < cinfo->blocks_in_MCU;) {
compptr = cinfo->cur_comp_info[cinfo->MCU_membership[sampn]];
ci = compptr->component_index;
for (yoffset = 0; yoffset < compptr->MCU_height; yoffset++, ptrn++) {
/* Precalculate the setup info for each input pointer */
entropy->input_ptr_info[ptrn].ci = ci;
entropy->input_ptr_info[ptrn].yoffset = yoffset;
entropy->input_ptr_info[ptrn].MCU_width = compptr->MCU_width;
for (xoffset = 0; xoffset < compptr->MCU_width; xoffset++, sampn++) {
/* Precalculate the input pointer index for each sample */
entropy->input_ptr_index[sampn] = ptrn;
/* Precalculate which tables to use for each sample */
entropy->cur_tbls[sampn] = entropy->derived_tbls[compptr->dc_tbl_no];
entropy->cur_counts[sampn] = entropy->count_ptrs[compptr->dc_tbl_no];
}
}
}
entropy->num_input_ptrs = ptrn;
/* Initialize bit buffer to empty */
entropy->saved.put_buffer = 0;
entropy->saved.put_bits = 0;
/* Initialize restart stuff */
entropy->restarts_to_go = cinfo->restart_interval;
entropy->next_restart_num = 0;
}
/* Outputting bytes to the file */
/* Emit a byte, taking 'action' if must suspend. */
#define emit_byte(state, val, action) { \
*(state)->next_output_byte++ = (JOCTET)(val); \
if (--(state)->free_in_buffer == 0) \
if (!dump_buffer(state)) \
{ action; } \
}
LOCAL(boolean)
dump_buffer(working_state *state)
/* Empty the output buffer; return TRUE if successful, FALSE if must suspend */
{
struct jpeg_destination_mgr *dest = state->cinfo->dest;
if (!(*dest->empty_output_buffer) (state->cinfo))
return FALSE;
/* After a successful buffer dump, must reset buffer pointers */
state->next_output_byte = dest->next_output_byte;
state->free_in_buffer = dest->free_in_buffer;
return TRUE;
}
/* Outputting bits to the file */
/* Only the right 24 bits of put_buffer are used; the valid bits are
* left-justified in this part. At most 16 bits can be passed to emit_bits
* in one call, and we never retain more than 7 bits in put_buffer
* between calls, so 24 bits are sufficient.
*/
INLINE
LOCAL(boolean)
emit_bits(working_state *state, unsigned int code, int size)
/* Emit some bits; return TRUE if successful, FALSE if must suspend */
{
/* This routine is heavily used, so it's worth coding tightly. */
register size_t put_buffer = (size_t)code;
register int put_bits = state->cur.put_bits;
/* if size is 0, caller used an invalid Huffman table entry */
if (size == 0)
ERREXIT(state->cinfo, JERR_HUFF_MISSING_CODE);
put_buffer &= (((size_t)1) << size) - 1; /* mask off any extra bits in code */
put_bits += size; /* new number of bits in buffer */
put_buffer <<= 24 - put_bits; /* align incoming bits */
put_buffer |= state->cur.put_buffer; /* and merge with old buffer contents */
while (put_bits >= 8) {
int c = (int)((put_buffer >> 16) & 0xFF);
emit_byte(state, c, return FALSE);
if (c == 0xFF) { /* need to stuff a zero byte? */
emit_byte(state, 0, return FALSE);
}
put_buffer <<= 8;
put_bits -= 8;
}
state->cur.put_buffer = put_buffer; /* update state variables */
state->cur.put_bits = put_bits;
return TRUE;
}
LOCAL(boolean)
flush_bits(working_state *state)
{
if (!emit_bits(state, 0x7F, 7)) /* fill any partial byte with ones */
return FALSE;
state->cur.put_buffer = 0; /* and reset bit-buffer to empty */
state->cur.put_bits = 0;
return TRUE;
}
/*
* Emit a restart marker & resynchronize predictions.
*/
LOCAL(boolean)
emit_restart(working_state *state, int restart_num)
{
if (!flush_bits(state))
return FALSE;
emit_byte(state, 0xFF, return FALSE);
emit_byte(state, JPEG_RST0 + restart_num, return FALSE);
/* The restart counter is not updated until we successfully write the MCU. */
return TRUE;
}
/*
* Encode and output nMCU MCUs' worth of Huffman-compressed differences.
*/
METHODDEF(JDIMENSION)
encode_mcus_huff(j_compress_ptr cinfo, JDIFFIMAGE diff_buf,
JDIMENSION MCU_row_num, JDIMENSION MCU_col_num,
JDIMENSION nMCU)
{
lhuff_entropy_ptr entropy = (lhuff_entropy_ptr)cinfo->entropy;
working_state state;
int sampn, ci, yoffset, MCU_width, ptrn;
JDIMENSION mcu_num;
/* Load up working state */
state.next_output_byte = cinfo->dest->next_output_byte;
state.free_in_buffer = cinfo->dest->free_in_buffer;
state.cur = entropy->saved;
state.cinfo = cinfo;
/* Emit restart marker if needed */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0)
if (!emit_restart(&state, entropy->next_restart_num))
return 0;
}
/* Set input pointer locations based on MCU_col_num */
for (ptrn = 0; ptrn < entropy->num_input_ptrs; ptrn++) {
ci = entropy->input_ptr_info[ptrn].ci;
yoffset = entropy->input_ptr_info[ptrn].yoffset;
MCU_width = entropy->input_ptr_info[ptrn].MCU_width;
entropy->input_ptr[ptrn] =
diff_buf[ci][MCU_row_num + yoffset] + (MCU_col_num * MCU_width);
}
for (mcu_num = 0; mcu_num < nMCU; mcu_num++) {
/* Inner loop handles the samples in the MCU */
for (sampn = 0; sampn < cinfo->blocks_in_MCU; sampn++) {
register int temp, temp2;
register int nbits;
c_derived_tbl *dctbl = entropy->cur_tbls[sampn];
/* Encode the difference per section H.1.2.2 */
/* Input the sample difference */
temp = *entropy->input_ptr[entropy->input_ptr_index[sampn]]++;
if (temp & 0x8000) { /* instead of temp < 0 */
temp = (-temp) & 0x7FFF; /* absolute value, mod 2^16 */
if (temp == 0) /* special case: magnitude = 32768 */
temp2 = temp = 0x8000;
temp2 = ~temp; /* one's complement of magnitude */
} else {
temp &= 0x7FFF; /* abs value mod 2^16 */
temp2 = temp; /* magnitude */
}
/* Find the number of bits needed for the magnitude of the difference */
nbits = 0;
while (temp) {
nbits++;
temp >>= 1;
}
/* Check for out-of-range difference values.
*/
if (nbits > MAX_DIFF_BITS)
ERREXIT(cinfo, JERR_BAD_DCT_COEF);
/* Emit the Huffman-coded symbol for the number of bits */
if (!emit_bits(&state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits]))
return mcu_num;
/* Emit that number of bits of the value, if positive, */
/* or the complement of its magnitude, if negative. */
if (nbits && /* emit_bits rejects calls with size 0 */
nbits != 16) /* special case: no bits should be emitted */
if (!emit_bits(&state, (unsigned int)temp2, nbits))
return mcu_num;
}
/* Completed MCU, so update state */
cinfo->dest->next_output_byte = state.next_output_byte;
cinfo->dest->free_in_buffer = state.free_in_buffer;
entropy->saved = state.cur;
/* Update restart-interval state too */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0) {
entropy->restarts_to_go = cinfo->restart_interval;
entropy->next_restart_num++;
entropy->next_restart_num &= 7;
}
entropy->restarts_to_go--;
}
}
return nMCU;
}
/*
* Finish up at the end of a Huffman-compressed scan.
*/
METHODDEF(void)
finish_pass_huff(j_compress_ptr cinfo)
{
lhuff_entropy_ptr entropy = (lhuff_entropy_ptr)cinfo->entropy;
working_state state;
/* Load up working state ... flush_bits needs it */
state.next_output_byte = cinfo->dest->next_output_byte;
state.free_in_buffer = cinfo->dest->free_in_buffer;
state.cur = entropy->saved;
state.cinfo = cinfo;
/* Flush out the last data */
if (!flush_bits(&state))
ERREXIT(cinfo, JERR_CANT_SUSPEND);
/* Update state */
cinfo->dest->next_output_byte = state.next_output_byte;
cinfo->dest->free_in_buffer = state.free_in_buffer;
entropy->saved = state.cur;
}
/*
* Huffman coding optimization.
*
* We first scan the supplied data and count the number of uses of each symbol
* that is to be Huffman-coded. (This process MUST agree with the code above.)
* Then we build a Huffman coding tree for the observed counts.
* Symbols which are not needed at all for the particular image are not
* assigned any code, which saves space in the DHT marker as well as in
* the compressed data.
*/
#ifdef ENTROPY_OPT_SUPPORTED
/*
* Trial-encode nMCU MCUs' worth of Huffman-compressed differences.
* No data is actually output, so no suspension return is possible.
*/
METHODDEF(JDIMENSION)
encode_mcus_gather(j_compress_ptr cinfo, JDIFFIMAGE diff_buf,
JDIMENSION MCU_row_num, JDIMENSION MCU_col_num,
JDIMENSION nMCU)
{
lhuff_entropy_ptr entropy = (lhuff_entropy_ptr)cinfo->entropy;
int sampn, ci, yoffset, MCU_width, ptrn;
JDIMENSION mcu_num;
/* Take care of restart intervals if needed */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0) {
/* Update restart state */
entropy->restarts_to_go = cinfo->restart_interval;
}
entropy->restarts_to_go--;
}
/* Set input pointer locations based on MCU_col_num */
for (ptrn = 0; ptrn < entropy->num_input_ptrs; ptrn++) {
ci = entropy->input_ptr_info[ptrn].ci;
yoffset = entropy->input_ptr_info[ptrn].yoffset;
MCU_width = entropy->input_ptr_info[ptrn].MCU_width;
entropy->input_ptr[ptrn] =
diff_buf[ci][MCU_row_num + yoffset] + (MCU_col_num * MCU_width);
}
for (mcu_num = 0; mcu_num < nMCU; mcu_num++) {
/* Inner loop handles the samples in the MCU */
for (sampn = 0; sampn < cinfo->blocks_in_MCU; sampn++) {
register int temp;
register int nbits;
long *counts = entropy->cur_counts[sampn];
/* Encode the difference per section H.1.2.2 */
/* Input the sample difference */
temp = *entropy->input_ptr[entropy->input_ptr_index[sampn]]++;
if (temp & 0x8000) { /* instead of temp < 0 */
temp = (-temp) & 0x7FFF; /* absolute value, mod 2^16 */
if (temp == 0) /* special case: magnitude = 32768 */
temp = 0x8000;
} else
temp &= 0x7FFF; /* abs value mod 2^16 */
/* Find the number of bits needed for the magnitude of the difference */
nbits = 0;
while (temp) {
nbits++;
temp >>= 1;
}
/* Check for out-of-range difference values.
*/
if (nbits > MAX_DIFF_BITS)
ERREXIT(cinfo, JERR_BAD_DCT_COEF);
/* Count the Huffman symbol for the number of bits */
counts[nbits]++;
}
}
return nMCU;
}
/*
* Finish up a statistics-gathering pass and create the new Huffman tables.
*/
METHODDEF(void)
finish_pass_gather(j_compress_ptr cinfo)
{
lhuff_entropy_ptr entropy = (lhuff_entropy_ptr)cinfo->entropy;
int ci, dctbl;
jpeg_component_info *compptr;
JHUFF_TBL **htblptr;
boolean did_dc[NUM_HUFF_TBLS];
/* It's important not to apply jpeg_gen_optimal_table more than once
* per table, because it clobbers the input frequency counts!
*/
memset(did_dc, 0, sizeof(did_dc));
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
dctbl = compptr->dc_tbl_no;
if (!did_dc[dctbl]) {
htblptr = &cinfo->dc_huff_tbl_ptrs[dctbl];
if (*htblptr == NULL)
*htblptr = jpeg_alloc_huff_table((j_common_ptr)cinfo);
jpeg_gen_optimal_table(cinfo, *htblptr, entropy->count_ptrs[dctbl]);
did_dc[dctbl] = TRUE;
}
}
}
#endif /* ENTROPY_OPT_SUPPORTED */
/*
* Module initialization routine for Huffman entropy encoding.
*/
GLOBAL(void)
jinit_lhuff_encoder(j_compress_ptr cinfo)
{
lhuff_entropy_ptr entropy;
int i;
entropy = (lhuff_entropy_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
sizeof(lhuff_entropy_encoder));
cinfo->entropy = (struct jpeg_entropy_encoder *)entropy;
entropy->pub.start_pass = start_pass_lhuff;
/* Mark tables unallocated */
for (i = 0; i < NUM_HUFF_TBLS; i++) {
entropy->derived_tbls[i] = NULL;
#ifdef ENTROPY_OPT_SUPPORTED
entropy->count_ptrs[i] = NULL;
#endif
}
}
#endif /* C_LOSSLESS_SUPPORTED */
-319
View File
@@ -1,319 +0,0 @@
/*
* jclossls.c
*
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1998, Thomas G. Lane.
* Lossless JPEG Modifications:
* Copyright (C) 1999, Ken Murchison.
* libjpeg-turbo Modifications:
* Copyright (C) 2022, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
* This file contains prediction, sample differencing, and point transform
* routines for the lossless JPEG compressor.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jlossls.h"
#ifdef C_LOSSLESS_SUPPORTED
/************************** Sample differencing **************************/
/*
* In order to avoid a performance penalty for checking which predictor is
* being used and which row is being processed for each call of the
* undifferencer, and to promote optimization, we have separate differencing
* functions for each predictor selection value.
*
* We are able to avoid duplicating source code by implementing the predictors
* and differencers as macros. Each of the differencing functions is simply a
* wrapper around a DIFFERENCE macro with the appropriate PREDICTOR macro
* passed as an argument.
*/
/* Forward declarations */
LOCAL(void) reset_predictor(j_compress_ptr cinfo, int ci);
/* Predictor for the first column of the first row: 2^(P-Pt-1) */
#define INITIAL_PREDICTORx (1 << (cinfo->data_precision - cinfo->Al - 1))
/* Predictor for the first column of the remaining rows: Rb */
#define INITIAL_PREDICTOR2 prev_row[0]
/*
* 1-Dimensional differencer routine.
*
* This macro implements the 1-D horizontal predictor (1). INITIAL_PREDICTOR
* is used as the special case predictor for the first column, which must be
* either INITIAL_PREDICTOR2 or INITIAL_PREDICTORx. The remaining samples
* use PREDICTOR1.
*/
#define DIFFERENCE_1D(INITIAL_PREDICTOR) \
lossless_comp_ptr losslessc = (lossless_comp_ptr)cinfo->fdct; \
boolean restart = FALSE; \
int samp, Ra; \
\
samp = *input_buf++; \
*diff_buf++ = samp - INITIAL_PREDICTOR; \
\
while (--width) { \
Ra = samp; \
samp = *input_buf++; \
*diff_buf++ = samp - PREDICTOR1; \
} \
\
/* Account for restart interval (no-op if not using restarts) */ \
if (cinfo->restart_interval) { \
if (--(losslessc->restart_rows_to_go[ci]) == 0) { \
reset_predictor(cinfo, ci); \
restart = TRUE; \
} \
}
/*
* 2-Dimensional differencer routine.
*
* This macro implements the 2-D horizontal predictors (#2-7). PREDICTOR2 is
* used as the special case predictor for the first column. The remaining
* samples use PREDICTOR, which is a function of Ra, Rb, and Rc.
*
* Because prev_row and output_buf may point to the same storage area (in an
* interleaved image with Vi=1, for example), we must take care to buffer Rb/Rc
* before writing the current reconstructed sample value into output_buf.
*/
#define DIFFERENCE_2D(PREDICTOR) \
lossless_comp_ptr losslessc = (lossless_comp_ptr)cinfo->fdct; \
int samp, Ra, Rb, Rc; \
\
Rb = *prev_row++; \
samp = *input_buf++; \
*diff_buf++ = samp - PREDICTOR2; \
\
while (--width) { \
Rc = Rb; \
Rb = *prev_row++; \
Ra = samp; \
samp = *input_buf++; \
*diff_buf++ = samp - PREDICTOR; \
} \
\
/* Account for restart interval (no-op if not using restarts) */ \
if (cinfo->restart_interval) { \
if (--losslessc->restart_rows_to_go[ci] == 0) \
reset_predictor(cinfo, ci); \
}
/*
* Differencers for the second and subsequent rows in a scan or restart
* interval. The first sample in the row is differenced using the vertical
* predictor (2). The rest of the samples are differenced using the predictor
* specified in the scan header.
*/
METHODDEF(void)
jpeg_difference1(j_compress_ptr cinfo, int ci,
_JSAMPROW input_buf, _JSAMPROW prev_row,
JDIFFROW diff_buf, JDIMENSION width)
{
DIFFERENCE_1D(INITIAL_PREDICTOR2);
(void)(restart);
}
METHODDEF(void)
jpeg_difference2(j_compress_ptr cinfo, int ci,
_JSAMPROW input_buf, _JSAMPROW prev_row,
JDIFFROW diff_buf, JDIMENSION width)
{
DIFFERENCE_2D(PREDICTOR2);
(void)(Ra);
(void)(Rc);
}
METHODDEF(void)
jpeg_difference3(j_compress_ptr cinfo, int ci,
_JSAMPROW input_buf, _JSAMPROW prev_row,
JDIFFROW diff_buf, JDIMENSION width)
{
DIFFERENCE_2D(PREDICTOR3);
(void)(Ra);
}
METHODDEF(void)
jpeg_difference4(j_compress_ptr cinfo, int ci,
_JSAMPROW input_buf, _JSAMPROW prev_row,
JDIFFROW diff_buf, JDIMENSION width)
{
DIFFERENCE_2D(PREDICTOR4);
}
METHODDEF(void)
jpeg_difference5(j_compress_ptr cinfo, int ci,
_JSAMPROW input_buf, _JSAMPROW prev_row,
JDIFFROW diff_buf, JDIMENSION width)
{
DIFFERENCE_2D(PREDICTOR5);
}
METHODDEF(void)
jpeg_difference6(j_compress_ptr cinfo, int ci,
_JSAMPROW input_buf, _JSAMPROW prev_row,
JDIFFROW diff_buf, JDIMENSION width)
{
DIFFERENCE_2D(PREDICTOR6);
}
METHODDEF(void)
jpeg_difference7(j_compress_ptr cinfo, int ci,
_JSAMPROW input_buf, _JSAMPROW prev_row,
JDIFFROW diff_buf, JDIMENSION width)
{
DIFFERENCE_2D(PREDICTOR7);
(void)(Rc);
}
/*
* Differencer for the first row in a scan or restart interval. The first
* sample in the row is differenced using the special predictor constant
* x = 2 ^ (P-Pt-1). The rest of the samples are differenced using the
* 1-D horizontal predictor (1).
*/
METHODDEF(void)
jpeg_difference_first_row(j_compress_ptr cinfo, int ci,
_JSAMPROW input_buf, _JSAMPROW prev_row,
JDIFFROW diff_buf, JDIMENSION width)
{
DIFFERENCE_1D(INITIAL_PREDICTORx);
/*
* Now that we have differenced the first row, we want to use the
* differencer that corresponds to the predictor specified in the
* scan header.
*
* Note that we don't do this if we have just reset the predictor
* for a new restart interval.
*/
if (!restart) {
switch (cinfo->Ss) {
case 1:
losslessc->predict_difference[ci] = jpeg_difference1;
break;
case 2:
losslessc->predict_difference[ci] = jpeg_difference2;
break;
case 3:
losslessc->predict_difference[ci] = jpeg_difference3;
break;
case 4:
losslessc->predict_difference[ci] = jpeg_difference4;
break;
case 5:
losslessc->predict_difference[ci] = jpeg_difference5;
break;
case 6:
losslessc->predict_difference[ci] = jpeg_difference6;
break;
case 7:
losslessc->predict_difference[ci] = jpeg_difference7;
break;
}
}
}
/*
* Reset predictor at the start of a pass or restart interval.
*/
LOCAL(void)
reset_predictor(j_compress_ptr cinfo, int ci)
{
lossless_comp_ptr losslessc = (lossless_comp_ptr)cinfo->fdct;
/* Initialize restart counter */
losslessc->restart_rows_to_go[ci] =
cinfo->restart_interval / cinfo->MCUs_per_row;
/* Set difference function to first row function */
losslessc->predict_difference[ci] = jpeg_difference_first_row;
}
/********************** Sample downscaling by 2^Pt ***********************/
METHODDEF(void)
simple_downscale(j_compress_ptr cinfo,
_JSAMPROW input_buf, _JSAMPROW output_buf, JDIMENSION width)
{
do {
*output_buf++ = (_JSAMPLE)RIGHT_SHIFT(*input_buf++, cinfo->Al);
} while (--width);
}
METHODDEF(void)
noscale(j_compress_ptr cinfo,
_JSAMPROW input_buf, _JSAMPROW output_buf, JDIMENSION width)
{
memcpy(output_buf, input_buf, width * sizeof(_JSAMPLE));
}
/*
* Initialize for a processing pass.
*/
METHODDEF(void)
start_pass_lossless(j_compress_ptr cinfo)
{
lossless_comp_ptr losslessc = (lossless_comp_ptr)cinfo->fdct;
int ci;
/* Set scaler function based on Pt */
if (cinfo->Al)
losslessc->scaler_scale = simple_downscale;
else
losslessc->scaler_scale = noscale;
/* Check that the restart interval is an integer multiple of the number
* of MCUs in an MCU row.
*/
if (cinfo->restart_interval % cinfo->MCUs_per_row != 0)
ERREXIT2(cinfo, JERR_BAD_RESTART,
cinfo->restart_interval, cinfo->MCUs_per_row);
/* Set predictors for start of pass */
for (ci = 0; ci < cinfo->num_components; ci++)
reset_predictor(cinfo, ci);
}
/*
* Initialize the lossless compressor.
*/
GLOBAL(void)
_jinit_lossless_compressor(j_compress_ptr cinfo)
{
lossless_comp_ptr losslessc;
/* Create subobject in permanent pool */
losslessc = (lossless_comp_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_PERMANENT,
sizeof(jpeg_lossless_compressor));
cinfo->fdct = (struct jpeg_forward_dct *)losslessc;
losslessc->pub.start_pass = start_pass_lossless;
}
#endif /* C_LOSSLESS_SUPPORTED */
+17 -28
View File
@@ -3,10 +3,8 @@
*
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1994-1996, Thomas G. Lane.
* Lossless JPEG Modifications:
* Copyright (C) 1999, Ken Murchison.
* libjpeg-turbo Modifications:
* Copyright (C) 2022, D. R. Commander.
* It was modified by The libjpeg-turbo Project to include only code relevant
* to libjpeg-turbo.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -18,11 +16,8 @@
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jsamplecomp.h"
#if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED)
/* Private buffer controller object */
typedef struct {
@@ -37,7 +32,7 @@ typedef struct {
* (we allocate one for each component). In the full-image case, this
* points to the currently accessible strips of the virtual arrays.
*/
_JSAMPARRAY buffer[MAX_COMPONENTS];
JSAMPARRAY buffer[MAX_COMPONENTS];
} my_main_controller;
typedef my_main_controller *my_main_ptr;
@@ -45,7 +40,7 @@ typedef my_main_controller *my_main_ptr;
/* Forward declarations */
METHODDEF(void) process_data_simple_main(j_compress_ptr cinfo,
_JSAMPARRAY input_buf,
JSAMPARRAY input_buf,
JDIMENSION *in_row_ctr,
JDIMENSION in_rows_avail);
@@ -70,7 +65,7 @@ start_pass_main(j_compress_ptr cinfo, J_BUF_MODE pass_mode)
main_ptr->rowgroup_ctr = 0;
main_ptr->suspended = FALSE;
main_ptr->pass_mode = pass_mode; /* save mode for use by process_data */
main_ptr->pub._process_data = process_data_simple_main;
main_ptr->pub.process_data = process_data_simple_main;
}
@@ -81,28 +76,28 @@ start_pass_main(j_compress_ptr cinfo, J_BUF_MODE pass_mode)
*/
METHODDEF(void)
process_data_simple_main(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
process_data_simple_main(j_compress_ptr cinfo, JSAMPARRAY input_buf,
JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail)
{
my_main_ptr main_ptr = (my_main_ptr)cinfo->main;
JDIMENSION data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
while (main_ptr->cur_iMCU_row < cinfo->total_iMCU_rows) {
/* Read input data if we haven't filled the main buffer yet */
if (main_ptr->rowgroup_ctr < data_unit)
(*cinfo->prep->_pre_process_data) (cinfo, input_buf, in_row_ctr,
in_rows_avail, main_ptr->buffer,
&main_ptr->rowgroup_ctr, data_unit);
if (main_ptr->rowgroup_ctr < DCTSIZE)
(*cinfo->prep->pre_process_data) (cinfo, input_buf, in_row_ctr,
in_rows_avail, main_ptr->buffer,
&main_ptr->rowgroup_ctr,
(JDIMENSION)DCTSIZE);
/* If we don't have a full iMCU row buffered, return to application for
* more data. Note that preprocessor will always pad to fill the iMCU row
* at the bottom of the image.
*/
if (main_ptr->rowgroup_ctr != data_unit)
if (main_ptr->rowgroup_ctr != DCTSIZE)
return;
/* Send the completed row to the compressor */
if (!(*cinfo->coef->_compress_data) (cinfo, main_ptr->buffer)) {
if (!(*cinfo->coef->compress_data) (cinfo, main_ptr->buffer)) {
/* If compressor did not consume the whole row, then we must need to
* suspend processing and return to the application. In this situation
* we pretend we didn't yet consume the last input row; otherwise, if
@@ -133,15 +128,11 @@ process_data_simple_main(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
*/
GLOBAL(void)
_jinit_c_main_controller(j_compress_ptr cinfo, boolean need_full_buffer)
jinit_c_main_controller(j_compress_ptr cinfo, boolean need_full_buffer)
{
my_main_ptr main_ptr;
int ci;
jpeg_component_info *compptr;
int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
if (cinfo->data_precision != BITS_IN_JSAMPLE)
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
main_ptr = (my_main_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
@@ -162,12 +153,10 @@ _jinit_c_main_controller(j_compress_ptr cinfo, boolean need_full_buffer)
/* Allocate a strip buffer for each component */
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
main_ptr->buffer[ci] = (_JSAMPARRAY)(*cinfo->mem->alloc_sarray)
main_ptr->buffer[ci] = (*cinfo->mem->alloc_sarray)
((j_common_ptr)cinfo, JPOOL_IMAGE,
compptr->width_in_blocks * data_unit,
(JDIMENSION)(compptr->v_samp_factor * data_unit));
compptr->width_in_blocks * DCTSIZE,
(JDIMENSION)(compptr->v_samp_factor * DCTSIZE));
}
}
}
#endif /* BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) */
+15 -21
View File
@@ -4,10 +4,8 @@
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2003-2010 by Guido Vollbeding.
* Lossless JPEG Modifications:
* Copyright (C) 1999, Ken Murchison.
* libjpeg-turbo Modifications:
* Copyright (C) 2010, 2022, D. R. Commander.
* Copyright (C) 2010, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -17,7 +15,7 @@
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jpegapicomp.h"
#include "jpegcomp.h"
typedef enum { /* JPEG marker codes */
@@ -499,26 +497,25 @@ write_file_header(j_compress_ptr cinfo)
METHODDEF(void)
write_frame_header(j_compress_ptr cinfo)
{
int ci, prec = 0;
int ci, prec;
boolean is_baseline;
jpeg_component_info *compptr;
if (!cinfo->master->lossless) {
/* Emit DQT for each quantization table.
* Note that emit_dqt() suppresses any duplicate tables.
*/
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
prec += emit_dqt(cinfo, compptr->quant_tbl_no);
}
/* now prec is nonzero iff there are any 16-bit quant tables. */
/* Emit DQT for each quantization table.
* Note that emit_dqt() suppresses any duplicate tables.
*/
prec = 0;
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
prec += emit_dqt(cinfo, compptr->quant_tbl_no);
}
/* now prec is nonzero iff there are any 16-bit quant tables. */
/* Check for a non-baseline specification.
* Note we assume that Huffman table numbers won't be changed later.
*/
if (cinfo->arith_code || cinfo->progressive_mode ||
cinfo->master->lossless || cinfo->data_precision != 8) {
cinfo->data_precision != 8) {
is_baseline = FALSE;
} else {
is_baseline = TRUE;
@@ -543,8 +540,6 @@ write_frame_header(j_compress_ptr cinfo)
} else {
if (cinfo->progressive_mode)
emit_sof(cinfo, M_SOF2); /* SOF code for progressive Huffman */
else if (cinfo->master->lossless)
emit_sof(cinfo, M_SOF3); /* SOF code for lossless Huffman */
else if (is_baseline)
emit_sof(cinfo, M_SOF0); /* SOF code for baseline implementation */
else
@@ -579,11 +574,10 @@ write_scan_header(j_compress_ptr cinfo)
for (i = 0; i < cinfo->comps_in_scan; i++) {
compptr = cinfo->cur_comp_info[i];
/* DC needs no table for refinement scan */
if ((cinfo->Ss == 0 && cinfo->Ah == 0) || cinfo->master->lossless)
if (cinfo->Ss == 0 && cinfo->Ah == 0)
emit_dht(cinfo, compptr->dc_tbl_no, FALSE);
/* AC needs no table when not present, and lossless mode uses only DC
tables. */
if (cinfo->Se && !cinfo->master->lossless)
/* AC needs no table when not present */
if (cinfo->Se)
emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
}
}
+82 -232
View File
@@ -4,10 +4,8 @@
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2003-2010 by Guido Vollbeding.
* Lossless JPEG Modifications:
* Copyright (C) 1999, Ken Murchison.
* libjpeg-turbo Modifications:
* Copyright (C) 2010, 2016, 2018, 2022-2024, D. R. Commander.
* Copyright (C) 2010, 2016, 2018, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -20,8 +18,40 @@
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jpegapicomp.h"
#include "jcmaster.h"
#include "jpegcomp.h"
#include "jconfigint.h"
/* Private state */
typedef enum {
main_pass, /* input data, also do first output step */
huff_opt_pass, /* Huffman code optimization pass */
output_pass /* data output pass */
} c_pass_type;
typedef struct {
struct jpeg_comp_master pub; /* public fields */
c_pass_type pass_type; /* the type of the current pass */
int pass_number; /* # of passes completed */
int total_passes; /* total # of passes needed */
int scan_number; /* current index in scan_info[] */
/*
* This is here so we can add libjpeg-turbo version/build information to the
* global string table without introducing a new global symbol. Adding this
* information to the global string table allows one to examine a binary
* object and determine which version of libjpeg-turbo it was built from or
* linked against.
*/
const char *jpeg_version;
} my_comp_master;
typedef my_comp_master *my_master_ptr;
/*
@@ -39,124 +69,15 @@ GLOBAL(void)
jpeg_calc_jpeg_dimensions(j_compress_ptr cinfo)
/* Do computations that are needed before master selection phase */
{
int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
/* Hardwire it to "no scaling" */
cinfo->jpeg_width = cinfo->image_width;
cinfo->jpeg_height = cinfo->image_height;
cinfo->min_DCT_h_scaled_size = data_unit;
cinfo->min_DCT_v_scaled_size = data_unit;
cinfo->min_DCT_h_scaled_size = DCTSIZE;
cinfo->min_DCT_v_scaled_size = DCTSIZE;
}
#endif
LOCAL(boolean)
using_std_huff_tables(j_compress_ptr cinfo)
{
int i;
static const UINT8 bits_dc_luminance[17] = {
/* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
};
static const UINT8 val_dc_luminance[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
};
static const UINT8 bits_dc_chrominance[17] = {
/* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0
};
static const UINT8 val_dc_chrominance[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
};
static const UINT8 bits_ac_luminance[17] = {
/* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
};
static const UINT8 val_ac_luminance[] = {
0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
0xf9, 0xfa
};
static const UINT8 bits_ac_chrominance[17] = {
/* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77
};
static const UINT8 val_ac_chrominance[] = {
0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
0xf9, 0xfa
};
if (cinfo->dc_huff_tbl_ptrs[0] == NULL ||
cinfo->ac_huff_tbl_ptrs[0] == NULL ||
cinfo->dc_huff_tbl_ptrs[1] == NULL ||
cinfo->ac_huff_tbl_ptrs[1] == NULL)
return FALSE;
for (i = 2; i < NUM_HUFF_TBLS; i++) {
if (cinfo->dc_huff_tbl_ptrs[i] != NULL ||
cinfo->ac_huff_tbl_ptrs[i] != NULL)
return FALSE;
}
if (memcmp(cinfo->dc_huff_tbl_ptrs[0]->bits, bits_dc_luminance,
sizeof(bits_dc_luminance)) ||
memcmp(cinfo->dc_huff_tbl_ptrs[0]->huffval, val_dc_luminance,
sizeof(val_dc_luminance)) ||
memcmp(cinfo->ac_huff_tbl_ptrs[0]->bits, bits_ac_luminance,
sizeof(bits_ac_luminance)) ||
memcmp(cinfo->ac_huff_tbl_ptrs[0]->huffval, val_ac_luminance,
sizeof(val_ac_luminance)) ||
memcmp(cinfo->dc_huff_tbl_ptrs[1]->bits, bits_dc_chrominance,
sizeof(bits_dc_chrominance)) ||
memcmp(cinfo->dc_huff_tbl_ptrs[1]->huffval, val_dc_chrominance,
sizeof(val_dc_chrominance)) ||
memcmp(cinfo->ac_huff_tbl_ptrs[1]->bits, bits_ac_chrominance,
sizeof(bits_ac_chrominance)) ||
memcmp(cinfo->ac_huff_tbl_ptrs[1]->huffval, val_ac_chrominance,
sizeof(val_ac_chrominance)))
return FALSE;
return TRUE;
}
LOCAL(void)
initial_setup(j_compress_ptr cinfo, boolean transcode_only)
/* Do computations that are needed before master selection phase */
@@ -165,7 +86,6 @@ initial_setup(j_compress_ptr cinfo, boolean transcode_only)
jpeg_component_info *compptr;
long samplesperrow;
JDIMENSION jd_samplesperrow;
int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
#if JPEG_LIB_VERSION >= 70
#if JPEG_LIB_VERSION >= 80
@@ -190,12 +110,8 @@ initial_setup(j_compress_ptr cinfo, boolean transcode_only)
if ((long)jd_samplesperrow != samplesperrow)
ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
#ifdef C_LOSSLESS_SUPPORTED
if (cinfo->data_precision != 8 && cinfo->data_precision != 12 &&
cinfo->data_precision != 16)
#else
if (cinfo->data_precision != 8 && cinfo->data_precision != 12)
#endif
/* For now, precision must match compiled-in value... */
if (cinfo->data_precision != BITS_IN_JSAMPLE)
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
/* Check that number of components won't exceed internal array sizes */
@@ -226,17 +142,17 @@ initial_setup(j_compress_ptr cinfo, boolean transcode_only)
compptr->component_index = ci;
/* For compression, we never do DCT scaling. */
#if JPEG_LIB_VERSION >= 70
compptr->DCT_h_scaled_size = compptr->DCT_v_scaled_size = data_unit;
compptr->DCT_h_scaled_size = compptr->DCT_v_scaled_size = DCTSIZE;
#else
compptr->DCT_scaled_size = data_unit;
compptr->DCT_scaled_size = DCTSIZE;
#endif
/* Size in data units */
/* Size in DCT blocks */
compptr->width_in_blocks = (JDIMENSION)
jdiv_round_up((long)cinfo->_jpeg_width * (long)compptr->h_samp_factor,
(long)(cinfo->max_h_samp_factor * data_unit));
(long)(cinfo->max_h_samp_factor * DCTSIZE));
compptr->height_in_blocks = (JDIMENSION)
jdiv_round_up((long)cinfo->_jpeg_height * (long)compptr->v_samp_factor,
(long)(cinfo->max_v_samp_factor * data_unit));
(long)(cinfo->max_v_samp_factor * DCTSIZE));
/* Size in samples */
compptr->downsampled_width = (JDIMENSION)
jdiv_round_up((long)cinfo->_jpeg_width * (long)compptr->h_samp_factor,
@@ -249,19 +165,15 @@ initial_setup(j_compress_ptr cinfo, boolean transcode_only)
}
/* Compute number of fully interleaved MCU rows (number of times that
* main controller will call coefficient or difference controller).
* main controller will call coefficient controller).
*/
cinfo->total_iMCU_rows = (JDIMENSION)
jdiv_round_up((long)cinfo->_jpeg_height,
(long)(cinfo->max_v_samp_factor * data_unit));
(long)(cinfo->max_v_samp_factor * DCTSIZE));
}
#if defined(C_MULTISCAN_FILES_SUPPORTED) || defined(C_LOSSLESS_SUPPORTED)
#define NEED_SCAN_SCRIPT
#endif
#ifdef NEED_SCAN_SCRIPT
#ifdef C_MULTISCAN_FILES_SUPPORTED
LOCAL(void)
validate_script(j_compress_ptr cinfo)
@@ -282,29 +194,13 @@ validate_script(j_compress_ptr cinfo)
if (cinfo->num_scans <= 0)
ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, 0);
#ifndef C_MULTISCAN_FILES_SUPPORTED
if (cinfo->num_scans > 1)
ERREXIT(cinfo, JERR_NOT_COMPILED);
#endif
scanptr = cinfo->scan_info;
if (scanptr->Ss != 0 && scanptr->Se == 0) {
#ifdef C_LOSSLESS_SUPPORTED
cinfo->master->lossless = TRUE;
cinfo->progressive_mode = FALSE;
for (ci = 0; ci < cinfo->num_components; ci++)
component_sent[ci] = FALSE;
#else
ERREXIT(cinfo, JERR_NOT_COMPILED);
#endif
}
/* For sequential JPEG, all scans must have Ss=0, Se=DCTSIZE2-1;
* for progressive JPEG, no scan can have this.
*/
else if (scanptr->Ss != 0 || scanptr->Se != DCTSIZE2 - 1) {
scanptr = cinfo->scan_info;
if (scanptr->Ss != 0 || scanptr->Se != DCTSIZE2 - 1) {
#ifdef C_PROGRESSIVE_SUPPORTED
cinfo->progressive_mode = TRUE;
cinfo->master->lossless = FALSE;
last_bitpos_ptr = &last_bitpos[0][0];
for (ci = 0; ci < cinfo->num_components; ci++)
for (coefi = 0; coefi < DCTSIZE2; coefi++)
@@ -313,7 +209,7 @@ validate_script(j_compress_ptr cinfo)
ERREXIT(cinfo, JERR_NOT_COMPILED);
#endif
} else {
cinfo->progressive_mode = cinfo->master->lossless = FALSE;
cinfo->progressive_mode = FALSE;
for (ci = 0; ci < cinfo->num_components; ci++)
component_sent[ci] = FALSE;
}
@@ -345,10 +241,13 @@ validate_script(j_compress_ptr cinfo)
* out-of-range reconstructed DC values during the first DC scan,
* which might cause problems for some decoders.
*/
int max_Ah_Al = cinfo->data_precision == 12 ? 13 : 10;
#if BITS_IN_JSAMPLE == 8
#define MAX_AH_AL 10
#else
#define MAX_AH_AL 13
#endif
if (Ss < 0 || Ss >= DCTSIZE2 || Se < Ss || Se >= DCTSIZE2 ||
Ah < 0 || Ah > max_Ah_Al || Al < 0 || Al > max_Ah_Al)
Ah < 0 || Ah > MAX_AH_AL || Al < 0 || Al > MAX_AH_AL)
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
if (Ss == 0) {
if (Se != 0) /* DC and AC together not OK */
@@ -376,25 +275,9 @@ validate_script(j_compress_ptr cinfo)
}
#endif
} else {
#ifdef C_LOSSLESS_SUPPORTED
if (cinfo->master->lossless) {
/* The JPEG spec simply gives the range 0..15 for Al (Pt), but that
* seems wrong: the upper bound ought to depend on data precision.
* Perhaps they really meant 0..N-1 for N-bit precision, which is what
* we allow here. Values greater than or equal to the data precision
* will result in a blank image.
*/
if (Ss < 1 || Ss > 7 || /* predictor selection value */
Se != 0 || Ah != 0 ||
Al < 0 || Al >= cinfo->data_precision) /* point transform */
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
} else
#endif
{
/* For sequential JPEG, all progression parameters must be these: */
if (Ss != 0 || Se != DCTSIZE2 - 1 || Ah != 0 || Al != 0)
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
}
/* For sequential JPEG, all progression parameters must be these: */
if (Ss != 0 || Se != DCTSIZE2 - 1 || Ah != 0 || Al != 0)
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
/* Make sure components are not sent twice */
for (ci = 0; ci < ncomps; ci++) {
thisi = scanptr->component_index[ci];
@@ -426,7 +309,7 @@ validate_script(j_compress_ptr cinfo)
}
}
#endif /* NEED_SCAN_SCRIPT */
#endif /* C_MULTISCAN_FILES_SUPPORTED */
LOCAL(void)
@@ -435,7 +318,7 @@ select_scan_parameters(j_compress_ptr cinfo)
{
int ci;
#ifdef NEED_SCAN_SCRIPT
#ifdef C_MULTISCAN_FILES_SUPPORTED
if (cinfo->scan_info != NULL) {
/* Prepare for current scan --- the script is already validated */
my_master_ptr master = (my_master_ptr)cinfo->master;
@@ -461,12 +344,10 @@ select_scan_parameters(j_compress_ptr cinfo)
for (ci = 0; ci < cinfo->num_components; ci++) {
cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci];
}
if (!cinfo->master->lossless) {
cinfo->Ss = 0;
cinfo->Se = DCTSIZE2 - 1;
cinfo->Ah = 0;
cinfo->Al = 0;
}
cinfo->Ss = 0;
cinfo->Se = DCTSIZE2 - 1;
cinfo->Ah = 0;
cinfo->Al = 0;
}
}
@@ -478,7 +359,6 @@ per_scan_setup(j_compress_ptr cinfo)
{
int ci, mcublks, tmp;
jpeg_component_info *compptr;
int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
if (cinfo->comps_in_scan == 1) {
@@ -493,7 +373,7 @@ per_scan_setup(j_compress_ptr cinfo)
compptr->MCU_width = 1;
compptr->MCU_height = 1;
compptr->MCU_blocks = 1;
compptr->MCU_sample_width = data_unit;
compptr->MCU_sample_width = DCTSIZE;
compptr->last_col_width = 1;
/* For noninterleaved scans, it is convenient to define last_row_height
* as the number of block rows present in the last iMCU row.
@@ -516,10 +396,10 @@ per_scan_setup(j_compress_ptr cinfo)
/* Overall image size in MCUs */
cinfo->MCUs_per_row = (JDIMENSION)
jdiv_round_up((long)cinfo->_jpeg_width,
(long)(cinfo->max_h_samp_factor * data_unit));
(long)(cinfo->max_h_samp_factor * DCTSIZE));
cinfo->MCU_rows_in_scan = (JDIMENSION)
jdiv_round_up((long)cinfo->_jpeg_height,
(long)(cinfo->max_v_samp_factor * data_unit));
(long)(cinfo->max_v_samp_factor * DCTSIZE));
cinfo->blocks_in_MCU = 0;
@@ -529,7 +409,7 @@ per_scan_setup(j_compress_ptr cinfo)
compptr->MCU_width = compptr->h_samp_factor;
compptr->MCU_height = compptr->v_samp_factor;
compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
compptr->MCU_sample_width = compptr->MCU_width * data_unit;
compptr->MCU_sample_width = compptr->MCU_width * DCTSIZE;
/* Figure number of non-dummy blocks in last MCU column & row */
tmp = (int)(compptr->width_in_blocks % compptr->MCU_width);
if (tmp == 0) tmp = compptr->MCU_width;
@@ -601,8 +481,7 @@ prepare_for_pass(j_compress_ptr cinfo)
/* Do Huffman optimization for a scan after the first one. */
select_scan_parameters(cinfo);
per_scan_setup(cinfo);
if (cinfo->Ss != 0 || cinfo->Ah == 0 || cinfo->arith_code ||
cinfo->master->lossless) {
if (cinfo->Ss != 0 || cinfo->Ah == 0 || cinfo->arith_code) {
(*cinfo->entropy->start_pass) (cinfo, TRUE);
(*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST);
master->pub.call_pass_startup = FALSE;
@@ -614,7 +493,7 @@ prepare_for_pass(j_compress_ptr cinfo)
master->pass_type = output_pass;
master->pass_number++;
#endif
FALLTHROUGH /*FALLTHROUGH*/
/*FALLTHROUGH*/
case output_pass:
/* Do a data-output pass. */
/* We need not repeat per-scan setup if prior optimization pass did it. */
@@ -711,17 +590,22 @@ finish_pass_master(j_compress_ptr cinfo)
GLOBAL(void)
jinit_c_master_control(j_compress_ptr cinfo, boolean transcode_only)
{
my_master_ptr master = (my_master_ptr)cinfo->master;
boolean empty_huff_tables = TRUE;
int i;
my_master_ptr master;
master = (my_master_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
sizeof(my_comp_master));
cinfo->master = (struct jpeg_comp_master *)master;
master->pub.prepare_for_pass = prepare_for_pass;
master->pub.pass_startup = pass_startup;
master->pub.finish_pass = finish_pass_master;
master->pub.is_last_pass = FALSE;
/* Validate parameters, determine derived values */
initial_setup(cinfo, transcode_only);
if (cinfo->scan_info != NULL) {
#ifdef NEED_SCAN_SCRIPT
#ifdef C_MULTISCAN_FILES_SUPPORTED
validate_script(cinfo);
#else
ERREXIT(cinfo, JERR_NOT_COMPILED);
@@ -731,42 +615,8 @@ jinit_c_master_control(j_compress_ptr cinfo, boolean transcode_only)
cinfo->num_scans = 1;
}
/* Disable smoothing and subsampling in lossless mode, since those are lossy
* algorithms. Set the JPEG colorspace to the input colorspace. Disable raw
* (downsampled) data input, because it isn't particularly useful without
* subsampling and has not been tested in lossless mode.
*/
if (cinfo->master->lossless) {
int ci;
jpeg_component_info *compptr;
cinfo->raw_data_in = FALSE;
cinfo->smoothing_factor = 0;
jpeg_default_colorspace(cinfo);
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++)
compptr->h_samp_factor = compptr->v_samp_factor = 1;
}
/* Validate parameters, determine derived values */
initial_setup(cinfo, transcode_only);
if (cinfo->master->lossless || /* TEMPORARY HACK ??? */
(cinfo->progressive_mode && !cinfo->arith_code))
cinfo->optimize_coding = TRUE; /* assume default tables no good for
progressive mode or lossless mode */
for (i = 0; i < NUM_HUFF_TBLS; i++) {
if (cinfo->dc_huff_tbl_ptrs[i] != NULL ||
cinfo->ac_huff_tbl_ptrs[i] != NULL) {
empty_huff_tables = FALSE;
break;
}
}
if (cinfo->data_precision == 12 && !cinfo->arith_code &&
!cinfo->optimize_coding &&
(empty_huff_tables || using_std_huff_tables(cinfo)))
cinfo->optimize_coding = TRUE; /* assume default tables no good for 12-bit
data precision */
if (cinfo->progressive_mode && !cinfo->arith_code) /* TEMPORARY HACK ??? */
cinfo->optimize_coding = TRUE; /* assume default tables no good for progressive mode */
/* Initialize my private state */
if (transcode_only) {

Some files were not shown because too many files have changed in this diff Show More