コード例 #1
0
ファイル: region.c プロジェクト: AlexSteel/wine
/* compute the union of two regions into dst, which can be one of the source regions */
struct region *union_region( struct region *dst, const struct region *src1,
                             const struct region *src2 )
{
    if (src1 == src2) return copy_region( dst, src1 );
    if (!src1->num_rects) return copy_region( dst, src2 );
    if (!src2->num_rects) return copy_region( dst, src1 );

    if ((src1->num_rects == 1) &&
        (src1->extents.left <= src2->extents.left) &&
        (src1->extents.top <= src2->extents.top) &&
        (src1->extents.right >= src2->extents.right) &&
        (src1->extents.bottom >= src2->extents.bottom))
        return copy_region( dst, src1 );

    if ((src2->num_rects == 1) &&
        (src2->extents.left <= src1->extents.left) &&
        (src2->extents.top <= src1->extents.top) &&
        (src2->extents.right >= src1->extents.right) &&
        (src2->extents.bottom >= src1->extents.bottom))
        return copy_region( dst, src2 );

    if (!region_op( dst, src1, src2, union_overlapping,
                    union_non_overlapping, union_non_overlapping )) return NULL;

    dst->extents.left = min(src1->extents.left, src2->extents.left);
    dst->extents.top = min(src1->extents.top, src2->extents.top);
    dst->extents.right = max(src1->extents.right, src2->extents.right);
    dst->extents.bottom = max(src1->extents.bottom, src2->extents.bottom);
    return dst;
}
コード例 #2
0
ファイル: mmio.c プロジェクト: fbezdeka/jailhouse
/**
 * Unregister MMIO region from a cell.
 * @param cell		Cell the region belongs to.
 * @param start		Region start address as it was passed to
 * 			mmio_region_register().
 *
 * @see mmio_region_register
 */
void mmio_region_unregister(struct cell *cell, unsigned long start)
{
	int index;

	spin_lock(&cell->mmio_region_lock);

	index = find_region(cell, start, 1, NULL, NULL);
	if (index >= 0) {
		/*
		 * Advance the generation to odd value, indicating that
		 * modifications are ongoing. Commit this change via a barrier
		 * so that other CPUs will see it before we start.
		 */
		cell->mmio_generation++;
		memory_barrier();

		for (/* empty */; index < cell->num_mmio_regions; index++)
			copy_region(cell, index + 1, index);

		cell->num_mmio_regions--;

		/*
		 * Ensure all regions and their number are committed before
		 * advancing the generation.
		 */
		memory_barrier();
		cell->mmio_generation++;
	}
	spin_unlock(&cell->mmio_region_lock);
}
コード例 #3
0
ファイル: region.c プロジェクト: AlexSteel/wine
/* compute the subtraction of two regions into dst, which can be one of the source regions */
struct region *subtract_region( struct region *dst, const struct region *src1,
                                const struct region *src2 )
{
    if (!src1->num_rects || !src2->num_rects || !EXTENTCHECK(&src1->extents, &src2->extents))
        return copy_region( dst, src1 );

    if (!region_op( dst, src1, src2, subtract_overlapping,
                    subtract_non_overlapping, NULL )) return NULL;
    set_region_extents( dst );
    return dst;
}
コード例 #4
0
ファイル: tilecache.c プロジェクト: alon/libvips
/* Generate func.
 */
static int
vips_tile_cache_gen( VipsRegion *or, 
	void *seq, void *a, void *b, gboolean *stop )
{
	VipsRegion *in = (VipsRegion *) seq;
	VipsTileCache *cache = (VipsTileCache *) b;
	const int tw = cache->tile_width;
	const int th = cache->tile_height;
	VipsRect *r = &or->valid;

	/* Find top left of tiles we need.
	 */
	int xs = (r->left / tw) * tw;
	int ys = (r->top / th) * th;

	int x, y;

	g_mutex_lock( cache->lock );

	VIPS_DEBUG_MSG( "vips_tile_cache_gen: "
		"left = %d, top = %d, width = %d, height = %d\n",
		r->left, r->top, r->width, r->height );

	for( y = ys; y < VIPS_RECT_BOTTOM( r ); y += th )
		for( x = xs; x < VIPS_RECT_RIGHT( r ); x += tw ) {
			Tile *tile;
			VipsRect tarea;
			VipsRect hit;

			if( !(tile = tile_find( cache, in, x, y )) ) {
				g_mutex_unlock( cache->lock );
				return( -1 );
			}

			/* The area of the tile.
			 */
			tarea.left = x;
			tarea.top = y;
			tarea.width = tw;
			tarea.height = th;

			/* The part of the tile that we need.
			 */
			vips_rect_intersectrect( &tarea, r, &hit );

			copy_region( tile->region, or, &hit );
		}

	g_mutex_unlock( cache->lock );

	return( 0 );
}
コード例 #5
0
ファイル: mmio.c プロジェクト: AdamRLukaitis/jailhouse
/**
 * Register a MMIO region access handler for a cell.
 * @param cell		Cell than can access the region.
 * @param start		Region start address in cell address space.
 * @param size		Region size.
 * @param handler	Access handler.
 * @param handler_arg	Opaque argument to pass to handler.
 *
 * @see mmio_region_unregister
 */
void mmio_region_register(struct cell *cell, unsigned long start,
			  unsigned long size, mmio_handler handler,
			  void *handler_arg)
{
	unsigned int index, n;

	spin_lock(&cell->mmio_region_lock);

	if (cell->num_mmio_regions >= cell->max_mmio_regions) {
		spin_unlock(&cell->mmio_region_lock);

		printk("WARNING: Overflow during MMIO region registration!\n");
		return;
	}

	for (index = 0; index < cell->num_mmio_regions; index++)
		if (cell->mmio_locations[index].start > start)
			break;

	/*
	 * Set and commit a dummy region at the end of the list so that
	 * we can safely grow it.
	 */
	cell->mmio_locations[cell->num_mmio_regions].start = -1;
	cell->mmio_locations[cell->num_mmio_regions].size = 0;
	memory_barrier();

	/*
	 * Extend region list by one so that we can start moving entries.
	 * Commit this change via a barrier so that the current last element
	 * will remain visible when moving it up.
	 */
	cell->num_mmio_regions++;
	memory_barrier();

	for (n = cell->num_mmio_regions - 1; n > index; n--)
		copy_region(cell, n - 1, n);

	/* Invalidate the new region entry first (see also copy_region()). */
	cell->mmio_locations[index].size = 0;
	memory_barrier();

	cell->mmio_locations[index].start = start;
	cell->mmio_handlers[index].handler = handler;
	cell->mmio_handlers[index].arg = handler_arg;
	/* Ensure all fields are committed before activating the region. */
	memory_barrier();

	cell->mmio_locations[index].size = size;

	spin_unlock(&cell->mmio_region_lock);
}
コード例 #6
0
void
floating_sel_restore (GimpLayer *layer,
                      gint       x,
                      gint       y,
                      gint       w,
                      gint       h)
{
  PixelRegion srcPR, destPR;
  gint        offx, offy;
  gint        x1, y1, x2, y2;

  g_return_if_fail (GIMP_IS_LAYER (layer));
  g_return_if_fail (gimp_layer_is_floating_sel (layer));

  /*  What this function does is "uncover" the specified area in the
   *  drawable that this floating selection obscures.  We do this so
   *  that either the floating selection can be removed or it can be
   *  translated
   */

  /*  Find the minimum area we need to uncover -- in image space  */
  gimp_item_offsets (GIMP_ITEM (layer->fs.drawable), &offx, &offy);

  x1 = MAX (GIMP_ITEM (layer)->offset_x, offx);
  y1 = MAX (GIMP_ITEM (layer)->offset_y, offy);
  x2 = MIN (GIMP_ITEM (layer)->offset_x + GIMP_ITEM (layer)->width,
            offx + gimp_item_width  (GIMP_ITEM (layer->fs.drawable)));
  y2 = MIN (GIMP_ITEM(layer)->offset_y + GIMP_ITEM (layer)->height,
            offy + gimp_item_height (GIMP_ITEM (layer->fs.drawable)));

  x1 = CLAMP (x, x1, x2);
  y1 = CLAMP (y, y1, y2);
  x2 = CLAMP (x + w, x1, x2);
  y2 = CLAMP (y + h, y1, y2);

  if ((x2 - x1) > 0 && (y2 - y1) > 0)
    {
      /*  Copy the area from the backing store to the drawable  */
      pixel_region_init (&srcPR, layer->fs.backing_store,
                         (x1 - GIMP_ITEM (layer)->offset_x),
                         (y1 - GIMP_ITEM (layer)->offset_y),
                         (x2 - x1), (y2 - y1), FALSE);
      pixel_region_init (&destPR, gimp_drawable_get_tiles (layer->fs.drawable),
                         (x1 - offx), (y1 - offy), (x2 - x1), (y2 - y1), TRUE);

      copy_region (&srcPR, &destPR);
    }
}
コード例 #7
0
ファイル: im_tile_cache.c プロジェクト: aturcotte/libvips
/* Loop over the output region, filling with data from cache.
 */
static int
tile_cache_fill( REGION *out, void *seq, void *a, void *b )
{
	REGION *in = (REGION *) seq;
	Read *read = (Read *) b;
	const int tw = read->tile_width;
	const int th = read->tile_height;
	Rect *r = &out->valid;

	/* Find top left of tiles we need.
	 */
	int xs = (r->left / tw) * tw;
	int ys = (r->top / th) * th;

	int x, y;

	g_mutex_lock( read->lock );

	for( y = ys; y < IM_RECT_BOTTOM( r ); y += th )
		for( x = xs; x < IM_RECT_RIGHT( r ); x += tw ) {
			Tile *tile;
			Rect tarea;
			Rect hit;

			if( !(tile = tile_find( read, in, x, y )) ) {
				g_mutex_unlock( read->lock );
				return( -1 );
			}

			/* The area of the tile.
			 */
			tarea.left = x;
			tarea.top = y;
			tarea.width = tw;
			tarea.height = th;

			/* The part of the tile that we need.
			 */
			im_rect_intersectrect( &tarea, r, &hit );

			copy_region( tile->region, out, &hit );
		}

	g_mutex_unlock( read->lock );

	return( 0 );
}
コード例 #8
0
ファイル: mmio.c プロジェクト: fbezdeka/jailhouse
/**
 * Register a MMIO region access handler for a cell.
 * @param cell		Cell than can access the region.
 * @param start		Region start address in cell address space.
 * @param size		Region size.
 * @param handler	Access handler.
 * @param handler_arg	Opaque argument to pass to handler.
 *
 * @see mmio_region_unregister
 */
void mmio_region_register(struct cell *cell, unsigned long start,
			  unsigned long size, mmio_handler handler,
			  void *handler_arg)
{
	unsigned int index, n;

	spin_lock(&cell->mmio_region_lock);

	if (cell->num_mmio_regions >= cell->max_mmio_regions) {
		spin_unlock(&cell->mmio_region_lock);

		printk("WARNING: Overflow during MMIO region registration!\n");
		return;
	}

	for (index = 0; index < cell->num_mmio_regions; index++)
		if (cell->mmio_locations[index].start > start)
			break;

	/*
	 * Advance the generation to odd value, indicating that modifications
	 * are ongoing. Commit this change via a barrier so that other CPUs
	 * will see this before we start changing any field.
	 */
	cell->mmio_generation++;
	memory_barrier();

	for (n = cell->num_mmio_regions; n > index; n--)
		copy_region(cell, n - 1, n);

	cell->mmio_locations[index].start = start;
	cell->mmio_locations[index].size = size;
	cell->mmio_handlers[index].function = handler;
	cell->mmio_handlers[index].arg = handler_arg;

	cell->num_mmio_regions++;

	/* Ensure all fields are committed before advancing the generation. */
	memory_barrier();
	cell->mmio_generation++;

	spin_unlock(&cell->mmio_region_lock);
}
コード例 #9
0
ファイル: gimppatternclipboard.c プロジェクト: 1ynx/gimp
static void
gimp_pattern_clipboard_buffer_changed (Gimp        *gimp,
                                       GimpPattern *pattern)
{
  if (pattern->mask)
    {
      temp_buf_free (pattern->mask);
      pattern->mask = NULL;
    }

  if (gimp->global_buffer)
    {
      gint         width;
      gint         height;
      gint         bytes;
      PixelRegion  bufferPR;
      PixelRegion  maskPR;

      width  = MIN (gimp_buffer_get_width  (gimp->global_buffer), 2048);
      height = MIN (gimp_buffer_get_height (gimp->global_buffer), 2048);
      bytes  = gimp_buffer_get_bytes (gimp->global_buffer);

      pattern->mask = temp_buf_new (width, height, bytes, 0, 0, NULL);

      pixel_region_init (&bufferPR,
                         gimp_buffer_get_tiles (gimp->global_buffer),
                         0, 0, width, height, FALSE);
      pixel_region_init_temp_buf (&maskPR, pattern->mask,
                                  0, 0, width, height);

      copy_region (&bufferPR, &maskPR);
    }
  else
    {
      guchar color[3] = { 255, 255, 255 };

      pattern->mask = temp_buf_new (16, 16, 3, 0, 0, color);
    }

  gimp_data_dirty (GIMP_DATA (pattern));
}
コード例 #10
0
ファイル: mmio.c プロジェクト: AdamRLukaitis/jailhouse
/**
 * Unregister MMIO region from a cell.
 * @param cell		Cell the region belongs to.
 * @param start		Region start address as it was passed to
 * 			mmio_region_register().
 *
 * @see mmio_region_register
 */
void mmio_region_unregister(struct cell *cell, unsigned long start)
{
	int index;

	spin_lock(&cell->mmio_region_lock);

	index = find_region(cell, start, 0);
	if (index >= 0) {
		for (/* empty */; index < cell->num_mmio_regions; index++)
			copy_region(cell, index + 1, index);

		/*
		 * Ensure the last region move is visible before shrinking the
		 * list.
		 */
		memory_barrier();

		cell->num_mmio_regions--;
	}
	spin_unlock(&cell->mmio_region_lock);
}
コード例 #11
0
ファイル: makeprior.cpp プロジェクト: blaze3j/DocHunt
void install_prior( const std::string& indexPath, const std::string& priorName, indri::file::File& priorFile ) {
  std::string priorDirectory = indri::file::Path::combine( indexPath, "prior" );
  std::string priorPath = indri::file::Path::combine( priorDirectory, priorName );

  // make sure there's a prior directory in the index
  if( indri::file::Path::exists( priorDirectory ) == false ) {
    indri::file::Path::make( priorDirectory );
  }

  // if there's a old prior there with this name, remove it
  if( indri::file::Path::exists( priorPath ) ) { 
    lemur_compat::remove( priorPath.c_str() );
  }

  // copy the file
  indri::file::File output;
  output.create( priorPath );
  size_t length = priorFile.size();
  
  copy_region( output, priorFile, 0, length );
  output.close(); 
}
コード例 #12
0
ファイル: gimpbuffer.c プロジェクト: Amerekanets/gimp
GimpBuffer *
gimp_buffer_new (TileManager *tiles,
                 const gchar *name,
                 gboolean     copy_pixels)
{
  GimpBuffer *buffer;
  gint        width, height;

  g_return_val_if_fail (tiles != NULL, NULL);
  g_return_val_if_fail (name != NULL, NULL);

  width  = tile_manager_width (tiles);
  height = tile_manager_height (tiles);

  buffer = g_object_new (GIMP_TYPE_BUFFER,
                         "name", name,
                         NULL);

  if (copy_pixels)
    {
      PixelRegion srcPR, destPR;

      buffer->tiles = tile_manager_new (width, height,
                                        tile_manager_bpp (tiles));

      pixel_region_init (&srcPR, tiles, 0, 0, width, height, FALSE);
      pixel_region_init (&destPR, buffer->tiles, 0, 0, width, height, TRUE);
      copy_region (&srcPR, &destPR);
    }
  else
    {
      buffer->tiles = tiles;
    }

  return buffer;
}
コード例 #13
0
ファイル: makeprior.cpp プロジェクト: blaze3j/DocHunt
void sort_file( indri::file::File& out, indri::file::File& in, size_t memory, int totalDocuments ) {
  UINT64 length = in.size();
  size_t rounded = (memory / 12) * 12;
    
  UINT64 total = 0;
  std::vector<std::string> temporaries;

  while( length > total ) {
    UINT64 chunk = lemur_compat::min<UINT64>( rounded, length - total );
    indri::file::File tempIn;
    indri::file::File tempOut;
    std::string nameIn;
    std::string nameOut;
  
    tempIn.openTemporary( nameIn );
    tempOut.openTemporary( nameOut );

    // make a sorted run
    copy_region( tempIn, in, total, chunk );
    sort_run( tempOut, tempIn, memory );
    
    tempIn.close();
    tempOut.close();
    lemur_compat::remove( nameIn.c_str() );
    temporaries.push_back( nameOut );
    
    total += chunk;
  }

  in.close();
  merge_sorted_runs( out, temporaries, totalDocuments );
  
  for( size_t i=0; i<temporaries.size(); i++ ) {
    lemur_compat::remove( temporaries[i].c_str() );
  }
}
コード例 #14
0
ファイル: flashsv.c プロジェクト: DanielGit/Intrisit201202
static int flashsv_decode_frame(AVCodecContext *avctx,
                                    void *data, int *data_size,
                                    uint8_t *buf, int buf_size)
{
    FlashSVContext *s = avctx->priv_data;
    int h_blocks, v_blocks, h_part, v_part, i, j;
    GetBitContext gb;

    /* no supplementary picture */
    if (buf_size == 0)
        return 0;

    if(s->frame.data[0])
            avctx->release_buffer(avctx, &s->frame);

    init_get_bits(&gb, buf, buf_size * 8);

    /* start to parse the bitstream */
    s->block_width = 16* (get_bits(&gb, 4)+1);
    s->image_width =     get_bits(&gb,12);
    s->block_height= 16* (get_bits(&gb, 4)+1);
    s->image_height=     get_bits(&gb,12);

    /* calculate amount of blocks and the size of the border blocks */
    h_blocks = s->image_width / s->block_width;
    h_part = s->image_width % s->block_width;
    v_blocks = s->image_height / s->block_height;
    v_part = s->image_height % s->block_height;

    /* the block size could change between frames, make sure the buffer
     * is large enough, if not, get a larger one */
    if(s->block_size < s->block_width*s->block_height) {
        if (s->tmpblock != NULL)
            av_free(s->tmpblock);
        if ((s->tmpblock = av_malloc(3*s->block_width*s->block_height)) == NULL) {
            av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
            return -1;
        }
    }
    s->block_size = s->block_width*s->block_height;

    /* init the image size once */
    if((avctx->width==0) && (avctx->height==0)){
        avctx->width = s->image_width;
        avctx->height = s->image_height;
    }

    /* check for changes of image width and image height */
    if ((avctx->width != s->image_width) || (avctx->height != s->image_height)) {
        av_log(avctx, AV_LOG_ERROR, "Frame width or height differs from first frames!\n");
        av_log(avctx, AV_LOG_ERROR, "fh = %d, fv %d  vs  ch = %d, cv = %d\n",avctx->height,
        avctx->width,s->image_height,s->image_width);
        return -1;
    }

    av_log(avctx, AV_LOG_DEBUG, "image: %dx%d block: %dx%d num: %dx%d part: %dx%d\n",
        s->image_width, s->image_height, s->block_width, s->block_height,
        h_blocks, v_blocks, h_part, v_part);

    s->frame.reference = 1;
    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID;
    if (avctx->get_buffer(avctx, &s->frame) < 0) {
        av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
        return -1;
    }

    /* loop over all block columns */
    for (j = 0; j < v_blocks + (v_part?1:0); j++)
    {

        int hp = j*s->block_height; // horiz position in frame
        int hs = (j<v_blocks)?s->block_height:v_part; // size of block


        /* loop over all block rows */
        for (i = 0; i < h_blocks + (h_part?1:0); i++)
        {
            int wp = i*s->block_width; // vert position in frame
            int ws = (i<h_blocks)?s->block_width:h_part; // size of block

            /* get the size of the compressed zlib chunk */
            int size = get_bits(&gb, 16);

            if (size == 0) {
                /* no change, don't do anything */
            } else {
                /* decompress block */
                int ret = inflateReset(&(s->zstream));
                if (ret != Z_OK)
                {
                    av_log(avctx, AV_LOG_ERROR, "error in decompression (reset) of block %dx%d\n", i, j);
                    /* return -1; */
                }
                s->zstream.next_in = buf+(get_bits_count(&gb)/8);
                s->zstream.avail_in = size;
                s->zstream.next_out = s->tmpblock;
                s->zstream.avail_out = s->block_size*3;
                ret = inflate(&(s->zstream), Z_FINISH);
                if (ret == Z_DATA_ERROR)
                {
                    av_log(avctx, AV_LOG_ERROR, "Zlib resync occured\n");
                    inflateSync(&(s->zstream));
                    ret = inflate(&(s->zstream), Z_FINISH);
                }

                if ((ret != Z_OK) && (ret != Z_STREAM_END))
                {
                    av_log(avctx, AV_LOG_ERROR, "error in decompression of block %dx%d: %d\n", i, j, ret);
                    /* return -1; */
                }
                copy_region(s->tmpblock, s->frame.data[0], s->image_height-(hp+hs+1), wp, hs, ws, s->frame.linesize[0]);
                skip_bits(&gb, 8*size);   /* skip the consumed bits */
            }
        }
    }

    *data_size = sizeof(AVFrame);
    *(AVFrame*)data = s->frame;

    if ((get_bits_count(&gb)/8) != buf_size)
        av_log(avctx, AV_LOG_ERROR, "buffer not fully consumed (%d != %d)\n",
            buf_size, (get_bits_count(&gb)/8));

    /* report that the buffer was completely consumed */
    return buf_size;
}
コード例 #15
0
static gboolean
gimp_perspective_clone_get_source (GimpSourceCore   *source_core,
                                   GimpDrawable     *drawable,
                                   GimpPaintOptions *paint_options,
                                   GimpPickable     *src_pickable,
                                   gint              src_offset_x,
                                   gint              src_offset_y,
                                   TempBuf          *paint_area,
                                   gint             *paint_area_offset_x,
                                   gint             *paint_area_offset_y,
                                   gint             *paint_area_width,
                                   gint             *paint_area_height,
                                   PixelRegion      *srcPR)
{
  GimpPerspectiveClone *clone      = GIMP_PERSPECTIVE_CLONE (source_core);
  GimpPaintCore        *paint_core = GIMP_PAINT_CORE (source_core);
  GimpSourceOptions    *options    = GIMP_SOURCE_OPTIONS (paint_options);
  GimpImage            *src_image;
  GimpImage            *image;
  GimpImageType         src_type;
  gint                  x1d, y1d, x2d, y2d;
  gdouble               x1s, y1s, x2s, y2s, x3s, y3s, x4s, y4s;
  gint                  xmin, ymin, xmax, ymax;
  TileManager          *src_tiles;
  TileManager          *orig_tiles;
  PixelRegion           origPR;
  PixelRegion           destPR;
  GimpMatrix3           matrix;
  gint                  bytes;

  src_image = gimp_pickable_get_image (src_pickable);
  image     = gimp_item_get_image (GIMP_ITEM (drawable));

  src_type  = gimp_pickable_get_image_type (src_pickable);
  src_tiles = gimp_pickable_get_tiles (src_pickable);

  /* Destination coordinates that will be painted */
  x1d = paint_area->x;
  y1d = paint_area->y;
  x2d = paint_area->x + paint_area->width;
  y2d = paint_area->y + paint_area->height;

  /* Boundary box for source pixels to copy: Convert all the vertex of
   * the box to paint in destination area to its correspondent in
   * source area bearing in mind perspective
   */
  gimp_perspective_clone_get_source_point (clone, x1d, y1d, &x1s, &y1s);
  gimp_perspective_clone_get_source_point (clone, x1d, y2d, &x2s, &y2s);
  gimp_perspective_clone_get_source_point (clone, x2d, y1d, &x3s, &y3s);
  gimp_perspective_clone_get_source_point (clone, x2d, y2d, &x4s, &y4s);

  xmin = floor (MIN4 (x1s, x2s, x3s, x4s));
  ymin = floor (MIN4 (y1s, y2s, y3s, y4s));
  xmax = ceil  (MAX4 (x1s, x2s, x3s, x4s));
  ymax = ceil  (MAX4 (y1s, y2s, y3s, y4s));

  xmin = CLAMP (xmin - 1, 0, tile_manager_width  (src_tiles));
  ymin = CLAMP (ymin - 1, 0, tile_manager_height (src_tiles));
  xmax = CLAMP (xmax + 1, 0, tile_manager_width  (src_tiles));
  ymax = CLAMP (ymax + 1, 0, tile_manager_height (src_tiles));

  /* if the source area is completely out of the image */
  if (!(xmax - xmin) || !(ymax - ymin))
    return FALSE;

  /*  If the source image is different from the destination,
   *  then we should copy straight from the source image
   *  to the canvas.
   *  Otherwise, we need a call to get_orig_image to make sure
   *  we get a copy of the unblemished (offset) image
   */
  if ((  options->sample_merged && (src_image                 != image)) ||
      (! options->sample_merged && (source_core->src_drawable != drawable)))
    {
      pixel_region_init (&origPR, src_tiles,
                         xmin, ymin, xmax - xmin, ymax - ymin, FALSE);
    }
  else
    {
      TempBuf *orig;

      /*  get the original image  */
      if (options->sample_merged)
        orig = gimp_paint_core_get_orig_proj (paint_core,
                                              src_pickable,
                                              xmin, ymin, xmax, ymax);
      else
        orig = gimp_paint_core_get_orig_image (paint_core,
                                               GIMP_DRAWABLE (src_pickable),
                                               xmin, ymin, xmax, ymax);

      pixel_region_init_temp_buf (&origPR, orig,
                                  0, 0, xmax - xmin, ymax - ymin);
    }

  /*  copy the original image to a tile manager, adding alpha if needed  */

  bytes = GIMP_IMAGE_TYPE_BYTES (GIMP_IMAGE_TYPE_WITH_ALPHA (src_type));

  orig_tiles = tile_manager_new (xmax - xmin, ymax - ymin, bytes);

  tile_manager_set_offsets (orig_tiles, xmin, ymin);

  pixel_region_init (&destPR, orig_tiles,
                     0, 0, xmax - xmin, ymax - ymin,
                     TRUE);

  if (bytes > origPR.bytes)
    add_alpha_region (&origPR, &destPR);
  else
    copy_region (&origPR, &destPR);

  clone->src_area = temp_buf_resize (clone->src_area,
                                     tile_manager_bpp (orig_tiles),
                                     0, 0,
                                     x2d - x1d, y2d - y1d);

  pixel_region_init_temp_buf (&destPR, clone->src_area,
                              0, 0,
                              x2d - x1d, y2d - y1d);

  gimp_perspective_clone_get_matrix (clone, &matrix);

  gimp_transform_region (src_pickable,
                         GIMP_CONTEXT (paint_options),
                         orig_tiles,
                         &destPR,
                         x1d, y1d, x2d, y2d,
                         &matrix,
                         GIMP_INTERPOLATION_LINEAR, 0, NULL);

  tile_manager_unref (orig_tiles);

  pixel_region_init_temp_buf (srcPR, clone->src_area,
                              0, 0, x2d - x1d, y2d - y1d);

  return TRUE;
}
コード例 #16
0
ファイル: gimpsmudge.c プロジェクト: Amerekanets/gimp
static gboolean
gimp_smudge_start (GimpPaintCore    *paint_core,
                   GimpDrawable     *drawable,
                   GimpPaintOptions *paint_options)
{
  GimpSmudge  *smudge = GIMP_SMUDGE (paint_core);
  GimpImage   *image;
  TempBuf     *area;
  PixelRegion  srcPR;
  gint         bytes;
  gint         x, y, w, h;

  image = gimp_item_get_image (GIMP_ITEM (drawable));

  if (gimp_drawable_is_indexed (drawable))
    return FALSE;

  area = gimp_paint_core_get_paint_area (paint_core, drawable, paint_options);
  if (! area)
    return FALSE;

  /*  adjust the x and y coordinates to the upper left corner of the brush  */
  gimp_smudge_brush_coords (paint_core, &x, &y, &w, &h);

  /*  Allocate the accumulation buffer */
  bytes = gimp_drawable_bytes (drawable);
  smudge->accum_data = g_malloc (w * h * bytes);

  /*  If clipped, prefill the smudge buffer with the color at the
   *  brush position.
   */
  if (x != area->x || y != area->y || w != area->width || h != area->height)
    {
      guchar fill[4];

      gimp_pickable_get_pixel_at (GIMP_PICKABLE (drawable),
                                  CLAMP ((gint) paint_core->cur_coords.x,
                                         0,
                                         gimp_item_width (GIMP_ITEM (drawable)) - 1),
                                  CLAMP ((gint) paint_core->cur_coords.y,
                                         0,
                                         gimp_item_height (GIMP_ITEM (drawable)) - 1),
                                  fill);

      pixel_region_init_data (&srcPR, smudge->accum_data,
                              bytes, bytes * w,
                              0, 0, w, h);

      color_region (&srcPR, fill);
    }

  pixel_region_init (&srcPR, gimp_drawable_get_tiles (drawable),
                     area->x, area->y, area->width, area->height, FALSE);

  pixel_region_init_data (&smudge->accumPR, smudge->accum_data,
                          bytes, bytes * w,
                          area->x - x,
                          area->y - y,
                          area->width,
                          area->height);

  /* copy the region under the original painthit. */
  copy_region (&srcPR, &smudge->accumPR);

  pixel_region_init_data (&smudge->accumPR, smudge->accum_data,
                          bytes, bytes * w,
                          area->x - x,
                          area->y - y,
                          area->width,
                          area->height);

  return TRUE;
}
コード例 #17
0
void
floating_sel_store (GimpLayer *layer,
                    gint       x,
                    gint       y,
                    gint       w,
                    gint       h)
{
  PixelRegion srcPR, destPR;
  gint        offx, offy;
  gint        x1, y1, x2, y2;

  g_return_if_fail (GIMP_IS_LAYER (layer));
  g_return_if_fail (gimp_layer_is_floating_sel (layer));

  /*  Check the backing store & make sure it has the correct dimensions  */
  if ((tile_manager_width  (layer->fs.backing_store) !=
       gimp_item_width (GIMP_ITEM(layer)))  ||
      (tile_manager_height (layer->fs.backing_store) !=
       gimp_item_height (GIMP_ITEM(layer))) ||
      (tile_manager_bpp    (layer->fs.backing_store) !=
       gimp_drawable_bytes (layer->fs.drawable)))
    {
      /*  free the backing store and allocate anew  */
      tile_manager_unref (layer->fs.backing_store);

      layer->fs.backing_store =
        tile_manager_new (GIMP_ITEM (layer)->width,
                          GIMP_ITEM (layer)->height,
                          gimp_drawable_bytes (layer->fs.drawable));
    }

  /*  What this function does is save the specified area of the
   *  drawable that this floating selection obscures.  We do this so
   *  that it will be possible to subsequently restore the drawable's area
   */
  gimp_item_offsets (GIMP_ITEM (layer->fs.drawable), &offx, &offy);

  /*  Find the minimum area we need to uncover -- in image space  */
  x1 = MAX (GIMP_ITEM (layer)->offset_x, offx);
  y1 = MAX (GIMP_ITEM (layer)->offset_y, offy);
  x2 = MIN (GIMP_ITEM (layer)->offset_x + GIMP_ITEM (layer)->width,
            offx + gimp_item_width (GIMP_ITEM (layer->fs.drawable)));
  y2 = MIN (GIMP_ITEM (layer)->offset_y + GIMP_ITEM (layer)->height,
            offy + gimp_item_height (GIMP_ITEM (layer->fs.drawable)));

  x1 = CLAMP (x, x1, x2);
  y1 = CLAMP (y, y1, y2);
  x2 = CLAMP (x + w, x1, x2);
  y2 = CLAMP (y + h, y1, y2);

  if ((x2 - x1) > 0 && (y2 - y1) > 0)
    {
      /*  Copy the area from the drawable to the backing store  */
      pixel_region_init (&srcPR, gimp_drawable_get_tiles (layer->fs.drawable),
                         (x1 - offx), (y1 - offy), (x2 - x1), (y2 - y1), FALSE);
      pixel_region_init (&destPR, layer->fs.backing_store,
                         (x1 - GIMP_ITEM (layer)->offset_x),
                         (y1 - GIMP_ITEM (layer)->offset_y),
                         (x2 - x1), (y2 - y1), TRUE);

      copy_region (&srcPR, &destPR);
    }
}
コード例 #18
0
ファイル: gimpdrawable-combine.c プロジェクト: 1ynx/gimp
/*  Similar to gimp_drawable_apply_region but works in "replace" mode (i.e.
 *  transparent pixels in src2 make the result transparent rather than
 *  opaque.
 *
 * Takes an additional mask pixel region as well.
 */
void
gimp_drawable_real_replace_region (GimpDrawable *drawable,
                                   PixelRegion  *src2PR,
                                   gboolean      push_undo,
                                   const gchar  *undo_desc,
                                   gdouble       opacity,
                                   PixelRegion  *maskPR,
                                   gint          x,
                                   gint          y)
{
  GimpItem        *item  = GIMP_ITEM (drawable);
  GimpImage       *image = gimp_item_get_image (item);
  GimpChannel     *mask  = gimp_image_get_mask (image);
  gint             x1, y1, x2, y2;
  gint             offset_x, offset_y;
  PixelRegion      src1PR, destPR;
  CombinationMode  operation;
  gboolean         active_components[MAX_CHANNELS];

  /*  don't apply the mask to itself and don't apply an empty mask  */
  if (GIMP_DRAWABLE (mask) == drawable || gimp_channel_is_empty (mask))
    mask = NULL;

  /*  configure the active channel array  */
  gimp_drawable_get_active_components (drawable, active_components);

  /*  determine what sort of operation is being attempted and
   *  if it's actually legal...
   */
  operation = gimp_image_get_combination_mode (gimp_drawable_type (drawable),
                                               src2PR->bytes);
  if (operation == -1)
    {
      g_warning ("%s: illegal parameters.", G_STRFUNC);
      return;
    }

  /*  get the layer offsets  */
  gimp_item_get_offset (item, &offset_x, &offset_y);

  /*  make sure the image application coordinates are within drawable bounds  */
  x1 = CLAMP (x, 0,             gimp_item_get_width  (item));
  y1 = CLAMP (y, 0,             gimp_item_get_height (item));
  x2 = CLAMP (x + src2PR->w, 0, gimp_item_get_width  (item));
  y2 = CLAMP (y + src2PR->h, 0, gimp_item_get_height (item));

  if (mask)
    {
      GimpItem *mask_item = GIMP_ITEM (mask);

      /*  make sure coordinates are in mask bounds ...
       *  we need to add the layer offset to transform coords
       *  into the mask coordinate system
       */
      x1 = CLAMP (x1, -offset_x, gimp_item_get_width  (mask_item) - offset_x);
      y1 = CLAMP (y1, -offset_y, gimp_item_get_height (mask_item) - offset_y);
      x2 = CLAMP (x2, -offset_x, gimp_item_get_width  (mask_item) - offset_x);
      y2 = CLAMP (y2, -offset_y, gimp_item_get_height (mask_item) - offset_y);
    }

  /*  If the calling procedure specified an undo step...  */
  if (push_undo)
    gimp_drawable_push_undo (drawable, undo_desc,
                             x1, y1,
                             x2 - x1, y2 - y1,
                             NULL, FALSE);

  /* configure the pixel regions */
  pixel_region_init (&src1PR, gimp_drawable_get_tiles (drawable),
                     x1, y1, x2 - x1, y2 - y1,
                     FALSE);
  pixel_region_init (&destPR, gimp_drawable_get_tiles (drawable),
                     x1, y1, x2 - x1, y2 - y1,
                     TRUE);
  pixel_region_resize (src2PR,
                       src2PR->x + (x1 - x), src2PR->y + (y1 - y),
                       x2 - x1, y2 - y1);

  if (mask)
    {
      PixelRegion  mask2PR, tempPR;
      guchar      *temp_data;

      pixel_region_init (&mask2PR,
                         gimp_drawable_get_tiles (GIMP_DRAWABLE (mask)),
                         x1 + offset_x,
                         y1 + offset_y,
                         x2 - x1, y2 - y1,
                         FALSE);

      temp_data = g_malloc ((y2 - y1) * (x2 - x1));

      pixel_region_init_data (&tempPR, temp_data, 1, x2 - x1,
                              0, 0, x2 - x1, y2 - y1);

      copy_region (&mask2PR, &tempPR);

      pixel_region_init_data (&tempPR, temp_data, 1, x2 - x1,
                              0, 0, x2 - x1, y2 - y1);

      apply_mask_to_region (&tempPR, maskPR, OPAQUE_OPACITY);

      pixel_region_init_data (&tempPR, temp_data, 1, x2 - x1,
                              0, 0, x2 - x1, y2 - y1);

      combine_regions_replace (&src1PR, src2PR, &destPR, &tempPR, NULL,
                               opacity * 255.999,
                               active_components,
                               operation);

      g_free (temp_data);
    }
  else
    {
      combine_regions_replace (&src1PR, src2PR, &destPR, maskPR, NULL,
                               opacity * 255.999,
                               active_components,
                               operation);
    }
}
コード例 #19
0
ファイル: gimpdrawable-combine.c プロジェクト: 1ynx/gimp
void
gimp_drawable_real_apply_region (GimpDrawable         *drawable,
                                 PixelRegion          *src2PR,
                                 gboolean              push_undo,
                                 const gchar          *undo_desc,
                                 gdouble               opacity,
                                 GimpLayerModeEffects  mode,
                                 TileManager          *src1_tiles,
                                 PixelRegion          *destPR,
                                 gint                  x,
                                 gint                  y)
{
  GimpItem        *item  = GIMP_ITEM (drawable);
  GimpImage       *image = gimp_item_get_image (item);
  GimpChannel     *mask  = gimp_image_get_mask (image);
  gint             x1, y1, x2, y2;
  gint             offset_x, offset_y;
  PixelRegion      src1PR, my_destPR;
  CombinationMode  operation;
  gboolean         active_components[MAX_CHANNELS];

  /*  don't apply the mask to itself and don't apply an empty mask  */
  if (GIMP_DRAWABLE (mask) == drawable || gimp_channel_is_empty (mask))
    mask = NULL;

  /*  configure the active channel array  */
  gimp_drawable_get_active_components (drawable, active_components);

  /*  determine what sort of operation is being attempted and
   *  if it's actually legal...
   */
  operation = gimp_image_get_combination_mode (gimp_drawable_type (drawable),
                                               src2PR->bytes);
  if (operation == -1)
    {
      g_warning ("%s: illegal parameters.", G_STRFUNC);
      return;
    }

  /*  get the layer offsets  */
  gimp_item_get_offset (item, &offset_x, &offset_y);

  /*  make sure the image application coordinates are within drawable bounds  */
  x1 = CLAMP (x,             0, gimp_item_get_width  (item));
  y1 = CLAMP (y,             0, gimp_item_get_height (item));
  x2 = CLAMP (x + src2PR->w, 0, gimp_item_get_width  (item));
  y2 = CLAMP (y + src2PR->h, 0, gimp_item_get_height (item));

  if (mask)
    {
      GimpItem *mask_item = GIMP_ITEM (mask);

      /*  make sure coordinates are in mask bounds ...
       *  we need to add the layer offset to transform coords
       *  into the mask coordinate system
       */
      x1 = CLAMP (x1, -offset_x, gimp_item_get_width  (mask_item) - offset_x);
      y1 = CLAMP (y1, -offset_y, gimp_item_get_height (mask_item) - offset_y);
      x2 = CLAMP (x2, -offset_x, gimp_item_get_width  (mask_item) - offset_x);
      y2 = CLAMP (y2, -offset_y, gimp_item_get_height (mask_item) - offset_y);
    }

  /*  If the calling procedure specified an undo step...  */
  if (push_undo)
    {
      GimpDrawableUndo *undo;

      gimp_drawable_push_undo (drawable, undo_desc,
                               x1, y1,
                               x2 - x1, y2 - y1,
                               NULL, FALSE);

      undo = GIMP_DRAWABLE_UNDO (gimp_image_undo_get_fadeable (image));

      if (undo)
        {
          PixelRegion tmp_srcPR;
          PixelRegion tmp_destPR;

          undo->paint_mode = mode;
          undo->opacity    = opacity;
          undo->src2_tiles = tile_manager_new (x2 - x1, y2 - y1,
                                               src2PR->bytes);

          tmp_srcPR = *src2PR;
          pixel_region_resize (&tmp_srcPR,
                               src2PR->x + (x1 - x), src2PR->y + (y1 - y),
                               x2 - x1, y2 - y1);
          pixel_region_init (&tmp_destPR, undo->src2_tiles,
                             0, 0,
                             x2 - x1, y2 - y1, TRUE);

          copy_region (&tmp_srcPR, &tmp_destPR);
        }
    }

  /* configure the pixel regions */

  /* check if an alternative to using the drawable's data as src1 was
   * provided...
   */
  if (src1_tiles)
    {
      pixel_region_init (&src1PR, src1_tiles,
                         x1, y1, x2 - x1, y2 - y1,
                         FALSE);
    }
  else
    {
      pixel_region_init (&src1PR, gimp_drawable_get_tiles (drawable),
                         x1, y1, x2 - x1, y2 - y1,
                         FALSE);
    }

  /* check if an alternative to using the drawable's data as dest was
   * provided...
   */
  if (!destPR)
    {
      pixel_region_init (&my_destPR, gimp_drawable_get_tiles (drawable),
                         x1, y1, x2 - x1, y2 - y1,
                         TRUE);
      destPR = &my_destPR;
    }

  pixel_region_resize (src2PR,
                       src2PR->x + (x1 - x), src2PR->y + (y1 - y),
                       x2 - x1, y2 - y1);

  if (mask)
    {
      PixelRegion maskPR;

      pixel_region_init (&maskPR,
                         gimp_drawable_get_tiles (GIMP_DRAWABLE (mask)),
                         x1 + offset_x,
                         y1 + offset_y,
                         x2 - x1, y2 - y1,
                         FALSE);

      combine_regions (&src1PR, src2PR, destPR, &maskPR, NULL,
                       opacity * 255.999,
                       mode,
                       active_components,
                       operation);
    }
  else
    {
      combine_regions (&src1PR, src2PR, destPR, NULL, NULL,
                       opacity * 255.999,
                       mode,
                       active_components,
                       operation);
    }
}
コード例 #20
0
ファイル: gimpconvolve.c プロジェクト: jdburton/gimp-osx
static void
gimp_convolve_motion (GimpPaintCore    *paint_core,
                      GimpDrawable     *drawable,
                      GimpPaintOptions *paint_options)
{
  GimpConvolve        *convolve   = GIMP_CONVOLVE (paint_core);
  GimpBrushCore       *brush_core = GIMP_BRUSH_CORE (paint_core);
  GimpConvolveOptions *options    = GIMP_CONVOLVE_OPTIONS (paint_options);
  GimpContext         *context    = GIMP_CONTEXT (paint_options);
  GimpImage           *image;
  TempBuf             *area;
  PixelRegion          srcPR;
  PixelRegion          destPR;
  PixelRegion          tempPR;
  guchar              *buffer;
  gdouble              opacity;
  gdouble              rate;
  gint                 bytes;

  image = gimp_item_get_image (GIMP_ITEM (drawable));

  if (gimp_drawable_is_indexed (drawable))
    return;

  opacity = gimp_paint_options_get_fade (paint_options, image,
                                         paint_core->pixel_dist);
  if (opacity == 0.0)
    return;

  area = gimp_paint_core_get_paint_area (paint_core, drawable, paint_options);
  if (! area)
    return;

  rate = options->rate;

  rate *= gimp_paint_options_get_dynamic_rate (paint_options,
                                               &paint_core->cur_coords);

  gimp_convolve_calculate_matrix (convolve, options->type,
                                  brush_core->brush->mask->width / 2,
                                  brush_core->brush->mask->height / 2,
                                  rate);

  /*  configure the source pixel region  */
  pixel_region_init (&srcPR, gimp_drawable_get_tiles (drawable),
                     area->x, area->y, area->width, area->height, FALSE);

  if (gimp_drawable_has_alpha (drawable))
    {
      bytes = srcPR.bytes;

      buffer = g_malloc (area->height * bytes * area->width);

      pixel_region_init_data (&tempPR, buffer,
                              bytes, bytes * area->width,
                              0, 0, area->width, area->height);

      copy_region (&srcPR, &tempPR);
    }
  else
    {
      /* note: this particular approach needlessly convolves the totally-
         opaque alpha channel. A faster approach would be to keep
         tempPR the same number of bytes as srcPR, and extend the
         paint_core_replace_canvas API to handle non-alpha images. */

      bytes = srcPR.bytes + 1;

      buffer = g_malloc (area->height * bytes * area->width);

      pixel_region_init_data (&tempPR, buffer,
                              bytes, bytes * area->width,
                              0, 0, area->width, area->height);

      add_alpha_region (&srcPR, &tempPR);
    }

  /*  Convolve the region  */
  pixel_region_init_data (&tempPR, buffer,
                          bytes, bytes * area->width,
                          0, 0, area->width, area->height);

  pixel_region_init_temp_buf (&destPR, area,
                              0, 0, area->width, area->height);

  convolve_region (&tempPR, &destPR,
                   convolve->matrix, 3, convolve->matrix_divisor,
                   GIMP_NORMAL_CONVOL, TRUE);

  g_free (buffer);

  gimp_brush_core_replace_canvas (brush_core, drawable,
                                  MIN (opacity, GIMP_OPACITY_OPAQUE),
                                  gimp_context_get_opacity (context),
                                  gimp_paint_options_get_brush_mode (paint_options),
                                  1.0,
                                  GIMP_PAINT_INCREMENTAL);
}
コード例 #21
0
void
gimp_projection_construct (GimpProjection *proj,
                           gint            x,
                           gint            y,
                           gint            w,
                           gint            h)
{
    g_return_if_fail (GIMP_IS_PROJECTION (proj));

#if 0
    GList *layers = gimp_projectable_get_layers (proj->projectable);

    if (layers && ! layers->next) /* a single layer */
    {
        GimpLayer    *layer    = layers->data;
        GimpDrawable *drawable = GIMP_DRAWABLE (layer);
        GimpItem     *item     = GIMP_ITEM (layer);
        gint          width, height;
        gint          off_x, off_y;

        gimp_projectable_get_offset (proj->projectable, &proj_off_x, &proj_off_y);
        gimp_projectable_get_size (proj->projectable, &width, &height);

        gimp_item_get_offset (item, &off_x, &off_y);

        if (gimp_drawable_has_alpha (drawable)                    &&
                gimp_item_get_visible (item)                          &&
                gimp_item_get_width  (item) == width                  &&
                gimp_item_get_height (item) == height                 &&
                ! gimp_drawable_is_indexed (layer)                    &&
                gimp_layer_get_opacity (layer) == GIMP_OPACITY_OPAQUE &&
                off_x == 0                                            &&
                off_y == 0                                            &&
                proj_offset_x == 0                                    &&
                proj_offset_y == 0)
        {
            PixelRegion srcPR, destPR;

            g_printerr ("cow-projection!");

            pixel_region_init (&srcPR,
                               gimp_drawable_get_tiles (layer),
                               x, y, w,h, FALSE);
            pixel_region_init (&destPR,
                               gimp_pickable_get_tiles (GIMP_PICKABLE (proj)),
                               x, y, w,h, TRUE);

            copy_region (&srcPR, &destPR);

            proj->construct_flag = TRUE;

            gimp_projection_construct_legacy (proj, FALSE, x, y, w, h);

            return;
        }
    }
#endif

    /*  First, determine if the projection image needs to be
     *  initialized--this is the case when there are no visible
     *  layers that cover the entire canvas--either because layers
     *  are offset or only a floating selection is visible
     */
    gimp_projection_initialize (proj, x, y, w, h);

    /*  call functions which process the list of layers and
     *  the list of channels
     */
    if (proj->use_gegl)
    {
        gimp_projection_construct_gegl (proj, x, y, w, h);
    }
    else
    {
        proj->construct_flag = FALSE;

        gimp_projection_construct_legacy (proj, TRUE, x, y, w, h);
    }
}
コード例 #22
0
ファイル: uc.c プロジェクト: charlieyqin/unicorn
// TODO: investigate whether qemu region manipulation functions already offered
// this capability
static bool split_region(struct uc_struct *uc, MemoryRegion *mr, uint64_t address,
        size_t size, bool do_delete)
{
    uint8_t *backup;
    uint32_t perms;
    uint64_t begin, end, chunk_end;
    size_t l_size, m_size, r_size;

    chunk_end = address + size;

    // if this region belongs to area [address, address+size],
    // then there is no work to do.
    if (address <= mr->addr && chunk_end >= mr->end)
        return true;

    if (size == 0)
        // trivial case
        return true;

    if (address >= mr->end || chunk_end <= mr->addr)
        // impossible case
        return false;

    backup = copy_region(uc, mr);
    if (backup == NULL)
        return false;

    // save the essential information required for the split before mr gets deleted
    perms = mr->perms;
    begin = mr->addr;
    end = mr->end;

    // unmap this region first, then do split it later
    if (uc_mem_unmap(uc, mr->addr, int128_get64(mr->size)) != UC_ERR_OK)
        goto error;

    /* overlapping cases
     *               |------mr------|
     * case 1    |---size--|
     * case 2           |--size--|
     * case 3                  |---size--|
     */

    // adjust some things
    if (address < begin)
        address = begin;
    if (chunk_end > end)
        chunk_end = end;

    // compute sub region sizes
    l_size = (size_t)(address - begin);
    r_size = (size_t)(end - chunk_end);
    m_size = (size_t)(chunk_end - address);

    // If there are error in any of the below operations, things are too far gone
    // at that point to recover. Could try to remap orignal region, but these smaller
    // allocation just failed so no guarantee that we can recover the original
    // allocation at this point
    if (l_size > 0) {
        if (uc_mem_map(uc, begin, l_size, perms) != UC_ERR_OK)
            goto error;
        if (uc_mem_write(uc, begin, backup, l_size) != UC_ERR_OK)
            goto error;
    }

    if (m_size > 0 && !do_delete) {
        if (uc_mem_map(uc, address, m_size, perms) != UC_ERR_OK)
            goto error;
        if (uc_mem_write(uc, address, backup + l_size, m_size) != UC_ERR_OK)
            goto error;
    }

    if (r_size > 0) {
        if (uc_mem_map(uc, chunk_end, r_size, perms) != UC_ERR_OK)
            goto error;
        if (uc_mem_write(uc, chunk_end, backup + l_size + m_size, r_size) != UC_ERR_OK)
            goto error;
    }

    return true;

error:
    free(backup);
    return false;
}
コード例 #23
0
GimpImage *
gimp_image_duplicate (GimpImage *image)
{
  GimpImage    *new_image;
  GimpLayer    *floating_layer;
  GList        *list;
  GimpLayer    *active_layer              = NULL;
  GimpChannel  *active_channel            = NULL;
  GimpVectors  *active_vectors            = NULL;
  GimpDrawable *new_floating_sel_drawable = NULL;
  GimpDrawable *floating_sel_drawable     = NULL;
  gchar        *filename;
  gint          count;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);

  gimp_set_busy_until_idle (image->gimp);

  /*  Create a new image  */
  new_image = gimp_create_image (image->gimp,
                                 image->width, image->height,
                                 image->base_type,
                                 FALSE);
  gimp_image_undo_disable (new_image);

  /*  Store the folder to be used by the save dialog  */
  filename = gimp_image_get_filename (image);
  if (filename)
    {
      g_object_set_data_full (G_OBJECT (new_image), "gimp-image-dirname",
                              g_path_get_dirname (filename),
                              (GDestroyNotify) g_free);
      g_free (filename);
    }

  /*  Copy the colormap if necessary  */
  if (new_image->base_type == GIMP_INDEXED)
    gimp_image_set_colormap (new_image,
                             gimp_image_get_colormap (image),
                             gimp_image_get_colormap_size (image),
                             FALSE);

  /*  Copy resolution information  */
  new_image->xresolution     = image->xresolution;
  new_image->yresolution     = image->yresolution;
  new_image->resolution_unit = image->resolution_unit;

  /*  Copy floating layer  */
  floating_layer = gimp_image_floating_sel (image);
  if (floating_layer)
    {
      floating_sel_relax (floating_layer, FALSE);

      floating_sel_drawable = floating_layer->fs.drawable;
      floating_layer = NULL;
    }

  /*  Copy the layers  */
  for (list = GIMP_LIST (image->layers)->list, count = 0;
       list;
       list = g_list_next (list))
    {
      GimpLayer *layer = list->data;
      GimpLayer *new_layer;

      new_layer = GIMP_LAYER (gimp_item_convert (GIMP_ITEM (layer),
                                                 new_image,
                                                 G_TYPE_FROM_INSTANCE (layer),
                                                 FALSE));

      /*  Make sure the copied layer doesn't say: "<old layer> copy"  */
      gimp_object_set_name (GIMP_OBJECT (new_layer),
                            gimp_object_get_name (GIMP_OBJECT (layer)));

      /*  Make sure that if the layer has a layer mask,
       *  its name isn't screwed up
       */
      if (new_layer->mask)
        gimp_object_set_name (GIMP_OBJECT (new_layer->mask),
                              gimp_object_get_name (GIMP_OBJECT (layer->mask)));

      if (gimp_image_get_active_layer (image) == layer)
        active_layer = new_layer;

      if (image->floating_sel == layer)
        floating_layer = new_layer;

      if (floating_sel_drawable == GIMP_DRAWABLE (layer))
        new_floating_sel_drawable = GIMP_DRAWABLE (new_layer);

      if (floating_layer != new_layer)
        gimp_image_add_layer (new_image, new_layer, count++);
    }

  /*  Copy the channels  */
  for (list = GIMP_LIST (image->channels)->list, count = 0;
       list;
       list = g_list_next (list))
    {
      GimpChannel *channel = list->data;
      GimpChannel *new_channel;

      new_channel =
        GIMP_CHANNEL (gimp_item_convert (GIMP_ITEM (channel),
                                         new_image,
                                         G_TYPE_FROM_INSTANCE (channel),
                                         FALSE));

      /*  Make sure the copied channel doesn't say: "<old channel> copy"  */
      gimp_object_set_name (GIMP_OBJECT (new_channel),
                            gimp_object_get_name (GIMP_OBJECT (channel)));

      if (gimp_image_get_active_channel (image) == channel)
        active_channel = (new_channel);

      if (floating_sel_drawable == GIMP_DRAWABLE (channel))
        new_floating_sel_drawable = GIMP_DRAWABLE (new_channel);

      gimp_image_add_channel (new_image, new_channel, count++);
    }

  /*  Copy any vectors  */
  for (list = GIMP_LIST (image->vectors)->list, count = 0;
       list;
       list = g_list_next (list))
    {
      GimpVectors *vectors = list->data;
      GimpVectors *new_vectors;

      new_vectors =
        GIMP_VECTORS (gimp_item_convert (GIMP_ITEM (vectors),
                                         new_image,
                                         G_TYPE_FROM_INSTANCE (vectors),
                                         FALSE));

      /*  Make sure the copied vectors doesn't say: "<old vectors> copy"  */
      gimp_object_set_name (GIMP_OBJECT (new_vectors),
                            gimp_object_get_name (GIMP_OBJECT (vectors)));

      if (gimp_image_get_active_vectors (image) == vectors)
        active_vectors = new_vectors;

      gimp_image_add_vectors (new_image, new_vectors, count++);
    }

  /*  Copy the selection mask  */
  {
    TileManager *src_tiles;
    TileManager *dest_tiles;
    PixelRegion  srcPR, destPR;

    src_tiles  =
      gimp_drawable_get_tiles (GIMP_DRAWABLE (image->selection_mask));
    dest_tiles =
      gimp_drawable_get_tiles (GIMP_DRAWABLE (new_image->selection_mask));

    pixel_region_init (&srcPR, src_tiles,
                       0, 0, image->width, image->height, FALSE);
    pixel_region_init (&destPR, dest_tiles,
                       0, 0, image->width, image->height, TRUE);

    copy_region (&srcPR, &destPR);

    new_image->selection_mask->bounds_known   = FALSE;
    new_image->selection_mask->boundary_known = FALSE;
  }

  if (floating_layer)
    floating_sel_attach (floating_layer, new_floating_sel_drawable);

  /*  Set active layer, active channel, active vectors  */
  if (active_layer)
    gimp_image_set_active_layer (new_image, active_layer);

  if (active_channel)
    gimp_image_set_active_channel (new_image, active_channel);

  if (active_vectors)
    gimp_image_set_active_vectors (new_image, active_vectors);

  /*  Copy state of all color channels  */
  for (count = 0; count < MAX_CHANNELS; count++)
    {
      new_image->visible[count] = image->visible[count];
      new_image->active[count]  = image->active[count];
    }

  /*  Copy any guides  */
  for (list = image->guides; list; list = g_list_next (list))
    {
      GimpGuide *guide    = list->data;
      gint       position = gimp_guide_get_position (guide);

      switch (gimp_guide_get_orientation (guide))
        {
        case GIMP_ORIENTATION_HORIZONTAL:
          gimp_image_add_hguide (new_image, position, FALSE);
          break;

        case GIMP_ORIENTATION_VERTICAL:
          gimp_image_add_vguide (new_image, position, FALSE);
          break;

        default:
          g_error ("Unknown guide orientation.\n");
        }
    }

  /*  Copy any sample points  */
  for (list = image->sample_points; list; list = g_list_next (list))
    {
      GimpSamplePoint *sample_point = list->data;

      gimp_image_add_sample_point_at_pos (new_image,
                                          sample_point->x,
                                          sample_point->y,
                                          FALSE);
    }

  /*  Copy the grid  */
  if (image->grid)
    gimp_image_set_grid (new_image, image->grid, FALSE);

  /*  Copy the quick mask info  */
  new_image->quick_mask_state    = image->quick_mask_state;
  new_image->quick_mask_inverted = image->quick_mask_inverted;
  new_image->quick_mask_color    = image->quick_mask_color;

  /*  Copy parasites  */
  if (image->parasites)
    {
      g_object_unref (new_image->parasites);
      new_image->parasites = gimp_parasite_list_copy (image->parasites);
    }

  gimp_image_undo_enable (new_image);

  return new_image;
}
コード例 #24
0
ファイル: VKImage.cpp プロジェクト: sponeil/VKSandbox
void Image::loadTexture(const char *path) {
	PixelBuffer<uint8_t> pb;
	if(!pb.load(path))
		throw "Failed to load texture";

	VkFormatProperties &props = formatProperties[VK_FORMAT_R8G8B8A8_UNORM];
	bool direct = (props.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0;

	VkImageSubresource subres = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0 };
	VkSubresourceLayout sublayout;
	createTexture(VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TILING_LINEAR, direct ? VK_IMAGE_USAGE_SAMPLED_BIT : VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, pb.getWidth(), pb.getHeight());
	vkGetImageSubresourceLayout(vk, image, &subres, &sublayout);
	uint8_t *data = NULL;
	OBJ_CHECK(vkMapMemory(vk, mem, 0, allocInfo.allocationSize, 0, (void **)&data));

	uint32_t x = 0, y = 0;
	uint8_t temp[4] = {0, 0, 0, 255};
	for (y = 0; y < pb.getHeight(); y++) {
		uint32_t *dest = (uint32_t *)data;
		uint8_t *src = pb(0, y);
		switch (pb.getChannels()) {
			case 4:
				memcpy(dest, src, pb.getWidth() * 4);
				break;
			case 3:
				for (x = 0; x < pb.getWidth(); x++) {
					temp[0] = *src++; // R
					temp[1] = *src++; // G
					temp[2] = *src++; // B
					*dest++ = *(uint32_t *)temp;
				}
				break;
			case 2:
				for (x = 0; x < pb.getWidth(); x++) {
					temp[0] = *src++; // R
					temp[1] = *src++; // G
					*dest++ = *(uint32_t *)temp;
				}
				break;
			case 1:
				for (x = 0; x < pb.getWidth(); x++) {
					temp[0] = *src++; // R
					*dest++ = *(uint32_t *)temp;
				}
				break;
		}
		data += sublayout.rowPitch;
	}
	vkUnmapMemory(vk, mem);

	if (direct) {
		setLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_PREINITIALIZED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
	} else {
		// Create a staging image visible to the host to load the texture into with linear tiling
		Image staging;
		Math::Swap(staging.image, image);
		Math::Swap(mem, staging.mem);
		Math::Swap(layout, staging.layout);
		Math::Swap(imageInfo, staging.imageInfo);
		Math::Swap(allocInfo, staging.allocInfo);
		staging.setLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_PREINITIALIZED, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);

		// Now create the actual device-local image and copy into it from the staging image
		createTexture(VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TILING_OPTIMAL, (VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, pb.getWidth(), pb.getHeight());
		setLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_PREINITIALIZED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
		ImageCopy copy_region(pb.getWidth(), pb.getHeight());
		vkCmdCopyImage(vk, staging.image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &copy_region);
		setLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);

		vk.flush(); // Wait for the copy command to complete before the staging texture goes out of scope!
	}

	ImageViewCreateInfo viewInfo(image, imageInfo.format, VK_IMAGE_ASPECT_COLOR_BIT);
	OBJ_CHECK(vkCreateImageView(vk, &viewInfo, NULL, &view));
}
コード例 #25
0
ファイル: gimpsmudge.c プロジェクト: Amerekanets/gimp
static void
gimp_smudge_motion (GimpPaintCore    *paint_core,
                    GimpDrawable     *drawable,
                    GimpPaintOptions *paint_options)
{
  GimpSmudge          *smudge           = GIMP_SMUDGE (paint_core);
  GimpSmudgeOptions   *options          = GIMP_SMUDGE_OPTIONS (paint_options);
  GimpContext         *context          = GIMP_CONTEXT (paint_options);
  GimpPressureOptions *pressure_options = paint_options->pressure_options;
  GimpImage           *image;
  TempBuf             *area;
  PixelRegion          srcPR, destPR, tempPR;
  gdouble              rate;
  gdouble              opacity;
  gint                 x, y, w, h;

  image = gimp_item_get_image (GIMP_ITEM (drawable));

  if (gimp_drawable_is_indexed (drawable))
    return;

  opacity = gimp_paint_options_get_fade (paint_options, image,
                                         paint_core->pixel_dist);
  if (opacity == 0.0)
    return;

  /*  Get the unclipped brush coordinates  */
  gimp_smudge_brush_coords (paint_core, &x, &y, &w, &h);

  /*  Get the paint area (Smudge won't scale!)  */
  area = gimp_paint_core_get_paint_area (paint_core, drawable, paint_options);
  if (! area)
    return;

  /* srcPR will be the pixels under the current painthit from the drawable */
  pixel_region_init (&srcPR, gimp_drawable_get_tiles (drawable),
                     area->x, area->y, area->width, area->height, FALSE);

  /* Enable pressure sensitive rate */
  if (pressure_options->rate)
    rate = MIN (options->rate / 100.0 * PRESSURE_SCALE *
                paint_core->cur_coords.pressure, 1.0);
  else
    rate = options->rate / 100.0;

  /* The tempPR will be the built up buffer (for smudge) */
  pixel_region_init_data (&tempPR, smudge->accum_data,
                          smudge->accumPR.bytes,
                          smudge->accumPR.rowstride,
                          area->x - x,
                          area->y - y,
                          area->width,
                          area->height);

  /* The dest will be the paint area we got above (= canvas_buf) */
  pixel_region_init_temp_buf (&destPR, area,
                              0, 0, area->width, area->height);

  /*  Smudge uses the buffer Accum.
   *  For each successive painthit Accum is built like this
   *    Accum =  rate*Accum  + (1-rate)*I.
   *  where I is the pixels under the current painthit.
   *  Then the paint area (canvas_buf) is built as
   *    (Accum,1) (if no alpha),
   */

  blend_region (&srcPR, &tempPR, &tempPR, ROUND (rate * 255.0));

  /* re-init the tempPR */
  pixel_region_init_data (&tempPR, smudge->accum_data,
                          smudge->accumPR.bytes,
                          smudge->accumPR.rowstride,
                          area->x - x,
                          area->y - y,
                          area->width,
                          area->height);

  if (! gimp_drawable_has_alpha (drawable))
    add_alpha_region (&tempPR, &destPR);
  else
    copy_region (&tempPR, &destPR);

  if (pressure_options->opacity)
    opacity *= PRESSURE_SCALE * paint_core->cur_coords.pressure;

  gimp_brush_core_replace_canvas (GIMP_BRUSH_CORE (paint_core), drawable,
                                  MIN (opacity, GIMP_OPACITY_OPAQUE),
                                  gimp_context_get_opacity (context),
                                  gimp_paint_options_get_brush_mode (paint_options),
                                  GIMP_PAINT_INCREMENTAL);
}
コード例 #26
0
static void
gimp_brush_clipboard_buffer_changed (Gimp      *gimp,
                                     GimpBrush *brush)
{
  gint width;
  gint height;

  if (brush->mask)
    {
      temp_buf_free (brush->mask);
      brush->mask = NULL;
    }

  if (brush->pixmap)
    {
      temp_buf_free (brush->pixmap);
      brush->pixmap = NULL;
    }

  if (gimp->global_buffer)
    {
      TileManager   *tiles = gimp_buffer_get_tiles (gimp->global_buffer);
      GimpImageType  type  = gimp_buffer_get_image_type (gimp->global_buffer);

      width  = MIN (gimp_buffer_get_width  (gimp->global_buffer), 1024);
      height = MIN (gimp_buffer_get_height (gimp->global_buffer), 1024);

      brush->mask   = temp_buf_new (width, height, 1, 0, 0, NULL);
      brush->pixmap = temp_buf_new (width, height, 3, 0, 0, NULL);

      /*  copy the alpha channel into the brush's mask  */
      if (GIMP_IMAGE_TYPE_HAS_ALPHA (type))
        {
          PixelRegion bufferPR;
          PixelRegion maskPR;

          pixel_region_init (&bufferPR, tiles,
                             0, 0, width, height, FALSE);
          pixel_region_init_temp_buf (&maskPR, brush->mask,
                                      0, 0, width, height);

          extract_alpha_region (&bufferPR, NULL, &maskPR);
        }
      else
        {
          PixelRegion maskPR;
          guchar      opaque = OPAQUE_OPACITY;

          pixel_region_init_temp_buf (&maskPR, brush->mask,
                                      0, 0, width, height);
          color_region (&maskPR, &opaque);
        }

      /*  copy the color channels into the brush's pixmap  */
      if (GIMP_IMAGE_TYPE_IS_RGB (type))
        {
          PixelRegion bufferPR;
          PixelRegion pixmapPR;

          pixel_region_init (&bufferPR, tiles,
                             0, 0, width, height, FALSE);
          pixel_region_init_temp_buf (&pixmapPR, brush->pixmap,
                                      0, 0, width, height);

          if (GIMP_IMAGE_TYPE_HAS_ALPHA (type))
            copy_color (&bufferPR, &pixmapPR);
          else
            copy_region (&bufferPR, &pixmapPR);
        }
      else
        {
          PixelRegion  bufferPR;
          PixelRegion  tempPR;
          TempBuf     *temp = temp_buf_new (width, height, 1, 0, 0, NULL);

          pixel_region_init (&bufferPR, tiles,
                             0, 0, width, height, FALSE);
          pixel_region_init_temp_buf (&tempPR, temp,
                                      0, 0, width, height);

          if (GIMP_IMAGE_TYPE_HAS_ALPHA (type))
            copy_component (&bufferPR, &tempPR, 0);
          else
            copy_region (&bufferPR, &tempPR);

          temp_buf_copy (temp, brush->pixmap);
          temp_buf_free (temp);
        }
    }
  else
    {
      guchar color = 0;

      width  = 17;
      height = 17;

      brush->mask = temp_buf_new (width, height, 1, 0, 0, &color);
    }

  brush->x_axis.x = width / 2;
  brush->x_axis.y = 0;
  brush->y_axis.x = 0;
  brush->y_axis.y = height / 2;

  gimp_data_dirty (GIMP_DATA (brush));
}