Skip to content

Instantly share code, notes, and snippets.

@AndrewFromMelbourne
Created March 6, 2015 11:25
Show Gist options
  • Save AndrewFromMelbourne/aa21944cbef4a8a0ae40 to your computer and use it in GitHub Desktop.
Save AndrewFromMelbourne/aa21944cbef4a8a0ae40 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <bcm_host.h>
#define SRC_WIDTH 640
#define SRC_HEIGHT 480
#define DST_WIDTH 1920
#define DST_HEIGHT 1080
int main()
{
bcm_host_init();
uint8_t *dst_buffer = malloc(DST_WIDTH * DST_HEIGHT * 4);
uint8_t *src_buffer = malloc(SRC_WIDTH * SRC_HEIGHT * 4);
int i, j;
for (i = 0; i < SRC_HEIGHT; i++) {
uint8_t p0 = i % 50 < 25 ? 0xff : 0x00;
uint8_t p1 = i % 50 < 25 ? 0x00 : 0xff;
for (j = 0; j < SRC_WIDTH; j++) {
uint8_t val = j % 50 < 25 ? p0 : p1;
src_buffer[i * SRC_WIDTH * 4 + 4 * j] = val;
src_buffer[i * SRC_WIDTH * 4 + 4 * j + 1] = val;
src_buffer[i * SRC_WIDTH * 4 + 4 * j + 2] = val;
src_buffer[i * SRC_WIDTH * 4 + 4 * j + 3] = 0xff;
}
}
DISPMANX_RESOURCE_HANDLE_T dest_res;
DISPMANX_DISPLAY_HANDLE_T display;
uint32_t dest_image_handle;
VC_IMAGE_TYPE_T img_type;
printf("+ %s(): create dest resource\n", __func__);
dest_res = vc_dispmanx_resource_create(VC_IMAGE_RGBA32,
DST_WIDTH, DST_HEIGHT, &dest_image_handle);
printf("+ %s(): create offscreen display\n", __func__);
display = vc_dispmanx_display_open_offscreen(dest_res,
DISPMANX_NO_ROTATE);
img_type = VC_IMAGE_RGBA32;
{
DISPMANX_RESOURCE_HANDLE_T src_res;
DISPMANX_ELEMENT_HANDLE_T src_el;
DISPMANX_UPDATE_HANDLE_T update;
VC_DISPMANX_ALPHA_T alpha;
uint32_t src_image_handle;
VC_RECT_T bmp_rect;
VC_RECT_T src_rect;
VC_RECT_T dst_rect;
const int src_pitch = SRC_WIDTH * 4;
const int dst_pitch = DST_WIDTH * 4;
const int src_height = SRC_HEIGHT;
const int src_width = SRC_WIDTH;
const int dst_height = DST_HEIGHT;
const int dst_width = DST_WIDTH;
printf("+ %s(): configure dimensions\n", __func__);
vc_dispmanx_rect_set(&bmp_rect, 0, 0, src_width, src_height);
vc_dispmanx_rect_set(&src_rect, 0, 0, src_width << 16, src_height << 16);
vc_dispmanx_rect_set(&dst_rect, 0, 0, dst_width, dst_height);
printf("+ %s(): start update\n", __func__);
update = vc_dispmanx_update_start(0);
printf("+ %s(): create source resource\n", __func__);
/* upload src image to dispmanx */
src_res = vc_dispmanx_resource_create(img_type,
src_width | (src_pitch << 16), src_height | (src_height << 16),
&src_image_handle);
printf("+ %s(): upload source data\n", __func__);
vc_dispmanx_resource_write_data(src_res, img_type, src_pitch,
src_buffer, &bmp_rect);
alpha.mask = DISPMANX_NO_HANDLE;
alpha.flags = DISPMANX_FLAGS_ALPHA_FROM_SOURCE | DISPMANX_FLAGS_ALPHA_MIX;
alpha.opacity = 255;
printf("+ %s(): place element\n", __func__);
/* place image to scaled output */
src_el = vc_dispmanx_element_add(update, display, 0, &dst_rect, src_res,
&src_rect, DISPMANX_PROTECTION_NONE, &alpha, NULL, VC_IMAGE_ROT0);
printf("+ %s(): submit\n", __func__);
/* execute the scaling */
vc_dispmanx_update_submit_sync(update);
printf("+ %s(): read data back\n", __func__);
/* read scaled image back */
vc_dispmanx_resource_read_data(dest_res, &dst_rect,
dst_buffer, dst_pitch);
/* teardown */
vc_dispmanx_element_remove(update, src_el);
vc_dispmanx_display_close(display);
vc_dispmanx_resource_delete(src_res);
vc_dispmanx_resource_delete(dest_res);
}
FILE *f = fopen("/tmp/input.rgba", "wb");
fwrite(src_buffer, SRC_WIDTH * SRC_HEIGHT * 4, 1, f);
fclose(f);
f = fopen("/tmp/output.rgba", "wb");
fwrite(dst_buffer, DST_WIDTH * DST_HEIGHT * 4, 1, f);
fclose(f);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment