home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / macraysh.sit / Code / Source / image.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-05  |  3.9 KB  |  173 lines

  1. /*
  2.  * image.c
  3.  *
  4.  * Copyright (C) 1989, 1991, Rod G. Bogart, Craig E. Kolb
  5.  * All rights reserved.
  6.  *
  7.  * This software may be freely copied, modified, and redistributed
  8.  * provided that this copyright notice is preserved on all copies.
  9.  *
  10.  * You may not distribute this software, in whole or in part, as part of
  11.  * any commercial product without the express consent of the authors.
  12.  *
  13.  * There is no warranty or other guarantee of fitness of this software
  14.  * for any purpose.  It is provided solely "as is".
  15.  *
  16.  * $Id: image.c,v 4.0 91/07/17 14:33:29 kolb Exp Locker: kolb $
  17.  *
  18.  * $Log:    image.c,v $
  19.  * Revision 4.0  91/07/17  14:33:29  kolb
  20.  * Initial version.
  21.  * 
  22.  */
  23. #include <stdio.h>
  24. #include "common.h"
  25. #include "image.h"
  26.  
  27. Image *image_list = NULL;        /* Linked list of images */
  28.  
  29. Image *
  30. ImageCreate(filename)
  31. char *filename;
  32. {
  33.     Image *new;
  34.  
  35.     new = (Image *)Malloc(sizeof(Image));
  36.     new->filename = strsave(filename);
  37.     new->width = 0;
  38.     new->height = 0;
  39.     new->chan = 0;
  40.     new->data = NULL;
  41.     new->next = image_list;
  42.     image_list = new;
  43.     return new;
  44. }
  45.  
  46. Image *
  47. ImageFind(name)
  48. char *name;
  49. {
  50.     Image *im;
  51.  
  52.     for (im = image_list; im; im = im->next) {
  53.         if (strcmp(im->filename, name) == 0)
  54.             return im;
  55.     }
  56.  
  57.     return (Image *)NULL;
  58. }
  59.  
  60. Image *
  61. ImageRead(filename)
  62. char *filename;
  63. {
  64.     FILE *fp;
  65.     char buf[80];
  66.     Image *image;
  67.     int y, x;
  68.     unsigned char *rbuf, *gbuf, *bbuf;
  69.  
  70.     image = ImageFind(filename);
  71.     if (image)
  72.         return image;
  73.  
  74.     fp = fopen(filename, "r");
  75.     if (fp == (FILE *)NULL) {
  76.         RLerror(RL_ABORT, "Cannot open image file %s.\n",filename,0,0);
  77.         return (Image *)NULL;
  78.     }
  79.  
  80.     image = ImageCreate(filename);
  81.     /*
  82.      * Read image header.
  83.      */
  84.     if (fgets(buf, 100, fp) == (char *)NULL ||
  85.         sscanf(buf, "%d %d\n", &image->width, &image->height) != 2) {
  86.         RLerror(RL_ABORT, "Cannot read header of image file %s.\n",
  87.             filename,0,0);
  88.         fclose(fp);
  89.         return (Image *)NULL;
  90.     }
  91.     /*
  92.      * Generic image files always have 3 channels, no alpha.
  93.      */
  94.     image->chan = image->totalchan = 3;
  95.     image->has_alpha = 0;
  96.     image->chansize = image->width * image->height;
  97.  
  98.     image->data = (unsigned char *) Malloc(
  99.         image->chansize * image->totalchan * sizeof(unsigned char));
  100.  
  101.     rbuf = image->data;
  102.     gbuf = &image->data[image->chansize];
  103.     bbuf = &image->data[image->chansize+image->chansize];
  104.     for (y = 0; y < image->height; y++ ) {
  105.         for (x = 0; x < image->width; x++) {
  106.             *(rbuf++) = getc(fp);
  107.             *(gbuf++) = getc(fp);
  108.             *(bbuf++) = getc(fp);
  109.             if (feof(fp)) {
  110.                 RLerror(RL_ABORT,
  111.                 "Error reading image %s\n",filename,0,0);
  112.                 fclose(fp);
  113.                 return (Image *)NULL;
  114.             }
  115.         }
  116.     }
  117.  
  118.     (void)fclose(fp);
  119.     return image;
  120. }
  121.  
  122. void
  123. ImageIndex(img, ix, iy, fx, fy, smooth, outval)
  124. Image *img;
  125. int ix, iy, smooth;
  126. Float fx, fy;
  127. Float outval[4];
  128. {
  129.     int xplus, yplus, chan, offset;
  130.     Float x0y0, x1y0, x0y1, x1y1;
  131.     unsigned char *data;
  132.  
  133.     if (smooth) {
  134.         /*
  135.          * bi-linear interp of four pixels.  Note this blends
  136.          * the top with the bottom, and the left with the right.
  137.          */
  138.         if (ix == img->width - 1)
  139.             xplus = 1 - img->width;
  140.         else 
  141.             xplus = 1;
  142.         if (iy == img->height - 1)
  143.             yplus = (1 - img->height) * img->width;
  144.         else
  145.             yplus = img->width;
  146.         data = img->data;
  147.         /* compute offset into first channel */
  148.         offset = ix + iy * img->width;
  149.         for (chan = 0; chan < img->totalchan; chan++) {
  150.             x0y0 = (Float)data[offset] / 255.0;
  151.             x1y0 = (Float)data[offset+xplus] / 255.0;
  152.             x0y1 = (Float)data[offset+yplus] / 255.0;
  153.             x1y1 = (Float)data[offset+xplus+yplus]/255.0;
  154.             outval[chan] = (x0y0*(1.0-fx)*(1.0-fy) +
  155.                     x1y0*(fx)*(1.0-fy) +
  156.                     x0y1*(1.0-fx)*(fy) +  x1y1*(fx)*(fy));
  157.             /* Make offset point to next channel */
  158.             offset += img->chansize;
  159.         }
  160.     } else {
  161.         /*
  162.          * Hard edged image pixels (rectangles)
  163.          * Compute offset into first channel
  164.          */
  165.         offset = ix + iy * img->width;
  166.         for (chan = 0; chan < img->totalchan; chan++) {
  167.             outval[chan] = (Float)img->data[offset]/255.0;
  168.             /* Make offset point to next channel */
  169.             offset += img->chansize;
  170.         }
  171.     }
  172. }
  173.