Merge tag 'RELEASE-3-4' into wps-merge
[WPS-merge.git] / ungrib / src / ngl / g2 / dec_png.c
blob5a35879a0c265a51b0602c5ac7b112b1cd12eb58
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #ifdef USE_PNG
5 #include <png.h>
6 #endif /* USE_PNG */
8 #ifdef __64BIT__
9 typedef int g2int;
10 #else
11 typedef long g2int;
12 #endif
14 #if defined _UNDERSCORE
15 #define dec_png dec_png_
16 #elif defined _DOUBLEUNDERSCORE
17 #define dec_png dec_png__
18 #endif
20 #ifdef USE_PNG
21 struct png_stream {
22 unsigned char *stream_ptr; /* location to write PNG stream */
23 g2int stream_len; /* number of bytes written */
25 typedef struct png_stream png_stream;
27 void user_read_data(png_structp , png_bytep , png_uint_32 );
29 void user_read_data(png_structp png_ptr,png_bytep data, png_uint_32 length)
31 Custom read function used so that libpng will read a PNG stream
32 from memory instead of a file on disk.
35 char *ptr;
36 g2int offset;
37 png_stream *mem;
39 mem=(png_stream *)png_get_io_ptr(png_ptr);
40 ptr=(void *)mem->stream_ptr;
41 offset=mem->stream_len;
42 /* printf("SAGrd %ld %ld %x\n",offset,length,ptr); */
43 memcpy(data,ptr+offset,length);
44 mem->stream_len += length;
46 #endif /* USE_PNG */
50 int dec_png(unsigned char *pngbuf,g2int *width,g2int *height,char *cout)
52 #ifdef USE_PNG
53 int interlace,color,compres,filter,bit_depth;
54 g2int j,k,n,bytes,clen;
55 png_structp png_ptr;
56 png_infop info_ptr,end_info;
57 png_bytepp row_pointers;
58 png_stream read_io_ptr;
59 png_uint_32 h32, w32;
61 /* check if stream is a valid PNG format */
63 if ( png_sig_cmp(pngbuf,0,8) != 0)
64 return (-3);
66 /* create and initialize png_structs */
68 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
69 NULL, NULL);
70 if (!png_ptr)
71 return (-1);
73 info_ptr = png_create_info_struct(png_ptr);
74 if (!info_ptr)
76 png_destroy_read_struct(&png_ptr,(png_infopp)NULL,(png_infopp)NULL);
77 return (-2);
80 end_info = png_create_info_struct(png_ptr);
81 if (!end_info)
83 png_destroy_read_struct(&png_ptr,(png_infopp)info_ptr,(png_infopp)NULL);
84 return (-2);
87 /* Set Error callback */
89 if (setjmp(png_jmpbuf(png_ptr)))
91 png_destroy_read_struct(&png_ptr, &info_ptr,&end_info);
92 return (-3);
95 /* Initialize info for reading PNG stream from memory */
97 read_io_ptr.stream_ptr=(png_voidp)pngbuf;
98 read_io_ptr.stream_len=0;
100 /* Set new custom read function */
102 png_set_read_fn(png_ptr,(png_voidp)&read_io_ptr,(png_rw_ptr)user_read_data);
103 /* png_init_io(png_ptr, fptr); */
105 /* Read and decode PNG stream */
107 png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
109 /* Get pointer to each row of image data */
111 row_pointers = png_get_rows(png_ptr, info_ptr);
113 /* Get image info, such as size, depth, colortype, etc... */
115 /*printf("SAGT:png %d %d %d\n",info_ptr->width,info_ptr->height,info_ptr->bit_depth);*/
116 /* (void)png_get_IHDR(png_ptr, info_ptr, (png_uint_32 *)width, (png_uint_32 *)height,
117 &bit_depth, &color, &interlace, &compres, &filter);*/
118 (void)png_get_IHDR(png_ptr, info_ptr, &w32, &h32,
119 &bit_depth, &color, &interlace, &compres, &filter);
121 *height = h32;
122 *width = w32;
124 /* Check if image was grayscale */
127 if (color != PNG_COLOR_TYPE_GRAY ) {
128 fprintf(stderr,"dec_png: Grayscale image was expected. \n");
131 if ( color == PNG_COLOR_TYPE_RGB ) {
132 bit_depth=24;
134 else if ( color == PNG_COLOR_TYPE_RGB_ALPHA ) {
135 bit_depth=32;
137 /* Copy image data to output string */
139 n=0;
140 bytes=bit_depth/8;
141 clen=(*width)*bytes;
142 for (j=0;j<*height;j++) {
143 for (k=0;k<clen;k++) {
144 cout[n]=*(row_pointers[j]+k);
145 n++;
149 /* Clean up */
151 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
152 #endif /* USE_PNG */
153 return 0;