Esempio n. 1
0
void
PngEncoder::encode()
{
    png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!png_ptr)
        throw "png_create_write_struct failed.";

    png_infop info_ptr = png_create_info_struct(png_ptr);
    if (!png_ptr)
        throw "png_create_info_struct failed.";

    int color_type;
    if (buf_type == BUF_RGB || buf_type == BUF_BGR)
        color_type = PNG_COLOR_TYPE_RGB;
    else
        color_type = PNG_COLOR_TYPE_RGB_ALPHA;

    png_set_IHDR(png_ptr, info_ptr, width, height,
        8, color_type, PNG_INTERLACE_NONE,
        PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);

    png_bytep *row_pointers = NULL;

    try {
        png_set_write_fn(png_ptr, (void *)this, png_chunk_producer, NULL);
        png_write_info(png_ptr, info_ptr);
        png_set_invert_alpha(png_ptr);

        if (buf_type == BUF_BGR || buf_type == BUF_BGRA)
            png_set_bgr(png_ptr);

        png_bytep *row_pointers = (png_bytep *)malloc(sizeof(png_bytep) * height);
        if (!row_pointers)
            throw "malloc failed in node-png (PngEncoder::encode).";

        if (buf_type == BUF_RGB || buf_type == BUF_BGR) {
            for (int i=0; i<height; i++)
                row_pointers[i] = data+3*i*width;
        }
        else {
            for (int i=0; i<height; i++)
                row_pointers[i] = data+4*i*width;
        }

        png_write_image(png_ptr, row_pointers);
        png_write_end(png_ptr, NULL);
        png_destroy_write_struct(&png_ptr, &info_ptr);
        free(row_pointers);
    }
    catch (const char *err) {
        png_destroy_write_struct(&png_ptr, &info_ptr);
        free(row_pointers);
        throw;
    }
}
Esempio n. 2
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         const GeglRectangle *result,
         gint                 level)
{
  GeglProperties *o = GEGL_PROPERTIES (operation);
  png_structp png = NULL;
  png_infop info = NULL;
  GOutputStream *stream = NULL;
  GFile *file = NULL;
  gboolean status = TRUE;
  GError *error = NULL;

  png = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, error_fn, NULL);
  if (png != NULL)
    info = png_create_info_struct (png);
  if (png == NULL || info == NULL)
    {
      status = FALSE;
      g_warning ("failed to initialize PNG writer");
      goto cleanup;
    }

  stream = gegl_gio_open_output_stream (NULL, o->path, &file, &error);
  if (stream == NULL)
    {
      status = FALSE;
      g_warning ("%s", error->message);
      goto cleanup;
    }

  png_set_write_fn (png, stream, write_fn, flush_fn);

  if (export_png (operation, input, result, png, info, o->compression, o->bitdepth))
    {
      status = FALSE;
      g_warning("could not export PNG file");
      goto cleanup;
    }

