Merge remote-tracking branch 'origin/release-v4.6.1'
[WRF.git] / external / io_grib2 / g2lib / dec_png.c
bloba33c0c0ac6b9348fe7a4521cff612f729966c506
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <png.h>
5 #include "proto.h"
7 #ifdef __64BIT__
8 typedef int g2int;
9 #else
10 typedef long g2int;
11 #endif
13 struct png_stream {
14 unsigned char *stream_ptr; /* location to write PNG stream */
15 g2int stream_len; /* number of bytes written */
17 typedef struct png_stream png_stream;
19 void user_read_data(png_structp , png_bytep , png_uint_32 );
21 void user_read_data(png_structp png_ptr,png_bytep data, png_uint_32 length)
23 Custom read function used so that libpng will read a PNG stream
24 from memory instead of a file on disk.
27 char *ptr;
28 g2int offset;
29 png_stream *mem;
31 mem=(png_stream *)png_get_io_ptr(png_ptr);
32 ptr=(void *)mem->stream_ptr;
33 offset=mem->stream_len;
34 /* printf("SAGrd %ld %ld %x\n",offset,length,ptr); */
35 memcpy(data,ptr+offset,length);
36 mem->stream_len += length;
41 int DEC_PNG(unsigned char *pngbuf,g2int *width,g2int *height,char *cout)
43 int interlace,color,compres,filter,bit_depth;
44 g2int j,k,n,bytes,clen;
45 png_structp png_ptr;
46 png_infop info_ptr,end_info;
47 png_bytepp row_pointers;
48 png_stream read_io_ptr;
50 /* check if stream is a valid PNG format */
52 if ( png_sig_cmp(pngbuf,0,8) != 0)
53 return (-3);
55 /* create and initialize png_structs */
57 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
58 NULL, NULL);
59 if (!png_ptr)
60 return (-1);
62 info_ptr = png_create_info_struct(png_ptr);
63 if (!info_ptr)
65 png_destroy_read_struct(&png_ptr,(png_infopp)NULL,(png_infopp)NULL);
66 return (-2);
69 end_info = png_create_info_struct(png_ptr);
70 if (!end_info)
72 png_destroy_read_struct(&png_ptr,(png_infopp)info_ptr,(png_infopp)NULL);
73 return (-2);
76 /* Set Error callback */
78 if (setjmp(png_jmpbuf(png_ptr)))
80 png_destroy_read_struct(&png_ptr, &info_ptr,&end_info);
81 return (-3);
84 /* Initialize info for reading PNG stream from memory */
86 read_io_ptr.stream_ptr=(png_voidp)pngbuf;
87 read_io_ptr.stream_len=0;
89 /* Set new custom read function */
91 png_set_read_fn(png_ptr,(png_voidp)&read_io_ptr,(png_rw_ptr)user_read_data);
92 /* png_init_io(png_ptr, fptr); */
94 /* Read and decode PNG stream */
96 png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
98 /* Get pointer to each row of image data */
100 row_pointers = png_get_rows(png_ptr, info_ptr);
102 /* Get image info, such as size, depth, colortype, etc... */
104 /*printf("SAGT:png %d %d %d\n",info_ptr->width,info_ptr->height,info_ptr->bit_depth);*/
105 (void)png_get_IHDR(png_ptr, info_ptr, (png_uint_32 *)width, (png_uint_32 *)height,
106 &bit_depth, &color, &interlace, &compres, &filter);
108 /* Check if image was grayscale */
111 if (color != PNG_COLOR_TYPE_GRAY ) {
112 fprintf(stderr,"dec_png: Grayscale image was expected. \n");
115 if ( color == PNG_COLOR_TYPE_RGB ) {
116 bit_depth=24;
118 else if ( color == PNG_COLOR_TYPE_RGB_ALPHA ) {
119 bit_depth=32;
121 /* Copy image data to output string */
123 n=0;
124 bytes=bit_depth/8;
125 clen=(*width)*bytes;
126 for (j=0;j<*height;j++) {
127 for (k=0;k<clen;k++) {
128 cout[n]=*(row_pointers[j]+k);
129 n++;
133 /* Clean up */
135 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
136 return 0;