Example #1
0
File: copy.c Project: kjell/libvips
/* Copy a small area.
 */
static int
vips_copy_gen( VipsRegion *or, void *seq, void *a, void *b, gboolean *stop )
{
    VipsRegion *ir = (VipsRegion *) seq;
    VipsRect *r = &or->valid;
    VipsCopy *copy = (VipsCopy *) b;
    SwapFn swap = vips_copy_swap_fn[copy->in->BandFmt];

    /* Ask for input we need.
     */
    if( vips_region_prepare( ir, r ) )
        return( -1 );

    if( copy->swap && swap ) {
        int y;

        for( y = 0; y < r->height; y++ ) {
            VipsPel *p = VIPS_REGION_ADDR( ir,
                                           r->left, r->top + y );
            VipsPel *q = VIPS_REGION_ADDR( or,
                                           r->left, r->top + y );

            swap( p, q, r->width, copy->in );
        }
    }
    else
        /* Nothing to do, just copy with pointers.
         */
        if( vips_region_region( or, ir, r, r->left, r->top ) )
            return( -1 );

    return( 0 );
}
Example #2
0
static int
vips_bandary_gen( VipsRegion *or, void *seq, void *a, void *b, gboolean *stop )
{
	VipsRegion **ir = (VipsRegion **) seq;
	VipsBandary *bandary = (VipsBandary *) b;
	VipsBandaryClass *class = VIPS_BANDARY_GET_CLASS( bandary ); 
	VipsRect *r = &or->valid;

	VipsPel *p[MAX_INPUT_IMAGES], *q;
	int y, i;

	for( i = 0; i < bandary->n; i++ ) {
		if( vips_region_prepare( ir[i], r ) )
			return( -1 );
		p[i] = VIPS_REGION_ADDR( ir[i], r->left, r->top );
	}
	p[i] = NULL;
	q = VIPS_REGION_ADDR( or, r->left, r->top );

	VIPS_GATE_START( "vips_bandary_gen: work" ); 

	for( y = 0; y < r->height; y++ ) {
		class->process_line( bandary, q, p, r->width );

		for( i = 0; i < bandary->n; i++ )
			p[i] += VIPS_REGION_LSKIP( ir[i] );
		q += VIPS_REGION_LSKIP( or );
	}

	VIPS_GATE_STOP( "vips_bandary_gen: work" ); 

	return( 0 );
}
Example #3
0
static int
vips_colour_gen( VipsRegion *or, 
	void *seq, void *a, void *b, gboolean *stop )
{
	VipsRegion **ir = (VipsRegion **) seq;
	VipsColour *colour = VIPS_COLOUR( b ); 
	VipsColourClass *class = VIPS_COLOUR_GET_CLASS( colour ); 
	VipsRect *r = &or->valid;

	int i, y;
	VipsPel *p[MAX_INPUT_IMAGES], *q;

	for( i = 0; ir[i]; i++ ) 
		if( vips_region_prepare( ir[i], r ) ) 
			return( -1 );

	VIPS_GATE_START( "vips_colour_gen: work" ); 

	for( y = 0; y < r->height; y++ ) {
		for( i = 0; ir[i]; i++ )
			p[i] = VIPS_REGION_ADDR( ir[i], r->left, r->top + y );
		p[i] = NULL;
		q = VIPS_REGION_ADDR( or, r->left, r->top + y );

		class->process_line( colour, q, p, r->width );
	}

	VIPS_GATE_STOP( "vips_colour_gen: work" ); 

	return( 0 );
}
Example #4
0
static int
vips_rot180_gen( VipsRegion *or, void *seq, void *a, void *b,
	gboolean *stop )
{
	VipsRegion *ir = (VipsRegion *) seq;
	VipsImage *in = (VipsImage *) a;

	/* Output area.
	 */
	VipsRect *r = &or->valid;
	int le = r->left;
	int ri = IM_RECT_RIGHT(r);
	int to = r->top;
	int bo = IM_RECT_BOTTOM(r);

	int x, y;

	/* Pixel geometry.
	 */
	int ps;

	/* Find the area of the input image we need.
	 */
	Rect need;

	need.left = in->Xsize - ri;
	need.top = in->Ysize - bo;
	need.width = r->width;
	need.height = r->height;
	if( vips_region_prepare( ir, &need ) )
		return( -1 );

	/* Find PEL size and line skip for ir.
	 */
	ps = VIPS_IMAGE_SIZEOF_PEL( in );

	/* Rotate the bit we now have.
	 */
	for( y = to; y < bo; y++ ) {
		/* Start of this output line.
		 */
		VipsPel *q = VIPS_REGION_ADDR( or, le, y );

		/* Corresponding position in ir.
		 */
		VipsPel *p = VIPS_REGION_ADDR( ir, 
			need.left + need.width - 1, 
			need.top + need.height - (y - to) - 1 );

		/* Blap across!
		 */
		for( x = le; x < ri; x++ ) {
			memcpy( q, p, ps );
			q += ps;
			p -= ps;
		}
	}

	return( 0 );
}
Example #5
0
static int
vips_msb_gen( VipsRegion *or, void *seq, void *a, void *b, gboolean *stop )
{
	VipsRegion *ir = (VipsRegion *) seq;
	VipsMsb *msb = (VipsMsb *) b;
	VipsConversion *conversion = (VipsConversion *) msb;
	VipsRect *r = &or->valid;
	int le = r->left;
	int to = r->top;
	int bo = VIPS_RECT_BOTTOM( r );
	int sz = r->width * conversion->out->Bands;

	int x, y, i;

	if( vips_region_prepare( ir, r ) )
		return( -1 );

	for( y = to; y < bo; y++ ) {
		VipsPel *p = VIPS_REGION_ADDR( ir, le, y ); 
		VipsPel *q = VIPS_REGION_ADDR( or, le, y ); 

		if( msb->in->Coding == VIPS_CODING_LABQ &&
			msb->band == -1 ) {
			/* LABQ, no sub-band select.
			 */
			for( x = 0; x < r->width; x++ ) {
				q[0] = p[0];
				q[1] = 0x80 ^ p[1];
				q[2] = 0x80 ^ p[2];

				q += 4;
				p += 3;
			}
		}
		else if( msb->sign ) {
			/* Copy, converting signed to unsigned.
			 */
			p += msb->offset;
			for( i = 0; i < sz; i++ ) {
				q[i] = 0x80 ^ *p;

				p += msb->instep;
			}
		}
		else {
			/* Just pick out bytes. 
			 */
			p += msb->offset;
			for( i = 0; i < sz; i++ ) {
				q[i] = *p;

				p += msb->instep;
			}
		}
	}

	return( 0 );
}
Example #6
0
/* Paint the part of the region containing only whole pels.
 */