cleanup:
  if (info != NULL)
    png_destroy_write_struct (&png, &info);
  else if (png != NULL)
    png_destroy_write_struct (&png, NULL);

  if (stream != NULL)
    g_clear_object(&stream);

  if (file != NULL)
    g_clear_object(&file);

  return status;
}
Esempio n. 3
0
static bool encodeImpl(const unsigned char* input, int imageWidth, int imageHeight, int bytesPerRow, Vector<unsigned char>* output, PixelConversionFunc conversionFunc)
{
    int inputColorComponents = 4;
    int outputColorComponents = 4;
    int pngOutputColorType = PNG_COLOR_TYPE_RGB_ALPHA;

    if (imageWidth < 0)
        imageWidth = 0;

    if (imageHeight < 0)
        imageHeight = 0;

    // Row stride should be at least as long as the length of the data.
    if (inputColorComponents * imageWidth > bytesPerRow) {
        ASSERT(false);
        return false;
    }

    png_struct* pngPtr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
    if (!pngPtr)
        return false;

    png_info* infoPtr = png_create_info_struct(pngPtr);
    if (!infoPtr) {
        png_destroy_write_struct(&pngPtr, 0);
        return false;
    }
    PNGWriteStructDestroyer destroyer(&pngPtr, &infoPtr);

    if (setjmp(png_jmpbuf(pngPtr))) {
        // The destroyer will ensure that the structures are cleaned up in this
        // case, even though we may get here as a jump from random parts of the
        // PNG library called below.
        return false;
    }

    // Set our callback for libpng to give us the data.
    PNGEncoderState state(output);
    png_set_write_fn(pngPtr, &state, encoderWriteCallback, 0);

    png_set_IHDR(pngPtr, infoPtr, imageWidth, imageHeight, 8, pngOutputColorType,
                 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
                 PNG_FILTER_TYPE_DEFAULT);
    png_write_info(pngPtr, infoPtr);

    OwnArrayPtr<unsigned char> rowPixels = adoptArrayPtr(new unsigned char[imageWidth * outputColorComponents]);
    for (int y = 0; y < imageHeight; y ++) {
        conversionFunc(&input[y * bytesPerRow], imageWidth, rowPixels.get());
        png_write_row(pngPtr, rowPixels.get());
    }

    png_write_end(pngPtr, infoPtr);
    return true;
}
Esempio n. 4
0
png_structp PNGWriteOpen(struct VFile* source) {
	png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
	if (!png) {
		return 0;
	}
	if (setjmp(png_jmpbuf(png))) {
		png_destroy_write_struct(&png, 0);
		return 0;
	}
	png_set_write_fn(png, source, _pngWrite, 0);
	return png;
}
Esempio n. 5
0
void FPngImageWrapper::Compress( int32 Quality )
{
	if (!CompressedData.Num())
	{
		// thread safety
		FScopeLock PNGLock(&GPNGSection);

		check(RawData.Num());
		check(Width > 0);
		check(Height > 0);

		// Reset to the beginning of file so we can use png_read_png(), which expects to start at the beginning.
		ReadOffset = 0;

		png_structp png_ptr	= png_create_write_struct( PNG_LIBPNG_VER_STRING, this, FPngImageWrapper::user_error_fn, FPngImageWrapper::user_warning_fn );
		check(png_ptr);

		png_infop info_ptr	= png_create_info_struct( png_ptr );
		check(info_ptr);

		PNGWriteGuard PNGGuard(&png_ptr, &info_ptr);
		{
			png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
			png_set_IHDR(png_ptr, info_ptr, Width, Height, RawBitDepth, (RawFormat == ERGBFormat::Gray) ? PNG_COLOR_TYPE_GRAY : PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
			png_set_write_fn(png_ptr, this, FPngImageWrapper::user_write_compressed, FPngImageWrapper::user_flush_data);
			png_bytep* row_pointers = (png_bytep*) png_malloc( png_ptr, Height*sizeof(png_bytep) );

			const uint32 PixelChannels = (RawFormat == ERGBFormat::Gray) ? 1 : 4;
			const uint32 BytesPerPixel = (RawBitDepth * PixelChannels) / 8;
			const uint32 BytesPerRow = BytesPerPixel * Width;

			PNGGuard.SetRowPointers( &row_pointers );
			for (int32 i = 0; i < Height; i++)
			{
				row_pointers[i]= &RawData[i * BytesPerRow];
			}
			png_set_rows(png_ptr, info_ptr, row_pointers);

			uint32 Transform = (RawFormat == ERGBFormat::BGRA) ? PNG_TRANSFORM_BGR : PNG_TRANSFORM_IDENTITY;

			// PNG files store 16-bit pixels in network byte order (big-endian, ie. most significant bits first).
#if PLATFORM_LITTLE_ENDIAN
			// We're little endian so we need to swap
			if (RawBitDepth == 16)
			{
				Transform |= PNG_TRANSFORM_SWAP_ENDIAN;
			}
#endif

			png_write_png(png_ptr, info_ptr, Transform, NULL);
		}
	}
}
Esempio n. 6
0
	void PNGFile::save(std::ostream &stream) {
		if (pixels.empty()) {
			throw std::runtime_error("Trying to save an empty PNG");
		}
		
		// Initializations needed by libpng
		png_structp PngPointer = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
		if (!PngPointer)
		{
			throw std::runtime_error("Cannot allocate memory");
		}

		png_infop InfoPointer = png_create_info_struct(PngPointer);
		if (!InfoPointer)
		{
			png_destroy_write_struct(&PngPointer, nullptr);
			throw std::runtime_error("Cannot allocate memory");
		}

		if (setjmp(png_jmpbuf(PngPointer)))
		{
			png_destroy_write_struct(&PngPointer, &InfoPointer);
			throw std::runtime_error("Cannot set jump pointer");
		}

		// Set PNG parameters
		png_set_IHDR(PngPointer, InfoPointer, params.width, params.height, params.BitDepth, params.BitsPerPixel == 24 ?
		       PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGBA, params.InterlaceType, params.CompressionType, params.FilterType);

		/*
		  Instead of storing the image in a 2D-array, I store it in a 1D-array.
		  Since png_set_rows() accepts a pointer to a pointer as an argument,
		  I need to create a temporary std::vector storing pointers
		  to addresses of 1st pixels for each row.
		*/
		std::vector<unsigned char*> RowPointers(params.height);
		size_t BytesPerLine = params.width << 2; // (x << 2) == (x * 4). 4 channels: RGB and Alpha.
		unsigned char *ptr = reinterpret_cast<unsigned char*>(pixels.data());
		for (size_t i = 0; i < params.height; ++i, ptr += BytesPerLine)
			RowPointers[i] = ptr;

		// Write data to file
		png_set_bgr(PngPointer);
		png_set_write_fn(PngPointer, reinterpret_cast<void*>(&stream), WriteToStream, nullptr);
		// png_set_rows() takes a pointer to a non-const data as its
		// 3rd argument, making it not possible to declare save() as const
		// without using const_cast on pixels.data(), I'd rather not do that.
		png_set_rows(PngPointer, InfoPointer, RowPointers.data());
		png_write_png(PngPointer, InfoPointer, params.BitsPerPixel == 24 ?
		         PNG_TRANSFORM_STRIP_FILLER_AFTER : PNG_TRANSFORM_IDENTITY, NULL);
		png_destroy_write_struct(&PngPointer, &InfoPointer);
	}
Esempio n. 7
0
encoder::encoder(std::streambuf *sb, info const &i)
  : output_(sb),
    png_(png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0)),
    info_(png_create_info_struct(png_))
{
  png_set_write_fn(png_, output_, encoder_write, encoder_flush);
  png_set_error_fn(png_, output_, encoder_error, encoder_warning);
  png_set_write_status_fn(png_, 0);

  png_set_IHDR(png_, info_,
	       i.width, i.height, i.depth, i.colortype,
	       i.interlace, i.compression, i.filter);
}
Esempio n. 8
0
bool bitmapToPNG( 
   bitmap_t const &bmp,
   void const    *&pngData,
   unsigned       &size )
{
   pngData = 0 ;
   size    = 0 ;
   
   png_structp png_ptr = png_create_write_struct
      (PNG_LIBPNG_VER_STRING, (png_voidp)0, 0, 0 );
   if( png_ptr ){
      png_infop info_ptr = png_create_info_struct(png_ptr);
      if(info_ptr){
         if( 0 == setjmp( png_jmpbuf( png_ptr ) ) ) {
            png_set_write_fn( png_ptr, 0, write_png_data, flush_png_data );
            png_set_IHDR( png_ptr, info_ptr, bmp.getWidth(), bmp.getHeight(), 8,
                  PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, 
                  PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT );
            png_write_info( png_ptr, info_ptr );

            unsigned char const *nextIn = bmp.getMem();
            unsigned char *const outRow = new unsigned char [bmp.getWidth()*4];

            for( unsigned row = 0; row < bmp.getHeight() ; row++, nextIn += bmp.bytesPerRow() )
            {
               bits_to_rgb24(nextIn,bmp.getWidth(),outRow);
               png_write_row( png_ptr, outRow );
            }

            delete [] outRow ;

            png_write_end(png_ptr, info_ptr);

            chunk_t *ch = get_png_chunk(png_ptr);
            if( ch ){
               void *outData ;
               collapse_png_data(ch,outData,size);
               pngData = outData ;
               flush_png_data(png_ptr);
            }
         }

         png_destroy_info_struct(png_ptr, &info_ptr);

      }
      else
         png_destroy_write_struct(&png_ptr, 0);
   }

   return (0 != pngData);
}
Esempio n. 9
0
	bool CPixmap::fromImage( const CImage& img )
	{
	   TRACE_FUN( Frequently, "CPixmap::fromImage" );

	   bool ret( false );

	   _png_write_ptr = png_create_write_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0 );
	   if( _png_write_ptr )
	   {
	   	_png_write_info = png_create_info_struct( _png_write_ptr );
	   	if( _png_write_info )
	   	{
	   		CByteArray ba;

	   		SCallbackContext context;
	   		context._data = &ba;
	   		context._offset = 0;

	   		png_set_write_fn( _png_write_ptr, &context, png_rw_callback, 0 );

	   	   png_set_IHDR( _png_write_ptr, _png_write_info, img.width(), img.height(), 8, PNG_COLOR_TYPE_RGB,
	   	      			  PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE );

	   	   png_write_info( _png_write_ptr, _png_write_info );

	   	   png_bytep dstImgRow( new png_byte[ _png_write_info->width * 3 ] );

	   	   for( int row( 0 ); row < _png_write_info->height; ++row )
	   	   {
	   	   	png_bytep srcImgRow( const_cast< png_bytep >( img.data() ) + row * _png_write_info->width * 4 );

	   	   	for( int col( 0 ); col < _png_write_info->width; ++col )
	   	   	{
	   	   		dstImgRow[ col * 3 ] = srcImgRow[ col * 4 + 2];
	   	   		dstImgRow[ col * 3 + 1 ] = srcImgRow[ col * 4 + 1 ];
	   	   		dstImgRow[ col * 3 + 2 ] = srcImgRow[ col * 4 ];
	   	   	}

	   	   	png_write_rows( _png_write_ptr, &dstImgRow, 1 );
	   	   }

	   	   delete dstImgRow;

	   	   png_write_end( _png_write_ptr, _png_write_info );

	   	   ret = load( ba );
	   	}
	   }

	   return ret;
	}
