/** * \brief encode an image to RGB(A) PNG format * \private \memberof mapcache_image_format_png * \sa mapcache_image_format::write() */ mapcache_buffer* _mapcache_imageio_png_encode(mapcache_context *ctx, mapcache_image *img, mapcache_image_format *format) { png_infop info_ptr; int color_type; size_t row; mapcache_buffer *buffer = NULL; int compression = ((mapcache_image_format_png*)format)->compression_level; png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,NULL,NULL); if (!png_ptr) { ctx->set_error(ctx, 500, "failed to allocate png_struct structure"); return NULL; } info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_write_struct(&png_ptr, (png_infopp)NULL); ctx->set_error(ctx, 500, "failed to allocate png_info structure"); return NULL; } if (setjmp(png_jmpbuf(png_ptr))) { ctx->set_error(ctx, 500, "failed to setjmp(png_jmpbuf(png_ptr))"); png_destroy_write_struct(&png_ptr, &info_ptr); return NULL; } buffer = mapcache_buffer_create(5000,ctx->pool); png_set_write_fn(png_ptr, buffer, _mapcache_imageio_png_write_func, _mapcache_imageio_png_flush_func); if(mapcache_image_has_alpha(img)) color_type = PNG_COLOR_TYPE_RGB_ALPHA; else color_type = PNG_COLOR_TYPE_RGB; png_set_IHDR(png_ptr, info_ptr, img->w, img->h, 8, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); if(compression == MAPCACHE_COMPRESSION_BEST) png_set_compression_level (png_ptr, Z_BEST_COMPRESSION); else if(compression == MAPCACHE_COMPRESSION_FAST) png_set_compression_level (png_ptr, Z_BEST_SPEED); png_write_info(png_ptr, info_ptr); if(color_type == PNG_COLOR_TYPE_RGB) png_set_filler(png_ptr, 255, PNG_FILLER_AFTER); png_bytep rowptr = img->data; for(row=0;row<img->h;row++) { png_write_row(png_ptr,rowptr); rowptr += img->stride; } png_write_end(png_ptr, info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr); return buffer; }
// // initialize PNG writing // static void s_PngWriteInit(png_structp& png_ptr, png_infop& info_ptr, size_t width, size_t height, size_t depth, CImageIO::ECompress compress) { png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, s_PngWriteErrorHandler, s_PngWarningHandler); if ( !png_ptr ) { NCBI_THROW(CImageException, eWriteError, "CImageIOPng::WriteImage(): png_create_read_struct() failed"); } info_ptr = png_create_info_struct(png_ptr); if ( !info_ptr ) { NCBI_THROW(CImageException, eWriteError, "CImageIOPng::WriteImage(): png_create_info_struct() failed"); } png_byte color_type = PNG_COLOR_TYPE_RGB; if (depth == 4) { color_type = PNG_COLOR_TYPE_RGBA; } png_set_IHDR(png_ptr, info_ptr, width, height, 8, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); // set our compression quality switch (compress) { case CImageIO::eCompress_None: png_set_filter(png_ptr, 0, PNG_FILTER_NONE); png_set_compression_level(png_ptr, Z_NO_COMPRESSION); break; case CImageIO::eCompress_Low: png_set_filter(png_ptr, 0, PNG_FILTER_NONE); png_set_compression_level(png_ptr, Z_BEST_SPEED); break; case CImageIO::eCompress_Medium: png_set_compression_level(png_ptr, Z_DEFAULT_COMPRESSION); break; case CImageIO::eCompress_High: png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); break; default: LOG_POST_X(26, Error << "unknown compression type: " << (int)compress); break; } }
bool PNGOutput::open (const std::string &name, const ImageSpec &userspec, OpenMode mode) { if (mode != Create) { error ("%s does not support subimages or MIP levels", format_name()); return false; } close (); // Close any already-opened file m_spec = userspec; // Stash the spec m_file = Filesystem::fopen (name, "wb"); if (! m_file) { error ("Could not open file \"%s\"", name.c_str()); return false; } std::string s = PNG_pvt::create_write_struct (m_png, m_info, m_color_type, m_spec); if (s.length ()) { close (); error ("%s", s.c_str ()); return false; } png_init_io (m_png, m_file); png_set_compression_level (m_png, 6 /* medium speed vs size tradeoff */); PNG_pvt::write_info (m_png, m_info, m_color_type, m_spec, m_pngtext); return true; }
static size_t rgb2png(ss_t **png, const ss_t *rgb, const struct RGB_Info *ri) { RETURN_IF(!valid_rgbi(ri) ||!rgb, 0); size_t out_size = 0; png_structp s = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); png_infop pi = png_create_info_struct(s); if (png) ss_set_size(*png, 0); png_set_write_fn(s, (png_voidp)png, aux_png_write, NULL); int ctype = (ri->chn > 1 ? PNG_COLOR_MASK_COLOR : 0) | (ri->chn == 2 || ri->chn == 4 ? PNG_COLOR_MASK_ALPHA : 0); png_set_IHDR(s, pi, (png_uint_32)ri->width, (png_uint_32)ri->height, ri->bpc, ctype, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_set_filter(s, PNG_FILTER_TYPE_BASE, PNG_ALL_FILTERS); png_set_compression_level(s, Z_BEST_COMPRESSION); png_write_info(s, pi); png_bytep *rows = (png_bytep *)alloca(sizeof(png_bytep) * pi->height); if (aux_png_set_rows(rows, pi, ss_get_buffer_r(rgb))) { png_write_image(s, rows); png_write_end(s, pi); out_size = ss_size(*png); } png_destroy_info_struct(s, &pi); png_destroy_write_struct(&s, &pi); return out_size; }
/** \brief Constructor. * * @param fd File handle to adapt. * @param skip How many bytes of file have already been read */ PngWriter(FILE *fd) : m_fd(fd), m_png(NULL), m_info(NULL) { m_png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if(!m_png) { std::stringstream sstr; sstr << "could not create a PNG read struct"; BOOST_THROW_EXCEPTION(std::runtime_error(sstr.str())); } m_info = png_create_info_struct(m_png); if(!m_info) { std::stringstream sstr; sstr << "could not create a PNG info struct"; BOOST_THROW_EXCEPTION(std::runtime_error(sstr.str())); } png_init_io(m_png, m_fd); // read header png_set_compression_buffer_size(m_png, 8192); png_set_compression_level(m_png, Z_BEST_COMPRESSION); png_set_compression_mem_level(m_png, Z_BEST_COMPRESSION); png_set_compression_window_bits(m_png, 15); }
pngquant_error rwpng_write_image_init(png_image *mainprog_ptr, png_structpp png_ptr_p, png_infopp info_ptr_p, FILE *outfile) { /* could also replace libpng warning-handler (final NULL), but no need: */ *png_ptr_p = png_create_write_struct(PNG_LIBPNG_VER_STRING, mainprog_ptr, rwpng_error_handler, NULL); if (!(*png_ptr_p)) { return LIBPNG_INIT_ERROR; /* out of memory */ } *info_ptr_p = png_create_info_struct(*png_ptr_p); if (!(*info_ptr_p)) { png_destroy_write_struct(png_ptr_p, NULL); return LIBPNG_INIT_ERROR; /* out of memory */ } /* setjmp() must be called in every function that calls a PNG-writing * libpng function, unless an alternate error handler was installed-- * but compatible error handlers must either use longjmp() themselves * (as in this program) or exit immediately, so here we go: */ if (setjmp(mainprog_ptr->jmpbuf)) { png_destroy_write_struct(png_ptr_p, info_ptr_p); return LIBPNG_INIT_ERROR; /* libpng error (via longjmp()) */ } png_init_io(*png_ptr_p, outfile); png_set_compression_level(*png_ptr_p, Z_BEST_COMPRESSION); return SUCCESS; }
/* Since libpng forces us to use longjmp, this function shouldn't create any C++ * objects, and needs to watch out for memleaks. */ static bool RageSurface_Save_PNG( RageFile &f, char szErrorbuf[1024], RageSurface *pImgIn ) { bool bAlpha = pImgIn->format->Amask != 0; RageSurface *pImg; bool bDeleteImg = RageSurfaceUtils::ConvertSurface( pImgIn, pImg, pImgIn->w, pImgIn->h, 32, Swap32BE( 0xFF000000 ), Swap32BE( 0x00FF0000 ), Swap32BE( 0x0000FF00 ), Swap32BE( 0x000000FF ) ); if( !bDeleteImg ) pImg = pImgIn; 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 ); if( bDeleteImg ) delete pImg; sprintf( szErrorbuf, "creating png_create_info_struct failed"); return false; } if( setjmp(png_jmpbuf(pPng)) ) { png_destroy_read_struct( &pPng, &pInfo, NULL ); return false; } png_set_write_fn( pPng, &f, RageFile_png_write, RageFile_png_flush ); png_set_compression_level( pPng, 1 ); png_set_IHDR( pPng, pInfo, pImg->w, pImg->h, 8, bAlpha? PNG_COLOR_TYPE_RGBA:PNG_COLOR_TYPE_RGB, 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 *) pImg->pixels; for( int y = 0; y < pImg->h; y++ ) png_write_row( pPng, pixels + pImg->pitch*y ); png_write_end( pPng, pInfo ); png_destroy_write_struct( &pPng, &pInfo ); /* Free the converted image. */ if( bDeleteImg ) delete pImg; return true; }
void write_png_image(char * dest, image_t * image) { FILE *outfile; if ((outfile = fopen(dest, "wb")) == NULL) { fprintf(stderr, "can't open %s", dest); return; } png_structp png_ptr; png_infop info_ptr; png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); info_ptr = png_create_info_struct(png_ptr); png_init_io(png_ptr, outfile); png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); png_set_IHDR(png_ptr, info_ptr, image->size[0], image->size[1], 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_write_info(png_ptr, info_ptr); for(int i = 0; i < image->size[1]; i++) { png_write_row(png_ptr , &(*image->pixels)[i * image->size[0] * RGB_CHANNEL]); } png_write_end(png_ptr, NULL); fclose(outfile); }
static int WritePNG(FILE* file, uint8_t* buffer, int width, int height) { size_t pitch = width * 4; png_structp png_ptr; png_infop info_ptr; if (!(png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL))) goto png_error; if (!(info_ptr = png_create_info_struct(png_ptr))) goto info_error; if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); goto png_error; } png_init_io(png_ptr, file); png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_write_info(png_ptr, info_ptr); for (int r = height * pitch - pitch; r >= 0; r -= pitch) png_write_row(png_ptr, buffer + r); png_write_end(png_ptr, info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr); return 1; info_error: png_destroy_write_struct(&png_ptr, NULL); png_error: return 0; }
void begin_png() { png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,0,0,0); info_ptr = png_create_info_struct(png_ptr); png_set_compression_level(png_ptr,9); png_set_write_fn(png_ptr, (void*)this, write, 0); }
static void write_png(const png_bytep rgba, png_uint_32 width, png_uint_32 height, SkWStream& out) { png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); SkASSERT(png != nullptr); png_infop info_ptr = png_create_info_struct(png); SkASSERT(info_ptr != nullptr); if (setjmp(png_jmpbuf(png))) { SkFAIL("png encode error"); } png_set_IHDR(png, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_set_compression_level(png, 1); png_bytepp rows = (png_bytepp) sk_malloc_throw(height * sizeof(png_byte*)); png_bytep pixels = (png_bytep) sk_malloc_throw(width * height * 3); for (png_size_t y = 0; y < height; ++y) { const png_bytep src = rgba + y * width * 4; rows[y] = pixels + y * width * 3; // convert from RGBA to RGB for (png_size_t x = 0; x < width; ++x) { rows[y][x * 3] = src[x * 4]; rows[y][x * 3 + 1] = src[x * 4 + 1]; rows[y][x * 3 + 2] = src[x * 4 + 2]; } } png_set_filter(png, 0, PNG_NO_FILTERS); png_set_rows(png, info_ptr, &rows[0]); png_set_write_fn(png, &out, write_png_callback, NULL); png_write_png(png, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); png_destroy_write_struct(&png, NULL); sk_free(rows); }
std::unique_ptr<PNGImageEncoderState> PNGImageEncoderState::create(const IntSize& imageSize, Vector<unsigned char>* output) { if (imageSize.width() <= 0 || imageSize.height() <= 0) return nullptr; 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 nullptr; } // 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 set to 3 instead of 6, to avoid the lazy Ziv-Lempel match searching. png_set_compression_level(png, 3); // The zlib memory level is set to 8. This actually matches the default, we are just future-proofing. png_set_compression_mem_level(png, 8); // The zlib strategy is set to Z_FILTERED, which does not match the default. // 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_strategy(png, Z_FILTERED); // The delta filter is PNG_FILTER_SUB instead of PNG_ALL_FILTERS, to reduce the filter computations. 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); return wrapUnique(new PNGImageEncoderState(png, info)); }
static int pngdrv_open_memmap(const char *filename, int x_size, int y_size, BYTE *palette) { pngdrv_memmap_png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (void *)NULL, NULL, NULL); if (pngdrv_memmap_png_ptr == NULL) { return -1; } pngdrv_memmap_info_ptr = png_create_info_struct(pngdrv_memmap_png_ptr); if (pngdrv_memmap_info_ptr == NULL) { png_destroy_write_struct(&(pngdrv_memmap_png_ptr), (png_infopp)NULL); return -1; } /* pngdrv.c:232: warning: ‘jmpbuf‘ is deprecated (declared at /usr/include/libpng14/png.h:1096) */ /* if (setjmp(pngdrv_memmap_png_ptr->jmpbuf)) { */ if (setjmp(png_jmpbuf(pngdrv_memmap_png_ptr))) { png_destroy_write_struct(&(pngdrv_memmap_png_ptr), &(pngdrv_memmap_info_ptr)); return -1; } pngdrv_memmap_ext_filename = util_add_extension_const(filename, png_drv.default_extension); pngdrv_memmap_fd = fopen(pngdrv_memmap_ext_filename, MODE_WRITE); if (pngdrv_memmap_fd == NULL) { lib_free(pngdrv_memmap_ext_filename); return -1; } pngdrv_memmap_png_data = lib_malloc(x_size * 4); png_init_io(pngdrv_memmap_png_ptr, pngdrv_memmap_fd); png_set_compression_level(pngdrv_memmap_png_ptr, Z_BEST_COMPRESSION); /* pngdrv.c:251: warning: ‘width‘ is deprecated (declared at /usr/include/libpng14/png.h:639) pngdrv.c:252: warning: ‘height‘ is deprecated (declared at /usr/include/libpng14/png.h:640) pngdrv.c:253: warning: ‘bit_depth‘ is deprecated (declared at /usr/include/libpng14/png.h:651) pngdrv.c:254: warning: ‘color_type‘ is deprecated (declared at /usr/include/libpng14/png.h:653) */ /* pngdrv_memmap_info_ptr->width = x_size; pngdrv_memmap_info_ptr->height= y_size; pngdrv_memmap_info_ptr->bit_depth = 8; pngdrv_memmap_info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA; */ png_set_IHDR(pngdrv_memmap_png_ptr, pngdrv_memmap_info_ptr, x_size, y_size, 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_write_info(pngdrv_memmap_png_ptr, pngdrv_memmap_info_ptr); #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED png_set_invert_alpha(pngdrv_memmap_png_ptr); #endif return 0; }
errort WritePNG( FILE * fp , unsigned char * data, unsigned int sizeX, unsigned int sizeY, int img_depth, int img_alpha) { png_structp png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, (png_voidp)NULL,NULL,NULL); if (!png_ptr) return BadFormat; png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_write_struct(&png_ptr, (png_infopp)NULL); return BadFormat; } if (setjmp(png_ptr->jmpbuf)) { png_destroy_write_struct(&png_ptr, &info_ptr); return BadFormat; } png_init_io(png_ptr, fp); png_set_filter(png_ptr, 0, PNG_FILTER_NONE); png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); /* set other zlib parameters */ png_set_compression_mem_level(png_ptr, 8); png_set_compression_strategy(png_ptr, Z_DEFAULT_STRATEGY); png_set_compression_window_bits(png_ptr, 15); png_set_compression_method(png_ptr, 8); png_set_IHDR(png_ptr, info_ptr, sizeX, sizeY, img_depth, img_alpha?PNG_COLOR_TYPE_RGB_ALPHA:PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_write_info(png_ptr, info_ptr); # if __BYTE_ORDER != __BIG_ENDIAN if (img_depth==16) { png_set_swap(png_ptr); } #endif int stride = (img_depth/8)*(img_alpha?4:3); png_byte **row_pointers = new png_byte*[sizeY]; for (unsigned int i=0;i<sizeY;i++) { row_pointers[i]= (png_byte *)&data[stride*i*sizeX]; } png_write_image (png_ptr,row_pointers); png_write_end(png_ptr, info_ptr); png_write_flush(png_ptr); png_destroy_write_struct(&png_ptr, &info_ptr); //free (data); delete [] row_pointers; return Ok; }
void Bonsai::_cacheColorImage( const char *suffix, GLubyte *data, int sz ) { char filename[256]; sprintf( filename, "./%s/%s_%s.png", CACHE_DIR, m_name, suffix ); FILE *fp = fopen( filename, "wb" ); if (!fp) { DBG::warn( "Error writing cache file %s\n", filename ); return; } png_structp png_ptr = png_create_write_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL ); if (!png_ptr) { DBG::warn( "error creating png write struct\n" ); } png_infop info_ptr = png_create_info_struct( png_ptr ); if (!info_ptr) { png_destroy_write_struct( &png_ptr, (png_infopp)NULL ); DBG::warn( "error creating png info struct\n" ); } // init IO and compression png_init_io( png_ptr, fp ); png_set_compression_level( png_ptr, Z_BEST_COMPRESSION ); // set content header png_set_IHDR( png_ptr, info_ptr, sz, sz, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT ); // write header info png_write_info(png_ptr, info_ptr); // write the thing // FIXME -- should use sz png_byte *row_pointers[1024]; for (int i=0; i < sz; i++) { // flip row_pointers[i] = &(data[(1023-i) * sz * 3]); } png_write_image( png_ptr, row_pointers ); png_write_end( png_ptr, info_ptr ); png_destroy_write_struct( &png_ptr, &info_ptr ); fclose( fp ); DBG::info( "Wrote cache image %s\n", filename ); }
int main(int argc, char **argv) { int i; unsigned char *scanbuf; unsigned char **rows; png_structp png_p; png_infop info_p; if ( !get_args( argc, argv ) ) { (void)fputs(usage, stderr); bu_exit ( 1, NULL ); } /* autosize input? */ if ( fileinput && autosize ) { unsigned long int w, h; if ( fb_common_file_size(&w, &h, file_name, 1) ) { file_width = (long)w; file_height = (long)h; } else { fprintf(stderr, "bw-png: unable to autosize\n"); } } png_p = png_create_write_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL ); if ( !png_p ) bu_exit( EXIT_FAILURE, "Could not create PNG write structure\n" ); info_p = png_create_info_struct( png_p ); if ( !info_p ) bu_exit( EXIT_FAILURE, "Could not create PNG info structure\n" ); /* allocate space for the image */ scanbuf = (unsigned char *)bu_calloc( SIZE, sizeof( unsigned char ), "scanbuf" ); /* create array of pointers to rows for libpng */ rows = (unsigned char **)bu_calloc( file_height, sizeof( unsigned char *), "rows" ); for ( i=0; i<file_height; i++ ) rows[i] = scanbuf + ((file_height-i-1)*ROWSIZE); /* read the bw file */ if ( fread( scanbuf, SIZE, 1, infp ) != 1 ) bu_exit( EXIT_FAILURE, "bw-png: Short read\n"); png_init_io( png_p, stdout ); png_set_filter( png_p, 0, PNG_FILTER_NONE ); png_set_compression_level( png_p, Z_BEST_COMPRESSION ); png_set_IHDR( png_p, info_p, file_width, file_height, 8, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT ); png_write_info( png_p, info_p ); png_write_image( png_p, rows ); png_write_end( png_p, NULL ); return 0; }
bool CPNGFile::Save(const char *szFilename) { // regular file saving - first, there has to be a buffer if (!pImageData) return false; // open the file fp = fopen(szFilename, "wb"); if (!fp) return false; // clear any previously initialized png-structs (e.g. by reading) ClearPngStructs(); // reinit them for writing fWriteMode=true; png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { Clear(); return false; } info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { Clear(); return false; } // error handling if (setjmp(png_jmpbuf(png_ptr))) { Clear(); return false; } // io initialization png_init_io(png_ptr, fp); // compression stuff png_set_filter(png_ptr, 0, PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_PAETH); png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); png_set_compression_mem_level(png_ptr, 8); png_set_compression_strategy(png_ptr, Z_DEFAULT_STRATEGY); png_set_compression_window_bits(png_ptr, 15); png_set_compression_method(png_ptr, 8); // set header png_set_IHDR(png_ptr, info_ptr, iWdt, iHgt, iBPC, iClrType, iIntrlcType, iCmprType, iFltrType); // double-check our calculated row size int iRealRowSize=png_get_rowbytes(png_ptr, info_ptr); if (iRealRowSize != iRowSize) { // this won't go well, so better abort Clear(); return false; } // write png header png_write_info(png_ptr, info_ptr); // image data is given as bgr... png_set_bgr(png_ptr); // create row array unsigned char **ppRowBuf = new unsigned char *[iHgt]; unsigned char **ppRows=ppRowBuf; unsigned char *pRow=pImageData; for (unsigned int i=0; i<iHgt; ++i,pRow+=iRowSize) *ppRows++=pRow; // write image png_write_image(png_ptr, ppRowBuf); // free row buffer delete [] ppRowBuf; // write end struct png_write_end(png_ptr, info_ptr); // finally, close the file fclose(fp); fp = NULL; // clear png structs ClearPngStructs(); // success! return true; }
void png_write( const char *myfile, unsigned char *data, unsigned int width, unsigned int height, bool alpha, char bpp ) { FILE *fp = VSFileSystem::vs_open( myfile, "wb" ); png_structp png_ptr = png_create_write_struct ( PNG_LIBPNG_VER_STRING, (png_voidp) NULL, NULL, NULL ); if (!png_ptr) return; png_infop info_ptr = png_create_info_struct( png_ptr ); if (!info_ptr) { png_destroy_write_struct( &png_ptr, (png_infopp) NULL ); return; } if ( setjmp( png_ptr->jmpbuf ) ) { png_destroy_write_struct( &png_ptr, &info_ptr ); VSFileSystem::vs_close( fp ); return; } png_init_io( png_ptr, fp ); png_set_filter( png_ptr, 0, PNG_FILTER_NONE ); png_set_compression_level( png_ptr, Z_BEST_COMPRESSION ); /* set other zlib parameters */ png_set_compression_mem_level( png_ptr, 8 ); png_set_compression_strategy( png_ptr, Z_DEFAULT_STRATEGY ); png_set_compression_window_bits( png_ptr, 15 ); png_set_compression_method( png_ptr, 8 ); png_set_IHDR( png_ptr, info_ptr, width, height, bpp, alpha ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT ); png_write_info( png_ptr, info_ptr ); # if __BYTE_ORDER != __BIG_ENDIAN if (bpp == 16) png_set_swap( png_ptr ); #endif int stride = (bpp/8)*(alpha ? 4 : 3); png_byte **row_pointers = new png_byte*[height]; for (unsigned int i = 0; i < height; i++) row_pointers[i] = (png_byte*) &data[stride*i*width]; png_write_image( png_ptr, row_pointers ); png_write_end( png_ptr, info_ptr ); png_write_flush( png_ptr ); png_destroy_write_struct( &png_ptr, &info_ptr ); VSFileSystem::vs_close( fp ); free( data ); delete[] row_pointers; }
/* save screenshot in png format, return true if success, or false */ bool CScreenShot::SavePng() { png_bytep *row_pointers; png_structp png_ptr; png_infop info_ptr; TIMER_START(); if(!OpenFile()) return false; row_pointers = (png_bytep *) malloc(sizeof(png_bytep) * yres); if (!row_pointers) { printf("CScreenShot::SavePng: malloc error\n"); fclose(fd); return false; } png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL, (png_error_ptr)NULL, (png_error_ptr)NULL); info_ptr = png_create_info_struct(png_ptr); if (setjmp(png_jmpbuf(png_ptr))) { printf("CScreenShot::SavePng: %s save error\n", filename.c_str()); png_destroy_write_struct(&png_ptr, &info_ptr); free(row_pointers); fclose(fd); return false; } png_init_io(png_ptr, fd); int y; for (y=0; y<yres; y++) { row_pointers[y] = pixel_data + (y*xres*4); } png_set_IHDR(png_ptr, info_ptr, xres, yres, 8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); //png_set_filter (png_ptr, 0, PNG_FILTER_NONE); png_set_compression_level(png_ptr, Z_BEST_SPEED); png_set_bgr(png_ptr); #ifdef BOXMODEL_APOLLO png_set_invert_alpha(png_ptr); #endif png_write_info(png_ptr, info_ptr); png_write_image(png_ptr, row_pointers); png_write_end(png_ptr, info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr); free(row_pointers); fclose(fd); TIMER_STOP(filename.c_str()); return true; }
int zbar_image_write_png (const zbar_image_t *img, const char *filename) { int rc = -1; FILE *file = NULL; png_struct *png = NULL; png_info *info = NULL; const uint8_t **rows = NULL; rows = malloc(img->height * sizeof(*rows)); if(!rows) goto done; rows[0] = img->data; int y; for(y = 1; y < img->height; y++) rows[y] = rows[y - 1] + img->width; file = fopen(filename, "wb"); if(!file) goto done; png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if(!png) goto done; info = png_create_info_struct(png); if(!info) goto done; if(setjmp(png_jmpbuf(png))) goto done; png_init_io(png, file); png_set_compression_level(png, 9); png_set_IHDR(png, info, img->width, img->height, 8, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_set_rows(png, info, (void*)rows); png_write_png(png, info, PNG_TRANSFORM_IDENTITY, NULL); png_write_end(png,info); rc = 0; done: if(png) png_destroy_write_struct(&png, &info); if(rows) free(rows); if(file) fclose(file); return(rc); }
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); } } }
void screenshot(int i) { char fname[128]; snprintf(fname, sizeof(fname), "output/screenshot-%i.png", i); cout << " + Saving \"" << fname << "\"" << endl; FILE *file = fopen(fname, "wb"); if (file == NULL) { cerr << "Error: Could not open \"" << fname << "\"!" << endl; exit(-1); } png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) { cout << "Error: could not initialize libpng!" << endl; exit(-1); } png_infop info = png_create_info_struct(png_ptr); if (info == NULL) { cout << "Error: could not initialize libpng!" << endl; exit(-1); } if (setjmp(png_ptr->jmpbuf)) { cerr << "Error: \"" << fname << "\" could not be written!" << endl; exit(-1); } png_init_io (png_ptr, file); png_set_compression_level(png_ptr, 3); png_set_IHDR(png_ptr, info, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_write_info(png_ptr, info); png_bytepp rows = new png_bytep[height]; png_bytep data = new png_byte[3*width*height]; glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, data); for (int i=0; i<height; i++) rows[height-1-i] = data + width*3*i; png_write_image(png_ptr, (png_bytepp) rows); png_write_end(png_ptr, info); png_destroy_write_struct(&png_ptr, &info); delete[] data; delete[] rows; fclose(file); }
void PNGImageWriter::beginOfImage(int cols, int rows) { _png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); _info_ptr = png_create_info_struct(_png_ptr); if (!_info_ptr) { png_destroy_write_struct(&_png_ptr, NULL); exit(1); } png_set_IHDR(_png_ptr, _info_ptr, cols, rows, 16, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, NULL/*PNG_COMPRESSION_TYPE_DEFAULT*/, PNG_FILTER_TYPE_DEFAULT); //png_set_filter(_png_ptr, 0, PNG_FILTER_NONE); //png_set_packing(_png_ptr); png_set_compression_level(_png_ptr, 0); // No compression png_set_filter(_png_ptr, 0 /* method */, PNG_NO_FILTERS); png_color_8 sig_bit; sig_bit.gray = 16; sig_bit.red = 0; sig_bit.green = 0; sig_bit.blue = 0; sig_bit.alpha = 0; png_set_sBIT(_png_ptr, _info_ptr, &sig_bit); //png_set_shift(_png_ptr, &sig_bit); //png_set_gamma(_png_ptr, 1., 1.); png_set_strip_16(_png_ptr); //if (lsb) //png_set_swap(_png_ptr); // flush output after every row if (_lineBuffered) png_set_flush(_png_ptr, 1); //png_set_filler(_png_ptr, 0, PNG_FILLER_BEFORE); // Represent black as 1 and white as 0 instead of the PNG default. //png_set_invert_mono(_png_ptr); png_init_io(_png_ptr, _output); /* write the file information */ png_write_info(_png_ptr, _info_ptr); }
void gdImagePng(gdImagePtr im, FILE *out) { int i; png_colorp palette; png_structp png_write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL, /* we would need to point to error handlers here to do it properly */ (png_error_ptr)NULL, (png_error_ptr)NULL); png_infop info_ptr = png_create_info_struct(png_write_ptr); if (setjmp(gdPngJmpbufStruct.jmpbuf)) { png_destroy_write_struct(&png_write_ptr, &info_ptr); return; } palette = (png_colorp)png_malloc (png_write_ptr, im->colorsTotal*sizeof(png_color)); if (palette == NULL) { png_destroy_write_struct(&png_write_ptr, &info_ptr); return; } png_init_io(png_write_ptr, out); png_set_write_status_fn(png_write_ptr, NULL); png_set_IHDR(png_write_ptr,info_ptr, im->sx,im->sy,im->colorsTotal > 16 ? 8:4, PNG_COLOR_TYPE_PALETTE, im->interlace ? PNG_INTERLACE_ADAM7: PNG_INTERLACE_NONE , PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); for(i=0; i<im->colorsTotal; i++) { palette[i].red = im->red[i]; palette[i].green = im->green[i]; palette[i].blue = im->blue[i]; } png_set_PLTE(png_write_ptr, info_ptr, palette, im->colorsTotal); /* choose between speed (1) and space (9) optimization */ /* we want to be fast ... */ png_set_compression_level(png_write_ptr,1); png_set_filter(png_write_ptr,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS); /* store file info */ png_write_info(png_write_ptr, info_ptr); png_set_packing(png_write_ptr); png_write_image(png_write_ptr, im->pixels); png_write_end(png_write_ptr, info_ptr); png_free(png_write_ptr, palette); png_destroy_write_struct(&png_write_ptr, &info_ptr); }
bool PNGOutput::open (const std::string &name, const ImageSpec &userspec, OpenMode mode) { if (mode != Create) { error ("%s does not support subimages or MIP levels", format_name()); return false; } close (); // Close any already-opened file m_spec = userspec; // Stash the spec m_file = Filesystem::fopen (name, "wb"); if (! m_file) { error ("Could not open file \"%s\"", name.c_str()); return false; } std::string s = PNG_pvt::create_write_struct (m_png, m_info, m_color_type, m_spec); if (s.length ()) { close (); error ("%s", s.c_str ()); return false; } png_init_io (m_png, m_file); int compression_level = 6; /* medium speed vs size tradeoff */ // RTT MOD: CVI use incoming compression values const ImageIOParameter *compParameter = m_spec.find_attribute ("CompressionQuality",TypeDesc::INT); if (compParameter) { compression_level = *(const int *)compParameter->data(); compression_level = std::min( std::max( compression_level, 0 ), 9 ); // compression 0-9 } png_set_compression_level (m_png, compression_level); const ImageIOParameter *filterParameter = m_spec.find_attribute ("png:Filters",TypeDesc::INT); if (filterParameter) { int filters = *(const int *)filterParameter->data(); filters &= PNG_ALL_FILTERS; png_set_filter(m_png, 0, filters); } PNG_pvt::write_info (m_png, m_info, m_color_type, m_spec, m_pngtext); return true; }
/* 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; }
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; }
void CSnapShot::WriteImageToFile(CThread * pThread) { m_threadData.bWriting = true; D3DDISPLAYMODE displayMode; g_pCore->GetGraphics()->GetDevice()->GetDisplayMode(0, &displayMode); UINT uiScreenWidth = displayMode.Width; UINT uiScreenHeight = displayMode.Height; BYTE* mem = new BYTE[SCREEN_SHOT_FORMAT_BYTES_PER_PIXEL * uiScreenWidth * uiScreenWidth]; GetFrontBufferPixels(uiScreenWidth, uiScreenHeight, mem); BYTE** ScreenData = nullptr; ScreenData = new BYTE* [uiScreenHeight]; for (unsigned short y = 0; y < uiScreenHeight; y++) { ScreenData[y] = new BYTE[uiScreenWidth * SCREEN_SHOT_FORMAT_BYTES_PER_PIXEL]; } UINT uiLinePitch = uiScreenWidth * SCREEN_SHOT_FORMAT_BYTES_PER_PIXEL; unsigned long ulLineWidth = uiScreenWidth * SCREEN_SHOT_FORMAT_BYTES_PER_PIXEL; for (unsigned int i = 0; i < uiScreenHeight; i++) { memcpy(ScreenData[i], (BYTE*) mem + i* uiLinePitch, ulLineWidth); for(unsigned int j = 3; j < ulLineWidth; j += SCREEN_SHOT_FORMAT_BYTES_PER_PIXEL) { ScreenData[i][j] = 0xFF; } } CString strPath = GetScreenShotPath(); FILE *file = fopen(strPath, "wb"); png_struct* png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); png_info* info_ptr = png_create_info_struct(png_ptr); png_init_io(png_ptr, file); png_set_filter(png_ptr, 0, PNG_FILTER_NONE); png_set_compression_level(png_ptr, 9); png_set_IHDR(png_ptr, info_ptr, uiScreenWidth, uiScreenHeight, 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_set_rows(png_ptr, info_ptr, ScreenData); png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_BGR | PNG_TRANSFORM_STRIP_ALPHA, NULL); png_write_end(png_ptr, info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr); fclose(file); for (unsigned short y = 0; y < uiScreenHeight; y++) { delete []ScreenData[y]; } delete []ScreenData; delete []mem; m_threadData.bWriting = false; }
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); }
static void write_png(char *fname, unsigned char *buffer, int width, int height, int stride) { FILE * fp; png_structp png_ptr; png_infop info_ptr; png_byte **row_pointers; int k; png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); info_ptr = png_create_info_struct(png_ptr); fp = NULL; if (setjmp(png_ptr->jmpbuf)) { png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); return; } fp = fopen (fname, "wb"); if (fp == NULL) { mp_msg(MSGT_VFILTER,MSGL_ERR,"\nPNG Error opening %s for writing!\n", fname); return; } png_init_io(png_ptr, fp); png_set_compression_level(png_ptr, 0); png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_write_info(png_ptr, info_ptr); png_set_bgr(png_ptr); row_pointers = malloc(height*sizeof(png_byte*)); for (k = 0; k < height; k++) { unsigned char* s=buffer + stride*k; row_pointers[k] = s; } png_write_image(png_ptr, row_pointers); png_write_end(png_ptr, info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr); free(row_pointers); fclose (fp); }