diff --git a/lib/noaa_apt_sink_impl.cc b/lib/noaa_apt_sink_impl.cc index c773171..72f2cf0 100644 --- a/lib/noaa_apt_sink_impl.cc +++ b/lib/noaa_apt_sink_impl.cc @@ -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(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(d_width/2, d_height); + d_right_image = png::image(d_width/2, d_height); + } + } + + void + noaa_apt_sink_impl::write_image (png::image image, std::string filename) { + if(d_flip) { + size_t width = image.get_width(); + size_t height = image.get_height(); + + png::image 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 */ - diff --git a/lib/noaa_apt_sink_impl.h b/lib/noaa_apt_sink_impl.h index 4612419..84e6597 100644 --- a/lib/noaa_apt_sink_impl.h +++ b/lib/noaa_apt_sink_impl.h @@ -23,9 +23,11 @@ #include #define PNG_DEBUG 3 -#include +#include #include + + 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 d_png_fn; bool d_flip; + size_t d_history_length; + + size_t d_num_images; + png::image d_full_image; + png::image d_left_image; + png::image 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 image, std::string filename); }; } // namespace satnogs } // namespace gr #endif /* INCLUDED_SATNOGS_NOAA_APT_SINK_IMPL_H */ -