[comp.sys.sgi] Creating Image Files

dahl@tahoe.unr.edu (Michael Dahl) (10/03/90)

I want to produce, from within my application, image files of the format
produced by snapshot(1).  Can anyone tell me the file format?

blbates@AERO4.LARC.NASA.GOV ("Brent L. Bates AAD/TAB MS361 x42854") (10/04/90)

  Go to /usr/people/4Dgifts/iristools/imgtools, the source file
scrsave.c is what snapshot uses to save the screen.
--

	Brent L. Bates
	NASA-Langley Research Center
	M.S. 361
	Hampton, Virginia  23665-5225
	(804) 864-2854
	E-mail: blbates@aero4.larc.nasa.gov or blbates@aero2.larc.nasa.gov

xxjgh@dali.lerc.nasa.gov (Jay G. Horowitz) (10/04/90)

In article <9010031654.AA15425@aero4.larc.nasa.gov> blbates@AERO4.LARC.NASA.GOV ("Brent L. Bates AAD/TAB MS361 x42854") writes:
>
>  Go to /usr/people/4Dgifts/iristools/imgtools, the source file
>scrsave.c is what snapshot uses to save the screen.

WARNING to those looking towards scrsave as an answer to their screen-saving
******* problem:

Do not be fooled by the apparent simplicity(?) of scrsave.c. There is an
undocumented subtlety in its usage. From our experiences it is crucial
that the code within scrsave (or a user-modifications of it) not be imbedded
directly in a program that uses a graphics port. Note that scrsave runs
with noport(); winopen();. Snapshot and others that require a graphics
port to allow you do establish your capture window, eventually do a:

	system ("scrsave 0 1280 0"); /* or whatever xmin, xmax, ymin, ymax */

which spawns a new process.

I assume that doing a succesfull screen capture (i.e., capture pixel rgb
regardless whether that pixel was colormap, rgb, window border, background,
or whatever) can only be done by a process that is not tied to a particular
window. I can kind of guess why this would be so, but haven't invested
the time to really understand it. I got my application to work and quit
while I was ahead.

If the above is incorrect I would appreciate being humbled on the network
by an appropriate guru.

--
..........................................................................
  Jay G. Horowitz                    "For the finest in kosher pixels!"
  NASA Lewis Research Center        
  (216) 433-5194                    xxjgh@dali.lerc.nasa.gov (128.156.1.48)
..........................................................................

" ratcliffe) (10/04/90)

In article <4671@tahoe.unr.edu> dahl@tahoe.unr.edu (Michael Dahl) writes:
>
>I want to produce, from within my application, image files of the format
>produced by snapshot(1).  Can anyone tell me the file format?

hi Michael-

  a boatload o' worms you sail in w/here with but i'll try to give it a go:

so snapshot uses the ubiquitous gl_readscreen (see the post i just sent out
before this one responding to a query about wanting more info on this un-
documented GL call) to go read, scanline by scanline, whatever area of the
screen is specified and, returns RGB triples for each pixel into the three 
red green and blue arrays gl_readscreen gets called with.  unfortunately
the request for information on the format of the equally ubiquitous
"SGI imagelib image" -type files betrays the dangling embarrassment that 
this information has never been adequately documented...

without being able to give you a blow-blow, technically inclusive 
specification of this format, here are some of the most salient points.  
(please know that i am, at this moment engaged in trying to work with 
those in the know, to once and for all create the ultimate document on 
the iris image libraries which *will* contain the details about the
creation and manipulation of "SGI imagelib image" files.  regretably, 
i am unable at this time to tell you when this will be completed.)

    refer to the IMAGE structure in /usr/include/gl/image.h
    this is the meat of what you are asking about.   the IMAGE structure
    *is* the header for every file created by snapshot/icut/scrsave which
    calls gl_readscreen.  

    if you haven't already found it, see /usr/people/4Dgifts/iristools.
    this subtree under the 4Dgifts sample source code user account contains
    all the source you are wondering about (~4Dgifts/iristools/libimage/*
    contains all the source that builds the library /usr/lib/libimage.a,
    ~4Dgifts/iristools/libgutil contains all the source that builds the
    library /usr/lib/libgutil.a).  this subtree is still in a process of 
    "evolvement" and its lack of documentation is an area we in support 
    engineering are painfully aware of and are trying to correct.  (if 
    you can't find /usr/people/4Dgifts on yer machine it's because no one
    has ever gone into manual mode while running the installation tool
    and explicitly tagged "dev.sw.giftssrc" for loading.  see the 
    description in the Release and Installation Notes document for how to 
    do this from the DEVelopment tape.)

    in essence you want to fold the guts of 

                 ~4Dgifts/iristools/imgtools/writeimg.c

    into yer own code.  this standalone "lobotomized" example program creates
    the SGI imagelib image file format you are seeking.  lets briefly examine 
    writeimg.c:
-----------------------------------------------------
/*
 *    writeimg -
 *          Write out an RGB image file.  This example uses three functions
 *    from the image library: 
 *
 *              iopen, putrow, and iclose.        
 *
 *    The function iopen is called to describe the xsize and ysize of the 
 *    RGB image to be written out.  
 *
 *    The function putrow writes a row of image data to the image file. It is
 *    called with an array of shorts with values in the range [0..255].
 *        
 *    The function iclose is called to close the image file.
 *
 *    Why not modify this program to be a filter that converts from your own
 *    image file format to IRIS images? 
 *
 *                                Paul Haeberli - 1987
 *
 */
#include "image.h"

unsigned short rbuf[4096];
unsigned short gbuf[4096];
unsigned short bbuf[4096];

main(argc,argv)
int argc;
char **argv;
{
    int y;
    int xsize, ysize;
    IMAGE *image;

    if(argc<4) {
        fprintf(stderr,"usage writeimg name xsize ysize\n");
        exit(1);
    }
    xsize = atoi(argv[2]);
    ysize = atoi(argv[3]);
    image = iopen(argv[1],"w",RLE(1),3,xsize,ysize,3);
    for(y=0; y<ysize; y++) {
        /*
                fill rbuf, gbuf, and bbuf with pixel values 
        */
        putrow(image,rbuf,y,0);                /* red row */
        putrow(image,gbuf,y,1);                /* green row */
        putrow(image,bbuf,y,2);                /* blue row */
    }
    iclose(image);
}
-----------------------------------------------------
so you will obviously been assigning yer own "xsize/ysize" values.
the iopen call is half of the core functionality (its source can be 
found in ~4Dgifts/iristools/open.c):

       IMAGE *iopen(file, mode [, type, dim, xsize, ysize, zsize])
       char *file;
       register char *mode;
       unsigned int type, dim, xsize, ysize, zsize;

             To open an image file for writing, iopen should be
        called with 7 arguments:  the name of the image file to open,
        and a mode of "w", followed by the type, the number of
        dimensions and the xsize, ysize and zsize of the image.  The 
	type indicates how many bytes are stored per pixel value, 
	and whether the image file should be run-length encoded.  Type 
	may be given as RLE(1), RLE(2), VERBATIM(1), or VERBATIM(2).  
	The recommended default is RLE(1).

             zsize should be 3 [bytes]--for the number of channels (Red, 
	Green, and Blue, 1 byte each)--if you want to generate RGB/SGI 
	imagelib image -type files.

             dim--the dimension--indicates whether the image is just a
        single row (one dimensional) or is an an array of rows (two
        dimensional) or is an array of 2 dimensional images (three
        dimensional).  A color image that consists of 3 layers (one
        for each read green and blue) is represented as a three
	dimensional image that is xsize by ysize by 3.  A black 
	and white image has one layer and is represented as a two 
	dimensional image that is xsize by ysize.

                iclose(image)
                register IMAGE  *image;

             Closes an image file that was open for reading or writing.  
	All output is flushed to the output file, and the output file 
	is closed.


The other thing you'll need to use is putrow (its source can be found in
~4Dgifts/iristools/libimage/row.c):

                putrow(image,buffer,y,z)
                register IMAGE  *image;
                unsigned short  *buffer;
                unsigned        y, z;

             Writes a row of pixels to the specified image file. The
        buffer should be an array of shorts that contain the pixel
        values.  If the image file maintains only one byte per
        pixel, then only the values passed in the buffer should be
        in the range 0..255.  The row of the image to be written is
        given by y, while z indicates which layer of the image to
        write to. The first layer of the image is layer 0.  The y
        argument should be greater than or equal to zero and less
        than the ysize of the image. You can write the rows to the
        image in any order.

what obviously has been left out of the above example ("the problem
is left to the reader as an exercise...") is the step where you need
to get the red channel's 8-bits of color intensity--as well as the
green and blue--from the the image data you are currently dealing
with, and load these channels, row by row into the 3 short arrays,
that you then call putrow with.  when compiling you'll want to include
"-limage" to specify libimage.a, and you may find you need/want
"-lgutil" (for libgutil.a) as well.  check out the Makefile in 
~4Dgifts/iristools/imgtools.

feel free to post more queries if yer still stuck.

--
                                             daveus rattus   

                                   yer friendly neighborhood ratman

                              KOYAANISQATSI

   ko.yan.nis.qatsi (from the Hopi Language)  n.  1. crazy life.  2. life
       in turmoil.  3. life out of balance.  4. life disintegrating.  
         5. a state of life that calls for another way of living.