Problem reading tiff image files?

This is a discussion on Problem reading tiff image files? within the C++ Programming forums, part of the General Programming Boards category; Hi, I'm currently working on some code that will need to read color tiff image files. While I have no ...

  1. #1
    Registered User
    Join Date
    Nov 2003
    Posts
    6

    Problem reading tiff image files?

    Hi,

    I'm currently working on some code that will need to read color tiff image files. While I have no problems working with gray scale images I have not had any luck getting color to work. At the moment all I am simply trying to do is read a color tiff image (which filename is "input.tif") and output the values of individual samples (pixel elements RGB) to the screen. (I'm intentionally not printing all image pixels to the screen at the moment.) However, what my code currently does is output partially correct results. It seems to display the first few (~10) samples fine to the screen, but then starts skipping samples. Do you guys have any ideas what may be causing that? What may be wrong with my code (listed below)?
    Any suggestions/pointers would be greatly appreciated.

    Thank you.

    This is my code (hopefully it doesn't lose all formatting):
    Code:
    #include <stdio.h>
    #include <iostream.h>
    #include <tiffio.h>
    void print_error (char *err_message);
    
    int main()
    {
    
    double red_mean;				// mean red value of fed image
    
        uint32 r; 						// row index
        uint32 c; 						// column index
        uint32 rows;					// number of rows in image
        uint32 columns;					// number of columns in image
        uint16 BitsPerSample;			// normally 8 for grayscale image
        uint16 SamplesPerPixel;			// normally 1 for grayscale image
        uint16 PhotoMetric; 			// normally 1 for grayscale image
        unsigned char *in_image;		// pointer for input image array
        unsigned char *out_image;		// pointer for output image array
        TIFF *in_filep; 				// handle for input image file
        TIFF *out_filep;	 			// handle for output image file
        int	check_io;					// status of I/O operation
    
        // Open input image file
        in_filep = TIFFOpen("input.tif", "r");
        if (in_filep == NULL)
    	print_error ("Could not open input file!");
    
        // Open output image file
        out_filep = TIFFOpen ("output.tif", "w"); 
        if (out_filep == NULL)
    	print_error ("Could not open output file!");
    
        // Determine the size of the input image
        TIFFGetField(in_filep, TIFFTAG_IMAGELENGTH, &rows);
        TIFFGetField(in_filep, TIFFTAG_IMAGEWIDTH, &columns);
        TIFFGetField(in_filep, TIFFTAG_BITSPERSAMPLE, &BitsPerSample);
        TIFFGetField(in_filep, TIFFTAG_SAMPLESPERPIXEL, &SamplesPerPixel);
        TIFFGetField(in_filep, TIFFTAG_PHOTOMETRIC, &PhotoMetric);
    	//TIFFGetField(in_filep, TIFFTAG_PHOTOMETRIC, &PlanarConfig);
        // The following statements are helpful in debugging
        printf ("rows = %ld\n", rows);
        printf ("columns = %ld\n", columns);
        printf ("BitsPerSample = %d\n", BitsPerSample);
        printf ("SamplesPerPixel = %d\n", SamplesPerPixel);
        printf ("PhotoMetric = %d\n", PhotoMetric);
    
        // Specify TIFF header fields for output image
        TIFFSetField(out_filep, TIFFTAG_IMAGELENGTH, rows);
        TIFFSetField(out_filep, TIFFTAG_IMAGEWIDTH, columns);
        TIFFSetField(out_filep, TIFFTAG_BITSPERSAMPLE, BitsPerSample);
        TIFFSetField(out_filep, TIFFTAG_SAMPLESPERPIXEL, SamplesPerPixel);
     	TIFFSetField(out_filep, TIFFTAG_PLANARCONFIG, 1);
        TIFFSetField(out_filep, TIFFTAG_PHOTOMETRIC, PhotoMetric);
    
    
        // Allocate memory to hold image arrays
        in_image = (unsigned char *) _TIFFmalloc(rows*columns);
        if (in_image == NULL) 
    	print_error ("Could not allocate memory!");
        out_image = (unsigned char *) _TIFFmalloc(rows*columns);
        if (out_image == NULL) 
    	print_error ("Could not allocate memory!");
    
        // Read image pixel values from file, row by row 
    	for (r = 0; r < rows; r++)
        {
            check_io = TIFFReadScanline(in_filep, &in_image[r*columns], r, 1);
            if (check_io != 1)
    	    print_error ("Could not read image from file!");
        }
    	
    //************************************************************************************
    	// Output the first several samples (pixel elements) to screen
    	red_mean = 0;
        for (r = 0; r < 3; r++)
    		for (c = 0; c < 24; c++)
    		//for (c = 0; c <= (columns*3); (c=c+3))
    	    {
    		    cout << "r = " << r << " c= " << c << " Intensity = " << (int) in_image[r*columns+c] << endl;
    		}		
    //************************************************************************************
       
        // Write new image to file, row by row 
        for (r = 0; r < rows; r++)
        {
            check_io = TIFFWriteScanline(out_filep, &out_image[r*columns], r, 1);
            if (check_io != 1)
    	    print_error ("Could not read image from file!");
        }
    
        // Deallocate the image memory, close file streams, and exit
        _TIFFfree(in_image);
        _TIFFfree(out_image);
        TIFFClose(in_filep);
        TIFFClose(out_filep);
        exit (0);
    }
    
    /*****************************************************
    Function name:   print_error
    Description:
        Print an error message, and exit the program.
    Input parameters:
        err_message -- pointer to string to be printed
    Returned value:
        none
    *****************************************************/
    void print_error (char *err_message)
    {
        fprintf(stderr, "Error:  %s\n", err_message);
        exit (1);
    }

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,674
    Code:
    check_io = TIFFWriteScanline(out_filep, &out_image[r*columns], r, 1);
    Hmmm, what exactly did you put in that buffer?



    gg

  3. #3
    Registered User
    Join Date
    Nov 2003
    Posts
    6
    Originally posted by Codeplug
    Code:
    check_io = TIFFWriteScanline(out_filep, &out_image[r*columns], r, 1);
    Hmmm, what exactly did you put in that buffer?



    gg

    Thank you for replying Codeplug!

    As for the out_image buffer, I removed the code that wrote to it for the moment as I was getting the wrong output. While debugging I found that the original image file was not being read correctly. (Good reason for the output not being correct ) So, at this point all I am trying to do is read in the image and output the first several RGB samples. Not sure what I'm doing wrong, whether it has someting to do with the headers or not?

    If I misunderstood your suggestion or if you happen to have further pointers I would greatly appreciate further feedback.

    Thanks, I look forward to more replies!

  4. #4
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,674
    Well, all I can really suggest is to make sure you understand the the pixel format of the scanline data based on the current bits-per-sample, samples-per-pixel, and photometric values (is the data RGB or colormap indexes).

    Can't help you much with libtiff since I've never used it but I did find a nice tutorial on libtiff.

    Google is great for finding such things.

    gg

  5. #5
    Registered User
    Join Date
    Nov 2003
    Posts
    6
    Thanks again for your help Codeplug.

    Unfortunately, I've already read the page...but I'll go ahead and reread it in case I missed something.

  6. #6
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    > in_filep = TIFFOpen("input.tif", "r");

    > out_filep = TIFFOpen ("output.tif", "w");

    You should probably use binary mode to open the files:
    in_filep = TIFFOpen("input.tif", "rb");

    out_filep = TIFFOpen ("output.tif", "wb");

  7. #7
    Registered User
    Join Date
    Nov 2003
    Posts
    6
    Originally posted by swoopy
    > in_filep = TIFFOpen("input.tif", "r");

    > out_filep = TIFFOpen ("output.tif", "w");

    You should probably use binary mode to open the files:
    in_filep = TIFFOpen("input.tif", "rb");

    out_filep = TIFFOpen ("output.tif", "wb");
    Swoopy,

    Thank you for your suggestion. I tried it out; however, it did not seem to change the output for some reason.

    Located here is my current code (which is a tiny bit different from what was posted in my first original message):
    http://filebox.vt.edu/h/hthomsch/tiff/color1.c

    Located here is the image I am using as input:
    http://filebox.vt.edu/h/hthomsch/tiff/input.tif

    Located here is the output I am currently getting:
    https://filebox.vt.edu/h/hthomsch/tiff/output.txt

    When looking at the input image (input.tif given above) the top row of pixels are all black, therefore shouldn't columns c=0 through c=27 be 0 (ie. black) for the first row (ie. r=0)? However, this is not what the output shows. (Peculiarities such as that seem to happen in every row.)

    Are the headers that I'm using "misconfigured" maybe?
    Any suggestions as to how I may solve this problem is greatly appreciated.

  8. #8
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,674
    Ok. Refering to the posted color1.c:

    - Once again, you're reading into "in_image" then writting "out_image". You may of "ommitted" that code, but you can't expect color1.c to work as is.

    - TIFFTAG_PLANARCONFIG should be 1, not 2

    >> in_image = (unsigned char *) _TIFFmalloc(rows*columns);
    - This assumes that each scanline is "columns" bytes, which is wrong for RGB data. Use TIFFScanlineSize() to determine the scanline size (this will be 24 for input.tif, 8 pixels wide * 3 bytes per pixel for red, green, blue). You will have to modify your TIFFReadScanline() and TIFFWriteScanline() calls accordinly as well.

    >> cout << "r = " << r << " c= " << c << " Intensity = " << (int) in_image[r*columns+c] << endl;
    - Don't mix in C++ with C. And remember that we are dealing with RGB data, not intensity data as with your previous greyscale image projects. Here is some code that will dump the RGB values for each pixel:
    Code:
        scanline = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in_filep));
        for (r = 0; r < rows; r++)
        {
            TIFFReadScanline(in_filep, scanline, r, 0);
            for (c = 0; c < columns; c++)
            {
                printf("[%d,%d,%d] ", 
                       *(scanline + c),      // red intensity
                       *(scanline + c + 1),  // green intensity
                       *(scanline + c + 2)); // blue intensity
            }
            printf("\n");
        }
        _TIFFfree(scanline);
    gg

  9. #9
    Registered User
    Join Date
    Nov 2003
    Posts
    6

    Talking

    Originally posted by Codeplug
    Ok. Refering to the posted color1.c:

    - Once again, you're reading into "in_image" then writting "out_image". You may of "ommitted" that code, but you can't expect color1.c to work as is.

    - TIFFTAG_PLANARCONFIG should be 1, not 2

    >> in_image = (unsigned char *) _TIFFmalloc(rows*columns);
    - This assumes that each scanline is "columns" bytes, which is wrong for RGB data. Use TIFFScanlineSize() to determine the scanline size (this will be 24 for input.tif, 8 pixels wide * 3 bytes per pixel for red, green, blue). You will have to modify your TIFFReadScanline() and TIFFWriteScanline() calls accordinly as well.

    >> cout << "r = " << r << " c= " << c << " Intensity = " << (int) in_image[r*columns+c] << endl;
    - Don't mix in C++ with C. And remember that we are dealing with RGB data, not intensity data as with your previous greyscale image projects. Here is some code that will dump the RGB values for each pixel:
    Code:
        scanline = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in_filep));
        for (r = 0; r < rows; r++)
        {
            TIFFReadScanline(in_filep, scanline, r, 0);
            for (c = 0; c < columns; c++)
            {
                printf("[%d,%d,%d] ", 
                       *(scanline + c),      // red intensity
                       *(scanline + c + 1),  // green intensity
                       *(scanline + c + 2)); // blue intensity
            }
            printf("\n");
        }
        _TIFFfree(scanline);
    gg

    Thanks again for your help Codeplug! Your help was great! (I would have replied sooner, but I got hit hard by the flu.)
    I slightly modified the code you suggested and extrapolated on the suggestions you made and my code is now progressing well. So far everything is working very well. I'm very happy!!!

    Thanks again for all your help!

  10. #10
    Registered User
    Join Date
    Oct 2009
    Posts
    1
    I want to create a TIFF with plain red color. Can anybody help me?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 6
    Last Post: 04-28-2006, 12:06 PM
  2. Problem with reading data files
    By CConfusion in forum C Programming
    Replies: 3
    Last Post: 04-02-2006, 02:55 PM
  3. C: include files problem
    By threahdead in forum Linux Programming
    Replies: 4
    Last Post: 05-07-2004, 08:02 AM
  4. problem reading pe files
    By Sebastiani in forum C++ Programming
    Replies: 0
    Last Post: 01-26-2003, 10:14 AM
  5. problem reading files in C
    By angelfly in forum C Programming
    Replies: 9
    Last Post: 10-10-2001, 11:58 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21