mirror of
https://github.com/opencv/opencv.git
synced 2026-07-22 03:43:03 +04:00
Compare commits
144 Commits
4.4.0-openvino
...
3.4.11
| Author | SHA1 | Date | |
|---|---|---|---|
| e8d4259f9a | |||
| 8086afc60a | |||
| b2ebd37ee2 | |||
| 83e6813345 | |||
| 09f24a851e | |||
| 81e027eef7 | |||
| 1c371d07b5 | |||
| 55e8549839 | |||
| f8d6c5b330 | |||
| 435b6df989 | |||
| bf8136eaa6 | |||
| cc584760d3 | |||
| d41b20b268 | |||
| 36da867caf | |||
| c5f540e3d7 | |||
| c90e824342 | |||
| 749bd80091 | |||
| 1c0b70bbd2 | |||
| b75f6c05c0 | |||
| 269b810601 | |||
| e54040d540 | |||
| b96e9a4a4a | |||
| e18df87a15 | |||
| 5cb8619eca | |||
| 476094ad5a | |||
| d2469edd10 | |||
| 0df8fb70b4 | |||
| 4dd9a36a3c | |||
| 41678fe3d3 | |||
| 5bc6b6fc26 | |||
| 8931c68b20 | |||
| f78f908c09 | |||
| 5487bca4f3 | |||
| 762a5c8334 | |||
| 2fed41dfa5 | |||
| e0f9eac521 | |||
| b90a2a8497 | |||
| 950a916952 | |||
| 3f13339071 | |||
| eb6678ebef | |||
| d62e0a3695 | |||
| dcb7fd8520 | |||
| d5713c657b | |||
| 99c4b76a6d | |||
| e4887aaa5b | |||
| d69a7a3bbf | |||
| ccf6dd07b3 | |||
| e8129429e9 | |||
| 2566d13100 | |||
| 5a15369d4d | |||
| deaf1dd458 | |||
| 65f87b114b | |||
| 8f5b453a96 | |||
| b7eec216e9 | |||
| dc57707e60 | |||
| 56b5a7d977 | |||
| 65dbbf712d | |||
| 49497d8e7c | |||
| 728684840c | |||
| 73f7d091f8 | |||
| 00e1bc49c8 | |||
| cb3a098b25 | |||
| 5a7045181a | |||
| 6a045fd678 | |||
| 327f92cc46 | |||
| 482cacd420 | |||
| 93a6be836c | |||
| ef7185ce43 | |||
| 920c180052 | |||
| a84afb6334 | |||
| cdac7c7bec | |||
| fe09c79f4b | |||
| cabad90d6c | |||
| 6dba1733f0 | |||
| daa88c6b9e | |||
| 9b727fa1f3 | |||
| e45d74c8f9 | |||
| 923009b5ff | |||
| 4064d4c7eb | |||
| e58ce89b10 | |||
| 6259ba1bfd | |||
| cd8262eb79 | |||
| d2b854674e | |||
| ad930f6216 | |||
| f061a0ab36 | |||
| 2e165053ef | |||
| 8cc8b0d2b4 | |||
| 06b4292534 | |||
| 29f883feee | |||
| 0e69cddda2 | |||
| ad5e70f94e | |||
| 7fae2e834c | |||
| 8e3f5fb209 | |||
| 1491934d17 | |||
| fce486c4f9 | |||
| 1b4955342f | |||
| 95ac650af6 | |||
| 2b98aa403e | |||
| 425c653a14 | |||
| 52844614c4 | |||
| 85c0c8c7ed | |||
| a8f04359e8 | |||
| cb54f4c2ec | |||
| 77fa1a20bf | |||
| a7cdc42140 | |||
| a8aa9d5ecb | |||
| 52fbfb3ec0 | |||
| d25293b721 | |||
| c07af090f5 | |||
| 456e88a8a4 | |||
| a7cc1159cd | |||
| 6bd87e8146 | |||
| 42a4c3fba6 | |||
| 1cba763189 | |||
| d01cbe9320 | |||
| b10ab79743 | |||
| 619462b029 | |||
| d93b6be3cc | |||
| 9755ab160d | |||
| 2043e06102 | |||
| c7dcdc0e88 | |||
| eb67dc9f50 | |||
| 676b818d6a | |||
| 411ce04f54 | |||
| d321a34f7c | |||
| fb1a58ac76 | |||
| 1644af841b | |||
| b0def9617f | |||
| c2664d912a | |||
| 9697e3ac24 | |||
| d2a9efd039 | |||
| 442999dcdb | |||
| d753ae1489 | |||
| db3e3be8ee | |||
| 0c8da03869 | |||
| 0417c8c9c7 | |||
| d4af89781b | |||
| a8c1cdf88e | |||
| 7a187e9b5e | |||
| 9096b1c768 | |||
| 781fbde449 | |||
| 1b336bb602 | |||
| 0fb3b8db72 | |||
| b44302382d |
Vendored
+5
-5
@@ -1,8 +1,8 @@
|
||||
# Binaries branch name: ffmpeg/3.4_20200310
|
||||
# Binaries were created for OpenCV: 4966186e10e2a940514d8c20447ca4a828af5f46
|
||||
ocv_update(FFMPEG_BINARIES_COMMIT "e81ccda615672833b578c6cefdb859ad69c560ba")
|
||||
ocv_update(FFMPEG_FILE_HASH_BIN32 "301ae2000e25f800ab8e0065f277ad28")
|
||||
ocv_update(FFMPEG_FILE_HASH_BIN64 "d87ce032289c3f811d02f0c3d8dbe366")
|
||||
# Binaries branch name: ffmpeg/3.4_20200608
|
||||
# Binaries were created for OpenCV: 458f1d5ebe31e22789d9d781d0ca2ca936758fde
|
||||
ocv_update(FFMPEG_BINARIES_COMMIT "57064cd66d98994503b34aade3c8d8ff25007b46")
|
||||
ocv_update(FFMPEG_FILE_HASH_BIN32 "6fff20f5617bd1b7362058790db52caa")
|
||||
ocv_update(FFMPEG_FILE_HASH_BIN64 "15df55131471191b575668a424dff385")
|
||||
ocv_update(FFMPEG_FILE_HASH_CMAKE "3b90f67f4b429e77d3da36698cef700c")
|
||||
|
||||
function(download_win_ffmpeg script_var)
|
||||
|
||||
+4
-2
@@ -4,9 +4,9 @@ ocv_warnings_disable(CMAKE_C_FLAGS -Wunused-parameter -Wsign-compare -Wshorten-6
|
||||
|
||||
set(VERSION_MAJOR 2)
|
||||
set(VERSION_MINOR 0)
|
||||
set(VERSION_REVISION 4)
|
||||
set(VERSION_REVISION 5)
|
||||
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION})
|
||||
set(LIBJPEG_TURBO_VERSION_NUMBER 2000004)
|
||||
set(LIBJPEG_TURBO_VERSION_NUMBER 2000005)
|
||||
|
||||
string(TIMESTAMP BUILD "opencv-${OPENCV_VERSION}-libjpeg-turbo")
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
@@ -65,6 +65,8 @@ set(JPEG_LIB_VERSION 62)
|
||||
# OpenCV
|
||||
set(JPEG_LIB_VERSION "${VERSION}-${JPEG_LIB_VERSION}" PARENT_SCOPE)
|
||||
|
||||
set(THREAD_LOCAL "") # WITH_TURBOJPEG is not used
|
||||
|
||||
if(MSVC)
|
||||
add_definitions(-W3 -wd4996 -wd4018)
|
||||
endif()
|
||||
|
||||
+3
@@ -15,6 +15,9 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* How to obtain thread-local storage */
|
||||
#define THREAD_LOCAL @THREAD_LOCAL@
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "@CMAKE_PROJECT_NAME@"
|
||||
|
||||
|
||||
+1
-2
@@ -143,8 +143,7 @@ empty_mem_output_buffer(j_compress_ptr cinfo)
|
||||
|
||||
MEMCOPY(nextbuffer, dest->buffer, dest->bufsize);
|
||||
|
||||
if (dest->newbuffer != NULL)
|
||||
free(dest->newbuffer);
|
||||
free(dest->newbuffer);
|
||||
|
||||
dest->newbuffer = nextbuffer;
|
||||
|
||||
|
||||
+3
-3
@@ -4,7 +4,7 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-2012, Thomas G. Lane, Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2010, 2012-2019, D. R. Commander.
|
||||
* Copyright (C) 2010, 2012-2020, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -36,7 +36,7 @@
|
||||
*/
|
||||
|
||||
#define JCOPYRIGHT \
|
||||
"Copyright (C) 2009-2019 D. R. Commander\n" \
|
||||
"Copyright (C) 2009-2020 D. R. Commander\n" \
|
||||
"Copyright (C) 2011-2016 Siarhei Siamashka\n" \
|
||||
"Copyright (C) 2015-2016, 2018 Matthieu Darbois\n" \
|
||||
"Copyright (C) 2015 Intel Corporation\n" \
|
||||
@@ -49,4 +49,4 @@
|
||||
"Copyright (C) 1991-2016 Thomas G. Lane, Guido Vollbeding"
|
||||
|
||||
#define JCOPYRIGHT_SHORT \
|
||||
"Copyright (C) 1991-2019 The libjpeg-turbo Project and many others"
|
||||
"Copyright (C) 1991-2020 The libjpeg-turbo Project and many others"
|
||||
|
||||
Vendored
+6
-13
@@ -1,7 +1,7 @@
|
||||
The Independent JPEG Group's JPEG software
|
||||
==========================================
|
||||
|
||||
README for release 9c of 14-Jan-2018
|
||||
README for release 9d of 12-Jan-2020
|
||||
====================================
|
||||
|
||||
This distribution contains the ninth public release of the Independent JPEG
|
||||
@@ -10,8 +10,8 @@ to use it for any purpose, subject to the conditions under LEGAL ISSUES, below.
|
||||
|
||||
This software is the work of Tom Lane, Guido Vollbeding, Philip Gladstone,
|
||||
Bill Allombert, Jim Boucher, Lee Crocker, Bob Friesenhahn, Ben Jackson,
|
||||
Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi, Ge' Weijers,
|
||||
and other members of the Independent JPEG Group.
|
||||
John Korejwa, Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi,
|
||||
Ge' Weijers, and other members of the Independent JPEG Group.
|
||||
|
||||
IJG is not affiliated with the ISO/IEC JTC1/SC29/WG1 standards committee
|
||||
(previously known as JPEG, together with ITU-T SG16).
|
||||
@@ -115,7 +115,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-2018, 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
|
||||
@@ -152,13 +152,6 @@ The same holds for its supporting scripts (config.guess, config.sub,
|
||||
ltmain.sh). Another support script, install-sh, is copyright by X Consortium
|
||||
but is also freely distributable.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
REFERENCES
|
||||
==========
|
||||
@@ -246,8 +239,8 @@ ARCHIVE LOCATIONS
|
||||
The "official" archive site for this software is www.ijg.org.
|
||||
The most recent released version can always be found there in
|
||||
directory "files". This particular version will be archived as
|
||||
http://www.ijg.org/files/jpegsrc.v9c.tar.gz, and in Windows-compatible
|
||||
"zip" archive format as http://www.ijg.org/files/jpegsr9c.zip.
|
||||
http://www.ijg.org/files/jpegsrc.v9d.tar.gz, and in Windows-compatible
|
||||
"zip" archive format as http://www.ijg.org/files/jpegsr9d.zip.
|
||||
|
||||
The JPEG FAQ (Frequently Asked Questions) article is a source of some
|
||||
general information about JPEG.
|
||||
|
||||
Vendored
+49
@@ -1,6 +1,55 @@
|
||||
CHANGE LOG for Independent JPEG Group's JPEG software
|
||||
|
||||
|
||||
Version 9d 12-Jan-2020
|
||||
-----------------------
|
||||
|
||||
Optimize the optimal Huffman code table generation to produce
|
||||
slightly smaller files. Thank to John Korejwa for suggestion.
|
||||
Note: Requires rebuild of testimgp.jpg.
|
||||
|
||||
Decoding Huffman: Use default tables if tables are not defined.
|
||||
Thank to Simone Azzalin for report (Motion JPEG),
|
||||
and to Martin Strunz for hint.
|
||||
|
||||
Add sanity check in optimal Huffman code table generation.
|
||||
Thank to Adam Farley for suggestion.
|
||||
|
||||
rdtarga.c: use read_byte(), with EOF check, instead of getc()
|
||||
in read_*_pixel().
|
||||
Thank to Chijin Zhou for cjpeg potential vulnerability report.
|
||||
|
||||
jmemnobs.c: respect the max_memory_to_use setting in
|
||||
jpeg_mem_available() computation. Thank to Sheng Shu and
|
||||
Dongdong She for djpeg potential vulnerability report.
|
||||
|
||||
jdarith.c, jdhuff.c: avoid left shift of negative value
|
||||
compiler warning in decode_mcu_AC_refine().
|
||||
Thank to Indu Bhagat for suggestion.
|
||||
|
||||
Add x64 (64-bit) platform support, avoid compiler warnings.
|
||||
Thank to Jonathan Potter, Feiyun Wang, and Sheng Shu for suggestion.
|
||||
|
||||
Adjust libjpeg version specification for pkg-config file.
|
||||
Thank to Chen Chen for suggestion.
|
||||
|
||||
Restore GIF read and write support from libjpeg version 6a.
|
||||
Thank to Wolfgang Werner (W.W.) Heinz for suggestion.
|
||||
|
||||
Improve consistency in raw (downsampled) image data processing mode.
|
||||
Thank to Zhongyuan Zhou for hint.
|
||||
|
||||
Avoid out of bounds array read (AC derived table pointers)
|
||||
in start pass in jdhuff.c. Thank to Peng Li for report.
|
||||
|
||||
Improve code sanity (jdhuff.c).
|
||||
Thank to Reza Mirzazade farkhani for reports.
|
||||
|
||||
Add jpegtran -drop option; add options to the crop extension and wipe
|
||||
to fill the extra area with content from the source image region,
|
||||
instead of gray out.
|
||||
|
||||
|
||||
Version 9c 14-Jan-2018
|
||||
-----------------------
|
||||
|
||||
|
||||
Vendored
+9
-8
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* jcarith.c
|
||||
*
|
||||
* Developed 1997-2013 by Guido Vollbeding.
|
||||
* Developed 1997-2019 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -181,11 +181,11 @@ finish_pass (j_compress_ptr cinfo)
|
||||
if (e->zc) /* output final pending zero bytes */
|
||||
do emit_byte(0x00, cinfo);
|
||||
while (--e->zc);
|
||||
emit_byte((e->c >> 19) & 0xFF, cinfo);
|
||||
emit_byte((int) ((e->c >> 19) & 0xFF), cinfo);
|
||||
if (((e->c >> 19) & 0xFF) == 0xFF)
|
||||
emit_byte(0x00, cinfo);
|
||||
if (e->c & 0x7F800L) {
|
||||
emit_byte((e->c >> 11) & 0xFF, cinfo);
|
||||
emit_byte((int) ((e->c >> 11) & 0xFF), cinfo);
|
||||
if (((e->c >> 11) & 0xFF) == 0xFF)
|
||||
emit_byte(0x00, cinfo);
|
||||
}
|
||||
@@ -280,7 +280,8 @@ arith_encode (j_compress_ptr cinfo, unsigned char *st, int val)
|
||||
/* Note: The 3 spacer bits in the C register guarantee
|
||||
* that the new buffer byte can't be 0xFF here
|
||||
* (see page 160 in the P&M JPEG book). */
|
||||
e->buffer = temp & 0xFF; /* new output byte, might overflow later */
|
||||
/* New output byte, might overflow later */
|
||||
e->buffer = (int) (temp & 0xFF);
|
||||
} else if (temp == 0xFF) {
|
||||
++e->sc; /* stack 0xFF byte (which might overflow later) */
|
||||
} else {
|
||||
@@ -302,7 +303,8 @@ arith_encode (j_compress_ptr cinfo, unsigned char *st, int val)
|
||||
emit_byte(0x00, cinfo);
|
||||
} while (--e->sc);
|
||||
}
|
||||
e->buffer = temp & 0xFF; /* new output byte (can still overflow) */
|
||||
/* New output byte (can still overflow) */
|
||||
e->buffer = (int) (temp & 0xFF);
|
||||
}
|
||||
e->c &= 0x7FFFFL;
|
||||
e->ct += 8;
|
||||
@@ -926,9 +928,8 @@ jinit_arith_encoder (j_compress_ptr cinfo)
|
||||
arith_entropy_ptr entropy;
|
||||
int i;
|
||||
|
||||
entropy = (arith_entropy_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(arith_entropy_encoder));
|
||||
entropy = (arith_entropy_ptr) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(arith_entropy_encoder));
|
||||
cinfo->entropy = &entropy->pub;
|
||||
entropy->pub.start_pass = start_pass;
|
||||
entropy->pub.finish_pass = finish_pass;
|
||||
|
||||
Vendored
+47
-50
@@ -2,7 +2,7 @@
|
||||
* jccolor.c
|
||||
*
|
||||
* Copyright (C) 1991-1996, Thomas G. Lane.
|
||||
* Modified 2011-2013 by Guido Vollbeding.
|
||||
* Modified 2011-2019 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -105,14 +105,14 @@ rgb_ycc_start (j_compress_ptr cinfo)
|
||||
/* Allocate and fill in the conversion tables. */
|
||||
cconvert->rgb_ycc_tab = rgb_ycc_tab = (INT32 *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(TABLE_SIZE * SIZEOF(INT32)));
|
||||
TABLE_SIZE * SIZEOF(INT32));
|
||||
|
||||
for (i = 0; i <= MAXJSAMPLE; i++) {
|
||||
rgb_ycc_tab[i+R_Y_OFF] = FIX(0.299) * i;
|
||||
rgb_ycc_tab[i+G_Y_OFF] = FIX(0.587) * i;
|
||||
rgb_ycc_tab[i+B_Y_OFF] = FIX(0.114) * i + ONE_HALF;
|
||||
rgb_ycc_tab[i+R_CB_OFF] = (-FIX(0.168735892)) * i;
|
||||
rgb_ycc_tab[i+G_CB_OFF] = (-FIX(0.331264108)) * i;
|
||||
rgb_ycc_tab[i+R_CB_OFF] = (- FIX(0.168735892)) * i;
|
||||
rgb_ycc_tab[i+G_CB_OFF] = (- FIX(0.331264108)) * i;
|
||||
/* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr.
|
||||
* This ensures that the maximum output will round to MAXJSAMPLE
|
||||
* not MAXJSAMPLE+1, and thus that we don't have to range-limit.
|
||||
@@ -121,8 +121,8 @@ rgb_ycc_start (j_compress_ptr cinfo)
|
||||
/* B=>Cb and R=>Cr tables are the same
|
||||
rgb_ycc_tab[i+R_CR_OFF] = FIX(0.5) * i + CBCR_OFFSET + ONE_HALF-1;
|
||||
*/
|
||||
rgb_ycc_tab[i+G_CR_OFF] = (-FIX(0.418687589)) * i;
|
||||
rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.081312411)) * i;
|
||||
rgb_ycc_tab[i+G_CR_OFF] = (- FIX(0.418687589)) * i;
|
||||
rgb_ycc_tab[i+B_CR_OFF] = (- FIX(0.081312411)) * i;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,12 +131,12 @@ rgb_ycc_start (j_compress_ptr cinfo)
|
||||
* Convert some rows of samples to the JPEG colorspace.
|
||||
*
|
||||
* Note that we change from the application's interleaved-pixel format
|
||||
* to our internal noninterleaved, one-plane-per-component format.
|
||||
* The input buffer is therefore three times as wide as the output buffer.
|
||||
* to our internal noninterleaved, one-plane-per-component format. The
|
||||
* input buffer is therefore three times as wide as the output buffer.
|
||||
*
|
||||
* A starting row offset is provided only for the output buffer. The caller
|
||||
* can easily adjust the passed input_buf value to accommodate any row
|
||||
* offset required on that side.
|
||||
* A starting row offset is provided only for the output buffer. The
|
||||
* caller can easily adjust the passed input_buf value to accommodate
|
||||
* any row offset required on that side.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
@@ -145,8 +145,8 @@ rgb_ycc_convert (j_compress_ptr cinfo,
|
||||
JDIMENSION output_row, int num_rows)
|
||||
{
|
||||
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
|
||||
register INT32 * ctab = cconvert->rgb_ycc_tab;
|
||||
register int r, g, b;
|
||||
register INT32 * ctab = cconvert->rgb_ycc_tab;
|
||||
register JSAMPROW inptr;
|
||||
register JSAMPROW outptr0, outptr1, outptr2;
|
||||
register JDIMENSION col;
|
||||
@@ -162,6 +162,7 @@ rgb_ycc_convert (j_compress_ptr cinfo,
|
||||
r = GETJSAMPLE(inptr[RGB_RED]);
|
||||
g = GETJSAMPLE(inptr[RGB_GREEN]);
|
||||
b = GETJSAMPLE(inptr[RGB_BLUE]);
|
||||
inptr += RGB_PIXELSIZE;
|
||||
/* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
|
||||
* must be too; we do not need an explicit range-limiting operation.
|
||||
* Hence the value being shifted is never negative, and we don't
|
||||
@@ -179,7 +180,6 @@ rgb_ycc_convert (j_compress_ptr cinfo,
|
||||
outptr2[col] = (JSAMPLE)
|
||||
((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
|
||||
>> SCALEBITS);
|
||||
inptr += RGB_PIXELSIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -201,8 +201,8 @@ rgb_gray_convert (j_compress_ptr cinfo,
|
||||
JDIMENSION output_row, int num_rows)
|
||||
{
|
||||
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
|
||||
register INT32 * ctab = cconvert->rgb_ycc_tab;
|
||||
register int r, g, b;
|
||||
register INT32 * ctab = cconvert->rgb_ycc_tab;
|
||||
register JSAMPROW inptr;
|
||||
register JSAMPROW outptr;
|
||||
register JDIMENSION col;
|
||||
@@ -215,11 +215,11 @@ rgb_gray_convert (j_compress_ptr cinfo,
|
||||
r = GETJSAMPLE(inptr[RGB_RED]);
|
||||
g = GETJSAMPLE(inptr[RGB_GREEN]);
|
||||
b = GETJSAMPLE(inptr[RGB_BLUE]);
|
||||
inptr += RGB_PIXELSIZE;
|
||||
/* Y */
|
||||
outptr[col] = (JSAMPLE)
|
||||
((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
|
||||
>> SCALEBITS);
|
||||
inptr += RGB_PIXELSIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -228,8 +228,8 @@ rgb_gray_convert (j_compress_ptr cinfo,
|
||||
/*
|
||||
* Convert some rows of samples to the JPEG colorspace.
|
||||
* This version handles Adobe-style CMYK->YCCK conversion,
|
||||
* where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the same
|
||||
* conversion as above, while passing K (black) unchanged.
|
||||
* where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the
|
||||
* same conversion as above, while passing K (black) unchanged.
|
||||
* We assume rgb_ycc_start has been called.
|
||||
*/
|
||||
|
||||
@@ -239,8 +239,8 @@ cmyk_ycck_convert (j_compress_ptr cinfo,
|
||||
JDIMENSION output_row, int num_rows)
|
||||
{
|
||||
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
|
||||
register INT32 * ctab = cconvert->rgb_ycc_tab;
|
||||
register int r, g, b;
|
||||
register INT32 * ctab = cconvert->rgb_ycc_tab;
|
||||
register JSAMPROW inptr;
|
||||
register JSAMPROW outptr0, outptr1, outptr2, outptr3;
|
||||
register JDIMENSION col;
|
||||
@@ -259,6 +259,7 @@ cmyk_ycck_convert (j_compress_ptr cinfo,
|
||||
b = MAXJSAMPLE - GETJSAMPLE(inptr[2]);
|
||||
/* K passes through as-is */
|
||||
outptr3[col] = inptr[3]; /* don't need GETJSAMPLE here */
|
||||
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.
|
||||
* Hence the value being shifted is never negative, and we don't
|
||||
@@ -276,7 +277,6 @@ cmyk_ycck_convert (j_compress_ptr cinfo,
|
||||
outptr2[col] = (JSAMPLE)
|
||||
((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
|
||||
>> SCALEBITS);
|
||||
inptr += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -312,13 +312,13 @@ rgb_rgb1_convert (j_compress_ptr cinfo,
|
||||
r = GETJSAMPLE(inptr[RGB_RED]);
|
||||
g = GETJSAMPLE(inptr[RGB_GREEN]);
|
||||
b = GETJSAMPLE(inptr[RGB_BLUE]);
|
||||
inptr += RGB_PIXELSIZE;
|
||||
/* Assume that MAXJSAMPLE+1 is a power of 2, so that the MOD
|
||||
* (modulo) operator is equivalent to the bitmask operator AND.
|
||||
*/
|
||||
outptr0[col] = (JSAMPLE) ((r - g + CENTERJSAMPLE) & MAXJSAMPLE);
|
||||
outptr1[col] = (JSAMPLE) g;
|
||||
outptr2[col] = (JSAMPLE) ((b - g + CENTERJSAMPLE) & MAXJSAMPLE);
|
||||
inptr += RGB_PIXELSIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -335,17 +335,17 @@ grayscale_convert (j_compress_ptr cinfo,
|
||||
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
|
||||
JDIMENSION output_row, int num_rows)
|
||||
{
|
||||
int instride = cinfo->input_components;
|
||||
register JSAMPROW inptr;
|
||||
register JSAMPROW outptr;
|
||||
register JDIMENSION col;
|
||||
register JDIMENSION count;
|
||||
register int instride = cinfo->input_components;
|
||||
JDIMENSION num_cols = cinfo->image_width;
|
||||
|
||||
while (--num_rows >= 0) {
|
||||
inptr = *input_buf++;
|
||||
outptr = output_buf[0][output_row++];
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
outptr[col] = inptr[0]; /* don't need GETJSAMPLE() here */
|
||||
for (count = num_cols; count > 0; count--) {
|
||||
*outptr++ = *inptr; /* don't need GETJSAMPLE() here */
|
||||
inptr += instride;
|
||||
}
|
||||
}
|
||||
@@ -396,21 +396,21 @@ null_convert (j_compress_ptr cinfo,
|
||||
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
|
||||
JDIMENSION output_row, int num_rows)
|
||||
{
|
||||
int ci;
|
||||
register int nc = cinfo->num_components;
|
||||
register JSAMPROW inptr;
|
||||
register JSAMPROW outptr;
|
||||
register JDIMENSION col;
|
||||
register JDIMENSION count;
|
||||
register int num_comps = cinfo->num_components;
|
||||
JDIMENSION num_cols = cinfo->image_width;
|
||||
int ci;
|
||||
|
||||
while (--num_rows >= 0) {
|
||||
/* It seems fastest to make a separate pass for each component. */
|
||||
for (ci = 0; ci < nc; ci++) {
|
||||
for (ci = 0; ci < num_comps; ci++) {
|
||||
inptr = input_buf[0] + ci;
|
||||
outptr = output_buf[ci][output_row];
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
for (count = num_cols; count > 0; count--) {
|
||||
*outptr++ = *inptr; /* don't need GETJSAMPLE() here */
|
||||
inptr += nc;
|
||||
inptr += num_comps;
|
||||
}
|
||||
}
|
||||
input_buf++;
|
||||
@@ -439,9 +439,8 @@ jinit_color_converter (j_compress_ptr cinfo)
|
||||
{
|
||||
my_cconvert_ptr cconvert;
|
||||
|
||||
cconvert = (my_cconvert_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(my_color_converter));
|
||||
cconvert = (my_cconvert_ptr) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_color_converter));
|
||||
cinfo->cconvert = &cconvert->pub;
|
||||
/* set start_pass to null method until we find out differently */
|
||||
cconvert->pub.start_pass = null_method;
|
||||
@@ -455,9 +454,11 @@ jinit_color_converter (j_compress_ptr cinfo)
|
||||
|
||||
case JCS_RGB:
|
||||
case JCS_BG_RGB:
|
||||
#if RGB_PIXELSIZE != 3
|
||||
if (cinfo->input_components != RGB_PIXELSIZE)
|
||||
ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
|
||||
break;
|
||||
#endif /* else share code with YCbCr */
|
||||
|
||||
case JCS_YCbCr:
|
||||
case JCS_BG_YCC:
|
||||
@@ -474,7 +475,6 @@ jinit_color_converter (j_compress_ptr cinfo)
|
||||
default: /* JCS_UNKNOWN can be anything */
|
||||
if (cinfo->input_components < 1)
|
||||
ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Support color transform only for RGB colorspaces */
|
||||
@@ -507,19 +507,18 @@ jinit_color_converter (j_compress_ptr cinfo)
|
||||
case JCS_BG_RGB:
|
||||
if (cinfo->num_components != 3)
|
||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
||||
if (cinfo->in_color_space == cinfo->jpeg_color_space) {
|
||||
switch (cinfo->color_transform) {
|
||||
case JCT_NONE:
|
||||
cconvert->pub.color_convert = rgb_convert;
|
||||
break;
|
||||
case JCT_SUBTRACT_GREEN:
|
||||
cconvert->pub.color_convert = rgb_rgb1_convert;
|
||||
break;
|
||||
default:
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
}
|
||||
} else
|
||||
if (cinfo->in_color_space != cinfo->jpeg_color_space)
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
switch (cinfo->color_transform) {
|
||||
case JCT_NONE:
|
||||
cconvert->pub.color_convert = rgb_convert;
|
||||
break;
|
||||
case JCT_SUBTRACT_GREEN:
|
||||
cconvert->pub.color_convert = rgb_rgb1_convert;
|
||||
break;
|
||||
default:
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
}
|
||||
break;
|
||||
|
||||
case JCS_YCbCr:
|
||||
@@ -572,10 +571,9 @@ jinit_color_converter (j_compress_ptr cinfo)
|
||||
case JCS_CMYK:
|
||||
if (cinfo->num_components != 4)
|
||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
||||
if (cinfo->in_color_space == JCS_CMYK)
|
||||
cconvert->pub.color_convert = null_convert;
|
||||
else
|
||||
if (cinfo->in_color_space != JCS_CMYK)
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
cconvert->pub.color_convert = null_convert;
|
||||
break;
|
||||
|
||||
case JCS_YCCK:
|
||||
@@ -599,6 +597,5 @@ jinit_color_converter (j_compress_ptr cinfo)
|
||||
cinfo->num_components != cinfo->input_components)
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
cconvert->pub.color_convert = null_convert;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+109
-42
@@ -2,7 +2,7 @@
|
||||
* jchuff.c
|
||||
*
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Modified 2006-2013 by Guido Vollbeding.
|
||||
* Modified 2006-2019 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -178,13 +178,12 @@ jpeg_make_c_derived_tbl (j_compress_ptr cinfo, boolean isDC, int tblno,
|
||||
htbl =
|
||||
isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno];
|
||||
if (htbl == NULL)
|
||||
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
|
||||
htbl = jpeg_std_huff_table((j_common_ptr) cinfo, isDC, tblno);
|
||||
|
||||
/* Allocate a workspace if we haven't already done so. */
|
||||
if (*pdtbl == NULL)
|
||||
*pdtbl = (c_derived_tbl *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(c_derived_tbl));
|
||||
*pdtbl = (c_derived_tbl *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(c_derived_tbl));
|
||||
dtbl = *pdtbl;
|
||||
|
||||
/* Figure C.1: make table of Huffman code length for each symbol */
|
||||
@@ -1256,22 +1255,88 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
|
||||
UINT8 bits[MAX_CLEN+1]; /* bits[k] = # of symbols with code length k */
|
||||
int codesize[257]; /* codesize[k] = code length of symbol k */
|
||||
int others[257]; /* next symbol in current branch of tree */
|
||||
int c1, c2;
|
||||
int p, i, j;
|
||||
int c1, c2, i, j;
|
||||
UINT8 *p;
|
||||
long v;
|
||||
|
||||
freq[256] = 1; /* make sure 256 has a nonzero count */
|
||||
/* Including the pseudo-symbol 256 in the Huffman procedure guarantees
|
||||
* that no real symbol is given code-value of all ones, because 256
|
||||
* will be placed last in the largest codeword category.
|
||||
* In the symbol list build procedure this element serves as sentinel
|
||||
* for the zero run loop.
|
||||
*/
|
||||
|
||||
#ifndef DONT_USE_FANCY_HUFF_OPT
|
||||
|
||||
/* Build list of symbols sorted in order of descending frequency */
|
||||
/* This approach has several benefits (thank to John Korejwa for the idea):
|
||||
* 1.
|
||||
* If a codelength category is split during the length limiting procedure
|
||||
* below, the feature that more frequent symbols are assigned shorter
|
||||
* codewords remains valid for the adjusted code.
|
||||
* 2.
|
||||
* To reduce consecutive ones in a Huffman data stream (thus reducing the
|
||||
* number of stuff bytes in JPEG) it is preferable to follow 0 branches
|
||||
* (and avoid 1 branches) as much as possible. This is easily done by
|
||||
* assigning symbols to leaves of the Huffman tree in order of decreasing
|
||||
* frequency, with no secondary sort based on codelengths.
|
||||
* 3.
|
||||
* The symbol list can be built independently from the assignment of code
|
||||
* lengths by the Huffman procedure below.
|
||||
* Note: The symbol list build procedure must be performed first, because
|
||||
* the Huffman procedure assigning the codelengths clobbers the frequency
|
||||
* counts!
|
||||
*/
|
||||
|
||||
/* Here we use the others array as a linked list of nonzero frequencies
|
||||
* to be sorted. Already sorted elements are removed from the list.
|
||||
*/
|
||||
|
||||
/* Building list */
|
||||
|
||||
/* This item does not correspond to a valid symbol frequency and is used
|
||||
* as starting index.
|
||||
*/
|
||||
j = 256;
|
||||
|
||||
for (i = 0;; i++) {
|
||||
if (freq[i] == 0) /* skip zero frequencies */
|
||||
continue;
|
||||
if (i > 255)
|
||||
break;
|
||||
others[j] = i; /* this symbol value */
|
||||
j = i; /* previous symbol value */
|
||||
}
|
||||
others[j] = -1; /* mark end of list */
|
||||
|
||||
/* Sorting list */
|
||||
|
||||
p = htbl->huffval;
|
||||
while ((c1 = others[256]) >= 0) {
|
||||
v = freq[c1];
|
||||
i = c1; /* first symbol value */
|
||||
j = 256; /* pseudo symbol value for starting index */
|
||||
while ((c2 = others[c1]) >= 0) {
|
||||
if (freq[c2] > v) {
|
||||
v = freq[c2];
|
||||
i = c2; /* this symbol value */
|
||||
j = c1; /* previous symbol value */
|
||||
}
|
||||
c1 = c2;
|
||||
}
|
||||
others[j] = others[i]; /* remove this symbol i from list */
|
||||
*p++ = (UINT8) i;
|
||||
}
|
||||
|
||||
#endif /* DONT_USE_FANCY_HUFF_OPT */
|
||||
|
||||
/* This algorithm is explained in section K.2 of the JPEG standard */
|
||||
|
||||
MEMZERO(bits, SIZEOF(bits));
|
||||
MEMZERO(codesize, SIZEOF(codesize));
|
||||
for (i = 0; i < 257; i++)
|
||||
others[i] = -1; /* init links to empty */
|
||||
|
||||
freq[256] = 1; /* make sure 256 has a nonzero count */
|
||||
/* Including the pseudo-symbol 256 in the Huffman procedure guarantees
|
||||
* that no real symbol is given code-value of all ones, because 256
|
||||
* will be placed last in the largest codeword category.
|
||||
*/
|
||||
|
||||
/* Huffman's basic algorithm to assign optimal code lengths to symbols */
|
||||
|
||||
@@ -1301,7 +1366,7 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
|
||||
/* Done if we've merged everything into one frequency */
|
||||
if (c2 < 0)
|
||||
break;
|
||||
|
||||
|
||||
/* Else merge the two counts/trees */
|
||||
freq[c1] += freq[c2];
|
||||
freq[c2] = 0;
|
||||
@@ -1312,9 +1377,9 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
|
||||
c1 = others[c1];
|
||||
codesize[c1]++;
|
||||
}
|
||||
|
||||
|
||||
others[c1] = c2; /* chain c2 onto c1's tree branch */
|
||||
|
||||
|
||||
/* Increment the codesize of everything in c2's tree branch */
|
||||
codesize[c2]++;
|
||||
while (others[c2] >= 0) {
|
||||
@@ -1329,7 +1394,7 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
|
||||
/* The JPEG standard seems to think that this can't happen, */
|
||||
/* but I'm paranoid... */
|
||||
if (codesize[i] > MAX_CLEN)
|
||||
ERREXIT(cinfo, JERR_HUFF_CLEN_OVERFLOW);
|
||||
ERREXIT(cinfo, JERR_HUFF_CLEN_OUTOFBOUNDS);
|
||||
|
||||
bits[codesize[i]]++;
|
||||
}
|
||||
@@ -1345,13 +1410,16 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
|
||||
* shortest nonzero BITS entry is converted into a prefix for two code words
|
||||
* one bit longer.
|
||||
*/
|
||||
|
||||
|
||||
for (i = MAX_CLEN; i > 16; i--) {
|
||||
while (bits[i] > 0) {
|
||||
j = i - 2; /* find length of new prefix to be used */
|
||||
while (bits[j] == 0)
|
||||
while (bits[j] == 0) {
|
||||
if (j == 0)
|
||||
ERREXIT(cinfo, JERR_HUFF_CLEN_OUTOFBOUNDS);
|
||||
j--;
|
||||
|
||||
}
|
||||
|
||||
bits[i] -= 2; /* remove two symbols */
|
||||
bits[i-1]++; /* one goes in this length */
|
||||
bits[j+1] += 2; /* two new symbols in this length */
|
||||
@@ -1363,24 +1431,27 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
|
||||
while (bits[i] == 0) /* find largest codelength still in use */
|
||||
i--;
|
||||
bits[i]--;
|
||||
|
||||
|
||||
/* Return final symbol counts (only for lengths 0..16) */
|
||||
MEMCOPY(htbl->bits, bits, SIZEOF(htbl->bits));
|
||||
|
||||
|
||||
#ifdef DONT_USE_FANCY_HUFF_OPT
|
||||
|
||||
/* Return a list of the symbols sorted by code length */
|
||||
/* It's not real clear to me why we don't need to consider the codelength
|
||||
* changes made above, but the JPEG spec seems to think this works.
|
||||
/* Note: Due to the codelength changes made above, it can happen
|
||||
* that more frequent symbols are assigned longer codewords.
|
||||
*/
|
||||
p = 0;
|
||||
p = htbl->huffval;
|
||||
for (i = 1; i <= MAX_CLEN; i++) {
|
||||
for (j = 0; j <= 255; j++) {
|
||||
if (codesize[j] == i) {
|
||||
htbl->huffval[p] = (UINT8) j;
|
||||
p++;
|
||||
*p++ = (UINT8) j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DONT_USE_FANCY_HUFF_OPT */
|
||||
|
||||
/* Set sent_table FALSE so updated table will be written to JPEG file. */
|
||||
htbl->sent_table = FALSE;
|
||||
}
|
||||
@@ -1400,13 +1471,13 @@ finish_pass_gather (j_compress_ptr cinfo)
|
||||
boolean did_dc[NUM_HUFF_TBLS];
|
||||
boolean did_ac[NUM_HUFF_TBLS];
|
||||
|
||||
/* It's important not to apply jpeg_gen_optimal_table more than once
|
||||
* per table, because it clobbers the input frequency counts!
|
||||
*/
|
||||
if (cinfo->progressive_mode)
|
||||
/* Flush out buffered data (all we care about is counting the EOB symbol) */
|
||||
emit_eobrun(entropy);
|
||||
|
||||
/* It's important not to apply jpeg_gen_optimal_table more than once
|
||||
* per table, because it clobbers the input frequency counts!
|
||||
*/
|
||||
MEMZERO(did_dc, SIZEOF(did_dc));
|
||||
MEMZERO(did_ac, SIZEOF(did_ac));
|
||||
|
||||
@@ -1475,9 +1546,8 @@ start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics)
|
||||
entropy->pub.encode_mcu = encode_mcu_AC_refine;
|
||||
/* AC refinement needs a correction bit buffer */
|
||||
if (entropy->bit_buffer == NULL)
|
||||
entropy->bit_buffer = (char *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
MAX_CORR_BITS * SIZEOF(char));
|
||||
entropy->bit_buffer = (char *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, MAX_CORR_BITS * SIZEOF(char));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1505,9 +1575,8 @@ start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics)
|
||||
/* Allocate and zero the statistics tables */
|
||||
/* Note that jpeg_gen_optimal_table expects 257 entries in each table! */
|
||||
if (entropy->dc_count_ptrs[tbl] == NULL)
|
||||
entropy->dc_count_ptrs[tbl] = (long *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
257 * SIZEOF(long));
|
||||
entropy->dc_count_ptrs[tbl] = (long *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, 257 * SIZEOF(long));
|
||||
MEMZERO(entropy->dc_count_ptrs[tbl], 257 * SIZEOF(long));
|
||||
} else {
|
||||
/* Compute derived values for Huffman tables */
|
||||
@@ -1525,9 +1594,8 @@ start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics)
|
||||
if (tbl < 0 || tbl >= NUM_HUFF_TBLS)
|
||||
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl);
|
||||
if (entropy->ac_count_ptrs[tbl] == NULL)
|
||||
entropy->ac_count_ptrs[tbl] = (long *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
257 * SIZEOF(long));
|
||||
entropy->ac_count_ptrs[tbl] = (long *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, 257 * SIZEOF(long));
|
||||
MEMZERO(entropy->ac_count_ptrs[tbl], 257 * SIZEOF(long));
|
||||
} else {
|
||||
jpeg_make_c_derived_tbl(cinfo, FALSE, tbl,
|
||||
@@ -1556,9 +1624,8 @@ jinit_huff_encoder (j_compress_ptr cinfo)
|
||||
huff_entropy_ptr entropy;
|
||||
int i;
|
||||
|
||||
entropy = (huff_entropy_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(huff_entropy_encoder));
|
||||
entropy = (huff_entropy_ptr) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(huff_entropy_encoder));
|
||||
cinfo->entropy = &entropy->pub;
|
||||
entropy->pub.start_pass = start_pass_huff;
|
||||
|
||||
|
||||
Vendored
+3
-5
@@ -2,7 +2,7 @@
|
||||
* jcmarker.c
|
||||
*
|
||||
* Copyright (C) 1991-1998, Thomas G. Lane.
|
||||
* Modified 2003-2013 by Guido Vollbeding.
|
||||
* Modified 2003-2019 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -471,7 +471,6 @@ emit_adobe_app14 (j_compress_ptr cinfo)
|
||||
break;
|
||||
default:
|
||||
emit_byte(cinfo, 0); /* Color transform = 0 */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -702,9 +701,8 @@ jinit_marker_writer (j_compress_ptr cinfo)
|
||||
my_marker_ptr marker;
|
||||
|
||||
/* Create the subobject */
|
||||
marker = (my_marker_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(my_marker_writer));
|
||||
marker = (my_marker_ptr) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_marker_writer));
|
||||
cinfo->marker = &marker->pub;
|
||||
/* Initialize method pointers */
|
||||
marker->pub.write_file_header = write_file_header;
|
||||
|
||||
Vendored
+18
-15
@@ -2,7 +2,7 @@
|
||||
* jcmaster.c
|
||||
*
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Modified 2003-2017 by Guido Vollbeding.
|
||||
* Modified 2003-2019 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -62,7 +62,7 @@ initial_setup (j_compress_ptr cinfo)
|
||||
case 5: cinfo->natural_order = jpeg_natural_order5; break;
|
||||
case 6: cinfo->natural_order = jpeg_natural_order6; break;
|
||||
case 7: cinfo->natural_order = jpeg_natural_order7; break;
|
||||
default: cinfo->natural_order = jpeg_natural_order; break;
|
||||
default: cinfo->natural_order = jpeg_natural_order;
|
||||
}
|
||||
|
||||
/* Derive lim_Se from block_size */
|
||||
@@ -114,20 +114,24 @@ initial_setup (j_compress_ptr cinfo)
|
||||
*/
|
||||
ssize = 1;
|
||||
#ifdef DCT_SCALING_SUPPORTED
|
||||
while (cinfo->min_DCT_h_scaled_size * ssize <=
|
||||
(cinfo->do_fancy_downsampling ? DCTSIZE : DCTSIZE / 2) &&
|
||||
(cinfo->max_h_samp_factor % (compptr->h_samp_factor * ssize * 2)) == 0) {
|
||||
ssize = ssize * 2;
|
||||
}
|
||||
if (! cinfo->raw_data_in)
|
||||
while (cinfo->min_DCT_h_scaled_size * ssize <=
|
||||
(cinfo->do_fancy_downsampling ? DCTSIZE : DCTSIZE / 2) &&
|
||||
(cinfo->max_h_samp_factor % (compptr->h_samp_factor * ssize * 2)) ==
|
||||
0) {
|
||||
ssize = ssize * 2;
|
||||
}
|
||||
#endif
|
||||
compptr->DCT_h_scaled_size = cinfo->min_DCT_h_scaled_size * ssize;
|
||||
ssize = 1;
|
||||
#ifdef DCT_SCALING_SUPPORTED
|
||||
while (cinfo->min_DCT_v_scaled_size * ssize <=
|
||||
(cinfo->do_fancy_downsampling ? DCTSIZE : DCTSIZE / 2) &&
|
||||
(cinfo->max_v_samp_factor % (compptr->v_samp_factor * ssize * 2)) == 0) {
|
||||
ssize = ssize * 2;
|
||||
}
|
||||
if (! cinfo->raw_data_in)
|
||||
while (cinfo->min_DCT_v_scaled_size * ssize <=
|
||||
(cinfo->do_fancy_downsampling ? DCTSIZE : DCTSIZE / 2) &&
|
||||
(cinfo->max_v_samp_factor % (compptr->v_samp_factor * ssize * 2)) ==
|
||||
0) {
|
||||
ssize = ssize * 2;
|
||||
}
|
||||
#endif
|
||||
compptr->DCT_v_scaled_size = cinfo->min_DCT_v_scaled_size * ssize;
|
||||
|
||||
@@ -620,9 +624,8 @@ jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only)
|
||||
{
|
||||
my_master_ptr master;
|
||||
|
||||
master = (my_master_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(my_comp_master));
|
||||
master = (my_master_ptr) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_comp_master));
|
||||
cinfo->master = &master->pub;
|
||||
master->pub.prepare_for_pass = prepare_for_pass;
|
||||
master->pub.pass_startup = pass_startup;
|
||||
|
||||
Vendored
+138
@@ -2,6 +2,7 @@
|
||||
* jcomapi.c
|
||||
*
|
||||
* Copyright (C) 1994-1997, Thomas G. Lane.
|
||||
* Modified 2019 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -104,3 +105,140 @@ jpeg_alloc_huff_table (j_common_ptr cinfo)
|
||||
tbl->sent_table = FALSE; /* make sure this is false in any new table */
|
||||
return tbl;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set up the standard Huffman tables (cf. JPEG standard section K.3).
|
||||
* IMPORTANT: these are only valid for 8-bit data precision!
|
||||
* (Would jutils.c be a more reasonable place to put this?)
|
||||
*/
|
||||
|
||||
GLOBAL(JHUFF_TBL *)
|
||||
jpeg_std_huff_table (j_common_ptr cinfo, boolean isDC, int tblno)
|
||||
{
|
||||
JHUFF_TBL **htblptr, *htbl;
|
||||
const UINT8 *bits, *val;
|
||||
int nsymbols, len;
|
||||
|
||||
static const UINT8 bits_dc_luminance[17] =
|
||||
{ /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
|
||||
static const UINT8 val_dc_luminance[] =
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
|
||||
|
||||
static const UINT8 bits_dc_chrominance[17] =
|
||||
{ /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
|
||||
static const UINT8 val_dc_chrominance[] =
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
|
||||
|
||||
static const UINT8 bits_ac_luminance[17] =
|
||||
{ /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
|
||||
static const UINT8 val_ac_luminance[] =
|
||||
{ 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
|
||||
0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
|
||||
0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
|
||||
0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
|
||||
0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
|
||||
0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
|
||||
0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
|
||||
0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
|
||||
0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
|
||||
0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
|
||||
0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
|
||||
0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
|
||||
0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
|
||||
0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
|
||||
0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
|
||||
0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
|
||||
0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
|
||||
0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
|
||||
0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
|
||||
0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
|
||||
0xf9, 0xfa };
|
||||
|
||||
static const UINT8 bits_ac_chrominance[17] =
|
||||
{ /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
|
||||
static const UINT8 val_ac_chrominance[] =
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
|
||||
0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
|
||||
0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
|
||||
0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
|
||||
0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
|
||||
0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
|
||||
0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
|
||||
0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
|
||||
0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
|
||||
0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
|
||||
0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
|
||||
0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
|
||||
0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
|
||||
0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
|
||||
0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
|
||||
0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
|
||||
0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
|
||||
0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
|
||||
0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
|
||||
0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
|
||||
0xf9, 0xfa };
|
||||
|
||||
if (cinfo->is_decompressor) {
|
||||
if (isDC)
|
||||
htblptr = ((j_decompress_ptr) cinfo)->dc_huff_tbl_ptrs;
|
||||
else
|
||||
htblptr = ((j_decompress_ptr) cinfo)->ac_huff_tbl_ptrs;
|
||||
} else {
|
||||
if (isDC)
|
||||
htblptr = ((j_compress_ptr) cinfo)->dc_huff_tbl_ptrs;
|
||||
else
|
||||
htblptr = ((j_compress_ptr) cinfo)->ac_huff_tbl_ptrs;
|
||||
}
|
||||
|
||||
switch (tblno) {
|
||||
case 0:
|
||||
if (isDC) {
|
||||
bits = bits_dc_luminance;
|
||||
val = val_dc_luminance;
|
||||
} else {
|
||||
bits = bits_ac_luminance;
|
||||
val = val_ac_luminance;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (isDC) {
|
||||
bits = bits_dc_chrominance;
|
||||
val = val_dc_chrominance;
|
||||
} else {
|
||||
bits = bits_ac_chrominance;
|
||||
val = val_ac_chrominance;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
|
||||
return NULL; /* avoid compiler warnings for uninitialized variables */
|
||||
}
|
||||
|
||||
if (htblptr[tblno] == NULL)
|
||||
htblptr[tblno] = jpeg_alloc_huff_table(cinfo);
|
||||
|
||||
htbl = htblptr[tblno];
|
||||
|
||||
/* Copy the number-of-symbols-of-each-code-length counts */
|
||||
MEMCOPY(htbl->bits, bits, SIZEOF(htbl->bits));
|
||||
|
||||
/* Validate the counts. We do this here mainly so we can copy the right
|
||||
* number of symbols from the val[] array, without risking marching off
|
||||
* the end of memory. jxhuff.c will do a more thorough test later.
|
||||
*/
|
||||
nsymbols = 0;
|
||||
for (len = 1; len <= 16; len++)
|
||||
nsymbols += bits[len];
|
||||
if (nsymbols > 256)
|
||||
ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
|
||||
|
||||
if (nsymbols > 0)
|
||||
MEMCOPY(htbl->huffval, val, nsymbols * SIZEOF(UINT8));
|
||||
|
||||
/* Initialize sent_table FALSE so table will be written to JPEG file. */
|
||||
htbl->sent_table = FALSE;
|
||||
|
||||
return htbl;
|
||||
}
|
||||
|
||||
Vendored
+14
-103
@@ -2,7 +2,7 @@
|
||||
* jcparam.c
|
||||
*
|
||||
* Copyright (C) 1991-1998, Thomas G. Lane.
|
||||
* Modified 2003-2013 by Guido Vollbeding.
|
||||
* Modified 2003-2019 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -162,112 +162,23 @@ jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline)
|
||||
|
||||
|
||||
/*
|
||||
* Huffman table setup routines
|
||||
* Reset standard Huffman tables
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
add_huff_table (j_compress_ptr cinfo,
|
||||
JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val)
|
||||
/* Define a Huffman table */
|
||||
{
|
||||
int nsymbols, len;
|
||||
|
||||
if (*htblptr == NULL)
|
||||
*htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
|
||||
|
||||
/* Copy the number-of-symbols-of-each-code-length counts */
|
||||
MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits));
|
||||
|
||||
/* Validate the counts. We do this here mainly so we can copy the right
|
||||
* number of symbols from the val[] array, without risking marching off
|
||||
* the end of memory. jchuff.c will do a more thorough test later.
|
||||
*/
|
||||
nsymbols = 0;
|
||||
for (len = 1; len <= 16; len++)
|
||||
nsymbols += bits[len];
|
||||
if (nsymbols < 1 || nsymbols > 256)
|
||||
ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
|
||||
|
||||
MEMCOPY((*htblptr)->huffval, val, nsymbols * SIZEOF(UINT8));
|
||||
|
||||
/* Initialize sent_table FALSE so table will be written to JPEG file. */
|
||||
(*htblptr)->sent_table = FALSE;
|
||||
}
|
||||
|
||||
|
||||
LOCAL(void)
|
||||
std_huff_tables (j_compress_ptr cinfo)
|
||||
/* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
|
||||
/* IMPORTANT: these are only valid for 8-bit data precision! */
|
||||
{
|
||||
static const UINT8 bits_dc_luminance[17] =
|
||||
{ /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
|
||||
static const UINT8 val_dc_luminance[] =
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
|
||||
|
||||
static const UINT8 bits_dc_chrominance[17] =
|
||||
{ /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
|
||||
static const UINT8 val_dc_chrominance[] =
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
|
||||
|
||||
static const UINT8 bits_ac_luminance[17] =
|
||||
{ /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
|
||||
static const UINT8 val_ac_luminance[] =
|
||||
{ 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
|
||||
0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
|
||||
0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
|
||||
0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
|
||||
0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
|
||||
0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
|
||||
0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
|
||||
0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
|
||||
0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
|
||||
0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
|
||||
0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
|
||||
0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
|
||||
0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
|
||||
0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
|
||||
0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
|
||||
0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
|
||||
0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
|
||||
0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
|
||||
0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
|
||||
0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
|
||||
0xf9, 0xfa };
|
||||
|
||||
static const UINT8 bits_ac_chrominance[17] =
|
||||
{ /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
|
||||
static const UINT8 val_ac_chrominance[] =
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
|
||||
0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
|
||||
0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
|
||||
0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
|
||||
0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
|
||||
0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
|
||||
0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
|
||||
0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
|
||||
0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
|
||||
0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
|
||||
0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
|
||||
0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
|
||||
0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
|
||||
0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
|
||||
0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
|
||||
0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
|
||||
0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
|
||||
0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
|
||||
0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
|
||||
0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
|
||||
0xf9, 0xfa };
|
||||
|
||||
add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[0],
|
||||
bits_dc_luminance, val_dc_luminance);
|
||||
add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[0],
|
||||
bits_ac_luminance, val_ac_luminance);
|
||||
add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[1],
|
||||
bits_dc_chrominance, val_dc_chrominance);
|
||||
add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[1],
|
||||
bits_ac_chrominance, val_ac_chrominance);
|
||||
if (cinfo->dc_huff_tbl_ptrs[0] != NULL)
|
||||
(void) jpeg_std_huff_table((j_common_ptr) cinfo, TRUE, 0);
|
||||
|
||||
if (cinfo->ac_huff_tbl_ptrs[0] != NULL)
|
||||
(void) jpeg_std_huff_table((j_common_ptr) cinfo, FALSE, 0);
|
||||
|
||||
if (cinfo->dc_huff_tbl_ptrs[1] != NULL)
|
||||
(void) jpeg_std_huff_table((j_common_ptr) cinfo, TRUE, 1);
|
||||
|
||||
if (cinfo->ac_huff_tbl_ptrs[1] != NULL)
|
||||
(void) jpeg_std_huff_table((j_common_ptr) cinfo, FALSE, 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -306,7 +217,7 @@ jpeg_set_defaults (j_compress_ptr cinfo)
|
||||
cinfo->data_precision = BITS_IN_JSAMPLE;
|
||||
/* Set up two quantization tables using default quality of 75 */
|
||||
jpeg_set_quality(cinfo, 75, TRUE);
|
||||
/* Set up two Huffman tables */
|
||||
/* Reset standard Huffman tables */
|
||||
std_huff_tables(cinfo);
|
||||
|
||||
/* Initialize default arithmetic coding conditioning */
|
||||
|
||||
Vendored
+14
-14
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* jdarith.c
|
||||
*
|
||||
* Developed 1997-2015 by Guido Vollbeding.
|
||||
* Developed 1997-2019 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -280,7 +280,7 @@ decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
if ((m = arith_decode(cinfo, st)) != 0) {
|
||||
st = entropy->dc_stats[tbl] + 20; /* Table F.4: X1 = 20 */
|
||||
while (arith_decode(cinfo, st)) {
|
||||
if ((m <<= 1) == 0x8000) {
|
||||
if ((m <<= 1) == (int) 0x8000U) {
|
||||
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
|
||||
entropy->ct = -1; /* magnitude overflow */
|
||||
return TRUE;
|
||||
@@ -370,7 +370,7 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
st = entropy->ac_stats[tbl] +
|
||||
(k <= cinfo->arith_ac_K[tbl] ? 189 : 217);
|
||||
while (arith_decode(cinfo, st)) {
|
||||
if ((m <<= 1) == 0x8000) {
|
||||
if ((m <<= 1) == (int) 0x8000U) {
|
||||
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
|
||||
entropy->ct = -1; /* magnitude overflow */
|
||||
return TRUE;
|
||||
@@ -404,7 +404,8 @@ decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
{
|
||||
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
|
||||
unsigned char *st;
|
||||
int p1, blkn;
|
||||
JCOEF p1;
|
||||
int blkn;
|
||||
|
||||
/* Process restart marker if needed */
|
||||
if (cinfo->restart_interval) {
|
||||
@@ -440,7 +441,7 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
JCOEFPTR thiscoef;
|
||||
unsigned char *st;
|
||||
int tbl, k, kex;
|
||||
int p1, m1;
|
||||
JCOEF p1, m1;
|
||||
const int * natural_order;
|
||||
|
||||
/* Process restart marker if needed */
|
||||
@@ -459,7 +460,7 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
tbl = cinfo->cur_comp_info[0]->ac_tbl_no;
|
||||
|
||||
p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
|
||||
m1 = (-1) << cinfo->Al; /* -1 in the bit position being coded */
|
||||
m1 = -p1; /* -1 in the bit position being coded */
|
||||
|
||||
/* Establish EOBx (previous stage end-of-block) index */
|
||||
kex = cinfo->Se;
|
||||
@@ -555,7 +556,7 @@ decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
if ((m = arith_decode(cinfo, st)) != 0) {
|
||||
st = entropy->dc_stats[tbl] + 20; /* Table F.4: X1 = 20 */
|
||||
while (arith_decode(cinfo, st)) {
|
||||
if ((m <<= 1) == 0x8000) {
|
||||
if ((m <<= 1) == (int) 0x8000U) {
|
||||
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
|
||||
entropy->ct = -1; /* magnitude overflow */
|
||||
return TRUE;
|
||||
@@ -612,7 +613,7 @@ decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
st = entropy->ac_stats[tbl] +
|
||||
(k <= cinfo->arith_ac_K[tbl] ? 189 : 217);
|
||||
while (arith_decode(cinfo, st)) {
|
||||
if ((m <<= 1) == 0x8000) {
|
||||
if ((m <<= 1) == (int) 0x8000U) {
|
||||
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
|
||||
entropy->ct = -1; /* magnitude overflow */
|
||||
return TRUE;
|
||||
@@ -766,9 +767,8 @@ jinit_arith_decoder (j_decompress_ptr cinfo)
|
||||
arith_entropy_ptr entropy;
|
||||
int i;
|
||||
|
||||
entropy = (arith_entropy_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(arith_entropy_decoder));
|
||||
entropy = (arith_entropy_ptr) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(arith_entropy_decoder));
|
||||
cinfo->entropy = &entropy->pub;
|
||||
entropy->pub.start_pass = start_pass;
|
||||
entropy->pub.finish_pass = finish_pass;
|
||||
@@ -785,9 +785,9 @@ jinit_arith_decoder (j_decompress_ptr cinfo)
|
||||
if (cinfo->progressive_mode) {
|
||||
/* Create progression status table */
|
||||
int *coef_bit_ptr, ci;
|
||||
cinfo->coef_bits = (int (*)[DCTSIZE2])
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
cinfo->num_components*DCTSIZE2*SIZEOF(int));
|
||||
cinfo->coef_bits = (int (*)[DCTSIZE2]) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
cinfo->num_components * DCTSIZE2 * SIZEOF(int));
|
||||
coef_bit_ptr = & cinfo->coef_bits[0][0];
|
||||
for (ci = 0; ci < cinfo->num_components; ci++)
|
||||
for (i = 0; i < DCTSIZE2; i++)
|
||||
|
||||
Vendored
+10
-13
@@ -2,7 +2,7 @@
|
||||
* jdatadst.c
|
||||
*
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* Modified 2009-2017 by Guido Vollbeding.
|
||||
* Modified 2009-2019 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -46,7 +46,7 @@ typedef struct {
|
||||
struct jpeg_destination_mgr pub; /* public fields */
|
||||
|
||||
unsigned char ** outbuffer; /* target buffer */
|
||||
unsigned long * outsize;
|
||||
size_t * outsize;
|
||||
unsigned char * newbuffer; /* newly allocated buffer */
|
||||
JOCTET * buffer; /* start of buffer */
|
||||
size_t bufsize;
|
||||
@@ -66,9 +66,8 @@ init_destination (j_compress_ptr cinfo)
|
||||
my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
|
||||
|
||||
/* Allocate the output buffer --- it will be released when done with image */
|
||||
dest->buffer = (JOCTET *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
OUTPUT_BUF_SIZE * SIZEOF(JOCTET));
|
||||
dest->buffer = (JOCTET *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, OUTPUT_BUF_SIZE * SIZEOF(JOCTET));
|
||||
|
||||
dest->pub.next_output_byte = dest->buffer;
|
||||
dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
|
||||
@@ -131,7 +130,7 @@ empty_mem_output_buffer (j_compress_ptr cinfo)
|
||||
nextbuffer = (JOCTET *) malloc(nextsize);
|
||||
|
||||
if (nextbuffer == NULL)
|
||||
ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10);
|
||||
ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 11);
|
||||
|
||||
MEMCOPY(nextbuffer, dest->buffer, dest->bufsize);
|
||||
|
||||
@@ -204,9 +203,8 @@ jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile)
|
||||
* sizes may be different. Caveat programmer.
|
||||
*/
|
||||
if (cinfo->dest == NULL) { /* first time for this JPEG object? */
|
||||
cinfo->dest = (struct jpeg_destination_mgr *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
||||
SIZEOF(my_destination_mgr));
|
||||
cinfo->dest = (struct jpeg_destination_mgr *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(my_destination_mgr));
|
||||
}
|
||||
|
||||
dest = (my_dest_ptr) cinfo->dest;
|
||||
@@ -233,7 +231,7 @@ jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile)
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_mem_dest (j_compress_ptr cinfo,
|
||||
unsigned char ** outbuffer, unsigned long * outsize)
|
||||
unsigned char ** outbuffer, size_t * outsize)
|
||||
{
|
||||
my_mem_dest_ptr dest;
|
||||
|
||||
@@ -244,9 +242,8 @@ jpeg_mem_dest (j_compress_ptr cinfo,
|
||||
* can be written to the same buffer without re-executing jpeg_mem_dest.
|
||||
*/
|
||||
if (cinfo->dest == NULL) { /* first time for this JPEG object? */
|
||||
cinfo->dest = (struct jpeg_destination_mgr *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
||||
SIZEOF(my_mem_destination_mgr));
|
||||
cinfo->dest = (struct jpeg_destination_mgr *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(my_mem_destination_mgr));
|
||||
}
|
||||
|
||||
dest = (my_mem_dest_ptr) cinfo->dest;
|
||||
|
||||
Vendored
+15
-16
@@ -2,7 +2,7 @@
|
||||
* jdatasrc.c
|
||||
*
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* Modified 2009-2015 by Guido Vollbeding.
|
||||
* Modified 2009-2019 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -156,21 +156,23 @@ METHODDEF(void)
|
||||
skip_input_data (j_decompress_ptr cinfo, long num_bytes)
|
||||
{
|
||||
struct jpeg_source_mgr * src = cinfo->src;
|
||||
size_t nbytes;
|
||||
|
||||
/* Just a dumb implementation for now. Could use fseek() except
|
||||
* it doesn't work on pipes. Not clear that being smart is worth
|
||||
* any trouble anyway --- large skips are infrequent.
|
||||
*/
|
||||
if (num_bytes > 0) {
|
||||
while (num_bytes > (long) src->bytes_in_buffer) {
|
||||
num_bytes -= (long) src->bytes_in_buffer;
|
||||
nbytes = (size_t) num_bytes;
|
||||
while (nbytes > src->bytes_in_buffer) {
|
||||
nbytes -= src->bytes_in_buffer;
|
||||
(void) (*src->fill_input_buffer) (cinfo);
|
||||
/* note we assume that fill_input_buffer will never return FALSE,
|
||||
* so suspension need not be handled.
|
||||
*/
|
||||
}
|
||||
src->next_input_byte += (size_t) num_bytes;
|
||||
src->bytes_in_buffer -= (size_t) num_bytes;
|
||||
src->next_input_byte += nbytes;
|
||||
src->bytes_in_buffer -= nbytes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,13 +221,11 @@ jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile)
|
||||
* manager serially with the same JPEG object. Caveat programmer.
|
||||
*/
|
||||
if (cinfo->src == NULL) { /* first time for this JPEG object? */
|
||||
cinfo->src = (struct jpeg_source_mgr *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
||||
SIZEOF(my_source_mgr));
|
||||
cinfo->src = (struct jpeg_source_mgr *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(my_source_mgr));
|
||||
src = (my_src_ptr) cinfo->src;
|
||||
src->buffer = (JOCTET *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
||||
INPUT_BUF_SIZE * SIZEOF(JOCTET));
|
||||
src->buffer = (JOCTET *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_PERMANENT, INPUT_BUF_SIZE * SIZEOF(JOCTET));
|
||||
}
|
||||
|
||||
src = (my_src_ptr) cinfo->src;
|
||||
@@ -247,7 +247,7 @@ jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile)
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_mem_src (j_decompress_ptr cinfo,
|
||||
const unsigned char * inbuffer, unsigned long insize)
|
||||
const unsigned char * inbuffer, size_t insize)
|
||||
{
|
||||
struct jpeg_source_mgr * src;
|
||||
|
||||
@@ -259,9 +259,8 @@ jpeg_mem_src (j_decompress_ptr cinfo,
|
||||
* the first one.
|
||||
*/
|
||||
if (cinfo->src == NULL) { /* first time for this JPEG object? */
|
||||
cinfo->src = (struct jpeg_source_mgr *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
||||
SIZEOF(struct jpeg_source_mgr));
|
||||
cinfo->src = (struct jpeg_source_mgr *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(struct jpeg_source_mgr));
|
||||
}
|
||||
|
||||
src = cinfo->src;
|
||||
@@ -270,6 +269,6 @@ jpeg_mem_src (j_decompress_ptr cinfo,
|
||||
src->skip_input_data = skip_input_data;
|
||||
src->resync_to_restart = jpeg_resync_to_restart; /* use default method */
|
||||
src->term_source = term_source;
|
||||
src->bytes_in_buffer = (size_t) insize;
|
||||
src->bytes_in_buffer = insize;
|
||||
src->next_input_byte = (const JOCTET *) inbuffer;
|
||||
}
|
||||
|
||||
Vendored
+59
-71
@@ -2,7 +2,7 @@
|
||||
* jdcolor.c
|
||||
*
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Modified 2011-2017 by Guido Vollbeding.
|
||||
* Modified 2011-2019 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -124,28 +124,22 @@ build_ycc_rgb_table (j_decompress_ptr cinfo)
|
||||
INT32 x;
|
||||
SHIFT_TEMPS
|
||||
|
||||
cconvert->Cr_r_tab = (int *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(int));
|
||||
cconvert->Cb_b_tab = (int *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(int));
|
||||
cconvert->Cr_g_tab = (INT32 *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(INT32));
|
||||
cconvert->Cb_g_tab = (INT32 *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(INT32));
|
||||
cconvert->Cr_r_tab = (int *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(int));
|
||||
cconvert->Cb_b_tab = (int *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(int));
|
||||
cconvert->Cr_g_tab = (INT32 *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32));
|
||||
cconvert->Cb_g_tab = (INT32 *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32));
|
||||
|
||||
for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
|
||||
/* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
|
||||
/* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
|
||||
/* Cr=>R value is nearest int to 1.402 * x */
|
||||
cconvert->Cr_r_tab[i] = (int)
|
||||
RIGHT_SHIFT(FIX(1.402) * x + ONE_HALF, SCALEBITS);
|
||||
cconvert->Cr_r_tab[i] = (int) DESCALE(FIX(1.402) * x, SCALEBITS);
|
||||
/* Cb=>B value is nearest int to 1.772 * x */
|
||||
cconvert->Cb_b_tab[i] = (int)
|
||||
RIGHT_SHIFT(FIX(1.772) * x + ONE_HALF, SCALEBITS);
|
||||
cconvert->Cb_b_tab[i] = (int) DESCALE(FIX(1.772) * x, SCALEBITS);
|
||||
/* Cr=>G value is scaled-up -0.714136286 * x */
|
||||
cconvert->Cr_g_tab[i] = (- FIX(0.714136286)) * x;
|
||||
/* Cb=>G value is scaled-up -0.344136286 * x */
|
||||
@@ -164,28 +158,22 @@ build_bg_ycc_rgb_table (j_decompress_ptr cinfo)
|
||||
INT32 x;
|
||||
SHIFT_TEMPS
|
||||
|
||||
cconvert->Cr_r_tab = (int *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(int));
|
||||
cconvert->Cb_b_tab = (int *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(int));
|
||||
cconvert->Cr_g_tab = (INT32 *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(INT32));
|
||||
cconvert->Cb_g_tab = (INT32 *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(INT32));
|
||||
cconvert->Cr_r_tab = (int *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(int));
|
||||
cconvert->Cb_b_tab = (int *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(int));
|
||||
cconvert->Cr_g_tab = (INT32 *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32));
|
||||
cconvert->Cb_g_tab = (INT32 *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32));
|
||||
|
||||
for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
|
||||
/* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
|
||||
/* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
|
||||
/* Cr=>R value is nearest int to 2.804 * x */
|
||||
cconvert->Cr_r_tab[i] = (int)
|
||||
RIGHT_SHIFT(FIX(2.804) * x + ONE_HALF, SCALEBITS);
|
||||
cconvert->Cr_r_tab[i] = (int) DESCALE(FIX(2.804) * x, SCALEBITS);
|
||||
/* Cb=>B value is nearest int to 3.544 * x */
|
||||
cconvert->Cb_b_tab[i] = (int)
|
||||
RIGHT_SHIFT(FIX(3.544) * x + ONE_HALF, SCALEBITS);
|
||||
cconvert->Cb_b_tab[i] = (int) DESCALE(FIX(3.544) * x, SCALEBITS);
|
||||
/* Cr=>G value is scaled-up -1.428272572 * x */
|
||||
cconvert->Cr_g_tab[i] = (- FIX(1.428272572)) * x;
|
||||
/* Cb=>G value is scaled-up -0.688272572 * x */
|
||||
@@ -201,6 +189,7 @@ build_bg_ycc_rgb_table (j_decompress_ptr cinfo)
|
||||
* Note that we change from noninterleaved, one-plane-per-component format
|
||||
* to interleaved-pixel format. The output buffer is therefore three times
|
||||
* as wide as the input buffer.
|
||||
*
|
||||
* A starting row offset is provided only for the input buffer. The caller
|
||||
* can easily adjust the passed output_buf value to accommodate any row
|
||||
* offset required on that side.
|
||||
@@ -264,9 +253,8 @@ build_rgb_y_table (j_decompress_ptr cinfo)
|
||||
INT32 i;
|
||||
|
||||
/* Allocate and fill in the conversion tables. */
|
||||
cconvert->rgb_y_tab = rgb_y_tab = (INT32 *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(TABLE_SIZE * SIZEOF(INT32)));
|
||||
cconvert->rgb_y_tab = rgb_y_tab = (INT32 *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, TABLE_SIZE * SIZEOF(INT32));
|
||||
|
||||
for (i = 0; i <= MAXJSAMPLE; i++) {
|
||||
rgb_y_tab[i+R_Y_OFF] = FIX(0.299) * i;
|
||||
@@ -286,8 +274,8 @@ rgb_gray_convert (j_decompress_ptr cinfo,
|
||||
JSAMPARRAY output_buf, int num_rows)
|
||||
{
|
||||
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
|
||||
register INT32 * ctab = cconvert->rgb_y_tab;
|
||||
register int r, g, b;
|
||||
register INT32 * ctab = cconvert->rgb_y_tab;
|
||||
register JSAMPROW outptr;
|
||||
register JSAMPROW inptr0, inptr1, inptr2;
|
||||
register JDIMENSION col;
|
||||
@@ -313,6 +301,7 @@ rgb_gray_convert (j_decompress_ptr cinfo,
|
||||
|
||||
|
||||
/*
|
||||
* Convert some rows of samples to the output colorspace.
|
||||
* [R-G,G,B-G] to [R,G,B] conversion with modulo calculation
|
||||
* (inverse color transform).
|
||||
* This can be seen as an adaption of the general YCbCr->RGB
|
||||
@@ -364,8 +353,8 @@ rgb1_gray_convert (j_decompress_ptr cinfo,
|
||||
JSAMPARRAY output_buf, int num_rows)
|
||||
{
|
||||
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
|
||||
register INT32 * ctab = cconvert->rgb_y_tab;
|
||||
register int r, g, b;
|
||||
register INT32 * ctab = cconvert->rgb_y_tab;
|
||||
register JSAMPROW outptr;
|
||||
register JSAMPROW inptr0, inptr1, inptr2;
|
||||
register JDIMENSION col;
|
||||
@@ -396,6 +385,7 @@ rgb1_gray_convert (j_decompress_ptr cinfo,
|
||||
|
||||
|
||||
/*
|
||||
* Convert some rows of samples to the output colorspace.
|
||||
* No colorspace change, but conversion from separate-planes
|
||||
* to interleaved representation.
|
||||
*/
|
||||
@@ -430,6 +420,7 @@ rgb_convert (j_decompress_ptr cinfo,
|
||||
/*
|
||||
* Color conversion for no colorspace change: just copy the data,
|
||||
* converting from separate-planes to interleaved representation.
|
||||
* We assume out_color_components == num_components.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
@@ -437,20 +428,21 @@ null_convert (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION input_row,
|
||||
JSAMPARRAY output_buf, int num_rows)
|
||||
{
|
||||
int ci;
|
||||
register int nc = cinfo->num_components;
|
||||
register JSAMPROW outptr;
|
||||
register JSAMPROW inptr;
|
||||
register JDIMENSION col;
|
||||
register JDIMENSION count;
|
||||
register int num_comps = cinfo->num_components;
|
||||
JDIMENSION num_cols = cinfo->output_width;
|
||||
int ci;
|
||||
|
||||
while (--num_rows >= 0) {
|
||||
for (ci = 0; ci < nc; ci++) {
|
||||
/* It seems fastest to make a separate pass for each component. */
|
||||
for (ci = 0; ci < num_comps; ci++) {
|
||||
inptr = input_buf[ci][input_row];
|
||||
outptr = output_buf[0] + ci;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
*outptr = *inptr++; /* needn't bother with GETJSAMPLE() here */
|
||||
outptr += nc;
|
||||
for (count = num_cols; count > 0; count--) {
|
||||
*outptr = *inptr++; /* don't need GETJSAMPLE() here */
|
||||
outptr += num_comps;
|
||||
}
|
||||
}
|
||||
input_row++;
|
||||
@@ -504,9 +496,10 @@ gray_rgb_convert (j_decompress_ptr cinfo,
|
||||
|
||||
|
||||
/*
|
||||
* Adobe-style YCCK->CMYK conversion.
|
||||
* We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
|
||||
* conversion as above, while passing K (black) unchanged.
|
||||
* Convert some rows of samples to the output colorspace.
|
||||
* This version handles Adobe-style YCCK->CMYK conversion,
|
||||
* where we convert YCbCr to R=1-C, G=1-M, and B=1-Y using the
|
||||
* same conversion as above, while passing K (black) unchanged.
|
||||
* We assume build_ycc_rgb_table has been called.
|
||||
*/
|
||||
|
||||
@@ -577,9 +570,8 @@ jinit_color_deconverter (j_decompress_ptr cinfo)
|
||||
my_cconvert_ptr cconvert;
|
||||
int ci;
|
||||
|
||||
cconvert = (my_cconvert_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(my_color_deconverter));
|
||||
cconvert = (my_cconvert_ptr) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_color_deconverter));
|
||||
cinfo->cconvert = &cconvert->pub;
|
||||
cconvert->pub.start_pass = start_pass_dcolor;
|
||||
|
||||
@@ -607,7 +599,6 @@ jinit_color_deconverter (j_decompress_ptr cinfo)
|
||||
default: /* JCS_UNKNOWN can be anything */
|
||||
if (cinfo->num_components < 1)
|
||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Support color transform only for RGB colorspaces */
|
||||
@@ -684,19 +675,18 @@ jinit_color_deconverter (j_decompress_ptr cinfo)
|
||||
|
||||
case JCS_BG_RGB:
|
||||
cinfo->out_color_components = RGB_PIXELSIZE;
|
||||
if (cinfo->jpeg_color_space == JCS_BG_RGB) {
|
||||
switch (cinfo->color_transform) {
|
||||
case JCT_NONE:
|
||||
cconvert->pub.color_convert = rgb_convert;
|
||||
break;
|
||||
case JCT_SUBTRACT_GREEN:
|
||||
cconvert->pub.color_convert = rgb1_rgb_convert;
|
||||
break;
|
||||
default:
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
}
|
||||
} else
|
||||
if (cinfo->jpeg_color_space != JCS_BG_RGB)
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
switch (cinfo->color_transform) {
|
||||
case JCT_NONE:
|
||||
cconvert->pub.color_convert = rgb_convert;
|
||||
break;
|
||||
case JCT_SUBTRACT_GREEN:
|
||||
cconvert->pub.color_convert = rgb1_rgb_convert;
|
||||
break;
|
||||
default:
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
}
|
||||
break;
|
||||
|
||||
case JCS_CMYK:
|
||||
@@ -714,14 +704,12 @@ jinit_color_deconverter (j_decompress_ptr cinfo)
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Permit null conversion to same output space */
|
||||
if (cinfo->out_color_space == cinfo->jpeg_color_space) {
|
||||
cinfo->out_color_components = cinfo->num_components;
|
||||
cconvert->pub.color_convert = null_convert;
|
||||
} else /* unsupported non-null conversion */
|
||||
default: /* permit null conversion to same output space */
|
||||
if (cinfo->out_color_space != cinfo->jpeg_color_space)
|
||||
/* unsupported non-null conversion */
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
break;
|
||||
cinfo->out_color_components = cinfo->num_components;
|
||||
cconvert->pub.color_convert = null_convert;
|
||||
}
|
||||
|
||||
if (cinfo->quantize_colors)
|
||||
|
||||
Vendored
+1
-8
@@ -2,7 +2,7 @@
|
||||
* jdct.h
|
||||
*
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* Modified 2002-2017 by Guido Vollbeding.
|
||||
* Modified 2002-2019 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -358,13 +358,6 @@ EXTERN(void) jpeg_idct_1x2
|
||||
|
||||
#define FIX(x) ((INT32) ((x) * CONST_SCALE + 0.5))
|
||||
|
||||
/* Descale and correctly round an INT32 value that's scaled by N bits.
|
||||
* We assume RIGHT_SHIFT rounds towards minus infinity, so adding
|
||||
* the fudge factor is correct for either sign of X.
|
||||
*/
|
||||
|
||||
#define DESCALE(x,n) RIGHT_SHIFT((x) + (ONE << ((n)-1)), n)
|
||||
|
||||
/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
|
||||
* This macro is used only when the two inputs will actually be no more than
|
||||
* 16 bits wide, so that a 16x16->32 bit multiply can be used instead of a
|
||||
|
||||
Vendored
+56
-50
@@ -2,7 +2,7 @@
|
||||
* jdhuff.c
|
||||
*
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Modified 2006-2016 by Guido Vollbeding.
|
||||
* Modified 2006-2019 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -341,13 +341,12 @@ jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, boolean isDC, int tblno,
|
||||
htbl =
|
||||
isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno];
|
||||
if (htbl == NULL)
|
||||
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
|
||||
htbl = jpeg_std_huff_table((j_common_ptr) cinfo, isDC, tblno);
|
||||
|
||||
/* Allocate a workspace if we haven't already done so. */
|
||||
if (*pdtbl == NULL)
|
||||
*pdtbl = (d_derived_tbl *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(d_derived_tbl));
|
||||
*pdtbl = (d_derived_tbl *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(d_derived_tbl));
|
||||
dtbl = *pdtbl;
|
||||
dtbl->pub = htbl; /* fill in back link */
|
||||
|
||||
@@ -706,7 +705,7 @@ process_restart (j_decompress_ptr cinfo)
|
||||
|
||||
METHODDEF(boolean)
|
||||
decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
{
|
||||
{
|
||||
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
|
||||
int Al = cinfo->Al;
|
||||
register int s, r;
|
||||
@@ -730,7 +729,7 @@ decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
if (! entropy->insufficient_data) {
|
||||
|
||||
/* Load up working state */
|
||||
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
|
||||
BITREAD_LOAD_STATE(cinfo, entropy->bitstate);
|
||||
ASSIGN_STATE(state, entropy->saved);
|
||||
|
||||
/* Outer loop handles each block in the MCU */
|
||||
@@ -759,12 +758,13 @@ decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
}
|
||||
|
||||
/* Completed MCU, so update state */
|
||||
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
|
||||
BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
|
||||
ASSIGN_STATE(entropy->saved, state);
|
||||
}
|
||||
|
||||
/* Account for restart interval (no-op if not using restarts) */
|
||||
entropy->restarts_to_go--;
|
||||
/* Account for restart interval if using restarts */
|
||||
if (cinfo->restart_interval)
|
||||
entropy->restarts_to_go--;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -777,7 +777,7 @@ decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
|
||||
METHODDEF(boolean)
|
||||
decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
{
|
||||
{
|
||||
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
|
||||
register int s, k, r;
|
||||
unsigned int EOBRUN;
|
||||
@@ -809,7 +809,7 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
if (EOBRUN) /* if it's a band of zeroes... */
|
||||
EOBRUN--; /* ...process it now (we do nothing) */
|
||||
else {
|
||||
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
|
||||
BITREAD_LOAD_STATE(cinfo, entropy->bitstate);
|
||||
Se = cinfo->Se;
|
||||
Al = cinfo->Al;
|
||||
natural_order = cinfo->natural_order;
|
||||
@@ -842,15 +842,16 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
}
|
||||
}
|
||||
|
||||
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
|
||||
BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
|
||||
}
|
||||
|
||||
/* Completed MCU, so update state */
|
||||
entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */
|
||||
}
|
||||
|
||||
/* Account for restart interval (no-op if not using restarts) */
|
||||
entropy->restarts_to_go--;
|
||||
/* Account for restart interval if using restarts */
|
||||
if (cinfo->restart_interval)
|
||||
entropy->restarts_to_go--;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -864,9 +865,10 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
|
||||
METHODDEF(boolean)
|
||||
decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
{
|
||||
{
|
||||
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
|
||||
int p1, blkn;
|
||||
JCOEF p1;
|
||||
int blkn;
|
||||
BITREAD_STATE_VARS;
|
||||
|
||||
/* Process restart marker if needed; may have to suspend */
|
||||
@@ -881,7 +883,7 @@ decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
*/
|
||||
|
||||
/* Load up working state */
|
||||
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
|
||||
BITREAD_LOAD_STATE(cinfo, entropy->bitstate);
|
||||
|
||||
p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
|
||||
|
||||
@@ -896,10 +898,11 @@ decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
}
|
||||
|
||||
/* Completed MCU, so update state */
|
||||
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
|
||||
BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
|
||||
|
||||
/* Account for restart interval (no-op if not using restarts) */
|
||||
entropy->restarts_to_go--;
|
||||
/* Account for restart interval if using restarts */
|
||||
if (cinfo->restart_interval)
|
||||
entropy->restarts_to_go--;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -911,11 +914,12 @@ decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
|
||||
METHODDEF(boolean)
|
||||
decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
{
|
||||
{
|
||||
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
|
||||
register int s, k, r;
|
||||
unsigned int EOBRUN;
|
||||
int Se, p1, m1;
|
||||
int Se;
|
||||
JCOEF p1, m1;
|
||||
const int * natural_order;
|
||||
JBLOCKROW block;
|
||||
JCOEFPTR thiscoef;
|
||||
@@ -937,11 +941,11 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
|
||||
Se = cinfo->Se;
|
||||
p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
|
||||
m1 = (-1) << cinfo->Al; /* -1 in the bit position being coded */
|
||||
m1 = -p1; /* -1 in the bit position being coded */
|
||||
natural_order = cinfo->natural_order;
|
||||
|
||||
/* Load up working state */
|
||||
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
|
||||
BITREAD_LOAD_STATE(cinfo, entropy->bitstate);
|
||||
EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */
|
||||
|
||||
/* There is always only one block per MCU */
|
||||
@@ -1043,12 +1047,13 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
}
|
||||
|
||||
/* Completed MCU, so update state */
|
||||
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
|
||||
BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
|
||||
entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */
|
||||
}
|
||||
|
||||
/* Account for restart interval (no-op if not using restarts) */
|
||||
entropy->restarts_to_go--;
|
||||
/* Account for restart interval if using restarts */
|
||||
if (cinfo->restart_interval)
|
||||
entropy->restarts_to_go--;
|
||||
|
||||
return TRUE;
|
||||
|
||||
@@ -1091,7 +1096,7 @@ decode_mcu_sub (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
Se = cinfo->lim_Se;
|
||||
|
||||
/* Load up working state */
|
||||
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
|
||||
BITREAD_LOAD_STATE(cinfo, entropy->bitstate);
|
||||
ASSIGN_STATE(state, entropy->saved);
|
||||
|
||||
/* Outer loop handles each block in the MCU */
|
||||
@@ -1178,12 +1183,13 @@ decode_mcu_sub (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
}
|
||||
|
||||
/* Completed MCU, so update state */
|
||||
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
|
||||
BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
|
||||
ASSIGN_STATE(entropy->saved, state);
|
||||
}
|
||||
|
||||
/* Account for restart interval (no-op if not using restarts) */
|
||||
entropy->restarts_to_go--;
|
||||
/* Account for restart interval if using restarts */
|
||||
if (cinfo->restart_interval)
|
||||
entropy->restarts_to_go--;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1215,7 +1221,7 @@ decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
if (! entropy->insufficient_data) {
|
||||
|
||||
/* Load up working state */
|
||||
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
|
||||
BITREAD_LOAD_STATE(cinfo, entropy->bitstate);
|
||||
ASSIGN_STATE(state, entropy->saved);
|
||||
|
||||
/* Outer loop handles each block in the MCU */
|
||||
@@ -1302,12 +1308,13 @@ decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
}
|
||||
|
||||
/* Completed MCU, so update state */
|
||||
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
|
||||
BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
|
||||
ASSIGN_STATE(entropy->saved, state);
|
||||
}
|
||||
|
||||
/* Account for restart interval (no-op if not using restarts) */
|
||||
entropy->restarts_to_go--;
|
||||
/* Account for restart interval if using restarts */
|
||||
if (cinfo->restart_interval)
|
||||
entropy->restarts_to_go--;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1343,11 +1350,11 @@ start_pass_huff_decoder (j_decompress_ptr cinfo)
|
||||
goto bad;
|
||||
}
|
||||
if (cinfo->Al > 13) { /* need not check for < 0 */
|
||||
/* Arguably the maximum Al value should be less than 13 for 8-bit precision,
|
||||
* but the spec doesn't say so, and we try to be liberal about what we
|
||||
* accept. Note: large Al values could result in out-of-range DC
|
||||
* coefficients during early scans, leading to bizarre displays due to
|
||||
* overflows in the IDCT math. But we won't crash.
|
||||
/* Arguably the maximum Al value should be less than 13 for 8-bit
|
||||
* precision, but the spec doesn't say so, and we try to be liberal
|
||||
* about what we accept. Note: large Al values could result in
|
||||
* out-of-range DC coefficients during early scans, leading to bizarre
|
||||
* displays due to overflows in the IDCT math. But we won't crash.
|
||||
*/
|
||||
bad:
|
||||
ERREXIT4(cinfo, JERR_BAD_PROGRESSION,
|
||||
@@ -1451,7 +1458,8 @@ start_pass_huff_decoder (j_decompress_ptr cinfo)
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
/* Precalculate which table to use for each block */
|
||||
entropy->dc_cur_tbls[blkn] = entropy->dc_derived_tbls[compptr->dc_tbl_no];
|
||||
entropy->ac_cur_tbls[blkn] = entropy->ac_derived_tbls[compptr->ac_tbl_no];
|
||||
entropy->ac_cur_tbls[blkn] = /* AC needs no table when not present */
|
||||
cinfo->lim_Se ? entropy->ac_derived_tbls[compptr->ac_tbl_no] : NULL;
|
||||
/* Decide whether we really care about the coefficient values */
|
||||
if (compptr->component_needed) {
|
||||
ci = compptr->DCT_v_scaled_size;
|
||||
@@ -1494,7 +1502,6 @@ start_pass_huff_decoder (j_decompress_ptr cinfo)
|
||||
if (ci <= 0 || ci > 8) ci = 8;
|
||||
if (i <= 0 || i > 8) i = 8;
|
||||
entropy->coef_limit[blkn] = 1 + jpeg_zigzag_order[ci - 1][i - 1];
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
entropy->coef_limit[blkn] = 0;
|
||||
@@ -1522,9 +1529,8 @@ jinit_huff_decoder (j_decompress_ptr cinfo)
|
||||
huff_entropy_ptr entropy;
|
||||
int i;
|
||||
|
||||
entropy = (huff_entropy_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(huff_entropy_decoder));
|
||||
entropy = (huff_entropy_ptr) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(huff_entropy_decoder));
|
||||
cinfo->entropy = &entropy->pub;
|
||||
entropy->pub.start_pass = start_pass_huff_decoder;
|
||||
entropy->pub.finish_pass = finish_pass_huff;
|
||||
@@ -1532,9 +1538,9 @@ jinit_huff_decoder (j_decompress_ptr cinfo)
|
||||
if (cinfo->progressive_mode) {
|
||||
/* Create progression status table */
|
||||
int *coef_bit_ptr, ci;
|
||||
cinfo->coef_bits = (int (*)[DCTSIZE2])
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
cinfo->num_components*DCTSIZE2*SIZEOF(int));
|
||||
cinfo->coef_bits = (int (*)[DCTSIZE2]) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
cinfo->num_components * DCTSIZE2 * SIZEOF(int));
|
||||
coef_bit_ptr = & cinfo->coef_bits[0][0];
|
||||
for (ci = 0; ci < cinfo->num_components; ci++)
|
||||
for (i = 0; i < DCTSIZE2; i++)
|
||||
@@ -1545,7 +1551,7 @@ jinit_huff_decoder (j_decompress_ptr cinfo)
|
||||
entropy->derived_tbls[i] = NULL;
|
||||
}
|
||||
} else {
|
||||
/* Mark tables unallocated */
|
||||
/* Mark derived tables unallocated */
|
||||
for (i = 0; i < NUM_HUFF_TBLS; i++) {
|
||||
entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL;
|
||||
}
|
||||
|
||||
Vendored
+7
-13
@@ -2,7 +2,7 @@
|
||||
* jdmarker.c
|
||||
*
|
||||
* Copyright (C) 1991-1998, Thomas G. Lane.
|
||||
* Modified 2009-2013 by Guido Vollbeding.
|
||||
* Modified 2009-2019 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -496,8 +496,6 @@ get_dht (j_decompress_ptr cinfo)
|
||||
if (count > 256 || ((INT32) count) > length)
|
||||
ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
|
||||
|
||||
MEMZERO(huffval, SIZEOF(huffval)); /* pre-zero array for later copy */
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
INPUT_BYTE(cinfo, huffval[i], return FALSE);
|
||||
|
||||
@@ -517,7 +515,8 @@ get_dht (j_decompress_ptr cinfo)
|
||||
*htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
|
||||
|
||||
MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits));
|
||||
MEMCOPY((*htblptr)->huffval, huffval, SIZEOF((*htblptr)->huffval));
|
||||
if (count > 0)
|
||||
MEMCOPY((*htblptr)->huffval, huffval, count * SIZEOF(UINT8));
|
||||
}
|
||||
|
||||
if (length != 0)
|
||||
@@ -577,14 +576,14 @@ get_dqt (j_decompress_ptr cinfo)
|
||||
count = DCTSIZE2;
|
||||
}
|
||||
|
||||
switch (count) {
|
||||
switch ((int) count) {
|
||||
case (2*2): natural_order = jpeg_natural_order2; break;
|
||||
case (3*3): natural_order = jpeg_natural_order3; break;
|
||||
case (4*4): natural_order = jpeg_natural_order4; break;
|
||||
case (5*5): natural_order = jpeg_natural_order5; break;
|
||||
case (6*6): natural_order = jpeg_natural_order6; break;
|
||||
case (7*7): natural_order = jpeg_natural_order7; break;
|
||||
default: natural_order = jpeg_natural_order; break;
|
||||
default: natural_order = jpeg_natural_order;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
@@ -784,7 +783,6 @@ examine_app0 (j_decompress_ptr cinfo, JOCTET FAR * data,
|
||||
default:
|
||||
TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION,
|
||||
GETJOCTET(data[5]), (int) totallen);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* Start of APP0 does not match "JFIF" or "JFXX", or too short */
|
||||
@@ -858,7 +856,6 @@ get_interesting_appn (j_decompress_ptr cinfo)
|
||||
default:
|
||||
/* can't get here unless jpeg_save_markers chooses wrong processor */
|
||||
ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
|
||||
break;
|
||||
}
|
||||
|
||||
/* skip any remaining data -- could be lots */
|
||||
@@ -964,7 +961,6 @@ save_marker (j_decompress_ptr cinfo)
|
||||
default:
|
||||
TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker,
|
||||
(int) (data_length + length));
|
||||
break;
|
||||
}
|
||||
|
||||
/* skip any remaining data -- could be lots */
|
||||
@@ -1240,7 +1236,6 @@ read_markers (j_decompress_ptr cinfo)
|
||||
* ought to change!
|
||||
*/
|
||||
ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
|
||||
break;
|
||||
}
|
||||
/* Successfully processed marker, so reset state variable */
|
||||
cinfo->unread_marker = 0;
|
||||
@@ -1416,9 +1411,8 @@ jinit_marker_reader (j_decompress_ptr cinfo)
|
||||
int i;
|
||||
|
||||
/* Create subobject in permanent pool */
|
||||
marker = (my_marker_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
||||
SIZEOF(my_marker_reader));
|
||||
marker = (my_marker_ptr) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(my_marker_reader));
|
||||
cinfo->marker = &marker->pub;
|
||||
/* Initialize public method pointers */
|
||||
marker->pub.reset_marker_reader = reset_marker_reader;
|
||||
|
||||
Vendored
+24
-23
@@ -2,7 +2,7 @@
|
||||
* jdmaster.c
|
||||
*
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Modified 2002-2017 by Guido Vollbeding.
|
||||
* Modified 2002-2019 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -104,7 +104,7 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
|
||||
*/
|
||||
{
|
||||
#ifdef IDCT_SCALING_SUPPORTED
|
||||
int ci;
|
||||
int ci, ssize;
|
||||
jpeg_component_info *compptr;
|
||||
#endif
|
||||
|
||||
@@ -124,19 +124,23 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
|
||||
*/
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
int ssize = 1;
|
||||
while (cinfo->min_DCT_h_scaled_size * ssize <=
|
||||
(cinfo->do_fancy_upsampling ? DCTSIZE : DCTSIZE / 2) &&
|
||||
(cinfo->max_h_samp_factor % (compptr->h_samp_factor * ssize * 2)) == 0) {
|
||||
ssize = ssize * 2;
|
||||
}
|
||||
ssize = 1;
|
||||
if (! cinfo->raw_data_out)
|
||||
while (cinfo->min_DCT_h_scaled_size * ssize <=
|
||||
(cinfo->do_fancy_upsampling ? DCTSIZE : DCTSIZE / 2) &&
|
||||
(cinfo->max_h_samp_factor % (compptr->h_samp_factor * ssize * 2)) ==
|
||||
0) {
|
||||
ssize = ssize * 2;
|
||||
}
|
||||
compptr->DCT_h_scaled_size = cinfo->min_DCT_h_scaled_size * ssize;
|
||||
ssize = 1;
|
||||
while (cinfo->min_DCT_v_scaled_size * ssize <=
|
||||
(cinfo->do_fancy_upsampling ? DCTSIZE : DCTSIZE / 2) &&
|
||||
(cinfo->max_v_samp_factor % (compptr->v_samp_factor * ssize * 2)) == 0) {
|
||||
ssize = ssize * 2;
|
||||
}
|
||||
if (! cinfo->raw_data_out)
|
||||
while (cinfo->min_DCT_v_scaled_size * ssize <=
|
||||
(cinfo->do_fancy_upsampling ? DCTSIZE : DCTSIZE / 2) &&
|
||||
(cinfo->max_v_samp_factor % (compptr->v_samp_factor * ssize * 2)) ==
|
||||
0) {
|
||||
ssize = ssize * 2;
|
||||
}
|
||||
compptr->DCT_v_scaled_size = cinfo->min_DCT_v_scaled_size * ssize;
|
||||
|
||||
/* We don't support IDCT ratios larger than 2. */
|
||||
@@ -144,13 +148,10 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
|
||||
compptr->DCT_h_scaled_size = compptr->DCT_v_scaled_size * 2;
|
||||
else if (compptr->DCT_v_scaled_size > compptr->DCT_h_scaled_size * 2)
|
||||
compptr->DCT_v_scaled_size = compptr->DCT_h_scaled_size * 2;
|
||||
}
|
||||
|
||||
/* Recompute downsampled dimensions of components;
|
||||
* application needs to know these if using raw downsampled data.
|
||||
*/
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
/* Recompute downsampled dimensions of components;
|
||||
* application needs to know these if using raw downsampled data.
|
||||
*/
|
||||
/* Size in samples, after IDCT scaling */
|
||||
compptr->downsampled_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width *
|
||||
@@ -172,8 +173,10 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
|
||||
break;
|
||||
case JCS_RGB:
|
||||
case JCS_BG_RGB:
|
||||
#if RGB_PIXELSIZE != 3
|
||||
cinfo->out_color_components = RGB_PIXELSIZE;
|
||||
break;
|
||||
#endif /* else share code with YCbCr */
|
||||
case JCS_YCbCr:
|
||||
case JCS_BG_YCC:
|
||||
cinfo->out_color_components = 3;
|
||||
@@ -184,7 +187,6 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
|
||||
break;
|
||||
default: /* else must be same colorspace as in file */
|
||||
cinfo->out_color_components = cinfo->num_components;
|
||||
break;
|
||||
}
|
||||
cinfo->output_components = (cinfo->quantize_colors ? 1 :
|
||||
cinfo->out_color_components);
|
||||
@@ -525,9 +527,8 @@ jinit_master_decompress (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_master_ptr master;
|
||||
|
||||
master = (my_master_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(my_decomp_master));
|
||||
master = (my_master_ptr) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_decomp_master));
|
||||
cinfo->master = &master->pub;
|
||||
master->pub.prepare_for_output_pass = prepare_for_output_pass;
|
||||
master->pub.finish_output_pass = finish_output_pass;
|
||||
|
||||
Vendored
+26
-39
@@ -2,7 +2,7 @@
|
||||
* jdmerge.c
|
||||
*
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* Modified 2013-2017 by Guido Vollbeding.
|
||||
* Modified 2013-2019 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -95,28 +95,22 @@ build_ycc_rgb_table (j_decompress_ptr cinfo)
|
||||
INT32 x;
|
||||
SHIFT_TEMPS
|
||||
|
||||
upsample->Cr_r_tab = (int *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(int));
|
||||
upsample->Cb_b_tab = (int *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(int));
|
||||
upsample->Cr_g_tab = (INT32 *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(INT32));
|
||||
upsample->Cb_g_tab = (INT32 *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(INT32));
|
||||
upsample->Cr_r_tab = (int *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(int));
|
||||
upsample->Cb_b_tab = (int *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(int));
|
||||
upsample->Cr_g_tab = (INT32 *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32));
|
||||
upsample->Cb_g_tab = (INT32 *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32));
|
||||
|
||||
for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
|
||||
/* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
|
||||
/* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
|
||||
/* Cr=>R value is nearest int to 1.402 * x */
|
||||
upsample->Cr_r_tab[i] = (int)
|
||||
RIGHT_SHIFT(FIX(1.402) * x + ONE_HALF, SCALEBITS);
|
||||
upsample->Cr_r_tab[i] = (int) DESCALE(FIX(1.402) * x, SCALEBITS);
|
||||
/* Cb=>B value is nearest int to 1.772 * x */
|
||||
upsample->Cb_b_tab[i] = (int)
|
||||
RIGHT_SHIFT(FIX(1.772) * x + ONE_HALF, SCALEBITS);
|
||||
upsample->Cb_b_tab[i] = (int) DESCALE(FIX(1.772) * x, SCALEBITS);
|
||||
/* Cr=>G value is scaled-up -0.714136286 * x */
|
||||
upsample->Cr_g_tab[i] = (- FIX(0.714136286)) * x;
|
||||
/* Cb=>G value is scaled-up -0.344136286 * x */
|
||||
@@ -135,28 +129,22 @@ build_bg_ycc_rgb_table (j_decompress_ptr cinfo)
|
||||
INT32 x;
|
||||
SHIFT_TEMPS
|
||||
|
||||
upsample->Cr_r_tab = (int *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(int));
|
||||
upsample->Cb_b_tab = (int *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(int));
|
||||
upsample->Cr_g_tab = (INT32 *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(INT32));
|
||||
upsample->Cb_g_tab = (INT32 *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(INT32));
|
||||
upsample->Cr_r_tab = (int *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(int));
|
||||
upsample->Cb_b_tab = (int *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(int));
|
||||
upsample->Cr_g_tab = (INT32 *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32));
|
||||
upsample->Cb_g_tab = (INT32 *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32));
|
||||
|
||||
for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
|
||||
/* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
|
||||
/* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
|
||||
/* Cr=>R value is nearest int to 2.804 * x */
|
||||
upsample->Cr_r_tab[i] = (int)
|
||||
RIGHT_SHIFT(FIX(2.804) * x + ONE_HALF, SCALEBITS);
|
||||
upsample->Cr_r_tab[i] = (int) DESCALE(FIX(2.804) * x, SCALEBITS);
|
||||
/* Cb=>B value is nearest int to 3.544 * x */
|
||||
upsample->Cb_b_tab[i] = (int)
|
||||
RIGHT_SHIFT(FIX(3.544) * x + ONE_HALF, SCALEBITS);
|
||||
upsample->Cb_b_tab[i] = (int) DESCALE(FIX(3.544) * x, SCALEBITS);
|
||||
/* Cr=>G value is scaled-up -1.428272572 * x */
|
||||
upsample->Cr_g_tab[i] = (- FIX(1.428272572)) * x;
|
||||
/* Cb=>G value is scaled-up -0.688272572 * x */
|
||||
@@ -419,9 +407,8 @@ jinit_merged_upsampler (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_upsample_ptr upsample;
|
||||
|
||||
upsample = (my_upsample_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(my_upsampler));
|
||||
upsample = (my_upsample_ptr) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_upsampler));
|
||||
cinfo->upsample = &upsample->pub;
|
||||
upsample->pub.start_pass = start_pass_merged_upsample;
|
||||
upsample->pub.need_context_rows = FALSE;
|
||||
@@ -432,9 +419,9 @@ jinit_merged_upsampler (j_decompress_ptr cinfo)
|
||||
upsample->pub.upsample = merged_2v_upsample;
|
||||
upsample->upmethod = h2v2_merged_upsample;
|
||||
/* Allocate a spare row buffer */
|
||||
upsample->spare_row = (JSAMPROW)
|
||||
(*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
|
||||
upsample->spare_row = (JSAMPROW) (*cinfo->mem->alloc_large)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(size_t) upsample->out_row_width * SIZEOF(JSAMPLE));
|
||||
} else {
|
||||
upsample->pub.upsample = merged_1v_upsample;
|
||||
upsample->upmethod = h2v1_merged_upsample;
|
||||
|
||||
Vendored
+2
-2
@@ -2,7 +2,7 @@
|
||||
* jerror.h
|
||||
*
|
||||
* Copyright (C) 1994-1997, Thomas G. Lane.
|
||||
* Modified 1997-2012 by Guido Vollbeding.
|
||||
* Modified 1997-2018 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -84,7 +84,7 @@ JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan")
|
||||
JMESSAGE(JERR_FILE_READ, "Input file read error")
|
||||
JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?")
|
||||
JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet")
|
||||
JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow")
|
||||
JMESSAGE(JERR_HUFF_CLEN_OUTOFBOUNDS, "Huffman code size table out of bounds")
|
||||
JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry")
|
||||
JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels")
|
||||
JMESSAGE(JERR_INPUT_EMPTY, "Empty input file")
|
||||
|
||||
Vendored
+61
-55
@@ -2,7 +2,7 @@
|
||||
* jfdctint.c
|
||||
*
|
||||
* Copyright (C) 1991-1996, Thomas G. Lane.
|
||||
* Modification developed 2003-2015 by Guido Vollbeding.
|
||||
* Modification developed 2003-2018 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -3261,78 +3261,84 @@ jpeg_fdct_6x3 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
|
||||
GLOBAL(void)
|
||||
jpeg_fdct_4x2 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
|
||||
{
|
||||
INT32 tmp0, tmp1;
|
||||
INT32 tmp10, tmp11;
|
||||
DCTELEM *dataptr;
|
||||
DCTELEM tmp0, tmp2, tmp10, tmp12, tmp4, tmp5;
|
||||
INT32 tmp1, tmp3, tmp11, tmp13;
|
||||
INT32 z1, z2, z3;
|
||||
JSAMPROW elemptr;
|
||||
int ctr;
|
||||
SHIFT_TEMPS
|
||||
|
||||
/* Pre-zero output coefficient block. */
|
||||
MEMZERO(data, SIZEOF(DCTELEM) * DCTSIZE2);
|
||||
|
||||
/* Pass 1: process rows.
|
||||
* Note results are scaled up by sqrt(8) compared to a true DCT;
|
||||
* furthermore, we scale the results by 2**PASS1_BITS.
|
||||
* We must also scale the output by (8/4)*(8/2) = 2**3, which we add here.
|
||||
* Note results are scaled up by sqrt(8) compared to a true DCT.
|
||||
* 4-point FDCT kernel,
|
||||
* cK represents sqrt(2) * cos(K*pi/16) [refers to 8-point FDCT].
|
||||
*/
|
||||
|
||||
dataptr = data;
|
||||
for (ctr = 0; ctr < 2; ctr++) {
|
||||
elemptr = sample_data[ctr] + start_col;
|
||||
/* Row 0 */
|
||||
elemptr = sample_data[0] + start_col;
|
||||
|
||||
/* Even part */
|
||||
/* Even part */
|
||||
|
||||
tmp0 = GETJSAMPLE(elemptr[0]) + GETJSAMPLE(elemptr[3]);
|
||||
tmp1 = GETJSAMPLE(elemptr[1]) + GETJSAMPLE(elemptr[2]);
|
||||
tmp4 = GETJSAMPLE(elemptr[0]) + GETJSAMPLE(elemptr[3]);
|
||||
tmp5 = GETJSAMPLE(elemptr[1]) + GETJSAMPLE(elemptr[2]);
|
||||
|
||||
tmp10 = GETJSAMPLE(elemptr[0]) - GETJSAMPLE(elemptr[3]);
|
||||
tmp11 = GETJSAMPLE(elemptr[1]) - GETJSAMPLE(elemptr[2]);
|
||||
tmp0 = tmp4 + tmp5;
|
||||
tmp2 = tmp4 - tmp5;
|
||||
|
||||
/* Apply unsigned->signed conversion. */
|
||||
dataptr[0] = (DCTELEM)
|
||||
((tmp0 + tmp1 - 4 * CENTERJSAMPLE) << (PASS1_BITS+3));
|
||||
dataptr[2] = (DCTELEM) ((tmp0 - tmp1) << (PASS1_BITS+3));
|
||||
/* Odd part */
|
||||
|
||||
/* Odd part */
|
||||
z2 = GETJSAMPLE(elemptr[0]) - GETJSAMPLE(elemptr[3]);
|
||||
z3 = GETJSAMPLE(elemptr[1]) - GETJSAMPLE(elemptr[2]);
|
||||
|
||||
tmp0 = MULTIPLY(tmp10 + tmp11, FIX_0_541196100); /* c6 */
|
||||
/* Add fudge factor here for final descale. */
|
||||
tmp0 += ONE << (CONST_BITS-PASS1_BITS-4);
|
||||
z1 = MULTIPLY(z2 + z3, FIX_0_541196100); /* c6 */
|
||||
/* Add fudge factor here for final descale. */
|
||||
z1 += ONE << (CONST_BITS-3-1);
|
||||
tmp1 = z1 + MULTIPLY(z2, FIX_0_765366865); /* c2-c6 */
|
||||
tmp3 = z1 - MULTIPLY(z3, FIX_1_847759065); /* c2+c6 */
|
||||
|
||||
dataptr[1] = (DCTELEM)
|
||||
RIGHT_SHIFT(tmp0 + MULTIPLY(tmp10, FIX_0_765366865), /* c2-c6 */
|
||||
CONST_BITS-PASS1_BITS-3);
|
||||
dataptr[3] = (DCTELEM)
|
||||
RIGHT_SHIFT(tmp0 - MULTIPLY(tmp11, FIX_1_847759065), /* c2+c6 */
|
||||
CONST_BITS-PASS1_BITS-3);
|
||||
/* Row 1 */
|
||||
elemptr = sample_data[1] + start_col;
|
||||
|
||||
dataptr += DCTSIZE; /* advance pointer to next row */
|
||||
}
|
||||
/* Even part */
|
||||
|
||||
tmp4 = GETJSAMPLE(elemptr[0]) + GETJSAMPLE(elemptr[3]);
|
||||
tmp5 = GETJSAMPLE(elemptr[1]) + GETJSAMPLE(elemptr[2]);
|
||||
|
||||
tmp10 = tmp4 + tmp5;
|
||||
tmp12 = tmp4 - tmp5;
|
||||
|
||||
/* Odd part */
|
||||
|
||||
z2 = GETJSAMPLE(elemptr[0]) - GETJSAMPLE(elemptr[3]);
|
||||
z3 = GETJSAMPLE(elemptr[1]) - GETJSAMPLE(elemptr[2]);
|
||||
|
||||
z1 = MULTIPLY(z2 + z3, FIX_0_541196100); /* c6 */
|
||||
tmp11 = z1 + MULTIPLY(z2, FIX_0_765366865); /* c2-c6 */
|
||||
tmp13 = z1 - MULTIPLY(z3, FIX_1_847759065); /* c2+c6 */
|
||||
|
||||
/* Pass 2: process columns.
|
||||
* We remove the PASS1_BITS scaling, but leave the results scaled up
|
||||
* by an overall factor of 8.
|
||||
* We leave the results scaled up by an overall factor of 8.
|
||||
* We must also scale the output by (8/4)*(8/2) = 2**3.
|
||||
*/
|
||||
|
||||
dataptr = data;
|
||||
for (ctr = 0; ctr < 4; ctr++) {
|
||||
/* Even part */
|
||||
/* Column 0 */
|
||||
/* Apply unsigned->signed conversion. */
|
||||
data[DCTSIZE*0] = (tmp0 + tmp10 - 8 * CENTERJSAMPLE) << 3;
|
||||
data[DCTSIZE*1] = (tmp0 - tmp10) << 3;
|
||||
|
||||
/* Add fudge factor here for final descale. */
|
||||
tmp0 = dataptr[DCTSIZE*0] + (ONE << (PASS1_BITS-1));
|
||||
tmp1 = dataptr[DCTSIZE*1];
|
||||
/* Column 1 */
|
||||
data[DCTSIZE*0+1] = (DCTELEM) RIGHT_SHIFT(tmp1 + tmp11, CONST_BITS-3);
|
||||
data[DCTSIZE*1+1] = (DCTELEM) RIGHT_SHIFT(tmp1 - tmp11, CONST_BITS-3);
|
||||
|
||||
dataptr[DCTSIZE*0] = (DCTELEM) RIGHT_SHIFT(tmp0 + tmp1, PASS1_BITS);
|
||||
/* Column 2 */
|
||||
data[DCTSIZE*0+2] = (tmp2 + tmp12) << 3;
|
||||
data[DCTSIZE*1+2] = (tmp2 - tmp12) << 3;
|
||||
|
||||
/* Odd part */
|
||||
|
||||
dataptr[DCTSIZE*1] = (DCTELEM) RIGHT_SHIFT(tmp0 - tmp1, PASS1_BITS);
|
||||
|
||||
dataptr++; /* advance pointer to next column */
|
||||
}
|
||||
/* Column 3 */
|
||||
data[DCTSIZE*0+3] = (DCTELEM) RIGHT_SHIFT(tmp3 + tmp13, CONST_BITS-3);
|
||||
data[DCTSIZE*1+3] = (DCTELEM) RIGHT_SHIFT(tmp3 - tmp13, CONST_BITS-3);
|
||||
}
|
||||
|
||||
|
||||
@@ -4312,7 +4318,6 @@ jpeg_fdct_2x4 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
|
||||
|
||||
/* Pass 1: process rows.
|
||||
* Note results are scaled up by sqrt(8) compared to a true DCT.
|
||||
* We must also scale the output by (8/2)*(8/4) = 2**3, which we add here.
|
||||
*/
|
||||
|
||||
dataptr = data;
|
||||
@@ -4325,17 +4330,18 @@ jpeg_fdct_2x4 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
|
||||
tmp1 = GETJSAMPLE(elemptr[1]);
|
||||
|
||||
/* Apply unsigned->signed conversion. */
|
||||
dataptr[0] = (DCTELEM) ((tmp0 + tmp1 - 2 * CENTERJSAMPLE) << 3);
|
||||
dataptr[0] = (DCTELEM) (tmp0 + tmp1 - 2 * CENTERJSAMPLE);
|
||||
|
||||
/* Odd part */
|
||||
|
||||
dataptr[1] = (DCTELEM) ((tmp0 - tmp1) << 3);
|
||||
dataptr[1] = (DCTELEM) (tmp0 - tmp1);
|
||||
|
||||
dataptr += DCTSIZE; /* advance pointer to next row */
|
||||
}
|
||||
|
||||
/* Pass 2: process columns.
|
||||
* We leave the results scaled up by an overall factor of 8.
|
||||
* We must also scale the output by (8/2)*(8/4) = 2**3.
|
||||
* 4-point FDCT kernel,
|
||||
* cK represents sqrt(2) * cos(K*pi/16) [refers to 8-point FDCT].
|
||||
*/
|
||||
@@ -4350,21 +4356,21 @@ jpeg_fdct_2x4 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
|
||||
tmp10 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*3];
|
||||
tmp11 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*2];
|
||||
|
||||
dataptr[DCTSIZE*0] = (DCTELEM) (tmp0 + tmp1);
|
||||
dataptr[DCTSIZE*2] = (DCTELEM) (tmp0 - tmp1);
|
||||
dataptr[DCTSIZE*0] = (DCTELEM) ((tmp0 + tmp1) << 3);
|
||||
dataptr[DCTSIZE*2] = (DCTELEM) ((tmp0 - tmp1) << 3);
|
||||
|
||||
/* Odd part */
|
||||
|
||||
tmp0 = MULTIPLY(tmp10 + tmp11, FIX_0_541196100); /* c6 */
|
||||
/* Add fudge factor here for final descale. */
|
||||
tmp0 += ONE << (CONST_BITS-1);
|
||||
tmp0 += ONE << (CONST_BITS-3-1);
|
||||
|
||||
dataptr[DCTSIZE*1] = (DCTELEM)
|
||||
RIGHT_SHIFT(tmp0 + MULTIPLY(tmp10, FIX_0_765366865), /* c2-c6 */
|
||||
CONST_BITS);
|
||||
CONST_BITS-3);
|
||||
dataptr[DCTSIZE*3] = (DCTELEM)
|
||||
RIGHT_SHIFT(tmp0 - MULTIPLY(tmp11, FIX_1_847759065), /* c2+c6 */
|
||||
CONST_BITS);
|
||||
CONST_BITS-3);
|
||||
|
||||
dataptr++; /* advance pointer to next column */
|
||||
}
|
||||
|
||||
Vendored
+6
-6
@@ -2,7 +2,7 @@
|
||||
* jidctint.c
|
||||
*
|
||||
* Copyright (C) 1991-1998, Thomas G. Lane.
|
||||
* Modification developed 2002-2016 by Guido Vollbeding.
|
||||
* Modification developed 2002-2018 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -1474,7 +1474,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).
|
||||
@@ -3675,7 +3675,7 @@ jpeg_idct_10x5 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
|
||||
/*
|
||||
* Perform dequantization and inverse DCT on one block of coefficients,
|
||||
* producing a 8x4 output block.
|
||||
* producing an 8x4 output block.
|
||||
*
|
||||
* 4-point IDCT in pass 1 (columns), 8-point in pass 2 (rows).
|
||||
*/
|
||||
@@ -3835,7 +3835,7 @@ jpeg_idct_8x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
|
||||
/*
|
||||
* Perform dequantization and inverse DCT on one block of coefficients,
|
||||
* producing a reduced-size 6x3 output block.
|
||||
* producing a 6x3 output block.
|
||||
*
|
||||
* 3-point IDCT in pass 1 (columns), 6-point in pass 2 (rows).
|
||||
*/
|
||||
@@ -4082,7 +4082,7 @@ jpeg_idct_2x1 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
|
||||
/*
|
||||
* Perform dequantization and inverse DCT on one block of coefficients,
|
||||
* producing a 8x16 output block.
|
||||
* producing an 8x16 output block.
|
||||
*
|
||||
* 16-point IDCT in pass 1 (columns), 8-point in pass 2 (rows).
|
||||
*/
|
||||
@@ -5004,7 +5004,7 @@ jpeg_idct_4x8 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
|
||||
/*
|
||||
* Perform dequantization and inverse DCT on one block of coefficients,
|
||||
* producing a reduced-size 3x6 output block.
|
||||
* producing a 3x6 output block.
|
||||
*
|
||||
* 6-point IDCT in pass 1 (columns), 3-point in pass 2 (rows).
|
||||
*/
|
||||
|
||||
Vendored
+28
-32
@@ -2,7 +2,7 @@
|
||||
* jmemmgr.c
|
||||
*
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Modified 2011-2012 by Guido Vollbeding.
|
||||
* Modified 2011-2019 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -130,7 +130,7 @@ typedef struct {
|
||||
jvirt_barray_ptr virt_barray_list;
|
||||
|
||||
/* This counts total space obtained from jpeg_get_small/large */
|
||||
long total_space_allocated;
|
||||
size_t total_space_allocated;
|
||||
|
||||
/* alloc_sarray and alloc_barray set this value for use by virtual
|
||||
* array routines.
|
||||
@@ -195,7 +195,7 @@ print_mem_stats (j_common_ptr cinfo, int pool_id)
|
||||
* This is helpful because message parm array can't handle longs.
|
||||
*/
|
||||
fprintf(stderr, "Freeing pool %d, total space = %ld\n",
|
||||
pool_id, mem->total_space_allocated);
|
||||
pool_id, (long) mem->total_space_allocated);
|
||||
|
||||
for (lhdr_ptr = mem->large_list[pool_id]; lhdr_ptr != NULL;
|
||||
lhdr_ptr = lhdr_ptr->hdr.next) {
|
||||
@@ -260,11 +260,11 @@ alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
|
||||
{
|
||||
my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
|
||||
small_pool_ptr hdr_ptr, prev_hdr_ptr;
|
||||
char * data_ptr;
|
||||
size_t odd_bytes, min_request, slop;
|
||||
char * data_ptr;
|
||||
|
||||
/* Check for unsatisfiable request (do now to ensure no overflow below) */
|
||||
if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(small_pool_hdr)))
|
||||
if (sizeofobject > (size_t) MAX_ALLOC_CHUNK - SIZEOF(small_pool_hdr))
|
||||
out_of_memory(cinfo, 1); /* request exceeds malloc's ability */
|
||||
|
||||
/* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
|
||||
@@ -293,8 +293,8 @@ alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
|
||||
else
|
||||
slop = extra_pool_slop[pool_id];
|
||||
/* Don't ask for more than MAX_ALLOC_CHUNK */
|
||||
if (slop > (size_t) (MAX_ALLOC_CHUNK-min_request))
|
||||
slop = (size_t) (MAX_ALLOC_CHUNK-min_request);
|
||||
if (slop > (size_t) MAX_ALLOC_CHUNK - min_request)
|
||||
slop = (size_t) MAX_ALLOC_CHUNK - min_request;
|
||||
/* Try to get space, if fail reduce slop and try again */
|
||||
for (;;) {
|
||||
hdr_ptr = (small_pool_ptr) jpeg_get_small(cinfo, min_request + slop);
|
||||
@@ -348,7 +348,7 @@ alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
|
||||
size_t odd_bytes;
|
||||
|
||||
/* Check for unsatisfiable request (do now to ensure no overflow below) */
|
||||
if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)))
|
||||
if (sizeofobject > (size_t) MAX_ALLOC_CHUNK - SIZEOF(large_pool_hdr))
|
||||
out_of_memory(cinfo, 3); /* request exceeds malloc's ability */
|
||||
|
||||
/* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
|
||||
@@ -404,7 +404,7 @@ alloc_sarray (j_common_ptr cinfo, int pool_id,
|
||||
long ltemp;
|
||||
|
||||
/* Calculate max # of rows allowed in one allocation chunk */
|
||||
ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
|
||||
ltemp = (MAX_ALLOC_CHUNK - SIZEOF(large_pool_hdr)) /
|
||||
((long) samplesperrow * SIZEOF(JSAMPLE));
|
||||
if (ltemp <= 0)
|
||||
ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
|
||||
@@ -416,15 +416,14 @@ alloc_sarray (j_common_ptr cinfo, int pool_id,
|
||||
|
||||
/* Get space for row pointers (small object) */
|
||||
result = (JSAMPARRAY) alloc_small(cinfo, pool_id,
|
||||
(size_t) (numrows * SIZEOF(JSAMPROW)));
|
||||
(size_t) numrows * SIZEOF(JSAMPROW));
|
||||
|
||||
/* Get the rows themselves (large objects) */
|
||||
currow = 0;
|
||||
while (currow < numrows) {
|
||||
rowsperchunk = MIN(rowsperchunk, numrows - currow);
|
||||
workspace = (JSAMPROW) alloc_large(cinfo, pool_id,
|
||||
(size_t) ((size_t) rowsperchunk * (size_t) samplesperrow
|
||||
* SIZEOF(JSAMPLE)));
|
||||
(size_t) rowsperchunk * (size_t) samplesperrow * SIZEOF(JSAMPLE));
|
||||
for (i = rowsperchunk; i > 0; i--) {
|
||||
result[currow++] = workspace;
|
||||
workspace += samplesperrow;
|
||||
@@ -452,7 +451,7 @@ alloc_barray (j_common_ptr cinfo, int pool_id,
|
||||
long ltemp;
|
||||
|
||||
/* Calculate max # of rows allowed in one allocation chunk */
|
||||
ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
|
||||
ltemp = (MAX_ALLOC_CHUNK - SIZEOF(large_pool_hdr)) /
|
||||
((long) blocksperrow * SIZEOF(JBLOCK));
|
||||
if (ltemp <= 0)
|
||||
ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
|
||||
@@ -464,15 +463,14 @@ alloc_barray (j_common_ptr cinfo, int pool_id,
|
||||
|
||||
/* Get space for row pointers (small object) */
|
||||
result = (JBLOCKARRAY) alloc_small(cinfo, pool_id,
|
||||
(size_t) (numrows * SIZEOF(JBLOCKROW)));
|
||||
(size_t) numrows * SIZEOF(JBLOCKROW));
|
||||
|
||||
/* Get the rows themselves (large objects) */
|
||||
currow = 0;
|
||||
while (currow < numrows) {
|
||||
rowsperchunk = MIN(rowsperchunk, numrows - currow);
|
||||
workspace = (JBLOCKROW) alloc_large(cinfo, pool_id,
|
||||
(size_t) ((size_t) rowsperchunk * (size_t) blocksperrow
|
||||
* SIZEOF(JBLOCK)));
|
||||
(size_t) rowsperchunk * (size_t) blocksperrow * SIZEOF(JBLOCK));
|
||||
for (i = rowsperchunk; i > 0; i--) {
|
||||
result[currow++] = workspace;
|
||||
workspace += blocksperrow;
|
||||
@@ -585,8 +583,8 @@ realize_virt_arrays (j_common_ptr cinfo)
|
||||
/* Allocate the in-memory buffers for any unrealized virtual arrays */
|
||||
{
|
||||
my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
|
||||
long space_per_minheight, maximum_space, avail_mem;
|
||||
long minheights, max_minheights;
|
||||
long bytesperrow, space_per_minheight, maximum_space;
|
||||
long avail_mem, minheights, max_minheights;
|
||||
jvirt_sarray_ptr sptr;
|
||||
jvirt_barray_ptr bptr;
|
||||
|
||||
@@ -598,18 +596,16 @@ realize_virt_arrays (j_common_ptr cinfo)
|
||||
maximum_space = 0;
|
||||
for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
|
||||
if (sptr->mem_buffer == NULL) { /* if not realized yet */
|
||||
space_per_minheight += (long) sptr->maxaccess *
|
||||
(long) sptr->samplesperrow * SIZEOF(JSAMPLE);
|
||||
maximum_space += (long) sptr->rows_in_array *
|
||||
(long) sptr->samplesperrow * SIZEOF(JSAMPLE);
|
||||
bytesperrow = (long) sptr->samplesperrow * SIZEOF(JSAMPLE);
|
||||
space_per_minheight += (long) sptr->maxaccess * bytesperrow;
|
||||
maximum_space += (long) sptr->rows_in_array * bytesperrow;
|
||||
}
|
||||
}
|
||||
for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
|
||||
if (bptr->mem_buffer == NULL) { /* if not realized yet */
|
||||
space_per_minheight += (long) bptr->maxaccess *
|
||||
(long) bptr->blocksperrow * SIZEOF(JBLOCK);
|
||||
maximum_space += (long) bptr->rows_in_array *
|
||||
(long) bptr->blocksperrow * SIZEOF(JBLOCK);
|
||||
bytesperrow = (long) bptr->blocksperrow * SIZEOF(JBLOCK);
|
||||
space_per_minheight += (long) bptr->maxaccess * bytesperrow;
|
||||
maximum_space += (long) bptr->rows_in_array * bytesperrow;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -618,7 +614,7 @@ realize_virt_arrays (j_common_ptr cinfo)
|
||||
|
||||
/* Determine amount of memory to actually use; this is system-dependent. */
|
||||
avail_mem = jpeg_mem_available(cinfo, space_per_minheight, maximum_space,
|
||||
mem->total_space_allocated);
|
||||
(long) mem->total_space_allocated);
|
||||
|
||||
/* If the maximum space needed is available, make all the buffers full
|
||||
* height; otherwise parcel it out with the same number of minheights
|
||||
@@ -694,7 +690,7 @@ do_sarray_io (j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing)
|
||||
long bytesperrow, file_offset, byte_count, rows, thisrow, i;
|
||||
|
||||
bytesperrow = (long) ptr->samplesperrow * SIZEOF(JSAMPLE);
|
||||
file_offset = ptr->cur_start_row * bytesperrow;
|
||||
file_offset = (long) ptr->cur_start_row * bytesperrow;
|
||||
/* Loop to read or write each allocation chunk in mem_buffer */
|
||||
for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) {
|
||||
/* One chunk, but check for short chunk at end of buffer */
|
||||
@@ -727,7 +723,7 @@ do_barray_io (j_common_ptr cinfo, jvirt_barray_ptr ptr, boolean writing)
|
||||
long bytesperrow, file_offset, byte_count, rows, thisrow, i;
|
||||
|
||||
bytesperrow = (long) ptr->blocksperrow * SIZEOF(JBLOCK);
|
||||
file_offset = ptr->cur_start_row * bytesperrow;
|
||||
file_offset = (long) ptr->cur_start_row * bytesperrow;
|
||||
/* Loop to read or write each allocation chunk in mem_buffer */
|
||||
for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) {
|
||||
/* One chunk, but check for short chunk at end of buffer */
|
||||
@@ -771,7 +767,7 @@ access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr,
|
||||
|
||||
/* Make the desired part of the virtual array accessible */
|
||||
if (start_row < ptr->cur_start_row ||
|
||||
end_row > ptr->cur_start_row+ptr->rows_in_mem) {
|
||||
end_row > ptr->cur_start_row + ptr->rows_in_mem) {
|
||||
if (! ptr->b_s_open)
|
||||
ERREXIT(cinfo, JERR_VIRTUAL_BUG);
|
||||
/* Flush old buffer contents if necessary */
|
||||
@@ -856,7 +852,7 @@ access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr,
|
||||
|
||||
/* Make the desired part of the virtual array accessible */
|
||||
if (start_row < ptr->cur_start_row ||
|
||||
end_row > ptr->cur_start_row+ptr->rows_in_mem) {
|
||||
end_row > ptr->cur_start_row + ptr->rows_in_mem) {
|
||||
if (! ptr->b_s_open)
|
||||
ERREXIT(cinfo, JERR_VIRTUAL_BUG);
|
||||
/* Flush old buffer contents if necessary */
|
||||
@@ -1093,7 +1089,7 @@ jinit_memory_mgr (j_common_ptr cinfo)
|
||||
mem->total_space_allocated = SIZEOF(my_memory_mgr);
|
||||
|
||||
/* Declare ourselves open for business */
|
||||
cinfo->mem = & mem->pub;
|
||||
cinfo->mem = &mem->pub;
|
||||
|
||||
/* Check for an environment variable JPEGMEM; if found, override the
|
||||
* default max_memory setting from jpeg_mem_init. Note that the
|
||||
|
||||
Vendored
+6
-2
@@ -2,6 +2,7 @@
|
||||
* jmemnobs.c
|
||||
*
|
||||
* Copyright (C) 1992-1996, Thomas G. Lane.
|
||||
* Modified 2019 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -12,7 +13,7 @@
|
||||
* This is very portable in the sense that it'll compile on almost anything,
|
||||
* but you'd better have lots of main memory (or virtual memory) if you want
|
||||
* to process big images.
|
||||
* Note that the max_memory_to_use option is ignored by this implementation.
|
||||
* Note that the max_memory_to_use option is respected by this implementation.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
@@ -66,13 +67,16 @@ jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
|
||||
|
||||
/*
|
||||
* This routine computes the total memory space available for allocation.
|
||||
* Here we always say, "we got all you want bud!"
|
||||
*/
|
||||
|
||||
GLOBAL(long)
|
||||
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
|
||||
long max_bytes_needed, long already_allocated)
|
||||
{
|
||||
if (cinfo->mem->max_memory_to_use)
|
||||
return cinfo->mem->max_memory_to_use - already_allocated;
|
||||
|
||||
/* Here we say, "we got all you want bud!" */
|
||||
return max_bytes_needed;
|
||||
}
|
||||
|
||||
|
||||
Vendored
+8
-1
@@ -2,7 +2,7 @@
|
||||
* jpegint.h
|
||||
*
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Modified 1997-2017 by Guido Vollbeding.
|
||||
* Modified 1997-2019 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -302,6 +302,13 @@ struct jpeg_color_quantizer {
|
||||
#define RIGHT_SHIFT(x,shft) ((x) >> (shft))
|
||||
#endif
|
||||
|
||||
/* Descale and correctly round an INT32 value that's scaled by N bits.
|
||||
* We assume RIGHT_SHIFT rounds towards minus infinity, so adding
|
||||
* the fudge factor is correct for either sign of X.
|
||||
*/
|
||||
|
||||
#define DESCALE(x,n) RIGHT_SHIFT((x) + ((INT32) 1 << ((n)-1)), n)
|
||||
|
||||
|
||||
/* Short forms of external names for systems with brain-damaged linkers. */
|
||||
|
||||
|
||||
Vendored
+7
-4
@@ -2,7 +2,7 @@
|
||||
* jpeglib.h
|
||||
*
|
||||
* Copyright (C) 1991-1998, Thomas G. Lane.
|
||||
* Modified 2002-2017 by Guido Vollbeding.
|
||||
* Modified 2002-2019 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -39,7 +39,7 @@ extern "C" {
|
||||
|
||||
#define JPEG_LIB_VERSION 90 /* Compatibility version 9.0 */
|
||||
#define JPEG_LIB_VERSION_MAJOR 9
|
||||
#define JPEG_LIB_VERSION_MINOR 3
|
||||
#define JPEG_LIB_VERSION_MINOR 4
|
||||
|
||||
|
||||
/* Various constants determining the sizes of things.
|
||||
@@ -909,6 +909,7 @@ typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo));
|
||||
#define jpeg_suppress_tables jSuppressTables
|
||||
#define jpeg_alloc_quant_table jAlcQTable
|
||||
#define jpeg_alloc_huff_table jAlcHTable
|
||||
#define jpeg_std_huff_table jStdHTable
|
||||
#define jpeg_start_compress jStrtCompress
|
||||
#define jpeg_write_scanlines jWrtScanlines
|
||||
#define jpeg_finish_compress jFinCompress
|
||||
@@ -977,10 +978,10 @@ EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile));
|
||||
/* Data source and destination managers: memory buffers. */
|
||||
EXTERN(void) jpeg_mem_dest JPP((j_compress_ptr cinfo,
|
||||
unsigned char ** outbuffer,
|
||||
unsigned long * outsize));
|
||||
size_t * outsize));
|
||||
EXTERN(void) jpeg_mem_src JPP((j_decompress_ptr cinfo,
|
||||
const unsigned char * inbuffer,
|
||||
unsigned long insize));
|
||||
size_t insize));
|
||||
|
||||
/* Default parameter setup for compression */
|
||||
EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo));
|
||||
@@ -1005,6 +1006,8 @@ EXTERN(void) jpeg_suppress_tables JPP((j_compress_ptr cinfo,
|
||||
boolean suppress));
|
||||
EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table JPP((j_common_ptr cinfo));
|
||||
EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table JPP((j_common_ptr cinfo));
|
||||
EXTERN(JHUFF_TBL *) jpeg_std_huff_table JPP((j_common_ptr cinfo,
|
||||
boolean isDC, int tblno));
|
||||
|
||||
/* Main entry points for compression */
|
||||
EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo,
|
||||
|
||||
Vendored
+3
-3
@@ -2,7 +2,7 @@
|
||||
* jutils.c
|
||||
*
|
||||
* Copyright (C) 1991-1996, Thomas G. Lane.
|
||||
* Modified 2009-2011 by Guido Vollbeding.
|
||||
* Modified 2009-2019 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -185,7 +185,7 @@ jcopy_sample_rows (JSAMPARRAY input_array, int source_row,
|
||||
{
|
||||
register JSAMPROW inptr, outptr;
|
||||
#ifdef FMEMCOPY
|
||||
register size_t count = (size_t) (num_cols * SIZEOF(JSAMPLE));
|
||||
register size_t count = (size_t) num_cols * SIZEOF(JSAMPLE);
|
||||
#else
|
||||
register JDIMENSION count;
|
||||
#endif
|
||||
@@ -213,7 +213,7 @@ jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row,
|
||||
/* Copy a row of coefficient blocks from one place to another. */
|
||||
{
|
||||
#ifdef FMEMCOPY
|
||||
FMEMCOPY(output_row, input_row, num_blocks * (DCTSIZE2 * SIZEOF(JCOEF)));
|
||||
FMEMCOPY(output_row, input_row, (size_t) num_blocks * (DCTSIZE2 * SIZEOF(JCOEF)));
|
||||
#else
|
||||
register JCOEFPTR inptr, outptr;
|
||||
register long count;
|
||||
|
||||
Vendored
+3
-3
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* jversion.h
|
||||
*
|
||||
* Copyright (C) 1991-2018, Thomas G. Lane, Guido Vollbeding.
|
||||
* Copyright (C) 1991-2020, Thomas G. Lane, Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -9,6 +9,6 @@
|
||||
*/
|
||||
|
||||
|
||||
#define JVERSION "9c 14-Jan-2018"
|
||||
#define JVERSION "9d 12-Jan-2020"
|
||||
|
||||
#define JCOPYRIGHT "Copyright (C) 2018, Thomas G. Lane, Guido Vollbeding"
|
||||
#define JCOPYRIGHT "Copyright (C) 2020, Thomas G. Lane, Guido Vollbeding"
|
||||
|
||||
Vendored
+3
-5
@@ -22,7 +22,7 @@
|
||||
# sqfu@openailab.com
|
||||
#
|
||||
|
||||
SET(TENGINE_COMMIT_VERSION "2f3cd86217f3530c8e4a82f3ed5af14c7a4e3943")
|
||||
SET(TENGINE_COMMIT_VERSION "8a4c58e0e05cd850f4bb0936a330edc86dc0e28c")
|
||||
SET(OCV_TENGINE_DIR "${OpenCV_BINARY_DIR}/3rdparty/libtengine")
|
||||
SET(OCV_TENGINE_SOURCE_PATH "${OCV_TENGINE_DIR}/Tengine-${TENGINE_COMMIT_VERSION}")
|
||||
|
||||
@@ -34,7 +34,7 @@ IF(EXISTS "${OCV_TENGINE_SOURCE_PATH}")
|
||||
ELSE()
|
||||
SET(OCV_TENGINE_FILENAME "${TENGINE_COMMIT_VERSION}.zip")#name2
|
||||
SET(OCV_TENGINE_URL "https://github.com/OAID/Tengine/archive/") #url2
|
||||
SET(tengine_md5sum 9124324b6e2b350012e46ae1db4bad7d) #md5sum2
|
||||
SET(tengine_md5sum f51ca8f3963faeeff3f019a6f6edc206) #md5sum2
|
||||
|
||||
#MESSAGE(STATUS "**** TENGINE DOWNLOAD BEGIN ****")
|
||||
ocv_download(FILENAME ${OCV_TENGINE_FILENAME}
|
||||
@@ -69,7 +69,6 @@ if(BUILD_TENGINE)
|
||||
elseif(${ANDROID_ABI} STREQUAL "arm64-v8a")
|
||||
SET(CONFIG_ARCH_ARM64 ON)
|
||||
endif()
|
||||
SET(Tengine_LIB "tengine" CACHE INTERNAL "")
|
||||
else()
|
||||
# linux system
|
||||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL arm)
|
||||
@@ -77,7 +76,6 @@ if(BUILD_TENGINE)
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64) ## AARCH64
|
||||
SET(CONFIG_ARCH_ARM64 ON)
|
||||
endif()
|
||||
SET(Tengine_LIB "tengine" CACHE INTERNAL "")
|
||||
endif()
|
||||
|
||||
SET(BUILT_IN_OPENCV ON) ## set for tengine compile discern .
|
||||
@@ -86,6 +84,6 @@ if(BUILD_TENGINE)
|
||||
add_subdirectory("${OCV_TENGINE_SOURCE_PATH}" "${OCV_TENGINE_DIR}/build")
|
||||
else()
|
||||
message(WARNING "TENGINE: Missing 'CMakeLists.txt' in source code package: ${OCV_TENGINE_SOURCE_PATH}")
|
||||
SET(HAVE_TENGINE 1)
|
||||
endif()
|
||||
SET(Tengine_LIB "tengine" CACHE INTERNAL "")
|
||||
endif()
|
||||
|
||||
@@ -1652,6 +1652,10 @@ if(ENABLE_CONFIG_VERIFICATION)
|
||||
ocv_verify_config()
|
||||
endif()
|
||||
|
||||
if(HAVE_CUDA AND COMMAND CUDA_BUILD_CLEAN_TARGET)
|
||||
CUDA_BUILD_CLEAN_TARGET()
|
||||
endif()
|
||||
|
||||
ocv_cmake_hook(POST_FINALIZE)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
@@ -189,7 +189,6 @@ if(CV_GCC OR CV_CLANG)
|
||||
|
||||
# Profiling?
|
||||
if(ENABLE_PROFILING)
|
||||
add_extra_compiler_option("-pg -g")
|
||||
# turn off incompatible options
|
||||
foreach(flags CMAKE_CXX_FLAGS CMAKE_C_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG CMAKE_C_FLAGS_DEBUG
|
||||
OPENCV_EXTRA_FLAGS_RELEASE OPENCV_EXTRA_FLAGS_DEBUG OPENCV_EXTRA_C_FLAGS OPENCV_EXTRA_CXX_FLAGS)
|
||||
@@ -197,6 +196,9 @@ if(CV_GCC OR CV_CLANG)
|
||||
string(REPLACE "-ffunction-sections" "" ${flags} "${${flags}}")
|
||||
string(REPLACE "-fdata-sections" "" ${flags} "${${flags}}")
|
||||
endforeach()
|
||||
# -pg should be placed both in the linker and in the compiler settings
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg")
|
||||
add_extra_compiler_option("-pg -g")
|
||||
else()
|
||||
if(MSVC)
|
||||
# TODO: Clang/C2 is not supported
|
||||
|
||||
+198
-26
@@ -1,13 +1,14 @@
|
||||
if(WIN32 AND NOT MSVC)
|
||||
if((WIN32 AND NOT MSVC) OR OPENCV_CMAKE_FORCE_CUDA)
|
||||
message(STATUS "CUDA compilation is disabled (due to only Visual Studio compiler supported on your platform).")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(NOT UNIX AND CV_CLANG)
|
||||
if((NOT UNIX AND CV_CLANG) OR OPENCV_CMAKE_FORCE_CUDA)
|
||||
message(STATUS "CUDA compilation is disabled (due to Clang unsupported on your platform).")
|
||||
return()
|
||||
endif()
|
||||
|
||||
#set(OPENCV_CMAKE_CUDA_DEBUG 1)
|
||||
|
||||
if(((NOT CMAKE_VERSION VERSION_LESS "3.9.0") # requires https://gitlab.kitware.com/cmake/cmake/merge_requests/663
|
||||
OR OPENCV_CUDA_FORCE_EXTERNAL_CMAKE_MODULE)
|
||||
@@ -28,6 +29,11 @@ endif()
|
||||
|
||||
if(CUDA_FOUND)
|
||||
set(HAVE_CUDA 1)
|
||||
if(NOT CUDA_VERSION VERSION_LESS 11.0)
|
||||
# CUDA 11.0 removes nppicom
|
||||
ocv_list_filterout(CUDA_nppi_LIBRARY "nppicom")
|
||||
ocv_list_filterout(CUDA_npp_LIBRARY "nppicom")
|
||||
endif()
|
||||
|
||||
if(WITH_CUFFT)
|
||||
set(HAVE_CUFFT 1)
|
||||
@@ -38,11 +44,31 @@ if(CUDA_FOUND)
|
||||
endif()
|
||||
|
||||
if(WITH_NVCUVID)
|
||||
macro(ocv_cuda_SEARCH_NVCUVID_HEADER _filename _result)
|
||||
# place header file under CUDA_TOOLKIT_TARGET_DIR or CUDA_TOOLKIT_ROOT_DIR
|
||||
find_path(_header_result
|
||||
${_filename}
|
||||
PATHS "${CUDA_TOOLKIT_TARGET_DIR}" "${CUDA_TOOLKIT_ROOT_DIR}"
|
||||
ENV CUDA_PATH
|
||||
ENV CUDA_INC_PATH
|
||||
PATH_SUFFIXES include
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
if("x${_header_result}" STREQUAL "x_header_result-NOTFOUND")
|
||||
set(${_result} 0)
|
||||
else()
|
||||
set(${_result} 1)
|
||||
endif()
|
||||
unset(_header_result CACHE)
|
||||
endmacro()
|
||||
ocv_cuda_SEARCH_NVCUVID_HEADER("nvcuvid.h" HAVE_NVCUVID_HEADER)
|
||||
ocv_cuda_SEARCH_NVCUVID_HEADER("dynlink_nvcuvid.h" HAVE_DYNLINK_NVCUVID_HEADER)
|
||||
find_cuda_helper_libs(nvcuvid)
|
||||
if(WIN32)
|
||||
find_cuda_helper_libs(nvcuvenc)
|
||||
endif()
|
||||
if(CUDA_nvcuvid_LIBRARY)
|
||||
if(CUDA_nvcuvid_LIBRARY AND (${HAVE_NVCUVID_HEADER} OR ${HAVE_DYNLINK_NVCUVID_HEADER}))
|
||||
# make sure to have both header and library before enabling
|
||||
set(HAVE_NVCUVID 1)
|
||||
endif()
|
||||
if(CUDA_nvcuvenc_LIBRARY)
|
||||
@@ -52,13 +78,14 @@ if(CUDA_FOUND)
|
||||
|
||||
message(STATUS "CUDA detected: " ${CUDA_VERSION})
|
||||
|
||||
set(_generations "Fermi" "Kepler" "Maxwell" "Pascal" "Volta" "Turing")
|
||||
set(_generations "Fermi" "Kepler" "Maxwell" "Pascal" "Volta" "Turing" "Ampere")
|
||||
set(_arch_fermi "2.0")
|
||||
set(_arch_kepler "3.0;3.5;3.7")
|
||||
set(_arch_maxwell "5.0;5.2")
|
||||
set(_arch_pascal "6.0;6.1")
|
||||
set(_arch_volta "7.0")
|
||||
set(_arch_turing "7.5")
|
||||
set(_arch_ampere "8.0")
|
||||
if(NOT CMAKE_CROSSCOMPILING)
|
||||
list(APPEND _generations "Auto")
|
||||
endif()
|
||||
@@ -76,36 +103,104 @@ if(CUDA_FOUND)
|
||||
unset(CUDA_ARCH_PTX CACHE)
|
||||
endif()
|
||||
|
||||
if(OPENCV_CUDA_DETECTION_NVCC_FLAGS MATCHES "-ccbin")
|
||||
# already specified by user
|
||||
elseif(CUDA_HOST_COMPILER AND EXISTS "${CUDA_HOST_COMPILER}")
|
||||
get_filename_component(c_compiler_realpath "${CMAKE_C_COMPILER}" REALPATH)
|
||||
# C compiler doesn't work with --run option, forcing C++ compiler instead
|
||||
if(CUDA_HOST_COMPILER STREQUAL c_compiler_realpath OR CUDA_HOST_COMPILER STREQUAL CMAKE_C_COMPILER)
|
||||
if(DEFINED CMAKE_CXX_COMPILER)
|
||||
get_filename_component(cxx_compiler_realpath "${CMAKE_CXX_COMPILER}" REALPATH)
|
||||
LIST(APPEND OPENCV_CUDA_DETECTION_NVCC_FLAGS -ccbin "${cxx_compiler_realpath}")
|
||||
else()
|
||||
message(STATUS "CUDA: CMAKE_CXX_COMPILER is not available. You may need to specify CUDA_HOST_COMPILER.")
|
||||
endif()
|
||||
else()
|
||||
LIST(APPEND OPENCV_CUDA_DETECTION_NVCC_FLAGS -ccbin "${CUDA_HOST_COMPILER}")
|
||||
endif()
|
||||
elseif(WIN32 AND CMAKE_LINKER) # Workaround for VS cl.exe not being in the env. path
|
||||
get_filename_component(host_compiler_bindir ${CMAKE_LINKER} DIRECTORY)
|
||||
LIST(APPEND OPENCV_CUDA_DETECTION_NVCC_FLAGS -ccbin "${host_compiler_bindir}")
|
||||
else()
|
||||
if(CUDA_HOST_COMPILER)
|
||||
message(STATUS "CUDA: CUDA_HOST_COMPILER='${CUDA_HOST_COMPILER}' is not valid, autodetection may not work. Specify OPENCV_CUDA_DETECTION_NVCC_FLAGS with -ccbin option for fix that")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
macro(ocv_filter_available_architecture result_list)
|
||||
if(DEFINED CUDA_SUPPORTED_CC)
|
||||
set(${result_list} "${CUDA_SUPPORTED_CC}")
|
||||
set(__cache_key_check "${ARGN} : ${CUDA_NVCC_EXECUTABLE} ${OPENCV_CUDA_DETECTION_NVCC_FLAGS}")
|
||||
if(DEFINED OPENCV_CACHE_CUDA_SUPPORTED_CC AND OPENCV_CACHE_CUDA_SUPPORTED_CC_check STREQUAL __cache_key_check)
|
||||
set(${result_list} "${OPENCV_CACHE_CUDA_SUPPORTED_CC}")
|
||||
else()
|
||||
set(CC_LIST ${ARGN})
|
||||
foreach(target_arch ${CC_LIST})
|
||||
string(REPLACE "." "" target_arch_short ${target_arch})
|
||||
string(REPLACE "." "" target_arch_short "${target_arch}")
|
||||
set(NVCC_OPTION "-gencode;arch=compute_${target_arch_short},code=sm_${target_arch_short}")
|
||||
execute_process( COMMAND "${CUDA_NVCC_EXECUTABLE}" ${NVCC_OPTION} "${OpenCV_SOURCE_DIR}/cmake/checks/OpenCVDetectCudaArch.cu"
|
||||
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/"
|
||||
RESULT_VARIABLE _nvcc_res OUTPUT_VARIABLE _nvcc_out
|
||||
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
set(_cmd "${CUDA_NVCC_EXECUTABLE}" ${OPENCV_CUDA_DETECTION_NVCC_FLAGS} ${NVCC_OPTION} "${OpenCV_SOURCE_DIR}/cmake/checks/OpenCVDetectCudaArch.cu" --compile)
|
||||
execute_process(
|
||||
COMMAND ${_cmd}
|
||||
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/"
|
||||
RESULT_VARIABLE _nvcc_res
|
||||
OUTPUT_VARIABLE _nvcc_out
|
||||
ERROR_VARIABLE _nvcc_err
|
||||
#ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
if(OPENCV_CMAKE_CUDA_DEBUG)
|
||||
message(WARNING "COMMAND: ${_cmd}")
|
||||
message(STATUS "Result: ${_nvcc_res}")
|
||||
message(STATUS "Out: ${_nvcc_out}")
|
||||
message(STATUS "Err: ${_nvcc_err}")
|
||||
endif()
|
||||
if(_nvcc_res EQUAL 0)
|
||||
set(${result_list} "${${result_list}} ${target_arch}")
|
||||
LIST(APPEND ${result_list} "${target_arch}")
|
||||
endif()
|
||||
endforeach()
|
||||
string(STRIP ${${result_list}} ${result_list})
|
||||
set(CUDA_SUPPORTED_CC ${${result_list}} CACHE INTERNAL "List of supported compute capability")
|
||||
string(STRIP "${${result_list}}" ${result_list})
|
||||
if(" ${${result_list}}" STREQUAL " ")
|
||||
message(WARNING "CUDA: Autodetection arch list is empty. Please enable OPENCV_CMAKE_CUDA_DEBUG=1 and check/specify OPENCV_CUDA_DETECTION_NVCC_FLAGS variable")
|
||||
endif()
|
||||
|
||||
# cache detected values
|
||||
set(OPENCV_CACHE_CUDA_SUPPORTED_CC ${${result_list}} CACHE INTERNAL "")
|
||||
set(OPENCV_CACHE_CUDA_SUPPORTED_CC_check "${__cache_key_check}" CACHE INTERNAL "")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(ocv_detect_native_cuda_arch status output)
|
||||
execute_process( COMMAND "${CUDA_NVCC_EXECUTABLE}" ${CUDA_NVCC_FLAGS} "${OpenCV_SOURCE_DIR}/cmake/checks/OpenCVDetectCudaArch.cu" "--run"
|
||||
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/"
|
||||
RESULT_VARIABLE ${status} OUTPUT_VARIABLE ${output}
|
||||
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
set(OPENCV_CUDA_DETECT_ARCHS_COMMAND "${CUDA_NVCC_EXECUTABLE}" ${OPENCV_CUDA_DETECTION_NVCC_FLAGS} "${OpenCV_SOURCE_DIR}/cmake/checks/OpenCVDetectCudaArch.cu" "--run")
|
||||
set(__cache_key_check "${OPENCV_CUDA_DETECT_ARCHS_COMMAND}")
|
||||
if(DEFINED OPENCV_CACHE_CUDA_ACTIVE_CC AND OPENCV_CACHE_CUDA_ACTIVE_CC_check STREQUAL __cache_key_check)
|
||||
set(${output} "${OPENCV_CACHE_CUDA_ACTIVE_CC}")
|
||||
set(${status} 0)
|
||||
else()
|
||||
execute_process(
|
||||
COMMAND ${OPENCV_CUDA_DETECT_ARCHS_COMMAND}
|
||||
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/"
|
||||
RESULT_VARIABLE ${status}
|
||||
OUTPUT_VARIABLE _nvcc_out
|
||||
ERROR_VARIABLE _nvcc_err
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
if(OPENCV_CMAKE_CUDA_DEBUG)
|
||||
message(WARNING "COMMAND: ${OPENCV_CUDA_DETECT_ARCHS_COMMAND}")
|
||||
message(STATUS "Result: ${${status}}")
|
||||
message(STATUS "Out: ${_nvcc_out}")
|
||||
message(STATUS "Err: ${_nvcc_err}")
|
||||
endif()
|
||||
string(REGEX REPLACE ".*\n" "" ${output} "${_nvcc_out}") #Strip leading warning messages, if any
|
||||
|
||||
if(${status} EQUAL 0)
|
||||
# cache detected values
|
||||
set(OPENCV_CACHE_CUDA_ACTIVE_CC ${${result_list}} CACHE INTERNAL "")
|
||||
set(OPENCV_CACHE_CUDA_ACTIVE_CC_check "${__cache_key_check}" CACHE INTERNAL "")
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(ocv_wipeout_deprecated _arch_bin_list)
|
||||
string(REPLACE "2.1" "2.1(2.0)" ${_arch_bin_list} ${${_arch_bin_list}})
|
||||
string(REPLACE "2.1" "2.1(2.0)" ${_arch_bin_list} "${${_arch_bin_list}}")
|
||||
endmacro()
|
||||
|
||||
set(__cuda_arch_ptx "")
|
||||
@@ -121,6 +216,8 @@ if(CUDA_FOUND)
|
||||
set(__cuda_arch_bin ${_arch_volta})
|
||||
elseif(CUDA_GENERATION STREQUAL "Turing")
|
||||
set(__cuda_arch_bin ${_arch_turing})
|
||||
elseif(CUDA_GENERATION STREQUAL "Ampere")
|
||||
set(__cuda_arch_bin ${_arch_ampere})
|
||||
elseif(CUDA_GENERATION STREQUAL "Auto")
|
||||
ocv_detect_native_cuda_arch(_nvcc_res _nvcc_out)
|
||||
if(NOT _nvcc_res EQUAL 0)
|
||||
@@ -128,6 +225,9 @@ if(CUDA_FOUND)
|
||||
else()
|
||||
string(REGEX MATCHALL "[0-9]+\\.[0-9]" __cuda_arch_bin "${_nvcc_out}")
|
||||
endif()
|
||||
elseif(CUDA_ARCH_BIN)
|
||||
message(STATUS "CUDA: Using CUDA_ARCH_BIN=${CUDA_ARCH_BIN}")
|
||||
set(__cuda_arch_bin ${CUDA_ARCH_BIN})
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED __cuda_arch_bin)
|
||||
@@ -135,10 +235,20 @@ if(CUDA_FOUND)
|
||||
set(__cuda_arch_bin "3.2")
|
||||
set(__cuda_arch_ptx "")
|
||||
elseif(AARCH64)
|
||||
ocv_detect_native_cuda_arch(_nvcc_res _nvcc_out)
|
||||
if(NOT CMAKE_CROSSCOMPILING)
|
||||
ocv_detect_native_cuda_arch(_nvcc_res _nvcc_out)
|
||||
else()
|
||||
set(_nvcc_res -1) # emulate error, see below
|
||||
endif()
|
||||
if(NOT _nvcc_res EQUAL 0)
|
||||
message(STATUS "Automatic detection of CUDA generation failed. Going to build for all known architectures.")
|
||||
set(__cuda_arch_bin "5.3 6.2 7.2")
|
||||
# TX1 (5.3) TX2 (6.2) Xavier (7.2) V100 (7.0)
|
||||
ocv_filter_available_architecture(__cuda_arch_bin
|
||||
5.3
|
||||
6.2
|
||||
7.2
|
||||
7.0
|
||||
)
|
||||
else()
|
||||
set(__cuda_arch_bin "${_nvcc_out}")
|
||||
endif()
|
||||
@@ -151,6 +261,7 @@ if(CUDA_FOUND)
|
||||
${_arch_pascal}
|
||||
${_arch_volta}
|
||||
${_arch_turing}
|
||||
${_arch_ampere}
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
@@ -162,11 +273,9 @@ if(CUDA_FOUND)
|
||||
string(REGEX REPLACE "\\." "" ARCH_BIN_NO_POINTS "${CUDA_ARCH_BIN}")
|
||||
string(REGEX REPLACE "\\." "" ARCH_PTX_NO_POINTS "${CUDA_ARCH_PTX}")
|
||||
|
||||
# Ckeck if user specified 1.0 compute capability: we don't support it
|
||||
string(REGEX MATCH "1.0" HAS_ARCH_10 "${CUDA_ARCH_BIN} ${CUDA_ARCH_PTX}")
|
||||
set(CUDA_ARCH_BIN_OR_PTX_10 0)
|
||||
if(NOT ${HAS_ARCH_10} STREQUAL "")
|
||||
set(CUDA_ARCH_BIN_OR_PTX_10 1)
|
||||
# Check if user specified 1.0 compute capability: we don't support it
|
||||
if(" ${CUDA_ARCH_BIN} ${CUDA_ARCH_PTX}" MATCHES " 1.0")
|
||||
message(SEND_ERROR "CUDA: 1.0 compute capability is not supported - exclude it from ARCH/PTX list are re-run CMake")
|
||||
endif()
|
||||
|
||||
# NVCC flags to be set
|
||||
@@ -277,6 +386,16 @@ if(CUDA_FOUND)
|
||||
|
||||
if(UNIX OR APPLE)
|
||||
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcompiler -fPIC)
|
||||
if(
|
||||
ENABLE_CXX11
|
||||
AND NOT " ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS_DEBUG} ${CUDA_NVCC_FLAGS}" MATCHES "-std="
|
||||
)
|
||||
if(CUDA_VERSION VERSION_LESS "11.0")
|
||||
list(APPEND CUDA_NVCC_FLAGS "--std=c++11")
|
||||
else()
|
||||
list(APPEND CUDA_NVCC_FLAGS "--std=c++14")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if(APPLE)
|
||||
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcompiler -fno-finite-math-only)
|
||||
@@ -340,4 +459,57 @@ if(HAVE_CUDA)
|
||||
set(CUDA_cufft_LIBRARY_ABS ${CUDA_cufft_LIBRARY})
|
||||
ocv_convert_to_lib_name(CUDA_cufft_LIBRARY ${CUDA_cufft_LIBRARY})
|
||||
endif()
|
||||
|
||||
if(CMAKE_GENERATOR MATCHES "Visual Studio"
|
||||
AND NOT OPENCV_SKIP_CUDA_CMAKE_SUPPRESS_REGENERATION
|
||||
)
|
||||
message(STATUS "CUDA: MSVS generator is detected. Disabling CMake re-run checks (CMAKE_SUPPRESS_REGENERATION=ON). You need to run CMake manually if updates are required.")
|
||||
set(CMAKE_SUPPRESS_REGENERATION ON)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Add CUDA libraries (needed for apps/tools, samples)
|
||||
# ----------------------------------------------------------------------------
|
||||
if(HAVE_CUDA)
|
||||
# details: https://github.com/NVIDIA/nvidia-docker/issues/775
|
||||
if(" ${CUDA_CUDA_LIBRARY}" MATCHES "/stubs/libcuda.so" AND NOT OPENCV_SKIP_CUDA_STUB_WORKAROUND)
|
||||
set(CUDA_STUB_ENABLED_LINK_WORKAROUND 1)
|
||||
if(EXISTS "${CUDA_CUDA_LIBRARY}" AND NOT OPENCV_SKIP_CUDA_STUB_WORKAROUND_RPATH_LINK)
|
||||
set(CUDA_STUB_TARGET_PATH "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/")
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${CUDA_CUDA_LIBRARY}" "${CUDA_STUB_TARGET_PATH}/libcuda.so.1"
|
||||
RESULT_VARIABLE CUDA_STUB_SYMLINK_RESULT)
|
||||
if(NOT CUDA_STUB_SYMLINK_RESULT EQUAL 0)
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CUDA_CUDA_LIBRARY}" "${CUDA_STUB_TARGET_PATH}/libcuda.so.1"
|
||||
RESULT_VARIABLE CUDA_STUB_COPY_RESULT)
|
||||
if(NOT CUDA_STUB_COPY_RESULT EQUAL 0)
|
||||
set(CUDA_STUB_ENABLED_LINK_WORKAROUND 0)
|
||||
endif()
|
||||
endif()
|
||||
if(CUDA_STUB_ENABLED_LINK_WORKAROUND)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath-link,\"${CUDA_STUB_TARGET_PATH}\"")
|
||||
endif()
|
||||
else()
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--allow-shlib-undefined")
|
||||
endif()
|
||||
if(NOT CUDA_STUB_ENABLED_LINK_WORKAROUND)
|
||||
message(WARNING "CUDA: workaround for stubs/libcuda.so.1 is not applied")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
|
||||
if(HAVE_CUBLAS)
|
||||
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDA_cublas_LIBRARY})
|
||||
endif()
|
||||
if(HAVE_CUFFT)
|
||||
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDA_cufft_LIBRARY})
|
||||
endif()
|
||||
foreach(p ${CUDA_LIBS_PATH})
|
||||
if(MSVC AND CMAKE_GENERATOR MATCHES "Ninja|JOM")
|
||||
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CMAKE_LIBRARY_PATH_FLAG}"${p}")
|
||||
else()
|
||||
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CMAKE_LIBRARY_PATH_FLAG}${p})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
@@ -135,9 +135,9 @@ endif()
|
||||
|
||||
if(INF_ENGINE_TARGET)
|
||||
if(NOT INF_ENGINE_RELEASE)
|
||||
message(WARNING "InferenceEngine version has not been set, 2020.2 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.")
|
||||
message(WARNING "InferenceEngine version has not been set, 2020.4 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.")
|
||||
endif()
|
||||
set(INF_ENGINE_RELEASE "2020020000" CACHE STRING "Force IE version, should be in form YYYYAABBCC (e.g. 2020.1.0.2 -> 2020010002)")
|
||||
set(INF_ENGINE_RELEASE "2020040000" CACHE STRING "Force IE version, should be in form YYYYAABBCC (e.g. 2020.1.0.2 -> 2020010002)")
|
||||
set_target_properties(${INF_ENGINE_TARGET} PROPERTIES
|
||||
INTERFACE_COMPILE_DEFINITIONS "HAVE_INF_ENGINE=1;INF_ENGINE_RELEASE=${INF_ENGINE_RELEASE}"
|
||||
)
|
||||
|
||||
@@ -79,9 +79,10 @@ get_mkl_version(${MKL_INCLUDE_DIRS}/mkl_version.h)
|
||||
|
||||
#determine arch
|
||||
if(CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 8)
|
||||
set(MKL_X64 1)
|
||||
set(MKL_ARCH "intel64")
|
||||
|
||||
set(MKL_ARCH_LIST "intel64")
|
||||
if(MSVC)
|
||||
list(APPEND MKL_ARCH_LIST "win-x64")
|
||||
endif()
|
||||
include(CheckTypeSize)
|
||||
CHECK_TYPE_SIZE(int _sizeof_int)
|
||||
if (_sizeof_int EQUAL 4)
|
||||
@@ -90,14 +91,19 @@ if(CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 8)
|
||||
set(MKL_ARCH_SUFFIX "ilp64")
|
||||
endif()
|
||||
else()
|
||||
set(MKL_ARCH "ia32")
|
||||
set(MKL_ARCH_LIST "ia32")
|
||||
set(MKL_ARCH_SUFFIX "c")
|
||||
endif()
|
||||
|
||||
if(MKL_VERSION_STR VERSION_GREATER "11.3.0" OR MKL_VERSION_STR VERSION_EQUAL "11.3.0")
|
||||
set(mkl_lib_find_paths
|
||||
${MKL_ROOT_DIR}/lib
|
||||
${MKL_ROOT_DIR}/lib/${MKL_ARCH} ${MKL_ROOT_DIR}/../tbb/lib/${MKL_ARCH})
|
||||
${MKL_ROOT_DIR}/lib)
|
||||
foreach(MKL_ARCH ${MKL_ARCH_LIST})
|
||||
list(APPEND mkl_lib_find_paths
|
||||
${MKL_ROOT_DIR}/lib/${MKL_ARCH}
|
||||
${MKL_ROOT_DIR}/../tbb/lib/${MKL_ARCH}
|
||||
${MKL_ROOT_DIR}/${MKL_ARCH})
|
||||
endforeach()
|
||||
|
||||
set(mkl_lib_list "mkl_intel_${MKL_ARCH_SUFFIX}")
|
||||
|
||||
@@ -121,7 +127,7 @@ endif()
|
||||
|
||||
set(MKL_LIBRARIES "")
|
||||
foreach(lib ${mkl_lib_list})
|
||||
find_library(${lib} ${lib} ${mkl_lib_find_paths})
|
||||
find_library(${lib} NAMES ${lib} ${lib}_dll HINTS ${mkl_lib_find_paths})
|
||||
mark_as_advanced(${lib})
|
||||
if(NOT ${lib})
|
||||
mkl_fail()
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
SET(Open_BLAS_INCLUDE_SEARCH_PATHS
|
||||
$ENV{OpenBLAS_HOME}
|
||||
$ENV{OpenBLAS_HOME}/include
|
||||
$ENV{OpenBLAS_HOME}/include/openblas
|
||||
/opt/OpenBLAS/include
|
||||
/usr/local/include/openblas
|
||||
/usr/include/openblas
|
||||
@@ -103,4 +104,4 @@ MARK_AS_ADVANCED(
|
||||
OpenBLAS_INCLUDE_DIR
|
||||
OpenBLAS_LIB
|
||||
OpenBLAS
|
||||
)
|
||||
)
|
||||
|
||||
@@ -88,7 +88,7 @@ FOREACH(SEARCH_PATH ${SEARCH_PATHS})
|
||||
ocv_find_openexr("-${OPENEXR_VERSION}")
|
||||
ocv_find_openexr("-${OPENEXR_VERSION}_s")
|
||||
ocv_find_openexr("-${OPENEXR_VERSION}_d")
|
||||
ocv_find_openexr("-${OPEXEXR_VERSION}_s_d")
|
||||
ocv_find_openexr("-${OPENEXR_VERSION}_s_d")
|
||||
ocv_find_openexr("")
|
||||
ocv_find_openexr("_s")
|
||||
ocv_find_openexr("_d")
|
||||
|
||||
@@ -13,9 +13,6 @@
|
||||
/* Compile for 'real' NVIDIA GPU architectures */
|
||||
#define CUDA_ARCH_BIN "${OPENCV_CUDA_ARCH_BIN}"
|
||||
|
||||
/* Create PTX or BIN for 1.0 compute capability */
|
||||
#cmakedefine CUDA_ARCH_BIN_OR_PTX_10
|
||||
|
||||
/* NVIDIA GPU features are used */
|
||||
#define CUDA_ARCH_FEATURES "${OPENCV_CUDA_ARCH_FEATURES}"
|
||||
|
||||
@@ -127,6 +124,8 @@
|
||||
|
||||
/* NVIDIA Video Decoding API*/
|
||||
#cmakedefine HAVE_NVCUVID
|
||||
#cmakedefine HAVE_NVCUVID_HEADER
|
||||
#cmakedefine HAVE_DYNLINK_NVCUVID_HEADER
|
||||
|
||||
/* NVIDIA Video Encoding API*/
|
||||
#cmakedefine HAVE_NVCUVENC
|
||||
|
||||
+2
-1
@@ -346,7 +346,8 @@
|
||||
year = {2003},
|
||||
pages = {363--370},
|
||||
publisher = {Springer},
|
||||
url = {https://arxiv.org/pdf/1808.01752}
|
||||
url = {https://doi.org/10.1007/3-540-45103-X_50},
|
||||
doi = {10.1007/3-540-45103-X_50}
|
||||
}
|
||||
@inproceedings{Farsiu03,
|
||||
author = {Farsiu, Sina and Robinson, Dirk and Elad, Michael and Milanfar, Peyman},
|
||||
|
||||
@@ -30,7 +30,7 @@ Installing CMake
|
||||
|
||||
-# Install the dmg package and launch it from Applications. That will give you the UI app of CMake
|
||||
|
||||
-# From the CMake app window, choose menu Tools --> Install For Command Line Use.
|
||||
-# From the CMake app window, choose menu Tools --> How to Install For Command Line Use. Then, follow the instructions from the pop-up there.
|
||||
|
||||
-# Install folder will be /usr/bin/ by default, submit it by choosing Install command line links.
|
||||
|
||||
@@ -66,7 +66,7 @@ git clone https://github.com/opencv/opencv_contrib.git
|
||||
Building OpenCV from Source Using CMake
|
||||
---------------------------------------
|
||||
|
||||
-# Create a temporary directory, which we denote as `<cmake_build_dir>`, where you want to put
|
||||
-# Create a temporary directory, which we denote as `build_opencv`, where you want to put
|
||||
the generated Makefiles, project files as well the object files and output binaries and enter
|
||||
there.
|
||||
|
||||
@@ -87,8 +87,8 @@ Building OpenCV from Source Using CMake
|
||||
|
||||
or cmake-gui
|
||||
|
||||
- set full path to OpenCV source code, e.g. `/home/user/opencv`
|
||||
- set full path to `<cmake_build_dir>`, e.g. `/home/user/build_opencv`
|
||||
- set the OpenCV source code path to, e.g. `/home/user/opencv`
|
||||
- set the binary build path to your CMake build directory, e.g. `/home/user/build_opencv`
|
||||
- set optional parameters
|
||||
- run: "Configure"
|
||||
- run: "Generate"
|
||||
|
||||
@@ -101,6 +101,20 @@ namespace cv { namespace cuda
|
||||
cudaChannelFormatDesc desc = cudaCreateChannelDesc<T>();
|
||||
cudaSafeCall( cudaBindTexture2D(0, tex, img.ptr(), &desc, img.cols, img.rows, img.step) );
|
||||
}
|
||||
|
||||
template<class T> inline void createTextureObjectPitch2D(cudaTextureObject_t* tex, PtrStepSz<T>& img, const cudaTextureDesc& texDesc)
|
||||
{
|
||||
cudaResourceDesc resDesc;
|
||||
memset(&resDesc, 0, sizeof(resDesc));
|
||||
resDesc.resType = cudaResourceTypePitch2D;
|
||||
resDesc.res.pitch2D.devPtr = static_cast<void*>(img.ptr());
|
||||
resDesc.res.pitch2D.height = img.rows;
|
||||
resDesc.res.pitch2D.width = img.cols;
|
||||
resDesc.res.pitch2D.pitchInBytes = img.step;
|
||||
resDesc.res.pitch2D.desc = cudaCreateChannelDesc<T>();
|
||||
|
||||
cudaSafeCall( cudaCreateTextureObject(tex, &resDesc, &texDesc, NULL) );
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
||||
|
||||
@@ -106,8 +106,8 @@ namespace cv
|
||||
|
||||
size_t step;
|
||||
|
||||
__CV_CUDA_HOST_DEVICE__ T* ptr(int y = 0) { return ( T*)( ( char*)DevPtr<T>::data + y * step); }
|
||||
__CV_CUDA_HOST_DEVICE__ const T* ptr(int y = 0) const { return (const T*)( (const char*)DevPtr<T>::data + y * step); }
|
||||
__CV_CUDA_HOST_DEVICE__ T* ptr(int y = 0) { return ( T*)( ( char*)(((DevPtr<T>*)this)->data) + y * step); }
|
||||
__CV_CUDA_HOST_DEVICE__ const T* ptr(int y = 0) const { return (const T*)( (const char*)(((DevPtr<T>*)this)->data) + y * step); }
|
||||
|
||||
__CV_CUDA_HOST_DEVICE__ T& operator ()(int y, int x) { return ptr(y)[x]; }
|
||||
__CV_CUDA_HOST_DEVICE__ const T& operator ()(int y, int x) const { return ptr(y)[x]; }
|
||||
|
||||
@@ -86,12 +86,24 @@ namespace cv { namespace debug_build_guard { } using namespace debug_build_guard
|
||||
#define __CV_VA_NUM_ARGS_HELPER(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
|
||||
#define __CV_VA_NUM_ARGS(...) __CV_VA_NUM_ARGS_HELPER(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
|
||||
|
||||
#if defined __GNUC__
|
||||
#ifdef CV_Func
|
||||
// keep current value (through OpenCV port file)
|
||||
#elif defined __GNUC__ || (defined (__cpluscplus) && (__cpluscplus >= 201103))
|
||||
#define CV_Func __func__
|
||||
#elif defined __clang__ && (__clang_minor__ * 100 + __clang_major >= 305)
|
||||
#define CV_Func __func__
|
||||
#elif defined(__STDC_VERSION__) && (__STDC_VERSION >= 199901)
|
||||
#define CV_Func __func__
|
||||
#elif defined _MSC_VER
|
||||
#define CV_Func __FUNCTION__
|
||||
#elif defined(__INTEL_COMPILER) && (_INTEL_COMPILER >= 600)
|
||||
#define CV_Func __FUNCTION__
|
||||
#elif defined __IBMCPP__ && __IBMCPP__ >=500
|
||||
#define CV_Func __FUNCTION__
|
||||
#elif defined __BORLAND__ && (__BORLANDC__ >= 0x550)
|
||||
#define CV_Func __FUNC__
|
||||
#else
|
||||
#define CV_Func ""
|
||||
#define CV_Func "<unknown>"
|
||||
#endif
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
@@ -51,25 +51,34 @@
|
||||
|
||||
#include "opencv2/core.hpp"
|
||||
|
||||
#if defined _MSC_VER && _MSC_VER >= 1200
|
||||
#define NOMINMAX // fix https://github.com/opencv/opencv/issues/17548
|
||||
#pragma warning( disable: 4714 ) //__forceinline is not inlined
|
||||
#pragma warning( disable: 4127 ) //conditional expression is constant
|
||||
#pragma warning( disable: 4244 ) //conversion from '__int64' to 'int', possible loss of data
|
||||
#endif
|
||||
|
||||
#if EIGEN_WORLD_VERSION == 3 && EIGEN_MAJOR_VERSION >= 3 \
|
||||
&& defined(CV_CXX11) && defined(CV_CXX_STD_ARRAY)
|
||||
#include <unsupported/Eigen/CXX11/Tensor>
|
||||
#define OPENCV_EIGEN_TENSOR_SUPPORT
|
||||
#endif // EIGEN_WORLD_VERSION == 3 && EIGEN_MAJOR_VERSION >= 3
|
||||
|
||||
#if defined _MSC_VER && _MSC_VER >= 1200
|
||||
#pragma warning( disable: 4714 ) //__forceinline is not inlined
|
||||
#pragma warning( disable: 4127 ) //conditional expression is constant
|
||||
#pragma warning( disable: 4244 ) //conversion from '__int64' to 'int', possible loss of data
|
||||
#endif
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
//! @addtogroup core_eigen
|
||||
/** @addtogroup core_eigen
|
||||
These functions are provided for OpenCV-Eigen interoperability. They convert `Mat`
|
||||
objects to corresponding `Eigen::Matrix` objects and vice-versa. Consult the [Eigen
|
||||
documentation](https://eigen.tuxfamily.org/dox/group__TutorialMatrixClass.html) for
|
||||
information about the `Matrix` template type.
|
||||
|
||||
@note Using these functions requires the `Eigen/Dense` or similar header to be
|
||||
included before this header.
|
||||
*/
|
||||
//! @{
|
||||
|
||||
#ifdef OPENCV_EIGEN_TENSOR_SUPPORT
|
||||
#if defined(OPENCV_EIGEN_TENSOR_SUPPORT) || defined(CV_DOXYGEN)
|
||||
/** @brief Converts an Eigen::Tensor to a cv::Mat.
|
||||
|
||||
The method converts an Eigen::Tensor with shape (H x W x C) to a cv::Mat where:
|
||||
|
||||
@@ -82,9 +82,6 @@
|
||||
# error "Insufficient Cuda Runtime library version, please update it."
|
||||
# endif
|
||||
|
||||
# if defined(CUDA_ARCH_BIN_OR_PTX_10)
|
||||
# error "OpenCV CUDA module doesn't support NVIDIA compute capability 1.0"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#define CV_VERSION_MAJOR 3
|
||||
#define CV_VERSION_MINOR 4
|
||||
#define CV_VERSION_REVISION 11
|
||||
#define CV_VERSION_STATUS "-pre"
|
||||
#define CV_VERSION_STATUS ""
|
||||
|
||||
#define CVAUX_STR_EXP(__A) #__A
|
||||
#define CVAUX_STR(__A) CVAUX_STR_EXP(__A)
|
||||
|
||||
@@ -25,9 +25,26 @@ String dumpInputArray(InputArray argument)
|
||||
break; // done
|
||||
}
|
||||
ss << cv::format(" total(-1)=%lld", (long long int)argument.total(-1));
|
||||
ss << cv::format(" dims(-1)=%d", argument.dims(-1));
|
||||
Size size = argument.size(-1);
|
||||
ss << cv::format(" size(-1)=%dx%d", size.width, size.height);
|
||||
int dims = argument.dims(-1);
|
||||
ss << cv::format(" dims(-1)=%d", dims);
|
||||
if (dims <= 2)
|
||||
{
|
||||
Size size = argument.size(-1);
|
||||
ss << cv::format(" size(-1)=%dx%d", size.width, size.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
int sz[CV_MAX_DIM] = {0};
|
||||
argument.sizend(sz, -1);
|
||||
ss << " size(-1)=[";
|
||||
for (int i = 0; i < dims; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
ss << ' ';
|
||||
ss << sz[i];
|
||||
}
|
||||
ss << "]";
|
||||
}
|
||||
ss << " type(-1)=" << cv::typeToString(argument.type(-1));
|
||||
} while (0);
|
||||
}
|
||||
@@ -61,10 +78,26 @@ CV_EXPORTS_W String dumpInputArrayOfArrays(InputArrayOfArrays argument)
|
||||
if (argument.total(-1) > 0)
|
||||
{
|
||||
ss << " type(0)=" << cv::typeToString(argument.type(0));
|
||||
ss << cv::format(" dims(0)=%d", argument.dims(0));
|
||||
size = argument.size(0);
|
||||
ss << cv::format(" size(0)=%dx%d", size.width, size.height);
|
||||
ss << " type(0)=" << cv::typeToString(argument.type(0));
|
||||
int dims = argument.dims(0);
|
||||
ss << cv::format(" dims(0)=%d", dims);
|
||||
if (dims <= 2)
|
||||
{
|
||||
Size size0 = argument.size(0);
|
||||
ss << cv::format(" size(0)=%dx%d", size0.width, size0.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
int sz[CV_MAX_DIM] = {0};
|
||||
argument.sizend(sz, 0);
|
||||
ss << " size(0)=[";
|
||||
for (int i = 0; i < dims; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
ss << ' ';
|
||||
ss << sz[i];
|
||||
}
|
||||
ss << "]";
|
||||
}
|
||||
}
|
||||
} while (0);
|
||||
}
|
||||
@@ -92,9 +125,26 @@ CV_EXPORTS_W String dumpInputOutputArray(InputOutputArray argument)
|
||||
break; // done
|
||||
}
|
||||
ss << cv::format(" total(-1)=%lld", (long long int)argument.total(-1));
|
||||
ss << cv::format(" dims(-1)=%d", argument.dims(-1));
|
||||
Size size = argument.size(-1);
|
||||
ss << cv::format(" size(-1)=%dx%d", size.width, size.height);
|
||||
int dims = argument.dims(-1);
|
||||
ss << cv::format(" dims(-1)=%d", dims);
|
||||
if (dims <= 2)
|
||||
{
|
||||
Size size = argument.size(-1);
|
||||
ss << cv::format(" size(-1)=%dx%d", size.width, size.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
int sz[CV_MAX_DIM] = {0};
|
||||
argument.sizend(sz, -1);
|
||||
ss << " size(-1)=[";
|
||||
for (int i = 0; i < dims; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
ss << ' ';
|
||||
ss << sz[i];
|
||||
}
|
||||
ss << "]";
|
||||
}
|
||||
ss << " type(-1)=" << cv::typeToString(argument.type(-1));
|
||||
} while (0);
|
||||
}
|
||||
@@ -128,10 +178,26 @@ CV_EXPORTS_W String dumpInputOutputArrayOfArrays(InputOutputArrayOfArrays argume
|
||||
if (argument.total(-1) > 0)
|
||||
{
|
||||
ss << " type(0)=" << cv::typeToString(argument.type(0));
|
||||
ss << cv::format(" dims(0)=%d", argument.dims(0));
|
||||
size = argument.size(0);
|
||||
ss << cv::format(" size(0)=%dx%d", size.width, size.height);
|
||||
ss << " type(0)=" << cv::typeToString(argument.type(0));
|
||||
int dims = argument.dims(0);
|
||||
ss << cv::format(" dims(0)=%d", dims);
|
||||
if (dims <= 2)
|
||||
{
|
||||
Size size0 = argument.size(0);
|
||||
ss << cv::format(" size(0)=%dx%d", size0.width, size0.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
int sz[CV_MAX_DIM] = {0};
|
||||
argument.sizend(sz, 0);
|
||||
ss << " size(0)=[";
|
||||
for (int i = 0; i < dims; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
ss << ' ';
|
||||
ss << sz[i];
|
||||
}
|
||||
ss << "]";
|
||||
}
|
||||
}
|
||||
} while (0);
|
||||
}
|
||||
|
||||
@@ -72,9 +72,13 @@ static int64 getTimestamp()
|
||||
return (int64)((t - g_zero_timestamp) * tick_to_ns);
|
||||
}
|
||||
|
||||
// TODO lazy configuration flags
|
||||
static bool param_traceEnable = utils::getConfigurationParameterBool("OPENCV_TRACE", false);
|
||||
static bool getParameterTraceEnable()
|
||||
{
|
||||
static bool param_traceEnable = utils::getConfigurationParameterBool("OPENCV_TRACE", false);
|
||||
return param_traceEnable;
|
||||
}
|
||||
|
||||
// TODO lazy configuration flags
|
||||
static int param_maxRegionDepthOpenCV = (int)utils::getConfigurationParameterSizeT("OPENCV_TRACE_DEPTH_OPENCV", 1);
|
||||
static int param_maxRegionChildrenOpenCV = (int)utils::getConfigurationParameterSizeT("OPENCV_TRACE_MAX_CHILDREN_OPENCV", 1000);
|
||||
static int param_maxRegionChildren = (int)utils::getConfigurationParameterSizeT("OPENCV_TRACE_MAX_CHILDREN", 10000);
|
||||
@@ -841,7 +845,7 @@ TraceManager::TraceManager()
|
||||
CV_LOG("TraceManager ctor: " << (void*)this);
|
||||
|
||||
CV_LOG("TraceManager configure()");
|
||||
activated = param_traceEnable;
|
||||
activated = getParameterTraceEnable();
|
||||
|
||||
if (activated)
|
||||
trace_storage.reset(new SyncTraceStorage(std::string(param_traceLocation) + ".txt"));
|
||||
|
||||
@@ -44,17 +44,9 @@
|
||||
#ifndef __CUVID_VIDEO_SOURCE_HPP__
|
||||
#define __CUVID_VIDEO_SOURCE_HPP__
|
||||
|
||||
#if CUDA_VERSION >= 9000 && CUDA_VERSION < 10000
|
||||
#include <dynlink_nvcuvid.h>
|
||||
#else
|
||||
#include <nvcuvid.h>
|
||||
#endif
|
||||
#include "opencv2/core/private.cuda.hpp"
|
||||
#include "opencv2/cudacodec.hpp"
|
||||
#include "video_source.hpp"
|
||||
|
||||
namespace cv { namespace cudacodec { namespace detail
|
||||
{
|
||||
namespace cv { namespace cudacodec { namespace detail {
|
||||
|
||||
class CuvidVideoSource : public VideoSource
|
||||
{
|
||||
|
||||
@@ -45,16 +45,8 @@
|
||||
#define __FRAME_QUEUE_HPP__
|
||||
|
||||
#include "opencv2/core/utility.hpp"
|
||||
#include "opencv2/core/private.cuda.hpp"
|
||||
|
||||
#if CUDA_VERSION >= 9000 && CUDA_VERSION < 10000
|
||||
#include <dynlink_nvcuvid.h>
|
||||
#else
|
||||
#include <nvcuvid.h>
|
||||
#endif
|
||||
|
||||
namespace cv { namespace cudacodec { namespace detail
|
||||
{
|
||||
namespace cv { namespace cudacodec { namespace detail {
|
||||
|
||||
class FrameQueue
|
||||
{
|
||||
|
||||
@@ -56,9 +56,9 @@
|
||||
#include "opencv2/core/private.cuda.hpp"
|
||||
|
||||
#ifdef HAVE_NVCUVID
|
||||
#if CUDA_VERSION >= 9000 && CUDA_VERSION < 10000
|
||||
#if defined(HAVE_DYNLINK_NVCUVID_HEADER)
|
||||
#include <dynlink_nvcuvid.h>
|
||||
#else
|
||||
#elif defined(HAVE_NVCUVID_HEADER)
|
||||
#include <nvcuvid.h>
|
||||
#endif
|
||||
|
||||
|
||||
@@ -44,17 +44,7 @@
|
||||
#ifndef __VIDEO_DECODER_HPP__
|
||||
#define __VIDEO_DECODER_HPP__
|
||||
|
||||
#if CUDA_VERSION >= 9000 && CUDA_VERSION < 10000
|
||||
#include <dynlink_nvcuvid.h>
|
||||
#else
|
||||
#include <nvcuvid.h>
|
||||
#endif
|
||||
|
||||
#include "opencv2/core/private.cuda.hpp"
|
||||
#include "opencv2/cudacodec.hpp"
|
||||
|
||||
namespace cv { namespace cudacodec { namespace detail
|
||||
{
|
||||
namespace cv { namespace cudacodec { namespace detail {
|
||||
|
||||
class VideoDecoder
|
||||
{
|
||||
|
||||
@@ -44,19 +44,10 @@
|
||||
#ifndef __VIDEO_PARSER_HPP__
|
||||
#define __VIDEO_PARSER_HPP__
|
||||
|
||||
#if CUDA_VERSION >= 9000 && CUDA_VERSION < 10000
|
||||
#include <dynlink_nvcuvid.h>
|
||||
#else
|
||||
#include <nvcuvid.h>
|
||||
#endif
|
||||
|
||||
#include "opencv2/core/private.cuda.hpp"
|
||||
#include "opencv2/cudacodec.hpp"
|
||||
#include "frame_queue.hpp"
|
||||
#include "video_decoder.hpp"
|
||||
|
||||
namespace cv { namespace cudacodec { namespace detail
|
||||
{
|
||||
namespace cv { namespace cudacodec { namespace detail {
|
||||
|
||||
class VideoParser
|
||||
{
|
||||
|
||||
@@ -44,12 +44,9 @@
|
||||
#ifndef __CUDACODEC_VIDEO_SOURCE_H__
|
||||
#define __CUDACODEC_VIDEO_SOURCE_H__
|
||||
|
||||
#include "opencv2/core/private.cuda.hpp"
|
||||
#include "opencv2/cudacodec.hpp"
|
||||
#include "thread.hpp"
|
||||
|
||||
namespace cv { namespace cudacodec { namespace detail
|
||||
{
|
||||
namespace cv { namespace cudacodec { namespace detail {
|
||||
|
||||
class VideoParser;
|
||||
|
||||
|
||||
@@ -90,12 +90,22 @@ namespace cv { namespace cuda { namespace device
|
||||
|
||||
namespace canny
|
||||
{
|
||||
texture<uchar, cudaTextureType2D, cudaReadModeElementType> tex_src(false, cudaFilterModePoint, cudaAddressModeClamp);
|
||||
struct SrcTex
|
||||
{
|
||||
virtual ~SrcTex() {}
|
||||
|
||||
__host__ SrcTex(int _xoff, int _yoff) : xoff(_xoff), yoff(_yoff) {}
|
||||
|
||||
__device__ __forceinline__ virtual int operator ()(int y, int x) const = 0;
|
||||
|
||||
int xoff;
|
||||
int yoff;
|
||||
__host__ SrcTex(int _xoff, int _yoff) : xoff(_xoff), yoff(_yoff) {}
|
||||
};
|
||||
|
||||
texture<uchar, cudaTextureType2D, cudaReadModeElementType> tex_src(false, cudaFilterModePoint, cudaAddressModeClamp);
|
||||
struct SrcTexRef : SrcTex
|
||||
{
|
||||
__host__ SrcTexRef(int _xoff, int _yoff) : SrcTex(_xoff, _yoff) {}
|
||||
|
||||
__device__ __forceinline__ int operator ()(int y, int x) const
|
||||
{
|
||||
@@ -103,40 +113,23 @@ namespace canny
|
||||
}
|
||||
};
|
||||
|
||||
struct SrcTexObject
|
||||
struct SrcTexObj : SrcTex
|
||||
{
|
||||
int xoff;
|
||||
int yoff;
|
||||
cudaTextureObject_t tex_src_object;
|
||||
__host__ SrcTexObject(int _xoff, int _yoff, cudaTextureObject_t _tex_src_object) : xoff(_xoff), yoff(_yoff), tex_src_object(_tex_src_object) { }
|
||||
__host__ SrcTexObj(int _xoff, int _yoff, cudaTextureObject_t _tex_src_object) : SrcTex(_xoff, _yoff), tex_src_object(_tex_src_object) { }
|
||||
|
||||
__device__ __forceinline__ int operator ()(int y, int x) const
|
||||
{
|
||||
return tex2D<uchar>(tex_src_object, x + xoff, y + yoff);
|
||||
}
|
||||
|
||||
cudaTextureObject_t tex_src_object;
|
||||
};
|
||||
|
||||
template <class Norm> __global__
|
||||
void calcMagnitudeKernel(const SrcTex src, PtrStepi dx, PtrStepi dy, PtrStepSzf mag, const Norm norm)
|
||||
{
|
||||
const int x = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
const int y = blockIdx.y * blockDim.y + threadIdx.y;
|
||||
|
||||
if (y >= mag.rows || x >= mag.cols)
|
||||
return;
|
||||
|
||||
int dxVal = (src(y - 1, x + 1) + 2 * src(y, x + 1) + src(y + 1, x + 1)) - (src(y - 1, x - 1) + 2 * src(y, x - 1) + src(y + 1, x - 1));
|
||||
int dyVal = (src(y + 1, x - 1) + 2 * src(y + 1, x) + src(y + 1, x + 1)) - (src(y - 1, x - 1) + 2 * src(y - 1, x) + src(y - 1, x + 1));
|
||||
|
||||
dx(y, x) = dxVal;
|
||||
dy(y, x) = dyVal;
|
||||
|
||||
mag(y, x) = norm(dxVal, dyVal);
|
||||
}
|
||||
|
||||
template <class Norm> __global__
|
||||
void calcMagnitudeKernel(const SrcTexObject src, PtrStepi dx, PtrStepi dy, PtrStepSzf mag, const Norm norm)
|
||||
template <
|
||||
class T,
|
||||
class Norm
|
||||
>
|
||||
__global__ void calcMagnitudeKernel(const T src, PtrStepi dx, PtrStepi dy, PtrStepSzf mag, const Norm norm)
|
||||
{
|
||||
const int x = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
const int y = blockIdx.y * blockDim.y + threadIdx.y;
|
||||
@@ -162,15 +155,6 @@ namespace canny
|
||||
|
||||
if (cc30)
|
||||
{
|
||||
cudaResourceDesc resDesc;
|
||||
memset(&resDesc, 0, sizeof(resDesc));
|
||||
resDesc.resType = cudaResourceTypePitch2D;
|
||||
resDesc.res.pitch2D.devPtr = srcWhole.ptr();
|
||||
resDesc.res.pitch2D.height = srcWhole.rows;
|
||||
resDesc.res.pitch2D.width = srcWhole.cols;
|
||||
resDesc.res.pitch2D.pitchInBytes = srcWhole.step;
|
||||
resDesc.res.pitch2D.desc = cudaCreateChannelDesc<uchar>();
|
||||
|
||||
cudaTextureDesc texDesc;
|
||||
memset(&texDesc, 0, sizeof(texDesc));
|
||||
texDesc.addressMode[0] = cudaAddressModeClamp;
|
||||
@@ -178,9 +162,9 @@ namespace canny
|
||||
texDesc.addressMode[2] = cudaAddressModeClamp;
|
||||
|
||||
cudaTextureObject_t tex = 0;
|
||||
cudaCreateTextureObject(&tex, &resDesc, &texDesc, NULL);
|
||||
createTextureObjectPitch2D(&tex, srcWhole, texDesc);
|
||||
|
||||
SrcTexObject src(xoff, yoff, tex);
|
||||
SrcTexObj src(xoff, yoff, tex);
|
||||
|
||||
if (L2Grad)
|
||||
{
|
||||
@@ -205,7 +189,7 @@ namespace canny
|
||||
else
|
||||
{
|
||||
bindTexture(&tex_src, srcWhole);
|
||||
SrcTex src(xoff, yoff);
|
||||
SrcTexRef src(xoff, yoff);
|
||||
|
||||
if (L2Grad)
|
||||
{
|
||||
|
||||
@@ -116,7 +116,7 @@ protected:
|
||||
bool useL2gradient;
|
||||
};
|
||||
|
||||
#define NUM_STREAMS 64
|
||||
#define NUM_STREAMS 128
|
||||
|
||||
CUDA_TEST_P(Canny, Async)
|
||||
{
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "opencv2/core/cuda/common.hpp"
|
||||
#include "opencv2/core/cuda/border_interpolate.hpp"
|
||||
#include "opencv2/core/cuda/limits.hpp"
|
||||
#include "opencv2/core/cuda.hpp"
|
||||
|
||||
using namespace cv::cuda;
|
||||
using namespace cv::cuda::device;
|
||||
@@ -101,11 +102,63 @@ namespace tvl1flow
|
||||
}
|
||||
}
|
||||
|
||||
struct SrcTex
|
||||
{
|
||||
virtual ~SrcTex() {}
|
||||
|
||||
__device__ __forceinline__ virtual float I1(float x, float y) const = 0;
|
||||
__device__ __forceinline__ virtual float I1x(float x, float y) const = 0;
|
||||
__device__ __forceinline__ virtual float I1y(float x, float y) const = 0;
|
||||
};
|
||||
|
||||
texture<float, cudaTextureType2D, cudaReadModeElementType> tex_I1 (false, cudaFilterModePoint, cudaAddressModeClamp);
|
||||
texture<float, cudaTextureType2D, cudaReadModeElementType> tex_I1x(false, cudaFilterModePoint, cudaAddressModeClamp);
|
||||
texture<float, cudaTextureType2D, cudaReadModeElementType> tex_I1y(false, cudaFilterModePoint, cudaAddressModeClamp);
|
||||
struct SrcTexRef : SrcTex
|
||||
{
|
||||
__device__ __forceinline__ float I1(float x, float y) const override
|
||||
{
|
||||
return tex2D(tex_I1, x, y);
|
||||
}
|
||||
__device__ __forceinline__ float I1x(float x, float y) const override
|
||||
{
|
||||
return tex2D(tex_I1x, x, y);
|
||||
}
|
||||
__device__ __forceinline__ float I1y(float x, float y) const override
|
||||
{
|
||||
return tex2D(tex_I1y, x, y);
|
||||
}
|
||||
};
|
||||
|
||||
__global__ void warpBackwardKernel(const PtrStepSzf I0, const PtrStepf u1, const PtrStepf u2, PtrStepf I1w, PtrStepf I1wx, PtrStepf I1wy, PtrStepf grad, PtrStepf rho)
|
||||
struct SrcTexObj : SrcTex
|
||||
{
|
||||
__host__ SrcTexObj(cudaTextureObject_t tex_obj_I1_, cudaTextureObject_t tex_obj_I1x_, cudaTextureObject_t tex_obj_I1y_)
|
||||
: tex_obj_I1(tex_obj_I1_), tex_obj_I1x(tex_obj_I1x_), tex_obj_I1y(tex_obj_I1y_) {}
|
||||
|
||||
__device__ __forceinline__ float I1(float x, float y) const override
|
||||
{
|
||||
return tex2D<float>(tex_obj_I1, x, y);
|
||||
}
|
||||
__device__ __forceinline__ float I1x(float x, float y) const override
|
||||
{
|
||||
return tex2D<float>(tex_obj_I1x, x, y);
|
||||
}
|
||||
__device__ __forceinline__ float I1y(float x, float y) const override
|
||||
{
|
||||
return tex2D<float>(tex_obj_I1y, x, y);
|
||||
}
|
||||
|
||||
cudaTextureObject_t tex_obj_I1;
|
||||
cudaTextureObject_t tex_obj_I1x;
|
||||
cudaTextureObject_t tex_obj_I1y;
|
||||
};
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
__global__ void warpBackwardKernel(
|
||||
const PtrStepSzf I0, const T src, const PtrStepf u1, const PtrStepf u2,
|
||||
PtrStepf I1w, PtrStepf I1wx, PtrStepf I1wy, PtrStepf grad, PtrStepf rho)
|
||||
{
|
||||
const int x = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
const int y = blockIdx.y * blockDim.y + threadIdx.y;
|
||||
@@ -136,9 +189,9 @@ namespace tvl1flow
|
||||
{
|
||||
const float w = bicubicCoeff(wx - cx) * bicubicCoeff(wy - cy);
|
||||
|
||||
sum += w * tex2D(tex_I1 , cx, cy);
|
||||
sumx += w * tex2D(tex_I1x, cx, cy);
|
||||
sumy += w * tex2D(tex_I1y, cx, cy);
|
||||
sum += w * src.I1(cx, cy);
|
||||
sumx += w * src.I1x(cx, cy);
|
||||
sumy += w * src.I1y(cx, cy);
|
||||
|
||||
wsum += w;
|
||||
}
|
||||
@@ -173,15 +226,46 @@ namespace tvl1flow
|
||||
const dim3 block(32, 8);
|
||||
const dim3 grid(divUp(I0.cols, block.x), divUp(I0.rows, block.y));
|
||||
|
||||
bindTexture(&tex_I1 , I1);
|
||||
bindTexture(&tex_I1x, I1x);
|
||||
bindTexture(&tex_I1y, I1y);
|
||||
bool cc30 = deviceSupports(FEATURE_SET_COMPUTE_30);
|
||||
|
||||
warpBackwardKernel<<<grid, block, 0, stream>>>(I0, u1, u2, I1w, I1wx, I1wy, grad, rho);
|
||||
cudaSafeCall( cudaGetLastError() );
|
||||
if (cc30)
|
||||
{
|
||||
cudaTextureDesc texDesc;
|
||||
memset(&texDesc, 0, sizeof(texDesc));
|
||||
texDesc.addressMode[0] = cudaAddressModeClamp;
|
||||
texDesc.addressMode[1] = cudaAddressModeClamp;
|
||||
texDesc.addressMode[2] = cudaAddressModeClamp;
|
||||
|
||||
if (!stream)
|
||||
cudaSafeCall( cudaDeviceSynchronize() );
|
||||
cudaTextureObject_t texObj_I1 = 0, texObj_I1x = 0, texObj_I1y = 0;
|
||||
|
||||
createTextureObjectPitch2D(&texObj_I1, I1, texDesc);
|
||||
createTextureObjectPitch2D(&texObj_I1x, I1x, texDesc);
|
||||
createTextureObjectPitch2D(&texObj_I1y, I1y, texDesc);
|
||||
|
||||
warpBackwardKernel << <grid, block, 0, stream >> > (I0, SrcTexObj(texObj_I1, texObj_I1x, texObj_I1y), u1, u2, I1w, I1wx, I1wy, grad, rho);
|
||||
cudaSafeCall(cudaGetLastError());
|
||||
|
||||
if (!stream)
|
||||
cudaSafeCall(cudaDeviceSynchronize());
|
||||
else
|
||||
cudaSafeCall(cudaStreamSynchronize(stream));
|
||||
|
||||
cudaSafeCall(cudaDestroyTextureObject(texObj_I1));
|
||||
cudaSafeCall(cudaDestroyTextureObject(texObj_I1x));
|
||||
cudaSafeCall(cudaDestroyTextureObject(texObj_I1y));
|
||||
}
|
||||
else
|
||||
{
|
||||
bindTexture(&tex_I1, I1);
|
||||
bindTexture(&tex_I1x, I1x);
|
||||
bindTexture(&tex_I1y, I1y);
|
||||
|
||||
warpBackwardKernel << <grid, block, 0, stream >> > (I0, SrcTexRef(), u1, u2, I1w, I1wx, I1wy, grad, rho);
|
||||
cudaSafeCall(cudaGetLastError());
|
||||
|
||||
if (!stream)
|
||||
cudaSafeCall(cudaDeviceSynchronize());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -405,10 +405,71 @@ CUDA_TEST_P(OpticalFlowDual_TVL1, Accuracy)
|
||||
EXPECT_MAT_SIMILAR(flow, d_flow, 4e-3);
|
||||
}
|
||||
|
||||
class TVL1AsyncParallelLoopBody : public cv::ParallelLoopBody
|
||||
{
|
||||
public:
|
||||
TVL1AsyncParallelLoopBody(const cv::cuda::GpuMat& d_img1_, const cv::cuda::GpuMat& d_img2_, cv::cuda::GpuMat* d_flow_, int iterations_, double gamma_)
|
||||
: d_img1(d_img1_), d_img2(d_img2_), d_flow(d_flow_), iterations(iterations_), gamma(gamma_) {}
|
||||
~TVL1AsyncParallelLoopBody() {}
|
||||
void operator()(const cv::Range& r) const
|
||||
{
|
||||
for (int i = r.start; i < r.end; i++) {
|
||||
cv::cuda::Stream stream;
|
||||
cv::Ptr<cv::cuda::OpticalFlowDual_TVL1> d_alg = cv::cuda::OpticalFlowDual_TVL1::create();
|
||||
d_alg->setNumIterations(iterations);
|
||||
d_alg->setGamma(gamma);
|
||||
d_alg->calc(d_img1, d_img2, d_flow[i], stream);
|
||||
stream.waitForCompletion();
|
||||
}
|
||||
}
|
||||
protected:
|
||||
const cv::cuda::GpuMat& d_img1;
|
||||
const cv::cuda::GpuMat& d_img2;
|
||||
cv::cuda::GpuMat* d_flow;
|
||||
int iterations;
|
||||
double gamma;
|
||||
};
|
||||
|
||||
#define NUM_STREAMS 16
|
||||
|
||||
CUDA_TEST_P(OpticalFlowDual_TVL1, Async)
|
||||
{
|
||||
if (!supportFeature(devInfo, cv::cuda::FEATURE_SET_COMPUTE_30))
|
||||
{
|
||||
throw SkipTestException("CUDA device doesn't support texture objects");
|
||||
}
|
||||
else
|
||||
{
|
||||
cv::Mat frame0 = readImage("opticalflow/rubberwhale1.png", cv::IMREAD_GRAYSCALE);
|
||||
ASSERT_FALSE(frame0.empty());
|
||||
|
||||
cv::Mat frame1 = readImage("opticalflow/rubberwhale2.png", cv::IMREAD_GRAYSCALE);
|
||||
ASSERT_FALSE(frame1.empty());
|
||||
|
||||
const int iterations = 10;
|
||||
|
||||
// Synchronous call
|
||||
cv::Ptr<cv::cuda::OpticalFlowDual_TVL1> d_alg =
|
||||
cv::cuda::OpticalFlowDual_TVL1::create();
|
||||
d_alg->setNumIterations(iterations);
|
||||
d_alg->setGamma(gamma);
|
||||
|
||||
cv::cuda::GpuMat d_flow_gold;
|
||||
d_alg->calc(loadMat(frame0), loadMat(frame1), d_flow_gold);
|
||||
|
||||
// Asynchronous call
|
||||
cv::cuda::GpuMat d_flow[NUM_STREAMS];
|
||||
cv::parallel_for_(cv::Range(0, NUM_STREAMS), TVL1AsyncParallelLoopBody(loadMat(frame0), loadMat(frame1), d_flow, iterations, gamma));
|
||||
|
||||
// Compare the results of synchronous call and asynchronous call
|
||||
for (int i = 0; i < NUM_STREAMS; i++)
|
||||
EXPECT_MAT_NEAR(d_flow_gold, d_flow[i], 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(CUDA_OptFlow, OpticalFlowDual_TVL1, testing::Combine(
|
||||
ALL_DEVICES,
|
||||
testing::Values(Gamma(0.0), Gamma(1.0))));
|
||||
|
||||
|
||||
}} // namespace
|
||||
#endif // HAVE_CUDA
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#include "perf_precomp.hpp"
|
||||
#include <opencv2/dnn/shape_utils.hpp>
|
||||
|
||||
namespace opencv_test {
|
||||
|
||||
struct Layer_Slice : public TestBaseWithParam<tuple<Backend, Target> >
|
||||
{
|
||||
template<int DIMS>
|
||||
void test_slice(const int* inputShape, const int* begin, const int* end)
|
||||
{
|
||||
int backendId = get<0>(GetParam());
|
||||
int targetId = get<1>(GetParam());
|
||||
|
||||
Mat input(DIMS, inputShape, CV_32FC1, Scalar::all(0));
|
||||
for (int i = 0; i < (int)input.total(); ++i)
|
||||
input.ptr<float>()[i] = (float)(i & 4095);
|
||||
|
||||
std::vector<Range> range(DIMS);
|
||||
for (int i = 0; i < DIMS; ++i)
|
||||
range[i] = Range(begin[i], end[i]);
|
||||
|
||||
Net net;
|
||||
LayerParams lp;
|
||||
lp.type = "Slice";
|
||||
lp.name = "testLayer";
|
||||
lp.set("begin", DictValue::arrayInt<int*>((int*)&begin[0], DIMS));
|
||||
lp.set("end", DictValue::arrayInt<int*>((int*)&end[0], DIMS));
|
||||
net.addLayerToPrev(lp.name, lp.type, lp);
|
||||
|
||||
// warmup
|
||||
{
|
||||
net.setInput(input);
|
||||
net.setPreferableBackend(backendId);
|
||||
net.setPreferableTarget(targetId);
|
||||
Mat out = net.forward();
|
||||
|
||||
EXPECT_GT(cv::norm(out, NORM_INF), 0);
|
||||
#if 0
|
||||
//normAssert(out, input(range));
|
||||
cout << input(range).clone().reshape(1, 1) << endl;
|
||||
cout << out.reshape(1, 1) << endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CYCLE()
|
||||
{
|
||||
Mat res = net.forward();
|
||||
}
|
||||
|
||||
SANITY_CHECK_NOTHING();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
PERF_TEST_P_(Layer_Slice, YOLOv4_tiny_1)
|
||||
{
|
||||
const int inputShape[4] = {1, 64, 104, 104};
|
||||
const int begin[] = {0, 32, 0, 0};
|
||||
const int end[] = {1, 64, 104, 104};
|
||||
test_slice<4>(inputShape, begin, end);
|
||||
}
|
||||
|
||||
PERF_TEST_P_(Layer_Slice, YOLOv4_tiny_2)
|
||||
{
|
||||
const int inputShape[4] = {1, 128, 52, 52};
|
||||
const int begin[] = {0, 64, 0, 0};
|
||||
const int end[] = {1, 128, 52, 52};
|
||||
test_slice<4>(inputShape, begin, end);
|
||||
}
|
||||
|
||||
PERF_TEST_P_(Layer_Slice, YOLOv4_tiny_3)
|
||||
{
|
||||
const int inputShape[4] = {1, 256, 26, 26};
|
||||
const int begin[] = {0, 128, 0, 0};
|
||||
const int end[] = {1, 256, 26, 26};
|
||||
test_slice<4>(inputShape, begin, end);
|
||||
}
|
||||
|
||||
|
||||
PERF_TEST_P_(Layer_Slice, FastNeuralStyle_eccv16)
|
||||
{
|
||||
const int inputShape[4] = {1, 128, 80, 100};
|
||||
const int begin[] = {0, 0, 2, 2};
|
||||
const int end[] = {1, 128, 76, 96};
|
||||
test_slice<4>(inputShape, begin, end);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Layer_Slice, dnnBackendsAndTargets(false, false));
|
||||
|
||||
} // namespace
|
||||
@@ -196,6 +196,13 @@ PERF_TEST_P_(DNNTestNetwork, YOLOv3)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000) // nGraph compilation failure
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
|
||||
throw SkipTestException("Test is disabled in OpenVINO 2020.4");
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
throw SkipTestException("Test is disabled in OpenVINO 2020.4");
|
||||
#endif
|
||||
|
||||
Mat sample = imread(findDataFile("dnn/dog416.png"));
|
||||
cvtColor(sample, sample, COLOR_BGR2RGB);
|
||||
Mat inp;
|
||||
@@ -209,6 +216,12 @@ PERF_TEST_P_(DNNTestNetwork, YOLOv4)
|
||||
throw SkipTestException("");
|
||||
if (target == DNN_TARGET_MYRIAD)
|
||||
throw SkipTestException("");
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000) // nGraph compilation failure
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
|
||||
throw SkipTestException("Test is disabled in OpenVINO 2020.4");
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
throw SkipTestException("Test is disabled in OpenVINO 2020.4");
|
||||
#endif
|
||||
Mat sample = imread(findDataFile("dnn/dog416.png"));
|
||||
cvtColor(sample, sample, COLOR_BGR2RGB);
|
||||
Mat inp;
|
||||
@@ -216,6 +229,17 @@ PERF_TEST_P_(DNNTestNetwork, YOLOv4)
|
||||
processNet("dnn/yolov4.weights", "dnn/yolov4.cfg", "", inp);
|
||||
}
|
||||
|
||||
PERF_TEST_P_(DNNTestNetwork, YOLOv4_tiny)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
Mat sample = imread(findDataFile("dnn/dog416.png"));
|
||||
cvtColor(sample, sample, COLOR_BGR2RGB);
|
||||
Mat inp;
|
||||
sample.convertTo(inp, CV_32FC3, 1.0f / 255, 0);
|
||||
processNet("dnn/yolov4-tiny.weights", "dnn/yolov4-tiny.cfg", "", inp);
|
||||
}
|
||||
|
||||
PERF_TEST_P_(DNNTestNetwork, EAST_text_detection)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
|
||||
@@ -363,6 +363,28 @@ namespace cv {
|
||||
fused_layer_names.push_back(last_layer);
|
||||
}
|
||||
|
||||
void setSlice(int input_index, int split_size, int group_id)
|
||||
{
|
||||
int begin[] = {0, split_size * group_id, 0, 0};
|
||||
cv::dnn::DictValue paramBegin = cv::dnn::DictValue::arrayInt(begin, 4);
|
||||
|
||||
int end[] = {-1, begin[1] + split_size, -1, -1};
|
||||
cv::dnn::DictValue paramEnd = cv::dnn::DictValue::arrayInt(end, 4);
|
||||
|
||||
darknet::LayerParameter lp;
|
||||
lp.layer_name = cv::format("slice_%d", layer_id);
|
||||
lp.layer_type = "Slice";
|
||||
lp.layerParams.set("begin", paramBegin);
|
||||
lp.layerParams.set("end", paramEnd);
|
||||
|
||||
lp.bottom_indexes.push_back(fused_layer_names.at(input_index));
|
||||
net->layers.push_back(lp);
|
||||
|
||||
layer_id++;
|
||||
last_layer = lp.layer_name;
|
||||
fused_layer_names.push_back(last_layer);
|
||||
}
|
||||
|
||||
void setReorg(int stride)
|
||||
{
|
||||
cv::dnn::LayerParams reorg_params;
|
||||
@@ -717,6 +739,7 @@ namespace cv {
|
||||
{
|
||||
std::string bottom_layers = getParam<std::string>(layer_params, "layers", "");
|
||||
CV_Assert(!bottom_layers.empty());
|
||||
int groups = getParam<int>(layer_params, "groups", 1);
|
||||
std::vector<int> layers_vec = getNumbers<int>(bottom_layers);
|
||||
|
||||
tensor_shape[0] = 0;
|
||||
@@ -725,10 +748,31 @@ namespace cv {
|
||||
tensor_shape[0] += net->out_channels_vec[layers_vec[k]];
|
||||
}
|
||||
|
||||
if (layers_vec.size() == 1)
|
||||
setParams.setIdentity(layers_vec.at(0));
|
||||
if (groups > 1)
|
||||
{
|
||||
int group_id = getParam<int>(layer_params, "group_id", 0);
|
||||
tensor_shape[0] /= groups;
|
||||
int split_size = tensor_shape[0] / layers_vec.size();
|
||||
for (size_t k = 0; k < layers_vec.size(); ++k)
|
||||
setParams.setSlice(layers_vec[k], split_size, group_id);
|
||||
|
||||
if (layers_vec.size() > 1)
|
||||
{
|
||||
// layer ids in layers_vec - inputs of Slice layers
|
||||
// after adding offset to layers_vec: layer ids - ouputs of Slice layers
|
||||
for (size_t k = 0; k < layers_vec.size(); ++k)
|
||||
layers_vec[k] += layers_vec.size();
|
||||
|
||||
setParams.setConcat(layers_vec.size(), layers_vec.data());
|
||||
}
|
||||
}
|
||||
else
|
||||
setParams.setConcat(layers_vec.size(), layers_vec.data());
|
||||
{
|
||||
if (layers_vec.size() == 1)
|
||||
setParams.setIdentity(layers_vec.at(0));
|
||||
else
|
||||
setParams.setConcat(layers_vec.size(), layers_vec.data());
|
||||
}
|
||||
}
|
||||
else if (layer_type == "dropout" || layer_type == "cost")
|
||||
{
|
||||
@@ -797,7 +841,7 @@ namespace cv {
|
||||
int classes = getParam<int>(layer_params, "classes", -1);
|
||||
int num_of_anchors = getParam<int>(layer_params, "num", -1);
|
||||
float thresh = getParam<float>(layer_params, "thresh", 0.2);
|
||||
float nms_threshold = getParam<float>(layer_params, "nms_threshold", 0.4);
|
||||
float nms_threshold = getParam<float>(layer_params, "nms_threshold", 0.0);
|
||||
float scale_x_y = getParam<float>(layer_params, "scale_x_y", 1.0);
|
||||
|
||||
std::string anchors_values = getParam<std::string>(layer_params, "anchors", std::string());
|
||||
|
||||
+14
-7
@@ -2023,6 +2023,7 @@ struct Net::Impl : public detail::NetImplBase
|
||||
Ptr<BackendNode> inpNode = inpLd.backendNodes[preferableBackend];
|
||||
if (!inpNode.empty()) {
|
||||
Ptr<InfEngineNgraphNode> ieNode = inpNode.dynamicCast<InfEngineNgraphNode>();
|
||||
CV_Assert(!ieNode.empty());
|
||||
ieNode->net->setUnconnectedNodes(ieNode);
|
||||
}
|
||||
}
|
||||
@@ -2067,6 +2068,7 @@ struct Net::Impl : public detail::NetImplBase
|
||||
int cons_inp = cons->oid;
|
||||
Ptr<NgraphBackendWrapper> inpWrapper = inpLd.outputBlobsWrappers[cons_inp].
|
||||
dynamicCast<NgraphBackendWrapper>();
|
||||
CV_Assert(!inpWrapper.empty());
|
||||
auto iter = std::find(inputNames.begin(), inputNames.end(),
|
||||
inpWrapper->dataPtr->getName());
|
||||
if (iter == inputNames.end()) {
|
||||
@@ -2111,7 +2113,7 @@ struct Net::Impl : public detail::NetImplBase
|
||||
|
||||
auto ieInpNode = inputNodes[i].dynamicCast<InfEngineNgraphNode>();
|
||||
CV_Assert(oid < ieInpNode->node->get_output_size());
|
||||
#if INF_ENGINE_VER_MAJOR_GT(2020030000)
|
||||
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_3)
|
||||
inputNodes[i] = Ptr<BackendNode>(new InfEngineNgraphNode(ieInpNode->node->get_output_as_single_output_node(oid)));
|
||||
#else
|
||||
inputNodes[i] = Ptr<BackendNode>(new InfEngineNgraphNode(ieInpNode->node->get_output_as_single_output_node(oid, false)));
|
||||
@@ -2523,8 +2525,7 @@ struct Net::Impl : public detail::NetImplBase
|
||||
// (and so we eliminate the concatenation layer, because the channels
|
||||
// are concatenated implicitly).
|
||||
Ptr<ConcatLayer> concatLayer = ld.layerInstance.dynamicCast<ConcatLayer>();
|
||||
if( !concatLayer.empty() && concatLayer->axis == 1 && !concatLayer->padding &&
|
||||
ld.outputBlobs.size() == 1 )
|
||||
if( !concatLayer.empty() && !concatLayer->padding && ld.outputBlobs.size() == 1 )
|
||||
{
|
||||
Mat& output = ld.outputBlobs[0];
|
||||
UMat umat_output;
|
||||
@@ -2561,7 +2562,8 @@ struct Net::Impl : public detail::NetImplBase
|
||||
// the concatenation optimization is applied with batch_size > 1.
|
||||
// so, for now, we only apply this optimization in the most popular
|
||||
// case batch_size == 1.
|
||||
if( output.dims == 4 && output.size[0] == 1 )
|
||||
int axis = clamp(concatLayer->axis, output.dims);
|
||||
if( output.total(0, axis) == 1 )
|
||||
{
|
||||
size_t i, ninputs = ld.inputBlobsId.size();
|
||||
std::vector<LayerPin> realinputs(ninputs);
|
||||
@@ -2600,14 +2602,14 @@ struct Net::Impl : public detail::NetImplBase
|
||||
OpenCLBackendWrapper::update(ld.outputBlobsWrappers, umats);
|
||||
}
|
||||
#endif
|
||||
Range chrange[] = { Range::all(), Range::all(), Range::all(), Range::all() };
|
||||
std::vector<Range> chrange(output.dims, Range::all());
|
||||
int ofs = 0;
|
||||
for( i = 0; i < ninputs; i++ )
|
||||
{
|
||||
LayerPin pin = realinputs[i];
|
||||
LayerData* inp_i_data = &layers[pin.lid];
|
||||
int channels_i = ld.inputBlobs[i]->size[1];
|
||||
chrange[1] = Range(ofs, ofs + channels_i);
|
||||
int channels_i = ld.inputBlobs[i]->size[axis];
|
||||
chrange[axis] = Range(ofs, ofs + channels_i);
|
||||
printf_(("\toutput %s(%d) to channels (%d, %d)\n", inp_i_data->layerInstance->name.c_str(),
|
||||
pin.oid, ofs, ofs + channels_i));
|
||||
ofs += channels_i;
|
||||
@@ -3261,6 +3263,9 @@ Net Net::Impl::createNetworkFromModelOptimizer(InferenceEngine::CNNNetwork& ieNe
|
||||
}
|
||||
else
|
||||
{
|
||||
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4)
|
||||
CV_Error(Error::StsNotImplemented, "This OpenCV version is built with Inference Engine which has dropped IR v7 support");
|
||||
#else
|
||||
CV_TRACE_REGION("legacy_cnn_layer");
|
||||
try
|
||||
{
|
||||
@@ -3276,6 +3281,8 @@ Net Net::Impl::createNetworkFromModelOptimizer(InferenceEngine::CNNNetwork& ieNe
|
||||
CV_LOG_DEBUG(NULL, "IE layer extraction failure: '" << name << "' - " << e.what());
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -63,9 +63,6 @@ int Subgraph::getInputNodeId(const Ptr<ImportGraphWrapper>& net,
|
||||
{
|
||||
CV_Assert(inpId < node->getNumInputs());
|
||||
std::string name = node->getInputName(inpId);
|
||||
// If operation produces several tensors, they are specified by index
|
||||
// after ':' character. In example, "input:0".
|
||||
name = name.substr(0, name.rfind(':'));
|
||||
const int numNodes = net->getNumNodes();
|
||||
for (int i = 0; i < numNodes; ++i)
|
||||
{
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
|
||||
#ifdef HAVE_DNN_NGRAPH
|
||||
#include <ie_extension.h>
|
||||
#include <ie_plugin_dispatcher.hpp>
|
||||
#endif // HAVE_DNN_NGRAPH
|
||||
|
||||
#include <opencv2/core/utils/configuration.private.hpp>
|
||||
@@ -82,7 +81,7 @@ public:
|
||||
return type_info;
|
||||
}
|
||||
|
||||
#if INF_ENGINE_VER_MAJOR_GT(2020020000)
|
||||
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_3)
|
||||
NgraphCustomOp(const ngraph::OutputVector& inputs,
|
||||
#else
|
||||
NgraphCustomOp(const ngraph::NodeVector& inputs,
|
||||
@@ -112,7 +111,7 @@ public:
|
||||
|
||||
std::shared_ptr<ngraph::Node> copy_with_new_args(const ngraph::NodeVector& new_args) const override
|
||||
{
|
||||
#if INF_ENGINE_VER_MAJOR_GT(2020020000)
|
||||
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_3)
|
||||
return std::make_shared<NgraphCustomOp>(ngraph::as_output_vector(new_args), params);
|
||||
#else
|
||||
return std::make_shared<NgraphCustomOp>(new_args, params);
|
||||
@@ -129,7 +128,6 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<std::string, InferenceEngine::Parameter> params;
|
||||
};
|
||||
|
||||
@@ -137,15 +135,28 @@ private:
|
||||
class InfEngineNgraphCustomLayer : public InferenceEngine::ILayerExecImpl
|
||||
{
|
||||
public:
|
||||
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_2)
|
||||
explicit InfEngineNgraphCustomLayer(const std::shared_ptr<ngraph::Node>& _node)
|
||||
{
|
||||
node = std::dynamic_pointer_cast<NgraphCustomOp>(_node);
|
||||
CV_Assert(node);
|
||||
std::string implStr = node->params["impl"];
|
||||
std::istringstream iss(implStr);
|
||||
#else
|
||||
explicit InfEngineNgraphCustomLayer(const InferenceEngine::CNNLayer& layer) : cnnLayer(layer)
|
||||
{
|
||||
std::istringstream iss(layer.GetParamAsString("impl"));
|
||||
#endif
|
||||
size_t ptr;
|
||||
iss >> ptr;
|
||||
cvLayer = (Layer*)ptr;
|
||||
|
||||
std::vector<std::vector<size_t> > shapes;
|
||||
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_2)
|
||||
strToShapes(node->params["internals"], shapes);
|
||||
#else
|
||||
strToShapes(layer.GetParamAsString("internals"), shapes);
|
||||
#endif
|
||||
internals.resize(shapes.size());
|
||||
for (int i = 0; i < shapes.size(); ++i)
|
||||
internals[i].create(std::vector<int>(shapes[i].begin(), shapes[i].end()), CV_32F);
|
||||
@@ -181,6 +192,29 @@ public:
|
||||
{
|
||||
std::vector<InferenceEngine::DataConfig> inDataConfig;
|
||||
std::vector<InferenceEngine::DataConfig> outDataConfig;
|
||||
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_2)
|
||||
InferenceEngine::SizeVector order;
|
||||
size_t offset = std::numeric_limits<size_t>::max();
|
||||
for (int i = 0; i < node->get_input_size(); ++i)
|
||||
{
|
||||
InferenceEngine::DataConfig conf;
|
||||
auto shape = node->input_value(i).get_shape();
|
||||
order.resize(shape.size());
|
||||
std::iota(order.begin(), order.end(), 0);
|
||||
conf.desc = InferenceEngine::TensorDesc(InferenceEngine::Precision::FP32, shape, {shape, order, offset});
|
||||
inDataConfig.push_back(conf);
|
||||
}
|
||||
|
||||
for (int i = 0; i < node->get_output_size(); ++i)
|
||||
{
|
||||
InferenceEngine::DataConfig conf;
|
||||
auto shape = node->output(i).get_shape();
|
||||
order.resize(shape.size());
|
||||
std::iota(order.begin(), order.end(), 0);
|
||||
conf.desc = InferenceEngine::TensorDesc(InferenceEngine::Precision::FP32, shape, {shape, order, offset});
|
||||
outDataConfig.push_back(conf);
|
||||
}
|
||||
#else
|
||||
for (auto& it : cnnLayer.insData)
|
||||
{
|
||||
InferenceEngine::DataConfig conf;
|
||||
@@ -194,6 +228,7 @@ public:
|
||||
conf.desc = it->getTensorDesc();
|
||||
outDataConfig.push_back(conf);
|
||||
}
|
||||
#endif
|
||||
|
||||
InferenceEngine::LayerConfig layerConfig;
|
||||
layerConfig.inConfs = inDataConfig;
|
||||
@@ -210,12 +245,16 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_2)
|
||||
std::shared_ptr<NgraphCustomOp> node;
|
||||
#else
|
||||
InferenceEngine::CNNLayer cnnLayer;
|
||||
#endif
|
||||
dnn::Layer* cvLayer;
|
||||
std::vector<Mat> internals;
|
||||
};
|
||||
|
||||
|
||||
#if INF_ENGINE_VER_MAJOR_LT(INF_ENGINE_RELEASE_2020_2)
|
||||
class InfEngineNgraphCustomLayerFactory : public InferenceEngine::ILayerImplFactory {
|
||||
public:
|
||||
explicit InfEngineNgraphCustomLayerFactory(const InferenceEngine::CNNLayer* layer) : cnnLayer(*layer)
|
||||
@@ -234,15 +273,29 @@ public:
|
||||
private:
|
||||
InferenceEngine::CNNLayer cnnLayer;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
class InfEngineNgraphExtension : public InferenceEngine::IExtension
|
||||
{
|
||||
public:
|
||||
void Unload() noexcept override {}
|
||||
void Release() noexcept override { delete this; }
|
||||
void GetVersion(const InferenceEngine::Version*&) const noexcept override {}
|
||||
|
||||
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_2)
|
||||
std::vector<std::string> getImplTypes(const std::shared_ptr<ngraph::Node>& node) override {
|
||||
return {"CPU"};
|
||||
}
|
||||
|
||||
InferenceEngine::ILayerImpl::Ptr getImplementation(const std::shared_ptr<ngraph::Node>& node, const std::string& implType) override {
|
||||
if (std::dynamic_pointer_cast<NgraphCustomOp>(node) && implType == "CPU") {
|
||||
return std::make_shared<InfEngineNgraphCustomLayer>(node);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
#else
|
||||
virtual void SetLogCallback(InferenceEngine::IErrorListener&) noexcept {}
|
||||
virtual void Unload() noexcept {}
|
||||
virtual void Release() noexcept {}
|
||||
virtual void GetVersion(const InferenceEngine::Version*&) const noexcept {}
|
||||
|
||||
virtual InferenceEngine::StatusCode getPrimitiveTypes(char**&, unsigned int&,
|
||||
InferenceEngine::ResponseDesc*) noexcept
|
||||
@@ -259,6 +312,7 @@ public:
|
||||
factory = new InfEngineNgraphCustomLayerFactory(cnnLayer);
|
||||
return InferenceEngine::StatusCode::OK;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -283,7 +337,7 @@ InfEngineNgraphNode::InfEngineNgraphNode(const std::vector<Ptr<BackendNode> >& n
|
||||
{"internals", shapesToStr(internals)}
|
||||
};
|
||||
|
||||
#if INF_ENGINE_VER_MAJOR_GT(2020020000)
|
||||
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_3)
|
||||
ngraph::OutputVector inp_nodes;
|
||||
#else
|
||||
ngraph::NodeVector inp_nodes;
|
||||
|
||||
@@ -54,9 +54,14 @@
|
||||
|
||||
#ifdef HAVE_DNN_NGRAPH
|
||||
#include "../ie_ngraph.hpp"
|
||||
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4)
|
||||
#include <ngraph/op/detection_output.hpp>
|
||||
#else
|
||||
#include <ngraph/op/experimental/layers/detection_output.hpp>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace dnn
|
||||
|
||||
@@ -667,8 +667,11 @@ struct MishFunctor : public BaseFunctor
|
||||
{
|
||||
for( int i = 0; i < len; i++ )
|
||||
{
|
||||
// Use fast approximation introduced in https://github.com/opencv/opencv/pull/17200
|
||||
float x = srcptr[i];
|
||||
dstptr[i] = x * tanh(log(1.0f + exp(x)));
|
||||
float eX = exp(std::min(x, 20.f));
|
||||
float n = (eX + 2) * eX;
|
||||
dstptr[i] = (x * n) / (n + 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,9 +48,14 @@
|
||||
|
||||
#ifdef HAVE_DNN_NGRAPH
|
||||
#include "../ie_ngraph.hpp"
|
||||
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4)
|
||||
#include <ngraph/op/roi_pooling.hpp>
|
||||
#include <ngraph/op/psroi_pooling.hpp>
|
||||
#else
|
||||
#include <ngraph/op/experimental/layers/roi_pooling.hpp>
|
||||
#include <ngraph/op/experimental/layers/psroi_pooling.hpp>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <float.h>
|
||||
#include <algorithm>
|
||||
|
||||
@@ -46,9 +46,14 @@
|
||||
|
||||
#ifdef HAVE_DNN_NGRAPH
|
||||
#include "../ie_ngraph.hpp"
|
||||
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4)
|
||||
#include <ngraph/op/prior_box.hpp>
|
||||
#include <ngraph/op/prior_box_clustered.hpp>
|
||||
#else
|
||||
#include <ngraph/op/experimental/layers/prior_box.hpp>
|
||||
#include <ngraph/op/experimental/layers/prior_box_clustered.hpp>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <float.h>
|
||||
#include <algorithm>
|
||||
|
||||
@@ -10,8 +10,12 @@
|
||||
|
||||
#ifdef HAVE_DNN_NGRAPH
|
||||
#include "../ie_ngraph.hpp"
|
||||
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4)
|
||||
#include <ngraph/op/proposal.hpp>
|
||||
#else
|
||||
#include <ngraph/op/experimental/layers/proposal.hpp>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace cv { namespace dnn {
|
||||
|
||||
|
||||
@@ -412,12 +412,12 @@ public:
|
||||
auto scale_x_y_node = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, ngraph::Shape{1}, &scale_x_y);
|
||||
auto shift_node = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, ngraph::Shape{1}, std::vector<float>{0.5});
|
||||
|
||||
auto axis = ngraph::op::Constant::create<int64_t>(ngraph::element::i64, ngraph::Shape{}, {0});
|
||||
auto splits = ngraph::op::Constant::create<int64_t>(ngraph::element::i64, ngraph::Shape{5}, {1, 1, 1, 1, rows - 4});
|
||||
auto split = std::make_shared<ngraph::op::v1::VariadicSplit>(input2d, axis, splits);
|
||||
std::shared_ptr<ngraph::Node> box_x;
|
||||
{
|
||||
auto lower_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{0, 0});
|
||||
auto upper_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{1, cols});
|
||||
box_x = std::make_shared<ngraph::op::v1::StridedSlice>(input2d, lower_bounds, upper_bounds, strides, std::vector<int64_t>{}, std::vector<int64_t>{});
|
||||
box_x = std::make_shared<ngraph::op::Sigmoid>(box_x);
|
||||
box_x = std::make_shared<ngraph::op::Sigmoid>(split->output(0));
|
||||
box_x = std::make_shared<ngraph::op::v1::Subtract>(box_x, shift_node, ngraph::op::AutoBroadcastType::NUMPY);
|
||||
box_x = std::make_shared<ngraph::op::v1::Multiply>(box_x, scale_x_y_node, ngraph::op::AutoBroadcastType::NUMPY);
|
||||
box_x = std::make_shared<ngraph::op::v1::Add>(box_x, shift_node, ngraph::op::AutoBroadcastType::NUMPY);
|
||||
@@ -443,10 +443,7 @@ public:
|
||||
|
||||
std::shared_ptr<ngraph::Node> box_y;
|
||||
{
|
||||
auto lower_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{1, 0});
|
||||
auto upper_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{2, cols});
|
||||
box_y = std::make_shared<ngraph::op::v1::StridedSlice>(input2d, lower_bounds, upper_bounds, strides, std::vector<int64_t>{}, std::vector<int64_t>{});
|
||||
box_y = std::make_shared<ngraph::op::Sigmoid>(box_y);
|
||||
box_y = std::make_shared<ngraph::op::Sigmoid>(split->output(1));
|
||||
box_y = std::make_shared<ngraph::op::v1::Subtract>(box_y, shift_node, ngraph::op::AutoBroadcastType::NUMPY);
|
||||
box_y = std::make_shared<ngraph::op::v1::Multiply>(box_y, scale_x_y_node, ngraph::op::AutoBroadcastType::NUMPY);
|
||||
box_y = std::make_shared<ngraph::op::v1::Add>(box_y, shift_node, ngraph::op::AutoBroadcastType::NUMPY);
|
||||
@@ -499,45 +496,32 @@ public:
|
||||
std::copy(bias_h.begin(), bias_h.begin() + h * anchors, bias_h.begin() + i * h * anchors);
|
||||
}
|
||||
|
||||
auto lower_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{2, 0});
|
||||
auto upper_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{3, cols});
|
||||
box_w = std::make_shared<ngraph::op::v1::StridedSlice>(input2d, lower_bounds, upper_bounds, strides, std::vector<int64_t>{}, std::vector<int64_t>{});
|
||||
box_w = std::make_shared<ngraph::op::v0::Exp>(box_w);
|
||||
box_w = std::make_shared<ngraph::op::v0::Exp>(split->output(2));
|
||||
box_w = std::make_shared<ngraph::op::v1::Reshape>(box_w, shape_3d, true);
|
||||
auto anchor_w_node = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, box_broad_shape, bias_w.data());
|
||||
box_w = std::make_shared<ngraph::op::v1::Multiply>(box_w, anchor_w_node, ngraph::op::AutoBroadcastType::NUMPY);
|
||||
|
||||
lower_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{3, 0});
|
||||
upper_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{4, cols});
|
||||
box_h = std::make_shared<ngraph::op::v1::StridedSlice>(input2d, lower_bounds, upper_bounds, strides, std::vector<int64_t>{}, std::vector<int64_t>{});
|
||||
box_h = std::make_shared<ngraph::op::v0::Exp>(box_h);
|
||||
box_h = std::make_shared<ngraph::op::v0::Exp>(split->output(3));
|
||||
box_h = std::make_shared<ngraph::op::v1::Reshape>(box_h, shape_3d, true);
|
||||
auto anchor_h_node = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, box_broad_shape, bias_h.data());
|
||||
box_h = std::make_shared<ngraph::op::v1::Multiply>(box_h, anchor_h_node, ngraph::op::AutoBroadcastType::NUMPY);
|
||||
}
|
||||
|
||||
auto region_splits = ngraph::op::Constant::create<int64_t>(ngraph::element::i64, ngraph::Shape{3}, {4, 1, rows - 5});
|
||||
auto region_split = std::make_shared<ngraph::op::v1::VariadicSplit>(region, axis, region_splits);
|
||||
|
||||
std::shared_ptr<ngraph::Node> scale;
|
||||
{
|
||||
auto lower_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{4, 0});
|
||||
auto upper_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{5, cols});
|
||||
scale = std::make_shared<ngraph::op::v1::StridedSlice>(region, lower_bounds, upper_bounds, strides, std::vector<int64_t>{}, std::vector<int64_t>{});
|
||||
|
||||
if (classfix == -1)
|
||||
{
|
||||
auto thresh_node = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, ngraph::Shape{1}, std::vector<float>{0.5});
|
||||
auto mask = std::make_shared<ngraph::op::v1::Less>(scale, thresh_node);
|
||||
auto zero_node = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, mask->get_shape(), std::vector<float>(b * cols, 0));
|
||||
scale = std::make_shared<ngraph::op::v1::Select>(mask, scale, zero_node);
|
||||
}
|
||||
float thr = classfix == -1 ? 0.5 : 0;
|
||||
auto thresh_node = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, ngraph::Shape{1}, std::vector<float>{thr});
|
||||
auto mask = std::make_shared<ngraph::op::v1::Less>(region_split->output(1), thresh_node);
|
||||
auto zero_node = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, mask->get_shape(), std::vector<float>(cols, 0));
|
||||
scale = std::make_shared<ngraph::op::v1::Select>(mask, zero_node, region_split->output(1));
|
||||
}
|
||||
|
||||
std::shared_ptr<ngraph::Node> probs;
|
||||
{
|
||||
auto lower_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{5, 0});
|
||||
auto upper_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{rows, cols});
|
||||
auto classes = std::make_shared<ngraph::op::v1::StridedSlice>(region, lower_bounds, upper_bounds, strides, std::vector<int64_t>{}, std::vector<int64_t>{});
|
||||
probs = std::make_shared<ngraph::op::v1::Multiply>(classes, scale, ngraph::op::AutoBroadcastType::NUMPY);
|
||||
|
||||
probs = std::make_shared<ngraph::op::v1::Multiply>(region_split->output(2), scale, ngraph::op::AutoBroadcastType::NUMPY);
|
||||
auto thresh_node = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, ngraph::Shape{1}, &thresh);
|
||||
auto mask = std::make_shared<ngraph::op::v1::Greater>(probs, thresh_node);
|
||||
auto zero_node = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, mask->get_shape(), std::vector<float>((rows - 5) * cols, 0));
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
//M*/
|
||||
|
||||
#include "../precomp.hpp"
|
||||
#include "../op_inf_engine.hpp"
|
||||
|
||||
#include <opencv2/dnn/shape_utils.hpp>
|
||||
#include <opencv2/dnn/all_layers.hpp>
|
||||
@@ -50,10 +49,15 @@
|
||||
#include "opencl_kernels_dnn.hpp"
|
||||
#endif
|
||||
|
||||
#include "../op_inf_engine.hpp"
|
||||
#ifdef HAVE_DNN_NGRAPH
|
||||
#include "../ie_ngraph.hpp"
|
||||
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4)
|
||||
#include <ngraph/op/reorg_yolo.hpp>
|
||||
#else
|
||||
#include <ngraph/op/experimental/layers/reorg_yolo.hpp>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
@@ -11,8 +11,12 @@
|
||||
|
||||
#ifdef HAVE_DNN_NGRAPH
|
||||
#include "../ie_ngraph.hpp"
|
||||
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4)
|
||||
#include <ngraph/op/interpolate.hpp>
|
||||
#else
|
||||
#include <ngraph/op/experimental/layers/interpolate.hpp>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace cv { namespace dnn {
|
||||
|
||||
|
||||
@@ -47,6 +47,8 @@
|
||||
#include "layers_common.hpp"
|
||||
#include <opencv2/dnn/shape_utils.hpp>
|
||||
|
||||
#include <opencv2/core/utils/logger.hpp>
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
#include "opencl_kernels_dnn.hpp"
|
||||
#endif
|
||||
@@ -197,6 +199,18 @@ public:
|
||||
finalSliceRanges[i][j] = clamp(finalSliceRanges[i][j], inpShape[j]);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
std::cout << "DEBUG: DNN/Slice: " << outputs.size() << " inpShape=" << inpShape << std::endl;
|
||||
for (int i = 0; i < outputs.size(); ++i)
|
||||
{
|
||||
for (int j = 0; j < finalSliceRanges[i].size(); ++j)
|
||||
{
|
||||
std::cout << finalSliceRanges[i][j];
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
@@ -205,46 +219,149 @@ public:
|
||||
std::vector<UMat> inputs;
|
||||
std::vector<UMat> outputs;
|
||||
|
||||
bool use_half = (inputs_.depth() == CV_16S);
|
||||
inputs_.getUMatVector(inputs);
|
||||
outputs_.getUMatVector(outputs);
|
||||
|
||||
if (inputs[0].dims < 4 || (total(shape(outputs[0]), 0, 2) % 4 != 0) ||
|
||||
(total(shape(outputs[0]), 2) % 4 != 0))
|
||||
return false;
|
||||
CV_Assert(outputs.size() == finalSliceRanges.size());
|
||||
|
||||
String opts;
|
||||
if (use_half)
|
||||
opts = "-DDtype=half -DDtype4=half4 -DDtype8=half8";
|
||||
else
|
||||
opts = "-DDtype=float -DDtype4=float4 -DDtype8=float8";
|
||||
const UMat& inpMat = inputs[0];
|
||||
for (size_t i = 0; i < outputs.size(); i++)
|
||||
const UMat& input = inputs[0];
|
||||
if (input.dims > 5)
|
||||
{
|
||||
int groups = outputs[i].size[0];
|
||||
int channels = outputs[i].size[1];
|
||||
int rows = outputs[i].size[2];
|
||||
int cols = outputs[i].size[3];
|
||||
|
||||
ocl::Kernel kernel("slice", ocl::dnn::slice_oclsrc, opts);
|
||||
size_t local[] = { 128 };
|
||||
size_t global[] = { (size_t)groups * channels / 4 * local[0] };
|
||||
int idx = 0;
|
||||
kernel.set(idx++, ocl::KernelArg::PtrReadOnly(inpMat));
|
||||
kernel.set(idx++, (int)(inpMat.size[2] * inpMat.size[3]));
|
||||
kernel.set(idx++, (int)(rows * cols));
|
||||
kernel.set(idx++, (int)inpMat.size[3]);
|
||||
kernel.set(idx++, (int)cols);
|
||||
kernel.set(idx++, (int)finalSliceRanges[i][2].start);
|
||||
kernel.set(idx++, (int)finalSliceRanges[i][3].start);
|
||||
kernel.set(idx++, ocl::KernelArg::PtrWriteOnly(outputs[i]));
|
||||
bool ret = kernel.run(1, global, local, false);
|
||||
if (!ret)
|
||||
return false;
|
||||
CV_LOG_INFO(NULL, "DNN/OpenCL/Slice: implementation doesn't support dims=" << input.dims << ". Fallback to CPU");
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t WSZ = 128;
|
||||
|
||||
const int dims = input.dims;
|
||||
const int elemSize = (int)input.elemSize();
|
||||
String opts0 = cv::format(
|
||||
"-DDIMS=%d -DELEMSIZE=%d",
|
||||
dims, elemSize
|
||||
);
|
||||
for (int d = 0; d < dims; d++)
|
||||
{
|
||||
opts0 += cv::format(" -DSRC_STEP_%d=%d", d, (int)input.step[dims - 1 - d]);
|
||||
}
|
||||
String kname = cv::format("slice_%d", dims);
|
||||
for (size_t i = 0; i < outputs.size(); i++)
|
||||
{
|
||||
UMat& output = outputs[i];
|
||||
const std::vector<Range>& range = finalSliceRanges[i];
|
||||
|
||||
String opts = opts0;
|
||||
|
||||
CV_CheckEQ(output.dims, dims, "");
|
||||
for (int d = 0; d < dims; d++)
|
||||
{
|
||||
opts += cv::format(" -DDST_STEP_%d=%d -DDST_SZ_%d=%d -DSRC_START_%d=%d",
|
||||
d, (int)output.step[dims - 1 - d],
|
||||
d, (int)output.size[dims - 1 - d],
|
||||
d, (int)range[dims - 1 - d].start
|
||||
);
|
||||
CV_CheckEQ(range[d].size(), (int)output.size[d], "");
|
||||
}
|
||||
|
||||
int block_dims = 0;
|
||||
size_t block_size = elemSize;
|
||||
for (int i = dims - 1; i >= 0; --i)
|
||||
{
|
||||
if (input.step[i] != output.step[i])
|
||||
break;
|
||||
block_size *= output.size[i];
|
||||
block_dims++;
|
||||
}
|
||||
|
||||
const size_t total = output.total() * elemSize;
|
||||
size_t num_blocks = total / block_size;
|
||||
|
||||
if ((num_blocks <= 8 && block_size >= WSZ * 4) || (block_size >= WSZ * 64))
|
||||
{
|
||||
// use 1D copy mode
|
||||
opts += cv::format(" -DUSE_COPY_1D=1");
|
||||
|
||||
opts += cv::format(" -DBLOCK_DIMS=%d", block_dims);
|
||||
opts += cv::format(" -DBLOCK_DIMS_CONTIGUOUS=%d", block_dims);
|
||||
opts += cv::format(" -DBLOCK_SIZE=%d", (int)block_size);
|
||||
|
||||
opts += cv::format(" -DBLOCK_COLS=%d", (int)block_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
// use 2D copy mode
|
||||
int block_cols = block_size;
|
||||
int block_dims_contiguous = block_dims;
|
||||
size_t input_base_step = input.step[dims - 1 - block_dims_contiguous];
|
||||
size_t output_base_step = output.step[dims - 1 - block_dims_contiguous];
|
||||
|
||||
size_t block_rows = 1;
|
||||
for (int i = dims - 1 - block_dims_contiguous; i >= 0; --i)
|
||||
{
|
||||
if (input.step[i] * output_base_step != output.step[i] * input_base_step)
|
||||
break;
|
||||
block_rows *= output.size[i];
|
||||
block_dims++;
|
||||
}
|
||||
|
||||
block_size *= block_rows;
|
||||
|
||||
num_blocks = total / block_size;
|
||||
|
||||
if (block_rows > 1)
|
||||
{
|
||||
opts += cv::format(" -DBLOCK_DIMS=%d", block_dims);
|
||||
opts += cv::format(" -DBLOCK_DIMS_CONTIGUOUS=%d", block_dims_contiguous);
|
||||
opts += cv::format(" -DBLOCK_SIZE=%d", (int)block_size);
|
||||
|
||||
opts += cv::format(" -DBLOCK_COLS=%d", (int)block_cols);
|
||||
|
||||
opts += cv::format(" -DBLOCK_ROWS=%d", (int)block_rows);
|
||||
opts += cv::format(" -DBLOCK_SRC_STRIDE=%d", (int)input_base_step);
|
||||
}
|
||||
else
|
||||
{
|
||||
// use 1D copy mode
|
||||
opts += cv::format(" -DUSE_COPY_1D=1");
|
||||
|
||||
opts += cv::format(" -DBLOCK_DIMS=%d", block_dims_contiguous);
|
||||
opts += cv::format(" -DBLOCK_DIMS_CONTIGUOUS=%d", block_dims_contiguous);
|
||||
opts += cv::format(" -DBLOCK_SIZE=%d", (int)block_size);
|
||||
|
||||
opts += cv::format(" -DBLOCK_COLS=%d", (int)block_size);
|
||||
}
|
||||
}
|
||||
|
||||
const size_t MIN_WORK_ITEMS = 16;
|
||||
if (block_size <= 4 * MIN_WORK_ITEMS)
|
||||
WSZ = 4;
|
||||
else if (block_size <= 8 * MIN_WORK_ITEMS)
|
||||
WSZ = 8;
|
||||
else if (block_size <= 16 * MIN_WORK_ITEMS)
|
||||
WSZ = 16;
|
||||
else if (block_size <= 32 * MIN_WORK_ITEMS)
|
||||
WSZ = 32;
|
||||
else if (block_size <= 64 * MIN_WORK_ITEMS)
|
||||
WSZ = 64;
|
||||
|
||||
opts += cv::format(" -DWSZ=%d", (int)WSZ);
|
||||
|
||||
size_t local[] = { WSZ, 1 };
|
||||
size_t global[] = { WSZ, num_blocks };
|
||||
|
||||
ocl::Kernel kernel(kname.c_str(), ocl::dnn::slice_oclsrc, opts);
|
||||
if (kernel.empty())
|
||||
return false;
|
||||
bool ret = kernel.args(
|
||||
ocl::KernelArg::PtrReadOnly(input),
|
||||
ocl::KernelArg::PtrWriteOnly(output)
|
||||
)
|
||||
.run(2, global, local, false);
|
||||
if (!ret)
|
||||
return false;
|
||||
} // for outputs.size()
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void forward(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays internals_arr) CV_OVERRIDE
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
#include <ie_extension.h>
|
||||
#include <ie_plugin_dispatcher.hpp>
|
||||
#endif // HAVE_INF_ENGINE
|
||||
|
||||
#include <opencv2/core/utils/configuration.private.hpp>
|
||||
@@ -832,18 +831,18 @@ void InfEngineBackendNet::initPlugin(InferenceEngine::CNNNetwork& net)
|
||||
CV_LOG_INFO(NULL, "DNN-IE: Can't register OpenCV custom layers extension: " << e.what());
|
||||
}
|
||||
#endif
|
||||
#ifndef _WIN32
|
||||
// Limit the number of CPU threads.
|
||||
#if INF_ENGINE_VER_MAJOR_LE(INF_ENGINE_RELEASE_2019R1)
|
||||
#ifndef _WIN32
|
||||
enginePtr->SetConfig({{
|
||||
InferenceEngine::PluginConfigParams::KEY_CPU_THREADS_NUM, format("%d", getNumThreads()),
|
||||
}}, 0);
|
||||
#endif // _WIN32
|
||||
#else
|
||||
if (device_name == "CPU")
|
||||
ie.SetConfig({{
|
||||
InferenceEngine::PluginConfigParams::KEY_CPU_THREADS_NUM, format("%d", getNumThreads()),
|
||||
}}, device_name);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#if INF_ENGINE_VER_MAJOR_LE(INF_ENGINE_RELEASE_2019R1)
|
||||
|
||||
@@ -25,10 +25,12 @@
|
||||
#define INF_ENGINE_RELEASE_2019R3 2019030000
|
||||
#define INF_ENGINE_RELEASE_2020_1 2020010000
|
||||
#define INF_ENGINE_RELEASE_2020_2 2020020000
|
||||
#define INF_ENGINE_RELEASE_2020_3 2020030000
|
||||
#define INF_ENGINE_RELEASE_2020_4 2020040000
|
||||
|
||||
#ifndef INF_ENGINE_RELEASE
|
||||
#warning("IE version have not been provided via command-line. Using 2020.2 by default")
|
||||
#define INF_ENGINE_RELEASE INF_ENGINE_RELEASE_2020_2
|
||||
#warning("IE version have not been provided via command-line. Using 2020.4 by default")
|
||||
#define INF_ENGINE_RELEASE INF_ENGINE_RELEASE_2020_4
|
||||
#endif
|
||||
|
||||
#define INF_ENGINE_VER_MAJOR_GT(ver) (((INF_ENGINE_RELEASE) / 10000) > ((ver) / 10000))
|
||||
@@ -42,7 +44,7 @@
|
||||
#pragma GCC diagnostic ignored "-Wsuggest-override"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DNN_IE_NN_BUILDER_2019
|
||||
#if defined(HAVE_DNN_IE_NN_BUILDER_2019) || INF_ENGINE_VER_MAJOR_EQ(INF_ENGINE_RELEASE_2020_4)
|
||||
//#define INFERENCE_ENGINE_DEPRECATED // turn off deprecation warnings from IE
|
||||
//there is no way to suppress warnings from IE only at this moment, so we are forced to suppress warnings globally
|
||||
#if defined(__GNUC__)
|
||||
@@ -51,7 +53,7 @@
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable: 4996) // was declared deprecated
|
||||
#endif
|
||||
#endif // HAVE_DNN_IE_NN_BUILDER_2019
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && INF_ENGINE_VER_MAJOR_LT(INF_ENGINE_RELEASE_2020_1)
|
||||
#pragma GCC visibility push(default)
|
||||
@@ -225,7 +227,9 @@ private:
|
||||
class InfEngineExtension : public InferenceEngine::IExtension
|
||||
{
|
||||
public:
|
||||
#if INF_ENGINE_VER_MAJOR_LT(INF_ENGINE_RELEASE_2020_2)
|
||||
virtual void SetLogCallback(InferenceEngine::IErrorListener&) noexcept {}
|
||||
#endif
|
||||
virtual void Unload() noexcept {}
|
||||
virtual void Release() noexcept {}
|
||||
virtual void GetVersion(const InferenceEngine::Version*&) const noexcept {}
|
||||
|
||||
+274
-72
@@ -1,81 +1,283 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2017, Intel Corporation, all rights reserved.
|
||||
// Copyright (c) 2016-2017 Fabian David Tschopp, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#if defined(cl_khr_fp16)
|
||||
#pragma OPENCL EXTENSION cl_khr_fp16 : enable
|
||||
// Copyright (C) 2020, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
/*
|
||||
Specialization constants:
|
||||
- WSZ: size of OpenCL local group
|
||||
- DIMS: number of working dimensions
|
||||
- ELEMSIZE: element size in bytes
|
||||
- DST_SZ_<i>: dst sizes
|
||||
- SRC_START_<i>: src index shift (slice .start value)
|
||||
- SRC_STEP_<i>: src steps (bytes)
|
||||
- DST_STEP_<i>: dst steps (bytes), derived from DST_SZ_<i> and ELEMSIZE
|
||||
- BLOCK_DIMS: number of dims for copy block (argmax(count(SRC_STEP_<i> != DST_STEP_<i>) <= 1))
|
||||
- BLOCK_DIMS_CONTIGUOUS (<= BLOCK_DIMS): SRC_STEP_<i> == DST_STEP_<i> for i in [0, BLOCK_DIMS_CONTIGUOUS)
|
||||
|
||||
derived specialization constants:
|
||||
- BLOCK_SIZE: ELEMSIZE * mul(DST_SZ_<i>) for i in [0, BLOCK_DIMS)
|
||||
|
||||
- USE_COPY_1D iff BLOCK_DIMS == BLOCK_DIMS_CONTIGUOUS
|
||||
- BLOCK_COLS:
|
||||
* with USE_COPY_1D: BLOCK_SIZE
|
||||
* w/o USE_COPY_1D: ELEMSIZE * mul(DST_SZ_<i>) for i in [0, BLOCK_DIMS_CONTIGUOUS)
|
||||
- BLOCK_ROWS:
|
||||
* with USE_COPY_1D: N/A
|
||||
* w/o USE_COPY_1D: ELEMSIZE * mul(DST_SZ_<i>) for i in [BLOCK_DIMS_CONTIGUOUS, BLOCK_DIMS)
|
||||
- BLOCK_SRC_STRIDE:
|
||||
* with USE_COPY_1D: N/A
|
||||
* w/o USE_COPY_1D: ELEMSIZE * mul(SRC_STEP_<i>) for i in [0, BLOCK_DIMS_CONTIGUOUS)
|
||||
|
||||
Note: SZ, STEP values are in reversed order than OpenCV Mat:
|
||||
- NCHW SZ: [cols, rows, channels, batch]
|
||||
- NCHW STEP: [elemsize, cols * elemsize, rows * cols * elemsize, ...] (DIMS+1 value)
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
local: <WSZ, 1, 1>
|
||||
global: <WSZ, number_of_copy_blocks, 1>
|
||||
*/
|
||||
|
||||
#define CONCAT_(A, B) A##B
|
||||
#define CONCAT(A, B) CONCAT_(A, B)
|
||||
|
||||
#define BLOCK_COLS_X4 (BLOCK_COLS / 4)
|
||||
#define BLOCK_COLS_X16 (BLOCK_COLS / 16)
|
||||
|
||||
#ifdef USE_COPY_1D
|
||||
|
||||
static inline
|
||||
__attribute__((always_inline))
|
||||
void copy_block_1d(
|
||||
__global const uchar* src0,
|
||||
const uint src_offset,
|
||||
__global uchar* dst0,
|
||||
const uint dst_offset
|
||||
)
|
||||
{
|
||||
__global const uchar* src = src0 + src_offset;
|
||||
__global uchar* dst = dst0 + dst_offset;
|
||||
|
||||
uint processed = 0;
|
||||
|
||||
#if BLOCK_COLS_X16 >= 4
|
||||
{
|
||||
// uchar16 x 4rows per iteration
|
||||
uint i = get_local_id(0) * 16; // uchar16
|
||||
while (i < BLOCK_COLS_X16 * 16)
|
||||
{
|
||||
uint4 idx = (uint4)(i, i + 16 * WSZ, i + 32 * WSZ, i + 48 * WSZ);
|
||||
idx = select((uint4)i, idx, idx < (BLOCK_COLS_X16 * 16));
|
||||
|
||||
uchar16 a0 = vload16(0, src + idx.s0);
|
||||
uchar16 a1 = vload16(0, src + idx.s1);
|
||||
uchar16 a2 = vload16(0, src + idx.s2);
|
||||
uchar16 a3 = vload16(0, src + idx.s3);
|
||||
|
||||
vstore16(a0, 0, dst + idx.s0);
|
||||
vstore16(a1, 0, dst + idx.s1);
|
||||
vstore16(a2, 0, dst + idx.s2);
|
||||
vstore16(a3, 0, dst + idx.s3);
|
||||
|
||||
i += WSZ * 16 * 4;
|
||||
}
|
||||
processed = BLOCK_COLS_X16 * 16;
|
||||
}
|
||||
#else
|
||||
#define SKIP_1D_BLOCK_COLS_X16 1
|
||||
#endif
|
||||
|
||||
__kernel void slice(__global const Dtype* src,
|
||||
const int src_plane_size,
|
||||
const int dst_plane_size,
|
||||
const int src_cols,
|
||||
const int dst_cols,
|
||||
const int row_offset,
|
||||
const int col_offset,
|
||||
__global Dtype* dst)
|
||||
{
|
||||
unsigned int row_gid = get_group_id(0);
|
||||
unsigned int lid = get_local_id(0);
|
||||
const __global Dtype *src_read = src + row_gid * 4 * src_plane_size;
|
||||
__global Dtype *dst_read = dst + row_gid * 4 * dst_plane_size;
|
||||
Dtype4 a0, a1, a2, a3;
|
||||
|
||||
int i = lid;
|
||||
while( i < dst_plane_size / 4)
|
||||
#if BLOCK_COLS_X4 > 0 && (defined(SKIP_1D_BLOCK_COLS_X16) || (BLOCK_COLS_X16 * 16 != BLOCK_COLS_X4 * 4))
|
||||
{
|
||||
int row = (4 * i) / dst_cols + row_offset;
|
||||
int col = (4 * i) % dst_cols + col_offset;
|
||||
int src_index = row * src_cols + col;
|
||||
// uchar4 x 4rows per iteration
|
||||
uint i = get_local_id(0) * 4 + processed; // uchar4
|
||||
while (i < BLOCK_COLS_X4 * 4)
|
||||
{
|
||||
uint4 idx = (uint4)(i, i + 4 * WSZ, i + 8 * WSZ, i + 12 * WSZ);
|
||||
idx = select((uint4)i, idx, idx < (BLOCK_COLS_X4 * 4));
|
||||
|
||||
a0 = vload4(0, src_read + src_index);
|
||||
a1 = vload4(0, src_read + src_index + src_plane_size);
|
||||
a2 = vload4(0, src_read + src_index + 2 * src_plane_size);
|
||||
a3 = vload4(0, src_read + src_index + 3 * src_plane_size);
|
||||
uchar4 a0 = vload4(0, src + idx.s0);
|
||||
uchar4 a1 = vload4(0, src + idx.s1);
|
||||
uchar4 a2 = vload4(0, src + idx.s2);
|
||||
uchar4 a3 = vload4(0, src + idx.s3);
|
||||
|
||||
vstore4(a0, i, dst_read);
|
||||
vstore4(a1, i, dst_read + dst_plane_size);
|
||||
vstore4(a2, i, dst_read + 2 * dst_plane_size);
|
||||
vstore4(a3, i, dst_read + 3 * dst_plane_size);
|
||||
vstore4(a0, 0, dst + idx.s0);
|
||||
vstore4(a1, 0, dst + idx.s1);
|
||||
vstore4(a2, 0, dst + idx.s2);
|
||||
vstore4(a3, 0, dst + idx.s3);
|
||||
|
||||
i += get_local_size(0);
|
||||
i += WSZ * 4 * 4;
|
||||
}
|
||||
processed = BLOCK_COLS_X4 * 4;
|
||||
}
|
||||
#else
|
||||
#define SKIP_1D_BLOCK_COLS_X4 1
|
||||
#endif // BLOCK_COLS_X4 > 0
|
||||
|
||||
#if (defined(SKIP_1D_BLOCK_COLS_X16) && defined(SKIP_1D_BLOCK_COLS_X4)) || BLOCK_COLS_X4 * 4 != BLOCK_COLS
|
||||
{
|
||||
uint i = get_local_id(0) + processed;
|
||||
while (i < BLOCK_COLS)
|
||||
{
|
||||
uchar a0 = src[i];
|
||||
dst[i] = a0;
|
||||
|
||||
i += WSZ;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#else // USE_COPY_1D
|
||||
|
||||
static inline
|
||||
__attribute__((always_inline))
|
||||
void copy_block_2d(
|
||||
__global const uchar* src0,
|
||||
const uint src_offset0,
|
||||
__global uchar* dst0,
|
||||
const uint dst_offset0
|
||||
)
|
||||
{
|
||||
__global const uchar* src = src0 + src_offset0;
|
||||
__global uchar* dst = dst0 + dst_offset0;
|
||||
|
||||
uint i = get_local_id(0) * 4;
|
||||
|
||||
#define BLOCK_COLS_FILL_X4 (((BLOCK_COLS + 3) / 4) * 4)
|
||||
#define BLOCK_SIZE_FILL_X4 (BLOCK_COLS_FILL_X4 * BLOCK_ROWS)
|
||||
|
||||
while (i < BLOCK_SIZE_FILL_X4)
|
||||
{
|
||||
int row = i / BLOCK_COLS_FILL_X4;
|
||||
int col = i % BLOCK_COLS_FILL_X4;
|
||||
|
||||
uint src_offset = row * BLOCK_SRC_STRIDE + col;
|
||||
#if BLOCK_COLS_FILL_X4 == BLOCK_COLS
|
||||
uint dst_offset = i;
|
||||
#else
|
||||
uint dst_offset = row * BLOCK_COLS + col;
|
||||
#endif
|
||||
|
||||
#if BLOCK_COLS_FILL_X4 != BLOCK_COLS
|
||||
if (col <= BLOCK_COLS - 4)
|
||||
#endif
|
||||
{
|
||||
uchar4 a = vload4(0, src + src_offset);
|
||||
vstore4(a, 0, dst + dst_offset);
|
||||
}
|
||||
#if BLOCK_COLS_FILL_X4 != BLOCK_COLS
|
||||
else
|
||||
{
|
||||
/* non-optimized reference code
|
||||
while (col < BLOCK_COLS)
|
||||
{
|
||||
uchar a = src[src_offset];
|
||||
dst[dst_offset] = a;
|
||||
col++;
|
||||
src_offset++;
|
||||
dst_offset++;
|
||||
}
|
||||
*/
|
||||
|
||||
uint4 shift = (uint4)(0, 1, 2, 3);
|
||||
shift = select((uint4)0, shift, col + shift < BLOCK_COLS);
|
||||
|
||||
dst[dst_offset + shift.s0] = src[src_offset + shift.s0];
|
||||
|
||||
#if BLOCK_COLS_FILL_X4 - BLOCK_COLS <= 2
|
||||
dst[dst_offset + shift.s1] = src[src_offset + shift.s1];
|
||||
#endif
|
||||
#if BLOCK_COLS_FILL_X4 - BLOCK_COLS <= 1
|
||||
dst[dst_offset + shift.s2] = src[src_offset + shift.s2];
|
||||
#endif
|
||||
}
|
||||
#endif // BLOCK_COLS_FILL_X4 != BLOCK_COLS
|
||||
i += WSZ * 4;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // USE_COPY_1D
|
||||
|
||||
__kernel void
|
||||
CONCAT(slice_, DIMS)(
|
||||
__global const uchar* src,
|
||||
__global uchar* dst
|
||||
)
|
||||
{
|
||||
uint block_id = get_global_id(1);
|
||||
|
||||
uint dst_offset = block_id * BLOCK_SIZE;
|
||||
|
||||
uint src_offset = 0;
|
||||
|
||||
#define CALC_SRC_INDEX(dim) \
|
||||
{ \
|
||||
uint plane_sz = CONCAT(DST_STEP_, dim) / BLOCK_SIZE; \
|
||||
CONCAT(idx_, dim) = block_id / plane_sz; \
|
||||
block_id = block_id - CONCAT(idx_, dim) * plane_sz; \
|
||||
}
|
||||
#define UPDATE_SRC_OFFSET(dim) \
|
||||
src_offset = mad24((uint)(CONCAT(idx_, dim) + CONCAT(SRC_START_, dim)), (uint)CONCAT(SRC_STEP_, dim), (uint)src_offset);
|
||||
/*
|
||||
if (get_global_id(0) == 0 && get_global_id(1) == 0) \
|
||||
printf("(%d, %d): @%d src_offset=%d idx_dim=%d block_id=%d\n", \
|
||||
get_global_id(0), get_global_id(1), \
|
||||
dim, src_offset, CONCAT(idx_, dim), block_id \
|
||||
);
|
||||
*/
|
||||
|
||||
#if DIMS > 5
|
||||
#error "invalid configuration"
|
||||
#endif
|
||||
#if DIMS > 4
|
||||
uint idx_4 = 0;
|
||||
#if BLOCK_DIMS <= 4
|
||||
CALC_SRC_INDEX(4)
|
||||
#endif
|
||||
UPDATE_SRC_OFFSET(4)
|
||||
#endif
|
||||
#if DIMS > 3
|
||||
uint idx_3 = 0;
|
||||
#if BLOCK_DIMS <= 3
|
||||
CALC_SRC_INDEX(3)
|
||||
#endif
|
||||
UPDATE_SRC_OFFSET(3)
|
||||
#endif
|
||||
#if DIMS > 2
|
||||
uint idx_2 = 0;
|
||||
#if BLOCK_DIMS <= 2
|
||||
CALC_SRC_INDEX(2)
|
||||
#endif
|
||||
UPDATE_SRC_OFFSET(2)
|
||||
#endif
|
||||
#if DIMS > 1
|
||||
uint idx_1 = 0;
|
||||
#if BLOCK_DIMS <= 1
|
||||
CALC_SRC_INDEX(1)
|
||||
#endif
|
||||
UPDATE_SRC_OFFSET(1)
|
||||
#endif
|
||||
#if DIMS > 0
|
||||
uint idx_0 = 0;
|
||||
UPDATE_SRC_OFFSET(0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
if (get_global_id(0) == 0)
|
||||
printf("(%d, %d): src_offset=%d dst_offset=%d\n",
|
||||
get_global_id(0), get_global_id(1),
|
||||
src_offset, dst_offset
|
||||
);
|
||||
*/
|
||||
|
||||
#ifdef USE_COPY_1D
|
||||
copy_block_1d(src, src_offset, dst, dst_offset);
|
||||
#else
|
||||
copy_block_2d(src, src_offset, dst, dst_offset);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -31,7 +31,10 @@ public:
|
||||
|
||||
virtual std::string getInputName(int idx) const CV_OVERRIDE
|
||||
{
|
||||
return node->input(idx);
|
||||
// If operation produces several tensors, they are specified by index
|
||||
// after ':' character. In example, "input:0".
|
||||
std::string name = node->input(idx);
|
||||
return name.substr(0, name.rfind(':'));
|
||||
}
|
||||
|
||||
virtual std::string getType() const CV_OVERRIDE
|
||||
|
||||
@@ -390,6 +390,8 @@ TEST_P(DNNTestNetwork, DenseNet_121)
|
||||
if (target == DNN_TARGET_OPENCL_FP16)
|
||||
{
|
||||
l1 = 2e-2; lInf = 9e-2;
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
lInf = 0.1f;
|
||||
}
|
||||
else if (target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
|
||||
@@ -489,6 +489,11 @@ TEST_P(Test_Caffe_nets, Colorization)
|
||||
{
|
||||
l1 = 0.5; lInf = 11;
|
||||
}
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
{
|
||||
l1 = 0.26; lInf = 6.5;
|
||||
}
|
||||
|
||||
normAssert(out, ref, "", l1, lInf);
|
||||
expectNoFallbacksFromIE(net);
|
||||
}
|
||||
@@ -515,8 +520,8 @@ TEST_P(Test_Caffe_nets, DenseNet_121)
|
||||
float l1 = default_l1, lInf = default_lInf;
|
||||
if (target == DNN_TARGET_OPENCL_FP16)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2019020000)
|
||||
l1 = 0.04; lInf = 0.21;
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019020000)
|
||||
l1 = 0.045; lInf = 0.21;
|
||||
#else
|
||||
l1 = 0.017; lInf = 0.0795;
|
||||
#endif
|
||||
|
||||
@@ -96,9 +96,12 @@ void normAssertDetections(
|
||||
const char *comment /*= ""*/, double confThreshold /*= 0.0*/,
|
||||
double scores_diff /*= 1e-5*/, double boxes_iou_diff /*= 1e-4*/)
|
||||
{
|
||||
ASSERT_FALSE(testClassIds.empty()) << "No detections";
|
||||
std::vector<bool> matchedRefBoxes(refBoxes.size(), false);
|
||||
std::vector<double> refBoxesIoUDiff(refBoxes.size(), 1.0);
|
||||
for (int i = 0; i < testBoxes.size(); ++i)
|
||||
{
|
||||
//cout << "Test[i=" << i << "]: score=" << testScores[i] << " id=" << testClassIds[i] << " box " << testBoxes[i] << endl;
|
||||
double testScore = testScores[i];
|
||||
if (testScore < confThreshold)
|
||||
continue;
|
||||
@@ -115,6 +118,7 @@ void normAssertDetections(
|
||||
double interArea = (testBox & refBoxes[j]).area();
|
||||
double iou = interArea / (testBox.area() + refBoxes[j].area() - interArea);
|
||||
topIoU = std::max(topIoU, iou);
|
||||
refBoxesIoUDiff[j] = std::min(refBoxesIoUDiff[j], 1.0f - iou);
|
||||
if (1.0 - iou < boxes_iou_diff)
|
||||
{
|
||||
matched = true;
|
||||
@@ -137,7 +141,9 @@ void normAssertDetections(
|
||||
if (!matchedRefBoxes[i] && refScores[i] > confThreshold)
|
||||
{
|
||||
std::cout << cv::format("Unmatched reference: class %d score %f box ",
|
||||
refClassIds[i], refScores[i]) << refBoxes[i] << std::endl;
|
||||
refClassIds[i], refScores[i]) << refBoxes[i]
|
||||
<< " IoU diff: " << refBoxesIoUDiff[i]
|
||||
<< std::endl;
|
||||
EXPECT_LE(refScores[i], confThreshold) << comment;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,6 +254,13 @@ public:
|
||||
|
||||
}
|
||||
|
||||
if (cvIsNaN(iouDiff))
|
||||
{
|
||||
if (b == 0)
|
||||
std::cout << "Skip accuracy checks" << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
normAssertDetections(refClassIds[b], refConfidences[b], refBoxes[b], nms_classIds,
|
||||
nms_confidences, nms_boxes, format("batch size %d, sample %d\n", batch_size, b).c_str(), confThreshold, scoreDiff, iouDiff);
|
||||
}
|
||||
@@ -316,6 +323,12 @@ TEST_P(Test_Darknet_nets, YoloVoc)
|
||||
CV_TEST_TAG_LONG
|
||||
);
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000) // nGraph compilation failure
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16);
|
||||
@@ -356,6 +369,12 @@ TEST_P(Test_Darknet_nets, TinyYoloVoc)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_512MB);
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000) // nGraph compilation failure
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 || backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) &&
|
||||
target == DNN_TARGET_MYRIAD && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
@@ -449,7 +468,7 @@ TEST_P(Test_Darknet_nets_async, Accuracy)
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Test_Darknet_nets_async, Combine(
|
||||
Values("yolo-voc", "tiny-yolo-voc", "yolov3", "yolov4"),
|
||||
Values("yolo-voc", "tiny-yolo-voc", "yolov3", "yolov4", "yolov4-tiny"),
|
||||
dnnBackendsAndTargets()
|
||||
));
|
||||
|
||||
@@ -459,6 +478,13 @@ TEST_P(Test_Darknet_nets, YOLOv3)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_LONG, (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_1GB : CV_TEST_TAG_MEMORY_2GB));
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000) // nGraph compilation failure
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
||||
|
||||
@@ -523,6 +549,12 @@ TEST_P(Test_Darknet_nets, YOLOv4)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_LONG, (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_1GB : CV_TEST_TAG_MEMORY_2GB));
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000) // nGraph compilation failure
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (target == DNN_TARGET_MYRIAD) // NC_OUT_OF_MEMORY
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
@@ -587,6 +619,63 @@ TEST_P(Test_Darknet_nets, YOLOv4)
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_nets, YOLOv4_tiny)
|
||||
{
|
||||
applyTestTag(
|
||||
target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB
|
||||
);
|
||||
|
||||
const double confThreshold = 0.5;
|
||||
// batchId, classId, confidence, left, top, right, bottom
|
||||
const int N0 = 2;
|
||||
const int N1 = 3;
|
||||
static const float ref_[/* (N0 + N1) * 7 */] = {
|
||||
0, 7, 0.85935f, 0.593484f, 0.141211f, 0.920356f, 0.291593f,
|
||||
0, 16, 0.795188f, 0.169207f, 0.386886f, 0.423753f, 0.933004f,
|
||||
|
||||
1, 2, 0.996832f, 0.653802f, 0.464573f, 0.815193f, 0.653292f,
|
||||
1, 2, 0.963325f, 0.451151f, 0.458915f, 0.496255f, 0.52241f,
|
||||
1, 0, 0.926244f, 0.194851f, 0.361743f, 0.260277f, 0.632364f,
|
||||
};
|
||||
Mat ref(N0 + N1, 7, CV_32FC1, (void*)ref_);
|
||||
|
||||
double scoreDiff = 0.01f;
|
||||
double iouDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.15 : 0.01f;
|
||||
|
||||
std::string config_file = "yolov4-tiny.cfg";
|
||||
std::string weights_file = "yolov4-tiny.weights";
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (target == DNN_TARGET_MYRIAD) // bad accuracy
|
||||
iouDiff = std::numeric_limits<double>::quiet_NaN();
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_OPENCL)
|
||||
iouDiff = std::numeric_limits<double>::quiet_NaN();
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ||
|
||||
backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) && target == DNN_TARGET_OPENCL_FP16)
|
||||
iouDiff = std::numeric_limits<double>::quiet_NaN();
|
||||
#endif
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 1");
|
||||
testDarknetModel(config_file, weights_file, ref.rowRange(0, N0), scoreDiff, iouDiff, confThreshold);
|
||||
}
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 2");
|
||||
testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff, confThreshold);
|
||||
}
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (target == DNN_TARGET_MYRIAD) // bad accuracy
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ||
|
||||
backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Test_Darknet_nets, dnnBackendsAndTargets());
|
||||
|
||||
@@ -627,6 +716,12 @@ TEST_P(Test_Darknet_layers, reorg)
|
||||
testDarknetLayer("reorg");
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_layers, route)
|
||||
{
|
||||
testDarknetLayer("route");
|
||||
testDarknetLayer("route_multi");
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_layers, maxpool)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2020020000)
|
||||
|
||||
@@ -73,7 +73,8 @@ struct OpenVINOModelTestCaseInfo
|
||||
static const std::map<std::string, OpenVINOModelTestCaseInfo>& getOpenVINOTestModels()
|
||||
{
|
||||
static std::map<std::string, OpenVINOModelTestCaseInfo> g_models {
|
||||
#if INF_ENGINE_RELEASE >= 2018050000
|
||||
#if INF_ENGINE_RELEASE >= 2018050000 && \
|
||||
INF_ENGINE_RELEASE <= 2020999999 // don't use IRv5 models with 2020.1+
|
||||
// layout is defined by open_model_zoo/model_downloader
|
||||
// Downloaded using these parameters for Open Model Zoo downloader (2019R1):
|
||||
// ./downloader.py -o ${OPENCV_DNN_TEST_DATA_PATH}/omz_intel_models --cache_dir ${OPENCV_DNN_TEST_DATA_PATH}/.omz_cache/ \
|
||||
@@ -136,12 +137,6 @@ void runIE(Target target, const std::string& xmlPath, const std::string& binPath
|
||||
{
|
||||
SCOPED_TRACE("runIE");
|
||||
|
||||
CNNNetReader reader;
|
||||
reader.ReadNetwork(xmlPath);
|
||||
reader.ReadWeights(binPath);
|
||||
|
||||
CNNNetwork net = reader.getNetwork();
|
||||
|
||||
std::string device_name;
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GT(2019010000)
|
||||
@@ -150,6 +145,17 @@ void runIE(Target target, const std::string& xmlPath, const std::string& binPath
|
||||
InferenceEnginePluginPtr enginePtr;
|
||||
InferencePlugin plugin;
|
||||
#endif
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GT(2019030000)
|
||||
CNNNetwork net = ie.ReadNetwork(xmlPath, binPath);
|
||||
#else
|
||||
CNNNetReader reader;
|
||||
reader.ReadNetwork(xmlPath);
|
||||
reader.ReadWeights(binPath);
|
||||
|
||||
CNNNetwork net = reader.getNetwork();
|
||||
#endif
|
||||
|
||||
ExecutableNetwork netExec;
|
||||
InferRequest infRequest;
|
||||
|
||||
@@ -290,6 +296,11 @@ TEST_P(DNNTestOpenVINO, models)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if INF_ENGINE_VER_MAJOR_EQ(2020040000)
|
||||
if (targetId == DNN_TARGET_MYRIAD && modelName == "person-detection-retail-0002") // IRv5, OpenVINO 2020.4 regression
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
setInferenceEngineBackendType(CV_DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_API);
|
||||
else if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
|
||||
@@ -364,6 +364,16 @@ TEST_P(Test_Caffe_layers, layer_prelu_fc)
|
||||
// Reference output values are in range [-0.0001, 10.3906]
|
||||
double l1 = (target == DNN_TARGET_MYRIAD) ? 0.005 : 0.0;
|
||||
double lInf = (target == DNN_TARGET_MYRIAD) ? 0.021 : 0.0;
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
|
||||
{
|
||||
l1 = 0.006f; lInf = 0.05f;
|
||||
}
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
{
|
||||
l1 = 0.01f; lInf = 0.05f;
|
||||
}
|
||||
#endif
|
||||
testLayerUsingCaffeModels("layer_prelu_fc", true, false, l1, lInf);
|
||||
}
|
||||
|
||||
@@ -1837,7 +1847,115 @@ TEST_P(Layer_Test_Resize, change_input)
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Layer_Test_Resize, dnnBackendsAndTargets());
|
||||
|
||||
typedef testing::TestWithParam<tuple<Backend, Target> > Layer_Test_Slice;
|
||||
struct Layer_Test_Slice : public testing::TestWithParam<tuple<Backend, Target> >
|
||||
{
|
||||
template<int DIMS>
|
||||
void test_slice(const int* inputShape, const int* begin, const int* end)
|
||||
{
|
||||
int backendId = get<0>(GetParam());
|
||||
int targetId = get<1>(GetParam());
|
||||
|
||||
Mat input(DIMS, inputShape, CV_32FC1, Scalar::all(0));
|
||||
for (int i = 0; i < (int)input.total(); ++i)
|
||||
input.ptr<float>()[i] = (float)i;
|
||||
|
||||
std::vector<Range> range(DIMS);
|
||||
for (int i = 0; i < DIMS; ++i)
|
||||
range[i] = Range(begin[i], end[i]);
|
||||
|
||||
Net net;
|
||||
LayerParams lp;
|
||||
lp.type = "Slice";
|
||||
lp.name = "testLayer";
|
||||
lp.set("begin", DictValue::arrayInt<int*>((int*)&begin[0], DIMS));
|
||||
lp.set("end", DictValue::arrayInt<int*>((int*)&end[0], DIMS));
|
||||
net.addLayerToPrev(lp.name, lp.type, lp);
|
||||
|
||||
{
|
||||
net.setInput(input);
|
||||
net.setPreferableBackend(backendId);
|
||||
net.setPreferableTarget(targetId);
|
||||
Mat out = net.forward();
|
||||
|
||||
EXPECT_GT(cv::norm(out, NORM_INF), 0);
|
||||
normAssert(out, input(range));
|
||||
#if 0
|
||||
cout << input(range).clone().reshape(1, 1) << endl;
|
||||
cout << out.reshape(1, 1) << endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(Layer_Test_Slice, slice_channels_17762)
|
||||
{
|
||||
const int inputShape[4] = {1, 16, 6, 8};
|
||||
const int begin[] = {0, 4, 0, 0};
|
||||
const int end[] = {1, 8, 6, 8};
|
||||
test_slice<4>(inputShape, begin, end);
|
||||
}
|
||||
|
||||
TEST_P(Layer_Test_Slice, slice_channels_with_batch_17762)
|
||||
{
|
||||
const int inputShape[4] = {4, 4, 3, 4};
|
||||
const int begin[] = {0, 1, 0, 0};
|
||||
const int end[] = {4, 3, 3, 4};
|
||||
test_slice<4>(inputShape, begin, end);
|
||||
}
|
||||
|
||||
TEST_P(Layer_Test_Slice, slice_channels_and_batch_17762)
|
||||
{
|
||||
int backend = get<0>(GetParam());
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
|
||||
const int inputShape[4] = {4, 4, 3, 4};
|
||||
const int begin[] = {2, 1, 0, 0};
|
||||
const int end[] = {4, 3, 3, 4};
|
||||
test_slice<4>(inputShape, begin, end);
|
||||
}
|
||||
|
||||
TEST_P(Layer_Test_Slice, slice_rows)
|
||||
{
|
||||
const int inputShape[4] = {1, 2, 6, 4};
|
||||
const int begin[] = {0, 0, 4, 0};
|
||||
const int end[] = {1, 2, 6, 4};
|
||||
test_slice<4>(inputShape, begin, end);
|
||||
}
|
||||
|
||||
TEST_P(Layer_Test_Slice, slice_cols)
|
||||
{
|
||||
const int inputShape[4] = {1, 2, 3, 8};
|
||||
const int begin[] = {0, 0, 0, 4};
|
||||
const int end[] = {1, 2, 3, 8};
|
||||
test_slice<4>(inputShape, begin, end);
|
||||
}
|
||||
|
||||
|
||||
TEST_P(Layer_Test_Slice, slice_complex_1_unaligned)
|
||||
{
|
||||
const int inputShape[4] = {1, 4, 2, 3};
|
||||
const int begin[] = {0, 2, 1, 0};
|
||||
const int end[] = {1, 3, 2, 2};
|
||||
test_slice<4>(inputShape, begin, end);
|
||||
}
|
||||
|
||||
TEST_P(Layer_Test_Slice, slice_complex_2_x4)
|
||||
{
|
||||
const int inputShape[4] = {1, 3, 2, 4};
|
||||
const int begin[] = {0, 2, 1, 0};
|
||||
const int end[] = {1, 3, 2, 2};
|
||||
test_slice<4>(inputShape, begin, end);
|
||||
}
|
||||
|
||||
TEST_P(Layer_Test_Slice, slice_complex_3)
|
||||
{
|
||||
const int inputShape[4] = {1, 6, 4, 8};
|
||||
const int begin[] = {0, 2, 1, 4};
|
||||
const int end[] = {1, 4, 3, 8};
|
||||
test_slice<4>(inputShape, begin, end);
|
||||
}
|
||||
|
||||
TEST_P(Layer_Test_Slice, variable_input_shape)
|
||||
{
|
||||
int backendId = get<0>(GetParam());
|
||||
|
||||
@@ -704,6 +704,13 @@ TEST_P(Test_ONNX_nets, TinyYolov2)
|
||||
// output range: [-11; 8]
|
||||
double l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.017 : default_l1;
|
||||
double lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.14 : default_lInf;
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
{
|
||||
l1 = 0.018f; lInf = 0.16f;
|
||||
}
|
||||
#endif
|
||||
|
||||
testONNXModels("tiny_yolo2", pb, l1, lInf);
|
||||
}
|
||||
|
||||
@@ -781,6 +788,13 @@ TEST_P(Test_ONNX_nets, Emotion_ferplus)
|
||||
l1 = 2.4e-4;
|
||||
lInf = 6e-4;
|
||||
}
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
{
|
||||
l1 = 0.012f; lInf = 0.035f;
|
||||
}
|
||||
#endif
|
||||
|
||||
testONNXModels("emotion_ferplus", pb, l1, lInf);
|
||||
}
|
||||
|
||||
|
||||
@@ -261,6 +261,10 @@ public:
|
||||
@param contrastThreshold The contrast threshold used to filter out weak features in semi-uniform
|
||||
(low-contrast) regions. The larger the threshold, the less features are produced by the detector.
|
||||
|
||||
@note The contrast threshold will be divided by nOctaveLayers when the filtering is applied. When
|
||||
nOctaveLayers is set to default and if you want to use the value used in D. Lowe paper, 0.03, set
|
||||
this argument to 0.09.
|
||||
|
||||
@param edgeThreshold The threshold used to filter out edge-like features. Note that the its meaning
|
||||
is different from the contrastThreshold, i.e. the larger the edgeThreshold, the less features are
|
||||
filtered out (more features are retained).
|
||||
@@ -271,6 +275,8 @@ public:
|
||||
CV_WRAP static Ptr<SIFT> create(int nfeatures = 0, int nOctaveLayers = 3,
|
||||
double contrastThreshold = 0.04, double edgeThreshold = 10,
|
||||
double sigma = 1.6);
|
||||
|
||||
CV_WRAP virtual String getDefaultName() const CV_OVERRIDE;
|
||||
};
|
||||
|
||||
typedef SIFT SiftFeatureDetector;
|
||||
|
||||
@@ -21,7 +21,8 @@ namespace opencv_test
|
||||
ORB_DEFAULT, ORB_1500_13_1, \
|
||||
AKAZE_DEFAULT, AKAZE_DESCRIPTOR_KAZE, \
|
||||
BRISK_DEFAULT, \
|
||||
KAZE_DEFAULT
|
||||
KAZE_DEFAULT, \
|
||||
SIFT_DEFAULT
|
||||
|
||||
#define CV_ENUM_EXPAND(name, ...) CV_ENUM(name, __VA_ARGS__)
|
||||
|
||||
@@ -77,6 +78,8 @@ static inline Ptr<Feature2D> getFeature2D(Feature2DType type)
|
||||
return KAZE::create();
|
||||
case MSER_DEFAULT:
|
||||
return MSER::create();
|
||||
case SIFT_DEFAULT:
|
||||
return SIFT::create();
|
||||
default:
|
||||
return Ptr<Feature2D>();
|
||||
}
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#include "perf_precomp.hpp"
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
typedef perf::TestBaseWithParam<std::string> SIFT_detect;
|
||||
typedef perf::TestBaseWithParam<std::string> SIFT_extract;
|
||||
typedef perf::TestBaseWithParam<std::string> SIFT_full;
|
||||
|
||||
#define SIFT_IMAGES \
|
||||
"cv/detectors_descriptors_evaluation/images_datasets/leuven/img1.png",\
|
||||
"stitching/a3.png"
|
||||
|
||||
PERF_TEST_P_(SIFT_detect, SIFT)
|
||||
{
|
||||
string filename = getDataPath(GetParam());
|
||||
Mat frame = imread(filename, IMREAD_GRAYSCALE);
|
||||
ASSERT_FALSE(frame.empty()) << "Unable to load source image " << filename;
|
||||
|
||||
Mat mask;
|
||||
declare.in(frame).time(90);
|
||||
Ptr<SIFT> detector = SIFT::create();
|
||||
vector<KeyPoint> points;
|
||||
|
||||
PERF_SAMPLE_BEGIN();
|
||||
detector->detect(frame, points, mask);
|
||||
PERF_SAMPLE_END();
|
||||
|
||||
SANITY_CHECK_NOTHING();
|
||||
}
|
||||
|
||||
PERF_TEST_P_(SIFT_extract, SIFT)
|
||||
{
|
||||
string filename = getDataPath(GetParam());
|
||||
Mat frame = imread(filename, IMREAD_GRAYSCALE);
|
||||
ASSERT_FALSE(frame.empty()) << "Unable to load source image " << filename;
|
||||
|
||||
Mat mask;
|
||||
declare.in(frame).time(90);
|
||||
|
||||
Ptr<SIFT> detector = SIFT::create();
|
||||
vector<KeyPoint> points;
|
||||
Mat descriptors;
|
||||
detector->detect(frame, points, mask);
|
||||
|
||||
PERF_SAMPLE_BEGIN();
|
||||
detector->compute(frame, points, descriptors);
|
||||
PERF_SAMPLE_END();
|
||||
|
||||
SANITY_CHECK_NOTHING();
|
||||
}
|
||||
|
||||
PERF_TEST_P_(SIFT_full, SIFT)
|
||||
{
|
||||
string filename = getDataPath(GetParam());
|
||||
Mat frame = imread(filename, IMREAD_GRAYSCALE);
|
||||
ASSERT_FALSE(frame.empty()) << "Unable to load source image " << filename;
|
||||
|
||||
Mat mask;
|
||||
declare.in(frame).time(90);
|
||||
Ptr<SIFT> detector = SIFT::create();
|
||||
vector<KeyPoint> points;
|
||||
Mat descriptors;
|
||||
|
||||
PERF_SAMPLE_BEGIN();
|
||||
detector->detectAndCompute(frame, mask, points, descriptors, false);
|
||||
PERF_SAMPLE_END();
|
||||
|
||||
SANITY_CHECK_NOTHING();
|
||||
}
|
||||
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/*nothing*/, SIFT_detect,
|
||||
testing::Values(SIFT_IMAGES)
|
||||
);
|
||||
INSTANTIATE_TEST_CASE_P(/*nothing*/, SIFT_extract,
|
||||
testing::Values(SIFT_IMAGES)
|
||||
);
|
||||
INSTANTIATE_TEST_CASE_P(/*nothing*/, SIFT_full,
|
||||
testing::Values(SIFT_IMAGES)
|
||||
);
|
||||
|
||||
}} // namespace
|
||||
@@ -257,7 +257,7 @@ void SimpleBlobDetectorImpl::findBlobs(InputArray _image, InputArray _binaryImag
|
||||
{
|
||||
std::vector < Point > hull;
|
||||
convexHull(contours[contourIdx], hull);
|
||||
double area = contourArea(contours[contourIdx]);
|
||||
double area = moms.m00;
|
||||
double hullArea = contourArea(hull);
|
||||
if (fabs(hullArea) < DBL_EPSILON)
|
||||
continue;
|
||||
|
||||
@@ -622,15 +622,20 @@ void DescriptorMatcher::checkMasks( InputArrayOfArrays _masks, int queryDescript
|
||||
if( isMaskSupported() && !masks.empty() )
|
||||
{
|
||||
// Check masks
|
||||
size_t imageCount = std::max(trainDescCollection.size(), utrainDescCollection.size() );
|
||||
const size_t imageCount = std::max(trainDescCollection.size(), utrainDescCollection.size() );
|
||||
CV_Assert( masks.size() == imageCount );
|
||||
for( size_t i = 0; i < imageCount; i++ )
|
||||
{
|
||||
if( !masks[i].empty() && (!trainDescCollection[i].empty() || !utrainDescCollection[i].empty() ) )
|
||||
if (masks[i].empty())
|
||||
continue;
|
||||
const bool hasTrainDesc = !trainDescCollection.empty() && !trainDescCollection[i].empty();
|
||||
const bool hasUTrainDesc = !utrainDescCollection.empty() && !utrainDescCollection[i].empty();
|
||||
if (hasTrainDesc || hasUTrainDesc)
|
||||
{
|
||||
int rows = trainDescCollection[i].empty() ? utrainDescCollection[i].rows : trainDescCollection[i].rows;
|
||||
CV_Assert( masks[i].rows == queryDescriptorsCount &&
|
||||
masks[i].cols == rows && masks[i].type() == CV_8UC1);
|
||||
const int rows = hasTrainDesc ? trainDescCollection[i].rows : utrainDescCollection[i].rows;
|
||||
CV_Assert(masks[i].type() == CV_8UC1
|
||||
&& masks[i].rows == queryDescriptorsCount
|
||||
&& masks[i].cols == rows);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,6 +126,11 @@ Ptr<SIFT> SIFT::create( int _nfeatures, int _nOctaveLayers,
|
||||
return makePtr<SIFT_Impl>(_nfeatures, _nOctaveLayers, _contrastThreshold, _edgeThreshold, _sigma);
|
||||
}
|
||||
|
||||
String SIFT::getDefaultName() const
|
||||
{
|
||||
return (Feature2D::getDefaultName() + ".SIFT");
|
||||
}
|
||||
|
||||
static inline void
|
||||
unpackOctave(const KeyPoint& kpt, int& octave, int& layer, float& scale)
|
||||
{
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
|
||||
#include <opencv2/core/hal/hal.hpp>
|
||||
#include "opencv2/core/hal/intrin.hpp"
|
||||
#include <opencv2/core/utils/buffer_area.private.hpp>
|
||||
|
||||
namespace cv {
|
||||
|
||||
@@ -167,9 +168,17 @@ float calcOrientationHist(
|
||||
int i, j, k, len = (radius*2+1)*(radius*2+1);
|
||||
|
||||
float expf_scale = -1.f/(2.f * sigma * sigma);
|
||||
AutoBuffer<float> buf(len*4 + n+4);
|
||||
float *X = buf.data(), *Y = X + len, *Mag = X, *Ori = Y + len, *W = Ori + len;
|
||||
float* temphist = W + len + 2;
|
||||
|
||||
cv::utils::BufferArea area;
|
||||
float *X = 0, *Y = 0, *Mag, *Ori = 0, *W = 0, *temphist = 0;
|
||||
area.allocate(X, len, CV_SIMD_WIDTH);
|
||||
area.allocate(Y, len, CV_SIMD_WIDTH);
|
||||
area.allocate(Ori, len, CV_SIMD_WIDTH);
|
||||
area.allocate(W, len, CV_SIMD_WIDTH);
|
||||
area.allocate(temphist, n+4, CV_SIMD_WIDTH);
|
||||
area.commit();
|
||||
temphist += 2;
|
||||
Mag = X;
|
||||
|
||||
for( i = 0; i < n; i++ )
|
||||
temphist[i] = 0.f;
|
||||
@@ -201,32 +210,29 @@ float calcOrientationHist(
|
||||
cv::hal::magnitude32f(X, Y, Mag, len);
|
||||
|
||||
k = 0;
|
||||
#if CV_AVX2
|
||||
#if CV_SIMD
|
||||
const int vecsize = v_float32::nlanes;
|
||||
v_float32 nd360 = vx_setall_f32(n/360.f);
|
||||
v_int32 __n = vx_setall_s32(n);
|
||||
int CV_DECL_ALIGNED(CV_SIMD_WIDTH) bin_buf[vecsize];
|
||||
float CV_DECL_ALIGNED(CV_SIMD_WIDTH) w_mul_mag_buf[vecsize];
|
||||
|
||||
for( ; k <= len - vecsize; k += vecsize )
|
||||
{
|
||||
__m256 __nd360 = _mm256_set1_ps(n/360.f);
|
||||
__m256i __n = _mm256_set1_epi32(n);
|
||||
int CV_DECL_ALIGNED(32) bin_buf[8];
|
||||
float CV_DECL_ALIGNED(32) w_mul_mag_buf[8];
|
||||
for ( ; k <= len - 8; k+=8 )
|
||||
v_float32 w = vx_load_aligned( W + k );
|
||||
v_float32 mag = vx_load_aligned( Mag + k );
|
||||
v_float32 ori = vx_load_aligned( Ori + k );
|
||||
v_int32 bin = v_round( nd360 * ori );
|
||||
|
||||
bin = v_select(bin >= __n, bin - __n, bin);
|
||||
bin = v_select(bin < vx_setzero_s32(), bin + __n, bin);
|
||||
|
||||
w = w * mag;
|
||||
v_store_aligned(bin_buf, bin);
|
||||
v_store_aligned(w_mul_mag_buf, w);
|
||||
for(int vi = 0; vi < vecsize; vi++)
|
||||
{
|
||||
__m256i __bin = _mm256_cvtps_epi32(_mm256_mul_ps(__nd360, _mm256_loadu_ps(&Ori[k])));
|
||||
|
||||
__bin = _mm256_sub_epi32(__bin, _mm256_andnot_si256(_mm256_cmpgt_epi32(__n, __bin), __n));
|
||||
__bin = _mm256_add_epi32(__bin, _mm256_and_si256(__n, _mm256_cmpgt_epi32(_mm256_setzero_si256(), __bin)));
|
||||
|
||||
__m256 __w_mul_mag = _mm256_mul_ps(_mm256_loadu_ps(&W[k]), _mm256_loadu_ps(&Mag[k]));
|
||||
|
||||
_mm256_store_si256((__m256i *) bin_buf, __bin);
|
||||
_mm256_store_ps(w_mul_mag_buf, __w_mul_mag);
|
||||
|
||||
temphist[bin_buf[0]] += w_mul_mag_buf[0];
|
||||
temphist[bin_buf[1]] += w_mul_mag_buf[1];
|
||||
temphist[bin_buf[2]] += w_mul_mag_buf[2];
|
||||
temphist[bin_buf[3]] += w_mul_mag_buf[3];
|
||||
temphist[bin_buf[4]] += w_mul_mag_buf[4];
|
||||
temphist[bin_buf[5]] += w_mul_mag_buf[5];
|
||||
temphist[bin_buf[6]] += w_mul_mag_buf[6];
|
||||
temphist[bin_buf[7]] += w_mul_mag_buf[7];
|
||||
temphist[bin_buf[vi]] += w_mul_mag_buf[vi];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -247,34 +253,20 @@ float calcOrientationHist(
|
||||
temphist[n+1] = temphist[1];
|
||||
|
||||
i = 0;
|
||||
#if CV_AVX2
|
||||
#if CV_SIMD
|
||||
v_float32 d_1_16 = vx_setall_f32(1.f/16.f);
|
||||
v_float32 d_4_16 = vx_setall_f32(4.f/16.f);
|
||||
v_float32 d_6_16 = vx_setall_f32(6.f/16.f);
|
||||
for( ; i <= n - v_float32::nlanes; i += v_float32::nlanes )
|
||||
{
|
||||
__m256 __d_1_16 = _mm256_set1_ps(1.f/16.f);
|
||||
__m256 __d_4_16 = _mm256_set1_ps(4.f/16.f);
|
||||
__m256 __d_6_16 = _mm256_set1_ps(6.f/16.f);
|
||||
for( ; i <= n - 8; i+=8 )
|
||||
{
|
||||
#if CV_FMA3
|
||||
__m256 __hist = _mm256_fmadd_ps(
|
||||
_mm256_add_ps(_mm256_loadu_ps(&temphist[i-2]), _mm256_loadu_ps(&temphist[i+2])),
|
||||
__d_1_16,
|
||||
_mm256_fmadd_ps(
|
||||
_mm256_add_ps(_mm256_loadu_ps(&temphist[i-1]), _mm256_loadu_ps(&temphist[i+1])),
|
||||
__d_4_16,
|
||||
_mm256_mul_ps(_mm256_loadu_ps(&temphist[i]), __d_6_16)));
|
||||
#else
|
||||
__m256 __hist = _mm256_add_ps(
|
||||
_mm256_mul_ps(
|
||||
_mm256_add_ps(_mm256_loadu_ps(&temphist[i-2]), _mm256_loadu_ps(&temphist[i+2])),
|
||||
__d_1_16),
|
||||
_mm256_add_ps(
|
||||
_mm256_mul_ps(
|
||||
_mm256_add_ps(_mm256_loadu_ps(&temphist[i-1]), _mm256_loadu_ps(&temphist[i+1])),
|
||||
__d_4_16),
|
||||
_mm256_mul_ps(_mm256_loadu_ps(&temphist[i]), __d_6_16)));
|
||||
#endif
|
||||
_mm256_storeu_ps(&hist[i], __hist);
|
||||
}
|
||||
v_float32 tn2 = vx_load_aligned(temphist + i-2);
|
||||
v_float32 tn1 = vx_load(temphist + i-1);
|
||||
v_float32 t0 = vx_load(temphist + i);
|
||||
v_float32 t1 = vx_load(temphist + i+1);
|
||||
v_float32 t2 = vx_load(temphist + i+2);
|
||||
v_float32 _hist = v_fma(tn2 + t2, d_1_16,
|
||||
v_fma(tn1 + t1, d_4_16, t0 * d_6_16));
|
||||
v_store(hist + i, _hist);
|
||||
}
|
||||
#endif
|
||||
for( ; i < n; i++ )
|
||||
@@ -623,91 +615,65 @@ void calcSIFTDescriptor(
|
||||
cv::hal::exp32f(W, W, len);
|
||||
|
||||
k = 0;
|
||||
#if CV_AVX2
|
||||
#if CV_SIMD
|
||||
{
|
||||
int CV_DECL_ALIGNED(32) idx_buf[8];
|
||||
float CV_DECL_ALIGNED(32) rco_buf[64];
|
||||
const __m256 __ori = _mm256_set1_ps(ori);
|
||||
const __m256 __bins_per_rad = _mm256_set1_ps(bins_per_rad);
|
||||
const __m256i __n = _mm256_set1_epi32(n);
|
||||
for( ; k <= len - 8; k+=8 )
|
||||
const int vecsize = v_float32::nlanes;
|
||||
int CV_DECL_ALIGNED(CV_SIMD_WIDTH) idx_buf[vecsize];
|
||||
float CV_DECL_ALIGNED(CV_SIMD_WIDTH) rco_buf[8*vecsize];
|
||||
const v_float32 __ori = vx_setall_f32(ori);
|
||||
const v_float32 __bins_per_rad = vx_setall_f32(bins_per_rad);
|
||||
const v_int32 __n = vx_setall_s32(n);
|
||||
const v_int32 __1 = vx_setall_s32(1);
|
||||
const v_int32 __d_plus_2 = vx_setall_s32(d+2);
|
||||
const v_int32 __n_plus_2 = vx_setall_s32(n+2);
|
||||
for( ; k <= len - vecsize; k += vecsize )
|
||||
{
|
||||
__m256 __rbin = _mm256_loadu_ps(&RBin[k]);
|
||||
__m256 __cbin = _mm256_loadu_ps(&CBin[k]);
|
||||
__m256 __obin = _mm256_mul_ps(_mm256_sub_ps(_mm256_loadu_ps(&Ori[k]), __ori), __bins_per_rad);
|
||||
__m256 __mag = _mm256_mul_ps(_mm256_loadu_ps(&Mag[k]), _mm256_loadu_ps(&W[k]));
|
||||
v_float32 rbin = vx_load(RBin + k);
|
||||
v_float32 cbin = vx_load(CBin + k);
|
||||
v_float32 obin = (vx_load(Ori + k) - __ori) * __bins_per_rad;
|
||||
v_float32 mag = vx_load(Mag + k) * vx_load(W + k);
|
||||
|
||||
__m256 __r0 = _mm256_floor_ps(__rbin);
|
||||
__rbin = _mm256_sub_ps(__rbin, __r0);
|
||||
__m256 __c0 = _mm256_floor_ps(__cbin);
|
||||
__cbin = _mm256_sub_ps(__cbin, __c0);
|
||||
__m256 __o0 = _mm256_floor_ps(__obin);
|
||||
__obin = _mm256_sub_ps(__obin, __o0);
|
||||
v_int32 r0 = v_floor(rbin);
|
||||
v_int32 c0 = v_floor(cbin);
|
||||
v_int32 o0 = v_floor(obin);
|
||||
rbin -= v_cvt_f32(r0);
|
||||
cbin -= v_cvt_f32(c0);
|
||||
obin -= v_cvt_f32(o0);
|
||||
|
||||
__m256i __o0i = _mm256_cvtps_epi32(__o0);
|
||||
__o0i = _mm256_add_epi32(__o0i, _mm256_and_si256(__n, _mm256_cmpgt_epi32(_mm256_setzero_si256(), __o0i)));
|
||||
__o0i = _mm256_sub_epi32(__o0i, _mm256_andnot_si256(_mm256_cmpgt_epi32(__n, __o0i), __n));
|
||||
o0 = v_select(o0 < vx_setzero_s32(), o0 + __n, o0);
|
||||
o0 = v_select(o0 >= __n, o0 - __n, o0);
|
||||
|
||||
__m256 __v_r1 = _mm256_mul_ps(__mag, __rbin);
|
||||
__m256 __v_r0 = _mm256_sub_ps(__mag, __v_r1);
|
||||
v_float32 v_r1 = mag*rbin, v_r0 = mag - v_r1;
|
||||
v_float32 v_rc11 = v_r1*cbin, v_rc10 = v_r1 - v_rc11;
|
||||
v_float32 v_rc01 = v_r0*cbin, v_rc00 = v_r0 - v_rc01;
|
||||
v_float32 v_rco111 = v_rc11*obin, v_rco110 = v_rc11 - v_rco111;
|
||||
v_float32 v_rco101 = v_rc10*obin, v_rco100 = v_rc10 - v_rco101;
|
||||
v_float32 v_rco011 = v_rc01*obin, v_rco010 = v_rc01 - v_rco011;
|
||||
v_float32 v_rco001 = v_rc00*obin, v_rco000 = v_rc00 - v_rco001;
|
||||
|
||||
__m256 __v_rc11 = _mm256_mul_ps(__v_r1, __cbin);
|
||||
__m256 __v_rc10 = _mm256_sub_ps(__v_r1, __v_rc11);
|
||||
v_int32 idx = v_muladd(v_muladd(r0+__1, __d_plus_2, c0+__1), __n_plus_2, o0);
|
||||
v_store_aligned(idx_buf, idx);
|
||||
|
||||
__m256 __v_rc01 = _mm256_mul_ps(__v_r0, __cbin);
|
||||
__m256 __v_rc00 = _mm256_sub_ps(__v_r0, __v_rc01);
|
||||
v_store_aligned(rco_buf, v_rco000);
|
||||
v_store_aligned(rco_buf+vecsize, v_rco001);
|
||||
v_store_aligned(rco_buf+vecsize*2, v_rco010);
|
||||
v_store_aligned(rco_buf+vecsize*3, v_rco011);
|
||||
v_store_aligned(rco_buf+vecsize*4, v_rco100);
|
||||
v_store_aligned(rco_buf+vecsize*5, v_rco101);
|
||||
v_store_aligned(rco_buf+vecsize*6, v_rco110);
|
||||
v_store_aligned(rco_buf+vecsize*7, v_rco111);
|
||||
|
||||
__m256 __v_rco111 = _mm256_mul_ps(__v_rc11, __obin);
|
||||
__m256 __v_rco110 = _mm256_sub_ps(__v_rc11, __v_rco111);
|
||||
|
||||
__m256 __v_rco101 = _mm256_mul_ps(__v_rc10, __obin);
|
||||
__m256 __v_rco100 = _mm256_sub_ps(__v_rc10, __v_rco101);
|
||||
|
||||
__m256 __v_rco011 = _mm256_mul_ps(__v_rc01, __obin);
|
||||
__m256 __v_rco010 = _mm256_sub_ps(__v_rc01, __v_rco011);
|
||||
|
||||
__m256 __v_rco001 = _mm256_mul_ps(__v_rc00, __obin);
|
||||
__m256 __v_rco000 = _mm256_sub_ps(__v_rc00, __v_rco001);
|
||||
|
||||
__m256i __one = _mm256_set1_epi32(1);
|
||||
__m256i __idx = _mm256_add_epi32(
|
||||
_mm256_mullo_epi32(
|
||||
_mm256_add_epi32(
|
||||
_mm256_mullo_epi32(_mm256_add_epi32(_mm256_cvtps_epi32(__r0), __one), _mm256_set1_epi32(d + 2)),
|
||||
_mm256_add_epi32(_mm256_cvtps_epi32(__c0), __one)),
|
||||
_mm256_set1_epi32(n + 2)),
|
||||
__o0i);
|
||||
|
||||
_mm256_store_si256((__m256i *)idx_buf, __idx);
|
||||
|
||||
_mm256_store_ps(&(rco_buf[0]), __v_rco000);
|
||||
_mm256_store_ps(&(rco_buf[8]), __v_rco001);
|
||||
_mm256_store_ps(&(rco_buf[16]), __v_rco010);
|
||||
_mm256_store_ps(&(rco_buf[24]), __v_rco011);
|
||||
_mm256_store_ps(&(rco_buf[32]), __v_rco100);
|
||||
_mm256_store_ps(&(rco_buf[40]), __v_rco101);
|
||||
_mm256_store_ps(&(rco_buf[48]), __v_rco110);
|
||||
_mm256_store_ps(&(rco_buf[56]), __v_rco111);
|
||||
#define HIST_SUM_HELPER(id) \
|
||||
hist[idx_buf[(id)]] += rco_buf[(id)]; \
|
||||
hist[idx_buf[(id)]+1] += rco_buf[8 + (id)]; \
|
||||
hist[idx_buf[(id)]+(n+2)] += rco_buf[16 + (id)]; \
|
||||
hist[idx_buf[(id)]+(n+3)] += rco_buf[24 + (id)]; \
|
||||
hist[idx_buf[(id)]+(d+2)*(n+2)] += rco_buf[32 + (id)]; \
|
||||
hist[idx_buf[(id)]+(d+2)*(n+2)+1] += rco_buf[40 + (id)]; \
|
||||
hist[idx_buf[(id)]+(d+3)*(n+2)] += rco_buf[48 + (id)]; \
|
||||
hist[idx_buf[(id)]+(d+3)*(n+2)+1] += rco_buf[56 + (id)];
|
||||
|
||||
HIST_SUM_HELPER(0);
|
||||
HIST_SUM_HELPER(1);
|
||||
HIST_SUM_HELPER(2);
|
||||
HIST_SUM_HELPER(3);
|
||||
HIST_SUM_HELPER(4);
|
||||
HIST_SUM_HELPER(5);
|
||||
HIST_SUM_HELPER(6);
|
||||
HIST_SUM_HELPER(7);
|
||||
|
||||
#undef HIST_SUM_HELPER
|
||||
for(int id = 0; id < vecsize; id++)
|
||||
{
|
||||
hist[idx_buf[id]] += rco_buf[id];
|
||||
hist[idx_buf[id]+1] += rco_buf[vecsize + id];
|
||||
hist[idx_buf[id]+(n+2)] += rco_buf[2*vecsize + id];
|
||||
hist[idx_buf[id]+(n+3)] += rco_buf[3*vecsize + id];
|
||||
hist[idx_buf[id]+(d+2)*(n+2)] += rco_buf[4*vecsize + id];
|
||||
hist[idx_buf[id]+(d+2)*(n+2)+1] += rco_buf[5*vecsize + id];
|
||||
hist[idx_buf[id]+(d+3)*(n+2)] += rco_buf[6*vecsize + id];
|
||||
hist[idx_buf[id]+(d+3)*(n+2)+1] += rco_buf[7*vecsize + id];
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -766,23 +732,16 @@ void calcSIFTDescriptor(
|
||||
float nrm2 = 0;
|
||||
len = d*d*n;
|
||||
k = 0;
|
||||
#if CV_AVX2
|
||||
#if CV_SIMD
|
||||
{
|
||||
float CV_DECL_ALIGNED(32) nrm2_buf[8];
|
||||
__m256 __nrm2 = _mm256_setzero_ps();
|
||||
__m256 __dst;
|
||||
for( ; k <= len - 8; k += 8 )
|
||||
v_float32 __nrm2 = vx_setzero_f32();
|
||||
v_float32 __dst;
|
||||
for( ; k <= len - v_float32::nlanes; k += v_float32::nlanes )
|
||||
{
|
||||
__dst = _mm256_loadu_ps(&dst[k]);
|
||||
#if CV_FMA3
|
||||
__nrm2 = _mm256_fmadd_ps(__dst, __dst, __nrm2);
|
||||
#else
|
||||
__nrm2 = _mm256_add_ps(__nrm2, _mm256_mul_ps(__dst, __dst));
|
||||
#endif
|
||||
__dst = vx_load(dst + k);
|
||||
__nrm2 = v_fma(__dst, __dst, __nrm2);
|
||||
}
|
||||
_mm256_store_ps(nrm2_buf, __nrm2);
|
||||
nrm2 = nrm2_buf[0] + nrm2_buf[1] + nrm2_buf[2] + nrm2_buf[3] +
|
||||
nrm2_buf[4] + nrm2_buf[5] + nrm2_buf[6] + nrm2_buf[7];
|
||||
nrm2 = (float)v_reduce_sum(__nrm2);
|
||||
}
|
||||
#endif
|
||||
for( ; k < len; k++ )
|
||||
@@ -795,7 +754,7 @@ void calcSIFTDescriptor(
|
||||
// This code cannot be enabled because it sums nrm2 in a different order,
|
||||
// thus producing slightly different results
|
||||
{
|
||||
float CV_DECL_ALIGNED(32) nrm2_buf[8];
|
||||
float CV_DECL_ALIGNED(CV_SIMD_WIDTH) nrm2_buf[8];
|
||||
__m256 __dst;
|
||||
__m256 __nrm2 = _mm256_setzero_ps();
|
||||
__m256 __thr = _mm256_set1_ps(thr);
|
||||
@@ -825,17 +784,17 @@ void calcSIFTDescriptor(
|
||||
|
||||
#if 1
|
||||
k = 0;
|
||||
#if CV_AVX2
|
||||
#if CV_SIMD
|
||||
{
|
||||
__m256 __dst;
|
||||
__m256 __min = _mm256_setzero_ps();
|
||||
__m256 __max = _mm256_set1_ps(255.0f); // max of uchar
|
||||
__m256 __nrm2 = _mm256_set1_ps(nrm2);
|
||||
for( k = 0; k <= len - 8; k+=8 )
|
||||
v_float32 __dst;
|
||||
v_float32 __min = vx_setzero_f32();
|
||||
v_float32 __max = vx_setall_f32(255.0f); // max of uchar
|
||||
v_float32 __nrm2 = vx_setall_f32(nrm2);
|
||||
for( k = 0; k <= len - v_float32::nlanes; k += v_float32::nlanes )
|
||||
{
|
||||
__dst = _mm256_loadu_ps(&dst[k]);
|
||||
__dst = _mm256_min_ps(_mm256_max_ps(_mm256_round_ps(_mm256_mul_ps(__dst, __nrm2), _MM_FROUND_TO_NEAREST_INT |_MM_FROUND_NO_EXC), __min), __max);
|
||||
_mm256_storeu_ps(&dst[k], __dst);
|
||||
__dst = vx_load(dst + k);
|
||||
__dst = v_min(v_max(v_cvt_f32(v_round(__dst * __nrm2)), __min), __max);
|
||||
v_store(dst + k, __dst);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -15,6 +15,26 @@ const static std::string IMAGE_TSUKUBA = "features2d/tsukuba.png";
|
||||
const static std::string IMAGE_BIKES = "detectors_descriptors_evaluation/images_datasets/bikes/img1.png";
|
||||
#define Value(...) Values(String_FeatureDetector_DescriptorExtractor_Float_t(__VA_ARGS__))
|
||||
|
||||
static
|
||||
void SetSuitableSIFTOctave(vector<KeyPoint>& keypoints,
|
||||
int firstOctave = -1, int nOctaveLayers = 3, double sigma = 1.6)
|
||||
{
|
||||
for (size_t i = 0; i < keypoints.size(); i++ )
|
||||
{
|
||||
int octv, layer;
|
||||
KeyPoint& kpt = keypoints[i];
|
||||
double octv_layer = std::log(kpt.size / sigma) / std::log(2.) - 1;
|
||||
octv = cvFloor(octv_layer);
|
||||
layer = cvRound( (octv_layer - octv) * nOctaveLayers );
|
||||
if (octv < firstOctave)
|
||||
{
|
||||
octv = firstOctave;
|
||||
layer = 0;
|
||||
}
|
||||
kpt.octave = (layer << 8) | (octv & 255);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void rotateKeyPoints(const vector<KeyPoint>& src, const Mat& H, float angle, vector<KeyPoint>& dst)
|
||||
{
|
||||
@@ -132,6 +152,10 @@ TEST_P(DescriptorScaleInvariance, scale)
|
||||
|
||||
vector<KeyPoint> keypoints1;
|
||||
scaleKeyPoints(keypoints0, keypoints1, 1.0f/scale);
|
||||
if (featureDetector->getDefaultName() == "Feature2D.SIFT")
|
||||
{
|
||||
SetSuitableSIFTOctave(keypoints1);
|
||||
}
|
||||
Mat descriptors1;
|
||||
descriptorExtractor->compute(image1, keypoints1, descriptors1);
|
||||
|
||||
@@ -186,9 +210,8 @@ INSTANTIATE_TEST_CASE_P(AKAZE_DESCRIPTOR_KAZE, DescriptorRotationInvariance,
|
||||
* Descriptor's scale invariance check
|
||||
*/
|
||||
|
||||
// TODO: Expected: (descInliersRatio) >= (minInliersRatio), actual: 0.330378 vs 0.78
|
||||
INSTANTIATE_TEST_CASE_P(DISABLED_SIFT, DescriptorScaleInvariance,
|
||||
Value(IMAGE_BIKES, SIFT::create(), SIFT::create(), 0.78f));
|
||||
INSTANTIATE_TEST_CASE_P(SIFT, DescriptorScaleInvariance,
|
||||
Value(IMAGE_BIKES, SIFT::create(0, 3, 0.09), SIFT::create(0, 3, 0.09), 0.78f));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(AKAZE, DescriptorScaleInvariance,
|
||||
Value(IMAGE_BIKES, AKAZE::create(), AKAZE::create(), 0.6f));
|
||||
|
||||
@@ -29,7 +29,6 @@ void matchKeyPoints(const vector<KeyPoint>& keypoints0, const Mat& H,
|
||||
perspectiveTransform(Mat(points0), points0t, H);
|
||||
|
||||
matches.clear();
|
||||
vector<uchar> usedMask(keypoints1.size(), 0);
|
||||
for(int i0 = 0; i0 < static_cast<int>(keypoints0.size()); i0++)
|
||||
{
|
||||
int nearestPointIndex = -1;
|
||||
@@ -37,8 +36,6 @@ void matchKeyPoints(const vector<KeyPoint>& keypoints0, const Mat& H,
|
||||
const float r0 = 0.5f * keypoints0[i0].size;
|
||||
for(size_t i1 = 0; i1 < keypoints1.size(); i1++)
|
||||
{
|
||||
if(nearestPointIndex >= 0 && usedMask[i1])
|
||||
continue;
|
||||
|
||||
float r1 = 0.5f * keypoints1[i1].size;
|
||||
float intersectRatio = calcIntersectRatio(points0t.at<Point2f>(i0), r0,
|
||||
@@ -51,8 +48,6 @@ void matchKeyPoints(const vector<KeyPoint>& keypoints0, const Mat& H,
|
||||
}
|
||||
|
||||
matches.push_back(DMatch(i0, nearestPointIndex, maxIntersectRatio));
|
||||
if(nearestPointIndex >= 0)
|
||||
usedMask[nearestPointIndex] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,9 +234,8 @@ INSTANTIATE_TEST_CASE_P(AKAZE_DESCRIPTOR_KAZE, DetectorRotationInvariance,
|
||||
* Detector's scale invariance check
|
||||
*/
|
||||
|
||||
// TODO: Expected: (keyPointMatchesRatio) >= (minKeyPointMatchesRatio), actual: 0.596752 vs 0.69
|
||||
INSTANTIATE_TEST_CASE_P(DISABLED_SIFT, DetectorScaleInvariance,
|
||||
Value(IMAGE_BIKES, SIFT::create(), 0.69f, 0.98f));
|
||||
INSTANTIATE_TEST_CASE_P(SIFT, DetectorScaleInvariance,
|
||||
Value(IMAGE_BIKES, SIFT::create(0, 3, 0.09), 0.69f, 0.98f));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(BRISK, DetectorScaleInvariance,
|
||||
Value(IMAGE_BIKES, BRISK::create(), 0.08f, 0.49f));
|
||||
|
||||
@@ -565,7 +565,6 @@ TEST(Features2d_DMatch, issue_11855)
|
||||
1, 1, 1);
|
||||
Mat targets = (Mat_<uchar>(2, 3) << 1, 1, 1,
|
||||
0, 0, 0);
|
||||
|
||||
Ptr<BFMatcher> bf = BFMatcher::create(NORM_HAMMING, true);
|
||||
vector<vector<DMatch> > match;
|
||||
bf->knnMatch(sources, targets, match, 1, noArray(), true);
|
||||
@@ -577,4 +576,18 @@ TEST(Features2d_DMatch, issue_11855)
|
||||
EXPECT_EQ(0.0f, match[0][0].distance);
|
||||
}
|
||||
|
||||
TEST(Features2d_DMatch, issue_17771)
|
||||
{
|
||||
Mat sources = (Mat_<uchar>(2, 3) << 1, 1, 0,
|
||||
1, 1, 1);
|
||||
Mat targets = (Mat_<uchar>(2, 3) << 1, 1, 1,
|
||||
0, 0, 0);
|
||||
UMat usources = sources.getUMat(ACCESS_READ);
|
||||
UMat utargets = targets.getUMat(ACCESS_READ);
|
||||
vector<vector<DMatch> > match;
|
||||
Ptr<BFMatcher> ubf = BFMatcher::create(NORM_HAMMING);
|
||||
Mat mask = (Mat_<uchar>(2, 2) << 1, 0, 0, 1);
|
||||
EXPECT_NO_THROW(ubf->knnMatch(usources, utargets, match, 1, mask, true));
|
||||
}
|
||||
|
||||
}} // namespace
|
||||
|
||||
@@ -536,7 +536,7 @@ private:
|
||||
@param features The points to be clustered. The matrix must have elements of type
|
||||
Distance::ElementType.
|
||||
@param centers The centers of the clusters obtained. The matrix must have type
|
||||
Distance::ResultType. The number of rows in this matrix represents the number of clusters desired,
|
||||
Distance::CentersType. The number of rows in this matrix represents the number of clusters desired,
|
||||
however, because of the way the cut in the hierarchical tree is chosen, the number of clusters
|
||||
computed will be the highest number of the form (branching-1)\*k+1 that's lower than the number of
|
||||
clusters desired, where branching is the tree's branching factor (see description of the
|
||||
@@ -553,15 +553,15 @@ int hierarchicalClustering(const Mat& features, Mat& centers, const ::cvflann::K
|
||||
Distance d = Distance())
|
||||
{
|
||||
typedef typename Distance::ElementType ElementType;
|
||||
typedef typename Distance::ResultType DistanceType;
|
||||
typedef typename Distance::CentersType CentersType;
|
||||
|
||||
CV_Assert(features.type() == CvType<ElementType>::type());
|
||||
CV_Assert(features.isContinuous());
|
||||
::cvflann::Matrix<ElementType> m_features((ElementType*)features.ptr<ElementType>(0), features.rows, features.cols);
|
||||
|
||||
CV_Assert(centers.type() == CvType<DistanceType>::type());
|
||||
CV_Assert(centers.type() == CvType<CentersType>::type());
|
||||
CV_Assert(centers.isContinuous());
|
||||
::cvflann::Matrix<DistanceType> m_centers((DistanceType*)centers.ptr<DistanceType>(0), centers.rows, centers.cols);
|
||||
::cvflann::Matrix<CentersType> m_centers((CentersType*)centers.ptr<CentersType>(0), centers.rows, centers.cols);
|
||||
|
||||
return ::cvflann::hierarchicalClustering<Distance>(m_features, m_centers, params, d);
|
||||
}
|
||||
|
||||
@@ -130,6 +130,9 @@ struct index_creator<False,False,Distance>
|
||||
case FLANN_INDEX_LINEAR:
|
||||
nnIndex = new LinearIndex<Distance>(dataset, params, distance);
|
||||
break;
|
||||
case FLANN_INDEX_KMEANS:
|
||||
nnIndex = new KMeansIndex<Distance>(dataset, params, distance);
|
||||
break;
|
||||
case FLANN_INDEX_HIERARCHICAL:
|
||||
nnIndex = new HierarchicalClusteringIndex<Distance>(dataset, params, distance);
|
||||
break;
|
||||
|
||||
@@ -497,7 +497,7 @@ private:
|
||||
const int nn = 1;
|
||||
const size_t SAMPLE_COUNT = 1000;
|
||||
|
||||
assert(bestIndex_ != NULL); // must have a valid index
|
||||
CV_Assert(bestIndex_ != NULL && "Requires a valid index"); // must have a valid index
|
||||
|
||||
float speedup = 0;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user