Solid Fluid System Solutions  
Home Software About Hardware Firmware
Current Document Icon LibJPEG
Document Icon Modifications
Document Icon Mods - jbufferdst.cpp
Document Icon Mods - jbuffersrc.cpp
Document Icon ToJPEG
Document Icon FromJPEG

LibJPEG

LibJPEG is another amazing resource. It doesn't have quite the spiffy nature of LibPNG and ZLib, but if it's the code that counts for you, then LibJPEG has got the beans. As we say, there aren't any fancy pictures or amiable narration, but the homepage is everything you could expect.

The actual libraries can be downloaded from the IJG website here. The IJG site has some FAQ's but if you're a programmer you're probably going to want more detail. Fear not because they include Word documents in the distributable zip file, along with all of the sources for their library and command line applications. It has all the information one could ever want about both installing the command line tool and using the core library in a standalone way, such as we are.

Of course, there's a wiki page too.

In summary, JPEG, is a variably lossy image compression format. As the image quality reductions are requested, the actual image file size reduces. In addition to this capability, it must be noted that as the quality is reduced, it can never be reconstituted. Perhaps if the original data is retained, it will be possbile save the image to a lossless format like PNG. The actual benefit to JPEG is that it has the capability to compress images to a much greater degree than lossless schemes, like PNG, whilst also maintaining the legibility of the image. In general terms this image format achieves this feat, by prioritising the sort of data a viewer will and will not miss. It selectively disposes of information least missed first. Typically JPEG is very good at compressing images and scenes, diagrams it will struggle with. The early (and very common) JPEG format supported by this library does not support transparency, merely 24bpp colour images.

Transparency is offered by the JPEG2000 format which is not supported by this library. Given the sort of images that JPEG deals with, the benefit of transparency is not immediately clear. It is understood that the compression capabilities of JPEG2000 are improved. From what is easily available on the internet, it's not too clear that it makes any improvement over JPEG for charts and diagrams. Until perhaps the format deals with these issues of compessing diagrams, it is predicted that the JPEG2000 format will be somewhat slow on the uptake, by computer users.

As, perhaps, you will have come to expect we have made modifications to LibJPEG in order to make it functional in our environment. As usual we make all the standard disclaimers about not wanting to be a bad net neighbour, so we don't distribute the sources ourselves. We do, however, include the modifications that we have made to those libraries for reference. Prototypes for modified functions are as follows;

GLOBAL(void *) jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject);
GLOBAL(void) jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject);
GLOBAL(void FAR *) jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject);
GLOBAL(void) jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject);

Like the PNG library, the JPEG library, interfaces the JPEG data through a file by default. We duplicated the existing buffering mechanism and modified it to suit our own aims. Our modified buffering functions to allow us to supply and receive JPEG data as a memory block. Declarations of structures, and prototypes of functions modifed are given;

/* jbuffersrc.cpp */
typedef struct {
  struct jpeg_source_mgr pub;	/* public fields */

  unsigned char * inbuf;
  unsigned long insize;
  unsigned long inptr;

  JOCTET * buffer;		/* start of buffer */
} my_source_mgr;

METHODDEF(void) init_source (j_decompress_ptr cinfo);
METHODDEF(boolean) fill_input_buffer (j_decompress_ptr cinfo);

/* jbufferdst.cpp */
typedef struct {
  struct jpeg_destination_mgr pub; /* public fields */

  unsigned char ** outbuf;		/* target buffer */
  unsigned long * outsize;

  JOCTET * buffer;		/* start of buffer */
} my_destination_mgr;

METHODDEF(void) init_destination (j_compress_ptr cinfo);
METHODDEF(boolean) empty_output_buffer (j_compress_ptr cinfo);
METHODDEF(void) term_destination (j_compress_ptr cinfo);

These modifications are made in the form of updated replications of existing library source files which are then added to the source code pool for LibJPEG. We have shown these modifications as separate pages adjacent, under their new filenames, "jbuffersrc.cpp" and "jbufferdst.cpp", respectively.

Our overall implementation of the JPEG library is much the same as it is for GIF and PNG. The interface is described below;

typedef struct
{
	// Percentage 0=poor 100=good
	int Quality;	

	unsigned long XDim;
	unsigned long YDim;
	unsigned long LineSize;
}ImgJPEGInfo;

void jpeg_ToJPEG(void*& pBuf,unsigned long& BufSz,ImgJPEGInfo& Info);
void jpeg_FromJPEG(void*& pBuf,unsigned long& BufSz,ImgJPEGInfo& Info);

Our JPEG interface follows the format of our other image library interfaces, first described in LibPNG. For more general details see the description at that link. The notable difference here is that the all important BitCount parameter is missing, and seems to have been replaced by a quality parameter. In simple terms this interface deals only with 24bpp non-paletted images. There's no point in trying to convert anything other than 24bpp images with ToJPEG(), it just won't work.

The quality factor is a guide, when converting bitmaps to JPEG, indicating how much of a loss, or alternatively how much compression is required. When an image is converted from JPEG to bitmap, this parameter is set to 50%. The instructions that come with the libary tend to indicate that maximum quality is 100%, and given that this is a lossy format, one would think that 100% is a unity gain factor of the system. In practice this seems not to be the case. In fact it seems that 50% is unity, with (obviously) little improvement in the image quality above this value. Clearly the compression scheme is unable to add anything more than entropy, at best. At around 70% aberrations begin to appear. Since there seems to be little loss at 50%, the value is set on retrieval of a JPEG in bitmap format. This (with hope!) ensures that a loaded JPEG, converted to bitmap format, which is then converted directly back to JPEG, will not lose image quality.

Copyright © Solid Fluid 2007-2022
Last modified: SolFlu  Tue, 16 Jun 2009 18:53:33 GMT