Commit 89b25397 authored by Marina Nikolova's avatar Marina Nikolova
Browse files

Upload New File

parent debefc67
/***
The MIT License (MIT)
Copyright (c) 2019 Marina Nikolova, EMBL
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
***/
#include <stdio.h>
#include <string>
#include <cstring>
#include <zlib.h>
#include "cbf.h"
#include "xds_zcbf_defs.h"
#include "xds_zcbf_plugin.h"
typedef struct {
std::string file_name; // dir + part of file name that doesn't change;
std::string gz_extension; // gzipped file extension: .gz, .z
int digit_count; // number of file_name digits for the frame number;
int header_frame; // frame to be used for extraction of header info;
} zcbf_data;
static zcbf_data *data_cache = NULL;
static void set_info(int info[1024]);
static std::string frame_name(int frame_number);
static int read_gz(int frame_number, size_t &size, void *buf);
static int read_cbf(size_t &size, void *in_buf, int *out_buf);
#ifdef __cplusplus
extern "C" {
#endif
// input: file_name of the form /dir/subdir/.../file_name_00001.cbf.gz with a varying 0-count, and first image number;
void plugin_open(const char *file_name, int info[1024], int *error)
{
std::size_t found, found_ext;
*error = 0;
data_cache = new zcbf_data;
data_cache->file_name.assign(file_name);
if ((found = data_cache->file_name.find_last_of("_")) != std::string::npos)
{
if ((found_ext = data_cache->file_name.find(".cbf")) == std::string::npos)
*error = -4;
else
{
data_cache->digit_count = found_ext - found - 1;
data_cache->gz_extension = data_cache->file_name.substr(found_ext + 4);
data_cache->file_name.erase(found_ext);
data_cache->header_frame = strtol(data_cache->file_name.substr(found + 1, found_ext).c_str(), NULL, 10);
if (data_cache->header_frame == 0)
*error = -4;
else
data_cache->file_name.erase(found + 1);
}
}
set_info(info);
fprintf(OUTPUT_INFO, "\n XDS zlib-cbf plugin %d.%d.%d (EMBL-HH, 2019)\n", info[1], info[2], info[3]);
#ifdef DEBUG_MSG_ENABLED
fprintf(OUTPUT_INFO, " plugin_open: %s\n", file_name);
#endif
}
// read in the file_name indicated above and populate pixel_count_x/y;
// the remaining parameters seem to be not needed as they are read from XDS.INP;
void plugin_get_header(int *pixel_count_x, int *pixel_count_y,
int *, float *, float *, int *, int *, int *error)
{
void *buf;
size_t size = 32 * 1024 * 1024;
int pixel_count[2];
*error = 0;
if (posix_memalign(&buf, HUGE_MEM_ALIGNMENT, size) != 0)
buf = malloc(size);
if (buf == NULL)
{
#ifdef DEBUG_MSG_ENABLED
fprintf(OUTPUT_ERROR, " plugin_get_header: unable to allocate memory\n");
#endif
*error = -1;
return;
}
if ((*error = read_gz(data_cache->header_frame, size, buf)) != 0)
{
#ifdef DEBUG_MSG_ENABLED
fprintf(OUTPUT_ERROR, " plugin_get_header: unable to unzip %s\n",
frame_name(data_cache->header_frame).c_str());
#endif
free(buf);
return;
}
pixel_count[0] = PLUGIN_HEADER;
*error = read_cbf(size, buf, pixel_count);
*pixel_count_x = pixel_count[0];
*pixel_count_y = pixel_count[1];
#ifdef DEBUG_MSG_ENABLED
fprintf(OUTPUT_INFO, " plugin_get_header: pixel count x, y: %d, %d\n", *pixel_count_x, *pixel_count_y);
#endif
free(buf);
}
// unzip file with requested frame_number, and populate data with the unzipped, uncbfed raw stream;
void plugin_get_data(int *frame_number, int *, int *,
int *data, int *, int *error)
{
void *buf;
size_t size = 24 * 1024 * 1024;
*error = 0;
#ifdef DEBUG_MSG_ENABLED
fprintf(OUTPUT_INFO, " plugin_get_data: frame # %d\n", *frame_number);
#endif
if (posix_memalign(&buf, HUGE_MEM_ALIGNMENT, size) != 0)
buf = malloc(size);
if (buf == NULL)
{
#ifdef DEBUG_MSG_ENABLED
fprintf(OUTPUT_ERROR, " plugin_get_data: unable to allocate memory\n");
#endif
*error = -1;
return;
}
if ((*error = read_gz(*frame_number, size, buf)) != 0)
{
#ifdef DEBUG_MSG_ENABLED
fprintf(OUTPUT_ERROR, " plugin_get_data: unable to unzip %s\n", frame_name(*frame_number).c_str());
#endif
free(buf);
return;
}
data[0] = PLUGIN_DATA;
*error = read_cbf(size, buf, data);
free(buf);
}
// release the memory for the data cache created in plugin_open;
void plugin_close(int *error)
{
*error = 0;
if (data_cache)
{
delete data_cache;
data_cache = NULL;
}
}
#ifdef __cplusplus
} // extern "C"
#endif
static void set_info(int info[1024])
{
info[0] = CUSTOMER_ID; // Customer ID
info[1] = VERSION_MAJOR; // Version [Major]
info[2] = VERSION_MINOR; // Version [Minor]
info[3] = VERSION_PATCH; // Version [Patch]
info[4] = VERSION_TIMESTAMP; // Version [timestamp]
}
static std::string frame_name(int frame_number)
{
char temp[data_cache->file_name.length() + 64];
char name[data_cache->file_name.length() + 64];
sprintf(temp, "%s%%0%dd.cbf%s",
data_cache->file_name.c_str(), data_cache->digit_count, data_cache->gz_extension.c_str());
sprintf(name, temp, frame_number);
#ifdef DEBUG_MSG_ENABLED
fprintf(OUTPUT_INFO, " file name: %s\n", name);
#endif
return name;
}
static int read_gz(int frame_number, size_t &size, void *buf)
{
gzFile file;
size_t bytes_read;
int data_size;
data_size = 0;
file = gzopen(frame_name(frame_number).c_str(), "rb");
if (file == NULL)
return -2;
gzbuffer(file, 128 * 1024);
while (1)
{
bytes_read = gzread(file, (char*) buf + data_size, size);
data_size += bytes_read;
if (bytes_read < size)
{
if (gzeof(file))
break;
else
{
gzclose(file);
return -2;
}
} else {
// with realloc we lose our nice memory alignment;
buf = realloc(buf, data_size);
if (buf == NULL)
{
gzclose(file);
return -2;
}
}
}
size = data_size;
gzclose(file);
return 0;
}
static int read_cbf(size_t &size, void *in_buf, int *out_buf)
{
FILE *file;
cbf_handle cbf;
unsigned int compression;
int id, el_min, el_max, el_signed, el_unsigned;
size_t pixel_size, pixel_count, pixel_count_x, pixel_count_y, pixel_count_z, padding;
const char *byte_order;
file = fmemopen(in_buf, size, "rb");
if (file == NULL)
{
#ifdef DEBUG_MSG_ENABLED
fprintf(OUTPUT_ERROR, " %s, unable to open memory stream\n",
(out_buf[0] == PLUGIN_HEADER) ? "plugin_get_header" : "plugin_get_data");
#endif
return -2;
}
if (cbf_make_handle(&cbf))
{
#ifdef DEBUG_MSG_ENABLED
fprintf(OUTPUT_ERROR, " %s, unable to make cbf file handle\n",
(out_buf[0] == PLUGIN_HEADER) ? "plugin_get_header" : "plugin_get_data");
#endif
return -2;
}
/* CBFlib will call fclose(file) when it's ready */
if (cbf_read_file(cbf, file, 0))
{
cbf_free_handle(cbf);
#ifdef DEBUG_MSG_ENABLED
fprintf(OUTPUT_ERROR, " %s, unable to read cbf file\n",
(out_buf[0] == PLUGIN_HEADER) ? "plugin_get_header" : "plugin_get_data");
#endif
return -4;
}
cbf_find_category(cbf, "array_data");
cbf_find_column(cbf, "data");
cbf_select_row(cbf, 0);
if (cbf_get_integerarrayparameters_wdims(cbf, &compression, &id,
&pixel_size, &el_signed, &el_unsigned,
&pixel_count, &el_min, &el_max, &byte_order,
&pixel_count_x, &pixel_count_y, &pixel_count_z,
&padding) != 0)
{
cbf_free_handle(cbf);
#ifdef DEBUG_MSG_ENABLED
fprintf(OUTPUT_ERROR, " %s, unable to get cbf integerarrayparameters_wdims\n",
(out_buf[0] == PLUGIN_HEADER) ? "plugin_get_header" : "plugin_get_data");
#endif
return -4;
}
if (out_buf[0] == PLUGIN_DATA)
{
// XDS expects back an array of 4-byte ints; thus force cbflib to make one;
if (cbf_get_integerarray(cbf, &id, out_buf, 4, 1, pixel_count, &pixel_count) != 0)
{
cbf_free_handle(cbf);
#ifdef DEBUG_MSG_ENABLED
fprintf(OUTPUT_ERROR, " plugin_get_data, unable to get cbf integerarray\n");
#endif
return -4;
}
} else if (out_buf[0] == PLUGIN_HEADER)
{
out_buf[0] = pixel_count_x;
out_buf[1] = pixel_count_y;
}
cbf_free_handle(cbf);
return 0;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment