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

Compare commits

...

400 Commits

Author SHA1 Message Date
Alexander Alekhin 591708903b release: OpenCV 3.4.15 2021-07-04 21:10:13 +00:00
Alexander Alekhin f9d62fba7a Merge pull request #20350 from alalek:issue_20285 2021-07-04 21:07:02 +00:00
Alexander Alekhin 9d039c206b Merge pull request #20354 from alalek:issue_20353 2021-07-04 18:41:34 +00:00
Alexander Alekhin 4c3f9b2ef4 cmake: update Halide detection 2021-07-04 13:20:52 +03:00
Alexander Alekhin 0e523618a1 cmake: exclude -pthread from Emscripten default build 2021-07-03 11:13:28 +00:00
Alexander Alekhin 3b26105f68 Merge pull request #20346 from alalek:backport_20026 2021-07-03 00:27:55 +00:00
Alexander Alekhin 0f2f966a91 Merge pull request #20345 from mitruska:update_ngraph_normalizel2 2021-07-02 23:37:03 +00:00
Alexander Alekhin d7d491d445 Merge pull request #20344 from alalek:backport_20343 2021-07-02 23:35:12 +00:00
Alexander Alekhin 9b0d6862c4 cmake(IE): extract INF_ENGINE_RELEASE from InferenceEngine package 2021-07-02 23:29:35 +00:00
Alexander Alekhin 890fcdf842 Merge pull request #20337 from alalek:build_opencv_winpack_dldt_2021.4.0 2021-07-02 21:47:14 +00:00
mitruska 18dbac203f Use explicit version of ngraph NormalizeL2 2021-07-02 21:33:05 +00:00
Alexander Alekhin 8d1f254dcc java: force using of 'Ptr<>' for OpenCV classes
backport of commit: e5841d3126
2021-07-02 21:20:08 +00:00
Alexander Alekhin 90df3af6cf build: winpack_dldt with dldt 2021.4.0 2021-07-02 09:58:00 +00:00
Alexander Alekhin b699fe7a9d Merge pull request #20335 from SamFC10:concat-const-input 2021-07-01 10:25:35 +00:00
Alexander Alekhin b2ed5c3070 Merge pull request #20333 from APrigarina:fix_samples_3.4 2021-07-01 09:41:56 +00:00
SamFC10 5b8c10f2f8 modified onnx importer to concat const input blobs 2021-07-01 10:58:31 +05:30
Alexander Alekhin 24983f62e2 Merge pull request #20325 from alalek:dnn_openvino_2021.4.0 2021-06-30 23:58:26 +00:00
Alexander Alekhin f2057ce1ab dnn(ie): replace deprecated calls 2021-06-30 22:30:15 +00:00
Alexander Alekhin 6797fd65a5 dnn(test): update tests for OpenVINO 2021.4 2021-06-30 22:30:15 +00:00
Alexander Alekhin 947e06a860 Merge pull request #20328 from alalek:backport_20321 2021-06-30 20:51:49 +00:00
Alexander Alekhin 04d5ba266f Merge pull request #20330 from Wovchena:fix-arg-for-calcHist-in-demos 2021-06-30 14:59:22 +00:00
Vladimir 90be83ae99 Fix an arg for calcHist() in demos
`float* histRange = { range };` doesn't make much sense. `histRange` is
an array of array(s), so it should have a type of ptr to ptr. Strangely
some domos are correct as well as the example for the function
https://docs.opencv.org/master/d6/dc7/group__imgproc__hist.html#ga4b2b5fd75503ff9e6844cc4dcdaed35d
2021-06-30 17:22:56 +03:00
APrigarina 5e80bd3cc9 fix samples 3.4 2021-06-30 12:50:21 +03:00
Alexander Alekhin db4b1e613c core(persistence): fix types format handling
partial backport of 4eac198270
2021-06-29 21:54:52 +00:00
Alexander Alekhin 7d842f5bcf dnn: use OpenVINO 2021.4 defines 2021-06-29 18:48:21 +00:00
Alexander Alekhin 828304d587 Merge pull request #20128 from kikaxa:master 2021-06-21 21:52:17 +00:00
Alexander Alekhin 9d584475f6 Merge pull request #20283 from SamFC10:fix-batchnorm 2021-06-21 11:27:12 +00:00
kikaxa bb60cb0bf9 Reenable filesystem for ios builds 2021-06-20 16:33:25 +00:00
SamFC10 55e1dfb778 Fix BatchNorm reinitialization 2021-06-20 13:19:29 +05:30
Alexander Alekhin c2263db7bc Merge pull request #20232 from gasparitiago:drawMatches3.4 2021-06-18 19:47:52 +00:00
Alexander Alekhin 7bbbda71df Merge pull request #20253 from rogday:gtk_modifiers 2021-06-18 15:46:44 +00:00
Alexander Alekhin 8e0baf257c Merge pull request #20263 from vrabaud:3.4 2021-06-15 18:20:21 +00:00
Vincent Rabaud c8268e65fd Fix potential NaN in cv::norm.
There can be an int overflow.
cv::norm( InputArray _src, int normType, InputArray _mask ) is fine,
not cv::norm( InputArray _src1, InputArray _src2, int normType, InputArray _mask ).
2021-06-15 14:58:11 +02:00
Tiago De Gaspari 3cf4375387 Merge pull request #19842 from gasparitiago:3.4
Update rotatedRectangleIntersection function to calculate near to origin

* Change type used in points function from RotatedRect

In the function that sets the points of a RotatedRect, the types

should be double in order to keep the precision when dealing with
RotatedRects that are defined far from the origin.

This commit solves the problem in some assertions from
rotatedRectangleIntersection when dealing with rectangles far from
origin.

* added proper type casts

* Update rotatedRectangleIntersection function to calculate near to origin

This commit changes the rotatedRectangleIntersection function in order
to calculate the intersection of two rectangles considering that they
are shifted near the coordinates origin (0, 0).

This commit solves the problem in some assertions from
rotatedRectangleIntersection when dealing with rectangles far from
origin.

* Revert type changes in types.cpp and adequate code to c++98

* Revert unnecessary casts on types.cpp

Co-authored-by: Vadim Pisarevsky <vadim.pisarevsky@gmail.com>
2021-06-12 23:28:54 +03:00
Alexander Alekhin c1adbe3189 Merge pull request #20190 from rogday:tf_importer_ref 2021-06-11 20:06:09 +00:00
rogday 7ee1816612 split if into map of functions 2021-06-11 13:20:45 +03:00
Smirnov Egor 8f4f834ce6 applied modifier mask to the state 2021-06-10 10:57:15 +03:00
Alexander Alekhin 2b84c97a78 Merge pull request #20251 from alalek:python_sys_path_0_workaround 2021-06-09 10:58:18 +00:00
Alexander Alekhin 3ddf84534b Merge pull request #20248 from alalek:issue_20246 2021-06-09 10:52:16 +00:00
Alexander Alekhin bd26104088 python(loader): add workaround to detect and patch sys.path[0] 2021-06-09 09:51:07 +00:00
Alexander Alekhin 5f80f43ff5 core: fix nSize initialization in cvIplImage() 2021-06-09 07:31:38 +00:00
Alexander Alekhin b221143c0f Merge pull request #20241 from alalek:fixup_20149 2021-06-08 13:44:58 +00:00
Alexander Alekhin 995841624c highgui(gtk): fix NULL ptr checks 2021-06-08 10:57:24 +00:00
Alexander Alekhin bbcd06f42f Merge pull request #20236 from alalek:update_version_3.4.15-pre 2021-06-07 22:05:29 +00:00
Alexander Alekhin 43940f7ffc pre: OpenCV 3.4.15 (version++) 2021-06-07 20:10:34 +00:00
jogo- f4a79b0554 Merge pull request #20223 from jogo-:3.4_wp8_samples_typos
* Fix typo in App.xaml.cs

* Fix typo in App.xaml.cs

* Fix typo in App.xaml.cs
2021-06-07 17:32:14 +00:00
Tiago De Gaspari 411fd2b761 Add Thickness parameter in drawMatches function
This commit adds the feature of selecting the thickness
of the matches drawn by the drawMatches function.

In larger images, the default thickness of 1 pixel creates images
that are hard to visualize.
2021-06-07 12:52:48 -03:00
Alexander Alekhin 61e30c15a9 Merge pull request #20211 from kstuedem:fix_dshow_memory_leak 2021-06-05 16:02:12 +00:00
Alexander Alekhin d332f33346 Merge pull request #20210 from kstuedem:fix_invalid_media_type 2021-06-05 16:01:51 +00:00
Kai Stüdemann 636db09d73 videoio(dshow) fix incompatible media type left set on video device 2021-06-04 10:45:39 +02:00
Kai Stüdemann 64c018507b videoio(dshow) fix memory leak 2021-06-04 10:02:48 +02:00
Alexander Alekhin c34445a496 Merge pull request #20201 from PolarNick239:3.4 2021-06-03 16:20:24 +00:00
Paul Jurczak ff60abb575 Merge pull request #20080 from pauljurczak:patch-3
* Update dnn.hpp

getPerfProfile is not supported by the CUDA backend, see https://github.com/opencv/opencv/issues/20077

* dnn.hpp: fix doxygen formatting
2021-06-02 19:15:52 +00:00
Alexander Alekhin 7d91dfe339 Merge pull request #20146 from asmorkalov:as/java_test_filter 2021-06-02 17:50:29 +00:00
Alexander Alekhin 15af65d4cf Merge pull request #20149 from rogday:on_mouse_floor 2021-06-02 17:48:43 +00:00
Alexander Alekhin 81afeda537 Merge pull request #20192 from alalek:update_libjpeg-turbo 2021-06-02 16:30:25 +00:00
Alexander Alekhin e10de25e86 Merge pull request #20191 from alalek:issue_20032 2021-06-02 16:29:51 +00:00
Nikolay Polyarniy 746bd47ce5 EXR reading: support Z channel if no Y channel 2021-06-02 15:53:32 +03:00
Alexander Alekhin dcb4cabb26 3rdparty: libjpeg-turbo 2.0.6 => 2.1.0
https://github.com/libjpeg-turbo/libjpeg-turbo/releases/tag/2.1.0
2021-06-01 20:01:19 +00:00
Alexander Alekhin 59b4baee0c ts: migrate from cgi.escape to html.escape in .py file 2021-06-01 19:19:05 +00:00
Alexander Alekhin bb3bbd192b Merge pull request #20150 from rogday:svm_detector_test 2021-06-01 13:31:12 +00:00
Alexander Smorkalov 1212aef03b Analog of gtest_filter for java tests. 2021-06-01 11:04:18 +03:00
Developer-Ecosystem-Engineering 814550d2a6 Merge pull request #20011 from Developer-Ecosystem-Engineering:3.4
Improve performance on Arm64

* Improve performance on Apple silicon

This patch will
- Enable dot product intrinsics for macOS arm64 builds
- Enable for macOS arm64 builds
- Improve HAL primitives
  - reduction (sum, min, max, sad)
  - signmask
  - mul_expand
  - check_any / check_all

Results on a M1 Macbook Pro

* Updates to #20011 based on feedback

  - Removes Apple Silicon specific workarounds
  - Makes #ifdef sections smaller for v_mul_expand cases
  - Moves dot product optimization to compiler optimization check
  - Adds 4x4 matrix transpose optimization

* Remove dotprod and fix v_transpose

Based on the latest, we've removed dotprod entirely and will revisit in a future PR.

Added explicit cats with v_transpose4x4()

This should resolve all opens with this PR

* Remove commented out lines

Remove two extraneous comments
2021-06-01 09:39:55 +03:00
Smirnov Egor fb68fe8930 bring back bounds check and switch to floor 2021-05-31 19:03:50 +03:00
yo1990 d3be58b6d7 Merge pull request #20102 from yo1990:master
Add missing sqrt to magSpectrum().

* https://github.com/opencv/opencv/issues/20100

* slight optimization + fix for double-precision case

Co-authored-by: Yuma Oyama <yuma.oyama@acuity-inc.co.jp>
Co-authored-by: Vadim Pisarevsky <vadim.pisarevsky@me.com>
2021-05-29 17:43:21 +03:00
Jonathan Deakin 8ecfbdb4ff Merge pull request #19883 from jondea:arm-neon-optimised-color-lab-3.4
* Add Neon optimised RGB2Lab conversion

* Fix compile errors, change lambda to macro

* Change NEON optimised RGB2Lab to just use HAL

* Change [] to v_extract_n in RGB2Lab

* RGB2LAB Code quality, change to nlane agnostic

* Change RGB2Lab to use function rather than macro

* Remove whitespace

Co-authored-by: Francesco Petrogalli <25690309+fpetrogalli@users.noreply.github.com>
2021-05-28 14:20:26 +00:00
Alexander Alekhin 63256a00ff Merge pull request #20174 from alalek:issue_20159 2021-05-28 14:10:17 +00:00
Alexander Alekhin 450dc92452 Merge pull request #20172 from alalek:fixup_19334 2021-05-28 14:09:52 +00:00
Alexander Alekhin 3d2f4fa164 highgui: fix trackbar value pointer handling 2021-05-28 01:58:58 +00:00
Alexander Alekhin 3d394943e6 core(ocl): avoid limit of Image kernel args 2021-05-28 00:43:59 +00:00
Alexander Alekhin 3e25f32c9b Merge pull request #20158 from hyrodium:fix/latex 2021-05-26 06:31:05 +00:00
hyrodium 81567a9d3e fix latex script in the docs 2021-05-26 12:46:14 +09:00
Vadim Pisarevsky 4a2adba8f4 Merge pull request #20135 from mightbxg:bugfix_GaussianBlur 2021-05-25 12:54:56 +00:00
Smirnov Egor 84f78059d3 add reproducer and bugfix 2021-05-25 11:28:23 +03:00
Xinguang Bian 7499a15c92 fix data overflow problem in GaussianBlur 2021-05-21 15:17:20 +08:00
Alexander Alekhin 5f4e55bc68 Merge pull request #20123 from catree:fix_tsai_park_bib_render 2021-05-19 14:19:53 +00:00
catree c621384707 Use correct BibTeX syntax for month field. 2021-05-19 14:24:07 +02:00
thezane c0162a64d1 Merge pull request #20103 from thezane:make-div-spectrums-public
* Make divSpectrums public

* Add unit test
2021-05-19 12:14:11 +03:00
Alexander Alekhin 1ae16beb06 Merge pull request #20097 from komakai:fix_qrcode_test 2021-05-17 17:53:35 +00:00
Giles Payne e53a4ce64d Fix for failing QRCodeDetectorTest.testDetectAndDecodeMulti test 2021-05-17 20:09:12 +09:00
Alexander Alekhin 72655a9eea Merge pull request #20085 from changh95:fix_typo_calib3d_sample_code 2021-05-17 07:26:51 +00:00
Alexander Alekhin 125f890dc3 Merge pull request #20088 from alalek:cmake_module_linker_flags 2021-05-17 07:26:25 +00:00
changh95 101d50703c fix typo 'undistorsed'->'undistorted' 2021-05-16 15:08:37 +09:00
Alexander Alekhin 901ed5545f cmake: fix handling of CMAKE_MODULE_LINKER_FLAGS 2021-05-14 17:47:00 +00:00
Alexander Alekhin 699b4b9fc5 Merge pull request #20071 from rogday:depth_fallback_doc 2021-05-14 06:09:09 +00:00
Smirnov Egor 1d7d18afba Document imwrite depth fallback 2021-05-12 19:55:58 +03:00
Alexander Alekhin b335fe67b0 Merge pull request #20049 from jstaahl:jstaahl-static-inits 2021-05-11 17:06:11 +00:00
Alexander Alekhin dde029f105 Merge pull request #20053 from berak:core_mat_ptr_vec 2021-05-11 16:34:03 +00:00
berak 302c2354a3 core: add missing implementation for Mat::ptr(Vec) 2021-05-09 14:15:12 +02:00
Jake Staahl 158b13e0ba Remove static initializers caused by templated static member. 2021-05-07 12:53:14 -07:00
Alexander Alekhin b1dc7ed873 Merge pull request #20033 from berak:dnn_openpose_py 2021-05-07 12:42:16 +00:00
berak 1bced43e96 samples/dnn: better errormsg in openpose.py 2021-05-05 10:39:12 +02:00
Alexander Alekhin 8550f7e04d Merge pull request #20018 from lpea:doc_fixes_calib3d 2021-05-01 09:35:59 +00:00
Guillaume Jacob 9f3e83baf6 calib3d: Update documentation of calibrateCamera
- Added missing documentation for the CALIB_FIX_FOCAL_LENGTH flag
- Removed erroneous information about the number of distortion coefficients
returned
- Added some missing @ref tags
2021-04-30 20:34:04 +02:00
Alexander Alekhin 17ab61a40d Merge pull request #19956 from danielenricocahall:fix-edge-case-matcher-loop 2021-04-30 17:22:16 +00:00
Danny 1b844f8413 Merge pull request #19993 from danielenricocahall:fix-compute-ecc-issue
Fix unsigned int bug in computeECC

* address issue with unsigned ints in computeEcc

* remove additional logic checking firstOctave

* use swap instead of same src/dst

* simplify the unsigned check logic
2021-04-30 17:20:52 +00:00
Alexander Alekhin baa22fa808 Merge pull request #20006 from alalek:dnn_ie_gpu_cache_dir 2021-04-30 17:18:52 +00:00
Alexander Alekhin f78cebfc98 Merge pull request #20014 from alalek:fix_core_tls_process_termination 2021-04-30 16:06:40 +00:00
Alexander Alekhin d2a9ca13f1 core(tls): handle process termination / cleanup issues 2021-04-29 23:25:44 +00:00
Alexander Alekhin 71bae7c23f dnn(ie): implicit usage of IE::GPU OpenCL kernels cache 2021-04-29 12:43:22 +03:00
Alexander Alekhin d4f104f17f Merge pull request #19988 from alexkalmuk:fix-squares-cpp-sample 2021-04-28 22:03:14 +00:00
Alexander Alekhin fd44ba296d Merge pull request #19984 from sturkmen72:patch-4 2021-04-28 22:02:02 +00:00
Alex Kalmuk b04d6a2d9b Fix squares sample failure when a single file passed 2021-04-28 09:36:04 +03:00
Alexander Alekhin a08eac452e Merge pull request #19979 from micha137:patch-3 2021-04-27 13:31:05 +00:00
micha137 7021ea6748 Fix link 2021-04-27 11:22:07 +02:00
Alexander Alekhin 55aa1d4852 Merge pull request #19975 from danielenricocahall:fix-template-matcher-sqdiff 2021-04-26 22:52:13 +00:00
Suleyman TURKMEN 159534313e Update CMakeLists.txt 2021-04-26 22:43:04 +03:00
Alexander Alekhin 2f68c43e39 Merge pull request #19983 from hartmannathan:typo-fix-download 2021-04-26 19:25:56 +00:00
Nathan Hartman e2483aa072 Fix typo: 'DOWNLAOD' to 'DOWNLOAD' 2021-04-26 11:01:13 -04:00
Alexander Alekhin c69f37343c Merge pull request #19980 from zchrissirhcz:fix-CV_XADD-missing-return-type 2021-04-26 14:10:51 +00:00
Alexander Alekhin aec62a7fc5 Merge pull request #19969 from alalek:issue_19850 2021-04-26 13:23:29 +00:00
Zhuo Zhang bf26050f7e Fix missing return type for unsafe CV_XADD function 2021-04-26 20:08:45 +08:00
danielenricocahall 402bce1a31 address template matching sqdiff bug 2021-04-25 22:17:07 -04:00
Alexander Alekhin 8868350888 doxygen: fix quotes in add_toggle macro 2021-04-23 22:31:04 +00:00
Stefano Allegretti 1b64851fa8 Merge pull request #19951 from stal12:3.4
* Fix #4363 - wrong hierarchy (CV_RETR_TREE) in findContours

* Add regression test for findContours

* use C++11 => C++98 on 3.4 branch
2021-04-22 18:20:12 +00:00
Aleksandr Voron 2e143b8799 Merge pull request #19961 from alvoron:dnn_ngraph_int64_fix
Explicit usage of int64_t in CropAndResizeLayer (IE backend)

* Update crop_and_resize_layer.cpp
2021-04-21 18:29:19 +00:00
danielenricocahall 3930c9a492 fix loop boundary condition 2021-04-20 22:08:01 -04:00
Alexander Alekhin f0839d2703 Merge pull request #19944 from berak:patch-1 2021-04-20 17:16:52 +00:00
berak 405e820fe1 Update contrast_preserve.hpp
fix a build warning:

```
C:\Slave\workspace\precommit\windows10\opencv\modules\photo\src\contrast_preserve.hpp(289): warning C4244: '=': conversion from 'double' to '_Tp', possible loss of data
        with
        [
            _Tp=float
        ]
C:\Slave\workspace\precommit\windows10\opencv\modules\photo\src\contrast_preserve.hpp(361): warning C4244: '=': conversion from 'double' to '_Tp', possible loss of data
        with
        [
            _Tp=float
        ]
```

(from https://build.opencv.org.cn/job/precommit/job/windows10/1633/console)
2021-04-20 12:59:36 +02:00
Alexander Alekhin 6598e9d506 Merge pull request #19908 from CSBVision:patch-2 2021-04-15 20:45:30 +00:00
Alexander Alekhin 8c2cf89845 Merge pull request #19913 from mshabunin:fix-san-build 2021-04-15 11:15:37 +00:00
Maksim Shabunin aeb8dfc52d Fix header sorting for modules without headers 2021-04-15 12:13:15 +03:00
Alexander Alekhin 0649a2fbdb Merge pull request #19886 from alalek:issue_19875 2021-04-14 16:14:44 +00:00
CSBVision ec32061f5f Update __init__.py to support symbolic links
Currently, the LOADER_DIR is set as os.path.dirname(os.path.abspath(__file__)). This does not point to the true library path if the cv2 folder is symlinked into the Python package directory such that importing cv2 under Python fails. The proposed change only resolves symbolic links correctly by calling os.path.realpath(__file__) first and does not change anything if __file__ contains no symbolic link.
2021-04-14 16:13:45 +00:00
Alexander Alekhin f2da1a0a7a Merge pull request #19900 from berak:doc_fix_python_retval 2021-04-13 17:38:07 +00:00
Alexander Alekhin fda1e6f148 Merge pull request #19901 from alalek:ml_update_checks 2021-04-13 15:47:01 +00:00
berak 2a48730166 docs:fix python retvals 2021-04-13 15:48:31 +02:00
Alexander Alekhin 0bdbc745c4 ml: update checks 2021-04-13 11:09:14 +00:00
Alexander Alekhin 6f70b0524a Merge pull request #19894 from alalek:fix_ml_tree_legacy_import 2021-04-12 20:33:34 +00:00
Alexander Alekhin b9b19185bc ml: fix legacy import in DTreesImpl 2021-04-12 19:21:48 +00:00
Alexander Alekhin 63ba9970bd Merge pull request #19851 from sturkmen72:update_documentation 2021-04-11 21:44:03 +00:00
Danny a9a6801c6d Merge pull request #19884 from danielenricocahall:fix-prediction-features-bug
Fix bug with predictions in RTrees/Boost

* address bug where predict functions with invalid feature count in rtrees/boost models

* compact matrix rep in tests

* check 1..n-1 and n+1 in feature size validation test
2021-04-09 16:56:14 +00:00
Alexander Alekhin 222af8e7e4 core: avoid process cleanup deadlock if TlsStorage is not used 2021-04-09 16:08:08 +00:00
Suleyman TURKMEN ec8b7c933a Update Documentation 2021-04-08 22:29:45 +03:00
Danny 76860933f0 Merge pull request #19859 from danielenricocahall:fix-blob-detector-single-thresh
Fix Single ThresholdBug in Simple Blob Detector

* address bug with using min dist between blobs in blob detector

cast type in comparison and remove docs

address bug with using min dist between blobs in blob detector

use scalar instead of int

address bug with using min dist between blobs in blob detector

* fix namespace and formatting
2021-04-08 10:39:26 +00:00
Alexander Alekhin 19a936fc03 Merge pull request #19836 from 103yiran:warpaffine 2021-04-08 10:32:27 +00:00
Alexander Alekhin be17fce657 Merge pull request #19847 from gasparitiago:expose-max-iters 2021-04-08 10:31:36 +00:00
Alexander Alekhin 9a1d7736f8 Merge pull request #19838 from mshabunin:fix-intel-ipp-link 2021-04-07 09:42:32 +00:00
Tiago De Gaspari 9f295b2c91 Expose maxIters in findEssentialMat
Lets the user choose the maximum number of iterations the robust
estimator runs for, similary to findFundamentalMat
and findHomography functions.
2021-04-07 00:07:33 -03:00
Alexander Alekhin 3a8154051f Merge pull request #19810 from aarongreig:aaron/core/relaxClArithmTest 2021-04-06 19:56:46 +00:00
Aaron Greig f3f46096d6 Relax accuracy requirements in the OpenCL sqrt perf arithmetic test.
Also bring perf_imgproc CornerMinEigenVal accuracy requirements in line with
the test_imgproc accuracy requirements on that test and fix indentation on
the latter.

Partially addresses issue #9821
2021-04-06 17:32:48 +01:00
Alexander Alekhin ace37df941 Merge pull request #19854 from gasparitiago:fundamentalMat-fix 2021-04-06 10:19:57 +00:00
Tiago De Gaspari ac9182f20d Add maxIters parameter to LMeDS method in findFundamentalMat
This commit passes the parameter maxIters that represent
the maximum number of iterations, that can be passed to findFundamentalMat
to the method LMeDS.

This parameter were added to the function findFundamentalMat and
were passed just for the RANSAC method, but should be passed to
both methods to be consistent.
2021-04-03 21:56:05 -03:00
Alexander Alekhin 2cf1a13755 Merge tag '3.4.14' 2021-04-02 09:31:32 +00:00
Maksim Shabunin 6465e393b6 IPP: use linker workaround for Intel compiler on Linux 2021-04-02 10:44:32 +03:00
103yiran 6e6c0f31f7 delete unused variable 2021-04-02 10:30:27 +08:00
Alexander Alekhin d0e3e638c3 release: OpenCV 3.4.14 2021-04-01 21:37:19 +00:00
Alexander Alekhin 6a72bf5085 Merge pull request #19823 from alalek:issue_contrib_2895 2021-04-01 20:38:46 +00:00
Alexander Alekhin 0ff57e3292 Merge pull request #19830 from alalek:issue_19368 2021-04-01 15:30:18 +00:00
Alexander Alekhin 5db484b6c2 Merge pull request #19831 from alalek:backport_19771 2021-04-01 14:05:09 +00:00
Alexander Alekhin 6865787a75 Merge pull request #19827 from alalek:build_videoio_macosx_override_3.4 2021-04-01 12:34:23 +00:00
Alexander Alekhin 7f664850f5 Merge pull request #19825 from alalek:cmake_fix_headers_order_python_3.4 2021-04-01 12:34:10 +00:00
Alexander Alekhin 2907fb88f5 Merge pull request #19822 from alalek:core_wui_backward_compatibility 2021-04-01 12:32:33 +00:00
Alexander Alekhin d7cb2ea210 videoio(dshow): add NULL ptr check 2021-04-01 11:28:41 +00:00
Alexander Alekhin 4ae2c11520 videoio(build): eliminate inconsistent 'override' warnings 2021-04-01 09:56:21 +00:00
Alexander Alekhin 1b3e0b27af cmake: fix files order in Python bindings
- with changes backport from 4.x
2021-04-01 09:48:50 +00:00
Alexander Alekhin e4b0251e9d cuda: fix inplace condition in cv::cuda::flip 2021-04-01 02:26:59 +00:00
Alexander Alekhin b26f5b9468 core: backward compatibility for vx_store/vx_store_aligned calls 2021-04-01 02:17:47 +00:00
Alexander Alekhin 5340dc6686 Merge pull request #19819 from alalek:cmake_fix_headers_order 2021-04-01 01:34:21 +00:00
Alexander Alekhin 2b86de217a cmake: fix order of headers
- cmake uses filesystem's order which may vary
- unpredictable headers order may cause build failures (primary bindings)
2021-03-31 23:16:46 +00:00
Alexander Alekhin 1615afd7f4 Merge pull request #19814 from alalek:pyopencv_to_safe 2021-03-31 22:58:18 +00:00
Alexander Alekhin 908957317f Merge pull request #19813 from alalek:issue_19506 2021-03-31 22:57:50 +00:00
Alexander Alekhin 6fa2bdd7f2 Merge pull request #19812 from alalek:workaround_19634 2021-03-31 22:57:15 +00:00
Alexander Alekhin f82303d614 Merge pull request #19811 from alalek:issue_19599 2021-03-31 22:56:48 +00:00
Alexander Alekhin 6773fa03e2 Merge pull request #19808 from alalek:3.4_python_fix_wrap_as 2021-03-31 22:56:14 +00:00
Alexander Alekhin d651ff8d6b python: exception-free pyopencv_to() wrapper 2021-03-31 14:18:32 +00:00
Alexander Alekhin 8069a6b4f8 core(IPP): disable some ippsMagnitude_32f calls 2021-03-31 13:38:57 +00:00
Alexander Alekhin b697b3162f videoio(mjpeg): disable parallel encoder 2021-03-31 12:35:12 +00:00
Alexander Alekhin 53a16b1186 Merge pull request #19809 from alalek:issue_19513 2021-03-31 10:50:20 +00:00
Alexander Alekhin a2a92999be core(arithm_op): workaround problem with scalars handling 2021-03-31 10:35:52 +00:00
Alexander Alekhin 40c0830b63 videoio(avfoundation): add getCaptureDomain() 2021-03-31 09:35:11 +00:00
eplankin 6f1eefec69 Merge pull request #19681 from eplankin:link_problem
* Workaround for IPP linking problem

* Apply -Bsymbolic to all cases when IPP is on

* Tried to hide symbols on MacOS

* Tried on --exclude-libs option

* Fixed macos and win warnings

* Fixed win build

* cmake(IPP): move --exclude-libs,libippcore.a to IPP CMake file

Co-authored-by: Alexander Alekhin <alexander.a.alekhin@gmail.com>
2021-03-31 09:24:37 +00:00
Alexander Alekhin bb6e15f2c0 python: fix CV_WRAP_AS handling 2021-03-30 22:02:48 +00:00
Alexander Alekhin 0dcb99cf23 Merge pull request #19798 from LupusSanctus:am/reduce_sum_ch 2021-03-30 21:37:13 +00:00
Anastasia Murzova cc6d48959e Added reduce sum by channel support 2021-03-30 23:01:22 +03:00
Vitaly Tuzov aab62aa6dd Merge pull request #18952 from terfendail:wui_doc
* Updated UI documentation to address WUI

* Added documentation for vx_ calls

* Removed vx_store operation overload

* Doxyfile updated to enable wide UI

* Enable doxygen documentation for vx_ WUI functions

* Wide intrinsics definition rework

* core: fix SIMD C++ emulator build (supports 128-bit only)
2021-03-30 16:18:03 +00:00
Alexander Alekhin ac9f3a1242 Merge pull request #19793 from aarongreig:aaron/imgproc/relaxCornerEigenValTest 2021-03-29 13:41:44 +00:00
Aaron Greig 53652a6194 Relax accuracy requirement on OpenCL MinEigenVal corner kernel test.
The MinEigenVal path through the corner.cl kernel makes use of native_sqrt,
a math builtin function which has implementation defined accuracy.

Partially addresses issue #9821
2021-03-29 12:06:02 +01:00
lionkun 8d232a63ad fix the perf tests of OpenCV.js so that it can run on Node.js successfully 2021-03-27 21:52:44 +00:00
Alexander Alekhin bf03f5fa3a Merge pull request #19786 from alalek:build_opencv_winpack_dldt_2021.3.0 2021-03-26 22:38:52 +00:00
Alexander Alekhin 6e8022a3af Merge pull request #19773 from jondea:add-aarch64-specialised-v_expand-3.4 2021-03-26 16:54:51 +00:00
Alexander Alekhin d27eb79fa6 Merge pull request #19785 from alalek:dnn_ocl_fix_async_kernels 2021-03-26 12:27:58 +00:00
Anastasia M 3e48a91d97 Merge pull request #19546 from LupusSanctus:am/slice_steps
* Added Steps support in DNN Slice layer

* Added code corrections

* dnn(slice): fix OCL and OCL_FP16 processing
2021-03-26 11:04:57 +00:00
Alexander Alekhin 144443d011 build: winpack_dldt with dldt 2021.3.0 2021-03-26 08:58:00 +00:00
Alexander Alekhin 86d0a86141 dnn(ocl): fix gemm kernel scheduling 2021-03-26 00:35:00 +00:00
Mikhail Nikolskii bf9f67e93f Merge pull request #19783 from mikhail-nikolskiy:interop-perf
Performance optimization in DirectX and VAAPI interop

* optimization in OpenCL NV12<>BGR kernels

* reduce kernel work-size
2021-03-25 21:27:31 +00:00
Alexander Alekhin 26ea4760ad Merge pull request #19774 from aarongreig:aaron/dnn/oclTestAccuracyThresholds 2021-03-25 16:58:07 +00:00
Aaron Greig f59917bea1 Introduce relaxed accuracy thresholds for CL target in some dnn tests.
Partially addresses #9821
2021-03-25 10:58:23 +00:00
Alexander Alekhin a394c8b10b Merge pull request #19770 from alalek:dnn_openvino_2021.3.0 2021-03-24 18:50:47 +00:00
Alexander Alekhin e56e4876e7 dnn(test): update tests for OpenVINO 2021.3 2021-03-24 14:50:42 +00:00
Alexander Alekhin 56bdd7db5c dnn: use OpenVINO 2021.3 defines
original commit: 6291503793
2021-03-24 10:26:24 +00:00
Alexander Alekhin 3df6bc58e9 Merge pull request #19765 from LupusSanctus:am/mobilenetv3 2021-03-24 09:43:27 +00:00
Anastasia Murzova e75f1b071b Added reshape corrections 2021-03-24 10:53:11 +03:00
Anastasia Murzova 7a2b3ed471 Corrected DNN elementwise multiplication 2021-03-24 10:53:11 +03:00
Anastasia M 551d4a8ec1 Merge pull request #19477 from LupusSanctus:am/eltwice_vec
* Aligned OpenCV DNN and TF sum op behaviour

Support Mat (shape: [1, m, k, n] ) + Vec (shape: [1, 1, 1, n]) operation
by vec to mat expansion

* Added code corrections: backend, minor refactoring
2021-03-23 22:16:09 +00:00
Jonathan Deakin 29a289dfa1 Add v_expand for AArch64, fuse vmovl+vget_high into vmovl_high 2021-03-23 15:06:41 +00:00
Alexander Alekhin bdd2b57e5d Merge pull request #19757 from alalek:js_setLogLevel 2021-03-21 17:37:05 +00:00
Alexander Alekhin a97f6f8058 js: support setLogLevel() / getLogLevel() calls 2021-03-20 18:14:10 +00:00
Liubov Batanina c0dd82fb53 Merge pull request #19632 from l-bat:lb/ie_arm_target
Added OpenVINO ARM target

* Added IE ARM target

* Added OpenVINO ARM target

* Delete ARM target

* Detect ARM platform

* Changed device name in ArmPlugin

* Change ARM detection
2021-03-20 11:20:02 +00:00
Alexander Alekhin 1211a8b9cd Merge pull request #19745 from alalek:issue_19729 2021-03-19 12:52:34 +00:00
Alexander Alekhin f680505086 features2d(mser): chi_table.h notes 2021-03-18 21:30:12 +00:00
Alexander Alekhin ae60bbc7e4 Merge pull request #19741 from alalek:ml_logistic_regression_use_opencv_license_header 2021-03-18 20:47:44 +00:00
Alexander Alekhin 7664e6d090 ml: use OpenCV license header for logistic regression 2021-03-17 20:29:52 +00:00
Ziachnix 960f501cc1 Merge pull request #19284 from Ziachnix:feature/js-qr-code-detector
Add QRCodeDetector to JavaScript Build

* ADD: js support for qrCodeDetector

- cherry picked commit to solve rebase error

* CHG. Revert haarcascade path

* FIX: Tests without images

* ADD: decodeCurved

* js(docs): don't require OPENCV_TEST_DATA_PATH

Co-authored-by: Alexander Alekhin <alexander.a.alekhin@gmail.com>
2021-03-13 12:52:44 +00:00
Alexander Alekhin 7a8e171691 Merge pull request #19720 from alalek:ocl_test_skip_spir_amd 2021-03-13 12:48:20 +00:00
Alexander Alekhin 7ca9740da5 Merge pull request #19718 from alalek:backport_19683 2021-03-13 12:46:24 +00:00
Alexander Alekhin 68fae94cbb Merge pull request #19717 from danbey:bad_value_param_should_be_passed_by_reference 2021-03-13 12:45:55 +00:00
Alexander Alekhin 6da5c7c1d0 Merge pull request #19716 from l-bat:lb/fix_resize 2021-03-13 12:45:07 +00:00
Alexander Alekhin 87e607a19b core(ocl): skip SPIR test on AMD devices if problem detected 2021-03-13 06:12:52 +00:00
Dale Phurrough cbe236652b noexcept def construct Mat, UMat, Mat_, MatSize, MatStep
original commit: 1b0f781b7c
2021-03-12 20:26:32 +00:00
Dan Ben Yosef d4d805cb3e Avoiding copy by passing param by reference
It is best to pass bad_value_ param by reference to avoid copy.
2021-03-12 14:17:11 -05:00
Liubov Batanina 8d29a902e4 Added ngraph::op::v6::MVN 2021-03-12 21:02:03 +03:00
Alexander Alekhin f136adcad5 Merge pull request #19715 from seiko2plus:issue_19698 2021-03-12 09:45:19 +00:00
Liubov Batanina 95ab9468c1 Added ngraph::op::v4::Interpolation 2021-03-12 12:00:59 +03:00
Sayed Adel f8181fbef8 core:ppc64 fix detecting CPU features when optimization is off 2021-03-12 02:02:31 +00:00
Xinguang Bian b995de4ff3 Merge pull request #19253 from mightbxg:bugfix_PnPRansac
* fix unexpected Exception in solvePnPRansac caused by input points

* calib3d: solvePnPRansac - keep minimal changes to handle DLT 6 points requirement

Co-authored-by: Alexander Alekhin <alexander.a.alekhin@gmail.com>
2021-03-12 00:53:06 +03:00
Alexander Alekhin 825dadfbdd Merge pull request #19703 from danbey:setting_StereoSGBMParams_in_init_list 2021-03-11 21:33:19 +00:00
Dan Ben Yosef 63048812c7 Init params (StereoSGBMParams) in StereoSGBMImpl constructor initialization list
To improve preformence it is better to init the params (StereoSGBMParams) in the
    initialization list.
2021-03-10 13:05:35 -05:00
Alexander Alekhin e4692ac079 Merge pull request #19613 from WeiChungChang:NMS_refine 2021-03-10 17:36:57 +00:00
Qoo 47337e2196 boost NMS performance 2021-03-10 15:59:26 +00:00
Alexander Alekhin 1d6a1e5f9c Merge pull request #19692 from seiko2plus:issue_19647 2021-03-09 18:14:41 +00:00
Sayed Adel 84fcc4ab9b core:ppc64 fix the build with the newer versions of Eigen on IBM/Power
It also fixes the build when universal intrinsics is disabled
   via `-DDCV_ENABLE_INTRINSICS=OFF`.
2021-03-09 19:20:18 +02:00
Daniel Playfair Cal 65b51e1538 Merge pull request #19690 from hedgepigdaniel:fix/calibration_fisheye
* fix(samples/camera_calibration): set new camera matrix for fisheye

* fix(camera_calibration): ignore inapplicable flags for fisheye
2021-03-09 15:09:08 +00:00
Alexander Alekhin 6c9be1bc1d Merge pull request #19675 from asmorkalov:as/pylint_warnings 2021-03-09 09:43:52 +00:00
Alexander Smorkalov 4c48f1eed2 Removed unused variables found by pylint. 2021-03-09 10:56:45 +03:00
Dan Ben-Yosef 31f66766b7 Merge pull request #19685 from danbey:setting_stereoBMImpl_in_init_list
Init params (StereoBMParams) in StereoBMImpl constructor initialization list

* Init StereoBMImpl in initialization list

To improve preformence it is better to init the params (StereoBMImpl) in the
initialization list.

* coding style

* drop useless copy/move ctor

Co-authored-by: Alexander Alekhin <alexander.a.alekhin@gmail.com>
2021-03-07 20:06:08 +03:00
Alexander Alekhin 601690695e Merge pull request #19687 from alalek:videoio_docs_fixes_3.4 2021-03-07 16:23:24 +00:00
Alexander Alekhin 85009800b3 videoio(docs): fixes 2021-03-07 04:26:49 +00:00
Vitaly Tuzov 04a9ff88d8 Merge pull request #19622 from terfendail:ref_doc
* Updated cpp reference implementations for a few intrinsics to address wide universal intrinsics as well

* Updated cpp reference implementations for a few more universal intrinsics
2021-03-06 17:22:21 +00:00
Alexander Alekhin dc24663e8d Merge pull request #19641 from LupusSanctus:am/tf_reshape 2021-03-06 17:21:34 +00:00
Alexander Alekhin d2cc63e779 Merge pull request #19680 from alalek:cmake_update_python_linters 2021-03-06 17:20:02 +00:00
Alexander Alekhin 358878caf7 Merge pull request #19671 from SamFC10:sam-darknet 2021-03-05 15:12:21 +00:00
Mradul Agrawal 640f188ca2 Merge pull request #19583 from theroyalpekka:patch-1
* Update polynom_solver.cpp

This pull request is in the response to Issue  #19526. I have fixed the problem with the cube root calculation of 2*R. The Issue was in the usage of pow function with negative values of R, but if it is calculated for only positive values of R then changing x0 according to the parity of R, the Issue is resolved. Kindly consider it, Thanks!

* add cv::cubeRoot(double)

Co-authored-by: Alexander Alekhin <alexander.a.alekhin@gmail.com>
2021-03-05 13:55:52 +00:00
Alexander Alekhin a1e2c4f338 Merge pull request #19655 from raaldrid:EXR_rw_alpha_support_16115 2021-03-05 16:54:31 +03:00
Alexander Alekhin 625d4fc884 cmake: update Python linters handling
- exclude from getBuildInformation()
- fix pylint version
2021-03-05 12:54:51 +00:00
Alexander Alekhin f821530eb0 Merge pull request #19677 from APrigarina:detection_fix 2021-03-05 08:40:27 +00:00
Anastasia Murzova 7894cd3c73 Aligned TF Reshape layer behaviour 2021-03-05 01:01:37 +03:00
APrigarina 125cc79c17 fix false positive detection 2021-03-04 19:20:31 +03:00
Alexander Alekhin 2a808aeec0 Merge pull request #19674 from l-bat:lb/fix_ie_tests 2021-03-04 14:52:20 +00:00
Liubov Batanina 94533e12eb Determine layout 2021-03-04 13:05:01 +03:00
Alexander Alekhin a0008de281 Merge pull request #19607 from alalek:backport_19606 2021-03-03 21:10:57 +00:00
SamFC10 a42d4da003 Added Spatial Attention Module in Darknet Importer 2021-03-03 22:42:47 +05:30
Alexander Alekhin 0689c70dba Merge pull request #19665 from alalek:update_ffmpeg_3.4 2021-03-03 11:22:56 +00:00
Alexander Alekhin 75ad74c893 ffmpeg/3.4: update FFmpeg wrapper 2021.03
- FFmpeg 3.4.8
2021-03-02 23:59:38 +00:00
Alexander Alekhin cbfd38bd41 core: rework code locality
- to reduce binaries size of FFmpeg Windows wrapper
- MinGW linker doesn't support -ffunction-sections (used for FFmpeg Windows wrapper)
- move code to improve locality with its used dependencies
- move UMat::dot() to matmul.dispatch.cpp (Mat::dot() is already there)
- move UMat::inv() to lapack.cpp
- move UMat::mul() to arithm.cpp
- move UMat:eye() to matrix_operations.cpp (near setIdentity() implementation)
- move normalize(): convert_scale.cpp => norm.cpp
- move convertAndUnrollScalar(): arithm.cpp => copy.cpp
- move scalarToRawData(): array.cpp => copy.cpp
- move transpose(): matrix_operations.cpp => matrix_transform.cpp
- move flip(), rotate(): copy.cpp => matrix_transform.cpp (rotate90 uses flip and transpose)
- add 'OPENCV_CORE_EXCLUDE_C_API' CMake variable to exclude compilation of C-API functions from the core module
- matrix_wrap.cpp: add compile-time checks for CUDA/OpenGL calls
- the steps above allow to reduce FFmpeg wrapper size for ~1.5Mb (initial size of OpenCV part is about 3Mb)

backport is done to improve merge experience (less conflicts)
backport of commit: 65eb946756
2021-03-02 23:24:28 +00:00
Alexander Alekhin 2ab1f3f166 Merge pull request #19656 from alalek:update_version_3.4.14-pre 2021-03-02 21:44:19 +00:00
Alexander Alekhin a123c48d4d pre: OpenCV 3.4.14 (version++) 2021-03-02 20:47:29 +00:00
Alexander Alekhin 1c88e1fd19 Merge pull request #19661 from alalek:ffmpeg_fixes_3.4
* videoio(ffmpeg): eliminate MSVC build warnings

* videoio(ffmpeg): update initialization code

- repair FFmpeg logger settings on each .open() call
2021-03-02 20:41:05 +00:00
Rachel A cc22a73d0f EXR alpha support for 4 channel reading and writing. Issue https://github.com/opencv/opencv/issues/16115. 2021-03-02 11:49:56 -08:00
Alexander Alekhin ba7d0c5b23 Merge pull request #19659 from alalek:update_libtiff 2021-03-02 12:15:33 +00:00
Alexander Alekhin 5d499a185b Merge pull request #19658 from alalek:update_libwebp
* 3rdparty: update libwebp 1.1.0 => 1.2.0

- https://github.com/webmproject/libwebp/releases/tag/v1.2.0

* 3rdparty(libwebp): re-apply OpenCV patches
2021-03-02 12:14:56 +00:00
Alexander Alekhin eab8ac9a71 3rdparty: update libtiff 4.1.0 => 4.2.0
- https://gitlab.com/libtiff/libtiff/-/tags/v4.2.0
2021-03-01 23:19:00 +00:00
Alexander Alekhin 19865a26e5 Merge pull request #19642 from alalek:backport_19545 2021-02-28 21:37:30 +00:00
SamFC10 96947c30c0 Added exp layer
backport of commit: 6111935835
partial backport of commit: dd5976162b
2021-02-28 19:59:40 +00:00
Alexander Alekhin 19f1bac18c Merge pull request #19603 from federicohml:fix-ub-copy-make-const-border-8u 2021-02-27 17:32:42 +00:00
Alexander Alekhin b3b80f85fe Merge pull request #19636 from LaurentBerger:blendlinear_py 2021-02-27 17:31:59 +00:00
Federico Bolelli 9695165877 Merge pull request #19631 from prittt:sota-ccl
* Add Spaghetti algorithm for CCL

* Add stat tests for new and old algorithms

* Switch license header to short version
2021-02-27 17:27:24 +00:00
LaurentBerger 84080c12fd python binding blendLinear 2021-02-27 16:47:35 +00:00
Alexander Alekhin 1a855fed8f Merge pull request #19628 from alalek:fix_19566 2021-02-26 21:43:37 +00:00
Federico Martinez 773262bc09 Fix UB in CopyMakeConstBoder_8u
Caused by overflow of arithmetic operators conversion rank
2021-02-26 19:15:50 +00:00
Alexander Alekhin fadb25baf8 imgproc(warpAffine): avoid buffer indexes overflow in SIMD code 2021-02-25 20:16:50 +00:00
Alexander Alekhin 20a46b31cd Merge pull request #19625 from mshabunin:static-analysis-issues-34 2021-02-25 16:31:47 +00:00
Maksim Shabunin b2321576bc Fixed several issues found by static analysis 2021-02-25 15:44:15 +03:00
Alexander Alekhin 67b6ef4c2a Merge pull request #19503 from komakai:fix-android-putget 2021-02-24 21:07:13 +00:00
Alexander Alekhin 7ffc4b57aa Merge pull request #19535 from alalek:issue_18897 2021-02-23 22:42:51 +00:00
WeiChungChang d4d12164aa Merge pull request #19529 from WeiChungChang:3.4
* improve map allocation check

* fix accoring to CR
2021-02-23 21:09:55 +00:00
Alexander Alekhin 34d5746553 Merge pull request #19601 from alalek:hotfix_19536 2021-02-23 06:44:04 +03:00
Alexander Alekhin 86cb435adf dnn: fix build (nullptr issue) 2021-02-23 03:31:29 +00:00
Alexander Alekhin 513f5a8869 Merge pull request #19536 from WeiChungChang:ReduceMemory 2021-02-22 20:04:11 +00:00
Alexander Alekhin 1de02b9c57 Merge pull request #19564 from sturkmen72:patch-4 2021-02-22 20:02:40 +00:00
WeiChungChang f6bc4fd4c6 Merge pull request #19552 from WeiChungChang:partialSort
apply partial sort to save computations

* apply partial sort

* fix typo

* fix accroding to CR
2021-02-22 19:44:00 +03:00
Suleyman TURKMEN 9b399f3960 Update python samples 2021-02-21 23:02:16 +03:00
Larry Wei 98c2ccfaa3 Merge pull request #19586 from larryw3i:patch-2
* Update py_setup_in_ubuntu.markdown
2021-02-21 19:22:43 +00:00
Alexander Alekhin 309e1e2b1d core(InputArray): replace STD_ARRAY to MATX
- remove duplication kind
2021-02-21 19:12:21 +00:00
Sergey Krivohatskiy af13f61a43 Merge pull request #19580 from SergeyKrivohatskiy:patch-1
* Fixed OCL implementation of pyrlk

If prevPts size is (N, 1) (which is a default layout for converting `vector<Point2f>` to `UMat`) the `prevPts.cols == 1` and optical flow will be calculated for the first point only.
Getting `prevPts.total()` as in line 1048 is the correct way to get points count.

* fixed compilation warning (size_t to int)

Signed-off-by: Sergey Krivohatskiy <s.krivohatskiy@gmail.com>
2021-02-21 15:57:18 +00:00
Alexander Alekhin d093ac6a0f Merge pull request #19582 from alalek:backport_19572 2021-02-20 22:46:55 +00:00
Dale Phurrough 4badf640bf add noexcept to default constructors of cv::ocl
- follows iso c++ guideline C.44
- enables default compiler-created constructors to
  also be noexcept

original commit: 77e26a7db3

- handled KernelArg, Image2D
2021-02-20 16:20:25 +00:00
Alexander Alekhin 8f6ba5a089 Merge pull request #19541 from alalek:core_includes 2021-02-19 11:03:31 +00:00
Giles Payne 5cf08b0722 Fix/optimize Android put/get functions 2021-02-19 17:10:11 +09:00
Alexander Alekhin 0421c3991d Merge pull request #19534 from tomoaki0705:fixCudaFiltersRace 2021-02-18 19:41:21 +00:00
Alexander Alekhin 50a1a33d07 Merge pull request #19559 from APrigarina:calib3d_fix 2021-02-18 15:33:02 +00:00
APrigarina 96570820ef handle empty cameraMatrix 2021-02-18 16:18:19 +03:00
Anastasia M eb90186614 Merge pull request #19417 from LupusSanctus:am/text_graph_identity
* Corrected SSD text graph generation for Identity nodes

* Added minor code corrections
2021-02-17 18:01:41 +00:00
Alexander Alekhin 8d21c84e7d Merge pull request #19474 from aryanshomray:darknet_tanh 2021-02-17 17:10:44 +00:00
Aryansh Omray 601851cc7e TanH darknet and test 2021-02-17 18:49:52 +05:30
Alexander Alekhin 29f55810cf Merge pull request #19550 from Nico769:patch-1 2021-02-17 10:19:20 +00:00
Nicola Landolfi f76ba285c9 Fix single-word typo 2021-02-17 10:03:16 +01:00
Matt Alvarado 0a7a54f312 Merge pull request #19498 from mattalvarado:fix_findcirclesgrid
* Properly handle empty centers in findCirclesGrid

* Address alalek comments. Add unit test to validate bugfix

* fix build warnings, remove unrelated comment
2021-02-16 16:18:43 +00:00
Alexander Alekhin 5b16b190c1 Merge pull request #19543 from alalek:hotfix_19439 2021-02-16 16:05:09 +00:00
Alexander Alekhin 0885a79c28 imgcodecs(test): don't include png.h 2021-02-16 13:26:51 +00:00
Alexander Alekhin 6d3502833f core: include version.hpp in cvdef.h, fix precomp.hpp usage 2021-02-16 11:10:45 +00:00
Qoo bc8727786b save allocation of memory for fake image 2021-02-15 20:14:07 -05:00
Dan Ben-Yosef f0445295bd Merge pull request #19525 from danbey:Fix-cppcheck-error-in-carotete-lib
* Reduce if statement as it has the same expression on both sides of '&&'

If statement has the same expression on both sides so this can be reduce

Signed-off-by: Dan Ben Yosef <danbey@gmail.com>

* The if statement is to check width and height
2021-02-15 19:58:37 +00:00
Alexander Alekhin 5a06d679cf Merge pull request #19532 from amirtu:OCV-166_getDefaultName_overload 2021-02-15 15:33:54 +00:00
Alexander Alekhin 76cc034df2 Merge pull request #19519 from alalek:issue_19485 2021-02-15 15:15:27 +00:00
amir.tulegenov cbb230fdfc fix getDefaultName() 2021-02-15 19:21:53 +06:00
Tomoaki Teshima 5d1540f4fc remove danger race condition 2021-02-15 21:01:41 +09:00
Zhuo Zhang a5a421a9f1 Merge pull request #19522 from zchrissirhcz:3.4-fix-android-find-zlib-shared-since-ndk19
* fix find zlib.so instead of zlib.a when NDK >= 19

On Android platform, `libopencv_imgcodecs.a` is built, expected to
depend on `libz.so`. However, since Android NDK r19, NDK's `libz.a`
is found instead of `libz.so`, leading to link error
(not found libz.a) on machines without same NDK version & direcotry.

Since Android NDK-r19, toolchain pieces are installed to
`$NDK/toolchains/llvm/prebuilt/<host-tag>/...`, including `libz.so`.
Also installed to old paths (`<NDK>/platforms` and `<NDK>/sysroot`)
in NDK r19, r20, r21, but since NDK 22, old paths are removed.

- https://github.com/android/ndk/wiki/Changelog-r19
- https://github.com/android/ndk/wiki/Changelog-r22

With this commit, `libz.so` can be correctly found in NDK<19 and NDK>=19.

`ZLIB_LIBRARIES` is also simplified as `z`, by appending match (regex)
patterns for new toolchain installation directory's libz.so's paths.

* simplify libz.so match pattern for abbreviation
2021-02-14 21:38:53 +03:00
Zhuo Zhang 743099f9f9 Merge pull request #19521 from zchrissirhcz:3.4-fix-core-module-android-arm64-build
* fix core module android arm64 build

* fix core module android build when neon is off

When building for Android ARM platform, cmake with
`-D CV_DISABLE_OPTIMIZATION=ON`, the expected behavior is
not using ARM NEON, using naive computation instead.

This commit fix the un-expected compile error for neon intrinsincs.
2021-02-14 21:37:11 +03:00
Alexander Alekhin d2d6eba16a cmake: fix add_apple_compiler_options() calls and OBJCXX handling 2021-02-13 18:37:30 +00:00
Alexander Alekhin cceec84139 Merge pull request #19520 from WeiChungChang:refine 2021-02-13 18:18:12 +00:00
Qoo c909693d45 refine 2021-02-12 20:53:09 -05:00
Alexander Alekhin fba70f7991 Merge pull request #19515 from zchrissirhcz:3.4-fix-mislinked-zlib-in-vcpkg-by-adjust-link-order 2021-02-12 20:28:52 +00:00
Zhuo Zhang 84a290097b fix link order: put zlib after png/tiff/openexr
Previous link dependency: imgcodecs --> zlib --> libpng
this can generate imgcodecs shared lib, until Visual Studio integrated
with vcpkg, which will additionally specify LIBPATH, pointing to vcpkg
installed zlib (if any), which links the wrong zlib.

Fixed link dependency: imgcodecs --> libpng --> zlib
in this fixed case, symbols in zlib referenced in libpng will be found
in the build-from-source static zlib, instead of the vcpkg one.

related discussion:
- https://github.com/microsoft/vcpkg/issues/16165
- https://github.com/opencv/opencv/issues/17051
- https://github.com/opencv/opencv/issues/10576

MSVC linking order reference pages:
- https://docs.microsoft.com/en-us/cpp/build/reference/link-input-files?view=msvc-160
  for link order
- https://docs.microsoft.com/en-us/cpp/build/reference/linking?view=msvc-160
  LIB environment variable, for library file searching
- https://docs.microsoft.com/en-us/cpp/build/reference/libpath-additional-libpath?view=msvc-160
  LIBPATH option, for library file searching
2021-02-12 22:19:35 +08:00
Francesco Petrogalli 6ee23c9b85 Merge pull request #19486 from fpetrogalli:dotprod_fast-3.4
* [hal][neon] Optimize the v_dotprod_fast intrinsics for aarch64.

On Armv8 in AArch64 execution mode, we can skip the sequence

   v<op>_<ty>(vget_high_<ty>(x), vget_high_<ty>(y))

in favour of

   v<op>_high_<ty>(x, y)

This has better changes for recent compilers to use less data movement
operations and better register allocation. See for example:

   https://godbolt.org/z/bPq7vd

* [hal][neon] Fix build failure on armv7.

* [hal][neon] Address review comments in PR.

PR: https://github.com/opencv/opencv/pull/19486

* [hal][neon] Define macro to check for the AArch64 execution state of Armv8.

* [hal][neon] Fix macro definition for AArch64.

The fix is needed to prevent warnings when building for Armv7.
2021-02-11 13:24:09 +00:00
Alexander Alekhin cac5b0fe5a Merge pull request #19494 from derbosper:js-build-config-fix 2021-02-10 19:43:16 +00:00
Alexander Alekhin 93783df42a Merge pull request #19439 from raaldrid:Exif_support_for_PNG_issue_16579 2021-02-10 19:35:31 +00:00
Mieszko Boczkowski a3fb64d1cd Pass custom config file path as absolute 2021-02-10 12:45:35 +01:00
Alexander Alekhin 7079e7ea5e Merge pull request #19480 from vrabaud:3.4 2021-02-09 22:48:59 +00:00
Alexander Alekhin 4f39f8a8d0 Merge pull request #19488 from asmorkalov:as/nonfree_check 2021-02-09 20:38:30 +00:00
Alexander Alekhin 27bada6737 Merge pull request #19471 from sturkmen72:patch-5 2021-02-09 18:57:43 +00:00
Rachel A 650836d700 Exif parsing for PNG files to support Exif orientation tag. Moved decoder specific Exif parsing to JPEG and PNG decoders, respectively. Issue 16579 2021-02-09 10:35:27 -08:00
Alexander Smorkalov 3b9aebee11 Not not test stitiching with SURF, if NONFREE is disabled 2021-02-09 16:54:06 +03:00
Vincent Rabaud 847b16fb76 Disable thread sanitization when CV_USE_GLOBAL_WORKERS_COND_VAR is not set.
This fixes #19463
2021-02-09 14:12:39 +01:00
Suleyman TURKMEN 2387813428 Update imageSegmentation.cpp, imageSegmentation.py 2021-02-07 17:42:52 +03:00
Polina Smolnikova 0be18f5cb0 Merge pull request #19407 from rayonnant14:issue_19363
QRCodeDetector::decodeMulti() fixed invalid usage fixedType()

* fixed invalid usage fixedType()
changed default barcode type to CV_8UC1
added tests
added assert in case multi channel straight barcode input

* deleted extra wrap into OutputArray

* fix warnings

* objdetect(qr): remove unnecessary checks

Co-authored-by: Alexander Alekhin <alexander.a.alekhin@gmail.com>
2021-02-05 21:24:27 +00:00
Alexander Alekhin 4f08bb5046 Merge pull request #19428 from alalek:dnn_drop_misbehaved_clamp 2021-02-04 11:57:19 +00:00
Jebastin Nadar 09d2ca17cf Merge pull request #19449 from SamFC10:tf-leakyrelu
* add LeakyRelu to tf-importer

* fix whitespace error

* added test for leakyrelu
2021-02-04 08:50:08 +00:00
Alexander Alekhin 83aa711346 dnn: rename clamp() => normalize_axis() 2021-02-04 08:13:55 +00:00
Alexander Alekhin 863ecded30 Merge pull request #19440 from paroj:pyexcept 2021-02-03 11:08:24 +00:00
Alexander Alekhin 0a86ddc36c Merge pull request #19435 from l-bat:lb/onnx_normalize 2021-02-03 09:16:06 +00:00
Pavel Rojtberg 6c1a433c4c python: also catch general c++ exceptions
they might be thrown from third-party code (notably Ogre in the ovis
module).
While Linux is kind enough to print them, they cause instant termination
on Windows.
Arguably, they do not origin from OpenCV itself, but still this helps
understanding what went wrong when calling an OpenCV function.
2021-02-02 21:16:01 +01:00
Alexander Alekhin 23734aff74 Merge pull request #19443 from asmorkalov:as/guard_nonfree 2021-02-02 11:12:14 +00:00
Alexander Smorkalov 0016c25b58 Guard non-free usage in stitching as contrib can be built without it. 2021-02-02 13:24:59 +03:00
Liubov Batanina 68eb54dc13 Added ONNX NormalizeL2 subgraph 2021-02-01 12:44:48 +03:00
Liangda-w b08d67c4e1 Merge pull request #19419 from Liangda-w:patch-1
* Fix error in documentation for RGB->HSV convertion

* Update colors.markdown
2021-02-01 09:17:54 +00:00
Alexander Alekhin 5ab4623c2a Merge pull request #19430 from alalek:fixup_19216 2021-01-31 17:41:24 +00:00
Alexander Alekhin cdf73f2e05 Merge pull request #19427 from alalek:issue_19426 2021-01-31 14:24:37 +00:00
Alexander Alekhin 30bef20e22 js: fix SIMD build 2021-01-31 00:12:51 +00:00
Alexander Alekhin 4be077163f Merge pull request #19424 from alalek:cmake_linters_update 2021-01-30 12:37:57 +00:00
Alexander Alekhin b9dfffc237 Merge pull request #19057 from sl-sergei:changes_for_cuda_1d 2021-01-30 11:39:43 +00:00
Alexander Alekhin c5bf15e009 build: fix cv2.cpp compilation 2021-01-30 11:32:27 +00:00
Sergey Slashchinin e2949c7d0a Align 3.4 branch with master 2021-01-29 23:48:08 +03:00
Alexander Alekhin e448f4f6ef cmake: fix pylint/flake8 detection, update flake8 exclude 2021-01-29 17:06:54 +00:00
Alexander Alekhin ebd91459f2 Merge pull request #19395 from Ixarias:patch-1 2021-01-29 12:34:00 +00:00
Alexander Alekhin ff8a624189 Merge pull request #19404 from LupusSanctus:am/text_graph_preproc 2021-01-27 18:32:33 +00:00
Anastasia Murzova 449ebc1b70 Corrected SSD text graph generation 2021-01-27 19:53:52 +03:00
Ixarias 3f14341629 Change Keymap wording for gray image in curve mode
Instead of being a copy of line 76, line 79 instead correctly indicates that it will show a histogram for a gray image in curve mode, as given by the code block at line 103 referencing image "gray" instead of image "im".
2021-01-26 16:30:50 -06:00
Alexander Alekhin ca9cbab532 Merge pull request #19403 from diablodale:fix_19402_python_test_filter_34 2021-01-26 19:23:12 +00:00
Dale Phurrough 5c70a2015f fix python test runner wildcard handling
* fix opencv/opencv#19402
2021-01-26 19:05:40 +01:00
Alexander Alekhin 573812d0ff Merge pull request #19373 from l-bat:lb/tf_matmul_shared 2021-01-25 22:08:24 +00:00
Liubov Batanina c12930cdde Merge pull request #19372 from l-bat:lb/onnx_pads_calc
* Fixed bug with constant Div

* Supported constant mul and div for inputs with different shapes
2021-01-25 22:07:50 +00:00
Alexander Alekhin 857f339914 Merge pull request #19385 from alalek:ocl_isOpenCLActivated_update 2021-01-25 13:54:00 +00:00
Alexander Alekhin b1ffe7a153 Merge pull request #19390 from tomoaki0705:fixCudaLegacyCalib3d 2021-01-25 13:32:43 +00:00
Alexander Alekhin 62b60b11bb Merge pull request #19344 from VadimLevin:dev/vlevin/generic-sequence-conversion 2021-01-25 08:22:57 +00:00
Tomoaki Teshima 96e0902f39 fix peaky test failure
* follow the review comment
2021-01-25 17:14:37 +09:00
Vadim Levin 1d3207d7c7 feat: common fixed size sequence conversion for Python bindings 2021-01-25 08:08:38 +03:00
Alexander Alekhin fb0abdeb4f Merge pull request #19383 from tomoaki0705:fixWrongIndex 2021-01-24 15:23:34 +00:00
Alexander Alekhin 331f1b9961 Merge pull request #19382 from crackwitz:highgui-w32-remove-gutter 2021-01-24 15:23:04 +00:00
Tomoaki Teshima 3cfe7b9af9 fix wrong index 2021-01-24 20:29:52 +09:00
Alexander Alekhin 37e656082b core(ocl): update isOpenCLActivated()
- reuse g_isOpenCLAvailable variable instead
2021-01-24 01:25:17 +00:00
Christoph Rackwitz 0c0cf8b19f highgui: remove gutter in window_w32 2021-01-23 16:01:07 +01:00
Alexander Alekhin bbad38b2c5 Merge pull request #19376 from alalek:fixup_19105 2021-01-22 20:22:36 +00:00
Alexander Alekhin 413febf657 Merge pull request #19334 from alalek:fix_19134 2021-01-22 20:05:58 +00:00
Alexander Alekhin d5447d859f js(doc): fix path 2021-01-22 19:50:25 +00:00
Liubov Batanina 38a49f92ab Added shared weights for MatMul 2021-01-22 16:47:02 +03:00
Alexander Alekhin 0f968e3b6d Merge pull request #19352 from mshabunin:new-forum-links 2021-01-19 21:56:42 +00:00
Maksim Shabunin f65d75f5c8 Updated more links to forum.opencv.org 2021-01-19 21:55:45 +03:00
Alexander Alekhin 291dbdfbe6 Merge pull request #19336 from kyshel:patch-1 2021-01-18 20:16:04 +00:00
Alexander Alekhin 6ce9bb6f7a Merge pull request #19312 from VadimLevin:dev/vlevin/clear-msg-for-failed-overload-resolution 2021-01-18 20:14:10 +00:00
Vadim Levin a0bdb78a99 feat: add overload resolution exception for Python bindings 2021-01-18 16:29:17 +03:00
kyshel 321f26f450 update xrange() to range()
update xrange() to range() as Python 2 has been deprecate, more info:
1.  Python 2 has been no longer supported officially since January 1, 2020.  Check  https://www.python.org/doc/sunset-python-2/
2.  xrange() was renamed to range() in Python 3. Check  https://stackoverflow.com/questions/17192158/nameerror-global-name-xrange-is-not-defined-in-python-3/17192181#17192181

update xrange() to range()

Update py_fourier_transform.markdown

update xrange() to range()
2021-01-18 19:52:37 +08:00
Alexander Alekhin 212815a10d core(ocl): fix lifetime handling of Image kernel args 2021-01-18 06:24:36 +00:00
Alexander Alekhin 104e64dd0f Merge pull request #19339 from ichisadashioko:modules_highgui_src_window_w32_typo 2021-01-17 22:00:00 +00:00
shioko 5967acc9ca fix typo of the word storage 2021-01-17 18:59:20 +00:00
Alexander Alekhin eea4397b12 Merge pull request #19332 from alalek:xcode_ccache 2021-01-16 18:58:02 +00:00
Alexander Alekhin a122a53e72 Merge pull request #19330 from l-bat:lb/onnx_mish_subgraph 2021-01-16 18:42:19 +00:00
Alexander Alekhin 8215380336 cmake: support ccache with Xcode generator 2021-01-15 19:58:01 +00:00
Liubov Batanina af9597f454 Added Mish ONNX subgraph 2021-01-15 14:01:48 +03:00
Francesco Petrogalli 235e648bf5 Merge pull request #19268 from fpetrogalli:tabs-summary-output
* [ts][summary.py] Extend `-o` to support tabs separated output.

* [ts][summary.py] Improve TABS sepatated output.

There is no need to print TAB at the beginning and at the end of each
row in the table.

Cosmetic change: using python list comprehension instead of for loop
to process a single row.
2021-01-14 12:01:36 +00:00
Alexander Alekhin fbcc532de5 Merge pull request #19300 from alkasm:patch-2 2021-01-12 18:28:58 +00:00
Alexander Alekhin 72894a1a90 Merge pull request #19216 from terfendail:wasm_fall 2021-01-12 17:57:24 +00:00
Alexander Reynolds e3856dfe5d hotfix: call isOpened() in python bg sub tutorial
https://github.com/opencv/opencv/issues/19299
2021-01-11 14:04:56 -08:00
Alexander Alekhin 62420b900e Merge pull request #19301 from krush11:3.4 2021-01-11 20:58:33 +00:00
Alexander Alekhin 89ef676613 Merge pull request #19297 from raaldrid:Template_Match_Tutorial_fix_17739 2021-01-11 20:54:54 +00:00
Alexander Alekhin 83e14f602f Merge pull request #19296 from raaldrid:Doc_issue_fix_18836_FULL 2021-01-11 20:04:49 +00:00
Alexander Alekhin 5389309d40 Merge pull request #19291 from gpiffault:docs-js_usage-fix_imshow 2021-01-11 20:03:29 +00:00
Alexander Alekhin 058460ddf4 Merge pull request #19248 from LaurentBerger:forum 2021-01-11 20:02:51 +00:00
Rachel A 380009ac58 Template Matching Tutorial issue fix https://github.com/opencv/opencv/issues/17739 2021-01-11 11:19:59 -08:00
Alexander Alekhin 2775099a32 Merge pull request #19220 from alalek:dnn_tf_importer_error_reporting 2021-01-11 19:12:41 +00:00
Rachel A f98e567f49 Solution to documentation issue https://github.com/opencv/opencv/issues/18836 2021-01-11 10:43:26 -08:00
LaurentBerger 9fb48d5f44 update forum link 2021-01-11 18:39:46 +00:00
Vitaly Tuzov 8f653ba8de Inlined WASM fallback intrinsics to avoid using of V_TypeTraits 2021-01-11 18:12:21 +03:00
krush11 87b3b48fe0 added multi-config to regexp 2021-01-10 11:11:23 +05:30
Grégoire Piffault 0043d9bf13 docs(tutorial_js_usage): fix imshow usage 2021-01-09 14:53:35 +01:00
notmatthancock 2d2d72afbb Merge pull request #19258 from notmatthancock:doc/update-sift-patent-blurb
* Remove sentences about SIFT patent and code location

* Add note about patent in opencv-specific section
2021-01-05 11:33:57 +00:00
Alexander Alekhin 4f9cb3871a copyright: 2021 2021-01-01 13:40:32 +00:00
Alexander Alekhin 5b598c1812 Merge pull request #19239 from justinchuby:justinchuby-doc-typo-hough-lines 2020-12-31 10:33:59 +00:00
Justin Chu 8f66dad65b Fix typo in hough_lines tutorial
Argument `minLinLength` -> `minLineLength`
2020-12-30 16:20:27 -05:00
Alexander Alekhin 55f06b76f9 dnn: improve debugging of TensorFlow parsing errors 2020-12-26 15:31:30 +00:00
Zhuo Zhang 6e1da2ef91 Merge pull request #19203 from zchrissirhcz:fix-cvSaveImage
Fix cvSaveImage( ) function bug

* fix cvSaveImage crash

* replace emplace_back with {}, no C++11 required

* fix MacOSX build with vector's push_back
2020-12-24 16:58:16 +00:00
Alexander Alekhin 1ec2ade65b Merge pull request #19210 from alalek:backport_19199 2020-12-24 10:01:37 +00:00
Alexander Alekhin 13148df9f2 Merge pull request #19208 from alalek:js_build_reuse_python 2020-12-24 10:01:17 +00:00
Alexander Alekhin 5a10261111 Merge pull request #19207 from alalek:issue_19198 2020-12-24 10:00:56 +00:00
Ilya Lavrenov 064d48771d Find only shared IE libraries, not plugins
original commit: 3ed376d103
2020-12-24 06:48:54 +00:00
Alexander Alekhin 7eeba4d485 js(build): reuse Python executable used to run main script
- don't switch between Python versions in the middle of the build
2020-12-24 05:25:38 +00:00
Alexander Alekhin 0681deb3c9 js: fix Python 3 support in make_umd.py 2020-12-23 15:07:12 +00:00
Alexander Alekhin 0ffa78b66a Merge pull request #19193 from alalek:samples_python_3.9 2020-12-23 12:09:07 +00:00
Alexander Alekhin b51ae87828 samples: check for Python 3.9 2020-12-21 14:59:34 +00:00
Alexander Alekhin 68fb8dd873 Merge tag '3.4.13' 2020-12-21 14:55:54 +00:00
465 changed files with 20892 additions and 8808 deletions
+2 -2
View File
@@ -1,5 +1,5 @@
<!--
If you have a question rather than reporting a bug please go to http://answers.opencv.org where you get much faster responses.
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.
@@ -27,4 +27,4 @@ This is a template helping you to create an issue which can be processed as quic
// C++ code example
```
or attach as .txt or .zip file
-->
-->
+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) && (wr == 2.0f))
if ((wr == 2.0f) && (hr == 2.0f))
{
#ifndef __ANDROID__
size_t roiw16 = dsize.width >= 15 ? (dsize.width - 15) * 3 : 0;
+5 -5
View File
@@ -1,8 +1,8 @@
# Binaries branch name: ffmpeg/3.4_20200907
# Binaries were created for OpenCV: 03bee14372f5537daa56c62e771ec16181ca1f98
ocv_update(FFMPEG_BINARIES_COMMIT "2a96257b743695a47f8012aab1ffb995a1dee8b4")
ocv_update(FFMPEG_FILE_HASH_BIN32 "5e68a3ff82f43ac6524e50e448a34c9c")
ocv_update(FFMPEG_FILE_HASH_BIN64 "205db629d893e7d4865fd1459807ff47")
# Binaries branch name: ffmpeg/3.4_20210302
# Binaries were created for OpenCV: 2ab1f3f166fccc3a01497209cc01c5cea44ff201
ocv_update(FFMPEG_BINARIES_COMMIT "e99214251d9f3cde7c48abd46b2259bddc9885b6")
ocv_update(FFMPEG_FILE_HASH_BIN32 "fad5ada9be36120bba8966709e7953a8")
ocv_update(FFMPEG_FILE_HASH_BIN64 "650e2272728491923e566f784f79cfef")
ocv_update(FFMPEG_FILE_HASH_CMAKE "3b90f67f4b429e77d3da36698cef700c")
function(download_win_ffmpeg script_var)
+3 -4
View File
@@ -3,10 +3,10 @@ project(${JPEG_LIBRARY} C)
ocv_warnings_disable(CMAKE_C_FLAGS -Wunused-parameter -Wsign-compare -Wshorten-64-to-32 -Wimplicit-fallthrough)
set(VERSION_MAJOR 2)
set(VERSION_MINOR 0)
set(VERSION_REVISION 6)
set(VERSION_MINOR 1)
set(VERSION_REVISION 0)
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION})
set(LIBJPEG_TURBO_VERSION_NUMBER 2000006)
set(LIBJPEG_TURBO_VERSION_NUMBER 2001000)
string(TIMESTAMP BUILD "opencv-${OPENCV_VERSION}-libjpeg-turbo")
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
@@ -46,7 +46,6 @@ 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()
+1 -1
View File
@@ -91,7 +91,7 @@ best of our understanding.
The Modified (3-clause) BSD License
===================================
Copyright (C)2009-2020 D. R. Commander. All Rights Reserved.
Copyright (C)2009-2021 D. R. Commander. All Rights Reserved.<br>
Copyright (C)2015 Viktor Szathmáry. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
+1 -14
View File
@@ -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-2016, Thomas G. Lane, Guido Vollbeding.
This software is copyright (C) 1991-2020, Thomas G. Lane, Guido Vollbeding.
All Rights Reserved except as specified below.
Permission is hereby granted to use, copy, modify, and distribute this
@@ -159,19 +159,6 @@ 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
==========
+1 -1
View File
@@ -3,7 +3,7 @@ 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 and x86-64
MIPS systems, as well as progressive JPEG compression on x86, x86-64, and Arm
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
-5
View File
@@ -61,11 +61,6 @@
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 */
-1
View File
@@ -18,7 +18,6 @@
#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 */
+9 -9
View File
@@ -48,9 +48,9 @@ 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 = GETJSAMPLE(inptr[RGB_RED]);
g = GETJSAMPLE(inptr[RGB_GREEN]);
b = GETJSAMPLE(inptr[RGB_BLUE]);
r = inptr[RGB_RED];
g = inptr[RGB_GREEN];
b = inptr[RGB_BLUE];
inptr += RGB_PIXELSIZE;
/* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
* must be too; we do not need an explicit range-limiting operation.
@@ -100,9 +100,9 @@ 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 = GETJSAMPLE(inptr[RGB_RED]);
g = GETJSAMPLE(inptr[RGB_GREEN]);
b = GETJSAMPLE(inptr[RGB_BLUE]);
r = inptr[RGB_RED];
g = inptr[RGB_GREEN];
b = inptr[RGB_BLUE];
inptr += RGB_PIXELSIZE;
/* Y */
outptr[col] = (JSAMPLE)((ctab[r + R_Y_OFF] + ctab[g + G_Y_OFF] +
@@ -135,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] = GETJSAMPLE(inptr[RGB_RED]);
outptr1[col] = GETJSAMPLE(inptr[RGB_GREEN]);
outptr2[col] = GETJSAMPLE(inptr[RGB_BLUE]);
outptr0[col] = inptr[RGB_RED];
outptr1[col] = inptr[RGB_GREEN];
outptr2[col] = inptr[RGB_BLUE];
inptr += RGB_PIXELSIZE;
}
}
+6 -6
View File
@@ -392,11 +392,11 @@ 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 - GETJSAMPLE(inptr[0]);
g = MAXJSAMPLE - GETJSAMPLE(inptr[1]);
b = MAXJSAMPLE - GETJSAMPLE(inptr[2]);
r = MAXJSAMPLE - inptr[0];
g = MAXJSAMPLE - inptr[1];
b = MAXJSAMPLE - inptr[2];
/* K passes through as-is */
outptr3[col] = inptr[3]; /* don't need GETJSAMPLE here */
outptr3[col] = inptr[3];
inptr += 4;
/* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
* must be too; we do not need an explicit range-limiting operation.
@@ -438,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]; /* don't need GETJSAMPLE() here */
outptr[col] = inptr[0];
inptr += instride;
}
}
@@ -497,7 +497,7 @@ null_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
inptr = *input_buf;
outptr = output_buf[ci][output_row];
for (col = 0; col < num_cols; col++) {
outptr[col] = inptr[ci]; /* don't need GETJSAMPLE() here */
outptr[col] = inptr[ci];
inptr += nc;
}
}
+18 -19
View File
@@ -381,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++ = 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;
*workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
#else
{
register int elemc;
for (elemc = DCTSIZE; elemc > 0; elemc--)
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
}
#endif
}
@@ -533,20 +533,19 @@ convsamp_float(JSAMPARRAY sample_data, JDIMENSION start_col,
for (elemr = 0; elemr < DCTSIZE; elemr++) {
elemptr = sample_data[elemr] + start_col;
#if DCTSIZE == 8 /* unroll the inner loop */
*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);
*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);
#else
{
register int elemc;
for (elemc = DCTSIZE; elemc > 0; elemc--)
*workspaceptr++ = (FAST_FLOAT)
(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE);
}
#endif
}
+220 -180
View File
@@ -4,8 +4,10 @@
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-1997, Thomas G. Lane.
* libjpeg-turbo Modifications:
* Copyright (C) 2009-2011, 2014-2016, 2018-2019, D. R. Commander.
* Copyright (C) 2009-2011, 2014-2016, 2018-2021, D. R. Commander.
* Copyright (C) 2015, Matthieu Darbois.
* Copyright (C) 2018, Matthias Räncker.
* Copyright (C) 2020, Arm Limited.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -42,15 +44,19 @@
* flags (this defines __thumb__).
*/
/* NOTE: Both GCC and Clang define __GNUC__ */
#if defined(__GNUC__) && (defined(__arm__) || defined(__aarch64__))
#if defined(__arm__) || defined(__aarch64__) || defined(_M_ARM) || \
defined(_M_ARM64)
#if !defined(__thumb__) || defined(__thumb2__)
#define USE_CLZ_INTRINSIC
#endif
#endif
#ifdef USE_CLZ_INTRINSIC
#if defined(_MSC_VER) && !defined(__clang__)
#define JPEG_NBITS_NONZERO(x) (32 - _CountLeadingZeros(x))
#else
#define JPEG_NBITS_NONZERO(x) (32 - __builtin_clz(x))
#endif
#define JPEG_NBITS(x) (x ? JPEG_NBITS_NONZERO(x) : 0)
#else
#include "jpeg_nbits_table.h"
@@ -65,32 +71,43 @@
* 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 {
size_t put_buffer; /* current bit-accumulation buffer */
int put_bits; /* # of bits now in it */
union {
bit_buf_type c;
simd_bit_buf_type simd;
} put_buffer; /* current bit accumulation buffer */
int free_bits; /* # of bits available in it */
/* (Neon GAS: # 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 */
@@ -123,6 +140,7 @@ 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 */
int simd;
} working_state;
@@ -201,8 +219,17 @@ start_pass_huff(j_compress_ptr cinfo, boolean gather_statistics)
}
/* Initialize bit buffer to empty */
entropy->saved.put_buffer = 0;
entropy->saved.put_bits = 0;
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 {
entropy->saved.put_buffer.c = 0;
entropy->saved.free_bits = BIT_BUF_SIZE;
}
/* Initialize restart stuff */
entropy->restarts_to_go = cinfo->restart_interval;
@@ -287,6 +314,7 @@ 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.
*/
MEMZERO(dtbl->ehufco, sizeof(dtbl->ehufco));
MEMZERO(dtbl->ehufsi, sizeof(dtbl->ehufsi));
/* This is also a convenient place to check for out-of-range
@@ -334,94 +362,94 @@ dump_buffer(working_state *state)
/* Outputting bits to the file */
/* 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.
/* 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.
*/
#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; \
#define EMIT_BYTE(b) { \
buffer[0] = (JOCTET)(b); \
buffer[1] = 0; \
buffer -= -2 + ((JOCTET)(b) < 0xFF); \
}
#define PUT_BITS(code, size) { \
put_bits += size; \
put_buffer = (put_buffer << size) | code; \
}
/* 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
#if SIZEOF_SIZE_T != 8 && !defined(_WIN64)
#define CHECKBUF15() { \
if (put_bits > 15) { \
EMIT_BYTE() \
EMIT_BYTE() \
#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; \
} \
}
#endif
#define CHECKBUF31() { \
if (put_bits > 31) { \
EMIT_BYTE() \
EMIT_BYTE() \
EMIT_BYTE() \
EMIT_BYTE() \
} \
}
#define CHECKBUF47() { \
if (put_bits > 47) { \
EMIT_BYTE() \
EMIT_BYTE() \
EMIT_BYTE() \
EMIT_BYTE() \
EMIT_BYTE() \
EMIT_BYTE() \
} \
}
#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() \
#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; \
} \
}
#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; \
}
/* 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 PUT_CODE(code, size) { \
temp &= (((JLONG)1) << nbits) - 1; \
temp |= code << nbits; \
nbits += size; \
PUT_BITS(temp, nbits) \
}
/* 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
@@ -444,6 +472,7 @@ dump_buffer(working_state *state)
#define STORE_BUFFER() { \
if (localbuf) { \
size_t bytes, bytestocopy; \
bytes = buffer - _buffer; \
buffer = _buffer; \
while (bytes > 0) { \
@@ -466,20 +495,46 @@ dump_buffer(working_state *state)
LOCAL(boolean)
flush_bits(working_state *state)
{
JOCTET _buffer[BUFSIZE], *buffer;
size_t put_buffer; int put_bits;
size_t bytes, bytestocopy; int localbuf = 0;
JOCTET _buffer[BUFSIZE], *buffer, temp;
simd_bit_buf_type put_buffer; int put_bits;
int localbuf = 0;
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 {
put_bits = BIT_BUF_SIZE - 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()
/* fill any partial byte with ones */
PUT_BITS(0x7F, 7)
while (put_bits >= 8) EMIT_BYTE()
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)
}
state->cur.put_buffer = 0; /* and reset bit-buffer to empty */
state->cur.put_bits = 0;
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 {
state->cur.put_buffer.c = 0;
state->cur.free_bits = BIT_BUF_SIZE;
}
STORE_BUFFER()
return TRUE;
@@ -493,7 +548,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;
size_t bytes, bytestocopy; int localbuf = 0;
int localbuf = 0;
LOAD_BUFFER()
@@ -509,53 +564,41 @@ LOCAL(boolean)
encode_one_block(working_state *state, JCOEFPTR block, int last_dc_val,
c_derived_tbl *dctbl, c_derived_tbl *actbl)
{
int temp, temp2, temp3;
int nbits;
int r, code, size;
int temp, nbits, free_bits;
bit_buf_type put_buffer;
JOCTET _buffer[BUFSIZE], *buffer;
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;
int localbuf = 0;
put_buffer = state->cur.put_buffer;
put_bits = state->cur.put_bits;
free_bits = state->cur.free_bits;
put_buffer = state->cur.put_buffer.c;
LOAD_BUFFER()
/* Encode the DC coefficient difference per section F.1.2.1 */
temp = temp2 = block[0] - last_dc_val;
temp = 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.
* Agner Fog. This code assumes we are on a two's complement machine.
*/
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;
nbits = temp >> (CHAR_BIT * sizeof(int) - 1);
temp += nbits;
nbits ^= temp;
/* Find the number of bits needed for the magnitude of the coefficient */
nbits = JPEG_NBITS(temp);
nbits = JPEG_NBITS(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)
/* 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])
/* Encode the AC coefficients per section F.1.2.2 */
r = 0; /* r = run length of zeros */
{
int 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
@@ -563,51 +606,46 @@ 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++; \
r += 16; \
} else { \
temp2 = temp; \
/* Branch-less absolute value, bitwise complement, etc., same as above */ \
temp3 = temp >> (CHAR_BIT * sizeof(int) - 1); \
temp ^= temp3; \
temp -= temp3; \
temp2 += temp3; \
nbits = JPEG_NBITS_NONZERO(temp); \
nbits = temp >> (CHAR_BIT * sizeof(int) - 1); \
temp += nbits; \
nbits ^= temp; \
nbits = JPEG_NBITS_NONZERO(nbits); \
/* if run length > 15, must emit special run-length-16 codes (0xF0) */ \
while (r > 15) { \
EMIT_BITS(code_0xf0, size_0xf0) \
r -= 16; \
while (r >= 16 * 16) { \
r -= 16 * 16; \
PUT_BITS(actbl->ehufco[0xf0], actbl->ehufsi[0xf0]) \
} \
/* Emit Huffman symbol for run length / number of bits */ \
temp3 = (r << 4) + nbits; \
code = actbl->ehufco[temp3]; \
size = actbl->ehufsi[temp3]; \
EMIT_CODE(code, size) \
r += nbits; \
PUT_CODE(actbl->ehufco[r], actbl->ehufsi[r]) \
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) {
code = actbl->ehufco[0];
size = actbl->ehufsi[0];
EMIT_BITS(code, size)
/* If the last coef(s) were zero, emit an end-of-block code */
if (r > 0) {
PUT_BITS(actbl->ehufco[0], actbl->ehufsi[0])
}
}
state->cur.put_buffer = put_buffer;
state->cur.put_bits = put_bits;
state->cur.put_buffer.c = put_buffer;
state->cur.free_bits = free_bits;
STORE_BUFFER()
return TRUE;
@@ -654,8 +692,9 @@ 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;
ASSIGN_STATE(state.cur, entropy->saved);
state.cur = entropy->saved;
state.cinfo = cinfo;
state.simd = entropy->simd;
/* Emit restart marker if needed */
if (cinfo->restart_interval) {
@@ -694,7 +733,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;
ASSIGN_STATE(entropy->saved, state.cur);
entropy->saved = state.cur;
/* Update restart-interval state too */
if (cinfo->restart_interval) {
@@ -723,8 +762,9 @@ 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;
ASSIGN_STATE(state.cur, entropy->saved);
state.cur = entropy->saved;
state.cinfo = cinfo;
state.simd = entropy->simd;
/* Flush out the last data */
if (!flush_bits(&state))
@@ -733,7 +773,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;
ASSIGN_STATE(entropy->saved, state.cur);
entropy->saved = state.cur;
}
+16 -9
View File
@@ -4,8 +4,9 @@
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1995-1997, Thomas G. Lane.
* libjpeg-turbo Modifications:
* Copyright (C) 2011, 2015, 2018, D. R. Commander.
* Copyright (C) 2011, 2015, 2018, 2021, D. R. Commander.
* Copyright (C) 2016, 2018, Matthieu Darbois.
* Copyright (C) 2020, Arm Limited.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -51,15 +52,19 @@
* flags (this defines __thumb__).
*/
/* NOTE: Both GCC and Clang define __GNUC__ */
#if defined(__GNUC__) && (defined(__arm__) || defined(__aarch64__))
#if defined(__arm__) || defined(__aarch64__) || defined(_M_ARM) || \
defined(_M_ARM64)
#if !defined(__thumb__) || defined(__thumb2__)
#define USE_CLZ_INTRINSIC
#endif
#endif
#ifdef USE_CLZ_INTRINSIC
#if defined(_MSC_VER) && !defined(__clang__)
#define JPEG_NBITS_NONZERO(x) (32 - _CountLeadingZeros(x))
#else
#define JPEG_NBITS_NONZERO(x) (32 - __builtin_clz(x))
#endif
#define JPEG_NBITS(x) (x ? JPEG_NBITS_NONZERO(x) : 0)
#else
#include "jpeg_nbits_table.h"
@@ -169,24 +174,26 @@ INLINE
METHODDEF(int)
count_zeroes(size_t *x)
{
int result;
#if defined(HAVE_BUILTIN_CTZL)
int result;
result = __builtin_ctzl(*x);
*x >>= result;
#elif defined(HAVE_BITSCANFORWARD64)
unsigned long result;
_BitScanForward64(&result, *x);
*x >>= result;
#elif defined(HAVE_BITSCANFORWARD)
unsigned long result;
_BitScanForward(&result, *x);
*x >>= result;
#else
result = 0;
int result = 0;
while ((*x & 1) == 0) {
++result;
*x >>= 1;
}
#endif
return result;
return (int)result;
}
@@ -860,7 +867,7 @@ encode_mcu_AC_refine_prepare(const JCOEF *block,
#define ENCODE_COEFS_AC_REFINE(label) { \
while (zerobits) { \
int idx = count_zeroes(&zerobits); \
idx = count_zeroes(&zerobits); \
r += idx; \
cabsvalue += idx; \
signbits >>= idx; \
@@ -917,7 +924,7 @@ METHODDEF(boolean)
encode_mcu_AC_refine(j_compress_ptr cinfo, JBLOCKROW *MCU_data)
{
phuff_entropy_ptr entropy = (phuff_entropy_ptr)cinfo->entropy;
register int temp, r;
register int temp, r, idx;
char *BR_buffer;
unsigned int BR;
int Sl = cinfo->Se - cinfo->Ss + 1;
@@ -968,7 +975,7 @@ encode_mcu_AC_refine(j_compress_ptr cinfo, JBLOCKROW *MCU_data)
if (zerobits) {
int diff = ((absvalues + DCTSIZE2 / 2) - cabsvalue);
int idx = count_zeroes(&zerobits);
idx = count_zeroes(&zerobits);
signbits >>= idx;
idx += diff;
r += idx;
+23 -40
View File
@@ -6,7 +6,7 @@
* libjpeg-turbo Modifications:
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
* Copyright (C) 2014, MIPS Technologies, Inc., California.
* Copyright (C) 2015, D. R. Commander.
* Copyright (C) 2015, 2019, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -103,7 +103,7 @@ expand_right_edge(JSAMPARRAY image_data, int num_rows, JDIMENSION input_cols,
if (numcols > 0) {
for (row = 0; row < num_rows; row++) {
ptr = image_data[row] + input_cols;
pixval = ptr[-1]; /* don't need GETJSAMPLE() here */
pixval = ptr[-1];
for (count = numcols; count > 0; count--)
*ptr++ = pixval;
}
@@ -174,7 +174,7 @@ int_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
for (v = 0; v < v_expand; v++) {
inptr = input_data[inrow + v] + outcol_h;
for (h = 0; h < h_expand; h++) {
outvalue += (JLONG)GETJSAMPLE(*inptr++);
outvalue += (JLONG)(*inptr++);
}
}
*outptr++ = (JSAMPLE)((outvalue + numpix2) / numpix);
@@ -237,8 +237,7 @@ h2v1_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
inptr = input_data[outrow];
bias = 0; /* bias = 0,1,0,1,... for successive samples */
for (outcol = 0; outcol < output_cols; outcol++) {
*outptr++ =
(JSAMPLE)((GETJSAMPLE(*inptr) + GETJSAMPLE(inptr[1]) + bias) >> 1);
*outptr++ = (JSAMPLE)((inptr[0] + inptr[1] + bias) >> 1);
bias ^= 1; /* 0=>1, 1=>0 */
inptr += 2;
}
@@ -277,8 +276,7 @@ h2v2_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
bias = 1; /* bias = 1,2,1,2,... for successive samples */
for (outcol = 0; outcol < output_cols; outcol++) {
*outptr++ =
(JSAMPLE)((GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]) + bias) >> 2);
(JSAMPLE)((inptr0[0] + inptr0[1] + inptr1[0] + inptr1[1] + bias) >> 2);
bias ^= 3; /* 1=>2, 2=>1 */
inptr0 += 2; inptr1 += 2;
}
@@ -337,33 +335,25 @@ h2v2_smooth_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
below_ptr = input_data[inrow + 2];
/* Special case for first column: pretend column -1 is same as column 0 */
membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[2]) +
GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[2]);
membersum = inptr0[0] + inptr0[1] + inptr1[0] + inptr1[1];
neighsum = above_ptr[0] + above_ptr[1] + below_ptr[0] + below_ptr[1] +
inptr0[0] + inptr0[2] + inptr1[0] + inptr1[2];
neighsum += neighsum;
neighsum += GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[2]) +
GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[2]);
neighsum += above_ptr[0] + above_ptr[2] + below_ptr[0] + below_ptr[2];
membersum = membersum * memberscale + neighsum * neighscale;
*outptr++ = (JSAMPLE)((membersum + 32768) >> 16);
inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2;
for (colctr = output_cols - 2; colctr > 0; colctr--) {
/* sum of pixels directly mapped to this output element */
membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
membersum = inptr0[0] + inptr0[1] + inptr1[0] + inptr1[1];
/* sum of edge-neighbor pixels */
neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[2]) +
GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[2]);
neighsum = above_ptr[0] + above_ptr[1] + below_ptr[0] + below_ptr[1] +
inptr0[-1] + inptr0[2] + inptr1[-1] + inptr1[2];
/* The edge-neighbors count twice as much as corner-neighbors */
neighsum += neighsum;
/* Add in the corner-neighbors */
neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[2]) +
GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[2]);
neighsum += above_ptr[-1] + above_ptr[2] + below_ptr[-1] + below_ptr[2];
/* form final output scaled up by 2^16 */
membersum = membersum * memberscale + neighsum * neighscale;
/* round, descale and output it */
@@ -372,15 +362,11 @@ h2v2_smooth_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
}
/* Special case for last column */
membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[1]) +
GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[1]);
membersum = inptr0[0] + inptr0[1] + inptr1[0] + inptr1[1];
neighsum = above_ptr[0] + above_ptr[1] + below_ptr[0] + below_ptr[1] +
inptr0[-1] + inptr0[1] + inptr1[-1] + inptr1[1];
neighsum += neighsum;
neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[1]) +
GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[1]);
neighsum += above_ptr[-1] + above_ptr[1] + below_ptr[-1] + below_ptr[1];
membersum = membersum * memberscale + neighsum * neighscale;
*outptr = (JSAMPLE)((membersum + 32768) >> 16);
@@ -429,21 +415,18 @@ fullsize_smooth_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
below_ptr = input_data[outrow + 1];
/* Special case for first column */
colsum = GETJSAMPLE(*above_ptr++) + GETJSAMPLE(*below_ptr++) +
GETJSAMPLE(*inptr);
membersum = GETJSAMPLE(*inptr++);
nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) +
GETJSAMPLE(*inptr);
colsum = (*above_ptr++) + (*below_ptr++) + inptr[0];
membersum = *inptr++;
nextcolsum = above_ptr[0] + below_ptr[0] + inptr[0];
neighsum = colsum + (colsum - membersum) + nextcolsum;
membersum = membersum * memberscale + neighsum * neighscale;
*outptr++ = (JSAMPLE)((membersum + 32768) >> 16);
lastcolsum = colsum; colsum = nextcolsum;
for (colctr = output_cols - 2; colctr > 0; colctr--) {
membersum = GETJSAMPLE(*inptr++);
membersum = *inptr++;
above_ptr++; below_ptr++;
nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) +
GETJSAMPLE(*inptr);
nextcolsum = above_ptr[0] + below_ptr[0] + inptr[0];
neighsum = lastcolsum + (colsum - membersum) + nextcolsum;
membersum = membersum * memberscale + neighsum * neighscale;
*outptr++ = (JSAMPLE)((membersum + 32768) >> 16);
@@ -451,7 +434,7 @@ fullsize_smooth_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
}
/* Special case for last column */
membersum = GETJSAMPLE(*inptr);
membersum = *inptr;
neighsum = lastcolsum + (colsum - membersum) + colsum;
membersum = membersum * memberscale + neighsum * neighscale;
*outptr = (JSAMPLE)((membersum + 32768) >> 16);
+9 -1
View File
@@ -4,7 +4,7 @@
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1994-1996, Thomas G. Lane.
* libjpeg-turbo Modifications:
* Copyright (C) 2010, 2015-2018, 2020, D. R. Commander.
* Copyright (C) 2010, 2015-2020, D. R. Commander.
* Copyright (C) 2015, Google, Inc.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
@@ -319,6 +319,8 @@ read_and_discard_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
{
JDIMENSION n;
my_master_ptr master = (my_master_ptr)cinfo->master;
JSAMPLE dummy_sample[1] = { 0 };
JSAMPROW dummy_row = dummy_sample;
JSAMPARRAY scanlines = NULL;
void (*color_convert) (j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
JDIMENSION input_row, JSAMPARRAY output_buf,
@@ -329,6 +331,10 @@ read_and_discard_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
if (cinfo->cconvert && cinfo->cconvert->color_convert) {
color_convert = cinfo->cconvert->color_convert;
cinfo->cconvert->color_convert = noop_convert;
/* This just prevents UBSan from complaining about adding 0 to a NULL
* pointer. The pointer isn't actually used.
*/
scanlines = &dummy_row;
}
if (cinfo->cquantize && cinfo->cquantize->color_quantize) {
@@ -532,6 +538,8 @@ jpeg_skip_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
* decoded coefficients. This is ~5% faster for large subsets, but
* it's tough to tell a difference for smaller images.
*/
if (!cinfo->entropy->insufficient_data)
cinfo->master->last_good_iMCU_row = cinfo->input_iMCU_row;
(*cinfo->entropy->decode_mcu) (cinfo, NULL);
}
}
+12 -3
View File
@@ -4,7 +4,7 @@
* This file was part of the Independent JPEG Group's software:
* Developed 1997-2015 by Guido Vollbeding.
* libjpeg-turbo Modifications:
* Copyright (C) 2015-2018, D. R. Commander.
* Copyright (C) 2015-2020, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -80,7 +80,7 @@ get_byte(j_decompress_ptr cinfo)
if (!(*src->fill_input_buffer) (cinfo))
ERREXIT(cinfo, JERR_CANT_SUSPEND);
src->bytes_in_buffer--;
return GETJOCTET(*src->next_input_byte++);
return *src->next_input_byte++;
}
@@ -665,8 +665,16 @@ bad:
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
int coefi, cindex = cinfo->cur_comp_info[ci]->component_index;
int *coef_bit_ptr = &cinfo->coef_bits[cindex][0];
int *prev_coef_bit_ptr =
&cinfo->coef_bits[cindex + cinfo->num_components][0];
if (cinfo->Ss && coef_bit_ptr[0] < 0) /* AC without prior DC scan */
WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, 0);
for (coefi = MIN(cinfo->Ss, 1); coefi <= MAX(cinfo->Se, 9); coefi++) {
if (cinfo->input_scan_number > 1)
prev_coef_bit_ptr[coefi] = coef_bit_ptr[coefi];
else
prev_coef_bit_ptr[coefi] = 0;
}
for (coefi = cinfo->Ss; coefi <= cinfo->Se; coefi++) {
int expected = (coef_bit_ptr[coefi] < 0) ? 0 : coef_bit_ptr[coefi];
if (cinfo->Ah != expected)
@@ -727,6 +735,7 @@ bad:
entropy->c = 0;
entropy->a = 0;
entropy->ct = -16; /* force reading 2 initial bytes to fill C */
entropy->pub.insufficient_data = FALSE;
/* Initialize restart counter */
entropy->restarts_to_go = cinfo->restart_interval;
@@ -763,7 +772,7 @@ jinit_arith_decoder(j_decompress_ptr cinfo)
int *coef_bit_ptr, ci;
cinfo->coef_bits = (int (*)[DCTSIZE2])
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
cinfo->num_components * DCTSIZE2 *
cinfo->num_components * 2 * DCTSIZE2 *
sizeof(int));
coef_bit_ptr = &cinfo->coef_bits[0][0];
for (ci = 0; ci < cinfo->num_components; ci++)
+237 -53
View File
@@ -5,7 +5,7 @@
* Copyright (C) 1994-1997, Thomas G. Lane.
* libjpeg-turbo Modifications:
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
* Copyright (C) 2010, 2015-2016, D. R. Commander.
* Copyright (C) 2010, 2015-2016, 2019-2020, D. R. Commander.
* Copyright (C) 2015, 2020, Google, Inc.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
@@ -102,6 +102,8 @@ decompress_onepass(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
/* Try to fetch an MCU. Entropy decoder expects buffer to be zeroed. */
jzero_far((void *)coef->MCU_buffer[0],
(size_t)(cinfo->blocks_in_MCU * sizeof(JBLOCK)));
if (!cinfo->entropy->insufficient_data)
cinfo->master->last_good_iMCU_row = cinfo->input_iMCU_row;
if (!(*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
/* Suspension forced; update state counters and exit */
coef->MCU_vert_offset = yoffset;
@@ -227,6 +229,8 @@ consume_data(j_decompress_ptr cinfo)
}
}
}
if (!cinfo->entropy->insufficient_data)
cinfo->master->last_good_iMCU_row = cinfo->input_iMCU_row;
/* Try to fetch the MCU. */
if (!(*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
/* Suspension forced; update state counters and exit */
@@ -326,19 +330,22 @@ decompress_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
#ifdef BLOCK_SMOOTHING_SUPPORTED
/*
* This code applies interblock smoothing as described by section K.8
* of the JPEG standard: the first 5 AC coefficients are estimated from
* the DC values of a DCT block and its 8 neighboring blocks.
* This code applies interblock smoothing; the first 9 AC coefficients are
* estimated from the DC values of a DCT block and its 24 neighboring blocks.
* We apply smoothing only for progressive JPEG decoding, and only if
* the coefficients it can estimate are not yet known to full precision.
*/
/* Natural-order array positions of the first 5 zigzag-order coefficients */
/* Natural-order array positions of the first 9 zigzag-order coefficients */
#define Q01_POS 1
#define Q10_POS 8
#define Q20_POS 16
#define Q11_POS 9
#define Q02_POS 2
#define Q03_POS 3
#define Q12_POS 10
#define Q21_POS 17
#define Q30_POS 24
/*
* Determine whether block smoothing is applicable and safe.
@@ -356,8 +363,8 @@ smoothing_ok(j_decompress_ptr cinfo)
int ci, coefi;
jpeg_component_info *compptr;
JQUANT_TBL *qtable;
int *coef_bits;
int *coef_bits_latch;
int *coef_bits, *prev_coef_bits;
int *coef_bits_latch, *prev_coef_bits_latch;
if (!cinfo->progressive_mode || cinfo->coef_bits == NULL)
return FALSE;
@@ -366,34 +373,47 @@ smoothing_ok(j_decompress_ptr cinfo)
if (coef->coef_bits_latch == NULL)
coef->coef_bits_latch = (int *)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
cinfo->num_components *
cinfo->num_components * 2 *
(SAVED_COEFS * sizeof(int)));
coef_bits_latch = coef->coef_bits_latch;
prev_coef_bits_latch =
&coef->coef_bits_latch[cinfo->num_components * SAVED_COEFS];
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
/* All components' quantization values must already be latched. */
if ((qtable = compptr->quant_table) == NULL)
return FALSE;
/* Verify DC & first 5 AC quantizers are nonzero to avoid zero-divide. */
/* Verify DC & first 9 AC quantizers are nonzero to avoid zero-divide. */
if (qtable->quantval[0] == 0 ||
qtable->quantval[Q01_POS] == 0 ||
qtable->quantval[Q10_POS] == 0 ||
qtable->quantval[Q20_POS] == 0 ||
qtable->quantval[Q11_POS] == 0 ||
qtable->quantval[Q02_POS] == 0)
qtable->quantval[Q02_POS] == 0 ||
qtable->quantval[Q03_POS] == 0 ||
qtable->quantval[Q12_POS] == 0 ||
qtable->quantval[Q21_POS] == 0 ||
qtable->quantval[Q30_POS] == 0)
return FALSE;
/* DC values must be at least partly known for all components. */
coef_bits = cinfo->coef_bits[ci];
prev_coef_bits = cinfo->coef_bits[ci + cinfo->num_components];
if (coef_bits[0] < 0)
return FALSE;
coef_bits_latch[0] = coef_bits[0];
/* Block smoothing is helpful if some AC coefficients remain inaccurate. */
for (coefi = 1; coefi <= 5; coefi++) {
for (coefi = 1; coefi < SAVED_COEFS; coefi++) {
if (cinfo->input_scan_number > 1)
prev_coef_bits_latch[coefi] = prev_coef_bits[coefi];
else
prev_coef_bits_latch[coefi] = -1;
coef_bits_latch[coefi] = coef_bits[coefi];
if (coef_bits[coefi] != 0)
smoothing_useful = TRUE;
}
coef_bits_latch += SAVED_COEFS;
prev_coef_bits_latch += SAVED_COEFS;
}
return smoothing_useful;
@@ -412,17 +432,20 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
JDIMENSION block_num, last_block_column;
int ci, block_row, block_rows, access_rows;
JBLOCKARRAY buffer;
JBLOCKROW buffer_ptr, prev_block_row, next_block_row;
JBLOCKROW buffer_ptr, prev_prev_block_row, prev_block_row;
JBLOCKROW next_block_row, next_next_block_row;
JSAMPARRAY output_ptr;
JDIMENSION output_col;
jpeg_component_info *compptr;
inverse_DCT_method_ptr inverse_DCT;
boolean first_row, last_row;
boolean change_dc;
JCOEF *workspace;
int *coef_bits;
JQUANT_TBL *quanttbl;
JLONG Q00, Q01, Q02, Q10, Q11, Q20, num;
int DC1, DC2, DC3, DC4, DC5, DC6, DC7, DC8, DC9;
JLONG Q00, Q01, Q02, Q03 = 0, Q10, Q11, Q12 = 0, Q20, Q21 = 0, Q30 = 0, num;
int DC01, DC02, DC03, DC04, DC05, DC06, DC07, DC08, DC09, DC10, DC11, DC12,
DC13, DC14, DC15, DC16, DC17, DC18, DC19, DC20, DC21, DC22, DC23, DC24,
DC25;
int Al, pred;
/* Keep a local variable to avoid looking it up more than once */
@@ -434,10 +457,10 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
if (cinfo->input_scan_number == cinfo->output_scan_number) {
/* If input is working on current scan, we ordinarily want it to
* have completed the current row. But if input scan is DC,
* we want it to keep one row ahead so that next block row's DC
* we want it to keep two rows ahead so that next two block rows' DC
* values are up to date.
*/
JDIMENSION delta = (cinfo->Ss == 0) ? 1 : 0;
JDIMENSION delta = (cinfo->Ss == 0) ? 2 : 0;
if (cinfo->input_iMCU_row > cinfo->output_iMCU_row + delta)
break;
}
@@ -452,34 +475,53 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
if (!compptr->component_needed)
continue;
/* Count non-dummy DCT block rows in this iMCU row. */
if (cinfo->output_iMCU_row < last_iMCU_row) {
if (cinfo->output_iMCU_row < last_iMCU_row - 1) {
block_rows = compptr->v_samp_factor;
access_rows = block_rows * 3; /* this and next two iMCU rows */
} else if (cinfo->output_iMCU_row < last_iMCU_row) {
block_rows = compptr->v_samp_factor;
access_rows = block_rows * 2; /* this and next iMCU row */
last_row = FALSE;
} else {
/* NB: can't use last_row_height here; it is input-side-dependent! */
block_rows = (int)(compptr->height_in_blocks % compptr->v_samp_factor);
if (block_rows == 0) block_rows = compptr->v_samp_factor;
access_rows = block_rows; /* this iMCU row only */
last_row = TRUE;
}
/* Align the virtual buffer for this component. */
if (cinfo->output_iMCU_row > 0) {
access_rows += compptr->v_samp_factor; /* prior iMCU row too */
if (cinfo->output_iMCU_row > 1) {
access_rows += 2 * compptr->v_samp_factor; /* prior two iMCU rows too */
buffer = (*cinfo->mem->access_virt_barray)
((j_common_ptr)cinfo, coef->whole_image[ci],
(cinfo->output_iMCU_row - 2) * compptr->v_samp_factor,
(JDIMENSION)access_rows, FALSE);
buffer += 2 * compptr->v_samp_factor; /* point to current iMCU row */
} else if (cinfo->output_iMCU_row > 0) {
buffer = (*cinfo->mem->access_virt_barray)
((j_common_ptr)cinfo, coef->whole_image[ci],
(cinfo->output_iMCU_row - 1) * compptr->v_samp_factor,
(JDIMENSION)access_rows, FALSE);
buffer += compptr->v_samp_factor; /* point to current iMCU row */
first_row = FALSE;
} else {
buffer = (*cinfo->mem->access_virt_barray)
((j_common_ptr)cinfo, coef->whole_image[ci],
(JDIMENSION)0, (JDIMENSION)access_rows, FALSE);
first_row = TRUE;
}
/* Fetch component-dependent info */
coef_bits = coef->coef_bits_latch + (ci * SAVED_COEFS);
/* Fetch component-dependent info.
* If the current scan is incomplete, then we use the component-dependent
* info from the previous scan.
*/
if (cinfo->output_iMCU_row > cinfo->master->last_good_iMCU_row)
coef_bits =
coef->coef_bits_latch + ((ci + cinfo->num_components) * SAVED_COEFS);
else
coef_bits = coef->coef_bits_latch + (ci * SAVED_COEFS);
/* We only do DC interpolation if no AC coefficient data is available. */
change_dc =
coef_bits[1] == -1 && coef_bits[2] == -1 && coef_bits[3] == -1 &&
coef_bits[4] == -1 && coef_bits[5] == -1 && coef_bits[6] == -1 &&
coef_bits[7] == -1 && coef_bits[8] == -1 && coef_bits[9] == -1;
quanttbl = compptr->quant_table;
Q00 = quanttbl->quantval[0];
Q01 = quanttbl->quantval[Q01_POS];
@@ -487,27 +529,51 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
Q20 = quanttbl->quantval[Q20_POS];
Q11 = quanttbl->quantval[Q11_POS];
Q02 = quanttbl->quantval[Q02_POS];
if (change_dc) {
Q03 = quanttbl->quantval[Q03_POS];
Q12 = quanttbl->quantval[Q12_POS];
Q21 = quanttbl->quantval[Q21_POS];
Q30 = quanttbl->quantval[Q30_POS];
}
inverse_DCT = cinfo->idct->inverse_DCT[ci];
output_ptr = output_buf[ci];
/* Loop over all DCT blocks to be processed. */
for (block_row = 0; block_row < block_rows; block_row++) {
buffer_ptr = buffer[block_row] + cinfo->master->first_MCU_col[ci];
if (first_row && block_row == 0)
if (block_row > 0 || cinfo->output_iMCU_row > 0)
prev_block_row =
buffer[block_row - 1] + cinfo->master->first_MCU_col[ci];
else
prev_block_row = buffer_ptr;
if (block_row > 1 || cinfo->output_iMCU_row > 1)
prev_prev_block_row =
buffer[block_row - 2] + cinfo->master->first_MCU_col[ci];
else
prev_prev_block_row = prev_block_row;
if (block_row < block_rows - 1 || cinfo->output_iMCU_row < last_iMCU_row)
next_block_row =
buffer[block_row + 1] + cinfo->master->first_MCU_col[ci];
else
prev_block_row = buffer[block_row - 1] +
cinfo->master->first_MCU_col[ci];
if (last_row && block_row == block_rows - 1)
next_block_row = buffer_ptr;
if (block_row < block_rows - 2 ||
cinfo->output_iMCU_row < last_iMCU_row - 1)
next_next_block_row =
buffer[block_row + 2] + cinfo->master->first_MCU_col[ci];
else
next_block_row = buffer[block_row + 1] +
cinfo->master->first_MCU_col[ci];
next_next_block_row = next_block_row;
/* We fetch the surrounding DC values using a sliding-register approach.
* Initialize all nine here so as to do the right thing on narrow pics.
* Initialize all 25 here so as to do the right thing on narrow pics.
*/
DC1 = DC2 = DC3 = (int)prev_block_row[0][0];
DC4 = DC5 = DC6 = (int)buffer_ptr[0][0];
DC7 = DC8 = DC9 = (int)next_block_row[0][0];
DC01 = DC02 = DC03 = DC04 = DC05 = (int)prev_prev_block_row[0][0];
DC06 = DC07 = DC08 = DC09 = DC10 = (int)prev_block_row[0][0];
DC11 = DC12 = DC13 = DC14 = DC15 = (int)buffer_ptr[0][0];
DC16 = DC17 = DC18 = DC19 = DC20 = (int)next_block_row[0][0];
DC21 = DC22 = DC23 = DC24 = DC25 = (int)next_next_block_row[0][0];
output_col = 0;
last_block_column = compptr->width_in_blocks - 1;
for (block_num = cinfo->master->first_MCU_col[ci];
@@ -515,18 +581,39 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
/* Fetch current DCT block into workspace so we can modify it. */
jcopy_block_row(buffer_ptr, (JBLOCKROW)workspace, (JDIMENSION)1);
/* Update DC values */
if (block_num < last_block_column) {
DC3 = (int)prev_block_row[1][0];
DC6 = (int)buffer_ptr[1][0];
DC9 = (int)next_block_row[1][0];
if (block_num == cinfo->master->first_MCU_col[ci] &&
block_num < last_block_column) {
DC04 = (int)prev_prev_block_row[1][0];
DC09 = (int)prev_block_row[1][0];
DC14 = (int)buffer_ptr[1][0];
DC19 = (int)next_block_row[1][0];
DC24 = (int)next_next_block_row[1][0];
}
/* Compute coefficient estimates per K.8.
* An estimate is applied only if coefficient is still zero,
* and is not known to be fully accurate.
if (block_num + 1 < last_block_column) {
DC05 = (int)prev_prev_block_row[2][0];
DC10 = (int)prev_block_row[2][0];
DC15 = (int)buffer_ptr[2][0];
DC20 = (int)next_block_row[2][0];
DC25 = (int)next_next_block_row[2][0];
}
/* If DC interpolation is enabled, compute coefficient estimates using
* a Gaussian-like kernel, keeping the averages of the DC values.
*
* If DC interpolation is disabled, compute coefficient estimates using
* an algorithm similar to the one described in Section K.8 of the JPEG
* standard, except applied to a 5x5 window rather than a 3x3 window.
*
* An estimate is applied only if the coefficient is still zero and is
* not known to be fully accurate.
*/
/* AC01 */
if ((Al = coef_bits[1]) != 0 && workspace[1] == 0) {
num = 36 * Q00 * (DC4 - DC6);
num = Q00 * (change_dc ?
(-DC01 - DC02 + DC04 + DC05 - 3 * DC06 + 13 * DC07 -
13 * DC09 + 3 * DC10 - 3 * DC11 + 38 * DC12 - 38 * DC14 +
3 * DC15 - 3 * DC16 + 13 * DC17 - 13 * DC19 + 3 * DC20 -
DC21 - DC22 + DC24 + DC25) :
(-7 * DC11 + 50 * DC12 - 50 * DC14 + 7 * DC15));
if (num >= 0) {
pred = (int)(((Q01 << 7) + num) / (Q01 << 8));
if (Al > 0 && pred >= (1 << Al))
@@ -541,7 +628,12 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
}
/* AC10 */
if ((Al = coef_bits[2]) != 0 && workspace[8] == 0) {
num = 36 * Q00 * (DC2 - DC8);
num = Q00 * (change_dc ?
(-DC01 - 3 * DC02 - 3 * DC03 - 3 * DC04 - DC05 - DC06 +
13 * DC07 + 38 * DC08 + 13 * DC09 - DC10 + DC16 -
13 * DC17 - 38 * DC18 - 13 * DC19 + DC20 + DC21 +
3 * DC22 + 3 * DC23 + 3 * DC24 + DC25) :
(-7 * DC03 + 50 * DC08 - 50 * DC18 + 7 * DC23));
if (num >= 0) {
pred = (int)(((Q10 << 7) + num) / (Q10 << 8));
if (Al > 0 && pred >= (1 << Al))
@@ -556,7 +648,10 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
}
/* AC20 */
if ((Al = coef_bits[3]) != 0 && workspace[16] == 0) {
num = 9 * Q00 * (DC2 + DC8 - 2 * DC5);
num = Q00 * (change_dc ?
(DC03 + 2 * DC07 + 7 * DC08 + 2 * DC09 - 5 * DC12 - 14 * DC13 -
5 * DC14 + 2 * DC17 + 7 * DC18 + 2 * DC19 + DC23) :
(-DC03 + 13 * DC08 - 24 * DC13 + 13 * DC18 - DC23));
if (num >= 0) {
pred = (int)(((Q20 << 7) + num) / (Q20 << 8));
if (Al > 0 && pred >= (1 << Al))
@@ -571,7 +666,11 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
}
/* AC11 */
if ((Al = coef_bits[4]) != 0 && workspace[9] == 0) {
num = 5 * Q00 * (DC1 - DC3 - DC7 + DC9);
num = Q00 * (change_dc ?
(-DC01 + DC05 + 9 * DC07 - 9 * DC09 - 9 * DC17 +
9 * DC19 + DC21 - DC25) :
(DC10 + DC16 - 10 * DC17 + 10 * DC19 - DC02 - DC20 + DC22 -
DC24 + DC04 - DC06 + 10 * DC07 - 10 * DC09));
if (num >= 0) {
pred = (int)(((Q11 << 7) + num) / (Q11 << 8));
if (Al > 0 && pred >= (1 << Al))
@@ -586,7 +685,10 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
}
/* AC02 */
if ((Al = coef_bits[5]) != 0 && workspace[2] == 0) {
num = 9 * Q00 * (DC4 + DC6 - 2 * DC5);
num = Q00 * (change_dc ?
(2 * DC07 - 5 * DC08 + 2 * DC09 + DC11 + 7 * DC12 - 14 * DC13 +
7 * DC14 + DC15 + 2 * DC17 - 5 * DC18 + 2 * DC19) :
(-DC11 + 13 * DC12 - 24 * DC13 + 13 * DC14 - DC15));
if (num >= 0) {
pred = (int)(((Q02 << 7) + num) / (Q02 << 8));
if (Al > 0 && pred >= (1 << Al))
@@ -599,14 +701,96 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
}
workspace[2] = (JCOEF)pred;
}
if (change_dc) {
/* AC03 */
if ((Al = coef_bits[6]) != 0 && workspace[3] == 0) {
num = Q00 * (DC07 - DC09 + 2 * DC12 - 2 * DC14 + DC17 - DC19);
if (num >= 0) {
pred = (int)(((Q03 << 7) + num) / (Q03 << 8));
if (Al > 0 && pred >= (1 << Al))
pred = (1 << Al) - 1;
} else {
pred = (int)(((Q03 << 7) - num) / (Q03 << 8));
if (Al > 0 && pred >= (1 << Al))
pred = (1 << Al) - 1;
pred = -pred;
}
workspace[3] = (JCOEF)pred;
}
/* AC12 */
if ((Al = coef_bits[7]) != 0 && workspace[10] == 0) {
num = Q00 * (DC07 - 3 * DC08 + DC09 - DC17 + 3 * DC18 - DC19);
if (num >= 0) {
pred = (int)(((Q12 << 7) + num) / (Q12 << 8));
if (Al > 0 && pred >= (1 << Al))
pred = (1 << Al) - 1;
} else {
pred = (int)(((Q12 << 7) - num) / (Q12 << 8));
if (Al > 0 && pred >= (1 << Al))
pred = (1 << Al) - 1;
pred = -pred;
}
workspace[10] = (JCOEF)pred;
}
/* AC21 */
if ((Al = coef_bits[8]) != 0 && workspace[17] == 0) {
num = Q00 * (DC07 - DC09 - 3 * DC12 + 3 * DC14 + DC17 - DC19);
if (num >= 0) {
pred = (int)(((Q21 << 7) + num) / (Q21 << 8));
if (Al > 0 && pred >= (1 << Al))
pred = (1 << Al) - 1;
} else {
pred = (int)(((Q21 << 7) - num) / (Q21 << 8));
if (Al > 0 && pred >= (1 << Al))
pred = (1 << Al) - 1;
pred = -pred;
}
workspace[17] = (JCOEF)pred;
}
/* AC30 */
if ((Al = coef_bits[9]) != 0 && workspace[24] == 0) {
num = Q00 * (DC07 + 2 * DC08 + DC09 - DC17 - 2 * DC18 - DC19);
if (num >= 0) {
pred = (int)(((Q30 << 7) + num) / (Q30 << 8));
if (Al > 0 && pred >= (1 << Al))
pred = (1 << Al) - 1;
} else {
pred = (int)(((Q30 << 7) - num) / (Q30 << 8));
if (Al > 0 && pred >= (1 << Al))
pred = (1 << Al) - 1;
pred = -pred;
}
workspace[24] = (JCOEF)pred;
}
/* coef_bits[0] is non-negative. Otherwise this function would not
* be called.
*/
num = Q00 *
(-2 * DC01 - 6 * DC02 - 8 * DC03 - 6 * DC04 - 2 * DC05 -
6 * DC06 + 6 * DC07 + 42 * DC08 + 6 * DC09 - 6 * DC10 -
8 * DC11 + 42 * DC12 + 152 * DC13 + 42 * DC14 - 8 * DC15 -
6 * DC16 + 6 * DC17 + 42 * DC18 + 6 * DC19 - 6 * DC20 -
2 * DC21 - 6 * DC22 - 8 * DC23 - 6 * DC24 - 2 * DC25);
if (num >= 0) {
pred = (int)(((Q00 << 7) + num) / (Q00 << 8));
} else {
pred = (int)(((Q00 << 7) - num) / (Q00 << 8));
pred = -pred;
}
workspace[0] = (JCOEF)pred;
} /* change_dc */
/* OK, do the IDCT */
(*inverse_DCT) (cinfo, compptr, (JCOEFPTR)workspace, output_ptr,
output_col);
/* Advance for next column */
DC1 = DC2; DC2 = DC3;
DC4 = DC5; DC5 = DC6;
DC7 = DC8; DC8 = DC9;
buffer_ptr++, prev_block_row++, next_block_row++;
DC01 = DC02; DC02 = DC03; DC03 = DC04; DC04 = DC05;
DC06 = DC07; DC07 = DC08; DC08 = DC09; DC09 = DC10;
DC11 = DC12; DC12 = DC13; DC13 = DC14; DC14 = DC15;
DC16 = DC17; DC17 = DC18; DC18 = DC19; DC19 = DC20;
DC21 = DC22; DC22 = DC23; DC23 = DC24; DC24 = DC25;
buffer_ptr++, prev_block_row++, next_block_row++,
prev_prev_block_row++, next_next_block_row++;
output_col += compptr->_DCT_scaled_size;
}
output_ptr += compptr->_DCT_scaled_size;
@@ -655,7 +839,7 @@ jinit_d_coef_controller(j_decompress_ptr cinfo, boolean need_full_buffer)
#ifdef BLOCK_SMOOTHING_SUPPORTED
/* If block smoothing could be used, need a bigger window */
if (cinfo->progressive_mode)
access_rows *= 3;
access_rows *= 5;
#endif
coef->whole_image[ci] = (*cinfo->mem->request_virt_barray)
((j_common_ptr)cinfo, JPOOL_IMAGE, TRUE,
+2 -1
View File
@@ -5,6 +5,7 @@
* Copyright (C) 1994-1997, Thomas G. Lane.
* libjpeg-turbo Modifications:
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
* Copyright (C) 2020, Google, Inc.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*/
@@ -51,7 +52,7 @@ typedef struct {
#ifdef BLOCK_SMOOTHING_SUPPORTED
/* When doing block smoothing, we latch coefficient Al values here */
int *coef_bits_latch;
#define SAVED_COEFS 6 /* we save coef_bits[0..5] */
#define SAVED_COEFS 10 /* we save coef_bits[0..9] */
#endif
} my_coef_controller;
+48 -48
View File
@@ -45,9 +45,9 @@ ycc_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
outptr = *output_buf++;
if (PACK_NEED_ALIGNMENT(outptr)) {
y = GETJSAMPLE(*inptr0++);
cb = GETJSAMPLE(*inptr1++);
cr = GETJSAMPLE(*inptr2++);
y = *inptr0++;
cb = *inptr1++;
cr = *inptr2++;
r = range_limit[y + Crrtab[cr]];
g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
SCALEBITS))];
@@ -58,18 +58,18 @@ ycc_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
num_cols--;
}
for (col = 0; col < (num_cols >> 1); col++) {
y = GETJSAMPLE(*inptr0++);
cb = GETJSAMPLE(*inptr1++);
cr = GETJSAMPLE(*inptr2++);
y = *inptr0++;
cb = *inptr1++;
cr = *inptr2++;
r = range_limit[y + Crrtab[cr]];
g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
SCALEBITS))];
b = range_limit[y + Cbbtab[cb]];
rgb = PACK_SHORT_565(r, g, b);
y = GETJSAMPLE(*inptr0++);
cb = GETJSAMPLE(*inptr1++);
cr = GETJSAMPLE(*inptr2++);
y = *inptr0++;
cb = *inptr1++;
cr = *inptr2++;
r = range_limit[y + Crrtab[cr]];
g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
SCALEBITS))];
@@ -80,9 +80,9 @@ ycc_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
outptr += 4;
}
if (num_cols & 1) {
y = GETJSAMPLE(*inptr0);
cb = GETJSAMPLE(*inptr1);
cr = GETJSAMPLE(*inptr2);
y = *inptr0;
cb = *inptr1;
cr = *inptr2;
r = range_limit[y + Crrtab[cr]];
g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
SCALEBITS))];
@@ -125,9 +125,9 @@ ycc_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
input_row++;
outptr = *output_buf++;
if (PACK_NEED_ALIGNMENT(outptr)) {
y = GETJSAMPLE(*inptr0++);
cb = GETJSAMPLE(*inptr1++);
cr = GETJSAMPLE(*inptr2++);
y = *inptr0++;
cb = *inptr1++;
cr = *inptr2++;
r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
g = range_limit[DITHER_565_G(y +
((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
@@ -139,9 +139,9 @@ ycc_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
num_cols--;
}
for (col = 0; col < (num_cols >> 1); col++) {
y = GETJSAMPLE(*inptr0++);
cb = GETJSAMPLE(*inptr1++);
cr = GETJSAMPLE(*inptr2++);
y = *inptr0++;
cb = *inptr1++;
cr = *inptr2++;
r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
g = range_limit[DITHER_565_G(y +
((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
@@ -150,9 +150,9 @@ ycc_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
d0 = DITHER_ROTATE(d0);
rgb = PACK_SHORT_565(r, g, b);
y = GETJSAMPLE(*inptr0++);
cb = GETJSAMPLE(*inptr1++);
cr = GETJSAMPLE(*inptr2++);
y = *inptr0++;
cb = *inptr1++;
cr = *inptr2++;
r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
g = range_limit[DITHER_565_G(y +
((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
@@ -165,9 +165,9 @@ ycc_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
outptr += 4;
}
if (num_cols & 1) {
y = GETJSAMPLE(*inptr0);
cb = GETJSAMPLE(*inptr1);
cr = GETJSAMPLE(*inptr2);
y = *inptr0;
cb = *inptr1;
cr = *inptr2;
r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
g = range_limit[DITHER_565_G(y +
((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
@@ -202,32 +202,32 @@ rgb_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
input_row++;
outptr = *output_buf++;
if (PACK_NEED_ALIGNMENT(outptr)) {
r = GETJSAMPLE(*inptr0++);
g = GETJSAMPLE(*inptr1++);
b = GETJSAMPLE(*inptr2++);
r = *inptr0++;
g = *inptr1++;
b = *inptr2++;
rgb = PACK_SHORT_565(r, g, b);
*(INT16 *)outptr = (INT16)rgb;
outptr += 2;
num_cols--;
}
for (col = 0; col < (num_cols >> 1); col++) {
r = GETJSAMPLE(*inptr0++);
g = GETJSAMPLE(*inptr1++);
b = GETJSAMPLE(*inptr2++);
r = *inptr0++;
g = *inptr1++;
b = *inptr2++;
rgb = PACK_SHORT_565(r, g, b);
r = GETJSAMPLE(*inptr0++);
g = GETJSAMPLE(*inptr1++);
b = GETJSAMPLE(*inptr2++);
r = *inptr0++;
g = *inptr1++;
b = *inptr2++;
rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
outptr += 4;
}
if (num_cols & 1) {
r = GETJSAMPLE(*inptr0);
g = GETJSAMPLE(*inptr1);
b = GETJSAMPLE(*inptr2);
r = *inptr0;
g = *inptr1;
b = *inptr2;
rgb = PACK_SHORT_565(r, g, b);
*(INT16 *)outptr = (INT16)rgb;
}
@@ -259,24 +259,24 @@ rgb_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
input_row++;
outptr = *output_buf++;
if (PACK_NEED_ALIGNMENT(outptr)) {
r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0++), d0)];
g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1++), d0)];
b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2++), d0)];
r = range_limit[DITHER_565_R(*inptr0++, d0)];
g = range_limit[DITHER_565_G(*inptr1++, d0)];
b = range_limit[DITHER_565_B(*inptr2++, d0)];
rgb = PACK_SHORT_565(r, g, b);
*(INT16 *)outptr = (INT16)rgb;
outptr += 2;
num_cols--;
}
for (col = 0; col < (num_cols >> 1); col++) {
r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0++), d0)];
g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1++), d0)];
b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2++), d0)];
r = range_limit[DITHER_565_R(*inptr0++, d0)];
g = range_limit[DITHER_565_G(*inptr1++, d0)];
b = range_limit[DITHER_565_B(*inptr2++, d0)];
d0 = DITHER_ROTATE(d0);
rgb = PACK_SHORT_565(r, g, b);
r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0++), d0)];
g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1++), d0)];
b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2++), d0)];
r = range_limit[DITHER_565_R(*inptr0++, d0)];
g = range_limit[DITHER_565_G(*inptr1++, d0)];
b = range_limit[DITHER_565_B(*inptr2++, d0)];
d0 = DITHER_ROTATE(d0);
rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
@@ -284,9 +284,9 @@ rgb_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
outptr += 4;
}
if (num_cols & 1) {
r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0), d0)];
g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1), d0)];
b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2), d0)];
r = range_limit[DITHER_565_R(*inptr0, d0)];
g = range_limit[DITHER_565_G(*inptr1, d0)];
b = range_limit[DITHER_565_B(*inptr2, d0)];
rgb = PACK_SHORT_565(r, g, b);
*(INT16 *)outptr = (INT16)rgb;
}
+3 -5
View File
@@ -53,9 +53,9 @@ ycc_rgb_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
input_row++;
outptr = *output_buf++;
for (col = 0; col < num_cols; col++) {
y = GETJSAMPLE(inptr0[col]);
cb = GETJSAMPLE(inptr1[col]);
cr = GETJSAMPLE(inptr2[col]);
y = inptr0[col];
cb = inptr1[col];
cr = inptr2[col];
/* Range-limiting is essential due to noise introduced by DCT losses. */
outptr[RGB_RED] = range_limit[y + Crrtab[cr]];
outptr[RGB_GREEN] = range_limit[y +
@@ -93,7 +93,6 @@ gray_rgb_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
inptr = input_buf[0][input_row++];
outptr = *output_buf++;
for (col = 0; col < num_cols; col++) {
/* We can dispense with GETJSAMPLE() here */
outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
/* Set unused byte to 0xFF so it can be interpreted as an opaque */
/* alpha channel value */
@@ -128,7 +127,6 @@ rgb_rgb_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
input_row++;
outptr = *output_buf++;
for (col = 0; col < num_cols; col++) {
/* We can dispense with GETJSAMPLE() here */
outptr[RGB_RED] = inptr0[col];
outptr[RGB_GREEN] = inptr1[col];
outptr[RGB_BLUE] = inptr2[col];
+7 -7
View File
@@ -341,9 +341,9 @@ rgb_gray_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
input_row++;
outptr = *output_buf++;
for (col = 0; col < num_cols; col++) {
r = GETJSAMPLE(inptr0[col]);
g = GETJSAMPLE(inptr1[col]);
b = GETJSAMPLE(inptr2[col]);
r = inptr0[col];
g = inptr1[col];
b = inptr2[col];
/* Y */
outptr[col] = (JSAMPLE)((ctab[r + R_Y_OFF] + ctab[g + G_Y_OFF] +
ctab[b + B_Y_OFF]) >> SCALEBITS);
@@ -550,9 +550,9 @@ ycck_cmyk_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
input_row++;
outptr = *output_buf++;
for (col = 0; col < num_cols; col++) {
y = GETJSAMPLE(inptr0[col]);
cb = GETJSAMPLE(inptr1[col]);
cr = GETJSAMPLE(inptr2[col]);
y = inptr0[col];
cb = inptr1[col];
cr = inptr2[col];
/* Range-limiting is essential due to noise introduced by DCT losses. */
outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])]; /* red */
outptr[1] = range_limit[MAXJSAMPLE - (y + /* green */
@@ -560,7 +560,7 @@ ycck_cmyk_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
SCALEBITS)))];
outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])]; /* blue */
/* K passes through unchanged */
outptr[3] = inptr3[col]; /* don't need GETJSAMPLE here */
outptr[3] = inptr3[col];
outptr += 4;
}
}
+27 -33
View File
@@ -5,6 +5,7 @@
* Copyright (C) 1991-1997, Thomas G. Lane.
* libjpeg-turbo Modifications:
* Copyright (C) 2009-2011, 2016, 2018-2019, D. R. Commander.
* Copyright (C) 2018, Matthias Räncker.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -39,24 +40,6 @@ typedef struct {
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).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_decoder pub; /* public fields */
@@ -325,7 +308,7 @@ jpeg_fill_bit_buffer(bitread_working_state *state,
bytes_in_buffer = cinfo->src->bytes_in_buffer;
}
bytes_in_buffer--;
c = GETJOCTET(*next_input_byte++);
c = *next_input_byte++;
/* If it's 0xFF, check and discard stuffed zero byte */
if (c == 0xFF) {
@@ -342,7 +325,7 @@ jpeg_fill_bit_buffer(bitread_working_state *state,
bytes_in_buffer = cinfo->src->bytes_in_buffer;
}
bytes_in_buffer--;
c = GETJOCTET(*next_input_byte++);
c = *next_input_byte++;
} while (c == 0xFF);
if (c == 0) {
@@ -405,8 +388,8 @@ no_more_bytes:
#define GET_BYTE { \
register int c0, c1; \
c0 = GETJOCTET(*buffer++); \
c1 = GETJOCTET(*buffer); \
c0 = *buffer++; \
c1 = *buffer; \
/* Pre-execute most common case */ \
get_buffer = (get_buffer << 8) | c0; \
bits_left += 8; \
@@ -423,7 +406,7 @@ no_more_bytes:
} \
}
#if SIZEOF_SIZE_T == 8 || defined(_WIN64)
#if SIZEOF_SIZE_T == 8 || defined(_WIN64) || (defined(__x86_64__) && defined(__ILP32__))
/* Pre-fetch 48 bytes, because the holding register is 64-bit */
#define FILL_BIT_BUFFER_FAST \
@@ -557,6 +540,12 @@ process_restart(j_decompress_ptr cinfo)
}
#if defined(__has_feature)
#if __has_feature(undefined_behavior_sanitizer)
__attribute__((no_sanitize("signed-integer-overflow"),
no_sanitize("unsigned-integer-overflow")))
#endif
#endif
LOCAL(boolean)
decode_mcu_slow(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{
@@ -568,7 +557,7 @@ decode_mcu_slow(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
/* Load up working state */
BITREAD_LOAD_STATE(cinfo, entropy->bitstate);
ASSIGN_STATE(state, entropy->saved);
state = entropy->saved;
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
JBLOCKROW block = MCU_data ? MCU_data[blkn] : NULL;
@@ -589,11 +578,15 @@ decode_mcu_slow(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
if (entropy->dc_needed[blkn]) {
/* Convert DC difference to actual value, update last_dc_val */
int ci = cinfo->MCU_membership[blkn];
/* This is really just
* s += state.last_dc_val[ci];
* It is written this way in order to shut up UBSan.
/* Certain malformed JPEG images produce repeated DC coefficient
* differences of 2047 or -2047, which causes state.last_dc_val[ci] to
* grow until it overflows or underflows a 32-bit signed integer. This
* behavior is, to the best of our understanding, innocuous, and it is
* unclear how to work around it without potentially affecting
* performance. Thus, we (hopefully temporarily) suppress UBSan integer
* overflow errors for this function.
*/
s = (int)((unsigned int)s + (unsigned int)state.last_dc_val[ci]);
s += state.last_dc_val[ci];
state.last_dc_val[ci] = s;
if (block) {
/* Output the DC coefficient (assumes jpeg_natural_order[0] = 0) */
@@ -653,7 +646,7 @@ decode_mcu_slow(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
/* Completed MCU, so update state */
BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
ASSIGN_STATE(entropy->saved, state);
entropy->saved = state;
return TRUE;
}
@@ -671,7 +664,7 @@ decode_mcu_fast(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
/* Load up working state */
BITREAD_LOAD_STATE(cinfo, entropy->bitstate);
buffer = (JOCTET *)br_state.next_input_byte;
ASSIGN_STATE(state, entropy->saved);
state = entropy->saved;
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
JBLOCKROW block = MCU_data ? MCU_data[blkn] : NULL;
@@ -688,7 +681,7 @@ decode_mcu_fast(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
if (entropy->dc_needed[blkn]) {
int ci = cinfo->MCU_membership[blkn];
s = (int)((unsigned int)s + (unsigned int)state.last_dc_val[ci]);
s += state.last_dc_val[ci];
state.last_dc_val[ci] = s;
if (block)
(*block)[0] = (JCOEF)s;
@@ -740,7 +733,7 @@ decode_mcu_fast(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
br_state.bytes_in_buffer -= (buffer - br_state.next_input_byte);
br_state.next_input_byte = buffer;
BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
ASSIGN_STATE(entropy->saved, state);
entropy->saved = state;
return TRUE;
}
@@ -795,7 +788,8 @@ use_slow:
}
/* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--;
if (cinfo->restart_interval)
entropy->restarts_to_go--;
return TRUE;
}
+11 -2
View File
@@ -4,7 +4,8 @@
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-1997, Thomas G. Lane.
* libjpeg-turbo Modifications:
* Copyright (C) 2010-2011, 2015-2016, D. R. Commander.
* Copyright (C) 2010-2011, 2015-2016, 2021, D. R. Commander.
* Copyright (C) 2018, Matthias Räncker.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -78,6 +79,11 @@ EXTERN(void) jpeg_make_d_derived_tbl(j_decompress_ptr cinfo, boolean isDC,
typedef size_t bit_buf_type; /* type of bit-extraction buffer */
#define BIT_BUF_SIZE 64 /* size of buffer in bits */
#elif defined(__x86_64__) && defined(__ILP32__)
typedef unsigned long long bit_buf_type; /* type of bit-extraction buffer */
#define BIT_BUF_SIZE 64 /* size of buffer in bits */
#else
typedef unsigned long bit_buf_type; /* type of bit-extraction buffer */
@@ -228,7 +234,10 @@ slowlabel: \
s |= GET_BITS(1); \
nb++; \
} \
s = htbl->pub->huffval[(int)(s + htbl->valoffset[nb]) & 0xFF]; \
if (nb > 16) \
s = 0; \
else \
s = htbl->pub->huffval[(int)(s + htbl->valoffset[nb]) & 0xFF]; \
}
/* Out-of-line case for Huffman code fetching */
+16 -16
View File
@@ -38,18 +38,18 @@ marker_is_icc(jpeg_saved_marker_ptr marker)
marker->marker == ICC_MARKER &&
marker->data_length >= ICC_OVERHEAD_LEN &&
/* verify the identifying string */
GETJOCTET(marker->data[0]) == 0x49 &&
GETJOCTET(marker->data[1]) == 0x43 &&
GETJOCTET(marker->data[2]) == 0x43 &&
GETJOCTET(marker->data[3]) == 0x5F &&
GETJOCTET(marker->data[4]) == 0x50 &&
GETJOCTET(marker->data[5]) == 0x52 &&
GETJOCTET(marker->data[6]) == 0x4F &&
GETJOCTET(marker->data[7]) == 0x46 &&
GETJOCTET(marker->data[8]) == 0x49 &&
GETJOCTET(marker->data[9]) == 0x4C &&
GETJOCTET(marker->data[10]) == 0x45 &&
GETJOCTET(marker->data[11]) == 0x0;
marker->data[0] == 0x49 &&
marker->data[1] == 0x43 &&
marker->data[2] == 0x43 &&
marker->data[3] == 0x5F &&
marker->data[4] == 0x50 &&
marker->data[5] == 0x52 &&
marker->data[6] == 0x4F &&
marker->data[7] == 0x46 &&
marker->data[8] == 0x49 &&
marker->data[9] == 0x4C &&
marker->data[10] == 0x45 &&
marker->data[11] == 0x0;
}
@@ -102,12 +102,12 @@ jpeg_read_icc_profile(j_decompress_ptr cinfo, JOCTET **icc_data_ptr,
for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) {
if (marker_is_icc(marker)) {
if (num_markers == 0)
num_markers = GETJOCTET(marker->data[13]);
else if (num_markers != GETJOCTET(marker->data[13])) {
num_markers = marker->data[13];
else if (num_markers != marker->data[13]) {
WARNMS(cinfo, JWRN_BOGUS_ICC); /* inconsistent num_markers fields */
return FALSE;
}
seq_no = GETJOCTET(marker->data[12]);
seq_no = marker->data[12];
if (seq_no <= 0 || seq_no > num_markers) {
WARNMS(cinfo, JWRN_BOGUS_ICC); /* bogus sequence number */
return FALSE;
@@ -154,7 +154,7 @@ jpeg_read_icc_profile(j_decompress_ptr cinfo, JOCTET **icc_data_ptr,
JOCTET FAR *src_ptr;
JOCTET *dst_ptr;
unsigned int length;
seq_no = GETJOCTET(marker->data[12]);
seq_no = marker->data[12];
dst_ptr = icc_data + data_offset[seq_no];
src_ptr = marker->data + ICC_OVERHEAD_LEN;
length = data_length[seq_no];
+32 -35
View File
@@ -151,7 +151,7 @@ typedef my_marker_reader *my_marker_ptr;
#define INPUT_BYTE(cinfo, V, action) \
MAKESTMT( MAKE_BYTE_AVAIL(cinfo, action); \
bytes_in_buffer--; \
V = GETJOCTET(*next_input_byte++); )
V = *next_input_byte++; )
/* As above, but read two bytes interpreted as an unsigned 16-bit integer.
* V should be declared unsigned int or perhaps JLONG.
@@ -159,10 +159,10 @@ typedef my_marker_reader *my_marker_ptr;
#define INPUT_2BYTES(cinfo, V, action) \
MAKESTMT( MAKE_BYTE_AVAIL(cinfo, action); \
bytes_in_buffer--; \
V = ((unsigned int)GETJOCTET(*next_input_byte++)) << 8; \
V = ((unsigned int)(*next_input_byte++)) << 8; \
MAKE_BYTE_AVAIL(cinfo, action); \
bytes_in_buffer--; \
V += GETJOCTET(*next_input_byte++); )
V += *next_input_byte++; )
/*
@@ -608,18 +608,18 @@ examine_app0(j_decompress_ptr cinfo, JOCTET *data, unsigned int datalen,
JLONG totallen = (JLONG)datalen + remaining;
if (datalen >= APP0_DATA_LEN &&
GETJOCTET(data[0]) == 0x4A &&
GETJOCTET(data[1]) == 0x46 &&
GETJOCTET(data[2]) == 0x49 &&
GETJOCTET(data[3]) == 0x46 &&
GETJOCTET(data[4]) == 0) {
data[0] == 0x4A &&
data[1] == 0x46 &&
data[2] == 0x49 &&
data[3] == 0x46 &&
data[4] == 0) {
/* Found JFIF APP0 marker: save info */
cinfo->saw_JFIF_marker = TRUE;
cinfo->JFIF_major_version = GETJOCTET(data[5]);
cinfo->JFIF_minor_version = GETJOCTET(data[6]);
cinfo->density_unit = GETJOCTET(data[7]);
cinfo->X_density = (GETJOCTET(data[8]) << 8) + GETJOCTET(data[9]);
cinfo->Y_density = (GETJOCTET(data[10]) << 8) + GETJOCTET(data[11]);
cinfo->JFIF_major_version = data[5];
cinfo->JFIF_minor_version = data[6];
cinfo->density_unit = data[7];
cinfo->X_density = (data[8] << 8) + data[9];
cinfo->Y_density = (data[10] << 8) + data[11];
/* Check version.
* Major version must be 1, anything else signals an incompatible change.
* (We used to treat this as an error, but now it's a nonfatal warning,
@@ -634,24 +634,22 @@ examine_app0(j_decompress_ptr cinfo, JOCTET *data, unsigned int datalen,
cinfo->JFIF_major_version, cinfo->JFIF_minor_version,
cinfo->X_density, cinfo->Y_density, cinfo->density_unit);
/* Validate thumbnail dimensions and issue appropriate messages */
if (GETJOCTET(data[12]) | GETJOCTET(data[13]))
TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL,
GETJOCTET(data[12]), GETJOCTET(data[13]));
if (data[12] | data[13])
TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL, data[12], data[13]);
totallen -= APP0_DATA_LEN;
if (totallen !=
((JLONG)GETJOCTET(data[12]) * (JLONG)GETJOCTET(data[13]) * (JLONG)3))
if (totallen != ((JLONG)data[12] * (JLONG)data[13] * (JLONG)3))
TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int)totallen);
} else if (datalen >= 6 &&
GETJOCTET(data[0]) == 0x4A &&
GETJOCTET(data[1]) == 0x46 &&
GETJOCTET(data[2]) == 0x58 &&
GETJOCTET(data[3]) == 0x58 &&
GETJOCTET(data[4]) == 0) {
data[0] == 0x4A &&
data[1] == 0x46 &&
data[2] == 0x58 &&
data[3] == 0x58 &&
data[4] == 0) {
/* Found JFIF "JFXX" extension APP0 marker */
/* The library doesn't actually do anything with these,
* but we try to produce a helpful trace message.
*/
switch (GETJOCTET(data[5])) {
switch (data[5]) {
case 0x10:
TRACEMS1(cinfo, 1, JTRC_THUMB_JPEG, (int)totallen);
break;
@@ -662,8 +660,7 @@ examine_app0(j_decompress_ptr cinfo, JOCTET *data, unsigned int datalen,
TRACEMS1(cinfo, 1, JTRC_THUMB_RGB, (int)totallen);
break;
default:
TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION,
GETJOCTET(data[5]), (int)totallen);
TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION, data[5], (int)totallen);
break;
}
} else {
@@ -684,16 +681,16 @@ examine_app14(j_decompress_ptr cinfo, JOCTET *data, unsigned int datalen,
unsigned int version, flags0, flags1, transform;
if (datalen >= APP14_DATA_LEN &&
GETJOCTET(data[0]) == 0x41 &&
GETJOCTET(data[1]) == 0x64 &&
GETJOCTET(data[2]) == 0x6F &&
GETJOCTET(data[3]) == 0x62 &&
GETJOCTET(data[4]) == 0x65) {
data[0] == 0x41 &&
data[1] == 0x64 &&
data[2] == 0x6F &&
data[3] == 0x62 &&
data[4] == 0x65) {
/* Found Adobe APP14 marker */
version = (GETJOCTET(data[5]) << 8) + GETJOCTET(data[6]);
flags0 = (GETJOCTET(data[7]) << 8) + GETJOCTET(data[8]);
flags1 = (GETJOCTET(data[9]) << 8) + GETJOCTET(data[10]);
transform = GETJOCTET(data[11]);
version = (data[5] << 8) + data[6];
flags0 = (data[7] << 8) + data[8];
flags1 = (data[9] << 8) + data[10];
transform = data[11];
TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform);
cinfo->saw_Adobe_marker = TRUE;
cinfo->Adobe_transform = (UINT8)transform;
+2 -13
View File
@@ -5,7 +5,7 @@
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2002-2009 by Guido Vollbeding.
* libjpeg-turbo Modifications:
* Copyright (C) 2009-2011, 2016, D. R. Commander.
* Copyright (C) 2009-2011, 2016, 2019, D. R. Commander.
* Copyright (C) 2013, Linaro Limited.
* Copyright (C) 2015, Google, Inc.
* For conditions of distribution and use, see the accompanying README.ijg
@@ -22,7 +22,6 @@
#include "jpeglib.h"
#include "jpegcomp.h"
#include "jdmaster.h"
#include "jsimd.h"
/*
@@ -70,17 +69,6 @@ use_merged_upsample(j_decompress_ptr cinfo)
cinfo->comp_info[1]._DCT_scaled_size != cinfo->_min_DCT_scaled_size ||
cinfo->comp_info[2]._DCT_scaled_size != cinfo->_min_DCT_scaled_size)
return FALSE;
#ifdef WITH_SIMD
/* If YCbCr-to-RGB color conversion is SIMD-accelerated but merged upsampling
isn't, then disabling merged upsampling is likely to be faster when
decompressing YCbCr JPEG images. */
if (!jsimd_can_h2v2_merged_upsample() && !jsimd_can_h2v1_merged_upsample() &&
jsimd_can_ycc_rgb() && cinfo->jpeg_color_space == JCS_YCbCr &&
(cinfo->out_color_space == JCS_RGB ||
(cinfo->out_color_space >= JCS_EXT_RGB &&
cinfo->out_color_space <= JCS_EXT_ARGB)))
return FALSE;
#endif
/* ??? also need to test for upsample-time rescaling, when & if supported */
return TRUE; /* by golly, it'll work... */
#else
@@ -580,6 +568,7 @@ master_selection(j_decompress_ptr cinfo)
*/
cinfo->master->first_iMCU_col = 0;
cinfo->master->last_iMCU_col = cinfo->MCUs_per_row - 1;
cinfo->master->last_good_iMCU_row = 0;
#ifdef D_MULTISCAN_FILES_SUPPORTED
/* If jpeg_start_decompress will read the whole file, initialize
+34 -34
View File
@@ -43,20 +43,20 @@ h2v1_merged_upsample_565_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
/* Loop for each pair of output pixels */
for (col = cinfo->output_width >> 1; col > 0; col--) {
/* Do the chroma part of the calculation */
cb = GETJSAMPLE(*inptr1++);
cr = GETJSAMPLE(*inptr2++);
cb = *inptr1++;
cr = *inptr2++;
cred = Crrtab[cr];
cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
cblue = Cbbtab[cb];
/* Fetch 2 Y values and emit 2 pixels */
y = GETJSAMPLE(*inptr0++);
y = *inptr0++;
r = range_limit[y + cred];
g = range_limit[y + cgreen];
b = range_limit[y + cblue];
rgb = PACK_SHORT_565(r, g, b);
y = GETJSAMPLE(*inptr0++);
y = *inptr0++;
r = range_limit[y + cred];
g = range_limit[y + cgreen];
b = range_limit[y + cblue];
@@ -68,12 +68,12 @@ h2v1_merged_upsample_565_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
/* If image width is odd, do the last output column separately */
if (cinfo->output_width & 1) {
cb = GETJSAMPLE(*inptr1);
cr = GETJSAMPLE(*inptr2);
cb = *inptr1;
cr = *inptr2;
cred = Crrtab[cr];
cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
cblue = Cbbtab[cb];
y = GETJSAMPLE(*inptr0);
y = *inptr0;
r = range_limit[y + cred];
g = range_limit[y + cgreen];
b = range_limit[y + cblue];
@@ -115,21 +115,21 @@ h2v1_merged_upsample_565D_internal(j_decompress_ptr cinfo,
/* Loop for each pair of output pixels */
for (col = cinfo->output_width >> 1; col > 0; col--) {
/* Do the chroma part of the calculation */
cb = GETJSAMPLE(*inptr1++);
cr = GETJSAMPLE(*inptr2++);
cb = *inptr1++;
cr = *inptr2++;
cred = Crrtab[cr];
cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
cblue = Cbbtab[cb];
/* Fetch 2 Y values and emit 2 pixels */
y = GETJSAMPLE(*inptr0++);
y = *inptr0++;
r = range_limit[DITHER_565_R(y + cred, d0)];
g = range_limit[DITHER_565_G(y + cgreen, d0)];
b = range_limit[DITHER_565_B(y + cblue, d0)];
d0 = DITHER_ROTATE(d0);
rgb = PACK_SHORT_565(r, g, b);
y = GETJSAMPLE(*inptr0++);
y = *inptr0++;
r = range_limit[DITHER_565_R(y + cred, d0)];
g = range_limit[DITHER_565_G(y + cgreen, d0)];
b = range_limit[DITHER_565_B(y + cblue, d0)];
@@ -142,12 +142,12 @@ h2v1_merged_upsample_565D_internal(j_decompress_ptr cinfo,
/* If image width is odd, do the last output column separately */
if (cinfo->output_width & 1) {
cb = GETJSAMPLE(*inptr1);
cr = GETJSAMPLE(*inptr2);
cb = *inptr1;
cr = *inptr2;
cred = Crrtab[cr];
cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
cblue = Cbbtab[cb];
y = GETJSAMPLE(*inptr0);
y = *inptr0;
r = range_limit[DITHER_565_R(y + cred, d0)];
g = range_limit[DITHER_565_G(y + cgreen, d0)];
b = range_limit[DITHER_565_B(y + cblue, d0)];
@@ -189,20 +189,20 @@ h2v2_merged_upsample_565_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
/* Loop for each group of output pixels */
for (col = cinfo->output_width >> 1; col > 0; col--) {
/* Do the chroma part of the calculation */
cb = GETJSAMPLE(*inptr1++);
cr = GETJSAMPLE(*inptr2++);
cb = *inptr1++;
cr = *inptr2++;
cred = Crrtab[cr];
cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
cblue = Cbbtab[cb];
/* Fetch 4 Y values and emit 4 pixels */
y = GETJSAMPLE(*inptr00++);
y = *inptr00++;
r = range_limit[y + cred];
g = range_limit[y + cgreen];
b = range_limit[y + cblue];
rgb = PACK_SHORT_565(r, g, b);
y = GETJSAMPLE(*inptr00++);
y = *inptr00++;
r = range_limit[y + cred];
g = range_limit[y + cgreen];
b = range_limit[y + cblue];
@@ -211,13 +211,13 @@ h2v2_merged_upsample_565_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
WRITE_TWO_PIXELS(outptr0, rgb);
outptr0 += 4;
y = GETJSAMPLE(*inptr01++);
y = *inptr01++;
r = range_limit[y + cred];
g = range_limit[y + cgreen];
b = range_limit[y + cblue];
rgb = PACK_SHORT_565(r, g, b);
y = GETJSAMPLE(*inptr01++);
y = *inptr01++;
r = range_limit[y + cred];
g = range_limit[y + cgreen];
b = range_limit[y + cblue];
@@ -229,20 +229,20 @@ h2v2_merged_upsample_565_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
/* If image width is odd, do the last output column separately */
if (cinfo->output_width & 1) {
cb = GETJSAMPLE(*inptr1);
cr = GETJSAMPLE(*inptr2);
cb = *inptr1;
cr = *inptr2;
cred = Crrtab[cr];
cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
cblue = Cbbtab[cb];
y = GETJSAMPLE(*inptr00);
y = *inptr00;
r = range_limit[y + cred];
g = range_limit[y + cgreen];
b = range_limit[y + cblue];
rgb = PACK_SHORT_565(r, g, b);
*(INT16 *)outptr0 = (INT16)rgb;
y = GETJSAMPLE(*inptr01);
y = *inptr01;
r = range_limit[y + cred];
g = range_limit[y + cgreen];
b = range_limit[y + cblue];
@@ -287,21 +287,21 @@ h2v2_merged_upsample_565D_internal(j_decompress_ptr cinfo,
/* Loop for each group of output pixels */
for (col = cinfo->output_width >> 1; col > 0; col--) {
/* Do the chroma part of the calculation */
cb = GETJSAMPLE(*inptr1++);
cr = GETJSAMPLE(*inptr2++);
cb = *inptr1++;
cr = *inptr2++;
cred = Crrtab[cr];
cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
cblue = Cbbtab[cb];
/* Fetch 4 Y values and emit 4 pixels */
y = GETJSAMPLE(*inptr00++);
y = *inptr00++;
r = range_limit[DITHER_565_R(y + cred, d0)];
g = range_limit[DITHER_565_G(y + cgreen, d0)];
b = range_limit[DITHER_565_B(y + cblue, d0)];
d0 = DITHER_ROTATE(d0);
rgb = PACK_SHORT_565(r, g, b);
y = GETJSAMPLE(*inptr00++);
y = *inptr00++;
r = range_limit[DITHER_565_R(y + cred, d0)];
g = range_limit[DITHER_565_G(y + cgreen, d0)];
b = range_limit[DITHER_565_B(y + cblue, d0)];
@@ -311,14 +311,14 @@ h2v2_merged_upsample_565D_internal(j_decompress_ptr cinfo,
WRITE_TWO_PIXELS(outptr0, rgb);
outptr0 += 4;
y = GETJSAMPLE(*inptr01++);
y = *inptr01++;
r = range_limit[DITHER_565_R(y + cred, d1)];
g = range_limit[DITHER_565_G(y + cgreen, d1)];
b = range_limit[DITHER_565_B(y + cblue, d1)];
d1 = DITHER_ROTATE(d1);
rgb = PACK_SHORT_565(r, g, b);
y = GETJSAMPLE(*inptr01++);
y = *inptr01++;
r = range_limit[DITHER_565_R(y + cred, d1)];
g = range_limit[DITHER_565_G(y + cgreen, d1)];
b = range_limit[DITHER_565_B(y + cblue, d1)];
@@ -331,20 +331,20 @@ h2v2_merged_upsample_565D_internal(j_decompress_ptr cinfo,
/* If image width is odd, do the last output column separately */
if (cinfo->output_width & 1) {
cb = GETJSAMPLE(*inptr1);
cr = GETJSAMPLE(*inptr2);
cb = *inptr1;
cr = *inptr2;
cred = Crrtab[cr];
cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
cblue = Cbbtab[cb];
y = GETJSAMPLE(*inptr00);
y = *inptr00;
r = range_limit[DITHER_565_R(y + cred, d0)];
g = range_limit[DITHER_565_G(y + cgreen, d0)];
b = range_limit[DITHER_565_B(y + cblue, d0)];
rgb = PACK_SHORT_565(r, g, b);
*(INT16 *)outptr0 = (INT16)rgb;
y = GETJSAMPLE(*inptr01);
y = *inptr01;
r = range_limit[DITHER_565_R(y + cred, d1)];
g = range_limit[DITHER_565_G(y + cgreen, d1)];
b = range_limit[DITHER_565_B(y + cblue, d1)];
+17 -17
View File
@@ -46,13 +46,13 @@ h2v1_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
/* Loop for each pair of output pixels */
for (col = cinfo->output_width >> 1; col > 0; col--) {
/* Do the chroma part of the calculation */
cb = GETJSAMPLE(*inptr1++);
cr = GETJSAMPLE(*inptr2++);
cb = *inptr1++;
cr = *inptr2++;
cred = Crrtab[cr];
cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
cblue = Cbbtab[cb];
/* Fetch 2 Y values and emit 2 pixels */
y = GETJSAMPLE(*inptr0++);
y = *inptr0++;
outptr[RGB_RED] = range_limit[y + cred];
outptr[RGB_GREEN] = range_limit[y + cgreen];
outptr[RGB_BLUE] = range_limit[y + cblue];
@@ -60,7 +60,7 @@ h2v1_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
outptr[RGB_ALPHA] = 0xFF;
#endif
outptr += RGB_PIXELSIZE;
y = GETJSAMPLE(*inptr0++);
y = *inptr0++;
outptr[RGB_RED] = range_limit[y + cred];
outptr[RGB_GREEN] = range_limit[y + cgreen];
outptr[RGB_BLUE] = range_limit[y + cblue];
@@ -71,12 +71,12 @@ h2v1_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
}
/* If image width is odd, do the last output column separately */
if (cinfo->output_width & 1) {
cb = GETJSAMPLE(*inptr1);
cr = GETJSAMPLE(*inptr2);
cb = *inptr1;
cr = *inptr2;
cred = Crrtab[cr];
cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
cblue = Cbbtab[cb];
y = GETJSAMPLE(*inptr0);
y = *inptr0;
outptr[RGB_RED] = range_limit[y + cred];
outptr[RGB_GREEN] = range_limit[y + cgreen];
outptr[RGB_BLUE] = range_limit[y + cblue];
@@ -120,13 +120,13 @@ h2v2_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
/* Loop for each group of output pixels */
for (col = cinfo->output_width >> 1; col > 0; col--) {
/* Do the chroma part of the calculation */
cb = GETJSAMPLE(*inptr1++);
cr = GETJSAMPLE(*inptr2++);
cb = *inptr1++;
cr = *inptr2++;
cred = Crrtab[cr];
cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
cblue = Cbbtab[cb];
/* Fetch 4 Y values and emit 4 pixels */
y = GETJSAMPLE(*inptr00++);
y = *inptr00++;
outptr0[RGB_RED] = range_limit[y + cred];
outptr0[RGB_GREEN] = range_limit[y + cgreen];
outptr0[RGB_BLUE] = range_limit[y + cblue];
@@ -134,7 +134,7 @@ h2v2_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
outptr0[RGB_ALPHA] = 0xFF;
#endif
outptr0 += RGB_PIXELSIZE;
y = GETJSAMPLE(*inptr00++);
y = *inptr00++;
outptr0[RGB_RED] = range_limit[y + cred];
outptr0[RGB_GREEN] = range_limit[y + cgreen];
outptr0[RGB_BLUE] = range_limit[y + cblue];
@@ -142,7 +142,7 @@ h2v2_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
outptr0[RGB_ALPHA] = 0xFF;
#endif
outptr0 += RGB_PIXELSIZE;
y = GETJSAMPLE(*inptr01++);
y = *inptr01++;
outptr1[RGB_RED] = range_limit[y + cred];
outptr1[RGB_GREEN] = range_limit[y + cgreen];
outptr1[RGB_BLUE] = range_limit[y + cblue];
@@ -150,7 +150,7 @@ h2v2_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
outptr1[RGB_ALPHA] = 0xFF;
#endif
outptr1 += RGB_PIXELSIZE;
y = GETJSAMPLE(*inptr01++);
y = *inptr01++;
outptr1[RGB_RED] = range_limit[y + cred];
outptr1[RGB_GREEN] = range_limit[y + cgreen];
outptr1[RGB_BLUE] = range_limit[y + cblue];
@@ -161,19 +161,19 @@ h2v2_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
}
/* If image width is odd, do the last output column separately */
if (cinfo->output_width & 1) {
cb = GETJSAMPLE(*inptr1);
cr = GETJSAMPLE(*inptr2);
cb = *inptr1;
cr = *inptr2;
cred = Crrtab[cr];
cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
cblue = Cbbtab[cb];
y = GETJSAMPLE(*inptr00);
y = *inptr00;
outptr0[RGB_RED] = range_limit[y + cred];
outptr0[RGB_GREEN] = range_limit[y + cgreen];
outptr0[RGB_BLUE] = range_limit[y + cblue];
#ifdef RGB_ALPHA
outptr0[RGB_ALPHA] = 0xFF;
#endif
y = GETJSAMPLE(*inptr01);
y = *inptr01;
outptr1[RGB_RED] = range_limit[y + cred];
outptr1[RGB_GREEN] = range_limit[y + cgreen];
outptr1[RGB_BLUE] = range_limit[y + cblue];
+20 -28
View File
@@ -4,7 +4,7 @@
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1995-1997, Thomas G. Lane.
* libjpeg-turbo Modifications:
* Copyright (C) 2015-2016, 2018, D. R. Commander.
* Copyright (C) 2015-2016, 2018-2021, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -41,25 +41,6 @@ typedef struct {
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).EOBRUN = (src).EOBRUN, \
(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_decoder pub; /* public fields */
@@ -102,7 +83,7 @@ start_pass_phuff_decoder(j_decompress_ptr cinfo)
boolean is_DC_band, bad;
int ci, coefi, tbl;
d_derived_tbl **pdtbl;
int *coef_bit_ptr;
int *coef_bit_ptr, *prev_coef_bit_ptr;
jpeg_component_info *compptr;
is_DC_band = (cinfo->Ss == 0);
@@ -143,8 +124,15 @@ start_pass_phuff_decoder(j_decompress_ptr cinfo)
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
int cindex = cinfo->cur_comp_info[ci]->component_index;
coef_bit_ptr = &cinfo->coef_bits[cindex][0];
prev_coef_bit_ptr = &cinfo->coef_bits[cindex + cinfo->num_components][0];
if (!is_DC_band && coef_bit_ptr[0] < 0) /* AC without prior DC scan */
WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, 0);
for (coefi = MIN(cinfo->Ss, 1); coefi <= MAX(cinfo->Se, 9); coefi++) {
if (cinfo->input_scan_number > 1)
prev_coef_bit_ptr[coefi] = coef_bit_ptr[coefi];
else
prev_coef_bit_ptr[coefi] = 0;
}
for (coefi = cinfo->Ss; coefi <= cinfo->Se; coefi++) {
int expected = (coef_bit_ptr[coefi] < 0) ? 0 : coef_bit_ptr[coefi];
if (cinfo->Ah != expected)
@@ -323,7 +311,7 @@ decode_mcu_DC_first(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
/* Load up working state */
BITREAD_LOAD_STATE(cinfo, entropy->bitstate);
ASSIGN_STATE(state, entropy->saved);
state = entropy->saved;
/* Outer loop handles each block in the MCU */
@@ -356,11 +344,12 @@ decode_mcu_DC_first(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
/* Completed MCU, so update state */
BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
ASSIGN_STATE(entropy->saved, state);
entropy->saved = state;
}
/* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--;
if (cinfo->restart_interval)
entropy->restarts_to_go--;
return TRUE;
}
@@ -444,7 +433,8 @@ decode_mcu_AC_first(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
}
/* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--;
if (cinfo->restart_interval)
entropy->restarts_to_go--;
return TRUE;
}
@@ -495,7 +485,8 @@ decode_mcu_DC_refine(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
/* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--;
if (cinfo->restart_interval)
entropy->restarts_to_go--;
return TRUE;
}
@@ -638,7 +629,8 @@ decode_mcu_AC_refine(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
}
/* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--;
if (cinfo->restart_interval)
entropy->restarts_to_go--;
return TRUE;
@@ -676,7 +668,7 @@ jinit_phuff_decoder(j_decompress_ptr cinfo)
/* Create progression status table */
cinfo->coef_bits = (int (*)[DCTSIZE2])
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
cinfo->num_components * DCTSIZE2 *
cinfo->num_components * 2 * DCTSIZE2 *
sizeof(int));
coef_bit_ptr = &cinfo->coef_bits[0][0];
for (ci = 0; ci < cinfo->num_components; ci++)
+22 -16
View File
@@ -8,7 +8,7 @@
* Copyright (C) 2010, 2015-2016, D. R. Commander.
* Copyright (C) 2014, MIPS Technologies, Inc., California.
* Copyright (C) 2015, Google, Inc.
* Copyright (C) 2019, Arm Limited.
* Copyright (C) 2019-2020, Arm Limited.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -177,7 +177,7 @@ int_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
outptr = output_data[outrow];
outend = outptr + cinfo->output_width;
while (outptr < outend) {
invalue = *inptr++; /* don't need GETJSAMPLE() here */
invalue = *inptr++;
for (h = h_expand; h > 0; h--) {
*outptr++ = invalue;
}
@@ -213,7 +213,7 @@ h2v1_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
outptr = output_data[inrow];
outend = outptr + cinfo->output_width;
while (outptr < outend) {
invalue = *inptr++; /* don't need GETJSAMPLE() here */
invalue = *inptr++;
*outptr++ = invalue;
*outptr++ = invalue;
}
@@ -242,7 +242,7 @@ h2v2_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
outptr = output_data[outrow];
outend = outptr + cinfo->output_width;
while (outptr < outend) {
invalue = *inptr++; /* don't need GETJSAMPLE() here */
invalue = *inptr++;
*outptr++ = invalue;
*outptr++ = invalue;
}
@@ -283,20 +283,20 @@ h2v1_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
inptr = input_data[inrow];
outptr = output_data[inrow];
/* Special case for first column */
invalue = GETJSAMPLE(*inptr++);
invalue = *inptr++;
*outptr++ = (JSAMPLE)invalue;
*outptr++ = (JSAMPLE)((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2);
*outptr++ = (JSAMPLE)((invalue * 3 + inptr[0] + 2) >> 2);
for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
/* General case: 3/4 * nearer pixel + 1/4 * further pixel */
invalue = GETJSAMPLE(*inptr++) * 3;
*outptr++ = (JSAMPLE)((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2);
*outptr++ = (JSAMPLE)((invalue + GETJSAMPLE(*inptr) + 2) >> 2);
invalue = (*inptr++) * 3;
*outptr++ = (JSAMPLE)((invalue + inptr[-2] + 1) >> 2);
*outptr++ = (JSAMPLE)((invalue + inptr[0] + 2) >> 2);
}
/* Special case for last column */
invalue = GETJSAMPLE(*inptr);
*outptr++ = (JSAMPLE)((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2);
invalue = *inptr;
*outptr++ = (JSAMPLE)((invalue * 3 + inptr[-1] + 1) >> 2);
*outptr++ = (JSAMPLE)invalue;
}
}
@@ -338,7 +338,7 @@ h1v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
outptr = output_data[outrow++];
for (colctr = 0; colctr < compptr->downsampled_width; colctr++) {
thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
thiscolsum = (*inptr0++) * 3 + (*inptr1++);
*outptr++ = (JSAMPLE)((thiscolsum + bias) >> 2);
}
}
@@ -381,8 +381,8 @@ h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
outptr = output_data[outrow++];
/* Special case for first column */
thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
thiscolsum = (*inptr0++) * 3 + (*inptr1++);
nextcolsum = (*inptr0++) * 3 + (*inptr1++);
*outptr++ = (JSAMPLE)((thiscolsum * 4 + 8) >> 4);
*outptr++ = (JSAMPLE)((thiscolsum * 3 + nextcolsum + 7) >> 4);
lastcolsum = thiscolsum; thiscolsum = nextcolsum;
@@ -390,7 +390,7 @@ h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
/* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */
/* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */
nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
nextcolsum = (*inptr0++) * 3 + (*inptr1++);
*outptr++ = (JSAMPLE)((thiscolsum * 3 + lastcolsum + 8) >> 4);
*outptr++ = (JSAMPLE)((thiscolsum * 3 + nextcolsum + 7) >> 4);
lastcolsum = thiscolsum; thiscolsum = nextcolsum;
@@ -477,7 +477,13 @@ jinit_upsampler(j_decompress_ptr cinfo)
} else if (h_in_group == h_out_group &&
v_in_group * 2 == v_out_group && do_fancy) {
/* Non-fancy upsampling is handled by the generic method */
upsample->methods[ci] = h1v2_fancy_upsample;
#if defined(__arm__) || defined(__aarch64__) || \
defined(_M_ARM) || defined(_M_ARM64)
if (jsimd_can_h1v2_fancy_upsample())
upsample->methods[ci] = jsimd_h1v2_fancy_upsample;
else
#endif
upsample->methods[ci] = h1v2_fancy_upsample;
upsample->pub.need_context_rows = TRUE;
} else if (h_in_group * 2 == h_out_group &&
v_in_group * 2 == v_out_group) {
+13
View File
@@ -207,6 +207,10 @@ JMESSAGE(JWRN_ARITH_BAD_CODE, "Corrupt JPEG data: bad arithmetic code")
#endif
#endif
JMESSAGE(JWRN_BOGUS_ICC, "Corrupt JPEG data: bad ICC marker")
#if JPEG_LIB_VERSION < 70
JMESSAGE(JERR_BAD_DROP_SAMPLING,
"Component index %d: mismatching sampling ratio %d:%d, %d:%d, %c")
#endif
#ifdef JMAKE_ENUM_LIST
@@ -252,6 +256,15 @@ JMESSAGE(JWRN_BOGUS_ICC, "Corrupt JPEG data: bad ICC marker")
(cinfo)->err->msg_parm.i[2] = (p3), \
(cinfo)->err->msg_parm.i[3] = (p4), \
(*(cinfo)->err->error_exit) ((j_common_ptr)(cinfo)))
#define ERREXIT6(cinfo, code, p1, p2, p3, p4, p5, p6) \
((cinfo)->err->msg_code = (code), \
(cinfo)->err->msg_parm.i[0] = (p1), \
(cinfo)->err->msg_parm.i[1] = (p2), \
(cinfo)->err->msg_parm.i[2] = (p3), \
(cinfo)->err->msg_parm.i[3] = (p4), \
(cinfo)->err->msg_parm.i[4] = (p5), \
(cinfo)->err->msg_parm.i[5] = (p6), \
(*(cinfo)->err->error_exit) ((j_common_ptr)(cinfo)))
#define ERREXITS(cinfo, code, str) \
((cinfo)->err->msg_code = (code), \
strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
+4 -4
View File
@@ -3,7 +3,7 @@
*
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-1998, Thomas G. Lane.
* Modification developed 2002-2009 by Guido Vollbeding.
* Modification developed 2002-2018 by Guido Vollbeding.
* libjpeg-turbo Modifications:
* Copyright (C) 2015, 2020, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
@@ -417,7 +417,7 @@ jpeg_idct_islow(j_decompress_ptr cinfo, jpeg_component_info *compptr,
/*
* Perform dequantization and inverse DCT on one block of coefficients,
* producing a 7x7 output block.
* producing a reduced-size 7x7 output block.
*
* Optimized algorithm with 12 multiplications in the 1-D kernel.
* cK represents sqrt(2) * cos(K*pi/14).
@@ -1258,7 +1258,7 @@ jpeg_idct_10x10(j_decompress_ptr cinfo, jpeg_component_info *compptr,
/*
* Perform dequantization and inverse DCT on one block of coefficients,
* producing a 11x11 output block.
* producing an 11x11 output block.
*
* Optimized algorithm with 24 multiplications in the 1-D kernel.
* cK represents sqrt(2) * cos(K*pi/22).
@@ -2398,7 +2398,7 @@ jpeg_idct_16x16(j_decompress_ptr cinfo, jpeg_component_info *compptr,
tmp0 = DEQUANTIZE(inptr[DCTSIZE * 0], quantptr[DCTSIZE * 0]);
tmp0 = LEFT_SHIFT(tmp0, CONST_BITS);
/* Add fudge factor here for final descale. */
tmp0 += 1 << (CONST_BITS - PASS1_BITS - 1);
tmp0 += ONE << (CONST_BITS - PASS1_BITS - 1);
z1 = DEQUANTIZE(inptr[DCTSIZE * 4], quantptr[DCTSIZE * 4]);
tmp1 = MULTIPLY(z1, FIX(1.306562965)); /* c4[16] = c2[8] */
-35
View File
@@ -43,25 +43,11 @@
#if BITS_IN_JSAMPLE == 8
/* JSAMPLE should be the smallest type that will hold the values 0..255.
* You can use a signed char by having GETJSAMPLE mask it with 0xFF.
*/
#ifdef HAVE_UNSIGNED_CHAR
typedef unsigned char JSAMPLE;
#define GETJSAMPLE(value) ((int)(value))
#else /* not HAVE_UNSIGNED_CHAR */
typedef char JSAMPLE;
#ifdef __CHAR_UNSIGNED__
#define GETJSAMPLE(value) ((int)(value))
#else
#define GETJSAMPLE(value) ((int)(value) & 0xFF)
#endif /* __CHAR_UNSIGNED__ */
#endif /* HAVE_UNSIGNED_CHAR */
#define MAXJSAMPLE 255
#define CENTERJSAMPLE 128
@@ -97,22 +83,9 @@ typedef short JCOEF;
* managers, this is also the data type passed to fread/fwrite.
*/
#ifdef HAVE_UNSIGNED_CHAR
typedef unsigned char JOCTET;
#define GETJOCTET(value) (value)
#else /* not HAVE_UNSIGNED_CHAR */
typedef char JOCTET;
#ifdef __CHAR_UNSIGNED__
#define GETJOCTET(value) (value)
#else
#define GETJOCTET(value) ((value) & 0xFF)
#endif /* __CHAR_UNSIGNED__ */
#endif /* HAVE_UNSIGNED_CHAR */
/* These typedefs are used for various table entries and so forth.
* They must be at least as wide as specified; but making them too big
@@ -123,15 +96,7 @@ typedef char JOCTET;
/* UINT8 must hold at least the values 0..255. */
#ifdef HAVE_UNSIGNED_CHAR
typedef unsigned char UINT8;
#else /* not HAVE_UNSIGNED_CHAR */
#ifdef __CHAR_UNSIGNED__
typedef char UINT8;
#else /* not __CHAR_UNSIGNED__ */
typedef short UINT8;
#endif /* __CHAR_UNSIGNED__ */
#endif /* HAVE_UNSIGNED_CHAR */
/* UINT16 must hold at least the values 0..65535. */
+4 -1
View File
@@ -5,7 +5,7 @@
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 1997-2009 by Guido Vollbeding.
* libjpeg-turbo Modifications:
* Copyright (C) 2015-2016, D. R. Commander.
* Copyright (C) 2015-2016, 2019, D. R. Commander.
* Copyright (C) 2015, Google, Inc.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
@@ -158,6 +158,9 @@ struct jpeg_decomp_master {
JDIMENSION first_MCU_col[MAX_COMPONENTS];
JDIMENSION last_MCU_col[MAX_COMPONENTS];
boolean jinit_upsampler_no_alloc;
/* Last iMCU row that was successfully decoded */
JDIMENSION last_good_iMCU_row;
};
/* Input control module */
+12 -15
View File
@@ -479,7 +479,7 @@ color_quantize(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
for (col = width; col > 0; col--) {
pixcode = 0;
for (ci = 0; ci < nc; ci++) {
pixcode += GETJSAMPLE(colorindex[ci][GETJSAMPLE(*ptrin++)]);
pixcode += colorindex[ci][*ptrin++];
}
*ptrout++ = (JSAMPLE)pixcode;
}
@@ -506,9 +506,9 @@ color_quantize3(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
ptrin = input_buf[row];
ptrout = output_buf[row];
for (col = width; col > 0; col--) {
pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*ptrin++)]);
pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*ptrin++)]);
pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*ptrin++)]);
pixcode = colorindex0[*ptrin++];
pixcode += colorindex1[*ptrin++];
pixcode += colorindex2[*ptrin++];
*ptrout++ = (JSAMPLE)pixcode;
}
}
@@ -552,7 +552,7 @@ quantize_ord_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
* required amount of padding.
*/
*output_ptr +=
colorindex_ci[GETJSAMPLE(*input_ptr) + dither[col_index]];
colorindex_ci[*input_ptr + dither[col_index]];
input_ptr += nc;
output_ptr++;
col_index = (col_index + 1) & ODITHER_MASK;
@@ -595,12 +595,9 @@ quantize3_ord_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
col_index = 0;
for (col = width; col > 0; col--) {
pixcode =
GETJSAMPLE(colorindex0[GETJSAMPLE(*input_ptr++) + dither0[col_index]]);
pixcode +=
GETJSAMPLE(colorindex1[GETJSAMPLE(*input_ptr++) + dither1[col_index]]);
pixcode +=
GETJSAMPLE(colorindex2[GETJSAMPLE(*input_ptr++) + dither2[col_index]]);
pixcode = colorindex0[(*input_ptr++) + dither0[col_index]];
pixcode += colorindex1[(*input_ptr++) + dither1[col_index]];
pixcode += colorindex2[(*input_ptr++) + dither2[col_index]];
*output_ptr++ = (JSAMPLE)pixcode;
col_index = (col_index + 1) & ODITHER_MASK;
}
@@ -677,15 +674,15 @@ quantize_fs_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
* The maximum error is +- MAXJSAMPLE; this sets the required size
* of the range_limit array.
*/
cur += GETJSAMPLE(*input_ptr);
cur = GETJSAMPLE(range_limit[cur]);
cur += *input_ptr;
cur = range_limit[cur];
/* Select output value, accumulate into output code for this pixel */
pixcode = GETJSAMPLE(colorindex_ci[cur]);
pixcode = colorindex_ci[cur];
*output_ptr += (JSAMPLE)pixcode;
/* Compute actual representation error at this pixel */
/* Note: we can do this even though we don't have the final */
/* pixel code, because the colormap is orthogonal. */
cur -= GETJSAMPLE(colormap_ci[pixcode]);
cur -= colormap_ci[pixcode];
/* Compute error fractions to be propagated to adjacent pixels.
* Add these into the running sums, and simultaneously shift the
* next-line error sums left by 1 column.
+23 -23
View File
@@ -215,9 +215,9 @@ prescan_quantize(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
ptr = input_buf[row];
for (col = width; col > 0; col--) {
/* get pixel value and index into the histogram */
histp = &histogram[GETJSAMPLE(ptr[0]) >> C0_SHIFT]
[GETJSAMPLE(ptr[1]) >> C1_SHIFT]
[GETJSAMPLE(ptr[2]) >> C2_SHIFT];
histp = &histogram[ptr[0] >> C0_SHIFT]
[ptr[1] >> C1_SHIFT]
[ptr[2] >> C2_SHIFT];
/* increment, check for overflow and undo increment if so. */
if (++(*histp) <= 0)
(*histp)--;
@@ -665,7 +665,7 @@ find_nearby_colors(j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
for (i = 0; i < numcolors; i++) {
/* We compute the squared-c0-distance term, then add in the other two. */
x = GETJSAMPLE(cinfo->colormap[0][i]);
x = cinfo->colormap[0][i];
if (x < minc0) {
tdist = (x - minc0) * C0_SCALE;
min_dist = tdist * tdist;
@@ -688,7 +688,7 @@ find_nearby_colors(j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
}
}
x = GETJSAMPLE(cinfo->colormap[1][i]);
x = cinfo->colormap[1][i];
if (x < minc1) {
tdist = (x - minc1) * C1_SCALE;
min_dist += tdist * tdist;
@@ -710,7 +710,7 @@ find_nearby_colors(j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
}
}
x = GETJSAMPLE(cinfo->colormap[2][i]);
x = cinfo->colormap[2][i];
if (x < minc2) {
tdist = (x - minc2) * C2_SCALE;
min_dist += tdist * tdist;
@@ -788,13 +788,13 @@ find_best_colors(j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
#define STEP_C2 ((1 << C2_SHIFT) * C2_SCALE)
for (i = 0; i < numcolors; i++) {
icolor = GETJSAMPLE(colorlist[i]);
icolor = colorlist[i];
/* Compute (square of) distance from minc0/c1/c2 to this color */
inc0 = (minc0 - GETJSAMPLE(cinfo->colormap[0][icolor])) * C0_SCALE;
inc0 = (minc0 - cinfo->colormap[0][icolor]) * C0_SCALE;
dist0 = inc0 * inc0;
inc1 = (minc1 - GETJSAMPLE(cinfo->colormap[1][icolor])) * C1_SCALE;
inc1 = (minc1 - cinfo->colormap[1][icolor]) * C1_SCALE;
dist0 += inc1 * inc1;
inc2 = (minc2 - GETJSAMPLE(cinfo->colormap[2][icolor])) * C2_SCALE;
inc2 = (minc2 - cinfo->colormap[2][icolor]) * C2_SCALE;
dist0 += inc2 * inc2;
/* Form the initial difference increments */
inc0 = inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0;
@@ -879,7 +879,7 @@ fill_inverse_cmap(j_decompress_ptr cinfo, int c0, int c1, int c2)
for (ic1 = 0; ic1 < BOX_C1_ELEMS; ic1++) {
cachep = &histogram[c0 + ic0][c1 + ic1][c2];
for (ic2 = 0; ic2 < BOX_C2_ELEMS; ic2++) {
*cachep++ = (histcell)(GETJSAMPLE(*cptr++) + 1);
*cachep++ = (histcell)((*cptr++) + 1);
}
}
}
@@ -909,9 +909,9 @@ pass2_no_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
outptr = output_buf[row];
for (col = width; col > 0; col--) {
/* get pixel value and index into the cache */
c0 = GETJSAMPLE(*inptr++) >> C0_SHIFT;
c1 = GETJSAMPLE(*inptr++) >> C1_SHIFT;
c2 = GETJSAMPLE(*inptr++) >> C2_SHIFT;
c0 = (*inptr++) >> C0_SHIFT;
c1 = (*inptr++) >> C1_SHIFT;
c2 = (*inptr++) >> C2_SHIFT;
cachep = &histogram[c0][c1][c2];
/* If we have not seen this color before, find nearest colormap entry */
/* and update the cache */
@@ -996,12 +996,12 @@ pass2_fs_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
* The maximum error is +- MAXJSAMPLE (or less with error limiting);
* this sets the required size of the range_limit array.
*/
cur0 += GETJSAMPLE(inptr[0]);
cur1 += GETJSAMPLE(inptr[1]);
cur2 += GETJSAMPLE(inptr[2]);
cur0 = GETJSAMPLE(range_limit[cur0]);
cur1 = GETJSAMPLE(range_limit[cur1]);
cur2 = GETJSAMPLE(range_limit[cur2]);
cur0 += inptr[0];
cur1 += inptr[1];
cur2 += inptr[2];
cur0 = range_limit[cur0];
cur1 = range_limit[cur1];
cur2 = range_limit[cur2];
/* Index into the cache with adjusted pixel value */
cachep =
&histogram[cur0 >> C0_SHIFT][cur1 >> C1_SHIFT][cur2 >> C2_SHIFT];
@@ -1015,9 +1015,9 @@ pass2_fs_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
register int pixcode = *cachep - 1;
*outptr = (JSAMPLE)pixcode;
/* Compute representation error for this pixel */
cur0 -= GETJSAMPLE(colormap0[pixcode]);
cur1 -= GETJSAMPLE(colormap1[pixcode]);
cur2 -= GETJSAMPLE(colormap2[pixcode]);
cur0 -= colormap0[pixcode];
cur1 -= colormap1[pixcode];
cur2 -= colormap2[pixcode];
}
/* Compute error fractions to be propagated to adjacent pixels.
* Add these into the running sums, and simultaneously shift the
+6
View File
@@ -4,6 +4,7 @@
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
* Copyright (C) 2011, 2014, D. R. Commander.
* Copyright (C) 2015-2016, 2018, Matthieu Darbois.
* Copyright (C) 2020, Arm Limited.
*
* Based on the x86 SIMD extension for IJG JPEG library,
* Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -75,6 +76,7 @@ EXTERN(void) jsimd_int_upsample(j_decompress_ptr cinfo,
EXTERN(int) jsimd_can_h2v2_fancy_upsample(void);
EXTERN(int) jsimd_can_h2v1_fancy_upsample(void);
EXTERN(int) jsimd_can_h1v2_fancy_upsample(void);
EXTERN(void) jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo,
jpeg_component_info *compptr,
@@ -84,6 +86,10 @@ EXTERN(void) jsimd_h2v1_fancy_upsample(j_decompress_ptr cinfo,
jpeg_component_info *compptr,
JSAMPARRAY input_data,
JSAMPARRAY *output_data_ptr);
EXTERN(void) jsimd_h1v2_fancy_upsample(j_decompress_ptr cinfo,
jpeg_component_info *compptr,
JSAMPARRAY input_data,
JSAMPARRAY *output_data_ptr);
EXTERN(int) jsimd_can_h2v2_merged_upsample(void);
EXTERN(int) jsimd_can_h2v1_merged_upsample(void);
+13
View File
@@ -4,6 +4,7 @@
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
* Copyright (C) 2009-2011, 2014, D. R. Commander.
* Copyright (C) 2015-2016, 2018, Matthieu Darbois.
* Copyright (C) 2020, Arm Limited.
*
* Based on the x86 SIMD extension for IJG JPEG library,
* Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -169,6 +170,12 @@ jsimd_can_h2v1_fancy_upsample(void)
return 0;
}
GLOBAL(int)
jsimd_can_h1v2_fancy_upsample(void)
{
return 0;
}
GLOBAL(void)
jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
@@ -181,6 +188,12 @@ jsimd_h2v1_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
{
}
GLOBAL(void)
jsimd_h1v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
{
}
GLOBAL(int)
jsimd_can_h2v2_merged_upsample(void)
{
+6 -6
View File
@@ -2,9 +2,9 @@
* jversion.h
*
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-2012, Thomas G. Lane, Guido Vollbeding.
* Copyright (C) 1991-2020, Thomas G. Lane, Guido Vollbeding.
* libjpeg-turbo Modifications:
* Copyright (C) 2010, 2012-2020, D. R. Commander.
* Copyright (C) 2010, 2012-2021, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -37,9 +37,9 @@
*/
#define JCOPYRIGHT \
"Copyright (C) 2009-2020 D. R. Commander\n" \
"Copyright (C) 2009-2021 D. R. Commander\n" \
"Copyright (C) 2015, 2020 Google, Inc.\n" \
"Copyright (C) 2019 Arm Limited\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" \
@@ -48,7 +48,7 @@
"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) 1991-2017 Thomas G. Lane, Guido Vollbeding"
"Copyright (C) 1991-2020 Thomas G. Lane, Guido Vollbeding"
#define JCOPYRIGHT_SHORT \
"Copyright (C) 1991-2020 The libjpeg-turbo Project and many others"
"Copyright (C) 1991-2021 The libjpeg-turbo Project and many others"
+3
View File
@@ -239,6 +239,9 @@ if(HOST_BIG_ENDIAN)
else()
set(HOST_BIG_ENDIAN 0)
endif()
if(HOST_BIG_ENDIAN)
add_definitions(-DWORDS_BIGENDIAN)
endif()
# IEEE floating point
set(HAVE_IEEEFP 1 CACHE STRING "IEEE floating point is available")
+2326
View File
File diff suppressed because it is too large Load Diff
+8 -4
View File
@@ -24,6 +24,10 @@
#ifndef _LIBPORT_
#define _LIBPORT_
#if defined(HAVE_CONFIG_H)
# include <tif_config.h>
#endif
int getopt(int argc, char * const argv[], const char *optstring);
extern char *optarg;
extern int opterr;
@@ -36,16 +40,16 @@ int strcasecmp(const char *s1, const char *s2);
# define HAVE_GETOPT 1
#endif
#if HAVE_STRTOL
#if !defined(HAVE_STRTOL)
long strtol(const char *nptr, char **endptr, int base);
#endif
#if HAVE_STRTOLL
#if !defined(HAVE_STRTOLL)
long long strtoll(const char *nptr, char **endptr, int base);
#endif
#if HAVE_STRTOUL
#if !defined(HAVE_STRTOUL)
unsigned long strtoul(const char *nptr, char **endptr, int base);
#endif
#if HAVE_STRTOULL
#if !defined(HAVE_STRTOULL)
unsigned long long strtoull(const char *nptr, char **endptr, int base);
#endif
+62 -27
View File
@@ -35,27 +35,61 @@
uint32
_TIFFMultiply32(TIFF* tif, uint32 first, uint32 second, const char* where)
{
uint32 bytes = first * second;
if (second && bytes / second != first) {
if (second && first > TIFF_UINT32_MAX / second) {
TIFFErrorExt(tif->tif_clientdata, where, "Integer overflow in %s", where);
bytes = 0;
return 0;
}
return bytes;
return first * second;
}
uint64
_TIFFMultiply64(TIFF* tif, uint64 first, uint64 second, const char* where)
{
uint64 bytes = first * second;
if (second && bytes / second != first) {
if (second && first > TIFF_UINT64_MAX / second) {
TIFFErrorExt(tif->tif_clientdata, where, "Integer overflow in %s", where);
bytes = 0;
return 0;
}
return bytes;
return first * second;
}
tmsize_t
_TIFFMultiplySSize(TIFF* tif, tmsize_t first, tmsize_t second, const char* where)
{
if( first <= 0 || second <= 0 )
{
if( tif != NULL && where != NULL )
{
TIFFErrorExt(tif->tif_clientdata, where,
"Invalid argument to _TIFFMultiplySSize() in %s", where);
}
return 0;
}
if( first > TIFF_TMSIZE_T_MAX / second )
{
if( tif != NULL && where != NULL )
{
TIFFErrorExt(tif->tif_clientdata, where,
"Integer overflow in %s", where);
}
return 0;
}
return first * second;
}
tmsize_t _TIFFCastUInt64ToSSize(TIFF* tif, uint64 val, const char* module)
{
if( val > (uint64)TIFF_TMSIZE_T_MAX )
{
if( tif != NULL && module != NULL )
{
TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
}
return 0;
}
return (tmsize_t)val;
}
void*
@@ -63,13 +97,14 @@ _TIFFCheckRealloc(TIFF* tif, void* buffer,
tmsize_t nmemb, tmsize_t elem_size, const char* what)
{
void* cp = NULL;
tmsize_t bytes = nmemb * elem_size;
tmsize_t count = _TIFFMultiplySSize(tif, nmemb, elem_size, NULL);
/*
* XXX: Check for integer overflow.
* Check for integer overflow.
*/
if (nmemb && elem_size && bytes / elem_size == nmemb)
cp = _TIFFrealloc(buffer, bytes);
if (count != 0)
{
cp = _TIFFrealloc(buffer, count);
}
if (cp == NULL) {
TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
@@ -235,7 +270,7 @@ TIFFVGetFieldDefaulted(TIFF* tif, uint32 tag, va_list ap)
return (1);
case TIFFTAG_EXTRASAMPLES:
*va_arg(ap, uint16 *) = td->td_extrasamples;
*va_arg(ap, uint16 **) = td->td_sampleinfo;
*va_arg(ap, const uint16 **) = td->td_sampleinfo;
return (1);
case TIFFTAG_MATTEING:
*va_arg(ap, uint16 *) =
@@ -257,8 +292,8 @@ TIFFVGetFieldDefaulted(TIFF* tif, uint32 tag, va_list ap)
case TIFFTAG_YCBCRCOEFFICIENTS:
{
/* defaults are from CCIR Recommendation 601-1 */
static float ycbcrcoeffs[] = { 0.299f, 0.587f, 0.114f };
*va_arg(ap, float **) = ycbcrcoeffs;
static const float ycbcrcoeffs[] = { 0.299f, 0.587f, 0.114f };
*va_arg(ap, const float **) = ycbcrcoeffs;
return 1;
}
case TIFFTAG_YCBCRSUBSAMPLING:
@@ -270,14 +305,14 @@ TIFFVGetFieldDefaulted(TIFF* tif, uint32 tag, va_list ap)
return (1);
case TIFFTAG_WHITEPOINT:
{
static float whitepoint[2];
/* TIFF 6.0 specification tells that it is no default
value for the WhitePoint, but AdobePhotoshop TIFF
Technical Note tells that it should be CIE D50. */
whitepoint[0] = D50_X0 / (D50_X0 + D50_Y0 + D50_Z0);
whitepoint[1] = D50_Y0 / (D50_X0 + D50_Y0 + D50_Z0);
*va_arg(ap, float **) = whitepoint;
static const float whitepoint[] = {
D50_X0 / (D50_X0 + D50_Y0 + D50_Z0),
D50_Y0 / (D50_X0 + D50_Y0 + D50_Z0)
};
*va_arg(ap, const float **) = whitepoint;
return 1;
}
case TIFFTAG_TRANSFERFUNCTION:
@@ -286,16 +321,16 @@ TIFFVGetFieldDefaulted(TIFF* tif, uint32 tag, va_list ap)
TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "No space for \"TransferFunction\" tag");
return (0);
}
*va_arg(ap, uint16 **) = td->td_transferfunction[0];
*va_arg(ap, const uint16 **) = td->td_transferfunction[0];
if (td->td_samplesperpixel - td->td_extrasamples > 1) {
*va_arg(ap, uint16 **) = td->td_transferfunction[1];
*va_arg(ap, uint16 **) = td->td_transferfunction[2];
*va_arg(ap, const uint16 **) = td->td_transferfunction[1];
*va_arg(ap, const uint16 **) = td->td_transferfunction[2];
}
return (1);
case TIFFTAG_REFERENCEBLACKWHITE:
if (!td->td_refblackwhite && !TIFFDefaultRefBlackWhite(td))
return (0);
*va_arg(ap, float **) = td->td_refblackwhite;
*va_arg(ap, const float **) = td->td_refblackwhite;
return (1);
}
return 0;
+1 -1
View File
@@ -264,7 +264,7 @@ TIFFGetConfiguredCODECs()
return NULL;
}
codecs = new_codecs;
_TIFFmemcpy(codecs + i - 1, cd, sizeof(TIFFCodec));
_TIFFmemcpy(codecs + i - 1, cd->info, sizeof(TIFFCodec));
i++;
}
for (c = _TIFFBuiltinCODECS; c->name; c++) {
+79 -28
View File
@@ -29,6 +29,7 @@
* (and also some miscellaneous stuff)
*/
#include "tiffiop.h"
#include <float.h> /*--: for Rational2Double */
/*
* These are used in the backwards compatibility code...
@@ -46,8 +47,8 @@ setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size)
*vpp = 0;
}
if (vp) {
tmsize_t bytes = (tmsize_t)(nmemb * elem_size);
if (elem_size && bytes / elem_size == nmemb)
tmsize_t bytes = _TIFFMultiplySSize(NULL, nmemb, elem_size, NULL);
if (bytes)
*vpp = (void*) _TIFFmalloc(bytes);
if (*vpp)
_TIFFmemcpy(*vpp, vp, bytes);
@@ -123,7 +124,7 @@ setExtraSamples(TIFF* tif, va_list ap, uint32* v)
{
TIFFWarningExt(tif->tif_clientdata,module,
"ExtraSamples tag value is changing, "
"but TransferFunction was read with a different value. Cancelling it");
"but TransferFunction was read with a different value. Canceling it");
TIFFClrFieldBit(tif,FIELD_TRANSFERFUNCTION);
_TIFFfree(td->td_transferfunction[0]);
td->td_transferfunction[0] = NULL;
@@ -205,7 +206,7 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
/*
* If the data require post-decoding processing to byte-swap
* samples, set it up here. Note that since tags are required
* to be ordered, compression code can override this behaviour
* to be ordered, compression code can override this behavior
* in the setup method if it wants to roll the post decoding
* work in with its normal work.
*/
@@ -275,7 +276,7 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
{
TIFFWarningExt(tif->tif_clientdata,module,
"SamplesPerPixel tag value is changing, "
"but SMinSampleValue tag was read with a different value. Cancelling it");
"but SMinSampleValue tag was read with a different value. Canceling it");
TIFFClrFieldBit(tif,FIELD_SMINSAMPLEVALUE);
_TIFFfree(td->td_sminsamplevalue);
td->td_sminsamplevalue = NULL;
@@ -284,7 +285,7 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
{
TIFFWarningExt(tif->tif_clientdata,module,
"SamplesPerPixel tag value is changing, "
"but SMaxSampleValue tag was read with a different value. Cancelling it");
"but SMaxSampleValue tag was read with a different value. Canceling it");
TIFFClrFieldBit(tif,FIELD_SMAXSAMPLEVALUE);
_TIFFfree(td->td_smaxsamplevalue);
td->td_smaxsamplevalue = NULL;
@@ -296,7 +297,7 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
{
TIFFWarningExt(tif->tif_clientdata,module,
"SamplesPerPixel tag value is changing, "
"but TransferFunction was read with a different value. Cancelling it");
"but TransferFunction was read with a different value. Canceling it");
TIFFClrFieldBit(tif,FIELD_TRANSFERFUNCTION);
_TIFFfree(td->td_transferfunction[0]);
td->td_transferfunction[0] = NULL;
@@ -393,7 +394,7 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
if (tif->tif_mode != O_RDONLY)
goto badvalue32;
TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
"Nonstandard tile width %d, convert file", v32);
"Nonstandard tile width %u, convert file", v32);
}
td->td_tilewidth = v32;
tif->tif_flags |= TIFF_ISTILED;
@@ -404,7 +405,7 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
if (tif->tif_mode != O_RDONLY)
goto badvalue32;
TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
"Nonstandard tile length %d, convert file", v32);
"Nonstandard tile length %u, convert file", v32);
}
td->td_tilelength = v32;
tif->tif_flags |= TIFF_ISTILED;
@@ -559,6 +560,10 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
* Set custom value ... save a copy of the custom tag value.
*/
tv_size = _TIFFDataSize(fip->field_type);
/*--: Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size. */
if (fip->field_type == TIFF_RATIONAL || fip->field_type == TIFF_SRATIONAL) {
tv_size = _TIFFSetGetFieldSize(fip->set_field_type);
}
if (tv_size == 0) {
status = 0;
TIFFErrorExt(tif->tif_clientdata, module,
@@ -638,6 +643,7 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
|| fip->field_writecount == TIFF_VARIABLE2
|| fip->field_writecount == TIFF_SPP
|| tv->count > 1) {
/*--: Rational2Double: For Rationals tv_size is set above to 4 or 8 according to fip->set_field_type! */
_TIFFmemcpy(tv->value, va_arg(ap, void *),
tv->count * tv_size);
} else {
@@ -698,6 +704,22 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
break;
case TIFF_RATIONAL:
case TIFF_SRATIONAL:
/*-- Rational2Double: For Rationals tv_size is set above to 4 or 8 according to fip->set_field_type! */
{
if (tv_size == 8) {
double v2 = va_arg(ap, double);
_TIFFmemcpy(val, &v2, tv_size);
} else {
/*-- default should be tv_size == 4 */
float v3 = (float)va_arg(ap, double);
_TIFFmemcpy(val, &v3, tv_size);
/*-- ToDo: After Testing, this should be removed and tv_size==4 should be set as default. */
if (tv_size != 4) {
TIFFErrorExt(0,"TIFFLib: _TIFFVSetField()", "Rational2Double: .set_field_type in not 4 but %d", tv_size);
}
}
}
break;
case TIFF_FLOAT:
{
float v2 = _TIFFClampDoubleToFloat(va_arg(ap, double));
@@ -1011,19 +1033,19 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
*va_arg(ap, uint16*) = td->td_halftonehints[1];
break;
case TIFFTAG_COLORMAP:
*va_arg(ap, uint16**) = td->td_colormap[0];
*va_arg(ap, uint16**) = td->td_colormap[1];
*va_arg(ap, uint16**) = td->td_colormap[2];
*va_arg(ap, const uint16**) = td->td_colormap[0];
*va_arg(ap, const uint16**) = td->td_colormap[1];
*va_arg(ap, const uint16**) = td->td_colormap[2];
break;
case TIFFTAG_STRIPOFFSETS:
case TIFFTAG_TILEOFFSETS:
_TIFFFillStriles( tif );
*va_arg(ap, uint64**) = td->td_stripoffset;
*va_arg(ap, const uint64**) = td->td_stripoffset_p;
break;
case TIFFTAG_STRIPBYTECOUNTS:
case TIFFTAG_TILEBYTECOUNTS:
_TIFFFillStriles( tif );
*va_arg(ap, uint64**) = td->td_stripbytecount;
*va_arg(ap, const uint64**) = td->td_stripbytecount_p;
break;
case TIFFTAG_MATTEING:
*va_arg(ap, uint16*) =
@@ -1032,7 +1054,7 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
break;
case TIFFTAG_EXTRASAMPLES:
*va_arg(ap, uint16*) = td->td_extrasamples;
*va_arg(ap, uint16**) = td->td_sampleinfo;
*va_arg(ap, const uint16**) = td->td_sampleinfo;
break;
case TIFFTAG_TILEWIDTH:
*va_arg(ap, uint32*) = td->td_tilewidth;
@@ -1067,7 +1089,7 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
break;
case TIFFTAG_SUBIFD:
*va_arg(ap, uint16*) = td->td_nsubifd;
*va_arg(ap, uint64**) = td->td_subifd;
*va_arg(ap, const uint64**) = td->td_subifd;
break;
case TIFFTAG_YCBCRPOSITIONING:
*va_arg(ap, uint16*) = td->td_ycbcrpositioning;
@@ -1077,20 +1099,20 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
*va_arg(ap, uint16*) = td->td_ycbcrsubsampling[1];
break;
case TIFFTAG_TRANSFERFUNCTION:
*va_arg(ap, uint16**) = td->td_transferfunction[0];
*va_arg(ap, const uint16**) = td->td_transferfunction[0];
if (td->td_samplesperpixel - td->td_extrasamples > 1) {
*va_arg(ap, uint16**) = td->td_transferfunction[1];
*va_arg(ap, uint16**) = td->td_transferfunction[2];
*va_arg(ap, const uint16**) = td->td_transferfunction[1];
*va_arg(ap, const uint16**) = td->td_transferfunction[2];
} else {
*va_arg(ap, uint16**) = NULL;
*va_arg(ap, uint16**) = NULL;
*va_arg(ap, const uint16**) = NULL;
*va_arg(ap, const uint16**) = NULL;
}
break;
case TIFFTAG_REFERENCEBLACKWHITE:
*va_arg(ap, float**) = td->td_refblackwhite;
*va_arg(ap, const float**) = td->td_refblackwhite;
break;
case TIFFTAG_INKNAMES:
*va_arg(ap, char**) = td->td_inknames;
*va_arg(ap, const char**) = td->td_inknames;
break;
default:
{
@@ -1132,7 +1154,7 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
*va_arg(ap, uint32*) = (uint32)tv->count;
else /* Assume TIFF_VARIABLE */
*va_arg(ap, uint16*) = (uint16)tv->count;
*va_arg(ap, void **) = tv->value;
*va_arg(ap, const void **) = tv->value;
ret_val = 1;
} else if (fip->field_tag == TIFFTAG_DOTRANGE
&& strcmp(fip->field_name,"DotRange") == 0) {
@@ -1200,6 +1222,23 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
break;
case TIFF_RATIONAL:
case TIFF_SRATIONAL:
{
/*-- Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size and return value size. */
int tv_size = _TIFFSetGetFieldSize(fip->set_field_type);
if (tv_size == 8) {
*va_arg(ap, double*) = *(double *)val;
ret_val = 1;
} else {
/*-- default should be tv_size == 4 */
*va_arg(ap, float*) = *(float *)val;
ret_val = 1;
/*-- ToDo: After Testing, this should be removed and tv_size==4 should be set as default. */
if (tv_size != 4) {
TIFFErrorExt(0,"TIFFLib: _TIFFVGetField()", "Rational2Double: .set_field_type in not 4 but %d", tv_size);
}
}
}
break;
case TIFF_FLOAT:
*va_arg(ap, float*) =
*(float *)val;
@@ -1282,8 +1321,9 @@ TIFFFreeDirectory(TIFF* tif)
CleanupField(td_transferfunction[0]);
CleanupField(td_transferfunction[1]);
CleanupField(td_transferfunction[2]);
CleanupField(td_stripoffset);
CleanupField(td_stripbytecount);
CleanupField(td_stripoffset_p);
CleanupField(td_stripbytecount_p);
td->td_stripoffsetbyteallocsize = 0;
TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING);
TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING);
@@ -1296,10 +1336,8 @@ TIFFFreeDirectory(TIFF* tif)
td->td_customValueCount = 0;
CleanupField(td_customValues);
#if defined(DEFER_STRILE_LOAD)
_TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
_TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
#endif
}
#undef CleanupField
@@ -1365,6 +1403,17 @@ TIFFCreateEXIFDirectory(TIFF* tif)
return TIFFCreateCustomDirectory(tif, exifFieldArray);
}
/*
* Creates the EXIF GPS custom directory
*/
int
TIFFCreateGPSDirectory(TIFF* tif)
{
const TIFFFieldArray* gpsFieldArray;
gpsFieldArray = _TIFFGetGpsFields();
return TIFFCreateCustomDirectory(tif, gpsFieldArray);
}
/*
* Setup a default directory structure.
*/
@@ -1387,7 +1436,9 @@ TIFFDefaultDirectory(TIFF* tif)
td->td_tilewidth = 0;
td->td_tilelength = 0;
td->td_tiledepth = 1;
#ifdef STRIPBYTECOUNTSORTED_UNUSED
td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */
#endif
td->td_resolutionunit = RESUNIT_INCH;
td->td_sampleformat = SAMPLEFORMAT_UINT;
td->td_imagedepth = 1;
+10 -4
View File
@@ -58,6 +58,7 @@ typedef struct {
uint32 toff_long;
uint64 toff_long8;
} tdir_offset; /* either offset or the data itself if fits */
uint8 tdir_ignore; /* flag status to ignore tag when parsing tags in tif_dirread.c */
} TIFFDirEntry;
/*
@@ -97,13 +98,14 @@ typedef struct {
* number of striles */
uint32 td_stripsperimage;
uint32 td_nstrips; /* size of offset & bytecount arrays */
uint64* td_stripoffset;
uint64* td_stripbytecount;
uint64* td_stripoffset_p; /* should be accessed with TIFFGetStrileOffset */
uint64* td_stripbytecount_p; /* should be accessed with TIFFGetStrileByteCount */
uint32 td_stripoffsetbyteallocsize; /* number of elements currently allocated for td_stripoffset/td_stripbytecount. Only used if TIFF_LAZYSTRILELOAD is set */
#ifdef STRIPBYTECOUNTSORTED_UNUSED
int td_stripbytecountsorted; /* is the bytecount array sorted ascending? */
#if defined(DEFER_STRILE_LOAD)
#endif
TIFFDirEntry td_stripoffset_entry; /* for deferred loading */
TIFFDirEntry td_stripbytecount_entry; /* for deferred loading */
#endif
uint16 td_nsubifd;
uint64* td_subifd;
/* YCbCr parameters */
@@ -118,6 +120,8 @@ typedef struct {
int td_customValueCount;
TIFFTagValue *td_customValues;
unsigned char td_deferstrilearraywriting; /* see TIFFDeferStrileArrayWriting() */
} TIFFDirectory;
/*
@@ -257,6 +261,7 @@ extern "C" {
extern const TIFFFieldArray* _TIFFGetFields(void);
extern const TIFFFieldArray* _TIFFGetExifFields(void);
extern const TIFFFieldArray* _TIFFGetGpsFields(void);
extern void _TIFFSetupFields(TIFF* tif, const TIFFFieldArray* infoarray);
extern void _TIFFPrintFieldInfo(TIFF*, FILE*);
@@ -265,6 +270,7 @@ extern int _TIFFFillStriles(TIFF*);
typedef enum {
tfiatImage,
tfiatExif,
tfiatGps, /* EXIF-GPS fields array type */
tfiatOther
} TIFFFieldArrayType;
+207 -37
View File
@@ -47,9 +47,19 @@
#endif
static const TIFFFieldArray tiffFieldArray;
static const TIFFFieldArray exifFieldArray;
static const TIFFFieldArray gpsFieldArray;
#ifdef _MSC_VER
#pragma warning( pop )
#endif
/*--: Rational2Double: --
* The Rational2Double upgraded libtiff functionality allows the definition and achievement of true double-precision accuracy
* for TIFF tags of RATIONAL type and field_bit=FIELD_CUSTOM using the set_field_type = TIFF_SETGET_DOUBLE.
* Unfortunately, that changes the old implemented interface for TIFFGetField().
* In order to keep the old TIFFGetField() interface behavior those tags have to be redefined with set_field_type = TIFF_SETGET_FLOAT!
*
* Rational custom arrays are already defined as _Cxx_FLOAT, thus can stay.
*
*/
static const TIFFField
tiffFields[] = {
@@ -75,12 +85,12 @@ tiffFields[] = {
{ TIFFTAG_STRIPBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPBYTECOUNTS, 0, 0, "StripByteCounts", NULL },
{ TIFFTAG_MINSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_MINSAMPLEVALUE, 1, 0, "MinSampleValue", NULL },
{ TIFFTAG_MAXSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_MAXSAMPLEVALUE, 1, 0, "MaxSampleValue", NULL },
{ TIFFTAG_XRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "XResolution", NULL },
{ TIFFTAG_YRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "YResolution", NULL },
{ TIFFTAG_XRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "XResolution", NULL },
{ TIFFTAG_YRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "YResolution", NULL },
{ TIFFTAG_PLANARCONFIG, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_PLANARCONFIG, 0, 0, "PlanarConfiguration", NULL },
{ TIFFTAG_PAGENAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PageName", NULL },
{ TIFFTAG_XPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "XPosition", NULL },
{ TIFFTAG_YPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "YPosition", NULL },
{ TIFFTAG_XPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "XPosition", NULL },
{ TIFFTAG_YPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "YPosition", NULL },
{ TIFFTAG_FREEOFFSETS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeOffsets", NULL },
{ TIFFTAG_FREEBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeByteCounts", NULL },
{ TIFFTAG_GRAYRESPONSEUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "GrayResponseUnit", NULL },
@@ -135,14 +145,18 @@ tiffFields[] = {
{ TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToScreen", NULL },
{ TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToCamera", NULL },
{ TIFFTAG_CFAREPEATPATTERNDIM, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CFARepeatPatternDim", NULL },
{ TIFFTAG_CFAPATTERN, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CFAPattern" , NULL},
{ TIFFTAG_CFAPATTERN, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CFAPattern" , NULL},
{ TIFFTAG_COPYRIGHT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Copyright", NULL },
/* end Pixar tags */
{ TIFFTAG_RICHTIFFIPTC, -3, -3, TIFF_LONG, 0, TIFF_SETGET_C32_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "RichTIFFIPTC", NULL },
{ TIFFTAG_RICHTIFFIPTC, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "RichTIFFIPTC", NULL },
{ TIFFTAG_PHOTOSHOP, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "Photoshop", NULL },
{ TIFFTAG_EXIFIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "EXIFIFDOffset", (TIFFFieldArray*) &exifFieldArray },
/*--: EXIFIFD and GPSIFD specified as TIFF_LONG by Aware-Systems and not TIFF_IFD8 as in original LibTiff.
* However, for IFD-like tags, libtiff uses the data type TIFF_IFD8 in tiffFields[]-tag definition combined with
* a special handling procedure in order to write either a 32-bit value and the TIFF_IFD type-id into ClassicTIFF files
* or a 64-bit value and the TIFF_IFD8 type-id into BigTIFF files. */
{ TIFFTAG_EXIFIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EXIFIFDOffset", (TIFFFieldArray*) &exifFieldArray },
{ TIFFTAG_ICCPROFILE, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ICC Profile", NULL },
{ TIFFTAG_GPSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "GPSIFDOffset", NULL },
{ TIFFTAG_GPSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "GPSIFDOffset", (TIFFFieldArray*) &gpsFieldArray },
{ TIFFTAG_FAXRECVPARAMS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvParams", NULL },
{ TIFFTAG_FAXSUBADDRESS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxSubAddress", NULL },
{ TIFFTAG_FAXRECVTIME, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvTime", NULL },
@@ -163,7 +177,7 @@ tiffFields[] = {
{ TIFFTAG_BLACKLEVELDELTAV, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "BlackLevelDeltaV", NULL },
{ TIFFTAG_WHITELEVEL, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "WhiteLevel", NULL },
{ TIFFTAG_DEFAULTSCALE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultScale", NULL },
{ TIFFTAG_BESTQUALITYSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BestQualityScale", NULL },
{ TIFFTAG_BESTQUALITYSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BestQualityScale", NULL },
{ TIFFTAG_DEFAULTCROPORIGIN, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultCropOrigin", NULL },
{ TIFFTAG_DEFAULTCROPSIZE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultCropSize", NULL },
{ TIFFTAG_COLORMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ColorMatrix1", NULL },
@@ -175,16 +189,16 @@ tiffFields[] = {
{ TIFFTAG_ANALOGBALANCE, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AnalogBalance", NULL },
{ TIFFTAG_ASSHOTNEUTRAL, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AsShotNeutral", NULL },
{ TIFFTAG_ASSHOTWHITEXY, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "AsShotWhiteXY", NULL },
{ TIFFTAG_BASELINEEXPOSURE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineExposure", NULL },
{ TIFFTAG_BASELINENOISE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineNoise", NULL },
{ TIFFTAG_BASELINESHARPNESS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineSharpness", NULL },
{ TIFFTAG_BASELINEEXPOSURE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineExposure", NULL },
{ TIFFTAG_BASELINENOISE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineNoise", NULL },
{ TIFFTAG_BASELINESHARPNESS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineSharpness", NULL },
{ TIFFTAG_BAYERGREENSPLIT, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BayerGreenSplit", NULL },
{ TIFFTAG_LINEARRESPONSELIMIT, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "LinearResponseLimit", NULL },
{ TIFFTAG_LINEARRESPONSELIMIT, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "LinearResponseLimit", NULL },
{ TIFFTAG_CAMERASERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraSerialNumber", NULL },
{ TIFFTAG_LENSINFO, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "LensInfo", NULL },
{ TIFFTAG_CHROMABLURRADIUS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ChromaBlurRadius", NULL },
{ TIFFTAG_ANTIALIASSTRENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "AntiAliasStrength", NULL },
{ TIFFTAG_SHADOWSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ShadowScale", NULL },
{ TIFFTAG_CHROMABLURRADIUS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ChromaBlurRadius", NULL },
{ TIFFTAG_ANTIALIASSTRENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "AntiAliasStrength", NULL },
{ TIFFTAG_SHADOWSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ShadowScale", NULL },
{ TIFFTAG_DNGPRIVATEDATA, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "DNGPrivateData", NULL },
{ TIFFTAG_MAKERNOTESAFETY, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "MakerNoteSafety", NULL },
{ TIFFTAG_CALIBRATIONILLUMINANT1, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CalibrationIlluminant1", NULL },
@@ -217,47 +231,68 @@ tiffFields[] = {
/* begin pseudo tags */
};
/*
* EXIF tags (Version 2.31, July 2016 plus version 2.32 May 2019)
*/
static const TIFFField
exifFields[] = {
{ EXIFTAG_EXPOSURETIME, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureTime", NULL },
{ EXIFTAG_FNUMBER, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FNumber", NULL },
{ EXIFTAG_EXPOSURETIME, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureTime", NULL },
{ EXIFTAG_FNUMBER, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FNumber", NULL },
{ EXIFTAG_EXPOSUREPROGRAM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureProgram", NULL },
{ EXIFTAG_SPECTRALSENSITIVITY, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SpectralSensitivity", NULL },
{ EXIFTAG_ISOSPEEDRATINGS, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ISOSpeedRatings", NULL },
{ EXIFTAG_OECF, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OptoelectricConversionFactor", NULL },
{ EXIFTAG_SENSITIVITYTYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SensitivityType", NULL },
{ EXIFTAG_STANDARDOUTPUTSENSITIVITY, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "StandardOutputSensitivity", NULL },
{ EXIFTAG_RECOMMENDEDEXPOSUREINDEX, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RecommendedExposureIndex", NULL },
{ EXIFTAG_ISOSPEED, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ISOSpeed", NULL },
{ EXIFTAG_ISOSPEEDLATITUDEYYY, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ISOSpeedLatitudeyyy", NULL },
{ EXIFTAG_ISOSPEEDLATITUDEZZZ, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ISOSpeedLatitudezzz", NULL },
{ EXIFTAG_EXIFVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExifVersion", NULL },
{ EXIFTAG_DATETIMEORIGINAL, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTimeOriginal", NULL },
{ EXIFTAG_DATETIMEDIGITIZED, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTimeDigitized", NULL },
{ EXIFTAG_OFFSETTIME, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OffsetTime", NULL },
{ EXIFTAG_OFFSETTIMEORIGINAL, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OffsetTimeOriginal", NULL },
{ EXIFTAG_OFFSETTIMEDIGITIZED, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OffsetTimeDigitized", NULL },
{ EXIFTAG_COMPONENTSCONFIGURATION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ComponentsConfiguration", NULL },
{ EXIFTAG_COMPRESSEDBITSPERPIXEL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CompressedBitsPerPixel", NULL },
{ EXIFTAG_SHUTTERSPEEDVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ShutterSpeedValue", NULL },
{ EXIFTAG_APERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ApertureValue", NULL },
{ EXIFTAG_BRIGHTNESSVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BrightnessValue", NULL },
{ EXIFTAG_EXPOSUREBIASVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureBiasValue", NULL },
{ EXIFTAG_MAXAPERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MaxApertureValue", NULL },
{ EXIFTAG_SUBJECTDISTANCE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistance", NULL },
{ EXIFTAG_COMPRESSEDBITSPERPIXEL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CompressedBitsPerPixel", NULL },
{ EXIFTAG_SHUTTERSPEEDVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ShutterSpeedValue", NULL },
{ EXIFTAG_APERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ApertureValue", NULL },
{ EXIFTAG_BRIGHTNESSVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BrightnessValue", NULL },
{ EXIFTAG_EXPOSUREBIASVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureBiasValue", NULL },
{ EXIFTAG_MAXAPERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MaxApertureValue", NULL },
/*--: EXIFTAG_SUBJECTDISTANCE: LibTiff returns value of "-1" if numerator equals 4294967295 (0xFFFFFFFF) to indicate infinite distance!
* However, there are two other EXIF tags where numerator indicates a special value and six other cases where the denominator indicates special values,
* which are not treated within LibTiff!! */
{ EXIFTAG_SUBJECTDISTANCE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistance", NULL },
{ EXIFTAG_METERINGMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MeteringMode", NULL },
{ EXIFTAG_LIGHTSOURCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LightSource", NULL },
{ EXIFTAG_FLASH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Flash", NULL },
{ EXIFTAG_FOCALLENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLength", NULL },
{ EXIFTAG_FOCALLENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLength", NULL },
{ EXIFTAG_SUBJECTAREA, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SubjectArea", NULL },
{ EXIFTAG_MAKERNOTE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "MakerNote", NULL },
{ EXIFTAG_USERCOMMENT, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "UserComment", NULL },
{ EXIFTAG_SUBSECTIME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTime", NULL },
{ EXIFTAG_SUBSECTIMEORIGINAL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTimeOriginal", NULL },
{ EXIFTAG_SUBSECTIMEDIGITIZED, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTimeDigitized", NULL },
{ EXIFTAG_TEMPERATURE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Temperature", NULL },
{ EXIFTAG_HUMIDITY, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Humidity", NULL },
{ EXIFTAG_PRESSURE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Pressure", NULL },
{ EXIFTAG_WATERDEPTH, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WaterDepth", NULL },
{ EXIFTAG_ACCELERATION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Acceleration", NULL },
{ EXIFTAG_CAMERAELEVATIONANGLE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraElevationAngle", NULL },
{ EXIFTAG_FLASHPIXVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashpixVersion", NULL },
{ EXIFTAG_COLORSPACE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ColorSpace", NULL },
{ EXIFTAG_PIXELXDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PixelXDimension", NULL },
{ EXIFTAG_PIXELYDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PixelYDimension", NULL },
{ EXIFTAG_RELATEDSOUNDFILE, 13, 13, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RelatedSoundFile", NULL },
{ EXIFTAG_FLASHENERGY, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashEnergy", NULL },
{ EXIFTAG_FLASHENERGY, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashEnergy", NULL },
{ EXIFTAG_SPATIALFREQUENCYRESPONSE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SpatialFrequencyResponse", NULL },
{ EXIFTAG_FOCALPLANEXRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneXResolution", NULL },
{ EXIFTAG_FOCALPLANEYRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneYResolution", NULL },
{ EXIFTAG_FOCALPLANEXRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneXResolution", NULL },
{ EXIFTAG_FOCALPLANEYRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneYResolution", NULL },
{ EXIFTAG_FOCALPLANERESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneResolutionUnit", NULL },
{ EXIFTAG_SUBJECTLOCATION, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectLocation", NULL },
{ EXIFTAG_EXPOSUREINDEX, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureIndex", NULL },
{ EXIFTAG_EXPOSUREINDEX, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureIndex", NULL },
{ EXIFTAG_SENSINGMETHOD, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SensingMethod", NULL },
{ EXIFTAG_FILESOURCE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FileSource", NULL },
{ EXIFTAG_SCENETYPE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SceneType", NULL },
@@ -265,22 +300,79 @@ exifFields[] = {
{ EXIFTAG_CUSTOMRENDERED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CustomRendered", NULL },
{ EXIFTAG_EXPOSUREMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureMode", NULL },
{ EXIFTAG_WHITEBALANCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WhiteBalance", NULL },
{ EXIFTAG_DIGITALZOOMRATIO, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DigitalZoomRatio", NULL },
{ EXIFTAG_DIGITALZOOMRATIO, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DigitalZoomRatio", NULL },
{ EXIFTAG_FOCALLENGTHIN35MMFILM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLengthIn35mmFilm", NULL },
{ EXIFTAG_SCENECAPTURETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SceneCaptureType", NULL },
{ EXIFTAG_GAINCONTROL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "GainControl", NULL },
{ EXIFTAG_GAINCONTROL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "GainControl", NULL },
{ EXIFTAG_CONTRAST, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Contrast", NULL },
{ EXIFTAG_SATURATION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Saturation", NULL },
{ EXIFTAG_SHARPNESS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Sharpness", NULL },
{ EXIFTAG_DEVICESETTINGDESCRIPTION, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "DeviceSettingDescription", NULL },
{ EXIFTAG_SUBJECTDISTANCERANGE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistanceRange", NULL },
{ EXIFTAG_IMAGEUNIQUEID, 33, 33, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageUniqueID", NULL }
{ EXIFTAG_IMAGEUNIQUEID, 33, 33, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageUniqueID", NULL },
{ EXIFTAG_CAMERAOWNERNAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraOwnerName", NULL },
{ EXIFTAG_BODYSERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BodySerialNumber", NULL },
{ EXIFTAG_LENSSPECIFICATION, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensSpecification", NULL },
{ EXIFTAG_LENSMAKE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensMake", NULL },
{ EXIFTAG_LENSMODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensModel", NULL },
{ EXIFTAG_LENSSERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensSerialNumber", NULL },
{ EXIFTAG_GAMMA, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Gamma", NULL },
{ EXIFTAG_COMPOSITEIMAGE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CompositeImage", NULL },
{ EXIFTAG_SOURCEIMAGENUMBEROFCOMPOSITEIMAGE, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SourceImageNumberOfCompositeImage", NULL },
{ EXIFTAG_SOURCEEXPOSURETIMESOFCOMPOSITEIMAGE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SourceExposureTimesOfCompositeImage", NULL }
};
/*
* EXIF-GPS tags (Version 2.31, July 2016; nothing changed for version 2.32 May 2019)
*/
static TIFFField
gpsFields[] = {
/* For the GPS tag definitions in gpsFields[] the standard definition for Rationals is TIFF_SETGET_DOUBLE and TIFF_SETGET_C0_FLOAT.
*-- ATTENTION: After the upgrade with Rational2Double, the GPSTAG values can now be written and also read in double precision!
* In order to achieve double precision for GPS tags:
* Standard definitions for GPSTAG is kept to TIFF_SETGET_DOUBLE
* and TIFF_SETGET_C0_FLOAT is changed to TIFF_SETGET_C0_DOUBLE.
*/
{ GPSTAG_VERSIONID , 4, 4, TIFF_BYTE , 0, TIFF_SETGET_C0_UINT8 , TIFF_SETGET_UINT8 , FIELD_CUSTOM , 1, 0, "VersionID", NULL },
{ GPSTAG_LATITUDEREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "LatitudeRef", NULL },
{ GPSTAG_LATITUDE , 3, 3, TIFF_RATIONAL , 0, TIFF_SETGET_C0_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Latitude", NULL },
{ GPSTAG_LONGITUDEREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "LongitudeRef", NULL },
{ GPSTAG_LONGITUDE , 3, 3, TIFF_RATIONAL , 0, TIFF_SETGET_C0_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Longitude", NULL },
{ GPSTAG_ALTITUDEREF , 1, 1, TIFF_BYTE , 0, TIFF_SETGET_UINT8 , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "AltitudeRef", NULL },
{ GPSTAG_ALTITUDE , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Altitude", NULL },
{ GPSTAG_TIMESTAMP , 3, 3, TIFF_RATIONAL , 0, TIFF_SETGET_C0_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "TimeStamp", NULL },
{ GPSTAG_SATELLITES , -1, -1, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Satellites", NULL },
{ GPSTAG_STATUS , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Status", NULL },
{ GPSTAG_MEASUREMODE , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "MeasureMode", NULL },
{ GPSTAG_DOP , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DOP", NULL },
{ GPSTAG_SPEEDREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "SpeedRef", NULL },
{ GPSTAG_SPEED , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Speed", NULL },
{ GPSTAG_TRACKREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "TrackRef", NULL },
{ GPSTAG_TRACK , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Track", NULL },
{ GPSTAG_IMGDIRECTIONREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "ImgDirectionRef", NULL },
{ GPSTAG_IMGDIRECTION , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "ImgDirection", NULL },
{ GPSTAG_MAPDATUM , -1, -1, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "MapDatum", NULL },
{ GPSTAG_DESTLATITUDEREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestLatitudeRef", NULL },
{ GPSTAG_DESTLATITUDE , 3, 3, TIFF_RATIONAL , 0, TIFF_SETGET_C0_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestLatitude", NULL },
{ GPSTAG_DESTLONGITUDEREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestLongitudeRef", NULL },
{ GPSTAG_DESTLONGITUDE , 3, 3, TIFF_RATIONAL , 0, TIFF_SETGET_C0_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestLongitude", NULL },
{ GPSTAG_DESTBEARINGREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestBearingRef", NULL },
{ GPSTAG_DESTBEARING , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestBearing", NULL },
{ GPSTAG_DESTDISTANCEREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestDistanceRef", NULL },
{ GPSTAG_DESTDISTANCE , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestDistance", NULL },
{ GPSTAG_PROCESSINGMETHOD , -1, -1, TIFF_UNDEFINED , 0, TIFF_SETGET_C16_UINT8 , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 1, "ProcessingMethod", NULL },
{ GPSTAG_AREAINFORMATION , -1, -1, TIFF_UNDEFINED , 0, TIFF_SETGET_C16_UINT8 , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 1, "AreaInformation", NULL },
{ GPSTAG_DATESTAMP , 11, 11, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DateStamp", NULL },
{ GPSTAG_DIFFERENTIAL , 1, 1, TIFF_SHORT , 0, TIFF_SETGET_UINT16 , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Differential", NULL },
{ GPSTAG_GPSHPOSITIONINGERROR , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "HorizontalPositioningError", NULL }
};
static const TIFFFieldArray
tiffFieldArray = { tfiatImage, 0, TIFFArrayCount(tiffFields), (TIFFField*) tiffFields };
static const TIFFFieldArray
exifFieldArray = { tfiatExif, 0, TIFFArrayCount(exifFields), (TIFFField*) exifFields };
static const TIFFFieldArray
gpsFieldArray = { tfiatGps, 0, TIFFArrayCount(gpsFields), (TIFFField*) gpsFields };
/*
* We have our own local lfind() equivalent to avoid subtle differences
@@ -313,6 +405,12 @@ _TIFFGetExifFields(void)
return(&exifFieldArray);
}
const TIFFFieldArray*
_TIFFGetGpsFields(void)
{
return(&gpsFieldArray);
}
void
_TIFFSetupFields(TIFF* tif, const TIFFFieldArray* fieldarray)
{
@@ -502,6 +600,82 @@ _TIFFDataSize(TIFFDataType type)
}
}
/*
* Rational2Double:
* Return size of TIFFSetGetFieldType in bytes.
*
* XXX: TIFF_RATIONAL values for FIELD_CUSTOM are stored internally as 4-byte float.
* However, some of them should be stored internally as 8-byte double.
* This is now managed by the SetGetField of the tag-definition!
*/
int
_TIFFSetGetFieldSize(TIFFSetGetFieldType setgettype)
{
switch (setgettype)
{
case TIFF_SETGET_UNDEFINED:
case TIFF_SETGET_ASCII:
case TIFF_SETGET_C0_ASCII:
case TIFF_SETGET_C16_ASCII:
case TIFF_SETGET_C32_ASCII:
case TIFF_SETGET_OTHER:
return 0;
case TIFF_SETGET_UINT8:
case TIFF_SETGET_SINT8:
case TIFF_SETGET_C0_UINT8:
case TIFF_SETGET_C0_SINT8:
case TIFF_SETGET_C16_UINT8:
case TIFF_SETGET_C16_SINT8:
case TIFF_SETGET_C32_UINT8:
case TIFF_SETGET_C32_SINT8:
return 1;
case TIFF_SETGET_UINT16:
case TIFF_SETGET_SINT16:
case TIFF_SETGET_C0_UINT16:
case TIFF_SETGET_C0_SINT16:
case TIFF_SETGET_C16_UINT16:
case TIFF_SETGET_C16_SINT16:
case TIFF_SETGET_C32_UINT16:
case TIFF_SETGET_C32_SINT16:
return 2;
case TIFF_SETGET_INT:
case TIFF_SETGET_UINT32:
case TIFF_SETGET_SINT32:
case TIFF_SETGET_FLOAT:
case TIFF_SETGET_UINT16_PAIR:
case TIFF_SETGET_C0_UINT32:
case TIFF_SETGET_C0_SINT32:
case TIFF_SETGET_C0_FLOAT:
case TIFF_SETGET_C16_UINT32:
case TIFF_SETGET_C16_SINT32:
case TIFF_SETGET_C16_FLOAT:
case TIFF_SETGET_C32_UINT32:
case TIFF_SETGET_C32_SINT32:
case TIFF_SETGET_C32_FLOAT:
return 4;
case TIFF_SETGET_UINT64:
case TIFF_SETGET_SINT64:
case TIFF_SETGET_DOUBLE:
case TIFF_SETGET_IFD8:
case TIFF_SETGET_C0_UINT64:
case TIFF_SETGET_C0_SINT64:
case TIFF_SETGET_C0_DOUBLE:
case TIFF_SETGET_C0_IFD8:
case TIFF_SETGET_C16_UINT64:
case TIFF_SETGET_C16_SINT64:
case TIFF_SETGET_C16_DOUBLE:
case TIFF_SETGET_C16_IFD8:
case TIFF_SETGET_C32_UINT64:
case TIFF_SETGET_C32_SINT64:
case TIFF_SETGET_C32_DOUBLE:
case TIFF_SETGET_C32_IFD8:
return 8;
default:
return 0;
}
} /*-- _TIFFSetGetFieldSize --- */
const TIFFField*
TIFFFindField(TIFF* tif, uint32 tag, TIFFDataType dt)
{
@@ -1062,10 +1236,6 @@ _TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag)
if (tag == TIFFTAG_LERC_PARAMETERS)
return 1;
break;
case COMPRESSION_WEBP:
if (tag == TIFFTAG_PREDICTOR)
return 1;
break;
}
return 0;
}
+852 -359
View File
File diff suppressed because it is too large Load Diff
+786 -55
View File
File diff suppressed because it is too large Load Diff
+86 -28
View File
@@ -73,6 +73,7 @@ typedef struct {
int EOLcnt; /* count of EOL codes recognized */
TIFFFaxFillFunc fill; /* fill routine */
uint32* runs; /* b&w runs for current/previous row */
uint32 nruns; /* size of the refruns / curruns arrays */
uint32* refruns; /* runs for reference line */
uint32* curruns; /* runs for current line */
@@ -160,7 +161,9 @@ Fax3PreDecode(TIFF* tif, uint16 s)
*/
sp->bitmap =
TIFFGetBitRevTable(tif->tif_dir.td_fillorder != FILLORDER_LSB2MSB);
sp->curruns = sp->runs;
if (sp->refruns) { /* init reference line to white */
sp->refruns = sp->runs + sp->nruns;
sp->refruns[0] = (uint32) sp->b.rowpixels;
sp->refruns[1] = 0;
}
@@ -218,8 +221,12 @@ Fax3PrematureEOF(const char* module, TIFF* tif, uint32 line, uint32 a0)
#define Nop
/*
/**
* Decode the requested amount of G3 1D-encoded data.
* @param buf destination buffer
* @param occ available bytes in destination buffer
* @param s number of planes (ignored)
* @returns 1 for success, -1 in case of error
*/
static int
Fax3Decode1D(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
@@ -300,7 +307,9 @@ Fax3Decode2D(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
else
EXPAND2D(EOF2Da);
(*sp->fill)(buf, thisrun, pa, lastx);
SETVALUE(0); /* imaginary change for reference */
if (pa < thisrun + sp->nruns) {
SETVALUE(0); /* imaginary change for reference */
}
SWAP(uint32*, sp->curruns, sp->refruns);
buf += sp->b.rowbytes;
occ -= sp->b.rowbytes;
@@ -506,7 +515,7 @@ Fax3SetupState(TIFF* tif)
int needsRefLine;
Fax3CodecState* dsp = (Fax3CodecState*) Fax3State(tif);
tmsize_t rowbytes;
uint32 rowpixels, nruns;
uint32 rowpixels;
if (td->td_bitspersample != 1) {
TIFFErrorExt(tif->tif_clientdata, module,
@@ -523,6 +532,13 @@ Fax3SetupState(TIFF* tif)
rowbytes = TIFFScanlineSize(tif);
rowpixels = td->td_imagewidth;
}
if ((uint64)rowbytes < ((uint64)rowpixels + 7) / 8)
{
TIFFErrorExt(tif->tif_clientdata, module,
"Inconsistent number of bytes per row : rowbytes=%lu rowpixels=%lu",
(unsigned long)(rowbytes), (unsigned long)(rowpixels));
return (0);
}
sp->rowbytes = rowbytes;
sp->rowpixels = rowpixels;
/*
@@ -539,26 +555,26 @@ Fax3SetupState(TIFF* tif)
TIFFroundup and TIFFSafeMultiply return zero on integer overflow
*/
dsp->runs=(uint32*) NULL;
nruns = TIFFroundup_32(rowpixels,32);
dsp->nruns = TIFFroundup_32(rowpixels,32);
if (needsRefLine) {
nruns = TIFFSafeMultiply(uint32,nruns,2);
dsp->nruns = TIFFSafeMultiply(uint32,dsp->nruns,2);
}
if ((nruns == 0) || (TIFFSafeMultiply(uint32,nruns,2) == 0)) {
if ((dsp->nruns == 0) || (TIFFSafeMultiply(uint32,dsp->nruns,2) == 0)) {
TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
"Row pixels integer overflow (rowpixels %u)",
rowpixels);
return (0);
}
dsp->runs = (uint32*) _TIFFCheckMalloc(tif,
TIFFSafeMultiply(uint32,nruns,2),
TIFFSafeMultiply(uint32,dsp->nruns,2),
sizeof (uint32),
"for Group 3/4 run arrays");
if (dsp->runs == NULL)
return (0);
memset( dsp->runs, 0, TIFFSafeMultiply(uint32,nruns,2)*sizeof(uint32));
memset( dsp->runs, 0, TIFFSafeMultiply(uint32,dsp->nruns,2)*sizeof(uint32));
dsp->curruns = dsp->runs;
if (needsRefLine)
dsp->refruns = dsp->runs + nruns;
dsp->refruns = dsp->runs + dsp->nruns;
else
dsp->refruns = NULL;
if (td->td_compression == COMPRESSION_CCITTFAX3
@@ -594,15 +610,19 @@ Fax3SetupState(TIFF* tif)
*/
#define Fax3FlushBits(tif, sp) { \
if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) \
(void) TIFFFlushData1(tif); \
if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) { \
if( !TIFFFlushData1(tif) ) \
return 0; \
} \
*(tif)->tif_rawcp++ = (uint8) (sp)->data; \
(tif)->tif_rawcc++; \
(sp)->data = 0, (sp)->bit = 8; \
}
#define _FlushBits(tif) { \
if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) \
(void) TIFFFlushData1(tif); \
if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) { \
if( !TIFFFlushData1(tif) ) \
return 0; \
} \
*(tif)->tif_rawcp++ = (uint8) data; \
(tif)->tif_rawcc++; \
data = 0, bit = 8; \
@@ -627,7 +647,7 @@ static const int _msbmask[9] =
* the output stream. Values are
* assumed to be at most 16 bits.
*/
static void
static int
Fax3PutBits(TIFF* tif, unsigned int bits, unsigned int length)
{
Fax3CodecState* sp = EncoderState(tif);
@@ -638,6 +658,7 @@ Fax3PutBits(TIFF* tif, unsigned int bits, unsigned int length)
sp->data = data;
sp->bit = bit;
return 1;
}
/*
@@ -662,7 +683,7 @@ Fax3PutBits(TIFF* tif, unsigned int bits, unsigned int length)
* appropriate table that holds the make-up and
* terminating codes is supplied.
*/
static void
static int
putspan(TIFF* tif, int32 span, const tableentry* tab)
{
Fax3CodecState* sp = EncoderState(tif);
@@ -700,6 +721,8 @@ putspan(TIFF* tif, int32 span, const tableentry* tab)
sp->data = data;
sp->bit = bit;
return 1;
}
/*
@@ -708,7 +731,7 @@ putspan(TIFF* tif, int32 span, const tableentry* tab)
* here. We also handle writing the tag bit for the next
* scanline when doing 2d encoding.
*/
static void
static int
Fax3PutEOL(TIFF* tif)
{
Fax3CodecState* sp = EncoderState(tif);
@@ -742,6 +765,8 @@ Fax3PutEOL(TIFF* tif)
sp->data = data;
sp->bit = bit;
return 1;
}
/*
@@ -991,12 +1016,14 @@ Fax3Encode1DRow(TIFF* tif, unsigned char* bp, uint32 bits)
for (;;) {
span = find0span(bp, bs, bits); /* white span */
putspan(tif, span, TIFFFaxWhiteCodes);
if( !putspan(tif, span, TIFFFaxWhiteCodes) )
return 0;
bs += span;
if (bs >= bits)
break;
span = find1span(bp, bs, bits); /* black span */
putspan(tif, span, TIFFFaxBlackCodes);
if( !putspan(tif, span, TIFFFaxBlackCodes) )
return 0;
bs += span;
if (bs >= bits)
break;
@@ -1048,21 +1075,28 @@ Fax3Encode2DRow(TIFF* tif, unsigned char* bp, unsigned char* rp, uint32 bits)
(b1 < a1 && a1 - b1 <= 3U) ? -(int32)(a1 - b1) : 0x7FFFFFFF;
if (!(-3 <= d && d <= 3)) { /* horizontal mode */
a2 = finddiff2(bp, a1, bits, PIXEL(bp,a1));
putcode(tif, &horizcode);
if( !putcode(tif, &horizcode) )
return 0;
if (a0+a1 == 0 || PIXEL(bp, a0) == 0) {
putspan(tif, a1-a0, TIFFFaxWhiteCodes);
putspan(tif, a2-a1, TIFFFaxBlackCodes);
if( !putspan(tif, a1-a0, TIFFFaxWhiteCodes) )
return 0;
if( !putspan(tif, a2-a1, TIFFFaxBlackCodes) )
return 0;
} else {
putspan(tif, a1-a0, TIFFFaxBlackCodes);
putspan(tif, a2-a1, TIFFFaxWhiteCodes);
if( !putspan(tif, a1-a0, TIFFFaxBlackCodes) )
return 0;
if( !putspan(tif, a2-a1, TIFFFaxWhiteCodes) )
return 0;
}
a0 = a2;
} else { /* vertical mode */
putcode(tif, &vcodes[d+3]);
if( !putcode(tif, &vcodes[d+3]) )
return 0;
a0 = a1;
}
} else { /* pass mode */
putcode(tif, &passcode);
if( !putcode(tif, &passcode) )
return 0;
a0 = b2;
}
if (a0 >= bits)
@@ -1091,7 +1125,10 @@ Fax3Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
}
while (cc > 0) {
if ((sp->b.mode & FAXMODE_NOEOL) == 0)
Fax3PutEOL(tif);
{
if( !Fax3PutEOL(tif) )
return 0;
}
if (is2DEncoding(sp)) {
if (sp->tag == G3_1D) {
if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels))
@@ -1128,8 +1165,8 @@ Fax3PostEncode(TIFF* tif)
return (1);
}
static void
Fax3Close(TIFF* tif)
static int
_Fax3Close(TIFF* tif)
{
if ((Fax3State(tif)->mode & FAXMODE_NORTC) == 0 && tif->tif_rawcp) {
Fax3CodecState* sp = EncoderState(tif);
@@ -1145,6 +1182,13 @@ Fax3Close(TIFF* tif)
Fax3PutBits(tif, code, length);
Fax3FlushBits(tif, sp);
}
return 1;
}
static void
Fax3Close(TIFF* tif)
{
_Fax3Close(tif);
}
static void
@@ -1453,6 +1497,13 @@ Fax4Decode(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
EXPAND2D(EOFG4);
if (EOLcnt)
goto EOFG4;
if (((lastx + 7) >> 3) > (int)occ) /* check for buffer overrun */
{
TIFFErrorExt(tif->tif_clientdata, module,
"Buffer overrun detected : %d bytes available, %d bits needed",
(int)occ, lastx);
return -1;
}
(*sp->fill)(buf, thisrun, pa, lastx);
SETVALUE(0); /* imaginary change for reference */
SWAP(uint32*, sp->curruns, sp->refruns);
@@ -1468,6 +1519,13 @@ Fax4Decode(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
fputs( "Bad EOFB\n", stderr );
#endif
ClrBits( 13 );
if (((lastx + 7) >> 3) > (int)occ) /* check for buffer overrun */
{
TIFFErrorExt(tif->tif_clientdata, module,
"Buffer overrun detected : %d bytes available, %d bits needed",
(int)occ, lastx);
return -1;
}
(*sp->fill)(buf, thisrun, pa, lastx);
UNCACHE_STATE(tif, sp);
return ( sp->line ? 1 : -1); /* don't error on badly-terminated strips */
+34 -5
View File
@@ -240,6 +240,11 @@ static const char* StateNames[] = {
* current row and reset decoding state.
*/
#define SETVALUE(x) do { \
if (pa >= thisrun + sp->nruns) { \
TIFFErrorExt(tif->tif_clientdata, module, "Buffer overflow at line %u of %s %u", \
sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \
return (-1); \
} \
*pa++ = RunLength + (x); \
a0 += (x); \
RunLength = 0; \
@@ -377,6 +382,11 @@ done1d: \
*/
#define CHECK_b1 do { \
if (pa != thisrun) while (b1 <= a0 && b1 < lastx) { \
if( pb + 1 >= sp->refruns + sp->nruns) { \
TIFFErrorExt(tif->tif_clientdata, module, "Buffer overflow at line %u of %s %u", \
sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \
return (-1); \
} \
b1 += pb[0] + pb[1]; \
pb += 2; \
} \
@@ -387,10 +397,20 @@ done1d: \
*/
#define EXPAND2D(eoflab) do { \
while (a0 < lastx) { \
if (pa >= thisrun + sp->nruns) { \
TIFFErrorExt(tif->tif_clientdata, module, "Buffer overflow at line %u of %s %u", \
sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \
return (-1); \
} \
LOOKUP8(7, TIFFFaxMainTable, eof2d); \
switch (TabEnt->State) { \
case S_Pass: \
CHECK_b1; \
if( pb + 1 >= sp->refruns + sp->nruns) { \
TIFFErrorExt(tif->tif_clientdata, module, "Buffer overflow at line %u of %s %u", \
sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \
return (-1); \
} \
b1 += *pb++; \
RunLength += b1 - a0; \
a0 = b1; \
@@ -469,20 +489,28 @@ done1d: \
case S_V0: \
CHECK_b1; \
SETVALUE(b1 - a0); \
if( pb >= sp->refruns + sp->nruns) { \
TIFFErrorExt(tif->tif_clientdata, module, "Buffer overflow at line %u of %s %u", \
sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \
return (-1); \
} \
b1 += *pb++; \
break; \
case S_VR: \
CHECK_b1; \
SETVALUE(b1 - a0 + TabEnt->Param); \
if( pb >= sp->refruns + sp->nruns) { \
TIFFErrorExt(tif->tif_clientdata, module, "Buffer overflow at line %u of %s %u", \
sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \
return (-1); \
} \
b1 += *pb++; \
break; \
case S_VL: \
CHECK_b1; \
if (b1 <= (int) (a0 + TabEnt->Param)) { \
if (b1 < (int) (a0 + TabEnt->Param) || pa != thisrun) { \
unexpected("VL", a0); \
goto eol2d; \
} \
if (b1 < (int) (a0 + TabEnt->Param)) { \
unexpected("VL", a0); \
goto eol2d; \
} \
SETVALUE(b1 - a0 - TabEnt->Param); \
b1 -= *--pb; \
@@ -529,6 +557,7 @@ eol2d: \
CLEANUP_RUNS(); \
} while (0)
#endif /* _FAX3_ */
/* vim: set ts=8 sts=4 sw=4 noet: */
/*
* Local Variables:
* mode: c
+1
View File
@@ -1,5 +1,6 @@
/* WARNING, this file was automatically generated by the
mkg3states program */
#include <stdint.h>
#include "tiff.h"
#include "tif_fax3.h"
const TIFFFaxTabEnt TIFFFaxMainTable[128] = {
+88 -30
View File
@@ -45,36 +45,8 @@ TIFFFlush(TIFF* tif)
&& !(tif->tif_flags & TIFF_DIRTYDIRECT)
&& tif->tif_mode == O_RDWR )
{
uint64 *offsets=NULL, *sizes=NULL;
if( TIFFIsTiled(tif) )
{
if( TIFFGetField( tif, TIFFTAG_TILEOFFSETS, &offsets )
&& TIFFGetField( tif, TIFFTAG_TILEBYTECOUNTS, &sizes )
&& _TIFFRewriteField( tif, TIFFTAG_TILEOFFSETS, TIFF_LONG8,
tif->tif_dir.td_nstrips, offsets )
&& _TIFFRewriteField( tif, TIFFTAG_TILEBYTECOUNTS, TIFF_LONG8,
tif->tif_dir.td_nstrips, sizes ) )
{
tif->tif_flags &= ~TIFF_DIRTYSTRIP;
tif->tif_flags &= ~TIFF_BEENWRITING;
return 1;
}
}
else
{
if( TIFFGetField( tif, TIFFTAG_STRIPOFFSETS, &offsets )
&& TIFFGetField( tif, TIFFTAG_STRIPBYTECOUNTS, &sizes )
&& _TIFFRewriteField( tif, TIFFTAG_STRIPOFFSETS, TIFF_LONG8,
tif->tif_dir.td_nstrips, offsets )
&& _TIFFRewriteField( tif, TIFFTAG_STRIPBYTECOUNTS, TIFF_LONG8,
tif->tif_dir.td_nstrips, sizes ) )
{
tif->tif_flags &= ~TIFF_DIRTYSTRIP;
tif->tif_flags &= ~TIFF_BEENWRITING;
return 1;
}
}
if( TIFFForceStrileArrayWriting(tif) )
return 1;
}
if ((tif->tif_flags & (TIFF_DIRTYDIRECT|TIFF_DIRTYSTRIP))
@@ -84,6 +56,92 @@ TIFFFlush(TIFF* tif)
return (1);
}
/*
* This is an advanced writing function that must be used in a particular
* sequence, and together with TIFFDeferStrileArrayWriting(),
* to make its intended effect. Its aim is to force the writing of
* the [Strip/Tile][Offsets/ByteCounts] arrays at the end of the file, when
* they have not yet been rewritten.
*
* The typical sequence of calls is:
* TIFFOpen()
* [ TIFFCreateDirectory(tif) ]
* Set fields with calls to TIFFSetField(tif, ...)
* TIFFDeferStrileArrayWriting(tif)
* TIFFWriteCheck(tif, ...)
* TIFFWriteDirectory(tif)
* ... potentially create other directories and come back to the above directory
* TIFFForceStrileArrayWriting(tif)
*
* Returns 1 in case of success, 0 otherwise.
*/
int TIFFForceStrileArrayWriting(TIFF* tif)
{
static const char module[] = "TIFFForceStrileArrayWriting";
const int isTiled = TIFFIsTiled(tif);
if (tif->tif_mode == O_RDONLY)
{
TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
"File opened in read-only mode");
return 0;
}
if( tif->tif_diroff == 0 )
{
TIFFErrorExt(tif->tif_clientdata, module,
"Directory has not yet been written");
return 0;
}
if( (tif->tif_flags & TIFF_DIRTYDIRECT) != 0 )
{
TIFFErrorExt(tif->tif_clientdata, module,
"Directory has changes other than the strile arrays. "
"TIFFRewriteDirectory() should be called instead");
return 0;
}
if( !(tif->tif_flags & TIFF_DIRTYSTRIP) )
{
if( !(tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 &&
tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 &&
tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0) )
{
TIFFErrorExt(tif->tif_clientdata, module,
"Function not called together with "
"TIFFDeferStrileArrayWriting()");
return 0;
}
if (tif->tif_dir.td_stripoffset_p == NULL && !TIFFSetupStrips(tif))
return 0;
}
if( _TIFFRewriteField( tif,
isTiled ? TIFFTAG_TILEOFFSETS :
TIFFTAG_STRIPOFFSETS,
TIFF_LONG8,
tif->tif_dir.td_nstrips,
tif->tif_dir.td_stripoffset_p )
&& _TIFFRewriteField( tif,
isTiled ? TIFFTAG_TILEBYTECOUNTS :
TIFFTAG_STRIPBYTECOUNTS,
TIFF_LONG8,
tif->tif_dir.td_nstrips,
tif->tif_dir.td_stripbytecount_p ) )
{
tif->tif_flags &= ~TIFF_DIRTYSTRIP;
tif->tif_flags &= ~TIFF_BEENWRITING;
return 1;
}
return 0;
}
/*
* Flush buffered data to the file.
*
+52 -15
View File
@@ -29,6 +29,7 @@
*/
#include "tiffiop.h"
#include <stdio.h>
#include <limits.h>
static int gtTileContig(TIFFRGBAImage*, uint32*, uint32, uint32);
static int gtTileSeparate(TIFFRGBAImage*, uint32*, uint32, uint32);
@@ -645,12 +646,20 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
flip = setorientation(img);
if (flip & FLIP_VERTICALLY) {
y = h - 1;
toskew = -(int32)(tw + w);
if ((tw + w) > INT_MAX) {
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "unsupported tile size (too wide)");
return (0);
}
y = h - 1;
toskew = -(int32)(tw + w);
}
else {
y = 0;
toskew = -(int32)(tw - w);
if (tw > (INT_MAX + w)) {
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "unsupported tile size (too wide)");
return (0);
}
y = 0;
toskew = -(int32)(tw - w);
}
/*
@@ -755,9 +764,8 @@ gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
uint32 leftmost_tw;
tilesize = TIFFTileSize(tif);
bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,tilesize);
bufsize = _TIFFMultiplySSize(tif, alpha?4:3,tilesize, "gtTileSeparate");
if (bufsize == 0) {
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtTileSeparate");
return (0);
}
@@ -766,10 +774,18 @@ gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
flip = setorientation(img);
if (flip & FLIP_VERTICALLY) {
if ((tw + w) > INT_MAX) {
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "unsupported tile size (too wide)");
return (0);
}
y = h - 1;
toskew = -(int32)(tw + w);
}
else {
if (tw > (INT_MAX + w)) {
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "unsupported tile size (too wide)");
return (0);
}
y = 0;
toskew = -(int32)(tw - w);
}
@@ -937,6 +953,10 @@ gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
flip = setorientation(img);
if (flip & FLIP_VERTICALLY) {
if ( w > INT_MAX ) {
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Width overflow");
return (0);
}
y = h - 1;
toskew = -(int32)(w + w);
} else {
@@ -950,16 +970,23 @@ gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
fromskew = (w < imagewidth ? imagewidth - w : 0);
for (row = 0; row < h; row += nrow)
{
uint32 temp;
rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
nrow = (row + rowstoread > h ? h - row : rowstoread);
nrowsub = nrow;
if ((nrowsub%subsamplingver)!=0)
nrowsub+=subsamplingver-nrowsub%subsamplingver;
temp = (row + img->row_offset)%rowsperstrip + nrowsub;
if( scanline > 0 && temp > (size_t)(TIFF_TMSIZE_T_MAX / scanline) )
{
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in gtStripContig");
return 0;
}
if (_TIFFReadEncodedStripAndAllocBuffer(tif,
TIFFComputeStrip(tif,row+img->row_offset, 0),
(void**)(&buf),
maxstripsize,
((row + img->row_offset)%rowsperstrip + nrowsub) * scanline)==(tmsize_t)(-1)
temp * scanline)==(tmsize_t)(-1)
&& (buf == NULL || img->stoponerr))
{
ret = 0;
@@ -1019,14 +1046,17 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
uint16 colorchannels;
stripsize = TIFFStripSize(tif);
bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,stripsize);
bufsize = _TIFFMultiplySSize(tif,alpha?4:3,stripsize, "gtStripSeparate");
if (bufsize == 0) {
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtStripSeparate");
return (0);
}
flip = setorientation(img);
if (flip & FLIP_VERTICALLY) {
if ( w > INT_MAX ) {
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Width overflow");
return (0);
}
y = h - 1;
toskew = -(int32)(w + w);
}
@@ -1053,15 +1083,22 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
fromskew = (w < imagewidth ? imagewidth - w : 0);
for (row = 0; row < h; row += nrow)
{
uint32 temp;
rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
nrow = (row + rowstoread > h ? h - row : rowstoread);
offset_row = row + img->row_offset;
temp = (row + img->row_offset)%rowsperstrip + nrow;
if( scanline > 0 && temp > (size_t)(TIFF_TMSIZE_T_MAX / scanline) )
{
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in gtStripSeparate");
return 0;
}
if( buf == NULL )
{
if (_TIFFReadEncodedStripAndAllocBuffer(
tif, TIFFComputeStrip(tif, offset_row, 0),
(void**) &buf, bufsize,
((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1)
temp * scanline)==(tmsize_t)(-1)
&& (buf == NULL || img->stoponerr))
{
ret = 0;
@@ -1081,7 +1118,7 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
}
}
else if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0),
p0, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1)
p0, temp * scanline)==(tmsize_t)(-1)
&& img->stoponerr)
{
ret = 0;
@@ -1089,7 +1126,7 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
}
if (colorchannels > 1
&& TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 1),
p1, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) == (tmsize_t)(-1)
p1, temp * scanline) == (tmsize_t)(-1)
&& img->stoponerr)
{
ret = 0;
@@ -1097,7 +1134,7 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
}
if (colorchannels > 1
&& TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 2),
p2, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) == (tmsize_t)(-1)
p2, temp * scanline) == (tmsize_t)(-1)
&& img->stoponerr)
{
ret = 0;
@@ -1106,7 +1143,7 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
if (alpha)
{
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, colorchannels),
pa, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1)
pa, temp * scanline)==(tmsize_t)(-1)
&& img->stoponerr)
{
ret = 0;
@@ -2957,7 +2994,7 @@ TIFFReadRGBATileExt(TIFF* tif, uint32 col, uint32 row, uint32 * raster, int stop
if( !TIFFIsTiled( tif ) )
{
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
"Can't use TIFFReadRGBATile() with stripped file.");
"Can't use TIFFReadRGBATile() with striped file.");
return (0);
}
+1
View File
@@ -199,6 +199,7 @@ static int JBIGEncode(TIFF* tif, uint8* buffer, tmsize_t size, uint16 s)
int TIFFInitJBIG(TIFF* tif, int scheme)
{
(void)scheme;
assert(scheme == COMPRESSION_JBIG);
/*
+42 -38
View File
@@ -466,7 +466,8 @@ std_empty_output_buffer(j_compress_ptr cinfo)
}
#endif
TIFFFlushData1(tif);
if( !TIFFFlushData1(tif) )
return FALSE;
sp->dest.next_output_byte = (JOCTET*) tif->tif_rawdata;
sp->dest.free_in_buffer = (size_t) tif->tif_rawdatasize;
@@ -780,12 +781,9 @@ JPEGFixupTagsSubsampling(TIFF* tif)
*/
static const char module[] = "JPEGFixupTagsSubsampling";
struct JPEGFixupTagsSubsamplingData m;
uint64 fileoffset = TIFFGetStrileOffset(tif, 0);
_TIFFFillStriles( tif );
if( tif->tif_dir.td_stripbytecount == NULL
|| tif->tif_dir.td_stripoffset == NULL
|| tif->tif_dir.td_stripbytecount[0] == 0 )
if( fileoffset == 0 )
{
/* Do not even try to check if the first strip/tile does not
yet exist, as occurs when GDAL has created a new NULL file
@@ -804,9 +802,9 @@ JPEGFixupTagsSubsampling(TIFF* tif)
}
m.buffercurrentbyte=NULL;
m.bufferbytesleft=0;
m.fileoffset=tif->tif_dir.td_stripoffset[0];
m.fileoffset=fileoffset;
m.filepositioned=0;
m.filebytesleft=tif->tif_dir.td_stripbytecount[0];
m.filebytesleft=TIFFGetStrileByteCount(tif, 0);
if (!JPEGFixupTagsSubsamplingSec(&m))
TIFFWarningExt(tif->tif_clientdata,module,
"Unable to auto-correct subsampling values, likely corrupt JPEG compressed data in first strip/tile; auto-correcting skipped");
@@ -940,7 +938,10 @@ JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData* data, uint
return(0);
if (!data->filepositioned)
{
TIFFSeekFile(data->tif,data->fileoffset,SEEK_SET);
if (TIFFSeekFile(data->tif,data->fileoffset,SEEK_SET) == (toff_t)-1)
{
return 0;
}
data->filepositioned=1;
}
m=data->buffersize;
@@ -1209,35 +1210,37 @@ JPEGPreDecode(TIFF* tif, uint16 s)
/* store for all coefficients */
/* See call to jinit_d_coef_controller() from master_selection() */
/* in libjpeg */
toff_t nRequiredMemory = (toff_t)sp->cinfo.d.image_width *
sp->cinfo.d.image_height *
sp->cinfo.d.num_components *
((td->td_bitspersample+7)/8);
/* BLOCK_SMOOTHING_SUPPORTED is generally defined, so we need */
/* to replicate the logic of jinit_d_coef_controller() */
if( sp->cinfo.d.progressive_mode )
nRequiredMemory *= 3;
#ifndef TIFF_LIBJPEG_LARGEST_MEM_ALLOC
#define TIFF_LIBJPEG_LARGEST_MEM_ALLOC (100 * 1024 * 1024)
#endif
/* 1 MB for regular libjpeg usage */
toff_t nRequiredMemory = 1024 * 1024;
if( nRequiredMemory > TIFF_LIBJPEG_LARGEST_MEM_ALLOC &&
for (ci = 0; ci < sp->cinfo.d.num_components; ci++) {
const jpeg_component_info *compptr = &(sp->cinfo.d.comp_info[ci]);
if( compptr->h_samp_factor > 0 && compptr->v_samp_factor > 0 )
{
nRequiredMemory += (toff_t)(
((compptr->width_in_blocks + compptr->h_samp_factor - 1) / compptr->h_samp_factor)) *
((compptr->height_in_blocks + compptr->v_samp_factor - 1) / compptr->v_samp_factor) *
sizeof(JBLOCK);
}
}
if( sp->cinfo.d.mem->max_memory_to_use > 0 &&
nRequiredMemory > (toff_t)(sp->cinfo.d.mem->max_memory_to_use) &&
getenv("LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC") == NULL )
{
TIFFErrorExt(tif->tif_clientdata, module,
"Reading this strip would require libjpeg to allocate "
"at least %u bytes. "
"This is disabled since above the %u threshold. "
"You may override this restriction by defining the "
"LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC environment variable, "
"or recompile libtiff by defining the "
"TIFF_LIBJPEG_LARGEST_MEM_ALLOC macro to a value greater "
"than %u",
(unsigned)nRequiredMemory,
(unsigned)TIFF_LIBJPEG_LARGEST_MEM_ALLOC,
(unsigned)TIFF_LIBJPEG_LARGEST_MEM_ALLOC);
return (0);
TIFFErrorExt(tif->tif_clientdata, module,
"Reading this image would require libjpeg to allocate "
"at least %u bytes. "
"This is disabled since above the %u threshold. "
"You may override this restriction by defining the "
"LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC environment variable, "
"or setting the JPEGMEM environment variable to a value greater "
"or equal to '%uM'",
(unsigned)(nRequiredMemory),
(unsigned)(sp->cinfo.d.mem->max_memory_to_use),
(unsigned)((nRequiredMemory + 1000000 - 1) / 1000000));
return 0;
}
}
@@ -1566,7 +1569,7 @@ JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
JSAMPLE *outptr = (JSAMPLE*)tmpbuf + clumpoffset;
#else
JSAMPLE *outptr = (JSAMPLE*)buf + clumpoffset;
if (cc < (tmsize_t) (clumpoffset + samples_per_clump*(clumps_per_line-1) + hsamp)) {
if (cc < (tmsize_t)(clumpoffset + (tmsize_t)samples_per_clump*(clumps_per_line-1) + hsamp)) {
TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw",
"application buffer not large enough for all data, possible subsampling issue");
return 0;
@@ -2126,8 +2129,8 @@ JPEGEncodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
/* data is expected to be supplied in multiples of a clumpline */
/* a clumpline is equivalent to v_sampling desubsampled scanlines */
/* TODO: the following calculation of bytesperclumpline, should substitute calculation of sp->bytesperline, except that it is per v_sampling lines */
bytesperclumpline = (((sp->cinfo.c.image_width+sp->h_sampling-1)/sp->h_sampling)
*(sp->h_sampling*sp->v_sampling+2)*sp->cinfo.c.data_precision+7)
bytesperclumpline = ((((tmsize_t)sp->cinfo.c.image_width+sp->h_sampling-1)/sp->h_sampling)
*((tmsize_t)sp->h_sampling*sp->v_sampling+2)*sp->cinfo.c.data_precision+7)
/8;
nrows = ( cc / bytesperclumpline ) * sp->v_sampling;
@@ -2347,7 +2350,7 @@ JPEGVGetField(TIFF* tif, uint32 tag, va_list ap)
switch (tag) {
case TIFFTAG_JPEGTABLES:
*va_arg(ap, uint32*) = sp->jpegtables_length;
*va_arg(ap, void**) = sp->jpegtables;
*va_arg(ap, const void**) = sp->jpegtables;
break;
case TIFFTAG_JPEGQUALITY:
*va_arg(ap, int*) = sp->jpegquality;
@@ -2482,6 +2485,7 @@ TIFFInitJPEG(TIFF* tif, int scheme)
{
JPEGState* sp;
(void)scheme;
assert(scheme == COMPRESSION_JPEG);
/*
+21 -21
View File
@@ -193,6 +193,7 @@ LogL16Decode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
tmsize_t cc;
int rc;
(void)s;
assert(s == 0);
assert(sp != NULL);
@@ -266,6 +267,7 @@ LogLuvDecode24(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
unsigned char* bp;
uint32* tp;
(void)s;
assert(s == 0);
assert(sp != NULL);
@@ -326,6 +328,7 @@ LogLuvDecode32(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
tmsize_t cc;
int rc;
(void)s;
assert(s == 0);
sp = DecoderState(tif);
assert(sp != NULL);
@@ -447,6 +450,7 @@ LogL16Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
int rc=0, mask;
tmsize_t beg;
(void)s;
assert(s == 0);
assert(sp != NULL);
npixels = cc / sp->pixel_size;
@@ -541,6 +545,7 @@ LogLuvEncode24(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
uint8* op;
uint32* tp;
(void)s;
assert(s == 0);
assert(sp != NULL);
npixels = cc / sp->pixel_size;
@@ -598,6 +603,7 @@ LogLuvEncode32(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
int rc=0, mask;
tmsize_t beg;
(void)s;
assert(s == 0);
assert(sp != NULL);
@@ -742,7 +748,7 @@ LogLuvEncodeTile(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
#undef exp2 /* Conflict with C'99 function */
#define exp2(x) exp(M_LN2*(x))
static int itrunc(double x, int m)
static int tiff_itrunc(double x, int m)
{
if( m == SGILOGENCODE_NODITHER )
return (int)x;
@@ -777,9 +783,9 @@ LogL16fromY(double Y, int em) /* get 16-bit LogL from Y */
if (Y <= -1.8371976e19)
return (0xffff);
if (Y > 5.4136769e-20)
return itrunc(256.*(log2(Y) + 64.), em);
return tiff_itrunc(256.*(log2(Y) + 64.), em);
if (Y < -5.4136769e-20)
return (~0x7fff | itrunc(256.*(log2(-Y) + 64.), em));
return (~0x7fff | tiff_itrunc(256.*(log2(-Y) + 64.), em));
return (0);
}
@@ -855,7 +861,7 @@ LogL10fromY(double Y, int em) /* get 10-bit LogL from Y */
else if (Y <= .00024283)
return (0);
else
return itrunc(64.*(log2(Y) + 12.), em);
return tiff_itrunc(64.*(log2(Y) + 12.), em);
}
#define NANGLES 100
@@ -925,12 +931,12 @@ uv_encode(double u, double v, int em) /* encode (u',v') coordinates */
if (v < UV_VSTART)
return oog_encode(u, v);
vi = itrunc((v - UV_VSTART)*(1./UV_SQSIZ), em);
vi = tiff_itrunc((v - UV_VSTART)*(1./UV_SQSIZ), em);
if (vi >= UV_NVS)
return oog_encode(u, v);
if (u < uv_row[vi].ustart)
return oog_encode(u, v);
ui = itrunc((u - uv_row[vi].ustart)*(1./UV_SQSIZ), em);
ui = tiff_itrunc((u - uv_row[vi].ustart)*(1./UV_SQSIZ), em);
if (ui >= uv_row[vi].nus)
return oog_encode(u, v);
@@ -1099,7 +1105,7 @@ Luv24fromLuv48(LogLuvState* sp, uint8* op, tmsize_t n)
else if (sp->encode_meth == SGILOGENCODE_NODITHER)
Le = (luv3[0]-3314) >> 2;
else
Le = itrunc(.25*(luv3[0]-3314.), sp->encode_meth);
Le = tiff_itrunc(.25*(luv3[0]-3314.), sp->encode_meth);
Ce = uv_encode((luv3[1]+.5)/(1<<15), (luv3[2]+.5)/(1<<15),
sp->encode_meth);
@@ -1155,10 +1161,10 @@ LogLuv32fromXYZ(float XYZ[3], int em)
v = 9.*XYZ[1] / s;
}
if (u <= 0.) ue = 0;
else ue = itrunc(UVSCALE*u, em);
else ue = tiff_itrunc(UVSCALE*u, em);
if (ue > 255) ue = 255;
if (v <= 0.) ve = 0;
else ve = itrunc(UVSCALE*v, em);
else ve = tiff_itrunc(UVSCALE*v, em);
if (ve > 255) ve = 255;
/* combine encodings */
return (Le << 16 | ue << 8 | ve);
@@ -1238,8 +1244,8 @@ Luv32fromLuv48(LogLuvState* sp, uint8* op, tmsize_t n)
}
while (n-- > 0) {
*luv++ = (uint32)luv3[0] << 16 |
(itrunc(luv3[1]*(UVSCALE/(1<<15)), sp->encode_meth) << 8 & 0xff00) |
(itrunc(luv3[2]*(UVSCALE/(1<<15)), sp->encode_meth) & 0xff);
(tiff_itrunc(luv3[1]*(UVSCALE/(1<<15)), sp->encode_meth) << 8 & 0xff00) |
(tiff_itrunc(luv3[2]*(UVSCALE/(1<<15)), sp->encode_meth) & 0xff);
luv3 += 3;
}
}
@@ -1269,16 +1275,10 @@ LogL16GuessDataFmt(TIFFDirectory *td)
return (SGILOGDATAFMT_UNKNOWN);
}
#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0))
#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1)
static tmsize_t
multiply_ms(tmsize_t m1, tmsize_t m2)
{
if( m1 == 0 || m2 > TIFF_TMSIZE_T_MAX / m1 )
return 0;
return m1 * m2;
return _TIFFMultiplySSize(NULL, m1, m2, NULL);
}
static int
@@ -1512,7 +1512,7 @@ LogLuvSetupEncode(TIFF* tif)
switch (td->td_photometric) {
case PHOTOMETRIC_LOGLUV:
if (!LogLuvInitState(tif))
break;
return (0);
if (td->td_compression == COMPRESSION_SGILOG24) {
tif->tif_encoderow = LogLuvEncode24;
switch (sp->user_datafmt) {
@@ -1545,7 +1545,7 @@ LogLuvSetupEncode(TIFF* tif)
break;
case PHOTOMETRIC_LOGL:
if (!LogL16InitState(tif))
break;
return (0);
tif->tif_encoderow = LogL16Encode;
switch (sp->user_datafmt) {
case SGILOGDATAFMT_FLOAT:
@@ -1561,7 +1561,7 @@ LogLuvSetupEncode(TIFF* tif)
TIFFErrorExt(tif->tif_clientdata, module,
"Inappropriate photometric interpretation %d for SGILog compression; %s",
td->td_photometric, "must be either LogLUV or LogL");
break;
return (0);
}
sp->encoder_state = 1;
return (1);
+5 -2
View File
@@ -300,7 +300,8 @@ LZMAEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
}
if (sp->stream.avail_out == 0) {
tif->tif_rawcc = tif->tif_rawdatasize;
TIFFFlushData1(tif);
if (!TIFFFlushData1(tif))
return 0;
sp->stream.next_out = tif->tif_rawdata;
sp->stream.avail_out = (size_t)tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in LZMAPreEncode */
}
@@ -328,7 +329,8 @@ LZMAPostEncode(TIFF* tif)
if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) {
tif->tif_rawcc =
tif->tif_rawdatasize - sp->stream.avail_out;
TIFFFlushData1(tif);
if (!TIFFFlushData1(tif))
return 0;
sp->stream.next_out = tif->tif_rawdata;
sp->stream.avail_out = (size_t)tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in ZIPPreEncode */
}
@@ -418,6 +420,7 @@ TIFFInitLZMA(TIFF* tif, int scheme)
LZMAState* sp;
lzma_stream tmp_stream = LZMA_STREAM_INIT;
(void)scheme;
assert( scheme == COMPRESSION_LZMA );
/*
+5 -7
View File
@@ -214,19 +214,16 @@ LZWSetupDecode(TIFF* tif)
return (0);
}
DecoderState(tif)->dec_codetab = NULL;
DecoderState(tif)->dec_decode = NULL;
sp = DecoderState(tif);
sp->dec_codetab = NULL;
sp->dec_decode = NULL;
/*
* Setup predictor setup.
*/
(void) TIFFPredictorInit(tif);
sp = DecoderState(tif);
}
assert(sp != NULL);
if (sp->dec_codetab == NULL) {
sp->dec_codetab = (code_t*)_TIFFmalloc(CSIZE*sizeof (code_t));
if (sp->dec_codetab == NULL) {
@@ -1161,6 +1158,7 @@ int
TIFFInitLZW(TIFF* tif, int scheme)
{
static const char module[] = "TIFFInitLZW";
(void)scheme;
assert(scheme == COMPRESSION_LZW);
/*
* Allocate state block so tag methods have storage to record values.
@@ -1218,7 +1216,7 @@ bad:
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#endif /* LZW_SUPPORT */
+69 -25
View File
@@ -74,7 +74,7 @@
or errors, up to the point where either these values are read, or it's clear they
aren't there. This means that some of the data is read twice, but we feel speed
in correcting these values is important enough to warrant this sacrifice. Although
there is currently no define or other configuration mechanism to disable this behaviour,
there is currently no define or other configuration mechanism to disable this behavior,
the actual header scanning is build to robustly respond with error report if it
should encounter an uncorrected mismatch of subsampling values. See
OJPEGReadHeaderInfoSecStreamSof.
@@ -243,6 +243,7 @@ typedef enum {
typedef struct {
TIFF* tif;
int decoder_ok;
int error_in_raw_data_decoding;
#ifndef LIBJPEG_ENCAP_EXTERNAL
JMP_BUF exit_jmpbuf;
#endif
@@ -420,6 +421,7 @@ TIFFInitOJPEG(TIFF* tif, int scheme)
static const char module[]="TIFFInitOJPEG";
OJPEGState* sp;
(void)scheme;
assert(scheme==COMPRESSION_OJPEG);
/*
@@ -497,15 +499,15 @@ OJPEGVGetField(TIFF* tif, uint32 tag, va_list ap)
break;
case TIFFTAG_JPEGQTABLES:
*va_arg(ap,uint32*)=(uint32)sp->qtable_offset_count;
*va_arg(ap,void**)=(void*)sp->qtable_offset;
*va_arg(ap,const void**)=(const void*)sp->qtable_offset;
break;
case TIFFTAG_JPEGDCTABLES:
*va_arg(ap,uint32*)=(uint32)sp->dctable_offset_count;
*va_arg(ap,void**)=(void*)sp->dctable_offset;
*va_arg(ap,const void**)=(const void*)sp->dctable_offset;
break;
case TIFFTAG_JPEGACTABLES:
*va_arg(ap,uint32*)=(uint32)sp->actable_offset_count;
*va_arg(ap,void**)=(void*)sp->actable_offset;
*va_arg(ap,const void**)=(const void*)sp->actable_offset;
break;
case TIFFTAG_JPEGPROC:
*va_arg(ap,uint16*)=(uint16)sp->jpeg_proc;
@@ -657,7 +659,7 @@ static int
OJPEGSetupDecode(TIFF* tif)
{
static const char module[]="OJPEGSetupDecode";
TIFFWarningExt(tif->tif_clientdata,module,"Depreciated and troublesome old-style JPEG compression mode, please convert to new-style JPEG compression and notify vendor of writing software");
TIFFWarningExt(tif->tif_clientdata,module,"Deprecated and troublesome old-style JPEG compression mode, please convert to new-style JPEG compression and notify vendor of writing software");
return(1);
}
@@ -678,7 +680,7 @@ OJPEGPreDecode(TIFF* tif, uint16 s)
if (OJPEGReadSecondarySos(tif,s)==0)
return(0);
}
if isTiled(tif)
if (isTiled(tif))
m=tif->tif_curtile;
else
m=tif->tif_curstrip;
@@ -742,6 +744,7 @@ OJPEGPreDecodeSkipRaw(TIFF* tif)
}
m-=sp->subsampling_convert_clines-sp->subsampling_convert_state;
sp->subsampling_convert_state=0;
sp->error_in_raw_data_decoding=0;
}
while (m>=sp->subsampling_convert_clines)
{
@@ -792,6 +795,10 @@ OJPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
TIFFErrorExt(tif->tif_clientdata,module,"Cannot decode: decoder not correctly initialized");
return 0;
}
if( sp->error_in_raw_data_decoding )
{
return 0;
}
if (sp->libjpeg_jpeg_query_style==0)
{
if (OJPEGDecodeRaw(tif,buf,cc)==0)
@@ -832,7 +839,10 @@ OJPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc)
if (sp->subsampling_convert_state==0)
{
if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0)
{
sp->error_in_raw_data_decoding = 1;
return(0);
}
}
oy=sp->subsampling_convert_ybuf+sp->subsampling_convert_state*sp->subsampling_ver*sp->subsampling_convert_ylinelen;
ocb=sp->subsampling_convert_cbbuf+sp->subsampling_convert_state*sp->subsampling_convert_clinelen;
@@ -990,7 +1000,6 @@ OJPEGSubsamplingCorrect(TIFF* tif)
OJPEGState* sp=(OJPEGState*)tif->tif_data;
uint8 mh;
uint8 mv;
_TIFFFillStriles( tif );
assert(sp->subsamplingcorrect_done==0);
if ((tif->tif_dir.td_samplesperpixel!=3) || ((tif->tif_dir.td_photometric!=PHOTOMETRIC_YCBCR) &&
@@ -1046,7 +1055,7 @@ OJPEGReadHeaderInfo(TIFF* tif)
assert(sp->readheader_done==0);
sp->image_width=tif->tif_dir.td_imagewidth;
sp->image_length=tif->tif_dir.td_imagelength;
if isTiled(tif)
if (isTiled(tif))
{
sp->strile_width=tif->tif_dir.td_tilewidth;
sp->strile_length=tif->tif_dir.td_tilelength;
@@ -1056,6 +1065,8 @@ OJPEGReadHeaderInfo(TIFF* tif)
{
sp->strile_width=sp->image_width;
sp->strile_length=tif->tif_dir.td_rowsperstrip;
if( sp->strile_length == (uint32)-1 )
sp->strile_length = sp->image_length;
sp->strile_length_total=sp->image_length;
}
if (tif->tif_dir.td_samplesperpixel==1)
@@ -1082,6 +1093,12 @@ OJPEGReadHeaderInfo(TIFF* tif)
}
if (sp->strile_length<sp->image_length)
{
if (((sp->subsampling_hor!=1) && (sp->subsampling_hor!=2) && (sp->subsampling_hor!=4)) ||
((sp->subsampling_ver!=1) && (sp->subsampling_ver!=2) && (sp->subsampling_ver!=4)))
{
TIFFErrorExt(tif->tif_clientdata,module,"Invalid subsampling values");
return(0);
}
if (sp->strile_length%(sp->subsampling_ver*8)!=0)
{
TIFFErrorExt(tif->tif_clientdata,module,"Incompatible vertical subsampling and image strip/tile length");
@@ -1197,7 +1214,13 @@ OJPEGWriteHeaderInfo(TIFF* tif)
sp->subsampling_convert_ybuflen=sp->subsampling_convert_ylinelen*sp->subsampling_convert_ylines;
sp->subsampling_convert_cbuflen=sp->subsampling_convert_clinelen*sp->subsampling_convert_clines;
sp->subsampling_convert_ycbcrbuflen=sp->subsampling_convert_ybuflen+2*sp->subsampling_convert_cbuflen;
sp->subsampling_convert_ycbcrbuf=_TIFFmalloc(sp->subsampling_convert_ycbcrbuflen);
/* The calloc is not normally necessary, except in some edge/broken cases */
/* for example for a tiled image of height 1 with a tile height of 1 and subsampling_hor=subsampling_ver=2 */
/* In that case, libjpeg will only fill the 8 first lines of the 16 lines */
/* See https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16844 */
/* Even if this case is allowed (?), its handling is broken because OJPEGPreDecode() should also likely */
/* reset subsampling_convert_state to 0 when changing tile. */
sp->subsampling_convert_ycbcrbuf=_TIFFcalloc(1, sp->subsampling_convert_ycbcrbuflen);
if (sp->subsampling_convert_ycbcrbuf==0)
{
TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
@@ -1223,10 +1246,11 @@ OJPEGWriteHeaderInfo(TIFF* tif)
*m++=sp->subsampling_convert_cbbuf+n*sp->subsampling_convert_clinelen;
for (n=0; n<sp->subsampling_convert_clines; n++)
*m++=sp->subsampling_convert_crbuf+n*sp->subsampling_convert_clinelen;
sp->subsampling_convert_clinelenout=((sp->strile_width+sp->subsampling_hor-1)/sp->subsampling_hor);
sp->subsampling_convert_clinelenout=sp->strile_width/sp->subsampling_hor + ((sp->strile_width % sp->subsampling_hor) != 0 ? 1 : 0);
sp->subsampling_convert_state=0;
sp->error_in_raw_data_decoding=0;
sp->bytes_per_line=sp->subsampling_convert_clinelenout*(sp->subsampling_ver*sp->subsampling_hor+2);
sp->lines_per_strile=((sp->strile_length+sp->subsampling_ver-1)/sp->subsampling_ver);
sp->lines_per_strile=sp->strile_length/sp->subsampling_ver + ((sp->strile_length % sp->subsampling_ver) != 0 ? 1 : 0);
sp->subsampling_convert_log=1;
}
}
@@ -1240,6 +1264,26 @@ OJPEGWriteHeaderInfo(TIFF* tif)
}
if (jpeg_start_decompress_encap(sp,&(sp->libjpeg_jpeg_decompress_struct))==0)
return(0);
if(sp->libjpeg_jpeg_decompress_struct.image_width != sp->strile_width ) {
TIFFErrorExt(tif->tif_clientdata,module,
"jpeg_start_decompress() returned image_width = %d, "
"expected %d",
sp->libjpeg_jpeg_decompress_struct.image_width,
sp->strile_width);
return 0;
}
if(sp->libjpeg_jpeg_decompress_struct.max_h_samp_factor != sp->subsampling_hor ||
sp->libjpeg_jpeg_decompress_struct.max_v_samp_factor != sp->subsampling_ver) {
TIFFErrorExt(tif->tif_clientdata,module,
"jpeg_start_decompress() returned max_h_samp_factor = %d "
"and max_v_samp_factor = %d, expected %d and %d",
sp->libjpeg_jpeg_decompress_struct.max_h_samp_factor,
sp->libjpeg_jpeg_decompress_struct.max_v_samp_factor,
sp->subsampling_hor,
sp->subsampling_ver);
return 0;
}
sp->writeheader_done=1;
return(1);
}
@@ -1272,7 +1316,9 @@ OJPEGReadHeaderInfoSec(TIFF* tif)
}
else
{
if ((sp->jpeg_interchange_format_length==0) || (sp->jpeg_interchange_format+sp->jpeg_interchange_format_length>sp->file_size))
if ((sp->jpeg_interchange_format_length==0) ||
(sp->jpeg_interchange_format > TIFF_UINT64_MAX - sp->jpeg_interchange_format_length) ||
(sp->jpeg_interchange_format+sp->jpeg_interchange_format_length>sp->file_size))
sp->jpeg_interchange_format_length=sp->file_size-sp->jpeg_interchange_format;
}
}
@@ -1989,32 +2035,30 @@ OJPEGReadBufferFill(OJPEGState* sp)
sp->in_buffer_source=osibsStrile;
break;
case osibsStrile:
if (!_TIFFFillStriles( sp->tif )
|| sp->tif->tif_dir.td_stripoffset == NULL
|| sp->tif->tif_dir.td_stripbytecount == NULL)
return 0;
if (sp->in_buffer_next_strile==sp->in_buffer_strile_count)
sp->in_buffer_source=osibsEof;
else
{
sp->in_buffer_file_pos=sp->tif->tif_dir.td_stripoffset[sp->in_buffer_next_strile];
int err = 0;
sp->in_buffer_file_pos=TIFFGetStrileOffsetWithErr(sp->tif, sp->in_buffer_next_strile, &err);
if( err )
return 0;
if (sp->in_buffer_file_pos!=0)
{
uint64 bytecount = TIFFGetStrileByteCountWithErr(sp->tif, sp->in_buffer_next_strile, &err);
if( err )
return 0;
if (sp->in_buffer_file_pos>=sp->file_size)
sp->in_buffer_file_pos=0;
else if (sp->tif->tif_dir.td_stripbytecount==NULL)
else if (bytecount==0)
sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos;
else
{
if (sp->tif->tif_dir.td_stripbytecount == 0) {
TIFFErrorExt(sp->tif->tif_clientdata,sp->tif->tif_name,"Strip byte counts are missing");
return(0);
}
sp->in_buffer_file_togo=sp->tif->tif_dir.td_stripbytecount[sp->in_buffer_next_strile];
sp->in_buffer_file_togo=bytecount;
if (sp->in_buffer_file_togo==0)
sp->in_buffer_file_pos=0;
else if (sp->in_buffer_file_pos+sp->in_buffer_file_togo>sp->file_size)
else if (sp->in_buffer_file_pos > TIFF_UINT64_MAX - sp->in_buffer_file_togo ||
sp->in_buffer_file_pos+sp->in_buffer_file_togo>sp->file_size)
sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos;
}
}
+21 -2
View File
@@ -104,6 +104,7 @@ TIFFClientOpen(
} n;
n.a8[0]=1;
n.a8[1]=0;
(void)n;
#ifdef WORDS_BIGENDIAN
assert(n.a16==256);
#else
@@ -131,6 +132,7 @@ TIFFClientOpen(
if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc) {
TIFFErrorExt(clientdata, module,
"One of the client procedures is NULL pointer.");
_TIFFfree(tif);
goto bad2;
}
tif->tif_readproc = readproc;
@@ -164,7 +166,7 @@ TIFFClientOpen(
/*
* Process library-specific flags in the open mode string.
* The following flags may be used to control intrinsic library
* behaviour that may or may not be desirable (usually for
* behavior that may or may not be desirable (usually for
* compatibility with some application that claims to support
* TIFF but only supports some brain dead idea of what the
* vendor thinks TIFF is):
@@ -181,6 +183,8 @@ TIFFClientOpen(
* 'h' read TIFF header only, do not load the first IFD
* '4' ClassicTIFF for creating a file (default)
* '8' BigTIFF for creating a file
* 'D' enable use of deferred strip/tile offset/bytecount array loading.
* 'O' on-demand loading of values instead of whole array loading (implies D)
*
* The use of the 'l' and 'b' flags is strongly discouraged.
* These flags are provided solely because numerous vendors,
@@ -203,7 +207,7 @@ TIFFClientOpen(
* not do right now.
*
* The 'M' and 'm' flags are provided because some virtual memory
* systems exhibit poor behaviour when large images are mapped.
* systems exhibit poor behavior when large images are mapped.
* These options permit clients to control the use of memory-mapped
* files on a per-file basis.
*
@@ -262,7 +266,22 @@ TIFFClientOpen(
if (m&O_CREAT)
tif->tif_flags |= TIFF_BIGTIFF;
break;
case 'D':
tif->tif_flags |= TIFF_DEFERSTRILELOAD;
break;
case 'O':
if( m == O_RDONLY )
tif->tif_flags |= (TIFF_LAZYSTRILELOAD | TIFF_DEFERSTRILELOAD);
break;
}
#ifdef DEFER_STRILE_LOAD
/* Compatibility with old DEFER_STRILE_LOAD compilation flag */
/* Probably unneeded, since to the best of my knowledge (E. Rouault) */
/* GDAL was the only user of this, and will now use the new 'D' flag */
tif->tif_flags |= TIFF_DEFERSTRILELOAD;
#endif
/*
* Read in TIFF header.
*/
+7 -10
View File
@@ -634,16 +634,10 @@ PixarLogGuessDataFmt(TIFFDirectory *td)
return guess;
}
#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0))
#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1)
static tmsize_t
multiply_ms(tmsize_t m1, tmsize_t m2)
{
assert(m1 >= 0 && m2 >= 0);
if( m1 == 0 || m2 > TIFF_TMSIZE_T_MAX / m1 )
return 0;
return m1 * m2;
return _TIFFMultiplySSize(NULL, m1, m2, NULL);
}
static tmsize_t
@@ -1153,7 +1147,7 @@ PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
llen = sp->stride * td->td_imagewidth;
/* Check against the number of elements (of size uint16) of sp->tbuf */
if( n > (tmsize_t)(td->td_rowsperstrip * llen) )
if( n > ((tmsize_t)td->td_rowsperstrip * llen) )
{
TIFFErrorExt(tif->tif_clientdata, module,
"Too many input bytes provided");
@@ -1206,7 +1200,8 @@ PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
}
if (sp->stream.avail_out == 0) {
tif->tif_rawcc = tif->tif_rawdatasize;
TIFFFlushData1(tif);
if (!TIFFFlushData1(tif))
return 0;
sp->stream.next_out = tif->tif_rawdata;
sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in PixarLogPreEncode */
}
@@ -1236,7 +1231,8 @@ PixarLogPostEncode(TIFF* tif)
if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) {
tif->tif_rawcc =
tif->tif_rawdatasize - sp->stream.avail_out;
TIFFFlushData1(tif);
if (!TIFFFlushData1(tif))
return 0;
sp->stream.next_out = tif->tif_rawdata;
sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in PixarLogPreEncode */
}
@@ -1404,6 +1400,7 @@ TIFFInitPixarLog(TIFF* tif, int scheme)
PixarLogState* sp;
(void)scheme;
assert(scheme == COMPRESSION_PIXARLOG);
/*
+3 -3
View File
@@ -116,7 +116,7 @@ PredictorSetupDecode(TIFF* tif)
TIFFDirectory* td = &tif->tif_dir;
/* Note: when PredictorSetup() fails, the effets of setupdecode() */
/* will not be "cancelled" so setupdecode() might be robust to */
/* will not be "canceled" so setupdecode() might be robust to */
/* be called several times. */
if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif))
return 0;
@@ -270,8 +270,8 @@ PredictorSetupEncode(TIFF* tif)
}
/* Remarks related to C standard compliance in all below functions : */
/* - to avoid any undefined behaviour, we only operate on unsigned types */
/* since the behaviour of "overflows" is defined (wrap over) */
/* - to avoid any undefined behavior, we only operate on unsigned types */
/* since the behavior of "overflows" is defined (wrap over) */
/* - when storing into the byte stream, we explicitly mask with 0xff so */
/* as to make icc -check=conversions happy (not necessary by the standard) */
+4 -6
View File
@@ -652,8 +652,6 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
if (tif->tif_tagmethods.printdir)
(*tif->tif_tagmethods.printdir)(tif, fd, flags);
_TIFFFillStriles( tif );
if ((flags & TIFFPRINT_STRIPS) &&
TIFFFieldSet(tif,FIELD_STRIPOFFSETS)) {
uint32 s;
@@ -665,13 +663,13 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
fprintf(fd, " %3lu: [%8I64u, %8I64u]\n",
(unsigned long) s,
td->td_stripoffset ? (unsigned __int64) td->td_stripoffset[s] : 0,
td->td_stripbytecount ? (unsigned __int64) td->td_stripbytecount[s] : 0);
(unsigned __int64) TIFFGetStrileOffset(tif, s),
(unsigned __int64) TIFFGetStrileByteCount(tif, s));
#else
fprintf(fd, " %3lu: [%8llu, %8llu]\n",
(unsigned long) s,
td->td_stripoffset ? (unsigned long long) td->td_stripoffset[s] : 0,
td->td_stripbytecount ? (unsigned long long) td->td_stripbytecount[s] : 0);
(unsigned long long) TIFFGetStrileOffset(tif, s),
(unsigned long long) TIFFGetStrileByteCount(tif, s));
#endif
}
}
+167 -95
View File
@@ -29,9 +29,6 @@
#include "tiffiop.h"
#include <stdio.h>
#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0))
#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1)
int TIFFFillStrip(TIFF* tif, uint32 strip);
int TIFFFillTile(TIFF* tif, uint32 tile);
static int TIFFStartStrip(TIFF* tif, uint32 strip);
@@ -49,6 +46,8 @@ TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* m
#define THRESHOLD_MULTIPLIER 10
#define MAX_THRESHOLD (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * INITIAL_THRESHOLD)
#define TIFF_INT64_MAX ((((int64)0x7FFFFFFF) << 32) | 0xFFFFFFFF)
/* Read 'size' bytes in tif_rawdata buffer starting at offset 'rawdata_offset'
* Returns 1 in case of success, 0 otherwise. */
static int TIFFReadAndRealloc( TIFF* tif, tmsize_t size,
@@ -61,6 +60,22 @@ static int TIFFReadAndRealloc( TIFF* tif, tmsize_t size,
#endif
tmsize_t already_read = 0;
#if SIZEOF_SIZE_T != 8
/* On 32 bit processes, if the request is large enough, check against */
/* file size */
if( size > 1000 * 1000 * 1000 )
{
uint64 filesize = TIFFGetFileSize(tif);
if( (uint64)size >= filesize )
{
TIFFErrorExt(tif->tif_clientdata, module,
"Chunk size requested is larger than file size.");
return 0;
}
}
#endif
/* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */
/* so as to avoid allocating too much memory in case the file is too */
/* short. We could ask for the file size, but this might be */
@@ -175,17 +190,14 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
tmsize_t to_read;
tmsize_t read_ahead_mod;
/* tmsize_t bytecountm; */
if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
return 0;
/*
* Expand raw data buffer, if needed, to hold data
* strip coming from file (perhaps should set upper
* bound on the size of a buffer we'll use?).
*/
/* bytecountm=(tmsize_t) td->td_stripbytecount[strip]; */
/* bytecountm=(tmsize_t) TIFFGetStrileByteCount(tif, strip); */
/* Not completely sure where the * 2 comes from, but probably for */
/* an exponentional growth strategy of tif_rawdatasize */
@@ -229,7 +241,7 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
/*
** Seek to the point in the file where more data should be read.
*/
read_offset = td->td_stripoffset[strip]
read_offset = TIFFGetStrileOffset(tif, strip)
+ tif->tif_rawdataoff + tif->tif_rawdataloaded;
if (!SeekOK(tif, read_offset)) {
@@ -246,10 +258,10 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
to_read = read_ahead_mod - unused_data;
else
to_read = tif->tif_rawdatasize - unused_data;
if( (uint64) to_read > td->td_stripbytecount[strip]
if( (uint64) to_read > TIFFGetStrileByteCount(tif, strip)
- tif->tif_rawdataoff - tif->tif_rawdataloaded )
{
to_read = (tmsize_t) td->td_stripbytecount[strip]
to_read = (tmsize_t) TIFFGetStrileByteCount(tif, strip)
- tif->tif_rawdataoff - tif->tif_rawdataloaded;
}
@@ -288,7 +300,7 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
/* For JPEG, if there are multiple scans (can generally be known */
/* with the read_ahead used), we need to read the whole strip */
if( tif->tif_dir.td_compression==COMPRESSION_JPEG &&
(uint64)tif->tif_rawcc < td->td_stripbytecount[strip] )
(uint64)tif->tif_rawcc < TIFFGetStrileByteCount(tif, strip) )
{
if( TIFFJPEGIsFullStripRequired(tif) )
{
@@ -347,9 +359,7 @@ TIFFSeek(TIFF* tif, uint32 row, uint16 sample )
* read it a few lines at a time?
*/
#if defined(CHUNKY_STRIP_READ_SUPPORT)
if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
return 0;
whole_strip = tif->tif_dir.td_stripbytecount[strip] < 10
whole_strip = TIFFGetStrileByteCount(tif, strip) < 10
|| isMapped(tif);
if( td->td_compression == COMPRESSION_LERC ||
td->td_compression == COMPRESSION_JBIG )
@@ -402,7 +412,7 @@ TIFFSeek(TIFF* tif, uint32 row, uint16 sample )
else if( !whole_strip )
{
if( ((tif->tif_rawdata + tif->tif_rawdataloaded) - tif->tif_rawcp) < read_ahead
&& (uint64) tif->tif_rawdataoff+tif->tif_rawdataloaded < td->td_stripbytecount[strip] )
&& (uint64) tif->tif_rawdataoff+tif->tif_rawdataloaded < TIFFGetStrileByteCount(tif, strip) )
{
if( !TIFFFillStripPartial(tif,strip,read_ahead,0) )
return 0;
@@ -599,16 +609,11 @@ static tmsize_t
TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,
const char* module)
{
TIFFDirectory *td = &tif->tif_dir;
if (!_TIFFFillStriles( tif ))
return ((tmsize_t)(-1));
assert((tif->tif_flags&TIFF_NOREADRAW)==0);
if (!isMapped(tif)) {
tmsize_t cc;
if (!SeekOK(tif, td->td_stripoffset[strip])) {
if (!SeekOK(tif, TIFFGetStrileOffset(tif, strip))) {
TIFFErrorExt(tif->tif_clientdata, module,
"Seek error at scanline %lu, strip %lu",
(unsigned long) tif->tif_row, (unsigned long) strip);
@@ -634,8 +639,8 @@ TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,
} else {
tmsize_t ma = 0;
tmsize_t n;
if ((td->td_stripoffset[strip] > (uint64)TIFF_TMSIZE_T_MAX)||
((ma=(tmsize_t)td->td_stripoffset[strip])>tif->tif_size))
if ((TIFFGetStrileOffset(tif, strip) > (uint64)TIFF_TMSIZE_T_MAX)||
((ma=(tmsize_t)TIFFGetStrileOffset(tif, strip))>tif->tif_size))
{
n=0;
}
@@ -679,12 +684,10 @@ static tmsize_t
TIFFReadRawStripOrTile2(TIFF* tif, uint32 strip_or_tile, int is_strip,
tmsize_t size, const char* module)
{
TIFFDirectory *td = &tif->tif_dir;
assert( !isMapped(tif) );
assert((tif->tif_flags&TIFF_NOREADRAW)==0);
if (!SeekOK(tif, td->td_stripoffset[strip_or_tile])) {
if (!SeekOK(tif, TIFFGetStrileOffset(tif, strip_or_tile))) {
if( is_strip )
{
TIFFErrorExt(tif->tif_clientdata, module,
@@ -720,7 +723,7 @@ TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
{
static const char module[] = "TIFFReadRawStrip";
TIFFDirectory *td = &tif->tif_dir;
uint64 bytecount;
uint64 bytecount64;
tmsize_t bytecountm;
if (!TIFFCheckRead(tif, 0))
@@ -738,31 +741,23 @@ TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
"Compression scheme does not support access to raw uncompressed data");
return ((tmsize_t)(-1));
}
bytecount = td->td_stripbytecount[strip];
if ((int64)bytecount <= 0) {
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
TIFFErrorExt(tif->tif_clientdata, module,
"%I64u: Invalid strip byte count, strip %lu",
(unsigned __int64) bytecount,
(unsigned long) strip);
#else
TIFFErrorExt(tif->tif_clientdata, module,
"%llu: Invalid strip byte count, strip %lu",
(unsigned long long) bytecount,
(unsigned long) strip);
#endif
return ((tmsize_t)(-1));
}
bytecountm = (tmsize_t)bytecount;
if ((uint64)bytecountm!=bytecount) {
TIFFErrorExt(tif->tif_clientdata, module, "Integer overflow");
return ((tmsize_t)(-1));
}
if (size != (tmsize_t)(-1) && size < bytecountm)
bytecount64 = TIFFGetStrileByteCount(tif, strip);
if (size != (tmsize_t)(-1) && (uint64)size <= bytecount64)
bytecountm = size;
else
bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module);
if( bytecountm == 0 ) {
return ((tmsize_t)(-1));
}
return (TIFFReadRawStrip1(tif, strip, buf, bytecountm, module));
}
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
static uint64 NoSanitizeSubUInt64(uint64 a, uint64 b)
{
return a - b;
}
/*
* Read the specified strip and setup for decoding. The data buffer is
* expanded, as necessary, to hold the strip's data.
@@ -773,13 +768,10 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
static const char module[] = "TIFFFillStrip";
TIFFDirectory *td = &tif->tif_dir;
if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
return 0;
if ((tif->tif_flags&TIFF_NOREADRAW)==0)
{
uint64 bytecount = td->td_stripbytecount[strip];
if ((int64)bytecount <= 0) {
uint64 bytecount = TIFFGetStrileByteCount(tif, strip);
if( bytecount == 0 || bytecount > (uint64)TIFF_INT64_MAX ) {
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
TIFFErrorExt(tif->tif_clientdata, module,
"Invalid strip byte count %I64u, strip %lu",
@@ -806,7 +798,7 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
(bytecount - 4096) / 10 > (uint64)stripsize )
{
uint64 newbytecount = (uint64)stripsize * 10 + 4096;
if( (int64)newbytecount >= 0 )
if( newbytecount == 0 || newbytecount > (uint64)TIFF_INT64_MAX )
{
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
TIFFWarningExt(tif->tif_clientdata, module,
@@ -831,13 +823,13 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
* We must check for overflow, potentially causing
* an OOB read. Instead of simple
*
* td->td_stripoffset[strip]+bytecount > tif->tif_size
* TIFFGetStrileOffset(tif, strip)+bytecount > tif->tif_size
*
* comparison (which can overflow) we do the following
* two comparisons:
*/
if (bytecount > (uint64)tif->tif_size ||
td->td_stripoffset[strip] > (uint64)tif->tif_size - bytecount) {
TIFFGetStrileOffset(tif, strip) > (uint64)tif->tif_size - bytecount) {
/*
* This error message might seem strange, but
* it's what would happen if a read were done
@@ -849,7 +841,7 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
"Read error on strip %lu; "
"got %I64u bytes, expected %I64u",
(unsigned long) strip,
(unsigned __int64) tif->tif_size - td->td_stripoffset[strip],
(unsigned __int64) NoSanitizeSubUInt64(tif->tif_size, TIFFGetStrileOffset(tif, strip)),
(unsigned __int64) bytecount);
#else
TIFFErrorExt(tif->tif_clientdata, module,
@@ -857,7 +849,7 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
"Read error on strip %lu; "
"got %llu bytes, expected %llu",
(unsigned long) strip,
(unsigned long long) tif->tif_size - td->td_stripoffset[strip],
(unsigned long long) NoSanitizeSubUInt64(tif->tif_size, TIFFGetStrileOffset(tif, strip)),
(unsigned long long) bytecount);
#endif
tif->tif_curstrip = NOSTRIP;
@@ -886,7 +878,7 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
}
tif->tif_flags &= ~TIFF_MYBUFFER;
tif->tif_rawdatasize = (tmsize_t)bytecount;
tif->tif_rawdata = tif->tif_base + (tmsize_t)td->td_stripoffset[strip];
tif->tif_rawdata = tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, strip);
tif->tif_rawdataoff = 0;
tif->tif_rawdataloaded = (tmsize_t) bytecount;
@@ -1101,16 +1093,11 @@ _TIFFReadEncodedTileAndAllocBuffer(TIFF* tif, uint32 tile,
static tmsize_t
TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* module)
{
TIFFDirectory *td = &tif->tif_dir;
if (!_TIFFFillStriles( tif ))
return ((tmsize_t)(-1));
assert((tif->tif_flags&TIFF_NOREADRAW)==0);
if (!isMapped(tif)) {
tmsize_t cc;
if (!SeekOK(tif, td->td_stripoffset[tile])) {
if (!SeekOK(tif, TIFFGetStrileOffset(tif, tile))) {
TIFFErrorExt(tif->tif_clientdata, module,
"Seek error at row %lu, col %lu, tile %lu",
(unsigned long) tif->tif_row,
@@ -1140,9 +1127,9 @@ TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* m
} else {
tmsize_t ma,mb;
tmsize_t n;
ma=(tmsize_t)td->td_stripoffset[tile];
ma=(tmsize_t)TIFFGetStrileOffset(tif, tile);
mb=ma+size;
if ((td->td_stripoffset[tile] > (uint64)TIFF_TMSIZE_T_MAX)||(ma>tif->tif_size))
if ((TIFFGetStrileOffset(tif, tile) > (uint64)TIFF_TMSIZE_T_MAX)||(ma>tif->tif_size))
n=0;
else if ((mb<ma)||(mb<size)||(mb>tif->tif_size))
n=tif->tif_size-ma;
@@ -1198,13 +1185,12 @@ TIFFReadRawTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size)
"Compression scheme does not support access to raw uncompressed data");
return ((tmsize_t)(-1));
}
bytecount64 = td->td_stripbytecount[tile];
if (size != (tmsize_t)(-1) && (uint64)size < bytecount64)
bytecount64 = (uint64)size;
bytecountm = (tmsize_t)bytecount64;
if ((uint64)bytecountm!=bytecount64)
{
TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
bytecount64 = TIFFGetStrileByteCount(tif, tile);
if (size != (tmsize_t)(-1) && (uint64)size <= bytecount64)
bytecountm = size;
else
bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module);
if( bytecountm == 0 ) {
return ((tmsize_t)(-1));
}
return (TIFFReadRawTile1(tif, tile, buf, bytecountm, module));
@@ -1220,13 +1206,10 @@ TIFFFillTile(TIFF* tif, uint32 tile)
static const char module[] = "TIFFFillTile";
TIFFDirectory *td = &tif->tif_dir;
if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
return 0;
if ((tif->tif_flags&TIFF_NOREADRAW)==0)
{
uint64 bytecount = td->td_stripbytecount[tile];
if ((int64)bytecount <= 0) {
uint64 bytecount = TIFFGetStrileByteCount(tif, tile);
if( bytecount == 0 || bytecount > (uint64)TIFF_INT64_MAX ) {
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
TIFFErrorExt(tif->tif_clientdata, module,
"%I64u: Invalid tile byte count, tile %lu",
@@ -1253,7 +1236,7 @@ TIFFFillTile(TIFF* tif, uint32 tile)
(bytecount - 4096) / 10 > (uint64)stripsize )
{
uint64 newbytecount = (uint64)stripsize * 10 + 4096;
if( (int64)newbytecount >= 0 )
if( newbytecount == 0 || newbytecount > (uint64)TIFF_INT64_MAX )
{
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
TIFFWarningExt(tif->tif_clientdata, module,
@@ -1278,13 +1261,13 @@ TIFFFillTile(TIFF* tif, uint32 tile)
* We must check for overflow, potentially causing
* an OOB read. Instead of simple
*
* td->td_stripoffset[tile]+bytecount > tif->tif_size
* TIFFGetStrileOffset(tif, tile)+bytecount > tif->tif_size
*
* comparison (which can overflow) we do the following
* two comparisons:
*/
if (bytecount > (uint64)tif->tif_size ||
td->td_stripoffset[tile] > (uint64)tif->tif_size - bytecount) {
TIFFGetStrileOffset(tif, tile) > (uint64)tif->tif_size - bytecount) {
tif->tif_curtile = NOTILE;
return (0);
}
@@ -1313,7 +1296,7 @@ TIFFFillTile(TIFF* tif, uint32 tile)
tif->tif_rawdatasize = (tmsize_t)bytecount;
tif->tif_rawdata =
tif->tif_base + (tmsize_t)td->td_stripoffset[tile];
tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, tile);
tif->tif_rawdataoff = 0;
tif->tif_rawdataloaded = (tmsize_t) bytecount;
tif->tif_flags |= TIFF_BUFFERMMAP;
@@ -1440,9 +1423,6 @@ TIFFStartStrip(TIFF* tif, uint32 strip)
{
TIFFDirectory *td = &tif->tif_dir;
if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
return 0;
if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
if (!(*tif->tif_setupdecode)(tif))
return (0);
@@ -1463,10 +1443,18 @@ TIFFStartStrip(TIFF* tif, uint32 strip)
if( tif->tif_rawdataloaded > 0 )
tif->tif_rawcc = tif->tif_rawdataloaded;
else
tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[strip];
tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, strip);
}
return ((*tif->tif_predecode)(tif,
(uint16)(strip / td->td_stripsperimage)));
if ((*tif->tif_predecode)(tif,
(uint16)(strip / td->td_stripsperimage)) == 0 ) {
/* Needed for example for scanline access, if tif_predecode */
/* fails, and we try to read the same strip again. Without invalidating */
/* tif_curstrip, we'd call tif_decoderow() on a possibly invalid */
/* codec state. */
tif->tif_curstrip = NOSTRIP;
return 0;
}
return 1;
}
/*
@@ -1480,9 +1468,6 @@ TIFFStartTile(TIFF* tif, uint32 tile)
TIFFDirectory *td = &tif->tif_dir;
uint32 howmany32;
if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
return 0;
if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
if (!(*tif->tif_setupdecode)(tif))
return (0);
@@ -1513,7 +1498,7 @@ TIFFStartTile(TIFF* tif, uint32 tile)
if( tif->tif_rawdataloaded > 0 )
tif->tif_rawcc = tif->tif_rawdataloaded;
else
tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[tile];
tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, tile);
}
return ((*tif->tif_predecode)(tif,
(uint16)(tile/td->td_stripsperimage)));
@@ -1528,13 +1513,100 @@ TIFFCheckRead(TIFF* tif, int tiles)
}
if (tiles ^ isTiled(tif)) {
TIFFErrorExt(tif->tif_clientdata, tif->tif_name, tiles ?
"Can not read tiles from a stripped image" :
"Can not read tiles from a striped image" :
"Can not read scanlines from a tiled image");
return (0);
}
return (1);
}
/* Use the provided input buffer (inbuf, insize) and decompress it into
* (outbuf, outsize).
* This function replaces the use of TIFFReadEncodedStrip()/TIFFReadEncodedTile()
* when the user can provide the buffer for the input data, for example when
* he wants to avoid libtiff to read the strile offset/count values from the
* [Strip|Tile][Offsets/ByteCounts] array.
* inbuf content must be writable (if bit reversal is needed)
* Returns 1 in case of success, 0 otherwise.
*/
int TIFFReadFromUserBuffer(TIFF* tif, uint32 strile,
void* inbuf, tmsize_t insize,
void* outbuf, tmsize_t outsize)
{
static const char module[] = "TIFFReadFromUserBuffer";
TIFFDirectory *td = &tif->tif_dir;
int ret = 1;
uint32 old_tif_flags = tif->tif_flags;
tmsize_t old_rawdatasize = tif->tif_rawdatasize;
void* old_rawdata = tif->tif_rawdata;
if (tif->tif_mode == O_WRONLY) {
TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "File not open for reading");
return 0;
}
if (tif->tif_flags&TIFF_NOREADRAW)
{
TIFFErrorExt(tif->tif_clientdata, module,
"Compression scheme does not support access to raw uncompressed data");
return 0;
}
tif->tif_flags &= ~TIFF_MYBUFFER;
tif->tif_flags |= TIFF_BUFFERMMAP;
tif->tif_rawdatasize = insize;
tif->tif_rawdata = inbuf;
tif->tif_rawdataoff = 0;
tif->tif_rawdataloaded = insize;
if (!isFillOrder(tif, td->td_fillorder) &&
(tif->tif_flags & TIFF_NOBITREV) == 0)
{
TIFFReverseBits(inbuf, insize);
}
if( TIFFIsTiled(tif) )
{
if( !TIFFStartTile(tif, strile) ||
!(*tif->tif_decodetile)(tif, (uint8*) outbuf, outsize,
(uint16)(strile/td->td_stripsperimage)) )
{
ret = 0;
}
}
else
{
uint32 rowsperstrip=td->td_rowsperstrip;
uint32 stripsperplane;
if (rowsperstrip>td->td_imagelength)
rowsperstrip=td->td_imagelength;
stripsperplane= TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip);
if( !TIFFStartStrip(tif, strile) ||
!(*tif->tif_decodestrip)(tif, (uint8*) outbuf, outsize,
(uint16)(strile/stripsperplane)) )
{
ret = 0;
}
}
if( ret )
{
(*tif->tif_postdecode)(tif, (uint8*) outbuf, outsize);
}
if (!isFillOrder(tif, td->td_fillorder) &&
(tif->tif_flags & TIFF_NOBITREV) == 0)
{
TIFFReverseBits(inbuf, insize);
}
tif->tif_flags = old_tif_flags;
tif->tif_rawdatasize = old_rawdatasize;
tif->tif_rawdata = old_rawdata;
tif->tif_rawdataoff = 0;
tif->tif_rawdataloaded = 0;
return ret;
}
void
_TIFFNoPostDecode(TIFF* tif, uint8* buf, tmsize_t cc)
{
+5 -33
View File
@@ -129,15 +129,8 @@ TIFFVStripSize(TIFF* tif, uint32 nrows)
{
static const char module[] = "TIFFVStripSize";
uint64 m;
tmsize_t n;
m=TIFFVStripSize64(tif,nrows);
n=(tmsize_t)m;
if ((uint64)n!=m)
{
TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
n=0;
}
return(n);
return _TIFFCastUInt64ToSSize(tif, m, module);
}
/*
@@ -147,8 +140,7 @@ uint64
TIFFRawStripSize64(TIFF* tif, uint32 strip)
{
static const char module[] = "TIFFRawStripSize64";
TIFFDirectory* td = &tif->tif_dir;
uint64 bytecount = td->td_stripbytecount[strip];
uint64 bytecount = TIFFGetStrileByteCount(tif, strip);
if (bytecount == 0)
{
@@ -211,15 +203,8 @@ TIFFStripSize(TIFF* tif)
{
static const char module[] = "TIFFStripSize";
uint64 m;
tmsize_t n;
m=TIFFStripSize64(tif);
n=(tmsize_t)m;
if ((uint64)n!=m)
{
TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
n=0;
}
return(n);
return _TIFFCastUInt64ToSSize(tif, m, module);
}
/*
@@ -330,14 +315,8 @@ TIFFScanlineSize(TIFF* tif)
{
static const char module[] = "TIFFScanlineSize";
uint64 m;
tmsize_t n;
m=TIFFScanlineSize64(tif);
n=(tmsize_t)m;
if ((uint64)n!=m) {
TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow");
n=0;
}
return(n);
return _TIFFCastUInt64ToSSize(tif, m, module);
}
/*
@@ -366,15 +345,8 @@ TIFFRasterScanlineSize(TIFF* tif)
{
static const char module[] = "TIFFRasterScanlineSize";
uint64 m;
tmsize_t n;
m=TIFFRasterScanlineSize64(tif);
n=(tmsize_t)m;
if ((uint64)n!=m)
{
TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow");
n=0;
}
return(n);
return _TIFFCastUInt64ToSSize(tif, m, module);
}
/* vim: set ts=8 sts=8 sw=8 noet: */
+5 -5
View File
@@ -122,17 +122,17 @@ ThunderDecode(TIFF* tif, uint8* op, tmsize_t maxpixels)
break;
case THUNDER_2BITDELTAS: /* 2-bit deltas */
if ((delta = ((n >> 4) & 3)) != DELTA2_SKIP)
SETPIXEL(op, lastpixel + twobitdeltas[delta]);
SETPIXEL(op, (unsigned)((int)lastpixel + twobitdeltas[delta]));
if ((delta = ((n >> 2) & 3)) != DELTA2_SKIP)
SETPIXEL(op, lastpixel + twobitdeltas[delta]);
SETPIXEL(op, (unsigned)((int)lastpixel + twobitdeltas[delta]));
if ((delta = (n & 3)) != DELTA2_SKIP)
SETPIXEL(op, lastpixel + twobitdeltas[delta]);
SETPIXEL(op, (unsigned)((int)lastpixel + twobitdeltas[delta]));
break;
case THUNDER_3BITDELTAS: /* 3-bit deltas */
if ((delta = ((n >> 3) & 7)) != DELTA3_SKIP)
SETPIXEL(op, lastpixel + threebitdeltas[delta]);
SETPIXEL(op, (unsigned)((int)lastpixel + threebitdeltas[delta]));
if ((delta = (n & 7)) != DELTA3_SKIP)
SETPIXEL(op, lastpixel + threebitdeltas[delta]);
SETPIXEL(op, (unsigned)((int)lastpixel + threebitdeltas[delta]));
break;
case THUNDER_RAW: /* raw data */
SETPIXEL(op, n);
+3 -24
View File
@@ -181,15 +181,8 @@ TIFFTileRowSize(TIFF* tif)
{
static const char module[] = "TIFFTileRowSize";
uint64 m;
tmsize_t n;
m=TIFFTileRowSize64(tif);
n=(tmsize_t)m;
if ((uint64)n!=m)
{
TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
n=0;
}
return(n);
return _TIFFCastUInt64ToSSize(tif, m, module);
}
/*
@@ -248,15 +241,8 @@ TIFFVTileSize(TIFF* tif, uint32 nrows)
{
static const char module[] = "TIFFVTileSize";
uint64 m;
tmsize_t n;
m=TIFFVTileSize64(tif,nrows);
n=(tmsize_t)m;
if ((uint64)n!=m)
{
TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
n=0;
}
return(n);
return _TIFFCastUInt64ToSSize(tif, m, module);
}
/*
@@ -272,15 +258,8 @@ TIFFTileSize(TIFF* tif)
{
static const char module[] = "TIFFTileSize";
uint64 m;
tmsize_t n;
m=TIFFTileSize64(tif);
n=(tmsize_t)m;
if ((uint64)n!=m)
{
TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
n=0;
}
return(n);
return _TIFFCastUInt64ToSSize(tif, m, module);
}
/*
+1 -1
View File
@@ -162,7 +162,7 @@ _tiffMapProc(thandle_t fd, void** pbase, toff_t* psize)
{
uint64 size64 = _tiffSizeProc(fd);
tmsize_t sizem = (tmsize_t)size64;
if ((uint64)sizem==size64) {
if (size64 && (uint64)sizem==size64) {
fd_as_handle_union_t fdh;
fdh.h = fd;
*pbase = (void*)
+11 -4
View File
@@ -267,6 +267,12 @@ TWebPPreDecode(TIFF* tif, uint16 s)
segment_height = td->td_rowsperstrip;
}
if( segment_width > 16383 || segment_height > 16383 ) {
TIFFErrorExt(tif->tif_clientdata, module,
"WEBP maximum image dimensions are 16383 x 16383.");
return 0;
}
if( (sp->state & LSTATE_INIT_DECODE) == 0 )
tif->tif_setupdecode(tif);
@@ -333,7 +339,7 @@ TWebPSetupEncode(TIFF* tif)
}
/* check bits per sample and data type */
if ((nBitsPerSample != 8) && (sampleFormat != 1)) {
if ((nBitsPerSample != 8) || (sampleFormat != SAMPLEFORMAT_UINT)) {
TIFFErrorExt(tif->tif_clientdata, module,
"WEBP driver requires 8 bit unsigned data");
return 0;
@@ -356,7 +362,7 @@ TWebPSetupEncode(TIFF* tif)
}
if (!WebPConfigInitInternal(&sp->sEncoderConfig, WEBP_PRESET_DEFAULT,
sp->quality_level,
(float)sp->quality_level,
WEBP_ENCODER_ABI_VERSION)) {
TIFFErrorExt(tif->tif_clientdata, module,
"Error creating WebP encoder configuration.");
@@ -579,7 +585,7 @@ TWebPVSetField(TIFF* tif, uint32 tag, va_list ap)
#if WEBP_ENCODER_ABI_VERSION >= 0x0100
sp->lossless = va_arg(ap, int);
if (sp->lossless){
sp->quality_level = 100.0f;
sp->quality_level = 100;
}
return 1;
#else
@@ -628,6 +634,7 @@ TIFFInitWebP(TIFF* tif, int scheme)
static const char module[] = "TIFFInitWebP";
WebPState* sp;
(void)scheme;
assert( scheme == COMPRESSION_WEBP );
/*
@@ -656,7 +663,7 @@ TIFFInitWebP(TIFF* tif, int scheme)
tif->tif_tagmethods.vsetfield = TWebPVSetField; /* hook for codec tags */
/* Default values for codec-specific fields */
sp->quality_level = 75.0f; /* default comp. level */
sp->quality_level = 75; /* default comp. level */
sp->lossless = 0; /* default to false */
sp->state = 0;
sp->nSamples = 0;
+37 -31
View File
@@ -27,34 +27,38 @@
* Scott Wagner (wagner@itek.com), Itek Graphix, Rochester, NY USA
*/
/*
CreateFileA/CreateFileW return type 'HANDLE'.
thandle_t is declared like
DECLARE_HANDLE(thandle_t);
in tiffio.h.
Windows (from winnt.h) DECLARE_HANDLE logic looks like
#ifdef STRICT
typedef void *HANDLE;
#define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
#else
typedef PVOID HANDLE;
#define DECLARE_HANDLE(name) typedef HANDLE name
#endif
See http://bugzilla.maptools.org/show_bug.cgi?id=1941 for problems in WIN64
builds resulting from this. Unfortunately, the proposed patch was lost.
*/
#include "tiffiop.h"
#include <windows.h>
/*
CreateFileA/CreateFileW return type 'HANDLE' while TIFFFdOpen() takes 'int',
which is formally incompatible and can even seemingly be of different size:
HANDLE is 64 bit under Win64, while int is still 32 bits there.
However, only the lower 32 bits of a HANDLE are significant under Win64 as,
for interoperability reasons, they must have the same values in 32- and
64-bit programs running on the same system, see
https://docs.microsoft.com/en-us/windows/win32/winprog64/interprocess-communication
Because of this, it is safe to define the following trivial functions for
casting between ints and HANDLEs, which are only really needed to avoid
compiler warnings (and, perhaps, to make the code slightly more clear).
Note that using the intermediate cast to "intptr_t" is crucial for warning
avoidance, as this integer type has the same size as HANDLE in all builds.
*/
static inline thandle_t thandle_from_int(int ifd)
{
return (thandle_t)(intptr_t)ifd;
}
static inline int thandle_to_int(thandle_t fd)
{
return (int)(intptr_t)fd;
}
static tmsize_t
_tiffReadProc(thandle_t fd, void* buf, tmsize_t size)
{
@@ -151,9 +155,11 @@ _tiffCloseProc(thandle_t fd)
static uint64
_tiffSizeProc(thandle_t fd)
{
ULARGE_INTEGER m;
m.LowPart=GetFileSize(fd,&m.HighPart);
return(m.QuadPart);
LARGE_INTEGER m;
if (GetFileSizeEx(fd,&m))
return(m.QuadPart);
else
return(0);
}
static int
@@ -185,7 +191,7 @@ _tiffMapProc(thandle_t fd, void** pbase, toff_t* psize)
size = _tiffSizeProc(fd);
sizem = (tmsize_t)size;
if ((uint64)sizem!=size)
if (!size || (uint64)sizem!=size)
return (0);
/* By passing in 0 for the maximum file size, it specifies that we
@@ -237,7 +243,7 @@ TIFFFdOpen(int ifd, const char* name, const char* mode)
break;
}
}
tif = TIFFClientOpen(name, mode, (thandle_t)ifd, /* FIXME: WIN64 cast to pointer warning */
tif = TIFFClientOpen(name, mode, thandle_from_int(ifd),
_tiffReadProc, _tiffWriteProc,
_tiffSeekProc, _tiffCloseProc, _tiffSizeProc,
fSuppressMap ? _tiffDummyMapProc : _tiffMapProc,
@@ -282,7 +288,7 @@ TIFFOpen(const char* name, const char* mode)
return ((TIFF *)0);
}
tif = TIFFFdOpen((int)fd, name, mode); /* FIXME: WIN64 cast from pointer to int warning */
tif = TIFFFdOpen(thandle_to_int(fd), name, mode);
if(!tif)
CloseHandle(fd);
return tif;
@@ -337,7 +343,7 @@ TIFFOpenW(const wchar_t* name, const char* mode)
NULL, NULL);
}
tif = TIFFFdOpen((int)fd, /* FIXME: WIN64 cast from pointer to int warning */
tif = TIFFFdOpen(thandle_to_int(fd),
(mbname != NULL) ? mbname : "<unknown>", mode);
if(!tif)
CloseHandle(fd);
+86 -63
View File
@@ -128,10 +128,10 @@ TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample)
tif->tif_rawcc = 0;
tif->tif_rawcp = tif->tif_rawdata;
if( td->td_stripbytecount[strip] > 0 )
if( td->td_stripbytecount_p[strip] > 0 )
{
/* if we are writing over existing tiles, zero length */
td->td_stripbytecount[strip] = 0;
td->td_stripbytecount_p[strip] = 0;
/* this forces TIFFAppendToStrip() to do a seek */
tif->tif_curoff = 0;
@@ -176,6 +176,32 @@ TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample)
return (status);
}
/* Make sure that at the first attempt of rewriting a tile/strip, we will have */
/* more bytes available in the output buffer than the previous byte count, */
/* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
/* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
static int _TIFFReserveLargeEnoughWriteBuffer(TIFF* tif, uint32 strip_or_tile)
{
TIFFDirectory *td = &tif->tif_dir;
if( td->td_stripbytecount_p[strip_or_tile] > 0 )
{
/* The +1 is to ensure at least one extra bytes */
/* The +4 is because the LZW encoder flushes 4 bytes before the limit */
uint64 safe_buffer_size = (uint64)(td->td_stripbytecount_p[strip_or_tile] + 1 + 4);
if( tif->tif_rawdatasize <= (tmsize_t)safe_buffer_size )
{
if( !(TIFFWriteBufferSetup(tif, NULL,
(tmsize_t)TIFFroundup_64(safe_buffer_size, 1024))) )
return 0;
}
/* Force TIFFAppendToStrip() to consider placing data at end
of file. */
tif->tif_curoff = 0;
}
return 1;
}
/*
* Encode the supplied data and write it to the
* specified strip.
@@ -222,6 +248,13 @@ TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc)
tif->tif_flags |= TIFF_BUF4WRITE;
tif->tif_curstrip = strip;
if( !_TIFFReserveLargeEnoughWriteBuffer(tif, strip) ) {
return ((tmsize_t)(-1));
}
tif->tif_rawcc = 0;
tif->tif_rawcp = tif->tif_rawdata;
if (td->td_stripsperimage == 0) {
TIFFErrorExt(tif->tif_clientdata, module, "Zero strips per image");
return ((tmsize_t) -1);
@@ -234,27 +267,6 @@ TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc)
tif->tif_flags |= TIFF_CODERSETUP;
}
if( td->td_stripbytecount[strip] > 0 )
{
/* Make sure that at the first attempt of rewriting the tile, we will have */
/* more bytes available in the output buffer than the previous byte count, */
/* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
/* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
if( tif->tif_rawdatasize <= (tmsize_t)td->td_stripbytecount[strip] )
{
if( !(TIFFWriteBufferSetup(tif, NULL,
(tmsize_t)TIFFroundup_64((uint64)(td->td_stripbytecount[strip] + 1), 1024))) )
return ((tmsize_t)(-1));
}
/* Force TIFFAppendToStrip() to consider placing data at end
of file. */
tif->tif_curoff = 0;
}
tif->tif_rawcc = 0;
tif->tif_rawcp = tif->tif_rawdata;
tif->tif_flags &= ~TIFF_POSTENCODE;
/* shortcut to avoid an extra memcpy() */
@@ -402,22 +414,8 @@ TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc)
tif->tif_flags |= TIFF_BUF4WRITE;
tif->tif_curtile = tile;
if( td->td_stripbytecount[tile] > 0 )
{
/* Make sure that at the first attempt of rewriting the tile, we will have */
/* more bytes available in the output buffer than the previous byte count, */
/* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
/* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
if( tif->tif_rawdatasize <= (tmsize_t) td->td_stripbytecount[tile] )
{
if( !(TIFFWriteBufferSetup(tif, NULL,
(tmsize_t)TIFFroundup_64((uint64)(td->td_stripbytecount[tile] + 1), 1024))) )
return ((tmsize_t)(-1));
}
/* Force TIFFAppendToStrip() to consider placing data at end
of file. */
tif->tif_curoff = 0;
if( !_TIFFReserveLargeEnoughWriteBuffer(tif, tile) ) {
return ((tmsize_t)(-1));
}
tif->tif_rawcc = 0;
@@ -535,22 +533,29 @@ TIFFSetupStrips(TIFF* tif)
isUnspecified(tif, FIELD_ROWSPERSTRIP) ?
td->td_samplesperpixel : TIFFNumberOfStrips(tif);
td->td_nstrips = td->td_stripsperimage;
/* TIFFWriteDirectoryTagData has a limitation to 0x80000000U bytes */
if( td->td_nstrips >= 0x80000000U / ((tif->tif_flags&TIFF_BIGTIFF)?0x8U:0x4U) )
{
TIFFErrorExt(tif->tif_clientdata, "TIFFSetupStrips",
"Too large Strip/Tile Offsets/ByteCounts arrays");
return 0;
}
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
td->td_stripsperimage /= td->td_samplesperpixel;
td->td_stripoffset = (uint64 *)
td->td_stripoffset_p = (uint64 *)
_TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64),
"for \"StripOffsets\" array");
td->td_stripbytecount = (uint64 *)
td->td_stripbytecount_p = (uint64 *)
_TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64),
"for \"StripByteCounts\" array");
if (td->td_stripoffset == NULL || td->td_stripbytecount == NULL)
if (td->td_stripoffset_p == NULL || td->td_stripbytecount_p == NULL)
return (0);
/*
* Place data at the end-of-file
* (by setting offsets to zero).
*/
_TIFFmemset(td->td_stripoffset, 0, td->td_nstrips*sizeof (uint64));
_TIFFmemset(td->td_stripbytecount, 0, td->td_nstrips*sizeof (uint64));
_TIFFmemset(td->td_stripoffset_p, 0, td->td_nstrips*sizeof (uint64));
_TIFFmemset(td->td_stripbytecount_p, 0, td->td_nstrips*sizeof (uint64));
TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
return (1);
@@ -572,7 +577,7 @@ TIFFWriteCheck(TIFF* tif, int tiles, const char* module)
}
if (tiles ^ isTiled(tif)) {
TIFFErrorExt(tif->tif_clientdata, module, tiles ?
"Can not write tiles to a stripped image" :
"Can not write tiles to a striped image" :
"Can not write scanlines to a tiled image");
return (0);
}
@@ -610,7 +615,7 @@ TIFFWriteCheck(TIFF* tif, int tiles, const char* module)
return (0);
}
}
if (tif->tif_dir.td_stripoffset == NULL && !TIFFSetupStrips(tif)) {
if (tif->tif_dir.td_stripoffset_p == NULL && !TIFFSetupStrips(tif)) {
tif->tif_dir.td_nstrips = 0;
TIFFErrorExt(tif->tif_clientdata, module, "No space for %s arrays",
isTiled(tif) ? "tile" : "strip");
@@ -628,6 +633,20 @@ TIFFWriteCheck(TIFF* tif, int tiles, const char* module)
if (tif->tif_scanlinesize == 0)
return (0);
tif->tif_flags |= TIFF_BEENWRITING;
if( tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 &&
tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 &&
tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 &&
!(tif->tif_flags & TIFF_DIRTYDIRECT) )
{
TIFFForceStrileArrayWriting(tif);
}
return (1);
}
@@ -649,6 +668,10 @@ TIFFWriteBufferSetup(TIFF* tif, void* bp, tmsize_t size)
if (size == (tmsize_t)(-1)) {
size = (isTiled(tif) ?
tif->tif_tilesize : TIFFStripSize(tif));
/* Adds 10% margin for cases where compression would expand a bit */
if( size < TIFF_TMSIZE_T_MAX - size / 10 )
size += size / 10;
/*
* Make raw data buffer at least 8K
*/
@@ -684,9 +707,9 @@ TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module)
uint64* new_stripbytecount;
assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
new_stripoffset = (uint64*)_TIFFrealloc(td->td_stripoffset,
new_stripoffset = (uint64*)_TIFFrealloc(td->td_stripoffset_p,
(td->td_nstrips + delta) * sizeof (uint64));
new_stripbytecount = (uint64*)_TIFFrealloc(td->td_stripbytecount,
new_stripbytecount = (uint64*)_TIFFrealloc(td->td_stripbytecount_p,
(td->td_nstrips + delta) * sizeof (uint64));
if (new_stripoffset == NULL || new_stripbytecount == NULL) {
if (new_stripoffset)
@@ -697,11 +720,11 @@ TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module)
TIFFErrorExt(tif->tif_clientdata, module, "No space to expand strip arrays");
return (0);
}
td->td_stripoffset = new_stripoffset;
td->td_stripbytecount = new_stripbytecount;
_TIFFmemset(td->td_stripoffset + td->td_nstrips,
td->td_stripoffset_p = new_stripoffset;
td->td_stripbytecount_p = new_stripbytecount;
_TIFFmemset(td->td_stripoffset_p + td->td_nstrips,
0, delta*sizeof (uint64));
_TIFFmemset(td->td_stripbytecount + td->td_nstrips,
_TIFFmemset(td->td_stripbytecount_p + td->td_nstrips,
0, delta*sizeof (uint64));
td->td_nstrips += delta;
tif->tif_flags |= TIFF_DIRTYDIRECT;
@@ -720,12 +743,12 @@ TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc)
uint64 m;
int64 old_byte_count = -1;
if (td->td_stripoffset[strip] == 0 || tif->tif_curoff == 0) {
if (td->td_stripoffset_p[strip] == 0 || tif->tif_curoff == 0) {
assert(td->td_nstrips > 0);
if( td->td_stripbytecount[strip] != 0
&& td->td_stripoffset[strip] != 0
&& td->td_stripbytecount[strip] >= (uint64) cc )
if( td->td_stripbytecount_p[strip] != 0
&& td->td_stripoffset_p[strip] != 0
&& td->td_stripbytecount_p[strip] >= (uint64) cc )
{
/*
* There is already tile data on disk, and the new tile
@@ -734,7 +757,7 @@ TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc)
* more data to append to this strip before we are done
* depending on how we are getting called.
*/
if (!SeekOK(tif, td->td_stripoffset[strip])) {
if (!SeekOK(tif, td->td_stripoffset_p[strip])) {
TIFFErrorExt(tif->tif_clientdata, module,
"Seek error at scanline %lu",
(unsigned long)tif->tif_row);
@@ -747,17 +770,17 @@ TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc)
* Seek to end of file, and set that as our location to
* write this strip.
*/
td->td_stripoffset[strip] = TIFFSeekFile(tif, 0, SEEK_END);
td->td_stripoffset_p[strip] = TIFFSeekFile(tif, 0, SEEK_END);
tif->tif_flags |= TIFF_DIRTYSTRIP;
}
tif->tif_curoff = td->td_stripoffset[strip];
tif->tif_curoff = td->td_stripoffset_p[strip];
/*
* We are starting a fresh strip/tile, so set the size to zero.
*/
old_byte_count = td->td_stripbytecount[strip];
td->td_stripbytecount[strip] = 0;
old_byte_count = td->td_stripbytecount_p[strip];
td->td_stripbytecount_p[strip] = 0;
}
m = tif->tif_curoff+cc;
@@ -774,9 +797,9 @@ TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc)
return (0);
}
tif->tif_curoff = m;
td->td_stripbytecount[strip] += cc;
td->td_stripbytecount_p[strip] += cc;
if( (int64) td->td_stripbytecount[strip] != old_byte_count )
if( (int64) td->td_stripbytecount_p[strip] != old_byte_count )
tif->tif_flags |= TIFF_DIRTYSTRIP;
return (1);
+262 -18
View File
@@ -29,24 +29,22 @@
*
* ZIP (aka Deflate) Compression Support
*
* This file is simply an interface to the zlib library written by
* This file is an interface to the zlib library written by
* Jean-loup Gailly and Mark Adler. You must use version 1.0 or later
* of the library: this code assumes the 1.0 API and also depends on
* the ability to write the zlib header multiple times (one per strip)
* which was not possible with versions prior to 0.95. Note also that
* older versions of this codec avoided this bug by suppressing the header
* entirely. This means that files written with the old library cannot
* be read; they should be converted to a different compression scheme
* and then reconverted.
* of the library.
*
* The data format used by the zlib library is described in the files
* zlib-3.1.doc, deflate-1.1.doc and gzip-4.1.doc, available in the
* directory ftp://ftp.uu.net/pub/archiving/zip/doc. The library was
* last found at ftp://ftp.uu.net/pub/archiving/zip/zlib/zlib-0.99.tar.gz.
* Optionally, libdeflate (https://github.com/ebiggers/libdeflate) may be used
* to do the compression and decompression, but only for whole strips and tiles.
* For scanline access, zlib will be sued as a fallback.
*/
#include "tif_predict.h"
#include "zlib.h"
#if LIBDEFLATE_SUPPORT
#include "libdeflate.h"
#endif
#define LIBDEFLATE_MAX_COMPRESSION_LEVEL 12
#include <stdio.h>
/*
@@ -70,6 +68,12 @@ typedef struct {
z_stream stream;
int zipquality; /* compression level */
int state; /* state flags */
int subcodec; /* DEFLATE_SUBCODEC_ZLIB or DEFLATE_SUBCODEC_LIBDEFLATE */
#if LIBDEFLATE_SUPPORT
int libdeflate_state; /* -1 = until first time ZIPEncode() / ZIPDecode() is called, 0 = use zlib, 1 = use libdeflate */
struct libdeflate_decompressor* libdeflate_dec;
struct libdeflate_compressor* libdeflate_enc;
#endif
#define ZSTATE_INIT_DECODE 0x01
#define ZSTATE_INIT_ENCODE 0x02
@@ -132,6 +136,9 @@ ZIPPreDecode(TIFF* tif, uint16 s)
if( (sp->state & ZSTATE_INIT_DECODE) == 0 )
tif->tif_setupdecode( tif );
#if LIBDEFLATE_SUPPORT
sp->libdeflate_state = -1;
#endif
sp->stream.next_in = tif->tif_rawdata;
assert(sizeof(sp->stream.avail_in)==4); /* if this assert gets raised,
we need to simplify this code to reflect a ZLib that is likely updated
@@ -151,6 +158,77 @@ ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
assert(sp != NULL);
assert(sp->state == ZSTATE_INIT_DECODE);
#if LIBDEFLATE_SUPPORT
if( sp->libdeflate_state == 1 )
return 0;
/* If we have libdeflate support and we are asked to read a whole */
/* strip/tile, then go for using it */
do {
TIFFDirectory *td = &tif->tif_dir;
if( sp->libdeflate_state == 0 )
break;
if( sp->subcodec == DEFLATE_SUBCODEC_ZLIB )
break;
/* Check if we are in the situation where we can use libdeflate */
if (isTiled(tif)) {
if( TIFFTileSize64(tif) != (uint64)occ )
break;
} else {
uint32 strip_height = td->td_imagelength - tif->tif_row;
if (strip_height > td->td_rowsperstrip)
strip_height = td->td_rowsperstrip;
if( TIFFVStripSize64(tif, strip_height) != (uint64)occ )
break;
}
/* Check for overflow */
if( (size_t)tif->tif_rawcc != (uint64)tif->tif_rawcc )
break;
if( (size_t)occ != (uint64)occ )
break;
/* Go for decompression using libdeflate */
{
enum libdeflate_result res;
if( sp->libdeflate_dec == NULL )
{
sp->libdeflate_dec = libdeflate_alloc_decompressor();
if( sp->libdeflate_dec == NULL )
{
break;
}
}
sp->libdeflate_state = 1;
res = libdeflate_zlib_decompress(
sp->libdeflate_dec, tif->tif_rawcp, (size_t)tif->tif_rawcc, op, (size_t)occ, NULL);
tif->tif_rawcp += tif->tif_rawcc;
tif->tif_rawcc = 0;
/* We accept LIBDEFLATE_INSUFFICIENT_SPACE has a return */
/* There are odd files in the wild where the last strip, when */
/* it is smaller in height than td_rowsperstrip, actually contains */
/* data for td_rowsperstrip lines. Just ignore that silently. */
if( res != LIBDEFLATE_SUCCESS &&
res != LIBDEFLATE_INSUFFICIENT_SPACE )
{
TIFFErrorExt(tif->tif_clientdata, module,
"Decoding error at scanline %lu",
(unsigned long) tif->tif_row);
return 0;
}
return 1;
}
} while(0);
sp->libdeflate_state = 0;
#endif /* LIBDEFLATE_SUPPORT */
sp->stream.next_in = tif->tif_rawcp;
sp->stream.next_out = op;
@@ -198,6 +276,7 @@ ZIPSetupEncode(TIFF* tif)
{
static const char module[] = "ZIPSetupEncode";
ZIPState* sp = EncoderState(tif);
int cappedQuality;
assert(sp != NULL);
if (sp->state & ZSTATE_INIT_DECODE) {
@@ -205,7 +284,11 @@ ZIPSetupEncode(TIFF* tif)
sp->state = 0;
}
if (deflateInit(&sp->stream, sp->zipquality) != Z_OK) {
cappedQuality = sp->zipquality;
if( cappedQuality > Z_BEST_COMPRESSION )
cappedQuality = Z_BEST_COMPRESSION;
if (deflateInit(&sp->stream, cappedQuality) != Z_OK) {
TIFFErrorExt(tif->tif_clientdata, module, "%s", SAFE_MSG(sp));
return (0);
} else {
@@ -227,6 +310,9 @@ ZIPPreEncode(TIFF* tif, uint16 s)
if( sp->state != ZSTATE_INIT_ENCODE )
tif->tif_setupencode( tif );
#if LIBDEFLATE_SUPPORT
sp->libdeflate_state = -1;
#endif
sp->stream.next_out = tif->tif_rawdata;
assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised,
we need to simplify this code to reflect a ZLib that is likely updated
@@ -249,6 +335,95 @@ ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
assert(sp->state == ZSTATE_INIT_ENCODE);
(void) s;
#if LIBDEFLATE_SUPPORT
if( sp->libdeflate_state == 1 )
return 0;
/* If we have libdeflate support and we are asked to write a whole */
/* strip/tile, then go for using it */
do {
TIFFDirectory *td = &tif->tif_dir;
if( sp->libdeflate_state == 0 )
break;
if( sp->subcodec == DEFLATE_SUBCODEC_ZLIB )
break;
/* Libdeflate does not support the 0-compression level */
if( sp->zipquality == Z_NO_COMPRESSION )
break;
/* Check if we are in the situation where we can use libdeflate */
if (isTiled(tif)) {
if( TIFFTileSize64(tif) != (uint64)cc )
break;
} else {
uint32 strip_height = td->td_imagelength - tif->tif_row;
if (strip_height > td->td_rowsperstrip)
strip_height = td->td_rowsperstrip;
if( TIFFVStripSize64(tif, strip_height) != (uint64)cc )
break;
}
/* Check for overflow */
if( (size_t)tif->tif_rawdatasize != (uint64)tif->tif_rawdatasize )
break;
if( (size_t)cc != (uint64)cc )
break;
/* Go for compression using libdeflate */
{
size_t nCompressedBytes;
if( sp->libdeflate_enc == NULL )
{
/* To get results as good as zlib, we asked for an extra */
/* level of compression */
sp->libdeflate_enc = libdeflate_alloc_compressor(
sp->zipquality == Z_DEFAULT_COMPRESSION ? 7 :
sp->zipquality >= 6 && sp->zipquality <= 9 ? sp->zipquality + 1 :
sp->zipquality);
if( sp->libdeflate_enc == NULL )
{
TIFFErrorExt(tif->tif_clientdata, module,
"Cannot allocate compressor");
break;
}
}
/* Make sure the output buffer is large enough for the worse case. */
/* In TIFFWriteBufferSetup(), when libtiff allocates the buffer */
/* we've taken a 10% margin over the uncompressed size, which should */
/* be large enough even for the the worse case scenario. */
if( libdeflate_zlib_compress_bound(sp->libdeflate_enc, (size_t)cc) >
(size_t)tif->tif_rawdatasize)
{
break;
}
sp->libdeflate_state = 1;
nCompressedBytes = libdeflate_zlib_compress(
sp->libdeflate_enc, bp, (size_t)cc, tif->tif_rawdata, (size_t)tif->tif_rawdatasize);
if( nCompressedBytes == 0 )
{
TIFFErrorExt(tif->tif_clientdata, module,
"Encoder error at scanline %lu",
(unsigned long) tif->tif_row);
return 0;
}
tif->tif_rawcc = nCompressedBytes;
if( !TIFFFlushData1(tif) )
return 0;
return 1;
}
} while(0);
sp->libdeflate_state = 0;
#endif /* LIBDEFLATE_SUPPORT */
sp->stream.next_in = bp;
assert(sizeof(sp->stream.avail_in)==4); /* if this assert gets raised,
we need to simplify this code to reflect a ZLib that is likely updated
@@ -265,7 +440,8 @@ ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
}
if (sp->stream.avail_out == 0) {
tif->tif_rawcc = tif->tif_rawdatasize;
TIFFFlushData1(tif);
if (!TIFFFlushData1(tif))
return 0;
sp->stream.next_out = tif->tif_rawdata;
sp->stream.avail_out = (uint64)tif->tif_rawdatasize <= 0xFFFFFFFFU ? (uInt)tif->tif_rawdatasize : 0xFFFFFFFFU;
}
@@ -285,6 +461,11 @@ ZIPPostEncode(TIFF* tif)
ZIPState *sp = EncoderState(tif);
int state;
#if LIBDEFLATE_SUPPORT
if( sp->libdeflate_state == 1 )
return 1;
#endif
sp->stream.avail_in = 0;
do {
state = deflate(&sp->stream, Z_FINISH);
@@ -294,7 +475,8 @@ ZIPPostEncode(TIFF* tif)
if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
{
tif->tif_rawcc = tif->tif_rawdatasize - sp->stream.avail_out;
TIFFFlushData1(tif);
if (!TIFFFlushData1(tif))
return 0;
sp->stream.next_out = tif->tif_rawdata;
sp->stream.avail_out = (uint64)tif->tif_rawdatasize <= 0xFFFFFFFFU ? (uInt)tif->tif_rawdatasize : 0xFFFFFFFFU;
}
@@ -327,6 +509,14 @@ ZIPCleanup(TIFF* tif)
inflateEnd(&sp->stream);
sp->state = 0;
}
#if LIBDEFLATE_SUPPORT
if( sp->libdeflate_dec )
libdeflate_free_decompressor(sp->libdeflate_dec);
if( sp->libdeflate_enc )
libdeflate_free_compressor(sp->libdeflate_enc);
#endif
_TIFFfree(sp);
tif->tif_data = NULL;
@@ -342,15 +532,55 @@ ZIPVSetField(TIFF* tif, uint32 tag, va_list ap)
switch (tag) {
case TIFFTAG_ZIPQUALITY:
sp->zipquality = (int) va_arg(ap, int);
if ( sp->state&ZSTATE_INIT_ENCODE ) {
if( sp->zipquality < Z_DEFAULT_COMPRESSION ||
sp->zipquality > LIBDEFLATE_MAX_COMPRESSION_LEVEL ) {
TIFFErrorExt(tif->tif_clientdata, module,
"Invalid ZipQuality value. Should be in [-1,%d] range",
LIBDEFLATE_MAX_COMPRESSION_LEVEL);
return 0;
}
if ( sp->state&ZSTATE_INIT_ENCODE ) {
int cappedQuality = sp->zipquality;
if( cappedQuality > Z_BEST_COMPRESSION )
cappedQuality = Z_BEST_COMPRESSION;
if (deflateParams(&sp->stream,
sp->zipquality, Z_DEFAULT_STRATEGY) != Z_OK) {
cappedQuality, Z_DEFAULT_STRATEGY) != Z_OK) {
TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
SAFE_MSG(sp));
return (0);
}
}
#if LIBDEFLATE_SUPPORT
if( sp->libdeflate_enc )
{
libdeflate_free_compressor(sp->libdeflate_enc);
sp->libdeflate_enc = NULL;
}
#endif
return (1);
case TIFFTAG_DEFLATE_SUBCODEC:
sp->subcodec = (int) va_arg(ap, int);
if( sp->subcodec != DEFLATE_SUBCODEC_ZLIB &&
sp->subcodec != DEFLATE_SUBCODEC_LIBDEFLATE )
{
TIFFErrorExt(tif->tif_clientdata, module,
"Invalid DeflateCodec value.");
return 0;
}
#if !LIBDEFLATE_SUPPORT
if( sp->subcodec == DEFLATE_SUBCODEC_LIBDEFLATE )
{
TIFFErrorExt(tif->tif_clientdata, module,
"DeflateCodec = DEFLATE_SUBCODEC_LIBDEFLATE unsupported in this build");
return 0;
}
#endif
return 1;
default:
return (*sp->vsetparent)(tif, tag, ap);
}
@@ -366,6 +596,11 @@ ZIPVGetField(TIFF* tif, uint32 tag, va_list ap)
case TIFFTAG_ZIPQUALITY:
*va_arg(ap, int*) = sp->zipquality;
break;
case TIFFTAG_DEFLATE_SUBCODEC:
*va_arg(ap, int*) = sp->subcodec;
break;
default:
return (*sp->vgetparent)(tif, tag, ap);
}
@@ -374,6 +609,7 @@ ZIPVGetField(TIFF* tif, uint32 tag, va_list ap)
static const TIFFField zipFields[] = {
{ TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL },
{ TIFFTAG_DEFLATE_SUBCODEC, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL },
};
int
@@ -384,6 +620,9 @@ TIFFInitZIP(TIFF* tif, int scheme)
assert( (scheme == COMPRESSION_DEFLATE)
|| (scheme == COMPRESSION_ADOBE_DEFLATE));
#ifdef NDEBUG
(void)scheme;
#endif
/*
* Merge codec-specific tag information.
@@ -397,7 +636,7 @@ TIFFInitZIP(TIFF* tif, int scheme)
/*
* Allocate state block so tag methods have storage to record values.
*/
tif->tif_data = (uint8*) _TIFFmalloc(sizeof (ZIPState));
tif->tif_data = (uint8*) _TIFFcalloc(sizeof (ZIPState), 1);
if (tif->tif_data == NULL)
goto bad;
sp = ZState(tif);
@@ -417,6 +656,11 @@ TIFFInitZIP(TIFF* tif, int scheme)
/* Default values for codec-specific fields */
sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */
sp->state = 0;
#if LIBDEFLATE_SUPPORT
sp->subcodec = DEFLATE_SUBCODEC_LIBDEFLATE;
#else
sp->subcodec = DEFLATE_SUBCODEC_ZLIB;
#endif
/*
* Install codec methods.
+4 -2
View File
@@ -260,7 +260,8 @@ ZSTDEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
}
if( sp->out_buffer.pos == sp->out_buffer.size ) {
tif->tif_rawcc = tif->tif_rawdatasize;
TIFFFlushData1(tif);
if (!TIFFFlushData1(tif))
return 0;
sp->out_buffer.dst = tif->tif_rawcp;
sp->out_buffer.pos = 0;
}
@@ -289,7 +290,8 @@ ZSTDPostEncode(TIFF* tif)
}
if( sp->out_buffer.pos > 0 ) {
tif->tif_rawcc = sp->out_buffer.pos;
TIFFFlushData1(tif);
if (!TIFFFlushData1(tif))
return 0;
sp->out_buffer.dst = tif->tif_rawcp;
sp->out_buffer.pos = 0;
}
+111 -6
View File
@@ -119,6 +119,11 @@ typedef struct {
* Tag data type information.
*
* Note: RATIONALs are the ratio of two 32-bit integer values.
*--:
* Note2: TIFF_IFD8 data type is used in tiffFields[]-tag definition in order to distinguish the write-handling
of those tags between ClassicTIFF and BigTiff:
For ClassicTIFF libtiff writes a 32-bit value and the TIFF_IFD type-id into the file
For BigTIFF libtiff writes a 64-bit value and the TIFF_IFD8 type-id into the file
*/
typedef enum {
TIFF_NOTYPE = 0, /* placeholder */
@@ -375,6 +380,7 @@ typedef enum {
January 2004 */
#define TIFFTAG_OPIIMAGEID 32781 /* %OPI ImageID
[Adobe TIFF technote] */
#define TIFFTAG_TIFFANNOTATIONDATA 32932 /* http://web.archive.org/web/20050309141348/http://www.kofile.com/support%20pro/faqs/annospec.htm */
/* tags 32952-32956 are private tags registered to Island Graphics */
#define TIFFTAG_REFPTS 32953 /* image reference points */
#define TIFFTAG_REGIONTACKPOINT 32954 /* region-xform tack point */
@@ -409,8 +415,23 @@ typedef enum {
#define TIFFTAG_CFAPATTERN 33422 /* color filter array pattern */
/* tag 33432 is listed in the 6.0 spec w/ unknown ownership */
#define TIFFTAG_COPYRIGHT 33432 /* copyright string */
/* Tags 33445-33452 are used for GEL fileformat, see
* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf
*/
#define TIFFTAG_MD_FILETAG 33445 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */
#define TIFFTAG_MD_SCALEPIXEL 33446 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */
#define TIFFTAG_MD_COLORTABLE 33447 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */
#define TIFFTAG_MD_LABNAME 33448 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */
#define TIFFTAG_MD_SAMPLEINFO 33449 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */
#define TIFFTAG_MD_PREPDATE 33450 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */
#define TIFFTAG_MD_PREPTIME 33451 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */
#define TIFFTAG_MD_FILEUNITS 33452 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */
/* IPTC TAG from RichTIFF specifications */
#define TIFFTAG_RICHTIFFIPTC 33723
#define TIFFTAG_INGR_PACKET_DATA_TAG 33918 /* Intergraph Application specific storage. */
#define TIFFTAG_INGR_FLAG_REGISTERS 33919 /* Intergraph Application specific flags. */
#define TIFFTAG_IRASB_TRANSORMATION_MATRIX 33920 /* Originally part of Intergraph's GeoTIFF tags, but likely understood by IrasB only. */
#define TIFFTAG_MODELTIEPOINTTAG 33922 /* GeoTIFF */
/* 34016-34029 are reserved for ANSI IT8 TIFF/IT <dkelly@apago.com) */
#define TIFFTAG_IT8SITE 34016 /* site name */
#define TIFFTAG_IT8COLORSEQUENCE 34017 /* color seq. [RGB,CMYK,etc] */
@@ -432,6 +453,7 @@ typedef enum {
#define TIFFTAG_IT8CMYKEQUIVALENT 34032 /* CMYK color equivalents */
/* tags 34232-34236 are private tags registered to Texas Instruments */
#define TIFFTAG_FRAMECOUNT 34232 /* Sequence Frame Count */
#define TIFFTAG_MODELTRANSFORMATIONTAG 34264 /* Used in interchangeable GeoTIFF files */
/* tag 34377 is private tag registered to Adobe for PhotoShop */
#define TIFFTAG_PHOTOSHOP 34377
/* tags 34665, 34853 and 40965 are documented in EXIF specification */
@@ -451,7 +473,15 @@ typedef enum {
#define TIFFTAG_STONITS 37439 /* Sample value to Nits */
/* tag 34929 is a private tag registered to FedEx */
#define TIFFTAG_FEDEX_EDR 34929 /* unknown use */
#define TIFFTAG_IMAGESOURCEDATA 37724 /* http://justsolve.archiveteam.org/wiki/PSD, http://www.adobe.com/devnet-apps/photoshop/fileformatashtml/ */
#define TIFFTAG_INTEROPERABILITYIFD 40965 /* Pointer to Interoperability private directory */
#define TIFFTAG_GDAL_METADATA 42112 /* Used by the GDAL library */
#define TIFFTAG_GDAL_NODATA 42113 /* Used by the GDAL library */
#define TIFFTAG_OCE_SCANJOB_DESCRIPTION 50215 /* Used in the Oce scanning process */
#define TIFFTAG_OCE_APPLICATION_SELECTOR 50216 /* Used in the Oce scanning process. */
#define TIFFTAG_OCE_IDENTIFICATION_NUMBER 50217
#define TIFFTAG_OCE_IMAGELOGIC_CHARACTERISTICS 50218
/* tags 50674 to 50677 are reserved for ESRI */
#define TIFFTAG_LERC_PARAMETERS 50674 /* Stores LERC version and additional compression method */
/* Adobe Digital Negative (DNG) format tags */
@@ -535,6 +565,17 @@ typedef enum {
into ICC profile space */
#define TIFFTAG_CURRENTICCPROFILE 50833 /* & */
#define TIFFTAG_CURRENTPREPROFILEMATRIX 50834 /* & */
#define TIFFTAG_RPCCOEFFICIENT 50844 /* Define by GDAL for geospatial georeferencing through RPC: http://geotiff.maptools.org/rpc_prop.html */
#define TIFFTAG_ALIAS_LAYER_METADATA 50784 /* Alias Sketchbook Pro layer usage description. */
/* GeoTIFF DGIWG */
#define TIFFTAG_TIFF_RSID 50908 /* https://www.awaresystems.be/imaging/tiff/tifftags/tiff_rsid.html */
#define TIFFTAG_GEO_METADATA 50909 /* https://www.awaresystems.be/imaging/tiff/tifftags/geo_metadata.html */
#define TIFFTAG_EXTRACAMERAPROFILES 50933 /* http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/products/photoshop/pdfs/dng_spec_1.4.0.0.pdf */
/* tag 65535 is an undefined tag used by Eastman Kodak */
#define TIFFTAG_DCSHUESHIFTVALUES 65535 /* hue shift correction data */
@@ -615,8 +656,11 @@ typedef enum {
#define LERC_ADD_COMPRESSION_DEFLATE 1
#define LERC_ADD_COMPRESSION_ZSTD 2
#define TIFFTAG_LERC_MAXZERROR 65567 /* LERC maximum error */
#define TIFFTAG_WEBP_LEVEL 65568 /* WebP compression level: WARNING not registered in Adobe-maintained registry */
#define TIFFTAG_WEBP_LOSSLESS 65569 /* WebP lossless/lossy : WARNING not registered in Adobe-maintained registry */
#define TIFFTAG_WEBP_LEVEL 65568 /* WebP compression level */
#define TIFFTAG_WEBP_LOSSLESS 65569 /* WebP lossless/lossy */
#define TIFFTAG_DEFLATE_SUBCODEC 65570 /* ZIP codec: to get/set the sub-codec to use. Will default to libdeflate when available */
#define DEFLATE_SUBCODEC_ZLIB 0
#define DEFLATE_SUBCODEC_LIBDEFLATE 1
/*
* EXIF tags
@@ -626,8 +670,8 @@ typedef enum {
#define EXIFTAG_EXPOSUREPROGRAM 34850 /* Exposure program */
#define EXIFTAG_SPECTRALSENSITIVITY 34852 /* Spectral sensitivity */
#define EXIFTAG_ISOSPEEDRATINGS 34855 /* ISO speed rating */
#define EXIFTAG_OECF 34856 /* Optoelectric conversion
factor */
#define EXIFTAG_PHOTOGRAPHICSENSITIVITY 34855 /* Photographic Sensitivity (new name for tag 34855) */
#define EXIFTAG_OECF 34856 /* Optoelectric conversion factor */
#define EXIFTAG_EXIFVERSION 36864 /* Exif version */
#define EXIFTAG_DATETIMEORIGINAL 36867 /* Date and time of original
data generation */
@@ -679,10 +723,71 @@ typedef enum {
#define EXIFTAG_SHARPNESS 41994 /* Sharpness */
#define EXIFTAG_DEVICESETTINGDESCRIPTION 41995 /* Device settings description */
#define EXIFTAG_SUBJECTDISTANCERANGE 41996 /* Subject distance range */
#define EXIFTAG_GAINCONTROL 41991 /* Gain control */
#define EXIFTAG_GAINCONTROL 41991 /* Gain control */
#define EXIFTAG_IMAGEUNIQUEID 42016 /* Unique image ID */
/*--: New for EXIF-Version 2.32, May 2019 ... */
#define EXIFTAG_SENSITIVITYTYPE 34864 /* The SensitivityType tag indicates which one of the parameters of ISO12232 is the PhotographicSensitivity tag. */
#define EXIFTAG_STANDARDOUTPUTSENSITIVITY 34865 /* This tag indicates the standard output sensitivity value of a camera or input device defined in ISO 12232. */
#define EXIFTAG_RECOMMENDEDEXPOSUREINDEX 34866 /* recommended exposure index */
#define EXIFTAG_ISOSPEED 34867 /* ISO speed value */
#define EXIFTAG_ISOSPEEDLATITUDEYYY 34868 /* ISO speed latitude yyy */
#define EXIFTAG_ISOSPEEDLATITUDEZZZ 34869 /* ISO speed latitude zzz */
#define EXIFTAG_OFFSETTIME 36880 /* offset from UTC of the time of DateTime tag. */
#define EXIFTAG_OFFSETTIMEORIGINAL 36881 /* offset from UTC of the time of DateTimeOriginal tag. */
#define EXIFTAG_OFFSETTIMEDIGITIZED 36882 /* offset from UTC of the time of DateTimeDigitized tag. */
#define EXIFTAG_TEMPERATURE 37888 /* Temperature as the ambient situation at the shot in dergee Celsius */
#define EXIFTAG_HUMIDITY 37889 /* Humidity as the ambient situation at the shot in percent */
#define EXIFTAG_PRESSURE 37890 /* Pressure as the ambient situation at the shot hecto-Pascal (hPa) */
#define EXIFTAG_WATERDEPTH 37891 /* WaterDepth as the ambient situation at the shot in meter (m) */
#define EXIFTAG_ACCELERATION 37892 /* Acceleration (a scalar regardless of direction) as the ambient situation at the shot in units of mGal (10-5 m/s^2) */
#define EXIFTAG_CAMERAELEVATIONANGLE 37893 /* Elevation/depression. angle of the orientation of the camera(imaging optical axis) as the ambient situation at the shot in degree from -180deg to +180deg. */
#define EXIFTAG_CAMERAOWNERNAME 42032 /* owner of a camera */
#define EXIFTAG_BODYSERIALNUMBER 42033 /* serial number of the body of the camera */
#define EXIFTAG_LENSSPECIFICATION 42034 /* minimum focal length (in mm), maximum focal length (in mm), minimum F number in the minimum focal length, and minimum F number in the maximum focal length, */
#define EXIFTAG_LENSMAKE 42035 /* the lens manufacturer */
#define EXIFTAG_LENSMODEL 42036 /* the lens model name and model number */
#define EXIFTAG_LENSSERIALNUMBER 42037 /* the serial number of the interchangeable lens */
#define EXIFTAG_GAMMA 42240 /* value of coefficient gamma */
#define EXIFTAG_COMPOSITEIMAGE 42080 /* composite image */
#define EXIFTAG_SOURCEIMAGENUMBEROFCOMPOSITEIMAGE 42081 /* source image number of composite image */
#define EXIFTAG_SOURCEEXPOSURETIMESOFCOMPOSITEIMAGE 42082 /* source exposure times of composite image */
/*
* EXIF-GPS tags (Version 2.31, July 2016)
*/
#define GPSTAG_VERSIONID 0 /* Indicates the version of GPSInfoIFD. */
#define GPSTAG_LATITUDEREF 1 /* Indicates whether the latitude is north or south latitude. */
#define GPSTAG_LATITUDE 2 /* Indicates the latitude. */
#define GPSTAG_LONGITUDEREF 3 /* Indicates whether the longitude is east or west longitude. */
#define GPSTAG_LONGITUDE 4 /* Indicates the longitude. */
#define GPSTAG_ALTITUDEREF 5 /* Indicates the altitude used as the reference altitude. */
#define GPSTAG_ALTITUDE 6 /* Indicates the altitude based on the reference in GPSAltitudeRef. */
#define GPSTAG_TIMESTAMP 7 /* Indicates the time as UTC (Coordinated Universal Time). */
#define GPSTAG_SATELLITES 8 /* Indicates the GPS satellites used for measurements. */
#define GPSTAG_STATUS 9 /* Indicates the status of the GPS receiver when the image is recorded. */
#define GPSTAG_MEASUREMODE 10 /* Indicates the GPS measurement mode. */
#define GPSTAG_DOP 11 /* Indicates the GPS DOP (data degree of precision). */
#define GPSTAG_SPEEDREF 12 /* Indicates the unit used to express the GPS receiver speed of movement. */
#define GPSTAG_SPEED 13 /* Indicates the speed of GPS receiver movement. */
#define GPSTAG_TRACKREF 14 /* Indicates the reference for giving the direction of GPS receiver movement. */
#define GPSTAG_TRACK 15 /* Indicates the direction of GPS receiver movement. */
#define GPSTAG_IMGDIRECTIONREF 16 /* Indicates the reference for giving the direction of the image when it is captured. */
#define GPSTAG_IMGDIRECTION 17 /* Indicates the direction of the image when it was captured. */
#define GPSTAG_MAPDATUM 18 /* Indicates the geodetic survey data used by the GPS receiver. (e.g. WGS-84) */
#define GPSTAG_DESTLATITUDEREF 19 /* Indicates whether the latitude of the destination point is north or south latitude. */
#define GPSTAG_DESTLATITUDE 20 /* Indicates the latitude of the destination point. */
#define GPSTAG_DESTLONGITUDEREF 21 /* Indicates whether the longitude of the destination point is east or west longitude. */
#define GPSTAG_DESTLONGITUDE 22 /* Indicates the longitude of the destination point. */
#define GPSTAG_DESTBEARINGREF 23 /* Indicates the reference used for giving the bearing to the destination point. */
#define GPSTAG_DESTBEARING 24 /* Indicates the bearing to the destination point. */
#define GPSTAG_DESTDISTANCEREF 25 /* Indicates the unit used to express the distance to the destination point. */
#define GPSTAG_DESTDISTANCE 26 /* Indicates the distance to the destination point. */
#define GPSTAG_PROCESSINGMETHOD 27 /* A character string recording the name of the method used for location finding. */
#define GPSTAG_AREAINFORMATION 28 /* A character string recording the name of the GPS area. */
#define GPSTAG_DATESTAMP 29 /* A character string recording date and time information relative to UTC (Coordinated Universal Time). */
#define GPSTAG_DIFFERENTIAL 30 /* Indicates whether differential correction is applied to the GPS receiver. */
#define GPSTAG_GPSHPOSITIONINGERROR 31 /* Indicates horizontal positioning errors in meters. */
#endif /* _TIFF_ */
/* vim: set ts=8 sts=8 sw=8 noet: */
+3
View File
@@ -87,6 +87,9 @@
/* Support Deflate compression */
#cmakedefine ZIP_SUPPORT 1
/* Support libdeflate enhanced compression */
#cmakedefine LIBDEFLATE_SUPPORT 1
/* Support strip chopping (whether or not to convert single-strip uncompressed
images to mutiple strips of ~8Kb to reduce memory usage) */
#cmakedefine STRIPCHOP_DEFAULT 1
+20 -6
View File
@@ -261,8 +261,10 @@ typedef struct {
#define LOGLUV_PUBLIC 1
#endif
#if !defined(__GNUC__) && !defined(__attribute__)
# define __attribute__(x) /*nothing*/
#if defined(__GNUC__) || defined(__attribute__)
# define TIFF_ATTRIBUTE(x) __attribute__(x)
#else
# define TIFF_ATTRIBUTE(x) /*nothing*/
#endif
#if defined(c_plusplus) || defined(__cplusplus)
@@ -350,6 +352,7 @@ extern int TIFFVGetFieldDefaulted(TIFF* tif, uint32 tag, va_list ap);
extern int TIFFReadDirectory(TIFF* tif);
extern int TIFFReadCustomDirectory(TIFF* tif, toff_t diroff, const TIFFFieldArray* infoarray);
extern int TIFFReadEXIFDirectory(TIFF* tif, toff_t diroff);
extern int TIFFReadGPSDirectory(TIFF* tif, toff_t diroff);
extern uint64 TIFFScanlineSize64(TIFF* tif);
extern tmsize_t TIFFScanlineSize(TIFF* tif);
extern uint64 TIFFRasterScanlineSize64(TIFF* tif);
@@ -400,6 +403,7 @@ extern void TIFFFreeDirectory(TIFF*);
extern int TIFFCreateDirectory(TIFF*);
extern int TIFFCreateCustomDirectory(TIFF*,const TIFFFieldArray*);
extern int TIFFCreateEXIFDirectory(TIFF*);
extern int TIFFCreateGPSDirectory(TIFF*);
extern int TIFFLastDirectory(TIFF*);
extern int TIFFSetDirectory(TIFF*, uint16);
extern int TIFFSetSubDirectory(TIFF*, uint64);
@@ -411,6 +415,8 @@ extern int TIFFWriteDirectory(TIFF *);
extern int TIFFWriteCustomDirectory(TIFF *, uint64 *);
extern int TIFFCheckpointDirectory(TIFF *);
extern int TIFFRewriteDirectory(TIFF *);
extern int TIFFDeferStrileArrayWriting(TIFF *);
extern int TIFFForceStrileArrayWriting(TIFF* );
#if defined(c_plusplus) || defined(__cplusplus)
extern void TIFFPrintDirectory(TIFF*, FILE*, long = 0);
@@ -448,10 +454,10 @@ extern TIFF* TIFFClientOpen(const char*, const char*,
TIFFMapFileProc, TIFFUnmapFileProc);
extern const char* TIFFFileName(TIFF*);
extern const char* TIFFSetFileName(TIFF*, const char *);
extern void TIFFError(const char*, const char*, ...) __attribute__((__format__ (__printf__,2,3)));
extern void TIFFErrorExt(thandle_t, const char*, const char*, ...) __attribute__((__format__ (__printf__,3,4)));
extern void TIFFWarning(const char*, const char*, ...) __attribute__((__format__ (__printf__,2,3)));
extern void TIFFWarningExt(thandle_t, const char*, const char*, ...) __attribute__((__format__ (__printf__,3,4)));
extern void TIFFError(const char*, const char*, ...) TIFF_ATTRIBUTE((__format__ (__printf__,2,3)));
extern void TIFFErrorExt(thandle_t, const char*, const char*, ...) TIFF_ATTRIBUTE((__format__ (__printf__,3,4)));
extern void TIFFWarning(const char*, const char*, ...) TIFF_ATTRIBUTE((__format__ (__printf__,2,3)));
extern void TIFFWarningExt(thandle_t, const char*, const char*, ...) TIFF_ATTRIBUTE((__format__ (__printf__,3,4)));
extern TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler);
extern TIFFErrorHandlerExt TIFFSetErrorHandlerExt(TIFFErrorHandlerExt);
extern TIFFErrorHandler TIFFSetWarningHandler(TIFFErrorHandler);
@@ -468,6 +474,9 @@ extern tmsize_t TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_
extern tmsize_t TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size);
extern tmsize_t TIFFReadEncodedTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size);
extern tmsize_t TIFFReadRawTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size);
extern int TIFFReadFromUserBuffer(TIFF* tif, uint32 strile,
void* inbuf, tmsize_t insize,
void* outbuf, tmsize_t outsize);
extern tmsize_t TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc);
extern tmsize_t TIFFWriteRawStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc);
extern tmsize_t TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc);
@@ -488,6 +497,11 @@ extern void TIFFSwabArrayOfDouble(double* dp, tmsize_t n);
extern void TIFFReverseBits(uint8* cp, tmsize_t n);
extern const unsigned char* TIFFGetBitRevTable(int);
extern uint64 TIFFGetStrileOffset(TIFF *tif, uint32 strile);
extern uint64 TIFFGetStrileByteCount(TIFF *tif, uint32 strile);
extern uint64 TIFFGetStrileOffsetWithErr(TIFF *tif, uint32 strile, int *pbErr);
extern uint64 TIFFGetStrileByteCountWithErr(TIFF *tif, uint32 strile, int *pbErr);
#ifdef LOGLUV_PUBLIC
#define U_NEU 0.210526316
#define V_NEU 0.473684211
+22 -1
View File
@@ -77,6 +77,19 @@ extern int snprintf(char* str, size_t size, const char* format, ...);
#define FALSE 0
#endif
#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0))
#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1)
/*
* Largest 32-bit unsigned integer value.
*/
#define TIFF_UINT32_MAX 0xFFFFFFFFU
/*
* Largest 64-bit unsigned integer value.
*/
#define TIFF_UINT64_MAX (((uint64)(TIFF_UINT32_MAX)) << 32 | TIFF_UINT32_MAX)
typedef struct client_info {
struct client_info *next;
void *data;
@@ -127,6 +140,9 @@ struct tiff {
#define TIFF_DIRTYSTRIP 0x200000U /* stripoffsets/stripbytecount dirty*/
#define TIFF_PERSAMPLE 0x400000U /* get/set per sample tags as arrays */
#define TIFF_BUFFERMMAP 0x800000U /* read buffer (tif_rawdata) points into mmap() memory */
#define TIFF_DEFERSTRILELOAD 0x1000000U /* defer strip/tile offset/bytecount array loading. */
#define TIFF_LAZYSTRILELOAD 0x2000000U /* lazy/ondemand loading of strip/tile offset/bytecount values. Only used if TIFF_DEFERSTRILELOAD is set and in read-only mode */
#define TIFF_CHOPPEDUPARRAYS 0x4000000U /* set when allocChoppedUpStripArrays() has modified strip array */
uint64 tif_diroff; /* file offset of current directory */
uint64 tif_nextdiroff; /* file offset of following directory */
uint64* tif_dirlist; /* list of offsets to already seen directories to prevent IFD looping */
@@ -258,7 +274,7 @@ struct tiff {
#define TIFFhowmany8_64(x) (((x)&0x07)?((uint64)(x)>>3)+1:(uint64)(x)>>3)
#define TIFFroundup_64(x, y) (TIFFhowmany_64(x,y)*(y))
/* Safe multiply which returns zero if there is an integer overflow */
/* Safe multiply which returns zero if there is an *unsigned* integer overflow. This macro is not safe for *signed* integer types */
#define TIFFSafeMultiply(t,v,m) ((((t)(m) != (t)0) && (((t)(((v)*(m))/(m))) == (t)(v))) ? (t)((v)*(m)) : (t)0)
#define TIFFmax(A,B) ((A)>(B)?(A):(B))
@@ -351,6 +367,9 @@ extern uint32 _TIFFDefaultStripSize(TIFF* tif, uint32 s);
extern void _TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th);
extern int _TIFFDataSize(TIFFDataType type);
/*--: Rational2Double: Return size of TIFFSetGetFieldType in bytes. */
extern int _TIFFSetGetFieldSize(TIFFSetGetFieldType setgettype);
extern void _TIFFsetByteArray(void**, void*, uint32);
extern void _TIFFsetString(char**, char*);
extern void _TIFFsetShortArray(uint16**, uint16*, uint32);
@@ -368,6 +387,8 @@ extern TIFFErrorHandlerExt _TIFFerrorHandlerExt;
extern uint32 _TIFFMultiply32(TIFF*, uint32, uint32, const char*);
extern uint64 _TIFFMultiply64(TIFF*, uint64, uint64, const char*);
extern tmsize_t _TIFFMultiplySSize(TIFF*, tmsize_t, tmsize_t, const char*);
extern tmsize_t _TIFFCastUInt64ToSSize(TIFF*, uint64, const char*);
extern void* _TIFFCheckMalloc(TIFF*, tmsize_t, tmsize_t, const char*);
extern void* _TIFFCheckRealloc(TIFF*, void*, tmsize_t, tmsize_t, const char*);
+2 -2
View File
@@ -1,4 +1,4 @@
#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.0.10\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc."
#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.2.0\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc."
/*
* This define can be used in code that requires
* compilation-related definitions specific to a
@@ -6,4 +6,4 @@
* version checking should be done based on the
* string returned by TIFFGetVersion.
*/
#define TIFFLIB_VERSION 20181110
#define TIFFLIB_VERSION 20201219
+24 -29
View File
@@ -25,21 +25,16 @@
static int EmitYUV(const VP8Io* const io, WebPDecParams* const p) {
WebPDecBuffer* output = p->output;
const WebPYUVABuffer* const buf = &output->u.YUVA;
uint8_t* const y_dst = buf->y + io->mb_y * buf->y_stride;
uint8_t* const u_dst = buf->u + (io->mb_y >> 1) * buf->u_stride;
uint8_t* const v_dst = buf->v + (io->mb_y >> 1) * buf->v_stride;
uint8_t* const y_dst = buf->y + (size_t)io->mb_y * buf->y_stride;
uint8_t* const u_dst = buf->u + (size_t)(io->mb_y >> 1) * buf->u_stride;
uint8_t* const v_dst = buf->v + (size_t)(io->mb_y >> 1) * buf->v_stride;
const int mb_w = io->mb_w;
const int mb_h = io->mb_h;
const int uv_w = (mb_w + 1) / 2;
const int uv_h = (mb_h + 1) / 2;
int j;
for (j = 0; j < mb_h; ++j) {
memcpy(y_dst + j * buf->y_stride, io->y + j * io->y_stride, mb_w);
}
for (j = 0; j < uv_h; ++j) {
memcpy(u_dst + j * buf->u_stride, io->u + j * io->uv_stride, uv_w);
memcpy(v_dst + j * buf->v_stride, io->v + j * io->uv_stride, uv_w);
}
WebPCopyPlane(io->y, io->y_stride, y_dst, buf->y_stride, mb_w, mb_h);
WebPCopyPlane(io->u, io->uv_stride, u_dst, buf->u_stride, uv_w, uv_h);
WebPCopyPlane(io->v, io->uv_stride, v_dst, buf->v_stride, uv_w, uv_h);
return io->mb_h;
}
@@ -47,7 +42,7 @@ static int EmitYUV(const VP8Io* const io, WebPDecParams* const p) {
static int EmitSampledRGB(const VP8Io* const io, WebPDecParams* const p) {
WebPDecBuffer* const output = p->output;
WebPRGBABuffer* const buf = &output->u.RGBA;
uint8_t* const dst = buf->rgba + io->mb_y * buf->stride;
uint8_t* const dst = buf->rgba + (size_t)io->mb_y * buf->stride;
WebPSamplerProcessPlane(io->y, io->y_stride,
io->u, io->v, io->uv_stride,
dst, buf->stride, io->mb_w, io->mb_h,
@@ -62,7 +57,7 @@ static int EmitSampledRGB(const VP8Io* const io, WebPDecParams* const p) {
static int EmitFancyRGB(const VP8Io* const io, WebPDecParams* const p) {
int num_lines_out = io->mb_h; // a priori guess
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
uint8_t* dst = buf->rgba + io->mb_y * buf->stride;
uint8_t* dst = buf->rgba + (size_t)io->mb_y * buf->stride;
WebPUpsampleLinePairFunc upsample = WebPUpsamplers[p->output->colorspace];
const uint8_t* cur_y = io->y;
const uint8_t* cur_u = io->u;
@@ -133,7 +128,7 @@ static int EmitAlphaYUV(const VP8Io* const io, WebPDecParams* const p,
const WebPYUVABuffer* const buf = &p->output->u.YUVA;
const int mb_w = io->mb_w;
const int mb_h = io->mb_h;
uint8_t* dst = buf->a + io->mb_y * buf->a_stride;
uint8_t* dst = buf->a + (size_t)io->mb_y * buf->a_stride;
int j;
(void)expected_num_lines_out;
assert(expected_num_lines_out == mb_h);
@@ -186,7 +181,7 @@ static int EmitAlphaRGB(const VP8Io* const io, WebPDecParams* const p,
(colorspace == MODE_ARGB || colorspace == MODE_Argb);
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
int num_rows;
const int start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
const size_t start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
uint8_t* const base_rgba = buf->rgba + start_y * buf->stride;
uint8_t* const dst = base_rgba + (alpha_first ? 0 : 3);
const int has_alpha = WebPDispatchAlpha(alpha, io->width, mb_w,
@@ -210,7 +205,7 @@ static int EmitAlphaRGBA4444(const VP8Io* const io, WebPDecParams* const p,
const WEBP_CSP_MODE colorspace = p->output->colorspace;
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
int num_rows;
const int start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
const size_t start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
uint8_t* const base_rgba = buf->rgba + start_y * buf->stride;
#if (WEBP_SWAP_16BIT_CSP == 1)
uint8_t* alpha_dst = base_rgba;
@@ -276,9 +271,9 @@ static int EmitRescaledYUV(const VP8Io* const io, WebPDecParams* const p) {
static int EmitRescaledAlphaYUV(const VP8Io* const io, WebPDecParams* const p,
int expected_num_lines_out) {
const WebPYUVABuffer* const buf = &p->output->u.YUVA;
uint8_t* const dst_a = buf->a + p->last_y * buf->a_stride;
uint8_t* const dst_a = buf->a + (size_t)p->last_y * buf->a_stride;
if (io->a != NULL) {
uint8_t* const dst_y = buf->y + p->last_y * buf->y_stride;
uint8_t* const dst_y = buf->y + (size_t)p->last_y * buf->y_stride;
const int num_lines_out = Rescale(io->a, io->width, io->mb_h, p->scaler_a);
assert(expected_num_lines_out == num_lines_out);
if (num_lines_out > 0) { // unmultiply the Y
@@ -356,7 +351,7 @@ static int ExportRGB(WebPDecParams* const p, int y_pos) {
const WebPYUV444Converter convert =
WebPYUV444Converters[p->output->colorspace];
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
uint8_t* dst = buf->rgba + y_pos * buf->stride;
uint8_t* dst = buf->rgba + (size_t)y_pos * buf->stride;
int num_lines_out = 0;
// For RGB rescaling, because of the YUV420, current scan position
// U/V can be +1/-1 line from the Y one. Hence the double test.
@@ -383,15 +378,15 @@ static int EmitRescaledRGB(const VP8Io* const io, WebPDecParams* const p) {
while (j < mb_h) {
const int y_lines_in =
WebPRescalerImport(p->scaler_y, mb_h - j,
io->y + j * io->y_stride, io->y_stride);
io->y + (size_t)j * io->y_stride, io->y_stride);
j += y_lines_in;
if (WebPRescaleNeededLines(p->scaler_u, uv_mb_h - uv_j)) {
const int u_lines_in =
WebPRescalerImport(p->scaler_u, uv_mb_h - uv_j,
io->u + uv_j * io->uv_stride, io->uv_stride);
const int v_lines_in =
WebPRescalerImport(p->scaler_v, uv_mb_h - uv_j,
io->v + uv_j * io->uv_stride, io->uv_stride);
const int u_lines_in = WebPRescalerImport(
p->scaler_u, uv_mb_h - uv_j, io->u + (size_t)uv_j * io->uv_stride,
io->uv_stride);
const int v_lines_in = WebPRescalerImport(
p->scaler_v, uv_mb_h - uv_j, io->v + (size_t)uv_j * io->uv_stride,
io->uv_stride);
(void)v_lines_in; // remove a gcc warning
assert(u_lines_in == v_lines_in);
uv_j += u_lines_in;
@@ -403,7 +398,7 @@ static int EmitRescaledRGB(const VP8Io* const io, WebPDecParams* const p) {
static int ExportAlpha(WebPDecParams* const p, int y_pos, int max_lines_out) {
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
uint8_t* const base_rgba = buf->rgba + y_pos * buf->stride;
uint8_t* const base_rgba = buf->rgba + (size_t)y_pos * buf->stride;
const WEBP_CSP_MODE colorspace = p->output->colorspace;
const int alpha_first =
(colorspace == MODE_ARGB || colorspace == MODE_Argb);
@@ -431,7 +426,7 @@ static int ExportAlpha(WebPDecParams* const p, int y_pos, int max_lines_out) {
static int ExportAlphaRGBA4444(WebPDecParams* const p, int y_pos,
int max_lines_out) {
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
uint8_t* const base_rgba = buf->rgba + y_pos * buf->stride;
uint8_t* const base_rgba = buf->rgba + (size_t)y_pos * buf->stride;
#if (WEBP_SWAP_16BIT_CSP == 1)
uint8_t* alpha_dst = base_rgba;
#else
@@ -470,7 +465,7 @@ static int EmitRescaledAlphaRGB(const VP8Io* const io, WebPDecParams* const p,
int lines_left = expected_num_out_lines;
const int y_end = p->last_y + lines_left;
while (lines_left > 0) {
const int row_offset = scaler->src_y - io->mb_y;
const int64_t row_offset = (int64_t)scaler->src_y - io->mb_y;
WebPRescalerImport(scaler, io->mb_h + io->mb_y - scaler->src_y,
io->a + row_offset * io->width, io->width);
lines_left -= p->emit_alpha_row(p, y_end - lines_left, lines_left);
+5 -7
View File
@@ -494,13 +494,11 @@ static int GetCoeffsAlt(VP8BitReader* const br,
return 16;
}
static WEBP_TSAN_IGNORE_FUNCTION void InitGetCoeffs(void) {
if (GetCoeffs == NULL) {
if (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kSlowSSSE3)) {
GetCoeffs = GetCoeffsAlt;
} else {
GetCoeffs = GetCoeffsFast;
}
WEBP_DSP_INIT_FUNC(InitGetCoeffs) {
if (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kSlowSSSE3)) {
GetCoeffs = GetCoeffsAlt;
} else {
GetCoeffs = GetCoeffsFast;
}
}
+1 -1
View File
@@ -31,7 +31,7 @@ extern "C" {
// version numbers
#define DEC_MAJ_VERSION 1
#define DEC_MIN_VERSION 1
#define DEC_MIN_VERSION 2
#define DEC_REV_VERSION 0
// YUV-cache parameters. Cache is 32-bytes wide (= one cacheline).
-1
View File
@@ -947,7 +947,6 @@ static WEBP_INLINE void CopyBlock8b(uint8_t* const dst, int dist, int length) {
break;
default:
goto Copy;
break;
}
CopySmallPattern8b(src, dst, length, pattern);
return;
+7 -4
View File
@@ -346,12 +346,15 @@ int WebPAnimDecoderGetNext(WebPAnimDecoder* dec,
{
const uint8_t* in = iter.fragment.bytes;
const size_t in_size = iter.fragment.size;
const size_t out_offset =
(iter.y_offset * width + iter.x_offset) * NUM_CHANNELS;
const uint32_t stride = width * NUM_CHANNELS; // at most 25 + 2 bits
const uint64_t out_offset = (uint64_t)iter.y_offset * stride +
(uint64_t)iter.x_offset * NUM_CHANNELS; // 53b
const uint64_t size = (uint64_t)iter.height * stride; // at most 25 + 27b
WebPDecoderConfig* const config = &dec->config_;
WebPRGBABuffer* const buf = &config->output.u.RGBA;
buf->stride = NUM_CHANNELS * width;
buf->size = buf->stride * iter.height;
if ((size_t)size != size) goto Error;
buf->stride = (int)stride;
buf->size = (size_t)size;
buf->rgba = dec->curr_frame_ + out_offset;
if (WebPDecode(in, in_size, config) != VP8_STATUS_OK) {
+6 -1
View File
@@ -24,7 +24,7 @@
#include "src/webp/format_constants.h"
#define DMUX_MAJ_VERSION 1
#define DMUX_MIN_VERSION 1
#define DMUX_MIN_VERSION 2
#define DMUX_REV_VERSION 0
typedef struct {
@@ -312,6 +312,7 @@ static ParseStatus ParseAnimationFrame(
int bits;
MemBuffer* const mem = &dmux->mem_;
Frame* frame;
size_t start_offset;
ParseStatus status =
NewFrame(mem, ANMF_CHUNK_SIZE, frame_chunk_size, &frame);
if (status != PARSE_OK) return status;
@@ -332,7 +333,11 @@ static ParseStatus ParseAnimationFrame(
// Store a frame only if the animation flag is set there is some data for
// this frame is available.
start_offset = mem->start_;
status = StoreFrame(dmux->num_frames_ + 1, anmf_payload_size, mem, frame);
if (status != PARSE_ERROR && mem->start_ - start_offset > anmf_payload_size) {
status = PARSE_ERROR;
}
if (status != PARSE_ERROR && is_animation && frame->frame_num_ > 0) {
added_frame = AddFrame(dmux, frame);
if (added_frame) {
+8
View File
@@ -359,6 +359,11 @@ static int HasAlpha32b_C(const uint8_t* src, int length) {
return 0;
}
static void AlphaReplace_C(uint32_t* src, int length, uint32_t color) {
int x;
for (x = 0; x < length; ++x) if ((src[x] >> 24) == 0) src[x] = color;
}
//------------------------------------------------------------------------------
// Simple channel manipulations.
@@ -400,6 +405,7 @@ void (*WebPPackRGB)(const uint8_t* r, const uint8_t* g, const uint8_t* b,
int (*WebPHasAlpha8b)(const uint8_t* src, int length);
int (*WebPHasAlpha32b)(const uint8_t* src, int length);
void (*WebPAlphaReplace)(uint32_t* src, int length, uint32_t color);
//------------------------------------------------------------------------------
// Init function
@@ -428,6 +434,7 @@ WEBP_DSP_INIT_FUNC(WebPInitAlphaProcessing) {
WebPHasAlpha8b = HasAlpha8b_C;
WebPHasAlpha32b = HasAlpha32b_C;
WebPAlphaReplace = AlphaReplace_C;
// If defined, use CPUInfo() to overwrite some pointers with faster versions.
if (VP8GetCPUInfo != NULL) {
@@ -469,4 +476,5 @@ WEBP_DSP_INIT_FUNC(WebPInitAlphaProcessing) {
assert(WebPPackRGB != NULL);
assert(WebPHasAlpha8b != NULL);
assert(WebPHasAlpha32b != NULL);
assert(WebPAlphaReplace != NULL);
}
+22
View File
@@ -265,6 +265,27 @@ static int HasAlpha32b_SSE2(const uint8_t* src, int length) {
return 0;
}
static void AlphaReplace_SSE2(uint32_t* src, int length, uint32_t color) {
const __m128i m_color = _mm_set1_epi32(color);
const __m128i zero = _mm_setzero_si128();
int i = 0;
for (; i + 8 <= length; i += 8) {
const __m128i a0 = _mm_loadu_si128((const __m128i*)(src + i + 0));
const __m128i a1 = _mm_loadu_si128((const __m128i*)(src + i + 4));
const __m128i b0 = _mm_srai_epi32(a0, 24);
const __m128i b1 = _mm_srai_epi32(a1, 24);
const __m128i c0 = _mm_cmpeq_epi32(b0, zero);
const __m128i c1 = _mm_cmpeq_epi32(b1, zero);
const __m128i d0 = _mm_and_si128(c0, m_color);
const __m128i d1 = _mm_and_si128(c1, m_color);
const __m128i e0 = _mm_andnot_si128(c0, a0);
const __m128i e1 = _mm_andnot_si128(c1, a1);
_mm_storeu_si128((__m128i*)(src + i + 0), _mm_or_si128(d0, e0));
_mm_storeu_si128((__m128i*)(src + i + 4), _mm_or_si128(d1, e1));
}
for (; i < length; ++i) if ((src[i] >> 24) == 0) src[i] = color;
}
// -----------------------------------------------------------------------------
// Apply alpha value to rows
@@ -334,6 +355,7 @@ WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessingSSE2(void) {
WebPHasAlpha8b = HasAlpha8b_SSE2;
WebPHasAlpha32b = HasAlpha32b_SSE2;
WebPAlphaReplace = AlphaReplace_SSE2;
}
#else // !WEBP_USE_SSE2
+34 -4
View File
@@ -55,12 +55,18 @@ static WEBP_INLINE void GetCPUInfo(int cpu_info[4], int info_type) {
: "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3])
: "a"(info_type), "c"(0));
}
#elif (defined(_M_X64) || defined(_M_IX86)) && \
defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 150030729 // >= VS2008 SP1
#elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86))
#if defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 150030729 // >= VS2008 SP1
#include <intrin.h>
#define GetCPUInfo(info, type) __cpuidex(info, type, 0) // set ecx=0
#elif defined(WEBP_MSC_SSE2)
#define WEBP_HAVE_MSC_CPUID
#elif _MSC_VER > 1310
#include <intrin.h>
#define GetCPUInfo __cpuid
#define WEBP_HAVE_MSC_CPUID
#endif
#endif
// NaCl has no support for xgetbv or the raw opcode.
@@ -94,7 +100,7 @@ static WEBP_INLINE uint64_t xgetbv(void) {
#define xgetbv() 0U // no AVX for older x64 or unrecognized toolchains.
#endif
#if defined(__i386__) || defined(__x86_64__) || defined(WEBP_MSC_SSE2)
#if defined(__i386__) || defined(__x86_64__) || defined(WEBP_HAVE_MSC_CPUID)
// helper function for run-time detection of slow SSSE3 platforms
static int CheckSlowModel(int info) {
@@ -179,6 +185,30 @@ static int AndroidCPUInfo(CPUFeature feature) {
return 0;
}
VP8CPUInfo VP8GetCPUInfo = AndroidCPUInfo;
#elif defined(EMSCRIPTEN) // also needs to be before generic NEON test
// Use compile flags as an indicator of SIMD support instead of a runtime check.
static int wasmCPUInfo(CPUFeature feature) {
switch (feature) {
#ifdef WEBP_USE_SSE2
case kSSE2:
return 1;
#endif
#ifdef WEBP_USE_SSE41
case kSSE3:
case kSlowSSSE3:
case kSSE4_1:
return 1;
#endif
#ifdef WEBP_USE_NEON
case kNEON:
return 1;
#endif
default:
break;
}
return 0;
}
VP8CPUInfo VP8GetCPUInfo = wasmCPUInfo;
#elif defined(WEBP_USE_NEON)
// define a dummy function to enable turning off NEON at runtime by setting
// VP8DecGetCPUInfo = NULL
+36 -32
View File
@@ -1283,12 +1283,12 @@ static void DC4_NEON(uint8_t* dst) { // DC
const uint8x8_t A = vld1_u8(dst - BPS); // top row
const uint16x4_t p0 = vpaddl_u8(A); // cascading summation of the top
const uint16x4_t p1 = vpadd_u16(p0, p0);
const uint16x8_t L0 = vmovl_u8(vld1_u8(dst + 0 * BPS - 1));
const uint16x8_t L1 = vmovl_u8(vld1_u8(dst + 1 * BPS - 1));
const uint16x8_t L2 = vmovl_u8(vld1_u8(dst + 2 * BPS - 1));
const uint16x8_t L3 = vmovl_u8(vld1_u8(dst + 3 * BPS - 1));
const uint16x8_t s0 = vaddq_u16(L0, L1);
const uint16x8_t s1 = vaddq_u16(L2, L3);
const uint8x8_t L0 = vld1_u8(dst + 0 * BPS - 1);
const uint8x8_t L1 = vld1_u8(dst + 1 * BPS - 1);
const uint8x8_t L2 = vld1_u8(dst + 2 * BPS - 1);
const uint8x8_t L3 = vld1_u8(dst + 3 * BPS - 1);
const uint16x8_t s0 = vaddl_u8(L0, L1);
const uint16x8_t s1 = vaddl_u8(L2, L3);
const uint16x8_t s01 = vaddq_u16(s0, s1);
const uint16x8_t sum = vaddq_u16(s01, vcombine_u16(p1, p1));
const uint8x8_t dc0 = vrshrn_n_u16(sum, 3); // (sum + 4) >> 3
@@ -1429,8 +1429,7 @@ static WEBP_INLINE void DC8_NEON(uint8_t* dst, int do_top, int do_left) {
if (do_top) {
const uint8x8_t A = vld1_u8(dst - BPS); // top row
#if defined(__aarch64__)
const uint16x8_t B = vmovl_u8(A);
const uint16_t p2 = vaddvq_u16(B);
const uint16_t p2 = vaddlv_u8(A);
sum_top = vdupq_n_u16(p2);
#else
const uint16x4_t p0 = vpaddl_u8(A); // cascading summation of the top
@@ -1441,18 +1440,18 @@ static WEBP_INLINE void DC8_NEON(uint8_t* dst, int do_top, int do_left) {
}
if (do_left) {
const uint16x8_t L0 = vmovl_u8(vld1_u8(dst + 0 * BPS - 1));
const uint16x8_t L1 = vmovl_u8(vld1_u8(dst + 1 * BPS - 1));
const uint16x8_t L2 = vmovl_u8(vld1_u8(dst + 2 * BPS - 1));
const uint16x8_t L3 = vmovl_u8(vld1_u8(dst + 3 * BPS - 1));
const uint16x8_t L4 = vmovl_u8(vld1_u8(dst + 4 * BPS - 1));
const uint16x8_t L5 = vmovl_u8(vld1_u8(dst + 5 * BPS - 1));
const uint16x8_t L6 = vmovl_u8(vld1_u8(dst + 6 * BPS - 1));
const uint16x8_t L7 = vmovl_u8(vld1_u8(dst + 7 * BPS - 1));
const uint16x8_t s0 = vaddq_u16(L0, L1);
const uint16x8_t s1 = vaddq_u16(L2, L3);
const uint16x8_t s2 = vaddq_u16(L4, L5);
const uint16x8_t s3 = vaddq_u16(L6, L7);
const uint8x8_t L0 = vld1_u8(dst + 0 * BPS - 1);
const uint8x8_t L1 = vld1_u8(dst + 1 * BPS - 1);
const uint8x8_t L2 = vld1_u8(dst + 2 * BPS - 1);
const uint8x8_t L3 = vld1_u8(dst + 3 * BPS - 1);
const uint8x8_t L4 = vld1_u8(dst + 4 * BPS - 1);
const uint8x8_t L5 = vld1_u8(dst + 5 * BPS - 1);
const uint8x8_t L6 = vld1_u8(dst + 6 * BPS - 1);
const uint8x8_t L7 = vld1_u8(dst + 7 * BPS - 1);
const uint16x8_t s0 = vaddl_u8(L0, L1);
const uint16x8_t s1 = vaddl_u8(L2, L3);
const uint16x8_t s2 = vaddl_u8(L4, L5);
const uint16x8_t s3 = vaddl_u8(L6, L7);
const uint16x8_t s01 = vaddq_u16(s0, s1);
const uint16x8_t s23 = vaddq_u16(s2, s3);
sum_left = vaddq_u16(s01, s23);
@@ -1512,29 +1511,34 @@ static WEBP_INLINE void DC16_NEON(uint8_t* dst, int do_top, int do_left) {
if (do_top) {
const uint8x16_t A = vld1q_u8(dst - BPS); // top row
#if defined(__aarch64__)
const uint16_t p3 = vaddlvq_u8(A);
sum_top = vdupq_n_u16(p3);
#else
const uint16x8_t p0 = vpaddlq_u8(A); // cascading summation of the top
const uint16x4_t p1 = vadd_u16(vget_low_u16(p0), vget_high_u16(p0));
const uint16x4_t p2 = vpadd_u16(p1, p1);
const uint16x4_t p3 = vpadd_u16(p2, p2);
sum_top = vcombine_u16(p3, p3);
#endif
}
if (do_left) {
int i;
sum_left = vdupq_n_u16(0);
for (i = 0; i < 16; i += 8) {
const uint16x8_t L0 = vmovl_u8(vld1_u8(dst + (i + 0) * BPS - 1));
const uint16x8_t L1 = vmovl_u8(vld1_u8(dst + (i + 1) * BPS - 1));
const uint16x8_t L2 = vmovl_u8(vld1_u8(dst + (i + 2) * BPS - 1));
const uint16x8_t L3 = vmovl_u8(vld1_u8(dst + (i + 3) * BPS - 1));
const uint16x8_t L4 = vmovl_u8(vld1_u8(dst + (i + 4) * BPS - 1));
const uint16x8_t L5 = vmovl_u8(vld1_u8(dst + (i + 5) * BPS - 1));
const uint16x8_t L6 = vmovl_u8(vld1_u8(dst + (i + 6) * BPS - 1));
const uint16x8_t L7 = vmovl_u8(vld1_u8(dst + (i + 7) * BPS - 1));
const uint16x8_t s0 = vaddq_u16(L0, L1);
const uint16x8_t s1 = vaddq_u16(L2, L3);
const uint16x8_t s2 = vaddq_u16(L4, L5);
const uint16x8_t s3 = vaddq_u16(L6, L7);
const uint8x8_t L0 = vld1_u8(dst + (i + 0) * BPS - 1);
const uint8x8_t L1 = vld1_u8(dst + (i + 1) * BPS - 1);
const uint8x8_t L2 = vld1_u8(dst + (i + 2) * BPS - 1);
const uint8x8_t L3 = vld1_u8(dst + (i + 3) * BPS - 1);
const uint8x8_t L4 = vld1_u8(dst + (i + 4) * BPS - 1);
const uint8x8_t L5 = vld1_u8(dst + (i + 5) * BPS - 1);
const uint8x8_t L6 = vld1_u8(dst + (i + 6) * BPS - 1);
const uint8x8_t L7 = vld1_u8(dst + (i + 7) * BPS - 1);
const uint16x8_t s0 = vaddl_u8(L0, L1);
const uint16x8_t s1 = vaddl_u8(L2, L3);
const uint16x8_t s2 = vaddl_u8(L4, L5);
const uint16x8_t s3 = vaddl_u8(L6, L7);
const uint16x8_t s01 = vaddq_u16(s0, s1);
const uint16x8_t s23 = vaddq_u16(s2, s3);
const uint16x8_t sum = vaddq_u16(s01, s23);
+13 -5
View File
@@ -51,9 +51,7 @@ extern "C" {
# define __has_builtin(x) 0
#endif
// for now, none of the optimizations below are available in emscripten
#if !defined(EMSCRIPTEN)
#if !defined(HAVE_CONFIG_H)
#if defined(_MSC_VER) && _MSC_VER > 1310 && \
(defined(_M_X64) || defined(_M_IX86))
#define WEBP_MSC_SSE2 // Visual C++ SSE2 targets
@@ -63,6 +61,7 @@ extern "C" {
(defined(_M_X64) || defined(_M_IX86))
#define WEBP_MSC_SSE41 // Visual C++ SSE4.1 targets
#endif
#endif
// WEBP_HAVE_* are used to indicate the presence of the instruction set in dsp
// files without intrinsics, allowing the corresponding Init() to be called.
@@ -76,6 +75,9 @@ extern "C" {
#define WEBP_USE_SSE41
#endif
#undef WEBP_MSC_SSE41
#undef WEBP_MSC_SSE2
// The intrinsics currently cause compiler errors with arm-nacl-gcc and the
// inline assembly would need to be modified for use with Native Client.
#if (defined(__ARM_NEON__) || \
@@ -110,8 +112,6 @@ extern "C" {
#define WEBP_USE_MSA
#endif
#endif /* EMSCRIPTEN */
#ifndef WEBP_DSP_OMIT_C_CODE
#define WEBP_DSP_OMIT_C_CODE 1
#endif
@@ -193,6 +193,12 @@ extern "C" {
#endif
#endif
// If 'ptr' is NULL, returns NULL. Otherwise returns 'ptr + off'.
// Prevents undefined behavior sanitizer nullptr-with-nonzero-offset warning.
#if !defined(WEBP_OFFSET_PTR)
#define WEBP_OFFSET_PTR(ptr, off) (((ptr) == NULL) ? NULL : ((ptr) + (off)))
#endif
// Regularize the definition of WEBP_SWAP_16BIT_CSP (backward compatibility)
#if !defined(WEBP_SWAP_16BIT_CSP)
#define WEBP_SWAP_16BIT_CSP 0
@@ -632,6 +638,8 @@ extern void (*WebPPackRGB)(const uint8_t* r, const uint8_t* g, const uint8_t* b,
extern int (*WebPHasAlpha8b)(const uint8_t* src, int length);
// This function returns true if src[4*i] contains a value different from 0xff.
extern int (*WebPHasAlpha32b)(const uint8_t* src, int length);
// replaces transparent values in src[] by 'color'.
extern void (*WebPAlphaReplace)(uint32_t* src, int length, uint32_t color);
// To be called first before using the above.
void WebPInitAlphaProcessing(void);
+27 -29
View File
@@ -107,62 +107,62 @@ static WEBP_INLINE uint32_t Select(uint32_t a, uint32_t b, uint32_t c) {
//------------------------------------------------------------------------------
// Predictors
static uint32_t Predictor0_C(uint32_t left, const uint32_t* const top) {
uint32_t VP8LPredictor0_C(uint32_t left, const uint32_t* const top) {
(void)top;
(void)left;
return ARGB_BLACK;
}
static uint32_t Predictor1_C(uint32_t left, const uint32_t* const top) {
uint32_t VP8LPredictor1_C(uint32_t left, const uint32_t* const top) {
(void)top;
return left;
}
static uint32_t Predictor2_C(uint32_t left, const uint32_t* const top) {
uint32_t VP8LPredictor2_C(uint32_t left, const uint32_t* const top) {
(void)left;
return top[0];
}
static uint32_t Predictor3_C(uint32_t left, const uint32_t* const top) {
uint32_t VP8LPredictor3_C(uint32_t left, const uint32_t* const top) {
(void)left;
return top[1];
}
static uint32_t Predictor4_C(uint32_t left, const uint32_t* const top) {
uint32_t VP8LPredictor4_C(uint32_t left, const uint32_t* const top) {
(void)left;
return top[-1];
}
static uint32_t Predictor5_C(uint32_t left, const uint32_t* const top) {
uint32_t VP8LPredictor5_C(uint32_t left, const uint32_t* const top) {
const uint32_t pred = Average3(left, top[0], top[1]);
return pred;
}
static uint32_t Predictor6_C(uint32_t left, const uint32_t* const top) {
uint32_t VP8LPredictor6_C(uint32_t left, const uint32_t* const top) {
const uint32_t pred = Average2(left, top[-1]);
return pred;
}
static uint32_t Predictor7_C(uint32_t left, const uint32_t* const top) {
uint32_t VP8LPredictor7_C(uint32_t left, const uint32_t* const top) {
const uint32_t pred = Average2(left, top[0]);
return pred;
}
static uint32_t Predictor8_C(uint32_t left, const uint32_t* const top) {
uint32_t VP8LPredictor8_C(uint32_t left, const uint32_t* const top) {
const uint32_t pred = Average2(top[-1], top[0]);
(void)left;
return pred;
}
static uint32_t Predictor9_C(uint32_t left, const uint32_t* const top) {
uint32_t VP8LPredictor9_C(uint32_t left, const uint32_t* const top) {
const uint32_t pred = Average2(top[0], top[1]);
(void)left;
return pred;
}
static uint32_t Predictor10_C(uint32_t left, const uint32_t* const top) {
uint32_t VP8LPredictor10_C(uint32_t left, const uint32_t* const top) {
const uint32_t pred = Average4(left, top[-1], top[0], top[1]);
return pred;
}
static uint32_t Predictor11_C(uint32_t left, const uint32_t* const top) {
uint32_t VP8LPredictor11_C(uint32_t left, const uint32_t* const top) {
const uint32_t pred = Select(top[0], left, top[-1]);
return pred;
}
static uint32_t Predictor12_C(uint32_t left, const uint32_t* const top) {
uint32_t VP8LPredictor12_C(uint32_t left, const uint32_t* const top) {
const uint32_t pred = ClampedAddSubtractFull(left, top[0], top[-1]);
return pred;
}
static uint32_t Predictor13_C(uint32_t left, const uint32_t* const top) {
uint32_t VP8LPredictor13_C(uint32_t left, const uint32_t* const top) {
const uint32_t pred = ClampedAddSubtractHalf(left, top[0], top[-1]);
return pred;
}
@@ -182,18 +182,18 @@ static void PredictorAdd1_C(const uint32_t* in, const uint32_t* upper,
out[i] = left = VP8LAddPixels(in[i], left);
}
}
GENERATE_PREDICTOR_ADD(Predictor2_C, PredictorAdd2_C)
GENERATE_PREDICTOR_ADD(Predictor3_C, PredictorAdd3_C)
GENERATE_PREDICTOR_ADD(Predictor4_C, PredictorAdd4_C)
GENERATE_PREDICTOR_ADD(Predictor5_C, PredictorAdd5_C)
GENERATE_PREDICTOR_ADD(Predictor6_C, PredictorAdd6_C)
GENERATE_PREDICTOR_ADD(Predictor7_C, PredictorAdd7_C)
GENERATE_PREDICTOR_ADD(Predictor8_C, PredictorAdd8_C)
GENERATE_PREDICTOR_ADD(Predictor9_C, PredictorAdd9_C)
GENERATE_PREDICTOR_ADD(Predictor10_C, PredictorAdd10_C)
GENERATE_PREDICTOR_ADD(Predictor11_C, PredictorAdd11_C)
GENERATE_PREDICTOR_ADD(Predictor12_C, PredictorAdd12_C)
GENERATE_PREDICTOR_ADD(Predictor13_C, PredictorAdd13_C)
GENERATE_PREDICTOR_ADD(VP8LPredictor2_C, PredictorAdd2_C)
GENERATE_PREDICTOR_ADD(VP8LPredictor3_C, PredictorAdd3_C)
GENERATE_PREDICTOR_ADD(VP8LPredictor4_C, PredictorAdd4_C)
GENERATE_PREDICTOR_ADD(VP8LPredictor5_C, PredictorAdd5_C)
GENERATE_PREDICTOR_ADD(VP8LPredictor6_C, PredictorAdd6_C)
GENERATE_PREDICTOR_ADD(VP8LPredictor7_C, PredictorAdd7_C)
GENERATE_PREDICTOR_ADD(VP8LPredictor8_C, PredictorAdd8_C)
GENERATE_PREDICTOR_ADD(VP8LPredictor9_C, PredictorAdd9_C)
GENERATE_PREDICTOR_ADD(VP8LPredictor10_C, PredictorAdd10_C)
GENERATE_PREDICTOR_ADD(VP8LPredictor11_C, PredictorAdd11_C)
GENERATE_PREDICTOR_ADD(VP8LPredictor12_C, PredictorAdd12_C)
GENERATE_PREDICTOR_ADD(VP8LPredictor13_C, PredictorAdd13_C)
//------------------------------------------------------------------------------
@@ -562,7 +562,6 @@ VP8LPredictorFunc VP8LPredictors[16];
// exposed plain-C implementations
VP8LPredictorAddSubFunc VP8LPredictorsAdd_C[16];
VP8LPredictorFunc VP8LPredictors_C[16];
VP8LTransformColorInverseFunc VP8LTransformColorInverse;
@@ -600,8 +599,7 @@ extern void VP8LDspInitMSA(void);
} while (0);
WEBP_DSP_INIT_FUNC(VP8LDspInit) {
COPY_PREDICTOR_ARRAY(Predictor, VP8LPredictors)
COPY_PREDICTOR_ARRAY(Predictor, VP8LPredictors_C)
COPY_PREDICTOR_ARRAY(VP8LPredictor, VP8LPredictors)
COPY_PREDICTOR_ARRAY(PredictorAdd, VP8LPredictorsAdd)
COPY_PREDICTOR_ARRAY(PredictorAdd, VP8LPredictorsAdd_C)
+16 -1
View File
@@ -30,7 +30,22 @@ extern "C" {
typedef uint32_t (*VP8LPredictorFunc)(uint32_t left, const uint32_t* const top);
extern VP8LPredictorFunc VP8LPredictors[16];
extern VP8LPredictorFunc VP8LPredictors_C[16];
uint32_t VP8LPredictor0_C(uint32_t left, const uint32_t* const top);
uint32_t VP8LPredictor1_C(uint32_t left, const uint32_t* const top);
uint32_t VP8LPredictor2_C(uint32_t left, const uint32_t* const top);
uint32_t VP8LPredictor3_C(uint32_t left, const uint32_t* const top);
uint32_t VP8LPredictor4_C(uint32_t left, const uint32_t* const top);
uint32_t VP8LPredictor5_C(uint32_t left, const uint32_t* const top);
uint32_t VP8LPredictor6_C(uint32_t left, const uint32_t* const top);
uint32_t VP8LPredictor7_C(uint32_t left, const uint32_t* const top);
uint32_t VP8LPredictor8_C(uint32_t left, const uint32_t* const top);
uint32_t VP8LPredictor9_C(uint32_t left, const uint32_t* const top);
uint32_t VP8LPredictor10_C(uint32_t left, const uint32_t* const top);
uint32_t VP8LPredictor11_C(uint32_t left, const uint32_t* const top);
uint32_t VP8LPredictor12_C(uint32_t left, const uint32_t* const top);
uint32_t VP8LPredictor13_C(uint32_t left, const uint32_t* const top);
// These Add/Sub function expects upper[-1] and out[-1] to be readable.
typedef void (*VP8LPredictorAddSubFunc)(const uint32_t* in,
const uint32_t* upper, int num_pixels,
-13
View File
@@ -184,19 +184,6 @@ static void PREDICTOR_ADD(const uint32_t* in, const uint32_t* upper, \
} \
}
// It subtracts the prediction from the input pixel and stores the residual
// in the output pixel.
#define GENERATE_PREDICTOR_SUB(PREDICTOR, PREDICTOR_SUB) \
static void PREDICTOR_SUB(const uint32_t* in, const uint32_t* upper, \
int num_pixels, uint32_t* out) { \
int x; \
assert(upper != NULL); \
for (x = 0; x < num_pixels; ++x) { \
const uint32_t pred = (PREDICTOR)(in[x - 1], upper + x); \
out[x] = VP8LSubPixels(in[x], pred); \
} \
}
#ifdef __cplusplus
} // extern "C"
#endif
+27 -146
View File
@@ -702,140 +702,6 @@ void VP8LHistogramAdd(const VP8LHistogram* const a,
//------------------------------------------------------------------------------
// Image transforms.
static WEBP_INLINE uint32_t Average2(uint32_t a0, uint32_t a1) {
return (((a0 ^ a1) & 0xfefefefeu) >> 1) + (a0 & a1);
}
static WEBP_INLINE uint32_t Average3(uint32_t a0, uint32_t a1, uint32_t a2) {
return Average2(Average2(a0, a2), a1);
}
static WEBP_INLINE uint32_t Average4(uint32_t a0, uint32_t a1,
uint32_t a2, uint32_t a3) {
return Average2(Average2(a0, a1), Average2(a2, a3));
}
static WEBP_INLINE uint32_t Clip255(uint32_t a) {
if (a < 256) {
return a;
}
// return 0, when a is a negative integer.
// return 255, when a is positive.
return ~a >> 24;
}
static WEBP_INLINE int AddSubtractComponentFull(int a, int b, int c) {
return Clip255(a + b - c);
}
static WEBP_INLINE uint32_t ClampedAddSubtractFull(uint32_t c0, uint32_t c1,
uint32_t c2) {
const int a = AddSubtractComponentFull(c0 >> 24, c1 >> 24, c2 >> 24);
const int r = AddSubtractComponentFull((c0 >> 16) & 0xff,
(c1 >> 16) & 0xff,
(c2 >> 16) & 0xff);
const int g = AddSubtractComponentFull((c0 >> 8) & 0xff,
(c1 >> 8) & 0xff,
(c2 >> 8) & 0xff);
const int b = AddSubtractComponentFull(c0 & 0xff, c1 & 0xff, c2 & 0xff);
return ((uint32_t)a << 24) | (r << 16) | (g << 8) | b;
}
static WEBP_INLINE int AddSubtractComponentHalf(int a, int b) {
return Clip255(a + (a - b) / 2);
}
static WEBP_INLINE uint32_t ClampedAddSubtractHalf(uint32_t c0, uint32_t c1,
uint32_t c2) {
const uint32_t ave = Average2(c0, c1);
const int a = AddSubtractComponentHalf(ave >> 24, c2 >> 24);
const int r = AddSubtractComponentHalf((ave >> 16) & 0xff, (c2 >> 16) & 0xff);
const int g = AddSubtractComponentHalf((ave >> 8) & 0xff, (c2 >> 8) & 0xff);
const int b = AddSubtractComponentHalf((ave >> 0) & 0xff, (c2 >> 0) & 0xff);
return ((uint32_t)a << 24) | (r << 16) | (g << 8) | b;
}
// gcc-4.9 on ARM generates incorrect code in Select() when Sub3() is inlined.
#if defined(__arm__) && \
(LOCAL_GCC_VERSION == 0x409 || LOCAL_GCC_VERSION == 0x408)
# define LOCAL_INLINE __attribute__ ((noinline))
#else
# define LOCAL_INLINE WEBP_INLINE
#endif
static LOCAL_INLINE int Sub3(int a, int b, int c) {
const int pb = b - c;
const int pa = a - c;
return abs(pb) - abs(pa);
}
#undef LOCAL_INLINE
static WEBP_INLINE uint32_t Select(uint32_t a, uint32_t b, uint32_t c) {
const int pa_minus_pb =
Sub3((a >> 24) , (b >> 24) , (c >> 24) ) +
Sub3((a >> 16) & 0xff, (b >> 16) & 0xff, (c >> 16) & 0xff) +
Sub3((a >> 8) & 0xff, (b >> 8) & 0xff, (c >> 8) & 0xff) +
Sub3((a ) & 0xff, (b ) & 0xff, (c ) & 0xff);
return (pa_minus_pb <= 0) ? a : b;
}
//------------------------------------------------------------------------------
// Predictors
static uint32_t Predictor2(uint32_t left, const uint32_t* const top) {
(void)left;
return top[0];
}
static uint32_t Predictor3(uint32_t left, const uint32_t* const top) {
(void)left;
return top[1];
}
static uint32_t Predictor4(uint32_t left, const uint32_t* const top) {
(void)left;
return top[-1];
}
static uint32_t Predictor5(uint32_t left, const uint32_t* const top) {
const uint32_t pred = Average3(left, top[0], top[1]);
return pred;
}
static uint32_t Predictor6(uint32_t left, const uint32_t* const top) {
const uint32_t pred = Average2(left, top[-1]);
return pred;
}
static uint32_t Predictor7(uint32_t left, const uint32_t* const top) {
const uint32_t pred = Average2(left, top[0]);
return pred;
}
static uint32_t Predictor8(uint32_t left, const uint32_t* const top) {
const uint32_t pred = Average2(top[-1], top[0]);
(void)left;
return pred;
}
static uint32_t Predictor9(uint32_t left, const uint32_t* const top) {
const uint32_t pred = Average2(top[0], top[1]);
(void)left;
return pred;
}
static uint32_t Predictor10(uint32_t left, const uint32_t* const top) {
const uint32_t pred = Average4(left, top[-1], top[0], top[1]);
return pred;
}
static uint32_t Predictor11(uint32_t left, const uint32_t* const top) {
const uint32_t pred = Select(top[0], left, top[-1]);
return pred;
}
static uint32_t Predictor12(uint32_t left, const uint32_t* const top) {
const uint32_t pred = ClampedAddSubtractFull(left, top[0], top[-1]);
return pred;
}
static uint32_t Predictor13(uint32_t left, const uint32_t* const top) {
const uint32_t pred = ClampedAddSubtractHalf(left, top[0], top[-1]);
return pred;
}
//------------------------------------------------------------------------------
static void PredictorSub0_C(const uint32_t* in, const uint32_t* upper,
int num_pixels, uint32_t* out) {
int i;
@@ -850,18 +716,33 @@ static void PredictorSub1_C(const uint32_t* in, const uint32_t* upper,
(void)upper;
}
GENERATE_PREDICTOR_SUB(Predictor2, PredictorSub2_C)
GENERATE_PREDICTOR_SUB(Predictor3, PredictorSub3_C)
GENERATE_PREDICTOR_SUB(Predictor4, PredictorSub4_C)
GENERATE_PREDICTOR_SUB(Predictor5, PredictorSub5_C)
GENERATE_PREDICTOR_SUB(Predictor6, PredictorSub6_C)
GENERATE_PREDICTOR_SUB(Predictor7, PredictorSub7_C)
GENERATE_PREDICTOR_SUB(Predictor8, PredictorSub8_C)
GENERATE_PREDICTOR_SUB(Predictor9, PredictorSub9_C)
GENERATE_PREDICTOR_SUB(Predictor10, PredictorSub10_C)
GENERATE_PREDICTOR_SUB(Predictor11, PredictorSub11_C)
GENERATE_PREDICTOR_SUB(Predictor12, PredictorSub12_C)
GENERATE_PREDICTOR_SUB(Predictor13, PredictorSub13_C)
// It subtracts the prediction from the input pixel and stores the residual
// in the output pixel.
#define GENERATE_PREDICTOR_SUB(PREDICTOR_I) \
static void PredictorSub##PREDICTOR_I##_C(const uint32_t* in, \
const uint32_t* upper, \
int num_pixels, uint32_t* out) { \
int x; \
assert(upper != NULL); \
for (x = 0; x < num_pixels; ++x) { \
const uint32_t pred = \
VP8LPredictor##PREDICTOR_I##_C(in[x - 1], upper + x); \
out[x] = VP8LSubPixels(in[x], pred); \
} \
}
GENERATE_PREDICTOR_SUB(2)
GENERATE_PREDICTOR_SUB(3)
GENERATE_PREDICTOR_SUB(4)
GENERATE_PREDICTOR_SUB(5)
GENERATE_PREDICTOR_SUB(6)
GENERATE_PREDICTOR_SUB(7)
GENERATE_PREDICTOR_SUB(8)
GENERATE_PREDICTOR_SUB(9)
GENERATE_PREDICTOR_SUB(10)
GENERATE_PREDICTOR_SUB(11)
GENERATE_PREDICTOR_SUB(12)
GENERATE_PREDICTOR_SUB(13)
//------------------------------------------------------------------------------
+24 -14
View File
@@ -249,6 +249,7 @@ static void AddVectorEq_SSE2(const uint32_t* a, uint32_t* out, int size) {
} \
} while (0)
#if !(defined(__i386__) || defined(_M_IX86))
static float CombinedShannonEntropy_SSE2(const int X[256], const int Y[256]) {
int i;
double retval = 0.;
@@ -300,6 +301,8 @@ static float CombinedShannonEntropy_SSE2(const int X[256], const int Y[256]) {
retval += VP8LFastSLog2(sumX) + VP8LFastSLog2(sumXY);
return (float)retval;
}
#endif // !(defined(__i386__) || defined(_M_IX86))
#undef ANALYZE_X_OR_Y
#undef ANALYZE_XY
@@ -460,20 +463,22 @@ static void PredictorSub0_SSE2(const uint32_t* in, const uint32_t* upper,
(void)upper;
}
#define GENERATE_PREDICTOR_1(X, IN) \
static void PredictorSub##X##_SSE2(const uint32_t* in, const uint32_t* upper, \
int num_pixels, uint32_t* out) { \
int i; \
for (i = 0; i + 4 <= num_pixels; i += 4) { \
const __m128i src = _mm_loadu_si128((const __m128i*)&in[i]); \
const __m128i pred = _mm_loadu_si128((const __m128i*)&(IN)); \
const __m128i res = _mm_sub_epi8(src, pred); \
_mm_storeu_si128((__m128i*)&out[i], res); \
} \
if (i != num_pixels) { \
VP8LPredictorsSub_C[(X)](in + i, upper + i, num_pixels - i, out + i); \
} \
}
#define GENERATE_PREDICTOR_1(X, IN) \
static void PredictorSub##X##_SSE2(const uint32_t* const in, \
const uint32_t* const upper, \
int num_pixels, uint32_t* const out) { \
int i; \
for (i = 0; i + 4 <= num_pixels; i += 4) { \
const __m128i src = _mm_loadu_si128((const __m128i*)&in[i]); \
const __m128i pred = _mm_loadu_si128((const __m128i*)&(IN)); \
const __m128i res = _mm_sub_epi8(src, pred); \
_mm_storeu_si128((__m128i*)&out[i], res); \
} \
if (i != num_pixels) { \
VP8LPredictorsSub_C[(X)](in + i, WEBP_OFFSET_PTR(upper, i), \
num_pixels - i, out + i); \
} \
}
GENERATE_PREDICTOR_1(1, in[i - 1]) // Predictor1: L
GENERATE_PREDICTOR_1(2, upper[i]) // Predictor2: T
@@ -657,7 +662,12 @@ WEBP_TSAN_IGNORE_FUNCTION void VP8LEncDspInitSSE2(void) {
VP8LCollectColorRedTransforms = CollectColorRedTransforms_SSE2;
VP8LAddVector = AddVector_SSE2;
VP8LAddVectorEq = AddVectorEq_SSE2;
// TODO(https://crbug.com/webp/499): this function produces different results
// from the C code due to use of double/float resulting in output differences
// when compared to -noasm.
#if !(defined(__i386__) || defined(_M_IX86))
VP8LCombinedShannonEntropy = CombinedShannonEntropy_SSE2;
#endif
VP8LVectorMismatch = VectorMismatch_SSE2;
VP8LBundleColorMap = BundleColorMap_SSE2;
-60
View File
@@ -126,16 +126,6 @@ static void InitHistogram(VP8Histogram* const histo) {
histo->last_non_zero = 1;
}
static void MergeHistograms(const VP8Histogram* const in,
VP8Histogram* const out) {
if (in->max_value > out->max_value) {
out->max_value = in->max_value;
}
if (in->last_non_zero > out->last_non_zero) {
out->last_non_zero = in->last_non_zero;
}
}
//------------------------------------------------------------------------------
// Simplified k-Means, to assign Nb segments based on alpha-histogram
@@ -285,49 +275,6 @@ static int FastMBAnalyze(VP8EncIterator* const it) {
return 0;
}
static int MBAnalyzeBestIntra4Mode(VP8EncIterator* const it,
int best_alpha) {
uint8_t modes[16];
const int max_mode = MAX_INTRA4_MODE;
int i4_alpha;
VP8Histogram total_histo;
int cur_histo = 0;
InitHistogram(&total_histo);
VP8IteratorStartI4(it);
do {
int mode;
int best_mode_alpha = DEFAULT_ALPHA;
VP8Histogram histos[2];
const uint8_t* const src = it->yuv_in_ + Y_OFF_ENC + VP8Scan[it->i4_];
VP8MakeIntra4Preds(it);
for (mode = 0; mode < max_mode; ++mode) {
int alpha;
InitHistogram(&histos[cur_histo]);
VP8CollectHistogram(src, it->yuv_p_ + VP8I4ModeOffsets[mode],
0, 1, &histos[cur_histo]);
alpha = GetAlpha(&histos[cur_histo]);
if (IS_BETTER_ALPHA(alpha, best_mode_alpha)) {
best_mode_alpha = alpha;
modes[it->i4_] = mode;
cur_histo ^= 1; // keep track of best histo so far.
}
}
// accumulate best histogram
MergeHistograms(&histos[cur_histo ^ 1], &total_histo);
// Note: we reuse the original samples for predictors
} while (VP8IteratorRotateI4(it, it->yuv_in_ + Y_OFF_ENC));
i4_alpha = GetAlpha(&total_histo);
if (IS_BETTER_ALPHA(i4_alpha, best_alpha)) {
VP8SetIntra4Mode(it, modes);
best_alpha = i4_alpha;
}
return best_alpha;
}
static int MBAnalyzeBestUVMode(VP8EncIterator* const it) {
int best_alpha = DEFAULT_ALPHA;
int smallest_alpha = 0;
@@ -371,13 +318,6 @@ static void MBAnalyze(VP8EncIterator* const it,
best_alpha = FastMBAnalyze(it);
} else {
best_alpha = MBAnalyzeBestIntra16Mode(it);
if (enc->method_ >= 5) {
// We go and make a fast decision for intra4/intra16.
// It's usually not a good and definitive pick, but helps seeding the
// stats about level bit-cost.
// TODO(skal): improve criterion.
best_alpha = MBAnalyzeBestIntra4Mode(it, best_alpha);
}
}
best_uv_alpha = MBAnalyzeBestUVMode(it);
+144 -59
View File
@@ -11,13 +11,14 @@
//
#include <assert.h>
#include <float.h>
#include <math.h>
#include "src/enc/backward_references_enc.h"
#include "src/enc/histogram_enc.h"
#include "src/dsp/dsp.h"
#include "src/dsp/lossless.h"
#include "src/dsp/lossless_common.h"
#include "src/dsp/dsp.h"
#include "src/enc/backward_references_enc.h"
#include "src/enc/histogram_enc.h"
#include "src/utils/color_cache_utils.h"
#include "src/utils/utils.h"
@@ -103,6 +104,20 @@ void VP8LBackwardRefsClear(VP8LBackwardRefs* const refs) {
}
}
// Swaps the content of two VP8LBackwardRefs.
static void BackwardRefsSwap(VP8LBackwardRefs* const refs1,
VP8LBackwardRefs* const refs2) {
const int point_to_refs1 =
(refs1->tail_ != NULL && refs1->tail_ == &refs1->refs_);
const int point_to_refs2 =
(refs2->tail_ != NULL && refs2->tail_ == &refs2->refs_);
const VP8LBackwardRefs tmp = *refs1;
*refs1 = *refs2;
*refs2 = tmp;
if (point_to_refs2) refs1->tail_ = &refs1->refs_;
if (point_to_refs1) refs2->tail_ = &refs2->refs_;
}
void VP8LBackwardRefsInit(VP8LBackwardRefs* const refs, int block_size) {
assert(refs != NULL);
memset(refs, 0, sizeof(*refs));
@@ -154,6 +169,22 @@ static PixOrCopyBlock* BackwardRefsNewBlock(VP8LBackwardRefs* const refs) {
return b;
}
// Return 1 on success, 0 on error.
static int BackwardRefsClone(const VP8LBackwardRefs* const from,
VP8LBackwardRefs* const to) {
const PixOrCopyBlock* block_from = from->refs_;
VP8LClearBackwardRefs(to);
while (block_from != NULL) {
PixOrCopyBlock* const block_to = BackwardRefsNewBlock(to);
if (block_to == NULL) return 0;
memcpy(block_to->start_, block_from->start_,
block_from->size_ * sizeof(PixOrCopy));
block_to->size_ = block_from->size_;
block_from = block_from->next_;
}
return 1;
}
extern void VP8LBackwardRefsCursorAdd(VP8LBackwardRefs* const refs,
const PixOrCopy v);
void VP8LBackwardRefsCursorAdd(VP8LBackwardRefs* const refs,
@@ -753,12 +784,18 @@ static int CalculateBestCacheSize(const uint32_t* argb, int quality,
}
}
} else {
int code, extra_bits, extra_bits_value;
// We should compute the contribution of the (distance,length)
// histograms but those are the same independently from the cache size.
// As those constant contributions are in the end added to the other
// histogram contributions, we can safely ignore them.
// histogram contributions, we can ignore them, except for the length
// prefix that is part of the literal_ histogram.
int len = PixOrCopyLength(v);
uint32_t argb_prev = *argb ^ 0xffffffffu;
VP8LPrefixEncode(len, &code, &extra_bits, &extra_bits_value);
for (i = 0; i <= cache_bits_max; ++i) {
++histos[i]->literal_[NUM_LITERAL_CODES + code];
}
// Update the color caches.
do {
if (*argb != argb_prev) {
@@ -842,16 +879,21 @@ extern int VP8LBackwardReferencesTraceBackwards(
int xsize, int ysize, const uint32_t* const argb, int cache_bits,
const VP8LHashChain* const hash_chain,
const VP8LBackwardRefs* const refs_src, VP8LBackwardRefs* const refs_dst);
static VP8LBackwardRefs* GetBackwardReferences(
int width, int height, const uint32_t* const argb, int quality,
int lz77_types_to_try, int* const cache_bits,
const VP8LHashChain* const hash_chain, VP8LBackwardRefs* best,
VP8LBackwardRefs* worst) {
const int cache_bits_initial = *cache_bits;
double bit_cost_best = -1;
static int GetBackwardReferences(int width, int height,
const uint32_t* const argb, int quality,
int lz77_types_to_try, int cache_bits_max,
int do_no_cache,
const VP8LHashChain* const hash_chain,
VP8LBackwardRefs* const refs,
int* const cache_bits_best) {
VP8LHistogram* histo = NULL;
int lz77_type, lz77_type_best = 0;
int i, lz77_type;
// Index 0 is for a color cache, index 1 for no cache (if needed).
int lz77_types_best[2] = {0, 0};
double bit_costs_best[2] = {DBL_MAX, DBL_MAX};
VP8LHashChain hash_chain_box;
VP8LBackwardRefs* const refs_tmp = &refs[do_no_cache ? 2 : 1];
int status = 0;
memset(&hash_chain_box, 0, sizeof(hash_chain_box));
histo = VP8LAllocateHistogram(MAX_COLOR_CACHE_BITS);
@@ -860,86 +902,129 @@ static VP8LBackwardRefs* GetBackwardReferences(
for (lz77_type = 1; lz77_types_to_try;
lz77_types_to_try &= ~lz77_type, lz77_type <<= 1) {
int res = 0;
double bit_cost;
int cache_bits_tmp = cache_bits_initial;
double bit_cost = 0.;
if ((lz77_types_to_try & lz77_type) == 0) continue;
switch (lz77_type) {
case kLZ77RLE:
res = BackwardReferencesRle(width, height, argb, 0, worst);
res = BackwardReferencesRle(width, height, argb, 0, refs_tmp);
break;
case kLZ77Standard:
// Compute LZ77 with no cache (0 bits), as the ideal LZ77 with a color
// cache is not that different in practice.
res = BackwardReferencesLz77(width, height, argb, 0, hash_chain, worst);
res = BackwardReferencesLz77(width, height, argb, 0, hash_chain,
refs_tmp);
break;
case kLZ77Box:
if (!VP8LHashChainInit(&hash_chain_box, width * height)) goto Error;
res = BackwardReferencesLz77Box(width, height, argb, 0, hash_chain,
&hash_chain_box, worst);
&hash_chain_box, refs_tmp);
break;
default:
assert(0);
}
if (!res) goto Error;
// Next, try with a color cache and update the references.
if (!CalculateBestCacheSize(argb, quality, worst, &cache_bits_tmp)) {
goto Error;
}
if (cache_bits_tmp > 0) {
if (!BackwardRefsWithLocalCache(argb, cache_bits_tmp, worst)) {
goto Error;
// Start with the no color cache case.
for (i = 1; i >= 0; --i) {
int cache_bits = (i == 1) ? 0 : cache_bits_max;
if (i == 1 && !do_no_cache) continue;
if (i == 0) {
// Try with a color cache.
if (!CalculateBestCacheSize(argb, quality, refs_tmp, &cache_bits)) {
goto Error;
}
if (cache_bits > 0) {
if (!BackwardRefsWithLocalCache(argb, cache_bits, refs_tmp)) {
goto Error;
}
}
}
if (i == 0 && do_no_cache && cache_bits == 0) {
// No need to re-compute bit_cost as it was computed at i == 1.
} else {
VP8LHistogramCreate(histo, refs_tmp, cache_bits);
bit_cost = VP8LHistogramEstimateBits(histo);
}
if (bit_cost < bit_costs_best[i]) {
if (i == 1) {
// Do not swap as the full cache analysis would have the wrong
// VP8LBackwardRefs to start with.
if (!BackwardRefsClone(refs_tmp, &refs[1])) goto Error;
} else {
BackwardRefsSwap(refs_tmp, &refs[0]);
}
bit_costs_best[i] = bit_cost;
lz77_types_best[i] = lz77_type;
if (i == 0) *cache_bits_best = cache_bits;
}
}
// Keep the best backward references.
VP8LHistogramCreate(histo, worst, cache_bits_tmp);
bit_cost = VP8LHistogramEstimateBits(histo);
if (lz77_type_best == 0 || bit_cost < bit_cost_best) {
VP8LBackwardRefs* const tmp = worst;
worst = best;
best = tmp;
bit_cost_best = bit_cost;
*cache_bits = cache_bits_tmp;
lz77_type_best = lz77_type;
}
}
assert(lz77_type_best > 0);
assert(lz77_types_best[0] > 0);
assert(!do_no_cache || lz77_types_best[1] > 0);
// Improve on simple LZ77 but only for high quality (TraceBackwards is
// costly).
if ((lz77_type_best == kLZ77Standard || lz77_type_best == kLZ77Box) &&
quality >= 25) {
const VP8LHashChain* const hash_chain_tmp =
(lz77_type_best == kLZ77Standard) ? hash_chain : &hash_chain_box;
if (VP8LBackwardReferencesTraceBackwards(width, height, argb, *cache_bits,
hash_chain_tmp, best, worst)) {
double bit_cost_trace;
VP8LHistogramCreate(histo, worst, *cache_bits);
bit_cost_trace = VP8LHistogramEstimateBits(histo);
if (bit_cost_trace < bit_cost_best) best = worst;
for (i = 1; i >= 0; --i) {
if (i == 1 && !do_no_cache) continue;
if ((lz77_types_best[i] == kLZ77Standard ||
lz77_types_best[i] == kLZ77Box) &&
quality >= 25) {
const VP8LHashChain* const hash_chain_tmp =
(lz77_types_best[i] == kLZ77Standard) ? hash_chain : &hash_chain_box;
const int cache_bits = (i == 1) ? 0 : *cache_bits_best;
if (VP8LBackwardReferencesTraceBackwards(width, height, argb, cache_bits,
hash_chain_tmp, &refs[i],
refs_tmp)) {
double bit_cost_trace;
VP8LHistogramCreate(histo, refs_tmp, cache_bits);
bit_cost_trace = VP8LHistogramEstimateBits(histo);
if (bit_cost_trace < bit_costs_best[i]) {
BackwardRefsSwap(refs_tmp, &refs[i]);
}
}
}
BackwardReferences2DLocality(width, &refs[i]);
if (i == 1 && lz77_types_best[0] == lz77_types_best[1] &&
*cache_bits_best == 0) {
// If the best cache size is 0 and we have the same best LZ77, just copy
// the data over and stop here.
if (!BackwardRefsClone(&refs[1], &refs[0])) goto Error;
break;
}
}
BackwardReferences2DLocality(width, best);
status = 1;
Error:
VP8LHashChainClear(&hash_chain_box);
VP8LFreeHistogram(histo);
return best;
return status;
}
VP8LBackwardRefs* VP8LGetBackwardReferences(
WebPEncodingError VP8LGetBackwardReferences(
int width, int height, const uint32_t* const argb, int quality,
int low_effort, int lz77_types_to_try, int* const cache_bits,
const VP8LHashChain* const hash_chain, VP8LBackwardRefs* const refs_tmp1,
VP8LBackwardRefs* const refs_tmp2) {
int low_effort, int lz77_types_to_try, int cache_bits_max, int do_no_cache,
const VP8LHashChain* const hash_chain, VP8LBackwardRefs* const refs,
int* const cache_bits_best) {
if (low_effort) {
return GetBackwardReferencesLowEffort(width, height, argb, cache_bits,
hash_chain, refs_tmp1);
VP8LBackwardRefs* refs_best;
*cache_bits_best = cache_bits_max;
refs_best = GetBackwardReferencesLowEffort(
width, height, argb, cache_bits_best, hash_chain, refs);
if (refs_best == NULL) return VP8_ENC_ERROR_OUT_OF_MEMORY;
// Set it in first position.
BackwardRefsSwap(refs_best, &refs[0]);
} else {
return GetBackwardReferences(width, height, argb, quality,
lz77_types_to_try, cache_bits, hash_chain,
refs_tmp1, refs_tmp2);
if (!GetBackwardReferences(width, height, argb, quality, lz77_types_to_try,
cache_bits_max, do_no_cache, hash_chain, refs,
cache_bits_best)) {
return VP8_ENC_ERROR_OUT_OF_MEMORY;
}
}
return VP8_ENC_OK;
}
+13 -7
View File
@@ -16,6 +16,7 @@
#include <assert.h>
#include <stdlib.h>
#include "src/webp/types.h"
#include "src/webp/encode.h"
#include "src/webp/format_constants.h"
#ifdef __cplusplus
@@ -218,14 +219,19 @@ enum VP8LLZ77Type {
// Evaluates best possible backward references for specified quality.
// The input cache_bits to 'VP8LGetBackwardReferences' sets the maximum cache
// bits to use (passing 0 implies disabling the local color cache).
// The optimal cache bits is evaluated and set for the *cache_bits parameter.
// The return value is the pointer to the best of the two backward refs viz,
// refs[0] or refs[1].
VP8LBackwardRefs* VP8LGetBackwardReferences(
// The optimal cache bits is evaluated and set for the *cache_bits_best
// parameter with the matching refs_best.
// If do_no_cache == 0, refs is an array of 2 values and the best
// VP8LBackwardRefs is put in the first element.
// If do_no_cache != 0, refs is an array of 3 values and the best
// VP8LBackwardRefs is put in the first element, the best value with no-cache in
// the second element.
// In both cases, the last element is used as temporary internally.
WebPEncodingError VP8LGetBackwardReferences(
int width, int height, const uint32_t* const argb, int quality,
int low_effort, int lz77_types_to_try, int* const cache_bits,
const VP8LHashChain* const hash_chain, VP8LBackwardRefs* const refs_tmp1,
VP8LBackwardRefs* const refs_tmp2);
int low_effort, int lz77_types_to_try, int cache_bits_max, int do_no_cache,
const VP8LHashChain* const hash_chain, VP8LBackwardRefs* const refs,
int* const cache_bits_best);
#ifdef __cplusplus
}
+5
View File
@@ -39,6 +39,8 @@ int WebPConfigInitInternal(WebPConfig* config,
config->partitions = 0;
config->segments = 4;
config->pass = 1;
config->qmin = 0;
config->qmax = 100;
config->show_compressed = 0;
config->preprocessing = 0;
config->autofilter = 0;
@@ -106,6 +108,9 @@ int WebPValidateConfig(const WebPConfig* config) {
if (config->filter_type < 0 || config->filter_type > 1) return 0;
if (config->autofilter < 0 || config->autofilter > 1) return 0;
if (config->pass < 1 || config->pass > 10) return 0;
if (config->qmin < 0 || config->qmax > 100 || config->qmin > config->qmax) {
return 0;
}
if (config->show_compressed < 0 || config->show_compressed > 1) return 0;
if (config->preprocessing < 0 || config->preprocessing > 7) return 0;
if (config->partitions < 0 || config->partitions > 3) return 0;

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