Example #1
0
static Bool   
load( PImgCodec instance, PImgLoadFileInstance fi)
{
   dPROFILE;
   LoadRec * l = ( LoadRec *) fi-> instance;
   png_uint_32 width, height;
   int obd, bit_depth, color_type, interlace_type, bpp, number_passes, pass, filter;
   HV * profile;
   Color background;
   int alpha_opt, channels, trns_n;
   Bool icon;
   Handle alpha_image;
   png_bytep trns_t;
   png_color_16p trns_p;

   if (setjmp(png_jmpbuf( l-> png_ptr)) != 0) return false;

   profile = fi-> profile;

   png_read_info(l->png_ptr, l->info_ptr);

   png_get_IHDR(l->png_ptr, l->info_ptr, &width, &height, &bit_depth, &color_type,
       &interlace_type, NULL, &filter);
   obd = bit_depth;
   channels = (int) png_get_channels(l->png_ptr, l->info_ptr);
   icon = kind_of( fi-> object, CIcon);
   
   switch ( bit_depth) {
   case 1: case 4: case 8:
      break;
   case 2:
      png_set_packing(l->png_ptr);
      bit_depth = 4;
      break;
   case 16:   
      png_set_strip_16(l->png_ptr);
      bit_depth = 8;
      break;
   default:
      sprintf( fi-> errbuf, "Bit depth %d is not supported", bit_depth);
      return false;
   }

   
   switch ( color_type) {
   case PNG_COLOR_TYPE_GRAY:
      bpp = bit_depth | imGrayScale;
      break;
   case PNG_COLOR_TYPE_PALETTE:
      bpp = bit_depth;
      break;
   case PNG_COLOR_TYPE_RGB:
      png_set_bgr(l-> png_ptr);
      bpp = 24;
      break; 
   case PNG_COLOR_TYPE_GRAY_ALPHA:
      bpp = bit_depth | imGrayScale;
      break; 
   case PNG_COLOR_TYPE_RGB_ALPHA:
      png_set_bgr(l-> png_ptr);
      bpp = 24;
      break; 
   default:
      sprintf( fi-> errbuf, "Unknown file color type: %d", color_type);
      return false;
   }

   /* gamma stuff */
   {
      double screen_gamma = default_screen_gamma, gamma = 0.45455;
      Bool has_gamma = false;

      if ( pexist( screen_gamma)) {
         screen_gamma = pget_f( screen_gamma);
         if ( screen_gamma < PNG_GAMMA_THRESHOLD || screen_gamma > PNG_MAX_GAMMA) {
            sprintf( fi-> errbuf, "Error: screen_gamma value must be within %g..%g", PNG_GAMMA_THRESHOLD, (double)PNG_MAX_GAMMA);
            return false;
         } 
      }

#ifdef PNG_gAMA_SUPPORTED      
      if ( pexist( gamma)) {
         gamma = pget_f( gamma);
         if ( gamma < PNG_GAMMA_THRESHOLD || gamma > PNG_MAX_GAMMA) {
            sprintf( fi-> errbuf, "Error: gamma value must be within %g..%g", PNG_GAMMA_THRESHOLD, (double)PNG_MAX_GAMMA);
            return false;
         }
         has_gamma = true;
      } else if ( png_get_gAMA(l-> png_ptr, l-> info_ptr, &gamma)) {
         has_gamma = true;
      }
#endif      

      if ( has_gamma) png_set_gamma(l->png_ptr, screen_gamma, gamma);
   }

   /* alpha option */
   if ( pexist( alpha)) {
      char * c = pget_c( alpha);
      if ( stricmp( c, "blend") == 0) alpha_opt = ALPHA_OPT_BLEND; else
      if ( stricmp( c, "split") == 0) {
         if ( icon)
            outc("Alpha channel cannot be loaded to an Icon object")
         else
            alpha_opt = ALPHA_OPT_SPLIT; 
      } else
      if ( stricmp( c, "none") == 0)  alpha_opt = ALPHA_OPT_NONE;  else {
         snprintf( fi-> errbuf, 256, "unknown alpha option '%s'", c);
         return false;
      }
   } else
Example #2
0
File: fft.c Project: dk/IPA
PImage 
IPA__Global_band_filter(PImage img,HV *profile)
{
#define METHOD "IPA::Global::band_filter"
   dPROFILE;
   PImage ret;
   int spatial = 1, homomorph = 0, lw, failed = 0, LowPass = 0;
   double MinVal = 0.0, Power = 2.0, CutOff = 20.0, Boost = 0.7;
   double * data, * buffer = nil;
   
   
   if ( sizeof(double) % 2) {
      warn("%s:'double' is even-sized on this platform", METHOD);
      return nil;      
   }   
   if ( !img || !kind_of(( Handle) img, CImage))
     croak("%s: not an image passed", METHOD);

   if ( pexist( spatial))  spatial = pget_i( spatial);
   if ( pexist( homomorph)) homomorph = pget_i( homomorph);
   if ( pexist( power))  Power = pget_f( power);
   if ( pexist( cutoff)) CutOff = pget_f( cutoff);
   if ( pexist( boost))  Boost = pget_f( boost);
   if ( pexist( low))    LowPass = pget_i( low);
   if ( homomorph && !spatial)
      croak("%s:Cannot perform the homomorph equalization in the spatial domain", METHOD);
   if ( LowPass && ( CutOff < 0.0000001))
      croak("%s:cutoff is too small for low pass", METHOD);
   
   if ( !spatial && (( img-> type & imCategory) != imComplexNumber))
      croak("%s: not an im::DComplex image passed", METHOD); 
   
   ret = ( PImage) img-> self-> dup(( Handle) img);
   if ( !ret) fail( "%s: Return image allocation failed");
   ++SvREFCNT( SvRV( ret-> mate));
   if ( spatial) {
      ret-> self-> set_type(( Handle) ret, imDComplex);
      if ( ret-> type != imDComplex) {
          warn("%s: Cannot convert image to im::DComplex", METHOD);
          failed = 1;
          goto EXIT;
      }   
   }   

   data = ( double *) ret-> data;
   lw = ret-> w * 2;

   /* Take log of input image */
   if ( homomorph) {
      long i, k = ret-> w * ret-> h * 2;
      
      MinVal = *data;
      for ( i = 0; i < k; i += 2)
         if ( MinVal > data[i])
            MinVal = data[i];
      for ( i = 0; i < k; i += 2)
         data[i] = ( double) log(( double) ( 1.0 + data[i] - MinVal));
   }

   /* fft */
   if ( spatial) {
      if ( !pow2( img-> w))
         croak("%s: image width is not a power of 2", METHOD);
      if ( !pow2( img-> h))
         croak("%s: image height is not a power of 2", METHOD);
      buffer = malloc((sizeof(double) * ret-> w * 2));
      if ( !buffer) {
         warn("%s: Error allocating %d bytes", METHOD, (int)(sizeof(double) * img-> w * 2));
         failed = 1;
         goto EXIT;
      }   
      fft_2d( data, ret-> w, ret-> h, FFT_DIRECT, buffer);
   }   

   butterworth( data, ret-> w, ret-> h, homomorph, LowPass, Power, CutOff, Boost);

   /* inverse fft */
   if ( spatial) {
      fft_2d( data, ret-> w, ret-> h, FFT_INVERSE, buffer);
      free( buffer);
      buffer = nil;
   }   
   
   /* Take exp of input image */
   if ( homomorph) {
      long i, k = ret-> w * ret-> h * 2;
      for ( i = 0; i < k; i += 2)
         data[i] = ( double) ( exp( data[i]) - 1.0 + MinVal);
   }  

   /* converting type back */
   if ( spatial && ret-> self-> get_preserveType(( Handle) ret))
      ret-> self-> set_type(( Handle) ret, img-> type);
   
EXIT:   
   free( buffer);
   if ( ret)
      --SvREFCNT( SvRV( ret-> mate));           
   return failed ? nil : ret;
#undef METHOD   
}