static void
vips_zoom_paint_whole( VipsRegion *or, VipsRegion *ir, VipsZoom *zoom,
	const int left, const int right, const int top, const int bottom )
{
	const int ps = VIPS_IMAGE_SIZEOF_PEL( ir->im );
	const int ls = VIPS_REGION_LSKIP( or );
	const int rs = ps * (right - left);

	/* Transform to ir coordinates.
	 */
	const int ileft = left / zoom->xfac;
	const int iright = right / zoom->xfac;
	const int itop = top / zoom->yfac;
	const int ibottom = bottom / zoom->yfac;

	int x, y, z, i;

	/* We know this!
	 */
	g_assert( right > left && bottom > top && 
		right % zoom->xfac == 0 &&
		left % zoom->xfac == 0 &&
		top % zoom->yfac == 0 &&
		bottom % zoom->yfac == 0 );

	/* Loop over input, as we know we are all whole.
	 */
	for( y = itop; y < ibottom; y++ ) {
		VipsPel *p = VIPS_REGION_ADDR( ir, ileft, y );
		VipsPel *q = VIPS_REGION_ADDR( or, left, y * zoom->yfac );
		VipsPel *r;

		/* Expand the first line of pels.
		 */
		r = q;
		for( x = ileft; x < iright; x++ ) {
			/* Copy each pel xfac times.
			 */
			for( z = 0; z < zoom->xfac; z++ ) {
				for( i = 0; i < ps; i++ )
					r[i] = p[i];

				r += ps;
			}

			p += ps;
		}

		/* Copy the expanded line yfac-1 times.
		 */
		r = q + ls;
		for( z = 1; z < zoom->yfac; z++ ) {
			memcpy( r, q, rs );
			r += ls;
		}
	}
}
Example #7
0
static int
vips_flip_horizontal_gen( VipsRegion *or, void *seq, void *a, void *b, 
	gboolean *stop )
{
	VipsRegion *ir = (VipsRegion *) seq;
	VipsRect *r = &or->valid;
	VipsRect in;
	VipsPel *p, *q;
	int x, y, z;

	int le = r->left;
	int ri = VIPS_RECT_RIGHT(r);
	int to = r->top;
	int bo = VIPS_RECT_BOTTOM(r);

	int ps = VIPS_IMAGE_SIZEOF_PEL( ir->im );	/* sizeof pel */

	int hgt = ir->im->Xsize - r->width;

	int lastx;

	/* Transform to input coordinates.
	 */
	in = *r;
	in.left = hgt - r->left;

	/* Find x of final pixel in input area.
	 */
	lastx = VIPS_RECT_RIGHT( &in ) - 1;

	/* Ask for input we need.
	 */
	if( vips_region_prepare( ir, &in ) )
		return( -1 );

	/* Loop, copying and reversing lines.
	 */
	for( y = to; y < bo; y++ ) {
		p = VIPS_REGION_ADDR( ir, lastx, y );
		q = VIPS_REGION_ADDR( or, le, y );

		for( x = le; x < ri; x++ ) {
			/* Copy the pel.
			 */
			for( z = 0; z < ps; z++ )
				q[z] = p[z];

			/* Skip forwards in out, back in in.
			 */
			q += ps;
			p -= ps;
		}
	}

	return( 0 );
}
Example #8
0
/* Generate an area of @or. @ir is large enough.
 */
