Exemplo n.º 1
0
int combineblk(RECPOS ads, int size)
{
    ENTRY  e;
    RECPOS address;
    int    esize, off, ret, saveoff, ibuff;
    ret = 0;
    saveoff = CO(--(pci->level));
    retrieve_block(pci->level, CB(pci->level));
    if ((off = next_entry( saveoff )) < block_ptr->bend)
        /* combine with page on right */
    {
        if ((ENT_SIZE(ENT_ADR(block_ptr, off)) + size) < (uint32_t)split_size)
        {
            copy_entry(&e, ENT_ADR(block_ptr, off));
            address = ENT_ADR(block_ptr, CO(pci->level))->idxptr;
            retrieve_block(++pci->level, address);
            ibuff = cache_ptr;
            spare_block = block_ptr;
            retrieve_block(pci->level, ads);
            esize = ENT_SIZE(&e);
            if(((block_ptr->bend + spare_block->bend + esize) >= split_size)&& (spare_block->bend <= block_ptr->bend + esize)) 
            {
                return  ret;
            }

            e.idxptr = spare_block->p0;
            ins_block(block_ptr, &e, block_ptr->bend);
            update_block();
            if ((block_ptr->bend + spare_block->bend) < split_size)
                /* combine the blocks */
            {
                memcpy(ENT_ADR(block_ptr, block_ptr->bend),ENT_ADR(spare_block, 0),spare_block->bend);
                block_ptr->bend += spare_block->bend;
                write_free(spare_block->brec, spare_block);
                BUFDIRTY(ibuff) = 0;
                BUFHANDLE(ibuff) = 0;
                --pci->level;
                ret = 1;
            }
            else
                /* move an entry up to replace the one moved */
            {
                copy_entry(&e, ENT_ADR(spare_block, 0));
                esize = ENT_SIZE(&e);
                movedown(spare_block, 0, esize);
                spare_block->bend -= esize;
                spare_block->p0 = e.idxptr;
                BUFDIRTY(ibuff) = 1;
                --(pci->level);
                replace_entry(&e);
            }
        }
    }
    else
        /* move from page on left */
    {
        if ( (ENT_SIZE(ENT_ADR(block_ptr, CO(pci->level))) + size) < (uint32_t)split_size)
        {
            copy_entry(&e, ENT_ADR(block_ptr, saveoff));
            off = prev_entry(saveoff);

            if (CO(pci->level) == -1) 
                address = block_ptr->p0;
            else 
                address = ENT_ADR(block_ptr, CO(pci->level))->idxptr;

            retrieve_block(++pci->level, address);
            off = last_entry();
            ibuff = cache_ptr;
            spare_block = block_ptr;
            retrieve_block(pci->level, ads);
            esize = ENT_SIZE(&e);

            if(((block_ptr->bend + spare_block->bend + esize) >= split_size)&& (spare_block->bend <= block_ptr->bend + esize))
            {
                return ret;
            }

            BUFDIRTY(ibuff) = 1;
            CO(pci->level) = 0;
            e.idxptr = block_ptr->p0;
            ins_block(block_ptr, &e, 0);
            if ((block_ptr->bend + spare_block->bend) < split_size)
                /* combine the blocks */
            {
                memcpy(ENT_ADR(spare_block, spare_block->bend),ENT_ADR(block_ptr, 0),block_ptr->bend);
                spare_block->bend += block_ptr->bend;
                write_free(block_ptr->brec, block_ptr);
                BUFDIRTY(cache_ptr) = 0;
                BUFHANDLE(cache_ptr) = 0;
                CO(--(pci->level)) = saveoff;
                ret = 1;
            }
            else
                /* move an entry up to replace the one moved */
            {
                block_ptr->p0 = ENT_ADR(spare_block,off)->idxptr;
                copy_entry(&e, ENT_ADR(spare_block, off));
                spare_block->bend = off;
                update_block();
                CO(--(pci->level)) = saveoff;
                replace_entry(&e);
            }
        }
    }
    root_dirty = 1;

    return ret;
} 
Exemplo n.º 2
0
/* Make and init a Write.
 */
