/* routines used for generating RGB raster images * * D_cell_draw_setup_RGB(t, b, l, r) * int t, b, l, r (pixle extents of display window) * (obtainable via D_get_screen_window(&t, &b, &l, &r) * Sets up the environment for D_draw_cell_RGB et al * * D_draw_cell_RGB(A_row, r_array, g_array, b_array, minval, maxval) * int A_row ; * CELL *r_array, *b_array, *g_array ; * CELL minval, maxval ; * - determinew which pixel row gets the data * - scales the data such that minval => 0 and maxval => 255 * - resamples the data to create a pixel array * - returns -1 on error or end of picture * or array row number needed for next pixel row. * * presumes the map is drawn from north to south * * NOTE: D_cell_draw_RGB() must be preceded by a call to D_set_colors_RGB() * * ALSO: if overlay mode is desired, then call D_set_overlay_mode(1) * first. */ #include #include #include #include #include extern int D__overlay_mode; static int *D_to_A_tab; static int D_x_beg, D_y_beg, D_x_end, D_y_end ; static int cur_D_row ; static int color_buf_size; static unsigned char *r_buf, *g_buf, *b_buf, *n_buf; static void *r_raster, *g_raster, *b_raster; static int draw_cell_RGB( int A_row, void *r_array, void *g_array, void *b_array, struct Colors *r_colors, struct Colors *g_colors, struct Colors *b_colors, RASTER_MAP_TYPE r_type, RASTER_MAP_TYPE g_type, RASTER_MAP_TYPE b_type); int D_draw_raster_RGB( int A_row, void *r_array, void *g_array, void *b_array, struct Colors *r_colors, struct Colors *g_colors, struct Colors *b_colors, RASTER_MAP_TYPE r_type, RASTER_MAP_TYPE g_type, RASTER_MAP_TYPE b_type) { return draw_cell_RGB(A_row, r_array, g_array, b_array, r_colors, g_colors, b_colors, r_type, g_type, b_type); } int D_draw_d_raster_RGB( int A_row, DCELL *r_array, DCELL *g_array, DCELL *b_array, struct Colors *r_colors, struct Colors *g_colors, struct Colors *b_colors) { return draw_cell_RGB(A_row, r_array, g_array, b_array, r_colors, g_colors, b_colors, DCELL_TYPE, DCELL_TYPE, DCELL_TYPE); } int D_draw_f_raster_RGB( int A_row, FCELL *r_array, FCELL *g_array, FCELL *b_array, struct Colors *r_colors, struct Colors *g_colors, struct Colors *b_colors) { return draw_cell_RGB(A_row, r_array, g_array, b_array, r_colors, g_colors, b_colors, FCELL_TYPE, FCELL_TYPE, FCELL_TYPE); } int D_draw_c_raster_RGB( int A_row, CELL *r_array, CELL *g_array, CELL *b_array, struct Colors *r_colors, struct Colors *g_colors, struct Colors *b_colors) { return draw_cell_RGB(A_row, r_array, g_array, b_array, r_colors, g_colors, b_colors, CELL_TYPE, CELL_TYPE, CELL_TYPE); } int D_draw_cell_RGB( int A_row, CELL *r_array, CELL *g_array, CELL *b_array, struct Colors *r_colors, struct Colors *g_colors, struct Colors *b_colors) { return draw_cell_RGB(A_row, r_array, g_array, b_array, r_colors, g_colors, b_colors, CELL_TYPE, CELL_TYPE, CELL_TYPE); } static int draw_cell_RGB( int A_row, void *r_array, void *g_array, void *b_array, struct Colors *r_colors, struct Colors *g_colors, struct Colors *b_colors, RASTER_MAP_TYPE r_type, RASTER_MAP_TYPE g_type, RASTER_MAP_TYPE b_type) { int D_row ; int repeat ; int cur_A_row ; int r_size = G_raster_size(r_type); int g_size = G_raster_size(g_type); int b_size = G_raster_size(b_type); size_t r_bytes = (D_x_end - D_x_beg) * r_size; size_t g_bytes = (D_x_end - D_x_beg) * g_size; size_t b_bytes = (D_x_end - D_x_beg) * b_size; /* Allocate memory for raster */ if(!r_raster) r_raster = G_malloc(r_bytes) ; if(!g_raster) g_raster = G_malloc(g_bytes) ; if(!b_raster) b_raster = G_malloc(b_bytes) ; /* If picture is done, return -1 */ if (cur_D_row >= D_y_end) return(-1) ; /* Get window (array) row currently required */ D_row = cur_D_row ; cur_A_row = (int)D_d_to_a_row(cur_D_row + 0.5) ; /* If we need a row further down the array, return that row number */ if (cur_A_row > A_row) return (cur_A_row) ; /* Find out how many screen lines the current A_row gets repeated */ repeat = 1 ; for (cur_D_row++ ; cur_D_row < D_y_end; cur_D_row++) { if (A_row == (cur_A_row = (int)D_d_to_a_row(cur_D_row + 0.5))) repeat++ ; else break ; } /* Make the screen raster */ { register int D_col ; void *r_ptr, *r_arr_ptr; void *g_ptr, *g_arr_ptr; void *b_ptr, *b_arr_ptr; r_ptr = r_raster; g_ptr = g_raster; b_ptr = b_raster; for (D_col = D_x_beg; D_col < D_x_end; D_col++) { /* copy array[[D_to_A_tab[D_col]] to *raster, advance raster by 1 */ r_arr_ptr = G_incr_void_ptr(r_array, D_to_A_tab[D_col] * r_size); G_raster_cpy(r_ptr, r_arr_ptr, 1, r_type); r_ptr = G_incr_void_ptr(r_ptr, r_size); g_arr_ptr = G_incr_void_ptr(g_array, D_to_A_tab[D_col] * g_size); G_raster_cpy(g_ptr, g_arr_ptr, 1, g_type); g_ptr = G_incr_void_ptr(g_ptr, g_size); b_arr_ptr = G_incr_void_ptr(b_array, D_to_A_tab[D_col] * b_size); G_raster_cpy(b_ptr, b_arr_ptr, 1, b_type); b_ptr = G_incr_void_ptr(b_ptr, b_size); } } R_move_abs(D_x_beg, D_row) ; D_raster_of_type_RGB(r_raster, g_raster, b_raster, D_x_end - D_x_beg, repeat, r_colors, g_colors, b_colors, r_type, g_type, b_type); /* If picture is done, return -1 */ if (cur_D_row >= D_y_end) return(-1) ; /* Return the array row of the next row needed */ return (cur_A_row) ; } int D_cell_draw_setup_RGB(int t,int b,int l,int r) { int D_col ; struct Cell_head window ; if (G_get_set_window(&window) == -1) G_fatal_error("Current window not available") ; if (D_do_conversions(&window, t, b, l, r)) G_fatal_error("Error in calculating conversions") ; /* Set up the screen for drawing map */ D_x_beg = (int)D_get_d_west() ; D_x_end = (int)D_get_d_east() ; D_y_beg = (int)D_get_d_north() ; D_y_end = (int)D_get_d_south() ; cur_D_row = D_y_beg ; if (D_to_A_tab) free (D_to_A_tab) ; D_to_A_tab = (int *)G_calloc(D_x_end, sizeof(int)) ; /* construct D_to_A_tab for converting x screen Dots to x data Array values */ for (D_col = D_x_beg; D_col < D_x_end; D_col++) D_to_A_tab[D_col] = (int)(D_d_to_a_col(D_col + 0.5)) ; if (r_raster) { free(r_raster) ; r_raster = NULL ; } if (g_raster) { free(g_raster) ; g_raster = NULL ; } if (b_raster) { free(b_raster) ; b_raster = NULL ; } return(0) ; } int D_raster_of_type_RGB ( void *r_raster, void *g_raster, void *b_raster, int ncols,int nrows, struct Colors *r_colors, struct Colors *g_colors, struct Colors *b_colors, RASTER_MAP_TYPE r_type, RASTER_MAP_TYPE g_type, RASTER_MAP_TYPE b_type) { int r_size = G_raster_size(r_type); int g_size = G_raster_size(g_type); int b_size = G_raster_size(b_type); int i; /* reallocate color_buf if necessary */ if(ncols > color_buf_size) { r_buf = (unsigned char *) G_realloc(r_buf, ncols); g_buf = (unsigned char *) G_realloc(g_buf, ncols); b_buf = (unsigned char *) G_realloc(b_buf, ncols); n_buf = (unsigned char *) G_realloc(n_buf, ncols); color_buf_size = ncols; } /* convert cell values to bytes */ for (i = 0; i < ncols; i++) { int r, g, b, x; G_get_raster_color (r_raster, &r, &x, &x, r_colors, r_type); G_get_raster_color (g_raster, &x, &g, &x, g_colors, g_type); G_get_raster_color (b_raster, &x, &x, &b, b_colors, b_type); r_buf[i] = r; g_buf[i] = g; b_buf[i] = b; n_buf[i] = (G_is_null_value(r_raster, r_type) || G_is_null_value(g_raster, g_type) || G_is_null_value(b_raster, b_type)); r_raster = G_incr_void_ptr(r_raster, r_size); g_raster = G_incr_void_ptr(g_raster, g_size); b_raster = G_incr_void_ptr(b_raster, b_size); } R_RGB_raster (ncols, nrows, r_buf, g_buf, b_buf, D__overlay_mode ? n_buf : NULL); return 0; } void D_set_colors_RGB(void) { unsigned char array[256]; int i; for (i = 0; i < 256; i++) array[i] = i; R_set_RGB_color(array, array, array); }