vector<Byte> PngFormatter::Encode(const Bitmap &bmp) const
{
	png_struct *png = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr,
			nullptr, nullptr);
	if (!png)
	{
		LU_LOG_E(LU_TAG "Encode", "Failed while png_create_read_struct");
		return {};
	}
	png_info *info = png_create_info_struct(png);
	if (!info)
	{
		LU_LOG_E(LU_TAG "Encode", "Failed while png_create_info_struct");
		png_destroy_write_struct(&png, nullptr);
		return {};
	}

	const bool is_opaque = BitmapUtils::IsOpaque(bmp);
	const vector<Byte> &src = is_opaque ? BitmapUtils::GetBgrData(bmp)
			: bmp.GetData();
	vector<const Byte*> src_rows;
	src_rows.reserve(bmp.GetH());
	for (Uint i = 0; i < bmp.GetH(); ++i)
	{
		src_rows.push_back(src.data() + (bmp.GetW() * (is_opaque ? 3 : 4) * i));
	}

	vector<Byte> product;

	if (setjmp(png_jmpbuf(png)))
	{
		LU_LOG_E(LU_TAG "Encode", "Unknown error");
		png_destroy_write_struct(&png, &info);
		return {};
	}

	png_set_write_fn(png, &product, PngWriteData, PngFlushData);

	png_set_compression_level(png, m_level);
	png_set_IHDR(png, info, bmp.GetW(), bmp.GetH(), 8,
			is_opaque ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA,
			PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
			PNG_FILTER_TYPE_DEFAULT);
	png_set_rows(png, info, const_cast<Byte**>(src_rows.data()));

	png_write_png(png, info, PNG_TRANSFORM_BGR, nullptr);

	product.shrink_to_fit();
	return product;
}
Esempio n. 11
0
void encode_png(const char* data ,size_t width, size_t height, size_t channels, char** out_data, size_t& out_length){
  //Beginning of setup 
  png_structp png_ptr;
  png_infop info_ptr;
  setup_png_writer(&png_ptr, &info_ptr, width, height, channels);

  //Reading the data in
  png_byte** row_pointers = (png_byte**) png_malloc(png_ptr, height * sizeof(png_byte *));
  for (size_t y = 0; y < height; ++y){
    char* row =(char*) png_malloc(png_ptr, sizeof(char) * channels * width);
    row_pointers[y] = (png_byte *) row; 
    for (size_t x = 0; x < width; ++x){
      for (size_t z = 0; z < channels; ++z){ 
        *row++ = *data++;
        }
      } 
    }

  // Construct in memory-buffer
  png_memory_buffer destination;
  destination.data = NULL;
  destination.length = 0;
  destination.offset = 0;

  // Writing decoded data into buffer 
  png_set_write_fn(png_ptr, &destination, png_memwrite_func, png_mem_flush);
  png_set_rows(png_ptr, info_ptr, row_pointers);
  png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);

  //Copying buffer to output
  out_length = destination.length; 

  /**
   * destination.data is allocated using malloc realloc. This cannot
   * be used directly because `image_type`
   * requires C++ char[] for proper resource management.
   */
  // Make a copy into char[]
  *out_data = new char[out_length];
  memcpy(*out_data, destination.data, out_length);
  free(destination.data);

  //Cleanup
  for (size_t y = 0; y < height; y++){
    png_free (png_ptr, row_pointers[y]);
  }
  png_free(png_ptr, row_pointers);

  png_destroy_write_struct(&png_ptr, &info_ptr); 
}
Esempio n. 12
0
/* Since libpng forces us to use longjmp, this function shouldn't create any C++
 * objects, and needs to watch out for memleaks. */
