/*
 * image.c
 *
 * Copyright (C) 1993, 1994 Evan Harris
 *
 * Permission is granted to freely redistribute and modify this code,
 * providing the author(s) get credit for having written it.
 */

#include "seejpeg.h"
#include <setjmp.h>


/* These extern variables are needed by the error routines. */
extern jmp_buf setjmp_buffer;	/* for return to caller */
extern external_methods_ptr emethods; /* needed for access to message_parm */


GLOBAL int
read_image_file(char * filename)
{
  struct Compress_info_struct cinfo;
  struct Compress_methods_struct c_methods;
  struct External_methods_struct e_methods;
  JSAMPARRAY pixel_row, cmap_row;
  JSAMPIMAGE pixel_data;
  char *type;
  int c, row, components, translate;

  if ((cinfo.input_file = fopen(filename, "rb")) == NULL) {
    fprintf(stderr, "can't open %s\n", filename);
    return 0;
  }
  if ((c = getc(cinfo.input_file)) == EOF)
    error_exit("Empty input file");
  fseek(cinfo.input_file, 0, 0);

  cinfo.methods = &c_methods;	/* links to method structs */
  cinfo.emethods = &e_methods;
  emethods = &e_methods;	/* save struct addr for possible access */
  e_methods.error_exit = error_exit; /* supply error-exit routine */
  e_methods.trace_message = trace_message; /* supply trace-message routine */
  e_methods.trace_level = 0;	/* default = no tracing */
  e_methods.num_warnings = 0;	/* no warnings emitted yet */
  e_methods.first_warning_level = 0; /* display first corrupt-data warning */
  e_methods.more_warning_level = 3; /* but suppress additional ones */

  switch (c) {
  case 'G':
    type = "GIF";
    jselrgif(&cinfo);
    break;
  case 'P':
    type = "PPM";
    jselrppm(&cinfo);
    break;
#if 0
  case 'R':
    jselrrle(&cinfo);
    break;
#endif
  case 0x00:
    type = "TARGA";
    jselrtarga(&cinfo);
    break;
  default:
    fclose(cinfo.input_file);
    return read_JPEG_file(filename);
    break;
  }

  if (opt_verbose) {
    printf("Type   : %s\n", type);
  }

  if (setjmp(setjmp_buffer)) {
    fclose(cinfo.input_file);
    return 0;
  }
  
  jselmemmgr(&e_methods);	/* select std memory allocation routines */

  (cinfo.methods->input_init) (&cinfo);
  components = cinfo.input_components;
  if (c == 'G' && components == 3) { /* GIF */
    components = 1;
    translate = 1;
    translate_init();
  } else {
    translate = 0;
  }
  display_init(cinfo.image_width, cinfo.image_height, components);
  
  if (components == 1 && !translate) {
    display_set_greyscale_palette();
  }

  pixel_row = (*cinfo.emethods->alloc_small_sarray)
    (cinfo.image_width, (long) cinfo.input_components);
  if (translate) {
    cmap_row = (*cinfo.emethods->alloc_small_sarray)
	(cinfo.image_width, (long) components);
    pixel_data = (JSAMPIMAGE)(*cinfo.emethods->alloc_small_sarray)
      (sizeof(JSAMPROW *), (long) components);
    for (c = 0; c < components; c++) {
      pixel_data[c][0] = cmap_row[c];
    }
  } else {
    cmap_row = NULL;
    pixel_data = (JSAMPIMAGE)(*cinfo.emethods->alloc_small_sarray)
      (sizeof(JSAMPROW *), (long) cinfo.input_components);
    for (c = 0; c < cinfo.input_components; c++) {
      pixel_data[c][0] = pixel_row[c];
    }
  }

  for (row = 0; row < cinfo.image_height; row++) {
    (*cinfo.methods->get_input_row) (&cinfo, pixel_row);
    if (translate) {
      translate_row(cinfo.image_width, pixel_row, cmap_row);
    }
    display_rows(1, pixel_data, cinfo.image_width, components);
  }

  (*cinfo.methods->input_term) (&cinfo);
  scroll_until_end();
  
  (*cinfo.emethods->free_all) ();

  fclose(cinfo.input_file);

  return 1;
}
