SGI Techpubs Library

IRIX 6.5  »  Man Pages
find in page

IFL(3)

 NAME

     IFL - overview of Image Format Library

 SYNOPSIS

     The Image Format Library (IFL) is a library for opening, reading, writing
     and creating image files in a format independent manner. IFL consists of
     a library developed in C++. An interface library for C programmers is
     also provided.  IFL includes support for the FIT, GIF, JFIF, Photo CD,
     PNG, PPM, SGI, TIFF and numerous other file formats.  It also supports
     reading and writing raw image data in a fairly flexible manner.  It is
     designed to be very easy to use with a straight-forward mechanism support
     user-defined file formats.

 GETTING STARTED

     To open a file and read it into memory you can write C++ code like the
     following:

          #include <ifl/iflFile.h>

          // open the file named by 'filename'

          iflStatus sts;
          iflFile* file = iflFile::open(filename, O_RDONLY, &sts);
          if (sts != iflOKAY) { /* handle the error */ }

          // read the entire image (just the first plane in z if image has depth)
          // into a buffer of unsiged chars

          iflSize dims;
          file->getDimensions(dims);
          unsigned char* data = new unsigned char[dims.x*dims.y*dims.c];
          iflConfig cfg(iflUChar, iflInterleaved);
          sts = file->getTile(0, 0, 0, dims.x, dims.y, 1, data, &cfg);
          if (sts != iflOKAY) { /* handle error */ }

          // close the file
          file->close();

     or equivalently in C you could write:

          #include <ifl/iflCdefs.h>

          /* open the file named by 'filename' */

          iflStatus sts;
          iflFile *file;
          iflSize dims;
          unsigned char *data;
          iflConfig* cfg;
          file = iflFileOpen(filename, O_RDONLY, &sts);
          if (sts != iflOKAY) { /* handle the error */ }

          /*
              read the entire image (just the first plane in z if image
              has depth) into a buffer of unsiged chars
          */

          iflFileGetDimensions(file, &dims);
          data = (unsigned char*)malloc(dims.x*dims.y*dims.c);
          cfg = iflConfigCreate(iflUChar, iflInterleaved, 0, NULL, 0, 0);
          sts = iflFileGetTile(file, 0, 0, 0, dims.x, dims.y, 1, data, cfg);
          if (sts != iflOKAY) { /* handle error */ }

          /* close the file */
          iflFileClose(file, 0);

     This simple example opens a file in any image format supported by IFL.
     The open function returns a pointer to an iflFile object which is IFL's
     abstraction for accessing image files. This object is described further
     below and in the iflFile(3) man page. The file object is then used to
     read the image's data it into memory. The iflConfig object is used to
     specify that that data should be read in the file's orientation, but with
     the pixels forced to unsigned char format and interleaved ordering.

     Creating and writing an image file is just as simple:

          // create a one-channel, unsigned char image file
          iflSize dims(width, height, 1);
          iflFileConfig fc(&dims, iflUChar);
          iflStatus sts;
          iflFile* file = iflFile::create(filename, NULL, &fc, NULL, &sts);
          if (sts != iflOKAY) { /* handle the create error */ }

          // write a tile of data to it
          sts = file->setTile(0, 0, 0, width, height, 1, data);
          if (sts != iflOKAY) { /* handle error */ }

          // make sure the data gets written out to disk (or you can close here)
          sts = file->flush();
          if (sts != iflOKAY) { /* handle error */ }

     or equivalently in C you could write:

          iflFile *file;
          iflFileConfig *fc;
          iflStatus sts;
          iflSize dims;

          /* create a one-channel, unsigned char image file */
          dims.x = width;
          dims.y = height;
          dims.z = 1;
          dims.c = 1;
          fc = iflFileConfigCreate(&dims, iflUChar, 0, 0, 0, 0, NULL);
          file = iflFileCreate(filename, NULL, fc, NULL, &sts);
          if (sts != iflOKAY) { /* handle the create error */ }

          /* write a tile of data to it */
          sts = iflFileSetTile(file, 0, 0, 0, width, height, 1, data, NULL);
          if (sts != iflOKAY) { /* handle error */ }

          /* make sure the data gets written out to disk (or you can close here) */
          sts = iflFileFlush(file);
          if (sts != iflOKAY) { /* handle error */ }

     The code fragment above creates a one-channel file with the specified
     width and height and unsigned char data type.  The rest of the attributes
     default to a format-preferred value.  The file format will be inferred
     from the file name suffix.  (It is also possible to explicitly give a
     format, and to inherit attributes from another iflFile.)  This example
     then writes a tile of data to the file.  It assumes the data buffer is
     the size and data type as the image created. It is also possible to do
     automatic conversion on the setTile() operation.  Always be sure to flush
     or close the file when you are done writing data to it or the disk file
     may not be correctly written.

     Be aware that IFL doesn't scale the data when converting data types, so
     you'd better be sure to pick a data type large enough to hold the range
     of data values in the image file; you can use the getScaleMinMax() and
     getStatMinMax() methods of iflFile to check the range of values.  Also,
     IFL doesn't do any color model conversions; if you need that level of
     functionality you may want to use the ImageVision Library (IL) that is
     layered on top of IFL.

     The following section on image attributes defines some of the terms just
     used such as orientation and dimension ordering.

   Example source
     If you install ifl_dev.sw.gifts, you can examine the source code provided
     in /usr/share/src/ifl/apps for more examples of using IFL.

 IMAGE ATTRIBUTES

     The Image Format Library characterizes images according to the common
     attributes described in the following sections.

   Image size
     Image have four dimensions: x, y, z, and c.  The x and y dimensions are
     typically the width and height of the image although their interpretation
     is dependent upon the orientation of the image (described below).

     The z dimension is generally interpreted as either depth for volume
     images or time for image sequences like movies; for 2D images the size of
     the z dimension is one.

     The c dimension is the channel or component dimension; the size of the c
     dimension is the number of components in each pixel.  The size of the c
     dimension must match the color model (see below) of the image.  For
     example, an RGB image must have a c size of three and a greyscale image
     must have a c size of one.  The only exception is the multi-spectral
     color model which can have any size for the c dimension.  The image size
     is represented by the iflSize structure defined in <ifl/iflSize.h>.

   Data type
     The data type of an IFL image is the data type of the individual
     components of each pixel.  All components of a pixel must have the same
     data type.  The library supports nine data types: bit, signed byte,
     unsigned byte, signed short (16 bits), unsigned short, signed long (32
     bits), unsigned long, float (32 bits) and double (64 bits).  These data
     types are encoded by the iflDataType enum defined in <ifl/iflTypes.h>.
     Typically, if a format actually stores data in say 4 bits per component
     the IFL interface to the file will present the data as unsigned char with
     a scaling range of 0-15 (see below).

     For a color palette image (see Color model section below), the image's
     data type refers to the type of its color index.  The type of the color
     map values is determined by the file format and stored in an iflColormap.

   Dimension order
     This is the relative ordering of the image's x, y and channel dimensions.
     There are three orderings supported by IFL:

          interleaved   channel dimension varies fastest, then x, then y, z
                        last; thus all the components of each pixel are
                        grouped together

          sequential    x dimension varies fastest, then channels, then y, z
                        last; all the components of a single row are grouped
                        together (seldom used)

          separate      x dimension varies fastest, then y, then channels, z
                        last; the data is stored with each component isolated
                        in a separate plane.

     These orderings are encoded by the iflOrder enum defined in
     <ifl/iflTypes.h>.

   Color model
     The color model of an image defines the interpretation of the components
     of its pixels.  There are 11 color models supported by IFL: greyscale,
     inverted greyscale (minimum is white, maximum is black), greyscale plus
     alpha, color palette (indicies mapped through a color map), RGB triplets,
     RGB plus alpha, HSV, CMY, CMYK, YCC and multi-spectral.  There are also
     component reversed versions of RGB and RGBA but their use is deprecated
     (they are for backward compatibility with older SGI systems).  These
     color models are encoded by the iflColorModel enum defined in
     <ifl/iflTypes.h>.

   Orientation
     The orientation of an image defines the spatial interpretation of its x
     and y dimensions.  It is defined in terms of the location of the origin
     of the image (one of the four corners) and the direction of the x and y
     dimension (whether x runs horizontally or vertically).  The combination
     of these two factors yields the eight orientations supported by IFL:

          upper-left    origin in upper-left corner, x dimension is horizontal
                        (y is vertical)

          upper-right   origin in upper-right corner, x dimension is
                        horizontal

          lower-left    origin in lower-left corner, x dimension is horizontal

          lower-right   origin in lower-right corner, x dimension is
                        horizontal

          left-upper    origin in upper-left corner, x dimension is vertical
                        (y is horizontal)

          right-upper   origin in upper-right corner, x dimension is vertical

          right-lower   origin in lower-right corner, x dimension is vertical

          left-lower    origin in lower-left corner, x dimension is vertical

     These orientations are encoded by the iflOrientation enum defined in
     <ifl/iflTypes.h>.

   Compression
     The data in an image file may be compressed (depending on the format).
     Each format supported by IFL will automatically decompress the data read
     from the file when it is accessed through the iflFile methods getPage()
     and getTile().  Similarly, each format will compress data passed to the
     setPage() and setTile() methods before it is written out.  The
     compressions are encoded in the iflCompression enum defined in
     <ifl/iflTypes.h>.

   Page size
     Some images are stored in a paged manner, others are stored in horizontal
     strips, others may not allow random access at all.  Each file format
     encodes the underlying structure of its data with the page size
     attribute. The page size defines the dimensions of the natural chunks
     that an application can access with the getPage() and setPage() methods
     of iflFile.  For arbitrarily paged images the x and y page size may be
     smaller than the image's x and y size, requiring multiple fixed-size
     pages to be tiled across the image.  For strip oriented images the page
     width will be the same as the image width and the strips will be stacked
     vertically to cover the image.  For images that can't support random
     access to pages of fixed size, the page size will be the same as the
     image size; i.e. there will only be one page.

     The page size is defined by x, y, z and c dimensions as with the image
     size and follows the same rules with respect to the image's orientation.
     Data within each page is packed; there is no padding at the end of each
     line, even for bit data.  Some file formats may indicate such padding by
     having the page size wider that the image size.

   Display scaling range
     Some image formats store a notion of the range of component values for
     purposes of scaling the data for display.  This attribute may not be
     present in an image, in which case the application should assume the
     range is the full range of values than can be represented by the image's
     component data type.  For images whose color model is iflRGBpalette this
     is the range of the entries on the color map, not the indices.

   Statistical range
     Some image formats store a notion of the statistical range of component
     values.  This range should not be used for display scaling purposes, but
     may be useful in some image processing computations.

   ICC profiles
     Some image formats store an ICC (International Color Consortium) profile
     that can be used for color management.  See http://www.color.org for more
     details on the specifics of how such profiles are used.

 THE IMAGE FILE ABSTRACTION

     IFL's mechanism for accessing image files is through the iflFile class.
     This class is used as a base for deriving all of the file formats
     supported by IFL. It provides static methods to open existing image files
     and to create new ones.  It provides methods to read and write image
     data, query all attributes and set some attributes.  Format specific
     operations are supported through the getItem() and setItem() methods.
     Because of this base abstraction, IFL enables applications to be written
     that are image file format independent, yet still allows full access to
     unique attributes and capabilities of particular file formats.  Refer to
     the iflFile(3) man page for more details.

 THE IMAGE FORMAT ABSTRACTION

     The Image Format Library uses the iflFormat object to represent a
     description of the capabilities of a particular image file format. The
     iflFormat class provides a number of functions that can be used to look
     up formats by format name, by a file's "magic" number, or by file name
     extension (e.g. ".gif").  There is also a method to iterate through all
     available formats ( useful for user interfaces, for instance, to generate
     a menu of available file formats).

     The methods on an iflFormat allow the user to determine which values of
     the image attributes are supported by that format.  There are also
     methods to query the preferred values of those attributes.  See the
     iflFormat(3) man page for more details.

 ADDING NEW IMAGE FILE FORMATS

     To add support for a new image file format, you create a Dynamic Shared
     Object (DSO) that implements the format and add an entry in the IFL file
     format database for the format.

     The DSO implements the file format I/O itself and the IFL interface
     abstraction.  This is often done by using an already existing file format
     library and creating an IFL interface that makes calls into that library
     (see the iflJFIFFile.c++ and iflTIFFFile.c++ examples in ifl_dev.sw.gifts
     as examples of this).  The IFL interface is implemented by deriving
     classes from iflFormat and iflFile for the format.  Refer to the
     iflFile(3) and iflFormat(3) man pages for information on deriving your
     own classes.

     IFL uses a text database file to determine what file formats are
     available for use with IFL.  The database is normally located in the file
     /usr/lib/ifl/ifl_database but this may be overridden with the
     IFL_DATABASE environment variable.

     The database is generated by the /usr/lib/ifl/ifldbgen program when new
     file formats are added to the system. To add you own file format, you
     should create a database file with the new entry or entries and place
     that file in the /usr/lib/ifl/database directory. Once there, running the
     ifldbgen program will generate the updated database. Unlike previous
     versions of IFL, you should not include an include directive in the new
     database file.  Doing so will result in conflicts when ifldbgen creates
     the new database.

   Building your DSO
     There are two critical things that must be done when you build the DSO
     for your file format.

          You must build your DSO using the C++ compiler so that the
          statically declared iflFormat derived object (see the iflFormat(3)
          man page for more info) will be automatically instantiated when the
          DSO is dynamically opened by IFL.

          The DSO version string must be 'sgi2.0' for IFL 1.1 and IFL 1.2 to
          recognize it as a valid file format DSO.

     An example command line to create a DSO for the TIFF format might be:

          % CC -mips3 -n32 -o libiflTIFF.so -set_version sgi2.0 -shared -all \
               iflTIFFFile.o -ltiff -lifl -lm

     The DSO would then normally be installed in /usr/lib32 or some other
     directory that can be pointed to by the LD_LIBRARYN32_PATH environment
     variable.  If you wish your file format to be useable with both -32 and
     -n32 executables then you will need to build the DSO for each object
     style and install them in the appropriate directories.  See the ld(1) and
     rld(1) man pages for more details on DSO search paths.

   Format of the database file
     IFL database files are text files made up of a list of "format"
     declarations.  A format declaration looks like this:

          format formatname
            match          matchrule
            description    "human-readable description of the format"
            dso            name of DSO file
            access         supported access modes
            subsystem      inst sub-system containing the DSO
            suffixes       comma-separated list of file name suffixes

     The format declaration must come first and declares the name of an image
     file format.  A format name is a one-word string and can be any legal C-
     language variable name.  Each format declaration must have a unique name.
     All attribute declarations that follow a format declaration may appear in
     any order and apply to that format until the next format declaration is
     encountered in the database file.  The match, description, and dso
     attribute declarations are required for every format.

     The match declaration is a logical expression that determines whether a
     particular file is of the declared format.  A match rule consists of a
     C-style logical expression made up of functions, comparison operators and
     parentheses.  The following C-language operators may be used in a MATCH
     expression:

          &&  ||  ==  !=  <  >  <=  >= ( )

     The == operator works for string comparisons as well as for numerical
     expressions.

     Numbers in a match expression may be expressed in decimal, octal, or
     hexadecimal notation.  Octal numbers are expressed with a leading zero,
     such as 0732.  Hexadecimal numbers are expressed with a leading `0x' such
     as 0xf03c.  Decimal number are expressed normally, but may not have a
     leading zero.

     The following expression functions are available:

     char(n)         Returns the signed byte located at offset n in the file;
                     range -128 to 127.

     long(n)         Returns the signed long integer located at offset n in
                     the file; range -2^31 to 2^31-1.

     short(n)        Returns the signed short integer located at offset n in
                     the file; range -32768 to 32767.

     string(n,l)     Returns the l character long string located at offset n
                     in the file.

     uchar(n)        Returns the unsigned byte located at offset n in the
                     file; range 0 to 255.

     ulong(n)        Returns the unsigned long integer located at offset n in
                     the file; range 0 to 2^32-1.

     ushort(n)       Returns the unsigned short integer located at offset n in
                     the file; range 0 to 65535.

     Typical match declaration examples are:

         match short(0) == 0x01da || short(0) == 0xda01

     or

         match long(0) == 0xffd8ffe0 && string(6,4) == "JFIF"

     The description declaration is a human-readable description of the image
     format.  Typical description declaration examples are:

         description "Kodak Photo CD image"

     or

         description "TIFF image"

     Descriptions should be relatively short as they are used as the labels
     for GUI components in some applications.

     The dso declaration specifies that name of the DSO that contains the code
     to read and/or write the format.  This name is typically specified
     without a directory path; instead, the environment variable,
     LD_LIBRARY_PATH, is used to locate the DSO at run-time.

     The optional access declaration determines what access modes are
     supported for the format.  Possible values are: "readonly", "writeonly",
     or the default, "readwrite".

     The optional subsystem declaration can be used to name the inst sub-
     system that should be installed to obtain support for the format.  This
     name is included in error messages when the DSO for a format can not be
     opened.

     The optional suffixes declaration lists a set of file name suffixes that
     will be used to determined what format a newly created file should use
     when the format is not specified in an iflFile::create() call.  A typical
     suffixes rule would be:

         suffixes .jpg,.jpeg

     Comments may be placed in a database file by using the '!' character.
     The comment extends to the end of the line.

     Other files (like /usr/lib/ifl/ifl_database) can be included in a
     database file using the "#include" directive.  This directive uses the
     same syntax as the C preprocessor equivalent; the "#" must be the first
     character on a line and the filename must be enclosed in quotes or
     angle-brackets:

         #include "filename"

     or

         #include <filename>

     The filename must be an absolute pathname (i.e. it must start with a
     "/").

 SEE ALSO

     iflFile(3), iflFormat(3), iflSize(3), IFL(1), <ifl/iflTypes.h>, IL(1)




home/search | what's new | help