bool SavePNG( FILE *f, char szErrorbuf[1024], const Surface *pSurf )
{
/*	RageSurfaceUtils::ConvertSurface( pImgIn, pImg, pImgIn->w, pImgIn->h, 32,
			Swap32BE( 0xFF000000 ),
			Swap32BE( 0x00FF0000 ),
			Swap32BE( 0x0000FF00 ),
			Swap32BE( 0x000000FF ) );
*/
	error_info error;
	error.szErr = szErrorbuf;

	png_struct *pPng = png_create_write_struct( PNG_LIBPNG_VER_STRING, &error, PNG_Error, PNG_Warning );
	if( pPng == NULL )
	{
		sprintf( szErrorbuf, "creating png_create_write_struct failed");
		return false;
	}

	png_info *pInfo = png_create_info_struct(pPng);
	if( pInfo == NULL )
	{
		png_destroy_read_struct( &pPng, NULL, NULL );
		sprintf( szErrorbuf, "creating png_create_info_struct failed");
		return false;
	}

	if( setjmp(pPng->jmpbuf) )
	{
		png_destroy_read_struct( &pPng, &pInfo, png_infopp_NULL );
		return false;
	}

	png_set_write_fn( pPng, f, File_png_write, File_png_flush );
	png_set_compression_level( pPng, 1 );

	png_set_IHDR( pPng, pInfo, pSurf->iWidth, pSurf->iHeight, 8, PNG_COLOR_TYPE_RGBA,
		PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE );

	png_write_info( pPng, pInfo );
	png_set_filler( pPng, 0, PNG_FILLER_AFTER );

	png_byte *pixels = (png_byte *) pSurf->pRGBA;
	for( int y = 0; y < pSurf->iHeight; y++ )
		png_write_row( pPng, pixels + pSurf->iPitch*y );

	png_write_end( pPng, pInfo );
	png_destroy_write_struct( &pPng, &pInfo );

	return true;
}
Esempio n. 13
0
static int writePixmapToPng(screenshot_info_t *screenshot, char *fname) {
  png_structp png_ptr;
  png_infop info_ptr;
  png_byte **row_ptrs;
  int i;

  if (!(fp = fopen(fname, "wb"))) {
    fprintf(stderr, "can't open %s for writing\n", fname);
    return -1;
  }

  if (!(png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 
                                          NULL, NULL, NULL))) {
    return -1;
  }

  if (!(info_ptr = png_create_info_struct(png_ptr))) {
    png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
    return -1;
  }

  png_set_write_fn(png_ptr, 0, user_write_data, user_flush_data);
  /* png_init_io(png_ptr, fp); */

  png_set_IHDR(png_ptr, info_ptr, screenshot->width, screenshot->height,
	             SCREENSHOT_PNG_BITDEPTH, PNG_COLOR_TYPE_RGB, 
	             PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
	             PNG_FILTER_TYPE_DEFAULT);
  png_write_info(png_ptr, info_ptr);

  /* get pointers */
  if(!(row_ptrs = (png_byte**) malloc(screenshot->height * sizeof(png_byte*)))) {
    png_destroy_write_struct(&png_ptr, &info_ptr);
    return -1;
  }
  
  for(i = 0; i < screenshot->height; i++) {
    row_ptrs[i] = screenshot->pixmap + (screenshot->height - i - 1) 
      * SCREENSHOT_BYTES_PER_PIXEL * screenshot->width;
  }

  png_write_image(png_ptr, row_ptrs);
  png_write_end(png_ptr, info_ptr);
  png_destroy_write_struct(&png_ptr, &info_ptr); 
  
  free(row_ptrs);
  fclose(fp);
  return 0;
}
Esempio n. 14
0
//
// WriteImage()
// write an image to a file in PNG format
// This version writes the entire image
//
void CImageIOPng::WriteImage(const CImage& image, CNcbiOstream& ostr,
                             CImageIO::ECompress compress)
{
    // make sure we've got an image
    if ( !image.GetData() ) {
        NCBI_THROW(CImageException, eWriteError,
                   "CImageIOPng::WriteImage(): "
                   "attempt to write an empty image");
    }

    // validate our image - we need RGB or RGBA images
    if (image.GetDepth() != 3  &&  image.GetDepth() != 4) {
        string msg("CImageIOPng::WriteImage(): invalid image depth: ");
        msg += NStr::NumericToString(image.GetDepth());
        NCBI_THROW(CImageException, eWriteError, msg);
    }

    png_structp png_ptr  = NULL;
    png_infop   info_ptr = NULL;

    try {
        // initialize png stuff
        s_PngWriteInit(png_ptr, info_ptr,
                       image.GetWidth(), image.GetHeight(), image.GetDepth(),
                       compress);

        // begin writing data
        png_set_write_fn(png_ptr, &ostr, s_PngWrite, s_PngFlush);
        png_write_info(png_ptr, info_ptr);

        // write our image, line-by-line
        unsigned char* row_ptr = const_cast<unsigned char*> (image.GetData());
        size_t width  = image.GetWidth();
        size_t height = image.GetHeight();
        size_t depth  = image.GetDepth();
        for (size_t i = 0;  i < height;  ++i) {
            png_write_row(png_ptr, row_ptr);
            row_ptr += width * depth;
        }

        // standard clean-up
        png_write_end(png_ptr, info_ptr);
        s_PngWriteFinalize(png_ptr, info_ptr);
    }
    catch (...) {
        s_PngWriteFinalize(png_ptr, info_ptr);
        throw;
    }
}
Esempio n. 15
0
void save_as_png(T1 & file,
                T2 const& image,
                png_options const& opts)

{
    png_voidp error_ptr=0;
    png_structp png_ptr=png_create_write_struct(PNG_LIBPNG_VER_STRING,
                                                error_ptr,0, 0);

    if (!png_ptr) return;

    // switch on optimization only if supported
#if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) && defined(PNG_MMX_CODE_SUPPORTED)
    png_uint_32 mask, flags;
    flags = png_get_asm_flags(png_ptr);
    mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE);
    png_set_asm_flags(png_ptr, flags | mask);
