#!/usr/bin/env bash
#
#  Part of kf5-servicemenus-imagetools
#  Copyright (c) 2021-2024 by Marco Nelles <dev at maniatek dot de>
#  (derived from kde-service-menu-reimage Version 2.5, Copyright (C) 2018-2019 Giuseppe Benigno <giuseppe.benigno(at)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 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/>.
#

readonly PROGNAME="$(basename "$0")"

function help() {

    case $1 in
        en_US | *)

            echo "Image tool collection for KDE service menus.

Usage: ${PROGNAME} \$command --

Commands:
    help, -h, --help
        Show this help text

    convert <\$format|custom>
        Convert the image to the desired format. A complete list
        can be obtained with: \"mogrify -list format\".

    resize <\$percent|\$pixel|custom>
        Resize image file. Give scale factor in percentage or
        the maximum size in pixel for the longer edge. Values
        can be e.g. \"50%\" or \"1920px\".
    rotate <\$angle|auto>
        Rotate the image by the desired angle in degree. Postive
        values rotate to the right, negative values to the left.
        Values can be e.g. \"90\" or \"-90\".
    mirror <flip|flop>
        Mirror image. flip: mirror in the vertical axis, flop:
        mirror in the horizontal axis.

    jpeg_make_progressive
        Encode JPEG progressive
    jpeg_prepare_to_publish <\$y>
        Reduce JPEG to \$y pixels on the longer side,
        reencode JPEG with quality value 70% (lossy) and
        remove all unnecessary metadata (strip)
    jpeg_reencode <\$percent|custom>
        Reencode JPEG with new quality value
    jpeg_optimize_lossless
        Optimize file size of JPEG without changing image data

    png_optimize
        Optimize PNG encoding (lossless)
    png_recompress_lossy_small
        Recompress for minimal file size (lossy)

    strip
        Remove all unnecessary metadata

    gen_icon
        generate icon (format PNG, size: 360x360px)
    gen_icon_rectangle
        generate icon (format PNG, size: 440x360px)
    gen_favicon
        generate favicon

    gen_optimized_text_img
        generate optimized text image

Examples:
    ${PROGNAME} jpeg_reencode 50% /path/to/image1.jpg
    ${PROGNAME} resize 1920px /path/to/image1.jpg
    ${PROGNAME} resize custom /path/to/image1.jpg
"

        ;;

    esac

}

## language

function load_lang() {

    case $1 in
        en_US | *)

            msg_common_dependency_check_failed_title="Dependency check failed"
            msg_common_kdialog_not_found_text="kdialog not found. Assuming KDE environment."
            msg_common_imagemagick_not_found_text="ImageMagick not found."
            msg_common_cjpegli_not_found_text="cjpegli not found."
            msg_common_exiftool_not_found_text="ExifTool not found."
            msg_common_optipng_not_found_text="OptiPNG not found."
            msg_common_pngquant_not_found_text="pngquant not found."
            msg_common_jpegotim_not_found_text="Jpegotim not found."
            msg_common_qdbus_not_found_text="Qdbus not found."


            msg_common_abort="Operation interrupted by user."
            msg_common_overwrite_text="Do you want to overwrite the original file(s)? Otherwise a new file with a filename suffix will be created."
            msg_common_overwrite_yes="YES, OVERWRITE"
            msg_common_overwrite_no="No, create new files"
            msg_common_progress_text="Processing file \$i of \$file_count \(\$basename_file\)"
            msg_common_start="Starting."
            msg_common_error="An error has occurred."
            msg_common_file_not_found="File \$basename_file not found."
            msg_common_command_not_found_text="The requested command \$command is not implemented."
            msg_common_cancel="Cancel"

            msg_convert_title="Conversion of images"
            msg_convert_format_text="Type the format you want.\nA complete list can be obtained from the shell with: mogrify -list format\nor by consulting the ImageMagick manual."

            msg_resize_title="Resizing of images"
            msg_resize_scale_text="Type the scale factor in percentage or the maximum size in pixel you want for the longer edge.\nValid values can be: 50% or 1920px:"

            msg_rotate_title="Rotation of images"
            msg_rotate_angle_text="Enter the desired rotation angle in degree:"

            msg_mirror_title="Mirroring of images"

            msg_jpeg_make_progressive_title="Make jpeg files progressive"

            msg_jpeg_prepare_to_publish_title="Prepare jpegs for publishing"
            msg_jpeg_prepare_to_publish_title_scale_text="Type the width in px for the longer side:"

            msg_jpeg_reencode_title="Reencoding of jpegs"
            msg_jpeg_reencode_quality_text="Type the quality in percent:"

            msg_jpeg_optimize_lossless_title="Optimize file size lossless"

            msg_png_optimize_title="Optimizing of png files"
            msg_png_recompress_lossy_small="Recompression of png files"

            msg_strip_title="Striping of metadata from images"

            msg_gen_icon_title="Generating icon from images"

            msg_gen_icon_rectangle_title="Generating icon from images"

            msg_gen_favicon_title="Generating favicon from images"

            msg_gen_optimized_text_img_title="Generate optimized text image from image"

            ;;
    esac

}

load_lang ${LANGUAGE%%:*}

## Check dependencies

kdialog_bin=$(which kdialog)
if [ -z "${kdialog_bin}" ]; then
    echo "${msg_common_kdialog_not_found_text}"
    exit 2
fi

mogrify_bin=$(which mogrify)
if [ -z "${mogrify_bin}" ]; then
    "${kdialog_bin}" --icon configure --title "${msg_common_dependency_check_failed_title}" --error "${msg_common_imagemagick_not_found_text}"
    exit 2
fi

convert_bin=$(which convert)
if [ -z "${convert_bin}" ]; then
    "${kdialog_bin}" --icon configure --title "${msg_common_dependency_check_failed_title}" --error "${msg_common_imagemagick_not_found_text}"
    exit 2
fi

cjpegli_bin=$(which cjpegli)
if [ -z "${cjpegli_bin}" ]; then
    "${kdialog_bin}" --icon configure --title "${msg_common_dependency_check_failed_title}" --error "${msg_common_cjpegli_not_found_text}"
    exit 2
fi

exiftool_bin=$(which exiftool)
if [ -z "${exiftool_bin}" ]; then
    "${kdialog_bin}" --icon configure --title "${msg_common_dependency_check_failed_title}" --error "${msg_common_exiftool_not_found_text}"
    exit 2
fi

optipng_bin=$(which optipng)
if [ -z "${optipng_bin}" ]; then
    "${kdialog_bin}" --icon configure --title "${msg_common_dependency_check_failed_title}" --error "${msg_common_optipng_not_found_text}"
    exit 2
fi

pngquant_bin=$(which pngquant)
if [ -z "${pngquant_bin}" ]; then
    "${kdialog_bin}" --icon configure --title "${msg_common_dependency_check_failed_title}" --error "${msg_common_pngquant_not_found_text}"
    exit 2
fi

jpegoptim_bin=$(which jpegoptim)
if [ -z "${jpegoptim_bin}" ]; then
    "${kdialog_bin}" --icon configure --title "${msg_common_dependency_check_failed_title}" --error "${msg_common_jpegotim_not_found_text}"
    exit 2
fi

qdbus_bin=$(which qdbus 2>/dev/null)
if [ -z "${qdbus_bin}" ]; then
    qdbus_bin=$(which qdbus6)
    if [ -z "${qdbus_bin}" ]; then
        "${kdialog_bin}" --icon configure --title "${msg_common_dependency_check_failed_title}" --error "${msg_common_qdbus_not_found_text}"
        exit 2
    fi
fi

cjxl_bin=$(which cjxl)

## exec functions

exec_convert() {

    local inputfile="$1"
    local format="$FORMAT"

    local dir
    dir=$(dirname -- "${inputfile}")
    local name="${inputfile##*/}"
    local base="${name%.*}"
    local ext="${name##*.}"

    if [ "${ext}" != "${format}" ]; then
        if [ "${format}" == jxl ] && [ ! -z "${cjxl_bin}" ]; then
            OUTPUT=$("${cjxl_bin}" "${inputfile}" "${dir}/${base}.${format}" 2>&1)
        else
            OUTPUT=$("${mogrify_bin}" -format "${format}" "${inputfile}" 2>&1)
        fi
    fi

    return $?

}

exec_resize() {

    local inputfile="$1"
    local scale_factor="$SCALE_FACTOR"

    local dir
    dir=$(dirname -- "${inputfile}")
    local name="${inputfile##*/}"
    local base="${name%.*}"
    local ext="${name##*.}"

    if [ "${scale_factor: -1}" == "%" ]; then
        if [ "${overwrite}" = true ]; then
            OUTPUT=$("${mogrify_bin}" -resize "${scale_factor}" "${inputfile}" 2>&1)
        else
            OUTPUT=$("${convert_bin}" -resize "${scale_factor}" "${inputfile}" "${dir}/${base}_resized_${scale_factor}.${ext}" 2>&1)
        fi
    elif [ "${scale_factor: -2}" == "px" ]; then
        scale_factor=${scale_factor::-2}
        if [ "${overwrite}" = true ]; then
            OUTPUT=$("${mogrify_bin}" -resize "${scale_factor}x${scale_factor}>" "${inputfile}" 2>&1)
        else
            OUTPUT=$("${convert_bin}" -resize "${scale_factor}x${scale_factor}>" "${inputfile}" "${dir}/${base}_resized_${scale_factor}p.${ext}" 2>&1)
        fi
    fi

    return $?

}

exec_rotate() {

    local inputfile="$1"
    local angle="$ANGLE"

    local dir
    dir=$(dirname -- "${inputfile}")
    local name="${inputfile##*/}"
    local base="${name%.*}"
    local ext="${name##*.}"

    if [ "${overwrite}" = true ]; then
        if [ "${angle}" = "auto" ]; then
            OUTPUT=$("${mogrify_bin}" -auto-orient "${inputfile}" 2>&1)
        else
            OUTPUT=$("${mogrify_bin}" -rotate "${angle}" "${inputfile}" 2>&1)
        fi
    else
        if [ "${angle}" = "auto" ]; then
            OUTPUT=$("${convert_bin}" -auto-orient "${inputfile}" "${dir}/${base}_rotated_${angle}°.${ext}" 2>&1)
        else
            OUTPUT=$("${convert_bin}" -rotate "${angle}" "${inputfile}" "${dir}/${base}_rotated_${angle}°.${ext}" 2>&1)
        fi
    fi

    return $?

}

exec_mirror() {

    local inputfile="$1"
    local mirrordirection="$MIRRORDIRECTION"

    local dir
    dir=$(dirname -- "${inputfile}")
    local name="${inputfile##*/}"
    local base="${name%.*}"
    local ext="${name##*.}"

    if [ "${overwrite}" = true ]; then
        OUTPUT=$("${mogrify_bin}" -"${mirrordirection}" "${inputfile}" 2>&1)
    else
        OUTPUT=$("${convert_bin}" -"${mirrordirection}" "${inputfile}" "${dir}/${base}_${mirrordirection}.${ext}" 2>&1)
    fi

    return $?

}

exec_jpeg_reencode() {

    local inputfile="$1"
    local quality="$JPEG_QUALITY"

    local dir
    dir=$(dirname -- "${inputfile}")
    local name="${inputfile##*/}"
    local base="${name%.*}"
    local ext="${name##*.}"

    OUTPUT=$("${cjpegli_bin}" -q ${quality} "${inputfile}" "${dir}/${base}_reencoded-${quality}.${ext}" 2>&1)

    if [ "${overwrite}" = true ] && [ $? -eq 0 ]; then
        rm "${inputfile}"
        mv "${dir}/${base}_reencoded-${quality}.${ext}" "${inputfile}"
    fi

    return $?
}

exec_jpeg_prepare_to_publish() {

    local inputfile="$1"
    local width="$WIDTH"

    local dir
    dir=$(dirname -- "${inputfile}")
    local name="${inputfile##*/}"
    local base="${name%.*}"
    local ext="${name##*.}"

    local tmpfile
    tmpfile=$(mktemp -p "${dir}" --suffix=".${ext}")

    OUTPUT=$("${convert_bin}" -resize "${width}x${width}>" "${inputfile}" "${tmpfile}" 2>&1)
    rc=$?
    if [ $rc -ne 0 ]; then
        rm "${tmpfile}"
        return $rc
    fi

    local tmpfile2
    tmpfile2=$(mktemp -p "${dir}" --suffix=".${ext}")

    OUTPUT=$("${cjpegli_bin}" -q 70 "${tmpfile}" "${tmpfile2}" 2>&1)
    rc=$?
    if [ $rc -ne 0 ]; then
        rm "${tmpfile}"
        rm "${tmpfile2}"
        return $rc
    fi
    rm "${tmpfile}"

    OUTPUT=$("${exiftool_bin}" -all= -overwrite_original -r "${tmpfile2}" 2>&1)
    rc=$?
    if [ $rc -ne 0 ]; then
        rm "${tmpfile2}"
        return $rc
    fi

    if [ "${overwrite}" = true ]; then
        rm "${inputfile}"
        mv "${tmpfile2}" "${inputfile}"
    else
        mv "${tmpfile2}" "${dir}/${base}_to_publish.${ext}"
    fi

    return 0

}

exec_jpeg_make_progressive() {

    local inputfile="$1"

    local dir
    dir=$(dirname -- "${inputfile}")
    local name="${inputfile##*/}"
    local base="${name%.*}"
    local ext="${name##*.}"

    if [ "${overwrite}" = true ]; then
        OUTPUT=$("${mogrify_bin}" -strip -interlace Plane "${inputfile}" 2>&1)
    else
        OUTPUT=$("${convert_bin}" -strip -interlace Plane "${inputfile}" "${dir}/${base}_progressive.${ext}" 2>&1)
    fi

    return $?

}

exec_jpeg_optimize_lossless() {

    local inputfile="$1"

    local dir
    dir=$(dirname -- "${inputfile}")
    local name="${inputfile##*/}"
    local base="${name%.*}"
    local ext="${name##*.}"

    if [ "${overwrite}" = true ]; then
        OUTPUT=$("${jpegoptim_bin}" "${inputfile}" 2>&1)
    else
        local tmpfile
        tmpfile=$(mktemp -p "${dir}" --suffix=".${ext}")
        cp "${inputfile}" "${tmpfile}"
        OUTPUT=$("${jpegoptim_bin}" "${tmpfile}" 2>&1)
        mv "${tmpfile}" "${dir}/${base}_optimized.${ext}"
    fi

    return $?

}

exec_png_optimize() {

    local inputfile="$1"

    local dir
    dir=$(dirname -- "${inputfile}")
    local name="${inputfile##*/}"
    local base="${name%.*}"
    local ext="${name##*.}"

    if [ "${overwrite}" = true ]; then
        OUTPUT=$("${optipng_bin}" "${inputfile}" 2>&1)
    else
        OUTPUT=$("${optipng_bin}" -out "${dir}/${base}_optimized.${ext}" "${inputfile}" 2>&1)
    fi

    return $?

}

exec_png_recompress_lossy_small() {

    local inputfile="$1"

    local dir
    dir=$(dirname -- "${inputfile}")
    local name="${inputfile##*/}"
    local base="${name%.*}"
    local ext="${name##*.}"

    if [ "${overwrite}" = true ]; then
        OUTPUT=$("${pngquant_bin}" "${inputfile}" 2>&1)
    else
        OUTPUT=$("${pngquant_bin}" --output "${dir}/${base}_recompressed.${ext}" "${inputfile}" 2>&1)
    fi

    return $?

}

exec_strip() {

    local inputfile="$1"

    OUTPUT=$("${exiftool_bin}" -all= -overwrite_original -r "${inputfile}" 2>&1)

    return $?

}

exec_gen_icon() {

    local inputfile="$1"

    local dir
    dir=$(dirname -- "${inputfile}")
    local name="${inputfile##*/}"
    local base="${name%.*}"
    local ext="${name##*.}"

    OUTPUT=$("${convert_bin}" -format png -resize 288x288 -gravity center -background white -extent 360x360 "${inputfile}" "${dir}/${base}_icon.png" 2>&1)
    rc=$?
    if [ $rc -ne 0 ]; then
        return $rc
    fi

    OUTPUT=$("${optipng_bin}" "${dir}/${base}_icon.png" 2>&1)

    return $?

}

exec_gen_icon_rectangle() {

    local inputfile="$1"

    local dir
    dir=$(dirname -- "${inputfile}")
    local name="${inputfile##*/}"
    local base="${name%.*}"
    local ext="${name##*.}"

    OUTPUT=$("${convert_bin}" -format png -resize 352x288 -gravity center -background white -extent 440x360 "${inputfile}" "${dir}/${base}_icon.png" 2>&1)
    rc=$?
    if [ $rc -ne 0 ]; then
        return $rc
    fi

    OUTPUT=$("${optipng_bin}" "${dir}/${base}_icon.png" 2>&1)

    return $?

}

exec_gen_favicon() {

    local inputfile="$1"

    local dir
    dir=$(dirname -- "${inputfile}")
    local name="${inputfile##*/}"
    local base="${name%.*}"
    local ext="${name##*.}"

    local wxh
    wxh=$(${convert_bin} "${inputfile}" -format "%w x %h" info:)
    local w=${wxh%% *}
    local h=${wxh##* }
    local max=$((w > h ? w : h))

    local tmpfile
    tmpfile=$(mktemp -p "${dir}" --suffix=".png")

    OUTPUT=$("${convert_bin}" -background transparent -compose Copy -gravity center -extent ${max}x${max} "${inputfile}" "${tmpfile}" 2>&1)
    rc=$?
    if [ $rc -ne 0 ]; then
        rm "${tmpfile}"
        return $rc
    fi

    OUTPUT=$("${convert_bin}" -define icon:auto-resize=64,48,32,16 "${tmpfile}" "${dir}/${base}_favicon.ico" 2>&1)
    rc=$?
    if [ $rc -ne 0 ]; then
        rm "${tmpfile}"
        return $rc
    fi

    rm "${tmpfile}"

    return 0

}

# https://gist.github.com/lelandbatey/8677901
exec_gen_optimized_text_img() {

    local inputfile="$1"

    local dir
    dir=$(dirname -- "${inputfile}")
    local name="${inputfile##*/}"
    local base="${name%.*}"
    local ext="${name##*.}"

    OUTPUT=$("${convert_bin}" -format png -morphology Convolve DoG:15,100,0 -negate -normalize -blur 0x1 -channel RBG -depth 2 -level 60%,91%,0.1 "${inputfile}" "${dir}/${base}_optimized_txt.png" 2>&1)
    rc=$?
    if [ $rc -ne 0 ]; then
        return $rc
    fi

    OUTPUT=$("${optipng_bin}" "${dir}/${base}_optimized_txt.png" 2>&1)

    return $?

}

overwrite_question() {

    "${kdialog_bin}" --icon configure --title "${msg_title}" --dontagain servicemenus-imagetools:nooverwritemsg --warningyesno "${msg_common_overwrite_text}" --yes-label "${msg_common_overwrite_no}" --no-label "${msg_common_overwrite_yes}"
    rc=$?

    if [ $rc -eq 1 ]; then
        overwrite=true
    else
        if [ $rc -eq 0 ]; then
            overwrite=false
        else
            {
                "${kdialog_bin}" --title "${msg_title}" --passivepopup "${msg_common_abort}" 5
                exit 2
            }
        fi
    fi

}

iterate_files() {

    if [ "${flag_ask_overwrite}" = true ]; then
        overwrite_question
    fi

    file_count=$#
    dbus_ref=$(${kdialog_bin} --icon configure --title "${msg_title}" --progressbar "${msg_common_start}" $file_count)
    ${qdbus_bin} $dbus_ref org.kde.kdialog.ProgressDialog.showCancelButton true
    i=1

    while [ "$(${qdbus_bin} $dbus_ref org.kde.kdialog.ProgressDialog.wasCancelled 2>/dev/null)" = "false" ] && (( i <= file_count )); do

        local file="${!i}"
        local basename_file
        basename_file="$(basename "$file")"

        if [ ! -f "${file}" ]; then
            "${kdialog_bin}" --title --icon configure "${msg_title}" --error "$(eval echo "${msg_common_file_not_found}")"
            break
        fi
        ${qdbus_bin} $dbus_ref org.kde.kdialog.ProgressDialog.setLabelText "$(eval echo "${msg_common_progress_text}")"

        case $command in
        convert)
            exec_convert "${file}"
            ;;
        resize)
            exec_resize "${file}"
            ;;
        rotate)
            exec_rotate "${file}"
            ;;
        mirror)
            exec_mirror "${file}"
            ;;
        jpeg_make_progressive)
            exec_jpeg_make_progressive "${file}"
            ;;
        jpeg_prepare_to_publish)
            exec_jpeg_prepare_to_publish "${file}"
            ;;
        jpeg_reencode)
            exec_jpeg_reencode "${file}"
            ;;
        jpeg_optimize_lossless)
            exec_jpeg_optimize_lossless "${file}"
            ;;
        png_optimize)
            exec_png_optimize "${file}"
            ;;
        png_recompress_lossy_small)
            exec_png_recompress_lossy_small "${file}"
            ;;
        strip)
            exec_strip "${file}"
            ;;
        gen_icon)
            exec_gen_icon "${file}"
            ;;
        gen_icon_rectangle)
            exec_gen_icon_rectangle "${file}"
            ;;
        gen_favicon)
            exec_gen_favicon "${file}"
            ;;
        gen_optimized_text_img)
            exec_gen_optimized_text_img "${file}"
            ;;
        esac

        rc=$?
        if [ $rc -ne 0 ]; then
            {
                ${qdbus_bin} $dbus_ref close
                "${kdialog_bin}" --icon configure --title "${msg_title}" --detailederror "${msg_common_error}" "${OUTPUT}"
                exit 2
            }
        fi

        ${qdbus_bin} $dbus_ref org.freedesktop.DBus.Properties.Set org.kde.kdialog.ProgressDialog value $i

        ((i++))

    done

    ${qdbus_bin} $dbus_ref close 2>/dev/null

}

## init functions

init_convert() {

    value="${1}"
    shift

    FORMAT="png"
    if [ "${value}" = "custom" ]; then
        FORMAT=$("${kdialog_bin}" --icon configure --title "${msg_title}" --inputbox "${msg_convert_format_text}") ||
            { "${kdialog_bin}" --title "${msg_title}" --passivepopup "${msg_common_cancel}" 5 && exit 2; }
    else
        FORMAT="${value}"
    fi

    iterate_files "${@}"

}

init_resize() {

    value="${1}"
    shift

    SCALE_FACTOR="50%"
    if [ "${value}" = "custom" ]; then
        SCALE_FACTOR=$("${kdialog_bin}" --icon configure --title "${msg_title}" --inputbox "${msg_resize_scale_text}") ||
            { "${kdialog_bin}" --title "${msg_title}" --passivepopup "${msg_common_cancel}" 5 && exit 2; }
    else
        SCALE_FACTOR="${value}"
    fi

    flag_ask_overwrite=true
    iterate_files "${@}"

}

init_rotate() {

    value="${1}"
    shift

    ANGLE="90"
    if [ "${value}" = "custom" ]; then
        ANGLE=$("${kdialog_bin}" --icon configure --title "${msg_title}" --inputbox "${msg_rotate_angle_text}") ||
            { "${kdialog_bin}" --title "${msg_title}" --passivepopup "${msg_common_cancel}" 5 && exit 2; }
    else
        ANGLE="${value}"
    fi

    flag_ask_overwrite=true
    iterate_files "${@}"

}

init_mirror() {

    value="${1}"
    shift

    MIRRORDIRECTION="${value}"

    flag_ask_overwrite=true
    iterate_files "${@}"

}

init_jpeg_reencode() {

    value="${1}"
    shift

    JPEG_QUALITY="70"
    if [ "${value}" = "custom" ]; then
        JPEG_QUALITY=$("${kdialog_bin}" --icon configure --title "${msg_title}" --inputbox "${msg_jpeg_reencode_quality_text}" "${JPEG_QUALITY}") ||
            { "${kdialog_bin}" --title "${msg_title}" --passivepopup "${msg_common_cancel}" 5 && exit 2; }
    else
        JPEG_QUALITY="${value}"
    fi

    JPEG_QUALITY=${JPEG_QUALITY/%\%/}

    flag_ask_overwrite=true
    iterate_files "${@}"

}

init_jpeg_prepare_to_publish() {

    value="${1}"
    shift

    WIDTH="1920"
    if [ "${value}" = "custom" ]; then
        WIDTH=$("${kdialog_bin}" --icon configure --title "${msg_title}" --inputbox "${msg_jpeg_prepare_to_publish_title_scale_text}" "${WIDTH}") ||
            { "${kdialog_bin}" --title "${msg_title}" --passivepopup "${msg_common_cancel}" 5 && exit 2; }
    else
        WIDTH="${value}"
    fi

    WIDTH=${WIDTH/%px/}
    WIDTH=${WIDTH/%p/}

    flag_ask_overwrite=true
    iterate_files "${@}"

}

init_jpeg_make_progressive() {

    flag_ask_overwrite=true
    iterate_files "${@}"

}

init_jpeg_optimize_lossless() {

    flag_ask_overwrite=true
    iterate_files "${@}"

}

init_png_optimize() {

    flag_ask_overwrite=true
    iterate_files "${@}"

}

init_png_recompress_lossy_small() {

    flag_ask_overwrite=true
    iterate_files "${@}"

}

init_strip() {

    iterate_files "${@}"

}

init_gen_icon() {

    iterate_files "${@}"

}

init_gen_icon_rectangle() {

    iterate_files "${@}"

}

init_gen_favicon() {

    iterate_files "${@}"

}

init_gen_optimized_text_img() {

    iterate_files "${@}"

}

## main part

command="${1}"
shift

flag_ask_overwrite=false

if [ -z "$command" ]; then
    help ${LANGUAGE%%:*}
    exit 0
fi

case $command in
help | -h | --help)
    help
    exit 0
    ;;
convert)
    msg_title="${msg_convert_title}"
    init_convert "${@}"
    ;;
resize)
    msg_title="${msg_resize_title}"
    init_resize "${@}"
    ;;
rotate)
    msg_title="${msg_rotate_title}"
    init_rotate "${@}"
    ;;
mirror)
    msg_title="${msg_mirror_title}"
    init_mirror "${@}"
    ;;
jpeg_make_progressive)
    msg_title="${msg_jpeg_make_progressive_title}"
    init_jpeg_make_progressive "${@}"
    ;;
jpeg_prepare_to_publish)
    msg_title="${msg_jpeg_prepare_to_publish_title}"
    init_jpeg_prepare_to_publish "${@}"
    ;;
jpeg_reencode)
    msg_title="${msg_jpeg_reencode_title}"
    init_jpeg_reencode "${@}"
    ;;
jpeg_optimize_lossless)
    msg_title="${msg_jpeg_optimize_lossless_title}"
    init_jpeg_optimize_lossless "${@}"
    ;;
png_optimize)
    msg_title="${msg_png_optimize_title}"
    init_png_optimize "${@}"
    ;;
png_recompress_lossy_small)
    msg_title="${msg_png_recompress_lossy_small}"
    init_png_recompress_lossy_small "${@}"
    ;;
strip)
    msg_title="${msg_strip_title}"
    init_strip "${@}"
    ;;
gen_icon)
    msg_title="${msg_gen_icon_title}"
    init_gen_icon "${@}"
    ;;
gen_icon_rectangle)
    msg_title="${msg_gen_icon_rectangle_title}"
    init_gen_icon_rectangle "${@}"
    ;;
gen_favicon)
    msg_title="${msg_gen_favicon_title}"
    init_gen_favicon "${@}"
    ;;
gen_optimized_text_img)
    msg_title="${msg_gen_optimized_text_img_title}"
    init_gen_optimized_text_img "${@}"
    ;;
*)
    "${kdialog_bin}" --icon configure --title "${msg_common_dependency_check_failed_title}" --error "$(eval echo "${msg_common_command_not_found_text}")"
    exit 2
    ;;
esac

exit 0
