Add option for rotating image
This commit is contained in:
parent
d4fbd62c03
commit
bb2401356a
|
@ -4,7 +4,7 @@
|
||||||
<key>satnogs_noaa_apt_sink</key>
|
<key>satnogs_noaa_apt_sink</key>
|
||||||
<category>[satnogs]</category>
|
<category>[satnogs]</category>
|
||||||
<import>import satnogs</import>
|
<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>
|
<param>
|
||||||
<name>Output PNG Filename</name>
|
<name>Output PNG Filename</name>
|
||||||
<key>filename_png</key>
|
<key>filename_png</key>
|
||||||
|
@ -53,6 +53,21 @@
|
||||||
<key>True</key>
|
<key>True</key>
|
||||||
</option>
|
</option>
|
||||||
</param>
|
</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>
|
<sink>
|
||||||
<name>in</name>
|
<name>in</name>
|
||||||
<type>float</type>
|
<type>float</type>
|
||||||
|
|
|
@ -703,12 +703,15 @@ namespace gr
|
||||||
* choose between deriving a single PNG file for each
|
* choose between deriving a single PNG file for each
|
||||||
* width x length pixels or two PNG files corresponding to
|
* width x length pixels or two PNG files corresponding to
|
||||||
* each one of the two different spectrum images contained
|
* each one of the two different spectrum images contained
|
||||||
* in a NOAA APT transmission. Further, this block performs
|
* in a NOAA APT transmission. The notation 'left' and 'right'
|
||||||
* normalization on the input float values based on the max
|
* is with respect to the original image sent by the satellite.
|
||||||
* and min values observed in the stream. Adding to that,
|
* Further, this block performs normalization on the input
|
||||||
* the user has the option to synchronize to the first of the
|
* 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
|
* 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)
|
* @param filename_png the base filename of the output PNG file(s)
|
||||||
|
@ -718,11 +721,12 @@ namespace gr
|
||||||
* in a NOAA APT transmission
|
* in a NOAA APT transmission
|
||||||
* @param sync user option for synchronizing to the first of the
|
* @param sync user option for synchronizing to the first of the
|
||||||
* two training sequences
|
* two training sequences
|
||||||
|
* @param flip user option to rotate the image(s) 180 degrees
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static sptr
|
static sptr
|
||||||
make (const char *filename_png, size_t width,
|
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
|
} // namespace satnogs
|
||||||
|
|
|
@ -691,10 +691,10 @@ namespace gr
|
||||||
|
|
||||||
noaa_apt_sink::sptr
|
noaa_apt_sink::sptr
|
||||||
noaa_apt_sink::make (const char *filename_png,
|
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 (
|
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,
|
noaa_apt_sink_impl::noaa_apt_sink_impl (const char *filename_png,
|
||||||
size_t width, size_t height,
|
size_t width, size_t height,
|
||||||
bool split,
|
bool split,
|
||||||
bool sync) :
|
bool sync,
|
||||||
|
bool flip) :
|
||||||
gr::sync_block ("noaa_apt_sink",
|
gr::sync_block ("noaa_apt_sink",
|
||||||
gr::io_signature::make (1, 1, sizeof(float)),
|
gr::io_signature::make (1, 1, sizeof(float)),
|
||||||
gr::io_signature::make (0, 0, 0)),
|
gr::io_signature::make (0, 0, 0)),
|
||||||
|
@ -723,13 +724,21 @@ namespace gr
|
||||||
d_synchronize_opt(sync),
|
d_synchronize_opt(sync),
|
||||||
d_row_counter(0),
|
d_row_counter(0),
|
||||||
d_num_images(0),
|
d_num_images(0),
|
||||||
d_current_buffered_samples(0)
|
d_current_buffered_samples(0),
|
||||||
|
d_flip(flip)
|
||||||
|
|
||||||
{
|
{
|
||||||
set_history(d_history_length);
|
set_history(d_history_length);
|
||||||
d_color_type = PNG_COLOR_TYPE_GRAY;
|
d_color_type = PNG_COLOR_TYPE_GRAY;
|
||||||
d_bit_depth = 8;
|
d_bit_depth = 8;
|
||||||
d_row_buffer = (uint8_t*)malloc(d_width*sizeof(uint8_t));
|
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();
|
init_png();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -737,7 +746,7 @@ namespace gr
|
||||||
noaa_apt_sink_impl::init_png(){
|
noaa_apt_sink_impl::init_png(){
|
||||||
if (d_split) {
|
if (d_split) {
|
||||||
d_images_per_frame = 2;
|
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_png_ptr = (png_structp*) malloc (2 * sizeof(png_structp));
|
||||||
d_info_ptr = (png_infop*) malloc (2 * sizeof(png_infop));
|
d_info_ptr = (png_infop*) malloc (2 * sizeof(png_infop));
|
||||||
std::string fn (d_filename_png);
|
std::string fn (d_filename_png);
|
||||||
|
@ -766,14 +775,16 @@ namespace gr
|
||||||
std::to_string (d_num_images).append ("_right"));
|
std::to_string (d_num_images).append ("_right"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d_png_fn[0] = fopen (fn_left.c_str (), "wb");
|
d_png_fn[0] = fn_left;
|
||||||
d_png_fn[1] = fopen (fn_right.c_str (), "wb");
|
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++) {
|
for (size_t i = 0; i < d_images_per_frame; i++) {
|
||||||
d_png_ptr[i] = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL,
|
d_png_ptr[i] = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
d_info_ptr[i] = png_create_info_struct (d_png_ptr[i]);
|
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,
|
png_set_IHDR (d_png_ptr[i], d_info_ptr[i], d_width / 2, d_height,
|
||||||
d_bit_depth, d_color_type,
|
d_bit_depth, d_color_type,
|
||||||
PNG_INTERLACE_NONE,
|
PNG_INTERLACE_NONE,
|
||||||
|
@ -785,11 +796,12 @@ namespace gr
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
d_images_per_frame = 1;
|
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_png_ptr = (png_structp*) malloc (sizeof(png_structp));
|
||||||
d_info_ptr = (png_infop*) malloc (sizeof(png_infop));
|
d_info_ptr = (png_infop*) malloc (sizeof(png_infop));
|
||||||
if (d_num_images == 0) {
|
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 {
|
else {
|
||||||
std::string fn (d_filename_png);
|
std::string fn (d_filename_png);
|
||||||
|
@ -799,14 +811,15 @@ namespace gr
|
||||||
else {
|
else {
|
||||||
fn.insert (found, std::to_string (d_num_images));
|
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,
|
d_png_ptr[0] = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
d_info_ptr[0] = png_create_info_struct (d_png_ptr[0]);
|
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,
|
png_set_IHDR (d_png_ptr[0], d_info_ptr[0], d_width, d_height,
|
||||||
d_bit_depth, d_color_type,
|
d_bit_depth, d_color_type,
|
||||||
PNG_INTERLACE_NONE,
|
PNG_INTERLACE_NONE,
|
||||||
|
@ -819,12 +832,14 @@ namespace gr
|
||||||
void
|
void
|
||||||
noaa_apt_sink_impl::write_png_row (){
|
noaa_apt_sink_impl::write_png_row (){
|
||||||
if (d_row_counter == d_height) {
|
if (d_row_counter == d_height) {
|
||||||
d_row_counter =0;
|
|
||||||
d_num_images++;
|
|
||||||
for (size_t i = 0; i < d_images_per_frame; i++) {
|
for (size_t i = 0; i < d_images_per_frame; i++) {
|
||||||
png_write_end (d_png_ptr[i], NULL);
|
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();
|
init_png();
|
||||||
}
|
}
|
||||||
if (d_split) {
|
if (d_split) {
|
||||||
|
@ -837,7 +852,6 @@ namespace gr
|
||||||
}
|
}
|
||||||
d_row_counter++;
|
d_row_counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
noaa_apt_sink_impl::~noaa_apt_sink_impl ()
|
noaa_apt_sink_impl::~noaa_apt_sink_impl ()
|
||||||
{
|
{
|
||||||
if(d_current_buffered_samples < d_width){
|
if(d_current_buffered_samples < d_width){
|
||||||
|
@ -851,12 +865,80 @@ namespace gr
|
||||||
write_png_row();
|
write_png_row();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < d_images_per_frame; i++) {
|
for (size_t i = 0; i < d_images_per_frame; i++) {
|
||||||
png_write_end (d_png_ptr[i], NULL);
|
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
|
int
|
||||||
noaa_apt_sink_impl::work (int noutput_items,
|
noaa_apt_sink_impl::work (int noutput_items,
|
||||||
gr_vector_const_void_star &input_items,
|
gr_vector_const_void_star &input_items,
|
||||||
|
|
|
@ -709,20 +709,25 @@ namespace gr
|
||||||
uint8_t* d_row_buffer;
|
uint8_t* d_row_buffer;
|
||||||
png_byte d_color_type;
|
png_byte d_color_type;
|
||||||
png_byte d_bit_depth;
|
png_byte d_bit_depth;
|
||||||
FILE** d_png_fn;
|
FILE** d_png_fd;
|
||||||
size_t d_images_per_frame;
|
size_t d_images_per_frame;
|
||||||
size_t d_row_counter;
|
size_t d_row_counter;
|
||||||
size_t d_num_images;
|
size_t d_num_images;
|
||||||
size_t d_current_buffered_samples;
|
size_t d_current_buffered_samples;
|
||||||
|
std::vector<std::string> d_png_fn;
|
||||||
|
bool d_flip;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
noaa_apt_sink_impl (const char *filename_png,
|
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 ();
|
~noaa_apt_sink_impl ();
|
||||||
void
|
void
|
||||||
write_png_row ();
|
write_png_row ();
|
||||||
void
|
void
|
||||||
init_png ();
|
init_png ();
|
||||||
|
void
|
||||||
|
flip_image();
|
||||||
|
|
||||||
// Where all the action really happens
|
// Where all the action really happens
|
||||||
int
|
int
|
||||||
|
|
Loading…
Reference in New Issue