00001 #include <typeinfo>
00002
00003 #include "headers.h"
00004
00005 #include "modules/root.h"
00006 #include "modules/colorModel.h"
00007 #include "modules/squarePixels.h"
00008 #include "modules/quadTree.h"
00009 #include "modules/stdDomains.h"
00010 #include "modules/quality2SE.h"
00011 #include "modules/stdEncoder.h"
00012 #include "modules/vliCodec.h"
00013 #include "modules/saupePredictor.h"
00014 #include "modules/noPredictor.h"
00015
00016 #include "fileUtil.h"
00017
00018 #include "FerrisLoki/DataGenerators.h"
00019
00020 using namespace std;
00021
00022 typedef Loki::TL::MakeTypelist< MRoot, MColorModel, MSquarePixels, MQuadTree, MStdDomains
00023 , MQuality2SE_std, MStdEncoder, MDifferentialVLICodec, MSaupePredictor, MNoPredictor
00024 , MQuality2SE_alt >
00025 ::Result Modules;
00026
00027 const int powers[31]= { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2*1024
00028 , 4*1024, 8*1024, 16*1024, 32*1024, 64*1024, 128*1024, 256*1024, 512*1024
00029 , 1024*1024, 2*1024*1024, 4*1024*1024, 8*1024*1024, 16*1024*1024, 32*1024*1024
00030 , 64*1024*1024, 128*1024*1024, 256*1024*1024, 512*1024*1024, 1024*1024*1024 };
00031
00032
00033 const bool UpdateInfo::noTerminate;
00034 const UpdateInfo UpdateInfo::none= UpdateInfo
00035 ( UpdateInfo::noTerminate, &UpdateInfo::emptyFunction, &UpdateInfo::emptyFunction );
00036
00037
00038 namespace NOSPACE {
00039 using namespace Loki;
00040 using namespace Loki::TL;
00041
00044 template <class Typelist,class Interface>
00045 struct Compatible;
00046
00047 template <class Iface>
00048 struct Compatible<NullType,Iface> {
00049 typedef NullType Result;
00050 };
00051
00052 template <class Head,class Tail,class Iface>
00053 struct Compatible< Typelist<Head,Tail> , Iface > {
00054 typedef typename Select
00055 <SuperSubclass<Iface,Head>::value
00056 ,Typelist< Head , typename Compatible<Tail,Iface>::Result >
00057 ,typename Compatible<Tail,Iface>::Result
00058 >::Result Result;
00059 };
00060
00061 template <class T> struct ExtractId {
00062 int operator()() const
00063 { return Loki::TL::IndexOf<Modules,T>::value; }
00064 };
00065 }
00066 template<class Iface> const vector<int>& Interface<Iface>::getCompMods() {
00067 using namespace Loki::TL;
00068 typedef typename Compatible<Modules,Iface>::Result CompList;
00069
00070 if ( compMods_.empty() && Length<CompList>::value ) {
00071 compMods_.reserve(Length<CompList>::value);
00072 IterateTypes<CompList,ExtractId> gendata;
00073 gendata( back_inserter(compMods_) );
00074 }
00075 return compMods_;
00076 }
00077 template <class Iface> std::vector<int> Interface<Iface>::compMods_;
00078
00079
00081 const Module::SettingTypeItem Module::SettingTypeItem
00082 ::stopper= { 0, 0, {Stop,{i:-1},{text:0}} };
00083
00084 Module::SettingItem* Module::copySettings(CloneMethod method) const {
00085 ASSERT( method==DeepCopy || method==ShallowCopy );
00086
00087 int length= info().setLength;
00088 if (!length)
00089 return 0;
00090 SettingItem *result= new SettingItem[length];
00091 copy( settings, settings+length, result );
00092
00093 SettingItem *item= result, *itemEnd= result+length;
00094 if (method==DeepCopy)
00095
00096 while (item!=itemEnd) {
00097 if (item->m)
00098 item->m= item->m->abstractClone(DeepCopy);
00099 ++item;
00100 }
00101 else
00102
00103 while (item!=itemEnd) {
00104 item->m= 0;
00105 ++item;
00106 }
00107
00108 return result;
00109 }
00110 void Module::initDefaultModuleLinks() {
00111
00112 const SettingTypeItem *setType= info().setType;
00113 for (int i=0; setType[i].type.type!=Stop; ++i )
00114 if (setType[i].type.type==ModuleCombo) {
00115
00116 ASSERT(!settings[i].m);
00117 settings[i].m= constCast(&ModuleFactory::prototype(
00118 (*setType[i].type.data.compatIDs)[settings[i].val.i]
00119 ));
00120 }
00121 }
00122 void Module::nullModuleLinks() {
00123
00124 SettingItem *itEnd= settings+info().setLength;
00125 for (SettingItem *it=settings; it!=itEnd; ++it)
00126 it->m= 0;
00127 }
00128 template<class M> M* Module::concreteClone(CloneMethod method) const {
00129 ASSERT( this && info().id == ModuleFactory::getModuleID<M>() );
00130
00131 M *result= new M;
00132 result->settings= copySettings(method);
00133 return result;
00134 }
00135
00136 void Module::createDefaultSettings() {
00137 ASSERT(!settings);
00138 const TypeInfo &inf= info();
00139 settings= new SettingItem[inf.setLength];
00140 copy( inf.setType, inf.setType+inf.setLength, settings );
00141 }
00142
00143 void Module::file_saveModuleType( ostream &os, int which ) {
00144
00145 ASSERT( which>=0 && which<info().setLength );
00146 SettingItem &setItem= settings[which];
00147 ASSERT( info().setType[which].type.type==ModuleCombo && setItem.m );
00148
00149 put<Uchar>( os, setItem.m->info().id );
00150 }
00151 void Module::file_loadModuleType( istream &is, int which ) {
00152
00153 ASSERT( which>=0 && which<info().setLength );
00154 const SettingTypeItem &setType= info().setType[which];
00155 SettingItem &setItem= settings[which];
00156 ASSERT( setType.type.type==ModuleCombo && !setItem.m );
00157
00158 int newId= get<Uchar>(is);
00159 checkThrow( 0<=newId && newId<Loki::TL::Length<Modules>::value );
00160
00161 const vector<int> &v= *setType.type.data.compatIDs;
00162 settings[which].val.i= find(v.begin(),v.end(),newId) - v.begin();
00163 checkThrow( settings[which].val.i < (int)v.size() );
00164
00165 setItem.m= ModuleFactory::newModule(newId,ShallowCopy);
00166 }
00167
00168 void Module::file_saveAllSettings(std::ostream &stream) {
00169 int setLength= info().setLength;
00170 if (!setLength)
00171 return;
00172 else
00173 ASSERT( settings && setLength>0 );
00174
00175 const SettingTypeItem *setType= info().setType;
00176 for (int i=0; i<setLength; ++i)
00177 switch(setType[i].type.type) {
00178 case Int:
00179 case IntLog2:
00180 case Combo:
00181 put<Uint32>( stream, settings[i].val.i );
00182 break;
00183 case Float:
00184 put<float>( stream, settings[i].val.f );
00185 break;
00186 case ModuleCombo:
00187 file_saveModuleType( stream, i );
00188 settings[i].m->file_saveAllSettings(stream);
00189 break;
00190 default:
00191 ASSERT(false);
00192 }
00193 }
00194
00195 void Module::file_loadAllSettings(std::istream &stream) {
00196 int setLength= info().setLength;
00197 ASSERT(setLength>=0);
00198 if (!setLength)
00199 return;
00200 if (!settings)
00201 settings= new SettingItem[setLength];
00202
00203 const SettingTypeItem *setType= info().setType;
00204 for (int i=0; i<setLength; ++i)
00205 switch(setType[i].type.type) {
00206 case Int:
00207 case IntLog2:
00208 case Combo:
00209 settings[i].val.i= get<Uint32>(stream);
00210 break;
00211 case Float:
00212 settings[i].val.f= get<float>(stream);
00213 break;
00214 case ModuleCombo:
00215 file_loadModuleType( stream, i );
00216 settings[i].m->file_loadAllSettings(stream);
00217 break;
00218 default:
00219 ASSERT(false);
00220 }
00221 }
00222
00224 ModuleFactory* ModuleFactory::instance=0;
00225
00226 template<class M> int ModuleFactory::getModuleID()
00227 { return Loki::TL::IndexOf<Modules,M>::value; }
00228
00229
00230 void ModuleFactory::initialize() {
00231
00232 ASSERT( prototypes.empty() );
00233 prototypes.reserve( Loki::TL::Length<Modules>::value );
00234 Loki::TL::IterateTypes<Modules,Creator> gendata;
00235 gendata( back_inserter(prototypes) );
00236
00237 for_each( prototypes, mem_fun(&Module::createDefaultSettings) );
00238 for_each( prototypes, mem_fun(&Module::initDefaultModuleLinks) );
00239 }
00240 void ModuleFactory::changeDefaultSettings(const Module &module) {
00241
00242 const Module::TypeInfo &mi= module.info();
00243 Module::SettingItem *protSet= prototype(mi.id).settings;
00244
00245 ASSERT( protSet && module.settings );
00246 copy( module.settings, module.settings+mi.setLength, protSet );
00247
00248 for (const Module::SettingTypeItem *setType= mi.setType
00249 ; setType->type.type!=Module::Stop; ++setType,++protSet)
00250 if ( setType->type.type==Module::ModuleCombo ) {
00251 ASSERT(protSet->m);
00252 protSet->m= constCast(&prototype( protSet->m->info().id ));
00253 }
00254 }
00255
00256
00257 template<class T> int ModuleFactory::Instantiator<T>::operator()() const {
00258 int i= getModuleID<T>();
00259 Module *m= T::newCompatibleModule();
00260 m= m->concreteClone<T>(Module::DeepCopy);
00261 i+= T::getCompMods().front();
00262 return i;
00263 }
00264 void ModuleFactory::instantiateModules() {
00265 IterateTypes<Modules,Instantiator> gendata;
00266 vector<int> v;
00267 gendata(back_inserter(v));
00268 }