LCOV - code coverage report
Current view: top level - frmts/grib/degrib/g2clib - dec_png.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 40 65 61.5 %
Date: 2024-05-06 11:10:03 Functions: 2 2 100.0 %

          Line data    Source code
       1             : #include "grib2.h"
       2             : #ifndef USE_PNG
       3             : int dec_png(unsigned char *pngbuf,g2int len,g2int *width,g2int *height,unsigned char *cout, g2int ndpts, g2int nbits){return 0;}
       4             : #else   /* USE_PNG */
       5             : #include <stdio.h>
       6             : #include <stdlib.h>
       7             : #include <string.h>
       8             : #include <limits.h>
       9             : #include <png.h>
      10             : 
      11             : 
      12             : struct png_stream {
      13             :    unsigned char *stream_ptr;     /*  location to write PNG stream  */
      14             :    g2int stream_len;               /*  number of bytes written       */
      15             :    g2int stream_total_len;
      16             : };
      17             : typedef struct png_stream png_stream;
      18             : 
      19         129 : static void user_read_data(png_structp png_ptr,png_bytep data, png_size_t length)
      20             : /*
      21             :         Custom read function used so that libpng will read a PNG stream
      22             :         from memory instead of a file on disk.
      23             : */
      24             : {
      25             :      char *ptr;
      26             :      g2int offset;
      27             :      png_stream *mem;
      28             : 
      29         129 :      mem=(png_stream *)png_get_io_ptr(png_ptr);
      30         129 :      if( (g2int)length + mem->stream_len > mem->stream_total_len )
      31             :      {
      32           0 :         jmp_buf* psSetJmpContext = (jmp_buf *)png_get_error_ptr( png_ptr );
      33           0 :         if (psSetJmpContext)
      34           0 :             longjmp( *psSetJmpContext, 1 );
      35             :      }
      36             :      else
      37             :      {
      38         129 :         ptr=(void *)mem->stream_ptr;
      39         129 :         offset=mem->stream_len;
      40             :     /*     printf("SAGrd %ld %ld %x\n",offset,length,ptr);  */
      41         129 :         memcpy(data,ptr+offset,length);
      42         129 :         mem->stream_len += (g2int)length;
      43             :      }
      44         129 : }
      45             : 
      46             : 
      47             : 
      48          14 : int dec_png(unsigned char *pngbuf,g2int len,g2int *width,g2int *height,unsigned char *cout, g2int ndpts, g2int nbits)
      49             : {
      50             :     int interlace,color,l_compress,filter,bit_depth;
      51             :     g2int j,k,n,bytes,clen;
      52             :     png_structp png_ptr;
      53             :     png_infop info_ptr,end_info;
      54             :     png_bytepp row_pointers;
      55             :     png_stream read_io_ptr;
      56             :     png_uint_32 u_width;
      57             :     png_uint_32 u_height;
      58             : 
      59             : /*  check if stream is a valid PNG format   */
      60             : 
      61          14 :     if ( len < 8 || png_sig_cmp(pngbuf,0,8) != 0)
      62           0 :        return (-3);
      63             : 
      64             : /* create and initialize png_structs  */
      65             : 
      66          14 :     png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
      67             :                                       NULL, NULL);
      68          14 :     if (!png_ptr)
      69           0 :        return (-1);
      70             : 
      71          14 :     info_ptr = png_create_info_struct(png_ptr);
      72          14 :     if (!info_ptr)
      73             :     {
      74           0 :        png_destroy_read_struct(&png_ptr,(png_infopp)NULL,(png_infopp)NULL);
      75           0 :        return (-2);
      76             :     }
      77             : 
      78          14 :     end_info = png_create_info_struct(png_ptr);
      79          14 :     if (!end_info)
      80             :     {
      81           0 :        png_destroy_read_struct(&png_ptr,(png_infopp)info_ptr,(png_infopp)NULL);
      82           0 :        return (-2);
      83             :     }
      84             : 
      85             : /*     Set Error callback   */
      86             : 
      87          14 :     if (setjmp(png_jmpbuf(png_ptr)))
      88             :     {
      89           0 :        png_destroy_read_struct(&png_ptr, &info_ptr,&end_info);
      90           0 :        return (-3);
      91             :     }
      92             : 
      93             : /*    Initialize info for reading PNG stream from memory   */
      94             : 
      95          14 :     read_io_ptr.stream_ptr=(png_voidp)pngbuf;
      96          14 :     read_io_ptr.stream_len=0;
      97          14 :     read_io_ptr.stream_total_len = len;
      98             : 
      99             : /*    Set new custom read function    */
     100             : 
     101          14 :     png_set_read_fn(png_ptr,(png_voidp)&read_io_ptr,(png_rw_ptr)user_read_data);
     102             : /*     png_init_io(png_ptr, fptr);   */
     103             : 
     104             : /*     Read and decode PNG stream   */
     105             : 
     106          14 :     png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
     107             : 
     108             : /*     Get pointer to each row of image data   */
     109             : 
     110          14 :     row_pointers = png_get_rows(png_ptr, info_ptr);
     111             : 
     112             : /*     Get image info, such as size, depth, colortype, etc...   */
     113             : 
     114             :     /*printf("SAGT:png %d %d %d\n",info_ptr->width,info_ptr->height,info_ptr->bit_depth);*/
     115          14 :     if( !png_get_IHDR(png_ptr, info_ptr, &u_width, &u_height,
     116             :                &bit_depth, &color, &interlace, &l_compress, &filter) )
     117             :     {
     118           0 :         fprintf(stderr, "png_get_IHDR() failed\n");
     119           0 :         png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
     120           0 :         return( -4 );
     121             :     }
     122          14 :     if( u_width > (unsigned)INT_MAX || u_height > (unsigned)INT_MAX )
     123             :     {
     124           0 :         fprintf(stderr, "invalid width/height\n");
     125           0 :         png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
     126           0 :         return( -5 );
     127             :     }
     128          14 :     *width = (g2int) u_width;
     129          14 :     *height = (g2int) u_height;
     130          14 :     if( (*width) * (*height) != ndpts )
     131             :     {
     132           0 :         fprintf(stderr, "invalid width/height\n");
     133           0 :         png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
     134           0 :         return( -6 );
     135             :     }
     136             : 
     137             : /*     Check if image was grayscale      */
     138             : 
     139             : /*
     140             :     if (color != PNG_COLOR_TYPE_GRAY ) {
     141             :        fprintf(stderr,"dec_png: Grayscale image was expected. \n");
     142             :     }
     143             : */
     144          14 :     if ( color == PNG_COLOR_TYPE_RGB ) {
     145           0 :        bit_depth=24;
     146             :     }
     147          14 :     else if ( color == PNG_COLOR_TYPE_RGB_ALPHA ) {
     148           0 :        bit_depth=32;
     149             :     }
     150          14 :     if( bit_depth != nbits )
     151             :     {
     152           0 :         fprintf(stderr, "inconsistent PNG bit depth\n");
     153           0 :         png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
     154           0 :         return( -7 );
     155             :     }
     156             : /*     Copy image data to output string   */
     157             : 
     158          14 :     n=0;
     159          14 :     bytes=bit_depth/8;
     160          14 :     clen=(*width)*bytes;
     161        1738 :     for (j=0;j<*height;j++) {
     162     9004940 :       for (k=0;k<clen;k++) {
     163     9003210 :         cout[n]=*(row_pointers[j]+k);
     164     9003210 :         n++;
     165             :       }
     166             :     }
     167             : 
     168             : /*      Clean up   */
     169             : 
     170          14 :     png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
     171          14 :     return 0;
     172             : 
     173             : }
     174             : 
     175             : #endif   /* USE_PNG */

Generated by: LCOV version 1.14