/* GEM-View 3.00 SAVING Modul: Bild als Enhanced Simplex speichern
   (c) 22.10.1993 by Dieter Fiebelkorn
                     Grner Weg 29a
                     D-45768 Marl
                     (GERMANY)
*/

#include <stdio.h>
#include "image.h"
#include "moduls.h"
#include "esm.h"

#define Write(a,b,c,d)  write(d,c,a)



void Save_esm0 (SAVE_Structure *saveS, unsigned int verbose, unsigned int  truecolor)
{
  Image          *image;
  char           *filename;
  unsigned int    windepth;
  int             fd;
  ESM_Header      esm;
  char           *data, out,
                  mask, bbuf[4];
  long            col, line;
  unsigned char  *raster[8];
  long            width, height,
                  RealLine;
  short           planes, plane, i,
                  buf[4] = {0, 0, 0, 0};

  image      = saveS->image;
  filename   = saveS->out_filename;
  windepth   = saveS->screen_depth;

  if ((width = image->unalignwidth) == 0)
    width      = image->width;
  height     = image->height;
  planes     = image->depth;
  
  *(long*)&esm.kennung = 'TMS\0';
  esm.head_size     = sizeof(ESM_Header) + 4 * sizeof(short);
  esm.breite        = width;
  esm.hoehe         = height;
  if (MONOCHROMEP(image)) {
    truecolor       = FALSE;
    esm.tiefe       = 1;
    esm.bildart     = 1;
  }
  if (PALETTEP(image) && !truecolor) {
    esm.tiefe       = 8;
    esm.bildart     = 3;
  }
  if (TRUECOLORP(image) || truecolor) {
    esm.tiefe       = 24;
    esm.bildart     = 3;
  }
  esm.tiefe_rot     = 8;
  esm.tiefe_gruen   = 8;
  esm.tiefe_blau    = 8;
  esm.tiefe_schwarz = 0;
  esm.version       = 4;
  esm.xdpi          = 100;
  esm.ydpi          = 100;
  esm.file_hoehe    = height;
  esm.start_zeile   = 1;
  esm.end_zeile     = height;
  esm.maske         = 0;
  for (col = 0; col < 256; col++)
    esm.rot_tab  [col] = esm.gruen_tab[col] = esm.blau_tab [col] = col;
  if (!truecolor)
    for (col = 0; col < image->rgb.used; col++) {
      esm.rot_tab  [col] = (char)(image->rgb.red  [col] >> 8);
      esm.gruen_tab[col] = (char)(image->rgb.green[col] >> 8);
      esm.blau_tab [col] = (char)(image->rgb.blue [col] >> 8);
    }
  
  saveS->print.printout ("  Saving Enhanced-SiMplex Image '%s' ... ", filename);

  if ((fd = saveS->output.open(filename)) > 0) {
    if (saveS->output.Write(&esm, 1L, sizeof(ESM_Header), fd) != sizeof(ESM_Header))
      goto CloseAndRemove;
    if (saveS->output.Write(&buf, 1L, 4L * sizeof(short), fd) != 4L * sizeof(short))
      goto CloseAndRemove;


    if (MONOCHROMEP(image)) {
      width = (width >> 3) + (width & 0x0007 ? 1 : 0);
      width <<= 3;
      RealLine = (width >> 4) + ((width & 0x000F) ? 1 : 0);
      RealLine *= 2;
      data = image->data;
      for (line = 0; line < height; line++) {
        if (saveS->output.Write(data, 1L, width / 8, fd) != width / 8)
          goto CloseAndRemove;
        data += RealLine;
      }
    }
    
    if (ATARI_RGBP(image)) {
      RealLine = (width >> 4) + ((width & 0x000F) ? 1 : 0);
      RealLine *= 2;
      for (line = 0; line < height; line++) {
        raster[0] = image->data + ((long)line * RealLine);
        for (plane = 1; plane < planes; plane++)
          raster[plane] = raster[plane-1] + (long)RealLine * height;

        mask = 0x80;
        col = 0;
        for (i = 0; i < width; i++) {
          out = 0;
          for (plane = 0; plane < planes; plane++) {
            if (raster[plane][col] & mask)
              out |= (1U << plane);
          }
          mask >>= 1;
          if (!truecolor) {
            if (saveS->output.Write(&out, 1L, 1L, fd) != 1L)
              goto CloseAndRemove;
          } else {
            bbuf[0] = (char)(image->rgb.red  [out] >> 8);
            bbuf[1] = (char)(image->rgb.green[out] >> 8);
            bbuf[2] = (char)(image->rgb.blue [out] >> 8);
            if (saveS->output.Write(bbuf, 1L, 3L, fd) != 3L)
              goto CloseAndRemove;
          }

          if (mask == 0) {
            mask = 0x80;
            col++;
          }
        }
      }
    }

    if (RGBP(image)) {
      RealLine = (width >> 4) + ((width & 0x000F) ? 1 : 0);
      RealLine <<= 4;
      data = image->data;
      for (line = 0; line < height; line++) {
        if (!truecolor) {
          if (saveS->output.Write(data, 1L, width, fd) != width)
            goto CloseAndRemove;
        } else {
          for (i = 0; i < width; i++) {
            out = data[i];
            bbuf[0] = (char)(image->rgb.red  [out] >> 8);
            bbuf[1] = (char)(image->rgb.green[out] >> 8);
            bbuf[2] = (char)(image->rgb.blue [out] >> 8);
            if (saveS->output.Write(bbuf, 1L, 3L, fd) != 3L)
              goto CloseAndRemove;
          }
        }
        data += RealLine;
      }
    }

    if (TRUECOLORP(image)) {
      RealLine = (width >> 4) + ((width & 0x000F) ? 1 : 0);
      RealLine <<= 4;
      RealLine *= 3;
      data = image->data;
      for (line = 0; line < height; line++) {
        if (saveS->output.Write(data, 1L, 3L * width, fd) != 3L * width)
          goto CloseAndRemove;
        data += RealLine;
      }
    }


    if (saveS->output.close(fd) != 0) {
      fd = 0;
      goto CloseAndRemove;
    }
    saveS->print.printout ("done.\n");
    return;
  }
  
CloseAndRemove:
  saveS->events.alert(1, "[3][ | Error in writing!  | |    Disk full ? ][   OK   ]");
  if (fd > 0)
    saveS->output.close(fd);
  saveS->output.delete(filename);
  saveS->print.printout ("error.\n");
  return;
}



void Save_esm (SAVE_Structure *saveS, unsigned int verbose)
{
  Save_esm0 (saveS, verbose, FALSE);
}
