Example #1
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 );
}
Example #2
0
/* Generate a region of pixels ... with threads! Very like im_prepare(), but
 * threaded and does sub-division. 
 */
int
im_prepare_thread( im_threadgroup_t *tg, REGION *or, Rect *r )
{
	IMAGE *im = or->im;

	g_assert( !im_image_sanity( im ) );

	switch( im->dtype ) {
	case IM_PARTIAL:
                if( im_region_fill( or, r,
			(im_region_fill_fn) eval_to_region, tg ) )
                        return( -1 );

		break;

	case IM_OPENIN:
	case IM_SETBUF:
        case IM_SETBUF_FOREIGN:
	case IM_MMAPIN:
	case IM_MMAPINRW:
		/* Attach to existing buffer.
		 */
		if( im_region_image( or, r ) )
			return( -1 );

		break;

	default:
		im_error( "im_prepare_thread", _( "unable to input from a %s "
			"image" ), im_dtype2char( im->dtype ) );
		return( -1 );
	}

	return( 0 );
}
Example #3
0
/**
 * im_generate:
 * @im: generate this image
 * @start: start sequences with this function
 * @generate: generate pixels with this function
 * @stop: stop sequences with this function
 * @a: user data
 * @b: user data
 *
 * Generates an image. The action depends on the image type.
 *
 * For images opened with "p", im_generate() just attaches the
 * start/generate/stop callbacks and returns.
 *
 * For "t" images, memory is allocated for the whole image and it is entirely
 * generated using vips_sink().
 *
 * For "w" images, memory for a few scanlines is allocated and
 * vips_sink_disc() used to generate the image in small chunks. As each
 * chunk is generated, it is written to disc.
 *
 * See also: vips_sink(), im_open(), im_prepare(), im_wrapone().
 *
 * Returns: 0 on success, or -1 on error.
 */
int
im_generate( IMAGE *im,
             im_start_fn start, im_generate_fn generate, im_stop_fn stop,
             void *a, void *b )
{
    int res;

    g_assert( !im_image_sanity( im ) );

    if( !im->hint_set ) {
        im_error( "im_generate",
                  "%s", _( "im_demand_hint() not set" ) );
        return( -1 );
    }

    if( im->Xsize <= 0 || im->Ysize <= 0 || im->Bands <= 0 ) {
        im_error( "im_generate",
                  "%s", _( "bad dimensions" ) );
        return( -1 );
    }

    /* We don't use this, but make sure it's set in case any old binaries
     * are expectiing it.
     */
    im->Bbits = im_bits_of_fmt( im->BandFmt );

    /* Look at output type to decide our action.
     */
    switch( im->dtype ) {
    case IM_PARTIAL:
        /* Output to partial image. Just attach functions and return.
         */
        if( im->generate || im->start || im->stop ) {
            im_error( "im_generate",
                      "%s", _( "func already attached" ) );
            return( -1 );
        }

        im->start = start;
        im->generate = generate;
        im->stop = stop;
        im->client1 = a;
        im->client2 = b;

#ifdef DEBUG_IO
        printf( "im_generate: attaching partial callbacks\n" );
#endif /*DEBUG_IO*/

        break;

    case IM_SETBUF:
    case IM_SETBUF_FOREIGN:
    case IM_MMAPINRW:
    case IM_OPENOUT:
        /* Eval now .. sanity check.
         */
        if( im->generate || im->start || im->stop ) {
            im_error( "im_generate",
                      "%s", _( "func already attached" ) );
            return( -1 );
        }

        /* Get output ready.
         */
        if( im_setupout( im ) )
            return( -1 );

        /* Attach callbacks.
         */
        im->start = start;
        im->generate = generate;
        im->stop = stop;
        im->client1 = a;
        im->client2 = b;

        if( im->dtype == IM_OPENOUT )
            res = vips_sink_disc( im,
                                  (VipsRegionWrite) write_vips, NULL );
        else
            res = vips_sink_memory( im );

        /* Error?
         */
        if( res )
            return( -1 );

        break;

    default:
        /* Not a known output style.
         */
        im_error( "im_generate", _( "unable to output to a %s image" ),
                  im_dtype2char( im->dtype ) );
        return( -1 );
    }

    /* Successful write: trigger "written".
     */
    if( im__trigger_callbacks( im->writtenfns ) )
        return( -1 );

    return( 0 );
}
Example #4
0
/* Make REGION reg ready for input of area r. For most image types, we can
 * just im_attach, for PARTIAL though we may need to generate. 
 */
