static void fill_colortbl(unsigned char *lo_rgb, unsigned char *hi_rgb) { int i; double a, b; #if BLEND_USING_HSV fastf_t lo_hsv[3], hi_hsv[3]; fastf_t hsv[3]; bu_rgb_to_hsv(lo_rgb, lo_hsv); bu_rgb_to_hsv(hi_rgb, hi_hsv); #endif for (i = 0; i < MAX_COLORTBL; ++i) { b = ((double) i) / (MAX_COLORTBL - 1); a = 1.0 - b; #if BLEND_USING_HSV VBLEND2(hsv, a, lo_hsv, b, hi_hsv); bu_hsv_to_rgb(hsv, colortbl[i]); #else VBLEND2(colortbl[i], a, lo_rgb, b, hi_rgb); #endif } }
static void val_To_RGB(cell_val cv, unsigned char *rgb) { double val; if (color_flag) { COPYRGB(rgb, cv.v_color); return; } val = (cv.v_scalar - dom_min) * dom_cvt; if ((boolean_flag && !ZERO(cv.v_scalar - bool_val)) || (val < SMALL_FASTF) || (val > 10.0)) { COPYRGB(rgb, BACKGROUND); } else if (ZERO(val)) { COPYRGB(rgb, WHITE); } else { int idx; double rem; double res; if (interp_flag) { vect_t prev_hsv; vect_t hsv; vect_t next_hsv; idx = val + 0.01; /* convert to range [0 to 10] */ if ((rem = val - (double) idx) < 0.0) /* remainder */ rem = 0.0; res = 1.0 - rem; #if BLEND_USING_HSV bu_rgb_to_hsv(colortbl[idx], prev_hsv); bu_rgb_to_hsv(colortbl[idx+1], next_hsv); VBLEND2(hsv, res, prev_hsv, rem, next_hsv); bu_hsv_to_rgb(hsv, rgb); #else VBLEND2(rgb, res, colortbl[idx], rem, colortbl[idx+1]); #endif } else { idx = val + 0.51; COPYRGB(rgb, colortbl[idx]); } } return; }
/** * action performed at the end of each scanline */ void view_eol(struct application *ap) { int cpu = ap->a_resource->re_cpu; int i; if (overlay) { /* * Overlay mode. Check if the pixel is an edge. If so, write * it to the framebuffer. */ for (i = 0; i < per_processor_chunk; ++i) { if (writeable[cpu][i]) { /* * Write this pixel */ bu_semaphore_acquire(BU_SEM_SYSCALL); fb_write(fbp, i, ap->a_y, &scanline[cpu][i*3], 1); bu_semaphore_release(BU_SEM_SYSCALL); } } return; } else if (blend) { /* * Blend mode. * * Read a line from the existing framebuffer, convert to HSV, * manipulate, and put the results in the scanline as RGB. */ int replace_down = 0; /* flag that specifies if the pixel in the * scanline below must be replaced. */ RGBpixel rgb; fastf_t hsv[3]; bu_semaphore_acquire(BU_SEM_SYSCALL); if (fb_read(fbp, 0, ap->a_y, blendline[cpu], per_processor_chunk) < 0) bu_exit(EXIT_FAILURE, "rtedge: error reading from framebuffer.\n"); bu_semaphore_release(BU_SEM_SYSCALL); for (i = 0; i < per_processor_chunk; ++i) { /* * Is this pixel an edge? */ if (writeable[cpu][i]) { /* * The pixel is an edge, retrieve the appropriate * pixel from the line buffer and convert it to HSV. */ rgb[RED] = blendline[cpu][i*3+RED]; rgb[GRN] = blendline[cpu][i*3+GRN]; rgb[BLU] = blendline[cpu][i*3+BLU]; /* * Is the pixel in the blendline array the background * color? If so, look left and down to determine which * pixel is the "source" of the edge. Unless, of * course, we are on the bottom scanline or the * leftmost column (x=y=0) */ if (i != 0 && ap->a_y != 0 && !diffpixel(rgb, fb_bg_color)) { RGBpixel left; RGBpixel down; left[RED] = blendline[cpu][(i-1)*3+RED]; left[GRN] = blendline[cpu][(i-1)*3+GRN]; left[BLU] = blendline[cpu][(i-1)*3+BLU]; bu_semaphore_acquire(BU_SEM_SYSCALL); fb_read(fbp, i, ap->a_y - 1, down, 1); bu_semaphore_release(BU_SEM_SYSCALL); if (diffpixel(left, fb_bg_color)) { /* * Use this one. */ rgb[RED] = left[RED]; rgb[GRN] = left[GRN]; rgb[BLU] = left[BLU]; } else if (diffpixel(down, fb_bg_color)) { /* * Use the pixel from the scanline below */ replace_down = 1; rgb[RED] = down[RED]; rgb[GRN] = down[GRN]; rgb[BLU] = down[BLU]; } } /* * Convert to HSV */ bu_rgb_to_hsv(rgb, hsv); /* * Now perform the manipulations. */ hsv[VAL] *= 3.0; hsv[SAT] /= 3.0; if (hsv[VAL] > 1.0) { fastf_t d = hsv[VAL] - 1.0; hsv[VAL] = 1.0; hsv[SAT] -= d; hsv[SAT] = hsv[SAT] >= 0.0 ? hsv[SAT] : 0.0; } /* * Convert back to RGB. */ bu_hsv_to_rgb(hsv, rgb); if (replace_down) { /* * Write this pixel immediately, do not put it * into the blendline since it corresponds to the * wrong scanline. */ bu_semaphore_acquire(BU_SEM_SYSCALL); fb_write(fbp, i, ap->a_y, rgb, 1); bu_semaphore_release(BU_SEM_SYSCALL); replace_down = 0; } else { /* * Put this pixel back into the blendline array. * We'll push it to the buffer when the entire * scanline has been processed. */ blendline[cpu][i*3+RED] = rgb[RED]; blendline[cpu][i*3+GRN] = rgb[GRN]; blendline[cpu][i*3+BLU] = rgb[BLU]; } } /* end "if this pixel is an edge" */ } /* end pixel loop */ /* * Write the blendline to the framebuffer. */ bu_semaphore_acquire(BU_SEM_SYSCALL); fb_write(fbp, 0, ap->a_y, blendline[cpu], per_processor_chunk); bu_semaphore_release(BU_SEM_SYSCALL); return; } /* end blend */ if (fbp != FBIO_NULL) { /* * Simple whole scanline write to a framebuffer. */ bu_semaphore_acquire(BU_SEM_SYSCALL); fb_write(fbp, 0, ap->a_y, scanline[cpu], per_processor_chunk); bu_semaphore_release(BU_SEM_SYSCALL); } if (outputfile != NULL) { /* * Write to a file. */ bu_semaphore_acquire(BU_SEM_SYSCALL); /* TODO : Add double type data to maintain resolution */ icv_writeline(bif, ap->a_y, scanline[cpu], ICV_DATA_UCHAR); bu_semaphore_release(BU_SEM_SYSCALL); } if (fbp == FBIO_NULL && outputfile == NULL) bu_log("rtedge: strange, no end of line actions taken.\n"); return; }