/* pamfile.c - describe a portable anymap
**
** Copyright (C) 1991 by Jef Poskanzer.
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted, provided
** that the above copyright notice appear in all copies and that both that
** copyright notice and this permission notice appear in supporting
** documentation.  This software is provided "as is" without express or
** implied warranty.
*/

#include "pam.h"
#include "shhopt.h"

struct cmdline_info {
    /* All the information the user supplied in the command line,
       in a form easy for the program to use.
    */
    int n_input_file;  /* Number of input files */
    char **input_filespec;  /* Filespecs of input files */
    int allimages;  /* He wants info on all images in each file */
};



static void
parse_command_line(int argc, char ** argv,
                   struct cmdline_info *cmdline_p) {
/*----------------------------------------------------------------------------
   Note that the file spec array we return is stored in the storage that
   was passed to as as the argv array.
-----------------------------------------------------------------------------*/
    optStruct *option_def = malloc(100*sizeof(optStruct));
        /* Instructions to OptParseOptions2 on how to parse our options.
         */
    optStruct2 opt;

    unsigned int option_def_index;

    option_def_index = 0;   /* incremented by OPTENTRY */
    OPTENTRY(0,   "allimages", OPT_FLAG,   &cmdline_p->allimages,     0);

    /* Set the defaults */
    cmdline_p->allimages = FALSE;

    opt.opt_table = option_def;
    opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
    opt.allowNegNum = FALSE;  /* We have no parms that are negative numbers */
    
    optParseOptions2(&argc, argv, opt, 0);
        /* Uses and sets argc, argv, and all of *cmdline_p. */

    cmdline_p->input_filespec = argv + 1;
    cmdline_p->n_input_file = argc - 1;
}



static void
dump_header(const struct pam pam) {
    switch (pam.format) {
    case PAM_FORMAT:
        printf("PAM, %d by %d by %d maxval %ld\n", 
               pam.width, pam.height, pam.depth, pam.maxval);
        printf("    Tuple type: %s\n", pam.tuple_type);
        break;

	case PBM_FORMAT:
        printf("PBM plain, %d by %d\n", pam.width, pam.height );
        break;

	case RPBM_FORMAT:
        printf("PBM raw, %d by %d\n", pam.width, pam.height);
        break;

	case PGM_FORMAT:
        printf("PGM plain, %d by %d  maxval %ld\n", 
               pam.width, pam.height, pam.maxval);
        break;

	case RPGM_FORMAT:
        printf("PGM raw, %d by %d  maxval %ld\n", 
               pam.width, pam.height, pam.maxval);
        break;

	case PPM_FORMAT:
        printf("PPM plain, %d by %d  maxval %ld\n", 
               pam.width, pam.height, pam.maxval);
        break;

	case RPPM_FORMAT:
        printf("PPM raw, %d by %d  maxval %ld\n", 
               pam.width, pam.height, pam.maxval);
        break;
    }
}



static void
describe_one_file(const char * const name, FILE *file, const int allimages) {

    struct pam pam;
    enum pm_check_code check_retval;
    int image_no;  /* Sequence number of current image in file.  First = 0 */
    int done;  /* No more images we must describe */
    
    done = FALSE;  /* At least one image is required */
    for (image_no = 0; !done; image_no++) {
        if (allimages)
            printf("%s:\tImage %d:\t", name, image_no);
        else 
            printf( "%s:\t", name );

        pnm_readpaminit(file, &pam, sizeof(pam));
        
        dump_header(pam);

        pnm_checkpam(&pam, PM_CHECK_BASIC, &check_retval);
        if (allimages) {
            tuple *tuplerow;
            int eof;
            int row;

            tuplerow = pnm_allocpamrow(&pam);
            for (row = 0; row < pam.height; row++) 
                pnm_readpamrow(&pam, tuplerow);
            pnm_freepamrow(tuplerow);
            pnm_nextimage(file, &eof);
            done = eof;
        } else
            done = TRUE;
    }
}



int
main(int argc, char *argv[]) {

    struct cmdline_info cmdline;

    pnm_init(&argc, argv);

    parse_command_line(argc, argv, &cmdline);

    if (cmdline.n_input_file == 0)
        describe_one_file("stdin", stdin, cmdline.allimages);
    else {
        int i;
        for (i = 0; i < cmdline.n_input_file; i++) {
            FILE* ifp;
            ifp = pm_openr(cmdline.input_filespec[i]);
            describe_one_file(cmdline.input_filespec[i], ifp, 
                              cmdline.allimages);
            pm_close(ifp);
	    }
	}
    
    exit(0);
}
