line++; } else { #ifdef XP_WIN *cptr++ = 0; *cptr++ = 0; *cptr++ = 0; #else cptr += 3; #endif line += 4;
row_callback(png_structp png_ptr, png_bytep new_row,             png_uint_32 row_num, int pass){  /* libpng comments:   *   * this function is called for every row in the image.  If the   * image is interlacing, and you turned on the interlace handler,   * this function will be called for every row in every pass.   * Some of these rows will not be changed from the previous pass.   * When the row is not changed, the new_row variable will be NULL.   * The rows and passes are called in order, so you don't really   * need the row_num and pass, but I'm supplying them because it   * may make your life easier.   *   * For the non-NULL rows of interlaced images, you must call   * png_progressive_combine_row() passing in the row and the   * old row.  You can call this function for NULL rows (it will   * just return) and for non-interlaced images (it just does the   * memcpy for you) if it will make the code easier.  Thus, you   * can just do this for all cases:   *   *    png_progressive_combine_row(png_ptr, old_row, new_row);   *   * where old_row is what was displayed for previous rows.  Note   * that the first pass (pass == 0 really) will completely cover   * the old row, so the rows do not have to be initialized.  After   * the first pass (and only for interlaced images), you will have   * to pass the current row, and the function will combine the   * old row and the new row.   */  nsPNGDecoder *decoder = NS_STATIC_CAST(nsPNGDecoder*, png_get_progressive_ptr(png_ptr));  PRUint32 bpr, abpr;  decoder->mFrame->GetImageBytesPerRow(&bpr);  decoder->mFrame->GetAlphaBytesPerRow(&abpr);  png_bytep line;  if (decoder->interlacebuf) {    line = decoder->interlacebuf+(row_num*decoder->ibpr);    png_progressive_combine_row(png_ptr, line, new_row);  }  else    line = new_row;  if (new_row) {    nscoord width;    decoder->mFrame->GetWidth(&width);    PRUint32 iwidth = width;    gfx_format format;    decoder->mFrame->GetFormat(&format);    PRUint8 *aptr, *cptr;    // The mac specific ifdefs in the code below are there to make sure we    // always fill in 4 byte pixels right now, which is what the mac always    // allocates for its pixel buffers in true color mode. This will change    // when we start storing images with color palettes when they don't need    // true color support (GIFs).    switch (format) {    case gfxIFormats::RGB:    case gfxIFormats::BGR:#ifdef XP_MAC        cptr = decoder->colorLine;        for (PRUint32 x=0; x<iwidth; x++) {          *cptr++ = 0;          *cptr++ = *line++;          *cptr++ = *line++;          *cptr++ = *line++;        }        decoder->mFrame->SetImageData(decoder->colorLine, bpr, row_num*bpr);#else        decoder->mFrame->SetImageData((PRUint8*)line, bpr, row_num*bpr);#endif      break;    case gfxIFormats::RGB_A1:    case gfxIFormats::BGR_A1:      {        cptr = decoder->colorLine;        aptr = decoder->alphaLine;        memset(aptr, 0, abpr);        for (PRUint32 x=0; x<iwidth; x++) {#ifdef XP_MAC          *cptr++ = 0;#endif          *cptr++ = *line++;          *cptr++ = *line++;          *cptr++ = *line++;          if (*line++) {            aptr[x>>3] |= 1<<(7-x&0x7);          }        }        decoder->mFrame->SetAlphaData(decoder->alphaLine, abpr, row_num*abpr);        decoder->mFrame->SetImageData(decoder->colorLine, bpr, row_num*bpr);      }      break;    case gfxIFormats::RGB_A8:    case gfxIFormats::BGR_A8:      {        cptr = decoder->colorLine;        aptr = decoder->alphaLine;        for (PRUint32 x=0; x<iwidth; x++) {#ifdef XP_MAC          *cptr++ = 0;#endif          *cptr++ = *line++;          *cptr++ = *line++;          *cptr++ = *line++;          *aptr++ = *line++;        }        decoder->mFrame->SetAlphaData(decoder->alphaLine, abpr, row_num*abpr);        decoder->mFrame->SetImageData(decoder->colorLine, bpr, row_num*bpr);      }      break;    case gfxIFormats::RGBA:    case gfxIFormats::BGRA:#ifdef XP_MAC      {        cptr = decoder->colorLine;        aptr = decoder->alphaLine;        for (PRUint32 x=0; x<iwidth; x++) {          *cptr++ = 0;          *cptr++ = *line++;          *cptr++ = *line++;          *cptr++ = *line++;          *aptr++ = *line++;        }        decoder->mFrame->SetAlphaData(decoder->alphaLine, abpr, row_num*abpr);        decoder->mFrame->SetImageData(decoder->colorLine, bpr, row_num*bpr);      }#else      decoder->mFrame->SetImageData(line, bpr, row_num*bpr);#endif      break;    }    nsRect r(0, row_num, width, 1);    decoder->mObserver->OnDataAvailable(nsnull, nsnull, decoder->mFrame, &r);  }}