Example #1
0
/* Write the cluster read map for all files in INFO as BMP image to FILE.
 * If MAX_X is not 0, scale all lines to MAX_X pixels.  Use POOL for
 * allocations.
 */
static void
write_bitmap(apr_array_header_t *info,
             int max_x,
             apr_file_t *file,
             apr_pool_t *pool)
{
  int ysize = info->nelts;
  int xsize = 0;
  int x, y;
  apr_size_t row_size;
  apr_size_t written;
  color_t *line, *scaled_line;
  svn_boolean_t do_scale = max_x > 0;

  /* xsize = max cluster number */
  for (y = 0; y < ysize; ++y)
    if (xsize < APR_ARRAY_IDX(info, y, file_stats_t *)->read_map->nelts)
      xsize = APR_ARRAY_IDX(info, y, file_stats_t *)->read_map->nelts;

  /* limit picture dimensions (16k pixels in each direction) */
  if (xsize >= 0x4000)
    xsize = 0x3fff;
  if (ysize >= 0x4000)
    ysize = 0x3fff;
  if (max_x == 0)
    max_x = xsize;

  /* rows in BMP files must be aligned to 4 bytes */
  row_size = APR_ALIGN(max_x * sizeof(color_t), 4);

  /**/
  line = apr_pcalloc(pool, xsize * sizeof(color_t));
  scaled_line = apr_pcalloc(pool, row_size);

  /* write header to file */
  write_bitmap_header(file, max_x, ysize);

  /* write all rows */
  for (y = 0; y < ysize; ++y)
    {
      file_stats_t *file_info = APR_ARRAY_IDX(info, y, file_stats_t *);
      int block_count = file_info->read_map->nelts;
      for (x = 0; x < xsize; ++x)
        {
          color_t color = { 128, 128, 128 };
          if (x < block_count)
            {
              word count = APR_ARRAY_IDX(file_info->read_map, x, word);
              select_color(color, count);
            }

          memcpy(line[x], color, sizeof(color));
        }

      scale_line(scaled_line, max_x, line, block_count ? block_count : 1);

      written = row_size;
      apr_file_write(file, do_scale ? scaled_line : line, &written);
    }
}
Example #2
0
/*--------------------------------------------------------------
 Routine : scale_segment
 Purpose : Scales the segment.
           Creates and returns the "scaled" segment.
           Space is allocated to hold the scaled segment.
---------------------------------------------------------------*/
static SEGMENT *
scale_segment(SEGMENT *seg_list, float scale)
{
    SEGMENT        *new_seg;

/*     ASSERTMSG(      */
/*       fValidPointer( seg_list, sizeof( SEGMENT ) ),     */
/*       "Segment list ptr not valid" );     */

/*     if ((new_seg = (SEGMENT *)malloc(sizeof(SEGMENT))) == NULL) { */
/*         printf("\n*** scale_segment : malloc failed ***\n"); */
/*         exit(1); */
/*     } */
    if ( !fNewMemory( (void *)&new_seg, sizeof( SEGMENT ) ) )
    {
      printf("\n*** scale_segment : malloc failed ***\n");
      exit(1);
    }
    new_seg->next = NULL;
    new_seg->type = seg_list->type;
/*     new_seg->seg = seg_list->seg;  */
    switch (seg_list->type) {
    case CLEAR_ARC_SEG :
    case FILL_ARC_SEG :
    case ARC_SEG :
        new_seg->seg = (void *)scale_arc(seg_list->seg, scale);
        break;
    case RECTANGLE_SEG :
	case FILL_RECTANGLE_SEG:
        new_seg->seg = (void *)scale_rectangle(seg_list->seg, scale);
        break;
    case FILL_POLYLINE_SEG :
    case POLYLINE_SEG :
        new_seg->seg = (void *)scale_polyline(seg_list->seg, scale);
        break;
    case LINE_SEG :
        new_seg->seg = (void *)scale_line(seg_list->seg, scale);
        break;
    default:
        printf("\n*** scale_segment : Invalid symbol type ***\n\n");
        exit(1);
    }
    return new_seg;
}
Example #3
0
void gr_bitmap_scale_to(grs_bitmap *src, grs_bitmap *dst)
{
	unsigned char *s = src->bm_data;
	unsigned char *d = dst->bm_data;
	int h = src->bm_h;
	int a = dst->bm_h/h, b = dst->bm_h%h;
	int c = 0, i, y;

	for(y=0; y<h; y++) {
		i = a;
		c += b;
		if(c >= h) {
			c -= h;
			goto inside;
		}
		while(--i>=0) {
inside:
			scale_line(s, d, src->bm_w, dst->bm_w);
			d += dst->bm_rowsize;
		}
		s += src->bm_rowsize;
	}
}
Example #4
0
static int vivid_copy_buffer(struct vivid_dev *dev, unsigned p, u8 *vcapbuf,
		struct vivid_buffer *vid_cap_buf)
{
	bool blank = dev->must_blank[vid_cap_buf->vb.v4l2_buf.index];
	struct tpg_data *tpg = &dev->tpg;
	struct vivid_buffer *vid_out_buf = NULL;
	unsigned pixsize = tpg_g_twopixelsize(tpg, p) / 2;
	unsigned img_width = dev->compose_cap.width;
	unsigned img_height = dev->compose_cap.height;
	unsigned stride_cap = tpg->bytesperline[p];
	unsigned stride_out = dev->bytesperline_out[p];
	unsigned stride_osd = dev->display_byte_stride;
	unsigned hmax = (img_height * tpg->perc_fill) / 100;
	u8 *voutbuf;
	u8 *vosdbuf = NULL;
	unsigned y;
	bool blend = dev->bitmap_out || dev->clipcount_out || dev->fbuf_out_flags;
	/* Coarse scaling with Bresenham */
	unsigned vid_out_int_part;
	unsigned vid_out_fract_part;
	unsigned vid_out_y = 0;
	unsigned vid_out_error = 0;
	unsigned vid_overlay_int_part = 0;
	unsigned vid_overlay_fract_part = 0;
	unsigned vid_overlay_y = 0;
	unsigned vid_overlay_error = 0;
	unsigned vid_cap_right;
	bool quick;

	vid_out_int_part = dev->loop_vid_out.height / dev->loop_vid_cap.height;
	vid_out_fract_part = dev->loop_vid_out.height % dev->loop_vid_cap.height;

	if (!list_empty(&dev->vid_out_active))
		vid_out_buf = list_entry(dev->vid_out_active.next,
					 struct vivid_buffer, list);
	if (vid_out_buf == NULL)
		return -ENODATA;

	vid_cap_buf->vb.v4l2_buf.field = vid_out_buf->vb.v4l2_buf.field;

	voutbuf = vb2_plane_vaddr(&vid_out_buf->vb, p) +
				  vid_out_buf->vb.v4l2_planes[p].data_offset;
	voutbuf += dev->loop_vid_out.left * pixsize + dev->loop_vid_out.top * stride_out;
	vcapbuf += dev->compose_cap.left * pixsize + dev->compose_cap.top * stride_cap;

	if (dev->loop_vid_copy.width == 0 || dev->loop_vid_copy.height == 0) {
		/*
		 * If there is nothing to copy, then just fill the capture window
		 * with black.
		 */
		for (y = 0; y < hmax; y++, vcapbuf += stride_cap)
			memcpy(vcapbuf, tpg->black_line[p], img_width * pixsize);
		return 0;
	}

	if (dev->overlay_out_enabled &&
	    dev->loop_vid_overlay.width && dev->loop_vid_overlay.height) {
		vosdbuf = dev->video_vbase;
		vosdbuf += dev->loop_fb_copy.left * pixsize +
			   dev->loop_fb_copy.top * stride_osd;
		vid_overlay_int_part = dev->loop_vid_overlay.height /
				       dev->loop_vid_overlay_cap.height;
		vid_overlay_fract_part = dev->loop_vid_overlay.height %
					 dev->loop_vid_overlay_cap.height;
	}

	vid_cap_right = dev->loop_vid_cap.left + dev->loop_vid_cap.width;
	/* quick is true if no video scaling is needed */
	quick = dev->loop_vid_out.width == dev->loop_vid_cap.width;

	dev->cur_scaled_line = dev->loop_vid_out.height;
	for (y = 0; y < hmax; y++, vcapbuf += stride_cap) {
		/* osdline is true if this line requires overlay blending */
		bool osdline = vosdbuf && y >= dev->loop_vid_overlay_cap.top &&
			  y < dev->loop_vid_overlay_cap.top + dev->loop_vid_overlay_cap.height;

		/*
		 * If this line of the capture buffer doesn't get any video, then
		 * just fill with black.
		 */
		if (y < dev->loop_vid_cap.top ||
		    y >= dev->loop_vid_cap.top + dev->loop_vid_cap.height) {
			memcpy(vcapbuf, tpg->black_line[p], img_width * pixsize);
			continue;
		}

		/* fill the left border with black */
		if (dev->loop_vid_cap.left)
			memcpy(vcapbuf, tpg->black_line[p], dev->loop_vid_cap.left * pixsize);

		/* fill the right border with black */
		if (vid_cap_right < img_width)
			memcpy(vcapbuf + vid_cap_right * pixsize,
				tpg->black_line[p], (img_width - vid_cap_right) * pixsize);

		if (quick && !osdline) {
			memcpy(vcapbuf + dev->loop_vid_cap.left * pixsize,
			       voutbuf + vid_out_y * stride_out,
			       dev->loop_vid_cap.width * pixsize);
			goto update_vid_out_y;
		}
		if (dev->cur_scaled_line == vid_out_y) {
			memcpy(vcapbuf + dev->loop_vid_cap.left * pixsize,
			       dev->scaled_line,
			       dev->loop_vid_cap.width * pixsize);
			goto update_vid_out_y;
		}
		if (!osdline) {
			scale_line(voutbuf + vid_out_y * stride_out, dev->scaled_line,
				dev->loop_vid_out.width, dev->loop_vid_cap.width,
				tpg_g_twopixelsize(tpg, p));
		} else {
			/*
			 * Offset in bytes within loop_vid_copy to the start of the
			 * loop_vid_overlay rectangle.
			 */
			unsigned offset =
				(dev->loop_vid_overlay.left - dev->loop_vid_copy.left) * pixsize;
			u8 *osd = vosdbuf + vid_overlay_y * stride_osd;

			scale_line(voutbuf + vid_out_y * stride_out, dev->blended_line,
				dev->loop_vid_out.width, dev->loop_vid_copy.width,
				tpg_g_twopixelsize(tpg, p));
			if (blend)
				blend_line(dev, vid_overlay_y + dev->loop_vid_overlay.top,
					   dev->loop_vid_overlay.left,
					   dev->blended_line + offset, osd,
					   dev->loop_vid_overlay.width, pixsize);
			else
				memcpy(dev->blended_line + offset,
				       osd, dev->loop_vid_overlay.width * pixsize);
			scale_line(dev->blended_line, dev->scaled_line,
					dev->loop_vid_copy.width, dev->loop_vid_cap.width,
					tpg_g_twopixelsize(tpg, p));
		}
		dev->cur_scaled_line = vid_out_y;
		memcpy(vcapbuf + dev->loop_vid_cap.left * pixsize,
		       dev->scaled_line,
		       dev->loop_vid_cap.width * pixsize);

update_vid_out_y:
		if (osdline) {
			vid_overlay_y += vid_overlay_int_part;
			vid_overlay_error += vid_overlay_fract_part;
			if (vid_overlay_error >= dev->loop_vid_overlay_cap.height) {
				vid_overlay_error -= dev->loop_vid_overlay_cap.height;
				vid_overlay_y++;
			}
		}
		vid_out_y += vid_out_int_part;
		vid_out_error += vid_out_fract_part;
		if (vid_out_error >= dev->loop_vid_cap.height) {
			vid_out_error -= dev->loop_vid_cap.height;
			vid_out_y++;
		}
	}

	if (!blank)
		return 0;
	for (; y < img_height; y++, vcapbuf += stride_cap)
		memcpy(vcapbuf, tpg->contrast_line[p], img_width * pixsize);
	return 0;
}