User Name Password Register
DaniWeb IT Discussion Community
All
What is DaniWeb IT Discussion Community?
You're currently browsing the C++ section within the Software Development category of DaniWeb, a massive community of 455,962 software developers, web developers, Internet marketers, and tech gurus who are all enthusiastic about making contacts, networking, and learning from each other. In fact, there are 3,602 IT professionals currently interacting right now! Registration is free, only takes a minute and lets you enjoy all of the interactive features of the site.
Please support our C++ advertiser: Programming Forums
Views: 1357 | Replies: 3 | Solved
Reply
Join Date: Jul 2005
Location: Bristol, UK
Posts: 18
Reputation: ravenous is an unknown quantity at this point 
Rep Power: 4
Solved Threads: 1
ravenous's Avatar
ravenous ravenous is offline Offline
Newbie Poster

libtiff questions

  #1  
Nov 18th, 2007
Hi,

Does anyone here have any experience of using libtiff in c++? I have been trying to do some simple image processing using it and I don't seem to be able to write images. I can make files that have roughly the right size, but they're not correct as they don't open with any image viewers that I have. A test example of my code is shown below. The code is supposed to read in a colour image to an array (raster), convert it to monochrome by averaging the pixel values and storing them in an int array (image_mono), then convert the int array back into a char array (monoFile) and output this array as a tiff. Anyway, it compiles and runs, but the tiff is not readable :-( Any tips would be greatly appreciated.
  1. #include <iostream>
  2. using std::cout;
  3. using std::endl;
  4. using std::cerr;
  5. #include <cmath>
  6. #include <tiffio.h>
  7.  
  8.  
  9. int main(int argc, char* argv[])
  10. {
  11. uint32 width = 0;
  12. uint32 height = 0;
  13. float xres;
  14. float yres;
  15. uint16 resUnit;
  16. uint32 *raster = NULL;
  17. uint32 numberOfPixels = 0;
  18. unsigned pixel = 0;
  19.  
  20. // Open the input file, as given via the command line
  21. TIFF* tif = TIFFOpen(argv[1], "r");
  22. if (!tif){
  23. cerr << "Unable to open image!" << endl;
  24. return 1;
  25. }
  26.  
  27. // Get the dimensions of the image
  28. TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
  29. TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
  30. TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres);
  31. TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres);
  32. TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT, &resUnit);
  33.  
  34. // Now use the libtiff malloc functions to allocate memory to store the image data
  35. numberOfPixels=width*height;
  36. if(numberOfPixels)
  37. raster = (uint32 *)_TIFFmalloc(numberOfPixels*sizeof(uint32));
  38.  
  39. // Now actually read the data from the image...
  40. if(!TIFFReadRGBAImage(tif,width,height,raster,0)){
  41. // Print an error and exit if it doesn't read properly
  42. cerr << "Error occured when reading image data!" << endl;
  43. return 1;
  44. }
  45. else // Close the file if the info is read OK
  46. TIFFClose(tif);
  47.  
  48. // Now the pixel values are in memory, so get the pixel values into the form
  49. // that I want; that is monochromatic, by averaging the R, G & B channels...
  50. int *image_mono = (int*)malloc(numberOfPixels*sizeof(int));
  51.  
  52. for(pixel = 0; pixel < numberOfPixels; pixel++)
  53. image_mono[pixel] = ( (static_cast<int>(static_cast<char>(TIFFGetR(raster[pixel]))) & 0xFF) +
  54. (static_cast<int>(static_cast<char>(TIFFGetG(raster[pixel]))) & 0xFF) +
  55. (static_cast<int>(static_cast<char>(TIFFGetB(raster[pixel]))) & 0xFF))/3;
  56.  
  57. // The reason for the bitwise AND (&) in the above is that I found that
  58. // if I just do static_cast<int>(static_cast<char>(TIFFGetX(raster[pixel])))
  59. // then I get the result (in hex) FFFFFF00 + the actual pixel value. By doing
  60. // 0xFF & on it then I get the answer I am looking for.
  61.  
  62. char *monoFile = (char *)malloc(numberOfPixels);
  63.  
  64. for(pixel = 0; pixel < numberOfPixels; pixel++)
  65. monoFile[pixel] = (char)(image_mono[pixel] | 0xFFFFFF00);
  66. // The bitwise OR (|) here undoes the AND that I used above.
  67.  
  68. // Open a new TIFF file for the output...
  69. if((tif = TIFFOpen("output.tif", "w")) == NULL){
  70. cerr << "Could not open output.tif for writing" << endl;
  71. return 1;
  72. }
  73.  
  74. // Set some tags in the output file. To be honest, I don't know much about
  75. // what I'm doing here, I've just tried a bunch of different things...
  76. TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, 8*width);
  77. TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
  78. TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
  79. TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
  80. TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, height);
  81. TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);
  82. TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, 2);
  83. TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
  84. TIFFSetField(tif, TIFFTAG_XRESOLUTION, xres);
  85. TIFFSetField(tif, TIFFTAG_YRESOLUTION, yres);
  86. TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, resUnit);
  87.  
  88. // Write the information to the file
  89. TIFFWriteEncodedStrip(tif, 0, monoFile, width*height);
  90.  
  91. return 0;
  92. }

I'm all out of ideas about what to do to get this to work. The documentation for libtiff seems to be a lot more sparse than I expected. Alternatively, if there is some other tiff library that I should be using then certainly let me know that as well!

Cheers,
Ravenous
AddThis Social Bookmark Button
Reply With Quote  
Join Date: Dec 2005
Posts: 3,834
Reputation: Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of 
Rep Power: 23
Solved Threads: 436
Colleague
Salem's Avatar
Salem Salem is offline Offline
banned

Re: libtiff questions

  #2  
Nov 19th, 2007
You could try reading a known mono TIF image to make sure you know what values are expected for the various header fields.

Also, being a mono image, shouldn't it be just 1 bit per pixel, and not 1 byte set to 0x00 or 0xFF (just a guess)?
Reply With Quote  
Join Date: Jul 2005
Location: Bristol, UK
Posts: 18
Reputation: ravenous is an unknown quantity at this point 
Rep Power: 4
Solved Threads: 1
ravenous's Avatar
ravenous ravenous is offline Offline
Newbie Poster

Re: libtiff questions

  #3  
Nov 19th, 2007
Originally Posted by Salem View Post
You could try reading a known mono TIF image to make sure you know what values are expected for the various header fields.

Yep, I'll try this. I couldn't find any suitable images, but I guess I'll just create one with Gimp or something,

Also, being a mono image, shouldn't it be just 1 bit per pixel, and not 1 byte set to 0x00 or 0xFF (just a guess)?


Sorry, this is just me using the wrong word. You are, of course, correct. A mono image is just one bit. What I meant was *greyscale*. Sorry for the confusion!
Last edited by ravenous : Nov 19th, 2007 at 6:22 pm. Reason: Edited [QUOTE] tags
Reply With Quote  
Join Date: Jul 2005
Location: Bristol, UK
Posts: 18
Reputation: ravenous is an unknown quantity at this point 
Rep Power: 4
Solved Threads: 1
ravenous's Avatar
ravenous ravenous is offline Offline
Newbie Poster

Re: libtiff questions

  #4  
Nov 20th, 2007
I think I'm going to use Magic++ instead, it has a much more C++-centric API!
Reply With Quote  
Reply

Only community members can participate in forum threads. You must register or log in to contribute.

DaniWeb C++ Marketplace
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)

 

Thread Tools Display Modes

Similar Threads
Other Threads in the C++ Forum

All times are GMT -4. The time now is 9:00 am.
Forum system based on vBulletin Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
©2003 - 2008 DaniWeb® LLC