本文整理汇总了C++中png_set_write_fn函数的典型用法代码示例。如果您正苦于以下问题:C++ png_set_write_fn函数的具体用法?C++ png_set_write_fn怎么用?C++ png_set_write_fn使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了png_set_write_fn函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: png_create_write_struct
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;
}
}
示例2: process
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;
}
示例3: encodeImpl
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;
}
示例4: PNGWriteOpen
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;
}
示例5: PNGLock
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);
}
}
}
示例6: png_create_write_struct
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);
}
示例7: output_
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);
}
示例8: bitmapToPNG
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);
}
示例9: TRACE_FUN
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;
}
示例10: png_create_write_struct
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;
}
示例11: encode_png
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);
}
示例12: SavePNG
/* 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;
}
示例13: writePixmapToPng
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;
}
示例14: NCBI_THROW
//
// 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;
}
}
示例15: save_as_png
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);
}