/* Like im_insert, but perform an in-place insertion. */ int im_insertplace( IMAGE *big, IMAGE *small, int x, int y ) { Rect br, sr; PEL *p, *q; int z; /* Check IO. */ if( im_rwcheck( big ) || im_incheck( small ) ) return( -1 ); /* Check compatibility. */ if( big->BandFmt != small->BandFmt || big->Bands != small->Bands || big->Coding != small->Coding ) { im_error( "im_insertplace", _( "inputs differ in format" ) ); return( -1 ); } if( big->Coding != IM_CODING_NONE && big->Coding != IM_CODING_LABQ ) { im_error( "im_insertplace", _( "input should be uncoded " "or IM_CODING_LABQ" ) ); return( -1 ); } /* Make rects for big and small. */ br.left = 0; br.top = 0; br.width = big->Xsize; br.height = big->Ysize; sr.left = x; sr.top = y; sr.width = small->Xsize; sr.height = small->Ysize; /* Small fits inside big? */ if( !im_rect_includesrect( &br, &sr ) ) { im_error( "im_insertplace", _( "small not inside big" ) ); return( -1 ); } /* Loop, memcpying small to big. */ p = (PEL *) IM_IMAGE_ADDR( small, 0, 0 ); q = (PEL *) IM_IMAGE_ADDR( big, x, y ); for( z = 0; z < small->Ysize; z++ ) { memcpy( (char *) q, (char *) p, IM_IMAGE_SIZEOF_LINE( small ) ); p += IM_IMAGE_SIZEOF_LINE( small ); q += IM_IMAGE_SIZEOF_LINE( big ); } im_invalidate( big ); return( 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 ); }
/* 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 ); }
/* Print a one-line description of an image, with an index. */ static void * print_one_line( IMAGE *im, int *n, int *total ) { printf( "%2d) %p, %s, %s: %dx%d, %d bands, %s\n", *n, im, im_dtype2char( im->dtype ), im->filename, im->Xsize, im->Ysize, im->Bands, im_BandFmt2char( im->BandFmt ) ); *n += 1; if( im->dtype == IM_SETBUF && im->data ) { int size = IM_IMAGE_SIZEOF_LINE( im ) * im->Ysize; printf( "\t*** %d malloced bytes\n", size ); *total += size; } if( im->regions ) { int n2; int total2; printf( "\t%d regions\n", g_slist_length( im->regions ) ); n2 = 0; total2 = 0; (void) im_slist_map2( im->regions, (VSListMap2Fn) print_one_line_region, &n2, &total2 ); if( total2 ) printf( "\t*** using total of %d bytes\n", total2 ); *total += total2; } return( NULL ); }
/* 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 ); }
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 ); }
/** * im_draw_image: * @image: image to draw on * @sub: image to draw * @x: position to insert * @y: position to insert * * Draw @sub on top of @image at position @x, @y. The two images must have the * same * Coding. If @sub has 1 band, the bands will be duplicated to match the * number of bands in @image. @sub will be converted to @image's format, see * im_clip2fmt(). * * See also: im_insert(). * * Returns: 0 on success, or -1 on error. */ int im_draw_image( VipsImage *image, VipsImage *sub, int x, int y ) { Rect br, sr, clip; PEL *p, *q; int z; /* Make rects for main and sub and clip. */ br.left = 0; br.top = 0; br.width = image->Xsize; br.height = image->Ysize; sr.left = x; sr.top = y; sr.width = sub->Xsize; sr.height = sub->Ysize; im_rect_intersectrect( &br, &sr, &clip ); if( im_rect_isempty( &clip ) ) return( 0 ); if( !(sub = im__inplace_base( "im_draw_image", image, sub, image )) || im_rwcheck( image ) || im_incheck( sub ) ) return( -1 ); /* Loop, memcpying sub to main. */ p = (PEL *) IM_IMAGE_ADDR( sub, clip.left - x, clip.top - y ); q = (PEL *) IM_IMAGE_ADDR( image, clip.left, clip.top ); for( z = 0; z < clip.height; z++ ) { memcpy( (char *) q, (char *) p, clip.width * IM_IMAGE_SIZEOF_PEL( sub ) ); p += IM_IMAGE_SIZEOF_LINE( sub ); q += IM_IMAGE_SIZEOF_LINE( image ); } return( 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 ); }
Draw * im__draw_init( Draw *draw, IMAGE *im, PEL *ink ) { if( im_rwcheck( im ) ) return( NULL ); draw->im = im; draw->ink = NULL; draw->lsize = IM_IMAGE_SIZEOF_LINE( im ); draw->psize = IM_IMAGE_SIZEOF_PEL( im ); draw->noclip = FALSE; if( ink ) { if( !(draw->ink = (PEL *) im_malloc( NULL, draw->psize )) ) return( NULL ); memcpy( draw->ink, ink, draw->psize ); } return( draw ); }
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 ); }
/* 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 ); }
/* Sort of open for read for image files. Shared with im_binfile(). */ int im__open_image_file( const char *filename ) { int fd; /* Try to open read-write, so that calls to im_makerw() will work. * When we later mmap this file, we set read-only, so there * is little danger of scrubbing over files we own. */ #ifdef BINARY_OPEN if( (fd = open( filename, O_RDWR | O_BINARY )) == -1 ) { #else /*BINARY_OPEN*/ if( (fd = open( filename, O_RDWR )) == -1 ) { #endif /*BINARY_OPEN*/ /* Open read-write failed. Fall back to open read-only. */ #ifdef BINARY_OPEN if( (fd = open( filename, O_RDONLY | O_BINARY )) == -1 ) { #else /*BINARY_OPEN*/ if( (fd = open( filename, O_RDONLY )) == -1 ) { #endif /*BINARY_OPEN*/ im_error( "im__open_image_file", _( "unable to open \"%s\", %s" ), filename, strerror( errno ) ); return( -1 ); } } return( fd ); } /* Predict the size of the header plus pixel data. Don't use off_t, * it's sometimes only 32 bits (eg. on many windows build environments) and we * want to always be 64 bit. */ static gint64 im__image_pixel_length( IMAGE *im ) { gint64 psize; switch( im->Coding ) { case IM_CODING_LABQ: case IM_CODING_NONE: psize = (gint64) IM_IMAGE_SIZEOF_LINE( im ) * im->Ysize; break; default: psize = im->Length; break; } return( psize + im->sizeof_header ); } /* Read short/int/float LSB and MSB first. */ void im__read_4byte( int msb_first, unsigned char *to, unsigned char **from ) { unsigned char *p = *from; int out; if( msb_first ) out = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; else out = p[3] << 24 | p[2] << 16 | p[1] << 8 | p[0]; *from += 4; *((guint32 *) to) = out; }
/** * 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 ); }
/* 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 ); }
/* 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 ); }
/* 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 ); }
/** * im_region_image: * @reg: region to operate upon * @r: #Rect of pixels you need to be able to address * * The region is transformed so that at least @r pixels are available directly * from the image. The image needs to be a memory buffer or represent a file * on disc that has been mapped or can be mapped. * * Returns: 0 on success, or -1 for error. */ int im_region_image( REGION *reg, Rect *r ) { Rect image; Rect clipped; /* Sanity check. */ im__region_check_ownership( reg ); /* Clip against image. */ image.top = 0; image.left = 0; image.width = reg->im->Xsize; image.height = reg->im->Ysize; im_rect_intersectrect( r, &image, &clipped ); /* Test for empty. */ if( im_rect_isempty( &clipped ) ) { im_error( "im_region_image", "%s", _( "valid clipped to nothing" ) ); return( -1 ); } if( reg->im->data ) { /* We have the whole image available ... easy! */ im_region_reset( reg ); /* We can't just set valid = clipped, since this may be an * incompletely calculated memory buffer. Just set valid to r. */ reg->valid = clipped; reg->bpl = IM_IMAGE_SIZEOF_LINE( reg->im ); reg->data = reg->im->data + (gint64) clipped.top * IM_IMAGE_SIZEOF_LINE( reg->im ) + clipped.left * IM_IMAGE_SIZEOF_PEL( reg->im ); reg->type = IM_REGION_OTHER_IMAGE; } else if( reg->im->dtype == IM_OPENIN ) { /* No complete image data ... but we can use a rolling window. */ if( reg->type != IM_REGION_WINDOW || !reg->window || reg->window->top > clipped.top || reg->window->top + reg->window->height < clipped.top + clipped.height ) { im_region_reset( reg ); if( !(reg->window = im_window_ref( reg->im, clipped.top, clipped.height )) ) return( -1 ); reg->type = IM_REGION_WINDOW; } /* Note the area the window actually represents. */ reg->valid.left = 0; reg->valid.top = reg->window->top; reg->valid.width = reg->im->Xsize; reg->valid.height = reg->window->height; reg->bpl = IM_IMAGE_SIZEOF_LINE( reg->im ); reg->data = reg->window->data; } else { im_error( "im_region_image", "%s", _( "bad image type" ) ); return( -1 ); } return( 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); }
/* 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 ); }