' *****************************************************
' PROGRAM:      picscale.bac
' PURPOSE:      to scale png images from the command line
' AUTHOR:               vovchik (Puppy Linux forum)
' MODDED:               PvE (thanks for the help)
' DEPENDS:      gcc, bacon, bash, gtk
' PLATFORM:     Puppy Linux (actually, any *nix)
' DATE:         09-11-2010
' NOTES:                This program makes use of gdk_pixbuf to
'                       scale/convert images. The formats supported
'                       by gdk_pixbuf on your system are listed
'                       in /etc/gtk-2.0/gdk-pixbuf.loaders.
'                       This program recognizes some of them.
' *****************************************************

' *********************
' DEF ERROR HANDER
' *********************

TRAP LOCAL
CATCH GOTO PRINT_ERROR

' *********************
' END DEF ERROR HANDER
' *********************


' *********************
' CONSTANTS
' *********************

CONST Gtk$ = "libgtk-x11-2.0.so.0"
CONST Gdk$ = "libgdk-x11-2.0.so.0"
CONST GDK_INTERP_HYPER = 3
CONST MY_VERSION$ = "v.0.1a by vovchik, Puppy Linux Forum"
CONST BACON_BLURB$ = "Check out BaCon at www.basic-converter.org"

' *********************
' END CONSTANTS
' *********************


' *********************
' DECLARATIONS
' *********************

DECLARE NUL TYPE STRING
GLOBAL org_file$, new_file$, new_height$, new_width$, quality$ TYPE STRING
GLOBAL new_quality$, argv_err$, my_input_formats$, my_output_formats$ TYPE STRING
GLOBAL old_file_type$, new_file_type TYPE STRING
GLOBAL t_height, t_width, q, new_q, w, h, r_x, r_y TYPE float
GLOBAL q2, zoom_quality, new_w, new_h, new_x, new_y TYPE int

' *********************
' END DECLARATIONS
' *********************


' *********************
' IMPORTS
' *********************

IMPORT "gtk_init(int*,void*)" FROM Gtk$ TYPE void
IMPORT "gtk_exit(int)" FROM Gtk$ TYPE void
IMPORT "gdk_pixbuf_scale_simple(long,int,int,int)" FROM "libgdk_pixbuf-2.0.so.0" TYPE long
IMPORT "gdk_pixbuf_get_width(int)" FROM "libgdk_pixbuf-2.0.so.0" TYPE int
IMPORT "gdk_pixbuf_get_height(int)" FROM "libgdk_pixbuf-2.0.so.0" TYPE int
IMPORT "gdk_pixbuf_new_from_file(char*,void*)" FROM "libgdk_pixbuf-2.0.so.0" TYPE long
IMPORT "gdk_pixbuf_scale_simple(long,int,int,int)" FROM "libgdk_pixbuf-2.0.so.0" TYPE long
IMPORT "gdk_pixbuf_save(long,char*,char*,void*,...)" FROM "libgdk_pixbuf-2.0.so.0" TYPE int
IMPORT "g_object_unref(long)" FROM "libgobject-2.0.so.0" TYPE void

' *********************
' END IMPORTS
' *********************


' *********************
' FUNCTIONS & SUBS
' *********************

' -----------
SUB INIT_VARS
' -----------
        org_file$ = ""
        new_file$ = ""
        new_height$ = ""
        thewidht$ = ""
        quality$ = ""
        w = 0
        h = 0
        r_x = 0
        r_y = 0
        new_w = 0
        new_h = 0
        new_x = 0
        new_y = 0
        argv_err$ = CONCAT$(NL$, \
                                "picscale image resizer/converter - ", MY_VERSION$, ", Nov 2010", NL$, NL$, \
                                "Input formats supported: pnm, pbm, pgm, ppm, tga, xpm, tiff, pcx, gif,", NL$, \
                                "xbm, wmf, icns, bmp, png, jpg and ico.", NL$, NL$ \
                                "Output formats supported: png, jpg, bmp, tiff and ico.", NL$, NL$ \
                                "Input parameters: oldfilename newfilename height width quality/compression/depth", NL$, NL$ \
                                "Example: picscale old.png new.png 128 128 9", NL$, NL$ \
                                "Quality/compression/depth settings:", NL$, NL$ \
                                "       bmp (N/A):               0 - 100", NL$, \
                                "       jpeg (quality):          0 - 100", NL$, \
                                "       png (compression):       0 - 9", NL$, \
                                "       tiff (compression type): 1 - 8", NL$, \
                                "       ico (depth):             16, 24 or 32", NL$, NL$, \
                                BACON_BLURB$, NL$)
        ' allowed input formats
        my_input_formats$ = "pnm pbm pgm ppm tga xpm tiff tif png bmp pcx ico wbmp gif jpe jpg jpeg xbm wmf icns"
        ' allowed output formats
        my_output_formats$ = "png jpg bmp ico tif tiff jpeg jpe"
END SUB

' -----------
SUB SHOW_ERROR(STRING my_msg$))
' -----------
        PRINT my_msg$
        PRINT argv_err$
END SUB

' -----------
SUB CHECK_ARGS()
' -----------
        LOCAL org_extension$, new_extension$ TYPE STRING
        IF NOT(INSTR(ARGUMENT$, " ")) THEN
                PRINT argv_err$
                END
        ELSE
                SPLIT ARGUMENT$ BY " " TO argv$ SIZE argc
                IF argc EQ 6 THEN
                        org_file$ = argv$[1]
                        new_file$ = argv$[2]
                        new_width$ = argv$[3]
                        new_height$ = argv$[4]
                        quality$ = argv$[5]
                ELSE
                        IF INSTR(ARGUMENT$, "-") THEN
                                SHOW_ERROR("")
                                END
                        ELSE
                                SHOW_ERROR(CONCAT$(NL$, "ERROR: Check input arguments!", NL$))
                                END
                        END IF
                END IF
                IF NOT(FILEEXISTS(org_file$)) THEN
                        SHOW_ERROR(CONCAT$(NL$, "ERROR: Input image does not exit!", NL$))
                        END
                END IF
                ' check org file extensions
                org_extension$ = LCASE$(MID$(org_file$, INSTRREV(org_file$, ".") + 1))
                IF INSTR(my_input_formats$, org_extension$) THEN
                        SELECT org_extension$
                                CASE "bmp"
                                        old_file_type$ = "bmp"
                                CASE "jpg";
                                CASE "jpeg";
                                CASE "jpe"
                                        old_file_type$ = "jpg"
                                CASE "ico"
                                        old_file_type$ = "ico"
                                CASE "png"
                                        old_file_type$ = "png"
                                CASE "icns"
                                        old_file_type$ = "icns"
                                CASE "wmf"
                                        old_file_type$ = "wmf"
                                CASE "gif"
                                        old_file_type$ = "gif"
                                CASE "xpm"
                                        old_file_type$ = "xpm"
                                CASE "xbm"
                                        old_file_type$ = "xbm"
                                CASE "tiff";
                                CASE "tif"
                                        old_file_type$ = "tiff"
                                CASE "ppm"
                                        old_file_type$ = "ppm"
                                CASE "pbm"
                                        old_file_type$ = "pbm"
                                CASE "pgm"
                                        old_file_type$ = "pgm"
                                CASE "pnm"
                                        old_file_type$ = "pnm"
                                CASE "pcx"
                                        old_file_type$ = "pcx"
                        END SELECT
                ELSE
                        SHOW_ERROR(CONCAT$(NL$, "Picscale cannot handle the ", org_extension$, " input format.", NL$))
                        END
                END IF
                ' check new file extensions
                new_extension$ = LCASE$(MID$(new_file$, INSTRREV(new_file$, ".") + 1))
                IF INSTR(my_output_formats$, new_extension$) THEN
                        SELECT new_extension$
                                CASE "bmp"
                                        new_file_type$ = "bmp"
                                CASE "jpg";
                                CASE "jpeg";
                                CASE "jpe"
                                        new_file_type$ = "jpeg"
                                CASE "ico"
                                        new_file_type$ = "ico"
                                CASE "png"
                                        new_file_type$ = "png"
                                CASE "tiff";
                                CASE "tif"
                                        new_file_type$ = "tiff"
                        END SELECT
                ELSE
                        SHOW_ERROR(CONCAT$("Picscale cannot handle the ", new_extension$, " output format."))
                        END
                END IF                  
        END IF
END SUB

' -----------
SUB PREPARE_VARS()
' -----------
        t_height = VAL(new_height$)
        t_width = VAL(new_width$)
        q = VAL(quality$)
        new_q = 100 - q
        q2 = new_q / 10
        new_quality$ = STR$(q2)
END SUB

' -----------
SUB PROCESS_DATA()
' -----------
        gtk_init(0, 0)
        zoom_quality = (int)GDK_INTERP_HYPER
        im2 = gdk_pixbuf_new_from_file(org_file$, NULL)
        w = gdk_pixbuf_get_width(im2)
        h = gdk_pixbuf_get_height(im2)
        r_x = t_width / w
        r_y = t_height / h
        IF t_height EQ t_width THEN
                new_w = t_width
                new_h = t_height
        ELSE
                IF r_x <=r_y THEN
                        new_w = t_width
                        new_h = h * r_x + 1
                ELSE
                  new_w = w * r_y + 1
                  new_h = t_height
                END IF
        END IF
        im = gdk_pixbuf_scale_simple(im2, new_w, new_h, zoom_quality)
        SELECT new_file_type$
                CASE "png"
                        gdk_pixbuf_save(im, new_file$, new_file_type$, NUL, "compression", new_quality$, NUL)
                CASE "jpeg"
                        new_quality$ = quality$
                        gdk_pixbuf_save(im, new_file$, new_file_type$, NUL, "quality", new_quality$, NUL)              
                CASE "tiff"
                        new_quality$ = quality$
                        gdk_pixbuf_save(im, new_file$, new_file_type$, NUL, "compression", new_quality$, NUL)
                CASE "ico"
                        new_quality$ = quality$
                        gdk_pixbuf_save(im, new_file$, new_file_type$, NUL, "depth", new_quality$, NUL)
                DEFAULT
                        gdk_pixbuf_save(im, new_file$, new_file_type$, NUL, NUL, NUL, NUL)
        END SELECT
        g_object_unref(im)
        g_object_unref(im2)
END SUB

' -----------
SUB REPORT_RESULTS()
' -----------
        IF FILEEXISTS(new_file$) THEN
                PRINT "File ", new_file$, " created."
                PRINT "Original image: ", org_file$
                PRINT "New dimensions (w x h): ", new_width$, " x ", new_height$
                PRINT "Quality of new image: ", quality$
        ELSE
                PRINT "OOPS.. something terrible happened and ", new_file$, " was not created."
        END IF
        gtk_exit(0)
END SUB

' *********************
' END FUNCTIONS & SUBS
' *********************


' *********************
' MAIN
' *********************

INIT_VARS
CHECK_ARGS
PREPARE_VARS
PROCESS_DATA
REPORT_RESULTS

' *********************
' END MAIN
' *********************


' *********************
' ERROR HANDLER
' *********************

LABEL PRINT_ERROR
    PRINT "GTK library ", Gtk$, " is not available on this platform!"
    END