#endif
    png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, PNG_FILTER_NONE);
    png_infop info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr)
    {
        png_destroy_write_struct(&png_ptr,static_cast<png_infopp>(0));
        return;
    }
    jmp_buf* jmp_context = static_cast<jmp_buf*>(png_get_error_ptr(png_ptr));
    if (jmp_context)
    {
        png_destroy_write_struct(&png_ptr, &info_ptr);
        return;
    }
    png_set_write_fn (png_ptr, &file, &write_data<T1>, &flush_data<T1>);

    png_set_compression_level(png_ptr, opts.compression);
    png_set_compression_strategy(png_ptr, opts.strategy);
    png_set_compression_buffer_size(png_ptr, 32768);

    png_set_IHDR(png_ptr, info_ptr,image.width(),image.height(),8,
                 (opts.trans_mode == 0) ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA,PNG_INTERLACE_NONE,
                 PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT);
    const std::unique_ptr<png_bytep[]> row_pointers(new png_bytep[image.height()]);
    for (unsigned int i = 0; i < image.height(); i++)
    {
        row_pointers[i] = const_cast<png_bytep>(reinterpret_cast<const unsigned char *>(image.get_row(i)));
    }
    png_set_rows(png_ptr, info_ptr, row_pointers.get());
    png_write_png(png_ptr, info_ptr, (opts.trans_mode == 0) ? PNG_TRANSFORM_STRIP_FILLER_AFTER : PNG_TRANSFORM_IDENTITY, nullptr);
    png_destroy_write_struct(&png_ptr, &info_ptr);
}
Esempio n. 16
0
/* Initialize png_ptr structure, and allocate any memory needed */
png_structp
png_create_write_struct(png_const_charp user_png_ver, voidp error_ptr,
   png_error_ptr error_fn, png_error_ptr warn_fn)
{
   png_structp png_ptr;
#ifdef USE_FAR_KEYWORD
   jmp_buf jmpbuf;
#endif
   png_debug(1, "in png_create_write_struct\n");
   if ((png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG)) == NULL)
   {
      return (png_structp)NULL;
   }
#ifdef USE_FAR_KEYWORD
   if (setjmp(jmpbuf))
#else
   if (setjmp(png_ptr->jmpbuf))
#endif
   {
      png_free(png_ptr, png_ptr->zbuf);
      png_destroy_struct(png_ptr);
      return (png_structp)NULL;
   }
