Beispiel #1
0
void
embryo::savePNG(ostream& inStream, const Picture& inPicture) {
  // Setup libpng
  png_structp lPngPtr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
  if (!lPngPtr)
    throw Exception("Out of memory");

  png_infop lInfoPtr = png_create_info_struct(lPngPtr);
  if (!lInfoPtr) {
    png_destroy_write_struct(&lPngPtr, 0);
    throw Exception("Out of memory");
  }

  png_set_error_fn(lPngPtr, 0, &errorCallback, &warningCallback);
  png_set_write_fn(lPngPtr, &inStream, &writeDataCallback, &flushCallback);

  // Setup and write the picture infos
  png_set_IHDR(lPngPtr, lInfoPtr,
                 inPicture.width(),
                 inPicture.height(),
                 8,
                 PNG_COLOR_TYPE_GRAY,
                 PNG_INTERLACE_NONE,
                 PNG_COMPRESSION_TYPE_DEFAULT,
                 PNG_FILTER_TYPE_DEFAULT);
  png_write_info(lPngPtr, lInfoPtr);
 
  // Write the picture datas
  png_bytep lRasterRow = new png_byte[inPicture.width()];
  const double* lSrc = inPicture.pixels();

  for(size_t i = 0; i < inPicture.height(); ++i) {
    png_bytep lDst = lRasterRow;
    for(size_t j = inPicture.width(); j != 0; ++lSrc, ++lDst, --j)
      (*lDst) = 255.0 * (*lSrc);

    png_write_row(lPngPtr, lRasterRow);
  }

  png_write_end(lPngPtr, lInfoPtr);

  // Job done
  delete[] lRasterRow;
  png_destroy_write_struct(&lPngPtr, &lInfoPtr);
}