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; } }
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; }
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; }
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; }
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 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); }
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); }
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); }
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; }
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); }
/* 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; }
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; }
// // 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; } }
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); }
/* 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); }
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; }
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)); }
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; }
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 ); }
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; }
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); }
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; }
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; }
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); }
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; }
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; }