static void
vips_shrink2_gen2( VipsShrink2 *shrink, VipsShrink2Sequence *seq,
                   VipsRegion *or, VipsRegion *ir,
                   int left, int top, int width, int height )
{
    VipsResample *resample = VIPS_RESAMPLE( shrink );
    const int bands = resample->in->Bands;
    const int sizeof_pixel = VIPS_IMAGE_SIZEOF_PEL( resample->in );
    const int ls = VIPS_REGION_LSKIP( ir ) /
                   VIPS_IMAGE_SIZEOF_ELEMENT( resample->in );

    int x, y, i;
    int x1, y1, b;

    for( y = 0; y < height; y++ ) {
        VipsPel *out = VIPS_REGION_ADDR( or, left, top + y );

        for( x = 0; x < width; x++ ) {
            int ix = (left + x) * shrink->xshrink;
            int iy = (top + y) * shrink->yshrink;
            VipsPel *in = VIPS_REGION_ADDR( ir, ix, iy );

            switch( resample->in->BandFmt ) {
            case VIPS_FORMAT_UCHAR:
                ISHRINK( unsigned char );
                break;
            case VIPS_FORMAT_CHAR:
                ISHRINK( char );
                break;
            case VIPS_FORMAT_USHORT:
                ISHRINK( unsigned short );
                break;
            case VIPS_FORMAT_SHORT:
                ISHRINK( short );
                break;
            case VIPS_FORMAT_UINT:
                ISHRINK( unsigned int );
                break;
            case VIPS_FORMAT_INT:
                ISHRINK( int );
                break;
            case VIPS_FORMAT_FLOAT:
                FSHRINK( float );
                break;
            case VIPS_FORMAT_DOUBLE:
                FSHRINK( double );
                break;

            default:
                g_assert( 0 );
            }

            out += sizeof_pixel;
        }
    }
}
Example #9
0
/* Paint r of region or. It's a border area, lying entirely within 
 * embed->border[i]. p points to the top-left source pixel to fill with. 
 * plsk is the line stride.
 */
static void
vips_embed_paint_edge( VipsEmbed *embed, 
	VipsRegion *or, int i, VipsRect *r, VipsPel *p, int plsk )
{
	const int bs = VIPS_IMAGE_SIZEOF_PEL( embed->in );

	VipsRect todo;
	VipsPel *q;
	int y;

	VIPS_GATE_START( "vips_embed_paint_edge: work" );

	/* Pixels left to paint.
	 */
	todo = *r;

	/* Corner pieces ... copy the single pixel to paint the top line of
	 * todo, then use the line copier below to paint the rest of it.
	 */
	if( i > 3 ) {
		q = VIPS_REGION_ADDR( or, todo.left, todo.top );
		vips_embed_copy_pixel( embed, q, p, todo.width );

		p = q;
		todo.top += 1;
		todo.height -= 1;
	}

	if( i == 1 || i == 3 ) {
		/* Vertical line of pixels to copy.
		 */
		for( y = 0; y < todo.height; y++ ) {
			q = VIPS_REGION_ADDR( or, todo.left, todo.top + y );
			vips_embed_copy_pixel( embed, q, p, todo.width );
			p += plsk;
		}
	}
	else {
		/* Horizontal line of pixels to copy.
		 */
		for( y = 0; y < todo.height; y++ ) {
			q = VIPS_REGION_ADDR( or, todo.left, todo.top + y );
			memcpy( q, p, bs * todo.width );
		}
	}

	VIPS_GATE_STOP( "vips_embed_paint_edge: work" );
}
Example #10
0
static int
write_png_block( VipsRegion *region, VipsRect *area, void *a )
{
	Write *write = (Write *) a;

	int i;

	/* The area to write is always a set of complete scanlines.
	 */
	g_assert( area->left == 0 );
	g_assert( area->width == region->im->Xsize );
	g_assert( area->top + area->height <= region->im->Ysize );

	/* Catch PNG errors. Yuk.
	 */
	if( setjmp( png_jmpbuf( write->pPng ) ) ) 
		return( -1 );

	for( i = 0; i < area->height; i++ ) 
		write->row_pointer[i] = (png_bytep)
			VIPS_REGION_ADDR( region, 0, area->top + i );

	png_write_rows( write->pPng, write->row_pointer, area->height );

	return( 0 );
}
Example #11
0
static int
vips_gaussnoise_gen( VipsRegion *or, void *seq, void *a, void *b,
	gboolean *stop )
{
	VipsGaussnoise *gaussnoise = (VipsGaussnoise *) a;
	int sz = VIPS_REGION_N_ELEMENTS( or );

	int y;

	for( y = 0; y < or->valid.height; y++ ) {
		float *q = (float *) VIPS_REGION_ADDR( or, 
			or->valid.left, y + or->valid.top );

		int x;

		for( x = 0; x < sz; x++ ) {
			double sum;
			int i;

			sum = 0.0;
			for( i = 0; i < 12; i++ ) 
				sum += g_random_double(); 

			q[x] = (sum - 6.0) * gaussnoise->sigma + 
				gaussnoise->mean;
		}
	}

	return( 0 );
}
Example #12
0
static int
vips_statistic_scan( VipsRegion *region, 
	void *seq, void *a, void *b, gboolean *stop )
{
	VipsStatistic *statistic = VIPS_STATISTIC( a );
	VipsStatisticClass *class = VIPS_STATISTIC_GET_CLASS( statistic );

	VipsRect *r = &region->valid;
	int lsk = IM_REGION_LSKIP( region );

	int y;
	VipsPel *p;

	VIPS_DEBUG_MSG( "vips_statistic_scan: %d x %d @ %d x %d\n",
		r->width, r->height, r->left, r->top );

	p = VIPS_REGION_ADDR( region, r->left, r->top ); 
	for( y = 0; y < r->height; y++ ) { 
		if( class->scan( statistic, 
			seq, r->left, r->top + y, p, r->width ) ) 
			return( -1 );
		p += lsk;
	} 

	/* If we've requested stop, pass the message on.
	 */
	if( statistic->stop )
		*stop = TRUE;

	return( 0 );
}
Example #13
0
static int
vips_worley_gen( VipsRegion *or, void *vseq, void *a, void *b,
	gboolean *stop )
{
	VipsWorley *worley = (VipsWorley *) a;
	VipsRect *r = &or->valid;
	Sequence *seq = (Sequence *) vseq;

	int x, y;

	for( y = 0; y < r->height; y++ ) {
		int *q = (int *) VIPS_REGION_ADDR( or, r->left, r->top + y );

		for( x = 0; x < r->width; x++ ) {
			int cell_x = (r->left + x) / worley->cell_size;
			int cell_y = (r->top + y) / worley->cell_size;

			if( cell_x != seq->cell_x ||
				cell_y != seq->cell_y ) {
				vips_worley_create_cells( worley, 
					seq->cells, cell_x, cell_y );
				seq->cell_x = cell_x;
				seq->cell_y = cell_y;
			}

			q[x] = vips_worley_distance( worley, seq->cells, 
				r->left + x, r->top + y );
		}
	}

	return( 0 );
}
Example #14
0
static int
magick_fill_region( VipsRegion *out, 
	void *seq, void *a, void *b, gboolean *stop )
{
	Read *read = (Read *) a;
	VipsRect *r = &out->valid;
	int y;

	for( y = 0; y < r->height; y++ ) {
		int top = r->top + y;
		int frame = top / read->frame_height;
		int line = top % read->frame_height;

		PixelPacket *pixels;

		g_mutex_lock( read->lock );
		pixels = get_pixels( read->frames[frame], 
			r->left, line, r->width, 1 );
		g_mutex_unlock( read->lock );

		if( !pixels ) {
			vips_error( "magick2vips", 
				"%s", _( "unable to read pixels" ) );
			return( -1 );
		}

		unpack_pixels( read->im, VIPS_REGION_ADDR( out, r->left, top ), 
			pixels, r->width );
	}

	return( 0 );
}
Example #15
0
/* Fetch one pixel at a time ... good for very large shrinks.
 */
static int
vips_subsample_point_gen( VipsRegion *or, 
	void *seq, void *a, void *b, gboolean *stop )
{
	VipsRegion *ir = (VipsRegion *) seq;
	VipsSubsample *subsample = (VipsSubsample *) b;
	VipsImage *in = (VipsImage *) a;
	VipsRect *r = &or->valid;
	int le = r->left;
	int ri = VIPS_RECT_RIGHT( r );
	int to = r->top;
	int bo = VIPS_RECT_BOTTOM(r);
	int ps = VIPS_IMAGE_SIZEOF_PEL( in );

	VipsRect s;
	int x, y;
	int k;

	/* Loop down the region.
	 */
	for( y = to; y < bo; y++ ) {
		VipsPel *q = VIPS_REGION_ADDR( or, le, y );
		VipsPel *p;

		/* Loop across the region, in owidth sized pieces.
		 */
		for( x = le; x < ri; x++ ) {
			/* Ask for input.
			 */
			s.left = x * subsample->xfac;
			s.top = y * subsample->yfac;
			s.width = 1;
			s.height = 1;
			if( vips_region_prepare( ir, &s ) )
				return( -1 );

			/* Append new pels to output.
			 */
			p = VIPS_REGION_ADDR( ir, s.left, s.top );
			for( k = 0; k < ps; k++ )
				q[k] = p[k];
			q += ps;
		}
	}

	return( 0 );
}
Example #16
0
static int
vips_fits_write( VipsRegion *region, VipsRect *area, void *a )
{
	VipsFits *fits = (VipsFits *) a;
	VipsImage *image = fits->image;
	int es = VIPS_IMAGE_SIZEOF_ELEMENT( image );
	int ps = VIPS_IMAGE_SIZEOF_PEL( image );

	int status;
	int y, b, x, k;

	status = 0;

	VIPS_DEBUG_MSG( "vips_fits_write: "
		"writing left = %d, top = %d, width = %d, height = %d\n", 
		area->left, area->top, area->width, area->height );

	/* We need to write a band at a time. We can't bandsplit in vips,
	 * since vips_sink_disc() can't loop over many images at once, sadly.
	 */

	for( y = 0; y < area->height; y++ ) {
		VipsPel *p = VIPS_REGION_ADDR( region, 
			area->left, area->top + y );

		for( b = 0; b < image->Bands; b++ ) {
			VipsPel *p1, *q;
			long fpixel[3];

			p1 = p + b * es;
			q = fits->buffer;

			for( x = 0; x < area->width; x++ ) {
				for( k = 0; k < es; k++ ) 
					q[k] = p1[k];
				
				q += es;
				p1 += ps;
			}

			fpixel[0] = area->left + 1;
			fpixel[1] = area->top + y + 1;
			fpixel[2] = b + 1;

			/* No need to lock, write functions are single-threaded.
			 */

			if( fits_write_pix( fits->fptr, fits->datatype, 
				fpixel, area->width, fits->buffer, 
				&status ) ) {
				vips_fits_error( status );
				return( -1 );
			}
		}
	}

	return( 0 );
}
Example #17
0
static int
vips_flip_vertical_gen( VipsRegion *or, void *seq, void *a, void *b,
	gboolean *stop )
{
	VipsRegion *ir = (VipsRegion *) seq;
	VipsRect *r = &or->valid;
	VipsRect in;
	VipsPel *p, *q;
	int y;

	int le = r->left;
	int to = r->top;
	int bo = VIPS_RECT_BOTTOM( r );

	int ls;
	int psk, qsk;

	/* Transform to input coordinates.
	 */
	in = *r;
	in.top = ir->im->Ysize - bo;

	/* Ask for input we need.
	 */
	if( vips_region_prepare( ir, &in ) )
		return( -1 );

	/* Loop, copying and reversing lines.
	 */
	p = VIPS_REGION_ADDR( ir, le, in.top + in.height - 1 );
	q = VIPS_REGION_ADDR( or, le, to );
	psk = VIPS_REGION_LSKIP( ir );
	qsk = VIPS_REGION_LSKIP( or );
	ls = VIPS_REGION_SIZEOF_LINE( or );

	for( y = to; y < bo; y++ ) {
		memcpy( q, p, ls );

		p -= psk;
		q += qsk;
	}

	return( 0 );
}
Example #18
0
/* Copy rect from @from to @to.
 */
static void
copy_region( VipsRegion *from, VipsRegion *to, VipsRect *area )
{
	int y;

	/* Area should be inside both from and to.
	 */
	g_assert( vips_rect_includesrect( &from->valid, area ) );
	g_assert( vips_rect_includesrect( &to->valid, area ) );

	/* Loop down common area, copying.
	 */
	for( y = area->top; y < VIPS_RECT_BOTTOM( area ); y++ ) {
		VipsPel *p = VIPS_REGION_ADDR( from, area->left, y );
		VipsPel *q = VIPS_REGION_ADDR( to, area->left, y );

		memcpy( q, p, VIPS_IMAGE_SIZEOF_PEL( from->im ) * area->width );
	}
}
Example #19
0
static int
read_jpeg_generate( VipsRegion *or,
                    void *seq, void *a, void *b, gboolean *stop )
{
    VipsRect *r = &or->valid;
    ReadJpeg *jpeg = (ReadJpeg *) a;
    struct jpeg_decompress_struct *cinfo = &jpeg->cinfo;
    int sz = cinfo->output_width * cinfo->output_components;

    int y;

#ifdef DEBUG
    printf( "read_jpeg_generate: line %d, %d rows\n",
            r->top, r->height );
#endif /*DEBUG*/

    /* We're inside a tilecache where tiles are the full image width, so
     * this should always be true.
     */
    g_assert( r->left == 0 );
    g_assert( r->width == or->im->Xsize );
    g_assert( VIPS_RECT_BOTTOM( r ) <= or->im->Ysize );

    /* Tiles should always be on a 8-pixel boundary.
     */
    g_assert( r->top % 8 == 0 );

    /* Tiles should always be a strip in height, unless it's the final
     * strip.
     */
    g_assert( r->height == VIPS_MIN( 8, or->im->Ysize - r->top ) );

    /* Here for longjmp() from vips__new_error_exit().
     */
    if( setjmp( jpeg->eman.jmp ) )
        return( -1 );

    for( y = 0; y < r->height; y++ ) {
        JSAMPROW row_pointer[1];

        row_pointer[0] = (JSAMPLE *)
                         VIPS_REGION_ADDR( or, 0, r->top + y );

        jpeg_read_scanlines( cinfo, &row_pointer[0], 1 );

        if( jpeg->invert_pels ) {
            int x;

            for( x = 0; x < sz; x++ )
                row_pointer[0][x] = 255 - row_pointer[0][x];
        }
    }

    return( 0 );
}
Example #20
0
/* Generate an area of @or. @ir is large enough.
 */
static void
vips_shrinkh_gen2( VipsShrinkh *shrink, VipsShrinkhSequence *seq,
	VipsRegion *or, VipsRegion *ir,
	int left, int top, int width )
{
	VipsResample *resample = VIPS_RESAMPLE( shrink );
	const int bands = resample->in->Bands * 
		(vips_band_format_iscomplex( resample->in->BandFmt ) ? 
		 	2 : 1);
	const int ne = shrink->xshrink * bands; 
	VipsPel *out = VIPS_REGION_ADDR( or, left, top ); 
	VipsPel *in = VIPS_REGION_ADDR( ir, left * shrink->xshrink, top ); 

	int x;
	int x1, b;

	switch( resample->in->BandFmt ) {
	case VIPS_FORMAT_UCHAR: 	
		ISHRINK( unsigned char ); break;
	case VIPS_FORMAT_CHAR: 	
		ISHRINK( char ); break; 
	case VIPS_FORMAT_USHORT: 
		ISHRINK( unsigned short ); break;
	case VIPS_FORMAT_SHORT: 	
		ISHRINK( short ); break; 
	case VIPS_FORMAT_UINT: 	
		ISHRINK( unsigned int ); break; 
	case VIPS_FORMAT_INT: 	
		ISHRINK( int );  break; 
	case VIPS_FORMAT_FLOAT: 	
		FSHRINK( float ); break; 
	case VIPS_FORMAT_DOUBLE:	
		FSHRINK( double ); break;
	case VIPS_FORMAT_COMPLEX: 	
		FSHRINK( float ); break; 
	case VIPS_FORMAT_DPCOMPLEX:	
		FSHRINK( double ); break;

	default:
		g_assert( 0 ); 
	}
}
Example #21
0
static int
png2vips_generate( VipsRegion *or, 
	void *seq, void *a, void *b, gboolean *stop )
{
        VipsRect *r = &or->valid;
	Read *read = (Read *) a;

	int y;

#ifdef DEBUG
	printf( "png2vips_generate: line %d, %d rows\n", 
		r->top, r->height );
#endif /*DEBUG*/

	/* We're inside a tilecache where tiles are the full image width, so
	 * this should always be true.
	 */
	g_assert( r->left == 0 );
	g_assert( r->width == or->im->Xsize );
	g_assert( VIPS_RECT_BOTTOM( r ) <= or->im->Ysize );

	/* Tiles should always be a strip in height, unless it's the final
	 * strip.
	 */
	g_assert( r->height == VIPS_MIN( 8, or->im->Ysize - r->top ) ); 

	/* And check that y_pos is correct. It should be, since we are inside
	 * a vips_sequential().
	 */
	g_assert( r->top == read->y_pos ); 

	for( y = 0; y < r->height; y++ ) {
		png_bytep q = (png_bytep) VIPS_REGION_ADDR( or, 0, r->top + y );

		/* We need to catch and ignore errors from read_row().
		 */
		if( !setjmp( png_jmpbuf( read->pPng ) ) ) 
			png_read_row( read->pPng, q, NULL );
		else { 
#ifdef DEBUG
			printf( "png2vips_generate: png_read_row() failed, "
				"line %d\n", r->top + y ); 
			printf( "png2vips_generate: file %s\n", read->name );
			printf( "png2vips_generate: thread %p\n", 
				g_thread_self() );
#endif /*DEBUG*/
		}

		read->y_pos += 1;
	}

	return( 0 );
}
Example #22
0
static int
vips_recomb_gen( VipsRegion *or, 
	void *seq, void *a, void *b, gboolean *stop )
{
	VipsRegion *ir = (VipsRegion *) seq;
	VipsRecomb *recomb = (VipsRecomb *) b;
	VipsImage *im = recomb->in;
	int mwidth = recomb->m->Xsize;
	int mheight = recomb->m->Ysize;

	int y, x, u, v;

	if( vips_region_prepare( ir, &or->valid ) ) 
		return( -1 );

	for( y = 0; y < or->valid.height; y++ ) {
		PEL *in = (PEL *) VIPS_REGION_ADDR( ir, 
			or->valid.left, or->valid.top + y );
		PEL *out = (PEL *) VIPS_REGION_ADDR( or, 
			or->valid.left, or->valid.top + y );

		switch( vips_image_get_format( im ) ) {
		case VIPS_FORMAT_UCHAR: LOOP( unsigned char, float ); break;
		case VIPS_FORMAT_CHAR: 	LOOP( signed char, float ); break; 
		case VIPS_FORMAT_USHORT:LOOP( unsigned short, float ); break; 
		case VIPS_FORMAT_SHORT: LOOP( signed short, float ); break; 
		case VIPS_FORMAT_UINT: 	LOOP( unsigned int, float ); break; 
		case VIPS_FORMAT_INT: 	LOOP( signed int, float );  break; 
		case VIPS_FORMAT_FLOAT: LOOP( float, float ); break; 
		case VIPS_FORMAT_DOUBLE:LOOP( double, double ); break; 

		default:
			g_assert( 0 );
		}
	}

	return( 0 );
}
Example #23
0
/* Byteswap, turning bands into the x axis.
 */
