#include #include #include "grib2.h" int enc_png(char *,g2int ,g2int ,g2int ,char *); void pngpack(g2float *fld,g2int width,g2int height,g2int *idrstmpl, unsigned char *cpack,g2int *lcpack) //$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: pngpack // PRGMMR: Gilbert ORG: W/NP11 DATE: 2003-08-27 // // ABSTRACT: This subroutine packs up a data field into PNG image format. // After the data field is scaled, and the reference value is subtracted out, // it is treated as a grayscale image and passed to a PNG encoder. // It also fills in GRIB2 Data Representation Template 5.41 or 5.40010 with // the appropriate values. // // PROGRAM HISTORY LOG: // 2003-08-27 Gilbert // // USAGE: pngpack(g2float *fld,g2int width,g2int height,g2int *idrstmpl, // unsigned char *cpack,g2int *lcpack); // INPUT ARGUMENT LIST: // fld[] - Contains the data values to pack // width - number of points in the x direction // height - number of points in the y direction // idrstmpl - Contains the array of values for Data Representation // Template 5.41 or 5.40010 // [0] = Reference value - ignored on input // [1] = Binary Scale Factor // [2] = Decimal Scale Factor // [3] = number of bits for each data value - ignored on input // [4] = Original field type - currently ignored on input // Data values assumed to be reals. // // OUTPUT ARGUMENT LIST: // idrstmpl - Contains the array of values for Data Representation // Template 5.41 or 5.40010 // [0] = Reference value - set by pngpack routine. // [1] = Binary Scale Factor - unchanged from input // [2] = Decimal Scale Factor - unchanged from input // [3] = Number of bits containing each grayscale pixel value // [4] = Original field type - currently set = 0 on output. // Data values assumed to be reals. // cpack - The packed data field // lcpack - length of packed field cpack. // // REMARKS: None // // ATTRIBUTES: // LANGUAGE: C // MACHINE: IBM SP // //$$$ { g2int *ifld; static g2float alog2=0.69314718; // ln(2.0) g2int j,nbits,imin,imax,maxdif; g2int ndpts,nbytes; g2float bscale,dscale,rmax,rmin,temp; unsigned char *ctemp; ifld=0; ndpts=width*height; bscale=int_power(2.0,-idrstmpl[1]); dscale=int_power(10.0,idrstmpl[2]); // // Find max and min values in the data // rmax=fld[0]; rmin=fld[0]; for (j=1;j rmax) rmax=fld[j]; if (fld[j] < rmin) rmin=fld[j]; } maxdif = (g2int)rint( (rmax-rmin)*dscale*bscale ); // // If max and min values are not equal, pack up field. // If they are equal, we have a constant field, and the reference // value (rmin) is the value for each point in the field and // set nbits to 0. // if (rmin != rmax && maxdif != 0 ) { ifld=(g2int *)malloc(ndpts*sizeof(g2int)); // // Determine which algorithm to use based on user-supplied // binary scale factor and number of bits. // if (idrstmpl[1] == 0) { // // No binary scaling and calculate minumum number of // bits in which the data will fit. // imin=(g2int)rint(rmin*dscale); imax=(g2int)rint(rmax*dscale); maxdif=imax-imin; temp=log((double)(maxdif+1))/alog2; nbits=(g2int)ceil(temp); rmin=(g2float)imin; // scale data for(j=0;j