示例#1
0
/* Yuk! Have to malloc enough space for the whole image. Interlaced PNG
 * is not really suitable for large objects ...
 */
static int
png2vips_interlace( Read *read )
{
	const int rowbytes = IM_IMAGE_SIZEOF_LINE( read->out );
	int y;

	if( !(read->row_pointer = IM_ARRAY( NULL, 
		read->pInfo->height, png_bytep )) )
		return( -1 );
	if( !(read->data = (png_bytep) im_malloc( NULL,
		read->pInfo->height * rowbytes ))  )
		return( -1 );

	for( y = 0; y < (int) read->pInfo->height; y++ )
		read->row_pointer[y] = read->data + y * rowbytes;
	if( im_outcheck( read->out ) || 
		im_setupout( read->out ) || 
		setjmp( read->pPng->jmpbuf ) ) 
		return( -1 );

	png_read_image( read->pPng, read->row_pointer );

	for( y = 0; y < (int) read->pInfo->height; y++ )
		if( im_writeline( y, read->out, read->row_pointer[y] ) )
			return( -1 );

	return( 0 );
}
示例#2
0
/* Read an ascii 1 bit file.
 */
static int
read_1bit_ascii( FILE *fp, IMAGE *out )
{
	int x, y;
	PEL *buf;

	if( im_outcheck( out ) || im_setupout( out ) ||
		!(buf = IM_ARRAY( out, IM_IMAGE_SIZEOF_LINE( out ), PEL )) )
		return( -1 );

	for( y = 0; y < out->Ysize; y++ ) {
		for( x = 0; x < out->Xsize * out->Bands; x++ ) {
			int val;

			if( read_int( fp, &val ) )
				return( -1 );

			if( val == 1 )
				buf[x] = 0;
			else
				buf[x] = 255;
		}

		if( im_writeline( y, out, buf ) )
			return( -1 );
	}

	return( 0 );
}
示例#3
0
/**
 * im_buildlut:
 * @input: input mask
 * @output: output image
 *
 * This operation builds a lookup table from a set of points. Intermediate
 * values are generated by piecewise linear interpolation. 
 *
 * For example, consider this 2 x 2 matrix of (x, y) coordinates:
 *
 *   <tgroup cols='2' align='left' colsep='1' rowsep='1'>
 *     <tbody>
 *       <row>
 *         <entry>0</entry>
 *         <entry>0</entry>
 *       </row>
 *       <row>
 *         <entry>255</entry>
 *         <entry>100</entry>
 *       </row>
 *     </tbody>
 *   </tgroup>
 * 
 * We then generate:
 *
 *   <tgroup cols='2' align='left' colsep='1' rowsep='1'>
 *     <thead>
 *       <row>
 *         <entry>Index</entry>
 *         <entry>Value</entry>
 *       </row>
 *     </thead>
 *     <tbody>
 *       <row>
 *         <entry>0</entry>
 *         <entry>0</entry>
 *       </row>
 *       <row>
 *         <entry>1</entry>
 *         <entry>0.4</entry>
 *       </row>
 *       <row>
 *         <entry>...</entry>
 *         <entry>etc. by linear interpolation</entry>
 *       </row>
 *       <row>
 *         <entry>255</entry>
 *         <entry>100</entry>
 *       </row>
 *     </tbody>
 *   </tgroup>
 *
 * This is then written as the output image, with the left column giving the
 * index in the image to place the value.
 * 
 * The (x, y) points don't need to be sorted: we do that. You can have 
 * several Ys, each becomes a band in the output LUT. You don't need to
 * start at zero, any integer will do, including negatives.
 *
 * See also: im_identity(), im_invertlut().
 *
 * Returns: 0 on success, -1 on error
 */
int
im_buildlut( DOUBLEMASK *input, IMAGE *output )
{
	State state;

	if( !input || input->xsize < 2 || input->ysize < 1 ) {
		im_error( "im_buildlut", "%s", _( "bad input matrix size" ) );
		return( -1 );
	}

	if( build_state( &state, input ) ||
		buildlut( &state ) ) {
		free_state( &state );
                return( -1 );
	}

        im_initdesc( output,
                state.lut_size, 1, input->xsize - 1, 
		IM_BBITS_DOUBLE, IM_BANDFMT_DOUBLE,
                IM_CODING_NONE, IM_TYPE_HISTOGRAM, 1.0, 1.0, 0, 0 );
        if( im_setupout( output ) ||
		im_writeline( 0, output, (PEL *) state.buf ) ) {
		free_state( &state );
		return( -1 );
	}

	free_state( &state );

	return( 0 );
}
示例#4
0
/* Read a 1 bit binary file.
 */
