diff --git a/3rdparty/libwebp/src/dec/quant_dec.c b/3rdparty/libwebp/src/dec/quant_dec.c index f07212ad73..a0ac018b0f 100644 --- a/3rdparty/libwebp/src/dec/quant_dec.c +++ b/3rdparty/libwebp/src/dec/quant_dec.c @@ -61,12 +61,17 @@ static const uint16_t kAcTable[128] = { void VP8ParseQuant(VP8Decoder* const dec) { VP8BitReader* const br = &dec->br_; - const int base_q0 = VP8GetValue(br, 7); - const int dqy1_dc = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0; - const int dqy2_dc = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0; - const int dqy2_ac = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0; - const int dquv_dc = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0; - const int dquv_ac = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0; + const int base_q0 = VP8GetValue(br, 7, "global-header"); + const int dqy1_dc = VP8Get(br, "global-header") ? + VP8GetSignedValue(br, 4, "global-header") : 0; + const int dqy2_dc = VP8Get(br, "global-header") ? + VP8GetSignedValue(br, 4, "global-header") : 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_; int i; diff --git a/3rdparty/libwebp/src/dec/tree_dec.c b/3rdparty/libwebp/src/dec/tree_dec.c index 3f5a957d32..1c6fdea27c 100644 --- a/3rdparty/libwebp/src/dec/tree_dec.c +++ b/3rdparty/libwebp/src/dec/tree_dec.c @@ -296,20 +296,21 @@ static void ParseIntraMode(VP8BitReader* const br, // to decode more than 1 keyframe. if (dec->segment_hdr_.update_map_) { // Hardcoded tree parsing - block->segment_ = !VP8GetBit(br, dec->proba_.segments_[0]) - ? VP8GetBit(br, dec->proba_.segments_[1]) - : 2 + VP8GetBit(br, dec->proba_.segments_[2]); + block->segment_ = !VP8GetBit(br, dec->proba_.segments_[0], "segments") + ? VP8GetBit(br, dec->proba_.segments_[1], "segments") + : VP8GetBit(br, dec->proba_.segments_[2], "segments") + 2; } else { 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_) { // Hardcoded 16x16 intra-mode decision tree. const int ymode = - VP8GetBit(br, 156) ? (VP8GetBit(br, 128) ? TM_PRED : H_PRED) - : (VP8GetBit(br, 163) ? V_PRED : DC_PRED); + VP8GetBit(br, 156, "pred-modes") ? + (VP8GetBit(br, 128, "pred-modes") ? TM_PRED : H_PRED) : + (VP8GetBit(br, 163, "pred-modes") ? V_PRED : DC_PRED); block->imodes_[0] = ymode; memset(top, ymode, 4 * sizeof(*top)); 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]; #if (USE_GENERIC_TREE == 1) // Generic tree-parsing - int i = kYModesIntra4[VP8GetBit(br, prob[0])]; + int i = kYModesIntra4[VP8GetBit(br, prob[0], "pred-modes")]; while (i > 0) { - i = kYModesIntra4[2 * i + VP8GetBit(br, prob[i])]; + i = kYModesIntra4[2 * i + VP8GetBit(br, prob[i], "pred-modes")]; } ymode = -i; #else // Hardcoded tree parsing - ymode = !VP8GetBit(br, prob[0]) ? B_DC_PRED : - !VP8GetBit(br, prob[1]) ? B_TM_PRED : - !VP8GetBit(br, prob[2]) ? B_VE_PRED : - !VP8GetBit(br, prob[3]) ? - (!VP8GetBit(br, prob[4]) ? B_HE_PRED : - (!VP8GetBit(br, prob[5]) ? B_RD_PRED : B_VR_PRED)) : - (!VP8GetBit(br, prob[6]) ? B_LD_PRED : - (!VP8GetBit(br, prob[7]) ? B_VL_PRED : - (!VP8GetBit(br, prob[8]) ? B_HD_PRED : B_HU_PRED))); + ymode = !VP8GetBit(br, prob[0], "pred-modes") ? B_DC_PRED : + !VP8GetBit(br, prob[1], "pred-modes") ? B_TM_PRED : + !VP8GetBit(br, prob[2], "pred-modes") ? B_VE_PRED : + !VP8GetBit(br, prob[3], "pred-modes") ? + (!VP8GetBit(br, prob[4], "pred-modes") ? B_HE_PRED : + (!VP8GetBit(br, prob[5], "pred-modes") ? B_RD_PRED + : B_VR_PRED)) : + (!VP8GetBit(br, prob[6], "pred-modes") ? B_LD_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 top[x] = ymode; } @@ -348,9 +352,9 @@ static void ParseIntraMode(VP8BitReader* const br, } } // Hardcoded UVMode decision tree - block->uvmode_ = !VP8GetBit(br, 142) ? DC_PRED - : !VP8GetBit(br, 114) ? V_PRED - : VP8GetBit(br, 183) ? TM_PRED : H_PRED; + block->uvmode_ = !VP8GetBit(br, 142, "pred-modes-uv") ? DC_PRED + : !VP8GetBit(br, 114, "pred-modes-uv") ? V_PRED + : VP8GetBit(br, 183, "pred-modes-uv") ? TM_PRED : H_PRED; } 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 (c = 0; c < NUM_CTX; ++c) { for (p = 0; p < NUM_PROBAS; ++p) { - const int v = VP8GetBit(br, CoeffsUpdateProba[t][b][c][p]) ? - VP8GetValue(br, 8) : CoeffsProba0[t][b][c][p]; + const int v = + 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; } } @@ -524,9 +530,8 @@ void VP8ParseProba(VP8BitReader* const br, VP8Decoder* const dec) { 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_) { - dec->skip_p_ = VP8GetValue(br, 8); + dec->skip_p_ = VP8GetValue(br, 8, "global-header"); } } - diff --git a/3rdparty/libwebp/src/dec/vp8_dec.c b/3rdparty/libwebp/src/dec/vp8_dec.c index c904b529f6..57efb69041 100644 --- a/3rdparty/libwebp/src/dec/vp8_dec.c +++ b/3rdparty/libwebp/src/dec/vp8_dec.c @@ -161,23 +161,26 @@ static int ParseSegmentHeader(VP8BitReader* br, VP8SegmentHeader* hdr, VP8Proba* proba) { assert(br != NULL); assert(hdr != NULL); - hdr->use_segment_ = VP8Get(br); + hdr->use_segment_ = VP8Get(br, "global-header"); if (hdr->use_segment_) { - hdr->update_map_ = VP8Get(br); - if (VP8Get(br)) { // update data + hdr->update_map_ = VP8Get(br, "global-header"); + if (VP8Get(br, "global-header")) { // update data int s; - hdr->absolute_delta_ = VP8Get(br); + hdr->absolute_delta_ = VP8Get(br, "global-header"); 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) { - 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_) { int 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 { @@ -205,7 +208,7 @@ static VP8StatusCode ParsePartitions(VP8Decoder* const dec, size_t last_part; 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_; if (size < 3 * last_part) { // 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 static int ParseFilterHeader(VP8BitReader* br, VP8Decoder* const dec) { VP8FilterHeader* const hdr = &dec->filter_hdr_; - hdr->simple_ = VP8Get(br); - hdr->level_ = VP8GetValue(br, 6); - hdr->sharpness_ = VP8GetValue(br, 3); - hdr->use_lf_delta_ = VP8Get(br); + hdr->simple_ = VP8Get(br, "global-header"); + hdr->level_ = VP8GetValue(br, 6, "global-header"); + hdr->sharpness_ = VP8GetValue(br, 3, "global-header"); + hdr->use_lf_delta_ = VP8Get(br, "global-header"); if (hdr->use_lf_delta_) { - if (VP8Get(br)) { // update lf-delta? + if (VP8Get(br, "global-header")) { // update lf-delta? int i; for (i = 0; i < NUM_REF_LF_DELTAS; ++i) { - if (VP8Get(br)) { - hdr->ref_lf_delta_[i] = VP8GetSignedValue(br, 6); + if (VP8Get(br, "global-header")) { + hdr->ref_lf_delta_[i] = VP8GetSignedValue(br, 6, "global-header"); } } for (i = 0; i < NUM_MODE_LF_DELTAS; ++i) { - if (VP8Get(br)) { - hdr->mode_lf_delta_[i] = VP8GetSignedValue(br, 6); + if (VP8Get(br, "global-header")) { + 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_; if (frm_hdr->key_frame_) { - pic_hdr->colorspace_ = VP8Get(br); - pic_hdr->clamp_type_ = VP8Get(br); + pic_hdr->colorspace_ = VP8Get(br, "global-header"); + pic_hdr->clamp_type_ = VP8Get(br, "global-header"); } if (!ParseSegmentHeader(br, &dec->segment_hdr_, &dec->proba_)) { return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR, @@ -378,7 +381,7 @@ int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) { "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); @@ -403,28 +406,28 @@ static const uint8_t kZigzag[16] = { // See section 13-2: http://tools.ietf.org/html/rfc6386#section-13.2 static int GetLargeValue(VP8BitReader* const br, const uint8_t* const p) { int v; - if (!VP8GetBit(br, p[3])) { - if (!VP8GetBit(br, p[4])) { + if (!VP8GetBit(br, p[3], "coeffs")) { + if (!VP8GetBit(br, p[4], "coeffs")) { v = 2; } else { - v = 3 + VP8GetBit(br, p[5]); + v = 3 + VP8GetBit(br, p[5], "coeffs"); } } else { - if (!VP8GetBit(br, p[6])) { - if (!VP8GetBit(br, p[7])) { - v = 5 + VP8GetBit(br, 159); + if (!VP8GetBit(br, p[6], "coeffs")) { + if (!VP8GetBit(br, p[7], "coeffs")) { + v = 5 + VP8GetBit(br, 159, "coeffs"); } else { - v = 7 + 2 * VP8GetBit(br, 165); - v += VP8GetBit(br, 145); + v = 7 + 2 * VP8GetBit(br, 165, "coeffs"); + v += VP8GetBit(br, 145, "coeffs"); } } else { const uint8_t* tab; - const int bit1 = VP8GetBit(br, p[8]); - const int bit0 = VP8GetBit(br, p[9 + bit1]); + const int bit1 = VP8GetBit(br, p[8], "coeffs"); + const int bit0 = VP8GetBit(br, p[9 + bit1], "coeffs"); const int cat = 2 * bit1 + bit0; v = 0; for (tab = kCat3456[cat]; *tab; ++tab) { - v += v + VP8GetBit(br, *tab); + v += v + VP8GetBit(br, *tab, "coeffs"); } 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) { const uint8_t* p = prob[n]->probas_[ctx]; for (; n < 16; ++n) { - if (!VP8GetBit(br, p[0])) { + if (!VP8GetBit(br, p[0], "coeffs")) { 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]; if (n == 16) return 16; } { // non zero coeff const VP8ProbaArray* const p_ctx = &prob[n + 1]->probas_[0]; int v; - if (!VP8GetBit(br, p[2])) { + if (!VP8GetBit(br, p[2], "coeffs")) { v = 1; p = p_ctx[1]; } else { v = GetLargeValue(br, p); 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; @@ -468,24 +471,24 @@ static int GetCoeffsAlt(VP8BitReader* const br, int ctx, const quant_t dq, int n, int16_t* out) { const uint8_t* p = prob[n]->probas_[ctx]; for (; n < 16; ++n) { - if (!VP8GetBitAlt(br, p[0])) { + if (!VP8GetBitAlt(br, p[0], "coeffs")) { 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]; if (n == 16) return 16; } { // non zero coeff const VP8ProbaArray* const p_ctx = &prob[n + 1]->probas_[0]; int v; - if (!VP8GetBitAlt(br, p[2])) { + if (!VP8GetBitAlt(br, p[2], "coeffs")) { v = 1; p = p_ctx[1]; } else { v = GetLargeValue(br, p); 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; diff --git a/3rdparty/libwebp/src/dec/vp8i_dec.h b/3rdparty/libwebp/src/dec/vp8i_dec.h index 2d7900aae1..3de8d86f90 100644 --- a/3rdparty/libwebp/src/dec/vp8i_dec.h +++ b/3rdparty/libwebp/src/dec/vp8i_dec.h @@ -32,7 +32,7 @@ extern "C" { // version numbers #define DEC_MAJ_VERSION 1 #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). // Constraints are: We need to store one 16x16 block of luma samples (y), diff --git a/3rdparty/libwebp/src/dec/vp8l_dec.c b/3rdparty/libwebp/src/dec/vp8l_dec.c index 333bb3e80d..d3e27119ea 100644 --- a/3rdparty/libwebp/src/dec/vp8l_dec.c +++ b/3rdparty/libwebp/src/dec/vp8l_dec.c @@ -362,12 +362,8 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize, VP8LMetadata* const hdr = &dec->hdr_; uint32_t* huffman_image = 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_bogus = NULL; - HuffmanCode* next = NULL; + HuffmanCode* huffman_table = NULL; int num_htree_groups = 1; int num_htree_groups_max = 1; 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++; 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 { num_htree_groups = num_htree_groups_max; } @@ -453,63 +443,71 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize, goto Error; } - next = huffman_tables; + huffman_table = huffman_tables; for (i = 0; i < num_htree_groups_max; ++i) { - // If the index "i" is unused in the Huffman image, read the coefficients - // but store them to a bogus htree_group. - const int is_bogus = (mapping != NULL && mapping[i] == -1); - HTreeGroup* const htree_group = - is_bogus ? &htree_group_bogus : - &htree_groups[(mapping == NULL) ? i : mapping[i]]; - HuffmanCode** const htrees = htree_group->htrees; - HuffmanCode* huffman_tables_i = is_bogus ? huffman_tables_bogus : next; - int size; - int total_size = 0; - int is_trivial_literal = 1; - 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); + // If the index "i" is unused in the Huffman image, just make sure the + // coefficients are valid but do not store them. + if (mapping != NULL && mapping[i] == -1) { + for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) { + int alphabet_size = kAlphabetSize[j]; + if (j == 0 && color_cache_bits > 0) { + alphabet_size += (1 << color_cache_bits); + } + // Passing in NULL so that nothing gets filled. + if (!ReadHuffmanCode(alphabet_size, dec, code_lengths, NULL)) { + goto Error; + } } - total_size += huffman_tables_i->bits; - huffman_tables_i += 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]; + } else { + HTreeGroup* const htree_group = + &htree_groups[(mapping == NULL) ? i : mapping[i]]; + HuffmanCode** const htrees = htree_group->htrees; + int size; + int total_size = 0; + int is_trivial_literal = 1; + 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; } - } - if (!is_bogus) next = huffman_tables_i; - htree_group->is_trivial_literal = is_trivial_literal; - htree_group->is_trivial_code = 0; - if (is_trivial_literal) { - const int red = htrees[RED][0].value; - const int blue = htrees[BLUE][0].value; - const int alpha = htrees[ALPHA][0].value; - htree_group->literal_arb = ((uint32_t)alpha << 24) | (red << 16) | blue; - if (total_size == 0 && htrees[GREEN][0].value < NUM_LITERAL_CODES) { - htree_group->is_trivial_code = 1; - htree_group->literal_arb |= htrees[GREEN][0].value << 8; + htree_group->is_trivial_literal = is_trivial_literal; + htree_group->is_trivial_code = 0; + if (is_trivial_literal) { + const int red = htrees[RED][0].value; + const int blue = htrees[BLUE][0].value; + const int alpha = htrees[ALPHA][0].value; + htree_group->literal_arb = ((uint32_t)alpha << 24) | (red << 16) | blue; + if (total_size == 0 && htrees[GREEN][0].value < NUM_LITERAL_CODES) { + 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; @@ -521,7 +519,6 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize, Error: WebPSafeFree(code_lengths); - WebPSafeFree(huffman_tables_bogus); WebPSafeFree(mapping); if (!ok) { WebPSafeFree(huffman_image); diff --git a/3rdparty/libwebp/src/demux/demux.c b/3rdparty/libwebp/src/demux/demux.c index d8f7a40a56..ab6433e54b 100644 --- a/3rdparty/libwebp/src/demux/demux.c +++ b/3rdparty/libwebp/src/demux/demux.c @@ -25,7 +25,7 @@ #define DMUX_MAJ_VERSION 1 #define DMUX_MIN_VERSION 0 -#define DMUX_REV_VERSION 2 +#define DMUX_REV_VERSION 3 typedef struct { size_t start_; // start location of the data diff --git a/3rdparty/libwebp/src/dsp/alpha_processing_sse2.c b/3rdparty/libwebp/src/dsp/alpha_processing_sse2.c index 76587006a1..2871c56d84 100644 --- a/3rdparty/libwebp/src/dsp/alpha_processing_sse2.c +++ b/3rdparty/libwebp/src/dsp/alpha_processing_sse2.c @@ -214,7 +214,7 @@ static void ApplyAlphaMultiply_SSE2(uint8_t* rgba, int alpha_first, // Alpha detection 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; for (; i + 16 <= length; i += 16) { 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) { 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; // 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 diff --git a/3rdparty/libwebp/src/dsp/cpu.c b/3rdparty/libwebp/src/dsp/cpu.c index 8b40feed29..0fa5b6a5ce 100644 --- a/3rdparty/libwebp/src/dsp/cpu.c +++ b/3rdparty/libwebp/src/dsp/cpu.c @@ -173,8 +173,8 @@ static int AndroidCPUInfo(CPUFeature feature) { const AndroidCpuFamily cpu_family = android_getCpuFamily(); const uint64_t cpu_features = android_getCpuFeatures(); if (feature == kNEON) { - return (cpu_family == ANDROID_CPU_FAMILY_ARM && - 0 != (cpu_features & ANDROID_CPU_ARM_FEATURE_NEON)); + return cpu_family == ANDROID_CPU_FAMILY_ARM && + (cpu_features & ANDROID_CPU_ARM_FEATURE_NEON) != 0; } return 0; } diff --git a/3rdparty/libwebp/src/dsp/dec_sse2.c b/3rdparty/libwebp/src/dsp/dec_sse2.c index b3840faf3a..873aa59e8a 100644 --- a/3rdparty/libwebp/src/dsp/dec_sse2.c +++ b/3rdparty/libwebp/src/dsp/dec_sse2.c @@ -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_hi = _mm_srai_epi16(*a0_hi, 7); 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); *qi = _mm_subs_epi8(*qi, delta); 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 q1, 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 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 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, int thresh) { __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) const __m128i p1s = _mm_xor_si128(*p1, 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, int hev_thresh) { 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 k3 = _mm_set1_epi8(3); 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, int hev_thresh) { 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; // 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 abcd = _mm_avg_epu8(XABCD, ABCD0); 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 lsb = _mm_and_si128(_mm_xor_si128(IXABCD, ABCD0), one); const __m128i avg2 = _mm_subs_epu8(avg1, lsb); diff --git a/3rdparty/libwebp/src/dsp/enc_sse2.c b/3rdparty/libwebp/src/dsp/enc_sse2.c index 7b3f142c31..b2e78ed941 100644 --- a/3rdparty/libwebp/src/dsp/enc_sse2.c +++ b/3rdparty/libwebp/src/dsp/enc_sse2.c @@ -777,7 +777,7 @@ static WEBP_INLINE void VR4_SSE2(uint8_t* dst, const __m128i ABCD0 = _mm_srli_si128(XABCD, 1); const __m128i abcd = _mm_avg_epu8(XABCD, ABCD0); 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 lsb = _mm_and_si128(_mm_xor_si128(IXABCD, ABCD0), one); const __m128i avg2 = _mm_subs_epu8(avg1, lsb); diff --git a/3rdparty/libwebp/src/dsp/filters.c b/3rdparty/libwebp/src/dsp/filters.c index 069a22eaef..9e910d99c9 100644 --- a/3rdparty/libwebp/src/dsp/filters.c +++ b/3rdparty/libwebp/src/dsp/filters.c @@ -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) { int i; 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 { - 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], preds[w - stride], preds[w - stride - 1]); - out[w] = in[w] + (inverse ? pred : -pred); + out[w] = (uint8_t)(in[w] + (inverse ? pred : -pred)); } ++row; 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]; int i; for (i = 0; i < width; ++i) { - out[i] = pred + in[i]; + out[i] = (uint8_t)(pred + in[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); } else { 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 @@ -220,7 +220,7 @@ static void GradientUnfilter_C(const uint8_t* prev, const uint8_t* in, int i; for (i = 0; i < width; ++i) { 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; out[i] = left; } diff --git a/3rdparty/libwebp/src/dsp/filters_sse2.c b/3rdparty/libwebp/src/dsp/filters_sse2.c index 5a18895676..4b3f2d020f 100644 --- a/3rdparty/libwebp/src/dsp/filters_sse2.c +++ b/3rdparty/libwebp/src/dsp/filters_sse2.c @@ -163,7 +163,8 @@ static void GradientPredictDirect_SSE2(const uint8_t* const row, _mm_storel_epi64((__m128i*)(out + i), H); } 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. 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); ++row; in += stride; @@ -223,7 +224,7 @@ static void HorizontalUnfilter_SSE2(const uint8_t* prev, const uint8_t* in, uint8_t* out, int width) { int i; __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; last = _mm_set_epi32(0, 0, 0, out[0]); 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); 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, @@ -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 + 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); } 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) { HorizontalUnfilter_SSE2(NULL, in, out, width); } 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); } } diff --git a/3rdparty/libwebp/src/dsp/lossless.c b/3rdparty/libwebp/src/dsp/lossless.c index d21aa6a0a0..d05af84e7b 100644 --- a/3rdparty/libwebp/src/dsp/lossless.c +++ b/3rdparty/libwebp/src/dsp/lossless.c @@ -270,14 +270,14 @@ void VP8LTransformColorInverse_C(const VP8LMultipliers* const m, int i; for (i = 0; i < num_pixels; ++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; int new_red = red & 0xff; int new_blue = argb & 0xff; new_red += ColorTransformDelta(m->green_to_red_, green); new_red &= 0xff; 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; dst[i] = (argb & 0xff00ff00u) | (new_red << 16) | (new_blue); } diff --git a/3rdparty/libwebp/src/dsp/lossless_enc.c b/3rdparty/libwebp/src/dsp/lossless_enc.c index 1408fbf580..9c36055afc 100644 --- a/3rdparty/libwebp/src/dsp/lossless_enc.c +++ b/3rdparty/libwebp/src/dsp/lossless_enc.c @@ -515,13 +515,17 @@ static WEBP_INLINE int ColorTransformDelta(int8_t color_pred, int8_t color) { 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, int num_pixels) { int i; for (i = 0; i < num_pixels; ++i) { const uint32_t argb = data[i]; - const uint32_t green = argb >> 8; - const uint32_t red = argb >> 16; + const int8_t green = U32ToS8(argb >> 8); + const int8_t red = U32ToS8(argb >> 16); int new_red = red & 0xff; int new_blue = argb & 0xff; 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, uint32_t argb) { - const uint32_t green = argb >> 8; + const int8_t green = U32ToS8(argb >> 8); int new_red = argb >> 16; new_red -= ColorTransformDelta(green_to_red, green); 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, uint8_t red_to_blue, uint32_t argb) { - const uint32_t green = argb >> 8; - const uint32_t red = argb >> 16; - uint8_t new_blue = argb; + const int8_t green = U32ToS8(argb >> 8); + const int8_t red = U32ToS8(argb >> 16); + uint8_t new_blue = argb & 0xff; new_blue -= ColorTransformDelta(green_to_blue, green); new_blue -= ColorTransformDelta(red_to_blue, red); return (new_blue & 0xff); @@ -558,7 +562,7 @@ void VP8LCollectColorRedTransforms_C(const uint32_t* argb, int stride, while (tile_height-- > 0) { int 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; } @@ -571,7 +575,8 @@ void VP8LCollectColorBlueTransforms_C(const uint32_t* argb, int stride, while (tile_height-- > 0) { int 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; } diff --git a/3rdparty/libwebp/src/dsp/lossless_enc_sse2.c b/3rdparty/libwebp/src/dsp/lossless_enc_sse2.c index 36478c4912..8adc52139b 100644 --- a/3rdparty/libwebp/src/dsp/lossless_enc_sse2.c +++ b/3rdparty/libwebp/src/dsp/lossless_enc_sse2.c @@ -363,7 +363,7 @@ static void BundleColorMap_SSE2(const uint8_t* const row, int width, int xbits, assert(xbits <= 3); switch (xbits) { case 0: { - const __m128i ff = _mm_set1_epi16(0xff00); + const __m128i ff = _mm_set1_epi16((short)0xff00); const __m128i zero = _mm_setzero_si128(); // Store 0xff000000 | (row[x] << 8). 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; } case 1: { - const __m128i ff = _mm_set1_epi16(0xff00); + const __m128i ff = _mm_set1_epi16((short)0xff00); const __m128i mul = _mm_set1_epi16(0x110); for (x = 0; x + 16 <= width; x += 16, dst += 8) { // 0a0b | (where a/b are 4 bits). diff --git a/3rdparty/libwebp/src/dsp/lossless_enc_sse41.c b/3rdparty/libwebp/src/dsp/lossless_enc_sse41.c index 2e12a712eb..719d8ed25e 100644 --- a/3rdparty/libwebp/src/dsp/lossless_enc_sse41.c +++ b/3rdparty/libwebp/src/dsp/lossless_enc_sse41.c @@ -51,9 +51,9 @@ static void CollectColorBlueTransforms_SSE41(const uint32_t* argb, int stride, int histo[]) { 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 mask_g = _mm_set1_epi16(0xff00); // green 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_g = _mm_set1_epi16((short)0xff00); // green mask + const __m128i mask_gb = _mm_set1_epi32(0xffff); // green/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, -1, -1, -1, -1, -1, -1, -1); const __m128i shuffler_hi = _mm_setr_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, diff --git a/3rdparty/libwebp/src/dsp/quant.h b/3rdparty/libwebp/src/dsp/quant.h index 5ba6f9c377..5e8dba8d19 100644 --- a/3rdparty/libwebp/src/dsp/quant.h +++ b/3rdparty/libwebp/src/dsp/quant.h @@ -10,6 +10,8 @@ #ifndef WEBP_DSP_QUANT_H_ #define WEBP_DSP_QUANT_H_ +#include + #include "src/dsp/dsp.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) && // !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_ diff --git a/3rdparty/libwebp/src/dsp/rescaler.c b/3rdparty/libwebp/src/dsp/rescaler.c index 753f84fcf4..c5a01e82df 100644 --- a/3rdparty/libwebp/src/dsp/rescaler.c +++ b/3rdparty/libwebp/src/dsp/rescaler.c @@ -109,8 +109,7 @@ void WebPRescalerExportRowExpand_C(WebPRescaler* const wrk) { for (x_out = 0; x_out < x_out_max; ++x_out) { const uint32_t J = frow[x_out]; const int v = (int)MULT_FIX(J, wrk->fy_scale); - assert(v >= 0 && v <= 255); - dst[x_out] = v; + dst[x_out] = (v > 255) ? 255u : (uint8_t)v; } } else { 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]; const uint32_t J = (uint32_t)((I + ROUNDER) >> WEBP_RESCALER_RFIX); const int v = (int)MULT_FIX(J, wrk->fy_scale); - assert(v >= 0 && v <= 255); - dst[x_out] = v; + dst[x_out] = (v > 255) ? 255u : (uint8_t)v; } } } @@ -138,17 +136,15 @@ void WebPRescalerExportRowShrink_C(WebPRescaler* const wrk) { assert(!wrk->y_expand); if (yscale) { for (x_out = 0; x_out < x_out_max; ++x_out) { - const uint32_t frac = (uint32_t)MULT_FIX(frow[x_out], yscale); - const int v = (int)MULT_FIX_FLOOR(irow[x_out] - frac, wrk->fxy_scale); - assert(v >= 0 && v <= 255); - dst[x_out] = v; + const uint32_t frac = (uint32_t)MULT_FIX_FLOOR(frow[x_out], yscale); + const int v = (int)MULT_FIX(irow[x_out] - frac, wrk->fxy_scale); + dst[x_out] = (v > 255) ? 255u : (uint8_t)v; irow[x_out] = frac; // new fractional start } } else { for (x_out = 0; x_out < x_out_max; ++x_out) { const int v = (int)MULT_FIX(irow[x_out], wrk->fxy_scale); - assert(v >= 0 && v <= 255); - dst[x_out] = v; + dst[x_out] = (v > 255) ? 255u : (uint8_t)v; irow[x_out] = 0; } } diff --git a/3rdparty/libwebp/src/dsp/rescaler_mips_dsp_r2.c b/3rdparty/libwebp/src/dsp/rescaler_mips_dsp_r2.c index ce9e64862e..419b741fa5 100644 --- a/3rdparty/libwebp/src/dsp/rescaler_mips_dsp_r2.c +++ b/3rdparty/libwebp/src/dsp/rescaler_mips_dsp_r2.c @@ -107,10 +107,9 @@ static void ExportRowShrink_MIPSdspR2(WebPRescaler* const wrk) { ); } for (i = 0; i < (x_out_max & 0x3); ++i) { - const uint32_t frac = (uint32_t)MULT_FIX(*frow++, yscale); - const int v = (int)MULT_FIX_FLOOR(*irow - frac, wrk->fxy_scale); - assert(v >= 0 && v <= 255); - *dst++ = v; + const uint32_t frac = (uint32_t)MULT_FIX_FLOOR(*frow++, yscale); + const int v = (int)MULT_FIX(*irow - frac, wrk->fxy_scale); + *dst++ = (v > 255) ? 255u : (uint8_t)v; *irow++ = frac; // new fractional start } } else { @@ -157,8 +156,7 @@ static void ExportRowShrink_MIPSdspR2(WebPRescaler* const wrk) { } for (i = 0; i < (x_out_max & 0x3); ++i) { const int v = (int)MULT_FIX_FLOOR(*irow, wrk->fxy_scale); - assert(v >= 0 && v <= 255); - *dst++ = v; + *dst++ = (v > 255) ? 255u : (uint8_t)v; *irow++ = 0; } } @@ -219,8 +217,7 @@ static void ExportRowExpand_MIPSdspR2(WebPRescaler* const wrk) { for (i = 0; i < (x_out_max & 0x3); ++i) { const uint32_t J = *frow++; const int v = (int)MULT_FIX(J, wrk->fy_scale); - assert(v >= 0 && v <= 255); - *dst++ = v; + *dst++ = (v > 255) ? 255u : (uint8_t)v; } } else { 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++; const uint32_t J = (uint32_t)((I + ROUNDER) >> WEBP_RESCALER_RFIX); const int v = (int)MULT_FIX(J, wrk->fy_scale); - assert(v >= 0 && v <= 255); - *dst++ = v; + *dst++ = (v > 255) ? 255u : (uint8_t)v; } } } diff --git a/3rdparty/libwebp/src/dsp/rescaler_msa.c b/3rdparty/libwebp/src/dsp/rescaler_msa.c index c559254836..256dbdd437 100644 --- a/3rdparty/libwebp/src/dsp/rescaler_msa.c +++ b/3rdparty/libwebp/src/dsp/rescaler_msa.c @@ -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) { const uint32_t J = frow[x_out]; const int v = (int)MULT_FIX(J, wrk->fy_scale); - assert(v >= 0 && v <= 255); - dst[x_out] = v; + dst[x_out] = (v > 255) ? 255u : (uint8_t)v; } } } @@ -241,8 +240,7 @@ static WEBP_INLINE void ExportRowExpand_1(const uint32_t* frow, uint32_t* irow, + (uint64_t)B * irow[x_out]; const uint32_t J = (uint32_t)((I + ROUNDER) >> WEBP_RESCALER_RFIX); const int v = (int)MULT_FIX(J, wrk->fy_scale); - assert(v >= 0 && v <= 255); - dst[x_out] = v; + dst[x_out] = (v > 255) ? 255u : (uint8_t)v; } } } @@ -342,10 +340,9 @@ static WEBP_INLINE void ExportRowShrink_0(const uint32_t* frow, uint32_t* irow, length -= 4; } for (x_out = 0; x_out < length; ++x_out) { - const uint32_t frac = (uint32_t)MULT_FIX(frow[x_out], yscale); - const int v = (int)MULT_FIX_FLOOR(irow[x_out] - frac, wrk->fxy_scale); - assert(v >= 0 && v <= 255); - dst[x_out] = v; + const uint32_t frac = (uint32_t)MULT_FIX_FLOOR(frow[x_out], yscale); + const int v = (int)MULT_FIX(irow[x_out] - frac, wrk->fxy_scale); + dst[x_out] = (v > 255) ? 255u : (uint8_t)v; 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) { const int v = (int)MULT_FIX(irow[x_out], wrk->fxy_scale); - assert(v >= 0 && v <= 255); - dst[x_out] = v; + dst[x_out] = (v > 255) ? 255u : (uint8_t)v; irow[x_out] = 0; } } diff --git a/3rdparty/libwebp/src/dsp/rescaler_neon.c b/3rdparty/libwebp/src/dsp/rescaler_neon.c index a553f06f79..b976a852cf 100644 --- a/3rdparty/libwebp/src/dsp/rescaler_neon.c +++ b/3rdparty/libwebp/src/dsp/rescaler_neon.c @@ -81,14 +81,13 @@ static void RescalerExportRowExpand_NEON(WebPRescaler* const wrk) { const uint32x4_t B1 = MULT_FIX(A1, fy_scale_half); const uint16x4_t C0 = vmovn_u32(B0); 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); } for (; x_out < x_out_max; ++x_out) { const uint32_t J = frow[x_out]; const int v = (int)MULT_FIX_C(J, fy_scale); - assert(v >= 0 && v <= 255); - dst[x_out] = v; + dst[x_out] = (v > 255) ? 255u : (uint8_t)v; } } else { 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 uint16x4_t E0 = vmovn_u32(D0); 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); } 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]; const uint32_t J = (uint32_t)((I + ROUNDER) >> WEBP_RESCALER_RFIX); const int v = (int)MULT_FIX_C(J, fy_scale); - assert(v >= 0 && v <= 255); - dst[x_out] = v; + dst[x_out] = (v > 255) ? 255u : (uint8_t)v; } } } @@ -135,23 +133,22 @@ static void RescalerExportRowShrink_NEON(WebPRescaler* const wrk) { for (x_out = 0; x_out < max_span; x_out += 8) { LOAD_32x8(frow + x_out, in0, in1); LOAD_32x8(irow + x_out, in2, in3); - const uint32x4_t A0 = MULT_FIX(in0, yscale_half); - const uint32x4_t A1 = MULT_FIX(in1, yscale_half); + const uint32x4_t A0 = MULT_FIX_FLOOR(in0, yscale_half); + const uint32x4_t A1 = MULT_FIX_FLOOR(in1, yscale_half); const uint32x4_t B0 = vqsubq_u32(in2, A0); const uint32x4_t B1 = vqsubq_u32(in3, A1); - const uint32x4_t C0 = MULT_FIX_FLOOR(B0, fxy_scale_half); - const uint32x4_t C1 = MULT_FIX_FLOOR(B1, fxy_scale_half); + const uint32x4_t C0 = MULT_FIX(B0, fxy_scale_half); + const uint32x4_t C1 = MULT_FIX(B1, fxy_scale_half); const uint16x4_t D0 = vmovn_u32(C0); 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); STORE_32x8(A0, A1, irow + x_out); } for (; x_out < x_out_max; ++x_out) { - const uint32_t frac = (uint32_t)MULT_FIX_C(frow[x_out], yscale); - const int v = (int)MULT_FIX_FLOOR_C(irow[x_out] - frac, fxy_scale); - assert(v >= 0 && v <= 255); - dst[x_out] = v; + const uint32_t frac = (uint32_t)MULT_FIX_FLOOR_C(frow[x_out], yscale); + const int v = (int)MULT_FIX_C(irow[x_out] - frac, fxy_scale); + dst[x_out] = (v > 255) ? 255u : (uint8_t)v; irow[x_out] = frac; // new fractional start } } else { @@ -161,14 +158,13 @@ static void RescalerExportRowShrink_NEON(WebPRescaler* const wrk) { const uint32x4_t A1 = MULT_FIX(in1, fxy_scale_half); const uint16x4_t B0 = vmovn_u32(A0); 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); STORE_32x8(zero, zero, irow + x_out); } for (; x_out < x_out_max; ++x_out) { const int v = (int)MULT_FIX_C(irow[x_out], fxy_scale); - assert(v >= 0 && v <= 255); - dst[x_out] = v; + dst[x_out] = (v > 255) ? 255u : (uint8_t)v; irow[x_out] = 0; } } diff --git a/3rdparty/libwebp/src/dsp/rescaler_sse2.c b/3rdparty/libwebp/src/dsp/rescaler_sse2.c index f7461a452c..d7effea16e 100644 --- a/3rdparty/libwebp/src/dsp/rescaler_sse2.c +++ b/3rdparty/libwebp/src/dsp/rescaler_sse2.c @@ -225,35 +225,6 @@ static WEBP_INLINE void ProcessRow_SSE2(const __m128i* const A0, _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) { int x_out; 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) { const uint32_t J = frow[x_out]; const int v = (int)MULT_FIX(J, wrk->fy_scale); - assert(v >= 0 && v <= 255); - dst[x_out] = v; + dst[x_out] = (v > 255) ? 255u : (uint8_t)v; } } else { 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]; const uint32_t J = (uint32_t)((I + ROUNDER) >> WEBP_RESCALER_RFIX); const int v = (int)MULT_FIX(J, wrk->fy_scale); - assert(v >= 0 && v <= 255); - dst[x_out] = v; + dst[x_out] = (v > 255) ? 255u : (uint8_t)v; } } } @@ -328,20 +297,15 @@ static void RescalerExportRowShrink_SSE2(WebPRescaler* const wrk) { const int scale_xy = wrk->fxy_scale; 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 rounder = _mm_set_epi32(0, ROUNDER, 0, ROUNDER); for (x_out = 0; x_out + 8 <= x_out_max; x_out += 8) { __m128i A0, A1, A2, A3, B0, B1, B2, B3; LoadDispatchAndMult_SSE2(irow + x_out, NULL, &A0, &A1, &A2, &A3); LoadDispatchAndMult_SSE2(frow + x_out, &mult_y, &B0, &B1, &B2, &B3); { - const __m128i C0 = _mm_add_epi64(B0, rounder); - const __m128i C1 = _mm_add_epi64(B1, rounder); - const __m128i C2 = _mm_add_epi64(B2, rounder); - const __m128i C3 = _mm_add_epi64(B3, rounder); - 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 D0 = _mm_srli_epi64(B0, WEBP_RESCALER_RFIX); // = frac + const __m128i D1 = _mm_srli_epi64(B1, WEBP_RESCALER_RFIX); + const __m128i D2 = _mm_srli_epi64(B2, WEBP_RESCALER_RFIX); + const __m128i D3 = _mm_srli_epi64(B3, WEBP_RESCALER_RFIX); const __m128i E0 = _mm_sub_epi64(A0, D0); // irow[x] - frac const __m128i E1 = _mm_sub_epi64(A1, D1); 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); _mm_storeu_si128((__m128i*)(irow + x_out + 0), G0); _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) { - const uint32_t frac = (int)MULT_FIX(frow[x_out], yscale); - const int v = (int)MULT_FIX_FLOOR(irow[x_out] - frac, wrk->fxy_scale); - assert(v >= 0 && v <= 255); - dst[x_out] = v; + const uint32_t frac = (int)MULT_FIX_FLOOR(frow[x_out], yscale); + const int v = (int)MULT_FIX(irow[x_out] - frac, wrk->fxy_scale); + dst[x_out] = (v > 255) ? 255u : (uint8_t)v; irow[x_out] = frac; // new fractional start } } else { @@ -375,8 +338,7 @@ static void RescalerExportRowShrink_SSE2(WebPRescaler* const wrk) { } for (; x_out < x_out_max; ++x_out) { const int v = (int)MULT_FIX(irow[x_out], scale); - assert(v >= 0 && v <= 255); - dst[x_out] = v; + dst[x_out] = (v > 255) ? 255u : (uint8_t)v; irow[x_out] = 0; } } diff --git a/3rdparty/libwebp/src/enc/backward_references_enc.c b/3rdparty/libwebp/src/enc/backward_references_enc.c index 3ab7b0ac7d..d445b40fc5 100644 --- a/3rdparty/libwebp/src/enc/backward_references_enc.c +++ b/3rdparty/libwebp/src/enc/backward_references_enc.c @@ -191,13 +191,14 @@ void VP8LHashChainClear(VP8LHashChain* const p) { // ----------------------------------------------------------------------------- -#define HASH_MULTIPLIER_HI (0xc6a4a793ULL) -#define HASH_MULTIPLIER_LO (0x5bd1e996ULL) +static const uint32_t kHashMultiplierHi = 0xc6a4a793u; +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; - key = (argb[1] * HASH_MULTIPLIER_HI) & 0xffffffffu; - key += (argb[0] * HASH_MULTIPLIER_LO) & 0xffffffffu; + key = argb[1] * kHashMultiplierHi; + key += argb[0] * kHashMultiplierLo; key = key >> (32 - HASH_BITS); return key; } diff --git a/3rdparty/libwebp/src/enc/histogram_enc.c b/3rdparty/libwebp/src/enc/histogram_enc.c index 8ac6fa8e02..d89b98524a 100644 --- a/3rdparty/libwebp/src/enc/histogram_enc.c +++ b/3rdparty/libwebp/src/enc/histogram_enc.c @@ -929,9 +929,8 @@ static int HistogramCombineStochastic(VP8LHistogramSet* const image_histo, } mappings = (int*) WebPSafeMalloc(*num_used, sizeof(*mappings)); - if (mappings == NULL || !HistoQueueInit(&histo_queue, kHistoQueueSize)) { - goto End; - } + if (mappings == NULL) return 0; + if (!HistoQueueInit(&histo_queue, kHistoQueueSize)) goto End; // Fill the initial mapping. for (j = 0, iter = 0; iter < image_histo->size; ++iter) { if (histograms[iter] == NULL) continue; diff --git a/3rdparty/libwebp/src/enc/predictor_enc.c b/3rdparty/libwebp/src/enc/predictor_enc.c index 802e89693e..2e6762ea0d 100644 --- a/3rdparty/libwebp/src/enc/predictor_enc.c +++ b/3rdparty/libwebp/src/enc/predictor_enc.c @@ -202,7 +202,7 @@ static uint32_t NearLossless(uint32_t value, uint32_t predict, } if ((value >> 24) == 0 || (value >> 24) == 0xff) { // Preserve transparency of fully transparent or fully opaque pixels. - a = NearLosslessDiff(value >> 24, predict >> 24); + a = NearLosslessDiff((value >> 24) & 0xff, (predict >> 24) & 0xff); } else { 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 // subtracted from red and blue for compensation, to avoid accumulating two // 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, quantization); - b = NearLosslessComponent(NearLosslessDiff(value, green_diff), + b = NearLosslessComponent(NearLosslessDiff(value & 0xff, green_diff), predict & 0xff, 0xff - new_green, quantization); 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( @@ -666,8 +666,8 @@ static void GetBestGreenRedToBlue( break; // out of iter-loop. } } - best_tx->green_to_blue_ = green_to_blue_best; - best_tx->red_to_blue_ = red_to_blue_best; + best_tx->green_to_blue_ = green_to_blue_best & 0xff; + best_tx->red_to_blue_ = red_to_blue_best & 0xff; } #undef kGreenRedToBlueMaxIters #undef kGreenRedToBlueNumAxis diff --git a/3rdparty/libwebp/src/enc/quant_enc.c b/3rdparty/libwebp/src/enc/quant_enc.c index 03c682e3ae..01eb565c7f 100644 --- a/3rdparty/libwebp/src/enc/quant_enc.c +++ b/3rdparty/libwebp/src/enc/quant_enc.c @@ -33,7 +33,7 @@ // number of non-zero coeffs below which we consider the block very flat // (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_UV 2 // UV mode #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_best = rd; int mode; + int is_flat = IsFlatSource16(it->yuv_in_ + Y_OFF_ENC); rd->mode_i16 = -1; 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; rd_cur->H = VP8FixedCostsI16[mode]; rd_cur->R = VP8GetCostLuma16(it, rd_cur); - if (mode > 0 && - IsFlat(rd_cur->y_ac_levels[0], kNumBlocks, FLATNESS_LIMIT_I16)) { - // penalty to avoid flat area to be mispredicted by complex mode - rd_cur->R += FLATNESS_PENALTY * kNumBlocks; + if (is_flat) { + // refine the first impression (which was in pixel space) + is_flat = IsFlat(rd_cur->y_ac_levels[0], kNumBlocks, FLATNESS_LIMIT_I16); + 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. @@ -1087,7 +1092,8 @@ static int PickBestIntra4(VP8EncIterator* const it, VP8ModeScore* const rd) { : 0; 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)) { rd_tmp.R = FLATNESS_PENALTY * kNumBlocks; } else { @@ -1242,11 +1248,19 @@ static void RefineUsingDistortion(VP8EncIterator* const it, if (mode > 0 && VP8FixedCostsI16[mode] > bit_limit) { continue; } + if (score < best_score) { best_mode = mode; 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); // we'll reconstruct later, if i16 mode actually gets selected } diff --git a/3rdparty/libwebp/src/enc/vp8i_enc.h b/3rdparty/libwebp/src/enc/vp8i_enc.h index 3a1967da88..24e1944610 100644 --- a/3rdparty/libwebp/src/enc/vp8i_enc.h +++ b/3rdparty/libwebp/src/enc/vp8i_enc.h @@ -32,7 +32,7 @@ extern "C" { // version numbers #define ENC_MAJ_VERSION 1 #define ENC_MIN_VERSION 0 -#define ENC_REV_VERSION 2 +#define ENC_REV_VERSION 3 enum { MAX_LF_LEVELS = 64, // Maximum loop filter level MAX_VARIABLE_LEVEL = 67, // last (inclusive) level with variable cost diff --git a/3rdparty/libwebp/src/mux/muxi.h b/3rdparty/libwebp/src/mux/muxi.h index 3e9d8c48d8..7bc0b07e9b 100644 --- a/3rdparty/libwebp/src/mux/muxi.h +++ b/3rdparty/libwebp/src/mux/muxi.h @@ -29,7 +29,7 @@ extern "C" { #define MUX_MAJ_VERSION 1 #define MUX_MIN_VERSION 0 -#define MUX_REV_VERSION 2 +#define MUX_REV_VERSION 3 // Chunk object. typedef struct WebPChunk WebPChunk; diff --git a/3rdparty/libwebp/src/utils/bit_reader_inl_utils.h b/3rdparty/libwebp/src/utils/bit_reader_inl_utils.h index 7e607f370a..46b3880706 100644 --- a/3rdparty/libwebp/src/utils/bit_reader_inl_utils.h +++ b/3rdparty/libwebp/src/utils/bit_reader_inl_utils.h @@ -104,7 +104,8 @@ void VP8LoadNewBytes(VP8BitReader* const br) { } // 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 // 'range' *before* calling VP8LoadNewBytes(), even if this function doesn't // alter br->range_ value. @@ -129,13 +130,14 @@ static WEBP_INLINE int VP8GetBit(VP8BitReader* const br, int prob) { br->bits_ -= shift; } br->range_ = range - 1; + BT_TRACK(br); return bit; } } // simplified version of VP8GetBit() for prob=0x80 (note shift is always 1 here) 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) { VP8LoadNewBytes(br); } @@ -148,11 +150,13 @@ int VP8GetSigned(VP8BitReader* const br, int v) { br->range_ += mask; br->range_ |= 1; br->value_ -= (bit_t)((split + 1) & mask) << pos; + BT_TRACK(br); 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 // 'range' *before* calling VP8LoadNewBytes(), even if this function doesn't // alter br->range_ value. @@ -179,6 +183,7 @@ static WEBP_INLINE int VP8GetBitAlt(VP8BitReader* const br, int prob) { br->bits_ -= shift; } br->range_ = range; + BT_TRACK(br); return bit; } } diff --git a/3rdparty/libwebp/src/utils/bit_reader_utils.c b/3rdparty/libwebp/src/utils/bit_reader_utils.c index 1500354d5c..857cd60988 100644 --- a/3rdparty/libwebp/src/utils/bit_reader_utils.c +++ b/3rdparty/libwebp/src/utils/bit_reader_utils.c @@ -102,17 +102,18 @@ void VP8LoadFinalBytes(VP8BitReader* const br) { //------------------------------------------------------------------------------ // 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; while (bits-- > 0) { - v |= VP8GetBit(br, 0x80) << bits; + v |= VP8GetBit(br, 0x80, label) << bits; } return v; } -int32_t VP8GetSignedValue(VP8BitReader* const br, int bits) { - const int value = VP8GetValue(br, bits); - return VP8Get(br) ? -value : value; +int32_t VP8GetSignedValue(VP8BitReader* const br, int bits, + const char label[]) { + 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 // for atexit() +#include +#include + +#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 + +//------------------------------------------------------------------------------ diff --git a/3rdparty/libwebp/src/utils/bit_reader_utils.h b/3rdparty/libwebp/src/utils/bit_reader_utils.h index 0f8db2caf2..e64156e318 100644 --- a/3rdparty/libwebp/src/utils/bit_reader_utils.h +++ b/3rdparty/libwebp/src/utils/bit_reader_utils.h @@ -21,6 +21,27 @@ #endif #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 extern "C" { #endif @@ -92,17 +113,15 @@ void VP8BitReaderSetBuffer(VP8BitReader* const br, void VP8RemapBitReader(VP8BitReader* const br, ptrdiff_t offset); // return the next value made of 'num_bits' bits -uint32_t VP8GetValue(VP8BitReader* const br, int num_bits); -static WEBP_INLINE uint32_t VP8Get(VP8BitReader* const br) { - return VP8GetValue(br, 1); -} +uint32_t VP8GetValue(VP8BitReader* const br, int num_bits, const char label[]); // 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: -// static WEBP_INLINE int VP8GetBit(VP8BitReader* const br, int prob) -// static WEBP_INLINE int VP8GetSigned(VP8BitReader* const br, int v) +// static WEBP_INLINE int VP8GetBit(VP8BitReader* const br, int prob, ...) +// static WEBP_INLINE int VP8GetSigned(VP8BitReader* const br, int v, ...) // 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, // and also allowing platform-specific ad-hoc hacks. diff --git a/3rdparty/libwebp/src/utils/bit_writer_utils.c b/3rdparty/libwebp/src/utils/bit_writer_utils.c index 7f83b4c8a2..bef0e31ca5 100644 --- a/3rdparty/libwebp/src/utils/bit_writer_utils.c +++ b/3rdparty/libwebp/src/utils/bit_writer_utils.c @@ -70,7 +70,7 @@ static void Flush(VP8BitWriter* const bw) { const int value = (bits & 0x100) ? 0x00 : 0xff; for (; bw->run_ > 0; --bw->run_) bw->buf_[pos++] = value; } - bw->buf_[pos++] = bits; + bw->buf_[pos++] = bits & 0xff; bw->pos_ = pos; } else { bw->run_++; // delay writing of bytes 0xff, pending eventual carry. diff --git a/3rdparty/libwebp/src/utils/color_cache_utils.h b/3rdparty/libwebp/src/utils/color_cache_utils.h index 20b7be11c9..ec21d5199b 100644 --- a/3rdparty/libwebp/src/utils/color_cache_utils.h +++ b/3rdparty/libwebp/src/utils/color_cache_utils.h @@ -17,6 +17,7 @@ #include +#include "src/dsp/dsp.h" #include "src/webp/types.h" #ifdef __cplusplus @@ -30,10 +31,11 @@ typedef struct { int hash_bits_; } VP8LColorCache; -static const uint64_t kHashMul = 0x1e35a7bdull; +static const uint32_t kHashMul = 0x1e35a7bdu; -static WEBP_INLINE int VP8LHashPix(uint32_t argb, int shift) { - return (int)(((argb * kHashMul) & 0xffffffffu) >> shift); +static WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW WEBP_INLINE +int VP8LHashPix(uint32_t argb, int shift) { + return (int)((argb * kHashMul) >> shift); } static WEBP_INLINE uint32_t VP8LColorCacheLookup( diff --git a/3rdparty/libwebp/src/utils/huffman_utils.c b/3rdparty/libwebp/src/utils/huffman_utils.c index 7a69963c3e..0cba0fbb7d 100644 --- a/3rdparty/libwebp/src/utils/huffman_utils.c +++ b/3rdparty/libwebp/src/utils/huffman_utils.c @@ -91,7 +91,8 @@ static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits, assert(code_lengths_size != 0); assert(code_lengths != NULL); - assert(root_table != NULL); + assert((root_table != NULL && sorted != NULL) || + (root_table == NULL && sorted == NULL)); assert(root_bits > 0); // 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) { const int symbol_code_length = code_lengths[symbol]; 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. if (offset[MAX_ALLOWED_CODE_LENGTH] == 1) { - HuffmanCode code; - code.bits = 0; - code.value = (uint16_t)sorted[0]; - ReplicateValue(table, 1, total_size, code); + if (sorted != NULL) { + HuffmanCode code; + code.bits = 0; + code.value = (uint16_t)sorted[0]; + ReplicateValue(table, 1, total_size, code); + } return total_size; } @@ -151,6 +158,7 @@ static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits, if (num_open < 0) { return 0; } + if (root_table == NULL) continue; for (; count[len] > 0; --count[len]) { HuffmanCode code; code.bits = (uint8_t)len; @@ -169,6 +177,7 @@ static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits, if (num_open < 0) { return 0; } + if (root_table == NULL) continue; for (; count[len] > 0; --count[len]) { HuffmanCode code; 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) { int total_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. uint16_t sorted[SORTED_SIZE_CUTOFF]; total_size = BuildHuffmanTable(root_table, root_bits, diff --git a/3rdparty/libwebp/src/utils/huffman_utils.h b/3rdparty/libwebp/src/utils/huffman_utils.h index ff7ef17f3b..13b7ad1ac4 100644 --- a/3rdparty/libwebp/src/utils/huffman_utils.h +++ b/3rdparty/libwebp/src/utils/huffman_utils.h @@ -78,6 +78,8 @@ void VP8LHtreeGroupsFree(HTreeGroup* const htree_groups); // the huffman table. // Returns built table size or 0 in case of error (invalid tree or // 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, const int code_lengths[], int code_lengths_size); diff --git a/3rdparty/libwebp/src/utils/rescaler_utils.c b/3rdparty/libwebp/src/utils/rescaler_utils.c index 90e2ea76a1..4bcae24af5 100644 --- a/3rdparty/libwebp/src/utils/rescaler_utils.c +++ b/3rdparty/libwebp/src/utils/rescaler_utils.c @@ -84,14 +84,14 @@ int WebPRescalerGetScaledDimensions(int src_width, int src_height, int height = *scaled_height; // if width is unspecified, scale original proportionally to height ratio. - if (width == 0) { + if (width == 0 && src_height > 0) { 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 == 0) { + if (height == 0 && src_width > 0) { 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. if (width <= 0 || height <= 0) { diff --git a/3rdparty/libwebp/src/utils/thread_utils.c b/3rdparty/libwebp/src/utils/thread_utils.c index 2052b6b006..438296b45f 100644 --- a/3rdparty/libwebp/src/utils/thread_utils.c +++ b/3rdparty/libwebp/src/utils/thread_utils.c @@ -217,8 +217,12 @@ static THREADFN ThreadLoop(void* ptr) { done = 1; } // 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_cond_signal(&impl->condition_); } 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 if (new_status != OK) { 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_); + return; } } pthread_mutex_unlock(&impl->mutex_); diff --git a/3rdparty/libwebp/src/utils/utils.h b/3rdparty/libwebp/src/utils/utils.h index c7620f91ec..2a3ec92678 100644 --- a/3rdparty/libwebp/src/utils/utils.h +++ b/3rdparty/libwebp/src/utils/utils.h @@ -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. static WEBP_INLINE void PutLE16(uint8_t* const data, int val) { assert(val < (1 << 16)); - data[0] = (val >> 0); - data[1] = (val >> 8); + data[0] = (val >> 0) & 0xff; + data[1] = (val >> 8) & 0xff; } static WEBP_INLINE void PutLE24(uint8_t* const data, int val) { assert(val < (1 << 24)); 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) { diff --git a/3rdparty/libwebp/src/webp/encode.h b/3rdparty/libwebp/src/webp/encode.h index 549cf07730..339f8810aa 100644 --- a/3rdparty/libwebp/src/webp/encode.h +++ b/3rdparty/libwebp/src/webp/encode.h @@ -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 // lossless manner. Files are usually larger than lossy format, but will // 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, int width, int height, int stride, uint8_t** output); diff --git a/3rdparty/openvx/hal/CMakeLists.txt b/3rdparty/openvx/hal/CMakeLists.txt index f5af67a3c8..4824c45a24 100644 --- a/3rdparty/openvx/hal/CMakeLists.txt +++ b/3rdparty/openvx/hal/CMakeLists.txt @@ -5,7 +5,7 @@ target_include_directories(openvx_hal PUBLIC ${CMAKE_SOURCE_DIR}/modules/core/include ${CMAKE_SOURCE_DIR}/modules/imgproc/include ${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}) if(NOT BUILD_SHARED_LIBS) ocv_install_target(openvx_hal EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev) diff --git a/cmake/OpenCVCompilerOptimizations.cmake b/cmake/OpenCVCompilerOptimizations.cmake index 9377cfc0b9..970dd28903 100644 --- a/cmake/OpenCVCompilerOptimizations.cmake +++ b/cmake/OpenCVCompilerOptimizations.cmake @@ -288,7 +288,7 @@ if(X86 OR X86_64) ocv_update(CPU_AVX2_FLAGS_ON "/arch:AVX2") ocv_update(CPU_AVX_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 ocv_update(CPU_SSE_FLAGS_ON "/arch:SSE") ocv_update(CPU_SSE_SUPPORTED ON) diff --git a/cmake/OpenCVDetectCUDA.cmake b/cmake/OpenCVDetectCUDA.cmake index db0c25716c..509f417e47 100644 --- a/cmake/OpenCVDetectCUDA.cmake +++ b/cmake/OpenCVDetectCUDA.cmake @@ -12,7 +12,7 @@ endif() 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) 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) else() # Use OpenCV's patched "FindCUDA" module diff --git a/cmake/OpenCVDetectCXXCompiler.cmake b/cmake/OpenCVDetectCXXCompiler.cmake index 25bfe96883..6690bcc1ec 100644 --- a/cmake/OpenCVDetectCXXCompiler.cmake +++ b/cmake/OpenCVDetectCXXCompiler.cmake @@ -3,15 +3,14 @@ # - CV_CLANG - Clang-compatible compiler (CMAKE_CXX_COMPILER_ID MATCHES "Clang" - Clang or AppleClang, see CMP0025) # - CV_ICC - Intel compiler # - MSVC - Microsoft Visual Compiler (CMake variable) -# - MSVC64 - additional flag, 64-bit # - MINGW / CYGWIN / CMAKE_COMPILER_IS_MINGW / CMAKE_COMPILER_IS_CYGWIN (CMake original variables) -# - MINGW64 - 64-bit # # CPU Platforms: # - X86 / X86_64 # - ARM - ARM CPU, not defined for AArch64 # - AARCH64 - ARMv8+ (64-bit) # - PPC64 / PPC64LE - PowerPC +# - MIPS # # OS: # - WIN32 - Windows | MINGW @@ -21,9 +20,8 @@ # - APPLE - MacOSX | iOS # ---------------------------------------------------------------------------- -if(CMAKE_CL_64) - set(MSVC64 1) -endif() +ocv_declare_removed_variables(MINGW64 MSVC64) +# do not use (CMake variables): CMAKE_CL_64 if(NOT DEFINED CV_GCC AND CMAKE_CXX_COMPILER_ID MATCHES "GNU") set(CV_GCC 1) @@ -51,7 +49,7 @@ variable_watch(CMAKE_COMPILER_IS_CLANGCC access_CMAKE_COMPILER_IS_CLANGCXX) # Detect Intel ICC compiler # ---------------------------------------------------------------------------- if(UNIX) - if (__ICL) + if(__ICL) set(CV_ICC __ICL) elseif(__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) endif() -if(NOT DEFINED CMAKE_CXX_COMPILER_VERSION) - message(WARNING "Compiler version is not available: CMAKE_CXX_COMPILER_VERSION is not set") +if(NOT DEFINED CMAKE_CXX_COMPILER_VERSION + AND NOT OPENCV_SUPPRESS_MESSAGE_MISSING_COMPILER_VERSION) + message(WARNING "OpenCV: Compiler version is not available: CMAKE_CXX_COMPILER_VERSION is not set") endif() - -if(WIN32 AND CV_GCC) - execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpmachine - OUTPUT_VARIABLE OPENCV_GCC_TARGET_MACHINE - OUTPUT_STRIP_TRAILING_WHITESPACE) - if(OPENCV_GCC_TARGET_MACHINE MATCHES "amd64|x86_64|AMD64") - set(MINGW64 1) - endif() +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() message(STATUS "Detected processor: ${CMAKE_SYSTEM_PROCESSOR}") -if(MSVC64 OR MINGW64) - set(X86_64 1) -elseif(MINGW OR (MSVC AND NOT CMAKE_CROSSCOMPILING)) - set(X86 1) +if(OPENCV_SKIP_SYSTEM_PROCESSOR_DETECTION) + # custom setup: required variables are passed through cache / CMake's command-line elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|x86_64.*|AMD64.*") 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) +elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64.*|AARCH64.*|arm64.*|ARM64.*)") + set(AARCH64 1) elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm.*|ARM.*)") set(ARM 1) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64.*|AARCH64.*)") - set(AARCH64 1) elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64le") set(PPC64LE 1) elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64") set(PPC64 1) elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(mips.*|MIPS.*)") set(MIPS 1) +else() + if(NOT OPENCV_SUPPRESS_MESSAGE_UNRECOGNIZED_SYSTEM_PROCESSOR) + message(WARNING "OpenCV: unrecognized target processor configuration") + endif() endif() -# Workaround for 32-bit operating systems on x86_64/aarch64 processor -if(CMAKE_SIZEOF_VOID_P EQUAL 4 AND NOT FORCE_X86_64) +# Workaround for 32-bit operating systems on 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") - if (X86_64) + if(X86_64) unset(X86_64) set(X86 1) 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) set(ARM 1) endif() endif() + # Similar code exists in OpenCVConfig.cmake if(NOT DEFINED OpenCV_STATIC) # look for global setting @@ -130,14 +140,19 @@ endif() if(DEFINED OpenCV_ARCH AND DEFINED OpenCV_RUNTIME) # custom overridden values elseif(MSVC) - if(CMAKE_CL_64) - set(OpenCV_ARCH x64) - elseif((CMAKE_GENERATOR MATCHES "ARM") OR ("${arch_hint}" STREQUAL "ARM") OR (CMAKE_VS_EFFECTIVE_PLATFORMS MATCHES "ARM|arm")) - # see Modules/CmakeGenericSystem.cmake - set(OpenCV_ARCH ARM) + # see Modules/CMakeGenericSystem.cmake + if("${CMAKE_GENERATOR}" MATCHES "(Win64|IA64)") + set(OpenCV_ARCH "x64") + elseif("${CMAKE_GENERATOR_PLATFORM}" MATCHES "ARM64") + 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() set(OpenCV_ARCH x86) endif() + if(MSVC_VERSION EQUAL 1400) set(OpenCV_RUNTIME vc8) elseif(MSVC_VERSION EQUAL 1500) @@ -160,7 +175,7 @@ elseif(MSVC) elseif(MINGW) set(OpenCV_RUNTIME mingw) - if(MINGW64) + if(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|x86_64.*|AMD64.*") set(OpenCV_ARCH x64) else() set(OpenCV_ARCH x86) diff --git a/cmake/OpenCVFindIPP.cmake b/cmake/OpenCVFindIPP.cmake index 7fa0bb0b64..f938e21a57 100644 --- a/cmake/OpenCVFindIPP.cmake +++ b/cmake/OpenCVFindIPP.cmake @@ -40,11 +40,8 @@ if (X86 AND UNIX AND NOT APPLE AND NOT ANDROID AND BUILD_SHARED_LIBS) endif() set(IPP_X64 0) -if(CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 8) - set(IPP_X64 1) -endif() -if(CMAKE_CL_64) - set(IPP_X64 1) +if(X86_64) + set(IPP_X64 1) endif() # This function detects Intel IPP version by analyzing .h file diff --git a/cmake/OpenCVFindOpenEXR.cmake b/cmake/OpenCVFindOpenEXR.cmake index 39a0c7dbce..fb6c2fa146 100644 --- a/cmake/OpenCVFindOpenEXR.cmake +++ b/cmake/OpenCVFindOpenEXR.cmake @@ -15,7 +15,7 @@ file(TO_CMAKE_PATH "$ENV{ProgramFiles}" ProgramFiles_ENV_PATH) if(WIN32) 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) elseif(MSVC) SET(OPENEXR_LIBSEARCH_SUFFIXES Win32/Release Win32 Win32/Debug) diff --git a/cmake/OpenCVModule.cmake b/cmake/OpenCVModule.cmake index 4ad2814864..abb089d060 100644 --- a/cmake/OpenCVModule.cmake +++ b/cmake/OpenCVModule.cmake @@ -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} 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} LINK_PUBLIC ${OPENCV_MODULE_${the_module}_DEPS_EXT}) - 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_TO_LINK} + INTERFACE ${OPENCV_MODULE_${the_module}_DEPS_TO_LINK} + ) + 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) - 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() if(OPENCV_MODULE_${the_module}_COMPILE_DEFINITIONS) @@ -1149,7 +1153,7 @@ function(ocv_add_perf_tests) source_group("Src" FILES "${${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_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}) if(TARGET opencv_videoio_plugins) @@ -1239,7 +1243,7 @@ function(ocv_add_accuracy_tests) if(EXISTS "${CMAKE_CURRENT_BINARY_DIR}/test") ocv_target_include_directories(${the_target} "${CMAKE_CURRENT_BINARY_DIR}/test") 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}) if(TARGET opencv_videoio_plugins) @@ -1309,7 +1313,7 @@ function(ocv_add_samples) ocv_add_executable(${the_target} "${source}") 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 PROJECT_LABEL "(sample) ${name}" diff --git a/cmake/OpenCVUtils.cmake b/cmake/OpenCVUtils.cmake index eb714a6cb8..d465105f13 100644 --- a/cmake/OpenCVUtils.cmake +++ b/cmake/OpenCVUtils.cmake @@ -100,6 +100,30 @@ macro(ocv_update VAR) endif() 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 # in case of cross compilation these macros should be defined by the toolchain file if(NOT COMMAND find_host_package) @@ -1407,13 +1431,13 @@ endmacro() function(ocv_target_link_libraries target) set(LINK_DEPS ${ARGN}) _ocv_fix_target(target) - set(LINK_MODE "LINK_PRIVATE") + set(LINK_MODE "PRIVATE") set(LINK_PENDING "") foreach(dep ${LINK_DEPS}) if(" ${dep}" STREQUAL " ${target}") # prevent "link to itself" warning (world problem) - elseif(" ${dep}" STREQUAL " LINK_PRIVATE" OR " ${dep}" STREQUAL "LINK_PUBLIC" - OR " ${dep}" STREQUAL " PRIVATE" OR " ${dep}" STREQUAL "PUBLIC" + elseif(" ${dep}" STREQUAL " LINK_PRIVATE" OR " ${dep}" STREQUAL " LINK_PUBLIC" # deprecated + OR " ${dep}" STREQUAL " PRIVATE" OR " ${dep}" STREQUAL " PUBLIC" OR " ${dep}" STREQUAL " INTERFACE" ) if(NOT LINK_PENDING STREQUAL "") __ocv_push_target_link_libraries(${LINK_MODE} ${LINK_PENDING}) @@ -1553,7 +1577,10 @@ macro(ocv_get_all_libs _modules _extra _3rdparty) endif() if (TARGET ${dep}) 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 else() get_target_property(_output ${dep} IMPORTED_LOCATION) diff --git a/cmake/android/android_ant_projects.cmake b/cmake/android/android_ant_projects.cmake index b422da7042..0b5a9a65b9 100644 --- a/cmake/android/android_ant_projects.cmake +++ b/cmake/android/android_ant_projects.cmake @@ -194,7 +194,7 @@ macro(add_android_project target path) 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_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 OUTPUT_NAME "${JNI_LIB_NAME}" diff --git a/cmake/templates/OpenCVConfig.root-WIN32.cmake.in b/cmake/templates/OpenCVConfig.root-WIN32.cmake.in index 76027bf92e..5da438a9ee 100644 --- a/cmake/templates/OpenCVConfig.root-WIN32.cmake.in +++ b/cmake/templates/OpenCVConfig.root-WIN32.cmake.in @@ -84,17 +84,31 @@ endfunction() 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) # custom overridden values elseif(MSVC) - if(CMAKE_CL_64) - set(OpenCV_ARCH x64) - elseif((CMAKE_GENERATOR MATCHES "ARM") OR ("${arch_hint}" STREQUAL "ARM") OR (CMAKE_VS_EFFECTIVE_PLATFORMS MATCHES "ARM|arm")) - # see Modules/CmakeGenericSystem.cmake - set(OpenCV_ARCH ARM) + # see Modules/CMakeGenericSystem.cmake + if("${CMAKE_GENERATOR}" MATCHES "(Win64|IA64)") + set(OpenCV_ARCH "x64") + elseif("${CMAKE_GENERATOR_PLATFORM}" MATCHES "ARM64") + 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() set(OpenCV_ARCH x86) endif() + if(MSVC_VERSION EQUAL 1400) set(OpenCV_RUNTIME vc8) elseif(MSVC_VERSION EQUAL 1500) @@ -127,11 +141,7 @@ elseif(MSVC) elseif(MINGW) set(OpenCV_RUNTIME mingw) - execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpmachine - OUTPUT_VARIABLE OPENCV_GCC_TARGET_MACHINE - OUTPUT_STRIP_TRAILING_WHITESPACE) - if(OPENCV_GCC_TARGET_MACHINE MATCHES "amd64|x86_64|AMD64") - set(MINGW64 1) + if(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|x86_64.*|AMD64.*") set(OpenCV_ARCH x64) else() set(OpenCV_ARCH x86) diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 99bed33153..e89a89daef 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -172,9 +172,27 @@ if(DOXYGEN_FOUND) list(APPEND CMAKE_DOXYGEN_HTML_FILES "${CMAKE_CURRENT_SOURCE_DIR}/tutorial-utils.js") 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 - configure_file(DoxygenLayout.xml DoxygenLayout.xml @ONLY) - configure_file(Doxyfile.in ${doxyfile} @ONLY) + configure_file("${OPENCV_DOCS_DOXYGEN_LAYOUT}" DoxygenLayout.xml @ONLY) + configure_file("${OPENCV_DOCS_DOXYFILE_IN}" ${doxyfile} @ONLY) configure_file(root.markdown.in ${rootfile} @ONLY) # js tutorial assets diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index c8d25d0126..ce7a91dbf1 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -269,7 +269,7 @@ EXTERNAL_PAGES = YES CLASS_DIAGRAMS = YES DIA_PATH = HIDE_UNDOC_RELATIONS = NO -HAVE_DOT = NO +HAVE_DOT = @CMAKECONFIG_HAVE_DOT@ DOT_NUM_THREADS = 0 DOT_FONTNAME = Helvetica DOT_FONTSIZE = 10 @@ -286,9 +286,9 @@ CALL_GRAPH = YES CALLER_GRAPH = NO GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES -DOT_IMAGE_FORMAT = svg -INTERACTIVE_SVG = NO -DOT_PATH = +DOT_IMAGE_FORMAT = @CMAKECONFIG_DOT_IMAGE_FORMAT@ +INTERACTIVE_SVG = @CMAKECONFIG_INTERACTIVE_SVG@ +DOT_PATH = @CMAKECONFIG_DOT_PATH@ DOTFILE_DIRS = MSCFILE_DIRS = DIAFILE_DIRS = diff --git a/doc/py_tutorials/py_feature2d/py_brief/py_brief.markdown b/doc/py_tutorials/py_feature2d/py_brief/py_brief.markdown index 825183747e..4abcdc1bad 100644 --- a/doc/py_tutorials/py_feature2d/py_brief/py_brief.markdown +++ b/doc/py_tutorials/py_feature2d/py_brief/py_brief.markdown @@ -43,11 +43,19 @@ points than for SURF points. 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. +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 --------------- -Below code shows the computation of BRIEF descriptors with the help of CenSurE detector. (CenSurE -detector is called STAR detector in OpenCV) +Below code shows the computation of BRIEF descriptors with the help of CenSurE detector. note, that you need [opencv contrib](https://github.com/opencv/opencv_contrib)) to use this. @code{.py} diff --git a/doc/py_tutorials/py_gui/py_trackbar/py_trackbar.markdown b/doc/py_tutorials/py_gui/py_trackbar/py_trackbar.markdown index c55515c76d..a18ee20dfd 100644 --- a/doc/py_tutorials/py_gui/py_trackbar/py_trackbar.markdown +++ b/doc/py_tutorials/py_gui/py_trackbar/py_trackbar.markdown @@ -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 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 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, diff --git a/modules/calib3d/test/test_undistort_badarg.cpp b/modules/calib3d/test/test_undistort_badarg.cpp index c5ed5b1e2b..0ba13f1212 100644 --- a/modules/calib3d/test/test_undistort_badarg.cpp +++ b/modules/calib3d/test/test_undistort_badarg.cpp @@ -114,7 +114,7 @@ void CV_UndistortPointsBadArgTest::run(int) src_points = cv::cvarrToMat(&_src_points_orig); 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); //------------ diff --git a/modules/core/CMakeLists.txt b/modules/core/CMakeLists.txt index 37756cccad..e4a63d9c2b 100644 --- a/modules/core/CMakeLists.txt +++ b/modules/core/CMakeLists.txt @@ -83,7 +83,7 @@ endif() 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}" "${LAPACK_LIBRARIES}" "${CPUFEATURES_LIBRARIES}" "${HALIDE_LIBRARIES}" "${ITT_LIBRARIES}" diff --git a/modules/core/src/matrix_expressions.cpp b/modules/core/src/matrix_expressions.cpp index 243d6b0397..ea431336f0 100644 --- a/modules/core/src/matrix_expressions.cpp +++ b/modules/core/src/matrix_expressions.cpp @@ -14,6 +14,25 @@ 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 { public: @@ -659,6 +678,7 @@ MatExpr MatExpr::mul(const Mat& m, double scale) const MatExpr operator + (const Mat& a, const Mat& b) { + checkOperandsExist(a, b); MatExpr e; MatOp_AddEx::makeExpr(e, a, b, 1, 1); return e; @@ -666,6 +686,7 @@ MatExpr operator + (const Mat& a, const Mat& b) MatExpr operator + (const Mat& a, const Scalar& s) { + checkOperandsExist(a); MatExpr e; MatOp_AddEx::makeExpr(e, a, Mat(), 1, 0, s); return e; @@ -673,6 +694,7 @@ MatExpr operator + (const Mat& a, const Scalar& s) MatExpr operator + (const Scalar& s, const Mat& a) { + checkOperandsExist(a); MatExpr e; MatOp_AddEx::makeExpr(e, a, Mat(), 1, 0, s); return e; @@ -687,6 +709,7 @@ MatExpr operator + (const MatExpr& e, const Mat& m) MatExpr operator + (const Mat& m, const MatExpr& e) { + checkOperandsExist(m); MatExpr en; e.op->add(e, MatExpr(m), en); return en; @@ -715,6 +738,7 @@ MatExpr operator + (const MatExpr& e1, const MatExpr& e2) MatExpr operator - (const Mat& a, const Mat& b) { + checkOperandsExist(a, b); MatExpr e; MatOp_AddEx::makeExpr(e, a, b, 1, -1); return e; @@ -722,6 +746,7 @@ MatExpr operator - (const Mat& a, const Mat& b) MatExpr operator - (const Mat& a, const Scalar& s) { + checkOperandsExist(a); MatExpr e; MatOp_AddEx::makeExpr(e, a, Mat(), 1, 0, -s); return e; @@ -729,6 +754,7 @@ MatExpr operator - (const Mat& a, const Scalar& s) MatExpr operator - (const Scalar& s, const Mat& a) { + checkOperandsExist(a); MatExpr e; MatOp_AddEx::makeExpr(e, a, Mat(), -1, 0, s); return e; @@ -736,6 +762,7 @@ MatExpr operator - (const Scalar& s, const Mat& a) MatExpr operator - (const MatExpr& e, const Mat& m) { + checkOperandsExist(m); MatExpr en; e.op->subtract(e, MatExpr(m), en); return en; @@ -743,6 +770,7 @@ MatExpr operator - (const MatExpr& e, const Mat& m) MatExpr operator - (const Mat& m, const MatExpr& e) { + checkOperandsExist(m); MatExpr en; e.op->subtract(MatExpr(m), e, en); return en; @@ -771,6 +799,7 @@ MatExpr operator - (const MatExpr& e1, const MatExpr& e2) MatExpr operator - (const Mat& m) { + checkOperandsExist(m); MatExpr e; MatOp_AddEx::makeExpr(e, m, Mat(), -1, 0); return e; @@ -785,6 +814,7 @@ MatExpr operator - (const MatExpr& e) MatExpr operator * (const Mat& a, const Mat& b) { + checkOperandsExist(a, b); MatExpr e; MatOp_GEMM::makeExpr(e, 0, a, b); return e; @@ -792,6 +822,7 @@ MatExpr operator * (const Mat& a, const Mat& b) MatExpr operator * (const Mat& a, double s) { + checkOperandsExist(a); MatExpr e; MatOp_AddEx::makeExpr(e, a, Mat(), s, 0); return e; @@ -799,6 +830,7 @@ MatExpr operator * (const Mat& a, double s) MatExpr operator * (double s, const Mat& a) { + checkOperandsExist(a); MatExpr e; MatOp_AddEx::makeExpr(e, a, Mat(), s, 0); return e; @@ -813,6 +845,7 @@ MatExpr operator * (const MatExpr& e, const Mat& m) MatExpr operator * (const Mat& m, const MatExpr& e) { + checkOperandsExist(m); MatExpr en; e.op->matmul(MatExpr(m), e, en); return en; @@ -841,6 +874,7 @@ MatExpr operator * (const MatExpr& e1, const MatExpr& e2) MatExpr operator / (const Mat& a, const Mat& b) { + checkOperandsExist(a, b); MatExpr e; MatOp_Bin::makeExpr(e, '/', a, b); return e; @@ -848,6 +882,7 @@ MatExpr operator / (const Mat& a, const Mat& b) MatExpr operator / (const Mat& a, double s) { + checkOperandsExist(a); MatExpr e; MatOp_AddEx::makeExpr(e, a, Mat(), 1./s, 0); return e; @@ -855,6 +890,7 @@ MatExpr operator / (const Mat& a, double s) MatExpr operator / (double s, const Mat& a) { + checkOperandsExist(a); MatExpr e; MatOp_Bin::makeExpr(e, '/', a, Mat(), s); return e; @@ -869,6 +905,7 @@ MatExpr operator / (const MatExpr& e, const Mat& m) MatExpr operator / (const Mat& m, const MatExpr& e) { + checkOperandsExist(m); MatExpr en; e.op->divide(MatExpr(m), e, en); return en; @@ -897,6 +934,7 @@ MatExpr operator / (const MatExpr& e1, const MatExpr& e2) MatExpr operator < (const Mat& a, const Mat& b) { + checkOperandsExist(a, b); MatExpr e; MatOp_Cmp::makeExpr(e, CV_CMP_LT, a, b); return e; @@ -904,6 +942,7 @@ MatExpr operator < (const Mat& a, const Mat& b) MatExpr operator < (const Mat& a, double s) { + checkOperandsExist(a); MatExpr e; MatOp_Cmp::makeExpr(e, CV_CMP_LT, a, s); return e; @@ -911,6 +950,7 @@ MatExpr operator < (const Mat& a, double s) MatExpr operator < (double s, const Mat& a) { + checkOperandsExist(a); MatExpr e; MatOp_Cmp::makeExpr(e, CV_CMP_GT, a, s); return e; @@ -918,6 +958,7 @@ MatExpr operator < (double s, const Mat& a) MatExpr operator <= (const Mat& a, const Mat& b) { + checkOperandsExist(a, b); MatExpr e; MatOp_Cmp::makeExpr(e, CV_CMP_LE, a, b); return e; @@ -925,6 +966,7 @@ MatExpr operator <= (const Mat& a, const Mat& b) MatExpr operator <= (const Mat& a, double s) { + checkOperandsExist(a); MatExpr e; MatOp_Cmp::makeExpr(e, CV_CMP_LE, a, s); return e; @@ -932,6 +974,7 @@ MatExpr operator <= (const Mat& a, double s) MatExpr operator <= (double s, const Mat& a) { + checkOperandsExist(a); MatExpr e; MatOp_Cmp::makeExpr(e, CV_CMP_GE, a, s); return e; @@ -939,6 +982,7 @@ MatExpr operator <= (double s, const Mat& a) MatExpr operator == (const Mat& a, const Mat& b) { + checkOperandsExist(a, b); MatExpr e; MatOp_Cmp::makeExpr(e, CV_CMP_EQ, a, b); return e; @@ -946,6 +990,7 @@ MatExpr operator == (const Mat& a, const Mat& b) MatExpr operator == (const Mat& a, double s) { + checkOperandsExist(a); MatExpr e; MatOp_Cmp::makeExpr(e, CV_CMP_EQ, a, s); return e; @@ -953,6 +998,7 @@ MatExpr operator == (const Mat& a, double s) MatExpr operator == (double s, const Mat& a) { + checkOperandsExist(a); MatExpr e; MatOp_Cmp::makeExpr(e, CV_CMP_EQ, a, s); return e; @@ -960,6 +1006,7 @@ MatExpr operator == (double s, const Mat& a) MatExpr operator != (const Mat& a, const Mat& b) { + checkOperandsExist(a, b); MatExpr e; MatOp_Cmp::makeExpr(e, CV_CMP_NE, a, b); return e; @@ -967,6 +1014,7 @@ MatExpr operator != (const Mat& a, const Mat& b) MatExpr operator != (const Mat& a, double s) { + checkOperandsExist(a); MatExpr e; MatOp_Cmp::makeExpr(e, CV_CMP_NE, a, s); return e; @@ -974,6 +1022,7 @@ MatExpr operator != (const Mat& a, double s) MatExpr operator != (double s, const Mat& a) { + checkOperandsExist(a); MatExpr e; MatOp_Cmp::makeExpr(e, CV_CMP_NE, a, s); return e; @@ -981,6 +1030,7 @@ MatExpr operator != (double s, const Mat& a) MatExpr operator >= (const Mat& a, const Mat& b) { + checkOperandsExist(a, b); MatExpr e; MatOp_Cmp::makeExpr(e, CV_CMP_GE, a, b); return e; @@ -988,6 +1038,7 @@ MatExpr operator >= (const Mat& a, const Mat& b) MatExpr operator >= (const Mat& a, double s) { + checkOperandsExist(a); MatExpr e; MatOp_Cmp::makeExpr(e, CV_CMP_GE, a, s); return e; @@ -995,6 +1046,7 @@ MatExpr operator >= (const Mat& a, double s) MatExpr operator >= (double s, const Mat& a) { + checkOperandsExist(a); MatExpr e; MatOp_Cmp::makeExpr(e, CV_CMP_LE, a, s); return e; @@ -1002,6 +1054,7 @@ MatExpr operator >= (double s, const Mat& a) MatExpr operator > (const Mat& a, const Mat& b) { + checkOperandsExist(a, b); MatExpr e; MatOp_Cmp::makeExpr(e, CV_CMP_GT, a, b); return e; @@ -1009,6 +1062,7 @@ MatExpr operator > (const Mat& a, const Mat& b) MatExpr operator > (const Mat& a, double s) { + checkOperandsExist(a); MatExpr e; MatOp_Cmp::makeExpr(e, CV_CMP_GT, a, s); return e; @@ -1016,6 +1070,7 @@ MatExpr operator > (const Mat& a, double s) MatExpr operator > (double s, const Mat& a) { + checkOperandsExist(a); MatExpr e; MatOp_Cmp::makeExpr(e, CV_CMP_LT, a, s); return e; @@ -1025,6 +1080,7 @@ MatExpr min(const Mat& a, const Mat& b) { CV_INSTRUMENT_REGION(); + checkOperandsExist(a, b); MatExpr e; MatOp_Bin::makeExpr(e, 'm', a, b); return e; @@ -1034,6 +1090,7 @@ MatExpr min(const Mat& a, double s) { CV_INSTRUMENT_REGION(); + checkOperandsExist(a); MatExpr e; MatOp_Bin::makeExpr(e, 'n', a, s); return e; @@ -1043,6 +1100,7 @@ MatExpr min(double s, const Mat& a) { CV_INSTRUMENT_REGION(); + checkOperandsExist(a); MatExpr e; MatOp_Bin::makeExpr(e, 'n', a, s); return e; @@ -1052,6 +1110,7 @@ MatExpr max(const Mat& a, const Mat& b) { CV_INSTRUMENT_REGION(); + checkOperandsExist(a, b); MatExpr e; MatOp_Bin::makeExpr(e, 'M', a, b); return e; @@ -1061,6 +1120,7 @@ MatExpr max(const Mat& a, double s) { CV_INSTRUMENT_REGION(); + checkOperandsExist(a); MatExpr e; MatOp_Bin::makeExpr(e, 'N', a, s); return e; @@ -1070,6 +1130,7 @@ MatExpr max(double s, const Mat& a) { CV_INSTRUMENT_REGION(); + checkOperandsExist(a); MatExpr e; MatOp_Bin::makeExpr(e, 'N', a, s); return e; @@ -1077,6 +1138,7 @@ MatExpr max(double s, const Mat& a) MatExpr operator & (const Mat& a, const Mat& b) { + checkOperandsExist(a, b); MatExpr e; MatOp_Bin::makeExpr(e, '&', a, b); return e; @@ -1084,6 +1146,7 @@ MatExpr operator & (const Mat& a, const Mat& b) MatExpr operator & (const Mat& a, const Scalar& s) { + checkOperandsExist(a); MatExpr e; MatOp_Bin::makeExpr(e, '&', a, s); return e; @@ -1091,6 +1154,7 @@ MatExpr operator & (const Mat& a, const Scalar& s) MatExpr operator & (const Scalar& s, const Mat& a) { + checkOperandsExist(a); MatExpr e; MatOp_Bin::makeExpr(e, '&', a, s); return e; @@ -1098,6 +1162,7 @@ MatExpr operator & (const Scalar& s, const Mat& a) MatExpr operator | (const Mat& a, const Mat& b) { + checkOperandsExist(a, b); MatExpr e; MatOp_Bin::makeExpr(e, '|', a, b); return e; @@ -1105,6 +1170,7 @@ MatExpr operator | (const Mat& a, const Mat& b) MatExpr operator | (const Mat& a, const Scalar& s) { + checkOperandsExist(a); MatExpr e; MatOp_Bin::makeExpr(e, '|', a, s); return e; @@ -1112,6 +1178,7 @@ MatExpr operator | (const Mat& a, const Scalar& s) MatExpr operator | (const Scalar& s, const Mat& a) { + checkOperandsExist(a); MatExpr e; MatOp_Bin::makeExpr(e, '|', a, s); return e; @@ -1119,6 +1186,7 @@ MatExpr operator | (const Scalar& s, const Mat& a) MatExpr operator ^ (const Mat& a, const Mat& b) { + checkOperandsExist(a, b); MatExpr e; MatOp_Bin::makeExpr(e, '^', a, b); return e; @@ -1126,6 +1194,7 @@ MatExpr operator ^ (const Mat& a, const Mat& b) MatExpr operator ^ (const Mat& a, const Scalar& s) { + checkOperandsExist(a); MatExpr e; MatOp_Bin::makeExpr(e, '^', a, s); return e; @@ -1133,6 +1202,7 @@ MatExpr operator ^ (const Mat& a, const Scalar& s) MatExpr operator ^ (const Scalar& s, const Mat& a) { + checkOperandsExist(a); MatExpr e; MatOp_Bin::makeExpr(e, '^', a, s); return e; @@ -1140,6 +1210,7 @@ MatExpr operator ^ (const Scalar& s, const Mat& a) MatExpr operator ~(const Mat& a) { + checkOperandsExist(a); MatExpr e; MatOp_Bin::makeExpr(e, '~', a, Scalar()); return e; @@ -1149,6 +1220,7 @@ MatExpr abs(const Mat& a) { CV_INSTRUMENT_REGION(); + checkOperandsExist(a); MatExpr e; MatOp_Bin::makeExpr(e, 'a', a, Scalar()); return e; @@ -1630,6 +1702,7 @@ MatExpr Mat::t() const { CV_INSTRUMENT_REGION(); + checkOperandsExist(*this); MatExpr e; MatOp_T::makeExpr(e, *this); return e; diff --git a/modules/core/test/test_operations.cpp b/modules/core/test/test_operations.cpp index aea6f229ac..dd91617537 100644 --- a/modules/core/test/test_operations.cpp +++ b/modules/core/test/test_operations.cpp @@ -1467,4 +1467,19 @@ TEST(Core_sortIdx, regression_8941) "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 diff --git a/modules/dnn/src/layers/eltwise_layer.cpp b/modules/dnn/src/layers/eltwise_layer.cpp index 6925863773..81a947cd2f 100644 --- a/modules/dnn/src/layers/eltwise_layer.cpp +++ b/modules/dnn/src/layers/eltwise_layer.cpp @@ -668,6 +668,12 @@ public: for (int i = 2; i < inputBuffers.size(); ++i) topExpr *= inputBuffers[i](x, y, c, n); 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: topExpr = max(inputBuffers[0](x, y, c, n), inputBuffers[1](x, y, c, n)); diff --git a/modules/dnn/test/test_halide_layers.cpp b/modules/dnn/test/test_halide_layers.cpp index 757a98c612..11668b4b79 100644 --- a/modules/dnn/test/test_halide_layers.cpp +++ b/modules/dnn/test/test_halide_layers.cpp @@ -16,10 +16,11 @@ using namespace cv; using namespace cv::dnn; 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); - randu(input, -1.0f, 1.0f); + if (randInput) + randu(input, -1.0f, 1.0f); net.setInput(input); 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); #endif + bool convInputShift = 1; + int numEltwiseInputs = numConv; + if (op == "div") + { + numConv = 1; + convInputShift = 0; // first input is convolution + } + Net net; std::vector convLayerIds(numConv); @@ -815,20 +824,29 @@ TEST_P(Eltwise, Accuracy) eltwiseParam.type = "Eltwise"; eltwiseParam.name = "testLayer"; 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) { - 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]}; 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( /*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), /*weighted(for sum only)*/ Bool(), dnnBackendsAndTargetsWithHalide() diff --git a/modules/imgcodecs/src/grfmt_bmp.cpp b/modules/imgcodecs/src/grfmt_bmp.cpp index 5ca015a9b2..880a8cd105 100644 --- a/modules/imgcodecs/src/grfmt_bmp.cpp +++ b/modules/imgcodecs/src/grfmt_bmp.cpp @@ -102,7 +102,9 @@ bool BmpDecoder::readHeader() m_width = m_strm.getDWord(); m_height = m_strm.getDWord(); 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); int clrused = m_strm.getDWord(); m_strm.skip( size - 36 ); diff --git a/modules/java/jni/CMakeLists.txt b/modules/java/jni/CMakeLists.txt index c0cfbb3e1a..614e0ae0cc 100644 --- a/modules/java/jni/CMakeLists.txt +++ b/modules/java/jni/CMakeLists.txt @@ -50,16 +50,16 @@ if(BUILD_FAT_JAVA_LIB) endif() if(APPLE) 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() 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() - ocv_target_link_libraries(${the_module} LINK_PRIVATE ${__deps}) + ocv_target_link_libraries(${the_module} PRIVATE ${__deps}) 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() - ocv_target_link_libraries(${the_module} LINK_PRIVATE ${__deps} ${OPENCV_LINKER_LIBS}) + ocv_target_link_libraries(${the_module} PRIVATE ${__deps} ${OPENCV_LINKER_LIBS}) endif() # Additional target properties @@ -72,8 +72,12 @@ set_target_properties(${the_module} PROPERTIES ) if(ANDROID) - ocv_target_link_libraries(${the_module} LINK_PUBLIC jnigraphics) # for Mat <=> Bitmap converters - ocv_target_link_libraries(${the_module} LINK_PUBLIC log dl z) + ocv_target_link_libraries(${the_module} PUBLIC jnigraphics # for Mat <=> Bitmap converters + INTERFACE jnigraphics + ) + ocv_target_link_libraries(${the_module} PUBLIC log dl z + INTERFACE log dl z + ) # force strip library after the build command # because samples and tests will make a copy of the library before install diff --git a/modules/python/common.cmake b/modules/python/common.cmake index 6a9d32d99a..b69d13d5ae 100644 --- a/modules/python/common.cmake +++ b/modules/python/common.cmake @@ -44,9 +44,9 @@ if(APPLE) set_target_properties(${the_module} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup") elseif(WIN32 OR OPENCV_FORCE_PYTHON_LIBS) 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() - ocv_target_link_libraries(${the_module} LINK_PRIVATE ${${PYTHON}_LIBRARIES}) + ocv_target_link_libraries(${the_module} PRIVATE ${${PYTHON}_LIBRARIES}) endif() endif() @@ -54,7 +54,7 @@ if(TARGET gen_opencv_python_source) 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 endif() -ocv_target_link_libraries(${the_module} LINK_PRIVATE ${deps}) +ocv_target_link_libraries(${the_module} PRIVATE ${deps}) if(DEFINED ${PYTHON}_CVPY_SUFFIX) set(CVPY_SUFFIX "${${PYTHON}_CVPY_SUFFIX}") diff --git a/modules/videoio/CMakeLists.txt b/modules/videoio/CMakeLists.txt index 16086555d4..7c72786521 100644 --- a/modules/videoio/CMakeLists.txt +++ b/modules/videoio/CMakeLists.txt @@ -203,8 +203,8 @@ ocv_target_link_libraries(${the_module} LINK_PRIVATE ${tgts}) # copy FFmpeg dll to the output folder if(WIN32 AND HAVE_FFMPEG_WRAPPER) - if(MSVC64 OR MINGW64) - set(FFMPEG_SUFFIX "_64") + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(FFMPEG_SUFFIX _64) endif() set(ffmpeg_dir "${OpenCV_BINARY_DIR}/3rdparty/ffmpeg") set(ffmpeg_bare_name "opencv_videoio_ffmpeg${FFMPEG_SUFFIX}.dll") diff --git a/samples/CMakeLists.example.in b/samples/CMakeLists.example.in index cb741b76e1..9a00ac2991 100644 --- a/samples/CMakeLists.example.in +++ b/samples/CMakeLists.example.in @@ -39,4 +39,4 @@ message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}") add_executable(${EXAMPLE_NAME} "${EXAMPLE_FILE}") # Link your application with OpenCV libraries -target_link_libraries(${EXAMPLE_NAME} LINK_PRIVATE ${OpenCV_LIBS}) +target_link_libraries(${EXAMPLE_NAME} PRIVATE ${OpenCV_LIBS}) diff --git a/samples/cpp/CMakeLists.txt b/samples/cpp/CMakeLists.txt index 4e009461b8..33cf490a2a 100644 --- a/samples/cpp/CMakeLists.txt +++ b/samples/cpp/CMakeLists.txt @@ -35,12 +35,12 @@ foreach(sample_filename ${cpp_samples}) set(package "tutorial") endif() 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) - ocv_target_link_libraries(${tgt} LINK_PRIVATE opencv_cudaarithm opencv_cudafilters) + ocv_target_link_libraries(${tgt} PRIVATE opencv_cudaarithm opencv_cudafilters) endif() 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) endif() if(HAVE_OPENGL AND sample_filename MATCHES "detect_mser") diff --git a/samples/cpp/example_cmake/CMakeLists.txt b/samples/cpp/example_cmake/CMakeLists.txt index d9fe9ccc6b..d3d86eed9d 100644 --- a/samples/cpp/example_cmake/CMakeLists.txt +++ b/samples/cpp/example_cmake/CMakeLists.txt @@ -27,4 +27,4 @@ message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}") add_executable(opencv_example example.cpp) # Link your application with OpenCV libraries -target_link_libraries(opencv_example LINK_PRIVATE ${OpenCV_LIBS}) +target_link_libraries(opencv_example PRIVATE ${OpenCV_LIBS}) diff --git a/samples/cpp/tutorial_code/calib3d/real_time_pose_estimation/CMakeLists.txt b/samples/cpp/tutorial_code/calib3d/real_time_pose_estimation/CMakeLists.txt index 2f63f048a0..5b5520f287 100644 --- a/samples/cpp/tutorial_code/calib3d/real_time_pose_estimation/CMakeLists.txt +++ b/samples/cpp/tutorial_code/calib3d/real_time_pose_estimation/CMakeLists.txt @@ -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_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_detection 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 PRIVATE ${OPENCV_LINKER_LIBS} ${OPENCV_CPP_SAMPLES_REQUIRED_DEPS}) diff --git a/samples/directx/CMakeLists.txt b/samples/directx/CMakeLists.txt index 961ed68a67..c1d4c5d0d1 100644 --- a/samples/directx/CMakeLists.txt +++ b/samples/directx/CMakeLists.txt @@ -17,5 +17,5 @@ ocv_include_modules_recurse(${tgt} ${OPENCV_DIRECTX_SAMPLES_REQUIRED_DEPS}) file(GLOB all_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp) foreach(sample_filename ${all_samples}) 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() diff --git a/samples/dnn/CMakeLists.txt b/samples/dnn/CMakeLists.txt index d1ec67f4ff..f2cb949d0a 100644 --- a/samples/dnn/CMakeLists.txt +++ b/samples/dnn/CMakeLists.txt @@ -18,5 +18,5 @@ ocv_include_modules_recurse(${OPENCV_DNN_SAMPLES_REQUIRED_DEPS}) file(GLOB_RECURSE dnn_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp) foreach(sample_filename ${dnn_samples}) 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() diff --git a/samples/gpu/CMakeLists.txt b/samples/gpu/CMakeLists.txt index d6f7d43320..eeab50a993 100644 --- a/samples/gpu/CMakeLists.txt +++ b/samples/gpu/CMakeLists.txt @@ -51,11 +51,11 @@ endif() file(GLOB all_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp) foreach(sample_filename ${all_samples}) 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) - ocv_target_link_libraries(${tgt} LINK_PRIVATE opencv_xfeatures2d) + ocv_target_link_libraries(${tgt} PRIVATE opencv_xfeatures2d) endif() if(HAVE_opencv_cudacodec) - ocv_target_link_libraries(${tgt} LINK_PRIVATE opencv_cudacodec) + ocv_target_link_libraries(${tgt} PRIVATE opencv_cudacodec) endif() endforeach() diff --git a/samples/opencl/CMakeLists.txt b/samples/opencl/CMakeLists.txt index bb857ef448..d71e866ffa 100644 --- a/samples/opencl/CMakeLists.txt +++ b/samples/opencl/CMakeLists.txt @@ -31,7 +31,7 @@ ocv_include_directories(${OpenCL_INCLUDE_DIR}) file(GLOB all_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp) foreach(sample_filename ${all_samples}) ocv_define_sample(tgt ${sample_filename} opencl) - ocv_target_link_libraries(${tgt} LINK_PRIVATE + ocv_target_link_libraries(${tgt} PRIVATE ${OPENCV_LINKER_LIBS} ${OPENCV_OPENCL_SAMPLES_REQUIRED_DEPS} ${OpenCL_LIBRARY}) diff --git a/samples/opengl/CMakeLists.txt b/samples/opengl/CMakeLists.txt index adf48a8d16..1e5d68dfe5 100644 --- a/samples/opengl/CMakeLists.txt +++ b/samples/opengl/CMakeLists.txt @@ -23,9 +23,9 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND) endif() foreach(sample_filename ${all_samples}) 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") - 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}) endif() endforeach() diff --git a/samples/openvx/CMakeLists.txt b/samples/openvx/CMakeLists.txt index ad65f050c9..701184d369 100644 --- a/samples/openvx/CMakeLists.txt +++ b/samples/openvx/CMakeLists.txt @@ -21,5 +21,5 @@ add_definitions(-DIVX_HIDE_INFO_WARNINGS) file(GLOB_RECURSE cpp_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp) foreach(sample_filename ${cpp_samples}) 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() diff --git a/samples/samples_utils.cmake b/samples/samples_utils.cmake index b39996aea1..845b4585ea 100644 --- a/samples/samples_utils.cmake +++ b/samples/samples_utils.cmake @@ -6,7 +6,7 @@ function(ocv_define_sample out_target source sub) set(the_target "example_${sub}_${name}") add_executable(${the_target} "${source}") 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() set_target_properties(${the_target} PROPERTIES PROJECT_LABEL "(sample) ${name}") if(ENABLE_SOLUTION_FOLDERS) diff --git a/samples/tapi/CMakeLists.txt b/samples/tapi/CMakeLists.txt index c44e92dc73..1f00326137 100644 --- a/samples/tapi/CMakeLists.txt +++ b/samples/tapi/CMakeLists.txt @@ -22,5 +22,5 @@ ocv_include_modules_recurse(${OPENCV_TAPI_SAMPLES_REQUIRED_DEPS}) file(GLOB all_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp) foreach(sample_filename ${all_samples}) 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() diff --git a/samples/va_intel/CMakeLists.txt b/samples/va_intel/CMakeLists.txt index 2974d41c8f..0e56951302 100644 --- a/samples/va_intel/CMakeLists.txt +++ b/samples/va_intel/CMakeLists.txt @@ -17,5 +17,5 @@ ocv_include_modules_recurse(${OPENCV_VA_INTEL_SAMPLES_REQUIRED_DEPS}) file(GLOB all_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp) foreach(sample_filename ${all_samples}) 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()