#!/usr/bin/python

# list_different_images.py
#       --copyright--                   Copyright 2013 (C) Tranzoa, Co. All rights reserved.    Warranty: You're free and on your own here. This code is not necessarily up-to-date or of public quality.
#       --url--                         http://www.tranzoa.net/tzpython/
#       --email--                       pycode is the name to send to. tranzoa.com is the place to send to.
#       --bodstamps--
#       May 15, 2013            bar
#       May 16, 2013            bar     sorta handle compare's problem with too-dissimilar images
#       May 17, 2013            bar     flush the output every printout so it's easier to watch progress on a big job
#       April 13, 2014          bar     first file is first file
#       June 9, 2019            bar     allow negative --diff to mean print close images
#       --eodstamps--
##      \file
#       \namespace              tzpython.list_different_images
#
#
#       List images that are sufficiently different from "near"-named images.
#
#

import  re
import  sys

import  tzlib


def do_it(fns, metric, diff, verbose = 0) :

    dissimilar      = False
    v_re            = re.compile(r"(" + tzlib.float_regx_str + ")")
    dfn             = fns[0]
    if  verbose :
        print "%10.1f" % 0,
    print dfn
    for fn in fns[1:] :
        cmd         = 'compare -metric %s "%s" "%s" /dev/null' % ( metric, dfn, fn, )       # note: /dev/null is the output, difference image or something. this program doesn't quit if the files given to it are different sizes or something.
        ( r, rs )   = tzlib.run_program(cmd)
        if  r       :
            if  not dissimilar :                        # have we run the compare program yet? if not, then this is probably a legit failure
                raise IOError("Cannot process %s and %s [%s]!" % ( dfn, fn, rs ) )
            rs      = str(10000000)                     # probably "images too dissimilar"
        else        :
            dissimilar  = True

        g           = v_re.search(rs)
        if  not g   :
            raise ValueError("Cannot find metric for %s and %s [%s]!" % ( dfn, fn, rs ) )

        v           = float(g.group(1))
        if  ((diff >= 0) and (v >= diff)) or ((diff < 0) and (v < -diff)) :
            dfn     = fn
            if  verbose :
                print "%10.1f" % v,
            print dfn
        elif verbose > 1 :
            print "%10.1f" % v,
            print   fn
        sys.stdout.flush()

    pass



help_str    = """
%s (options) image_file_name ambiguous_image_file_name...

    Lists images that differ enough - taken in sorted order.
    Uses ImageMagick the 'compare' program.

Options:

    --diff      difference_cutoff   Differences of this value or more are sufficient. (Default: %f)
                                    If this value is less than zero, print the images
                                       closer than the absolute --diff value.
    --metric    name                ImageMagick 'metric' name                         (Default: %s)
    --verbose                       Increase the verbosity level.

This program lists image files that are sufficiently different from their neighbors in sorted order.

It really runs 'compare -metric %s file1 file2 /dev/null'
and does not list file2 if the output value is below the --diff value.
The first file is always listed.

"""



if  __name__ == '__main__' :

    import  os

    import  TZCommandLineAtFile
    import  tz_os_priority


    program_name    = sys.argv.pop(0)

    TZCommandLineAtFile.expand_at_sign_command_line_files(sys.argv)


    verbose = 0
    metric  = 'mse'
    diff    = 100.0

    while True :
        oi  = tzlib.array_find(sys.argv, [ "--help", "-h", "-?", "/h", "/H", "/?" ] )
        if  oi < 0  :   break
        del sys.argv[oi]
        print help_str % ( os.path.basename(program_name), diff, metric, metric, )
        sys.exit(254)


    while True :
        oi  = tzlib.array_find(sys.argv, [ "--verbose", "-v", ] )
        if  oi < 0  :   break
        del sys.argv[oi]
        verbose    += 1

    while True :
        oi  = tzlib.array_find(sys.argv, [ "--diff", "-diff", ] )
        if  oi < 0  :   break
        del sys.argv[oi]
        diff        = float(sys.argv.pop(oi))

    while True :
        oi  = tzlib.array_find(sys.argv, [ "--metric", "-metric", ] )
        if  oi < 0  :   break
        del sys.argv[oi]
        metric      = sys.argv.pop(oi)

    ff  = sys.argv.pop(0)
    fns = []
    while len(sys.argv) :
        afn     = sys.argv.pop(0)
        fns    += tzlib.ambiguous_file_list(afn)

    if  not len(fns) :
        print "Tell me files to compare!"
        sys.exit(101)

    tz_os_priority.set_proc_to_idle_priority(0)

    fns.sort(lambda a, b : cmp(a.lower(), b.lower()))

    fns = [ ff ] + fns

    do_it(fns, metric, diff, verbose = verbose)



#
#
# eof
