static void write_gray_alpha_to_gray_alpha (png_struct *png, png_byte *data, SLindex_Type num_cols, png_byte *tmpbuf) { if (Is_Little_Endian == 0) { png_write_row (png, data); return; } byte_swap16 ((unsigned char *) data, (unsigned char *) tmpbuf, num_cols); png_write_row (png, tmpbuf); }
static void dump_png24_impl( png_struct * ppng, png_info * pinfo, const uint8_t * data, const size_t width, const size_t height, const size_t rowsize, const bool bgr, IsOk is_ok ) { assert(align4(rowsize) == rowsize); png_set_IHDR(ppng, pinfo, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_write_info(ppng, pinfo); // send image buffer to file, one pixel row at once const uint8_t * row = data; if (bgr) { uint8_t bgrtmp[8192*4]; for (size_t k = 0 ; k < height && is_ok(); ++k) { const uint8_t * s = row; uint8_t * t = bgrtmp; uint8_t * e = t + (width / 4) * 12; for (; t < e; s += 12, t += 12){ t[0] = s[2]; t[1] = s[1]; t[2] = s[0]; t[3] = s[5]; t[4] = s[4]; t[5] = s[3]; t[6] = s[8]; t[7] = s[7]; t[8] = s[6]; t[9] = s[11]; t[10] = s[10]; t[11] = s[9]; } png_write_row(ppng, const_cast<unsigned char*>(bgrtmp)); row += rowsize; } } else { for (size_t k = 0 ; k < height && is_ok(); ++k) { png_write_row(ppng, const_cast<unsigned char*>(row)); row += rowsize; } } }
static int write_image(const char *filename, const dssim_rgba *pixels, int width, int height) { FILE *outfile = fopen(filename, "wb"); if (!outfile) { return 1; } png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); png_infop info_ptr = png_create_info_struct(png_ptr); png_init_io(png_ptr, outfile); png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGBA, 0, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_write_info(png_ptr, info_ptr); for (int i = 0; i < height; i++) { png_write_row(png_ptr, (png_bytep)(pixels + i * width)); } png_write_end(png_ptr, info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr); return 0; }
static VALUE each_interlace_none(struct each_args *args) { struct readerdata *reader; unsigned char *inwidthbuf, *outwidthbuf, *yinbuf; struct xscaler *xs; struct yscaler *ys; uint32_t i, scaley; int cmp; reader = args->reader; xs = &args->xs; inwidthbuf = xscaler_psl_pos0(xs); outwidthbuf = args->outwidthbuf; ys = &args->ys; scaley = reader->scale_height; cmp = png_get_channels(reader->png, reader->info); png_write_info(args->wpng, args->winfo); for(i=0; i<scaley; i++) { while ((yinbuf = yscaler_next(ys))) { png_read_row(reader->png, inwidthbuf, NULL); xscaler_scale(xs, yinbuf); } yscaler_scale(ys, outwidthbuf, i, cmp, 0); png_write_row(args->wpng, outwidthbuf); } png_write_end(args->wpng, args->winfo); return Qnil; }
static VALUE each_interlace(struct each_args *args) { struct readerdata *reader; unsigned char *inwidthbuf, *outwidthbuf; uint32_t i, width, height, scaley; int cmp; struct xscaler *xs; reader = args->reader; xs = &args->xs; inwidthbuf = xscaler_psl_pos0(xs); outwidthbuf = args->outwidthbuf; scaley = reader->scale_height; cmp = png_get_channels(reader->png, reader->info); width = png_get_image_width(reader->png, reader->info); height = png_get_image_height(reader->png, reader->info); png_write_info(args->wpng, args->winfo); png_read_image(args->reader->png, (png_bytepp)args->scanlines); for (i=0; i<scaley; i++) { yscaler_prealloc_scale(height, scaley, (uint8_t **)args->scanlines, (uint8_t *)inwidthbuf, i, width, cmp, 0); xscaler_scale(xs, outwidthbuf); png_write_row(args->wpng, outwidthbuf); } png_write_end(args->wpng, args->winfo); return Qnil; }
/* save_rgba: * Core save routine for 32 bpp images. */ static int save_rgba(png_structp png_ptr, BITMAP *bmp) { unsigned char *rowdata; int x, y; ASSERT(bitmap_color_depth(bmp) == 32); rowdata = (unsigned char *)malloc(bmp->w * 4); if (!rowdata) return 0; for (y=0; y<bmp->h; y++) { unsigned char *p = rowdata; for (x=0; x<bmp->w; x++) { int c = getpixel(bmp, x, y); *p++ = getr32(c); *p++ = getg32(c); *p++ = getb32(c); *p++ = geta32(c); } png_write_row(png_ptr, rowdata); } free(rowdata); return 1; }
bool PNGWritePixels(png_structp png, unsigned width, unsigned height, unsigned stride, const void* pixels) { png_bytep row = malloc(sizeof(png_bytep) * width * 3); if (!row) { return false; } const png_byte* pixelData = pixels; if (setjmp(png_jmpbuf(png))) { free(row); return false; } unsigned i; for (i = 0; i < height; ++i) { unsigned x; for (x = 0; x < width; ++x) { #if defined(__POWERPC__) || defined(__PPC__) row[x * 3] = pixelData[stride * i * 4 + x * 4 + 3]; row[x * 3 + 1] = pixelData[stride * i * 4 + x * 4 + 2]; row[x * 3 + 2] = pixelData[stride * i * 4 + x * 4 + 1]; #else row[x * 3] = pixelData[stride * i * 4 + x * 4]; row[x * 3 + 1] = pixelData[stride * i * 4 + x * 4 + 1]; row[x * 3 + 2] = pixelData[stride * i * 4 + x * 4 + 2]; #endif } png_write_row(png, row); } free(row); return true; }
int writepng_encode_row(mainprog_info *mainprog_ptr) /* NON-interlaced only! */ { AMJU_CALL_STACK; png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr; png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr; /* as always, setjmp() must be called in every function that calls a * PNG-writing libpng function */ if (setjmp(mainprog_ptr->jmpbuf)) { png_destroy_write_struct(&png_ptr, &info_ptr); mainprog_ptr->png_ptr = NULL; mainprog_ptr->info_ptr = NULL; return 2; } /* image_data points at our one row of image data */ png_write_row(png_ptr, mainprog_ptr->image_data); return 0; }
void write_image_data(const char* filename, png_bytep data, size_t w, size_t h) { unsigned int i; png_structp png_ptr; png_infop info_ptr; /* Open output file */ FILE *png_output; if((png_output = fopen(filename, "wb")) == NULL) { perror("Create output image file"); exit(1); } /* Write image data */ 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, png_output); png_set_IHDR(png_ptr, info_ptr, w, h, 16, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_write_info(png_ptr, info_ptr); for(i=0; i<h; i++) { png_write_row(png_ptr, data + i*png_get_rowbytes(png_ptr, info_ptr)); } /* Close file */ png_write_end(png_ptr, NULL); png_destroy_write_struct(&png_ptr, &info_ptr); fclose(png_output); }
int save_pixmap_png(struct pixmap *p, FILE *fp) { int result = 0, y; png_structp png_ptr; png_infop info_ptr; if (p) { if ((png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)) != NULL) { if ((info_ptr = png_create_info_struct(png_ptr)) != NULL) { if (setjmp(png_ptr->jmpbuf) == 0) { png_init_io(png_ptr, fp); png_set_IHDR(png_ptr, info_ptr, p->width, p->height, 8, (p->components == 1) ? PNG_COLOR_TYPE_GRAY : PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_write_info(png_ptr, info_ptr); for (y = 0; y < p->height; y++) { png_write_row(png_ptr, (png_bytep)&GET_COMP(p, 0, y, 0)); } png_write_end(png_ptr, info_ptr); png_destroy_write_struct(&png_ptr, (png_infopp)NULL); } else result = -1; } else result = -1; png_destroy_write_struct(&png_ptr, (png_infopp)NULL); } else result = -1; } return result; }
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); }
/* save_truecolour: * Core save routine for 32 bpp images. */ static int save_truecolour(png_structp png_ptr, BITMAP *bmp) { unsigned char *row, *p; int i, j, c; // [OMAR] row = malloc(bmp->w * 3); //row = malloc(bmp->w * 4); if (!row) return 0; for (i=0; i<bmp->h; i++) { p = row; for (j = 0; j < bmp->w; j++) { c = getpixel(bmp, j, i); *p++ = getr32(c); *p++ = getg32(c); *p++ = getb32(c); // [OMAR] //*p++ = geta32(c); } png_write_row(png_ptr, row); } free(row); return 1; }
/* 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; }
int rwpng_write_image_row(mainprog_info *mainprog_ptr) { png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr; png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr; /* as always, setjmp() must be called in every function that calls a * PNG-writing libpng function */ if (setjmp(mainprog_ptr->jmpbuf)) { png_destroy_write_struct(&png_ptr, &info_ptr); mainprog_ptr->png_ptr = NULL; mainprog_ptr->info_ptr = NULL; mainprog_ptr->retval = 55; /* libpng error (via longjmp()) */ return mainprog_ptr->retval; } /* indexed_data points at our one row of indexed data */ png_write_row(png_ptr, mainprog_ptr->indexed_data); mainprog_ptr->retval = 0; return 0; }
static void write_rgb_alpha_to_rgb_alpha (png_struct *png, png_byte *data, SLindex_Type num_cols, png_byte *tmpbuf) { unsigned char *data_max; unsigned char *p; if (Is_Little_Endian) { byte_swap32 ((unsigned char *) data, (unsigned char *) tmpbuf, num_cols); data = tmpbuf; } data_max = data + 4 * num_cols; p = tmpbuf; /* Change ARGBARGB... to RGBARGBA... */ while (data < data_max) { unsigned char a = data[0]; p[0] = data[1]; p[1] = data[2]; p[2] = data[3]; p[3] = a; data += 4; p += 4; } png_write_row (png, tmpbuf); }
bool encodePNGAndAppendToBuffer(unsigned char *pixmap, int width, int height, std::vector<char>& output) { png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); png_infop info_ptr = png_create_info_struct(png_ptr); if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, NULL); return false; } 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); png_set_write_fn(png_ptr, &output, user_write_fn, user_flush_fn); png_set_write_status_fn(png_ptr, user_write_status_fn); png_write_info(png_ptr, info_ptr); for (int y = 0; y < height; ++y) png_write_row(png_ptr, pixmap + y * width * 4); png_write_end(png_ptr, info_ptr); png_destroy_write_struct(&png_ptr, NULL); return true; }
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; }
/* Write the image. You only need to call this function once, even * if you are writing an interlaced image. */ void png_write_image(png_structp png_ptr, png_bytepp image) { png_uint_32 i; /* row index */ int pass, num_pass; /* pass variables */ png_bytepp rp; /* points to current row */ png_debug(1, "in png_write_image\n"); #if defined(PNG_WRITE_INTERLACING_SUPPORTED) /* intialize interlace handling. If image is not interlaced, this will set pass to 1 */ num_pass = png_set_interlace_handling(png_ptr); #else num_pass = 1; #endif /* loop through passes */ for (pass = 0; pass < num_pass; pass++) { /* loop through image */ for (i = 0, rp = image; i < png_ptr->height; i++, rp++) { png_write_row(png_ptr, *rp); } } }
/* save_hicolour: * Core save routine for 15/16 bpp images, by Martijn Versteegh. */ static int save_hicolour(png_structp png_ptr, BITMAP *bmp, int depth) { unsigned char *row, *p; int i, j, c; row = malloc(bmp->w * 3); if (!row) return 0; for (i=0; i<bmp->h; i++) { p = row; for (j = 0; j < bmp->w; j++) { c = getpixel(bmp, j, i); if (depth == 15) { *p++ = getr15(c); *p++ = getg15(c); *p++ = getb15(c); } else { *p++ = getr16(c); *p++ = getg16(c); *p++ = getb16(c); } } png_write_row(png_ptr, row); } free(row); return 1; }
static void crop_image(img_t *img, int base_offset, FILE *out) { int i, u, v; int ret, idx; int nr = img->sizeX / TILE_SIZE; png_bytep png_row_ptr; png_t png; png.fp = out; for (v = 0; v < nr; v++) { for (u = 0; u < nr; u++) { // update offset_map for zoom levels > 13 if (base_offset < 5) { idx = u + v*nr; offset_map[idx + offsets[base_offset]] = (int) ftell(out); } ret = open_png_writer(&png, TILE_SIZE/(img->sizeX/img->sizeY)); for (i = 0; i < img->sizeY/nr; i++) { png_row_ptr = (png_bytep) &img->raw_data[u*TILE_SIZE+v*(img->sizeY/nr)*img->sizeX+i*img->sizeX]; png_write_row(png.png_ptr, png_row_ptr); } close_png_writer(&png); } } }
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 write_rgba ( FILE *out, uint8 *data, int width, int height, int bpp ) // Writes a 24 or 32-bit color image in .png format, to the // given output stream. Data should be in [RGB or RGBA...] byte order. { if ( bpp != 3 && bpp != 4 ) { return; } png_structp png_ptr; png_infop info_ptr; png_ptr = png_create_write_struct ( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL ); if ( png_ptr == NULL ) { // @@ log error here! return; } info_ptr = png_create_info_struct ( png_ptr ); if ( info_ptr == NULL ) { // @@ log error here! png_destroy_write_struct ( &png_ptr, NULL ); return; } if ( setjmp ( png_jmpbuf ( png_ptr ) ) ) { // Error. png_destroy_write_struct ( &png_ptr, &info_ptr ); return; } png_init_io ( png_ptr, out ); png_set_write_fn ( png_ptr, ( png_voidp ) out, write_data, NULL ); png_set_IHDR ( png_ptr, info_ptr, width, height, 8, bpp == 3 ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT ); // png_set_swap_alpha(png_ptr); // png_set_bgr(png_ptr); png_write_info ( png_ptr, info_ptr ); for ( int y = 0; y < height; y++ ) { png_write_row ( png_ptr, data + ( width * bpp ) * y ); } png_write_end ( png_ptr, info_ptr ); png_destroy_write_struct ( &png_ptr, &info_ptr ); }
static void raw_callback(unsigned num, rgba *pixels) { if( libpng == NULL ) { init_output() ; } png_write_row(libpng,(png_bytep)pixels); xcffree(pixels); }
/** * \brief Writes a row of image data at a time. */ void write_row(byte* bytes) { if (setjmp(m_png->jmpbuf)) { throw error(m_error); } png_write_row(m_png, bytes); }
int jbig2_image_write_png(Jbig2Image *image, FILE *out) { int i; png_structp png; png_infop info; png_bytep rowpointer; png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png == NULL) { fprintf(stderr, "unable to create png structure\n"); return 2; } info = png_create_info_struct(png); if (info == NULL) { fprintf(stderr, "unable to create png info structure\n"); png_destroy_write_struct(&png, (png_infopp)NULL); return 3; } /* set/check error handling */ if (setjmp(png_jmpbuf(png))) { /* we've returned here after an internal error */ fprintf(stderr, "internal error in libpng saving file\n"); png_destroy_write_struct(&png, &info); return 4; } /* png_init_io() doesn't work linking dynamically to libpng on win32 one has to either link statically or use callbacks because of runtime variations */ /* png_init_io(png, out); */ png_set_write_fn(png, (png_voidp)out, jbig2_png_write_data, jbig2_png_flush); /* now we fill out the info structure with our format data */ png_set_IHDR(png, info, image->width, image->height, 1, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_write_info(png, info); /* png natively treates 0 as black. This will convert for us */ png_set_invert_mono(png); /* write out each row in turn */ rowpointer = (png_bytep)image->data; for(i = 0; i < image->height; i++) { png_write_row(png, rowpointer); rowpointer += image->stride; } /* finish and clean up */ png_write_end(png, info); png_destroy_write_struct(&png, &info); return 0; }
/** * \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; }
// // WriteImage() // write an image to a file in PNG format // This version writes only a subpart of the image // void CImageIOPng::WriteImage(const CImage& image, CNcbiOstream& ostr, size_t x, size_t y, size_t w, size_t h, 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, w, h, 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 // we plan to march through only part of our image // get a pointer to the start of our scan line // // NB: the const cast is necessary as png_write_row takes a non-const // pointer (go figure...) unsigned char* from_data = const_cast<unsigned char*>(image.GetData()); from_data += (y * image.GetWidth() + x) * image.GetDepth(); size_t from_stride = w * image.GetDepth(); // march out h scan lines for (size_t i = 0; i < h; ++i) { png_write_row(png_ptr, from_data); from_data += from_stride; } // 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 encodePngIntoOutputStream( JNIEnv* env, DecodedImage& decoded_image, jobject os) { THROW_AND_RETURN_IF( decoded_image.getPixelFormat() != PixelFormat::RGBA, "png encode function expect ARGB pixel format"); png_structp png_ptr = png_create_write_struct( PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); THROW_AND_RETURN_IF(png_ptr == nullptr, "could not create png struct"); PngStructGuard png_guard{png_ptr}; png_infop info_ptr = png_create_info_struct(png_ptr); THROW_AND_RETURN_IF(info_ptr == nullptr, "could not create png info"); png_guard.setInfoPtr(info_ptr); PngOutputStreamWrapper os_wrapper{env, os}; RETURN_IF_EXCEPTION_PENDING; // Create all png structs that needs releasing before this line. if (setjmp(png_jmpbuf(png_ptr))) { safeThrowJavaException(env, jRuntimeException_class, "error encoding png"); return; } png_set_IHDR( png_ptr, info_ptr, decoded_image.getWidth(), decoded_image.getHeight(), 8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE ); png_set_write_fn( png_ptr, &os_wrapper, pngWriteToJavaOutputStream, pngNoOpFlush); // write the image const int row_stride = decoded_image.getStride(); png_bytep row_pointer = decoded_image.getPixelsPtr(); png_write_info(png_ptr, info_ptr); for (unsigned i = 0; i < decoded_image.getHeight(); ++i) { png_write_row(png_ptr, row_pointer); std::advance(row_pointer, row_stride); } png_write_end(png_ptr, info_ptr); }
bool PngWrite32bpp(sint32 width, sint32 height, const void * pixels, const utf8 * path) { bool result = false; // Setup PNG png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, PngError, PngWarning); if (png_ptr == nullptr) { return false; } png_infop info_ptr = png_create_info_struct(png_ptr); if (info_ptr == nullptr) { png_destroy_write_struct(&png_ptr, (png_infopp)nullptr); return false; } try { // Open file for writing auto fs = FileStream(path, FILE_MODE_WRITE); png_set_write_fn(png_ptr, &fs, PngWriteData, PngFlush); // Set error handler if (setjmp(png_jmpbuf(png_ptr))) { throw Exception("PNG ERROR"); } // Write header 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 ); png_write_info(png_ptr, info_ptr); // Write pixels uint8 * bits = (uint8 *)pixels; for (int y = 0; y < height; y++) { png_write_row(png_ptr, (png_byte *)bits); bits += width * 4; } // Finish png_write_end(png_ptr, nullptr); result = true; } catch (Exception) { } png_destroy_write_struct(&png_ptr, &info_ptr); return result; }
int writeImage(const char* filename, int width, int height, BGR *buffer, uint8_t *alpha, char *pimg) { int code = 0; FILE *fp = nullptr; png_structp png_ptr; png_infop info_ptr; // Open file for writing (binary mode) fp = fopen(filename, "wb"); // Initialize write structure png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); // Initialize info structure info_ptr = png_create_info_struct(png_ptr); png_init_io(png_ptr, fp); // Write header (8 bit colour depth) png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_text text; text.compression = PNG_TEXT_COMPRESSION_NONE; char buff[16]; strcpy(buff, "Comment"); text.key = buff; text.text = pimg; text.text_length = strlen(text.text); png_set_text(png_ptr, info_ptr, (png_const_textp)&text, 1); png_write_info(png_ptr, info_ptr); RGBA *data = new RGBA[width*height]; for (int i = 0; i < width*height; ++i) { data[i].a = alpha[i]; data[i].r = buffer[i].b; data[i].g = buffer[i].g; data[i].b = buffer[i].r; } // Write image data for (int y=0 ; y<height ; y++) { png_write_row(png_ptr, (uint8_t *)data + y*width*4); } png_write_end(png_ptr, NULL); if (fp != NULL) fclose(fp); if (info_ptr != NULL) png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); if (png_ptr != NULL) png_destroy_write_struct(&png_ptr, (png_infopp)NULL); delete[] data; return 0; }