#ifdef USE_FAR_KEYWORD
   png_memcpy(png_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
#endif
   png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);

   /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
    * we must recompile any applications that use any older library version.
    * For versions after libpng 1.0, we will be compatible, so we need
    * only check the first digit.
    */
   if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
       (png_libpng_ver[0] == '0' && user_png_ver[2] < '9'))
   {
      png_error(png_ptr,
         "Incompatible libpng version in application and library");
   }

   /* initialize zbuf - compression buffer */
   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
   png_ptr->zbuf = png_malloc(png_ptr, png_ptr->zbuf_size);

   png_set_write_fn(png_ptr, NULL, NULL, NULL);

   return (png_ptr);
}
Esempio n. 17
0
bool plPNG::IWrite(plMipmap* source, hsStream* outStream)
{
    bool result = true;

    try {
        //  Allocate required structs
        png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

        if (!png_ptr) {
            throw false;
        }

        png_infop info_ptr = png_create_info_struct(png_ptr);

        if (!info_ptr) {
            png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
            throw false;
        }

        //  Assign delegate function for writing to hsStream
        png_set_write_fn(png_ptr, (png_voidp)outStream, pngWriteDelegate, NULL);
        uint8_t psize = source->GetPixelSize();
        png_set_IHDR(png_ptr, info_ptr, source->GetWidth(), source->GetHeight(), 8, PNG_COLOR_TYPE_RGB_ALPHA,
                     PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
        // Invert color byte-order as used by plMipmap for DirectX
        png_set_bgr(png_ptr);
        // Write out the image metadata
        png_write_info(png_ptr, info_ptr);
        char* srcp = (char*)source->GetImage();
        png_bytep* row_ptrs = new png_bytep[source->GetHeight()];
        const unsigned int stride = source->GetWidth() * source->GetPixelSize() / 8;

        //  Assign row pointers to the appropriate locations in the newly-created Mipmap
        for (size_t i = 0; i < source->GetHeight(); i++) {
            row_ptrs[i] = (png_bytep)srcp + (i * stride);
        }

        png_write_image(png_ptr, row_ptrs);
        png_write_end(png_ptr, info_ptr);
        //  Clean up allocated structs
        png_destroy_write_struct(&png_ptr, &info_ptr);
        delete [] row_ptrs;
    } catch (...) {
        result = false;
    }

    return result;
}
Esempio n. 18
0
std::unique_ptr<SkPngEncoderMgr> SkPngEncoderMgr::Make(SkWStream* stream) {
    png_structp pngPtr =
            png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, sk_error_fn, nullptr);
    if (!pngPtr) {
        return nullptr;
    }

    png_infop infoPtr = png_create_info_struct(pngPtr);
    if (!infoPtr) {
        png_destroy_write_struct(&pngPtr, nullptr);
        return nullptr;
    }

    png_set_write_fn(pngPtr, (void*)stream, sk_write_fn, nullptr);
    return std::unique_ptr<SkPngEncoderMgr>(new SkPngEncoderMgr(pngPtr, infoPtr));
}
Esempio n. 19
0
char Image_write_png_internal(Image *img, FILE *file, void *write_io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn) {
  png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  if (!png) {
    return 0;
  }

  png_infop info = png_create_info_struct(png);
  if (!info) {
    png_destroy_write_struct(&png, (png_infopp)NULL);
    return 0;
  }

  if (setjmp(png_jmpbuf(png))) {
    png_destroy_info_struct(png, (png_infopp)&info);
    png_destroy_write_struct(&png, (png_infopp)&info);
    return 0;
  }

  if (file == NULL) {
    png_set_write_fn(png, write_io_ptr, write_data_fn, output_flush_fn);
  } else {
    png_init_io(png, file);
  }

  png_set_IHDR(png, info, img->width, img->height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
  png_write_info(png, info);

  int x, y;
  Pixel pixel;
  png_bytep row = (png_bytep)malloc(img->width * 3 * sizeof(png_byte));

  for (y = 0; y < img->height; y++) {
    for (x = 0; x < img->width; x++) {
      pixel = Image_get_pixel(img, x, y);
      row[(x * 3) + 0] = Pixel_get_red(pixel);
      row[(x * 3) + 1] = Pixel_get_green(pixel);
      row[(x * 3) + 2] = Pixel_get_blue(pixel);
    }
    png_write_row(png, row);
  }

  free(row);
  png_write_end(png, NULL);
  png_destroy_info_struct(png, (png_infopp)&info);
  png_destroy_write_struct(&png, (png_infopp)&info);
  return 1;
}
static bool encodePixels(IntSize imageSize, const unsigned char* inputPixels, bool premultiplied, Vector<unsigned char>* output)
{
    if (imageSize.width() <= 0 || imageSize.height() <= 0)
        return false;

    Vector<unsigned char> row;

    png_struct* png = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
    png_info* info = png_create_info_struct(png);
    if (!png || !info || setjmp(png_jmpbuf(png))) {
        png_destroy_write_struct(png ? &png : 0, info ? &info : 0);
        return false;
    }

    // Optimize compression for speed.
    // The parameters are the same as what libpng uses by default for RGB and RGBA images, except:
    // - the zlib compression level is 3 instead of 6, to avoid the lazy Ziv-Lempel match searching;
    // - the delta filter is 1 ("sub") instead of 5 ("all"), to reduce the filter computations.
    // The zlib memory level (8) and strategy (Z_FILTERED) will be set inside libpng.
    //
    // Avoid the zlib strategies Z_HUFFMAN_ONLY or Z_RLE.
    // Although they are the fastest for poorly-compressible images (e.g. photographs),
    // they are very slow for highly-compressible images (e.g. text, drawings or business graphics).
    png_set_compression_level(png, 3);
    png_set_filter(png, PNG_FILTER_TYPE_BASE, PNG_FILTER_SUB);

    png_set_write_fn(png, output, writeOutput, 0);
    png_set_IHDR(png, info, imageSize.width(), imageSize.height(),
                 8, PNG_COLOR_TYPE_RGB_ALPHA, 0, 0, 0);
    png_write_info(png, info);

    unsigned char* pixels = const_cast<unsigned char*>(inputPixels);
    row.resize(imageSize.width() * sizeof(SkPMColor));
    const size_t pixelRowStride = imageSize.width() * 4;
    for (int y = 0; y < imageSize.height(); ++y) {
        if (premultiplied) {
            preMultipliedBGRAtoRGBA(pixels, imageSize.width(), row.data());
            png_write_row(png, row.data());
        } else
            png_write_row(png, pixels);
        pixels += pixelRowStride;
    }

    png_write_end(png, info);
    png_destroy_write_struct(&png, &info);
    return true;
}
Esempio n. 21
0
	void Texture::SaveTexture( const OutPutTextureData& saveto )
	{
		unsigned long i;
		png_structp png_ptr;
		png_infop info_ptr;
		png_colorp palette;
		png_byte *image;
		png_bytep *row_pointers;

		IFile* writefile = IOSystem::Instance().FileFactory(saveto.m_Path);
		writefile->OpenFile( IFile::AT_READ );


		png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
		info_ptr = png_create_info_struct(png_ptr);
		png_set_write_fn( png_ptr, writefile, png_rw, png_flush );
		//png_init_io(png_ptr, writefile.BaseFile() );

		int colortype, bitesize;
		switch( saveto.m_Pixel )
		{
		case Device::PF_R8G8B8: colortype = PNG_COLOR_TYPE_RGB; bitesize = 3; break;
		case Device::PF_R8G8B8A8: colortype = PNG_COLOR_TYPE_RGBA; bitesize = 4; break;
		}
		png_set_IHDR(png_ptr, info_ptr, saveto.m_Size.m_x, saveto.m_Size.m_y, 8, colortype,
			PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
		palette = (png_colorp)png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH * sizeof (png_color));
		png_set_PLTE(png_ptr, info_ptr, palette, PNG_MAX_PALETTE_LENGTH);
		png_write_info(png_ptr, info_ptr);
		png_set_packing(png_ptr);
		row_pointers = (png_bytep *)malloc(saveto.m_Size.m_y * sizeof(png_bytep));

		for (i = 0; i < saveto.m_Size.m_y; i++)
		{
			row_pointers[i] = (png_bytep)&saveto.m_Data[i * saveto.m_Size.m_y * bitesize];
		}
		png_write_image(png_ptr, row_pointers);
		png_write_end(png_ptr, info_ptr);
		png_free(png_ptr, palette);
		palette = NULL;
		png_destroy_write_struct(&png_ptr, &info_ptr);
		free(row_pointers);
		row_pointers = NULL;
		writefile->CloseFile( );
		IOSystem::Instance().FileDestroy( writefile );
	}
Esempio n. 22
0
	bool ImageEncoderPNG::_initialize()
	{
		m_png_ptr = png_create_write_struct( PNG_LIBPNG_VER_STRING, (png_voidp)this, s_handlerError, s_handlerWarning );

		if( m_png_ptr == nullptr )  
		{
			LOGGER_ERROR(m_serviceProvider)("PNG encoder error: Can't create write structure" 
                );

			return false;
		}

		// init the IO
		png_set_write_fn( m_png_ptr, m_stream.get(), s_writeProc, s_flushProc );

		return true;
	}
Esempio n. 23
0
void save_as_png(T1 & file , T2 const& image, int compression = Z_DEFAULT_COMPRESSION, int strategy = Z_DEFAULT_STRATEGY)
{
    png_voidp error_ptr=0;
    png_structp png_ptr=png_create_write_struct(PNG_LIBPNG_VER_STRING,
                                                error_ptr,0, 0);

    if (!png_ptr) return;

    // switch on optimization only if supported
#if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) && defined(PNG_MMX_CODE_SUPPORTED)
    png_uint_32 mask, flags;
    flags = png_get_asm_flags(png_ptr);
    mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE);
    png_set_asm_flags(png_ptr, flags | mask);
#endif
    png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, PNG_FILTER_NONE);
    png_infop info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr)
    {
        png_destroy_write_struct(&png_ptr,(png_infopp)0);
        return;
    }
    jmp_buf* jmp_context = (jmp_buf*) png_get_error_ptr(png_ptr);
    if (jmp_context)
    {
        png_destroy_write_struct(&png_ptr, &info_ptr);
        return;
    }
    png_set_write_fn (png_ptr, &file, &write_data<T1>, &flush_data<T1>);

    png_set_compression_level(png_ptr, compression);
    png_set_compression_strategy(png_ptr, strategy);
    png_set_compression_buffer_size(png_ptr, 32768);

    png_set_IHDR(png_ptr, info_ptr,image.width(),image.height(),8,
                 PNG_COLOR_TYPE_RGB_ALPHA,PNG_INTERLACE_NONE,
                 PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT);
    png_write_info(png_ptr, info_ptr);
    for (unsigned i=0;i<image.height();i++)
    {
        png_write_row(png_ptr,(png_bytep)image.getRow(i));
    }

    png_write_end(png_ptr, info_ptr);
    png_destroy_write_struct(&png_ptr, &info_ptr);
}
Esempio n. 24
0
std::string compress_png(int width, int height, void *rgba) {
    png_voidp error_ptr = 0;
    png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, error_ptr, NULL, NULL);
    if (!png_ptr) {
        fprintf(stderr, "Couldn't create png_ptr\n");
        return "";
    }

    png_infop info_ptr = png_create_info_struct(png_ptr);
    if (!png_ptr) {
        png_destroy_write_struct(&png_ptr, (png_infopp)0);
        fprintf(stderr, "Couldn't create info_ptr\n");
        return "";
    }

    png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
                 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);

    jmp_buf *jmp_context = (jmp_buf *)png_get_error_ptr(png_ptr);
    if (jmp_context) {
        png_destroy_write_struct(&png_ptr, &info_ptr);
        return "";
    }

    std::string result;
    png_set_write_fn(png_ptr, &result, [](png_structp png_ptr_, png_bytep data, png_size_t length) {
        std::string *out = static_cast<std::string *>(png_get_io_ptr(png_ptr_));
        out->append(reinterpret_cast<char *>(data), length);
    }, NULL);

    struct ptrs {
        ptrs(size_t count) : rows(new png_bytep[count]) {}
        ~ptrs() { delete[] rows; }
        png_bytep *rows = nullptr;
    } pointers(height);

    for (int i = 0; i < height; i++) {
        pointers.rows[i] = (png_bytep)((png_bytep)rgba + width * 4 * i);
    }

    png_set_rows(png_ptr, info_ptr, pointers.rows);
    png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
    png_destroy_write_struct(&png_ptr, &info_ptr);

    return result;
}
Esempio n. 25
0
pngquant_error rwpng_write_image8(FILE *outfile, png8_image *mainprog_ptr)
{
    png_structp png_ptr;
    png_infop info_ptr;

    pngquant_error retval = rwpng_write_image_init((rwpng_png_image*)mainprog_ptr, &png_ptr, &info_ptr, mainprog_ptr->fast_compression);
    if (retval) return retval;

    struct rwpng_write_data write_data;
    if (mainprog_ptr->maximum_file_size) {
        write_data = (struct rwpng_write_data){
            .buffer = malloc(mainprog_ptr->maximum_file_size),
            .bytes_left = mainprog_ptr->maximum_file_size,
        };
        if (!write_data.buffer) return PNG_OUT_OF_MEMORY_ERROR;
        png_set_write_fn(png_ptr, &write_data, user_write_data, user_flush_data);
    } else {
//==============================================================================
bool cSavePNG(cImage* a_image, unsigned char **a_buffer, unsigned int *a_len)
{
    png_structp png_ptr;
    png_infop   info_ptr;

    // create and initialize the png_struct
    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!png_ptr)
    {
        return false;
    }

    // allocate/initialize image information struct
    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr)
    {
        png_destroy_write_struct(&png_ptr,  NULL);
        return false;
    }

    // set error handling
    if (setjmp(png_jmpbuf(png_ptr)))
    {
        png_destroy_write_struct(&png_ptr, &info_ptr);
        return false;
    }

    // write to buffer
    _PNGWriteBuf pngbuf;
    pngbuf.m_buffer = NULL;
    pngbuf.m_len    = 0;
    png_set_write_fn(png_ptr, &pngbuf, _writeToBuffer, _flushBuffer);

    // compress
    bool ret = _compressPNG(png_ptr, info_ptr, a_image);

    // cleanup
    png_destroy_write_struct(&png_ptr, &info_ptr);

    // retrieve result
    *a_buffer = pngbuf.m_buffer;
    *a_len    = pngbuf.m_len;

    // success
    return ret;
}
/*
 * Encodes an image to a PNG file stream.
 */
