
/* Copyright (C) 1992  AHPCRC, Univeristy of Minnesota
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program in a file named 'Copying'; if not, write to
 * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139.
 */

/* Author:
 *	Ken Chin-Purcell (ken@ahpcrc.umn.edu)
 *	Army High Performance Computing Research Center (AHPCRC)
 *	Univeristy of Minnesota
 *
 * $Header: /usr/people/ken/gvl/icol/RCS/file.c,v 2.1 92/10/19 16:59:31 ken Exp $
 *
 * $Log:	file.c,v $
 * Revision 2.1  92/10/19  16:59:31  ken
 * *** empty log message ***
 * 
 * Revision 1.1  92/10/19  16:58:11  ken
 * Initial revision
 * 
 */

#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <math.h>

#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>

#include "util.h"
#include "rgb.h"
#include "xtutil.h"
#include "cbar.h"
#include "file.h"


static void ReadLongArray(long *larr, int n, FILE *file)
{
    int		i;

    for (i = 0; i < n; i++) {
	if (fscanf(file, "%ld", larr+i) < 1)
	    break;
    }
    for ( ; i < n; i++)
	larr[i] = 0;
}


static void IndexOut(FILE *file, char *fmt, ColorBar *cbar, int i)
{
    float	r, g, b;
    
    GetRGB(cbar, i, &r, &g, &b);
    (void) fprintf(file, fmt, i, (int)(r*255), (int)(g*255), (int)(b*255));
}


static void PlainOut(FILE *file, char *fmt, ColorBar *cbar, int i)
{
    float	r, g, b;
    
    GetRGB(cbar, i, &r, &g, &b);
    (void) fprintf(file, fmt, (int)(r*255), (int)(g*255), (int)(b*255));
}


int FileSaveBar(ColorBar *cbar, char *fname, FileFormat format)
{
    FILE		*file;
    unsigned		i, j, k;
    float		r, g, b;
    unsigned char	*c;
    
    if (strcmp(fname, "-") == 0)
	file = stdout;
    else
	file = fopen(fname, "w");
    if (!file)
	return 0;
    
    switch (format) {

      case ASCII_INDEX:
	j = cbar->ncolor / 4;
	for (i = 0; i < j; ++i) {
	    IndexOut(file, "%4d%4d%4d%4d   ", cbar, i);
	    IndexOut(file, "%4d%4d%4d%4d   ", cbar, i + j);
	    IndexOut(file, "%4d%4d%4d%4d   ", cbar, i + 2*j);
	    IndexOut(file, "%4d%4d%4d%4d\n",  cbar, i + 3*j);
	}
	break;
	
      case ASCII_PLAIN:
	for (i = 0; i < cbar->ncolor; ++i)
	    PlainOut(file, "%4d%4d%4d\n",  cbar, i);
	break;

      case BIN_LEAVE:
	c = CallocType(unsigned char, 3*cbar->ncolor);
	MemCheck(c);
	for (i = 0, j = 0; i < cbar->ncolor; ++i, j += 3) {
	    GetRGB(cbar, i, &r, &g, &b);
	    c[j  ] = r * 255;
	    c[j+1] = g * 255;
	    c[j+2] = b * 255;
	}
	(void) fwrite(c, cbar->ncolor, 3, file);
	free(c);
	break;

      case BIN_ROW:
	c = CallocType(unsigned char, 3 * cbar->ncolor);
	MemCheck(c);
	for (i = 0, j = cbar->ncolor, k = 2*cbar->ncolor;
	     i < cbar->ncolor; ++i, ++j, ++k) {
	    GetRGB(cbar, i, &r, &g, &b);
	    c[i] = r * 255;
	    c[j] = g * 255;
	    c[k] = b * 255;
	}
	(void) fwrite(c, cbar->ncolor, 3, file);
	free(c);
	break;
    }

    i = ferror(file);
    if (file == stdout)
	(void) fflush(file);
    else
	(void) fclose(file);

    return i == 0;
}


int FileOpenBar(ColorBar *cbar, char *fname, FileFormat format)
{
    FILE		*file;
    unsigned		i, j;
    unsigned char	*c;
    long		*l;
    
    if (strcmp(fname, "-") == 0)
	file = stdin;
    else
	file = fopen(fname, "r");
    if (!file)
	return 0;
    
    switch (format) {

      case ASCII_INDEX:
	j = 4 * cbar->ncolor;
	l = CallocType(long, j);	
	MemCheck(l);
	ReadLongArray(l, j, file);
	for (i = 0; i < j; i += 4) {
	    l[i] = MAX(l[i], 0);
	    l[i] = MIN(l[i], cbar->ncolor - 1);
	    PutRGB(cbar, l[i], l[i+1]/255.0, l[i+2]/255.0, l[i+3]/255.0);
	}
	free(l);
	break;
	
      case ASCII_PLAIN:
	j = 3 * cbar->ncolor;
	l = CallocType(long, j);	
	MemCheck(l);
	ReadLongArray(l, j, file);
	for (i = 0; i < j; i += 3)
	    PutRGB(cbar, i/3, l[i]/255.0, l[i+1]/255.0, l[i+2]/255.0);
	free(l);
	break;

      case BIN_LEAVE:
	j = 3 * cbar->ncolor;
	c = CallocType(unsigned char, j);
	MemCheck(c);
	(void) memset(c, 0, j);
	(void) fread(c, j, 1, file);
	for (i = 0; i < j; i += 3)
	    PutRGB(cbar, i/3, c[i]/255.0, c[i+1]/255.0, c[i+2]/255.0);
	free(c);
	break;

      case BIN_ROW:
	j = cbar->ncolor;
	c = CallocType(unsigned char, 3*j);
	MemCheck(c);
	(void) memset(c, 0, 3*j);
	(void) fread(c, j, 3, file);
	for (i = 0; i < j; ++i)
	    PutRGB(cbar, i, c[i]/255.0, c[i+j]/255.0, c[i+2*j]/255.0);
	free(c);
	break;
    }

    i = ferror(file);
    if (file != stdin)
	(void) fclose(file);

    return i == 0;
}


