kopia lustrzana https://github.com/jamescoxon/dl-fldigi
Add PNG save support
rodzic
c85ee8da3c
commit
226e560cb4
|
@ -61,7 +61,8 @@ public:
|
|||
void clear();
|
||||
void image(Fl_Image *img) {Fl_Widget::image(img);}
|
||||
void resize(int, int, int, int);
|
||||
int save_jpeg(const char *);
|
||||
int save_jpeg(const char *);
|
||||
int save_png(const char *);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -253,8 +253,8 @@ void mfsk::recvpic(complex z)
|
|||
|
||||
if (color) {
|
||||
pixelnbr = rgb + row + 3*col;
|
||||
updateRxPic(byte, pixelnbr);
|
||||
// REQ(&mfsk::updateRxPic, this, byte, pixelnbr);
|
||||
//! updateRxPic(byte, pixelnbr);
|
||||
REQ(updateRxPic, byte, pixelnbr);
|
||||
if (++col == picW) {
|
||||
col = 0;
|
||||
if (++rgb == 3) {
|
||||
|
@ -264,8 +264,8 @@ void mfsk::recvpic(complex z)
|
|||
}
|
||||
} else {
|
||||
for (int i = 0; i < 3; i++)
|
||||
updateRxPic(byte, pixelnbr);
|
||||
// REQ(&mfsk::updateRxPic, this, byte, pixelnbr++);
|
||||
//! updateRxPic(byte, pixelnbr++);
|
||||
REQ(updateRxPic, byte, pixelnbr++);
|
||||
}
|
||||
picf = 0.0;
|
||||
|
||||
|
@ -566,10 +566,10 @@ int mfsk::rx_process(const double *buf, int len)
|
|||
rxstate = RX_STATE_DATA;
|
||||
// REQ_FLUSH();
|
||||
put_status("");
|
||||
#ifndef __CYGWIN__
|
||||
//#ifndef __CYGWIN__
|
||||
string autosave_dir = HomeDir + "mfsk_pics/";
|
||||
picRx->save_jpeg(autosave_dir.c_str());
|
||||
#endif
|
||||
picRx->save_png(autosave_dir.c_str());
|
||||
//#endif
|
||||
} else
|
||||
recvpic(z);
|
||||
continue;
|
||||
|
@ -696,8 +696,8 @@ void mfsk::sendpic(unsigned char *data, int len)
|
|||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (txstate == TX_STATE_PICTURE)
|
||||
updateTxPic(data[i], this);
|
||||
// REQ(&mfsk::updateTxPic, this, data[i]);
|
||||
//! updateTxPic(data[i], this);
|
||||
REQ(updateTxPic, data[i], this);
|
||||
if (reverse)
|
||||
f = get_txfreq_woffset() - bandwidth * (data[i] - 128) / 256.0;
|
||||
else
|
||||
|
@ -877,14 +877,14 @@ void cb_picRxSave( Fl_Widget *w, void *who)
|
|||
{
|
||||
// mfsk *me = (mfsk *)who;
|
||||
const char *fn =
|
||||
file_saveas( "Save image as:", "Independent JPEG Group\t*.{jpg,jpeg}", NULL );
|
||||
file_saveas( "Save image as:", "Portable Network Graphics\t*.png", "." );
|
||||
if (!fn) return;
|
||||
picRx->save_jpeg(fn);
|
||||
picRx->save_png(fn);
|
||||
}
|
||||
|
||||
void createRxViewer(mfsk *who)
|
||||
{
|
||||
FL_LOCK_E();
|
||||
FL_LOCK_D();
|
||||
picRxWin = new Fl_Double_Window(200, 140);
|
||||
picRxWin->xclass(PACKAGE_NAME);
|
||||
picRx = new picture(2, 2, 136, 104);
|
||||
|
@ -898,11 +898,12 @@ void createRxViewer(mfsk *who)
|
|||
btnpicRxClose = new Fl_Button(135, 140 - 30, 60, 24, "Hide");
|
||||
btnpicRxClose->callback(cb_picRxClose, who);
|
||||
activate_mfsk_image_item(true);
|
||||
FL_UNLOCK_E();
|
||||
FL_UNLOCK_D();
|
||||
}
|
||||
|
||||
void showRxViewer(int W, int H, mfsk *who)
|
||||
{
|
||||
FL_LOCK_E();
|
||||
if (!picRxWin) createRxViewer(who);
|
||||
int winW, winH;
|
||||
int picX, picY;
|
||||
|
@ -910,7 +911,6 @@ void showRxViewer(int W, int H, mfsk *who)
|
|||
winH = H + 34;
|
||||
picX = (winW - W) / 2;
|
||||
picY = 2;
|
||||
FL_LOCK_D();
|
||||
picRxWin->size(winW, winH);
|
||||
picRx->resize(picX, picY, W, H);
|
||||
btnpicRxSave->resize(winW/2 - 65, H + 6, 60, 24);
|
||||
|
@ -919,7 +919,7 @@ void showRxViewer(int W, int H, mfsk *who)
|
|||
#ifndef __CYGWIN__
|
||||
picRxWin->show();
|
||||
#endif
|
||||
FL_UNLOCK_D();
|
||||
FL_UNLOCK_E();
|
||||
}
|
||||
|
||||
void load_file(const char *n) {
|
||||
|
|
|
@ -57,6 +57,7 @@ extern "C" {
|
|||
//# include "transupp.h"
|
||||
};
|
||||
|
||||
#include <png.h>
|
||||
|
||||
#include "picture.h"
|
||||
|
||||
|
@ -237,6 +238,43 @@ int picture::handle(int event)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static FILE* open_file(const char* name, const char* suffix)
|
||||
{
|
||||
FILE* fp;
|
||||
|
||||
size_t flen = strlen(name);
|
||||
if (name[flen - 1] == '/') {
|
||||
// if the name ends in a slash we will generate
|
||||
// a timestamped name in the following format:
|
||||
const char t[] = "pic_YYYY-MM-DD_HHMMSSz";
|
||||
|
||||
size_t newlen = flen + sizeof(t);
|
||||
if (suffix)
|
||||
newlen += 5;
|
||||
char* newfn = new char[newlen];
|
||||
memcpy(newfn, name, flen);
|
||||
|
||||
time_t time_sec = time(0);
|
||||
struct tm ztime;
|
||||
(void)gmtime_r(&time_sec, &ztime);
|
||||
|
||||
size_t sz;
|
||||
if ((sz = strftime(newfn + flen, newlen - flen, "pic_%F_%H%M%Sz", &ztime)) > 0) {
|
||||
strncpy(newfn + flen + sz, suffix, newlen - flen - sz);
|
||||
newfn[newlen - 1] = '\0';
|
||||
mkdir(name, 0777);
|
||||
fp = fopen(newfn, "wb");
|
||||
}
|
||||
else
|
||||
fp = NULL;
|
||||
delete [] newfn;
|
||||
}
|
||||
else
|
||||
fp = fopen(name, "wb");
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
||||
//
|
||||
// save_jpeg - Write a captured picture to a JPEG format file.
|
||||
//
|
||||
|
@ -248,29 +286,8 @@ int picture::save_jpeg(const char *filename)
|
|||
struct jpeg_compress_struct info; // Compressor info
|
||||
struct jpeg_error_mgr err; // Error handler info
|
||||
|
||||
size_t flen = strlen(filename);
|
||||
if (filename[flen - 1] == '/') {
|
||||
// if the filename ends in a slash we will generate
|
||||
// a timestamped filename in the following format:
|
||||
const char t[] = "pic_YYYY-MM-DD_HH:MM:SSz.jpg";
|
||||
|
||||
size_t newlen = flen + sizeof(t);
|
||||
char newfn[newlen];
|
||||
memcpy(newfn, filename, flen);
|
||||
|
||||
time_t time_sec = time(0);
|
||||
struct tm ztime;
|
||||
(void)gmtime_r(&time_sec, &ztime);
|
||||
|
||||
if (strftime(newfn + flen, newlen - flen, "pic_%F_%Tz.jpg", &ztime) > 0) {
|
||||
mkdir(filename, 0777);
|
||||
if ((fp = fopen(newfn, "wb")) == NULL)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
if ((fp = fopen(filename, "wb")) == NULL)
|
||||
return -1;
|
||||
if ((fp = open_file(filename, ".jpg")) == NULL)
|
||||
return -1;
|
||||
|
||||
// Setup the JPEG compression stuff...
|
||||
info.err = jpeg_std_error(&err);
|
||||
|
@ -302,3 +319,61 @@ int picture::save_jpeg(const char *filename)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int picture::save_png(const char* filename)
|
||||
{
|
||||
FILE* fp;
|
||||
if ((fp = open_file(filename, ".png")) == NULL)
|
||||
return -1;
|
||||
|
||||
// set up the png structures
|
||||
png_structp png;
|
||||
png_infop info;
|
||||
if ((png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)) == NULL) {
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
if ((info = png_create_info_struct(png)) == NULL) {
|
||||
png_destroy_write_struct(&png, png_infopp_NULL);
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
if (setjmp(png_jmpbuf(png))) {
|
||||
png_destroy_write_struct(&png, &info);
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// use an stdio stream
|
||||
png_init_io(png, fp);
|
||||
|
||||
// set png header
|
||||
png_set_IHDR(png, info, width, height, 1 << depth,
|
||||
PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
|
||||
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
||||
|
||||
// TODO: write more useful image comments
|
||||
png_text text;
|
||||
text.key = strdup("Comment");
|
||||
text.text = strdup("MFSK-16 image decoded by " PACKAGE_STRING);
|
||||
text.compression = PNG_TEXT_COMPRESSION_NONE;
|
||||
png_set_text(png, info, &text, 1);
|
||||
|
||||
// write header
|
||||
png_write_info(png, info);
|
||||
|
||||
// write image
|
||||
png_bytep row;
|
||||
for (int i = 0; i < height; i++) {
|
||||
row = &vidbuf[i * width * depth];
|
||||
png_write_rows(png, &row, 1);
|
||||
}
|
||||
png_write_end(png, info);
|
||||
|
||||
// clean up
|
||||
free(text.key);
|
||||
free(text.text);
|
||||
png_destroy_write_struct(&png, &info);
|
||||
fclose(fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue