home *** CD-ROM | disk | FTP | other *** search
- /*
- * image.c
- *
- * Copyright (C) 1989, 1991, Rod G. Bogart, Craig E. Kolb
- * All rights reserved.
- *
- * This software may be freely copied, modified, and redistributed
- * provided that this copyright notice is preserved on all copies.
- *
- * You may not distribute this software, in whole or in part, as part of
- * any commercial product without the express consent of the authors.
- *
- * There is no warranty or other guarantee of fitness of this software
- * for any purpose. It is provided solely "as is".
- *
- * $Id: image.c,v 4.0 91/07/17 14:33:29 kolb Exp Locker: kolb $
- *
- * $Log: image.c,v $
- * Revision 4.0 91/07/17 14:33:29 kolb
- * Initial version.
- *
- */
- #include <stdio.h>
- #include "common.h"
- #include "image.h"
-
- Image *image_list = NULL; /* Linked list of images */
-
- Image *
- ImageCreate(filename)
- char *filename;
- {
- Image *new;
-
- new = (Image *)Malloc(sizeof(Image));
- new->filename = strsave(filename);
- new->width = 0;
- new->height = 0;
- new->chan = 0;
- new->data = NULL;
- new->next = image_list;
- image_list = new;
- return new;
- }
-
- Image *
- ImageFind(name)
- char *name;
- {
- Image *im;
-
- for (im = image_list; im; im = im->next) {
- if (strcmp(im->filename, name) == 0)
- return im;
- }
-
- return (Image *)NULL;
- }
-
- Image *
- ImageRead(filename)
- char *filename;
- {
- FILE *fp;
- char buf[80];
- Image *image;
- int y, x;
- unsigned char *rbuf, *gbuf, *bbuf;
-
- image = ImageFind(filename);
- if (image)
- return image;
-
- fp = fopen(filename, "r");
- if (fp == (FILE *)NULL) {
- RLerror(RL_ABORT, "Cannot open image file %s.\n",filename,0,0);
- return (Image *)NULL;
- }
-
- image = ImageCreate(filename);
- /*
- * Read image header.
- */
- if (fgets(buf, 100, fp) == (char *)NULL ||
- sscanf(buf, "%d %d\n", &image->width, &image->height) != 2) {
- RLerror(RL_ABORT, "Cannot read header of image file %s.\n",
- filename,0,0);
- fclose(fp);
- return (Image *)NULL;
- }
- /*
- * Generic image files always have 3 channels, no alpha.
- */
- image->chan = image->totalchan = 3;
- image->has_alpha = 0;
- image->chansize = image->width * image->height;
-
- image->data = (unsigned char *) Malloc(
- image->chansize * image->totalchan * sizeof(unsigned char));
-
- rbuf = image->data;
- gbuf = &image->data[image->chansize];
- bbuf = &image->data[image->chansize+image->chansize];
- for (y = 0; y < image->height; y++ ) {
- for (x = 0; x < image->width; x++) {
- *(rbuf++) = getc(fp);
- *(gbuf++) = getc(fp);
- *(bbuf++) = getc(fp);
- if (feof(fp)) {
- RLerror(RL_ABORT,
- "Error reading image %s\n",filename,0,0);
- fclose(fp);
- return (Image *)NULL;
- }
- }
- }
-
- (void)fclose(fp);
- return image;
- }
-
- void
- ImageIndex(img, ix, iy, fx, fy, smooth, outval)
- Image *img;
- int ix, iy, smooth;
- Float fx, fy;
- Float outval[4];
- {
- int xplus, yplus, chan, offset;
- Float x0y0, x1y0, x0y1, x1y1;
- unsigned char *data;
-
- if (smooth) {
- /*
- * bi-linear interp of four pixels. Note this blends
- * the top with the bottom, and the left with the right.
- */
- if (ix == img->width - 1)
- xplus = 1 - img->width;
- else
- xplus = 1;
- if (iy == img->height - 1)
- yplus = (1 - img->height) * img->width;
- else
- yplus = img->width;
- data = img->data;
- /* compute offset into first channel */
- offset = ix + iy * img->width;
- for (chan = 0; chan < img->totalchan; chan++) {
- x0y0 = (Float)data[offset] / 255.0;
- x1y0 = (Float)data[offset+xplus] / 255.0;
- x0y1 = (Float)data[offset+yplus] / 255.0;
- x1y1 = (Float)data[offset+xplus+yplus]/255.0;
- outval[chan] = (x0y0*(1.0-fx)*(1.0-fy) +
- x1y0*(fx)*(1.0-fy) +
- x0y1*(1.0-fx)*(fy) + x1y1*(fx)*(fy));
- /* Make offset point to next channel */
- offset += img->chansize;
- }
- } else {
- /*
- * Hard edged image pixels (rectangles)
- * Compute offset into first channel
- */
- offset = ix + iy * img->width;
- for (chan = 0; chan < img->totalchan; chan++) {
- outval[chan] = (Float)img->data[offset]/255.0;
- /* Make offset point to next channel */
- offset += img->chansize;
- }
- }
- }
-