static int ambitv_lpd8806_set_output_to_rgb( struct ambitv_sink_component* component, int idx, int r, int g, int b) { int ret = -1, *outp = NULL, i, *rgb[] = {&r, &g, &b}; uint16_t rt, gt, bt, d; struct ambitv_lpd8806_priv* lpd8806 = (struct ambitv_lpd8806_priv*)component->priv; outp = ambitv_lpd8806_ptr_for_output(lpd8806, idx, NULL, NULL); if (NULL != outp) { int ii = *outp; if (lpd8806->num_bbuf) { unsigned char* acc = lpd8806->bbuf[lpd8806->bbuf_idx]; acc[3 * ii] = g; acc[3 * ii + 1] = r; acc[3 * ii + 2] = b; r = g = b = 0; for (i=0; i<lpd8806->num_bbuf; i++) { g += lpd8806->bbuf[i][3 * ii]; r += lpd8806->bbuf[i][3 * ii + 1]; b += lpd8806->bbuf[i][3 * ii + 2]; } g /= lpd8806->num_bbuf; r /= lpd8806->num_bbuf; b /= lpd8806->num_bbuf; } for (i=0; i<3; i++) { if (lpd8806->gamma_lut[i]) *rgb[i] = ambitv_color_map_with_lut(lpd8806->gamma_lut[i], *rgb[i]); } rt = r >> 3; gt = g >> 3; bt = b >> 3; d = (rt*1024) + (gt*32) + bt + 32768; lpd8806->grb[2 * ii + 4] = d >> 8; lpd8806->grb[2 * ii + 5] = d & 0x00FF; ret = 0; }
static int ambitv_lpd8806_map_output_to_point( struct ambitv_sink_component* component, int output, int width, int height, int* x, int* y) { int ret = -1, *outp = NULL, str_idx = 0, led_idx = 0; struct ambitv_lpd8806_priv* lpd8806 = (struct ambitv_lpd8806_priv*)component->priv; outp = ambitv_lpd8806_ptr_for_output(lpd8806, output, &str_idx, &led_idx); if (NULL != outp) { ret = 0; float llen = lpd8806->led_len[str_idx] - 1; float dim = (str_idx < 2) ? width : height; float inset = lpd8806->led_inset[str_idx] * dim; dim -= 2*inset; switch (str_idx) { case 0: // top *x = (int)CONSTRAIN(inset + (dim / llen) * led_idx, 0, width); *y = 0; break; case 1: // bottom *x = (int)CONSTRAIN(inset + (dim / llen) * led_idx, 0, width); *y = height; break; case 2: // left *x = 0; *y = (int)CONSTRAIN(inset + (dim / llen) * led_idx, 0, height); break; case 3: // right *x = width; *y = (int)CONSTRAIN(inset + (dim / llen) * led_idx, 0, height); break; default: ret = -1; break; } } else { *x = *y = -1; } return ret; }
void test_lpd8806_ptr_for_output_top_left(void) { set_up(); int output = 0; int str_idx = -1; int led_idx = -1; int *ptr = ambitv_lpd8806_ptr_for_output(SINK->priv, output, &str_idx, &led_idx); CU_ASSERT_EQUAL(str_idx, 0); CU_ASSERT_EQUAL(led_idx, 0); CU_ASSERT_PTR_NOT_NULL_FATAL(ptr); CU_ASSERT_EQUAL(ptr, get_led_str(SINK, 0, 0)); tear_down(); }
void test_lpd8806_ptr_for_output_bottom_left(void) { set_up(); // LEDs are indexed continuously through the side arrays top-bottom-left-right // not according to the stripe layout or clockwise sequence so ten means it is on // the second side which is the bottom one int output = 10; int str_idx = -1; int led_idx = -1; int *ptr = ambitv_lpd8806_ptr_for_output(SINK->priv, output, &str_idx, &led_idx); CU_ASSERT_EQUAL(str_idx, 1); CU_ASSERT_EQUAL(led_idx, 0); CU_ASSERT_PTR_NOT_NULL_FATAL(ptr); CU_ASSERT_EQUAL(ptr, get_led_str(SINK, 1, 0)); tear_down(); }
void test_lpd8806_ptr_for_output_left_top(void) { set_up(); // LEDs are indexed continuously through the side arrays top-bottom-left-right // not according to the stripe layout or clockwise sequence // The first LED on the left side comes after ten LEDs from the top, then ten LEDs // from the bottom; therefore it is number 20. int output = 20; int str_idx = -1; int led_idx = -1; int *ptr = ambitv_lpd8806_ptr_for_output(SINK->priv, output, &str_idx, &led_idx); CU_ASSERT_EQUAL(str_idx, 2); CU_ASSERT_EQUAL(led_idx, 0); CU_ASSERT_PTR_NOT_NULL_FATAL(ptr); CU_ASSERT_EQUAL(ptr, get_led_str(SINK, 2, 0)); tear_down(); }