static int
read_1bit_binary( FILE *fp, IMAGE *out )
{
	int x, y, i;
	int bits;
	PEL *buf;

	if( im_outcheck( out ) || im_setupout( out ) ||
		!(buf = IM_ARRAY( out, IM_IMAGE_SIZEOF_LINE( out ), PEL )) )
		return( -1 );

	bits = fgetc( fp );
	for( i = 0, y = 0; y < out->Ysize; y++ ) {
		for( x = 0; x < out->Xsize * out->Bands; x++, i++ ) {
			buf[x] = (bits & 128) ? 255 : 0;
			bits <<= 1;
			if( (i & 7) == 7 )
				bits = fgetc( fp );
		}

		if( im_writeline( y, out, buf ) )
			return( -1 );
	}

	return( 0 );
}
示例#5
0
static int
mat2vips_get_data( mat_t *mat, matvar_t *var, IMAGE *im )
{
	int y;
	PEL *buffer;
	const int es = IM_IMAGE_SIZEOF_ELEMENT( im );

	/* Matlab images are plane-separate, so we have to assemble bands in
	 * image-size chunks.
	 */
	const int is = es * im->Xsize * im->Ysize;

	if( Mat_VarReadDataAll( mat, var ) ) {
		im_error( "im_mat2vips", "%s", 
			_( "Mat_VarReadDataAll failed" ) );
		return( -1 );
	}
	if( im_outcheck( im ) ||
		im_setupout( im ) )
		return( -1 );

	/* Matlab images are in columns, so we have to transpose into
	 * scanlines with this buffer.
	 */
	if( !(buffer = IM_ARRAY( im, IM_IMAGE_SIZEOF_LINE( im ), PEL )) )
		return( -1 );

	for( y = 0; y < im->Ysize; y++ ) {
		const PEL *p = var->data + y * es;
		int x;
		PEL *q;

		q = buffer;
		for( x = 0; x < im->Xsize; x++ ) {
			int b;

			for( b = 0; b < im->Bands; b++ ) {
				const PEL *p2 = p + b * is;
				int z;

				for( z = 0; z < es; z++ )
					q[z] = p2[z];

				q += es;
			}

			p += es * im->Ysize;
		}

		if( im_writeline( y, im, buffer ) )
			return( -1 );
	}

	return( 0 );
}
示例#6
0
static int
hist_write( IMAGE *out, Histogram *hist )
{
	if( im_cp_descv( out, hist->index, hist->value, NULL ) ) 
		return( -1 );
	im_initdesc( out,
		hist->mx + 1, 1, hist->value->Bands, 
		IM_BBITS_DOUBLE, IM_BANDFMT_DOUBLE, 
		IM_CODING_NONE, IM_TYPE_HISTOGRAM, 1.0, 1.0, 0, 0 );
	if( im_setupout( out ) )
		return( -1 );

	if( im_writeline( 0, out, (PEL *) hist->bins ) )
		return( -1 );

	return( 0 );
}
示例#7
0
/* Read a cinfo to a VIPS image.
 */
static int
read_jpeg_image( struct jpeg_decompress_struct *cinfo, IMAGE *out, 
	gboolean invert_pels )
{
	int x, y, sz;
	JSAMPROW row_pointer[1];

	/* Check VIPS.
	 */
	if( im_outcheck( out ) || im_setupout( out ) )
		return( -1 );

	/* Get size of output line and make a buffer.
	 */
	sz = cinfo->output_width * cinfo->output_components;
	row_pointer[0] = (JSAMPLE *) (*cinfo->mem->alloc_large) 
		( (j_common_ptr) cinfo, JPOOL_IMAGE, sz );

	/* Start up decompressor.
	 */
	jpeg_start_decompress( cinfo );

	/* Process image.
	 */
	for( y = 0; y < out->Ysize; y++ ) {
		/* We set an error handler that longjmps() out, so I don't
		 * think this can fail.
		 */
		jpeg_read_scanlines( cinfo, &row_pointer[0], 1 );

		if( invert_pels ) {
			for( x = 0; x < sz; x++ )
				row_pointer[0][x] = 255 - row_pointer[0][x];
		}
		if( im_writeline( y, out, row_pointer[0] ) )
			return( -1 );
	}

	/* Stop decompressor.
	 */
	jpeg_finish_decompress( cinfo );

	return( 0 );
}
示例#8
0
/**
 * im_mask2vips:
 * @in: input mask
 * @out: output image
 *
 * Write a one-band, %IM_BANDFMT_DOUBLE image to @out based on mask @in.
 *
 * See also: im_vips2mask().
 *
 * Returns: 0 on success, -1 on error
 */
int
im_mask2vips( DOUBLEMASK *in, IMAGE *out )
{
	int x, y;
	double *buf, *p, *q;

	/* Check the mask.
	 */
	if( !in || !in->coeff ) {
		im_error( "im_mask2vips", "%s", _( "bad input mask" ) );
		return( -1 );
	}

	/* Make the output image.
	 */
	im_initdesc( out, in->xsize, in->ysize, 1, 
		IM_BBITS_DOUBLE, IM_BANDFMT_DOUBLE, 
		IM_CODING_NONE, 
		IM_TYPE_B_W, 
		1.0, 1.0, 
		0, 0 );
	if( im_setupout( out ) )
		return( -1 );

	/* Make an output buffer.
	 */
	if( !(buf = IM_ARRAY( out, in->xsize, double )) )
		return( -1 );

	/* Write!
	 */
	for( p = in->coeff, y = 0; y < out->Ysize; y++ ) {
		q = buf;

		for( x = 0; x < out->Xsize; x++ )
			*q++ = *p++;

		if( im_writeline( y, out, (void *) buf ) )
			return( -1 );
	}

	return( 0 );
}
示例#9
0
/* Read an ascii ppm/pgm file.
 */
static int
read_ascii( FILE *fp, IMAGE *out )
{
	int x, y;
	PEL *buf;

	if( im_outcheck( out ) || im_setupout( out ) ||
		!(buf = IM_ARRAY( out, IM_IMAGE_SIZEOF_LINE( out ), PEL )) )
		return( -1 );

	for( y = 0; y < out->Ysize; y++ ) {
		for( x = 0; x < out->Xsize * out->Bands; x++ ) {
			int val;

			if( read_int( fp, &val ) )
				return( -1 );
			
			switch( out->BandFmt ) {
			case IM_BANDFMT_UCHAR:
				buf[x] = IM_CLIP( 0, val, 255 );
				break;

			case IM_BANDFMT_USHORT:
				((unsigned short *) buf)[x] = 
					IM_CLIP( 0, val, 65535 );
				break;

			case IM_BANDFMT_UINT:
				((unsigned int *) buf)[x] = val;
				break;

			default:
				g_assert( 0 );
			}
		}

		if( im_writeline( y, out, buf ) )
			return( -1 );
	}

	return( 0 );
}
示例#10
0
int
im_fzone( IMAGE *image, int size )
{
	int x, y;
	int i, j;

	float *buf;
	const int size2 = size/2;

	/* Check args.
	 */
	if( im_outcheck( image ) )
		return( -1 );
	if( size <= 0 || (size % 2) != 0 ) {
		im_error( "im_zone", "%s", 
			_( "size must be even and positive" ) );
		return( -1 );
	}

	/* Set up output image.
	 */
        im_initdesc( image, size, size, 1, IM_BBITS_FLOAT, IM_BANDFMT_FLOAT,
		IM_CODING_NONE, IM_TYPE_B_W, 1.0, 1.0, 0, 0 );
        if( im_setupout( image ) )
                return( -1 );

	/* Create output buffer.
	 */
        if( !(buf = IM_ARRAY( image, size, float )) )
                return( -1 );

	/* Make zone plate.
	 */
	for( y = 0, j = -size2; j < size2; j++, y++ ) {
		for( x = 0, i = -size2; i < size2; i++, x++ )
			buf[x] = cos( (IM_PI / size) * (i * i + j * j) );
		if( im_writeline( y, image, (PEL *) buf ) )
			return( -1 );
	}

	return( 0 );
}
示例#11
0
/**
 * im_fav4:
 * @in: array of 4 input #IMAGE s
 * @out: output #IMAGE
 *
 * Average four identical images. 
 *
 * Deprecated.
*/
int
im_fav4( IMAGE **in, IMAGE *out)
{
	PEL *result, *buffer, *p1, *p2, *p3, *p4;
	int x,y;
	int linebytes, PICY;

/* check IMAGEs parameters 
*/
if(im_iocheck(in[1], out)) return(-1);

/* BYTE images only!
*/
if( (in[0]->BandFmt != IM_BANDFMT_CHAR) &&  (in[0]->BandFmt != IM_BANDFMT_UCHAR)) return(-1);

if ( im_cp_desc(out, in[1]) == -1)   /* copy image descriptors */
      return(-1);
if ( im_setupout(out) == -1)
      return(-1);

linebytes = in[0]->Xsize * in[0]->Bands;
PICY = in[0]->Ysize;
buffer = (PEL*)im_malloc(NULL,linebytes);
memset(buffer, 0, linebytes);

	p1 = (PEL*)in[0]->data;
	p2 = (PEL*)in[1]->data;
	p3 = (PEL*)in[2]->data;
	p4 = (PEL*)in[3]->data;

for (y = 0; y < PICY; y++)
	{
	result = buffer;
	/* average 4 pels with rounding, for whole line*/
	for (x = 0; x < linebytes; x++) {
		*result++ = (PEL)((int)((int)*p1++ + (int)*p2++ + (int)*p3++ + (int)*p4++ +2) >> 2);
		}
	im_writeline(y,out, buffer);
	}
im_free(buffer);
return(0);
}
示例#12
0
static int
lgrab_capture( LGrab *lg, IMAGE *im )
{
	int x, y;
	unsigned char *line;

	if( lgrab_capturen( lg ) )
		return( -1 );

	if( im_outcheck( im ) )
		return( -1 );
        im_initdesc( im, lg->c_width, lg->c_height, 3,
                IM_BBITS_BYTE, IM_BANDFMT_UCHAR,
                IM_CODING_NONE, IM_TYPE_MULTIBAND, 1.0, 1.0, 0, 0 );
        if( im_setupout( im ) )
                return( -1 );
	if( !(line = IM_ARRAY( im, 
		IM_IMAGE_SIZEOF_LINE( im ), unsigned char )) )
                return( -1 );

        for( y = 0; y < lg->c_height; y++ ) {
                unsigned char *p = (unsigned char *) lg->capture_buffer + 
			y * IM_IMAGE_SIZEOF_LINE( im );
                unsigned char *q = line;

		for( x = 0; x < lg->c_width; x++ ) {
			q[0] = p[2];
			q[1] = p[1];
			q[2] = p[0];

			p += 3;
			q += 3;
		}

                if( im_writeline( y, im, line ) )
                        return( -1 );
	}

	return( 0 );
}
示例#13
0
/* Noninterlaced images can be read without needing enough RAM for the whole
 * image.
 */
static int
png2vips_noninterlace( Read *read )
{
	const int rowbytes = IM_IMAGE_SIZEOF_LINE( read->out );
	int y;

	if( !(read->data = (png_bytep) im_malloc( NULL, rowbytes ))  )
		return( -1 );
	if( im_outcheck( read->out ) || 
		im_setupout( read->out ) || 
		setjmp( read->pPng->jmpbuf ) ) 
		return( -1 );

	for( y = 0; y < (int) read->pInfo->height; y++ ) {
		png_read_row( read->pPng, read->data, NULL );

		if( im_writeline( y, read->out, read->data ) )
			return( -1 );
	}

	return( 0 );
}
示例#14
0
/* 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 );
}
示例#15
0
文件: tone.c 项目: sepastian/libvips
/**
 * im_tone_build_range:
 * @out: output image
 * @in_max: input range
 * @out_max: output range
 * @Lb: black-point [0-100]
 * @Lw: white-point [0-100]
 * @Ps: shadow point (eg. 0.2)
 * @Pm: mid-tone point (eg. 0.5)
 * @Ph: highlight point (eg. 0.8)
 * @S: shadow adjustment (+/- 30)
 * @M: mid-tone adjustment (+/- 30)
 * @H: highlight adjustment (+/- 30)
 *
 * im_tone_build_range() generates a tone curve for the adjustment of image
 * levels. It is mostly designed for adjusting the L* part of a LAB image in
 * way suitable for print work, but you can use it for other things too.
 *
 * The curve is an unsigned 16-bit image with (@in_max + 1) entries,
 * each in the range [0, @out_max].
 *
 * @Lb, @Lw are expressed as 0-100, as in LAB colour space. You
 * specify the scaling for the input and output images with the @in_max and
 * @out_max parameters.
 *
 * See also: im_ismonotonic(), im_tone_map(), im_tone_analyse().
 *
 * Returns: 0 on success, -1 on error
 */
int
im_tone_build_range( IMAGE *out,
                     int in_max, int out_max,
                     double Lb, double Lw,
                     double Ps, double Pm, double Ph,
                     double S, double M, double H )
{
    ToneShape *ts;
    unsigned short lut[65536];
    int i;

    /* Check args.
     */
    if( !(ts = IM_NEW( out, ToneShape )) ||
            im_outcheck( out ) )
        return( -1 );
    if( in_max < 0 || in_max > 65535 ||
            out_max < 0 || out_max > 65535 ) {
        im_error( "im_tone_build",
                  "%s", _( "bad in_max, out_max parameters" ) );
        return( -1 );
    }
    if( Lb < 0 || Lb > 100 || Lw < 0 || Lw > 100 || Lb > Lw ) {
        im_error( "im_tone_build",
                  "%s", _( "bad Lb, Lw parameters" ) );
        return( -1 );
    }
    if( Ps < 0.0 || Ps > 1.0 ) {
        im_error( "im_tone_build",
                  "%s", _( "Ps not in range [0.0,1.0]" ) );
        return( -1 );
    }
    if( Pm < 0.0 || Pm > 1.0 ) {
        im_error( "im_tone_build",
                  "%s", _( "Pm not in range [0.0,1.0]" ) );
        return( -1 );
    }
    if( Ph < 0.0 || Ph > 1.0 ) {
        im_error( "im_tone_build",
                  "%s", _( "Ph not in range [0.0,1.0]" ) );
        return( -1 );
    }
    if( S < -30 || S > 30 ) {
        im_error( "im_tone_build",
                  "%s", _( "S not in range [-30,+30]" ) );
        return( -1 );
    }
    if( M < -30 || M > 30 ) {
        im_error( "im_tone_build",
                  "%s", _( "M not in range [-30,+30]" ) );
        return( -1 );
    }
    if( H < -30 || H > 30 ) {
        im_error( "im_tone_build",
                  "%s", _( "H not in range [-30,+30]" ) );
        return( -1 );
    }

    /* Note params.
     */
    ts->Lb = Lb;
    ts->Lw = Lw;
    ts->Ps = Ps;
    ts->Pm = Pm;
    ts->Ph = Ph;
    ts->S = S;
    ts->M = M;
    ts->H = H;

    /* Note derived params.
     */
    ts->Ls = Lb + Ps * (Lw - Lb);
    ts->Lm = Lb + Pm * (Lw - Lb);
    ts->Lh = Lb + Ph * (Lw - Lb);

    /* Generate curve.
     */
    for( i = 0; i <= in_max; i++ ) {
        int v = (out_max / 100.0) *
                tone_curve( ts, 100.0 * i / in_max );

        if( v < 0 )
            v = 0;
        else if( v > out_max )
            v = out_max;

        lut[i] = v;
    }

    /* Make the output image.
     */
    im_initdesc( out,
                 in_max + 1, 1, 1, IM_BBITS_SHORT, IM_BANDFMT_USHORT,
                 IM_CODING_NONE, IM_TYPE_HISTOGRAM, 1.0, 1.0, 0, 0 );
    if( im_setupout( out ) )
        return( -1 );

    if( im_writeline( 0, out, (VipsPel *) lut ) )
        return( -1 );

    return( 0 );
}
示例#16
0
/**
 * im_profile:
 * @in: input image
 * @out: output image
 * @dir: search direction
 *
 * im_profile() searches inward from the edge of @in and finds the 
 * first non-zero pixel. It outputs an image containing a list of the offsets 
 * for each row or column.
 *
 * If @dir == 0, then im_profile() searches down from the top edge, writing an 
 * image as wide as the input image, but only 1 pixel high, containing the 
 * number of pixels down to the first non-zero pixel for each column of input 
 * pixels.
 *
 * If @dir == 1, then im_profile() searches across from the left edge, 
 * writing an image as high as the input image, but only 1 pixel wide, 
 * containing the number of pixels across to the
 * first non-zero pixel for each row of input pixels.
 *
 * See also: im_cntlines().
 *
 * Returns: 0 on success, -1 on error
 */