int opng_encode_image(struct opng_codec_context *context, int filtered, FILE *stream, const char *fname, int level)
{
    const char * volatile err_msg;  /* volatile is required by cexcept */

    context->libpng_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, opng_write_error, opng_write_warning);
    context->info_ptr = png_create_info_struct(context->libpng_ptr);
    if (!context->libpng_ptr || !context->info_ptr)
    {
        opng_error(0, "Out of memory");
        png_destroy_write_struct(&context->libpng_ptr, &context->info_ptr);
        exit(1);
    }

    struct opng_encoding_stats * stats = context->stats;
    opng_init_stats(stats);
    context->stream = stream;
    context->fname = fname;

    Try
    {

        png_set_filter(context->libpng_ptr, PNG_FILTER_TYPE_BASE, filtered ? PNG_ALL_FILTERS : PNG_FILTER_NONE);
        if (level != 6) {
            png_set_compression_level(context->libpng_ptr, level);
        }
        png_set_compression_mem_level(context->libpng_ptr, 8);
        png_set_compression_window_bits(context->libpng_ptr, 15);
        png_set_compression_strategy(context->libpng_ptr, 0);
        png_set_keep_unknown_chunks(context->libpng_ptr, PNG_HANDLE_CHUNK_ALWAYS, 0, 0);
        opng_store_image(context->image, context->libpng_ptr, context->info_ptr);

        /* Write the PNG stream. */
        png_set_write_fn(context->libpng_ptr, context, opng_write_data, 0);
        png_write_png(context->libpng_ptr, context->info_ptr, 0, 0);
    }
    Catch (err_msg)
    {
        stats->idat_size = OPTK_INT64_MAX;
        opng_error(fname, err_msg);
        return -1;
    }
    png_data_freer(context->libpng_ptr, context->info_ptr, PNG_USER_WILL_FREE_DATA, PNG_FREE_ALL);
    png_destroy_write_struct(&context->libpng_ptr, &context->info_ptr);
    return 0;
}
Esempio n. 28
0
void PNGImageCodec::Save(OutputStreamPtr& file, const ImageParams& params,
		const ImageData& data) {
	OutputStream* writr = file.GetPtr();
	if (data.format != PixelFormat::BGRA8 && data.format != PixelFormat::RGBA8)
		// todo support formats like rgba16 etc.
		NEX_THROW_FatalError(EXCEPT_NOT_IMPLEMENTED);
	png_structp pngPtr = nullptr;
	png_infop infoPtr = nullptr;
	png_byte ** rowPointers = nullptr;

	// todo Fix for 64
	uint32 bitDepth = 32;
	size_t rowStride = data.width * bitDepth;
	bool flip = (data.format == PixelFormat::BGRA8);

	pngPtr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	if (pngPtr == nullptr)
		goto failed;
	infoPtr = png_create_info_struct(pngPtr);
	if (infoPtr == nullptr)
		goto failed;

	png_set_error_fn(pngPtr, (void *) (writr), PngWarn, PngWarn);
	png_set_write_fn(pngPtr, (void *) (writr), PngWriteFile, PngFlushFile);

	png_set_IHDR(pngPtr, infoPtr, data.width, data.height, bitDepth, // assumed
			PNG_COLOR_TYPE_RGB_ALPHA,
			PNG_INTERLACE_NONE,
			PNG_COMPRESSION_TYPE_DEFAULT,
			PNG_FILTER_TYPE_DEFAULT);
	rowPointers = (png_byte**) NEX_ALLOC(sizeof(png_byte*) * data.height,
			MEMCAT_GENERAL);

	for (uint32 i = 0; i < data.height; ++i) {
		rowPointers[i] = (static_cast<uint8*>(data.data)) + i * rowStride;
	}
	png_set_rows(pngPtr, infoPtr, rowPointers);
	png_write_png(pngPtr, infoPtr,
			flip ? PNG_TRANSFORM_BGR : PNG_TRANSFORM_IDENTITY, NULL);

	failed: if (rowPointers)
		NEX_FREE(rowPointers, MEMCAT_GENERAL);
	if (pngPtr)
		png_destroy_write_struct(&pngPtr, &infoPtr);
}
Esempio n. 29
0
bool Pixmap::savePNG ( std::ostream& stream, unsigned int compressionLevel ) const
{
    png_structp png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0);
    if ( !png_ptr )
       return SetError ( "Error creating the PNG write struct" );
    
    png_byte** row_pointers = (png_byte **)png_malloc ( png_ptr, sizeof(png_byte*)*m_height );
    png_infop info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr)
    {
        png_free ( png_ptr, row_pointers );
        png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
        return SetError ( "Error creating the PNG write info struct" );
    }
    
    if (setjmp(png_jmpbuf(png_ptr)))
    {
       png_free ( png_ptr, row_pointers );
       png_destroy_write_struct(&png_ptr, &info_ptr);
       return SetError ( "An error occured when writing the PNG data" );
    }
    
    png_set_IHDR(png_ptr,
                 info_ptr,
                 m_width,
                 m_height,
                 8,
                 PNG_COLOR_TYPE_RGB_ALPHA,
                 PNG_INTERLACE_NONE,
                 PNG_COMPRESSION_TYPE_DEFAULT,
                 PNG_FILTER_TYPE_DEFAULT);
    
    png_set_write_fn ( png_ptr, &stream, write_to_png, flush_png );
    png_set_compression_level( png_ptr, compressionLevel );
    
    for ( unsigned int i = 0; i < m_height; ++i )
        row_pointers[i] = (png_byte *)&m_pixels[i*m_width];
    png_set_rows(png_ptr, info_ptr, row_pointers);
    png_write_png(png_ptr, info_ptr, detectBigEndian() ? PNG_TRANSFORM_BGR|PNG_TRANSFORM_SWAP_ALPHA : PNG_TRANSFORM_IDENTITY, 0);     
    png_destroy_write_struct(&png_ptr, &info_ptr);

    png_free ( png_ptr, row_pointers );
    
    return true;
}
Esempio n. 30
0
uint8_t *createPNGData(MMBitmapRef bitmap, size_t *len)
{
	PNGWriteInfoRef info = NULL;
	struct io_data data = {NULL, 0, 0};

	assert(bitmap != NULL);
	assert(len != NULL);

	if ((info = createPNGWriteInfo(bitmap)) == NULL) return NULL;

	png_set_write_fn(info->png_ptr, &data, &png_append_data, NULL);
	png_write_png(info->png_ptr, info->info_ptr, PNG_TRANSFORM_IDENTITY, NULL);

	destroyPNGWriteInfo(info);

	*len = data.size;
	return data.buffer;
}