Merge remote-tracking branch 'upstream/3.4' into merge-3.4

pull/16167/head
Alexander Alekhin 5 years ago
commit ba7b0f4c54
  1. 17
      3rdparty/libwebp/src/dec/quant_dec.c
  2. 57
      3rdparty/libwebp/src/dec/tree_dec.c
  3. 81
      3rdparty/libwebp/src/dec/vp8_dec.c
  4. 2
      3rdparty/libwebp/src/dec/vp8i_dec.h
  5. 121
      3rdparty/libwebp/src/dec/vp8l_dec.c
  6. 2
      3rdparty/libwebp/src/demux/demux.c
  7. 4
      3rdparty/libwebp/src/dsp/alpha_processing_sse2.c
  8. 4
      3rdparty/libwebp/src/dsp/cpu.c
  9. 14
      3rdparty/libwebp/src/dsp/dec_sse2.c
  10. 2
      3rdparty/libwebp/src/dsp/enc_sse2.c
  11. 12
      3rdparty/libwebp/src/dsp/filters.c
  12. 16
      3rdparty/libwebp/src/dsp/filters_sse2.c
  13. 4
      3rdparty/libwebp/src/dsp/lossless.c
  14. 21
      3rdparty/libwebp/src/dsp/lossless_enc.c
  15. 4
      3rdparty/libwebp/src/dsp/lossless_enc_sse2.c
  16. 6
      3rdparty/libwebp/src/dsp/lossless_enc_sse41.c
  17. 15
      3rdparty/libwebp/src/dsp/quant.h
  18. 16
      3rdparty/libwebp/src/dsp/rescaler.c
  19. 16
      3rdparty/libwebp/src/dsp/rescaler_mips_dsp_r2.c
  20. 16
      3rdparty/libwebp/src/dsp/rescaler_msa.c
  21. 32
      3rdparty/libwebp/src/dsp/rescaler_neon.c
  22. 60
      3rdparty/libwebp/src/dsp/rescaler_sse2.c
  23. 11
      3rdparty/libwebp/src/enc/backward_references_enc.c
  24. 5
      3rdparty/libwebp/src/enc/histogram_enc.c
  25. 14
      3rdparty/libwebp/src/enc/predictor_enc.c
  26. 26
      3rdparty/libwebp/src/enc/quant_enc.c
  27. 2
      3rdparty/libwebp/src/enc/vp8i_enc.h
  28. 2
      3rdparty/libwebp/src/mux/muxi.h
  29. 11
      3rdparty/libwebp/src/utils/bit_reader_inl_utils.h
  30. 86
      3rdparty/libwebp/src/utils/bit_reader_utils.c
  31. 33
      3rdparty/libwebp/src/utils/bit_reader_utils.h
  32. 2
      3rdparty/libwebp/src/utils/bit_writer_utils.c
  33. 8
      3rdparty/libwebp/src/utils/color_cache_utils.h
  34. 26
      3rdparty/libwebp/src/utils/huffman_utils.c
  35. 2
      3rdparty/libwebp/src/utils/huffman_utils.h
  36. 8
      3rdparty/libwebp/src/utils/rescaler_utils.c
  37. 12
      3rdparty/libwebp/src/utils/thread_utils.c
  38. 6
      3rdparty/libwebp/src/utils/utils.h
  39. 4
      3rdparty/libwebp/src/webp/encode.h
  40. 2
      3rdparty/openvx/hal/CMakeLists.txt
  41. 2
      cmake/OpenCVCompilerOptimizations.cmake
  42. 2
      cmake/OpenCVDetectCUDA.cmake
  43. 81
      cmake/OpenCVDetectCXXCompiler.cmake
  44. 7
      cmake/OpenCVFindIPP.cmake
  45. 2
      cmake/OpenCVFindOpenEXR.cmake
  46. 18
      cmake/OpenCVModule.cmake
  47. 35
      cmake/OpenCVUtils.cmake
  48. 2
      cmake/android/android_ant_projects.cmake
  49. 30
      cmake/templates/OpenCVConfig.root-WIN32.cmake.in
  50. 22
      doc/CMakeLists.txt
  51. 8
      doc/Doxyfile.in
  52. 12
      doc/py_tutorials/py_feature2d/py_brief/py_brief.markdown
  53. 2
      doc/py_tutorials/py_gui/py_trackbar/py_trackbar.markdown
  54. 2
      modules/calib3d/test/test_undistort_badarg.cpp
  55. 2
      modules/core/CMakeLists.txt
  56. 73
      modules/core/src/matrix_expressions.cpp
  57. 15
      modules/core/test/test_operations.cpp
  58. 6
      modules/dnn/src/layers/eltwise_layer.cpp
  59. 30
      modules/dnn/test/test_halide_layers.cpp
  60. 4
      modules/imgcodecs/src/grfmt_bmp.cpp
  61. 18
      modules/java/jni/CMakeLists.txt
  62. 6
      modules/python/common.cmake
  63. 4
      modules/videoio/CMakeLists.txt
  64. 2
      samples/CMakeLists.example.in
  65. 6
      samples/cpp/CMakeLists.txt
  66. 2
      samples/cpp/example_cmake/CMakeLists.txt
  67. 4
      samples/cpp/tutorial_code/calib3d/real_time_pose_estimation/CMakeLists.txt
  68. 2
      samples/directx/CMakeLists.txt
  69. 2
      samples/dnn/CMakeLists.txt
  70. 6
      samples/gpu/CMakeLists.txt
  71. 2
      samples/opencl/CMakeLists.txt
  72. 4
      samples/opengl/CMakeLists.txt
  73. 2
      samples/openvx/CMakeLists.txt
  74. 2
      samples/samples_utils.cmake
  75. 2
      samples/tapi/CMakeLists.txt
  76. 2
      samples/va_intel/CMakeLists.txt

@ -61,12 +61,17 @@ static const uint16_t kAcTable[128] = {
void VP8ParseQuant(VP8Decoder* const dec) { void VP8ParseQuant(VP8Decoder* const dec) {
VP8BitReader* const br = &dec->br_; VP8BitReader* const br = &dec->br_;
const int base_q0 = VP8GetValue(br, 7); const int base_q0 = VP8GetValue(br, 7, "global-header");
const int dqy1_dc = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0; const int dqy1_dc = VP8Get(br, "global-header") ?
const int dqy2_dc = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0; VP8GetSignedValue(br, 4, "global-header") : 0;
const int dqy2_ac = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0; const int dqy2_dc = VP8Get(br, "global-header") ?
const int dquv_dc = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0; VP8GetSignedValue(br, 4, "global-header") : 0;
const int dquv_ac = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0; const int dqy2_ac = VP8Get(br, "global-header") ?
VP8GetSignedValue(br, 4, "global-header") : 0;
const int dquv_dc = VP8Get(br, "global-header") ?
VP8GetSignedValue(br, 4, "global-header") : 0;
const int dquv_ac = VP8Get(br, "global-header") ?
VP8GetSignedValue(br, 4, "global-header") : 0;
const VP8SegmentHeader* const hdr = &dec->segment_hdr_; const VP8SegmentHeader* const hdr = &dec->segment_hdr_;
int i; int i;

@ -296,20 +296,21 @@ static void ParseIntraMode(VP8BitReader* const br,
// to decode more than 1 keyframe. // to decode more than 1 keyframe.
if (dec->segment_hdr_.update_map_) { if (dec->segment_hdr_.update_map_) {
// Hardcoded tree parsing // Hardcoded tree parsing
block->segment_ = !VP8GetBit(br, dec->proba_.segments_[0]) block->segment_ = !VP8GetBit(br, dec->proba_.segments_[0], "segments")
? VP8GetBit(br, dec->proba_.segments_[1]) ? VP8GetBit(br, dec->proba_.segments_[1], "segments")
: 2 + VP8GetBit(br, dec->proba_.segments_[2]); : VP8GetBit(br, dec->proba_.segments_[2], "segments") + 2;
} else { } else {
block->segment_ = 0; // default for intra block->segment_ = 0; // default for intra
} }
if (dec->use_skip_proba_) block->skip_ = VP8GetBit(br, dec->skip_p_); if (dec->use_skip_proba_) block->skip_ = VP8GetBit(br, dec->skip_p_, "skip");
block->is_i4x4_ = !VP8GetBit(br, 145); // decide for B_PRED first block->is_i4x4_ = !VP8GetBit(br, 145, "block-size");
if (!block->is_i4x4_) { if (!block->is_i4x4_) {
// Hardcoded 16x16 intra-mode decision tree. // Hardcoded 16x16 intra-mode decision tree.
const int ymode = const int ymode =
VP8GetBit(br, 156) ? (VP8GetBit(br, 128) ? TM_PRED : H_PRED) VP8GetBit(br, 156, "pred-modes") ?
: (VP8GetBit(br, 163) ? V_PRED : DC_PRED); (VP8GetBit(br, 128, "pred-modes") ? TM_PRED : H_PRED) :
(VP8GetBit(br, 163, "pred-modes") ? V_PRED : DC_PRED);
block->imodes_[0] = ymode; block->imodes_[0] = ymode;
memset(top, ymode, 4 * sizeof(*top)); memset(top, ymode, 4 * sizeof(*top));
memset(left, ymode, 4 * sizeof(*left)); memset(left, ymode, 4 * sizeof(*left));
@ -323,22 +324,25 @@ static void ParseIntraMode(VP8BitReader* const br,
const uint8_t* const prob = kBModesProba[top[x]][ymode]; const uint8_t* const prob = kBModesProba[top[x]][ymode];
#if (USE_GENERIC_TREE == 1) #if (USE_GENERIC_TREE == 1)
// Generic tree-parsing // Generic tree-parsing
int i = kYModesIntra4[VP8GetBit(br, prob[0])]; int i = kYModesIntra4[VP8GetBit(br, prob[0], "pred-modes")];
while (i > 0) { while (i > 0) {
i = kYModesIntra4[2 * i + VP8GetBit(br, prob[i])]; i = kYModesIntra4[2 * i + VP8GetBit(br, prob[i], "pred-modes")];
} }
ymode = -i; ymode = -i;
#else #else
// Hardcoded tree parsing // Hardcoded tree parsing
ymode = !VP8GetBit(br, prob[0]) ? B_DC_PRED : ymode = !VP8GetBit(br, prob[0], "pred-modes") ? B_DC_PRED :
!VP8GetBit(br, prob[1]) ? B_TM_PRED : !VP8GetBit(br, prob[1], "pred-modes") ? B_TM_PRED :
!VP8GetBit(br, prob[2]) ? B_VE_PRED : !VP8GetBit(br, prob[2], "pred-modes") ? B_VE_PRED :
!VP8GetBit(br, prob[3]) ? !VP8GetBit(br, prob[3], "pred-modes") ?
(!VP8GetBit(br, prob[4]) ? B_HE_PRED : (!VP8GetBit(br, prob[4], "pred-modes") ? B_HE_PRED :
(!VP8GetBit(br, prob[5]) ? B_RD_PRED : B_VR_PRED)) : (!VP8GetBit(br, prob[5], "pred-modes") ? B_RD_PRED
(!VP8GetBit(br, prob[6]) ? B_LD_PRED : : B_VR_PRED)) :
(!VP8GetBit(br, prob[7]) ? B_VL_PRED : (!VP8GetBit(br, prob[6], "pred-modes") ? B_LD_PRED :
(!VP8GetBit(br, prob[8]) ? B_HD_PRED : B_HU_PRED))); (!VP8GetBit(br, prob[7], "pred-modes") ? B_VL_PRED :
(!VP8GetBit(br, prob[8], "pred-modes") ? B_HD_PRED
: B_HU_PRED))
);
#endif // USE_GENERIC_TREE #endif // USE_GENERIC_TREE
top[x] = ymode; top[x] = ymode;
} }
@ -348,9 +352,9 @@ static void ParseIntraMode(VP8BitReader* const br,
} }
} }
// Hardcoded UVMode decision tree // Hardcoded UVMode decision tree
block->uvmode_ = !VP8GetBit(br, 142) ? DC_PRED block->uvmode_ = !VP8GetBit(br, 142, "pred-modes-uv") ? DC_PRED
: !VP8GetBit(br, 114) ? V_PRED : !VP8GetBit(br, 114, "pred-modes-uv") ? V_PRED
: VP8GetBit(br, 183) ? TM_PRED : H_PRED; : VP8GetBit(br, 183, "pred-modes-uv") ? TM_PRED : H_PRED;
} }
int VP8ParseIntraModeRow(VP8BitReader* const br, VP8Decoder* const dec) { int VP8ParseIntraModeRow(VP8BitReader* const br, VP8Decoder* const dec) {
@ -514,8 +518,10 @@ void VP8ParseProba(VP8BitReader* const br, VP8Decoder* const dec) {
for (b = 0; b < NUM_BANDS; ++b) { for (b = 0; b < NUM_BANDS; ++b) {
for (c = 0; c < NUM_CTX; ++c) { for (c = 0; c < NUM_CTX; ++c) {
for (p = 0; p < NUM_PROBAS; ++p) { for (p = 0; p < NUM_PROBAS; ++p) {
const int v = VP8GetBit(br, CoeffsUpdateProba[t][b][c][p]) ? const int v =
VP8GetValue(br, 8) : CoeffsProba0[t][b][c][p]; VP8GetBit(br, CoeffsUpdateProba[t][b][c][p], "global-header") ?
VP8GetValue(br, 8, "global-header") :
CoeffsProba0[t][b][c][p];
proba->bands_[t][b].probas_[c][p] = v; proba->bands_[t][b].probas_[c][p] = v;
} }
} }
@ -524,9 +530,8 @@ void VP8ParseProba(VP8BitReader* const br, VP8Decoder* const dec) {
proba->bands_ptr_[t][b] = &proba->bands_[t][kBands[b]]; proba->bands_ptr_[t][b] = &proba->bands_[t][kBands[b]];
} }
} }
dec->use_skip_proba_ = VP8Get(br); dec->use_skip_proba_ = VP8Get(br, "global-header");
if (dec->use_skip_proba_) { if (dec->use_skip_proba_) {
dec->skip_p_ = VP8GetValue(br, 8); dec->skip_p_ = VP8GetValue(br, 8, "global-header");
} }
} }

@ -161,23 +161,26 @@ static int ParseSegmentHeader(VP8BitReader* br,
VP8SegmentHeader* hdr, VP8Proba* proba) { VP8SegmentHeader* hdr, VP8Proba* proba) {
assert(br != NULL); assert(br != NULL);
assert(hdr != NULL); assert(hdr != NULL);
hdr->use_segment_ = VP8Get(br); hdr->use_segment_ = VP8Get(br, "global-header");
if (hdr->use_segment_) { if (hdr->use_segment_) {
hdr->update_map_ = VP8Get(br); hdr->update_map_ = VP8Get(br, "global-header");
if (VP8Get(br)) { // update data if (VP8Get(br, "global-header")) { // update data
int s; int s;
hdr->absolute_delta_ = VP8Get(br); hdr->absolute_delta_ = VP8Get(br, "global-header");
for (s = 0; s < NUM_MB_SEGMENTS; ++s) { for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
hdr->quantizer_[s] = VP8Get(br) ? VP8GetSignedValue(br, 7) : 0; hdr->quantizer_[s] = VP8Get(br, "global-header") ?
VP8GetSignedValue(br, 7, "global-header") : 0;
} }
for (s = 0; s < NUM_MB_SEGMENTS; ++s) { for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
hdr->filter_strength_[s] = VP8Get(br) ? VP8GetSignedValue(br, 6) : 0; hdr->filter_strength_[s] = VP8Get(br, "global-header") ?
VP8GetSignedValue(br, 6, "global-header") : 0;
} }
} }
if (hdr->update_map_) { if (hdr->update_map_) {
int s; int s;
for (s = 0; s < MB_FEATURE_TREE_PROBS; ++s) { for (s = 0; s < MB_FEATURE_TREE_PROBS; ++s) {
proba->segments_[s] = VP8Get(br) ? VP8GetValue(br, 8) : 255u; proba->segments_[s] = VP8Get(br, "global-header") ?
VP8GetValue(br, 8, "global-header") : 255u;
} }
} }
} else { } else {
@ -205,7 +208,7 @@ static VP8StatusCode ParsePartitions(VP8Decoder* const dec,
size_t last_part; size_t last_part;
size_t p; size_t p;
dec->num_parts_minus_one_ = (1 << VP8GetValue(br, 2)) - 1; dec->num_parts_minus_one_ = (1 << VP8GetValue(br, 2, "global-header")) - 1;
last_part = dec->num_parts_minus_one_; last_part = dec->num_parts_minus_one_;
if (size < 3 * last_part) { if (size < 3 * last_part) {
// we can't even read the sizes with sz[]! That's a failure. // we can't even read the sizes with sz[]! That's a failure.
@ -229,21 +232,21 @@ static VP8StatusCode ParsePartitions(VP8Decoder* const dec,
// Paragraph 9.4 // Paragraph 9.4
static int ParseFilterHeader(VP8BitReader* br, VP8Decoder* const dec) { static int ParseFilterHeader(VP8BitReader* br, VP8Decoder* const dec) {
VP8FilterHeader* const hdr = &dec->filter_hdr_; VP8FilterHeader* const hdr = &dec->filter_hdr_;
hdr->simple_ = VP8Get(br); hdr->simple_ = VP8Get(br, "global-header");
hdr->level_ = VP8GetValue(br, 6); hdr->level_ = VP8GetValue(br, 6, "global-header");
hdr->sharpness_ = VP8GetValue(br, 3); hdr->sharpness_ = VP8GetValue(br, 3, "global-header");
hdr->use_lf_delta_ = VP8Get(br); hdr->use_lf_delta_ = VP8Get(br, "global-header");
if (hdr->use_lf_delta_) { if (hdr->use_lf_delta_) {
if (VP8Get(br)) { // update lf-delta? if (VP8Get(br, "global-header")) { // update lf-delta?
int i; int i;
for (i = 0; i < NUM_REF_LF_DELTAS; ++i) { for (i = 0; i < NUM_REF_LF_DELTAS; ++i) {
if (VP8Get(br)) { if (VP8Get(br, "global-header")) {
hdr->ref_lf_delta_[i] = VP8GetSignedValue(br, 6); hdr->ref_lf_delta_[i] = VP8GetSignedValue(br, 6, "global-header");
} }
} }
for (i = 0; i < NUM_MODE_LF_DELTAS; ++i) { for (i = 0; i < NUM_MODE_LF_DELTAS; ++i) {
if (VP8Get(br)) { if (VP8Get(br, "global-header")) {
hdr->mode_lf_delta_[i] = VP8GetSignedValue(br, 6); hdr->mode_lf_delta_[i] = VP8GetSignedValue(br, 6, "global-header");
} }
} }
} }
@ -352,8 +355,8 @@ int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) {
buf_size -= frm_hdr->partition_length_; buf_size -= frm_hdr->partition_length_;
if (frm_hdr->key_frame_) { if (frm_hdr->key_frame_) {
pic_hdr->colorspace_ = VP8Get(br); pic_hdr->colorspace_ = VP8Get(br, "global-header");
pic_hdr->clamp_type_ = VP8Get(br); pic_hdr->clamp_type_ = VP8Get(br, "global-header");
} }
if (!ParseSegmentHeader(br, &dec->segment_hdr_, &dec->proba_)) { if (!ParseSegmentHeader(br, &dec->segment_hdr_, &dec->proba_)) {
return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR, return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
@ -378,7 +381,7 @@ int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) {
"Not a key frame."); "Not a key frame.");
} }
VP8Get(br); // ignore the value of update_proba_ VP8Get(br, "global-header"); // ignore the value of update_proba_
VP8ParseProba(br, dec); VP8ParseProba(br, dec);
@ -403,28 +406,28 @@ static const uint8_t kZigzag[16] = {
// See section 13-2: http://tools.ietf.org/html/rfc6386#section-13.2 // See section 13-2: http://tools.ietf.org/html/rfc6386#section-13.2
static int GetLargeValue(VP8BitReader* const br, const uint8_t* const p) { static int GetLargeValue(VP8BitReader* const br, const uint8_t* const p) {
int v; int v;
if (!VP8GetBit(br, p[3])) { if (!VP8GetBit(br, p[3], "coeffs")) {
if (!VP8GetBit(br, p[4])) { if (!VP8GetBit(br, p[4], "coeffs")) {
v = 2; v = 2;
} else { } else {
v = 3 + VP8GetBit(br, p[5]); v = 3 + VP8GetBit(br, p[5], "coeffs");
} }
} else { } else {
if (!VP8GetBit(br, p[6])) { if (!VP8GetBit(br, p[6], "coeffs")) {
if (!VP8GetBit(br, p[7])) { if (!VP8GetBit(br, p[7], "coeffs")) {
v = 5 + VP8GetBit(br, 159); v = 5 + VP8GetBit(br, 159, "coeffs");
} else { } else {
v = 7 + 2 * VP8GetBit(br, 165); v = 7 + 2 * VP8GetBit(br, 165, "coeffs");
v += VP8GetBit(br, 145); v += VP8GetBit(br, 145, "coeffs");
} }
} else { } else {
const uint8_t* tab; const uint8_t* tab;
const int bit1 = VP8GetBit(br, p[8]); const int bit1 = VP8GetBit(br, p[8], "coeffs");
const int bit0 = VP8GetBit(br, p[9 + bit1]); const int bit0 = VP8GetBit(br, p[9 + bit1], "coeffs");
const int cat = 2 * bit1 + bit0; const int cat = 2 * bit1 + bit0;
v = 0; v = 0;
for (tab = kCat3456[cat]; *tab; ++tab) { for (tab = kCat3456[cat]; *tab; ++tab) {
v += v + VP8GetBit(br, *tab); v += v + VP8GetBit(br, *tab, "coeffs");
} }
v += 3 + (8 << cat); v += 3 + (8 << cat);
} }
@ -438,24 +441,24 @@ static int GetCoeffsFast(VP8BitReader* const br,
int ctx, const quant_t dq, int n, int16_t* out) { int ctx, const quant_t dq, int n, int16_t* out) {
const uint8_t* p = prob[n]->probas_[ctx]; const uint8_t* p = prob[n]->probas_[ctx];
for (; n < 16; ++n) { for (; n < 16; ++n) {
if (!VP8GetBit(br, p[0])) { if (!VP8GetBit(br, p[0], "coeffs")) {
return n; // previous coeff was last non-zero coeff return n; // previous coeff was last non-zero coeff
} }
while (!VP8GetBit(br, p[1])) { // sequence of zero coeffs while (!VP8GetBit(br, p[1], "coeffs")) { // sequence of zero coeffs
p = prob[++n]->probas_[0]; p = prob[++n]->probas_[0];
if (n == 16) return 16; if (n == 16) return 16;
} }
{ // non zero coeff { // non zero coeff
const VP8ProbaArray* const p_ctx = &prob[n + 1]->probas_[0]; const VP8ProbaArray* const p_ctx = &prob[n + 1]->probas_[0];
int v; int v;
if (!VP8GetBit(br, p[2])) { if (!VP8GetBit(br, p[2], "coeffs")) {
v = 1; v = 1;
p = p_ctx[1]; p = p_ctx[1];
} else { } else {
v = GetLargeValue(br, p); v = GetLargeValue(br, p);
p = p_ctx[2]; p = p_ctx[2];
} }
out[kZigzag[n]] = VP8GetSigned(br, v) * dq[n > 0]; out[kZigzag[n]] = VP8GetSigned(br, v, "coeffs") * dq[n > 0];
} }
} }
return 16; return 16;
@ -468,24 +471,24 @@ static int GetCoeffsAlt(VP8BitReader* const br,
int ctx, const quant_t dq, int n, int16_t* out) { int ctx, const quant_t dq, int n, int16_t* out) {
const uint8_t* p = prob[n]->probas_[ctx]; const uint8_t* p = prob[n]->probas_[ctx];
for (; n < 16; ++n) { for (; n < 16; ++n) {
if (!VP8GetBitAlt(br, p[0])) { if (!VP8GetBitAlt(br, p[0], "coeffs")) {
return n; // previous coeff was last non-zero coeff return n; // previous coeff was last non-zero coeff
} }
while (!VP8GetBitAlt(br, p[1])) { // sequence of zero coeffs while (!VP8GetBitAlt(br, p[1], "coeffs")) { // sequence of zero coeffs
p = prob[++n]->probas_[0]; p = prob[++n]->probas_[0];
if (n == 16) return 16; if (n == 16) return 16;
} }
{ // non zero coeff { // non zero coeff
const VP8ProbaArray* const p_ctx = &prob[n + 1]->probas_[0]; const VP8ProbaArray* const p_ctx = &prob[n + 1]->probas_[0];
int v; int v;
if (!VP8GetBitAlt(br, p[2])) { if (!VP8GetBitAlt(br, p[2], "coeffs")) {
v = 1; v = 1;
p = p_ctx[1]; p = p_ctx[1];
} else { } else {
v = GetLargeValue(br, p); v = GetLargeValue(br, p);
p = p_ctx[2]; p = p_ctx[2];
} }
out[kZigzag[n]] = VP8GetSigned(br, v) * dq[n > 0]; out[kZigzag[n]] = VP8GetSigned(br, v, "coeffs") * dq[n > 0];
} }
} }
return 16; return 16;

@ -32,7 +32,7 @@ extern "C" {
// version numbers // version numbers
#define DEC_MAJ_VERSION 1 #define DEC_MAJ_VERSION 1
#define DEC_MIN_VERSION 0 #define DEC_MIN_VERSION 0
#define DEC_REV_VERSION 2 #define DEC_REV_VERSION 3
// YUV-cache parameters. Cache is 32-bytes wide (= one cacheline). // YUV-cache parameters. Cache is 32-bytes wide (= one cacheline).
// Constraints are: We need to store one 16x16 block of luma samples (y), // Constraints are: We need to store one 16x16 block of luma samples (y),

@ -362,12 +362,8 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
VP8LMetadata* const hdr = &dec->hdr_; VP8LMetadata* const hdr = &dec->hdr_;
uint32_t* huffman_image = NULL; uint32_t* huffman_image = NULL;
HTreeGroup* htree_groups = NULL; HTreeGroup* htree_groups = NULL;
// When reading htrees, some might be unused, as the format allows it.
// We will still read them but put them in this htree_group_bogus.
HTreeGroup htree_group_bogus;
HuffmanCode* huffman_tables = NULL; HuffmanCode* huffman_tables = NULL;
HuffmanCode* huffman_tables_bogus = NULL; HuffmanCode* huffman_table = NULL;
HuffmanCode* next = NULL;
int num_htree_groups = 1; int num_htree_groups = 1;
int num_htree_groups_max = 1; int num_htree_groups_max = 1;
int max_alphabet_size = 0; int max_alphabet_size = 0;
@ -418,12 +414,6 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
if (*mapped_group == -1) *mapped_group = num_htree_groups++; if (*mapped_group == -1) *mapped_group = num_htree_groups++;
huffman_image[i] = *mapped_group; huffman_image[i] = *mapped_group;
} }
huffman_tables_bogus = (HuffmanCode*)WebPSafeMalloc(
table_size, sizeof(*huffman_tables_bogus));
if (huffman_tables_bogus == NULL) {
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
goto Error;
}
} else { } else {
num_htree_groups = num_htree_groups_max; num_htree_groups = num_htree_groups_max;
} }
@ -453,63 +443,71 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
goto Error; goto Error;
} }
next = huffman_tables; huffman_table = huffman_tables;
for (i = 0; i < num_htree_groups_max; ++i) { for (i = 0; i < num_htree_groups_max; ++i) {
// If the index "i" is unused in the Huffman image, read the coefficients // If the index "i" is unused in the Huffman image, just make sure the
// but store them to a bogus htree_group. // coefficients are valid but do not store them.
const int is_bogus = (mapping != NULL && mapping[i] == -1); if (mapping != NULL && mapping[i] == -1) {
HTreeGroup* const htree_group = for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
is_bogus ? &htree_group_bogus : int alphabet_size = kAlphabetSize[j];
&htree_groups[(mapping == NULL) ? i : mapping[i]]; if (j == 0 && color_cache_bits > 0) {
HuffmanCode** const htrees = htree_group->htrees; alphabet_size += (1 << color_cache_bits);
HuffmanCode* huffman_tables_i = is_bogus ? huffman_tables_bogus : next; }
int size; // Passing in NULL so that nothing gets filled.
int total_size = 0; if (!ReadHuffmanCode(alphabet_size, dec, code_lengths, NULL)) {
int is_trivial_literal = 1; goto Error;
int max_bits = 0; }
for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
int alphabet_size = kAlphabetSize[j];
htrees[j] = huffman_tables_i;
if (j == 0 && color_cache_bits > 0) {
alphabet_size += 1 << color_cache_bits;
}
size =
ReadHuffmanCode(alphabet_size, dec, code_lengths, huffman_tables_i);
if (size == 0) {
goto Error;
}
if (is_trivial_literal && kLiteralMap[j] == 1) {
is_trivial_literal = (huffman_tables_i->bits == 0);
} }
total_size += huffman_tables_i->bits; } else {
huffman_tables_i += size; HTreeGroup* const htree_group =
if (j <= ALPHA) { &htree_groups[(mapping == NULL) ? i : mapping[i]];
int local_max_bits = code_lengths[0]; HuffmanCode** const htrees = htree_group->htrees;
int k; int size;
for (k = 1; k < alphabet_size; ++k) { int total_size = 0;
if (code_lengths[k] > local_max_bits) { int is_trivial_literal = 1;
local_max_bits = code_lengths[k]; int max_bits = 0;
for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
int alphabet_size = kAlphabetSize[j];
htrees[j] = huffman_table;
if (j == 0 && color_cache_bits > 0) {
alphabet_size += (1 << color_cache_bits);
}
size = ReadHuffmanCode(alphabet_size, dec, code_lengths, huffman_table);
if (size == 0) {
goto Error;
}
if (is_trivial_literal && kLiteralMap[j] == 1) {
is_trivial_literal = (huffman_table->bits == 0);
}
total_size += huffman_table->bits;
huffman_table += size;
if (j <= ALPHA) {
int local_max_bits = code_lengths[0];
int k;
for (k = 1; k < alphabet_size; ++k) {
if (code_lengths[k] > local_max_bits) {
local_max_bits = code_lengths[k];
}
} }
max_bits += local_max_bits;
} }
max_bits += local_max_bits;
} }
} htree_group->is_trivial_literal = is_trivial_literal;
if (!is_bogus) next = huffman_tables_i; htree_group->is_trivial_code = 0;
htree_group->is_trivial_literal = is_trivial_literal; if (is_trivial_literal) {
htree_group->is_trivial_code = 0; const int red = htrees[RED][0].value;
if (is_trivial_literal) { const int blue = htrees[BLUE][0].value;
const int red = htrees[RED][0].value; const int alpha = htrees[ALPHA][0].value;
const int blue = htrees[BLUE][0].value; htree_group->literal_arb = ((uint32_t)alpha << 24) | (red << 16) | blue;
const int alpha = htrees[ALPHA][0].value; if (total_size == 0 && htrees[GREEN][0].value < NUM_LITERAL_CODES) {
htree_group->literal_arb = ((uint32_t)alpha << 24) | (red << 16) | blue; htree_group->is_trivial_code = 1;
if (total_size == 0 && htrees[GREEN][0].value < NUM_LITERAL_CODES) { htree_group->literal_arb |= htrees[GREEN][0].value << 8;
htree_group->is_trivial_code = 1; }
htree_group->literal_arb |= htrees[GREEN][0].value << 8;
} }
htree_group->use_packed_table =
!htree_group->is_trivial_code && (max_bits < HUFFMAN_PACKED_BITS);
if (htree_group->use_packed_table) BuildPackedTable(htree_group);
} }
htree_group->use_packed_table =
!htree_group->is_trivial_code && (max_bits < HUFFMAN_PACKED_BITS);
if (htree_group->use_packed_table) BuildPackedTable(htree_group);
} }
ok = 1; ok = 1;
@ -521,7 +519,6 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
Error: Error:
WebPSafeFree(code_lengths); WebPSafeFree(code_lengths);
WebPSafeFree(huffman_tables_bogus);
WebPSafeFree(mapping); WebPSafeFree(mapping);
if (!ok) { if (!ok) {
WebPSafeFree(huffman_image); WebPSafeFree(huffman_image);

@ -25,7 +25,7 @@
#define DMUX_MAJ_VERSION 1 #define DMUX_MAJ_VERSION 1
#define DMUX_MIN_VERSION 0 #define DMUX_MIN_VERSION 0
#define DMUX_REV_VERSION 2 #define DMUX_REV_VERSION 3
typedef struct { typedef struct {
size_t start_; // start location of the data size_t start_; // start location of the data

@ -214,7 +214,7 @@ static void ApplyAlphaMultiply_SSE2(uint8_t* rgba, int alpha_first,
// Alpha detection // Alpha detection
static int HasAlpha8b_SSE2(const uint8_t* src, int length) { static int HasAlpha8b_SSE2(const uint8_t* src, int length) {
const __m128i all_0xff = _mm_set1_epi8(0xff); const __m128i all_0xff = _mm_set1_epi8((char)0xff);
int i = 0; int i = 0;
for (; i + 16 <= length; i += 16) { for (; i + 16 <= length; i += 16) {
const __m128i v = _mm_loadu_si128((const __m128i*)(src + i)); const __m128i v = _mm_loadu_si128((const __m128i*)(src + i));
@ -228,7 +228,7 @@ static int HasAlpha8b_SSE2(const uint8_t* src, int length) {
static int HasAlpha32b_SSE2(const uint8_t* src, int length) { static int HasAlpha32b_SSE2(const uint8_t* src, int length) {
const __m128i alpha_mask = _mm_set1_epi32(0xff); const __m128i alpha_mask = _mm_set1_epi32(0xff);
const __m128i all_0xff = _mm_set1_epi8(0xff); const __m128i all_0xff = _mm_set1_epi8((char)0xff);
int i = 0; int i = 0;
// We don't know if we can access the last 3 bytes after the last alpha // We don't know if we can access the last 3 bytes after the last alpha
// value 'src[4 * length - 4]' (because we don't know if alpha is the first // value 'src[4 * length - 4]' (because we don't know if alpha is the first

@ -173,8 +173,8 @@ static int AndroidCPUInfo(CPUFeature feature) {
const AndroidCpuFamily cpu_family = android_getCpuFamily(); const AndroidCpuFamily cpu_family = android_getCpuFamily();
const uint64_t cpu_features = android_getCpuFeatures(); const uint64_t cpu_features = android_getCpuFeatures();
if (feature == kNEON) { if (feature == kNEON) {
return (cpu_family == ANDROID_CPU_FAMILY_ARM && return cpu_family == ANDROID_CPU_FAMILY_ARM &&
0 != (cpu_features & ANDROID_CPU_ARM_FEATURE_NEON)); (cpu_features & ANDROID_CPU_ARM_FEATURE_NEON) != 0;
} }
return 0; return 0;
} }

@ -326,7 +326,7 @@ static WEBP_INLINE void Update2Pixels_SSE2(__m128i* const pi, __m128i* const qi,
const __m128i a1_lo = _mm_srai_epi16(*a0_lo, 7); const __m128i a1_lo = _mm_srai_epi16(*a0_lo, 7);
const __m128i a1_hi = _mm_srai_epi16(*a0_hi, 7); const __m128i a1_hi = _mm_srai_epi16(*a0_hi, 7);
const __m128i delta = _mm_packs_epi16(a1_lo, a1_hi); const __m128i delta = _mm_packs_epi16(a1_lo, a1_hi);
const __m128i sign_bit = _mm_set1_epi8(0x80); const __m128i sign_bit = _mm_set1_epi8((char)0x80);
*pi = _mm_adds_epi8(*pi, delta); *pi = _mm_adds_epi8(*pi, delta);
*qi = _mm_subs_epi8(*qi, delta); *qi = _mm_subs_epi8(*qi, delta);
FLIP_SIGN_BIT2(*pi, *qi); FLIP_SIGN_BIT2(*pi, *qi);
@ -338,9 +338,9 @@ static WEBP_INLINE void NeedsFilter_SSE2(const __m128i* const p1,
const __m128i* const q0, const __m128i* const q0,
const __m128i* const q1, const __m128i* const q1,
int thresh, __m128i* const mask) { int thresh, __m128i* const mask) {
const __m128i m_thresh = _mm_set1_epi8(thresh); const __m128i m_thresh = _mm_set1_epi8((char)thresh);
const __m128i t1 = MM_ABS(*p1, *q1); // abs(p1 - q1) const __m128i t1 = MM_ABS(*p1, *q1); // abs(p1 - q1)
const __m128i kFE = _mm_set1_epi8(0xFE); const __m128i kFE = _mm_set1_epi8((char)0xFE);
const __m128i t2 = _mm_and_si128(t1, kFE); // set lsb of each byte to zero const __m128i t2 = _mm_and_si128(t1, kFE); // set lsb of each byte to zero
const __m128i t3 = _mm_srli_epi16(t2, 1); // abs(p1 - q1) / 2 const __m128i t3 = _mm_srli_epi16(t2, 1); // abs(p1 - q1) / 2
@ -360,7 +360,7 @@ static WEBP_INLINE void DoFilter2_SSE2(__m128i* const p1, __m128i* const p0,
__m128i* const q0, __m128i* const q1, __m128i* const q0, __m128i* const q1,
int thresh) { int thresh) {
__m128i a, mask; __m128i a, mask;
const __m128i sign_bit = _mm_set1_epi8(0x80); const __m128i sign_bit = _mm_set1_epi8((char)0x80);
// convert p1/q1 to int8_t (for GetBaseDelta_SSE2) // convert p1/q1 to int8_t (for GetBaseDelta_SSE2)
const __m128i p1s = _mm_xor_si128(*p1, sign_bit); const __m128i p1s = _mm_xor_si128(*p1, sign_bit);
const __m128i q1s = _mm_xor_si128(*q1, sign_bit); const __m128i q1s = _mm_xor_si128(*q1, sign_bit);
@ -380,7 +380,7 @@ static WEBP_INLINE void DoFilter4_SSE2(__m128i* const p1, __m128i* const p0,
const __m128i* const mask, const __m128i* const mask,
int hev_thresh) { int hev_thresh) {
const __m128i zero = _mm_setzero_si128(); const __m128i zero = _mm_setzero_si128();
const __m128i sign_bit = _mm_set1_epi8(0x80); const __m128i sign_bit = _mm_set1_epi8((char)0x80);
const __m128i k64 = _mm_set1_epi8(64); const __m128i k64 = _mm_set1_epi8(64);
const __m128i k3 = _mm_set1_epi8(3); const __m128i k3 = _mm_set1_epi8(3);
const __m128i k4 = _mm_set1_epi8(4); const __m128i k4 = _mm_set1_epi8(4);
@ -427,7 +427,7 @@ static WEBP_INLINE void DoFilter6_SSE2(__m128i* const p2, __m128i* const p1,
const __m128i* const mask, const __m128i* const mask,
int hev_thresh) { int hev_thresh) {
const __m128i zero = _mm_setzero_si128(); const __m128i zero = _mm_setzero_si128();
const __m128i sign_bit = _mm_set1_epi8(0x80); const __m128i sign_bit = _mm_set1_epi8((char)0x80);
__m128i a, not_hev; __m128i a, not_hev;
// compute hev mask // compute hev mask
@ -941,7 +941,7 @@ static void VR4_SSE2(uint8_t* dst) { // Vertical-Right
const __m128i ABCD0 = _mm_srli_si128(XABCD, 1); const __m128i ABCD0 = _mm_srli_si128(XABCD, 1);
const __m128i abcd = _mm_avg_epu8(XABCD, ABCD0); const __m128i abcd = _mm_avg_epu8(XABCD, ABCD0);
const __m128i _XABCD = _mm_slli_si128(XABCD, 1); const __m128i _XABCD = _mm_slli_si128(XABCD, 1);
const __m128i IXABCD = _mm_insert_epi16(_XABCD, I | (X << 8), 0); const __m128i IXABCD = _mm_insert_epi16(_XABCD, (short)(I | (X << 8)), 0);
const __m128i avg1 = _mm_avg_epu8(IXABCD, ABCD0); const __m128i avg1 = _mm_avg_epu8(IXABCD, ABCD0);
const __m128i lsb = _mm_and_si128(_mm_xor_si128(IXABCD, ABCD0), one); const __m128i lsb = _mm_and_si128(_mm_xor_si128(IXABCD, ABCD0), one);
const __m128i avg2 = _mm_subs_epu8(avg1, lsb); const __m128i avg2 = _mm_subs_epu8(avg1, lsb);

@ -777,7 +777,7 @@ static WEBP_INLINE void VR4_SSE2(uint8_t* dst,
const __m128i ABCD0 = _mm_srli_si128(XABCD, 1); const __m128i ABCD0 = _mm_srli_si128(XABCD, 1);
const __m128i abcd = _mm_avg_epu8(XABCD, ABCD0); const __m128i abcd = _mm_avg_epu8(XABCD, ABCD0);
const __m128i _XABCD = _mm_slli_si128(XABCD, 1); const __m128i _XABCD = _mm_slli_si128(XABCD, 1);
const __m128i IXABCD = _mm_insert_epi16(_XABCD, I | (X << 8), 0); const __m128i IXABCD = _mm_insert_epi16(_XABCD, (short)(I | (X << 8)), 0);
const __m128i avg1 = _mm_avg_epu8(IXABCD, ABCD0); const __m128i avg1 = _mm_avg_epu8(IXABCD, ABCD0);
const __m128i lsb = _mm_and_si128(_mm_xor_si128(IXABCD, ABCD0), one); const __m128i lsb = _mm_and_si128(_mm_xor_si128(IXABCD, ABCD0), one);
const __m128i avg2 = _mm_subs_epu8(avg1, lsb); const __m128i avg2 = _mm_subs_epu8(avg1, lsb);

@ -33,9 +33,9 @@ static WEBP_INLINE void PredictLine_C(const uint8_t* src, const uint8_t* pred,
uint8_t* dst, int length, int inverse) { uint8_t* dst, int length, int inverse) {
int i; int i;
if (inverse) { if (inverse) {
for (i = 0; i < length; ++i) dst[i] = src[i] + pred[i]; for (i = 0; i < length; ++i) dst[i] = (uint8_t)(src[i] + pred[i]);
} else { } else {
for (i = 0; i < length; ++i) dst[i] = src[i] - pred[i]; for (i = 0; i < length; ++i) dst[i] = (uint8_t)(src[i] - pred[i]);
} }
} }
@ -155,7 +155,7 @@ static WEBP_INLINE void DoGradientFilter_C(const uint8_t* in,
const int pred = GradientPredictor_C(preds[w - 1], const int pred = GradientPredictor_C(preds[w - 1],
preds[w - stride], preds[w - stride],
preds[w - stride - 1]); preds[w - stride - 1]);
out[w] = in[w] + (inverse ? pred : -pred); out[w] = (uint8_t)(in[w] + (inverse ? pred : -pred));
} }
++row; ++row;
preds += stride; preds += stride;
@ -194,7 +194,7 @@ static void HorizontalUnfilter_C(const uint8_t* prev, const uint8_t* in,
uint8_t pred = (prev == NULL) ? 0 : prev[0]; uint8_t pred = (prev == NULL) ? 0 : prev[0];
int i; int i;
for (i = 0; i < width; ++i) { for (i = 0; i < width; ++i) {
out[i] = pred + in[i]; out[i] = (uint8_t)(pred + in[i]);
pred = out[i]; pred = out[i];
} }
} }
@ -206,7 +206,7 @@ static void VerticalUnfilter_C(const uint8_t* prev, const uint8_t* in,
HorizontalUnfilter_C(NULL, in, out, width); HorizontalUnfilter_C(NULL, in, out, width);
} else { } else {
int i; int i;
for (i = 0; i < width; ++i) out[i] = prev[i] + in[i]; for (i = 0; i < width; ++i) out[i] = (uint8_t)(prev[i] + in[i]);
} }
} }
#endif // !WEBP_NEON_OMIT_C_CODE #endif // !WEBP_NEON_OMIT_C_CODE
@ -220,7 +220,7 @@ static void GradientUnfilter_C(const uint8_t* prev, const uint8_t* in,
int i; int i;
for (i = 0; i < width; ++i) { for (i = 0; i < width; ++i) {
top = prev[i]; // need to read this first, in case prev==out top = prev[i]; // need to read this first, in case prev==out
left = in[i] + GradientPredictor_C(left, top, top_left); left = (uint8_t)(in[i] + GradientPredictor_C(left, top, top_left));
top_left = top; top_left = top;
out[i] = left; out[i] = left;
} }

@ -163,7 +163,8 @@ static void GradientPredictDirect_SSE2(const uint8_t* const row,
_mm_storel_epi64((__m128i*)(out + i), H); _mm_storel_epi64((__m128i*)(out + i), H);
} }
for (; i < length; ++i) { for (; i < length; ++i) {
out[i] = row[i] - GradientPredictor_SSE2(row[i - 1], top[i], top[i - 1]); const int delta = GradientPredictor_SSE2(row[i - 1], top[i], top[i - 1]);
out[i] = (uint8_t)(row[i] - delta);
} }
} }
@ -188,7 +189,7 @@ static WEBP_INLINE void DoGradientFilter_SSE2(const uint8_t* in,
// Filter line-by-line. // Filter line-by-line.
while (row < last_row) { while (row < last_row) {
out[0] = in[0] - in[-stride]; out[0] = (uint8_t)(in[0] - in[-stride]);
GradientPredictDirect_SSE2(in + 1, in + 1 - stride, out + 1, width - 1); GradientPredictDirect_SSE2(in + 1, in + 1 - stride, out + 1, width - 1);
++row; ++row;
in += stride; in += stride;
@ -223,7 +224,7 @@ static void HorizontalUnfilter_SSE2(const uint8_t* prev, const uint8_t* in,
uint8_t* out, int width) { uint8_t* out, int width) {
int i; int i;
__m128i last; __m128i last;
out[0] = in[0] + (prev == NULL ? 0 : prev[0]); out[0] = (uint8_t)(in[0] + (prev == NULL ? 0 : prev[0]));
if (width <= 1) return; if (width <= 1) return;
last = _mm_set_epi32(0, 0, 0, out[0]); last = _mm_set_epi32(0, 0, 0, out[0]);
for (i = 1; i + 8 <= width; i += 8) { for (i = 1; i + 8 <= width; i += 8) {
@ -238,7 +239,7 @@ static void HorizontalUnfilter_SSE2(const uint8_t* prev, const uint8_t* in,
_mm_storel_epi64((__m128i*)(out + i), A7); _mm_storel_epi64((__m128i*)(out + i), A7);
last = _mm_srli_epi64(A7, 56); last = _mm_srli_epi64(A7, 56);
} }
for (; i < width; ++i) out[i] = in[i] + out[i - 1]; for (; i < width; ++i) out[i] = (uint8_t)(in[i] + out[i - 1]);
} }
static void VerticalUnfilter_SSE2(const uint8_t* prev, const uint8_t* in, static void VerticalUnfilter_SSE2(const uint8_t* prev, const uint8_t* in,
@ -259,7 +260,7 @@ static void VerticalUnfilter_SSE2(const uint8_t* prev, const uint8_t* in,
_mm_storeu_si128((__m128i*)&out[i + 0], C0); _mm_storeu_si128((__m128i*)&out[i + 0], C0);
_mm_storeu_si128((__m128i*)&out[i + 16], C1); _mm_storeu_si128((__m128i*)&out[i + 16], C1);
} }
for (; i < width; ++i) out[i] = in[i] + prev[i]; for (; i < width; ++i) out[i] = (uint8_t)(in[i] + prev[i]);
} }
} }
@ -296,7 +297,8 @@ static void GradientPredictInverse_SSE2(const uint8_t* const in,
_mm_storel_epi64((__m128i*)&row[i], out); _mm_storel_epi64((__m128i*)&row[i], out);
} }
for (; i < length; ++i) { for (; i < length; ++i) {
row[i] = in[i] + GradientPredictor_SSE2(row[i - 1], top[i], top[i - 1]); const int delta = GradientPredictor_SSE2(row[i - 1], top[i], top[i - 1]);
row[i] = (uint8_t)(in[i] + delta);
} }
} }
} }
@ -306,7 +308,7 @@ static void GradientUnfilter_SSE2(const uint8_t* prev, const uint8_t* in,
if (prev == NULL) { if (prev == NULL) {
HorizontalUnfilter_SSE2(NULL, in, out, width); HorizontalUnfilter_SSE2(NULL, in, out, width);
} else { } else {
out[0] = in[0] + prev[0]; // predict from above out[0] = (uint8_t)(in[0] + prev[0]); // predict from above
GradientPredictInverse_SSE2(in + 1, prev + 1, out + 1, width - 1); GradientPredictInverse_SSE2(in + 1, prev + 1, out + 1, width - 1);
} }
} }

@ -270,14 +270,14 @@ void VP8LTransformColorInverse_C(const VP8LMultipliers* const m,
int i; int i;
for (i = 0; i < num_pixels; ++i) { for (i = 0; i < num_pixels; ++i) {
const uint32_t argb = src[i]; const uint32_t argb = src[i];
const uint32_t green = argb >> 8; const int8_t green = (int8_t)(argb >> 8);
const uint32_t red = argb >> 16; const uint32_t red = argb >> 16;
int new_red = red & 0xff; int new_red = red & 0xff;
int new_blue = argb & 0xff; int new_blue = argb & 0xff;
new_red += ColorTransformDelta(m->green_to_red_, green); new_red += ColorTransformDelta(m->green_to_red_, green);
new_red &= 0xff; new_red &= 0xff;
new_blue += ColorTransformDelta(m->green_to_blue_, green); new_blue += ColorTransformDelta(m->green_to_blue_, green);
new_blue += ColorTransformDelta(m->red_to_blue_, new_red); new_blue += ColorTransformDelta(m->red_to_blue_, (int8_t)new_red);
new_blue &= 0xff; new_blue &= 0xff;
dst[i] = (argb & 0xff00ff00u) | (new_red << 16) | (new_blue); dst[i] = (argb & 0xff00ff00u) | (new_red << 16) | (new_blue);
} }

@ -515,13 +515,17 @@ static WEBP_INLINE int ColorTransformDelta(int8_t color_pred, int8_t color) {
return ((int)color_pred * color) >> 5; return ((int)color_pred * color) >> 5;
} }
static WEBP_INLINE int8_t U32ToS8(uint32_t v) {
return (int8_t)(v & 0xff);
}
void VP8LTransformColor_C(const VP8LMultipliers* const m, uint32_t* data, void VP8LTransformColor_C(const VP8LMultipliers* const m, uint32_t* data,
int num_pixels) { int num_pixels) {
int i; int i;
for (i = 0; i < num_pixels; ++i) { for (i = 0; i < num_pixels; ++i) {
const uint32_t argb = data[i]; const uint32_t argb = data[i];
const uint32_t green = argb >> 8; const int8_t green = U32ToS8(argb >> 8);
const uint32_t red = argb >> 16; const int8_t red = U32ToS8(argb >> 16);
int new_red = red & 0xff; int new_red = red & 0xff;
int new_blue = argb & 0xff; int new_blue = argb & 0xff;
new_red -= ColorTransformDelta(m->green_to_red_, green); new_red -= ColorTransformDelta(m->green_to_red_, green);
@ -535,7 +539,7 @@ void VP8LTransformColor_C(const VP8LMultipliers* const m, uint32_t* data,
static WEBP_INLINE uint8_t TransformColorRed(uint8_t green_to_red, static WEBP_INLINE uint8_t TransformColorRed(uint8_t green_to_red,
uint32_t argb) { uint32_t argb) {
const uint32_t green = argb >> 8; const int8_t green = U32ToS8(argb >> 8);
int new_red = argb >> 16; int new_red = argb >> 16;
new_red -= ColorTransformDelta(green_to_red, green); new_red -= ColorTransformDelta(green_to_red, green);
return (new_red & 0xff); return (new_red & 0xff);
@ -544,9 +548,9 @@ static WEBP_INLINE uint8_t TransformColorRed(uint8_t green_to_red,
static WEBP_INLINE uint8_t TransformColorBlue(uint8_t green_to_blue, static WEBP_INLINE uint8_t TransformColorBlue(uint8_t green_to_blue,
uint8_t red_to_blue, uint8_t red_to_blue,
uint32_t argb) { uint32_t argb) {
const uint32_t green = argb >> 8; const int8_t green = U32ToS8(argb >> 8);
const uint32_t red = argb >> 16; const int8_t red = U32ToS8(argb >> 16);
uint8_t new_blue = argb; uint8_t new_blue = argb & 0xff;
new_blue -= ColorTransformDelta(green_to_blue, green); new_blue -= ColorTransformDelta(green_to_blue, green);
new_blue -= ColorTransformDelta(red_to_blue, red); new_blue -= ColorTransformDelta(red_to_blue, red);
return (new_blue & 0xff); return (new_blue & 0xff);
@ -558,7 +562,7 @@ void VP8LCollectColorRedTransforms_C(const uint32_t* argb, int stride,
while (tile_height-- > 0) { while (tile_height-- > 0) {
int x; int x;
for (x = 0; x < tile_width; ++x) { for (x = 0; x < tile_width; ++x) {
++histo[TransformColorRed(green_to_red, argb[x])]; ++histo[TransformColorRed((uint8_t)green_to_red, argb[x])];
} }
argb += stride; argb += stride;
} }
@ -571,7 +575,8 @@ void VP8LCollectColorBlueTransforms_C(const uint32_t* argb, int stride,
while (tile_height-- > 0) { while (tile_height-- > 0) {
int x; int x;
for (x = 0; x < tile_width; ++x) { for (x = 0; x < tile_width; ++x) {
++histo[TransformColorBlue(green_to_blue, red_to_blue, argb[x])]; ++histo[TransformColorBlue((uint8_t)green_to_blue, (uint8_t)red_to_blue,
argb[x])];
} }
argb += stride; argb += stride;
} }

@ -363,7 +363,7 @@ static void BundleColorMap_SSE2(const uint8_t* const row, int width, int xbits,
assert(xbits <= 3); assert(xbits <= 3);
switch (xbits) { switch (xbits) {
case 0: { case 0: {
const __m128i ff = _mm_set1_epi16(0xff00); const __m128i ff = _mm_set1_epi16((short)0xff00);
const __m128i zero = _mm_setzero_si128(); const __m128i zero = _mm_setzero_si128();
// Store 0xff000000 | (row[x] << 8). // Store 0xff000000 | (row[x] << 8).
for (x = 0; x + 16 <= width; x += 16, dst += 16) { for (x = 0; x + 16 <= width; x += 16, dst += 16) {
@ -382,7 +382,7 @@ static void BundleColorMap_SSE2(const uint8_t* const row, int width, int xbits,
break; break;
} }
case 1: { case 1: {
const __m128i ff = _mm_set1_epi16(0xff00); const __m128i ff = _mm_set1_epi16((short)0xff00);
const __m128i mul = _mm_set1_epi16(0x110); const __m128i mul = _mm_set1_epi16(0x110);
for (x = 0; x + 16 <= width; x += 16, dst += 8) { for (x = 0; x + 16 <= width; x += 16, dst += 8) {
// 0a0b | (where a/b are 4 bits). // 0a0b | (where a/b are 4 bits).

@ -51,9 +51,9 @@ static void CollectColorBlueTransforms_SSE41(const uint32_t* argb, int stride,
int histo[]) { int histo[]) {
const __m128i mults_r = _mm_set1_epi16(CST_5b(red_to_blue)); const __m128i mults_r = _mm_set1_epi16(CST_5b(red_to_blue));
const __m128i mults_g = _mm_set1_epi16(CST_5b(green_to_blue)); const __m128i mults_g = _mm_set1_epi16(CST_5b(green_to_blue));
const __m128i mask_g = _mm_set1_epi16(0xff00); // green mask const __m128i mask_g = _mm_set1_epi16((short)0xff00); // green mask
const __m128i mask_gb = _mm_set1_epi32(0xffff); // green/blue mask const __m128i mask_gb = _mm_set1_epi32(0xffff); // green/blue mask
const __m128i mask_b = _mm_set1_epi16(0x00ff); // blue mask const __m128i mask_b = _mm_set1_epi16(0x00ff); // blue mask
const __m128i shuffler_lo = _mm_setr_epi8(-1, 2, -1, 6, -1, 10, -1, 14, -1, const __m128i shuffler_lo = _mm_setr_epi8(-1, 2, -1, 6, -1, 10, -1, 14, -1,
-1, -1, -1, -1, -1, -1, -1); -1, -1, -1, -1, -1, -1, -1);
const __m128i shuffler_hi = _mm_setr_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, const __m128i shuffler_hi = _mm_setr_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1,

@ -10,6 +10,8 @@
#ifndef WEBP_DSP_QUANT_H_ #ifndef WEBP_DSP_QUANT_H_
#define WEBP_DSP_QUANT_H_ #define WEBP_DSP_QUANT_H_
#include <string.h>
#include "src/dsp/dsp.h" #include "src/dsp/dsp.h"
#include "src/webp/types.h" #include "src/webp/types.h"
@ -67,4 +69,17 @@ static WEBP_INLINE int IsFlat(const int16_t* levels, int num_blocks,
#endif // defined(WEBP_USE_NEON) && !defined(WEBP_ANDROID_NEON) && #endif // defined(WEBP_USE_NEON) && !defined(WEBP_ANDROID_NEON) &&
// !defined(WEBP_HAVE_NEON_RTCD) // !defined(WEBP_HAVE_NEON_RTCD)
static WEBP_INLINE int IsFlatSource16(const uint8_t* src) {
const uint32_t v = src[0] * 0x01010101u;
int i;
for (i = 0; i < 16; ++i) {
if (memcmp(src + 0, &v, 4) || memcmp(src + 4, &v, 4) ||
memcmp(src + 8, &v, 4) || memcmp(src + 12, &v, 4)) {
return 0;
}
src += BPS;
}
return 1;
}
#endif // WEBP_DSP_QUANT_H_ #endif // WEBP_DSP_QUANT_H_

@ -109,8 +109,7 @@ void WebPRescalerExportRowExpand_C(WebPRescaler* const wrk) {
for (x_out = 0; x_out < x_out_max; ++x_out) { for (x_out = 0; x_out < x_out_max; ++x_out) {
const uint32_t J = frow[x_out]; const uint32_t J = frow[x_out];
const int v = (int)MULT_FIX(J, wrk->fy_scale); const int v = (int)MULT_FIX(J, wrk->fy_scale);
assert(v >= 0 && v <= 255); dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
dst[x_out] = v;
} }
} else { } else {
const uint32_t B = WEBP_RESCALER_FRAC(-wrk->y_accum, wrk->y_sub); const uint32_t B = WEBP_RESCALER_FRAC(-wrk->y_accum, wrk->y_sub);
@ -120,8 +119,7 @@ void WebPRescalerExportRowExpand_C(WebPRescaler* const wrk) {
+ (uint64_t)B * irow[x_out]; + (uint64_t)B * irow[x_out];
const uint32_t J = (uint32_t)((I + ROUNDER) >> WEBP_RESCALER_RFIX); const uint32_t J = (uint32_t)((I + ROUNDER) >> WEBP_RESCALER_RFIX);
const int v = (int)MULT_FIX(J, wrk->fy_scale); const int v = (int)MULT_FIX(J, wrk->fy_scale);
assert(v >= 0 && v <= 255); dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
dst[x_out] = v;
} }
} }
} }
@ -138,17 +136,15 @@ void WebPRescalerExportRowShrink_C(WebPRescaler* const wrk) {
assert(!wrk->y_expand); assert(!wrk->y_expand);
if (yscale) { if (yscale) {
for (x_out = 0; x_out < x_out_max; ++x_out) { for (x_out = 0; x_out < x_out_max; ++x_out) {
const uint32_t frac = (uint32_t)MULT_FIX(frow[x_out], yscale); const uint32_t frac = (uint32_t)MULT_FIX_FLOOR(frow[x_out], yscale);
const int v = (int)MULT_FIX_FLOOR(irow[x_out] - frac, wrk->fxy_scale); const int v = (int)MULT_FIX(irow[x_out] - frac, wrk->fxy_scale);
assert(v >= 0 && v <= 255); dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
dst[x_out] = v;
irow[x_out] = frac; // new fractional start irow[x_out] = frac; // new fractional start
} }
} else { } else {
for (x_out = 0; x_out < x_out_max; ++x_out) { for (x_out = 0; x_out < x_out_max; ++x_out) {
const int v = (int)MULT_FIX(irow[x_out], wrk->fxy_scale); const int v = (int)MULT_FIX(irow[x_out], wrk->fxy_scale);
assert(v >= 0 && v <= 255); dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
dst[x_out] = v;
irow[x_out] = 0; irow[x_out] = 0;
} }
} }

@ -107,10 +107,9 @@ static void ExportRowShrink_MIPSdspR2(WebPRescaler* const wrk) {
); );
} }
for (i = 0; i < (x_out_max & 0x3); ++i) { for (i = 0; i < (x_out_max & 0x3); ++i) {
const uint32_t frac = (uint32_t)MULT_FIX(*frow++, yscale); const uint32_t frac = (uint32_t)MULT_FIX_FLOOR(*frow++, yscale);
const int v = (int)MULT_FIX_FLOOR(*irow - frac, wrk->fxy_scale); const int v = (int)MULT_FIX(*irow - frac, wrk->fxy_scale);
assert(v >= 0 && v <= 255); *dst++ = (v > 255) ? 255u : (uint8_t)v;
*dst++ = v;
*irow++ = frac; // new fractional start *irow++ = frac; // new fractional start
} }
} else { } else {
@ -157,8 +156,7 @@ static void ExportRowShrink_MIPSdspR2(WebPRescaler* const wrk) {
} }
for (i = 0; i < (x_out_max & 0x3); ++i) { for (i = 0; i < (x_out_max & 0x3); ++i) {
const int v = (int)MULT_FIX_FLOOR(*irow, wrk->fxy_scale); const int v = (int)MULT_FIX_FLOOR(*irow, wrk->fxy_scale);
assert(v >= 0 && v <= 255); *dst++ = (v > 255) ? 255u : (uint8_t)v;
*dst++ = v;
*irow++ = 0; *irow++ = 0;
} }
} }
@ -219,8 +217,7 @@ static void ExportRowExpand_MIPSdspR2(WebPRescaler* const wrk) {
for (i = 0; i < (x_out_max & 0x3); ++i) { for (i = 0; i < (x_out_max & 0x3); ++i) {
const uint32_t J = *frow++; const uint32_t J = *frow++;
const int v = (int)MULT_FIX(J, wrk->fy_scale); const int v = (int)MULT_FIX(J, wrk->fy_scale);
assert(v >= 0 && v <= 255); *dst++ = (v > 255) ? 255u : (uint8_t)v;
*dst++ = v;
} }
} else { } else {
const uint32_t B = WEBP_RESCALER_FRAC(-wrk->y_accum, wrk->y_sub); const uint32_t B = WEBP_RESCALER_FRAC(-wrk->y_accum, wrk->y_sub);
@ -291,8 +288,7 @@ static void ExportRowExpand_MIPSdspR2(WebPRescaler* const wrk) {
+ (uint64_t)B * *irow++; + (uint64_t)B * *irow++;
const uint32_t J = (uint32_t)((I + ROUNDER) >> WEBP_RESCALER_RFIX); const uint32_t J = (uint32_t)((I + ROUNDER) >> WEBP_RESCALER_RFIX);
const int v = (int)MULT_FIX(J, wrk->fy_scale); const int v = (int)MULT_FIX(J, wrk->fy_scale);
assert(v >= 0 && v <= 255); *dst++ = (v > 255) ? 255u : (uint8_t)v;
*dst++ = v;
} }
} }
} }

@ -166,8 +166,7 @@ static WEBP_INLINE void ExportRowExpand_0(const uint32_t* frow, uint8_t* dst,
for (x_out = 0; x_out < length; ++x_out) { for (x_out = 0; x_out < length; ++x_out) {
const uint32_t J = frow[x_out]; const uint32_t J = frow[x_out];
const int v = (int)MULT_FIX(J, wrk->fy_scale); const int v = (int)MULT_FIX(J, wrk->fy_scale);
assert(v >= 0 && v <= 255); dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
dst[x_out] = v;
} }
} }
} }
@ -241,8 +240,7 @@ static WEBP_INLINE void ExportRowExpand_1(const uint32_t* frow, uint32_t* irow,
+ (uint64_t)B * irow[x_out]; + (uint64_t)B * irow[x_out];
const uint32_t J = (uint32_t)((I + ROUNDER) >> WEBP_RESCALER_RFIX); const uint32_t J = (uint32_t)((I + ROUNDER) >> WEBP_RESCALER_RFIX);
const int v = (int)MULT_FIX(J, wrk->fy_scale); const int v = (int)MULT_FIX(J, wrk->fy_scale);
assert(v >= 0 && v <= 255); dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
dst[x_out] = v;
} }
} }
} }
@ -342,10 +340,9 @@ static WEBP_INLINE void ExportRowShrink_0(const uint32_t* frow, uint32_t* irow,
length -= 4; length -= 4;
} }
for (x_out = 0; x_out < length; ++x_out) { for (x_out = 0; x_out < length; ++x_out) {
const uint32_t frac = (uint32_t)MULT_FIX(frow[x_out], yscale); const uint32_t frac = (uint32_t)MULT_FIX_FLOOR(frow[x_out], yscale);
const int v = (int)MULT_FIX_FLOOR(irow[x_out] - frac, wrk->fxy_scale); const int v = (int)MULT_FIX(irow[x_out] - frac, wrk->fxy_scale);
assert(v >= 0 && v <= 255); dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
dst[x_out] = v;
irow[x_out] = frac; irow[x_out] = frac;
} }
} }
@ -406,8 +403,7 @@ static WEBP_INLINE void ExportRowShrink_1(uint32_t* irow, uint8_t* dst,
} }
for (x_out = 0; x_out < length; ++x_out) { for (x_out = 0; x_out < length; ++x_out) {
const int v = (int)MULT_FIX(irow[x_out], wrk->fxy_scale); const int v = (int)MULT_FIX(irow[x_out], wrk->fxy_scale);
assert(v >= 0 && v <= 255); dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
dst[x_out] = v;
irow[x_out] = 0; irow[x_out] = 0;
} }
} }

@ -81,14 +81,13 @@ static void RescalerExportRowExpand_NEON(WebPRescaler* const wrk) {
const uint32x4_t B1 = MULT_FIX(A1, fy_scale_half); const uint32x4_t B1 = MULT_FIX(A1, fy_scale_half);
const uint16x4_t C0 = vmovn_u32(B0); const uint16x4_t C0 = vmovn_u32(B0);
const uint16x4_t C1 = vmovn_u32(B1); const uint16x4_t C1 = vmovn_u32(B1);
const uint8x8_t D = vmovn_u16(vcombine_u16(C0, C1)); const uint8x8_t D = vqmovn_u16(vcombine_u16(C0, C1));
vst1_u8(dst + x_out, D); vst1_u8(dst + x_out, D);
} }
for (; x_out < x_out_max; ++x_out) { for (; x_out < x_out_max; ++x_out) {
const uint32_t J = frow[x_out]; const uint32_t J = frow[x_out];
const int v = (int)MULT_FIX_C(J, fy_scale); const int v = (int)MULT_FIX_C(J, fy_scale);
assert(v >= 0 && v <= 255); dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
dst[x_out] = v;
} }
} else { } else {
const uint32_t B = WEBP_RESCALER_FRAC(-wrk->y_accum, wrk->y_sub); const uint32_t B = WEBP_RESCALER_FRAC(-wrk->y_accum, wrk->y_sub);
@ -102,7 +101,7 @@ static void RescalerExportRowExpand_NEON(WebPRescaler* const wrk) {
const uint32x4_t D1 = MULT_FIX(C1, fy_scale_half); const uint32x4_t D1 = MULT_FIX(C1, fy_scale_half);
const uint16x4_t E0 = vmovn_u32(D0); const uint16x4_t E0 = vmovn_u32(D0);
const uint16x4_t E1 = vmovn_u32(D1); const uint16x4_t E1 = vmovn_u32(D1);
const uint8x8_t F = vmovn_u16(vcombine_u16(E0, E1)); const uint8x8_t F = vqmovn_u16(vcombine_u16(E0, E1));
vst1_u8(dst + x_out, F); vst1_u8(dst + x_out, F);
} }
for (; x_out < x_out_max; ++x_out) { for (; x_out < x_out_max; ++x_out) {
@ -110,8 +109,7 @@ static void RescalerExportRowExpand_NEON(WebPRescaler* const wrk) {
+ (uint64_t)B * irow[x_out]; + (uint64_t)B * irow[x_out];
const uint32_t J = (uint32_t)((I + ROUNDER) >> WEBP_RESCALER_RFIX); const uint32_t J = (uint32_t)((I + ROUNDER) >> WEBP_RESCALER_RFIX);
const int v = (int)MULT_FIX_C(J, fy_scale); const int v = (int)MULT_FIX_C(J, fy_scale);
assert(v >= 0 && v <= 255); dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
dst[x_out] = v;
} }
} }
} }
@ -135,23 +133,22 @@ static void RescalerExportRowShrink_NEON(WebPRescaler* const wrk) {
for (x_out = 0; x_out < max_span; x_out += 8) { for (x_out = 0; x_out < max_span; x_out += 8) {
LOAD_32x8(frow + x_out, in0, in1); LOAD_32x8(frow + x_out, in0, in1);
LOAD_32x8(irow + x_out, in2, in3); LOAD_32x8(irow + x_out, in2, in3);
const uint32x4_t A0 = MULT_FIX(in0, yscale_half); const uint32x4_t A0 = MULT_FIX_FLOOR(in0, yscale_half);
const uint32x4_t A1 = MULT_FIX(in1, yscale_half); const uint32x4_t A1 = MULT_FIX_FLOOR(in1, yscale_half);
const uint32x4_t B0 = vqsubq_u32(in2, A0); const uint32x4_t B0 = vqsubq_u32(in2, A0);
const uint32x4_t B1 = vqsubq_u32(in3, A1); const uint32x4_t B1 = vqsubq_u32(in3, A1);
const uint32x4_t C0 = MULT_FIX_FLOOR(B0, fxy_scale_half); const uint32x4_t C0 = MULT_FIX(B0, fxy_scale_half);
const uint32x4_t C1 = MULT_FIX_FLOOR(B1, fxy_scale_half); const uint32x4_t C1 = MULT_FIX(B1, fxy_scale_half);
const uint16x4_t D0 = vmovn_u32(C0); const uint16x4_t D0 = vmovn_u32(C0);
const uint16x4_t D1 = vmovn_u32(C1); const uint16x4_t D1 = vmovn_u32(C1);
const uint8x8_t E = vmovn_u16(vcombine_u16(D0, D1)); const uint8x8_t E = vqmovn_u16(vcombine_u16(D0, D1));
vst1_u8(dst + x_out, E); vst1_u8(dst + x_out, E);
STORE_32x8(A0, A1, irow + x_out); STORE_32x8(A0, A1, irow + x_out);
} }
for (; x_out < x_out_max; ++x_out) { for (; x_out < x_out_max; ++x_out) {
const uint32_t frac = (uint32_t)MULT_FIX_C(frow[x_out], yscale); const uint32_t frac = (uint32_t)MULT_FIX_FLOOR_C(frow[x_out], yscale);
const int v = (int)MULT_FIX_FLOOR_C(irow[x_out] - frac, fxy_scale); const int v = (int)MULT_FIX_C(irow[x_out] - frac, fxy_scale);
assert(v >= 0 && v <= 255); dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
dst[x_out] = v;
irow[x_out] = frac; // new fractional start irow[x_out] = frac; // new fractional start
} }
} else { } else {
@ -161,14 +158,13 @@ static void RescalerExportRowShrink_NEON(WebPRescaler* const wrk) {
const uint32x4_t A1 = MULT_FIX(in1, fxy_scale_half); const uint32x4_t A1 = MULT_FIX(in1, fxy_scale_half);
const uint16x4_t B0 = vmovn_u32(A0); const uint16x4_t B0 = vmovn_u32(A0);
const uint16x4_t B1 = vmovn_u32(A1); const uint16x4_t B1 = vmovn_u32(A1);
const uint8x8_t C = vmovn_u16(vcombine_u16(B0, B1)); const uint8x8_t C = vqmovn_u16(vcombine_u16(B0, B1));
vst1_u8(dst + x_out, C); vst1_u8(dst + x_out, C);
STORE_32x8(zero, zero, irow + x_out); STORE_32x8(zero, zero, irow + x_out);
} }
for (; x_out < x_out_max; ++x_out) { for (; x_out < x_out_max; ++x_out) {
const int v = (int)MULT_FIX_C(irow[x_out], fxy_scale); const int v = (int)MULT_FIX_C(irow[x_out], fxy_scale);
assert(v >= 0 && v <= 255); dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
dst[x_out] = v;
irow[x_out] = 0; irow[x_out] = 0;
} }
} }

@ -225,35 +225,6 @@ static WEBP_INLINE void ProcessRow_SSE2(const __m128i* const A0,
_mm_storel_epi64((__m128i*)dst, G); _mm_storel_epi64((__m128i*)dst, G);
} }
static WEBP_INLINE void ProcessRow_Floor_SSE2(const __m128i* const A0,
const __m128i* const A1,
const __m128i* const A2,
const __m128i* const A3,
const __m128i* const mult,
uint8_t* const dst) {
const __m128i mask = _mm_set_epi32(0xffffffffu, 0, 0xffffffffu, 0);
const __m128i B0 = _mm_mul_epu32(*A0, *mult);
const __m128i B1 = _mm_mul_epu32(*A1, *mult);
const __m128i B2 = _mm_mul_epu32(*A2, *mult);
const __m128i B3 = _mm_mul_epu32(*A3, *mult);
const __m128i D0 = _mm_srli_epi64(B0, WEBP_RESCALER_RFIX);
const __m128i D1 = _mm_srli_epi64(B1, WEBP_RESCALER_RFIX);
#if (WEBP_RESCALER_RFIX < 32)
const __m128i D2 =
_mm_and_si128(_mm_slli_epi64(B2, 32 - WEBP_RESCALER_RFIX), mask);
const __m128i D3 =
_mm_and_si128(_mm_slli_epi64(B3, 32 - WEBP_RESCALER_RFIX), mask);
#else
const __m128i D2 = _mm_and_si128(B2, mask);
const __m128i D3 = _mm_and_si128(B3, mask);
#endif
const __m128i E0 = _mm_or_si128(D0, D2);
const __m128i E1 = _mm_or_si128(D1, D3);
const __m128i F = _mm_packs_epi32(E0, E1);
const __m128i G = _mm_packus_epi16(F, F);
_mm_storel_epi64((__m128i*)dst, G);
}
static void RescalerExportRowExpand_SSE2(WebPRescaler* const wrk) { static void RescalerExportRowExpand_SSE2(WebPRescaler* const wrk) {
int x_out; int x_out;
uint8_t* const dst = wrk->dst; uint8_t* const dst = wrk->dst;
@ -274,8 +245,7 @@ static void RescalerExportRowExpand_SSE2(WebPRescaler* const wrk) {
for (; x_out < x_out_max; ++x_out) { for (; x_out < x_out_max; ++x_out) {
const uint32_t J = frow[x_out]; const uint32_t J = frow[x_out];
const int v = (int)MULT_FIX(J, wrk->fy_scale); const int v = (int)MULT_FIX(J, wrk->fy_scale);
assert(v >= 0 && v <= 255); dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
dst[x_out] = v;
} }
} else { } else {
const uint32_t B = WEBP_RESCALER_FRAC(-wrk->y_accum, wrk->y_sub); const uint32_t B = WEBP_RESCALER_FRAC(-wrk->y_accum, wrk->y_sub);
@ -308,8 +278,7 @@ static void RescalerExportRowExpand_SSE2(WebPRescaler* const wrk) {
+ (uint64_t)B * irow[x_out]; + (uint64_t)B * irow[x_out];
const uint32_t J = (uint32_t)((I + ROUNDER) >> WEBP_RESCALER_RFIX); const uint32_t J = (uint32_t)((I + ROUNDER) >> WEBP_RESCALER_RFIX);
const int v = (int)MULT_FIX(J, wrk->fy_scale); const int v = (int)MULT_FIX(J, wrk->fy_scale);
assert(v >= 0 && v <= 255); dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
dst[x_out] = v;
} }
} }
} }
@ -328,20 +297,15 @@ static void RescalerExportRowShrink_SSE2(WebPRescaler* const wrk) {
const int scale_xy = wrk->fxy_scale; const int scale_xy = wrk->fxy_scale;
const __m128i mult_xy = _mm_set_epi32(0, scale_xy, 0, scale_xy); const __m128i mult_xy = _mm_set_epi32(0, scale_xy, 0, scale_xy);
const __m128i mult_y = _mm_set_epi32(0, yscale, 0, yscale); const __m128i mult_y = _mm_set_epi32(0, yscale, 0, yscale);
const __m128i rounder = _mm_set_epi32(0, ROUNDER, 0, ROUNDER);
for (x_out = 0; x_out + 8 <= x_out_max; x_out += 8) { for (x_out = 0; x_out + 8 <= x_out_max; x_out += 8) {
__m128i A0, A1, A2, A3, B0, B1, B2, B3; __m128i A0, A1, A2, A3, B0, B1, B2, B3;
LoadDispatchAndMult_SSE2(irow + x_out, NULL, &A0, &A1, &A2, &A3); LoadDispatchAndMult_SSE2(irow + x_out, NULL, &A0, &A1, &A2, &A3);
LoadDispatchAndMult_SSE2(frow + x_out, &mult_y, &B0, &B1, &B2, &B3); LoadDispatchAndMult_SSE2(frow + x_out, &mult_y, &B0, &B1, &B2, &B3);
{ {
const __m128i C0 = _mm_add_epi64(B0, rounder); const __m128i D0 = _mm_srli_epi64(B0, WEBP_RESCALER_RFIX); // = frac
const __m128i C1 = _mm_add_epi64(B1, rounder); const __m128i D1 = _mm_srli_epi64(B1, WEBP_RESCALER_RFIX);
const __m128i C2 = _mm_add_epi64(B2, rounder); const __m128i D2 = _mm_srli_epi64(B2, WEBP_RESCALER_RFIX);
const __m128i C3 = _mm_add_epi64(B3, rounder); const __m128i D3 = _mm_srli_epi64(B3, WEBP_RESCALER_RFIX);
const __m128i D0 = _mm_srli_epi64(C0, WEBP_RESCALER_RFIX); // = frac
const __m128i D1 = _mm_srli_epi64(C1, WEBP_RESCALER_RFIX);
const __m128i D2 = _mm_srli_epi64(C2, WEBP_RESCALER_RFIX);
const __m128i D3 = _mm_srli_epi64(C3, WEBP_RESCALER_RFIX);
const __m128i E0 = _mm_sub_epi64(A0, D0); // irow[x] - frac const __m128i E0 = _mm_sub_epi64(A0, D0); // irow[x] - frac
const __m128i E1 = _mm_sub_epi64(A1, D1); const __m128i E1 = _mm_sub_epi64(A1, D1);
const __m128i E2 = _mm_sub_epi64(A2, D2); const __m128i E2 = _mm_sub_epi64(A2, D2);
@ -352,14 +316,13 @@ static void RescalerExportRowShrink_SSE2(WebPRescaler* const wrk) {
const __m128i G1 = _mm_or_si128(D1, F3); const __m128i G1 = _mm_or_si128(D1, F3);
_mm_storeu_si128((__m128i*)(irow + x_out + 0), G0); _mm_storeu_si128((__m128i*)(irow + x_out + 0), G0);
_mm_storeu_si128((__m128i*)(irow + x_out + 4), G1); _mm_storeu_si128((__m128i*)(irow + x_out + 4), G1);
ProcessRow_Floor_SSE2(&E0, &E1, &E2, &E3, &mult_xy, dst + x_out); ProcessRow_SSE2(&E0, &E1, &E2, &E3, &mult_xy, dst + x_out);
} }
} }
for (; x_out < x_out_max; ++x_out) { for (; x_out < x_out_max; ++x_out) {
const uint32_t frac = (int)MULT_FIX(frow[x_out], yscale); const uint32_t frac = (int)MULT_FIX_FLOOR(frow[x_out], yscale);
const int v = (int)MULT_FIX_FLOOR(irow[x_out] - frac, wrk->fxy_scale); const int v = (int)MULT_FIX(irow[x_out] - frac, wrk->fxy_scale);
assert(v >= 0 && v <= 255); dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
dst[x_out] = v;
irow[x_out] = frac; // new fractional start irow[x_out] = frac; // new fractional start
} }
} else { } else {
@ -375,8 +338,7 @@ static void RescalerExportRowShrink_SSE2(WebPRescaler* const wrk) {
} }
for (; x_out < x_out_max; ++x_out) { for (; x_out < x_out_max; ++x_out) {
const int v = (int)MULT_FIX(irow[x_out], scale); const int v = (int)MULT_FIX(irow[x_out], scale);
assert(v >= 0 && v <= 255); dst[x_out] = (v > 255) ? 255u : (uint8_t)v;
dst[x_out] = v;
irow[x_out] = 0; irow[x_out] = 0;
} }
} }

@ -191,13 +191,14 @@ void VP8LHashChainClear(VP8LHashChain* const p) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#define HASH_MULTIPLIER_HI (0xc6a4a793ULL) static const uint32_t kHashMultiplierHi = 0xc6a4a793u;
#define HASH_MULTIPLIER_LO (0x5bd1e996ULL) static const uint32_t kHashMultiplierLo = 0x5bd1e996u;
static WEBP_INLINE uint32_t GetPixPairHash64(const uint32_t* const argb) { static WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW WEBP_INLINE
uint32_t GetPixPairHash64(const uint32_t* const argb) {
uint32_t key; uint32_t key;
key = (argb[1] * HASH_MULTIPLIER_HI) & 0xffffffffu; key = argb[1] * kHashMultiplierHi;
key += (argb[0] * HASH_MULTIPLIER_LO) & 0xffffffffu; key += argb[0] * kHashMultiplierLo;
key = key >> (32 - HASH_BITS); key = key >> (32 - HASH_BITS);
return key; return key;
} }

@ -929,9 +929,8 @@ static int HistogramCombineStochastic(VP8LHistogramSet* const image_histo,
} }
mappings = (int*) WebPSafeMalloc(*num_used, sizeof(*mappings)); mappings = (int*) WebPSafeMalloc(*num_used, sizeof(*mappings));
if (mappings == NULL || !HistoQueueInit(&histo_queue, kHistoQueueSize)) { if (mappings == NULL) return 0;
goto End; if (!HistoQueueInit(&histo_queue, kHistoQueueSize)) goto End;
}
// Fill the initial mapping. // Fill the initial mapping.
for (j = 0, iter = 0; iter < image_histo->size; ++iter) { for (j = 0, iter = 0; iter < image_histo->size; ++iter) {
if (histograms[iter] == NULL) continue; if (histograms[iter] == NULL) continue;

@ -202,7 +202,7 @@ static uint32_t NearLossless(uint32_t value, uint32_t predict,
} }
if ((value >> 24) == 0 || (value >> 24) == 0xff) { if ((value >> 24) == 0 || (value >> 24) == 0xff) {
// Preserve transparency of fully transparent or fully opaque pixels. // Preserve transparency of fully transparent or fully opaque pixels.
a = NearLosslessDiff(value >> 24, predict >> 24); a = NearLosslessDiff((value >> 24) & 0xff, (predict >> 24) & 0xff);
} else { } else {
a = NearLosslessComponent(value >> 24, predict >> 24, 0xff, quantization); a = NearLosslessComponent(value >> 24, predict >> 24, 0xff, quantization);
} }
@ -215,12 +215,12 @@ static uint32_t NearLossless(uint32_t value, uint32_t predict,
// The amount by which green has been adjusted during quantization. It is // The amount by which green has been adjusted during quantization. It is
// subtracted from red and blue for compensation, to avoid accumulating two // subtracted from red and blue for compensation, to avoid accumulating two
// quantization errors in them. // quantization errors in them.
green_diff = NearLosslessDiff(new_green, value >> 8); green_diff = NearLosslessDiff(new_green, (value >> 8) & 0xff);
} }
r = NearLosslessComponent(NearLosslessDiff(value >> 16, green_diff), r = NearLosslessComponent(NearLosslessDiff((value >> 16) & 0xff, green_diff),
(predict >> 16) & 0xff, 0xff - new_green, (predict >> 16) & 0xff, 0xff - new_green,
quantization); quantization);
b = NearLosslessComponent(NearLosslessDiff(value, green_diff), b = NearLosslessComponent(NearLosslessDiff(value & 0xff, green_diff),
predict & 0xff, 0xff - new_green, quantization); predict & 0xff, 0xff - new_green, quantization);
return ((uint32_t)a << 24) | ((uint32_t)r << 16) | ((uint32_t)g << 8) | b; return ((uint32_t)a << 24) | ((uint32_t)r << 16) | ((uint32_t)g << 8) | b;
} }
@ -587,7 +587,7 @@ static void GetBestGreenToRed(
} }
} }
} }
best_tx->green_to_red_ = green_to_red_best; best_tx->green_to_red_ = (green_to_red_best & 0xff);
} }
static float GetPredictionCostCrossColorBlue( static float GetPredictionCostCrossColorBlue(
@ -666,8 +666,8 @@ static void GetBestGreenRedToBlue(
break; // out of iter-loop. break; // out of iter-loop.
} }
} }
best_tx->green_to_blue_ = green_to_blue_best; best_tx->green_to_blue_ = green_to_blue_best & 0xff;
best_tx->red_to_blue_ = red_to_blue_best; best_tx->red_to_blue_ = red_to_blue_best & 0xff;
} }
#undef kGreenRedToBlueMaxIters #undef kGreenRedToBlueMaxIters
#undef kGreenRedToBlueNumAxis #undef kGreenRedToBlueNumAxis

@ -33,7 +33,7 @@
// number of non-zero coeffs below which we consider the block very flat // number of non-zero coeffs below which we consider the block very flat
// (and apply a penalty to complex predictions) // (and apply a penalty to complex predictions)
#define FLATNESS_LIMIT_I16 10 // I16 mode #define FLATNESS_LIMIT_I16 0 // I16 mode (special case)
#define FLATNESS_LIMIT_I4 3 // I4 mode #define FLATNESS_LIMIT_I4 3 // I4 mode
#define FLATNESS_LIMIT_UV 2 // UV mode #define FLATNESS_LIMIT_UV 2 // UV mode
#define FLATNESS_PENALTY 140 // roughly ~1bit per block #define FLATNESS_PENALTY 140 // roughly ~1bit per block
@ -988,6 +988,7 @@ static void PickBestIntra16(VP8EncIterator* const it, VP8ModeScore* rd) {
VP8ModeScore* rd_cur = &rd_tmp; VP8ModeScore* rd_cur = &rd_tmp;
VP8ModeScore* rd_best = rd; VP8ModeScore* rd_best = rd;
int mode; int mode;
int is_flat = IsFlatSource16(it->yuv_in_ + Y_OFF_ENC);
rd->mode_i16 = -1; rd->mode_i16 = -1;
for (mode = 0; mode < NUM_PRED_MODES; ++mode) { for (mode = 0; mode < NUM_PRED_MODES; ++mode) {
@ -1003,10 +1004,14 @@ static void PickBestIntra16(VP8EncIterator* const it, VP8ModeScore* rd) {
tlambda ? MULT_8B(tlambda, VP8TDisto16x16(src, tmp_dst, kWeightY)) : 0; tlambda ? MULT_8B(tlambda, VP8TDisto16x16(src, tmp_dst, kWeightY)) : 0;
rd_cur->H = VP8FixedCostsI16[mode]; rd_cur->H = VP8FixedCostsI16[mode];
rd_cur->R = VP8GetCostLuma16(it, rd_cur); rd_cur->R = VP8GetCostLuma16(it, rd_cur);
if (mode > 0 && if (is_flat) {
IsFlat(rd_cur->y_ac_levels[0], kNumBlocks, FLATNESS_LIMIT_I16)) { // refine the first impression (which was in pixel space)
// penalty to avoid flat area to be mispredicted by complex mode is_flat = IsFlat(rd_cur->y_ac_levels[0], kNumBlocks, FLATNESS_LIMIT_I16);
rd_cur->R += FLATNESS_PENALTY * kNumBlocks; if (is_flat) {
// Block is very flat. We put emphasis on the distortion being very low!
rd_cur->D *= 2;
rd_cur->SD *= 2;
}
} }
// Since we always examine Intra16 first, we can overwrite *rd directly. // Since we always examine Intra16 first, we can overwrite *rd directly.
@ -1087,7 +1092,8 @@ static int PickBestIntra4(VP8EncIterator* const it, VP8ModeScore* const rd) {
: 0; : 0;
rd_tmp.H = mode_costs[mode]; rd_tmp.H = mode_costs[mode];
// Add flatness penalty // Add flatness penalty, to avoid flat area to be mispredicted
// by a complex mode.
if (mode > 0 && IsFlat(tmp_levels, kNumBlocks, FLATNESS_LIMIT_I4)) { if (mode > 0 && IsFlat(tmp_levels, kNumBlocks, FLATNESS_LIMIT_I4)) {
rd_tmp.R = FLATNESS_PENALTY * kNumBlocks; rd_tmp.R = FLATNESS_PENALTY * kNumBlocks;
} else { } else {
@ -1242,11 +1248,19 @@ static void RefineUsingDistortion(VP8EncIterator* const it,
if (mode > 0 && VP8FixedCostsI16[mode] > bit_limit) { if (mode > 0 && VP8FixedCostsI16[mode] > bit_limit) {
continue; continue;
} }
if (score < best_score) { if (score < best_score) {
best_mode = mode; best_mode = mode;
best_score = score; best_score = score;
} }
} }
if (it->x_ == 0 || it->y_ == 0) {
// avoid starting a checkerboard resonance from the border. See bug #432.
if (IsFlatSource16(src)) {
best_mode = (it->x_ == 0) ? 0 : 2;
try_both_modes = 0; // stick to i16
}
}
VP8SetIntra16Mode(it, best_mode); VP8SetIntra16Mode(it, best_mode);
// we'll reconstruct later, if i16 mode actually gets selected // we'll reconstruct later, if i16 mode actually gets selected
} }

@ -32,7 +32,7 @@ extern "C" {
// version numbers // version numbers
#define ENC_MAJ_VERSION 1 #define ENC_MAJ_VERSION 1
#define ENC_MIN_VERSION 0 #define ENC_MIN_VERSION 0
#define ENC_REV_VERSION 2 #define ENC_REV_VERSION 3
enum { MAX_LF_LEVELS = 64, // Maximum loop filter level enum { MAX_LF_LEVELS = 64, // Maximum loop filter level
MAX_VARIABLE_LEVEL = 67, // last (inclusive) level with variable cost MAX_VARIABLE_LEVEL = 67, // last (inclusive) level with variable cost

@ -29,7 +29,7 @@ extern "C" {
#define MUX_MAJ_VERSION 1 #define MUX_MAJ_VERSION 1
#define MUX_MIN_VERSION 0 #define MUX_MIN_VERSION 0
#define MUX_REV_VERSION 2 #define MUX_REV_VERSION 3
// Chunk object. // Chunk object.
typedef struct WebPChunk WebPChunk; typedef struct WebPChunk WebPChunk;

@ -104,7 +104,8 @@ void VP8LoadNewBytes(VP8BitReader* const br) {
} }
// Read a bit with proba 'prob'. Speed-critical function! // Read a bit with proba 'prob'. Speed-critical function!
static WEBP_INLINE int VP8GetBit(VP8BitReader* const br, int prob) { static WEBP_INLINE int VP8GetBit(VP8BitReader* const br,
int prob, const char label[]) {
// Don't move this declaration! It makes a big speed difference to store // Don't move this declaration! It makes a big speed difference to store
// 'range' *before* calling VP8LoadNewBytes(), even if this function doesn't // 'range' *before* calling VP8LoadNewBytes(), even if this function doesn't
// alter br->range_ value. // alter br->range_ value.
@ -129,13 +130,14 @@ static WEBP_INLINE int VP8GetBit(VP8BitReader* const br, int prob) {
br->bits_ -= shift; br->bits_ -= shift;
} }
br->range_ = range - 1; br->range_ = range - 1;
BT_TRACK(br);
return bit; return bit;
} }
} }
// simplified version of VP8GetBit() for prob=0x80 (note shift is always 1 here) // simplified version of VP8GetBit() for prob=0x80 (note shift is always 1 here)
static WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW WEBP_INLINE static WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW WEBP_INLINE
int VP8GetSigned(VP8BitReader* const br, int v) { int VP8GetSigned(VP8BitReader* const br, int v, const char label[]) {
if (br->bits_ < 0) { if (br->bits_ < 0) {
VP8LoadNewBytes(br); VP8LoadNewBytes(br);
} }
@ -148,11 +150,13 @@ int VP8GetSigned(VP8BitReader* const br, int v) {
br->range_ += mask; br->range_ += mask;
br->range_ |= 1; br->range_ |= 1;
br->value_ -= (bit_t)((split + 1) & mask) << pos; br->value_ -= (bit_t)((split + 1) & mask) << pos;
BT_TRACK(br);
return (v ^ mask) - mask; return (v ^ mask) - mask;
} }
} }
static WEBP_INLINE int VP8GetBitAlt(VP8BitReader* const br, int prob) { static WEBP_INLINE int VP8GetBitAlt(VP8BitReader* const br,
int prob, const char label[]) {
// Don't move this declaration! It makes a big speed difference to store // Don't move this declaration! It makes a big speed difference to store
// 'range' *before* calling VP8LoadNewBytes(), even if this function doesn't // 'range' *before* calling VP8LoadNewBytes(), even if this function doesn't
// alter br->range_ value. // alter br->range_ value.
@ -179,6 +183,7 @@ static WEBP_INLINE int VP8GetBitAlt(VP8BitReader* const br, int prob) {
br->bits_ -= shift; br->bits_ -= shift;
} }
br->range_ = range; br->range_ = range;
BT_TRACK(br);
return bit; return bit;
} }
} }

@ -102,17 +102,18 @@ void VP8LoadFinalBytes(VP8BitReader* const br) {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Higher-level calls // Higher-level calls
uint32_t VP8GetValue(VP8BitReader* const br, int bits) { uint32_t VP8GetValue(VP8BitReader* const br, int bits, const char label[]) {
uint32_t v = 0; uint32_t v = 0;
while (bits-- > 0) { while (bits-- > 0) {
v |= VP8GetBit(br, 0x80) << bits; v |= VP8GetBit(br, 0x80, label) << bits;
} }
return v; return v;
} }
int32_t VP8GetSignedValue(VP8BitReader* const br, int bits) { int32_t VP8GetSignedValue(VP8BitReader* const br, int bits,
const int value = VP8GetValue(br, bits); const char label[]) {
return VP8Get(br) ? -value : value; const int value = VP8GetValue(br, bits, label);
return VP8Get(br, label) ? -value : value;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -220,3 +221,78 @@ uint32_t VP8LReadBits(VP8LBitReader* const br, int n_bits) {
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Bit-tracing tool
#if (BITTRACE > 0)
#include <stdlib.h> // for atexit()
#include <stdio.h>
#include <string.h>
#define MAX_NUM_LABELS 32
static struct {
const char* label;
int size;
int count;
} kLabels[MAX_NUM_LABELS];
static int last_label = 0;
static int last_pos = 0;
static const uint8_t* buf_start = NULL;
static int init_done = 0;
static void PrintBitTraces(void) {
int i;
int scale = 1;
int total = 0;
const char* units = "bits";
#if (BITTRACE == 2)
scale = 8;
units = "bytes";
#endif
for (i = 0; i < last_label; ++i) total += kLabels[i].size;
if (total < 1) total = 1; // avoid rounding errors
printf("=== Bit traces ===\n");
for (i = 0; i < last_label; ++i) {
const int skip = 16 - (int)strlen(kLabels[i].label);
const int value = (kLabels[i].size + scale - 1) / scale;
assert(skip > 0);
printf("%s \%*s: %6d %s \t[%5.2f%%] [count: %7d]\n",
kLabels[i].label, skip, "", value, units,
100.f * kLabels[i].size / total,
kLabels[i].count);
}
total = (total + scale - 1) / scale;
printf("Total: %d %s\n", total, units);
}
void BitTrace(const struct VP8BitReader* const br, const char label[]) {
int i, pos;
if (!init_done) {
memset(kLabels, 0, sizeof(kLabels));
atexit(PrintBitTraces);
buf_start = br->buf_;
init_done = 1;
}
pos = (int)(br->buf_ - buf_start) * 8 - br->bits_;
// if there's a too large jump, we've changed partition -> reset counter
if (abs(pos - last_pos) > 32) {
buf_start = br->buf_;
pos = 0;
last_pos = 0;
}
if (br->range_ >= 0x7f) pos += kVP8Log2Range[br->range_ - 0x7f];
for (i = 0; i < last_label; ++i) {
if (!strcmp(label, kLabels[i].label)) break;
}
if (i == MAX_NUM_LABELS) abort(); // overflow!
kLabels[i].label = label;
kLabels[i].size += pos - last_pos;
kLabels[i].count += 1;
if (i == last_label) ++last_label;
last_pos = pos;
}
#endif // BITTRACE > 0
//------------------------------------------------------------------------------

@ -21,6 +21,27 @@
#endif #endif
#include "src/webp/types.h" #include "src/webp/types.h"
// Warning! This macro triggers quite some MACRO wizardry around func signature!
#if !defined(BITTRACE)
#define BITTRACE 0 // 0 = off, 1 = print bits, 2 = print bytes
#endif
#if (BITTRACE > 0)
struct VP8BitReader;
extern void BitTrace(const struct VP8BitReader* const br, const char label[]);
#define BT_TRACK(br) BitTrace(br, label)
#define VP8Get(BR, L) VP8GetValue(BR, 1, L)
#else
#define BT_TRACK(br)
// We'll REMOVE the 'const char label[]' from all signatures and calls (!!):
#define VP8GetValue(BR, N, L) VP8GetValue(BR, N)
#define VP8Get(BR, L) VP8GetValue(BR, 1, L)
#define VP8GetSignedValue(BR, N, L) VP8GetSignedValue(BR, N)
#define VP8GetBit(BR, P, L) VP8GetBit(BR, P)
#define VP8GetBitAlt(BR, P, L) VP8GetBitAlt(BR, P)
#define VP8GetSigned(BR, V, L) VP8GetSigned(BR, V)
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -92,17 +113,15 @@ void VP8BitReaderSetBuffer(VP8BitReader* const br,
void VP8RemapBitReader(VP8BitReader* const br, ptrdiff_t offset); void VP8RemapBitReader(VP8BitReader* const br, ptrdiff_t offset);
// return the next value made of 'num_bits' bits // return the next value made of 'num_bits' bits
uint32_t VP8GetValue(VP8BitReader* const br, int num_bits); uint32_t VP8GetValue(VP8BitReader* const br, int num_bits, const char label[]);
static WEBP_INLINE uint32_t VP8Get(VP8BitReader* const br) {
return VP8GetValue(br, 1);
}
// return the next value with sign-extension. // return the next value with sign-extension.
int32_t VP8GetSignedValue(VP8BitReader* const br, int num_bits); int32_t VP8GetSignedValue(VP8BitReader* const br, int num_bits,
const char label[]);
// bit_reader_inl.h will implement the following methods: // bit_reader_inl.h will implement the following methods:
// static WEBP_INLINE int VP8GetBit(VP8BitReader* const br, int prob) // static WEBP_INLINE int VP8GetBit(VP8BitReader* const br, int prob, ...)
// static WEBP_INLINE int VP8GetSigned(VP8BitReader* const br, int v) // static WEBP_INLINE int VP8GetSigned(VP8BitReader* const br, int v, ...)
// and should be included by the .c files that actually need them. // and should be included by the .c files that actually need them.
// This is to avoid recompiling the whole library whenever this file is touched, // This is to avoid recompiling the whole library whenever this file is touched,
// and also allowing platform-specific ad-hoc hacks. // and also allowing platform-specific ad-hoc hacks.

@ -70,7 +70,7 @@ static void Flush(VP8BitWriter* const bw) {
const int value = (bits & 0x100) ? 0x00 : 0xff; const int value = (bits & 0x100) ? 0x00 : 0xff;
for (; bw->run_ > 0; --bw->run_) bw->buf_[pos++] = value; for (; bw->run_ > 0; --bw->run_) bw->buf_[pos++] = value;
} }
bw->buf_[pos++] = bits; bw->buf_[pos++] = bits & 0xff;
bw->pos_ = pos; bw->pos_ = pos;
} else { } else {
bw->run_++; // delay writing of bytes 0xff, pending eventual carry. bw->run_++; // delay writing of bytes 0xff, pending eventual carry.

@ -17,6 +17,7 @@
#include <assert.h> #include <assert.h>
#include "src/dsp/dsp.h"
#include "src/webp/types.h" #include "src/webp/types.h"
#ifdef __cplusplus #ifdef __cplusplus
@ -30,10 +31,11 @@ typedef struct {
int hash_bits_; int hash_bits_;
} VP8LColorCache; } VP8LColorCache;
static const uint64_t kHashMul = 0x1e35a7bdull; static const uint32_t kHashMul = 0x1e35a7bdu;
static WEBP_INLINE int VP8LHashPix(uint32_t argb, int shift) { static WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW WEBP_INLINE
return (int)(((argb * kHashMul) & 0xffffffffu) >> shift); int VP8LHashPix(uint32_t argb, int shift) {
return (int)((argb * kHashMul) >> shift);
} }
static WEBP_INLINE uint32_t VP8LColorCacheLookup( static WEBP_INLINE uint32_t VP8LColorCacheLookup(

@ -91,7 +91,8 @@ static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
assert(code_lengths_size != 0); assert(code_lengths_size != 0);
assert(code_lengths != NULL); assert(code_lengths != NULL);
assert(root_table != NULL); assert((root_table != NULL && sorted != NULL) ||
(root_table == NULL && sorted == NULL));
assert(root_bits > 0); assert(root_bits > 0);
// Build histogram of code lengths. // Build histogram of code lengths.
@ -120,16 +121,22 @@ static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
for (symbol = 0; symbol < code_lengths_size; ++symbol) { for (symbol = 0; symbol < code_lengths_size; ++symbol) {
const int symbol_code_length = code_lengths[symbol]; const int symbol_code_length = code_lengths[symbol];
if (code_lengths[symbol] > 0) { if (code_lengths[symbol] > 0) {
sorted[offset[symbol_code_length]++] = symbol; if (sorted != NULL) {
sorted[offset[symbol_code_length]++] = symbol;
} else {
offset[symbol_code_length]++;
}
} }
} }
// Special case code with only one value. // Special case code with only one value.
if (offset[MAX_ALLOWED_CODE_LENGTH] == 1) { if (offset[MAX_ALLOWED_CODE_LENGTH] == 1) {
HuffmanCode code; if (sorted != NULL) {
code.bits = 0; HuffmanCode code;
code.value = (uint16_t)sorted[0]; code.bits = 0;
ReplicateValue(table, 1, total_size, code); code.value = (uint16_t)sorted[0];
ReplicateValue(table, 1, total_size, code);
}
return total_size; return total_size;
} }
@ -151,6 +158,7 @@ static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
if (num_open < 0) { if (num_open < 0) {
return 0; return 0;
} }
if (root_table == NULL) continue;
for (; count[len] > 0; --count[len]) { for (; count[len] > 0; --count[len]) {
HuffmanCode code; HuffmanCode code;
code.bits = (uint8_t)len; code.bits = (uint8_t)len;
@ -169,6 +177,7 @@ static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
if (num_open < 0) { if (num_open < 0) {
return 0; return 0;
} }
if (root_table == NULL) continue;
for (; count[len] > 0; --count[len]) { for (; count[len] > 0; --count[len]) {
HuffmanCode code; HuffmanCode code;
if ((key & mask) != low) { if ((key & mask) != low) {
@ -206,7 +215,10 @@ int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
const int code_lengths[], int code_lengths_size) { const int code_lengths[], int code_lengths_size) {
int total_size; int total_size;
assert(code_lengths_size <= MAX_CODE_LENGTHS_SIZE); assert(code_lengths_size <= MAX_CODE_LENGTHS_SIZE);
if (code_lengths_size <= SORTED_SIZE_CUTOFF) { if (root_table == NULL) {
total_size = BuildHuffmanTable(NULL, root_bits,
code_lengths, code_lengths_size, NULL);
} else if (code_lengths_size <= SORTED_SIZE_CUTOFF) {
// use local stack-allocated array. // use local stack-allocated array.
uint16_t sorted[SORTED_SIZE_CUTOFF]; uint16_t sorted[SORTED_SIZE_CUTOFF];
total_size = BuildHuffmanTable(root_table, root_bits, total_size = BuildHuffmanTable(root_table, root_bits,

@ -78,6 +78,8 @@ void VP8LHtreeGroupsFree(HTreeGroup* const htree_groups);
// the huffman table. // the huffman table.
// Returns built table size or 0 in case of error (invalid tree or // Returns built table size or 0 in case of error (invalid tree or
// memory error). // memory error).
// If root_table is NULL, it returns 0 if a lookup cannot be built, something
// > 0 otherwise (but not the table size).
int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits, int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
const int code_lengths[], int code_lengths_size); const int code_lengths[], int code_lengths_size);

@ -84,14 +84,14 @@ int WebPRescalerGetScaledDimensions(int src_width, int src_height,
int height = *scaled_height; int height = *scaled_height;
// if width is unspecified, scale original proportionally to height ratio. // if width is unspecified, scale original proportionally to height ratio.
if (width == 0) { if (width == 0 && src_height > 0) {
width = width =
(int)(((uint64_t)src_width * height + src_height / 2) / src_height); (int)(((uint64_t)src_width * height + src_height - 1) / src_height);
} }
// if height is unspecified, scale original proportionally to width ratio. // if height is unspecified, scale original proportionally to width ratio.
if (height == 0) { if (height == 0 && src_width > 0) {
height = height =
(int)(((uint64_t)src_height * width + src_width / 2) / src_width); (int)(((uint64_t)src_height * width + src_width - 1) / src_width);
} }
// Check if the overall dimensions still make sense. // Check if the overall dimensions still make sense.
if (width <= 0 || height <= 0) { if (width <= 0 || height <= 0) {

@ -217,8 +217,12 @@ static THREADFN ThreadLoop(void* ptr) {
done = 1; done = 1;
} }
// signal to the main thread that we're done (for Sync()) // signal to the main thread that we're done (for Sync())
pthread_cond_signal(&impl->condition_); // Note the associated mutex does not need to be held when signaling the
// condition. Unlocking the mutex first may improve performance in some
// implementations, avoiding the case where the waiting thread can't
// reacquire the mutex when woken.
pthread_mutex_unlock(&impl->mutex_); pthread_mutex_unlock(&impl->mutex_);
pthread_cond_signal(&impl->condition_);
} }
return THREAD_RETURN(NULL); // Thread is finished return THREAD_RETURN(NULL); // Thread is finished
} }
@ -240,7 +244,13 @@ static void ChangeState(WebPWorker* const worker, WebPWorkerStatus new_status) {
// assign new status and release the working thread if needed // assign new status and release the working thread if needed
if (new_status != OK) { if (new_status != OK) {
worker->status_ = new_status; worker->status_ = new_status;
// Note the associated mutex does not need to be held when signaling the
// condition. Unlocking the mutex first may improve performance in some
// implementations, avoiding the case where the waiting thread can't
// reacquire the mutex when woken.
pthread_mutex_unlock(&impl->mutex_);
pthread_cond_signal(&impl->condition_); pthread_cond_signal(&impl->condition_);
return;
} }
} }
pthread_mutex_unlock(&impl->mutex_); pthread_mutex_unlock(&impl->mutex_);

@ -92,14 +92,14 @@ static WEBP_INLINE uint32_t GetLE32(const uint8_t* const data) {
// Store 16, 24 or 32 bits in little-endian order. // Store 16, 24 or 32 bits in little-endian order.
static WEBP_INLINE void PutLE16(uint8_t* const data, int val) { static WEBP_INLINE void PutLE16(uint8_t* const data, int val) {
assert(val < (1 << 16)); assert(val < (1 << 16));
data[0] = (val >> 0); data[0] = (val >> 0) & 0xff;
data[1] = (val >> 8); data[1] = (val >> 8) & 0xff;
} }
static WEBP_INLINE void PutLE24(uint8_t* const data, int val) { static WEBP_INLINE void PutLE24(uint8_t* const data, int val) {
assert(val < (1 << 24)); assert(val < (1 << 24));
PutLE16(data, val & 0xffff); PutLE16(data, val & 0xffff);
data[2] = (val >> 16); data[2] = (val >> 16) & 0xff;
} }
static WEBP_INLINE void PutLE32(uint8_t* const data, uint32_t val) { static WEBP_INLINE void PutLE32(uint8_t* const data, uint32_t val) {

@ -62,6 +62,10 @@ WEBP_EXTERN size_t WebPEncodeBGRA(const uint8_t* bgra,
// These functions are the equivalent of the above, but compressing in a // These functions are the equivalent of the above, but compressing in a
// lossless manner. Files are usually larger than lossy format, but will // lossless manner. Files are usually larger than lossy format, but will
// not suffer any compression loss. // not suffer any compression loss.
// Note these functions, like the lossy versions, use the library's default
// settings. For lossless this means 'exact' is disabled. RGB values in
// transparent areas will be modified to improve compression. To avoid this,
// use WebPEncode() and set WebPConfig::exact to 1.
WEBP_EXTERN size_t WebPEncodeLosslessRGB(const uint8_t* rgb, WEBP_EXTERN size_t WebPEncodeLosslessRGB(const uint8_t* rgb,
int width, int height, int stride, int width, int height, int stride,
uint8_t** output); uint8_t** output);

@ -5,7 +5,7 @@ target_include_directories(openvx_hal PUBLIC
${CMAKE_SOURCE_DIR}/modules/core/include ${CMAKE_SOURCE_DIR}/modules/core/include
${CMAKE_SOURCE_DIR}/modules/imgproc/include ${CMAKE_SOURCE_DIR}/modules/imgproc/include
${OPENVX_INCLUDE_DIR}) ${OPENVX_INCLUDE_DIR})
target_link_libraries(openvx_hal LINK_PUBLIC ${OPENVX_LIBRARIES}) target_link_libraries(openvx_hal PUBLIC ${OPENVX_LIBRARIES})
set_target_properties(openvx_hal PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH}) set_target_properties(openvx_hal PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH})
if(NOT BUILD_SHARED_LIBS) if(NOT BUILD_SHARED_LIBS)
ocv_install_target(openvx_hal EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev) ocv_install_target(openvx_hal EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)

@ -288,7 +288,7 @@ if(X86 OR X86_64)
ocv_update(CPU_AVX2_FLAGS_ON "/arch:AVX2") ocv_update(CPU_AVX2_FLAGS_ON "/arch:AVX2")
ocv_update(CPU_AVX_FLAGS_ON "/arch:AVX") ocv_update(CPU_AVX_FLAGS_ON "/arch:AVX")
ocv_update(CPU_FP16_FLAGS_ON "/arch:AVX") ocv_update(CPU_FP16_FLAGS_ON "/arch:AVX")
if(NOT MSVC64) if(NOT X86_64)
# 64-bit MSVC compiler uses SSE/SSE2 by default # 64-bit MSVC compiler uses SSE/SSE2 by default
ocv_update(CPU_SSE_FLAGS_ON "/arch:SSE") ocv_update(CPU_SSE_FLAGS_ON "/arch:SSE")
ocv_update(CPU_SSE_SUPPORTED ON) ocv_update(CPU_SSE_SUPPORTED ON)

@ -12,7 +12,7 @@ endif()
if(((NOT CMAKE_VERSION VERSION_LESS "3.9.0") # requires https://gitlab.kitware.com/cmake/cmake/merge_requests/663 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) OR OPENCV_CUDA_FORCE_EXTERNAL_CMAKE_MODULE)
AND NOT OPENCV_CUDA_FORCE_BUILTIN_CMAKE_MODULE) AND NOT OPENCV_CUDA_FORCE_BUILTIN_CMAKE_MODULE)
ocv_update(CUDA_LINK_LIBRARIES_KEYWORD "LINK_PRIVATE") ocv_update(CUDA_LINK_LIBRARIES_KEYWORD "PRIVATE")
find_host_package(CUDA "${MIN_VER_CUDA}" QUIET) find_host_package(CUDA "${MIN_VER_CUDA}" QUIET)
else() else()
# Use OpenCV's patched "FindCUDA" module # Use OpenCV's patched "FindCUDA" module

@ -3,15 +3,14 @@
# - CV_CLANG - Clang-compatible compiler (CMAKE_CXX_COMPILER_ID MATCHES "Clang" - Clang or AppleClang, see CMP0025) # - CV_CLANG - Clang-compatible compiler (CMAKE_CXX_COMPILER_ID MATCHES "Clang" - Clang or AppleClang, see CMP0025)
# - CV_ICC - Intel compiler # - CV_ICC - Intel compiler
# - MSVC - Microsoft Visual Compiler (CMake variable) # - MSVC - Microsoft Visual Compiler (CMake variable)
# - MSVC64 - additional flag, 64-bit
# - MINGW / CYGWIN / CMAKE_COMPILER_IS_MINGW / CMAKE_COMPILER_IS_CYGWIN (CMake original variables) # - MINGW / CYGWIN / CMAKE_COMPILER_IS_MINGW / CMAKE_COMPILER_IS_CYGWIN (CMake original variables)
# - MINGW64 - 64-bit
# #
# CPU Platforms: # CPU Platforms:
# - X86 / X86_64 # - X86 / X86_64
# - ARM - ARM CPU, not defined for AArch64 # - ARM - ARM CPU, not defined for AArch64
# - AARCH64 - ARMv8+ (64-bit) # - AARCH64 - ARMv8+ (64-bit)
# - PPC64 / PPC64LE - PowerPC # - PPC64 / PPC64LE - PowerPC
# - MIPS
# #
# OS: # OS:
# - WIN32 - Windows | MINGW # - WIN32 - Windows | MINGW
@ -21,9 +20,8 @@
# - APPLE - MacOSX | iOS # - APPLE - MacOSX | iOS
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
if(CMAKE_CL_64) ocv_declare_removed_variables(MINGW64 MSVC64)
set(MSVC64 1) # do not use (CMake variables): CMAKE_CL_64
endif()
if(NOT DEFINED CV_GCC AND CMAKE_CXX_COMPILER_ID MATCHES "GNU") if(NOT DEFINED CV_GCC AND CMAKE_CXX_COMPILER_ID MATCHES "GNU")
set(CV_GCC 1) set(CV_GCC 1)
@ -51,7 +49,7 @@ variable_watch(CMAKE_COMPILER_IS_CLANGCC access_CMAKE_COMPILER_IS_CLANGCXX)
# Detect Intel ICC compiler # Detect Intel ICC compiler
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
if(UNIX) if(UNIX)
if (__ICL) if(__ICL)
set(CV_ICC __ICL) set(CV_ICC __ICL)
elseif(__ICC) elseif(__ICC)
set(CV_ICC __ICC) set(CV_ICC __ICC)
@ -70,53 +68,65 @@ if(MSVC AND CMAKE_C_COMPILER MATCHES "icc|icl")
set(CV_ICC __INTEL_COMPILER_FOR_WINDOWS) set(CV_ICC __INTEL_COMPILER_FOR_WINDOWS)
endif() endif()
if(NOT DEFINED CMAKE_CXX_COMPILER_VERSION) if(NOT DEFINED CMAKE_CXX_COMPILER_VERSION
message(WARNING "Compiler version is not available: CMAKE_CXX_COMPILER_VERSION is not set") AND NOT OPENCV_SUPPRESS_MESSAGE_MISSING_COMPILER_VERSION)
message(WARNING "OpenCV: Compiler version is not available: CMAKE_CXX_COMPILER_VERSION is not set")
endif() endif()
if((NOT DEFINED CMAKE_SYSTEM_PROCESSOR OR CMAKE_SYSTEM_PROCESSOR STREQUAL "")
if(WIN32 AND CV_GCC) AND NOT OPENCV_SUPPRESS_MESSAGE_MISSING_CMAKE_SYSTEM_PROCESSOR)
execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpmachine message(WARNING "OpenCV: CMAKE_SYSTEM_PROCESSOR is not defined. Perhaps CMake toolchain is broken")
OUTPUT_VARIABLE OPENCV_GCC_TARGET_MACHINE endif()
OUTPUT_STRIP_TRAILING_WHITESPACE) if(NOT DEFINED CMAKE_SIZEOF_VOID_P
if(OPENCV_GCC_TARGET_MACHINE MATCHES "amd64|x86_64|AMD64") AND NOT OPENCV_SUPPRESS_MESSAGE_MISSING_CMAKE_SIZEOF_VOID_P)
set(MINGW64 1) message(WARNING "OpenCV: CMAKE_SIZEOF_VOID_P is not defined. Perhaps CMake toolchain is broken")
endif()
endif() endif()
message(STATUS "Detected processor: ${CMAKE_SYSTEM_PROCESSOR}") message(STATUS "Detected processor: ${CMAKE_SYSTEM_PROCESSOR}")
if(MSVC64 OR MINGW64) if(OPENCV_SKIP_SYSTEM_PROCESSOR_DETECTION)
set(X86_64 1) # custom setup: required variables are passed through cache / CMake's command-line
elseif(MINGW OR (MSVC AND NOT CMAKE_CROSSCOMPILING))
set(X86 1)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|x86_64.*|AMD64.*") elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|x86_64.*|AMD64.*")
set(X86_64 1) set(X86_64 1)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "i686.*|i386.*|x86.*|amd64.*|AMD64.*") elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "i686.*|i386.*|x86.*")
set(X86 1) set(X86 1)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64.*|AARCH64.*|arm64.*|ARM64.*)")
set(AARCH64 1)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm.*|ARM.*)") elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm.*|ARM.*)")
set(ARM 1) set(ARM 1)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64.*|AARCH64.*)")
set(AARCH64 1)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64le") elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64le")
set(PPC64LE 1) set(PPC64LE 1)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64") elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64")
set(PPC64 1) set(PPC64 1)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(mips.*|MIPS.*)") elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(mips.*|MIPS.*)")
set(MIPS 1) set(MIPS 1)
else()
if(NOT OPENCV_SUPPRESS_MESSAGE_UNRECOGNIZED_SYSTEM_PROCESSOR)
message(WARNING "OpenCV: unrecognized target processor configuration")
endif()
endif() endif()
# Workaround for 32-bit operating systems on x86_64/aarch64 processor # Workaround for 32-bit operating systems on x86_64
if(CMAKE_SIZEOF_VOID_P EQUAL 4 AND NOT FORCE_X86_64) if(CMAKE_SIZEOF_VOID_P EQUAL 4 AND X86_64
AND NOT FORCE_X86_64 # deprecated (2019-12)
AND NOT OPENCV_FORCE_X86_64
)
message(STATUS "sizeof(void) = 4 on 64 bit processor. Assume 32-bit compilation mode") message(STATUS "sizeof(void) = 4 on 64 bit processor. Assume 32-bit compilation mode")
if (X86_64) if(X86_64)
unset(X86_64) unset(X86_64)
set(X86 1) set(X86 1)
endif() endif()
if (AARCH64) endif()
# Workaround for 32-bit operating systems on aarch64 processor
if(CMAKE_SIZEOF_VOID_P EQUAL 4 AND AARCH64
AND NOT OPENCV_FORCE_AARCH64
)
message(STATUS "sizeof(void) = 4 on 64 bit processor. Assume 32-bit compilation mode")
if(AARCH64)
unset(AARCH64) unset(AARCH64)
set(ARM 1) set(ARM 1)
endif() endif()
endif() endif()
# Similar code exists in OpenCVConfig.cmake # Similar code exists in OpenCVConfig.cmake
if(NOT DEFINED OpenCV_STATIC) if(NOT DEFINED OpenCV_STATIC)
# look for global setting # look for global setting
@ -130,14 +140,19 @@ endif()
if(DEFINED OpenCV_ARCH AND DEFINED OpenCV_RUNTIME) if(DEFINED OpenCV_ARCH AND DEFINED OpenCV_RUNTIME)
# custom overridden values # custom overridden values
elseif(MSVC) elseif(MSVC)
if(CMAKE_CL_64) # see Modules/CMakeGenericSystem.cmake
set(OpenCV_ARCH x64) if("${CMAKE_GENERATOR}" MATCHES "(Win64|IA64)")
elseif((CMAKE_GENERATOR MATCHES "ARM") OR ("${arch_hint}" STREQUAL "ARM") OR (CMAKE_VS_EFFECTIVE_PLATFORMS MATCHES "ARM|arm")) set(OpenCV_ARCH "x64")
# see Modules/CmakeGenericSystem.cmake elseif("${CMAKE_GENERATOR_PLATFORM}" MATCHES "ARM64")
set(OpenCV_ARCH ARM) set(OpenCV_ARCH "ARM64")
elseif("${CMAKE_GENERATOR}" MATCHES "ARM")
set(OpenCV_ARCH "ARM")
elseif("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
set(OpenCV_ARCH "x64")
else() else()
set(OpenCV_ARCH x86) set(OpenCV_ARCH x86)
endif() endif()
if(MSVC_VERSION EQUAL 1400) if(MSVC_VERSION EQUAL 1400)
set(OpenCV_RUNTIME vc8) set(OpenCV_RUNTIME vc8)
elseif(MSVC_VERSION EQUAL 1500) elseif(MSVC_VERSION EQUAL 1500)
@ -160,7 +175,7 @@ elseif(MSVC)
elseif(MINGW) elseif(MINGW)
set(OpenCV_RUNTIME mingw) set(OpenCV_RUNTIME mingw)
if(MINGW64) if(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|x86_64.*|AMD64.*")
set(OpenCV_ARCH x64) set(OpenCV_ARCH x64)
else() else()
set(OpenCV_ARCH x86) set(OpenCV_ARCH x86)

@ -40,11 +40,8 @@ if (X86 AND UNIX AND NOT APPLE AND NOT ANDROID AND BUILD_SHARED_LIBS)
endif() endif()
set(IPP_X64 0) set(IPP_X64 0)
if(CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 8) if(X86_64)
set(IPP_X64 1) set(IPP_X64 1)
endif()
if(CMAKE_CL_64)
set(IPP_X64 1)
endif() endif()
# This function detects Intel IPP version by analyzing .h file # This function detects Intel IPP version by analyzing .h file

@ -15,7 +15,7 @@ file(TO_CMAKE_PATH "$ENV{ProgramFiles}" ProgramFiles_ENV_PATH)
if(WIN32) if(WIN32)
SET(OPENEXR_ROOT "C:/Deploy" CACHE STRING "Path to the OpenEXR \"Deploy\" folder") SET(OPENEXR_ROOT "C:/Deploy" CACHE STRING "Path to the OpenEXR \"Deploy\" folder")
if(CMAKE_CL_64) if(X86_64)
SET(OPENEXR_LIBSEARCH_SUFFIXES x64/Release x64 x64/Debug) SET(OPENEXR_LIBSEARCH_SUFFIXES x64/Release x64 x64/Debug)
elseif(MSVC) elseif(MSVC)
SET(OPENEXR_LIBSEARCH_SUFFIXES Win32/Release Win32 Win32/Debug) SET(OPENEXR_LIBSEARCH_SUFFIXES Win32/Release Win32 Win32/Debug)

@ -936,11 +936,15 @@ macro(_ocv_create_module)
set_source_files_properties(${OPENCV_MODULE_${the_module}_HEADERS} ${OPENCV_MODULE_${the_module}_SOURCES} ${${the_module}_pch} set_source_files_properties(${OPENCV_MODULE_${the_module}_HEADERS} ${OPENCV_MODULE_${the_module}_SOURCES} ${${the_module}_pch}
PROPERTIES LABELS "${OPENCV_MODULE_${the_module}_LABEL};Module") PROPERTIES LABELS "${OPENCV_MODULE_${the_module}_LABEL};Module")
ocv_target_link_libraries(${the_module} LINK_PUBLIC ${OPENCV_MODULE_${the_module}_DEPS_TO_LINK}) ocv_target_link_libraries(${the_module} PUBLIC ${OPENCV_MODULE_${the_module}_DEPS_TO_LINK}
ocv_target_link_libraries(${the_module} LINK_PUBLIC ${OPENCV_MODULE_${the_module}_DEPS_EXT}) INTERFACE ${OPENCV_MODULE_${the_module}_DEPS_TO_LINK}
ocv_target_link_libraries(${the_module} LINK_PRIVATE ${OPENCV_LINKER_LIBS} ${OPENCV_HAL_LINKER_LIBS} ${IPP_LIBS} ${ARGN}) )
ocv_target_link_libraries(${the_module} PUBLIC ${OPENCV_MODULE_${the_module}_DEPS_EXT}
INTERFACE ${OPENCV_MODULE_${the_module}_DEPS_EXT}
)
ocv_target_link_libraries(${the_module} PRIVATE ${OPENCV_LINKER_LIBS} ${OPENCV_HAL_LINKER_LIBS} ${IPP_LIBS} ${ARGN})
if (HAVE_CUDA) if (HAVE_CUDA)
ocv_target_link_libraries(${the_module} LINK_PRIVATE ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY}) ocv_target_link_libraries(${the_module} PRIVATE ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
endif() endif()
if(OPENCV_MODULE_${the_module}_COMPILE_DEFINITIONS) if(OPENCV_MODULE_${the_module}_COMPILE_DEFINITIONS)
@ -1149,7 +1153,7 @@ function(ocv_add_perf_tests)
source_group("Src" FILES "${${the_target}_pch}") source_group("Src" FILES "${${the_target}_pch}")
ocv_add_executable(${the_target} ${OPENCV_PERF_${the_module}_SOURCES} ${${the_target}_pch}) ocv_add_executable(${the_target} ${OPENCV_PERF_${the_module}_SOURCES} ${${the_target}_pch})
ocv_target_include_modules(${the_target} ${perf_deps}) ocv_target_include_modules(${the_target} ${perf_deps})
ocv_target_link_libraries(${the_target} LINK_PRIVATE ${perf_deps} ${OPENCV_MODULE_${the_module}_DEPS} ${OPENCV_LINKER_LIBS} ${OPENCV_PERF_${the_module}_DEPS}) ocv_target_link_libraries(${the_target} PRIVATE ${perf_deps} ${OPENCV_MODULE_${the_module}_DEPS} ${OPENCV_LINKER_LIBS} ${OPENCV_PERF_${the_module}_DEPS})
add_dependencies(opencv_perf_tests ${the_target}) add_dependencies(opencv_perf_tests ${the_target})
if(TARGET opencv_videoio_plugins) if(TARGET opencv_videoio_plugins)
@ -1239,7 +1243,7 @@ function(ocv_add_accuracy_tests)
if(EXISTS "${CMAKE_CURRENT_BINARY_DIR}/test") if(EXISTS "${CMAKE_CURRENT_BINARY_DIR}/test")
ocv_target_include_directories(${the_target} "${CMAKE_CURRENT_BINARY_DIR}/test") ocv_target_include_directories(${the_target} "${CMAKE_CURRENT_BINARY_DIR}/test")
endif() endif()
ocv_target_link_libraries(${the_target} LINK_PRIVATE ${test_deps} ${OPENCV_MODULE_${the_module}_DEPS} ${OPENCV_LINKER_LIBS} ${OPENCV_TEST_${the_module}_DEPS}) ocv_target_link_libraries(${the_target} PRIVATE ${test_deps} ${OPENCV_MODULE_${the_module}_DEPS} ${OPENCV_LINKER_LIBS} ${OPENCV_TEST_${the_module}_DEPS})
add_dependencies(opencv_tests ${the_target}) add_dependencies(opencv_tests ${the_target})
if(TARGET opencv_videoio_plugins) if(TARGET opencv_videoio_plugins)
@ -1309,7 +1313,7 @@ function(ocv_add_samples)
ocv_add_executable(${the_target} "${source}") ocv_add_executable(${the_target} "${source}")
ocv_target_include_modules(${the_target} ${samples_deps}) ocv_target_include_modules(${the_target} ${samples_deps})
ocv_target_link_libraries(${the_target} LINK_PRIVATE ${samples_deps}) ocv_target_link_libraries(${the_target} PRIVATE ${samples_deps})
set_target_properties(${the_target} PROPERTIES set_target_properties(${the_target} PROPERTIES
PROJECT_LABEL "(sample) ${name}" PROJECT_LABEL "(sample) ${name}"

@ -100,6 +100,30 @@ macro(ocv_update VAR)
endif() endif()
endmacro() endmacro()
function(_ocv_access_removed_variable VAR ACCESS)
if(ACCESS STREQUAL "MODIFIED_ACCESS")
set(OPENCV_SUPPRESS_MESSAGE_REMOVED_VARIABLE_${VAR} 1 PARENT_SCOPE)
return()
endif()
if(ACCESS MATCHES "UNKNOWN_.*"
AND NOT OPENCV_SUPPRESS_MESSAGE_REMOVED_VARIABLE
AND NOT OPENCV_SUPPRESS_MESSAGE_REMOVED_VARIABLE_${VAR}
)
message(WARNING "OpenCV: Variable has been removed from CMake scripts: ${VAR}")
set(OPENCV_SUPPRESS_MESSAGE_REMOVED_VARIABLE_${VAR} 1 PARENT_SCOPE) # suppress similar messages
endif()
endfunction()
macro(ocv_declare_removed_variable VAR)
if(NOT DEFINED ${VAR}) # don't hit external variables
variable_watch(${VAR} _ocv_access_removed_variable)
endif()
endmacro()
macro(ocv_declare_removed_variables)
foreach(_var ${ARGN})
ocv_declare_removed_variable(${_var})
endforeach()
endmacro()
# Search packages for the host system instead of packages for the target system # Search packages for the host system instead of packages for the target system
# in case of cross compilation these macros should be defined by the toolchain file # in case of cross compilation these macros should be defined by the toolchain file
if(NOT COMMAND find_host_package) if(NOT COMMAND find_host_package)
@ -1407,13 +1431,13 @@ endmacro()
function(ocv_target_link_libraries target) function(ocv_target_link_libraries target)
set(LINK_DEPS ${ARGN}) set(LINK_DEPS ${ARGN})
_ocv_fix_target(target) _ocv_fix_target(target)
set(LINK_MODE "LINK_PRIVATE") set(LINK_MODE "PRIVATE")
set(LINK_PENDING "") set(LINK_PENDING "")
foreach(dep ${LINK_DEPS}) foreach(dep ${LINK_DEPS})
if(" ${dep}" STREQUAL " ${target}") if(" ${dep}" STREQUAL " ${target}")
# prevent "link to itself" warning (world problem) # prevent "link to itself" warning (world problem)
elseif(" ${dep}" STREQUAL " LINK_PRIVATE" OR " ${dep}" STREQUAL "LINK_PUBLIC" elseif(" ${dep}" STREQUAL " LINK_PRIVATE" OR " ${dep}" STREQUAL " LINK_PUBLIC" # deprecated
OR " ${dep}" STREQUAL " PRIVATE" OR " ${dep}" STREQUAL "PUBLIC" OR " ${dep}" STREQUAL " PRIVATE" OR " ${dep}" STREQUAL " PUBLIC" OR " ${dep}" STREQUAL " INTERFACE"
) )
if(NOT LINK_PENDING STREQUAL "") if(NOT LINK_PENDING STREQUAL "")
__ocv_push_target_link_libraries(${LINK_MODE} ${LINK_PENDING}) __ocv_push_target_link_libraries(${LINK_MODE} ${LINK_PENDING})
@ -1553,7 +1577,10 @@ macro(ocv_get_all_libs _modules _extra _3rdparty)
endif() endif()
if (TARGET ${dep}) if (TARGET ${dep})
get_target_property(_type ${dep} TYPE) get_target_property(_type ${dep} TYPE)
if(_type STREQUAL "STATIC_LIBRARY" AND BUILD_SHARED_LIBS OR _type STREQUAL "INTERFACE_LIBRARY") if((_type STREQUAL "STATIC_LIBRARY" AND BUILD_SHARED_LIBS)
OR _type STREQUAL "INTERFACE_LIBRARY"
OR DEFINED OPENCV_MODULE_${dep}_LOCATION # OpenCV modules
)
# nothing # nothing
else() else()
get_target_property(_output ${dep} IMPORTED_LOCATION) get_target_property(_output ${dep} IMPORTED_LOCATION)

@ -194,7 +194,7 @@ macro(add_android_project target path)
add_library(${JNI_LIB_NAME} SHARED ${android_proj_jni_files}) add_library(${JNI_LIB_NAME} SHARED ${android_proj_jni_files})
ocv_target_include_modules_recurse(${JNI_LIB_NAME} ${android_proj_NATIVE_DEPS}) ocv_target_include_modules_recurse(${JNI_LIB_NAME} ${android_proj_NATIVE_DEPS})
ocv_target_include_directories(${JNI_LIB_NAME} "${path}/jni") ocv_target_include_directories(${JNI_LIB_NAME} "${path}/jni")
ocv_target_link_libraries(${JNI_LIB_NAME} LINK_PRIVATE ${OPENCV_LINKER_LIBS} ${android_proj_NATIVE_DEPS}) ocv_target_link_libraries(${JNI_LIB_NAME} PRIVATE ${OPENCV_LINKER_LIBS} ${android_proj_NATIVE_DEPS})
set_target_properties(${JNI_LIB_NAME} PROPERTIES set_target_properties(${JNI_LIB_NAME} PROPERTIES
OUTPUT_NAME "${JNI_LIB_NAME}" OUTPUT_NAME "${JNI_LIB_NAME}"

@ -84,17 +84,31 @@ endfunction()
get_filename_component(OpenCV_CONFIG_PATH "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY) get_filename_component(OpenCV_CONFIG_PATH "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY)
if((NOT DEFINED CMAKE_SYSTEM_PROCESSOR OR CMAKE_SYSTEM_PROCESSOR STREQUAL "")
AND NOT OPENCV_SUPPRESS_MESSAGE_MISSING_CMAKE_SYSTEM_PROCESSOR)
message(WARNING "OpenCV: CMAKE_SYSTEM_PROCESSOR is not defined. Perhaps CMake toolchain is broken")
endif()
if(NOT DEFINED CMAKE_SIZEOF_VOID_P
AND NOT OPENCV_SUPPRESS_MESSAGE_MISSING_CMAKE_SIZEOF_VOID_P)
message(WARNING "OpenCV: CMAKE_SIZEOF_VOID_P is not defined. Perhaps CMake toolchain is broken")
endif()
if(DEFINED OpenCV_ARCH AND DEFINED OpenCV_RUNTIME) if(DEFINED OpenCV_ARCH AND DEFINED OpenCV_RUNTIME)
# custom overridden values # custom overridden values
elseif(MSVC) elseif(MSVC)
if(CMAKE_CL_64) # see Modules/CMakeGenericSystem.cmake
set(OpenCV_ARCH x64) if("${CMAKE_GENERATOR}" MATCHES "(Win64|IA64)")
elseif((CMAKE_GENERATOR MATCHES "ARM") OR ("${arch_hint}" STREQUAL "ARM") OR (CMAKE_VS_EFFECTIVE_PLATFORMS MATCHES "ARM|arm")) set(OpenCV_ARCH "x64")
# see Modules/CmakeGenericSystem.cmake elseif("${CMAKE_GENERATOR_PLATFORM}" MATCHES "ARM64")
set(OpenCV_ARCH ARM) set(OpenCV_ARCH "ARM64")
elseif("${CMAKE_GENERATOR}" MATCHES "ARM")
set(OpenCV_ARCH "ARM")
elseif("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
set(OpenCV_ARCH "x64")
else() else()
set(OpenCV_ARCH x86) set(OpenCV_ARCH x86)
endif() endif()
if(MSVC_VERSION EQUAL 1400) if(MSVC_VERSION EQUAL 1400)
set(OpenCV_RUNTIME vc8) set(OpenCV_RUNTIME vc8)
elseif(MSVC_VERSION EQUAL 1500) elseif(MSVC_VERSION EQUAL 1500)
@ -127,11 +141,7 @@ elseif(MSVC)
elseif(MINGW) elseif(MINGW)
set(OpenCV_RUNTIME mingw) set(OpenCV_RUNTIME mingw)
execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpmachine if(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|x86_64.*|AMD64.*")
OUTPUT_VARIABLE OPENCV_GCC_TARGET_MACHINE
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(OPENCV_GCC_TARGET_MACHINE MATCHES "amd64|x86_64|AMD64")
set(MINGW64 1)
set(OpenCV_ARCH x64) set(OpenCV_ARCH x64)
else() else()
set(OpenCV_ARCH x86) set(OpenCV_ARCH x86)

@ -172,9 +172,27 @@ if(DOXYGEN_FOUND)
list(APPEND CMAKE_DOXYGEN_HTML_FILES "${CMAKE_CURRENT_SOURCE_DIR}/tutorial-utils.js") list(APPEND CMAKE_DOXYGEN_HTML_FILES "${CMAKE_CURRENT_SOURCE_DIR}/tutorial-utils.js")
string(REPLACE ";" " \\\n" CMAKE_DOXYGEN_HTML_FILES "${CMAKE_DOXYGEN_HTML_FILES}") string(REPLACE ";" " \\\n" CMAKE_DOXYGEN_HTML_FILES "${CMAKE_DOXYGEN_HTML_FILES}")
set(OPENCV_DOCS_DOT_PATH "" CACHE PATH "Doxygen/DOT_PATH value")
set(CMAKECONFIG_DOT_PATH "${OPENCV_DOCS_DOT_PATH}")
set(OPENCV_DOCS_HAVE_DOT "NO" CACHE BOOL "Doxygen: build extra diagrams")
set(CMAKECONFIG_HAVE_DOT "${OPENCV_DOCS_HAVE_DOT}")
# 'png' is good enough for compatibility (but requires +50% storage space)
set(OPENCV_DOCS_DOT_IMAGE_FORMAT "svg" CACHE STRING "Doxygen/DOT_IMAGE_FORMAT value")
set(CMAKECONFIG_DOT_IMAGE_FORMAT "${OPENCV_DOCS_DOT_IMAGE_FORMAT}")
# Doxygen 1.8.16 fix: https://github.com/doxygen/doxygen/pull/6870
# NO is needed here: https://github.com/opencv/opencv/pull/16039
set(OPENCV_DOCS_INTERACTIVE_SVG "NO" CACHE BOOL "Doxygen/INTERACTIVE_SVG value")
set(CMAKECONFIG_INTERACTIVE_SVG "${OPENCV_DOCS_INTERACTIVE_SVG}")
set(OPENCV_DOCS_DOXYFILE_IN "Doxyfile.in" CACHE PATH "Doxygen configuration template file (Doxyfile.in)")
set(OPENCV_DOCS_DOXYGEN_LAYOUT "DoxygenLayout.xml" CACHE PATH "Doxygen layout file (.xml)")
# writing file # writing file
configure_file(DoxygenLayout.xml DoxygenLayout.xml @ONLY) configure_file("${OPENCV_DOCS_DOXYGEN_LAYOUT}" DoxygenLayout.xml @ONLY)
configure_file(Doxyfile.in ${doxyfile} @ONLY) configure_file("${OPENCV_DOCS_DOXYFILE_IN}" ${doxyfile} @ONLY)
configure_file(root.markdown.in ${rootfile} @ONLY) configure_file(root.markdown.in ${rootfile} @ONLY)
# js tutorial assets # js tutorial assets

@ -269,7 +269,7 @@ EXTERNAL_PAGES = YES
CLASS_DIAGRAMS = YES CLASS_DIAGRAMS = YES
DIA_PATH = DIA_PATH =
HIDE_UNDOC_RELATIONS = NO HIDE_UNDOC_RELATIONS = NO
HAVE_DOT = NO HAVE_DOT = @CMAKECONFIG_HAVE_DOT@
DOT_NUM_THREADS = 0 DOT_NUM_THREADS = 0
DOT_FONTNAME = Helvetica DOT_FONTNAME = Helvetica
DOT_FONTSIZE = 10 DOT_FONTSIZE = 10
@ -286,9 +286,9 @@ CALL_GRAPH = YES
CALLER_GRAPH = NO CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = YES GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = svg DOT_IMAGE_FORMAT = @CMAKECONFIG_DOT_IMAGE_FORMAT@
INTERACTIVE_SVG = NO INTERACTIVE_SVG = @CMAKECONFIG_INTERACTIVE_SVG@
DOT_PATH = DOT_PATH = @CMAKECONFIG_DOT_PATH@
DOTFILE_DIRS = DOTFILE_DIRS =
MSCFILE_DIRS = MSCFILE_DIRS =
DIAFILE_DIRS = DIAFILE_DIRS =

@ -43,11 +43,19 @@ points than for SURF points.
In short, BRIEF is a faster method feature descriptor calculation and matching. It also provides In short, BRIEF is a faster method feature descriptor calculation and matching. It also provides
high recognition rate unless there is large in-plane rotation. high recognition rate unless there is large in-plane rotation.
STAR(CenSurE) in OpenCV
------
STAR is a feature detector derived from CenSurE.
Unlike CenSurE however, which uses polygons like squares, hexagons and octagons to approach a circle,
Star emulates a circle with 2 overlapping squares: 1 upright and 1 45-degree rotated. These polygons are bi-level.
They can be seen as polygons with thick borders. The borders and the enclosed area have weights of opposing signs.
This has better computational characteristics than other scale-space detectors and it is capable of real-time implementation.
In contrast to SIFT and SURF, which find extrema at sub-sampled pixels that compromises accuracy at larger scales,
CenSurE creates a feature vector using full spatial resolution at all scales in the pyramid.
BRIEF in OpenCV BRIEF in OpenCV
--------------- ---------------
Below code shows the computation of BRIEF descriptors with the help of CenSurE detector. (CenSurE Below code shows the computation of BRIEF descriptors with the help of CenSurE detector.
detector is called STAR detector in OpenCV)
note, that you need [opencv contrib](https://github.com/opencv/opencv_contrib)) to use this. note, that you need [opencv contrib](https://github.com/opencv/opencv_contrib)) to use this.
@code{.py} @code{.py}

@ -14,7 +14,7 @@ Here we will create a simple application which shows the color you specify. You
shows the color and three trackbars to specify each of B,G,R colors. You slide the trackbar and shows the color and three trackbars to specify each of B,G,R colors. You slide the trackbar and
correspondingly window color changes. By default, initial color will be set to Black. correspondingly window color changes. By default, initial color will be set to Black.
For cv.getTrackbarPos() function, first argument is the trackbar name, second one is the window For cv.createTrackbar() function, first argument is the trackbar name, second one is the window
name to which it is attached, third argument is the default value, fourth one is the maximum value name to which it is attached, third argument is the default value, fourth one is the maximum value
and fifth one is the callback function which is executed every time trackbar value changes. The and fifth one is the callback function which is executed every time trackbar value changes. The
callback function always has a default argument which is the trackbar position. In our case, callback function always has a default argument which is the trackbar position. In our case,

@ -114,7 +114,7 @@ void CV_UndistortPointsBadArgTest::run(int)
src_points = cv::cvarrToMat(&_src_points_orig); src_points = cv::cvarrToMat(&_src_points_orig);
src_points = cv::Mat(); src_points = cv::Mat();
errcount += run_test_case( CV_StsAssert, "Input data matrix is not continuous" ); errcount += run_test_case( CV_StsBadArg, "Input data matrix is not continuous" );
src_points = cv::cvarrToMat(&_src_points_orig); src_points = cv::cvarrToMat(&_src_points_orig);
//------------ //------------

@ -83,7 +83,7 @@ endif()
ocv_create_module(${extra_libs}) ocv_create_module(${extra_libs})
ocv_target_link_libraries(${the_module} LINK_PRIVATE ocv_target_link_libraries(${the_module} PRIVATE
"${ZLIB_LIBRARIES}" "${OPENCL_LIBRARIES}" "${VA_LIBRARIES}" "${ZLIB_LIBRARIES}" "${OPENCL_LIBRARIES}" "${VA_LIBRARIES}"
"${LAPACK_LIBRARIES}" "${CPUFEATURES_LIBRARIES}" "${HALIDE_LIBRARIES}" "${LAPACK_LIBRARIES}" "${CPUFEATURES_LIBRARIES}" "${HALIDE_LIBRARIES}"
"${ITT_LIBRARIES}" "${ITT_LIBRARIES}"

@ -14,6 +14,25 @@
namespace cv namespace cv
{ {
//This and its overload below are used in various MatExpr operator overloads
//implemented to check that Matrix operands exist.
static void checkOperandsExist(const Mat& a)
{
if (a.empty())
{
CV_Error(CV_StsBadArg, "Matrix operand is an empty matrix.");
}
}
static void checkOperandsExist(const Mat& a, const Mat& b)
{
if (a.empty() || b.empty())
{
CV_Error(CV_StsBadArg, "One or more matrix operands are empty.");
}
}
class MatOp_Identity CV_FINAL : public MatOp class MatOp_Identity CV_FINAL : public MatOp
{ {
public: public:
@ -659,6 +678,7 @@ MatExpr MatExpr::mul(const Mat& m, double scale) const
MatExpr operator + (const Mat& a, const Mat& b) MatExpr operator + (const Mat& a, const Mat& b)
{ {
checkOperandsExist(a, b);
MatExpr e; MatExpr e;
MatOp_AddEx::makeExpr(e, a, b, 1, 1); MatOp_AddEx::makeExpr(e, a, b, 1, 1);
return e; return e;
@ -666,6 +686,7 @@ MatExpr operator + (const Mat& a, const Mat& b)
MatExpr operator + (const Mat& a, const Scalar& s) MatExpr operator + (const Mat& a, const Scalar& s)
{ {
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_AddEx::makeExpr(e, a, Mat(), 1, 0, s); MatOp_AddEx::makeExpr(e, a, Mat(), 1, 0, s);
return e; return e;
@ -673,6 +694,7 @@ MatExpr operator + (const Mat& a, const Scalar& s)
MatExpr operator + (const Scalar& s, const Mat& a) MatExpr operator + (const Scalar& s, const Mat& a)
{ {
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_AddEx::makeExpr(e, a, Mat(), 1, 0, s); MatOp_AddEx::makeExpr(e, a, Mat(), 1, 0, s);
return e; return e;
@ -687,6 +709,7 @@ MatExpr operator + (const MatExpr& e, const Mat& m)
MatExpr operator + (const Mat& m, const MatExpr& e) MatExpr operator + (const Mat& m, const MatExpr& e)
{ {
checkOperandsExist(m);
MatExpr en; MatExpr en;
e.op->add(e, MatExpr(m), en); e.op->add(e, MatExpr(m), en);
return en; return en;
@ -715,6 +738,7 @@ MatExpr operator + (const MatExpr& e1, const MatExpr& e2)
MatExpr operator - (const Mat& a, const Mat& b) MatExpr operator - (const Mat& a, const Mat& b)
{ {
checkOperandsExist(a, b);
MatExpr e; MatExpr e;
MatOp_AddEx::makeExpr(e, a, b, 1, -1); MatOp_AddEx::makeExpr(e, a, b, 1, -1);
return e; return e;
@ -722,6 +746,7 @@ MatExpr operator - (const Mat& a, const Mat& b)
MatExpr operator - (const Mat& a, const Scalar& s) MatExpr operator - (const Mat& a, const Scalar& s)
{ {
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_AddEx::makeExpr(e, a, Mat(), 1, 0, -s); MatOp_AddEx::makeExpr(e, a, Mat(), 1, 0, -s);
return e; return e;
@ -729,6 +754,7 @@ MatExpr operator - (const Mat& a, const Scalar& s)
MatExpr operator - (const Scalar& s, const Mat& a) MatExpr operator - (const Scalar& s, const Mat& a)
{ {
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_AddEx::makeExpr(e, a, Mat(), -1, 0, s); MatOp_AddEx::makeExpr(e, a, Mat(), -1, 0, s);
return e; return e;
@ -736,6 +762,7 @@ MatExpr operator - (const Scalar& s, const Mat& a)
MatExpr operator - (const MatExpr& e, const Mat& m) MatExpr operator - (const MatExpr& e, const Mat& m)
{ {
checkOperandsExist(m);
MatExpr en; MatExpr en;
e.op->subtract(e, MatExpr(m), en); e.op->subtract(e, MatExpr(m), en);
return en; return en;
@ -743,6 +770,7 @@ MatExpr operator - (const MatExpr& e, const Mat& m)
MatExpr operator - (const Mat& m, const MatExpr& e) MatExpr operator - (const Mat& m, const MatExpr& e)
{ {
checkOperandsExist(m);
MatExpr en; MatExpr en;
e.op->subtract(MatExpr(m), e, en); e.op->subtract(MatExpr(m), e, en);
return en; return en;
@ -771,6 +799,7 @@ MatExpr operator - (const MatExpr& e1, const MatExpr& e2)
MatExpr operator - (const Mat& m) MatExpr operator - (const Mat& m)
{ {
checkOperandsExist(m);
MatExpr e; MatExpr e;
MatOp_AddEx::makeExpr(e, m, Mat(), -1, 0); MatOp_AddEx::makeExpr(e, m, Mat(), -1, 0);
return e; return e;
@ -785,6 +814,7 @@ MatExpr operator - (const MatExpr& e)
MatExpr operator * (const Mat& a, const Mat& b) MatExpr operator * (const Mat& a, const Mat& b)
{ {
checkOperandsExist(a, b);
MatExpr e; MatExpr e;
MatOp_GEMM::makeExpr(e, 0, a, b); MatOp_GEMM::makeExpr(e, 0, a, b);
return e; return e;
@ -792,6 +822,7 @@ MatExpr operator * (const Mat& a, const Mat& b)
MatExpr operator * (const Mat& a, double s) MatExpr operator * (const Mat& a, double s)
{ {
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_AddEx::makeExpr(e, a, Mat(), s, 0); MatOp_AddEx::makeExpr(e, a, Mat(), s, 0);
return e; return e;
@ -799,6 +830,7 @@ MatExpr operator * (const Mat& a, double s)
MatExpr operator * (double s, const Mat& a) MatExpr operator * (double s, const Mat& a)
{ {
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_AddEx::makeExpr(e, a, Mat(), s, 0); MatOp_AddEx::makeExpr(e, a, Mat(), s, 0);
return e; return e;
@ -813,6 +845,7 @@ MatExpr operator * (const MatExpr& e, const Mat& m)
MatExpr operator * (const Mat& m, const MatExpr& e) MatExpr operator * (const Mat& m, const MatExpr& e)
{ {
checkOperandsExist(m);
MatExpr en; MatExpr en;
e.op->matmul(MatExpr(m), e, en); e.op->matmul(MatExpr(m), e, en);
return en; return en;
@ -841,6 +874,7 @@ MatExpr operator * (const MatExpr& e1, const MatExpr& e2)
MatExpr operator / (const Mat& a, const Mat& b) MatExpr operator / (const Mat& a, const Mat& b)
{ {
checkOperandsExist(a, b);
MatExpr e; MatExpr e;
MatOp_Bin::makeExpr(e, '/', a, b); MatOp_Bin::makeExpr(e, '/', a, b);
return e; return e;
@ -848,6 +882,7 @@ MatExpr operator / (const Mat& a, const Mat& b)
MatExpr operator / (const Mat& a, double s) MatExpr operator / (const Mat& a, double s)
{ {
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_AddEx::makeExpr(e, a, Mat(), 1./s, 0); MatOp_AddEx::makeExpr(e, a, Mat(), 1./s, 0);
return e; return e;
@ -855,6 +890,7 @@ MatExpr operator / (const Mat& a, double s)
MatExpr operator / (double s, const Mat& a) MatExpr operator / (double s, const Mat& a)
{ {
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_Bin::makeExpr(e, '/', a, Mat(), s); MatOp_Bin::makeExpr(e, '/', a, Mat(), s);
return e; return e;
@ -869,6 +905,7 @@ MatExpr operator / (const MatExpr& e, const Mat& m)
MatExpr operator / (const Mat& m, const MatExpr& e) MatExpr operator / (const Mat& m, const MatExpr& e)
{ {
checkOperandsExist(m);
MatExpr en; MatExpr en;
e.op->divide(MatExpr(m), e, en); e.op->divide(MatExpr(m), e, en);
return en; return en;
@ -897,6 +934,7 @@ MatExpr operator / (const MatExpr& e1, const MatExpr& e2)
MatExpr operator < (const Mat& a, const Mat& b) MatExpr operator < (const Mat& a, const Mat& b)
{ {
checkOperandsExist(a, b);
MatExpr e; MatExpr e;
MatOp_Cmp::makeExpr(e, CV_CMP_LT, a, b); MatOp_Cmp::makeExpr(e, CV_CMP_LT, a, b);
return e; return e;
@ -904,6 +942,7 @@ MatExpr operator < (const Mat& a, const Mat& b)
MatExpr operator < (const Mat& a, double s) MatExpr operator < (const Mat& a, double s)
{ {
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_Cmp::makeExpr(e, CV_CMP_LT, a, s); MatOp_Cmp::makeExpr(e, CV_CMP_LT, a, s);
return e; return e;
@ -911,6 +950,7 @@ MatExpr operator < (const Mat& a, double s)
MatExpr operator < (double s, const Mat& a) MatExpr operator < (double s, const Mat& a)
{ {
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_Cmp::makeExpr(e, CV_CMP_GT, a, s); MatOp_Cmp::makeExpr(e, CV_CMP_GT, a, s);
return e; return e;
@ -918,6 +958,7 @@ MatExpr operator < (double s, const Mat& a)
MatExpr operator <= (const Mat& a, const Mat& b) MatExpr operator <= (const Mat& a, const Mat& b)
{ {
checkOperandsExist(a, b);
MatExpr e; MatExpr e;
MatOp_Cmp::makeExpr(e, CV_CMP_LE, a, b); MatOp_Cmp::makeExpr(e, CV_CMP_LE, a, b);
return e; return e;
@ -925,6 +966,7 @@ MatExpr operator <= (const Mat& a, const Mat& b)
MatExpr operator <= (const Mat& a, double s) MatExpr operator <= (const Mat& a, double s)
{ {
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_Cmp::makeExpr(e, CV_CMP_LE, a, s); MatOp_Cmp::makeExpr(e, CV_CMP_LE, a, s);
return e; return e;
@ -932,6 +974,7 @@ MatExpr operator <= (const Mat& a, double s)
MatExpr operator <= (double s, const Mat& a) MatExpr operator <= (double s, const Mat& a)
{ {
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_Cmp::makeExpr(e, CV_CMP_GE, a, s); MatOp_Cmp::makeExpr(e, CV_CMP_GE, a, s);
return e; return e;
@ -939,6 +982,7 @@ MatExpr operator <= (double s, const Mat& a)
MatExpr operator == (const Mat& a, const Mat& b) MatExpr operator == (const Mat& a, const Mat& b)
{ {
checkOperandsExist(a, b);
MatExpr e; MatExpr e;
MatOp_Cmp::makeExpr(e, CV_CMP_EQ, a, b); MatOp_Cmp::makeExpr(e, CV_CMP_EQ, a, b);
return e; return e;
@ -946,6 +990,7 @@ MatExpr operator == (const Mat& a, const Mat& b)
MatExpr operator == (const Mat& a, double s) MatExpr operator == (const Mat& a, double s)
{ {
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_Cmp::makeExpr(e, CV_CMP_EQ, a, s); MatOp_Cmp::makeExpr(e, CV_CMP_EQ, a, s);
return e; return e;
@ -953,6 +998,7 @@ MatExpr operator == (const Mat& a, double s)
MatExpr operator == (double s, const Mat& a) MatExpr operator == (double s, const Mat& a)
{ {
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_Cmp::makeExpr(e, CV_CMP_EQ, a, s); MatOp_Cmp::makeExpr(e, CV_CMP_EQ, a, s);
return e; return e;
@ -960,6 +1006,7 @@ MatExpr operator == (double s, const Mat& a)
MatExpr operator != (const Mat& a, const Mat& b) MatExpr operator != (const Mat& a, const Mat& b)
{ {
checkOperandsExist(a, b);
MatExpr e; MatExpr e;
MatOp_Cmp::makeExpr(e, CV_CMP_NE, a, b); MatOp_Cmp::makeExpr(e, CV_CMP_NE, a, b);
return e; return e;
@ -967,6 +1014,7 @@ MatExpr operator != (const Mat& a, const Mat& b)
MatExpr operator != (const Mat& a, double s) MatExpr operator != (const Mat& a, double s)
{ {
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_Cmp::makeExpr(e, CV_CMP_NE, a, s); MatOp_Cmp::makeExpr(e, CV_CMP_NE, a, s);
return e; return e;
@ -974,6 +1022,7 @@ MatExpr operator != (const Mat& a, double s)
MatExpr operator != (double s, const Mat& a) MatExpr operator != (double s, const Mat& a)
{ {
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_Cmp::makeExpr(e, CV_CMP_NE, a, s); MatOp_Cmp::makeExpr(e, CV_CMP_NE, a, s);
return e; return e;
@ -981,6 +1030,7 @@ MatExpr operator != (double s, const Mat& a)
MatExpr operator >= (const Mat& a, const Mat& b) MatExpr operator >= (const Mat& a, const Mat& b)
{ {
checkOperandsExist(a, b);
MatExpr e; MatExpr e;
MatOp_Cmp::makeExpr(e, CV_CMP_GE, a, b); MatOp_Cmp::makeExpr(e, CV_CMP_GE, a, b);
return e; return e;
@ -988,6 +1038,7 @@ MatExpr operator >= (const Mat& a, const Mat& b)
MatExpr operator >= (const Mat& a, double s) MatExpr operator >= (const Mat& a, double s)
{ {
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_Cmp::makeExpr(e, CV_CMP_GE, a, s); MatOp_Cmp::makeExpr(e, CV_CMP_GE, a, s);
return e; return e;
@ -995,6 +1046,7 @@ MatExpr operator >= (const Mat& a, double s)
MatExpr operator >= (double s, const Mat& a) MatExpr operator >= (double s, const Mat& a)
{ {
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_Cmp::makeExpr(e, CV_CMP_LE, a, s); MatOp_Cmp::makeExpr(e, CV_CMP_LE, a, s);
return e; return e;
@ -1002,6 +1054,7 @@ MatExpr operator >= (double s, const Mat& a)
MatExpr operator > (const Mat& a, const Mat& b) MatExpr operator > (const Mat& a, const Mat& b)
{ {
checkOperandsExist(a, b);
MatExpr e; MatExpr e;
MatOp_Cmp::makeExpr(e, CV_CMP_GT, a, b); MatOp_Cmp::makeExpr(e, CV_CMP_GT, a, b);
return e; return e;
@ -1009,6 +1062,7 @@ MatExpr operator > (const Mat& a, const Mat& b)
MatExpr operator > (const Mat& a, double s) MatExpr operator > (const Mat& a, double s)
{ {
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_Cmp::makeExpr(e, CV_CMP_GT, a, s); MatOp_Cmp::makeExpr(e, CV_CMP_GT, a, s);
return e; return e;
@ -1016,6 +1070,7 @@ MatExpr operator > (const Mat& a, double s)
MatExpr operator > (double s, const Mat& a) MatExpr operator > (double s, const Mat& a)
{ {
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_Cmp::makeExpr(e, CV_CMP_LT, a, s); MatOp_Cmp::makeExpr(e, CV_CMP_LT, a, s);
return e; return e;
@ -1025,6 +1080,7 @@ MatExpr min(const Mat& a, const Mat& b)
{ {
CV_INSTRUMENT_REGION(); CV_INSTRUMENT_REGION();
checkOperandsExist(a, b);
MatExpr e; MatExpr e;
MatOp_Bin::makeExpr(e, 'm', a, b); MatOp_Bin::makeExpr(e, 'm', a, b);
return e; return e;
@ -1034,6 +1090,7 @@ MatExpr min(const Mat& a, double s)
{ {
CV_INSTRUMENT_REGION(); CV_INSTRUMENT_REGION();
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_Bin::makeExpr(e, 'n', a, s); MatOp_Bin::makeExpr(e, 'n', a, s);
return e; return e;
@ -1043,6 +1100,7 @@ MatExpr min(double s, const Mat& a)
{ {
CV_INSTRUMENT_REGION(); CV_INSTRUMENT_REGION();
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_Bin::makeExpr(e, 'n', a, s); MatOp_Bin::makeExpr(e, 'n', a, s);
return e; return e;
@ -1052,6 +1110,7 @@ MatExpr max(const Mat& a, const Mat& b)
{ {
CV_INSTRUMENT_REGION(); CV_INSTRUMENT_REGION();
checkOperandsExist(a, b);
MatExpr e; MatExpr e;
MatOp_Bin::makeExpr(e, 'M', a, b); MatOp_Bin::makeExpr(e, 'M', a, b);
return e; return e;
@ -1061,6 +1120,7 @@ MatExpr max(const Mat& a, double s)
{ {
CV_INSTRUMENT_REGION(); CV_INSTRUMENT_REGION();
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_Bin::makeExpr(e, 'N', a, s); MatOp_Bin::makeExpr(e, 'N', a, s);
return e; return e;
@ -1070,6 +1130,7 @@ MatExpr max(double s, const Mat& a)
{ {
CV_INSTRUMENT_REGION(); CV_INSTRUMENT_REGION();
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_Bin::makeExpr(e, 'N', a, s); MatOp_Bin::makeExpr(e, 'N', a, s);
return e; return e;
@ -1077,6 +1138,7 @@ MatExpr max(double s, const Mat& a)
MatExpr operator & (const Mat& a, const Mat& b) MatExpr operator & (const Mat& a, const Mat& b)
{ {
checkOperandsExist(a, b);
MatExpr e; MatExpr e;
MatOp_Bin::makeExpr(e, '&', a, b); MatOp_Bin::makeExpr(e, '&', a, b);
return e; return e;
@ -1084,6 +1146,7 @@ MatExpr operator & (const Mat& a, const Mat& b)
MatExpr operator & (const Mat& a, const Scalar& s) MatExpr operator & (const Mat& a, const Scalar& s)
{ {
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_Bin::makeExpr(e, '&', a, s); MatOp_Bin::makeExpr(e, '&', a, s);
return e; return e;
@ -1091,6 +1154,7 @@ MatExpr operator & (const Mat& a, const Scalar& s)
MatExpr operator & (const Scalar& s, const Mat& a) MatExpr operator & (const Scalar& s, const Mat& a)
{ {
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_Bin::makeExpr(e, '&', a, s); MatOp_Bin::makeExpr(e, '&', a, s);
return e; return e;
@ -1098,6 +1162,7 @@ MatExpr operator & (const Scalar& s, const Mat& a)
MatExpr operator | (const Mat& a, const Mat& b) MatExpr operator | (const Mat& a, const Mat& b)
{ {
checkOperandsExist(a, b);
MatExpr e; MatExpr e;
MatOp_Bin::makeExpr(e, '|', a, b); MatOp_Bin::makeExpr(e, '|', a, b);
return e; return e;
@ -1105,6 +1170,7 @@ MatExpr operator | (const Mat& a, const Mat& b)
MatExpr operator | (const Mat& a, const Scalar& s) MatExpr operator | (const Mat& a, const Scalar& s)
{ {
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_Bin::makeExpr(e, '|', a, s); MatOp_Bin::makeExpr(e, '|', a, s);
return e; return e;
@ -1112,6 +1178,7 @@ MatExpr operator | (const Mat& a, const Scalar& s)
MatExpr operator | (const Scalar& s, const Mat& a) MatExpr operator | (const Scalar& s, const Mat& a)
{ {
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_Bin::makeExpr(e, '|', a, s); MatOp_Bin::makeExpr(e, '|', a, s);
return e; return e;
@ -1119,6 +1186,7 @@ MatExpr operator | (const Scalar& s, const Mat& a)
MatExpr operator ^ (const Mat& a, const Mat& b) MatExpr operator ^ (const Mat& a, const Mat& b)
{ {
checkOperandsExist(a, b);
MatExpr e; MatExpr e;
MatOp_Bin::makeExpr(e, '^', a, b); MatOp_Bin::makeExpr(e, '^', a, b);
return e; return e;
@ -1126,6 +1194,7 @@ MatExpr operator ^ (const Mat& a, const Mat& b)
MatExpr operator ^ (const Mat& a, const Scalar& s) MatExpr operator ^ (const Mat& a, const Scalar& s)
{ {
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_Bin::makeExpr(e, '^', a, s); MatOp_Bin::makeExpr(e, '^', a, s);
return e; return e;
@ -1133,6 +1202,7 @@ MatExpr operator ^ (const Mat& a, const Scalar& s)
MatExpr operator ^ (const Scalar& s, const Mat& a) MatExpr operator ^ (const Scalar& s, const Mat& a)
{ {
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_Bin::makeExpr(e, '^', a, s); MatOp_Bin::makeExpr(e, '^', a, s);
return e; return e;
@ -1140,6 +1210,7 @@ MatExpr operator ^ (const Scalar& s, const Mat& a)
MatExpr operator ~(const Mat& a) MatExpr operator ~(const Mat& a)
{ {
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_Bin::makeExpr(e, '~', a, Scalar()); MatOp_Bin::makeExpr(e, '~', a, Scalar());
return e; return e;
@ -1149,6 +1220,7 @@ MatExpr abs(const Mat& a)
{ {
CV_INSTRUMENT_REGION(); CV_INSTRUMENT_REGION();
checkOperandsExist(a);
MatExpr e; MatExpr e;
MatOp_Bin::makeExpr(e, 'a', a, Scalar()); MatOp_Bin::makeExpr(e, 'a', a, Scalar());
return e; return e;
@ -1630,6 +1702,7 @@ MatExpr Mat::t() const
{ {
CV_INSTRUMENT_REGION(); CV_INSTRUMENT_REGION();
checkOperandsExist(*this);
MatExpr e; MatExpr e;
MatOp_T::makeExpr(e, *this); MatOp_T::makeExpr(e, *this);
return e; return e;

@ -1467,4 +1467,19 @@ TEST(Core_sortIdx, regression_8941)
"expected=" << std::endl << expected; "expected=" << std::endl << expected;
} }
//These tests guard regressions against running MatExpr
//operations on empty operands and giving bogus
//results.
TEST(Core_MatExpr, empty_check_15760)
{
EXPECT_THROW(Mat c = min(Mat(), Mat()), cv::Exception);
EXPECT_THROW(Mat c = abs(Mat()), cv::Exception);
EXPECT_THROW(Mat c = min(Mat(), Mat()), cv::Exception);
EXPECT_THROW(Mat c = Mat() | Mat(), cv::Exception);
EXPECT_THROW(Mat c = Mat() + Mat(), cv::Exception);
EXPECT_THROW(Mat c = Mat().t(), cv::Exception);
EXPECT_THROW(Mat c = Mat().cross(Mat()), cv::Exception);
}
}} // namespace }} // namespace

@ -668,6 +668,12 @@ public:
for (int i = 2; i < inputBuffers.size(); ++i) for (int i = 2; i < inputBuffers.size(); ++i)
topExpr *= inputBuffers[i](x, y, c, n); topExpr *= inputBuffers[i](x, y, c, n);
break; break;
case DIV:
topExpr = inputBuffers[0](x, y, c, n) /
inputBuffers[1](x, y, c, n);
for (int i = 2; i < inputBuffers.size(); ++i)
topExpr /= inputBuffers[i](x, y, c, n);
break;
case MAX: case MAX:
topExpr = max(inputBuffers[0](x, y, c, n), topExpr = max(inputBuffers[0](x, y, c, n),
inputBuffers[1](x, y, c, n)); inputBuffers[1](x, y, c, n));

@ -16,10 +16,11 @@ using namespace cv;
using namespace cv::dnn; using namespace cv::dnn;
using namespace testing; using namespace testing;
static void test(Mat& input, Net& net, Backend backendId, Target targetId, bool skipCheck = false) static void test(Mat& input, Net& net, Backend backendId, Target targetId, bool skipCheck = false, bool randInput = true)
{ {
DNNTestLayer::checkBackend(backendId, targetId); DNNTestLayer::checkBackend(backendId, targetId);
randu(input, -1.0f, 1.0f); if (randInput)
randu(input, -1.0f, 1.0f);
net.setInput(input); net.setInput(input);
net.setPreferableBackend(DNN_BACKEND_OPENCV); net.setPreferableBackend(DNN_BACKEND_OPENCV);
@ -776,6 +777,14 @@ TEST_P(Eltwise, Accuracy)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION); applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#endif #endif
bool convInputShift = 1;
int numEltwiseInputs = numConv;
if (op == "div")
{
numConv = 1;
convInputShift = 0; // first input is convolution
}
Net net; Net net;
std::vector<int> convLayerIds(numConv); std::vector<int> convLayerIds(numConv);
@ -815,20 +824,29 @@ TEST_P(Eltwise, Accuracy)
eltwiseParam.type = "Eltwise"; eltwiseParam.type = "Eltwise";
eltwiseParam.name = "testLayer"; eltwiseParam.name = "testLayer";
int eltwiseId = net.addLayer(eltwiseParam.name, eltwiseParam.type, eltwiseParam); int eltwiseId = net.addLayer(eltwiseParam.name, eltwiseParam.type, eltwiseParam);
net.connect(0, 0, eltwiseId, 0); if (convInputShift == 1)
net.connect(0, 0, eltwiseId, 0);
for (int i = 0; i < numConv; ++i) for (int i = 0; i < numConv; ++i)
{ {
net.connect(convLayerIds[i], 0, eltwiseId, i + 1); net.connect(convLayerIds[i], 0, eltwiseId, i + convInputShift);
}
if (convInputShift == 0)
net.connect(0, 0, eltwiseId, numConv);
for (int i = numConv; i < numEltwiseInputs; ++i)
{
net.connect(0, 0, eltwiseId, i + 1);
} }
int sz[] = {1, inSize[0], inSize[1], inSize[2]}; int sz[] = {1, inSize[0], inSize[1], inSize[2]};
Mat input(4, &sz[0], CV_32F); Mat input(4, &sz[0], CV_32F);
test(input, net, backendId, targetId); if (op == "div")
randu(input, 1.0f, 1.0f); // ensure no divisor value has absouluate value of less than 0.5
test(input, net, backendId, targetId, /*skipCheck*/false, (op == "div") ? false : true);
} }
INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, Eltwise, Combine( INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, Eltwise, Combine(
/*input size*/ Values(Vec3i(1, 4, 5), Vec3i(2, 8, 6)), /*input size*/ Values(Vec3i(1, 4, 5), Vec3i(2, 8, 6)),
/*operation*/ Values("prod", "sum", "max"), /*operation*/ Values("prod", "sum", "div", "max"),
/*num convs*/ Values(1, 2, 3), /*num convs*/ Values(1, 2, 3),
/*weighted(for sum only)*/ Bool(), /*weighted(for sum only)*/ Bool(),
dnnBackendsAndTargetsWithHalide() dnnBackendsAndTargetsWithHalide()

@ -102,7 +102,9 @@ bool BmpDecoder::readHeader()
m_width = m_strm.getDWord(); m_width = m_strm.getDWord();
m_height = m_strm.getDWord(); m_height = m_strm.getDWord();
m_bpp = m_strm.getDWord() >> 16; m_bpp = m_strm.getDWord() >> 16;
m_rle_code = (BmpCompression)m_strm.getDWord(); int m_rle_code_ = m_strm.getDWord();
CV_Assert(m_rle_code_ >= 0 && m_rle_code_ <= BMP_BITFIELDS);
m_rle_code = (BmpCompression)m_rle_code_;
m_strm.skip(12); m_strm.skip(12);
int clrused = m_strm.getDWord(); int clrused = m_strm.getDWord();
m_strm.skip( size - 36 ); m_strm.skip( size - 36 );

@ -50,16 +50,16 @@ if(BUILD_FAT_JAVA_LIB)
endif() endif()
if(APPLE) if(APPLE)
foreach(_dep ${__deps}) foreach(_dep ${__deps})
ocv_target_link_libraries(${the_module} LINK_PRIVATE -Wl,-force_load "${_dep}") ocv_target_link_libraries(${the_module} PRIVATE -Wl,-force_load "${_dep}")
endforeach() endforeach()
elseif(((CV_GCC OR CV_CLANG OR UNIX) OR (OPENCV_FORCE_FAT_JAVA_LIB_LD_RULES)) AND (NOT OPENCV_SKIP_FAT_JAVA_LIB_LD_RULES)) elseif(((CV_GCC OR CV_CLANG OR UNIX) OR (OPENCV_FORCE_FAT_JAVA_LIB_LD_RULES)) AND (NOT OPENCV_SKIP_FAT_JAVA_LIB_LD_RULES))
ocv_target_link_libraries(${the_module} LINK_PRIVATE -Wl,-whole-archive ${__deps} -Wl,-no-whole-archive) ocv_target_link_libraries(${the_module} PRIVATE -Wl,-whole-archive ${__deps} -Wl,-no-whole-archive)
else() else()
ocv_target_link_libraries(${the_module} LINK_PRIVATE ${__deps}) ocv_target_link_libraries(${the_module} PRIVATE ${__deps})
endif() endif()
ocv_target_link_libraries(${the_module} LINK_PRIVATE ${__extradeps} ${OPENCV_LINKER_LIBS}) ocv_target_link_libraries(${the_module} PRIVATE ${__extradeps} ${OPENCV_LINKER_LIBS})
else() else()
ocv_target_link_libraries(${the_module} LINK_PRIVATE ${__deps} ${OPENCV_LINKER_LIBS}) ocv_target_link_libraries(${the_module} PRIVATE ${__deps} ${OPENCV_LINKER_LIBS})
endif() endif()
# Additional target properties # Additional target properties
@ -72,8 +72,12 @@ set_target_properties(${the_module} PROPERTIES
) )
if(ANDROID) if(ANDROID)
ocv_target_link_libraries(${the_module} LINK_PUBLIC jnigraphics) # for Mat <=> Bitmap converters ocv_target_link_libraries(${the_module} PUBLIC jnigraphics # for Mat <=> Bitmap converters
ocv_target_link_libraries(${the_module} LINK_PUBLIC log dl z) INTERFACE jnigraphics
)
ocv_target_link_libraries(${the_module} PUBLIC log dl z
INTERFACE log dl z
)
# force strip library after the build command # force strip library after the build command
# because samples and tests will make a copy of the library before install # because samples and tests will make a copy of the library before install

@ -44,9 +44,9 @@ if(APPLE)
set_target_properties(${the_module} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup") set_target_properties(${the_module} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
elseif(WIN32 OR OPENCV_FORCE_PYTHON_LIBS) elseif(WIN32 OR OPENCV_FORCE_PYTHON_LIBS)
if(${PYTHON}_DEBUG_LIBRARIES AND NOT ${PYTHON}_LIBRARIES MATCHES "optimized.*debug") if(${PYTHON}_DEBUG_LIBRARIES AND NOT ${PYTHON}_LIBRARIES MATCHES "optimized.*debug")
ocv_target_link_libraries(${the_module} LINK_PRIVATE debug ${${PYTHON}_DEBUG_LIBRARIES} optimized ${${PYTHON}_LIBRARIES}) ocv_target_link_libraries(${the_module} PRIVATE debug ${${PYTHON}_DEBUG_LIBRARIES} optimized ${${PYTHON}_LIBRARIES})
else() else()
ocv_target_link_libraries(${the_module} LINK_PRIVATE ${${PYTHON}_LIBRARIES}) ocv_target_link_libraries(${the_module} PRIVATE ${${PYTHON}_LIBRARIES})
endif() endif()
endif() endif()
@ -54,7 +54,7 @@ if(TARGET gen_opencv_python_source)
set(deps ${OPENCV_MODULE_${the_module}_DEPS}) set(deps ${OPENCV_MODULE_${the_module}_DEPS})
list(REMOVE_ITEM deps opencv_python_bindings_generator) # don't add dummy module to target_link_libraries list list(REMOVE_ITEM deps opencv_python_bindings_generator) # don't add dummy module to target_link_libraries list
endif() endif()
ocv_target_link_libraries(${the_module} LINK_PRIVATE ${deps}) ocv_target_link_libraries(${the_module} PRIVATE ${deps})
if(DEFINED ${PYTHON}_CVPY_SUFFIX) if(DEFINED ${PYTHON}_CVPY_SUFFIX)
set(CVPY_SUFFIX "${${PYTHON}_CVPY_SUFFIX}") set(CVPY_SUFFIX "${${PYTHON}_CVPY_SUFFIX}")

@ -203,8 +203,8 @@ ocv_target_link_libraries(${the_module} LINK_PRIVATE ${tgts})
# copy FFmpeg dll to the output folder # copy FFmpeg dll to the output folder
if(WIN32 AND HAVE_FFMPEG_WRAPPER) if(WIN32 AND HAVE_FFMPEG_WRAPPER)
if(MSVC64 OR MINGW64) if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(FFMPEG_SUFFIX "_64") set(FFMPEG_SUFFIX _64)
endif() endif()
set(ffmpeg_dir "${OpenCV_BINARY_DIR}/3rdparty/ffmpeg") set(ffmpeg_dir "${OpenCV_BINARY_DIR}/3rdparty/ffmpeg")
set(ffmpeg_bare_name "opencv_videoio_ffmpeg${FFMPEG_SUFFIX}.dll") set(ffmpeg_bare_name "opencv_videoio_ffmpeg${FFMPEG_SUFFIX}.dll")

@ -39,4 +39,4 @@ message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}")
add_executable(${EXAMPLE_NAME} "${EXAMPLE_FILE}") add_executable(${EXAMPLE_NAME} "${EXAMPLE_FILE}")
# Link your application with OpenCV libraries # Link your application with OpenCV libraries
target_link_libraries(${EXAMPLE_NAME} LINK_PRIVATE ${OpenCV_LIBS}) target_link_libraries(${EXAMPLE_NAME} PRIVATE ${OpenCV_LIBS})

@ -35,12 +35,12 @@ foreach(sample_filename ${cpp_samples})
set(package "tutorial") set(package "tutorial")
endif() endif()
ocv_define_sample(tgt ${sample_filename} ${package}) ocv_define_sample(tgt ${sample_filename} ${package})
ocv_target_link_libraries(${tgt} LINK_PRIVATE ${OPENCV_LINKER_LIBS} ${OPENCV_CPP_SAMPLES_REQUIRED_DEPS}) ocv_target_link_libraries(${tgt} PRIVATE ${OPENCV_LINKER_LIBS} ${OPENCV_CPP_SAMPLES_REQUIRED_DEPS})
if(sample_filename MATCHES "/gpu/" AND HAVE_opencv_cudaarithm AND HAVE_opencv_cuda_filters) if(sample_filename MATCHES "/gpu/" AND HAVE_opencv_cudaarithm AND HAVE_opencv_cuda_filters)
ocv_target_link_libraries(${tgt} LINK_PRIVATE opencv_cudaarithm opencv_cudafilters) ocv_target_link_libraries(${tgt} PRIVATE opencv_cudaarithm opencv_cudafilters)
endif() endif()
if(sample_filename MATCHES "/viz/") if(sample_filename MATCHES "/viz/")
ocv_target_link_libraries(${tgt} LINK_PRIVATE ${VTK_LIBRARIES}) ocv_target_link_libraries(${tgt} PRIVATE ${VTK_LIBRARIES})
target_compile_definitions(${tgt} PRIVATE -DUSE_VTK) target_compile_definitions(${tgt} PRIVATE -DUSE_VTK)
endif() endif()
if(HAVE_OPENGL AND sample_filename MATCHES "detect_mser") if(HAVE_OPENGL AND sample_filename MATCHES "detect_mser")

@ -27,4 +27,4 @@ message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}")
add_executable(opencv_example example.cpp) add_executable(opencv_example example.cpp)
# Link your application with OpenCV libraries # Link your application with OpenCV libraries
target_link_libraries(opencv_example LINK_PRIVATE ${OpenCV_LIBS}) target_link_libraries(opencv_example PRIVATE ${OpenCV_LIBS})

@ -17,5 +17,5 @@ ocv_include_modules_recurse(${OPENCV_CPP_SAMPLES_REQUIRED_DEPS})
add_executable( ${target}pnp_registration ${sample_dir}main_registration.cpp ${sample_pnplib} ) add_executable( ${target}pnp_registration ${sample_dir}main_registration.cpp ${sample_pnplib} )
add_executable( ${target}pnp_detection ${sample_dir}main_detection.cpp ${sample_pnplib} ) add_executable( ${target}pnp_detection ${sample_dir}main_detection.cpp ${sample_pnplib} )
ocv_target_link_libraries(${target}pnp_registration LINK_PRIVATE ${OPENCV_LINKER_LIBS} ${OPENCV_CPP_SAMPLES_REQUIRED_DEPS}) ocv_target_link_libraries(${target}pnp_registration PRIVATE ${OPENCV_LINKER_LIBS} ${OPENCV_CPP_SAMPLES_REQUIRED_DEPS})
ocv_target_link_libraries(${target}pnp_detection LINK_PRIVATE ${OPENCV_LINKER_LIBS} ${OPENCV_CPP_SAMPLES_REQUIRED_DEPS}) ocv_target_link_libraries(${target}pnp_detection PRIVATE ${OPENCV_LINKER_LIBS} ${OPENCV_CPP_SAMPLES_REQUIRED_DEPS})

@ -17,5 +17,5 @@ ocv_include_modules_recurse(${tgt} ${OPENCV_DIRECTX_SAMPLES_REQUIRED_DEPS})
file(GLOB all_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp) file(GLOB all_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp)
foreach(sample_filename ${all_samples}) foreach(sample_filename ${all_samples})
ocv_define_sample(tgt ${sample_filename} directx) ocv_define_sample(tgt ${sample_filename} directx)
ocv_target_link_libraries(${tgt} LINK_PRIVATE ${OPENCV_LINKER_LIBS} ${OPENCV_DIRECTX_SAMPLES_REQUIRED_DEPS}) ocv_target_link_libraries(${tgt} PRIVATE ${OPENCV_LINKER_LIBS} ${OPENCV_DIRECTX_SAMPLES_REQUIRED_DEPS})
endforeach() endforeach()

@ -18,5 +18,5 @@ ocv_include_modules_recurse(${OPENCV_DNN_SAMPLES_REQUIRED_DEPS})
file(GLOB_RECURSE dnn_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp) file(GLOB_RECURSE dnn_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp)
foreach(sample_filename ${dnn_samples}) foreach(sample_filename ${dnn_samples})
ocv_define_sample(tgt ${sample_filename} dnn) ocv_define_sample(tgt ${sample_filename} dnn)
ocv_target_link_libraries(${tgt} LINK_PRIVATE ${OPENCV_LINKER_LIBS} ${OPENCV_DNN_SAMPLES_REQUIRED_DEPS}) ocv_target_link_libraries(${tgt} PRIVATE ${OPENCV_LINKER_LIBS} ${OPENCV_DNN_SAMPLES_REQUIRED_DEPS})
endforeach() endforeach()

@ -51,11 +51,11 @@ endif()
file(GLOB all_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp) file(GLOB all_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp)
foreach(sample_filename ${all_samples}) foreach(sample_filename ${all_samples})
ocv_define_sample(tgt ${sample_filename} gpu) ocv_define_sample(tgt ${sample_filename} gpu)
ocv_target_link_libraries(${tgt} LINK_PRIVATE ${OPENCV_LINKER_LIBS} ${OPENCV_CUDA_SAMPLES_REQUIRED_DEPS}) ocv_target_link_libraries(${tgt} PRIVATE ${OPENCV_LINKER_LIBS} ${OPENCV_CUDA_SAMPLES_REQUIRED_DEPS})
if(HAVE_opencv_xfeatures2d) if(HAVE_opencv_xfeatures2d)
ocv_target_link_libraries(${tgt} LINK_PRIVATE opencv_xfeatures2d) ocv_target_link_libraries(${tgt} PRIVATE opencv_xfeatures2d)
endif() endif()
if(HAVE_opencv_cudacodec) if(HAVE_opencv_cudacodec)
ocv_target_link_libraries(${tgt} LINK_PRIVATE opencv_cudacodec) ocv_target_link_libraries(${tgt} PRIVATE opencv_cudacodec)
endif() endif()
endforeach() endforeach()

@ -31,7 +31,7 @@ ocv_include_directories(${OpenCL_INCLUDE_DIR})
file(GLOB all_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp) file(GLOB all_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp)
foreach(sample_filename ${all_samples}) foreach(sample_filename ${all_samples})
ocv_define_sample(tgt ${sample_filename} opencl) ocv_define_sample(tgt ${sample_filename} opencl)
ocv_target_link_libraries(${tgt} LINK_PRIVATE ocv_target_link_libraries(${tgt} PRIVATE
${OPENCV_LINKER_LIBS} ${OPENCV_LINKER_LIBS}
${OPENCV_OPENCL_SAMPLES_REQUIRED_DEPS} ${OPENCV_OPENCL_SAMPLES_REQUIRED_DEPS}
${OpenCL_LIBRARY}) ${OpenCL_LIBRARY})

@ -23,9 +23,9 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND)
endif() endif()
foreach(sample_filename ${all_samples}) foreach(sample_filename ${all_samples})
ocv_define_sample(tgt ${sample_filename} opengl) ocv_define_sample(tgt ${sample_filename} opengl)
ocv_target_link_libraries(${tgt} LINK_PRIVATE ${OPENCV_LINKER_LIBS} ${OPENCV_OPENGL_SAMPLES_REQUIRED_DEPS}) ocv_target_link_libraries(${tgt} PRIVATE ${OPENCV_LINKER_LIBS} ${OPENCV_OPENGL_SAMPLES_REQUIRED_DEPS})
if(sample_filename STREQUAL "opengl_interop.cpp") if(sample_filename STREQUAL "opengl_interop.cpp")
ocv_target_link_libraries(${tgt} LINK_PRIVATE ${X11_LIBRARIES}) ocv_target_link_libraries(${tgt} PRIVATE ${X11_LIBRARIES})
ocv_target_include_directories(${tgt} ${X11_INCLUDE_DIR}) ocv_target_include_directories(${tgt} ${X11_INCLUDE_DIR})
endif() endif()
endforeach() endforeach()

@ -21,5 +21,5 @@ add_definitions(-DIVX_HIDE_INFO_WARNINGS)
file(GLOB_RECURSE cpp_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp) file(GLOB_RECURSE cpp_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp)
foreach(sample_filename ${cpp_samples}) foreach(sample_filename ${cpp_samples})
ocv_define_sample(tgt ${sample_filename} openvx) ocv_define_sample(tgt ${sample_filename} openvx)
ocv_target_link_libraries(${tgt} LINK_PRIVATE ${OPENCV_LINKER_LIBS} ${OPENCV_OPENVX_SAMPLE_REQUIRED_DEPS}) ocv_target_link_libraries(${tgt} PRIVATE ${OPENCV_LINKER_LIBS} ${OPENCV_OPENVX_SAMPLE_REQUIRED_DEPS})
endforeach() endforeach()

@ -6,7 +6,7 @@ function(ocv_define_sample out_target source sub)
set(the_target "example_${sub}_${name}") set(the_target "example_${sub}_${name}")
add_executable(${the_target} "${source}") add_executable(${the_target} "${source}")
if(TARGET Threads::Threads AND NOT OPENCV_EXAMPLES_DISABLE_THREADS) if(TARGET Threads::Threads AND NOT OPENCV_EXAMPLES_DISABLE_THREADS)
target_link_libraries(${the_target} LINK_PRIVATE Threads::Threads) target_link_libraries(${the_target} PRIVATE Threads::Threads)
endif() endif()
set_target_properties(${the_target} PROPERTIES PROJECT_LABEL "(sample) ${name}") set_target_properties(${the_target} PROPERTIES PROJECT_LABEL "(sample) ${name}")
if(ENABLE_SOLUTION_FOLDERS) if(ENABLE_SOLUTION_FOLDERS)

@ -22,5 +22,5 @@ ocv_include_modules_recurse(${OPENCV_TAPI_SAMPLES_REQUIRED_DEPS})
file(GLOB all_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp) file(GLOB all_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp)
foreach(sample_filename ${all_samples}) foreach(sample_filename ${all_samples})
ocv_define_sample(tgt ${sample_filename} tapi) ocv_define_sample(tgt ${sample_filename} tapi)
ocv_target_link_libraries(${tgt} LINK_PRIVATE ${OPENCV_LINKER_LIBS} ${OPENCV_TAPI_SAMPLES_REQUIRED_DEPS}) ocv_target_link_libraries(${tgt} PRIVATE ${OPENCV_LINKER_LIBS} ${OPENCV_TAPI_SAMPLES_REQUIRED_DEPS})
endforeach() endforeach()

@ -17,5 +17,5 @@ ocv_include_modules_recurse(${OPENCV_VA_INTEL_SAMPLES_REQUIRED_DEPS})
file(GLOB all_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp) file(GLOB all_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp)
foreach(sample_filename ${all_samples}) foreach(sample_filename ${all_samples})
ocv_define_sample(tgt ${sample_filename} va_intel) ocv_define_sample(tgt ${sample_filename} va_intel)
ocv_target_link_libraries(${tgt} LINK_PRIVATE ${OPENCV_LINKER_LIBS} ${OPENCV_VA_INTEL_SAMPLES_REQUIRED_DEPS} ${VA_LIBRARIES} ${VA_INTEL_LIBRARIES}) ocv_target_link_libraries(${tgt} PRIVATE ${OPENCV_LINKER_LIBS} ${OPENCV_VA_INTEL_SAMPLES_REQUIRED_DEPS} ${VA_LIBRARIES} ${VA_INTEL_LIBRARIES})
endforeach() endforeach()

Loading…
Cancel
Save