int 
im_profile( IMAGE *in, IMAGE *out, int dir )
{
	int sz;
	unsigned short *buf;
	int x, y, b;

	/* If in is not uchar, do (!=0) to make a uchar image.
	 */
	if( in->BandFmt != IM_BANDFMT_UCHAR ) {
		IMAGE *t;

		if( !(t = im_open_local( out, "im_profile", "p" )) ||
			im_notequalconst( in, t, 0 ) )
			return( -1 );

		in = t;
	}

	/* Check im.
	 */
	if( im_iocheck( in, out ) ||
		im_check_uncoded( "im_profile", in ) ||
		im_check_format( "im_profile", in, IM_BANDFMT_UCHAR ) )
		return( -1 );
	if( dir != 0 && 
		dir != 1 ) {
		im_error( "im_profile", "%s", _( "dir not 0 or 1" ) );
		return( -1 ); 
	}

	if( im_cp_desc( out, in ) )
		return( -1 );
	out->Type = IM_TYPE_HISTOGRAM;
	if( dir == 0 ) {
		out->Xsize = in->Xsize;
		out->Ysize = 1;
	}
	else {
		out->Xsize = 1;
		out->Ysize = in->Ysize;
	}
	out->BandFmt = IM_BANDFMT_USHORT;
	if( im_setupout( out ) )
		return( -1 );
	sz = IM_IMAGE_N_ELEMENTS( out );
	if( !(buf = IM_ARRAY( out, sz, unsigned short )) )
		return( -1 );

	if( dir == 0 ) {
		/* Find vertical lines.
		 */
		for( x = 0; x < sz; x++ ) {
			PEL *p = (PEL *) IM_IMAGE_ADDR( in, 0, 0 ) + x;
			int lsk = IM_IMAGE_SIZEOF_LINE( in );

			for( y = 0; y < in->Ysize; y++ ) {
				if( *p )
					break;
				p += lsk;
			}

			buf[x] = y;
		}

		if( im_writeline( 0, out, (PEL *) buf ) )
			return( -1 );
	}
	else {
		/* Search horizontal lines.
		 */
		for( y = 0; y < in->Ysize; y++ ) {
			PEL *p = (PEL *) IM_IMAGE_ADDR( in, 0, y );

			for( b = 0; b < in->Bands; b++ ) {
				PEL *p1;

				p1 = p + b;
				for( x = 0; x < in->Xsize; x++ ) {
					if( *p1 )
						break;
					p1 += in->Bands;
				}

				buf[b] = x;
			}

			if( im_writeline( y, out, (PEL *) buf ) )
				return( -1 );
		}
	}

	return( 0 );
}
示例#17
0
int 
im_histnD( IMAGE *in, IMAGE *out, int bins )
{
	int max_val;
	Histogram *mhist;
	int x, y, z, i;
	unsigned int *obuffer;

	/* Check images. PIO from in, WIO to out.
	 */
	if( im_pincheck( in ) || im_outcheck( out ) )
		return( -1 );
	if( in->Coding != IM_CODING_NONE ) {
		im_error( "im_histnD", _( " uncoded images only" ) );
		return( -1 );
	}
	if( in->BandFmt != IM_BANDFMT_UCHAR && 
		in->BandFmt != IM_BANDFMT_USHORT ) {
		im_error( "im_histnD", 
			_( " unsigned 8 or 16 bit images only" ) );
		return( -1 );
	}

	max_val = in->BandFmt == IM_BANDFMT_UCHAR ? 256 : 65536;
	if( bins < 1 || bins > max_val ) {
		im_error( "im_histnD", 
			_( " bins out of range [1,%d]" ), max_val );
		return( -1 );
	}

	/* Build main hist we accumulate to.
	 */
	if( !(mhist = build_hist( in, out, bins )) )
		return( -1 );

	/* Accumulate data.
	 */
	if( im_iterate( in, 
		build_subhist, find_hist, merge_subhist, mhist, NULL ) )
		return( -1 );

	/* Make the output image.
	 */
	if( im_cp_desc( out, in ) ) 
		return( -1 );
	im_initdesc( out,
		bins, in->Bands > 1 ? bins : 1, in->Bands > 2 ? bins : 1,
		IM_BBITS_INT, IM_BANDFMT_UINT, 
		IM_CODING_NONE, IM_TYPE_HISTOGRAM, 1.0, 1.0, 0, 0 );
	if( im_setupout( out ) )
		return( -1 );

	/* Interleave to output buffer.
	 */
	if( !(obuffer = IM_ARRAY( out, 
		IM_IMAGE_N_ELEMENTS( out ), unsigned int )) )
		return( -1 );

	for( y = 0; y < out->Ysize; y++ ) {
		for( i = 0, x = 0; x < out->Xsize; x++ ) 
			for( z = 0; z < out->Bands; z++, i++ )
				obuffer[i] = mhist->data[z][y][x];

		if( im_writeline( y, out, (PEL *) obuffer ) )
			return( -1 );
	}

	return( 0 );
}
示例#18
0
/**
 * im_simcontr:
 * @out: output image
 * @xsize: image size
 * @ysize: image size
 *
 * Creates a pattern showing the similtaneous constrast effect.
 *
 * See also: im_eye().
 *
 * Returns: 0 on success, -1 on error
 */
int 
im_simcontr( IMAGE *out, int xsize, int ysize )
{
	int x, y;
	unsigned char *line1, *line2, *cpline;


/* Check input args */
	if( im_outcheck( out ) )
		return( -1 );

/* Set now image properly */
        im_initdesc(out, xsize, ysize, 1, IM_BBITS_BYTE, IM_BANDFMT_UCHAR,
		IM_CODING_NONE, IM_TYPE_B_W, 1.0, 1.0, 0, 0 );

/* Set up image checking whether the output is a buffer or a file */
        if (im_setupout( out ) == -1 )
                return( -1 );
/* Create data */
        line1 = (unsigned char *)calloc((unsigned)xsize, sizeof(char));
        line2 = (unsigned char *)calloc((unsigned)xsize, sizeof(char));
        if ( (line1 == NULL) || (line2 == NULL) ) { 
		im_error( "im_simcontr", "%s", _( "calloc failed") ); 
		return(-1); }

	cpline = line1;
	for (x=0; x<xsize; x++)
		*cpline++ = (PEL)255;
	cpline = line1;
	for (x=0; x<xsize/2; x++)
		*cpline++ = (PEL)0;
	
	cpline = line2;
	for (x=0; x<xsize; x++)
		*cpline++ = (PEL)255;
	cpline = line2;
	for (x=0; x<xsize/8; x++)
		*cpline++ = (PEL)0;
	for (x=0; x<xsize/4; x++)
		*cpline++ = (PEL)128;
	for (x=0; x<xsize/8; x++)
		*cpline++ = (PEL)0;
	for (x=0; x<xsize/8; x++)
		*cpline++ = (PEL)255;
	for (x=0; x<xsize/4; x++)
		*cpline++ = (PEL)128;

	for (y=0; y<ysize/4; y++)
		{
		if ( im_writeline( y, out, (PEL *)line1 ) == -1 )
			{
			free ( (char *)line1 ); free ( (char *)line2 );
			return( -1 );
			}
		}
	for (y=ysize/4; y<(ysize/4+ysize/2); y++)
		{
		if ( im_writeline( y, out, (PEL *)line2 ) == -1 )
			{
			free ( (char *)line1 ); free ( (char *)line2 );
			return( -1 );
			}
		}
	for (y=(ysize/4 + ysize/2); y<ysize; y++)
		{
		if ( im_writeline( y, out, (PEL *)line1 ) == -1 )
			{
			free ( (char *)line1 ); free ( (char *)line2 );
			return( -1 );
			}
		}
	free ( (char *)line1 ); free ( (char *)line2 );
	return(0);
}
示例#19
0
/* Call rfftw for a 1 band real image.
 */
static int 
rfwfft1( IMAGE *dummy, IMAGE *in, IMAGE *out )
{
	const int size = in->Xsize * in->Ysize;
	const int half_width = in->Xsize / 2 + 1;

	/* Pack to double real here.
	 */
	IMAGE *real = im_open_local( dummy, "fwfft1:1", "t" );

	/* Transform to halfcomplex here.
	 */
	double *half_complex = IM_ARRAY( dummy, 
		in->Ysize * half_width * 2, double );

	rfftwnd_plan plan;
	double *buf, *q, *p;
	int x, y;

	if( !real || !half_complex || im_pincheck( in ) || im_outcheck( out ) )
		return( -1 );
	if( in->Coding != IM_CODING_NONE || in->Bands != 1 ) {
                im_error( "im_fwfft", _( "one band uncoded only" ) );
                return( -1 );
	}
	if( im_clip2d( in, real ) )
                return( -1 );

	/* Make the plan for the transform. Yes, they really do use nx for
	 * height and ny for width.
	 */
	if( !(plan = rfftw2d_create_plan( in->Ysize, in->Xsize,
		FFTW_FORWARD, FFTW_MEASURE | FFTW_USE_WISDOM )) ) {
                im_error( "im_fwfft", _( "unable to create transform plan" ) );
		return( -1 );
	}

	rfftwnd_one_real_to_complex( plan, 
		(fftw_real *) real->data, (fftw_complex *) half_complex );

	rfftwnd_destroy_plan( plan );

	/* WIO to out.
	 */
        if( im_cp_desc( out, in ) )
                return( -1 );
	out->Bbits = IM_BBITS_DPCOMPLEX;
	out->BandFmt = IM_BANDFMT_DPCOMPLEX;
        if( im_setupout( out ) )
                return( -1 );
	if( !(buf = (double *) IM_ARRAY( dummy, 
		IM_IMAGE_SIZEOF_LINE( out ), PEL )) )
		return( -1 );

	/* Copy to out and normalise. The right half is the up/down and 
	 * left/right flip of the left, but conjugated. Do the first 
	 * row separately, then mirror around the centre row.
	 */
	p = half_complex;
	q = buf;

	for( x = 0; x < half_width; x++ ) {
		q[0] = p[0] / size;
		q[1] = p[1] / size;
		p += 2;
		q += 2;
	}

	p = half_complex + ((in->Xsize + 1) / 2 - 1) * 2; 

	for( x = half_width; x < out->Xsize; x++ ) {
		q[0] = p[0] / size;
		q[1] = -1.0 * p[1] / size;
		p -= 2;
		q += 2;
	}

	if( im_writeline( 0, out, (PEL *) buf ) )
		return( -1 );

	for( y = 1; y < out->Ysize; y++ ) {
		p = half_complex + y * half_width * 2; 
		q = buf;

		for( x = 0; x < half_width; x++ ) {
			q[0] = p[0] / size;
			q[1] = p[1] / size;
			p += 2;
			q += 2;
		}

		/* Good grief. 
		 */
		p = half_complex + 2 *
			((out->Ysize - y + 1) * half_width - 2 + 
				(in->Xsize & 1));

		for( x = half_width; x < out->Xsize; x++ ) {
			q[0] = p[0] / size;
			q[1] = -1.0 * p[1] / size;
			p -= 2;
			q += 2;
		}

		if( im_writeline( y, out, (PEL *) buf ) )
			return( -1 );
	}

	return( 0 );
}
示例#20
0
/* Transform a 1 band image with vips's built-in fft routine.
 */
