/*!
* pixWriteStreamPng()
*
* Input: stream
* pix
* gamma (use 0.0 if gamma is not defined)
* Return: 0 if OK; 1 on error
*
* Notes:
* (1) If called from pixWriteStream(), the stream is positioned
* at the beginning of the file.
* (2) To do sequential writes of png format images to a stream,
* use pixWriteStreamPng() directly.
* (3) gamma is an optional png chunk. If no gamma value is to be
* placed into the file, use gamma = 0.0. Otherwise, if
* gamma > 0.0, its value is written into the header.
* (4) The use of gamma in png is highly problematic. For an illuminating
* discussion, see: http://hsivonen.iki.fi/png-gamma/
* (5) What is the effect/meaning of gamma in the png file? This
* gamma, which we can call the 'source' gamma, is the
* inverse of the gamma that was used in enhance.c to brighten
* or darken images. The 'source' gamma is supposed to indicate
* the intensity mapping that was done at the time the
* image was captured. Display programs typically apply a
* 'display' gamma of 2.2 to the output, which is intended
* to linearize the intensity based on the response of
* thermionic tubes (CRTs). Flat panel LCDs have typically
* been designed to give a similar response as CRTs (call it
* "backward compatibility"). The 'display' gamma is
* in some sense the inverse of the 'source' gamma.
* jpeg encoders attached to scanners and cameras will lighten
* the pixels, applying a gamma corresponding to approximately
* a square-root relation of output vs input:
* output = input^(gamma)
* where gamma is often set near 0.4545 (1/gamma is 2.2).
* This is stored in the image file. Then if the display
* program reads the gamma, it will apply a display gamma,
* typically about 2.2; the product is 1.0, and the
* display program produces a linear output. This works because
* the dark colors were appropriately boosted by the scanner,
* as described by the 'source' gamma, so they should not
* be further boosted by the display program.
* (6) As an example, with xv and display, if no gamma is stored,
* the program acts as if gamma were 0.4545, multiplies this by 2.2,
* and does a linear rendering. Taking this as a baseline
* brightness, if the stored gamma is:
* > 0.4545, the image is rendered lighter than baseline
* < 0.4545, the image is rendered darker than baseline
* In contrast, gqview seems to ignore the gamma chunk in png.
* (7) The only valid pixel depths in leptonica are 1, 2, 4, 8, 16
* and 32. However, it is possible, and in some cases desirable,
* to write out a png file using an rgb pix that has 24 bpp.
* For example, the open source xpdf SplashBitmap class generates
* 24 bpp rgb images. Consequently, we anble writing 24 bpp pix.
* To generate such a pix, you can make a 24 bpp pix without data
* and assign the data array to the pix; e.g.,
* pix = pixCreateHeader(w, h, 24);
* pixSetData(pix, rgbdata);
* See pixConvert32To24() for an example, where we get rgbdata
* from the 32 bpp pix. Caution: do not call pixSetPadBits(),
* because the alignment is wrong and you may erase part of the
* last pixel on each line.
*/
l_int32
pixWriteStreamPng(FILE *fp,
PIX *pix,
l_float32 gamma)
{
char commentstring[] = "Comment";
l_int32 i, j, k;
l_int32 wpl, d, cmflag;
l_int32 ncolors;
l_int32 *rmap, *gmap, *bmap;
l_uint32 *data, *ppixel;
png_byte bit_depth, color_type;
png_uint_32 w, h;
png_uint_32 xres, yres;
png_bytep *row_pointers;
png_bytep rowbuffer;
png_structp png_ptr;
png_infop info_ptr;
png_colorp palette;
PIX *pixt;
PIXCMAP *cmap;
char *text;
PROCNAME("pixWriteStreamPng");
if (!fp)
return ERROR_INT("stream not open", procName, 1);
if (!pix)
return ERROR_INT("pix not defined", procName, 1);
/* Allocate the 2 data structures */
if ((png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
(png_voidp)NULL, NULL, NULL)) == NULL)
return ERROR_INT("png_ptr not made", procName, 1);
if ((info_ptr = png_create_info_struct(png_ptr)) == NULL) {
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
//.........这里部分代码省略.........
/**
* @short Writes an image as png to the response object
*
* @param image flat buffer with all pixels
* @param Bpp Bytes per pixel: 1 grayscale, 2 grayscale with alpha, 3 RGB, 4 RGB with alpha. Negative if in BGR format (cairo)
* @param width The width of the image
* @param height The height of the image
* @param res where to write the image, it sets the necessary structs
*/
int onion_png_response(unsigned char *image, int Bpp, int width, int height, onion_response *res){
// Many copied from example.c from libpng source code.
png_structp png_ptr;
png_infop info_ptr;
/* Create and initialize the png_struct with the desired error handler
* functions. If you want to use the default stderr and longjump method,
* you can supply NULL for the last three parameters. We also check that
* the library version is compatible with the one used at compile time,
* in case we are using dynamically linked libraries. REQUIRED.
*/
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, error, warning);
if (png_ptr == NULL)
{
return OCS_INTERNAL_ERROR;
}
/* Allocate/initialize the image information data. REQUIRED */
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL)
{
png_destroy_write_struct(&png_ptr, NULL);
return OCS_INTERNAL_ERROR;
}
onion_png_data opd;
opd.res=res;
opd.sent=0;
png_set_write_fn(png_ptr, (void *)&opd, onion_png_write, onion_png_flush);
/* where user_io_ptr is a structure you want available to the callbacks */
onion_response_set_header(res, "Content-Type", "image/png");
if (onion_response_write_headers(res)==OR_SKIP_CONTENT) // Maybe it was HEAD.
return OCS_PROCESSED;
/* Set the image information here. Width and height are up to 2^31,
* bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
* the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
* PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
* or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or
* PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
* currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED
*/
if (Bpp<0){
png_set_bgr(png_ptr);
Bpp=-Bpp;
}
switch(Bpp){
case 1:
png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_GRAY,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
break;
case 2:
png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_GRAY_ALPHA,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
break;
case 3:
png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
break;
case 4:
png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB_ALPHA,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
break;
default:
png_error(png_ptr, "Wrong bytes per pixel");
break;
}
png_uint_32 k;
png_bytep row_pointers[height];
if (height > PNG_UINT_32_MAX/png_sizeof(png_bytep))
png_error (png_ptr, "Image is too tall to process in memory");
for (k = 0; k < height; k++)
row_pointers[k] = (png_byte *) (image + k*width*Bpp);
// Sets the rows to save at the image
png_set_rows(png_ptr, info_ptr, row_pointers);
// If header already sent, then there was an error.
if (opd.sent){
return OCS_PROCESSED;
}
opd.sent=1;
// Finally WRITE the image. Uses the onion_response_write via onion_png_write helper.
png_write_png(png_ptr, info_ptr, 0, NULL);
//.........这里部分代码省略.........
开发者ID:IPInfusion,项目名称:SDN-IP,代码行数:101,代码来源:png.c
示例4: RE_SavePNG
int RE_SavePNG( const char *filename, byte *buf, size_t width, size_t height, int byteDepth ) {
fileHandle_t fp;
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
unsigned int x, y;
png_byte ** row_pointers = NULL;
/* "status" contains the return value of this function. At first
it is set to a value which means 'failure'. When the routine
has finished its work, it is set to a value which means
'success'. */
int status = -1;
/* The following number is set by trial and error only. I cannot
see where it it is documented in the libpng manual.
*/
int depth = 8;
fp = ri->FS_FOpenFileWrite( filename, qtrue );
if ( !fp ) {
goto fopen_failed;
}
png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (png_ptr == NULL) {
goto png_create_write_struct_failed;
}
info_ptr = png_create_info_struct (png_ptr);
if (info_ptr == NULL) {
goto png_create_info_struct_failed;
}
/* Set up error handling. */
if (setjmp (png_jmpbuf (png_ptr))) {
goto png_failure;
}
/* Set image attributes. */
png_set_IHDR (png_ptr,
info_ptr,
width,
height,
depth,
PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT);
/* Initialize rows of PNG. */
row_pointers = (png_byte **)png_malloc (png_ptr, height * sizeof (png_byte *));
for ( y=0; y<height; ++y ) {
png_byte *row = (png_byte *)png_malloc (png_ptr, sizeof (uint8_t) * width * byteDepth);
row_pointers[height-y-1] = row;
for (x = 0; x < width; ++x) {
byte *px = buf + (width * y + x)*3;
*row++ = px[0];
*row++ = px[1];
*row++ = px[2];
}
}
/* Write the image data to "fp". */
// png_init_io (png_ptr, fp);
png_set_write_fn( png_ptr, (png_voidp)&fp, user_write_data, user_flush_data );
png_set_rows (png_ptr, info_ptr, row_pointers);
png_write_png (png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
/* The routine has successfully written the file, so we set
"status" to a value which indicates success. */
status = 0;
for (y = 0; y < height; y++) {
png_free (png_ptr, row_pointers[y]);
}
png_free (png_ptr, row_pointers);
png_failure:
png_create_info_struct_failed:
png_destroy_write_struct (&png_ptr, &info_ptr);
png_create_write_struct_failed:
ri->FS_FCloseFile( fp );
fopen_failed:
return status;
}
static int
_store_picture_to_buffer_png(int width, int height,BYTE *prgb_data,
guint8 **data, guint *data_len)
{
int l=0;
//FILE *fp;
guint8 *png_buff = g_new0(BYTE, width*height*3);
png_structp png_ptr;
png_infop info_ptr;
png_text text_ptr[3];
png_bytep row_pointers[height];
/* open the file */
// fp = fopen(file_name, "wb");
// if (fp == NULL)
// return (1);
/* Create and initialize the png_struct with the desired error handler
* functions. If you want to use the default stderr and longjump method,
* you can supply NULL for the last three parameters. We also check that
* the library version is compatible with the one used at compile time,
* in case we are using dynamically linked libraries.
*/
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
NULL, NULL, NULL);
if (png_ptr == NULL)
{
//fclose(fp);
g_free(png_buff);
return (2);
}
/* Allocate/initialize the image information data. */
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL)
{
//fclose(fp);
g_free(png_buff);
png_destroy_write_struct(&png_ptr, NULL);
return (3);
}
/* Set error handling. REQUIRED if you aren't supplying your own
* error handling functions in the png_create_write_struct() call.
*/
if (setjmp(png_jmpbuf(png_ptr)))
{
/* If we get here, we had a problem reading the file */
//fclose(fp);
g_free(png_buff);
png_destroy_write_struct(&png_ptr, &info_ptr);
return (4);
}
/* set up the output control using standard C streams */
//png_init_io(png_ptr, fp);
_png_current_write_position = png_buff;
voidp write_io_ptr = png_get_io_ptr(png_ptr);
png_set_write_fn(png_ptr,
write_io_ptr,
_png_mem_write_data,
_png_mem_flush_data);
/* turn on or off filtering, and/or choose
specific filters. You can use either a single
PNG_FILTER_VALUE_NAME or the bitwise OR of one
or more PNG_FILTER_NAME masks. */
/* png_set_filter(png_ptr, 0,
PNG_FILTER_NONE | PNG_FILTER_VALUE_NONE |
PNG_FILTER_SUB | PNG_FILTER_VALUE_SUB |
PNG_FILTER_UP | PNG_FILTER_VALUE_UP |
PNG_FILTER_AVE | PNG_FILTER_VALUE_AVE |
PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH|
PNG_ALL_FILTERS);*/
/* set the zlib compression level */
//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_compression_buffer_size(png_ptr, 8192);
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);
/* Optional gamma chunk is strongly suggested if you have any guess
* as to the correct gamma of the image.
*/
//png_set_gAMA(png_ptr, info_ptr, gamma);
/* Optionally write comments into the image */
text_ptr[0].key = "Title";
//text_ptr[0].text = file_name;
//.........这里部分代码省略.........
请发表评论