Various improvements
This commit is contained in:
parent
1b93f5d09d
commit
37b80d3624
7 changed files with 474 additions and 83 deletions
57
.vscode/settings.json
vendored
57
.vscode/settings.json
vendored
|
@ -29,6 +29,61 @@
|
||||||
"deque": "cpp",
|
"deque": "cpp",
|
||||||
"__memory": "cpp",
|
"__memory": "cpp",
|
||||||
"locale": "cpp",
|
"locale": "cpp",
|
||||||
"vector": "cpp"
|
"vector": "cpp",
|
||||||
|
"cctype": "cpp",
|
||||||
|
"clocale": "cpp",
|
||||||
|
"cmath": "cpp",
|
||||||
|
"cstdarg": "cpp",
|
||||||
|
"cstddef": "cpp",
|
||||||
|
"cstdio": "cpp",
|
||||||
|
"cstdlib": "cpp",
|
||||||
|
"cstring": "cpp",
|
||||||
|
"ctime": "cpp",
|
||||||
|
"cwchar": "cpp",
|
||||||
|
"cwctype": "cpp",
|
||||||
|
"hash_map": "cpp",
|
||||||
|
"bit": "cpp",
|
||||||
|
"*.tcc": "cpp",
|
||||||
|
"codecvt": "cpp",
|
||||||
|
"compare": "cpp",
|
||||||
|
"complex": "cpp",
|
||||||
|
"concepts": "cpp",
|
||||||
|
"condition_variable": "cpp",
|
||||||
|
"list": "cpp",
|
||||||
|
"map": "cpp",
|
||||||
|
"set": "cpp",
|
||||||
|
"string": "cpp",
|
||||||
|
"unordered_map": "cpp",
|
||||||
|
"exception": "cpp",
|
||||||
|
"iterator": "cpp",
|
||||||
|
"memory": "cpp",
|
||||||
|
"memory_resource": "cpp",
|
||||||
|
"string_view": "cpp",
|
||||||
|
"fstream": "cpp",
|
||||||
|
"initializer_list": "cpp",
|
||||||
|
"iomanip": "cpp",
|
||||||
|
"iostream": "cpp",
|
||||||
|
"istream": "cpp",
|
||||||
|
"mutex": "cpp",
|
||||||
|
"new": "cpp",
|
||||||
|
"ostream": "cpp",
|
||||||
|
"sstream": "cpp",
|
||||||
|
"stdexcept": "cpp",
|
||||||
|
"stop_token": "cpp",
|
||||||
|
"streambuf": "cpp",
|
||||||
|
"thread": "cpp",
|
||||||
|
"cinttypes": "cpp",
|
||||||
|
"typeinfo": "cpp",
|
||||||
|
"variant": "cpp",
|
||||||
|
"__config": "cpp",
|
||||||
|
"__debug": "cpp",
|
||||||
|
"__errc": "cpp",
|
||||||
|
"__hash_table": "cpp",
|
||||||
|
"__locale": "cpp",
|
||||||
|
"__mutex_base": "cpp",
|
||||||
|
"__split_buffer": "cpp",
|
||||||
|
"__threading_support": "cpp",
|
||||||
|
"__tree": "cpp",
|
||||||
|
"__verbose_abort": "cpp"
|
||||||
}
|
}
|
||||||
}
|
}
|
105
bitmapx16.cpp
105
bitmapx16.cpp
|
@ -17,6 +17,7 @@ float BitmapX16::closeness_to_color(PaletteEntry a, PaletteEntry b) {
|
||||||
void BitmapX16::set_bpp(uint8_t bpp) {
|
void BitmapX16::set_bpp(uint8_t bpp) {
|
||||||
this->bpp = bpp;
|
this->bpp = bpp;
|
||||||
quantize_colors = true;
|
quantize_colors = true;
|
||||||
|
operations_pending = true;
|
||||||
}
|
}
|
||||||
uint8_t BitmapX16::get_bpp() const {
|
uint8_t BitmapX16::get_bpp() const {
|
||||||
return bpp;
|
return bpp;
|
||||||
|
@ -27,6 +28,7 @@ void BitmapX16::set_significant(uint8_t value) {
|
||||||
}
|
}
|
||||||
significant_count = value;
|
significant_count = value;
|
||||||
quantize_colors = true;
|
quantize_colors = true;
|
||||||
|
operations_pending = true;
|
||||||
}
|
}
|
||||||
uint8_t BitmapX16::get_significant() const {
|
uint8_t BitmapX16::get_significant() const {
|
||||||
return significant_count;
|
return significant_count;
|
||||||
|
@ -39,6 +41,7 @@ size_t BitmapX16::get_height() const {
|
||||||
}
|
}
|
||||||
void BitmapX16::enable_dithering(bool enabled) {
|
void BitmapX16::enable_dithering(bool enabled) {
|
||||||
dither = enabled;
|
dither = enabled;
|
||||||
|
operations_pending = true;
|
||||||
}
|
}
|
||||||
bool BitmapX16::dithering_enabled() const {
|
bool BitmapX16::dithering_enabled() const {
|
||||||
return dither;
|
return dither;
|
||||||
|
@ -50,6 +53,26 @@ void BitmapX16::resize(size_t w, size_t h) {
|
||||||
void BitmapX16::queue_resize(size_t w, size_t h) {
|
void BitmapX16::queue_resize(size_t w, size_t h) {
|
||||||
tw = w;
|
tw = w;
|
||||||
th = h;
|
th = h;
|
||||||
|
operations_pending = true;
|
||||||
|
}
|
||||||
|
void BitmapX16::apply_operations(BitmapX16Operation operations) {
|
||||||
|
if (operations & BitmapX16Operation::Resize) {
|
||||||
|
if (tw != 0 && th != 0) {
|
||||||
|
resize(tw, th);
|
||||||
|
tw = 0;
|
||||||
|
th = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (operations & BitmapX16Operation::Quantize) {
|
||||||
|
if (significant_count != 0) {
|
||||||
|
image->quantizeColors(significant_count);
|
||||||
|
image->quantizeDither(dither);
|
||||||
|
image->quantize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (operations & BitmapX16Operation::PreparePalette) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void BitmapX16::apply() {
|
void BitmapX16::apply() {
|
||||||
if (tw != 0 && th != 0) {
|
if (tw != 0 && th != 0) {
|
||||||
|
@ -70,6 +93,7 @@ void BitmapX16::apply() {
|
||||||
}
|
}
|
||||||
image->quantize();
|
image->quantize();
|
||||||
generate_palette();
|
generate_palette();
|
||||||
|
operations_pending = false;
|
||||||
}
|
}
|
||||||
uint8_t BitmapX16::extra_to_real_palette(uint8_t idx) {
|
uint8_t BitmapX16::extra_to_real_palette(uint8_t idx) {
|
||||||
return image_palette_count + idx;
|
return image_palette_count + idx;
|
||||||
|
@ -83,7 +107,11 @@ void BitmapX16::write_x16(const char *filename) {
|
||||||
size_t outpixelsize;
|
size_t outpixelsize;
|
||||||
size_t pixelCount;
|
size_t pixelCount;
|
||||||
pixels_per_byte = (8/bpp);
|
pixels_per_byte = (8/bpp);
|
||||||
|
if (operations_pending) {
|
||||||
apply();
|
apply();
|
||||||
|
} else {
|
||||||
|
generate_palette();
|
||||||
|
}
|
||||||
w = image->columns();
|
w = image->columns();
|
||||||
h = image->rows();
|
h = image->rows();
|
||||||
printf("Image size: (%lu, %lu)\n", w, h);
|
printf("Image size: (%lu, %lu)\n", w, h);
|
||||||
|
@ -306,48 +334,47 @@ uint8_t BitmapX16::get_orable_pixel(uint8_t pixelinbyte, uint8_t color) {
|
||||||
BitmapX16::BitmapX16() {
|
BitmapX16::BitmapX16() {
|
||||||
palette_entries = vector<PaletteEntry>();
|
palette_entries = vector<PaletteEntry>();
|
||||||
}
|
}
|
||||||
void BitmapX16::generate_palette() {
|
void BitmapX16::prepare_palette() {
|
||||||
size_t min;
|
size_t max_start;
|
||||||
uint16_t max;
|
uint16_t max_colors;
|
||||||
if (!generate_palette_enabled || !write_palette) {
|
if (!generate_palette_enabled) {
|
||||||
significant_count = write_palette ? palette_entries.size() : 0;
|
max_colors = palette_entries.size();
|
||||||
max = significant_count;
|
} else {
|
||||||
min = 256 - max;
|
max_colors = image->colorMapSize();
|
||||||
if (min >= 16 && write_palette) {
|
|
||||||
significant_start = 16;
|
|
||||||
}
|
}
|
||||||
if (max > 256) max = 256;
|
max_start = 256 - max_colors;
|
||||||
|
if (max_start >= target_palette_start) {
|
||||||
|
significant_start = target_palette_start;
|
||||||
|
} else {
|
||||||
|
significant_start = max_start;
|
||||||
|
}
|
||||||
|
if (max_colors > 256) max_colors = 256;
|
||||||
if (bpp == 0) {
|
if (bpp == 0) {
|
||||||
if (max <= 4) {
|
if (max_colors <= 4) {
|
||||||
bpp = 2;
|
bpp = 2;
|
||||||
} else if (max <= 16) {
|
} else if (max_colors <= 16) {
|
||||||
bpp = 4;
|
bpp = 4;
|
||||||
} else {
|
} else {
|
||||||
bpp = 8;
|
bpp = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
if (generate_palette_enabled) {
|
||||||
}
|
|
||||||
max = (uint16_t)image->colorMapSize();
|
|
||||||
if (max > 256) max = 256;
|
|
||||||
if (bpp == 0) {
|
|
||||||
if (max <= 4) {
|
|
||||||
bpp = 2;
|
|
||||||
} else if (max <= 16) {
|
|
||||||
bpp = 4;
|
|
||||||
} else {
|
|
||||||
bpp = 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
min = 256 - (1 << bpp);
|
|
||||||
if (min >= 16) {
|
|
||||||
significant_start = 16;
|
|
||||||
}
|
|
||||||
if (significant_count == 0) {
|
if (significant_count == 0) {
|
||||||
significant_count = max;
|
significant_count = max_colors;
|
||||||
}
|
}
|
||||||
bitmask = (1 << bpp) - 1;
|
}
|
||||||
image_palette_count = max;
|
image_palette_count = max_colors;
|
||||||
|
if (debug & DebugShowSignificant) {
|
||||||
|
uint16_t significant_end = significant_start + significant_count;
|
||||||
|
uint16_t image_end = significant_start + image_palette_count;
|
||||||
|
printf("Significant: %u-%u, %u entries\n", significant_start, significant_end, significant_count);
|
||||||
|
printf("Image: %u-%u, %u entries\n", significant_start, image_end, image_palette_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void BitmapX16::generate_palette() {
|
||||||
|
uint16_t max_colors;
|
||||||
|
prepare_palette();
|
||||||
|
max_colors = image_palette_count;
|
||||||
palette_entries.clear();
|
palette_entries.clear();
|
||||||
for (uint16_t i = 0; i < image_palette_count; i++) {
|
for (uint16_t i = 0; i < image_palette_count; i++) {
|
||||||
ColorRGB map_color = image->colorMap(i);
|
ColorRGB map_color = image->colorMap(i);
|
||||||
|
@ -368,6 +395,7 @@ void BitmapX16::generate_palette() {
|
||||||
}
|
}
|
||||||
uint8_t BitmapX16::add_palette_entry(PaletteEntry entry) {
|
uint8_t BitmapX16::add_palette_entry(PaletteEntry entry) {
|
||||||
extra_palette_entries.push_back(entry);
|
extra_palette_entries.push_back(entry);
|
||||||
|
operations_pending = true;
|
||||||
return (uint8_t)(extra_palette_entries.size() - 1);
|
return (uint8_t)(extra_palette_entries.size() - 1);
|
||||||
}
|
}
|
||||||
uint8_t BitmapX16::color_to_palette_entry(const ColorRGB &rgb) {
|
uint8_t BitmapX16::color_to_palette_entry(const ColorRGB &rgb) {
|
||||||
|
@ -377,7 +405,7 @@ uint8_t BitmapX16::color_to_palette_entry(const ColorRGB &rgb) {
|
||||||
if (debug & DebugShowCloseness) {
|
if (debug & DebugShowCloseness) {
|
||||||
printf("Closest color for %s: ", color.to_string().c_str());
|
printf("Closest color for %s: ", color.to_string().c_str());
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < image_palette_count; i++) {
|
for (size_t i = 0; i < image_palette_count && i < (1 << bpp); i++) {
|
||||||
float possibility_closeness = closeness_to_color(palette_entries[i], color);
|
float possibility_closeness = closeness_to_color(palette_entries[i], color);
|
||||||
//printf("Closeness: %f", possibility_closeness);
|
//printf("Closeness: %f", possibility_closeness);
|
||||||
if (possibility_closeness < closeness) {
|
if (possibility_closeness < closeness) {
|
||||||
|
@ -433,19 +461,14 @@ void BitmapX16::set_palette(vector<PaletteEntry> entries) {
|
||||||
palette_entries.shrink_to_fit();
|
palette_entries.shrink_to_fit();
|
||||||
extra_palette_entries.clear();
|
extra_palette_entries.clear();
|
||||||
generate_palette_enabled = false;
|
generate_palette_enabled = false;
|
||||||
image->quantizeColors(entries.size());
|
operations_pending = true;
|
||||||
image->quantizeColorSpace(MagickCore::RGBColorspace);
|
|
||||||
image->colorMapSize(entries.size());
|
|
||||||
for (uint16_t i = 0; i < entries.size(); i++) {
|
|
||||||
image->colorMap(i, entries[i].toColor());
|
|
||||||
}
|
|
||||||
image->quantize();
|
|
||||||
}
|
}
|
||||||
void BitmapX16::enable_palette_generation() {
|
void BitmapX16::enable_palette_generation() {
|
||||||
generate_palette_enabled = true;
|
generate_palette_enabled = true;
|
||||||
|
operations_pending = true;
|
||||||
}
|
}
|
||||||
bool BitmapX16::palette_generation_enabled() const {
|
bool BitmapX16::palette_generation_enabled() const {
|
||||||
return generate_palette_enabled && write_palette;
|
return generate_palette_enabled;
|
||||||
}
|
}
|
||||||
void BitmapX16::read_palette(const char *filename) {
|
void BitmapX16::read_palette(const char *filename) {
|
||||||
size_t fsize = std::filesystem::file_size(filename);
|
size_t fsize = std::filesystem::file_size(filename);
|
||||||
|
|
30
bitmapx16.h
30
bitmapx16.h
|
@ -2,12 +2,22 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <Magick++.h>
|
#include <Magick++.h>
|
||||||
#include "palette.h"
|
#include "palette.h"
|
||||||
|
#include <stdint.h>
|
||||||
using namespace Magick;
|
using namespace Magick;
|
||||||
using std::vector;
|
using std::vector;
|
||||||
enum BitmapX16DebugFlags : int {
|
enum BitmapX16DebugFlags : uint16_t {
|
||||||
DebugNone = 0,
|
DebugNone = 0,
|
||||||
DebugShowPalette = (1 << 0),
|
DebugShowPalette = (1 << 0),
|
||||||
DebugShowCloseness = (1 << 1)
|
DebugShowCloseness = (1 << 1),
|
||||||
|
DebugShowSignificant = (1 << 2),
|
||||||
|
|
||||||
|
};
|
||||||
|
enum BitmapX16Operation : uint16_t {
|
||||||
|
None = 0,
|
||||||
|
Resize = (1 << 0),
|
||||||
|
Quantize = (1 << 1),
|
||||||
|
PreparePalette = (1 << 2),
|
||||||
|
GeneratePalette = (1 << 15),
|
||||||
};
|
};
|
||||||
class BitmapX16 {
|
class BitmapX16 {
|
||||||
/// \brief Bits per pixel of the image
|
/// \brief Bits per pixel of the image
|
||||||
|
@ -26,10 +36,12 @@ class BitmapX16 {
|
||||||
bool quantize_colors = false;
|
bool quantize_colors = false;
|
||||||
/// \brief Enables LZSA compression
|
/// \brief Enables LZSA compression
|
||||||
bool compress = false;
|
bool compress = false;
|
||||||
/// \brief False to set the used palette to 0, and palette start also to 0.
|
/// \brief Whether or not an operation is pending.
|
||||||
bool write_palette = true;
|
bool operations_pending = false;
|
||||||
/// \brief True if the palette should be generated, false if it has been set manually and shouldn't be regenerated.
|
/// \brief True if the palette should be generated, false if it has been set manually and shouldn't be regenerated.
|
||||||
bool generate_palette_enabled = true;
|
bool generate_palette_enabled = true;
|
||||||
|
/// \brief The intended start of the palette.
|
||||||
|
uint8_t target_palette_start = 16;
|
||||||
/// \brief Current width
|
/// \brief Current width
|
||||||
size_t w = 0;
|
size_t w = 0;
|
||||||
/// \brief Current height
|
/// \brief Current height
|
||||||
|
@ -52,10 +64,6 @@ class BitmapX16 {
|
||||||
uint8_t image_palette_count = 0;
|
uint8_t image_palette_count = 0;
|
||||||
/// \brief Generates a palette from the current image
|
/// \brief Generates a palette from the current image
|
||||||
void generate_palette();
|
void generate_palette();
|
||||||
/// \brief Actually resizes the image. User code should call queue_resize then apply
|
|
||||||
/// \param w The width to resize to
|
|
||||||
/// \param h The height to resize to
|
|
||||||
void resize(size_t w, size_t h);
|
|
||||||
/// \brief Gets the pixel index within this image based on X and Y values, as well as the width of the image
|
/// \brief Gets the pixel index within this image based on X and Y values, as well as the width of the image
|
||||||
/// \param x The X value of the pixel
|
/// \param x The X value of the pixel
|
||||||
/// \param y The Y value of the pixel
|
/// \param y The Y value of the pixel
|
||||||
|
@ -83,6 +91,7 @@ class BitmapX16 {
|
||||||
uint8_t color_to_palette_entry(const ColorRGB &rgb);
|
uint8_t color_to_palette_entry(const ColorRGB &rgb);
|
||||||
uint8_t extra_to_real_palette(uint8_t idx);
|
uint8_t extra_to_real_palette(uint8_t idx);
|
||||||
float closeness_to_color(PaletteEntry a, PaletteEntry b);
|
float closeness_to_color(PaletteEntry a, PaletteEntry b);
|
||||||
|
void prepare_palette();
|
||||||
public:
|
public:
|
||||||
vector<PaletteEntry> get_palette() const;
|
vector<PaletteEntry> get_palette() const;
|
||||||
vector<PaletteEntry> get_extra_entries() const;
|
vector<PaletteEntry> get_extra_entries() const;
|
||||||
|
@ -90,6 +99,11 @@ class BitmapX16 {
|
||||||
/// \brief Sets the palette to use
|
/// \brief Sets the palette to use
|
||||||
/// \param entries The entries to replace the existing palette
|
/// \param entries The entries to replace the existing palette
|
||||||
void set_palette(vector<PaletteEntry> entries);
|
void set_palette(vector<PaletteEntry> entries);
|
||||||
|
/// \brief Actually resizes the image. User code should call queue_resize then apply
|
||||||
|
/// \param w The width to resize to
|
||||||
|
/// \param h The height to resize to
|
||||||
|
void resize(size_t w, size_t h);
|
||||||
|
void apply_operations(BitmapX16Operation operations);
|
||||||
/// \brief Enables palette generation after disabling it with set_palette.
|
/// \brief Enables palette generation after disabling it with set_palette.
|
||||||
void enable_palette_generation();
|
void enable_palette_generation();
|
||||||
/// \brief Checks the status of palette generation
|
/// \brief Checks the status of palette generation
|
||||||
|
|
26
main.cpp
26
main.cpp
|
@ -266,6 +266,12 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
if (tbpp == 0) tbpp = 8;
|
if (tbpp == 0) tbpp = 8;
|
||||||
if (tcolorcount == 0) tcolorcount = (1 << tbpp);
|
if (tcolorcount == 0) tcolorcount = (1 << tbpp);
|
||||||
|
if (probe_only) {
|
||||||
|
tw = 0;
|
||||||
|
th = 0;
|
||||||
|
tbpp = 0;
|
||||||
|
tcolorcount = 0;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
BitmapX16 bitmap;
|
BitmapX16 bitmap;
|
||||||
bitmap.enable_compression(compress);
|
bitmap.enable_compression(compress);
|
||||||
|
@ -276,6 +282,11 @@ int main(int argc, char **argv) {
|
||||||
} else {
|
} else {
|
||||||
printf("Loading PC image file '%s' to be converted to the X16 bitmap format...\n", input);
|
printf("Loading PC image file '%s' to be converted to the X16 bitmap format...\n", input);
|
||||||
printf("Using at most %u colors (excluding border color) at %u bpp\n", tcolorcount, tbpp);
|
printf("Using at most %u colors (excluding border color) at %u bpp\n", tcolorcount, tbpp);
|
||||||
|
if (palette_file != NULL) {
|
||||||
|
printf("Using palette file '%s'\n", palette_file);
|
||||||
|
} else {
|
||||||
|
printf("Using generated palette.\n");
|
||||||
|
}
|
||||||
if (bitmap.compression_enabled()) printf("Compression enabled\n");
|
if (bitmap.compression_enabled()) printf("Compression enabled\n");
|
||||||
bitmap.load_pc(input);
|
bitmap.load_pc(input);
|
||||||
}
|
}
|
||||||
|
@ -292,6 +303,21 @@ int main(int argc, char **argv) {
|
||||||
h = bitmap.get_height();
|
h = bitmap.get_height();
|
||||||
uint8_t entry_count = bitmap.get_significant();
|
uint8_t entry_count = bitmap.get_significant();
|
||||||
uint8_t entry_start = bitmap.get_significant_start();
|
uint8_t entry_start = bitmap.get_significant_start();
|
||||||
|
printf("Image BPP: %u\n", tbpp);
|
||||||
|
printf("Image size: (%u, %u)\n", w, h);
|
||||||
|
printf("Palette starts at %u, has %u entries, and ends at %u\n", entry_start, entry_count == 0 ? 256 : entry_count, entry_start + entry_count);
|
||||||
|
printf("Palette:\n");
|
||||||
|
vector<PaletteEntry> entries = bitmap.get_palette();
|
||||||
|
for (size_t i = 0; i < entries.size(); i+=8) {
|
||||||
|
for (size_t j = 0; j < 8; j++) {
|
||||||
|
if (i + j > entries.size()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
printf("[%u] = %s, ", i + j, entries[i + j].to_string().c_str());
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
if (reverse) {
|
if (reverse) {
|
||||||
error_msg_part = "write the file";
|
error_msg_part = "write the file";
|
||||||
|
|
133
output.cpp
Normal file
133
output.cpp
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
#include "output.h"
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
ConsoleOutput::FormatType ConsoleOutput::format_type = ConsoleOutput::Text;
|
||||||
|
std::string ConsoleOutput::CategoryPrefix(Category category) {
|
||||||
|
if (format_type == Text) {
|
||||||
|
switch (category) {
|
||||||
|
case Debug:
|
||||||
|
return "Debug: ";
|
||||||
|
case Warning:
|
||||||
|
return "WARNING: ";
|
||||||
|
case Error:
|
||||||
|
return "ERROR: ";
|
||||||
|
case Info:
|
||||||
|
case None:
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::string output;
|
||||||
|
switch (category) {
|
||||||
|
case Debug:
|
||||||
|
output = "DEBUG";
|
||||||
|
break;
|
||||||
|
case Info:
|
||||||
|
output = "INFO";
|
||||||
|
break;
|
||||||
|
case Warning:
|
||||||
|
output = "WARNING";
|
||||||
|
break;
|
||||||
|
case Error:
|
||||||
|
output = "ERROR";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (format_type == Json) {
|
||||||
|
output = "NONE";
|
||||||
|
} else {
|
||||||
|
output = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (format_type == LogStyle) {
|
||||||
|
output = "[" + output + "] ";
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::string ConsoleOutput::InsertCategoryPrefix(Category category, std::string input) {
|
||||||
|
std::string output = "";
|
||||||
|
std::string categoryPrefix = CategoryPrefix(category);
|
||||||
|
if (format_type == Json) {
|
||||||
|
output = "{\"category\": \"";
|
||||||
|
output += categoryPrefix;
|
||||||
|
output += "\", \"text\": \"";
|
||||||
|
for (size_t i = 0; i < input.length(); i++) {
|
||||||
|
char inChar = input[i];
|
||||||
|
switch (inChar) {
|
||||||
|
case '\"':
|
||||||
|
output += "\\\"";
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
output += "\\n";
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
output += "\\r";
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
output += '\\\\';
|
||||||
|
break;
|
||||||
|
case '/':
|
||||||
|
output += "\\/";
|
||||||
|
break;
|
||||||
|
case '\b':
|
||||||
|
output += "\\b";
|
||||||
|
break;
|
||||||
|
case '\t':
|
||||||
|
output += '\\t';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
output += inChar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output += "\"}";
|
||||||
|
} else {
|
||||||
|
for (size_t i = 0; i < input.length(); i++) {
|
||||||
|
char inChar = input[i];
|
||||||
|
if (inChar == '\n' || (inChar == '\r' && (i + 1 < input.length() && input[i] != '\n'))) {
|
||||||
|
output += "\n";
|
||||||
|
output += categoryPrefix;
|
||||||
|
} else {
|
||||||
|
output += inChar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
void ConsoleOutput::Write(Category category, const char *fmt, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
std::string output = VFormat(fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
output = InsertCategoryPrefix(category, output);
|
||||||
|
printf("%s", output.c_str());
|
||||||
|
}
|
||||||
|
void ConsoleOutput::WriteLn(Category category, const char *fmt, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
std::string output = VFormat(fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
output = InsertCategoryPrefix(category, output);
|
||||||
|
printf("%s", output.c_str());
|
||||||
|
}
|
||||||
|
std::string ConsoleOutput::Format(const char *fmt, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
std::string output = VFormat(fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
std::string ConsoleOutput::VFormat(const char *fmt, va_list args) {
|
||||||
|
size_t len = 0;
|
||||||
|
char *buf = NULL;
|
||||||
|
va_list args_copy;
|
||||||
|
va_copy(args_copy, args);
|
||||||
|
len = vsnprintf(NULL, 0, fmt, args_copy);
|
||||||
|
va_end(args_copy);
|
||||||
|
buf = (char*)malloc(len);
|
||||||
|
va_copy(args_copy, args);
|
||||||
|
len = vsnprintf(buf, len, fmt, args_copy);
|
||||||
|
va_end(args_copy);
|
||||||
|
std::string output(buf);
|
||||||
|
free(buf);
|
||||||
|
return output;
|
||||||
|
}
|
31
output.h
Normal file
31
output.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
class ConsoleOutput;
|
||||||
|
class ConsoleOutput {
|
||||||
|
public:
|
||||||
|
enum FormatType {
|
||||||
|
Text,
|
||||||
|
LogStyle,
|
||||||
|
Json
|
||||||
|
}
|
||||||
|
enum Category {
|
||||||
|
None,
|
||||||
|
Debug,
|
||||||
|
Info,
|
||||||
|
Warning,
|
||||||
|
Error,
|
||||||
|
};
|
||||||
|
static FormatType format_type;
|
||||||
|
static std::string CategoryPrefix(Category category);
|
||||||
|
static std::string InsertCategoryPrefix(Category category, std::string input);
|
||||||
|
static void Write(Category category, const char *fmt, ...);
|
||||||
|
static void WriteLn(Category category, const char *fmt, ...);
|
||||||
|
static std::string Format(const char *fmt, ...);
|
||||||
|
static std::string VFormat(const char *fmt, va_list args);
|
||||||
|
};
|
||||||
|
#define Debug(...) ConsoleOutput::WriteLn(ConsoleOutput::Debug, __VA_ARGS__)
|
||||||
|
#define Info(...) ConsoleOutput::WriteLn(ConsoleOutput::Info, __VA_ARGS__)
|
||||||
|
#define Warning(...) ConsoleOutput::WriteLn(ConsoleOutput::Warning, __VA_ARGS__)
|
||||||
|
#define Error(...) ConsoleOutput::WriteLn(ConsoleOutput::Error, __VA_ARGS__)
|
||||||
|
#define Print(...) ConsoleOutput::Write(ConsoleOutput::None, __VA_ARGS__)
|
||||||
|
#define PrintLn(...) ConsoleOutput::WriteLn(ConsoleOutput::None, __VA_ARGS__)
|
173
test.sh
173
test.sh
|
@ -1,11 +1,21 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
BLACK=0
|
||||||
|
RED=1
|
||||||
|
GREEN=2
|
||||||
|
YELLOW=3
|
||||||
|
BLUE=4
|
||||||
|
MAGENTA=5
|
||||||
|
CYAN=6
|
||||||
|
WHITE=7
|
||||||
|
GRAY=8
|
||||||
|
DEFAULT=9
|
||||||
bool_true() {
|
bool_true() {
|
||||||
[ "$1" = "true" ] 2>/dev/null || [ "$1" -ne 0 ] 2>/dev/null
|
[ "$1" = "true" ] 2>/dev/null || [ "$1" -ne 0 ] 2>/dev/null
|
||||||
[ $? -ne 0 ] # Convert $? to 1 or 0 value
|
[ $? -eq 0 ] # Convert $? to 1 or 0 value
|
||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
bool_false() {
|
bool_false() {
|
||||||
! bool_true
|
! bool_true "$1"
|
||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
cmd_avail() {
|
cmd_avail() {
|
||||||
|
@ -14,15 +24,19 @@ cmd_avail() {
|
||||||
tests=0
|
tests=0
|
||||||
failed=0
|
failed=0
|
||||||
succeeded=0
|
succeeded=0
|
||||||
|
failed_ids=()
|
||||||
color=1
|
color=1
|
||||||
tput_avail=0
|
tput_avail=0
|
||||||
if cmd_avail tput; then
|
if cmd_avail tput; then
|
||||||
tput_avail=1
|
tput_avail=1
|
||||||
fi
|
fi
|
||||||
if bool_true $tput_avail; then
|
if bool_true $tput_avail; then
|
||||||
COLORS=$(tput color 2>/dev/null)
|
COLORS=$(tput colors 2>/dev/null)
|
||||||
if [ $? -eq 0 ] && [ $COLORS -gt 2 ]; then
|
if [ $? -eq 0 ] && [ $COLORS -gt 2 ]; then
|
||||||
color=1
|
color=1
|
||||||
|
if [ $COLORS -lt 8 ]; then
|
||||||
|
GRAY=9
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
color=0
|
color=0
|
||||||
fi
|
fi
|
||||||
|
@ -30,6 +44,7 @@ fi
|
||||||
usage() {
|
usage() {
|
||||||
cat << EOF
|
cat << EOF
|
||||||
$0 usage:
|
$0 usage:
|
||||||
|
-o|--output-dir <output directory>
|
||||||
-p|--use-program <program path>
|
-p|--use-program <program path>
|
||||||
Uses the specified already-compiled binary rather than compiling manually
|
Uses the specified already-compiled binary rather than compiling manually
|
||||||
-i|--input-image <image path>
|
-i|--input-image <image path>
|
||||||
|
@ -58,7 +73,9 @@ $0 usage:
|
||||||
Disables color.
|
Disables color.
|
||||||
-h|--help
|
-h|--help
|
||||||
Shows this message.
|
Shows this message.
|
||||||
|
-O|--reverse-dir <directory for reverse conversion files>
|
||||||
|
Sets the directory for files that have been converted to PNG from BMX
|
||||||
|
No effect when reverse conversion is disabled
|
||||||
EOF
|
EOF
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
@ -80,7 +97,9 @@ enable_dither=1
|
||||||
enable_probe=1
|
enable_probe=1
|
||||||
debug_flags=""
|
debug_flags=""
|
||||||
outdir="testout"
|
outdir="testout"
|
||||||
OPTIONS=$(getopt -o "b:hp:i:r:no:d:p:cCDRS" --long "help,use-program:,input-image:,output-bpp:,resize:,no-defaults,output-dir:,debug:,no-reverse,no-dither,no-compress,palette-file,no-generate-palette,no-probe,color,no-color" -- "$@")
|
reverse_dir_set=0
|
||||||
|
reversedir=""
|
||||||
|
OPTIONS=$(getopt -o "b:hp:i:r:no:d:p:cCDRSO" --long "help,use-program:,input-image:,output-bpp:,resize:,no-defaults,output-dir:,debug:,no-reverse,no-dither,no-compress,palette-file,no-generate-palette,no-probe,color,no-color,reverse-dir" -- "$@")
|
||||||
if [ $? != 0 ]; then
|
if [ $? != 0 ]; then
|
||||||
echo "Getopt error."
|
echo "Getopt error."
|
||||||
usage
|
usage
|
||||||
|
@ -88,6 +107,11 @@ fi
|
||||||
eval set -- "$OPTIONS"
|
eval set -- "$OPTIONS"
|
||||||
while [ -n "$1" ]; do
|
while [ -n "$1" ]; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
|
-O|--reverse-dir)
|
||||||
|
reversedir="$2"
|
||||||
|
reverse_dir_set=1
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
-o|--output-dir)
|
-o|--output-dir)
|
||||||
outdir="$2"
|
outdir="$2"
|
||||||
shift 2
|
shift 2
|
||||||
|
@ -162,15 +186,22 @@ while [ -n "$1" ]; do
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
if [ $generate_palette -ne 0 ]; then
|
if bool_false $reverse_dir_set; then
|
||||||
|
reversedir="$outdir/reverse"
|
||||||
|
fi
|
||||||
|
if bool_true $generate_palette; then
|
||||||
palettes+=""
|
palettes+=""
|
||||||
fi
|
fi
|
||||||
if [ $enable_defaults -ne 0 ]; then
|
if bool_true $enable_defaults; then
|
||||||
images+=("TEST.png" "PACK.png" "CAT.jpg")
|
images+=("TEST.png" "PACK.png" "CAT.jpg")
|
||||||
bpps+=(1 2 4 8)
|
bpps+=(1 2 4 8)
|
||||||
resize+=("8x8" "16x16" "32x32" "64x64" "320x240" "640x480")
|
resize+=("64x64" "320x240" "640x480")
|
||||||
|
palettes+=("DPAL.BIN")
|
||||||
fi
|
fi
|
||||||
if [ $prebuilt -eq 0 ]; then
|
if bool_true $enable_reverse; then
|
||||||
|
mkdir -p $reversedir
|
||||||
|
fi
|
||||||
|
if bool_false $prebuilt; then
|
||||||
meson setup builddir
|
meson setup builddir
|
||||||
meson compile -C builddir || exit $?
|
meson compile -C builddir || exit $?
|
||||||
fi
|
fi
|
||||||
|
@ -201,7 +232,7 @@ setfgcolor() {
|
||||||
if bool_true "$tput_avail"; then
|
if bool_true "$tput_avail"; then
|
||||||
tput setaf "$1"
|
tput setaf "$1"
|
||||||
else
|
else
|
||||||
printf "\033[0;3%sm" "$1"
|
printf "\033[38;5;%sm" "$1"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
setbgcolor() {
|
setbgcolor() {
|
||||||
|
@ -211,7 +242,7 @@ setbgcolor() {
|
||||||
if bool_true "$tput_avail"; then
|
if bool_true "$tput_avail"; then
|
||||||
tput setab "$1"
|
tput setab "$1"
|
||||||
else
|
else
|
||||||
printf "\033[0;4%sm" "$1"
|
printf "\033[48;5;%sm" "$1"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
resetcolor() {
|
resetcolor() {
|
||||||
|
@ -224,6 +255,10 @@ resetcolor() {
|
||||||
printf "\033[0m"
|
printf "\033[0m"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
extension() {
|
||||||
|
len="$(printf "%s" "$1" | sed 's/[^.]*\.[^.]*/./g' | wc -c)"
|
||||||
|
printf "%s" "$1" | cut -d. -f$(($len+1))
|
||||||
|
}
|
||||||
mkdir -p "$outdir"
|
mkdir -p "$outdir"
|
||||||
run() {
|
run() {
|
||||||
converter="$1"
|
converter="$1"
|
||||||
|
@ -234,41 +269,65 @@ run() {
|
||||||
shift
|
shift
|
||||||
reverse="$1"
|
reverse="$1"
|
||||||
shift
|
shift
|
||||||
|
infile_for_id=$(basename $infile)
|
||||||
|
outfile_for_id=$(basename $outfile)
|
||||||
extra_flags_run=()
|
extra_flags_run=()
|
||||||
if [ -n "$reverse" ]; then
|
extra_flags_probe=()
|
||||||
extra_flags_run+=( "$reverse" )
|
if bool_true "$reverse"; then
|
||||||
|
extra_flags_run+=( "-reverse" )
|
||||||
|
else
|
||||||
|
extra_flags_probe+=( "-reverse" )
|
||||||
fi
|
fi
|
||||||
setfgcolor 2
|
id="convert_${infile_for_id}_${outfile_for_id}"
|
||||||
|
if [ -n "$reverse" ]; then
|
||||||
|
id="${id}_reverse"
|
||||||
|
fi
|
||||||
|
setfgcolor $WHITE
|
||||||
bold
|
bold
|
||||||
printf "Running: %s\n" "$converter $* -in $infile -out $outfile"
|
printf "Running test %s\n" "$id"
|
||||||
|
printf "Command: %s\n" "$converter -in $infile -out $outfile ${extra_flags_run[*]} $*"
|
||||||
resetcolor
|
resetcolor
|
||||||
setfgcolor 8
|
setfgcolor $GRAY
|
||||||
tests=$(($tests+1))
|
tests=$(($tests+1))
|
||||||
"$converter" -in "$infile" -out "$outfile" "${extra_flags_run[@]}" "$@"
|
"$converter" -in "$infile" -out "$outfile" "${extra_flags_run[@]}" "$@"
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
setfgcolor 1
|
setfgcolor 1
|
||||||
printf "Test failed.\n"
|
printf "Test $id failed.\n"
|
||||||
resetcolor
|
resetcolor
|
||||||
failed=$(($failed+1))
|
failed=$(($failed+1))
|
||||||
|
failed_ids+=($id)
|
||||||
else
|
else
|
||||||
|
setfgcolor $GREEN
|
||||||
|
printf "Test $id succeeded!\n"
|
||||||
|
resetcolor
|
||||||
succeeded=$(($succeeded+1))
|
succeeded=$(($succeeded+1))
|
||||||
fi
|
fi
|
||||||
resetcolor
|
resetcolor
|
||||||
if [ $enable_probe -ne 0 ]; then
|
if [ $enable_probe -ne 0 ]; then
|
||||||
setfgcolor 2
|
id="probe_${outfile_for_id}"
|
||||||
|
if [ -z "$reverse" ]; then
|
||||||
|
id="${id}_pc"
|
||||||
|
fi
|
||||||
|
setfgcolor $BLUE
|
||||||
bold
|
bold
|
||||||
|
printf "Running test %s\n" "$id"
|
||||||
printf "Probing %s...\n" "$outfile"
|
printf "Probing %s...\n" "$outfile"
|
||||||
resetcolor
|
resetcolor
|
||||||
setfgcolor 8
|
setfgcolor $GRAY
|
||||||
"$converter" -in "$outfile" -probe "${extra_flags_run[@]}"
|
printf "Command: %s\n" "$converter -in $infile -probe ${extra_flags_probe[*]}"
|
||||||
|
"$converter" -in "$outfile" -probe "${extra_flags_probe[@]}"
|
||||||
resetcolor
|
resetcolor
|
||||||
tests=$(($tests+1))
|
tests=$(($tests+1))
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
setfgcolor 1
|
setfgcolor $RED
|
||||||
printf "Test failed.\n"
|
printf "Test $id failed.\n"
|
||||||
resetcolor
|
resetcolor
|
||||||
failed=$(($failed+1))
|
failed=$(($failed+1))
|
||||||
|
failed_ids+=($id)
|
||||||
else
|
else
|
||||||
|
setfgcolor $GREEN
|
||||||
|
printf "Test $id succeeded!\n"
|
||||||
|
resetcolor
|
||||||
succeeded=$(($succeeded+1))
|
succeeded=$(($succeeded+1))
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
@ -280,11 +339,14 @@ for img in "${images[@]}"; do
|
||||||
for palette in "${palettes[@]}"; do
|
for palette in "${palettes[@]}"; do
|
||||||
width="$(echo -n "$size" | cut -dx -f1)"
|
width="$(echo -n "$size" | cut -dx -f1)"
|
||||||
height="$(echo -n "$size" | cut -dx -f2)"
|
height="$(echo -n "$size" | cut -dx -f2)"
|
||||||
name="$(basename "$img" | sed 's/\.png$//' | sed 's/\.jpg$//' | sed 's/\.jpeg$//')"
|
ext="$(extension "$img")"
|
||||||
name="$(printf "%s.%sP.%sB" "$name" "$width" "$bpp")"
|
ext_upper="$(printf "%s" "$ext" | tr '[:lower:]' '[:upper:]')"
|
||||||
|
name="$(basename -s ".$ext" "$img")"
|
||||||
|
name="$(printf "%s.%s.%sPX.%sB" "$name" "$ext_upper" "$width" "$bpp")"
|
||||||
extraflags=()
|
extraflags=()
|
||||||
if [ -n "$palette" ]; then
|
if [ -n "$palette" ]; then
|
||||||
extraflags+=( "-palette-file" "$palette" )
|
extraflags+=( "-palette-file" "$palette" )
|
||||||
|
name+=".PL-$(basename -s ".$(extension "$palette")" "$palette" | tr '[:lower:]' '[:upper]')"
|
||||||
fi
|
fi
|
||||||
if [ -n "$compressflag" ]; then
|
if [ -n "$compressflag" ]; then
|
||||||
if [ $enable_compression -eq 0 ]; then
|
if [ $enable_compression -eq 0 ]; then
|
||||||
|
@ -293,14 +355,14 @@ for img in "${images[@]}"; do
|
||||||
extraflags+=( "$compressflag" )
|
extraflags+=( "$compressflag" )
|
||||||
name+=".C"
|
name+=".C"
|
||||||
fi
|
fi
|
||||||
run "$converter" "$img" "$outdir/$name.BMX" "" "${extraflags[@]}" "" -bpp "$bpp" -resize "$width" "$height" -border 15 0 15 -debug "$debug_flags"
|
run "$converter" "$img" "$outdir/$name.BMX" false "${extraflags[@]}" -bpp "$bpp" -resize "$width" "$height" -border 15 0 15 -debug "$debug_flags"
|
||||||
if [ $enable_dither -ne 0 ]; then
|
if bool_true $enable_dither; then
|
||||||
run "$converter" "$img" "$outdir/$name.D.BMX" "" "${extraflags[@]}" "" -bpp "$bpp" -resize "$width" "$height" -dither -border 15 0 15 -debug "$debug_flags"
|
run "$converter" "$img" "$outdir/$name.D.BMX" false "${extraflags[@]}" -bpp "$bpp" -resize "$width" "$height" -dither -border 15 0 15 -debug "$debug_flags"
|
||||||
fi
|
fi
|
||||||
if [ $enable_reverse -ne 0 ]; then
|
if bool_true $enable_reverse; then
|
||||||
run "$converter" "$outdir/$name.BMX" "$outdir/$name.PNG" -reverse "${extraflags[@]}" -resize "$width" "$height" -debug "$debug_flags"
|
run "$converter" "$outdir/$name.BMX" "$reversedir/$name.PNG" true "${extraflags[@]}" -resize "$width" "$height" -debug "$debug_flags"
|
||||||
if [ $enable_dither -ne 0 ]; then
|
if bool_true $enable_dither; then
|
||||||
run "$converter" "$outdir/$name.D.BMX" "$outdir/$name.D.PNG" -reverse "${extraflags[@]}" -resize "$width" "$height" -dither -debug "$debug_flags"
|
run "$converter" "$outdir/$name.D.BMX" "$reversedir/$name.D.PNG" true "${extraflags[@]}" -resize "$width" "$height" -dither -debug "$debug_flags"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
@ -308,5 +370,52 @@ for img in "${images[@]}"; do
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
printf "%s total test cases, %s failed, %s succeeded, %s%% succeeded and %s%% failed.\n" "$tests" "$failed" "$succeeded" "$((($succeeded*100)/$tests))" "$((($failed*100)/$tests))"
|
badcolor=$RED
|
||||||
|
goodcolor=$GREEN
|
||||||
|
okcolor=$YELLOW
|
||||||
|
success_good=90
|
||||||
|
success_ok=50
|
||||||
|
percent_out_of_tests() {
|
||||||
|
if [ "$tests" -eq 0 ]; then
|
||||||
|
printf "100"
|
||||||
|
else
|
||||||
|
printf "%s" "$((($1*100)/$tests))"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
invert_percent() {
|
||||||
|
printf "%s" "$((100-$1))"
|
||||||
|
}
|
||||||
|
success_percent="$(percent_out_of_tests $succeeded)"
|
||||||
|
failed_percent="$(percent_out_of_tests $failed)"
|
||||||
|
set_color_by_good_percentage() {
|
||||||
|
if [ "$1" -ge $success_good ]; then
|
||||||
|
setfgcolor "$goodcolor"
|
||||||
|
elif [ "$1" -ge $success_ok ]; then
|
||||||
|
setfgcolor "$okcolor"
|
||||||
|
else
|
||||||
|
setfgcolor "$badcolor"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
set_color_by_bad_percentage() {
|
||||||
|
set_color_by_good_percentage "$(invert_percent $1)"
|
||||||
|
}
|
||||||
|
bold
|
||||||
|
setfgcolor $WHITE
|
||||||
|
printf "%s total test cases, " "$tests"
|
||||||
|
set_color_by_bad_percentage "$failed_percent"
|
||||||
|
printf "%s failed (%s%%) " "$failed" "$failed_percent"
|
||||||
|
setfgcolor $WHITE
|
||||||
|
printf "and "
|
||||||
|
set_color_by_good_percentage "$success_percent"
|
||||||
|
printf "%s succeeded (%s%%)." "$succeeded" "$success_percent"
|
||||||
|
resetcolor
|
||||||
|
printf "\n"
|
||||||
|
if [ "$failed" -gt 0 ]; then
|
||||||
|
setfgcolor $RED
|
||||||
|
printf "Failing tests:\n"
|
||||||
|
for test in "${failed_ids[@]}"; do
|
||||||
|
printf "Test '%s'\n"
|
||||||
|
done
|
||||||
|
resetcolor
|
||||||
|
fi
|
||||||
cd "$oldpwd"
|
cd "$oldpwd"
|
||||||
|
|
Loading…
Reference in a new issue