int
im_prepare( REGION *reg, Rect *r )
{	
	IMAGE *im = reg->im;

	Rect save = *r;

	im__region_check_ownership( reg );

	if( im__test_kill( im ) )
		return( -1 );

	/* We use save for sanity checking valid: we test at the end that the
	 * pixels we have generated are indeed all the ones that were asked
	 * for.
	 *
	 * However, r may be clipped by the image size, so we need to clip
	 * save as well to make sure we don't fail the assert due to that.
	 */
{	
	Rect image;

	image.left = 0;
	image.top = 0;
	image.width = reg->im->Xsize;
	image.height = reg->im->Ysize;
	im_rect_intersectrect( &save, &image, &save );
}

#ifdef DEBUG
        printf( "im_prepare: left = %d, top = %d, width = %d, height = %d\n",
		r->left, r->top, r->width, r->height );
#endif /*DEBUG*/

	switch( im->dtype ) {
	case IM_PARTIAL:
		if( im_region_fill( reg, r, 
			(im_region_fill_fn) fill_region, NULL ) )
			return( -1 );

		break;

	case IM_SETBUF:
	case IM_SETBUF_FOREIGN:
	case IM_MMAPIN:
	case IM_MMAPINRW:
	case IM_OPENIN:
		/* Attach to existing buffer.
		 */
		if( im_region_image( reg, r ) )
			return( -1 );

		break;

	default:
		im_error( "im_prepare", _( "unable to input from a %s image" ),
			im_dtype2char( im->dtype ) );
		return( -1 );
	}

	/* valid should now include all the pixels that were asked for.
	 */
	assert( im_rect_includesrect( &reg->valid, &save ) );

	return( 0 );
}
Example #5
0
void 
im_printdesc( IMAGE *image )
{	
	if( !image ) {
		printf( "NULL descriptor\n" );
		return;
	}

	printf( "IMAGE* %p\n", image );

	if( im_isMSBfirst( image ) )
		printf( "SPARC (MSB first) " );
	else
		printf( "Intel (LSB first) " );
	printf( "byte order image, on a " );
	if( im_amiMSBfirst() )
		printf( "SPARC (MSB first) " );
	else
		printf( "Intel (LSB first) " );
	printf( "byte order machine\n" );
 
	(void) im_header_map( image, (im_header_map_fn) print_field_fn, NULL );

	printf( "Hist: %s", im_history_get( image ) );

	/* Print other (non-header) fields.
	 */
	if( image->generate )
		printf( "generate function attached\n" );
	if( image->closefns )
		printf( "close callbacks attached\n" );
	if( image->evalfns )
		printf( "eval callbacks attached\n" );
	if( image->evalendfns )
		printf( "evalend callbacks attached\n" );
	if( image->evalstartfns )
		printf( "evalstart callbacks attached\n" );
	if( image->preclosefns )
		printf( "preclose callbacks attached\n" );
	if( image->invalidatefns )
		printf( "invalidate callbacks attached\n" );
	if( image->regions ) {
		printf( "%d regions present\n", 
			g_slist_length( image->regions ) );
		im_slist_map2( image->regions, 
			(VSListMap2Fn) print_region, NULL, NULL );
	}
	if( image->kill )
		printf( "kill flag set\n" );
	if( image->closing )
		printf( "closing flag set\n" );
	if( image->close_pending )
		printf( "close_pending flag set\n" );

#ifdef DEBUG
	/* Can't get these with im_header_get(), so only show for debugging.
	 */
	printf( "dhint: %s\n", im_dhint2char( image->dhint ) );
	printf( "dtype: %s\n", im_dtype2char( image->dtype ) );
#endif /*DEBUG*/
}
Example #6
0
/* Attach a generate function to an image.
 */
int
im_generate( IMAGE *im,
	im_start_fn start, im_generate_fn generate, im_stop_fn stop,
        void *a, void *b )
{
        int res;
	REGION *or;
	im_threadgroup_t *tg;

	g_assert( !im_image_sanity( im ) );

	if( im->Xsize <= 0 || im->Ysize <= 0 || im->Bands <= 0 ) {
		im_error( "im_generate", _( "bad dimensions" ) );
		return( -1 );
	}
 
        /* Look at output type to decide our action.
         */
        switch( im->dtype ) {
        case IM_PARTIAL:
                /* Output to partial image. Just attach functions and return.
                 */
                if( im->generate || im->start || im->stop ) {
                        im_error( "im_generate", _( "func already attached" ) );
                        return( -1 );
                }

                im->start = start;
                im->generate = generate;
                im->stop = stop;
                im->client1 = a;
                im->client2 = b;
 
#ifdef DEBUG_IO
                printf( "im_generate: attaching partial callbacks\n" );
#endif /*DEBUG_IO*/
 
                break;
 
        case IM_SETBUF:
        case IM_SETBUF_FOREIGN:
        case IM_MMAPINRW:
        case IM_OPENOUT:
                /* Eval now .. sanity check.
                 */
                if( im->generate || im->start || im->stop ) {
                        im_error( "im_generate", _( "func already attached" ) );
                        return( -1 );
                }

                /* Get output ready.
                 */
                if( im_setupout( im ) )
                        return( -1 );

                /* Attach callbacks.
                 */
                im->start = start;
                im->generate = generate;
                im->stop = stop;
                im->client1 = a;
                im->client2 = b;

                /* Evaluate. Two output styles: to memory area (im_setbuf()
                 * or im_mmapinrw()) or to file (im_openout()).
                 */
		if( !(or = im_region_create( im )) )
			return( -1 );
		if( !(tg = im_threadgroup_create( im )) ) {
			im_region_free( or );
			return( -1 );
		}
                if( im->dtype == IM_OPENOUT )
                        res = im_wbuffer( tg, write_vips, NULL, NULL );
                else
                        res = eval_to_memory( tg, or );

                /* Clean up.
                 */
		im_threadgroup_free( tg );
		im_region_free( or );

                /* Error?
                 */
                if( res )
                        return( -1 );
 
                break;
 
        default:
                /* Not a known output style.
                 */
		im_error( "im_generate", _( "unable to output to a %s image" ),
			im_dtype2char( im->dtype ) );
                return( -1 );
        }
 
        return( 0 );
}