?? gsegyseismicaccessor.c
字號:
/*
* GSEGYLIB - Library for accessing files in SEG-Y format
*
* Copyright (C) 2005-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 "gsegyseismicaccessor.h"
G_DEFINE_TYPE (GSEGYSeismicAccessor, g_segy_seismic_accessor, G_TYPE_OBJECT)
#define G_SEGY_SEISMIC_ACCESSOR_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), G_SEGY_TYPE_SEISMIC_ACCESSOR, GSEGYSeismicAccessorPrivate))
typedef struct _GSEGYSeismicAccessorPrivate GSEGYSeismicAccessorPrivate;
struct _GSEGYSeismicAccessorPrivate {
GSEGYFileAccessor *file_accessor;
guint8 *trace_header_buffer;
gint16 first_sort_level_id;
gint16 second_sort_level_id;
gboolean first_level_ascending;
gboolean second_level_ascending;
GArray *first_sort_level;
GArray *second_sort_level;
};
typedef struct _GSEGYSeismicAccessorDataForSorting GSEGYSeismicAccessorDataForSorting;
struct _GSEGYSeismicAccessorDataForSorting {
GArray *sorting_contents;
guint16 sorting_desc_size;
GCompareDataFunc first_level_compare;
GCompareDataFunc second_level_compare;
guint16 first_level_offset;
guint16 second_level_offset;
};
static gint g_segy_seismic_accessor_trace_compare (gconstpointer a, gconstpointer b, gpointer user_data) {
GSEGYSeismicAccessorDataForSorting *data_for_sorting = (GSEGYSeismicAccessorDataForSorting*)user_data;
guint8 *trace_a = &g_array_index (data_for_sorting->sorting_contents, guint8, *(guint32*)a * data_for_sorting->sorting_desc_size);
guint8 *trace_b = &g_array_index (data_for_sorting->sorting_contents, guint8, *(guint32*)b * data_for_sorting->sorting_desc_size);
gpointer data_for_second_level[4];
if (data_for_sorting->second_level_compare) {
data_for_second_level[0] = (gpointer)data_for_sorting->second_level_compare;
data_for_second_level[1] = (gpointer)&trace_a[data_for_sorting->second_level_offset];
data_for_second_level[2] = (gpointer)&trace_b[data_for_sorting->second_level_offset];
data_for_second_level[3] = NULL;
return (data_for_sorting->first_level_compare) ((gconstpointer)&trace_a[data_for_sorting->first_level_offset],
(gconstpointer)&trace_b[data_for_sorting->first_level_offset],
(gpointer)data_for_second_level);
} else
return (data_for_sorting->first_level_compare) ((gconstpointer)&trace_a[data_for_sorting->first_level_offset],
(gconstpointer)&trace_b[data_for_sorting->first_level_offset],
NULL);
}
static void g_segy_seismic_accessor_sort_traces (GSEGYSeismicAccessor *self) {
GSEGYSeismicAccessorPrivate *private = G_SEGY_SEISMIC_ACCESSOR_GET_PRIVATE (self);
GSEGYSeismicAccessorDataForSorting data_for_sorting;
guint32 i, number_of_traces;
guint8 *prev_trace;
guint8 *curr_trace;
data_for_sorting.sorting_contents = g_segy_file_accessor_get_sorting_contents (private->file_accessor);
data_for_sorting.sorting_desc_size = g_segy_file_accessor_get_sorting_desc_size (private->file_accessor);
data_for_sorting.first_level_compare = g_segy_file_accessor_get_compare_func_for_sorting_id (private->file_accessor, private->first_sort_level_id,
private->first_level_ascending,
&(data_for_sorting.first_level_offset));
data_for_sorting.second_level_compare = g_segy_file_accessor_get_compare_func_for_sorting_id (private->file_accessor, private->second_sort_level_id,
private->second_level_ascending,
&(data_for_sorting.second_level_offset));
if (NULL == data_for_sorting.first_level_compare) {
i = 0;
g_array_append_val (private->first_sort_level, i);
return;
}
g_array_sort_with_data (private->second_sort_level, g_segy_seismic_accessor_trace_compare, (gpointer)(&data_for_sorting));
number_of_traces = private->second_sort_level->len;
i = 0;
g_array_append_val (private->first_sort_level, i);
if (data_for_sorting.second_level_compare) {
prev_trace = &((&g_array_index (data_for_sorting.sorting_contents, guint8, data_for_sorting.sorting_desc_size *
g_array_index (private->second_sort_level, guint32, i)))[data_for_sorting.first_level_offset]);
for (i = 1; i < number_of_traces; i++) {
curr_trace = &((&g_array_index (data_for_sorting.sorting_contents, guint8, data_for_sorting.sorting_desc_size *
g_array_index (private->second_sort_level, guint32, i)))[data_for_sorting.first_level_offset]);
if (0 != (data_for_sorting.first_level_compare)((gconstpointer)prev_trace, (gconstpointer)curr_trace, NULL))
g_array_append_val (private->first_sort_level, i);
prev_trace = curr_trace;
}
}
#ifdef DEBUG
g_print ("Sorting completed\n");
g_print ("First sorting level number: %" G_GINT32_FORMAT "\n", private->first_sort_level->len);
g_print ("Second sorting level number: %" G_GINT32_FORMAT "\n", private->second_sort_level->len);
#endif
}
GSEGYSeismicAccessor* g_segy_seismic_accessor_new (GSEGYFileAccessor *file_accessor) {
return G_SEGY_SEISMIC_ACCESSOR (g_object_new (G_SEGY_TYPE_SEISMIC_ACCESSOR, "file_accessor", file_accessor, NULL));
}
void g_segy_seismic_accessor_sort (GSEGYSeismicAccessor *self,
gint16 first_sort_level_id, gint16 second_sort_level_id,
gboolean first_level_ascending, gboolean second_level_ascending) {
GSEGYSeismicAccessorPrivate *private = G_SEGY_SEISMIC_ACCESSOR_GET_PRIVATE (self);
guint32 i, number_of_traces;
number_of_traces = g_segy_file_accessor_get_number_of_traces (private->file_accessor);
if (private->second_sort_level)
g_array_free (private->second_sort_level, TRUE);
private->second_sort_level = g_array_sized_new (FALSE, FALSE, sizeof (guint32), number_of_traces);
for (i = 0; i < number_of_traces; i++)
g_array_insert_val (private->second_sort_level, i, i);
if (private->first_sort_level)
g_array_free (private->first_sort_level, TRUE);
private->first_sort_level = g_array_new (FALSE, FALSE, sizeof (guint32));
private->first_sort_level_id = first_sort_level_id;
private->second_sort_level_id = second_sort_level_id;
private->first_level_ascending = first_level_ascending;
private->second_level_ascending = second_level_ascending;
#ifdef DEBUG
g_print ("First sorting level id: %" G_GUINT16_FORMAT "\n", (guint16)first_sort_level_id);
g_print ("Second sorting level id: %" G_GUINT16_FORMAT "\n", (guint16)second_sort_level_id);
#endif
g_segy_seismic_accessor_sort_traces (self);
}
void g_segy_seismic_accessor_get_label_for_second_level (GSEGYSeismicAccessor *self, guint16 field_number,
guint32 first_level_index, guint32 second_level_index,
gchar *gbuffer, guint32 buffer_len) {
GSEGYSeismicAccessorPrivate *private = G_SEGY_SEISMIC_ACCESSOR_GET_PRIVATE (self);
if (NULL == gbuffer || 0 == buffer_len || 0 == field_number)
return;
g_segy_format_wizard_get_label_for_sorting_field (g_segy_file_accessor_get_format_wizard (private->file_accessor),
field_number,
g_array_index (private->second_sort_level, guint32,
g_array_index (private->first_sort_level, guint32, first_level_index) +
second_level_index),
g_segy_file_accessor_get_sorting_contents (private->file_accessor),
gbuffer, buffer_len);
}
void g_segy_seismic_accessor_get_labels_for_first_level (GSEGYSeismicAccessor *self,
GStringChunk **chunk, GPtrArray **labels) {
GSEGYSeismicAccessorPrivate *private = G_SEGY_SEISMIC_ACCESSOR_GET_PRIVATE (self);
guint i;
*chunk = NULL;
*labels = NULL;
if (NULL == chunk || NULL == labels || NULL == private->second_sort_level || NULL == private->first_sort_level ||
0 == private->first_sort_level_id || 1 >= private->first_sort_level->len)
return;
guint32 number_of_traces = private->first_sort_level->len;
GArray *traces_indices = g_array_sized_new (FALSE, FALSE, sizeof (guint32), number_of_traces);
for (i = 0; i < number_of_traces; i++)
g_array_append_val (traces_indices, g_array_index (private->second_sort_level, guint32,
g_array_index (private->first_sort_level, guint32, i)));
g_segy_format_wizard_get_labels_for_sorting_field (g_segy_file_accessor_get_format_wizard (private->file_accessor),
private->first_sort_level_id, traces_indices,
g_segy_file_accessor_get_sorting_contents (private->file_accessor),
chunk, labels);
g_array_free (traces_indices, TRUE);
}
void g_segy_seismic_accessor_get_labels_for_second_level (GSEGYSeismicAccessor *self,
guint32 first_level_index, gint16 second_level_id,
GStringChunk **chunk, GPtrArray **labels) {
GSEGYSeismicAccessorPrivate *private = G_SEGY_SEISMIC_ACCESSOR_GET_PRIVATE (self);
guint i;
*chunk = NULL;
*labels = NULL;
if (NULL == chunk || NULL == labels || NULL == private->second_sort_level || NULL == private->first_sort_level ||
0 == private->first_sort_level_id || first_level_index >= private->first_sort_level->len)
return;
guint32 second_level_start = g_array_index (private->first_sort_level, guint32, first_level_index);
guint32 second_level_end = first_level_index == (private->first_sort_level->len - 1)
? private->second_sort_level->len
: g_array_index (private->first_sort_level, guint32, first_level_index + 1);
guint32 number_of_traces = second_level_end - second_level_start;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -