SGI: Discussion

SGI RGB image format

Does any one know of a library of routines (or just a code snippet) that I could use in a C application to:

1) open an SGI RBG file (iopen?)

2) convert it into a X pixmap?

Thanks.
squeen wrote: Does any one know of a library of routines (or just a code snippet) that I could use in a C application to:

1) open an SGI RBG file (iopen?)

2) convert it into a X pixmap?

Thanks.


Sounds like a job for IFL:

http://techpubs.sgi.com/library/tpl/cgi ... /ifl/IFL.z
Twitter: @neko_no_ko
IRIX Release 4.0.5 IP12 Version 06151813 System V
Copyright 1987-1992 Silicon Graphics, Inc.
All Rights Reserved.
Thanks Neko.
IFL seems to advertise that I can do the job...but I can't make heads or tails out of the @#%!& C++ API (. :x ).

The C API example program in the IFL manual is a mess. It is cualked full of C++ comments...includes a header that doesn't exist ( #include <il/ilCdefs.h> I think should be #include <ifl/iflCdefs.h> ), even if I did the first declared type is non-existant.

I seems to me that SGI should not be surprised that few developers have made use of this undocumented mess! [ I have a theory that C <=> Unix && C++ <=> Microsoft Windows. ]

\end{rant}
I found this code sample for IFL that might help:

iflimg is a small program that takes a single command line
argument, the name of a file ("outputFile.suffix", where
".suffix" is any supported ifl format) to write the graphics
results of the program to. As it is currently written,
iflimg draws a triangle on the screen and when the user
presses the 'd' key, will save that image into outputFile.suffix
using the ifl library.

The file type format is taken from the file name suffix, i.e.
file.rgb is an SGI rgb file, file.jpg is a jpeg file, etc.
Use the imgformats(1) command to see all the supported ifl
formats.

The code has a single function dumpViewport() that does the
work of grabbing the screen image and using ifl to write it out.
See "man 3 ifl", the specific ifl class man pages, and
/usr/include/ifl.


Code: Select all

/*
* Copyright (c) 1999 Silicon Graphics, Inc.
* ALL RIGHTS RESERVED
*
* Permission to use, copy, modify, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that the name of Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE
* POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include <iostream.h>
#include <stdlib.h>

#include <X11/Intrinsic.h>
#include <X11/keysym.h>
#include <Xm/Xm.h>

#include <GL/GLwMDrawA.h>

#include <ifl/iflFile.h>

void createToplevel( Display *dpy );

void drawScene( void );
void exposeCB ( Widget, XtPointer, XtPointer );
void initCB  ( Widget, XtPointer, XtPointer );
void inputCB  ( Widget, XtPointer, XtPointer );

char *filename = "iflimg.jfif";

void main( int argc, char** argv )
{
XtToolkitInitialize();
XtAppContext ctx = XtCreateApplicationContext();

if ( argc > 1 ) filename = argv[1];

Display *dpy = XtOpenDisplay( ctx, NULL, "Iflimg", "iflimg", NULL, 0, &argc, argv ) ;

createToplevel( dpy ) ;

XtAppMainLoop( ctx ) ;
}

void createToplevel( Display *dpy )
{

Widget top = XtVaAppCreateShell( "iflimg", "iflimg",
applicationShellWidgetClass, dpy,
XmNheight, 500,
XmNwidth, 500,
NULL ) ;


Widget glw = XtVaCreateManagedWidget( "glw",
glwMDrawingAreaWidgetClass, top,
GLwNrgba, TRUE,
NULL ) ;

XtAddCallback( glw, GLwNginitCallback, initCB, NULL );

XtAddCallback( glw, GLwNexposeCallback, exposeCB, NULL );
XtAddCallback( glw, GLwNinputCallback, inputCB, NULL );


XtRealizeWidget( top );
}

void drawScene( void )
{
// Hardcode 500x500 viewport and an ortho projection
glViewport( 0, 0, 500, 500 );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( -250, 250, -250, 250, -250.0,250.0);

glMatrixMode( GL_MODELVIEW );
glClear( GL_COLOR_BUFFER_BIT );

// Dray a simple triangle
float v1[2], v2[2], v3[2];

v1[0] = -200; v1[1] = -200;
v2[0] =  200; v2[1] = -200;
v3[0] =  200; v3[1] =  200;

glBegin( GL_TRIANGLES );
glColor3ub( 255, 0, 0 );
glVertex2fv( v1 );

glColor3ub( 0, 255, 0 );
glVertex2fv( v2 );

glColor3ub( 0, 0, 255 );
glVertex2fv( v3 );
glEnd();

glFlush();
}

//
// Dumps the current viewport to a file named 'name'
//
bool dumpViewport( char *name )
{
// Read the viewport that's been defined for this context
int params[4];
glGetIntegerv( GL_VIEWPORT, params );
int x      = params[0];
int y      = params[1];
int width  = params[2];
int height = params[3];

// Setup an ortho projection matrix to read the image data
glMatrixMode( GL_PROJECTION );
glPushMatrix();
glLoadIdentity();
glOrtho( 0, width, 0, height, -1, 1);

// Rasterpos goes through the model view matrix, reset it.
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
glLoadIdentity();

//
// Create an ifl file
//

// w x h rgb image
iflSize        dims( width, height, 3 );

// set the file config to the dimensions and unsigned byte data
iflFileConfig  fc( &dims, iflUChar );
iflStatus      status;

// Create the file and default it to whatever format is denoted
// by the file name extension
iflFile        *file = iflFile::create( filename, NULL, &fc, NULL, &status );

// Make sure it was created ok
if ( status != iflOKAY ) {
char buf[1000];
iflStatusToString( status, buf, 1000 );
cout << buf << endl;
return 0;
}

// w x h rgb unsigned char image
unsigned char pixels[ width * height * 3 ];

// If the packing isn't default
if ( width % 4 != 0 ) {
glPixelStorei( GL_PACK_ALIGNMENT, 1 );
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
}

//
// The origin for OpenGL is lower left, but most images have the
// origin as the upper left, so when reading the data, we might
// have to flip it.
//

// Check if native orientation of file format is not OpenGL (l right )
if ( file->getOrientation() == iflUpperLeftOrigin ) {

//
// This is a hack to flip the image. Instead of writing a bit
// of code to do the image flip, I'm writing it back to the frame
// buffer with a negative pixelzoom Y scale. This will write it
// flipped and then I could just read it again and I'll have my
// flipped image.
//

// Read the native OpenGL image
unsigned char oglPixels[ width * height * 3 ];
glReadPixels( x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, oglPixels );

// Set the raster position at the top of the viewport.
glRasterPos2i( 0, height );

// Setup flip for write
glPixelZoom( 1.0, -1.0 );

// Draw the pixels, which will draw them upside down
glDrawPixels( width, height, GL_RGB, GL_UNSIGNED_BYTE, oglPixels );

// Read the new upside down image
glReadPixels( x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels );

// Reset
glPixelZoom( 1.0, 1.0 );

// Put the old pixels back so the image for the user isn't upside down
glRasterPos2f( 0.0, 0.0 );
glDrawPixels( width, height, GL_RGB, GL_UNSIGNED_BYTE, oglPixels );

glFlush();
} else {

// Read data into pixels array
glReadPixels( x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels );
}

// Write data to file
status = file->setTile( 0, 0, 0, width, height, 1, pixels );
if ( status != iflOKAY ) {
char buf[1000];
iflStatusToString( status, buf, 1000 );
cout << buf << endl;
return 0;
}

file->flush();
file->close();

glMatrixMode( GL_PROJECTION );
glPopMatrix();
glMatrixMode( GL_MODELVIEW );
glPopMatrix();

return 1;
}


void inputCB( Widget , XtPointer , XtPointer callData )
{

GLwDrawingAreaCallbackStruct *cbs = (GLwDrawingAreaCallbackStruct *)callData ;

switch( cbs->event->type )
{
case ButtonPress:
switch ( cbs->event->xbutton.button )
{
case Button1:
exit( 0 ) ;
break;

case Button2:

break;

case Button3:

break;
}
break;

case KeyPress: {
KeySym key = XLookupKeysym(&cbs->event->xkey, 0);
switch( key ) {
case XK_Escape:
exit( 0 );

case XK_d:
dumpViewport( filename );
break;
}
}

default:
break;
}
}


void exposeCB( Widget, XtPointer , XtPointer )
{
drawScene();

}

void initCB( Widget w, XtPointer , XtPointer )
{
XVisualInfo *vis;

XtVaGetValues( w, GLwNvisualInfo, &vis, NULL );

GLXContext ctx = glXCreateContext( XtDisplay( w ), vis, 0, 0 );

GLwDrawingAreaMakeCurrent( w, ctx );
}
Twitter: @neko_no_ko
IRIX Release 4.0.5 IP12 Version 06151813 System V
Copyright 1987-1992 Silicon Graphics, Inc.
All Rights Reserved.
Bumping this to the top since the long quoted text made the BBS software time out :x
Twitter: @neko_no_ko
IRIX Release 4.0.5 IP12 Version 06151813 System V
Copyright 1987-1992 Silicon Graphics, Inc.
All Rights Reserved.
Thanks Neko. You really are the one who (by example) sets the helpful tone for this entire forum.
It took me a bit of research, but I did the conversion manually (at least as far as my needs go).
Here is a smal pasted-together excerpt from my (ANSI C !!) code that gives the general idea:
It uses the iopen function that is provided with all SGI systems (see man rgb ) and is linked in using -limage.
This I/O library seems to date back to when the RGB format was first created at SGI, and even the support techs have forgotten about it.

Code: Select all

#include <gl/image.h>

#define PIXMAP_WD   100
#define PIXMAP_HT   100
#define BUFSIZE   4*PIXMAP_WD*PIXMAP_HT

Pixmap *rgbToPixmap( Widget w, char *fname ) {
int                  cc, x, y, z, offset, bitmap_pad, bytes_per_line;
unsigned int         icon_w, icon_h, depth;
IMAGE                *sgi_image;
short                *rbuf, *gbuf, *bbuf;
char                 *zbuf;
XImage               *ximg;
Pixmap               icon_pixmap;
GC                   gc;
XGCValues            gcvalues;
Display              *dpy;
Window               root_win;

dpy = XtDisplay(w);
root_win = RootWindowOfScreen( XtScreen( w ) );

XtVaGetValues( w, XmNdepth, &depth, NULL );
icon_pixmap = XCreatePixmap( dpy, root_win, PIXMAP_WD, PIXMAP_HT, depth );
gc = XtGetGC( w, GCForeground | GCBackground, &gcvalues );


sgi_image = iopen(fname,"r");

printf("geticon: converting SGI RGB format file %s\n",fname);
printf("Image x and y size in pixels: %d,%d\n",sgi_image->xsize,sgi_image->ysize);
printf("Image zsize in channels: %d\n",sgi_image->zsize);
printf("Image pixel min and max: %d %d\n",sgi_image->min,sgi_image->max);

/* this assumes zsize is 3 (RGB) but it could be 1 (B&W) or 4 (RGBA) */
zbuf = (char *)malloc(BUFSIZE*sizeof(short));
bzero( zbuf, BUFSIZE*sizeof(short) );
rbuf = (short *)malloc(sgi_image->xsize*sizeof(short));
gbuf = (short *)malloc(sgi_image->xsize*sizeof(short));
bbuf = (short *)malloc(sgi_image->xsize*sizeof(short));
z = 0;
for (y=sgi_image->ysize-1;y>=0;y--) {
getrow(sgi_image,rbuf,y,0);
getrow(sgi_image,gbuf,y,1);
getrow(sgi_image,bbuf,y,2);
for (x=0;x<sgi_image->xsize;x++) {
zbuf[z++] = (char)rbuf[x]; /* red   (0-255)  */
zbuf[z++] = (char)gbuf[x]; /* green (0-255)  */
zbuf[z++] = (char)bbuf[x]; /* blue  (0-255)  */
zbuf[z++] = 255;           /* alpha (0-255)  */
}
}

/* create an XImage from the SGI RGB data */
offset = 0;
bitmap_pad = 32;
bytes_per_line = 0;
/* NOTE: this may not work if the default visual is not 24bit !! */
icon_w = sgi_image->xsize;
icon_h = sgi_image->ysize;
ximg = XCreateImage( dpy, DefaultVisual( dpy, DefaultScreen(dpy) ),
DefaultDepth( dpy, DefaultScreen(dpy) ), ZPixmap,
offset, zbuf, icon_w, icon_h, bitmap_pad, bytes_per_line );

ximg->byte_order = LSBFirst;

/* write the XImage to a Pixmap for displaying on a widget */
XPutImage( dpy, icon_pixmap, gc, ximg, 0, 0,
(unsigned int)x_off, (unsigned int)y_off, icon_w, icon_h );

/* to save it to an XPM file you need the Xpm library and would first */
/* set up XpmAtrributes and then call XpmWriteFileFromPixmap(... ) */

return( &icon_pixmap );
}


As a side note, my iconbar app is really coming along. I have worked out a method for getting the application pixmaps that even the X Windows gurus said couldn't be done! I hope to have an alpha test version out in less than a week.
Great! I'm really looking forward to it! :)
Twitter: @neko_no_ko
IRIX Release 4.0.5 IP12 Version 06151813 System V
Copyright 1987-1992 Silicon Graphics, Inc.
All Rights Reserved.