for (int i = srcComponentsLength - 1; i >= 0; i--)
for (int i = srcComponentsLength - 2; i >= 0; i--)
  public void compose(Raster src, Raster dstIn, WritableRaster dstOut)  {    // TODO: This implementation is very general and highly inefficient. There    // are two possible ways to optimize this:    // 1. Special cased implementations for common ColorModels and transfer    //    types.    // 2. Native implementation.    int x0 = src.getMinX();    int y0 = src.getMinY();    int width = src.getWidth();    int height = src.getHeight();    int x1 = x0 + width;    int y1 = y0 + height;    Object srcPixel = null;    Object dstPixel = null;    // Prepare the array that holds the color and alpha components of the    // source pixels.    float[] srcComponents;    int srcComponentsLength = srcColorModel.getNumComponents();    if (! srcColorModel.hasAlpha())      srcComponentsLength += 1;    srcComponents = new float[srcComponentsLength];    // Prepare the array that holds the color and alpha components of the    // destination pixels.    float[] dstComponents;    int dstComponentsLength = dstColorModel.getNumComponents();    if (! dstColorModel.hasAlpha())      dstComponentsLength += 1;    dstComponents = new float[dstComponentsLength];    if (srcComponentsLength != dstComponentsLength)      throw new AWTError("The color models of the source and destination have"                         + "incompatible number of color components");    int srcTransferType = srcColorModel.getTransferType();    int dstTransferType = dstColorModel.getTransferType();    for (int y = y0; y < y1; y++)      {        for (int x = x0; x < x1; x++)          {            // Fetch source pixel.            srcPixel = src.getDataElements(x, y, (int[]) srcPixel);            // Fetch destination pixel.            dstPixel = dstIn.getDataElements(x, y, dstPixel);            // Get normalized components. This is the only type that is            // guaranteed to be supported by all ColorModels.            srcComponents =              srcColorModel.getNormalizedComponents(srcPixel, srcComponents, 0);            if (! srcColorModel.hasAlpha())              srcComponents[srcComponentsLength - 1] = 1.0F;            dstComponents =              dstColorModel.getNormalizedComponents(dstPixel, dstComponents, 0);            if (! dstColorModel.hasAlpha())              dstComponents[dstComponentsLength - 1] = 1.0F;            // Prepare the input.            float compositeAlpha = composite.getAlpha();            srcComponents[srcComponentsLength - 1] *= compositeAlpha;            if (srcColorModel.isAlphaPremultiplied())              {                for (int i = srcComponentsLength - 2; i >= 0; i--)                  srcComponents[i] *= compositeAlpha;              }            else              {                for (int i = srcComponentsLength - 1; i >= 0; i--)                  srcComponents[i] *= srcComponents[srcComponentsLength - 1];              }            if (! dstColorModel.isAlphaPremultiplied())              {                for (int i = dstComponentsLength - 2; i >= 0; i--)                  dstComponents[i] *= dstComponents[dstComponents.length - 1];              }            // Determine the blending factors according to the rule in the            // AlphaComposite. For some rules the factors must be determined            // dynamically because they depend on the actual pixel value.            float srcAlpha = srcComponents[srcComponentsLength - 1];            float dstAlpha = dstComponents[dstComponentsLength - 1];            switch (composite.getRule())            {              case AlphaComposite.DST_ATOP:                fs = 1.F - dstAlpha;                fd = srcAlpha;                break;              case AlphaComposite.DST_IN:                fd = srcAlpha;                break;              case AlphaComposite.DST_OUT:                fd = 1.F - srcAlpha;                break;              case AlphaComposite.DST_OVER:                fs = 1.F - dstAlpha;                break;              case AlphaComposite.SRC_ATOP:                fs = srcAlpha;                fd = 1.F - srcAlpha;                break;              case AlphaComposite.SRC_IN:                fs = dstAlpha;                break;              case AlphaComposite.SRC_OUT:                fs = 1.F - dstAlpha;                break;              case AlphaComposite.SRC_OVER:                fd= 1.F - srcAlpha;                break;              case AlphaComposite.XOR:                fs = 1.F - dstAlpha;                fd= 1.F - srcAlpha;                break;              default:                // For the other cases the factors have already been determined                // in the constructor.            }            // Apply the blending equation to the pixels.            for (int i = 0; i < srcComponentsLength; i++)              {                dstComponents[i] = srcComponents[i] * fs                                   + dstComponents[i] * fd;              }            // Convert the result back when the destination is not            // alpha-premultiplied.            dstAlpha = dstComponents[dstComponentsLength - 1];            if (!dstColorModel.isAlphaPremultiplied() && dstAlpha != 0.F)              {                for (int i = 0; i < dstComponentsLength - 1; i++)                  {                    dstComponents[i] = dstComponents[i] / dstAlpha;                   }              }            // Store the result in the destination raster.            dstPixel = dstColorModel.getDataElements(dstComponents, 0,                                                     dstPixel);            dstOut.setDataElements(x, y, dstPixel);          } // End X loop.      } // End Y loop.  }