# An overview of the JIMI

## What Jimi is and does

Jimi is a class library for managing images. Its primary function is in image I/O, however it has a considerable range of supporting features for image viewing, managing large or very-large images independently of physical memory, extension for support new types of imaging, and more. Jimi’s range of supported formats include, to varying degreees, GIF(no compressed encoding) JPEG, TIFF, PNG, PICT, Photoshop, BMP, Targa, ICO, CUR, Sunraster, XBM, XPM, PCX, DCX.

Jimi’s format support can easily be extended via its Open Image I/O interface. Any format handler implemented under this interface will inherit all of Jimi’s powerful features. Using this interface, developers are able to create modules to support new formats and register them with the Jimi runtime system, instantly gaining access to features like Jimi’s Virtual Memory Management (“VMM”).

Jimi also provides its own set of image abstractions, not wholly compatible with a java.awt.Image. Jimi’s images provide fast RGB random-access to pixel data, even for images that are being stored in disk cache using Jimi’s VMM system. While these imaging classes provide powerful features for handling images, Jimi also provides interoperability with the AWT ImageProducer/ImageConsumer model, meaning that images created with Jimi can be exported for use as AWT images.

## General structure

Jimi’s core is a small set of classes for mediating between user requests, a set of encoders and decoders (called “format modules”), and support classes for managing images. The following figure and table show an overview of the most central classes.

## Core Class | ## Description
Jimi | Façade providing one-call access to all the most common image I/O operations.
JimiReader | Lower level front-end for talking with JimiDecoders. Provides loading multiple images from a single file.
JimiWriter | Lower level front-end for talking with JimiEncoders. Provides saving multiple images to a single file.
JimiControl | Manager of the central encoder/decoder pool. Used for registering new format modules, and finding appropriate modules based on filename, URL, mime type, and stream content.
JimiDecoder | Interface for decoder implementations. Defines methods for reading images.
JimiEncoder | Interface for encoder implementations. Defines methods for writing images.
JimiDecoderFactory | Factory interface for creating JimiDecoder objects. Defines methods for creating JimiDecoder instances, and for querying meta-information such as mime types, format signatures, and filename extensions.
JimiEncoderFactory | Factory interface for creating JimiEncoder objects. Defines methods for creating JimiEncoder instances, and for querying meta-information such as mime types and filename extensions.

Jimi, JimiReader, and JimiWriter cover the main user API for image I/O operations. Jimi itself does little work, just wrapping to JimiReader and JimiWriter, which are responsible for instantiating and delegating to format modules. Instantiation is managed through JimiControl, which finds an appropriate format module based on filename, URL mime-type, or stream content. Once the format module has been instantiated, the JimiReader or JimiWriter maps user requests to the module to handle the actual image I/O.

Collectively, these classes form a front-end to Jimi which keeps operations simple, for most operations a single method call, and keeping Jimi-based applications as simple as possible.

## Image abstractions

Although it provides interoperatbility with the AWT Image and ImageProducer system, Jimi uses its own set of abstractions for manipulating images, as shown in the following figure and table.

## Imaging Class | ## Description
## JimiImage | Highest level image abstraction. Defines methods for use as a java.awt.ImageProducer, for accessing format-specific properties, and for querying processing state.
## JimiRasterImage | Specialization of JimiImage for raster images. Defines methods for accessing pixel data as ARGB values, and querying image dimensions.
## JimiImageFactory | Factory interface for creating specific types of JimiImage.
## MutableJimiRasterImage | Specialization of JimiRasterImage for mutable images. Abstract base for further specialization to add getter-setter methods for specific types of pixel storage.
## ByteRasterImage | Specialization of MutableJimiRasterImage for byte-based pixels.
## IntRasterImage | Specialization of MutableJimiRasterImage for int-based pixels.
## BitRasterImage | Specialization of MutableJimiRasterImage for bit-based pixels. Pixels are packed 8-per-byte for memory-efficient mono-color images.

The top-level interface for images is JimiImage. JimiImage provides only the most generic operations, which can be supported by any type of image, whether it’s based on raster, vector, or something else. These operations include exporting to the AWT via an ImageProducer, checking for errors, and waiting for decoding completion. JimiRasterImage is the specialization for raster images, which are used throughout the present set of Jimi functionality. JimiRasterImage’s main addition to JimiImage is a set of methods for reading pixel data in standard Alpha/Red/Green/Blue form. Beyond this, a set of specialized interfaces is provided for creating JimiRasterImages for specific types of image data, such as byte-per-pixel, int-per-pixel, and bit-per-pixel. It is these interfaces which are used by decoders to create images suitable for their formats, and used by encoders to extract image data in the most appropriate form.

Instances of imaging classes are created using an abstract factory class called JimiImageFactory. This allows creation of specific types of image without being coupled with any specific implementation, so that different implementations can be used transparently. Jimi 2.0 provides three JimiImageFactory implementations: MemoryJimiImageFactory, VMemJimiImageFactory, and OneshotJimiImageFactory.

MemoryJimiImageFactory creates images that use memory-array storage of pixel data. This provides fast, reliable access to pixel data both for export via ImageProducer and for copying directly into arrays.

VMemJimiImageFactory creates images that store their pixel data in swap files on secondary storage. As data is requested, regions of pixels are transparently paged between memory and disk, buffering in memory only the parts of the image which are immediately required. This allows large images to be loaded with fixed memory requirements, and because typically only a relatively small amount of pixel data needs to be manipulated at any given time.

OneshotJimiImageFactory takes a very different approach to image production. Rather than storing pixel data itself, all pixel information is sent to the ImageConsumer request, and not stored persistently. This is used when Jimi’s images are not required, and a once off Image is required for fast display without memory overhead. This is ideal for applications that just need to get an image sent to the screen and have no need to later encode it or query it for specific pixel information.

## Extensibility

Because Jimi’s core is small and most functionality is provided by plugging in standard modules, Jimi is easy to extend beyond what is provided. The most obvious candidate for extension is the set of formats supported by Jimi. This is handled by allowing the addition of new format modules to Jimi at runtime. Once registered with JimiControl, these additional modules are treated in exactly the same way as Jimi’s core format set. Features likes VMM and one-shot production are automatically usable with any new modules, and appropriate format-signature and mime type mappings are added to the central registry.

More sophisticated extension is also possible. Because Jimi’s images are defined as interfaces, decoder implementers are free to create their own implementations. For example, a JimiRasterImage could be implemented to delegate all requests for pixels back to the decoder, which could scan the input file to extract the required region of image data. Indeed, most parts of Jimi could be modified to use entirely different behavior without conflicting with the existing implementations.

## Modularity

Because many of Jimi’s core features are implemented as extension modules, most features can be unplugged for the purposes of lightweight versions for specific functions. All the format modules, image filters, and even such core features as Virtual Memory Management and One-shot image production can be plugged in and unplugged easily. This means that Jimi can be tailored to match the needs of your application, with a smaller size footprint so that you only pay for what you use.

## Format-specific options

As well as normal image encoding and decoding, Jimi supports managing format-specific options of image files. The basic pieces supporting this are FormatOption objects, which are aggregated in FormatOptionSets. Each FormatOption describes a parameter which certain formats can take advantage of, such as a compression level for PNG, frame-delay for a GIF frame, or interlacing for a variety of formats. FormatOptionSets are used for specifying parameters for image encoding, as well as discovering the original properties of images that are decoded.