/* ppm.c - load PPM image from file
 * 
 *  Raster graphics library
 * 
 *  Copyright (c) 1997-2002 Alfredo K. Kojima
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Library General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *  
 *  This library 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
 *  Library General Public License for more details.
 *  
 *  You should have received a copy of the GNU Library General Public
 *  License along with this library; if not, write to the Free
 *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <config.h>


#include <X11/Xlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "wraster.h"


static RImage*
load_graymap(char *file_name, FILE *file, int w, int h, int max, int raw)
{
    RImage *image;
    
    image = RCreateImage(w, h, 0);
    if (!image) {
	return NULL;
    }
    if (!raw) {
	
    } else {
	if (max<256) {
	    int x, y;
	    char *buf, *ptr;
	    
	    buf = malloc(w+1);
	    if (!buf) {
		return NULL;
	    }
	    
	    ptr = image->data;
	    for (y = 0; y < h; y++) {
                if (!fread(buf, w, 1, file)) {
		    free(buf);
		    goto short_file;
		}
		for (x = 0; x < w; x++) {
		    *(ptr++) = buf[x];
		    *(ptr++) = buf[x];
		    *(ptr++) = buf[x];
		}
	    }
	    free(buf);
	} else {
	    
	}
    }
    
    return image;
    
  short_file:
    RErrorCode = RERR_BADIMAGEFILE;
    return NULL;
}


static RImage*
load_pixmap(char *file_name, FILE *file, int w, int h, int max, int raw)
{
    RImage *image;
    int i;
    char buf[3];
    char *ptr;
    
    image = RCreateImage(w, h, 0);
    if (!image) {
	return NULL;
    }
    ptr = image->data;
    if (!raw) {
	
    } else {
	if (max<256) {
	    i = 0;
	    while (i < w*h) {
		if (fread(buf, 1, 3, file)!=3)
		    goto short_file;
		*(ptr++) = buf[0];
		*(ptr++) = buf[1];
		*(ptr++) = buf[2];
		i++;
	    }
	} else {
	    
	}
    }
    
    return image;
    
  short_file:
    RErrorCode = RERR_BADIMAGEFILE;
    return NULL;
}


RImage*
RLoadPPM(RContext *context, char *file_name, int index)
{
    FILE *file;
    RImage *image = NULL;
    char buffer[256];
    int w, h, m;
    int type;

#define GETL() if (!fgets(buffer, 255, file)) goto short_file
    
    file = fopen(file_name, "r");
    if (!file) {
	RErrorCode = RERR_OPEN;
	return NULL;
    }
    
    /* get signature */
    GETL();

    /* only accept raw pixmaps or graymaps */
    if (buffer[0] != 'P' || (buffer[1] != '5' && buffer[1] != '6')) {
	RErrorCode = RERR_BADFORMAT;
	fclose(file);
	return NULL;
    }
    
    type = buffer[1];
    
    /* skip comments */
    while (1) {
	GETL();
	
	if (buffer[0]!='#')
	    break;
    }
    
    /* get size */
    if (sscanf(buffer, "%i %i", &w, &h)!=2)
	goto bad_file;
    

    GETL();
    if (sscanf(buffer, "%i", &m)!=1 || m < 1)
	goto bad_file;

    if (type=='5')
	image = load_graymap(file_name, file, w, h, m, type=='5');
    else if (type=='6')
	image = load_pixmap(file_name, file, w, h, m, type=='6');

    fclose(file);
    return image;
    
  bad_file:
  short_file:
    RErrorCode = RERR_BADIMAGEFILE;
    fclose(file);
    return NULL;
}

