Skip to content

Commit

Permalink
QR-Code-scanner: integrate QUIRC library, implement QrDecoder, drop ZBar
Browse files Browse the repository at this point in the history
  • Loading branch information
xiphon committed Dec 23, 2020
1 parent df77147 commit 8d4cda0
Show file tree
Hide file tree
Showing 15 changed files with 140 additions and 149 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@
path = monero
url = https://github.com/monero-project/monero
ignore = all
[submodule "external/quirc"]
path = external/quirc
url = https://github.com/dlbeer/quirc/
6 changes: 1 addition & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,8 @@ message(STATUS "OpenSSL: Version ${OPENSSL_VERSION}")
message(STATUS "OpenSSL: include dir at ${OPENSSL_INCLUDE_DIR}")
message(STATUS "OpenSSL: libraries at ${OPENSSL_LIBRARIES} ${OPENSSL_SSL_LIBRARIES}")

# Zbar (for QR scanner)
if(WITH_SCANNER)
add_definitions(-DWITH_SCANNER)
find_package(ZBar0 REQUIRED)
message(STATUS "libzbar: include dir at ${ZBAR_INCLUDE_DIR}")
message(STATUS "libzbar: libraries at ${ZBAR_LIBRARIES}")
endif()

# Sodium
Expand Down Expand Up @@ -563,6 +559,6 @@ if (HIDAPI_FOUND OR LibUSB_COMPILE_TEST_PASSED)
endif()
endif()

add_subdirectory(external)
add_subdirectory(translations)

add_subdirectory(src)
19 changes: 0 additions & 19 deletions Dockerfile.android
Original file line number Diff line number Diff line change
Expand Up @@ -151,25 +151,6 @@ RUN set -ex \
&& make -j${THREADS} install \
&& rm -rf $(pwd)

RUN git clone https://github.com/ZBar/ZBar.git --depth 1 \
&& cd ZBar \
&& git reset --hard 854a5d97059e395807091ac4d80c53f7968abb8f \
&& sed -i 's/SHARED/STATIC/' android/jni/Android.mk \
&& sed -i -E 's/(.*BUILD_STATIC_LIBRARY.*)/LOCAL_CPP_FEATURES := exceptions rtti features\n\0/' android/jni/Android.mk \
&& sed -i -E 's/(.*BUILD_STATIC_LIBRARY.*)/LOCAL_CFLAGS := -Wno-multichar\n\0/' android/jni/Android.mk \
&& sed -i -E 's/(.*BUILD_STATIC_LIBRARY.*)/LOCAL_CFLAGS += -D_ANDROID\n\0/' android/jni/Android.mk \
&& sed -i -E 's/(.*BUILD_STATIC_LIBRARY.*)/LOCAL_CFLAGS += -DLIBDIR="\\".\\""\n\0/' android/jni/Android.mk \
&& sed -i -E 's/(.*BUILD_STATIC_LIBRARY.*)/LOCAL_CFLAGS += -DBUILDING_LIBICONV\n\0/' android/jni/Android.mk \
&& sed -i -E 's/(.*BUILD_STATIC_LIBRARY.*)/LOCAL_CFLAGS += -DBUILDING_LIBCHARSET\n\0/' android/jni/Android.mk \
&& sed -i -E 's/(.*BUILD_STATIC_LIBRARY.*)/LOCAL_CFLAGS += -DIN_LIBRARY\n\0/' android/jni/Android.mk \
&& sed -i -E 's/(.*BUILD_STATIC_LIBRARY.*)/LOCAL_CFLAGS += -fno-stack-protector\n\0/' android/jni/Android.mk \
&& echo "APP_ABI := arm64-v8a \nAPP_STL := c++_shared \nTARGET_PLATFORM := ${ANDROID_API} \nTARGET_ARCH_ABI := arm64-v8a \nAPP_CFLAGS += -target aarch64-none-linux-android -fexceptions -fstack-protector-strong -fno-limit-debug-info -mfloat-abi=softfp -fno-builtin-memmove -fno-omit-frame-pointer -fno-stack-protector\n" \
>> android/jni/Application.mk \
&& cd android \
&& CC=${ANDROID_CLANG} CXX=${ANDROID_CLANGPP} ${ANDROID_NDK_ROOT}/ndk-build ICONV_SRC=${WORKDIR}/libiconv-${ICONV_VERSION} -B V=1 NDK_APPLICATION_MK=jni/Application.mk \
&& cp obj/local/arm64-v8a/lib* ${PREFIX}/lib \
&& cp -r ../include/* ${PREFIX}/include

RUN git clone -b libgpg-error-1.38 --depth 1 git://git.gnupg.org/libgpg-error.git \
&& cd libgpg-error \
&& git reset --hard 71d278824c5fe61865f7927a2ed1aa3115f9e439 \
Expand Down
10 changes: 2 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,13 +217,13 @@ The following instructions will fetch Qt from your distribution's repositories i
- For Ubuntu
`sudo apt install qtmultimedia5-dev qml-module-qtmultimedia libzbar-dev`
`sudo apt install qtmultimedia5-dev qml-module-qtmultimedia`
- For Gentoo
The *qml* USE flag must be enabled.
`emerge dev-qt/qtmultimedia:5 media-gfx/zbar`
`emerge dev-qt/qtmultimedia:5`
3. Clone repository
Expand Down Expand Up @@ -290,12 +290,6 @@ The Monero GUI on Windows is 64 bits only; 32-bit Windows GUI builds are not off
pacman -S mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-zeromq mingw-w64-x86_64-libsodium mingw-w64-x86_64-hidapi mingw-w64-x86_64-protobuf-c mingw-w64-x86_64-libusb mingw-w64-x86_64-libgcrypt
```
Optional : To build the flag `WITH_SCANNER`
```
pacman -S mingw-w64-x86_64-zbar
```
You find more details about those dependencies in the [Monero documentation](https://github.com/monero-project/monero). Note that that there is no more need to compile Boost from source; like everything else, you can install it now with a MSYS2 package.
4. Install Qt5
Expand Down
38 changes: 0 additions & 38 deletions cmake/FindZBar0.cmake

This file was deleted.

7 changes: 7 additions & 0 deletions external/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
add_library(quirc STATIC
quirc/lib/decode.c
quirc/lib/identify.c
quirc/lib/quirc.c
quirc/lib/version_db.c
)
target_include_directories(quirc PUBLIC quirc/lib)
1 change: 1 addition & 0 deletions external/quirc
Submodule quirc added at 7e7ab5
16 changes: 3 additions & 13 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,6 @@ if(ENABLE_PASS_STRENGTH_METER)
)
endif()

if(WITH_SCANNER)
file(GLOB QR_CODE_FILES
"QR-Code-scanner/*.h"
"QR-Code-scanner/*.cpp"
)
endif()

set(EXECUTABLE_FLAG)
if(MINGW)
set(EXECUTABLE_FLAG WIN32)
Expand All @@ -84,7 +77,6 @@ endif()
set(monero_wallet_gui_sources
${SOURCE_FILES}
${PASS_STRENGTH_FILES}
${QR_CODE_FILES}
${RESOURCES}
)

Expand Down Expand Up @@ -128,7 +120,6 @@ target_include_directories(monero-wallet-gui PUBLIC
${X11_INCLUDE_DIR}
${Boost_INCLUDE_DIRS}
${OPENSSL_INCLUDE_DIR}
${ZBAR_INCLUDE_DIR}
)

target_compile_definitions(monero-wallet-gui
Expand Down Expand Up @@ -159,6 +150,7 @@ target_link_libraries(monero-wallet-gui
${EXTRA_LIBRARIES}
${ICU_LIBRARIES}
openpgp
qrdecoder
translations
)

Expand All @@ -171,16 +163,14 @@ if(X11_FOUND)
endif()

if(WITH_SCANNER)
if(NOT ANDROID)
target_link_libraries(monero-wallet-gui qrscanner)
if(LINUX AND NOT ANDROID)
target_link_libraries(monero-wallet-gui
${ZBAR_LIBRARIES}
jpeg
v4l2
v4lconvert
rt
)
else()
target_link_libraries(monero-wallet-gui ${ZBAR_LIBRARIES})
endif()
endif()

Expand Down
23 changes: 20 additions & 3 deletions src/QR-Code-scanner/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,21 @@
file(GLOB_RECURSE SRC_SOURCES *.cpp)
file(GLOB_RECURSE SRC_HEADERS *.h)

add_library(qrdecoder STATIC
Decoder.cpp
)
target_link_libraries(qrdecoder
PUBLIC
Qt5::Gui
PRIVATE
quirc
)

if(WITH_SCANNER)
add_library(qrscanner
QrCodeScanner.cpp
QrScanThread.cpp
)
target_link_libraries(qrscanner
PUBLIC
Qt5::Multimedia
qrdecoder
)
endif()
71 changes: 71 additions & 0 deletions src/QR-Code-scanner/Decoder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include "Decoder.h"

#include <limits>

#include "quirc.h"

QrDecoder::QrDecoder()
: m_qr(quirc_new())
{
if (m_qr == nullptr)
{
throw std::runtime_error("QUIRC: failed to allocate memory");
}
}

QrDecoder::~QrDecoder()
{
quirc_destroy(m_qr);
}

std::vector<std::string> QrDecoder::decode(const QImage &image)
{
if (image.format() == QImage::Format_Grayscale8)
{
return decodeGrayscale8(image);
}
return decodeGrayscale8(image.convertToFormat(QImage::Format_Grayscale8));
}

std::vector<std::string> QrDecoder::decodeGrayscale8(const QImage &image)
{
if (quirc_resize(m_qr, image.width(), image.height()) < 0)
{
throw std::runtime_error("QUIRC: failed to allocate video memory");
}

uint8_t *rawImage = quirc_begin(m_qr, nullptr, nullptr);
if (rawImage == nullptr)
{
throw std::runtime_error("QUIRC: failed to get image buffer");
}
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
std::copy(image.constBits(), image.constBits() + image.sizeInBytes(), rawImage);
#else
std::copy(image.constBits(), image.constBits() + image.byteCount(), rawImage);
#endif
quirc_end(m_qr);

const int count = quirc_count(m_qr);
if (count < 0)
{
throw std::runtime_error("QUIRC: failed to get the number of recognized QR-codes");
}

std::vector<std::string> result;
result.reserve(static_cast<size_t>(count));
for (int index = 0; index < count; ++index)
{
quirc_code code;
quirc_extract(m_qr, index, &code);

quirc_data data;
const quirc_decode_error_t err = quirc_decode(&code, &data);
if (err == QUIRC_SUCCESS)
{
result.emplace_back(&data.payload[0], &data.payload[data.payload_len]);
}
}

return result;
}
21 changes: 21 additions & 0 deletions src/QR-Code-scanner/Decoder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include <QImage>

struct quirc;

class QrDecoder
{
public:
QrDecoder(const QrDecoder &) = delete;
QrDecoder &operator=(const QrDecoder &) = delete;

QrDecoder();
~QrDecoder();

std::vector<std::string> decode(const QImage &image);

private:
std::vector<std::string> decodeGrayscale8(const QImage &image);

private:
quirc *m_qr;
};
3 changes: 1 addition & 2 deletions src/QR-Code-scanner/QrCodeScanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "QrCodeScanner.h"
#include <WalletManager.h>
#include <QVideoProbe>
#include <QCamera>

Expand All @@ -40,7 +39,7 @@ QrCodeScanner::QrCodeScanner(QObject *parent)
m_probe = new QVideoProbe(this);
m_thread = new QrScanThread(this);
m_thread->start();
QObject::connect(m_thread, SIGNAL(decoded(int, QString)), this, SIGNAL(decoded(int, QString)));
QObject::connect(m_thread, SIGNAL(decoded(QString)), this, SIGNAL(decoded(QString)));
QObject::connect(m_thread, SIGNAL(notifyError(const QString &, bool)), this, SIGNAL(notifyError(const QString &, bool)));
connect(m_probe, SIGNAL(videoFrameProbed(QVideoFrame)), this, SLOT(processFrame(QVideoFrame)));
}
Expand Down
3 changes: 1 addition & 2 deletions src/QR-Code-scanner/QrCodeScanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@ public Q_SLOTS:
Q_SIGNALS:
void enabledChanged();

void decoded(int type, const QString &data);
void decode(int type, const QString &data);
void decoded(const QString &data);
void notifyError(const QString &error, bool warning = false);

protected:
Expand Down
Loading

0 comments on commit 8d4cda0

Please sign in to comment.