00001 #include "root.h"
00002 #include "../util.h"
00003 #include "../fileUtil.h"
00004
00005 #include <QImage>
00006 #include <QThreadPool>
00007
00008 using namespace std;
00009
00010
00011 QImage MRoot::toImage() {
00012 ASSERT( getMode()!=Clear && settings && moduleColor() && moduleShape() );
00013 return moduleColor()->planes2image();
00014 }
00015
00016 namespace NOSPACE {
00018 class ScheduledJob: public QRunnable {
00019 IShapeTransformer *worker;
00020 int job;
00021 volatile bool &errorFlag;
00022 public:
00024 ScheduledJob( IShapeTransformer *worker_, int job_, volatile bool &errorFlag_ )
00025 : worker(worker_), job(job_), errorFlag(errorFlag_) {}
00026
00028 void run() {
00029 try {
00030 worker->jobEncode(job);
00031 } catch (exception &e) {
00032 errorFlag= true;
00033 }
00034 }
00035 };
00036 }
00037 bool MRoot::encode(const QImage &toEncode,const UpdateInfo &updateInfo) {
00038 ASSERT( getMode()==Clear && settings && moduleColor() && moduleShape()
00039 && maxThreads()>=1 );
00040
00041 zoom= 0;
00042 this->width= toEncode.width();
00043 this->height= toEncode.height();
00044
00045 PlaneSettings planeProto( width, height, settingsInt(DomainCountLog2), 0
00046 , quality(), moduleQuality(), updateInfo );
00047 PlaneList planes= moduleColor()->image2planes( toEncode, planeProto );
00048 int jobCount= moduleShape()->createJobs(planes);
00049
00050 if (maxThreads()==1)
00051
00052 try {
00053 for (int i=0; i<jobCount; ++i)
00054 moduleShape()->jobEncode(i);
00055 } catch (exception &e) {
00056 return false;
00057 }
00058 else {
00059
00060 volatile bool errorFlag= false;
00061 QThreadPool jobPool;
00062 jobPool.setMaxThreadCount( maxThreads() );
00063 for (int job=0; job<jobCount; ++job)
00064 jobPool.start( new ScheduledJob(moduleShape(),job,errorFlag) );
00065 jobPool.waitForDone();
00066 if (errorFlag)
00067 return false;
00068 }
00069
00070 myMode= Encode;
00071 return true;
00072 }
00073
00074 void MRoot::decodeAct(DecodeAct action,int count) {
00075 ASSERT( getMode()!=Clear && settings && moduleColor() && moduleShape() );
00076 int jobCount= moduleShape()->jobCount();
00077 ASSERT(jobCount>0);
00078
00079 for (int i=0; i<jobCount; ++i)
00080 moduleShape()->jobDecodeAct(i,action,count);
00081 }
00082
00083 bool MRoot::toStream(std::ostream &file) {
00084 ASSERT( getMode()!=Clear && settings && moduleColor() && moduleShape() );
00085
00086 try {
00087 file.exceptions( ofstream::eofbit | ofstream::failbit | ofstream::badbit );
00088
00089 STREAM_POS(file);
00090
00091 put<Uint16>(file,Magic);
00092 put<Uint16>( file, rShift(width,zoom) );
00093 put<Uint16>( file, rShift(height,zoom) );
00094 file_saveModuleType( file, ModuleColor );
00095 file_saveModuleType( file, ModuleShape );
00096
00097 STREAM_POS(file);
00098
00099 put<Uchar>( file, settingsInt(DomainCountLog2) );
00100
00101 STREAM_POS(file);
00102 moduleColor()->writeData(file);
00103
00104 STREAM_POS(file);
00105 moduleShape()->writeSettings(file);
00106
00107 STREAM_POS(file);
00108
00109 moduleShape()->writeJobs(file);
00110
00111 STREAM_POS(file);
00112 return true;
00113 } catch(exception &e) {
00114 return false;
00115 }
00116 }
00117
00118 bool MRoot::fromStream(istream &file,int newZoom) {
00119 ASSERT( newZoom>=0 && getMode()==Clear && settings && !moduleColor() && !moduleShape() );
00120 zoom= newZoom;
00121
00122 try {
00123 file.exceptions( ifstream::eofbit | ifstream::failbit | ifstream::badbit );
00124
00125 STREAM_POS(file);
00126
00127 if (get<Uint16>(file) != Magic)
00128 return false;
00129 this->width= lShift( (int)get<Uint16>(file), zoom );
00130 this->height= lShift( (int)get<Uint16>(file), zoom );
00131 file_loadModuleType( file, ModuleColor );
00132 file_loadModuleType( file, ModuleShape );
00133
00134 STREAM_POS(file);
00135
00136 settingsInt(DomainCountLog2)= get<Uchar>(file);
00137 PlaneSettings planeProto( width, height, settingsInt(DomainCountLog2), zoom );
00138
00139 STREAM_POS(file);
00140 PlaneList planes= moduleColor()->readData(file,planeProto);
00141
00142 STREAM_POS(file);
00143 moduleShape()->readSettings(file);
00144
00145 STREAM_POS(file);
00146
00147 moduleShape()->createJobs(planes);
00148 moduleShape()->readJobs(file);
00149
00150 STREAM_POS(file);
00151 myMode= Decode;
00152 return true;
00153 } catch(exception &e) {
00154 return false;
00155 }
00156 }