diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f808864..69f2232 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,154 +1,155 @@ set(KDE_INSTALL_INCLUDEDIR_PIM ${KDE_INSTALL_INCLUDEDIR}/KPim) add_subdirectory(knowledgedb-generator) configure_file(config-kitinerary.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kitinerary.h) set(kitinerary_lib_srcs datatypes/action.cpp datatypes/brand.cpp datatypes/bustrip.cpp datatypes/event.cpp datatypes/flight.cpp datatypes/organization.cpp datatypes/person.cpp datatypes/place.cpp datatypes/reservation.cpp datatypes/taxi.cpp datatypes/ticket.cpp datatypes/traintrip.cpp datatypes/rentalcar.cpp datatypes/visit.cpp jsapi/barcode.cpp jsapi/context.cpp jsapi/jsonld.cpp knowledgedb/airportdb.cpp knowledgedb/countrydb.cpp knowledgedb/knowledgedb.cpp knowledgedb/timezonedb.cpp knowledgedb/trainstationdb.cpp barcodedecoder.cpp calendarhandler.cpp extractor.cpp extractorengine.cpp extractorfilter.cpp extractorpostprocessor.cpp extractorrepository.cpp genericpdfextractor.cpp htmldocument.cpp iatabcbpparser.cpp jsonlddocument.cpp jsonldimportfilter.cpp mergeutil.cpp pdfdocument.cpp + qimageluminancesource.cpp sortutil.cpp stringutil.cpp structureddataextractor.cpp uic9183parser.cpp ) qt5_add_resources(kitinerary_lib_srcs extractors/extractors.qrc) ecm_qt_declare_logging_category(kitinerary_lib_srcs HEADER logging.h IDENTIFIER KItinerary::Log CATEGORY_NAME org.kde.kitinerary) kde_source_files_enable_exceptions(barcodedecoder.cpp) add_library(KPimItinerary ${kitinerary_lib_srcs}) add_library(KPim::Itinerary ALIAS KPimItinerary) generate_export_header(KPimItinerary BASE_NAME KItinerary) set_target_properties(KPimItinerary PROPERTIES VERSION ${KITINERARY_VERSION_STRING} SOVERSION ${KITINERARY_SOVERSION} EXPORT_NAME Itinerary ) target_include_directories(KPimItinerary INTERFACE "$") target_include_directories(KPimItinerary PUBLIC "$") target_link_libraries(KPimItinerary PUBLIC Qt5::Core KF5::Mime PRIVATE Qt5::Qml KF5::I18n KF5::Contacts KPim::PkPass ${ZLIB_LIBRARIES} ) if (HAVE_POPPLER) target_link_libraries(KPimItinerary PRIVATE Poppler::Core) endif() if (HAVE_ZXING) target_link_libraries(KPimItinerary PRIVATE zxing::libzxing) endif() if (HAVE_KCAL) target_link_libraries(KPimItinerary PUBLIC KF5::CalendarCore) endif() if (HAVE_LIBXML2) target_compile_definitions(KPimItinerary PRIVATE ${LIBXML2_DEFINITIONS}) target_include_directories(KPimItinerary PRIVATE ${LIBXML2_INCLUDE_DIR}) target_link_libraries(KPimItinerary PRIVATE ${LIBXML2_LIBRARIES}) endif() ecm_generate_headers(KItinerary_FORWARDING_HEADERS HEADER_NAMES BarcodeDecoder CalendarHandler Extractor ExtractorEngine ExtractorPostprocessor HtmlDocument IataBcbpParser JsonLdDocument MergeUtil PdfDocument SortUtil Uic9183Parser PREFIX KItinerary REQUIRED_HEADERS KItinerary_HEADERS ) ecm_generate_headers(KItinerary_KnowledgeDb_FORWARDING_HEADERS HEADER_NAMES AirportDb CountryDb KnowledgeDb TrainStationDb PREFIX KItinerary REQUIRED_HEADERS KItinerary_KnowledgeDb_HEADERS RELATIVE knowledgedb ) ecm_generate_headers(KItinerary_Datatypes_FORWARDING_HEADERS HEADER_NAMES Action Brand BusTrip Datatypes Event Flight Organization Reservation RentalCar Person Place Taxi Ticket TrainTrip Visit PREFIX KItinerary REQUIRED_HEADERS KItinerary_Datatypes_HEADERS RELATIVE datatypes ) install(TARGETS KPimItinerary EXPORT KPimItineraryTargets ${INSTALL_TARGETS_DEFAULT_ARGS}) install(FILES ${KItinerary_FORWARDING_HEADERS} ${KItinerary_KnowledgeDb_FORWARDING_HEADERS} ${KItinerary_Datatypes_FORWARDING_HEADERS} DESTINATION ${KDE_INSTALL_INCLUDEDIR_PIM}/KItinerary ) install(FILES ${KItinerary_HEADERS} ${KItinerary_AirportDb_HEADERS} ${KItinerary_Datatypes_HEADERS} ${KItinerary_KnowledgeDb_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/kitinerary_export.h DESTINATION ${KDE_INSTALL_INCLUDEDIR_PIM}/kitinerary ) diff --git a/src/barcodedecoder.cpp b/src/barcodedecoder.cpp index dc9d0b3..c14edcc 100644 --- a/src/barcodedecoder.cpp +++ b/src/barcodedecoder.cpp @@ -1,197 +1,129 @@ /* Copyright (C) 2018 Volker Krause This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config-kitinerary.h" #include "barcodedecoder.h" #include "logging.h" +#include "qimageluminancesource.h" #include #include #include #ifdef HAVE_ZXING #include #include -#include #include #include #include #endif #include using namespace KItinerary; -namespace KItinerary { #ifdef HAVE_ZXING -class QImageLuminanceSource : public zxing::LuminanceSource -{ -public: - explicit QImageLuminanceSource(const QImage &img); - - zxing::ArrayRef getRow(int y, zxing::ArrayRef row) const override; - zxing::ArrayRef getMatrix() const override; - -private: - char luminance(int x, int y) const; - - QImage m_img; -}; - -#endif -} - -#ifdef HAVE_ZXING -// this automatically adds a 1px quiet zone around the content -QImageLuminanceSource::QImageLuminanceSource(const QImage &img) - : zxing::LuminanceSource(img.width() + 2, img.height() + 2) - , m_img(img) -{ -} - -zxing::ArrayRef QImageLuminanceSource::getRow(int y, zxing::ArrayRef row) const -{ - if (!row) { - row = zxing::ArrayRef(getWidth()); - } - - if (y == 0 || y == getHeight() - 1) { - memset(&row[0], 0xff, getWidth()); - return row; - } - - row[0] = (char)0xff; - for (int i = 1; i < getWidth() - 1; ++i) { - row[i] = luminance(i - 1, y); - } - row[getWidth() - 1] = (char)0xff; - - return row; -} - -zxing::ArrayRef QImageLuminanceSource::getMatrix() const -{ - zxing::ArrayRef matrix(getWidth() * getHeight()); - - memset(&matrix[0], 0xff, getWidth()); - for (int i = 1; i < getHeight() - 1; ++i) { - matrix[i * getWidth()] = (char)0xff; - for (int j = 1; j < getWidth() - 1; ++j) { - matrix[i * getWidth() + j] = luminance(j - 1, i - 1); - } - matrix[(i + 1) * getWidth() - 1] = (char)0xff; - } - memset(&matrix[(getHeight() - 1) * getWidth()], 0xff, getWidth()); - - return matrix; -} - -char QImageLuminanceSource::luminance(int x, int y) const -{ - return qGray(m_img.pixel(x, y)); -} - static QString decodePdf417Internal(const QImage &img) { try { const zxing::Ref source(new QImageLuminanceSource(img)); const zxing::Ref binarizer(new zxing::HybridBinarizer(source)); const zxing::Ref binary(new zxing::BinaryBitmap(binarizer)); const zxing::DecodeHints hints(zxing::DecodeHints::PDF_417_HINT); zxing::MultiFormatReader reader; const auto result = reader.decode(binary, hints); return QString::fromStdString(result->getText()->getText()); } catch (const std::exception &e) { //qCDebug(Log) << e.what(); } return {}; } #endif QString BarcodeDecoder::decodePdf417(const QImage &img) { #ifdef HAVE_ZXING auto normalizedImg = img; if (normalizedImg.width() < normalizedImg.height()) { QTransform tf; tf.rotate(-90); normalizedImg = normalizedImg.transformed(tf); } const auto result = decodePdf417Internal(normalizedImg); if (!result.isEmpty()) { return result; } // try flipped around the x axis, zxing doesn't detect that, but it's e.g. encountered in SAS passes return decodePdf417Internal(normalizedImg.transformed(QTransform{1, 0, 0, -1, 0, 0})); #else Q_UNUSED(img); #endif return {}; } QString BarcodeDecoder::decodeAztec(const QImage &img) { return QString::fromUtf8(decodeAztecBinary(img)); } QByteArray BarcodeDecoder::decodeAztecBinary(const QImage &img) { #ifdef HAVE_ZXING try { const zxing::Ref source(new QImageLuminanceSource(img)); const zxing::Ref binarizer(new zxing::HybridBinarizer(source)); const zxing::Ref binary(new zxing::BinaryBitmap(binarizer)); const zxing::DecodeHints hints(zxing::DecodeHints::AZTEC_HINT); zxing::MultiFormatReader reader; const auto result = reader.decode(binary, hints); return QByteArray(result->getText()->getText().c_str(), result->getText()->getText().size()); } catch (const std::exception &e) { //qCDebug(Log) << e.what(); } #else Q_UNUSED(img); #endif return {}; } QString BarcodeDecoder::decodeQRCode(const QImage &img) { #ifdef HAVE_ZXING try { const zxing::Ref source(new QImageLuminanceSource(img)); const zxing::Ref binarizer(new zxing::HybridBinarizer(source)); const zxing::Ref binary(new zxing::BinaryBitmap(binarizer)); const zxing::DecodeHints hints(zxing::DecodeHints::QR_CODE_HINT); zxing::MultiFormatReader reader; const auto result = reader.decode(binary, hints); return QString::fromStdString(result->getText()->getText()); } catch (const std::exception &e) { //qCDebug(Log) << e.what(); } #else Q_UNUSED(img); #endif return {}; } diff --git a/src/qimageluminancesource.cpp b/src/qimageluminancesource.cpp new file mode 100644 index 0000000..1593362 --- /dev/null +++ b/src/qimageluminancesource.cpp @@ -0,0 +1,73 @@ +/* + Copyright (C) 2018 Volker Krause + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "qimageluminancesource.h" +#ifdef HAVE_ZXING + +using namespace KItinerary; + +QImageLuminanceSource::QImageLuminanceSource(const QImage &img) + : zxing::LuminanceSource(img.width() + 2, img.height() + 2) + , m_img(img) +{ +} + +QImageLuminanceSource::~QImageLuminanceSource() = default; + +zxing::ArrayRef QImageLuminanceSource::getRow(int y, zxing::ArrayRef row) const +{ + if (!row) { + row = zxing::ArrayRef(getWidth()); + } + + if (y == 0 || y == getHeight() - 1) { + memset(&row[0], 0xff, getWidth()); + return row; + } + + row[0] = (char)0xff; + for (int i = 1; i < getWidth() - 1; ++i) { + row[i] = luminance(i - 1, y); + } + row[getWidth() - 1] = (char)0xff; + + return row; +} + +zxing::ArrayRef QImageLuminanceSource::getMatrix() const +{ + zxing::ArrayRef matrix(getWidth() * getHeight()); + + memset(&matrix[0], 0xff, getWidth()); + for (int i = 1; i < getHeight() - 1; ++i) { + matrix[i * getWidth()] = (char)0xff; + for (int j = 1; j < getWidth() - 1; ++j) { + matrix[i * getWidth() + j] = luminance(j - 1, i - 1); + } + matrix[(i + 1) * getWidth() - 1] = (char)0xff; + } + memset(&matrix[(getHeight() - 1) * getWidth()], 0xff, getWidth()); + + return matrix; +} + +char QImageLuminanceSource::luminance(int x, int y) const +{ + return qGray(m_img.pixel(x, y)); +} + +#endif diff --git a/src/qimageluminancesource.h b/src/qimageluminancesource.h new file mode 100644 index 0000000..55c8c55 --- /dev/null +++ b/src/qimageluminancesource.h @@ -0,0 +1,52 @@ +/* + Copyright (C) 2018 Volker Krause + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef KITINERARY_QIMAGELUMINANCESOURCE_H +#define KITINERARY_QIMAGELUMINANCESOURCE_H + +#include "config-kitinerary.h" +#ifdef HAVE_ZXING + +#include + +#include + +namespace KItinerary { + +/** QImage-based LuminanceSource. + * This automatically adds a 1px quiet zone around the content. + */ +class QImageLuminanceSource : public zxing::LuminanceSource +{ +public: + explicit QImageLuminanceSource(const QImage &img); + ~QImageLuminanceSource(); + + zxing::ArrayRef getRow(int y, zxing::ArrayRef row) const override; + zxing::ArrayRef getMatrix() const override; + +private: + char luminance(int x, int y) const; + + QImage m_img; +}; + +} + +#endif + +#endif // KITINERARY_QIMAGELUMINANCESOURCE_H