/* 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); } }
/*-------------------------------------------------------------- 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; }
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; } }
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; }