[ Previous | Next | Contents | Glossary | Home | Search ]
Ultimedia Services Version 2 for AIX: Programmer's Guide and Reference

Image File Access

The UMS image reader is an Ultimedia Services Version 2 feature and does not apply to Ultimedia Services Version 1.2.1. Subsequent releases of Ultimedia Services have extended the image reader's functionality.

The image reader is one component of the UMS support for image display. The initial release was limited to support for JPEG and Photo CD images; subsequent releases have added support for GIF and a subset of TIFF images. An image reader allows applications to read and decode a range of image files in a consistent manner. Image reader support includes the ability to read subimages as well as entire images, decode image data into a variety of data formats, control color maps used in decoding, and apply transformations to the image data.

A number of image reader classes are supported. The base image reader class is UMSImageReader. This base class contains the image reader methods that are common to all derived image reader classes. In addition to the base class, a number of format-specific image reader classes are also available:

Some of these derived classes offer functionality beyond that of the UMSImageReader, but their methods are not shared among all the derived classes. Consequently, you should use these classes only when you require the extended functionality that they offer. If portability of code across different image formats is important, then you should use only the base image reader class in your applications.

To learn more about image file access, see:

For introductory information, see Programming with Formatted File Access Objects.

UMSImageReader Object Method Calls

UMSImageReader object method calls include:

open Opens an image file.
get_image_count Returns the number of different images in an image file.
set_image Sets the current image.
get_image Returns the image number of the current image.
get_formats Allocates and returns a pointer to the first pointer in an array of string pointers, each of which specifies one valid format for the current image object.
set_format Specifies the color format to be used when reading image data.
get_format Gets the currently specified color format for image data.
set_colormap_attributes Specifies the number of entries in the color map and the offset of these entries.
get_colormap_attributes Gets the current color map size and the base index value used when dithering 8-bit image data.
set_colormap Sets a color map using the current settings for color map base index and color map size.
get_colormap Gets the current color map using the current settings for color map base index and color map size.
get_rightsideup_transform Gets the transformation required to read the currently selected image right-side up.
get_transforms Returns an array of UMSImageTransform enumerations that specify which transforms are supported on an image reader.
set_transform Specifies the orientation with which the current image reads.
get_transform Gets the currently specified orientation to be applied when an image is read.
get_image_sizes Returns a pointer to an array of UMSImageSize elements that describe the image sizes available for the current image.
set_image_size Sets the image size (for example, width and height) to be used when reading an image file.
get_image_size Returns the currently specified size to be used in reading an image file.
set_display_size Sets the size of the displayable image.
get_display_size Returns the currently specified size to be used when displaying an image file.
supports_arbitrary_scaling Returns TRUE if arbitrary scaling (such as, any desired size) is supported for the current image format.
get_subimage_coordinates For a subimage defined in one coordinate system, the method returns the corresponding coordinates of the subimage in a different coordinate system.
read_image Reads a rectangular image area defined by rect from an image into a corresponding rectangular area in the memory block buffer.
set_color_properties Allows the caller to change the brightness, saturation, and red, blue, and green color balances of an image when reading it from disk.
get_color_properties Allows the caller to determine the current color property settings used when reading an image.
supports_color_properties Returns TRUE if changing color properties is supported for the current image format
close Closes an image file and deallocates resources.
get_file_type Returns the applicable detector file type alias for the current image reader.
get_associated_image_path Determine the fully qualified filename of the image file associated with any currently selected image, if any.
get_file_info Returns the full pathname of the current image file. The method also returns a pointer to an array of string pointers containing information about the current image file, if such information exists.
get_image_info Returns a pointer to the first pointer in an array of string pointers, if such information exists.
get_read_progress Returns the progress of the current image read operation, expressed as a percentage of the entire operation.
get_copyright_info Returns any copyright information that is associated with the current image.
get_output_buffer_size Returns the number of bytes required to contain the image data returned by read_image.
get_dither_types Returns an array of UMSImageDitherTypes enumerations that specify which dither algorithms are supported for the current format.
set_dither Allows dithering to be turned off or set to one of several dithering algorithms.

Reading Image Files: Programming Examples

The following example code fragments demonstrate various aspects of using the image reader object in a program. Because the base image reader class UMSImageReader is used, this code works with all image formats supported by UMS. (A complete example file that uses the UMS image reader to display an image file can be found in /usr/lpp/UMS/Examples. The file name is UMSImageReaderExample.c.)

The following code fragment shows which UMS include files should be used, and how to declare the required UMS objects and structures:

 #include <UMSTypes.h>
 #include <UMSImageReader.h>
 
  Environment *ev;
  UMSImageReaderMClass IR_Class;  /*  UMSImageReader MetaClass object */
  UMSImageReader IR;               /* UMSImageReader object */ 
  char path[PATH_MAX];
  UMSImageReaderMClass_ErrorCode IR_class_error;
  char *error_string;
  string astring, astring2;
  string fileType;
  int rc;
  int i;
  _IDL_SEQUENCE_string format_list;
  char **rayptr;
  UMSImageTransform lastTransform;
  _IDL_SEQUENCE_UMSImageTransform transforms;
  UMSImageTransform *transformPtr;
  _IDL_SEQUENCE_UMSImageSize sizes;
  UMSImageSize size;
  UMSImageSize *sptr;
  unsigned long colormap_index, colormap_size;
  _IDL_SEQUENCE_octet* colormap_t =  NULL;

