int main(int argc, char **argv) { png_t *png = png_read(argv[1]); if (!png) { printf("Invalid png.\n"); exit(1); } png_print_information(png); gui_display_image(png); exit(0); }
void Record(bool toStop, int last) { unsigned char *rgb = (unsigned char*)malloc(w * h * 3); for(int y = 0 ; y < ImageHeight ; y++) { for(int x = 0 ; x < ImageWidth ; x++) { int Ofs = y * ImageWidth + x; rgb[ Ofs * 3 + 0 ] = CamImg[ImageWidth*ImageHeight*3 - 1 - (Ofs * 3 + 2)]; rgb[ Ofs * 3 + 1 ] = CamImg[ImageWidth*ImageHeight*3 - 1 - (Ofs * 3 + 1)]; rgb[ Ofs * 3 + 2 ] = CamImg[ImageWidth*ImageHeight*3 - 1 - (Ofs * 3 + 0)]; } } unsigned char *yuv; png_read(rgb, &yuv); if(theora_write_frame(yuv, last)) { fprintf(stderr,"Encoding error.\n"); exit(1); } free(yuv); free(rgb); RECORD = !toStop; }
Image* open_image(const std::string& filename) { Image* image = new Image; memset(image, 0, sizeof(Image)); int error = 0; char bit_depth = 0; std::string ext = get_extension(filename); if (ext.length() == 0) { error = 10; } if (ext == "jpg" || ext == "jpeg") { image->buffer = jpeg_read(filename, image->width, image->height, error); } if (ext == "png") { image->buffer = png_read(filename, image->width, image->height, bit_depth, error); image->type = IMAGE_TYPE::PNG; } if (ext == "exr") { error = 5; } if (error) { delete image; return NULL; } return image; }
void Texture2D::readPng(const string& fullpath){ png_data_t png_data; if(!png_read(fullpath.c_str(),&png_data)) { _width = png_data.width; _height = png_data.height; _pixelFormat = png_data.format; glGenTextures(1,&_textureId); glBindTexture(GL_TEXTURE_2D,_textureId); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); glTexImage2D(GL_TEXTURE_2D,0, GL_RGBA, png_data.width,png_data.height,0, GL_RGBA,GL_UNSIGNED_BYTE,png_data.data); free(png_data.data); } }
bool png_image::load( std::istream & stream, uint32_t flags ) { uint32_t format = png_read_stream_format( stream ); if (format == PNG_FORMAT_INVALID) { pngio_error( "Not a valid PNG file." ); return 0; } #ifdef PNG_APPLE_MODE_SUPPORTED png_set_apple_mode( format == PNG_FORMAT_APPLE ); #endif png_structp readPtr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL ); if (!readPtr) { pngio_error( "Couldn't initialize PNG read struct." ); return 0; } png_set_read_fn( readPtr, (png_voidp) & stream, png_read_stream_data ); return png_read( readPtr, this, flags ); }
uint8_t png_image_load( png_image * image, FILE * file, uint32_t flags ) { uint32_t format = png_read_file_format( file ); if (format == PNG_FORMAT_INVALID) { pngio_error( "Not a valid PNG file." ); return 0; } #ifdef PNG_APPLE_MODE_SUPPORTED png_set_apple_mode( format == PNG_FORMAT_APPLE ); #endif png_structp readPtr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL ); if (!readPtr) { pngio_error( "Couldn't initialize PNG read struct." ); return 0; } png_set_read_fn( readPtr, (png_voidp) file, png_read_file_data ); return png_read( readPtr, image, flags ); }
void crarea ( char *imgnam, int *iret ) /************************************************************************ * crarea * * * * This subroutine reads the image data from a MCIDAS AREA file. * * The full image is placed in memory pointed to by imgData. * * * * crarea ( imgnam, iret ) * * * * Input parameters: * * *imgnam char Name of image file * * * * Output parameters: * * *iret int Return code * * G_NORMAL = normal return * * G_NIDSIZ = invalid image depth * * G_NIMGFL = cannot open/read img * * G_NMEMRY = memory alloc failure * ** * * Log: * * J. Cowie/COMET 3/95 * * J. Cowie/COMET 5/95 Modified to work with NAWIPS 5.2.1 * * S. Jacobs/NCEP 1/97 Copied from XRAREA * * J. Cowie/COMET 1/97 Changed common variable names * * J. Cowie/COMET 12/97 Added cfl_clos if error on cfl_seek * * S. Chiswell/Unidata 8/06 Added multibyte image check * ***********************************************************************/ { FILE *fp; char defdir[12]; long lofset; unsigned int iboff; int lstrt, ii, jj, kk, nbin, ier; unsigned char *rwdptr, *imdptr, buf[8]; int isPNG = 0; /*---------------------------------------------------------------------*/ if ( imdpth <= 0 ) { *iret = G_NIDSIZ; return; } /* * Open the file and seek to data offset. */ defdir[0] = CHNULL; fp = cfl_ropn ( imgnam, defdir, &ier ); if ( ier != 0 ) { *iret = G_NIMGFL; return; } else { lofset = (long) imdoff; cfl_seek ( fp, lofset, SEEK_SET, &ier ); if ( ier != 0 ) { cfl_clos ( fp, &ier ); *iret = G_NIMGFL; return; } /* See if this is a png compressed AREA file */ cfl_read ( fp, 8, buf, &nbin, &ier); if ( ( *iret == 0 ) && ( nbin == 8 ) ) { /* ** Check PNG magic word (8 first bytes): ** http://www.libpng.org/pub/png/spec/1.2/PNG-Rationale.html ** decimal - 137 80 78 71 13 10 26 10 ** hexadecimal - 89 50 4e 47 0d 0a 1a 0a ** ASCII - \211 P N G \r \n \032 \n */ if ( buf[0] == (unsigned char)137 && buf[1] == (unsigned char) 80 && buf[2] == (unsigned char) 78 && buf[3] == (unsigned char) 71 && buf[4] == (unsigned char) 13 && buf[5] == (unsigned char) 10 && buf[6] == (unsigned char) 26 && buf[7] == (unsigned char) 10 ) { isPNG = 1; } } cfl_seek ( fp, lofset, SEEK_SET, &ier ); } *iret = G_NORMAL; /* * If this file contains only one channel (band) and no line * prefix data, read the raw data directly into imgData and exit. */ if ( imprsz == 0 && imnchl == 1 ) { if ( isPNG ) png_read ( fp, imnpix, imnlin, imgData, &ier ); else cfl_read ( fp, imldat, imgData, &nbin, &ier ); cfl_clos ( fp, &ier ); crarea_pixel ( imgData ); return; } else { /* * Allocate space for the raw image data. */ if ( ( rawData == (unsigned char *) NULL ) || ( imldat > (int)last_rawsize) ) { if ( rawData != (unsigned char *) NULL) { free(rawData); } rawData = (unsigned char *) calloc ( imldat, sizeof(unsigned char) ); if ( rawData == (unsigned char *) NULL ) { *iret = G_NMEMRY; return; } last_rawsize = imldat; } /* * Read the raw image data. */ if ( isPNG ) png_read ( fp, imnpix, imnlin, imgData, &ier ); else cfl_read ( fp, imldat, rawData, &nbin, &ier ); cfl_clos ( fp, &ier ); } /* * Process the prefix bytes and move data for the * image channel into the imgData array. * * NOTE: This has been tested for images with prefix bytes. * Have not tested any image files with multiple channels * in the file. */ imdptr = imgData; for ( ii = 0; ii < imnlin; ii++ ) { /* * Calculate the starting byte in rawData for this line. */ lstrt = ii * (imnpix * imdpth * imnchl + imprsz); rwdptr = &rawData[lstrt]; /* * Process prefix data to each line, if any. * iboff = band offset in each element. */ iboff = 0; if ( imprsz != 0 ) { /* * Skip 4 bytes of validity code. */ if ( imvald != 0 ) rwdptr += 4; /* * Skip documentation and calibration code. */ rwdptr += imdcsz + imclsz; /* * Process level map to get the band for each element, * if necessary. */ if ( imnchl > 1) { /* * Get the band offset. */ for ( kk = 0; kk < imlvsz; kk ++ ) { if ( *rawData == 8 ) { iboff = kk; rwdptr += imlvsz - kk; break; } else { rwdptr ++; } } } else { /* * Skip the level map. */ rwdptr += imlvsz; } } /* End of "if ( imprsz != 0 )" */ /* * Get the image data. */ for ( jj = 0; jj < imnpix; jj++ ) { for ( kk = 0; kk < imdpth; kk++ ) { *imdptr++ = *(rwdptr + iboff); rwdptr ++; } } } /* End of loop over imnlin */ crarea_pixel ( imgData ); }
void initView() { glClearColor(0,0,0,1); glViewport(0,0,VIEW_W,VIEW_H); GLuint vbos[numVBOs]; glGenBuffers(numVBOs,vbos); glBindBuffer(GL_ARRAY_BUFFER,vbos[vertex]); int vSize = num_jewels * 16 * sizeof(GLfloat); vertices = (GLfloat*)malloc(vSize); memset(vertices,0,vSize); int iSize = num_jewels * 6 * sizeof(GLushort); indices = (GLushort*)malloc(iSize); memset(indices,0,iSize); dragXs = (float*) malloc(num_jewels * sizeof(float)); dragYs = (float*) malloc(num_jewels * sizeof(float)); // glBufferData(GL_ARRAY_BUFFER,4*4*sizeof(GLfloat),vertices,GL_STATIC_DRAW); memset(dragXs,0,num_jewels * sizeof(float)); memset(dragYs,0,num_jewels * sizeof(float)); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,vbos[index]); // glBufferData(GL_ELEMENT_ARRAY_BUFFER,6*sizeof(GLushort),indices,GL_STATIC_DRAW); glVertexAttribPointer(a_postion,2,GL_FLOAT,GL_FALSE,4*sizeof(GLfloat),BUFFER_OFFSET(0)); glEnableVertexAttribArray(a_postion); glVertexAttribPointer(a_texCoord,2,GL_FLOAT,GL_FALSE,4*sizeof(GLfloat),BUFFER_OFFSET(2)); glEnableVertexAttribArray(a_texCoord); GLuint vShader = glCreateShader(GL_VERTEX_SHADER); GLuint fShader = glCreateShader(GL_FRAGMENT_SHADER); const char* vSrc = t_read("jewel.vert"); const char* fSrc = t_read("jewel.frag"); glShaderSource(vShader,1,&vSrc,0); glShaderSource(fShader,1,&fSrc,0); glCompileShader(vShader); glCompileShader(fShader); GLint vStatus,fStatus; glGetShaderiv(vShader,GL_COMPILE_STATUS,&vStatus); glGetShaderiv(fShader,GL_COMPILE_STATUS,&fStatus); if(!vStatus) { GLint infoLen; char* infoLog; glGetShaderiv(vShader,GL_INFO_LOG_LENGTH,&infoLen); infoLog = (char*) malloc(infoLen); glGetShaderInfoLog(vShader,infoLen,NULL,infoLog); printf("vertex shader compile error:%s\n",infoLog); free(infoLog); } if(!fStatus) { GLint infoLen; char* infoLog; glGetShaderiv(fShader,GL_INFO_LOG_LENGTH,&infoLen); infoLog = (char*) malloc(infoLen); glGetShaderInfoLog(fShader,infoLen,NULL,infoLog); printf("fragment shader compile error:%s\n",infoLog); free(infoLog); } GLuint program = glCreateProgram(); glAttachShader(program,vShader); glAttachShader(program,fShader); glBindAttribLocation(program,a_postion,"a_position"); glBindAttribLocation(program,a_texCoord,"a_texCoord"); glLinkProgram(program); GLint pStatus; glGetProgramiv(program,GL_LINK_STATUS,&pStatus); if(!pStatus) { GLint infoLen; char* infoLog; glGetProgramiv(program,GL_INFO_LOG_LENGTH,&infoLen); infoLog = (char*) malloc(infoLen); glGetProgramInfoLog(program,infoLen,NULL,infoLog); printf("program link error:%s\n"); free(infoLog); } glUseProgram(program); GLint mvpLoc = glGetUniformLocation(program,"u_mvp"); GLfloat mvp[] = { 2.0/VIEW_W, 0.0, 0.0, 0.0, 0.0, -2.0/VIEW_H, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 1.0, 0.0, 1.0 }; glUniformMatrix4fv(mvpLoc,1,GL_FALSE,mvp); GLuint textures[numTexs]; glGenTextures(numTexs,textures); glBindTexture(GL_TEXTURE_2D,textures[s_popo]); png_data_t png_data; if(!png_read("./Data/Jewels.png",&png_data)) { glTexImage2D(GL_TEXTURE_2D,0, GL_RGBA, png_data.width,png_data.height,0, GL_RGBA,GL_UNSIGNED_BYTE,png_data.data); free(png_data.data); } glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); glPixelStorei(GL_PACK_ALIGNMENT, 1); GLint sampleLoc = glGetUniformLocation(program,"s_texture"); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,textures[s_popo]); glUniform1i(sampleLoc,0); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE); }
int bm3d (char* const infile, // name of input file char* const kind, // kind of shrinkage (ht, wnr, avg) int const block_size, // size of internal processed blocks int const block_step, // step size between blocks int const sigma, // standard deviation of noise int const max_blocks, // maximum number of block in one 3D array int const h_search, // horizontal width of search window int const v_search, // vertical width of search window double const th_2d, // threshold for the 2D transformation double const tau_match, // match value for block-matching double const th_3d, // threshold for the 3D transformtaion int const block_marking) { // indicates the action of block marking png_img img; // noisy input image png_img org; // temporary image for marking the blocks FILE* log = 0; // log-file for all kinds of messages char logfile[30]; // name of the log-file including path char path[30]; // universally used path-name char prefix[20]; // universally used prefix-name char pure_name[30]; int h_search_true; // true value of horizontal search window size after validation int v_search_true; // true value of vertical search window size after validation list_t y_list = 0; // list of groups of the y-channel list_t u_list = 0; // list of groups of the u-channel list_t v_list = 0; // list of groups of the v-channel clock_t start, end; // time variables for counting durations double time; // ---------------------------------------------------------------------- // OPEN LOG-FILE FOR WRITING // ---------------------------------------------------------------------- // obtain filename without path and extension if (exclude_extension(infile, pure_name) != 0) { return 1; } sprintf (logfile, "log/log_%s_%s[%d].txt", pure_name, kind, sigma); log = fopen (logfile, "a"); if (log == NULL) { generate_error ("Unable to open log-file for writing ..."); return 1; } // ---------------------------------------------------------------------- // INPUT READING AND VALIDATION // ---------------------------------------------------------------------- // read input image if (png_read(&img, infile) != 0) { return 1; } // read temporary image if (png_read(&org, infile) != 0) { return 1; } // control color type if (img.color != PNG_COLOR_TYPE_RGB) { generate_error ("Wrong color type..."); return 1; } // control number of channels if (img.channels != 3) { generate_error ("Wrong number of channels..."); return 1; } // ---------------------------------------------------------------------- // PARAMETER VALIDATION // ---------------------------------------------------------------------- // verify kind of shrinkage if (strcmp(kind, "none") && strcmp(kind, "avg") && strcmp(kind, "ht") && strcmp(kind, "wnr")) { generate_error ("Unknown kind of shrinkage..."); return 1; } // verify block size if ((block_size!=7) && (block_size!=9) && (block_size!=11) && (block_size!=13)) { generate_error ("Wrong value for block size...\nValid values: 7, 9, 11, 13"); return 1; } // verify block step if ((block_step<5) || (block_step>15)) { generate_error ("Block step is out of valid Range...\nValid range: 5..15"); return 1; } // control search window dimensions h_search_true = ((h_search > img.width) || (h_search <= 0)) ? img.width : h_search; v_search_true = ((v_search > img.height) || (v_search <= 0)) ? img.height : v_search; // ---------------------------------------------------------------------- // PRINTING OF STATUS INFORMATION // ---------------------------------------------------------------------- fprintf (log, "-------------------------------------------------------------------------\n"); fprintf (log, "-------------------------------------------------------------------------\n"); fprintf (log, "[INFO] ... image dimensions: %dx%d\n", img.width, img.height); fprintf (log, "[INFO] ... kind of shrinkage: %s\n", kind); fprintf (log, "[INFO] ... block size: %d\n", block_size); fprintf (log, "[INFO] ... block step: %d\n", block_step); fprintf (log, "[INFO] ... sigma: %d\n", sigma); fprintf (log, "[INFO] ... maximum number of blocks: %d\n", max_blocks); fprintf (log, "[INFO] ... horizontal search window size: %d\n", h_search_true); fprintf (log, "[INFO] ... vertical search window size: %d\n", v_search_true); fprintf (log, "[INFO] ... threshold 2D: %f\n", th_2d); fprintf (log, "[INFO] ... tau-match 2D: %f\n", tau_match); fprintf (log, "[INFO] ... threshold 3D: %f\n", th_3d); fprintf (log, "[INFO] ... block marking: %s\n\n", block_marking ? "yes" : "no"); // ---------------------------------------------------------------------- // COLORSPACE CONVERSION & WRITEBACK // ---------------------------------------------------------------------- printf ("[INFO] ... launch of color conversion...\n"); rgb2yuv (&img); // write output image if (png_write(&img, "img/yuv/", "noisy_yuv", 0) != 0) { return 1; } printf ("[INFO] ... end of color conversion...\n\n"); fprintf (log, "[INFO] ... converted colorspace of input image to YUV...\n\n"); // ---------------------------------------------------------------------- // IMAGE-TO-ARRAY CONVERSION // ---------------------------------------------------------------------- printf ("[INFO] ... launch of printing image as three separate value arrays...\n"); printf ("[INFO] ... ... luminance channel...\n"); img2array (&img, 0, "img/", "y_channel_before"); printf ("[INFO] ... ... chrominance channel 1...\n"); img2array (&img, 1, "img/", "u_channel_before"); printf ("[INFO] ... ... chrominance channel 2...\n"); img2array (&img, 2, "img/", "v_channel_before"); printf ("[INFO] ... end of printing arrays...\n\n"); fprintf (log, "[INFO] ... printed every intput channel as array of values...\n\n"); // ---------------------------------------------------------------------- // BLOCK-MATCHING // ---------------------------------------------------------------------- printf ("[INFO] ... launch of block-matching...\n"); printf ("[INFO] ... ... luminance channel...\n"); start = clock(); if (block_matching(&img, &org, block_size, block_step, sigma, h_search_true, v_search_true, th_2d, tau_match, 0, block_marking, &y_list) != 0) { return 1; } printf ("[INFO] ... end of block-matching...\n\n"); end = clock(); time = (end - start) / (double)CLOCKS_PER_SEC; fprintf (log, "[INFO] ... block-matching accomplished...\n"); fprintf (log, "[INFO] ... ... elapsed time: %f\n", time); fprintf (log, "[INFO] ... ... number of groups in list: %d\n\n", list_length(&y_list)); // print recognized groups to file sprintf (path, "grp/org/%s/y/", kind); if (print_list(y_list, path, "group") != 0) { return 1; } // trim groups to maximal number of blocks printf ("[INFO] ... trimming groups to maximum size...\n\n"); if (trim_list(&y_list, max_blocks) != 0) { return 1; } fprintf (log, "[INFO] ... trimmed groups to maximum size of blocks...\n\n"); // obtain the pixel values from the u- and v-channel of the image printf ("[INFO] ... extracting blocks from chrominance channels...\n"); printf ("[INFO] ... ... chrominance channel 1...\n"); if (get_chrom(&img, &y_list, &u_list, 1)) { return 1; } printf ("[INFO] ... ... chrominance channel 2...\n\n"); if (get_chrom(&img, &y_list, &v_list, 2)) { return 1; } fprintf (log, "[INFO] ... extracted values from chrominance channels...\n\n"); // print trimmed groups to file sprintf (path, "grp/trm/%s/y/", kind); if (print_list(y_list, path, "group") != 0) { return 1; } sprintf (path, "grp/trm/%s/u/", kind); if (print_list(u_list, path, "group") != 0) { return 1; } sprintf (path, "grp/trm/%s/v/", kind); if (print_list(v_list, path, "group") != 0) { return 1; } // ---------------------------------------------------------------------- // IMAGE-DENOISING // ---------------------------------------------------------------------- printf ("[INFO] ... launch of shrinkage...\n"); start = clock(); printf ("[INFO] ... ... luminance channel...\n"); if (shrinkage(kind, &y_list, sigma, th_3d, 0) != 0) { return 1; } // printf ("[INFO] ... ... chrominance channel 1...\n"); // if (shrinkage(kind, &u_list, sigma, th_3d, 1) != 0) { // return 1; // } // printf ("[INFO] ... ... chrominance channel 2...\n"); // if (shrinkage(kind, &v_list, sigma, th_3d, 1) != 0) { // return 1; // } printf ("[INFO] ... end of shrinkage...\n\n"); end = clock(); time = (end - start) / (double)CLOCKS_PER_SEC; fprintf (log, "[INFO] ... accomplished shrinkage...\n"); fprintf (log, "[INFO] ... ... elapsed time: %f\n\n", time); sprintf (path, "grp/est/%s/y/", kind); if (print_list(y_list, path, "group") != 0) { return 1; } sprintf (path, "grp/est/%s/u/", kind); if (print_list(u_list, path, "group") != 0) { return 1; } sprintf (path, "grp/est/%s/v/", kind); if (print_list(v_list, path, "group") != 0) { return 1; } // ---------------------------------------------------------------------- // AGGREGATION // ---------------------------------------------------------------------- printf ("[INFO] ... launch of aggregation...\n"); start = clock(); printf ("[INFO] ... ... luminance channel...\n"); if (aggregate(kind, &img, &y_list, 0) != 0) { return 1; } // printf ("[INFO] ... chrominance channel 1...\n"); // if (aggregate(kind, &img, &u_list, 1) != 0) { // return 1; // } // printf ("[INFO] ... chrominance channel 2...\n"); // if (aggregate(kind, &img, &v_list, 2) != 0) { // return 1; // } printf ("[INFO] ... end of aggregation...\n\n"); end = clock(); time = (end - start) / (double)CLOCKS_PER_SEC; fprintf (log, "[INFO] ... accomplished aggregation...\n"); fprintf (log, "[INFO] ... ... elapsed time: %f\n\n", time); // ---------------------------------------------------------------------- // IMAGE-TO-ARRAY CONVERSION // ---------------------------------------------------------------------- printf ("[INFO] ... launch of printing image as three separate value arrays...\n"); printf ("[INFO] ... ... luminance channel...\n"); img2array (&img, 0, "img/", "y_channel_after"); printf ("[INFO] ... ... chrominance channel 1...\n"); img2array (&img, 1, "img/", "u_channel_after"); printf ("[INFO] ... ... chrominance channel 2...\n"); img2array (&img, 2, "img/", "v_channel_after"); printf ("[INFO] ... end of printing arrays...\n\n"); // ---------------------------------------------------------------------- // COLORSPACE CONVERSION & WRITEBACK // ---------------------------------------------------------------------- printf ("[INFO] ... launch of color conversion...\n"); yuv2rgb (&img); sprintf (prefix, "denoised_rgb_%s_%s", pure_name, kind); // write output image if (png_write(&img, "img/rgb/", prefix, sigma) != 0) { return 1; } printf ("[INFO] ... end of color conversion...\n\n"); fprintf (log, "[INFO] ... converted colorspace of output image to RGB...\n\n"); fprintf (log, "[INFO] ... PSNR after denoising: %fdB\n", get_snr(&org, &img)); fprintf (log, "-------------------------------------------------------------------------\n"); fprintf (log, "-------------------------------------------------------------------------\n\n\n"); // ---------------------------------------------------------------------- // FREEING DYNAMICALY ALLOCATED MEMORY // ---------------------------------------------------------------------- free_list (&y_list); free_list (&u_list); free_list (&v_list); png_free_mem (&img); png_free_mem (&org); fclose (log); return 0; }