Fixed wrong prediction for incomplete ranges.
[fic.git] / modules / squarePixels.cpp
blob9ccb4f18ca1d15351e01cd36fee7371c90d1b071
1 #include "squarePixels.h"
2 #include "../fileUtil.h"
4 using namespace std;
6 int MSquarePixels::createJobs(const PlaneList &planes) {
7 ASSERT( jobs.empty() && !planes.empty()
8 && moduleRanges() && moduleDomains() && moduleEncoder() );
9 DEBUG_ONLY( planeList= planes; )
11 for (PlaneList::const_iterator plane= planes.begin(); plane!=planes.end(); ++plane) {
12 // convert the Plane into a PlaneBlock (containing the whole contents)
13 const IColorTransformer::PlaneSettings *plSet= plane->settings;
14 PlaneBlock job;
15 job.width= plSet->width;
16 job.height= plSet->height;
17 job.pixels= plane->pixels;
18 job.sumsValid= false;
19 job.settings= plSet;
20 DEBUG_ONLY( job.ranges= 0; job.domains= 0; job.encoder= 0; )
21 // append the result to the jobs
22 jobs.push_back(job);
25 // the zoom only affects maxPixels (zoom is assumed to be the same for all planes)
26 int maxPixels= powers[maxPartSize()+2*jobs.front().settings->zoom];
27 // split jobs until they're small enough
28 Uint i= 0;
29 while ( i < jobs.size() )
30 if ( jobs[i].width*jobs[i].height <= maxPixels )
31 ++i; // the part is small enough, move on
32 else { // divide the job
33 // splitting the longer coordinate
34 bool xdiv= ( jobs[i].width >= jobs[i].height );
35 int longer= ( xdiv ? jobs[i].width : jobs[i].height );
36 // get the place to split (at least one of the parts will have size 2^q)
37 int bits= log2ceil(longer);
38 int divSize= ( longer >= powers[bits-1]+powers[bits-2]
39 ? powers[bits-1]
40 : powers[bits-2] );
41 // split the job (reusing the splitted-one's space and appending the second one)
42 jobs.push_back(jobs[i]);
43 if (xdiv) {
44 jobs[i].width= divSize; // reducing the width of the first job
45 jobs.back().pixels.shiftMatrix(divSize,0); // shifting the second job
46 jobs.back().width-= divSize; // reducing the width of the second job
47 } else {
48 jobs[i].height= divSize; // reducing the height of the first job
49 jobs.back().pixels.shiftMatrix(0,divSize); // shifting the second job
50 jobs.back().height-= divSize; // reducing the height of the second job
54 // create the modules in the jobs by cloning those from module's settings
55 for (JobIterator job=jobs.begin(); job!=jobs.end(); ++job) {
56 job->ranges= moduleRanges() ->clone();
57 job->domains= moduleDomains()->clone();
58 job->encoder= moduleEncoder()->clone();
61 return jobs.size();
64 void MSquarePixels::writeSettings(ostream &file) {
65 ASSERT( moduleRanges() && moduleDomains() && moduleEncoder() );
66 // put settings and ID's of child modules
67 put<Uchar>( file, maxPartSize() );
68 file_saveModuleType( file, ModuleRanges );
69 file_saveModuleType( file, ModuleDomains );
70 file_saveModuleType( file, ModuleEncoder );
71 // put settings of child modules
72 moduleRanges()->writeSettings(file);
73 moduleDomains()->writeSettings(file);
74 moduleEncoder()->writeSettings(file);
77 void MSquarePixels::readSettings(istream &file) {
78 ASSERT( !moduleRanges() && !moduleDomains() && !moduleEncoder() );
79 // get settings and create the right child modules
80 maxPartSize()= get<Uchar>(file);
81 file_loadModuleType( file, ModuleRanges );
82 file_loadModuleType( file, ModuleDomains );
83 file_loadModuleType( file, ModuleEncoder );
84 // get settings of child modules
85 moduleRanges()->readSettings(file);
86 moduleDomains()->readSettings(file);
87 moduleEncoder()->readSettings(file);
90 void MSquarePixels::writeJobs(ostream &file,int phaseBegin,int phaseEnd) {
91 ASSERT( !jobs.empty() && 0<=phaseBegin && phaseBegin<phaseEnd && phaseEnd<=phaseCount() );
92 // if writing phase 0, for each job: write data of domain and range modules
93 if (!phaseBegin)
94 for (JobIterator it=jobs.begin(); it!=jobs.end(); ++it) {
95 STREAM_POS(file);
96 it->ranges->writeData(file);
97 STREAM_POS(file);
98 it->domains->writeData(file);
100 // write all the requested phases of all jobs (phase-sequentially)
101 for (int phase=phaseBegin; phase<phaseEnd; ++phase)
102 for (JobIterator it=jobs.begin(); it!=jobs.end(); ++it)
103 STREAM_POS(file), it->encoder->writeData(file,phase);
106 void MSquarePixels::readJobs(istream &file,int phaseBegin,int phaseEnd) {
107 ASSERT( !jobs.empty() && 0<=phaseBegin && phaseBegin<phaseEnd && phaseEnd<=phaseCount() );
108 // if reading phase 0, for each job: read data of domain and range modules
109 if (!phaseBegin)
110 for (JobIterator it=jobs.begin(); it!=jobs.end(); ++it) {
111 STREAM_POS(file);
112 it->ranges->readData_buildRanges(file,*it);
113 STREAM_POS(file);
114 it->domains->readData(file);
115 it->encoder->initialize(IRoot::Decode,*it);
117 // read all the requested phases of all jobs (phase-sequentially)
118 for (int phase=phaseBegin; phase<phaseEnd; ++phase)
119 for (JobIterator it=jobs.begin(); it!=jobs.end(); ++it)
120 STREAM_POS(file), it->encoder->readData(file,phase);