public static WritableRaster CIEXYZToRGB(Raster src,
                                             int[] srcComponentSize,
                                             WritableRaster dest,
                                             int[] destComponentSize) {

	// Validate the parameters
        checkParameters(src, srcComponentSize, dest,destComponentSize) ;

	SampleModel srcSampleModel = src.getSampleModel() ;

	/*if the parameter srcComponentSize is null, use the sample size
	 * of the source raster.
	 */
	if (srcComponentSize == null)
	    srcComponentSize = srcSampleModel.getSampleSize() ;

	// if the destination raster is null, create a new WritableRaster
	if (dest == null) {
	    Point origin = new Point(src.getMinX(), src.getMinY()) ;
	    dest = RasterFactory.createWritableRaster(srcSampleModel,
						      origin) ;
	}

	/* if the parameter dstComponentSize is null, use the sample size
	 * of the source raster.
	 */
	SampleModel dstSampleModel = dest.getSampleModel() ;
	if (destComponentSize == null)
	    destComponentSize = dstSampleModel.getSampleSize() ;

        PixelAccessor srcAcc = new PixelAccessor(srcSampleModel, null) ;
        UnpackedImageData srcUid
	    = srcAcc.getPixels(src, src.getBounds(),
                               srcSampleModel.getDataType(), false) ;

	switch (srcSampleModel.getDataType()) {

	case DataBuffer.TYPE_BYTE:
	     CIEXYZToRGBByte(srcUid, srcComponentSize,
			     dest, destComponentSize) ;
	     break ;
	case DataBuffer.TYPE_USHORT:
	case DataBuffer.TYPE_SHORT:
	     CIEXYZToRGBShort(srcUid, srcComponentSize,
			      dest, destComponentSize) ;
	     break ;
	case DataBuffer.TYPE_INT:
	     CIEXYZToRGBInt(srcUid, srcComponentSize,
			    dest, destComponentSize) ;
	     break ;
	case DataBuffer.TYPE_FLOAT:
	     CIEXYZToRGBFloat(srcUid, srcComponentSize,
			      dest, destComponentSize) ;
	     break ;
	case DataBuffer.TYPE_DOUBLE:
	     CIEXYZToRGBDouble(srcUid, srcComponentSize,
			       dest, destComponentSize) ;
	     break ;
	}

	return dest ;
    }