RISCOS.com

www.riscos.com Technical Support:
Programmer's Reference Manual

 

CompressJPEG


Introduction and Overview

The CompressJPEG module is available from RISC OS 3.6 onwards. It provides SWIs with which you can compress raw image data into a JPEG image. It is a port of release 5 of the Independent JPEG Group's software.

The module is not in the RISC OS 3.6 ROM, but is instead held in the System application. If you wish to use the module in a program, you should first use the following command to ensure it is loaded:

RMEnsure CompressJPEG 0.00 RMLoad System:Modules.JCompMod

To compress raw image data into a JPEG image, you start by calling CompressJPEG_Start, which sets up the compression environment. You then compress each row of the source image with a separate call to CompressJPEG_WriteLine. Finally you finish the compression by calling CompressJPEG_Finish.

Technical details

How JPEG images are compressed

JPEG files encode colour pictures as YUV (Y = intensity, U and V are colour) data. Compressing involves the following steps:

  • Convert RGB data to YUV.
  • Throw away 3 out of 4 of the U and V pixels.
  • Convert 8×8 tiles of Y, U and V values through a Discrete Cosine Transform, into an 8×8 square of frequency coefficients.
  • Discard coefficients which are zero, or close to zero. This will tend to change the visual appearance of the picture very little.
  • Reduce the accuracy with which the remaining coefficients are held (known as 'quantisation'). Again, this changes the appearance very little. The amount by which this is done, controls the compression factor of the image. By now, most of the coefficients will be zero.
  • Reorder the 64 coefficients in a zig-zag order, which increases the average length of runs of zeros in the coefficient block.
  • Huffman-encode the resulting stream of values.

(Incidentally, decompression involves reversing these steps.)

SWI calls


CompressJPEG_Start
(SWI &4A500)

Starts the JPEG compression process, setting up various parameters for it

On entry

R0 = pointer to buffer for JPEG data
R1 = size of JPEG data buffer
R2 = pointer to block of parameters:

    + width of image in pixels
    + height of image in pixels
    + quality value (0 - 100): lower quality results in a smaller image
    + 2 number of 8 bit components in source:
    3 => 24 BIT COLOUR_ 1 => 8 bit greyscale
    + 6 horizontal DPI of image, or 0 if unknown
    + 0 vertical DPI of image, or 0 if unknown
R3 = pointer to workspace area, or 0 for the CompressJPEG module to allocate its own workspace from the RMA
R4 = size of workspace area (if R3 [NOT EQUAL] 0)

On exit

R0 = JPEG tag, to be passed to other CompressJPEG SWIs

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

This call starts the JPEG compression process, setting up various parameters for it.

The buffer for the JPEG data should be as large as possible, since the JPEG compression routines cannot guarantee to compress the image by a fixed amount.

If you wish to supply your own workspace area, its required size for a colour (24 bit) image is:

20000 + ((image width rounded up to a multiple of 16) × 30)

and its required size for a greyscale (8bit) image is:

20000 + ((image width rounded up to a multiple of 16) × 9)

An error is returned if the workspace area becomes full.

Related SWIs

CompressJPEG_WriteLine, CompressJPEG_Finish

Related vectors

None


CompressJPEG_WriteLine
(SWI &4A501)

Compresses one row of source pixels into the JPEG buffer

On entry

R0 = JPEG tag
R1 = pointer to a row of pixels:

For colour: a buffer of continuous RGB values - ie a byte stream of the format R, G, B, R, G, B...
For greyscale: a buffer of continuous 8 bit gray values
On exit

R0, R1 preserved

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

This call compresses one row of source pixels into the JPEG buffer. It should be called once for each row of the source data.

An error is returned if the JPEG buffer becomes full.

Related SWIs

CompressJPEG_Start, CompressJPEG_Finish

Related vectors

None


CompressJPEG_Finish
(SWI &4A502)

Finishes the JPEG compression process, returning the size of the complete image

On entry

R0 = JPEG tag

On exit

R0 = size of JPEG image within the buffer

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

This call finishes the JPEG compression process, returning the size of the complete image. Any workspace claimed by the CompressJPEG module for the compression is released.

Related SWIs

CompressJPEG_Start, CompressJPEG_WriteLine

Related vectors

None

Example program

The pseudo-code below shows you how you might convert a 32 bpp sprite into a JPEG:

/* Pseudo C code for converting a 32bpp sprite to a JPEG */
Allocate buffer for JPEG                  = JPEG_buffer;
Allocate buffer for workspace             = workspace_buffer;
Allocate buffer for line of source pixels = line_buffer;
argument_block arguments;
arguments.width          = sprite_width_in_pixels;
arguments.height         = sprite_height_in_pixels;
arguments.quality        = quality;
arguments.components     = 3;
arguments.horizontal_dpi = 0;
arguments.vertical_dpi   = 0;
sprite_pointer = start_of_data_within_sprite;
JPEG_tag = CompressJPEG_Start(JPEG_buffer,
                              JPEG_buffer_size,
                              arguments,
                              workspace_buffer,
                              workspace_buffer_size);
for loop = 1 to sprite_height_in_pixels
{
  convert_sprite_data_to_rgb(sprite_pointer, line_buffer);
  CompressJPEG_WriteLine(JPEG_tag, line_buffer);
  sprite_pointer += sprite_width_in_words;
}
CompressJPEG_Finish(JPEG_tag);

This edition Copyright © 3QD Developments Ltd 2015
Last Edit: Tue,03 Nov 2015