summaryrefslogtreecommitdiffstats
path: root/gis/qmapshack/rgb2pct.patch
diff options
context:
space:
mode:
Diffstat (limited to 'gis/qmapshack/rgb2pct.patch')
-rw-r--r--gis/qmapshack/rgb2pct.patch971
1 files changed, 0 insertions, 971 deletions
diff --git a/gis/qmapshack/rgb2pct.patch b/gis/qmapshack/rgb2pct.patch
deleted file mode 100644
index 92c5df8776..0000000000
--- a/gis/qmapshack/rgb2pct.patch
+++ /dev/null
@@ -1,971 +0,0 @@
-From 763cfc149566325cce9e4690cb7b5f986048f86a Mon Sep 17 00:00:00 2001
-From: Oliver Eichler <oliver.eichler@dspsolutions.de>
-Date: Thu, 12 Sep 2019 20:32:06 +0200
-Subject: [PATCH] [QMS-3] Add qmt_rgb2pct from former sub-repo
-
----
- src/qmt_rgb2pct/CApp.cpp | 280 +++++++++++++++++++++++
- src/qmt_rgb2pct/CApp.h | 55 +++++
- src/qmt_rgb2pct/CMakeLists.txt | 117 ++++++++++
- src/qmt_rgb2pct/README.md | 5 +
- src/qmt_rgb2pct/locale/qmt_rgb2pct.ts | 126 ++++++++++
- src/qmt_rgb2pct/locale/qmt_rgb2pct_de.ts | 127 ++++++++++
- src/qmt_rgb2pct/main.cpp | 155 +++++++++++++
- src/qmt_rgb2pct/version.h | 33 +++
- 8 files changed, 898 insertions(+)
- create mode 100644 src/qmt_rgb2pct/CApp.cpp
- create mode 100644 src/qmt_rgb2pct/CApp.h
- create mode 100644 src/qmt_rgb2pct/CMakeLists.txt
- create mode 100644 src/qmt_rgb2pct/README.md
- create mode 100644 src/qmt_rgb2pct/locale/qmt_rgb2pct.ts
- create mode 100644 src/qmt_rgb2pct/locale/qmt_rgb2pct_de.ts
- create mode 100644 src/qmt_rgb2pct/main.cpp
- create mode 100644 src/qmt_rgb2pct/version.h
-
-diff --git a/src/qmt_rgb2pct/CApp.cpp b/src/qmt_rgb2pct/CApp.cpp
-new file mode 100644
-index 00000000..993ed759
---- /dev/null
-+++ b/src/qmt_rgb2pct/CApp.cpp
-@@ -0,0 +1,280 @@
-+/**********************************************************************************************
-+ Copyright (C) 2018 Oliver Eichler oliver.eichler@gmx.de
-+
-+ This program is free software: you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation, either version 3 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 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 <http://www.gnu.org/licenses/>.
-+
-+**********************************************************************************************/
-+
-+#include "CApp.h"
-+
-+#include <gdal_alg.h>
-+#include <gdal_priv.h>
-+#include <iostream>
-+
-+const GDALColorEntry CApp::noColor = {255,255,255,0};
-+
-+void printStdoutQString(const QString& str)
-+{
-+ QByteArray array = str.toUtf8();
-+ printf("%s", array.data());
-+ printf("\n");
-+}
-+
-+void printStderrQString(const QString& str)
-+{
-+ QByteArray array = str.toUtf8();
-+ fprintf(stderr, "%s", array.data());
-+ fprintf(stderr, "\n");
-+}
-+
-+
-+
-+CApp::CApp(qint32 ncolors, const QString& pctFilename, const QString &sctFilename, const QString &srcFilename, const QString &tarFilename)
-+ : ncolors(ncolors)
-+ , pctFilename(pctFilename)
-+ , sctFilename(sctFilename)
-+ , srcFilename(srcFilename)
-+ , tarFilename(tarFilename)
-+{
-+ GDALAllRegister();
-+}
-+
-+qint32 CApp::exec()
-+{
-+ qint32 res = 0;
-+ GDALColorTable * ct = nullptr;
-+ GDALDataset * dsSrc = nullptr;
-+ try
-+ {
-+ dsSrc = (GDALDataset*)GDALOpenShared(srcFilename.toUtf8(),GA_ReadOnly);
-+ if(dsSrc == nullptr)
-+ {
-+ throw tr("Failed to open source file.");
-+ }
-+
-+ if(dsSrc->GetRasterCount() < 3 || dsSrc->GetRasterCount() > 4)
-+ {
-+ throw tr("Raster band count of source file must be either 3 or 4.");
-+ }
-+
-+ if(QFile(tarFilename).exists())
-+ {
-+ QFile::remove(tarFilename);
-+ }
-+
-+ ct = createColorTable(ncolors, pctFilename, dsSrc);
-+ saveColorTable(ct, sctFilename);
-+ ditherMap(dsSrc, tarFilename, ct);
-+ }
-+ catch(const QString& msg)
-+ {
-+ printStderrQString(msg);
-+ res = -1;
-+ }
-+
-+
-+ GDALClose(dsSrc);
-+ delete ct;
-+ return res;
-+}
-+
-+GDALColorTable * CApp::createColorTable(qint32 ncolors, const QString& pctFilename, GDALDataset * dataset)
-+{
-+ GDALColorTable * ct = nullptr;
-+ try
-+ {
-+ if(pctFilename.isEmpty())
-+ {
-+ ct = (GDALColorTable*)GDALCreateColorTable(GPI_RGB);
-+
-+ printStdoutQString(tr("Calculate optimal color table from source file"));
-+
-+ int ok = GDALComputeMedianCutPCT(dataset->GetRasterBand(1),
-+ dataset->GetRasterBand(2),
-+ dataset->GetRasterBand(3),
-+ nullptr,
-+ ncolors,
-+ ct,
-+ GDALTermProgress,
-+ 0
-+ );
-+
-+ if(ok != CE_None)
-+ {
-+ throw tr("Failed to create color table.");
-+ }
-+ }
-+ else
-+ {
-+ GDALDataset * dsPct = (GDALDataset*)GDALOpenShared(pctFilename.toUtf8(),GA_ReadOnly);
-+ if(dsPct == nullptr)
-+ {
-+ throw tr("Failed to open file with palette.");
-+ }
-+
-+ GDALRasterBand * band = (GDALRasterBand*)dsPct->GetRasterBand(1);
-+
-+ if((dsPct->GetRasterCount() != 1) || (band->GetColorInterpretation() != GCI_PaletteIndex))
-+ {
-+ GDALClose(dsPct);
-+ throw tr("Palette file does not have a single band with a color table");
-+ }
-+
-+ int ok = 0;
-+ band->GetNoDataValue(&ok);
-+
-+ if(ok || band->GetColorTable()->GetColorEntryCount() > 255)
-+ {
-+ GDALClose(dsPct);
-+ throw tr("The color table must not contain a \"no data\" value and it's size must not exceed 255 colors.");
-+ }
-+
-+ ct = dsPct->GetRasterBand(1)->GetColorTable()->Clone();
-+ }
-+ }
-+ catch(const QString& msg)
-+ {
-+ delete ct;
-+ throw msg;
-+ }
-+ return ct;
-+}
-+
-+void CApp::saveColorTable(GDALColorTable * ct, QString& sctFilename)
-+{
-+ if(sctFilename.isEmpty())
-+ {
-+ return;
-+ }
-+
-+ if(!sctFilename.endsWith(".vrt"))
-+ {
-+ sctFilename += ".vrt";
-+ }
-+
-+ QByteArray buf = sctFilename.toUtf8();
-+ printStdoutQString(tr("Save color table to: %1").arg(buf.data()));
-+
-+ GDALDriverManager * drvman = GetGDALDriverManager();
-+ GDALDriver * driver = drvman->GetDriverByName("VRT");
-+ GDALDataset * dataset = driver->Create(sctFilename.toUtf8(), 1, 1, 1, GDT_Byte, {});
-+
-+ dataset->GetRasterBand(1)->SetColorInterpretation(GCI_PaletteIndex);
-+ dataset->GetRasterBand(1)->SetColorTable(ct);
-+
-+ dataset->FlushCache();
-+ GDALClose(dataset);
-+}
-+
-+void CApp::ditherMap(GDALDataset * dsSrc, const QString& tarFilename, GDALColorTable *ct)
-+{
-+ if(tarFilename.isEmpty())
-+ {
-+ return;
-+ }
-+
-+ qint32 xsize = dsSrc->GetRasterBand(1)->GetXSize();
-+ qint32 ysize = dsSrc->GetRasterBand(1)->GetYSize();
-+
-+ GDALDriverManager * drvman = nullptr;
-+ GDALDriver * driver = nullptr;
-+ GDALDataset * dataset = nullptr;
-+
-+ try
-+ {
-+ const char * cargs[] = {"TILED=YES","COMPRESS=LZW", 0};
-+ drvman = GetGDALDriverManager();
-+ driver = drvman->GetDriverByName("GTiff");
-+ dataset = driver->Create(tarFilename.toUtf8(), xsize, ysize, 1, GDT_Byte, (char**)cargs);
-+
-+ if(dataset == nullptr)
-+ {
-+ throw tr("Failed to create target file.");
-+ }
-+
-+ dataset->GetRasterBand(1)->SetColorTable(ct);
-+ dataset->GetRasterBand(1)->SetNoDataValue(ct->GetColorEntryCount());
-+ dataset->SetProjection(dsSrc->GetProjectionRef());
-+
-+ double adfGeoTransform[6] = {0};
-+ dsSrc->GetGeoTransform(adfGeoTransform);
-+ dataset->SetGeoTransform(adfGeoTransform);
-+
-+ printStdoutQString(tr("Dither source file to target file"));
-+ int res = GDALDitherRGB2PCT(dsSrc->GetRasterBand(1),
-+ dsSrc->GetRasterBand(2),
-+ dsSrc->GetRasterBand(3),
-+ dataset->GetRasterBand(1),
-+ ct,
-+ GDALTermProgress,
-+ 0
-+ );
-+ if(res != CE_None)
-+ {
-+ throw tr("Failed to dither file.");
-+ }
-+
-+ if(dsSrc->GetRasterCount() == 3)
-+ {
-+ return;
-+ }
-+
-+ GDALRasterBand * alpha = dsSrc->GetRasterBand(4);
-+ GDALRasterBand * band = dataset->GetRasterBand(1);
-+
-+ QByteArray buffer1(xsize, 0);
-+ QByteArray buffer2(xsize, 0);
-+
-+ quint8 nodata = band->GetNoDataValue();
-+ printStdoutQString(tr("Apply alpha channel as no data value to target file"));
-+ for(int y = 0; y < ysize; y++)
-+ {
-+ GDALTermProgress(double(xsize * y)/(xsize*ysize),0,0);
-+ res = alpha->RasterIO(GF_Read, 0, y, xsize, 1, buffer1.data(), xsize, 1, GDT_Byte, 0, 0);
-+ if(res != CE_None)
-+ {
-+ throw tr("Failed to read from alpha channel.");
-+ }
-+
-+ res = band->RasterIO(GF_Read, 0, y, xsize, 1, buffer2.data(), xsize, 1, GDT_Byte, 0, 0);
-+ if(res != CE_None)
-+ {
-+ throw tr("Failed to read from target file.");
-+ }
-+
-+ for(int x = 0; x < xsize; x++)
-+ {
-+ if(buffer1[x] != char(0xFF))
-+ {
-+ buffer2[x] = nodata;
-+ }
-+ }
-+
-+ res = band->RasterIO(GF_Write, 0, y, xsize, 1, buffer2.data(), xsize, 1, GDT_Byte, 0, 0);
-+ if(res != CE_None)
-+ {
-+ throw tr("Failed to write to target file.");
-+ }
-+ }
-+ GDALTermProgress(1.0,0,0);
-+ }
-+ catch(const QString& msg)
-+ {
-+ GDALClose(dataset);
-+ throw msg;
-+ }
-+
-+ dataset->FlushCache();
-+ GDALClose(dataset);
-+}
-diff --git a/src/qmt_rgb2pct/CApp.h b/src/qmt_rgb2pct/CApp.h
-new file mode 100644
-index 00000000..e2e0f7ca
---- /dev/null
-+++ b/src/qmt_rgb2pct/CApp.h
-@@ -0,0 +1,55 @@
-+/**********************************************************************************************
-+ Copyright (C) 2018 Oliver Eichler oliver.eichler@gmx.de
-+
-+ This program is free software: you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation, either version 3 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 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 <http://www.gnu.org/licenses/>.
-+
-+**********************************************************************************************/
-+
-+#ifndef CAPP_H
-+#define CAPP_H
-+
-+#include <QtCore>
-+#include <gdal.h>
-+
-+class GDALColorTable;
-+class GDALDataset;
-+
-+class CApp
-+{
-+ Q_DECLARE_TR_FUNCTIONS(CApp)
-+public:
-+ CApp(qint32 ncolors, const QString& pctFilename, const QString& sctFilename, const QString& srcFilename, const QString& tarFilename);
-+ virtual ~CApp() = default;
-+
-+ qint32 exec();
-+
-+private:
-+ static GDALColorTable * createColorTable(qint32 ncolors, const QString& pctFilename, GDALDataset *dataset);
-+ static void saveColorTable(GDALColorTable *ct, QString &sctFilename);
-+ static void ditherMap(GDALDataset * dsSrc, const QString& tarFilename, GDALColorTable *ct);
-+
-+ qint32 ncolors = 0;
-+ QString pctFilename;
-+ QString sctFilename;
-+ QString srcFilename;
-+ QString tarFilename;
-+
-+ static const GDALColorEntry noColor;
-+};
-+
-+void printStdoutQString(const QString& str);
-+void printStderrQString(const QString& str);
-+
-+#endif //CAPP_H
-+
-diff --git a/src/qmt_rgb2pct/CMakeLists.txt b/src/qmt_rgb2pct/CMakeLists.txt
-new file mode 100644
-index 00000000..c763595e
---- /dev/null
-+++ b/src/qmt_rgb2pct/CMakeLists.txt
-@@ -0,0 +1,117 @@
-+# Prevent custom commands/targets outputs to be deleted by make clean
-+# We need this to prevent .ts files from being deleted with make clean, when
-+# UPDATE_TRANSLATIONS=ON
-+# WARNING: Only works with Makefile generator.
-+set_directory_properties(PROPERTIES CLEAN_NO_CUSTOM TRUE)
-+# Find includes in corresponding build directories
-+set(CMAKE_INCLUDE_CURRENT_DIR ON)
-+# Instruct CMake to run moc automatically when needed.
-+set(CMAKE_AUTOMOC ON)
-+
-+###############################################################################################
-+# Setup application name and version tags
-+###############################################################################################
-+
-+set(APPLICATION_NAME qmt_rgb2pct)
-+set(RGB2PCT_VERSION_MAJOR 1)
-+set(RGB2PCT_VERSION_MINOR 0)
-+set(RGB2PCT_VERSION_PATCH 0)
-+
-+add_definitions(
-+ -DVER_MAJOR=${RGB2PCT_VERSION_MAJOR}
-+ -DVER_MINOR=${RGB2PCT_VERSION_MINOR}
-+ -DVER_STEP=${RGB2PCT_VERSION_PATCH}
-+ -DVER_TWEAK=${VERSION_SUFFIX}
-+ -DAPPLICATION_NAME=${APPLICATION_NAME}
-+)
-+
-+###############################################################################################
-+# All source files needed to compile
-+###############################################################################################
-+set( SRCS
-+ main.cpp
-+ CApp.cpp
-+)
-+
-+set( HDRS
-+ version.h
-+ CApp.h
-+)
-+
-+set( UIS
-+)
-+
-+set( RCS
-+)
-+
-+###############################################################################################
-+# Some Qt magic
-+###############################################################################################
-+
-+qt5_wrap_ui(UI_HDRS ${UIS})
-+qt5_add_resources(RC_SRCS ${RCS})
-+
-+###############################################################################################
-+# Translation related stuff
-+###############################################################################################
-+translate_ts(${APPLICATION_NAME}_QM_FILES
-+ UPDATE_TRANSLATIONS ${UPDATE_TRANSLATIONS}
-+ UPDATE_OPTIONS "-I${CMAKE_CURRENT_SOURCE_DIR}" ${KEEP_OLD_TRANSLATIONS}
-+ SOURCES ${SRCS} ${HDRS} ${UIS}
-+ TEMPLATE ${APPLICATION_NAME}
-+ TRANSLATION_DIR "locale"
-+)
-+
-+###############################################################################################
-+# Build source file and include paths lists
-+###############################################################################################
-+set(MAININP
-+ ${SRCS}
-+ ${HDRS}
-+ ${UI_HDRS}
-+ ${RC_SRCS}
-+ ${${APPLICATION_NAME}_QM_FILES}
-+ ${${APPLICATION_NAME}_DESKTOP_FILES}
-+)
-+
-+include_directories(
-+ SYSTEM # this prevents warnings from non-QMS headers
-+ ${CMAKE_BINARY_DIR}
-+ ${GDAL_INCLUDE_DIRS}
-+ ${PROJ4_INCLUDE_DIRS}
-+)
-+
-+if(APPLE)
-+ INCLUDE_DIRECTORIES(/System/Library/Frameworks/Foundation.framework)
-+ INCLUDE_DIRECTORIES(/System/Library/Frameworks/DiskArbitration.framework)
-+endif(APPLE)
-+
-+
-+###############################################################################################
-+# Build the executable and define necessary libraries.
-+###############################################################################################
-+add_executable(${APPLICATION_NAME} WIN32 ${MAININP})
-+
-+target_link_libraries(${APPLICATION_NAME}
-+ Qt5::Core
-+ ${GDAL_LIBRARIES}
-+ ${PROJ4_LIBRARIES}
-+)
-+
-+if(APPLE)
-+ target_link_libraries(${APPLICATION_NAME}
-+ ${Foundation_LIBRARY}
-+ ${DiskArbitration_LIBRARY}
-+ )
-+endif(APPLE)
-+
-+
-+###############################################################################################
-+# Install target related stuff
-+###############################################################################################
-+install(TARGETS ${APPLICATION_NAME} DESTINATION ${BIN_INSTALL_DIR})
-+
-+if (UNIX AND NOT WIN32 AND NOT APPLE)
-+ install(FILES ${${APPLICATION_NAME}_QM_FILES} DESTINATION ${DATA_INSTALL_PREFIX}/${APPLICATION_NAME}/translations)
-+ install(FILES ${${APPLICATION_NAME}_DESKTOP_FILES} DESTINATION ${XDG_APPS_DIR})
-+endif (UNIX AND NOT WIN32 AND NOT APPLE)
-diff --git a/src/qmt_rgb2pct/README.md b/src/qmt_rgb2pct/README.md
-new file mode 100644
-index 00000000..21e6c750
---- /dev/null
-+++ b/src/qmt_rgb2pct/README.md
-@@ -0,0 +1,5 @@
-+This is a sub-project of QMapShack and it's not supposed to compile on it's own. Please refere to
-+
-+https://bitbucket.org/maproom/qmapshack/overview
-+
-+to check out and compile this project.
-\ No newline at end of file
-diff --git a/src/qmt_rgb2pct/locale/qmt_rgb2pct.ts b/src/qmt_rgb2pct/locale/qmt_rgb2pct.ts
-new file mode 100644
-index 00000000..02904577
---- /dev/null
-+++ b/src/qmt_rgb2pct/locale/qmt_rgb2pct.ts
-@@ -0,0 +1,126 @@
-+<?xml version="1.0" encoding="utf-8"?>
-+<!DOCTYPE TS>
-+<TS version="2.1">
-+<context>
-+ <name>CApp</name>
-+ <message>
-+ <location filename="../CApp.cpp" line="63"/>
-+ <source>Failed to open source file.</source>
-+ <translation type="unfinished"></translation>
-+ </message>
-+ <message>
-+ <location filename="../CApp.cpp" line="68"/>
-+ <source>Raster band count of source file must be either 3 or 4.</source>
-+ <translation type="unfinished"></translation>
-+ </message>
-+ <message>
-+ <location filename="../CApp.cpp" line="101"/>
-+ <source>Calculate optimal color table from source file</source>
-+ <translation type="unfinished"></translation>
-+ </message>
-+ <message>
-+ <location filename="../CApp.cpp" line="115"/>
-+ <source>Failed to create color table.</source>
-+ <translation type="unfinished"></translation>
-+ </message>
-+ <message>
-+ <location filename="../CApp.cpp" line="123"/>
-+ <source>Failed to open file with palette.</source>
-+ <translation type="unfinished"></translation>
-+ </message>
-+ <message>
-+ <location filename="../CApp.cpp" line="131"/>
-+ <source>Palette file does not have a single band with a color table</source>
-+ <translation type="unfinished"></translation>
-+ </message>
-+ <message>
-+ <location filename="../CApp.cpp" line="140"/>
-+ <source>The color table must not contain a &quot;no data&quot; value and it&apos;s size must not exceed 255 colors.</source>
-+ <translation type="unfinished"></translation>
-+ </message>
-+ <message>
-+ <location filename="../CApp.cpp" line="167"/>
-+ <source>Save color table to: %1</source>
-+ <translation type="unfinished"></translation>
-+ </message>
-+ <message>
-+ <location filename="../CApp.cpp" line="203"/>
-+ <source>Failed to create target file.</source>
-+ <translation type="unfinished"></translation>
-+ </message>
-+ <message>
-+ <location filename="../CApp.cpp" line="214"/>
-+ <source>Dither source file to target file</source>
-+ <translation type="unfinished"></translation>
-+ </message>
-+ <message>
-+ <location filename="../CApp.cpp" line="225"/>
-+ <source>Failed to dither file.</source>
-+ <translation type="unfinished"></translation>
-+ </message>
-+ <message>
-+ <location filename="../CApp.cpp" line="240"/>
-+ <source>Apply alpha channel as no data value to target file</source>
-+ <translation type="unfinished"></translation>
-+ </message>
-+ <message>
-+ <location filename="../CApp.cpp" line="247"/>
-+ <source>Failed to read from alpha channel.</source>
-+ <translation type="unfinished"></translation>
-+ </message>
-+ <message>
-+ <location filename="../CApp.cpp" line="253"/>
-+ <source>Failed to read from target file.</source>
-+ <translation type="unfinished"></translation>
-+ </message>
-+ <message>
-+ <location filename="../CApp.cpp" line="267"/>
-+ <source>Failed to write to target file.</source>
-+ <translation type="unfinished"></translation>
-+ </message>
-+</context>
-+<context>
-+ <name>main</name>
-+ <message>
-+ <location filename="../main.cpp" line="96"/>
-+ <source>
-+Convert a map file with RGBA color coding to a color palette coding.</source>
-+ <translation type="unfinished"></translation>
-+ </message>
-+ <message>
-+ <location filename="../main.cpp" line="99"/>
-+ <source>Source file.</source>
-+ <translation type="unfinished"></translation>
-+ </message>
-+ <message>
-+ <location filename="../main.cpp" line="100"/>
-+ <source>Target file.</source>
-+ <translation type="unfinished"></translation>
-+ </message>
-+ <message>
-+ <location filename="../main.cpp" line="104"/>
-+ <source>Number of colors. (default: 255)</source>
-+ <translation type="unfinished"></translation>
-+ </message>
-+ <message>
-+ <location filename="../main.cpp" line="107"/>
-+ <source>Input palette file for color table (*.vrt)</source>
-+ <translation type="unfinished"></translation>
-+ </message>
-+ <message>
-+ <location filename="../main.cpp" line="110"/>
-+ <source>Save color table to palette file (*.vrt)</source>
-+ <translation type="unfinished"></translation>
-+ </message>
-+ <message>
-+ <location filename="../main.cpp" line="120"/>
-+ <source>There must be a source and destination file.</source>
-+ <translation type="unfinished"></translation>
-+ </message>
-+ <message>
-+ <location filename="../main.cpp" line="143"/>
-+ <source>--ncolors must be an integer value less than 256</source>
-+ <translation type="unfinished"></translation>
-+ </message>
-+</context>
-+</TS>
-diff --git a/src/qmt_rgb2pct/locale/qmt_rgb2pct_de.ts b/src/qmt_rgb2pct/locale/qmt_rgb2pct_de.ts
-new file mode 100644
-index 00000000..9622b8d9
---- /dev/null
-+++ b/src/qmt_rgb2pct/locale/qmt_rgb2pct_de.ts
-@@ -0,0 +1,127 @@
-+<?xml version="1.0" encoding="utf-8"?>
-+<!DOCTYPE TS>
-+<TS version="2.1" language="de_DE">
-+<context>
-+ <name>CApp</name>
-+ <message>
-+ <location filename="../CApp.cpp" line="63"/>
-+ <source>Failed to open source file.</source>
-+ <translation>Konnte Quelldatei nicht öffnen.</translation>
-+ </message>
-+ <message>
-+ <location filename="../CApp.cpp" line="68"/>
-+ <source>Raster band count of source file must be either 3 or 4.</source>
-+ <translation>Die Anzahl der Rasterbänder muss entweder 3 oder 4 sein.</translation>
-+ </message>
-+ <message>
-+ <location filename="../CApp.cpp" line="101"/>
-+ <source>Calculate optimal color table from source file</source>
-+ <translation>Berechne die optimale Farbtabelle für die Quelldatei</translation>
-+ </message>
-+ <message>
-+ <location filename="../CApp.cpp" line="115"/>
-+ <source>Failed to create color table.</source>
-+ <translation>Konnte die Farbtabelle nicht erstellen.</translation>
-+ </message>
-+ <message>
-+ <location filename="../CApp.cpp" line="123"/>
-+ <source>Failed to open file with palette.</source>
-+ <translation>Konnte die Datei mit der Palette nicht öffnen.</translation>
-+ </message>
-+ <message>
-+ <location filename="../CApp.cpp" line="131"/>
-+ <source>Palette file does not have a single band with a color table</source>
-+ <translation>Die Datei mit der Palette hat kein einzelnes Band mit einer Farbtabelle</translation>
-+ </message>
-+ <message>
-+ <location filename="../CApp.cpp" line="140"/>
-+ <source>The color table must not contain a &quot;no data&quot; value and it&apos;s size must not exceed 255 colors.</source>
-+ <translation>Die Farbtabelle darf keinen Eintrag für &quot;no data&quot; haben und ihre Größe darf nicht 255 Farben überschreiten.</translation>
-+ </message>
-+ <message>
-+ <location filename="../CApp.cpp" line="167"/>
-+ <source>Save color table to: %1</source>
-+ <translation>Speichere Farbtabelle in: %1</translation>
-+ </message>
-+ <message>
-+ <location filename="../CApp.cpp" line="203"/>
-+ <source>Failed to create target file.</source>
-+ <translation>Konnte Zieldatei nicht erstellen.</translation>
-+ </message>
-+ <message>
-+ <location filename="../CApp.cpp" line="214"/>
-+ <source>Dither source file to target file</source>
-+ <translation>Wandle Quelldatei in Zieldatei um</translation>
-+ </message>
-+ <message>
-+ <location filename="../CApp.cpp" line="225"/>
-+ <source>Failed to dither file.</source>
-+ <translation>Konnte die Datei nicht umwandeln.</translation>
-+ </message>
-+ <message>
-+ <location filename="../CApp.cpp" line="240"/>
-+ <source>Apply alpha channel as no data value to target file</source>
-+ <translation>Wandle für die Zieldatei den Alphakanal in &quot;no data&quot; Werte um </translation>
-+ </message>
-+ <message>
-+ <location filename="../CApp.cpp" line="247"/>
-+ <source>Failed to read from alpha channel.</source>
-+ <translation>Konnte den Alphakanal nicht lesen.</translation>
-+ </message>
-+ <message>
-+ <location filename="../CApp.cpp" line="253"/>
-+ <source>Failed to read from target file.</source>
-+ <translation>Konnte die Zieldatei nicht lesen.</translation>
-+ </message>
-+ <message>
-+ <location filename="../CApp.cpp" line="267"/>
-+ <source>Failed to write to target file.</source>
-+ <translation>Konnte die Zieldatei nicht schreiben.</translation>
-+ </message>
-+</context>
-+<context>
-+ <name>main</name>
-+ <message>
-+ <location filename="../main.cpp" line="96"/>
-+ <source>
-+Convert a map file with RGBA color coding to a color palette coding.</source>
-+ <translation>
-+Konvertiert eine Kartendatei mit RGBA Farbschema in eine Kartendatei mit Farbtabelle.</translation>
-+ </message>
-+ <message>
-+ <location filename="../main.cpp" line="99"/>
-+ <source>Source file.</source>
-+ <translation>Quelldatei.</translation>
-+ </message>
-+ <message>
-+ <location filename="../main.cpp" line="100"/>
-+ <source>Target file.</source>
-+ <translation>Zieldatei.</translation>
-+ </message>
-+ <message>
-+ <location filename="../main.cpp" line="104"/>
-+ <source>Number of colors. (default: 255)</source>
-+ <translation>Anzahl an Farben (Vorgabe: 255)</translation>
-+ </message>
-+ <message>
-+ <location filename="../main.cpp" line="107"/>
-+ <source>Input palette file for color table (*.vrt)</source>
-+ <translation>Datei mit Palette als Vorgabe für die Farbtabelle (*.vrt) </translation>
-+ </message>
-+ <message>
-+ <location filename="../main.cpp" line="110"/>
-+ <source>Save color table to palette file (*.vrt)</source>
-+ <translation>Farbtabelle in Datei mit Palette sichern (*.vrt)</translation>
-+ </message>
-+ <message>
-+ <location filename="../main.cpp" line="120"/>
-+ <source>There must be a source and destination file.</source>
-+ <translation>Es muss eine Quell- und eine Zieldatei angegeben werden.</translation>
-+ </message>
-+ <message>
-+ <location filename="../main.cpp" line="143"/>
-+ <source>--ncolors must be an integer value less than 256</source>
-+ <translation>--ncolors muss eine ganze Zahl kleiner 256 sein</translation>
-+ </message>
-+</context>
-+</TS>
-diff --git a/src/qmt_rgb2pct/main.cpp b/src/qmt_rgb2pct/main.cpp
-new file mode 100644
-index 00000000..4ff9a9ae
---- /dev/null
-+++ b/src/qmt_rgb2pct/main.cpp
-@@ -0,0 +1,155 @@
-+/**********************************************************************************************
-+ Copyright (C) 2018 Oliver Eichler oliver.eichler@gmx.de
-+
-+ This program is free software: you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation, either version 3 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 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 <http://www.gnu.org/licenses/>.
-+
-+**********************************************************************************************/
-+
-+#include "CApp.h"
-+#include "version.h"
-+#include <QtCore>
-+
-+#ifdef Q_OS_MACOS
-+static QDir getApplicationDir(QString subdir)
-+{
-+ QDir appDir(QCoreApplication::applicationDirPath());
-+ appDir.cdUp();
-+ appDir.cd(subdir);
-+ return appDir;
-+}
-+#endif
-+static void prepareTranslator(QString translationPath, QString translationPrefix)
-+{
-+ QString locale = QLocale::system().name();
-+ QDir dir(translationPath);
-+ if(!QFile::exists(dir.absoluteFilePath(translationPrefix + locale)))
-+ {
-+ locale = locale.left(2);
-+ }
-+
-+ QCoreApplication* app = (QCoreApplication*) QCoreApplication::instance();
-+ QTranslator *qtTranslator = new QTranslator(app);
-+
-+ if (qtTranslator->load(translationPrefix + locale, translationPath))
-+ {
-+ app->installTranslator(qtTranslator);
-+ }
-+}
-+
-+static void loadTranslations()
-+{
-+#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(__FreeBSD_kernel__) || defined(__GNU__) || defined(Q_OS_CYGWIN)
-+ QString resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
-+ QString translationPath = QCoreApplication::applicationDirPath();
-+ translationPath.replace(QRegExp("bin$"), "share/" APP_STR "/translations");
-+ prepareTranslator(resourceDir, "qt_");
-+ prepareTranslator(translationPath, APP_STR "_");
-+#endif
-+
-+#ifdef Q_OS_OSX
-+ // os x
-+ static QString relTranslationDir = "Resources/translations"; // app
-+ QString translationPath = getApplicationDir(relTranslationDir).absolutePath();
-+ prepareTranslator(translationPath, "qt_");
-+ prepareTranslator(translationPath, APP_STR "_");
-+#endif
-+
-+#ifdef Q_OS_WIN
-+ QString apppath = QCoreApplication::applicationDirPath();
-+ apppath = apppath.replace("/", "\\");
-+ QString appResourceDir = QString("%1\\translations").arg(apppath).toUtf8();
-+ prepareTranslator(appResourceDir, "qtbase_");
-+ prepareTranslator(appResourceDir, APP_STR "_");
-+#endif
-+
-+}
-+
-+int main(int argc, char ** argv)
-+{
-+ QCoreApplication app(argc, argv);
-+ QCoreApplication::setApplicationName(APP_STR);
-+ QCoreApplication::setApplicationVersion(VER_STR);
-+ if(QString(VER_SUFFIX).isEmpty())
-+ {
-+ QCoreApplication::setApplicationVersion(VER_STR);
-+ }
-+ else
-+ {
-+ QCoreApplication::setApplicationVersion(VER_STR "." VER_SUFFIX);
-+ }
-+
-+
-+ loadTranslations();
-+
-+ QCommandLineParser parser;
-+ parser.setApplicationDescription(QCoreApplication::translate("main", "\nConvert a map file with RGBA color coding to a color palette coding."));
-+ parser.addHelpOption();
-+ parser.addVersionOption();
-+ parser.addPositionalArgument("source", QCoreApplication::translate("main", "Source file."));
-+ parser.addPositionalArgument("target", QCoreApplication::translate("main", "Target file."));
-+
-+ parser.addOptions({
-+ {
-+ {"n","ncolors"}, QCoreApplication::translate("main", "Number of colors. (default: 255)"), "number", "255"
-+ },
-+ {
-+ {"p","pct"}, QCoreApplication::translate("main", "Input palette file for color table (*.vrt)"), "filename", ""
-+ },
-+ {
-+ {"s","sct"}, QCoreApplication::translate("main", "Save color table to palette file (*.vrt)"), "filename", ""
-+ },
-+ });
-+
-+ // Process the actual command line arguments given by the user
-+ parser.process(app);
-+
-+ if(parser.positionalArguments().count() == 1 && parser.value("sct").isEmpty())
-+ {
-+ printStderrQString("");
-+ printStderrQString(QCoreApplication::translate("main","There must be a source and destination file."));
-+ printStderrQString("");
-+ parser.showHelp(-1);
-+ }
-+
-+ if(parser.positionalArguments().isEmpty())
-+ {
-+ parser.showHelp(-1);
-+ }
-+
-+ QString srcFilename = parser.positionalArguments()[0];
-+ QString tarFilename;
-+ if(parser.positionalArguments().count() > 1)
-+ {
-+ tarFilename = parser.positionalArguments()[1];
-+ }
-+
-+
-+ bool ok = false;
-+ const qint32 ncolors = parser.value("ncolors").toInt(&ok);
-+ if(!ok || ncolors > 255)
-+ {
-+ printStderrQString("");
-+ printStderrQString(QCoreApplication::translate("main","--ncolors must be an integer value less than 256"));
-+ printStderrQString("");
-+ parser.showHelp(-1);
-+ }
-+
-+ QString pctFilename = parser.value("pct");
-+ QString sctFilename = parser.value("sct");
-+
-+ CApp theApp(ncolors, pctFilename, sctFilename, srcFilename, tarFilename);
-+ return theApp.exec();
-+}
-+
-+
-diff --git a/src/qmt_rgb2pct/version.h b/src/qmt_rgb2pct/version.h
-new file mode 100644
-index 00000000..60f94f71
---- /dev/null
-+++ b/src/qmt_rgb2pct/version.h
-@@ -0,0 +1,33 @@
-+/**********************************************************************************************
-+ Copyright (C) 2017 Oliver Eichler oliver.eichler@gmx.de
-+
-+ This program is free software: you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation, either version 3 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 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 <http://www.gnu.org/licenses/>.
-+
-+**********************************************************************************************/
-+
-+#ifndef VERSION_H
-+#define VERSION_H
-+
-+#ifndef _MKSTR_1
-+#define _MKSTR_1(x) #x
-+#define _MKSTR(x) _MKSTR_1(x)
-+#endif
-+
-+#define VER_STR _MKSTR(VER_MAJOR) "." _MKSTR (VER_MINOR) "." _MKSTR (VER_STEP)
-+#define VER_SUFFIX _MKSTR(VER_TWEAK)
-+#define APP_STR _MKSTR(APPLICATION_NAME)
-+#define WHAT_STR _MKSTR(APPLICATION_NAME) ", Version " VER_STR
-+
-+#endif //VERSION_H
-+