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 "no data" value and it'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 "no data" value and it's size must not exceed 255 colors.</source>
+ <translation>Die Farbtabelle darf keinen Eintrag für "no data" 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 "no data" 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
+
|