static int 
fwfft1( IMAGE *dummy, IMAGE *in, IMAGE *out )
{
	int size = in->Xsize * in->Ysize;
	int bpx = im_ispoweroftwo( in->Xsize );
	int bpy = im_ispoweroftwo( in->Ysize );
	float *buf, *q, *p1, *p2;
	int x, y;

	/* Buffers for real and imaginary parts.
	 */
	IMAGE *real = im_open_local( dummy, "fwfft1:1", "t" );
	IMAGE *imag = im_open_local( dummy, "fwfft1:2", "t" );

	/* Temporaries.
	 */
	IMAGE *t1 = im_open_local( dummy, "fwfft1:3", "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_fwfft", 
			_( "one band non-complex uncoded only" ) );
                return( -1 );
	}
	if( !bpx || !bpy ) {
		im_error( "im_fwfft", _( "sides must be power of 2" ) );
		return( -1 );
	}

	/* Make sure we have a float input image.
	 */
	if( im_clip2f( in, real ) )
		return( -1 );

	/* Make a buffer of 0 floats of the same size for the imaginary part.
	 */
	if( im_black( t1, in->Xsize, in->Ysize, 1 ) )
		return( -1 );
	if( im_clip2f( t1, imag ) )
		return( -1 );

	/* Transform!
	 */
	if( im__fft_sp( (float *) real->data, (float *) imag->data, 
		bpx - 1, bpy - 1 ) ) {
                im_error( "im_fwfft", _( "fft_sp failed" ) );
                return( -1 );
	}	

	/* WIO to out.
	 */
        if( im_cp_desc( out, in ) )
                return( -1 );
	out->Bbits = IM_BBITS_COMPLEX;
	out->BandFmt = IM_BANDFMT_COMPLEX;
        if( im_setupout( out ) )
                return( -1 );
	if( !(buf = (float *) IM_ARRAY( dummy, 
		IM_IMAGE_SIZEOF_LINE( out ), PEL )) )
		return( -1 );

	/* Gather together real and imag parts. We have to normalise output!
	 */
	for( p1 = (float *) real->data, p2 = (float *) imag->data,
		y = 0; y < out->Ysize; y++ ) {
		q = buf;

		for( x = 0; x < out->Xsize; x++ ) {
			q[0] = *p1++ / size;
			q[1] = *p2++ / size;
			q += 2;
		}

		if( im_writeline( y, out, (PEL *) buf ) )
			return( -1 );
	}

	return( 0 );
}
示例#21
0
/* Complex to complex forward transform.
 */
static int 
cfwfft1( IMAGE *dummy, IMAGE *in, IMAGE *out )
{
	fftw_plan plan;
	double *buf, *q, *p;
	int x, y;

	IMAGE *cmplx = im_open_local( dummy, "fwfft1:1", "t" );

	/* We have to have a separate buffer for the planner to work on.
	 */
	double *planner_scratch = IM_ARRAY( dummy, 
		in->Xsize * in->Ysize * 2, double );

	/* Make dp complex image.
	 */
	if( !cmplx || im_pincheck( in ) || im_outcheck( out ) )
		return( -1 );
	if( in->Coding != IM_CODING_NONE || in->Bands != 1 ) {
                im_error( "im_fwfft", _( "one band uncoded only" ) );
                return( -1 );
	}
	if( im_clip2dcm( in, cmplx ) )
                return( -1 );

	/* Make the plan for the transform.
	 */
	if( !(plan = fftw_plan_dft_2d( in->Ysize, in->Xsize,
		(fftw_complex *) planner_scratch, 
		(fftw_complex *) planner_scratch,
		FFTW_FORWARD, 
		0 )) ) {
                im_error( "im_fwfft", _( "unable to create transform plan" ) );
		return( -1 );
	}

	fftw_execute_dft( plan,
		(fftw_complex *) cmplx->data, (fftw_complex *) cmplx->data );

	fftw_destroy_plan( plan );

	/* WIO to out.
	 */
        if( im_cp_desc( out, in ) )
                return( -1 );
	out->Bbits = IM_BBITS_DPCOMPLEX;
	out->BandFmt = IM_BANDFMT_DPCOMPLEX;
        if( im_setupout( out ) )
                return( -1 );
	if( !(buf = (double *) IM_ARRAY( dummy, 
		IM_IMAGE_SIZEOF_LINE( out ), PEL )) )
		return( -1 );

	/* Copy to out, normalise.
	 */
	for( p = (double *) cmplx->data, y = 0; y < out->Ysize; y++ ) {
		int size = out->Xsize * out->Ysize;

		q = buf;

		for( x = 0; x < out->Xsize; x++ ) {
			q[0] = p[0] / size;
			q[1] = p[1] / size;
			p += 2;
			q += 2;
		}

		if( im_writeline( y, out, (PEL *) buf ) )
			return( -1 );
	}

	return( 0 );
}
示例#22
0
/**
 * im_sines:
 * @out: output image
 * @xsize: image size
 * @ysize: image size
 * @horfreq: horizontal frequency
 * @verfreq: vertical frequency
 *
 * im_sines() creates a float one band image of the a sine waveform in two
 * dimensions.  
 *
 * The number of horizontal and vertical spatial frequencies are
 * determined by the variables @horfreq and @verfreq respectively.  The
 * function is useful for creating displayable sine waves and
 * square waves in two dimensions.
 *
 * If horfreq and verfreq are integers the resultant image is periodical
 * and therfore the Fourier transform doesnot present spikes
 * 
 * See also: im_grey(), im_make_xy(). 
 *
 * Returns: 0 on success, -1 on error
 */
