/** * im_scaleps: * @in: input image * @out: output image * * Scale a power spectrum. Transform with log10(1.0 + pow(x, 0.25)) + .5, * then scale so max == 255. * * See also: im_scale(). * * Returns: 0 on success, -1 on error */ int im_scaleps( IMAGE *in, IMAGE *out ) { IMAGE *t[4]; double mx; double scale; if( im_open_local_array( out, t, 4, "im_scaleps-1", "p" ) || im_max( in, &mx ) ) return( -1 ); if( mx <= 0.0 ) /* Range of zero: just return black. */ return( im_black( out, in->Xsize, in->Ysize, in->Bands ) ); scale = 255.0 / log10( 1.0 + pow( mx, .25 ) ); /* Transform! */ if( im_powtra( in, t[0], 0.25 ) || im_lintra( 1.0, t[0], 1.0, t[1] ) || im_log10tra( t[1], t[2] ) || im_lintra( scale, t[2], 0.0, t[3] ) || im_clip2fmt( t[3], out, IM_BANDFMT_UCHAR ) ) return( -1 ); return( 0 ); }
/* Normalise an image using the rules noted above. */ static int normalise( IMAGE *in, IMAGE *out ) { if( im_check_uncoded( "im_histplot", in ) || im_check_noncomplex( "im_histplot", in ) ) return( -1 ); if( vips_bandfmt_isuint( in->BandFmt ) ) { if( im_copy( in, out ) ) return( -1 ); } else if( vips_bandfmt_isint( in->BandFmt ) ) { IMAGE *t1; double min; /* Move min up to 0. */ if( !(t1 = im_open_local( out, "im_histplot", "p" )) || im_min( in, &min ) || im_lintra( 1.0, in, -min, t1 ) ) return( -1 ); } else { /* Float image: scale min--max to 0--any. Output square * graph. */ IMAGE *t1; DOUBLEMASK *stats; double min, max; int any; if( in->Xsize == 1 ) any = in->Ysize; else any = in->Xsize; if( !(stats = im_stats( in )) ) return( -1 ); min = VIPS_MASK( stats, 0, 0 ); max = VIPS_MASK( stats, 1, 0 ); im_free_dmask( stats ); if( !(t1 = im_open_local( out, "im_histplot", "p" )) || im_lintra( any / (max - min), in, -min * any / (max - min), out ) ) return( -1 ); } return( 0 ); }
/** * im_grey: * @out: output image * @xsize: image size * @ysize: image size * * Create a one-band uchar image with the left-most column zero and the * right-most 255. Intermediate pixels are a linear ramp. * * See also: im_fgrey(), im_make_xy(), im_identity(). * * Returns: 0 on success, -1 on error */ int im_grey( IMAGE *out, const int xsize, const int ysize ) { IMAGE *t[2]; /* Change range to [0,255]. */ if( im_open_local_array( out, t, 2, "im_grey", "p" ) || im_fgrey( t[0], xsize, ysize ) || im_lintra( 255.0, t[0], 0.0, t[1] ) || im_clip2fmt( t[1], out, IM_BANDFMT_UCHAR ) ) return( -1 ); return( 0 ); }
/* As above, but make a IM_BANDFMT_UCHAR image. */ int im_zone( IMAGE *im, int size ) { IMAGE *t1 = im_open_local( im, "im_zone:1", "p" ); IMAGE *t2 = im_open_local( im, "im_zone:2", "p" ); if( !t1 || !t2 ) return( -1 ); if( im_fzone( t1, size ) || im_lintra( 127.5, t1, 127.5, t2 ) || im_clip2fmt( t2, im, IM_BANDFMT_UCHAR ) ) return( -1 ); return( 0 ); }
/** * im_gammacorrect: * @in: input image * @out: output image * @exponent: gamma factor * * Gamma-correct an 8- or 16-bit unsigned image with a lookup table. The * output format is the same as the input format. * * See also: im_identity(), im_powtra(), im_maplut() * * Returns: 0 on success, -1 on error */ int im_gammacorrect( IMAGE *in, IMAGE *out, double exponent ) { IMAGE *t[4]; double mx1, mx2; if( im_open_local_array( out, t, 4, "im_gammacorrect", "p" ) || im_check_u8or16( "im_gammacorrect", in ) || im_piocheck( in, out ) || (in->BandFmt == IM_BANDFMT_UCHAR ? im_identity( t[0], 1 ) : im_identity_ushort( t[0], 1, 65536 )) || im_powtra( t[0], t[1], exponent ) || im_max( t[0], &mx1 ) || im_max( t[1], &mx2 ) || im_lintra( mx1 / mx2, t[1], 0, t[2] ) || im_clip2fmt( t[2], t[3], in->BandFmt ) || im_maplut( in, out, t[3] ) ) return( -1 ); return( 0 ); }
/* The main part of the benchmark ... transform labq to labq. Chain several of * these together to get a CPU-bound operation. */ static int benchmark( IMAGE *in, IMAGE *out ) { IMAGE *t[18]; double one[3] = { 1.0, 1.0, 1.0 }; double zero[3] = { 0.0, 0.0, 0.0 }; double darken[3] = { 1.0 / 1.18, 1.0, 1.0 }; double whitepoint[3] = { 1.06, 1.0, 1.01 }; double shadow[3] = { -2, 0, 0 }; double white[3] = { 100, 0, 0 }; DOUBLEMASK *d652d50 = im_create_dmaskv( "d652d50", 3, 3, 1.13529, -0.0604663, -0.0606321, 0.0975399, 0.935024, -0.0256156, -0.0336428, 0.0414702, 0.994135 ); im_add_close_callback( out, (im_callback_fn) im_free_dmask, d652d50, NULL ); return( /* Set of descriptors for this operation. */ im_open_local_array( out, t, 18, "im_benchmark", "p" ) || /* Unpack to float. */ im_LabQ2Lab( in, t[0] ) || /* Crop 100 pixels off all edges. */ im_extract_area( t[0], t[1], 100, 100, t[0]->Xsize - 200, t[0]->Ysize - 200 ) || /* Shrink by 10%, bilinear interp. */ im_affinei_all( t[1], t[2], vips_interpolate_bilinear_static(), 0.9, 0, 0, 0.9, 0, 0 ) || /* Find L ~= 100 areas (white surround). */ im_extract_band( t[2], t[3], 0 ) || im_moreconst( t[3], t[4], 99 ) || /* Adjust white point and shadows. */ im_lintra_vec( 3, darken, t[2], zero, t[5] ) || im_Lab2XYZ( t[5], t[6] ) || im_recomb( t[6], t[7], d652d50 ) || im_lintra_vec( 3, whitepoint, t[7], zero, t[8] ) || im_lintra( 1.5, t[8], 0.0, t[9] ) || im_XYZ2Lab( t[9], t[10] ) || im_lintra_vec( 3, one, t[10], shadow, t[11] ) || /* Make a solid white image. */ im_black( t[12], t[4]->Xsize, t[4]->Ysize, 3 ) || im_lintra_vec( 3, zero, t[12], white, t[13] ) || /* Reattach border. */ im_ifthenelse( t[4], t[13], t[11], t[14] ) || /* Sharpen. */ im_Lab2LabQ( t[14], t[15] ) || im_sharpen( t[15], out, 11, 2.5, 40, 20, 0.5, 1.5 ) ); }
/* Fall back to vips's built-in fft. */ static int invfft1( IMAGE *dummy, IMAGE *in, IMAGE *out ) { int bpx = im_ispoweroftwo( in->Xsize ); int bpy = im_ispoweroftwo( in->Ysize ); float *buf, *q, *p1; int x, y; /* Buffers for real and imaginary parts. */ IMAGE *real = im_open_local( dummy, "invfft1:1", "t" ); IMAGE *imag = im_open_local( dummy, "invfft1:2", "t" ); /* Temps. */ IMAGE *t1 = im_open_local( dummy, "invfft1:3", "p" ); IMAGE *t2 = im_open_local( dummy, "invfft1:4", "p" ); if( !real || !imag || !t1 ) return( -1 ); if( im_pincheck( in ) || im_outcheck( out ) ) return( -1 ); if( in->Coding != IM_CODING_NONE || in->Bands != 1 || !im_iscomplex( in ) ) { im_error( "im_invfft", "%s", _( "one band complex uncoded only" ) ); return( -1 ); } if( !bpx || !bpy ) { im_error( "im_invfft", "%s", _( "sides must be power of 2" ) ); return( -1 ); } /* Make sure we have a single-precision complex input image. */ if( im_clip2fmt( in, t1, IM_BANDFMT_COMPLEX ) ) return( -1 ); /* Extract real and imag parts. We have to complement the imaginary. */ if( im_c2real( t1, real ) ) return( -1 ); if( im_c2imag( t1, t2 ) || im_lintra( -1.0, t2, 0.0, imag ) ) return( -1 ); /* Transform! */ if( im__fft_sp( (float *) real->data, (float *) imag->data, bpx - 1, bpy - 1 ) ) { im_error( "im_invfft", "%s", _( "fft_sp failed" ) ); return( -1 ); } /* WIO to out. */ if( im_cp_desc( out, in ) ) return( -1 ); out->BandFmt = IM_BANDFMT_FLOAT; if( im_setupout( out ) ) return( -1 ); if( !(buf = (float *) IM_ARRAY( dummy, IM_IMAGE_SIZEOF_LINE( out ), PEL )) ) return( -1 ); /* Just write real part. */ for( p1 = (float *) real->data, y = 0; y < out->Ysize; y++ ) { q = buf; for( x = 0; x < out->Xsize; x++ ) { q[x] = *p1++; } if( im_writeline( y, out, (PEL *) buf ) ) return( -1 ); } return( 0 ); }