Once the include files are specified and the necessary variables declared, a SOM environment is obtained and an image reader class is created.

  ev = somGetGlobalEnvironment();   /* Get a SOM environment. */
 
  /* Get an instance of an image reader class. */
  if ( ( IR_Class = UMSImageReaderNewClass(                                UMSImageReader_MajorVersion,
         UMSImageReader_MinorVersion) ) == NULL )
  {
    fprintf( stderr, "ERROR: NewClass failed\n" );
    return( -1 );
  }

The next code fragment assumes that the char array "path" has been initialized with the path of the image file that is to be displayed. Because the path is known, the image reader method make_by_pathname is invoked to create an image reader object. (Note that make_by_pathname opens the image file, so it is not necessary for the application to call open as well.)

  /* Use the image file path to get an image reader object. */
  if ( ( IR = UMSImageReaderMClass_make_by_pathname( IR_Class, ev, path,
         &IR_class_error, &error_string, &astring ) ) == NULL )
  {
    fprintf( stderr, "ERROR: failed make_by_pathname.\n" );
    return( -1 );
  }

Once an image reader object is created, it can be queried to obtain a variety of information about an image file, such as the file type, as shown in the following code fragment. The file type is returned as a string, the buffer for which is allocated by the get_file_type method . The application should deallocate the buffer once it has been used.

  if ( ( rc = UMSImageReader_get_file_type( IR, ev, &astring2 ) ) !=
    UMSImageReader_Success )
  {
    fprintf( stderr, "ERROR: failed get_file_type\n" );
    return( -1 );
  }
  /* Do whatever you want with the file type, and then deallocate it. */    /* Note that the file type was also returned by make_by_pathname,   */    /* so that buffer needs to be deallocated as well */
  SOMFree( astring );
  SOMFree( astring2 );

You might want to determine which image data formats are available to your application from the image reader. The get_formats method provides this information. This method allocates several buffers that the application should deallocate.

  /* Query the available image data formats for this image format. */
  if ( ( rc = UMSImageReader_get_formats( IR, ev, &format_list ) ) !=
    UMSImageReader_Success )
  {
    fprintf( stderr, "ERROR %d: failed get_formats\n" );
    return( -1 );
  }
  rayptr = format_list._buffer;
  printf( "The supported pixel data formats are:\n" );
  for ( i=0; i<format_list._length; i++ )
  {
    printf("\t%s\n",*rayptr);
    SOMFree( *rayptr++ );   /* free the buffer allocated by the method */
  }
  SOMFree(format_list._buffer);   /* free the buffer allocated by the */    /* method */

Each image has a default transform (or rotation), and the image reader supports changing the transform for many image formats. Both the default transform and the available transforms can be obtained from the image reader. The Image Reader Transforms figure contains an example of all possible transforms that may be supported by the image reader. (Note that a particular image format may not support all transforms.) For image formats such as Photo CD that support multiple transforms, the default transform is "right side up." Otherwise, the default transform is ROTATE_0, which is defined as the image orientation contained in the image file (which typically is also "right side up").

  /* Query the default transform for this image. */
  if ( ( rc = UMSImageReader_get_transform( IR, ev, &lastTransform ) ) !=
    UMSImageReader_Success )
  {
    fprintf( stderr, "ERROR: failed get_transform\n" );
    return( -1 );
  }
  /* Query the supported transforms for this image type. */
  if ( ( rc = UMSImageReader_get_transforms( IR, ev, &transforms ) ) !=
    UMSImageReader_Success )
  {
    fprintf( stderr, "ERROR: failed get_transforms\n" );
    return( -1 );
  }
  transformPtr = transforms._buffer;
  printf( "The supported transforms are:\n" );
  for ( i=0; i<transforms._length; i++ )
  {
    switch( *transformPtr )
    {
      case ROTATE_0 :
        printf( "\tROTATE_0\n" );
        break;
      case ROTATE_90 :
        printf( "\tROTATE_90\n" );
        break;
      case ROTATE_180 :
        printf( "\tROTATE_180\n" );
        break;
      case ROTATE_270 :
        printf( "\tROTATE_270\n" );
        break;
      case MIRROR_0 :
        printf( "\tMIRROR_0\n" );
        break;
      case MIRROR_90 :
        printf( "\tMIRROR_90\n" );
        break;
      case MIRROR_180 :
        printf( "\tMIRROR_180\n" );
        break;
      case MIRROR_270 :
        printf( "\tMIRROR_270\n" );
        break;
      default :
        fprintf( stderr, "ERROR: found unknown transform type %d\n",
          *transformPtr );
    }
    transformPtr++;
  }
  lastTransform = *( transformPtr - 1 ); /* save the last supported 
                                         /* transform */
  SOMFree( transforms._buffer );   /* free the buffer allocated by the 
                                   /* method */
  /* Change the current transform to the last transform supported */
  /* for this image type. */
   if ( ( rc = UMSImageReader_set_transform( IR, ev, lastTransform ) ) !=
           UMSImageReader_Success )
    {
      fprintf( stderr, "ERROR: failed set_transform\n" );
      return( -1 );
    }

