00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
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
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 }