# *************************************************************** #
# PerlSub                                                         #
# -------                                                         #
# Author : Mahlon R. Smith - The Software Samurai                 #
# Copyright (c) 2026-2027 Mahlon R. Smith, The Software Samurai   #
#                    - - - - - - - - - -                          #
# Developed under: Perl v:5.40.3                                  #
#                  libheif v:1.19.8                               #
# *************************************************************** #
# Copyright Notice:                                               #
# -----------------                                               #
# 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.            #
#                <http://www.gnu.org/licenses/>.                  #
# *************************************************************** #
# This package includes two simple Perl scripts which demonstrate #
# the use of subroutines in Perl.                                 #
#                                                                 #
# 'subtest.pl'                                                    #
# ------------                                                    #
# This simple program demonstrates the use of "call-by-reference" #
# versus "call-by-value" parameters.                              #
#                                                                 #
# 'heic.pl'                                                       #
# ---------                                                       #
# This is a more complex example which demonstrates the various   #
# ways Perl subroutines can be built and invoked.                 #
# The code itself is constructed as a front-end for the           #
# third-party utility program, "heif-dec" (heif-decode), which    #
# converts Apple(tm) HEIC-encoded images to other image formats.  #
# The Perl source demonstrates subroutine access even without the #
# external utility; however, for full functionality, "heif-dec"   #
# should be installed on the target system.                       #
# See below for additional information.                           #
#                                                                 #
# 'create_archive.pl'                                             #
# -------------------                                             #
# Also included is an example utility script used for creating    #
# distribution archives. This kind of utility ensures that        #
# every time you update your distro package, it contains exactly  #
# the same files. This utility script was created specifically    #
# for this package, but the program structure and function can    #
# be easily adapted for any set of source files regardless of     #
# the complexity of the source tree. Another useful feature is    #
# that it extracts a copy of the distro version number from       #
# the source data which is then incorporated into the name of     #
# the archive file.                                               #
#                    - - - - - - - - - -                          #
#                                                                 #
# Unpack the Archive:                                             #
# -------------------                                             #
# 1) Navigate to the base directory where package will be         #
#    installed (example):                                         #
#       cd ~/Software                                             #
# 2) Move the archive file to the base directory:                 #
#       mv ~/Dowloads/perlsub-0.0.01.tar.bz2 &nbsp; ./.           #
# 3) Unpack the tar archive:                                      #
#       tar -xjvf perlsub-0.0.01.tar.bz2</span></li>              #
# 4) Navigate to the target directory:                            #
#       cd PerlSub                                                #
# 5) Check the version of the Perl compiler currently installed   #
#    on the system:                                               #
#       perl --version                                            #
#    If the installed version is earlier that v:5.36, then an     #
#    upgrade is strongly recommended.                             #
#                    - - - - - - - - - -                          #
# Package Contents:                                               #
# -----------------                                               #
# subtest.pl         - Perl scripts demonstrating subroutine calls#
# heic.pl                                                         #
# Image_01.heic      - Sample images, (not under copyright)       #
# Image_02.heic                                                   #
# Image_03.heic                                                   #
# README             - Release notes (this file)                  #
# /install           - Subdirectory                               #
#  create_archive.pl - Perl script example for creating archives  #
#                                                                 #
# Image Source: https://heic.digital/samples/                     #
#               https://filesamples.com/formats/heic              #
#                    - - - - - - - - - -                          #
# To access the utility from any current-working-directory (CWD), #
# do one of the following:                                        #
# 1) Copy the Perl script to a directory on the execution path.   #
#       cp --preserve=all ./heic.pl ~/bin/.                       #
# 2) Create a symlink in a directory on the execution path.       #
#       cp --symbolic-link ./heic.pl ~/bin/heiconv                #
# 3) Create a shell script to reference the Perl script.          #
#       #!/bin/bash                                               #
#       ~/SoftwareDesign/heic/heic.pl $1 $2 $3 $4 $5 $6 $7 $8     #
#     Save to a convenient name (example: 'heiconv')              #
#     (Be sure to set the shell script as executable.)            #
#       chmod +x heiconv                                          #
#                                                                 #
# *************************************************************** #
# heic.pl Command Line Options:                                   #
# -----------------------------                                   #
# Usage: heic.pl SOURCE_FILE [TARGET_FILE] [OPTIONS]              #
#                                                                 #
# An option which does not begin with a dash ('-') character      #
# is assumed to be a filename.                                    #
#                                                                 #
# Source File Name(s) (required)                                  #
# ------------------------------                                  #
#   Filename of a High-Efficiency-Image-Container (HEIC-encoded)  #
#   file located in the current working directory (CWD).          #
#   Source file(s) may be specified in exactly one of three ways: #
#   1) as the first argument:                                     #
#        heic.pl Orange.heic                                      #
#   2) '-src' switch (in any argument position)                   #
#        heic.pl -e=png -src=Orange.heic                          #
#   3) '-all' option:                                             #
#      Used to specify that all HEIC-encoded files in the CWD     #
#      are to be processed.                                       #
#        heic.pl -all -e=jpeg -q=75                               #
#      -- Note that if the '-all' option is used, then any        #
#         individual source or target filenames specified will    #
#         be ignored.                                             #
#                                                                 #
# Target File Name (optional)                                     #
# ---------------------------                                     #
#   Name of target file, optionally including a filename          #
#   extension indicating the target encoding.                     #
#   The target filename may be specified in either of two ways:   #
#   1) as the second argument (following the source filename):    #
#        heic.pl Orange.heic Tangerine.png                        #
#   2) Using the '-trg' switch (in any argument position):        #
#        heic.pl -src=Orange.heic -q=80 -trg=Tangerine.jpg        #
#                                                                 #
#   a) If no target filename specified, the target takes the base #
#      name of the source file(s) and the filename extension is   #
#      taken from the '-e' option if specified, else default      #
#      extension/encoding (jpg) is used. Examples:                #
#        heic.pl Orange.heic                   yields: Orange.jpg #
#        heic.pl Orange.heic -e=png            yields: Orange.png #
#   b) If a target filename is specified with no filename         #
#      extension, the extension/encoding is taken from the        #
#      '-e' option, if specified, else the default extension      #
#      and encoding are used. Examples:                           #
#        heic.pl Orange.heic Grape             yields: Grape.jpg  #
#        heic.pl Orange.heic -e=tif -trg=Grape yields: Grape.tif  #
#   c) If target is specified with filename extension (target     #
#      encoding), the extension will be compared against the list #
#      of supported extensions/encodings. Examples:               #
#        heic.pl Orange.heic Grape.png         yields: Grape.png  #
#        heic.pl Orange.heic -trg=Grape.tif    yields: Grape.tif  #
#        heic.pl Orange.heic Grape.xyz         yields: ERROR!     #
#   d) If both filename and '-e' option specified, then the '-e'  #
#      option overrides target filename extension. Example:       #
#        heic.pl Orange.heic Grape.tif -e=png  yields: Grape.png  #
#   e) If the '-all' (all source) option is used, then the        #
#      target filename(s) will be be constructed from the source  #
#      filenames, and the individual target specification will be #
#      ignored; however, if an encoding was specified, it will be #
#      retained unless overridden by a subsequent '-e' option.    #
#        heic.pl -all -trg=Grape.tif                              #
#           yields: Orange.tif Apple.tif Grape.tif etc.           #
#        heic.pl -all -trg=Grape.tif -e=png                       #
#           yields: Orange.png Apple.png Grape.png etc.           #
#                                                                 #
# -e=ENCODING (optional)                                          #
# ----------------------                                          #
# Specifies target encoding AND target filename extension,        #
# (case insensitive). Do not include a leading '.' character.     #
# If specified, the '-e' option overrides the target filename     #
# extension (if any).                                             #
# Encoding Options: jpg (default), jpeg, tif, tiff, png, y4m      #
#                   (See below for details.)                      #
# Example: heic.pl Orange.heic -e=png                             #
#                                                                 #
# -q=QUALITY (optional)                                           #
# ---------------------                                           #
# For JPEG ('lossy') compression only, specify the encoding       #
# quality (integer percentage of image data retained).            #
#   minimum percentage:  10                                       #
#   default percentage:  92                                       #
#   maximum percentage: 100                                       #
# The '-q' option does not apply to lossless encoding formats     #
# (PNG, TIF, Y4M).                                                #
#                                                                 #
# -v Verbose Output (optional)                                    #
# ----------------------------                                    #
# By default, the intermediate results and any warning messages   #
# produced by the 'heif-dec' application are silently discarded.  #
# If verbose output is specified, however, then the invocation    #
# command used to call 'heif-dec' as well as the interim results  #
# of the conversion process will be reported.                     #
#                                                                 #
# --version (optional)                                            #
# --------------------                                            #
# Display application version number and copyright information,   #
# then exit. This option overrides all other arguments.           #
#                                                                 #
# --help[less] or -h[l] (optional)                                #
# --------------------------------                                #
# Display a list of command line options, then exit. This option  #
# overrides all other arguments _except_ '--version'.             #
#   a) The '--help' or '-h' option writes the command-line help   #
#      directly to the terminal window.                           #
#   b) The '--helpless' or '-hl' option redirects the             #
#      command-line help through the 'less' utility.              #
#                                                                 #
# *************************************************************** #
# HEIC Encoding and the 'heif-dec' image conversion utility:      #
# ----------------------------------------------------------      #
# High Efficiency Image Container encoding was developed by the   #
# Movig Picture Experts Group (MPEG), ISO/IEC 23008-12.           #
# The first major player to adopt this encoding was Apple(tm)     #
# with iOS-11.                                                    #
# HEIC encoding (.heic extension) is now the default iPhone image #
# format. It is technically efficient, but at this time, we       #
# aren’t sure whether we want to pollute our Linux systems with   #
# this image format.                                              #
# Fortunately, the 'heif-dec' utility converts a file from .heic  #
# format to one of the following formats:                         #
#    JPEG: 'jpg', 'jpeg'  - Joint Photographic Experts Group      #
#    TIFF: 'tif', 'tiff'  - Tag Image File Format                 #
#          'png'          - Portable Network Graphics             #
#          'y4m'          - YUV4MPEG2 (uncompressed)              #
#                           Y4M is a lossless encoding used       #
#                           primarily for testing codecs.         #
#                              (the output is HUGE!)              #
#                                                                 #
# The source file contains a magic-number sequence in the header: #
# 1) "ftypmif1" generic version of HEIC encoding.                 #
# 2) "ftypheic" indicates the specific codec used for encoding.   #
# 3) "ftypheix" indicates a "compatible" codec used for encoding  #
#                                                                 #
# The 'heif-dec' utility (Copyright © 2017 struktur AG) is        #
# distributed as part of the 'libheif-tools' package.             #
# To install that package, see the following (or visit GitHub).   #
#                                                                 #
# - The "documentation" for 'heif-dec' can be accessed as:        #
#     info heif-dec                                               #
#   This single-page document can claim to be documentation ONLY  #
#   because the info reader can read it, and not because it       #
#   actually documents anything.                                  #
# - The command-line help indicates support for the above target  #
#   image formats; however, the documentation does not include    #
#   any mention of the 'tif/tiff' encoding, presumably because    #
#   the document has not been updated since 2017.                 #
# - The 'heif-convert' utility is a legacy version of the same    #
#   tool, but is deprecated in newer environments. It appears     #
#   that 'heif-convert' is now simply a backward-compatibility    #
#   symlink to 'heif-dec'.                                        #
# - The likely reason that the utility is so simple is that the   #
#   algorithm is intended primarily for integration into other    #
#   tools, and that the stand-alone version is simply a reference #
#   model. (The authors may dispute this evaluation.)             #
# - Note that 'heif-dec' will silently overwrite existing         #
#   targets; however, the 'heic.pl' utility does not allow such   #
#   amateur-hour functionality.                                   #
# - The 'heif-dec' utility ignores the case of the specified      #
#   encoding, and always writes the target filename extension     #
#   in lowercase.                                                 #
# - Note that 'heif-dec' offers several command-line options      #
#   for image tweaking.                                           #
#   - The most interesting of these options (from our point of    #
#     view) is the '--png-compression-level #' option. This       #
#     option is designed to specify the speed (not the quality)   #
#     of the conversion to PNG encoding. In another context, e.g. #
#     dynamic conversion by a web browser, this might be useful,  #
#     but it seems to be a trivial option in the current context. #
#   The heic.pl demonstration program ignores these options       #
#   because implementing them would tend to obscure the primary   #
#   value of this example code, which is to describe the various  #
#   ways in which Perl subroutines can be constructed and called. #
# - The libheif package is available on GitHub or through         #
#    RPM Fusion.                                                  #
#                    - - - - - - - - - -                          #
#    If your system is not yet set up for 'rpmfusion', first      #
#    enable it, then:                                             #
#       sudo dnf install libheif-tools libheif-freeworld          #
#          or                                                     #
#       sudo apt update && sudo apt install libheif-examples      #
#                                                                 #
# *************************************************************** #
# subtest.pl Command Line Options:                                #
# --------------------------------                                #
# Usage: subtest.pl [ -a | -p=WIDTH ]                             #
#                                                                 #
# -- If called without parameters, execute the first three tests: #
#     subtest1 - Anonymous, by-reference:                         #
#        call: subtest1 ( $data ) ;                               #
#        ref : print "$_[0]" ;                                    #
#                                                                 #
#     subtest2 - Named, by-value:                                 #
#        call: subtest2 ( $data ) ;                               #
#        ref : print "$data" ;                                    #
#                                                                 #
#     subtest3 - Named, by-reference:                             #
#        call: subtest3 ( \$data ) ;                              #
#        ref : print "$$data" ;                                   #
#                                                                 #
# -- If called with: subtest.pl -a          ('A' is for Array)    #
#    execute the fourth test: subtest4().                         #
#     subtest4 - Anonymous, by-reference, (locally aliased):      #
#        call: subtest4 ( \@data ) ;                              #
#        ref : my ($arrayPtr) = @_ ;                              #
#              print "$arrayPtr->[$indx]" ;                       #
#                                                                 #
# -- If called with: subtest.pl -p=WIDTH    ('P' is for Padding)  #
#    execute the string padding test where WIDTH is an integer    #
#    value in the range: 18 <= WIDTH <= 120.                      #
#    If the specified value is out of range, then value will      #
#    brought within range. If invoked without a value, then the   #
#    default value (36) will be used.                             #
#     padTest - Named, by-value:                                  #
#        call: padTest ( $trgWidth ) ;                            #
#        ref : print "$trgWidth" ;                                #
#                                                                 #
# *************************************************************** #
# Tech Notes:                                                     #
# -----------                                                     #
# The functionality available in any Perl script depends heavily  #
# upon the version of Perl installed and the modules loaded.      #
# This script uses the standard modules available by default      #
# for the version currently installed.                            #
# The version used for development of this project is: v5.40.4    #
# The pragma used at the top of the file is: "use v5.40"          #
#                                                                 #
# Calling subroutines: (v5.36+)                                   #
# -----------------------------                                   #
# 1) Unnamed parameters are pass-by-reference:                    #
#    ($_[0] is an alias for caller's variable).                   #
#    When subroutine changes the contents of pass-by-reference,   #
#    then caller's data has been changed.                         #
#    my $Apple = "original data" ;                                #
#    PolishApple ( $Apple ) ;                                     #
#    print "$Apple" ;  yields "new data"                          #
#                                                                 #
#    sub PolishApple                                              #
#    { $_[0] = "new data" ; }                                     #
#                                                                 #
# 2) Named parameters are pass-by-value:                          #
#    ($a is a copy of caller's variable)                          #
#                                                                 #
#    my $Apple = "original data" ;                                #
#    PolishApple ( $Apple ) ;                                     #
#    print "$Apple" ;  yields "original data"                     #
#                                                                 #
#    sub PolishApple ( $a )                                       #
#    { $a = "new data" ; }                                        #
#                                                                 #
# 3) Named pass-by-reference parameters:                          #
#    Perl syntax does not yet support named pass-by-reference;    #
#    however, there is kludgy work-around:                        #
#    ($a is an alias for caller's variable).                      #
#                                                                 #
#    my $Apple = "original data" ;                                #
#    PolishApple ( \$Apple ) ;                                    #
#    print "$Apple" ;  yields "new data"                          #
#                                                                 #
#    sub PolishApple ( $a )                                       #
#    { $$a = "new data" ; }                                       #
#                                                                 #
# 4) Perl experimental modules (v:5.36) provide for a similar     #
#    syntax for pass-by-reference which affects only the          #
#    subroutine itself.                                           #
#    (\$a is an alias for caller's variable).                     #
#    This experimental pragma is not used in heic.pl.             #
#                                                                 #
#    use experimental 'refaliasing', 'signatures' ;               #
#    my $Apple = "original data" ;                                #
#    PolishApple ( $Apple ) ;                                     #
#    print "$Apple" ;  yields "new data"                          #
#                                                                 #
#    sub PolishApple ( \$a )                                      #
#    { $a = "new data" ; }                                        #
#                                                                 #
# 5) Passing an  array to a subroutine:                           #
#    Because most Perl variables are handled as arrays, even if   #
#    the array contains only one element or one scalar value,     #
#    passing an array to a subroutine by reference is actually    #
#    more straight-forward than non-array parameters.             #
#    my @FruitBowl = ("Apple", "Orange",                          #
#                     "Pear", "Peach", "Kumquat");                #
#    FruitSaladA ( @FruitBowl ) ;                                 #
#    FruitSaladB ( \@FruitBowl ) ;                                #
#    FruitSaladC ( \@FruitBowl ) ;                                #
#    FruitSaladD ( \@FruitBowl ) ;                                #
#                                                                 #
#    sub FruitSaladA                                              #
#    { my $buff = @_[1] ; }                                       #
#    sub FruitSaladB ( $fPtr )                                    #
#    { my $buff = $fPtr->[1] ; }                                  #
#    sub FruitSaladC ( @fArray )                                  #
#    { my $buff = $fArray[0][1] ; }                               #
#    sub FruitSaladD ( @fArray )                                  #
#    { my $fPtr = @fArray[0] ; my $buff = $fPtr->[1] ; }          #
#                                                                 #
#    For further details, please study the examples in subtest.pl,#
#    or review the release notes posted on the website.           #
#                                                                 #
# *************************************************************** #
