png_set_gAMA(png_ptr, info_ptr, aGamma); }
info_callback(png_structp png_ptr, png_infop info_ptr){/*  int number_passes;   NOT USED  */  png_uint_32 width, height;  int bit_depth, color_type, interlace_type, compression_type, filter_type;  int channels;  double aGamma;  png_bytep trans=NULL;  int num_trans =0;  /* always decode to 24-bit RGB or 32-bit RGBA  */  png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,               &interlace_type, &compression_type, &filter_type);  if (color_type == PNG_COLOR_TYPE_PALETTE)    png_set_expand(png_ptr);  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)    png_set_expand(png_ptr);  if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {    png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL);    png_set_expand(png_ptr);  }  if (bit_depth == 16)    png_set_strip_16(png_ptr);  if (color_type == PNG_COLOR_TYPE_GRAY ||      color_type == PNG_COLOR_TYPE_GRAY_ALPHA)      png_set_gray_to_rgb(png_ptr);#if defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON)  // windows likes BGR  png_set_bgr(png_ptr);#endif  if (png_get_gAMA(png_ptr, info_ptr, &aGamma)) {      if (aGamma < 0)          aGamma = 0.45455;      png_set_gamma(png_ptr, 2.2, aGamma);  }  else      png_set_gamma(png_ptr, 2.2, 0.45455);  /* let libpng expand interlaced images */  if (interlace_type == PNG_INTERLACE_ADAM7) {    /* number_passes = */    png_set_interlace_handling(png_ptr);  }  /* now all of those things we set above are used to update various struct   * members and whatnot, after which we can get channels, rowbytes, etc. */  png_read_update_info(png_ptr, info_ptr);  channels = png_get_channels(png_ptr, info_ptr);  PR_ASSERT(channels == 3 || channels == 4);  /*---------------------------------------------------------------*/  /* copy PNG info into imagelib structs (formerly png_set_dims()) */  /*---------------------------------------------------------------*/  PRInt32 alpha_bits = 1;  if (channels > 3) {    /* check if alpha is coming from a tRNS chunk and is binary */    if (num_trans) {      /* if it's not a indexed color image, tRNS means binary */      if (color_type == PNG_COLOR_TYPE_PALETTE) {        for (int i=0; i<num_trans; i++) {          if ((trans[i] != 0) && (trans[i] != 255)) {            alpha_bits = 8;            break;          }        }      }    } else {      alpha_bits = 8;    }  }  nsPNGDecoder *decoder = NS_STATIC_CAST(nsPNGDecoder*, png_get_progressive_ptr(png_ptr));  if (decoder->mObserver)    decoder->mObserver->OnStartDecode(nsnull);  decoder->mImage = do_CreateInstance("@mozilla.org/image/container;1");  if (!decoder->mImage)    longjmp(decoder->mPNG->jmpbuf, 5); // NS_ERROR_OUT_OF_MEMORY  decoder->mImageLoad->SetImage(decoder->mImage);  // since the png is only 1 frame, initalize the container to the width and height of the frame  decoder->mImage->Init(width, height, decoder->mObserver);  if (decoder->mObserver)    decoder->mObserver->OnStartContainer(nsnull, decoder->mImage);  decoder->mFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2");  if (!decoder->mFrame)    longjmp(decoder->mPNG->jmpbuf, 5); // NS_ERROR_OUT_OF_MEMORY  gfx_format format;  if (channels == 3) {    format = gfxIFormats::RGB;  } else if (channels > 3) {    if (alpha_bits == 8) {      decoder->mImage->GetPreferredAlphaChannelFormat(&format);    } else if (alpha_bits == 1) {      format = gfxIFormats::RGB_A1;    }  }#if defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON)  // XXX this works...  format += 1; // RGB to BGR#endif  // then initalize the frame and append it to the container  nsresult rv = decoder->mFrame->Init(0, 0, width, height, format, 24);  if (NS_FAILED(rv))    longjmp(decoder->mPNG->jmpbuf, 5); // NS_ERROR_OUT_OF_MEMORY  decoder->mImage->AppendFrame(decoder->mFrame);  if (decoder->mObserver)    decoder->mObserver->OnStartFrame(nsnull, decoder->mFrame);  PRUint32 bpr, abpr;  decoder->mFrame->GetImageBytesPerRow(&bpr);  decoder->mFrame->GetAlphaBytesPerRow(&abpr);  decoder->colorLine = (PRUint8 *)nsMemory::Alloc(bpr);  if (channels > 3)    decoder->alphaLine = (PRUint8 *)nsMemory::Alloc(abpr);  if (interlace_type == PNG_INTERLACE_ADAM7) {    decoder->interlacebuf = (PRUint8 *)nsMemory::Alloc(channels*width*height);    decoder->ibpr = channels*width;    if (!decoder->interlacebuf) {      longjmp(decoder->mPNG->jmpbuf, 5); // NS_ERROR_OUT_OF_MEMORY    }              }  return;}