static Write *
write_new( VipsImage *im, const char *filename,
	VipsForeignTiffCompression compression, int Q, 
		VipsForeignTiffPredictor predictor,
	char *profile,
	gboolean tile, int tile_width, int tile_height,
	gboolean pyramid,
	gboolean squash,
	gboolean miniswhite,
	VipsForeignTiffResunit resunit, double xres, double yres,
	gboolean bigtiff,
	gboolean rgbjpeg,
	gboolean properties,
	gboolean strip )
{
	Write *write;

	if( !(write = VIPS_NEW( im, Write )) )
		return( NULL );
	write->im = im;
	write->filename = vips_strdup( VIPS_OBJECT( im ), filename );
	write->layer = NULL;
	write->tbuf = NULL;
	write->compression = get_compression( compression );
	write->jpqual = Q;
	write->predictor = predictor;
	write->tile = tile;
	write->tilew = tile_width;
	write->tileh = tile_height;
	write->pyramid = pyramid;
	write->onebit = squash;
	write->miniswhite = miniswhite;
	write->icc_profile = vips_strdup( NULL, profile );
	write->bigtiff = bigtiff;
	write->rgbjpeg = rgbjpeg;
	write->properties = properties;
	write->strip = strip;

	write->resunit = get_resunit( resunit );
	write->xres = xres;
	write->yres = yres;

	/* In strip mode we use tileh to set rowsperstrip, and that does not
	 * have the multiple-of-16 restriction.
	 */
	if( tile ) { 
		if( (write->tilew & 0xf) != 0 || 
			(write->tileh & 0xf) != 0 ) {
			vips_error( "vips2tiff", 
				"%s", _( "tile size not a multiple of 16" ) );
			return( NULL );
		}
	}

	/* We can only pyramid LABQ and non-complex images. 
	 */
	if( write->pyramid ) {
		if( im->Coding == VIPS_CODING_NONE && 
			vips_band_format_iscomplex( im->BandFmt ) ) {
			vips_error( "vips2tiff", 
				"%s", _( "can only pyramid LABQ and "
				"non-complex images" ) );
			return( NULL );
		}
	}

	/* Only 1-bit-ize 8 bit mono images.
	 */
	if( write->onebit &&
		(im->Coding != VIPS_CODING_NONE || 
			im->BandFmt != VIPS_FORMAT_UCHAR ||
			im->Bands != 1) ) {
		vips_warn( "vips2tiff", 
			"%s", _( "can only squash 1 band uchar images -- "
				"disabling squash" ) );
		write->onebit = 0;
	}

	if( write->onebit && 
		write->compression == COMPRESSION_JPEG ) {
		vips_warn( "vips2tiff", 
			"%s", _( "can't have 1-bit JPEG -- disabling JPEG" ) );
		write->compression = COMPRESSION_NONE;
	}
 
	/* We can only MINISWHITE non-complex images of 1 or 2 bands.
	 */
	if( write->miniswhite &&
		(im->Coding != VIPS_CODING_NONE || 
			vips_band_format_iscomplex( im->BandFmt ) ||
			im->Bands > 2) ) {
		vips_warn( "vips2tiff", 
			"%s", _( "can only save non-complex greyscale images "
				"as miniswhite -- disabling miniswhite" ) );
		write->miniswhite = FALSE;
	}

	/* Sizeof a line of bytes in the TIFF tile.
	 */
	if( im->Coding == VIPS_CODING_LABQ )
		write->tls = write->tilew * 3;
	else if( write->onebit )
		write->tls = VIPS_ROUND_UP( write->tilew, 8 ) / 8;
	else
		write->tls = VIPS_IMAGE_SIZEOF_PEL( im ) * write->tilew;

	/* Build the pyramid framework.
	 */
	write->layer = pyramid_new( write, NULL, im->Xsize, im->Ysize );

	/* Fill all the layers.
	 */
	if( pyramid_fill( write ) ) {
		write_free( write );
		return( NULL );
	}

	if( tile ) 
		write->tbuf = vips_malloc( NULL, 
			TIFFTileSize( write->layer->tif ) );
	else
		write->tbuf = vips_malloc( NULL, 
			TIFFScanlineSize( write->layer->tif ) );
	if( !write->tbuf ) {
		write_free( write );
		return( NULL );
	}

	return( write );
}
Exemplo n.º 3
0
/* BPLUS delete key functions */
int delete_key(ENTRY *pe, IX_DESC *pix)
{
    ENTRY   e;
    RECPOS  ads;
    int     h, leveli, levelf;
    if (!find_exact(pe, pix))  
    {
        return (IX_NOTEXISTED);
    }
    h = 1;
    if ((ads = pe->idxptr) != NULLREC)
    {
        leveli = pci->level;
        do
        {
            retrieve_block(++(pci->level), ads);
            CO(pci->level) = -1;
        }

        while ((ads = block_ptr->p0) != NULLREC);
        CO(pci->level) = 0;
        copy_entry(&e, ENT_ADR(block_ptr, CO(pci->level)));
        levelf = pci->level;
        pci->level = leveli;
        replace_entry(&e);
        pci->level = levelf;
        /*update_root(&pci->root);*/
    }
    while ( h )
    {
        retrieve_block(pci->level, CB(pci->level));
        del_block(block_ptr, CO(pci->level));
        update_block();
        if ( (pci->level == 0) && (block_ptr->bend == 0))
            /* tree was reduced in height */
        {
            if (pci->root.p0 != NULLREC)
            {
                retrieve_block(++pci->level, pci->root.p0);
                memcpy(&(pci->root), block_ptr, sizeof(BLOCK));
                (pci->dx.nl)--;
                write_free(block_ptr->brec, block_ptr);
                BUFDIRTY(cache_ptr) = 0;
                BUFHANDLE(cache_ptr) = 0;
                update_root(&pci->root);
            }

            break;
        }
        h = (block_ptr->bend < comb_size) && (pci->level > 0);
        if ( h )
        {
            h = combineblk(CB(pci->level), block_ptr->bend);
        }
    }

    /*return flush_index(pix);*/
    if(root_dirty == 1)
    {
        flush_index(pix);
        root_dirty = 0;
    }

    return(IX_OK);
} 
Exemplo n.º 4
0
int 
vips__tiff_write( VipsImage *in, const char *filename, 
	VipsForeignTiffCompression compression, int Q, 
	VipsForeignTiffPredictor predictor,
	char *profile,
	gboolean tile, int tile_width, int tile_height,
	gboolean pyramid,
	gboolean squash,
	gboolean miniswhite,
	VipsForeignTiffResunit resunit, double xres, double yres,
	gboolean bigtiff,
	gboolean rgbjpeg,
	gboolean properties, gboolean strip )
{
	Write *write;

#ifdef DEBUG
	printf( "tiff2vips: libtiff version is \"%s\"\n", TIFFGetVersion() );
#endif /*DEBUG*/

	vips__tiff_init();

	if( vips_check_coding_known( "vips2tiff", in ) )
		return( -1 );

	/* Make output image. 
	 */
	if( !(write = write_new( in, filename,
		compression, Q, predictor, profile,
		tile, tile_width, tile_height, pyramid, squash,
		miniswhite, resunit, xres, yres, bigtiff, rgbjpeg, 
		properties, strip )) )
		return( -1 );

	if( vips_sink_disc( write->im, write_strip, write ) ) {
		write_free( write );
		return( -1 );
	}

	if( !TIFFWriteDirectory( write->layer->tif ) ) 
		return( -1 );

	if( write->pyramid ) { 
		/* Free lower pyramid resources ... this will TIFFClose() (but
		 * not delete) the smaller layers ready for us to read from 
		 * them again.
		 */
		if( write->layer->below )
			pyramid_free( write->layer->below );

		/* Append smaller layers to the main file.
		 */
		if( write_gather( write ) ) {
			write_free( write );
			return( -1 );
		}
	}

	write_free( write );

	return( 0 );
}