📄 gseispalette.c
字号:
/* * GTKSEISVIEWGL - Library for rendering of 2D seismic data * * Copyright (C) 2006 Vladimir Bashkardin * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more av. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * Author: Vladimir Bashkardin <vovizmus@users.sourceforge.net> */#include <GL/gl.h>#include <gdk/gdkglglext.h>#include "gseispalette.h"static GMemChunk *color_chunk;GSeisColor* g_seis_color_copy (const GSeisColor *color) { GSeisColor *new_color; g_return_val_if_fail (color != NULL, NULL); if (color_chunk == NULL) color_chunk = g_mem_chunk_new ("colors", sizeof (GSeisColor), 4096, G_ALLOC_AND_FREE); new_color = g_chunk_new (GSeisColor, color_chunk); *new_color = *color; return new_color;}void g_seis_color_free (GSeisColor *color) { g_assert (color_chunk != NULL); g_return_if_fail (color != NULL); g_mem_chunk_free (color_chunk, color);}GType g_seis_color_get_type (void) { static GType our_type = 0; if (our_type == 0) our_type = g_boxed_type_register_static ("GSeisColor", (GBoxedCopyFunc)g_seis_color_copy, (GBoxedFreeFunc)g_seis_color_free); return our_type;}G_DEFINE_TYPE (GSeisPalette, g_seis_palette, G_TYPE_OBJECT)#define G_SEIS_PALETTE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), G_SEIS_TYPE_PALETTE, GSeisPalettePrivate))typedef struct _GSeisPalettePrivate GSeisPalettePrivate;struct _GSeisPalettePrivate { guint32 lookup_table_size; GLushort *red_lookup_table; GLushort *green_lookup_table; GLushort *blue_lookup_table; GLubyte *color_table; GdkPixbuf *color_scale; guint color_scale_width; guint color_scale_height; gchar *name; GSeisColor min_color; GSeisColor max_color; gboolean min_color_is_set; gboolean max_color_is_set;};GdkPixbuf* g_seis_palette_get_color_scale (GSeisPalette *self) { GSeisPalettePrivate *private = G_SEIS_PALETTE_GET_PRIVATE (self); guint i; GdkPixmap *color_pixmap; GdkColormap *colormap; GdkGC *gc; GdkColor color; if (private->color_scale) return private->color_scale; colormap = gdk_colormap_get_system (); color_pixmap = gdk_pixmap_new (NULL, private->color_scale_width, private->color_scale_height, gdk_visual_get_best_depth ()); gdk_drawable_set_colormap (GDK_DRAWABLE (color_pixmap), colormap); gc = gdk_gc_new (GDK_DRAWABLE (color_pixmap)); gdk_gc_set_colormap (gc, gdk_drawable_get_colormap (GDK_DRAWABLE (color_pixmap))); color.red = 0; color.green = 0; color.blue = 0; color.pixel = 0; gdk_colormap_alloc_color (colormap, &color, FALSE, TRUE); gdk_gc_set_foreground (gc, &color); gdk_draw_rectangle (GDK_DRAWABLE (color_pixmap), gc, FALSE, 0, 0, private->color_scale_width - 1, private->color_scale_height - 1); for (i = 0; i < private->lookup_table_size; i++) { color.red = private->red_lookup_table[i]; color.green = private->green_lookup_table[i]; color.blue = private->blue_lookup_table[i]; gdk_colormap_alloc_color (colormap, &color, FALSE, TRUE); gdk_gc_set_foreground (gc, &color); gdk_draw_line (GDK_DRAWABLE (color_pixmap), gc, i + 1, 1, i + 1, private->color_scale_height - 2); } private->color_scale = gdk_pixbuf_get_from_drawable (NULL, color_pixmap, NULL, 0, 0, 0, 0, private->color_scale_width, private->color_scale_height); gdk_pixmap_unref (color_pixmap); gdk_gc_unref (gc); return private->color_scale;}static void g_seis_palette_calculate_color_table (GSeisPalette *self) { GSeisPalettePrivate *private = G_SEIS_PALETTE_GET_PRIVATE (self); guint i, j; for (i = 0; i < private->lookup_table_size; i++) { j = i * 3; private->color_table[j] = private->red_lookup_table[i] / (G_MAXUINT8 + 1); private->color_table[j + 1] = private->green_lookup_table[i] / (G_MAXUINT8 + 1); private->color_table[j + 2] = private->blue_lookup_table[i] / (G_MAXUINT8 + 1); }}static void g_seis_palette_init_by_min_max (GSeisPalette *self, GSeisColor *min_color, GSeisColor *max_color) { GSeisPalettePrivate *private = G_SEIS_PALETTE_GET_PRIVATE (self); gfloat red_color_step, green_color_step, blue_color_step; guint i; red_color_step = (max_color->red - min_color->red) / (gfloat)(private->lookup_table_size - 1); green_color_step = (max_color->green - min_color->green) / (gfloat)(private->lookup_table_size - 1); blue_color_step = (max_color->blue - min_color->blue) / (gfloat)(private->lookup_table_size - 1); /* Fill the whole palette from min_color to max_color with linear interpolation */ for (i = 0; i < private->lookup_table_size; i++) { private->red_lookup_table[i] = (GLushort)(min_color->red + i * red_color_step + 0.5); private->green_lookup_table[i] = (GLushort)(min_color->green + i * green_color_step + 0.5); private->blue_lookup_table[i] = (GLushort)(min_color->blue + i * blue_color_step + 0.5); } g_seis_palette_calculate_color_table (self);}GSeisPalette* g_seis_palette_new_by_min_max (GSeisColor *min_color, GSeisColor *max_color, const gchar *name) { GSeisPalette *g_seis_palette = G_SEIS_PALETTE (g_object_new (G_SEIS_TYPE_PALETTE, "min_color", min_color, "max_color", max_color, "name", name, NULL)); return g_seis_palette;}static void g_seis_palette_init_by_array (GSeisPalette *self, GArray *seis_palette_def) { GSeisPalettePrivate *private = G_SEIS_PALETTE_GET_PRIVATE (self); GSeisColor min_color, max_color; GSeisPaletteDef *min_def, *max_def; gfloat red_color_step, green_color_step, blue_color_step; guint i = 0, j, start_index, end_index; if (NULL != seis_palette_def && 0 != seis_palette_def->len) min_def = &(g_array_index (seis_palette_def, GSeisPaletteDef, 0)); /* Fill the whole palette step by step */ while (NULL != seis_palette_def && i < seis_palette_def->len - 1) { max_def = &(g_array_index (seis_palette_def, GSeisPaletteDef, i + 1)); /* If the first color is not in the beginnig - fill the first palette samples with it */ if (0 == i && min_def->scale_position != 0.f) { start_index = 0; end_index = (private->lookup_table_size - 1) * min_def->scale_position; for (j = start_index; j <= end_index; j++) { private->red_lookup_table[j] = (GLushort)min_def->color.red; private->green_lookup_table[j] = (GLushort)min_def->color.green; private->blue_lookup_table[j] = (GLushort)min_def->color.blue; } } start_index = (private->lookup_table_size - 1) * min_def->scale_position; end_index = (private->lookup_table_size - 1) * max_def->scale_position; if (min_def->interpolate) { /* Linear interpolation from current color to the next */ red_color_step = (max_def->color.red - min_def->color.red) / (gfloat)(end_index - start_index); green_color_step = (max_def->color.green - min_def->color.green) / (gfloat)(end_index - start_index); blue_color_step = (max_def->color.blue - min_def->color.blue) / (gfloat)(end_index - start_index); } else { /* Simply propagate the color forward without interpolation */ red_color_step = 0; green_color_step = 0; blue_color_step = 0; } for (j = start_index; j <= end_index; j++) { private->red_lookup_table[j] = (GLushort)(min_def->color.red + (j - start_index) * red_color_step + 0.5); private->green_lookup_table[j] = (GLushort)(min_def->color.green + (j - start_index) * green_color_step + 0.5); private->blue_lookup_table[j] = (GLushort)(min_def->color.blue + (j - start_index) * blue_color_step + 0.5); } /* If the last color is not in the end - fill the last palette samples with it */ if (i == (seis_palette_def->len - 2) && max_def->scale_position != 1.f) { start_index = (private->lookup_table_size - 1) * max_def->scale_position; end_index = private->lookup_table_size - 1; for (j = start_index; j <= end_index; j++) { private->red_lookup_table[j] = (GLushort)max_def->color.red; private->green_lookup_table[j] = (GLushort)max_def->color.green; private->blue_lookup_table[j] = (GLushort)max_def->color.blue; } } min_def = max_def; i++; } if (NULL == seis_palette_def || 0 == seis_palette_def->len) { /* Nothing is passed here - produce default monochrome palette */ min_color.red = 0; min_color.green = 0; min_color.blue = 0; max_color.red = G_MAXUINT16; max_color.green = G_MAXUINT16; max_color.blue = G_MAXUINT16; start_index = 0; end_index = private->lookup_table_size - 1; red_color_step = (max_color.red - min_color.red) / (gfloat)(private->lookup_table_size - 1); green_color_step = (max_color.green - min_color.green) / (gfloat)(private->lookup_table_size - 1); blue_color_step = (max_color.blue - min_color.blue) / (gfloat)(private->lookup_table_size - 1); for (j = start_index; j <= end_index; j++) { private->red_lookup_table[j] = (GLushort)(min_color.red + j * red_color_step + 0.5); private->green_lookup_table[j] = (GLushort)(min_color.green + j * green_color_step + 0.5); private->blue_lookup_table[j] = (GLushort)(min_color.blue + j * blue_color_step + 0.5); } } else if (1 == seis_palette_def->len) { /* Only one color is specified - interpolate black->color specified->white */ min_color.red = 0; min_color.green = 0; min_color.blue = 0; max_color.red = min_def->color.red; max_color.green = min_def->color.green; max_color.blue = min_def->color.blue; start_index = 0; end_index = (private->lookup_table_size - 1) * min_def->scale_position; red_color_step = (max_color.red - min_color.red) / (gfloat)(private->lookup_table_size - 1); green_color_step = (max_color.green - min_color.green) / (gfloat)(private->lookup_table_size - 1); blue_color_step = (max_color.blue - min_color.blue) / (gfloat)(private->lookup_table_size - 1); for (j = start_index; j <= end_index; j++) { private->red_lookup_table[j] = (GLushort)(min_color.red + j * red_color_step + 0.5); private->green_lookup_table[j] = (GLushort)(min_color.green + j * green_color_step + 0.5); private->blue_lookup_table[j] = (GLushort)(min_color.blue + j * blue_color_step + 0.5); } min_color.red = min_def->color.red; min_color.green = min_def->color.green; min_color.blue = min_def->color.blue; max_color.red = G_MAXUINT16; max_color.green = G_MAXUINT16; max_color.blue = G_MAXUINT16; start_index = (private->lookup_table_size - 1) * min_def->scale_position; start_index = private->lookup_table_size - 1; red_color_step = (max_color.red - min_color.red) / (gfloat)(private->lookup_table_size - 1); green_color_step = (max_color.green - min_color.green) / (gfloat)(private->lookup_table_size - 1); blue_color_step = (max_color.blue - min_color.blue) / (gfloat)(private->lookup_table_size - 1); for (j = start_index; j <= end_index; j++) { private->red_lookup_table[j] = (GLushort)(min_color.red + j * red_color_step + 0.5); private->green_lookup_table[j] = (GLushort)(min_color.green + j * green_color_step + 0.5); private->blue_lookup_table[j] = (GLushort)(min_color.blue + j * blue_color_step + 0.5); } } g_seis_palette_calculate_color_table (self);}GSeisPalette* g_seis_palette_new_by_array (GArray *seis_palette_def, const gchar *name) { GSeisPalette *g_seis_palette = G_SEIS_PALETTE (g_object_new (G_SEIS_TYPE_PALETTE, "colors_array", seis_palette_def, "name", name, NULL)); return g_seis_palette;}void g_seis_palette_apply_pixel_map_lookup_tables (GSeisPalette *self) { GSeisPalettePrivate *private = G_SEIS_PALETTE_GET_PRIVATE (self); glPixelMapusv (GL_PIXEL_MAP_I_TO_R, private->lookup_table_size, private->red_lookup_table); glPixelMapusv (GL_PIXEL_MAP_I_TO_G, private->lookup_table_size, private->green_lookup_table); glPixelMapusv (GL_PIXEL_MAP_I_TO_B, private->lookup_table_size, private->blue_lookup_table);}void g_seis_palette_apply_shared_palette_lookup_tables (GSeisPalette *self, gpointer palette_ext) { GSeisPalettePrivate *private = G_SEIS_PALETTE_GET_PRIVATE (self); ((GdkGL_GL_EXT_paletted_texture*)palette_ext)->glColorTableEXT (GL_SHARED_TEXTURE_PALETTE_EXT, GL_RGB, private->lookup_table_size, GL_RGB, GL_UNSIGNED_BYTE, private->color_table);}void g_seis_palette_generate_fragment_shader_palette_lookup_tables (GSeisPalette *self, guint tex_pal_id) { GSeisPalettePrivate *private = G_SEIS_PALETTE_GET_PRIVATE (self); glTexImage1D (GL_TEXTURE_1D, 0, GL_RGB, private->lookup_table_size, 0, GL_RGB, GL_UNSIGNED_BYTE, private->color_table);}void g_seis_palette_apply_fragment_shader_palette_lookup_tables (GSeisPalette *self, guint tex_pal_id) { GSeisPalettePrivate *private = G_SEIS_PALETTE_GET_PRIVATE (self); glTexSubImage1D (GL_TEXTURE_1D, 0, 0, private->lookup_table_size, GL_RGB, GL_UNSIGNED_BYTE, private->color_table);}const gchar* g_seis_palette_get_name (GSeisPalette *self) { GSeisPalettePrivate *private = G_SEIS_PALETTE_GET_PRIVATE (self); return private->name;}static void g_seis_palette_init (GSeisPalette *self) { GSeisPalettePrivate *private = G_SEIS_PALETTE_GET_PRIVATE (self); private->lookup_table_size = G_MAXUINT8 + 1; private->red_lookup_table = (GLushort*)g_malloc (private->lookup_table_size * (sizeof (GLushort) + sizeof (GLubyte)) * 3); private->green_lookup_table = &private->red_lookup_table[private->lookup_table_size]; private->blue_lookup_table = &private->red_lookup_table[private->lookup_table_size * 2]; private->color_table = (GLubyte*)&private->red_lookup_table[private->lookup_table_size * 3]; private->color_scale = NULL; private->color_scale_width = private->lookup_table_size + 2; private->color_scale_height = 14; private->name = NULL; private->min_color.red = 0; private->min_color.green = 0; private->min_color.blue = 0; private->max_color.red = G_MAXUINT16; private->max_color.green = G_MAXUINT16; private->max_color.blue = G_MAXUINT16; private->min_color_is_set = FALSE; private->max_color_is_set = FALSE;#ifdef DEBUG g_print ("<GSeisPalette is inited>\n");#endif}static void g_seis_palette_finalize (GObject *object) { GSeisPalettePrivate *private = G_SEIS_PALETTE_GET_PRIVATE (G_SEIS_PALETTE (object));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -