PRUint8 *alphaBits, *rgbBits; PRUint32 alphaLen, rgbLen; PRUint32 alphaStride, rgbStride;
PRUint8 *alphaBits = nsnull, *rgbBits; PRUint32 alphaLen = 0, rgbLen; PRUint32 alphaStride = 0, rgbStride;
static nsresult CopyCairoImageToIImage(PRUint8* aData, PRInt32 aWidth, PRInt32 aHeight,    gfxIImageFrame* aImage){  PRUint8 *alphaBits, *rgbBits;  PRUint32 alphaLen, rgbLen;  PRUint32 alphaStride, rgbStride;  nsresult rv = aImage->LockImageData();  if (NS_FAILED(rv)) {    return rv;  }#ifndef XP_WIN  rv = aImage->LockAlphaData();  if (NS_FAILED(rv)) {    aImage->UnlockImageData();    return rv;  }#endif  rv = aImage->GetImageBytesPerRow(&rgbStride);  rv |= aImage->GetImageData(&rgbBits, &rgbLen);#ifndef XP_WIN  rv |= aImage->GetAlphaBytesPerRow(&alphaStride);  rv |= aImage->GetAlphaData(&alphaBits, &alphaLen);#endif  if (NS_FAILED(rv)) {    aImage->UnlockImageData();#ifndef XP_WIN    aImage->UnlockAlphaData();#endif    return rv;  }  nsCOMPtr<nsIImage> img(do_GetInterface(aImage));  PRBool topToBottom = img->GetIsRowOrderTopToBottom();  for (PRUint32 j = 0; j < (PRUint32) aHeight; j++) {    PRUint8 *inrow = (PRUint8*)(aData + (aWidth * 4 * j));    PRUint32 rowIndex;    if (topToBottom)      rowIndex = j;    else      rowIndex = aHeight - j - 1;    PRUint8 *outrowrgb = rgbBits + (rgbStride * rowIndex);#ifndef XP_WIN    PRUint8 *outrowalpha = alphaBits + (alphaStride * rowIndex);#endif    for (PRUint32 i = 0; i < (PRUint32) aWidth; i++) {#ifdef IS_LITTLE_ENDIAN      PRUint8 b = *inrow++;      PRUint8 g = *inrow++;      PRUint8 r = *inrow++;      PRUint8 a = *inrow++;#else      PRUint8 a = *inrow++;      PRUint8 r = *inrow++;      PRUint8 g = *inrow++;      PRUint8 b = *inrow++;#endif      // now recover the real bgra from the cairo      // premultiplied values      if (a == 0) {        // can't do much for us if we're at 0        b = g = r = 0;      } else {        // the (a/2) factor is a bias similar to one cairo applies        // when premultiplying        b = (b * 255 + a / 2) / a;        g = (g * 255 + a / 2) / a;        r = (r * 255 + a / 2) / a;      }#ifndef XP_WIN      *outrowalpha++ = a;#endif#ifdef XP_MACOSX      // On the mac, RGB_A8 is really RGBX_A8      *outrowrgb++ = 0;#endif#ifdef XP_WIN      // On windows, RGB_A8 is really BGR_A8.      // in fact, BGR_A8 is also BGR_A8.      // Preblend with white since win32 printing can't deal with RGBA      MOZ_BLEND(*outrowrgb++, 255, b, (unsigned)a);      MOZ_BLEND(*outrowrgb++, 255, g, (unsigned)a);      MOZ_BLEND(*outrowrgb++, 255, r, (unsigned)a);#else      *outrowrgb++ = r;      *outrowrgb++ = g;      *outrowrgb++ = b;#endif    }  }#ifndef XP_WIN  rv = aImage->UnlockAlphaData();#else  rv = NS_OK;#endif  rv |= aImage->UnlockImageData();  if (NS_FAILED(rv))    return rv;  nsRect r(0, 0, aWidth, aHeight);  img->ImageUpdated(nsnull, nsImageUpdateFlags_kBitsChanged, &r);  return NS_OK;}