ConvertPNG
Introduction
Developing from the initial PNG module supplied with RISC OS Select release 1 a new module dedicated to converting PNG images to sprites has been created. This module performs simple conversion of PNG images to standard RISC OS sprites. For more advanced uses clients can use the PNG operations from the PNG module itself without the ConvertPNG module. Many users will find that the interface provided by ImageFileConvert is more suitable.
PNG to sprite conversion
The PNG to Sprite conversion performed by the ConvertPNG module should allow PNG images to be imported into applications and rendered as native images. The operation of the PNG to Sprite conversion is usually hidden from the user as the conversion is usually performed implicitly as required. The ImageFileRender component will, via the ImageFileConvert tools, convert PNG files to sprites for rendering through the native sprite rendering routines.
Because of differences in the sprite and PNG format the images produced may not correspond to the original form of the image. Such conversions should not result in a reduction in image quality except where 16 bit per channel data is used. No 16 bit per channel format is defined for RISC OS and as a result all 16 bit per channel data will be reduced to 8 bit per channel. Such images are rare and this limitation should not pose a problem for users. Applications wishing to manipulate 16 bit per channel data should consider using the PNG module library directly.
The sBIT chunk
The sBIT chunk on a 24 bpp image declares the number of significant bits of image data in the original image. Such chunks will force the output sprite to be 16 bpp if, and only if, all three channels are 5 bits wide. All other representations declared in the sBIT chunk are ignored.
The pHYs chunk
The pHYs chunk declares the physical dimensions of the image. Where possible this will be retained, but it will be rounded to the nearest suitable sprite pixel size (11, 23, 45, 90 or 180 DPI). This should ensure that the approximate ratio of the source image is retained.
The gAMA chunk
The gAMA chunk - describing the gamma value of the image - is honoured, converting the image data according to the gamma correction specified in the file. This should ensure that the image is rendered correctly. Applications wishing to have greater control over the gamma correction features of PNGs should consider using the PNG module library directly.
The bKGD chunk
The bKGD chunk declares the colour that the image should be composed against if transparency is not present. This chunk is only processed if a background is requested and the natural background (background of -1) used. Images created through the ImageFileRender interface to ImageFileConvert will never use the bKGD chunk - they will always be masked if a mask of some form is present.
Masking through the tRNS chunk and alpha channels
The tRNS chunk provides information about transparent palette entries or a single colour which should be regarded as transparent. Such entries will be honoured and the image converted use an alpha channel mask. Images with alpha channel will be create sprites in the new format allowing alpha channel data in the 8bpp mask.
After the image has been generated its mask is examined. If it is found to be a binary mask (containing only fully transparent and fully opaque entries) the 8 bpp mask will be reduced to a 1 bpp mask. If it is found that no mask is present (the entire image is fully opaque) the mask will be removed entirely.
Greyscale images
Greyscale images will be converted to the equivalent paletted image. Greyscale images with alpha channel will be converted to 8 bpp sprites with alpha channel.
Known issues
True colour, or greyscale PNGs with 16 bit per channel and a tRNS entry referring to a colour which, when reduced to 8 bits per channel, is in use as part of the image, are masked incorrectly.
Sprite to PNG conversion
The Sprite to PNG conversion is performed by the ConvertPNG module. Because of differences in the capabilities of the formats, it may be necessary for the image format to be promoted to a wider format. For example, a 1bpp image may be promoted to 2bpp if it is not possible to represent the image data accurately as a PNG. None of the conversions should result in a reduction in image quality.
The following translations are performed on sprites :
Unpaletted 1 bpp, 2 bpp, 4 bpp and 8 bpp images
These are given the default desktop palette for their depth.
Images without masks
1 bpp, 2 bpp, 4 bpp, 8 bpp images
These are converted to paletted colour PNG images.
16 bpp images
These are converted to 24 bpp colour PNG images, with an sBIT chunk indicating that 5 bits are used per channel.
24 bpp images
These are converted to 24 bpp colour PNG images.
CMYK images
The image is converted to RGB and a 24 bpp PNG image is created.
Images with binary masks
1 bpp, 2 bpp, 4 bpp images
These are converted to paletted colour PNG images. A tRNS chunk is used to represent an unused palette entry as the mask. If all palette entries are used within the image, the image will be promoted to the next highest depth (1 bpp promoted to 2 bpp, 2 bpp promoted to 4 bpp, 4 bpp promoted to 8 bpp).
8 bpp images
If the image contains an unused palette entry, these are converted to paletted colour PNG images. A tRNS chunk is used to represent the mask. If no unused palette entries exist, the image is converted to a 24 bpp PNG with an alpha channel.
16 bpp images
If a region of the colour cube can be found which is not used, these are converted to 24 bpp colour PNG images, with a tRNS chunk indicating an unused colour entry as the mask. If a region cannot be found, the image is promoted to a 24 bpp colour PNG with an alpha channel. Either way, an sBIT chunk indicating that 5 bits are used per channel.
24 bpp images
If a region of the colour cube can be found which is not used, these are converted to 24 bpp colour PNG images, with a tRNS chunk indicating an unused colour entry as the mask. If a region cannot be found, the image is promoted to a 24 bpp colour PNG with an alpha channel.
CMYK images
The image is converted to RGB and a 24 bpp PNG image with alpha channel is created.
Images with alpha channel (8 bpp masks)
1 bpp, 2 bpp, 4 bpp, 8bpp, 24 bpp images
These are converted to 24 bpp PNG images with alpha channel.
16 bpp images
These are converted to 24 bpp PNG images with alpha channel, with an sBIT chunk indicating that 5 bits are used per channel
CMYK images
These are converted to RGB and a 24 bpp PNG image with alpha channel is created.
Deep sprites with binary masks
The algorithm used by the 16 bpp and 24 bpp binary mask conversions to locate an unused region of the image calculates the colour coverage of the image using a quantised form of the colour cube (4 bits per dimension). The image is examined and pixels within the image are flagged as being 'present' in the quantised cube. Once complete, the cube is searched for an unused cell. If no such cell can be found the image is deemed to be complex and will be promoted to alpha channel. If a free cell is found its colour will be used in the output image as part of the tRNS chunk.
Pixel dimensions
The pixel dimensions will be written to the image in the form of a pHYs chunk. This chunk describes the pixel dimensions in pixels per metre. Not all PNG processing tools and renderers handle the pHYs chunk, so images in non-square modes may be processed incorrectly by such tools.
Creator information
PNG images are always created with a text chunk describing the creator as 'ConvertPNG <version and date>'.
Other sprite formats
Sprite formats other than those described in the above paragraphs are not supported in the current version of the ConvertPNG module.
SWIs
SWI ConvertPNG_Info (&564C2)
On entry
R0 = flags (all reserved, must be zero)
R1 = pointer to PNG data
R2 = length of PNG data
On exit
R0 = width of PNG
R1 = height of PNG
R2 = bit depth (as stored in the PNG, ignoring sBIT chunks)
R3 = colour type :
Bit Meaning if set
0 Image has palette
1 Image is colour
2 Image has alpha channel
Others reserved
If bit 0 and bit 1 are clear, the image is greyscale.
R4 = interlace type :
0 No interlacing
1 Adam7 interlacing
This SWI is used to read simple information about a PNG in order to provide feedback to the user or as an indication of the requirements of an image. More complex information can be obtained by direct access to the PNG module.
SWI ConvertPNG_CreateSprite (&564C1)
On entry
R0 = flag bits :
bit 0 = Create sprite area, not sprite if set
bit 1 = If set use the background chunk if provided,
or the background colour in R5 if none is provided
Others reserved, must be zero
R1 = pointer to PNG data
R2 = length of PNG data
R3 = pointer to output sprite buffer, or 0 to read size
R4 = size of output sprite buffer, or 0 to read size
R5 = colour (&BBGGRR00) for background, or -1 for default
On exit
R4 = size of output sprite buffer required (if R3 = 0 on entry),
size of output sprite buffer used (if R3 not 0 on entry)
This SWI is used to create a sprite from a PNG file. It should usually be called twice, once to read the memory requirements and again to create the sprite itself. The space required by the first call may be larger than that actually used as additional workspace is required for certain conversion types. On exit from the conversion call R4 will reflect the actual size of the converted data. The sprite name is undefined and should be set by the application. Present implementations set the sprite name to '!'. The data created will be a raw sprite unless bit 1 of the flags is set. Clients wishing to operate on sprite areas may set bit 1, or to create an area header to precede the sprite itself. Clients wishing to merge sprite areas should ensure that sufficient space exists in the sprite area they are appending to.
|