SGI RGB image format

Open discussion on or around SGI; software/hardware related posts should go in the appropriate subforum.
Forum rules
Any posts concerning pirated software or offering to buy/sell/trade commercial software are subject to removal.
User avatar
squeen
Moderator
Moderator
Posts: 2932
Joined: Fri May 09, 2003 6:10 am
Location: Maryland, USA

SGI RGB image format

Unread postby squeen » Mon Jul 21, 2003 8:23 am

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.

User avatar
nekonoko
Site Admin
Site Admin
Posts: 8139
Joined: Thu Jan 23, 2003 1:31 am
Location: Pleasanton, California
Contact:

Re: SGI RGB image format

Unread postby nekonoko » Mon Jul 21, 2003 9:00 am

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.

User avatar
squeen
Moderator
Moderator
Posts: 2932
Joined: Fri May 09, 2003 6:10 am
Location: Maryland, USA

Unread postby squeen » Mon Jul 21, 2003 12:23 pm

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}

User avatar
nekonoko
Site Admin
Site Admin
Posts: 8139
Joined: Thu Jan 23, 2003 1:31 am
Location: Pleasanton, California
Contact:

Unread postby nekonoko » Wed Jul 23, 2003 2:07 am

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.

User avatar
nekonoko
Site Admin
Site Admin
Posts: 8139
Joined: Thu Jan 23, 2003 1:31 am
Location: Pleasanton, California
Contact:

Unread postby nekonoko » Wed Jul 23, 2003 2:15 am

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.

User avatar
squeen
Moderator
Moderator
Posts: 2932
Joined: Fri May 09, 2003 6:10 am
Location: Maryland, USA

Unread postby squeen » Wed Jul 23, 2003 4:36 am

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.

User avatar
nekonoko
Site Admin
Site Admin
Posts: 8139
Joined: Thu Jan 23, 2003 1:31 am
Location: Pleasanton, California
Contact:

Unread postby nekonoko » Wed Jul 23, 2003 8:54 am

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.


Return to “SGI: Discussion”

Who is online

Users browsing this forum: No registered users and 2 guests