Thread: Arrays and their Application to image processing

  1. #1
    Registered User
    Join Date
    Nov 2010
    Posts
    29

    Question Arrays and their Application to image processing

    Yes, I am working on homework for an intro C class but am not asking for the answer directly. Moreover some help would be appreciated.

    My teacher gave us the skeleton program to read and write image files in the PGM. I simply have to add the definition of a two dimensional array of integers to it. "Simply" it seems, but I'm new to this and can't seem to find very many good resources (that I can understand).

    The code is as follows:

    Code:
    // Read a PGM-format file into an array
    // PGM file format is documented here:
    // http://en.wikipedia.org/wiki/Netpbm_format
    //
    // Here's a short example:
    //
    // P2
    // # a comment line
    // 24 7
    // 3
    // 0 0 0 0 1 1 1 0 0 0 2 2 2 2 0 0 0 0 3 3 3 3 3 0
    // ... 6 more rows of pixel data
    // 
    // The P2 means a gray-scale image
    // Comment lines start with # and can be ignored
    // 24 means 24 wide
    // 7 means 7 high
    // 3 means the maximum pixel value is 3 in this example
    
    #include <stdio.h>
    #include <stdlib.h>
    
    //typedef unsigned short int word ;
    //typedef unsigned char byte ;
    
    // Maximum size image we will process (larger ones
    // get truncated to the upper left corner)
    #define MAX_HEIGHT 1024 
    #define MAX_WIDTH 1024 
    
    // allows writing multiple pixels per line to the
    // output PGM file.  Looks like many programs that
    // use the PGM format just keep this at one.  It 
    // should not be more than 70 in any event.
    #define MAX_PIXELS_PER_LINE 1
    
    // Useful macro def
    #define MIN( x, y ) ( ( x ) < ( y ) ? ( x ) : ( y ) )
    
    // This is the array that will contain the image
    // within your program.
    // ????????????????????????????????
    
    // You will need an identical  array to use to hold
    // the output of your image transformation
    // ????????????????????????????????
    
    // Internal function to read the header information
    // stored at the beginning of a PGM format file.
    // 
    // Used by read_pgm_file_into_array to see set the
    // height and width of the image
    FILE* read_pgm_file_info 
    ( 
    	int* height, 			// output
    	int* width, 			// output
    	int* maxPixel,		// output
    	char* pgmFname  	// input
    )
    {
    	static FILE* fp = 0L ;
    	char pgmFormatFlag[3] =  { '\0' } ;
    
    	char trash[80] = { '\0' } ;
    	memset ( ( void * ) trash, '\0', 80 ) ;
     
      fp = fopen ( pgmFname, "r" ) ;
    	
      if ( fp )
    	{
    		// Check the signature
    		fscanf ( fp, "%2c\n", pgmFormatFlag ) ;
    		//printf ( "%s\n", pgmFormatFlag ) ;
    		if ( ! strcmp ( pgmFormatFlag, "P2" ) )
    		{
    			// Skip the comment line
    			//fscanf ( fp, "\n" ) ;
    			fgets (  trash, 70, fp ) ;
    			//printf ( "%s", trash ) ;
    
    			// Read the width
    			fscanf ( fp, "%i", width ) ;
    			//printf ( "%i,", *width ) ;
    			
    			// Read the height
    			fscanf ( fp, "%i", height ) ;
    			//printf ( "%i\n", *height ) ;
    
    			// Read the maximum pixel value
    			fscanf ( fp, "%i", maxPixel ) ;
    		}
    		//fclose ( fp ) ;
    	}
    	
    	return fp ;
    }
    
    // Write out an array as a PGM file (ascii).
    // writes imageArray to the file named by pgmOutFileName.
    // commentLine, height, width, and maxPixel must be
    // set and passed to this function so they can
    // be written correctly in the PGM file header and
    // so this function will know how many rows (image height)
    // and how many columns (image width) to write.
    void write_pgm_file_from_array 
    (
    	char* pgmOutFileName,					// input
    	int imageArray[][MAX_WIDTH],	// input
    	char* commentLine,						// input
    	int height,										// input
    	int width,										// input
    	int maxPixel									// input
    )
    {
    	int row = 0 ;
    	int col = 0 ;
    	FILE* fp = fopen ( pgmOutFileName, "w" ) ;
    	if ( fp )
    	{
    		// Generate the header info
    		fprintf ( fp, "P2\n" ) ;
    		fprintf ( fp, "%s\n", commentLine ) ;
    		fprintf ( fp, "%u %u\n", width, height ) ;
    		fprintf ( fp, "%u\n", maxPixel ) ;
    
    		// Now write out the data, ensuring that at most 70 
    		// values appear on each line, even if width is > 70
    		for ( row = 0 ; row < height ; row ++ )
    		{
    			for ( col = 0 ; col < width ; col ++ ) 
    			{
    					fprintf ( fp, "%u", imageArray[row][col] ) ;
    					// break up long rows into multiple lines as needed
    					if ( MAX_PIXELS_PER_LINE > 1 )
    					{
    						fprintf ( fp, " " ) ;
    					}
    					if ( ( col % MAX_PIXELS_PER_LINE ) == 0 )
    					{
    						fprintf ( fp, "\n" ) ;
    					}
    			}
    			// Watch out of special case of width == 70
    			if ( col % MAX_PIXELS_PER_LINE )
    			{
    				fprintf ( fp, "\n" ) ;
    			}
    		}
    		fclose ( fp ) ;
    	}
    	return ;
    }
    
    // Read file named by pgmInFileName argument into
    // the array imageArray. This function respects the
    // MAX_HEIGHT and MAX_WIDTH values, so if you declare
    // your target array using these bounds, even reading
    // a large image file should not blow up your program.
    // (but you will only get the upper left-hand corner
    // of the image).  Checks that the file read is a PGM
    // (gray scale, ascii) file.
    //
    // Sets height, width, and maxPixel according to the
    // header read.
    void read_pgm_file_into_array 
    ( 
    	int imageArray[][MAX_WIDTH], 	// output
    	int* height, 								 	// output
    	int* width, 									// output
    	int* maxPixel, 								// output
    	char* pgmInFileName 					// input
    )
    {
    	int row = 0 ;
    	int col = 0 ;
    	FILE* fp = read_pgm_file_info ( height, width, maxPixel, pgmInFileName ) ;
    
    	if ( fp )
    	{
    		for ( row = 0 ; row < MIN( MAX_HEIGHT - 1, *height ) ; row ++ )
    		{
    			for ( col = 0 ; col < MIN( MAX_WIDTH -1, *width ) ; col ++ )
    			{
    				fscanf ( fp, "%i", &imageArray[row][col]) ;
    			}
    		}
    		fclose ( fp ) ;
    	}
    
    	return ;
    }
    
    int main( void )
    {
      int height  = 0 ;
      int width = 0 ;
    	int maxPixel = 0 ;
    	char* pgmInFileName = "irv.pgm" ;
    	char* pgmOutFileName = "irv_out.pgm" ;
    int theImageArray[height][width];
    
    
    	// Read input file into array, then write it back out,
    	// just to prove this all works.  Input file and output
    	// file should look just the same.  (sizes on disk might 
    	// vary slightly) 
    	read_pgm_file_into_array ( theImageArray, &height, &width, &maxPixel, pgmInFileName ) ;
    	write_pgm_file_from_array ( pgmOutFileName, theImageArray, "# JR test file", height, width, 
    		maxPixel ) ;
    
      printf ( "Copying %s to %s, height=%u, width=%u, maxPixel=%d\n", pgmInFileName,
    		pgmOutFileName,
    		height, width, maxPixel ) ;
      
      return 0 ;
    }
    I keep thinking that I need to stick in
    Code:
    int theImageArray[height][width];
    into the main program but I really don't know what I'm doing. If the number of rows and columns is defined by the pixel height and width of the PGM file, how do I define the array? Some help or hints appreciated- and idiot speak appreciated as well.

  2. #2
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Read the comment for read_pgm_file_into_array()
    It tells you exactly how to declare the array.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Nov 2010
    Posts
    29
    K got this to work with "int theImageArray[MAX_HEIGHT][MAX_WIDTH];" as global. Now that I have that working, I have to find some code to manipulate the brightness outcome of the image. I am looking at GameDev.net -- An Introduction To Digital Image Processing but it wants me to implement the Allegro library which I am having difficulty doing. Any other resources out there that you know of for code to produce a darker or lighter image?

    Thanks!

  5. #5
    Registered User
    Join Date
    Nov 2010
    Posts
    29
    Nevermind, I figured this out on my own. I'm proud of myself

  6. #6
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Well done, Quintenmater!

  7. #7
    Registered User
    Join Date
    Sep 2008
    Posts
    58
    Is your teacher by chance Professor Reed? I won't list his first name for obvious reasons, but I'm curious since I had this exact assignment three semesters ago.

  8. #8
    Registered User
    Join Date
    Nov 2010
    Posts
    29
    yes

Popular pages Recent additions subscribe to a feed

Tags for this Thread