From 67d9875195847dd973175038d6a303477efbaf62 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Vladim=C3=ADr=20=C4=8Cun=C3=A1t?= Date: Mon, 27 Apr 2009 11:00:54 +0200 Subject: [PATCH] Fixed encoding progress updating. --- gui.cpp | 1 - gui.h | 24 ++++++++++++++---------- interfaces.cpp | 4 ++-- interfaces.h | 24 ++++++++++++------------ modules.cpp | 13 ++++++++----- modules.h | 25 ++++++++++++++++--------- modules/colorModel.cpp | 18 +++++++++++------- modules/colorModel.h | 3 +-- util.h | 12 ++++++------ 9 files changed, 70 insertions(+), 54 deletions(-) diff --git a/gui.cpp b/gui.cpp index 1959268..dda235b 100644 --- a/gui.cpp +++ b/gui.cpp @@ -294,7 +294,6 @@ void ImageViewer::load() { bool error= !file2string( fname.toStdString().c_str(), decData ); if (!error) { stringstream stream(decData); - error= !modules_encoding->fromStream( stream, zoom ); } diff --git a/gui.h b/gui.h index 4982155..34f7b0e 100644 --- a/gui.h +++ b/gui.h @@ -201,7 +201,8 @@ class EncodingProgress: public QProgressDialog { Q_OBJECT static EncodingProgress *instance; ///< Pointer to the single instance of the class bool terminate /// Value indicating whether the encoding should be interrupted - , needUpdate; + , updateMaxProgress + , updateProgress; int progress /// The progress of the encoding - "the number of pixels encoded" , maxProgress; ///< The maximum value of progress @@ -216,12 +217,12 @@ private: /** Sets the maximum progress (the value corresponding to 100%) */ static void incMaxProgress(int increment) { instance->maxProgress+= increment; - instance->needUpdate= true; + instance->updateMaxProgress= true; } /** Increase the progress by a value */ static void incProgress(int increment) { instance->progress+= increment; - instance->needUpdate= true; + instance->updateProgress= true; } // TODO: Should we provide a thread-safe version? // q_atomic_fetch_and_add_acquire_int(&instance->progress,increment); @@ -233,17 +234,20 @@ private slots: { terminate= true; } /** Updating slot - called regularly by a timer */ void update() { - if (!needUpdate) - return; - needUpdate= false; - setMaximum(maxProgress); - setValue(progress); + if (updateMaxProgress) { + setMaximum(maxProgress); + updateMaxProgress= false; + } + if (updateProgress) { + setValue(progress); + updateProgress= false; + } } private: /** Creates and initializes the dialog */ EncodingProgress(ImageViewer *parent) : QProgressDialog( tr("Encoding..."), tr("Cancel"), 0, 100, parent, Qt::Dialog ) - , terminate(false), needUpdate(false) + , terminate(false), updateMaxProgress(false), updateProgress(false) , progress(0), maxProgress(0) , modules_encoding(parent->modules_settings->clone()) , updateInfo( terminate, &incMaxProgress, &incProgress ), updateTimer(this) @@ -258,7 +262,7 @@ private: aConnect( this, SIGNAL(canceled()), this, SLOT(setTerminate()) ); // start the updating timer aConnect( &updateTimer, SIGNAL(timeout()), this, SLOT(update()) ); - updateTimer.start(500); + updateTimer.start(1000); encTime.start(); // start measuring the time // start the encoding thread, set it to call ImageViewer::encDone when finished aConnect( &encThread, SIGNAL(finished()), parent, SLOT(encDone()) ); diff --git a/interfaces.cpp b/interfaces.cpp index 0d31da1..5e5ee55 100644 --- a/interfaces.cpp +++ b/interfaces.cpp @@ -8,7 +8,7 @@ bool IRoot::allSettingsToFile(const char *fileName) { ofstream file( fileName, ios_base::binary|ios_base::trunc|ios_base::out ); file.exceptions( ifstream::eofbit | ifstream::failbit | ifstream::badbit ); put( file, SettingsMagic ); - saveAllSettings(file); + file_saveAllSettings(file); return true; } catch(exception &e) { return false; @@ -22,7 +22,7 @@ bool IRoot::allSettingsFromFile(const char *fileName) { file.exceptions( ifstream::eofbit | ifstream::failbit | ifstream::badbit ); if (get(file)!=SettingsMagic) return false; - loadAllSettings(file); + file_loadAllSettings(file); return true; } catch(exception &e) { return false; diff --git a/interfaces.h b/interfaces.h index c77db53..565a8e6 100644 --- a/interfaces.h +++ b/interfaces.h @@ -17,10 +17,9 @@ struct IIntCodec; /** Contains basic types frequently used in modules */ namespace MTypes { - typedef double Real; ///< The floating-point type in which most computations are made - typedef float SReal; ///< The floating-point type for long-term pixel-value storage + typedef double Real; ///< The floating-point type in which most computations are made + typedef float SReal; ///< The floating-point type for long-term pixel-value storage - //typedef MatrixSummer BlockSummer; ///< Summer instanciation used for pixels typedef MatrixSlice SMatrix; typedef SMatrix::Const CSMatrix; typedef std::vector MatrixList; @@ -59,8 +58,9 @@ struct IRoot: public Interface { /** Saves current decoding state into a QImage */ virtual QImage toImage() =0; - /** Encodes an image - returns false on exception */ - virtual bool encode(const QImage &toEncode,const UpdateInfo &updateInfo=UpdateInfo()) =0; + /** Encodes an image - returns false on exception, getMode() have to be to be Clear */ + virtual bool encode + ( const QImage &toEncode, const UpdateInfo &updateInfo=UpdateInfo::none ) =0; /** Performs a decoding action (e.g.\ clearing, multiple iteration) */ virtual void decodeAct( DecodeAct action, int count=1 ) =0; @@ -94,8 +94,6 @@ struct IColorTransformer: public Interface { /** Contains some setings for one color plane of an image */ struct PlaneSettings { typedef IQuality2SquareError ModuleQ2SE; - - //static const PlaneSettings Empty; ///< an empty instance int width /// the width of the image (zoomed) , height /// the height of the image (zoomed) @@ -103,12 +101,12 @@ struct IColorTransformer: public Interface { , zoom; ///< the zoom (dimensions multiplied by 2^zoom) SReal quality; ///< encoding quality for the plane, in [0,1] (higher is better) ModuleQ2SE *moduleQ2SE; ///< pointer to the module computing maximum SE (not owned) - UpdateInfo updateInfo; ///< structure for communication with user + const UpdateInfo &updateInfo; ///< structure for communication with user /** A simple constructor, only initializes the values from the parameters */ PlaneSettings( int width_, int height_, int domainCountLog2_, int zoom_ , SReal quality_=numeric_limits::quiet_NaN() - , ModuleQ2SE *moduleQ2SE_=0, const UpdateInfo &updateInfo_=UpdateInfo() ) + , ModuleQ2SE *moduleQ2SE_=0, const UpdateInfo &updateInfo_=UpdateInfo::none ) : width(width_), height(height_) , domainCountLog2(domainCountLog2_), zoom(zoom_) , quality(quality_), moduleQ2SE(moduleQ2SE_), updateInfo(updateInfo_) {} @@ -122,7 +120,8 @@ struct IColorTransformer: public Interface { /** List of planes, in returned vectors the pointed to memory is owned by the module */ typedef std::vector PlaneList; - /** Splits an image into color-planes and adjusts their settings (from \p prototype) */ + /** Splits an image into color-planes and adjusts their settings (from \p prototype). + * It should call UpdateInfo::incMaxProgress with the total pixel count. */ virtual PlaneList image2planes(const QImage &toEncode,const PlaneSettings &prototype) =0; /** Merges planes back into a color image (only useful when decoding) */ virtual QImage planes2image() =0; @@ -191,7 +190,7 @@ struct ISquareRanges: public Interface { struct RangeNode: public Block { /** A common base type for data stored by encoders */ struct EncoderData { - float bestSE; + float bestSE; ///< the best square error found until now }; /** Encoders can store their data here, !not deleted! (use BulkAllocator) */ @@ -209,7 +208,8 @@ struct ISquareRanges: public Interface { }; // RangeNode struct typedef std::vector RangeList; - /** Starts encoding, calls modules in the passed structure */ + /** Starts encoding, calls modules in the passed structure. + * It should update UpdateInfo continually by the count of encoded pixels. */ virtual void encode(const PlaneBlock &toEncode) =0; /** Returns a reference to the current range-block list */ virtual const RangeList& getRangeList() const =0; diff --git a/modules.cpp b/modules.cpp index a40488d..bfadca9 100644 --- a/modules.cpp +++ b/modules.cpp @@ -27,7 +27,11 @@ const int powers[31]= { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2*1024 /* , 1024*1024, 2*1024*1024, 4*1024*1024, 8*1024*1024, 16*1024*1024, 32*1024*1024 /* 2^25 */ , 64*1024*1024, 128*1024*1024, 256*1024*1024, 512*1024*1024, 1024*1024*1024 }; /* 2^30 */ + const bool UpdateInfo::noTerminate; +const UpdateInfo UpdateInfo::none= UpdateInfo + ( UpdateInfo::noTerminate, &UpdateInfo::emptyFunction, &UpdateInfo::emptyFunction ); + namespace NOSPACE { using namespace Loki; @@ -159,7 +163,7 @@ void Module::file_loadModuleType( istream &is, int which ) { setItem.m= ModuleFactory::newModule(newId,ShallowCopy); } -void Module::saveAllSettings(std::ostream &stream) { +void Module::file_saveAllSettings(std::ostream &stream) { int setLength= info().setLength; if (!setLength) return; @@ -179,14 +183,14 @@ void Module::saveAllSettings(std::ostream &stream) { break; case ModuleCombo: file_saveModuleType( stream, i ); - settings[i].m->saveAllSettings(stream); + settings[i].m->file_saveAllSettings(stream); break; default: ASSERT(false); } // switch } -void Module::loadAllSettings(std::istream &stream) { +void Module::file_loadAllSettings(std::istream &stream) { int setLength= info().setLength; ASSERT(setLength>=0); if (!setLength) @@ -207,7 +211,7 @@ void Module::loadAllSettings(std::istream &stream) { break; case ModuleCombo: file_loadModuleType( stream, i ); - settings[i].m->loadAllSettings(stream); + settings[i].m->file_loadAllSettings(stream); break; default: ASSERT(false); @@ -220,7 +224,6 @@ ModuleFactory* ModuleFactory::instance=0; template int ModuleFactory::getModuleID() { return Loki::TL::IndexOf::value; } -template int ModuleFactory::getModuleID(); void ModuleFactory::initialize() { // create one instance of each module-type diff --git a/modules.h b/modules.h index 0d5dda4..c4b91e2 100644 --- a/modules.h +++ b/modules.h @@ -108,11 +108,7 @@ protected: virtual Module* abstractClone(CloneMethod method) const =0; /** Concrete cloning method - templated by the actual type of the module */ template M* concreteClone(CloneMethod method) const; - - /** Saves all the settings, icluding child modules */ - void saveAllSettings(std::ostream &stream); - /** Loads all the settings, icluding child modules (and their settings) */ - void loadAllSettings(std::istream &stream); + public: /** Deletes the settings, destroying child modules as well */ virtual ~Module() @@ -141,6 +137,10 @@ protected: // Other methods protected: + /** Saves all the settings, icluding child modules */ + void file_saveAllSettings(std::ostream &stream); + /** Loads all the settings, icluding child modules (and their settings) */ + void file_loadAllSettings(std::istream &stream); /** Puts a module-identifier in a stream (\p which is the index in settings) */ void file_saveModuleType( std::ostream &os, int which ); /** Gets an module-identifier from the stream, initializes the pointer in settings @@ -203,6 +203,8 @@ protected: }; // Module class +//// Macros for easier Module-writing + #define DECLARE_TypeInfo_helper(CNAME_,NAME_,DESC_,SETTYPE_...) \ friend class Module; /* Needed for concreteClone */ \ /*friend class ModuleFactory;*/ \ @@ -221,14 +223,19 @@ public: \ setType: setType_ \ }; \ return info_; \ - } \ + } + +/** Declares technical stuff within a Module descendant that contains no settings + * - parameters: the name of the class (Token), + * the name of the module ("Name"), some description ("Desc...") */ +#define DECLARE_TypeInfo_noSettings(CNAME_,NAME_,DESC_) \ + DECLARE_TypeInfo_helper(CNAME_,NAME_,DESC_,SettingTypeItem::stopper) -/** Macros for easier Module-writing */ +/** Like DECLARE_TypeInfo_noSettings, but for a module containing settings + * - additional parameter: an array of SettingTypeItem */ #define DECLARE_TypeInfo(CNAME_,NAME_,DESC_,SETTYPE_...) \ DECLARE_TypeInfo_helper(CNAME_,NAME_,DESC_,SETTYPE_,SettingTypeItem::stopper) -#define DECLARE_TypeInfo_noSettings(CNAME_,NAME_,DESC_) \ - DECLARE_TypeInfo_helper(CNAME_,NAME_,DESC_,SettingTypeItem::stopper) /** A singleton factory class for creating modules */ diff --git a/modules/colorModel.cpp b/modules/colorModel.cpp index d705489..7955654 100644 --- a/modules/colorModel.cpp +++ b/modules/colorModel.cpp @@ -26,7 +26,7 @@ MColorModel::PlaneList MColorModel int width= image.width(), height= image.height(); ownedPlanes= createPlanes(IRoot::Encode,prototype); // get the correct coefficients and plane count - const Real (*coeffs)[4]= (colorModel() ? YCbCrCoeffs : RGBCoeffs); + const Real (*coeffs)[4]= ( settingsInt(ColorModel) ? YCbCrCoeffs : RGBCoeffs); int planeCount= ownedPlanes.size(); // fill pixels in all planes for (int i=0; i=0 && colorModel()=0 && settingsInt(ColorModel)(file); - checkThrow( 0<=colorModel() && colorModel()(file); + checkThrow( 0<=settingsInt(ColorModel) && settingsInt(ColorModel)( file, colorModel() ); } + { put( file, settingsInt(ColorModel) ); } PlaneList readData(std::istream &file,const PlaneSettings &prototype); /// @} private: diff --git a/util.h b/util.h index ec63c67..8a28aef 100644 --- a/util.h +++ b/util.h @@ -173,20 +173,20 @@ public: /** Structure providing support for progress update and interruption (used for encoding) */ struct UpdateInfo { typedef void (*IncInt)(int increment); ///< Type for used functions -> more readable code + + static void emptyFunction(int) {} ///< does nothing, default for IncInt functions + static const bool noTerminate= false; ///< default for #terminate, defined in modules.cpp + static const UpdateInfo none; ///< empty UpdateInfo instance, in modules.cpp volatile const bool *terminate; ///< true if the action should be terminated IncInt incMaxProgress /// function for increasing the maximum progress (100%) , incProgress; ///< function for increasing the current progress - static void emptyFunction(int) {} ///< does nothing, default for IncInt functions - static const bool noTerminate= false; ///< default for #terminate, defined in modules.cpp - /** Initializes the structure from supplied parametres */ - UpdateInfo( const bool &terminate_= noTerminate, IncInt incMaxProgress_= &emptyFunction - , IncInt incProgress_= &emptyFunction ) + UpdateInfo( const bool &terminate_, IncInt incMaxProgress_, IncInt incProgress_ ) : terminate(&terminate_), incMaxProgress(incMaxProgress_), incProgress(incProgress_) { ASSERT(isValid()); } - + bool isValid() const { return terminate && incMaxProgress && incProgress; } }; -- 2.11.4.GIT