cmtkPGM.cxx

Go to the documentation of this file.
00001 /*
00002 //
00003 //  Copyright 2004-2010 SRI International
00004 //
00005 //  Copyright 1997-2009 Torsten Rohlfing
00006 //
00007 //  This file is part of the Computational Morphometry Toolkit.
00008 //
00009 //  http://www.nitrc.org/projects/cmtk/
00010 //
00011 //  The Computational Morphometry Toolkit is free software: you can
00012 //  redistribute it and/or modify it under the terms of the GNU General Public
00013 //  License as published by the Free Software Foundation, either version 3 of
00014 //  the License, or (at your option) any later version.
00015 //
00016 //  The Computational Morphometry Toolkit is distributed in the hope that it
00017 //  will be useful, but WITHOUT ANY WARRANTY; without even the implied
00018 //  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019 //  GNU General Public License for more details.
00020 //
00021 //  You should have received a copy of the GNU General Public License along
00022 //  with the Computational Morphometry Toolkit.  If not, see
00023 //  <http://www.gnu.org/licenses/>.
00024 //
00025 //  $Revision: 2398 $
00026 //
00027 //  $LastChangedDate: 2010-10-05 14:54:37 -0700 (Tue, 05 Oct 2010) $
00028 //
00029 //  $LastChangedBy: torstenrohlfing $
00030 //
00031 */
00032 
00033 #include "cmtkPGM.h"
00034 
00035 #include <System/cmtkCompressedStream.h>
00036 #include <System/cmtkConsole.h>
00037 
00038 #include <stdlib.h>
00039 #include <string.h>
00040 
00041 #ifdef HAVE_MALLOC_H
00042 #  include <malloc.h>
00043 #endif
00044 
00045 #ifndef isspace
00046 #define isspace(c)      ((c=='\t') || (c==' ') || (c=='\n'))
00047 #endif
00048 
00049 namespace
00050 cmtk
00051 {
00052 
00055 
00056 ScalarImage* 
00057 PGM::Read( const char* filename ) 
00058 {
00059   CompressedStream stream(filename);
00060   if ( ! stream.IsValid() ) 
00061     {
00062     StdErr.printf( "File %s could not be opened.", filename );
00063     return NULL;
00064     }
00065   
00066   Types::Coordinate pixelSize[2] = { 1, 1 };
00067   
00068   int i;
00069   char c, fileID[3], line[1024];
00070   stream.Get(fileID[0]); 
00071   stream.Get(fileID[1]);
00072   stream.Get(c);
00073   
00074   do
00075     {
00076     stream.Get(line[0]);
00077     if (line[0]=='#') 
00078       {
00079       int idx = 1;
00080       c=0;
00081       while (c != '\n') { stream.Get(c); line[idx++] = c; }
00082       }
00083     float tmpf0, tmpf1;
00084     if ( sscanf( line, "# calibration %f %f", &tmpf0, &tmpf1 ) == 2 ) 
00085       {
00086       pixelSize[0] = tmpf0;
00087       pixelSize[1] = tmpf1;
00088       } 
00089     else
00090       {
00091       if ( sscanf( line, "# tablepos %f", &tmpf0 ) == 1 ) 
00092         {
00093         }
00094       }
00095     } while (line[0]=='#');
00096   
00097   i = 1;
00098   for ( int spaces=0; spaces<3; ++i ) 
00099     {
00100     stream.Get(line[i]);
00101     if (isspace(line[i]))
00102       ++spaces;
00103     }
00104   line[i]=0;
00105   
00106   unsigned int dimsx, dimsy, maxvalue;
00107   sscanf( line, "%d%d%d", &dimsx , &dimsy, &maxvalue );
00108   
00109   int bytesperpixel = 1;
00110   while (maxvalue > 255) 
00111     {
00112     ++bytesperpixel;
00113     maxvalue /= 256;
00114     }
00115   
00116   int dim = dimsx * dimsy;
00117   
00118   TypedArray::SmartPtr pixelData;
00119   switch ( bytesperpixel ) 
00120     {
00121     case 1:
00122       pixelData = TypedArray::Create( TYPE_BYTE, dim );
00123       break;
00124     case 2:
00125       pixelData = TypedArray::Create( TYPE_USHORT, dim );
00126       break;
00127     case 4:
00128       pixelData = TypedArray::Create( TYPE_INT, dim );
00129       break;
00130     default:
00131       return NULL;
00132     }
00133   stream.Read( pixelData->GetDataPtr(), bytesperpixel, dim);
00134   
00135   ScalarImage *image = new ScalarImage( dimsx, dimsy );
00136   image->SetPixelSize( pixelSize );
00137   image->SetPixelData( TypedArray::SmartPtr( pixelData ) );
00138   
00139   return image;
00140 }
00141 
00142 void
00143 PGM::Write
00144 ( const char* filename, const ScalarImage *image, const Types::DataItem greyFrom, const Types::DataItem greyTo )
00145 {
00146   const size_t numberOfPixels = image->GetNumberOfPixels();
00147   byte *pgmData = Memory::AllocateArray<byte>(  numberOfPixels  );
00148 
00149   const TypedArray *pixelData = image->GetPixelData();
00150 
00151   const Types::DataItem greyScale = 255.0 / (greyTo - greyFrom);
00152   
00153   for ( unsigned int i = 0; i < numberOfPixels; ++i ) 
00154     {
00155     Types::DataItem pixel;
00156     if ( pixelData->Get( pixel, i ) ) 
00157       {
00158       if ( pixel <= greyFrom )
00159         pgmData[i] = 0;
00160       else
00161         if ( pixel >= greyTo )
00162           pgmData[i] = 255;
00163         else
00164           pgmData[i] = static_cast<byte>( (pixel - greyFrom) * greyScale );
00165       }
00166     }
00167   
00168   FILE *fp = fopen( filename, "wb" );
00169   if ( fp ) 
00170     {
00171     fprintf( fp, "P5\n" );
00172     fprintf( fp, "# calibration %f %f\n", image->GetPixelSize()[0], image->GetPixelSize()[1] );
00173     fprintf( fp, "# tablepos %f \n", image->GetImageSlicePosition() );
00174     
00175     fprintf( fp, "%d %d %d\n", image->GetDims()[0], image->GetDims()[1], 255 );
00176     
00177     fwrite( pgmData, 1, numberOfPixels, fp );
00178     
00179     fclose(fp);
00180     }
00181 
00182   Memory::DeleteArray( pgmData );
00183 }
00184 
00185 void
00186 PGM::Write16bit( const char* filename, const ScalarImage *image, const Types::DataItem greyFrom, const Types::DataItem greyTo )
00187 {
00188   const size_t numberOfPixels = image->GetNumberOfPixels();
00189   
00190   const TypedArray *pixelData = image->GetPixelData();
00191 
00192   const Types::DataItem greyScale = 255.0 / (greyTo - greyFrom);
00193   
00194   unsigned short *pgmData = Memory::AllocateArray<unsigned short>(  numberOfPixels  );
00195   unsigned short maxData = 0;
00196   for ( size_t i = 0; i < numberOfPixels; ++i ) 
00197     {
00198     Types::DataItem pixel;
00199     if ( pixelData->Get( pixel, i ) ) 
00200       {
00201       if ( pixel <= greyFrom )
00202         pixel = 0;
00203       else
00204         if ( pixel >= greyTo )
00205           pixel = 65535;
00206         else
00207           pixel = (pixel - greyFrom) * greyScale;
00208       
00209       // gthumb and ImageMagick want 16bit pgm in little endian, so let's do it if necessary
00210 #ifdef WORDS_BIGENDIAN
00211       const unsigned short tmp = static_cast<unsigned short>( pixel );
00212       pgmData[i] = ((tmp&255)<<8) + (tmp>>8);
00213 #else
00214       pgmData[i] = static_cast<unsigned short>( pixel );
00215 #endif
00216       }
00217     else
00218       {
00219       pgmData[i] = 0;
00220       }
00221     maxData = std::max( maxData, pgmData[i] );
00222     }
00223   
00224   FILE *fp = fopen( filename, "wb" );
00225   if ( fp ) 
00226     {
00227     fprintf( fp, "P5\n" );
00228     fprintf( fp, "# calibration %f %f\n", image->GetPixelSize()[0], image->GetPixelSize()[1] );
00229     fprintf( fp, "# tablepos %f \n", image->GetImageSlicePosition() );
00230     
00231     fprintf( fp, "%d %d %d\n", image->GetDims()[0], image->GetDims()[1], maxData );
00232     
00233     fwrite( pgmData, sizeof( *pgmData ), numberOfPixels, fp );
00234     fclose(fp);
00235     }
00236   
00237   Memory::DeleteArray( pgmData );
00238 }
00239 
00240 } // namespace cmtk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines