Add option for rotating image

This commit is contained in:
George Vardakis 2017-04-10 18:03:00 +03:00
parent d4fbd62c03
commit bb2401356a
4 changed files with 133 additions and 27 deletions

View File

@ -4,7 +4,7 @@
<key>satnogs_noaa_apt_sink</key>
<category>[satnogs]</category>
<import>import satnogs</import>
<make>satnogs.noaa_apt_sink($*filename_png, $width, $height, $split, $sync)</make>
<make>satnogs.noaa_apt_sink($*filename_png, $width, $height, $split, $sync, $flip)</make>
<param>
<name>Output PNG Filename</name>
<key>filename_png</key>
@ -53,6 +53,21 @@
<key>True</key>
</option>
</param>
<param>
<name>Flip Image</name>
<key>flip</key>
<value>False</value>
<type>bool</type>
<hide>part</hide>
<option>
<name>Yes</name>
<key>True</key>
</option>
<option>
<name>No</name>
<key>False</key>
</option>
</param>
<sink>
<name>in</name>
<type>float</type>

View File

@ -703,12 +703,15 @@ namespace gr
* choose between deriving a single PNG file for each
* width x length pixels or two PNG files corresponding to
* each one of the two different spectrum images contained
* in a NOAA APT transmission. Further, this block performs
* normalization on the input float values based on the max
* and min values observed in the stream. Adding to that,
* the user has the option to synchronize to the first of the
* in a NOAA APT transmission. The notation 'left' and 'right'
* is with respect to the original image sent by the satellite.
* Further, this block performs normalization on the input
* float values based on the max and min values observed in the stream.
* Adding to that, the user has the option to synchronize to the first of the
* two training sequences used by the NOAA APT protocol so that
* the two images are displayed one next to the other.
* the two images are displayed one next to the other. The user
* can also select to rotate the image 180 degrees in case the captured one
* is upside down.
*
*
* @param filename_png the base filename of the output PNG file(s)
@ -718,11 +721,12 @@ namespace gr
* in a NOAA APT transmission
* @param sync user option for synchronizing to the first of the
* two training sequences
* @param flip user option to rotate the image(s) 180 degrees
*
*/
static sptr
make (const char *filename_png, size_t width,
size_t height, bool split, bool sync);
size_t height, bool split, bool sync, bool flip);
};
} // namespace satnogs

View File

@ -691,10 +691,10 @@ namespace gr
noaa_apt_sink::sptr
noaa_apt_sink::make (const char *filename_png,
size_t width, size_t height, bool split, bool sync)
size_t width, size_t height, bool split, bool sync, bool flip)
{
return gnuradio::get_initial_sptr (
new noaa_apt_sink_impl (filename_png, width, height, split, sync));
new noaa_apt_sink_impl (filename_png, width, height, split, sync, flip));
}
/*
@ -703,7 +703,8 @@ namespace gr
noaa_apt_sink_impl::noaa_apt_sink_impl (const char *filename_png,
size_t width, size_t height,
bool split,
bool sync) :
bool sync,
bool flip) :
gr::sync_block ("noaa_apt_sink",
gr::io_signature::make (1, 1, sizeof(float)),
gr::io_signature::make (0, 0, 0)),
@ -723,13 +724,21 @@ namespace gr
d_synchronize_opt(sync),
d_row_counter(0),
d_num_images(0),
d_current_buffered_samples(0)
d_current_buffered_samples(0),
d_flip(flip)
{
set_history(d_history_length);
d_color_type = PNG_COLOR_TYPE_GRAY;
d_bit_depth = 8;
d_row_buffer = (uint8_t*)malloc(d_width*sizeof(uint8_t));
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();
}
@ -737,7 +746,7 @@ namespace gr
noaa_apt_sink_impl::init_png(){
if (d_split) {
d_images_per_frame = 2;
d_png_fn = (FILE**) malloc (2 * sizeof(FILE*));
d_png_fd = (FILE**) malloc (2 * sizeof(FILE*));
d_png_ptr = (png_structp*) malloc (2 * sizeof(png_structp));
d_info_ptr = (png_infop*) malloc (2 * sizeof(png_infop));
std::string fn (d_filename_png);
@ -766,14 +775,16 @@ namespace gr
std::to_string (d_num_images).append ("_right"));
}
}
d_png_fn[0] = fopen (fn_left.c_str (), "wb");
d_png_fn[1] = fopen (fn_right.c_str (), "wb");
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_fn[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,
@ -785,11 +796,12 @@ namespace gr
}
else {
d_images_per_frame = 1;
d_png_fn = (FILE**) malloc (sizeof(FILE*));
d_png_fd = (FILE**) malloc (sizeof(FILE*));
d_png_ptr = (png_structp*) malloc (sizeof(png_structp));
d_info_ptr = (png_infop*) malloc (sizeof(png_infop));
if (d_num_images == 0) {
d_png_fn[0] = fopen (d_filename_png, "wb");
d_png_fd[0] = fopen (d_filename_png, "wb");
d_png_fn[0] = std::string(d_filename_png);
}
else {
std::string fn (d_filename_png);
@ -799,14 +811,15 @@ namespace gr
else {
fn.insert (found, std::to_string (d_num_images));
}
d_png_fn[0] = fopen (fn.c_str (), "wb");
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_fn[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,
@ -819,12 +832,14 @@ namespace gr
void
noaa_apt_sink_impl::write_png_row (){
if (d_row_counter == d_height) {
d_row_counter =0;
d_num_images++;
for (size_t i = 0; i < d_images_per_frame; i++) {
png_write_end (d_png_ptr[i], NULL);
fclose (d_png_fn[i]);
fclose (d_png_fd[i]);
}
if(d_flip)
flip_image();
d_row_counter =0;
d_num_images++;
init_png();
}
if (d_split) {
@ -837,7 +852,6 @@ namespace gr
}
d_row_counter++;
}
noaa_apt_sink_impl::~noaa_apt_sink_impl ()
{
if(d_current_buffered_samples < d_width){
@ -851,12 +865,80 @@ namespace gr
write_png_row();
}
}
for (size_t i = 0; i < d_images_per_frame; i++) {
png_write_end (d_png_ptr[i], NULL);
fclose (d_png_fn[i]);
fclose (d_png_fd[i]);
}
if(d_flip)
flip_image();
}
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;
//init_png();
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]);
/* initialize stuff */
png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL,
NULL);
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 = (png_bytep*) malloc (sizeof(png_bytep) * d_height);
for (size_t y = 0; y < d_height; y++)
row_pointers[y] = (png_byte*) malloc (
png_get_rowbytes (png_ptr, info_ptr));
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]);
}
png_write_end (d_png_ptr[i], NULL);
fclose (d_png_fd[i]);
}
}
int
noaa_apt_sink_impl::work (int noutput_items,
gr_vector_const_void_star &input_items,

View File

@ -709,20 +709,25 @@ namespace gr
uint8_t* d_row_buffer;
png_byte d_color_type;
png_byte d_bit_depth;
FILE** d_png_fn;
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;
public:
noaa_apt_sink_impl (const char *filename_png,
size_t width, size_t height, bool split, bool sync);
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