static int
vips_byteswap_gen( VipsRegion *or, 
	void *seq, void *a, void *b, gboolean *stop )
{
	VipsRegion *ir = (VipsRegion *) seq;
	VipsImage *im = ir->im;
	VipsRect *r = &or->valid;
	SwapFn swap = vips_byteswap_swap_fn[im->BandFmt];

	int y;

	if( vips_region_prepare( ir, r ) )
		return( -1 );

	for( y = 0; y < r->height; y++ ) {
		VipsPel *p = VIPS_REGION_ADDR( ir, r->left, r->top + y );
		VipsPel *q = VIPS_REGION_ADDR( or, r->left, r->top + y );

		swap( p, q, r->width, im );
	}

	return( 0 );
}
Example #24
0
void
vips_executor_set_scanline( VipsExecutor *executor, 
	VipsRegion *ir, int x, int y )
{
	VipsVector *vector = executor->vector;
	VipsPel *base = VIPS_REGION_ADDR( ir, x, y );
	int lsk = VIPS_REGION_LSKIP( ir );

	int i;

	for( i = 0; i < vector->n_scanline; i++ ) 
		vips_executor_set_array( executor, 
			vector->sl[i], base + vector->line[i] * lsk );
}
Example #25
0
static int
vips_bandunfold_gen( VipsRegion *or, 
	void *seq, void *a, void *b, gboolean *stop )
{
	VipsBandunfold *bandunfold = (VipsBandunfold *) b;
	VipsRegion *ir = (VipsRegion *) seq;
	VipsImage *in = ir->im;
	VipsImage *out = or->im;
	VipsRect *r = &or->valid;
	int esize = VIPS_IMAGE_SIZEOF_ELEMENT( in );
	int psize = VIPS_IMAGE_SIZEOF_PEL( out );

	VipsRect need;
	int y;

	need.left = r->left / bandunfold->factor;
	need.top = r->top;
	need.width = (1 + r->width) / bandunfold->factor;
	need.height = r->height;
	if( vips_region_prepare( ir, &need ) )
		return( -1 );

	for( y = 0; y < r->height; y++ ) {
		VipsPel *p = VIPS_REGION_ADDR( ir, 
			r->left / bandunfold->factor, r->top + y ) + 
			(r->left % bandunfold->factor) * esize;
		VipsPel *q = VIPS_REGION_ADDR( or, r->left, r->top + y );

		/* We can't use vips_region_region() since we change pixel
		 * coordinates.
		 */
		memcpy( q, p, r->width * psize );
	}

	return( 0 );
}
Example #26
0
static int
vips_arithmetic_gen( VipsRegion *or,
                     void *seq, void *a, void *b, gboolean *stop )
{
    VipsRegion **ir = (VipsRegion **) seq;
    VipsArithmetic *arithmetic = VIPS_ARITHMETIC( b );
    VipsArithmeticClass *class = VIPS_ARITHMETIC_GET_CLASS( arithmetic );
    Rect *r = &or->valid;

    VipsPel *p[MAX_INPUT_IMAGES], *q;
    int i, y;

    /* Prepare all input regions and make buffer pointers.
     */
    for( i = 0; ir[i]; i++ ) {
        if( vips_region_prepare( ir[i], r ) )
            return( -1 );
        p[i] = (VipsPel *) VIPS_REGION_ADDR( ir[i], r->left, r->top );
    }
    p[i] = NULL;
    q = (VipsPel *) VIPS_REGION_ADDR( or, r->left, r->top );

    VIPS_GATE_START( "vips_arithmetic_gen: work" );

    for( y = 0; y < r->height; y++ ) {
        class->process_line( arithmetic, q, p, r->width );

        for( i = 0; ir[i]; i++ )
            p[i] += VIPS_REGION_LSKIP( ir[i] );
        q += VIPS_REGION_LSKIP( or );
    }

    VIPS_GATE_STOP( "vips_arithmetic_gen: work" );

    return( 0 );
}
Example #27
0
static int
write_ppm_block( REGION *region, Rect *area, void *a )
{
	Write *write = (Write *) a;
	int i;

	for( i = 0; i < area->height; i++ ) {
		VipsPel *p = VIPS_REGION_ADDR( region, 0, area->top + i );

		if( write->fn( write->in, write->fp, p ) )
			return( -1 );
	}

	return( 0 );
}
Example #28
0
static int
vips_xyz_gen( VipsRegion *or, void *seq, void *a, void *b,
	gboolean *stop )
{
	VipsXyz *xyz = (VipsXyz *) a;
	VipsRect *r = &or->valid;
	int le = r->left;
	int to = r->top;
	int ri = VIPS_RECT_RIGHT( r );
	int bo = VIPS_RECT_BOTTOM( r );

	int x, y, i;

	for( y = to; y < bo; y++ ) {
		unsigned int *q = (unsigned int *) 
			VIPS_REGION_ADDR( or, le, y );

		unsigned int dims[5];
		int r;
		int h;

		h = xyz->height * xyz->csize * xyz->dsize; 
		dims[4] = y / h;
		r = y % h;

		h /= xyz->dsize; 
		dims[3] = r / h;
		r %= h;

		h /= xyz->csize; 
		dims[2] = r / h;
		r %= h;

		dims[1] = r;

		for( x = le; x < ri; x++ ) {
			dims[0] = x;
			for( i = 0; i < xyz->dimensions; i++ )
				q[i] = dims[i];

			q += xyz->dimensions;
		}
	}

	return( 0 );
}
Example #29
0
static int
vips__gdal_generate( VipsRegion *out, 
	void *_seq, void *_read, void *unused, gboolean *stop )
{
	Read *read = _read;
	VipsRect *r = &out->valid;
	int n = r->width * r->height;
	unsigned char *buf = (unsigned char *) VIPS_REGION_ADDR( out, r->left, r->top );

	VIPS_DEBUG_MSG( "vips__gdal_generate: %dx%d @ %dx%d\n",
		r->width, r->height, r->left, r->top );

	/* We're inside a cache, so requests should always be
	 * tile_width by tile_height pixels and on a tile boundary.
	 */
	g_assert( (r->left % read->tile_width) == 0 );
	g_assert( (r->top % read->tile_height) == 0 );
	g_assert( r->width <= read->tile_width );
	g_assert( r->height <= read->tile_height );

	g_assert( read->data_type == GDT_Byte );

	g_assert( GDALGetRasterCount );

  for (int channel = 0; channel < 3; ++channel) {

		GDALRasterBandH hBand;
		hBand = GDALGetRasterBand( read->hDataset, channel + 1 );

		unsigned char* gdal_data;
		gdal_data = (unsigned char*) CPLMalloc(sizeof(unsigned char) * r->width * r->height);
		GDALRasterIO( hBand, GF_Read, r->left, r->top, r->width, r->height, 
		              gdal_data, r->width, r->height, GDT_Byte, 
		              0, 0 );

		for (int i = 0; i < r->width * r->height; ++i) {
			buf[i * 3 + channel] = gdal_data[i];
		}

	  CPLFree (gdal_data);
	}

	return( 0 );
}
Example #30
0
/* Write tileh scanlines, less for the last strip.
 */
static int
layer_write_strip( Write *write, Layer *layer, VipsRegion *strip )
{
	VipsImage *im = layer->image;
	VipsRect *area = &strip->valid;
	int height = VIPS_MIN( write->tileh, area->height ); 

	int y;

#ifdef DEBUG_VERBOSE
	printf( "Writing %d pixel strip at height %d to image %s\n",
		height, area->top, TIFFFileName( layer->tif ) );
#endif /*DEBUG_VERBOSE*/

	for( y = 0; y < height; y++ ) {
		VipsPel *p = VIPS_REGION_ADDR( strip, 0, area->top + y );

		/* Any repacking necessary.
		 */
		if( im->Coding == VIPS_CODING_LABQ ) {
			LabQ2LabC( write->tbuf, p, im->Xsize );
			p = write->tbuf;
		}
		else if( im->BandFmt == VIPS_FORMAT_SHORT &&
			im->Type == VIPS_INTERPRETATION_LABS ) {
			LabS2Lab16( write->tbuf, p, im->Xsize );
			p = write->tbuf;
		}
		else if( write->onebit ) {
			eightbit2onebit( write, write->tbuf, p, im->Xsize );
			p = write->tbuf;
		}
		else if( (im->Bands == 1 || im->Bands == 2) && 
			write->miniswhite ) {
			invert_band0( write, write->tbuf, p, im->Xsize );
			p = write->tbuf;
		}

		if( TIFFWriteScanline( layer->tif, p, area->top + y, 0 ) < 0 ) 
			return( -1 );
	}

	return( 0 );
}