From: portuesi@tweezers.esd.sgi.com (Michael Portuesi)
Newsgroups: comp.sys.sgi
Subject: Re: Help with Image Vision and MRI
Date: 14 Oct 92 17:35:02 GMT
Organization: Silicon Graphics, Inc.  Mountain View, CA


In article <33073@adm.brl.mil>, rose@baby.swmed.utexas.edu writes:
> 
> I'm trying to use the ImageVision Library to display and
> process MR images. Currently, each MR slice is in its own
> file (256x256x2bytes) with one header file foe all.  I
> understand that the MRs can also be stored in one file.
> In any case, the MRs are not currently in a file format
> recognized by IL. The programming guide implies that I
> can implement my own file format by extending the IL.  The
> problem is that I seem to need C++ to do this, but
> I don't have it.  Is there another way of doing this?
> Can I do something simple to my MRs so that they're
> recognized?  It seems that this should be an easy task,
> but I have not figured it out.  So, any suggestions will be
> greatly appreciated.
> 

Don't worry, it is a (relatively) easy task.

One way to solve your problem is to do exactly what you
mentioned, i.e. extend IL to handle your specific file format.
However, while IL may be *used* from C, C++, and Fortran,
it can only be extended from C++.

However, for the needs of a specific application, you can
get IL to recognize your data another way.  IL has a facility
called an ilMemoryImg.  This is an image whose source is
in memory.  You can write a program to read your image from
a disk file into a memory buffer, then initialize an ilMemoryImg
with your memory buffer.  From that point on, you can process
the image using all of the IL image processing operators, and
even write it to one of IL's file formats using its I/O
commands.

You don't specify details of exactly how the data in your
image file is interpreted, so I'll make the following assumptions
for the example:

	x dimension:	256
	y dimension:	256
	data type:	unsigned short (2 bytes/pixel)
	pixel order:	interleaved (see the IL documentation)

Here's a code fragment (unfortunately written using C++; I
don't have the docs for the C API near me) which will do
something along the lines you're looking for.  It should give
you a head start.

Note that I haven't run this through a compiler, and I can't
be sure that your problem matches the one solved here, so
this code of course comes without any guarantees whatsoever.
If you destroy your entire database of images with it,
neither I nor Silicon Graphics can be held responsible.


#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <il/ilMemoryImg.h>
/* don't forget include files for the other IL features
 * you'll be using */

#define IMG_WIDTH	256
#define IMG_HEIGHT	256

void main (int argc, char* argv[])
{
    int fd, totalbytes, bytesread;	/* for file handling */
    unsigned short* buffer;		/* of image data */
    ilSize sz;				/* to create IL memory img */
    ilMemoryImg* memimg;

    if (argc < 2) {
	printf ("Usage: %s in-image\n", argv[0]);
	exit(0);
    }

    /* Allocate a memory buffer to hold the raw image data. */
    totalbytes = IMG_WIDTH * IMG_HEIGHT * sizeof(unsigned short);
    unsigned short* buffer = (unsigned short*) malloc(totalbytes);
    if (buffer == NULL) {
	printf ("%s: could not allocate memory\n" argv[0]);
	exit(0);
    }

    /* Place appropriate code to open and read your raw image
       file here.  One example might be: */
    if ((fd = open(argv[1], O_RDONLY)) < 0) {
	printf ("%s: could not open file name %s\n", argv[0], argv[1]);
	exit(0);
    }
    if ((bytesread = read(fd, buffer, totalbytes)) != totalbytes) {
	printf ("%s: read (%d) data, expected amount (%d), file name %s\n",
		argv[0], bytesread, totalbytes, argv[1]);
	exit(0);
    }
    close(fd);
	
    /* Create ilMemoryImg and initialize with memory buffer.  Note
     * that this example uses C++ syntax. */
    sz.x = IMG_WIDTH;
    sz.y = IMG_HEIGHT;
    sz.z = 1;			/* only one image in Z */
    sz.c = 1;			/* only one channel (monochrome) */

    memimg = new ilMemoryImg(buffer,		/* image data from file */
			     sz,		/* image dimensions */
			     ilUShort,		/* image data type */
			     ilInterleaved	/* data ordering for each pixel */
			     );

    /* At this point, memimg is a full-fledged IL image which can
     * be chained into image processing operators, displayed using
     * the IL display facilities, or written to files using the IL
     * file facilities.
     *
     * Note that the ilMemoryImg does not make a copy of the image
     * data.  So, you should wait until after you are done processing
     * your data before freeing the memory that you allocated
     * earlier.
     */

    /* free allocated memory.  Note that "new" and "delete" are C++
       ways of dynamically allocating memory for structures, etc. */
    delete memimg;		/* use "delete" because this was obtained
				   from "new" */
    free(buffer);		/* we use "free" because this was obtained
				   from malloc() */

    /* done processing */
    exit(0);
}


--
Michael Portuesi   Silicon Graphics, Inc.   portuesi@sgi.com
Xref: sparky comp.sys.sgi:14936 comp.graphics.explorer:250