int 
im_sines( IMAGE *out, int xsize, int ysize, double horfreq, double verfreq )
{
	int x, y;
	float *line, *cpline;
	int size;
	double cons, factor;
	double theta_rad, costheta, sintheta, ysintheta;

/* Check input args */
	if( im_outcheck( out ) )
		return( -1 );
        if ( xsize <= 0 || ysize <= 0 ) { 
		im_error( "im_sines", "%s", _( "wrong sizes") ); 
		return(-1); }

/* Set now out properly */
        im_initdesc(out, xsize, ysize, 1, IM_BBITS_FLOAT, IM_BANDFMT_FLOAT,
		IM_CODING_NONE, IM_TYPE_B_W, 1.0, 1.0, 0, 0);

/* Set up out checking whether the output is a buffer or a file */
        if (im_setupout( out ) == -1 )
                return( -1 );
/* Create data */
	size = out->Xsize;
        if ( (line=(float *)calloc((unsigned)size, sizeof(float))) == NULL ) { 
		im_error( "im_sines", "%s", _( "calloc failed") ); 
		return(-1); }

/* make angle in rad */
	if (horfreq == 0)
		theta_rad = IM_PI/2.0;
	else
		theta_rad = atan(verfreq/horfreq);
	costheta = cos(theta_rad); sintheta = sin(theta_rad);
	factor = sqrt ((double)(horfreq*horfreq + verfreq*verfreq));
	cons =  factor * IM_PI * 2.0/(double)out->Xsize;
/* There is a bug (rounding error ?) for horfreq=0,
 *so do this calculation independantly */
	if ( horfreq != 0 )
		{
		for (y=0; y<out->Ysize; y++)
			{
			ysintheta = y * sintheta;
			cpline = line;
			for (x=0; x<out->Xsize; x++)
				*cpline++ =
				(float)(cos(cons*(x*costheta-ysintheta)));
			if ( im_writeline( y, out, (PEL *)line ) == -1 )
				{
				free ( (char *)line );
				return( -1 );
				}
			}
		}
	else
		{
		for (y=0; y<out->Ysize; y++)
			{
			cpline = line;
			ysintheta = cos (- cons * y * sintheta);
			for (x=0; x<out->Xsize; x++)
				*cpline++ = (float)ysintheta;
			if ( im_writeline( y, out, (PEL *)line ) == -1 )
				{
				free ( (char *)line );
				return( -1 );
				}
			}
		}
	free ( (char *)line );
	return(0);
}
示例#23
0
int 
im_resize_linear( IMAGE *in, IMAGE *out, int X, int Y )
{
    double	dx, dy, xscale, yscale;
    double	Xnew, Ynew;	/* inv. coord. of the interpolated pt */

    int		x, y;
    int		Xint, Yint;
    int		bb;

    PEL		*input, *opline;
    PEL 	*q, *p;

    int 	ils, ips, ies;		/* Input and output line, pel and */
    int 	ols, ops, oes;		/* element sizes */

	if( im_iocheck( in, out ) )
		return( -1 );
	if( im_iscomplex( in ) ) {
		im_errormsg( "im_lowpass: non-complex input only" );
		return( -1 );
	}
	if( in->Coding != IM_CODING_NONE ) {
		im_errormsg("im_lowpass: input should be uncoded");
		return( -1 );
	}
	if( im_cp_desc( out, in ) ) 
		return( -1 );

	out->Xsize = X;
	out->Ysize = Y;

	if( im_setupout( out ) )
		return( -1 );

	ils = IM_IMAGE_SIZEOF_LINE( in );
	ips = IM_IMAGE_SIZEOF_PEL( in );
	ies = IM_IMAGE_SIZEOF_ELEMENT( in );

	ols = IM_IMAGE_SIZEOF_LINE( out );
	ops = IM_IMAGE_SIZEOF_PEL( out );
	oes = IM_IMAGE_SIZEOF_ELEMENT( out );

/* buffer lines
***************/
	if( !(opline = IM_ARRAY( out, ols, PEL )) ) 
		return( -1 );

/* Resampling
*************/
	input = (PEL*) in->data;
	xscale = ((double)in->Xsize-1)/(X-1);
	yscale = ((double)in->Ysize-1)/(Y-1);

for (y=0; y<Y; y++)
  {
    q = opline;
    for (x=0; x<X; x++)
      {
	Xnew = x*xscale;
	Ynew = y*yscale;
	Xint = floor(Xnew);
	Yint = floor(Ynew);
	dx = Xnew - Xint;
	dy = Ynew - Yint;
	p = input + Xint*ips + Yint*ils;

	switch( in->BandFmt ) {
	case IM_BANDFMT_UCHAR:		LOOP( unsigned char); break;
	case IM_BANDFMT_USHORT:		LOOP( unsigned short ); break;
	case IM_BANDFMT_UINT:		LOOP( unsigned int ); break;
	case IM_BANDFMT_CHAR:		LOOP( signed char ); break;
	case IM_BANDFMT_SHORT:		LOOP( signed short ); break;
	case IM_BANDFMT_INT:		LOOP( signed int ); break;
	case IM_BANDFMT_FLOAT:		LOOP( float ); break;
	case IM_BANDFMT_DOUBLE:		LOOP( double ); break;

	default:
		im_errormsg( "im_lowpass: unsupported image type" );
		return( -1 );
		/*NOTREACHED*/
	}
      }

    if (im_writeline(y, out, opline) )
	    return(-1);
  } 
return(0);
}