From b5a6df4966b8a7cba3b14f4c18f89a53a3fab1d8 Mon Sep 17 00:00:00 2001 From: Dinar Ahmatnurov Date: Tue, 14 Oct 2014 17:11:18 +0400 Subject: [PATCH] fixed issue with malformed UTF-8 string; ocl: Change static variable order in cl_context.cpp to avoid crashes during destruction ContextImpl::currentContext contains a reference to one of the DeviceInfoImpl objects from: static std::vector global_devices; ContextImpl::currentContext is destroyed in the destructor for the statically defined object __module, and relies on its DeviceInfoImpl reference to query some hardware features while being destroyed. This means that we need to ensure that the global_devices vector is destroyed affter __module, otherwise ContextImpl::currentContext's DeviceInfoImpl reference will no longer be valid when __module is destroyed. Since these variables are all confined to a single compilation unit, they will be destruct from bottom to top, so we need to make sure that __module is the bottom definition so it can be destroyed first. iOS: fix crash from overrelease in UIImageToMat viz: fixed memory leak, issue 3961 fix installation layout for debian packages: Install symlinks to shared libraries as a part of development package, not runtime package. It is default behavior for debian packages. Fix test name. TIFF loader: Allocate large enough buffer when (bpp * ncn) > 8. TIFF loader: Pass buffer size to read functions. replace not ascii and not cyrillic symbols with '?'; add test for putText; fix warning; minor fixes; --- modules/core/src/drawing.cpp | 36 ++++++------- modules/highgui/test/test_drawing.cpp | 78 +++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 19 deletions(-) diff --git a/modules/core/src/drawing.cpp b/modules/core/src/drawing.cpp index eaedca5b8..66778797d 100644 --- a/modules/core/src/drawing.cpp +++ b/modules/core/src/drawing.cpp @@ -2028,38 +2028,36 @@ inline void readCheck(int &c, int &i, const string &text, int fontFace) if(c >= 0x80 && fontFace == FONT_HERSHEY_COMPLEX) { - if(c >= 0xC0 && c <= 0xDF) //2 bytes utf + if(c == 0xD0 && (uchar)text[i + 1] >= 0x90 && (uchar)text[i + 1] <= 0xBF) { - if(c & 1) - { - c = (uchar)text[++i] + 47; - leftBoundary = 175; - rightBoundary = 191; - } - else - { - c = (uchar)text[++i] - 17; - leftBoundary = 127; - rightBoundary = 175; - } + c = (uchar)text[++i] - 17; + leftBoundary = 127; + rightBoundary = 175; + } + else if(c == 0xD1 && (uchar)text[i + 1] >= 0x80 && (uchar)text[i + 1] <= 0x8F) + { + c = (uchar)text[++i] + 47; + leftBoundary = 175; + rightBoundary = 191; } else { - if(c >= 0xE0) //3 bytes utf + if(c >= 0xC0 && text[i+1] != 0) //2 bytes utf i++; - if(c >= 0xF0) //4 bytes utf + if(c >= 0xE0 && text[i+1] != 0) //3 bytes utf i++; - if(c >= 0xF8) //5 bytes utf + if(c >= 0xF0 && text[i+1] != 0) //4 bytes utf i++; - if(c >= 0xFC) //6 bytes utf + if(c >= 0xF8 && text[i+1] != 0) //5 bytes utf + i++; + + if(c >= 0xFC && text[i+1] != 0) //6 bytes utf i++; - i++; c = '?'; - } } diff --git a/modules/highgui/test/test_drawing.cpp b/modules/highgui/test/test_drawing.cpp index 6abdeac68..46bffbebe 100644 --- a/modules/highgui/test/test_drawing.cpp +++ b/modules/highgui/test/test_drawing.cpp @@ -447,3 +447,81 @@ protected: }; TEST(Highgui_Drawing, fillconvexpoly_clipping) { CV_FillConvexPolyTest test; test.safe_run(); } + +class CV_DrawingTest_UTF8 : public cvtest::BaseTest +{ +public: + CV_DrawingTest_UTF8() {} + ~CV_DrawingTest_UTF8() {} +protected: + void run(int) + { + vector lines; + lines.push_back("abcdefghijklmnopqrstuvwxyz1234567890"); + // cyrillic letters small + lines.push_back("\xD0\xB0\xD0\xB1\xD0\xB2\xD0\xB3\xD0\xB4\xD0\xB5\xD1\x91\xD0\xB6\xD0\xB7" + "\xD0\xB8\xD0\xB9\xD0\xBA\xD0\xBB\xD0\xBC\xD0\xBD\xD0\xBE\xD0\xBF\xD1\x80" + "\xD1\x81\xD1\x82\xD1\x83\xD1\x84\xD1\x85\xD1\x86\xD1\x87\xD1\x88\xD1\x89" + "\xD1\x8A\xD1\x8B\xD1\x8C\xD1\x8D\xD1\x8E\xD1\x8F"); + // cyrillic letters capital + lines.push_back("\xD0\x90\xD0\x91\xD0\x92\xD0\x93\xD0\x94\xD0\x95\xD0\x81\xD0\x96\xD0\x97" + "\xD0\x98\xD0\x99\xD0\x9A\xD0\x9B\xD0\x9C\xD0\x9D\xD0\x9E\xD0\x9F\xD0\xA0" + "\xD0\xA1\xD0\xA2\xD0\xA3\xD0\xA4\xD0\xA5\xD0\xA6\xD0\xA7\xD0\xA8\xD0\xA9" + "\xD0\xAA\xD0\xAB\xD0\xAC\xD0\xAD\xD0\xAE\xD0\xAF"); + // bounds + lines.push_back("-\xD0\x80-\xD0\x8E-\xD0\x8F-"); + lines.push_back("-\xD1\x90-\xD1\x91-\xD1\xBF-"); + // bad utf8 + lines.push_back("-\x81-\x82-\x83-"); + lines.push_back("--\xF0--"); + lines.push_back("-\xF0"); + + vector fonts; + fonts.push_back(FONT_HERSHEY_SIMPLEX); + fonts.push_back(FONT_HERSHEY_PLAIN); + fonts.push_back(FONT_HERSHEY_DUPLEX); + fonts.push_back(FONT_HERSHEY_COMPLEX); + fonts.push_back(FONT_HERSHEY_TRIPLEX); + fonts.push_back(FONT_HERSHEY_COMPLEX_SMALL); + fonts.push_back(FONT_HERSHEY_SCRIPT_SIMPLEX); + fonts.push_back(FONT_HERSHEY_SCRIPT_COMPLEX); + + vector results; + Size bigSize(0, 0); + for (vector::const_iterator font = fonts.begin(); font != fonts.end(); ++font) + { + for (int italic = 0; italic <= FONT_ITALIC; italic += FONT_ITALIC) + { + for (vector::const_iterator line = lines.begin(); line != lines.end(); ++line) + { + const float fontScale = 1; + const int thickness = 1; + const Scalar color(20,20,20); + int baseline = 0; + + Size textSize = getTextSize(*line, *font | italic, fontScale, thickness, &baseline); + Point textOrg(0, textSize.height + 2); + Mat img(textSize + Size(0, baseline), CV_8UC3, Scalar(255, 255, 255)); + putText(img, *line, textOrg, *font | italic, fontScale, color, thickness, CV_AA); + + results.push_back(img); + bigSize.width = max(bigSize.width, img.size().width); + bigSize.height += img.size().height + 1; + } + } + } + + int shift = 0; + Mat result(bigSize, CV_8UC3, Scalar(100, 100, 100)); + for (vector::const_iterator img = results.begin(); img != results.end(); ++img) + { + Rect roi(Point(0, shift), img->size()); + Mat sub(result, roi); + img->copyTo(sub); + shift += img->size().height + 1; + } + // imwrite("all_fonts.png", result); + } +}; + +TEST(Highgui_Drawing, utf8_support) { CV_DrawingTest_UTF8 test; test.safe_run(); }