/* jpegAGA 2.2 written by Günther Röhrich */

#define __NOLIBBASE__
#include <workbench/startup.h>
#include <proto/dos.h>
#include "WBFlags.h"

#include <stdio.h>
#include <stdlib.h>

/*
 * Include file for users of JPEG library.
 * You will need to have included system headers that define at least
 * the typedefs FILE and size_t before you can include jpeglib.h.
 * (stdio.h is sufficient on ANSI-conforming systems.)
 * You may also wish to include "jerror.h".
 */

#include "jpeglib.h"
#include "jerror.h"
#include "myerror.h"
#define JMAKE_MSG_TABLE
#include "myerror.h" /* create the message string table */

/*
 * <setjmp.h> is used for the optional error recovery mechanism shown in
 * the second part of the example.
 */

#include <setjmp.h>
#include <signal.h>
#include <string.h>


extern void Amiga_jpeg_stdio_src (j_decompress_ptr cinfo, BPTR infile);

#define HAM8 1

/* #define DEBUGFILE */ /* write a ppm file for debugging */

#ifdef __GNUC__
#define MYSTRCMP strcasecmp
#define MYSTRNCMP strncasecmp
#else
#define MYSTRCMP strcmp
#define MYSTRNCMP strncmp
#endif

#define MAXFILES 500

char  *ver = "\0$VER: jpegAGA 2.2 (15.9.95)";

#ifdef __GNUC__
char __stdiowin[]="CON:30/12/600/80/jpegAGA 2.2";
#endif


struct WBFlags WBFlags =
{
 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

struct WBFlags OldFlags;

short SMR_HAM;
short WBFiles=0;
short DoNotWait=0;
short finish=0;
static short ButtonPressed=0;

BPTR olddir=0;
int NumPictures=0;
struct WBArg *wb_arg=NULL;
char *PicArray[MAXFILES];
unsigned long SMR_DisplayID = 0;
unsigned long *ScreenColorTable=NULL;
short ASLPicSelect = 0;

static unsigned long Mode=0;
static char *MapFileName=NULL;
static char *MapDirName=NULL;
static BPTR infile=0;
static BPTR ColorMapFile = 0;

/* This struct contains the JPEG decompression parameters and pointers to
 * working space (which is allocated as needed by the JPEG library).
 */

static struct jpeg_decompress_struct cinfo;

/* We use our private extension JPEG error handler. */

static struct jpeg_error_mgr jerr;

volatile int PictureNr;

extern void FillNameBuffer(char *pattern);
extern void ParseToolTypes(struct WBArg *wbarg, int initial);
extern int InitDisplay(int cols, int rows, unsigned long Mode, int NumPlanes);
extern void CloseDisplay(void);
extern void DisplayRow(JSAMPROW buffer, int cols);
extern int CheckButton(void);
extern void FinalWait(void);
extern void FlipScreen(void);
extern void FreeASL(void);
extern int ChooseScreenMode(int grayscale, char *title);
extern void ChooseFiles(void);
extern int FindScaleFit(JDIMENSION width, JDIMENSION height, unsigned long Mode);
extern unsigned long my_screen[2];
extern unsigned long ScaleFitDisplayID;
JSAMPROW OutputBuffer=NULL;

extern void EncodeHAM8(JSAMPROW orig, JSAMPROW yham, int xsize);
unsigned short Mult_Table[2*256];
jmp_buf setjmp_buffer;

/* NOTE: this array is in brgbrg order */

char *ColorCache=NULL;
unsigned char FixedColorTable[64*3] =
 { 0, 0, 0,  4, 4, 4,  8, 8, 8, 12,12,12,   
  16,16,16, 20,20,20, 24,24,24, 28,28,28,  /* 16 colors */
  32,32,32, 36,36,36, 41,41,41, 46,46,46,
  51,51,51, 55,55,55, 59,59,59, 63,63,63,


                      17,17,39, 17,17,55, /* 13 colors */ 
  17,29,17,           17,29,39, 17,29,55, 
  17,39,17, 17,39,29, 17,39,39, 17,39,55,
  17,55,17, 17,55,39, 17,55,39, 17,55,55,


            29,17,29, 29,17,39, 29,17,55, /* 11 colors */
                                29,29,55,
  29,39,17, 29,39,29,           29,39,55,
  29,55,17, 29,55,29, 29,55,39, 29,55,55,


  39,17,17, 39,17,29, 39,17,39, 39,17,55, /* 12 colors */
  39,29,17, 39,29,29,           39,29,55,
  39,39,17, 39,39,29,          
  39,55,17, 39,55,29,  

  
  55,17,17, 55,17,29, 55,17,39, 55,17,55, /* 13 colors */
  55,29,27, 55,29,29, 55,29,39, 55,29,55,
  55,39,17, 55,39,29, 55,39,39, 
  55,55,17, 55,55,29
};

unsigned char ColorTable[64*3];



METHODDEF void
my_error_exit (j_common_ptr cinfo)
{
 #ifdef __GNUC__
 signal(SIGINT, SIG_IGN);
 #endif
 /* Always display the message. */
 if(cinfo->err->msg_code != JWRN_JPEGAGA_STOPPED) (*cinfo->err->output_message) (cinfo);

 /* Return control to the setjmp point */
 longjmp(setjmp_buffer, 1);
}

void interrupt(int signum)
{
 #ifdef __GNUC__
 signal(SIGINT, SIG_IGN);
 #endif
 printf("^C\n");
 ButtonPressed = 1;
 longjmp(setjmp_buffer, 1);
}


GLOBAL int
read_JPEG_file (char *filenames[])
{
  /* More stuff */
  JSAMPARRAY buffer;		/* Output row buffer */
  int row_stride;		/* physical row width in output buffer */
  int DisplaySuccess, i;
  char *filename;

  /* Step 1: allocate and initialize JPEG decompression object */
  
  jpeg_create_decompress(&cinfo);

  /* Now we can initialize the JPEG decompression object. */

  /* We set up the normal JPEG error routines, then override error_exit. */
  cinfo.err = jpeg_std_error(&jerr);
  jerr.error_exit = my_error_exit;

  /* Set maximum memory to use */
  if(WBFlags.MaxMemFlag) cinfo.mem->max_memory_to_use = WBFlags.MaxMem * 1000L;
  

  /* Add some application-specific error messages (from myerror.h) */
  jerr.addon_message_table = addon_message_table;
  jerr.first_addon_message = JMSG_FIRSTADDONCODE;
  jerr.last_addon_message = JMSG_LASTADDONCODE;

  /* main loop */

  for(PictureNr=0; PictureNr < NumPictures; PictureNr++)
  {

    /* Establish the setjmp return context for my_error_exit to use. */
    if (setjmp(setjmp_buffer)) {
      /* If we get here, the JPEG code has signaled an error.
       * We need to clean up the JPEG object, close the input file, and return.
       */
      if(PictureNr == NumPictures -1)
        jpeg_destroy_decompress(&cinfo);
      else
        jpeg_abort_decompress(&cinfo);
      if(infile)
      {
        Close(infile);
        infile=0;
      }
      if(olddir)
      {
        CurrentDir(olddir);
        olddir=0;
      }
      if(ColorCache)
      {
        free(ColorCache);
        ColorCache=NULL;
      }
      if(MapFileName)
      {
        free(MapFileName);
        MapFileName=NULL;
      }
      if(MapDirName)
      {
        free(MapDirName);
        MapDirName=NULL;
      }
      if(ColorMapFile)
      {
        Close(ColorMapFile);
        ColorMapFile=0;
      }
      if(OutputBuffer)
      {
       free(OutputBuffer);
       OutputBuffer=NULL;
      }
      if(ScreenColorTable)
      {
        free(ScreenColorTable);
        ScreenColorTable=NULL;
      }
      if(PictureNr == NumPictures -1 || WBFlags.SMRenable)
      {
        if(!ButtonPressed) FinalWait();
        CloseDisplay();
        if(finish) break;
      }
      if(finish)
      {
        CloseDisplay();
        break;
      }
      else if(ButtonPressed)
        DoNotWait=1;
      continue;
    }

    /* CTRL-C handling) */

    #ifdef __GNUC__
    signal(SIGINT, interrupt);
    #endif
    
    if(olddir)
    {
      CurrentDir(olddir);
      olddir=0;
    }

    ScaleFitDisplayID = 0;

    if(WBFiles) memcpy(&WBFlags, &OldFlags, sizeof(struct WBFlags));

    if(WBFiles && wb_arg)
    {
      if(wb_arg->wa_Name == NULL) ERREXIT(&cinfo, JERR_JPEGAGA_OPEN);
      filename = wb_arg->wa_Name;
      printf(" %s: ", filename);
      fflush(stdout);

      if(wb_arg->wa_Lock != 0)
      {
        olddir = CurrentDir(wb_arg->wa_Lock);
        infile = Open(filename, MODE_OLDFILE);
        if(infile) ParseToolTypes(wb_arg, 0);
      }
      else
      {
        infile = Open(filename, MODE_OLDFILE);    
      }
      wb_arg++;
    }
    else if(!WBFiles)
    {
      filename = filenames[PictureNr];
      printf(" %s: ", filename);
      fflush(stdout);
      infile = Open(filename, MODE_OLDFILE);
    }

    if(infile == 0)
    {
      ERREXIT(&cinfo, JERR_JPEGAGA_OPEN);
    }
    
    /* Step 2: specify data source (eg, a file) */

    Amiga_jpeg_stdio_src(&cinfo, infile);

    /* Step 3: read file parameters with jpeg_read_header() */

    (void) jpeg_read_header(&cinfo, TRUE);
    /* We can ignore the return value from jpeg_read_header since
     *   (a) suspension is not possible with the stdio data source, and
     *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
     * See libjpeg.doc for more info.
     */

    printf("%d x %d, ", (int)cinfo.image_width, (int)cinfo.image_height);
    if(cinfo.progressive_mode) printf("progr., ");
    fflush(stdout);

    /* Step 4: set parameters for decompression */

    /* set user selectable options */
  
    if(WBFlags.DCTFast) cinfo.dct_method = JDCT_IFAST; 

    if(WBFlags.NoSmooth) cinfo.do_fancy_upsampling = FALSE; /* override this with options */

    if(WBFlags.SMRenable)
    {
      int grayscale=0;
      
      if(cinfo.out_color_space == JCS_GRAYSCALE) grayscale = 1;
      FinalWait();
      CloseDisplay();
      if(finish) ERREXIT(&cinfo, JWRN_JPEGAGA_STOPPED);
      if(ChooseScreenMode(grayscale, filename)) ERREXIT(&cinfo, JERR_JPEGAGA_NOMODE);
      if(SMR_HAM)
        WBFlags.GrayEnable = 0;
      else
        WBFlags.GrayEnable = 1;
    }
    else if(WBFlags.ScaleFit)
    {
      int tempscale;
      if(WBFlags.GrayEnable) cinfo.out_color_space=JCS_GRAYSCALE; /* force grayscale output */
      if(cinfo.out_color_space != JCS_GRAYSCALE)
        Mode = HAM8;
      else
        Mode = 0;
      tempscale = FindScaleFit(cinfo.image_width, cinfo.image_height, Mode);
      if(tempscale == -1) ERREXIT(&cinfo, JERR_JPEGAGA_DISPLAY);
      WBFlags.scale = tempscale;
    }
  
    if(WBFlags.GrayEnable) cinfo.out_color_space=JCS_GRAYSCALE; /* force grayscale output */
    cinfo.scale_num = 1;
    cinfo.scale_denom = (unsigned int)WBFlags.scale;

    if(WBFlags.scale != 1) printf("scale 1/%d, ", WBFlags.scale);

    /* Step 5: Start decompressor */

    jpeg_start_decompress(&cinfo);

    /* Now setup everything for showing the picture */

    if(cinfo.out_color_space == JCS_GRAYSCALE)
    {
      printf("grayscale\n");
      fflush(stdout);
      ScreenColorTable = malloc(256*4*3+8);
      if(!ScreenColorTable) ERREXIT(&cinfo, JERR_JPEGAGA_MEMORY);

      for(i=0; i<256; i++)
      {
        ScreenColorTable[i*3+1] = (unsigned long)i<<24;
        ScreenColorTable[i*3+2] = (unsigned long)i<<24;
        ScreenColorTable[i*3+3] = (unsigned long)i<<24;
      }

      ScreenColorTable[0] = 256L<<16+0;
      ScreenColorTable[256*3+1] = 0;

      DisplaySuccess = InitDisplay(cinfo.output_width, cinfo.output_height, 0, 8);

      if(finish) ERREXIT(&cinfo, JWRN_JPEGAGA_STOPPED);

      if(ScreenColorTable)
      {
        free(ScreenColorTable);
        ScreenColorTable=NULL;
      }

      if(DisplaySuccess != 1)
      {
        CloseDisplay();
        ERREXIT(&cinfo, JERR_JPEGAGA_DISPLAY);
      }

    }
    else if(cinfo.out_color_space == JCS_RGB)
    {
      printf("HAM8");
      fflush(stdout);
      ColorCache = calloc(262145, 1);
      if(ColorCache == NULL) ERREXIT(&cinfo, JERR_JPEGAGA_MEMORY);

      /* create the multiplication table */
      for(i=-255; i<256; i++) Mult_Table[i+255] = (unsigned short)(i*i);

      MapFileName = malloc(strlen(filename)+5);
      if(MapFileName == NULL) ERREXIT(&cinfo, JERR_JPEGAGA_MEMORY);
      
      strcpy(MapFileName, filename); /* create a copy of the file name */

      strcat(MapFileName, ".map");

      ColorMapFile = Open(MapFileName, MODE_OLDFILE);

      /* try to find the file in the directory pointed to by the environment */
      /* variable MAPDIR to support read-only devices like CD-ROM */
      if(!ColorMapFile)
      {
        char *MapDir;
        MapDir = getenv("MAPDIR");
        if(MapDir)
        if(strlen(MapDir) != 0)
        {
          int pos,i;
          MapDirName = malloc(strlen(MapDir)+strlen(MapFileName)+5); /* worst case */
          if(!MapDirName) ERREXIT(&cinfo, JERR_JPEGAGA_MEMORY);
          strcpy(MapDirName, MapDir);

          i = strlen(MapDirName);
          if(MapDirName[i-1] != '/' && MapDirName[i-1] != ':')
          {
            strcat(MapDirName, "/");
            i++;
          }
          i = strlen(MapFileName);
          while(i > 0 && MapFileName[i-1] != '/' && MapFileName[i-1] != ':') i--;
          strcat(MapDirName, &MapFileName[i]);
          /* printf("%s\n", MapDirName); */
          ColorMapFile = Open(MapDirName, MODE_OLDFILE);
        }
      }


      if(!ColorMapFile)
      {
        int i = strlen(MapFileName) - 4;
        while(i > 0 && MapFileName[i-1] != '.') i--;
        if(MapFileName[i-1] == '.')
        {
          strcpy(&MapFileName[i], "map");
          ColorMapFile = Open(MapFileName, MODE_OLDFILE);
        }
      }
 
 
      if(ColorMapFile)
      {
        unsigned short MagicNumber;
        unsigned int Reserved;

        if(Read(ColorMapFile, &MagicNumber, 2) != 2) ERREXIT(&cinfo, JERR_JPEGAGA_MAPFILE);
        if(MagicNumber != 0x1203) ERREXIT(&cinfo, JERR_JPEGAGA_MAPFILE);  
        if(Read(ColorMapFile, &Reserved, 4) != 4) ERREXIT(&cinfo, JERR_JPEGAGA_MAPFILE);
        if(Read(ColorMapFile, ColorTable,  64*3) != 64*3) ERREXIT(&cinfo, JERR_JPEGAGA_MAPFILE);

        printf(" with mapfile\n");
        Close(ColorMapFile);

        ColorMapFile = 0;
      }
      else
      {
        printf(", create a colormap file for better quality!\n");
        memcpy(ColorTable, FixedColorTable, 64*3);
      }

      if(MapFileName)
      {
        free(MapFileName);
        MapFileName=NULL;
      }
      if(MapDirName)
      {
        free(MapDirName);
        MapDirName=NULL;
      }

      ScreenColorTable = malloc(64*4*3+8);
      if(!ScreenColorTable) ERREXIT(&cinfo, JERR_JPEGAGA_MEMORY);

      for(i=0; i<64; i++)
      {
        ScreenColorTable[i*3+1] = (unsigned long)ColorTable[i*3+1]<<26; 
        ScreenColorTable[i*3+2] = (unsigned long)ColorTable[i*3+2]<<26;
        ScreenColorTable[i*3+3] = (unsigned long)ColorTable[i*3]<<26;
      }

      ScreenColorTable[0] = 64L<<16+0;
      ScreenColorTable[64*3+1] = 0;

      DisplaySuccess = InitDisplay(cinfo.output_width, cinfo.output_height, HAM8, 8);
      
      if(finish) ERREXIT(&cinfo, JWRN_JPEGAGA_STOPPED);
       
      if(ScreenColorTable)
      {
        free(ScreenColorTable);
        ScreenColorTable=NULL;
      }

      if(DisplaySuccess != 1)
      {
        CloseDisplay();
        ERREXIT(&cinfo, JERR_JPEGAGA_DISPLAY);
      }
    }
    else ERREXIT(&cinfo, JERR_CONVERSION_NOTIMPL); 

    /* JSAMPLEs per row in output buffer */
    /* make it a bit larger to allow direct screen output */

    row_stride = (((cinfo.output_width * cinfo.output_components +15)>>4)<<4);

    /* Make a sample array that will go away when done with image */
    buffer = (*cinfo.mem->alloc_sarray)
	  	((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, cinfo.rec_outbuf_height);

    /* printf("Recommended size: %d\n", cinfo.rec_outbuf_height); */

    /* Step 6: while (scan lines remain to be read) */
    /*           jpeg_read_scanlines(...); */

    /* Here we use the library's state variable cinfo.output_scanline as the
     * loop counter, so that we don't have to keep track ourselves.
     */

    ButtonPressed=0;

    if(cinfo.out_color_space == JCS_GRAYSCALE)
    {
      JDIMENSION numpixels, i;
      while (cinfo.output_scanline < cinfo.output_height)
      {
        numpixels = jpeg_read_scanlines(&cinfo, buffer, cinfo.rec_outbuf_height);
        if(CheckButton())
        {
          ButtonPressed=1;
          ERREXIT(&cinfo, JWRN_JPEGAGA_STOPPED);
        }
        /* Assume put_scanline_someplace wants a pointer and sample count. */
        for(i=0; i<numpixels; i++)
          DisplayRow(buffer[i], cinfo.output_width);
      }
    }

    else if(cinfo.out_color_space == JCS_RGB)
    {
      JDIMENSION numpixels, i;
#ifdef DEBUGFILE
      FILE *testfile;
      testfile = fopen("test.ppm", "w");
      if(testfile == NULL) ERREXIT(&cinfo, JERR_JPEGAGA_MEMORY);
      fprintf(testfile, "P6\n%ld %ld\n%d\n",
	      (long) cinfo.output_width, (long) cinfo.output_height, 255);
#endif

      OutputBuffer = malloc(((cinfo.output_width+15)>>4)<<4);
      if(!OutputBuffer) ERREXIT(&cinfo, JERR_JPEGAGA_MEMORY);
    
    
      while (cinfo.output_scanline < cinfo.output_height)
      {
        numpixels = jpeg_read_scanlines(&cinfo, buffer, cinfo.rec_outbuf_height);
        if(CheckButton())
        {
          ButtonPressed=1;
          ERREXIT(&cinfo, JWRN_JPEGAGA_STOPPED);
        }
        /* Assume put_scanline_someplace wants a pointer and sample count. */
        for(i=0; i<numpixels; i++)
        {
#ifdef DEBUGFILE
          fwrite(buffer[i], 3, cinfo.output_width, testfile);
#endif
          EncodeHAM8(buffer[i], OutputBuffer, cinfo.output_width);
          DisplayRow(OutputBuffer, cinfo.output_width);
        }
      }
#ifdef DEBUGFILE
      fclose(testfile);
#endif
      free(OutputBuffer);
      OutputBuffer = NULL;
    }


    /* Step 7: Finish decompression */
  
    (void) jpeg_finish_decompress(&cinfo);
    /* We can ignore the return value since suspension is not possible
     * with the stdio data source.
     */

    /* Step 8: Release JPEG decompression object */

    #ifdef __GNUC__
    signal(SIGINT, SIG_IGN);
    #endif


    /* This is an important step since it will release a good deal of memory. */
    if(PictureNr == NumPictures -1) jpeg_destroy_decompress(&cinfo);

    /* After finish_decompress, we can close the input file.
     * Here we postpone it until after no more JPEG errors are possible,
     * so as to simplify the setjmp error logic above.  (Actually, I don't
     * think that jpeg_destroy can do an error exit, but why assume anything...)
     */
    if(olddir)
    {
      CurrentDir(olddir);
      olddir=0;
    }
    if(infile)
    {
      Close(infile);
      infile=0;
    }
    if(ColorCache)
    {
      free(ColorCache);
      ColorCache=NULL;
    }

    DoNotWait=0;
    if(PictureNr == NumPictures -1)
    {
      FinalWait();
      CloseDisplay();
    }
    if(finish) break;

    /* At this point you may want to check to see whether any corrupt-data
     * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
     */

    /* And we're done! */
  }
  CloseDisplay(); /* just for the case we forgot to close something */
  return 0;
}


static void Usage(void)
{
 printf("Usage: jpegAGA [switches] [files]\n"
        "switches: -gray      force grayscale output\n"
        "          -fit       scale output to fit on the screen\n"
        "          -scale M/N scale output image by fraction M/N, eg. 1/8\n"
        "          -nosmooth  don't use high quality upsampling\n"
        "          -dct fast  use fast integer DCT (less accurate)\n"
        "          -vga       use VGA screenmode\n"
        "          -super72   use SUPER72 mode for large pictures\n"
        "          -smr       use screen mode requester\n"
        "          -maxmem N  maximum memory to use (for decoder)\n");
 CloseDisplay();
 exit(10);
}

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

#ifdef __GNUC__
 signal(SIGINT, SIG_IGN); /* disable CTRL-C handling */
#endif

 printf("jpegAGA 2.2 by Günther Röhrich. This program is Public Domain.\n");

 /* remove the comments for beta versions */
 /* printf("Preliminary version. DO NOT SPREAD IT!\n"); */

 if(argc == 0 && argv) FillWB(argv);

 else for(i=1; i<argc; i++)
 {
   if(MYSTRNCMP(argv[i], "-", 1))
   {
     FillNameBuffer(argv[i]);
     continue;
   }
   #ifndef __GNUC__
   strupr(argv[i]);
   #endif
   if(!MYSTRNCMP(argv[i], "-GRAY", 5)) WBFlags.GrayEnable=1;   

   else if(!MYSTRNCMP(argv[i], "-VGA", 4)) WBFlags.VGAenable=1;

   else if(!MYSTRNCMP(argv[i], "-SUPER72", 8)) WBFlags.SUPER72enable=1;

   else if(!MYSTRNCMP(argv[i], "-SMR", 4)) WBFlags.SMRenable=1;

   else if(!MYSTRNCMP(argv[i], "-NOSMOOTH", 9)) WBFlags.NoSmooth=1;

   else if(!MYSTRNCMP(argv[i], "-FIT", 4)) WBFlags.ScaleFit=1;

   else if(!MYSTRNCMP(argv[i], "-DCT", 4))
   {
     if(argc == i+1) Usage(); /* last argument */
     i++;
      if(!MYSTRNCMP(argv[i], "FAST", 3)) WBFlags.DCTFast=1;
      else if(!MYSTRNCMP(argv[i], "INT", 3)) WBFlags.DCTFast=0;
   }

   else if(!MYSTRNCMP(argv[i], "-SCALE", 6))
   {
     if(argc == i+1) Usage(); /* last argument */
     i++;
      if(!MYSTRNCMP(argv[i], "1/1", 3)) WBFlags.scale=1;
      else if(!MYSTRNCMP(argv[i], "1/2", 3)) WBFlags.scale=2;
      else if(!MYSTRNCMP(argv[i], "1/4", 3)) WBFlags.scale=4;
      else if(!MYSTRNCMP(argv[i], "1/8", 3)) WBFlags.scale=8;
      else Usage();
   }
    
   else if(!MYSTRNCMP(argv[i], "-MAXMEM", 7))
   {
     char ch = 'x';
     if(argc == i+1) Usage(); /* last argument */
     i++;
     if (sscanf(argv[i], "%ld%c", &WBFlags.MaxMem, &ch) < 1) Usage();
     if (ch == 'm' || ch == 'M') WBFlags.MaxMem *= 1000L;
     WBFlags.MaxMemFlag = 1;
   }
 
   else Usage();
 }    

 if(NumPictures == 0) ChooseFiles();

 if(NumPictures == 0)
 {
   CloseDisplay();
   FreeASL();
   exit(10);
 }

 while(NumPictures)
 {
   read_JPEG_file(PicArray);
   finish=0;
   for(i=0; i<NumPictures; i++)
   {
     free(PicArray[i]);
     PicArray[i]=NULL;
   }
   NumPictures=0;
   if(ASLPicSelect) ChooseFiles();
 }

 CloseDisplay();
 FreeASL();
 return 0;
}
