DnD Image
* Add Dnd Image to TX panel - applies to MFSK, IFKP and THOR image transfers - allows operator to insert image processing into TX text stream - drag-drop image from system file viewer to TX text panel - updated specific modem documentationpull/4/head
Po Szerokość: | Wysokość: | Rozmiar: 34 KiB |
Przed Szerokość: | Wysokość: | Rozmiar: 35 KiB Po Szerokość: | Wysokość: | Rozmiar: 13 KiB |
Przed Szerokość: | Wysokość: | Rozmiar: 51 KiB Po Szerokość: | Wysokość: | Rozmiar: 94 KiB |
Po Szerokość: | Wysokość: | Rozmiar: 85 KiB |
Przed Szerokość: | Wysokość: | Rozmiar: 38 KiB Po Szerokość: | Wysokość: | Rozmiar: 65 KiB |
Przed Szerokość: | Wysokość: | Rozmiar: 61 KiB |
Po Szerokość: | Wysokość: | Rozmiar: 4.9 KiB |
Po Szerokość: | Wysokość: | Rozmiar: 6.0 KiB |
Po Szerokość: | Wysokość: | Rozmiar: 17 KiB |
Po Szerokość: | Wysokość: | Rozmiar: 40 KiB |
Przed Szerokość: | Wysokość: | Rozmiar: 75 KiB |
Po Szerokość: | Wysokość: | Rozmiar: 44 KiB |
|
@ -309,6 +309,55 @@ mode when the image transmission is completed.
|
|||
\image latex ifkp-WF-image-mode.png "Image Mode Waterfall" width=3.5in
|
||||
</center>
|
||||
|
||||
There is an alternate way of sending an image, but one which only transmits a color
|
||||
image with no provision for slant correction. This may be more convenient
|
||||
for sharing images when you do not need the additional utility of the image dialog.
|
||||
<br>
|
||||
|
||||
Open a file folder to the location of your image files that are suitable for MFSK
|
||||
transmission. These images should be constrained to be 240 x 200 or less for
|
||||
reasonable transmit times. Optionally prepare fldigi for the MFSK image
|
||||
transmission by entering some suitable text to precede the transmission.
|
||||
You may be sending the image, blossoms.jpg, for example.
|
||||
<br>
|
||||
|
||||
<center>
|
||||
\image html blossoms.png "image in files folder"
|
||||
\image latex blossoms.png "image in files folder" width=3.0in
|
||||
</center>
|
||||
|
||||
One might enter:
|
||||
|
||||
\image html blossoms-1.png ""
|
||||
\image latex blossoms-1.png "" width=4.0in
|
||||
|
||||
Then drag and drop the the image file from the files folder to the transmit
|
||||
text panel in fldigi. The program will automatically resize the image to the
|
||||
nearest scale-aspect ratio less than or equal to the actual image size.
|
||||
<br>
|
||||
|
||||
The TX panel text will then change to
|
||||
|
||||
\image html blossoms-2.png ""
|
||||
\image latex blossoms-2.png "" width=4.0in
|
||||
|
||||
The ^! is the character sequence used by the fldigi TX parser to indicate
|
||||
that there is a pending execution command. In this case it is to transmit
|
||||
the blossoms.jpg file.
|
||||
<br>
|
||||
|
||||
Add some suitable ending text and the sequence ^r to the next line and
|
||||
then press the T/R button (if not already transmitting). At the end of the
|
||||
image the TX parser will find the ^r and return the program to the receive
|
||||
mode.
|
||||
|
||||
The Rx panel will echo the transmitted data:
|
||||
<br>
|
||||
\image html thor-pic-transmission.png ""
|
||||
\image latex thor-pic-transmission.png "" width=4.0in
|
||||
|
||||
The transmit progress dialog will close at the conclusion of the image transmission.
|
||||
|
||||
<b>Receive Image</b>
|
||||
|
||||
Reception is completely automatic. The decoder will identify the picture start,
|
||||
|
|
|
@ -27,7 +27,6 @@ This is an example of properly tuned MFSK16 signal with a s/n of
|
|||
approximately 9 dB.
|
||||
<br>
|
||||
|
||||
|
||||
\image html mfsk-9db.png " MFSK16 signal"
|
||||
\image latex mfsk-9db.png " MFSK16 signal" width=6.0in
|
||||
<br>
|
||||
|
@ -61,15 +60,6 @@ is subject to burst and phase noise on the transmission path. It
|
|||
can provide excellent photo transmission on a really good path.
|
||||
<br>
|
||||
|
||||
\image html mfskpix-bee.png "Received MFSK Image"
|
||||
\image latex mfskpix-bee.png "Received MFSK Image" width=2.0in
|
||||
<br>
|
||||
|
||||
This is an example of a photo received on a bench test. The received
|
||||
image is an exact replica of the transmitted image. The color depth is
|
||||
a full 24 bits.
|
||||
<br>
|
||||
|
||||
Images should be carefully selected for size before beginning a
|
||||
transmission. To calculate the transmit time for an image use the
|
||||
following formula:
|
||||
|
@ -100,12 +90,11 @@ Received images are saved in the default folder $HOME/.fldigi/images
|
|||
|
||||
\section mfsk_tx_image Transmitting an Image
|
||||
|
||||
|
||||
\image html Xmt-Pix.png "Xmit Picture Dialog box"
|
||||
\image latex Xmt-Pix.png "Xmit Picture Dialog box" width=3.0in
|
||||
<br>
|
||||
|
||||
You can only transmit an image while in the MFSK-16 mode. The
|
||||
You can only transmit an image while in the MFSK-16/32/64/128 modes. The
|
||||
image can be prepared for transmission while in the receive mode. Right click
|
||||
in the transmit text box and select "Send Image" from the popup menu. This
|
||||
will open up the transmit image dialog which will be blank to start.
|
||||
|
@ -159,28 +148,84 @@ will then have to toggle the T/R button if you want to return to
|
|||
receive.
|
||||
<br>
|
||||
|
||||
\image html Xmt-Pix3.png "Received MFSK Image"
|
||||
\image latex Xmt-Pix3.png "Received MFSK Image" width=1.5in
|
||||
There is an alternate way of sending an image, but one which only transmits a color
|
||||
image with no provision for slant correction. This may be more convenient
|
||||
for sharing images when you do not need the additional utility of the image dialog.
|
||||
<br>
|
||||
|
||||
The receiving program decodes the "Pic:110x119C;" as a color picture
|
||||
110 wide by 119 high. Here is shown being received on a computer
|
||||
running Vista Home Premium.
|
||||
Open a file folder to the location of your image files that are suitable for MFSK
|
||||
transmission. These images should be constrained to be 240 x 200 or less for
|
||||
reasonable transmit times. Optionally prepare fldigi for the MFSK image
|
||||
transmission by entering some suitable text to precede the transmission.
|
||||
You may be sending the image, blossoms.jpg, for example.
|
||||
<br>
|
||||
|
||||
<center>
|
||||
\image html blossoms.png "image in files folder"
|
||||
\image latex blossoms.png "image in files folder" width=3.0in
|
||||
</center>
|
||||
|
||||
\image html Xmt-Pix4.png "Waterfall of a MFSK Image"
|
||||
\image latex Xmt-Pix4.png "Waterfall of a MFSK Image" width=3.5in
|
||||
One might enter:
|
||||
|
||||
\image html blossoms-1.png ""
|
||||
\image latex blossoms-1.png "" width=4.0in
|
||||
|
||||
Then drag and drop the the image file from the files folder to the transmit
|
||||
text panel in fldigi.
|
||||
<br>
|
||||
|
||||
The TX panel text will then change to
|
||||
|
||||
\image html blossoms-2.png ""
|
||||
\image latex blossoms-2.png "" width=4.0in
|
||||
|
||||
The ^! is the character sequence used by the fldigi TX parser to indicate
|
||||
that there is a pending execution command. In this case it is to transmit
|
||||
the blossoms.jpg file.
|
||||
<br>
|
||||
|
||||
Add some suitable ending text and the sequence ^r to the next line and
|
||||
then press the T/R button (if not already transmitting). At the end of the
|
||||
image the TX parser will find the ^r and return the program to the receive
|
||||
mode.
|
||||
|
||||
The Rx panel will echo the transmitted data:
|
||||
<br>
|
||||
\image html blossoms-3.png ""
|
||||
\image latex blossoms-3.png "" width=4.0in
|
||||
|
||||
The image progress dialog will close at the end of the image transfer.
|
||||
|
||||
\section mfsk_rx_image Receiving an Image
|
||||
|
||||
The receiving program decodes the "Pic:240x160C;" as a color picture
|
||||
240 wide by 160 high.
|
||||
<center>
|
||||
\image html Xmt-Pix2.png "Received MFSK Image"
|
||||
\image latex Xmt-Pix2.png "Received MFSK Image" width=3.0in
|
||||
</center>
|
||||
|
||||
This is what the waterfall will look like during the reception of an
|
||||
MFSK-16 image.
|
||||
MFSK-64 image.
|
||||
<br>
|
||||
<center>
|
||||
\image html Xmt-Pix3.png "MFSK Image - Waterfall"
|
||||
\image latex Xmt-Pix3.png "MFSK Image - Waterfall" width=4.5in
|
||||
</center>
|
||||
|
||||
The actual spectrum signature will vary with the image bytes being
|
||||
transmitted. The waterfall scale is in the x4 mode and the above
|
||||
photo was being transmitted in 24 bit color for this screenshot. The
|
||||
transmitted. The image was being transmitted in 24 bit color for this screenshot. The
|
||||
waterfall clearly shows that the image transmission is within the bandwidth
|
||||
occupied by MFSK-16.
|
||||
occupied by MFSK-64.
|
||||
|
||||
Received images are automatically saved to the images folder and annotated with
|
||||
a date-time stamp.
|
||||
|
||||
<center>
|
||||
\image html MFSK-rx-images.png "MFSK Rx Images"
|
||||
\image latex MFSK-rx-images.png "MFSK Rx Images" width=4.5in
|
||||
</center>
|
||||
|
||||
<br>
|
||||
|
||||
\section mfsk_picture_slant Picture with a slant
|
||||
|
@ -203,9 +248,8 @@ move the mouse to bottom left or right corner of the slanted images
|
|||
(the corner that clearly visible). Then left click on that
|
||||
corner. The program will correct for the slant. The
|
||||
correction will not be perfect but it may help to make the image more
|
||||
viewable.
|
||||
<br>
|
||||
|
||||
viewable. Right click to undo the slant correction. Slant corrections are
|
||||
not saved to the Rx image file.
|
||||
|
||||
<br>
|
||||
\ref mfsk_page "Return to Top of Page"
|
||||
|
|
|
@ -146,6 +146,55 @@ Transmission begins when you press the "Xmt" button. fldigi will insert the tex
|
|||
preamble and immediately begin the image transmission. fldigi returns to the receive
|
||||
mode when the image transmission is completed.
|
||||
|
||||
There is an alternate way of sending an image, but one which only transmits a color
|
||||
image with no provision for slant correction. This may be more convenient
|
||||
for sharing images when you do not need the additional utility of the image dialog.
|
||||
<br>
|
||||
|
||||
Open a file folder to the location of your image files that are suitable for MFSK
|
||||
transmission. These images should be constrained to be 240 x 200 or less for
|
||||
reasonable transmit times. Optionally prepare fldigi for the MFSK image
|
||||
transmission by entering some suitable text to precede the transmission.
|
||||
You may be sending the image, blossoms.jpg, for example.
|
||||
<br>
|
||||
|
||||
<center>
|
||||
\image html blossoms.png "image in files folder"
|
||||
\image latex blossoms.png "image in files folder" width=3.0in
|
||||
</center>
|
||||
|
||||
One might enter:
|
||||
|
||||
\image html blossoms-1.png ""
|
||||
\image latex blossoms-1.png "" width=4.0in
|
||||
|
||||
Then drag and drop the the image file from the files folder to the transmit
|
||||
text panel in fldigi. The program will automatically resize the image to the
|
||||
nearest scale-aspect ratio less than or equal to the actual image size.
|
||||
<br>
|
||||
|
||||
The TX panel text will then change to
|
||||
|
||||
\image html blossoms-2.png ""
|
||||
\image latex blossoms-2.png "" width=4.0in
|
||||
|
||||
The ^! is the character sequence used by the fldigi TX parser to indicate
|
||||
that there is a pending execution command. In this case it is to transmit
|
||||
the blossoms.jpg file.
|
||||
<br>
|
||||
|
||||
Add some suitable ending text and the sequence ^r to the next line and
|
||||
then press the T/R button (if not already transmitting). At the end of the
|
||||
image the TX parser will find the ^r and return the program to the receive
|
||||
mode.
|
||||
|
||||
The Rx panel will echo the transmitted data:
|
||||
<br>
|
||||
\image html thor-pic-transmission.png ""
|
||||
\image latex thor-pic-transmission.png "" width=4.0in
|
||||
|
||||
The transmit progress dialog will close at the conclusion of the image transmission.
|
||||
|
||||
<b>Receive Image</b>
|
||||
|
||||
Reception is completely automatic. The decoder will identify the picture start,
|
||||
|
@ -153,7 +202,7 @@ and record the picture. In doing so, it automatically opens a separate "thor Rx
|
|||
|
||||
<center>
|
||||
\image html thor-image-partial.png "Image Reception"
|
||||
\image latex thor-image-partial.png "Image Reception" width=3.5in
|
||||
\image latex thor-image-partial.png "Image Reception" width=6.0in
|
||||
</center>
|
||||
|
||||
Demodulation uses a phase detection algorithm based on quadrature demodulation
|
||||
|
|
|
@ -116,7 +116,7 @@ void ifkp_updateRxPic(unsigned char data, int pos)
|
|||
for (int i = 0; i < ifkp::IMAGEspp; i++)
|
||||
ifkp_rawvideo[RAWSTART + ifkp::IMAGEspp*ifkp_numpixels + i] = data;
|
||||
ifkp_numpixels++;
|
||||
if (ifkp_numpixels >= (RAWSIZE - RAWSTART - ifkp::IMAGEspp))
|
||||
if (ifkp_numpixels >= (RAWSIZE - RAWSTART - ifkp::IMAGEspp))
|
||||
ifkp_numpixels = RAWSIZE - RAWSTART - ifkp::IMAGEspp;
|
||||
}
|
||||
|
||||
|
@ -473,6 +473,145 @@ void ifkp_createTxViewer()
|
|||
|
||||
}
|
||||
|
||||
|
||||
void ifkp_load_scaled_image(std::string fname)
|
||||
{
|
||||
|
||||
if (!ifkppicTxWin) ifkp_createTxViewer();
|
||||
|
||||
int D = 0;
|
||||
unsigned char *img_data;
|
||||
int W = 160;
|
||||
int H = 120;
|
||||
int winW = 644;
|
||||
int winH = 512;
|
||||
int ifkppicX = 0;
|
||||
int ifkppicY = 0;
|
||||
string picmode = "pic% \n";
|
||||
|
||||
if (ifkpTxImg) {
|
||||
ifkpTxImg->release();
|
||||
ifkpTxImg = 0;
|
||||
}
|
||||
|
||||
ifkpTxImg = Fl_Shared_Image::get(fname.c_str());
|
||||
if (!ifkpTxImg)
|
||||
return;
|
||||
|
||||
int iW = ifkpTxImg->w();
|
||||
int iH = ifkpTxImg->h();
|
||||
int aspect = 0;
|
||||
|
||||
if (iW > iH ) {
|
||||
if (iW >= 640) {
|
||||
W = 640; H = 480;
|
||||
winW = 644; winH = 484;
|
||||
aspect = 4;
|
||||
picmode[4] = 'V';
|
||||
}
|
||||
else if (iW >= 320) {
|
||||
W = 320; H = 240;
|
||||
winW = 324; winH = 244;
|
||||
aspect = 2;
|
||||
picmode[4] = 'L';
|
||||
}
|
||||
else {
|
||||
W = 160; H = 120;
|
||||
winW = 164; winH = 124;
|
||||
aspect = 1;
|
||||
picmode[4] = 'S';
|
||||
}
|
||||
} else {
|
||||
if (iH >= 300) {
|
||||
W = 240; H = 300;
|
||||
winW = 244; winH = 304;
|
||||
aspect = 5;
|
||||
picmode[4] = 'P';
|
||||
}
|
||||
else if (iH >= 150) {
|
||||
W = 120; H = 150;
|
||||
winW = 124; winH = 154;
|
||||
aspect = 7;
|
||||
picmode[4] = 'M';
|
||||
}
|
||||
else {
|
||||
W = 59; H = 74;
|
||||
winW = 67; winH = 82;
|
||||
aspect = 0;
|
||||
picmode[4] = 'T';
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Fl_Image *temp;
|
||||
selifkppicSize->value(aspect);
|
||||
temp = ifkpTxImg->copy(W, H);
|
||||
ifkpTxImg->release();
|
||||
ifkpTxImg = (Fl_Shared_Image *)temp;
|
||||
}
|
||||
|
||||
if (ifkpTxImg->count() > 1) {
|
||||
ifkpTxImg->release();
|
||||
ifkpTxImg = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
ifkppicTx->hide();
|
||||
ifkppicTx->clear();
|
||||
|
||||
img_data = (unsigned char *)ifkpTxImg->data()[0];
|
||||
|
||||
D = ifkpTxImg->d();
|
||||
|
||||
if (ifkpxmtimg) delete [] ifkpxmtimg;
|
||||
|
||||
ifkpxmtimg = new unsigned char [W * H * 3];
|
||||
if (D == 3)
|
||||
memcpy(ifkpxmtimg, img_data, W*H*3);
|
||||
else if (D == 4) {
|
||||
int i, j, k;
|
||||
for (i = 0; i < W*H; i++) {
|
||||
j = i*3; k = i*4;
|
||||
ifkpxmtimg[j] = img_data[k];
|
||||
ifkpxmtimg[j+1] = img_data[k+1];
|
||||
ifkpxmtimg[j+2] = img_data[k+2];
|
||||
}
|
||||
} else if (D == 1) {
|
||||
int i, j;
|
||||
for (i = 0; i < W*H; i++) {
|
||||
j = i * 3;
|
||||
ifkpxmtimg[j] = ifkpxmtimg[j+1] = ifkpxmtimg[j+2] = img_data[i];
|
||||
}
|
||||
} else
|
||||
return;
|
||||
|
||||
char* label = strdup(fname.c_str());
|
||||
ifkppicTxWin->copy_label(basename(label));
|
||||
free(label);
|
||||
|
||||
// load the ifkppicture widget with the rgb image
|
||||
|
||||
ifkppicTxWin->size(winW, winH);
|
||||
ifkppicX = (winW - W) / 2;
|
||||
ifkppicY = (winH - H) / 2;
|
||||
ifkppicTx->resize(ifkppicX, ifkppicY, W, H);
|
||||
|
||||
selifkppicSize->hide();
|
||||
btnifkppicTransmit->hide();
|
||||
btnifkppicTxLoad->hide();
|
||||
btnifkppicTxClose->hide();
|
||||
btnifkppicTxSendAbort->hide();
|
||||
|
||||
ifkppicTx->video(ifkpxmtimg, W * H * 3);
|
||||
ifkppicTx->show();
|
||||
|
||||
ifkppicTxWin->show();
|
||||
|
||||
active_modem->ifkp_send_image(picmode);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void ifkp_showTxViewer(char c)
|
||||
{
|
||||
if (!ifkppicTxWin) ifkp_createTxViewer();
|
||||
|
@ -494,7 +633,7 @@ void ifkp_showTxViewer(char c)
|
|||
break;
|
||||
case 'L' :
|
||||
case 'l' :
|
||||
W = 320; H = 240; winW = 324; winH = 274;
|
||||
W = 320; H = 240; winW = 324; winH = 274;
|
||||
selifkppicSize->value(2);
|
||||
break;
|
||||
case 'F' :
|
||||
|
@ -641,7 +780,7 @@ int ifkp_load_avatar(std::string image_fname, int W, int H)
|
|||
shared_avatar_img = Fl_Shared_Image::get(fname.c_str(), W, H);
|
||||
|
||||
// force image to be retrieved from hard drive vice shared image memory
|
||||
shared_avatar_img->reload();
|
||||
shared_avatar_img->reload();
|
||||
|
||||
if (!shared_avatar_img) {
|
||||
ifkp_avatar->video(tux_img, W * H * 3);
|
||||
|
@ -732,7 +871,7 @@ void ifkp_update_avatar(unsigned char data, int pos)
|
|||
|
||||
ifkp_numpixels++;
|
||||
|
||||
if (ifkp_numpixels >= (RAWSIZE - RAWSTART - ifkp::IMAGEspp))
|
||||
if (ifkp_numpixels >= (RAWSIZE - RAWSTART - ifkp::IMAGEspp))
|
||||
ifkp_numpixels = RAWSIZE - RAWSTART - ifkp::IMAGEspp;
|
||||
|
||||
}
|
||||
|
@ -820,4 +959,3 @@ void cb_ifkp_send_avatar( Fl_Widget *w, void *)
|
|||
ifkp_avatar->save_png(fname.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -770,7 +770,10 @@ void ifkp::send_image()
|
|||
}
|
||||
}
|
||||
|
||||
void ifkp::ifkp_send_image() {
|
||||
std::string img_str;
|
||||
|
||||
void ifkp::ifkp_send_image(std::string image_str) {
|
||||
img_str = image_str;
|
||||
TX_IMAGE = true;
|
||||
start_tx();
|
||||
}
|
||||
|
@ -787,17 +790,29 @@ int ifkp::tx_process()
|
|||
send_char(0);
|
||||
send_char(0);
|
||||
}
|
||||
|
||||
int c = get_tx_char();
|
||||
if (c == GET_TX_CHAR_ETX) {
|
||||
|
||||
// if (c == GET_TX_CHAR_ETX || enable_image) {
|
||||
if (TX_IMAGE || TX_AVATAR) {
|
||||
if (img_str.length()) {
|
||||
for (size_t n = 0; n < img_str.length(); n++)
|
||||
send_char(img_str[n]);
|
||||
}
|
||||
if (TX_IMAGE) send_image();
|
||||
if (TX_AVATAR) send_avatar();
|
||||
send_char(0);
|
||||
stopflag = false;
|
||||
TX_IMAGE = false;
|
||||
TX_AVATAR = false;
|
||||
return -1;
|
||||
if (img_str.length()) {
|
||||
ifkppicTxWin->hide();
|
||||
img_str.clear();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if ( stopflag ) { // aborts transmission
|
||||
if ( stopflag || c == GET_TX_CHAR_ETX) { // aborts transmission
|
||||
send_char(0);
|
||||
TX_IMAGE = false;
|
||||
TX_AVATAR = false;
|
||||
stopflag = false;
|
||||
|
|
|
@ -242,6 +242,7 @@ extern void cbSELCAL(Fl_Widget *w, void *d);
|
|||
extern void cbFSQCALL(Fl_Widget *w, void *d);
|
||||
|
||||
extern void ifkp_showTxViewer(char C = 'T');
|
||||
extern void ifkp_load_scaled_image(std::string);
|
||||
extern Fl_Double_Window *ifkppicRxWin;
|
||||
extern Fl_Double_Window *ifkppicTxWin;
|
||||
|
||||
|
@ -554,5 +555,6 @@ extern void thor_update_avatar(unsigned char data, int pos);
|
|||
extern int thor_get_avatar_pixel(int pos, int color);
|
||||
extern void cb_thor_send_avatar( Fl_Widget *w, void *);
|
||||
extern picture *thor_avatar;
|
||||
extern void thor_load_scaled_image(std::string fname);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -171,7 +171,7 @@ static int IMAGEspp;
|
|||
void send_image();
|
||||
void send_avatar();
|
||||
void ifkp_send_avatar();
|
||||
void ifkp_send_image();
|
||||
void ifkp_send_image(std::string s = "");
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -98,4 +98,6 @@ void Rx_queue_execute();
|
|||
bool queue_must_rx();
|
||||
void idleTimer(void *);
|
||||
|
||||
extern void TxQueINSERTIMAGE(std::string s);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -150,10 +150,10 @@ public:
|
|||
virtual void send_color_image(std::string) {}
|
||||
virtual void send_Grey_image(std::string) {}
|
||||
|
||||
virtual void ifkp_send_image(){}
|
||||
virtual void ifkp_send_image(std::string s = ""){}
|
||||
virtual void ifkp_send_avatar(){}
|
||||
|
||||
virtual void thor_send_image(){}
|
||||
virtual void thor_send_image(std::string s = ""){}
|
||||
virtual void thor_send_avatar(){}
|
||||
|
||||
void set_stopflag(bool b) { stopflag = b;};
|
||||
|
|
|
@ -252,6 +252,7 @@ public:
|
|||
void send_avatar();
|
||||
void thor_send_avatar();
|
||||
void thor_send_image();
|
||||
void thor_send_image(std::string s = "");
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -1022,6 +1022,8 @@ void mfsk::send_epilogue()
|
|||
flush_xmt_filter(64);
|
||||
}
|
||||
|
||||
static bool close_after_transmit = false;
|
||||
|
||||
void mfsk::clearbits()
|
||||
{
|
||||
int data = enc->encode(0);
|
||||
|
@ -1137,6 +1139,8 @@ int mfsk::tx_process()
|
|||
btnpicTxSendGrey->show();
|
||||
btnpicTxLoad->show();
|
||||
btnpicTxClose->show();
|
||||
if (close_after_transmit) picTxWin->hide();
|
||||
close_after_transmit = false;
|
||||
abortxmt = false;
|
||||
rxstate = RX_STATE_DATA;
|
||||
memset(picheader, ' ', PICHEADER - 1);
|
||||
|
@ -1151,6 +1155,7 @@ int mfsk::tx_process()
|
|||
void mfsk::send_color_image(std::string s)
|
||||
{
|
||||
if (load_image(s.c_str())) {
|
||||
close_after_transmit = true;
|
||||
pic_TxSendColor();
|
||||
}
|
||||
}
|
||||
|
@ -1158,6 +1163,7 @@ void mfsk::send_color_image(std::string s)
|
|||
void mfsk::send_Grey_image(std::string s)
|
||||
{
|
||||
if (load_image(s.c_str())) {
|
||||
close_after_transmit = true;
|
||||
pic_TxSendGrey();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1892,6 +1892,74 @@ static void pTxQueIMAGE(std::string &s, size_t &i, size_t endbracket)
|
|||
s.replace(i, endbracket - i + 1, "^!");
|
||||
}
|
||||
|
||||
static void doINSERTIMAGE(std::string s)
|
||||
{
|
||||
if (s.length() > 0) {
|
||||
|
||||
bool Greyscale = false;
|
||||
size_t p = string::npos;
|
||||
string fname = s.substr(7);
|
||||
p = fname.find(">");
|
||||
fname.erase(p);
|
||||
p = fname.find("G,");
|
||||
if (p == string::npos) p = fname.find("g,");
|
||||
if (p != string::npos) {
|
||||
Greyscale = true;
|
||||
fname.erase(p,2);
|
||||
}
|
||||
while (fname[0] == ' ') fname.erase(0,1);
|
||||
if (s.empty()) return;
|
||||
|
||||
trx_mode md = active_modem->get_mode();
|
||||
if ((md == MODE_MFSK16 || md == MODE_MFSK32 ||
|
||||
md == MODE_MFSK64 || md == MODE_MFSK128) &&
|
||||
active_modem->get_cap() & modem::CAP_IMG) {
|
||||
Greyscale ?
|
||||
active_modem->send_Grey_image(fname) :
|
||||
active_modem->send_color_image(fname);
|
||||
}
|
||||
else if (md == MODE_IFKP) {
|
||||
ifkp_load_scaled_image(fname);
|
||||
}
|
||||
else if (md >= MODE_THOR_FIRST && md <= MODE_THOR_LAST)
|
||||
thor_load_scaled_image(fname);
|
||||
}
|
||||
que_ok = true;
|
||||
}
|
||||
|
||||
void TxQueINSERTIMAGE(std::string s)
|
||||
{
|
||||
trx_mode active_mode = active_modem->get_mode();
|
||||
if (! (active_mode == MODE_MFSK16 ||
|
||||
active_mode == MODE_MFSK32 ||
|
||||
active_mode == MODE_MFSK64 ||
|
||||
active_mode == MODE_MFSK128 ||
|
||||
active_mode == MODE_IFKP ||
|
||||
(active_mode >= MODE_THOR_FIRST && active_mode <= MODE_THOR_LAST) ) &&
|
||||
active_modem->get_cap() & modem::CAP_IMG)
|
||||
return;
|
||||
|
||||
string scmd = "<IMAGE:>";
|
||||
scmd.insert(7,s);
|
||||
|
||||
struct CMDS cmd = { scmd, doINSERTIMAGE };
|
||||
push_txcmd(cmd);
|
||||
|
||||
string itext = s;
|
||||
size_t p = itext.rfind("\\");
|
||||
if (p == string::npos) p = itext.rfind("/");
|
||||
if (p != string::npos) itext.erase(0, p+1);
|
||||
p = itext.rfind(".");
|
||||
if (p != string::npos) itext.erase(p);
|
||||
itext.insert(0, "\nImage: ");
|
||||
itext.append(" ^!");
|
||||
|
||||
if (active_mode == MODE_IFKP)
|
||||
ifkp_tx_text->add_text(itext);
|
||||
else
|
||||
TransmitText->add_text(itext);
|
||||
}
|
||||
|
||||
#include <float.h>
|
||||
#include "re.h"
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "fileselect.h"
|
||||
#include "qrunner.h"
|
||||
|
||||
void thor_createTxViewer();
|
||||
|
||||
Fl_Double_Window *thorpicRxWin = (Fl_Double_Window *)0;
|
||||
picture *thorpicRx = (picture *)0;
|
||||
|
@ -291,6 +292,145 @@ void thor_clear_rximage()
|
|||
// image transmit functions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void thor_load_scaled_image(std::string fname)
|
||||
{
|
||||
|
||||
if (!thorpicTxWin) thor_createTxViewer();
|
||||
|
||||
int D = 0;
|
||||
unsigned char *img_data;
|
||||
int W = 160;
|
||||
int H = 120;
|
||||
int winW = 644;
|
||||
int winH = 512;
|
||||
int thorpicX = 0;
|
||||
int thorpicY = 0;
|
||||
string picmode = "pic% \n";
|
||||
|
||||
if (thorTxImg) {
|
||||
thorTxImg->release();
|
||||
thorTxImg = 0;
|
||||
}
|
||||
|
||||
thorTxImg = Fl_Shared_Image::get(fname.c_str());
|
||||
if (!thorTxImg)
|
||||
return;
|
||||
|
||||
int iW = thorTxImg->w();
|
||||
int iH = thorTxImg->h();
|
||||
int aspect = 0;
|
||||
|
||||
if (iW > iH ) {
|
||||
if (iW >= 640) {
|
||||
W = 640; H = 480;
|
||||
winW = 644; winH = 484;
|
||||
aspect = 4;
|
||||
picmode[4] = 'V';
|
||||
}
|
||||
else if (iW >= 320) {
|
||||
W = 320; H = 240;
|
||||
winW = 324; winH = 244;
|
||||
aspect = 2;
|
||||
picmode[4] = 'L';
|
||||
}
|
||||
else {
|
||||
W = 160; H = 120;
|
||||
winW = 164; winH = 124;
|
||||
aspect = 1;
|
||||
picmode[4] = 'S';
|
||||
}
|
||||
} else {
|
||||
if (iH >= 300) {
|
||||
W = 240; H = 300;
|
||||
winW = 244; winH = 304;
|
||||
aspect = 5;
|
||||
picmode[4] = 'P';
|
||||
}
|
||||
else if (iH >= 150) {
|
||||
W = 120; H = 150;
|
||||
winW = 124; winH = 154;
|
||||
aspect = 7;
|
||||
picmode[4] = 'M';
|
||||
}
|
||||
else {
|
||||
W = 59; H = 74;
|
||||
winW = 67; winH = 82;
|
||||
aspect = 0;
|
||||
picmode[4] = 'T';
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Fl_Image *temp;
|
||||
selthorpicSize->value(aspect);
|
||||
temp = thorTxImg->copy(W, H);
|
||||
thorTxImg->release();
|
||||
thorTxImg = (Fl_Shared_Image *)temp;
|
||||
}
|
||||
|
||||
if (thorTxImg->count() > 1) {
|
||||
thorTxImg->release();
|
||||
thorTxImg = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
thorpicTx->hide();
|
||||
thorpicTx->clear();
|
||||
|
||||
img_data = (unsigned char *)thorTxImg->data()[0];
|
||||
|
||||
D = thorTxImg->d();
|
||||
|
||||
if (thorxmtimg) delete [] thorxmtimg;
|
||||
|
||||
thorxmtimg = new unsigned char [W * H * 3];
|
||||
if (D == 3)
|
||||
memcpy(thorxmtimg, img_data, W*H*3);
|
||||
else if (D == 4) {
|
||||
int i, j, k;
|
||||
for (i = 0; i < W*H; i++) {
|
||||
j = i*3; k = i*4;
|
||||
thorxmtimg[j] = img_data[k];
|
||||
thorxmtimg[j+1] = img_data[k+1];
|
||||
thorxmtimg[j+2] = img_data[k+2];
|
||||
}
|
||||
} else if (D == 1) {
|
||||
int i, j;
|
||||
for (i = 0; i < W*H; i++) {
|
||||
j = i * 3;
|
||||
thorxmtimg[j] = thorxmtimg[j+1] = thorxmtimg[j+2] = img_data[i];
|
||||
}
|
||||
} else
|
||||
return;
|
||||
|
||||
char* label = strdup(fname.c_str());
|
||||
thorpicTxWin->copy_label(basename(label));
|
||||
free(label);
|
||||
|
||||
// load the thorpicture widget with the rgb image
|
||||
|
||||
thorpicTxWin->size(winW, winH);
|
||||
thorpicX = (winW - W) / 2;
|
||||
thorpicY = (winH - H) / 2;
|
||||
thorpicTx->resize(thorpicX, thorpicY, W, H);
|
||||
|
||||
selthorpicSize->hide();
|
||||
btnthorpicTransmit->hide();
|
||||
btnthorpicTxLoad->hide();
|
||||
btnthorpicTxClose->hide();
|
||||
btnthorpicTxSendAbort->hide();
|
||||
|
||||
thorpicTx->video(thorxmtimg, W * H * 3);
|
||||
thorpicTx->show();
|
||||
|
||||
thorpicTxWin->show();
|
||||
|
||||
active_modem->thor_send_image(picmode);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int thor_load_image(const char *n) {
|
||||
|
||||
int D = 0;
|
||||
|
|
|
@ -1190,6 +1190,8 @@ void thor::flushtx()
|
|||
bitstate = 0;
|
||||
}
|
||||
|
||||
static bool hide_after_sending = false;
|
||||
|
||||
int thor::tx_process()
|
||||
{
|
||||
int i = 0;
|
||||
|
@ -1246,6 +1248,8 @@ int thor::tx_process()
|
|||
sendchar(imageheader[n], 0);
|
||||
flushtx();
|
||||
send_image();
|
||||
if (hide_after_sending) thorpicTxWin->hide();
|
||||
hide_after_sending = false;
|
||||
txstate = TX_STATE_DATA;
|
||||
break;
|
||||
case TX_STATE_AVATAR:
|
||||
|
@ -1353,10 +1357,11 @@ void thor::send_image() {
|
|||
|
||||
}
|
||||
|
||||
void thor::thor_send_image() {
|
||||
if (txstate == TX_STATE_RECEIVE) {
|
||||
void thor::thor_send_image(std::string image_str) {
|
||||
if (!image_str.empty()) hide_after_sending = true;
|
||||
imageheader = image_str;
|
||||
if (txstate == TX_STATE_RECEIVE)
|
||||
start_tx();
|
||||
}
|
||||
}
|
||||
|
||||
void thor::send_avatar()
|
||||
|
|
|
@ -764,8 +764,8 @@ void FTextRX::dxcc_tooltip(void* obj)
|
|||
Fl_Menu_Item FTextTX::menu[] = {
|
||||
{ icons::make_icon_label(_("Transmit"), tx_icon), 0, 0, 0, 0, _FL_MULTI_LABEL },
|
||||
{ icons::make_icon_label(_("Receive"), rx_icon), 0, 0, 0, 0, _FL_MULTI_LABEL },
|
||||
{ icons::make_icon_label(_("Abort"), process_stop_icon), 0, 0, 0, 0, _FL_MULTI_LABEL },
|
||||
{ icons::make_icon_label(_("Send image..."), image_icon), 0, 0, 0, FL_MENU_DIVIDER, _FL_MULTI_LABEL },
|
||||
{ icons::make_icon_label(_("Abort"), process_stop_icon), 0, 0, 0, FL_MENU_DIVIDER, _FL_MULTI_LABEL },
|
||||
{ icons::make_icon_label(_("Send image..."), image_icon), 0, 0, 0, 0, _FL_MULTI_LABEL },
|
||||
|
||||
{ 0 }, // EDIT_MENU_CUT
|
||||
{ 0 }, // EDIT_MENU_COPY
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "ascii.h"
|
||||
#include "icons.h"
|
||||
#include "gettext.h"
|
||||
#include "macros.h"
|
||||
|
||||
#include "FTextView.h"
|
||||
|
||||
|
@ -810,8 +811,33 @@ int FTextEdit::handle_dnd_drop(void)
|
|||
len -= 7;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef BUILD_FLARQ
|
||||
if ((text.find("jpg") != string::npos) ||
|
||||
(text.find("JPG") != string::npos) ||
|
||||
(text.find("jpeg") != string::npos) ||
|
||||
(text.find("JPEG") != string::npos) ||
|
||||
(text.find("png") != string::npos) ||
|
||||
(text.find("PNG") != string::npos) ||
|
||||
(text.find("bmp") != string::npos) ||
|
||||
(text.find("BMP") != string::npos) ) {
|
||||
|
||||
LOG_INFO("DnD image %s", text.c_str());
|
||||
|
||||
if ((p = text.find("file://")) != string::npos)
|
||||
text.erase(0, p + strlen("file://"));
|
||||
if ((p = text.find('\r')) != string::npos)
|
||||
text.erase(p);
|
||||
if ((p = text.find('\n')) != string::npos)
|
||||
text.erase(p);
|
||||
if (text[text.length()-1] == 0) text.erase(text.length() -1);
|
||||
TxQueINSERTIMAGE(text);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
// paste everything verbatim if we cannot read the first file
|
||||
LOG_INFO("DnD file %s", text.c_str());
|
||||
LOG_INFO("DnD file %s", text.c_str());
|
||||
if (readFile(text.c_str()) == -1 && len == text.length())
|
||||
return FTextBase::handle(FL_PASTE);
|
||||
text.erase(0, p + sizeof(sep) - 1);
|
||||
|
|