1818#include " tlereader.h"
1919#include " settings.h"
2020
21+ #include " threadpool.h"
22+
2123struct ImageForSpread {
2224 ImageForSpread (cv::Mat img, std::string fileNamebase)
2325 : image(img)
@@ -34,6 +36,7 @@ int mean(int cur, int prev);
3436void differentialDecode (int8_t *data, int64_t len);
3537int8_t clamp (float x);
3638
39+ static std::mutex saveImageMutex;
3740
3841static uint16_t intSqrtTable[32768 ];
3942
@@ -72,6 +75,7 @@ static Viterbi mViterbi;
7275static PacketParser mPacketParser ;
7376static ReedSolomon mReedSolomon ;
7477static Settings &mSettings = Settings::getInstance();
78+ static ThreadPool mThreadPool (std::thread::hardware_concurrency());
7579
7680int main (int argc, char *argv[])
7781{
@@ -84,6 +88,7 @@ int main(int argc, char *argv[])
8488 mSettings .parseArgs (argc, argv);
8589 mSettings .parseIni (mSettings .getResourcesPath () + " settings.ini" );
8690
91+ mThreadPool .start ();
8792 TleReader reader (mSettings .getTlePath ());
8893 TleReader::TLE tle;
8994 reader.processFile ();
@@ -291,11 +296,15 @@ int main(int argc, char *argv[])
291296 }
292297
293298 } else if (mPacketParser .isChannel64Available () && mPacketParser .isChannel65Available () && mPacketParser .isChannel66Available ()) {
294- cv::Mat threatedImage = mPacketParser .getRGBImage (PacketParser::APID_66 , PacketParser::APID_65 , PacketParser::APID_64 , mSettings .fillBackLines ());
299+ cv::Mat threatedImage1 = mPacketParser .getRGBImage (PacketParser::APID_66 , PacketParser::APID_65 , PacketParser::APID_64 , mSettings .fillBackLines ());
300+ cv::Mat threatedImage2 = mPacketParser .getRGBImage (PacketParser::APID_65 , PacketParser::APID_65 , PacketParser::APID_64 , mSettings .fillBackLines ());
295301
296- if (!ThreatImage::isNightPass (threatedImage, mSettings .getNightPassTreshold ())) {
297- imagesToSpread.push_back (ImageForSpread (threatedImage, " 123_" ));
298- saveImage (mSettings .getOutputPath () + fileNameDate + " _123.bmp" , threatedImage);
302+ if (!ThreatImage::isNightPass (threatedImage1, mSettings .getNightPassTreshold ())) {
303+ imagesToSpread.push_back (ImageForSpread (threatedImage1, " 321_" ));
304+ saveImage (mSettings .getOutputPath () + fileNameDate + " _321.bmp" , threatedImage1);
305+
306+ imagesToSpread.push_back (ImageForSpread (threatedImage2, " 221_" ));
307+ saveImage (mSettings .getOutputPath () + fileNameDate + " _221.bmp" , threatedImage2);
299308 } else {
300309 std::cout << " Night pass, RGB image skipped, threshold set to: " << mSettings .getNightPassTreshold () << std::endl;
301310 }
@@ -306,7 +315,7 @@ int main(int argc, char *argv[])
306315
307316 cv::Mat ch64 = mPacketParser .getChannelImage (PacketParser::APID_64 , mSettings .fillBackLines ());
308317 cv::Mat ch65 = mPacketParser .getChannelImage (PacketParser::APID_65 , mSettings .fillBackLines ());
309- cv::Mat ch66 = mPacketParser .getChannelImage (PacketParser::APID_68 , mSettings .fillBackLines ());
318+ cv::Mat ch66 = mPacketParser .getChannelImage (PacketParser::APID_66 , mSettings .fillBackLines ());
310319
311320 saveImage (mSettings .getOutputPath () + fileNameDate + " _64.bmp" , ch64);
312321 saveImage (mSettings .getOutputPath () + fileNameDate + " _65.bmp" , ch65);
@@ -346,61 +355,68 @@ int main(int argc, char *argv[])
346355 return 0 ;
347356 }
348357
349- SpreadImage spreadImage;
350358 std::ostringstream oss;
351359 oss << std::setfill (' 0' ) << std::setw (2 ) << passStart.Day () << " /" << std::setw (2 ) << passStart.Month () << " /" << passStart.Year () << " " << std::setw (2 ) << passStart.Hour () << " :" << std::setw (2 ) << passStart.Minute () << " :" << std::setw (2 ) << passStart.Second () << " UTC" ;
352360 std::string dateStr = oss.str ();
353361
354362 std::list<ImageForSpread>::const_iterator it;
355-
356- int c = 1 ;
357- for (it = imagesToSpread.begin (); it != imagesToSpread.end (); ++it, c++) {
363+ for (it = imagesToSpread.begin (); it != imagesToSpread.end (); ++it) {
358364 std::string fileName = (*it).fileNameBase + fileNameDate + " ." + mSettings .getOutputFormat ();
359365
360366 if (mSettings .spreadImage ()) {
361- cv::Mat strechedImg = spreadImage.stretch ((*it).image );
362-
363- if (!strechedImg.empty ()) {
364- ThreatImage::drawWatermark (strechedImg, dateStr);
365- saveImage (mSettings .getOutputPath () + std::string (" spread_" ) + fileName, strechedImg);
366- } else {
367- std::cout << " Failed to strech image" << std::endl;
368- }
367+ mThreadPool .addJob ([=]() {
368+ SpreadImage spreadImage;
369+ cv::Mat strechedImg = spreadImage.stretch ((*it).image );
370+
371+ if (!strechedImg.empty ()) {
372+ ThreatImage::drawWatermark (strechedImg, dateStr);
373+ saveImage (mSettings .getOutputPath () + std::string (" spread_" ) + fileName, strechedImg);
374+ } else {
375+ std::cout << " Failed to strech image" << std::endl;
376+ }
377+ });
369378 }
370379
371380 if (mSettings .mercatorProjection ()) {
372- cv::Mat mercator = spreadImage.mercatorProjection ((*it).image , calc, [c, &imagesToSpread](float percent) {
373- std::cout << " Spreading mercator " << c << " of " << imagesToSpread.size () << " " << static_cast <int >(percent) << " %\t\t\r " << std::flush;
381+ mThreadPool .addJob ([=]() {
382+ SpreadImage spreadImage;
383+ cv::Mat mercator = spreadImage.mercatorProjection ((*it).image , calc);
384+
385+ if (!mercator.empty ()) {
386+ ThreatImage::drawWatermark (mercator, dateStr);
387+ saveImage (mSettings .getOutputPath () + std::string (" mercator_" ) + fileName, mercator);
388+ } else {
389+ std::cout << " Failed to create mercator projection" << std::endl;
390+ }
374391 });
375- std::cout << std::endl;
376-
377- if (!mercator.empty ()) {
378- ThreatImage::drawWatermark (mercator, dateStr);
379- saveImage (mSettings .getOutputPath () + std::string (" mercator_" ) + fileName, mercator);
380- } else {
381- std::cout << " Failed to create mercator projection" << std::endl;
382- }
383392 }
384393
385394 if (mSettings .equadistantProjection ()) {
386- cv::Mat equidistant = spreadImage.equidistantProjection ((*it).image , calc, [c, &imagesToSpread](float percent) {
387- std::cout << " Spreading equidistant " << c << " of " << imagesToSpread.size () << " " << static_cast <int >(percent) << " %\t\t\r " << std::flush;
395+ mThreadPool .addJob ([=]() {
396+ SpreadImage spreadImage;
397+ cv::Mat equidistant = spreadImage.equidistantProjection ((*it).image , calc);
398+
399+ if (!equidistant.empty ()) {
400+ ThreatImage::drawWatermark (equidistant, dateStr);
401+ saveImage (mSettings .getOutputPath () + std::string (" equidistant_" ) + fileName, equidistant);
402+ } else {
403+ std::cout << " Failed to create equidistant projection" << std::endl;
404+ }
388405 });
389- std::cout << std::endl;
390-
391- if (!equidistant.empty ()) {
392- ThreatImage::drawWatermark (equidistant, dateStr);
393- saveImage (mSettings .getOutputPath () + std::string (" equidistant_" ) + fileName, equidistant);
394- } else {
395- std::cout << " Failed to create equidistant projection" << std::endl;
396- }
397406 }
398407 }
408+
409+ std::cout << " Generate images" << std::endl;
410+ mThreadPool .stop ();
411+ std::cout << " Generate images done" << std::endl;
412+
399413 return 0 ;
400414}
401415
402416void saveImage (const std::string fileName, const cv::Mat &image)
403417{
418+ std::unique_lock<decltype (saveImageMutex)>lock (saveImageMutex);
419+
404420 std::vector<int > compression_params;
405421 compression_params.push_back (cv::IMWRITE_JPEG_QUALITY );
406422 compression_params.push_back (mSettings .getJpegQuality ());
0 commit comments