#!/usr/bin/perl

###########################################################################
#   crengine-ng                                                           #
#   Copyright (C) 2022 Aleksey Chernov <valexlin@gmail.com>               #
#                                                                         #
#   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 2        #
#   of the License, or (at your option) any later version.                #
#                                                                         #
#   This program is distributed in the hope that it will be useful,       #
#   but WITHOUT ANY WARRANTY; without even the implied warranty of        #
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         #
#   GNU General Public License for more details.                          #
#                                                                         #
#   You should have received a copy of the GNU General Public License     #
#   along with this program; if not, write to the Free Software           #
#   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,            #
#   MA 02110-1301, USA.                                                   #
###########################################################################

#
# This program is based on the gammagen.cpp sources and uses its algorithms
# Copyright (C) 2011 Vadim Lopatin <coolreader.org@gmail.com>
#

use 5.022;
use POSIX qw(lround);

use constant GAMMA_LEVELS => (
    0.30, 0.35, 0.40, 0.45, 0.50, 0.55, 0.60, 0.65, 0.70, 0.75, 0.80, 0.85, 0.90, 0.95, 0.98, 1.00,
    1.02, 1.05, 1.10, 1.15, 1.20, 1.25, 1.30, 1.35, 1.40, 1.45, 1.50, 1.60, 1.70, 1.80, 1.90, 2.00,
    2.10, 2.20, 2.30, 2.40, 2.50, 2.60, 2.70, 2.80, 2.90, 3.00, 3.10, 3.20, 3.40, 3.60, 3.80, 4.00
);
use constant GAMMA_LEVELS_SZ => scalar(GAMMA_LEVELS);

sub genTable($$$);

my $out1_filename = "../../src/lvfont/lvgammatbl.h";
my $out2_filename = "../../src/lvfont/lvgammatbl.c";

my $out1fh;
my $out2fh;
if (!open($out1fh, ">", $out1_filename)) {
    print "Cannot create file ${out1_filename}\n";
    exit 1;
}
if (!open($out2fh, ">", $out2_filename)) {
    close($out1fh);
    print "Cannot create file ${out2_filename}\n";
    exit 1;
}

# Make header file...
print $out1fh <<EOF;
// Gamma tables for use with FreeType
// don't edit: this file is generated by crengine/Tools/GammaGen/gammagen.pl
// to rebuild, run perl crengine/Tools/GammaGen/gammagen.pl
//

/***************************************************************************
 *   crengine-ng                                                           *
 *   Copyright (C) 2011 Vadim Lopatin <coolreader.org\@gmail.com>           *
 *   Copyright (C) 2022 Aleksey Chernov <valexlin\@gmail.com>               *
 *                                                                         *
 *   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 2        *
 *   of the License, or (at your option) any later version.                *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the Free Software           *
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,            *
 *   MA 02110-1301, USA.                                                   *
 ***************************************************************************/

#ifndef __LVGAMMATBL_H_INCLUDED__
#define __LVGAMMATBL_H_INCLUDED__

EOF

printf $out1fh ("#define GAMMA_LEVELS              %d\n", GAMMA_LEVELS_SZ);
my $i = 0;
my $no_correction_index = 0;
for (GAMMA_LEVELS) {
    if (abs($_ - 1.0) < 0.0001) {
        $no_correction_index = $i;
        last;
    }
    $i++;
}
printf $out1fh ("#define GAMMA_NO_CORRECTION_INDEX %d\n", $no_correction_index);

print $out1fh <<EOF;

#ifdef __cplusplus
extern "C" {
#endif

struct lvgammatbl_rec
{
    float gamma;
    const unsigned char* table;
};

extern const struct lvgammatbl_rec lvgammatbl_data[];

#ifdef __cplusplus
}
#endif

#endif // __LVGAMMATBL_H_INCLUDED__
EOF

close($out1fh);

# Make implementation file...
print $out2fh <<EOF;
// Gamma tables for use with FreeType
// don't edit: this file is generated by crengine/Tools/GammaGen/gammagen.pl
// to rebuild, run perl crengine/Tools/GammaGen/gammagen.pl
//

/***************************************************************************
 *   crengine-ng                                                           *
 *   Copyright (C) 2011 Vadim Lopatin <coolreader.org\@gmail.com>           *
 *   Copyright (C) 2022 Aleksey Chernov <valexlin\@gmail.com>               *
 *                                                                         *
 *   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 2        *
 *   of the License, or (at your option) any later version.                *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the Free Software           *
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,            *
 *   MA 02110-1301, USA.                                                   *
 ***************************************************************************/

#include "lvgammatbl.h"

// clang-format off

EOF

$i = 0;
for (GAMMA_LEVELS) {
    genTable($out2fh, $_, $i);
    $i++;
}
print $out2fh ("// clang-format on\n\n");
printf $out2fh ("const struct lvgammatbl_rec lvgammatbl_data[GAMMA_LEVELS] = {\n");
$i = 0;
for (GAMMA_LEVELS) {
    if ($i != GAMMA_LEVELS_SZ - 1) {
        printf $out2fh ("    { %.2ff, s_gamma_table_%02d },\n", $_, $i);
    } else {
        printf $out2fh ("    { %.2ff, s_gamma_table_%02d }\n", $_, $i);
    }
    $i++;
}
printf $out2fh ("};\n");

close($out2fh);

# End of main.
1;


# print gamma table for given gamma value & index into file
sub genTable($$$) {
    my ($fh, $gamma, $index) = @_;
    printf $fh ("// gamma=%0.2f\n", $gamma);
    printf $fh ("static const unsigned char s_gamma_table_%02d[256] = {", $index);
    for (my $i = 0; $i < 256; $i++) {
        my $v = (255.0 - $i) / 255.0;
        $v **= $gamma;
        my $n = 255 - lround($v * 255);
        if ($i == 255) {
            printf $fh ("%3d\n", $n);
        } else {
            if ($i % 16 == 0) {
                printf $fh ("\n    ");
            }
            if ($i % 16 != 15) {
                printf $fh ("%3d, ", $n);
            } else {
                printf $fh ("%3d,", $n);
            }
        }
    }
    printf $fh ("};\n\n");
}
