1 #ifndef INTERFACES_HEADER_
2 #define INTERFACES_HEADER_
4 /* Forwards for interfaces */
7 struct IColorTransformer
;
8 struct IShapeTransformer
;
11 struct ISquareDomains
;
12 struct IStdEncPredictor
;
15 /** Contains basic types frequently used in modules */
17 typedef double Real
; ///< The floating-point type in which most computations are made
18 typedef float SReal
; ///< The floating-point type for long-term pixel-value storage
20 typedef MatrixSlice
<SReal
> SMatrix
; ///< Used for storing pixel matrices
21 typedef SMatrix::Const CSMatrix
; ///< Used for passing constant pixels
22 typedef std::vector
<SMatrix
> MatrixList
; ///< A list of pixel matrices
24 enum DecodeAct
{ Clear
, Iterate
}; ///< Possible decoding actions
25 // \todo name clash, etc.
27 struct PlaneBlock
; // declared and described later in the file
29 typedef SummedMatrix
<Real
,SReal
> SummedPixels
;
33 using namespace MTypes
;
38 /** \defgroup interfaces Interfaces for coding modules
41 /** Interface for root modules (with only one implementation MRoot),
42 * all modules are always owned (either directly or indirectly) by one of this type */
43 struct IRoot
: public Interface
<IRoot
> {
44 /** The root can be in any of these modes */
46 Clear
, ///< no action has been done
47 Encode
, ///< contains an encoded image
48 Decode
///< contains an image decoded from a file
51 static const Uint16 Magic
= 65535-4063 /// magic number - integer identifying FIC files
52 , SettingsMagic
= Magic
^12345; ///< magic number - integer identifying settings files
54 /** A status-query method */
55 virtual Mode
getMode() =0;
56 /** Saves current decoding state into a QImage */
57 virtual QImage
toImage() =0;
59 /** Encodes an image - returns false on exception, getMode() have to be to be Clear */
61 ( const QImage
&toEncode
, const UpdateInfo
&updateInfo
=UpdateInfo::none
) =0;
62 /** Performs a decoding action (e.g.\ clearing, multiple iteration) */
63 virtual void decodeAct( DecodeAct action
, int count
=1 ) =0;
65 /** Saves an encoded image into a stream, returns true on success */
66 virtual bool toStream(std::ostream
&file
) =0;
67 /** Loads image from a file - returns true on success (to be run on in Clear state),
68 * can load in bigger size: dimension == orig_dim*2^\p zoom */
69 virtual bool fromStream(std::istream
&file
,int zoom
=0) =0;
71 /** Shorthand: saves an encoded image to a file - returns the number of bytes written
72 * or \p false on failure */
73 int toFile(const char *fileName
) {
74 std::ofstream
file( fileName
, ios_base::binary
|ios_base::trunc
|ios_base::out
);
75 if ( !toStream(file
) )
80 /** Shorthand: loads image from a file - returns true on success, see ::fromStream */
81 bool fromFile(const char *fileName
,int zoom
=0) {
82 std::ifstream
file( fileName
, ios_base::binary
|ios_base::in
);
83 return fromStream(file
,zoom
);
86 /** Saves all settings to a file (incl.\ child modules), returns true on success */
87 bool allSettingsToFile(const char *fileName
);
88 /** Loads all settings from a file (to be run on a shallow module), returns true on success */
89 bool allSettingsFromFile(const char *fileName
);
95 /** Interface for modules deciding how the max.\ SE will depend on block size
96 * (parametrized by quality) */
97 struct IQuality2SE
: public Interface
<IQuality2SE
> {
98 /** Returns maximum SE for a [0,1] quality and range blocks with pixelCount pixels */
99 virtual float rangeSE(float quality
,int pixelCount
) =0;
100 /** Fills an array (until levelEnd) with SE's according to [0,1] quality
101 * : on i-th index for "complete square range blocks" of level i.
102 * Common implementation - uses ::rangeSE method */
103 void regularRangeErrors(float quality
,int levelEnd
,float *squareErrors
);
109 /** Interface for modules performing color transformations,
110 * following modules always work with single-color (greyscale) images */
111 struct IColorTransformer
: public Interface
<IColorTransformer
> {
112 /** Contains some setings for one color plane of an image */
113 struct PlaneSettings
;
115 /** Represents a one-color image, together with some setttings.
116 * In returned instances the pointed-to memory is always owned by this module. */
118 mutable SMatrix pixels
; ///< a matrix of pixels with values in [0,1]
119 const PlaneSettings
*settings
; ///< the settings for the plane
122 /** List of planes (the pointed-to memory is owned by the module) */
123 typedef std::vector
<Plane
> PlaneList
;
125 /** Splits an image into color-planes and adjusts their settings (from \p prototype).
126 * It should call UpdateInfo::incMaxProgress with the total pixel count. */
127 virtual PlaneList
image2planes(const QImage
&toEncode
,const PlaneSettings
&prototype
) =0;
128 /** Merges planes back into a color image (only useful when decoding) */
129 virtual QImage
planes2image() =0;
131 /** Writes any data needed for plane reconstruction to a stream */
132 virtual void writeData(std::ostream
&file
) =0;
133 /** Reads any data needed for plane reconstruction from a stream and creates the plane list */
134 virtual PlaneList
readData( std::istream
&file
, const PlaneSettings
&prototype
) =0;
135 }; // IColorTransformer interface
137 struct IColorTransformer::PlaneSettings
{
138 int width
/// the width of the image (zoomed)
139 , height
/// the height of the image (zoomed)
140 , domainCountLog2
/// 2-logarithm of the maximum domain count
141 , zoom
; ///< the zoom (dimensions multiplied by 2^zoom)
142 SReal quality
; ///< encoding quality for the plane, in [0,1] (higher is better)
143 IQuality2SE
*moduleQ2SE
; ///< pointer to the module computing maximum SE (never owned)
144 const UpdateInfo
&updateInfo
; ///< structure for communication with user
146 /** A simple constructor, only initializes the values from the parameters */
147 PlaneSettings( int width_
, int height_
, int domainCountLog2_
, int zoom_
148 , SReal quality_
=numeric_limits
<SReal
>::quiet_NaN()
149 , IQuality2SE
*moduleQ2SE_
=0, const UpdateInfo
&updateInfo_
=UpdateInfo::none
)
150 : width(width_
), height(height_
)
151 , domainCountLog2(domainCountLog2_
), zoom(zoom_
)
152 , quality(quality_
), moduleQ2SE(moduleQ2SE_
), updateInfo(updateInfo_
) {}
153 }; // PlaneSettings struct
158 /** Interface for modules handling pixel-shape changes
159 * and/or splitting the single-color planes into independently processed parts */
160 struct IShapeTransformer
: public Interface
<IShapeTransformer
> {
161 typedef IColorTransformer::PlaneList PlaneList
;
163 /** Creates jobs from the list of color planes, returns job count */
164 virtual int createJobs(const PlaneList
&planes
) =0;
165 /** Returns the number of jobs */
166 virtual int jobCount() =0;
168 /** Starts encoding a job - thread-safe (for different jobs) */
169 virtual void jobEncode(int jobIndex
) =0;
170 /** Performs a decoding action for a job - thread-safe (for different jobs) */
171 virtual void jobDecodeAct( int jobIndex
, DecodeAct action
, int count
=1 ) =0;
173 /** Writes all settings (shared by all jobs) needed for later reconstruction */
174 virtual void writeSettings(std::ostream
&file
) =0;
175 /** Reads settings (shared by all jobs) needed for reconstruction from a stream -
176 * needs to be done before the job creation */
177 virtual void readSettings(std::istream
&file
) =0;
179 /** Returns the number of phases (progressive encoding), only depends on settings */
180 virtual int phaseCount() =0;
181 /** Writes any data needed for reconstruction of every job, phase parameters
182 * determine the range of saved phases */
183 virtual void writeJobs(std::ostream
&file
,int phaseBegin
,int phaseEnd
) =0;
184 /** Reads all data needed for reconstruction of every job and prepares for encoding,
185 * parameters like ::writeJobs */
186 virtual void readJobs(std::istream
&file
,int phaseBegin
,int phaseEnd
) =0;
188 /** Shortcut - default parameters "phaseBegin=0,phaseEnd=phaseCount()" */
189 void writeJobs(std::ostream
&file
,int phaseBegin
=0)
190 { writeJobs( file
, phaseBegin
, phaseCount() ); }
191 /** Shortcut - default parameters "phaseBegin=0,phaseEnd=phaseCount()" */
192 void readJobs(std::istream
&file
,int phaseBegin
=0)
193 { readJobs( file
, phaseBegin
, phaseCount() ); }
194 }; // IShapeTransformer interface
201 /** Represents a rectangular piece of single-color image to be encoded/decoded.
202 * It is common structure for ISquare{Range,Domain,Encoder}.
203 * Inherits a pixel-matrix, its dimensions and block-summers and adds
204 * pointers to settings and modules handling square ranges, domains and encoding */
205 struct PlaneBlock
: public SummedPixels
{
206 typedef IColorTransformer::PlaneSettings PlaneSettings
;
208 const PlaneSettings
*settings
; ///< the settings for the plane
209 ISquareRanges
*ranges
; ///< module for range blocks generation
210 ISquareDomains
*domains
;///< module for domain blocks generation
211 ISquareEncoder
*encoder
;///< module for encoding (maintaining domain-range mappings)
213 /** A simple integrity test - needs nonzero modules and pixel-matrix */
215 { return this && ranges
&& domains
&& encoder
&& pixels
.isValid(); }
216 }; // PlaneBlock struct
220 /** \addtogroup interfaces
224 /** Interface for modules that control how the image
225 * will be split into rectangular (mostly square) range blocks */
226 struct ISquareRanges
: public Interface
<ISquareRanges
> {
227 /** Structure representing a rectangular range block (usually square) */
229 /** List of range nodes (pointers) */
230 typedef std::vector
<RangeNode
*> RangeList
;
232 /** Starts encoding, calls modules in the passed structure.
233 * It should update UpdateInfo continually by the count of encoded pixels.
234 * \throws std::exception when cancelled via UpdateInfo or on other errors */
235 virtual void encode(const PlaneBlock
&toEncode
) =0;
236 /** Returns a reference to the current range-block list */
237 virtual const RangeList
& getRangeList() const =0;
239 /** Write all settings needed for reconstruction */
240 virtual void writeSettings(std::ostream
&file
) =0;
241 /** Read all settings needed for reconstruction */
242 virtual void readSettings(std::istream
&file
) =0;
244 /** Writes data needed for reconstruction (except for settings) */
245 virtual void writeData(std::ostream
&file
) =0;
246 /** Reads data from a stream and reconstructs the positions of range blocks.
247 * \param file the stream to read from
248 * \param block contains the properties of the block to be reconstructed */
249 virtual void readData_buildRanges( std::istream
&file
, const PlaneBlock
&block
) =0;
250 }; // ISquareRanges interface
252 struct ISquareRanges::RangeNode
: public Block
{
253 /** A common base type for data stored by encoders */
255 float bestSE
; ///< the best square error found until now
258 /// Encoders can store their data here, deleted in ::~RangeNode
259 mutable EncoderData
*encoderData
;
260 /// The smallest integer such that the block fits into square with side of length 2^level
263 /** Checks whether the block has regular shape (dimensions equal to 2^level) */
264 bool isRegular() const
265 { return width()==powers
[level
] && height()==powers
[level
]; }
267 /** Constructor - initializes ::encoderData to zero, to be used by derived classes */
268 RangeNode(const Block
&block
,int level_
)
269 : Block(block
), encoderData(0), level(level_
) {}
271 /** Only deletes ::encoderData */
273 { delete encoderData
; }
274 }; // ISquareRanges::RangeNode struct
279 /** Interface for modules deciding what will square domain blocks look like */
280 struct ISquareDomains
: public Interface
<ISquareDomains
> {
281 /** Describes one domain pool */
284 typedef std::vector
<Pool
> PoolList
;
286 /** Initializes the pools for given PlaneBlock, assumes settings are OK */
287 virtual void initPools(const PlaneBlock
&planeBlock
) =0;
288 /** Prepares domains in already initialized pools (and invalidates summers, etc.\ ) */
289 virtual void fillPixelsInPools(PlaneBlock
&planeBlock
) =0;
291 /** Returns a reference to internal list of domain pools */
292 virtual const PoolList
& getPools() const =0;
293 /** Gets densities for all domain pools on a particular level (with size 2^level - zoomed),
294 * returns unzoomed densities */
295 virtual std::vector
<short> getLevelDensities(int level
,int stdDomCountLog2
) =0;
297 /** Writes all settings (data needed for reconstruction that don't depend on the input) */
298 virtual void writeSettings(std::ostream
&file
) =0;
299 /** Reads all settings (like ::writeSettings) */
300 virtual void readSettings(std::istream
&file
) =0;
302 /** Writes all input-dependent data */
303 virtual void writeData(std::ostream
&file
) =0;
304 /** Reads all data, assumes the settings have already been read */
305 virtual void readData(std::istream
&file
) =0;
306 }; // ISquareDomains interface
308 struct ISquareDomains::Pool
: public SummedPixels
{
309 char type
/// The pool-type identifier (like diamond, module-specific)
310 , level
; ///< The count of down-scaling steps (1 for basic domains)
311 float contrFactor
; ///< The contractive factor (0,1) - the quotient of areas
313 /** Constructor allocating the parent SummedPixels with correct dimensions
314 * (increased according to \p zoom) */
315 Pool(short width_
,short height_
,char type_
,char level_
,float cFactor
,short zoom
)
316 : type(type_
), level(level_
), contrFactor(cFactor
)
317 { setSize( lShift(width_
,zoom
), lShift(height_
,zoom
) ); }
323 /** Interface for square encoders - maintaining mappings from square domains to square ranges */
324 struct ISquareEncoder
: public Interface
<ISquareEncoder
> {
325 typedef IColorTransformer::Plane Plane
;
326 typedef ISquareRanges::RangeNode RangeNode
;
328 /** Used by encoders, represents information about a domain pool on a level */
329 struct LevelPoolInfo
{
330 int indexBegin
/// the beginning of domain indices in "this pool" on "this level"
331 , density
; ///< the domain density (step size) in "this pool" on "this level"
333 /** [level][pool] -> LevelPoolInfo (the levels are zoomed). For every used level
334 * contains for all domain pools precomputed densities and the domain-ID boundaries */
335 typedef std::vector
< std::vector
<LevelPoolInfo
> > LevelPoolInfos
;
337 /** Initializes the module for encoding or decoding of a PlaneBlock */
338 virtual void initialize( IRoot::Mode mode
, PlaneBlock
&planeBlock
) =0;
339 /** Finds mapping with the best square error for a range (returns the SE),
340 * data neccessary for decoding are stored in RangeNode.encoderData */
341 virtual float findBestSE(const RangeNode
&range
,bool allowHigherSE
=false) =0;
342 /** Finishes encoding - to be ready for saving or decoding (can do some cleanup) */
343 virtual void finishEncoding() =0;
344 /** Performs a decoding action */
345 virtual void decodeAct( DecodeAct action
, int count
=1 ) =0;
347 /** Write all settings needed for reconstruction (don't depend on encoded thing) */
348 virtual void writeSettings(std::ostream
&file
) =0;
349 /** Read all settings, opposite to ::writeSettings */
350 virtual void readSettings(std::istream
&file
) =0;
352 /** Returns the number of phases (progressive encoding), only depends on settings */
353 virtual int phaseCount() const =0;
354 /** Write one phase of data needed for reconstruction (excluding settings) */
355 virtual void writeData(std::ostream
&file
,int phase
) =0;
356 /** Reads one phase of data needed for recostruction,
357 * assumes the settings have been read previously via ::readSettings */
358 virtual void readData(std::istream
&file
,int phase
) =0;
359 }; // ISquareEncoder interface
364 /** Interface for domain-range mapping predictor generator for MStdEncoder */
365 struct IStdEncPredictor
: public Interface
<IStdEncPredictor
> {
366 /** Contains information about one predicted domain block */
368 explicit Prediction( int domainID_
=-1, char rotation_
=-1 )
369 : domainID(domainID_
), rotation(rotation_
) {}
371 int domainID
; ///< domain's identification number
372 char rotation
; ///< the rotation of the domain
374 /** List of predictions (later often reffered to as a chunk) */
375 typedef std::vector
<Prediction
> Predictions
;
377 /** %Interface for objects that predict domains for a concrete range block */
378 struct IOneRangePredictor
{
379 /** Virtual destructor needed for safe deletion of derived classes */
380 virtual ~IOneRangePredictor() {}
381 /** Makes several predictions at once, returns \p store reference */
382 virtual Predictions
& getChunk(float maxPredictedSE
,Predictions
&store
) =0;
385 /** Holds plenty precomputed information about the range block to be predicted for */
386 struct NewPredictorData
;
388 /** Creates a predictor (passing the ownership) for a range block */
389 virtual IOneRangePredictor
* newPredictor(const NewPredictorData
&data
) =0;
390 /** Releases common resources (to be called when encoding is complete) */
391 virtual void cleanUp() =0;
392 }; // IStdEncPredictor interface
394 struct IStdEncPredictor::NewPredictorData
{
395 const ISquareRanges::RangeNode
*rangeBlock
; ///< Pointer to the range block
396 const SummedPixels
*rangePixels
; ///< Pointer to range's pixels
397 const ISquareDomains::PoolList
*pools
; ///< Pointer to the domain pools
398 const ISquareEncoder::LevelPoolInfos::value_type
*poolInfos
;
399 ///< Pointer to LevelPoolInfos for all pools (for this level)
401 bool allowRotations
/// Are rotations allowed?
402 , quantError
/// Should quantization errors be taken into account?
403 , allowInversion
/// Are mappings with negative linear coefficients allowed?
404 , isRegular
; ///< Is this range block regular? (see RangeNode::isRegular)
406 Real maxLinCoeff2
/// The maximum linear coefficient squared (or <0 if none)
407 , bigScaleCoeff
; ///< The coefficient of big-scaling penalization
409 Real rSum
/// The sum of range block's all pixels
410 , r2Sum
/// The sum of squares of range block's pixels
411 , pixCount
/// The number of range block's pixels
412 , rnDev2
/// Precomputed = ( ::pixCount*::r2Sum - sqr(::rSum) )
413 , rnDev
/// Precomputed = sqrt(::rnDev2)
414 , qrAvg
/// The average of range's pixels rounded by the selected quantizer
415 , qrDev
/// ::rnDev rounded by the selected quantizer
416 , qrDev2
; ///< sqr(::qrDev)
419 : rangeBlock(0), rangePixels(), pools(0), poolInfos(0) {}
421 }; // NewPredictorData struct
426 /** Integer sequences (de)coder interface */
427 struct IIntCodec
: public Interface
<IIntCodec
> {
428 /** Sets the number of possible symbols to work with from now on data: [0,possib-1] */
429 virtual void setPossibilities(int possib
) =0;
430 /** Codes data and sends them into a stream */
431 virtual void encode(std::vector
<int> &data
,std::ostream
&file
) =0;
432 /** Reads \c count symbols from \c file, decodes them and fills in \c data */
433 virtual void decode(std::istream
&file
,int count
,std::vector
<int> &data
) =0;
435 /** Write all settings needed (doesn't include possibilities set) */
436 virtual void writeSettings(std::ostream
&file
) =0;
437 /** Read all settings needed (doesn't include possibilities set) */
438 virtual void readSettings(std::istream
&file
) =0;
441 /// @} - interfaces defgroup
443 #endif // INTERFACES_HEADER_