?? gsegyfileaccessor.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 <stdio.h>
#ifdef LINUX
#include <sys/types.h>
#include <unistd.h>
#define LSEEK_ERR (off_t)-1
#elif WIN32
#include <io.h>
#define lseek _lseeki64
#define LSEEK_ERR -1L
#endif
#include "gsegyfileaccessor.h"
#include "gsegyfile_marshal.h"
G_DEFINE_TYPE (GSEGYFileAccessor, g_segy_file_accessor, G_TYPE_OBJECT)
#define G_SEGY_FILE_ACCESSOR_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), G_SEGY_TYPE_FILE_ACCESSOR, GSEGYFileAccessorPrivate))
typedef struct _GSEGYFileAccessorPrivate GSEGYFileAccessorPrivate;
struct _GSEGYFileAccessorPrivate {
GSEGYFormatWizard *format_wizard;
GIOChannel *io_channel;
GMutex *file_mutex;
guint8 *ebcdic_header;
guint16 ebcdic_header_size;
guint8 *binary_header;
guint16 binary_header_size;
guint16 trace_header_size;
guint8 sample_id;
guint8 sample_size;
guint16 number_of_samples;
guint16 first_sample_value;
guint16 sample_interval;
GArray *sorting_contents;
guint16 sorting_element_size;
GArray *trace_positions;
guint8 *trace_buffer;
guint32 trace_buffer_size;
guint8 *sorting_data_buffer;
};
static gboolean g_segy_file_accessor_scan_fraction_signal (GSEGYFileAccessor *self, gfloat fraction, GSEGYFileError *file_error) {
gboolean return_value;
g_signal_emit (self, G_SEGY_GET_FILE_ACCESSOR_CLASS (self)->scan_fraction_id, 0, fraction, file_error, &return_value);
return return_value;
}
static gboolean g_segy_file_accessor_initial_read (GSEGYFileAccessor *self, GSEGYFileError *file_error) {
GSEGYFileAccessorPrivate *private = G_SEGY_FILE_ACCESSOR_GET_PRIVATE (self);
gsize bytes_read = 0;
GError *gerror = NULL;
GIOStatus status;
guint16 number_of_samples;
guint64 trace_position, prev_trace_position;
guint64 total_size = 0;
guint64 seek_pos = 0;
gint fd;
gboolean continue_scan = TRUE;
if (0 == private->trace_buffer_size) {
private->trace_buffer_size = (G_MAXINT16 + 1) * sizeof (gfloat);
private->trace_buffer = (guint8*)g_malloc (private->trace_buffer_size);
}
if (file_error) {
file_error->gerror = NULL;
file_error->id = G_SEGY_FILE_NO_ERROR;
}
fd = g_io_channel_unix_get_fd (private->io_channel);
#if defined LINUX || defined WIN32
if (private->file_mutex)
g_mutex_lock (private->file_mutex);
total_size = lseek (fd, 0, SEEK_END);
if (total_size != (guint64)LSEEK_ERR) {
#ifdef DEBUG
g_printf ("File size: %"G_GUINT64_FORMAT"\n", total_size);
#endif
lseek (fd, 0, SEEK_SET);
} else {
#ifdef DEBUG
g_printf ("Impossible to determine file size\n");
total_size = 0;
#endif
}
#endif
#if defined LINUX || defined WIN32
lseek (fd, 0, SEEK_SET);
#else
g_io_channel_seek_position (private->io_channel, 0, G_SEEK_SET, NULL);
g_io_channel_set_encoding (private->io_channel, NULL, NULL);
#endif
if (private->ebcdic_header_size) {
#if defined LINUX || defined WIN32
bytes_read = read (fd, private->ebcdic_header, private->ebcdic_header_size);
if (!bytes_read && bytes_read != private->ebcdic_header_size) {
if (private->file_mutex)
g_mutex_unlock (private->file_mutex);
#else
status = g_io_channel_read_chars (private->io_channel, private->ebcdic_header,
private->ebcdic_header_size, &bytes_read, &gerror);
if (G_IO_STATUS_EOF == status || bytes_read != private->ebcdic_header_size) {
#endif
if (file_error) {
file_error->id = G_SEGY_FILE_PREMATURE_EOF;
file_error->gerror = gerror;
}
return FALSE;
#if defined LINUX || defined WIN32
} else if (bytes_read && bytes_read != private->ebcdic_header_size) {
if (private->file_mutex)
g_mutex_unlock (private->file_mutex);
#else
} else if (status != G_IO_STATUS_NORMAL) {
#endif
if (file_error) {
file_error->id = G_SEGY_FILE_READ_ERROR;
file_error->gerror = gerror;
}
return FALSE;
}
#ifdef DEBUG
g_print ("EBCDIC header read\n");
#endif
g_segy_format_wizard_decode_ebcdic_header (private->format_wizard, private->ebcdic_header, private->ebcdic_header);
private->ebcdic_header[private->ebcdic_header_size] = '\0';
}
if (private->binary_header_size) {
#if defined LINUX || defined WIN32
bytes_read = read (fd, private->binary_header, private->binary_header_size);
if (!bytes_read && bytes_read != private->binary_header_size) {
if (private->file_mutex)
g_mutex_unlock (private->file_mutex);
#else
status = g_io_channel_read_chars (private->io_channel, private->binary_header,
private->binary_header_size, &bytes_read, &gerror);
if (G_IO_STATUS_EOF == status || bytes_read != private->binary_header_size) {
#endif
if (file_error) {
file_error->id = G_SEGY_FILE_PREMATURE_EOF;
file_error->gerror = gerror;
}
g_segy_file_accessor_scan_fraction_signal (self, -1, file_error);
return FALSE;
#if defined LINUX || defined WIN32
} else if (bytes_read && bytes_read != private->binary_header_size) {
if (private->file_mutex)
g_mutex_unlock (private->file_mutex);
#else
} else if (status != G_IO_STATUS_NORMAL) {
#endif
if (file_error) {
file_error->id = G_SEGY_FILE_READ_ERROR;
file_error->gerror = gerror;
}
g_segy_file_accessor_scan_fraction_signal (self, -1, file_error);
return FALSE;
}
#ifdef DEBUG
g_print ("Binary header read\n");
#endif
if (FALSE == g_segy_format_wizard_get_sample_format_id (private->format_wizard, private->binary_header, &private->sample_id, &private->sample_size)) {
if (file_error)
file_error->id = G_SEGY_FILE_UNKNOW_SAMPLE_ID;
g_segy_file_accessor_scan_fraction_signal (self, -1, file_error);
#if defined LINUX || defined WIN32
if (private->file_mutex)
g_mutex_unlock (private->file_mutex);
#endif
return FALSE;
}
#ifdef DEBUG
g_printf ("Sample format ID: %d (%d bytes)\n", private->sample_id, private->sample_size);
#endif
} else
g_segy_format_wizard_get_default_sample_format_id (private->format_wizard, &private->sample_id, &private->sample_size);
if (NULL == private->sorting_data_buffer)
private->sorting_data_buffer = (guint8*)g_malloc (private->sorting_element_size);
trace_position = private->ebcdic_header_size + private->binary_header_size;
prev_trace_position = trace_position;
for (;;) {
#if defined LINUX || defined WIN32
bytes_read = read (fd, private->trace_buffer, private->trace_header_size);
if (bytes_read != private->trace_header_size) {
if (private->file_mutex)
g_mutex_unlock (private->file_mutex);
if (file_error && bytes_read != 0) {
file_error->id = G_SEGY_FILE_PREMATURE_EOF;
#else
status = g_io_channel_read_chars (private->io_channel, private->trace_buffer, private->trace_header_size,
&bytes_read, &file_error->gerror);
if (status != G_IO_STATUS_NORMAL || bytes_read != private->trace_header_size) {
if (file_error && (status != G_IO_STATUS_EOF || bytes_read != 0)) {
if (status == G_IO_STATUS_EOF && bytes_read != 0)
file_error->id = G_SEGY_FILE_PREMATURE_EOF;
else
file_error->id = G_SEGY_FILE_READ_ERROR;
#endif
file_error->gerror = gerror;
g_segy_file_accessor_scan_fraction_signal (self, -1, file_error);
}
break;
}
g_segy_format_wizard_get_number_of_samples (private->format_wizard, private->trace_buffer, &number_of_samples);
if (0 == private->trace_positions->len) {
g_segy_format_wizard_get_first_sample_value (private->format_wizard, private->trace_buffer,
&private->first_sample_value);
g_segy_format_wizard_get_sample_interval (private->format_wizard, private->trace_buffer,
&private->sample_interval);
if (number_of_samples > 0 && number_of_samples <= G_MAXINT16)
private->number_of_samples = number_of_samples;
else if (private->binary_header_size) {
g_segy_format_wizard_get_number_of_samples_from_bin (private->format_wizard,
private->binary_header,
&private->number_of_samples);
number_of_samples = private->number_of_samples;
}
if (0 == private->number_of_samples) {
if (file_error)
file_error->id = G_SEGY_FILE_ZERO_NUMBER_OF_SAMPLES;
g_segy_file_accessor_scan_fraction_signal (self, -1, file_error);
#if defined LINUX || defined WIN32
if (private->file_mutex)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -