 /*
  * Khoros: $Id: lrast2viff.c,v 1.3 1992/03/20 23:35:34 dkhoros Exp $
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id: lrast2viff.c,v 1.3 1992/03/20 23:35:34 dkhoros Exp $";
#endif

 /*
  * $Log: lrast2viff.c,v $
 * Revision 1.3  1992/03/20  23:35:34  dkhoros
 * VirtualPatch5
 *
  */ 

/*
 *----------------------------------------------------------------------
 *
 * Copyright 1991, University of New Mexico.  All rights reserved.
 * Permission to copy and modify this software and its documen-
 * tation only for internal use in your organization is hereby
 * granted, provided that this notice is retained thereon and
 * on all copies.  UNM makes no representations as too the sui-
 * tability and operability of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
 * 
 * UNM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
 * NESS.  IN NO EVENT SHALL UNM BE LIABLE FOR ANY SPECIAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY OTHER DAMAGES WHAT-
 * SOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PER-
 * FORMANCE OF THIS SOFTWARE.
 * 
 * No other rights, including for example, the right to redis-
 * tribute this software and its documentation or the right to
 * prepare derivative works, are granted unless specifically
 * provided in a separate license agreement.
 *---------------------------------------------------------------------
 */

#include "unmcopyright.h"        /* Copyright 1991 by UNM */

/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 >>>>
 >>>>         File Name: lrast2viff.c
 >>>>
 >>>>      Program Name: rast2viff
 >>>>
 >>>> Date Last Updated: Sat Mar  2 14:34:56 1991 
 >>>>
 >>>>          Routines: lrast2viff - the library call for rast2viff
 >>>>
 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/


#include "vinclude.h"


/* -library_includes */

#include "file_formats/rast.h"
#include "vrev.h"

/* -library_includes_end */


/****************************************************************
*
* Routine Name: lrast2viff - library call for rast2viff
*
* Purpose:
*    
*    converts a SUN raster image to the VIFF image format
*    
*    
* Input:
*    
*    Input to lrast2viff :
*    
*    rast_image     A SUN raster image of type struct  rast  that  has
*                   the  correct byte order for the machine processing
*                   the image
*    
*    invert_flag    resulting image is  either  photopositive  (1)  or
*                   photonegaative (0)
*    
*    
* Output:
*    
*    viff_image     A pointer to struct xvimage, this image will  con-
*                   tain the converted image from SUN rast to VIFF.
*    
*    
*
* Written By: Tom Sauer
*    
*    
****************************************************************/


/* -library_def */
int
lrast2viff (rast_image, viff_image, invert_flag)
struct rast *rast_image;
struct xvimage **viff_image;
int invert_flag;
/* -library_def_end */

/* -library_code */
{

    int     width, height, depth, imagetype, maptype, maplen;
    int     data_type, bands, map_row, map_col, map_scheme, map_stor, model;
    int     i, num_bytes;
    unsigned char  *rast_ptr, *data, *r_ptr, *g_ptr, *b_ptr;
    char   *program = "lrast2viff";
    struct xvimage *img, *createimage ();

    /* read Sun Raster header */
    if (rast_image -> ras_magic != RAS_MAGIC)
    {
        fprintf (stderr,"%s: Input image is not a Sun Raster file.\n", program);
        return (0);
    }

    width = rast_image->ras_width;
    height = rast_image->ras_height;
    depth = rast_image->ras_depth;
    imagetype = rast_image->ras_type;
    maptype = rast_image->ras_maptype;
    maplen = rast_image->ras_maplength;

    /* set up VIFF header */
    if ((imagetype != RT_OLD) && (imagetype != RT_STANDARD))
    {
        fprintf (stderr,"%s: Raster image is stored in an unsupported format.\n"
                ,program);
        fprintf (stderr, "Should be either RT_OLD or RT_STANDARD.\n");
        return (0);
    }

    switch (depth)
    {
        case 1: 
            data_type = (int) VFF_TYP_BIT;
            bands = 1;
            break;
        case 8: 
            data_type = (int) VFF_TYP_1_BYTE;
            bands = 1;
            break;
        case 24: 
            data_type = (int) VFF_TYP_1_BYTE;
            bands = 3;
            break;
        default: 
            fprintf (stderr, "%s: Invalid image depth.\n", program);
            fprintf (stderr, "Should be either 1, 8, or 24.\n");
            return (0);
            break;
    }

    switch (maptype)
    {
        case RMT_NONE: 
            map_row = 0;
            map_col = 0;
            map_scheme = VFF_MS_NONE;
            map_stor = VFF_MAPTYP_NONE;
            if (depth == 24) 
               model = VFF_CM_genericRGB;
            else
               model = VFF_CM_NONE;
            break;
        case RMT_EQUAL_RGB: 
            map_row = 3;
            map_col = maplen/3;
            map_scheme = VFF_MS_ONEPERBAND;
            map_stor = VFF_MAPTYP_1_BYTE;
            model = VFF_CM_genericRGB;
            break;
        case RMT_RAW: 
            fprintf (stderr, 
                    "%s: Raw Sun Raster images are not supported.\n", program);
            return (0);
            break;
        default: 
            fprintf (stderr, "%s: Invalid map type.\n", program);
            fprintf (stderr, "Should be either RMT_NONE or RMT_EQUAL_RGB\n");
            return (0);
            break;
    }

    /* create new image space with header info */
    img = createimage ((unsigned long) height,       /* number of rows    */
            (unsigned long) width,                   /* number of columns */
            (unsigned long) data_type,               /* data_storage_type */
            (unsigned long) 1,                       /* num_of_images     */
            (unsigned long) bands,                   /* num_data_bands    */
            "This is a converted Sun Raster image.", /* comment o         */
            (unsigned long) map_row,                 /* map_row_size      */
            (unsigned long) map_col,                 /* map_col_size      */
            (unsigned long) map_scheme,              /* map_scheme        */
            (unsigned long) map_stor,                /* map_storage_type  */
            (unsigned long) VFF_LOC_IMPLICIT,        /* location_type     */
            (unsigned long) 0);                      /* dimension         */
    *viff_image = img;
    if (img == NULL)
    {
        fprintf (stderr, "%s: Unable to allocate space for the new image.\n",
                program);
        return (0);
    }

    /* set color_space_model */
    img->color_space_model = model;

    /* convert image and possible map data to VIFF format */
    rast_ptr = (unsigned char *) rast_image -> data;

    switch (depth)
    {
        case 1: 
            /* transfer the image data while reversing the order of
               the bits */
	    data = (unsigned char *) img->imagedata;
            num_bytes = (width+7)/8;
            for (i = 0; i < num_bytes*height; i++)
            {
               if (invert_flag)
                  data[i] = ~(rev[*rast_ptr]);
               else
                  data[i] = rev[*rast_ptr];
               rast_ptr++;

               if (i % num_bytes == 0 && num_bytes % 2 == 1 && i != 0)
                  rast_ptr++;
            }
            break;
        case 8: 
            if (maplen != 0)
                bcopy (rast_ptr, img->maps, maplen);

                  /* transfer image data */
            rast_ptr = rast_ptr + maplen;
            data = (unsigned char *) img->imagedata;
            for (i = 0; i < width*height; i++)
            {
                *data++ = *rast_ptr; rast_ptr++;
                if (i % width == 0 && width % 2 == 1 && i != 0)
                   rast_ptr++;
            }
            break;
        case 24: 
            r_ptr = (unsigned char *) (&img -> imagedata[0]);
            g_ptr = (unsigned char *) (&img -> imagedata[height * width]);
            b_ptr = (unsigned char *) (&img -> imagedata[height * width * 2]);

            /* transfer image that is stored in red-byte, green-byte,
               blue-byte order to all red followed by all green followed
               by all blue */

            for (i = 0; i < width*height; i++)
            {
                *r_ptr++ = *rast_ptr; rast_ptr++;
                *g_ptr++ = *rast_ptr; rast_ptr++;
                *b_ptr++ = *rast_ptr; rast_ptr++;
                if (i % width == 0 && 3*width % 2 == 1 && i != 0)
                   rast_ptr++;
            }
            break;
    }
    return (1);
}

/* -library_code_end */