Some file formats, such as Photo CD, support more than one resolution per image. Applications can invoke the get_image_sizes method to determine the height and width of each available resolution. The number of resolutions is returned in the _length field of the "sizes" input variable (which is of type _IDL_SEQUENCE_UMSImageSize).

  /* Query the sizes of the images in the file. */
  if ( ( rc = UMSImageReader_get_image_sizes( IR, ev, &sizes ) ) !=
    UMSImageReader_Success )
  {
    fprintf( stderr, "ERROR: failed get_image_sizes\n" );
    return( -1 );
  }
  sptr = sizes._buffer;
  printf( "The image sizes are:\n" );
  for ( i=0; i<sizes._length; i++ )
  {
    printf( "\twidth = %d height = %d\n",sptr->width, sptr->height );
    sptr++;
  }
  SOMFree( sizes._buffer );

Similarly, the get_image_count method can be used to determine the number of different images contained in a single image file. For example, a Photo CD overview file can contain over one hundred separate images.

Some file formats, such as JPEG and Photo CD, support the decoding of image data into a variety of formats, including 8-bit dithered and 24-bit RGB. The available formats can be queried with the get_formats method. Once the desired format is selected, it should be set using the set_format method. The following code fragment sets the format to 8-bit dithered RGB. (The file /usr/lpp/UMS/include/UMSStrings.h contains defines for image data formats.)

    rc = UMSImageReader_set_format(IR, ev, IF_RGB8Dither);

In the case of 8-bit RGB images, an application might require the color map associated with a image for further use (such as setting an X Windows color map). You can obtain the number of colors in an image's color map, the starting index of that map within a 256 element color map, and the color map itself as follows:

    /* Query the number of colors in the image and where they are */          /* located within a 256-color color map. */
    rc = UMSImageReader_get_colormap_attributes(IR, ev, &colormap_index,
         &colormap_size );
    if ( rc != UMSImageReader_Success )
    {
      fprintf( stderr, "ERROR: failed get_colormap_attributes\n" );
      return( -1 );
    }
    printf( "The image contains %d colors starting at index %d\n",
             colormap_size, colormap_index );
    /* Malloc space for the IDL sequence containing the color map. */
    colormap_t = malloc( sizeof( _IDL_SEQUENCE_octet ) );
    /* Initialize the colormap IDL sequence to indicate no colormap. */
    colormap_t->_buffer = NULL;
    colormap_t->_maximum = colormap_t->_length = 0;
    /* Get a copy of the image's color map. */
    if ( ( rc = UMSImageReader_get_colormap(IR, ev, colormap_t) ) !=
           UMSImageReader_Success )
    {
      fprintf( stderr, "ERROR: failed get_colormap\n" );
      return( -1 );
    }
  }

An application might need an image to dither an image to a smaller 8-bit color map than was used to create the image. This can be accomplished by using the methods set_colormap_attributes and set_colormap.

Once the image attributes are set to the desired values, the read_image method should be invoked to place the decoded image data into a buffer allocated by the application. If the entire image is desired, the input parameter "rect" can be set either to NULL or point to a UMSImageRect structure with all fields set to 0. If only a portion of the image is desired, "rect" should be set to the desired subimage coordinates. In all cases, the coordinates must be set either in the source coordinate system (that is, image space) or the destination coordinate system (that is, display space).

  /* Read the image data.  Whenever the image and display sizes are */      /* the same, either the source or destination coordinate system */ 
  /* flag could be specified. */
  if ( ( rc = UMSImageReader_read_image( IR, ev,                              DESTINATION_COORDINATE_SYSTEM,
    NULL, 0, &buffer ) ) != UMSImageReader_Success )
  {
    fprintf( stderr, "ERROR: failed reading image data\n" );
    return( -1 );
  }

Some image formats support scaling. The supports_arbitrary_scaling method allows applications to determine if scaling is supported by a particular image reader. If scaling is supported by an image reader, an application can scale the image by invoking the set_display_size method. If, for example, an image is 100 by 200 pixels, and a scaled image four times as large is desired, then set_display_size should be called with the values 200 and 400 set in the height and width fields of the input parameter "inSize." (Do not call set_display_size if you do not wish to scale.)

When the image reader object is no longer needed, the close method should be called:

 if ( ( rc = UMSImageReader_close( IR, ev ) ) != UMSImageReader_Success )
  {
    fprintf( stderr, "ERROR: failed closing image file\n" );
    return( -1 );
  }

For introductory information, see Programming with Formatted File Access Objects.


[ Previous | Next | Contents | Glossary | Home | Search ]