Writing images, split and flip work

This commit is contained in:
Sebastian 2018-01-02 19:00:53 +01:00 committed by Sebastian
parent 234a6cd676
commit d15bf778e3
2 changed files with 125 additions and 326 deletions

View File

@ -50,234 +50,105 @@ namespace gr
gr::sync_block ("noaa_apt_sink",
gr::io_signature::make (1, 1, sizeof(float)),
gr::io_signature::make (0, 0, 0)),
d_sync_word (0x0ccccccc),
d_constructed_word (0),
d_slicer_threshold (0.5),
d_sync_found (false),
d_norm_window (2048),
d_sample_counter (0),
d_filename_png (filename_png),
d_width (width),
d_height (height),
d_split (split),
d_history_length (28),
d_synchronize_opt (sync),
d_row_counter (0),
d_flip (flip),
d_history_length (40),
d_current_x (0),
d_current_y (0),
d_num_images (0),
d_current_buffered_samples (0),
d_flip (flip)
f_max_level(0.0),
f_min_level(1.0)
{
set_history (d_history_length);
if (sync) {
d_max_value = -1;
d_min_value = 100;
}
else {
d_max_value = 1;
d_min_value = 0;
}
d_color_type = PNG_COLOR_TYPE_GRAY;
d_bit_depth = 8;
d_row_buffer = new uint8_t[d_width];
if (d_split) {
d_png_fn.push_back (std::string (""));
d_png_fn.push_back (std::string (""));
}
else {
d_png_fn.push_back (std::string (""));
}
init_png ();
set_history(d_history_length);
init_images();
}
void
noaa_apt_sink_impl::init_png ()
{
std::string fn (d_filename_png);
if (d_split) {
d_images_per_frame = 2;
d_png_fd = new FILE*[2];
d_png_ptr = new png_structp[2];
d_info_ptr = new png_infop[2];
std::string fn_left = fn;
std::string fn_right = fn;
if (d_num_images == 0) {
fn_left.append ("_left");
fn_right.append ("_right");
noaa_apt_sink_impl::init_images () {
size_t len = d_filename_png.size();
size_t pos = d_filename_png.rfind('.');
std::string base_filename = d_filename_png.substr(0, pos);
std::string extension = d_filename_png.substr(pos+1, len-1);
d_full_filename = base_filename + std::to_string(d_num_images) + "." + extension;
d_full_image = png::image<png::gray_pixel>(d_width, d_height);
if(d_split) {
d_left_filename = base_filename + "_left" + std::to_string(d_num_images) + "." + extension;
d_right_filename = base_filename + "_right" + std::to_string(d_num_images)+ "." + extension;
d_left_image = png::image<png::gray_pixel>(d_width/2, d_height);
d_right_image = png::image<png::gray_pixel>(d_width/2, d_height);
}
}
void
noaa_apt_sink_impl::write_image (png::image<png::gray_pixel> image, std::string filename) {
if(d_flip) {
size_t width = image.get_width();
size_t height = image.get_height();
png::image<png::gray_pixel> flipped(width, height);
for(size_t y = 0; y < height; y++) {
for(size_t x = 0; x < width; x++) {
auto pixel = image.get_pixel(x, height - y - 1);
flipped.set_pixel(x, y, pixel);
}
}
flipped.write(filename);
}
else {
fn_left.append (std::to_string (d_num_images).append ("_left"));
fn_right.append (std::to_string (d_num_images).append ("_right"));
image.write(filename);
}
d_png_fn[0] = fn_left;
d_png_fn[1] = fn_right;
d_png_fd[0] = fopen (fn_right.c_str (), "wb");
d_png_fd[1] = fopen (fn_left.c_str (), "wb");
for (size_t i = 0; i < d_images_per_frame; i++) {
d_png_ptr[i] = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL,
NULL,
NULL);
d_info_ptr[i] = png_create_info_struct (d_png_ptr[i]);
png_init_io (d_png_ptr[i], d_png_fd[i]);
png_set_IHDR (d_png_ptr[i], d_info_ptr[i], d_width / 2, d_height,
d_bit_depth, d_color_type,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE,
PNG_FILTER_TYPE_BASE);
png_write_info (d_png_ptr[i], d_info_ptr[i]);
}
}
else {
d_images_per_frame = 1;
d_png_fd = new FILE*[1];
d_png_ptr = new png_structp[2];
d_info_ptr = new png_infop[2];
if (d_num_images == 0) {
d_png_fd[0] = fopen (fn.c_str (), "wb");
d_png_fn[0] = fn;
}
else {
fn.append (std::to_string (d_num_images));
d_png_fd[0] = fopen (fn.c_str (), "wb");
d_png_fn[0] = fn;
}
d_png_ptr[0] = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL,
NULL,
NULL);
d_info_ptr[0] = png_create_info_struct (d_png_ptr[0]);
png_init_io (d_png_ptr[0], d_png_fd[0]);
png_set_IHDR (d_png_ptr[0], d_info_ptr[0], d_width, d_height,
d_bit_depth, d_color_type,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE,
PNG_FILTER_TYPE_BASE);
png_write_info (d_png_ptr[0], d_info_ptr[0]);
}
}
void
noaa_apt_sink_impl::write_png_row ()
{
if (d_row_counter == d_height) {
for (size_t i = 0; i < d_images_per_frame; i++) {
png_write_end (d_png_ptr[i], NULL);
fclose (d_png_fd[i]);
}
if (d_flip) {
flip_image ();
}
d_row_counter = 0;
d_num_images++;
init_png ();
}
if (d_split) {
for (size_t i = 0; i < d_images_per_frame; i++) {
png_write_row (d_png_ptr[i], d_row_buffer + i * d_width / 2);
}
}
else {
png_write_row (d_png_ptr[0], d_row_buffer);
}
d_row_counter++;
}
noaa_apt_sink_impl::~noaa_apt_sink_impl ()
{
if (d_current_buffered_samples < d_width) {
memset (d_row_buffer + d_current_buffered_samples, 0,
(d_width - d_current_buffered_samples) * sizeof(uint8_t));
}
write_png_row ();
if (d_row_counter < d_height) {
size_t row_count = d_row_counter;
for (size_t i = 0; i < d_height - row_count; i++) {
memset (d_row_buffer, 0, d_width * sizeof(uint8_t));
write_png_row ();
}
}
noaa_apt_sink_impl::write_images () {
write_image(d_full_image, d_full_filename);
for (size_t i = 0; i < d_images_per_frame; i++) {
png_write_end (d_png_ptr[i], NULL);
fclose (d_png_fd[i]);
}
if (d_flip) {
flip_image ();
}
delete[] d_row_buffer;
delete[] d_png_fd;
delete[] d_png_ptr;
delete[] d_info_ptr;
if(d_split) {
write_image(d_left_image, d_left_filename);
write_image(d_right_image, d_right_filename);
}
}
void
noaa_apt_sink_impl::flip_image ()
{
int height;
png_byte color_type;
png_byte bit_depth;
png_structp png_ptr;
png_infop info_ptr;
int number_of_passes;
png_bytep* row_pointers;
size_t width;
if (d_split) {
width = d_width / 2;
}
else {
width = d_width;
}
for (size_t i = 0; i < d_images_per_frame; i++) {
char header[8]; // 8 is the maximum size that can be checked
d_png_fd[i] = fopen (d_png_fn[i].c_str (), "rb");
fread (header, 1, 8, d_png_fd[i]);
noaa_apt_sink_impl::~noaa_apt_sink_impl () {
write_images();
}
/* initialize stuff */
png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL,
NULL);
void noaa_apt_sink_impl::end_line () {
d_current_y += 1;
d_current_x = 0;
info_ptr = png_create_info_struct (png_ptr);
png_init_io (png_ptr, d_png_fd[i]);
png_set_sig_bytes (png_ptr, 8);
png_read_info (png_ptr, info_ptr);
png_read_update_info (png_ptr, info_ptr);
row_pointers = new png_bytep[d_height];
for (size_t y = 0; y < d_height; y++) {
row_pointers[y] = new png_byte[png_get_rowbytes (png_ptr, info_ptr)];
if(d_current_y % 100 == 0) {
write_images();
}
png_read_image (png_ptr, row_pointers);
fclose (d_png_fd[i]);
d_png_fd[i] = fopen (d_png_fn[i].c_str (), "wb");
d_png_ptr[i] = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL,
NULL,
NULL);
d_info_ptr[i] = png_create_info_struct (d_png_ptr[i]);
png_init_io (d_png_ptr[i], d_png_fd[i]);
png_set_IHDR (d_png_ptr[i], d_info_ptr[i], width, d_height, d_bit_depth,
d_color_type,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE,
PNG_FILTER_TYPE_BASE);
png_write_info (d_png_ptr[i], d_info_ptr[i]);
for (int j = d_height - 1; j >= 0; j--) {
uint8_t *istart = row_pointers[j];
uint8_t *iend = istart + width;
std::reverse (row_pointers[j], iend);
png_write_row (d_png_ptr[i], row_pointers[j]);
if(d_current_y >= d_height) {
d_current_y = 0;
d_num_images += 1;
write_images();
init_images();
}
png_write_end (d_png_ptr[i], NULL);
fclose (d_png_fd[i]);
}
for (size_t y = 0; y < d_height; y++) {
delete[] row_pointers[y];
void noaa_apt_sink_impl::set_pixel (float sample) {
sample = (sample - f_min_level) / (f_max_level - f_min_level) * 255;
d_full_image.set_pixel(d_current_x, d_current_y, sample);
if(d_split) {
if(d_current_x < d_width / 2) {
d_left_image.set_pixel(d_current_x, d_current_y, sample);
}
else {
d_right_image.set_pixel(d_current_x - d_width / 2, d_current_y, sample);
}
}
delete[] row_pointers;
}
}
int
@ -285,103 +156,25 @@ namespace gr
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
const float *in = (const float *) input_items[0];
uint8_t b = 0;
float sample;
long int r;
const float *in = (const float *) input_items[0];
for (size_t i = d_history_length - 1;
i < noutput_items + d_history_length - 1; i++) {
if (!d_synchronize_opt) {
sample = 255 * in[i];
r = (long int) rint (sample);
if (r < 0)
r = 0;
else if (r > 255)
r = 255;
d_row_buffer[d_current_buffered_samples] = (uint8_t) r;
d_current_buffered_samples++;
if (d_current_buffered_samples == d_width) {
write_png_row ();
d_current_buffered_samples = 0;
}
for (size_t i = d_history_length - 1; i < noutput_items + d_history_length - 1; i++) {
float sample = in[i];
f_min_level = std::fmin(f_min_level, sample);
f_max_level = std::fmax(f_max_level, sample);
set_pixel(sample);
d_current_x += 1;
if(d_current_x >= d_width) {
end_line();
}
}
else {
if (d_sync_found) {
if (d_sample_counter < d_norm_window) {
if (in[i] < d_min_value) {
d_min_value = in[i];
}
if (in[i] > d_max_value) {
d_max_value = in[i];
}
d_sample_counter++;
}
sample = ((in[i] - d_min_value) / (d_max_value - d_min_value));
sample = 255 * sample;
r = (long int) rint (sample);
if (r < 0) {
r = 0;
}
else if (r > 255) {
r = 255;
}
d_row_buffer[d_current_buffered_samples] = (uint8_t) r;
d_current_buffered_samples++;
if (d_current_buffered_samples == d_width) {
write_png_row ();
d_current_buffered_samples = 0;
}
}
else {
if (d_sample_counter < d_norm_window) {
if (in[i] < d_min_value) {
d_min_value = in[i];
}
if (in[i] > d_max_value) {
d_max_value = in[i];
}
d_sample_counter++;
d_slicer_threshold = (d_max_value + d_min_value)/2.0;
continue;
}
b = in[i] > d_slicer_threshold ? 1 : 0;
d_constructed_word = (d_constructed_word << 1) | b;
if (d_constructed_word == d_sync_word) {
d_sync_found = true;
d_sample_counter =0;
for (size_t j = i - (d_history_length - 1); j <= i; j++) {
if (in[j] < d_min_value) {
d_min_value = in[i];
}
if (in[j] > d_max_value) {
d_max_value = in[j];
}
}
for (size_t j = i - (d_history_length - 1); j <= i; j++) {
sample = ((in[i] - d_min_value) / (d_max_value - d_min_value));
sample = 255 * sample;
r = (long int) rint (sample);
if (r < 0) {
r = 0;
}
else if (r > 255) {
r = 255;
}
d_row_buffer[d_current_buffered_samples] = (uint8_t) r;
d_current_buffered_samples++;
if (d_current_buffered_samples == d_width) {
write_png_row ();
d_current_buffered_samples = 0;
}
}
}
}
}
}
return noutput_items;
return noutput_items;
}
} /* namespace satnogs */
} /* namespace gr */

View File

@ -23,9 +23,11 @@
#include <satnogs/noaa_apt_sink.h>
#define PNG_DEBUG 3
#include <png.h>
#include <png++/png.hpp>
#include <chrono>
namespace gr
{
namespace satnogs
@ -34,52 +36,56 @@ namespace gr
class noaa_apt_sink_impl : public noaa_apt_sink
{
private:
uint32_t d_sync_word;
uint32_t d_constructed_word;
float d_slicer_threshold;
bool d_sync_found;
float d_max_value;
float d_min_value;
size_t d_norm_window;
size_t d_sample_counter;
const char* d_filename_png;
std::string d_filename_png;
size_t d_width;
size_t d_height;
bool d_split;
size_t d_history_length;
bool d_synchronize_opt;
png_structp* d_png_ptr;
png_infop* d_info_ptr;
uint8_t* d_row_buffer;
png_byte d_color_type;
png_byte d_bit_depth;
FILE** d_png_fd;
size_t d_images_per_frame;
size_t d_row_counter;
size_t d_num_images;
size_t d_current_buffered_samples;
std::vector<std::string> d_png_fn;
bool d_flip;
size_t d_history_length;
size_t d_num_images;
png::image<png::gray_pixel> d_full_image;
png::image<png::gray_pixel> d_left_image;
png::image<png::gray_pixel> d_right_image;
std::string d_full_filename;
std::string d_left_filename;
std::string d_right_filename;
size_t d_current_x;
size_t d_current_y;
float f_max_level;
float f_min_level;
public:
noaa_apt_sink_impl (const char *filename_png, size_t width, size_t height,
bool split, bool sync, bool flip);
~noaa_apt_sink_impl ();
void
write_png_row ();
void
init_png ();
void
flip_image ();
// Where all the action really happens
int
work (int noutput_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
private:
void
init_images ();
void
set_pixel (float sample);
void
end_line ();
void
write_images ();
void
write_image (png::image<png::gray_pixel> image, std::string filename);
};
} // namespace satnogs
} // namespace gr
#endif /* INCLUDED_SATNOGS_NOAA_APT_SINK_IMPL_H */