 /*
  * Khoros: $Id: lvextract.c,v 1.2 1991/12/18 09:22:33 dkhoros Exp $
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id: lvextract.c,v 1.2 1991/12/18 09:22:33 dkhoros Exp $";
#endif

 /*
  * $Log: lvextract.c,v $
 * Revision 1.2  1991/12/18  09:22:33  dkhoros
 * HellPatch3
 *
  */

/*
 *----------------------------------------------------------------------
 *
 * 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 to 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: lvextract.c
 >>>>
 >>>>      Program Name: vextract
 >>>>
 >>>> Date Last Updated: Thu Nov  7 11:59:22 1991 
 >>>>
 >>>>          Routines: lvextract - the library call for vextract
 >>>>
 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/


#include "vinclude.h"


/* -library_includes */
#define NUM_OF_IMAGES 1
/* -library_includes_end */


/****************************************************************
*
* Routine Name: lvextract - library call for vextract
*
* Purpose:
*    
*    Extract a rectangular piece from an image and put  it  in  a
*    subimage
*    
*    

* Input:
*    
*    img1           the input xvimage structure
*    
*    xoff           the x offset from the upper left  hand  corner  of
*                   the input image.
*    
*    yoff           the y offset from the upper left  hand  corner  of
*                   the input image.
*    
*    width          the row_size of the output image
*    
*    height         the col_size of the output image
*    
*    copymapflag    copy map only if set
*    
*    

* Output:
*    
*    *img2          holds the result of the extract operation.
*    
*    

*
* Written By: John Rasure, Mark Young
*    
*    John Rasure Fri Mar 24 15:25:53  MST  1989  included  createimage
*    call, and added flag for the option of copying map data.
*    
*    Mark Young - Re-wrote extract loop to use bcopy  instead  of  for
*    loops.
*    
*    

****************************************************************/


/* -library_def */
int
lvextract(img1, img2, width, height, xoff, yoff, copymapflag)
struct xvimage *img1, **img2;
unsigned long width, height, xoff, yoff, copymapflag;
/* -library_def_end */

/* -library_code */
{
        char     *cptr1, *cptr2;
        int      i, j, rows, cols, map_scheme;
        int      row_size, nrow_size, size, nsize, xoffset;
        struct xvimage *result, *createimage();
        char *program="lvextract";

        rows = img1->col_size;
        cols = img1->row_size;

        if (width <= 0 || height <= 0 )
        {
           (void) fprintf(stderr,"%s: Subimage must be larger than 0!\n",
                          program);
           return(0);
        }

        if (width > cols || height > rows )
        {
           (void) fprintf(stderr,"%s: Subimage larger than image!\n", program);
           return(0);
        }

        if (xoff > cols || yoff > rows )
        {
           (void) fprintf(stderr,"%s: Subimage offset is outside of original \
image!\n", program);
           return(0);
        }

        /*  check to see that subimage does not extend beyond image */
        if (width + xoff > cols )  width = cols - xoff;
        if (height + yoff > rows ) height = rows - yoff ;


        /*  malloc space and assign header field values for new image */
        if (!copymapflag)
           map_scheme = VFF_MS_NONE;
        else
           map_scheme = img1->map_scheme;

        result = createimage(height, width, img1->data_storage_type,
                        NUM_OF_IMAGES, img1->num_data_bands, img1->comment,
                        img1->map_row_size, img1->map_col_size,
                        map_scheme, img1->map_storage_type,
                        img1->location_type, img1->location_dim);

        /* fix up the rest of the header information */
        result->startx              = xoff;
        result->starty              = yoff;
        result->pixsizx             = img1->pixsizx  ;
        result->pixsizy             = img1->pixsizy  ;
        result->data_encode_scheme  = img1->data_encode_scheme ;
        result->map_enable          = img1->map_enable ;
        result->color_space_model   = img1->color_space_model ;
        result->subrow_size         = img1->subrow_size ;

        /* copy map data from img1 to result if flag set */
        if ( copymapflag == TRUE ) 
        {
           if ( ! copymapdata(img1, &result, FALSE) ) 
           {
              (void) fprintf(stderr,"%s: Could not copy map data!\n", program);
              return(0);
           }
        }

        /* copy location data if explicit */
        if ( img1->location_type == VFF_LOC_EXPLICIT)
        {
           if ( !  copylocationdata(img1, result, 0))
           {
              (void) fprintf(stderr,"%s: Could not copy location data!\n",
                             program);
              return(0);
           }
        }


        /*
         *  Now it's time to copy the image "img1" into our extracted image.
         */
        row_size  = viff_rowsize(img1->data_storage_type, cols);
        nrow_size = viff_rowsize(img1->data_storage_type, width);
        xoffset   = viff_rowsize(img1->data_storage_type, xoff);

        size  = row_size*rows;
        nsize = nrow_size*height;
        for (i = 0; i < img1->num_data_bands; i++)
        {
            cptr1 = img1->imagedata + size*i + yoff*row_size + xoffset;
            cptr2 = result->imagedata + nsize*i;
            for (j = 0; j < height; j++)
            {
                bcopy(cptr1, cptr2, nrow_size);
                cptr1 += row_size;
                cptr2 += nrow_size;
            }
        }
        *img2 = result;
        return(1);
}
/* -library_code_end */
