TePDIColorTransform.cpp

Go to the documentation of this file.
00001 #include "TePDIColorTransform.hpp"
00002 
00003 #include "../kernel/TeAgnostic.h"
00004 #include "TePDIUtils.hpp"
00005 #include "TePDIMatrix.hpp"
00006 #include "../kernel/TeDefines.h"
00007 
00008 #ifndef M_PI
00009   #define M_PI       3.14159265358979323846
00010 #endif
00011 
00012 
00013 TePDIColorTransform::TePDIColorTransform()
00014 {
00015 }
00016 
00017 
00018 TePDIColorTransform::~TePDIColorTransform()
00019 {
00020 }
00021 
00022 
00023 void TePDIColorTransform::ResetState( const TePDIParameters& )
00024 {
00025 }
00026 
00027 
00028 bool TePDIColorTransform::CheckParameters( 
00029   const TePDIParameters& parameters ) const
00030 {
00031   /* Checking transformation type */
00032   
00033   ColorTransfTypes transf_type;
00034   TEAGN_TRUE_OR_RETURN( parameters.GetParameter( "transf_type", transf_type ),
00035     "Missing parameter: transf_type" );
00036   TEAGN_TRUE_OR_RETURN(
00037     ( ( transf_type == Rgb2Ihs ) || ( transf_type == Ihs2Rgb ) ),
00038     "Invalid parameter: transf_type" );
00039     
00040   /* Checking input_rasters and input_channels */
00041   
00042   TePDITypes::TePDIRasterVectorType input_rasters;
00043   TEAGN_TRUE_OR_RETURN( 
00044     parameters.GetParameter( "input_rasters", input_rasters ),
00045     "Missing parameter: input_rasters" );
00046     
00047   TEAGN_TRUE_OR_RETURN( ( input_rasters.size() == 3 ),
00048     "Invalid number of input rasters" );    
00049     
00050   std::vector< int > input_channels;
00051   TEAGN_TRUE_OR_RETURN( 
00052     parameters.GetParameter( "input_channels", input_channels ),
00053     "Missing parameter: input_channels" );
00054     
00055   TEAGN_TRUE_OR_RETURN( ( input_channels.size() == 3 ), 
00056     "Invalid number of input channels" );
00057     
00058   for( unsigned int index = 0 ; index < input_rasters.size() ; ++index ) {
00059     TEAGN_TRUE_OR_RETURN( input_rasters[ index ].isActive(),
00060       "Invalid parameter: raster " + 
00061       Te2String( index ) + " inactive" );
00062       
00063     TEAGN_TRUE_OR_RETURN( 
00064       input_rasters[ index ]->params().status_ != TeRasterParams::TeNotReady,
00065       "Invalid parameter: raster " + 
00066       Te2String( index ) + " not ready" );
00067         
00068     TEAGN_TRUE_OR_RETURN( 
00069       input_rasters[ 0 ]->params().nlines_ == 
00070       input_rasters[ index ]->params().nlines_,
00071       "Lines number mismatch between raster 0 and raster " +
00072       Te2String( index ) );
00073       
00074     TEAGN_TRUE_OR_RETURN( 
00075       input_rasters[ 0 ]->params().ncols_ == 
00076       input_rasters[ index ]->params().ncols_,
00077       "Columns number mismatch between raster 0 and raster " +
00078       Te2String( index ) );
00079             
00080     TEAGN_TRUE_OR_RETURN( 
00081       input_channels[ index ] >= 0, "Invalid channel number (" + 
00082       Te2String( index ) + ")" );
00083     TEAGN_TRUE_OR_RETURN( 
00084       input_channels[ index ] < input_rasters[ index ]->nBands(), 
00085       "Invalid channel number (" + 
00086       Te2String( index ) + ")" );
00087       
00088     /* Checking photometric interpretation */
00089     
00090     TEAGN_TRUE_OR_RETURN( ( 
00091       ( input_rasters[ index ]->params().photometric_[ 
00092         input_channels[ index ] ] == TeRasterParams::TeRGB ) ||
00093       ( input_rasters[ index ]->params().photometric_[ 
00094         input_channels[ index ] ] == TeRasterParams::TeMultiBand ) ),
00095       "Invalid parameter - rasters (invalid photometric "
00096       "interpretation)" );      
00097   }    
00098   
00099   /* Checking output_rasters */
00100   
00101   TePDITypes::TePDIRasterVectorType output_rasters;
00102   TEAGN_TRUE_OR_RETURN( 
00103     parameters.GetParameter( "output_rasters", output_rasters ),
00104     "Missing parameter: output_rasters" );
00105     
00106   TEAGN_TRUE_OR_RETURN( ( ( output_rasters.size() == 3 ) ||
00107     ( output_rasters.size() == 1 ) ), 
00108     "Invalid number of output rasters" );
00109     
00110   for( unsigned int index = 0 ; index < output_rasters.size() ; ++index ) {
00111     TEAGN_TRUE_OR_RETURN( output_rasters[ index ].isActive(),
00112       "Invalid parameter: output raster " + 
00113       Te2String( index ) + " inactive" );
00114       
00115     TEAGN_TRUE_OR_RETURN( 
00116       output_rasters[ index ]->params().status_ != TeRasterParams::TeNotReady,
00117       "Invalid parameter: output raster " + 
00118       Te2String( index ) + " not ready" );
00119       
00120     if( ( index != 0 ) && ( output_rasters.size() != 1 ) ) {
00121       TEAGN_TRUE_OR_RETURN( 
00122         ( output_rasters[ 0 ] != output_rasters[ index ] ),
00123         "Cannot use the same output raster two more times" );    
00124     }
00125     
00126     /* Checking input data type */
00127     
00128     if( transf_type == Rgb2Ihs ) {
00129       TEAGN_TRUE_OR_RETURN( 
00130         (
00131           ( 
00132             output_rasters[ index ]->params().dataType_[ 0 ] == TeDOUBLE 
00133           )
00134           ||
00135           (
00136             output_rasters[ index ]->params().dataType_[ 0 ] == TeFLOAT 
00137           )
00138         ), "Invalid output rasters data type" );  
00139     }      
00140   }     
00141   
00142   /* Checking  rgb_channels_min and rgbs_channel_max */
00143   
00144   if( ( transf_type == Ihs2Rgb ) || ( transf_type == Rgb2Ihs ) ) {
00145     double rgb_channels_min = 0;
00146     TEAGN_TRUE_OR_RETURN( 
00147       parameters.GetParameter( "rgb_channels_min", rgb_channels_min ),
00148       "Missing parameter: rgbs_channels_min" );  
00149       
00150     double rgb_channels_max = 0;
00151     TEAGN_TRUE_OR_RETURN( 
00152       parameters.GetParameter( "rgb_channels_max", rgb_channels_max ),
00153       "Missing parameter: rgb_channels_max" );    
00154       
00155     TEAGN_TRUE_OR_RETURN( 
00156       ( rgb_channels_max > rgb_channels_min ),
00157       "Invalid parameters: rgb_channels_max - rgb_channels_min" );       
00158   }
00159   
00160   return true;
00161 }
00162 
00163 
00164 bool TePDIColorTransform::RunImplementation()
00165 {
00166   TePDITypes::TePDIRasterVectorType input_rasters;
00167   params_.GetParameter( "input_rasters", input_rasters );
00168     
00169   std::vector< int > input_channels;
00170   params_.GetParameter( "input_channels", input_channels );
00171   
00172   TePDITypes::TePDIRasterVectorType output_rasters;
00173   params_.GetParameter( "output_rasters", output_rasters );
00174 
00175   ColorTransfTypes transf_type;
00176   params_.GetParameter( "transf_type", transf_type );
00177   
00178   std::vector< int > output_channels;
00179   
00180   /* Updating output raster geometries */
00181   
00182   TeRaster& ref_input_raster = *(input_rasters[ 0 ].nakedPointer() );
00183   
00184   if( output_rasters.size() == 1 ) {
00185     TeRaster& output_raster = *( output_rasters[ 0 ].nakedPointer() );
00186     
00187     /* Generating the new output raster parameters */
00188     
00189     TeRasterParams output_raster_params = output_raster.params();
00190     
00191     output_raster_params.nBands( 3 );
00192     if( ref_input_raster.projection() != 0 ) {
00193       output_raster_params.projection( ref_input_raster.projection() );
00194     }
00195     output_raster_params.boxLinesColumns( 
00196       ref_input_raster.params().box().x1(), 
00197       ref_input_raster.params().box().y1(), 
00198       ref_input_raster.params().box().x2(), 
00199       ref_input_raster.params().box().y2(), 
00200       ref_input_raster.params().nlines_, 
00201       ref_input_raster.params().ncols_ );
00202       
00203     switch( transf_type ) {
00204       case Rgb2Ihs :
00205       {
00206         output_raster_params.setPhotometric( TeRasterParams::TeMultiBand, -1 );
00207 
00208         break;
00209       }
00210       case Ihs2Rgb :
00211       {
00212         output_raster_params.setPhotometric( TeRasterParams::TeRGB, -1 );
00213 
00214         break;
00215       }
00216       default :
00217       {
00218         TEAGN_LOG_AND_RETURN( "Invalid transformation type" );
00219         break;
00220       }
00221     }      
00222       
00223     TEAGN_TRUE_OR_RETURN( output_raster.init( output_raster_params ),
00224       "Output raster reset error" );  
00225       
00226     /* updating the output_channels vector */
00227       
00228     output_channels.push_back( 0 );
00229     output_channels.push_back( 1 );
00230     output_channels.push_back( 2 );     
00231     
00232      /* updating the output_channels vector */
00233 
00234     output_rasters.push_back( output_rasters[ 0 ] );   
00235     output_rasters.push_back( output_rasters[ 0 ] );
00236   } else {
00237     /* output_rasters.size() == 3 */
00238     
00239     for( unsigned int index = 0 ; index < output_rasters.size() ; ++index ) {
00240       TeRaster& output_raster = *( output_rasters[ index ].nakedPointer() );
00241       
00242       /* Generating the new output raster parameters */
00243       
00244       TeRasterParams output_raster_params = output_raster.params();
00245       
00246       output_raster_params.nBands( 1 );
00247       if( ref_input_raster.projection() != 0 ) {
00248         output_raster_params.projection( ref_input_raster.projection() );
00249       }
00250       output_raster_params.boxLinesColumns( 
00251         ref_input_raster.params().box().x1(), 
00252         ref_input_raster.params().box().y1(), 
00253         ref_input_raster.params().box().x2(), 
00254         ref_input_raster.params().box().y2(), 
00255         ref_input_raster.params().nlines_, 
00256         ref_input_raster.params().ncols_ );  
00257       switch( transf_type ) {
00258         case Rgb2Ihs :
00259         {
00260           output_raster_params.setPhotometric( TeRasterParams::TeMultiBand, -1 );
00261 
00262           break;
00263         }
00264         case Ihs2Rgb :
00265         {
00266           output_raster_params.setPhotometric( TeRasterParams::TeRGB, -1 );
00267 
00268           break;
00269         }
00270         default :
00271         {
00272           TEAGN_LOG_AND_RETURN( "Invalid transformation type" );
00273           break;
00274         }
00275       }           
00276         
00277       TEAGN_TRUE_OR_RETURN( output_raster.init( output_raster_params ),
00278         "Output raster reset error" );  
00279     }
00280 
00281     /* updating the output_channels vector */
00282       
00283     output_channels.push_back( 0 );
00284     output_channels.push_back( 0 );
00285     output_channels.push_back( 0 );       
00286   }
00287     
00288   /* Calling the required color conversion */  
00289 
00290   switch( transf_type ) {
00291     case Rgb2Ihs :
00292     {
00293       double rgb_channels_min = 0;
00294       params_.GetParameter( "rgb_channels_min", rgb_channels_min );
00295         
00296       double rgb_channels_max = 0;
00297       params_.GetParameter( "rgb_channels_max", rgb_channels_max );
00298           
00299       return RunRgb2Ihs( input_rasters, input_channels, output_rasters,
00300         output_channels, rgb_channels_min, rgb_channels_max );
00301       break;
00302     }
00303     case Ihs2Rgb :
00304     {
00305       double rgb_channels_min = 0;
00306       params_.GetParameter( "rgb_channels_min", rgb_channels_min );
00307         
00308       double rgb_channels_max = 0;
00309       params_.GetParameter( "rgb_channels_max", rgb_channels_max );
00310          
00311       return RunIhs2Rgb( input_rasters, input_channels, output_rasters,
00312         output_channels, rgb_channels_min, rgb_channels_max );
00313       break;
00314     }
00315     default :
00316     {
00317       TEAGN_LOG_AND_RETURN( "Invalid transformation type" );
00318       break;
00319     }
00320   }
00321 
00322   return false;
00323 }
00324 
00325 
00326 bool TePDIColorTransform::RunRgb2Ihs(
00327   TePDITypes::TePDIRasterVectorType& input_rasters,
00328   std::vector< int >& input_channels,
00329   TePDITypes::TePDIRasterVectorType& output_rasters,
00330   std::vector< int >& output_channels,
00331   const double rgb_channels_min, const double rgb_channels_max )
00332 {
00333   TEAGN_DEBUG_CONDITION( ( input_rasters.size() == 3 ),
00334     "Invalid vector size" )
00335   TEAGN_DEBUG_CONDITION( ( input_channels.size() == 3 ),
00336     "Invalid vector size" )
00337   TEAGN_DEBUG_CONDITION( ( output_rasters.size() == 3 ),
00338     "Invalid vector size" )
00339   TEAGN_DEBUG_CONDITION( ( output_channels.size() == 3 ),
00340     "Invalid vector size" )
00341   TEAGN_DEBUG_CONDITION( ( rgb_channels_max >= rgb_channels_min ),
00342     "Invalid rgb channels max/min" )    
00343                 
00344   /* Extracting local references */
00345   
00346   TeRaster& input_raster0 = *( input_rasters[ 0 ].nakedPointer() ); 
00347   TeRaster& input_raster1 = *( input_rasters[ 1 ].nakedPointer() ); 
00348   TeRaster& input_raster2 = *( input_rasters[ 2 ].nakedPointer() );
00349   
00350   const int input_channel0 = input_channels[ 0 ];
00351   const int input_channel1 = input_channels[ 1 ];
00352   const int input_channel2 = input_channels[ 2 ];
00353   
00354   TeRaster& output_raster0 = *( output_rasters[ 0 ].nakedPointer() ); 
00355   TeRaster& output_raster1 = *( output_rasters[ 1 ].nakedPointer() ); 
00356   TeRaster& output_raster2 = *( output_rasters[ 2 ].nakedPointer() );
00357   
00358   const int output_channel0 = output_channels[ 0 ];
00359   const int output_channel1 = output_channels[ 1 ];
00360   const int output_channel2 = output_channels[ 2 ];    
00361   
00362   const unsigned int lines = ( unsigned int ) input_raster0.params().nlines_;
00363   const unsigned int columns = ( unsigned int ) 
00364     input_raster0.params().ncols_;
00365     
00366   const double rgb_channels_diff = rgb_channels_max - rgb_channels_min;
00367   const double rgb_channels_norm_fac = ( rgb_channels_diff != 0.0 ) ? 
00368     rgb_channels_diff : 1.0;
00369   
00370   /* Dummy use definition */
00371   
00372   double out_raster_dummy = 0;
00373   if( output_raster0.params().useDummy_ ) {
00374     out_raster_dummy = output_raster0.params().dummy_[ 0 ];
00375   }
00376   
00377   /* Generating the non-normalized ihs matrixes */
00378   
00379   double red = 0, green = 0, blue = 0;
00380   double hue = 0, sat = 0, light = 0;  
00381   unsigned int line = 0;
00382   unsigned int column = 0;
00383   double teta = 0;
00384   double red_norm = 0, green_norm = 0, blue_norm = 0;
00385   double r_minus_g = 0, r_minus_b = 0;
00386   double rgb_sum = 0;
00387   double cosvalue = 0;
00388   const double two_pi = 2.0 * ((double)M_PI);
00389   const double pi_rat_2 = ((double)M_PI) / 2.0;
00390   
00391   TePDIPIManager progress( "Converting RGB -> IHS...", lines,
00392     progress_enabled_ ); 
00393 
00394   for( line = 0 ; line < lines ; ++line ) {
00395     for( column = 0 ; column < columns ; ++column ) {
00396       if( input_raster0.getElement( column, line, red, input_channel0 ) && 
00397         input_raster1.getElement( column, line, green, input_channel1 ) &&
00398         input_raster2.getElement( column, line, blue, input_channel2 ) ) 
00399       {
00400         if( ( red == green ) && ( green == blue ) ) 
00401         { // Gray scale case
00402           // From Wikipedia:
00403           // h = 0 is used for grays though the hue has no geometric 
00404           // meaning there, where the saturation s = 0. Similarly, 
00405           // the choice of 0 as the value for s when l is equal to 0 or 1 
00406           // is arbitrary.        
00407           
00408           hue = sat = 0.0;
00409           light = ( red / rgb_channels_norm_fac ); // or green or blue since they all are the same.
00410         }
00411         else
00412         { // Color case
00413           red_norm = ( red - rgb_channels_min ) / rgb_channels_norm_fac;
00414           green_norm = ( green - rgb_channels_min ) / rgb_channels_norm_fac;
00415           blue_norm = ( blue - rgb_channels_min ) / rgb_channels_norm_fac;
00416           
00417           r_minus_g = red_norm - green_norm;
00418           r_minus_b = red_norm - blue_norm;
00419           
00420           cosvalue = sqrt( ( r_minus_g * r_minus_g ) + ( r_minus_b * 
00421             ( green_norm - blue_norm ) ) );
00422             
00423           if( cosvalue == 0.0 )
00424           {
00425             teta = pi_rat_2;
00426           }
00427           else
00428           {
00429             cosvalue =  ( 0.5 * ( r_minus_g + r_minus_b )  ) /
00430               cosvalue;
00431             teta = acos( cosvalue );  
00432           }
00433             
00434           TEAGN_DEBUG_CONDITION( ( cosvalue >= (-1.0) ) &&
00435             ( cosvalue <= (1.0) ), "Invalid cosvalue value"
00436             " cosvalue=" + Te2String( cosvalue, 9 )
00437             + " red_norm=" + Te2String( red_norm, 9 )
00438             + " green_norm=" + Te2String( green_norm, 9 )
00439             + " blue_norm=" + Te2String( blue_norm, 9 )
00440             + " r_minus_g=" + Te2String( r_minus_g, 9 )
00441             + " r_minus_b=" + Te2String( r_minus_b, 9 )
00442             + " rgb_channels_min=" + Te2String( rgb_channels_min, 9 ) 
00443             + " rgb_channels_norm_fac=" + Te2String( rgb_channels_norm_fac, 9 )  
00444             );
00445             
00446           if( blue_norm > green_norm )
00447           {
00448             hue = two_pi - teta;
00449           }
00450           else
00451           {
00452             hue = teta;
00453           }
00454             
00455           rgb_sum = red_norm + green_norm + blue_norm;
00456           
00457           sat = 1.0 - ( 3 * MIN( MIN( red_norm, green_norm ), blue_norm ) /
00458             rgb_sum );
00459             
00460           light = rgb_sum / 3.0;
00461         }
00462       } else {
00463         hue = sat = light = 0.0;
00464       }
00465       
00466       TEAGN_TRUE_OR_RETURN( output_raster0.setElement(
00467         column, line, light, output_channel0 ),
00468         "Unable to write intensity channel for output_image" );
00469       TEAGN_TRUE_OR_RETURN( output_raster1.setElement(
00470         column, line, hue, output_channel1 ),
00471         "Unable to write hue channel for output_image" );
00472       TEAGN_TRUE_OR_RETURN( output_raster2.setElement(
00473         column, line, sat, output_channel2 ),
00474         "Unable to write saturation channel for output_image" ); 
00475     }
00476     
00477     TEAGN_FALSE_OR_RETURN( progress.Increment(), 
00478       "Canceled by the user" );    
00479   }
00480   
00481   return true;
00482 }
00483 
00484 
00485 bool TePDIColorTransform::RunIhs2Rgb(
00486   TePDITypes::TePDIRasterVectorType& input_rasters,
00487   std::vector< int >& input_channels,
00488   TePDITypes::TePDIRasterVectorType& output_rasters,
00489   std::vector< int >& output_channels,
00490   const double rgb_channels_min, const double rgb_channels_max )
00491 {
00492   TEAGN_TRUE_OR_THROW( ( input_rasters.size() == 3 ),
00493     "Invalid vector size" )
00494   TEAGN_TRUE_OR_THROW( ( input_channels.size() == 3 ),
00495     "Invalid vector size" )
00496   TEAGN_TRUE_OR_THROW( ( output_rasters.size() == 3 ),
00497     "Invalid vector size" )
00498   TEAGN_TRUE_OR_THROW( ( output_channels.size() == 3 ),
00499     "Invalid vector size" )
00500                 
00501   /* Extracting local references */
00502   
00503   TeRaster& input_raster0 = *( input_rasters[ 0 ].nakedPointer() ); 
00504   TeRaster& input_raster1 = *( input_rasters[ 1 ].nakedPointer() ); 
00505   TeRaster& input_raster2 = *( input_rasters[ 2 ].nakedPointer() );
00506   
00507   const int input_channel0 = input_channels[ 0 ];
00508   const int input_channel1 = input_channels[ 1 ];
00509   const int input_channel2 = input_channels[ 2 ];
00510   
00511   TeRaster& output_raster0 = *( output_rasters[ 0 ].nakedPointer() ); 
00512   TeRaster& output_raster1 = *( output_rasters[ 1 ].nakedPointer() ); 
00513   TeRaster& output_raster2 = *( output_rasters[ 2 ].nakedPointer() );
00514   
00515   int output_channel0 = output_channels[ 0 ];
00516   int output_channel1 = output_channels[ 1 ];
00517   int output_channel2 = output_channels[ 2 ];  
00518     
00519   unsigned int lines = ( unsigned int ) input_raster0.params().nlines_;
00520   unsigned int columns = ( unsigned int ) input_raster0.params().ncols_;
00521 
00522   const double rgb_channels_diff = rgb_channels_max - rgb_channels_min;
00523   const double rgb_channels_norm_fac = ( rgb_channels_diff != 0.0 ) ? 
00524     rgb_channels_diff : 1.0;  
00525  
00526   /* Dummy use definition */
00527   
00528   double out_raster_dummy = 0;
00529   if( output_raster0.params().useDummy_ ) {
00530     out_raster_dummy = output_raster0.params().dummy_[ 0 ];
00531   }
00532   
00533   /* Raster convertion */
00534   
00535   const double pi_rat3 = M_PI / 3.0; // 60
00536   const double two_pi_rat3 = 2.0 * M_PI / 3.0; // 120
00537   const double four_pi_rat3 = 4.0 * M_PI / 3.0; // 240
00538   
00539   double red = 0, green = 0, blue = 0;
00540   double hue = 0, sat = 0, lig = 0;
00541   
00542   StartProgInt( "Converting IHS -> RGB...", lines );
00543   
00544   for( unsigned int line = 0 ; line < lines ; ++line ) {
00545     TEAGN_FALSE_OR_RETURN( UpdateProgInt( line ), "Canceled by the user" );
00546   
00547     for( unsigned int column = 0 ; column < columns ; ++column ) {
00548       if( input_raster0.getElement( column, line, lig, input_channel0 ) &&
00549           input_raster1.getElement( column, line, hue, input_channel1 ) &&
00550           input_raster2.getElement( column, line, sat, input_channel2 ) ) 
00551       {
00552         if( ( hue == 0.0 ) && ( sat == 0.0 ) )
00553         { // Gray scale case
00554           red = green = blue = ( lig * rgb_channels_norm_fac );
00555         }
00556         else
00557         { // color case
00558           /* Hue inside RG sector */
00559           if( hue < two_pi_rat3 )
00560           {
00561             blue = lig * ( 1.0 - sat );
00562             red = lig * ( 1.0 + ( sat * cos( hue ) / 
00563               cos( pi_rat3 - hue ) ) );
00564             green = ( 3.0 * lig ) - ( red + blue );
00565           }
00566           else if( hue < four_pi_rat3 )
00567           { /* Hue inside GB sector */
00568           
00569             hue -= two_pi_rat3;
00570             
00571             red = lig * ( 1.0 - sat );
00572             green = lig * ( 1.0 + ( sat * cos( hue ) / 
00573               cos( pi_rat3 - hue ) ) );
00574             blue = ( 3.0 * lig ) - ( red + green );
00575           }
00576           else
00577           { /* Hue inside BR sector */
00578           
00579             hue -= four_pi_rat3;
00580             
00581             green = lig * ( 1.0 - sat );
00582             blue = lig * ( 1.0 + ( sat * cos( hue ) / 
00583               cos( pi_rat3 - hue ) ) );
00584             red = ( 3.0 * lig ) - ( green + blue );
00585           }
00586           
00587           red = ( red * rgb_channels_norm_fac ) + rgb_channels_min;
00588           green = ( green * rgb_channels_norm_fac ) + rgb_channels_min;
00589           blue = ( blue * rgb_channels_norm_fac ) + rgb_channels_min;
00590         }
00591         
00592         red = MIN( red, rgb_channels_max );
00593         green = MIN( green, rgb_channels_max );
00594         blue = MIN( blue, rgb_channels_max );
00595         
00596         red = MAX( red, rgb_channels_min );
00597         green = MAX( green, rgb_channels_min );
00598         blue = MAX( blue, rgb_channels_min );        
00599   
00600         TEAGN_TRUE_OR_RETURN( output_raster0.setElement(
00601           column, line, red, output_channel0 ),
00602           "Unable to write red channel for output_image" );
00603         TEAGN_TRUE_OR_RETURN( output_raster1.setElement(
00604           column, line, green, output_channel1 ),
00605           "Unable to write green channel for output_image" );
00606         TEAGN_TRUE_OR_RETURN( output_raster2.setElement(
00607           column, line, blue, output_channel2 ),
00608           "Unable to write blue channel for output_image" );
00609       } else {                    
00610         TEAGN_TRUE_OR_RETURN( output_raster0.setElement(
00611           column, line, out_raster_dummy, output_channel0 ),
00612           "Unable to write red channel for output_image" );
00613         TEAGN_TRUE_OR_RETURN( output_raster1.setElement(
00614           column, line, out_raster_dummy, output_channel1 ),
00615           "Unable to write green channel for output_image" );
00616         TEAGN_TRUE_OR_RETURN( output_raster2.setElement(
00617           column, line, out_raster_dummy, output_channel2 ),
00618           "Unable to write blue channel for output_image" );
00619       }
00620     }
00621   }
00622 
00623   return true;
00624 }
00625 

Generated on Sun Jul 29 04:01:23 2012 for TerraLib - Development Source by  doxygen 1.5.3