FileDocCategorySizeDatePackage
ImageToRawConverter.javaAPI DocphoneME MR2 API (J2ME)12434Wed May 02 18:00:26 BST 2007com.sun.midp.imageutil

ImageToRawConverter

public class ImageToRawConverter extends Object
This class generates raw data from image according to specified raw format and pixel format. Supported formats are listed in static formatList array. To add new supported format one should define new raw or/and color format constants if needed, update static formatList array, implement new conversion function byte[] _function_name_(BufferedImage image) and update imageToByteArray function to support new format.

Fields Summary
public static final int
FORMAT_INVALID
value for invalid format indication
public static final int
RAW_FORMAT_PP
Put Pixel raw format
public static final int
RAW_FORMAT_ARGB
RGBA raw format
public static final int
COLOR_FORMAT_888
pixel format - 24bit color
public static final int
COLOR_FORMAT_565
pixel format - 16bit color
public static final int
INT_FORMAT_LITTLE_ENDIAN
int byte order - little-endian
public static final int
INT_FORMAT_BIG_ENDIAN
int byte order - big-endian
static final int[]
formatList
list of supported pairs raw format - color format
static final short[]
rawMagic
byte sequence that indentifies raw format
protected int
rawFormat
current raw, color and int formats
protected int
colorFormat
protected int
intFormat
Constructors Summary
public ImageToRawConverter(int rawFormat, int colorFormat, int endian)
Constructs instance of ImageToRawConverter which will convert images to raw data in specified here format. Raw format and color format should be in list of supported formarts, otherwise IllegalArgumentException will be thrown.

param
rawFormat required raw format
param
colorFormat required color format
param
endian required int format
exception
IllegalArgumentException if unsupported format

        if (!isFormatSupported(rawFormat, colorFormat)) {
            throw new IllegalArgumentException("invalid format");
        }
        this.rawFormat = rawFormat;
        this.colorFormat = colorFormat;
        this.intFormat = endian;
    
Methods Summary
private shortRGB888TORGB565(int x)
Convert 24bit color to 16bit color

param
x the color in format 8bit-R 8bit-G 8bit-B to convert
return
int 16bit color in format 5bit-R 6bit-G 5bit-B

        return ((short)(((x & 0x00F80000) >> 8) + 
                ((x & 0x0000FC00) >> 5) + 
                ((x & 0x000000F8) >> 3)));
    
public byte[]convertToRaw(int[] imageData, int width, int height, boolean hasAlpha)
Converts image to raw data in byte array.

param
imageData image pixels in 32bit ARGB format
param
width image width
param
height image height
param
hasAlpha true if image has alpha channel
return
byte[] raw data

        if (imageData == null) {
            throw new IllegalArgumentException("Source image data is null");
        }

        byte [] ret = null;
        // build raw data
        if ((rawFormat == RAW_FORMAT_PP) && 
            (colorFormat == COLOR_FORMAT_565)) {
            ret = imageToPutpixel565(imageData, width, height, hasAlpha);
        } else if ((rawFormat == RAW_FORMAT_ARGB) && 
            (colorFormat == COLOR_FORMAT_888)) {
            ret = imageToARGB888(imageData, width, height, hasAlpha);
        }
        return ret;
    
voidfillRawHeader(byte[] rawData, int width, int height, boolean hasAlpha)
Fills byte array with raw header byte RAW_HEADER[4] = {0x89, 'S', 'U', 'N'}; int32 width; int32 height; int32 hasAlpha;

param
rawData byte array to fill header for, length of that array must be greater than 16, otherwise function fails (returns false)
param
width width of the image
param
height height of the image
param
hasAlpha if image has alpha channel

        int magicLength = rawMagic.length;
        for (int i = 0; i < magicLength; ++i) {
            rawData[i] = (byte)(rawMagic[i] & 0xFF);
        }
            
        storeValue(rawData, magicLength, width, intFormat);
        storeValue(rawData, magicLength + 4, height, intFormat);
        storeValue(rawData, magicLength + 8, 
                (int)(hasAlpha ? 1 : 0), intFormat);
    
private byte[]imageToARGB888(int[] imageData, int width, int height, boolean hasAlpha)
Converts image to ARGB with 24bits per pixel in big-endian. Output byte array represents the following c-struct: typedef struct { byte header[4]; // Must equal RAW_HEADER int32 width; int32 height; int32 hasAlpha; byte data[1]; // variable length byte array } MIDP_IMAGE_BUFFER_RAW; where RAW image file header const byte RAW_HEADER[4] = {0x89, 'S', 'U', 'N'}; and data array consists of image pixel array - 24bit per pixel, RGBA(8, 8, 8, 8)

param
imageData image pixels in 32 bit ARGB format
param
width image width
param
height image height
param
hasAlpha true if the image has alpha channel
return
byte[] raw data in RGBA format

        hasAlpha = reallyHasAlpha(imageData);

        // sizeof resulting raw buffer = 
        // sizeof(RAW_HEADER) + 
        // sizeof(MIDP_IMAGE_BUFFER_RAW.width) + 
        // sizeof(MIDP_IMAGE_BUFFER_RAW.height) + 
        // sizeof(MIDP_IMAGE_BUFFER_RAW.hasAlpha) + 
        // sizeof(pixe_l565) * image_pixel_count + 
        // (hasAlpha ? alpha_size * image_pixel_count : 0)

        int rawsz = 4 + 4 + 4 + 4 + 4 * imageData.length;
        int dataOffset = 4 + 4 + 4 + 4;

        byte[] rawData = new byte[rawsz];

        fillRawHeader(rawData, width, height, hasAlpha);

        for (int i = 0; i < imageData.length; ++i) {
            // write ARGB
            storeValue(rawData, dataOffset + i*4, imageData[i], intFormat);
        }

        return rawData;

    
private byte[]imageToPutpixel565(int[] imageData, int width, int height, boolean hasAlpha)
Converts image to PutPixel raw format, 16bit color format, big-endian. Output byte array represents the following c-struct: typedef struct { byte header[4]; // Must equal RAW_HEADER int32 width; int32 height; int32 hasAlpha; byte data[1]; // variable length byte array } MIDP_IMAGE_BUFFER_RAW; where RAW image file header const byte RAW_HEADER[4] = {0x89, 'S', 'U', 'N'}; and data array consists of image pixel array - 16bit per pixel, RGB(5, 6, 5) - and following alpha channel array if any - 8bit per pixel

param
imageData image pixels in 32 bit ARGB format
param
width image width
param
height image height
param
hasAlpha true if the image has alpha channel
return
byte[] raw data in PutPixel raw format and 16bit color format

        hasAlpha = reallyHasAlpha(imageData);

        // sizeof resulting raw buffer = 
        // sizeof(RAW_HEADER) + 
        // sizeof(MIDP_IMAGE_BUFFER_RAW.width) + 
        // sizeof(MIDP_IMAGE_BUFFER_RAW.height) + 
        // sizeof(MIDP_IMAGE_BUFFER_RAW.hasAlpha) + 
        // sizeof(pixe_l565) * image_pixel_count + 
        // (hasAlpha ? alpha_size * image_pixel_count : 0)

        int rawsz = 4 + 4 + 4 + 4 + 2 * imageData.length;
        int dataOffset = 4 + 4 + 4 + 4;
        int alphaOffset = rawsz;
        if (hasAlpha) rawsz += 1 * imageData.length;

        byte[] rawData = new byte[rawsz];
        
        fillRawHeader(rawData, width, height, hasAlpha);
        
        for (int i = 0; i < imageData.length; ++i) {
            short val = RGB888TORGB565(imageData[i]);
            storeValue(rawData, dataOffset + i * 2, val, intFormat);
            if (hasAlpha) {
                rawData[alphaOffset + i] = (byte)((imageData[i] >> 24) & 0xFF);
            }
        }

        return rawData;
    
public static booleanisFormatSupported(int rawFormat, int colorFormat)
Defines if format is currently supported.

param
rawFormat raw format
param
colorFormat color format
return
true if format is supported false otherwise


                                   
          
    
        for (int i = 0; i < formatList.length; ++i) {
            if ((formatList[i][0] == rawFormat) &&
                (formatList[i][1] == colorFormat)) {
                return true;
            }
        }
        return false;
    
private static booleanreallyHasAlpha(int[] imageData)
Checks if the image that supposely has alpha channel really has it, i.e there is at least one non opaque pixel.

param
imageData image data in 32 bits ARGB format
return
true if the image really has alpha channel

        boolean hasAlpha = false;
        for (int i = 0; i < imageData.length; ++i) {
            if ((imageData[i] & 0xFF000000) != 0xFF000000) {
                hasAlpha = true;
                break;
            }
        }

        return hasAlpha;
    
private static voidstoreValue(byte[] data, int offset, int value, int endian)
writes int to byte array at specified position in big- or little- endian.

param
data target byte array
param
offset offset in byte array
param
value source integer
param
endian endian type

        if (endian == INT_FORMAT_BIG_ENDIAN) {
            data[offset + 0] = (byte)((value >> 24) & 0xFF);
            data[offset + 1] = (byte)((value >> 16) & 0xFF);
            data[offset + 2] = (byte)((value >> 8) & 0xFF);
            data[offset + 3] = (byte)(value & 0xFF);
        } else { 
            data[offset + 0] = (byte)(value & 0xFF);
            data[offset + 1] = (byte)((value >> 8) & 0xFF);
            data[offset + 2] = (byte)((value >> 16) & 0xFF);
            data[offset + 3] = (byte)((value >> 24) & 0xFF);
        }
    
private static voidstoreValue(byte[] data, int offset, short value, int endian)
writes short to byte array at specified position in big- or little- endian.

param
data target byte array
param
offset offset in byte array
param
value source integer
param
endian endian type

        if (endian == INT_FORMAT_BIG_ENDIAN) {
            data[offset + 0] = (byte)((value >> 8) & 0xFF);
            data[offset + 1] = (byte)(value & 0xFF);
        } else { 
            data[offset + 0] = (byte)(value & 0xFF);
            data[offset + 1] = (byte)((value >> 8) & 0xFF);
        }